From b642730be93149baa7556e5791393168ab396175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Feb 2008 17:35:24 +0900 Subject: Code reorganization: move files into their places. This is in a separate commit to ensure renames are properly preserved. --- src/gallium/Makefile | 28 + src/gallium/Makefile.template | 63 + src/gallium/README.portability | 43 + src/gallium/SConscript | 9 + src/gallium/aux/cso_cache/cso_cache.c | 181 ++ src/gallium/aux/cso_cache/cso_cache.h | 107 + src/gallium/aux/cso_cache/cso_hash.c | 388 +++ src/gallium/aux/cso_cache/cso_hash.h | 62 + src/gallium/aux/draw/Makefile | 2 + src/gallium/aux/draw/draw_clip.c | 488 +++ src/gallium/aux/draw/draw_context.c | 293 ++ src/gallium/aux/draw/draw_context.h | 142 + src/gallium/aux/draw/draw_cull.c | 150 + src/gallium/aux/draw/draw_debug.c | 113 + src/gallium/aux/draw/draw_flatshade.c | 205 ++ src/gallium/aux/draw/draw_offset.c | 186 ++ src/gallium/aux/draw/draw_prim.c | 482 +++ src/gallium/aux/draw/draw_private.h | 346 +++ src/gallium/aux/draw/draw_stipple.c | 239 ++ src/gallium/aux/draw/draw_twoside.c | 203 ++ src/gallium/aux/draw/draw_unfilled.c | 206 ++ src/gallium/aux/draw/draw_validate.c | 185 ++ src/gallium/aux/draw/draw_vbuf.c | 570 ++++ src/gallium/aux/draw/draw_vbuf.h | 106 + src/gallium/aux/draw/draw_vertex.c | 79 + src/gallium/aux/draw/draw_vertex.h | 111 + src/gallium/aux/draw/draw_vertex_cache.c | 196 ++ src/gallium/aux/draw/draw_vertex_fetch.c | 510 ++++ src/gallium/aux/draw/draw_vertex_shader.c | 325 ++ src/gallium/aux/draw/draw_vf.c | 428 +++ src/gallium/aux/draw/draw_vf.h | 236 ++ src/gallium/aux/draw/draw_vf_generic.c | 585 ++++ src/gallium/aux/draw/draw_vf_sse.c | 614 ++++ src/gallium/aux/draw/draw_wide_prims.c | 432 +++ src/gallium/aux/llvm/Makefile | 83 + src/gallium/aux/llvm/gallivm.cpp | 327 ++ src/gallium/aux/llvm/gallivm.h | 103 + src/gallium/aux/llvm/gallivm_builtins.cpp | 567 ++++ src/gallium/aux/llvm/gallivm_cpu.cpp | 202 ++ src/gallium/aux/llvm/gallivm_p.h | 110 + src/gallium/aux/llvm/instructions.cpp | 889 ++++++ src/gallium/aux/llvm/instructions.h | 152 + src/gallium/aux/llvm/instructionssoa.cpp | 121 + src/gallium/aux/llvm/instructionssoa.h | 74 + src/gallium/aux/llvm/llvm_builtins.c | 115 + src/gallium/aux/llvm/loweringpass.cpp | 17 + src/gallium/aux/llvm/loweringpass.h | 15 + src/gallium/aux/llvm/storage.cpp | 364 +++ src/gallium/aux/llvm/storage.h | 133 + src/gallium/aux/llvm/storagesoa.cpp | 389 +++ src/gallium/aux/llvm/storagesoa.h | 111 + src/gallium/aux/llvm/tgsitollvm.cpp | 1221 ++++++++ src/gallium/aux/llvm/tgsitollvm.h | 20 + src/gallium/aux/pipebuffer/Makefile | 23 + src/gallium/aux/pipebuffer/linked_list.h | 91 + src/gallium/aux/pipebuffer/pb_buffer.h | 202 ++ src/gallium/aux/pipebuffer/pb_buffer_fenced.c | 299 ++ src/gallium/aux/pipebuffer/pb_buffer_fenced.h | 117 + src/gallium/aux/pipebuffer/pb_buffer_malloc.c | 127 + src/gallium/aux/pipebuffer/pb_bufmgr.h | 126 + src/gallium/aux/pipebuffer/pb_bufmgr_fenced.c | 131 + src/gallium/aux/pipebuffer/pb_bufmgr_mm.c | 593 ++++ src/gallium/aux/pipebuffer/pb_bufmgr_pool.c | 288 ++ src/gallium/aux/pipebuffer/pb_winsys.c | 170 ++ src/gallium/aux/tgsi/Makefile | 3 + src/gallium/aux/tgsi/exec/Makefile | 3 + src/gallium/aux/tgsi/exec/tgsi_exec.c | 2485 +++++++++++++++ src/gallium/aux/tgsi/exec/tgsi_exec.h | 239 ++ src/gallium/aux/tgsi/exec/tgsi_sse2.c | 2378 +++++++++++++++ src/gallium/aux/tgsi/exec/tgsi_sse2.h | 26 + src/gallium/aux/tgsi/util/tgsi_build.c | 1371 +++++++++ src/gallium/aux/tgsi/util/tgsi_build.h | 320 ++ src/gallium/aux/tgsi/util/tgsi_dump.c | 1581 ++++++++++ src/gallium/aux/tgsi/util/tgsi_dump.h | 28 + src/gallium/aux/tgsi/util/tgsi_parse.c | 319 ++ src/gallium/aux/tgsi/util/tgsi_parse.h | 121 + src/gallium/aux/tgsi/util/tgsi_transform.c | 199 ++ src/gallium/aux/tgsi/util/tgsi_transform.h | 93 + src/gallium/aux/tgsi/util/tgsi_util.c | 274 ++ src/gallium/aux/tgsi/util/tgsi_util.h | 70 + src/gallium/aux/util/p_debug.c | 76 + src/gallium/aux/util/p_tile.c | 699 +++++ src/gallium/aux/util/p_tile.h | 81 + src/gallium/aux/util/p_util.c | 73 + src/gallium/drivers/cell/Makefile | 12 + src/gallium/drivers/cell/common.h | 220 ++ src/gallium/drivers/cell/ppu/Makefile | 76 + src/gallium/drivers/cell/ppu/cell_batch.c | 217 ++ src/gallium/drivers/cell/ppu/cell_batch.h | 58 + src/gallium/drivers/cell/ppu/cell_clear.c | 76 + src/gallium/drivers/cell/ppu/cell_clear.h | 43 + src/gallium/drivers/cell/ppu/cell_context.c | 287 ++ src/gallium/drivers/cell/ppu/cell_context.h | 135 + src/gallium/drivers/cell/ppu/cell_draw_arrays.c | 164 + src/gallium/drivers/cell/ppu/cell_draw_arrays.h | 42 + src/gallium/drivers/cell/ppu/cell_flush.c | 84 + src/gallium/drivers/cell/ppu/cell_flush.h | 38 + src/gallium/drivers/cell/ppu/cell_render.c | 210 ++ src/gallium/drivers/cell/ppu/cell_render.h | 39 + src/gallium/drivers/cell/ppu/cell_spu.c | 155 + src/gallium/drivers/cell/ppu/cell_spu.h | 82 + src/gallium/drivers/cell/ppu/cell_state.h | 115 + src/gallium/drivers/cell/ppu/cell_state_blend.c | 109 + src/gallium/drivers/cell/ppu/cell_state_clip.c | 84 + src/gallium/drivers/cell/ppu/cell_state_derived.c | 192 ++ src/gallium/drivers/cell/ppu/cell_state_emit.c | 103 + src/gallium/drivers/cell/ppu/cell_state_emit.h | 36 + src/gallium/drivers/cell/ppu/cell_state_fs.c | 171 ++ .../drivers/cell/ppu/cell_state_rasterizer.c | 106 + src/gallium/drivers/cell/ppu/cell_state_sampler.c | 84 + src/gallium/drivers/cell/ppu/cell_state_surface.c | 71 + src/gallium/drivers/cell/ppu/cell_state_vertex.c | 63 + src/gallium/drivers/cell/ppu/cell_surface.c | 179 ++ src/gallium/drivers/cell/ppu/cell_surface.h | 42 + src/gallium/drivers/cell/ppu/cell_texture.c | 252 ++ src/gallium/drivers/cell/ppu/cell_texture.h | 80 + src/gallium/drivers/cell/ppu/cell_vbuf.c | 294 ++ src/gallium/drivers/cell/ppu/cell_vbuf.h | 38 + src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 120 + src/gallium/drivers/cell/ppu/cell_winsys.c | 40 + src/gallium/drivers/cell/ppu/cell_winsys.h | 50 + src/gallium/drivers/cell/spu/Makefile | 72 + src/gallium/drivers/cell/spu/spu_blend.c | 62 + src/gallium/drivers/cell/spu/spu_blend.h | 37 + src/gallium/drivers/cell/spu/spu_colorpack.h | 110 + src/gallium/drivers/cell/spu/spu_exec.c | 1948 ++++++++++++ src/gallium/drivers/cell/spu/spu_exec.h | 172 ++ src/gallium/drivers/cell/spu/spu_main.c | 567 ++++ src/gallium/drivers/cell/spu/spu_main.h | 177 ++ src/gallium/drivers/cell/spu/spu_render.c | 301 ++ src/gallium/drivers/cell/spu/spu_render.h | 38 + src/gallium/drivers/cell/spu/spu_texture.c | 217 ++ src/gallium/drivers/cell/spu/spu_texture.h | 47 + src/gallium/drivers/cell/spu/spu_tile.c | 83 + src/gallium/drivers/cell/spu/spu_tile.h | 73 + src/gallium/drivers/cell/spu/spu_tri.c | 926 ++++++ src/gallium/drivers/cell/spu/spu_tri.h | 37 + src/gallium/drivers/cell/spu/spu_util.c | 165 + src/gallium/drivers/cell/spu/spu_vertex_fetch.c | 673 +++++ src/gallium/drivers/cell/spu/spu_vertex_shader.c | 231 ++ src/gallium/drivers/cell/spu/spu_vertex_shader.h | 63 + src/gallium/drivers/cell/spu/spu_ztest.h | 135 + src/gallium/drivers/failover/Makefile | 21 + src/gallium/drivers/failover/fo_context.c | 155 + src/gallium/drivers/failover/fo_context.h | 114 + src/gallium/drivers/failover/fo_state.c | 457 +++ src/gallium/drivers/failover/fo_state_emit.c | 137 + src/gallium/drivers/failover/fo_winsys.h | 45 + src/gallium/drivers/i915simple/Makefile | 38 + src/gallium/drivers/i915simple/SConscript | 29 + src/gallium/drivers/i915simple/i915_batch.h | 54 + src/gallium/drivers/i915simple/i915_blit.c | 162 + src/gallium/drivers/i915simple/i915_blit.h | 55 + src/gallium/drivers/i915simple/i915_clear.c | 47 + src/gallium/drivers/i915simple/i915_context.c | 320 ++ src/gallium/drivers/i915simple/i915_context.h | 304 ++ src/gallium/drivers/i915simple/i915_debug.c | 901 ++++++ src/gallium/drivers/i915simple/i915_debug.h | 117 + src/gallium/drivers/i915simple/i915_debug_fp.c | 366 +++ src/gallium/drivers/i915simple/i915_flush.c | 81 + src/gallium/drivers/i915simple/i915_fpc.h | 213 ++ src/gallium/drivers/i915simple/i915_fpc_emit.c | 375 +++ .../drivers/i915simple/i915_fpc_translate.c | 1135 +++++++ src/gallium/drivers/i915simple/i915_prim_emit.c | 215 ++ src/gallium/drivers/i915simple/i915_prim_vbuf.c | 254 ++ src/gallium/drivers/i915simple/i915_reg.h | 978 ++++++ src/gallium/drivers/i915simple/i915_state.c | 694 +++++ src/gallium/drivers/i915simple/i915_state.h | 50 + .../drivers/i915simple/i915_state_derived.c | 177 ++ .../drivers/i915simple/i915_state_dynamic.c | 308 ++ src/gallium/drivers/i915simple/i915_state_emit.c | 374 +++ .../drivers/i915simple/i915_state_immediate.c | 221 ++ .../drivers/i915simple/i915_state_inlines.h | 230 ++ .../drivers/i915simple/i915_state_sampler.c | 231 ++ src/gallium/drivers/i915simple/i915_strings.c | 83 + src/gallium/drivers/i915simple/i915_surface.c | 191 ++ src/gallium/drivers/i915simple/i915_texture.c | 536 ++++ src/gallium/drivers/i915simple/i915_texture.h | 17 + src/gallium/drivers/i915simple/i915_winsys.h | 115 + src/gallium/drivers/i965simple/Makefile | 66 + src/gallium/drivers/i965simple/SConscript | 55 + src/gallium/drivers/i965simple/brw_batch.h | 59 + src/gallium/drivers/i965simple/brw_blit.c | 218 ++ src/gallium/drivers/i965simple/brw_blit.h | 33 + src/gallium/drivers/i965simple/brw_cc.c | 269 ++ src/gallium/drivers/i965simple/brw_clip.c | 206 ++ src/gallium/drivers/i965simple/brw_clip.h | 170 ++ src/gallium/drivers/i965simple/brw_clip_line.c | 245 ++ src/gallium/drivers/i965simple/brw_clip_point.c | 47 + src/gallium/drivers/i965simple/brw_clip_state.c | 92 + src/gallium/drivers/i965simple/brw_clip_tri.c | 566 ++++ src/gallium/drivers/i965simple/brw_clip_unfilled.c | 477 +++ src/gallium/drivers/i965simple/brw_clip_util.c | 351 +++ src/gallium/drivers/i965simple/brw_context.c | 245 ++ src/gallium/drivers/i965simple/brw_context.h | 690 +++++ src/gallium/drivers/i965simple/brw_curbe.c | 368 +++ src/gallium/drivers/i965simple/brw_defines.h | 852 ++++++ src/gallium/drivers/i965simple/brw_draw.c | 239 ++ src/gallium/drivers/i965simple/brw_draw.h | 55 + src/gallium/drivers/i965simple/brw_draw_upload.c | 299 ++ src/gallium/drivers/i965simple/brw_eu.c | 130 + src/gallium/drivers/i965simple/brw_eu.h | 888 ++++++ src/gallium/drivers/i965simple/brw_eu_debug.c | 90 + src/gallium/drivers/i965simple/brw_eu_emit.c | 1080 +++++++ src/gallium/drivers/i965simple/brw_eu_util.c | 126 + src/gallium/drivers/i965simple/brw_flush.c | 80 + src/gallium/drivers/i965simple/brw_gs.c | 196 ++ src/gallium/drivers/i965simple/brw_gs.h | 75 + src/gallium/drivers/i965simple/brw_gs_emit.c | 148 + src/gallium/drivers/i965simple/brw_gs_state.c | 89 + src/gallium/drivers/i965simple/brw_misc_state.c | 486 +++ src/gallium/drivers/i965simple/brw_reg.h | 76 + src/gallium/drivers/i965simple/brw_sf.c | 351 +++ src/gallium/drivers/i965simple/brw_sf.h | 122 + src/gallium/drivers/i965simple/brw_sf_emit.c | 382 +++ src/gallium/drivers/i965simple/brw_sf_state.c | 180 ++ src/gallium/drivers/i965simple/brw_shader_info.c | 49 + src/gallium/drivers/i965simple/brw_state.c | 424 +++ src/gallium/drivers/i965simple/brw_state.h | 158 + src/gallium/drivers/i965simple/brw_state_batch.c | 113 + src/gallium/drivers/i965simple/brw_state_cache.c | 443 +++ src/gallium/drivers/i965simple/brw_state_pool.c | 137 + src/gallium/drivers/i965simple/brw_state_upload.c | 202 ++ src/gallium/drivers/i965simple/brw_strings.c | 72 + src/gallium/drivers/i965simple/brw_structs.h | 1348 +++++++++ src/gallium/drivers/i965simple/brw_surface.c | 210 ++ src/gallium/drivers/i965simple/brw_tex_layout.c | 353 +++ src/gallium/drivers/i965simple/brw_tex_layout.h | 15 + src/gallium/drivers/i965simple/brw_urb.c | 186 ++ src/gallium/drivers/i965simple/brw_util.c | 104 + src/gallium/drivers/i965simple/brw_util.h | 43 + src/gallium/drivers/i965simple/brw_vs.c | 120 + src/gallium/drivers/i965simple/brw_vs.h | 82 + src/gallium/drivers/i965simple/brw_vs_emit.c | 1332 ++++++++ src/gallium/drivers/i965simple/brw_vs_state.c | 102 + src/gallium/drivers/i965simple/brw_winsys.h | 205 ++ src/gallium/drivers/i965simple/brw_wm.c | 210 ++ src/gallium/drivers/i965simple/brw_wm.h | 142 + src/gallium/drivers/i965simple/brw_wm_decl.c | 383 +++ src/gallium/drivers/i965simple/brw_wm_glsl.c | 1079 +++++++ src/gallium/drivers/i965simple/brw_wm_iz.c | 214 ++ .../drivers/i965simple/brw_wm_sampler_state.c | 273 ++ src/gallium/drivers/i965simple/brw_wm_state.c | 194 ++ .../drivers/i965simple/brw_wm_surface_state.c | 304 ++ src/gallium/drivers/softpipe/Makefile | 50 + src/gallium/drivers/softpipe/SConscript | 42 + src/gallium/drivers/softpipe/sp_clear.c | 73 + src/gallium/drivers/softpipe/sp_clear.h | 43 + src/gallium/drivers/softpipe/sp_context.c | 333 ++ src/gallium/drivers/softpipe/sp_context.h | 152 + src/gallium/drivers/softpipe/sp_draw_arrays.c | 164 + src/gallium/drivers/softpipe/sp_flush.c | 76 + src/gallium/drivers/softpipe/sp_flush.h | 35 + src/gallium/drivers/softpipe/sp_headers.h | 82 + src/gallium/drivers/softpipe/sp_prim_setup.c | 1247 ++++++++ src/gallium/drivers/softpipe/sp_prim_setup.h | 79 + src/gallium/drivers/softpipe/sp_prim_vbuf.c | 221 ++ src/gallium/drivers/softpipe/sp_prim_vbuf.h | 38 + src/gallium/drivers/softpipe/sp_quad.c | 118 + src/gallium/drivers/softpipe/sp_quad.h | 70 + src/gallium/drivers/softpipe/sp_quad_alpha_test.c | 108 + src/gallium/drivers/softpipe/sp_quad_blend.c | 749 +++++ src/gallium/drivers/softpipe/sp_quad_bufloop.c | 72 + src/gallium/drivers/softpipe/sp_quad_colormask.c | 110 + src/gallium/drivers/softpipe/sp_quad_coverage.c | 88 + src/gallium/drivers/softpipe/sp_quad_depth_test.c | 276 ++ src/gallium/drivers/softpipe/sp_quad_earlyz.c | 88 + src/gallium/drivers/softpipe/sp_quad_fs.c | 390 +++ src/gallium/drivers/softpipe/sp_quad_occlusion.c | 85 + src/gallium/drivers/softpipe/sp_quad_output.c | 90 + src/gallium/drivers/softpipe/sp_quad_stencil.c | 352 +++ src/gallium/drivers/softpipe/sp_quad_stipple.c | 94 + src/gallium/drivers/softpipe/sp_query.c | 107 + src/gallium/drivers/softpipe/sp_query.h | 39 + src/gallium/drivers/softpipe/sp_state.h | 187 ++ src/gallium/drivers/softpipe/sp_state_blend.c | 98 + src/gallium/drivers/softpipe/sp_state_clip.c | 83 + src/gallium/drivers/softpipe/sp_state_derived.c | 235 ++ src/gallium/drivers/softpipe/sp_state_fs.c | 179 ++ src/gallium/drivers/softpipe/sp_state_rasterizer.c | 62 + src/gallium/drivers/softpipe/sp_state_sampler.c | 93 + src/gallium/drivers/softpipe/sp_state_surface.c | 109 + src/gallium/drivers/softpipe/sp_state_vertex.c | 64 + src/gallium/drivers/softpipe/sp_surface.c | 159 + src/gallium/drivers/softpipe/sp_surface.h | 42 + src/gallium/drivers/softpipe/sp_tex_sample.c | 916 ++++++ src/gallium/drivers/softpipe/sp_tex_sample.h | 17 + src/gallium/drivers/softpipe/sp_texture.c | 166 + src/gallium/drivers/softpipe/sp_texture.h | 71 + src/gallium/drivers/softpipe/sp_tile_cache.c | 585 ++++ src/gallium/drivers/softpipe/sp_tile_cache.h | 104 + src/gallium/drivers/softpipe/sp_winsys.h | 57 + src/gallium/include/pipe/p_compiler.h | 116 + src/gallium/include/pipe/p_context.h | 221 ++ src/gallium/include/pipe/p_debug.h | 86 + src/gallium/include/pipe/p_defines.h | 270 ++ src/gallium/include/pipe/p_format.h | 421 +++ src/gallium/include/pipe/p_inlines.h | 112 + src/gallium/include/pipe/p_shader_tokens.h | 806 +++++ src/gallium/include/pipe/p_state.h | 322 ++ src/gallium/include/pipe/p_thread.h | 54 + src/gallium/include/pipe/p_util.h | 408 +++ src/gallium/include/pipe/p_winsys.h | 160 + src/gallium/winsys/dri/intel/Makefile | 38 + src/gallium/winsys/dri/intel/SConscript | 41 + src/gallium/winsys/dri/intel/intel_batchbuffer.c | 357 +++ src/gallium/winsys/dri/intel/intel_batchbuffer.h | 149 + src/gallium/winsys/dri/intel/intel_batchpool.c | 424 +++ src/gallium/winsys/dri/intel/intel_batchpool.h | 37 + src/gallium/winsys/dri/intel/intel_context.c | 304 ++ src/gallium/winsys/dri/intel/intel_context.h | 158 + src/gallium/winsys/dri/intel/intel_lock.c | 102 + src/gallium/winsys/dri/intel/intel_reg.h | 53 + src/gallium/winsys/dri/intel/intel_screen.c | 537 ++++ src/gallium/winsys/dri/intel/intel_screen.h | 113 + src/gallium/winsys/dri/intel/intel_swapbuffers.c | 253 ++ src/gallium/winsys/dri/intel/intel_swapbuffers.h | 47 + src/gallium/winsys/dri/intel/intel_winsys.h | 73 + src/gallium/winsys/dri/intel/intel_winsys_i915.c | 154 + src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 302 ++ .../winsys/dri/intel/intel_winsys_softpipe.c | 81 + src/gallium/winsys/dri/intel/server/i830_common.h | 226 ++ src/gallium/winsys/dri/intel/server/i830_dri.h | 63 + src/gallium/winsys/dri/intel/server/intel.h | 331 ++ src/gallium/winsys/dri/intel/server/intel_dri.c | 1306 ++++++++ src/gallium/winsys/xlib/brw_aub.c | 392 +++ src/gallium/winsys/xlib/brw_aub.h | 114 + src/gallium/winsys/xlib/fakeglx.c | 3188 ++++++++++++++++++++ src/gallium/winsys/xlib/glxapi.c | 1408 +++++++++ src/gallium/winsys/xlib/glxapi.h | 228 ++ src/gallium/winsys/xlib/glxheader.h | 62 + src/gallium/winsys/xlib/realglx.c | 180 ++ src/gallium/winsys/xlib/realglx.h | 326 ++ src/gallium/winsys/xlib/xfonts.c | 377 +++ src/gallium/winsys/xlib/xfonts.h | 41 + src/gallium/winsys/xlib/xm_api.c | 1380 +++++++++ src/gallium/winsys/xlib/xm_image.c | 133 + src/gallium/winsys/xlib/xm_image.h | 77 + src/gallium/winsys/xlib/xm_winsys.c | 466 +++ src/gallium/winsys/xlib/xm_winsys_aub.c | 589 ++++ src/gallium/winsys/xlib/xm_winsys_aub.h | 67 + src/gallium/winsys/xlib/xmesaP.h | 176 ++ 342 files changed, 90658 insertions(+) create mode 100644 src/gallium/Makefile create mode 100644 src/gallium/Makefile.template create mode 100644 src/gallium/README.portability create mode 100644 src/gallium/SConscript create mode 100644 src/gallium/aux/cso_cache/cso_cache.c create mode 100644 src/gallium/aux/cso_cache/cso_cache.h create mode 100644 src/gallium/aux/cso_cache/cso_hash.c create mode 100644 src/gallium/aux/cso_cache/cso_hash.h create mode 100644 src/gallium/aux/draw/Makefile create mode 100644 src/gallium/aux/draw/draw_clip.c create mode 100644 src/gallium/aux/draw/draw_context.c create mode 100644 src/gallium/aux/draw/draw_context.h create mode 100644 src/gallium/aux/draw/draw_cull.c create mode 100644 src/gallium/aux/draw/draw_debug.c create mode 100644 src/gallium/aux/draw/draw_flatshade.c create mode 100644 src/gallium/aux/draw/draw_offset.c create mode 100644 src/gallium/aux/draw/draw_prim.c create mode 100644 src/gallium/aux/draw/draw_private.h create mode 100644 src/gallium/aux/draw/draw_stipple.c create mode 100644 src/gallium/aux/draw/draw_twoside.c create mode 100644 src/gallium/aux/draw/draw_unfilled.c create mode 100644 src/gallium/aux/draw/draw_validate.c create mode 100644 src/gallium/aux/draw/draw_vbuf.c create mode 100644 src/gallium/aux/draw/draw_vbuf.h create mode 100644 src/gallium/aux/draw/draw_vertex.c create mode 100644 src/gallium/aux/draw/draw_vertex.h create mode 100644 src/gallium/aux/draw/draw_vertex_cache.c create mode 100644 src/gallium/aux/draw/draw_vertex_fetch.c create mode 100644 src/gallium/aux/draw/draw_vertex_shader.c create mode 100644 src/gallium/aux/draw/draw_vf.c create mode 100644 src/gallium/aux/draw/draw_vf.h create mode 100644 src/gallium/aux/draw/draw_vf_generic.c create mode 100644 src/gallium/aux/draw/draw_vf_sse.c create mode 100644 src/gallium/aux/draw/draw_wide_prims.c create mode 100644 src/gallium/aux/llvm/Makefile create mode 100644 src/gallium/aux/llvm/gallivm.cpp create mode 100644 src/gallium/aux/llvm/gallivm.h create mode 100644 src/gallium/aux/llvm/gallivm_builtins.cpp create mode 100644 src/gallium/aux/llvm/gallivm_cpu.cpp create mode 100644 src/gallium/aux/llvm/gallivm_p.h create mode 100644 src/gallium/aux/llvm/instructions.cpp create mode 100644 src/gallium/aux/llvm/instructions.h create mode 100644 src/gallium/aux/llvm/instructionssoa.cpp create mode 100644 src/gallium/aux/llvm/instructionssoa.h create mode 100644 src/gallium/aux/llvm/llvm_builtins.c create mode 100644 src/gallium/aux/llvm/loweringpass.cpp create mode 100644 src/gallium/aux/llvm/loweringpass.h create mode 100644 src/gallium/aux/llvm/storage.cpp create mode 100644 src/gallium/aux/llvm/storage.h create mode 100644 src/gallium/aux/llvm/storagesoa.cpp create mode 100644 src/gallium/aux/llvm/storagesoa.h create mode 100644 src/gallium/aux/llvm/tgsitollvm.cpp create mode 100644 src/gallium/aux/llvm/tgsitollvm.h create mode 100644 src/gallium/aux/pipebuffer/Makefile create mode 100644 src/gallium/aux/pipebuffer/linked_list.h create mode 100644 src/gallium/aux/pipebuffer/pb_buffer.h create mode 100644 src/gallium/aux/pipebuffer/pb_buffer_fenced.c create mode 100644 src/gallium/aux/pipebuffer/pb_buffer_fenced.h create mode 100644 src/gallium/aux/pipebuffer/pb_buffer_malloc.c create mode 100644 src/gallium/aux/pipebuffer/pb_bufmgr.h create mode 100644 src/gallium/aux/pipebuffer/pb_bufmgr_fenced.c create mode 100644 src/gallium/aux/pipebuffer/pb_bufmgr_mm.c create mode 100644 src/gallium/aux/pipebuffer/pb_bufmgr_pool.c create mode 100644 src/gallium/aux/pipebuffer/pb_winsys.c create mode 100644 src/gallium/aux/tgsi/Makefile create mode 100644 src/gallium/aux/tgsi/exec/Makefile create mode 100644 src/gallium/aux/tgsi/exec/tgsi_exec.c create mode 100644 src/gallium/aux/tgsi/exec/tgsi_exec.h create mode 100755 src/gallium/aux/tgsi/exec/tgsi_sse2.c create mode 100755 src/gallium/aux/tgsi/exec/tgsi_sse2.h create mode 100644 src/gallium/aux/tgsi/util/tgsi_build.c create mode 100644 src/gallium/aux/tgsi/util/tgsi_build.h create mode 100644 src/gallium/aux/tgsi/util/tgsi_dump.c create mode 100644 src/gallium/aux/tgsi/util/tgsi_dump.h create mode 100644 src/gallium/aux/tgsi/util/tgsi_parse.c create mode 100644 src/gallium/aux/tgsi/util/tgsi_parse.h create mode 100644 src/gallium/aux/tgsi/util/tgsi_transform.c create mode 100644 src/gallium/aux/tgsi/util/tgsi_transform.h create mode 100644 src/gallium/aux/tgsi/util/tgsi_util.c create mode 100644 src/gallium/aux/tgsi/util/tgsi_util.h create mode 100644 src/gallium/aux/util/p_debug.c create mode 100644 src/gallium/aux/util/p_tile.c create mode 100644 src/gallium/aux/util/p_tile.h create mode 100644 src/gallium/aux/util/p_util.c create mode 100644 src/gallium/drivers/cell/Makefile create mode 100644 src/gallium/drivers/cell/common.h create mode 100644 src/gallium/drivers/cell/ppu/Makefile create mode 100644 src/gallium/drivers/cell/ppu/cell_batch.c create mode 100644 src/gallium/drivers/cell/ppu/cell_batch.h create mode 100644 src/gallium/drivers/cell/ppu/cell_clear.c create mode 100644 src/gallium/drivers/cell/ppu/cell_clear.h create mode 100644 src/gallium/drivers/cell/ppu/cell_context.c create mode 100644 src/gallium/drivers/cell/ppu/cell_context.h create mode 100644 src/gallium/drivers/cell/ppu/cell_draw_arrays.c create mode 100644 src/gallium/drivers/cell/ppu/cell_draw_arrays.h create mode 100644 src/gallium/drivers/cell/ppu/cell_flush.c create mode 100644 src/gallium/drivers/cell/ppu/cell_flush.h create mode 100644 src/gallium/drivers/cell/ppu/cell_render.c create mode 100644 src/gallium/drivers/cell/ppu/cell_render.h create mode 100644 src/gallium/drivers/cell/ppu/cell_spu.c create mode 100644 src/gallium/drivers/cell/ppu/cell_spu.h create mode 100644 src/gallium/drivers/cell/ppu/cell_state.h create mode 100644 src/gallium/drivers/cell/ppu/cell_state_blend.c create mode 100644 src/gallium/drivers/cell/ppu/cell_state_clip.c create mode 100644 src/gallium/drivers/cell/ppu/cell_state_derived.c create mode 100644 src/gallium/drivers/cell/ppu/cell_state_emit.c create mode 100644 src/gallium/drivers/cell/ppu/cell_state_emit.h create mode 100644 src/gallium/drivers/cell/ppu/cell_state_fs.c create mode 100644 src/gallium/drivers/cell/ppu/cell_state_rasterizer.c create mode 100644 src/gallium/drivers/cell/ppu/cell_state_sampler.c create mode 100644 src/gallium/drivers/cell/ppu/cell_state_surface.c create mode 100644 src/gallium/drivers/cell/ppu/cell_state_vertex.c create mode 100644 src/gallium/drivers/cell/ppu/cell_surface.c create mode 100644 src/gallium/drivers/cell/ppu/cell_surface.h create mode 100644 src/gallium/drivers/cell/ppu/cell_texture.c create mode 100644 src/gallium/drivers/cell/ppu/cell_texture.h create mode 100644 src/gallium/drivers/cell/ppu/cell_vbuf.c create mode 100644 src/gallium/drivers/cell/ppu/cell_vbuf.h create mode 100644 src/gallium/drivers/cell/ppu/cell_vertex_shader.c create mode 100644 src/gallium/drivers/cell/ppu/cell_winsys.c create mode 100644 src/gallium/drivers/cell/ppu/cell_winsys.h create mode 100644 src/gallium/drivers/cell/spu/Makefile create mode 100644 src/gallium/drivers/cell/spu/spu_blend.c create mode 100644 src/gallium/drivers/cell/spu/spu_blend.h create mode 100644 src/gallium/drivers/cell/spu/spu_colorpack.h create mode 100644 src/gallium/drivers/cell/spu/spu_exec.c create mode 100644 src/gallium/drivers/cell/spu/spu_exec.h create mode 100644 src/gallium/drivers/cell/spu/spu_main.c create mode 100644 src/gallium/drivers/cell/spu/spu_main.h create mode 100644 src/gallium/drivers/cell/spu/spu_render.c create mode 100644 src/gallium/drivers/cell/spu/spu_render.h create mode 100644 src/gallium/drivers/cell/spu/spu_texture.c create mode 100644 src/gallium/drivers/cell/spu/spu_texture.h create mode 100644 src/gallium/drivers/cell/spu/spu_tile.c create mode 100644 src/gallium/drivers/cell/spu/spu_tile.h create mode 100644 src/gallium/drivers/cell/spu/spu_tri.c create mode 100644 src/gallium/drivers/cell/spu/spu_tri.h create mode 100644 src/gallium/drivers/cell/spu/spu_util.c create mode 100644 src/gallium/drivers/cell/spu/spu_vertex_fetch.c create mode 100644 src/gallium/drivers/cell/spu/spu_vertex_shader.c create mode 100644 src/gallium/drivers/cell/spu/spu_vertex_shader.h create mode 100644 src/gallium/drivers/cell/spu/spu_ztest.h create mode 100644 src/gallium/drivers/failover/Makefile create mode 100644 src/gallium/drivers/failover/fo_context.c create mode 100644 src/gallium/drivers/failover/fo_context.h create mode 100644 src/gallium/drivers/failover/fo_state.c create mode 100644 src/gallium/drivers/failover/fo_state_emit.c create mode 100644 src/gallium/drivers/failover/fo_winsys.h create mode 100644 src/gallium/drivers/i915simple/Makefile create mode 100644 src/gallium/drivers/i915simple/SConscript create mode 100644 src/gallium/drivers/i915simple/i915_batch.h create mode 100644 src/gallium/drivers/i915simple/i915_blit.c create mode 100644 src/gallium/drivers/i915simple/i915_blit.h create mode 100644 src/gallium/drivers/i915simple/i915_clear.c create mode 100644 src/gallium/drivers/i915simple/i915_context.c create mode 100644 src/gallium/drivers/i915simple/i915_context.h create mode 100644 src/gallium/drivers/i915simple/i915_debug.c create mode 100644 src/gallium/drivers/i915simple/i915_debug.h create mode 100644 src/gallium/drivers/i915simple/i915_debug_fp.c create mode 100644 src/gallium/drivers/i915simple/i915_flush.c create mode 100644 src/gallium/drivers/i915simple/i915_fpc.h create mode 100644 src/gallium/drivers/i915simple/i915_fpc_emit.c create mode 100644 src/gallium/drivers/i915simple/i915_fpc_translate.c create mode 100644 src/gallium/drivers/i915simple/i915_prim_emit.c create mode 100644 src/gallium/drivers/i915simple/i915_prim_vbuf.c create mode 100644 src/gallium/drivers/i915simple/i915_reg.h create mode 100644 src/gallium/drivers/i915simple/i915_state.c create mode 100644 src/gallium/drivers/i915simple/i915_state.h create mode 100644 src/gallium/drivers/i915simple/i915_state_derived.c create mode 100644 src/gallium/drivers/i915simple/i915_state_dynamic.c create mode 100644 src/gallium/drivers/i915simple/i915_state_emit.c create mode 100644 src/gallium/drivers/i915simple/i915_state_immediate.c create mode 100644 src/gallium/drivers/i915simple/i915_state_inlines.h create mode 100644 src/gallium/drivers/i915simple/i915_state_sampler.c create mode 100644 src/gallium/drivers/i915simple/i915_strings.c create mode 100644 src/gallium/drivers/i915simple/i915_surface.c create mode 100644 src/gallium/drivers/i915simple/i915_texture.c create mode 100644 src/gallium/drivers/i915simple/i915_texture.h create mode 100644 src/gallium/drivers/i915simple/i915_winsys.h create mode 100644 src/gallium/drivers/i965simple/Makefile create mode 100644 src/gallium/drivers/i965simple/SConscript create mode 100644 src/gallium/drivers/i965simple/brw_batch.h create mode 100644 src/gallium/drivers/i965simple/brw_blit.c create mode 100644 src/gallium/drivers/i965simple/brw_blit.h create mode 100644 src/gallium/drivers/i965simple/brw_cc.c create mode 100644 src/gallium/drivers/i965simple/brw_clip.c create mode 100644 src/gallium/drivers/i965simple/brw_clip.h create mode 100644 src/gallium/drivers/i965simple/brw_clip_line.c create mode 100644 src/gallium/drivers/i965simple/brw_clip_point.c create mode 100644 src/gallium/drivers/i965simple/brw_clip_state.c create mode 100644 src/gallium/drivers/i965simple/brw_clip_tri.c create mode 100644 src/gallium/drivers/i965simple/brw_clip_unfilled.c create mode 100644 src/gallium/drivers/i965simple/brw_clip_util.c create mode 100644 src/gallium/drivers/i965simple/brw_context.c create mode 100644 src/gallium/drivers/i965simple/brw_context.h create mode 100644 src/gallium/drivers/i965simple/brw_curbe.c create mode 100644 src/gallium/drivers/i965simple/brw_defines.h create mode 100644 src/gallium/drivers/i965simple/brw_draw.c create mode 100644 src/gallium/drivers/i965simple/brw_draw.h create mode 100644 src/gallium/drivers/i965simple/brw_draw_upload.c create mode 100644 src/gallium/drivers/i965simple/brw_eu.c create mode 100644 src/gallium/drivers/i965simple/brw_eu.h create mode 100644 src/gallium/drivers/i965simple/brw_eu_debug.c create mode 100644 src/gallium/drivers/i965simple/brw_eu_emit.c create mode 100644 src/gallium/drivers/i965simple/brw_eu_util.c create mode 100644 src/gallium/drivers/i965simple/brw_flush.c create mode 100644 src/gallium/drivers/i965simple/brw_gs.c create mode 100644 src/gallium/drivers/i965simple/brw_gs.h create mode 100644 src/gallium/drivers/i965simple/brw_gs_emit.c create mode 100644 src/gallium/drivers/i965simple/brw_gs_state.c create mode 100644 src/gallium/drivers/i965simple/brw_misc_state.c create mode 100644 src/gallium/drivers/i965simple/brw_reg.h create mode 100644 src/gallium/drivers/i965simple/brw_sf.c create mode 100644 src/gallium/drivers/i965simple/brw_sf.h create mode 100644 src/gallium/drivers/i965simple/brw_sf_emit.c create mode 100644 src/gallium/drivers/i965simple/brw_sf_state.c create mode 100644 src/gallium/drivers/i965simple/brw_shader_info.c create mode 100644 src/gallium/drivers/i965simple/brw_state.c create mode 100644 src/gallium/drivers/i965simple/brw_state.h create mode 100644 src/gallium/drivers/i965simple/brw_state_batch.c create mode 100644 src/gallium/drivers/i965simple/brw_state_cache.c create mode 100644 src/gallium/drivers/i965simple/brw_state_pool.c create mode 100644 src/gallium/drivers/i965simple/brw_state_upload.c create mode 100644 src/gallium/drivers/i965simple/brw_strings.c create mode 100644 src/gallium/drivers/i965simple/brw_structs.h create mode 100644 src/gallium/drivers/i965simple/brw_surface.c create mode 100644 src/gallium/drivers/i965simple/brw_tex_layout.c create mode 100644 src/gallium/drivers/i965simple/brw_tex_layout.h create mode 100644 src/gallium/drivers/i965simple/brw_urb.c create mode 100644 src/gallium/drivers/i965simple/brw_util.c create mode 100644 src/gallium/drivers/i965simple/brw_util.h create mode 100644 src/gallium/drivers/i965simple/brw_vs.c create mode 100644 src/gallium/drivers/i965simple/brw_vs.h create mode 100644 src/gallium/drivers/i965simple/brw_vs_emit.c create mode 100644 src/gallium/drivers/i965simple/brw_vs_state.c create mode 100644 src/gallium/drivers/i965simple/brw_winsys.h create mode 100644 src/gallium/drivers/i965simple/brw_wm.c create mode 100644 src/gallium/drivers/i965simple/brw_wm.h create mode 100644 src/gallium/drivers/i965simple/brw_wm_decl.c create mode 100644 src/gallium/drivers/i965simple/brw_wm_glsl.c create mode 100644 src/gallium/drivers/i965simple/brw_wm_iz.c create mode 100644 src/gallium/drivers/i965simple/brw_wm_sampler_state.c create mode 100644 src/gallium/drivers/i965simple/brw_wm_state.c create mode 100644 src/gallium/drivers/i965simple/brw_wm_surface_state.c create mode 100644 src/gallium/drivers/softpipe/Makefile create mode 100644 src/gallium/drivers/softpipe/SConscript create mode 100644 src/gallium/drivers/softpipe/sp_clear.c create mode 100644 src/gallium/drivers/softpipe/sp_clear.h create mode 100644 src/gallium/drivers/softpipe/sp_context.c create mode 100644 src/gallium/drivers/softpipe/sp_context.h create mode 100644 src/gallium/drivers/softpipe/sp_draw_arrays.c create mode 100644 src/gallium/drivers/softpipe/sp_flush.c create mode 100644 src/gallium/drivers/softpipe/sp_flush.h create mode 100644 src/gallium/drivers/softpipe/sp_headers.h create mode 100644 src/gallium/drivers/softpipe/sp_prim_setup.c create mode 100644 src/gallium/drivers/softpipe/sp_prim_setup.h create mode 100644 src/gallium/drivers/softpipe/sp_prim_vbuf.c create mode 100644 src/gallium/drivers/softpipe/sp_prim_vbuf.h create mode 100644 src/gallium/drivers/softpipe/sp_quad.c create mode 100644 src/gallium/drivers/softpipe/sp_quad.h create mode 100644 src/gallium/drivers/softpipe/sp_quad_alpha_test.c create mode 100644 src/gallium/drivers/softpipe/sp_quad_blend.c create mode 100644 src/gallium/drivers/softpipe/sp_quad_bufloop.c create mode 100644 src/gallium/drivers/softpipe/sp_quad_colormask.c create mode 100644 src/gallium/drivers/softpipe/sp_quad_coverage.c create mode 100644 src/gallium/drivers/softpipe/sp_quad_depth_test.c create mode 100644 src/gallium/drivers/softpipe/sp_quad_earlyz.c create mode 100644 src/gallium/drivers/softpipe/sp_quad_fs.c create mode 100644 src/gallium/drivers/softpipe/sp_quad_occlusion.c create mode 100644 src/gallium/drivers/softpipe/sp_quad_output.c create mode 100644 src/gallium/drivers/softpipe/sp_quad_stencil.c create mode 100644 src/gallium/drivers/softpipe/sp_quad_stipple.c create mode 100644 src/gallium/drivers/softpipe/sp_query.c create mode 100644 src/gallium/drivers/softpipe/sp_query.h create mode 100644 src/gallium/drivers/softpipe/sp_state.h create mode 100644 src/gallium/drivers/softpipe/sp_state_blend.c create mode 100644 src/gallium/drivers/softpipe/sp_state_clip.c create mode 100644 src/gallium/drivers/softpipe/sp_state_derived.c create mode 100644 src/gallium/drivers/softpipe/sp_state_fs.c create mode 100644 src/gallium/drivers/softpipe/sp_state_rasterizer.c create mode 100644 src/gallium/drivers/softpipe/sp_state_sampler.c create mode 100644 src/gallium/drivers/softpipe/sp_state_surface.c create mode 100644 src/gallium/drivers/softpipe/sp_state_vertex.c create mode 100644 src/gallium/drivers/softpipe/sp_surface.c create mode 100644 src/gallium/drivers/softpipe/sp_surface.h create mode 100644 src/gallium/drivers/softpipe/sp_tex_sample.c create mode 100644 src/gallium/drivers/softpipe/sp_tex_sample.h create mode 100644 src/gallium/drivers/softpipe/sp_texture.c create mode 100644 src/gallium/drivers/softpipe/sp_texture.h create mode 100644 src/gallium/drivers/softpipe/sp_tile_cache.c create mode 100644 src/gallium/drivers/softpipe/sp_tile_cache.h create mode 100644 src/gallium/drivers/softpipe/sp_winsys.h create mode 100644 src/gallium/include/pipe/p_compiler.h create mode 100644 src/gallium/include/pipe/p_context.h create mode 100644 src/gallium/include/pipe/p_debug.h create mode 100644 src/gallium/include/pipe/p_defines.h create mode 100644 src/gallium/include/pipe/p_format.h create mode 100644 src/gallium/include/pipe/p_inlines.h create mode 100644 src/gallium/include/pipe/p_shader_tokens.h create mode 100644 src/gallium/include/pipe/p_state.h create mode 100644 src/gallium/include/pipe/p_thread.h create mode 100644 src/gallium/include/pipe/p_util.h create mode 100644 src/gallium/include/pipe/p_winsys.h create mode 100644 src/gallium/winsys/dri/intel/Makefile create mode 100644 src/gallium/winsys/dri/intel/SConscript create mode 100644 src/gallium/winsys/dri/intel/intel_batchbuffer.c create mode 100644 src/gallium/winsys/dri/intel/intel_batchbuffer.h create mode 100644 src/gallium/winsys/dri/intel/intel_batchpool.c create mode 100644 src/gallium/winsys/dri/intel/intel_batchpool.h create mode 100644 src/gallium/winsys/dri/intel/intel_context.c create mode 100644 src/gallium/winsys/dri/intel/intel_context.h create mode 100644 src/gallium/winsys/dri/intel/intel_lock.c create mode 100644 src/gallium/winsys/dri/intel/intel_reg.h create mode 100644 src/gallium/winsys/dri/intel/intel_screen.c create mode 100644 src/gallium/winsys/dri/intel/intel_screen.h create mode 100644 src/gallium/winsys/dri/intel/intel_swapbuffers.c create mode 100644 src/gallium/winsys/dri/intel/intel_swapbuffers.h create mode 100644 src/gallium/winsys/dri/intel/intel_winsys.h create mode 100644 src/gallium/winsys/dri/intel/intel_winsys_i915.c create mode 100644 src/gallium/winsys/dri/intel/intel_winsys_pipe.c create mode 100644 src/gallium/winsys/dri/intel/intel_winsys_softpipe.c create mode 100644 src/gallium/winsys/dri/intel/server/i830_common.h create mode 100644 src/gallium/winsys/dri/intel/server/i830_dri.h create mode 100644 src/gallium/winsys/dri/intel/server/intel.h create mode 100644 src/gallium/winsys/dri/intel/server/intel_dri.c create mode 100644 src/gallium/winsys/xlib/brw_aub.c create mode 100644 src/gallium/winsys/xlib/brw_aub.h create mode 100644 src/gallium/winsys/xlib/fakeglx.c create mode 100644 src/gallium/winsys/xlib/glxapi.c create mode 100644 src/gallium/winsys/xlib/glxapi.h create mode 100644 src/gallium/winsys/xlib/glxheader.h create mode 100644 src/gallium/winsys/xlib/realglx.c create mode 100644 src/gallium/winsys/xlib/realglx.h create mode 100644 src/gallium/winsys/xlib/xfonts.c create mode 100644 src/gallium/winsys/xlib/xfonts.h create mode 100644 src/gallium/winsys/xlib/xm_api.c create mode 100644 src/gallium/winsys/xlib/xm_image.c create mode 100644 src/gallium/winsys/xlib/xm_image.h create mode 100644 src/gallium/winsys/xlib/xm_winsys.c create mode 100644 src/gallium/winsys/xlib/xm_winsys_aub.c create mode 100644 src/gallium/winsys/xlib/xm_winsys_aub.h create mode 100644 src/gallium/winsys/xlib/xmesaP.h (limited to 'src/gallium') diff --git a/src/gallium/Makefile b/src/gallium/Makefile new file mode 100644 index 0000000000..d880d090c1 --- /dev/null +++ b/src/gallium/Makefile @@ -0,0 +1,28 @@ +TOP = ../../.. +include $(TOP)/configs/current + + +ifeq ($(CONFIG_NAME), linux-cell) +CELL_DIR = cell +endif + +ifeq ($(CONFIG_NAME), linux-llvm) +LLVM_DIR = llvm +endif + +SUBDIRS = softpipe i915simple i965simple failover pipebuffer $(CELL_DIR) $(LLVM_DIR) + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template new file mode 100644 index 0000000000..8e84f8eb2d --- /dev/null +++ b/src/gallium/Makefile.template @@ -0,0 +1,63 @@ +# -*-makefile-*- + + +# We still have a dependency on the "dri" buffer manager. Most likely +# the interface can be reused in non-dri environments, and also as a +# frontend to simpler memory managers. +# +COMMON_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(CPP_SOURCES:.cpp=.o) \ + $(ASM_SOURCES:.S=.o) + + +### Include directories +INCLUDES = \ + -I. \ + -I$(TOP)/src/mesa/pipe \ + -I$(TOP)/src/mesa \ + -I$(TOP)/include \ + $(DRIVER_INCLUDES) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) + + +$(LIBNAME): $(OBJECTS) Makefile $(TOP)/src/mesa/pipe/Makefile.template + $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) + + +depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean:: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +include depend diff --git a/src/gallium/README.portability b/src/gallium/README.portability new file mode 100644 index 0000000000..c70ca774da --- /dev/null +++ b/src/gallium/README.portability @@ -0,0 +1,43 @@ + CROSS-PLATFORM PORTABILITY GUIDELINES FOR GALLIUM3D + + += General Considerations = + +The state tracker and winsys driver support a rather limited number of +platforms. However, the pipe drivers are meant to run in a wide number of +platforms. Hence the pipe drivers, the auxiliary modules, and all public +headers in general, should stricly follow these guidelines to ensure + + += Compiler Support = + +* Include the p_compiler.h. + +* Don't use the 'inline' keyword, use the INLINE macro in p_compiler.h instead. + +* Cast explicitly when converting to integer types of smaller sizes. + +* Cast explicitly when converting between float, double and integral types. + +* Don't use named struct initializers. + +* Don't use variable number of macro arguments. Use static inline functions +instead. + + += Standard Library = + +* Avoid including standard library headers. Most standard library functions are +not available in Windows Kernel Mode. Use the appropriate p_*.h include. + +== Memory Allocation == + +* Use MALLOC, CALLOC, FREE instead of the malloc, calloc, free functions. + +* Use align_pointer() function defined in p_util.h for aligning pointers in a +portable way. + +== Debugging == + +TODO + diff --git a/src/gallium/SConscript b/src/gallium/SConscript new file mode 100644 index 0000000000..d9c20e0100 --- /dev/null +++ b/src/gallium/SConscript @@ -0,0 +1,9 @@ +Import('*') + +#env = env.Clone() + +SConscript([ + 'softpipe/SConscript', + 'i915simple/SConscript', + 'i965simple/SConscript', +]) diff --git a/src/gallium/aux/cso_cache/cso_cache.c b/src/gallium/aux/cso_cache/cso_cache.c new file mode 100644 index 0000000000..9e77e0774d --- /dev/null +++ b/src/gallium/aux/cso_cache/cso_cache.c @@ -0,0 +1,181 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Zack Rusin + */ + +#include "cso_cache.h" +#include "cso_hash.h" + +#if 1 +static unsigned hash_key(const void *key, unsigned key_size) +{ + unsigned *ikey = (unsigned *)key; + unsigned hash = 0, i; + + assert(key_size % 4 == 0); + + /* I'm sure this can be improved on: + */ + for (i = 0; i < key_size/4; i++) + hash ^= ikey[i]; + + return hash; +} +#else +static unsigned hash_key(const unsigned char *p, int n) +{ + unsigned h = 0; + unsigned g; + + while (n--) { + h = (h << 4) + *p++; + if ((g = (h & 0xf0000000)) != 0) + h ^= g >> 23; + h &= ~g; + } + return h; +} +#endif + +unsigned cso_construct_key(void *item, int item_size) +{ + return hash_key((item), item_size); +} + +static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_type type) +{ + struct cso_hash *hash = 0; + + switch(type) { + case CSO_BLEND: + hash = sc->blend_hash; + break; + case CSO_SAMPLER: + hash = sc->sampler_hash; + break; + case CSO_DEPTH_STENCIL_ALPHA: + hash = sc->depth_stencil_hash; + break; + case CSO_RASTERIZER: + hash = sc->rasterizer_hash; + break; + case CSO_FRAGMENT_SHADER: + hash = sc->fs_hash; + break; + case CSO_VERTEX_SHADER: + hash = sc->vs_hash; + break; + } + + return hash; +} + +static int _cso_size_for_type(enum cso_cache_type type) +{ + switch(type) { + case CSO_BLEND: + return sizeof(struct pipe_blend_state); + case CSO_SAMPLER: + return sizeof(struct pipe_sampler_state); + case CSO_DEPTH_STENCIL_ALPHA: + return sizeof(struct pipe_depth_stencil_alpha_state); + case CSO_RASTERIZER: + return sizeof(struct pipe_rasterizer_state); + case CSO_FRAGMENT_SHADER: + return sizeof(struct pipe_shader_state); + case CSO_VERTEX_SHADER: + return sizeof(struct pipe_shader_state); + } + return 0; +} + +struct cso_hash_iter +cso_insert_state(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type, + void *state) +{ + struct cso_hash *hash = _cso_hash_for_type(sc, type); + return cso_hash_insert(hash, hash_key, state); +} + +struct cso_hash_iter +cso_find_state(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type) +{ + struct cso_hash *hash = _cso_hash_for_type(sc, type); + + return cso_hash_find(hash, hash_key); +} + +struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type, + void *templ) +{ + struct cso_hash_iter iter = cso_find_state(sc, hash_key, type); + int size = _cso_size_for_type(type); + while (!cso_hash_iter_is_null(iter)) { + void *iter_data = cso_hash_iter_data(iter); + if (!memcmp(iter_data, templ, size)) + return iter; + iter = cso_hash_iter_next(iter); + } + return iter; +} + +void * cso_take_state(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type) +{ + struct cso_hash *hash = _cso_hash_for_type(sc, type); + return cso_hash_take(hash, hash_key); +} + +struct cso_cache *cso_cache_create(void) +{ + struct cso_cache *sc = malloc(sizeof(struct cso_cache)); + + sc->blend_hash = cso_hash_create(); + sc->sampler_hash = cso_hash_create(); + sc->depth_stencil_hash = cso_hash_create(); + sc->rasterizer_hash = cso_hash_create(); + sc->fs_hash = cso_hash_create(); + sc->vs_hash = cso_hash_create(); + + return sc; +} + +void cso_cache_delete(struct cso_cache *sc) +{ + assert(sc); + cso_hash_delete(sc->blend_hash); + cso_hash_delete(sc->sampler_hash); + cso_hash_delete(sc->depth_stencil_hash); + cso_hash_delete(sc->rasterizer_hash); + cso_hash_delete(sc->fs_hash); + cso_hash_delete(sc->vs_hash); + free(sc); +} diff --git a/src/gallium/aux/cso_cache/cso_cache.h b/src/gallium/aux/cso_cache/cso_cache.h new file mode 100644 index 0000000000..116e2eaa2c --- /dev/null +++ b/src/gallium/aux/cso_cache/cso_cache.h @@ -0,0 +1,107 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin + */ + +#ifndef CSO_CACHE_H +#define CSO_CACHE_H + +#include "pipe/p_context.h" +#include "pipe/p_state.h" + + +struct cso_hash; + +struct cso_cache { + struct cso_hash *blend_hash; + struct cso_hash *depth_stencil_hash; + struct cso_hash *fs_hash; + struct cso_hash *vs_hash; + struct cso_hash *rasterizer_hash; + struct cso_hash *sampler_hash; +}; + +struct cso_blend { + struct pipe_blend_state state; + void *data; +}; + +struct cso_depth_stencil_alpha { + struct pipe_depth_stencil_alpha_state state; + void *data; +}; + +struct cso_rasterizer { + struct pipe_rasterizer_state state; + void *data; +}; + +struct cso_fragment_shader { + struct pipe_shader_state state; + void *data; +}; + +struct cso_vertex_shader { + struct pipe_shader_state state; + void *data; +}; + +struct cso_sampler { + struct pipe_sampler_state state; + void *data; +}; + + +enum cso_cache_type { + CSO_BLEND, + CSO_SAMPLER, + CSO_DEPTH_STENCIL_ALPHA, + CSO_RASTERIZER, + CSO_FRAGMENT_SHADER, + CSO_VERTEX_SHADER +}; + +unsigned cso_construct_key(void *item, int item_size); + +struct cso_cache *cso_cache_create(void); +void cso_cache_delete(struct cso_cache *sc); + +struct cso_hash_iter cso_insert_state(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type, + void *state); +struct cso_hash_iter cso_find_state(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type); +struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type, + void *templ); +void * cso_take_state(struct cso_cache *sc, unsigned hash_key, + enum cso_cache_type type); + +#endif diff --git a/src/gallium/aux/cso_cache/cso_hash.c b/src/gallium/aux/cso_cache/cso_hash.c new file mode 100644 index 0000000000..0338cb3b47 --- /dev/null +++ b/src/gallium/aux/cso_cache/cso_hash.c @@ -0,0 +1,388 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin + */ + +#include "cso_hash.h" + +#include +#include +#include +#include + +#define MAX(a, b) ((a > b) ? (a) : (b)) + +static const int MinNumBits = 4; + +static const unsigned char prime_deltas[] = { + 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3, + 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0 +}; + +static int primeForNumBits(int numBits) +{ + return (1 << numBits) + prime_deltas[numBits]; +} + +/* + Returns the smallest integer n such that + primeForNumBits(n) >= hint. +*/ +static int countBits(int hint) +{ + int numBits = 0; + int bits = hint; + + while (bits > 1) { + bits >>= 1; + numBits++; + } + + if (numBits >= (int)sizeof(prime_deltas)) { + numBits = sizeof(prime_deltas) - 1; + } else if (primeForNumBits(numBits) < hint) { + ++numBits; + } + return numBits; +} + +struct cso_node { + struct cso_node *next; + unsigned key; + void *value; +}; + +struct cso_hash_data { + struct cso_node *fakeNext; + struct cso_node **buckets; + int size; + int nodeSize; + short userNumBits; + short numBits; + int numBuckets; +}; + +struct cso_hash { + union { + struct cso_hash_data *d; + struct cso_node *e; + } data; +}; + +static void *cso_data_allocate_node(struct cso_hash_data *hash) +{ + return malloc(hash->nodeSize); +} + +static void cso_data_free_node(struct cso_node *node) +{ + /* XXX still a leak here. + * Need to cast value ptr to original cso type, then free the + * driver-specific data hanging off of it. For example: + struct cso_sampler *csamp = (struct cso_sampler *) node->value; + free(csamp->data); + */ + free(node->value); + free(node); +} + +static struct cso_node * +cso_hash_create_node(struct cso_hash *hash, + unsigned akey, void *avalue, + struct cso_node **anextNode) +{ + struct cso_node *node = cso_data_allocate_node(hash->data.d); + node->key = akey; + node->value = avalue; + + node->next = (struct cso_node*)(*anextNode); + *anextNode = node; + ++hash->data.d->size; + return node; +} + +static void cso_data_rehash(struct cso_hash_data *hash, int hint) +{ + if (hint < 0) { + hint = countBits(-hint); + if (hint < MinNumBits) + hint = MinNumBits; + hash->userNumBits = hint; + while (primeForNumBits(hint) < (hash->size >> 1)) + ++hint; + } else if (hint < MinNumBits) { + hint = MinNumBits; + } + + if (hash->numBits != hint) { + struct cso_node *e = (struct cso_node *)(hash); + struct cso_node **oldBuckets = hash->buckets; + int oldNumBuckets = hash->numBuckets; + int i = 0; + + hash->numBits = hint; + hash->numBuckets = primeForNumBits(hint); + hash->buckets = malloc(sizeof(struct cso_node*) * hash->numBuckets); + for (i = 0; i < hash->numBuckets; ++i) + hash->buckets[i] = e; + + for (i = 0; i < oldNumBuckets; ++i) { + struct cso_node *firstNode = oldBuckets[i]; + while (firstNode != e) { + unsigned h = firstNode->key; + struct cso_node *lastNode = firstNode; + while (lastNode->next != e && lastNode->next->key == h) + lastNode = lastNode->next; + + struct cso_node *afterLastNode = lastNode->next; + struct cso_node **beforeFirstNode = &hash->buckets[h % hash->numBuckets]; + while (*beforeFirstNode != e) + beforeFirstNode = &(*beforeFirstNode)->next; + lastNode->next = *beforeFirstNode; + *beforeFirstNode = firstNode; + firstNode = afterLastNode; + } + } + free(oldBuckets); + } +} + +static void cso_data_might_grow(struct cso_hash_data *hash) +{ + if (hash->size >= hash->numBuckets) + cso_data_rehash(hash, hash->numBits + 1); +} + +static void cso_data_has_shrunk(struct cso_hash_data *hash) +{ + if (hash->size <= (hash->numBuckets >> 3) && + hash->numBits > hash->userNumBits) { + int max = MAX(hash->numBits-2, hash->userNumBits); + cso_data_rehash(hash, max); + } +} + +static struct cso_node *cso_data_first_node(struct cso_hash_data *hash) +{ + struct cso_node *e = (struct cso_node *)(hash); + struct cso_node **bucket = hash->buckets; + int n = hash->numBuckets; + while (n--) { + if (*bucket != e) + return *bucket; + ++bucket; + } + return e; +} + +static struct cso_node **cso_hash_find_node(struct cso_hash *hash, unsigned akey) +{ + struct cso_node **node; + + if (hash->data.d->numBuckets) { + node = (struct cso_node **)(&hash->data.d->buckets[akey % hash->data.d->numBuckets]); + assert(*node == hash->data.e || (*node)->next); + while (*node != hash->data.e && (*node)->key != akey) + node = &(*node)->next; + } else { + node = (struct cso_node **)((const struct cso_node * const *)(&hash->data.e)); + } + return node; +} + +struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, + unsigned key, void *data) +{ + cso_data_might_grow(hash->data.d); + + struct cso_node **nextNode = cso_hash_find_node(hash, key); + struct cso_node *node = cso_hash_create_node(hash, key, data, nextNode); + struct cso_hash_iter iter = {hash, node}; + return iter; +} + +struct cso_hash * cso_hash_create(void) +{ + struct cso_hash *hash = malloc(sizeof(struct cso_hash)); + hash->data.d = malloc(sizeof(struct cso_hash_data)); + hash->data.d->fakeNext = 0; + hash->data.d->buckets = 0; + hash->data.d->size = 0; + hash->data.d->nodeSize = sizeof(struct cso_node); + hash->data.d->userNumBits = MinNumBits; + hash->data.d->numBits = 0; + hash->data.d->numBuckets = 0; + + return hash; +} + +void cso_hash_delete(struct cso_hash *hash) +{ + struct cso_node *e_for_x = (struct cso_node *)(hash->data.d); + struct cso_node **bucket = (struct cso_node **)(hash->data.d->buckets); + int n = hash->data.d->numBuckets; + while (n--) { + struct cso_node *cur = *bucket++; + while (cur != e_for_x) { + struct cso_node *next = cur->next; + cso_data_free_node(cur); + cur = next; + } + } + free(hash->data.d->buckets); + free(hash->data.d); + free(hash); +} + +struct cso_hash_iter cso_hash_find(struct cso_hash *hash, + unsigned key) +{ + struct cso_node **nextNode = cso_hash_find_node(hash, key); + struct cso_hash_iter iter = {hash, *nextNode}; + return iter; +} + +unsigned cso_hash_iter_key(struct cso_hash_iter iter) +{ + if (!iter.node || iter.hash->data.e == iter.node) + return 0; + return iter.node->key; +} + +void * cso_hash_iter_data(struct cso_hash_iter iter) +{ + if (!iter.node || iter.hash->data.e == iter.node) + return 0; + return iter.node->value; +} + +static struct cso_node *cso_hash_data_next(struct cso_node *node) +{ + union { + struct cso_node *next; + struct cso_node *e; + struct cso_hash_data *d; + } a; + a.next = node->next; + if (!a.next) { + fprintf(stderr, "iterating beyond the last element\n"); + return 0; + } + if (a.next->next) + return a.next; + + int start = (node->key % a.d->numBuckets) + 1; + struct cso_node **bucket = a.d->buckets + start; + int n = a.d->numBuckets - start; + while (n--) { + if (*bucket != a.e) + return *bucket; + ++bucket; + } + return a.e; +} + + +static struct cso_node *cso_hash_data_prev(struct cso_node *node) +{ + union { + struct cso_node *e; + struct cso_hash_data *d; + } a; + + a.e = node; + while (a.e->next) + a.e = a.e->next; + + int start; + if (node == a.e) + start = a.d->numBuckets - 1; + else + start = node->key % a.d->numBuckets; + + struct cso_node *sentinel = node; + struct cso_node **bucket = a.d->buckets + start; + while (start >= 0) { + if (*bucket != sentinel) { + struct cso_node *prev = *bucket; + while (prev->next != sentinel) + prev = prev->next; + return prev; + } + + sentinel = a.e; + --bucket; + --start; + } + fprintf(stderr, "iterating backward beyond first element\n"); + return a.e; +} + +struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter) +{ + struct cso_hash_iter next = {iter.hash, cso_hash_data_next(iter.node)}; + return next; +} + +int cso_hash_iter_is_null(struct cso_hash_iter iter) +{ + if (!iter.node || iter.node == iter.hash->data.e) + return 1; + return 0; +} + +void * cso_hash_take(struct cso_hash *hash, + unsigned akey) +{ + struct cso_node **node = cso_hash_find_node(hash, akey); + if (*node != hash->data.e) { + void *t = (*node)->value; + struct cso_node *next = (*node)->next; + cso_data_free_node(*node); + *node = next; + --hash->data.d->size; + cso_data_has_shrunk(hash->data.d); + return t; + } + return 0; +} + +struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter) +{ + struct cso_hash_iter prev = {iter.hash, + cso_hash_data_prev(iter.node)}; + return prev; +} + +struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash) +{ + struct cso_hash_iter iter = {hash, cso_data_first_node(hash->data.d)}; + return iter; +} diff --git a/src/gallium/aux/cso_cache/cso_hash.h b/src/gallium/aux/cso_cache/cso_hash.h new file mode 100644 index 0000000000..b4aa111860 --- /dev/null +++ b/src/gallium/aux/cso_cache/cso_hash.h @@ -0,0 +1,62 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin + */ + +#ifndef CSO_HASH_H +#define CSO_HASH_H + +struct cso_hash; +struct cso_node; + +struct cso_hash_iter { + struct cso_hash *hash; + struct cso_node *node; +}; + +struct cso_hash *cso_hash_create(void); +void cso_hash_delete(struct cso_hash *hash); + +struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, unsigned key, + void *data); +void *cso_hash_take(struct cso_hash *hash, unsigned key); + +struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash); +struct cso_hash_iter cso_hash_find(struct cso_hash *hash, unsigned key); + + +int cso_hash_iter_is_null(struct cso_hash_iter iter); +unsigned cso_hash_iter_key(struct cso_hash_iter iter); +void *cso_hash_iter_data(struct cso_hash_iter iter); + +struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter); +struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter); + +#endif diff --git a/src/gallium/aux/draw/Makefile b/src/gallium/aux/draw/Makefile new file mode 100644 index 0000000000..451911a354 --- /dev/null +++ b/src/gallium/aux/draw/Makefile @@ -0,0 +1,2 @@ +default: + cd .. ; make diff --git a/src/gallium/aux/draw/draw_clip.c b/src/gallium/aux/draw/draw_clip.c new file mode 100644 index 0000000000..e3051507ea --- /dev/null +++ b/src/gallium/aux/draw/draw_clip.c @@ -0,0 +1,488 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Clipping stage + * + * \author Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#include "draw_context.h" +#include "draw_private.h" + + +#ifndef IS_NEGATIVE +#define IS_NEGATIVE(X) ((X) < 0.0) +#endif + +#ifndef DIFFERENT_SIGNS +#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F) +#endif + +#ifndef MAX_CLIPPED_VERTICES +#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1) +#endif + + + +struct clipper { + struct draw_stage stage; /**< base class */ + + /* Basically duplicate some of the flatshading logic here: + */ + boolean flat; + uint num_color_attribs; + uint color_attribs[4]; /* front/back primary/secondary colors */ + + float (*plane)[4]; +}; + + +/* This is a bit confusing: + */ +static INLINE struct clipper *clipper_stage( struct draw_stage *stage ) +{ + return (struct clipper *)stage; +} + + +#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT))) + + +/* All attributes are float[4], so this is easy: + */ +static void interp_attr( float *fdst, + float t, + const float *fin, + const float *fout ) +{ + fdst[0] = LINTERP( t, fout[0], fin[0] ); + fdst[1] = LINTERP( t, fout[1], fin[1] ); + fdst[2] = LINTERP( t, fout[2], fin[2] ); + fdst[3] = LINTERP( t, fout[3], fin[3] ); +} + +static void copy_colors( struct draw_stage *stage, + struct vertex_header *dst, + const struct vertex_header *src ) +{ + const struct clipper *clipper = clipper_stage(stage); + uint i; + for (i = 0; i < clipper->num_color_attribs; i++) { + const uint attr = clipper->color_attribs[i]; + COPY_4FV(dst->data[attr], src->data[attr]); + } +} + + + +/* Interpolate between two vertices to produce a third. + */ +static void interp( const struct clipper *clip, + struct vertex_header *dst, + float t, + const struct vertex_header *out, + const struct vertex_header *in ) +{ + const unsigned nr_attrs = clip->stage.draw->num_vs_outputs; + unsigned j; + + /* Vertex header. + */ + { + dst->clipmask = 0; + dst->edgeflag = 0; + dst->pad = 0; + dst->vertex_id = UNDEFINED_VERTEX_ID; + } + + /* Clip coordinates: interpolate normally + */ + { + interp_attr(dst->clip, t, in->clip, out->clip); + } + + /* Do the projective divide and insert window coordinates: + */ + { + const float *pos = dst->clip; + const float *scale = clip->stage.draw->viewport.scale; + const float *trans = clip->stage.draw->viewport.translate; + const float oow = 1.0f / pos[3]; + + dst->data[0][0] = pos[0] * oow * scale[0] + trans[0]; + dst->data[0][1] = pos[1] * oow * scale[1] + trans[1]; + dst->data[0][2] = pos[2] * oow * scale[2] + trans[2]; + dst->data[0][3] = oow; + } + + /* Other attributes + * Note: start at 1 to skip winpos (data[0]) since we just computed + * it above. + */ + for (j = 1; j < nr_attrs; j++) { + interp_attr(dst->data[j], t, in->data[j], out->data[j]); + } +} + + +static void emit_poly( struct draw_stage *stage, + struct vertex_header **inlist, + unsigned n, + const struct prim_header *origPrim) +{ + struct prim_header header; + unsigned i; + + /* later stages may need the determinant, but only the sign matters */ + header.det = origPrim->det; + + for (i = 2; i < n; i++) { + header.v[0] = inlist[i-1]; + header.v[1] = inlist[i]; + header.v[2] = inlist[0]; /* keep in v[2] for flatshading */ + + { + unsigned tmp1 = header.v[1]->edgeflag; + unsigned tmp2 = header.v[2]->edgeflag; + + if (i != n-1) header.v[1]->edgeflag = 0; + if (i != 2) header.v[2]->edgeflag = 0; + + header.edgeflags = ((header.v[0]->edgeflag << 0) | + (header.v[1]->edgeflag << 1) | + (header.v[2]->edgeflag << 2)); + + stage->next->tri( stage->next, &header ); + + header.v[1]->edgeflag = tmp1; + header.v[2]->edgeflag = tmp2; + } + } +} + + + + +/* Clip a triangle against the viewport and user clip planes. + */ +static void +do_clip_tri( struct draw_stage *stage, + struct prim_header *header, + unsigned clipmask ) +{ + struct clipper *clipper = clipper_stage( stage ); + struct vertex_header *a[MAX_CLIPPED_VERTICES]; + struct vertex_header *b[MAX_CLIPPED_VERTICES]; + struct vertex_header **inlist = a; + struct vertex_header **outlist = b; + unsigned tmpnr = 0; + unsigned n = 3; + unsigned i; + + inlist[0] = header->v[0]; + inlist[1] = header->v[1]; + inlist[2] = header->v[2]; + + while (clipmask && n >= 3) { + const unsigned plane_idx = ffs(clipmask)-1; + const float *plane = clipper->plane[plane_idx]; + struct vertex_header *vert_prev = inlist[0]; + float dp_prev = dot4( vert_prev->clip, plane ); + unsigned outcount = 0; + + clipmask &= ~(1<clip, plane ); + + if (!IS_NEGATIVE(dp_prev)) { + outlist[outcount++] = vert_prev; + } + + if (DIFFERENT_SIGNS(dp, dp_prev)) { + struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++]; + outlist[outcount++] = new_vert; + + if (IS_NEGATIVE(dp)) { + /* Going out of bounds. Avoid division by zero as we + * know dp != dp_prev from DIFFERENT_SIGNS, above. + */ + float t = dp / (dp - dp_prev); + interp( clipper, new_vert, t, vert, vert_prev ); + + /* Force edgeflag true in this case: + */ + new_vert->edgeflag = 1; + } else { + /* Coming back in. + */ + float t = dp_prev / (dp_prev - dp); + interp( clipper, new_vert, t, vert_prev, vert ); + + /* Copy starting vert's edgeflag: + */ + new_vert->edgeflag = vert_prev->edgeflag; + } + } + + vert_prev = vert; + dp_prev = dp; + } + + { + struct vertex_header **tmp = inlist; + inlist = outlist; + outlist = tmp; + n = outcount; + } + } + + /* If flat-shading, copy color to new provoking vertex. + */ + if (clipper->flat && inlist[0] != header->v[2]) { + if (1) { + inlist[0] = dup_vert(stage, inlist[0], tmpnr++); + } + + copy_colors(stage, inlist[0], header->v[2]); + } + + + + /* Emit the polygon as triangles to the setup stage: + */ + if (n >= 3) + emit_poly( stage, inlist, n, header ); +} + + +/* Clip a line against the viewport and user clip planes. + */ +static void +do_clip_line( struct draw_stage *stage, + struct prim_header *header, + unsigned clipmask ) +{ + const struct clipper *clipper = clipper_stage( stage ); + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + const float *pos0 = v0->clip; + const float *pos1 = v1->clip; + float t0 = 0.0F; + float t1 = 0.0F; + struct prim_header newprim; + + while (clipmask) { + const unsigned plane_idx = ffs(clipmask)-1; + const float *plane = clipper->plane[plane_idx]; + const float dp0 = dot4( pos0, plane ); + const float dp1 = dot4( pos1, plane ); + + if (dp1 < 0.0F) { + float t = dp1 / (dp1 - dp0); + t1 = MAX2(t1, t); + } + + if (dp0 < 0.0F) { + float t = dp0 / (dp0 - dp1); + t0 = MAX2(t0, t); + } + + if (t0 + t1 >= 1.0F) + return; /* discard */ + + clipmask &= ~(1 << plane_idx); /* turn off this plane's bit */ + } + + if (v0->clipmask) { + interp( clipper, stage->tmp[0], t0, v0, v1 ); + + if (clipper->flat) + copy_colors(stage, stage->tmp[0], v0); + + newprim.v[0] = stage->tmp[0]; + } + else { + newprim.v[0] = v0; + } + + if (v1->clipmask) { + interp( clipper, stage->tmp[1], t1, v1, v0 ); + newprim.v[1] = stage->tmp[1]; + } + else { + newprim.v[1] = v1; + } + + stage->next->line( stage->next, &newprim ); +} + + +static void +clip_point( struct draw_stage *stage, + struct prim_header *header ) +{ + if (header->v[0]->clipmask == 0) + stage->next->point( stage->next, header ); +} + + +static void +clip_line( struct draw_stage *stage, + struct prim_header *header ) +{ + unsigned clipmask = (header->v[0]->clipmask | + header->v[1]->clipmask); + + if (clipmask == 0) { + /* no clipping needed */ + stage->next->line( stage->next, header ); + } + else if ((header->v[0]->clipmask & + header->v[1]->clipmask) == 0) { + do_clip_line(stage, header, clipmask); + } + /* else, totally clipped */ +} + + +static void +clip_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + unsigned clipmask = (header->v[0]->clipmask | + header->v[1]->clipmask | + header->v[2]->clipmask); + + if (clipmask == 0) { + /* no clipping needed */ + stage->next->tri( stage->next, header ); + } + else if ((header->v[0]->clipmask & + header->v[1]->clipmask & + header->v[2]->clipmask) == 0) { + do_clip_tri(stage, header, clipmask); + } +} + +/* Update state. Could further delay this until we hit the first + * primitive that really requires clipping. + */ +static void +clip_init_state( struct draw_stage *stage ) +{ + struct clipper *clipper = clipper_stage( stage ); + + clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE; + + if (clipper->flat) { + const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; + uint i; + + clipper->num_color_attribs = 0; + for (i = 0; i < vs->num_outputs; i++) { + if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR || + vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + clipper->color_attribs[clipper->num_color_attribs++] = i; + } + } + } + + stage->tri = clip_tri; + stage->line = clip_line; +} + + + +static void clip_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + clip_init_state( stage ); + stage->tri( stage, header ); +} + +static void clip_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + clip_init_state( stage ); + stage->line( stage, header ); +} + + +static void clip_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = clip_first_tri; + stage->line = clip_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void clip_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void clip_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Allocate a new clipper stage. + * \return pointer to new stage object + */ +struct draw_stage *draw_clip_stage( struct draw_context *draw ) +{ + struct clipper *clipper = CALLOC_STRUCT(clipper); + + draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ); + + clipper->stage.draw = draw; + clipper->stage.point = clip_point; + clipper->stage.line = clip_first_line; + clipper->stage.tri = clip_first_tri; + clipper->stage.flush = clip_flush; + clipper->stage.reset_stipple_counter = clip_reset_stipple_counter; + clipper->stage.destroy = clip_destroy; + + clipper->plane = draw->plane; + + return &clipper->stage; +} diff --git a/src/gallium/aux/draw/draw_context.c b/src/gallium/aux/draw/draw_context.c new file mode 100644 index 0000000000..4be3830316 --- /dev/null +++ b/src/gallium/aux/draw/draw_context.c @@ -0,0 +1,293 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "draw_context.h" +#include "draw_private.h" + + + +struct draw_context *draw_create( void ) +{ + struct draw_context *draw = CALLOC_STRUCT( draw_context ); + +#if defined(__i386__) || defined(__386__) + draw->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; +#else + draw->use_sse = FALSE; +#endif + + /* create pipeline stages */ + draw->pipeline.wide = draw_wide_stage( draw ); + draw->pipeline.stipple = draw_stipple_stage( draw ); + draw->pipeline.unfilled = draw_unfilled_stage( draw ); + draw->pipeline.twoside = draw_twoside_stage( draw ); + draw->pipeline.offset = draw_offset_stage( draw ); + draw->pipeline.clip = draw_clip_stage( draw ); + draw->pipeline.flatshade = draw_flatshade_stage( draw ); + draw->pipeline.cull = draw_cull_stage( draw ); + draw->pipeline.validate = draw_validate_stage( draw ); + draw->pipeline.first = draw->pipeline.validate; + + 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 ); + ASSIGN_4V( draw->plane[3], 0, 1, 0, 1 ); + ASSIGN_4V( draw->plane[4], 0, 0, 1, 1 ); /* yes these are correct */ + ASSIGN_4V( draw->plane[5], 0, 0, -1, 1 ); /* mesa's a bit wonky */ + draw->nr_planes = 6; + + /* Statically allocate maximum sized vertices for the cache - could be cleverer... + */ + { + uint i; + const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; + char *tmp = align_malloc(Elements(draw->vcache.vertex) * size, 16); + + for (i = 0; i < Elements(draw->vcache.vertex); i++) + draw->vcache.vertex[i] = (struct vertex_header *)(tmp + i * size); + } + + draw->shader_queue_flush = draw_vertex_shader_queue_flush; + + draw->convert_wide_points = TRUE; + draw->convert_wide_lines = TRUE; + + draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ + + draw_vertex_cache_invalidate( draw ); + draw_set_mapped_element_buffer( draw, 0, NULL ); + + return draw; +} + + +void draw_destroy( struct draw_context *draw ) +{ + draw->pipeline.wide->destroy( draw->pipeline.wide ); + draw->pipeline.stipple->destroy( draw->pipeline.stipple ); + draw->pipeline.unfilled->destroy( draw->pipeline.unfilled ); + draw->pipeline.twoside->destroy( draw->pipeline.twoside ); + draw->pipeline.offset->destroy( draw->pipeline.offset ); + draw->pipeline.clip->destroy( draw->pipeline.clip ); + draw->pipeline.flatshade->destroy( draw->pipeline.flatshade ); + draw->pipeline.cull->destroy( draw->pipeline.cull ); + draw->pipeline.validate->destroy( draw->pipeline.validate ); + if (draw->pipeline.rasterize) + draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); + tgsi_exec_machine_free_data(&draw->machine); + align_free( draw->vcache.vertex[0] ); /* Frees all the vertices. */ + FREE( draw ); +} + + + +void draw_flush( struct draw_context *draw ) +{ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); +} + + + +/** + * Register new primitive rasterization/rendering state. + * This causes the drawing pipeline to be rebuilt. + */ +void draw_set_rasterizer_state( struct draw_context *draw, + const struct pipe_rasterizer_state *raster ) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + draw->rasterizer = raster; +} + + +/** + * Plug in the primitive rendering/rasterization stage (which is the last + * stage in the drawing pipeline). + * This is provided by the device driver. + */ +void draw_set_rasterize_stage( struct draw_context *draw, + struct draw_stage *stage ) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + draw->pipeline.rasterize = stage; +} + + +/** + * Set the draw module's clipping state. + */ +void draw_set_clip_state( struct draw_context *draw, + const struct pipe_clip_state *clip ) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + assert(clip->nr <= PIPE_MAX_CLIP_PLANES); + memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0])); + draw->nr_planes = 6 + clip->nr; +} + + +/** + * Set the draw module's viewport state. + */ +void draw_set_viewport_state( struct draw_context *draw, + const struct pipe_viewport_state *viewport ) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->viewport = *viewport; /* struct copy */ +} + + + +void +draw_set_vertex_buffer(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_buffer *buffer) +{ + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); + assert(attr < PIPE_ATTRIB_MAX); + draw->vertex_buffer[attr] = *buffer; +} + + +void +draw_set_vertex_element(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_element *element) +{ + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); + assert(attr < PIPE_ATTRIB_MAX); + draw->vertex_element[attr] = *element; +} + + +/** + * Tell drawing context where to find mapped vertex buffers. + */ +void +draw_set_mapped_vertex_buffer(struct draw_context *draw, + unsigned attr, const void *buffer) +{ + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); + draw->user.vbuffer[attr] = buffer; +} + + +void +draw_set_mapped_constant_buffer(struct draw_context *draw, + const void *buffer) +{ + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); + draw->user.constants = buffer; +} + + +/** + * Tells the draw module whether to convert wide points (size != 1) + * into triangles. + */ +void +draw_convert_wide_points(struct draw_context *draw, boolean enable) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->convert_wide_points = enable; +} + + +/** + * Tells the draw module whether to convert wide lines (width != 1) + * into triangles. + */ +void +draw_convert_wide_lines(struct draw_context *draw, boolean enable) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->convert_wide_lines = enable; +} + + +/** + * Allocate space for temporary post-transform vertices, such as for clipping. + */ +void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) +{ + assert(!stage->tmp); + + stage->nr_tmps = nr; + + if (nr) { + ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); + unsigned i; + + stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); + + for (i = 0; i < nr; i++) + stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + } +} + + +void draw_free_temp_verts( struct draw_stage *stage ) +{ + if (stage->tmp) { + FREE( stage->tmp[0] ); + FREE( stage->tmp ); + stage->tmp = NULL; + } +} + + +boolean draw_use_sse(struct draw_context *draw) +{ + return (boolean) draw->use_sse; +} + + +void draw_reset_vertex_ids(struct draw_context *draw) +{ + struct draw_stage *stage = draw->pipeline.first; + + while (stage) { + unsigned i; + + for (i = 0; i < stage->nr_tmps; i++) + stage->tmp[i]->vertex_id = UNDEFINED_VERTEX_ID; + + stage = stage->next; + } + + draw_vertex_cache_reset_vertex_ids(draw); +} diff --git a/src/gallium/aux/draw/draw_context.h b/src/gallium/aux/draw/draw_context.h new file mode 100644 index 0000000000..ddeb184497 --- /dev/null +++ b/src/gallium/aux/draw/draw_context.h @@ -0,0 +1,142 @@ + +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Public interface into the drawing module. + */ + +/* Authors: Keith Whitwell + */ + + +#ifndef DRAW_CONTEXT_H +#define DRAW_CONTEXT_H + + +#include "pipe/p_state.h" + + +struct vertex_buffer; +struct vertex_info; +struct draw_context; +struct draw_stage; +struct draw_vertex_shader; + + +/** + * Clipmask flags + */ +/*@{*/ +#define CLIP_RIGHT_BIT 0x01 +#define CLIP_LEFT_BIT 0x02 +#define CLIP_TOP_BIT 0x04 +#define CLIP_BOTTOM_BIT 0x08 +#define CLIP_NEAR_BIT 0x10 +#define CLIP_FAR_BIT 0x20 +/*@}*/ + +/** + * Bitshift for each clip flag + */ +/*@{*/ +#define CLIP_RIGHT_SHIFT 0 +#define CLIP_LEFT_SHIFT 1 +#define CLIP_TOP_SHIFT 2 +#define CLIP_BOTTOM_SHIFT 3 +#define CLIP_NEAR_SHIFT 4 +#define CLIP_FAR_SHIFT 5 +/*@}*/ + + +struct draw_context *draw_create( void ); + +void draw_destroy( struct draw_context *draw ); + +void draw_set_viewport_state( struct draw_context *draw, + const struct pipe_viewport_state *viewport ); + +void draw_set_clip_state( struct draw_context *pipe, + const struct pipe_clip_state *clip ); + +void draw_set_rasterizer_state( struct draw_context *draw, + const struct pipe_rasterizer_state *raster ); + +void draw_set_rasterize_stage( struct draw_context *draw, + struct draw_stage *stage ); + +void draw_convert_wide_points(struct draw_context *draw, boolean enable); + +void draw_convert_wide_lines(struct draw_context *draw, boolean enable); + + +struct draw_vertex_shader * +draw_create_vertex_shader(struct draw_context *draw, + const struct pipe_shader_state *shader); +void draw_bind_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs); +void draw_delete_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs); + +boolean draw_use_sse(struct draw_context *draw); + +void draw_set_vertex_buffer(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_buffer *buffer); + +void draw_set_vertex_element(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_element *element); + +void draw_set_mapped_element_buffer( struct draw_context *draw, + unsigned eltSize, void *elements ); + +void draw_set_mapped_vertex_buffer(struct draw_context *draw, + unsigned attr, const void *buffer); + +void draw_set_mapped_constant_buffer(struct draw_context *draw, + const void *buffer); + + +/*********************************************************************** + * draw_prim.c + */ + +void draw_arrays(struct draw_context *draw, unsigned prim, + unsigned start, unsigned count); + +void draw_flush(struct draw_context *draw); + +/*********************************************************************** + * draw_debug.c + */ +boolean draw_validate_prim( unsigned prim, unsigned length ); +unsigned draw_trim_prim( unsigned mode, unsigned count ); + + + +#endif /* DRAW_CONTEXT_H */ diff --git a/src/gallium/aux/draw/draw_cull.c b/src/gallium/aux/draw/draw_cull.c new file mode 100644 index 0000000000..8177b0ac86 --- /dev/null +++ b/src/gallium/aux/draw/draw_cull.c @@ -0,0 +1,150 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Drawing stage for polygon culling + */ + +/* Authors: Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + + +struct cull_stage { + struct draw_stage stage; + unsigned winding; /**< which winding(s) to cull (one of PIPE_WINDING_x) */ +}; + + +static INLINE struct cull_stage *cull_stage( struct draw_stage *stage ) +{ + return (struct cull_stage *)stage; +} + + + + +static void cull_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + /* Window coords: */ + const float *v0 = header->v[0]->data[0]; + const float *v1 = header->v[1]->data[0]; + const float *v2 = header->v[2]->data[0]; + + /* edge vectors e = v0 - v2, f = v1 - v2 */ + const float ex = v0[0] - v2[0]; + const float ey = v0[1] - v2[1]; + const float fx = v1[0] - v2[0]; + const float fy = v1[1] - v2[1]; + + /* det = cross(e,f).z */ + header->det = ex * fy - ey * fx; + + if (header->det != 0) { + /* if (det < 0 then Z points toward camera and triangle is + * counter-clockwise winding. + */ + unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; + + if ((winding & cull_stage(stage)->winding) == 0) { + /* triangle is not culled, pass to next stage */ + stage->next->tri( stage->next, header ); + } + } +} + +static void cull_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct cull_stage *cull = cull_stage(stage); + + cull->winding = stage->draw->rasterizer->cull_mode; + + stage->tri = cull_tri; + stage->tri( stage, header ); +} + + + +static void cull_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void cull_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void cull_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->tri = cull_first_tri; + stage->next->flush( stage->next, flags ); +} + +static void cull_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void cull_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create a new polygon culling stage. + */ +struct draw_stage *draw_cull_stage( struct draw_context *draw ) +{ + struct cull_stage *cull = CALLOC_STRUCT(cull_stage); + + draw_alloc_temp_verts( &cull->stage, 0 ); + + cull->stage.draw = draw; + cull->stage.next = NULL; + cull->stage.point = cull_point; + cull->stage.line = cull_line; + cull->stage.tri = cull_first_tri; + cull->stage.flush = cull_flush; + cull->stage.reset_stipple_counter = cull_reset_stipple_counter; + cull->stage.destroy = cull_destroy; + + return &cull->stage; +} diff --git a/src/gallium/aux/draw/draw_debug.c b/src/gallium/aux/draw/draw_debug.c new file mode 100644 index 0000000000..d6220b5f62 --- /dev/null +++ b/src/gallium/aux/draw/draw_debug.c @@ -0,0 +1,113 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "draw_private.h" +#include "draw_context.h" + + + +static void +draw_prim_info(unsigned prim, unsigned *first, unsigned *incr) +{ + assert(prim >= PIPE_PRIM_POINTS); + assert(prim <= PIPE_PRIM_POLYGON); + + switch (prim) { + case PIPE_PRIM_POINTS: + *first = 1; + *incr = 1; + break; + case PIPE_PRIM_LINES: + *first = 2; + *incr = 2; + break; + case PIPE_PRIM_LINE_STRIP: + *first = 2; + *incr = 1; + break; + case PIPE_PRIM_LINE_LOOP: + *first = 2; + *incr = 1; + break; + case PIPE_PRIM_TRIANGLES: + *first = 3; + *incr = 3; + break; + case PIPE_PRIM_TRIANGLE_STRIP: + *first = 3; + *incr = 1; + break; + case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_POLYGON: + *first = 3; + *incr = 1; + break; + case PIPE_PRIM_QUADS: + *first = 4; + *incr = 4; + break; + case PIPE_PRIM_QUAD_STRIP: + *first = 4; + *incr = 2; + break; + default: + assert(0); + *first = 1; + *incr = 1; + break; + } +} + + +unsigned +draw_trim_prim( unsigned mode, unsigned count ) +{ + unsigned length, first, incr; + + draw_prim_info( mode, &first, &incr ); + + if (count < first) + length = 0; + else + length = count - (count - first) % incr; + + return length; +} + + +boolean +draw_validate_prim( unsigned mode, unsigned count ) +{ + return (count > 0 && + count == draw_trim_prim( mode, count )); +} + diff --git a/src/gallium/aux/draw/draw_flatshade.c b/src/gallium/aux/draw/draw_flatshade.c new file mode 100644 index 0000000000..4398abbc60 --- /dev/null +++ b/src/gallium/aux/draw/draw_flatshade.c @@ -0,0 +1,205 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +/** subclass of draw_stage */ +struct flat_stage +{ + struct draw_stage stage; + + uint num_color_attribs; + uint color_attribs[4]; /* front/back primary/secondary colors */ +}; + + +static INLINE struct flat_stage * +flat_stage(struct draw_stage *stage) +{ + return (struct flat_stage *) stage; +} + + +/** Copy all the color attributes from 'src' vertex to 'dst' vertex */ +static INLINE void copy_colors( struct draw_stage *stage, + struct vertex_header *dst, + const struct vertex_header *src ) +{ + const struct flat_stage *flat = flat_stage(stage); + uint i; + for (i = 0; i < flat->num_color_attribs; i++) { + const uint attr = flat->color_attribs[i]; + COPY_4FV(dst->data[attr], src->data[attr]); + } +} + + +/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */ +static INLINE void copy_colors2( struct draw_stage *stage, + struct vertex_header *dst0, + struct vertex_header *dst1, + const struct vertex_header *src ) +{ + const struct flat_stage *flat = flat_stage(stage); + uint i; + for (i = 0; i < flat->num_color_attribs; i++) { + const uint attr = flat->color_attribs[i]; + COPY_4FV(dst0->data[attr], src->data[attr]); + COPY_4FV(dst1->data[attr], src->data[attr]); + } +} + + +/** + * Flatshade tri. Required for clipping and when unfilled tris are + * active, otherwise handled by hardware. + */ +static void flatshade_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = dup_vert(stage, header->v[1], 1); + tmp.v[2] = header->v[2]; + + copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]); + + stage->next->tri( stage->next, &tmp ); +} + + +/** + * Flatshade line. Required for clipping. + */ +static void flatshade_line( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = header->v[1]; + + copy_colors(stage, tmp.v[0], tmp.v[1]); + + stage->next->line( stage->next, &tmp ); +} + + +static void flatshade_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void flatshade_init_state( struct draw_stage *stage ) +{ + struct flat_stage *flat = flat_stage(stage); + const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; + uint i; + + /* Find which vertex shader outputs are colors, make a list */ + flat->num_color_attribs = 0; + for (i = 0; i < vs->num_outputs; i++) { + if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR || + vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + flat->color_attribs[flat->num_color_attribs++] = i; + } + } + + stage->line = flatshade_line; + stage->tri = flatshade_tri; +} + +static void flatshade_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + flatshade_init_state( stage ); + stage->tri( stage, header ); +} + +static void flatshade_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + flatshade_init_state( stage ); + stage->line( stage, header ); +} + + +static void flatshade_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = flatshade_first_tri; + stage->line = flatshade_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void flatshade_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void flatshade_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create flatshading drawing stage. + */ +struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) +{ + struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage); + + draw_alloc_temp_verts( &flatshade->stage, 2 ); + + flatshade->stage.draw = draw; + flatshade->stage.next = NULL; + flatshade->stage.point = flatshade_point; + flatshade->stage.line = flatshade_first_line; + flatshade->stage.tri = flatshade_first_tri; + flatshade->stage.flush = flatshade_flush; + flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter; + flatshade->stage.destroy = flatshade_destroy; + + return &flatshade->stage; +} + + diff --git a/src/gallium/aux/draw/draw_offset.c b/src/gallium/aux/draw/draw_offset.c new file mode 100644 index 0000000000..dbc676deae --- /dev/null +++ b/src/gallium/aux/draw/draw_offset.c @@ -0,0 +1,186 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief polygon offset state + * + * \author Keith Whitwell + * \author Brian Paul + */ + +#include "pipe/p_util.h" +#include "draw_private.h" + + + +struct offset_stage { + struct draw_stage stage; + + float scale; + float units; +}; + + + +static INLINE struct offset_stage *offset_stage( struct draw_stage *stage ) +{ + return (struct offset_stage *) stage; +} + + + + + +/** + * Offset tri Z. Some hardware can handle this, but not usually when + * doing unfilled rendering. + */ +static void do_offset_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct offset_stage *offset = offset_stage(stage); + float inv_det = 1.0f / header->det; + + /* Window coords: + */ + float *v0 = header->v[0]->data[0]; + float *v1 = header->v[1]->data[0]; + float *v2 = header->v[2]->data[0]; + + /* edge vectors e = v0 - v2, f = v1 - v2 */ + float ex = v0[0] - v2[0]; + float ey = v0[1] - v2[1]; + float ez = v0[2] - v2[2]; + float fx = v1[0] - v2[0]; + float fy = v1[1] - v2[1]; + float fz = v1[2] - v2[2]; + + /* (a,b) = cross(e,f).xy */ + float a = ey*fz - ez*fy; + float b = ez*fx - ex*fz; + + float dzdx = FABSF(a * inv_det); + float dzdy = FABSF(b * inv_det); + + float zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale; + + /* + * Note: we're applying the offset and clamping per-vertex. + * Ideally, the offset is applied per-fragment prior to fragment shading. + */ + v0[2] = CLAMP(v0[2] + zoffset, 0.0f, 1.0f); + v1[2] = CLAMP(v1[2] + zoffset, 0.0f, 1.0f); + v2[2] = CLAMP(v2[2] + zoffset, 0.0f, 1.0f); + + stage->next->tri( stage->next, header ); +} + + +static void offset_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = dup_vert(stage, header->v[1], 1); + tmp.v[2] = dup_vert(stage, header->v[2], 2); + + do_offset_tri( stage, &tmp ); +} + + +static void offset_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct offset_stage *offset = offset_stage(stage); + float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */ + + offset->units = stage->draw->rasterizer->offset_units * mrd; + offset->scale = stage->draw->rasterizer->offset_scale; + + stage->tri = offset_tri; + stage->tri( stage, header ); +} + + +static void offset_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void offset_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void offset_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = offset_first_tri; + stage->next->flush( stage->next, flags ); +} + + +static void offset_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void offset_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create polygon offset drawing stage. + */ +struct draw_stage *draw_offset_stage( struct draw_context *draw ) +{ + struct offset_stage *offset = CALLOC_STRUCT(offset_stage); + + draw_alloc_temp_verts( &offset->stage, 3 ); + + offset->stage.draw = draw; + offset->stage.next = NULL; + offset->stage.point = offset_point; + offset->stage.line = offset_line; + offset->stage.tri = offset_first_tri; + offset->stage.flush = offset_flush; + offset->stage.reset_stipple_counter = offset_reset_stipple_counter; + offset->stage.destroy = offset_destroy; + + return &offset->stage; +} diff --git a/src/gallium/aux/draw/draw_prim.c b/src/gallium/aux/draw/draw_prim.c new file mode 100644 index 0000000000..51e2242719 --- /dev/null +++ b/src/gallium/aux/draw/draw_prim.c @@ -0,0 +1,482 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_debug.h" + +#include "draw_private.h" +#include "draw_context.h" + + + +#define RP_NONE 0 +#define RP_POINT 1 +#define RP_LINE 2 +#define RP_TRI 3 + + +static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { + RP_POINT, + RP_LINE, + RP_LINE, + RP_LINE, + RP_TRI, + RP_TRI, + RP_TRI, + RP_TRI, + RP_TRI, + RP_TRI +}; + + +static void draw_prim_queue_flush( struct draw_context *draw ) +{ + unsigned i; + + if (0) + debug_printf("Flushing with %d prims, %d verts\n", + draw->pq.queue_nr, draw->vs.queue_nr); + + assert (draw->pq.queue_nr != 0); + + /* NOTE: we cannot save draw->pipeline->first in a local var because + * draw->pipeline->first is often changed by the first call to tri(), + * line(), etc. + */ + if (draw->rasterizer->line_stipple_enable) { + switch (draw->reduced_prim) { + case RP_TRI: + for (i = 0; i < draw->pq.queue_nr; i++) { + if (draw->pq.queue[i].reset_line_stipple) + draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); + + draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] ); + } + break; + case RP_LINE: + for (i = 0; i < draw->pq.queue_nr; i++) { + if (draw->pq.queue[i].reset_line_stipple) + draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); + + draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] ); + } + break; + case RP_POINT: + draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); + for (i = 0; i < draw->pq.queue_nr; i++) + draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] ); + break; + } + } + else { + switch (draw->reduced_prim) { + case RP_TRI: + for (i = 0; i < draw->pq.queue_nr; i++) + draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] ); + break; + case RP_LINE: + for (i = 0; i < draw->pq.queue_nr; i++) + draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] ); + break; + case RP_POINT: + for (i = 0; i < draw->pq.queue_nr; i++) + draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] ); + break; + } + } + + draw->pq.queue_nr = 0; + draw_vertex_cache_unreference( draw ); +} + + + +void draw_do_flush( struct draw_context *draw, unsigned flags ) +{ + if (0) + debug_printf("Flushing with %d verts, %d prims\n", + draw->vs.queue_nr, + draw->pq.queue_nr ); + + + if (flags >= DRAW_FLUSH_SHADER_QUEUE) { + if (draw->vs.queue_nr) + (*draw->shader_queue_flush)(draw); + + if (flags >= DRAW_FLUSH_PRIM_QUEUE) { + if (draw->pq.queue_nr) + draw_prim_queue_flush(draw); + + if (flags >= DRAW_FLUSH_VERTEX_CACHE) { + draw_vertex_cache_invalidate(draw); + + if (flags >= DRAW_FLUSH_STATE_CHANGE) { + draw->pipeline.first->flush( draw->pipeline.first, flags ); + draw->pipeline.first = draw->pipeline.validate; + draw->reduced_prim = ~0; + } + } + } + } +} + + + +/* Return a pointer to a freshly queued primitive header. Ensure that + * there is room in the vertex cache for a maximum of "nr_verts" new + * vertices. Flush primitive and/or vertex queues if necessary to + * make space. + */ +static struct prim_header *get_queued_prim( struct draw_context *draw, + unsigned nr_verts ) +{ + if (!draw_vertex_cache_check_space( draw, nr_verts )) { +// debug_printf("v"); + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE ); + } + else if (draw->pq.queue_nr == PRIM_QUEUE_LENGTH) { +// debug_printf("p"); + draw_do_flush( draw, DRAW_FLUSH_PRIM_QUEUE ); + } + + assert(draw->pq.queue_nr < PRIM_QUEUE_LENGTH); + + return &draw->pq.queue[draw->pq.queue_nr++]; +} + + + +/** + * Add a point to the primitive queue. + * \param i0 index into user's vertex arrays + */ +static void do_point( struct draw_context *draw, + unsigned i0 ) +{ + struct prim_header *prim = get_queued_prim( draw, 1 ); + + prim->reset_line_stipple = 0; + prim->edgeflags = 1; + prim->pad = 0; + prim->v[0] = draw->vcache.get_vertex( draw, i0 ); +} + + +/** + * Add a line to the primitive queue. + * \param i0 index into user's vertex arrays + * \param i1 index into user's vertex arrays + */ +static void do_line( struct draw_context *draw, + boolean reset_stipple, + unsigned i0, + unsigned i1 ) +{ + struct prim_header *prim = get_queued_prim( draw, 2 ); + + prim->reset_line_stipple = reset_stipple; + prim->edgeflags = 1; + prim->pad = 0; + prim->v[0] = draw->vcache.get_vertex( draw, i0 ); + prim->v[1] = draw->vcache.get_vertex( draw, i1 ); +} + +/** + * Add a triangle to the primitive queue. + */ +static void do_triangle( struct draw_context *draw, + unsigned i0, + unsigned i1, + unsigned i2 ) +{ + struct prim_header *prim = get_queued_prim( draw, 3 ); + + prim->reset_line_stipple = 1; + prim->edgeflags = ~0; + prim->pad = 0; + prim->v[0] = draw->vcache.get_vertex( draw, i0 ); + prim->v[1] = draw->vcache.get_vertex( draw, i1 ); + prim->v[2] = draw->vcache.get_vertex( draw, i2 ); +} + +static void do_ef_triangle( struct draw_context *draw, + boolean reset_stipple, + unsigned ef_mask, + unsigned i0, + unsigned i1, + unsigned i2 ) +{ + struct prim_header *prim = get_queued_prim( draw, 3 ); + struct vertex_header *v0 = draw->vcache.get_vertex( draw, i0 ); + struct vertex_header *v1 = draw->vcache.get_vertex( draw, i1 ); + struct vertex_header *v2 = draw->vcache.get_vertex( draw, i2 ); + + prim->reset_line_stipple = reset_stipple; + + prim->edgeflags = ef_mask & ((v0->edgeflag << 0) | + (v1->edgeflag << 1) | + (v2->edgeflag << 2)); + prim->pad = 0; + prim->v[0] = v0; + prim->v[1] = v1; + prim->v[2] = v2; +} + + +static void do_ef_quad( struct draw_context *draw, + unsigned v0, + unsigned v1, + unsigned v2, + unsigned v3 ) +{ + const unsigned omitEdge2 = ~(1 << 1); + const unsigned omitEdge3 = ~(1 << 2); + do_ef_triangle( draw, 1, omitEdge2, v0, v1, v3 ); + do_ef_triangle( draw, 0, omitEdge3, v1, v2, v3 ); +} + +static void do_quad( struct draw_context *draw, + unsigned v0, + unsigned v1, + unsigned v2, + unsigned v3 ) +{ + do_triangle( draw, v0, v1, v3 ); + do_triangle( draw, v1, v2, v3 ); +} + + +/** + * Main entrypoint to draw some number of points/lines/triangles + */ +static void +draw_prim( struct draw_context *draw, + unsigned prim, unsigned start, unsigned count ) +{ + unsigned i; + boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL); + +// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count ); + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i ++) { + do_point( draw, + start + i ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) { + do_line( draw, + TRUE, + start + i + 0, + start + i + 1); + } + break; + + case PIPE_PRIM_LINE_LOOP: + if (count >= 2) { + for (i = 1; i < count; i++) { + do_line( draw, + i == 1, /* XXX: only if vb not split */ + start + i - 1, + start + i ); + } + + do_line( draw, + 0, + start + count - 1, + start + 0 ); + } + break; + + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < count; i++) { + do_line( draw, + i == 1, + start + i - 1, + start + i ); + } + break; + + case PIPE_PRIM_TRIANGLES: + if (unfilled) { + for (i = 0; i+2 < count; i += 3) { + do_ef_triangle( draw, + 1, + ~0, + start + i + 0, + start + i + 1, + start + i + 2 ); + } + } + else { + for (i = 0; i+2 < count; i += 3) { + do_triangle( draw, + start + i + 0, + start + i + 1, + start + i + 2 ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + for (i = 0; i+2 < count; i++) { + if (i & 1) { + do_triangle( draw, + start + i + 1, + start + i + 0, + start + i + 2 ); + } + else { + do_triangle( draw, + start + i + 0, + start + i + 1, + start + i + 2 ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (count >= 3) { + for (i = 0; i+2 < count; i++) { + do_triangle( draw, + start + 0, + start + i + 1, + start + i + 2 ); + } + } + break; + + + case PIPE_PRIM_QUADS: + if (unfilled) { + for (i = 0; i+3 < count; i += 4) { + do_ef_quad( draw, + start + i + 0, + start + i + 1, + start + i + 2, + start + i + 3); + } + } + else { + for (i = 0; i+3 < count; i += 4) { + do_quad( draw, + start + i + 0, + start + i + 1, + start + i + 2, + start + i + 3); + } + } + break; + + case PIPE_PRIM_QUAD_STRIP: + if (unfilled) { + for (i = 0; i+3 < count; i += 2) { + do_ef_quad( draw, + start + i + 2, + start + i + 0, + start + i + 1, + start + i + 3); + } + } + else { + for (i = 0; i+3 < count; i += 2) { + do_quad( draw, + start + i + 2, + start + i + 0, + start + i + 1, + start + i + 3); + } + } + break; + + case PIPE_PRIM_POLYGON: + if (unfilled) { + unsigned ef_mask = (1<<2) | (1<<0); + + for (i = 0; i+2 < count; i++) { + + if (i + 3 >= count) + ef_mask |= (1<<1); + + do_ef_triangle( draw, + i == 0, + ef_mask, + start + i + 1, + start + i + 2, + start + 0); + + ef_mask &= ~(1<<2); + } + } + else { + for (i = 0; i+2 < count; i++) { + do_triangle( draw, + start + i + 1, + start + i + 2, + start + 0); + } + } + break; + + default: + assert(0); + break; + } +} + + + + +/** + * Draw vertex arrays + * This is the main entrypoint into the drawing module. + * \param prim one of PIPE_PRIM_x + * \param start index of first vertex to draw + * \param count number of vertices to draw + */ +void +draw_arrays(struct draw_context *draw, unsigned prim, + unsigned start, unsigned count) +{ + if (reduced_prim[prim] != draw->reduced_prim) { + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->reduced_prim = reduced_prim[prim]; + } + + /* drawing done here: */ + draw_prim(draw, prim, start, count); +} + + diff --git a/src/gallium/aux/draw/draw_private.h b/src/gallium/aux/draw/draw_private.h new file mode 100644 index 0000000000..b17eaaed65 --- /dev/null +++ b/src/gallium/aux/draw/draw_private.h @@ -0,0 +1,346 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Private data structures, etc for the draw module. + */ + + +/** + * Authors: + * Keith Whitwell + * Brian Paul + */ + + +#ifndef DRAW_PRIVATE_H +#define DRAW_PRIVATE_H + + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" + +#include "x86/rtasm/x86sse.h" +#include "pipe/tgsi/exec/tgsi_exec.h" + + +struct gallivm_prog; +struct gallivm_cpu_engine; + +/** + * Basic vertex info. + * Carry some useful information around with the vertices in the prim pipe. + */ +struct vertex_header { + unsigned clipmask:12; + unsigned edgeflag:1; + unsigned pad:3; + unsigned vertex_id:16; + + float clip[4]; + + float data[][4]; /* Note variable size */ +}; + +/* NOTE: It should match vertex_id size above */ +#define UNDEFINED_VERTEX_ID 0xffff + +/* XXX This is too large */ +#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) + + + +/** + * Basic info for a point/line/triangle primitive. + */ +struct prim_header { + float det; /**< front/back face determinant */ + unsigned reset_line_stipple:1; + unsigned edgeflags:3; + unsigned pad:28; + struct vertex_header *v[3]; /**< 1 to 3 vertex pointers */ +}; + + + +struct draw_context; + +/** + * Base class for all primitive drawing stages. + */ +struct draw_stage +{ + struct draw_context *draw; /**< parent context */ + + struct draw_stage *next; /**< next stage in pipeline */ + + struct vertex_header **tmp; /**< temp vert storage, such as for clipping */ + unsigned nr_tmps; + + void (*point)( struct draw_stage *, + struct prim_header * ); + + void (*line)( struct draw_stage *, + struct prim_header * ); + + void (*tri)( struct draw_stage *, + struct prim_header * ); + + void (*flush)( struct draw_stage *, + unsigned flags ); + + void (*reset_stipple_counter)( struct draw_stage * ); + + void (*destroy)( struct draw_stage * ); +}; + + +#define PRIM_QUEUE_LENGTH 16 +#define VCACHE_SIZE 32 +#define VCACHE_OVERFLOW 4 +#define VS_QUEUE_LENGTH (VCACHE_SIZE + VCACHE_OVERFLOW + 1) /* can never fill up */ + +/** + * Private version of the compiled vertex_shader + */ +struct draw_vertex_shader { + const struct pipe_shader_state *state; +#if defined(__i386__) || defined(__386__) + struct x86_function sse2_program; +#endif +#ifdef MESA_LLVM + struct gallivm_prog *llvm_prog; +#endif +}; + + +/* Internal function for vertex fetch. + */ +typedef void (*fetch_func)(const void *ptr, float *attrib); +typedef void (*full_fetch_func)( struct draw_context *draw, + struct tgsi_exec_machine *machine, + const unsigned *elts, + unsigned count ); + + + +/** + * Private context for the drawing module. + */ +struct draw_context +{ + /** Drawing/primitive pipeline stages */ + struct { + struct draw_stage *first; /**< one of the following */ + + struct draw_stage *validate; + + /* stages (in logical order) */ + struct draw_stage *flatshade; + struct draw_stage *clip; + struct draw_stage *cull; + struct draw_stage *twoside; + struct draw_stage *offset; + struct draw_stage *unfilled; + struct draw_stage *stipple; + struct draw_stage *wide; + struct draw_stage *rasterize; + } pipeline; + + /* pipe state that we need: */ + const struct pipe_rasterizer_state *rasterizer; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + const struct draw_vertex_shader *vertex_shader; + + uint num_vs_outputs; /**< convenience, from vertex_shader */ + + /* user-space vertex data, buffers */ + struct { + /** vertex element/index buffer (ex: glDrawElements) */ + const void *elts; + /** bytes per index (0, 1, 2 or 4) */ + unsigned eltSize; + + /** vertex arrays */ + const void *vbuffer[PIPE_ATTRIB_MAX]; + + /** constant buffer (for vertex shader) */ + const void *constants; + } user; + + /* Clip derived state: + */ + float plane[12][4]; + unsigned nr_planes; + + boolean convert_wide_points; /**< convert wide points to tris? */ + boolean convert_wide_lines; /**< convert side lines to tris? */ + + unsigned reduced_prim; + + /** TGSI program interpreter runtime state */ + struct tgsi_exec_machine machine; + + /* Vertex fetch internal state + */ + struct { + const ubyte *src_ptr[PIPE_ATTRIB_MAX]; + unsigned pitch[PIPE_ATTRIB_MAX]; + fetch_func fetch[PIPE_ATTRIB_MAX]; + unsigned nr_attrs; + full_fetch_func fetch_func; + } vertex_fetch; + + /* Post-tnl vertex cache: + */ + struct { + unsigned referenced; /**< bitfield */ + unsigned idx[VCACHE_SIZE + VCACHE_OVERFLOW]; + struct vertex_header *vertex[VCACHE_SIZE + VCACHE_OVERFLOW]; + unsigned overflow; + + /** To find space in the vertex cache: */ + struct vertex_header *(*get_vertex)( struct draw_context *draw, + unsigned i ); + } vcache; + + /* Vertex shader queue: + */ + struct { + struct { + unsigned elt; /**< index into the user's vertex arrays */ + struct vertex_header *dest; /**< points into vcache.vertex[] array */ + } queue[VS_QUEUE_LENGTH]; + unsigned queue_nr; + } vs; + + /** + * Run the vertex shader on all vertices in the vertex queue. + */ + void (*shader_queue_flush)(struct draw_context *draw); + + /* Prim pipeline queue: + */ + struct { + /* Need to queue up primitives until their vertices have been + * transformed by a vs queue flush. + */ + struct prim_header queue[PRIM_QUEUE_LENGTH]; + unsigned queue_nr; + } pq; + + int use_sse : 1; +#ifdef MESA_LLVM + struct gallivm_cpu_engine *engine; +#endif + + void *driver_private; +}; + + + +extern struct draw_stage *draw_unfilled_stage( struct draw_context *context ); +extern struct draw_stage *draw_twoside_stage( struct draw_context *context ); +extern struct draw_stage *draw_offset_stage( struct draw_context *context ); +extern struct draw_stage *draw_clip_stage( struct draw_context *context ); +extern struct draw_stage *draw_flatshade_stage( struct draw_context *context ); +extern struct draw_stage *draw_cull_stage( struct draw_context *context ); +extern struct draw_stage *draw_stipple_stage( struct draw_context *context ); +extern struct draw_stage *draw_wide_stage( struct draw_context *context ); +extern struct draw_stage *draw_validate_stage( struct draw_context *context ); + + +extern void draw_free_temp_verts( struct draw_stage *stage ); + +extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); + +extern void draw_reset_vertex_ids( struct draw_context *draw ); + + +extern int draw_vertex_cache_check_space( struct draw_context *draw, + unsigned nr_verts ); + +extern void draw_vertex_cache_invalidate( struct draw_context *draw ); +extern void draw_vertex_cache_unreference( struct draw_context *draw ); +extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ); + + +extern void draw_vertex_shader_queue_flush( struct draw_context *draw ); +#ifdef MESA_LLVM +extern void draw_vertex_shader_queue_flush_llvm( struct draw_context *draw ); +#endif + +struct tgsi_exec_machine; + +extern void draw_update_vertex_fetch( struct draw_context *draw ); + + +#define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ +#define DRAW_FLUSH_PRIM_QUEUE 0x2 +#define DRAW_FLUSH_VERTEX_CACHE 0x4 +#define DRAW_FLUSH_STATE_CHANGE 0x8 +#define DRAW_FLUSH_BACKEND 0x10 + + +void draw_do_flush( struct draw_context *draw, unsigned flags ); + + + +/** + * Get a writeable copy of a vertex. + * \param stage drawing stage info + * \param vert the vertex to copy (source) + * \param idx index into stage's tmp[] array to put the copy (dest) + * \return pointer to the copied vertex + */ +static INLINE struct vertex_header * +dup_vert( struct draw_stage *stage, + const struct vertex_header *vert, + unsigned idx ) +{ + struct vertex_header *tmp = stage->tmp[idx]; + const uint vsize = sizeof(struct vertex_header) + + stage->draw->num_vs_outputs * 4 * sizeof(float); + memcpy(tmp, vert, vsize); + tmp->vertex_id = UNDEFINED_VERTEX_ID; + return tmp; +} + +static INLINE float +dot4(const float *a, const float *b) +{ + float result = (a[0]*b[0] + + a[1]*b[1] + + a[2]*b[2] + + a[3]*b[3]); + + return result; +} + +#endif /* DRAW_PRIVATE_H */ diff --git a/src/gallium/aux/draw/draw_stipple.c b/src/gallium/aux/draw/draw_stipple.c new file mode 100644 index 0000000000..506f33512c --- /dev/null +++ b/src/gallium/aux/draw/draw_stipple.c @@ -0,0 +1,239 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +/* Implement line stipple by cutting lines up into smaller lines. + * There are hundreds of ways to implement line stipple, this is one + * choice that should work in all situations, requires no state + * manipulations, but with a penalty in terms of large amounts of + * generated geometry. + */ + + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +/** Subclass of draw_stage */ +struct stipple_stage { + struct draw_stage stage; + float counter; + uint pattern; + uint factor; +}; + + +static INLINE struct stipple_stage * +stipple_stage(struct draw_stage *stage) +{ + return (struct stipple_stage *) stage; +} + + +/** + * Compute interpolated vertex attributes for 'dst' at position 't' + * between 'v0' and 'v1'. + * XXX using linear interpolation for all attribs at this time. + */ +static void +screen_interp( struct draw_context *draw, + struct vertex_header *dst, + float t, + const struct vertex_header *v0, + const struct vertex_header *v1 ) +{ + uint attr; + for (attr = 0; attr < draw->num_vs_outputs; attr++) { + const float *val0 = v0->data[attr]; + const float *val1 = v1->data[attr]; + float *newv = dst->data[attr]; + uint i; + for (i = 0; i < 4; i++) { + newv[i] = val0[i] + t * (val1[i] - val0[i]); + } + } +} + + +static void +emit_segment(struct draw_stage *stage, struct prim_header *header, + float t0, float t1) +{ + struct vertex_header *v0new = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1new = dup_vert(stage, header->v[1], 1); + struct prim_header newprim = *header; + + if (t0 > 0.0) { + screen_interp( stage->draw, v0new, t0, header->v[0], header->v[1] ); + newprim.v[0] = v0new; + } + + if (t1 < 1.0) { + screen_interp( stage->draw, v1new, t1, header->v[0], header->v[1] ); + newprim.v[1] = v1new; + } + + stage->next->line( stage->next, &newprim ); +} + + +static INLINE unsigned +stipple_test(int counter, ushort pattern, int factor) +{ + int b = (counter / factor) & 0xf; + return (1 << b) & pattern; +} + + +static void +stipple_line(struct draw_stage *stage, struct prim_header *header) +{ + struct stipple_stage *stipple = stipple_stage(stage); + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + const float *pos0 = v0->data[0]; + const float *pos1 = v1->data[0]; + float start = 0; + int state = 0; + + float x0 = pos0[0]; + float x1 = pos1[0]; + float y0 = pos0[1]; + float y1 = pos1[1]; + + float dx = x0 > x1 ? x0 - x1 : x1 - x0; + float dy = y0 > y1 ? y0 - y1 : y1 - y0; + + float length = MAX2(dx, dy); + int i; + + /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table. + */ + for (i = 0; i < length; i++) { + int result = stipple_test( (int) stipple->counter+i, + (ushort) stipple->pattern, stipple->factor ); + if (result != state) { + /* changing from "off" to "on" or vice versa */ + if (state) { + if (start != i) { + /* finishing an "on" segment */ + emit_segment( stage, header, start / length, i / length ); + } + } + else { + /* starting an "on" segment */ + start = (float) i; + } + state = result; + } + } + + if (state && start < length) + emit_segment( stage, header, start / length, 1.0 ); + + stipple->counter += length; +} + + +static void +reset_stipple_counter(struct draw_stage *stage) +{ + struct stipple_stage *stipple = stipple_stage(stage); + stipple->counter = 0; + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +stipple_first_line(struct draw_stage *stage, + struct prim_header *header) +{ + struct stipple_stage *stipple = stipple_stage(stage); + struct draw_context *draw = stage->draw; + + stipple->pattern = draw->rasterizer->line_stipple_pattern; + stipple->factor = draw->rasterizer->line_stipple_factor + 1; + + stage->line = stipple_line; + stage->line( stage, header ); +} + + +static void +stipple_flush(struct draw_stage *stage, unsigned flags) +{ + stage->line = stipple_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point( stage->next, header ); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +static void +stipple_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create line stippler stage + */ +struct draw_stage *draw_stipple_stage( struct draw_context *draw ) +{ + struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage); + + draw_alloc_temp_verts( &stipple->stage, 2 ); + + stipple->stage.draw = draw; + stipple->stage.next = NULL; + stipple->stage.point = passthrough_point; + stipple->stage.line = stipple_first_line; + stipple->stage.tri = passthrough_tri; + stipple->stage.reset_stipple_counter = reset_stipple_counter; + stipple->stage.flush = stipple_flush; + stipple->stage.destroy = stipple_destroy; + + return &stipple->stage; +} diff --git a/src/gallium/aux/draw/draw_twoside.c b/src/gallium/aux/draw/draw_twoside.c new file mode 100644 index 0000000000..1c38957987 --- /dev/null +++ b/src/gallium/aux/draw/draw_twoside.c @@ -0,0 +1,203 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +struct twoside_stage { + struct draw_stage stage; + float sign; /**< +1 or -1 */ + uint attrib_front0, attrib_back0; + uint attrib_front1, attrib_back1; +}; + + +static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage ) +{ + return (struct twoside_stage *)stage; +} + + + + +/** + * Copy back color(s) to front color(s). + */ +static INLINE struct vertex_header * +copy_bfc( struct twoside_stage *twoside, + const struct vertex_header *v, + unsigned idx ) +{ + struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx ); + + if (twoside->attrib_back0) { + COPY_4FV(tmp->data[twoside->attrib_front0], + tmp->data[twoside->attrib_back0]); + } + if (twoside->attrib_back1) { + COPY_4FV(tmp->data[twoside->attrib_front1], + tmp->data[twoside->attrib_back1]); + } + + return tmp; +} + + +/* Twoside tri: + */ +static void twoside_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct twoside_stage *twoside = twoside_stage(stage); + + if (header->det * twoside->sign < 0.0) { + /* this is a back-facing triangle */ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + /* copy back attribs to front attribs */ + tmp.v[0] = copy_bfc(twoside, header->v[0], 0); + tmp.v[1] = copy_bfc(twoside, header->v[1], 1); + tmp.v[2] = copy_bfc(twoside, header->v[2], 2); + + stage->next->tri( stage->next, &tmp ); + } + else { + stage->next->tri( stage->next, header ); + } +} + + +static void twoside_line( struct draw_stage *stage, + struct prim_header *header ) +{ + /* pass-through */ + stage->next->line( stage->next, header ); +} + + +static void twoside_point( struct draw_stage *stage, + struct prim_header *header ) +{ + /* pass-through */ + stage->next->point( stage->next, header ); +} + + +static void twoside_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct twoside_stage *twoside = twoside_stage(stage); + const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; + uint i; + + twoside->attrib_front0 = 0; + twoside->attrib_front1 = 0; + twoside->attrib_back0 = 0; + twoside->attrib_back1 = 0; + + /* Find which vertex shader outputs are front/back colors */ + for (i = 0; i < vs->num_outputs; i++) { + if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR) { + if (vs->output_semantic_index[i] == 0) + twoside->attrib_front0 = i; + else + twoside->attrib_front1 = i; + } + if (vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + if (vs->output_semantic_index[i] == 0) + twoside->attrib_back0 = i; + else + twoside->attrib_back1 = i; + } + } + + if (!twoside->attrib_back0) + twoside->attrib_front0 = 0; + + if (!twoside->attrib_back1) + twoside->attrib_front1 = 0; + + /* + * We'll multiply the primitive's determinant by this sign to determine + * if the triangle is back-facing (negative). + * sign = -1 for CCW, +1 for CW + */ + twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f; + + stage->tri = twoside_tri; + stage->tri( stage, header ); +} + + +static void twoside_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->tri = twoside_first_tri; + stage->next->flush( stage->next, flags ); +} + + +static void twoside_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void twoside_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create twoside pipeline stage. + */ +struct draw_stage *draw_twoside_stage( struct draw_context *draw ) +{ + struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage); + + draw_alloc_temp_verts( &twoside->stage, 3 ); + + twoside->stage.draw = draw; + twoside->stage.next = NULL; + twoside->stage.point = twoside_point; + twoside->stage.line = twoside_line; + twoside->stage.tri = twoside_first_tri; + twoside->stage.flush = twoside_flush; + twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter; + twoside->stage.destroy = twoside_destroy; + + return &twoside->stage; +} diff --git a/src/gallium/aux/draw/draw_unfilled.c b/src/gallium/aux/draw/draw_unfilled.c new file mode 100644 index 0000000000..8777cfdfc8 --- /dev/null +++ b/src/gallium/aux/draw/draw_unfilled.c @@ -0,0 +1,206 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Drawing stage for handling glPolygonMode(line/point). + * Convert triangles to points or lines as needed. + */ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + + +struct unfilled_stage { + struct draw_stage stage; + + /** [0] = front face, [1] = back face. + * legal values: PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE, + * and PIPE_POLYGON_MODE_POINT, + */ + unsigned mode[2]; +}; + + +static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage ) +{ + return (struct unfilled_stage *)stage; +} + + + +static void point( struct draw_stage *stage, + struct vertex_header *v0 ) +{ + struct prim_header tmp; + tmp.v[0] = v0; + stage->next->point( stage->next, &tmp ); +} + +static void line( struct draw_stage *stage, + struct vertex_header *v0, + struct vertex_header *v1 ) +{ + struct prim_header tmp; + tmp.v[0] = v0; + tmp.v[1] = v1; + stage->next->line( stage->next, &tmp ); +} + + +static void points( struct draw_stage *stage, + struct prim_header *header ) +{ + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + struct vertex_header *v2 = header->v[2]; + + if (header->edgeflags & 0x1) point( stage, v0 ); + if (header->edgeflags & 0x2) point( stage, v1 ); + if (header->edgeflags & 0x4) point( stage, v2 ); +} + + +static void lines( struct draw_stage *stage, + struct prim_header *header ) +{ + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + struct vertex_header *v2 = header->v[2]; + +#if 0 + assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag); + assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag); + assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag); +#endif + + if (header->edgeflags & 0x1) line( stage, v0, v1 ); + if (header->edgeflags & 0x2) line( stage, v1, v2 ); + if (header->edgeflags & 0x4) line( stage, v2, v0 ); +} + + +/* Unfilled tri: + * + * Note edgeflags in the vertex struct is not sufficient as we will + * need to manipulate them when decomposing primitives??? + */ +static void unfilled_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct unfilled_stage *unfilled = unfilled_stage(stage); + unsigned mode = unfilled->mode[header->det >= 0.0]; + + switch (mode) { + case PIPE_POLYGON_MODE_FILL: + stage->next->tri( stage->next, header ); + break; + case PIPE_POLYGON_MODE_LINE: + lines( stage, header ); + break; + case PIPE_POLYGON_MODE_POINT: + points( stage, header ); + break; + default: + abort(); + } +} + + +static void unfilled_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct unfilled_stage *unfilled = unfilled_stage(stage); + + unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */ + unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */ + + stage->tri = unfilled_tri; + stage->tri( stage, header ); +} + + +static void unfilled_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void unfilled_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void unfilled_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->next->flush( stage->next, flags ); + + stage->tri = unfilled_first_tri; +} + + +static void unfilled_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void unfilled_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create unfilled triangle stage. + */ +struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) +{ + struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage); + + draw_alloc_temp_verts( &unfilled->stage, 0 ); + + unfilled->stage.draw = draw; + unfilled->stage.next = NULL; + unfilled->stage.tmp = NULL; + unfilled->stage.point = unfilled_point; + unfilled->stage.line = unfilled_line; + unfilled->stage.tri = unfilled_first_tri; + unfilled->stage.flush = unfilled_flush; + unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter; + unfilled->stage.destroy = unfilled_destroy; + + return &unfilled->stage; +} diff --git a/src/gallium/aux/draw/draw_validate.c b/src/gallium/aux/draw/draw_validate.c new file mode 100644 index 0000000000..4375ebabbc --- /dev/null +++ b/src/gallium/aux/draw/draw_validate.c @@ -0,0 +1,185 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + + + + + +/** + * Rebuild the rendering pipeline. + */ +static struct draw_stage *validate_pipeline( struct draw_stage *stage ) +{ + struct draw_context *draw = stage->draw; + struct draw_stage *next = draw->pipeline.rasterize; + int need_det = 0; + int precalc_flat = 0; + + /* Set the validate's next stage to the rasterize stage, so that it + * can be found later if needed for flushing. + */ + stage->next = next; + + /* + * NOTE: we build up the pipeline in end-to-start order. + * + * TODO: make the current primitive part of the state and build + * shorter pipelines for lines & points. + */ + + if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines) || + (draw->rasterizer->point_size != 1.0 && draw->convert_wide_points) || + draw->rasterizer->point_sprite) { + draw->pipeline.wide->next = next; + next = draw->pipeline.wide; + } + + if (draw->rasterizer->line_stipple_enable) { + draw->pipeline.stipple->next = next; + next = draw->pipeline.stipple; + precalc_flat = 1; /* only needed for lines really */ + } + + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { + draw->pipeline.unfilled->next = next; + next = draw->pipeline.unfilled; + precalc_flat = 1; /* only needed for triangles really */ + need_det = 1; + } + + if (draw->rasterizer->flatshade && precalc_flat) { + draw->pipeline.flatshade->next = next; + next = draw->pipeline.flatshade; + } + + if (draw->rasterizer->offset_cw || + draw->rasterizer->offset_ccw) { + draw->pipeline.offset->next = next; + next = draw->pipeline.offset; + need_det = 1; + } + + if (draw->rasterizer->light_twoside) { + draw->pipeline.twoside->next = next; + next = draw->pipeline.twoside; + need_det = 1; + } + + /* Always run the cull stage as we calculate determinant there + * also. + * + * This can actually be a win as culling out the triangles can lead + * to less work emitting vertices, smaller vertex buffers, etc. + * It's difficult to say whether this will be true in general. + */ + if (need_det || draw->rasterizer->cull_mode) { + draw->pipeline.cull->next = next; + next = draw->pipeline.cull; + } + + /* Clip stage + */ + if (!draw->rasterizer->bypass_clipping) + { + draw->pipeline.clip->next = next; + next = draw->pipeline.clip; + } + + + draw->pipeline.first = next; + return next; +} + +static void validate_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->tri( pipeline, header ); +} + +static void validate_line( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->line( pipeline, header ); +} + +static void validate_point( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->point( pipeline, header ); +} + +static void validate_reset_stipple_counter( struct draw_stage *stage ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->reset_stipple_counter( pipeline ); +} + +static void validate_flush( struct draw_stage *stage, + unsigned flags ) +{ + /* May need to pass a backend flush on to the rasterize stage. + */ + if (stage->next) + stage->next->flush( stage->next, flags ); +} + + +static void validate_destroy( struct draw_stage *stage ) +{ + FREE( stage ); +} + + +/** + * Create validate pipeline stage. + */ +struct draw_stage *draw_validate_stage( struct draw_context *draw ) +{ + struct draw_stage *stage = CALLOC_STRUCT(draw_stage); + + stage->draw = draw; + stage->next = NULL; + stage->point = validate_point; + stage->line = validate_line; + stage->tri = validate_tri; + stage->flush = validate_flush; + stage->reset_stipple_counter = validate_reset_stipple_counter; + stage->destroy = validate_destroy; + + return stage; +} diff --git a/src/gallium/aux/draw/draw_vbuf.c b/src/gallium/aux/draw/draw_vbuf.c new file mode 100644 index 0000000000..71ac73912b --- /dev/null +++ b/src/gallium/aux/draw/draw_vbuf.c @@ -0,0 +1,570 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Vertex buffer drawing stage. + * + * \author José Fonseca + * \author Keith Whitwell + */ + + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" + +#include "draw_vbuf.h" +#include "draw_private.h" +#include "draw_vertex.h" +#include "draw_vf.h" + + +/** + * Vertex buffer emit stage. + */ +struct vbuf_stage { + struct draw_stage stage; /**< This must be first (base class) */ + + struct vbuf_render *render; + + const struct vertex_info *vinfo; + + /** Vertex size in bytes */ + unsigned vertex_size; + + struct draw_vertex_fetch *vf; + + /* FIXME: we have no guarantee that 'unsigned' is 32bit */ + + /** Vertices in hardware format */ + unsigned *vertices; + unsigned *vertex_ptr; + unsigned max_vertices; + unsigned nr_vertices; + + /** Indices */ + ushort *indices; + unsigned max_indices; + unsigned nr_indices; + + /** Pipe primitive */ + unsigned prim; +}; + + +/** + * Basically a cast wrapper. + */ +static INLINE struct vbuf_stage * +vbuf_stage( struct draw_stage *stage ) +{ + assert(stage); + return (struct vbuf_stage *)stage; +} + + +static void vbuf_flush_indices( struct vbuf_stage *vbuf ); +static void vbuf_flush_vertices( struct vbuf_stage *vbuf ); +static void vbuf_alloc_vertices( struct vbuf_stage *vbuf ); + + +static INLINE boolean +overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz ) +{ + unsigned long used = (unsigned long) ((char *)ptr - (char *)map); + return (used + bytes) > bufsz; +} + + +static INLINE void +check_space( struct vbuf_stage *vbuf, unsigned nr ) +{ + if (vbuf->nr_vertices + nr > vbuf->max_vertices ) { + vbuf_flush_vertices(vbuf); + vbuf_alloc_vertices(vbuf); + } + + if (vbuf->nr_indices + nr > vbuf->max_indices ) + vbuf_flush_indices(vbuf); +} + + +#if 0 +static INLINE void +dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) +{ + assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); + unsigned i, j, k; + + for (i = 0; i < vinfo->num_attribs; i++) { + j = vinfo->src_index[i]; + switch (vinfo->emit[i]) { + case EMIT_OMIT: + debug_printf("EMIT_OMIT:"); + break; + case EMIT_ALL: + assert(i == 0); + assert(j == 0); + debug_printf("EMIT_ALL:\t"); + for(k = 0; k < vinfo->size*4; ++k) + debug_printf("%02x ", *data++); + break; + case EMIT_1F: + debug_printf("EMIT_1F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_1F_PSIZE: + debug_printf("EMIT_1F_PSIZE:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_2F: + debug_printf("EMIT_2F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_3F: + debug_printf("EMIT_3F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + data += sizeof(float); + break; + case EMIT_4F: + debug_printf("EMIT_4F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_4UB: + debug_printf("EMIT_4UB:\t"); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + break; + default: + assert(0); + } + debug_printf("\n"); + } + debug_printf("\n"); +} +#endif + + +/** + * Extract the needed fields from post-transformed vertex and emit + * a hardware(driver) vertex. + * Recall that the vertices are constructed by the 'draw' module and + * have a couple of slots at the beginning (1-dword header, 4-dword + * clip pos) that we ignore here. We only use the vertex->data[] fields. + */ +static INLINE void +emit_vertex( struct vbuf_stage *vbuf, + struct vertex_header *vertex ) +{ +#if 0 + debug_printf("emit vertex %d to %p\n", + vbuf->nr_vertices, vbuf->vertex_ptr); +#endif + + if(vertex->vertex_id != UNDEFINED_VERTEX_ID) { + if(vertex->vertex_id < vbuf->nr_vertices) + return; + else + debug_printf("Bad vertex id 0x%04x (>= 0x%04x)\n", + vertex->vertex_id, vbuf->nr_vertices); + return; + } + + vertex->vertex_id = vbuf->nr_vertices++; + + if(!vbuf->vf) { + const struct vertex_info *vinfo = vbuf->vinfo; + uint i; + uint count = 0; /* for debug/sanity */ + + assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); + + for (i = 0; i < vinfo->num_attribs; i++) { + uint j = vinfo->src_index[i]; + switch (vinfo->emit[i]) { + case EMIT_OMIT: + /* no-op */ + break; + case EMIT_ALL: + /* just copy the whole vertex as-is to the vbuf */ + assert(i == 0); + assert(j == 0); + memcpy(vbuf->vertex_ptr, vertex, vinfo->size * 4); + vbuf->vertex_ptr += vinfo->size; + count += vinfo->size; + break; + case EMIT_1F: + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + count++; + break; + case EMIT_1F_PSIZE: + *vbuf->vertex_ptr++ = fui(vbuf->stage.draw->rasterizer->point_size); + count++; + break; + case EMIT_2F: + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); + count += 2; + break; + case EMIT_3F: + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); + count += 3; + break; + case EMIT_4F: + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][3]); + count += 4; + break; + case EMIT_4UB: + *vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[j][2] ), + float_to_ubyte( vertex->data[j][1] ), + float_to_ubyte( vertex->data[j][0] ), + float_to_ubyte( vertex->data[j][3] )); + count += 1; + break; + default: + assert(0); + } + } + assert(count == vinfo->size); +#if 0 + { + static float data[256]; + draw_vf_emit_vertex(vbuf->vf, vertex, data); + if(memcmp((uint8_t *)vbuf->vertex_ptr - vbuf->vertex_size, data, vbuf->vertex_size)) { + debug_printf("With VF:\n"); + dump_emitted_vertex(vbuf->vinfo, (uint8_t *)data); + debug_printf("Without VF:\n"); + dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr - vbuf->vertex_size); + assert(0); + } + } +#endif + } + else { + draw_vf_emit_vertex(vbuf->vf, vertex, vbuf->vertex_ptr); + + vbuf->vertex_ptr += vbuf->vertex_size/4; + } +} + + +static void +vbuf_tri( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + unsigned i; + + check_space( vbuf, 3 ); + + for (i = 0; i < 3; i++) { + emit_vertex( vbuf, prim->v[i] ); + + vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[i]->vertex_id; + } +} + + +static void +vbuf_line( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + unsigned i; + + check_space( vbuf, 2 ); + + for (i = 0; i < 2; i++) { + emit_vertex( vbuf, prim->v[i] ); + + vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[i]->vertex_id; + } +} + + +static void +vbuf_point( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + check_space( vbuf, 1 ); + + emit_vertex( vbuf, prim->v[0] ); + + vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[0]->vertex_id; +} + + +/** + * Set the prim type for subsequent vertices. + * This may result in a new vertex size. The existing vbuffer (if any) + * will be flushed if needed and a new one allocated. + */ +static void +vbuf_set_prim( struct vbuf_stage *vbuf, uint newprim ) +{ + const struct vertex_info *vinfo; + unsigned vertex_size; + + assert(newprim == PIPE_PRIM_POINTS || + newprim == PIPE_PRIM_LINES || + newprim == PIPE_PRIM_TRIANGLES); + + vbuf->prim = newprim; + vbuf->render->set_primitive(vbuf->render, newprim); + + vinfo = vbuf->render->get_vertex_info(vbuf->render); + vertex_size = vinfo->size * sizeof(float); + + if (vertex_size != vbuf->vertex_size) + vbuf_flush_vertices(vbuf); + + vbuf->vinfo = vinfo; + vbuf->vertex_size = vertex_size; + if(vbuf->vf) + draw_vf_set_vertex_info(vbuf->vf, + vbuf->vinfo, + vbuf->stage.draw->rasterizer->point_size); + + if (!vbuf->vertices) + vbuf_alloc_vertices(vbuf); +} + + +static void +vbuf_first_tri( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->tri = vbuf_tri; + vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES); + stage->tri( stage, prim ); +} + + +static void +vbuf_first_line( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->line = vbuf_line; + vbuf_set_prim(vbuf, PIPE_PRIM_LINES); + stage->line( stage, prim ); +} + + +static void +vbuf_first_point( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->point = vbuf_point; + vbuf_set_prim(vbuf, PIPE_PRIM_POINTS); + stage->point( stage, prim ); +} + + +static void +vbuf_flush_indices( struct vbuf_stage *vbuf ) +{ + if(!vbuf->nr_indices) + return; + + assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == + vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned)); + + switch(vbuf->prim) { + case PIPE_PRIM_POINTS: + break; + case PIPE_PRIM_LINES: + assert(vbuf->nr_indices % 2 == 0); + break; + case PIPE_PRIM_TRIANGLES: + assert(vbuf->nr_indices % 3 == 0); + break; + default: + assert(0); + } + + vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices); + + vbuf->nr_indices = 0; + + /* don't need to reset point/line/tri functions */ +#if 0 + stage->point = vbuf_first_point; + stage->line = vbuf_first_line; + stage->tri = vbuf_first_tri; +#endif +} + + +/** + * Flush existing vertex buffer and allocate a new one. + * + * XXX: We separate flush-on-index-full and flush-on-vb-full, but may + * raise issues uploading vertices if the hardware wants to flush when + * we flush. + */ +static void +vbuf_flush_vertices( struct vbuf_stage *vbuf ) +{ + if(vbuf->vertices) { + vbuf_flush_indices(vbuf); + + /* Reset temporary vertices ids */ + if(vbuf->nr_vertices) + draw_reset_vertex_ids( vbuf->stage.draw ); + + /* Free the vertex buffer */ + vbuf->render->release_vertices(vbuf->render, + vbuf->vertices, + vbuf->vertex_size, + vbuf->nr_vertices); + vbuf->max_vertices = vbuf->nr_vertices = 0; + vbuf->vertex_ptr = vbuf->vertices = NULL; + + } +} + + +static void +vbuf_alloc_vertices( struct vbuf_stage *vbuf ) +{ + assert(!vbuf->nr_indices); + assert(!vbuf->vertices); + + /* Allocate a new vertex buffer */ + vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; + vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, + (ushort) vbuf->vertex_size, + (ushort) vbuf->max_vertices); + vbuf->vertex_ptr = vbuf->vertices; +} + + + +static void +vbuf_flush( struct draw_stage *stage, unsigned flags ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + + stage->point = vbuf_first_point; + stage->line = vbuf_first_line; + stage->tri = vbuf_first_tri; + + if (flags & DRAW_FLUSH_BACKEND) + vbuf_flush_vertices( vbuf ); +} + + +static void +vbuf_reset_stipple_counter( struct draw_stage *stage ) +{ + /* XXX: Need to do something here for hardware with linestipple. + */ + (void) stage; +} + + +static void vbuf_destroy( struct draw_stage *stage ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + if(vbuf->indices) + align_free( vbuf->indices ); + + if(vbuf->vf) + draw_vf_destroy( vbuf->vf ); + + if (vbuf->render) + vbuf->render->destroy( vbuf->render ); + + FREE( stage ); +} + + +/** + * Create a new primitive vbuf/render stage. + */ +struct draw_stage *draw_vbuf_stage( struct draw_context *draw, + struct vbuf_render *render ) +{ + struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); + + if(!vbuf) + return NULL; + + vbuf->stage.draw = draw; + vbuf->stage.point = vbuf_first_point; + vbuf->stage.line = vbuf_first_line; + vbuf->stage.tri = vbuf_first_tri; + vbuf->stage.flush = vbuf_flush; + vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter; + vbuf->stage.destroy = vbuf_destroy; + + vbuf->render = render; + + assert(render->max_indices < UNDEFINED_VERTEX_ID); + vbuf->max_indices = render->max_indices; + vbuf->indices = (ushort *) + align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 ); + if(!vbuf->indices) + vbuf_destroy(&vbuf->stage); + + vbuf->vertices = NULL; + vbuf->vertex_ptr = vbuf->vertices; + + vbuf->prim = ~0; + + if(!GETENV("GALLIUM_NOVF")) + vbuf->vf = draw_vf_create(); + + return &vbuf->stage; +} diff --git a/src/gallium/aux/draw/draw_vbuf.h b/src/gallium/aux/draw/draw_vbuf.h new file mode 100644 index 0000000000..cfd2b9820c --- /dev/null +++ b/src/gallium/aux/draw/draw_vbuf.h @@ -0,0 +1,106 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Vertex buffer drawing stage. + * + * \author Keith Whitwell + * \author José Fonseca + */ + +#ifndef DRAW_VBUF_H_ +#define DRAW_VBUF_H_ + + +#include "pipe/p_util.h" + + +struct draw_context; +struct vertex_info; + + +/** + * Interface for hardware vertex buffer rendering. + */ +struct vbuf_render { + + /** + * Driver limits. May be tuned lower to improve cache hits on + * index list. + */ + unsigned max_indices; + unsigned max_vertex_buffer_bytes; + + /** + * Get the hardware vertex format. + * + * XXX: have this in draw_context instead? + */ + const struct vertex_info *(*get_vertex_info)( struct vbuf_render * ); + + /** + * Request a destination for vertices. + * Hardware renderers will use ttm memory, others will just malloc + * something. + */ + void *(*allocate_vertices)( struct vbuf_render *, + ushort vertex_size, + ushort nr_vertices ); + + /** + * Notify the renderer of the current primitive when it changes. + * Prim is restricted to TRIANGLES, LINES and POINTS. + */ + void (*set_primitive)( struct vbuf_render *, unsigned prim ); + + /** + * DrawElements, note indices are ushort: + */ + void (*draw)( struct vbuf_render *, + const ushort *indices, + uint nr_indices ); + + /** + * Called when vbuf is done with this set of vertices: + */ + void (*release_vertices)( struct vbuf_render *, + void *vertices, + unsigned vertex_size, + unsigned vertices_used ); + + void (*destroy)( struct vbuf_render * ); +}; + + + +struct draw_stage * +draw_vbuf_stage( struct draw_context *draw, + struct vbuf_render *render ); + + +#endif /*DRAW_VBUF_H_*/ diff --git a/src/gallium/aux/draw/draw_vertex.c b/src/gallium/aux/draw/draw_vertex.c new file mode 100644 index 0000000000..2d6592150f --- /dev/null +++ b/src/gallium/aux/draw/draw_vertex.c @@ -0,0 +1,79 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* + * Functions for specifying the post-transformation vertex layout. + * + * Author: + * Brian Paul + * Keith Whitwell + */ + + +#include "pipe/draw/draw_private.h" +#include "pipe/draw/draw_vertex.h" + + +/** + * Compute the size of a vertex, in dwords/floats, to update the + * vinfo->size field. + */ +void +draw_compute_vertex_size(struct vertex_info *vinfo) +{ + uint i; + + vinfo->size = 0; + for (i = 0; i < vinfo->num_attribs; i++) { + switch (vinfo->emit[i]) { + case EMIT_OMIT: + break; + case EMIT_4UB: + /* fall-through */ + case EMIT_1F_PSIZE: + /* fall-through */ + case EMIT_1F: + vinfo->size += 1; + break; + case EMIT_2F: + vinfo->size += 2; + break; + case EMIT_3F: + vinfo->size += 3; + break; + case EMIT_4F: + vinfo->size += 4; + break; + case EMIT_ALL: + /* fall-through */ + default: + assert(0); + } + } + + assert(vinfo->size * 4 <= MAX_VERTEX_SIZE); +} diff --git a/src/gallium/aux/draw/draw_vertex.h b/src/gallium/aux/draw/draw_vertex.h new file mode 100644 index 0000000000..267c74203b --- /dev/null +++ b/src/gallium/aux/draw/draw_vertex.h @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Post-transform vertex format info. The vertex_info struct is used by + * the draw_vbuf code to emit hardware-specific vertex layouts into hw + * vertex buffers. + * + * Author: + * Brian Paul + */ + + +#ifndef DRAW_VERTEX_H +#define DRAW_VERTEX_H + + +#include "pipe/p_state.h" + + +/** + * Vertex attribute emit modes + */ +enum attrib_emit { + EMIT_OMIT, /**< don't emit the attribute */ + EMIT_ALL, /**< emit whole post-xform vertex, w/ header */ + EMIT_1F, + EMIT_1F_PSIZE, /**< insert constant point size */ + EMIT_2F, + EMIT_3F, + EMIT_4F, + EMIT_4UB /**< XXX may need variations for RGBA vs BGRA, etc */ +}; + + +/** + * Attribute interpolation mode + */ +enum interp_mode { + INTERP_NONE, /**< never interpolate vertex header info */ + INTERP_POS, /**< special case for frag position */ + INTERP_CONSTANT, + INTERP_LINEAR, + INTERP_PERSPECTIVE +}; + + +/** + * Information about hardware/rasterization vertex layout. + */ +struct vertex_info +{ + uint num_attribs; + uint hwfmt[4]; /**< hardware format info for this format */ + enum interp_mode interp_mode[PIPE_MAX_SHADER_INPUTS]; + enum attrib_emit emit[PIPE_MAX_SHADER_INPUTS]; /**< EMIT_x */ + uint src_index[PIPE_MAX_SHADER_INPUTS]; /**< map to post-xform attribs */ + uint size; /**< total vertex size in dwords */ +}; + + + +/** + * Add another attribute to the given vertex_info object. + * \param src_index indicates which post-transformed vertex attrib slot + * corresponds to this attribute. + * \return slot in which the attribute was added + */ +static INLINE uint +draw_emit_vertex_attr(struct vertex_info *vinfo, + enum attrib_emit emit, enum interp_mode interp, + uint src_index) +{ + const uint n = vinfo->num_attribs; + assert(n < PIPE_MAX_SHADER_INPUTS); + vinfo->emit[n] = emit; + vinfo->interp_mode[n] = interp; + vinfo->src_index[n] = src_index; + vinfo->num_attribs++; + return n; +} + + +extern void draw_compute_vertex_size(struct vertex_info *vinfo); + + +#endif /* DRAW_VERTEX_H */ diff --git a/src/gallium/aux/draw/draw_vertex_cache.c b/src/gallium/aux/draw/draw_vertex_cache.c new file mode 100644 index 0000000000..44427999cc --- /dev/null +++ b/src/gallium/aux/draw/draw_vertex_cache.c @@ -0,0 +1,196 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw_private.h" +#include "draw_context.h" + + +void draw_vertex_cache_invalidate( struct draw_context *draw ) +{ + assert(draw->pq.queue_nr == 0); + assert(draw->vs.queue_nr == 0); + assert(draw->vcache.referenced == 0); + + memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx)); +} + + +/** + * Check if vertex is in cache, otherwise add it. It won't go through + * VS yet, not until there is a flush operation or the VS queue fills up. + * + * Note that cache entries are basically just two pointers: the first + * an index into the user's vertex arrays, the second a location in + * the vertex shader cache for the post-transformed vertex. + * + * \return pointer to location of (post-transformed) vertex header in the cache + */ +static struct vertex_header *get_vertex( struct draw_context *draw, + unsigned i ) +{ + unsigned slot = (i + (i>>5)) % VCACHE_SIZE; + + assert(slot < 32); /* so we don't exceed the bitfield size below */ + + /* Cache miss? + */ + if (draw->vcache.idx[slot] != i) { + + /* If slot is in use, use the overflow area: + */ + if (draw->vcache.referenced & (1 << slot)) { + slot = VCACHE_SIZE + draw->vcache.overflow++; + } + + assert(slot < Elements(draw->vcache.idx)); + + draw->vcache.idx[slot] = i; + + /* Add to vertex shader queue: + */ + assert(draw->vs.queue_nr < VS_QUEUE_LENGTH); + draw->vs.queue[draw->vs.queue_nr].dest = draw->vcache.vertex[slot]; + draw->vs.queue[draw->vs.queue_nr].elt = i; + draw->vs.queue_nr++; + + /* Need to set the vertex's edge flag here. If we're being called + * by do_ef_triangle(), that function needs edge flag info! + */ + draw->vcache.vertex[slot]->clipmask = 0; + draw->vcache.vertex[slot]->edgeflag = 1; /*XXX use user's edge flag! */ + draw->vcache.vertex[slot]->pad = 0; + draw->vcache.vertex[slot]->vertex_id = UNDEFINED_VERTEX_ID; + } + + + /* primitive flushing may have cleared the bitfield but did not + * clear the idx[] array values. Set the bit now. This fixes a + * bug found when drawing long triangle fans. + */ + draw->vcache.referenced |= (1 << slot); + return draw->vcache.vertex[slot]; +} + + +static struct vertex_header *get_uint_elt_vertex( struct draw_context *draw, + unsigned i ) +{ + const unsigned *elts = (const unsigned *) draw->user.elts; + return get_vertex( draw, elts[i] ); +} + + +static struct vertex_header *get_ushort_elt_vertex( struct draw_context *draw, + unsigned i ) +{ + const ushort *elts = (const ushort *) draw->user.elts; + return get_vertex( draw, elts[i] ); +} + + +static struct vertex_header *get_ubyte_elt_vertex( struct draw_context *draw, + unsigned i ) +{ + const ubyte *elts = (const ubyte *) draw->user.elts; + return get_vertex( draw, elts[i] ); +} + + +void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ) +{ + unsigned i; + + for (i = 0; i < Elements(draw->vcache.vertex); i++) + draw->vcache.vertex[i]->vertex_id = UNDEFINED_VERTEX_ID; +} + + +void draw_vertex_cache_unreference( struct draw_context *draw ) +{ + draw->vcache.referenced = 0; + draw->vcache.overflow = 0; +} + + +int draw_vertex_cache_check_space( struct draw_context *draw, + unsigned nr_verts ) +{ + if (draw->vcache.overflow + nr_verts < VCACHE_OVERFLOW) { + /* The vs queue is sized so that this can never happen: + */ + assert(draw->vs.queue_nr + nr_verts < VS_QUEUE_LENGTH); + return TRUE; + } + else + return FALSE; +} + + + +/** + * Tell the drawing context about the index/element buffer to use + * (ala glDrawElements) + * If no element buffer is to be used (i.e. glDrawArrays) then this + * should be called with eltSize=0 and elements=NULL. + * + * \param draw the drawing context + * \param eltSize size of each element (1, 2 or 4 bytes) + * \param elements the element buffer ptr + */ +void +draw_set_mapped_element_buffer( struct draw_context *draw, + unsigned eltSize, void *elements ) +{ +// draw_statechange( draw ); + + /* choose the get_vertex() function to use */ + switch (eltSize) { + case 0: + draw->vcache.get_vertex = get_vertex; + break; + case 1: + draw->vcache.get_vertex = get_ubyte_elt_vertex; + break; + case 2: + draw->vcache.get_vertex = get_ushort_elt_vertex; + break; + case 4: + draw->vcache.get_vertex = get_uint_elt_vertex; + break; + default: + assert(0); + } + draw->user.elts = elements; + draw->user.eltSize = eltSize; +} + diff --git a/src/gallium/aux/draw/draw_vertex_fetch.c b/src/gallium/aux/draw/draw_vertex_fetch.c new file mode 100644 index 0000000000..e13df04605 --- /dev/null +++ b/src/gallium/aux/draw/draw_vertex_fetch.c @@ -0,0 +1,510 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" +#include "draw_context.h" + + +#define DRAW_DBG 0 + + +/** + * Fetch a float[4] vertex attribute from memory, doing format/type + * conversion as needed. + * + * This is probably needed/dupliocated elsewhere, eg format + * conversion, texture sampling etc. + */ +#define FETCH_ATTRIB( NAME, SZ, CVT ) \ +static void \ +fetch_##NAME(const void *ptr, float *attrib) \ +{ \ + static const float defaults[4] = { 0,0,0,1 }; \ + int i; \ + \ + for (i = 0; i < SZ; i++) { \ + attrib[i] = CVT; \ + } \ + \ + for (; i < 4; i++) { \ + attrib[i] = defaults[i]; \ + } \ +} + +#define CVT_64_FLOAT (float) ((double *) ptr)[i] +#define CVT_32_FLOAT ((float *) ptr)[i] + +#define CVT_8_USCALED (float) ((unsigned char *) ptr)[i] +#define CVT_16_USCALED (float) ((unsigned short *) ptr)[i] +#define CVT_32_USCALED (float) ((unsigned int *) ptr)[i] + +#define CVT_8_SSCALED (float) ((char *) ptr)[i] +#define CVT_16_SSCALED (float) ((short *) ptr)[i] +#define CVT_32_SSCALED (float) ((int *) ptr)[i] + +#define CVT_8_UNORM (float) ((unsigned char *) ptr)[i] / 255.0f +#define CVT_16_UNORM (float) ((unsigned short *) ptr)[i] / 65535.0f +#define CVT_32_UNORM (float) ((unsigned int *) ptr)[i] / 4294967295.0f + +#define CVT_8_SNORM (float) ((char *) ptr)[i] / 127.0f +#define CVT_16_SNORM (float) ((short *) ptr)[i] / 32767.0f +#define CVT_32_SNORM (float) ((int *) ptr)[i] / 2147483647.0f + +FETCH_ATTRIB( R64G64B64A64_FLOAT, 4, CVT_64_FLOAT ) +FETCH_ATTRIB( R64G64B64_FLOAT, 3, CVT_64_FLOAT ) +FETCH_ATTRIB( R64G64_FLOAT, 2, CVT_64_FLOAT ) +FETCH_ATTRIB( R64_FLOAT, 1, CVT_64_FLOAT ) + +FETCH_ATTRIB( R32G32B32A32_FLOAT, 4, CVT_32_FLOAT ) +FETCH_ATTRIB( R32G32B32_FLOAT, 3, CVT_32_FLOAT ) +FETCH_ATTRIB( R32G32_FLOAT, 2, CVT_32_FLOAT ) +FETCH_ATTRIB( R32_FLOAT, 1, CVT_32_FLOAT ) + +FETCH_ATTRIB( R32G32B32A32_USCALED, 4, CVT_32_USCALED ) +FETCH_ATTRIB( R32G32B32_USCALED, 3, CVT_32_USCALED ) +FETCH_ATTRIB( R32G32_USCALED, 2, CVT_32_USCALED ) +FETCH_ATTRIB( R32_USCALED, 1, CVT_32_USCALED ) + +FETCH_ATTRIB( R32G32B32A32_SSCALED, 4, CVT_32_SSCALED ) +FETCH_ATTRIB( R32G32B32_SSCALED, 3, CVT_32_SSCALED ) +FETCH_ATTRIB( R32G32_SSCALED, 2, CVT_32_SSCALED ) +FETCH_ATTRIB( R32_SSCALED, 1, CVT_32_SSCALED ) + +FETCH_ATTRIB( R32G32B32A32_UNORM, 4, CVT_32_UNORM ) +FETCH_ATTRIB( R32G32B32_UNORM, 3, CVT_32_UNORM ) +FETCH_ATTRIB( R32G32_UNORM, 2, CVT_32_UNORM ) +FETCH_ATTRIB( R32_UNORM, 1, CVT_32_UNORM ) + +FETCH_ATTRIB( R32G32B32A32_SNORM, 4, CVT_32_SNORM ) +FETCH_ATTRIB( R32G32B32_SNORM, 3, CVT_32_SNORM ) +FETCH_ATTRIB( R32G32_SNORM, 2, CVT_32_SNORM ) +FETCH_ATTRIB( R32_SNORM, 1, CVT_32_SNORM ) + +FETCH_ATTRIB( R16G16B16A16_USCALED, 4, CVT_16_USCALED ) +FETCH_ATTRIB( R16G16B16_USCALED, 3, CVT_16_USCALED ) +FETCH_ATTRIB( R16G16_USCALED, 2, CVT_16_USCALED ) +FETCH_ATTRIB( R16_USCALED, 1, CVT_16_USCALED ) + +FETCH_ATTRIB( R16G16B16A16_SSCALED, 4, CVT_16_SSCALED ) +FETCH_ATTRIB( R16G16B16_SSCALED, 3, CVT_16_SSCALED ) +FETCH_ATTRIB( R16G16_SSCALED, 2, CVT_16_SSCALED ) +FETCH_ATTRIB( R16_SSCALED, 1, CVT_16_SSCALED ) + +FETCH_ATTRIB( R16G16B16A16_UNORM, 4, CVT_16_UNORM ) +FETCH_ATTRIB( R16G16B16_UNORM, 3, CVT_16_UNORM ) +FETCH_ATTRIB( R16G16_UNORM, 2, CVT_16_UNORM ) +FETCH_ATTRIB( R16_UNORM, 1, CVT_16_UNORM ) + +FETCH_ATTRIB( R16G16B16A16_SNORM, 4, CVT_16_SNORM ) +FETCH_ATTRIB( R16G16B16_SNORM, 3, CVT_16_SNORM ) +FETCH_ATTRIB( R16G16_SNORM, 2, CVT_16_SNORM ) +FETCH_ATTRIB( R16_SNORM, 1, CVT_16_SNORM ) + +FETCH_ATTRIB( R8G8B8A8_USCALED, 4, CVT_8_USCALED ) +FETCH_ATTRIB( R8G8B8_USCALED, 3, CVT_8_USCALED ) +FETCH_ATTRIB( R8G8_USCALED, 2, CVT_8_USCALED ) +FETCH_ATTRIB( R8_USCALED, 1, CVT_8_USCALED ) + +FETCH_ATTRIB( R8G8B8A8_SSCALED, 4, CVT_8_SSCALED ) +FETCH_ATTRIB( R8G8B8_SSCALED, 3, CVT_8_SSCALED ) +FETCH_ATTRIB( R8G8_SSCALED, 2, CVT_8_SSCALED ) +FETCH_ATTRIB( R8_SSCALED, 1, CVT_8_SSCALED ) + +FETCH_ATTRIB( R8G8B8A8_UNORM, 4, CVT_8_UNORM ) +FETCH_ATTRIB( R8G8B8_UNORM, 3, CVT_8_UNORM ) +FETCH_ATTRIB( R8G8_UNORM, 2, CVT_8_UNORM ) +FETCH_ATTRIB( R8_UNORM, 1, CVT_8_UNORM ) + +FETCH_ATTRIB( R8G8B8A8_SNORM, 4, CVT_8_SNORM ) +FETCH_ATTRIB( R8G8B8_SNORM, 3, CVT_8_SNORM ) +FETCH_ATTRIB( R8G8_SNORM, 2, CVT_8_SNORM ) +FETCH_ATTRIB( R8_SNORM, 1, CVT_8_SNORM ) + +FETCH_ATTRIB( A8R8G8B8_UNORM, 4, CVT_8_UNORM ) +//FETCH_ATTRIB( R8G8B8A8_UNORM, 4, CVT_8_UNORM ) + + + +static fetch_func get_fetch_func( enum pipe_format format ) +{ +#if 0 + { + char tmp[80]; + pf_sprint_name(tmp, format); + debug_printf("%s: %s\n", __FUNCTION__, tmp); + } +#endif + + switch (format) { + case PIPE_FORMAT_R64_FLOAT: + return fetch_R64_FLOAT; + case PIPE_FORMAT_R64G64_FLOAT: + return fetch_R64G64_FLOAT; + case PIPE_FORMAT_R64G64B64_FLOAT: + return fetch_R64G64B64_FLOAT; + case PIPE_FORMAT_R64G64B64A64_FLOAT: + return fetch_R64G64B64A64_FLOAT; + + case PIPE_FORMAT_R32_FLOAT: + return fetch_R32_FLOAT; + case PIPE_FORMAT_R32G32_FLOAT: + return fetch_R32G32_FLOAT; + case PIPE_FORMAT_R32G32B32_FLOAT: + return fetch_R32G32B32_FLOAT; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return fetch_R32G32B32A32_FLOAT; + + case PIPE_FORMAT_R32_UNORM: + return fetch_R32_UNORM; + case PIPE_FORMAT_R32G32_UNORM: + return fetch_R32G32_UNORM; + case PIPE_FORMAT_R32G32B32_UNORM: + return fetch_R32G32B32_UNORM; + case PIPE_FORMAT_R32G32B32A32_UNORM: + return fetch_R32G32B32A32_UNORM; + + case PIPE_FORMAT_R32_USCALED: + return fetch_R32_USCALED; + case PIPE_FORMAT_R32G32_USCALED: + return fetch_R32G32_USCALED; + case PIPE_FORMAT_R32G32B32_USCALED: + return fetch_R32G32B32_USCALED; + case PIPE_FORMAT_R32G32B32A32_USCALED: + return fetch_R32G32B32A32_USCALED; + + case PIPE_FORMAT_R32_SNORM: + return fetch_R32_SNORM; + case PIPE_FORMAT_R32G32_SNORM: + return fetch_R32G32_SNORM; + case PIPE_FORMAT_R32G32B32_SNORM: + return fetch_R32G32B32_SNORM; + case PIPE_FORMAT_R32G32B32A32_SNORM: + return fetch_R32G32B32A32_SNORM; + + case PIPE_FORMAT_R32_SSCALED: + return fetch_R32_SSCALED; + case PIPE_FORMAT_R32G32_SSCALED: + return fetch_R32G32_SSCALED; + case PIPE_FORMAT_R32G32B32_SSCALED: + return fetch_R32G32B32_SSCALED; + case PIPE_FORMAT_R32G32B32A32_SSCALED: + return fetch_R32G32B32A32_SSCALED; + + case PIPE_FORMAT_R16_UNORM: + return fetch_R16_UNORM; + case PIPE_FORMAT_R16G16_UNORM: + return fetch_R16G16_UNORM; + case PIPE_FORMAT_R16G16B16_UNORM: + return fetch_R16G16B16_UNORM; + case PIPE_FORMAT_R16G16B16A16_UNORM: + return fetch_R16G16B16A16_UNORM; + + case PIPE_FORMAT_R16_USCALED: + return fetch_R16_USCALED; + case PIPE_FORMAT_R16G16_USCALED: + return fetch_R16G16_USCALED; + case PIPE_FORMAT_R16G16B16_USCALED: + return fetch_R16G16B16_USCALED; + case PIPE_FORMAT_R16G16B16A16_USCALED: + return fetch_R16G16B16A16_USCALED; + + case PIPE_FORMAT_R16_SNORM: + return fetch_R16_SNORM; + case PIPE_FORMAT_R16G16_SNORM: + return fetch_R16G16_SNORM; + case PIPE_FORMAT_R16G16B16_SNORM: + return fetch_R16G16B16_SNORM; + case PIPE_FORMAT_R16G16B16A16_SNORM: + return fetch_R16G16B16A16_SNORM; + + case PIPE_FORMAT_R16_SSCALED: + return fetch_R16_SSCALED; + case PIPE_FORMAT_R16G16_SSCALED: + return fetch_R16G16_SSCALED; + case PIPE_FORMAT_R16G16B16_SSCALED: + return fetch_R16G16B16_SSCALED; + case PIPE_FORMAT_R16G16B16A16_SSCALED: + return fetch_R16G16B16A16_SSCALED; + + case PIPE_FORMAT_R8_UNORM: + return fetch_R8_UNORM; + case PIPE_FORMAT_R8G8_UNORM: + return fetch_R8G8_UNORM; + case PIPE_FORMAT_R8G8B8_UNORM: + return fetch_R8G8B8_UNORM; + case PIPE_FORMAT_R8G8B8A8_UNORM: + return fetch_R8G8B8A8_UNORM; + + case PIPE_FORMAT_R8_USCALED: + return fetch_R8_USCALED; + case PIPE_FORMAT_R8G8_USCALED: + return fetch_R8G8_USCALED; + case PIPE_FORMAT_R8G8B8_USCALED: + return fetch_R8G8B8_USCALED; + case PIPE_FORMAT_R8G8B8A8_USCALED: + return fetch_R8G8B8A8_USCALED; + + case PIPE_FORMAT_R8_SNORM: + return fetch_R8_SNORM; + case PIPE_FORMAT_R8G8_SNORM: + return fetch_R8G8_SNORM; + case PIPE_FORMAT_R8G8B8_SNORM: + return fetch_R8G8B8_SNORM; + case PIPE_FORMAT_R8G8B8A8_SNORM: + return fetch_R8G8B8A8_SNORM; + + case PIPE_FORMAT_R8_SSCALED: + return fetch_R8_SSCALED; + case PIPE_FORMAT_R8G8_SSCALED: + return fetch_R8G8_SSCALED; + case PIPE_FORMAT_R8G8B8_SSCALED: + return fetch_R8G8B8_SSCALED; + case PIPE_FORMAT_R8G8B8A8_SSCALED: + return fetch_R8G8B8A8_SSCALED; + + case PIPE_FORMAT_A8R8G8B8_UNORM: + return fetch_A8R8G8B8_UNORM; + + case 0: + return NULL; /* not sure why this is needed */ + + default: + assert(0); + return NULL; + } +} + + +static void +transpose_4x4( float *out, const float *in ) +{ + /* This can be achieved in 12 sse instructions, plus the final + * stores I guess. This is probably a bit more than that - maybe + * 32 or so? + */ + out[0] = in[0]; out[1] = in[4]; out[2] = in[8]; out[3] = in[12]; + out[4] = in[1]; out[5] = in[5]; out[6] = in[9]; out[7] = in[13]; + out[8] = in[2]; out[9] = in[6]; out[10] = in[10]; out[11] = in[14]; + out[12] = in[3]; out[13] = in[7]; out[14] = in[11]; out[15] = in[15]; +} + + + +static void fetch_xyz_rgb( struct draw_context *draw, + struct tgsi_exec_machine *machine, + const unsigned *elts, + unsigned count ) +{ + const unsigned *pitch = draw->vertex_fetch.pitch; + const ubyte **src = draw->vertex_fetch.src_ptr; + int i; + + assert(count <= 4); + +// debug_printf("%s\n", __FUNCTION__); + + /* loop over vertex attributes (vertex shader inputs) + */ + + for (i = 0; i < 4; i++) { + { + const float *in = (const float *)(src[0] + elts[i] * pitch[0]); + float *out = &machine->Inputs[0].xyzw[0].f[i]; + out[0] = in[0]; + out[4] = in[1]; + out[8] = in[2]; + out[12] = 1.0f; + } + + { + const float *in = (const float *)(src[1] + elts[i] * pitch[1]); + float *out = &machine->Inputs[1].xyzw[0].f[i]; + out[0] = in[0]; + out[4] = in[1]; + out[8] = in[2]; + out[12] = 1.0f; + } + } +} + + + + +static void fetch_xyz_rgb_st( struct draw_context *draw, + struct tgsi_exec_machine *machine, + const unsigned *elts, + unsigned count ) +{ + const unsigned *pitch = draw->vertex_fetch.pitch; + const ubyte **src = draw->vertex_fetch.src_ptr; + int i; + + assert(count <= 4); + + /* loop over vertex attributes (vertex shader inputs) + */ + + for (i = 0; i < 4; i++) { + { + const float *in = (const float *)(src[0] + elts[i] * pitch[0]); + float *out = &machine->Inputs[0].xyzw[0].f[i]; + out[0] = in[0]; + out[4] = in[1]; + out[8] = in[2]; + out[12] = 1.0f; + } + + { + const float *in = (const float *)(src[1] + elts[i] * pitch[1]); + float *out = &machine->Inputs[1].xyzw[0].f[i]; + out[0] = in[0]; + out[4] = in[1]; + out[8] = in[2]; + out[12] = 1.0f; + } + + { + const float *in = (const float *)(src[2] + elts[i] * pitch[2]); + float *out = &machine->Inputs[2].xyzw[0].f[i]; + out[0] = in[0]; + out[4] = in[1]; + out[8] = 0.0f; + out[12] = 1.0f; + } + } +} + + + + +/** + * Fetch vertex attributes for 'count' vertices. + */ +static void generic_vertex_fetch( struct draw_context *draw, + struct tgsi_exec_machine *machine, + const unsigned *elts, + unsigned count ) +{ + unsigned nr_attrs = draw->vertex_fetch.nr_attrs; + unsigned attr; + + assert(count <= 4); + +// debug_printf("%s %d\n", __FUNCTION__, count); + + /* loop over vertex attributes (vertex shader inputs) + */ + for (attr = 0; attr < nr_attrs; attr++) { + + const unsigned pitch = draw->vertex_fetch.pitch[attr]; + const ubyte *src = draw->vertex_fetch.src_ptr[attr]; + const fetch_func fetch = draw->vertex_fetch.fetch[attr]; + unsigned i; + float p[4][4]; + + + /* Fetch four attributes for four vertices. + * + * Could fetch directly into AOS format, but this is meant to be + * a prototype for an sse implementation, which would have + * difficulties doing that. + */ + for (i = 0; i < count; i++) + fetch( src + elts[i] * pitch, p[i] ); + + /* Be nice and zero out any missing vertices: + */ + for ( ; i < 4; i++) + p[i][0] = p[i][1] = p[i][2] = p[i][3] = 0; + + /* Transpose/swizzle into sse-friendly format. Currently + * assuming that all vertex shader inputs are float[4], but this + * isn't true -- if the vertex shader only wants tex0.xy, we + * could optimize for that. + * + * To do so fully without codegen would probably require an + * excessive number of fetch functions, but we could at least + * minimize the transpose step: + */ + transpose_4x4( (float *)&machine->Inputs[attr].xyzw[0].f[0], (float *)p ); + } +} + + + +void draw_update_vertex_fetch( struct draw_context *draw ) +{ + unsigned nr_attrs, i; + +// debug_printf("%s\n", __FUNCTION__); + + /* this may happend during context init */ + if (!draw->vertex_shader) + return; + + nr_attrs = draw->vertex_shader->state->num_inputs; + + for (i = 0; i < nr_attrs; i++) { + unsigned buf = draw->vertex_element[i].vertex_buffer_index; + enum pipe_format format = draw->vertex_element[i].src_format; + + draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] + + draw->vertex_buffer[buf].buffer_offset + + draw->vertex_element[i].src_offset; + + draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch; + draw->vertex_fetch.fetch[i] = get_fetch_func( format ); + } + + draw->vertex_fetch.nr_attrs = nr_attrs; + + draw->vertex_fetch.fetch_func = generic_vertex_fetch; + + switch (nr_attrs) { + case 2: + if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT && + draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT) + draw->vertex_fetch.fetch_func = fetch_xyz_rgb; + break; + case 3: + if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT && + draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT && + draw->vertex_element[2].src_format == PIPE_FORMAT_R32G32_FLOAT) + draw->vertex_fetch.fetch_func = fetch_xyz_rgb_st; + break; + default: + break; + } + +} diff --git a/src/gallium/aux/draw/draw_vertex_shader.c b/src/gallium/aux/draw/draw_vertex_shader.c new file mode 100644 index 0000000000..c824c1407e --- /dev/null +++ b/src/gallium/aux/draw/draw_vertex_shader.c @@ -0,0 +1,325 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + * Brian Paul + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#if defined(__i386__) || defined(__386__) +#include "pipe/tgsi/exec/tgsi_sse2.h" +#endif +#include "draw_private.h" +#include "draw_context.h" + +#include "x86/rtasm/x86sse.h" +#include "pipe/llvm/gallivm.h" + + +#define DBG_VS 0 + + +static INLINE unsigned +compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) +{ + unsigned mask = 0; + unsigned i; + + /* Do the hardwired planes first: + */ + if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; + if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; + if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; + if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; + if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; + if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; + + /* Followed by any remaining ones: + */ + for (i = 6; i < nr; i++) { + if (dot4(clip, plane[i]) < 0) + mask |= (1<machine; + unsigned int j; + + ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); + ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); + const float *scale = draw->viewport.scale; + const float *trans = draw->viewport.translate; + + assert(count <= 4); + assert(draw->vertex_shader->state->output_semantic_name[0] + == TGSI_SEMANTIC_POSITION); + + /* Consts does not require 16 byte alignment. */ + machine->Consts = (float (*)[4]) draw->user.constants; + + machine->Inputs = ALIGN16_ASSIGN(inputs); + machine->Outputs = ALIGN16_ASSIGN(outputs); + + draw->vertex_fetch.fetch_func( draw, machine, elts, count ); + + /* run shader */ +#ifdef MESA_LLVM + if (1) { + struct gallivm_prog *prog = draw->vertex_shader->llvm_prog; + gallivm_cpu_vs_exec(prog, + machine->Inputs, + machine->Outputs, + machine->Consts, + machine->Temps); + } else +#elif defined(__i386__) || defined(__386__) + if (draw->use_sse) { + /* SSE */ + /* cast away const */ + struct draw_vertex_shader *shader + = (struct draw_vertex_shader *)draw->vertex_shader; + codegen_function func + = (codegen_function) x86_get_func( &shader->sse2_program ); + + if (func) + func( + machine->Inputs, + machine->Outputs, + machine->Consts, + machine->Temps ); + else + /* interpreter */ + tgsi_exec_machine_run( machine ); + } + else +#endif + { + /* interpreter */ + tgsi_exec_machine_run( machine ); + } + + /* store machine results */ + for (j = 0; j < count; j++) { + unsigned slot; + float x, y, z, w; + + /* Handle attr[0] (position) specially: + * + * XXX: Computing the clipmask should be done in the vertex + * program as a set of DP4 instructions appended to the + * user-provided code. + */ + x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + + vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + vOut[j]->edgeflag = 1; + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; + + /* Viewport mapping */ + vOut[j]->data[0][0] = x * scale[0] + trans[0]; + vOut[j]->data[0][1] = y * scale[1] + trans[1]; + vOut[j]->data[0][2] = z * scale[2] + trans[2]; + vOut[j]->data[0][3] = w; + +#if DBG_VS + debug_printf("output[%d]win: %f %f %f %f\n", j, + vOut[j]->data[0][0], + vOut[j]->data[0][1], + vOut[j]->data[0][2], + vOut[j]->data[0][3]); +#endif + /* Remaining attributes are packed into sequential post-transform + * vertex attrib slots. + */ + for (slot = 1; slot < draw->num_vs_outputs; slot++) { + vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; +#if DBG_VS + debug_printf("output[%d][%d]: %f %f %f %f\n", j, slot, + vOut[j]->data[slot][0], + vOut[j]->data[slot][1], + vOut[j]->data[slot][2], + vOut[j]->data[slot][3]); +#endif + } + } /* loop over vertices */ +} + + +/** + * Run the vertex shader on all vertices in the vertex queue. + * Called by the draw module when the vertx cache needs to be flushed. + */ +void +draw_vertex_shader_queue_flush(struct draw_context *draw) +{ + unsigned i; + + assert(draw->vs.queue_nr != 0); + + /* XXX: do this on statechange: + */ + draw_update_vertex_fetch( draw ); + +// fprintf(stderr, " q(%d) ", draw->vs.queue_nr ); + + /* run vertex shader on vertex cache entries, four per invokation */ + for (i = 0; i < draw->vs.queue_nr; i += 4) { + struct vertex_header *dests[4]; + unsigned elts[4]; + int j, n = MIN2(4, draw->vs.queue_nr - i); + + for (j = 0; j < n; j++) { + elts[j] = draw->vs.queue[i + j].elt; + dests[j] = draw->vs.queue[i + j].dest; + } + + for ( ; j < 4; j++) { + elts[j] = elts[0]; + dests[j] = dests[0]; + } + + assert(n > 0); + assert(n <= 4); + + run_vertex_program(draw, elts, n, dests); + } + + draw->vs.queue_nr = 0; +} + + +struct draw_vertex_shader * +draw_create_vertex_shader(struct draw_context *draw, + const struct pipe_shader_state *shader) +{ + struct draw_vertex_shader *vs; + + vs = CALLOC_STRUCT( draw_vertex_shader ); + if (vs == NULL) { + return NULL; + } + + vs->state = shader; + +#ifdef MESA_LLVM + struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); + gallivm_ir_set_layout(ir, GALLIVM_SOA); + gallivm_ir_set_components(ir, 4); + gallivm_ir_fill_from_tgsi(ir, shader->tokens); + vs->llvm_prog = gallivm_ir_compile(ir); + gallivm_ir_delete(ir); + + draw->engine = gallivm_global_cpu_engine(); + if (!draw->engine) { + draw->engine = gallivm_cpu_engine_create(vs->llvm_prog); + } + else { + gallivm_cpu_jit_compile(draw->engine, vs->llvm_prog); + } +#elif defined(__i386__) || defined(__386__) + if (draw->use_sse) { + /* cast-away const */ + struct pipe_shader_state *sh = (struct pipe_shader_state *) shader; + + x86_init_func( &vs->sse2_program ); + if (!tgsi_emit_sse2( (struct tgsi_token *) sh->tokens, + &vs->sse2_program )) { + x86_release_func( (struct x86_function *) &vs->sse2_program ); + fprintf(stdout /*err*/, + "tgsi_emit_sse2() failed, falling back to interpreter\n"); + } + } +#endif + + return vs; +} + + +void +draw_bind_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + draw->vertex_shader = dvs; + draw->num_vs_outputs = dvs->state->num_outputs; + + /* specify the vertex program to interpret/execute */ + tgsi_exec_machine_init(&draw->machine, + draw->vertex_shader->state->tokens, + PIPE_MAX_SAMPLERS, + NULL /*samplers*/ ); +} + + +void +draw_delete_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs) +{ +#if defined(__i386__) || defined(__386__) + x86_release_func( (struct x86_function *) &dvs->sse2_program ); +#endif + + FREE( dvs ); +} diff --git a/src/gallium/aux/draw/draw_vf.c b/src/gallium/aux/draw/draw_vf.c new file mode 100644 index 0000000000..dc3a5ecd21 --- /dev/null +++ b/src/gallium/aux/draw/draw_vf.c @@ -0,0 +1,428 @@ +/* + * Copyright 2003 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + + +#include + +#include "pipe/p_compiler.h" +#include "pipe/p_util.h" + +#include "draw_vf.h" + + +#define DRAW_VF_DBG 0 + + +/* TODO: remove this */ +extern void +_mesa_exec_free( void *addr ); + + +static boolean match_fastpath( struct draw_vertex_fetch *vf, + const struct draw_vf_fastpath *fp) +{ + unsigned j; + + if (vf->attr_count != fp->attr_count) + return FALSE; + + for (j = 0; j < vf->attr_count; j++) + if (vf->attr[j].format != fp->attr[j].format || + vf->attr[j].inputsize != fp->attr[j].size || + vf->attr[j].vertoffset != fp->attr[j].offset) + return FALSE; + + if (fp->match_strides) { + if (vf->vertex_stride != fp->vertex_stride) + return FALSE; + + for (j = 0; j < vf->attr_count; j++) + if (vf->attr[j].inputstride != fp->attr[j].stride) + return FALSE; + } + + return TRUE; +} + +static boolean search_fastpath_emit( struct draw_vertex_fetch *vf ) +{ + struct draw_vf_fastpath *fp = vf->fastpath; + + for ( ; fp ; fp = fp->next) { + if (match_fastpath(vf, fp)) { + vf->emit = fp->func; + return TRUE; + } + } + + return FALSE; +} + +void draw_vf_register_fastpath( struct draw_vertex_fetch *vf, + boolean match_strides ) +{ + struct draw_vf_fastpath *fastpath = CALLOC_STRUCT(draw_vf_fastpath); + unsigned i; + + fastpath->vertex_stride = vf->vertex_stride; + fastpath->attr_count = vf->attr_count; + fastpath->match_strides = match_strides; + fastpath->func = vf->emit; + fastpath->attr = (struct draw_vf_attr_type *) + MALLOC(vf->attr_count * sizeof(fastpath->attr[0])); + + for (i = 0; i < vf->attr_count; i++) { + fastpath->attr[i].format = vf->attr[i].format; + fastpath->attr[i].stride = vf->attr[i].inputstride; + fastpath->attr[i].size = vf->attr[i].inputsize; + fastpath->attr[i].offset = vf->attr[i].vertoffset; + } + + fastpath->next = vf->fastpath; + vf->fastpath = fastpath; +} + + + + +/*********************************************************************** + * Build codegen functions or return generic ones: + */ +static void choose_emit_func( struct draw_vertex_fetch *vf, + unsigned count, + uint8_t *dest) +{ + vf->emit = NULL; + + /* Does this match an existing (hardwired, codegen or known-bad) + * fastpath? + */ + if (search_fastpath_emit(vf)) { + /* Use this result. If it is null, then it is already known + * that the current state will fail for codegen and there is no + * point trying again. + */ + } + else if (vf->codegen_emit) { + vf->codegen_emit( vf ); + } + + if (!vf->emit) { + draw_vf_generate_hardwired_emit(vf); + } + + /* Otherwise use the generic version: + */ + if (!vf->emit) + vf->emit = draw_vf_generic_emit; + + vf->emit( vf, count, dest ); +} + + + + + +/*********************************************************************** + * Public entrypoints, mostly dispatch to the above: + */ + + + +static unsigned +draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, + const struct draw_vf_attr_map *map, + unsigned nr, + unsigned vertex_stride ) +{ + unsigned offset = 0; + unsigned i, j; + + assert(nr < PIPE_ATTRIB_MAX); + + for (j = 0, i = 0; i < nr; i++) { + const unsigned format = map[i].format; + if (format == DRAW_EMIT_PAD) { +#if (DRAW_VF_DBG) + debug_printf("%d: pad %d, offset %d\n", i, + map[i].offset, offset); +#endif + + offset += map[i].offset; + + } + else { + vf->attr[j].attrib = map[i].attrib; + vf->attr[j].format = format; + vf->attr[j].insert = draw_vf_format_info[format].insert; + vf->attr[j].vertattrsize = draw_vf_format_info[format].attrsize; + vf->attr[j].vertoffset = offset; + vf->attr[j].isconst = draw_vf_format_info[format].isconst; + if(vf->attr[j].isconst) + memcpy(vf->attr[j].data, &map[i].data, vf->attr[j].vertattrsize); + +#if (DRAW_VF_DBG) + debug_printf("%d: %s, offset %d\n", i, + draw_vf_format_info[format].name, + vf->attr[j].vertoffset); +#endif + + offset += draw_vf_format_info[format].attrsize; + j++; + } + } + + vf->attr_count = j; + vf->vertex_stride = vertex_stride ? vertex_stride : offset; + vf->emit = choose_emit_func; + + assert(vf->vertex_stride >= offset); + return vf->vertex_stride; +} + + +void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, + const struct vertex_info *vinfo, + float point_size ) +{ + unsigned i, j, k; + struct draw_vf_attr *a = vf->attr; + struct draw_vf_attr_map attrs[PIPE_MAX_SHADER_INPUTS]; + unsigned count = 0; /* for debug/sanity */ + unsigned nr_attrs = 0; + + for (i = 0; i < vinfo->num_attribs; i++) { + j = vinfo->src_index[i]; + switch (vinfo->emit[i]) { + case EMIT_OMIT: + /* no-op */ + break; + case EMIT_ALL: { + /* just copy the whole vertex as-is to the vbuf */ + unsigned s = vinfo->size; + assert(i == 0); + assert(j == 0); + /* copy the vertex header */ + /* XXX: we actually don't copy the header, just pad it */ + attrs[nr_attrs].attrib = 0; + attrs[nr_attrs].format = DRAW_EMIT_PAD; + attrs[nr_attrs].offset = offsetof(struct vertex_header, data); + s -= offsetof(struct vertex_header, data)/4; + count += offsetof(struct vertex_header, data)/4; + nr_attrs++; + /* copy the vertex data */ + for(k = 0; k < (s & ~0x3); k += 4) { + attrs[nr_attrs].attrib = k/4; + attrs[nr_attrs].format = DRAW_EMIT_4F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 4; + } + /* tail */ + /* XXX: actually, this shouldn't be needed */ + attrs[nr_attrs].attrib = k/4; + attrs[nr_attrs].offset = 0; + switch(s & 0x3) { + case 0: + break; + case 1: + attrs[nr_attrs].format = DRAW_EMIT_1F; + nr_attrs++; + count += 1; + break; + case 2: + attrs[nr_attrs].format = DRAW_EMIT_2F; + nr_attrs++; + count += 2; + break; + case 3: + attrs[nr_attrs].format = DRAW_EMIT_3F; + nr_attrs++; + count += 3; + break; + } + break; + } + case EMIT_1F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_1F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count++; + break; + case EMIT_1F_PSIZE: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_1F_CONST; + attrs[nr_attrs].offset = 0; + attrs[nr_attrs].data.f[0] = point_size; + nr_attrs++; + count++; + break; + case EMIT_2F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_2F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 2; + break; + case EMIT_3F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_3F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 3; + break; + case EMIT_4F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_4F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 4; + break; + case EMIT_4UB: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_4UB_4F_BGRA; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 1; + break; + default: + assert(0); + } + } + + assert(count == vinfo->size); + + draw_vf_set_vertex_attributes(vf, + attrs, + nr_attrs, + vinfo->size * sizeof(float) ); + + for (j = 0; j < vf->attr_count; j++) { + a[j].inputsize = 4; + a[j].do_insert = a[j].insert[4 - 1]; + if(a[j].isconst) { + a[j].inputptr = a[j].data; + a[j].inputstride = 0; + } + } +} + + +#if 0 +/* Set attribute pointers, adjusted for start position: + */ +void draw_vf_set_sources( struct draw_vertex_fetch *vf, + GLvector4f * const sources[], + unsigned start ) +{ + struct draw_vf_attr *a = vf->attr; + unsigned j; + + for (j = 0; j < vf->attr_count; j++) { + const GLvector4f *vptr = sources[a[j].attrib]; + + if ((a[j].inputstride != vptr->stride) || + (a[j].inputsize != vptr->size)) + vf->emit = choose_emit_func; + + a[j].inputstride = vptr->stride; + a[j].inputsize = vptr->size; + a[j].do_insert = a[j].insert[vptr->size - 1]; + a[j].inputptr = ((uint8_t *)vptr->data) + start * vptr->stride; + } +} +#endif + + +/** + * Emit a vertex to dest. + */ +void draw_vf_emit_vertex( struct draw_vertex_fetch *vf, + struct vertex_header *vertex, + void *dest ) +{ + struct draw_vf_attr *a = vf->attr; + unsigned j; + + for (j = 0; j < vf->attr_count; j++) { + if (!a[j].isconst) { + a[j].inputptr = (uint8_t *)&vertex->data[a[j].attrib][0]; + a[j].inputstride = 0; /* XXX: one-vertex-max ATM */ + } + } + + vf->emit( vf, 1, (uint8_t*) dest ); +} + + + +struct draw_vertex_fetch *draw_vf_create( void ) +{ + struct draw_vertex_fetch *vf = CALLOC_STRUCT(draw_vertex_fetch); + unsigned i; + + for (i = 0; i < PIPE_ATTRIB_MAX; i++) + vf->attr[i].vf = vf; + + vf->identity[0] = 0.0; + vf->identity[1] = 0.0; + vf->identity[2] = 0.0; + vf->identity[3] = 1.0; + + vf->codegen_emit = NULL; + +#ifdef USE_SSE_ASM + if (!GETENV("GALLIUM_NO_CODEGEN")) + vf->codegen_emit = draw_vf_generate_sse_emit; +#endif + + return vf; +} + + +void draw_vf_destroy( struct draw_vertex_fetch *vf ) +{ + struct draw_vf_fastpath *fp, *tmp; + + for (fp = vf->fastpath ; fp ; fp = tmp) { + tmp = fp->next; + FREE(fp->attr); + + /* KW: At the moment, fp->func is constrained to be allocated by + * _mesa_exec_alloc(), as the hardwired fastpaths in + * t_vertex_generic.c are handled specially. It would be nice + * to unify them, but this probably won't change until this + * module gets another overhaul. + */ + //_mesa_exec_free((void *) fp->func); + FREE(fp); + } + + vf->fastpath = NULL; + FREE(vf); +} diff --git a/src/gallium/aux/draw/draw_vf.h b/src/gallium/aux/draw/draw_vf.h new file mode 100644 index 0000000000..011c8f0ff1 --- /dev/null +++ b/src/gallium/aux/draw/draw_vf.h @@ -0,0 +1,236 @@ +/* + * Copyright 2008 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * Vertex fetch/store/convert code. This functionality is used in two places: + * 1. Vertex fetch/convert - to grab vertex data from incoming vertex + * arrays and convert to format needed by vertex shaders. + * 2. Vertex store/emit - to convert simple float[][4] vertex attributes + * (which is the organization used throughout the draw/prim pipeline) to + * hardware-specific formats and emit into hardware vertex buffers. + * + * + * Authors: + * Keith Whitwell + */ + +#ifndef DRAW_VF_H +#define DRAW_VF_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "draw_vertex.h" +#include "draw_private.h" /* for vertex_header */ + + +enum draw_vf_attr_format { + DRAW_EMIT_1F, + DRAW_EMIT_2F, + DRAW_EMIT_3F, + DRAW_EMIT_4F, + DRAW_EMIT_3F_XYW, /**< for projective texture */ + DRAW_EMIT_1UB_1F, /**< for fog coordinate */ + DRAW_EMIT_3UB_3F_RGB, /**< for specular color */ + DRAW_EMIT_3UB_3F_BGR, /**< for specular color */ + DRAW_EMIT_4UB_4F_RGBA, /**< for color */ + DRAW_EMIT_4UB_4F_BGRA, /**< for color */ + DRAW_EMIT_4UB_4F_ARGB, /**< for color */ + DRAW_EMIT_4UB_4F_ABGR, /**< for color */ + DRAW_EMIT_1F_CONST, + DRAW_EMIT_2F_CONST, + DRAW_EMIT_3F_CONST, + DRAW_EMIT_4F_CONST, + DRAW_EMIT_PAD, /**< leave a hole of 'offset' bytes */ + DRAW_EMIT_MAX +}; + +struct draw_vf_attr_map +{ + /** Input attribute number */ + unsigned attrib; + + enum draw_vf_attr_format format; + + unsigned offset; + + /** + * Constant data for DRAW_EMIT_*_CONST + */ + union { + uint8_t ub[4]; + float f[4]; + } data; +}; + +struct draw_vertex_fetch; + + + +#if 0 +unsigned +draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, + const struct draw_vf_attr_map *map, + unsigned nr, + unsigned vertex_stride ); +#endif + +void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, + const struct vertex_info *vinfo, + float point_size ); + +#if 0 +void +draw_vf_set_sources( struct draw_vertex_fetch *vf, + GLvector4f * const attrib[], + unsigned start ); +#endif + +void +draw_vf_emit_vertex( struct draw_vertex_fetch *vf, + struct vertex_header *vertex, + void *dest ); + +struct draw_vertex_fetch * +draw_vf_create( void ); + +void +draw_vf_destroy( struct draw_vertex_fetch *vf ); + + + +/*********************************************************************** + * Internal functions and structs: + */ + +struct draw_vf_attr; + +typedef void (*draw_vf_extract_func)( const struct draw_vf_attr *a, + float *out, + const uint8_t *v ); + +typedef void (*draw_vf_insert_func)( const struct draw_vf_attr *a, + uint8_t *v, + const float *in ); + +typedef void (*draw_vf_emit_func)( struct draw_vertex_fetch *vf, + unsigned count, + uint8_t *dest ); + + + +/** + * Describes how to convert/move a vertex attribute from a vertex + * array to a vertex structure. + */ +struct draw_vf_attr +{ + struct draw_vertex_fetch *vf; + + unsigned format; + unsigned inputsize; + unsigned inputstride; + unsigned vertoffset; /**< position of the attrib in the vertex struct */ + + boolean isconst; /**< read from const data below */ + uint8_t data[16]; + + unsigned attrib; /**< which vertex attrib (0=position, etc) */ + unsigned vertattrsize; /**< size of the attribute in bytes */ + + uint8_t *inputptr; + const draw_vf_insert_func *insert; + draw_vf_insert_func do_insert; + draw_vf_extract_func extract; +}; + +struct draw_vertex_fetch +{ + struct draw_vf_attr attr[PIPE_ATTRIB_MAX]; + unsigned attr_count; + unsigned vertex_stride; + + draw_vf_emit_func emit; + + /* Parameters and constants for codegen: + */ + float identity[4]; + + struct draw_vf_fastpath *fastpath; + + void (*codegen_emit)( struct draw_vertex_fetch *vf ); +}; + + +struct draw_vf_attr_type { + unsigned format; + unsigned size; + unsigned stride; + unsigned offset; +}; + +/** XXX this could be moved into draw_vf.c */ +struct draw_vf_fastpath { + unsigned vertex_stride; + unsigned attr_count; + boolean match_strides; + + struct draw_vf_attr_type *attr; + + draw_vf_emit_func func; + struct draw_vf_fastpath *next; +}; + + +void +draw_vf_register_fastpath( struct draw_vertex_fetch *vtx, + boolean match_strides ); + +void +draw_vf_generic_emit( struct draw_vertex_fetch *vf, + unsigned count, + uint8_t *v ); + +void +draw_vf_generate_hardwired_emit( struct draw_vertex_fetch *vf ); + +void +draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ); + + +/** XXX this type and function could probably be moved into draw_vf.c */ +struct draw_vf_format_info { + const char *name; + draw_vf_insert_func insert[4]; + const unsigned attrsize; + const boolean isconst; +}; + +extern const struct draw_vf_format_info +draw_vf_format_info[DRAW_EMIT_MAX]; + + +#endif diff --git a/src/gallium/aux/draw/draw_vf_generic.c b/src/gallium/aux/draw/draw_vf_generic.c new file mode 100644 index 0000000000..7a60a9db9c --- /dev/null +++ b/src/gallium/aux/draw/draw_vf_generic.c @@ -0,0 +1,585 @@ + +/* + * Copyright 2003 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" + +#include "draw_vf.h" + + + +static INLINE void insert_4f_4( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +static INLINE void insert_4f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = 1; +} + +static INLINE void insert_4f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = 0; + out[3] = 1; +} + +static INLINE void insert_4f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = 0; + out[2] = 0; + out[3] = 1; +} + +static INLINE void insert_3f_xyw_4( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[3]; +} + +static INLINE void insert_3f_xyw_err( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + (void) a; (void) v; (void) in; + assert(0); +} + +static INLINE void insert_3f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; +} + +static INLINE void insert_3f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = 0; +} + +static INLINE void insert_3f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = 0; + out[2] = 0; +} + + +static INLINE void insert_2f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; +} + +static INLINE void insert_2f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = 0; +} + +static INLINE void insert_1f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; +} + +static INLINE void insert_null( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + (void) a; (void) v; (void) in; +} + +static INLINE void insert_4ub_4f_rgba_4( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); +} + +static INLINE void insert_4ub_4f_rgba_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_rgba_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + v[2] = 0; + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_rgba_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + v[1] = 0; + v[2] = 0; + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_bgra_4( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); +} + +static INLINE void insert_4ub_4f_bgra_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_bgra_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + v[0] = 0; + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_bgra_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + v[1] = 0; + v[0] = 0; + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_argb_4( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); +} + +static INLINE void insert_4ub_4f_argb_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); + v[0] = 0xff; +} + +static INLINE void insert_4ub_4f_argb_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + v[3] = 0x00; + v[0] = 0xff; +} + +static INLINE void insert_4ub_4f_argb_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); + v[2] = 0x00; + v[3] = 0x00; + v[0] = 0xff; +} + +static INLINE void insert_4ub_4f_abgr_4( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); +} + +static INLINE void insert_4ub_4f_abgr_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); + v[0] = 0xff; +} + +static INLINE void insert_4ub_4f_abgr_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + v[1] = 0x00; + v[0] = 0xff; +} + +static INLINE void insert_4ub_4f_abgr_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); + v[2] = 0x00; + v[1] = 0x00; + v[0] = 0xff; +} + +static INLINE void insert_3ub_3f_rgb_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); +} + +static INLINE void insert_3ub_3f_rgb_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + v[2] = 0; +} + +static INLINE void insert_3ub_3f_rgb_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + v[1] = 0; + v[2] = 0; +} + +static INLINE void insert_3ub_3f_bgr_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); +} + +static INLINE void insert_3ub_3f_bgr_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + v[0] = 0; +} + +static INLINE void insert_3ub_3f_bgr_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + v[1] = 0; + v[0] = 0; +} + + +static INLINE void insert_1ub_1f_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); +} + + +const struct draw_vf_format_info draw_vf_format_info[DRAW_EMIT_MAX] = +{ + { "1f", + { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, + sizeof(float), FALSE }, + + { "2f", + { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, + 2 * sizeof(float), FALSE }, + + { "3f", + { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, + 3 * sizeof(float), FALSE }, + + { "4f", + { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, + 4 * sizeof(float), FALSE }, + + { "3f_xyw", + { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err, + insert_3f_xyw_4 }, + 3 * sizeof(float), FALSE }, + + { "1ub_1f", + { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 }, + sizeof(uint8_t), FALSE }, + + { "3ub_3f_rgb", + { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3, + insert_3ub_3f_rgb_3 }, + 3 * sizeof(uint8_t), FALSE }, + + { "3ub_3f_bgr", + { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3, + insert_3ub_3f_bgr_3 }, + 3 * sizeof(uint8_t), FALSE }, + + { "4ub_4f_rgba", + { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3, + insert_4ub_4f_rgba_4 }, + 4 * sizeof(uint8_t), FALSE }, + + { "4ub_4f_bgra", + { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3, + insert_4ub_4f_bgra_4 }, + 4 * sizeof(uint8_t), FALSE }, + + { "4ub_4f_argb", + { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3, + insert_4ub_4f_argb_4 }, + 4 * sizeof(uint8_t), FALSE }, + + { "4ub_4f_abgr", + { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3, + insert_4ub_4f_abgr_4 }, + 4 * sizeof(uint8_t), FALSE }, + + { "1f_const", + { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, + sizeof(float), TRUE }, + + { "2f_const", + { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, + 2 * sizeof(float), TRUE }, + + { "3f_const", + { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, + 3 * sizeof(float), TRUE }, + + { "4f_const", + { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, + 4 * sizeof(float), TRUE }, + + { "pad", + { NULL, NULL, NULL, NULL }, + 0, FALSE }, + +}; + + + + +/*********************************************************************** + * Hardwired fastpaths for emitting whole vertices or groups of + * vertices + */ +#define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \ +static void NAME( struct draw_vertex_fetch *vf, \ + unsigned count, \ + uint8_t *v ) \ +{ \ + struct draw_vf_attr *a = vf->attr; \ + unsigned i; \ + \ + for (i = 0 ; i < count ; i++, v += vf->vertex_stride) { \ + if (NR > 0) { \ + F0( &a[0], v + a[0].vertoffset, (float *)a[0].inputptr ); \ + a[0].inputptr += a[0].inputstride; \ + } \ + \ + if (NR > 1) { \ + F1( &a[1], v + a[1].vertoffset, (float *)a[1].inputptr ); \ + a[1].inputptr += a[1].inputstride; \ + } \ + \ + if (NR > 2) { \ + F2( &a[2], v + a[2].vertoffset, (float *)a[2].inputptr ); \ + a[2].inputptr += a[2].inputstride; \ + } \ + \ + if (NR > 3) { \ + F3( &a[3], v + a[3].vertoffset, (float *)a[3].inputptr ); \ + a[3].inputptr += a[3].inputstride; \ + } \ + \ + if (NR > 4) { \ + F4( &a[4], v + a[4].vertoffset, (float *)a[4].inputptr ); \ + a[4].inputptr += a[4].inputstride; \ + } \ + } \ +} + + +#define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \ + insert_null, insert_null, NAME) + +#define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \ + insert_null, NAME) + +#define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \ + insert_null, NAME) + + +EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4) + +EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2) + +EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2) + + +/* Use the codegen paths to select one of a number of hardwired + * fastpaths. + */ +void draw_vf_generate_hardwired_emit( struct draw_vertex_fetch *vf ) +{ + draw_vf_emit_func func = NULL; + + /* Does it fit a hardwired fastpath? Help! this is growing out of + * control! + */ + switch (vf->attr_count) { + case 2: + if (vf->attr[0].do_insert == insert_3f_3 && + vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { + func = emit_xyz3_rgba4; + } + break; + case 3: + if (vf->attr[2].do_insert == insert_2f_2) { + if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { + if (vf->attr[0].do_insert == insert_4f_4) + func = emit_xyzw4_rgba4_st2; + } + } + break; + case 4: + if (vf->attr[2].do_insert == insert_2f_2 && + vf->attr[3].do_insert == insert_2f_2) { + if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { + if (vf->attr[0].do_insert == insert_4f_4) + func = emit_xyzw4_rgba4_st2_st2; + } + } + break; + } + + vf->emit = func; +} + +/*********************************************************************** + * Generic (non-codegen) functions for whole vertices or groups of + * vertices + */ + +void draw_vf_generic_emit( struct draw_vertex_fetch *vf, + unsigned count, + uint8_t *v ) +{ + struct draw_vf_attr *a = vf->attr; + const unsigned attr_count = vf->attr_count; + const unsigned stride = vf->vertex_stride; + unsigned i, j; + + for (i = 0 ; i < count ; i++, v += stride) { + for (j = 0; j < attr_count; j++) { + float *in = (float *)a[j].inputptr; + a[j].inputptr += a[j].inputstride; + a[j].do_insert( &a[j], v + a[j].vertoffset, in ); + } + } +} + + diff --git a/src/gallium/aux/draw/draw_vf_sse.c b/src/gallium/aux/draw/draw_vf_sse.c new file mode 100644 index 0000000000..1ad2ae756d --- /dev/null +++ b/src/gallium/aux/draw/draw_vf_sse.c @@ -0,0 +1,614 @@ +/* + * Copyright 2003 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + + +#include "simple_list.h" + +#include "pipe/p_compiler.h" + +#include "draw_vf.h" + + +#if defined(USE_SSE_ASM) + +#include "x86/rtasm/x86sse.h" +#include "x86/common_x86_asm.h" + + +#define X 0 +#define Y 1 +#define Z 2 +#define W 3 + + +struct x86_program { + struct x86_function func; + + struct draw_vertex_fetch *vf; + boolean inputs_safe; + boolean outputs_safe; + boolean have_sse2; + + struct x86_reg identity; + struct x86_reg chan0; +}; + + +static struct x86_reg get_identity( struct x86_program *p ) +{ + return p->identity; +} + +static void emit_load4f_4( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movups(&p->func, dest, arg0); +} + +static void emit_load4f_3( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + /* Have to jump through some hoops: + * + * c 0 0 0 + * c 0 0 1 + * 0 0 c 1 + * a b c 1 + */ + sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); + sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); + sse_shufps(&p->func, dest, dest, SHUF(Y,Z,X,W) ); + sse_movlps(&p->func, dest, arg0); +} + +static void emit_load4f_2( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + /* Initialize from identity, then pull in low two words: + */ + sse_movups(&p->func, dest, get_identity(p)); + sse_movlps(&p->func, dest, arg0); +} + +static void emit_load4f_1( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + /* Pull in low word, then swizzle in identity */ + sse_movss(&p->func, dest, arg0); + sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); +} + + + +static void emit_load3f_3( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + /* Over-reads by 1 dword - potential SEGV if input is a vertex + * array. + */ + if (p->inputs_safe) { + sse_movups(&p->func, dest, arg0); + } + else { + /* c 0 0 0 + * c c c c + * a b c c + */ + sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); + sse_shufps(&p->func, dest, dest, SHUF(X,X,X,X)); + sse_movlps(&p->func, dest, arg0); + } +} + +static void emit_load3f_2( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + emit_load4f_2(p, dest, arg0); +} + +static void emit_load3f_1( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + emit_load4f_1(p, dest, arg0); +} + +static void emit_load2f_2( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movlps(&p->func, dest, arg0); +} + +static void emit_load2f_1( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + emit_load4f_1(p, dest, arg0); +} + +static void emit_load1f_1( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movss(&p->func, dest, arg0); +} + +static void (*load[4][4])( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) = { + { emit_load1f_1, + emit_load1f_1, + emit_load1f_1, + emit_load1f_1 }, + + { emit_load2f_1, + emit_load2f_2, + emit_load2f_2, + emit_load2f_2 }, + + { emit_load3f_1, + emit_load3f_2, + emit_load3f_3, + emit_load3f_3 }, + + { emit_load4f_1, + emit_load4f_2, + emit_load4f_3, + emit_load4f_4 } +}; + +static void emit_load( struct x86_program *p, + struct x86_reg dest, + unsigned sz, + struct x86_reg src, + unsigned src_sz) +{ + load[sz-1][src_sz-1](p, dest, src); +} + +static void emit_store4f( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movups(&p->func, dest, arg0); +} + +static void emit_store3f( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + if (p->outputs_safe) { + /* Emit the extra dword anyway. This may hurt writecombining, + * may cause other problems. + */ + sse_movups(&p->func, dest, arg0); + } + else { + /* Alternate strategy - emit two, shuffle, emit one. + */ + sse_movlps(&p->func, dest, arg0); + sse_shufps(&p->func, arg0, arg0, SHUF(Z,Z,Z,Z) ); /* NOTE! destructive */ + sse_movss(&p->func, x86_make_disp(dest,8), arg0); + } +} + +static void emit_store2f( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movlps(&p->func, dest, arg0); +} + +static void emit_store1f( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movss(&p->func, dest, arg0); +} + + +static void (*store[4])( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) = +{ + emit_store1f, + emit_store2f, + emit_store3f, + emit_store4f +}; + +static void emit_store( struct x86_program *p, + struct x86_reg dest, + unsigned sz, + struct x86_reg temp ) + +{ + store[sz-1](p, dest, temp); +} + +static void emit_pack_store_4ub( struct x86_program *p, + struct x86_reg dest, + struct x86_reg temp ) +{ + /* Scale by 255.0 + */ + sse_mulps(&p->func, temp, p->chan0); + + if (p->have_sse2) { + sse2_cvtps2dq(&p->func, temp, temp); + sse2_packssdw(&p->func, temp, temp); + sse2_packuswb(&p->func, temp, temp); + sse_movss(&p->func, dest, temp); + } + else { + struct x86_reg mmx0 = x86_make_reg(file_MMX, 0); + struct x86_reg mmx1 = x86_make_reg(file_MMX, 1); + sse_cvtps2pi(&p->func, mmx0, temp); + sse_movhlps(&p->func, temp, temp); + sse_cvtps2pi(&p->func, mmx1, temp); + mmx_packssdw(&p->func, mmx0, mmx1); + mmx_packuswb(&p->func, mmx0, mmx0); + mmx_movd(&p->func, dest, mmx0); + } +} + +static int get_offset( const void *a, const void *b ) +{ + return (const char *)b - (const char *)a; +} + +/* Not much happens here. Eventually use this function to try and + * avoid saving/reloading the source pointers each vertex (if some of + * them can fit in registers). + */ +static void get_src_ptr( struct x86_program *p, + struct x86_reg srcREG, + struct x86_reg vfREG, + struct draw_vf_attr *a ) +{ + struct draw_vertex_fetch *vf = p->vf; + struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr)); + + /* Load current a[j].inputptr + */ + x86_mov(&p->func, srcREG, ptr_to_src); +} + +static void update_src_ptr( struct x86_program *p, + struct x86_reg srcREG, + struct x86_reg vfREG, + struct draw_vf_attr *a ) +{ + if (a->inputstride) { + struct draw_vertex_fetch *vf = p->vf; + struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr)); + + /* add a[j].inputstride (hardcoded value - could just as easily + * pull the stride value from memory each time). + */ + x86_lea(&p->func, srcREG, x86_make_disp(srcREG, a->inputstride)); + + /* save new value of a[j].inputptr + */ + x86_mov(&p->func, ptr_to_src, srcREG); + } +} + + +/* Lots of hardcoding + * + * EAX -- pointer to current output vertex + * ECX -- pointer to current attribute + * + */ +static boolean build_vertex_emit( struct x86_program *p ) +{ + struct draw_vertex_fetch *vf = p->vf; + unsigned j = 0; + + struct x86_reg vertexEAX = x86_make_reg(file_REG32, reg_AX); + struct x86_reg srcECX = x86_make_reg(file_REG32, reg_CX); + struct x86_reg countEBP = x86_make_reg(file_REG32, reg_BP); + struct x86_reg vfESI = x86_make_reg(file_REG32, reg_SI); + struct x86_reg temp = x86_make_reg(file_XMM, 0); + uint8_t *fixup, *label; + + /* Push a few regs? + */ + x86_push(&p->func, countEBP); + x86_push(&p->func, vfESI); + + + /* Get vertex count, compare to zero + */ + x86_xor(&p->func, srcECX, srcECX); + x86_mov(&p->func, countEBP, x86_fn_arg(&p->func, 2)); + x86_cmp(&p->func, countEBP, srcECX); + fixup = x86_jcc_forward(&p->func, cc_E); + + /* Initialize destination register. + */ + x86_mov(&p->func, vertexEAX, x86_fn_arg(&p->func, 3)); + + /* Move argument 1 (vf) into a reg: + */ + x86_mov(&p->func, vfESI, x86_fn_arg(&p->func, 1)); + + + /* always load, needed or not: + */ + sse_movups(&p->func, p->identity, x86_make_disp(vfESI, get_offset(vf, &vf->identity[0]))); + + /* Note address for loop jump */ + label = x86_get_label(&p->func); + + /* Emit code for each of the attributes. Currently routes + * everything through SSE registers, even when it might be more + * efficient to stick with regular old x86. No optimization or + * other tricks - enough new ground to cover here just getting + * things working. + */ + while (j < vf->attr_count) { + struct draw_vf_attr *a = &vf->attr[j]; + struct x86_reg dest = x86_make_disp(vertexEAX, a->vertoffset); + + /* Now, load an XMM reg from src, perhaps transform, then save. + * Could be shortcircuited in specific cases: + */ + switch (a->format) { + case DRAW_EMIT_1F: + case DRAW_EMIT_1F_CONST: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); + emit_store(p, dest, 1, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_2F: + case DRAW_EMIT_2F_CONST: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); + emit_store(p, dest, 2, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_3F: + case DRAW_EMIT_3F_CONST: + /* Potentially the worst case - hardcode 2+1 copying: + */ + if (0) { + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); + emit_store(p, dest, 3, temp); + update_src_ptr(p, srcECX, vfESI, a); + } + else { + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); + emit_store(p, dest, 2, temp); + if (a->inputsize > 2) { + emit_load(p, temp, 1, x86_make_disp(srcECX, 8), 1); + emit_store(p, x86_make_disp(dest,8), 1, temp); + } + else { + sse_movss(&p->func, x86_make_disp(dest,8), get_identity(p)); + } + update_src_ptr(p, srcECX, vfESI, a); + } + break; + case DRAW_EMIT_4F: + case DRAW_EMIT_4F_CONST: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + emit_store(p, dest, 4, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_3F_XYW: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + sse_shufps(&p->func, temp, temp, SHUF(X,Y,W,Z)); + emit_store(p, dest, 3, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + + case DRAW_EMIT_1UB_1F: + /* Test for PAD3 + 1UB: + */ + if (j > 0 && + a[-1].vertoffset + a[-1].vertattrsize <= a->vertoffset - 3) + { + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); + sse_shufps(&p->func, temp, temp, SHUF(X,X,X,X)); + emit_pack_store_4ub(p, x86_make_disp(dest, -3), temp); /* overkill! */ + update_src_ptr(p, srcECX, vfESI, a); + } + else { + debug_printf("Can't emit 1ub %x %x %d\n", + a->vertoffset, a[-1].vertoffset, a[-1].vertattrsize ); + return FALSE; + } + break; + case DRAW_EMIT_3UB_3F_RGB: + case DRAW_EMIT_3UB_3F_BGR: + /* Test for 3UB + PAD1: + */ + if (j == vf->attr_count - 1 || + a[1].vertoffset >= a->vertoffset + 4) { + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); + if (a->format == DRAW_EMIT_3UB_3F_BGR) + sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); + emit_pack_store_4ub(p, dest, temp); + update_src_ptr(p, srcECX, vfESI, a); + } + /* Test for 3UB + 1UB: + */ + else if (j < vf->attr_count - 1 && + a[1].format == DRAW_EMIT_1UB_1F && + a[1].vertoffset == a->vertoffset + 3) { + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); + update_src_ptr(p, srcECX, vfESI, a); + + /* Make room for incoming value: + */ + sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); + + get_src_ptr(p, srcECX, vfESI, &a[1]); + emit_load(p, temp, 1, x86_deref(srcECX), a[1].inputsize); + update_src_ptr(p, srcECX, vfESI, &a[1]); + + /* Rearrange and possibly do BGR conversion: + */ + if (a->format == DRAW_EMIT_3UB_3F_BGR) + sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); + else + sse_shufps(&p->func, temp, temp, SHUF(Y,Z,W,X)); + + emit_pack_store_4ub(p, dest, temp); + j++; /* NOTE: two attrs consumed */ + } + else { + debug_printf("Can't emit 3ub\n"); + } + return FALSE; /* add this later */ + break; + + case DRAW_EMIT_4UB_4F_RGBA: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + emit_pack_store_4ub(p, dest, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_4UB_4F_BGRA: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); + emit_pack_store_4ub(p, dest, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_4UB_4F_ARGB: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); + emit_pack_store_4ub(p, dest, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_4UB_4F_ABGR: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); + emit_pack_store_4ub(p, dest, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + default: + debug_printf("unknown a[%d].format %d\n", j, a->format); + return FALSE; /* catch any new opcodes */ + } + + /* Increment j by at least 1 - may have been incremented above also: + */ + j++; + } + + /* Next vertex: + */ + x86_lea(&p->func, vertexEAX, x86_make_disp(vertexEAX, vf->vertex_stride)); + + /* decr count, loop if not zero + */ + x86_dec(&p->func, countEBP); + x86_test(&p->func, countEBP, countEBP); + x86_jcc(&p->func, cc_NZ, label); + + /* Exit mmx state? + */ + if (p->func.need_emms) + mmx_emms(&p->func); + + /* Land forward jump here: + */ + x86_fixup_fwd_jump(&p->func, fixup); + + /* Pop regs and return + */ + x86_pop(&p->func, x86_get_base_reg(vfESI)); + x86_pop(&p->func, countEBP); + x86_ret(&p->func); + + vf->emit = (draw_vf_emit_func)x86_get_func(&p->func); + return TRUE; +} + + + +void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) +{ + struct x86_program p; + + if (!cpu_has_xmm) { + vf->codegen_emit = NULL; + return; + } + + memset(&p, 0, sizeof(p)); + + p.vf = vf; + p.inputs_safe = 0; /* for now */ + p.outputs_safe = 1; /* for now */ + p.have_sse2 = cpu_has_xmm2; + p.identity = x86_make_reg(file_XMM, 6); + p.chan0 = x86_make_reg(file_XMM, 7); + + x86_init_func(&p.func); + + if (build_vertex_emit(&p)) { + draw_vf_register_fastpath( vf, TRUE ); + } + else { + /* Note the failure so that we don't keep trying to codegen an + * impossible state: + */ + draw_vf_register_fastpath( vf, FALSE ); + x86_release_func(&p.func); + } +} + +#else + +void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) +{ + /* Dummy version for when USE_SSE_ASM not defined */ +} + +#endif diff --git a/src/gallium/aux/draw/draw_wide_prims.c b/src/gallium/aux/draw/draw_wide_prims.c new file mode 100644 index 0000000000..655774b155 --- /dev/null +++ b/src/gallium/aux/draw/draw_wide_prims.c @@ -0,0 +1,432 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +struct wide_stage { + struct draw_stage stage; + + float half_line_width; + float half_point_size; + + uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; + uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; + uint num_texcoords; + + int psize_slot; +}; + + + +static INLINE struct wide_stage *wide_stage( struct draw_stage *stage ) +{ + return (struct wide_stage *)stage; +} + + +static void passthrough_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + +static void passthrough_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line(stage->next, header); +} + +static void passthrough_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw a wide line by drawing a quad (two triangles). + * XXX need to disable polygon stipple. + */ +static void wide_line( struct draw_stage *stage, + struct prim_header *header ) +{ + const struct wide_stage *wide = wide_stage(stage); + const float half_width = wide->half_line_width; + + struct prim_header tri; + + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + const float dx = FABSF(pos0[0] - pos2[0]); + const float dy = FABSF(pos0[1] - pos2[1]); + + /* + * Draw wide line as a quad (two tris) by "stretching" the line along + * X or Y. + * We need to tweak coords in several ways to be conformant here. + */ + + if (dx > dy) { + /* x-major line */ + pos0[1] = pos0[1] - half_width - 0.25f; + pos1[1] = pos1[1] + half_width - 0.25f; + pos2[1] = pos2[1] - half_width - 0.25f; + pos3[1] = pos3[1] + half_width - 0.25f; + if (pos0[0] < pos2[0]) { + /* left to right line */ + pos0[0] -= 0.5f; + pos1[0] -= 0.5f; + pos2[0] -= 0.5f; + pos3[0] -= 0.5f; + } + else { + /* right to left line */ + pos0[0] += 0.5f; + pos1[0] += 0.5f; + pos2[0] += 0.5f; + pos3[0] += 0.5f; + } + } + else { + /* y-major line */ + pos0[0] = pos0[0] - half_width + 0.25f; + pos1[0] = pos1[0] + half_width + 0.25f; + pos2[0] = pos2[0] - half_width + 0.25f; + pos3[0] = pos3[0] + half_width + 0.25f; + if (pos0[1] < pos2[1]) { + /* top to bottom line */ + pos0[1] -= 0.5f; + pos1[1] -= 0.5f; + pos2[1] -= 0.5f; + pos3[1] -= 0.5f; + } + else { + /* bottom to top line */ + pos0[1] += 0.5f; + pos1[1] += 0.5f; + pos2[1] += 0.5f; + pos3[1] += 0.5f; + } + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +/** + * Draw a wide line by drawing a quad, using geometry which will + * fullfill GL's antialiased line requirements. + */ +static void wide_line_aa(struct draw_stage *stage, + struct prim_header *header) +{ + const struct wide_stage *wide = wide_stage(stage); + const float half_width = wide->half_line_width; + struct prim_header tri; + struct vertex_header *v[4]; + float *pos; + float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; + float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; + const float len = (float) sqrt(dx * dx + dy * dy); + uint i; + + dx = dx * half_width / len; + dy = dy * half_width / len; + + /* allocate/dup new verts */ + for (i = 0; i < 4; i++) { + v[i] = dup_vert(stage, header->v[i/2], i); + } + + /* + * Quad for line from v0 to v1: + * + * 1 3 + * +-------------------------+ + * | | + * *v0 v1* + * | | + * +-------------------------+ + * 0 2 + */ + + pos = v[0]->data[0]; + pos[0] += dy; + pos[1] -= dx; + + pos = v[1]->data[0]; + pos[0] -= dy; + pos[1] += dx; + + pos = v[2]->data[0]; + pos[0] += dy; + pos[1] -= dx; + + pos = v[3]->data[0]; + pos[0] -= dy; + pos[1] += dx; + + tri.det = header->det; /* only the sign matters */ + + tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + +} + + +/** + * Set the vertex texcoords for sprite mode. + * Coords may be left untouched or set to a right-side-up or upside-down + * orientation. + */ +static void set_texcoords(const struct wide_stage *wide, + struct vertex_header *v, const float tc[4]) +{ + uint i; + for (i = 0; i < wide->num_texcoords; i++) { + if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { + uint j = wide->texcoord_slot[i]; + v->data[j][0] = tc[0]; + if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) + v->data[j][1] = 1.0f - tc[1]; + else + v->data[j][1] = tc[1]; + v->data[j][2] = tc[2]; + v->data[j][3] = tc[3]; + } + } +} + + +/* If there are lots of sprite points (and why wouldn't there be?) it + * would probably be more sensible to change hardware setup to + * optimize this rather than doing the whole thing in software like + * this. + */ +static void wide_point( struct draw_stage *stage, + struct prim_header *header ) +{ + const struct wide_stage *wide = wide_stage(stage); + const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; + float half_size; + float left_adj, right_adj; + + struct prim_header tri; + + /* four dups of original vertex */ + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + /* point size is either per-vertex or fixed size */ + if (wide->psize_slot >= 0) { + half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; + } + else { + half_size = wide->half_point_size; + } + + left_adj = -half_size + 0.25f; + right_adj = half_size + 0.25f; + + pos0[0] += left_adj; + pos0[1] -= half_size; + + pos1[0] += left_adj; + pos1[1] += half_size; + + pos2[0] += right_adj; + pos2[1] -= half_size; + + pos3[0] += right_adj; + pos3[1] += half_size; + + if (sprite) { + static const float tex00[4] = { 0, 0, 0, 1 }; + static const float tex01[4] = { 0, 1, 0, 1 }; + static const float tex11[4] = { 1, 1, 0, 1 }; + static const float tex10[4] = { 1, 0, 0, 1 }; + set_texcoords( wide, v0, tex00 ); + set_texcoords( wide, v1, tex01 ); + set_texcoords( wide, v2, tex10 ); + set_texcoords( wide, v3, tex11 ); + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +static void wide_first_point( struct draw_stage *stage, + struct prim_header *header ) +{ + struct wide_stage *wide = wide_stage(stage); + struct draw_context *draw = stage->draw; + + wide->half_point_size = 0.5f * draw->rasterizer->point_size; + + if (draw->rasterizer->point_size != 1.0) { + stage->point = wide_point; + } + else { + stage->point = passthrough_point; + } + + if (draw->rasterizer->point_sprite) { + /* find vertex shader texcoord outputs */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i, j = 0; + for (i = 0; i < vs->state->num_outputs; i++) { + if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { + wide->texcoord_slot[j] = i; + wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; + j++; + } + } + wide->num_texcoords = j; + } + + wide->psize_slot = -1; + + if (draw->rasterizer->point_size_per_vertex) { + /* find PSIZ vertex output */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i; + for (i = 0; i < vs->state->num_outputs; i++) { + if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + wide->psize_slot = i; + break; + } + } + } + + stage->point( stage, header ); +} + + + +static void wide_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + struct wide_stage *wide = wide_stage(stage); + struct draw_context *draw = stage->draw; + + wide->half_line_width = 0.5f * draw->rasterizer->line_width; + + if (draw->rasterizer->line_width != 1.0) { + if (draw->rasterizer->line_smooth) + wide->stage.line = wide_line_aa; + else + wide->stage.line = wide_line; + } + else { + wide->stage.line = passthrough_line; + } + + stage->line( stage, header ); +} + + +static void wide_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->line = wide_first_line; + stage->point = wide_first_point; + stage->next->flush( stage->next, flags ); +} + + +static void wide_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void wide_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +struct draw_stage *draw_wide_stage( struct draw_context *draw ) +{ + struct wide_stage *wide = CALLOC_STRUCT(wide_stage); + + draw_alloc_temp_verts( &wide->stage, 4 ); + + wide->stage.draw = draw; + wide->stage.next = NULL; + wide->stage.point = wide_first_point; + wide->stage.line = wide_first_line; + wide->stage.tri = passthrough_tri; + wide->stage.flush = wide_flush; + wide->stage.reset_stipple_counter = wide_reset_stipple_counter; + wide->stage.destroy = wide_destroy; + + return &wide->stage; +} diff --git a/src/gallium/aux/llvm/Makefile b/src/gallium/aux/llvm/Makefile new file mode 100644 index 0000000000..9c6e16d86b --- /dev/null +++ b/src/gallium/aux/llvm/Makefile @@ -0,0 +1,83 @@ +# -*-makefile-*- +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = gallivm + + +GALLIVM_SOURCES = \ + gallivm.cpp \ + gallivm_cpu.cpp \ + instructions.cpp \ + loweringpass.cpp \ + tgsitollvm.cpp \ + storage.cpp \ + storagesoa.cpp \ + instructionssoa.cpp + +INC_SOURCES = gallivm_builtins.cpp + +CPP_SOURCES = \ + $(GALLIVM_SOURCES) + +C_SOURCES = +ASM_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(CPP_SOURCES:.cpp=.o) \ + $(ASM_SOURCES:.S=.o) + +### Include directories +INCLUDES = \ + -I. \ + -I$(TOP)/src/mesa/pipe \ + -I$(TOP)/src/mesa \ + -I$(TOP)/include + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(LLVM_CFLAGS) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(LLVM_CXXFLAGS) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +##### TARGETS ##### + +default:: depend symlinks $(LIBNAME) + + +$(LIBNAME): $(OBJECTS) Makefile + $(TOP)/bin/mklib -o $@ -static $(OBJECTS) + + +depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ + $(ASM_SOURCES) $(INC_SOURCES) 2> /dev/null + + +gallivm_builtins.cpp: llvm_builtins.c + clang --emit-llvm $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.so *~ server/*.o + -rm -f depend depend.bak + -rm -f gallivm_builtins.cpp + +symlinks: + + +include depend diff --git a/src/gallium/aux/llvm/gallivm.cpp b/src/gallium/aux/llvm/gallivm.cpp new file mode 100644 index 0000000000..da0105c2c9 --- /dev/null +++ b/src/gallium/aux/llvm/gallivm.cpp @@ -0,0 +1,327 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "instructions.h" +#include "loweringpass.h" +#include "storage.h" +#include "tgsitollvm.h" + +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" + +#include "pipe/tgsi/exec/tgsi_exec.h" +#include "pipe/tgsi/util/tgsi_dump.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int GLOBAL_ID = 0; + +using namespace llvm; + +static inline +void AddStandardCompilePasses(PassManager &PM) +{ + PM.add(new LoweringPass()); + PM.add(createVerifierPass()); // Verify that input is correct + + PM.add(createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp + + //PM.add(createStripSymbolsPass(true)); + + PM.add(createRaiseAllocationsPass()); // call %malloc -> malloc inst + PM.add(createCFGSimplificationPass()); // Clean up disgusting code + PM.add(createPromoteMemoryToRegisterPass());// Kill useless allocas + PM.add(createGlobalOptimizerPass()); // Optimize out global vars + PM.add(createGlobalDCEPass()); // Remove unused fns and globs + PM.add(createIPConstantPropagationPass());// IP Constant Propagation + PM.add(createDeadArgEliminationPass()); // Dead argument elimination + PM.add(createInstructionCombiningPass()); // Clean up after IPCP & DAE + PM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE + + PM.add(createPruneEHPass()); // Remove dead EH info + + PM.add(createFunctionInliningPass()); // Inline small functions + PM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args + + PM.add(createTailDuplicationPass()); // Simplify cfg by copying code + PM.add(createInstructionCombiningPass()); // Cleanup for scalarrepl. + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createScalarReplAggregatesPass()); // Break up aggregate allocas + PM.add(createInstructionCombiningPass()); // Combine silly seq's + PM.add(createCondPropagationPass()); // Propagate conditionals + + PM.add(createTailCallEliminationPass()); // Eliminate tail calls + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createReassociatePass()); // Reassociate expressions + PM.add(createLoopRotatePass()); + PM.add(createLICMPass()); // Hoist loop invariants + PM.add(createLoopUnswitchPass()); // Unswitch loops. + PM.add(createLoopIndexSplitPass()); // Index split loops. + PM.add(createInstructionCombiningPass()); // Clean up after LICM/reassoc + PM.add(createIndVarSimplifyPass()); // Canonicalize indvars + PM.add(createLoopUnrollPass()); // Unroll small loops + PM.add(createInstructionCombiningPass()); // Clean up after the unroller + PM.add(createGVNPass()); // Remove redundancies + PM.add(createSCCPPass()); // Constant prop with SCCP + + // Run instcombine after redundancy elimination to exploit opportunities + // opened up by them. + PM.add(createInstructionCombiningPass()); + PM.add(createCondPropagationPass()); // Propagate conditionals + + PM.add(createDeadStoreEliminationPass()); // Delete dead stores + PM.add(createAggressiveDCEPass()); // SSA based 'Aggressive DCE' + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createSimplifyLibCallsPass()); // Library Call Optimizations + PM.add(createDeadTypeEliminationPass()); // Eliminate dead types + PM.add(createConstantMergePass()); // Merge dup global constants +} + +void gallivm_prog_delete(struct gallivm_prog *prog) +{ + delete prog->module; + prog->module = 0; + prog->function = 0; + free(prog); +} + +static inline void +constant_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan) +{ + unsigned i; + + for (i = 0; i < QUAD_SIZE; ++i) { + inputs[i][attrib][chan] = coefs[attrib].a0[chan]; + } +} + +static inline void +linear_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + const float x = inputs[i][0][0]; + const float y = inputs[i][0][1]; + + inputs[i][attrib][chan] = + coefs[attrib].a0[chan] + + coefs[attrib].dadx[chan] * x + + coefs[attrib].dady[chan] * y; + } +} + +static inline void +perspective_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan ) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + const float x = inputs[i][0][0]; + const float y = inputs[i][0][1]; + /* WPOS.w here is really 1/w */ + const float w = 1.0f / inputs[i][0][3]; + assert(inputs[i][0][3] != 0.0); + + inputs[i][attrib][chan] = + (coefs[attrib].a0[chan] + + coefs[attrib].dadx[chan] * x + + coefs[attrib].dady[chan] * y) * w; + } +} + +void gallivm_ir_dump(struct gallivm_ir *ir, const char *file_prefix) +{ + if (!ir || !ir->module) + return; + + if (file_prefix) { + std::ostringstream stream; + stream << file_prefix; + stream << ir->id; + stream << ".ll"; + std::string name = stream.str(); + std::ofstream out(name.c_str()); + if (!out) { + std::cerr<<"Can't open file : "<module); + out.close(); + } else { + const llvm::Module::FunctionListType &funcs = ir->module->getFunctionList(); + llvm::Module::FunctionListType::const_iterator itr; + std::cout<<"; ---------- Start shader "<id<id<num_interp; ++i) { + const gallivm_interpolate &interp = prog->interpolators[i]; + switch (interp.type) { + case TGSI_INTERPOLATE_CONSTANT: + constant_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + case TGSI_INTERPOLATE_LINEAR: + linear_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + perspective_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + default: + assert( 0 ); + } + } +} + + +struct gallivm_ir * gallivm_ir_new(enum gallivm_shader_type type) +{ + struct gallivm_ir *ir = + (struct gallivm_ir *)calloc(1, sizeof(struct gallivm_ir)); + ++GLOBAL_ID; + ir->id = GLOBAL_ID; + ir->type = type; + + return ir; +} + +void gallivm_ir_set_layout(struct gallivm_ir *ir, + enum gallivm_vector_layout layout) +{ + ir->layout = layout; +} + +void gallivm_ir_set_components(struct gallivm_ir *ir, int num) +{ + ir->num_components = num; +} + +void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, + const struct tgsi_token *tokens) +{ + std::cout << "Creating llvm from: " <module = mod; + gallivm_ir_dump(ir, 0); +} + +void gallivm_ir_delete(struct gallivm_ir *ir) +{ + delete ir->module; + free(ir); +} + +struct gallivm_prog * gallivm_ir_compile(struct gallivm_ir *ir) +{ + struct gallivm_prog *prog = + (struct gallivm_prog *)calloc(1, sizeof(struct gallivm_prog)); + llvm::Module *mod = llvm::CloneModule(ir->module); + prog->num_consts = ir->num_consts; + memcpy(prog->interpolators, ir->interpolators, sizeof(prog->interpolators)); + prog->num_interp = ir->num_interp; + + /* Run optimization passes over it */ + PassManager passes; + passes.add(new TargetData(mod)); + AddStandardCompilePasses(passes); + passes.run(*mod); + prog->module = mod; + + std::cout << "After optimizations:"<dump(); + + return prog; +} + +#endif /* MESA_LLVM */ diff --git a/src/gallium/aux/llvm/gallivm.h b/src/gallium/aux/llvm/gallivm.h new file mode 100644 index 0000000000..92da4bca7f --- /dev/null +++ b/src/gallium/aux/llvm/gallivm.h @@ -0,0 +1,103 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef GALLIVM_H +#define GALLIVM_H + +#if defined __cplusplus +extern "C" { +#endif + +#include "pipe/p_state.h" + +#ifdef MESA_LLVM + +struct tgsi_token; + +struct gallivm_ir; +struct gallivm_prog; +struct gallivm_cpu_engine; +struct tgsi_interp_coef; +struct tgsi_sampler; +struct tgsi_exec_vector; + +enum gallivm_shader_type { + GALLIVM_VS, + GALLIVM_FS +}; + +enum gallivm_vector_layout { + GALLIVM_AOS, + GALLIVM_SOA +}; + +struct gallivm_ir *gallivm_ir_new(enum gallivm_shader_type type); +void gallivm_ir_set_layout(struct gallivm_ir *ir, + enum gallivm_vector_layout layout); +void gallivm_ir_set_components(struct gallivm_ir *ir, int num); +void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, + const struct tgsi_token *tokens); +void gallivm_ir_delete(struct gallivm_ir *ir); + + +struct gallivm_prog *gallivm_ir_compile(struct gallivm_ir *ir); + +void gallivm_prog_inputs_interpolate(struct gallivm_prog *prog, + float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], + const struct tgsi_interp_coef *coefs); +void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix); + + +struct gallivm_cpu_engine *gallivm_cpu_engine_create(struct gallivm_prog *prog); +struct gallivm_cpu_engine *gallivm_global_cpu_engine(); +int gallivm_cpu_vs_exec(struct gallivm_prog *prog, + struct tgsi_exec_vector *inputs, + struct tgsi_exec_vector *dests, + float (*consts)[4], + struct tgsi_exec_vector *temps); +int gallivm_cpu_fs_exec(struct gallivm_prog *prog, + float x, float y, + float (*dests)[PIPE_MAX_SHADER_INPUTS][4], + float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], + float (*consts)[4], + struct tgsi_sampler *samplers); +void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *ee, struct gallivm_prog *prog); +void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *ee); + + +#endif /* MESA_LLVM */ + +#if defined __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/gallium/aux/llvm/gallivm_builtins.cpp b/src/gallium/aux/llvm/gallivm_builtins.cpp new file mode 100644 index 0000000000..1796f0a177 --- /dev/null +++ b/src/gallium/aux/llvm/gallivm_builtins.cpp @@ -0,0 +1,567 @@ +// Generated by llvm2cpp - DO NOT MODIFY! + + +Module* createGallivmBuiltins(Module *mod) { + +mod->setModuleIdentifier("shader"); + +// Type Definitions +ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(8), 25); + +PointerType* PointerTy_1 = PointerType::get(ArrayTy_0, 0); + +std::vectorFuncTy_2_args; +FuncTy_2_args.push_back(Type::FloatTy); +FuncTy_2_args.push_back(Type::FloatTy); +FunctionType* FuncTy_2 = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/FuncTy_2_args, + /*isVarArg=*/false); + +PointerType* PointerTy_3 = PointerType::get(FuncTy_2, 0); + +VectorType* VectorTy_4 = VectorType::get(Type::FloatTy, 4); + +std::vectorFuncTy_5_args; +FuncTy_5_args.push_back(VectorTy_4); +FunctionType* FuncTy_5 = FunctionType::get( + /*Result=*/VectorTy_4, + /*Params=*/FuncTy_5_args, + /*isVarArg=*/false); + +std::vectorFuncTy_6_args; +FuncTy_6_args.push_back(VectorTy_4); +FuncTy_6_args.push_back(VectorTy_4); +FuncTy_6_args.push_back(VectorTy_4); +FunctionType* FuncTy_6 = FunctionType::get( + /*Result=*/VectorTy_4, + /*Params=*/FuncTy_6_args, + /*isVarArg=*/false); + +VectorType* VectorTy_7 = VectorType::get(IntegerType::get(32), 4); + +std::vectorFuncTy_9_args; +FunctionType* FuncTy_9 = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/FuncTy_9_args, + /*isVarArg=*/true); + +PointerType* PointerTy_8 = PointerType::get(FuncTy_9, 0); + +PointerType* PointerTy_10 = PointerType::get(IntegerType::get(8), 0); + +std::vectorFuncTy_12_args; +FuncTy_12_args.push_back(Type::FloatTy); +FunctionType* FuncTy_12 = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/FuncTy_12_args, + /*isVarArg=*/false); + +PointerType* PointerTy_11 = PointerType::get(FuncTy_12, 0); + +std::vectorFuncTy_13_args; +FuncTy_13_args.push_back(VectorTy_4); +FunctionType* FuncTy_13 = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/FuncTy_13_args, + /*isVarArg=*/false); + + +// Function Declarations + +Function* func_approx = new Function( + /*Type=*/FuncTy_2, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"approx", mod); +func_approx->setCallingConv(CallingConv::C); +const ParamAttrsList *func_approx_PAL = 0; +func_approx->setParamAttrs(func_approx_PAL); + +Function* func_powf = new Function( + /*Type=*/FuncTy_2, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"powf", mod); // (external, no body) +func_powf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_powf_PAL = 0; +func_powf->setParamAttrs(func_powf_PAL); + +Function* func_lit = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"lit", mod); +func_lit->setCallingConv(CallingConv::C); +const ParamAttrsList *func_lit_PAL = 0; +func_lit->setParamAttrs(func_lit_PAL); + +Function* func_cmp = new Function( + /*Type=*/FuncTy_6, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"cmp", mod); +func_cmp->setCallingConv(CallingConv::C); +const ParamAttrsList *func_cmp_PAL = 0; +{ + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; + Attrs.push_back(PAWI); + func_cmp_PAL = ParamAttrsList::get(Attrs); + +} +func_cmp->setParamAttrs(func_cmp_PAL); + +Function* func_vcos = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"vcos", mod); +func_vcos->setCallingConv(CallingConv::C); +const ParamAttrsList *func_vcos_PAL = 0; +func_vcos->setParamAttrs(func_vcos_PAL); + +Function* func_printf = new Function( + /*Type=*/FuncTy_9, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"printf", mod); // (external, no body) +func_printf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_printf_PAL = 0; +func_printf->setParamAttrs(func_printf_PAL); + +Function* func_cosf = new Function( + /*Type=*/FuncTy_12, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"cosf", mod); // (external, no body) +func_cosf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_cosf_PAL = 0; +func_cosf->setParamAttrs(func_cosf_PAL); + +Function* func_scs = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"scs", mod); +func_scs->setCallingConv(CallingConv::C); +const ParamAttrsList *func_scs_PAL = 0; +func_scs->setParamAttrs(func_scs_PAL); + +Function* func_sinf = new Function( + /*Type=*/FuncTy_12, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"sinf", mod); // (external, no body) +func_sinf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_sinf_PAL = 0; +func_sinf->setParamAttrs(func_sinf_PAL); + +Function* func_vsin = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"vsin", mod); +func_vsin->setCallingConv(CallingConv::C); +const ParamAttrsList *func_vsin_PAL = 0; +func_vsin->setParamAttrs(func_vsin_PAL); + +Function* func_kilp = new Function( + /*Type=*/FuncTy_13, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"kilp", mod); +func_kilp->setCallingConv(CallingConv::C); +const ParamAttrsList *func_kilp_PAL = 0; +{ + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; + Attrs.push_back(PAWI); + func_kilp_PAL = ParamAttrsList::get(Attrs); + +} +func_kilp->setParamAttrs(func_kilp_PAL); + +// Global Variable Declarations + + +GlobalVariable* gvar_array__str = new GlobalVariable( +/*Type=*/ArrayTy_0, +/*isConstant=*/true, +/*Linkage=*/GlobalValue::InternalLinkage, +/*Initializer=*/0, // has initializer, specified below +/*Name=*/".str", +mod); + +GlobalVariable* gvar_array__str1 = new GlobalVariable( +/*Type=*/ArrayTy_0, +/*isConstant=*/true, +/*Linkage=*/GlobalValue::InternalLinkage, +/*Initializer=*/0, // has initializer, specified below +/*Name=*/".str1", +mod); + +// Constant Definitions +Constant* const_array_14 = ConstantArray::get("VEC IN is %f %f %f %f\x0A", true); +Constant* const_array_15 = ConstantArray::get("VEC OUT is %f %f %f %f\x0A", true); +ConstantFP* const_float_16 = ConstantFP::get(Type::FloatTy, APFloat(-1.280000e+02f)); +ConstantFP* const_float_17 = ConstantFP::get(Type::FloatTy, APFloat(1.280000e+02f)); +Constant* const_float_18 = Constant::getNullValue(Type::FloatTy); +Constant* const_int32_19 = Constant::getNullValue(IntegerType::get(32)); +std::vector const_packed_20_elems; +ConstantFP* const_float_21 = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); +const_packed_20_elems.push_back(const_float_21); +UndefValue* const_float_22 = UndefValue::get(Type::FloatTy); +const_packed_20_elems.push_back(const_float_22); +const_packed_20_elems.push_back(const_float_22); +const_packed_20_elems.push_back(const_float_21); +Constant* const_packed_20 = ConstantVector::get(VectorTy_4, const_packed_20_elems); +ConstantInt* const_int32_23 = ConstantInt::get(APInt(32, "1", 10)); +ConstantInt* const_int32_24 = ConstantInt::get(APInt(32, "3", 10)); +ConstantInt* const_int32_25 = ConstantInt::get(APInt(32, "2", 10)); +std::vector const_packed_26_elems; +const_packed_26_elems.push_back(const_float_21); +const_packed_26_elems.push_back(const_float_18); +const_packed_26_elems.push_back(const_float_18); +const_packed_26_elems.push_back(const_float_21); +Constant* const_packed_26 = ConstantVector::get(VectorTy_4, const_packed_26_elems); +Constant* const_double_27 = Constant::getNullValue(Type::DoubleTy); +std::vector const_packed_28_elems; +const_packed_28_elems.push_back(const_int32_19); +ConstantInt* const_int32_29 = ConstantInt::get(APInt(32, "5", 10)); +const_packed_28_elems.push_back(const_int32_29); +const_packed_28_elems.push_back(const_int32_25); +const_packed_28_elems.push_back(const_int32_24); +Constant* const_packed_28 = ConstantVector::get(VectorTy_7, const_packed_28_elems); +std::vector const_packed_30_elems; +const_packed_30_elems.push_back(const_int32_19); +const_packed_30_elems.push_back(const_int32_23); +ConstantInt* const_int32_31 = ConstantInt::get(APInt(32, "6", 10)); +const_packed_30_elems.push_back(const_int32_31); +const_packed_30_elems.push_back(const_int32_24); +Constant* const_packed_30 = ConstantVector::get(VectorTy_7, const_packed_30_elems); +std::vector const_packed_32_elems; +const_packed_32_elems.push_back(const_int32_19); +const_packed_32_elems.push_back(const_int32_23); +const_packed_32_elems.push_back(const_int32_25); +ConstantInt* const_int32_33 = ConstantInt::get(APInt(32, "7", 10)); +const_packed_32_elems.push_back(const_int32_33); +Constant* const_packed_32 = ConstantVector::get(VectorTy_7, const_packed_32_elems); +std::vector const_ptr_34_indices; +const_ptr_34_indices.push_back(const_int32_19); +const_ptr_34_indices.push_back(const_int32_19); +Constant* const_ptr_34 = ConstantExpr::getGetElementPtr(gvar_array__str, &const_ptr_34_indices[0], const_ptr_34_indices.size() ); +UndefValue* const_packed_35 = UndefValue::get(VectorTy_4); +std::vector const_ptr_36_indices; +const_ptr_36_indices.push_back(const_int32_19); +const_ptr_36_indices.push_back(const_int32_19); +Constant* const_ptr_36 = ConstantExpr::getGetElementPtr(gvar_array__str1, &const_ptr_36_indices[0], const_ptr_36_indices.size() ); + +// Global Variable Definitions +gvar_array__str->setInitializer(const_array_14); +gvar_array__str1->setInitializer(const_array_15); + +// Function Definitions + +// Function: approx (func_approx) +{ + Function::arg_iterator args = func_approx->arg_begin(); + Value* float_a = args++; + float_a->setName("a"); + Value* float_b = args++; + float_b->setName("b"); + + BasicBlock* label_entry = new BasicBlock("entry",func_approx,0); + + // Block entry (label_entry) + FCmpInst* int1_cmp = new FCmpInst(FCmpInst::FCMP_OLT, float_b, const_float_16, "cmp", label_entry); + SelectInst* float_b_addr_0 = new SelectInst(int1_cmp, const_float_16, float_b, "b.addr.0", label_entry); + FCmpInst* int1_cmp3 = new FCmpInst(FCmpInst::FCMP_OGT, float_b_addr_0, const_float_17, "cmp3", label_entry); + SelectInst* float_b_addr_1 = new SelectInst(int1_cmp3, const_float_17, float_b_addr_0, "b.addr.1", label_entry); + FCmpInst* int1_cmp7 = new FCmpInst(FCmpInst::FCMP_OLT, float_a, const_float_18, "cmp7", label_entry); + SelectInst* float_a_addr_0 = new SelectInst(int1_cmp7, const_float_18, float_a, "a.addr.0", label_entry); + std::vector float_call_params; + float_call_params.push_back(float_a_addr_0); + float_call_params.push_back(float_b_addr_1); + CallInst* float_call = new CallInst(func_powf, float_call_params.begin(), float_call_params.end(), "call", label_entry); + float_call->setCallingConv(CallingConv::C); + float_call->setTailCall(true);const ParamAttrsList *float_call_PAL = 0; + float_call->setParamAttrs(float_call_PAL); + + new ReturnInst(float_call, label_entry); + +} + +// Function: lit (func_lit) +{ + Function::arg_iterator args = func_lit->arg_begin(); + Value* packed_tmp = args++; + packed_tmp->setName("tmp"); + + BasicBlock* label_entry_38 = new BasicBlock("entry",func_lit,0); + BasicBlock* label_ifthen = new BasicBlock("ifthen",func_lit,0); + BasicBlock* label_UnifiedReturnBlock = new BasicBlock("UnifiedReturnBlock",func_lit,0); + + // Block entry (label_entry_38) + ExtractElementInst* float_tmp6 = new ExtractElementInst(packed_tmp, const_int32_19, "tmp6", label_entry_38); + FCmpInst* int1_cmp_39 = new FCmpInst(FCmpInst::FCMP_OGT, float_tmp6, const_float_18, "cmp", label_entry_38); + new BranchInst(label_ifthen, label_UnifiedReturnBlock, int1_cmp_39, label_entry_38); + + // Block ifthen (label_ifthen) + InsertElementInst* packed_tmp10 = new InsertElementInst(const_packed_20, float_tmp6, const_int32_23, "tmp10", label_ifthen); + ExtractElementInst* float_tmp12 = new ExtractElementInst(packed_tmp, const_int32_23, "tmp12", label_ifthen); + ExtractElementInst* float_tmp14 = new ExtractElementInst(packed_tmp, const_int32_24, "tmp14", label_ifthen); + std::vector float_call_41_params; + float_call_41_params.push_back(float_tmp12); + float_call_41_params.push_back(float_tmp14); + CallInst* float_call_41 = new CallInst(func_approx, float_call_41_params.begin(), float_call_41_params.end(), "call", label_ifthen); + float_call_41->setCallingConv(CallingConv::C); + float_call_41->setTailCall(true);const ParamAttrsList *float_call_41_PAL = 0; + float_call_41->setParamAttrs(float_call_41_PAL); + + InsertElementInst* packed_tmp16 = new InsertElementInst(packed_tmp10, float_call_41, const_int32_25, "tmp16", label_ifthen); + new ReturnInst(packed_tmp16, label_ifthen); + + // Block UnifiedReturnBlock (label_UnifiedReturnBlock) + new ReturnInst(const_packed_26, label_UnifiedReturnBlock); + +} + +// Function: cmp (func_cmp) +{ + Function::arg_iterator args = func_cmp->arg_begin(); + Value* packed_tmp0 = args++; + packed_tmp0->setName("tmp0"); + Value* packed_tmp1 = args++; + packed_tmp1->setName("tmp1"); + Value* packed_tmp2 = args++; + packed_tmp2->setName("tmp2"); + + BasicBlock* label_entry_44 = new BasicBlock("entry",func_cmp,0); + BasicBlock* label_cond__14 = new BasicBlock("cond.?14",func_cmp,0); + BasicBlock* label_cond_cont20 = new BasicBlock("cond.cont20",func_cmp,0); + BasicBlock* label_cond__28 = new BasicBlock("cond.?28",func_cmp,0); + BasicBlock* label_cond_cont34 = new BasicBlock("cond.cont34",func_cmp,0); + BasicBlock* label_cond__42 = new BasicBlock("cond.?42",func_cmp,0); + BasicBlock* label_cond_cont48 = new BasicBlock("cond.cont48",func_cmp,0); + + // Block entry (label_entry_44) + ExtractElementInst* float_tmp3 = new ExtractElementInst(packed_tmp0, const_int32_19, "tmp3", label_entry_44); + CastInst* double_conv = new FPExtInst(float_tmp3, Type::DoubleTy, "conv", label_entry_44); + FCmpInst* int1_cmp_45 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv, const_double_27, "cmp", label_entry_44); + ExtractElementInst* float_tmp11 = new ExtractElementInst(packed_tmp0, const_int32_23, "tmp11", label_entry_44); + CastInst* double_conv12 = new FPExtInst(float_tmp11, Type::DoubleTy, "conv12", label_entry_44); + FCmpInst* int1_cmp13 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv12, const_double_27, "cmp13", label_entry_44); + SelectInst* packed_tmp1_tmp2 = new SelectInst(int1_cmp_45, packed_tmp1, packed_tmp2, "tmp1.tmp2", label_entry_44); + new BranchInst(label_cond__14, label_cond_cont20, int1_cmp13, label_entry_44); + + // Block cond.?14 (label_cond__14) + ShuffleVectorInst* packed_tmp233 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp1, const_packed_28, "tmp233", label_cond__14); + ExtractElementInst* float_tmp254 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp254", label_cond__14); + CastInst* double_conv265 = new FPExtInst(float_tmp254, Type::DoubleTy, "conv265", label_cond__14); + FCmpInst* int1_cmp276 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv265, const_double_27, "cmp276", label_cond__14); + new BranchInst(label_cond__28, label_cond_cont34, int1_cmp276, label_cond__14); + + // Block cond.cont20 (label_cond_cont20) + ShuffleVectorInst* packed_tmp23 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp2, const_packed_28, "tmp23", label_cond_cont20); + ExtractElementInst* float_tmp25 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp25", label_cond_cont20); + CastInst* double_conv26 = new FPExtInst(float_tmp25, Type::DoubleTy, "conv26", label_cond_cont20); + FCmpInst* int1_cmp27 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv26, const_double_27, "cmp27", label_cond_cont20); + new BranchInst(label_cond__28, label_cond_cont34, int1_cmp27, label_cond_cont20); + + // Block cond.?28 (label_cond__28) + PHINode* packed_tmp23_reg2mem_0 = new PHINode(VectorTy_4, "tmp23.reg2mem.0", label_cond__28); + packed_tmp23_reg2mem_0->reserveOperandSpace(2); + packed_tmp23_reg2mem_0->addIncoming(packed_tmp233, label_cond__14); + packed_tmp23_reg2mem_0->addIncoming(packed_tmp23, label_cond_cont20); + + ShuffleVectorInst* packed_tmp378 = new ShuffleVectorInst(packed_tmp23_reg2mem_0, packed_tmp1, const_packed_30, "tmp378", label_cond__28); + ExtractElementInst* float_tmp399 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp399", label_cond__28); + CastInst* double_conv4010 = new FPExtInst(float_tmp399, Type::DoubleTy, "conv4010", label_cond__28); + FCmpInst* int1_cmp4111 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv4010, const_double_27, "cmp4111", label_cond__28); + new BranchInst(label_cond__42, label_cond_cont48, int1_cmp4111, label_cond__28); + + // Block cond.cont34 (label_cond_cont34) + PHINode* packed_tmp23_reg2mem_1 = new PHINode(VectorTy_4, "tmp23.reg2mem.1", label_cond_cont34); + packed_tmp23_reg2mem_1->reserveOperandSpace(2); + packed_tmp23_reg2mem_1->addIncoming(packed_tmp233, label_cond__14); + packed_tmp23_reg2mem_1->addIncoming(packed_tmp23, label_cond_cont20); + + ShuffleVectorInst* packed_tmp37 = new ShuffleVectorInst(packed_tmp23_reg2mem_1, packed_tmp2, const_packed_30, "tmp37", label_cond_cont34); + ExtractElementInst* float_tmp39 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp39", label_cond_cont34); + CastInst* double_conv40 = new FPExtInst(float_tmp39, Type::DoubleTy, "conv40", label_cond_cont34); + FCmpInst* int1_cmp41 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv40, const_double_27, "cmp41", label_cond_cont34); + new BranchInst(label_cond__42, label_cond_cont48, int1_cmp41, label_cond_cont34); + + // Block cond.?42 (label_cond__42) + PHINode* packed_tmp37_reg2mem_0 = new PHINode(VectorTy_4, "tmp37.reg2mem.0", label_cond__42); + packed_tmp37_reg2mem_0->reserveOperandSpace(2); + packed_tmp37_reg2mem_0->addIncoming(packed_tmp378, label_cond__28); + packed_tmp37_reg2mem_0->addIncoming(packed_tmp37, label_cond_cont34); + + ShuffleVectorInst* packed_tmp5113 = new ShuffleVectorInst(packed_tmp37_reg2mem_0, packed_tmp1, const_packed_32, "tmp5113", label_cond__42); + new ReturnInst(packed_tmp5113, label_cond__42); + + // Block cond.cont48 (label_cond_cont48) + PHINode* packed_tmp37_reg2mem_1 = new PHINode(VectorTy_4, "tmp37.reg2mem.1", label_cond_cont48); + packed_tmp37_reg2mem_1->reserveOperandSpace(2); + packed_tmp37_reg2mem_1->addIncoming(packed_tmp378, label_cond__28); + packed_tmp37_reg2mem_1->addIncoming(packed_tmp37, label_cond_cont34); + + ShuffleVectorInst* packed_tmp51 = new ShuffleVectorInst(packed_tmp37_reg2mem_1, packed_tmp2, const_packed_32, "tmp51", label_cond_cont48); + new ReturnInst(packed_tmp51, label_cond_cont48); + +} + +// Function: vcos (func_vcos) +{ + Function::arg_iterator args = func_vcos->arg_begin(); + Value* packed_val = args++; + packed_val->setName("val"); + + BasicBlock* label_entry_53 = new BasicBlock("entry",func_vcos,0); + + // Block entry (label_entry_53) + ExtractElementInst* float_tmp1 = new ExtractElementInst(packed_val, const_int32_19, "tmp1", label_entry_53); + CastInst* double_conv_54 = new FPExtInst(float_tmp1, Type::DoubleTy, "conv", label_entry_53); + ExtractElementInst* float_tmp3_55 = new ExtractElementInst(packed_val, const_int32_23, "tmp3", label_entry_53); + CastInst* double_conv4 = new FPExtInst(float_tmp3_55, Type::DoubleTy, "conv4", label_entry_53); + ExtractElementInst* float_tmp6_56 = new ExtractElementInst(packed_val, const_int32_25, "tmp6", label_entry_53); + CastInst* double_conv7 = new FPExtInst(float_tmp6_56, Type::DoubleTy, "conv7", label_entry_53); + ExtractElementInst* float_tmp9 = new ExtractElementInst(packed_val, const_int32_24, "tmp9", label_entry_53); + CastInst* double_conv10 = new FPExtInst(float_tmp9, Type::DoubleTy, "conv10", label_entry_53); + std::vector int32_call_params; + int32_call_params.push_back(const_ptr_34); + int32_call_params.push_back(double_conv_54); + int32_call_params.push_back(double_conv4); + int32_call_params.push_back(double_conv7); + int32_call_params.push_back(double_conv10); + CallInst* int32_call = new CallInst(func_printf, int32_call_params.begin(), int32_call_params.end(), "call", label_entry_53); + int32_call->setCallingConv(CallingConv::C); + int32_call->setTailCall(true);const ParamAttrsList *int32_call_PAL = 0; + int32_call->setParamAttrs(int32_call_PAL); + + CallInst* float_call13 = new CallInst(func_cosf, float_tmp1, "call13", label_entry_53); + float_call13->setCallingConv(CallingConv::C); + float_call13->setTailCall(true);const ParamAttrsList *float_call13_PAL = 0; + float_call13->setParamAttrs(float_call13_PAL); + + InsertElementInst* packed_tmp15 = new InsertElementInst(const_packed_35, float_call13, const_int32_19, "tmp15", label_entry_53); + CallInst* float_call18 = new CallInst(func_cosf, float_tmp1, "call18", label_entry_53); + float_call18->setCallingConv(CallingConv::C); + float_call18->setTailCall(true);const ParamAttrsList *float_call18_PAL = 0; + float_call18->setParamAttrs(float_call18_PAL); + + InsertElementInst* packed_tmp20 = new InsertElementInst(packed_tmp15, float_call18, const_int32_23, "tmp20", label_entry_53); + CallInst* float_call23 = new CallInst(func_cosf, float_tmp1, "call23", label_entry_53); + float_call23->setCallingConv(CallingConv::C); + float_call23->setTailCall(true);const ParamAttrsList *float_call23_PAL = 0; + float_call23->setParamAttrs(float_call23_PAL); + + InsertElementInst* packed_tmp25 = new InsertElementInst(packed_tmp20, float_call23, const_int32_25, "tmp25", label_entry_53); + CallInst* float_call28 = new CallInst(func_cosf, float_tmp1, "call28", label_entry_53); + float_call28->setCallingConv(CallingConv::C); + float_call28->setTailCall(true);const ParamAttrsList *float_call28_PAL = 0; + float_call28->setParamAttrs(float_call28_PAL); + + InsertElementInst* packed_tmp30 = new InsertElementInst(packed_tmp25, float_call28, const_int32_24, "tmp30", label_entry_53); + CastInst* double_conv33 = new FPExtInst(float_call13, Type::DoubleTy, "conv33", label_entry_53); + CastInst* double_conv36 = new FPExtInst(float_call18, Type::DoubleTy, "conv36", label_entry_53); + CastInst* double_conv39 = new FPExtInst(float_call23, Type::DoubleTy, "conv39", label_entry_53); + CastInst* double_conv42 = new FPExtInst(float_call28, Type::DoubleTy, "conv42", label_entry_53); + std::vector int32_call43_params; + int32_call43_params.push_back(const_ptr_36); + int32_call43_params.push_back(double_conv33); + int32_call43_params.push_back(double_conv36); + int32_call43_params.push_back(double_conv39); + int32_call43_params.push_back(double_conv42); + CallInst* int32_call43 = new CallInst(func_printf, int32_call43_params.begin(), int32_call43_params.end(), "call43", label_entry_53); + int32_call43->setCallingConv(CallingConv::C); + int32_call43->setTailCall(true);const ParamAttrsList *int32_call43_PAL = 0; + int32_call43->setParamAttrs(int32_call43_PAL); + + new ReturnInst(packed_tmp30, label_entry_53); + +} + +// Function: scs (func_scs) +{ + Function::arg_iterator args = func_scs->arg_begin(); + Value* packed_val_58 = args++; + packed_val_58->setName("val"); + + BasicBlock* label_entry_59 = new BasicBlock("entry",func_scs,0); + + // Block entry (label_entry_59) + ExtractElementInst* float_tmp2 = new ExtractElementInst(packed_val_58, const_int32_19, "tmp2", label_entry_59); + CallInst* float_call_60 = new CallInst(func_cosf, float_tmp2, "call", label_entry_59); + float_call_60->setCallingConv(CallingConv::C); + float_call_60->setTailCall(true);const ParamAttrsList *float_call_60_PAL = 0; + float_call_60->setParamAttrs(float_call_60_PAL); + + InsertElementInst* packed_tmp5 = new InsertElementInst(const_packed_35, float_call_60, const_int32_19, "tmp5", label_entry_59); + CallInst* float_call7 = new CallInst(func_sinf, float_tmp2, "call7", label_entry_59); + float_call7->setCallingConv(CallingConv::C); + float_call7->setTailCall(true);const ParamAttrsList *float_call7_PAL = 0; + float_call7->setParamAttrs(float_call7_PAL); + + InsertElementInst* packed_tmp9 = new InsertElementInst(packed_tmp5, float_call7, const_int32_23, "tmp9", label_entry_59); + new ReturnInst(packed_tmp9, label_entry_59); + +} + +// Function: vsin (func_vsin) +{ + Function::arg_iterator args = func_vsin->arg_begin(); + Value* packed_val_62 = args++; + packed_val_62->setName("val"); + + BasicBlock* label_entry_63 = new BasicBlock("entry",func_vsin,0); + + // Block entry (label_entry_63) + ExtractElementInst* float_tmp2_64 = new ExtractElementInst(packed_val_62, const_int32_19, "tmp2", label_entry_63); + CallInst* float_call_65 = new CallInst(func_sinf, float_tmp2_64, "call", label_entry_63); + float_call_65->setCallingConv(CallingConv::C); + float_call_65->setTailCall(true);const ParamAttrsList *float_call_65_PAL = 0; + float_call_65->setParamAttrs(float_call_65_PAL); + + InsertElementInst* packed_tmp6 = new InsertElementInst(const_packed_35, float_call_65, const_int32_19, "tmp6", label_entry_63); + InsertElementInst* packed_tmp9_66 = new InsertElementInst(packed_tmp6, float_call_65, const_int32_23, "tmp9", label_entry_63); + InsertElementInst* packed_tmp12 = new InsertElementInst(packed_tmp9_66, float_call_65, const_int32_25, "tmp12", label_entry_63); + InsertElementInst* packed_tmp15_67 = new InsertElementInst(packed_tmp12, float_call_65, const_int32_24, "tmp15", label_entry_63); + new ReturnInst(packed_tmp15_67, label_entry_63); + +} + +// Function: kilp (func_kilp) +{ + Function::arg_iterator args = func_kilp->arg_begin(); + Value* packed_val_69 = args++; + packed_val_69->setName("val"); + + BasicBlock* label_entry_70 = new BasicBlock("entry",func_kilp,0); + BasicBlock* label_lor_rhs = new BasicBlock("lor_rhs",func_kilp,0); + BasicBlock* label_lor_rhs5 = new BasicBlock("lor_rhs5",func_kilp,0); + BasicBlock* label_lor_rhs11 = new BasicBlock("lor_rhs11",func_kilp,0); + BasicBlock* label_UnifiedReturnBlock_71 = new BasicBlock("UnifiedReturnBlock",func_kilp,0); + + // Block entry (label_entry_70) + ExtractElementInst* float_tmp1_72 = new ExtractElementInst(packed_val_69, const_int32_19, "tmp1", label_entry_70); + FCmpInst* int1_cmp_73 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp1_72, const_float_18, "cmp", label_entry_70); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs, int1_cmp_73, label_entry_70); + + // Block lor_rhs (label_lor_rhs) + ExtractElementInst* float_tmp3_75 = new ExtractElementInst(packed_val_69, const_int32_23, "tmp3", label_lor_rhs); + FCmpInst* int1_cmp4 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp3_75, const_float_18, "cmp4", label_lor_rhs); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs5, int1_cmp4, label_lor_rhs); + + // Block lor_rhs5 (label_lor_rhs5) + ExtractElementInst* float_tmp7 = new ExtractElementInst(packed_val_69, const_int32_25, "tmp7", label_lor_rhs5); + FCmpInst* int1_cmp8 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp7, const_float_18, "cmp8", label_lor_rhs5); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs11, int1_cmp8, label_lor_rhs5); + + // Block lor_rhs11 (label_lor_rhs11) + ExtractElementInst* float_tmp13 = new ExtractElementInst(packed_val_69, const_int32_24, "tmp13", label_lor_rhs11); + FCmpInst* int1_cmp14 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp13, const_float_18, "cmp14", label_lor_rhs11); + CastInst* int32_retval = new ZExtInst(int1_cmp14, IntegerType::get(32), "retval", label_lor_rhs11); + new ReturnInst(int32_retval, label_lor_rhs11); + + // Block UnifiedReturnBlock (label_UnifiedReturnBlock_71) + new ReturnInst(const_int32_23, label_UnifiedReturnBlock_71); + +} + +return mod; + +} diff --git a/src/gallium/aux/llvm/gallivm_cpu.cpp b/src/gallium/aux/llvm/gallivm_cpu.cpp new file mode 100644 index 0000000000..dc4d92a72a --- /dev/null +++ b/src/gallium/aux/llvm/gallivm_cpu.cpp @@ -0,0 +1,202 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "instructions.h" +#include "loweringpass.h" +#include "storage.h" +#include "tgsitollvm.h" + +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" + +#include "pipe/tgsi/exec/tgsi_exec.h" +#include "pipe/tgsi/util/tgsi_dump.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct gallivm_cpu_engine { + llvm::ExecutionEngine *engine; +}; + +static struct gallivm_cpu_engine *CPU = 0; + +typedef int (*fragment_shader_runner)(float x, float y, + float (*dests)[16][4], + float (*inputs)[16][4], + int num_attribs, + float (*consts)[4], int num_consts, + struct tgsi_sampler *samplers); + +int gallivm_cpu_fs_exec(struct gallivm_prog *prog, + float fx, float fy, + float (*dests)[16][4], + float (*inputs)[16][4], + float (*consts)[4], + struct tgsi_sampler *samplers) +{ + fragment_shader_runner runner = reinterpret_cast(prog->function); + assert(runner); + + return runner(fx, fy, dests, inputs, prog->num_interp, + consts, prog->num_consts, + samplers); +} + +static inline llvm::Function *func_for_shader(struct gallivm_prog *prog) +{ + llvm::Module *mod = prog->module; + llvm::Function *func = 0; + + switch (prog->type) { + case GALLIVM_VS: + func = mod->getFunction("vs_shader"); + break; + case GALLIVM_FS: + func = mod->getFunction("fs_shader"); + break; + default: + assert(!"Unknown shader type!"); + break; + } + return func; +} + +/*! + This function creates a CPU based execution engine for the given gallivm_prog. + gallivm_cpu_engine should be used as a singleton throughout the library. Before + executing gallivm_prog_exec one needs to call gallivm_cpu_jit_compile. + The gallivm_prog instance which is being passed to the constructor is being + automatically JIT compiled so one shouldn't call gallivm_cpu_jit_compile + with it again. + */ +struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog) +{ + struct gallivm_cpu_engine *cpu = (struct gallivm_cpu_engine *) + calloc(1, sizeof(struct gallivm_cpu_engine)); + llvm::Module *mod = static_cast(prog->module); + llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); + llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false); + ee->DisableLazyCompilation(); + cpu->engine = ee; + + llvm::Function *func = func_for_shader(prog); + + prog->function = ee->getPointerToFunction(func); + CPU = cpu; + return cpu; +} + + +/*! + This function JIT compiles the given gallivm_prog with the given cpu based execution engine. + The reference to the generated machine code entry point will be stored + in the gallivm_prog program. After executing this function one can call gallivm_prog_exec + in order to execute the gallivm_prog on the CPU. + */ +void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog *prog) +{ + llvm::Module *mod = static_cast(prog->module); + llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); + llvm::ExecutionEngine *ee = cpu->engine; + assert(ee); + /*FIXME : remove */ + ee->DisableLazyCompilation(); + ee->addModuleProvider(mp); + + llvm::Function *func = func_for_shader(prog); + prog->function = ee->getPointerToFunction(func); +} + +void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu) +{ + free(cpu); +} + +struct gallivm_cpu_engine * gallivm_global_cpu_engine() +{ + return CPU; +} + + +typedef void (*vertex_shader_runner)(void *ainputs, + void *dests, + float (*aconsts)[4], + void *temps); + + +/*! + This function is used to execute the gallivm_prog in software. Before calling + this function the gallivm_prog has to be JIT compiled with the gallivm_cpu_jit_compile + function. + */ +int gallivm_cpu_vs_exec(struct gallivm_prog *prog, + struct tgsi_exec_vector *inputs, + struct tgsi_exec_vector *dests, + float (*consts)[4], + struct tgsi_exec_vector *temps) +{ + vertex_shader_runner runner = reinterpret_cast(prog->function); + assert(runner); + /*FIXME*/ + runner(inputs, dests, consts, temps); + + return 0; +} + +#endif diff --git a/src/gallium/aux/llvm/gallivm_p.h b/src/gallium/aux/llvm/gallivm_p.h new file mode 100644 index 0000000000..cfe7b1901b --- /dev/null +++ b/src/gallium/aux/llvm/gallivm_p.h @@ -0,0 +1,110 @@ +#ifndef GALLIVM_P_H +#define GALLIVM_P_H + +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_compiler.h" + +namespace llvm { + class Module; +} + +#if defined __cplusplus +extern "C" { +#endif + +enum gallivm_shader_type; +enum gallivm_vector_layout; + +struct gallivm_interpolate { + int attrib; + int chan; + int type; +}; + +struct gallivm_ir { + llvm::Module *module; + int id; + enum gallivm_shader_type type; + enum gallivm_vector_layout layout; + int num_components; + int num_consts; + + //FIXME: this might not be enough for some shaders + struct gallivm_interpolate interpolators[32*4]; + int num_interp; +}; + +struct gallivm_prog { + llvm::Module *module; + void *function; + + int id; + enum gallivm_shader_type type; + + int num_consts; + + //FIXME: this might not be enough for some shaders + struct gallivm_interpolate interpolators[32*4]; + int num_interp; +}; + +static INLINE void gallivm_swizzle_components(int swizzle, + int *xc, int *yc, + int *zc, int *wc) +{ + int x = swizzle / 1000; swizzle -= x * 1000; + int y = swizzle / 100; swizzle -= y * 100; + int z = swizzle / 10; swizzle -= z * 10; + int w = swizzle; + + if (xc) *xc = x; + if (yc) *yc = y; + if (zc) *zc = z; + if (wc) *wc = w; +} + +static INLINE boolean gallivm_is_swizzle(int swizzle) +{ + const int NO_SWIZZLE = TGSI_SWIZZLE_X * 1000 + TGSI_SWIZZLE_Y * 100 + + TGSI_SWIZZLE_Z * 10 + TGSI_SWIZZLE_W; + return swizzle != NO_SWIZZLE; +} + +static INLINE int gallivm_x_swizzle(int swizzle) +{ + int x; + gallivm_swizzle_components(swizzle, &x, 0, 0, 0); + return x; +} + +static INLINE int gallivm_y_swizzle(int swizzle) +{ + int y; + gallivm_swizzle_components(swizzle, 0, &y, 0, 0); + return y; +} + +static INLINE int gallivm_z_swizzle(int swizzle) +{ + int z; + gallivm_swizzle_components(swizzle, 0, 0, &z, 0); + return z; +} + +static INLINE int gallivm_w_swizzle(int swizzle) +{ + int w; + gallivm_swizzle_components(swizzle, 0, 0, 0, &w); + return w; +} + +#endif /* MESA_LLVM */ + +#if defined __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/gallium/aux/llvm/instructions.cpp b/src/gallium/aux/llvm/instructions.cpp new file mode 100644 index 0000000000..55d39fa5f1 --- /dev/null +++ b/src/gallium/aux/llvm/instructions.cpp @@ -0,0 +1,889 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "instructions.h" + +#include "storage.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace llvm; + +#include "gallivm_builtins.cpp" + +static inline std::string createFuncName(int label) +{ + std::ostringstream stream; + stream << "function"; + stream << label; + return stream.str(); +} + +Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, + Storage *storage) + : m_mod(mod), m_func(func), m_builder(block), m_idx(0), + m_storage(storage) +{ + m_floatVecType = VectorType::get(Type::FloatTy, 4); + + m_llvmFSqrt = 0; + m_llvmFAbs = 0; + m_llvmPow = 0; + m_llvmFloor = 0; + m_llvmFlog = 0; + m_llvmLit = 0; + m_fmtPtr = 0; + + createGallivmBuiltins(m_mod); +} + +llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2) +{ + return m_builder.CreateAdd(in1, in2, name("add")); +} + +llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3) +{ + Value *mulRes = mul(in1, in2); + return add(mulRes, in3); +} + +llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2) +{ + return m_builder.CreateMul(in1, in2, name("mul")); +} + +const char * Instructions::name(const char *prefix) +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + Value *x = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(0), + name("extractx")); + Value *y = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(1), + name("extracty")); + Value *z = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(2), + name("extractz")); + Value *xy = m_builder.CreateAdd(x, y,name("xy")); + Value *dot3 = m_builder.CreateAdd(xy, z, name("dot3")); + return vectorFromVals(dot3, dot3, dot3, dot3); +} + +llvm::Value *Instructions::callFSqrt(llvm::Value *val) +{ + if (!m_llvmFSqrt) { + // predeclare the intrinsic + std::vector fsqrtArgs; + fsqrtArgs.push_back(Type::FloatTy); + ParamAttrsList *fsqrtPal = 0; + FunctionType* fsqrtType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/fsqrtArgs, + /*isVarArg=*/false); + m_llvmFSqrt = new Function( + /*Type=*/fsqrtType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"llvm.sqrt.f32", m_mod); + m_llvmFSqrt->setCallingConv(CallingConv::C); + m_llvmFSqrt->setParamAttrs(fsqrtPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFSqrt, val, + name("sqrt")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::rsq(llvm::Value *in1) +{ + Value *x = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("extractx")); + Value *abs = callFAbs(x); + Value *sqrt = callFSqrt(abs); + + Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, + APFloat(1.f)), + sqrt, + name("rsqrt")); + return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt); +} + +llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w) +{ + Constant *const_vec = Constant::getNullValue(m_floatVecType); + Value *res = m_builder.CreateInsertElement(const_vec, x, + m_storage->constantInt(0), + name("vecx")); + res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), + name("vecxy")); + res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), + name("vecxyz")); + if (w) + res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), + name("vecxyzw")); + return res; +} + +llvm::Value *Instructions::callFAbs(llvm::Value *val) +{ + if (!m_llvmFAbs) { + // predeclare the intrinsic + std::vector fabsArgs; + fabsArgs.push_back(Type::FloatTy); + ParamAttrsList *fabsPal = 0; + FunctionType* fabsType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/fabsArgs, + /*isVarArg=*/false); + m_llvmFAbs = new Function( + /*Type=*/fabsType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"fabs", m_mod); + m_llvmFAbs->setCallingConv(CallingConv::C); + m_llvmFAbs->setParamAttrs(fabsPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFAbs, val, + name("fabs")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::lit(llvm::Value *in) +{ + if (!m_llvmLit) { + m_llvmLit = m_mod->getFunction("lit"); + } + CallInst *call = m_builder.CreateCall(m_llvmLit, in, name("litres")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2) +{ + Value *res = m_builder.CreateSub(in1, in2, name("sub")); + return res; +} + +llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2) +{ + if (!m_llvmPow) { + // predeclare the intrinsic + std::vector powArgs; + powArgs.push_back(Type::FloatTy); + powArgs.push_back(Type::FloatTy); + ParamAttrsList *powPal = 0; + FunctionType* powType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/powArgs, + /*isVarArg=*/false); + m_llvmPow = new Function( + /*Type=*/powType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"llvm.pow.f32", m_mod); + m_llvmPow->setCallingConv(CallingConv::C); + m_llvmPow->setParamAttrs(powPal); + } + std::vector params; + params.push_back(val1); + params.push_back(val2); + CallInst *call = m_builder.CreateCall(m_llvmPow, params.begin(), params.end(), + name("pow")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *x2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(0), + name("x2")); + llvm::Value *val = callPow(x1, x2); + return vectorFromVals(val, val, val, val); +} + +llvm::Value * Instructions::rcp(llvm::Value *in1) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *res = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, + APFloat(1.f)), + x1, name("rcp")); + return vectorFromVals(res, res, res, res); +} + +llvm::Value * Instructions::dp4(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + std::vector vec = extractVector(mulRes); + Value *xy = m_builder.CreateAdd(vec[0], vec[1], name("xy")); + Value *xyz = m_builder.CreateAdd(xy, vec[2], name("xyz")); + Value *dot4 = m_builder.CreateAdd(xyz, vec[3], name("dot4")); + return vectorFromVals(dot4, dot4, dot4, dot4); +} + +llvm::Value * Instructions::dph(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + std::vector vec1 = extractVector(mulRes); + Value *xy = m_builder.CreateAdd(vec1[0], vec1[1], name("xy")); + Value *xyz = m_builder.CreateAdd(xy, vec1[2], name("xyz")); + Value *dph = m_builder.CreateAdd(xyz, vec1[3], name("dph")); + return vectorFromVals(dph, dph, dph, dph); +} + +llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2) +{ + Value *y1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(1), + name("y1")); + Value *z = m_builder.CreateExtractElement(in1, + m_storage->constantInt(2), + name("z")); + Value *y2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(1), + name("y2")); + Value *w = m_builder.CreateExtractElement(in2, + m_storage->constantInt(3), + name("w")); + Value *ry = m_builder.CreateMul(y1, y2, name("tyuy")); + return vectorFromVals(ConstantFP::get(Type::FloatTy, APFloat(1.f)), + ry, z, w); +} + +llvm::Value * Instructions::ex2(llvm::Value *in) +{ + llvm::Value *val = callPow(ConstantFP::get(Type::FloatTy, APFloat(2.f)), + m_builder.CreateExtractElement( + in, m_storage->constantInt(0), + name("x1"))); + return vectorFromVals(val, val, val, val); +} + +llvm::Value * Instructions::callFloor(llvm::Value *val) +{ + if (!m_llvmFloor) { + // predeclare the intrinsic + std::vector floorArgs; + floorArgs.push_back(Type::FloatTy); + ParamAttrsList *floorPal = 0; + FunctionType* floorType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/floorArgs, + /*isVarArg=*/false); + m_llvmFloor = new Function( + /*Type=*/floorType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"floorf", m_mod); + m_llvmFloor->setCallingConv(CallingConv::C); + m_llvmFloor->setParamAttrs(floorPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFloor, val, + name("floorf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::floor(llvm::Value *in) +{ + std::vector vec = extractVector(in); + return vectorFromVals(callFloor(vec[0]), callFloor(vec[1]), + callFloor(vec[2]), callFloor(vec[3])); +} + +llvm::Value * Instructions::arl(llvm::Value *in) +{ + return floor(in); +} + +llvm::Value * Instructions::frc(llvm::Value *in) +{ + llvm::Value *flr = floor(in); + return sub(in, flr); +} + +llvm::Value * Instructions::callFLog(llvm::Value *val) +{ + if (!m_llvmFlog) { + // predeclare the intrinsic + std::vector flogArgs; + flogArgs.push_back(Type::FloatTy); + ParamAttrsList *flogPal = 0; + FunctionType* flogType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/flogArgs, + /*isVarArg=*/false); + m_llvmFlog = new Function( + /*Type=*/flogType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"logf", m_mod); + m_llvmFlog->setCallingConv(CallingConv::C); + m_llvmFlog->setParamAttrs(flogPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFlog, val, + name("logf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::lg2(llvm::Value *in) +{ + std::vector vec = extractVector(in); + llvm::Value *const_vec = constVector(1.442695f, 1.442695f, + 1.442695f, 1.442695f); + return mul(vectorFromVals(callFLog(vec[0]), callFLog(vec[1]), + callFLog(vec[2]), callFLog(vec[3])), const_vec); +} + +llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2) +{ + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); + Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], + name("selx")); + + Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); + Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], + name("sely")); + + Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); + Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], + name("selz")); + + Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); + Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], + name("selw")); + + return vectorFromVals(selx, sely, selz, selw); +} + +llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2) +{ + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], + name("xcmp")); + Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], + name("selx")); + + Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], + name("ycmp")); + Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], + name("sely")); + + Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], + name("zcmp")); + Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], + name("selz")); + + Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], + name("wcmp")); + Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], + name("selw")); + + return vectorFromVals(selx, sely, selz, selw); +} + +void Instructions::printVector(llvm::Value *val) +{ + static const char *frmt = "Vector is [%f, %f, %f, %f]\x0A"; + + if (!m_fmtPtr) { + Constant *format = ConstantArray::get(frmt, true); + ArrayType *arrayTy = ArrayType::get(IntegerType::get(8), strlen(frmt) + 1); + GlobalVariable* globalFormat = new GlobalVariable( + /*Type=*/arrayTy, + /*isConstant=*/true, + /*Linkage=*/GlobalValue::InternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name(".str"), + m_mod); + globalFormat->setInitializer(format); + + Constant* const_int0 = Constant::getNullValue(IntegerType::get(32)); + std::vector const_ptr_21_indices; + const_ptr_21_indices.push_back(const_int0); + const_ptr_21_indices.push_back(const_int0); + m_fmtPtr = ConstantExpr::getGetElementPtr(globalFormat, + &const_ptr_21_indices[0], const_ptr_21_indices.size()); + } + + Function *func_printf = m_mod->getFunction("printf"); + if (!func_printf) + func_printf = declarePrintf(); + assert(func_printf); + std::vector vec = extractVector(val); + Value *dx = m_builder.CreateFPExt(vec[0], Type::DoubleTy, name("dx")); + Value *dy = m_builder.CreateFPExt(vec[1], Type::DoubleTy, name("dy")); + Value *dz = m_builder.CreateFPExt(vec[2], Type::DoubleTy, name("dz")); + Value *dw = m_builder.CreateFPExt(vec[3], Type::DoubleTy, name("dw")); + std::vector params; + params.push_back(m_fmtPtr); + params.push_back(dx); + params.push_back(dy); + params.push_back(dz); + params.push_back(dw); + CallInst *call = m_builder.CreateCall(func_printf, params.begin(), params.end(), + name("printf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(true); +} + +llvm::Function * Instructions::declarePrintf() +{ + std::vector args; + ParamAttrsList *params = 0; + FunctionType* funcTy = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/args, + /*isVarArg=*/true); + Function* func_printf = new Function( + /*Type=*/funcTy, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"printf", m_mod); + func_printf->setCallingConv(CallingConv::C); + func_printf->setParamAttrs(params); + return func_printf; +} + + +llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} +llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} + + +llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} + +llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *y1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(1), + name("y1")); + Value *z1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(2), + name("z1")); + + Value *x2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(0), + name("x2")); + Value *y2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(1), + name("y2")); + Value *z2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(2), + name("z2")); + Value *y1z2 = mul(y1, z2); + Value *z1y2 = mul(z1, y2); + + Value *z1x2 = mul(z1, x2); + Value *x1z2 = mul(x1, z2); + + Value *x1y2 = mul(x1, y2); + Value *y1x2 = mul(y1, x2); + + return vectorFromVals(sub(y1z2, z1y2), sub(z1x2, x1z2), sub(x1y2, y1x2)); +} + + +llvm::Value * Instructions::abs(llvm::Value *in) +{ + std::vector vec = extractVector(in); + Value *xabs = callFAbs(vec[0]); + Value *yabs = callFAbs(vec[1]); + Value *zabs = callFAbs(vec[2]); + Value *wabs = callFAbs(vec[3]); + return vectorFromVals(xabs, yabs, zabs, wabs); +} + +void Instructions::ifop(llvm::Value *in) +{ + BasicBlock *ifthen = new BasicBlock(name("ifthen"), m_func,0); + BasicBlock *ifend = new BasicBlock(name("ifthenend"), m_func,0); + + //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0); + //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0); + //BasicBlock *wblock = new BasicBlock(name("wblock"), m_func,0); + + Constant *float0 = Constant::getNullValue(Type::FloatTy); + + Value *x = m_builder.CreateExtractElement(in, m_storage->constantInt(0), + name("extractx")); + Value *xcmp = m_builder.CreateFCmpUNE(x, float0, name("xcmp")); + m_builder.CreateCondBr(xcmp, ifthen, ifend); + //m_builder.SetInsertPoint(yblock); + + m_builder.SetInsertPoint(ifthen); + m_ifStack.push(ifend); +} + +llvm::BasicBlock * Instructions::currentBlock() const +{ + return m_builder.GetInsertBlock(); +} + +void Instructions::elseop() +{ + assert(!m_ifStack.empty()); + BasicBlock *ifend = new BasicBlock(name("ifend"), m_func,0); + m_builder.CreateBr(ifend); + m_builder.SetInsertPoint(m_ifStack.top()); + currentBlock()->setName(name("ifelse")); + m_ifStack.pop(); + m_ifStack.push(ifend); +} + +void Instructions::endif() +{ + assert(!m_ifStack.empty()); + m_builder.CreateBr(m_ifStack.top()); + m_builder.SetInsertPoint(m_ifStack.top()); + m_ifStack.pop(); +} + +llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3) +{ + llvm::Value *m = mul(in1, in2); + llvm::Value *vec1 = constVector(1.f, 1.f, 1.f, 1.f); + llvm::Value *s = sub(vec1, in1); + return add(m, mul(s, in3)); +} + +void Instructions::beginLoop() +{ + BasicBlock *begin = new BasicBlock(name("loop"), m_func,0); + BasicBlock *end = new BasicBlock(name("endloop"), m_func,0); + + m_builder.CreateBr(begin); + Loop loop; + loop.begin = begin; + loop.end = end; + m_builder.SetInsertPoint(begin); + m_loopStack.push(loop); +} + +void Instructions::endLoop() +{ + assert(!m_loopStack.empty()); + Loop loop = m_loopStack.top(); + m_builder.CreateBr(loop.begin); + loop.end->moveAfter(currentBlock()); + m_builder.SetInsertPoint(loop.end); + m_loopStack.pop(); +} + +void Instructions::brk() +{ + assert(!m_loopStack.empty()); + BasicBlock *unr = new BasicBlock(name("unreachable"), m_func,0); + m_builder.CreateBr(m_loopStack.top().end); + m_builder.SetInsertPoint(unr); +} + +llvm::Value * Instructions::trunc(llvm::Value *in) +{ + std::vector vec = extractVector(in); + Value *icastx = m_builder.CreateFPToSI(vec[0], IntegerType::get(32), + name("ftoix")); + Value *icasty = m_builder.CreateFPToSI(vec[1], IntegerType::get(32), + name("ftoiy")); + Value *icastz = m_builder.CreateFPToSI(vec[2], IntegerType::get(32), + name("ftoiz")); + Value *icastw = m_builder.CreateFPToSI(vec[3], IntegerType::get(32), + name("ftoiw")); + Value *fx = m_builder.CreateSIToFP(icastx, Type::FloatTy, + name("fx")); + Value *fy = m_builder.CreateSIToFP(icasty, Type::FloatTy, + name("fy")); + Value *fz = m_builder.CreateSIToFP(icastz, Type::FloatTy, + name("fz")); + Value *fw = m_builder.CreateSIToFP(icastw, Type::FloatTy, + name("fw")); + return vectorFromVals(fx, fy, fz, fw); +} + +void Instructions::end() +{ + m_builder.CreateRetVoid(); +} + +void Instructions::cal(int label, llvm::Value *input) +{ + std::vector params; + params.push_back(input); + llvm::Function *func = findFunction(label); + + m_builder.CreateCall(func, params.begin(), params.end()); +} + +llvm::Function * Instructions::declareFunc(int label) +{ + PointerType *vecPtr = PointerType::getUnqual(m_floatVecType); + std::vector args; + args.push_back(vecPtr); + args.push_back(vecPtr); + args.push_back(vecPtr); + args.push_back(vecPtr); + ParamAttrsList *params = 0; + FunctionType *funcType = FunctionType::get( + /*Result=*/Type::VoidTy, + /*Params=*/args, + /*isVarArg=*/false); + std::string name = createFuncName(label); + Function *func = new Function( + /*Type=*/funcType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/name.c_str(), m_mod); + func->setCallingConv(CallingConv::C); + func->setParamAttrs(params); + return func; +} + +void Instructions::bgnSub(unsigned label) +{ + llvm::Function *func = findFunction(label); + + Function::arg_iterator args = func->arg_begin(); + Value *ptr_INPUT = args++; + ptr_INPUT->setName("INPUT"); + m_storage->pushArguments(ptr_INPUT); + + llvm::BasicBlock *entry = new BasicBlock("entry", func, 0); + + m_func = func; + m_builder.SetInsertPoint(entry); +} + +void Instructions::endSub() +{ + m_func = 0; + m_builder.SetInsertPoint(0); +} + +llvm::Function * Instructions::findFunction(int label) +{ + llvm::Function *func = m_functions[label]; + if (!func) { + func = declareFunc(label); + m_functions[label] = func; + } + return func; +} + +llvm::Value * Instructions::constVector(float x, float y, float z, float w) +{ + std::vector vec(4); + vec[0] = ConstantFP::get(Type::FloatTy, APFloat(x)); + vec[1] = ConstantFP::get(Type::FloatTy, APFloat(y)); + vec[2] = ConstantFP::get(Type::FloatTy, APFloat(z)); + vec[3] = ConstantFP::get(Type::FloatTy, APFloat(w)); + return ConstantVector::get(m_floatVecType, vec); +} + + +std::vector Instructions::extractVector(llvm::Value *vec) +{ + std::vector elems(4); + elems[0] = m_builder.CreateExtractElement(vec, m_storage->constantInt(0), + name("x")); + elems[1] = m_builder.CreateExtractElement(vec, m_storage->constantInt(1), + name("y")); + elems[2] = m_builder.CreateExtractElement(vec, m_storage->constantInt(2), + name("z")); + elems[3] = m_builder.CreateExtractElement(vec, m_storage->constantInt(3), + name("w")); + return elems; +} + +llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) +{ + llvm::Function *func = m_mod->getFunction("cmp"); + assert(func); + + std::vector params; + params.push_back(in1); + params.push_back(in2); + params.push_back(in3); + CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), name("cmpres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::cos(llvm::Value *in) +{ +#if 0 + llvm::Function *func = m_mod->getFunction("vcos"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("cosres")); + call->setTailCall(false); + return call; +#else + std::vector elems = extractVector(in); + Function *func = m_mod->getFunction("cosf"); + assert(func); + CallInst *cos = m_builder.CreateCall(func, elems[0], name("cosres")); + cos->setCallingConv(CallingConv::C); + cos->setTailCall(true); + return vectorFromVals(cos, cos, cos, cos); +#endif +} + +llvm::Value * Instructions::scs(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("scs"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("scsres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::kilp(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("kilp"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("kilpres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::sin(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("vsin"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("sinres")); + call->setTailCall(false); + return call; +} +#endif //MESA_LLVM + + diff --git a/src/gallium/aux/llvm/instructions.h b/src/gallium/aux/llvm/instructions.h new file mode 100644 index 0000000000..9ebc17dd8e --- /dev/null +++ b/src/gallium/aux/llvm/instructions.h @@ -0,0 +1,152 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef INSTRUCTIONS_H +#define INSTRUCTIONS_H + +#include +#include +#include +#include + +#include +#include + +namespace llvm { + class VectorType; + class Function; +} + +class Storage; + +class Instructions +{ +public: + Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, + Storage *storage); + + llvm::BasicBlock *currentBlock() const; + + llvm::Value *abs(llvm::Value *in1); + llvm::Value *arl(llvm::Value *in1); + llvm::Value *add(llvm::Value *in1, llvm::Value *in2); + void beginLoop(); + void bgnSub(unsigned); + void brk(); + void cal(int label, llvm::Value *input); + llvm::Value *cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); + llvm::Value *cos(llvm::Value *in); + llvm::Value *cross(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dp3(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dp4(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dph(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dst(llvm::Value *in1, llvm::Value *in2); + void elseop(); + void endif(); + void endLoop(); + void end(); + void endSub(); + llvm::Value *ex2(llvm::Value *in); + llvm::Value *floor(llvm::Value *in); + llvm::Value *frc(llvm::Value *in); + void ifop(llvm::Value *in); + llvm::Value *kilp(llvm::Value *in); + llvm::Value *lerp(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3); + llvm::Value *lit(llvm::Value *in); + llvm::Value *lg2(llvm::Value *in); + llvm::Value *madd(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in2); + llvm::Value *min(llvm::Value *in1, llvm::Value *in2); + llvm::Value *max(llvm::Value *in1, llvm::Value *in2); + llvm::Value *mul(llvm::Value *in1, llvm::Value *in2); + llvm::Value *pow(llvm::Value *in1, llvm::Value *in2); + llvm::Value *rcp(llvm::Value *in); + llvm::Value *rsq(llvm::Value *in); + llvm::Value *scs(llvm::Value *in); + llvm::Value *sge(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sgt(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sin(llvm::Value *in); + llvm::Value *slt(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sub(llvm::Value *in1, llvm::Value *in2); + llvm::Value *trunc(llvm::Value *in); + + void printVector(llvm::Value *val); +private: + const char *name(const char *prefix); + + llvm::Value *callFAbs(llvm::Value *val); + llvm::Value *callFloor(llvm::Value *val); + llvm::Value *callFSqrt(llvm::Value *val); + llvm::Value *callFLog(llvm::Value *val); + llvm::Value *callPow(llvm::Value *val1, llvm::Value *val2); + + llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w=0); + + llvm::Value *constVector(float x, float y, float z, float w); + + llvm::Function *declarePrintf(); + llvm::Function *declareFunc(int label); + + llvm::Function *findFunction(int label); + + std::vector extractVector(llvm::Value *vec); +private: + llvm::Module *m_mod; + llvm::Function *m_func; + char m_name[32]; + llvm::LLVMFoldingBuilder m_builder; + int m_idx; + + llvm::VectorType *m_floatVecType; + + llvm::Function *m_llvmFSqrt; + llvm::Function *m_llvmFAbs; + llvm::Function *m_llvmPow; + llvm::Function *m_llvmFloor; + llvm::Function *m_llvmFlog; + llvm::Function *m_llvmLit; + + llvm::Constant *m_fmtPtr; + + std::stack m_ifStack; + struct Loop { + llvm::BasicBlock *begin; + llvm::BasicBlock *end; + }; + std::stack m_loopStack; + std::map m_functions; + Storage *m_storage; +}; + +#endif diff --git a/src/gallium/aux/llvm/instructionssoa.cpp b/src/gallium/aux/llvm/instructionssoa.cpp new file mode 100644 index 0000000000..a4d5046637 --- /dev/null +++ b/src/gallium/aux/llvm/instructionssoa.cpp @@ -0,0 +1,121 @@ +#include "instructionssoa.h" + +#include "storagesoa.h" + +#include + +using namespace llvm; + +InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, + llvm::BasicBlock *block, StorageSoa *storage) + : m_builder(block), + m_storage(storage), + m_idx(0) +{ +} + +const char * InstructionsSoa::name(const char *prefix) const +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + Constant *constVector = Constant::getNullValue(vectorType); + Value *res = m_builder.CreateInsertElement(constVector, x, + m_storage->constantInt(0), + name("vecx")); + res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), + name("vecxy")); + res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), + name("vecxyz")); + if (w) + res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), + name("vecxyzw")); + return res; +} + +std::vector InstructionsSoa::arl(const std::vector in) +{ + std::vector res(4); + + //Extract x's + llvm::Value *x1 = m_builder.CreateExtractElement(in[0], + m_storage->constantInt(0), + name("extractX")); + //cast it to an unsigned int + x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast")); + + res[0] = x1;//vectorFromVals(x1, x2, x3, x4); + //only x is valid. the others shouldn't be necessary + /* + res[1] = Constant::getNullValue(m_floatVecType); + res[2] = Constant::getNullValue(m_floatVecType); + res[3] = Constant::getNullValue(m_floatVecType); + */ + + return res; +} + + +std::vector InstructionsSoa::add(const std::vector in1, + const std::vector in2) +{ + std::vector res(4); + + res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx")); + res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy")); + res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz")); + res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw")); + + return res; +} + +std::vector InstructionsSoa::mul(const std::vector in1, + const std::vector in2) +{ + std::vector res(4); + + res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx")); + res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly")); + res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz")); + res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw")); + + return res; +} + +void InstructionsSoa::end() +{ + m_builder.CreateRetVoid(); +} + +std::vector InstructionsSoa::madd(const std::vector in1, + const std::vector in2, + const std::vector in3) +{ + std::vector res = mul(in1, in2); + return add(res, in3); +} + +std::vector InstructionsSoa::extractVector(llvm::Value *vector) +{ + std::vector res(4); + res[0] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(0), + name("extract1X")); + res[1] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(1), + name("extract2X")); + res[2] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(2), + name("extract3X")); + res[3] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(3), + name("extract4X")); + + return res; +} diff --git a/src/gallium/aux/llvm/instructionssoa.h b/src/gallium/aux/llvm/instructionssoa.h new file mode 100644 index 0000000000..4169dcbb2e --- /dev/null +++ b/src/gallium/aux/llvm/instructionssoa.h @@ -0,0 +1,74 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INSTRUCTIONSSOA_H +#define INSTRUCTIONSSOA_H + +#include + +#include + +namespace llvm { + class Module; + class Function; + class BasicBlock; + class Value; +} +class StorageSoa; + +class InstructionsSoa +{ +public: + InstructionsSoa(llvm::Module *mod, llvm::Function *func, + llvm::BasicBlock *block, StorageSoa *storage); + + std::vector arl(const std::vector in); + + std::vector add(const std::vector in1, + const std::vector in2); + std::vector madd(const std::vector in1, + const std::vector in2, + const std::vector in3); + std::vector mul(const std::vector in1, + const std::vector in2); + void end(); + + std::vector extractVector(llvm::Value *vector); +private: + const char * name(const char *prefix) const; + llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w); +private: + llvm::LLVMFoldingBuilder m_builder; + StorageSoa *m_storage; +private: + mutable int m_idx; + mutable char m_name[32]; +}; + + +#endif diff --git a/src/gallium/aux/llvm/llvm_builtins.c b/src/gallium/aux/llvm/llvm_builtins.c new file mode 100644 index 0000000000..4f98d754ba --- /dev/null +++ b/src/gallium/aux/llvm/llvm_builtins.c @@ -0,0 +1,115 @@ +/*clang --emit-llvm llvm_builtins.c |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=gallivm_builtins.cpp -f -for=shader -funcname=createGallivmBuiltins*/ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +typedef __attribute__(( ocu_vector_type(4) )) float float4; + +extern float powf(float a, float b); + +inline float approx(float a, float b) +{ + if (b < -128.0f) b = -128.0f; + if (b > 128.0f) b = 128.0f; + if (a < 0) a = 0; + return powf(a, b); +} + +inline float4 lit(float4 tmp) +{ + float4 result; + result.x = 1.0; + result.w = 1.0; + if (tmp.x > 0) { + result.y = tmp.x; + result.z = approx(tmp.y, tmp.w); + } else { + result.y = 0; + result.z = 0; + } + return result; +} + +inline float4 cmp(float4 tmp0, float4 tmp1, float4 tmp2) +{ + float4 result; + + result.x = (tmp0.x < 0.0) ? tmp1.x : tmp2.x; + result.y = (tmp0.y < 0.0) ? tmp1.y : tmp2.y; + result.z = (tmp0.z < 0.0) ? tmp1.z : tmp2.z; + result.w = (tmp0.w < 0.0) ? tmp1.w : tmp2.w; + + return result; +} + +extern float cosf(float val); +extern float sinf(float val); + +inline float4 vcos(float4 val) +{ + float4 result; + printf("VEC IN is %f %f %f %f\n", val.x, val.y, val.z, val.w); + result.x = cosf(val.x); + result.y = cosf(val.x); + result.z = cosf(val.x); + result.w = cosf(val.x); + printf("VEC OUT is %f %f %f %f\n", result.x, result.y, result.z, result.w); + return result; +} + +inline float4 scs(float4 val) +{ + float4 result; + float tmp = val.x; + result.x = cosf(tmp); + result.y = sinf(tmp); + return result; +} + + +inline float4 vsin(float4 val) +{ + float4 result; + float tmp = val.x; + float res = sinf(tmp); + result.x = res; + result.y = res; + result.z = res; + result.w = res; + return result; +} + +inline int kilp(float4 val) +{ + if (val.x < 0 || val.y < 0 || val.z < 0 || val.w < 0) + return 1; + else + return 0; +} diff --git a/src/gallium/aux/llvm/loweringpass.cpp b/src/gallium/aux/llvm/loweringpass.cpp new file mode 100644 index 0000000000..556dbec366 --- /dev/null +++ b/src/gallium/aux/llvm/loweringpass.cpp @@ -0,0 +1,17 @@ +#include "loweringpass.h" + +using namespace llvm; + +char LoweringPass::ID = 0; +RegisterPass X("lowering", "Lowering Pass"); + +LoweringPass::LoweringPass() + : ModulePass((intptr_t)&ID) +{ +} + +bool LoweringPass::runOnModule(Module &m) +{ + llvm::cerr << "Hello: " << m.getModuleIdentifier() << "\n"; + return false; +} diff --git a/src/gallium/aux/llvm/loweringpass.h b/src/gallium/aux/llvm/loweringpass.h new file mode 100644 index 0000000000..f62dcf6ba7 --- /dev/null +++ b/src/gallium/aux/llvm/loweringpass.h @@ -0,0 +1,15 @@ +#ifndef LOWERINGPASS_H +#define LOWERINGPASS_H + +#include "llvm/Pass.h" +#include "llvm/Module.h" + +struct LoweringPass : public llvm::ModulePass +{ + static char ID; + LoweringPass(); + + virtual bool runOnModule(llvm::Module &m); +}; + +#endif diff --git a/src/gallium/aux/llvm/storage.cpp b/src/gallium/aux/llvm/storage.cpp new file mode 100644 index 0000000000..c4326de8c5 --- /dev/null +++ b/src/gallium/aux/llvm/storage.cpp @@ -0,0 +1,364 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "storage.h" + +#include "gallivm_p.h" + +#include "pipe/p_shader_tokens.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace llvm; + +Storage::Storage(llvm::BasicBlock *block, llvm::Value *input) + : m_block(block), + m_INPUT(input), + m_addrs(32), + m_idx(0) +{ + m_floatVecType = VectorType::get(Type::FloatTy, 4); + m_intVecType = VectorType::get(IntegerType::get(32), 4); + + m_undefFloatVec = UndefValue::get(m_floatVecType); + m_undefIntVec = UndefValue::get(m_intVecType); + m_extSwizzleVec = 0; + + m_numConsts = 0; +} + +//can only build vectors with all members in the [0, 9] range +llvm::Constant *Storage::shuffleMask(int vec) +{ + if (!m_extSwizzleVec) { + std::vector elems; + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); + m_extSwizzleVec = ConstantVector::get(m_floatVecType, elems); + } + + if (m_intVecs.find(vec) != m_intVecs.end()) { + return m_intVecs[vec]; + } + int origVec = vec; + Constant* const_vec = 0; + if (origVec == 0) { + const_vec = Constant::getNullValue(m_intVecType); + } else { + int x = gallivm_x_swizzle(vec); + int y = gallivm_y_swizzle(vec); + int z = gallivm_z_swizzle(vec); + int w = gallivm_w_swizzle(vec); + std::vector elems; + elems.push_back(constantInt(x)); + elems.push_back(constantInt(y)); + elems.push_back(constantInt(z)); + elems.push_back(constantInt(w)); + const_vec = ConstantVector::get(m_intVecType, elems); + } + + m_intVecs[origVec] = const_vec; + return const_vec; +} + +llvm::ConstantInt *Storage::constantInt(int idx) +{ + if (m_constInts.find(idx) != m_constInts.end()) { + return m_constInts[idx]; + } + ConstantInt *const_int = ConstantInt::get(APInt(32, idx)); + m_constInts[idx] = const_int; + return const_int; +} + +llvm::Value *Storage::inputElement(int idx, llvm::Value *indIdx) +{ + Value *val = element(InputsArg, idx, indIdx); + LoadInst *load = new LoadInst(val, name("input"), false, m_block); + load->setAlignment(8); + + return load; +} + +llvm::Value *Storage::constElement(int idx, llvm::Value *indIdx) +{ + m_numConsts = ((idx + 1) > m_numConsts) ? (idx + 1) : m_numConsts; + + Value *elem = element(ConstsArg, idx, indIdx); + LoadInst *load = new LoadInst(elem, name("const"), false, m_block); + load->setAlignment(8); + return load; +} + +llvm::Value *Storage::shuffleVector(llvm::Value *vec, int shuffle) +{ + Constant *mask = shuffleMask(shuffle); + ShuffleVectorInst *res = + new ShuffleVectorInst(vec, m_extSwizzleVec, mask, + name("shuffle"), m_block); + return res; +} + + +llvm::Value *Storage::tempElement(int idx, llvm::Value *indIdx) +{ + Value *elem = element(TempsArg, idx, indIdx); + + LoadInst *load = new LoadInst(elem, name("temp"), false, m_block); + load->setAlignment(8); + + return load; +} + +void Storage::setTempElement(int idx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = 0; + if (m_tempWriteMap[idx]) + templ = tempElement(idx); + val = maskWrite(val, mask, templ); + } + Value *elem = element(TempsArg, idx); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); + m_tempWriteMap[idx] = true; +} + +void Storage::setOutputElement(int dstIdx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = 0; + if (m_destWriteMap[dstIdx]) + templ = outputElement(dstIdx); + val = maskWrite(val, mask, templ); + } + + Value *elem = element(DestsArg, dstIdx); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); + m_destWriteMap[dstIdx] = true; +} + +llvm::Value *Storage::maskWrite(llvm::Value *src, int mask, llvm::Value *templ) +{ + llvm::Value *dst = templ; + if (!dst) + dst = Constant::getNullValue(m_floatVecType); + if ((mask & TGSI_WRITEMASK_X)) { + llvm::Value *x = new ExtractElementInst(src, unsigned(0), + name("x"), m_block); + dst = new InsertElementInst(dst, x, unsigned(0), + name("dstx"), m_block); + } + if ((mask & TGSI_WRITEMASK_Y)) { + llvm::Value *y = new ExtractElementInst(src, unsigned(1), + name("y"), m_block); + dst = new InsertElementInst(dst, y, unsigned(1), + name("dsty"), m_block); + } + if ((mask & TGSI_WRITEMASK_Z)) { + llvm::Value *z = new ExtractElementInst(src, unsigned(2), + name("z"), m_block); + dst = new InsertElementInst(dst, z, unsigned(2), + name("dstz"), m_block); + } + if ((mask & TGSI_WRITEMASK_W)) { + llvm::Value *w = new ExtractElementInst(src, unsigned(3), + name("w"), m_block); + dst = new InsertElementInst(dst, w, unsigned(3), + name("dstw"), m_block); + } + return dst; +} + +const char * Storage::name(const char *prefix) +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +int Storage::numConsts() const +{ + return m_numConsts; +} + +llvm::Value * Storage::addrElement(int idx) const +{ + Value *ret = m_addrs[idx]; + if (!ret) + return m_undefFloatVec; + return ret; +} + +void Storage::setAddrElement(int idx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = m_addrs[idx]; + val = maskWrite(val, mask, templ); + } + m_addrs[idx] = val; +} + +llvm::Value * Storage::extractIndex(llvm::Value *vec) +{ + llvm::Value *x = new ExtractElementInst(vec, unsigned(0), + name("x"), m_block); + return new FPToSIInst(x, IntegerType::get(32), name("intidx"), m_block); +} + +void Storage::setCurrentBlock(llvm::BasicBlock *block) +{ + m_block = block; +} + +llvm::Value * Storage::outputElement(int idx, llvm::Value *indIdx) +{ + Value *elem = element(DestsArg, idx, indIdx); + LoadInst *load = new LoadInst(elem, name("output"), false, m_block); + load->setAlignment(8); + + return load; +} + +llvm::Value * Storage::inputPtr() const +{ + return m_INPUT; +} + +void Storage::pushArguments(llvm::Value *input) +{ + m_argStack.push(m_INPUT); + + m_INPUT = input; +} + +void Storage::popArguments() +{ + m_INPUT = m_argStack.top(); + m_argStack.pop(); +} + +void Storage::pushTemps() +{ + m_extSwizzleVec = 0; +} + +void Storage::popTemps() +{ +} + +llvm::Value * Storage::immediateElement(int idx) +{ + return m_immediates[idx]; +} + +void Storage::addImmediate(float *val) +{ + std::vector vec(4); + vec[0] = ConstantFP::get(Type::FloatTy, APFloat(val[0])); + vec[1] = ConstantFP::get(Type::FloatTy, APFloat(val[1])); + vec[2] = ConstantFP::get(Type::FloatTy, APFloat(val[2])); + vec[3] = ConstantFP::get(Type::FloatTy, APFloat(val[3])); + m_immediates.push_back(ConstantVector::get(m_floatVecType, vec)); +} + + +llvm::Value * Storage::elemPtr(Args arg) +{ + std::vector indices; + indices.push_back(constantInt(0)); + indices.push_back(constantInt(static_cast(arg))); + GetElementPtrInst *getElem = new GetElementPtrInst(m_INPUT, + indices.begin(), + indices.end(), + name("input_ptr"), + m_block); + return new LoadInst(getElem, name("input_field"), false, m_block); +} + +llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, + llvm::Value *indIdx ) +{ + GetElementPtrInst *getElem = 0; + + if (indIdx) { + getElem = new GetElementPtrInst(ptr, + BinaryOperator::create(Instruction::Add, + indIdx, + constantInt(idx), + name("add"), + m_block), + name("field"), + m_block); + } else { + getElem = new GetElementPtrInst(ptr, + constantInt(idx), + name("field"), + m_block); + } + return getElem; +} + +llvm::Value * Storage::element(Args arg, int idx, llvm::Value *indIdx ) +{ + Value *val = elemPtr(arg); + return elemIdx(val, idx, indIdx); +} + +void Storage::setKilElement(llvm::Value *val) +{ + std::vector indices; + indices.push_back(constantInt(0)); + indices.push_back(constantInt(static_cast(KilArg))); + GetElementPtrInst *elem = new GetElementPtrInst(m_INPUT, + indices.begin(), + indices.end(), + name("kil_ptr"), + m_block); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); +} + +#endif //MESA_LLVM + + diff --git a/src/gallium/aux/llvm/storage.h b/src/gallium/aux/llvm/storage.h new file mode 100644 index 0000000000..8574f7554e --- /dev/null +++ b/src/gallium/aux/llvm/storage.h @@ -0,0 +1,133 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef STORAGE_H +#define STORAGE_H + +#include +#include +#include +#include + +namespace llvm { + class BasicBlock; + class Constant; + class ConstantInt; + class LoadInst; + class Value; + class VectorType; +} + +class Storage +{ +public: + Storage(llvm::BasicBlock *block, + llvm::Value *input); + + llvm::Value *inputPtr() const; + + void setCurrentBlock(llvm::BasicBlock *block); + + llvm::ConstantInt *constantInt(int); + llvm::Constant *shuffleMask(int vec); + llvm::Value *inputElement(int idx, llvm::Value *indIdx =0); + llvm::Value *constElement(int idx, llvm::Value *indIdx =0); + llvm::Value *outputElement(int idx, llvm::Value *indIdx =0); + llvm::Value *tempElement(int idx, llvm::Value *indIdx =0); + llvm::Value *immediateElement(int idx); + + void setOutputElement(int dstIdx, llvm::Value *val, int mask); + void setTempElement(int idx, llvm::Value *val, int mask); + + llvm::Value *addrElement(int idx) const; + void setAddrElement(int idx, llvm::Value *val, int mask); + + void setKilElement(llvm::Value *val); + + llvm::Value *shuffleVector(llvm::Value *vec, int shuffle); + + llvm::Value *extractIndex(llvm::Value *vec); + + int numConsts() const; + + void pushArguments(llvm::Value *input); + void popArguments(); + void pushTemps(); + void popTemps(); + + void addImmediate(float *val); + +private: + llvm::Value *maskWrite(llvm::Value *src, int mask, llvm::Value *templ); + const char *name(const char *prefix); + + enum Args { + DestsArg = 0, + InputsArg = 1, + TempsArg = 2, + ConstsArg = 3, + KilArg = 4 + }; + llvm::Value *elemPtr(Args arg); + llvm::Value *elemIdx(llvm::Value *ptr, int idx, + llvm::Value *indIdx = 0); + llvm::Value *element(Args arg, int idx, llvm::Value *indIdx = 0); + +private: + llvm::BasicBlock *m_block; + llvm::Value *m_INPUT; + + std::map m_constInts; + std::map m_intVecs; + std::vector m_addrs; + std::vector m_immediates; + + llvm::VectorType *m_floatVecType; + llvm::VectorType *m_intVecType; + + char m_name[32]; + int m_idx; + + int m_numConsts; + + std::map m_destWriteMap; + std::map m_tempWriteMap; + + llvm::Value *m_undefFloatVec; + llvm::Value *m_undefIntVec; + llvm::Value *m_extSwizzleVec; + + std::stack m_argStack; + std::stack > m_tempStack; +}; + +#endif diff --git a/src/gallium/aux/llvm/storagesoa.cpp b/src/gallium/aux/llvm/storagesoa.cpp new file mode 100644 index 0000000000..ed0674a96f --- /dev/null +++ b/src/gallium/aux/llvm/storagesoa.cpp @@ -0,0 +1,389 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "storagesoa.h" + +#include "gallivm_p.h" + +#include "pipe/p_shader_tokens.h" +#include "pipe/p_debug.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace llvm; + + +StorageSoa::StorageSoa(llvm::BasicBlock *block, + llvm::Value *input, + llvm::Value *output, + llvm::Value *consts, + llvm::Value *temps) + : m_block(block), + m_input(input), + m_output(output), + m_consts(consts), + m_temps(temps), + m_immediates(0), + m_idx(0) +{ +} + +void StorageSoa::addImmediate(float *vec) +{ + std::vector vals(4); + vals[0] = vec[0]; + vals[1] = vec[1]; + vals[2] = vec[2]; + vals[3] = vec[3]; + m_immediatesToFlush.push_back(vals); +} + +void StorageSoa::declareImmediates() +{ + if (m_immediatesToFlush.empty()) + return; + + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + ArrayType *vectorChannels = ArrayType::get(vectorType, 4); + ArrayType *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size()); + + m_immediates = new GlobalVariable( + /*Type=*/arrayType, + /*isConstant=*/false, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name("immediates"), + currentModule()); + + std::vector arrayVals; + for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) { + std::vector vec = m_immediatesToFlush[i]; + std::vector vals(4); + std::vector channelArray; + + vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0]; + llvm::Constant *xChannel = createConstGlobalVector(vals); + + vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1]; + llvm::Constant *yChannel = createConstGlobalVector(vals); + + vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2]; + llvm::Constant *zChannel = createConstGlobalVector(vals); + + vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3]; + llvm::Constant *wChannel = createConstGlobalVector(vals); + channelArray.push_back(xChannel); + channelArray.push_back(yChannel); + channelArray.push_back(zChannel); + channelArray.push_back(wChannel); + Constant *constChannels = ConstantArray::get(vectorChannels, + channelArray); + arrayVals.push_back(constChannels); + } + Constant *constArray = ConstantArray::get(arrayType, arrayVals); + m_immediates->setInitializer(constArray); + + m_immediatesToFlush.clear(); +} + +llvm::Value *StorageSoa::addrElement(int idx) const +{ + std::map::const_iterator itr = m_addresses.find(idx); + if (itr == m_addresses.end()) { + debug_printf("Trying to access invalid shader 'address'\n"); + return 0; + } + llvm::Value * res = (*itr).second; + + res = new LoadInst(res, name("addr"), false, m_block); + + return res; +} + +std::vector StorageSoa::inputElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_input, idx, 0); + res[1] = element(m_input, idx, 1); + res[2] = element(m_input, idx, 2); + res[3] = element(m_input, idx, 3); + + return res; +} + +std::vector StorageSoa::constElement(llvm::Value *idx) +{ + std::vector res(4); + llvm::Value *xChannel, *yChannel, *zChannel, *wChannel; + + xChannel = elementPointer(m_consts, idx, 0); + yChannel = elementPointer(m_consts, idx, 1); + zChannel = elementPointer(m_consts, idx, 2); + wChannel = elementPointer(m_consts, idx, 3); + + res[0] = alignedArrayLoad(xChannel); + res[1] = alignedArrayLoad(yChannel); + res[2] = alignedArrayLoad(zChannel); + res[3] = alignedArrayLoad(wChannel); + + return res; +} + +std::vector StorageSoa::outputElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_output, idx, 0); + res[1] = element(m_output, idx, 1); + res[2] = element(m_output, idx, 2); + res[3] = element(m_output, idx, 3); + + return res; +} + +std::vector StorageSoa::tempElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_temps, idx, 0); + res[1] = element(m_temps, idx, 1); + res[2] = element(m_temps, idx, 2); + res[3] = element(m_temps, idx, 3); + + return res; +} + +std::vector StorageSoa::immediateElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_immediates, idx, 0); + res[1] = element(m_immediates, idx, 1); + res[2] = element(m_immediates, idx, 2); + res[3] = element(m_immediates, idx, 3); + + return res; +} + +llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, llvm::Value *index, + int channel) const +{ + std::vector indices; + if (m_immediates == ptr) + indices.push_back(constantInt(0)); + indices.push_back(index); + indices.push_back(constantInt(channel)); + + GetElementPtrInst *getElem = new GetElementPtrInst(ptr, + indices.begin(), + indices.end(), + name("ptr"), + m_block); + return getElem; +} + +llvm::Value * StorageSoa::element(llvm::Value *ptr, llvm::Value *index, + int channel) const +{ + llvm::Value *res = elementPointer(ptr, index, channel); + LoadInst *load = new LoadInst(res, name("element"), false, m_block); + //load->setAlignment(8); + return load; +} + +const char * StorageSoa::name(const char *prefix) const +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::ConstantInt * StorageSoa::constantInt(int idx) const +{ + if (m_constInts.find(idx) != m_constInts.end()) { + return m_constInts[idx]; + } + ConstantInt *constInt = ConstantInt::get(APInt(32, idx)); + m_constInts[idx] = constInt; + return constInt; +} + +llvm::Value *StorageSoa::alignedArrayLoad(llvm::Value *val) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + PointerType *vectorPtr = PointerType::get(vectorType, 0); + + CastInst *cast = new BitCastInst(val, vectorPtr, name("toVector"), m_block); + LoadInst *load = new LoadInst(cast, name("alignLoad"), false, m_block); + load->setAlignment(8); + return load; +} + +llvm::Module * StorageSoa::currentModule() const +{ + if (!m_block || !m_block->getParent()) + return 0; + + return m_block->getParent()->getParent(); +} + +llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &vec) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + std::vector immValues; + ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0])); + ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1])); + ConstantFP *constz = ConstantFP::get(Type::FloatTy, APFloat(vec[2])); + ConstantFP *constw = ConstantFP::get(Type::FloatTy, APFloat(vec[3])); + immValues.push_back(constx); + immValues.push_back(consty); + immValues.push_back(constz); + immValues.push_back(constw); + Constant *constVector = ConstantVector::get(vectorType, immValues); + + return constVector; +} + +std::vector StorageSoa::load(Argument type, int idx, int swizzle, + llvm::Value *indIdx) +{ + std::vector val(4); + + //if we have an indirect index, always use that + // if not use the integer offset to create one + llvm::Value *realIndex = 0; + if (indIdx) + realIndex = indIdx; + else + realIndex = constantInt(idx); + debug_printf("XXXXXXXXX realIdx = %p, indIdx = %p\n", realIndex, indIdx); + + switch(type) { + case Input: + val = inputElement(realIndex); + break; + case Output: + val = outputElement(realIndex); + break; + case Temp: + val = tempElement(realIndex); + break; + case Const: + val = constElement(realIndex); + break; + case Immediate: + val = immediateElement(realIndex); + break; + case Address: + debug_printf("Address not handled in the load phase!\n"); + assert(0); + break; + } + if (!gallivm_is_swizzle(swizzle)) + return val; + + std::vector res(4); + + res[0] = val[gallivm_x_swizzle(swizzle)]; + res[1] = val[gallivm_y_swizzle(swizzle)]; + res[2] = val[gallivm_z_swizzle(swizzle)]; + res[3] = val[gallivm_w_swizzle(swizzle)]; + return res; +} + +void StorageSoa::store(Argument type, int idx, const std::vector &val, + int mask) +{ + llvm::Value *out = 0; + switch(type) { + case Output: + out = m_output; + break; + case Temp: + out = m_temps; + break; + case Input: + out = m_input; + break; + case Address: { + llvm::Value *addr = m_addresses[idx]; + if (!addr) { + addAddress(idx); + addr = m_addresses[idx]; + assert(addr); + } + new StoreInst(val[0], addr, false, m_block); + return; + break; + } + default: + debug_printf("Can't save output of this type: %d !\n", type); + assert(0); + break; + } + llvm::Value *realIndex = constantInt(idx); + if ((mask & TGSI_WRITEMASK_X)) { + llvm::Value *xChannel = elementPointer(out, realIndex, 0); + new StoreInst(val[0], xChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_Y)) { + llvm::Value *yChannel = elementPointer(out, realIndex, 1); + new StoreInst(val[1], yChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_Z)) { + llvm::Value *zChannel = elementPointer(out, realIndex, 2); + new StoreInst(val[2], zChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_W)) { + llvm::Value *wChannel = elementPointer(out, realIndex, 3); + new StoreInst(val[3], wChannel, false, m_block); + } +} + +void StorageSoa::addAddress(int idx) +{ + GlobalVariable *val = new GlobalVariable( + /*Type=*/IntegerType::get(32), + /*isConstant=*/false, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name("address"), + currentModule()); + val->setInitializer(Constant::getNullValue(IntegerType::get(32))); + + debug_printf("adding to %d\n", idx); + m_addresses[idx] = val; +} diff --git a/src/gallium/aux/llvm/storagesoa.h b/src/gallium/aux/llvm/storagesoa.h new file mode 100644 index 0000000000..6443351f27 --- /dev/null +++ b/src/gallium/aux/llvm/storagesoa.h @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STORAGESOA_H +#define STORAGESOA_H + +#include +#include +#include + +namespace llvm { + class BasicBlock; + class Constant; + class ConstantInt; + class GlobalVariable; + class LoadInst; + class Value; + class VectorType; + class Module; +} + +class StorageSoa +{ +public: + enum Argument { + Input, + Output, + Temp, + Const, + Immediate, + Address + }; +public: + StorageSoa(llvm::BasicBlock *block, + llvm::Value *input, + llvm::Value *output, + llvm::Value *consts, + llvm::Value *temps); + + + std::vector load(Argument type, int idx, int swizzle, + llvm::Value *indIdx =0); + void store(Argument type, int idx, const std::vector &val, + int mask); + + void addImmediate(float *vec); + void declareImmediates(); + + void addAddress(int idx); + + llvm::Value * addrElement(int idx) const; + + llvm::ConstantInt *constantInt(int) const; +private: + llvm::Value *elementPointer(llvm::Value *ptr, llvm::Value *indIdx, + int channel) const; + llvm::Value *element(llvm::Value *ptr, llvm::Value *idx, + int channel) const; + const char *name(const char *prefix) const; + llvm::Value *alignedArrayLoad(llvm::Value *val); + llvm::Module *currentModule() const; + llvm::Constant *createConstGlobalVector(const std::vector &vec); + + std::vector inputElement(llvm::Value *indIdx); + std::vector constElement(llvm::Value *indIdx); + std::vector outputElement(llvm::Value *indIdx); + std::vector tempElement(llvm::Value *indIdx); + std::vector immediateElement(llvm::Value *indIdx); +private: + llvm::BasicBlock *m_block; + + llvm::Value *m_input; + llvm::Value *m_output; + llvm::Value *m_consts; + llvm::Value *m_temps; + llvm::GlobalVariable *m_immediates; + + std::map m_addresses; + + std::vector > m_immediatesToFlush; + + mutable std::map m_constInts; + mutable char m_name[32]; + mutable int m_idx; +}; + +#endif diff --git a/src/gallium/aux/llvm/tgsitollvm.cpp b/src/gallium/aux/llvm/tgsitollvm.cpp new file mode 100644 index 0000000000..0de595e678 --- /dev/null +++ b/src/gallium/aux/llvm/tgsitollvm.cpp @@ -0,0 +1,1221 @@ +#include "tgsitollvm.h" + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "storage.h" +#include "instructions.h" +#include "storagesoa.h" +#include "instructionssoa.h" + +#include "pipe/p_shader_tokens.h" + +#include "pipe/tgsi/util/tgsi_parse.h" +#include "pipe/tgsi/exec/tgsi_exec.h" +#include "pipe/tgsi/util/tgsi_util.h" +#include "pipe/tgsi/util/tgsi_build.h" +#include "pipe/tgsi/util/tgsi_dump.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +using namespace llvm; + +static inline FunctionType *vertexShaderFunctionType() +{ + //Function takes three arguments, + // the calling code has to make sure the types it will + // pass are castable to the following: + // [4 x <4 x float>] inputs, + // [4 x <4 x float>] output, + // [4 x [4 x float]] consts, + // [4 x <4 x float>] temps + + std::vector funcArgs; + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + ArrayType *vectorArray = ArrayType::get(vectorType, 4); + PointerType *vectorArrayPtr = PointerType::get(vectorArray, 0); + + ArrayType *floatArray = ArrayType::get(Type::FloatTy, 4); + ArrayType *constsArray = ArrayType::get(floatArray, 4); + PointerType *constsArrayPtr = PointerType::get(constsArray, 0); + + funcArgs.push_back(vectorArrayPtr);//inputs + funcArgs.push_back(vectorArrayPtr);//output + funcArgs.push_back(constsArrayPtr);//consts + funcArgs.push_back(vectorArrayPtr);//temps + + FunctionType *functionType = FunctionType::get( + /*Result=*/Type::VoidTy, + /*Params=*/funcArgs, + /*isVarArg=*/false); + + return functionType; +} + +static inline void +add_interpolator(struct gallivm_ir *ir, + struct gallivm_interpolate *interp) +{ + ir->interpolators[ir->num_interp] = *interp; + ++ir->num_interp; +} + +static void +translate_declaration(struct gallivm_ir *prog, + llvm::Module *module, + Storage *storage, + struct tgsi_full_declaration *decl, + struct tgsi_full_declaration *fd) +{ + if (decl->Declaration.File == TGSI_FILE_INPUT) { + unsigned first, last, mask; + uint interp_method; + + assert(decl->Declaration.Declare == TGSI_DECLARE_RANGE); + + first = decl->u.DeclarationRange.First; + last = decl->u.DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + /* Do not touch WPOS.xy */ + if (first == 0) { + mask &= ~TGSI_WRITEMASK_XY; + if (mask == TGSI_WRITEMASK_NONE) { + first++; + if (first > last) { + return; + } + } + } + + interp_method = decl->Interpolation.Interpolate; + + if (mask == TGSI_WRITEMASK_XYZW) { + unsigned i, j; + + for (i = first; i <= last; i++) { + for (j = 0; j < NUM_CHANNELS; j++) { + //interp( mach, i, j ); + struct gallivm_interpolate interp; + interp.type = interp_method; + interp.attrib = i; + interp.chan = j; + add_interpolator(prog, &interp); + } + } + } else { + unsigned i, j; + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + for( i = first; i <= last; i++ ) { + struct gallivm_interpolate interp; + interp.type = interp_method; + interp.attrib = i; + interp.chan = j; + add_interpolator(prog, &interp); + } + } + } + } + } +} + +static void +translate_declarationir(struct gallivm_ir *, + llvm::Module *, + StorageSoa *storage, + struct tgsi_full_declaration *decl, + struct tgsi_full_declaration *) +{ + if (decl->Declaration.File == TGSI_FILE_ADDRESS) { + int idx = decl->u.DeclarationRange.First; + storage->addAddress(idx); + } +} + +static void +translate_immediate(Storage *storage, + struct tgsi_full_immediate *imm) +{ + float vec[4]; + int i; + for (i = 0; i < imm->Immediate.Size - 1; ++i) { + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + vec[i] = imm->u.ImmediateFloat32[i].Float; + break; + default: + assert(0); + } + } + storage->addImmediate(vec); +} + + +static void +translate_immediateir(StorageSoa *storage, + struct tgsi_full_immediate *imm) +{ + float vec[4]; + int i; + for (i = 0; i < imm->Immediate.Size - 1; ++i) { + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + vec[i] = imm->u.ImmediateFloat32[i].Float; + break; + default: + assert(0); + } + } + storage->addImmediate(vec); +} + +static inline int +swizzleInt(struct tgsi_full_src_register *src) +{ + int swizzle = 0; + int start = 1000; + + for (int k = 0; k < 4; ++k) { + swizzle += tgsi_util_get_full_src_register_extswizzle(src, k) * start; + start /= 10; + } + return swizzle; +} + +static inline llvm::Value * +swizzleVector(llvm::Value *val, struct tgsi_full_src_register *src, + Storage *storage) +{ + int swizzle = swizzleInt(src); + + if (gallivm_is_swizzle(swizzle)) { + /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/ + val = storage->shuffleVector(val, swizzle); + } + return val; +} + +static void +translate_instruction(llvm::Module *module, + Storage *storage, + Instructions *instr, + struct tgsi_full_instruction *inst, + struct tgsi_full_instruction *fi, + unsigned instno) +{ + llvm::Value *inputs[4]; + inputs[0] = 0; + inputs[1] = 0; + inputs[2] = 0; + inputs[3] = 0; + + for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + llvm::Value *val = 0; + llvm::Value *indIdx = 0; + + if (src->SrcRegister.Indirect) { + indIdx = storage->addrElement(src->SrcRegisterInd.Index); + indIdx = storage->extractIndex(indIdx); + } + if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { + val = storage->constElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { + val = storage->inputElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { + val = storage->tempElement(src->SrcRegister.Index); + } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { + val = storage->outputElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { + val = storage->immediateElement(src->SrcRegister.Index); + } else { + fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); + return; + } + + inputs[i] = swizzleVector(val, src, storage); + } + + /*if (inputs[0]) + instr->printVector(inputs[0]); + if (inputs[1]) + instr->printVector(inputs[1]);*/ + llvm::Value *out = 0; + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: { + out = instr->arl(inputs[0]); + } + break; + case TGSI_OPCODE_MOV: { + out = inputs[0]; + } + break; + case TGSI_OPCODE_LIT: { + out = instr->lit(inputs[0]); + } + break; + case TGSI_OPCODE_RCP: { + out = instr->rcp(inputs[0]); + } + break; + case TGSI_OPCODE_RSQ: { + out = instr->rsq(inputs[0]); + } + break; + case TGSI_OPCODE_EXP: + break; + case TGSI_OPCODE_LOG: + break; + case TGSI_OPCODE_MUL: { + out = instr->mul(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_ADD: { + out = instr->add(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP3: { + out = instr->dp3(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP4: { + out = instr->dp4(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DST: { + out = instr->dst(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MIN: { + out = instr->min(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MAX: { + out = instr->max(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SLT: { + out = instr->slt(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SGE: { + out = instr->sge(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MAD: { + out = instr->madd(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SUB: { + out = instr->sub(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_LERP: { + out = instr->lerp(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_CND: + break; + case TGSI_OPCODE_CND0: + break; + case TGSI_OPCODE_DOT2ADD: + break; + case TGSI_OPCODE_INDEX: + break; + case TGSI_OPCODE_NEGATE: + break; + case TGSI_OPCODE_FRAC: { + out = instr->frc(inputs[0]); + } + break; + case TGSI_OPCODE_CLAMP: + break; + case TGSI_OPCODE_FLOOR: { + out = instr->floor(inputs[0]); + } + break; + case TGSI_OPCODE_ROUND: + break; + case TGSI_OPCODE_EXPBASE2: { + out = instr->ex2(inputs[0]); + } + break; + case TGSI_OPCODE_LOGBASE2: { + out = instr->lg2(inputs[0]); + } + break; + case TGSI_OPCODE_POWER: { + out = instr->pow(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_CROSSPRODUCT: { + out = instr->cross(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MULTIPLYMATRIX: + break; + case TGSI_OPCODE_ABS: { + out = instr->abs(inputs[0]); + } + break; + case TGSI_OPCODE_RCC: + break; + case TGSI_OPCODE_DPH: { + out = instr->dph(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_COS: { + out = instr->cos(inputs[0]); + } + break; + case TGSI_OPCODE_DDX: + break; + case TGSI_OPCODE_DDY: + break; + case TGSI_OPCODE_KILP: { + out = instr->kilp(inputs[0]); + storage->setKilElement(out); + return; + } + break; + case TGSI_OPCODE_PK2H: + break; + case TGSI_OPCODE_PK2US: + break; + case TGSI_OPCODE_PK4B: + break; + case TGSI_OPCODE_PK4UB: + break; + case TGSI_OPCODE_RFL: + break; + case TGSI_OPCODE_SEQ: + break; + case TGSI_OPCODE_SFL: + break; + case TGSI_OPCODE_SGT: { + out = instr->sgt(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SIN: { + out = instr->sin(inputs[0]); + } + break; + case TGSI_OPCODE_SLE: + break; + case TGSI_OPCODE_SNE: + break; + case TGSI_OPCODE_STR: + break; + case TGSI_OPCODE_TEX: + break; + case TGSI_OPCODE_TXD: + break; + case TGSI_OPCODE_UP2H: + break; + case TGSI_OPCODE_UP2US: + break; + case TGSI_OPCODE_UP4B: + break; + case TGSI_OPCODE_UP4UB: + break; + case TGSI_OPCODE_X2D: + break; + case TGSI_OPCODE_ARA: + break; + case TGSI_OPCODE_ARR: + break; + case TGSI_OPCODE_BRA: + break; + case TGSI_OPCODE_CAL: { + instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr()); + return; + } + break; + case TGSI_OPCODE_RET: { + instr->end(); + return; + } + break; + case TGSI_OPCODE_SSG: + break; + case TGSI_OPCODE_CMP: { + out = instr->cmp(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SCS: { + out = instr->scs(inputs[0]); + } + break; + case TGSI_OPCODE_TXB: + break; + case TGSI_OPCODE_NRM: + break; + case TGSI_OPCODE_DIV: + break; + case TGSI_OPCODE_DP2: + break; + case TGSI_OPCODE_TXL: + break; + case TGSI_OPCODE_BRK: { + instr->brk(); + return; + } + break; + case TGSI_OPCODE_IF: { + instr->ifop(inputs[0]); + storage->setCurrentBlock(instr->currentBlock()); + return; //just update the state + } + break; + case TGSI_OPCODE_LOOP: + break; + case TGSI_OPCODE_REP: + break; + case TGSI_OPCODE_ELSE: { + instr->elseop(); + storage->setCurrentBlock(instr->currentBlock()); + return; //only state update + } + break; + case TGSI_OPCODE_ENDIF: { + instr->endif(); + storage->setCurrentBlock(instr->currentBlock()); + return; //just update the state + } + break; + case TGSI_OPCODE_ENDLOOP: + break; + case TGSI_OPCODE_ENDREP: + break; + case TGSI_OPCODE_PUSHA: + break; + case TGSI_OPCODE_POPA: + break; + case TGSI_OPCODE_CEIL: + break; + case TGSI_OPCODE_I2F: + break; + case TGSI_OPCODE_NOT: + break; + case TGSI_OPCODE_TRUNC: { + out = instr->trunc(inputs[0]); + } + break; + case TGSI_OPCODE_SHL: + break; + case TGSI_OPCODE_SHR: + break; + case TGSI_OPCODE_AND: + break; + case TGSI_OPCODE_OR: + break; + case TGSI_OPCODE_MOD: + break; + case TGSI_OPCODE_XOR: + break; + case TGSI_OPCODE_SAD: + break; + case TGSI_OPCODE_TXF: + break; + case TGSI_OPCODE_TXQ: + break; + case TGSI_OPCODE_CONT: + break; + case TGSI_OPCODE_EMIT: + break; + case TGSI_OPCODE_ENDPRIM: + break; + case TGSI_OPCODE_BGNLOOP2: { + instr->beginLoop(); + storage->setCurrentBlock(instr->currentBlock()); + return; + } + break; + case TGSI_OPCODE_BGNSUB: { + instr->bgnSub(instno); + storage->setCurrentBlock(instr->currentBlock()); + storage->pushTemps(); + return; + } + break; + case TGSI_OPCODE_ENDLOOP2: { + instr->endLoop(); + storage->setCurrentBlock(instr->currentBlock()); + return; + } + break; + case TGSI_OPCODE_ENDSUB: { + instr->endSub(); + storage->setCurrentBlock(instr->currentBlock()); + storage->popArguments(); + storage->popTemps(); + return; + } + break; + case TGSI_OPCODE_NOISE1: + break; + case TGSI_OPCODE_NOISE2: + break; + case TGSI_OPCODE_NOISE3: + break; + case TGSI_OPCODE_NOISE4: + break; + case TGSI_OPCODE_NOP: + break; + case TGSI_OPCODE_TEXBEM: + break; + case TGSI_OPCODE_TEXBEML: + break; + case TGSI_OPCODE_TEXREG2AR: + break; + case TGSI_OPCODE_TEXM3X2PAD: + break; + case TGSI_OPCODE_TEXM3X2TEX: + break; + case TGSI_OPCODE_TEXM3X3PAD: + break; + case TGSI_OPCODE_TEXM3X3TEX: + break; + case TGSI_OPCODE_TEXM3X3SPEC: + break; + case TGSI_OPCODE_TEXM3X3VSPEC: + break; + case TGSI_OPCODE_TEXREG2GB: + break; + case TGSI_OPCODE_TEXREG2RGB: + break; + case TGSI_OPCODE_TEXDP3TEX: + break; + case TGSI_OPCODE_TEXDP3: + break; + case TGSI_OPCODE_TEXM3X3: + break; + case TGSI_OPCODE_TEXM3X2DEPTH: + break; + case TGSI_OPCODE_TEXDEPTH: + break; + case TGSI_OPCODE_BEM: + break; + case TGSI_OPCODE_M4X3: + break; + case TGSI_OPCODE_M3X4: + break; + case TGSI_OPCODE_M3X3: + break; + case TGSI_OPCODE_M3X2: + break; + case TGSI_OPCODE_NRM4: + break; + case TGSI_OPCODE_CALLNZ: + break; + case TGSI_OPCODE_IFC: + break; + case TGSI_OPCODE_BREAKC: + break; + case TGSI_OPCODE_KIL: + break; + case TGSI_OPCODE_END: + instr->end(); + return; + break; + default: + fprintf(stderr, "ERROR: Unknown opcode %d\n", + inst->Instruction.Opcode); + assert(0); + break; + } + + if (!out) { + fprintf(stderr, "ERROR: unsupported opcode %d\n", + inst->Instruction.Opcode); + assert(!"Unsupported opcode"); + } + + /* # not sure if we need this */ + switch( inst->Instruction.Saturate ) { + case TGSI_SAT_NONE: + break; + case TGSI_SAT_ZERO_ONE: + /*TXT( "_SAT" );*/ + break; + case TGSI_SAT_MINUS_PLUS_ONE: + /*TXT( "_SAT[-1,1]" );*/ + break; + default: + assert( 0 ); + } + + /* store results */ + for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + + if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { + storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { + storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { + storage->setAddrElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else { + fprintf(stderr, "ERROR: unsupported LLVM destination!"); + assert(!"wrong destination"); + } + } +} + + +static void +translate_instructionir(llvm::Module *module, + StorageSoa *storage, + InstructionsSoa *instr, + struct tgsi_full_instruction *inst, + struct tgsi_full_instruction *fi, + unsigned instno) +{ + std::vector< std::vector > inputs(inst->Instruction.NumSrcRegs); + + for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + std::vector val; + llvm::Value *indIdx = 0; + int swizzle = swizzleInt(src); + + if (src->SrcRegister.Indirect) { + indIdx = storage->addrElement(src->SrcRegisterInd.Index); + } + if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { + val = storage->load(StorageSoa::Const, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { + val = storage->load(StorageSoa::Input, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { + val = storage->load(StorageSoa::Temp, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { + val = storage->load(StorageSoa::Output, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { + val = storage->load(StorageSoa::Immediate, + src->SrcRegister.Index, swizzle, indIdx); + } else { + fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); + return; + } + + inputs[i] = val; + } + + std::vector out(4); + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: { + out = instr->arl(inputs[0]); + } + break; + case TGSI_OPCODE_MOV: { + out = inputs[0]; + } + break; + case TGSI_OPCODE_LIT: { + } + break; + case TGSI_OPCODE_RCP: { + } + break; + case TGSI_OPCODE_RSQ: { + } + break; + case TGSI_OPCODE_EXP: + break; + case TGSI_OPCODE_LOG: + break; + case TGSI_OPCODE_MUL: { + out = instr->mul(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_ADD: { + out = instr->add(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP3: { + } + break; + case TGSI_OPCODE_DP4: { + } + break; + case TGSI_OPCODE_DST: { + } + break; + case TGSI_OPCODE_MIN: { + } + break; + case TGSI_OPCODE_MAX: { + } + break; + case TGSI_OPCODE_SLT: { + } + break; + case TGSI_OPCODE_SGE: { + } + break; + case TGSI_OPCODE_MAD: { + out = instr->madd(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SUB: { + } + break; + case TGSI_OPCODE_LERP: { + } + break; + case TGSI_OPCODE_CND: + break; + case TGSI_OPCODE_CND0: + break; + case TGSI_OPCODE_DOT2ADD: + break; + case TGSI_OPCODE_INDEX: + break; + case TGSI_OPCODE_NEGATE: + break; + case TGSI_OPCODE_FRAC: { + } + break; + case TGSI_OPCODE_CLAMP: + break; + case TGSI_OPCODE_FLOOR: { + } + break; + case TGSI_OPCODE_ROUND: + break; + case TGSI_OPCODE_EXPBASE2: { + } + break; + case TGSI_OPCODE_LOGBASE2: { + } + break; + case TGSI_OPCODE_POWER: { + } + break; + case TGSI_OPCODE_CROSSPRODUCT: { + } + break; + case TGSI_OPCODE_MULTIPLYMATRIX: + break; + case TGSI_OPCODE_ABS: { + } + break; + case TGSI_OPCODE_RCC: + break; + case TGSI_OPCODE_DPH: { + } + break; + case TGSI_OPCODE_COS: { + } + break; + case TGSI_OPCODE_DDX: + break; + case TGSI_OPCODE_DDY: + break; + case TGSI_OPCODE_KILP: { + } + break; + case TGSI_OPCODE_PK2H: + break; + case TGSI_OPCODE_PK2US: + break; + case TGSI_OPCODE_PK4B: + break; + case TGSI_OPCODE_PK4UB: + break; + case TGSI_OPCODE_RFL: + break; + case TGSI_OPCODE_SEQ: + break; + case TGSI_OPCODE_SFL: + break; + case TGSI_OPCODE_SGT: { + } + break; + case TGSI_OPCODE_SIN: { + } + break; + case TGSI_OPCODE_SLE: + break; + case TGSI_OPCODE_SNE: + break; + case TGSI_OPCODE_STR: + break; + case TGSI_OPCODE_TEX: + break; + case TGSI_OPCODE_TXD: + break; + case TGSI_OPCODE_UP2H: + break; + case TGSI_OPCODE_UP2US: + break; + case TGSI_OPCODE_UP4B: + break; + case TGSI_OPCODE_UP4UB: + break; + case TGSI_OPCODE_X2D: + break; + case TGSI_OPCODE_ARA: + break; + case TGSI_OPCODE_ARR: + break; + case TGSI_OPCODE_BRA: + break; + case TGSI_OPCODE_CAL: { + } + break; + case TGSI_OPCODE_RET: { + } + break; + case TGSI_OPCODE_SSG: + break; + case TGSI_OPCODE_CMP: { + } + break; + case TGSI_OPCODE_SCS: { + } + break; + case TGSI_OPCODE_TXB: + break; + case TGSI_OPCODE_NRM: + break; + case TGSI_OPCODE_DIV: + break; + case TGSI_OPCODE_DP2: + break; + case TGSI_OPCODE_TXL: + break; + case TGSI_OPCODE_BRK: { + } + break; + case TGSI_OPCODE_IF: { + } + break; + case TGSI_OPCODE_LOOP: + break; + case TGSI_OPCODE_REP: + break; + case TGSI_OPCODE_ELSE: { + } + break; + case TGSI_OPCODE_ENDIF: { + } + break; + case TGSI_OPCODE_ENDLOOP: + break; + case TGSI_OPCODE_ENDREP: + break; + case TGSI_OPCODE_PUSHA: + break; + case TGSI_OPCODE_POPA: + break; + case TGSI_OPCODE_CEIL: + break; + case TGSI_OPCODE_I2F: + break; + case TGSI_OPCODE_NOT: + break; + case TGSI_OPCODE_TRUNC: { + } + break; + case TGSI_OPCODE_SHL: + break; + case TGSI_OPCODE_SHR: + break; + case TGSI_OPCODE_AND: + break; + case TGSI_OPCODE_OR: + break; + case TGSI_OPCODE_MOD: + break; + case TGSI_OPCODE_XOR: + break; + case TGSI_OPCODE_SAD: + break; + case TGSI_OPCODE_TXF: + break; + case TGSI_OPCODE_TXQ: + break; + case TGSI_OPCODE_CONT: + break; + case TGSI_OPCODE_EMIT: + break; + case TGSI_OPCODE_ENDPRIM: + break; + case TGSI_OPCODE_BGNLOOP2: { + } + break; + case TGSI_OPCODE_BGNSUB: { + } + break; + case TGSI_OPCODE_ENDLOOP2: { + } + break; + case TGSI_OPCODE_ENDSUB: { + } + break; + case TGSI_OPCODE_NOISE1: + break; + case TGSI_OPCODE_NOISE2: + break; + case TGSI_OPCODE_NOISE3: + break; + case TGSI_OPCODE_NOISE4: + break; + case TGSI_OPCODE_NOP: + break; + case TGSI_OPCODE_TEXBEM: + break; + case TGSI_OPCODE_TEXBEML: + break; + case TGSI_OPCODE_TEXREG2AR: + break; + case TGSI_OPCODE_TEXM3X2PAD: + break; + case TGSI_OPCODE_TEXM3X2TEX: + break; + case TGSI_OPCODE_TEXM3X3PAD: + break; + case TGSI_OPCODE_TEXM3X3TEX: + break; + case TGSI_OPCODE_TEXM3X3SPEC: + break; + case TGSI_OPCODE_TEXM3X3VSPEC: + break; + case TGSI_OPCODE_TEXREG2GB: + break; + case TGSI_OPCODE_TEXREG2RGB: + break; + case TGSI_OPCODE_TEXDP3TEX: + break; + case TGSI_OPCODE_TEXDP3: + break; + case TGSI_OPCODE_TEXM3X3: + break; + case TGSI_OPCODE_TEXM3X2DEPTH: + break; + case TGSI_OPCODE_TEXDEPTH: + break; + case TGSI_OPCODE_BEM: + break; + case TGSI_OPCODE_M4X3: + break; + case TGSI_OPCODE_M3X4: + break; + case TGSI_OPCODE_M3X3: + break; + case TGSI_OPCODE_M3X2: + break; + case TGSI_OPCODE_NRM4: + break; + case TGSI_OPCODE_CALLNZ: + break; + case TGSI_OPCODE_IFC: + break; + case TGSI_OPCODE_BREAKC: + break; + case TGSI_OPCODE_KIL: + break; + case TGSI_OPCODE_END: + instr->end(); + return; + break; + default: + fprintf(stderr, "ERROR: Unknown opcode %d\n", + inst->Instruction.Opcode); + assert(0); + break; + } + + if (!out[0]) { + fprintf(stderr, "ERROR: unsupported opcode %d\n", + inst->Instruction.Opcode); + assert(!"Unsupported opcode"); + } + + /* store results */ + for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + + if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { + storage->store(StorageSoa::Output, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { + storage->store(StorageSoa::Temp, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { + storage->store(StorageSoa::Address, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else { + fprintf(stderr, "ERROR: unsupported LLVM destination!"); + assert(!"wrong destination"); + } + } +} + +llvm::Module * +tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens) +{ + llvm::Module *mod = new Module("shader"); + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + unsigned instno = 0; + Function* shader = mod->getFunction("execute_shader"); + std::ostringstream stream; + if (ir->type == GALLIVM_VS) { + stream << "vs_shader"; + } else { + stream << "fs_shader"; + } + stream << ir->id; + std::string func_name = stream.str(); + shader->setName(func_name.c_str()); + + Function::arg_iterator args = shader->arg_begin(); + Value *ptr_INPUT = args++; + ptr_INPUT->setName("input"); + + BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + + tgsi_parse_init(&parse, tokens); + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + Storage storage(label_entry, ptr_INPUT); + Instructions instr(mod, shader, label_entry, &storage); + while(!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + translate_declaration(ir, mod, &storage, + &parse.FullToken.FullDeclaration, + &fd); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + translate_immediate(&storage, + &parse.FullToken.FullImmediate); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + translate_instruction(mod, &storage, &instr, + &parse.FullToken.FullInstruction, + &fi, instno); + ++instno; + break; + + default: + assert(0); + } + } + + tgsi_parse_free(&parse); + + ir->num_consts = storage.numConsts(); + return mod; +} + +llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, + const struct tgsi_token *tokens) +{ + llvm::Module *mod = new Module("shader"); + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + unsigned instno = 0; + std::ostringstream stream; + if (ir->type == GALLIVM_VS) { + stream << "vs_shader"; + } else { + stream << "fs_shader"; + } + //stream << ir->id; + std::string func_name = stream.str(); + Function *shader = llvm::cast(mod->getOrInsertFunction( + func_name.c_str(), + vertexShaderFunctionType())); + + Function::arg_iterator args = shader->arg_begin(); + Value *input = args++; + input->setName("inputs"); + Value *output = args++; + output->setName("outputs"); + Value *consts = args++; + consts->setName("consts"); + Value *temps = args++; + temps->setName("temps"); + + BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + + tgsi_parse_init(&parse, tokens); + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + + StorageSoa storage(label_entry, input, output, consts, temps); + InstructionsSoa instr(mod, shader, label_entry, &storage); + + while(!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + translate_declarationir(ir, mod, &storage, + &parse.FullToken.FullDeclaration, + &fd); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + translate_immediateir(&storage, + &parse.FullToken.FullImmediate); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + storage.declareImmediates(); + translate_instructionir(mod, &storage, &instr, + &parse.FullToken.FullInstruction, + &fi, instno); + ++instno; + break; + + default: + assert(0); + } + } + + tgsi_parse_free(&parse); + + return mod; +} diff --git a/src/gallium/aux/llvm/tgsitollvm.h b/src/gallium/aux/llvm/tgsitollvm.h new file mode 100644 index 0000000000..7ada04d629 --- /dev/null +++ b/src/gallium/aux/llvm/tgsitollvm.h @@ -0,0 +1,20 @@ +#ifndef TGSITOLLVM_H +#define TGSITOLLVM_H + + +namespace llvm { + class Module; +} + +struct gallivm_ir; +struct tgsi_token; + + +llvm::Module * tgsi_to_llvm(struct gallivm_ir *ir, + const struct tgsi_token *tokens); + + +llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, + const struct tgsi_token *tokens); + +#endif diff --git a/src/gallium/aux/pipebuffer/Makefile b/src/gallium/aux/pipebuffer/Makefile new file mode 100644 index 0000000000..75764a9a18 --- /dev/null +++ b/src/gallium/aux/pipebuffer/Makefile @@ -0,0 +1,23 @@ + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = pipebuffer + +DRIVER_SOURCES = \ + pb_buffer_fenced.c \ + pb_buffer_malloc.c \ + pb_bufmgr_fenced.c \ + pb_bufmgr_mm.c \ + pb_bufmgr_pool.c \ + pb_winsys.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../Makefile.template + +symlinks: + diff --git a/src/gallium/aux/pipebuffer/linked_list.h b/src/gallium/aux/pipebuffer/linked_list.h new file mode 100644 index 0000000000..e99817fb13 --- /dev/null +++ b/src/gallium/aux/pipebuffer/linked_list.h @@ -0,0 +1,91 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + +/** + * \file + * List macros heavily inspired by the Linux kernel + * list handling. No list looping yet. + * + * Is not threadsafe, so common operations need to + * be protected using an external mutex. + */ + +#ifndef LINKED_LIST_H_ +#define LINKED_LIST_H_ + + +#include + + +struct list_head +{ + struct list_head *prev; + struct list_head *next; +}; + + +#define LIST_INITHEAD(__item) \ + do { \ + (__item)->prev = (__item); \ + (__item)->next = (__item); \ + } while (0) + +#define LIST_ADD(__item, __list) \ + do { \ + (__item)->prev = (__list); \ + (__item)->next = (__list)->next; \ + (__list)->next->prev = (__item); \ + (__list)->next = (__item); \ + } while (0) + +#define LIST_ADDTAIL(__item, __list) \ + do { \ + (__item)->next = (__list); \ + (__item)->prev = (__list)->prev; \ + (__list)->prev->next = (__item); \ + (__list)->prev = (__item); \ + } while(0) + +#define LIST_DEL(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + } while(0) + +#define LIST_DELINIT(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + (__item)->next = (__item); \ + (__item)->prev = (__item); \ + } while(0) + +#define LIST_ENTRY(__type, __item, __field) \ + ((__type *)(((char *)(__item)) - offsetof(__type, __field))) + + +#endif /*LINKED_LIST_H_*/ diff --git a/src/gallium/aux/pipebuffer/pb_buffer.h b/src/gallium/aux/pipebuffer/pb_buffer.h new file mode 100644 index 0000000000..97beb5f72a --- /dev/null +++ b/src/gallium/aux/pipebuffer/pb_buffer.h @@ -0,0 +1,202 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Generic code for buffers. + * + * Behind a pipe buffle handle there can be DMA buffers, client (or user) + * buffers, regular malloced buffers, etc. This file provides an abstract base + * buffer handle that allows the driver to cope with all those kinds of buffers + * in a more flexible way. + * + * There is no obligation of a winsys driver to use this library. And a pipe + * driver should be completly agnostic about it. + * + * \author José Fonseca + */ + +#ifndef PB_BUFFER_H_ +#define PB_BUFFER_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" + + +struct pb_vtbl; + +/** + * Buffer description. + * + * Used when allocating the buffer. + */ +struct pb_desc +{ + unsigned alignment; + unsigned usage; +}; + + +/** + * Base class for all pb_* buffers. + */ +struct pb_buffer +{ + struct pipe_buffer base; + + /** + * Pointer to the virtual function table. + * + * Avoid accessing this table directly. Use the inline functions below + * instead to avoid mistakes. + */ + const struct pb_vtbl *vtbl; +}; + + +/** + * Virtual function table for the buffer storage operations. + * + * Note that creation is not done through this table. + */ +struct pb_vtbl +{ + void (*destroy)( struct pb_buffer *buf ); + + /** + * Map the entire data store of a buffer object into the client's address. + * flags is bitmask of PIPE_BUFFER_FLAG_READ/WRITE. + */ + void *(*map)( struct pb_buffer *buf, + unsigned flags ); + + void (*unmap)( struct pb_buffer *buf ); + + /** + * Get the base buffer and the offset. + * + * A buffer can be subdivided in smaller buffers. This method should return + * the underlaying buffer, and the relative offset. + * + * Buffers without an underlaying base buffer should return themselves, with + * a zero offset. + * + * Note that this will increase the reference count of the base buffer. + */ + void (*get_base_buffer)( struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset ); +}; + + +static INLINE struct pipe_buffer * +pb_pipe_buffer( struct pb_buffer *pbuf ) +{ + assert(pbuf); + return &pbuf->base; +} + + +static INLINE struct pb_buffer * +pb_buffer( struct pipe_buffer *buf ) +{ + assert(buf); + /* Could add a magic cookie check on debug builds. + */ + return (struct pb_buffer *)buf; +} + + +/* Accessor functions for pb->vtbl: + */ +static INLINE void * +pb_map(struct pb_buffer *buf, + unsigned flags) +{ + assert(buf); + return buf->vtbl->map(buf, flags); +} + + +static INLINE void +pb_unmap(struct pb_buffer *buf) +{ + assert(buf); + buf->vtbl->unmap(buf); +} + + +static INLINE void +pb_get_base_buffer( struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset ) +{ + buf->vtbl->get_base_buffer(buf, base_buf, offset); +} + + +static INLINE void +pb_destroy(struct pb_buffer *buf) +{ + assert(buf); + buf->vtbl->destroy(buf); +} + + +/* XXX: thread safety issues! + */ +static INLINE void +pb_reference(struct pb_buffer **dst, + struct pb_buffer *src) +{ + if (src) + src->base.refcount++; + + if (*dst && --(*dst)->base.refcount == 0) + pb_destroy( *dst ); + + *dst = src; +} + + +/** + * Malloc-based buffer to store data that can't be used by the graphics + * hardware. + */ +struct pb_buffer * +pb_malloc_buffer_create(size_t size, + const struct pb_desc *desc); + + +void +pb_init_winsys(struct pipe_winsys *winsys); + + +#endif /*PB_BUFFER_H_*/ diff --git a/src/gallium/aux/pipebuffer/pb_buffer_fenced.c b/src/gallium/aux/pipebuffer/pb_buffer_fenced.c new file mode 100644 index 0000000000..f4fc3f6d71 --- /dev/null +++ b/src/gallium/aux/pipebuffer/pb_buffer_fenced.c @@ -0,0 +1,299 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Implementation of fenced buffers. + * + * \author José Fonseca + * \author Thomas Hellström + */ + + +#include "linked_list.h" + +#include "p_compiler.h" +#include "p_debug.h" +#include "p_winsys.h" +#include "p_thread.h" +#include "p_util.h" + +#include "pb_buffer.h" +#include "pb_buffer_fenced.h" + +#ifndef __MSC__ +#include +#endif + + +/** + * Convenience macro (type safe). + */ +#define SUPER(__derived) (&(__derived)->base) + + +struct fenced_buffer_list +{ + _glthread_Mutex mutex; + + struct pipe_winsys *winsys; + + size_t numDelayed; + size_t checkDelayed; + + struct list_head delayed; +}; + + +/** + * Wrapper around a pipe buffer which adds fencing and reference counting. + */ +struct fenced_buffer +{ + struct pb_buffer base; + + struct pb_buffer *buffer; + + struct pipe_fence_handle *fence; + + struct list_head head; + struct fenced_buffer_list *list; +}; + + +static INLINE struct fenced_buffer * +fenced_buffer(struct pb_buffer *buf) +{ + assert(buf); + assert(buf->vtbl == &fenced_buffer_vtbl); + return (struct fenced_buffer *)buf; +} + + + + +static void +_fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, + int wait) +{ + struct pipe_winsys *winsys = fenced_list->winsys; + struct fenced_buffer *fenced_buf; + struct list_head *list, *prev; + int signaled = -1; + + list = fenced_list->delayed.next; + + if (fenced_list->numDelayed > 3) { + unsigned i; + + for (i = 0; i < fenced_list->numDelayed; i += 3) { + list = list->next; + } + } + + prev = list->prev; + for (; list != &fenced_list->delayed; list = prev, prev = list->prev) { + + fenced_buf = LIST_ENTRY(struct fenced_buffer, list, head); + + if (signaled != 0) { + if (wait) { + signaled = winsys->fence_finish(winsys, fenced_buf->fence, 0); + } + else { + signaled = winsys->fence_signalled(winsys, fenced_buf->fence, 0); + } + } + + if (signaled != 0) + /* XXX: we are assuming that buffers are freed in the same order they + * are fenced which may not always be true... + */ + break; + + winsys->fence_reference(winsys, &fenced_buf->fence, NULL); + + LIST_DEL(list); + fenced_list->numDelayed--; + + /* Do the delayed destroy: + */ + pb_reference(&fenced_buf->buffer, NULL); + FREE(fenced_buf); + } +} + + +static void +fenced_buffer_destroy(struct pb_buffer *buf) +{ + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + struct fenced_buffer_list *fenced_list = fenced_buf->list; + + if (fenced_buf->fence) { + LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); + fenced_list->numDelayed++; + } + else { + pb_reference(&fenced_buf->buffer, NULL); + FREE(fenced_buf); + } + + if ((fenced_list->numDelayed % fenced_list->checkDelayed) == 0) + _fenced_buffer_list_check_free(fenced_list, 0); +} + + +static void * +fenced_buffer_map(struct pb_buffer *buf, + unsigned flags) +{ + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + return pb_map(fenced_buf->buffer, flags); +} + + +static void +fenced_buffer_unmap(struct pb_buffer *buf) +{ + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + pb_unmap(fenced_buf->buffer); +} + + +static void +fenced_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + pb_get_base_buffer(fenced_buf->buffer, base_buf, offset); +} + + +const struct pb_vtbl +fenced_buffer_vtbl = { + fenced_buffer_destroy, + fenced_buffer_map, + fenced_buffer_unmap, + fenced_buffer_get_base_buffer +}; + + +struct pb_buffer * +fenced_buffer_create(struct fenced_buffer_list *fenced_list, + struct pb_buffer *buffer) +{ + struct fenced_buffer *buf; + + if(!buffer) + return NULL; + + buf = CALLOC_STRUCT(fenced_buffer); + if(!buf) + return NULL; + + buf->base.base.refcount = 1; + buf->base.base.alignment = buffer->base.alignment; + buf->base.base.usage = buffer->base.usage; + buf->base.base.size = buffer->base.size; + + buf->base.vtbl = &fenced_buffer_vtbl; + buf->buffer = buffer; + buf->list = fenced_list; + + return &buf->base; +} + + +void +buffer_fence(struct pb_buffer *buf, + struct pipe_fence_handle *fence) +{ + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + struct fenced_buffer_list *fenced_list = fenced_buf->list; + struct pipe_winsys *winsys = fenced_list->winsys; + + _glthread_LOCK_MUTEX(fenced_list->mutex); + winsys->fence_reference(winsys, &fenced_buf->fence, fence); + _glthread_UNLOCK_MUTEX(fenced_list->mutex); +} + + +struct fenced_buffer_list * +fenced_buffer_list_create(struct pipe_winsys *winsys) +{ + struct fenced_buffer_list *fenced_list; + + fenced_list = (struct fenced_buffer_list *)CALLOC(1, sizeof(*fenced_list)); + if (!fenced_list) + return NULL; + + fenced_list->winsys = winsys; + + LIST_INITHEAD(&fenced_list->delayed); + + fenced_list->numDelayed = 0; + + /* TODO: don't hard code this */ + fenced_list->checkDelayed = 5; + + _glthread_INIT_MUTEX(fenced_list->mutex); + + return fenced_list; +} + + +void +fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, + int wait) +{ + _glthread_LOCK_MUTEX(fenced_list->mutex); + _fenced_buffer_list_check_free(fenced_list, wait); + _glthread_UNLOCK_MUTEX(fenced_list->mutex); +} + + +void +fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list) +{ + _glthread_LOCK_MUTEX(fenced_list->mutex); + + /* Wait on outstanding fences */ + while (fenced_list->numDelayed) { + _glthread_UNLOCK_MUTEX(fenced_list->mutex); + sched_yield(); + _fenced_buffer_list_check_free(fenced_list, 1); + _glthread_LOCK_MUTEX(fenced_list->mutex); + } + + _glthread_UNLOCK_MUTEX(fenced_list->mutex); + + FREE(fenced_list); +} + + diff --git a/src/gallium/aux/pipebuffer/pb_buffer_fenced.h b/src/gallium/aux/pipebuffer/pb_buffer_fenced.h new file mode 100644 index 0000000000..c40b9c75e1 --- /dev/null +++ b/src/gallium/aux/pipebuffer/pb_buffer_fenced.h @@ -0,0 +1,117 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Buffer fencing. + * + * "Fenced buffers" is actually a misnomer. They should be referred as + * "fenceable buffers", i.e, buffers that can be fenced, but I couldn't find + * the word "fenceable" in the dictionary. + * + * A "fenced buffer" is a decorator around a normal buffer, which adds two + * special properties: + * - the ability for the destruction to be delayed by a fence; + * - reference counting. + * + * Usually DMA buffers have a life-time that will extend the life-time of its + * handle. The end-of-life is dictated by the fence signalling. + * + * Between the handle's destruction, and the fence signalling, the buffer is + * stored in a fenced buffer list. + * + * \author José Fonseca + */ + +#ifndef PB_BUFFER_FENCED_H_ +#define PB_BUFFER_FENCED_H_ + + +#include "pipe/p_debug.h" + + +struct pipe_winsys; +struct pipe_buffer; +struct pipe_fence_handle; + + +/** + * List of buffers which are awaiting fence signalling. + */ +struct fenced_buffer_list; + + +/** + * The fenced buffer's virtual function table. + * + * NOTE: Made public for debugging purposes. + */ +extern const struct pb_vtbl fenced_buffer_vtbl; + + +/** + * Create a fenced buffer list. + * + * See also fenced_bufmgr_create for a more convenient way to use this. + */ +struct fenced_buffer_list * +fenced_buffer_list_create(struct pipe_winsys *winsys); + + +/** + * Walk the fenced buffer list to check and free signalled buffers. + */ +void +fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, + int wait); + +void +fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list); + + +/** + * Wrap a buffer in a fenced buffer. + * + * NOTE: this will not increase the buffer reference count. + */ +struct pb_buffer * +fenced_buffer_create(struct fenced_buffer_list *fenced, + struct pb_buffer *buffer); + + +/** + * Set a buffer's fence. + * + * NOTE: Although it takes a generic pb_buffer argument, it will fail + * on everything but buffers returned by fenced_buffer_create. + */ +void +buffer_fence(struct pb_buffer *buf, + struct pipe_fence_handle *fence); + + +#endif /*PB_BUFFER_FENCED_H_*/ diff --git a/src/gallium/aux/pipebuffer/pb_buffer_malloc.c b/src/gallium/aux/pipebuffer/pb_buffer_malloc.c new file mode 100644 index 0000000000..9e8244f909 --- /dev/null +++ b/src/gallium/aux/pipebuffer/pb_buffer_malloc.c @@ -0,0 +1,127 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Implementation of malloc-based buffers to store data that can't be processed + * by the hardware. + * + * \author José Fonseca + */ + + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pb_buffer.h" + + +struct malloc_buffer +{ + struct pb_buffer base; + void *data; +}; + + +extern const struct pb_vtbl malloc_buffer_vtbl; + +static INLINE struct malloc_buffer * +malloc_buffer(struct pb_buffer *buf) +{ + assert(buf); + assert(buf->vtbl == &malloc_buffer_vtbl); + return (struct malloc_buffer *)buf; +} + + +static void +malloc_buffer_destroy(struct pb_buffer *buf) +{ + align_free(malloc_buffer(buf)->data); + FREE(buf); +} + + +static void * +malloc_buffer_map(struct pb_buffer *buf, + unsigned flags) +{ + return malloc_buffer(buf)->data; +} + + +static void +malloc_buffer_unmap(struct pb_buffer *buf) +{ + /* No-op */ +} + + +static void +malloc_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + *base_buf = buf; + *offset = 0; +} + + +const struct pb_vtbl +malloc_buffer_vtbl = { + malloc_buffer_destroy, + malloc_buffer_map, + malloc_buffer_unmap, + malloc_buffer_get_base_buffer +}; + + +struct pb_buffer * +pb_malloc_buffer_create(size_t size, + const struct pb_desc *desc) +{ + struct malloc_buffer *buf; + + /* TODO: do a single allocation */ + + buf = CALLOC_STRUCT(malloc_buffer); + if(!buf) + return NULL; + + buf->base.base.refcount = 1; + buf->base.base.alignment = desc->alignment; + buf->base.base.usage = desc->usage; + buf->base.base.size = size; + buf->base.vtbl = &malloc_buffer_vtbl; + + buf->data = align_malloc(size, desc->alignment < sizeof(void*) ? sizeof(void*) : desc->alignment); + if(!buf->data) { + align_free(buf); + return NULL; + } + + return &buf->base; +} diff --git a/src/gallium/aux/pipebuffer/pb_bufmgr.h b/src/gallium/aux/pipebuffer/pb_bufmgr.h new file mode 100644 index 0000000000..1ddf784c97 --- /dev/null +++ b/src/gallium/aux/pipebuffer/pb_bufmgr.h @@ -0,0 +1,126 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Buffer management. + * + * A buffer manager does only one basic thing: it creates buffers. Actually, + * "buffer factory" would probably a more accurate description. + * + * You can chain buffer managers so that you can have a finer grained memory + * management and pooling. + * + * For example, for a simple batch buffer manager you would chain: + * - the native buffer manager, which provides DMA memory from the graphics + * memory space; + * - the pool buffer manager, which keep around a pool of equally sized buffers + * to avoid latency associated with the native buffer manager; + * - the fenced buffer manager, which will delay buffer destruction until the + * the moment the card finishing processing it. + * + * \author José Fonseca + */ + +#ifndef PB_BUFMGR_H_ +#define PB_BUFMGR_H_ + + +#include + + +struct pb_desc; +struct pipe_buffer; +struct pipe_winsys; + + +/** + * Abstract base class for all buffer managers. + */ +struct pb_manager +{ + /* XXX: we will likely need more allocation flags */ + struct pb_buffer * + (*create_buffer)( struct pb_manager *mgr, + size_t size, + const struct pb_desc *desc); + + void + (*destroy)( struct pb_manager *mgr ); +}; + + +/** + * Static buffer pool manager. + * + * Manages the allocation of equally sized buffers. It does so by allocating + * a single big buffer and divide it equally sized buffers. + * + * It is meant to manage the allocation of batch buffer pools. + */ +struct pb_manager * +pool_bufmgr_create(struct pb_manager *provider, + size_t n, size_t size, + const struct pb_desc *desc); + + +/** + * Wraper around the old memory manager. + * + * It managers buffers of different sizes. It does so by allocating a buffer + * with the size of the heap, and then using the old mm memory manager to manage + * that heap. + */ +struct pb_manager * +mm_bufmgr_create(struct pb_manager *provider, + size_t size, size_t align2); + +/** + * Same as mm_bufmgr_create. + * + * Buffer will be release when the manager is destroyed. + */ +struct pb_manager * +mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, + size_t size, size_t align2); + + +/** + * Fenced buffer manager. + * + * This manager is just meant for convenience. It wraps the buffers returned + * by another manager in fenced buffers, so that + * + * NOTE: the buffer manager that provides the buffers will be destroyed + * at the same time. + */ +struct pb_manager * +fenced_bufmgr_create(struct pb_manager *provider, + struct pipe_winsys *winsys); + + +#endif /*PB_BUFMGR_H_*/ diff --git a/src/gallium/aux/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/aux/pipebuffer/pb_bufmgr_fenced.c new file mode 100644 index 0000000000..c535d3276c --- /dev/null +++ b/src/gallium/aux/pipebuffer/pb_bufmgr_fenced.c @@ -0,0 +1,131 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * \file + * A buffer manager that wraps buffers in fenced buffers. + * + * \author José Fonseca + */ + + +#include "p_debug.h" +#include "p_util.h" + +#include "pb_buffer.h" +#include "pb_buffer_fenced.h" +#include "pb_bufmgr.h" + + +struct fenced_pb_manager +{ + struct pb_manager base; + + struct pb_manager *provider; + + struct fenced_buffer_list *fenced_list; +}; + + +static INLINE struct fenced_pb_manager * +fenced_pb_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct fenced_pb_manager *)mgr; +} + + +static struct pb_buffer * +fenced_bufmgr_create_buffer(struct pb_manager *mgr, + size_t size, + const struct pb_desc *desc) +{ + struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr); + struct pb_buffer *buf; + struct pb_buffer *fenced_buf; + + /* check for free buffers before allocating new ones */ + fenced_buffer_list_check_free(fenced_mgr->fenced_list, 0); + + buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc); + if(!buf) { + /* try harder to get a buffer */ + fenced_buffer_list_check_free(fenced_mgr->fenced_list, 1); + + buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc); + if(!buf) { + /* give up */ + return NULL; + } + } + + fenced_buf = fenced_buffer_create(fenced_mgr->fenced_list, buf); + if(!fenced_buf) { + assert(buf->base.refcount == 1); + pb_destroy(buf); + } + + return fenced_buf; +} + + +static void +fenced_bufmgr_destroy(struct pb_manager *mgr) +{ + struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr); + + fenced_buffer_list_destroy(fenced_mgr->fenced_list); + + fenced_mgr->provider->destroy(fenced_mgr->provider); + + FREE(fenced_mgr); +} + + +struct pb_manager * +fenced_bufmgr_create(struct pb_manager *provider, + struct pipe_winsys *winsys) +{ + struct fenced_pb_manager *fenced_mgr; + + fenced_mgr = (struct fenced_pb_manager *)CALLOC(1, sizeof(*fenced_mgr)); + if (!fenced_mgr) + return NULL; + + fenced_mgr->base.destroy = fenced_bufmgr_destroy; + fenced_mgr->base.create_buffer = fenced_bufmgr_create_buffer; + + fenced_mgr->provider = provider; + fenced_mgr->fenced_list = fenced_buffer_list_create(winsys); + if(!fenced_mgr->fenced_list) { + FREE(fenced_mgr); + return NULL; + } + + return &fenced_mgr->base; +} diff --git a/src/gallium/aux/pipebuffer/pb_bufmgr_mm.c b/src/gallium/aux/pipebuffer/pb_bufmgr_mm.c new file mode 100644 index 0000000000..8b1b51c0e2 --- /dev/null +++ b/src/gallium/aux/pipebuffer/pb_bufmgr_mm.c @@ -0,0 +1,593 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 1999 Wittawat Yamwong + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Buffer manager using the old texture memory manager. + * + * \author José Fonseca + */ + + +#include "linked_list.h" + +#include "p_defines.h" +#include "p_debug.h" +#include "p_thread.h" +#include "p_util.h" +#include "pb_buffer.h" +#include "pb_bufmgr.h" + + +/** + * Convenience macro (type safe). + */ +#define SUPER(__derived) (&(__derived)->base) + + +struct mem_block +{ + struct mem_block *next, *prev; + struct mem_block *next_free, *prev_free; + struct mem_block *heap; + int ofs, size; + unsigned int free:1; + unsigned int reserved:1; +}; + + +#ifdef DEBUG +/** + * For debugging purposes. + */ +static void +mmDumpMemInfo(const struct mem_block *heap) +{ + debug_printf("Memory heap %p:\n", (void *)heap); + if (heap == 0) { + debug_printf(" heap == 0\n"); + } else { + const struct mem_block *p; + + for(p = heap->next; p != heap; p = p->next) { + debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + debug_printf("\nFree list:\n"); + + for(p = heap->next_free; p != heap; p = p->next_free) { + debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + } + debug_printf("End of memory blocks\n"); +} +#endif + + +/** + * input: total size in bytes + * return: a heap pointer if OK, NULL if error + */ +static struct mem_block * +mmInit(int ofs, int size) +{ + struct mem_block *heap, *block; + + if (size <= 0) + return NULL; + + heap = CALLOC_STRUCT(mem_block); + if (!heap) + return NULL; + + block = CALLOC_STRUCT(mem_block); + if (!block) { + FREE(heap); + return NULL; + } + + heap->next = block; + heap->prev = block; + heap->next_free = block; + heap->prev_free = block; + + block->heap = heap; + block->next = heap; + block->prev = heap; + block->next_free = heap; + block->prev_free = heap; + + block->ofs = ofs; + block->size = size; + block->free = 1; + + return heap; +} + + +static struct mem_block * +SliceBlock(struct mem_block *p, + int startofs, int size, + int reserved, int alignment) +{ + struct mem_block *newblock; + + /* break left [p, newblock, p->next], then p = newblock */ + if (startofs > p->ofs) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs; + newblock->size = p->size - (startofs - p->ofs); + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size -= newblock->size; + p = newblock; + } + + /* break right, also [p, newblock, p->next] */ + if (size < p->size) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs + size; + newblock->size = p->size - size; + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size = size; + } + + /* p = middle block */ + p->free = 0; + + /* Remove p from the free list: + */ + p->next_free->prev_free = p->prev_free; + p->prev_free->next_free = p->next_free; + + p->next_free = 0; + p->prev_free = 0; + + p->reserved = reserved; + return p; +} + + +/** + * Allocate 'size' bytes with 2^align2 bytes alignment, + * restrict the search to free memory after 'startSearch' + * depth and back buffers should be in different 4mb banks + * to get better page hits if possible + * input: size = size of block + * align2 = 2^align2 bytes alignment + * startSearch = linear offset from start of heap to begin search + * return: pointer to the allocated block, 0 if error + */ +static struct mem_block * +mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) +{ + struct mem_block *p; + const int mask = (1 << align2)-1; + int startofs = 0; + int endofs; + + if (!heap || align2 < 0 || size <= 0) + return NULL; + + for (p = heap->next_free; p != heap; p = p->next_free) { + assert(p->free); + + startofs = (p->ofs + mask) & ~mask; + if ( startofs < startSearch ) { + startofs = startSearch; + } + endofs = startofs+size; + if (endofs <= (p->ofs+p->size)) + break; + } + + if (p == heap) + return NULL; + + assert(p->free); + p = SliceBlock(p,startofs,size,0,mask+1); + + return p; +} + + +#if 0 +/** + * Free block starts at offset + * input: pointer to a heap, start offset + * return: pointer to a block + */ +static struct mem_block * +mmFindBlock(struct mem_block *heap, int start) +{ + struct mem_block *p; + + for (p = heap->next; p != heap; p = p->next) { + if (p->ofs == start) + return p; + } + + return NULL; +} +#endif + + +static INLINE int +Join2Blocks(struct mem_block *p) +{ + /* XXX there should be some assertions here */ + + /* NOTE: heap->free == 0 */ + + if (p->free && p->next->free) { + struct mem_block *q = p->next; + + assert(p->ofs + p->size == q->ofs); + p->size += q->size; + + p->next = q->next; + q->next->prev = p; + + q->next_free->prev_free = q->prev_free; + q->prev_free->next_free = q->next_free; + + FREE(q); + return 1; + } + return 0; +} + + +/** + * Free block starts at offset + * input: pointer to a block + * return: 0 if OK, -1 if error + */ +static int +mmFreeMem(struct mem_block *b) +{ + if (!b) + return 0; + + if (b->free) { + debug_printf("block already free\n"); + return -1; + } + if (b->reserved) { + debug_printf("block is reserved\n"); + return -1; + } + + b->free = 1; + b->next_free = b->heap->next_free; + b->prev_free = b->heap; + b->next_free->prev_free = b; + b->prev_free->next_free = b; + + Join2Blocks(b); + if (b->prev != b->heap) + Join2Blocks(b->prev); + + return 0; +} + + +/** + * destroy MM + */ +static void +mmDestroy(struct mem_block *heap) +{ + struct mem_block *p; + + if (!heap) + return; + + for (p = heap->next; p != heap; ) { + struct mem_block *next = p->next; + FREE(p); + p = next; + } + + FREE(heap); +} + + +struct mm_pb_manager +{ + struct pb_manager base; + + _glthread_Mutex mutex; + + size_t size; + struct mem_block *heap; + + size_t align2; + + struct pb_buffer *buffer; + void *map; +}; + + +static INLINE struct mm_pb_manager * +mm_pb_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct mm_pb_manager *)mgr; +} + + +struct mm_buffer +{ + struct pb_buffer base; + + struct mm_pb_manager *mgr; + + struct mem_block *block; +}; + + +static INLINE struct mm_buffer * +mm_buffer(struct pb_buffer *buf) +{ + assert(buf); + return (struct mm_buffer *)buf; +} + + +static void +mm_buffer_destroy(struct pb_buffer *buf) +{ + struct mm_buffer *mm_buf = mm_buffer(buf); + struct mm_pb_manager *mm = mm_buf->mgr; + + assert(buf->base.refcount == 0); + + _glthread_LOCK_MUTEX(mm->mutex); + mmFreeMem(mm_buf->block); + FREE(buf); + _glthread_UNLOCK_MUTEX(mm->mutex); +} + + +static void * +mm_buffer_map(struct pb_buffer *buf, + unsigned flags) +{ + struct mm_buffer *mm_buf = mm_buffer(buf); + struct mm_pb_manager *mm = mm_buf->mgr; + + return (unsigned char *) mm->map + mm_buf->block->ofs; +} + + +static void +mm_buffer_unmap(struct pb_buffer *buf) +{ + /* No-op */ +} + + +static void +mm_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + struct mm_buffer *mm_buf = mm_buffer(buf); + struct mm_pb_manager *mm = mm_buf->mgr; + pb_get_base_buffer(mm->buffer, base_buf, offset); + *offset += mm_buf->block->ofs; +} + + +static const struct pb_vtbl +mm_buffer_vtbl = { + mm_buffer_destroy, + mm_buffer_map, + mm_buffer_unmap, + mm_buffer_get_base_buffer +}; + + +static struct pb_buffer * +mm_bufmgr_create_buffer(struct pb_manager *mgr, + size_t size, + const struct pb_desc *desc) +{ + struct mm_pb_manager *mm = mm_pb_manager(mgr); + struct mm_buffer *mm_buf; + + /* We don't handle alignments larger then the one initially setup */ + assert(desc->alignment % (1 << mm->align2) == 0); + if(desc->alignment % (1 << mm->align2)) + return NULL; + + _glthread_LOCK_MUTEX(mm->mutex); + + mm_buf = CALLOC_STRUCT(mm_buffer); + if (!mm_buf) { + _glthread_UNLOCK_MUTEX(mm->mutex); + return NULL; + } + + mm_buf->base.base.refcount = 1; + mm_buf->base.base.alignment = desc->alignment; + mm_buf->base.base.usage = desc->usage; + mm_buf->base.base.size = size; + + mm_buf->base.vtbl = &mm_buffer_vtbl; + + mm_buf->mgr = mm; + + mm_buf->block = mmAllocMem(mm->heap, size, mm->align2, 0); + if(!mm_buf->block) { + debug_printf("warning: heap full\n"); +#if 0 + mmDumpMemInfo(mm->heap); +#endif + + mm_buf->block = mmAllocMem(mm->heap, size, mm->align2, 0); + if(!mm_buf->block) { + assert(0); + FREE(mm_buf); + _glthread_UNLOCK_MUTEX(mm->mutex); + return NULL; + } + } + + /* Some sanity checks */ + assert(0 <= mm_buf->block->ofs && mm_buf->block->ofs < mm->size); + assert(size <= mm_buf->block->size && mm_buf->block->ofs + mm_buf->block->size <= mm->size); + + _glthread_UNLOCK_MUTEX(mm->mutex); + return SUPER(mm_buf); +} + + +static void +mm_bufmgr_destroy(struct pb_manager *mgr) +{ + struct mm_pb_manager *mm = mm_pb_manager(mgr); + + _glthread_LOCK_MUTEX(mm->mutex); + + mmDestroy(mm->heap); + + pb_unmap(mm->buffer); + pb_reference(&mm->buffer, NULL); + + _glthread_UNLOCK_MUTEX(mm->mutex); + + FREE(mgr); +} + + +struct pb_manager * +mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, + size_t size, size_t align2) +{ + struct mm_pb_manager *mm; + + if(!buffer) + return NULL; + + mm = CALLOC_STRUCT(mm_pb_manager); + if (!mm) + return NULL; + + mm->base.create_buffer = mm_bufmgr_create_buffer; + mm->base.destroy = mm_bufmgr_destroy; + + mm->size = size; + mm->align2 = align2; /* 64-byte alignment */ + + _glthread_INIT_MUTEX(mm->mutex); + + mm->buffer = buffer; + + mm->map = pb_map(mm->buffer, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + if(!mm->map) + goto failure; + + mm->heap = mmInit(0, size); + if (!mm->heap) + goto failure; + + return SUPER(mm); + +failure: +if(mm->heap) + mmDestroy(mm->heap); + if(mm->map) + pb_unmap(mm->buffer); + if(mm) + FREE(mm); + return NULL; +} + + +struct pb_manager * +mm_bufmgr_create(struct pb_manager *provider, + size_t size, size_t align2) +{ + struct pb_buffer *buffer; + struct pb_manager *mgr; + struct pb_desc desc; + + assert(provider); + assert(provider->create_buffer); + + memset(&desc, 0, sizeof(desc)); + desc.alignment = 1 << align2; + + buffer = provider->create_buffer(provider, size, &desc); + if (!buffer) + return NULL; + + mgr = mm_bufmgr_create_from_buffer(buffer, size, align2); + if (!mgr) { + pb_reference(&buffer, NULL); + return NULL; + } + + return mgr; +} diff --git a/src/gallium/aux/pipebuffer/pb_bufmgr_pool.c b/src/gallium/aux/pipebuffer/pb_bufmgr_pool.c new file mode 100644 index 0000000000..04477a865a --- /dev/null +++ b/src/gallium/aux/pipebuffer/pb_bufmgr_pool.c @@ -0,0 +1,288 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * \file + * Batch buffer pool management. + * + * \author José Fonseca + * \author Thomas Hellström + */ + + +#include "linked_list.h" + +#include "p_compiler.h" +#include "p_debug.h" +#include "p_thread.h" +#include "p_defines.h" +#include "p_util.h" + +#include "pb_buffer.h" +#include "pb_bufmgr.h" + + +/** + * Convenience macro (type safe). + */ +#define SUPER(__derived) (&(__derived)->base) + + +struct pool_pb_manager +{ + struct pb_manager base; + + _glthread_Mutex mutex; + + size_t bufSize; + size_t bufAlign; + + size_t numFree; + size_t numTot; + + struct list_head free; + + struct pb_buffer *buffer; + void *map; + + struct pool_buffer *bufs; +}; + + +static INLINE struct pool_pb_manager * +pool_pb_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct pool_pb_manager *)mgr; +} + + +struct pool_buffer +{ + struct pb_buffer base; + + struct pool_pb_manager *mgr; + + struct list_head head; + + size_t start; +}; + + +static INLINE struct pool_buffer * +pool_buffer(struct pb_buffer *buf) +{ + assert(buf); + return (struct pool_buffer *)buf; +} + + + +static void +pool_buffer_destroy(struct pb_buffer *buf) +{ + struct pool_buffer *pool_buf = pool_buffer(buf); + struct pool_pb_manager *pool = pool_buf->mgr; + + assert(pool_buf->base.base.refcount == 0); + + _glthread_LOCK_MUTEX(pool->mutex); + LIST_ADD(&pool_buf->head, &pool->free); + pool->numFree++; + _glthread_UNLOCK_MUTEX(pool->mutex); +} + + +static void * +pool_buffer_map(struct pb_buffer *buf, unsigned flags) +{ + struct pool_buffer *pool_buf = pool_buffer(buf); + struct pool_pb_manager *pool = pool_buf->mgr; + void *map; + + _glthread_LOCK_MUTEX(pool->mutex); + map = (unsigned char *) pool->map + pool_buf->start; + _glthread_UNLOCK_MUTEX(pool->mutex); + return map; +} + + +static void +pool_buffer_unmap(struct pb_buffer *buf) +{ + /* No-op */ +} + + +static void +pool_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + struct pool_buffer *pool_buf = pool_buffer(buf); + struct pool_pb_manager *pool = pool_buf->mgr; + pb_get_base_buffer(pool->buffer, base_buf, offset); + *offset += pool_buf->start; +} + + +static const struct pb_vtbl +pool_buffer_vtbl = { + pool_buffer_destroy, + pool_buffer_map, + pool_buffer_unmap, + pool_buffer_get_base_buffer +}; + + +static struct pb_buffer * +pool_bufmgr_create_buffer(struct pb_manager *mgr, + size_t size, + const struct pb_desc *desc) +{ + struct pool_pb_manager *pool = pool_pb_manager(mgr); + struct pool_buffer *pool_buf; + struct list_head *item; + + assert(size == pool->bufSize); + assert(pool->bufAlign % desc->alignment == 0); + + _glthread_LOCK_MUTEX(pool->mutex); + + if (pool->numFree == 0) { + _glthread_UNLOCK_MUTEX(pool->mutex); + debug_printf("warning: out of fixed size buffer objects\n"); + return NULL; + } + + item = pool->free.next; + + if (item == &pool->free) { + _glthread_UNLOCK_MUTEX(pool->mutex); + debug_printf("error: fixed size buffer pool corruption\n"); + return NULL; + } + + LIST_DEL(item); + --pool->numFree; + + _glthread_UNLOCK_MUTEX(pool->mutex); + + pool_buf = LIST_ENTRY(struct pool_buffer, item, head); + assert(pool_buf->base.base.refcount == 0); + pool_buf->base.base.refcount = 1; + pool_buf->base.base.alignment = desc->alignment; + pool_buf->base.base.usage = desc->usage; + + return SUPER(pool_buf); +} + + +static void +pool_bufmgr_destroy(struct pb_manager *mgr) +{ + struct pool_pb_manager *pool = pool_pb_manager(mgr); + _glthread_LOCK_MUTEX(pool->mutex); + + FREE(pool->bufs); + + pb_unmap(pool->buffer); + pb_reference(&pool->buffer, NULL); + + _glthread_UNLOCK_MUTEX(pool->mutex); + + FREE(mgr); +} + + +struct pb_manager * +pool_bufmgr_create(struct pb_manager *provider, + size_t numBufs, + size_t bufSize, + const struct pb_desc *desc) +{ + struct pool_pb_manager *pool; + struct pool_buffer *pool_buf; + size_t i; + + pool = (struct pool_pb_manager *)CALLOC(1, sizeof(*pool)); + if (!pool) + return NULL; + + pool->base.destroy = pool_bufmgr_destroy; + pool->base.create_buffer = pool_bufmgr_create_buffer; + + LIST_INITHEAD(&pool->free); + + pool->numTot = numBufs; + pool->numFree = numBufs; + pool->bufSize = bufSize; + pool->bufAlign = desc->alignment; + + _glthread_INIT_MUTEX(pool->mutex); + + pool->buffer = provider->create_buffer(provider, numBufs*bufSize, desc); + if (!pool->buffer) + goto failure; + + pool->map = pb_map(pool->buffer, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + if(!pool->map) + goto failure; + + pool->bufs = (struct pool_buffer *)CALLOC(numBufs, sizeof(*pool->bufs)); + if (!pool->bufs) + goto failure; + + pool_buf = pool->bufs; + for (i = 0; i < numBufs; ++i) { + pool_buf->base.base.refcount = 0; + pool_buf->base.base.alignment = 0; + pool_buf->base.base.usage = 0; + pool_buf->base.base.size = bufSize; + pool_buf->base.vtbl = &pool_buffer_vtbl; + pool_buf->mgr = pool; + pool_buf->start = i * bufSize; + LIST_ADDTAIL(&pool_buf->head, &pool->free); + pool_buf++; + } + + return SUPER(pool); + +failure: + if(pool->bufs) + FREE(pool->bufs); + if(pool->map) + pb_unmap(pool->buffer); + if(pool->buffer) + pb_reference(&pool->buffer, NULL); + if(pool) + FREE(pool); + return NULL; +} diff --git a/src/gallium/aux/pipebuffer/pb_winsys.c b/src/gallium/aux/pipebuffer/pb_winsys.c new file mode 100644 index 0000000000..978944091f --- /dev/null +++ b/src/gallium/aux/pipebuffer/pb_winsys.c @@ -0,0 +1,170 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Implementation of client buffer (also designated as "user buffers"), which + * are just state-tracker owned data masqueraded as buffers. + * + * \author José Fonseca + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "pb_buffer.h" + + +/** + * User buffers are special buffers that initially reference memory + * held by the user but which may if necessary copy that memory into + * device memory behind the scenes, for submission to hardware. + * + * These are particularly useful when the referenced data is never + * submitted to hardware at all, in the particular case of software + * vertex processing. + */ +struct pb_user_buffer +{ + struct pb_buffer base; + void *data; +}; + + +extern const struct pb_vtbl pb_user_buffer_vtbl; + + +static INLINE struct pb_user_buffer * +pb_user_buffer(struct pb_buffer *buf) +{ + assert(buf); + assert(buf->vtbl == &pb_user_buffer_vtbl); + return (struct pb_user_buffer *)buf; +} + + +static void +pb_user_buffer_destroy(struct pb_buffer *buf) +{ + assert(buf); + FREE(buf); +} + + +static void * +pb_user_buffer_map(struct pb_buffer *buf, + unsigned flags) +{ + return pb_user_buffer(buf)->data; +} + + +static void +pb_user_buffer_unmap(struct pb_buffer *buf) +{ + /* No-op */ +} + + +static void +pb_user_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + *base_buf = buf; + *offset = 0; +} + + +const struct pb_vtbl +pb_user_buffer_vtbl = { + pb_user_buffer_destroy, + pb_user_buffer_map, + pb_user_buffer_unmap, + pb_user_buffer_get_base_buffer +}; + + +static struct pipe_buffer * +pb_winsys_user_buffer_create(struct pipe_winsys *winsys, + void *data, + unsigned bytes) +{ + struct pb_user_buffer *buf = CALLOC_STRUCT(pb_user_buffer); + + if(!buf) + return NULL; + + buf->base.base.refcount = 1; + buf->base.base.size = bytes; + buf->base.base.alignment = 0; + buf->base.base.usage = 0; + + buf->base.vtbl = &pb_user_buffer_vtbl; + buf->data = data; + + return &buf->base.base; +} + + +static void * +pb_winsys_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags) +{ + (void)winsys; + return pb_map(pb_buffer(buf), flags); +} + + +static void +pb_winsys_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + (void)winsys; + pb_unmap(pb_buffer(buf)); +} + + +static void +pb_winsys_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + (void)winsys; + pb_destroy(pb_buffer(buf)); +} + + +void +pb_init_winsys(struct pipe_winsys *winsys) +{ + winsys->user_buffer_create = pb_winsys_user_buffer_create; + winsys->buffer_map = pb_winsys_buffer_map; + winsys->buffer_unmap = pb_winsys_buffer_unmap; + winsys->buffer_destroy = pb_winsys_buffer_destroy; +} diff --git a/src/gallium/aux/tgsi/Makefile b/src/gallium/aux/tgsi/Makefile new file mode 100644 index 0000000000..12a8bd0409 --- /dev/null +++ b/src/gallium/aux/tgsi/Makefile @@ -0,0 +1,3 @@ +default: + cd ../.. ; make + diff --git a/src/gallium/aux/tgsi/exec/Makefile b/src/gallium/aux/tgsi/exec/Makefile new file mode 100644 index 0000000000..eb8b14e0e8 --- /dev/null +++ b/src/gallium/aux/tgsi/exec/Makefile @@ -0,0 +1,3 @@ +default: + cd ../../.. ; make + diff --git a/src/gallium/aux/tgsi/exec/tgsi_exec.c b/src/gallium/aux/tgsi/exec/tgsi_exec.c new file mode 100644 index 0000000000..37e6007068 --- /dev/null +++ b/src/gallium/aux/tgsi/exec/tgsi_exec.c @@ -0,0 +1,2485 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * TGSI interpretor/executor. + * + * Flow control information: + * + * Since we operate on 'quads' (4 pixels or 4 vertices in parallel) + * flow control statements (IF/ELSE/ENDIF, LOOP/ENDLOOP) require special + * care since a condition may be true for some quad components but false + * for other components. + * + * We basically execute all statements (even if they're in the part of + * an IF/ELSE clause that's "not taken") and use a special mask to + * control writing to destination registers. This is the ExecMask. + * See store_dest(). + * + * The ExecMask is computed from three other masks (CondMask, LoopMask and + * ContMask) which are controlled by the flow control instructions (namely: + * (IF/ELSE/ENDIF, LOOP/ENDLOOP and CONT). + * + * + * Authors: + * Michal Krol + * Brian Paul + */ + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/tgsi/util/tgsi_parse.h" +#include "pipe/tgsi/util/tgsi_util.h" +#include "tgsi_exec.h" + +#define TILE_TOP_LEFT 0 +#define TILE_TOP_RIGHT 1 +#define TILE_BOTTOM_LEFT 2 +#define TILE_BOTTOM_RIGHT 3 + +/* + * Shorthand locations of various utility registers (_I = Index, _C = Channel) + */ +#define TEMP_0_I TGSI_EXEC_TEMP_00000000_I +#define TEMP_0_C TGSI_EXEC_TEMP_00000000_C +#define TEMP_7F_I TGSI_EXEC_TEMP_7FFFFFFF_I +#define TEMP_7F_C TGSI_EXEC_TEMP_7FFFFFFF_C +#define TEMP_80_I TGSI_EXEC_TEMP_80000000_I +#define TEMP_80_C TGSI_EXEC_TEMP_80000000_C +#define TEMP_FF_I TGSI_EXEC_TEMP_FFFFFFFF_I +#define TEMP_FF_C TGSI_EXEC_TEMP_FFFFFFFF_C +#define TEMP_1_I TGSI_EXEC_TEMP_ONE_I +#define TEMP_1_C TGSI_EXEC_TEMP_ONE_C +#define TEMP_2_I TGSI_EXEC_TEMP_TWO_I +#define TEMP_2_C TGSI_EXEC_TEMP_TWO_C +#define TEMP_128_I TGSI_EXEC_TEMP_128_I +#define TEMP_128_C TGSI_EXEC_TEMP_128_C +#define TEMP_M128_I TGSI_EXEC_TEMP_MINUS_128_I +#define TEMP_M128_C TGSI_EXEC_TEMP_MINUS_128_C +#define TEMP_KILMASK_I TGSI_EXEC_TEMP_KILMASK_I +#define TEMP_KILMASK_C TGSI_EXEC_TEMP_KILMASK_C +#define TEMP_OUTPUT_I TGSI_EXEC_TEMP_OUTPUT_I +#define TEMP_OUTPUT_C TGSI_EXEC_TEMP_OUTPUT_C +#define TEMP_PRIMITIVE_I TGSI_EXEC_TEMP_PRIMITIVE_I +#define TEMP_PRIMITIVE_C TGSI_EXEC_TEMP_PRIMITIVE_C +#define TEMP_R0 TGSI_EXEC_TEMP_R0 + +#define FOR_EACH_CHANNEL(CHAN)\ + for (CHAN = 0; CHAN < 4; CHAN++) + +#define IS_CHANNEL_ENABLED(INST, CHAN)\ + ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) + +#define IS_CHANNEL_ENABLED2(INST, CHAN)\ + ((INST).FullDstRegisters[1].DstRegister.WriteMask & (1 << (CHAN))) + +#define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\ + FOR_EACH_CHANNEL( CHAN )\ + if (IS_CHANNEL_ENABLED( INST, CHAN )) + +#define FOR_EACH_ENABLED_CHANNEL2(INST, CHAN)\ + FOR_EACH_CHANNEL( CHAN )\ + if (IS_CHANNEL_ENABLED2( INST, CHAN )) + + +/** The execution mask depends on the conditional mask and the loop mask */ +#define UPDATE_EXEC_MASK(MACH) \ + MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask + + +#define CHAN_X 0 +#define CHAN_Y 1 +#define CHAN_Z 2 +#define CHAN_W 3 + + + +static void +tgsi_exec_prepare( struct tgsi_exec_machine *mach ) +{ + struct tgsi_exec_labels *labels = &mach->Labels; + struct tgsi_parse_context parse; + struct tgsi_full_instruction *instructions; + struct tgsi_full_declaration *declarations; + uint maxInstructions = 10, numInstructions = 0; + uint maxDeclarations = 10, numDeclarations = 0; + uint k; + uint instno = 0; + + mach->ImmLimit = 0; + labels->count = 0; + + declarations = (struct tgsi_full_declaration *) + MALLOC( maxDeclarations * sizeof(struct tgsi_full_declaration) ); + + instructions = (struct tgsi_full_instruction *) + MALLOC( maxInstructions * sizeof(struct tgsi_full_instruction) ); + + k = tgsi_parse_init( &parse, mach->Tokens ); + if (k != TGSI_PARSE_OK) { + debug_printf("Problem parsing!\n"); + return; + } + + while( !tgsi_parse_end_of_tokens( &parse ) ) { + uint pointer = parse.Position; + uint i; + + tgsi_parse_token( &parse ); + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + /* save expanded declaration */ + if (numDeclarations == maxDeclarations) { + declarations = REALLOC(declarations, + maxDeclarations + * sizeof(struct tgsi_full_declaration), + (maxDeclarations + 10) + * sizeof(struct tgsi_full_declaration)); + maxDeclarations += 10; + } + memcpy(declarations + numDeclarations, + &parse.FullToken.FullDeclaration, + sizeof(declarations[0])); + numDeclarations++; + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; + assert( size % 4 == 0 ); + assert( mach->ImmLimit + size / 4 <= TGSI_EXEC_NUM_IMMEDIATES ); + + for( i = 0; i < size; i++ ) { + mach->Imms[mach->ImmLimit + i / 4][i % 4] = parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; + } + mach->ImmLimit += size / 4; + } + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + assert( labels->count < 128 ); + + labels->labels[labels->count][0] = instno; + labels->labels[labels->count][1] = pointer; + labels->count++; + + /* save expanded instruction */ + if (numInstructions == maxInstructions) { + instructions = REALLOC(instructions, + maxInstructions + * sizeof(struct tgsi_full_instruction), + (maxInstructions + 10) + * sizeof(struct tgsi_full_instruction)); + maxInstructions += 10; + } + memcpy(instructions + numInstructions, + &parse.FullToken.FullInstruction, + sizeof(instructions[0])); + numInstructions++; + break; + + default: + assert( 0 ); + } + } + tgsi_parse_free (&parse); + + if (mach->Declarations) { + FREE( mach->Declarations ); + } + mach->Declarations = declarations; + mach->NumDeclarations = numDeclarations; + + if (mach->Instructions) { + FREE( mach->Instructions ); + } + mach->Instructions = instructions; + mach->NumInstructions = numInstructions; +} + + +/** + * Initialize machine state by expanding tokens to full instructions, + * allocating temporary storage, setting up constants, etc. + * After this, we can call tgsi_exec_machine_run() many times. + */ +void +tgsi_exec_machine_init( + struct tgsi_exec_machine *mach, + const struct tgsi_token *tokens, + uint numSamplers, + struct tgsi_sampler *samplers) +{ + uint i, k; + struct tgsi_parse_context parse; + +#if 0 + tgsi_dump(tokens, 0); +#endif + + mach->Tokens = tokens; + + mach->Samplers = samplers; + + k = tgsi_parse_init (&parse, mach->Tokens); + if (k != TGSI_PARSE_OK) { + debug_printf( "Problem parsing!\n" ); + return; + } + + mach->Processor = parse.FullHeader.Processor.Processor; + tgsi_parse_free (&parse); + + mach->Temps = (struct tgsi_exec_vector *) tgsi_align_128bit( mach->_Temps); + mach->Addrs = &mach->Temps[TGSI_EXEC_NUM_TEMPS]; + + /* Setup constants. */ + for( i = 0; i < 4; i++ ) { + mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].u[i] = 0x00000000; + mach->Temps[TEMP_7F_I].xyzw[TEMP_7F_C].u[i] = 0x7FFFFFFF; + mach->Temps[TEMP_80_I].xyzw[TEMP_80_C].u[i] = 0x80000000; + mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].u[i] = 0xFFFFFFFF; + mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].f[i] = 1.0f; + mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].f[i] = 2.0f; + mach->Temps[TEMP_128_I].xyzw[TEMP_128_C].f[i] = 128.0f; + mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C].f[i] = -128.0f; + } + + tgsi_exec_prepare( mach ); +} + + +void +tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach) +{ + if (mach->Instructions) { + FREE(mach->Instructions); + mach->Instructions = NULL; + mach->NumInstructions = 0; + } + if (mach->Declarations) { + FREE(mach->Declarations); + mach->Declarations = NULL; + mach->NumDeclarations = 0; + } +} + + +static void +micro_abs( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) fabs( (double) src->f[0] ); + dst->f[1] = (float) fabs( (double) src->f[1] ); + dst->f[2] = (float) fabs( (double) src->f[2] ); + dst->f[3] = (float) fabs( (double) src->f[3] ); +} + +static void +micro_add( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] + src1->f[0]; + dst->f[1] = src0->f[1] + src1->f[1]; + dst->f[2] = src0->f[2] + src1->f[2]; + dst->f[3] = src0->f[3] + src1->f[3]; +} + +static void +micro_iadd( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] + src1->i[0]; + dst->i[1] = src0->i[1] + src1->i[1]; + dst->i[2] = src0->i[2] + src1->i[2]; + dst->i[3] = src0->i[3] + src1->i[3]; +} + +static void +micro_and( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] & src1->u[0]; + dst->u[1] = src0->u[1] & src1->u[1]; + dst->u[2] = src0->u[2] & src1->u[2]; + dst->u[3] = src0->u[3] & src1->u[3]; +} + +static void +micro_ceil( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) ceil( (double) src->f[0] ); + dst->f[1] = (float) ceil( (double) src->f[1] ); + dst->f[2] = (float) ceil( (double) src->f[2] ); + dst->f[3] = (float) ceil( (double) src->f[3] ); +} + +static void +micro_cos( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) cos( (double) src->f[0] ); + dst->f[1] = (float) cos( (double) src->f[1] ); + dst->f[2] = (float) cos( (double) src->f[2] ); + dst->f[3] = (float) cos( (double) src->f[3] ); +} + +static void +micro_ddx( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = + dst->f[1] = + dst->f[2] = + dst->f[3] = src->f[TILE_BOTTOM_RIGHT] - src->f[TILE_BOTTOM_LEFT]; +} + +static void +micro_ddy( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = + dst->f[1] = + dst->f[2] = + dst->f[3] = src->f[TILE_TOP_LEFT] - src->f[TILE_BOTTOM_LEFT]; +} + +static void +micro_div( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] / src1->f[0]; + dst->f[1] = src0->f[1] / src1->f[1]; + dst->f[2] = src0->f[2] / src1->f[2]; + dst->f[3] = src0->f[3] / src1->f[3]; +} + +static void +micro_udiv( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] / src1->u[0]; + dst->u[1] = src0->u[1] / src1->u[1]; + dst->u[2] = src0->u[2] / src1->u[2]; + dst->u[3] = src0->u[3] / src1->u[3]; +} + +static void +micro_eq( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] == src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] == src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] == src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] == src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_ieq( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->i[0] = src0->i[0] == src1->i[0] ? src2->i[0] : src3->i[0]; + dst->i[1] = src0->i[1] == src1->i[1] ? src2->i[1] : src3->i[1]; + dst->i[2] = src0->i[2] == src1->i[2] ? src2->i[2] : src3->i[2]; + dst->i[3] = src0->i[3] == src1->i[3] ? src2->i[3] : src3->i[3]; +} + +static void +micro_exp2( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src) +{ + dst->f[0] = (float) pow( 2.0, (double) src->f[0] ); + dst->f[1] = (float) pow( 2.0, (double) src->f[1] ); + dst->f[2] = (float) pow( 2.0, (double) src->f[2] ); + dst->f[3] = (float) pow( 2.0, (double) src->f[3] ); +} + +static void +micro_f2it( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->i[0] = (int) src->f[0]; + dst->i[1] = (int) src->f[1]; + dst->i[2] = (int) src->f[2]; + dst->i[3] = (int) src->f[3]; +} + +static void +micro_f2ut( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->u[0] = (uint) src->f[0]; + dst->u[1] = (uint) src->f[1]; + dst->u[2] = (uint) src->f[2]; + dst->u[3] = (uint) src->f[3]; +} + +static void +micro_flr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) floor( (double) src->f[0] ); + dst->f[1] = (float) floor( (double) src->f[1] ); + dst->f[2] = (float) floor( (double) src->f[2] ); + dst->f[3] = (float) floor( (double) src->f[3] ); +} + +static void +micro_frc( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = src->f[0] - (float) floor( (double) src->f[0] ); + dst->f[1] = src->f[1] - (float) floor( (double) src->f[1] ); + dst->f[2] = src->f[2] - (float) floor( (double) src->f[2] ); + dst->f[3] = src->f[3] - (float) floor( (double) src->f[3] ); +} + +static void +micro_ge( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] >= src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] >= src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] >= src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] >= src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_i2f( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) src->i[0]; + dst->f[1] = (float) src->i[1]; + dst->f[2] = (float) src->i[2]; + dst->f[3] = (float) src->i[3]; +} + +static void +micro_lg2( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) log( (double) src->f[0] ) * 1.442695f; + dst->f[1] = (float) log( (double) src->f[1] ) * 1.442695f; + dst->f[2] = (float) log( (double) src->f[2] ) * 1.442695f; + dst->f[3] = (float) log( (double) src->f[3] ) * 1.442695f; +} + +static void +micro_lt( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] < src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] < src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] < src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] < src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_ilt( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->i[0] = src0->i[0] < src1->i[0] ? src2->i[0] : src3->i[0]; + dst->i[1] = src0->i[1] < src1->i[1] ? src2->i[1] : src3->i[1]; + dst->i[2] = src0->i[2] < src1->i[2] ? src2->i[2] : src3->i[2]; + dst->i[3] = src0->i[3] < src1->i[3] ? src2->i[3] : src3->i[3]; +} + +static void +micro_ult( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->u[0] = src0->u[0] < src1->u[0] ? src2->u[0] : src3->u[0]; + dst->u[1] = src0->u[1] < src1->u[1] ? src2->u[1] : src3->u[1]; + dst->u[2] = src0->u[2] < src1->u[2] ? src2->u[2] : src3->u[2]; + dst->u[3] = src0->u[3] < src1->u[3] ? src2->u[3] : src3->u[3]; +} + +static void +micro_max( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] > src1->f[0] ? src0->f[0] : src1->f[0]; + dst->f[1] = src0->f[1] > src1->f[1] ? src0->f[1] : src1->f[1]; + dst->f[2] = src0->f[2] > src1->f[2] ? src0->f[2] : src1->f[2]; + dst->f[3] = src0->f[3] > src1->f[3] ? src0->f[3] : src1->f[3]; +} + +static void +micro_imax( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] > src1->i[0] ? src0->i[0] : src1->i[0]; + dst->i[1] = src0->i[1] > src1->i[1] ? src0->i[1] : src1->i[1]; + dst->i[2] = src0->i[2] > src1->i[2] ? src0->i[2] : src1->i[2]; + dst->i[3] = src0->i[3] > src1->i[3] ? src0->i[3] : src1->i[3]; +} + +static void +micro_umax( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] > src1->u[0] ? src0->u[0] : src1->u[0]; + dst->u[1] = src0->u[1] > src1->u[1] ? src0->u[1] : src1->u[1]; + dst->u[2] = src0->u[2] > src1->u[2] ? src0->u[2] : src1->u[2]; + dst->u[3] = src0->u[3] > src1->u[3] ? src0->u[3] : src1->u[3]; +} + +static void +micro_min( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] < src1->f[0] ? src0->f[0] : src1->f[0]; + dst->f[1] = src0->f[1] < src1->f[1] ? src0->f[1] : src1->f[1]; + dst->f[2] = src0->f[2] < src1->f[2] ? src0->f[2] : src1->f[2]; + dst->f[3] = src0->f[3] < src1->f[3] ? src0->f[3] : src1->f[3]; +} + +static void +micro_imin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] < src1->i[0] ? src0->i[0] : src1->i[0]; + dst->i[1] = src0->i[1] < src1->i[1] ? src0->i[1] : src1->i[1]; + dst->i[2] = src0->i[2] < src1->i[2] ? src0->i[2] : src1->i[2]; + dst->i[3] = src0->i[3] < src1->i[3] ? src0->i[3] : src1->i[3]; +} + +static void +micro_umin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] < src1->u[0] ? src0->u[0] : src1->u[0]; + dst->u[1] = src0->u[1] < src1->u[1] ? src0->u[1] : src1->u[1]; + dst->u[2] = src0->u[2] < src1->u[2] ? src0->u[2] : src1->u[2]; + dst->u[3] = src0->u[3] < src1->u[3] ? src0->u[3] : src1->u[3]; +} + +static void +micro_umod( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] % src1->u[0]; + dst->u[1] = src0->u[1] % src1->u[1]; + dst->u[2] = src0->u[2] % src1->u[2]; + dst->u[3] = src0->u[3] % src1->u[3]; +} + +static void +micro_mul( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] * src1->f[0]; + dst->f[1] = src0->f[1] * src1->f[1]; + dst->f[2] = src0->f[2] * src1->f[2]; + dst->f[3] = src0->f[3] * src1->f[3]; +} + +static void +micro_imul( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] * src1->i[0]; + dst->i[1] = src0->i[1] * src1->i[1]; + dst->i[2] = src0->i[2] * src1->i[2]; + dst->i[3] = src0->i[3] * src1->i[3]; +} + +static void +micro_imul64( + union tgsi_exec_channel *dst0, + union tgsi_exec_channel *dst1, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst1->i[0] = src0->i[0] * src1->i[0]; + dst1->i[1] = src0->i[1] * src1->i[1]; + dst1->i[2] = src0->i[2] * src1->i[2]; + dst1->i[3] = src0->i[3] * src1->i[3]; + dst0->i[0] = 0; + dst0->i[1] = 0; + dst0->i[2] = 0; + dst0->i[3] = 0; +} + +static void +micro_umul64( + union tgsi_exec_channel *dst0, + union tgsi_exec_channel *dst1, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst1->u[0] = src0->u[0] * src1->u[0]; + dst1->u[1] = src0->u[1] * src1->u[1]; + dst1->u[2] = src0->u[2] * src1->u[2]; + dst1->u[3] = src0->u[3] * src1->u[3]; + dst0->u[0] = 0; + dst0->u[1] = 0; + dst0->u[2] = 0; + dst0->u[3] = 0; +} + +static void +micro_movc( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2 ) +{ + dst->u[0] = src0->u[0] ? src1->u[0] : src2->u[0]; + dst->u[1] = src0->u[1] ? src1->u[1] : src2->u[1]; + dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2]; + dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3]; +} + +static void +micro_neg( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = -src->f[0]; + dst->f[1] = -src->f[1]; + dst->f[2] = -src->f[2]; + dst->f[3] = -src->f[3]; +} + +static void +micro_ineg( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->i[0] = -src->i[0]; + dst->i[1] = -src->i[1]; + dst->i[2] = -src->i[2]; + dst->i[3] = -src->i[3]; +} + +static void +micro_not( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->u[0] = ~src->u[0]; + dst->u[1] = ~src->u[1]; + dst->u[2] = ~src->u[2]; + dst->u[3] = ~src->u[3]; +} + +static void +micro_or( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] | src1->u[0]; + dst->u[1] = src0->u[1] | src1->u[1]; + dst->u[2] = src0->u[2] | src1->u[2]; + dst->u[3] = src0->u[3] | src1->u[3]; +} + +static void +micro_pow( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = (float) pow( (double) src0->f[0], (double) src1->f[0] ); + dst->f[1] = (float) pow( (double) src0->f[1], (double) src1->f[1] ); + dst->f[2] = (float) pow( (double) src0->f[2], (double) src1->f[2] ); + dst->f[3] = (float) pow( (double) src0->f[3], (double) src1->f[3] ); +} + +static void +micro_rnd( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) floor( (double) (src->f[0] + 0.5f) ); + dst->f[1] = (float) floor( (double) (src->f[1] + 0.5f) ); + dst->f[2] = (float) floor( (double) (src->f[2] + 0.5f) ); + dst->f[3] = (float) floor( (double) (src->f[3] + 0.5f) ); +} + +static void +micro_shl( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] << src1->i[0]; + dst->i[1] = src0->i[1] << src1->i[1]; + dst->i[2] = src0->i[2] << src1->i[2]; + dst->i[3] = src0->i[3] << src1->i[3]; +} + +static void +micro_ishr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] >> src1->i[0]; + dst->i[1] = src0->i[1] >> src1->i[1]; + dst->i[2] = src0->i[2] >> src1->i[2]; + dst->i[3] = src0->i[3] >> src1->i[3]; +} + +static void +micro_trunc( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0 ) +{ + dst->f[0] = (float) (int) src0->f[0]; + dst->f[1] = (float) (int) src0->f[1]; + dst->f[2] = (float) (int) src0->f[2]; + dst->f[3] = (float) (int) src0->f[3]; +} + +static void +micro_ushr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] >> src1->u[0]; + dst->u[1] = src0->u[1] >> src1->u[1]; + dst->u[2] = src0->u[2] >> src1->u[2]; + dst->u[3] = src0->u[3] >> src1->u[3]; +} + +static void +micro_sin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) sin( (double) src->f[0] ); + dst->f[1] = (float) sin( (double) src->f[1] ); + dst->f[2] = (float) sin( (double) src->f[2] ); + dst->f[3] = (float) sin( (double) src->f[3] ); +} + +static void +micro_sqrt( union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) sqrt( (double) src->f[0] ); + dst->f[1] = (float) sqrt( (double) src->f[1] ); + dst->f[2] = (float) sqrt( (double) src->f[2] ); + dst->f[3] = (float) sqrt( (double) src->f[3] ); +} + +static void +micro_sub( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] - src1->f[0]; + dst->f[1] = src0->f[1] - src1->f[1]; + dst->f[2] = src0->f[2] - src1->f[2]; + dst->f[3] = src0->f[3] - src1->f[3]; +} + +static void +micro_u2f( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) src->u[0]; + dst->f[1] = (float) src->u[1]; + dst->f[2] = (float) src->u[2]; + dst->f[3] = (float) src->u[3]; +} + +static void +micro_xor( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] ^ src1->u[0]; + dst->u[1] = src0->u[1] ^ src1->u[1]; + dst->u[2] = src0->u[2] ^ src1->u[2]; + dst->u[3] = src0->u[3] ^ src1->u[3]; +} + +static void +fetch_src_file_channel( + const struct tgsi_exec_machine *mach, + const uint file, + const uint swizzle, + const union tgsi_exec_channel *index, + union tgsi_exec_channel *chan ) +{ + switch( swizzle ) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + switch( file ) { + case TGSI_FILE_CONSTANT: + chan->f[0] = mach->Consts[index->i[0]][swizzle]; + chan->f[1] = mach->Consts[index->i[1]][swizzle]; + chan->f[2] = mach->Consts[index->i[2]][swizzle]; + chan->f[3] = mach->Consts[index->i[3]][swizzle]; + break; + + case TGSI_FILE_INPUT: + chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Inputs[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_TEMPORARY: + chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Temps[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_IMMEDIATE: + assert( index->i[0] < (int) mach->ImmLimit ); + chan->f[0] = mach->Imms[index->i[0]][swizzle]; + assert( index->i[1] < (int) mach->ImmLimit ); + chan->f[1] = mach->Imms[index->i[1]][swizzle]; + assert( index->i[2] < (int) mach->ImmLimit ); + chan->f[2] = mach->Imms[index->i[2]][swizzle]; + assert( index->i[3] < (int) mach->ImmLimit ); + chan->f[3] = mach->Imms[index->i[3]][swizzle]; + break; + + case TGSI_FILE_ADDRESS: + chan->u[0] = mach->Addrs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Addrs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Addrs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Addrs[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_OUTPUT: + /* vertex/fragment output vars can be read too */ + chan->u[0] = mach->Outputs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Outputs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Outputs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Outputs[index->i[3]].xyzw[swizzle].u[3]; + break; + + default: + assert( 0 ); + } + break; + + case TGSI_EXTSWIZZLE_ZERO: + *chan = mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]; + break; + + case TGSI_EXTSWIZZLE_ONE: + *chan = mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]; + break; + + default: + assert( 0 ); + } +} + +static void +fetch_source( + const struct tgsi_exec_machine *mach, + union tgsi_exec_channel *chan, + const struct tgsi_full_src_register *reg, + const uint chan_index ) +{ + union tgsi_exec_channel index; + uint swizzle; + + index.i[0] = + index.i[1] = + index.i[2] = + index.i[3] = reg->SrcRegister.Index; + + if (reg->SrcRegister.Indirect) { + union tgsi_exec_channel index2; + union tgsi_exec_channel indir_index; + + index2.i[0] = + index2.i[1] = + index2.i[2] = + index2.i[3] = reg->SrcRegisterInd.Index; + + swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterInd, CHAN_X ); + fetch_src_file_channel( + mach, + reg->SrcRegisterInd.File, + swizzle, + &index2, + &indir_index ); + + index.i[0] += indir_index.i[0]; + index.i[1] += indir_index.i[1]; + index.i[2] += indir_index.i[2]; + index.i[3] += indir_index.i[3]; + } + + if( reg->SrcRegister.Dimension ) { + switch( reg->SrcRegister.File ) { + case TGSI_FILE_INPUT: + index.i[0] *= 17; + index.i[1] *= 17; + index.i[2] *= 17; + index.i[3] *= 17; + break; + case TGSI_FILE_CONSTANT: + index.i[0] *= 4096; + index.i[1] *= 4096; + index.i[2] *= 4096; + index.i[3] *= 4096; + break; + default: + assert( 0 ); + } + + index.i[0] += reg->SrcRegisterDim.Index; + index.i[1] += reg->SrcRegisterDim.Index; + index.i[2] += reg->SrcRegisterDim.Index; + index.i[3] += reg->SrcRegisterDim.Index; + + if (reg->SrcRegisterDim.Indirect) { + union tgsi_exec_channel index2; + union tgsi_exec_channel indir_index; + + index2.i[0] = + index2.i[1] = + index2.i[2] = + index2.i[3] = reg->SrcRegisterDimInd.Index; + + swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterDimInd, CHAN_X ); + fetch_src_file_channel( + mach, + reg->SrcRegisterDimInd.File, + swizzle, + &index2, + &indir_index ); + + index.i[0] += indir_index.i[0]; + index.i[1] += indir_index.i[1]; + index.i[2] += indir_index.i[2]; + index.i[3] += indir_index.i[3]; + } + } + + swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); + fetch_src_file_channel( + mach, + reg->SrcRegister.File, + swizzle, + &index, + chan ); + + switch (tgsi_util_get_full_src_register_sign_mode( reg, chan_index )) { + case TGSI_UTIL_SIGN_CLEAR: + micro_abs( chan, chan ); + break; + + case TGSI_UTIL_SIGN_SET: + micro_abs( chan, chan ); + micro_neg( chan, chan ); + break; + + case TGSI_UTIL_SIGN_TOGGLE: + micro_neg( chan, chan ); + break; + + case TGSI_UTIL_SIGN_KEEP: + break; + } + + if (reg->SrcRegisterExtMod.Complement) { + micro_sub( chan, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], chan ); + } +} + +static void +store_dest( + struct tgsi_exec_machine *mach, + const union tgsi_exec_channel *chan, + const struct tgsi_full_dst_register *reg, + const struct tgsi_full_instruction *inst, + uint chan_index ) +{ + union tgsi_exec_channel *dst; + + switch( reg->DstRegister.File ) { + case TGSI_FILE_NULL: + return; + + case TGSI_FILE_OUTPUT: + dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] + + reg->DstRegister.Index].xyzw[chan_index]; + break; + + case TGSI_FILE_TEMPORARY: + dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index]; + break; + + case TGSI_FILE_ADDRESS: + dst = &mach->Addrs[reg->DstRegister.Index].xyzw[chan_index]; + break; + + default: + assert( 0 ); + return; + } + + switch (inst->Instruction.Saturate) + { + case TGSI_SAT_NONE: + if (mach->ExecMask & 0x1) + dst->i[0] = chan->i[0]; + if (mach->ExecMask & 0x2) + dst->i[1] = chan->i[1]; + if (mach->ExecMask & 0x4) + dst->i[2] = chan->i[2]; + if (mach->ExecMask & 0x8) + dst->i[3] = chan->i[3]; + break; + + case TGSI_SAT_ZERO_ONE: + /* XXX need to obey ExecMask here */ + micro_max(dst, chan, &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]); + micro_min(dst, dst, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]); + break; + + case TGSI_SAT_MINUS_PLUS_ONE: + assert( 0 ); + break; + + default: + assert( 0 ); + } +} + +#define FETCH(VAL,INDEX,CHAN)\ + fetch_source (mach, VAL, &inst->FullSrcRegisters[INDEX], CHAN) + +#define STORE(VAL,INDEX,CHAN)\ + store_dest (mach, VAL, &inst->FullDstRegisters[INDEX], inst, CHAN ) + + +/** + * Execute ARB-style KIL which is predicated by a src register. + * Kill fragment if any of the four values is less than zero. + */ +static void +exec_kilp(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + uint uniquemask; + uint chan_index; + uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ + union tgsi_exec_channel r[1]; + + /* This mask stores component bits that were already tested. Note that + * we test if the value is less than zero, so 1.0 and 0.0 need not to be + * tested. */ + uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); + + for (chan_index = 0; chan_index < 4; chan_index++) + { + uint swizzle; + uint i; + + /* unswizzle channel */ + swizzle = tgsi_util_get_full_src_register_extswizzle ( + &inst->FullSrcRegisters[0], + chan_index); + + /* check if the component has not been already tested */ + if (uniquemask & (1 << swizzle)) + continue; + uniquemask |= 1 << swizzle; + + FETCH(&r[0], 0, chan_index); + for (i = 0; i < 4; i++) + if (r[0].f[i] < 0.0f) + kilmask |= 1 << i; + } + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; +} + + +/* + * Fetch a texel using STR texture coordinates. + */ +static void +fetch_texel( struct tgsi_sampler *sampler, + const union tgsi_exec_channel *s, + const union tgsi_exec_channel *t, + const union tgsi_exec_channel *p, + float lodbias, /* XXX should be float[4] */ + union tgsi_exec_channel *r, + union tgsi_exec_channel *g, + union tgsi_exec_channel *b, + union tgsi_exec_channel *a ) +{ + uint j; + float rgba[NUM_CHANNELS][QUAD_SIZE]; + + sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, rgba); + + for (j = 0; j < 4; j++) { + r->f[j] = rgba[0][j]; + g->f[j] = rgba[1][j]; + b->f[j] = rgba[2][j]; + a->f[j] = rgba[3][j]; + } +} + + +static void +exec_tex(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst, + boolean biasLod) +{ + const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; + union tgsi_exec_channel r[8]; + uint chan_index; + float lodBias; + + /* debug_printf("Sampler %u unit %u\n", sampler, unit); */ + + switch (inst->InstructionExtTexture.Texture) { + case TGSI_TEXTURE_1D: + + FETCH(&r[0], 0, CHAN_X); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[1], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[1] ); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } + + if (biasLod) { + FETCH(&r[1], 0, CHAN_W); + lodBias = r[2].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], NULL, NULL, lodBias, /* S, T, P, BIAS */ + &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */ + break; + + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_RECT: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[3], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[3] ); + micro_div( &r[1], &r[1], &r[3] ); + micro_div( &r[2], &r[2], &r[3] ); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } + + if (biasLod) { + FETCH(&r[3], 0, CHAN_W); + lodBias = r[3].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], &r[1], &r[2], lodBias, /* inputs */ + &r[0], &r[1], &r[2], &r[3]); /* outputs */ + break; + + case TGSI_TEXTURE_3D: + case TGSI_TEXTURE_CUBE: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[3], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[3] ); + micro_div( &r[1], &r[1], &r[3] ); + micro_div( &r[2], &r[2], &r[3] ); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } + + if (biasLod) { + FETCH(&r[3], 0, CHAN_W); + lodBias = r[3].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], &r[1], &r[2], lodBias, + &r[0], &r[1], &r[2], &r[3]); + break; + + default: + assert (0); + } + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[chan_index], 0, chan_index ); + } +} + + +/** + * Evaluate a constant-valued coefficient at the position of the + * current quad. + */ +static void +eval_constant_coef( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + mach->Inputs[attrib].xyzw[chan].f[i] = mach->InterpCoefs[attrib].a0[chan]; + } +} + +/** + * Evaluate a linear-valued coefficient at the position of the + * current quad. + */ +static void +eval_linear_coef( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + const float x = mach->QuadPos.xyzw[0].f[0]; + const float y = mach->QuadPos.xyzw[1].f[0]; + const float dadx = mach->InterpCoefs[attrib].dadx[chan]; + const float dady = mach->InterpCoefs[attrib].dady[chan]; + const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; + mach->Inputs[attrib].xyzw[chan].f[0] = a0; + mach->Inputs[attrib].xyzw[chan].f[1] = a0 + dadx; + mach->Inputs[attrib].xyzw[chan].f[2] = a0 + dady; + mach->Inputs[attrib].xyzw[chan].f[3] = a0 + dadx + dady; +} + +/** + * Evaluate a perspective-valued coefficient at the position of the + * current quad. + */ +static void +eval_perspective_coef( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + const float x = mach->QuadPos.xyzw[0].f[0]; + const float y = mach->QuadPos.xyzw[1].f[0]; + const float dadx = mach->InterpCoefs[attrib].dadx[chan]; + const float dady = mach->InterpCoefs[attrib].dady[chan]; + const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; + const float *w = mach->QuadPos.xyzw[3].f; + /* divide by W here */ + mach->Inputs[attrib].xyzw[chan].f[0] = a0 / w[0]; + mach->Inputs[attrib].xyzw[chan].f[1] = (a0 + dadx) / w[1]; + mach->Inputs[attrib].xyzw[chan].f[2] = (a0 + dady) / w[2]; + mach->Inputs[attrib].xyzw[chan].f[3] = (a0 + dadx + dady) / w[3]; +} + + +typedef void (* eval_coef_func)( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ); + +static void +exec_declaration( + struct tgsi_exec_machine *mach, + const struct tgsi_full_declaration *decl ) +{ + if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { + if( decl->Declaration.File == TGSI_FILE_INPUT ) { + unsigned first, last, mask; + eval_coef_func eval; + + assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); + + first = decl->u.DeclarationRange.First; + last = decl->u.DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + switch( decl->Interpolation.Interpolate ) { + case TGSI_INTERPOLATE_CONSTANT: + eval = eval_constant_coef; + break; + + case TGSI_INTERPOLATE_LINEAR: + eval = eval_linear_coef; + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + eval = eval_perspective_coef; + break; + + default: + assert( 0 ); + } + + if( mask == TGSI_WRITEMASK_XYZW ) { + unsigned i, j; + + for( i = first; i <= last; i++ ) { + for( j = 0; j < NUM_CHANNELS; j++ ) { + eval( mach, i, j ); + } + } + } + else { + unsigned i, j; + + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + for( i = first; i <= last; i++ ) { + eval( mach, i, j ); + } + } + } + } + } + } +} + +static void +exec_instruction( + struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst, + int *pc ) +{ + uint chan_index; + union tgsi_exec_channel r[8]; + + (*pc)++; + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_f2it( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOV: + /* TGSI_OPCODE_SWZ */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_LIT: + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y ) || IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[0], 0, CHAN_X ); + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + micro_max( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, CHAN_Y ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[1], 0, CHAN_Y ); + micro_max( &r[1], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + + FETCH( &r[2], 0, CHAN_W ); + micro_min( &r[2], &r[2], &mach->Temps[TEMP_128_I].xyzw[TEMP_128_C] ); + micro_max( &r[2], &r[2], &mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C] ); + micro_pow( &r[1], &r[1], &r[2] ); + micro_lt( &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, CHAN_Z ); + } + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_RCP: + /* TGSI_OPCODE_RECIP */ + FETCH( &r[0], 0, CHAN_X ); + micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_RSQ: + /* TGSI_OPCODE_RECIPSQRT */ + FETCH( &r[0], 0, CHAN_X ); + micro_sqrt( &r[0], &r[0] ); + micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXP: + assert (0); + break; + + case TGSI_OPCODE_LOG: + assert (0); + break; + + case TGSI_OPCODE_MUL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + micro_mul( &r[0], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_ADD: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_add( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP3: + /* TGSI_OPCODE_DOT3 */ + FETCH( &r[0], 0, CHAN_X ); + FETCH( &r[1], 1, CHAN_X ); + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Y ); + FETCH( &r[2], 1, CHAN_Y ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Z ); + FETCH( &r[2], 1, CHAN_Z ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP4: + /* TGSI_OPCODE_DOT4 */ + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 1, CHAN_Y); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Z); + FETCH(&r[2], 1, CHAN_Z); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_W); + FETCH(&r[2], 1, CHAN_W); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DST: + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + FETCH( &r[0], 0, CHAN_Y ); + FETCH( &r[1], 1, CHAN_Y); + micro_mul( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, CHAN_Y ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[0], 0, CHAN_Z ); + STORE( &r[0], 0, CHAN_Z ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + FETCH( &r[0], 1, CHAN_W ); + STORE( &r[0], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MIN: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + /* XXX use micro_min()?? */ + micro_lt( &r[0], &r[0], &r[1], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_MAX: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + /* XXX use micro_max()?? */ + micro_lt( &r[0], &r[0], &r[1], &r[1], &r[0] ); + + STORE(&r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLT: + /* TGSI_OPCODE_SETLT */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SGE: + /* TGSI_OPCODE_SETGE */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_ge( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MAD: + /* TGSI_OPCODE_MADD */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_mul( &r[0], &r[0], &r[1] ); + FETCH( &r[1], 2, chan_index ); + micro_add( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SUB: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + micro_sub( &r[0], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_LERP: + /* TGSI_OPCODE_LRP */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + FETCH(&r[2], 2, chan_index); + + micro_sub( &r[1], &r[1], &r[2] ); + micro_mul( &r[0], &r[0], &r[1] ); + micro_add( &r[0], &r[0], &r[2] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_CND: + assert (0); + break; + + case TGSI_OPCODE_CND0: + assert (0); + break; + + case TGSI_OPCODE_DOT2ADD: + /* TGSI_OPCODE_DP2A */ + assert (0); + break; + + case TGSI_OPCODE_INDEX: + assert (0); + break; + + case TGSI_OPCODE_NEGATE: + assert (0); + break; + + case TGSI_OPCODE_FRAC: + /* TGSI_OPCODE_FRC */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_frc( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_CLAMP: + assert (0); + break; + + case TGSI_OPCODE_FLOOR: + /* TGSI_OPCODE_FLR */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_flr( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_ROUND: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_rnd( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXPBASE2: + /* TGSI_OPCODE_EX2 */ + FETCH(&r[0], 0, CHAN_X); + + micro_pow( &r[0], &mach->Temps[TEMP_2_I].xyzw[TEMP_2_C], &r[0] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_LOGBASE2: + /* TGSI_OPCODE_LG2 */ + FETCH( &r[0], 0, CHAN_X ); + micro_lg2( &r[0], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_POWER: + /* TGSI_OPCODE_POW */ + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_pow( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_CROSSPRODUCT: + /* TGSI_OPCODE_XPD */ + FETCH(&r[0], 0, CHAN_Y); + FETCH(&r[1], 1, CHAN_Z); + + micro_mul( &r[2], &r[0], &r[1] ); + + FETCH(&r[3], 0, CHAN_Z); + FETCH(&r[4], 1, CHAN_Y); + + micro_mul( &r[5], &r[3], &r[4] ); + micro_sub( &r[2], &r[2], &r[5] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &r[2], 0, CHAN_X ); + } + + FETCH(&r[2], 1, CHAN_X); + + micro_mul( &r[3], &r[3], &r[2] ); + + FETCH(&r[5], 0, CHAN_X); + + micro_mul( &r[1], &r[1], &r[5] ); + micro_sub( &r[3], &r[3], &r[1] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + STORE( &r[3], 0, CHAN_Y ); + } + + micro_mul( &r[5], &r[5], &r[4] ); + micro_mul( &r[0], &r[0], &r[2] ); + micro_sub( &r[5], &r[5], &r[0] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + STORE( &r[5], 0, CHAN_Z ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MULTIPLYMATRIX: + assert (0); + break; + + case TGSI_OPCODE_ABS: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + + micro_abs( &r[0], &r[0] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_RCC: + assert (0); + break; + + case TGSI_OPCODE_DPH: + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 1, CHAN_Y); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Z); + FETCH(&r[2], 1, CHAN_Z); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 1, CHAN_W); + + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_COS: + FETCH(&r[0], 0, CHAN_X); + + micro_cos( &r[0], &r[0] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDX: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_ddx( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDY: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_ddy( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_KILP: + exec_kilp (mach, inst); + break; + + case TGSI_OPCODE_KIL: + /* for enabled ExecMask bits, set the killed bit */ + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= mach->ExecMask; + break; + + case TGSI_OPCODE_PK2H: + assert (0); + break; + + case TGSI_OPCODE_PK2US: + assert (0); + break; + + case TGSI_OPCODE_PK4B: + assert (0); + break; + + case TGSI_OPCODE_PK4UB: + assert (0); + break; + + case TGSI_OPCODE_RFL: + assert (0); + break; + + case TGSI_OPCODE_SEQ: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_eq( &r[0], &r[0], &r[1], + &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], + &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SFL: + assert (0); + break; + + case TGSI_OPCODE_SGT: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SIN: + FETCH( &r[0], 0, CHAN_X ); + micro_sin( &r[0], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLE: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_ge( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SNE: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_eq( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_STR: + assert (0); + break; + + case TGSI_OPCODE_TEX: + /* simple texture lookup */ + /* src[0] = texcoord */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, FALSE); + break; + + case TGSI_OPCODE_TXB: + /* Texture lookup with lod bias */ + /* src[0] = texcoord (src[0].w = LOD bias) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, TRUE); + break; + + case TGSI_OPCODE_TXD: + /* Texture lookup with explict partial derivatives */ + /* src[0] = texcoord */ + /* src[1] = d[strq]/dx */ + /* src[2] = d[strq]/dy */ + /* src[3] = sampler unit */ + assert (0); + break; + + case TGSI_OPCODE_TXL: + /* Texture lookup with explit LOD */ + /* src[0] = texcoord (src[0].w = LOD) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, TRUE); + break; + + case TGSI_OPCODE_UP2H: + assert (0); + break; + + case TGSI_OPCODE_UP2US: + assert (0); + break; + + case TGSI_OPCODE_UP4B: + assert (0); + break; + + case TGSI_OPCODE_UP4UB: + assert (0); + break; + + case TGSI_OPCODE_X2D: + assert (0); + break; + + case TGSI_OPCODE_ARA: + assert (0); + break; + + case TGSI_OPCODE_ARR: + assert (0); + break; + + case TGSI_OPCODE_BRA: + assert (0); + break; + + case TGSI_OPCODE_CAL: + /* skip the call if no execution channels are enabled */ + if (mach->ExecMask) { + /* do the call */ + + /* push the Cond, Loop, Cont stacks */ + assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); + mach->CondStack[mach->CondStackTop++] = mach->CondMask; + assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; + assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->ContStack[mach->ContStackTop++] = mach->ContMask; + + assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING); + mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask; + + /* note that PC was already incremented above */ + mach->CallStack[mach->CallStackTop++] = *pc; + *pc = inst->InstructionExtLabel.Label; + } + break; + + case TGSI_OPCODE_RET: + mach->FuncMask &= ~mach->ExecMask; + UPDATE_EXEC_MASK(mach); + + if (mach->ExecMask == 0x0) { + /* really return now (otherwise, keep executing */ + + if (mach->CallStackTop == 0) { + /* returning from main() */ + *pc = -1; + return; + } + *pc = mach->CallStack[--mach->CallStackTop]; + + /* pop the Cond, Loop, Cont stacks */ + assert(mach->CondStackTop > 0); + mach->CondMask = mach->CondStack[--mach->CondStackTop]; + assert(mach->LoopStackTop > 0); + mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[--mach->ContStackTop]; + assert(mach->FuncStackTop > 0); + mach->FuncMask = mach->FuncStack[--mach->FuncStackTop]; + + UPDATE_EXEC_MASK(mach); + } + break; + + case TGSI_OPCODE_SSG: + assert (0); + break; + + case TGSI_OPCODE_CMP: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + FETCH(&r[2], 2, chan_index); + + micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_SCS: + if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) || IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + FETCH( &r[0], 0, CHAN_X ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) ) { + micro_cos( &r[1], &r[0] ); + STORE( &r[1], 0, CHAN_X ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + micro_sin( &r[1], &r[0] ); + STORE( &r[1], 0, CHAN_Y ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + STORE( &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], 0, CHAN_Z ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_W ) ) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_NRM: + assert (0); + break; + + case TGSI_OPCODE_DIV: + assert( 0 ); + break; + + case TGSI_OPCODE_DP2: + FETCH( &r[0], 0, CHAN_X ); + FETCH( &r[1], 1, CHAN_X ); + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Y ); + FETCH( &r[2], 1, CHAN_Y ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_IF: + /* push CondMask */ + assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); + mach->CondStack[mach->CondStackTop++] = mach->CondMask; + FETCH( &r[0], 0, CHAN_X ); + /* update CondMask */ + if( ! r[0].u[0] ) { + mach->CondMask &= ~0x1; + } + if( ! r[0].u[1] ) { + mach->CondMask &= ~0x2; + } + if( ! r[0].u[2] ) { + mach->CondMask &= ~0x4; + } + if( ! r[0].u[3] ) { + mach->CondMask &= ~0x8; + } + UPDATE_EXEC_MASK(mach); + /* Todo: If CondMask==0, jump to ELSE */ + break; + + case TGSI_OPCODE_ELSE: + /* invert CondMask wrt previous mask */ + { + uint prevMask; + assert(mach->CondStackTop > 0); + prevMask = mach->CondStack[mach->CondStackTop - 1]; + mach->CondMask = ~mach->CondMask & prevMask; + UPDATE_EXEC_MASK(mach); + /* Todo: If CondMask==0, jump to ENDIF */ + } + break; + + case TGSI_OPCODE_ENDIF: + /* pop CondMask */ + assert(mach->CondStackTop > 0); + mach->CondMask = mach->CondStack[--mach->CondStackTop]; + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_END: + /* halt execution */ + *pc = -1; + break; + + case TGSI_OPCODE_REP: + assert (0); + break; + + case TGSI_OPCODE_ENDREP: + assert (0); + break; + + case TGSI_OPCODE_PUSHA: + assert (0); + break; + + case TGSI_OPCODE_POPA: + assert (0); + break; + + case TGSI_OPCODE_CEIL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_ceil( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_I2F: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_i2f( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_NOT: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_not( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_TRUNC: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_trunc( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SHL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_shl( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SHR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_ishr( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_AND: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_and( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_OR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_or( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOD: + assert (0); + break; + + case TGSI_OPCODE_XOR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_xor( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SAD: + assert (0); + break; + + case TGSI_OPCODE_TXF: + assert (0); + break; + + case TGSI_OPCODE_TXQ: + assert (0); + break; + + case TGSI_OPCODE_EMIT: + mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16; + mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++; + break; + + case TGSI_OPCODE_ENDPRIM: + mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++; + mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0; + break; + + case TGSI_OPCODE_LOOP: + /* fall-through (for now) */ + case TGSI_OPCODE_BGNLOOP2: + /* push LoopMask and ContMasks */ + assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; + assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->ContStack[mach->ContStackTop++] = mach->ContMask; + break; + + case TGSI_OPCODE_ENDLOOP: + /* fall-through (for now at least) */ + case TGSI_OPCODE_ENDLOOP2: + /* Restore ContMask, but don't pop */ + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[mach->ContStackTop - 1]; + if (mach->LoopMask) { + /* repeat loop: jump to instruction just past BGNLOOP */ + *pc = inst->InstructionExtLabel.Label + 1; + } + else { + /* exit loop: pop LoopMask */ + assert(mach->LoopStackTop > 0); + mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; + /* pop ContMask */ + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[--mach->ContStackTop]; + } + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_BRK: + /* turn off loop channels for each enabled exec channel */ + mach->LoopMask &= ~mach->ExecMask; + /* Todo: if mach->LoopMask == 0, jump to end of loop */ + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_CONT: + /* turn off cont channels for each enabled exec channel */ + mach->ContMask &= ~mach->ExecMask; + /* Todo: if mach->LoopMask == 0, jump to end of loop */ + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_BGNSUB: + /* no-op */ + break; + + case TGSI_OPCODE_ENDSUB: + /* no-op */ + break; + + case TGSI_OPCODE_NOISE1: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE2: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE3: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE4: + assert( 0 ); + break; + + case TGSI_OPCODE_NOP: + break; + + default: + assert( 0 ); + } +} + + +/** + * Run TGSI interpreter. + * \return bitmask of "alive" quad components + */ +uint +tgsi_exec_machine_run( struct tgsi_exec_machine *mach ) +{ + uint i; + int pc = 0; + + mach->CondMask = 0xf; + mach->LoopMask = 0xf; + mach->ContMask = 0xf; + mach->FuncMask = 0xf; + mach->ExecMask = 0xf; + + mach->CondStackTop = 0; /* temporarily subvert this assertion */ + assert(mach->CondStackTop == 0); + assert(mach->LoopStackTop == 0); + assert(mach->ContStackTop == 0); + assert(mach->CallStackTop == 0); + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0; + mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0; + + if( mach->Processor == TGSI_PROCESSOR_GEOMETRY ) { + mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0] = 0; + mach->Primitives[0] = 0; + } + + + /* execute declarations (interpolants) */ + for (i = 0; i < mach->NumDeclarations; i++) { + exec_declaration( mach, mach->Declarations+i ); + } + + /* execute instructions, until pc is set to -1 */ + while (pc != -1) { + assert(pc < mach->NumInstructions); + exec_instruction( mach, mach->Instructions + pc, &pc ); + } + +#if 0 + /* we scale from floats in [0,1] to Zbuffer ints in sp_quad_depth_test.c */ + if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) { + /* + * Scale back depth component. + */ + for (i = 0; i < 4; i++) + mach->Outputs[0].xyzw[2].f[i] *= ctx->DrawBuffer->_DepthMaxF; + } +#endif + + return ~mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0]; +} + + diff --git a/src/gallium/aux/tgsi/exec/tgsi_exec.h b/src/gallium/aux/tgsi/exec/tgsi_exec.h new file mode 100644 index 0000000000..1fb66ee960 --- /dev/null +++ b/src/gallium/aux/tgsi/exec/tgsi_exec.h @@ -0,0 +1,239 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#if !defined TGSI_EXEC_H +#define TGSI_EXEC_H + +#include "pipe/p_compiler.h" + +#if defined __cplusplus +extern "C" { +#endif + +#define NUM_CHANNELS 4 /* R,G,B,A */ +#define QUAD_SIZE 4 /* 4 pixel/quad */ + +/** + * Registers may be treated as float, signed int or unsigned int. + */ +union tgsi_exec_channel +{ + float f[QUAD_SIZE]; + int i[QUAD_SIZE]; + unsigned u[QUAD_SIZE]; +}; + +/** + * A vector[RGBA] of channels[4 pixels] + */ +struct tgsi_exec_vector +{ + union tgsi_exec_channel xyzw[NUM_CHANNELS]; +}; + +/** + * For fragment programs, information for computing fragment input + * values from plane equation of the triangle/line. + */ +struct tgsi_interp_coef +{ + float a0[NUM_CHANNELS]; /* in an xyzw layout */ + float dadx[NUM_CHANNELS]; + float dady[NUM_CHANNELS]; +}; + + +struct softpipe_tile_cache; /**< Opaque to TGSI */ + +/** + * Information for sampling textures, which must be implemented + * by code outside the TGSI executor. + */ +struct tgsi_sampler +{ + const struct pipe_sampler_state *state; + struct pipe_texture *texture; + /** Get samples for four fragments in a quad */ + void (*get_samples)(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]); + void *pipe; /*XXX temporary*/ + struct softpipe_tile_cache *cache; +}; + +/** + * For branching/calling subroutines. + */ +struct tgsi_exec_labels +{ + unsigned labels[128][2]; + unsigned count; +}; + +/* + * Locations of various utility registers (_I = Index, _C = Channel) + */ +#define TGSI_EXEC_TEMP_00000000_I 32 +#define TGSI_EXEC_TEMP_00000000_C 0 + +#define TGSI_EXEC_TEMP_7FFFFFFF_I 32 +#define TGSI_EXEC_TEMP_7FFFFFFF_C 1 + +#define TGSI_EXEC_TEMP_80000000_I 32 +#define TGSI_EXEC_TEMP_80000000_C 2 + +#define TGSI_EXEC_TEMP_FFFFFFFF_I 32 +#define TGSI_EXEC_TEMP_FFFFFFFF_C 3 + +#define TGSI_EXEC_TEMP_ONE_I 33 +#define TGSI_EXEC_TEMP_ONE_C 0 + +#define TGSI_EXEC_TEMP_TWO_I 33 +#define TGSI_EXEC_TEMP_TWO_C 1 + +#define TGSI_EXEC_TEMP_128_I 33 +#define TGSI_EXEC_TEMP_128_C 2 + +#define TGSI_EXEC_TEMP_MINUS_128_I 33 +#define TGSI_EXEC_TEMP_MINUS_128_C 3 + +#define TGSI_EXEC_TEMP_KILMASK_I 34 +#define TGSI_EXEC_TEMP_KILMASK_C 0 + +#define TGSI_EXEC_TEMP_OUTPUT_I 34 +#define TGSI_EXEC_TEMP_OUTPUT_C 1 + +#define TGSI_EXEC_TEMP_PRIMITIVE_I 34 +#define TGSI_EXEC_TEMP_PRIMITIVE_C 2 + +#define TGSI_EXEC_TEMP_R0 35 + +#define TGSI_EXEC_NUM_TEMPS (32 + 4) +#define TGSI_EXEC_NUM_ADDRS 1 +#define TGSI_EXEC_NUM_IMMEDIATES 256 + +#define TGSI_EXEC_MAX_COND_NESTING 10 +#define TGSI_EXEC_MAX_LOOP_NESTING 10 +#define TGSI_EXEC_MAX_CALL_NESTING 10 + +/** + * Run-time virtual machine state for executing TGSI shader. + */ +struct tgsi_exec_machine +{ + /* + * 32 program temporaries + * 4 internal temporaries + * 1 address + * 1 temporary of padding to align to 16 bytes + */ + struct tgsi_exec_vector _Temps[TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_ADDRS + 1]; + + /* + * This will point to _Temps after aligning to 16B boundary. + */ + struct tgsi_exec_vector *Temps; + struct tgsi_exec_vector *Addrs; + + struct tgsi_sampler *Samplers; + + float Imms[TGSI_EXEC_NUM_IMMEDIATES][4]; + unsigned ImmLimit; + float (*Consts)[4]; + struct tgsi_exec_vector *Inputs; + struct tgsi_exec_vector *Outputs; + const struct tgsi_token *Tokens; + unsigned Processor; + + /* GEOMETRY processor only. */ + unsigned *Primitives; + + /* FRAGMENT processor only. */ + const struct tgsi_interp_coef *InterpCoefs; + struct tgsi_exec_vector QuadPos; + + /* Conditional execution masks */ + uint CondMask; /**< For IF/ELSE/ENDIF */ + uint LoopMask; /**< For BGNLOOP/ENDLOOP */ + uint ContMask; /**< For loop CONT statements */ + uint FuncMask; /**< For function calls */ + uint ExecMask; /**< = CondMask & LoopMask */ + + /** Condition mask stack (for nested conditionals) */ + uint CondStack[TGSI_EXEC_MAX_COND_NESTING]; + int CondStackTop; + + /** Loop mask stack (for nested loops) */ + uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING]; + int LoopStackTop; + + /** Loop continue mask stack (see comments in tgsi_exec.c) */ + uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING]; + int ContStackTop; + + /** Function execution mask stack (for executing subroutine code) */ + uint FuncStack[TGSI_EXEC_MAX_CALL_NESTING]; + int FuncStackTop; + + /** Function call stack for saving/restoring the program counter */ + uint CallStack[TGSI_EXEC_MAX_CALL_NESTING]; + int CallStackTop; + + struct tgsi_full_instruction *Instructions; + uint NumInstructions; + + struct tgsi_full_declaration *Declarations; + uint NumDeclarations; + + struct tgsi_exec_labels Labels; +}; + + +void +tgsi_exec_machine_init( + struct tgsi_exec_machine *mach, + const struct tgsi_token *tokens, + unsigned numSamplers, + struct tgsi_sampler *samplers); + +uint +tgsi_exec_machine_run( + struct tgsi_exec_machine *mach ); + + +void +tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach); + + +#if defined __cplusplus +} /* extern "C" */ +#endif + +#endif /* TGSI_EXEC_H */ diff --git a/src/gallium/aux/tgsi/exec/tgsi_sse2.c b/src/gallium/aux/tgsi/exec/tgsi_sse2.c new file mode 100755 index 0000000000..1e56e4afb6 --- /dev/null +++ b/src/gallium/aux/tgsi/exec/tgsi_sse2.c @@ -0,0 +1,2378 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/tgsi/util/tgsi_parse.h" +#include "pipe/tgsi/util/tgsi_util.h" +#include "tgsi_exec.h" +#include "tgsi_sse2.h" + +#include "x86/rtasm/x86sse.h" + +#if defined(__i386__) || defined(__386__) + +#define DUMP_SSE 0 + +#if DUMP_SSE + +static void +_print_reg( + struct x86_reg reg ) +{ + if (reg.mod != mod_REG) + debug_printf( "[" ); + + switch( reg.file ) { + case file_REG32: + switch( reg.idx ) { + case reg_AX: + debug_printf( "EAX" ); + break; + case reg_CX: + debug_printf( "ECX" ); + break; + case reg_DX: + debug_printf( "EDX" ); + break; + case reg_BX: + debug_printf( "EBX" ); + break; + case reg_SP: + debug_printf( "ESP" ); + break; + case reg_BP: + debug_printf( "EBP" ); + break; + case reg_SI: + debug_printf( "ESI" ); + break; + case reg_DI: + debug_printf( "EDI" ); + break; + } + break; + case file_MMX: + assert( 0 ); + break; + case file_XMM: + debug_printf( "XMM%u", reg.idx ); + break; + case file_x87: + assert( 0 ); + break; + } + + if (reg.mod == mod_DISP8 || + reg.mod == mod_DISP32) + debug_printf("+%d", reg.disp); + + if (reg.mod != mod_REG) + debug_printf( "]" ); +} + +static void +_fill( + const char *op ) +{ + unsigned count = 10 - strlen( op ); + + while( count-- ) { + debug_printf( " " ); + } +} + +#define DUMP_START() debug_printf( "\nsse-dump start ----------------" ) +#define DUMP_END() debug_printf( "\nsse-dump end ----------------\n" ) +#define DUMP( OP ) debug_printf( "\n%s", OP ) +#define DUMP_I( OP, I ) do {\ + debug_printf( "\n%s", OP );\ + _fill( OP );\ + debug_printf( "%u", I ); } while( 0 ) +#define DUMP_R( OP, R0 ) do {\ + debug_printf( "\n%s", OP );\ + _fill( OP );\ + _print_reg( R0 ); } while( 0 ) +#define DUMP_RR( OP, R0, R1 ) do {\ + debug_printf( "\n%s", OP );\ + _fill( OP );\ + _print_reg( R0 );\ + debug_printf( ", " );\ + _print_reg( R1 ); } while( 0 ) +#define DUMP_RRI( OP, R0, R1, I ) do {\ + debug_printf( "\n%s", OP );\ + _fill( OP );\ + _print_reg( R0 );\ + debug_printf( ", " );\ + _print_reg( R1 );\ + debug_printf( ", " );\ + debug_printf( "%u", I ); } while( 0 ) + +#else + +#define DUMP_START() +#define DUMP_END() +#define DUMP( OP ) +#define DUMP_I( OP, I ) +#define DUMP_R( OP, R0 ) +#define DUMP_RR( OP, R0, R1 ) +#define DUMP_RRI( OP, R0, R1, I ) + +#endif + +#define FOR_EACH_CHANNEL( CHAN )\ + for( CHAN = 0; CHAN < 4; CHAN++ ) + +#define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ + ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) + +#define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ + if( IS_DST0_CHANNEL_ENABLED( INST, CHAN )) + +#define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\ + FOR_EACH_CHANNEL( CHAN )\ + IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN ) + +#define CHAN_X 0 +#define CHAN_Y 1 +#define CHAN_Z 2 +#define CHAN_W 3 + +#define TEMP_R0 TGSI_EXEC_TEMP_R0 + +/** + * X86 utility functions. + */ + +static struct x86_reg +make_xmm( + unsigned xmm ) +{ + return x86_make_reg( + file_XMM, + (enum x86_reg_name) xmm ); +} + +/** + * X86 register mapping helpers. + */ + +static struct x86_reg +get_const_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_CX ); +} + +static struct x86_reg +get_input_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_AX ); +} + +static struct x86_reg +get_output_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_DX ); +} + +static struct x86_reg +get_temp_base( void ) +{ +#ifdef WIN32 + return x86_make_reg( + file_REG32, + reg_BX ); +#else + return x86_make_reg( + file_REG32, + reg_SI ); +#endif +} + +static struct x86_reg +get_coef_base( void ) +{ + return get_output_base(); +} + +/** + * Data access helpers. + */ + +static struct x86_reg +get_argument( + unsigned index ) +{ + return x86_make_disp( + x86_make_reg( file_REG32, reg_SP ), + (index + 1) * 4 ); +} + +static struct x86_reg +get_const( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_const_base(), + (vec * 4 + chan) * 4 ); +} + +static struct x86_reg +get_input( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_input_base(), + (vec * 4 + chan) * 16 ); +} + +static struct x86_reg +get_output( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_output_base(), + (vec * 4 + chan) * 16 ); +} + +static struct x86_reg +get_temp( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_temp_base(), + (vec * 4 + chan) * 16 ); +} + +static struct x86_reg +get_coef( + unsigned vec, + unsigned chan, + unsigned member ) +{ + return x86_make_disp( + get_coef_base(), + ((vec * 3 + member) * 4 + chan) * 4 ); +} + +/** + * X86 rtasm wrappers. + */ + +static void +emit_addps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "ADDPS", dst, src ); + sse_addps( func, dst, src ); +} + +static void +emit_andnps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "ANDNPS", dst, src ); + sse_andnps( func, dst, src ); +} + +static void +emit_andps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "ANDPS", dst, src ); + sse_andps( func, dst, src ); +} + +static void +emit_call( + struct x86_function *func, + void (* addr)() ) +{ + struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); + + DUMP_I( "CALL", addr ); + x86_mov_reg_imm( func, ecx, (unsigned long) addr ); + x86_call( func, ecx ); +} + +static void +emit_cmpps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src, + enum sse_cc cc ) +{ + DUMP_RRI( "CMPPS", dst, src, cc ); + sse_cmpps( func, dst, src, cc ); +} + +static void +emit_cvttps2dq( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "CVTTPS2DQ", dst, src ); + sse2_cvttps2dq( func, dst, src ); +} + +static void +emit_maxps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MAXPS", dst, src ); + sse_maxps( func, dst, src ); +} + +static void +emit_minps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MINPS", dst, src ); + sse_minps( func, dst, src ); +} + +static void +emit_mov( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MOV", dst, src ); + x86_mov( func, dst, src ); +} + +static void +emit_movaps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MOVAPS", dst, src ); + sse_movaps( func, dst, src ); +} + +static void +emit_movss( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MOVSS", dst, src ); + sse_movss( func, dst, src ); +} + +static void +emit_movups( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MOVUPS", dst, src ); + sse_movups( func, dst, src ); +} + +static void +emit_mulps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MULPS", dst, src ); + sse_mulps( func, dst, src ); +} + +static void +emit_or( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "OR", dst, src ); + x86_or( func, dst, src ); +} + +static void +emit_orps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "ORPS", dst, src ); + sse_orps( func, dst, src ); +} + +static void +emit_pmovmskb( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "PMOVMSKB", dst, src ); + sse_pmovmskb( func, dst, src ); +} + +static void +emit_pop( + struct x86_function *func, + struct x86_reg dst ) +{ + DUMP_R( "POP", dst ); + x86_pop( func, dst ); +} + +static void +emit_push( + struct x86_function *func, + struct x86_reg dst ) +{ + DUMP_R( "PUSH", dst ); + x86_push( func, dst ); +} + +static void +emit_rcpps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "RCPPS", dst, src ); + sse2_rcpps( func, dst, src ); +} + +#ifdef WIN32 +static void +emit_retw( + struct x86_function *func, + unsigned size ) +{ + DUMP_I( "RET", size ); + x86_retw( func, size ); +} +#else +static void +emit_ret( + struct x86_function *func ) +{ + DUMP( "RET" ); + x86_ret( func ); +} +#endif + +static void +emit_rsqrtps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "RSQRTPS", dst, src ); + sse_rsqrtps( func, dst, src ); +} + +static void +emit_shufps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src, + unsigned char shuf ) +{ + DUMP_RRI( "SHUFPS", dst, src, shuf ); + sse_shufps( func, dst, src, shuf ); +} + +static void +emit_subps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "SUBPS", dst, src ); + sse_subps( func, dst, src ); +} + +static void +emit_xorps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "XORPS", dst, src ); + sse_xorps( func, dst, src ); +} + +/** + * Data fetch helpers. + */ + +static void +emit_const( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movss( + func, + make_xmm( xmm ), + get_const( vec, chan ) ); + emit_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); +} + +static void +emit_inputf( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movups( + func, + make_xmm( xmm ), + get_input( vec, chan ) ); +} + +static void +emit_output( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movups( + func, + get_output( vec, chan ), + make_xmm( xmm ) ); +} + +static void +emit_tempf( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movaps( + func, + make_xmm( xmm ), + get_temp( vec, chan ) ); +} + +static void +emit_coef( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan, + unsigned member ) +{ + emit_movss( + func, + make_xmm( xmm ), + get_coef( vec, chan, member ) ); + emit_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); +} + +/** + * Data store helpers. + */ + +static void +emit_inputs( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movups( + func, + get_input( vec, chan ), + make_xmm( xmm ) ); +} + +static void +emit_temps( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movaps( + func, + get_temp( vec, chan ), + make_xmm( xmm ) ); +} + +static void +emit_addrs( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_temps( + func, + xmm, + vec + TGSI_EXEC_NUM_TEMPS, + chan ); +} + +/** + * Coefficent fetch helpers. + */ + +static void +emit_coef_a0( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_coef( + func, + xmm, + vec, + chan, + 0 ); +} + +static void +emit_coef_dadx( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_coef( + func, + xmm, + vec, + chan, + 1 ); +} + +static void +emit_coef_dady( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_coef( + func, + xmm, + vec, + chan, + 2 ); +} + +/** + * Function call helpers. + */ + +static void +emit_push_gp( + struct x86_function *func ) +{ + emit_push( + func, + get_const_base() ); + emit_push( + func, + get_input_base() ); + emit_push( + func, + get_output_base() ); + + /* It is important on non-win32 platforms that temp base is pushed last. + */ + emit_push( + func, + get_temp_base() ); +} + +static void +emit_pop_gp( + struct x86_function *func ) +{ + /* Restore GP registers in a reverse order. + */ + emit_pop( + func, + get_temp_base() ); + emit_pop( + func, + get_output_base() ); + emit_pop( + func, + get_input_base() ); + emit_pop( + func, + get_const_base() ); +} + +static void +emit_func_call_dst( + struct x86_function *func, + unsigned xmm_dst, + void (*code)() ) +{ + emit_movaps( + func, + get_temp( TEMP_R0, 0 ), + make_xmm( xmm_dst ) ); + + emit_push_gp( + func ); + +#ifdef WIN32 + emit_push( + func, + get_temp( TEMP_R0, 0 ) ); +#endif + + emit_call( + func, + code ); + + emit_pop_gp( + func ); + + emit_movaps( + func, + make_xmm( xmm_dst ), + get_temp( TEMP_R0, 0 ) ); +} + +static void +emit_func_call_dst_src( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src, + void (*code)() ) +{ + emit_movaps( + func, + get_temp( TEMP_R0, 1 ), + make_xmm( xmm_src ) ); + + emit_func_call_dst( + func, + xmm_dst, + code ); +} + +/** + * Low-level instruction translators. + */ + +static void +emit_abs( + struct x86_function *func, + unsigned xmm ) +{ + emit_andps( + func, + make_xmm( xmm ), + get_temp( + TGSI_EXEC_TEMP_7FFFFFFF_I, + TGSI_EXEC_TEMP_7FFFFFFF_C ) ); +} + +static void +emit_add( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_addps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void XSTDCALL +cos4f( + float *store ) +{ +#ifdef WIN32 + store[0] = (float) cos( (double) store[0] ); + store[1] = (float) cos( (double) store[1] ); + store[2] = (float) cos( (double) store[2] ); + store[3] = (float) cos( (double) store[3] ); +#else + const unsigned X = TEMP_R0 * 16; + store[X + 0] = cosf( store[X + 0] ); + store[X + 1] = cosf( store[X + 1] ); + store[X + 2] = cosf( store[X + 2] ); + store[X + 3] = cosf( store[X + 3] ); +#endif +} + +static void +emit_cos( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + cos4f ); +} + +static void XSTDCALL +ex24f( + float *store ) +{ +#ifdef WIN32 + store[0] = (float) pow( 2.0, (double) store[0] ); + store[1] = (float) pow( 2.0, (double) store[1] ); + store[2] = (float) pow( 2.0, (double) store[2] ); + store[3] = (float) pow( 2.0, (double) store[3] ); +#else + const unsigned X = TEMP_R0 * 16; + store[X + 0] = powf( 2.0f, store[X + 0] ); + store[X + 1] = powf( 2.0f, store[X + 1] ); + store[X + 2] = powf( 2.0f, store[X + 2] ); + store[X + 3] = powf( 2.0f, store[X + 3] ); +#endif +} + +static void +emit_ex2( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + ex24f ); +} + +static void +emit_f2it( + struct x86_function *func, + unsigned xmm ) +{ + emit_cvttps2dq( + func, + make_xmm( xmm ), + make_xmm( xmm ) ); +} + +static void XSTDCALL +flr4f( + float *store ) +{ +#ifdef WIN32 + const unsigned X = 0; +#else + const unsigned X = TEMP_R0 * 16; +#endif + store[X + 0] = (float) floor( (double) store[X + 0] ); + store[X + 1] = (float) floor( (double) store[X + 1] ); + store[X + 2] = (float) floor( (double) store[X + 2] ); + store[X + 3] = (float) floor( (double) store[X + 3] ); +} + +static void +emit_flr( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + flr4f ); +} + +static void XSTDCALL +frc4f( + float *store ) +{ +#ifdef WIN32 + const unsigned X = 0; +#else + const unsigned X = TEMP_R0 * 16; +#endif + store[X + 0] -= (float) floor( (double) store[X + 0] ); + store[X + 1] -= (float) floor( (double) store[X + 1] ); + store[X + 2] -= (float) floor( (double) store[X + 2] ); + store[X + 3] -= (float) floor( (double) store[X + 3] ); +} + +static void +emit_frc( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + frc4f ); +} + +static void XSTDCALL +lg24f( + float *store ) +{ +#ifdef WIN32 + const unsigned X = 0; +#else + const unsigned X = TEMP_R0 * 16; +#endif + store[X + 0] = LOG2( store[X + 0] ); + store[X + 1] = LOG2( store[X + 1] ); + store[X + 2] = LOG2( store[X + 2] ); + store[X + 3] = LOG2( store[X + 3] ); +} + +static void +emit_lg2( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + lg24f ); +} + +static void +emit_MOV( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_movups( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void +emit_mul (struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src) +{ + emit_mulps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void +emit_neg( + struct x86_function *func, + unsigned xmm ) +{ + emit_xorps( + func, + make_xmm( xmm ), + get_temp( + TGSI_EXEC_TEMP_80000000_I, + TGSI_EXEC_TEMP_80000000_C ) ); +} + +static void XSTDCALL +pow4f( + float *store ) +{ +#ifdef WIN32 + store[0] = (float) pow( (double) store[0], (double) store[4] ); + store[1] = (float) pow( (double) store[1], (double) store[5] ); + store[2] = (float) pow( (double) store[2], (double) store[6] ); + store[3] = (float) pow( (double) store[3], (double) store[7] ); +#else + const unsigned X = TEMP_R0 * 16; + store[X + 0] = powf( store[X + 0], store[X + 4] ); + store[X + 1] = powf( store[X + 1], store[X + 5] ); + store[X + 2] = powf( store[X + 2], store[X + 6] ); + store[X + 3] = powf( store[X + 3], store[X + 7] ); +#endif +} + +static void +emit_pow( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_func_call_dst_src( + func, + xmm_dst, + xmm_src, + pow4f ); +} + +static void +emit_rcp ( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_rcpps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void +emit_rsqrt( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_rsqrtps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void +emit_setsign( + struct x86_function *func, + unsigned xmm ) +{ + emit_orps( + func, + make_xmm( xmm ), + get_temp( + TGSI_EXEC_TEMP_80000000_I, + TGSI_EXEC_TEMP_80000000_C ) ); +} + +static void XSTDCALL +sin4f( + float *store ) +{ +#ifdef WIN32 + store[0] = (float) sin( (double) store[0] ); + store[1] = (float) sin( (double) store[1] ); + store[2] = (float) sin( (double) store[2] ); + store[3] = (float) sin( (double) store[3] ); +#else + const unsigned X = TEMP_R0 * 16; + store[X + 0] = sinf( store[X + 0] ); + store[X + 1] = sinf( store[X + 1] ); + store[X + 2] = sinf( store[X + 2] ); + store[X + 3] = sinf( store[X + 3] ); +#endif +} + +static void +emit_sin (struct x86_function *func, + unsigned xmm_dst) +{ + emit_func_call_dst( + func, + xmm_dst, + sin4f ); +} + +static void +emit_sub( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_subps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +/** + * Register fetch. + */ + +static void +emit_fetch( + struct x86_function *func, + unsigned xmm, + const struct tgsi_full_src_register *reg, + const unsigned chan_index ) +{ + unsigned swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); + + switch( swizzle ) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + switch( reg->SrcRegister.File ) { + case TGSI_FILE_CONSTANT: + emit_const( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + + case TGSI_FILE_INPUT: + emit_inputf( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + + case TGSI_FILE_TEMPORARY: + emit_tempf( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + + default: + assert( 0 ); + } + break; + + case TGSI_EXTSWIZZLE_ZERO: + emit_tempf( + func, + xmm, + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ); + break; + + case TGSI_EXTSWIZZLE_ONE: + emit_tempf( + func, + xmm, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); + break; + + default: + assert( 0 ); + } + + switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) { + case TGSI_UTIL_SIGN_CLEAR: + emit_abs( func, xmm ); + break; + + case TGSI_UTIL_SIGN_SET: + emit_setsign( func, xmm ); + break; + + case TGSI_UTIL_SIGN_TOGGLE: + emit_neg( func, xmm ); + break; + + case TGSI_UTIL_SIGN_KEEP: + break; + } +} + +#define FETCH( FUNC, INST, XMM, INDEX, CHAN )\ + emit_fetch( FUNC, XMM, &(INST).FullSrcRegisters[INDEX], CHAN ) + +/** + * Register store. + */ + +static void +emit_store( + struct x86_function *func, + unsigned xmm, + const struct tgsi_full_dst_register *reg, + const struct tgsi_full_instruction *inst, + unsigned chan_index ) +{ + switch( reg->DstRegister.File ) { + case TGSI_FILE_OUTPUT: + emit_output( + func, + xmm, + reg->DstRegister.Index, + chan_index ); + break; + + case TGSI_FILE_TEMPORARY: + emit_temps( + func, + xmm, + reg->DstRegister.Index, + chan_index ); + break; + + case TGSI_FILE_ADDRESS: + emit_addrs( + func, + xmm, + reg->DstRegister.Index, + chan_index ); + break; + + default: + assert( 0 ); + } + + switch( inst->Instruction.Saturate ) { + case TGSI_SAT_NONE: + break; + + case TGSI_SAT_ZERO_ONE: +// assert( 0 ); + break; + + case TGSI_SAT_MINUS_PLUS_ONE: + assert( 0 ); + break; + } +} + +#define STORE( FUNC, INST, XMM, INDEX, CHAN )\ + emit_store( FUNC, XMM, &(INST).FullDstRegisters[INDEX], &(INST), CHAN ) + +/** + * High-level instruction translators. + */ + +static void +emit_kil( + struct x86_function *func, + const struct tgsi_full_src_register *reg ) +{ + unsigned uniquemask; + unsigned registers[4]; + unsigned nextregister = 0; + unsigned firstchan = ~0; + unsigned chan_index; + + /* This mask stores component bits that were already tested. Note that + * we test if the value is less than zero, so 1.0 and 0.0 need not to be + * tested. */ + uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); + + FOR_EACH_CHANNEL( chan_index ) { + unsigned swizzle; + + /* unswizzle channel */ + swizzle = tgsi_util_get_full_src_register_extswizzle( + reg, + chan_index ); + + /* check if the component has not been already tested */ + if( !(uniquemask & (1 << swizzle)) ) { + uniquemask |= 1 << swizzle; + + /* allocate register */ + registers[chan_index] = nextregister; + emit_fetch( + func, + nextregister, + reg, + chan_index ); + nextregister++; + + /* mark the first channel used */ + if( firstchan == ~0 ) { + firstchan = chan_index; + } + } + } + + emit_push( + func, + x86_make_reg( file_REG32, reg_AX ) ); + emit_push( + func, + x86_make_reg( file_REG32, reg_DX ) ); + + FOR_EACH_CHANNEL( chan_index ) { + if( uniquemask & (1 << chan_index) ) { + emit_cmpps( + func, + make_xmm( registers[chan_index] ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ), + cc_LessThan ); + + if( chan_index == firstchan ) { + emit_pmovmskb( + func, + x86_make_reg( file_REG32, reg_AX ), + make_xmm( registers[chan_index] ) ); + } + else { + emit_pmovmskb( + func, + x86_make_reg( file_REG32, reg_DX ), + make_xmm( registers[chan_index] ) ); + emit_or( + func, + x86_make_reg( file_REG32, reg_AX ), + x86_make_reg( file_REG32, reg_DX ) ); + } + } + } + + emit_or( + func, + get_temp( + TGSI_EXEC_TEMP_KILMASK_I, + TGSI_EXEC_TEMP_KILMASK_C ), + x86_make_reg( file_REG32, reg_AX ) ); + + emit_pop( + func, + x86_make_reg( file_REG32, reg_DX ) ); + emit_pop( + func, + x86_make_reg( file_REG32, reg_AX ) ); +} + +static void +emit_setcc( + struct x86_function *func, + struct tgsi_full_instruction *inst, + enum sse_cc cc ) +{ + unsigned chan_index; + + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_cmpps( + func, + make_xmm( 0 ), + make_xmm( 1 ), + cc ); + emit_andps( + func, + make_xmm( 0 ), + get_temp( + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ) ); + STORE( func, *inst, 0, 0, chan_index ); + } +} + +static void +emit_cmp( + struct x86_function *func, + struct tgsi_full_instruction *inst ) +{ + unsigned chan_index; + + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + FETCH( func, *inst, 2, 2, chan_index ); + emit_cmpps( + func, + make_xmm( 0 ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ), + cc_LessThan ); + emit_andps( + func, + make_xmm( 1 ), + make_xmm( 0 ) ); + emit_andnps( + func, + make_xmm( 0 ), + make_xmm( 2 ) ); + emit_orps( + func, + make_xmm( 0 ), + make_xmm( 1 ) ); + STORE( func, *inst, 0, 0, chan_index ); + } +} + +static int +emit_instruction( + struct x86_function *func, + struct tgsi_full_instruction *inst ) +{ + unsigned chan_index; + + switch( inst->Instruction.Opcode ) { + case TGSI_OPCODE_ARL: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_f2it( func, 0 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOV: + /* TGSI_OPCODE_SWZ */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_LIT: + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) { + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C); + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ) { + STORE( func, *inst, 0, 0, CHAN_X ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) { + STORE( func, *inst, 0, 0, CHAN_W ); + } + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_maxps( + func, + make_xmm( 0 ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ) ); + STORE( func, *inst, 0, 0, CHAN_Y ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + FETCH( func, *inst, 1, 0, CHAN_Y ); + emit_maxps( + func, + make_xmm( 1 ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ) ); + FETCH( func, *inst, 2, 0, CHAN_W ); + emit_minps( + func, + make_xmm( 2 ), + get_temp( + TGSI_EXEC_TEMP_128_I, + TGSI_EXEC_TEMP_128_C ) ); + emit_maxps( + func, + make_xmm( 2 ), + get_temp( + TGSI_EXEC_TEMP_MINUS_128_I, + TGSI_EXEC_TEMP_MINUS_128_C ) ); + emit_pow( func, 1, 2 ); + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_xorps( + func, + make_xmm( 2 ), + make_xmm( 2 ) ); + emit_cmpps( + func, + make_xmm( 2 ), + make_xmm( 0 ), + cc_LessThanEqual ); + emit_andps( + func, + make_xmm( 2 ), + make_xmm( 1 ) ); + STORE( func, *inst, 2, 0, CHAN_Z ); + } + } + break; + + case TGSI_OPCODE_RCP: + /* TGSI_OPCODE_RECIP */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_rcp( func, 0, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_RSQ: + /* TGSI_OPCODE_RECIPSQRT */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_rsqrt( func, 0, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXP: + return 0; + break; + + case TGSI_OPCODE_LOG: + return 0; + break; + + case TGSI_OPCODE_MUL: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_mul( func, 0, 1 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_ADD: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_add( func, 0, 1 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP3: + /* TGSI_OPCODE_DOT3 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_mul( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Y ); + FETCH( func, *inst, 2, 1, CHAN_Y ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Z ); + FETCH( func, *inst, 2, 1, CHAN_Z ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP4: + /* TGSI_OPCODE_DOT4 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_mul( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Y ); + FETCH( func, *inst, 2, 1, CHAN_Y ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Z ); + FETCH( func, *inst, 2, 1, CHAN_Z ); + emit_mul(func, 1, 2 ); + emit_add(func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_W ); + FETCH( func, *inst, 2, 1, CHAN_W ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DST: + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); + STORE( func, *inst, 0, 0, CHAN_X ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { + FETCH( func, *inst, 0, 0, CHAN_Y ); + FETCH( func, *inst, 1, 1, CHAN_Y ); + emit_mul( func, 0, 1 ); + STORE( func, *inst, 0, 0, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { + FETCH( func, *inst, 0, 0, CHAN_Z ); + STORE( func, *inst, 0, 0, CHAN_Z ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { + FETCH( func, *inst, 0, 1, CHAN_W ); + STORE( func, *inst, 0, 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MIN: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_minps( + func, + make_xmm( 0 ), + make_xmm( 1 ) ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_MAX: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_maxps( + func, + make_xmm( 0 ), + make_xmm( 1 ) ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLT: + /* TGSI_OPCODE_SETLT */ + emit_setcc( func, inst, cc_LessThan ); + break; + + case TGSI_OPCODE_SGE: + /* TGSI_OPCODE_SETGE */ + emit_setcc( func, inst, cc_NotLessThan ); + break; + + case TGSI_OPCODE_MAD: + /* TGSI_OPCODE_MADD */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + FETCH( func, *inst, 2, 2, chan_index ); + emit_mul( func, 0, 1 ); + emit_add( func, 0, 2 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_SUB: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_sub( func, 0, 1 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_LERP: + /* TGSI_OPCODE_LRP */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + FETCH( func, *inst, 2, 2, chan_index ); + emit_sub( func, 1, 2 ); + emit_mul( func, 0, 1 ); + emit_add( func, 0, 2 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_CND: + return 0; + break; + + case TGSI_OPCODE_CND0: + return 0; + break; + + case TGSI_OPCODE_DOT2ADD: + /* TGSI_OPCODE_DP2A */ + return 0; + break; + + case TGSI_OPCODE_INDEX: + return 0; + break; + + case TGSI_OPCODE_NEGATE: + return 0; + break; + + case TGSI_OPCODE_FRAC: + /* TGSI_OPCODE_FRC */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_frc( func, 0 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_CLAMP: + return 0; + break; + + case TGSI_OPCODE_FLOOR: + /* TGSI_OPCODE_FLR */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_flr( func, 0 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_ROUND: + return 0; + break; + + case TGSI_OPCODE_EXPBASE2: + /* TGSI_OPCODE_EX2 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_ex2( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_LOGBASE2: + /* TGSI_OPCODE_LG2 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_lg2( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_POWER: + /* TGSI_OPCODE_POW */ + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_pow( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_CROSSPRODUCT: + /* TGSI_OPCODE_XPD */ + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + FETCH( func, *inst, 1, 1, CHAN_Z ); + FETCH( func, *inst, 3, 0, CHAN_Z ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + FETCH( func, *inst, 0, 0, CHAN_Y ); + FETCH( func, *inst, 4, 1, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { + emit_MOV( func, 2, 0 ); + emit_mul( func, 2, 1 ); + emit_MOV( func, 5, 3 ); + emit_mul( func, 5, 4 ); + emit_sub( func, 2, 5 ); + STORE( func, *inst, 2, 0, CHAN_X ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + FETCH( func, *inst, 2, 1, CHAN_X ); + FETCH( func, *inst, 5, 0, CHAN_X ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { + emit_mul( func, 3, 2 ); + emit_mul( func, 1, 5 ); + emit_sub( func, 3, 1 ); + STORE( func, *inst, 3, 0, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { + emit_mul( func, 5, 4 ); + emit_mul( func, 0, 2 ); + emit_sub( func, 5, 0 ); + STORE( func, *inst, 5, 0, CHAN_Z ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { + FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C ); + STORE( func, *inst, 0, 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MULTIPLYMATRIX: + return 0; + break; + + case TGSI_OPCODE_ABS: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_abs( func, 0) ; + + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_RCC: + return 0; + break; + + case TGSI_OPCODE_DPH: + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_mul( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Y ); + FETCH( func, *inst, 2, 1, CHAN_Y ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Z ); + FETCH( func, *inst, 2, 1, CHAN_Z ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 1, CHAN_W ); + emit_add( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_COS: + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_cos( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDX: + return 0; + break; + + case TGSI_OPCODE_DDY: + return 0; + break; + + case TGSI_OPCODE_KIL: + emit_kil( func, &inst->FullSrcRegisters[0] ); + break; + + case TGSI_OPCODE_PK2H: + return 0; + break; + + case TGSI_OPCODE_PK2US: + return 0; + break; + + case TGSI_OPCODE_PK4B: + return 0; + break; + + case TGSI_OPCODE_PK4UB: + return 0; + break; + + case TGSI_OPCODE_RFL: + return 0; + break; + + case TGSI_OPCODE_SEQ: + return 0; + break; + + case TGSI_OPCODE_SFL: + return 0; + break; + + case TGSI_OPCODE_SGT: + return 0; + break; + + case TGSI_OPCODE_SIN: + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_sin( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLE: + return 0; + break; + + case TGSI_OPCODE_SNE: + return 0; + break; + + case TGSI_OPCODE_STR: + return 0; + break; + + case TGSI_OPCODE_TEX: + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_TXD: + return 0; + break; + + case TGSI_OPCODE_UP2H: + return 0; + break; + + case TGSI_OPCODE_UP2US: + return 0; + break; + + case TGSI_OPCODE_UP4B: + return 0; + break; + + case TGSI_OPCODE_UP4UB: + return 0; + break; + + case TGSI_OPCODE_X2D: + return 0; + break; + + case TGSI_OPCODE_ARA: + return 0; + break; + + case TGSI_OPCODE_ARR: + return 0; + break; + + case TGSI_OPCODE_BRA: + return 0; + break; + + case TGSI_OPCODE_CAL: + return 0; + break; + + case TGSI_OPCODE_RET: + case TGSI_OPCODE_END: +#ifdef WIN32 + emit_retw( func, 16 ); +#else + emit_ret( func ); +#endif + break; + + case TGSI_OPCODE_SSG: + return 0; + break; + + case TGSI_OPCODE_CMP: + emit_cmp (func, inst); + break; + + case TGSI_OPCODE_SCS: + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_cos( func, 0 ); + STORE( func, *inst, 0, 0, CHAN_X ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { + FETCH( func, *inst, 0, 0, CHAN_Y ); + emit_sin( func, 0 ); + STORE( func, *inst, 0, 0, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { + FETCH( func, *inst, 0, TGSI_EXEC_TEMP_00000000_I, TGSI_EXEC_TEMP_00000000_C ); + STORE( func, *inst, 0, 0, CHAN_Z ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { + FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C ); + STORE( func, *inst, 0, 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_TXB: + return 0; + break; + + case TGSI_OPCODE_NRM: + return 0; + break; + + case TGSI_OPCODE_DIV: + return 0; + break; + + case TGSI_OPCODE_DP2: + return 0; + break; + + case TGSI_OPCODE_TXL: + return 0; + break; + + case TGSI_OPCODE_BRK: + return 0; + break; + + case TGSI_OPCODE_IF: + return 0; + break; + + case TGSI_OPCODE_LOOP: + return 0; + break; + + case TGSI_OPCODE_REP: + return 0; + break; + + case TGSI_OPCODE_ELSE: + return 0; + break; + + case TGSI_OPCODE_ENDIF: + return 0; + break; + + case TGSI_OPCODE_ENDLOOP: + return 0; + break; + + case TGSI_OPCODE_ENDREP: + return 0; + break; + + case TGSI_OPCODE_PUSHA: + return 0; + break; + + case TGSI_OPCODE_POPA: + return 0; + break; + + case TGSI_OPCODE_CEIL: + return 0; + break; + + case TGSI_OPCODE_I2F: + return 0; + break; + + case TGSI_OPCODE_NOT: + return 0; + break; + + case TGSI_OPCODE_TRUNC: + return 0; + break; + + case TGSI_OPCODE_SHL: + return 0; + break; + + case TGSI_OPCODE_SHR: + return 0; + break; + + case TGSI_OPCODE_AND: + return 0; + break; + + case TGSI_OPCODE_OR: + return 0; + break; + + case TGSI_OPCODE_MOD: + return 0; + break; + + case TGSI_OPCODE_XOR: + return 0; + break; + + case TGSI_OPCODE_SAD: + return 0; + break; + + case TGSI_OPCODE_TXF: + return 0; + break; + + case TGSI_OPCODE_TXQ: + return 0; + break; + + case TGSI_OPCODE_CONT: + return 0; + break; + + case TGSI_OPCODE_EMIT: + return 0; + break; + + case TGSI_OPCODE_ENDPRIM: + return 0; + break; + + default: + return 0; + } + + return 1; +} + +static void +emit_declaration( + struct x86_function *func, + struct tgsi_full_declaration *decl ) +{ + if( decl->Declaration.File == TGSI_FILE_INPUT ) { + unsigned first, last, mask; + unsigned i, j; + + assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); + + first = decl->u.DeclarationRange.First; + last = decl->u.DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + /* Do not touch WPOS.xy */ + if( first == 0 ) { + mask &= ~TGSI_WRITEMASK_XY; + if( mask == TGSI_WRITEMASK_NONE ) { + first++; + } + } + + for( i = first; i <= last; i++ ) { + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + switch( decl->Interpolation.Interpolate ) { + case TGSI_INTERPOLATE_CONSTANT: + emit_coef_a0( func, 0, i, j ); + emit_inputs( func, 0, i, j ); + break; + + case TGSI_INTERPOLATE_LINEAR: + emit_inputf( func, 0, 0, TGSI_SWIZZLE_X ); + emit_coef_dadx( func, 1, i, j ); + emit_inputf( func, 2, 0, TGSI_SWIZZLE_Y ); + emit_coef_dady( func, 3, i, j ); + emit_mul( func, 0, 1 ); /* x * dadx */ + emit_coef_a0( func, 4, i, j ); + emit_mul( func, 2, 3 ); /* y * dady */ + emit_add( func, 0, 4 ); /* x * dadx + a0 */ + emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */ + emit_inputs( func, 0, i, j ); + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + emit_inputf( func, 0, 0, TGSI_SWIZZLE_X ); + emit_coef_dadx( func, 1, i, j ); + emit_inputf( func, 2, 0, TGSI_SWIZZLE_Y ); + emit_coef_dady( func, 3, i, j ); + emit_mul( func, 0, 1 ); /* x * dadx */ + emit_inputf( func, 4, 0, TGSI_SWIZZLE_W ); + emit_coef_a0( func, 5, i, j ); + emit_rcp( func, 4, 4 ); /* 1.0 / w */ + emit_mul( func, 2, 3 ); /* y * dady */ + emit_add( func, 0, 5 ); /* x * dadx + a0 */ + emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */ + emit_mul( func, 0, 4 ); /* (x * dadx + y * dady + a0) / w */ + emit_inputs( func, 0, i, j ); + break; + + default: + assert( 0 ); + break; + } + } + } + } + } +} + +unsigned +tgsi_emit_sse2( + struct tgsi_token *tokens, + struct x86_function *func ) +{ + struct tgsi_parse_context parse; + unsigned ok = 1; + + DUMP_START(); + + func->csr = func->store; + + emit_mov( + func, + get_input_base(), + get_argument( 0 ) ); + emit_mov( + func, + get_output_base(), + get_argument( 1 ) ); + emit_mov( + func, + get_const_base(), + get_argument( 2 ) ); + emit_mov( + func, + get_temp_base(), + get_argument( 3 ) ); + + tgsi_parse_init( &parse, tokens ); + + while( !tgsi_parse_end_of_tokens( &parse ) && ok ) { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + ok = emit_instruction( + func, + &parse.FullToken.FullInstruction ); + + if (!ok) { + debug_printf("failed to translate tgsi opcode %d\n", + parse.FullToken.FullInstruction.Instruction.Opcode ); + } + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + /* XXX implement this */ + ok = 0; + debug_printf("failed to emit immediate value\n"); + break; + + default: + assert( 0 ); + ok = 0; + break; + } + } + + tgsi_parse_free( &parse ); + + DUMP_END(); + + return ok; +} + +/** + * Fragment shaders are responsible for interpolating shader inputs. Because on + * x86 we have only 4 GP registers, and here we have 5 shader arguments (input, + * output, const, temp and coef), the code is split into two phases -- + * DECLARATION and INSTRUCTION phase. + * GP register holding the output argument is aliased with the coeff argument, + * as outputs are not needed in the DECLARATION phase. + */ +unsigned +tgsi_emit_sse2_fs( + struct tgsi_token *tokens, + struct x86_function *func ) +{ + struct tgsi_parse_context parse; + boolean instruction_phase = FALSE; + + DUMP_START(); + + func->csr = func->store; + + /* DECLARATION phase, do not load output argument. */ + emit_mov( + func, + get_input_base(), + get_argument( 0 ) ); + emit_mov( + func, + get_const_base(), + get_argument( 2 ) ); + emit_mov( + func, + get_temp_base(), + get_argument( 3 ) ); + emit_mov( + func, + get_coef_base(), + get_argument( 4 ) ); + + tgsi_parse_init( &parse, tokens ); + + while( !tgsi_parse_end_of_tokens( &parse ) ) { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + emit_declaration( + func, + &parse.FullToken.FullDeclaration ); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + if( !instruction_phase ) { + /* INSTRUCTION phase, overwrite coeff with output. */ + instruction_phase = TRUE; + emit_mov( + func, + get_output_base(), + get_argument( 1 ) ); + } + emit_instruction( + func, + &parse.FullToken.FullInstruction ); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + /* XXX implement this */ + assert(0); + break; + + default: + assert( 0 ); + } + } + + tgsi_parse_free( &parse ); + + DUMP_END(); + + return 1; +} + +#endif /* i386 */ diff --git a/src/gallium/aux/tgsi/exec/tgsi_sse2.h b/src/gallium/aux/tgsi/exec/tgsi_sse2.h new file mode 100755 index 0000000000..9bee371766 --- /dev/null +++ b/src/gallium/aux/tgsi/exec/tgsi_sse2.h @@ -0,0 +1,26 @@ +#if !defined TGSI_SSE2_H +#define TGSI_SSE2_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +struct tgsi_token; +struct x86_function; + +unsigned +tgsi_emit_sse2( + struct tgsi_token *tokens, + struct x86_function *function ); + +unsigned +tgsi_emit_sse2_fs( + struct tgsi_token *tokens, + struct x86_function *function ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_SSE2_H + diff --git a/src/gallium/aux/tgsi/util/tgsi_build.c b/src/gallium/aux/tgsi/util/tgsi_build.c new file mode 100644 index 0000000000..a00ff1c2a5 --- /dev/null +++ b/src/gallium/aux/tgsi/util/tgsi_build.c @@ -0,0 +1,1371 @@ +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi_build.h" +#include "tgsi_parse.h" + +/* + * version + */ + +struct tgsi_version +tgsi_build_version( void ) +{ + struct tgsi_version version; + + version.MajorVersion = 1; + version.MinorVersion = 1; + version.Padding = 0; + + return version; +} + +/* + * header + */ + +struct tgsi_header +tgsi_build_header( void ) +{ + struct tgsi_header header; + + header.HeaderSize = 1; + header.BodySize = 0; + + return header; +} + +static void +header_headersize_grow( struct tgsi_header *header ) +{ + assert( header->HeaderSize < 0xFF ); + assert( header->BodySize == 0 ); + + header->HeaderSize++; +} + +static void +header_bodysize_grow( struct tgsi_header *header ) +{ + assert( header->BodySize < 0xFFFFFF ); + + header->BodySize++; +} + +struct tgsi_processor +tgsi_default_processor( void ) +{ + struct tgsi_processor processor; + + processor.Processor = TGSI_PROCESSOR_FRAGMENT; + processor.Padding = 0; + + return processor; +} + +struct tgsi_processor +tgsi_build_processor( + unsigned type, + struct tgsi_header *header ) +{ + struct tgsi_processor processor; + + processor = tgsi_default_processor(); + processor.Processor = type; + + header_headersize_grow( header ); + + return processor; +} + +/* + * declaration + */ + +struct tgsi_declaration +tgsi_default_declaration( void ) +{ + struct tgsi_declaration declaration; + + declaration.Type = TGSI_TOKEN_TYPE_DECLARATION; + declaration.Size = 1; + declaration.File = TGSI_FILE_NULL; + declaration.Declare = TGSI_DECLARE_RANGE; + declaration.UsageMask = TGSI_WRITEMASK_XYZW; + declaration.Interpolate = 0; + declaration.Semantic = 0; + declaration.Padding = 0; + declaration.Extended = 0; + + return declaration; +} + +struct tgsi_declaration +tgsi_build_declaration( + unsigned file, + unsigned declare, + unsigned usage_mask, + unsigned interpolate, + unsigned semantic, + struct tgsi_header *header ) +{ + struct tgsi_declaration declaration; + + assert( file <= TGSI_FILE_IMMEDIATE ); + assert( declare <= TGSI_DECLARE_MASK ); + + declaration = tgsi_default_declaration(); + declaration.File = file; + declaration.Declare = declare; + declaration.UsageMask = usage_mask; + declaration.Interpolate = interpolate; + declaration.Semantic = semantic; + + header_bodysize_grow( header ); + + return declaration; +} + +static void +declaration_grow( + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + assert( declaration->Size < 0xFF ); + + declaration->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_full_declaration +tgsi_default_full_declaration( void ) +{ + struct tgsi_full_declaration full_declaration; + + full_declaration.Declaration = tgsi_default_declaration(); + full_declaration.Interpolation = tgsi_default_declaration_interpolation(); + full_declaration.Semantic = tgsi_default_declaration_semantic(); + + return full_declaration; +} + +unsigned +tgsi_build_full_declaration( + const struct tgsi_full_declaration *full_decl, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ) +{ + unsigned size = 0; + struct tgsi_declaration *declaration; + + if( maxsize <= size ) + return 0; + declaration = (struct tgsi_declaration *) &tokens[size]; + size++; + + *declaration = tgsi_build_declaration( + full_decl->Declaration.File, + full_decl->Declaration.Declare, + full_decl->Declaration.UsageMask, + full_decl->Declaration.Interpolate, + full_decl->Declaration.Semantic, + header ); + + switch( full_decl->Declaration.Declare ) { + case TGSI_DECLARE_RANGE: + { + struct tgsi_declaration_range *dr; + + if( maxsize <= size ) + return 0; + dr = (struct tgsi_declaration_range *) &tokens[size]; + size++; + + *dr = tgsi_build_declaration_range( + full_decl->u.DeclarationRange.First, + full_decl->u.DeclarationRange.Last, + declaration, + header ); + break; + } + + case TGSI_DECLARE_MASK: + { + struct tgsi_declaration_mask *dm; + + if( maxsize <= size ) + return 0; + dm = (struct tgsi_declaration_mask *) &tokens[size]; + size++; + + *dm = tgsi_build_declaration_mask( + full_decl->u.DeclarationMask.Mask, + declaration, + header ); + break; + } + + default: + assert( 0 ); + } + + if( full_decl->Declaration.Interpolate ) { + struct tgsi_declaration_interpolation *di; + + if( maxsize <= size ) + return 0; + di = (struct tgsi_declaration_interpolation *) &tokens[size]; + size++; + + *di = tgsi_build_declaration_interpolation( + full_decl->Interpolation.Interpolate, + declaration, + header ); + } + + if( full_decl->Declaration.Semantic ) { + struct tgsi_declaration_semantic *ds; + + if( maxsize <= size ) + return 0; + ds = (struct tgsi_declaration_semantic *) &tokens[size]; + size++; + + *ds = tgsi_build_declaration_semantic( + full_decl->Semantic.SemanticName, + full_decl->Semantic.SemanticIndex, + declaration, + header ); + } + + return size; +} + +struct tgsi_declaration_range +tgsi_build_declaration_range( + unsigned first, + unsigned last, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_range declaration_range; + + assert( last >= first ); + assert( last <= 0xFFFF ); + + declaration_range.First = first; + declaration_range.Last = last; + + declaration_grow( declaration, header ); + + return declaration_range; +} + +struct tgsi_declaration_mask +tgsi_build_declaration_mask( + unsigned mask, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_mask declaration_mask; + + declaration_mask.Mask = mask; + + declaration_grow( declaration, header ); + + return declaration_mask; +} + +struct tgsi_declaration_interpolation +tgsi_default_declaration_interpolation( void ) +{ + struct tgsi_declaration_interpolation di; + + di.Interpolate = TGSI_INTERPOLATE_CONSTANT; + di.Padding = 0; + + return di; +} + +struct tgsi_declaration_interpolation +tgsi_build_declaration_interpolation( + unsigned interpolate, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_interpolation di; + + assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE ); + + di = tgsi_default_declaration_interpolation(); + di.Interpolate = interpolate; + + declaration_grow( declaration, header ); + + return di; +} + +struct tgsi_declaration_semantic +tgsi_default_declaration_semantic( void ) +{ + struct tgsi_declaration_semantic ds; + + ds.SemanticName = TGSI_SEMANTIC_POSITION; + ds.SemanticIndex = 0; + ds.Padding = 0; + + return ds; +} + +struct tgsi_declaration_semantic +tgsi_build_declaration_semantic( + unsigned semantic_name, + unsigned semantic_index, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_semantic ds; + + assert( semantic_name <= TGSI_SEMANTIC_COUNT ); + assert( semantic_index <= 0xFFFF ); + + ds = tgsi_default_declaration_semantic(); + ds.SemanticName = semantic_name; + ds.SemanticIndex = semantic_index; + + declaration_grow( declaration, header ); + + return ds; +} + +/* + * immediate + */ + +struct tgsi_immediate +tgsi_default_immediate( void ) +{ + struct tgsi_immediate immediate; + + immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE; + immediate.Size = 1; + immediate.DataType = TGSI_IMM_FLOAT32; + immediate.Padding = 0; + immediate.Extended = 0; + + return immediate; +} + +struct tgsi_immediate +tgsi_build_immediate( + struct tgsi_header *header ) +{ + struct tgsi_immediate immediate; + + immediate = tgsi_default_immediate(); + + header_bodysize_grow( header ); + + return immediate; +} + +struct tgsi_full_immediate +tgsi_default_full_immediate( void ) +{ + struct tgsi_full_immediate fullimm; + + fullimm.Immediate = tgsi_default_immediate(); + fullimm.u.Pointer = (void *) 0; + + return fullimm; +} + +static void +immediate_grow( + struct tgsi_immediate *immediate, + struct tgsi_header *header ) +{ + assert( immediate->Size < 0xFF ); + + immediate->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_immediate_float32 +tgsi_build_immediate_float32( + float value, + struct tgsi_immediate *immediate, + struct tgsi_header *header ) +{ + struct tgsi_immediate_float32 immediate_float32; + + immediate_float32.Float = value; + + immediate_grow( immediate, header ); + + return immediate_float32; +} + +unsigned +tgsi_build_full_immediate( + const struct tgsi_full_immediate *full_imm, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ) +{ + unsigned size = 0, i; + struct tgsi_immediate *immediate; + + if( maxsize <= size ) + return 0; + immediate = (struct tgsi_immediate *) &tokens[size]; + size++; + + *immediate = tgsi_build_immediate( header ); + + for( i = 0; i < full_imm->Immediate.Size - 1; i++ ) { + struct tgsi_immediate_float32 *if32; + + if( maxsize <= size ) + return 0; + if32 = (struct tgsi_immediate_float32 *) &tokens[size]; + size++; + + *if32 = tgsi_build_immediate_float32( + full_imm->u.ImmediateFloat32[i].Float, + immediate, + header ); + } + + return size; +} + +/* + * instruction + */ + +struct tgsi_instruction +tgsi_default_instruction( void ) +{ + struct tgsi_instruction instruction; + + instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; + instruction.Size = 1; + instruction.Opcode = TGSI_OPCODE_MOV; + instruction.Saturate = TGSI_SAT_NONE; + instruction.NumDstRegs = 1; + instruction.NumSrcRegs = 1; + instruction.Padding = 0; + instruction.Extended = 0; + + return instruction; +} + +struct tgsi_instruction +tgsi_build_instruction( + unsigned opcode, + unsigned saturate, + unsigned num_dst_regs, + unsigned num_src_regs, + struct tgsi_header *header ) +{ + struct tgsi_instruction instruction; + + assert (opcode <= TGSI_OPCODE_LAST); + assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE); + assert (num_dst_regs <= 3); + assert (num_src_regs <= 15); + + instruction = tgsi_default_instruction(); + instruction.Opcode = opcode; + instruction.Saturate = saturate; + instruction.NumDstRegs = num_dst_regs; + instruction.NumSrcRegs = num_src_regs; + + header_bodysize_grow( header ); + + return instruction; +} + +static void +instruction_grow( + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + assert (instruction->Size < 0xFF); + + instruction->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_full_instruction +tgsi_default_full_instruction( void ) +{ + struct tgsi_full_instruction full_instruction; + unsigned i; + + full_instruction.Instruction = tgsi_default_instruction(); + full_instruction.InstructionExtNv = tgsi_default_instruction_ext_nv(); + full_instruction.InstructionExtLabel = tgsi_default_instruction_ext_label(); + full_instruction.InstructionExtTexture = tgsi_default_instruction_ext_texture(); + for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) { + full_instruction.FullDstRegisters[i] = tgsi_default_full_dst_register(); + } + for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) { + full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register(); + } + + return full_instruction; +} + +unsigned +tgsi_build_full_instruction( + const struct tgsi_full_instruction *full_inst, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ) +{ + unsigned size = 0; + unsigned i; + struct tgsi_instruction *instruction; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + instruction = (struct tgsi_instruction *) &tokens[size]; + size++; + + *instruction = tgsi_build_instruction( + full_inst->Instruction.Opcode, + full_inst->Instruction.Saturate, + full_inst->Instruction.NumDstRegs, + full_inst->Instruction.NumSrcRegs, + header ); + prev_token = (struct tgsi_token *) instruction; + + if( tgsi_compare_instruction_ext_nv( + full_inst->InstructionExtNv, + tgsi_default_instruction_ext_nv() ) ) { + struct tgsi_instruction_ext_nv *instruction_ext_nv; + + if( maxsize <= size ) + return 0; + instruction_ext_nv = + (struct tgsi_instruction_ext_nv *) &tokens[size]; + size++; + + *instruction_ext_nv = tgsi_build_instruction_ext_nv( + full_inst->InstructionExtNv.Precision, + full_inst->InstructionExtNv.CondDstIndex, + full_inst->InstructionExtNv.CondFlowIndex, + full_inst->InstructionExtNv.CondMask, + full_inst->InstructionExtNv.CondSwizzleX, + full_inst->InstructionExtNv.CondSwizzleY, + full_inst->InstructionExtNv.CondSwizzleZ, + full_inst->InstructionExtNv.CondSwizzleW, + full_inst->InstructionExtNv.CondDstUpdate, + full_inst->InstructionExtNv.CondFlowEnable, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_nv; + } + + if( tgsi_compare_instruction_ext_label( + full_inst->InstructionExtLabel, + tgsi_default_instruction_ext_label() ) ) { + struct tgsi_instruction_ext_label *instruction_ext_label; + + if( maxsize <= size ) + return 0; + instruction_ext_label = + (struct tgsi_instruction_ext_label *) &tokens[size]; + size++; + + *instruction_ext_label = tgsi_build_instruction_ext_label( + full_inst->InstructionExtLabel.Label, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_label; + } + + if( tgsi_compare_instruction_ext_texture( + full_inst->InstructionExtTexture, + tgsi_default_instruction_ext_texture() ) ) { + struct tgsi_instruction_ext_texture *instruction_ext_texture; + + if( maxsize <= size ) + return 0; + instruction_ext_texture = + (struct tgsi_instruction_ext_texture *) &tokens[size]; + size++; + + *instruction_ext_texture = tgsi_build_instruction_ext_texture( + full_inst->InstructionExtTexture.Texture, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_texture; + } + + for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { + const struct tgsi_full_dst_register *reg = &full_inst->FullDstRegisters[i]; + struct tgsi_dst_register *dst_register; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + dst_register = (struct tgsi_dst_register *) &tokens[size]; + size++; + + *dst_register = tgsi_build_dst_register( + reg->DstRegister.File, + reg->DstRegister.WriteMask, + reg->DstRegister.Index, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register; + + if( tgsi_compare_dst_register_ext_concode( + reg->DstRegisterExtConcode, + tgsi_default_dst_register_ext_concode() ) ) { + struct tgsi_dst_register_ext_concode *dst_register_ext_concode; + + if( maxsize <= size ) + return 0; + dst_register_ext_concode = + (struct tgsi_dst_register_ext_concode *) &tokens[size]; + size++; + + *dst_register_ext_concode = tgsi_build_dst_register_ext_concode( + reg->DstRegisterExtConcode.CondMask, + reg->DstRegisterExtConcode.CondSwizzleX, + reg->DstRegisterExtConcode.CondSwizzleY, + reg->DstRegisterExtConcode.CondSwizzleZ, + reg->DstRegisterExtConcode.CondSwizzleW, + reg->DstRegisterExtConcode.CondSrcIndex, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register_ext_concode; + } + + if( tgsi_compare_dst_register_ext_modulate( + reg->DstRegisterExtModulate, + tgsi_default_dst_register_ext_modulate() ) ) { + struct tgsi_dst_register_ext_modulate *dst_register_ext_modulate; + + if( maxsize <= size ) + return 0; + dst_register_ext_modulate = + (struct tgsi_dst_register_ext_modulate *) &tokens[size]; + size++; + + *dst_register_ext_modulate = tgsi_build_dst_register_ext_modulate( + reg->DstRegisterExtModulate.Modulate, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register_ext_modulate; + } + } + + for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { + const struct tgsi_full_src_register *reg = &full_inst->FullSrcRegisters[i]; + struct tgsi_src_register *src_register; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + src_register = (struct tgsi_src_register *) &tokens[size]; + size++; + + *src_register = tgsi_build_src_register( + reg->SrcRegister.File, + reg->SrcRegister.SwizzleX, + reg->SrcRegister.SwizzleY, + reg->SrcRegister.SwizzleZ, + reg->SrcRegister.SwizzleW, + reg->SrcRegister.Negate, + reg->SrcRegister.Indirect, + reg->SrcRegister.Dimension, + reg->SrcRegister.Index, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register; + + if( tgsi_compare_src_register_ext_swz( + reg->SrcRegisterExtSwz, + tgsi_default_src_register_ext_swz() ) ) { + struct tgsi_src_register_ext_swz *src_register_ext_swz; + + if( maxsize <= size ) + return 0; + src_register_ext_swz = + (struct tgsi_src_register_ext_swz *) &tokens[size]; + size++; + + *src_register_ext_swz = tgsi_build_src_register_ext_swz( + reg->SrcRegisterExtSwz.ExtSwizzleX, + reg->SrcRegisterExtSwz.ExtSwizzleY, + reg->SrcRegisterExtSwz.ExtSwizzleZ, + reg->SrcRegisterExtSwz.ExtSwizzleW, + reg->SrcRegisterExtSwz.NegateX, + reg->SrcRegisterExtSwz.NegateY, + reg->SrcRegisterExtSwz.NegateZ, + reg->SrcRegisterExtSwz.NegateW, + reg->SrcRegisterExtSwz.ExtDivide, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register_ext_swz; + } + + if( tgsi_compare_src_register_ext_mod( + reg->SrcRegisterExtMod, + tgsi_default_src_register_ext_mod() ) ) { + struct tgsi_src_register_ext_mod *src_register_ext_mod; + + if( maxsize <= size ) + return 0; + src_register_ext_mod = + (struct tgsi_src_register_ext_mod *) &tokens[size]; + size++; + + *src_register_ext_mod = tgsi_build_src_register_ext_mod( + reg->SrcRegisterExtMod.Complement, + reg->SrcRegisterExtMod.Bias, + reg->SrcRegisterExtMod.Scale2X, + reg->SrcRegisterExtMod.Absolute, + reg->SrcRegisterExtMod.Negate, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register_ext_mod; + } + + if( reg->SrcRegister.Indirect ) { + struct tgsi_src_register *ind; + + if( maxsize <= size ) + return 0; + ind = (struct tgsi_src_register *) &tokens[size]; + size++; + + *ind = tgsi_build_src_register( + reg->SrcRegisterInd.File, + reg->SrcRegisterInd.SwizzleX, + reg->SrcRegisterInd.SwizzleY, + reg->SrcRegisterInd.SwizzleZ, + reg->SrcRegisterInd.SwizzleW, + reg->SrcRegisterInd.Negate, + reg->SrcRegisterInd.Indirect, + reg->SrcRegisterInd.Dimension, + reg->SrcRegisterInd.Index, + instruction, + header ); + } + + if( reg->SrcRegister.Dimension ) { + struct tgsi_dimension *dim; + + assert( !reg->SrcRegisterDim.Dimension ); + + if( maxsize <= size ) + return 0; + dim = (struct tgsi_dimension *) &tokens[size]; + size++; + + *dim = tgsi_build_dimension( + reg->SrcRegisterDim.Indirect, + reg->SrcRegisterDim.Index, + instruction, + header ); + + if( reg->SrcRegisterDim.Indirect ) { + struct tgsi_src_register *ind; + + if( maxsize <= size ) + return 0; + ind = (struct tgsi_src_register *) &tokens[size]; + size++; + + *ind = tgsi_build_src_register( + reg->SrcRegisterDimInd.File, + reg->SrcRegisterDimInd.SwizzleX, + reg->SrcRegisterDimInd.SwizzleY, + reg->SrcRegisterDimInd.SwizzleZ, + reg->SrcRegisterDimInd.SwizzleW, + reg->SrcRegisterDimInd.Negate, + reg->SrcRegisterDimInd.Indirect, + reg->SrcRegisterDimInd.Dimension, + reg->SrcRegisterDimInd.Index, + instruction, + header ); + } + } + } + + return size; +} + +struct tgsi_instruction_ext_nv +tgsi_default_instruction_ext_nv( void ) +{ + struct tgsi_instruction_ext_nv instruction_ext_nv; + + instruction_ext_nv.Type = TGSI_INSTRUCTION_EXT_TYPE_NV; + instruction_ext_nv.Precision = TGSI_PRECISION_DEFAULT; + instruction_ext_nv.CondDstIndex = 0; + instruction_ext_nv.CondFlowIndex = 0; + instruction_ext_nv.CondMask = TGSI_CC_TR; + instruction_ext_nv.CondSwizzleX = TGSI_SWIZZLE_X; + instruction_ext_nv.CondSwizzleY = TGSI_SWIZZLE_Y; + instruction_ext_nv.CondSwizzleZ = TGSI_SWIZZLE_Z; + instruction_ext_nv.CondSwizzleW = TGSI_SWIZZLE_W; + instruction_ext_nv.CondDstUpdate = 0; + instruction_ext_nv.CondFlowEnable = 0; + instruction_ext_nv.Padding = 0; + instruction_ext_nv.Extended = 0; + + return instruction_ext_nv; +} + +union token_u32 +{ + unsigned u32; +}; + +unsigned +tgsi_compare_instruction_ext_nv( + struct tgsi_instruction_ext_nv a, + struct tgsi_instruction_ext_nv b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_instruction_ext_nv +tgsi_build_instruction_ext_nv( + unsigned precision, + unsigned cond_dst_index, + unsigned cond_flow_index, + unsigned cond_mask, + unsigned cond_swizzle_x, + unsigned cond_swizzle_y, + unsigned cond_swizzle_z, + unsigned cond_swizzle_w, + unsigned cond_dst_update, + unsigned cond_flow_update, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_nv instruction_ext_nv; + + instruction_ext_nv = tgsi_default_instruction_ext_nv(); + instruction_ext_nv.Precision = precision; + instruction_ext_nv.CondDstIndex = cond_dst_index; + instruction_ext_nv.CondFlowIndex = cond_flow_index; + instruction_ext_nv.CondMask = cond_mask; + instruction_ext_nv.CondSwizzleX = cond_swizzle_x; + instruction_ext_nv.CondSwizzleY = cond_swizzle_y; + instruction_ext_nv.CondSwizzleZ = cond_swizzle_z; + instruction_ext_nv.CondSwizzleW = cond_swizzle_w; + instruction_ext_nv.CondDstUpdate = cond_dst_update; + instruction_ext_nv.CondFlowEnable = cond_flow_update; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_nv; +} + +struct tgsi_instruction_ext_label +tgsi_default_instruction_ext_label( void ) +{ + struct tgsi_instruction_ext_label instruction_ext_label; + + instruction_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL; + instruction_ext_label.Label = 0; + instruction_ext_label.Padding = 0; + instruction_ext_label.Extended = 0; + + return instruction_ext_label; +} + +unsigned +tgsi_compare_instruction_ext_label( + struct tgsi_instruction_ext_label a, + struct tgsi_instruction_ext_label b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_instruction_ext_label +tgsi_build_instruction_ext_label( + unsigned label, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_label instruction_ext_label; + + instruction_ext_label = tgsi_default_instruction_ext_label(); + instruction_ext_label.Label = label; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_label; +} + +struct tgsi_instruction_ext_texture +tgsi_default_instruction_ext_texture( void ) +{ + struct tgsi_instruction_ext_texture instruction_ext_texture; + + instruction_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE; + instruction_ext_texture.Texture = TGSI_TEXTURE_UNKNOWN; + instruction_ext_texture.Padding = 0; + instruction_ext_texture.Extended = 0; + + return instruction_ext_texture; +} + +unsigned +tgsi_compare_instruction_ext_texture( + struct tgsi_instruction_ext_texture a, + struct tgsi_instruction_ext_texture b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_instruction_ext_texture +tgsi_build_instruction_ext_texture( + unsigned texture, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_texture instruction_ext_texture; + + instruction_ext_texture = tgsi_default_instruction_ext_texture(); + instruction_ext_texture.Texture = texture; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_texture; +} + +struct tgsi_src_register +tgsi_default_src_register( void ) +{ + struct tgsi_src_register src_register; + + src_register.File = TGSI_FILE_NULL; + src_register.SwizzleX = TGSI_SWIZZLE_X; + src_register.SwizzleY = TGSI_SWIZZLE_Y; + src_register.SwizzleZ = TGSI_SWIZZLE_Z; + src_register.SwizzleW = TGSI_SWIZZLE_W; + src_register.Negate = 0; + src_register.Indirect = 0; + src_register.Dimension = 0; + src_register.Index = 0; + src_register.Extended = 0; + + return src_register; +} + +struct tgsi_src_register +tgsi_build_src_register( + unsigned file, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + unsigned negate, + unsigned indirect, + unsigned dimension, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register src_register; + + assert( file <= TGSI_FILE_IMMEDIATE ); + assert( swizzle_x <= TGSI_SWIZZLE_W ); + assert( swizzle_y <= TGSI_SWIZZLE_W ); + assert( swizzle_z <= TGSI_SWIZZLE_W ); + assert( swizzle_w <= TGSI_SWIZZLE_W ); + assert( negate <= 1 ); + assert( index >= -0x8000 && index <= 0x7FFF ); + + src_register = tgsi_default_src_register(); + src_register.File = file; + src_register.SwizzleX = swizzle_x; + src_register.SwizzleY = swizzle_y; + src_register.SwizzleZ = swizzle_z; + src_register.SwizzleW = swizzle_w; + src_register.Negate = negate; + src_register.Indirect = indirect; + src_register.Dimension = dimension; + src_register.Index = index; + + instruction_grow( instruction, header ); + + return src_register; +} + +struct tgsi_full_src_register +tgsi_default_full_src_register( void ) +{ + struct tgsi_full_src_register full_src_register; + + full_src_register.SrcRegister = tgsi_default_src_register(); + full_src_register.SrcRegisterExtSwz = tgsi_default_src_register_ext_swz(); + full_src_register.SrcRegisterExtMod = tgsi_default_src_register_ext_mod(); + full_src_register.SrcRegisterInd = tgsi_default_src_register(); + full_src_register.SrcRegisterDim = tgsi_default_dimension(); + full_src_register.SrcRegisterDimInd = tgsi_default_src_register(); + + return full_src_register; +} + +struct tgsi_src_register_ext_swz +tgsi_default_src_register_ext_swz( void ) +{ + struct tgsi_src_register_ext_swz src_register_ext_swz; + + src_register_ext_swz.Type = TGSI_SRC_REGISTER_EXT_TYPE_SWZ; + src_register_ext_swz.ExtSwizzleX = TGSI_EXTSWIZZLE_X; + src_register_ext_swz.ExtSwizzleY = TGSI_EXTSWIZZLE_Y; + src_register_ext_swz.ExtSwizzleZ = TGSI_EXTSWIZZLE_Z; + src_register_ext_swz.ExtSwizzleW = TGSI_EXTSWIZZLE_W; + src_register_ext_swz.NegateX = 0; + src_register_ext_swz.NegateY = 0; + src_register_ext_swz.NegateZ = 0; + src_register_ext_swz.NegateW = 0; + src_register_ext_swz.ExtDivide = TGSI_EXTSWIZZLE_ONE; + src_register_ext_swz.Padding = 0; + src_register_ext_swz.Extended = 0; + + return src_register_ext_swz; +} + +unsigned +tgsi_compare_src_register_ext_swz( + struct tgsi_src_register_ext_swz a, + struct tgsi_src_register_ext_swz b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_src_register_ext_swz +tgsi_build_src_register_ext_swz( + unsigned ext_swizzle_x, + unsigned ext_swizzle_y, + unsigned ext_swizzle_z, + unsigned ext_swizzle_w, + unsigned negate_x, + unsigned negate_y, + unsigned negate_z, + unsigned negate_w, + unsigned ext_divide, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register_ext_swz src_register_ext_swz; + + assert( ext_swizzle_x <= TGSI_EXTSWIZZLE_ONE ); + assert( ext_swizzle_y <= TGSI_EXTSWIZZLE_ONE ); + assert( ext_swizzle_z <= TGSI_EXTSWIZZLE_ONE ); + assert( ext_swizzle_w <= TGSI_EXTSWIZZLE_ONE ); + assert( negate_x <= 1 ); + assert( negate_y <= 1 ); + assert( negate_z <= 1 ); + assert( negate_w <= 1 ); + assert( ext_divide <= TGSI_EXTSWIZZLE_ONE ); + + src_register_ext_swz = tgsi_default_src_register_ext_swz(); + src_register_ext_swz.ExtSwizzleX = ext_swizzle_x; + src_register_ext_swz.ExtSwizzleY = ext_swizzle_y; + src_register_ext_swz.ExtSwizzleZ = ext_swizzle_z; + src_register_ext_swz.ExtSwizzleW = ext_swizzle_w; + src_register_ext_swz.NegateX = negate_x; + src_register_ext_swz.NegateY = negate_y; + src_register_ext_swz.NegateZ = negate_z; + src_register_ext_swz.NegateW = negate_w; + src_register_ext_swz.ExtDivide = ext_divide; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return src_register_ext_swz; +} + +struct tgsi_src_register_ext_mod +tgsi_default_src_register_ext_mod( void ) +{ + struct tgsi_src_register_ext_mod src_register_ext_mod; + + src_register_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD; + src_register_ext_mod.Complement = 0; + src_register_ext_mod.Bias = 0; + src_register_ext_mod.Scale2X = 0; + src_register_ext_mod.Absolute = 0; + src_register_ext_mod.Negate = 0; + src_register_ext_mod.Padding = 0; + src_register_ext_mod.Extended = 0; + + return src_register_ext_mod; +} + +unsigned +tgsi_compare_src_register_ext_mod( + struct tgsi_src_register_ext_mod a, + struct tgsi_src_register_ext_mod b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_src_register_ext_mod +tgsi_build_src_register_ext_mod( + unsigned complement, + unsigned bias, + unsigned scale_2x, + unsigned absolute, + unsigned negate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register_ext_mod src_register_ext_mod; + + assert( complement <= 1 ); + assert( bias <= 1 ); + assert( scale_2x <= 1 ); + assert( absolute <= 1 ); + assert( negate <= 1 ); + + src_register_ext_mod = tgsi_default_src_register_ext_mod(); + src_register_ext_mod.Complement = complement; + src_register_ext_mod.Bias = bias; + src_register_ext_mod.Scale2X = scale_2x; + src_register_ext_mod.Absolute = absolute; + src_register_ext_mod.Negate = negate; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return src_register_ext_mod; +} + +struct tgsi_dimension +tgsi_default_dimension( void ) +{ + struct tgsi_dimension dimension; + + dimension.Indirect = 0; + dimension.Dimension = 0; + dimension.Padding = 0; + dimension.Index = 0; + dimension.Extended = 0; + + return dimension; +} + +struct tgsi_dimension +tgsi_build_dimension( + unsigned indirect, + unsigned index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dimension dimension; + + dimension = tgsi_default_dimension(); + dimension.Indirect = indirect; + dimension.Index = index; + + instruction_grow( instruction, header ); + + return dimension; +} + +struct tgsi_dst_register +tgsi_default_dst_register( void ) +{ + struct tgsi_dst_register dst_register; + + dst_register.File = TGSI_FILE_NULL; + dst_register.WriteMask = TGSI_WRITEMASK_XYZW; + dst_register.Indirect = 0; + dst_register.Dimension = 0; + dst_register.Index = 0; + dst_register.Padding = 0; + dst_register.Extended = 0; + + return dst_register; +} + +struct tgsi_dst_register +tgsi_build_dst_register( + unsigned file, + unsigned mask, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register dst_register; + + assert( file <= TGSI_FILE_IMMEDIATE ); + assert( mask <= TGSI_WRITEMASK_XYZW ); + assert( index >= -32768 && index <= 32767 ); + + dst_register = tgsi_default_dst_register(); + dst_register.File = file; + dst_register.WriteMask = mask; + dst_register.Index = index; + + instruction_grow( instruction, header ); + + return dst_register; +} + +struct tgsi_full_dst_register +tgsi_default_full_dst_register( void ) +{ + struct tgsi_full_dst_register full_dst_register; + + full_dst_register.DstRegister = tgsi_default_dst_register(); + full_dst_register.DstRegisterExtConcode = + tgsi_default_dst_register_ext_concode(); + full_dst_register.DstRegisterExtModulate = + tgsi_default_dst_register_ext_modulate(); + + return full_dst_register; +} + +struct tgsi_dst_register_ext_concode +tgsi_default_dst_register_ext_concode( void ) +{ + struct tgsi_dst_register_ext_concode dst_register_ext_concode; + + dst_register_ext_concode.Type = TGSI_DST_REGISTER_EXT_TYPE_CONDCODE; + dst_register_ext_concode.CondMask = TGSI_CC_TR; + dst_register_ext_concode.CondSwizzleX = TGSI_SWIZZLE_X; + dst_register_ext_concode.CondSwizzleY = TGSI_SWIZZLE_Y; + dst_register_ext_concode.CondSwizzleZ = TGSI_SWIZZLE_Z; + dst_register_ext_concode.CondSwizzleW = TGSI_SWIZZLE_W; + dst_register_ext_concode.CondSrcIndex = 0; + dst_register_ext_concode.Padding = 0; + dst_register_ext_concode.Extended = 0; + + return dst_register_ext_concode; +} + +unsigned +tgsi_compare_dst_register_ext_concode( + struct tgsi_dst_register_ext_concode a, + struct tgsi_dst_register_ext_concode b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_dst_register_ext_concode +tgsi_build_dst_register_ext_concode( + unsigned cc, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + int index, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register_ext_concode dst_register_ext_concode; + + assert( cc <= TGSI_CC_FL ); + assert( swizzle_x <= TGSI_SWIZZLE_W ); + assert( swizzle_y <= TGSI_SWIZZLE_W ); + assert( swizzle_z <= TGSI_SWIZZLE_W ); + assert( swizzle_w <= TGSI_SWIZZLE_W ); + assert( index >= -32768 && index <= 32767 ); + + dst_register_ext_concode = tgsi_default_dst_register_ext_concode(); + dst_register_ext_concode.CondMask = cc; + dst_register_ext_concode.CondSwizzleX = swizzle_x; + dst_register_ext_concode.CondSwizzleY = swizzle_y; + dst_register_ext_concode.CondSwizzleZ = swizzle_z; + dst_register_ext_concode.CondSwizzleW = swizzle_w; + dst_register_ext_concode.CondSrcIndex = index; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return dst_register_ext_concode; +} + +struct tgsi_dst_register_ext_modulate +tgsi_default_dst_register_ext_modulate( void ) +{ + struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; + + dst_register_ext_modulate.Type = TGSI_DST_REGISTER_EXT_TYPE_MODULATE; + dst_register_ext_modulate.Modulate = TGSI_MODULATE_1X; + dst_register_ext_modulate.Padding = 0; + dst_register_ext_modulate.Extended = 0; + + return dst_register_ext_modulate; +} + +unsigned +tgsi_compare_dst_register_ext_modulate( + struct tgsi_dst_register_ext_modulate a, + struct tgsi_dst_register_ext_modulate b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_dst_register_ext_modulate +tgsi_build_dst_register_ext_modulate( + unsigned modulate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; + + assert( modulate <= TGSI_MODULATE_EIGHTH ); + + dst_register_ext_modulate = tgsi_default_dst_register_ext_modulate(); + dst_register_ext_modulate.Modulate = modulate; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return dst_register_ext_modulate; +} + diff --git a/src/gallium/aux/tgsi/util/tgsi_build.h b/src/gallium/aux/tgsi/util/tgsi_build.h new file mode 100644 index 0000000000..116c78abf3 --- /dev/null +++ b/src/gallium/aux/tgsi/util/tgsi_build.h @@ -0,0 +1,320 @@ +#if !defined TGSI_BUILD_H +#define TGSI_BUILD_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +/* + * version + */ + +struct tgsi_version +tgsi_build_version( void ); + +/* + * header + */ + +struct tgsi_header +tgsi_build_header( void ); + +struct tgsi_processor +tgsi_default_processor( void ); + +struct tgsi_processor +tgsi_build_processor( + unsigned processor, + struct tgsi_header *header ); + +/* + * declaration + */ + +struct tgsi_declaration +tgsi_default_declaration( void ); + +struct tgsi_declaration +tgsi_build_declaration( + unsigned file, + unsigned declare, + unsigned usage_mask, + unsigned interpolate, + unsigned semantic, + struct tgsi_header *header ); + +struct tgsi_full_declaration +tgsi_default_full_declaration( void ); + +unsigned +tgsi_build_full_declaration( + const struct tgsi_full_declaration *full_decl, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ); + +struct tgsi_declaration_range +tgsi_build_declaration_range( + unsigned first, + unsigned last, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +struct tgsi_declaration_mask +tgsi_build_declaration_mask( + unsigned mask, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +struct tgsi_declaration_interpolation +tgsi_default_declaration_interpolation( void ); + +struct tgsi_declaration_interpolation +tgsi_build_declaration_interpolation( + unsigned interpolate, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +struct tgsi_declaration_semantic +tgsi_default_declaration_semantic( void ); + +struct tgsi_declaration_semantic +tgsi_build_declaration_semantic( + unsigned semantic_name, + unsigned semantic_index, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +/* + * immediate + */ + +struct tgsi_immediate +tgsi_default_immediate( void ); + +struct tgsi_immediate +tgsi_build_immediate( + struct tgsi_header *header ); + +struct tgsi_full_immediate +tgsi_default_full_immediate( void ); + +struct tgsi_immediate_float32 +tgsi_build_immediate_float32( + float value, + struct tgsi_immediate *immediate, + struct tgsi_header *header ); + +unsigned +tgsi_build_full_immediate( + const struct tgsi_full_immediate *full_imm, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ); + +/* + * instruction + */ + +struct tgsi_instruction +tgsi_default_instruction( void ); + +struct tgsi_instruction +tgsi_build_instruction( + unsigned opcode, + unsigned saturate, + unsigned num_dst_regs, + unsigned num_src_regs, + struct tgsi_header *header ); + +struct tgsi_full_instruction +tgsi_default_full_instruction( void ); + +unsigned +tgsi_build_full_instruction( + const struct tgsi_full_instruction *full_inst, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ); + +struct tgsi_instruction_ext_nv +tgsi_default_instruction_ext_nv( void ); + +unsigned +tgsi_compare_instruction_ext_nv( + struct tgsi_instruction_ext_nv a, + struct tgsi_instruction_ext_nv b ); + +struct tgsi_instruction_ext_nv +tgsi_build_instruction_ext_nv( + unsigned precision, + unsigned cond_dst_index, + unsigned cond_flow_index, + unsigned cond_mask, + unsigned cond_swizzle_x, + unsigned cond_swizzle_y, + unsigned cond_swizzle_z, + unsigned cond_swizzle_w, + unsigned cond_dst_update, + unsigned cond_flow_update, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_instruction_ext_label +tgsi_default_instruction_ext_label( void ); + +unsigned +tgsi_compare_instruction_ext_label( + struct tgsi_instruction_ext_label a, + struct tgsi_instruction_ext_label b ); + +struct tgsi_instruction_ext_label +tgsi_build_instruction_ext_label( + unsigned label, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_instruction_ext_texture +tgsi_default_instruction_ext_texture( void ); + +unsigned +tgsi_compare_instruction_ext_texture( + struct tgsi_instruction_ext_texture a, + struct tgsi_instruction_ext_texture b ); + +struct tgsi_instruction_ext_texture +tgsi_build_instruction_ext_texture( + unsigned texture, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_src_register +tgsi_default_src_register( void ); + +struct tgsi_src_register +tgsi_build_src_register( + unsigned file, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + unsigned negate, + unsigned indirect, + unsigned dimension, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_full_src_register +tgsi_default_full_src_register( void ); + +struct tgsi_src_register_ext_swz +tgsi_default_src_register_ext_swz( void ); + +unsigned +tgsi_compare_src_register_ext_swz( + struct tgsi_src_register_ext_swz a, + struct tgsi_src_register_ext_swz b ); + +struct tgsi_src_register_ext_swz +tgsi_build_src_register_ext_swz( + unsigned ext_swizzle_x, + unsigned ext_swizzle_y, + unsigned ext_swizzle_z, + unsigned ext_swizzle_w, + unsigned negate_x, + unsigned negate_y, + unsigned negate_z, + unsigned negate_w, + unsigned ext_divide, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_src_register_ext_mod +tgsi_default_src_register_ext_mod( void ); + +unsigned +tgsi_compare_src_register_ext_mod( + struct tgsi_src_register_ext_mod a, + struct tgsi_src_register_ext_mod b ); + +struct tgsi_src_register_ext_mod +tgsi_build_src_register_ext_mod( + unsigned complement, + unsigned bias, + unsigned scale_2x, + unsigned absolute, + unsigned negate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dimension +tgsi_default_dimension( void ); + +struct tgsi_dimension +tgsi_build_dimension( + unsigned indirect, + unsigned index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dst_register +tgsi_default_dst_register( void ); + +struct tgsi_dst_register +tgsi_build_dst_register( + unsigned file, + unsigned mask, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_full_dst_register +tgsi_default_full_dst_register( void ); + +struct tgsi_dst_register_ext_concode +tgsi_default_dst_register_ext_concode( void ); + +unsigned +tgsi_compare_dst_register_ext_concode( + struct tgsi_dst_register_ext_concode a, + struct tgsi_dst_register_ext_concode b ); + +struct tgsi_dst_register_ext_concode +tgsi_build_dst_register_ext_concode( + unsigned cc, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + int index, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dst_register_ext_modulate +tgsi_default_dst_register_ext_modulate( void ); + +unsigned +tgsi_compare_dst_register_ext_modulate( + struct tgsi_dst_register_ext_modulate a, + struct tgsi_dst_register_ext_modulate b ); + +struct tgsi_dst_register_ext_modulate +tgsi_build_dst_register_ext_modulate( + unsigned modulate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_BUILD_H + diff --git a/src/gallium/aux/tgsi/util/tgsi_dump.c b/src/gallium/aux/tgsi/util/tgsi_dump.c new file mode 100644 index 0000000000..b5c54847e0 --- /dev/null +++ b/src/gallium/aux/tgsi/util/tgsi_dump.c @@ -0,0 +1,1581 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi_dump.h" +#include "tgsi_parse.h" +#include "tgsi_build.h" + +struct gen_dump +{ + unsigned tabs; + void (* write)( + struct gen_dump *dump, + const void *data, + unsigned size ); +}; + +struct text_dump +{ + struct gen_dump base; + char *text; + unsigned length; + unsigned capacity; +}; + +static void +_text_dump_write( + struct gen_dump *dump, + const void *data, + unsigned size ) +{ + struct text_dump *td = (struct text_dump *) dump; + unsigned new_length = td->length + size; + + if( new_length >= td->capacity ) { + unsigned new_capacity = td->capacity; + + do { + if( new_capacity == 0 ) { + new_capacity = 256; + } + else { + new_capacity *= 2; + } + } while( new_length >= new_capacity ); + td->text = (char *) REALLOC( + td->text, + td->capacity, + new_capacity ); + td->capacity = new_capacity; + } + memcpy( + &td->text[td->length], + data, + size ); + td->length = new_length; + td->text[td->length] = '\0'; +} + +struct file_dump +{ + struct gen_dump base; + FILE *file; +}; + +static void +_file_dump_write( + struct gen_dump *dump, + const void *data, + unsigned size ) +{ + struct file_dump *fd = (struct file_dump *) dump; + +#if 0 + fwrite( data, 1, size, fd->file ); +#else + { + unsigned i; + + for (i = 0; i < size; i++ ) { + fprintf( fd->file, "%c", ((const char *) data)[i] ); + } + } +#endif +} + +static void +gen_dump_str( + struct gen_dump *dump, + const char *str ) +{ + unsigned i; + size_t len = strlen( str ); + + for (i = 0; i < len; i++) { + dump->write( dump, &str[i], 1 ); + if (str[i] == '\n') { + unsigned i; + + for (i = 0; i < dump->tabs; i++) { + dump->write( dump, " ", 4 ); + } + } + } +} + +static void +gen_dump_chr( + struct gen_dump *dump, + const char chr ) +{ + dump->write( dump, &chr, 1 ); +} + +static void +gen_dump_uix( + struct gen_dump *dump, + const unsigned ui ) +{ + char str[36]; + + sprintf( str, "0x%x", ui ); + gen_dump_str( dump, str ); +} + +static void +gen_dump_uid( + struct gen_dump *dump, + const unsigned ui ) +{ + char str[16]; + + sprintf( str, "%u", ui ); + gen_dump_str( dump, str ); +} + +static void +gen_dump_sid( + struct gen_dump *dump, + const int si ) +{ + char str[16]; + + sprintf( str, "%d", si ); + gen_dump_str( dump, str ); +} + +static void +gen_dump_flt( + struct gen_dump *dump, + const float flt ) +{ + char str[48]; + + sprintf( str, "%10.4f", flt ); + gen_dump_str( dump, str ); +} + +static void +gen_dump_enum( + struct gen_dump *dump, + const unsigned e, + const char **enums, + const unsigned enums_count ) +{ + if (e >= enums_count) { + gen_dump_uid( dump, e ); + } + else { + gen_dump_str( dump, enums[e] ); + } +} + +static void +gen_dump_tab( + struct gen_dump *dump ) +{ + ++dump->tabs; +} + +static void +gen_dump_untab( + struct gen_dump *dump ) +{ + assert( dump->tabs > 0 ); + + --dump->tabs; +} + +#define TXT(S) gen_dump_str( dump, S ) +#define CHR(C) gen_dump_chr( dump, C ) +#define UIX(I) gen_dump_uix( dump, I ) +#define UID(I) gen_dump_uid( dump, I ) +#define SID(I) gen_dump_sid( dump, I ) +#define FLT(F) gen_dump_flt( dump, F ) +#define TAB() gen_dump_tab( dump ) +#define UNT() gen_dump_untab( dump ) +#define ENM(E,ENUMS) gen_dump_enum( dump, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) + +static const char *TGSI_PROCESSOR_TYPES[] = +{ + "PROCESSOR_FRAGMENT", + "PROCESSOR_VERTEX", + "PROCESSOR_GEOMETRY" +}; + +static const char *TGSI_PROCESSOR_TYPES_SHORT[] = +{ + "FRAG", + "VERT", + "GEOM" +}; + +static const char *TGSI_TOKEN_TYPES[] = +{ + "TOKEN_TYPE_DECLARATION", + "TOKEN_TYPE_IMMEDIATE", + "TOKEN_TYPE_INSTRUCTION" +}; + +static const char *TGSI_FILES[] = +{ + "FILE_NULL", + "FILE_CONSTANT", + "FILE_INPUT", + "FILE_OUTPUT", + "FILE_TEMPORARY", + "FILE_SAMPLER", + "FILE_ADDRESS", + "FILE_IMMEDIATE" +}; + +static const char *TGSI_FILES_SHORT[] = +{ + "NULL", + "CONST", + "IN", + "OUT", + "TEMP", + "SAMP", + "ADDR", + "IMM" +}; + +static const char *TGSI_DECLARES[] = +{ + "DECLARE_RANGE", + "DECLARE_MASK" +}; + +static const char *TGSI_INTERPOLATES[] = +{ + "INTERPOLATE_CONSTANT", + "INTERPOLATE_LINEAR", + "INTERPOLATE_PERSPECTIVE", + "INTERPOLATE_ATTRIB" +}; + +static const char *TGSI_INTERPOLATES_SHORT[] = +{ + "CONSTANT", + "LINEAR", + "PERSPECTIVE", + "ATTRIB" +}; + +static const char *TGSI_SEMANTICS[] = +{ + "SEMANTIC_POSITION", + "SEMANTIC_COLOR", + "SEMANTIC_BCOLOR", + "SEMANTIC_FOG", + "SEMANTIC_PSIZE", + "SEMANTIC_GENERIC," +}; + +static const char *TGSI_SEMANTICS_SHORT[] = +{ + "POSITION", + "COLOR", + "BCOLOR", + "FOG", + "PSIZE", + "GENERIC", +}; + +static const char *TGSI_IMMS[] = +{ + "IMM_FLOAT32" +}; + +static const char *TGSI_IMMS_SHORT[] = +{ + "FLT32" +}; + +static const char *TGSI_OPCODES[] = +{ + "OPCODE_ARL", + "OPCODE_MOV", + "OPCODE_LIT", + "OPCODE_RCP", + "OPCODE_RSQ", + "OPCODE_EXP", + "OPCODE_LOG", + "OPCODE_MUL", + "OPCODE_ADD", + "OPCODE_DP3", + "OPCODE_DP4", + "OPCODE_DST", + "OPCODE_MIN", + "OPCODE_MAX", + "OPCODE_SLT", + "OPCODE_SGE", + "OPCODE_MAD", + "OPCODE_SUB", + "OPCODE_LERP", + "OPCODE_CND", + "OPCODE_CND0", + "OPCODE_DOT2ADD", + "OPCODE_INDEX", + "OPCODE_NEGATE", + "OPCODE_FRAC", + "OPCODE_CLAMP", + "OPCODE_FLOOR", + "OPCODE_ROUND", + "OPCODE_EXPBASE2", + "OPCODE_LOGBASE2", + "OPCODE_POWER", + "OPCODE_CROSSPRODUCT", + "OPCODE_MULTIPLYMATRIX", + "OPCODE_ABS", + "OPCODE_RCC", + "OPCODE_DPH", + "OPCODE_COS", + "OPCODE_DDX", + "OPCODE_DDY", + "OPCODE_KILP", + "OPCODE_PK2H", + "OPCODE_PK2US", + "OPCODE_PK4B", + "OPCODE_PK4UB", + "OPCODE_RFL", + "OPCODE_SEQ", + "OPCODE_SFL", + "OPCODE_SGT", + "OPCODE_SIN", + "OPCODE_SLE", + "OPCODE_SNE", + "OPCODE_STR", + "OPCODE_TEX", + "OPCODE_TXD", + "OPCODE_UP2H", + "OPCODE_UP2US", + "OPCODE_UP4B", + "OPCODE_UP4UB", + "OPCODE_X2D", + "OPCODE_ARA", + "OPCODE_ARR", + "OPCODE_BRA", + "OPCODE_CAL", + "OPCODE_RET", + "OPCODE_SSG", + "OPCODE_CMP", + "OPCODE_SCS", + "OPCODE_TXB", + "OPCODE_NRM", + "OPCODE_DIV", + "OPCODE_DP2", + "OPCODE_TXL", + "OPCODE_BRK", + "OPCODE_IF", + "OPCODE_LOOP", + "OPCODE_REP", + "OPCODE_ELSE", + "OPCODE_ENDIF", + "OPCODE_ENDLOOP", + "OPCODE_ENDREP", + "OPCODE_PUSHA", + "OPCODE_POPA", + "OPCODE_CEIL", + "OPCODE_I2F", + "OPCODE_NOT", + "OPCODE_TRUNC", + "OPCODE_SHL", + "OPCODE_SHR", + "OPCODE_AND", + "OPCODE_OR", + "OPCODE_MOD", + "OPCODE_XOR", + "OPCODE_SAD", + "OPCODE_TXF", + "OPCODE_TXQ", + "OPCODE_CONT", + "OPCODE_EMIT", + "OPCODE_ENDPRIM", + "OPCODE_BGNLOOP2", + "OPCODE_BGNSUB", + "OPCODE_ENDLOOP2", + "OPCODE_ENDSUB", + "OPCODE_NOISE1", + "OPCODE_NOISE2", + "OPCODE_NOISE3", + "OPCODE_NOISE4", + "OPCODE_NOP", + "OPCODE_TEXBEM", + "OPCODE_TEXBEML", + "OPCODE_TEXREG2AR", + "OPCODE_TEXM3X2PAD", + "OPCODE_TEXM3X2TEX", + "OPCODE_TEXM3X3PAD", + "OPCODE_TEXM3X3TEX", + "OPCODE_TEXM3X3SPEC", + "OPCODE_TEXM3X3VSPEC", + "OPCODE_TEXREG2GB", + "OPCODE_TEXREG2RGB", + "OPCODE_TEXDP3TEX", + "OPCODE_TEXDP3", + "OPCODE_TEXM3X3", + "OPCODE_TEXM3X2DEPTH", + "OPCODE_TEXDEPTH", + "OPCODE_BEM", + "OPCODE_M4X3", + "OPCODE_M3X4", + "OPCODE_M3X3", + "OPCODE_M3X2", + "OPCODE_NRM4", + "OPCODE_CALLNZ", + "OPCODE_IFC", + "OPCODE_BREAKC", + "OPCODE_KIL", + "OPCODE_END" +}; + +static const char *TGSI_OPCODES_SHORT[] = +{ + "ARL", + "MOV", + "LIT", + "RCP", + "RSQ", + "EXP", + "LOG", + "MUL", + "ADD", + "DP3", + "DP4", + "DST", + "MIN", + "MAX", + "SLT", + "SGE", + "MAD", + "SUB", + "LERP", + "CND", + "CND0", + "DOT2ADD", + "INDEX", + "NEGATE", + "FRAC", + "CLAMP", + "FLOOR", + "ROUND", + "EXPBASE2", + "LOGBASE2", + "POWER", + "CROSSPRODUCT", + "MULTIPLYMATRIX", + "ABS", + "RCC", + "DPH", + "COS", + "DDX", + "DDY", + "KILP", + "PK2H", + "PK2US", + "PK4B", + "PK4UB", + "RFL", + "SEQ", + "SFL", + "SGT", + "SIN", + "SLE", + "SNE", + "STR", + "TEX", + "TXD", + "UP2H", + "UP2US", + "UP4B", + "UP4UB", + "X2D", + "ARA", + "ARR", + "BRA", + "CAL", + "RET", + "SSG", + "CMP", + "SCS", + "TXB", + "NRM", + "DIV", + "DP2", + "TXL", + "BRK", + "IF", + "LOOP", + "REP", + "ELSE", + "ENDIF", + "ENDLOOP", + "ENDREP", + "PUSHA", + "POPA", + "CEIL", + "I2F", + "NOT", + "TRUNC", + "SHL", + "SHR", + "AND", + "OR", + "MOD", + "XOR", + "SAD", + "TXF", + "TXQ", + "CONT", + "EMIT", + "ENDPRIM", + "BGNLOOP2", + "BGNSUB", + "ENDLOOP2", + "ENDSUB", + "NOISE1", + "NOISE2", + "NOISE3", + "NOISE4", + "NOP", + "TEXBEM", + "TEXBEML", + "TEXREG2AR", + "TEXM3X2PAD", + "TEXM3X2TEX", + "TEXM3X3PAD", + "TEXM3X3TEX", + "TEXM3X3SPEC", + "TEXM3X3VSPEC", + "TEXREG2GB", + "TEXREG2RGB", + "TEXDP3TEX", + "TEXDP3", + "TEXM3X3", + "TEXM3X2DEPTH", + "TEXDEPTH", + "BEM", + "M4X3", + "M3X4", + "M3X3", + "M3X2", + "NRM4", + "CALLNZ", + "IFC", + "BREAKC", + "KIL", + "END" +}; + +static const char *TGSI_SATS[] = +{ + "SAT_NONE", + "SAT_ZERO_ONE", + "SAT_MINUS_PLUS_ONE" +}; + +static const char *TGSI_INSTRUCTION_EXTS[] = +{ + "INSTRUCTION_EXT_TYPE_NV", + "INSTRUCTION_EXT_TYPE_LABEL", + "INSTRUCTION_EXT_TYPE_TEXTURE" +}; + +static const char *TGSI_PRECISIONS[] = +{ + "PRECISION_DEFAULT", + "TGSI_PRECISION_FLOAT32", + "TGSI_PRECISION_FLOAT16", + "TGSI_PRECISION_FIXED12" +}; + +static const char *TGSI_CCS[] = +{ + "CC_GT", + "CC_EQ", + "CC_LT", + "CC_UN", + "CC_GE", + "CC_LE", + "CC_NE", + "CC_TR", + "CC_FL" +}; + +static const char *TGSI_SWIZZLES[] = +{ + "SWIZZLE_X", + "SWIZZLE_Y", + "SWIZZLE_Z", + "SWIZZLE_W" +}; + +static const char *TGSI_SWIZZLES_SHORT[] = +{ + "x", + "y", + "z", + "w" +}; + +static const char *TGSI_TEXTURES[] = +{ + "TEXTURE_UNKNOWN", + "TEXTURE_1D", + "TEXTURE_2D", + "TEXTURE_3D", + "TEXTURE_CUBE", + "TEXTURE_RECT", + "TEXTURE_SHADOW1D", + "TEXTURE_SHADOW2D", + "TEXTURE_SHADOWRECT" +}; + +static const char *TGSI_SRC_REGISTER_EXTS[] = +{ + "SRC_REGISTER_EXT_TYPE_SWZ", + "SRC_REGISTER_EXT_TYPE_MOD" +}; + +static const char *TGSI_EXTSWIZZLES[] = +{ + "EXTSWIZZLE_X", + "EXTSWIZZLE_Y", + "EXTSWIZZLE_Z", + "EXTSWIZZLE_W", + "EXTSWIZZLE_ZERO", + "EXTSWIZZLE_ONE" +}; + +static const char *TGSI_EXTSWIZZLES_SHORT[] = +{ + "x", + "y", + "z", + "w", + "0", + "1" +}; + +static const char *TGSI_WRITEMASKS[] = +{ + "0", + "WRITEMASK_X", + "WRITEMASK_Y", + "WRITEMASK_XY", + "WRITEMASK_Z", + "WRITEMASK_XZ", + "WRITEMASK_YZ", + "WRITEMASK_XYZ", + "WRITEMASK_W", + "WRITEMASK_XW", + "WRITEMASK_YW", + "WRITEMASK_XYW", + "WRITEMASK_ZW", + "WRITEMASK_XZW", + "WRITEMASK_YZW", + "WRITEMASK_XYZW" +}; + +static const char *TGSI_DST_REGISTER_EXTS[] = +{ + "DST_REGISTER_EXT_TYPE_CONDCODE", + "DST_REGISTER_EXT_TYPE_MODULATE" +}; + +static const char *TGSI_MODULATES[] = +{ + "MODULATE_1X", + "MODULATE_2X", + "MODULATE_4X", + "MODULATE_8X", + "MODULATE_HALF", + "MODULATE_QUARTER", + "MODULATE_EIGHTH" +}; + +static void +dump_declaration_short( + struct gen_dump *dump, + struct tgsi_full_declaration *decl ) +{ + TXT( "\nDCL " ); + ENM( decl->Declaration.File, TGSI_FILES_SHORT ); + + switch( decl->Declaration.Declare ) { + case TGSI_DECLARE_RANGE: + CHR( '[' ); + UID( decl->u.DeclarationRange.First ); + if( decl->u.DeclarationRange.First != decl->u.DeclarationRange.Last ) { + TXT( ".." ); + UID( decl->u.DeclarationRange.Last ); + } + CHR( ']' ); + break; + default: + assert( 0 ); + } + + if( decl->Declaration.UsageMask != TGSI_WRITEMASK_XYZW ) { + CHR( '.' ); + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { + CHR( 'x' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { + CHR( 'y' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { + CHR( 'z' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { + CHR( 'w' ); + } + } + + if( decl->Declaration.Interpolate ) { + TXT( ", " ); + ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES_SHORT ); + } + + if( decl->Declaration.Semantic ) { + TXT( ", " ); + ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT ); + CHR( '[' ); + UID( decl->Semantic.SemanticIndex ); + CHR( ']' ); + } +} + +static void +dump_declaration_verbose( + struct gen_dump *dump, + struct tgsi_full_declaration *decl, + unsigned ignored, + unsigned deflt, + struct tgsi_full_declaration *fd ) +{ + TXT( "\nFile : " ); + ENM( decl->Declaration.File, TGSI_FILES ); + TXT( "\nDeclare : " ); + ENM( decl->Declaration.Declare, TGSI_DECLARES ); + if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) { + TXT( "\nUsageMask : " ); + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { + CHR( 'X' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { + CHR( 'Y' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { + CHR( 'Z' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { + CHR( 'W' ); + } + } + if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) { + TXT( "\nInterpolate: " ); + UID( decl->Declaration.Interpolate ); + } + if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) { + TXT( "\nSemantic : " ); + UID( decl->Declaration.Semantic ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Declaration.Padding ); + } + + CHR( '\n' ); + switch( decl->Declaration.Declare ) { + case TGSI_DECLARE_RANGE: + TXT( "\nFirst: " ); + UID( decl->u.DeclarationRange.First ); + TXT( "\nLast : " ); + UID( decl->u.DeclarationRange.Last ); + break; + + case TGSI_DECLARE_MASK: + TXT( "\nMask: " ); + UIX( decl->u.DeclarationMask.Mask ); + break; + + default: + assert( 0 ); + } + + if( decl->Declaration.Interpolate ) { + CHR( '\n' ); + TXT( "\nInterpolate: " ); + ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Interpolation.Padding ); + } + } + + if( decl->Declaration.Semantic ) { + CHR( '\n' ); + TXT( "\nSemanticName : " ); + ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS ); + TXT( "\nSemanticIndex: " ); + UID( decl->Semantic.SemanticIndex ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Semantic.Padding ); + } + } +} + +static void +dump_immediate_short( + struct gen_dump *dump, + struct tgsi_full_immediate *imm ) +{ + unsigned i; + + TXT( "\nIMM " ); + ENM( imm->Immediate.DataType, TGSI_IMMS_SHORT ); + + TXT( " { " ); + for( i = 0; i < imm->Immediate.Size - 1; i++ ) { + switch( imm->Immediate.DataType ) { + case TGSI_IMM_FLOAT32: + FLT( imm->u.ImmediateFloat32[i].Float ); + break; + + default: + assert( 0 ); + } + + if( i < imm->Immediate.Size - 2 ) { + TXT( ", " ); + } + } + TXT( " }" ); +} + +static void +dump_immediate_verbose( + struct gen_dump *dump, + struct tgsi_full_immediate *imm, + unsigned ignored ) +{ + unsigned i; + + TXT( "\nDataType : " ); + ENM( imm->Immediate.DataType, TGSI_IMMS ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( imm->Immediate.Padding ); + } + + for( i = 0; i < imm->Immediate.Size - 1; i++ ) { + CHR( '\n' ); + switch( imm->Immediate.DataType ) { + case TGSI_IMM_FLOAT32: + TXT( "\nFloat: " ); + FLT( imm->u.ImmediateFloat32[i].Float ); + break; + + default: + assert( 0 ); + } + } +} + +static void +dump_instruction_short( + struct gen_dump *dump, + struct tgsi_full_instruction *inst, + unsigned instno ) +{ + unsigned i; + boolean first_reg = TRUE; + + CHR( '\n' ); + UID( instno ); + CHR( ':' ); + ENM( inst->Instruction.Opcode, TGSI_OPCODES_SHORT ); + + switch( inst->Instruction.Saturate ) { + case TGSI_SAT_NONE: + break; + case TGSI_SAT_ZERO_ONE: + TXT( "_SAT" ); + break; + case TGSI_SAT_MINUS_PLUS_ONE: + TXT( "_SAT[-1,1]" ); + break; + default: + assert( 0 ); + } + + for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + + if( !first_reg ) { + CHR( ',' ); + } + CHR( ' ' ); + + ENM( dst->DstRegister.File, TGSI_FILES_SHORT ); + + CHR( '[' ); + SID( dst->DstRegister.Index ); + CHR( ']' ); + + if( dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW ) { + CHR( '.' ); + if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_X ) { + CHR( 'x' ); + } + if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_Y ) { + CHR( 'y' ); + } + if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_Z ) { + CHR( 'z' ); + } + if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_W ) { + CHR( 'w' ); + } + } + + first_reg = FALSE; + } + + for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + + if( !first_reg ) { + CHR( ',' ); + } + CHR( ' ' ); + + if( src->SrcRegisterExtMod.Complement ) { + TXT( "(1 - " ); + } + if( src->SrcRegisterExtMod.Negate ) { + CHR( '-' ); + } + if( src->SrcRegisterExtMod.Absolute ) { + CHR( '|' ); + } + if( src->SrcRegister.Negate ) { + CHR( '-' ); + } + + ENM( src->SrcRegister.File, TGSI_FILES_SHORT ); + + CHR( '[' ); + SID( src->SrcRegister.Index ); + CHR( ']' ); + + if (src->SrcRegister.Extended) { + if (src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || + src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || + src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || + src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) { + CHR( '.' ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES_SHORT ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES_SHORT ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES_SHORT ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES_SHORT ); + } + } + else if( src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || + src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || + src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || + src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W ) { + CHR( '.' ); + ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES_SHORT ); + ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES_SHORT ); + ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES_SHORT ); + ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES_SHORT ); + } + + if( src->SrcRegisterExtMod.Absolute ) { + CHR( '|' ); + } + if( src->SrcRegisterExtMod.Complement ) { + CHR( ')' ); + } + + first_reg = FALSE; + } + + switch( inst->Instruction.Opcode ) { + case TGSI_OPCODE_IF: + case TGSI_OPCODE_ELSE: + case TGSI_OPCODE_BGNLOOP2: + case TGSI_OPCODE_ENDLOOP2: + case TGSI_OPCODE_CAL: + TXT( " :" ); + UID( inst->InstructionExtLabel.Label ); + break; + } +} + +static void +dump_instruction_verbose( + struct gen_dump *dump, + struct tgsi_full_instruction *inst, + unsigned ignored, + unsigned deflt, + struct tgsi_full_instruction *fi ) +{ + unsigned i; + + TXT( "\nOpcode : " ); + ENM( inst->Instruction.Opcode, TGSI_OPCODES ); + if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) { + TXT( "\nSaturate : " ); + ENM( inst->Instruction.Saturate, TGSI_SATS ); + } + if( deflt || fi->Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) { + TXT( "\nNumDstRegs : " ); + UID( inst->Instruction.NumDstRegs ); + } + if( deflt || fi->Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) { + TXT( "\nNumSrcRegs : " ); + UID( inst->Instruction.NumSrcRegs ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->Instruction.Padding ); + } + + if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi->InstructionExtNv ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) { + TXT( "\nPrecision : " ); + ENM( inst->InstructionExtNv.Precision, TGSI_PRECISIONS ); + } + if( deflt || fi->InstructionExtNv.CondDstIndex != inst->InstructionExtNv.CondDstIndex ) { + TXT( "\nCondDstIndex : " ); + UID( inst->InstructionExtNv.CondDstIndex ); + } + if( deflt || fi->InstructionExtNv.CondFlowIndex != inst->InstructionExtNv.CondFlowIndex ) { + TXT( "\nCondFlowIndex : " ); + UID( inst->InstructionExtNv.CondFlowIndex ); + } + if( deflt || fi->InstructionExtNv.CondMask != inst->InstructionExtNv.CondMask ) { + TXT( "\nCondMask : " ); + ENM( inst->InstructionExtNv.CondMask, TGSI_CCS ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleX != inst->InstructionExtNv.CondSwizzleX ) { + TXT( "\nCondSwizzleX : " ); + ENM( inst->InstructionExtNv.CondSwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleY != inst->InstructionExtNv.CondSwizzleY ) { + TXT( "\nCondSwizzleY : " ); + ENM( inst->InstructionExtNv.CondSwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleZ != inst->InstructionExtNv.CondSwizzleZ ) { + TXT( "\nCondSwizzleZ : " ); + ENM( inst->InstructionExtNv.CondSwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleW != inst->InstructionExtNv.CondSwizzleW ) { + TXT( "\nCondSwizzleW : " ); + ENM( inst->InstructionExtNv.CondSwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondDstUpdate != inst->InstructionExtNv.CondDstUpdate ) { + TXT( "\nCondDstUpdate : " ); + UID( inst->InstructionExtNv.CondDstUpdate ); + } + if( deflt || fi->InstructionExtNv.CondFlowEnable != inst->InstructionExtNv.CondFlowEnable ) { + TXT( "\nCondFlowEnable: " ); + UID( inst->InstructionExtNv.CondFlowEnable ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtNv.Padding ); + if( deflt || fi->InstructionExtNv.Extended != inst->InstructionExtNv.Extended ) { + TXT( "\nExtended : " ); + UID( inst->InstructionExtNv.Extended ); + } + } + } + + if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) { + TXT( "\nLabel : " ); + UID( inst->InstructionExtLabel.Label ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtLabel.Padding ); + if( deflt || fi->InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) { + TXT( "\nExtended: " ); + UID( inst->InstructionExtLabel.Extended ); + } + } + } + + if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) { + TXT( "\nTexture : " ); + ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtTexture.Padding ); + if( deflt || fi->InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) { + TXT( "\nExtended: " ); + UID( inst->InstructionExtTexture.Extended ); + } + } + } + + for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i]; + + CHR( '\n' ); + TXT( "\nFile : " ); + ENM( dst->DstRegister.File, TGSI_FILES ); + if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) { + TXT( "\nWriteMask: " ); + ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS ); + } + if( ignored ) { + if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) { + TXT( "\nIndirect : " ); + UID( dst->DstRegister.Indirect ); + } + if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) { + TXT( "\nDimension: " ); + UID( dst->DstRegister.Dimension ); + } + } + if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) { + TXT( "\nIndex : " ); + SID( dst->DstRegister.Index ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegister.Padding ); + if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) { + TXT( "\nExtended : " ); + UID( dst->DstRegister.Extended ); + } + } + + if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS ); + if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) { + TXT( "\nCondMask : " ); + ENM( dst->DstRegisterExtConcode.CondMask, TGSI_CCS ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleX != dst->DstRegisterExtConcode.CondSwizzleX ) { + TXT( "\nCondSwizzleX: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleY != dst->DstRegisterExtConcode.CondSwizzleY ) { + TXT( "\nCondSwizzleY: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleZ != dst->DstRegisterExtConcode.CondSwizzleZ ) { + TXT( "\nCondSwizzleZ: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleW != dst->DstRegisterExtConcode.CondSwizzleW ) { + TXT( "\nCondSwizzleW: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSrcIndex != dst->DstRegisterExtConcode.CondSrcIndex ) { + TXT( "\nCondSrcIndex: " ); + UID( dst->DstRegisterExtConcode.CondSrcIndex ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegisterExtConcode.Padding ); + if( deflt || fd->DstRegisterExtConcode.Extended != dst->DstRegisterExtConcode.Extended ) { + TXT( "\nExtended : " ); + UID( dst->DstRegisterExtConcode.Extended ); + } + } + } + + if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS ); + if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) { + TXT( "\nModulate: " ); + ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegisterExtModulate.Padding ); + if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) { + TXT( "\nExtended: " ); + UID( dst->DstRegisterExtModulate.Extended ); + } + } + } + } + + for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i]; + + CHR( '\n' ); + TXT( "\nFile : "); + ENM( src->SrcRegister.File, TGSI_FILES ); + if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) { + TXT( "\nSwizzleX : " ); + ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) { + TXT( "\nSwizzleY : " ); + ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) { + TXT( "\nSwizzleZ : " ); + ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) { + TXT( "\nSwizzleW : " ); + ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) { + TXT( "\nNegate : " ); + UID( src->SrcRegister.Negate ); + } + if( ignored ) { + if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) { + TXT( "\nIndirect : " ); + UID( src->SrcRegister.Indirect ); + } + if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) { + TXT( "\nDimension: " ); + UID( src->SrcRegister.Dimension ); + } + } + if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) { + TXT( "\nIndex : " ); + SID( src->SrcRegister.Index ); + } + if( ignored ) { + if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegister.Extended ); + } + } + + if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS ); + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) { + TXT( "\nExtSwizzleX: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleY != src->SrcRegisterExtSwz.ExtSwizzleY ) { + TXT( "\nExtSwizzleY: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleZ != src->SrcRegisterExtSwz.ExtSwizzleZ ) { + TXT( "\nExtSwizzleZ: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleW != src->SrcRegisterExtSwz.ExtSwizzleW ) { + TXT( "\nExtSwizzleW: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateX != src->SrcRegisterExtSwz.NegateX ) { + TXT( "\nNegateX : " ); + UID( src->SrcRegisterExtSwz.NegateX ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateY != src->SrcRegisterExtSwz.NegateY ) { + TXT( "\nNegateY : " ); + UID( src->SrcRegisterExtSwz.NegateY ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateZ != src->SrcRegisterExtSwz.NegateZ ) { + TXT( "\nNegateZ : " ); + UID( src->SrcRegisterExtSwz.NegateZ ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateW != src->SrcRegisterExtSwz.NegateW ) { + TXT( "\nNegateW : " ); + UID( src->SrcRegisterExtSwz.NegateW ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtDivide != src->SrcRegisterExtSwz.ExtDivide ) { + TXT( "\nExtDivide : " ); + ENM( src->SrcRegisterExtSwz.ExtDivide, TGSI_EXTSWIZZLES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( src->SrcRegisterExtSwz.Padding ); + if( deflt || fs->SrcRegisterExtSwz.Extended != src->SrcRegisterExtSwz.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegisterExtSwz.Extended ); + } + } + } + + if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS ); + if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) { + TXT( "\nComplement: " ); + UID( src->SrcRegisterExtMod.Complement ); + } + if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) { + TXT( "\nBias : " ); + UID( src->SrcRegisterExtMod.Bias ); + } + if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) { + TXT( "\nScale2X : " ); + UID( src->SrcRegisterExtMod.Scale2X ); + } + if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) { + TXT( "\nAbsolute : " ); + UID( src->SrcRegisterExtMod.Absolute ); + } + if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) { + TXT( "\nNegate : " ); + UID( src->SrcRegisterExtMod.Negate ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( src->SrcRegisterExtMod.Padding ); + if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegisterExtMod.Extended ); + } + } + } + } +} + +static void +dump_gen( + struct gen_dump *dump, + const struct tgsi_token *tokens, + unsigned flags ) +{ + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + unsigned verbose = flags & TGSI_DUMP_VERBOSE; + unsigned ignored = !(flags & TGSI_DUMP_NO_IGNORED); + unsigned deflt = !(flags & TGSI_DUMP_NO_DEFAULT); + unsigned instno = 0; + + dump->tabs = 0; + + /* sanity check */ + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); + + tgsi_parse_init( &parse, tokens ); + + TXT( "tgsi-dump begin -----------------" ); + + CHR( '\n' ); + ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES_SHORT ); + CHR( ' ' ); + UID( parse.FullVersion.Version.MajorVersion ); + CHR( '.' ); + UID( parse.FullVersion.Version.MinorVersion ); + + if( verbose ) { + TXT( "\nMajorVersion: " ); + UID( parse.FullVersion.Version.MajorVersion ); + TXT( "\nMinorVersion: " ); + UID( parse.FullVersion.Version.MinorVersion ); + CHR( '\n' ); + + TXT( "\nHeaderSize: " ); + UID( parse.FullHeader.Header.HeaderSize ); + TXT( "\nBodySize : " ); + UID( parse.FullHeader.Header.BodySize ); + TXT( "\nProcessor : " ); + ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); + CHR( '\n' ); + } + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + + while( !tgsi_parse_end_of_tokens( &parse ) ) { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + dump_declaration_short( + dump, + &parse.FullToken.FullDeclaration ); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + dump_immediate_short( + dump, + &parse.FullToken.FullImmediate ); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + dump_instruction_short( + dump, + &parse.FullToken.FullInstruction, + instno ); + instno++; + break; + + default: + assert( 0 ); + } + + if( verbose ) { + TXT( "\nType : " ); + ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES ); + if( ignored ) { + TXT( "\nSize : " ); + UID( parse.FullToken.Token.Size ); + if( deflt || parse.FullToken.Token.Extended ) { + TXT( "\nExtended : " ); + UID( parse.FullToken.Token.Extended ); + } + } + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + dump_declaration_verbose( + dump, + &parse.FullToken.FullDeclaration, + ignored, + deflt, + &fd ); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + dump_immediate_verbose( + dump, + &parse.FullToken.FullImmediate, + ignored ); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + dump_instruction_verbose( + dump, + &parse.FullToken.FullInstruction, + ignored, + deflt, + &fi ); + break; + + default: + assert( 0 ); + } + + CHR( '\n' ); + } + } + + TXT( "\ntgsi-dump end -------------------\n" ); + + tgsi_parse_free( &parse ); +} + + +static void +sanity_checks(void) +{ + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); + assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "END") == 0); +} + + +void +tgsi_dump( + const struct tgsi_token *tokens, + unsigned flags ) +{ + struct file_dump dump; + + sanity_checks(); + + dump.base.write = _file_dump_write; +#if 0 + { + static unsigned counter = 0; + char buffer[64]; + sprintf( buffer, "tgsi-dump-%.4u.txt", counter++ ); + dump.file = fopen( buffer, "wt" ); + } +#else + dump.file = stderr; +#endif + + dump_gen( + &dump.base, + tokens, + flags ); + +#if 0 + fclose( dump.file ); +#endif +} + +void +tgsi_dump_str( + char **str, + const struct tgsi_token *tokens, + unsigned flags ) +{ + struct text_dump dump; + + dump.base.write = _text_dump_write; + dump.text = NULL; + dump.length = 0; + dump.capacity = 0; + + dump_gen( + &dump.base, + tokens, + flags ); + + *str = dump.text; +} diff --git a/src/gallium/aux/tgsi/util/tgsi_dump.h b/src/gallium/aux/tgsi/util/tgsi_dump.h new file mode 100644 index 0000000000..1adc9db251 --- /dev/null +++ b/src/gallium/aux/tgsi/util/tgsi_dump.h @@ -0,0 +1,28 @@ +#if !defined TGSI_DUMP_H +#define TGSI_DUMP_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +#define TGSI_DUMP_VERBOSE 1 +#define TGSI_DUMP_NO_IGNORED 2 +#define TGSI_DUMP_NO_DEFAULT 4 + +void +tgsi_dump( + const struct tgsi_token *tokens, + unsigned flags ); + +void +tgsi_dump_str( + char **str, + const struct tgsi_token *tokens, + unsigned flags ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_DUMP_H + diff --git a/src/gallium/aux/tgsi/util/tgsi_parse.c b/src/gallium/aux/tgsi/util/tgsi_parse.c new file mode 100644 index 0000000000..bf6b89ce56 --- /dev/null +++ b/src/gallium/aux/tgsi/util/tgsi_parse.c @@ -0,0 +1,319 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi_parse.h" +#include "tgsi_build.h" + +void +tgsi_full_token_init( + union tgsi_full_token *full_token ) +{ + full_token->Token.Type = TGSI_TOKEN_TYPE_DECLARATION; +} + +void +tgsi_full_token_free( + union tgsi_full_token *full_token ) +{ + if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE ) { + FREE( full_token->FullImmediate.u.Pointer ); + } +} + +unsigned +tgsi_parse_init( + struct tgsi_parse_context *ctx, + const struct tgsi_token *tokens ) +{ + ctx->FullVersion.Version = *(struct tgsi_version *) &tokens[0]; + if( ctx->FullVersion.Version.MajorVersion > 1 ) { + return TGSI_PARSE_ERROR; + } + + ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[1]; + if( ctx->FullHeader.Header.HeaderSize >= 2 ) { + ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[2]; + } + else { + ctx->FullHeader.Processor = tgsi_default_processor(); + } + + ctx->Tokens = tokens; + ctx->Position = 1 + ctx->FullHeader.Header.HeaderSize; + + tgsi_full_token_init( &ctx->FullToken ); + + return TGSI_PARSE_OK; +} + +void +tgsi_parse_free( + struct tgsi_parse_context *ctx ) +{ + tgsi_full_token_free( &ctx->FullToken ); +} + +boolean +tgsi_parse_end_of_tokens( + struct tgsi_parse_context *ctx ) +{ + return ctx->Position >= + 1 + ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize; +} + +static void +next_token( + struct tgsi_parse_context *ctx, + void *token ) +{ + assert( !tgsi_parse_end_of_tokens( ctx ) ); + + *(struct tgsi_token *) token = ctx->Tokens[ctx->Position++]; +} + +void +tgsi_parse_token( + struct tgsi_parse_context *ctx ) +{ + struct tgsi_token token; + unsigned i; + + tgsi_full_token_free( &ctx->FullToken ); + tgsi_full_token_init( &ctx->FullToken ); + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + struct tgsi_full_declaration *decl = &ctx->FullToken.FullDeclaration; + + *decl = tgsi_default_full_declaration(); + decl->Declaration = *(struct tgsi_declaration *) &token; + + switch( decl->Declaration.Type ) { + case TGSI_DECLARE_RANGE: + next_token( ctx, &decl->u.DeclarationRange ); + break; + + case TGSI_DECLARE_MASK: + next_token( ctx, &decl->u.DeclarationMask ); + break; + + default: + assert (0); + } + + if( decl->Declaration.Interpolate ) { + next_token( ctx, &decl->Interpolation ); + } + + if( decl->Declaration.Semantic ) { + next_token( ctx, &decl->Semantic ); + } + + break; + } + + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate; + + *imm = tgsi_default_full_immediate(); + imm->Immediate = *(struct tgsi_immediate *) &token; + + assert( !imm->Immediate.Extended ); + + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + imm->u.Pointer = MALLOC( + sizeof( struct tgsi_immediate_float32 ) * (imm->Immediate.Size - 1) ); + for( i = 0; i < imm->Immediate.Size - 1; i++ ) { + next_token( ctx, &imm->u.ImmediateFloat32[i] ); + } + break; + + default: + assert( 0 ); + } + + break; + } + + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction; + unsigned extended; + + *inst = tgsi_default_full_instruction(); + inst->Instruction = *(struct tgsi_instruction *) &token; + + extended = inst->Instruction.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_INSTRUCTION_EXT_TYPE_NV: + inst->InstructionExtNv = + *(struct tgsi_instruction_ext_nv *) &token; + break; + + case TGSI_INSTRUCTION_EXT_TYPE_LABEL: + inst->InstructionExtLabel = + *(struct tgsi_instruction_ext_label *) &token; + break; + + case TGSI_INSTRUCTION_EXT_TYPE_TEXTURE: + inst->InstructionExtTexture = + *(struct tgsi_instruction_ext_texture *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + + assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS ); + + for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + unsigned extended; + + next_token( ctx, &inst->FullDstRegisters[i].DstRegister ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullDstRegisters[i].DstRegister.Indirect ); + assert( !inst->FullDstRegisters[i].DstRegister.Dimension ); + + extended = inst->FullDstRegisters[i].DstRegister.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_DST_REGISTER_EXT_TYPE_CONDCODE: + inst->FullDstRegisters[i].DstRegisterExtConcode = + *(struct tgsi_dst_register_ext_concode *) &token; + break; + + case TGSI_DST_REGISTER_EXT_TYPE_MODULATE: + inst->FullDstRegisters[i].DstRegisterExtModulate = + *(struct tgsi_dst_register_ext_modulate *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + } + + assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS ); + + for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + unsigned extended; + + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegister ); + + extended = inst->FullSrcRegisters[i].SrcRegister.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_SRC_REGISTER_EXT_TYPE_SWZ: + inst->FullSrcRegisters[i].SrcRegisterExtSwz = + *(struct tgsi_src_register_ext_swz *) &token; + break; + + case TGSI_SRC_REGISTER_EXT_TYPE_MOD: + inst->FullSrcRegisters[i].SrcRegisterExtMod = + *(struct tgsi_src_register_ext_mod *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + + if( inst->FullSrcRegisters[i].SrcRegister.Indirect ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterInd ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); + } + + if( inst->FullSrcRegisters[i].SrcRegister.Dimension ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDim ); + + /* + * No support for multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Extended ); + + if( inst->FullSrcRegisters[i].SrcRegisterDim.Indirect ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDimInd ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); + } + } + } + + break; + } + + default: + assert( 0 ); + } +} + diff --git a/src/gallium/aux/tgsi/util/tgsi_parse.h b/src/gallium/aux/tgsi/util/tgsi_parse.h new file mode 100644 index 0000000000..9372da8d5d --- /dev/null +++ b/src/gallium/aux/tgsi/util/tgsi_parse.h @@ -0,0 +1,121 @@ +#if !defined TGSI_PARSE_H +#define TGSI_PARSE_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +struct tgsi_full_version +{ + struct tgsi_version Version; +}; + +struct tgsi_full_header +{ + struct tgsi_header Header; + struct tgsi_processor Processor; +}; + +struct tgsi_full_dst_register +{ + struct tgsi_dst_register DstRegister; + struct tgsi_dst_register_ext_concode DstRegisterExtConcode; + struct tgsi_dst_register_ext_modulate DstRegisterExtModulate; +}; + +struct tgsi_full_src_register +{ + struct tgsi_src_register SrcRegister; + struct tgsi_src_register_ext_swz SrcRegisterExtSwz; + struct tgsi_src_register_ext_mod SrcRegisterExtMod; + struct tgsi_src_register SrcRegisterInd; + struct tgsi_dimension SrcRegisterDim; + struct tgsi_src_register SrcRegisterDimInd; +}; + +struct tgsi_full_declaration +{ + struct tgsi_declaration Declaration; + union + { + struct tgsi_declaration_range DeclarationRange; + struct tgsi_declaration_mask DeclarationMask; + } u; + struct tgsi_declaration_interpolation Interpolation; + struct tgsi_declaration_semantic Semantic; +}; + +struct tgsi_full_immediate +{ + struct tgsi_immediate Immediate; + union + { + void *Pointer; + struct tgsi_immediate_float32 *ImmediateFloat32; + } u; +}; + +#define TGSI_FULL_MAX_DST_REGISTERS 2 +#define TGSI_FULL_MAX_SRC_REGISTERS 3 + +struct tgsi_full_instruction +{ + struct tgsi_instruction Instruction; + struct tgsi_instruction_ext_nv InstructionExtNv; + struct tgsi_instruction_ext_label InstructionExtLabel; + struct tgsi_instruction_ext_texture InstructionExtTexture; + struct tgsi_full_dst_register FullDstRegisters[TGSI_FULL_MAX_DST_REGISTERS]; + struct tgsi_full_src_register FullSrcRegisters[TGSI_FULL_MAX_SRC_REGISTERS]; +}; + +union tgsi_full_token +{ + struct tgsi_token Token; + struct tgsi_full_declaration FullDeclaration; + struct tgsi_full_immediate FullImmediate; + struct tgsi_full_instruction FullInstruction; +}; + +void +tgsi_full_token_init( + union tgsi_full_token *full_token ); + +void +tgsi_full_token_free( + union tgsi_full_token *full_token ); + +struct tgsi_parse_context +{ + const struct tgsi_token *Tokens; + unsigned Position; + struct tgsi_full_version FullVersion; + struct tgsi_full_header FullHeader; + union tgsi_full_token FullToken; +}; + +#define TGSI_PARSE_OK 0 +#define TGSI_PARSE_ERROR 1 + +unsigned +tgsi_parse_init( + struct tgsi_parse_context *ctx, + const struct tgsi_token *tokens ); + +void +tgsi_parse_free( + struct tgsi_parse_context *ctx ); + +boolean +tgsi_parse_end_of_tokens( + struct tgsi_parse_context *ctx ); + +void +tgsi_parse_token( + struct tgsi_parse_context *ctx ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_PARSE_H + diff --git a/src/gallium/aux/tgsi/util/tgsi_transform.c b/src/gallium/aux/tgsi/util/tgsi_transform.c new file mode 100644 index 0000000000..357f77b05a --- /dev/null +++ b/src/gallium/aux/tgsi/util/tgsi_transform.c @@ -0,0 +1,199 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * TGSI program transformation utility. + * + * Authors: Brian Paul + */ + + +#include "tgsi_transform.h" + + + +static void +emit_instruction(struct tgsi_transform_context *ctx, + const struct tgsi_full_instruction *inst) +{ + uint ti = ctx->ti; + + ti += tgsi_build_full_instruction(inst, + ctx->tokens_out + ti, + ctx->header, + ctx->max_tokens_out - ti); + ctx->ti = ti; +} + + +static void +emit_declaration(struct tgsi_transform_context *ctx, + const struct tgsi_full_declaration *decl) +{ + uint ti = ctx->ti; + + ti += tgsi_build_full_declaration(decl, + ctx->tokens_out + ti, + ctx->header, + ctx->max_tokens_out - ti); + ctx->ti = ti; +} + + +static void +emit_immediate(struct tgsi_transform_context *ctx, + const struct tgsi_full_immediate *imm) +{ + uint ti = ctx->ti; + + ti += tgsi_build_full_immediate(imm, + ctx->tokens_out + ti, + ctx->header, + ctx->max_tokens_out - ti); + ctx->ti = ti; +} + + + +/** + * Apply user-defined transformations to the input shader to produce + * the output shader. + * For example, a register search-and-replace operation could be applied + * by defining a transform_instruction() callback that examined and changed + * the instruction src/dest regs. + * + * \return number of tokens emitted + */ +int +tgsi_transform_shader(const struct tgsi_token *tokens_in, + struct tgsi_token *tokens_out, + uint max_tokens_out, + struct tgsi_transform_context *ctx) +{ + uint procType; + + /* input shader */ + struct tgsi_parse_context parse; + + /* output shader */ + struct tgsi_processor *processor; + + + /** + ** callback context init + **/ + ctx->emit_instruction = emit_instruction; + ctx->emit_declaration = emit_declaration; + ctx->emit_immediate = emit_immediate; + ctx->tokens_out = tokens_out; + ctx->max_tokens_out = max_tokens_out; + + + /** + ** Setup to begin parsing input shader + **/ + if (tgsi_parse_init( &parse, tokens_in ) != TGSI_PARSE_OK) { + debug_printf("tgsi_parse_init() failed in tgsi_transform_shader()!\n"); + return -1; + } + procType = parse.FullHeader.Processor.Processor; + assert(procType == TGSI_PROCESSOR_FRAGMENT || + procType == TGSI_PROCESSOR_VERTEX || + procType == TGSI_PROCESSOR_GEOMETRY); + + + /** + ** Setup output shader + **/ + *(struct tgsi_version *) &tokens_out[0] = tgsi_build_version(); + + ctx->header = (struct tgsi_header *) (tokens_out + 1); + *ctx->header = tgsi_build_header(); + + processor = (struct tgsi_processor *) (tokens_out + 2); + *processor = tgsi_build_processor( procType, ctx->header ); + + ctx->ti = 3; + + + /** + ** Loop over incoming program tokens/instructions + */ + while( !tgsi_parse_end_of_tokens( &parse ) ) { + + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *fullinst + = &parse.FullToken.FullInstruction; + + if (ctx->transform_instruction) + ctx->transform_instruction(ctx, fullinst); + else + ctx->emit_instruction(ctx, fullinst); + } + break; + + case TGSI_TOKEN_TYPE_DECLARATION: + { + struct tgsi_full_declaration *fulldecl + = &parse.FullToken.FullDeclaration; + + if (ctx->transform_declaration) + ctx->transform_declaration(ctx, fulldecl); + else + ctx->emit_declaration(ctx, fulldecl); + } + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + struct tgsi_full_immediate *fullimm + = &parse.FullToken.FullImmediate; + + if (ctx->transform_immediate) + ctx->transform_immediate(ctx, fullimm); + else + ctx->emit_immediate(ctx, fullimm); + } + break; + + default: + assert( 0 ); + } + } + + if (ctx->epilog) { + ctx->epilog(ctx); + } + + tgsi_parse_free (&parse); + + return ctx->ti; +} diff --git a/src/gallium/aux/tgsi/util/tgsi_transform.h b/src/gallium/aux/tgsi/util/tgsi_transform.h new file mode 100644 index 0000000000..365d8c298c --- /dev/null +++ b/src/gallium/aux/tgsi/util/tgsi_transform.h @@ -0,0 +1,93 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_TRANSFORM_H +#define TGSI_TRANSFORM_H + + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/tgsi/util/tgsi_parse.h" +#include "pipe/tgsi/util/tgsi_build.h" + + + +/** + * Subclass this to add caller-specific data + */ +struct tgsi_transform_context +{ +/**** PUBLIC ***/ + + /** + * User-defined callbacks invoked per instruction. + */ + void (*transform_instruction)(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst); + + void (*transform_declaration)(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl); + + void (*transform_immediate)(struct tgsi_transform_context *ctx, + struct tgsi_full_immediate *imm); + + /** + * Called at end of input program to allow caller to append extra + * instructions. Return number of tokens emitted. + */ + void (*epilog)(struct tgsi_transform_context *ctx); + + +/*** PRIVATE ***/ + + /** + * These are setup by tgsi_transform_shader() and cannot be overridden. + * Meant to be called from in the above user callback functions. + */ + void (*emit_instruction)(struct tgsi_transform_context *ctx, + const struct tgsi_full_instruction *inst); + void (*emit_declaration)(struct tgsi_transform_context *ctx, + const struct tgsi_full_declaration *decl); + void (*emit_immediate)(struct tgsi_transform_context *ctx, + const struct tgsi_full_immediate *imm); + + struct tgsi_header *header; + uint max_tokens_out; + struct tgsi_token *tokens_out; + uint ti; +}; + + + +extern int +tgsi_transform_shader(const struct tgsi_token *tokens_in, + struct tgsi_token *tokens_out, + uint max_tokens_out, + struct tgsi_transform_context *ctx); + + +#endif /* TGSI_TRANSFORM_H */ diff --git a/src/gallium/aux/tgsi/util/tgsi_util.c b/src/gallium/aux/tgsi/util/tgsi_util.c new file mode 100644 index 0000000000..4cdd89182a --- /dev/null +++ b/src/gallium/aux/tgsi/util/tgsi_util.c @@ -0,0 +1,274 @@ +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi_parse.h" +#include "tgsi_build.h" +#include "tgsi_util.h" + +union pointer_hack +{ + void *pointer; + unsigned long long uint64; +}; + +void * +tgsi_align_128bit( + void *unaligned ) +{ + union pointer_hack ph; + + ph.uint64 = 0; + ph.pointer = unaligned; + ph.uint64 = (ph.uint64 + 15) & ~15; + return ph.pointer; +} + +unsigned +tgsi_util_get_src_register_swizzle( + const struct tgsi_src_register *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->SwizzleX; + case 1: + return reg->SwizzleY; + case 2: + return reg->SwizzleZ; + case 3: + return reg->SwizzleW; + default: + assert( 0 ); + } + return 0; +} + +unsigned +tgsi_util_get_src_register_extswizzle( + const struct tgsi_src_register_ext_swz *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->ExtSwizzleX; + case 1: + return reg->ExtSwizzleY; + case 2: + return reg->ExtSwizzleZ; + case 3: + return reg->ExtSwizzleW; + default: + assert( 0 ); + } + return 0; +} + +unsigned +tgsi_util_get_full_src_register_extswizzle( + const struct tgsi_full_src_register *reg, + unsigned component ) +{ + unsigned swizzle; + + /* + * First, calculate the extended swizzle for a given channel. This will give + * us either a channel index into the simple swizzle or a constant 1 or 0. + */ + swizzle = tgsi_util_get_src_register_extswizzle( + ®->SrcRegisterExtSwz, + component ); + + assert (TGSI_SWIZZLE_X == TGSI_EXTSWIZZLE_X); + assert (TGSI_SWIZZLE_Y == TGSI_EXTSWIZZLE_Y); + assert (TGSI_SWIZZLE_Z == TGSI_EXTSWIZZLE_Z); + assert (TGSI_SWIZZLE_W == TGSI_EXTSWIZZLE_W); + assert (TGSI_EXTSWIZZLE_ZERO > TGSI_SWIZZLE_W); + assert (TGSI_EXTSWIZZLE_ONE > TGSI_SWIZZLE_W); + + /* + * Second, calculate the simple swizzle for the unswizzled channel index. + * Leave the constants intact, they are not affected by the simple swizzle. + */ + if( swizzle <= TGSI_SWIZZLE_W ) { + swizzle = tgsi_util_get_src_register_swizzle( + ®->SrcRegister, + component ); + } + + return swizzle; +} + +void +tgsi_util_set_src_register_swizzle( + struct tgsi_src_register *reg, + unsigned swizzle, + unsigned component ) +{ + switch( component ) { + case 0: + reg->SwizzleX = swizzle; + break; + case 1: + reg->SwizzleY = swizzle; + break; + case 2: + reg->SwizzleZ = swizzle; + break; + case 3: + reg->SwizzleW = swizzle; + break; + default: + assert( 0 ); + } +} + +void +tgsi_util_set_src_register_extswizzle( + struct tgsi_src_register_ext_swz *reg, + unsigned swizzle, + unsigned component ) +{ + switch( component ) { + case 0: + reg->ExtSwizzleX = swizzle; + break; + case 1: + reg->ExtSwizzleY = swizzle; + break; + case 2: + reg->ExtSwizzleZ = swizzle; + break; + case 3: + reg->ExtSwizzleW = swizzle; + break; + default: + assert( 0 ); + } +} + +unsigned +tgsi_util_get_src_register_extnegate( + const struct tgsi_src_register_ext_swz *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->NegateX; + case 1: + return reg->NegateY; + case 2: + return reg->NegateZ; + case 3: + return reg->NegateW; + default: + assert( 0 ); + } + return 0; +} + +void +tgsi_util_set_src_register_extnegate( + struct tgsi_src_register_ext_swz *reg, + unsigned negate, + unsigned component ) +{ + switch( component ) { + case 0: + reg->NegateX = negate; + break; + case 1: + reg->NegateY = negate; + break; + case 2: + reg->NegateZ = negate; + break; + case 3: + reg->NegateW = negate; + break; + default: + assert( 0 ); + } +} + +unsigned +tgsi_util_get_full_src_register_sign_mode( + const struct tgsi_full_src_register *reg, + unsigned component ) +{ + unsigned sign_mode; + + if( reg->SrcRegisterExtMod.Absolute ) { + /* Consider only the post-abs negation. */ + + if( reg->SrcRegisterExtMod.Negate ) { + sign_mode = TGSI_UTIL_SIGN_SET; + } + else { + sign_mode = TGSI_UTIL_SIGN_CLEAR; + } + } + else { + /* Accumulate the three negations. */ + + unsigned negate; + + negate = reg->SrcRegister.Negate; + if( tgsi_util_get_src_register_extnegate( ®->SrcRegisterExtSwz, component ) ) { + negate = !negate; + } + if( reg->SrcRegisterExtMod.Negate ) { + negate = !negate; + } + + if( negate ) { + sign_mode = TGSI_UTIL_SIGN_TOGGLE; + } + else { + sign_mode = TGSI_UTIL_SIGN_KEEP; + } + } + + return sign_mode; +} + +void +tgsi_util_set_full_src_register_sign_mode( + struct tgsi_full_src_register *reg, + unsigned sign_mode ) +{ + reg->SrcRegisterExtSwz.NegateX = 0; + reg->SrcRegisterExtSwz.NegateY = 0; + reg->SrcRegisterExtSwz.NegateZ = 0; + reg->SrcRegisterExtSwz.NegateW = 0; + + switch (sign_mode) + { + case TGSI_UTIL_SIGN_CLEAR: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 1; + reg->SrcRegisterExtMod.Negate = 0; + break; + + case TGSI_UTIL_SIGN_SET: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 1; + reg->SrcRegisterExtMod.Negate = 1; + break; + + case TGSI_UTIL_SIGN_TOGGLE: + reg->SrcRegister.Negate = 1; + reg->SrcRegisterExtMod.Absolute = 0; + reg->SrcRegisterExtMod.Negate = 0; + break; + + case TGSI_UTIL_SIGN_KEEP: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 0; + reg->SrcRegisterExtMod.Negate = 0; + break; + + default: + assert( 0 ); + } +} + diff --git a/src/gallium/aux/tgsi/util/tgsi_util.h b/src/gallium/aux/tgsi/util/tgsi_util.h new file mode 100644 index 0000000000..ef14446f0e --- /dev/null +++ b/src/gallium/aux/tgsi/util/tgsi_util.h @@ -0,0 +1,70 @@ +#if !defined TGSI_UTIL_H +#define TGSI_UTIL_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +void * +tgsi_align_128bit( + void *unaligned ); + +unsigned +tgsi_util_get_src_register_swizzle( + const struct tgsi_src_register *reg, + unsigned component ); + +unsigned +tgsi_util_get_src_register_extswizzle( + const struct tgsi_src_register_ext_swz *reg, + unsigned component); + +unsigned +tgsi_util_get_full_src_register_extswizzle( + const struct tgsi_full_src_register *reg, + unsigned component ); + +void +tgsi_util_set_src_register_swizzle( + struct tgsi_src_register *reg, + unsigned swizzle, + unsigned component ); + +void +tgsi_util_set_src_register_extswizzle( + struct tgsi_src_register_ext_swz *reg, + unsigned swizzle, + unsigned component ); + +unsigned +tgsi_util_get_src_register_extnegate( + const struct tgsi_src_register_ext_swz *reg, + unsigned component ); + +void +tgsi_util_set_src_register_extnegate( + struct tgsi_src_register_ext_swz *reg, + unsigned negate, + unsigned component ); + +#define TGSI_UTIL_SIGN_CLEAR 0 /* Force positive */ +#define TGSI_UTIL_SIGN_SET 1 /* Force negative */ +#define TGSI_UTIL_SIGN_TOGGLE 2 /* Negate */ +#define TGSI_UTIL_SIGN_KEEP 3 /* No change */ + +unsigned +tgsi_util_get_full_src_register_sign_mode( + const struct tgsi_full_src_register *reg, + unsigned component ); + +void +tgsi_util_set_full_src_register_sign_mode( + struct tgsi_full_src_register *reg, + unsigned sign_mode ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_UTIL_H + diff --git a/src/gallium/aux/util/p_debug.c b/src/gallium/aux/util/p_debug.c new file mode 100644 index 0000000000..b9607a6ba7 --- /dev/null +++ b/src/gallium/aux/util/p_debug.c @@ -0,0 +1,76 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include + +#ifdef WIN32 +#include +#include +#else +#include +#include +#endif + +#include "pipe/p_debug.h" +#include "pipe/p_compiler.h" + + +void debug_vprintf(const char *format, va_list ap) +{ +#ifdef WIN32 + EngDebugPrint("Gallium3D: ", (PCHAR)format, ap); +#else + vfprintf(stderr, format, ap); +#endif +} + + +void debug_printf(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + debug_vprintf(format, ap); + va_end(ap); +} + + +static INLINE void debug_abort(void) +{ +#ifdef WIN32 + EngDebugBreak(); +#else + abort(); +#endif +} + + +void debug_assert_fail(const char *expr, const char *file, unsigned line) +{ + debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr); + debug_abort(); +} diff --git a/src/gallium/aux/util/p_tile.c b/src/gallium/aux/util/p_tile.c new file mode 100644 index 0000000000..3f795a3898 --- /dev/null +++ b/src/gallium/aux/util/p_tile.c @@ -0,0 +1,699 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * RGBA/float tile get/put functions. + * Usable both by drivers and state trackers. + * Surfaces should already be in a mapped state. + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "p_tile.h" + + + +/** + * Move raw block of pixels from surface to user memory. + * This should be usable by any hw driver that has mappable surfaces. + */ +void +pipe_get_tile_raw(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + void *p, int dst_stride) +{ + const uint cpp = ps->cpp; + const ubyte *pSrc; + const uint src_stride = ps->pitch * cpp; + ubyte *pDest; + uint i; + + if (dst_stride == 0) { + dst_stride = w * cpp; + } + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + pSrc = (const ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; + pDest = (ubyte *) p; + + for (i = 0; i < h; i++) { + memcpy(pDest, pSrc, w * cpp); + pDest += dst_stride; + pSrc += src_stride; + } + + pipe_surface_unmap(ps); +} + + +/** + * Move raw block of pixels from user memory to surface. + * This should be usable by any hw driver that has mappable surfaces. + */ +void +pipe_put_tile_raw(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const void *p, int src_stride) +{ + const uint cpp = ps->cpp; + const ubyte *pSrc; + const uint dst_stride = ps->pitch * cpp; + ubyte *pDest; + uint i; + + if (src_stride == 0) { + src_stride = w * cpp; + } + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + pSrc = (const ubyte *) p; + pDest = (ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; + + for (i = 0; i < h; i++) { + memcpy(pDest, pSrc, w * cpp); + pDest += dst_stride; + pSrc += src_stride; + } + + pipe_surface_unmap(ps); +} + + + + +/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */ +#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) + +#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \ + us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) + + + +/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ + +static void +a8r8g8b8_get_tile_rgba(unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const unsigned pixel = *src++; + pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); + pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); + pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); + pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); + } + p += dst_stride; + } +} + + +static void +a8r8g8b8_put_tile_rgba(unsigned *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b, a; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + *dst++ = (a << 24) | (r << 16) | (g << 8) | b; + } + p += src_stride; + } +} + + +/*** PIPE_FORMAT_B8G8R8A8_UNORM ***/ + +static void +b8g8r8a8_get_tile_rgba(unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const unsigned pixel = *src++; + pRow[0] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); + pRow[1] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); + pRow[2] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); + pRow[3] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); + } + p += dst_stride; + } +} + + +static void +b8g8r8a8_put_tile_rgba(unsigned *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b, a; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + *dst++ = (b << 24) | (g << 16) | (r << 8) | a; + } + p += src_stride; + } +} + + +/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/ + +static void +a1r5g5b5_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const ushort pixel = *src++; + pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f); + pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f); + pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); + pRow[3] = ((pixel >> 15) ) * 1.0f; + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_A4R4G4B4_UNORM ***/ + +static void +a4r4g4b4_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const ushort pixel = *src++; + pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f); + pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f); + pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f); + pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_R5G6B5_UNORM ***/ + +static void +r5g6b5_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const ushort pixel = *src++; + pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f); + pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f); + pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); + pRow[3] = 1.0f; + } + p += dst_stride; + } +} + + +static void +r5g5b5_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0); + uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0); + uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0); + *dst++ = (r << 11) | (g << 5) | (b); + } + p += src_stride; + } +} + + + +/*** PIPE_FORMAT_Z16_UNORM ***/ + +/** + * Return each Z value as four floats in [0,1]. + */ +static void +z16_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const float scale = 1.0f / 65535.0f; + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = *src++ * scale; + } + p += dst_stride; + } +} + + + + +/*** PIPE_FORMAT_U_L8 ***/ + +static void +l8_get_tile_rgba(ubyte *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = UBYTE_TO_FLOAT(*src); + pRow[3] = 1.0; + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_U_A8 ***/ + +static void +a8_get_tile_rgba(ubyte *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = 0.0; + pRow[3] = UBYTE_TO_FLOAT(*src); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ + +static void +r16g16b16a16_get_tile_rgba(short *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src += 4, pRow += 4) { + pRow[0] = SHORT_TO_FLOAT(src[0]); + pRow[1] = SHORT_TO_FLOAT(src[1]); + pRow[2] = SHORT_TO_FLOAT(src[2]); + pRow[3] = SHORT_TO_FLOAT(src[3]); + } + p += dst_stride; + } +} + + +static void +r16g16b16a16_put_tile_rgba(short *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, dst += 4, pRow += 4) { + UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); + UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]); + UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]); + UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]); + } + p += src_stride; + } +} + + + +/*** PIPE_FORMAT_U_I8 ***/ + +static void +i8_get_tile_rgba(ubyte *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = UBYTE_TO_FLOAT(*src); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_U_A8_L8 ***/ + +static void +a8_l8_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + ushort p = *src++; + pRow[0] = + pRow[1] = + pRow[2] = UBYTE_TO_FLOAT(p & 0xff); + pRow[3] = UBYTE_TO_FLOAT(p >> 8); + } + p += dst_stride; + } +} + + + + +/*** PIPE_FORMAT_Z32_UNORM ***/ + +/** + * Return each Z value as four floats in [0,1]. + */ +static void +z32_get_tile_rgba(unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const double scale = 1.0 / (double) 0xffffffff; + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = (float) (*src++ * scale); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_S8Z24_UNORM ***/ + +/** + * Return Z component as four float in [0,1]. Stencil part ignored. + */ +static void +s8z24_get_tile_rgba(unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const double scale = 1.0 / ((1 << 24) - 1); + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = (float) (scale * (*src++ & 0xffffff)); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_Z24S8_UNORM ***/ + +/** + * Return Z component as four float in [0,1]. Stencil part ignored. + */ +static void +z24s8_get_tile_rgba(unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const double scale = 1.0 / ((1 << 24) - 1); + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = (float) (scale * (*src++ >> 8)); + } + p += dst_stride; + } +} + + +void +pipe_get_tile_rgba(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + float *p) +{ + unsigned dst_stride = w * 4; + void *packed; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + packed = MALLOC(h * w * ps->cpp); + + if (!packed) + return; + + pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp); + + switch (ps->format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + a8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + b8g8r8a8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_A1R5G5B5_UNORM: + a1r5g5b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_A4R4G4B4_UNORM: + a4r4g4b4_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_R5G6B5_UNORM: + r5g6b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_U_L8: + l8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_U_A8: + a8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_U_I8: + i8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_U_A8_L8: + a8_l8_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_R16G16B16A16_SNORM: + r16g16b16a16_get_tile_rgba((short *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_Z16_UNORM: + z16_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_Z32_UNORM: + z32_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_S8Z24_UNORM: + s8z24_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_Z24S8_UNORM: + z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + break; + default: + assert(0); + } + + FREE(packed); +} + + +void +pipe_put_tile_rgba(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const float *p) +{ + unsigned src_stride = w * 4; + void *packed; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + packed = MALLOC(h * w * ps->cpp); + + if (!packed) + return; + + switch (ps->format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_A1R5G5B5_UNORM: + /*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_R5G6B5_UNORM: + r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + break; + case PIPE_FORMAT_U_L8: + /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_U_A8: + /*a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_U_I8: + /*i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_U_A8_L8: + /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_R16G16B16A16_SNORM: + r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_Z16_UNORM: + /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_Z32_UNORM: + /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_S8Z24_UNORM: + /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_Z24S8_UNORM: + /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ + break; + default: + assert(0); + } + + pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp); + + FREE(packed); +} diff --git a/src/gallium/aux/util/p_tile.h b/src/gallium/aux/util/p_tile.h new file mode 100644 index 0000000000..cd8124bf11 --- /dev/null +++ b/src/gallium/aux/util/p_tile.h @@ -0,0 +1,81 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef P_TILE_H +#define P_TILE_H + +#include "pipe/p_compiler.h" + +struct pipe_context; +struct pipe_surface; + + +/** + * Clip tile against surface dims. + * \return TRUE if tile is totally clipped, FALSE otherwise + */ +static INLINE boolean +pipe_clip_tile(uint x, uint y, uint *w, uint *h, const struct pipe_surface *ps) +{ + if (x >= ps->width) + return TRUE; + if (y >= ps->height) + return TRUE; + if (x + *w > ps->width) + *w = ps->width - x; + if (y + *h > ps->height) + *h = ps->height - y; + return FALSE; +} + + +extern void +pipe_get_tile_raw(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + void *p, int dst_stride); + +extern void +pipe_put_tile_raw(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const void *p, int src_stride); + + +extern void +pipe_get_tile_rgba(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + float *p); + +extern void +pipe_put_tile_rgba(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const float *p); + +#endif diff --git a/src/gallium/aux/util/p_util.c b/src/gallium/aux/util/p_util.c new file mode 100644 index 0000000000..2a92f8e408 --- /dev/null +++ b/src/gallium/aux/util/p_util.c @@ -0,0 +1,73 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Miscellaneous utility functions. + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" + + +/** + * Copy 2D rect from one place to another. + * Position and sizes are in pixels. + */ +void +pipe_copy_rect(ubyte * dst, + unsigned cpp, + unsigned dst_pitch, + unsigned dst_x, + unsigned dst_y, + unsigned width, + unsigned height, + const ubyte * src, + int src_pitch, + unsigned src_x, + int src_y) +{ + unsigned i; + + dst_pitch *= cpp; + src_pitch *= cpp; + dst += dst_x * cpp; + src += src_x * cpp; + dst += dst_y * dst_pitch; + src += src_y * src_pitch; + width *= cpp; + + if (width == dst_pitch && width == src_pitch) + memcpy(dst, src, height * width); + else { + for (i = 0; i < height; i++) { + memcpy(dst, src, width); + dst += dst_pitch; + src += src_pitch; + } + } +} diff --git a/src/gallium/drivers/cell/Makefile b/src/gallium/drivers/cell/Makefile new file mode 100644 index 0000000000..47aef7b05f --- /dev/null +++ b/src/gallium/drivers/cell/Makefile @@ -0,0 +1,12 @@ +# Cell Gallium driver Makefile + + +default: + ( cd spu ; make ) + ( cd ppu ; make ) + + + +clean: + ( cd spu ; make clean ) + ( cd ppu ; make clean ) diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h new file mode 100644 index 0000000000..4de514c358 --- /dev/null +++ b/src/gallium/drivers/cell/common.h @@ -0,0 +1,220 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Types and tokens which are common to the SPU and PPU code. + */ + + +#ifndef CELL_COMMON_H +#define CELL_COMMON_H + +#include "pipe/p_compiler.h" +#include "pipe/p_util.h" +#include "pipe/p_format.h" + + +/** The standard assert macro doesn't seem to work reliably */ +#define ASSERT(x) \ + if (!(x)) { \ + ubyte *p = NULL; \ + fprintf(stderr, "%s:%d: %s(): assertion %s failed.\n", \ + __FILE__, __LINE__, __FUNCTION__, #x); \ + *p = 0; \ + exit(1); \ + } + + +/** for sanity checking */ +#define ASSERT_ALIGN16(ptr) \ + ASSERT((((unsigned long) (ptr)) & 0xf) == 0); + + +/** round up value to next multiple of 4 */ +#define ROUNDUP4(k) (((k) + 0x3) & ~0x3) + +/** round up value to next multiple of 8 */ +#define ROUNDUP8(k) (((k) + 0x7) & ~0x7) + +/** round up value to next multiple of 16 */ +#define ROUNDUP16(k) (((k) + 0xf) & ~0xf) + + +#define CELL_MAX_SPUS 6 + +#define TILE_SIZE 32 + + +/** + * The low byte of a mailbox word contains the command opcode. + * Remaining higher bytes are command specific. + */ +#define CELL_CMD_OPCODE_MASK 0xff + +#define CELL_CMD_EXIT 1 +#define CELL_CMD_CLEAR_SURFACE 2 +#define CELL_CMD_FINISH 3 +#define CELL_CMD_RENDER 4 +#define CELL_CMD_BATCH 5 +#define CELL_CMD_RELEASE_VERTS 6 +#define CELL_CMD_STATE_FRAMEBUFFER 10 +#define CELL_CMD_STATE_DEPTH_STENCIL 11 +#define CELL_CMD_STATE_SAMPLER 12 +#define CELL_CMD_STATE_TEXTURE 13 +#define CELL_CMD_STATE_VERTEX_INFO 14 +#define CELL_CMD_STATE_VIEWPORT 15 +#define CELL_CMD_STATE_VS_ARRAY_INFO 16 +#define CELL_CMD_STATE_BLEND 17 +#define CELL_CMD_VS_EXECUTE 18 + + +#define CELL_NUM_BUFFERS 4 +#define CELL_BUFFER_SIZE (4*1024) /**< 16KB would be the max */ + +#define CELL_BUFFER_STATUS_FREE 10 +#define CELL_BUFFER_STATUS_USED 20 + + + +/** + * Tell SPUs about the framebuffer size, location + */ +struct cell_command_framebuffer +{ + uint64_t opcode; /**< CELL_CMD_FRAMEBUFFER */ + int width, height; + void *color_start, *depth_start; + enum pipe_format color_format, depth_format; +}; + + +/** + * Clear framebuffer to the given value/color. + */ +struct cell_command_clear_surface +{ + uint64_t opcode; /**< CELL_CMD_CLEAR_SURFACE */ + uint surface; /**< Temporary: 0=color, 1=Z */ + uint value; +}; + + +/** + * Array info used by the vertex shader's vertex puller. + */ +struct cell_array_info +{ + uint64_t base; /**< Base address of the 0th element. */ + uint attr; /**< Attribute that this state is for. */ + uint pitch; /**< Byte pitch from one entry to the next. */ + uint format; /**< Pipe format of each entry. */ +} ALIGN16_ATTRIB; + + +struct cell_shader_info +{ + unsigned num_outputs; + + uint64_t declarations; + unsigned num_declarations; + uint64_t instructions; + unsigned num_instructions; + uint64_t uniforms; + uint64_t immediates; + unsigned num_immediates; +} ALIGN16_ATTRIB; + + +#define SPU_VERTS_PER_BATCH 64 +struct cell_command_vs +{ + uint64_t opcode; /**< CELL_CMD_VS_EXECUTE */ + struct cell_shader_info shader; + unsigned num_elts; + unsigned elts[SPU_VERTS_PER_BATCH]; + uint64_t vOut[SPU_VERTS_PER_BATCH]; + float plane[12][4]; + unsigned nr_planes; + unsigned nr_attrs; +} ALIGN16_ATTRIB; + + +struct cell_command_render +{ + uint64_t opcode; /**< CELL_CMD_RENDER */ + uint prim_type; /**< PIPE_PRIM_x */ + uint num_verts; + uint vertex_size; /**< bytes per vertex */ + uint num_indexes; + uint vertex_buf; /**< which cell->buffer[] contains the vertex data */ + float xmin, ymin, xmax, ymax; /* XXX another dummy field */ + uint min_index; + boolean inline_verts; +}; + + +struct cell_command_release_verts +{ + uint64_t opcode; /**< CELL_CMD_RELEASE_VERTS */ + uint vertex_buf; /**< in [0, CELL_NUM_BUFFERS-1] */ +}; + + +struct cell_command_texture +{ + void *start; /**< Address in main memory */ + uint width, height; +}; + + +/** XXX unions don't seem to work */ +/* XXX this should go away; all commands should be placed in batch buffers */ +struct cell_command +{ +#if 0 + struct cell_command_framebuffer fb; + struct cell_command_clear_surface clear; + struct cell_command_render render; +#endif + struct cell_command_vs vs; +} ALIGN16_ATTRIB; + + +/** This is the object passed to spe_create_thread() */ +struct cell_init_info +{ + unsigned id; + unsigned num_spus; + struct cell_command *cmd; + + /** Buffers for command batches, vertex/index data */ + ubyte *buffers[CELL_NUM_BUFFERS]; + uint *buffer_status; /**< points at cell_context->buffer_status */ +} ALIGN16_ATTRIB; + + +#endif /* CELL_COMMON_H */ diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile new file mode 100644 index 0000000000..50060f5cd3 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -0,0 +1,76 @@ +# Gallium3D Cell driver: PPU code + +# This makefile builds the g3dcell.a library which gets pulled into +# the main libGL.so library + + +TOP = ../../../../.. +include $(TOP)/configs/linux-cell + + +#PROG = gl4 + +CELL_LIB = libcell.a + +SPU_CODE_MODULE = ../spu/g3d_spu.a + + +SOURCES = \ + cell_batch.c \ + cell_clear.c \ + cell_context.c \ + cell_draw_arrays.c \ + cell_flush.c \ + cell_state_blend.c \ + cell_state_clip.c \ + cell_state_derived.c \ + cell_state_emit.c \ + cell_state_fs.c \ + cell_state_rasterizer.c \ + cell_state_sampler.c \ + cell_state_surface.c \ + cell_state_vertex.c \ + cell_spu.c \ + cell_surface.c \ + cell_texture.c \ + cell_vbuf.c \ + cell_vertex_shader.c \ + cell_winsys.c + + +OBJECTS = $(SOURCES:.c=.o) \ + +INCLUDE_DIRS = -I$(TOP)/src/mesa + + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + + + +default: $(CELL_LIB) + + +$(CELL_LIB): $(OBJECTS) $(SPU_CODE_MODULE) +# ar -ru $(CELL_LIB) $(OBJECTS) $(SPU_CODE_MODULE) + ar -ru $(CELL_LIB) $(OBJECTS) + +#$(PROG): $(PPU_OBJECTS) +# $(CC) -o $(PROG) $(PPU_OBJECTS) $(SPU_CODE_MODULE) $(PPU_LFLAGS) + + + +clean: + rm -f *.o *~ $(CELL_LIB) + + + +depend: $(SOURCES) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDE_DIRS) $(SOURCES) 2> /dev/null + +include depend + + + diff --git a/src/gallium/drivers/cell/ppu/cell_batch.c b/src/gallium/drivers/cell/ppu/cell_batch.c new file mode 100644 index 0000000000..f45e5f25b6 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_batch.c @@ -0,0 +1,217 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "cell_context.h" +#include "cell_batch.h" +#include "cell_spu.h" + + + +uint +cell_get_empty_buffer(struct cell_context *cell) +{ + uint buf = 0, tries = 0; + + /* Find a buffer that's marked as free by all SPUs */ + while (1) { + uint spu, num_free = 0; + + for (spu = 0; spu < cell->num_spus; spu++) { + if (cell->buffer_status[spu][buf][0] == CELL_BUFFER_STATUS_FREE) { + num_free++; + + if (num_free == cell->num_spus) { + /* found a free buffer, now mark status as used */ + for (spu = 0; spu < cell->num_spus; spu++) { + cell->buffer_status[spu][buf][0] = CELL_BUFFER_STATUS_USED; + } + /* + printf("PPU: ALLOC BUFFER %u\n", buf); + */ + return buf; + } + } + else { + break; + } + } + + /* try next buf */ + buf = (buf + 1) % CELL_NUM_BUFFERS; + + tries++; + if (tries == 100) { + /* + printf("PPU WAITING for buffer...\n"); + */ + } + } +} + + +void +cell_batch_flush(struct cell_context *cell) +{ + static boolean flushing = FALSE; + uint batch = cell->cur_batch; + const uint size = cell->buffer_size[batch]; + uint spu, cmd_word; + + assert(!flushing); + + if (size == 0) + return; + + flushing = TRUE; + + assert(batch < CELL_NUM_BUFFERS); + + /* + printf("cell_batch_dispatch: buf %u at %p, size %u\n", + batch, &cell->batch_buffer[batch][0], size); + */ + + /* + * Build "BATCH" command and sent to all SPUs. + */ + cmd_word = CELL_CMD_BATCH | (batch << 8) | (size << 16); + + for (spu = 0; spu < cell->num_spus; spu++) { + assert(cell->buffer_status[spu][batch][0] == CELL_BUFFER_STATUS_USED); + send_mbox_message(cell_global.spe_contexts[spu], cmd_word); + } + + /* When the SPUs are done copying the buffer into their locals stores + * they'll write a BUFFER_STATUS_FREE message into the buffer_status[] + * array indicating that the PPU can re-use the buffer. + */ + + batch = cell_get_empty_buffer(cell); + + cell->buffer_size[batch] = 0; /* empty */ + cell->cur_batch = batch; + + flushing = FALSE; +} + + +uint +cell_batch_free_space(const struct cell_context *cell) +{ + uint free = CELL_BUFFER_SIZE - cell->buffer_size[cell->cur_batch]; + return free; +} + + +/** + * Append data to current batch. + */ +void +cell_batch_append(struct cell_context *cell, const void *data, uint bytes) +{ + uint size; + + ASSERT(bytes % 8 == 0); + ASSERT(bytes <= CELL_BUFFER_SIZE); + ASSERT(cell->cur_batch >= 0); + +#ifdef ASSERT + { + uint spu; + for (spu = 0; spu < cell->num_spus; spu++) { + ASSERT(cell->buffer_status[spu][cell->cur_batch][0] + == CELL_BUFFER_STATUS_USED); + } + } +#endif + + size = cell->buffer_size[cell->cur_batch]; + + if (size + bytes > CELL_BUFFER_SIZE) { + cell_batch_flush(cell); + size = 0; + } + + ASSERT(size + bytes <= CELL_BUFFER_SIZE); + + memcpy(cell->buffer[cell->cur_batch] + size, data, bytes); + + cell->buffer_size[cell->cur_batch] = size + bytes; +} + + +void * +cell_batch_alloc(struct cell_context *cell, uint bytes) +{ + return cell_batch_alloc_aligned(cell, bytes, 1); +} + + +void * +cell_batch_alloc_aligned(struct cell_context *cell, uint bytes, + uint alignment) +{ + void *pos; + uint size, padbytes; + + ASSERT(bytes % 8 == 0); + ASSERT(bytes <= CELL_BUFFER_SIZE); + ASSERT(alignment > 0); + ASSERT(cell->cur_batch >= 0); + +#ifdef ASSERT + { + uint spu; + for (spu = 0; spu < cell->num_spus; spu++) { + ASSERT(cell->buffer_status[spu][cell->cur_batch][0] + == CELL_BUFFER_STATUS_USED); + } + } +#endif + + size = cell->buffer_size[cell->cur_batch]; + + padbytes = (alignment - (size % alignment)) % alignment; + + if (padbytes + size + bytes > CELL_BUFFER_SIZE) { + cell_batch_flush(cell); + size = 0; + } + else { + size += padbytes; + } + + ASSERT(size % alignment == 0); + ASSERT(size + bytes <= CELL_BUFFER_SIZE); + + pos = (void *) (cell->buffer[cell->cur_batch] + size); + + cell->buffer_size[cell->cur_batch] = size + bytes; + + return pos; +} diff --git a/src/gallium/drivers/cell/ppu/cell_batch.h b/src/gallium/drivers/cell/ppu/cell_batch.h new file mode 100644 index 0000000000..a6eee0a8b1 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_batch.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef CELL_BATCH_H +#define CELL_BATCH_H + +#include "pipe/p_compiler.h" + + +struct cell_context; + + +extern uint +cell_get_empty_buffer(struct cell_context *cell); + +extern void +cell_batch_flush(struct cell_context *cell); + +extern uint +cell_batch_free_space(const struct cell_context *cell); + +extern void +cell_batch_append(struct cell_context *cell, const void *data, uint bytes); + +extern void * +cell_batch_alloc(struct cell_context *cell, uint bytes); + +extern void * +cell_batch_alloc_aligned(struct cell_context *cell, uint bytes, + uint alignment); + + +#endif /* CELL_BATCH_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c new file mode 100644 index 0000000000..07b908eec5 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_clear.c @@ -0,0 +1,76 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Authors + * Brian Paul + */ + +#include +#include +#include +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/cell/common.h" +#include "cell_clear.h" +#include "cell_context.h" +#include "cell_batch.h" +#include "cell_flush.h" +#include "cell_spu.h" + + +void +cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue) +{ + struct cell_context *cell = cell_context(pipe); + uint surfIndex; + + if (cell->dirty) + cell_update_derived(cell); + + + if (!cell->cbuf_map[0]) + cell->cbuf_map[0] = pipe_surface_map(ps); + + if (ps == cell->framebuffer.zsbuf) { + surfIndex = 1; + } + else { + surfIndex = 0; + } + + + { + struct cell_command_clear_surface *clr + = (struct cell_command_clear_surface *) + cell_batch_alloc(cell, sizeof(*clr)); + clr->opcode = CELL_CMD_CLEAR_SURFACE; + clr->surface = surfIndex; + clr->value = clearValue; + } +} diff --git a/src/gallium/drivers/cell/ppu/cell_clear.h b/src/gallium/drivers/cell/ppu/cell_clear.h new file mode 100644 index 0000000000..ff47d43f4c --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_clear.h @@ -0,0 +1,43 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef CELL_CLEAR_H +#define CELL_CLEAR_H + + +struct pipe_context; +struct pipe_surface; + + +extern void +cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + + + +#endif /* CELL_CLEAR_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c new file mode 100644 index 0000000000..bbe1fd7a11 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -0,0 +1,287 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Authors + * Brian Paul + */ + + +#include + +#include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/cell/common.h" +#include "pipe/draw/draw_context.h" +#include "pipe/draw/draw_private.h" +#include "cell_clear.h" +#include "cell_context.h" +#include "cell_draw_arrays.h" +#include "cell_flush.h" +#include "cell_render.h" +#include "cell_state.h" +#include "cell_surface.h" +#include "cell_spu.h" +#include "cell_texture.h" +#include "cell_vbuf.h" + + + +static boolean +cell_is_format_supported( struct pipe_context *pipe, + enum pipe_format format, uint type ) +{ + /*struct cell_context *cell = cell_context( pipe );*/ + + switch (type) { + case PIPE_TEXTURE: + /* cell supports all texture formats, XXX for now anyway */ + return TRUE; + case PIPE_SURFACE: + /* cell supports all (off-screen) surface formats, XXX for now */ + return TRUE; + default: + assert(0); + return FALSE; + } +} + + +static int cell_get_param(struct pipe_context *pipe, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 8; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 1; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 1; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 1; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 12; /* max 2Kx2K */ + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 8; /* max 128x128x128 */ + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 12; /* max 2Kx2K */ + default: + return 0; + } +} + +static float cell_get_paramf(struct pipe_context *pipe, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 255.0; /* arbitrary */ + + case PIPE_CAP_MAX_POINT_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 255.0; /* arbitrary */ + + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 0.0; + + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0; /* arbitrary */ + + default: + return 0; + } +} + + +static const char * +cell_get_name( struct pipe_context *pipe ) +{ + return "Cell"; +} + +static const char * +cell_get_vendor( struct pipe_context *pipe ) +{ + return "Tungsten Graphics, Inc."; +} + + + +static void +cell_destroy_context( struct pipe_context *pipe ) +{ + struct cell_context *cell = cell_context(pipe); + + cell_spu_exit(cell); + + align_free(cell); +} + + +static struct draw_context * +cell_draw_create(struct cell_context *cell) +{ + struct draw_context *draw = draw_create(); + + if (getenv("GALLIUM_CELL_VS")) { + /* plug in SPU-based vertex transformation code */ + draw->shader_queue_flush = cell_vertex_shader_queue_flush; + draw->driver_private = cell; + } + + return draw; +} + + +struct pipe_context * +cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) +{ + struct cell_context *cell; + uint spu, buf; + + /* some fields need to be 16-byte aligned, so align the whole object */ + cell = (struct cell_context*) align_malloc(sizeof(struct cell_context), 16); + if (!cell) + return NULL; + + memset(cell, 0, sizeof(*cell)); + + cell->winsys = cws; + cell->pipe.winsys = winsys; + cell->pipe.destroy = cell_destroy_context; + + /* queries */ + cell->pipe.is_format_supported = cell_is_format_supported; + cell->pipe.get_name = cell_get_name; + cell->pipe.get_vendor = cell_get_vendor; + cell->pipe.get_param = cell_get_param; + cell->pipe.get_paramf = cell_get_paramf; + + + /* state setters */ + cell->pipe.create_blend_state = cell_create_blend_state; + cell->pipe.bind_blend_state = cell_bind_blend_state; + cell->pipe.delete_blend_state = cell_delete_blend_state; + + cell->pipe.create_sampler_state = cell_create_sampler_state; + cell->pipe.bind_sampler_state = cell_bind_sampler_state; + cell->pipe.delete_sampler_state = cell_delete_sampler_state; + + cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state; + cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state; + cell->pipe.delete_depth_stencil_alpha_state = cell_delete_depth_stencil_alpha_state; + + cell->pipe.create_rasterizer_state = cell_create_rasterizer_state; + cell->pipe.bind_rasterizer_state = cell_bind_rasterizer_state; + cell->pipe.delete_rasterizer_state = cell_delete_rasterizer_state; + + cell->pipe.create_fs_state = cell_create_fs_state; + cell->pipe.bind_fs_state = cell_bind_fs_state; + cell->pipe.delete_fs_state = cell_delete_fs_state; + + cell->pipe.create_vs_state = cell_create_vs_state; + cell->pipe.bind_vs_state = cell_bind_vs_state; + cell->pipe.delete_vs_state = cell_delete_vs_state; + + cell->pipe.set_blend_color = cell_set_blend_color; + cell->pipe.set_clip_state = cell_set_clip_state; + cell->pipe.set_constant_buffer = cell_set_constant_buffer; + + cell->pipe.set_framebuffer_state = cell_set_framebuffer_state; + + cell->pipe.set_polygon_stipple = cell_set_polygon_stipple; + cell->pipe.set_scissor_state = cell_set_scissor_state; + cell->pipe.set_viewport_state = cell_set_viewport_state; + + cell->pipe.set_vertex_buffer = cell_set_vertex_buffer; + cell->pipe.set_vertex_element = cell_set_vertex_element; + + cell->pipe.draw_arrays = cell_draw_arrays; + cell->pipe.draw_elements = cell_draw_elements; + + cell->pipe.clear = cell_clear_surface; + cell->pipe.flush = cell_flush; + + /* textures */ + cell->pipe.texture_create = cell_texture_create; + cell->pipe.texture_release = cell_texture_release; + cell->pipe.get_tex_surface = cell_get_tex_surface; + + cell->pipe.set_sampler_texture = cell_set_sampler_texture; + +#if 0 + cell->pipe.begin_query = cell_begin_query; + cell->pipe.end_query = cell_end_query; + cell->pipe.wait_query = cell_wait_query; +#endif + + cell_init_surface_functions(cell); + + cell->draw = cell_draw_create(cell); + + cell_init_vbuf(cell); + draw_set_rasterize_stage(cell->draw, cell->vbuf); + + /* + * SPU stuff + */ + cell->num_spus = 6; + + cell_start_spus(cell); + + /* init command, vertex/index buffer info */ + for (buf = 0; buf < CELL_NUM_BUFFERS; buf++) { + cell->buffer_size[buf] = 0; + + /* init batch buffer status values, + * mark 0th buffer as used, rest as free. + */ + for (spu = 0; spu < cell->num_spus; spu++) { + if (buf == 0) + cell->buffer_status[spu][buf][0] = CELL_BUFFER_STATUS_USED; + else + cell->buffer_status[spu][buf][0] = CELL_BUFFER_STATUS_FREE; + } + } + + return &cell->pipe; +} diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h new file mode 100644 index 0000000000..3b63419b5e --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -0,0 +1,135 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef CELL_CONTEXT_H +#define CELL_CONTEXT_H + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/draw/draw_vertex.h" +#include "pipe/draw/draw_vbuf.h" +#include "cell_winsys.h" +#include "pipe/cell/common.h" + + +struct cell_vbuf_render; + +struct cell_vertex_shader_state +{ + struct pipe_shader_state shader; + void *draw_data; +}; + + +struct cell_fragment_shader_state +{ + struct pipe_shader_state shader; + void *data; +}; + + +struct cell_context +{ + struct pipe_context pipe; + + struct cell_winsys *winsys; + + const struct pipe_blend_state *blend; + const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct pipe_depth_stencil_alpha_state *depth_stencil; + const struct pipe_rasterizer_state *rasterizer; + const struct cell_vertex_shader_state *vs; + const struct cell_fragment_shader_state *fs; + + struct pipe_blend_color blend_color; + struct pipe_clip_state clip; + struct pipe_constant_buffer constants[2]; + struct pipe_framebuffer_state framebuffer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct cell_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + + ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS]; + ubyte *zsbuf_map; + + struct pipe_surface *tex_surf; + uint *tex_map; + + uint dirty; + + /** The primitive drawing context */ + struct draw_context *draw; + struct draw_stage *render_stage; + + /** For post-transformed vertex buffering: */ + struct cell_vbuf_render *vbuf_render; + struct draw_stage *vbuf; + + struct vertex_info vertex_info; + + /** Mapped constant buffers */ + void *mapped_constants[PIPE_SHADER_TYPES]; + + + uint num_spus; + + /** Buffers for command batches, vertex/index data */ + uint buffer_size[CELL_NUM_BUFFERS]; + ubyte buffer[CELL_NUM_BUFFERS][CELL_BUFFER_SIZE] ALIGN16_ATTRIB; + + int cur_batch; /**< which buffer is being filled w/ commands */ + + /** [4] to ensure 16-byte alignment for each status word */ + uint buffer_status[CELL_MAX_SPUS][CELL_NUM_BUFFERS][4] ALIGN16_ATTRIB; + +}; + + + + +static INLINE struct cell_context * +cell_context(struct pipe_context *pipe) +{ + return (struct cell_context *) pipe; +} + + +extern struct pipe_context * +cell_create_context(struct pipe_winsys *ws, struct cell_winsys *cws); + +extern void +cell_vertex_shader_queue_flush(struct draw_context *draw); + + + + +#endif /* CELL_CONTEXT_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c new file mode 100644 index 0000000000..717cd8370f --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -0,0 +1,164 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Brian Paul + * Keith Whitwell + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/p_winsys.h" + +#include "cell_context.h" +#include "cell_draw_arrays.h" +#include "cell_state.h" + +#include "pipe/draw/draw_context.h" + + + +static void +cell_map_constant_buffers(struct cell_context *sp) +{ + struct pipe_winsys *ws = sp->pipe.winsys; + uint i; + for (i = 0; i < 2; i++) { + if (sp->constants[i].size) + sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + } + + draw_set_mapped_constant_buffer(sp->draw, + sp->mapped_constants[PIPE_SHADER_VERTEX]); +} + +static void +cell_unmap_constant_buffers(struct cell_context *sp) +{ + struct pipe_winsys *ws = sp->pipe.winsys; + uint i; + for (i = 0; i < 2; i++) { + if (sp->constants[i].size) + ws->buffer_unmap(ws, sp->constants[i].buffer); + sp->mapped_constants[i] = NULL; + } +} + + +boolean +cell_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count) +{ + return cell_draw_elements(pipe, NULL, 0, mode, start, count); +} + + + +/** + * Draw vertex arrays, with optional indexing. + * Basically, map the vertex buffers (and drawing surfaces), then hand off + * the drawing to the 'draw' module. + * + * XXX should the element buffer be specified/bound with a separate function? + */ +boolean +cell_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + struct cell_context *sp = cell_context(pipe); + struct draw_context *draw = sp->draw; + unsigned i; + + /* first, check that the primitive is not malformed. It is the + * state tracker's responsibility to do send only correctly formed + * primitives down. It currently isn't doing that though... + */ +#if 1 + count = draw_trim_prim( mode, count ); +#else + if (!draw_validate_prim( mode, count )) + assert(0); +#endif + + if (sp->dirty) + cell_update_derived( sp ); + +#if 0 + cell_map_surfaces(sp); +#endif + cell_map_constant_buffers(sp); + + /* + * Map vertex buffers + */ + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (sp->vertex_buffer[i].buffer) { + void *buf = pipe->winsys->buffer_map(pipe->winsys, + sp->vertex_buffer[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(draw, i, buf); + } + } + /* Map index buffer, if present */ + if (indexBuffer) { + void *mapped_indexes = pipe->winsys->buffer_map(pipe->winsys, + indexBuffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); + } + else { + /* no index/element buffer */ + draw_set_mapped_element_buffer(draw, 0, NULL); + } + + + /* draw! */ + draw_arrays(draw, mode, start, count); + + /* + * unmap vertex/index buffers - will cause draw module to flush + */ + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (sp->vertex_buffer[i].buffer) { + draw_set_mapped_vertex_buffer(draw, i, NULL); + pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer); + } + } + if (indexBuffer) { + draw_set_mapped_element_buffer(draw, 0, NULL); + pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); + } + + /* Note: leave drawing surfaces mapped */ + cell_unmap_constant_buffers(sp); + + return TRUE; +} diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.h b/src/gallium/drivers/cell/ppu/cell_draw_arrays.h new file mode 100644 index 0000000000..d5df4aa05f --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.h @@ -0,0 +1,42 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef CELL_DRAW_ARRAYS_H +#define CELL_DRAW_ARRAYS_H + + +boolean cell_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count); + +boolean cell_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count); + + + +#endif /* CELL_DRAW_ARRAYS_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c new file mode 100644 index 0000000000..f62bc4650c --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_flush.c @@ -0,0 +1,84 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "cell_context.h" +#include "cell_batch.h" +#include "cell_flush.h" +#include "cell_spu.h" +#include "cell_render.h" +#include "pipe/draw/draw_context.h" + + +void +cell_flush(struct pipe_context *pipe, unsigned flags) +{ + struct cell_context *cell = cell_context(pipe); + + if (flags & PIPE_FLUSH_SWAPBUFFERS) + flags |= PIPE_FLUSH_WAIT; + + draw_flush( cell->draw ); + cell_flush_int(pipe, flags); +} + + +/** internal flush */ +void +cell_flush_int(struct pipe_context *pipe, unsigned flags) +{ + static boolean flushing = FALSE; /* recursion catcher */ + struct cell_context *cell = cell_context(pipe); + uint i; + + ASSERT(!flushing); + flushing = TRUE; + + if (flags & PIPE_FLUSH_WAIT) { + uint64_t *cmd = (uint64_t *) cell_batch_alloc(cell, sizeof(uint64_t)); + *cmd = CELL_CMD_FINISH; + } + + cell_batch_flush(cell); + +#if 0 + /* Send CMD_FINISH to all SPUs */ + for (i = 0; i < cell->num_spus; i++) { + send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_FINISH); + } +#endif + + if (flags & PIPE_FLUSH_WAIT) { + /* Wait for ack */ + for (i = 0; i < cell->num_spus; i++) { + uint k = wait_mbox_message(cell_global.spe_contexts[i]); + assert(k == CELL_CMD_FINISH); + } + } + + flushing = FALSE; +} diff --git a/src/gallium/drivers/cell/ppu/cell_flush.h b/src/gallium/drivers/cell/ppu/cell_flush.h new file mode 100644 index 0000000000..eda351b1cb --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_flush.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef CELL_FLUSH +#define CELL_FLUSH + +extern void +cell_flush(struct pipe_context *pipe, unsigned flags); + +extern void +cell_flush_int(struct pipe_context *pipe, unsigned flags); + +#endif diff --git a/src/gallium/drivers/cell/ppu/cell_render.c b/src/gallium/drivers/cell/ppu/cell_render.c new file mode 100644 index 0000000000..4ab277a4b2 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_render.c @@ -0,0 +1,210 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Last stage of 'draw' pipeline: send tris to SPUs. + * \author Brian Paul + */ + +#include "cell_context.h" +#include "cell_render.h" +#include "cell_spu.h" +#include "pipe/p_util.h" +#include "pipe/draw/draw_private.h" + + +struct render_stage { + struct draw_stage stage; /**< This must be first (base class) */ + + struct cell_context *cell; +}; + + +static INLINE struct render_stage * +render_stage(struct draw_stage *stage) +{ + return (struct render_stage *) stage; +} + + +static void render_begin( struct draw_stage *stage ) +{ +#if 0 + struct render_stage *render = render_stage(stage); + struct cell_context *sp = render->cell; + const struct pipe_shader_state *fs = &render->cell->fs->shader; + render->quad.nr_attrs = render->cell->nr_frag_attrs; + + render->firstFpInput = fs->input_semantic_name[0]; + + sp->quad.first->begin(sp->quad.first); +#endif +} + + +static void render_end( struct draw_stage *stage ) +{ +} + + +static void reset_stipple_counter( struct draw_stage *stage ) +{ + struct render_stage *render = render_stage(stage); + /*render->cell->line_stipple_counter = 0;*/ +} + + +static void +render_point(struct draw_stage *stage, struct prim_header *prim) +{ +} + + +static void +render_line(struct draw_stage *stage, struct prim_header *prim) +{ +} + + +/** Write a vertex into the prim buffer */ +static void +save_vertex(struct cell_prim_buffer *buf, uint pos, + const struct vertex_header *vert) +{ + uint attr, j; + + for (attr = 0; attr < 2; attr++) { + for (j = 0; j < 4; j++) { + buf->vertex[pos][attr][j] = vert->data[attr][j]; + } + } + + /* update bounding box */ + if (vert->data[0][0] < buf->xmin) + buf->xmin = vert->data[0][0]; + if (vert->data[0][0] > buf->xmax) + buf->xmax = vert->data[0][0]; + if (vert->data[0][1] < buf->ymin) + buf->ymin = vert->data[0][1]; + if (vert->data[0][1] > buf->ymax) + buf->ymax = vert->data[0][1]; +} + + +static void +render_tri(struct draw_stage *stage, struct prim_header *prim) +{ + struct render_stage *rs = render_stage(stage); + struct cell_context *cell = rs->cell; + struct cell_prim_buffer *buf = &cell->prim_buffer; + uint i; + + if (buf->num_verts + 3 > CELL_MAX_VERTS) { + cell_flush_prim_buffer(cell); + } + + i = buf->num_verts; + assert(i+2 <= CELL_MAX_VERTS); + save_vertex(buf, i+0, prim->v[0]); + save_vertex(buf, i+1, prim->v[1]); + save_vertex(buf, i+2, prim->v[2]); + buf->num_verts += 3; +} + + +/** + * Send the a RENDER command to all SPUs to have them render the prims + * in the current prim_buffer. + */ +void +cell_flush_prim_buffer(struct cell_context *cell) +{ + uint i; + + if (cell->prim_buffer.num_verts == 0) + return; + + for (i = 0; i < cell->num_spus; i++) { + struct cell_command_render *render = &cell_global.command[i].render; + render->prim_type = PIPE_PRIM_TRIANGLES; + render->num_verts = cell->prim_buffer.num_verts; + render->vertex_size = cell->vertex_info->size * 4; + render->xmin = cell->prim_buffer.xmin; + render->ymin = cell->prim_buffer.ymin; + render->xmax = cell->prim_buffer.xmax; + render->ymax = cell->prim_buffer.ymax; + render->vertex_data = &cell->prim_buffer.vertex; + ASSERT_ALIGN16(render->vertex_data); + send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_RENDER); + } + + cell->prim_buffer.num_verts = 0; + + cell->prim_buffer.xmin = 1e100; + cell->prim_buffer.ymin = 1e100; + cell->prim_buffer.xmax = -1e100; + cell->prim_buffer.ymax = -1e100; + + /* XXX temporary, need to double-buffer the prim buffer until we get + * a real command buffer/list system. + */ + cell_flush(&cell->pipe, 0x0); +} + + + +static void render_destroy( struct draw_stage *stage ) +{ + FREE( stage ); +} + + +/** + * Create a new draw/render stage. This will be plugged into the + * draw module as the last pipeline stage. + */ +struct draw_stage *cell_draw_render_stage( struct cell_context *cell ) +{ + struct render_stage *render = CALLOC_STRUCT(render_stage); + + render->cell = cell; + render->stage.draw = cell->draw; + render->stage.begin = render_begin; + render->stage.point = render_point; + render->stage.line = render_line; + render->stage.tri = render_tri; + render->stage.end = render_end; + render->stage.reset_stipple_counter = reset_stipple_counter; + render->stage.destroy = render_destroy; + + /* + render->quad.coef = render->coef; + render->quad.posCoef = &render->posCoef; + */ + + return &render->stage; +} diff --git a/src/gallium/drivers/cell/ppu/cell_render.h b/src/gallium/drivers/cell/ppu/cell_render.h new file mode 100644 index 0000000000..826dcbafeb --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_render.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef CELL_RENDER_H +#define CELL_RENDER_H + +struct cell_context; +struct draw_stage; + +extern void +cell_flush_prim_buffer(struct cell_context *cell); + +extern struct draw_stage *cell_draw_render_stage( struct cell_context *cell ); + +#endif /* CELL_RENDER_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_spu.c b/src/gallium/drivers/cell/ppu/cell_spu.c new file mode 100644 index 0000000000..7c83a47e57 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_spu.c @@ -0,0 +1,155 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include + +#include "cell_spu.h" +#include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "pipe/cell/common.h" + + +/* +helpful headers: +/opt/ibm/cell-sdk/prototype/src/include/ppu/cbe_mfc.h +*/ + + +struct cell_global_info cell_global; + + +/** + * Write a 1-word message to the given SPE mailbox. + */ +void +send_mbox_message(spe_context_ptr_t ctx, unsigned int msg) +{ + spe_in_mbox_write(ctx, &msg, 1, SPE_MBOX_ALL_BLOCKING); +} + + +/** + * Wait for a 1-word message to arrive in given mailbox. + */ +uint +wait_mbox_message(spe_context_ptr_t ctx) +{ + do { + unsigned data; + int count = spe_out_mbox_read(ctx, &data, 1); + + if (count == 1) { + return data; + } + + if (count < 0) { + /* error */ ; + } + } while (1); +} + + +static void *cell_thread_function(void *arg) +{ + struct cell_init_info *init = (struct cell_init_info *) arg; + unsigned entry = SPE_DEFAULT_ENTRY; + + ASSERT_ALIGN16(init); + + if (spe_context_run(cell_global.spe_contexts[init->id], &entry, 0, + init, NULL, NULL) < 0) { + fprintf(stderr, "spe_context_run() failed\n"); + exit(1); + } + + pthread_exit(NULL); +} + + +/** + * Create the SPU threads + */ +void +cell_start_spus(struct cell_context *cell) +{ + uint i, j; + + assert(cell->num_spus <= MAX_SPUS); + + ASSERT_ALIGN16(&cell_global.command[0]); + ASSERT_ALIGN16(&cell_global.command[1]); + + ASSERT_ALIGN16(&cell_global.inits[0]); + ASSERT_ALIGN16(&cell_global.inits[1]); + + for (i = 0; i < cell->num_spus; i++) { + cell_global.inits[i].id = i; + cell_global.inits[i].num_spus = cell->num_spus; + cell_global.inits[i].cmd = &cell_global.command[i]; + for (j = 0; j < CELL_NUM_BUFFERS; j++) { + cell_global.inits[i].buffers[j] = cell->buffer[j]; + } + cell_global.inits[i].buffer_status = &cell->buffer_status[0][0][0]; + + cell_global.spe_contexts[i] = spe_context_create(0, NULL); + if (!cell_global.spe_contexts[i]) { + fprintf(stderr, "spe_context_create() failed\n"); + exit(1); + } + + if (spe_program_load(cell_global.spe_contexts[i], &g3d_spu)) { + fprintf(stderr, "spe_program_load() failed\n"); + exit(1); + } + + pthread_create(&cell_global.spe_threads[i], NULL, &cell_thread_function, + &cell_global.inits[i]); + } +} + + +/** + * Tell all the SPUs to stop/exit. + */ +void +cell_spu_exit(struct cell_context *cell) +{ + uint i; + + for (i = 0; i < cell->num_spus; i++) { + send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_EXIT); + } + + /* wait for threads to exit */ + for (i = 0; i < cell->num_spus; i++) { + void *value; + pthread_join(cell_global.spe_threads[i], &value); + cell_global.spe_threads[i] = 0; + cell_global.spe_contexts[i] = 0; + } +} diff --git a/src/gallium/drivers/cell/ppu/cell_spu.h b/src/gallium/drivers/cell/ppu/cell_spu.h new file mode 100644 index 0000000000..19eff94f96 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_spu.h @@ -0,0 +1,82 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef CELL_SPU +#define CELL_SPU + + +#include +#include +#include "pipe/cell/common.h" + +#include "cell_context.h" + + +#define MAX_SPUS 8 + +/** + * Global vars, for now anyway. + */ +struct cell_global_info +{ + /** + * SPU/SPE handles, etc + */ + spe_context_ptr_t spe_contexts[MAX_SPUS]; + pthread_t spe_threads[MAX_SPUS]; + + /** + * Data sent to SPUs + */ + struct cell_init_info inits[MAX_SPUS]; + struct cell_command command[MAX_SPUS]; +}; + + +extern struct cell_global_info cell_global; + + +/** This is the handle for the actual SPE code */ +extern spe_program_handle_t g3d_spu; + + +extern void +send_mbox_message(spe_context_ptr_t ctx, unsigned int msg); + +extern uint +wait_mbox_message(spe_context_ptr_t ctx); + + +extern void +cell_start_spus(struct cell_context *cell); + + +extern void +cell_spu_exit(struct cell_context *cell); + + +#endif /* CELL_SPU */ diff --git a/src/gallium/drivers/cell/ppu/cell_state.h b/src/gallium/drivers/cell/ppu/cell_state.h new file mode 100644 index 0000000000..3a71ba14fa --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state.h @@ -0,0 +1,115 @@ + + +#ifndef CELL_STATE_H +#define CELL_STATE_H + + +#define CELL_NEW_VIEWPORT 0x1 +#define CELL_NEW_RASTERIZER 0x2 +#define CELL_NEW_FS 0x4 +#define CELL_NEW_BLEND 0x8 +#define CELL_NEW_CLIP 0x10 +#define CELL_NEW_SCISSOR 0x20 +#define CELL_NEW_STIPPLE 0x40 +#define CELL_NEW_FRAMEBUFFER 0x80 +#define CELL_NEW_ALPHA_TEST 0x100 +#define CELL_NEW_DEPTH_STENCIL 0x200 +#define CELL_NEW_SAMPLER 0x400 +#define CELL_NEW_TEXTURE 0x800 +#define CELL_NEW_VERTEX 0x1000 +#define CELL_NEW_VS 0x2000 +#define CELL_NEW_CONSTANTS 0x4000 +#define CELL_NEW_VERTEX_INFO 0x8000 + + + +extern void +cell_set_framebuffer_state( struct pipe_context *, + const struct pipe_framebuffer_state * ); + + + +extern void * +cell_create_blend_state(struct pipe_context *, const struct pipe_blend_state *); +extern void cell_bind_blend_state(struct pipe_context *, void *); +extern void cell_delete_blend_state(struct pipe_context *, void *); + +extern void cell_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ); + + +void * +cell_create_sampler_state(struct pipe_context *, + const struct pipe_sampler_state *); + +extern void +cell_bind_sampler_state(struct pipe_context *, unsigned, void *); + +extern void +cell_delete_sampler_state(struct pipe_context *, void *); + + +extern void * +cell_create_depth_stencil_alpha_state(struct pipe_context *, + const struct pipe_depth_stencil_alpha_state *); + +extern void +cell_bind_depth_stencil_alpha_state(struct pipe_context *, void *); + +extern void +cell_delete_depth_stencil_alpha_state(struct pipe_context *, void *); + + +void *cell_create_fs_state(struct pipe_context *, + const struct pipe_shader_state *); +void cell_bind_fs_state(struct pipe_context *, void *); +void cell_delete_fs_state(struct pipe_context *, void *); +void *cell_create_vs_state(struct pipe_context *, + const struct pipe_shader_state *); +void cell_bind_vs_state(struct pipe_context *, void *); +void cell_delete_vs_state(struct pipe_context *, void *); + + +void * +cell_create_rasterizer_state(struct pipe_context *, + const struct pipe_rasterizer_state *); +void cell_bind_rasterizer_state(struct pipe_context *, void *); +void cell_delete_rasterizer_state(struct pipe_context *, void *); + + +void cell_set_clip_state( struct pipe_context *, + const struct pipe_clip_state * ); + +void cell_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf); + +void cell_set_polygon_stipple( struct pipe_context *, + const struct pipe_poly_stipple * ); + +void +cell_set_sampler_texture(struct pipe_context *pipe, + unsigned sampler, + struct pipe_texture *texture); + +void cell_set_scissor_state( struct pipe_context *, + const struct pipe_scissor_state * ); + +void cell_set_texture_state( struct pipe_context *, + unsigned unit, struct pipe_texture * ); + +void cell_set_vertex_element(struct pipe_context *, + unsigned index, + const struct pipe_vertex_element *); + +void cell_set_vertex_buffer(struct pipe_context *, + unsigned index, + const struct pipe_vertex_buffer *); + +void cell_set_viewport_state( struct pipe_context *, + const struct pipe_viewport_state * ); + + +void cell_update_derived( struct cell_context *softpipe ); + +#endif diff --git a/src/gallium/drivers/cell/ppu/cell_state_blend.c b/src/gallium/drivers/cell/ppu/cell_state_blend.c new file mode 100644 index 0000000000..4fc60548c8 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_blend.c @@ -0,0 +1,109 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/draw/draw_context.h" +#include "cell_context.h" +#include "cell_state.h" + + + +void * +cell_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + return mem_dup(blend, sizeof(*blend)); +} + + +void +cell_bind_blend_state(struct pipe_context *pipe, void *blend) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->blend = (const struct pipe_blend_state *)blend; + + cell->dirty |= CELL_NEW_BLEND; +} + + +void +cell_delete_blend_state(struct pipe_context *pipe, void *blend) +{ + FREE(blend); +} + + +void +cell_set_blend_color(struct pipe_context *pipe, + const struct pipe_blend_color *blend_color) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->blend_color = *blend_color; + + cell->dirty |= CELL_NEW_BLEND; +} + + + + +void * +cell_create_depth_stencil_alpha_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + return mem_dup(depth_stencil, sizeof(*depth_stencil)); +} + + +void +cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->depth_stencil + = (const struct pipe_depth_stencil_alpha_state *) depth_stencil; + + cell->dirty |= CELL_NEW_DEPTH_STENCIL; +} + + +void +cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth) +{ + FREE(depth); +} diff --git a/src/gallium/drivers/cell/ppu/cell_state_clip.c b/src/gallium/drivers/cell/ppu/cell_state_clip.c new file mode 100644 index 0000000000..4f43665941 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_clip.c @@ -0,0 +1,84 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "cell_context.h" +#include "cell_state.h" +#include "pipe/draw/draw_context.h" + + +void cell_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct cell_context *cell = cell_context(pipe); + + /* pass the clip state to the draw module */ + draw_set_clip_state(cell->draw, clip); +} + + + +/* Called when driver state tracker notices changes to the viewport + * matrix: + */ +void cell_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct cell_context *cell = cell_context(pipe); + + cell->viewport = *viewport; /* struct copy */ + cell->dirty |= CELL_NEW_VIEWPORT; + + /* pass the viewport info to the draw module */ + draw_set_viewport_state(cell->draw, viewport); + + /* Using tnl/ and vf/ modules is temporary while getting started. + * Full pipe will have vertex shader, vertex fetch of its own. + */ +} + + +void cell_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct cell_context *cell = cell_context(pipe); + + memcpy( &cell->scissor, scissor, sizeof(*scissor) ); + cell->dirty |= CELL_NEW_SCISSOR; +} + + +void cell_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ + struct cell_context *cell = cell_context(pipe); + + memcpy( &cell->poly_stipple, stipple, sizeof(*stipple) ); + cell->dirty |= CELL_NEW_STIPPLE; +} diff --git a/src/gallium/drivers/cell/ppu/cell_state_derived.c b/src/gallium/drivers/cell/ppu/cell_state_derived.c new file mode 100644 index 0000000000..56daf5dfde --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_derived.c @@ -0,0 +1,192 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/draw/draw_context.h" +#include "pipe/draw/draw_vertex.h" +#include "cell_context.h" +#include "cell_batch.h" +#include "cell_state.h" +#include "cell_state_emit.h" + + +static int +find_vs_output(const struct pipe_shader_state *vs, + uint semantic_name, + uint semantic_index) +{ + uint i; + for (i = 0; i < vs->num_outputs; i++) { + if (vs->output_semantic_name[i] == semantic_name && + vs->output_semantic_index[i] == semantic_index) + return i; + } + return -1; +} + + +/** + * Determine how to map vertex program outputs to fragment program inputs. + * Basically, this will be used when computing the triangle interpolation + * coefficients from the post-transform vertex attributes. + */ +static void +calculate_vertex_layout( struct cell_context *cell ) +{ + const struct pipe_shader_state *vs = &cell->vs->shader; + const struct pipe_shader_state *fs = &cell->fs->shader; + const enum interp_mode colorInterp + = cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; + struct vertex_info *vinfo = &cell->vertex_info; + uint i; + int src; + +#if 0 + if (cell->vbuf) { + /* if using the post-transform vertex buffer, tell draw_vbuf to + * simply emit the whole post-xform vertex as-is: + */ + struct vertex_info *vinfo_vbuf = &cell->vertex_info_vbuf; + vinfo_vbuf->num_attribs = 0; + draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0); + vinfo_vbuf->size = 4 * vs->num_outputs + sizeof(struct vertex_header)/4; + } +#endif + + /* reset vinfo */ + vinfo->num_attribs = 0; + + /* we always want to emit vertex pos */ + src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src); + + + /* + * Loop over fragment shader inputs, searching for the matching output + * from the vertex shader. + */ + for (i = 0; i < fs->num_inputs; i++) { + switch (fs->input_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + /* already done above */ + break; + + case TGSI_SEMANTIC_COLOR: + src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, + fs->input_semantic_index[i]); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); + break; + + case TGSI_SEMANTIC_FOG: + src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0); +#if 1 + if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */ + src = 0; +#endif + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src); + break; + + case TGSI_SEMANTIC_GENERIC: + /* this includes texcoords and varying vars */ + src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC, + fs->input_semantic_index[i]); + assert(src >= 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); + break; + + default: + assert(0); + } + } + + draw_compute_vertex_size(vinfo); + + /* XXX only signal this if format really changes */ + cell->dirty |= CELL_NEW_VERTEX_INFO; +} + + +#if 0 +/** + * Recompute cliprect from scissor bounds, scissor enable and surface size. + */ +static void +compute_cliprect(struct cell_context *sp) +{ + unsigned surfWidth, surfHeight; + + if (sp->framebuffer.num_cbufs > 0) { + surfWidth = sp->framebuffer.cbufs[0]->width; + surfHeight = sp->framebuffer.cbufs[0]->height; + } + else { + /* no surface? */ + surfWidth = sp->scissor.maxx; + surfHeight = sp->scissor.maxy; + } + + if (sp->rasterizer->scissor) { + /* clip to scissor rect */ + sp->cliprect.minx = MAX2(sp->scissor.minx, 0); + sp->cliprect.miny = MAX2(sp->scissor.miny, 0); + sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth); + sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight); + } + else { + /* clip to surface bounds */ + sp->cliprect.minx = 0; + sp->cliprect.miny = 0; + sp->cliprect.maxx = surfWidth; + sp->cliprect.maxy = surfHeight; + } +} +#endif + + + +void cell_update_derived( struct cell_context *cell ) +{ + if (cell->dirty & (CELL_NEW_RASTERIZER | + CELL_NEW_FS | + CELL_NEW_VS)) + calculate_vertex_layout( cell ); + +#if 0 + if (cell->dirty & (CELL_NEW_SCISSOR | + CELL_NEW_DEPTH_STENCIL_ALPHA | + CELL_NEW_FRAMEBUFFER)) + compute_cliprect(cell); +#endif + + cell_emit_state(cell); + + cell->dirty = 0; +} diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c new file mode 100644 index 0000000000..5d2a786449 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -0,0 +1,103 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "cell_context.h" +#include "cell_state.h" +#include "cell_state_emit.h" +#include "cell_batch.h" +#include "cell_texture.h" + + +static void +emit_state_cmd(struct cell_context *cell, uint cmd, + const void *state, uint state_size) +{ + uint64_t *dst = (uint64_t *) + cell_batch_alloc(cell, ROUNDUP8(sizeof(uint64_t) + state_size)); + *dst = cmd; + memcpy(dst + 1, state, state_size); +} + + + +void +cell_emit_state(struct cell_context *cell) +{ + if (cell->dirty & CELL_NEW_FRAMEBUFFER) { + struct pipe_surface *cbuf = cell->framebuffer.cbufs[0]; + struct pipe_surface *zbuf = cell->framebuffer.zsbuf; + struct cell_command_framebuffer *fb + = cell_batch_alloc(cell, sizeof(*fb)); + fb->opcode = CELL_CMD_STATE_FRAMEBUFFER; + fb->color_start = cell->cbuf_map[0]; + fb->color_format = cbuf->format; + fb->depth_start = cell->zsbuf_map; + fb->depth_format = zbuf ? zbuf->format : PIPE_FORMAT_NONE; + fb->width = cell->framebuffer.cbufs[0]->width; + fb->height = cell->framebuffer.cbufs[0]->height; + } + + if (cell->dirty & CELL_NEW_BLEND) { + emit_state_cmd(cell, CELL_CMD_STATE_BLEND, + cell->blend, + sizeof(struct pipe_blend_state)); + } + + if (cell->dirty & CELL_NEW_DEPTH_STENCIL) { + emit_state_cmd(cell, CELL_CMD_STATE_DEPTH_STENCIL, + cell->depth_stencil, + sizeof(struct pipe_depth_stencil_alpha_state)); + } + + if (cell->dirty & CELL_NEW_SAMPLER) { + emit_state_cmd(cell, CELL_CMD_STATE_SAMPLER, + cell->sampler[0], sizeof(struct pipe_sampler_state)); + } + + if (cell->dirty & CELL_NEW_TEXTURE) { + struct cell_command_texture texture; + if (cell->texture[0]) { + texture.start = cell->texture[0]->tiled_data; + texture.width = cell->texture[0]->base.width[0]; + texture.height = cell->texture[0]->base.height[0]; + } + else { + texture.start = NULL; + texture.width = 0; + texture.height = 0; + } + + emit_state_cmd(cell, CELL_CMD_STATE_TEXTURE, + &texture, sizeof(struct cell_command_texture)); + } + + if (cell->dirty & CELL_NEW_VERTEX_INFO) { + emit_state_cmd(cell, CELL_CMD_STATE_VERTEX_INFO, + &cell->vertex_info, sizeof(struct vertex_info)); + } +} diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.h b/src/gallium/drivers/cell/ppu/cell_state_emit.h new file mode 100644 index 0000000000..59f8affe8d --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.h @@ -0,0 +1,36 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef CELL_STATE_EMIT_H +#define CELL_STATE_EMIT_H + + +extern void +cell_emit_state(struct cell_context *cell); + + +#endif /* CELL_STATE_EMIT_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_state_fs.c b/src/gallium/drivers/cell/ppu/cell_state_fs.c new file mode 100644 index 0000000000..3f46a87d18 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_fs.c @@ -0,0 +1,171 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" +#include "pipe/draw/draw_context.h" +#if 0 +#include "pipe/p_shader_tokens.h" +#include "pipe/llvm/gallivm.h" +#include "pipe/tgsi/util/tgsi_dump.h" +#include "pipe/tgsi/exec/tgsi_sse2.h" +#endif + +#include "cell_context.h" +#include "cell_state.h" + + +void * +cell_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + /*struct cell_context *cell = cell_context(pipe);*/ + struct cell_fragment_shader_state *state; + + state = CALLOC_STRUCT(cell_fragment_shader_state); + if (!state) + return NULL; + + state->shader = *templ; + +#if 0 + if (cell->dump_fs) { + tgsi_dump(state->shader.tokens, 0); + } + +#if defined(__i386__) || defined(__386__) + if (cell->use_sse) { + x86_init_func( &state->sse2_program ); + tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program ); + } +#endif + +#ifdef MESA_LLVM + state->llvm_prog = 0; + if (!gallivm_global_cpu_engine()) { + gallivm_cpu_engine_create(state->llvm_prog); + } + else + gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); +#endif +#endif + + return state; +} + + +void +cell_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct cell_context *cell = cell_context(pipe); + + cell->fs = (struct cell_fragment_shader_state *) fs; + + cell->dirty |= CELL_NEW_FS; +} + + +void +cell_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct cell_fragment_shader_state *state = + (struct cell_fragment_shader_state *) fs; + + FREE( state ); +} + + +void * +cell_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct cell_context *cell = cell_context(pipe); + struct cell_vertex_shader_state *state; + + state = CALLOC_STRUCT(cell_vertex_shader_state); + if (!state) + return NULL; + + state->shader = *templ; + + state->draw_data = draw_create_vertex_shader(cell->draw, &state->shader); + if (state->draw_data == NULL) { + FREE( state ); + return NULL; + } + + return state; +} + + +void +cell_bind_vs_state(struct pipe_context *pipe, void *vs) +{ + struct cell_context *cell = cell_context(pipe); + + cell->vs = (const struct cell_vertex_shader_state *) vs; + + draw_bind_vertex_shader(cell->draw, cell->vs->draw_data); + + cell->dirty |= CELL_NEW_VS; +} + + +void +cell_delete_vs_state(struct pipe_context *pipe, void *vs) +{ + struct cell_context *cell = cell_context(pipe); + + struct cell_vertex_shader_state *state = + (struct cell_vertex_shader_state *) vs; + + draw_delete_vertex_shader(cell->draw, state->draw_data); + FREE( state ); +} + + +void +cell_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct cell_context *cell = cell_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + + assert(shader < PIPE_SHADER_TYPES); + assert(index == 0); + + /* note: reference counting */ + pipe_buffer_reference(ws, + &cell->constants[shader].buffer, + buf->buffer); + cell->constants[shader].size = buf->size; + + cell->dirty |= CELL_NEW_CONSTANTS; +} diff --git a/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c b/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c new file mode 100644 index 0000000000..d8128ece54 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c @@ -0,0 +1,106 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/draw/draw_context.h" +#include "cell_context.h" +#include "cell_state.h" + + + +struct spu_rasterizer_state +{ + unsigned flatshade:1; +#if 0 + unsigned light_twoside:1; + unsigned front_winding:2; /**< PIPE_WINDING_x */ + unsigned cull_mode:2; /**< PIPE_WINDING_x */ + unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */ + unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */ + unsigned offset_cw:1; + unsigned offset_ccw:1; +#endif + unsigned scissor:1; + unsigned poly_smooth:1; + unsigned poly_stipple_enable:1; + unsigned point_smooth:1; +#if 0 + unsigned point_sprite:1; + unsigned point_size_per_vertex:1; /**< size computed in vertex shader */ +#endif + unsigned multisample:1; /* XXX maybe more ms state in future */ + unsigned line_smooth:1; + unsigned line_stipple_enable:1; + unsigned line_stipple_factor:8; /**< [1..256] actually */ + unsigned line_stipple_pattern:16; +#if 0 + unsigned bypass_clipping:1; +#endif + unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ + + float line_width; + float point_size; /**< used when no per-vertex size */ +#if 0 + float offset_units; + float offset_scale; + ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */ +#endif +}; + + + +void * +cell_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *setup) +{ + struct pipe_rasterizer_state *state + = MALLOC(sizeof(struct pipe_rasterizer_state)); + memcpy(state, setup, sizeof(struct pipe_rasterizer_state)); + return state; +} + + +void +cell_bind_rasterizer_state(struct pipe_context *pipe, void *setup) +{ + struct cell_context *cell = cell_context(pipe); + + /* pass-through to draw module */ + draw_set_rasterizer_state(cell->draw, setup); + + cell->rasterizer = (struct pipe_rasterizer_state *)setup; + + cell->dirty |= CELL_NEW_RASTERIZER; +} + + +void +cell_delete_rasterizer_state(struct pipe_context *pipe, void *rasterizer) +{ + FREE(rasterizer); +} diff --git a/src/gallium/drivers/cell/ppu/cell_state_sampler.c b/src/gallium/drivers/cell/ppu/cell_state_sampler.c new file mode 100644 index 0000000000..ade6cc8338 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_sampler.c @@ -0,0 +1,84 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: + * Brian Paul + */ + +#include "pipe/p_util.h" +#include "pipe/draw/draw_context.h" +#include "cell_context.h" +#include "cell_state.h" +#include "cell_texture.h" + + +void * +cell_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + return mem_dup(sampler, sizeof(*sampler)); +} + +void +cell_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, void *sampler) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + assert(unit < PIPE_MAX_SAMPLERS); + cell->sampler[unit] = (struct pipe_sampler_state *)sampler; + + cell->dirty |= CELL_NEW_SAMPLER; +} + + +void +cell_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + FREE( sampler ); +} + + + +void +cell_set_sampler_texture(struct pipe_context *pipe, + unsigned sampler, + struct pipe_texture *texture) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->texture[sampler] = texture; + + cell_update_texture_mapping(cell); + + cell->dirty |= CELL_NEW_TEXTURE; +} diff --git a/src/gallium/drivers/cell/ppu/cell_state_surface.c b/src/gallium/drivers/cell/ppu/cell_state_surface.c new file mode 100644 index 0000000000..287610b76b --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_surface.c @@ -0,0 +1,71 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_inlines.h" +#include "cell_context.h" +#include "cell_state.h" + + +void +cell_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct cell_context *cell = cell_context(pipe); + + if (1 /*memcmp(&cell->framebuffer, fb, sizeof(*fb))*/) { + struct pipe_surface *csurf = fb->cbufs[0]; + struct pipe_surface *zsurf = fb->zsbuf; + uint i; + + /* unmap old surfaces */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { + if (cell->framebuffer.cbufs[i] && cell->cbuf_map[i]) { + pipe_surface_unmap(cell->framebuffer.cbufs[i]); + cell->cbuf_map[i] = NULL; + } + } + + if (cell->framebuffer.zsbuf && cell->zsbuf_map) { + pipe_surface_unmap(cell->framebuffer.zsbuf); + cell->zsbuf_map = NULL; + } + + /* update my state */ + cell->framebuffer = *fb; + + /* map new surfaces */ + if (csurf) + cell->cbuf_map[0] = pipe_surface_map(csurf); + + if (zsurf) + cell->zsbuf_map = pipe_surface_map(zsurf); + + cell->dirty |= CELL_NEW_FRAMEBUFFER; + } +} + diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c new file mode 100644 index 0000000000..0f01e920f9 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + + +#include "cell_context.h" +#include "cell_state.h" + +#include "pipe/draw/draw_context.h" + + +void +cell_set_vertex_element(struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_element *attrib) +{ + struct cell_context *cell = cell_context(pipe); + assert(index < PIPE_ATTRIB_MAX); + cell->vertex_element[index] = *attrib; /* struct copy */ + cell->dirty |= CELL_NEW_VERTEX; + + draw_set_vertex_element(cell->draw, index, attrib); +} + + +void +cell_set_vertex_buffer(struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_buffer *buffer) +{ + struct cell_context *cell = cell_context(pipe); + assert(index < PIPE_ATTRIB_MAX); + cell->vertex_buffer[index] = *buffer; /* struct copy */ + cell->dirty |= CELL_NEW_VERTEX; + + draw_set_vertex_buffer(cell->draw, index, buffer); +} diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c new file mode 100644 index 0000000000..fca93e4742 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_surface.c @@ -0,0 +1,179 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" +#include "pipe/util/p_tile.h" +#include "cell_context.h" +#include "cell_surface.h" + + +/* Upload data to a rectangular sub-region. Lots of choices how to do this: + * + * - memcpy by span to current destination + * - upload data as new buffer and blit + * + * Currently always memcpy. + */ +static void +cell_surface_data(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + const void *src, unsigned src_pitch, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + pipe_copy_rect(pipe_surface_map(dst), + dst->cpp, + dst->pitch, + dstx, dsty, width, height, src, src_pitch, srcx, srcy); + + pipe_surface_unmap(dst); +} + + +static void +cell_surface_copy(struct pipe_context *pipe, + unsigned do_flip, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + assert( dst->cpp == src->cpp ); + + pipe_copy_rect(pipe_surface_map(dst), + dst->cpp, + dst->pitch, + dstx, dsty, + width, height, + pipe_surface_map(src), + do_flip ? -src->pitch : src->pitch, + srcx, do_flip ? 1 - srcy - height : srcy); + + pipe_surface_unmap(src); + pipe_surface_unmap(dst); +} + + +static void * +get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) +{ + return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; +} + + +#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8)) + + +/** + * Fill a rectangular sub-region. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ +static void +cell_surface_fill(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, unsigned value) +{ + unsigned i, j; + void *dst_map = pipe_surface_map(dst); + + assert(dst->pitch > 0); + assert(width <= dst->pitch); + + switch (dst->cpp) { + case 1: + { + ubyte *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + memset(row, value, width); + row += dst->pitch; + } + } + break; + case 2: + { + ushort *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = (ushort) value; + row += dst->pitch; + } + } + break; + case 4: + { + unsigned *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = value; + row += dst->pitch; + } + } + break; + case 8: + { + /* expand the 4-byte clear value to an 8-byte value */ + ushort *row = (ushort *) get_pointer(dst, dst_map, dstx, dsty); + ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff); + ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff); + ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff); + ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff); + val0 = (val0 << 8) | val0; + val1 = (val1 << 8) | val1; + val2 = (val2 << 8) | val2; + val3 = (val3 << 8) | val3; + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + row[j*4+0] = val0; + row[j*4+1] = val1; + row[j*4+2] = val2; + row[j*4+3] = val3; + } + row += dst->pitch * 4; + } + } + break; + default: + assert(0); + break; + } + + pipe_surface_unmap( dst ); +} + + +void +cell_init_surface_functions(struct cell_context *cell) +{ + cell->pipe.surface_copy = cell_surface_copy; + cell->pipe.surface_fill = cell_surface_fill; +} diff --git a/src/gallium/drivers/cell/ppu/cell_surface.h b/src/gallium/drivers/cell/ppu/cell_surface.h new file mode 100644 index 0000000000..9e58f32944 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_surface.h @@ -0,0 +1,42 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef CELL_SURFACE_H +#define CELL_SURFACE_H + + +struct cell_context; + + +extern void +cell_init_surface_functions(struct cell_context *cell); + + +#endif /* SP_SURFACE_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c new file mode 100644 index 0000000000..c8ef36002f --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -0,0 +1,252 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell + * Michel Dänzer + */ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" + +#include "cell_context.h" +#include "cell_state.h" +#include "cell_texture.h" + + +/* Simple, maximally packed layout. + */ + +static unsigned minify( unsigned d ) +{ + return MAX2(1, d>>1); +} + + +static void +cell_texture_layout(struct cell_texture * spt) +{ + struct pipe_texture *pt = &spt->base; + unsigned level; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; + + spt->buffer_size = 0; + + for ( level = 0 ; level <= pt->last_level ; level++ ) { + pt->width[level] = width; + pt->height[level] = height; + pt->depth[level] = depth; + + spt->level_offset[level] = spt->buffer_size; + + spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * + ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * + width * pt->cpp; + + width = minify(width); + height = minify(height); + depth = minify(depth); + } +} + + +struct pipe_texture * +cell_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) +{ + struct cell_texture *spt = CALLOC_STRUCT(cell_texture); + if (!spt) + return NULL; + + spt->base = *templat; + + cell_texture_layout(spt); + + spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32, + PIPE_BUFFER_USAGE_PIXEL, + spt->buffer_size); + + if (!spt->buffer) { + FREE(spt); + return NULL; + } + + return &spt->base; +} + + +void +cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + if (!*pt) + return; + + /* + DBG("%s %p refcount will be %d\n", + __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); + */ + if (--(*pt)->refcount <= 0) { + struct cell_texture *spt = cell_texture(*pt); + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); + */ + + pipe_buffer_reference(pipe->winsys, &spt->buffer, NULL); + + FREE(spt); + } + *pt = NULL; +} + + +/** + * Called via pipe->get_tex_surface() + */ +struct pipe_surface * +cell_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct cell_texture *spt = cell_texture(pt); + struct pipe_surface *ps; + + ps = pipe->winsys->surface_alloc(pipe->winsys); + if (ps) { + assert(ps->refcount); + assert(ps->winsys); + pipe_buffer_reference(pipe->winsys, &ps->buffer, spt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = ps->width; + ps->offset = spt->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { + ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * + (pt->compressed ? ps->height/4 : ps->height) * + ps->width * ps->cpp; + } else { + assert(face == 0); + assert(zslice == 0); + } + } + return ps; +} + + + +static void +tile_copy_data(uint w, uint h, uint tile_size, uint *dst, const uint *src) +{ + const uint tile_size2 = tile_size * tile_size; + const uint h_t = h / tile_size, w_t = w / tile_size; + + uint it, jt; /* tile counters */ + uint i, j; /* intra-tile counters */ + + for (it = 0; it < h_t; it++) { + for (jt = 0; jt < w_t; jt++) { + /* fill in tile (i, j) */ + uint *tdst = dst + (it * w_t + jt) * tile_size2; + for (i = 0; i < tile_size; i++) { + for (j = 0; j < tile_size; j++) { + const uint srci = it * tile_size + i; + const uint srcj = jt * tile_size + j; + *tdst++ = src[srci * h + srcj]; + } + } + } + } +} + + + +/** + * Convert linear texture image data to tiled format for SPU usage. + */ +static void +cell_tile_texture(struct cell_context *cell, + struct cell_texture *texture) +{ + uint face = 0, level = 0, zslice = 0; + struct pipe_surface *surf; + const uint w = texture->base.width[0], h = texture->base.height[0]; + const uint *src; + + /* temporary restrictions: */ + assert(w >= TILE_SIZE); + assert(h >= TILE_SIZE); + assert(w % TILE_SIZE == 0); + assert(h % TILE_SIZE == 0); + + surf = cell_get_tex_surface(&cell->pipe, &texture->base, face, level, zslice); + ASSERT(surf); + + src = (const uint *) pipe_surface_map(surf); + + if (texture->tiled_data) { + align_free(texture->tiled_data); + } + texture->tiled_data = align_malloc(w * h * 4, 16); + + tile_copy_data(w, h, TILE_SIZE, texture->tiled_data, src); + + pipe_surface_unmap(surf); + + pipe_surface_reference(&surf, NULL); +} + + + +void +cell_update_texture_mapping(struct cell_context *cell) +{ + uint face = 0, level = 0, zslice = 0; + + if (cell->texture[0]) + cell_tile_texture(cell, cell->texture[0]); +#if 0 + if (cell->tex_surf && cell->tex_map) { + pipe_surface_unmap(cell->tex_surf); + cell->tex_map = NULL; + } + + /* XXX free old surface */ + + cell->tex_surf = cell_get_tex_surface(&cell->pipe, + &cell->texture[0]->base, + face, level, zslice); + + cell->tex_map = pipe_surface_map(cell->tex_surf); +#endif +} diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h new file mode 100644 index 0000000000..0264fed88e --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_texture.h @@ -0,0 +1,80 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef CELL_TEXTURE_H +#define CELL_TEXTURE_H + + +struct pipe_context; +struct pipe_texture; + + +/** + * Subclass of pipe_texture + */ +struct cell_texture +{ + struct pipe_texture base; + + unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; + unsigned long buffer_size; + + void *tiled_data; /* XXX this may be temporary */ /*ALIGN16*/ +}; + + +/** cast wrapper */ +static INLINE struct cell_texture * +cell_texture(struct pipe_texture *pt) +{ + return (struct cell_texture *) pt; +} + + + +extern struct pipe_texture * +cell_texture_create(struct pipe_context *pipe, + const struct pipe_texture *templat); + +extern void +cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); + +extern struct pipe_surface * +cell_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice); + + +extern void +cell_update_texture_mapping(struct cell_context *cell); + + +#endif /* CELL_TEXTURE */ diff --git a/src/gallium/drivers/cell/ppu/cell_vbuf.c b/src/gallium/drivers/cell/ppu/cell_vbuf.c new file mode 100644 index 0000000000..e9fafe492e --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_vbuf.c @@ -0,0 +1,294 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Authors + * Brian Paul + */ + + +#include "cell_batch.h" +#include "cell_context.h" +#include "cell_flush.h" +#include "cell_spu.h" +#include "cell_vbuf.h" +#include "pipe/draw/draw_vbuf.h" + + +/** Allow vertex data to be inlined after RENDER command */ +#define ALLOW_INLINE_VERTS 1 + + +/** + * Subclass of vbuf_render because we need a cell_context pointer in + * a few places. + */ +struct cell_vbuf_render +{ + struct vbuf_render base; + struct cell_context *cell; + uint prim; /**< PIPE_PRIM_x */ + uint vertex_size; /**< in bytes */ + void *vertex_buffer; /**< just for debug, really */ + uint vertex_buf; /**< in [0, CELL_NUM_BUFFERS-1] */ +}; + + +/** cast wrapper */ +static struct cell_vbuf_render * +cell_vbuf_render(struct vbuf_render *vbr) +{ + return (struct cell_vbuf_render *) vbr; +} + + + +static const struct vertex_info * +cell_vbuf_get_vertex_info(struct vbuf_render *vbr) +{ + struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); + return &cvbr->cell->vertex_info; +} + + +static void * +cell_vbuf_allocate_vertices(struct vbuf_render *vbr, + ushort vertex_size, ushort nr_vertices) +{ + struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); + /*printf("Alloc verts %u * %u\n", vertex_size, nr_vertices);*/ + + assert(cvbr->vertex_buf == ~0); + cvbr->vertex_buf = cell_get_empty_buffer(cvbr->cell); + cvbr->vertex_buffer = cvbr->cell->buffer[cvbr->vertex_buf]; + cvbr->vertex_size = vertex_size; + return cvbr->vertex_buffer; +} + + +static void +cell_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices, + unsigned vertex_size, unsigned vertices_used) +{ + struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); + struct cell_context *cell = cvbr->cell; + + /* + printf("%s vertex_buf = %u count = %u\n", + __FUNCTION__, cvbr->vertex_buf, vertices_used); + */ + + /* Tell SPUs they can release the vert buf */ + if (cvbr->vertex_buf != ~0U) { + struct cell_command_release_verts *release + = (struct cell_command_release_verts *) + cell_batch_alloc(cell, sizeof(struct cell_command_release_verts)); + release->opcode = CELL_CMD_RELEASE_VERTS; + release->vertex_buf = cvbr->vertex_buf; + } + + cvbr->vertex_buf = ~0; + cell_flush_int(&cell->pipe, 0x0); + + assert(vertices == cvbr->vertex_buffer); + cvbr->vertex_buffer = NULL; +} + + + +static void +cell_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) +{ + struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); + cvbr->prim = prim; + /*printf("cell_set_prim %u\n", prim);*/ +} + + +static void +cell_vbuf_draw(struct vbuf_render *vbr, + const ushort *indices, + uint nr_indices) +{ + struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); + struct cell_context *cell = cvbr->cell; + float xmin, ymin, xmax, ymax; + uint i; + uint nr_vertices = 0, min_index = ~0; + const void *vertices = cvbr->vertex_buffer; + const uint vertex_size = cvbr->vertex_size; + + for (i = 0; i < nr_indices; i++) { + if (indices[i] > nr_vertices) + nr_vertices = indices[i]; + if (indices[i] < min_index) + min_index = indices[i]; + } + nr_vertices++; + +#if 0 + /*if (min_index > 0)*/ + printf("%s min_index = %u\n", __FUNCTION__, min_index); +#endif + +#if 0 + printf("cell_vbuf_draw() nr_indices = %u nr_verts = %u\n", + nr_indices, nr_vertices); + printf(" "); + for (i = 0; i < nr_indices; i += 3) { + printf("%u %u %u, ", indices[i+0], indices[i+1], indices[i+2]); + } + printf("\n"); +#elif 0 + printf("cell_vbuf_draw() nr_indices = %u nr_verts = %u indexes = [%u %u %u ...]\n", + nr_indices, nr_vertices, + indices[0], indices[1], indices[2]); + printf("ind space = %u, vert space = %u, space = %u\n", + nr_indices * 2, + nr_vertices * 4 * cell->vertex_info.size, + cell_batch_free_space(cell)); +#endif + + /* compute x/y bounding box */ + xmin = ymin = 1e50; + xmax = ymax = -1e50; + for (i = min_index; i < nr_vertices; i++) { + const float *v = (float *) ((ubyte *) vertices + i * vertex_size); + if (v[0] < xmin) + xmin = v[0]; + if (v[0] > xmax) + xmax = v[0]; + if (v[1] < ymin) + ymin = v[1]; + if (v[1] > ymax) + ymax = v[1]; + } +#if 0 + printf("PPU Bounds %g, %g .. %g, %g\n", xmin, ymin, xmax, ymax); + fflush(stdout); +#endif + + if (cvbr->prim != PIPE_PRIM_TRIANGLES) + return; /* only render tris for now */ + + /* build/insert batch RENDER command */ + { + const uint index_bytes = ROUNDUP8(nr_indices * 2); + const uint vertex_bytes = nr_vertices * 4 * cell->vertex_info.size; + const uint batch_size = sizeof(struct cell_command_render) + index_bytes; + + struct cell_command_render *render + = (struct cell_command_render *) + cell_batch_alloc(cell, batch_size); + + render->opcode = CELL_CMD_RENDER; + render->prim_type = cvbr->prim; + + render->num_indexes = nr_indices; + render->min_index = min_index; + + /* append indices after render command */ + memcpy(render + 1, indices, nr_indices * 2); + + /* if there's room, append vertices after the indices, else leave + * vertices in the original/separate buffer. + */ + render->vertex_size = 4 * cell->vertex_info.size; + render->num_verts = nr_vertices; + if (ALLOW_INLINE_VERTS && + min_index == 0 && + vertex_bytes + 16 <= cell_batch_free_space(cell)) { + /* vertex data inlined, after indices, at 16-byte boundary */ + void *dst = cell_batch_alloc_aligned(cell, vertex_bytes, 16); + memcpy(dst, vertices, vertex_bytes); + render->inline_verts = TRUE; + render->vertex_buf = ~0; + } + else { + /* vertex data in separate buffer */ + render->inline_verts = FALSE; + ASSERT(cvbr->vertex_buf >= 0); + render->vertex_buf = cvbr->vertex_buf; + } + + render->xmin = xmin; + render->ymin = ymin; + render->xmax = xmax; + render->ymax = ymax; + } + +#if 0 + /* helpful for debug */ + cell_flush_int(&cell->pipe, PIPE_FLUSH_WAIT); +#endif +} + + +static void +cell_vbuf_destroy(struct vbuf_render *vbr) +{ + struct cell_vbuf_render *cvbr = cell_vbuf_render(vbr); + cvbr->cell->vbuf_render = NULL; + FREE(cvbr); +} + + +/** + * Initialize the post-transform vertex buffer information for the given + * context. + */ +void +cell_init_vbuf(struct cell_context *cell) +{ + assert(cell->draw); + + cell->vbuf_render = CALLOC_STRUCT(cell_vbuf_render); + + /* The max number of indexes is what can fix into a batch buffer, + * minus the render and release-verts commands. + */ + cell->vbuf_render->base.max_indices + = (CELL_BUFFER_SIZE + - sizeof(struct cell_command_render) + - sizeof(struct cell_command_release_verts)) + / sizeof(ushort); + cell->vbuf_render->base.max_vertex_buffer_bytes = CELL_BUFFER_SIZE; + + cell->vbuf_render->base.get_vertex_info = cell_vbuf_get_vertex_info; + cell->vbuf_render->base.allocate_vertices = cell_vbuf_allocate_vertices; + cell->vbuf_render->base.set_primitive = cell_vbuf_set_primitive; + cell->vbuf_render->base.draw = cell_vbuf_draw; + cell->vbuf_render->base.release_vertices = cell_vbuf_release_vertices; + cell->vbuf_render->base.destroy = cell_vbuf_destroy; + + cell->vbuf_render->cell = cell; +#if 1 + cell->vbuf_render->vertex_buf = ~0; +#endif + + cell->vbuf = draw_vbuf_stage(cell->draw, &cell->vbuf_render->base); +} diff --git a/src/gallium/drivers/cell/ppu/cell_vbuf.h b/src/gallium/drivers/cell/ppu/cell_vbuf.h new file mode 100644 index 0000000000..d265cbf770 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_vbuf.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef CELL_VBUF_H +#define CELL_VBUF_H + + +struct cell_context; + +extern void +cell_init_vbuf(struct cell_context *cell); + + +#endif /* CELL_VBUF_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c new file mode 100644 index 0000000000..80dd500b34 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -0,0 +1,120 @@ +/* + * (C) Copyright IBM Corporation 2008 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file cell_vertex_shader.c + * Vertex shader interface routines for Cell. + * + * \author Ian Romanick + */ + +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/p_winsys.h" + +#include "cell_context.h" +#include "cell_draw_arrays.h" +#include "cell_spu.h" +#include "cell_batch.h" + +#include "pipe/cell/common.h" +#include "pipe/draw/draw_context.h" +#include "pipe/draw/draw_private.h" + +/** + * Run the vertex shader on all vertices in the vertex queue. + * Called by the draw module when the vertx cache needs to be flushed. + */ +void +cell_vertex_shader_queue_flush(struct draw_context *draw) +{ + struct cell_context *const cell = + (struct cell_context *) draw->driver_private; + struct cell_command_vs *const vs = &cell_global.command[0].vs; + uint64_t *batch; + struct cell_array_info *array_info; + unsigned i, j; + + assert(draw->vs.queue_nr != 0); + + /* XXX: do this on statechange: + */ + draw_update_vertex_fetch(draw); + + for (i = 0; i < draw->vertex_fetch.nr_attrs; i++) { + batch = cell_batch_alloc(cell, sizeof(batch[0]) + sizeof(*array_info)); + + batch[0] = CELL_CMD_STATE_VS_ARRAY_INFO; + + array_info = (struct cell_array_info *) &batch[1]; + assert(draw->vertex_fetch.src_ptr[i] != NULL); + array_info->base = (uintptr_t) draw->vertex_fetch.src_ptr[i]; + array_info->attr = i; + array_info->pitch = draw->vertex_fetch.pitch[i]; + array_info->format = draw->vertex_element[i].src_format; + } + + batch = cell_batch_alloc(cell, sizeof(batch[0]) + + sizeof(struct pipe_viewport_state)); + batch[0] = CELL_CMD_STATE_VIEWPORT; + (void) memcpy(&batch[1], &draw->viewport, + sizeof(struct pipe_viewport_state)); + + cell_batch_flush(cell); + + vs->opcode = CELL_CMD_VS_EXECUTE; + vs->shader.num_outputs = draw->num_vs_outputs; + vs->shader.declarations = (uintptr_t) draw->machine.Declarations; + vs->shader.num_declarations = draw->machine.NumDeclarations; + vs->shader.instructions = (uintptr_t) draw->machine.Instructions; + vs->shader.num_instructions = draw->machine.NumInstructions; + vs->shader.uniforms = (uintptr_t) draw->user.constants; + vs->shader.immediates = (uintptr_t) draw->machine.Imms; + vs->shader.num_immediates = draw->machine.ImmLimit / 4; + vs->nr_attrs = draw->vertex_fetch.nr_attrs; + + (void) memcpy(vs->plane, draw->plane, sizeof(draw->plane)); + vs->nr_planes = draw->nr_planes; + + for (i = 0; i < draw->vs.queue_nr; i += SPU_VERTS_PER_BATCH) { + const unsigned n = MIN2(SPU_VERTS_PER_BATCH, draw->vs.queue_nr - i); + + for (j = 0; j < n; j++) { + vs->elts[j] = draw->vs.queue[i + j].elt; + vs->vOut[j] = (uintptr_t) draw->vs.queue[i + j].dest; + } + + for (/* empty */; j < SPU_VERTS_PER_BATCH; j++) { + vs->elts[j] = vs->elts[0]; + vs->vOut[j] = vs->vOut[0]; + } + + vs->num_elts = n; + send_mbox_message(cell_global.spe_contexts[0], CELL_CMD_VS_EXECUTE); + + cell_flush_int(& cell->pipe, PIPE_FLUSH_WAIT); + } + + draw->vs.queue_nr = 0; +} diff --git a/src/gallium/drivers/cell/ppu/cell_winsys.c b/src/gallium/drivers/cell/ppu/cell_winsys.c new file mode 100644 index 0000000000..ebabce3c8f --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_winsys.c @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_util.h" +#include "cell_winsys.h" + + +struct cell_winsys * +cell_get_winsys(uint format) +{ + struct cell_winsys *cws = CALLOC_STRUCT(cell_winsys); + if (cws) + cws->preferredFormat = format; + return cws; +} diff --git a/src/gallium/drivers/cell/ppu/cell_winsys.h b/src/gallium/drivers/cell/ppu/cell_winsys.h new file mode 100644 index 0000000000..ae2af5696b --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_winsys.h @@ -0,0 +1,50 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef CELL_WINSYS_H +#define CELL_WINSYS_H + +#include "pipe/p_compiler.h" + + +/** + * Very simple winsys at this time. + * Will probably eventually add SPU control info. + */ +struct cell_winsys +{ + uint preferredFormat; +}; + + +extern struct cell_winsys * +cell_get_winsys(uint format); + + + +#endif diff --git a/src/gallium/drivers/cell/spu/Makefile b/src/gallium/drivers/cell/spu/Makefile new file mode 100644 index 0000000000..f202971d73 --- /dev/null +++ b/src/gallium/drivers/cell/spu/Makefile @@ -0,0 +1,72 @@ +# Gallium3D Cell driver: SPU code + +# This makefile builds the g3d_spu.a file that's linked into the +# PPU code/library. + + +TOP = ../../../../.. +include $(TOP)/configs/linux-cell + + +PROG = g3d + +PROG_SPU = $(PROG)_spu +PROG_SPU_A = $(PROG)_spu.a +PROG_SPU_EMBED_O = $(PROG)_spu-embed.o + + +SOURCES = \ + spu_main.c \ + spu_blend.c \ + spu_render.c \ + spu_texture.c \ + spu_tile.c \ + spu_tri.c \ + spu_exec.c \ + spu_util.c \ + spu_vertex_fetch.c \ + spu_vertex_shader.c + +SPU_OBJECTS = $(SOURCES:.c=.o) \ + +SPU_ASM_OUT = $(SOURCES:.c=.s) \ + +INCLUDE_DIRS = -I$(TOP)/src/mesa + + +.c.o: + $(SPU_CC) $(SPU_CFLAGS) -c $< + +.c.s: + $(SPU_CC) $(SPU_CFLAGS) -S $< + + +# The .a file will be linked into the main/PPU executable +default: $(PROG_SPU_A) + +$(PROG_SPU_A): $(PROG_SPU_EMBED_O) + $(SPU_AR) $(SPU_AR_FLAGS) $(PROG_SPU_A) $(PROG_SPU_EMBED_O) + +$(PROG_SPU_EMBED_O): $(PROG_SPU) + $(SPU_EMBED) $(SPU_EMBED_FLAGS) $(PROG_SPU) $(PROG_SPU) $(PROG_SPU_EMBED_O) + +$(PROG_SPU): $(SPU_OBJECTS) + $(SPU_CC) -o $(PROG_SPU) $(SPU_OBJECTS) $(SPU_LFLAGS) + + + +asmfiles: $(SPU_ASM_OUT) + + +clean: + rm -f *~ *.o *.a *.d *.s $(PROG_SPU) + + + +depend: $(SOURCES) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDE_DIRS) $(SOURCES) 2> /dev/null + +include depend + diff --git a/src/gallium/drivers/cell/spu/spu_blend.c b/src/gallium/drivers/cell/spu/spu_blend.c new file mode 100644 index 0000000000..23ec0eeb45 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_blend.c @@ -0,0 +1,62 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "spu_main.h" +#include "spu_blend.h" +#include "spu_colorpack.h" + + +void +blend_quad(uint itx, uint ity, vector float colors[4]) +{ + /* simple SRC_ALPHA, ONE_MINUS_SRC_ALPHA blending */ + vector float fbc00 = spu_unpack_color(spu.ctile.ui[ity][itx]); + vector float fbc01 = spu_unpack_color(spu.ctile.ui[ity][itx+1]); + vector float fbc10 = spu_unpack_color(spu.ctile.ui[ity+1][itx]); + vector float fbc11 = spu_unpack_color(spu.ctile.ui[ity+1][itx+1]); + + vector float alpha00 = spu_splats(spu_extract(colors[0], 3)); + vector float alpha01 = spu_splats(spu_extract(colors[1], 3)); + vector float alpha10 = spu_splats(spu_extract(colors[2], 3)); + vector float alpha11 = spu_splats(spu_extract(colors[3], 3)); + + vector float one_minus_alpha00 = spu_sub(spu_splats(1.0f), alpha00); + vector float one_minus_alpha01 = spu_sub(spu_splats(1.0f), alpha01); + vector float one_minus_alpha10 = spu_sub(spu_splats(1.0f), alpha10); + vector float one_minus_alpha11 = spu_sub(spu_splats(1.0f), alpha11); + + colors[0] = spu_add(spu_mul(colors[0], alpha00), + spu_mul(fbc00, one_minus_alpha00)); + colors[1] = spu_add(spu_mul(colors[1], alpha01), + spu_mul(fbc01, one_minus_alpha01)); + colors[2] = spu_add(spu_mul(colors[2], alpha10), + spu_mul(fbc10, one_minus_alpha10)); + colors[3] = spu_add(spu_mul(colors[3], alpha11), + spu_mul(fbc11, one_minus_alpha11)); +} + diff --git a/src/gallium/drivers/cell/spu/spu_blend.h b/src/gallium/drivers/cell/spu/spu_blend.h new file mode 100644 index 0000000000..2b594b578b --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_blend.h @@ -0,0 +1,37 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef SPU_BLEND_H +#define SPU_BLEND_H + + +extern void +blend_quad(uint itx, uint ity, vector float colors[4]); + + +#endif /* SPU_BLEND_H */ diff --git a/src/gallium/drivers/cell/spu/spu_colorpack.h b/src/gallium/drivers/cell/spu/spu_colorpack.h new file mode 100644 index 0000000000..e9fee8a3a6 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_colorpack.h @@ -0,0 +1,110 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + + +#ifndef SPU_COLORPACK_H +#define SPU_COLORPACK_H + + +#include + + +static INLINE unsigned int +spu_pack_R8G8B8A8(vector float rgba) +{ + vector unsigned int out = spu_convtu(rgba, 32); + + out = spu_shuffle(out, out, ((vector unsigned char) { + 0, 4, 8, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }) ); + + return spu_extract(out, 0); +} + + +static INLINE unsigned int +spu_pack_A8R8G8B8(vector float rgba) +{ + vector unsigned int out = spu_convtu(rgba, 32); + out = spu_shuffle(out, out, ((vector unsigned char) { + 12, 0, 4, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}) ); + return spu_extract(out, 0); +} + + +static INLINE unsigned int +spu_pack_B8G8R8A8(vector float rgba) +{ + vector unsigned int out = spu_convtu(rgba, 32); + out = spu_shuffle(out, out, ((vector unsigned char) { + 8, 4, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}) ); + return spu_extract(out, 0); +} + + +static INLINE unsigned int +spu_pack_color_shuffle(vector float rgba, vector unsigned char shuffle) +{ + vector unsigned int out = spu_convtu(rgba, 32); + out = spu_shuffle(out, out, shuffle); + return spu_extract(out, 0); +} + + +static INLINE vector float +spu_unpack_color(uint color) +{ + vector unsigned int color_u4 = spu_splats(color); + color_u4 = spu_shuffle(color_u4, color_u4, + ((vector unsigned char) { + 0, 0, 0, 0, + 5, 5, 5, 5, + 10, 10, 10, 10, + 15, 15, 15, 15}) ); + return spu_convtf(color_u4, 32); +} + + +static INLINE vector float +spu_unpack_A8R8G8B8(uint color) +{ + vector unsigned int color_u4 = spu_splats(color); + color_u4 = spu_shuffle(color_u4, color_u4, + ((vector unsigned char) { + 5, 5, 5, 5, + 10, 10, 10, 10, + 15, 15, 15, 15, + 0, 0, 0, 0}) ); + + return spu_convtf(color_u4, 32); +} + + +#endif /* SPU_COLORPACK_H */ diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c new file mode 100644 index 0000000000..e51008b9b3 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -0,0 +1,1948 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * TGSI interpretor/executor. + * + * Flow control information: + * + * Since we operate on 'quads' (4 pixels or 4 vertices in parallel) + * flow control statements (IF/ELSE/ENDIF, LOOP/ENDLOOP) require special + * care since a condition may be true for some quad components but false + * for other components. + * + * We basically execute all statements (even if they're in the part of + * an IF/ELSE clause that's "not taken") and use a special mask to + * control writing to destination registers. This is the ExecMask. + * See store_dest(). + * + * The ExecMask is computed from three other masks (CondMask, LoopMask and + * ContMask) which are controlled by the flow control instructions (namely: + * (IF/ELSE/ENDIF, LOOP/ENDLOOP and CONT). + * + * + * Authors: + * Michal Krol + * Brian Paul + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/tgsi/util/tgsi_parse.h" +#include "pipe/tgsi/util/tgsi_util.h" +#include "spu_exec.h" +#include "spu_main.h" +#include "spu_vertex_shader.h" + +#define TILE_TOP_LEFT 0 +#define TILE_TOP_RIGHT 1 +#define TILE_BOTTOM_LEFT 2 +#define TILE_BOTTOM_RIGHT 3 + +/* + * Shorthand locations of various utility registers (_I = Index, _C = Channel) + */ +#define TEMP_0_I TGSI_EXEC_TEMP_00000000_I +#define TEMP_0_C TGSI_EXEC_TEMP_00000000_C +#define TEMP_7F_I TGSI_EXEC_TEMP_7FFFFFFF_I +#define TEMP_7F_C TGSI_EXEC_TEMP_7FFFFFFF_C +#define TEMP_80_I TGSI_EXEC_TEMP_80000000_I +#define TEMP_80_C TGSI_EXEC_TEMP_80000000_C +#define TEMP_FF_I TGSI_EXEC_TEMP_FFFFFFFF_I +#define TEMP_FF_C TGSI_EXEC_TEMP_FFFFFFFF_C +#define TEMP_1_I TGSI_EXEC_TEMP_ONE_I +#define TEMP_1_C TGSI_EXEC_TEMP_ONE_C +#define TEMP_2_I TGSI_EXEC_TEMP_TWO_I +#define TEMP_2_C TGSI_EXEC_TEMP_TWO_C +#define TEMP_128_I TGSI_EXEC_TEMP_128_I +#define TEMP_128_C TGSI_EXEC_TEMP_128_C +#define TEMP_M128_I TGSI_EXEC_TEMP_MINUS_128_I +#define TEMP_M128_C TGSI_EXEC_TEMP_MINUS_128_C +#define TEMP_KILMASK_I TGSI_EXEC_TEMP_KILMASK_I +#define TEMP_KILMASK_C TGSI_EXEC_TEMP_KILMASK_C +#define TEMP_OUTPUT_I TGSI_EXEC_TEMP_OUTPUT_I +#define TEMP_OUTPUT_C TGSI_EXEC_TEMP_OUTPUT_C +#define TEMP_PRIMITIVE_I TGSI_EXEC_TEMP_PRIMITIVE_I +#define TEMP_PRIMITIVE_C TGSI_EXEC_TEMP_PRIMITIVE_C +#define TEMP_R0 TGSI_EXEC_TEMP_R0 + +#define FOR_EACH_CHANNEL(CHAN)\ + for (CHAN = 0; CHAN < 4; CHAN++) + +#define IS_CHANNEL_ENABLED(INST, CHAN)\ + ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) + +#define IS_CHANNEL_ENABLED2(INST, CHAN)\ + ((INST).FullDstRegisters[1].DstRegister.WriteMask & (1 << (CHAN))) + +#define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\ + FOR_EACH_CHANNEL( CHAN )\ + if (IS_CHANNEL_ENABLED( INST, CHAN )) + +#define FOR_EACH_ENABLED_CHANNEL2(INST, CHAN)\ + FOR_EACH_CHANNEL( CHAN )\ + if (IS_CHANNEL_ENABLED2( INST, CHAN )) + + +/** The execution mask depends on the conditional mask and the loop mask */ +#define UPDATE_EXEC_MASK(MACH) \ + MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask + + +#define CHAN_X 0 +#define CHAN_Y 1 +#define CHAN_Z 2 +#define CHAN_W 3 + + + +/** + * Initialize machine state by expanding tokens to full instructions, + * allocating temporary storage, setting up constants, etc. + * After this, we can call spu_exec_machine_run() many times. + */ +void +spu_exec_machine_init(struct spu_exec_machine *mach, + uint numSamplers, + struct spu_sampler *samplers, + unsigned processor) +{ + qword zero; + qword not_zero; + uint i; + + mach->Samplers = samplers; + mach->Processor = processor; + mach->Addrs = &mach->Temps[TGSI_EXEC_NUM_TEMPS]; + + zero = si_xor(zero, zero); + not_zero = si_xori(zero, 0xff); + + /* Setup constants. */ + mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].q = zero; + mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].q = not_zero; + mach->Temps[TEMP_7F_I].xyzw[TEMP_7F_C].q = si_shli(not_zero, -1); + mach->Temps[TEMP_80_I].xyzw[TEMP_80_C].q = si_shli(not_zero, 31); + + mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q = (qword) spu_splats(1.0f); + mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].q = (qword) spu_splats(2.0f); + mach->Temps[TEMP_128_I].xyzw[TEMP_128_C].q = (qword) spu_splats(128.0f); + mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C].q = (qword) spu_splats(-128.0f); +} + + +static INLINE qword +micro_abs(qword src) +{ + return si_rotmi(si_shli(src, 1), -1); +} + +static INLINE qword +micro_ceil(qword src) +{ + return (qword) _ceilf4((vec_float4) src); +} + +static INLINE qword +micro_cos(qword src) +{ + return (qword) _cosf4((vec_float4) src); +} + +static const qword br_shuf = { + TILE_BOTTOM_RIGHT + 0, TILE_BOTTOM_RIGHT + 1, + TILE_BOTTOM_RIGHT + 2, TILE_BOTTOM_RIGHT + 3, + TILE_BOTTOM_RIGHT + 0, TILE_BOTTOM_RIGHT + 1, + TILE_BOTTOM_RIGHT + 2, TILE_BOTTOM_RIGHT + 3, + TILE_BOTTOM_RIGHT + 0, TILE_BOTTOM_RIGHT + 1, + TILE_BOTTOM_RIGHT + 2, TILE_BOTTOM_RIGHT + 3, + TILE_BOTTOM_RIGHT + 0, TILE_BOTTOM_RIGHT + 1, + TILE_BOTTOM_RIGHT + 2, TILE_BOTTOM_RIGHT + 3, +}; + +static const qword bl_shuf = { + TILE_BOTTOM_LEFT + 0, TILE_BOTTOM_LEFT + 1, + TILE_BOTTOM_LEFT + 2, TILE_BOTTOM_LEFT + 3, + TILE_BOTTOM_LEFT + 0, TILE_BOTTOM_LEFT + 1, + TILE_BOTTOM_LEFT + 2, TILE_BOTTOM_LEFT + 3, + TILE_BOTTOM_LEFT + 0, TILE_BOTTOM_LEFT + 1, + TILE_BOTTOM_LEFT + 2, TILE_BOTTOM_LEFT + 3, + TILE_BOTTOM_LEFT + 0, TILE_BOTTOM_LEFT + 1, + TILE_BOTTOM_LEFT + 2, TILE_BOTTOM_LEFT + 3, +}; + +static const qword tl_shuf = { + TILE_TOP_LEFT + 0, TILE_TOP_LEFT + 1, + TILE_TOP_LEFT + 2, TILE_TOP_LEFT + 3, + TILE_TOP_LEFT + 0, TILE_TOP_LEFT + 1, + TILE_TOP_LEFT + 2, TILE_TOP_LEFT + 3, + TILE_TOP_LEFT + 0, TILE_TOP_LEFT + 1, + TILE_TOP_LEFT + 2, TILE_TOP_LEFT + 3, + TILE_TOP_LEFT + 0, TILE_TOP_LEFT + 1, + TILE_TOP_LEFT + 2, TILE_TOP_LEFT + 3, +}; + +static qword +micro_ddx(qword src) +{ + qword bottom_right = si_shufb(src, src, br_shuf); + qword bottom_left = si_shufb(src, src, bl_shuf); + + return si_fs(bottom_right, bottom_left); +} + +static qword +micro_ddy(qword src) +{ + qword top_left = si_shufb(src, src, tl_shuf); + qword bottom_left = si_shufb(src, src, bl_shuf); + + return si_fs(top_left, bottom_left); +} + +static INLINE qword +micro_div(qword src0, qword src1) +{ + return (qword) _divf4((vec_float4) src0, (vec_float4) src1); +} + +static qword +micro_flr(qword src) +{ + return (qword) _floorf4((vec_float4) src); +} + +static qword +micro_frc(qword src) +{ + return si_fs(src, (qword) _floorf4((vec_float4) src)); +} + +static INLINE qword +micro_ge(qword src0, qword src1) +{ + return si_or(si_fceq(src0, src1), si_fcgt(src0, src1)); +} + +static qword +micro_lg2(qword src) +{ + return (qword) _log2f4((vec_float4) src); +} + +static INLINE qword +micro_lt(qword src0, qword src1) +{ + const qword tmp = si_or(si_fceq(src0, src1), si_fcgt(src0, src1)); + + return si_xori(tmp, 0xff); +} + +static INLINE qword +micro_max(qword src0, qword src1) +{ + return si_selb(src1, src0, si_fcgt(src0, src1)); +} + +static INLINE qword +micro_min(qword src0, qword src1) +{ + return si_selb(src0, src1, si_fcgt(src0, src1)); +} + +static qword +micro_neg(qword src) +{ + return si_xor(src, (qword) spu_splats(0x80000000)); +} + +static qword +micro_set_sign(qword src) +{ + return si_or(src, (qword) spu_splats(0x80000000)); +} + +static qword +micro_pow(qword src0, qword src1) +{ + return (qword) _powf4((vec_float4) src0, (vec_float4) src1); +} + +static qword +micro_rnd(qword src) +{ + const qword half = (qword) spu_splats(0.5f); + + /* May be able to use _roundf4. There may be some difference, though. + */ + return (qword) _floorf4((vec_float4) si_fa(src, half)); +} + +static INLINE qword +micro_ishr(qword src0, qword src1) +{ + return si_rotma(src0, si_sfi(src1, 0)); +} + +static qword +micro_trunc(qword src) +{ + return (qword) _truncf4((vec_float4) src); +} + +static qword +micro_sin(qword src) +{ + return (qword) _sinf4((vec_float4) src); +} + +static INLINE qword +micro_sqrt(qword src) +{ + return (qword) _sqrtf4((vec_float4) src); +} + +static void +fetch_src_file_channel( + const struct spu_exec_machine *mach, + const uint file, + const uint swizzle, + const union spu_exec_channel *index, + union spu_exec_channel *chan ) +{ + switch( swizzle ) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + switch( file ) { + case TGSI_FILE_CONSTANT: { + unsigned char buffer[32] ALIGN16_ATTRIB; + unsigned i; + + for (i = 0; i < 4; i++) { + const float *ptr = mach->Consts[index->i[i]]; + const uint64_t addr = (uint64_t)(uintptr_t) ptr; + const unsigned size = ((addr & 0x0f) == 0) ? 16 : 32; + + mfc_get(buffer, addr & ~0x0f, size, TAG_VERTEX_BUFFER, 0, 0); + wait_on_mask(1 << TAG_VERTEX_BUFFER); + + (void) memcpy(& chan->f[i], &buffer[(addr & 0x0f) + + (sizeof(float) * swizzle)], sizeof(float)); + } + break; + } + + case TGSI_FILE_INPUT: + chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Inputs[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_TEMPORARY: + chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Temps[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_IMMEDIATE: + assert( index->i[0] < (int) mach->ImmLimit ); + assert( index->i[1] < (int) mach->ImmLimit ); + assert( index->i[2] < (int) mach->ImmLimit ); + assert( index->i[3] < (int) mach->ImmLimit ); + + chan->f[0] = mach->Imms[index->i[0]][swizzle]; + chan->f[1] = mach->Imms[index->i[1]][swizzle]; + chan->f[2] = mach->Imms[index->i[2]][swizzle]; + chan->f[3] = mach->Imms[index->i[3]][swizzle]; + break; + + case TGSI_FILE_ADDRESS: + chan->u[0] = mach->Addrs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Addrs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Addrs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Addrs[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_OUTPUT: + /* vertex/fragment output vars can be read too */ + chan->u[0] = mach->Outputs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Outputs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Outputs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Outputs[index->i[3]].xyzw[swizzle].u[3]; + break; + + default: + assert( 0 ); + } + break; + + case TGSI_EXTSWIZZLE_ZERO: + *chan = mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]; + break; + + case TGSI_EXTSWIZZLE_ONE: + *chan = mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]; + break; + + default: + assert( 0 ); + } +} + +static void +fetch_source( + const struct spu_exec_machine *mach, + union spu_exec_channel *chan, + const struct tgsi_full_src_register *reg, + const uint chan_index ) +{ + union spu_exec_channel index; + uint swizzle; + + index.i[0] = + index.i[1] = + index.i[2] = + index.i[3] = reg->SrcRegister.Index; + + if (reg->SrcRegister.Indirect) { + union spu_exec_channel index2; + union spu_exec_channel indir_index; + + index2.i[0] = + index2.i[1] = + index2.i[2] = + index2.i[3] = reg->SrcRegisterInd.Index; + + swizzle = tgsi_util_get_src_register_swizzle(®->SrcRegisterInd, + CHAN_X); + fetch_src_file_channel( + mach, + reg->SrcRegisterInd.File, + swizzle, + &index2, + &indir_index ); + + index.q = si_a(index.q, indir_index.q); + } + + if( reg->SrcRegister.Dimension ) { + switch( reg->SrcRegister.File ) { + case TGSI_FILE_INPUT: + index.q = si_mpyi(index.q, 17); + break; + case TGSI_FILE_CONSTANT: + index.q = si_shli(index.q, 12); + break; + default: + assert( 0 ); + } + + index.i[0] += reg->SrcRegisterDim.Index; + index.i[1] += reg->SrcRegisterDim.Index; + index.i[2] += reg->SrcRegisterDim.Index; + index.i[3] += reg->SrcRegisterDim.Index; + + if (reg->SrcRegisterDim.Indirect) { + union spu_exec_channel index2; + union spu_exec_channel indir_index; + + index2.i[0] = + index2.i[1] = + index2.i[2] = + index2.i[3] = reg->SrcRegisterDimInd.Index; + + swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterDimInd, CHAN_X ); + fetch_src_file_channel( + mach, + reg->SrcRegisterDimInd.File, + swizzle, + &index2, + &indir_index ); + + index.q = si_a(index.q, indir_index.q); + } + } + + swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); + fetch_src_file_channel( + mach, + reg->SrcRegister.File, + swizzle, + &index, + chan ); + + switch (tgsi_util_get_full_src_register_sign_mode( reg, chan_index )) { + case TGSI_UTIL_SIGN_CLEAR: + chan->q = micro_abs(chan->q); + break; + + case TGSI_UTIL_SIGN_SET: + chan->q = micro_set_sign(chan->q); + break; + + case TGSI_UTIL_SIGN_TOGGLE: + chan->q = micro_neg(chan->q); + break; + + case TGSI_UTIL_SIGN_KEEP: + break; + } + + if (reg->SrcRegisterExtMod.Complement) { + chan->q = si_fs(mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q, chan->q); + } +} + +static void +store_dest( + struct spu_exec_machine *mach, + const union spu_exec_channel *chan, + const struct tgsi_full_dst_register *reg, + const struct tgsi_full_instruction *inst, + uint chan_index ) +{ + union spu_exec_channel *dst; + + switch( reg->DstRegister.File ) { + case TGSI_FILE_NULL: + return; + + case TGSI_FILE_OUTPUT: + dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] + + reg->DstRegister.Index].xyzw[chan_index]; + break; + + case TGSI_FILE_TEMPORARY: + dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index]; + break; + + case TGSI_FILE_ADDRESS: + dst = &mach->Addrs[reg->DstRegister.Index].xyzw[chan_index]; + break; + + default: + assert( 0 ); + return; + } + + switch (inst->Instruction.Saturate) + { + case TGSI_SAT_NONE: + if (mach->ExecMask & 0x1) + dst->i[0] = chan->i[0]; + if (mach->ExecMask & 0x2) + dst->i[1] = chan->i[1]; + if (mach->ExecMask & 0x4) + dst->i[2] = chan->i[2]; + if (mach->ExecMask & 0x8) + dst->i[3] = chan->i[3]; + break; + + case TGSI_SAT_ZERO_ONE: + /* XXX need to obey ExecMask here */ + dst->q = micro_max(chan->q, mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].q); + dst->q = micro_min(dst->q, mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q); + break; + + case TGSI_SAT_MINUS_PLUS_ONE: + assert( 0 ); + break; + + default: + assert( 0 ); + } +} + +#define FETCH(VAL,INDEX,CHAN)\ + fetch_source (mach, VAL, &inst->FullSrcRegisters[INDEX], CHAN) + +#define STORE(VAL,INDEX,CHAN)\ + store_dest (mach, VAL, &inst->FullDstRegisters[INDEX], inst, CHAN ) + + +/** + * Execute ARB-style KIL which is predicated by a src register. + * Kill fragment if any of the four values is less than zero. + */ +static void +exec_kilp(struct spu_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + uint uniquemask; + uint chan_index; + uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ + union spu_exec_channel r[1]; + + /* This mask stores component bits that were already tested. Note that + * we test if the value is less than zero, so 1.0 and 0.0 need not to be + * tested. */ + uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); + + for (chan_index = 0; chan_index < 4; chan_index++) + { + uint swizzle; + uint i; + + /* unswizzle channel */ + swizzle = tgsi_util_get_full_src_register_extswizzle ( + &inst->FullSrcRegisters[0], + chan_index); + + /* check if the component has not been already tested */ + if (uniquemask & (1 << swizzle)) + continue; + uniquemask |= 1 << swizzle; + + FETCH(&r[0], 0, chan_index); + for (i = 0; i < 4; i++) + if (r[0].f[i] < 0.0f) + kilmask |= 1 << i; + } + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; +} + + +/* + * Fetch a texel using STR texture coordinates. + */ +static void +fetch_texel( struct spu_sampler *sampler, + const union spu_exec_channel *s, + const union spu_exec_channel *t, + const union spu_exec_channel *p, + float lodbias, /* XXX should be float[4] */ + union spu_exec_channel *r, + union spu_exec_channel *g, + union spu_exec_channel *b, + union spu_exec_channel *a ) +{ + qword rgba[4]; + qword out[4]; + + sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, (float *) rgba); + + _transpose_matrix4x4(out, rgba); + r->q = out[0]; + g->q = out[1]; + b->q = out[2]; + a->q = out[3]; +} + + +static void +exec_tex(struct spu_exec_machine *mach, + const struct tgsi_full_instruction *inst, + boolean biasLod) +{ + const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; + union spu_exec_channel r[8]; + uint chan_index; + float lodBias; + + /* printf("Sampler %u unit %u\n", sampler, unit); */ + + switch (inst->InstructionExtTexture.Texture) { + case TGSI_TEXTURE_1D: + + FETCH(&r[0], 0, CHAN_X); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[1], 0, CHAN_W); + r[0].q = micro_div(r[0].q, r[1].q); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } + + if (biasLod) { + FETCH(&r[1], 0, CHAN_W); + lodBias = r[2].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], NULL, NULL, lodBias, /* S, T, P, BIAS */ + &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */ + break; + + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_RECT: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[3], 0, CHAN_W); + r[0].q = micro_div(r[0].q, r[3].q); + r[1].q = micro_div(r[1].q, r[3].q); + r[2].q = micro_div(r[2].q, r[3].q); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } + + if (biasLod) { + FETCH(&r[3], 0, CHAN_W); + lodBias = r[3].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], &r[1], &r[2], lodBias, /* inputs */ + &r[0], &r[1], &r[2], &r[3]); /* outputs */ + break; + + case TGSI_TEXTURE_3D: + case TGSI_TEXTURE_CUBE: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[3], 0, CHAN_W); + r[0].q = micro_div(r[0].q, r[3].q); + r[1].q = micro_div(r[1].q, r[3].q); + r[2].q = micro_div(r[2].q, r[3].q); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } + + if (biasLod) { + FETCH(&r[3], 0, CHAN_W); + lodBias = r[3].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], &r[1], &r[2], lodBias, + &r[0], &r[1], &r[2], &r[3]); + break; + + default: + assert (0); + } + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[chan_index], 0, chan_index ); + } +} + + + +static void +constant_interpolation( + struct spu_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + mach->Inputs[attrib].xyzw[chan].f[i] = mach->InterpCoefs[attrib].a0[chan]; + } +} + +static void +linear_interpolation( + struct spu_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + const float x = mach->QuadPos.xyzw[0].f[0]; + const float y = mach->QuadPos.xyzw[1].f[0]; + const float dadx = mach->InterpCoefs[attrib].dadx[chan]; + const float dady = mach->InterpCoefs[attrib].dady[chan]; + const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; + mach->Inputs[attrib].xyzw[chan].f[0] = a0; + mach->Inputs[attrib].xyzw[chan].f[1] = a0 + dadx; + mach->Inputs[attrib].xyzw[chan].f[2] = a0 + dady; + mach->Inputs[attrib].xyzw[chan].f[3] = a0 + dadx + dady; +} + +static void +perspective_interpolation( + struct spu_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + const float x = mach->QuadPos.xyzw[0].f[0]; + const float y = mach->QuadPos.xyzw[1].f[0]; + const float dadx = mach->InterpCoefs[attrib].dadx[chan]; + const float dady = mach->InterpCoefs[attrib].dady[chan]; + const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; + const float *w = mach->QuadPos.xyzw[3].f; + /* divide by W here */ + mach->Inputs[attrib].xyzw[chan].f[0] = a0 / w[0]; + mach->Inputs[attrib].xyzw[chan].f[1] = (a0 + dadx) / w[1]; + mach->Inputs[attrib].xyzw[chan].f[2] = (a0 + dady) / w[2]; + mach->Inputs[attrib].xyzw[chan].f[3] = (a0 + dadx + dady) / w[3]; +} + + +typedef void (* interpolation_func)( + struct spu_exec_machine *mach, + unsigned attrib, + unsigned chan ); + +static void +exec_declaration(struct spu_exec_machine *mach, + const struct tgsi_full_declaration *decl) +{ + if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { + if( decl->Declaration.File == TGSI_FILE_INPUT ) { + unsigned first, last, mask; + interpolation_func interp; + + assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); + + first = decl->u.DeclarationRange.First; + last = decl->u.DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + switch( decl->Interpolation.Interpolate ) { + case TGSI_INTERPOLATE_CONSTANT: + interp = constant_interpolation; + break; + + case TGSI_INTERPOLATE_LINEAR: + interp = linear_interpolation; + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + interp = perspective_interpolation; + break; + + default: + assert( 0 ); + } + + if( mask == TGSI_WRITEMASK_XYZW ) { + unsigned i, j; + + for( i = first; i <= last; i++ ) { + for( j = 0; j < NUM_CHANNELS; j++ ) { + interp( mach, i, j ); + } + } + } + else { + unsigned i, j; + + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + for( i = first; i <= last; i++ ) { + interp( mach, i, j ); + } + } + } + } + } + } +} + +static void +exec_instruction( + struct spu_exec_machine *mach, + const struct tgsi_full_instruction *inst, + int *pc ) +{ + uint chan_index; + union spu_exec_channel r[8]; + + (*pc)++; + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + r[0].q = si_cflts(r[0].q, 0); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOV: + /* TGSI_OPCODE_SWZ */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_LIT: + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y ) || IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[0], 0, CHAN_X ); + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + r[0].q = micro_max(r[0].q, mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].q); + STORE( &r[0], 0, CHAN_Y ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[1], 0, CHAN_Y ); + r[1].q = micro_max(r[1].q, mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].q); + + FETCH( &r[2], 0, CHAN_W ); + r[2].q = micro_min(r[2].q, mach->Temps[TEMP_128_I].xyzw[TEMP_128_C].q); + r[2].q = micro_max(r[2].q, mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C].q); + r[1].q = micro_pow(r[1].q, r[2].q); + + /* r0 = (r0 > 0.0) ? r1 : 0.0 + */ + r[0].q = si_fcgt(r[0].q, mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].q); + r[0].q = si_selb(mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].q, r[1].q, + r[0].q); + STORE( &r[0], 0, CHAN_Z ); + } + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_RCP: + /* TGSI_OPCODE_RECIP */ + FETCH( &r[0], 0, CHAN_X ); + r[0].q = micro_div(mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q, r[0].q); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_RSQ: + /* TGSI_OPCODE_RECIPSQRT */ + FETCH( &r[0], 0, CHAN_X ); + r[0].q = micro_sqrt(r[0].q); + r[0].q = micro_div(mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q, r[0].q); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXP: + assert (0); + break; + + case TGSI_OPCODE_LOG: + assert (0); + break; + + case TGSI_OPCODE_MUL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + r[0].q = si_fm(r[0].q, r[1].q); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_ADD: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + r[0].q = si_fa(r[0].q, r[1].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP3: + /* TGSI_OPCODE_DOT3 */ + FETCH( &r[0], 0, CHAN_X ); + FETCH( &r[1], 1, CHAN_X ); + r[0].q = si_fm(r[0].q, r[1].q); + + FETCH( &r[1], 0, CHAN_Y ); + FETCH( &r[2], 1, CHAN_Y ); + r[0].q = si_fma(r[1].q, r[2].q, r[0].q); + + + FETCH( &r[1], 0, CHAN_Z ); + FETCH( &r[2], 1, CHAN_Z ); + r[0].q = si_fma(r[1].q, r[2].q, r[0].q); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP4: + /* TGSI_OPCODE_DOT4 */ + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + r[0].q = si_fm(r[0].q, r[1].q); + + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 1, CHAN_Y); + + r[0].q = si_fma(r[1].q, r[2].q, r[0].q); + + FETCH(&r[1], 0, CHAN_Z); + FETCH(&r[2], 1, CHAN_Z); + + r[0].q = si_fma(r[1].q, r[2].q, r[0].q); + + FETCH(&r[1], 0, CHAN_W); + FETCH(&r[2], 1, CHAN_W); + + r[0].q = si_fma(r[1].q, r[2].q, r[0].q); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DST: + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + FETCH( &r[0], 0, CHAN_Y ); + FETCH( &r[1], 1, CHAN_Y); + r[0].q = si_fm(r[0].q, r[1].q); + STORE( &r[0], 0, CHAN_Y ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[0], 0, CHAN_Z ); + STORE( &r[0], 0, CHAN_Z ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + FETCH( &r[0], 1, CHAN_W ); + STORE( &r[0], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MIN: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + r[0].q = micro_min(r[0].q, r[1].q); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_MAX: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + r[0].q = micro_max(r[0].q, r[1].q); + + STORE(&r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLT: + /* TGSI_OPCODE_SETLT */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + + r[0].q = micro_ge(r[0].q, r[1].q); + r[0].q = si_xori(r[0].q, 0xff); + + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SGE: + /* TGSI_OPCODE_SETGE */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + r[0].q = micro_ge(r[0].q, r[1].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MAD: + /* TGSI_OPCODE_MADD */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + FETCH( &r[2], 2, chan_index ); + r[0].q = si_fma(r[0].q, r[1].q, r[2].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SUB: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + r[0].q = si_fs(r[0].q, r[1].q); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_LERP: + /* TGSI_OPCODE_LRP */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + FETCH(&r[2], 2, chan_index); + + r[1].q = si_fs(r[1].q, r[2].q); + r[0].q = si_fma(r[0].q, r[1].q, r[2].q); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_CND: + assert (0); + break; + + case TGSI_OPCODE_CND0: + assert (0); + break; + + case TGSI_OPCODE_DOT2ADD: + /* TGSI_OPCODE_DP2A */ + assert (0); + break; + + case TGSI_OPCODE_INDEX: + assert (0); + break; + + case TGSI_OPCODE_NEGATE: + assert (0); + break; + + case TGSI_OPCODE_FRAC: + /* TGSI_OPCODE_FRC */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + r[0].q = micro_frc(r[0].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_CLAMP: + assert (0); + break; + + case TGSI_OPCODE_FLOOR: + /* TGSI_OPCODE_FLR */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + r[0].q = micro_flr(r[0].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_ROUND: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + r[0].q = micro_rnd(r[0].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXPBASE2: + /* TGSI_OPCODE_EX2 */ + FETCH(&r[0], 0, CHAN_X); + + r[0].q = micro_pow(mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].q, r[0].q); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_LOGBASE2: + /* TGSI_OPCODE_LG2 */ + FETCH( &r[0], 0, CHAN_X ); + r[0].q = micro_lg2(r[0].q); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_POWER: + /* TGSI_OPCODE_POW */ + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + r[0].q = micro_pow(r[0].q, r[1].q); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_CROSSPRODUCT: + /* TGSI_OPCODE_XPD */ + FETCH(&r[0], 0, CHAN_Y); + FETCH(&r[1], 1, CHAN_Z); + FETCH(&r[3], 0, CHAN_Z); + FETCH(&r[4], 1, CHAN_Y); + + /* r2 = (r0 * r1) - (r3 * r5) + */ + r[2].q = si_fm(r[3].q, r[5].q); + r[2].q = si_fms(r[0].q, r[1].q, r[2].q); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &r[2], 0, CHAN_X ); + } + + FETCH(&r[2], 1, CHAN_X); + FETCH(&r[5], 0, CHAN_X); + + /* r3 = (r3 * r2) - (r1 * r5) + */ + r[1].q = si_fm(r[1].q, r[5].q); + r[3].q = si_fms(r[3].q, r[2].q, r[1].q); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + STORE( &r[3], 0, CHAN_Y ); + } + + /* r5 = (r5 * r4) - (r0 * r2) + */ + r[0].q = si_fm(r[0].q, r[2].q); + r[5].q = si_fms(r[5].q, r[4].q, r[0].q); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + STORE( &r[5], 0, CHAN_Z ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MULTIPLYMATRIX: + assert (0); + break; + + case TGSI_OPCODE_ABS: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + + r[0].q = micro_abs(r[0].q); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_RCC: + assert (0); + break; + + case TGSI_OPCODE_DPH: + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + r[0].q = si_fm(r[0].q, r[1].q); + + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 1, CHAN_Y); + + r[0].q = si_fma(r[1].q, r[2].q, r[0].q); + + FETCH(&r[1], 0, CHAN_Z); + FETCH(&r[2], 1, CHAN_Z); + + r[0].q = si_fma(r[1].q, r[2].q, r[0].q); + + FETCH(&r[1], 1, CHAN_W); + + r[0].q = si_fa(r[0].q, r[1].q); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_COS: + FETCH(&r[0], 0, CHAN_X); + + r[0].q = micro_cos(r[0].q); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDX: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + r[0].q = micro_ddx(r[0].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDY: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + r[0].q = micro_ddy(r[0].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_KILP: + exec_kilp (mach, inst); + break; + + case TGSI_OPCODE_KIL: + /* for enabled ExecMask bits, set the killed bit */ + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= mach->ExecMask; + break; + + case TGSI_OPCODE_PK2H: + assert (0); + break; + + case TGSI_OPCODE_PK2US: + assert (0); + break; + + case TGSI_OPCODE_PK4B: + assert (0); + break; + + case TGSI_OPCODE_PK4UB: + assert (0); + break; + + case TGSI_OPCODE_RFL: + assert (0); + break; + + case TGSI_OPCODE_SEQ: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + + r[0].q = si_fceq(r[0].q, r[1].q); + + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SFL: + assert (0); + break; + + case TGSI_OPCODE_SGT: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + r[0].q = si_fcgt(r[0].q, r[1].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SIN: + FETCH( &r[0], 0, CHAN_X ); + r[0].q = micro_sin(r[0].q); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLE: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + + r[0].q = si_fcgt(r[0].q, r[1].q); + r[0].q = si_xori(r[0].q, 0xff); + + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SNE: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + + r[0].q = si_fceq(r[0].q, r[1].q); + r[0].q = si_xori(r[0].q, 0xff); + + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_STR: + assert (0); + break; + + case TGSI_OPCODE_TEX: + /* simple texture lookup */ + /* src[0] = texcoord */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, FALSE); + break; + + case TGSI_OPCODE_TXB: + /* Texture lookup with lod bias */ + /* src[0] = texcoord (src[0].w = load bias) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, TRUE); + break; + + case TGSI_OPCODE_TXD: + /* Texture lookup with explict partial derivatives */ + /* src[0] = texcoord */ + /* src[1] = d[strq]/dx */ + /* src[2] = d[strq]/dy */ + /* src[3] = sampler unit */ + assert (0); + break; + + case TGSI_OPCODE_TXL: + /* Texture lookup with explit LOD */ + /* src[0] = texcoord (src[0].w = load bias) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, TRUE); + break; + + case TGSI_OPCODE_UP2H: + assert (0); + break; + + case TGSI_OPCODE_UP2US: + assert (0); + break; + + case TGSI_OPCODE_UP4B: + assert (0); + break; + + case TGSI_OPCODE_UP4UB: + assert (0); + break; + + case TGSI_OPCODE_X2D: + assert (0); + break; + + case TGSI_OPCODE_ARA: + assert (0); + break; + + case TGSI_OPCODE_ARR: + assert (0); + break; + + case TGSI_OPCODE_BRA: + assert (0); + break; + + case TGSI_OPCODE_CAL: + /* skip the call if no execution channels are enabled */ + if (mach->ExecMask) { + /* do the call */ + + /* push the Cond, Loop, Cont stacks */ + assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); + mach->CondStack[mach->CondStackTop++] = mach->CondMask; + assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; + assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->ContStack[mach->ContStackTop++] = mach->ContMask; + + assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING); + mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask; + + /* note that PC was already incremented above */ + mach->CallStack[mach->CallStackTop++] = *pc; + *pc = inst->InstructionExtLabel.Label; + } + break; + + case TGSI_OPCODE_RET: + mach->FuncMask &= ~mach->ExecMask; + UPDATE_EXEC_MASK(mach); + + if (mach->ExecMask == 0x0) { + /* really return now (otherwise, keep executing */ + + if (mach->CallStackTop == 0) { + /* returning from main() */ + *pc = -1; + return; + } + *pc = mach->CallStack[--mach->CallStackTop]; + + /* pop the Cond, Loop, Cont stacks */ + assert(mach->CondStackTop > 0); + mach->CondMask = mach->CondStack[--mach->CondStackTop]; + assert(mach->LoopStackTop > 0); + mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[--mach->ContStackTop]; + assert(mach->FuncStackTop > 0); + mach->FuncMask = mach->FuncStack[--mach->FuncStackTop]; + + UPDATE_EXEC_MASK(mach); + } + break; + + case TGSI_OPCODE_SSG: + assert (0); + break; + + case TGSI_OPCODE_CMP: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + FETCH(&r[2], 2, chan_index); + + /* r0 = (r0 < 0.0) ? r1 : r2 + */ + r[3].q = si_xor(r[3].q, r[3].q); + r[0].q = micro_lt(r[0].q, r[3].q); + r[0].q = si_selb(r[1].q, r[2].q, r[0].q); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_SCS: + if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) || IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + FETCH( &r[0], 0, CHAN_X ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) ) { + r[1].q = micro_cos(r[0].q); + STORE( &r[1], 0, CHAN_X ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + r[1].q = micro_sin(r[0].q); + STORE( &r[1], 0, CHAN_Y ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + STORE( &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], 0, CHAN_Z ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_W ) ) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_NRM: + assert (0); + break; + + case TGSI_OPCODE_DIV: + assert( 0 ); + break; + + case TGSI_OPCODE_DP2: + FETCH( &r[0], 0, CHAN_X ); + FETCH( &r[1], 1, CHAN_X ); + r[0].q = si_fm(r[0].q, r[1].q); + + FETCH( &r[1], 0, CHAN_Y ); + FETCH( &r[2], 1, CHAN_Y ); + r[0].q = si_fma(r[1].q, r[2].q, r[0].q); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_IF: + /* push CondMask */ + assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); + mach->CondStack[mach->CondStackTop++] = mach->CondMask; + FETCH( &r[0], 0, CHAN_X ); + /* update CondMask */ + if( ! r[0].u[0] ) { + mach->CondMask &= ~0x1; + } + if( ! r[0].u[1] ) { + mach->CondMask &= ~0x2; + } + if( ! r[0].u[2] ) { + mach->CondMask &= ~0x4; + } + if( ! r[0].u[3] ) { + mach->CondMask &= ~0x8; + } + UPDATE_EXEC_MASK(mach); + /* Todo: If CondMask==0, jump to ELSE */ + break; + + case TGSI_OPCODE_ELSE: + /* invert CondMask wrt previous mask */ + { + uint prevMask; + assert(mach->CondStackTop > 0); + prevMask = mach->CondStack[mach->CondStackTop - 1]; + mach->CondMask = ~mach->CondMask & prevMask; + UPDATE_EXEC_MASK(mach); + /* Todo: If CondMask==0, jump to ENDIF */ + } + break; + + case TGSI_OPCODE_ENDIF: + /* pop CondMask */ + assert(mach->CondStackTop > 0); + mach->CondMask = mach->CondStack[--mach->CondStackTop]; + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_END: + /* halt execution */ + *pc = -1; + break; + + case TGSI_OPCODE_REP: + assert (0); + break; + + case TGSI_OPCODE_ENDREP: + assert (0); + break; + + case TGSI_OPCODE_PUSHA: + assert (0); + break; + + case TGSI_OPCODE_POPA: + assert (0); + break; + + case TGSI_OPCODE_CEIL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + r[0].q = micro_ceil(r[0].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_I2F: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + r[0].q = si_csflt(r[0].q, 0); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_NOT: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + r[0].q = si_xorbi(r[0].q, 0xff); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_TRUNC: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + r[0].q = micro_trunc(r[0].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SHL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + + r[0].q = si_shl(r[0].q, r[1].q); + + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SHR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + r[0].q = micro_ishr(r[0].q, r[1].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_AND: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + r[0].q = si_and(r[0].q, r[1].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_OR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + r[0].q = si_or(r[0].q, r[1].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOD: + assert (0); + break; + + case TGSI_OPCODE_XOR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + r[0].q = si_xor(r[0].q, r[1].q); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SAD: + assert (0); + break; + + case TGSI_OPCODE_TXF: + assert (0); + break; + + case TGSI_OPCODE_TXQ: + assert (0); + break; + + case TGSI_OPCODE_EMIT: + mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16; + mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++; + break; + + case TGSI_OPCODE_ENDPRIM: + mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++; + mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0; + break; + + case TGSI_OPCODE_LOOP: + /* fall-through (for now) */ + case TGSI_OPCODE_BGNLOOP2: + /* push LoopMask and ContMasks */ + assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; + assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->ContStack[mach->ContStackTop++] = mach->ContMask; + break; + + case TGSI_OPCODE_ENDLOOP: + /* fall-through (for now at least) */ + case TGSI_OPCODE_ENDLOOP2: + /* Restore ContMask, but don't pop */ + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[mach->ContStackTop - 1]; + if (mach->LoopMask) { + /* repeat loop: jump to instruction just past BGNLOOP */ + *pc = inst->InstructionExtLabel.Label + 1; + } + else { + /* exit loop: pop LoopMask */ + assert(mach->LoopStackTop > 0); + mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; + /* pop ContMask */ + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[--mach->ContStackTop]; + } + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_BRK: + /* turn off loop channels for each enabled exec channel */ + mach->LoopMask &= ~mach->ExecMask; + /* Todo: if mach->LoopMask == 0, jump to end of loop */ + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_CONT: + /* turn off cont channels for each enabled exec channel */ + mach->ContMask &= ~mach->ExecMask; + /* Todo: if mach->LoopMask == 0, jump to end of loop */ + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_BGNSUB: + /* no-op */ + break; + + case TGSI_OPCODE_ENDSUB: + /* no-op */ + break; + + case TGSI_OPCODE_NOISE1: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE2: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE3: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE4: + assert( 0 ); + break; + + case TGSI_OPCODE_NOP: + break; + + default: + assert( 0 ); + } +} + + +/** + * Run TGSI interpreter. + * \return bitmask of "alive" quad components + */ +uint +spu_exec_machine_run( struct spu_exec_machine *mach ) +{ + uint i; + int pc = 0; + + mach->CondMask = 0xf; + mach->LoopMask = 0xf; + mach->ContMask = 0xf; + mach->FuncMask = 0xf; + mach->ExecMask = 0xf; + + mach->CondStackTop = 0; /* temporarily subvert this assertion */ + assert(mach->CondStackTop == 0); + assert(mach->LoopStackTop == 0); + assert(mach->ContStackTop == 0); + assert(mach->CallStackTop == 0); + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0; + mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0; + + if( mach->Processor == TGSI_PROCESSOR_GEOMETRY ) { + mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0] = 0; + mach->Primitives[0] = 0; + } + + + /* execute declarations (interpolants) */ + if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { + for (i = 0; i < mach->NumDeclarations; i++) { + uint8_t buffer[sizeof(struct tgsi_full_declaration) + 32] ALIGN16_ATTRIB; + struct tgsi_full_declaration decl; + unsigned long decl_addr = (unsigned long) (mach->Declarations+i); + unsigned size = ((sizeof(decl) + (decl_addr & 0x0f) + 0x0f) & ~0x0f); + + mfc_get(buffer, decl_addr & ~0x0f, size, TAG_INSTRUCTION_FETCH, 0, 0); + wait_on_mask(1 << TAG_INSTRUCTION_FETCH); + + memcpy(& decl, buffer + (decl_addr & 0x0f), sizeof(decl)); + exec_declaration( mach, &decl ); + } + } + + /* execute instructions, until pc is set to -1 */ + while (pc != -1) { + uint8_t buffer[sizeof(struct tgsi_full_instruction) + 32] ALIGN16_ATTRIB; + struct tgsi_full_instruction inst; + unsigned long inst_addr = (unsigned long) (mach->Instructions + pc); + unsigned size = ((sizeof(inst) + (inst_addr & 0x0f) + 0x0f) & ~0x0f); + + assert(pc < mach->NumInstructions); + mfc_get(buffer, inst_addr & ~0x0f, size, TAG_INSTRUCTION_FETCH, 0, 0); + wait_on_mask(1 << TAG_INSTRUCTION_FETCH); + + memcpy(& inst, buffer + (inst_addr & 0x0f), sizeof(inst)); + exec_instruction( mach, & inst, &pc ); + } + +#if 0 + /* we scale from floats in [0,1] to Zbuffer ints in sp_quad_depth_test.c */ + if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) { + /* + * Scale back depth component. + */ + for (i = 0; i < 4; i++) + mach->Outputs[0].xyzw[2].f[i] *= ctx->DrawBuffer->_DepthMaxF; + } +#endif + + return ~mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0]; +} + + diff --git a/src/gallium/drivers/cell/spu/spu_exec.h b/src/gallium/drivers/cell/spu/spu_exec.h new file mode 100644 index 0000000000..b4c7661ef6 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_exec.h @@ -0,0 +1,172 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#if !defined SPU_EXEC_H +#define SPU_EXEC_H + +#include "pipe/p_compiler.h" +#include "pipe/tgsi/exec/tgsi_exec.h" + +#if defined __cplusplus +extern "C" { +#endif + +/** + * Registers may be treated as float, signed int or unsigned int. + */ +union spu_exec_channel +{ + float f[QUAD_SIZE]; + int i[QUAD_SIZE]; + unsigned u[QUAD_SIZE]; + qword q; +}; + +/** + * A vector[RGBA] of channels[4 pixels] + */ +struct spu_exec_vector +{ + union spu_exec_channel xyzw[NUM_CHANNELS]; +}; + +/** + * For fragment programs, information for computing fragment input + * values from plane equation of the triangle/line. + */ +struct spu_interp_coef +{ + float a0[NUM_CHANNELS]; /* in an xyzw layout */ + float dadx[NUM_CHANNELS]; + float dady[NUM_CHANNELS]; +}; + + +struct softpipe_tile_cache; /**< Opaque to TGSI */ + +/** + * Information for sampling textures, which must be implemented + * by code outside the TGSI executor. + */ +struct spu_sampler +{ + const struct pipe_sampler_state *state; + struct pipe_texture *texture; + /** Get samples for four fragments in a quad */ + void (*get_samples)(struct spu_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]); + void *pipe; /*XXX temporary*/ + struct softpipe_tile_cache *cache; +}; + + +/** + * Run-time virtual machine state for executing TGSI shader. + */ +struct spu_exec_machine +{ + /* + * 32 program temporaries + * 4 internal temporaries + * 1 address + */ + struct spu_exec_vector Temps[TGSI_EXEC_NUM_TEMPS + + TGSI_EXEC_NUM_ADDRS + 1] + ALIGN16_ATTRIB; + + struct spu_exec_vector *Addrs; + + struct spu_sampler *Samplers; + + float Imms[TGSI_EXEC_NUM_IMMEDIATES][4]; + unsigned ImmLimit; + float (*Consts)[4]; + struct spu_exec_vector *Inputs; + struct spu_exec_vector *Outputs; + unsigned Processor; + + /* GEOMETRY processor only. */ + unsigned *Primitives; + + /* FRAGMENT processor only. */ + const struct spu_interp_coef *InterpCoefs; + struct spu_exec_vector QuadPos; + + /* Conditional execution masks */ + uint CondMask; /**< For IF/ELSE/ENDIF */ + uint LoopMask; /**< For BGNLOOP/ENDLOOP */ + uint ContMask; /**< For loop CONT statements */ + uint FuncMask; /**< For function calls */ + uint ExecMask; /**< = CondMask & LoopMask */ + + /** Condition mask stack (for nested conditionals) */ + uint CondStack[TGSI_EXEC_MAX_COND_NESTING]; + int CondStackTop; + + /** Loop mask stack (for nested loops) */ + uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING]; + int LoopStackTop; + + /** Loop continue mask stack (see comments in tgsi_exec.c) */ + uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING]; + int ContStackTop; + + /** Function execution mask stack (for executing subroutine code) */ + uint FuncStack[TGSI_EXEC_MAX_CALL_NESTING]; + int FuncStackTop; + + /** Function call stack for saving/restoring the program counter */ + uint CallStack[TGSI_EXEC_MAX_CALL_NESTING]; + int CallStackTop; + + struct tgsi_full_instruction *Instructions; + uint NumInstructions; + + struct tgsi_full_declaration *Declarations; + uint NumDeclarations; +}; + + +extern void +spu_exec_machine_init(struct spu_exec_machine *mach, + uint numSamplers, + struct spu_sampler *samplers, + unsigned processor); + +extern uint +spu_exec_machine_run( struct spu_exec_machine *mach ); + + +#if defined __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPU_EXEC_H */ diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c new file mode 100644 index 0000000000..e375197fe6 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -0,0 +1,567 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/* main() for Cell SPU code */ + + +#include +#include + +#include "spu_main.h" +#include "spu_render.h" +#include "spu_texture.h" +#include "spu_tile.h" +//#include "spu_test.h" +#include "spu_vertex_shader.h" +#include "pipe/cell/common.h" +#include "pipe/p_defines.h" + + +/* +helpful headers: +/usr/lib/gcc/spu/4.1.1/include/spu_mfcio.h +/opt/ibm/cell-sdk/prototype/sysroot/usr/include/libmisc.h +*/ + +boolean Debug = FALSE; + +struct spu_global spu; + +struct spu_vs_context draw; + +/** + * Tell the PPU that this SPU has finished copying a buffer to + * local store and that it may be reused by the PPU. + * This is done by writting a 16-byte batch-buffer-status block back into + * main memory (in cell_context->buffer_status[]). + */ +static void +release_buffer(uint buffer) +{ + /* Evidently, using less than a 16-byte status doesn't work reliably */ + static const uint status[4] ALIGN16_ATTRIB + = {CELL_BUFFER_STATUS_FREE, 0, 0, 0}; + + const uint index = 4 * (spu.init.id * CELL_NUM_BUFFERS + buffer); + uint *dst = spu.init.buffer_status + index; + + ASSERT(buffer < CELL_NUM_BUFFERS); + + mfc_put((void *) &status, /* src in local memory */ + (unsigned int) dst, /* dst in main memory */ + sizeof(status), /* size */ + TAG_MISC, /* tag is unimportant */ + 0, /* tid */ + 0 /* rid */); +} + + +/** + * For tiles whose status is TILE_STATUS_CLEAR, write solid-filled + * tiles back to the main framebuffer. + */ +static void +really_clear_tiles(uint surfaceIndex) +{ + const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles; + uint i; + + if (surfaceIndex == 0) { + clear_c_tile(&spu.ctile); + + for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) { + uint tx = i % spu.fb.width_tiles; + uint ty = i / spu.fb.width_tiles; + if (spu.ctile_status[ty][tx] == TILE_STATUS_CLEAR) { + put_tile(tx, ty, &spu.ctile, TAG_SURFACE_CLEAR, 0); + } + } + } + else { + clear_z_tile(&spu.ztile); + + for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) { + uint tx = i % spu.fb.width_tiles; + uint ty = i / spu.fb.width_tiles; + if (spu.ztile_status[ty][tx] == TILE_STATUS_CLEAR) + put_tile(tx, ty, &spu.ctile, TAG_SURFACE_CLEAR, 1); + } + } + +#if 0 + wait_on_mask(1 << TAG_SURFACE_CLEAR); +#endif +} + + +static void +cmd_clear_surface(const struct cell_command_clear_surface *clear) +{ + const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles; + uint i; + + if (Debug) + printf("SPU %u: CLEAR SURF %u to 0x%08x\n", spu.init.id, + clear->surface, clear->value); + +#define CLEAR_OPT 1 +#if CLEAR_OPT + /* set all tile's status to CLEAR */ + if (clear->surface == 0) { + memset(spu.ctile_status, TILE_STATUS_CLEAR, sizeof(spu.ctile_status)); + spu.fb.color_clear_value = clear->value; + } + else { + memset(spu.ztile_status, TILE_STATUS_CLEAR, sizeof(spu.ztile_status)); + spu.fb.depth_clear_value = clear->value; + } + return; +#endif + + if (clear->surface == 0) { + spu.fb.color_clear_value = clear->value; + clear_c_tile(&spu.ctile); + } + else { + spu.fb.depth_clear_value = clear->value; + clear_z_tile(&spu.ztile); + } + + /* + printf("SPU: %s num=%d w=%d h=%d\n", + __FUNCTION__, num_tiles, spu.fb.width_tiles, spu.fb.height_tiles); + */ + + for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) { + uint tx = i % spu.fb.width_tiles; + uint ty = i / spu.fb.width_tiles; + if (clear->surface == 0) + put_tile(tx, ty, &spu.ctile, TAG_SURFACE_CLEAR, 0); + else + put_tile(tx, ty, &spu.ztile, TAG_SURFACE_CLEAR, 1); + /* XXX we don't want this here, but it fixes bad tile results */ + } + +#if 0 + wait_on_mask(1 << TAG_SURFACE_CLEAR); +#endif + + if (Debug) + printf("SPU %u: CLEAR SURF done\n", spu.init.id); +} + + +static void +cmd_release_verts(const struct cell_command_release_verts *release) +{ + if (Debug) + printf("SPU %u: RELEASE VERTS %u\n", + spu.init.id, release->vertex_buf); + ASSERT(release->vertex_buf != ~0U); + release_buffer(release->vertex_buf); +} + + +static void +cmd_state_framebuffer(const struct cell_command_framebuffer *cmd) +{ + if (Debug) + printf("SPU %u: FRAMEBUFFER: %d x %d at %p, cformat 0x%x zformat 0x%x\n", + spu.init.id, + cmd->width, + cmd->height, + cmd->color_start, + cmd->color_format, + cmd->depth_format); + + ASSERT_ALIGN16(cmd->color_start); + ASSERT_ALIGN16(cmd->depth_start); + + spu.fb.color_start = cmd->color_start; + spu.fb.depth_start = cmd->depth_start; + spu.fb.color_format = cmd->color_format; + spu.fb.depth_format = cmd->depth_format; + spu.fb.width = cmd->width; + spu.fb.height = cmd->height; + spu.fb.width_tiles = (spu.fb.width + TILE_SIZE - 1) / TILE_SIZE; + spu.fb.height_tiles = (spu.fb.height + TILE_SIZE - 1) / TILE_SIZE; + + if (spu.fb.depth_format == PIPE_FORMAT_Z32_UNORM) + spu.fb.zsize = 4; + else if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) + spu.fb.zsize = 2; + else + spu.fb.zsize = 0; + + if (spu.fb.color_format == PIPE_FORMAT_A8R8G8B8_UNORM) + spu.color_shuffle = ((vector unsigned char) { + 12, 0, 4, 8, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}); + else if (spu.fb.color_format == PIPE_FORMAT_B8G8R8A8_UNORM) + spu.color_shuffle = ((vector unsigned char) { + 8, 4, 0, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}); + else + ASSERT(0); +} + + +static void +cmd_state_blend(const struct pipe_blend_state *state) +{ + if (Debug) + printf("SPU %u: BLEND: enabled %d\n", + spu.init.id, + state->blend_enable); + + memcpy(&spu.blend, state, sizeof(*state)); +} + + +static void +cmd_state_depth_stencil(const struct pipe_depth_stencil_alpha_state *state) +{ + if (Debug) + printf("SPU %u: DEPTH_STENCIL: ztest %d\n", + spu.init.id, + state->depth.enabled); + + memcpy(&spu.depth_stencil, state, sizeof(*state)); +} + + +static void +cmd_state_sampler(const struct pipe_sampler_state *state) +{ + if (Debug) + printf("SPU %u: SAMPLER\n", + spu.init.id); + + memcpy(&spu.sampler[0], state, sizeof(*state)); + if (spu.sampler[0].min_img_filter == PIPE_TEX_FILTER_LINEAR) + spu.sample_texture = sample_texture_bilinear; + else + spu.sample_texture = sample_texture_nearest; +} + + +static void +cmd_state_texture(const struct cell_command_texture *texture) +{ + if (Debug) + printf("SPU %u: TEXTURE at %p size %u x %u\n", + spu.init.id, texture->start, texture->width, texture->height); + + memcpy(&spu.texture, texture, sizeof(*texture)); + spu.tex_size = (vector float) + { spu.texture.width, spu.texture.height, 0.0, 0.0}; + spu.tex_size_mask = (vector unsigned int) + { spu.texture.width - 1, spu.texture.height - 1, 0, 0 }; +} + + +static void +cmd_state_vertex_info(const struct vertex_info *vinfo) +{ + if (Debug) { + printf("SPU %u: VERTEX_INFO num_attribs=%u\n", spu.init.id, + vinfo->num_attribs); + } + ASSERT(vinfo->num_attribs >= 1); + ASSERT(vinfo->num_attribs <= 8); + memcpy(&spu.vertex_info, vinfo, sizeof(*vinfo)); +} + + +static void +cmd_state_vs_array_info(const struct cell_array_info *vs_info) +{ + const unsigned attr = vs_info->attr; + + ASSERT(attr < PIPE_ATTRIB_MAX); + draw.vertex_fetch.src_ptr[attr] = vs_info->base; + draw.vertex_fetch.pitch[attr] = vs_info->pitch; + draw.vertex_fetch.format[attr] = vs_info->format; + draw.vertex_fetch.dirty = 1; +} + + +static void +cmd_finish(void) +{ + if (Debug) + printf("SPU %u: FINISH\n", spu.init.id); + really_clear_tiles(0); + /* wait for all outstanding DMAs to finish */ + mfc_write_tag_mask(~0); + mfc_read_tag_status_all(); + /* send mbox message to PPU */ + spu_write_out_mbox(CELL_CMD_FINISH); +} + + +/** + * Execute a batch of commands + * The opcode param encodes the location of the buffer and its size. + */ +static void +cmd_batch(uint opcode) +{ + const uint buf = (opcode >> 8) & 0xff; + uint size = (opcode >> 16); + uint64_t buffer[CELL_BUFFER_SIZE / 8] ALIGN16_ATTRIB; + const unsigned usize = size / sizeof(buffer[0]); + uint pos; + + if (Debug) + printf("SPU %u: BATCH buffer %u, len %u, from %p\n", + spu.init.id, buf, size, spu.init.buffers[buf]); + + ASSERT((opcode & CELL_CMD_OPCODE_MASK) == CELL_CMD_BATCH); + + ASSERT_ALIGN16(spu.init.buffers[buf]); + + size = ROUNDUP16(size); + + ASSERT_ALIGN16(spu.init.buffers[buf]); + + mfc_get(buffer, /* dest */ + (unsigned int) spu.init.buffers[buf], /* src */ + size, + TAG_BATCH_BUFFER, + 0, /* tid */ + 0 /* rid */); + wait_on_mask(1 << TAG_BATCH_BUFFER); + + /* Tell PPU we're done copying the buffer to local store */ + if (Debug) + printf("SPU %u: release batch buf %u\n", spu.init.id, buf); + release_buffer(buf); + + for (pos = 0; pos < usize; /* no incr */) { + switch (buffer[pos]) { + case CELL_CMD_STATE_FRAMEBUFFER: + { + struct cell_command_framebuffer *fb + = (struct cell_command_framebuffer *) &buffer[pos]; + cmd_state_framebuffer(fb); + pos += sizeof(*fb) / 8; + } + break; + case CELL_CMD_CLEAR_SURFACE: + { + struct cell_command_clear_surface *clr + = (struct cell_command_clear_surface *) &buffer[pos]; + cmd_clear_surface(clr); + pos += sizeof(*clr) / 8; + } + break; + case CELL_CMD_RENDER: + { + struct cell_command_render *render + = (struct cell_command_render *) &buffer[pos]; + uint pos_incr; + cmd_render(render, &pos_incr); + pos += pos_incr; + } + break; + case CELL_CMD_RELEASE_VERTS: + { + struct cell_command_release_verts *release + = (struct cell_command_release_verts *) &buffer[pos]; + cmd_release_verts(release); + pos += sizeof(*release) / 8; + } + break; + case CELL_CMD_FINISH: + cmd_finish(); + pos += 1; + break; + case CELL_CMD_STATE_BLEND: + cmd_state_blend((struct pipe_blend_state *) + &buffer[pos+1]); + pos += (1 + ROUNDUP8(sizeof(struct pipe_blend_state)) / 8); + break; + case CELL_CMD_STATE_DEPTH_STENCIL: + cmd_state_depth_stencil((struct pipe_depth_stencil_alpha_state *) + &buffer[pos+1]); + pos += (1 + ROUNDUP8(sizeof(struct pipe_depth_stencil_alpha_state)) / 8); + break; + case CELL_CMD_STATE_SAMPLER: + cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]); + pos += (1 + ROUNDUP8(sizeof(struct pipe_sampler_state)) / 8); + break; + case CELL_CMD_STATE_TEXTURE: + cmd_state_texture((struct cell_command_texture *) &buffer[pos+1]); + pos += (1 + ROUNDUP8(sizeof(struct cell_command_texture)) / 8); + break; + case CELL_CMD_STATE_VERTEX_INFO: + cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]); + pos += (1 + ROUNDUP8(sizeof(struct vertex_info)) / 8); + break; + case CELL_CMD_STATE_VIEWPORT: + (void) memcpy(& draw.viewport, &buffer[pos+1], + sizeof(struct pipe_viewport_state)); + pos += (1 + ROUNDUP8(sizeof(struct pipe_viewport_state)) / 8); + break; + case CELL_CMD_STATE_VS_ARRAY_INFO: + cmd_state_vs_array_info((struct cell_array_info *) &buffer[pos+1]); + pos += (1 + ROUNDUP8(sizeof(struct cell_array_info)) / 8); + break; + default: + printf("SPU %u: bad opcode: 0x%llx\n", spu.init.id, buffer[pos]); + ASSERT(0); + break; + } + } + + if (Debug) + printf("SPU %u: BATCH complete\n", spu.init.id); +} + + +/** + * Temporary/simple main loop for SPEs: Get a command, execute it, repeat. + */ +static void +main_loop(void) +{ + struct cell_command cmd; + int exitFlag = 0; + + if (Debug) + printf("SPU %u: Enter main loop\n", spu.init.id); + + ASSERT((sizeof(struct cell_command) & 0xf) == 0); + ASSERT_ALIGN16(&cmd); + + while (!exitFlag) { + unsigned opcode; + int tag = 0; + + if (Debug) + printf("SPU %u: Wait for cmd...\n", spu.init.id); + + /* read/wait from mailbox */ + opcode = (unsigned int) spu_read_in_mbox(); + + if (Debug) + printf("SPU %u: got cmd 0x%x\n", spu.init.id, opcode); + + /* command payload */ + mfc_get(&cmd, /* dest */ + (unsigned int) spu.init.cmd, /* src */ + sizeof(struct cell_command), /* bytes */ + tag, + 0, /* tid */ + 0 /* rid */); + wait_on_mask( 1 << tag ); + + /* + * NOTE: most commands should be contained in a batch buffer + */ + + switch (opcode & CELL_CMD_OPCODE_MASK) { + case CELL_CMD_EXIT: + if (Debug) + printf("SPU %u: EXIT\n", spu.init.id); + exitFlag = 1; + break; + case CELL_CMD_VS_EXECUTE: + spu_execute_vertex_shader(&draw, &cmd.vs); + break; + case CELL_CMD_BATCH: + cmd_batch(opcode); + break; + default: + printf("Bad opcode!\n"); + } + + } + + if (Debug) + printf("SPU %u: Exit main loop\n", spu.init.id); +} + + + +static void +one_time_init(void) +{ + memset(spu.ctile_status, TILE_STATUS_DEFINED, sizeof(spu.ctile_status)); + memset(spu.ztile_status, TILE_STATUS_DEFINED, sizeof(spu.ztile_status)); + invalidate_tex_cache(); +} + + + +/* In some versions of the SDK the SPE main takes 'unsigned long' as a + * parameter. In others it takes 'unsigned long long'. Use a define to + * select between the two. + */ +#ifdef SPU_MAIN_PARAM_LONG_LONG +typedef unsigned long long main_param_t; +#else +typedef unsigned long main_param_t; +#endif + +/** + * SPE entrypoint. + */ +int +main(main_param_t speid, main_param_t argp) +{ + int tag = 0; + + (void) speid; + + ASSERT(sizeof(tile_t) == TILE_SIZE * TILE_SIZE * 4); + ASSERT(sizeof(struct cell_command_render) % 8 == 0); + + one_time_init(); + + if (Debug) + printf("SPU: main() speid=%lu\n", speid); + + mfc_get(&spu.init, /* dest */ + (unsigned int) argp, /* src */ + sizeof(struct cell_init_info), /* bytes */ + tag, + 0, /* tid */ + 0 /* rid */); + wait_on_mask( 1 << tag ); + +#if 0 + if (spu.init.id==0) + spu_test_misc(); +#endif + + main_loop(); + + return 0; +} diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h new file mode 100644 index 0000000000..1710a17512 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -0,0 +1,177 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SPU_MAIN_H +#define SPU_MAIN_H + + +#include + +#include "pipe/cell/common.h" +#include "pipe/draw/draw_vertex.h" +#include "pipe/p_state.h" + + + +#define MAX_WIDTH 1024 +#define MAX_HEIGHT 1024 + + +typedef union { + ushort us[TILE_SIZE][TILE_SIZE]; + uint ui[TILE_SIZE][TILE_SIZE]; + vector unsigned short us8[TILE_SIZE/2][TILE_SIZE/4]; + vector unsigned int ui4[TILE_SIZE/2][TILE_SIZE/2]; +} tile_t; + + +#define TILE_STATUS_CLEAR 1 +#define TILE_STATUS_DEFINED 2 /**< defined in FB, but not in local store */ +#define TILE_STATUS_CLEAN 3 /**< in local store, but not changed */ +#define TILE_STATUS_DIRTY 4 /**< modified locally, but not put back yet */ +#define TILE_STATUS_GETTING 5 /**< mfc_get() called but not yet arrived */ + + +struct spu_framebuffer { + void *color_start; /**< addr of color surface in main memory */ + void *depth_start; /**< addr of depth surface in main memory */ + enum pipe_format color_format; + enum pipe_format depth_format; + uint width, height; /**< size in pixels */ + uint width_tiles, height_tiles; /**< width and height in tiles */ + + uint color_clear_value; + uint depth_clear_value; + + uint zsize; /**< 0, 2 or 4 bytes per Z */ +} ALIGN16_ATTRIB; + + +/** + * All SPU global/context state will be in singleton object of this type: + */ +struct spu_global +{ + struct cell_init_info init; + + struct spu_framebuffer fb; + struct pipe_blend_state blend_stencil; + struct pipe_depth_stencil_alpha_state depth_stencil; + struct pipe_blend_state blend; + struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; + struct cell_command_texture texture; + + struct vertex_info vertex_info; + + /* XXX more state to come */ + + + /** current color and Z tiles */ + tile_t ctile ALIGN16_ATTRIB; + tile_t ztile ALIGN16_ATTRIB; + + /** Current tiles' status */ + ubyte cur_ctile_status, cur_ztile_status; + + /** Status of all tiles in framebuffer */ + ubyte ctile_status[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB; + ubyte ztile_status[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB; + + + /** for converting RGBA to PIPE_FORMAT_x colors */ + vector unsigned char color_shuffle; + + vector float tex_size; + vector unsigned int tex_size_mask; /**< == int(size - 1) */ + + vector float (*sample_texture)(vector float texcoord); + +} ALIGN16_ATTRIB; + + +extern struct spu_global spu; +extern boolean Debug; + + + + +/* DMA TAGS */ + +#define TAG_SURFACE_CLEAR 10 +#define TAG_VERTEX_BUFFER 11 +#define TAG_READ_TILE_COLOR 12 +#define TAG_READ_TILE_Z 13 +#define TAG_WRITE_TILE_COLOR 14 +#define TAG_WRITE_TILE_Z 15 +#define TAG_INDEX_BUFFER 16 +#define TAG_BATCH_BUFFER 17 +#define TAG_MISC 18 +#define TAG_TEXTURE_TILE 19 +#define TAG_INSTRUCTION_FETCH 20 + + + +static INLINE void +wait_on_mask(unsigned tagMask) +{ + mfc_write_tag_mask( tagMask ); + /* wait for completion of _any_ DMAs specified by tagMask */ + mfc_read_tag_status_any(); +} + + +static INLINE void +wait_on_mask_all(unsigned tagMask) +{ + mfc_write_tag_mask( tagMask ); + /* wait for completion of _any_ DMAs specified by tagMask */ + mfc_read_tag_status_all(); +} + + + + + +static INLINE void +memset16(ushort *d, ushort value, uint count) +{ + uint i; + for (i = 0; i < count; i++) + d[i] = value; +} + + +static INLINE void +memset32(uint *d, uint value, uint count) +{ + uint i; + for (i = 0; i < count; i++) + d[i] = value; +} + + +#endif /* SPU_MAIN_H */ diff --git a/src/gallium/drivers/cell/spu/spu_render.c b/src/gallium/drivers/cell/spu/spu_render.c new file mode 100644 index 0000000000..932fb500b3 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_render.c @@ -0,0 +1,301 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include +#include +#include + +#include "spu_main.h" +#include "spu_render.h" +#include "spu_tri.h" +#include "spu_tile.h" +#include "pipe/cell/common.h" + + + +/** + * Given a rendering command's bounding box (in pixels) compute the + * location of the corresponding screen tile bounding box. + */ +static INLINE void +tile_bounding_box(const struct cell_command_render *render, + uint *txmin, uint *tymin, + uint *box_num_tiles, uint *box_width_tiles) +{ +#if 0 + /* Debug: full-window bounding box */ + uint txmax = spu.fb.width_tiles - 1; + uint tymax = spu.fb.height_tiles - 1; + *txmin = 0; + *tymin = 0; + *box_num_tiles = spu.fb.width_tiles * spu.fb.height_tiles; + *box_width_tiles = spu.fb.width_tiles; + (void) render; + (void) txmax; + (void) tymax; +#else + uint txmax, tymax, box_height_tiles; + + *txmin = (uint) render->xmin / TILE_SIZE; + *tymin = (uint) render->ymin / TILE_SIZE; + txmax = (uint) render->xmax / TILE_SIZE; + tymax = (uint) render->ymax / TILE_SIZE; + if (txmax >= spu.fb.width_tiles) + txmax = spu.fb.width_tiles-1; + if (tymax >= spu.fb.height_tiles) + tymax = spu.fb.height_tiles-1; + *box_width_tiles = txmax - *txmin + 1; + box_height_tiles = tymax - *tymin + 1; + *box_num_tiles = *box_width_tiles * box_height_tiles; +#endif +#if 0 + printf("SPU %u: bounds: %g, %g ... %g, %g\n", spu.init.id, + render->xmin, render->ymin, render->xmax, render->ymax); + printf("SPU %u: tiles: %u, %u .. %u, %u\n", + spu.init.id, *txmin, *tymin, txmax, tymax); + ASSERT(render->xmin <= render->xmax); + ASSERT(render->ymin <= render->ymax); +#endif +} + + +/** Check if the tile at (tx,ty) belongs to this SPU */ +static INLINE boolean +my_tile(uint tx, uint ty) +{ + return (spu.fb.width_tiles * ty + tx) % spu.init.num_spus == spu.init.id; +} + + +/** + * Start fetching non-clear color/Z tiles from main memory + */ +static INLINE void +get_cz_tiles(uint tx, uint ty) +{ + if (spu.depth_stencil.depth.enabled) { + if (spu.cur_ztile_status != TILE_STATUS_CLEAR) { + //printf("SPU %u: getting Z tile %u, %u\n", spu.init.id, tx, ty); + get_tile(tx, ty, &spu.ztile, TAG_READ_TILE_Z, 1); + spu.cur_ztile_status = TILE_STATUS_GETTING; + } + } + + if (spu.cur_ctile_status != TILE_STATUS_CLEAR) { + //printf("SPU %u: getting C tile %u, %u\n", spu.init.id, tx, ty); + get_tile(tx, ty, &spu.ctile, TAG_READ_TILE_COLOR, 0); + spu.cur_ctile_status = TILE_STATUS_GETTING; + } +} + + +/** + * Start putting dirty color/Z tiles back to main memory + */ +static INLINE void +put_cz_tiles(uint tx, uint ty) +{ + if (spu.cur_ztile_status == TILE_STATUS_DIRTY) { + /* tile was modified and needs to be written back */ + //printf("SPU %u: put dirty Z tile %u, %u\n", spu.init.id, tx, ty); + put_tile(tx, ty, &spu.ztile, TAG_WRITE_TILE_Z, 1); + spu.cur_ztile_status = TILE_STATUS_DEFINED; + } + else if (spu.cur_ztile_status == TILE_STATUS_GETTING) { + /* tile was never used */ + spu.cur_ztile_status = TILE_STATUS_DEFINED; + //printf("SPU %u: put getting Z tile %u, %u\n", spu.init.id, tx, ty); + } + + if (spu.cur_ctile_status == TILE_STATUS_DIRTY) { + /* tile was modified and needs to be written back */ + //printf("SPU %u: put dirty C tile %u, %u\n", spu.init.id, tx, ty); + put_tile(tx, ty, &spu.ctile, TAG_WRITE_TILE_COLOR, 0); + spu.cur_ctile_status = TILE_STATUS_DEFINED; + } + else if (spu.cur_ctile_status == TILE_STATUS_GETTING) { + /* tile was never used */ + spu.cur_ctile_status = TILE_STATUS_DEFINED; + //printf("SPU %u: put getting C tile %u, %u\n", spu.init.id, tx, ty); + } +} + + +/** + * Wait for 'put' of color/z tiles to complete. + */ +static INLINE void +wait_put_cz_tiles(void) +{ + wait_on_mask(1 << TAG_WRITE_TILE_COLOR); + if (spu.depth_stencil.depth.enabled) { + wait_on_mask(1 << TAG_WRITE_TILE_Z); + } +} + + +/** + * Render primitives + * \param pos_incr returns value indicating how may words to skip after + * this command in the batch buffer + */ +void +cmd_render(const struct cell_command_render *render, uint *pos_incr) +{ + /* we'll DMA into these buffers */ + ubyte vertex_data[CELL_BUFFER_SIZE] ALIGN16_ATTRIB; + const uint vertex_size = render->vertex_size; /* in bytes */ + /*const*/ uint total_vertex_bytes = render->num_verts * vertex_size; + uint index_bytes; + const ubyte *vertices; + const ushort *indexes; + uint i, j; + + + if (Debug) { + printf("SPU %u: RENDER prim %u, num_vert=%u num_ind=%u " + "inline_vert=%u\n", + spu.init.id, + render->prim_type, + render->num_verts, + render->num_indexes, + render->inline_verts); + + /* + printf(" bound: %g, %g .. %g, %g\n", + render->xmin, render->ymin, render->xmax, render->ymax); + */ + } + + ASSERT(sizeof(*render) % 4 == 0); + ASSERT(total_vertex_bytes % 16 == 0); + ASSERT(render->prim_type == PIPE_PRIM_TRIANGLES); + ASSERT(render->num_indexes % 3 == 0); + + + /* indexes are right after the render command in the batch buffer */ + indexes = (const ushort *) (render + 1); + index_bytes = ROUNDUP8(render->num_indexes * 2); + *pos_incr = index_bytes / 8 + sizeof(*render) / 8; + + + if (render->inline_verts) { + /* Vertices are after indexes in batch buffer at next 16-byte addr */ + vertices = (const ubyte *) render + (*pos_incr * 8); + vertices = (const ubyte *) align_pointer((void *) vertices, 16); + ASSERT_ALIGN16(vertices); + *pos_incr = ((vertices + total_vertex_bytes) - (ubyte *) render) / 8; + } + else { + /* Begin DMA fetch of vertex buffer */ + ubyte *src = spu.init.buffers[render->vertex_buf]; + ubyte *dest = vertex_data; + + /* skip vertex data we won't use */ +#if 01 + src += render->min_index * vertex_size; + dest += render->min_index * vertex_size; + total_vertex_bytes -= render->min_index * vertex_size; +#endif + ASSERT(total_vertex_bytes % 16 == 0); + ASSERT_ALIGN16(dest); + ASSERT_ALIGN16(src); + + mfc_get(dest, /* in vertex_data[] array */ + (unsigned int) src, /* src in main memory */ + total_vertex_bytes, /* size */ + TAG_VERTEX_BUFFER, + 0, /* tid */ + 0 /* rid */); + + vertices = vertex_data; + + wait_on_mask(1 << TAG_VERTEX_BUFFER); + } + + + /** + ** find tiles which intersect the prim bounding box + **/ + uint txmin, tymin, box_width_tiles, box_num_tiles; + tile_bounding_box(render, &txmin, &tymin, + &box_num_tiles, &box_width_tiles); + + + /* make sure any pending clears have completed */ + wait_on_mask(1 << TAG_SURFACE_CLEAR); /* XXX temporary */ + + + /** + ** loop over tiles, rendering tris + **/ + for (i = 0; i < box_num_tiles; i++) { + const uint tx = txmin + i % box_width_tiles; + const uint ty = tymin + i / box_width_tiles; + + ASSERT(tx < spu.fb.width_tiles); + ASSERT(ty < spu.fb.height_tiles); + + if (!my_tile(tx, ty)) + continue; + + spu.cur_ctile_status = spu.ctile_status[ty][tx]; + spu.cur_ztile_status = spu.ztile_status[ty][tx]; + + get_cz_tiles(tx, ty); + + uint drawn = 0; + + /* loop over tris */ + for (j = 0; j < render->num_indexes; j += 3) { + const float *v0, *v1, *v2; + + v0 = (const float *) (vertices + indexes[j+0] * vertex_size); + v1 = (const float *) (vertices + indexes[j+1] * vertex_size); + v2 = (const float *) (vertices + indexes[j+2] * vertex_size); + + drawn += tri_draw(v0, v1, v2, tx, ty); + } + + //printf("SPU %u: drew %u of %u\n", spu.init.id, drawn, render->num_indexes/3); + + /* write color/z tiles back to main framebuffer, if dirtied */ + put_cz_tiles(tx, ty); + + wait_put_cz_tiles(); /* XXX seems unnecessary... */ + + spu.ctile_status[ty][tx] = spu.cur_ctile_status; + spu.ztile_status[ty][tx] = spu.cur_ztile_status; + } + + if (Debug) + printf("SPU %u: RENDER done\n", + spu.init.id); +} + + diff --git a/src/gallium/drivers/cell/spu/spu_render.h b/src/gallium/drivers/cell/spu/spu_render.h new file mode 100644 index 0000000000..fbcdc5ec31 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_render.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef SPU_RENDER_H +#define SPU_RENDER_H + +#include "pipe/cell/common.h" + +extern void +cmd_render(const struct cell_command_render *render, uint *pos_incr); + +#endif /* SPU_RENDER_H */ + diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c new file mode 100644 index 0000000000..3962aaa4a9 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -0,0 +1,217 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_compiler.h" +#include "spu_main.h" +#include "spu_texture.h" +#include "spu_tile.h" +#include "spu_colorpack.h" + + +/** + * Number of texture tiles to cache. + * Note that this will probably be the largest consumer of SPU local store/ + * memory for this driver! + */ +#define CACHE_SIZE 16 + +static tile_t tex_tiles[CACHE_SIZE] ALIGN16_ATTRIB; + +static vector unsigned int tex_tile_xy[CACHE_SIZE]; + + + +/** + * Mark all tex cache entries as invalid. + */ +void +invalidate_tex_cache(void) +{ + /* XXX memset? */ + uint i; + for (i = 0; i < CACHE_SIZE; i++) { + tex_tile_xy[i] = ((vector unsigned int) { ~0U, ~0U, ~0U, ~0U }); + } +} + + +/** + * Return the cache pos/index which corresponds to tile (tx,ty) + */ +static INLINE uint +cache_pos(vector unsigned int txty) +{ + uint pos = (spu_extract(txty,0) + spu_extract(txty,1) * 4) % CACHE_SIZE; + return pos; +} + + +/** + * Make sure the tile for texel (i,j) is present, return its position/index + * in the cache. + */ +static uint +get_tex_tile(vector unsigned int ij) +{ + /* tile address: tx,ty */ + const vector unsigned int txty = spu_rlmask(ij, -5); /* divide by 32 */ + const uint pos = cache_pos(txty); + + if ((spu_extract(tex_tile_xy[pos], 0) != spu_extract(txty, 0)) || + (spu_extract(tex_tile_xy[pos], 1) != spu_extract(txty, 1))) { + + /* texture cache miss, fetch tile from main memory */ + const uint tiles_per_row = spu.texture.width / TILE_SIZE; + const uint bytes_per_tile = sizeof(tile_t); + const void *src = (const ubyte *) spu.texture.start + + (spu_extract(txty,1) * tiles_per_row + spu_extract(txty,0)) * bytes_per_tile; + + printf("SPU %u: tex cache miss at %d, %d pos=%u old=%d,%d\n", + spu.init.id, + spu_extract(txty,0), + spu_extract(txty,1), + pos, + spu_extract(tex_tile_xy[pos],0), + spu_extract(tex_tile_xy[pos],1)); + + ASSERT_ALIGN16(tex_tiles[pos].ui); + ASSERT_ALIGN16(src); + + mfc_get(tex_tiles[pos].ui, /* dest */ + (unsigned int) src, + bytes_per_tile, /* size */ + TAG_TEXTURE_TILE, + 0, /* tid */ + 0 /* rid */); + + wait_on_mask(1 << TAG_TEXTURE_TILE); + + tex_tile_xy[pos] = txty; + } + else { +#if 0 + printf("SPU %u: tex cache HIT at %d, %d\n", + spu.init.id, tx, ty); +#endif + } + + return pos; +} + + +/** + * Get texture sample at texcoord. + * XXX this is extremely primitive for now. + */ +vector float +sample_texture_nearest(vector float texcoord) +{ + vector float tc = spu_mul(texcoord, spu.tex_size); + vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */ + itc = spu_and(itc, spu.tex_size_mask); /* mask (GL_REPEAT) */ + vector unsigned int ij = spu_and(itc, TILE_SIZE-1); /* intra tile addr */ + uint pos = get_tex_tile(itc); + uint texel = tex_tiles[pos].ui[spu_extract(ij, 1)][spu_extract(ij, 0)]; + return spu_unpack_A8R8G8B8(texel); +} + + +vector float +sample_texture_bilinear(vector float texcoord) +{ + static const vector unsigned int offset10 = {1, 0, 0, 0}; + static const vector unsigned int offset01 = {0, 1, 0, 0}; + + vector float tc = spu_mul(texcoord, spu.tex_size); + tc = spu_add(tc, spu_splats(-0.5f)); /* half texel bias */ + + /* integer texcoords S,T: */ + vector unsigned int itc00 = spu_convtu(tc, 0); /* convert to int */ + vector unsigned int itc01 = spu_add(itc00, offset01); + vector unsigned int itc10 = spu_add(itc00, offset10); + vector unsigned int itc11 = spu_add(itc10, offset01); + + /* mask (GL_REPEAT) */ + itc00 = spu_and(itc00, spu.tex_size_mask); + itc01 = spu_and(itc01, spu.tex_size_mask); + itc10 = spu_and(itc10, spu.tex_size_mask); + itc11 = spu_and(itc11, spu.tex_size_mask); + + /* intra tile addr */ + vector unsigned int ij00 = spu_and(itc00, TILE_SIZE-1); + vector unsigned int ij01 = spu_and(itc01, TILE_SIZE-1); + vector unsigned int ij10 = spu_and(itc10, TILE_SIZE-1); + vector unsigned int ij11 = spu_and(itc11, TILE_SIZE-1); + + /* get tile cache positions */ + uint pos00 = get_tex_tile(itc00); + uint pos01, pos10, pos11; + if ((spu_extract(ij00, 0) < TILE_SIZE-1) && + (spu_extract(ij00, 1) < TILE_SIZE-1)) { + /* all texels are in the same tile */ + pos01 = pos10 = pos11 = pos00; + } + else { + pos01 = get_tex_tile(itc01); + pos10 = get_tex_tile(itc10); + pos11 = get_tex_tile(itc11); + } + + /* get texels from tiles and convert to float[4] */ + vector float texel00 = spu_unpack_A8R8G8B8(tex_tiles[pos00].ui[spu_extract(ij00, 1)][spu_extract(ij00, 0)]); + vector float texel01 = spu_unpack_A8R8G8B8(tex_tiles[pos01].ui[spu_extract(ij01, 1)][spu_extract(ij01, 0)]); + vector float texel10 = spu_unpack_A8R8G8B8(tex_tiles[pos10].ui[spu_extract(ij10, 1)][spu_extract(ij10, 0)]); + vector float texel11 = spu_unpack_A8R8G8B8(tex_tiles[pos11].ui[spu_extract(ij11, 1)][spu_extract(ij11, 0)]); + + /* Compute weighting factors in [0,1] + * Multiply texcoord by 1024, AND with 1023, convert back to float. + */ + vector float tc1024 = spu_mul(tc, spu_splats(1024.0f)); + vector signed int itc1024 = spu_convts(tc1024, 0); + itc1024 = spu_and(itc1024, spu_splats((1 << 10) - 1)); + vector float weight = spu_convtf(itc1024, 10); + + /* smeared frac and 1-frac */ + vector float sfrac = spu_splats(spu_extract(weight, 0)); + vector float tfrac = spu_splats(spu_extract(weight, 1)); + vector float sfrac1 = spu_sub(spu_splats(1.0f), sfrac); + vector float tfrac1 = spu_sub(spu_splats(1.0f), tfrac); + + /* multiply the samples (colors) by the S/T weights */ + texel00 = spu_mul(spu_mul(texel00, sfrac1), tfrac1); + texel10 = spu_mul(spu_mul(texel10, sfrac ), tfrac1); + texel01 = spu_mul(spu_mul(texel01, sfrac1), tfrac ); + texel11 = spu_mul(spu_mul(texel11, sfrac ), tfrac ); + + /* compute sum of weighted samples */ + vector float texel_sum = spu_add(texel00, texel01); + texel_sum = spu_add(texel_sum, texel10); + texel_sum = spu_add(texel_sum, texel11); + + return texel_sum; +} diff --git a/src/gallium/drivers/cell/spu/spu_texture.h b/src/gallium/drivers/cell/spu/spu_texture.h new file mode 100644 index 0000000000..95eb87080f --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_texture.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SPU_TEXTURE_H +#define SPU_TEXTURE_H + + +#include "pipe/p_compiler.h" + + +extern void +invalidate_tex_cache(void); + + +extern vector float +sample_texture_nearest(vector float texcoord); + + +extern vector float +sample_texture_bilinear(vector float texcoord); + + +#endif /* SPU_TEXTURE_H */ diff --git a/src/gallium/drivers/cell/spu/spu_tile.c b/src/gallium/drivers/cell/spu/spu_tile.c new file mode 100644 index 0000000000..12dc246328 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_tile.c @@ -0,0 +1,83 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + + +#include "spu_tile.h" +#include "spu_main.h" + + +void +get_tile(uint tx, uint ty, tile_t *tile, int tag, int zBuf) +{ + const uint offset = ty * spu.fb.width_tiles + tx; + const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? spu.fb.zsize : 4); + const ubyte *src = zBuf ? spu.fb.depth_start : spu.fb.color_start; + + src += offset * bytesPerTile; + + ASSERT(tx < spu.fb.width_tiles); + ASSERT(ty < spu.fb.height_tiles); + ASSERT_ALIGN16(tile); + /* + printf("get_tile: dest: %p src: 0x%x size: %d\n", + tile, (unsigned int) src, bytesPerTile); + */ + mfc_get(tile->ui, /* dest in local memory */ + (unsigned int) src, /* src in main memory */ + bytesPerTile, + tag, + 0, /* tid */ + 0 /* rid */); +} + + +void +put_tile(uint tx, uint ty, const tile_t *tile, int tag, int zBuf) +{ + const uint offset = ty * spu.fb.width_tiles + tx; + const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? spu.fb.zsize : 4); + ubyte *dst = zBuf ? spu.fb.depth_start : spu.fb.color_start; + + dst += offset * bytesPerTile; + + ASSERT(tx < spu.fb.width_tiles); + ASSERT(ty < spu.fb.height_tiles); + ASSERT_ALIGN16(tile); + /* + printf("SPU %u: put_tile: src: %p dst: 0x%x size: %d\n", + spu.init.id, + tile, (unsigned int) dst, bytesPerTile); + */ + mfc_put((void *) tile->ui, /* src in local memory */ + (unsigned int) dst, /* dst in main memory */ + bytesPerTile, + tag, + 0, /* tid */ + 0 /* rid */); +} + diff --git a/src/gallium/drivers/cell/spu/spu_tile.h b/src/gallium/drivers/cell/spu/spu_tile.h new file mode 100644 index 0000000000..e53340a55a --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_tile.h @@ -0,0 +1,73 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SPU_TILE_H +#define SPU_TILE_H + + +#include +#include +#include "spu_main.h" +#include "pipe/cell/common.h" + + + +void +get_tile(uint tx, uint ty, tile_t *tile, int tag, int zBuf); + +void +put_tile(uint tx, uint ty, const tile_t *tile, int tag, int zBuf); + + + +static INLINE void +clear_c_tile(tile_t *ctile) +{ + memset32((uint*) ctile->ui, + spu.fb.color_clear_value, + TILE_SIZE * TILE_SIZE); +} + + +static INLINE void +clear_z_tile(tile_t *ztile) +{ + if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) { + memset16((ushort*) ztile->us, + spu.fb.depth_clear_value, + TILE_SIZE * TILE_SIZE); + } + else { + ASSERT(spu.fb.depth_format == PIPE_FORMAT_Z32_UNORM); + memset32((uint*) ztile->ui, + spu.fb.depth_clear_value, + TILE_SIZE * TILE_SIZE); + } +} + + +#endif /* SPU_TILE_H */ diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c new file mode 100644 index 0000000000..be9624cf7d --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -0,0 +1,926 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Triangle rendering within a tile. + */ + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" +#include "pipe/p_util.h" +#include "spu_blend.h" +#include "spu_colorpack.h" +#include "spu_main.h" +#include "spu_texture.h" +#include "spu_tile.h" +#include "spu_tri.h" + +#include "spu_ztest.h" + + +/** Masks are uint[4] vectors with each element being 0 or 0xffffffff */ +typedef vector unsigned int mask_t; + +typedef union +{ + vector float v; + float f[4]; +} float4; + + +/** + * Simplified types taken from other parts of Gallium + */ +struct vertex_header { + vector float data[1]; +}; + + + +/* XXX fix this */ +#undef CEILF +#define CEILF(X) ((float) (int) ((X) + 0.99999)) + + +#define QUAD_TOP_LEFT 0 +#define QUAD_TOP_RIGHT 1 +#define QUAD_BOTTOM_LEFT 2 +#define QUAD_BOTTOM_RIGHT 3 +#define MASK_TOP_LEFT (1 << QUAD_TOP_LEFT) +#define MASK_TOP_RIGHT (1 << QUAD_TOP_RIGHT) +#define MASK_BOTTOM_LEFT (1 << QUAD_BOTTOM_LEFT) +#define MASK_BOTTOM_RIGHT (1 << QUAD_BOTTOM_RIGHT) +#define MASK_ALL 0xf + + +#define DEBUG_VERTS 0 + +/** + * Triangle edge info + */ +struct edge { + float dx; /**< X(v1) - X(v0), used only during setup */ + float dy; /**< Y(v1) - Y(v0), used only during setup */ + float dxdy; /**< dx/dy */ + float sx, sy; /**< first sample point coord */ + int lines; /**< number of lines on this edge */ +}; + + +struct interp_coef +{ + float4 a0; + float4 dadx; + float4 dady; +}; + + +/** + * Triangle setup info (derived from draw_stage). + * Also used for line drawing (taking some liberties). + */ +struct setup_stage { + + /* Vertices are just an array of floats making up each attribute in + * turn. Currently fixed at 4 floats, but should change in time. + * Codegen will help cope with this. + */ + const struct vertex_header *vmax; + const struct vertex_header *vmid; + const struct vertex_header *vmin; + const struct vertex_header *vprovoke; + + struct edge ebot; + struct edge etop; + struct edge emaj; + + float oneoverarea; + + uint tx, ty; + + int cliprect_minx, cliprect_maxx, cliprect_miny, cliprect_maxy; + +#if 0 + struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS]; +#else + struct interp_coef coef[PIPE_MAX_SHADER_INPUTS]; +#endif + +#if 0 + struct quad_header quad; +#endif + + struct { + int left[2]; /**< [0] = row0, [1] = row1 */ + int right[2]; + int y; + unsigned y_flags; + unsigned mask; /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */ + } span; +}; + + + +static struct setup_stage setup; + + + + +#if 0 +/** + * Basically a cast wrapper. + */ +static INLINE struct setup_stage *setup_stage( struct draw_stage *stage ) +{ + return (struct setup_stage *)stage; +} +#endif + +#if 0 +/** + * Clip setup.quad against the scissor/surface bounds. + */ +static INLINE void +quad_clip(struct setup_stage *setup) +{ + const struct pipe_scissor_state *cliprect = &setup.softpipe->cliprect; + const int minx = (int) cliprect->minx; + const int maxx = (int) cliprect->maxx; + const int miny = (int) cliprect->miny; + const int maxy = (int) cliprect->maxy; + + if (setup.quad.x0 >= maxx || + setup.quad.y0 >= maxy || + setup.quad.x0 + 1 < minx || + setup.quad.y0 + 1 < miny) { + /* totally clipped */ + setup.quad.mask = 0x0; + return; + } + if (setup.quad.x0 < minx) + setup.quad.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); + if (setup.quad.y0 < miny) + setup.quad.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); + if (setup.quad.x0 == maxx - 1) + setup.quad.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); + if (setup.quad.y0 == maxy - 1) + setup.quad.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); +} +#endif + +#if 0 +/** + * Emit a quad (pass to next stage) with clipping. + */ +static INLINE void +clip_emit_quad(struct setup_stage *setup) +{ + quad_clip(setup); + if (setup.quad.mask) { + struct softpipe_context *sp = setup.softpipe; + sp->quad.first->run(sp->quad.first, &setup.quad); + } +} +#endif + +/** + * Evaluate attribute coefficients (plane equations) to compute + * attribute values for the four fragments in a quad. + * Eg: four colors will be compute. + */ +static INLINE void +eval_coeff(uint slot, float x, float y, vector float result[4]) +{ + switch (spu.vertex_info.interp_mode[slot]) { + case INTERP_CONSTANT: + result[QUAD_TOP_LEFT] = + result[QUAD_TOP_RIGHT] = + result[QUAD_BOTTOM_LEFT] = + result[QUAD_BOTTOM_RIGHT] = setup.coef[slot].a0.v; + break; + + case INTERP_LINEAR: + /* fall-through, for now */ + default: + { + register vector float dadx = setup.coef[slot].dadx.v; + register vector float dady = setup.coef[slot].dady.v; + register vector float topLeft + = spu_add(setup.coef[slot].a0.v, + spu_add(spu_mul(spu_splats(x), dadx), + spu_mul(spu_splats(y), dady))); + + result[QUAD_TOP_LEFT] = topLeft; + result[QUAD_TOP_RIGHT] = spu_add(topLeft, dadx); + result[QUAD_BOTTOM_LEFT] = spu_add(topLeft, dady); + result[QUAD_BOTTOM_RIGHT] = spu_add(spu_add(topLeft, dadx), dady); + } + } +} + + +static INLINE vector float +eval_z(float x, float y) +{ + const uint slot = 0; + const float dzdx = setup.coef[slot].dadx.f[2]; + const float dzdy = setup.coef[slot].dady.f[2]; + const float topLeft = setup.coef[slot].a0.f[2] + x * dzdx + y * dzdy; + const vector float topLeftv = spu_splats(topLeft); + const vector float derivs = (vector float) { 0.0, dzdx, dzdy, dzdx + dzdy }; + return spu_add(topLeftv, derivs); +} + + +static INLINE mask_t +do_depth_test(int x, int y, mask_t quadmask) +{ + float4 zvals; + mask_t mask; + + zvals.v = eval_z((float) x, (float) y); + + if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) { + int ix = (x - setup.cliprect_minx) / 4; + int iy = (y - setup.cliprect_miny) / 2; + mask = spu_z16_test_less(zvals.v, &spu.ztile.us8[iy][ix], x>>1, quadmask); + } + else { + int ix = (x - setup.cliprect_minx) / 2; + int iy = (y - setup.cliprect_miny) / 2; + mask = spu_z32_test_less(zvals.v, &spu.ztile.ui4[iy][ix], quadmask); + } + + if (spu_extract(spu_orx(mask), 0)) + spu.cur_ztile_status = TILE_STATUS_DIRTY; + + return mask; +} + + +/** + * Emit a quad (pass to next stage). No clipping is done. + * Note: about 1/5 to 1/7 of the time, mask is zero and this function + * should be skipped. But adding the test for that slows things down + * overall. + */ +static INLINE void +emit_quad( int x, int y, mask_t mask ) +{ +#if 0 + struct softpipe_context *sp = setup.softpipe; + setup.quad.x0 = x; + setup.quad.y0 = y; + setup.quad.mask = mask; + sp->quad.first->run(sp->quad.first, &setup.quad); +#else + + if (spu.depth_stencil.depth.enabled) { + mask = do_depth_test(x, y, mask); + } + + /* If any bits in mask are set... */ + if (spu_extract(spu_orx(mask), 0)) { + const int ix = x - setup.cliprect_minx; + const int iy = y - setup.cliprect_miny; + const vector unsigned char shuffle = spu.color_shuffle; + vector float colors[4]; + + spu.cur_ctile_status = TILE_STATUS_DIRTY; + + if (spu.texture.start) { + /* texture mapping */ + vector float texcoords[4]; + eval_coeff(2, (float) x, (float) y, texcoords); + + if (spu_extract(mask, 0)) + colors[0] = spu.sample_texture(texcoords[0]); + if (spu_extract(mask, 1)) + colors[1] = spu.sample_texture(texcoords[1]); + if (spu_extract(mask, 2)) + colors[2] = spu.sample_texture(texcoords[2]); + if (spu_extract(mask, 3)) + colors[3] = spu.sample_texture(texcoords[3]); + } + else { + /* simple shading */ + eval_coeff(1, (float) x, (float) y, colors); + } + +#if 1 + if (spu.blend.blend_enable) + blend_quad(ix % TILE_SIZE, iy % TILE_SIZE, colors); +#endif + + if (spu_extract(mask, 0)) + spu.ctile.ui[iy][ix] = spu_pack_color_shuffle(colors[0], shuffle); + if (spu_extract(mask, 1)) + spu.ctile.ui[iy][ix+1] = spu_pack_color_shuffle(colors[1], shuffle); + if (spu_extract(mask, 2)) + spu.ctile.ui[iy+1][ix] = spu_pack_color_shuffle(colors[2], shuffle); + if (spu_extract(mask, 3)) + spu.ctile.ui[iy+1][ix+1] = spu_pack_color_shuffle(colors[3], shuffle); + +#if 0 + /* SIMD_Z with swizzled color buffer (someday) */ + vector unsigned int uicolors = *((vector unsigned int *) &colors); + spu.ctile.ui4[iy/2][ix/2] = spu_sel(spu.ctile.ui4[iy/2][ix/2], uicolors, mask); +#endif + } + +#endif +} + + +/** + * Given an X or Y coordinate, return the block/quad coordinate that it + * belongs to. + */ +static INLINE int block( int x ) +{ + return x & ~1; +} + + +/** + * Compute mask which indicates which pixels in the 2x2 quad are actually inside + * the triangle's bounds. + * The mask is a uint4 vector and each element will be 0 or 0xffffffff. + */ +static INLINE mask_t calculate_mask( int x ) +{ + /* This is a little tricky. + * Use & instead of && to avoid branches. + * Use negation to convert true/false to ~0/0 values. + */ + mask_t mask; + mask = spu_insert(-((x >= setup.span.left[0]) & (x < setup.span.right[0])), mask, 0); + mask = spu_insert(-((x+1 >= setup.span.left[0]) & (x+1 < setup.span.right[0])), mask, 1); + mask = spu_insert(-((x >= setup.span.left[1]) & (x < setup.span.right[1])), mask, 2); + mask = spu_insert(-((x+1 >= setup.span.left[1]) & (x+1 < setup.span.right[1])), mask, 3); + return mask; +} + + +/** + * Render a horizontal span of quads + */ +static void flush_spans( void ) +{ + int minleft, maxright; + int x; + + switch (setup.span.y_flags) { + case 0x3: + /* both odd and even lines written (both quad rows) */ + minleft = MIN2(setup.span.left[0], setup.span.left[1]); + maxright = MAX2(setup.span.right[0], setup.span.right[1]); + break; + + case 0x1: + /* only even line written (quad top row) */ + minleft = setup.span.left[0]; + maxright = setup.span.right[0]; + break; + + case 0x2: + /* only odd line written (quad bottom row) */ + minleft = setup.span.left[1]; + maxright = setup.span.right[1]; + break; + + default: + return; + } + + + /* OK, we're very likely to need the tile data now. + * clear or finish waiting if needed. + */ + if (spu.cur_ctile_status == TILE_STATUS_GETTING) { + /* wait for mfc_get() to complete */ + //printf("SPU: %u: waiting for ctile\n", spu.init.id); + wait_on_mask(1 << TAG_READ_TILE_COLOR); + spu.cur_ctile_status = TILE_STATUS_CLEAN; + } + else if (spu.cur_ctile_status == TILE_STATUS_CLEAR) { + //printf("SPU %u: clearing C tile %u, %u\n", spu.init.id, setup.tx, setup.ty); + clear_c_tile(&spu.ctile); + spu.cur_ctile_status = TILE_STATUS_DIRTY; + } + ASSERT(spu.cur_ctile_status != TILE_STATUS_DEFINED); + + if (spu.depth_stencil.depth.enabled) { + if (spu.cur_ztile_status == TILE_STATUS_GETTING) { + /* wait for mfc_get() to complete */ + //printf("SPU: %u: waiting for ztile\n", spu.init.id); + wait_on_mask(1 << TAG_READ_TILE_Z); + spu.cur_ztile_status = TILE_STATUS_CLEAN; + } + else if (spu.cur_ztile_status == TILE_STATUS_CLEAR) { + //printf("SPU %u: clearing Z tile %u, %u\n", spu.init.id, setup.tx, setup.ty); + clear_z_tile(&spu.ztile); + spu.cur_ztile_status = TILE_STATUS_DIRTY; + } + ASSERT(spu.cur_ztile_status != TILE_STATUS_DEFINED); + } + + /* XXX this loop could be moved into the above switch cases and + * calculate_mask() could be simplified a bit... + */ + for (x = block(minleft); x <= block(maxright); x += 2) { +#if 1 + emit_quad( x, setup.span.y, calculate_mask( x ) ); +#endif + } + + setup.span.y = 0; + setup.span.y_flags = 0; + setup.span.right[0] = 0; + setup.span.right[1] = 0; +} + +#if DEBUG_VERTS +static void print_vertex(const struct vertex_header *v) +{ + int i; + fprintf(stderr, "Vertex: (%p)\n", v); + for (i = 0; i < setup.quad.nr_attrs; i++) { + fprintf(stderr, " %d: %f %f %f %f\n", i, + v->data[i][0], v->data[i][1], v->data[i][2], v->data[i][3]); + } +} +#endif + + +static boolean setup_sort_vertices(const struct vertex_header *v0, + const struct vertex_header *v1, + const struct vertex_header *v2) +{ + +#if DEBUG_VERTS + fprintf(stderr, "Triangle:\n"); + print_vertex(v0); + print_vertex(v1); + print_vertex(v2); +#endif + + setup.vprovoke = v2; + + /* determine bottom to top order of vertices */ + { + float y0 = spu_extract(v0->data[0], 1); + float y1 = spu_extract(v1->data[0], 1); + float y2 = spu_extract(v2->data[0], 1); + if (y0 <= y1) { + if (y1 <= y2) { + /* y0<=y1<=y2 */ + setup.vmin = v0; + setup.vmid = v1; + setup.vmax = v2; + } + else if (y2 <= y0) { + /* y2<=y0<=y1 */ + setup.vmin = v2; + setup.vmid = v0; + setup.vmax = v1; + } + else { + /* y0<=y2<=y1 */ + setup.vmin = v0; + setup.vmid = v2; + setup.vmax = v1; + } + } + else { + if (y0 <= y2) { + /* y1<=y0<=y2 */ + setup.vmin = v1; + setup.vmid = v0; + setup.vmax = v2; + } + else if (y2 <= y1) { + /* y2<=y1<=y0 */ + setup.vmin = v2; + setup.vmid = v1; + setup.vmax = v0; + } + else { + /* y1<=y2<=y0 */ + setup.vmin = v1; + setup.vmid = v2; + setup.vmax = v0; + } + } + } + + /* Check if triangle is completely outside the tile bounds */ + if (spu_extract(setup.vmin->data[0], 1) > setup.cliprect_maxy) + return FALSE; + if (spu_extract(setup.vmax->data[0], 1) < setup.cliprect_miny) + return FALSE; + if (spu_extract(setup.vmin->data[0], 0) < setup.cliprect_minx && + spu_extract(setup.vmid->data[0], 0) < setup.cliprect_minx && + spu_extract(setup.vmax->data[0], 0) < setup.cliprect_minx) + return FALSE; + if (spu_extract(setup.vmin->data[0], 0) > setup.cliprect_maxx && + spu_extract(setup.vmid->data[0], 0) > setup.cliprect_maxx && + spu_extract(setup.vmax->data[0], 0) > setup.cliprect_maxx) + return FALSE; + + setup.ebot.dx = spu_extract(setup.vmid->data[0], 0) - spu_extract(setup.vmin->data[0], 0); + setup.ebot.dy = spu_extract(setup.vmid->data[0], 1) - spu_extract(setup.vmin->data[0], 1); + setup.emaj.dx = spu_extract(setup.vmax->data[0], 0) - spu_extract(setup.vmin->data[0], 0); + setup.emaj.dy = spu_extract(setup.vmax->data[0], 1) - spu_extract(setup.vmin->data[0], 1); + setup.etop.dx = spu_extract(setup.vmax->data[0], 0) - spu_extract(setup.vmid->data[0], 0); + setup.etop.dy = spu_extract(setup.vmax->data[0], 1) - spu_extract(setup.vmid->data[0], 1); + + /* + * Compute triangle's area. Use 1/area to compute partial + * derivatives of attributes later. + * + * The area will be the same as prim->det, but the sign may be + * different depending on how the vertices get sorted above. + * + * To determine whether the primitive is front or back facing we + * use the prim->det value because its sign is correct. + */ + { + const float area = (setup.emaj.dx * setup.ebot.dy - + setup.ebot.dx * setup.emaj.dy); + + setup.oneoverarea = 1.0f / area; + /* + _mesa_printf("%s one-over-area %f area %f det %f\n", + __FUNCTION__, setup.oneoverarea, area, prim->det ); + */ + } + +#if 0 + /* We need to know if this is a front or back-facing triangle for: + * - the GLSL gl_FrontFacing fragment attribute (bool) + * - two-sided stencil test + */ + setup.quad.facing = (prim->det > 0.0) ^ (setup.softpipe->rasterizer->front_winding == PIPE_WINDING_CW); +#endif + + return TRUE; +} + + +/** + * Compute a0 for a constant-valued coefficient (GL_FLAT shading). + * The value value comes from vertex->data[slot]. + * The result will be put into setup.coef[slot].a0. + * \param slot which attribute slot + */ +static INLINE void +const_coeff(uint slot) +{ + setup.coef[slot].dadx.v = (vector float) {0.0, 0.0, 0.0, 0.0}; + setup.coef[slot].dady.v = (vector float) {0.0, 0.0, 0.0, 0.0}; + setup.coef[slot].a0.v = setup.vprovoke->data[slot]; +} + + +/** + * Compute a0, dadx and dady for a linearly interpolated coefficient, + * for a triangle. + */ +static INLINE void +tri_linear_coeff(uint slot, uint firstComp, uint lastComp) +{ + uint i; + const float *vmin_d = (float *) &setup.vmin->data[slot]; + const float *vmid_d = (float *) &setup.vmid->data[slot]; + const float *vmax_d = (float *) &setup.vmax->data[slot]; + const float x = spu_extract(setup.vmin->data[0], 0) - 0.5f; + const float y = spu_extract(setup.vmin->data[0], 1) - 0.5f; + + for (i = firstComp; i < lastComp; i++) { + float botda = vmid_d[i] - vmin_d[i]; + float majda = vmax_d[i] - vmin_d[i]; + float a = setup.ebot.dy * majda - botda * setup.emaj.dy; + float b = setup.emaj.dx * botda - majda * setup.ebot.dx; + + ASSERT(slot < PIPE_MAX_SHADER_INPUTS); + + setup.coef[slot].dadx.f[i] = a * setup.oneoverarea; + setup.coef[slot].dady.f[i] = b * setup.oneoverarea; + + /* calculate a0 as the value which would be sampled for the + * fragment at (0,0), taking into account that we want to sample at + * pixel centers, in other words (0.5, 0.5). + * + * this is neat but unfortunately not a good way to do things for + * triangles with very large values of dadx or dady as it will + * result in the subtraction and re-addition from a0 of a very + * large number, which means we'll end up loosing a lot of the + * fractional bits and precision from a0. the way to fix this is + * to define a0 as the sample at a pixel center somewhere near vmin + * instead - i'll switch to this later. + */ + setup.coef[slot].a0.f[i] = (vmin_d[i] - + (setup.coef[slot].dadx.f[i] * x + + setup.coef[slot].dady.f[i] * y)); + } + + /* + _mesa_printf("attr[%d].%c: %f dx:%f dy:%f\n", + slot, "xyzw"[i], + setup.coef[slot].a0[i], + setup.coef[slot].dadx.f[i], + setup.coef[slot].dady.f[i]); + */ +} + + +/** + * As above, but interp setup all four vector components. + */ +static INLINE void +tri_linear_coeff4(uint slot) +{ + const vector float vmin_d = setup.vmin->data[slot]; + const vector float vmid_d = setup.vmid->data[slot]; + const vector float vmax_d = setup.vmax->data[slot]; + const vector float xxxx = spu_splats(spu_extract(setup.vmin->data[0], 0) - 0.5f); + const vector float yyyy = spu_splats(spu_extract(setup.vmin->data[0], 1) - 0.5f); + + vector float botda = vmid_d - vmin_d; + vector float majda = vmax_d - vmin_d; + + vector float a = spu_sub(spu_mul(spu_splats(setup.ebot.dy), majda), + spu_mul(botda, spu_splats(setup.emaj.dy))); + vector float b = spu_sub(spu_mul(spu_splats(setup.emaj.dx), botda), + spu_mul(majda, spu_splats(setup.ebot.dx))); + + setup.coef[slot].dadx.v = spu_mul(a, spu_splats(setup.oneoverarea)); + setup.coef[slot].dady.v = spu_mul(b, spu_splats(setup.oneoverarea)); + + vector float tempx = spu_mul(setup.coef[slot].dadx.v, xxxx); + vector float tempy = spu_mul(setup.coef[slot].dady.v, yyyy); + + setup.coef[slot].a0.v = spu_sub(vmin_d, spu_add(tempx, tempy)); +} + + + +#if 0 +/** + * Compute a0, dadx and dady for a perspective-corrected interpolant, + * for a triangle. + * We basically multiply the vertex value by 1/w before computing + * the plane coefficients (a0, dadx, dady). + * Later, when we compute the value at a particular fragment position we'll + * divide the interpolated value by the interpolated W at that fragment. + */ +static void tri_persp_coeff( unsigned slot, + unsigned i ) +{ + /* premultiply by 1/w: + */ + float mina = setup.vmin->data[slot][i] * setup.vmin->data[0][3]; + float mida = setup.vmid->data[slot][i] * setup.vmid->data[0][3]; + float maxa = setup.vmax->data[slot][i] * setup.vmax->data[0][3]; + + float botda = mida - mina; + float majda = maxa - mina; + float a = setup.ebot.dy * majda - botda * setup.emaj.dy; + float b = setup.emaj.dx * botda - majda * setup.ebot.dx; + + /* + printf("tri persp %d,%d: %f %f %f\n", slot, i, + setup.vmin->data[slot][i], + setup.vmid->data[slot][i], + setup.vmax->data[slot][i] + ); + */ + + assert(slot < PIPE_MAX_SHADER_INPUTS); + assert(i <= 3); + + setup.coef[slot].dadx.f[i] = a * setup.oneoverarea; + setup.coef[slot].dady.f[i] = b * setup.oneoverarea; + setup.coef[slot].a0.f[i] = (mina - + (setup.coef[slot].dadx.f[i] * (setup.vmin->data[0][0] - 0.5f) + + setup.coef[slot].dady.f[i] * (setup.vmin->data[0][1] - 0.5f))); +} +#endif + + +/** + * Compute the setup.coef[] array dadx, dady, a0 values. + * Must be called after setup.vmin,vmid,vmax,vprovoke are initialized. + */ +static void setup_tri_coefficients(void) +{ +#if 1 + uint i; + + for (i = 0; i < spu.vertex_info.num_attribs; i++) { + switch (spu.vertex_info.interp_mode[i]) { + case INTERP_NONE: + break; + case INTERP_POS: + /*tri_linear_coeff(i, 2, 3);*/ + /* XXX interp W if PERSPECTIVE... */ + tri_linear_coeff4(i); + break; + case INTERP_CONSTANT: + const_coeff(i); + break; + case INTERP_LINEAR: + tri_linear_coeff4(i); + break; + case INTERP_PERSPECTIVE: + tri_linear_coeff4(i); /* temporary */ + break; + default: + ASSERT(0); + } + } +#else + ASSERT(spu.vertex_info.interp_mode[0] == INTERP_POS); + ASSERT(spu.vertex_info.interp_mode[1] == INTERP_LINEAR || + spu.vertex_info.interp_mode[1] == INTERP_CONSTANT); + tri_linear_coeff(0, 2, 3); /* slot 0, z */ + tri_linear_coeff(1, 0, 4); /* slot 1, color */ +#endif +} + + +static void setup_tri_edges(void) +{ + float vmin_x = spu_extract(setup.vmin->data[0], 0) + 0.5f; + float vmid_x = spu_extract(setup.vmid->data[0], 0) + 0.5f; + + float vmin_y = spu_extract(setup.vmin->data[0], 1) - 0.5f; + float vmid_y = spu_extract(setup.vmid->data[0], 1) - 0.5f; + float vmax_y = spu_extract(setup.vmax->data[0], 1) - 0.5f; + + setup.emaj.sy = CEILF(vmin_y); + setup.emaj.lines = (int) CEILF(vmax_y - setup.emaj.sy); + setup.emaj.dxdy = setup.emaj.dx / setup.emaj.dy; + setup.emaj.sx = vmin_x + (setup.emaj.sy - vmin_y) * setup.emaj.dxdy; + + setup.etop.sy = CEILF(vmid_y); + setup.etop.lines = (int) CEILF(vmax_y - setup.etop.sy); + setup.etop.dxdy = setup.etop.dx / setup.etop.dy; + setup.etop.sx = vmid_x + (setup.etop.sy - vmid_y) * setup.etop.dxdy; + + setup.ebot.sy = CEILF(vmin_y); + setup.ebot.lines = (int) CEILF(vmid_y - setup.ebot.sy); + setup.ebot.dxdy = setup.ebot.dx / setup.ebot.dy; + setup.ebot.sx = vmin_x + (setup.ebot.sy - vmin_y) * setup.ebot.dxdy; +} + + +/** + * Render the upper or lower half of a triangle. + * Scissoring/cliprect is applied here too. + */ +static void subtriangle( struct edge *eleft, + struct edge *eright, + unsigned lines ) +{ + const int minx = setup.cliprect_minx; + const int maxx = setup.cliprect_maxx; + const int miny = setup.cliprect_miny; + const int maxy = setup.cliprect_maxy; + int y, start_y, finish_y; + int sy = (int)eleft->sy; + + ASSERT((int)eleft->sy == (int) eright->sy); + + /* clip top/bottom */ + start_y = sy; + finish_y = sy + lines; + + if (start_y < miny) + start_y = miny; + + if (finish_y > maxy) + finish_y = maxy; + + start_y -= sy; + finish_y -= sy; + + /* + _mesa_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); + */ + + for (y = start_y; y < finish_y; y++) { + + /* avoid accumulating adds as floats don't have the precision to + * accurately iterate large triangle edges that way. luckily we + * can just multiply these days. + * + * this is all drowned out by the attribute interpolation anyway. + */ + int left = (int)(eleft->sx + y * eleft->dxdy); + int right = (int)(eright->sx + y * eright->dxdy); + + /* clip left/right */ + if (left < minx) + left = minx; + if (right > maxx) + right = maxx; + + if (left < right) { + int _y = sy + y; + if (block(_y) != setup.span.y) { + flush_spans(); + setup.span.y = block(_y); + } + + setup.span.left[_y&1] = left; + setup.span.right[_y&1] = right; + setup.span.y_flags |= 1<<(_y&1); + } + } + + + /* save the values so that emaj can be restarted: + */ + eleft->sx += lines * eleft->dxdy; + eright->sx += lines * eright->dxdy; + eleft->sy += lines; + eright->sy += lines; +} + + +/** + * Draw triangle into tile at (tx, ty) (tile coords) + * The tile data should have already been fetched. + */ +boolean +tri_draw(const float *v0, const float *v1, const float *v2, uint tx, uint ty) +{ + setup.tx = tx; + setup.ty = ty; + + /* set clipping bounds to tile bounds */ + setup.cliprect_minx = tx * TILE_SIZE; + setup.cliprect_miny = ty * TILE_SIZE; + setup.cliprect_maxx = (tx + 1) * TILE_SIZE; + setup.cliprect_maxy = (ty + 1) * TILE_SIZE; + + if (!setup_sort_vertices((struct vertex_header *) v0, + (struct vertex_header *) v1, + (struct vertex_header *) v2)) { + return FALSE; /* totally clipped */ + } + + setup_tri_coefficients(); + setup_tri_edges(); + + setup.span.y = 0; + setup.span.y_flags = 0; + setup.span.right[0] = 0; + setup.span.right[1] = 0; + /* setup.span.z_mode = tri_z_mode( setup.ctx ); */ + + /* init_constant_attribs( setup ); */ + + if (setup.oneoverarea < 0.0) { + /* emaj on left: + */ + subtriangle( &setup.emaj, &setup.ebot, setup.ebot.lines ); + subtriangle( &setup.emaj, &setup.etop, setup.etop.lines ); + } + else { + /* emaj on right: + */ + subtriangle( &setup.ebot, &setup.emaj, setup.ebot.lines ); + subtriangle( &setup.etop, &setup.emaj, setup.etop.lines ); + } + + flush_spans(); + + return TRUE; +} diff --git a/src/gallium/drivers/cell/spu/spu_tri.h b/src/gallium/drivers/cell/spu/spu_tri.h new file mode 100644 index 0000000000..aa694dd7c9 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_tri.h @@ -0,0 +1,37 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef SPU_TRI_H +#define SPU_TRI_H + + +extern boolean +tri_draw(const float *v0, const float *v1, const float *v2, uint tx, uint ty); + + +#endif /* SPU_TRI_H */ diff --git a/src/gallium/drivers/cell/spu/spu_util.c b/src/gallium/drivers/cell/spu/spu_util.c new file mode 100644 index 0000000000..ac373240c1 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_util.c @@ -0,0 +1,165 @@ +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/tgsi/util/tgsi_parse.h" +//#include "tgsi_build.h" +#include "pipe/tgsi/util/tgsi_util.h" + +unsigned +tgsi_util_get_src_register_swizzle( + const struct tgsi_src_register *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->SwizzleX; + case 1: + return reg->SwizzleY; + case 2: + return reg->SwizzleZ; + case 3: + return reg->SwizzleW; + default: + assert( 0 ); + } + return 0; +} + +unsigned +tgsi_util_get_src_register_extswizzle( + const struct tgsi_src_register_ext_swz *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->ExtSwizzleX; + case 1: + return reg->ExtSwizzleY; + case 2: + return reg->ExtSwizzleZ; + case 3: + return reg->ExtSwizzleW; + default: + assert( 0 ); + } + return 0; +} + +unsigned +tgsi_util_get_full_src_register_extswizzle( + const struct tgsi_full_src_register *reg, + unsigned component ) +{ + unsigned swizzle; + + /* + * First, calculate the extended swizzle for a given channel. This will give + * us either a channel index into the simple swizzle or a constant 1 or 0. + */ + swizzle = tgsi_util_get_src_register_extswizzle( + ®->SrcRegisterExtSwz, + component ); + + assert (TGSI_SWIZZLE_X == TGSI_EXTSWIZZLE_X); + assert (TGSI_SWIZZLE_Y == TGSI_EXTSWIZZLE_Y); + assert (TGSI_SWIZZLE_Z == TGSI_EXTSWIZZLE_Z); + assert (TGSI_SWIZZLE_W == TGSI_EXTSWIZZLE_W); + assert (TGSI_EXTSWIZZLE_ZERO > TGSI_SWIZZLE_W); + assert (TGSI_EXTSWIZZLE_ONE > TGSI_SWIZZLE_W); + + /* + * Second, calculate the simple swizzle for the unswizzled channel index. + * Leave the constants intact, they are not affected by the simple swizzle. + */ + if( swizzle <= TGSI_SWIZZLE_W ) { + swizzle = tgsi_util_get_src_register_swizzle( + ®->SrcRegister, + component ); + } + + return swizzle; +} + +unsigned +tgsi_util_get_src_register_extnegate( + const struct tgsi_src_register_ext_swz *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->NegateX; + case 1: + return reg->NegateY; + case 2: + return reg->NegateZ; + case 3: + return reg->NegateW; + default: + assert( 0 ); + } + return 0; +} + +void +tgsi_util_set_src_register_extnegate( + struct tgsi_src_register_ext_swz *reg, + unsigned negate, + unsigned component ) +{ + switch( component ) { + case 0: + reg->NegateX = negate; + break; + case 1: + reg->NegateY = negate; + break; + case 2: + reg->NegateZ = negate; + break; + case 3: + reg->NegateW = negate; + break; + default: + assert( 0 ); + } +} + +unsigned +tgsi_util_get_full_src_register_sign_mode( + const struct tgsi_full_src_register *reg, + unsigned component ) +{ + unsigned sign_mode; + + if( reg->SrcRegisterExtMod.Absolute ) { + /* Consider only the post-abs negation. */ + + if( reg->SrcRegisterExtMod.Negate ) { + sign_mode = TGSI_UTIL_SIGN_SET; + } + else { + sign_mode = TGSI_UTIL_SIGN_CLEAR; + } + } + else { + /* Accumulate the three negations. */ + + unsigned negate; + + negate = reg->SrcRegister.Negate; + if( tgsi_util_get_src_register_extnegate( ®->SrcRegisterExtSwz, component ) ) { + negate = !negate; + } + if( reg->SrcRegisterExtMod.Negate ) { + negate = !negate; + } + + if( negate ) { + sign_mode = TGSI_UTIL_SIGN_TOGGLE; + } + else { + sign_mode = TGSI_UTIL_SIGN_KEEP; + } + } + + return sign_mode; +} diff --git a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c new file mode 100644 index 0000000000..45e3c26c00 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c @@ -0,0 +1,673 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include +#include + +#include "pipe/p_util.h" +#include "pipe/p_state.h" +#include "pipe/p_shader_tokens.h" +#include "spu_exec.h" +#include "spu_vertex_shader.h" +#include "spu_main.h" + +#define CACHE_NAME attribute +#define CACHED_TYPE qword +#define CACHE_TYPE CACHE_TYPE_RO +#define CACHE_SET_TAGID(set) TAG_VERTEX_BUFFER +#define CACHE_LOG2NNWAY 2 +#define CACHE_LOG2NSETS 6 +#include + +/* Yes folks, this is ugly. + */ +#undef CACHE_NWAY +#undef CACHE_NSETS +#define CACHE_NAME attribute +#define CACHE_NWAY 4 +#define CACHE_NSETS (1U << 6) + + +#define DRAW_DBG 0 + +static const qword fetch_shuffle_data[] = { + /* Shuffle used by CVT_64_FLOAT + */ + { + 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + }, + + /* Shuffle used by CVT_8_USCALED and CVT_8_SSCALED + */ + { + 0x00, 0x80, 0x80, 0x80, 0x01, 0x80, 0x80, 0x80, + 0x02, 0x80, 0x80, 0x80, 0x03, 0x80, 0x80, 0x80, + }, + + /* Shuffle used by CVT_16_USCALED and CVT_16_SSCALED + */ + { + 0x00, 0x01, 0x80, 0x80, 0x02, 0x03, 0x80, 0x80, + 0x04, 0x05, 0x80, 0x80, 0x06, 0x07, 0x80, 0x80, + }, + + /* High value shuffle used by trans4x4. + */ + { + 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, + 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17 + }, + + /* Low value shuffle used by trans4x4. + */ + { + 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F + } +}; + + +static INLINE void +trans4x4(qword row0, qword row1, qword row2, qword row3, qword *out, + const qword *shuffle) +{ + qword t1 = si_shufb(row0, row2, shuffle[3]); + qword t2 = si_shufb(row0, row2, shuffle[4]); + qword t3 = si_shufb(row1, row3, shuffle[3]); + qword t4 = si_shufb(row1, row3, shuffle[4]); + + out[0] = si_shufb(t1, t3, shuffle[3]); + out[1] = si_shufb(t1, t3, shuffle[4]); + out[2] = si_shufb(t2, t4, shuffle[3]); + out[3] = si_shufb(t2, t4, shuffle[4]); +} + + +/** + * Fetch between 1 and 32 bytes from an unaligned address + */ +static INLINE void +fetch_unaligned(qword *dst, unsigned ea, unsigned size) +{ + qword tmp[4]; + const int shift = ea & 0x0f; + const unsigned aligned_start_ea = ea & ~0x0f; + const unsigned aligned_end_ea = (ea + size) & ~0x0f; + const unsigned num_entries = ((aligned_end_ea - aligned_start_ea) / 16) + 1; + unsigned i; + + + if (shift == 0) { + /* Data is already aligned. Fetch directly into the destination buffer. + */ + for (i = 0; i < num_entries; i++) { + dst[i] = cache_rd(attribute, (ea & ~0x0f) + (i * 16)); + } + } else { + /* Fetch data from the cache to the local buffer. + */ + for (i = 0; i < num_entries; i++) { + tmp[i] = cache_rd(attribute, (ea & ~0x0f) + (i * 16)); + } + + + /* Fix the alignment of the data and write to the destination buffer. + */ + for (i = 0; i < ((size + 15) / 16); i++) { + dst[i] = si_or((qword) spu_slqwbyte(tmp[i], shift), + (qword) spu_rlmaskqwbyte(tmp[i + 1], shift - 16)); + } + } +} + + +#define CVT_32_FLOAT(q, s) (*(q)) + +static INLINE qword +CVT_64_FLOAT(const qword *qw, const qword *shuffle) +{ + qword a = si_frds(qw[0]); + qword b = si_frds(si_rotqbyi(qw[0], 8)); + qword c = si_frds(qw[1]); + qword d = si_frds(si_rotqbyi(qw[1], 8)); + + qword ab = si_shufb(a, b, shuffle[0]); + qword cd = si_shufb(c, d, si_rotqbyi(shuffle[0], 8)); + + return si_or(ab, cd); +} + + +static INLINE qword +CVT_8_USCALED(const qword *qw, const qword *shuffle) +{ + return si_cuflt(si_shufb(*qw, *qw, shuffle[1]), 0); +} + + +static INLINE qword +CVT_16_USCALED(const qword *qw, const qword *shuffle) +{ + return si_cuflt(si_shufb(*qw, *qw, shuffle[2]), 0); +} + + +static INLINE qword +CVT_32_USCALED(const qword *qw, const qword *shuffle) +{ + (void) shuffle; + return si_cuflt(*qw, 0); +} + +static INLINE qword +CVT_8_SSCALED(const qword *qw, const qword *shuffle) +{ + return si_csflt(si_shufb(*qw, *qw, shuffle[1]), 0); +} + + +static INLINE qword +CVT_16_SSCALED(const qword *qw, const qword *shuffle) +{ + return si_csflt(si_shufb(*qw, *qw, shuffle[2]), 0); +} + + +static INLINE qword +CVT_32_SSCALED(const qword *qw, const qword *shuffle) +{ + (void) shuffle; + return si_csflt(*qw, 0); +} + + +static INLINE qword +CVT_8_UNORM(const qword *qw, const qword *shuffle) +{ + const qword scale = (qword) spu_splats(1.0f / 255.0f); + return si_fm(CVT_8_USCALED(qw, shuffle), scale); +} + + +static INLINE qword +CVT_16_UNORM(const qword *qw, const qword *shuffle) +{ + const qword scale = (qword) spu_splats(1.0f / 65535.0f); + return si_fm(CVT_16_USCALED(qw, shuffle), scale); +} + + +static INLINE qword +CVT_32_UNORM(const qword *qw, const qword *shuffle) +{ + const qword scale = (qword) spu_splats(1.0f / 4294967295.0f); + return si_fm(CVT_32_USCALED(qw, shuffle), scale); +} + + +static INLINE qword +CVT_8_SNORM(const qword *qw, const qword *shuffle) +{ + const qword scale = (qword) spu_splats(1.0f / 127.0f); + return si_fm(CVT_8_SSCALED(qw, shuffle), scale); +} + + +static INLINE qword +CVT_16_SNORM(const qword *qw, const qword *shuffle) +{ + const qword scale = (qword) spu_splats(1.0f / 32767.0f); + return si_fm(CVT_16_SSCALED(qw, shuffle), scale); +} + + +static INLINE qword +CVT_32_SNORM(const qword *qw, const qword *shuffle) +{ + const qword scale = (qword) spu_splats(1.0f / 2147483647.0f); + return si_fm(CVT_32_SSCALED(qw, shuffle), scale); +} + +#define SZ_4 si_il(0U) +#define SZ_3 si_fsmbi(0x000f) +#define SZ_2 si_fsmbi(0x00ff) +#define SZ_1 si_fsmbi(0x0fff) + +/** + * Fetch a float[4] vertex attribute from memory, doing format/type + * conversion as needed. + * + * This is probably needed/dupliocated elsewhere, eg format + * conversion, texture sampling etc. + */ +#define FETCH_ATTRIB( NAME, SZ, CVT, N ) \ +static void \ +fetch_##NAME(qword *out, const qword *in, qword defaults, \ + const qword *shuffle) \ +{ \ + qword tmp[4]; \ + \ + tmp[0] = si_selb(CVT(in + (0 * N), shuffle), defaults, SZ); \ + tmp[1] = si_selb(CVT(in + (1 * N), shuffle), defaults, SZ); \ + tmp[2] = si_selb(CVT(in + (2 * N), shuffle), defaults, SZ); \ + tmp[3] = si_selb(CVT(in + (3 * N), shuffle), defaults, SZ); \ + trans4x4(tmp[0], tmp[1], tmp[2], tmp[3], out, shuffle); \ +} + + +FETCH_ATTRIB( R64G64B64A64_FLOAT, SZ_4, CVT_64_FLOAT, 2 ) +FETCH_ATTRIB( R64G64B64_FLOAT, SZ_3, CVT_64_FLOAT, 2 ) +FETCH_ATTRIB( R64G64_FLOAT, SZ_2, CVT_64_FLOAT, 2 ) +FETCH_ATTRIB( R64_FLOAT, SZ_1, CVT_64_FLOAT, 2 ) + +FETCH_ATTRIB( R32G32B32A32_FLOAT, SZ_4, CVT_32_FLOAT, 1 ) +FETCH_ATTRIB( R32G32B32_FLOAT, SZ_3, CVT_32_FLOAT, 1 ) +FETCH_ATTRIB( R32G32_FLOAT, SZ_2, CVT_32_FLOAT, 1 ) +FETCH_ATTRIB( R32_FLOAT, SZ_1, CVT_32_FLOAT, 1 ) + +FETCH_ATTRIB( R32G32B32A32_USCALED, SZ_4, CVT_32_USCALED, 1 ) +FETCH_ATTRIB( R32G32B32_USCALED, SZ_3, CVT_32_USCALED, 1 ) +FETCH_ATTRIB( R32G32_USCALED, SZ_2, CVT_32_USCALED, 1 ) +FETCH_ATTRIB( R32_USCALED, SZ_1, CVT_32_USCALED, 1 ) + +FETCH_ATTRIB( R32G32B32A32_SSCALED, SZ_4, CVT_32_SSCALED, 1 ) +FETCH_ATTRIB( R32G32B32_SSCALED, SZ_3, CVT_32_SSCALED, 1 ) +FETCH_ATTRIB( R32G32_SSCALED, SZ_2, CVT_32_SSCALED, 1 ) +FETCH_ATTRIB( R32_SSCALED, SZ_1, CVT_32_SSCALED, 1 ) + +FETCH_ATTRIB( R32G32B32A32_UNORM, SZ_4, CVT_32_UNORM, 1 ) +FETCH_ATTRIB( R32G32B32_UNORM, SZ_3, CVT_32_UNORM, 1 ) +FETCH_ATTRIB( R32G32_UNORM, SZ_2, CVT_32_UNORM, 1 ) +FETCH_ATTRIB( R32_UNORM, SZ_1, CVT_32_UNORM, 1 ) + +FETCH_ATTRIB( R32G32B32A32_SNORM, SZ_4, CVT_32_SNORM, 1 ) +FETCH_ATTRIB( R32G32B32_SNORM, SZ_3, CVT_32_SNORM, 1 ) +FETCH_ATTRIB( R32G32_SNORM, SZ_2, CVT_32_SNORM, 1 ) +FETCH_ATTRIB( R32_SNORM, SZ_1, CVT_32_SNORM, 1 ) + +FETCH_ATTRIB( R16G16B16A16_USCALED, SZ_4, CVT_16_USCALED, 1 ) +FETCH_ATTRIB( R16G16B16_USCALED, SZ_3, CVT_16_USCALED, 1 ) +FETCH_ATTRIB( R16G16_USCALED, SZ_2, CVT_16_USCALED, 1 ) +FETCH_ATTRIB( R16_USCALED, SZ_1, CVT_16_USCALED, 1 ) + +FETCH_ATTRIB( R16G16B16A16_SSCALED, SZ_4, CVT_16_SSCALED, 1 ) +FETCH_ATTRIB( R16G16B16_SSCALED, SZ_3, CVT_16_SSCALED, 1 ) +FETCH_ATTRIB( R16G16_SSCALED, SZ_2, CVT_16_SSCALED, 1 ) +FETCH_ATTRIB( R16_SSCALED, SZ_1, CVT_16_SSCALED, 1 ) + +FETCH_ATTRIB( R16G16B16A16_UNORM, SZ_4, CVT_16_UNORM, 1 ) +FETCH_ATTRIB( R16G16B16_UNORM, SZ_3, CVT_16_UNORM, 1 ) +FETCH_ATTRIB( R16G16_UNORM, SZ_2, CVT_16_UNORM, 1 ) +FETCH_ATTRIB( R16_UNORM, SZ_1, CVT_16_UNORM, 1 ) + +FETCH_ATTRIB( R16G16B16A16_SNORM, SZ_4, CVT_16_SNORM, 1 ) +FETCH_ATTRIB( R16G16B16_SNORM, SZ_3, CVT_16_SNORM, 1 ) +FETCH_ATTRIB( R16G16_SNORM, SZ_2, CVT_16_SNORM, 1 ) +FETCH_ATTRIB( R16_SNORM, SZ_1, CVT_16_SNORM, 1 ) + +FETCH_ATTRIB( R8G8B8A8_USCALED, SZ_4, CVT_8_USCALED, 1 ) +FETCH_ATTRIB( R8G8B8_USCALED, SZ_3, CVT_8_USCALED, 1 ) +FETCH_ATTRIB( R8G8_USCALED, SZ_2, CVT_8_USCALED, 1 ) +FETCH_ATTRIB( R8_USCALED, SZ_1, CVT_8_USCALED, 1 ) + +FETCH_ATTRIB( R8G8B8A8_SSCALED, SZ_4, CVT_8_SSCALED, 1 ) +FETCH_ATTRIB( R8G8B8_SSCALED, SZ_3, CVT_8_SSCALED, 1 ) +FETCH_ATTRIB( R8G8_SSCALED, SZ_2, CVT_8_SSCALED, 1 ) +FETCH_ATTRIB( R8_SSCALED, SZ_1, CVT_8_SSCALED, 1 ) + +FETCH_ATTRIB( R8G8B8A8_UNORM, SZ_4, CVT_8_UNORM, 1 ) +FETCH_ATTRIB( R8G8B8_UNORM, SZ_3, CVT_8_UNORM, 1 ) +FETCH_ATTRIB( R8G8_UNORM, SZ_2, CVT_8_UNORM, 1 ) +FETCH_ATTRIB( R8_UNORM, SZ_1, CVT_8_UNORM, 1 ) + +FETCH_ATTRIB( R8G8B8A8_SNORM, SZ_4, CVT_8_SNORM, 1 ) +FETCH_ATTRIB( R8G8B8_SNORM, SZ_3, CVT_8_SNORM, 1 ) +FETCH_ATTRIB( R8G8_SNORM, SZ_2, CVT_8_SNORM, 1 ) +FETCH_ATTRIB( R8_SNORM, SZ_1, CVT_8_SNORM, 1 ) + +FETCH_ATTRIB( A8R8G8B8_UNORM, SZ_4, CVT_8_UNORM, 1 ) + + + +static spu_fetch_func get_fetch_func( enum pipe_format format ) +{ + switch (format) { + case PIPE_FORMAT_R64_FLOAT: + return fetch_R64_FLOAT; + case PIPE_FORMAT_R64G64_FLOAT: + return fetch_R64G64_FLOAT; + case PIPE_FORMAT_R64G64B64_FLOAT: + return fetch_R64G64B64_FLOAT; + case PIPE_FORMAT_R64G64B64A64_FLOAT: + return fetch_R64G64B64A64_FLOAT; + + case PIPE_FORMAT_R32_FLOAT: + return fetch_R32_FLOAT; + case PIPE_FORMAT_R32G32_FLOAT: + return fetch_R32G32_FLOAT; + case PIPE_FORMAT_R32G32B32_FLOAT: + return fetch_R32G32B32_FLOAT; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return fetch_R32G32B32A32_FLOAT; + + case PIPE_FORMAT_R32_UNORM: + return fetch_R32_UNORM; + case PIPE_FORMAT_R32G32_UNORM: + return fetch_R32G32_UNORM; + case PIPE_FORMAT_R32G32B32_UNORM: + return fetch_R32G32B32_UNORM; + case PIPE_FORMAT_R32G32B32A32_UNORM: + return fetch_R32G32B32A32_UNORM; + + case PIPE_FORMAT_R32_USCALED: + return fetch_R32_USCALED; + case PIPE_FORMAT_R32G32_USCALED: + return fetch_R32G32_USCALED; + case PIPE_FORMAT_R32G32B32_USCALED: + return fetch_R32G32B32_USCALED; + case PIPE_FORMAT_R32G32B32A32_USCALED: + return fetch_R32G32B32A32_USCALED; + + case PIPE_FORMAT_R32_SNORM: + return fetch_R32_SNORM; + case PIPE_FORMAT_R32G32_SNORM: + return fetch_R32G32_SNORM; + case PIPE_FORMAT_R32G32B32_SNORM: + return fetch_R32G32B32_SNORM; + case PIPE_FORMAT_R32G32B32A32_SNORM: + return fetch_R32G32B32A32_SNORM; + + case PIPE_FORMAT_R32_SSCALED: + return fetch_R32_SSCALED; + case PIPE_FORMAT_R32G32_SSCALED: + return fetch_R32G32_SSCALED; + case PIPE_FORMAT_R32G32B32_SSCALED: + return fetch_R32G32B32_SSCALED; + case PIPE_FORMAT_R32G32B32A32_SSCALED: + return fetch_R32G32B32A32_SSCALED; + + case PIPE_FORMAT_R16_UNORM: + return fetch_R16_UNORM; + case PIPE_FORMAT_R16G16_UNORM: + return fetch_R16G16_UNORM; + case PIPE_FORMAT_R16G16B16_UNORM: + return fetch_R16G16B16_UNORM; + case PIPE_FORMAT_R16G16B16A16_UNORM: + return fetch_R16G16B16A16_UNORM; + + case PIPE_FORMAT_R16_USCALED: + return fetch_R16_USCALED; + case PIPE_FORMAT_R16G16_USCALED: + return fetch_R16G16_USCALED; + case PIPE_FORMAT_R16G16B16_USCALED: + return fetch_R16G16B16_USCALED; + case PIPE_FORMAT_R16G16B16A16_USCALED: + return fetch_R16G16B16A16_USCALED; + + case PIPE_FORMAT_R16_SNORM: + return fetch_R16_SNORM; + case PIPE_FORMAT_R16G16_SNORM: + return fetch_R16G16_SNORM; + case PIPE_FORMAT_R16G16B16_SNORM: + return fetch_R16G16B16_SNORM; + case PIPE_FORMAT_R16G16B16A16_SNORM: + return fetch_R16G16B16A16_SNORM; + + case PIPE_FORMAT_R16_SSCALED: + return fetch_R16_SSCALED; + case PIPE_FORMAT_R16G16_SSCALED: + return fetch_R16G16_SSCALED; + case PIPE_FORMAT_R16G16B16_SSCALED: + return fetch_R16G16B16_SSCALED; + case PIPE_FORMAT_R16G16B16A16_SSCALED: + return fetch_R16G16B16A16_SSCALED; + + case PIPE_FORMAT_R8_UNORM: + return fetch_R8_UNORM; + case PIPE_FORMAT_R8G8_UNORM: + return fetch_R8G8_UNORM; + case PIPE_FORMAT_R8G8B8_UNORM: + return fetch_R8G8B8_UNORM; + case PIPE_FORMAT_R8G8B8A8_UNORM: + return fetch_R8G8B8A8_UNORM; + + case PIPE_FORMAT_R8_USCALED: + return fetch_R8_USCALED; + case PIPE_FORMAT_R8G8_USCALED: + return fetch_R8G8_USCALED; + case PIPE_FORMAT_R8G8B8_USCALED: + return fetch_R8G8B8_USCALED; + case PIPE_FORMAT_R8G8B8A8_USCALED: + return fetch_R8G8B8A8_USCALED; + + case PIPE_FORMAT_R8_SNORM: + return fetch_R8_SNORM; + case PIPE_FORMAT_R8G8_SNORM: + return fetch_R8G8_SNORM; + case PIPE_FORMAT_R8G8B8_SNORM: + return fetch_R8G8B8_SNORM; + case PIPE_FORMAT_R8G8B8A8_SNORM: + return fetch_R8G8B8A8_SNORM; + + case PIPE_FORMAT_R8_SSCALED: + return fetch_R8_SSCALED; + case PIPE_FORMAT_R8G8_SSCALED: + return fetch_R8G8_SSCALED; + case PIPE_FORMAT_R8G8B8_SSCALED: + return fetch_R8G8B8_SSCALED; + case PIPE_FORMAT_R8G8B8A8_SSCALED: + return fetch_R8G8B8A8_SSCALED; + + case PIPE_FORMAT_A8R8G8B8_UNORM: + return fetch_A8R8G8B8_UNORM; + + case 0: + return NULL; /* not sure why this is needed */ + + default: + assert(0); + return NULL; + } +} + + +static unsigned get_vertex_size( enum pipe_format format ) +{ + switch (format) { + case PIPE_FORMAT_R64_FLOAT: + return 8; + case PIPE_FORMAT_R64G64_FLOAT: + return 2 * 8; + case PIPE_FORMAT_R64G64B64_FLOAT: + return 3 * 8; + case PIPE_FORMAT_R64G64B64A64_FLOAT: + return 4 * 8; + + case PIPE_FORMAT_R32_SSCALED: + case PIPE_FORMAT_R32_SNORM: + case PIPE_FORMAT_R32_USCALED: + case PIPE_FORMAT_R32_UNORM: + case PIPE_FORMAT_R32_FLOAT: + return 4; + case PIPE_FORMAT_R32G32_SSCALED: + case PIPE_FORMAT_R32G32_SNORM: + case PIPE_FORMAT_R32G32_USCALED: + case PIPE_FORMAT_R32G32_UNORM: + case PIPE_FORMAT_R32G32_FLOAT: + return 2 * 4; + case PIPE_FORMAT_R32G32B32_SSCALED: + case PIPE_FORMAT_R32G32B32_SNORM: + case PIPE_FORMAT_R32G32B32_USCALED: + case PIPE_FORMAT_R32G32B32_UNORM: + case PIPE_FORMAT_R32G32B32_FLOAT: + return 3 * 4; + case PIPE_FORMAT_R32G32B32A32_SSCALED: + case PIPE_FORMAT_R32G32B32A32_SNORM: + case PIPE_FORMAT_R32G32B32A32_USCALED: + case PIPE_FORMAT_R32G32B32A32_UNORM: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return 4 * 4; + + case PIPE_FORMAT_R16_SSCALED: + case PIPE_FORMAT_R16_SNORM: + case PIPE_FORMAT_R16_UNORM: + case PIPE_FORMAT_R16_USCALED: + return 2; + case PIPE_FORMAT_R16G16_SSCALED: + case PIPE_FORMAT_R16G16_SNORM: + case PIPE_FORMAT_R16G16_USCALED: + case PIPE_FORMAT_R16G16_UNORM: + return 2 * 2; + case PIPE_FORMAT_R16G16B16_SSCALED: + case PIPE_FORMAT_R16G16B16_SNORM: + case PIPE_FORMAT_R16G16B16_USCALED: + case PIPE_FORMAT_R16G16B16_UNORM: + return 3 * 2; + case PIPE_FORMAT_R16G16B16A16_SSCALED: + case PIPE_FORMAT_R16G16B16A16_SNORM: + case PIPE_FORMAT_R16G16B16A16_USCALED: + case PIPE_FORMAT_R16G16B16A16_UNORM: + return 4 * 2; + + case PIPE_FORMAT_R8_SSCALED: + case PIPE_FORMAT_R8_SNORM: + case PIPE_FORMAT_R8_USCALED: + case PIPE_FORMAT_R8_UNORM: + return 1; + case PIPE_FORMAT_R8G8_SSCALED: + case PIPE_FORMAT_R8G8_SNORM: + case PIPE_FORMAT_R8G8_USCALED: + case PIPE_FORMAT_R8G8_UNORM: + return 2 * 1; + case PIPE_FORMAT_R8G8B8_SSCALED: + case PIPE_FORMAT_R8G8B8_SNORM: + case PIPE_FORMAT_R8G8B8_USCALED: + case PIPE_FORMAT_R8G8B8_UNORM: + return 3 * 1; + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R8G8B8A8_SSCALED: + case PIPE_FORMAT_R8G8B8A8_SNORM: + case PIPE_FORMAT_R8G8B8A8_USCALED: + case PIPE_FORMAT_R8G8B8A8_UNORM: + return 4 * 1; + + case 0: + return 0; /* not sure why this is needed */ + + default: + assert(0); + return 0; + } +} + + +/** + * Fetch vertex attributes for 'count' vertices. + */ +static void generic_vertex_fetch(struct spu_vs_context *draw, + struct spu_exec_machine *machine, + const unsigned *elts, + unsigned count) +{ + unsigned nr_attrs = draw->vertex_fetch.nr_attrs; + unsigned attr; + + assert(count <= 4); + +#if DRAW_DBG + printf("SPU: %s count = %u, nr_attrs = %u\n", + __FUNCTION__, count, nr_attrs); +#endif + + /* loop over vertex attributes (vertex shader inputs) + */ + for (attr = 0; attr < nr_attrs; attr++) { + const qword default_values = (qword)(vec_float4){ 0.0, 0.0, 0.0, 1.0 }; + const unsigned pitch = draw->vertex_fetch.pitch[attr]; + const uint64_t src = draw->vertex_fetch.src_ptr[attr]; + const spu_fetch_func fetch = draw->vertex_fetch.fetch[attr]; + unsigned i; + unsigned idx; + const unsigned bytes_per_entry = draw->vertex_fetch.size[attr]; + const unsigned quads_per_entry = (bytes_per_entry + 15) / 16; + qword in[2 * 4]; + + + /* Fetch four attributes for four vertices. + */ + idx = 0; + for (i = 0; i < count; i++) { + const uint64_t addr = src + (elts[i] * pitch); + +#if DRAW_DBG + printf("SPU: fetching = 0x%llx\n", addr); +#endif + + fetch_unaligned(& in[idx], addr, bytes_per_entry); + idx += quads_per_entry; + } + + /* Be nice and zero out any missing vertices. + */ + (void) memset(& in[idx], 0, (8 - idx) * sizeof(qword)); + + + /* Convert all 4 vertices to vectors of float. + */ + (*fetch)(&machine->Inputs[attr].xyzw[0].q, in, default_values, + fetch_shuffle_data); + } +} + + +void spu_update_vertex_fetch( struct spu_vs_context *draw ) +{ + unsigned i; + + + /* Invalidate the vertex cache. + */ + for (i = 0; i < (CACHE_NWAY * CACHE_NSETS); i++) { + CACHELINE_CLEARVALID(i); + } + + + for (i = 0; i < draw->vertex_fetch.nr_attrs; i++) { + draw->vertex_fetch.fetch[i] = + get_fetch_func(draw->vertex_fetch.format[i]); + draw->vertex_fetch.size[i] = + get_vertex_size(draw->vertex_fetch.format[i]); + } + + draw->vertex_fetch.fetch_func = generic_vertex_fetch; +} diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c new file mode 100644 index 0000000000..c1cbbb6d1e --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c @@ -0,0 +1,231 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + * Brian Paul + * Ian Romanick + */ + +#include + +#include "pipe/p_util.h" +#include "pipe/p_state.h" +#include "pipe/p_shader_tokens.h" +#include "spu_vertex_shader.h" +#include "spu_exec.h" +#include "pipe/draw/draw_private.h" +#include "pipe/draw/draw_context.h" +#include "pipe/cell/common.h" +#include "spu_main.h" + +static INLINE unsigned +compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) +{ + unsigned mask = 0; + unsigned i; + + /* Do the hardwired planes first: + */ + if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; + if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; + if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; + if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; + if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; + if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; + + /* Followed by any remaining ones: + */ + for (i = 6; i < nr; i++) { + if (dot4(clip, plane[i]) < 0) + mask |= (1<machine; + unsigned int j; + + ALIGN16_DECL(struct spu_exec_vector, inputs, PIPE_ATTRIB_MAX); + ALIGN16_DECL(struct spu_exec_vector, outputs, PIPE_ATTRIB_MAX); + const float *scale = draw->viewport.scale; + const float *trans = draw->viewport.translate; + + assert(count <= 4); + + machine->Processor = TGSI_PROCESSOR_VERTEX; + + ASSERT_ALIGN16(draw->constants); + machine->Consts = (float (*)[4]) draw->constants; + + machine->Inputs = ALIGN16_ASSIGN(inputs); + machine->Outputs = ALIGN16_ASSIGN(outputs); + + spu_vertex_fetch( draw, machine, elts, count ); + + /* run shader */ + spu_exec_machine_run( machine ); + + + /* store machine results */ + for (j = 0; j < count; j++) { + unsigned slot; + float x, y, z, w; + unsigned char buffer[sizeof(struct vertex_header) + + MAX_VERTEX_SIZE] ALIGN16_ATTRIB; + struct vertex_header *const tmpOut = + (struct vertex_header *) buffer; + const unsigned vert_size = ROUNDUP16(sizeof(struct vertex_header) + + (sizeof(float) * 4 + * draw->num_vs_outputs)); + + mfc_get(tmpOut, vOut[j], vert_size, TAG_VERTEX_BUFFER, 0, 0); + wait_on_mask(1 << TAG_VERTEX_BUFFER); + + + /* Handle attr[0] (position) specially: + * + * XXX: Computing the clipmask should be done in the vertex + * program as a set of DP4 instructions appended to the + * user-provided code. + */ + x = tmpOut->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = tmpOut->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = tmpOut->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = tmpOut->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + + tmpOut->clipmask = compute_clipmask(tmpOut->clip, draw->plane, + draw->nr_planes); + tmpOut->edgeflag = 1; + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; + + /* Viewport mapping */ + tmpOut->data[0][0] = x * scale[0] + trans[0]; + tmpOut->data[0][1] = y * scale[1] + trans[1]; + tmpOut->data[0][2] = z * scale[2] + trans[2]; + tmpOut->data[0][3] = w; + + /* Remaining attributes are packed into sequential post-transform + * vertex attrib slots. + */ + for (slot = 1; slot < draw->num_vs_outputs; slot++) { + tmpOut->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + tmpOut->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + tmpOut->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + tmpOut->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + + mfc_put(tmpOut, vOut[j], vert_size, TAG_VERTEX_BUFFER, 0, 0); + } /* loop over vertices */ +} + + +static void +spu_bind_vertex_shader(struct spu_vs_context *draw, + void *uniforms, + void *planes, + unsigned nr_planes, + unsigned num_outputs + ) +{ + draw->constants = (float (*)[4]) uniforms; + + (void) memcpy(draw->plane, planes, sizeof(float) * 4 * nr_planes); + draw->nr_planes = nr_planes; + draw->num_vs_outputs = num_outputs; + + /* specify the shader to interpret/execute */ + spu_exec_machine_init(&draw->machine, + PIPE_MAX_SAMPLERS, + NULL /*samplers*/, + PIPE_SHADER_VERTEX); +} + + +unsigned char immediates[(sizeof(float) * 4 * TGSI_EXEC_NUM_IMMEDIATES) + 32] + ALIGN16_ATTRIB; + +void +spu_execute_vertex_shader(struct spu_vs_context *draw, + const struct cell_command_vs *vs) +{ + unsigned i; + + const uint64_t immediate_addr = vs->shader.immediates; + const unsigned immediate_size = + ROUNDUP16((sizeof(float) * 4 * vs->shader.num_immediates) + + (immediate_addr & 0x0f)); + + mfc_get(immediates, immediate_addr & ~0x0f, immediate_size, + TAG_VERTEX_BUFFER, 0, 0); + + draw->machine.Instructions = (struct tgsi_full_instruction *) + vs->shader.instructions; + draw->machine.NumInstructions = vs->shader.num_instructions; + + draw->machine.Declarations = (struct tgsi_full_declaration *) + vs->shader.declarations; + draw->machine.NumDeclarations = vs->shader.num_declarations; + + draw->vertex_fetch.nr_attrs = vs->nr_attrs; + + wait_on_mask(1 << TAG_VERTEX_BUFFER); + + (void) memcpy(& draw->machine.Imms, &immediates[immediate_addr & 0x0f], + sizeof(float) * 4 * vs->shader.num_immediates); + + spu_bind_vertex_shader(draw, vs->shader.uniforms, + vs->plane, vs->nr_planes, + vs->shader.num_outputs); + + for (i = 0; i < vs->num_elts; i += 4) { + const unsigned batch_size = MIN2(vs->num_elts - i, 4); + + run_vertex_program(draw, & vs->elts[i], batch_size, &vs->vOut[i]); + } +} diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.h b/src/gallium/drivers/cell/spu/spu_vertex_shader.h new file mode 100644 index 0000000000..b5bf31e67d --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.h @@ -0,0 +1,63 @@ +#ifndef SPU_VERTEX_SHADER_H +#define SPU_VERTEX_SHADER_H + +#include "pipe/p_format.h" +#include "spu_exec.h" + +struct spu_vs_context; + +typedef void (*spu_fetch_func)(qword *out, const qword *in, qword defaults, + const qword *shuffle_data); +typedef void (*spu_full_fetch_func)( struct spu_vs_context *draw, + struct spu_exec_machine *machine, + const unsigned *elts, + unsigned count ); + +struct spu_vs_context { + struct pipe_viewport_state viewport; + + struct { + uint64_t src_ptr[PIPE_ATTRIB_MAX]; + unsigned pitch[PIPE_ATTRIB_MAX]; + unsigned size[PIPE_ATTRIB_MAX]; + enum pipe_format format[PIPE_ATTRIB_MAX]; + unsigned nr_attrs; + boolean dirty; + + spu_fetch_func fetch[PIPE_ATTRIB_MAX]; + spu_full_fetch_func fetch_func; + } vertex_fetch; + + /* Clip derived state: + */ + float plane[12][4]; + unsigned nr_planes; + + struct spu_exec_machine machine; + const float (*constants)[4]; + + unsigned num_vs_outputs; +}; + +extern void spu_update_vertex_fetch(struct spu_vs_context *draw); + +static INLINE void spu_vertex_fetch(struct spu_vs_context *draw, + struct spu_exec_machine *machine, + const unsigned *elts, + unsigned count) +{ + if (draw->vertex_fetch.dirty) { + spu_update_vertex_fetch(draw); + draw->vertex_fetch.dirty = 0; + } + + (*draw->vertex_fetch.fetch_func)(draw, machine, elts, count); +} + +struct cell_command_vs; + +extern void +spu_execute_vertex_shader(struct spu_vs_context *draw, + const struct cell_command_vs *vs); + +#endif /* SPU_VERTEX_SHADER_H */ diff --git a/src/gallium/drivers/cell/spu/spu_ztest.h b/src/gallium/drivers/cell/spu/spu_ztest.h new file mode 100644 index 0000000000..ce8ad00339 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_ztest.h @@ -0,0 +1,135 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Zbuffer/depth test code. + */ + + +#ifndef SPU_ZTEST_H +#define SPU_ZTEST_H + + +#ifdef __SPU__ +#include +#endif + + + +/** + * Perform Z testing for a 16-bit/value Z buffer. + * + * \param zvals vector of four fragment zvalues as floats + * \param zbuf ptr to vector of ushort[8] zbuffer values. Note that this + * contains the Z values for 2 quads, 8 pixels. + * \param x x coordinate of quad (only lsbit is significant) + * \param inMask indicates which fragments in the quad are alive + * \return new mask indicating which fragments are alive after ztest + */ +static INLINE vector unsigned int +spu_z16_test_less(vector float zvals, vector unsigned short *zbuf, + uint x, vector unsigned int inMask) +{ +#define ZERO 0x80 + vector unsigned int zvals_ui4, zbuf_ui4, mask; + + /* convert floats to uints in [0, 65535] */ + zvals_ui4 = spu_convtu(zvals, 32); /* convert to [0, 2^32] */ + zvals_ui4 = spu_rlmask(zvals_ui4, -16); /* right shift 16 */ + + /* XXX this conditional could be removed with a bit of work */ + if (x & 1) { + /* convert zbuffer values from ushorts to uints */ + /* gather lower four ushorts */ + zbuf_ui4 = spu_shuffle((vector unsigned int) *zbuf, + (vector unsigned int) *zbuf, + ((vector unsigned char) { + ZERO, ZERO, 8, 9, ZERO, ZERO, 10, 11, + ZERO, ZERO, 12, 13, ZERO, ZERO, 14, 15})); + /* mask = (zbuf_ui4 < zvals_ui4) ? ~0 : 0 */ + mask = spu_cmpgt(zbuf_ui4, zvals_ui4); + /* mask &= inMask */ + mask = spu_and(mask, inMask); + /* zbuf = mask ? zval : zbuf */ + zbuf_ui4 = spu_sel(zbuf_ui4, zvals_ui4, mask); + /* convert zbuffer values from uints back to ushorts, preserve lower 4 */ + *zbuf = (vector unsigned short) + spu_shuffle(zbuf_ui4, (vector unsigned int) *zbuf, + ((vector unsigned char) { + 16, 17, 18, 19, 20, 21, 22, 23, + 2, 3, 6, 7, 10, 11, 14, 15})); + } + else { + /* convert zbuffer values from ushorts to uints */ + /* gather upper four ushorts */ + zbuf_ui4 = spu_shuffle((vector unsigned int) *zbuf, + (vector unsigned int) *zbuf, + ((vector unsigned char) { + ZERO, ZERO, 0, 1, ZERO, ZERO, 2, 3, + ZERO, ZERO, 4, 5, ZERO, ZERO, 6, 7})); + /* mask = (zbuf_ui4 < zvals_ui4) ? ~0 : 0 */ + mask = spu_cmpgt(zbuf_ui4, zvals_ui4); + /* mask &= inMask */ + mask = spu_and(mask, inMask); + /* zbuf = mask ? zval : zbuf */ + zbuf_ui4 = spu_sel(zbuf_ui4, zvals_ui4, mask); + /* convert zbuffer values from uints back to ushorts, preserve upper 4 */ + *zbuf = (vector unsigned short) + spu_shuffle(zbuf_ui4, (vector unsigned int) *zbuf, + ((vector unsigned char) { + 2, 3, 6, 7, 10, 11, 14, 15, + 24, 25, 26, 27, 28, 29, 30, 31})); + } + return mask; +#undef ZERO +} + + +/** + * As above, but Zbuffer values as 32-bit uints + */ +static INLINE vector unsigned int +spu_z32_test_less(vector float zvals, vector unsigned int *zbuf_ptr, + vector unsigned int inMask) +{ + vector unsigned int zvals_ui4, mask, zbuf = *zbuf_ptr; + + /* convert floats to uints in [0, 0xffffffff] */ + zvals_ui4 = spu_convtu(zvals, 32); + /* mask = (zbuf < zvals_ui4) ? ~0 : 0 */ + mask = spu_cmpgt(zbuf, zvals_ui4); + /* mask &= inMask */ + mask = spu_and(mask, inMask); + /* zbuf = mask ? zval : zbuf */ + *zbuf_ptr = spu_sel(zbuf, zvals_ui4, mask); + + return mask; +} + + +#endif /* SPU_ZTEST_H */ diff --git a/src/gallium/drivers/failover/Makefile b/src/gallium/drivers/failover/Makefile new file mode 100644 index 0000000000..72d0895c74 --- /dev/null +++ b/src/gallium/drivers/failover/Makefile @@ -0,0 +1,21 @@ + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = failover + +DRIVER_SOURCES = \ + fo_state.c \ + fo_state_emit.c \ + fo_context.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c new file mode 100644 index 0000000000..7ce4a7df17 --- /dev/null +++ b/src/gallium/drivers/failover/fo_context.c @@ -0,0 +1,155 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_context.h" + +#include "fo_context.h" +#include "fo_winsys.h" + + + +static void failover_destroy( struct pipe_context *pipe ) +{ + struct failover_context *failover = failover_context( pipe ); + + free( failover ); +} + + + +static boolean failover_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned prim, unsigned start, unsigned count) +{ + struct failover_context *failover = failover_context( pipe ); + + /* If there has been any statechange since last time, try hardware + * rendering again: + */ + if (failover->dirty) { + failover->mode = FO_HW; + } + + /* Try hardware: + */ + if (failover->mode == FO_HW) { + if (!failover->hw->draw_elements( failover->hw, + indexBuffer, + indexSize, + prim, + start, + count )) { + + failover->hw->flush( failover->hw, ~0 ); + failover->mode = FO_SW; + } + } + + /* Possibly try software: + */ + if (failover->mode == FO_SW) { + + if (failover->dirty) + failover_state_emit( failover ); + + failover->sw->draw_elements( failover->sw, + indexBuffer, + indexSize, + prim, + start, + count ); + + /* Be ready to switch back to hardware rendering without an + * intervening flush. Unlikely to be much performance impact to + * this: + */ + failover->sw->flush( failover->sw, ~0 ); + } + + return TRUE; +} + + +static boolean failover_draw_arrays( struct pipe_context *pipe, + unsigned prim, unsigned start, unsigned count) +{ + return failover_draw_elements(pipe, NULL, 0, prim, start, count); +} + + + +struct pipe_context *failover_create( struct pipe_context *hw, + struct pipe_context *sw ) +{ + struct failover_context *failover = CALLOC_STRUCT(failover_context); + if (failover == NULL) + return NULL; + + failover->hw = hw; + failover->sw = sw; + failover->pipe.winsys = hw->winsys; + failover->pipe.destroy = failover_destroy; + failover->pipe.is_format_supported = hw->is_format_supported; + failover->pipe.get_name = hw->get_name; + failover->pipe.get_vendor = hw->get_vendor; + failover->pipe.get_param = hw->get_param; + failover->pipe.get_paramf = hw->get_paramf; + + failover->pipe.draw_arrays = failover_draw_arrays; + failover->pipe.draw_elements = failover_draw_elements; + failover->pipe.clear = hw->clear; + + /* No software occlusion fallback (or other optional functionality) + * at this point - if the hardware doesn't support it, don't + * advertise it to the application. + */ + failover->pipe.begin_query = hw->begin_query; + failover->pipe.end_query = hw->end_query; + + failover_init_state_functions( failover ); + +#if 0 + failover->pipe.surface_alloc = hw->surface_alloc; +#endif + failover->pipe.get_tex_surface = hw->get_tex_surface; + + failover->pipe.surface_copy = hw->surface_copy; + failover->pipe.surface_fill = hw->surface_fill; + failover->pipe.texture_create = hw->texture_create; + failover->pipe.texture_release = hw->texture_release; + failover->pipe.flush = hw->flush; + + failover->dirty = 0; + + return &failover->pipe; +} + diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h new file mode 100644 index 0000000000..1dc87291c9 --- /dev/null +++ b/src/gallium/drivers/failover/fo_context.h @@ -0,0 +1,114 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef FO_CONTEXT_H +#define FO_CONTEXT_H + +#include "pipe/p_state.h" +#include "pipe/p_context.h" + + + +#define FO_NEW_VIEWPORT 0x1 +#define FO_NEW_RASTERIZER 0x2 +#define FO_NEW_FRAGMENT_SHADER 0x4 +#define FO_NEW_BLEND 0x8 +#define FO_NEW_CLIP 0x10 +#define FO_NEW_SCISSOR 0x20 +#define FO_NEW_STIPPLE 0x40 +#define FO_NEW_FRAMEBUFFER 0x80 +#define FO_NEW_ALPHA_TEST 0x100 +#define FO_NEW_DEPTH_STENCIL 0x200 +#define FO_NEW_SAMPLER 0x400 +#define FO_NEW_TEXTURE 0x800 +#define FO_NEW_VERTEX 0x2000 +#define FO_NEW_VERTEX_SHADER 0x4000 +#define FO_NEW_BLEND_COLOR 0x8000 +#define FO_NEW_CLEAR_COLOR 0x10000 +#define FO_NEW_VERTEX_BUFFER 0x20000 +#define FO_NEW_VERTEX_ELEMENT 0x40000 + + + +#define FO_HW 0 +#define FO_SW 1 + +struct fo_state { + void *sw_state; + void *hw_state; +}; +struct failover_context { + struct pipe_context pipe; /**< base class */ + + + /* The most recent drawing state as set by the driver: + */ + const struct fo_state *blend; + const struct fo_state *sampler[PIPE_MAX_SAMPLERS]; + const struct fo_state *depth_stencil; + const struct fo_state *rasterizer; + const struct fo_state *fragment_shader; + const struct fo_state *vertex_shader; + + struct pipe_blend_color blend_color; + struct pipe_clip_state clip; + struct pipe_framebuffer_state framebuffer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + + unsigned dirty; + unsigned dirty_sampler; + unsigned dirty_texture; + unsigned dirty_vertex_buffer; + unsigned dirty_vertex_element; + + + unsigned mode; + struct pipe_context *hw; + struct pipe_context *sw; +}; + + + +void failover_init_state_functions( struct failover_context *failover ); +void failover_state_emit( struct failover_context *failover ); + +static INLINE struct failover_context * +failover_context( struct pipe_context *pipe ) +{ + return (struct failover_context *)pipe; +} + + +#endif /* FO_CONTEXT_H */ diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c new file mode 100644 index 0000000000..0fc5568da1 --- /dev/null +++ b/src/gallium/drivers/failover/fo_state.c @@ -0,0 +1,457 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "fo_context.h" + + +/* This looks like a lot of work at the moment - we're keeping a + * duplicate copy of the state up-to-date. + * + * This can change in two ways: + * - With constant state objects we would only need to save a pointer, + * not the whole object. + * - By adding a callback in the state tracker to re-emit state. The + * state tracker knows the current state already and can re-emit it + * without additional complexity. + * + * This works as a proof-of-concept, but a final version will have + * lower overheads. + */ + + + +static void * +failover_create_blend_state( struct pipe_context *pipe, + const struct pipe_blend_state *blend ) +{ + struct fo_state *state = malloc(sizeof(struct fo_state)); + struct failover_context *failover = failover_context(pipe); + + state->sw_state = failover->sw->create_blend_state(failover->sw, blend); + state->hw_state = failover->hw->create_blend_state(failover->hw, blend); + + return state; +} + +static void +failover_bind_blend_state( struct pipe_context *pipe, + void *blend ) +{ + struct failover_context *failover = failover_context(pipe); + struct fo_state *state = (struct fo_state *)blend; + failover->blend = state; + failover->dirty |= FO_NEW_BLEND; + failover->sw->bind_blend_state( failover->sw, state->sw_state ); + failover->hw->bind_blend_state( failover->hw, state->hw_state ); +} + +static void +failover_delete_blend_state( struct pipe_context *pipe, + void *blend ) +{ + struct fo_state *state = (struct fo_state*)blend; + struct failover_context *failover = failover_context(pipe); + + failover->sw->delete_blend_state(failover->sw, state->sw_state); + failover->hw->delete_blend_state(failover->hw, state->hw_state); + state->sw_state = 0; + state->hw_state = 0; + free(state); +} + +static void +failover_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ) +{ + struct failover_context *failover = failover_context(pipe); + + failover->blend_color = *blend_color; + failover->dirty |= FO_NEW_BLEND_COLOR; + failover->sw->set_blend_color( failover->sw, blend_color ); + failover->hw->set_blend_color( failover->hw, blend_color ); +} + +static void +failover_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct failover_context *failover = failover_context(pipe); + + failover->clip = *clip; + failover->dirty |= FO_NEW_CLIP; + failover->sw->set_clip_state( failover->sw, clip ); + failover->hw->set_clip_state( failover->hw, clip ); +} + + +static void * +failover_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *templ) +{ + struct fo_state *state = malloc(sizeof(struct fo_state)); + struct failover_context *failover = failover_context(pipe); + + state->sw_state = failover->sw->create_depth_stencil_alpha_state(failover->sw, templ); + state->hw_state = failover->hw->create_depth_stencil_alpha_state(failover->hw, templ); + + return state; +} + +static void +failover_bind_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct failover_context *failover = failover_context(pipe); + struct fo_state *state = (struct fo_state *)depth_stencil; + failover->depth_stencil = state; + failover->dirty |= FO_NEW_DEPTH_STENCIL; + failover->sw->bind_depth_stencil_alpha_state(failover->sw, state->sw_state); + failover->hw->bind_depth_stencil_alpha_state(failover->hw, state->hw_state); +} + +static void +failover_delete_depth_stencil_state(struct pipe_context *pipe, + void *ds) +{ + struct fo_state *state = (struct fo_state*)ds; + struct failover_context *failover = failover_context(pipe); + + failover->sw->delete_depth_stencil_alpha_state(failover->sw, state->sw_state); + failover->hw->delete_depth_stencil_alpha_state(failover->hw, state->hw_state); + state->sw_state = 0; + state->hw_state = 0; + free(state); +} + +static void +failover_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *framebuffer) +{ + struct failover_context *failover = failover_context(pipe); + + failover->framebuffer = *framebuffer; + failover->dirty |= FO_NEW_FRAMEBUFFER; + failover->sw->set_framebuffer_state( failover->sw, framebuffer ); + failover->hw->set_framebuffer_state( failover->hw, framebuffer ); +} + + +static void * +failover_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct fo_state *state = malloc(sizeof(struct fo_state)); + struct failover_context *failover = failover_context(pipe); + + state->sw_state = failover->sw->create_fs_state(failover->sw, templ); + state->hw_state = failover->hw->create_fs_state(failover->hw, templ); + + return state; +} + +static void +failover_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct failover_context *failover = failover_context(pipe); + struct fo_state *state = (struct fo_state*)fs; + failover->fragment_shader = state; + failover->dirty |= FO_NEW_FRAGMENT_SHADER; + failover->sw->bind_fs_state(failover->sw, state->sw_state); + failover->hw->bind_fs_state(failover->hw, state->hw_state); +} + +static void +failover_delete_fs_state(struct pipe_context *pipe, + void *fs) +{ + struct fo_state *state = (struct fo_state*)fs; + struct failover_context *failover = failover_context(pipe); + + failover->sw->delete_fs_state(failover->sw, state->sw_state); + failover->hw->delete_fs_state(failover->hw, state->hw_state); + state->sw_state = 0; + state->hw_state = 0; + free(state); +} + +static void * +failover_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct fo_state *state = malloc(sizeof(struct fo_state)); + struct failover_context *failover = failover_context(pipe); + + state->sw_state = failover->sw->create_vs_state(failover->sw, templ); + state->hw_state = failover->hw->create_vs_state(failover->hw, templ); + + return state; +} + +static void +failover_bind_vs_state(struct pipe_context *pipe, + void *vs) +{ + struct failover_context *failover = failover_context(pipe); + + struct fo_state *state = (struct fo_state*)vs; + failover->vertex_shader = state; + failover->dirty |= FO_NEW_VERTEX_SHADER; + failover->sw->bind_vs_state(failover->sw, state->sw_state); + failover->hw->bind_vs_state(failover->hw, state->hw_state); +} + +static void +failover_delete_vs_state(struct pipe_context *pipe, + void *vs) +{ + struct fo_state *state = (struct fo_state*)vs; + struct failover_context *failover = failover_context(pipe); + + failover->sw->delete_vs_state(failover->sw, state->sw_state); + failover->hw->delete_vs_state(failover->hw, state->hw_state); + state->sw_state = 0; + state->hw_state = 0; + free(state); +} + +static void +failover_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ + struct failover_context *failover = failover_context(pipe); + + failover->poly_stipple = *stipple; + failover->dirty |= FO_NEW_STIPPLE; + failover->sw->set_polygon_stipple( failover->sw, stipple ); + failover->hw->set_polygon_stipple( failover->hw, stipple ); +} + + +static void * +failover_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *templ) +{ + struct fo_state *state = malloc(sizeof(struct fo_state)); + struct failover_context *failover = failover_context(pipe); + + state->sw_state = failover->sw->create_rasterizer_state(failover->sw, templ); + state->hw_state = failover->hw->create_rasterizer_state(failover->hw, templ); + + return state; +} + +static void +failover_bind_rasterizer_state(struct pipe_context *pipe, + void *raster) +{ + struct failover_context *failover = failover_context(pipe); + + struct fo_state *state = (struct fo_state*)raster; + failover->rasterizer = state; + failover->dirty |= FO_NEW_RASTERIZER; + failover->sw->bind_rasterizer_state(failover->sw, state->sw_state); + failover->hw->bind_rasterizer_state(failover->hw, state->hw_state); +} + +static void +failover_delete_rasterizer_state(struct pipe_context *pipe, + void *raster) +{ + struct fo_state *state = (struct fo_state*)raster; + struct failover_context *failover = failover_context(pipe); + + failover->sw->delete_rasterizer_state(failover->sw, state->sw_state); + failover->hw->delete_rasterizer_state(failover->hw, state->hw_state); + state->sw_state = 0; + state->hw_state = 0; + free(state); +} + + +static void +failover_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct failover_context *failover = failover_context(pipe); + + failover->scissor = *scissor; + failover->dirty |= FO_NEW_SCISSOR; + failover->sw->set_scissor_state( failover->sw, scissor ); + failover->hw->set_scissor_state( failover->hw, scissor ); +} + + +static void * +failover_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *templ) +{ + struct fo_state *state = malloc(sizeof(struct fo_state)); + struct failover_context *failover = failover_context(pipe); + + state->sw_state = failover->sw->create_sampler_state(failover->sw, templ); + state->hw_state = failover->hw->create_sampler_state(failover->hw, templ); + + return state; +} + +static void +failover_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, void *sampler) +{ + struct failover_context *failover = failover_context(pipe); + struct fo_state *state = (struct fo_state*)sampler; + failover->sampler[unit] = state; + failover->dirty |= FO_NEW_SAMPLER; + failover->dirty_sampler |= (1<sw->bind_sampler_state(failover->sw, unit, + state->sw_state); + failover->hw->bind_sampler_state(failover->hw, unit, + state->hw_state); +} + +static void +failover_delete_sampler_state(struct pipe_context *pipe, void *sampler) +{ + struct fo_state *state = (struct fo_state*)sampler; + struct failover_context *failover = failover_context(pipe); + + failover->sw->delete_sampler_state(failover->sw, state->sw_state); + failover->hw->delete_sampler_state(failover->hw, state->hw_state); + state->sw_state = 0; + state->hw_state = 0; + free(state); +} + + +static void +failover_set_sampler_texture(struct pipe_context *pipe, + unsigned unit, + struct pipe_texture *texture) +{ + struct failover_context *failover = failover_context(pipe); + + failover->texture[unit] = texture; + failover->dirty |= FO_NEW_TEXTURE; + failover->dirty_texture |= (1<sw->set_sampler_texture( failover->sw, unit, texture ); + failover->hw->set_sampler_texture( failover->hw, unit, texture ); +} + + +static void +failover_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct failover_context *failover = failover_context(pipe); + + failover->viewport = *viewport; + failover->dirty |= FO_NEW_VIEWPORT; + failover->sw->set_viewport_state( failover->sw, viewport ); + failover->hw->set_viewport_state( failover->hw, viewport ); +} + + +static void +failover_set_vertex_buffer(struct pipe_context *pipe, + unsigned unit, + const struct pipe_vertex_buffer *vertex_buffer) +{ + struct failover_context *failover = failover_context(pipe); + + failover->vertex_buffer[unit] = *vertex_buffer; + failover->dirty |= FO_NEW_VERTEX_BUFFER; + failover->dirty_vertex_buffer |= (1<sw->set_vertex_buffer( failover->sw, unit, vertex_buffer ); + failover->hw->set_vertex_buffer( failover->hw, unit, vertex_buffer ); +} + + +static void +failover_set_vertex_element(struct pipe_context *pipe, + unsigned unit, + const struct pipe_vertex_element *vertex_element) +{ + struct failover_context *failover = failover_context(pipe); + + failover->vertex_element[unit] = *vertex_element; + failover->dirty |= FO_NEW_VERTEX_ELEMENT; + failover->dirty_vertex_element |= (1<sw->set_vertex_element( failover->sw, unit, vertex_element ); + failover->hw->set_vertex_element( failover->hw, unit, vertex_element ); +} + +void +failover_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct failover_context *failover = failover_context(pipe); + + assert(shader < PIPE_SHADER_TYPES); + assert(index == 0); + + failover->sw->set_constant_buffer(failover->sw, shader, index, buf); + failover->hw->set_constant_buffer(failover->hw, shader, index, buf); +} + + +void +failover_init_state_functions( struct failover_context *failover ) +{ + failover->pipe.create_blend_state = failover_create_blend_state; + failover->pipe.bind_blend_state = failover_bind_blend_state; + failover->pipe.delete_blend_state = failover_delete_blend_state; + failover->pipe.create_sampler_state = failover_create_sampler_state; + failover->pipe.bind_sampler_state = failover_bind_sampler_state; + failover->pipe.delete_sampler_state = failover_delete_sampler_state; + failover->pipe.create_depth_stencil_alpha_state = failover_create_depth_stencil_state; + failover->pipe.bind_depth_stencil_alpha_state = failover_bind_depth_stencil_state; + failover->pipe.delete_depth_stencil_alpha_state = failover_delete_depth_stencil_state; + failover->pipe.create_rasterizer_state = failover_create_rasterizer_state; + failover->pipe.bind_rasterizer_state = failover_bind_rasterizer_state; + failover->pipe.delete_rasterizer_state = failover_delete_rasterizer_state; + failover->pipe.create_fs_state = failover_create_fs_state; + failover->pipe.bind_fs_state = failover_bind_fs_state; + failover->pipe.delete_fs_state = failover_delete_fs_state; + failover->pipe.create_vs_state = failover_create_vs_state; + failover->pipe.bind_vs_state = failover_bind_vs_state; + failover->pipe.delete_vs_state = failover_delete_vs_state; + + failover->pipe.set_blend_color = failover_set_blend_color; + failover->pipe.set_clip_state = failover_set_clip_state; + failover->pipe.set_framebuffer_state = failover_set_framebuffer_state; + failover->pipe.set_polygon_stipple = failover_set_polygon_stipple; + failover->pipe.set_scissor_state = failover_set_scissor_state; + failover->pipe.set_sampler_texture = failover_set_sampler_texture; + failover->pipe.set_viewport_state = failover_set_viewport_state; + failover->pipe.set_vertex_buffer = failover_set_vertex_buffer; + failover->pipe.set_vertex_element = failover_set_vertex_element; + failover->pipe.set_constant_buffer = failover_set_constant_buffer; +} diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c new file mode 100644 index 0000000000..c663dd4947 --- /dev/null +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -0,0 +1,137 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "fo_context.h" + +/* This looks like a lot of work at the moment - we're keeping a + * duplicate copy of the state up-to-date. + * + * This can change in two ways: + * - With constant state objects we would only need to save a pointer, + * not the whole object. + * - By adding a callback in the state tracker to re-emit state. The + * state tracker knows the current state already and can re-emit it + * without additional complexity. + * + * This works as a proof-of-concept, but a final version will have + * lower overheads. + */ + + +/* Bring the software pipe uptodate with current state. + * + * With constant state objects we would probably just send all state + * to both rasterizers all the time??? + */ +void +failover_state_emit( struct failover_context *failover ) +{ + unsigned i; + + if (failover->dirty & FO_NEW_BLEND) + failover->sw->bind_blend_state( failover->sw, + failover->blend->sw_state ); + + if (failover->dirty & FO_NEW_BLEND_COLOR) + failover->sw->set_blend_color( failover->sw, &failover->blend_color ); + + if (failover->dirty & FO_NEW_CLIP) + failover->sw->set_clip_state( failover->sw, &failover->clip ); + + if (failover->dirty & FO_NEW_DEPTH_STENCIL) + failover->sw->bind_depth_stencil_alpha_state( failover->sw, + failover->depth_stencil->sw_state ); + + if (failover->dirty & FO_NEW_FRAMEBUFFER) + failover->sw->set_framebuffer_state( failover->sw, &failover->framebuffer ); + + if (failover->dirty & FO_NEW_FRAGMENT_SHADER) + failover->sw->bind_fs_state( failover->sw, + failover->fragment_shader->sw_state ); + + if (failover->dirty & FO_NEW_VERTEX_SHADER) + failover->sw->bind_vs_state( failover->sw, + failover->vertex_shader->sw_state ); + + if (failover->dirty & FO_NEW_STIPPLE) + failover->sw->set_polygon_stipple( failover->sw, &failover->poly_stipple ); + + if (failover->dirty & FO_NEW_RASTERIZER) + failover->sw->bind_rasterizer_state( failover->sw, + failover->rasterizer->sw_state ); + + if (failover->dirty & FO_NEW_SCISSOR) + failover->sw->set_scissor_state( failover->sw, &failover->scissor ); + + if (failover->dirty & FO_NEW_VIEWPORT) + failover->sw->set_viewport_state( failover->sw, &failover->viewport ); + + if (failover->dirty & FO_NEW_SAMPLER) { + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + if (failover->dirty_sampler & (1<sw->bind_sampler_state( failover->sw, i, + failover->sampler[i]->sw_state ); + } + } + } + + if (failover->dirty & FO_NEW_TEXTURE) { + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + if (failover->dirty_texture & (1<sw->set_sampler_texture( failover->sw, i, + failover->texture[i] ); + } + } + } + + if (failover->dirty & FO_NEW_VERTEX_BUFFER) { + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (failover->dirty_vertex_buffer & (1<sw->set_vertex_buffer( failover->sw, i, + &failover->vertex_buffer[i] ); + } + } + } + + if (failover->dirty & FO_NEW_VERTEX_ELEMENT) { + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (failover->dirty_vertex_element & (1<sw->set_vertex_element( failover->sw, i, + &failover->vertex_element[i] ); + } + } + } + + failover->dirty = 0; + failover->dirty_vertex_element = 0; + failover->dirty_vertex_buffer = 0; + failover->dirty_texture = 0; + failover->dirty_sampler = 0; +} diff --git a/src/gallium/drivers/failover/fo_winsys.h b/src/gallium/drivers/failover/fo_winsys.h new file mode 100644 index 0000000000..a8ce997a1f --- /dev/null +++ b/src/gallium/drivers/failover/fo_winsys.h @@ -0,0 +1,45 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef FO_WINSYS_H +#define FO_WINSYS_H + + +/* This is the interface that failover requires any window system + * hosting it to implement. This is the only include file in failover + * which is public. + */ + + +struct pipe_context; + + +struct pipe_context *failover_create( struct pipe_context *hw, + struct pipe_context *sw ); + + +#endif /* FO_WINSYS_H */ diff --git a/src/gallium/drivers/i915simple/Makefile b/src/gallium/drivers/i915simple/Makefile new file mode 100644 index 0000000000..2f91de3afc --- /dev/null +++ b/src/gallium/drivers/i915simple/Makefile @@ -0,0 +1,38 @@ + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = i915simple + +DRIVER_SOURCES = \ + i915_blit.c \ + i915_clear.c \ + i915_flush.c \ + i915_context.c \ + i915_context.c \ + i915_debug.c \ + i915_debug_fp.c \ + i915_state.c \ + i915_state_immediate.c \ + i915_state_dynamic.c \ + i915_state_derived.c \ + i915_state_emit.c \ + i915_state_sampler.c \ + i915_strings.c \ + i915_prim_emit.c \ + i915_prim_vbuf.c \ + i915_texture.c \ + i915_fpc_emit.c \ + i915_fpc_translate.c \ + i915_surface.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/i915simple/SConscript b/src/gallium/drivers/i915simple/SConscript new file mode 100644 index 0000000000..f5fb96b995 --- /dev/null +++ b/src/gallium/drivers/i915simple/SConscript @@ -0,0 +1,29 @@ +Import('*') + +env = env.Clone() + +i915simple = env.ConvenienceLibrary( + target = 'i915simple', + source = [ + 'i915_blit.c', + 'i915_clear.c', + 'i915_context.c', + 'i915_debug.c', + 'i915_debug_fp.c', + 'i915_flush.c', + 'i915_fpc_emit.c', + 'i915_fpc_translate.c', + 'i915_prim_emit.c', + 'i915_prim_vbuf.c', + 'i915_state.c', + 'i915_state_derived.c', + 'i915_state_dynamic.c', + 'i915_state_emit.c', + 'i915_state_immediate.c', + 'i915_state_sampler.c', + 'i915_strings.c', + 'i915_surface.c', + 'i915_texture.c', + ]) + +Export('i915simple') diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h new file mode 100644 index 0000000000..fb88cd6db0 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_batch.h @@ -0,0 +1,54 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef I915_BATCH_H +#define I915_BATCH_H + +#include "i915_winsys.h" +#include "i915_debug.h" + +#define BATCH_LOCALS + +#define BEGIN_BATCH( dwords, relocs ) \ + (i915->batch_start = i915->winsys->batch_start( i915->winsys, dwords, relocs )) + +#define OUT_BATCH( dword ) \ + i915->winsys->batch_dword( i915->winsys, dword ) + +#define OUT_RELOC( buf, flags, delta ) \ + i915->winsys->batch_reloc( i915->winsys, buf, flags, delta ) + +#define ADVANCE_BATCH() + +#define FLUSH_BATCH() do { \ + if (0) i915_dump_batchbuffer( i915 ); \ + i915->winsys->batch_flush( i915->winsys ); \ + i915->batch_start = NULL; \ + i915->hardware_dirty = ~0; \ +} while (0) + +#endif diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c new file mode 100644 index 0000000000..db4671ff55 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_blit.c @@ -0,0 +1,162 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "i915_context.h" +#include "i915_winsys.h" +#include "i915_blit.h" +#include "i915_reg.h" +#include "i915_batch.h" + +#define FILE_DEBUG_FLAG DEBUG_BLIT + +void +i915_fill_blit(struct i915_context *i915, + unsigned cpp, + short dst_pitch, + struct pipe_buffer *dst_buffer, + unsigned dst_offset, + short x, short y, + short w, short h, + unsigned color) +{ + unsigned BR13, CMD; + BATCH_LOCALS; + + dst_pitch *= (short) cpp; + + switch (cpp) { + case 1: + case 2: + case 3: + BR13 = dst_pitch | (0xF0 << 16) | (1 << 24); + CMD = XY_COLOR_BLT_CMD; + break; + case 4: + BR13 = dst_pitch | (0xF0 << 16) | (1 << 24) | (1 << 25); + CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | + XY_COLOR_BLT_WRITE_RGB); + break; + default: + return; + } + +// DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", +// __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h); + + + if (!BEGIN_BATCH(6, 1)) { + FLUSH_BATCH(); + assert(BEGIN_BATCH(6, 1)); + } + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((y << 16) | x); + OUT_BATCH(((y + h) << 16) | (x + w)); + OUT_RELOC( dst_buffer, I915_BUFFER_ACCESS_WRITE, dst_offset); + OUT_BATCH(color); + ADVANCE_BATCH(); +} + + +void +i915_copy_blit( struct i915_context *i915, + unsigned do_flip, + unsigned cpp, + short src_pitch, + struct pipe_buffer *src_buffer, + unsigned src_offset, + short dst_pitch, + struct pipe_buffer *dst_buffer, + unsigned dst_offset, + short src_x, short src_y, + short dst_x, short dst_y, + short w, short h ) +{ + unsigned CMD, BR13; + int dst_y2 = dst_y + h; + int dst_x2 = dst_x + w; + BATCH_LOCALS; + + + I915_DBG(i915, + "%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __FUNCTION__, + src_buffer, src_pitch, src_offset, src_x, src_y, + dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h); + + src_pitch *= (short) cpp; + dst_pitch *= (short) cpp; + + switch (cpp) { + case 1: + case 2: + case 3: + BR13 = (((int) dst_pitch) & 0xffff) | + (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + break; + case 4: + BR13 = + (((int) dst_pitch) & 0xffff) | + (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = + (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + break; + default: + return; + } + + if (dst_y2 < dst_y || + dst_x2 < dst_x) { + return; + } + + /* Hardware can handle negative pitches but loses the ability to do + * proper overlapping blits in that case. We don't really have a + * need for either at this stage. + */ + assert (dst_pitch > 0 && src_pitch > 0); + + + if (!BEGIN_BATCH(8, 2)) { + FLUSH_BATCH(); + assert(BEGIN_BATCH(8, 2)); + } + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((dst_y << 16) | dst_x); + OUT_BATCH((dst_y2 << 16) | dst_x2); + OUT_RELOC(dst_buffer, I915_BUFFER_ACCESS_WRITE, dst_offset); + OUT_BATCH((src_y << 16) | src_x); + OUT_BATCH(((int) src_pitch & 0xffff)); + OUT_RELOC(src_buffer, I915_BUFFER_ACCESS_READ, src_offset); + ADVANCE_BATCH(); +} + + diff --git a/src/gallium/drivers/i915simple/i915_blit.h b/src/gallium/drivers/i915simple/i915_blit.h new file mode 100644 index 0000000000..6e5b44e124 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_blit.h @@ -0,0 +1,55 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef I915_BLIT_H +#define I915_BLIT_H + +#include "i915_context.h" + +extern void i915_copy_blit(struct i915_context *i915, + unsigned do_flip, + unsigned cpp, + short src_pitch, + struct pipe_buffer *src_buffer, + unsigned src_offset, + short dst_pitch, + struct pipe_buffer *dst_buffer, + unsigned dst_offset, + short srcx, short srcy, + short dstx, short dsty, + short w, short h ); + +extern void i915_fill_blit(struct i915_context *i915, + unsigned cpp, + short dst_pitch, + struct pipe_buffer *dst_buffer, + unsigned dst_offset, + short x, short y, + short w, short h, unsigned color); + + +#endif diff --git a/src/gallium/drivers/i915simple/i915_clear.c b/src/gallium/drivers/i915simple/i915_clear.c new file mode 100644 index 0000000000..cde69daacc --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_clear.c @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Brian Paul + */ + + +#include "pipe/p_defines.h" +#include "i915_context.h" +#include "i915_state.h" + + +/** + * Clear the given surface to the specified value. + * No masking, no scissor (clear entire buffer). + */ +void +i915_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue) +{ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); +} diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c new file mode 100644 index 0000000000..497623a700 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -0,0 +1,320 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "i915_context.h" +#include "i915_winsys.h" +#include "i915_state.h" +#include "i915_batch.h" +#include "i915_texture.h" +#include "i915_reg.h" + +#include "pipe/draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + + +/** + * Query format support for creating a texture, drawing surface, etc. + * \param format the format to test + * \param type one of PIPE_TEXTURE, PIPE_SURFACE + */ +static boolean +i915_is_format_supported( struct pipe_context *pipe, + enum pipe_format format, uint type ) +{ + static const enum pipe_format tex_supported[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_U_L8, + PIPE_FORMAT_U_A8, + PIPE_FORMAT_U_I8, + PIPE_FORMAT_U_A8_L8, + PIPE_FORMAT_YCBCR, + PIPE_FORMAT_YCBCR_REV, + PIPE_FORMAT_S8Z24_UNORM, + PIPE_FORMAT_NONE /* list terminator */ + }; + static const enum pipe_format surface_supported[] = { + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_S8Z24_UNORM, + /*PIPE_FORMAT_R16G16B16A16_SNORM,*/ + PIPE_FORMAT_NONE /* list terminator */ + }; + const enum pipe_format *list; + uint i; + + switch (type) { + case PIPE_TEXTURE: + list = tex_supported; + break; + case PIPE_SURFACE: + list = surface_supported; + break; + default: + assert(0); + } + + for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { + if (list[i] == format) + return TRUE; + } + + return FALSE; +} + + +static int +i915_get_param(struct pipe_context *pipe, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 8; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 0; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 0; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 11; /* max 1024x1024 */ + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 8; /* max 128x128x128 */ + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 11; /* max 1024x1024 */ + default: + return 0; + } +} + + +static float +i915_get_paramf(struct pipe_context *pipe, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 7.5; + + case PIPE_CAP_MAX_POINT_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 255.0; + + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 4.0; + + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0; + + default: + return 0; + } +} + + +static void i915_destroy( struct pipe_context *pipe ) +{ + struct i915_context *i915 = i915_context( pipe ); + + draw_destroy( i915->draw ); + + FREE( i915 ); +} + + + + +static boolean +i915_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned prim, unsigned start, unsigned count) +{ + struct i915_context *i915 = i915_context( pipe ); + struct draw_context *draw = i915->draw; + unsigned i; + + if (i915->dirty) + i915_update_derived( i915 ); + + /* + * Map vertex buffers + */ + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (i915->vertex_buffer[i].buffer) { + void *buf + = pipe->winsys->buffer_map(pipe->winsys, + i915->vertex_buffer[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(draw, i, buf); + } + } + /* Map index buffer, if present */ + if (indexBuffer) { + void *mapped_indexes + = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); + } + else { + /* no index/element buffer */ + draw_set_mapped_element_buffer(draw, 0, NULL); + } + + + draw_set_mapped_constant_buffer(draw, + i915->current.constants[PIPE_SHADER_VERTEX]); + + /* draw! */ + draw_arrays(i915->draw, prim, start, count); + + /* + * unmap vertex/index buffers + */ + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (i915->vertex_buffer[i].buffer) { + pipe->winsys->buffer_unmap(pipe->winsys, i915->vertex_buffer[i].buffer); + draw_set_mapped_vertex_buffer(draw, i, NULL); + } + } + if (indexBuffer) { + pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); + draw_set_mapped_element_buffer(draw, 0, NULL); + } + + return TRUE; +} + + +static boolean i915_draw_arrays( struct pipe_context *pipe, + unsigned prim, unsigned start, unsigned count) +{ + return i915_draw_elements(pipe, NULL, 0, prim, start, count); +} + + + +struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, + struct i915_winsys *i915_winsys, + unsigned pci_id ) +{ + struct i915_context *i915; + unsigned is_i945 = 0; + + switch (pci_id) { + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + break; + + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q33_G: + case PCI_CHIP_Q35_G: + is_i945 = 1; + break; + + default: + pipe_winsys->printf(pipe_winsys, + "%s: unknown pci id 0x%x, cannot create context\n", + __FUNCTION__, pci_id); + return NULL; + } + + i915 = CALLOC_STRUCT(i915_context); + if (i915 == NULL) + return NULL; + + i915->winsys = i915_winsys; + i915->pipe.winsys = pipe_winsys; + + i915->pipe.destroy = i915_destroy; + i915->pipe.is_format_supported = i915_is_format_supported; + i915->pipe.get_param = i915_get_param; + i915->pipe.get_paramf = i915_get_paramf; + + i915->pipe.clear = i915_clear; + + + i915->pipe.draw_arrays = i915_draw_arrays; + i915->pipe.draw_elements = i915_draw_elements; + + /* + * Create drawing context and plug our rendering stage into it. + */ + i915->draw = draw_create(); + assert(i915->draw); + if (GETENV("I915_VBUF")) { + draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915)); + } + else { + draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915)); + } + + i915_init_surface_functions(i915); + i915_init_state_functions(i915); + i915_init_flush_functions(i915); + i915_init_string_functions(i915); + + i915->pci_id = pci_id; + i915->flags.is_i945 = is_i945; + + i915->pipe.texture_create = i915_texture_create; + i915->pipe.texture_release = i915_texture_release; + + i915->dirty = ~0; + i915->hardware_dirty = ~0; + + /* Batch stream debugging is a bit hacked up at the moment: + */ + i915->batch_start = NULL; + + /* + * XXX we could plug GL selection/feedback into the drawing pipeline + * by specifying a different setup/render stage. + */ + + return &i915->pipe; +} + diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h new file mode 100644 index 0000000000..b4ea63c3e7 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -0,0 +1,304 @@ + /************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef I915_CONTEXT_H +#define I915_CONTEXT_H + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "pipe/draw/draw_vertex.h" + + +#define I915_TEX_UNITS 8 + +#define I915_DYNAMIC_MODES4 0 +#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */ +#define I915_DYNAMIC_DEPTHSCALE_1 2 +#define I915_DYNAMIC_IAB 3 +#define I915_DYNAMIC_BC_0 4 /* just the header */ +#define I915_DYNAMIC_BC_1 5 +#define I915_DYNAMIC_BFO_0 6 +#define I915_DYNAMIC_BFO_1 7 +#define I915_DYNAMIC_STP_0 8 +#define I915_DYNAMIC_STP_1 9 +#define I915_DYNAMIC_SC_ENA_0 10 +#define I915_DYNAMIC_SC_RECT_0 11 +#define I915_DYNAMIC_SC_RECT_1 12 +#define I915_DYNAMIC_SC_RECT_2 13 +#define I915_MAX_DYNAMIC 14 + + +#define I915_IMMEDIATE_S0 0 +#define I915_IMMEDIATE_S1 1 +#define I915_IMMEDIATE_S2 2 +#define I915_IMMEDIATE_S3 3 +#define I915_IMMEDIATE_S4 4 +#define I915_IMMEDIATE_S5 5 +#define I915_IMMEDIATE_S6 6 +#define I915_IMMEDIATE_S7 7 +#define I915_MAX_IMMEDIATE 8 + +/* These must mach the order of LI0_STATE_* bits, as they will be used + * to generate hardware packets: + */ +#define I915_CACHE_STATIC 0 +#define I915_CACHE_DYNAMIC 1 /* handled specially */ +#define I915_CACHE_SAMPLER 2 +#define I915_CACHE_MAP 3 +#define I915_CACHE_PROGRAM 4 +#define I915_CACHE_CONSTANTS 5 +#define I915_MAX_CACHE 6 + +#define I915_MAX_CONSTANT 32 + + + +struct i915_cache_context; + +/* Use to calculate differences between state emitted to hardware and + * current driver-calculated state. + */ +struct i915_state +{ + unsigned immediate[I915_MAX_IMMEDIATE]; + unsigned dynamic[I915_MAX_DYNAMIC]; + + float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4]; + /** number of constants passed in through a constant buffer */ + uint num_user_constants[PIPE_SHADER_TYPES]; + /** user constants, plus extra constants from shader translation */ + uint num_constants[PIPE_SHADER_TYPES]; + + uint *program; + uint program_len; + + /* texture sampler state */ + unsigned sampler[I915_TEX_UNITS][3]; + unsigned sampler_enable_flags; + unsigned sampler_enable_nr; + + /* texture image buffers */ + unsigned texbuffer[I915_TEX_UNITS][2]; + + /** Describes the current hardware vertex layout */ + struct vertex_info vertex_info; + + unsigned id; /* track lost context events */ +}; + +struct i915_blend_state { + unsigned iab; + unsigned modes4; + unsigned LIS5; + unsigned LIS6; +}; + +struct i915_depth_stencil_state { + unsigned stencil_modes4; + unsigned bfo[2]; + unsigned stencil_LIS5; + unsigned depth_LIS6; +}; + +struct i915_rasterizer_state { + int light_twoside : 1; + unsigned st; + enum interp_mode color_interp; + + unsigned LIS4; + unsigned LIS7; + unsigned sc[1]; + + const struct pipe_rasterizer_state *templ; + + union { float f; unsigned u; } ds[2]; +}; + +struct i915_sampler_state { + unsigned state[3]; + const struct pipe_sampler_state *templ; +}; + + +struct i915_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +struct i915_context +{ + struct pipe_context pipe; + struct i915_winsys *winsys; + struct draw_context *draw; + + /* The most recent drawing state as set by the driver: + */ + const struct i915_blend_state *blend; + const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct i915_depth_stencil_state *depth_stencil; + const struct i915_rasterizer_state *rasterizer; + const struct pipe_shader_state *fs; + + struct pipe_blend_color blend_color; + struct pipe_clip_state clip; + struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; + struct pipe_framebuffer_state framebuffer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct i915_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; + + unsigned dirty; + + unsigned *batch_start; + + /** Vertex buffer */ + struct pipe_buffer *vbo; + + struct i915_state current; + unsigned hardware_dirty; + + unsigned debug; + unsigned pci_id; + + struct { + unsigned is_i945:1; + } flags; +}; + +/* A flag for each state_tracker state object: + */ +#define I915_NEW_VIEWPORT 0x1 +#define I915_NEW_RASTERIZER 0x2 +#define I915_NEW_FS 0x4 +#define I915_NEW_BLEND 0x8 +#define I915_NEW_CLIP 0x10 +#define I915_NEW_SCISSOR 0x20 +#define I915_NEW_STIPPLE 0x40 +#define I915_NEW_FRAMEBUFFER 0x80 +#define I915_NEW_ALPHA_TEST 0x100 +#define I915_NEW_DEPTH_STENCIL 0x200 +#define I915_NEW_SAMPLER 0x400 +#define I915_NEW_TEXTURE 0x800 +#define I915_NEW_CONSTANTS 0x1000 +#define I915_NEW_VBO 0x2000 + + +/* Driver's internally generated state flags: + */ +#define I915_NEW_VERTEX_FORMAT 0x10000 + + +/* Dirty flags for hardware emit + */ +#define I915_HW_STATIC (1<winsys->printf( stream->winsys, buffer ); + va_end( args ); +} + + +static boolean debug( struct debug_stream *stream, const char *name, unsigned len ) +{ + unsigned i; + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + + if (len == 0) { + PRINTF(stream, "Error - zero length packet (0x%08x)\n", stream->ptr[0]); + assert(0); + return FALSE; + } + + if (stream->print_addresses) + PRINTF(stream, "%08x: ", stream->offset); + + + PRINTF(stream, "%s (%d dwords):\n", name, len); + for (i = 0; i < len; i++) + PRINTF(stream, "\t0x%08x\n", ptr[i]); + PRINTF(stream, "\n"); + + stream->offset += len * sizeof(unsigned); + + return TRUE; +} + + +static const char *get_prim_name( unsigned val ) +{ + switch (val & PRIM3D_MASK) { + case PRIM3D_TRILIST: return "TRILIST"; break; + case PRIM3D_TRISTRIP: return "TRISTRIP"; break; + case PRIM3D_TRISTRIP_RVRSE: return "TRISTRIP_RVRSE"; break; + case PRIM3D_TRIFAN: return "TRIFAN"; break; + case PRIM3D_POLY: return "POLY"; break; + case PRIM3D_LINELIST: return "LINELIST"; break; + case PRIM3D_LINESTRIP: return "LINESTRIP"; break; + case PRIM3D_RECTLIST: return "RECTLIST"; break; + case PRIM3D_POINTLIST: return "POINTLIST"; break; + case PRIM3D_DIB: return "DIB"; break; + case PRIM3D_CLEAR_RECT: return "CLEAR_RECT"; break; + case PRIM3D_ZONE_INIT: return "ZONE_INIT"; break; + default: return "????"; break; + } +} + +static boolean debug_prim( struct debug_stream *stream, const char *name, + boolean dump_floats, + unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + const char *prim = get_prim_name( ptr[0] ); + unsigned i; + + + + PRINTF(stream, "%s %s (%d dwords):\n", name, prim, len); + PRINTF(stream, "\t0x%08x\n", ptr[0]); + for (i = 1; i < len; i++) { + if (dump_floats) + PRINTF(stream, "\t0x%08x // %f\n", ptr[i], *(float *)&ptr[i]); + else + PRINTF(stream, "\t0x%08x\n", ptr[i]); + } + + + PRINTF(stream, "\n"); + + stream->offset += len * sizeof(unsigned); + + return TRUE; +} + + + + +static boolean debug_program( struct debug_stream *stream, const char *name, unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + + if (len == 0) { + PRINTF(stream, "Error - zero length packet (0x%08x)\n", stream->ptr[0]); + assert(0); + return FALSE; + } + + if (stream->print_addresses) + PRINTF(stream, "%08x: ", stream->offset); + + PRINTF(stream, "%s (%d dwords):\n", name, len); + i915_disassemble_program( stream, ptr, len ); + + stream->offset += len * sizeof(unsigned); + return TRUE; +} + + +static boolean debug_chain( struct debug_stream *stream, const char *name, unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + unsigned old_offset = stream->offset + len * sizeof(unsigned); + unsigned i; + + PRINTF(stream, "%s (%d dwords):\n", name, len); + for (i = 0; i < len; i++) + PRINTF(stream, "\t0x%08x\n", ptr[i]); + + stream->offset = ptr[1] & ~0x3; + + if (stream->offset < old_offset) + PRINTF(stream, "\n... skipping backwards from 0x%x --> 0x%x ...\n\n", + old_offset, stream->offset ); + else + PRINTF(stream, "\n... skipping from 0x%x --> 0x%x ...\n\n", + old_offset, stream->offset ); + + + return TRUE; +} + + +static boolean debug_variable_length_prim( struct debug_stream *stream ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + const char *prim = get_prim_name( ptr[0] ); + unsigned i, len; + + ushort *idx = (ushort *)(ptr+1); + for (i = 0; idx[i] != 0xffff; i++) + ; + + len = 1+(i+2)/2; + + PRINTF(stream, "3DPRIM, %s variable length %d indicies (%d dwords):\n", prim, i, len); + for (i = 0; i < len; i++) + PRINTF(stream, "\t0x%08x\n", ptr[i]); + PRINTF(stream, "\n"); + + stream->offset += len * sizeof(unsigned); + return TRUE; +} + + +static void +BITS( + struct debug_stream *stream, + unsigned dw, + unsigned hi, + unsigned lo, + const char *fmt, + ... ) +{ + va_list args; + char buffer[256]; + unsigned himask = ~0UL >> (31 - (hi)); + + PRINTF(stream, "\t\t "); + + va_start( args, fmt ); + vsprintf( buffer, fmt, args ); + stream->winsys->printf( stream->winsys, buffer ); + va_end( args ); + + PRINTF(stream, ": 0x%x\n", ((dw) & himask) >> (lo)); +} + +#define MBZ( dw, hi, lo) do { \ + unsigned x = (dw) >> (lo); \ + unsigned lomask = (1 << (lo)) - 1; \ + unsigned himask; \ + himask = (1UL << (hi)) - 1; \ + assert ((x & himask & ~lomask) == 0); \ +} while (0) + +static void +FLAG( + struct debug_stream *stream, + unsigned dw, + unsigned bit, + const char *fmt, + ... ) +{ + if (((dw) >> (bit)) & 1) { + va_list args; + char buffer[256]; + + PRINTF(stream, "\t\t "); + + va_start( args, fmt ); + vsprintf( buffer, fmt, args ); + stream->winsys->printf( stream->winsys, buffer ); + va_end( args ); + + PRINTF(stream, "\n"); + } +} + +static boolean debug_load_immediate( struct debug_stream *stream, + const char *name, + unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + unsigned bits = (ptr[0] >> 4) & 0xff; + unsigned j = 0; + + PRINTF(stream, "%s (%d dwords, flags: %x):\n", name, len, bits); + PRINTF(stream, "\t0x%08x\n", ptr[j++]); + + if (bits & (1<<0)) { + PRINTF(stream, "\t LIS0: 0x%08x\n", ptr[j]); + PRINTF(stream, "\t vb address: 0x%08x\n", (ptr[j] & ~0x3)); + BITS(stream, ptr[j], 0, 0, "vb invalidate disable"); + j++; + } + if (bits & (1<<1)) { + PRINTF(stream, "\t LIS1: 0x%08x\n", ptr[j]); + BITS(stream, ptr[j], 29, 24, "vb dword width"); + BITS(stream, ptr[j], 21, 16, "vb dword pitch"); + BITS(stream, ptr[j], 15, 0, "vb max index"); + j++; + } + if (bits & (1<<2)) { + int i; + PRINTF(stream, "\t LIS2: 0x%08x\n", ptr[j]); + for (i = 0; i < 8; i++) { + unsigned tc = (ptr[j] >> (i * 4)) & 0xf; + if (tc != 0xf) + BITS(stream, tc, 3, 0, "tex coord %d", i); + } + j++; + } + if (bits & (1<<3)) { + PRINTF(stream, "\t LIS3: 0x%08x\n", ptr[j]); + j++; + } + if (bits & (1<<4)) { + PRINTF(stream, "\t LIS4: 0x%08x\n", ptr[j]); + BITS(stream, ptr[j], 31, 23, "point width"); + BITS(stream, ptr[j], 22, 19, "line width"); + FLAG(stream, ptr[j], 18, "alpha flatshade"); + FLAG(stream, ptr[j], 17, "fog flatshade"); + FLAG(stream, ptr[j], 16, "spec flatshade"); + FLAG(stream, ptr[j], 15, "rgb flatshade"); + BITS(stream, ptr[j], 14, 13, "cull mode"); + FLAG(stream, ptr[j], 12, "vfmt: point width"); + FLAG(stream, ptr[j], 11, "vfmt: specular/fog"); + FLAG(stream, ptr[j], 10, "vfmt: rgba"); + FLAG(stream, ptr[j], 9, "vfmt: depth offset"); + BITS(stream, ptr[j], 8, 6, "vfmt: position (2==xyzw)"); + FLAG(stream, ptr[j], 5, "force dflt diffuse"); + FLAG(stream, ptr[j], 4, "force dflt specular"); + FLAG(stream, ptr[j], 3, "local depth offset enable"); + FLAG(stream, ptr[j], 2, "vfmt: fp32 fog coord"); + FLAG(stream, ptr[j], 1, "sprite point"); + FLAG(stream, ptr[j], 0, "antialiasing"); + j++; + } + if (bits & (1<<5)) { + PRINTF(stream, "\t LIS5: 0x%08x\n", ptr[j]); + BITS(stream, ptr[j], 31, 28, "rgba write disables"); + FLAG(stream, ptr[j], 27, "force dflt point width"); + FLAG(stream, ptr[j], 26, "last pixel enable"); + FLAG(stream, ptr[j], 25, "global z offset enable"); + FLAG(stream, ptr[j], 24, "fog enable"); + BITS(stream, ptr[j], 23, 16, "stencil ref"); + BITS(stream, ptr[j], 15, 13, "stencil test"); + BITS(stream, ptr[j], 12, 10, "stencil fail op"); + BITS(stream, ptr[j], 9, 7, "stencil pass z fail op"); + BITS(stream, ptr[j], 6, 4, "stencil pass z pass op"); + FLAG(stream, ptr[j], 3, "stencil write enable"); + FLAG(stream, ptr[j], 2, "stencil test enable"); + FLAG(stream, ptr[j], 1, "color dither enable"); + FLAG(stream, ptr[j], 0, "logiop enable"); + j++; + } + if (bits & (1<<6)) { + PRINTF(stream, "\t LIS6: 0x%08x\n", ptr[j]); + FLAG(stream, ptr[j], 31, "alpha test enable"); + BITS(stream, ptr[j], 30, 28, "alpha func"); + BITS(stream, ptr[j], 27, 20, "alpha ref"); + FLAG(stream, ptr[j], 19, "depth test enable"); + BITS(stream, ptr[j], 18, 16, "depth func"); + FLAG(stream, ptr[j], 15, "blend enable"); + BITS(stream, ptr[j], 14, 12, "blend func"); + BITS(stream, ptr[j], 11, 8, "blend src factor"); + BITS(stream, ptr[j], 7, 4, "blend dst factor"); + FLAG(stream, ptr[j], 3, "depth write enable"); + FLAG(stream, ptr[j], 2, "color write enable"); + BITS(stream, ptr[j], 1, 0, "provoking vertex"); + j++; + } + + + PRINTF(stream, "\n"); + + assert(j == len); + + stream->offset += len * sizeof(unsigned); + + return TRUE; +} + + + +static boolean debug_load_indirect( struct debug_stream *stream, + const char *name, + unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + unsigned bits = (ptr[0] >> 8) & 0x3f; + unsigned i, j = 0; + + PRINTF(stream, "%s (%d dwords):\n", name, len); + PRINTF(stream, "\t0x%08x\n", ptr[j++]); + + for (i = 0; i < 6; i++) { + if (bits & (1<offset += len * sizeof(unsigned); + + return TRUE; +} + +static void BR13( struct debug_stream *stream, + unsigned val ) +{ + PRINTF(stream, "\t0x%08x\n", val); + FLAG(stream, val, 30, "clipping enable"); + BITS(stream, val, 25, 24, "color depth (3==32bpp)"); + BITS(stream, val, 23, 16, "raster op"); + BITS(stream, val, 15, 0, "dest pitch"); +} + + +static void BR22( struct debug_stream *stream, + unsigned val ) +{ + PRINTF(stream, "\t0x%08x\n", val); + BITS(stream, val, 31, 16, "dest y1"); + BITS(stream, val, 15, 0, "dest x1"); +} + +static void BR23( struct debug_stream *stream, + unsigned val ) +{ + PRINTF(stream, "\t0x%08x\n", val); + BITS(stream, val, 31, 16, "dest y2"); + BITS(stream, val, 15, 0, "dest x2"); +} + +static void BR09( struct debug_stream *stream, + unsigned val ) +{ + PRINTF(stream, "\t0x%08x -- dest address\n", val); +} + +static void BR26( struct debug_stream *stream, + unsigned val ) +{ + PRINTF(stream, "\t0x%08x\n", val); + BITS(stream, val, 31, 16, "src y1"); + BITS(stream, val, 15, 0, "src x1"); +} + +static void BR11( struct debug_stream *stream, + unsigned val ) +{ + PRINTF(stream, "\t0x%08x\n", val); + BITS(stream, val, 15, 0, "src pitch"); +} + +static void BR12( struct debug_stream *stream, + unsigned val ) +{ + PRINTF(stream, "\t0x%08x -- src address\n", val); +} + +static void BR16( struct debug_stream *stream, + unsigned val ) +{ + PRINTF(stream, "\t0x%08x -- color\n", val); +} + +static boolean debug_copy_blit( struct debug_stream *stream, + const char *name, + unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF(stream, "%s (%d dwords):\n", name, len); + PRINTF(stream, "\t0x%08x\n", ptr[j++]); + + BR13(stream, ptr[j++]); + BR22(stream, ptr[j++]); + BR23(stream, ptr[j++]); + BR09(stream, ptr[j++]); + BR26(stream, ptr[j++]); + BR11(stream, ptr[j++]); + BR12(stream, ptr[j++]); + + stream->offset += len * sizeof(unsigned); + assert(j == len); + return TRUE; +} + +static boolean debug_color_blit( struct debug_stream *stream, + const char *name, + unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF(stream, "%s (%d dwords):\n", name, len); + PRINTF(stream, "\t0x%08x\n", ptr[j++]); + + BR13(stream, ptr[j++]); + BR22(stream, ptr[j++]); + BR23(stream, ptr[j++]); + BR09(stream, ptr[j++]); + BR16(stream, ptr[j++]); + + stream->offset += len * sizeof(unsigned); + assert(j == len); + return TRUE; +} + +static boolean debug_modes4( struct debug_stream *stream, + const char *name, + unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF(stream, "%s (%d dwords):\n", name, len); + PRINTF(stream, "\t0x%08x\n", ptr[j]); + BITS(stream, ptr[j], 21, 18, "logicop func"); + FLAG(stream, ptr[j], 17, "stencil test mask modify-enable"); + FLAG(stream, ptr[j], 16, "stencil write mask modify-enable"); + BITS(stream, ptr[j], 15, 8, "stencil test mask"); + BITS(stream, ptr[j], 7, 0, "stencil write mask"); + j++; + + stream->offset += len * sizeof(unsigned); + assert(j == len); + return TRUE; +} + +static boolean debug_map_state( struct debug_stream *stream, + const char *name, + unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + unsigned j = 0; + + PRINTF(stream, "%s (%d dwords):\n", name, len); + PRINTF(stream, "\t0x%08x\n", ptr[j++]); + + { + PRINTF(stream, "\t0x%08x\n", ptr[j]); + BITS(stream, ptr[j], 15, 0, "map mask"); + j++; + } + + while (j < len) { + { + PRINTF(stream, "\t TMn.0: 0x%08x\n", ptr[j]); + PRINTF(stream, "\t map address: 0x%08x\n", (ptr[j] & ~0x3)); + FLAG(stream, ptr[j], 1, "vertical line stride"); + FLAG(stream, ptr[j], 0, "vertical line stride offset"); + j++; + } + + { + PRINTF(stream, "\t TMn.1: 0x%08x\n", ptr[j]); + BITS(stream, ptr[j], 31, 21, "height"); + BITS(stream, ptr[j], 20, 10, "width"); + BITS(stream, ptr[j], 9, 7, "surface format"); + BITS(stream, ptr[j], 6, 3, "texel format"); + FLAG(stream, ptr[j], 2, "use fence regs"); + FLAG(stream, ptr[j], 1, "tiled surface"); + FLAG(stream, ptr[j], 0, "tile walk ymajor"); + j++; + } + { + PRINTF(stream, "\t TMn.2: 0x%08x\n", ptr[j]); + BITS(stream, ptr[j], 31, 21, "dword pitch"); + BITS(stream, ptr[j], 20, 15, "cube face enables"); + BITS(stream, ptr[j], 14, 9, "max lod"); + FLAG(stream, ptr[j], 8, "mip layout right"); + BITS(stream, ptr[j], 7, 0, "depth"); + j++; + } + } + + stream->offset += len * sizeof(unsigned); + assert(j == len); + return TRUE; +} + +static boolean debug_sampler_state( struct debug_stream *stream, + const char *name, + unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + unsigned j = 0; + + PRINTF(stream, "%s (%d dwords):\n", name, len); + PRINTF(stream, "\t0x%08x\n", ptr[j++]); + + { + PRINTF(stream, "\t0x%08x\n", ptr[j]); + BITS(stream, ptr[j], 15, 0, "sampler mask"); + j++; + } + + while (j < len) { + { + PRINTF(stream, "\t TSn.0: 0x%08x\n", ptr[j]); + FLAG(stream, ptr[j], 31, "reverse gamma"); + FLAG(stream, ptr[j], 30, "planar to packed"); + FLAG(stream, ptr[j], 29, "yuv->rgb"); + BITS(stream, ptr[j], 28, 27, "chromakey index"); + BITS(stream, ptr[j], 26, 22, "base mip level"); + BITS(stream, ptr[j], 21, 20, "mip mode filter"); + BITS(stream, ptr[j], 19, 17, "mag mode filter"); + BITS(stream, ptr[j], 16, 14, "min mode filter"); + BITS(stream, ptr[j], 13, 5, "lod bias (s4.4)"); + FLAG(stream, ptr[j], 4, "shadow enable"); + FLAG(stream, ptr[j], 3, "max-aniso-4"); + BITS(stream, ptr[j], 2, 0, "shadow func"); + j++; + } + + { + PRINTF(stream, "\t TSn.1: 0x%08x\n", ptr[j]); + BITS(stream, ptr[j], 31, 24, "min lod"); + MBZ( ptr[j], 23, 18 ); + FLAG(stream, ptr[j], 17, "kill pixel enable"); + FLAG(stream, ptr[j], 16, "keyed tex filter mode"); + FLAG(stream, ptr[j], 15, "chromakey enable"); + BITS(stream, ptr[j], 14, 12, "tcx wrap mode"); + BITS(stream, ptr[j], 11, 9, "tcy wrap mode"); + BITS(stream, ptr[j], 8, 6, "tcz wrap mode"); + FLAG(stream, ptr[j], 5, "normalized coords"); + BITS(stream, ptr[j], 4, 1, "map (surface) index"); + FLAG(stream, ptr[j], 0, "EAST deinterlacer enable"); + j++; + } + { + PRINTF(stream, "\t TSn.2: 0x%08x (default color)\n", ptr[j]); + j++; + } + } + + stream->offset += len * sizeof(unsigned); + assert(j == len); + return TRUE; +} + +static boolean debug_dest_vars( struct debug_stream *stream, + const char *name, + unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF(stream, "%s (%d dwords):\n", name, len); + PRINTF(stream, "\t0x%08x\n", ptr[j++]); + + { + PRINTF(stream, "\t0x%08x\n", ptr[j]); + FLAG(stream, ptr[j], 31, "early classic ztest"); + FLAG(stream, ptr[j], 30, "opengl tex default color"); + FLAG(stream, ptr[j], 29, "bypass iz"); + FLAG(stream, ptr[j], 28, "lod preclamp"); + BITS(stream, ptr[j], 27, 26, "dither pattern"); + FLAG(stream, ptr[j], 25, "linear gamma blend"); + FLAG(stream, ptr[j], 24, "debug dither"); + BITS(stream, ptr[j], 23, 20, "dstorg x"); + BITS(stream, ptr[j], 19, 16, "dstorg y"); + MBZ (ptr[j], 15, 15 ); + BITS(stream, ptr[j], 14, 12, "422 write select"); + BITS(stream, ptr[j], 11, 8, "cbuf format"); + BITS(stream, ptr[j], 3, 2, "zbuf format"); + FLAG(stream, ptr[j], 1, "vert line stride"); + FLAG(stream, ptr[j], 1, "vert line stride offset"); + j++; + } + + stream->offset += len * sizeof(unsigned); + assert(j == len); + return TRUE; +} + +static boolean debug_buf_info( struct debug_stream *stream, + const char *name, + unsigned len ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF(stream, "%s (%d dwords):\n", name, len); + PRINTF(stream, "\t0x%08x\n", ptr[j++]); + + { + PRINTF(stream, "\t0x%08x\n", ptr[j]); + BITS(stream, ptr[j], 28, 28, "aux buffer id"); + BITS(stream, ptr[j], 27, 24, "buffer id (7=depth, 3=back)"); + FLAG(stream, ptr[j], 23, "use fence regs"); + FLAG(stream, ptr[j], 22, "tiled surface"); + FLAG(stream, ptr[j], 21, "tile walk ymajor"); + MBZ (ptr[j], 20, 14); + BITS(stream, ptr[j], 13, 2, "dword pitch"); + MBZ (ptr[j], 2, 0); + j++; + } + + PRINTF(stream, "\t0x%08x -- buffer base address\n", ptr[j++]); + + stream->offset += len * sizeof(unsigned); + assert(j == len); + return TRUE; +} + +static boolean i915_debug_packet( struct debug_stream *stream ) +{ + unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); + unsigned cmd = *ptr; + + switch (((cmd >> 29) & 0x7)) { + case 0x0: + switch ((cmd >> 23) & 0x3f) { + case 0x0: + return debug(stream, "MI_NOOP", 1); + case 0x3: + return debug(stream, "MI_WAIT_FOR_EVENT", 1); + case 0x4: + return debug(stream, "MI_FLUSH", 1); + case 0xA: + debug(stream, "MI_BATCH_BUFFER_END", 1); + return FALSE; + case 0x22: + return debug(stream, "MI_LOAD_REGISTER_IMM", 3); + case 0x31: + return debug_chain(stream, "MI_BATCH_BUFFER_START", 2); + default: + (void)debug(stream, "UNKNOWN 0x0 case!", 1); + assert(0); + break; + } + break; + case 0x1: + (void) debug(stream, "UNKNOWN 0x1 case!", 1); + assert(0); + break; + case 0x2: + switch ((cmd >> 22) & 0xff) { + case 0x50: + return debug_color_blit(stream, "XY_COLOR_BLT", (cmd & 0xff) + 2); + case 0x53: + return debug_copy_blit(stream, "XY_SRC_COPY_BLT", (cmd & 0xff) + 2); + default: + return debug(stream, "blit command", (cmd & 0xff) + 2); + } + break; + case 0x3: + switch ((cmd >> 24) & 0x1f) { + case 0x6: + return debug(stream, "3DSTATE_ANTI_ALIASING", 1); + case 0x7: + return debug(stream, "3DSTATE_RASTERIZATION_RULES", 1); + case 0x8: + return debug(stream, "3DSTATE_BACKFACE_STENCIL_OPS", 2); + case 0x9: + return debug(stream, "3DSTATE_BACKFACE_STENCIL_MASKS", 1); + case 0xb: + return debug(stream, "3DSTATE_INDEPENDENT_ALPHA_BLEND", 1); + case 0xc: + return debug(stream, "3DSTATE_MODES5", 1); + case 0xd: + return debug_modes4(stream, "3DSTATE_MODES4", 1); + case 0x15: + return debug(stream, "3DSTATE_FOG_COLOR", 1); + case 0x16: + return debug(stream, "3DSTATE_COORD_SET_BINDINGS", 1); + case 0x1c: + /* 3DState16NP */ + switch((cmd >> 19) & 0x1f) { + case 0x10: + return debug(stream, "3DSTATE_SCISSOR_ENABLE", 1); + case 0x11: + return debug(stream, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE", 1); + default: + (void) debug(stream, "UNKNOWN 0x1c case!", 1); + assert(0); + break; + } + break; + case 0x1d: + /* 3DStateMW */ + switch ((cmd >> 16) & 0xff) { + case 0x0: + return debug_map_state(stream, "3DSTATE_MAP_STATE", (cmd & 0x1f) + 2); + case 0x1: + return debug_sampler_state(stream, "3DSTATE_SAMPLER_STATE", (cmd & 0x1f) + 2); + case 0x4: + return debug_load_immediate(stream, "3DSTATE_LOAD_STATE_IMMEDIATE", (cmd & 0xf) + 2); + case 0x5: + return debug_program(stream, "3DSTATE_PIXEL_SHADER_PROGRAM", (cmd & 0x1ff) + 2); + case 0x6: + return debug(stream, "3DSTATE_PIXEL_SHADER_CONSTANTS", (cmd & 0xff) + 2); + case 0x7: + return debug_load_indirect(stream, "3DSTATE_LOAD_INDIRECT", (cmd & 0xff) + 2); + case 0x80: + return debug(stream, "3DSTATE_DRAWING_RECTANGLE", (cmd & 0xffff) + 2); + case 0x81: + return debug(stream, "3DSTATE_SCISSOR_RECTANGLE", (cmd & 0xffff) + 2); + case 0x83: + return debug(stream, "3DSTATE_SPAN_STIPPLE", (cmd & 0xffff) + 2); + case 0x85: + return debug_dest_vars(stream, "3DSTATE_DEST_BUFFER_VARS", (cmd & 0xffff) + 2); + case 0x88: + return debug(stream, "3DSTATE_CONSTANT_BLEND_COLOR", (cmd & 0xffff) + 2); + case 0x89: + return debug(stream, "3DSTATE_FOG_MODE", (cmd & 0xffff) + 2); + case 0x8e: + return debug_buf_info(stream, "3DSTATE_BUFFER_INFO", (cmd & 0xffff) + 2); + case 0x97: + return debug(stream, "3DSTATE_DEPTH_OFFSET_SCALE", (cmd & 0xffff) + 2); + case 0x98: + return debug(stream, "3DSTATE_DEFAULT_Z", (cmd & 0xffff) + 2); + case 0x99: + return debug(stream, "3DSTATE_DEFAULT_DIFFUSE", (cmd & 0xffff) + 2); + case 0x9a: + return debug(stream, "3DSTATE_DEFAULT_SPECULAR", (cmd & 0xffff) + 2); + case 0x9c: + return debug(stream, "3DSTATE_CLEAR_PARAMETERS", (cmd & 0xffff) + 2); + default: + assert(0); + return 0; + } + break; + case 0x1e: + if (cmd & (1 << 23)) + return debug(stream, "???", (cmd & 0xffff) + 1); + else + return debug(stream, "", 1); + break; + case 0x1f: + if ((cmd & (1 << 23)) == 0) + return debug_prim(stream, "3DPRIM (inline)", 1, (cmd & 0x1ffff) + 2); + else if (cmd & (1 << 17)) + { + if ((cmd & 0xffff) == 0) + return debug_variable_length_prim(stream); + else + return debug_prim(stream, "3DPRIM (indexed)", 0, (((cmd & 0xffff) + 1) / 2) + 1); + } + else + return debug_prim(stream, "3DPRIM (indirect sequential)", 0, 2); + break; + default: + return debug(stream, "", 0); + } + default: + assert(0); + return 0; + } + + assert(0); + return 0; +} + + + +void +i915_dump_batchbuffer( struct i915_context *i915 ) +{ + struct debug_stream stream; + unsigned *start = i915->batch_start; + unsigned *end = i915->winsys->batch_start( i915->winsys, 0, 0 ); + unsigned long bytes = (unsigned long) (end - start) * 4; + boolean done = FALSE; + + stream.offset = 0; + stream.ptr = (char *)start; + stream.print_addresses = 0; + stream.winsys = i915->pipe.winsys; + + if (!start || !end) { + stream.winsys->printf( stream.winsys, "\n\nBATCH: ???\n"); + return; + } + + stream.winsys->printf( stream.winsys, "\n\nBATCH: (%d)\n", bytes / 4); + + while (!done && + stream.offset < bytes) + { + if (!i915_debug_packet( &stream )) + break; + + assert(stream.offset <= bytes && + stream.offset >= 0); + } + + stream.winsys->printf( stream.winsys, "END-BATCH\n\n\n"); +} + + diff --git a/src/gallium/drivers/i915simple/i915_debug.h b/src/gallium/drivers/i915simple/i915_debug.h new file mode 100644 index 0000000000..0bcd094233 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_debug.h @@ -0,0 +1,117 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef I915_DEBUG_H +#define I915_DEBUG_H + +#include + +struct i915_context; + +struct debug_stream +{ + unsigned offset; /* current gtt offset */ + char *ptr; /* pointer to gtt offset zero */ + char *end; /* pointer to gtt offset zero */ + unsigned print_addresses; + struct pipe_winsys *winsys; +}; + + +/* Internal functions + */ +void i915_disassemble_program(struct debug_stream *stream, + const unsigned *program, unsigned sz); + +void i915_print_ureg(const char *msg, unsigned ureg); + + +#define DEBUG_BATCH 0x1 +#define DEBUG_BLIT 0x2 +#define DEBUG_BUFFER 0x4 +#define DEBUG_CONSTANTS 0x8 +#define DEBUG_CONTEXT 0x10 +#define DEBUG_DRAW 0x20 +#define DEBUG_DYNAMIC 0x40 +#define DEBUG_FLUSH 0x80 +#define DEBUG_MAP 0x100 +#define DEBUG_PROGRAM 0x200 +#define DEBUG_REGIONS 0x400 +#define DEBUG_SAMPLER 0x800 +#define DEBUG_STATIC 0x1000 +#define DEBUG_SURFACE 0x2000 +#define DEBUG_WINSYS 0x4000 + +#include "pipe/p_compiler.h" + +#if defined(DEBUG) && defined(FILE_DEBUG_FLAG) + +#include "pipe/p_winsys.h" + +static INLINE void +I915_DBG( + struct i915_context *i915, + const char *fmt, + ... ) +{ + if ((i915)->debug & FILE_DEBUG_FLAG) { + va_list args; + char buffer[256]; + + va_start( args, fmt ); + vsprintf( buffer, fmt, args ); + i915->pipe.winsys->printf( i915->pipe.winsys, buffer ); + va_end( args ); + } +} + +#else + +static INLINE void +I915_DBG( + struct i915_context *i915, + const char *fmt, + ... ) +{ + (void) i915; + (void) fmt; +} + +#endif + + +void i915_dump_batchbuffer( struct i915_context *i915 ); + + + +void i915_debug_init( struct i915_context *i915 ); + + +#endif diff --git a/src/gallium/drivers/i915simple/i915_debug_fp.c b/src/gallium/drivers/i915simple/i915_debug_fp.c new file mode 100644 index 0000000000..ebfdb3d93c --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_debug_fp.c @@ -0,0 +1,366 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "i915_reg.h" +#include "i915_debug.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + + +static void +PRINTF( + struct debug_stream *stream, + const char *fmt, + ... ) +{ + va_list args; + char buffer[256]; + + va_start( args, fmt ); + vsprintf( buffer, fmt, args ); + stream->winsys->printf( stream->winsys, buffer ); + va_end( args ); +} + + +static const char *opcodes[0x20] = { + "NOP", + "ADD", + "MOV", + "MUL", + "MAD", + "DP2ADD", + "DP3", + "DP4", + "FRC", + "RCP", + "RSQ", + "EXP", + "LOG", + "CMP", + "MIN", + "MAX", + "FLR", + "MOD", + "TRC", + "SGE", + "SLT", + "TEXLD", + "TEXLDP", + "TEXLDB", + "TEXKILL", + "DCL", + "0x1a", + "0x1b", + "0x1c", + "0x1d", + "0x1e", + "0x1f", +}; + + +static const int args[0x20] = { + 0, /* 0 nop */ + 2, /* 1 add */ + 1, /* 2 mov */ + 2, /* 3 m ul */ + 3, /* 4 mad */ + 3, /* 5 dp2add */ + 2, /* 6 dp3 */ + 2, /* 7 dp4 */ + 1, /* 8 frc */ + 1, /* 9 rcp */ + 1, /* a rsq */ + 1, /* b exp */ + 1, /* c log */ + 3, /* d cmp */ + 2, /* e min */ + 2, /* f max */ + 1, /* 10 flr */ + 1, /* 11 mod */ + 1, /* 12 trc */ + 2, /* 13 sge */ + 2, /* 14 slt */ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + + +static const char *regname[0x8] = { + "R", + "T", + "CONST", + "S", + "OC", + "OD", + "U", + "UNKNOWN", +}; + +static void +print_reg_type_nr(struct debug_stream *stream, unsigned type, unsigned nr) +{ + switch (type) { + case REG_TYPE_T: + switch (nr) { + case T_DIFFUSE: + PRINTF(stream, "T_DIFFUSE"); + return; + case T_SPECULAR: + PRINTF(stream, "T_SPECULAR"); + return; + case T_FOG_W: + PRINTF(stream, "T_FOG_W"); + return; + default: + PRINTF(stream, "T_TEX%d", nr); + return; + } + case REG_TYPE_OC: + if (nr == 0) { + PRINTF(stream, "oC"); + return; + } + break; + case REG_TYPE_OD: + if (nr == 0) { + PRINTF(stream, "oD"); + return; + } + break; + default: + break; + } + + PRINTF(stream, "%s[%d]", regname[type], nr); +} + +#define REG_SWIZZLE_MASK 0x7777 +#define REG_NEGATE_MASK 0x8888 + +#define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ + (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ + (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ + (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) + + +static void +print_reg_neg_swizzle(struct debug_stream *stream, unsigned reg) +{ + int i; + + if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW && + (reg & REG_NEGATE_MASK) == 0) + return; + + PRINTF(stream, "."); + + for (i = 3; i >= 0; i--) { + if (reg & (1 << ((i * 4) + 3))) + PRINTF(stream, "-"); + + switch ((reg >> (i * 4)) & 0x7) { + case 0: + PRINTF(stream, "x"); + break; + case 1: + PRINTF(stream, "y"); + break; + case 2: + PRINTF(stream, "z"); + break; + case 3: + PRINTF(stream, "w"); + break; + case 4: + PRINTF(stream, "0"); + break; + case 5: + PRINTF(stream, "1"); + break; + default: + PRINTF(stream, "?"); + break; + } + } +} + + +static void +print_src_reg(struct debug_stream *stream, unsigned dword) +{ + unsigned nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK; + unsigned type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK; + print_reg_type_nr(stream, type, nr); + print_reg_neg_swizzle(stream, dword); +} + + +static void +print_dest_reg(struct debug_stream *stream, unsigned dword) +{ + unsigned nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK; + unsigned type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK; + print_reg_type_nr(stream, type, nr); + if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) + return; + PRINTF(stream, "."); + if (dword & A0_DEST_CHANNEL_X) + PRINTF(stream, "x"); + if (dword & A0_DEST_CHANNEL_Y) + PRINTF(stream, "y"); + if (dword & A0_DEST_CHANNEL_Z) + PRINTF(stream, "z"); + if (dword & A0_DEST_CHANNEL_W) + PRINTF(stream, "w"); +} + + +#define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT)) +#define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT)) +#define GET_SRC2_REG(r) (r) + + +static void +print_arith_op(struct debug_stream *stream, + unsigned opcode, const unsigned * program) +{ + if (opcode != A0_NOP) { + print_dest_reg(stream, program[0]); + if (program[0] & A0_DEST_SATURATE) + PRINTF(stream, " = SATURATE "); + else + PRINTF(stream, " = "); + } + + PRINTF(stream, "%s ", opcodes[opcode]); + + print_src_reg(stream, GET_SRC0_REG(program[0], program[1])); + if (args[opcode] == 1) { + PRINTF(stream, "\n"); + return; + } + + PRINTF(stream, ", "); + print_src_reg(stream, GET_SRC1_REG(program[1], program[2])); + if (args[opcode] == 2) { + PRINTF(stream, "\n"); + return; + } + + PRINTF(stream, ", "); + print_src_reg(stream, GET_SRC2_REG(program[2])); + PRINTF(stream, "\n"); + return; +} + + +static void +print_tex_op(struct debug_stream *stream, + unsigned opcode, const unsigned * program) +{ + print_dest_reg(stream, program[0] | A0_DEST_CHANNEL_ALL); + PRINTF(stream, " = "); + + PRINTF(stream, "%s ", opcodes[opcode]); + + PRINTF(stream, "S[%d],", program[0] & T0_SAMPLER_NR_MASK); + + print_reg_type_nr(stream, + (program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & + REG_TYPE_MASK, + (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); + PRINTF(stream, "\n"); +} + +static void +print_texkil_op(struct debug_stream *stream, + unsigned opcode, const unsigned * program) +{ + PRINTF(stream, "TEXKIL "); + + print_reg_type_nr(stream, + (program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & + REG_TYPE_MASK, + (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); + PRINTF(stream, "\n"); +} + +static void +print_dcl_op(struct debug_stream *stream, + unsigned opcode, const unsigned * program) +{ + PRINTF(stream, "%s ", opcodes[opcode]); + print_dest_reg(stream, + program[0] | A0_DEST_CHANNEL_ALL); + PRINTF(stream, "\n"); +} + + +void +i915_disassemble_program(struct debug_stream *stream, + const unsigned * program, unsigned sz) +{ + unsigned size = program[0] & 0x1ff; + unsigned i; + + PRINTF(stream, "\t\tBEGIN\n"); + + assert(size + 2 == sz); + + program++; + for (i = 1; i < sz; i += 3, program += 3) { + unsigned opcode = program[0] & (0x1f << 24); + + PRINTF(stream, "\t\t"); + + if ((int) opcode >= A0_NOP && opcode <= A0_SLT) + print_arith_op(stream, opcode >> 24, program); + else if (opcode >= T0_TEXLD && opcode < T0_TEXKILL) + print_tex_op(stream, opcode >> 24, program); + else if (opcode == T0_TEXKILL) + print_texkil_op(stream, opcode >> 24, program); + else if (opcode == D0_DCL) + print_dcl_op(stream, opcode >> 24, program); + else + PRINTF(stream, "Unknown opcode 0x%x\n", opcode); + } + + PRINTF(stream, "\t\tEND\n\n"); +} + + diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c new file mode 100644 index 0000000000..3c2069b827 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_flush.c @@ -0,0 +1,81 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + + +#include "pipe/p_defines.h" +#include "i915_context.h" +#include "i915_reg.h" +#include "i915_batch.h" + + +/** + * In future we may want a fence-like interface instead of finish. + */ +static void i915_flush( struct pipe_context *pipe, + unsigned flags ) +{ + struct i915_context *i915 = i915_context(pipe); + + /* Do we need to emit an MI_FLUSH command to flush the hardware + * caches? + */ + if (flags & (PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE)) { + unsigned flush = MI_FLUSH; + + if (!(flags & PIPE_FLUSH_RENDER_CACHE)) + flush |= INHIBIT_FLUSH_RENDER_CACHE; + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) + flush |= FLUSH_MAP_CACHE; + + if (!BEGIN_BATCH(1, 0)) { + FLUSH_BATCH(); + assert(BEGIN_BATCH(1, 0)); + } + OUT_BATCH( flush ); + ADVANCE_BATCH(); + } + + /* If there are no flags, just flush pending commands to hardware: + */ + FLUSH_BATCH(); + + if (flags & PIPE_FLUSH_WAIT) { + i915->winsys->batch_finish(i915->winsys); + } +} + + + +void i915_init_flush_functions( struct i915_context *i915 ) +{ + i915->pipe.flush = i915_flush; +} diff --git a/src/gallium/drivers/i915simple/i915_fpc.h b/src/gallium/drivers/i915simple/i915_fpc.h new file mode 100644 index 0000000000..8c7b68aefb --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_fpc.h @@ -0,0 +1,213 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef I915_FPC_H +#define I915_FPC_H + +#include "pipe/p_util.h" + +#include "i915_context.h" +#include "i915_reg.h" + + + +#define I915_PROGRAM_SIZE 192 + + + +/** + * Program translation state + */ +struct i915_fp_compile { + const struct pipe_shader_state *shader; + + struct vertex_info *vertex_info; + + uint declarations[I915_PROGRAM_SIZE]; + uint program[I915_PROGRAM_SIZE]; + + uint input_semantic_name[PIPE_MAX_SHADER_INPUTS]; + uint input_semantic_index[PIPE_MAX_SHADER_INPUTS]; + + uint output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; + uint output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; + + /** points into the i915->current.constants array: */ + float (*constants)[4]; + uint num_constants; + uint constant_flags[I915_MAX_CONSTANT]; /**< status of each constant */ + + uint *csr; /**< Cursor, points into program. */ + + uint *decl; /**< Cursor, points into declarations. */ + + uint decl_s; /**< flags for which s regs need to be decl'd */ + uint decl_t; /**< flags for which t regs need to be decl'd */ + + uint temp_flag; /**< Tracks temporary regs which are in use */ + uint utemp_flag; /**< Tracks TYPE_U temporary regs which are in use */ + + uint nr_tex_indirect; + uint nr_tex_insn; + uint nr_alu_insn; + uint nr_decl_insn; + + boolean error; /**< Set if i915_program_error() is called */ + uint wpos_tex; + uint NumNativeInstructions; + uint NumNativeAluInstructions; + uint NumNativeTexInstructions; + uint NumNativeTexIndirections; +}; + + +/* Having zero and one in here makes the definition of swizzle a lot + * easier. + */ +#define UREG_TYPE_SHIFT 29 +#define UREG_NR_SHIFT 24 +#define UREG_CHANNEL_X_NEGATE_SHIFT 23 +#define UREG_CHANNEL_X_SHIFT 20 +#define UREG_CHANNEL_Y_NEGATE_SHIFT 19 +#define UREG_CHANNEL_Y_SHIFT 16 +#define UREG_CHANNEL_Z_NEGATE_SHIFT 15 +#define UREG_CHANNEL_Z_SHIFT 12 +#define UREG_CHANNEL_W_NEGATE_SHIFT 11 +#define UREG_CHANNEL_W_SHIFT 8 +#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5 +#define UREG_CHANNEL_ZERO_SHIFT 4 +#define UREG_CHANNEL_ONE_NEGATE_MBZ 1 +#define UREG_CHANNEL_ONE_SHIFT 0 + +#define UREG_BAD 0xffffffff /* not a valid ureg */ + +#define X SRC_X +#define Y SRC_Y +#define Z SRC_Z +#define W SRC_W +#define ZERO SRC_ZERO +#define ONE SRC_ONE + +/* Construct a ureg: + */ +#define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) | \ + ((nr) << UREG_NR_SHIFT) | \ + (X << UREG_CHANNEL_X_SHIFT) | \ + (Y << UREG_CHANNEL_Y_SHIFT) | \ + (Z << UREG_CHANNEL_Z_SHIFT) | \ + (W << UREG_CHANNEL_W_SHIFT) | \ + (ZERO << UREG_CHANNEL_ZERO_SHIFT) | \ + (ONE << UREG_CHANNEL_ONE_SHIFT)) + +#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20)) +#define CHANNEL_SRC( src, channel ) (src>>(channel*4)) + +#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)®_TYPE_MASK) +#define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)®_NR_MASK) + + + +#define UREG_XYZW_CHANNEL_MASK 0x00ffff00 + +/* One neat thing about the UREG representation: + */ +static INLINE int +swizzle(int reg, uint x, uint y, uint z, uint w) +{ + assert(x <= SRC_ONE); + assert(y <= SRC_ONE); + assert(z <= SRC_ONE); + assert(w <= SRC_ONE); + return ((reg & ~UREG_XYZW_CHANNEL_MASK) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, x), 0) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, y), 1) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, z), 2) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, w), 3)); +} + + + +/*********************************************************************** + * Public interface for the compiler + */ +extern void i915_translate_fragment_program( struct i915_context *i915 ); + + + +extern uint i915_get_temp(struct i915_fp_compile *p); +extern uint i915_get_utemp(struct i915_fp_compile *p); +extern void i915_release_utemps(struct i915_fp_compile *p); + + +extern uint i915_emit_texld(struct i915_fp_compile *p, + uint dest, + uint destmask, + uint sampler, uint coord, uint op); + +extern uint i915_emit_arith(struct i915_fp_compile *p, + uint op, + uint dest, + uint mask, + uint saturate, + uint src0, uint src1, uint src2); + +extern uint i915_emit_decl(struct i915_fp_compile *p, + uint type, uint nr, uint d0_flags); + + +extern uint i915_emit_const1f(struct i915_fp_compile *p, float c0); + +extern uint i915_emit_const2f(struct i915_fp_compile *p, + float c0, float c1); + +extern uint i915_emit_const4fv(struct i915_fp_compile *p, + const float * c); + +extern uint i915_emit_const4f(struct i915_fp_compile *p, + float c0, float c1, + float c2, float c3); + + +/*====================================================================== + * i915_fpc_debug.c + */ +extern void i915_disassemble_program(const uint * program, uint sz); + + +/*====================================================================== + * i915_fpc_translate.c + */ + +extern void +i915_program_error(struct i915_fp_compile *p, const char *msg, ...); + +extern void +i915_translate_fragment_program(struct i915_context *i915); + + +#endif diff --git a/src/gallium/drivers/i915simple/i915_fpc_emit.c b/src/gallium/drivers/i915simple/i915_fpc_emit.c new file mode 100644 index 0000000000..74924ff0a1 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_fpc_emit.c @@ -0,0 +1,375 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_fpc.h" + + +#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT) +#define A1_SRC0( reg ) (((reg)&UREG_MASK)<>UREG_A1_SRC1_SHIFT_LEFT) +#define A2_SRC1( reg ) (((reg)&UREG_MASK)<>UREG_A2_SRC2_SHIFT_LEFT) + +/* These are special, and don't have swizzle/negate bits. + */ +#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<temp_flag); + if (!bit) { + i915_program_error(p, "i915_get_temp: out of temporaries\n"); + return 0; + } + + p->temp_flag |= 1 << (bit - 1); + return UREG(REG_TYPE_R, (bit - 1)); +} + + +uint +i915_get_utemp(struct i915_fp_compile * p) +{ + int bit = ffs(~p->utemp_flag); + if (!bit) { + i915_program_error(p, "i915_get_utemp: out of temporaries\n"); + return 0; + } + + p->utemp_flag |= 1 << (bit - 1); + return UREG(REG_TYPE_U, (bit - 1)); +} + +void +i915_release_utemps(struct i915_fp_compile *p) +{ + p->utemp_flag = ~0x7; +} + + +uint +i915_emit_decl(struct i915_fp_compile *p, + uint type, uint nr, uint d0_flags) +{ + uint reg = UREG(type, nr); + + if (type == REG_TYPE_T) { + if (p->decl_t & (1 << nr)) + return reg; + + p->decl_t |= (1 << nr); + } + else if (type == REG_TYPE_S) { + if (p->decl_s & (1 << nr)) + return reg; + + p->decl_s |= (1 << nr); + } + else + return reg; + + *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags); + *(p->decl++) = D1_MBZ; + *(p->decl++) = D2_MBZ; + + p->nr_decl_insn++; + return reg; +} + +uint +i915_emit_arith(struct i915_fp_compile * p, + uint op, + uint dest, + uint mask, + uint saturate, uint src0, uint src1, uint src2) +{ + uint c[3]; + uint nr_const = 0; + + assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); + dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); + assert(dest); + + if (GET_UREG_TYPE(src0) == REG_TYPE_CONST) + c[nr_const++] = 0; + if (GET_UREG_TYPE(src1) == REG_TYPE_CONST) + c[nr_const++] = 1; + if (GET_UREG_TYPE(src2) == REG_TYPE_CONST) + c[nr_const++] = 2; + + /* Recursively call this function to MOV additional const values + * into temporary registers. Use utemp registers for this - + * currently shouldn't be possible to run out, but keep an eye on + * this. + */ + if (nr_const > 1) { + uint s[3], first, i, old_utemp_flag; + + s[0] = src0; + s[1] = src1; + s[2] = src2; + old_utemp_flag = p->utemp_flag; + + first = GET_UREG_NR(s[c[0]]); + for (i = 1; i < nr_const; i++) { + if (GET_UREG_NR(s[c[i]]) != first) { + uint tmp = i915_get_utemp(p); + + i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0, + s[c[i]], 0, 0); + s[c[i]] = tmp; + } + } + + src0 = s[0]; + src1 = s[1]; + src2 = s[2]; + p->utemp_flag = old_utemp_flag; /* restore */ + } + + *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); + *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1)); + *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2)); + + p->nr_alu_insn++; + return dest; +} + +uint i915_emit_texld( struct i915_fp_compile *p, + uint dest, + uint destmask, + uint sampler, + uint coord, + uint op ) +{ + uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord)); + if (coord != k) { + /* No real way to work around this in the general case - need to + * allocate and declare a new temporary register (a utemp won't + * do). Will fallback for now. + */ + i915_program_error(p, "Can't (yet) swizzle TEX arguments"); + assert(0); + return 0; + } + + /* Don't worry about saturate as we only support + */ + if (destmask != A0_DEST_CHANNEL_ALL) { + uint tmp = i915_get_utemp(p); + i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op ); + i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 ); + return dest; + } + else { + assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); + assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); + + if (GET_UREG_TYPE(coord) != REG_TYPE_T) { + p->nr_tex_indirect++; + } + + *(p->csr++) = (op | + T0_DEST( dest ) | + T0_SAMPLER( sampler )); + + *(p->csr++) = T1_ADDRESS_REG( coord ); + *(p->csr++) = T2_MBZ; + + p->nr_tex_insn++; + return dest; + } +} + + +uint +i915_emit_const1f(struct i915_fp_compile * p, float c0) +{ + unsigned reg, idx; + + if (c0 == 0.0) + return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO); + if (c0 == 1.0) + return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE); + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + continue; + for (idx = 0; idx < 4; idx++) { + if (!(p->constant_flags[reg] & (1 << idx)) || + p->constants[reg][idx] == c0) { + p->constants[reg][idx] = c0; + p->constant_flags[reg] |= 1 << idx; + if (reg + 1 > p->num_constants) + p->num_constants = reg + 1; + return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); + } + } + } + + i915_program_error(p, "i915_emit_const1f: out of constants\n"); + return 0; +} + +uint +i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1) +{ + unsigned reg, idx; + + if (c0 == 0.0) + return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W); + if (c0 == 1.0) + return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W); + + if (c1 == 0.0) + return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W); + if (c1 == 1.0) + return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0xf || + p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + continue; + for (idx = 0; idx < 3; idx++) { + if (!(p->constant_flags[reg] & (3 << idx))) { + p->constants[reg][idx + 0] = c0; + p->constants[reg][idx + 1] = c1; + p->constant_flags[reg] |= 3 << idx; + if (reg + 1 > p->num_constants) + p->num_constants = reg + 1; + return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE); + } + } + } + + i915_program_error(p, "i915_emit_const2f: out of constants\n"); + return 0; +} + + + +uint +i915_emit_const4f(struct i915_fp_compile * p, + float c0, float c1, float c2, float c3) +{ + unsigned reg; + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0xf && + p->constants[reg][0] == c0 && + p->constants[reg][1] == c1 && + p->constants[reg][2] == c2 && + p->constants[reg][3] == c3) { + return UREG(REG_TYPE_CONST, reg); + } + else if (p->constant_flags[reg] == 0) { + + p->constants[reg][0] = c0; + p->constants[reg][1] = c1; + p->constants[reg][2] = c2; + p->constants[reg][3] = c3; + p->constant_flags[reg] = 0xf; + if (reg + 1 > p->num_constants) + p->num_constants = reg + 1; + return UREG(REG_TYPE_CONST, reg); + } + } + + i915_program_error(p, "i915_emit_const4f: out of constants\n"); + return 0; +} + + +uint +i915_emit_const4fv(struct i915_fp_compile * p, const float * c) +{ + return i915_emit_const4f(p, c[0], c[1], c[2], c[3]); +} + + +#if 00000/*UNUSED*/ +/* Reserve a slot in the constant file for a Mesa state parameter. + * These will later need to be tracked on statechanges, but that is + * done elsewhere. + */ +uint +i915_emit_param4fv(struct i915_fp_compile * p, const float * values) +{ + struct i915_fragment_program *fp = p->fp; + int i; + + for (i = 0; i < fp->nr_params; i++) { + if (fp->param[i].values == values) + return UREG(REG_TYPE_CONST, fp->param[i].reg); + } + + if (p->constants->nr_constants == I915_MAX_CONSTANT || + fp->nr_params == I915_MAX_CONSTANT) { + i915_program_error(p, "i915_emit_param4fv: out of constants\n"); + return 0; + } + + { + int reg = p->constants->nr_constants++; + int i = fp->nr_params++; + + assert (p->constant_flags[reg] == 0); + p->constant_flags[reg] = I915_CONSTFLAG_PARAM; + + fp->param[i].values = values; + fp->param[i].reg = reg; + + return UREG(REG_TYPE_CONST, reg); + } +} +#endif diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c new file mode 100644 index 0000000000..868f0c7e04 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -0,0 +1,1135 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_fpc.h" + +#include "pipe/p_shader_tokens.h" +#include "pipe/tgsi/util/tgsi_parse.h" + +#include "pipe/draw/draw_vertex.h" + + +/** + * Simple pass-through fragment shader to use when we don't have + * a real shader (or it fails to compile for some reason). + */ +static unsigned passthrough[] = +{ + _3DSTATE_PIXEL_SHADER_PROGRAM | ((2*3)-1), + + /* declare input color: + */ + (D0_DCL | + (REG_TYPE_T << D0_TYPE_SHIFT) | + (T_DIFFUSE << D0_NR_SHIFT) | + D0_CHANNEL_ALL), + 0, + 0, + + /* move to output color: + */ + (A0_MOV | + (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | + A0_DEST_CHANNEL_ALL | + (REG_TYPE_T << A0_SRC0_TYPE_SHIFT) | + (T_DIFFUSE << A0_SRC0_NR_SHIFT)), + 0x01230000, /* .xyzw */ + 0 +}; + + +/* 1, -1/3!, 1/5!, -1/7! */ +static const float sin_constants[4] = { 1.0, + -1.0f / (3 * 2 * 1), + 1.0f / (5 * 4 * 3 * 2 * 1), + -1.0f / (7 * 6 * 5 * 4 * 3 * 2 * 1) +}; + +/* 1, -1/2!, 1/4!, -1/6! */ +static const float cos_constants[4] = { 1.0, + -1.0f / (2 * 1), + 1.0f / (4 * 3 * 2 * 1), + -1.0f / (6 * 5 * 4 * 3 * 2 * 1) +}; + + + +/** + * component-wise negation of ureg + */ +static INLINE int +negate(int reg, int x, int y, int z, int w) +{ + /* Another neat thing about the UREG representation */ + return reg ^ (((x & 1) << UREG_CHANNEL_X_NEGATE_SHIFT) | + ((y & 1) << UREG_CHANNEL_Y_NEGATE_SHIFT) | + ((z & 1) << UREG_CHANNEL_Z_NEGATE_SHIFT) | + ((w & 1) << UREG_CHANNEL_W_NEGATE_SHIFT)); +} + + +static void +i915_use_passthrough_shader(struct i915_context *i915) +{ + debug_printf("**** Using i915 pass-through fragment shader\n"); + + i915->current.program = (uint *) MALLOC(sizeof(passthrough)); + if (i915->current.program) { + memcpy(i915->current.program, passthrough, sizeof(passthrough)); + i915->current.program_len = Elements(passthrough); + } + + i915->current.num_constants[PIPE_SHADER_FRAGMENT] = 0; + i915->current.num_user_constants[PIPE_SHADER_FRAGMENT] = 0; +} + + +void +i915_program_error(struct i915_fp_compile *p, const char *msg, ...) +{ + va_list args; + char buffer[1024]; + + debug_printf("i915_program_error: "); + va_start( args, msg ); + vsprintf( buffer, msg, args ); + va_end( args ); + debug_printf(buffer); + debug_printf("\n"); + + p->error = 1; +} + + + +/** + * Construct a ureg for the given source register. Will emit + * constants, apply swizzling and negation as needed. + */ +static uint +src_vector(struct i915_fp_compile *p, + const struct tgsi_full_src_register *source) +{ + uint index = source->SrcRegister.Index; + uint src, sem_name, sem_ind; + + switch (source->SrcRegister.File) { + case TGSI_FILE_TEMPORARY: + if (source->SrcRegister.Index >= I915_MAX_TEMPORARY) { + i915_program_error(p, "Exceeded max temporary reg"); + return 0; + } + src = UREG(REG_TYPE_R, index); + break; + case TGSI_FILE_INPUT: + /* XXX: Packing COL1, FOGC into a single attribute works for + * texenv programs, but will fail for real fragment programs + * that use these attributes and expect them to be a full 4 + * components wide. Could use a texcoord to pass these + * attributes if necessary, but that won't work in the general + * case. + * + * We also use a texture coordinate to pass wpos when possible. + */ + + /* use vertex format info to map a slot number to a VF attrib */ + assert(index < p->vertex_info->num_attribs); + + sem_name = p->input_semantic_name[index]; + sem_ind = p->input_semantic_index[index]; + + switch (sem_name) { + case TGSI_SEMANTIC_POSITION: + debug_printf("SKIP SEM POS\n"); + /* + assert(p->wpos_tex != -1); + src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL); + */ + break; + case TGSI_SEMANTIC_COLOR: + if (sem_ind == 0) { + src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL); + } + else { + /* secondary color */ + assert(sem_ind == 1); + src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ); + src = swizzle(src, X, Y, Z, ONE); + } + break; + case TGSI_SEMANTIC_FOG: + src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W); + src = swizzle(src, W, W, W, W); + break; + case TGSI_SEMANTIC_GENERIC: + /* usually a texcoord */ + src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + sem_ind, D0_CHANNEL_ALL); + break; + default: + i915_program_error(p, "Bad source->Index"); + return 0; + } + break; + + case TGSI_FILE_IMMEDIATE: + /* XXX unfinished - need to append immediates onto const buffer */ + /* fall-through */ + case TGSI_FILE_CONSTANT: + src = UREG(REG_TYPE_CONST, index); + break; + + default: + i915_program_error(p, "Bad source->File"); + return 0; + } + + if (source->SrcRegister.Extended) { + src = swizzle(src, + source->SrcRegisterExtSwz.ExtSwizzleX, + source->SrcRegisterExtSwz.ExtSwizzleY, + source->SrcRegisterExtSwz.ExtSwizzleZ, + source->SrcRegisterExtSwz.ExtSwizzleW); + } + else { + src = swizzle(src, + source->SrcRegister.SwizzleX, + source->SrcRegister.SwizzleY, + source->SrcRegister.SwizzleZ, + source->SrcRegister.SwizzleW); + } + + + /* There's both negate-all-components and per-component negation. + * Try to handle both here. + */ + { + int nx = source->SrcRegisterExtSwz.NegateX; + int ny = source->SrcRegisterExtSwz.NegateY; + int nz = source->SrcRegisterExtSwz.NegateZ; + int nw = source->SrcRegisterExtSwz.NegateW; + if (source->SrcRegister.Negate) { + nx = !nx; + ny = !ny; + nz = !nz; + nw = !nw; + } + src = negate(src, nx, ny, nz, nw); + } + + /* no abs() or post-abs negation */ +#if 0 + /* XXX assertions disabled to allow arbfplight.c to run */ + /* XXX enable these assertions, or fix things */ + assert(!source->SrcRegisterExtMod.Absolute); + assert(!source->SrcRegisterExtMod.Negate); +#endif + return src; +} + + +/** + * Construct a ureg for a destination register. + */ +static uint +get_result_vector(struct i915_fp_compile *p, + const struct tgsi_full_dst_register *dest) +{ + switch (dest->DstRegister.File) { + case TGSI_FILE_OUTPUT: + { + uint sem_name = p->output_semantic_name[dest->DstRegister.Index]; + switch (sem_name) { + case TGSI_SEMANTIC_POSITION: + return UREG(REG_TYPE_OD, 0); + case TGSI_SEMANTIC_COLOR: + return UREG(REG_TYPE_OC, 0); + default: + i915_program_error(p, "Bad inst->DstReg.Index/semantics"); + return 0; + } + } + case TGSI_FILE_TEMPORARY: + return UREG(REG_TYPE_R, dest->DstRegister.Index); + default: + i915_program_error(p, "Bad inst->DstReg.File"); + return 0; + } +} + + +/** + * Compute flags for saturation and writemask. + */ +static uint +get_result_flags(const struct tgsi_full_instruction *inst) +{ + const uint writeMask + = inst->FullDstRegisters[0].DstRegister.WriteMask; + uint flags = 0x0; + + if (inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) + flags |= A0_DEST_SATURATE; + + if (writeMask & TGSI_WRITEMASK_X) + flags |= A0_DEST_CHANNEL_X; + if (writeMask & TGSI_WRITEMASK_Y) + flags |= A0_DEST_CHANNEL_Y; + if (writeMask & TGSI_WRITEMASK_Z) + flags |= A0_DEST_CHANNEL_Z; + if (writeMask & TGSI_WRITEMASK_W) + flags |= A0_DEST_CHANNEL_W; + + return flags; +} + + +/** + * Convert TGSI_TEXTURE_x token to DO_SAMPLE_TYPE_x token + */ +static uint +translate_tex_src_target(struct i915_fp_compile *p, uint tex) +{ + switch (tex) { + case TGSI_TEXTURE_1D: + return D0_SAMPLE_TYPE_2D; + case TGSI_TEXTURE_2D: + return D0_SAMPLE_TYPE_2D; + case TGSI_TEXTURE_RECT: + return D0_SAMPLE_TYPE_2D; + case TGSI_TEXTURE_3D: + return D0_SAMPLE_TYPE_VOLUME; + case TGSI_TEXTURE_CUBE: + return D0_SAMPLE_TYPE_CUBE; + default: + i915_program_error(p, "TexSrc type"); + return 0; + } +} + + +/** + * Generate texel lookup instruction. + */ +static void +emit_tex(struct i915_fp_compile *p, + const struct tgsi_full_instruction *inst, + uint opcode) +{ + uint texture = inst->InstructionExtTexture.Texture; + uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; + uint tex = translate_tex_src_target( p, texture ); + uint sampler = i915_emit_decl(p, REG_TYPE_S, unit, tex); + uint coord = src_vector( p, &inst->FullSrcRegisters[0]); + + i915_emit_texld( p, + get_result_vector( p, &inst->FullDstRegisters[0] ), + get_result_flags( inst ), + sampler, + coord, + opcode); +} + + +/** + * Generate a simple arithmetic instruction + * \param opcode the i915 opcode + * \param numArgs the number of input/src arguments + */ +static void +emit_simple_arith(struct i915_fp_compile *p, + const struct tgsi_full_instruction *inst, + uint opcode, uint numArgs) +{ + uint arg1, arg2, arg3; + + assert(numArgs <= 3); + + arg1 = (numArgs < 1) ? 0 : src_vector( p, &inst->FullSrcRegisters[0] ); + arg2 = (numArgs < 2) ? 0 : src_vector( p, &inst->FullSrcRegisters[1] ); + arg3 = (numArgs < 3) ? 0 : src_vector( p, &inst->FullSrcRegisters[2] ); + + i915_emit_arith( p, + opcode, + get_result_vector( p, &inst->FullDstRegisters[0]), + get_result_flags( inst ), 0, + arg1, + arg2, + arg3 ); +} + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +/* + * Translate TGSI instruction to i915 instruction. + * + * Possible concerns: + * + * SIN, COS -- could use another taylor step? + * LIT -- results seem a little different to sw mesa + * LOG -- different to mesa on negative numbers, but this is conformant. + */ +static void +i915_translate_instruction(struct i915_fp_compile *p, + const struct tgsi_full_instruction *inst) +{ + uint writemask; + uint src0, src1, src2, flags; + uint tmp = 0; + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ABS: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + i915_emit_arith(p, + A0_MAX, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + src0, negate(src0, 1, 1, 1, 1), 0); + break; + + case TGSI_OPCODE_ADD: + emit_simple_arith(p, inst, A0_ADD, 2); + break; + + case TGSI_OPCODE_CMP: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + src1 = src_vector(p, &inst->FullSrcRegisters[1]); + src2 = src_vector(p, &inst->FullSrcRegisters[2]); + i915_emit_arith(p, A0_CMP, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), + 0, src0, src2, src1); /* NOTE: order of src2, src1 */ + break; + + case TGSI_OPCODE_COS: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + src0, i915_emit_const1f(p, 1.0f / (float) (M_PI * 2.0)), 0); + + i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); + + /* By choosing different taylor constants, could get rid of this mul: + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + tmp, i915_emit_const1f(p, (float) (M_PI * 2.0)), 0); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, 1 + * t0 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 + * result = DP4 t0, cos_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(tmp, X, X, ONE, ONE), + swizzle(tmp, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, Y, X, ONE), + swizzle(tmp, X, X, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, X, Z, ONE), + swizzle(tmp, Z, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + swizzle(tmp, ONE, Z, Y, X), + i915_emit_const4fv(p, cos_constants), 0); + break; + + case TGSI_OPCODE_DP3: + emit_simple_arith(p, inst, A0_DP3, 2); + break; + + case TGSI_OPCODE_DP4: + emit_simple_arith(p, inst, A0_DP4, 2); + break; + + case TGSI_OPCODE_DPH: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + src1 = src_vector(p, &inst->FullSrcRegisters[1]); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + swizzle(src0, X, Y, Z, ONE), src1, 0); + break; + + case TGSI_OPCODE_DST: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + src1 = src_vector(p, &inst->FullSrcRegisters[1]); + + /* result[0] = 1 * 1; + * result[1] = a[1] * b[1]; + * result[2] = a[2] * 1; + * result[3] = 1 * b[3]; + */ + i915_emit_arith(p, + A0_MUL, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + swizzle(src0, ONE, Y, Z, ONE), + swizzle(src1, ONE, Y, ONE, W), 0); + break; + + case TGSI_OPCODE_END: + /* no-op */ + break; + + case TGSI_OPCODE_EX2: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + + i915_emit_arith(p, + A0_EXP, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case TGSI_OPCODE_FLR: + emit_simple_arith(p, inst, A0_FLR, 1); + break; + + case TGSI_OPCODE_FRC: + emit_simple_arith(p, inst, A0_FRC, 1); + break; + + case TGSI_OPCODE_KIL: + /* unconditional kill */ + assert(0); /* not tested yet */ +#if 0 + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + tmp = i915_get_utemp(p); + + i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */ + 0, src0, T0_TEXKILL); +#endif + break; + + case TGSI_OPCODE_KILP: + /* kill if src[0].x < 0 || src[0].y < 0 ... */ + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + tmp = i915_get_utemp(p); + + i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */ + 0, src0, T0_TEXKILL); + break; + + case TGSI_OPCODE_LG2: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + + i915_emit_arith(p, + A0_LOG, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case TGSI_OPCODE_LIT: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + tmp = i915_get_utemp(p); + + /* tmp = max( a.xyzw, a.00zw ) + * XXX: Clamp tmp.w to -128..128 + * tmp.y = log(tmp.y) + * tmp.y = tmp.w * tmp.y + * tmp.y = exp(tmp.y) + * result = cmp (a.11-x1, a.1x01, a.1xy1 ) + */ + i915_emit_arith(p, A0_MAX, tmp, A0_DEST_CHANNEL_ALL, 0, + src0, swizzle(src0, ZERO, ZERO, Z, W), 0); + + i915_emit_arith(p, A0_LOG, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, Y, Y, Y, Y), 0, 0); + + i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, ZERO, Y, ZERO, ZERO), + swizzle(tmp, ZERO, W, ZERO, ZERO), 0); + + i915_emit_arith(p, A0_EXP, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, Y, Y, Y, Y), 0, 0); + + i915_emit_arith(p, A0_CMP, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + negate(swizzle(tmp, ONE, ONE, X, ONE), 0, 0, 1, 0), + swizzle(tmp, ONE, X, ZERO, ONE), + swizzle(tmp, ONE, X, Y, ONE)); + + break; + + case TGSI_OPCODE_LRP: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + src1 = src_vector(p, &inst->FullSrcRegisters[1]); + src2 = src_vector(p, &inst->FullSrcRegisters[2]); + flags = get_result_flags(inst); + tmp = i915_get_utemp(p); + + /* b*a + c*(1-a) + * + * b*a + c - ca + * + * tmp = b*a + c, + * result = (-c)*a + tmp + */ + i915_emit_arith(p, A0_MAD, tmp, + flags & A0_DEST_CHANNEL_ALL, 0, src1, src0, src2); + + i915_emit_arith(p, A0_MAD, + get_result_vector(p, &inst->FullDstRegisters[0]), + flags, 0, negate(src2, 1, 1, 1, 1), src0, tmp); + break; + + case TGSI_OPCODE_MAD: + emit_simple_arith(p, inst, A0_MAD, 3); + break; + + case TGSI_OPCODE_MAX: + emit_simple_arith(p, inst, A0_MAX, 2); + break; + + case TGSI_OPCODE_MIN: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + src1 = src_vector(p, &inst->FullSrcRegisters[1]); + tmp = i915_get_utemp(p); + flags = get_result_flags(inst); + + i915_emit_arith(p, + A0_MAX, + tmp, flags & A0_DEST_CHANNEL_ALL, 0, + negate(src0, 1, 1, 1, 1), + negate(src1, 1, 1, 1, 1), 0); + + i915_emit_arith(p, + A0_MOV, + get_result_vector(p, &inst->FullDstRegisters[0]), + flags, 0, negate(tmp, 1, 1, 1, 1), 0, 0); + break; + + case TGSI_OPCODE_MOV: + /* aka TGSI_OPCODE_SWZ */ + emit_simple_arith(p, inst, A0_MOV, 1); + break; + + case TGSI_OPCODE_MUL: + emit_simple_arith(p, inst, A0_MUL, 2); + break; + + case TGSI_OPCODE_POW: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + src1 = src_vector(p, &inst->FullSrcRegisters[1]); + tmp = i915_get_utemp(p); + flags = get_result_flags(inst); + + /* XXX: masking on intermediate values, here and elsewhere. + */ + i915_emit_arith(p, + A0_LOG, + tmp, A0_DEST_CHANNEL_X, 0, + swizzle(src0, X, X, X, X), 0, 0); + + i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, tmp, src1, 0); + + i915_emit_arith(p, + A0_EXP, + get_result_vector(p, &inst->FullDstRegisters[0]), + flags, 0, swizzle(tmp, X, X, X, X), 0, 0); + break; + + case TGSI_OPCODE_RET: + /* XXX: no-op? */ + break; + + case TGSI_OPCODE_RCP: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + + i915_emit_arith(p, + A0_RCP, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case TGSI_OPCODE_RSQ: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + + i915_emit_arith(p, + A0_RSQ, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case TGSI_OPCODE_SCS: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + tmp = i915_get_utemp(p); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x + * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x + * scs.x = DP4 t1, sin_constants + * t1 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 + * scs.y = DP4 t1, cos_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(src0, X, X, ONE, ONE), + swizzle(src0, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, X, Y), + swizzle(tmp, X, X, ONE, ONE), 0); + + writemask = inst->FullDstRegisters[0].DstRegister.WriteMask; + + if (writemask & TGSI_WRITEMASK_Y) { + uint tmp1; + + if (writemask & TGSI_WRITEMASK_X) + tmp1 = i915_get_utemp(p); + else + tmp1 = tmp; + + i915_emit_arith(p, + A0_MUL, + tmp1, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, Y, W), + swizzle(tmp, X, Z, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, &inst->FullDstRegisters[0]), + A0_DEST_CHANNEL_Y, 0, + swizzle(tmp1, W, Z, Y, X), + i915_emit_const4fv(p, sin_constants), 0); + } + + if (writemask & TGSI_WRITEMASK_X) { + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, X, Z, ONE), + swizzle(tmp, Z, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, &inst->FullDstRegisters[0]), + A0_DEST_CHANNEL_X, 0, + swizzle(tmp, ONE, Z, Y, X), + i915_emit_const4fv(p, cos_constants), 0); + } + break; + + case TGSI_OPCODE_SGE: + emit_simple_arith(p, inst, A0_SGE, 2); + break; + + case TGSI_OPCODE_SIN: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + src0, i915_emit_const1f(p, 1.0f / (float) (M_PI * 2.0)), 0); + + i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); + + /* By choosing different taylor constants, could get rid of this mul: + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + tmp, i915_emit_const1f(p, (float) (M_PI * 2.0)), 0); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x + * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x + * result = DP4 t1.wzyx, sin_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(tmp, X, X, ONE, ONE), + swizzle(tmp, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, X, Y), + swizzle(tmp, X, X, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, Y, W), + swizzle(tmp, X, Z, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + swizzle(tmp, W, Z, Y, X), + i915_emit_const4fv(p, sin_constants), 0); + break; + + case TGSI_OPCODE_SLT: + emit_simple_arith(p, inst, A0_SLT, 2); + break; + + case TGSI_OPCODE_SUB: + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + src1 = src_vector(p, &inst->FullSrcRegisters[1]); + + i915_emit_arith(p, + A0_ADD, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + src0, negate(src1, 1, 1, 1, 1), 0); + break; + + case TGSI_OPCODE_TEX: + if (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide + == TGSI_EXTSWIZZLE_W) { + emit_tex(p, inst, T0_TEXLDP); + } + else { + emit_tex(p, inst, T0_TEXLD); + } + break; + + case TGSI_OPCODE_TXB: + emit_tex(p, inst, T0_TEXLDB); + break; + + case TGSI_OPCODE_XPD: + /* Cross product: + * result.x = src0.y * src1.z - src0.z * src1.y; + * result.y = src0.z * src1.x - src0.x * src1.z; + * result.z = src0.x * src1.y - src0.y * src1.x; + * result.w = undef; + */ + src0 = src_vector(p, &inst->FullSrcRegisters[0]); + src1 = src_vector(p, &inst->FullSrcRegisters[1]); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(src0, Z, X, Y, ONE), + swizzle(src1, Y, Z, X, ONE), 0); + + i915_emit_arith(p, + A0_MAD, + get_result_vector(p, &inst->FullDstRegisters[0]), + get_result_flags(inst), 0, + swizzle(src0, Y, Z, X, ONE), + swizzle(src1, Z, X, Y, ONE), + negate(tmp, 1, 1, 1, 0)); + break; + + default: + i915_program_error(p, "bad opcode %d", inst->Instruction.Opcode); + return; + } + + i915_release_utemps(p); +} + + +/** + * Translate TGSI fragment shader into i915 hardware instructions. + * \param p the translation state + * \param tokens the TGSI token array + */ +static void +i915_translate_instructions(struct i915_fp_compile *p, + const struct tgsi_token *tokens) +{ + struct tgsi_parse_context parse; + + tgsi_parse_init( &parse, tokens ); + + while( !tgsi_parse_end_of_tokens( &parse ) ) { + + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + if (parse.FullToken.FullDeclaration.Declaration.File + == TGSI_FILE_INPUT) { + /* save input register info for use in src_vector() */ + uint ind, sem, semi; + ind = parse.FullToken.FullDeclaration.u.DeclarationRange.First; + sem = parse.FullToken.FullDeclaration.Semantic.SemanticName; + semi = parse.FullToken.FullDeclaration.Semantic.SemanticIndex; + /*debug_printf("FS Input DECL [%u] sem %u\n", ind, sem);*/ + p->input_semantic_name[ind] = sem; + p->input_semantic_index[ind] = semi; + } + else if (parse.FullToken.FullDeclaration.Declaration.File + == TGSI_FILE_OUTPUT) { + /* save output register info for use in get_result_vector() */ + uint ind, sem, semi; + ind = parse.FullToken.FullDeclaration.u.DeclarationRange.First; + sem = parse.FullToken.FullDeclaration.Semantic.SemanticName; + semi = parse.FullToken.FullDeclaration.Semantic.SemanticIndex; + /*debug_printf("FS Output DECL [%u] sem %u\n", ind, sem);*/ + p->output_semantic_name[ind] = sem; + p->output_semantic_index[ind] = semi; + } + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + /* XXX append the immediate to the const buffer... */ + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + i915_translate_instruction(p, &parse.FullToken.FullInstruction); + break; + + default: + assert( 0 ); + } + + } /* while */ + + tgsi_parse_free (&parse); +} + + +static struct i915_fp_compile * +i915_init_compile(struct i915_context *i915, + const struct pipe_shader_state *fs) +{ + struct i915_fp_compile *p = CALLOC_STRUCT(i915_fp_compile); + + p->shader = i915->fs; + + p->vertex_info = &i915->current.vertex_info; + + /* new constants found during translation get appended after the + * user-provided constants. + */ + p->constants = i915->current.constants[PIPE_SHADER_FRAGMENT]; + p->num_constants = i915->current.num_user_constants[PIPE_SHADER_FRAGMENT]; + + p->nr_tex_indirect = 1; /* correct? */ + p->nr_tex_insn = 0; + p->nr_alu_insn = 0; + p->nr_decl_insn = 0; + + memset(p->constant_flags, 0, sizeof(p->constant_flags)); + + p->csr = p->program; + p->decl = p->declarations; + p->decl_s = 0; + p->decl_t = 0; + p->temp_flag = 0xffff000; + p->utemp_flag = ~0x7; + + p->wpos_tex = -1; + + /* initialize the first program word */ + *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; + + return p; +} + + +/* Copy compile results to the fragment program struct and destroy the + * compilation context. + */ +static void +i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) +{ + unsigned long program_size = (unsigned long) (p->csr - p->program); + unsigned long decl_size = (unsigned long) (p->decl - p->declarations); + + if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) + i915_program_error(p, "Exceeded max nr indirect texture lookups"); + + if (p->nr_tex_insn > I915_MAX_TEX_INSN) + i915_program_error(p, "Exceeded max TEX instructions"); + + if (p->nr_alu_insn > I915_MAX_ALU_INSN) + i915_program_error(p, "Exceeded max ALU instructions"); + + if (p->nr_decl_insn > I915_MAX_DECL_INSN) + i915_program_error(p, "Exceeded max DECL instructions"); + + /* free old program, if present */ + if (i915->current.program) { + FREE(i915->current.program); + i915->current.program_len = 0; + } + + if (p->error) { + p->NumNativeInstructions = 0; + p->NumNativeAluInstructions = 0; + p->NumNativeTexInstructions = 0; + p->NumNativeTexIndirections = 0; + + i915_use_passthrough_shader(i915); + } + else { + p->NumNativeInstructions + = p->nr_alu_insn + p->nr_tex_insn + p->nr_decl_insn; + p->NumNativeAluInstructions = p->nr_alu_insn; + p->NumNativeTexInstructions = p->nr_tex_insn; + p->NumNativeTexIndirections = p->nr_tex_indirect; + + /* patch in the program length */ + p->declarations[0] |= program_size + decl_size - 2; + + /* Copy compilation results to fragment program struct: + */ + i915->current.program + = (uint *) MALLOC((program_size + decl_size) * sizeof(uint)); + if (i915->current.program) { + i915->current.program_len = program_size + decl_size; + + memcpy(i915->current.program, + p->declarations, + decl_size * sizeof(uint)); + + memcpy(i915->current.program + decl_size, + p->program, + program_size * sizeof(uint)); + } + + /* update number of constants */ + i915->current.num_constants[PIPE_SHADER_FRAGMENT] = p->num_constants; + assert(i915->current.num_constants[PIPE_SHADER_FRAGMENT] + >= i915->current.num_user_constants[PIPE_SHADER_FRAGMENT]); + } + + /* Release the compilation struct: + */ + FREE(p); +} + + +/** + * Find an unused texture coordinate slot to use for fragment WPOS. + * Update p->fp->wpos_tex with the result (-1 if no used texcoord slot is found). + */ +static void +i915_find_wpos_space(struct i915_fp_compile *p) +{ +#if 0 + const uint inputs + = p->shader->inputs_read | (1 << TGSI_ATTRIB_POS); /*XXX hack*/ + uint i; + + p->wpos_tex = -1; + + if (inputs & (1 << TGSI_ATTRIB_POS)) { + for (i = 0; i < I915_TEX_UNITS; i++) { + if ((inputs & (1 << (TGSI_ATTRIB_TEX0 + i))) == 0) { + p->wpos_tex = i; + return; + } + } + + i915_program_error(p, "No free texcoord for wpos value"); + } +#else + if (p->shader->input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { + /* frag shader using the fragment position input */ +#if 0 + assert(0); +#endif + } +#endif +} + + + + +/** + * Rather than trying to intercept and jiggle depth writes during + * emit, just move the value into its correct position at the end of + * the program: + */ +static void +i915_fixup_depth_write(struct i915_fp_compile *p) +{ + /* XXX assuming pos/depth is always in output[0] */ + if (p->shader->output_semantic_name[0] == TGSI_SEMANTIC_POSITION) { + const uint depth = UREG(REG_TYPE_OD, 0); + + i915_emit_arith(p, + A0_MOV, /* opcode */ + depth, /* dest reg */ + A0_DEST_CHANNEL_W, /* write mask */ + 0, /* saturate? */ + swizzle(depth, X, Y, Z, Z), /* src0 */ + 0, 0 /* src1, src2 */); + } +} + + +void +i915_translate_fragment_program( struct i915_context *i915 ) +{ + struct i915_fp_compile *p = i915_init_compile(i915, i915->fs); + const struct tgsi_token *tokens = i915->fs->tokens; + + i915_find_wpos_space(p); + + i915_translate_instructions(p, tokens); + i915_fixup_depth_write(p); + + i915_fini_compile(i915, p); +} diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c new file mode 100644 index 0000000000..c4a706c37d --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_prim_emit.c @@ -0,0 +1,215 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/draw/draw_private.h" +#include "pipe/p_util.h" + +#include "i915_context.h" +#include "i915_winsys.h" +#include "i915_reg.h" +#include "i915_state.h" +#include "i915_batch.h" + + + +/** + * Primitive emit to hardware. No support for vertex buffers or any + * nice fast paths. + */ +struct setup_stage { + struct draw_stage stage; /**< This must be first (base class) */ + + struct i915_context *i915; +}; + + + +/** + * Basically a cast wrapper. + */ +static INLINE struct setup_stage *setup_stage( struct draw_stage *stage ) +{ + return (struct setup_stage *)stage; +} + + +/** + * Extract the needed fields from vertex_header and emit i915 dwords. + * Recall that the vertices are constructed by the 'draw' module and + * have a couple of slots at the beginning (1-dword header, 4-dword + * clip pos) that we ignore here. + */ +static INLINE void +emit_hw_vertex( struct i915_context *i915, + const struct vertex_header *vertex) +{ + const struct vertex_info *vinfo = &i915->current.vertex_info; + uint i; + uint count = 0; /* for debug/sanity */ + + for (i = 0; i < vinfo->num_attribs; i++) { + switch (vinfo->emit[i]) { + case EMIT_OMIT: + /* no-op */ + break; + case EMIT_1F: + OUT_BATCH( fui(vertex->data[i][0]) ); + count++; + break; + case EMIT_2F: + OUT_BATCH( fui(vertex->data[i][0]) ); + OUT_BATCH( fui(vertex->data[i][1]) ); + count += 2; + break; + case EMIT_3F: + OUT_BATCH( fui(vertex->data[i][0]) ); + OUT_BATCH( fui(vertex->data[i][1]) ); + OUT_BATCH( fui(vertex->data[i][2]) ); + count += 3; + break; + case EMIT_4F: + OUT_BATCH( fui(vertex->data[i][0]) ); + OUT_BATCH( fui(vertex->data[i][1]) ); + OUT_BATCH( fui(vertex->data[i][2]) ); + OUT_BATCH( fui(vertex->data[i][3]) ); + count += 4; + break; + case EMIT_4UB: + OUT_BATCH( pack_ub4(float_to_ubyte( vertex->data[i][2] ), + float_to_ubyte( vertex->data[i][1] ), + float_to_ubyte( vertex->data[i][0] ), + float_to_ubyte( vertex->data[i][3] )) ); + count += 1; + break; + default: + assert(0); + } + } + assert(count == vinfo->size); +} + + + +static INLINE void +emit_prim( struct draw_stage *stage, + struct prim_header *prim, + unsigned hwprim, + unsigned nr ) +{ + struct i915_context *i915 = setup_stage(stage)->i915; + unsigned vertex_size = i915->current.vertex_info.size * 4; /* in bytes */ + unsigned i; + + assert(vertex_size >= 12); /* never smaller than 12 bytes */ + + if (i915->dirty) + i915_update_derived( i915 ); + + if (i915->hardware_dirty) + i915_emit_hardware_state( i915 ); + + if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) { + FLUSH_BATCH(); + + /* Make sure state is re-emitted after a flush: + */ + i915_update_derived( i915 ); + i915_emit_hardware_state( i915 ); + + if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) { + assert(0); + return; + } + } + + /* Emit each triangle as a single primitive. I told you this was + * simple. + */ + OUT_BATCH(_3DPRIMITIVE | + hwprim | + ((4 + vertex_size * nr)/4 - 2)); + + for (i = 0; i < nr; i++) + emit_hw_vertex(i915, prim->v[i]); +} + + +static void +setup_tri( struct draw_stage *stage, struct prim_header *prim ) +{ + emit_prim( stage, prim, PRIM3D_TRILIST, 3 ); +} + + +static void +setup_line(struct draw_stage *stage, struct prim_header *prim) +{ + emit_prim( stage, prim, PRIM3D_LINELIST, 2 ); +} + + +static void +setup_point(struct draw_stage *stage, struct prim_header *prim) +{ + emit_prim( stage, prim, PRIM3D_POINTLIST, 1 ); +} + + +static void setup_flush( struct draw_stage *stage, unsigned flags ) +{ +} + +static void reset_stipple_counter( struct draw_stage *stage ) +{ +} + +static void render_destroy( struct draw_stage *stage ) +{ + FREE( stage ); +} + + +/** + * Create a new primitive setup/render stage. This gets plugged into + * the 'draw' module's pipeline. + */ +struct draw_stage *i915_draw_render_stage( struct i915_context *i915 ) +{ + struct setup_stage *setup = CALLOC_STRUCT(setup_stage); + + setup->i915 = i915; + setup->stage.draw = i915->draw; + setup->stage.point = setup_point; + setup->stage.line = setup_line; + setup->stage.tri = setup_tri; + setup->stage.flush = setup_flush; + setup->stage.reset_stipple_counter = reset_stipple_counter; + setup->stage.destroy = render_destroy; + + return &setup->stage; +} diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c new file mode 100644 index 0000000000..e069773fd4 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -0,0 +1,254 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Build post-transformation, post-clipping vertex buffers and element + * lists by hooking into the end of the primitive pipeline and + * manipulating the vertex_id field in the vertex headers. + * + * XXX: work in progress + * + * \author José Fonseca + * \author Keith Whitwell + */ + + +#include "pipe/draw/draw_vbuf.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" + +#include "i915_context.h" +#include "i915_reg.h" +#include "i915_winsys.h" +#include "i915_batch.h" +#include "i915_state.h" + + +/** + * Primitive renderer for i915. + */ +struct i915_vbuf_render { + struct vbuf_render base; + + struct i915_context *i915; + + /** Vertex size in bytes */ + unsigned vertex_size; + + /** Hardware primitive */ + unsigned hwprim; +}; + + +/** + * Basically a cast wrapper. + */ +static INLINE struct i915_vbuf_render * +i915_vbuf_render( struct vbuf_render *render ) +{ + assert(render); + return (struct i915_vbuf_render *)render; +} + + +static const struct vertex_info * +i915_vbuf_render_get_vertex_info( struct vbuf_render *render ) +{ + struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + struct i915_context *i915 = i915_render->i915; + return &i915->current.vertex_info; +} + + +static void * +i915_vbuf_render_allocate_vertices( struct vbuf_render *render, + ushort vertex_size, + ushort nr_vertices ) +{ + struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + struct i915_context *i915 = i915_render->i915; + struct pipe_winsys *winsys = i915->pipe.winsys; + size_t size = (size_t)vertex_size * (size_t)nr_vertices; + + /* FIXME: handle failure */ + assert(!i915->vbo); + i915->vbo = winsys->buffer_create(winsys, 64, I915_BUFFER_USAGE_LIT_VERTEX, + size); + + i915->dirty |= I915_NEW_VBO; + + return winsys->buffer_map(winsys, + i915->vbo, + PIPE_BUFFER_USAGE_CPU_WRITE); +} + + +static void +i915_vbuf_render_set_primitive( struct vbuf_render *render, + unsigned prim ) +{ + struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + + switch(prim) { + case PIPE_PRIM_POINTS: + i915_render->hwprim = PRIM3D_POINTLIST; + break; + case PIPE_PRIM_LINES: + i915_render->hwprim = PRIM3D_LINELIST; + break; + case PIPE_PRIM_TRIANGLES: + i915_render->hwprim = PRIM3D_TRILIST; + break; + default: + assert(0); + } +} + + +static void +i915_vbuf_render_draw( struct vbuf_render *render, + const ushort *indices, + uint nr_indices) +{ + struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + struct i915_context *i915 = i915_render->i915; + unsigned i; + + assert(nr_indices); + + assert((i915->dirty & ~I915_NEW_VBO) == 0); + + if (i915->dirty) + i915_update_derived( i915 ); + + if (i915->hardware_dirty) + i915_emit_hardware_state( i915 ); + + if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { + FLUSH_BATCH(); + + /* Make sure state is re-emitted after a flush: + */ + i915_update_derived( i915 ); + i915_emit_hardware_state( i915 ); + + if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { + assert(0); + return; + } + } + + OUT_BATCH( _3DPRIMITIVE | + PRIM_INDIRECT | + i915_render->hwprim | + PRIM_INDIRECT_ELTS | + nr_indices ); + for (i = 0; i + 1 < nr_indices; i += 2) { + OUT_BATCH( indices[i] | + (indices[i + 1] << 16) ); + } + if (i < nr_indices) { + OUT_BATCH( indices[i] ); + } +} + + +static void +i915_vbuf_render_release_vertices( struct vbuf_render *render, + void *vertices, + unsigned vertex_size, + unsigned vertices_used ) +{ + struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + struct i915_context *i915 = i915_render->i915; + struct pipe_winsys *winsys = i915->pipe.winsys; + + assert(i915->vbo); + winsys->buffer_unmap(winsys, i915->vbo); + pipe_buffer_reference(winsys, &i915->vbo, NULL); +} + + +static void +i915_vbuf_render_destroy( struct vbuf_render *render ) +{ + struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + FREE(i915_render); +} + + +/** + * Create a new primitive render. + */ +static struct vbuf_render * +i915_vbuf_render_create( struct i915_context *i915 ) +{ + struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render); + + i915_render->i915 = i915; + + i915_render->base.max_vertex_buffer_bytes = 128*1024; + + /* NOTE: it must be such that state and vertices indices fit in a single + * batch buffer. + */ + i915_render->base.max_indices = 16*1024; + + i915_render->base.get_vertex_info = i915_vbuf_render_get_vertex_info; + i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices; + i915_render->base.set_primitive = i915_vbuf_render_set_primitive; + i915_render->base.draw = i915_vbuf_render_draw; + i915_render->base.release_vertices = i915_vbuf_render_release_vertices; + i915_render->base.destroy = i915_vbuf_render_destroy; + + return &i915_render->base; +} + + +/** + * Create a new primitive vbuf/render stage. + */ +struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 ) +{ + struct vbuf_render *render; + struct draw_stage *stage; + + render = i915_vbuf_render_create(i915); + if(!render) + return NULL; + + stage = draw_vbuf_stage( i915->draw, render ); + if(!stage) { + render->destroy(render); + return NULL; + } + + return stage; +} diff --git a/src/gallium/drivers/i915simple/i915_reg.h b/src/gallium/drivers/i915simple/i915_reg.h new file mode 100644 index 0000000000..04620fec68 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_reg.h @@ -0,0 +1,978 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef I915_REG_H +#define I915_REG_H + + +#define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) + +#define CMD_3D (0x3<<29) + +#define PRIM3D_INLINE (CMD_3D | (0x1f<<24)) +#define PRIM3D_TRILIST (0x0<<18) +#define PRIM3D_TRISTRIP (0x1<<18) +#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) +#define PRIM3D_TRIFAN (0x3<<18) +#define PRIM3D_POLY (0x4<<18) +#define PRIM3D_LINELIST (0x5<<18) +#define PRIM3D_LINESTRIP (0x6<<18) +#define PRIM3D_RECTLIST (0x7<<18) +#define PRIM3D_POINTLIST (0x8<<18) +#define PRIM3D_DIB (0x9<<18) +#define PRIM3D_CLEAR_RECT (0xa<<18) +#define PRIM3D_ZONE_INIT (0xd<<18) +#define PRIM3D_MASK (0x1f<<18) + +/* p137 */ +#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) +#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) +#define AA_LINE_ECAAR_WIDTH_0_5 0 +#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) +#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) +#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) +#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) +#define AA_LINE_REGION_WIDTH_0_5 0 +#define AA_LINE_REGION_WIDTH_1_0 (1<<6) +#define AA_LINE_REGION_WIDTH_2_0 (2<<6) +#define AA_LINE_REGION_WIDTH_4_0 (3<<6) + +/* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/ +#define _3DSTATE_BACKFACE_STENCIL_OPS (CMD_3D | (0x8<<24)) +#define BFO_ENABLE_STENCIL_REF (1<<23) +#define BFO_STENCIL_REF_SHIFT 15 +#define BFO_STENCIL_REF_MASK (0xff<<15) +#define BFO_ENABLE_STENCIL_FUNCS (1<<14) +#define BFO_STENCIL_TEST_SHIFT 11 +#define BFO_STENCIL_TEST_MASK (0x7<<11) +#define BFO_STENCIL_FAIL_SHIFT 8 +#define BFO_STENCIL_FAIL_MASK (0x7<<8) +#define BFO_STENCIL_PASS_Z_FAIL_SHIFT 5 +#define BFO_STENCIL_PASS_Z_FAIL_MASK (0x7<<5) +#define BFO_STENCIL_PASS_Z_PASS_SHIFT 2 +#define BFO_STENCIL_PASS_Z_PASS_MASK (0x7<<2) +#define BFO_ENABLE_STENCIL_TWO_SIDE (1<<1) +#define BFO_STENCIL_TWO_SIDE (1<<0) + + +/* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */ +#define _3DSTATE_BACKFACE_STENCIL_MASKS (CMD_3D | (0x9<<24)) +#define BFM_ENABLE_STENCIL_TEST_MASK (1<<17) +#define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16) +#define BFM_STENCIL_TEST_MASK_SHIFT 8 +#define BFM_STENCIL_TEST_MASK_MASK (0xff<<8) +#define BFM_STENCIL_WRITE_MASK_SHIFT 0 +#define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0) + + + +/* 3DSTATE_BIN_CONTROL p141 */ + +/* p143 */ +#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) +/* Dword 1 */ +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_TILED_SURFACE (1<<22) +#define BUF_3D_TILE_WALK_X 0 +#define BUF_3D_TILE_WALK_Y (1<<21) +#define BUF_3D_PITCH(x) (((x)/4)<<2) +/* Dword 2 */ +#define BUF_3D_ADDR(x) ((x) & ~0x3) + + +/* 3DSTATE_CHROMA_KEY */ + +/* 3DSTATE_CLEAR_PARAMETERS, p150 */ +#define _3DSTATE_CLEAR_PARAMETERS (CMD_3D | (0x1d<<24) | (0x9c<<16) | 5) +/* Dword 1 */ +#define CLEARPARAM_CLEAR_RECT (1 << 16) +#define CLEARPARAM_ZONE_INIT (0 << 16) +#define CLEARPARAM_WRITE_COLOR (1 << 2) +#define CLEARPARAM_WRITE_DEPTH (1 << 1) +#define CLEARPARAM_WRITE_STENCIL (1 << 0) + +/* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */ +#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) + + + +/* 3DSTATE_COORD_SET_BINDINGS, p154 */ +#define _3DSTATE_COORD_SET_BINDINGS (CMD_3D | (0x16<<24)) +#define CSB_TCB(iunit, eunit) ((eunit)<<(iunit*3)) + +/* p156 */ +#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) + +/* p157 */ +#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) + +/* p158 */ +#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) + + +/* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */ +#define _3DSTATE_DEPTH_OFFSET_SCALE (CMD_3D | (0x1d<<24) | (0x97<<16)) +/* scale in dword 1 */ + + +/* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */ +#define _3DSTATE_DEPTH_SUBRECT_DISABLE (CMD_3D | (0x1c<<24) | (0x11<<19) | 0x2) + +/* p161 */ +#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) +/* Dword 1 */ +#define TEX_DEFAULT_COLOR_OGL (0<<30) +#define TEX_DEFAULT_COLOR_D3D (1<<30) +#define ZR_EARLY_DEPTH (1<<29) +#define LOD_PRECLAMP_OGL (1<<28) +#define LOD_PRECLAMP_D3D (0<<28) +#define DITHER_FULL_ALWAYS (0<<26) +#define DITHER_FULL_ON_FB_BLEND (1<<26) +#define DITHER_CLAMPED_ALWAYS (2<<26) +#define LINEAR_GAMMA_BLEND_32BPP (1<<25) +#define DEBUG_DISABLE_ENH_DITHER (1<<24) +#define DSTORG_HORT_BIAS(x) ((x)<<20) +#define DSTORG_VERT_BIAS(x) ((x)<<16) +#define COLOR_4_2_2_CHNL_WRT_ALL 0 +#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) +#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) +#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) +#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) +#define COLOR_BUF_8BIT 0 +#define COLOR_BUF_RGB555 (1<<8) +#define COLOR_BUF_RGB565 (2<<8) +#define COLOR_BUF_ARGB8888 (3<<8) +#define DEPTH_FRMT_16_FIXED 0 +#define DEPTH_FRMT_16_FLOAT (1<<2) +#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) +#define VERT_LINE_STRIDE_1 (1<<1) +#define VERT_LINE_STRIDE_0 (0<<1) +#define VERT_LINE_STRIDE_OFS_1 1 +#define VERT_LINE_STRIDE_OFS_0 0 + +/* p166 */ +#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) +/* Dword 1 */ +#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) +#define DRAW_DITHER_OFS_X(x) ((x)<<26) +#define DRAW_DITHER_OFS_Y(x) ((x)<<24) +/* Dword 2 */ +#define DRAW_YMIN(x) ((x)<<16) +#define DRAW_XMIN(x) (x) +/* Dword 3 */ +#define DRAW_YMAX(x) ((x)<<16) +#define DRAW_XMAX(x) (x) +/* Dword 4 */ +#define DRAW_YORG(x) ((x)<<16) +#define DRAW_XORG(x) (x) + + +/* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */ + +/* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */ + + +/* _3DSTATE_FOG_COLOR, p173 */ +#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) +#define FOG_COLOR_RED(x) ((x)<<16) +#define FOG_COLOR_GREEN(x) ((x)<<8) +#define FOG_COLOR_BLUE(x) (x) + +/* _3DSTATE_FOG_MODE, p174 */ +#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) +/* Dword 1 */ +#define FMC1_FOGFUNC_MODIFY_ENABLE (1<<31) +#define FMC1_FOGFUNC_VERTEX (0<<28) +#define FMC1_FOGFUNC_PIXEL_EXP (1<<28) +#define FMC1_FOGFUNC_PIXEL_EXP2 (2<<28) +#define FMC1_FOGFUNC_PIXEL_LINEAR (3<<28) +#define FMC1_FOGFUNC_MASK (3<<28) +#define FMC1_FOGINDEX_MODIFY_ENABLE (1<<27) +#define FMC1_FOGINDEX_Z (0<<25) +#define FMC1_FOGINDEX_W (1<<25) +#define FMC1_C1_C2_MODIFY_ENABLE (1<<24) +#define FMC1_DENSITY_MODIFY_ENABLE (1<<23) +#define FMC1_C1_ONE (1<<13) +#define FMC1_C1_MASK (0xffff<<4) +/* Dword 2 */ +#define FMC2_C2_ONE (1<<16) +/* Dword 3 */ +#define FMC3_D_ONE (1<<16) + + + +/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */ +#define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) +#define IAB_MODIFY_ENABLE (1<<23) +#define IAB_ENABLE (1<<22) +#define IAB_MODIFY_FUNC (1<<21) +#define IAB_FUNC_SHIFT 16 +#define IAB_MODIFY_SRC_FACTOR (1<<11) +#define IAB_SRC_FACTOR_SHIFT 6 +#define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6) +#define IAB_MODIFY_DST_FACTOR (1<<5) +#define IAB_DST_FACTOR_SHIFT 0 +#define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0) + + +#define BLENDFUNC_ADD 0x0 +#define BLENDFUNC_SUBTRACT 0x1 +#define BLENDFUNC_REVERSE_SUBTRACT 0x2 +#define BLENDFUNC_MIN 0x3 +#define BLENDFUNC_MAX 0x4 +#define BLENDFUNC_MASK 0x7 + +/* 3DSTATE_LOAD_INDIRECT, p180 */ + +#define _3DSTATE_LOAD_INDIRECT (CMD_3D|(0x1d<<24)|(0x7<<16)) +#define LI0_STATE_STATIC_INDIRECT (0x01<<8) +#define LI0_STATE_DYNAMIC_INDIRECT (0x02<<8) +#define LI0_STATE_SAMPLER (0x04<<8) +#define LI0_STATE_MAP (0x08<<8) +#define LI0_STATE_PROGRAM (0x10<<8) +#define LI0_STATE_CONSTANTS (0x20<<8) + +#define SIS0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define SIS0_FORCE_LOAD (1<<1) +#define SIS0_BUFFER_VALID (1<<0) +#define SIS1_BUFFER_LENGTH(x) ((x)&0xff) + +#define DIS0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define DIS0_BUFFER_RESET (1<<1) +#define DIS0_BUFFER_VALID (1<<0) + +#define SSB0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define SSB0_FORCE_LOAD (1<<1) +#define SSB0_BUFFER_VALID (1<<0) +#define SSB1_BUFFER_LENGTH(x) ((x)&0xff) + +#define MSB0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define MSB0_FORCE_LOAD (1<<1) +#define MSB0_BUFFER_VALID (1<<0) +#define MSB1_BUFFER_LENGTH(x) ((x)&0xff) + +#define PSP0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define PSP0_FORCE_LOAD (1<<1) +#define PSP0_BUFFER_VALID (1<<0) +#define PSP1_BUFFER_LENGTH(x) ((x)&0xff) + +#define PSC0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define PSC0_FORCE_LOAD (1<<1) +#define PSC0_BUFFER_VALID (1<<0) +#define PSC1_BUFFER_LENGTH(x) ((x)&0xff) + + + + + +/* _3DSTATE_RASTERIZATION_RULES */ +#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) +#define ENABLE_POINT_RASTER_RULE (1<<15) +#define OGL_POINT_RASTER_RULE (1<<13) +#define ENABLE_TEXKILL_3D_4D (1<<10) +#define TEXKILL_3D (0<<9) +#define TEXKILL_4D (1<<9) +#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) +#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) +#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) +#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) + +/* _3DSTATE_SCISSOR_ENABLE, p256 */ +#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) +#define ENABLE_SCISSOR_RECT ((1<<1) | 1) +#define DISABLE_SCISSOR_RECT (1<<1) + +/* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */ +#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) +/* Dword 1 */ +#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) +#define SCISSOR_RECT_0_XMIN(x) (x) +/* Dword 2 */ +#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) +#define SCISSOR_RECT_0_XMAX(x) (x) + +/* p189 */ +#define _3DSTATE_LOAD_STATE_IMMEDIATE_1 ((0x3<<29)|(0x1d<<24)|(0x04<<16)) +#define I1_LOAD_S(n) (1<<(4+n)) + +#define S0_VB_OFFSET_MASK 0xffffffc +#define S0_AUTO_CACHE_INV_DISABLE (1<<0) + +#define S1_VERTEX_WIDTH_SHIFT 24 +#define S1_VERTEX_WIDTH_MASK (0x3f<<24) +#define S1_VERTEX_PITCH_SHIFT 16 +#define S1_VERTEX_PITCH_MASK (0x3f<<16) + +#define TEXCOORDFMT_2D 0x0 +#define TEXCOORDFMT_3D 0x1 +#define TEXCOORDFMT_4D 0x2 +#define TEXCOORDFMT_1D 0x3 +#define TEXCOORDFMT_2D_16 0x4 +#define TEXCOORDFMT_4D_16 0x5 +#define TEXCOORDFMT_NOT_PRESENT 0xf +#define S2_TEXCOORD_FMT0_MASK 0xf +#define S2_TEXCOORD_FMT1_SHIFT 4 +#define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4)) +#define S2_TEXCOORD_NONE (~0) + +/* S3 not interesting */ + +#define S4_POINT_WIDTH_SHIFT 23 +#define S4_POINT_WIDTH_MASK (0x1ff<<23) +#define S4_LINE_WIDTH_SHIFT 19 +#define S4_LINE_WIDTH_ONE (0x2<<19) +#define S4_LINE_WIDTH_MASK (0xf<<19) +#define S4_FLATSHADE_ALPHA (1<<18) +#define S4_FLATSHADE_FOG (1<<17) +#define S4_FLATSHADE_SPECULAR (1<<16) +#define S4_FLATSHADE_COLOR (1<<15) +#define S4_CULLMODE_BOTH (0<<13) +#define S4_CULLMODE_NONE (1<<13) +#define S4_CULLMODE_CW (2<<13) +#define S4_CULLMODE_CCW (3<<13) +#define S4_CULLMODE_MASK (3<<13) +#define S4_VFMT_POINT_WIDTH (1<<12) +#define S4_VFMT_SPEC_FOG (1<<11) +#define S4_VFMT_COLOR (1<<10) +#define S4_VFMT_DEPTH_OFFSET (1<<9) +#define S4_VFMT_XYZ (1<<6) +#define S4_VFMT_XYZW (2<<6) +#define S4_VFMT_XY (3<<6) +#define S4_VFMT_XYW (4<<6) +#define S4_VFMT_XYZW_MASK (7<<6) +#define S4_FORCE_DEFAULT_DIFFUSE (1<<5) +#define S4_FORCE_DEFAULT_SPECULAR (1<<4) +#define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3) +#define S4_VFMT_FOG_PARAM (1<<2) +#define S4_SPRITE_POINT_ENABLE (1<<1) +#define S4_LINE_ANTIALIAS_ENABLE (1<<0) + +#define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \ + S4_VFMT_SPEC_FOG | \ + S4_VFMT_COLOR | \ + S4_VFMT_DEPTH_OFFSET | \ + S4_VFMT_XYZW_MASK | \ + S4_VFMT_FOG_PARAM) + + +#define S5_WRITEDISABLE_ALPHA (1<<31) +#define S5_WRITEDISABLE_RED (1<<30) +#define S5_WRITEDISABLE_GREEN (1<<29) +#define S5_WRITEDISABLE_BLUE (1<<28) +#define S5_WRITEDISABLE_MASK (0xf<<28) +#define S5_FORCE_DEFAULT_POINT_SIZE (1<<27) +#define S5_LAST_PIXEL_ENABLE (1<<26) +#define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25) +#define S5_FOG_ENABLE (1<<24) +#define S5_STENCIL_REF_SHIFT 16 +#define S5_STENCIL_REF_MASK (0xff<<16) +#define S5_STENCIL_TEST_FUNC_SHIFT 13 +#define S5_STENCIL_TEST_FUNC_MASK (0x7<<13) +#define S5_STENCIL_FAIL_SHIFT 10 +#define S5_STENCIL_FAIL_MASK (0x7<<10) +#define S5_STENCIL_PASS_Z_FAIL_SHIFT 7 +#define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7) +#define S5_STENCIL_PASS_Z_PASS_SHIFT 4 +#define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4) +#define S5_STENCIL_WRITE_ENABLE (1<<3) +#define S5_STENCIL_TEST_ENABLE (1<<2) +#define S5_COLOR_DITHER_ENABLE (1<<1) +#define S5_LOGICOP_ENABLE (1<<0) + + +#define S6_ALPHA_TEST_ENABLE (1<<31) +#define S6_ALPHA_TEST_FUNC_SHIFT 28 +#define S6_ALPHA_TEST_FUNC_MASK (0x7<<28) +#define S6_ALPHA_REF_SHIFT 20 +#define S6_ALPHA_REF_MASK (0xff<<20) +#define S6_DEPTH_TEST_ENABLE (1<<19) +#define S6_DEPTH_TEST_FUNC_SHIFT 16 +#define S6_DEPTH_TEST_FUNC_MASK (0x7<<16) +#define S6_CBUF_BLEND_ENABLE (1<<15) +#define S6_CBUF_BLEND_FUNC_SHIFT 12 +#define S6_CBUF_BLEND_FUNC_MASK (0x7<<12) +#define S6_CBUF_SRC_BLEND_FACT_SHIFT 8 +#define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8) +#define S6_CBUF_DST_BLEND_FACT_SHIFT 4 +#define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4) +#define S6_DEPTH_WRITE_ENABLE (1<<3) +#define S6_COLOR_WRITE_ENABLE (1<<2) +#define S6_TRISTRIP_PV_SHIFT 0 +#define S6_TRISTRIP_PV_MASK (0x3<<0) + +#define S7_DEPTH_OFFSET_CONST_MASK ~0 + + + +#define DST_BLND_FACT(f) ((f)<= 0.0) ? src1 : src2 */ +#define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ +#define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ +#define A0_FLR (0x10<<24) /* dst = floor(src0) */ +#define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ +#define A0_TRC (0x12<<24) /* dst = int(src0) */ +#define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ +#define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ +#define A0_DEST_SATURATE (1<<22) +#define A0_DEST_TYPE_SHIFT 19 +/* Allow: R, OC, OD, U */ +#define A0_DEST_NR_SHIFT 14 +/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ +#define A0_DEST_CHANNEL_X (1<<10) +#define A0_DEST_CHANNEL_Y (2<<10) +#define A0_DEST_CHANNEL_Z (4<<10) +#define A0_DEST_CHANNEL_W (8<<10) +#define A0_DEST_CHANNEL_ALL (0xf<<10) +#define A0_DEST_CHANNEL_SHIFT 10 +#define A0_SRC0_TYPE_SHIFT 7 +#define A0_SRC0_NR_SHIFT 2 + +#define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) +#define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) + + +#define SRC_X 0 +#define SRC_Y 1 +#define SRC_Z 2 +#define SRC_W 3 +#define SRC_ZERO 4 +#define SRC_ONE 5 + +#define A1_SRC0_CHANNEL_X_NEGATE (1<<31) +#define A1_SRC0_CHANNEL_X_SHIFT 28 +#define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) +#define A1_SRC0_CHANNEL_Y_SHIFT 24 +#define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) +#define A1_SRC0_CHANNEL_Z_SHIFT 20 +#define A1_SRC0_CHANNEL_W_NEGATE (1<<19) +#define A1_SRC0_CHANNEL_W_SHIFT 16 +#define A1_SRC1_TYPE_SHIFT 13 +#define A1_SRC1_NR_SHIFT 8 +#define A1_SRC1_CHANNEL_X_NEGATE (1<<7) +#define A1_SRC1_CHANNEL_X_SHIFT 4 +#define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) +#define A1_SRC1_CHANNEL_Y_SHIFT 0 + +#define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) +#define A2_SRC1_CHANNEL_Z_SHIFT 28 +#define A2_SRC1_CHANNEL_W_NEGATE (1<<27) +#define A2_SRC1_CHANNEL_W_SHIFT 24 +#define A2_SRC2_TYPE_SHIFT 21 +#define A2_SRC2_NR_SHIFT 16 +#define A2_SRC2_CHANNEL_X_NEGATE (1<<15) +#define A2_SRC2_CHANNEL_X_SHIFT 12 +#define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) +#define A2_SRC2_CHANNEL_Y_SHIFT 8 +#define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) +#define A2_SRC2_CHANNEL_Z_SHIFT 4 +#define A2_SRC2_CHANNEL_W_NEGATE (1<<3) +#define A2_SRC2_CHANNEL_W_SHIFT 0 + + + +/* Texture instructions */ +#define T0_TEXLD (0x15<<24) /* Sample texture using predeclared + * sampler and address, and output + * filtered texel data to destination + * register */ +#define T0_TEXLDP (0x16<<24) /* Same as texld but performs a + * perspective divide of the texture + * coordinate .xyz values by .w before + * sampling. */ +#define T0_TEXLDB (0x17<<24) /* Same as texld but biases the + * computed LOD by w. Only S4.6 two's + * comp is used. This implies that a + * float to fixed conversion is + * done. */ +#define T0_TEXKILL (0x18<<24) /* Does not perform a sampling + * operation. Simply kills the pixel + * if any channel of the address + * register is < 0.0. */ +#define T0_DEST_TYPE_SHIFT 19 +/* Allow: R, OC, OD, U */ +/* Note: U (unpreserved) regs do not retain their values between + * phases (cannot be used for feedback) + * + * Note: oC and OD registers can only be used as the destination of a + * texture instruction once per phase (this is an implementation + * restriction). + */ +#define T0_DEST_NR_SHIFT 14 +/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ +#define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ +#define T0_SAMPLER_NR_MASK (0xf<<0) + +#define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ +/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ +#define T1_ADDRESS_REG_NR_SHIFT 17 +#define T2_MBZ 0 + +/* Declaration instructions */ +#define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) + * register or an s (sampler) + * register. */ +#define D0_SAMPLE_TYPE_SHIFT 22 +#define D0_SAMPLE_TYPE_2D (0x0<<22) +#define D0_SAMPLE_TYPE_CUBE (0x1<<22) +#define D0_SAMPLE_TYPE_VOLUME (0x2<<22) +#define D0_SAMPLE_TYPE_MASK (0x3<<22) + +#define D0_TYPE_SHIFT 19 +/* Allow: T, S */ +#define D0_NR_SHIFT 14 +/* Allow T: 0..10, S: 0..15 */ +#define D0_CHANNEL_X (1<<10) +#define D0_CHANNEL_Y (2<<10) +#define D0_CHANNEL_Z (4<<10) +#define D0_CHANNEL_W (8<<10) +#define D0_CHANNEL_ALL (0xf<<10) +#define D0_CHANNEL_NONE (0<<10) + +#define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) +#define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) + +/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse + * or specular declarations. + * + * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) + * + * Must be zero for S (sampler) dcls + */ +#define D1_MBZ 0 +#define D2_MBZ 0 + + + +/* p207 */ +#define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16)) + +#define MS1_MAPMASK_SHIFT 0 +#define MS1_MAPMASK_MASK (0x8fff<<0) + +#define MS2_UNTRUSTED_SURFACE (1<<31) +#define MS2_ADDRESS_MASK 0xfffffffc +#define MS2_VERTICAL_LINE_STRIDE (1<<1) +#define MS2_VERTICAL_OFFSET (1<<1) + +#define MS3_HEIGHT_SHIFT 21 +#define MS3_WIDTH_SHIFT 10 +#define MS3_PALETTE_SELECT (1<<9) +#define MS3_MAPSURF_FORMAT_SHIFT 7 +#define MS3_MAPSURF_FORMAT_MASK (0x7<<7) +#define MAPSURF_8BIT (1<<7) +#define MAPSURF_16BIT (2<<7) +#define MAPSURF_32BIT (3<<7) +#define MAPSURF_422 (5<<7) +#define MAPSURF_COMPRESSED (6<<7) +#define MAPSURF_4BIT_INDEXED (7<<7) +#define MS3_MT_FORMAT_MASK (0x7 << 3) +#define MS3_MT_FORMAT_SHIFT 3 +#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ +#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ +#define MT_8BIT_L8 (1<<3) +#define MT_8BIT_A8 (4<<3) +#define MT_8BIT_MONO8 (5<<3) +#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ +#define MT_16BIT_ARGB1555 (1<<3) +#define MT_16BIT_ARGB4444 (2<<3) +#define MT_16BIT_AY88 (3<<3) +#define MT_16BIT_88DVDU (5<<3) +#define MT_16BIT_BUMP_655LDVDU (6<<3) +#define MT_16BIT_I16 (7<<3) +#define MT_16BIT_L16 (8<<3) +#define MT_16BIT_A16 (9<<3) +#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ +#define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_XRGB8888 (2<<3) +#define MT_32BIT_XBGR8888 (3<<3) +#define MT_32BIT_QWVU8888 (4<<3) +#define MT_32BIT_AXVU8888 (5<<3) +#define MT_32BIT_LXVU8888 (6<<3) +#define MT_32BIT_XLVU8888 (7<<3) +#define MT_32BIT_ARGB2101010 (8<<3) +#define MT_32BIT_ABGR2101010 (9<<3) +#define MT_32BIT_AWVU2101010 (0xA<<3) +#define MT_32BIT_GR1616 (0xB<<3) +#define MT_32BIT_VU1616 (0xC<<3) +#define MT_32BIT_xI824 (0xD<<3) +#define MT_32BIT_xA824 (0xE<<3) +#define MT_32BIT_xL824 (0xF<<3) +#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ +#define MT_422_YCRCB_NORMAL (1<<3) +#define MT_422_YCRCB_SWAPUV (2<<3) +#define MT_422_YCRCB_SWAPUVY (3<<3) +#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ +#define MT_COMPRESS_DXT2_3 (1<<3) +#define MT_COMPRESS_DXT4_5 (2<<3) +#define MT_COMPRESS_FXT1 (3<<3) +#define MT_COMPRESS_DXT1_RGB (4<<3) +#define MS3_USE_FENCE_REGS (1<<2) +#define MS3_TILED_SURFACE (1<<1) +#define MS3_TILE_WALK (1<<0) + +#define MS4_PITCH_SHIFT 21 +#define MS4_CUBE_FACE_ENA_NEGX (1<<20) +#define MS4_CUBE_FACE_ENA_POSX (1<<19) +#define MS4_CUBE_FACE_ENA_NEGY (1<<18) +#define MS4_CUBE_FACE_ENA_POSY (1<<17) +#define MS4_CUBE_FACE_ENA_NEGZ (1<<16) +#define MS4_CUBE_FACE_ENA_POSZ (1<<15) +#define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) +#define MS4_MAX_LOD_SHIFT 9 +#define MS4_MAX_LOD_MASK (0x3f<<9) +#define MS4_MIP_LAYOUT_LEGACY (0<<8) +#define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) +#define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) +#define MS4_VOLUME_DEPTH_SHIFT 0 +#define MS4_VOLUME_DEPTH_MASK (0xff<<0) + +/* p244 */ +#define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16)) + +#define SS1_MAPMASK_SHIFT 0 +#define SS1_MAPMASK_MASK (0x8fff<<0) + +#define SS2_REVERSE_GAMMA_ENABLE (1<<31) +#define SS2_PACKED_TO_PLANAR_ENABLE (1<<30) +#define SS2_COLORSPACE_CONVERSION (1<<29) +#define SS2_CHROMAKEY_SHIFT 27 +#define SS2_BASE_MIP_LEVEL_SHIFT 22 +#define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22) +#define SS2_MIP_FILTER_SHIFT 20 +#define SS2_MIP_FILTER_MASK (0x3<<20) +#define MIPFILTER_NONE 0 +#define MIPFILTER_NEAREST 1 +#define MIPFILTER_LINEAR 3 +#define SS2_MAG_FILTER_SHIFT 17 +#define SS2_MAG_FILTER_MASK (0x7<<17) +#define FILTER_NEAREST 0 +#define FILTER_LINEAR 1 +#define FILTER_ANISOTROPIC 2 +#define FILTER_4X4_1 3 +#define FILTER_4X4_2 4 +#define FILTER_4X4_FLAT 5 +#define FILTER_6X5_MONO 6 /* XXX - check */ +#define SS2_MIN_FILTER_SHIFT 14 +#define SS2_MIN_FILTER_MASK (0x7<<14) +#define SS2_LOD_BIAS_SHIFT 5 +#define SS2_LOD_BIAS_ONE (0x10<<5) +#define SS2_LOD_BIAS_MASK (0x1ff<<5) +/* Shadow requires: + * MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format + * FILTER_4X4_x MIN and MAG filters + */ +#define SS2_SHADOW_ENABLE (1<<4) +#define SS2_MAX_ANISO_MASK (1<<3) +#define SS2_MAX_ANISO_2 (0<<3) +#define SS2_MAX_ANISO_4 (1<<3) +#define SS2_SHADOW_FUNC_SHIFT 0 +#define SS2_SHADOW_FUNC_MASK (0x7<<0) +/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */ + +#define SS3_MIN_LOD_SHIFT 24 +#define SS3_MIN_LOD_ONE (0x10<<24) +#define SS3_MIN_LOD_MASK (0xff<<24) +#define SS3_KILL_PIXEL_ENABLE (1<<17) +#define SS3_TCX_ADDR_MODE_SHIFT 12 +#define SS3_TCX_ADDR_MODE_MASK (0x7<<12) +#define TEXCOORDMODE_WRAP 0 +#define TEXCOORDMODE_MIRROR 1 +#define TEXCOORDMODE_CLAMP_EDGE 2 +#define TEXCOORDMODE_CUBE 3 +#define TEXCOORDMODE_CLAMP_BORDER 4 +#define TEXCOORDMODE_MIRROR_ONCE 5 +#define SS3_TCY_ADDR_MODE_SHIFT 9 +#define SS3_TCY_ADDR_MODE_MASK (0x7<<9) +#define SS3_TCZ_ADDR_MODE_SHIFT 6 +#define SS3_TCZ_ADDR_MODE_MASK (0x7<<6) +#define SS3_NORMALIZED_COORDS (1<<5) +#define SS3_TEXTUREMAP_INDEX_SHIFT 1 +#define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1) +#define SS3_DEINTERLACER_ENABLE (1<<0) + +#define SS4_BORDER_COLOR_MASK (~0) + +/* 3DSTATE_SPAN_STIPPLE, p258 + */ +#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + +#define _3DSTATE_DEFAULT_Z ((0x3<<29)|(0x1d<<24)|(0x98<<16)) +#define _3DSTATE_DEFAULT_DIFFUSE ((0x3<<29)|(0x1d<<24)|(0x99<<16)) +#define _3DSTATE_DEFAULT_SPECULAR ((0x3<<29)|(0x1d<<24)|(0x9a<<16)) + + +#define MI_FLUSH ((0<<29)|(4<<23)) +#define FLUSH_MAP_CACHE (1<<0) +#define INHIBIT_FLUSH_RENDER_CACHE (1<<2) + + +#define CMD_3D (0x3<<29) + + +#define _3DPRIMITIVE ((0x3<<29)|(0x1f<<24)) +#define PRIM_INDIRECT (1<<23) +#define PRIM_INLINE (0<<23) +#define PRIM_INDIRECT_SEQUENTIAL (0<<17) +#define PRIM_INDIRECT_ELTS (1<<17) + +#define PRIM3D_TRILIST (0x0<<18) +#define PRIM3D_TRISTRIP (0x1<<18) +#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) +#define PRIM3D_TRIFAN (0x3<<18) +#define PRIM3D_POLY (0x4<<18) +#define PRIM3D_LINELIST (0x5<<18) +#define PRIM3D_LINESTRIP (0x6<<18) +#define PRIM3D_RECTLIST (0x7<<18) +#define PRIM3D_POINTLIST (0x8<<18) +#define PRIM3D_DIB (0x9<<18) +#define PRIM3D_MASK (0x1f<<18) + +#define I915PACKCOLOR4444(r,g,b,a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +#define I915PACKCOLOR1555(r,g,b,a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define I915PACKCOLOR565(r,g,b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define I915PACKCOLOR8888(r,g,b,a) \ + ((a<<24) | (r<<16) | (g<<8) | b) + + + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + +#define MI_BATCH_BUFFER (0x30<<23) +#define MI_BATCH_BUFFER_START (0x31<<23) +#define MI_BATCH_BUFFER_END (0xa<<23) + + + +#define COMPAREFUNC_ALWAYS 0 +#define COMPAREFUNC_NEVER 0x1 +#define COMPAREFUNC_LESS 0x2 +#define COMPAREFUNC_EQUAL 0x3 +#define COMPAREFUNC_LEQUAL 0x4 +#define COMPAREFUNC_GREATER 0x5 +#define COMPAREFUNC_NOTEQUAL 0x6 +#define COMPAREFUNC_GEQUAL 0x7 + +#define STENCILOP_KEEP 0 +#define STENCILOP_ZERO 0x1 +#define STENCILOP_REPLACE 0x2 +#define STENCILOP_INCRSAT 0x3 +#define STENCILOP_DECRSAT 0x4 +#define STENCILOP_INCR 0x5 +#define STENCILOP_DECR 0x6 +#define STENCILOP_INVERT 0x7 + +#define LOGICOP_CLEAR 0 +#define LOGICOP_NOR 0x1 +#define LOGICOP_AND_INV 0x2 +#define LOGICOP_COPY_INV 0x3 +#define LOGICOP_AND_RVRSE 0x4 +#define LOGICOP_INV 0x5 +#define LOGICOP_XOR 0x6 +#define LOGICOP_NAND 0x7 +#define LOGICOP_AND 0x8 +#define LOGICOP_EQUIV 0x9 +#define LOGICOP_NOOP 0xa +#define LOGICOP_OR_INV 0xb +#define LOGICOP_COPY 0xc +#define LOGICOP_OR_RVRSE 0xd +#define LOGICOP_OR 0xe +#define LOGICOP_SET 0xf + +#define BLENDFACT_ZERO 0x01 +#define BLENDFACT_ONE 0x02 +#define BLENDFACT_SRC_COLR 0x03 +#define BLENDFACT_INV_SRC_COLR 0x04 +#define BLENDFACT_SRC_ALPHA 0x05 +#define BLENDFACT_INV_SRC_ALPHA 0x06 +#define BLENDFACT_DST_ALPHA 0x07 +#define BLENDFACT_INV_DST_ALPHA 0x08 +#define BLENDFACT_DST_COLR 0x09 +#define BLENDFACT_INV_DST_COLR 0x0a +#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b +#define BLENDFACT_CONST_COLOR 0x0c +#define BLENDFACT_INV_CONST_COLOR 0x0d +#define BLENDFACT_CONST_ALPHA 0x0e +#define BLENDFACT_INV_CONST_ALPHA 0x0f +#define BLENDFACT_MASK 0x0f + +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_Q33_G 0x29D2 + + +#endif diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c new file mode 100644 index 0000000000..abd5571b88 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -0,0 +1,694 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + + +#include "pipe/draw/draw_context.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "i915_context.h" +#include "i915_reg.h" +#include "i915_state.h" +#include "i915_state_inlines.h" + + +/* The i915 (and related graphics cores) do not support GL_CLAMP. The + * Intel drivers for "other operating systems" implement GL_CLAMP as + * GL_CLAMP_TO_EDGE, so the same is done here. + */ +static unsigned +translate_wrap_mode(unsigned wrap) +{ + switch (wrap) { + case PIPE_TEX_WRAP_REPEAT: + return TEXCOORDMODE_WRAP; + case PIPE_TEX_WRAP_CLAMP: + return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return TEXCOORDMODE_CLAMP_EDGE; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return TEXCOORDMODE_CLAMP_BORDER; +// case PIPE_TEX_WRAP_MIRRORED_REPEAT: +// return TEXCOORDMODE_MIRROR; + default: + return TEXCOORDMODE_WRAP; + } +} + +static unsigned translate_img_filter( unsigned filter ) +{ + switch (filter) { + case PIPE_TEX_FILTER_NEAREST: + return FILTER_NEAREST; + case PIPE_TEX_FILTER_LINEAR: + return FILTER_LINEAR; + default: + assert(0); + return FILTER_NEAREST; + } +} + +static unsigned translate_mip_filter( unsigned filter ) +{ + switch (filter) { + case PIPE_TEX_MIPFILTER_NONE: + return MIPFILTER_NONE; + case PIPE_TEX_MIPFILTER_NEAREST: + return MIPFILTER_NEAREST; + case PIPE_TEX_FILTER_LINEAR: + return MIPFILTER_LINEAR; + default: + assert(0); + return MIPFILTER_NONE; + } +} + + +/* None of this state is actually used for anything yet. + */ +static void * +i915_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + struct i915_blend_state *cso_data = CALLOC_STRUCT( i915_blend_state ); + + { + unsigned eqRGB = blend->rgb_func; + unsigned srcRGB = blend->rgb_src_factor; + unsigned dstRGB = blend->rgb_dst_factor; + + unsigned eqA = blend->alpha_func; + unsigned srcA = blend->alpha_src_factor; + unsigned dstA = blend->alpha_dst_factor; + + /* Special handling for MIN/MAX filter modes handled at + * state_tracker level. + */ + + if (srcA != srcRGB || + dstA != dstRGB || + eqA != eqRGB) { + + cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | + IAB_MODIFY_ENABLE | + IAB_ENABLE | + IAB_MODIFY_FUNC | + IAB_MODIFY_SRC_FACTOR | + IAB_MODIFY_DST_FACTOR | + SRC_ABLND_FACT(i915_translate_blend_factor(srcA)) | + DST_ABLND_FACT(i915_translate_blend_factor(dstA)) | + (i915_translate_blend_func(eqA) << IAB_FUNC_SHIFT)); + } + else { + cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | + IAB_MODIFY_ENABLE | + 0); + } + } + + cso_data->modes4 |= (_3DSTATE_MODES_4_CMD | + ENABLE_LOGIC_OP_FUNC | + LOGIC_OP_FUNC(i915_translate_logic_op(blend->logicop_func))); + + if (blend->logicop_enable) + cso_data->LIS5 |= S5_LOGICOP_ENABLE; + + if (blend->dither) + cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE; + + if ((blend->colormask & PIPE_MASK_R) == 0) + cso_data->LIS5 |= S5_WRITEDISABLE_RED; + + if ((blend->colormask & PIPE_MASK_G) == 0) + cso_data->LIS5 |= S5_WRITEDISABLE_GREEN; + + if ((blend->colormask & PIPE_MASK_B) == 0) + cso_data->LIS5 |= S5_WRITEDISABLE_BLUE; + + if ((blend->colormask & PIPE_MASK_A) == 0) + cso_data->LIS5 |= S5_WRITEDISABLE_ALPHA; + + if (blend->blend_enable) { + unsigned funcRGB = blend->rgb_func; + unsigned srcRGB = blend->rgb_src_factor; + unsigned dstRGB = blend->rgb_dst_factor; + + cso_data->LIS6 |= (S6_CBUF_BLEND_ENABLE | + SRC_BLND_FACT(i915_translate_blend_factor(srcRGB)) | + DST_BLND_FACT(i915_translate_blend_factor(dstRGB)) | + (i915_translate_blend_func(funcRGB) << S6_CBUF_BLEND_FUNC_SHIFT)); + } + + return cso_data; +} + +static void i915_bind_blend_state(struct pipe_context *pipe, + void *blend) +{ + struct i915_context *i915 = i915_context(pipe); + + i915->blend = (struct i915_blend_state*)blend; + + i915->dirty |= I915_NEW_BLEND; +} + + +static void i915_delete_blend_state(struct pipe_context *pipe, void *blend) +{ + FREE(blend); +} + +static void i915_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ) +{ + struct i915_context *i915 = i915_context(pipe); + + i915->blend_color = *blend_color; + + i915->dirty |= I915_NEW_BLEND; +} + +static void * +i915_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + struct i915_sampler_state *cso = CALLOC_STRUCT( i915_sampler_state ); + const unsigned ws = sampler->wrap_s; + const unsigned wt = sampler->wrap_t; + const unsigned wr = sampler->wrap_r; + unsigned minFilt, magFilt; + unsigned mipFilt; + + cso->templ = sampler; + + mipFilt = translate_mip_filter(sampler->min_mip_filter); + if (sampler->max_anisotropy > 1.0) { + minFilt = FILTER_ANISOTROPIC; + magFilt = FILTER_ANISOTROPIC; + if (sampler->max_anisotropy > 2.0) { + cso->state[0] |= SS2_MAX_ANISO_4; + } + } + else { + minFilt = translate_img_filter( sampler->min_img_filter ); + magFilt = translate_img_filter( sampler->mag_img_filter ); + } + + { + int b = (int) (sampler->lod_bias * 16.0); + b = CLAMP(b, -256, 255); + cso->state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); + } + + /* Shadow: + */ + if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) + { + cso->state[0] |= (SS2_SHADOW_ENABLE | + i915_translate_compare_func(sampler->compare_func)); + + minFilt = FILTER_4X4_FLAT; + magFilt = FILTER_4X4_FLAT; + } + + cso->state[0] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | + (mipFilt << SS2_MIP_FILTER_SHIFT) | + (magFilt << SS2_MAG_FILTER_SHIFT)); + + cso->state[1] |= + ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT)); + + if (sampler->normalized_coords) + cso->state[1] |= SS3_NORMALIZED_COORDS; + + if (0) /* XXX not tested yet */ + { + int minlod = (int) (16.0 * sampler->min_lod); + minlod = CLAMP(minlod, 0, 16 * 11); + cso->state[1] |= (minlod << SS3_MIN_LOD_SHIFT); + } + + { + 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]); + cso->state[2] = I915PACKCOLOR8888(r, g, b, a); + } + return cso; +} + +static void i915_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, void *sampler) +{ + struct i915_context *i915 = i915_context(pipe); + + assert(unit < PIPE_MAX_SAMPLERS); + i915->sampler[unit] = (const struct i915_sampler_state*)sampler; + + i915->dirty |= I915_NEW_SAMPLER; +} + +static void i915_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + FREE(sampler); +} + + +/** XXX move someday? Or consolidate all these simple state setters + * into one file. + */ + +static void * +i915_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + struct i915_depth_stencil_state *cso = CALLOC_STRUCT( i915_depth_stencil_state ); + + { + int testmask = depth_stencil->stencil[0].value_mask & 0xff; + int writemask = depth_stencil->stencil[0].write_mask & 0xff; + + cso->stencil_modes4 |= (_3DSTATE_MODES_4_CMD | + ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(testmask) | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(writemask)); + } + + if (depth_stencil->stencil[0].enabled) { + int test = i915_translate_compare_func(depth_stencil->stencil[0].func); + int fop = i915_translate_stencil_op(depth_stencil->stencil[0].fail_op); + int dfop = i915_translate_stencil_op(depth_stencil->stencil[0].zfail_op); + int dpop = i915_translate_stencil_op(depth_stencil->stencil[0].zpass_op); + int ref = depth_stencil->stencil[0].ref_value & 0xff; + + cso->stencil_LIS5 |= (S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE | + (ref << S5_STENCIL_REF_SHIFT) | + (test << S5_STENCIL_TEST_FUNC_SHIFT) | + (fop << S5_STENCIL_FAIL_SHIFT) | + (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) | + (dpop << S5_STENCIL_PASS_Z_PASS_SHIFT)); + } + + if (depth_stencil->stencil[1].enabled) { + int test = i915_translate_compare_func(depth_stencil->stencil[1].func); + int fop = i915_translate_stencil_op(depth_stencil->stencil[1].fail_op); + int dfop = i915_translate_stencil_op(depth_stencil->stencil[1].zfail_op); + int dpop = i915_translate_stencil_op(depth_stencil->stencil[1].zpass_op); + int ref = depth_stencil->stencil[1].ref_value & 0xff; + int tmask = depth_stencil->stencil[1].value_mask & 0xff; + int wmask = depth_stencil->stencil[1].write_mask & 0xff; + + cso->bfo[0] = (_3DSTATE_BACKFACE_STENCIL_OPS | + BFO_ENABLE_STENCIL_FUNCS | + BFO_ENABLE_STENCIL_TWO_SIDE | + BFO_ENABLE_STENCIL_REF | + BFO_STENCIL_TWO_SIDE | + (ref << BFO_STENCIL_REF_SHIFT) | + (test << BFO_STENCIL_TEST_SHIFT) | + (fop << BFO_STENCIL_FAIL_SHIFT) | + (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) | + (dpop << BFO_STENCIL_PASS_Z_PASS_SHIFT)); + + cso->bfo[1] = (_3DSTATE_BACKFACE_STENCIL_MASKS | + BFM_ENABLE_STENCIL_TEST_MASK | + BFM_ENABLE_STENCIL_WRITE_MASK | + (tmask << BFM_STENCIL_TEST_MASK_SHIFT) | + (wmask << BFM_STENCIL_WRITE_MASK_SHIFT)); + } + else { + /* This actually disables two-side stencil: The bit set is a + * modify-enable bit to indicate we are changing the two-side + * setting. Then there is a symbolic zero to show that we are + * setting the flag to zero/off. + */ + cso->bfo[0] = (_3DSTATE_BACKFACE_STENCIL_OPS | + BFO_ENABLE_STENCIL_TWO_SIDE | + 0); + cso->bfo[1] = 0; + } + + if (depth_stencil->depth.enabled) { + int func = i915_translate_compare_func(depth_stencil->depth.func); + + cso->depth_LIS6 |= (S6_DEPTH_TEST_ENABLE | + (func << S6_DEPTH_TEST_FUNC_SHIFT)); + + if (depth_stencil->depth.writemask) + cso->depth_LIS6 |= S6_DEPTH_WRITE_ENABLE; + } + + if (depth_stencil->alpha.enabled) { + int test = i915_translate_compare_func(depth_stencil->alpha.func); + ubyte refByte = float_to_ubyte(depth_stencil->alpha.ref); + + cso->depth_LIS6 |= (S6_ALPHA_TEST_ENABLE | + (test << S6_ALPHA_TEST_FUNC_SHIFT) | + (((unsigned) refByte) << S6_ALPHA_REF_SHIFT)); + } + + return cso; +} + +static void i915_bind_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct i915_context *i915 = i915_context(pipe); + + i915->depth_stencil = (const struct i915_depth_stencil_state *)depth_stencil; + + i915->dirty |= I915_NEW_DEPTH_STENCIL; +} + +static void i915_delete_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + FREE(depth_stencil); +} + + +static void i915_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct i915_context *i915 = i915_context(pipe); + + memcpy( &i915->scissor, scissor, sizeof(*scissor) ); + i915->dirty |= I915_NEW_SCISSOR; +} + + +static void i915_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ +} + + +static void * i915_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + return 0; +} + +static void i915_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct i915_context *i915 = i915_context(pipe); + + i915->fs = (struct pipe_shader_state *)fs; + + i915->dirty |= I915_NEW_FS; +} + +static void i915_delete_fs_state(struct pipe_context *pipe, void *shader) +{ + /*do nothing*/ +} + +static void * +i915_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct i915_context *i915 = i915_context(pipe); + + /* just pass-through to draw module */ + return draw_create_vertex_shader(i915->draw, templ); +} + +static void i915_bind_vs_state(struct pipe_context *pipe, void *shader) +{ + struct i915_context *i915 = i915_context(pipe); + + /* just pass-through to draw module */ + draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader); +} + +static void i915_delete_vs_state(struct pipe_context *pipe, void *shader) +{ + struct i915_context *i915 = i915_context(pipe); + + /* just pass-through to draw module */ + draw_delete_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader); +} + +static void i915_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct i915_context *i915 = i915_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + + assert(shader < PIPE_SHADER_TYPES); + assert(index == 0); + + /* Make a copy of shader constants. + * During fragment program translation we may add additional + * constants to the array. + * + * We want to consider the situation where some user constants + * (ex: a material color) may change frequently but the shader program + * stays the same. In that case we should only be updating the first + * N constants, leaving any extras from shader translation alone. + */ + { + void *mapped; + if (buf->size && + (mapped = ws->buffer_map(ws, buf->buffer, + PIPE_BUFFER_USAGE_CPU_READ))) { + memcpy(i915->current.constants[shader], mapped, buf->size); + ws->buffer_unmap(ws, buf->buffer); + i915->current.num_user_constants[shader] + = buf->size / (4 * sizeof(float)); + } + else { + i915->current.num_user_constants[shader] = 0; + } + } + + i915->dirty |= I915_NEW_CONSTANTS; +} + + +static void i915_set_sampler_texture(struct pipe_context *pipe, + unsigned sampler, + struct pipe_texture *texture) +{ + struct i915_context *i915 = i915_context(pipe); + + i915->texture[sampler] = (struct i915_texture*)texture; /* ptr, not struct */ + + i915->dirty |= I915_NEW_TEXTURE; +} + + + +static void i915_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct i915_context *i915 = i915_context(pipe); + + i915->framebuffer = *fb; /* struct copy */ + + i915->dirty |= I915_NEW_FRAMEBUFFER; +} + + + +static void i915_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct i915_context *i915 = i915_context(pipe); + + draw_set_clip_state(i915->draw, clip); + + i915->dirty |= I915_NEW_CLIP; +} + + + +/* Called when driver state tracker notices changes to the viewport + * matrix: + */ +static void i915_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct i915_context *i915 = i915_context(pipe); + + i915->viewport = *viewport; /* struct copy */ + + /* pass the viewport info to the draw module */ + draw_set_viewport_state(i915->draw, &i915->viewport); + + i915->dirty |= I915_NEW_VIEWPORT; +} + + +static void * +i915_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *rasterizer) +{ + struct i915_rasterizer_state *cso = CALLOC_STRUCT( i915_rasterizer_state ); + + 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; + cso->ds[1].f = rasterizer->offset_scale; + if (rasterizer->poly_stipple_enable) { + cso->st |= ST1_ENABLE; + } + + if (rasterizer->scissor) + cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT; + else + cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT; + + switch (rasterizer->cull_mode) { + case PIPE_WINDING_NONE: + cso->LIS4 |= S4_CULLMODE_NONE; + break; + case PIPE_WINDING_CW: + cso->LIS4 |= S4_CULLMODE_CW; + break; + case PIPE_WINDING_CCW: + cso->LIS4 |= S4_CULLMODE_CCW; + break; + case PIPE_WINDING_BOTH: + cso->LIS4 |= S4_CULLMODE_BOTH; + break; + } + + { + int line_width = CLAMP((int)(rasterizer->line_width * 2), 1, 0xf); + + cso->LIS4 |= line_width << S4_LINE_WIDTH_SHIFT; + + if (rasterizer->line_smooth) + cso->LIS4 |= S4_LINE_ANTIALIAS_ENABLE; + } + + { + int point_size = CLAMP((int) rasterizer->point_size, 1, 0xff); + + cso->LIS4 |= point_size << S4_POINT_WIDTH_SHIFT; + } + + if (rasterizer->flatshade) { + cso->LIS4 |= (S4_FLATSHADE_ALPHA | + S4_FLATSHADE_COLOR | + S4_FLATSHADE_SPECULAR); + } + + cso->LIS7 = fui( rasterizer->offset_units ); + + + return cso; +} + +static void i915_bind_rasterizer_state( struct pipe_context *pipe, + void *setup ) +{ + struct i915_context *i915 = i915_context(pipe); + + i915->rasterizer = (struct i915_rasterizer_state *)setup; + + /* pass-through to draw module */ + draw_set_rasterizer_state(i915->draw, i915->rasterizer->templ); + + i915->dirty |= I915_NEW_RASTERIZER; +} + +static void i915_delete_rasterizer_state(struct pipe_context *pipe, + void *setup) +{ + FREE(setup); +} + +static void i915_set_vertex_buffer( struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_buffer *buffer ) +{ + struct i915_context *i915 = i915_context(pipe); + i915->vertex_buffer[index] = *buffer; + /* pass-through to draw module */ + draw_set_vertex_buffer(i915->draw, index, buffer); +} + +static void i915_set_vertex_element( struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_element *element) +{ + struct i915_context *i915 = i915_context(pipe); + /* pass-through to draw module */ + draw_set_vertex_element(i915->draw, index, element); +} + + + +void +i915_init_state_functions( struct i915_context *i915 ) +{ + i915->pipe.create_blend_state = i915_create_blend_state; + i915->pipe.bind_blend_state = i915_bind_blend_state; + i915->pipe.delete_blend_state = i915_delete_blend_state; + + i915->pipe.create_sampler_state = i915_create_sampler_state; + i915->pipe.bind_sampler_state = i915_bind_sampler_state; + i915->pipe.delete_sampler_state = i915_delete_sampler_state; + + i915->pipe.create_depth_stencil_alpha_state = i915_create_depth_stencil_state; + i915->pipe.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state; + i915->pipe.delete_depth_stencil_alpha_state = i915_delete_depth_stencil_state; + + i915->pipe.create_rasterizer_state = i915_create_rasterizer_state; + i915->pipe.bind_rasterizer_state = i915_bind_rasterizer_state; + i915->pipe.delete_rasterizer_state = i915_delete_rasterizer_state; + i915->pipe.create_fs_state = i915_create_fs_state; + i915->pipe.bind_fs_state = i915_bind_fs_state; + i915->pipe.delete_fs_state = i915_delete_fs_state; + i915->pipe.create_vs_state = i915_create_vs_state; + i915->pipe.bind_vs_state = i915_bind_vs_state; + i915->pipe.delete_vs_state = i915_delete_vs_state; + + i915->pipe.set_blend_color = i915_set_blend_color; + i915->pipe.set_clip_state = i915_set_clip_state; + i915->pipe.set_constant_buffer = i915_set_constant_buffer; + i915->pipe.set_framebuffer_state = i915_set_framebuffer_state; + + i915->pipe.set_polygon_stipple = i915_set_polygon_stipple; + i915->pipe.set_scissor_state = i915_set_scissor_state; + i915->pipe.set_sampler_texture = i915_set_sampler_texture; + i915->pipe.set_viewport_state = i915_set_viewport_state; + i915->pipe.set_vertex_buffer = i915_set_vertex_buffer; + i915->pipe.set_vertex_element = i915_set_vertex_element; +} diff --git a/src/gallium/drivers/i915simple/i915_state.h b/src/gallium/drivers/i915simple/i915_state.h new file mode 100644 index 0000000000..86c6b0027d --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_state.h @@ -0,0 +1,50 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef I915_STATE_H +#define I915_STATE_H + +struct i915_context; + + +struct i915_tracked_state { + unsigned dirty; + void (*update)( struct i915_context * ); +}; + +void i915_update_immediate( struct i915_context *i915 ); +void i915_update_dynamic( struct i915_context *i915 ); +void i915_update_derived( struct i915_context *i915 ); +void i915_update_samplers( struct i915_context *i915 ); +void i915_update_textures(struct i915_context *i915); + +void i915_emit_hardware_state( struct i915_context *i915 ); + +#endif diff --git a/src/gallium/drivers/i915simple/i915_state_derived.c b/src/gallium/drivers/i915simple/i915_state_derived.c new file mode 100644 index 0000000000..653983e4a9 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_state_derived.c @@ -0,0 +1,177 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_util.h" +#include "pipe/draw/draw_context.h" +#include "pipe/draw/draw_vertex.h" +#include "i915_context.h" +#include "i915_state.h" +#include "i915_reg.h" +#include "i915_fpc.h" +#include "pipe/p_shader_tokens.h" + + +/** + * Determine which post-transform / pre-rasterization vertex attributes + * we need. + * Derived from: fs, setup states. + */ +static void calculate_vertex_layout( struct i915_context *i915 ) +{ + const struct pipe_shader_state *fs = i915->fs; + const enum interp_mode colorInterp = i915->rasterizer->color_interp; + struct vertex_info vinfo; + uint front0 = 0, back0 = 0, front1 = 0, back1 = 0; + boolean needW = 0; + uint i; + boolean texCoords[8]; + uint src = 0; + + memset(texCoords, 0, sizeof(texCoords)); + memset(&vinfo, 0, sizeof(vinfo)); + + /* pos */ + draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src++); + /* Note: we'll set the S4_VFMT_XYZ[W] bits below */ + + for (i = 0; i < fs->num_inputs; i++) { + switch (fs->input_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + break; + case TGSI_SEMANTIC_COLOR: + if (fs->input_semantic_index[i] == 0) { + front0 = draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src++); + vinfo.hwfmt[0] |= S4_VFMT_COLOR; + } + else { + assert(fs->input_semantic_index[i] == 1); + front1 = draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src++); + vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG; + } + break; + case TGSI_SEMANTIC_GENERIC: + /* usually a texcoord */ + { + const uint unit = fs->input_semantic_index[i]; + uint hwtc; + texCoords[unit] = TRUE; + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); + hwtc = TEXCOORDFMT_4D; + needW = TRUE; + vinfo.hwfmt[1] |= hwtc << (unit * 4); + } + break; + case TGSI_SEMANTIC_FOG: + debug_printf("i915 fogcoord not implemented yet\n"); + draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src++); + break; + default: + assert(0); + } + + } + + /* finish up texcoord fields */ + for (i = 0; i < 8; i++) { + if (!texCoords[i]) { + const uint hwtc = TEXCOORDFMT_NOT_PRESENT; + vinfo.hwfmt[1] |= hwtc << (i* 4); + } + } + + /* go back and fill in the vertex position info now that we have needW */ + if (needW) { + vinfo.hwfmt[0] |= S4_VFMT_XYZW; + vinfo.emit[0] = EMIT_4F; + } + else { + vinfo.hwfmt[0] |= S4_VFMT_XYZ; + vinfo.emit[0] = EMIT_3F; + } + + /* Additional attributes required for setup: Just twosided + * lighting. Edgeflag is dealt with specially by setting bits in + * the vertex header. + */ + if (i915->rasterizer->light_twoside) { + if (front0) { + back0 = draw_emit_vertex_attr(&vinfo, EMIT_OMIT, colorInterp, src++); + } + if (back0) { + back1 = draw_emit_vertex_attr(&vinfo, EMIT_OMIT, colorInterp, src++); + } + } + + draw_compute_vertex_size(&vinfo); + + if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) { + /* Need to set this flag so that the LIS2/4 registers get set. + * It also means the i915_update_immediate() function must be called + * after this one, in i915_update_derived(). + */ + i915->dirty |= I915_NEW_VERTEX_FORMAT; + + memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo)); + } +} + + + + +/* Hopefully this will remain quite simple, otherwise need to pull in + * something like the state tracker mechanism. + */ +void i915_update_derived( struct i915_context *i915 ) +{ + if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS)) + calculate_vertex_layout( i915 ); + + if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_TEXTURE)) + i915_update_samplers(i915); + + if (i915->dirty & I915_NEW_TEXTURE) + i915_update_textures(i915); + + if (i915->dirty) + i915_update_immediate( i915 ); + + if (i915->dirty) + i915_update_dynamic( i915 ); + + if (i915->dirty & I915_NEW_FS) { + i915_translate_fragment_program(i915); + i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */ + } + + /* HW emit currently references framebuffer state directly: + */ + if (i915->dirty & I915_NEW_FRAMEBUFFER) + i915->hardware_dirty |= I915_HW_STATIC; + + i915->dirty = 0; +} diff --git a/src/gallium/drivers/i915simple/i915_state_dynamic.c b/src/gallium/drivers/i915simple/i915_state_dynamic.c new file mode 100644 index 0000000000..8cfbdddd19 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_state_dynamic.c @@ -0,0 +1,308 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "i915_batch.h" +#include "i915_state_inlines.h" +#include "i915_context.h" +#include "i915_reg.h" +#include "i915_state.h" +#include "pipe/p_util.h" + +#define FILE_DEBUG_FLAG DEBUG_STATE + +/* State that we have chosen to store in the DYNAMIC segment of the + * i915 indirect state mechanism. + * + * Can't cache these in the way we do the static state, as there is no + * start/size in the command packet, instead an 'end' value that gets + * incremented. + * + * Additionally, there seems to be a requirement to re-issue the full + * (active) state every time a 4kb boundary is crossed. + */ + +static INLINE void set_dynamic_indirect( struct i915_context *i915, + unsigned offset, + const unsigned *src, + unsigned dwords ) +{ + unsigned i; + + for (i = 0; i < dwords; i++) + i915->current.dynamic[offset + i] = src[i]; + + i915->hardware_dirty |= I915_HW_DYNAMIC; +} + + +/*********************************************************************** + * Modes4: stencil masks and logicop + */ +static void upload_MODES4( struct i915_context *i915 ) +{ + unsigned modes4 = 0; + + /* I915_NEW_STENCIL */ + modes4 |= i915->depth_stencil->stencil_modes4; + /* I915_NEW_BLEND */ + modes4 |= i915->blend->modes4; + + /* Always, so that we know when state is in-active: + */ + set_dynamic_indirect( i915, + I915_DYNAMIC_MODES4, + &modes4, + 1 ); +} + +const struct i915_tracked_state i915_upload_MODES4 = { + I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL, + upload_MODES4 +}; + + + + +/*********************************************************************** + */ + +static void upload_BFO( struct i915_context *i915 ) +{ + set_dynamic_indirect( i915, + I915_DYNAMIC_BFO_0, + &(i915->depth_stencil->bfo[0]), + 2 ); +} + +const struct i915_tracked_state i915_upload_BFO = { + I915_NEW_DEPTH_STENCIL, + upload_BFO +}; + + +/*********************************************************************** + */ + + +static void upload_BLENDCOLOR( struct i915_context *i915 ) +{ + unsigned bc[2]; + + memset( bc, 0, sizeof(bc) ); + + /* I915_NEW_BLEND {_COLOR} + */ + { + const float *color = i915->blend_color.color; + + bc[0] = _3DSTATE_CONST_BLEND_COLOR_CMD; + bc[1] = pack_ui32_float4( color[0], + color[1], + color[2], + color[3] ); + } + + set_dynamic_indirect( i915, + I915_DYNAMIC_BC_0, + bc, + 2 ); +} + +const struct i915_tracked_state i915_upload_BLENDCOLOR = { + I915_NEW_BLEND, + upload_BLENDCOLOR +}; + +/*********************************************************************** + */ + + +static void upload_IAB( struct i915_context *i915 ) +{ + unsigned iab = i915->blend->iab; + + + set_dynamic_indirect( i915, + I915_DYNAMIC_IAB, + &iab, + 1 ); +} + +const struct i915_tracked_state i915_upload_IAB = { + I915_NEW_BLEND, + upload_IAB +}; + + +/*********************************************************************** + */ + + + +static void upload_DEPTHSCALE( struct i915_context *i915 ) +{ + set_dynamic_indirect( i915, + I915_DYNAMIC_DEPTHSCALE_0, + &(i915->rasterizer->ds[0].u), + 2 ); +} + +const struct i915_tracked_state i915_upload_DEPTHSCALE = { + I915_NEW_RASTERIZER, + upload_DEPTHSCALE +}; + + + +/*********************************************************************** + * Polygon stipple + * + * The i915 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + * + * XXX: does stipple pattern need to be adjusted according to + * the window position? + * + * XXX: possibly need workaround for conform paths test. + */ + +static void upload_STIPPLE( struct i915_context *i915 ) +{ + unsigned st[2]; + + st[0] = _3DSTATE_STIPPLE; + st[1] = 0; + + /* I915_NEW_RASTERIZER + */ + st[1] |= i915->rasterizer->st; + + + /* I915_NEW_STIPPLE + */ + { + const ubyte *mask = (const ubyte *)i915->poly_stipple.stipple; + ubyte p[4]; + + p[0] = mask[12] & 0xf; + p[1] = mask[8] & 0xf; + p[2] = mask[4] & 0xf; + p[3] = mask[0] & 0xf; + + /* Not sure what to do about fallbacks, so for now just dont: + */ + st[1] |= ((p[0] << 0) | + (p[1] << 4) | + (p[2] << 8) | + (p[3] << 12)); + } + + + set_dynamic_indirect( i915, + I915_DYNAMIC_STP_0, + &st[0], + 2 ); +} + + +const struct i915_tracked_state i915_upload_STIPPLE = { + I915_NEW_RASTERIZER | I915_NEW_STIPPLE, + upload_STIPPLE +}; + + + +/*********************************************************************** + * Scissor. + */ +static void upload_SCISSOR_ENABLE( struct i915_context *i915 ) +{ + set_dynamic_indirect( i915, + I915_DYNAMIC_SC_ENA_0, + &(i915->rasterizer->sc[0]), + 1 ); +} + +const struct i915_tracked_state i915_upload_SCISSOR_ENABLE = { + I915_NEW_RASTERIZER, + upload_SCISSOR_ENABLE +}; + + + +static void upload_SCISSOR_RECT( struct i915_context *i915 ) +{ + unsigned x1 = i915->scissor.minx; + unsigned y1 = i915->scissor.miny; + unsigned x2 = i915->scissor.maxx; + unsigned y2 = i915->scissor.maxy; + unsigned sc[3]; + + sc[0] = _3DSTATE_SCISSOR_RECT_0_CMD; + sc[1] = (y1 << 16) | (x1 & 0xffff); + sc[2] = (y2 << 16) | (x2 & 0xffff); + + set_dynamic_indirect( i915, + I915_DYNAMIC_SC_RECT_0, + &sc[0], + 3 ); +} + + +const struct i915_tracked_state i915_upload_SCISSOR_RECT = { + I915_NEW_SCISSOR, + upload_SCISSOR_RECT +}; + + + + + + +static const struct i915_tracked_state *atoms[] = { + &i915_upload_MODES4, + &i915_upload_BFO, + &i915_upload_BLENDCOLOR, + &i915_upload_IAB, + &i915_upload_DEPTHSCALE, + &i915_upload_STIPPLE, + &i915_upload_SCISSOR_ENABLE, + &i915_upload_SCISSOR_RECT +}; + +/* These will be dynamic indirect state commands, but for now just end + * up on the batch buffer with everything else. + */ +void i915_update_dynamic( struct i915_context *i915 ) +{ + int i; + + for (i = 0; i < Elements(atoms); i++) + if (i915->dirty & atoms[i]->dirty) + atoms[i]->update( i915 ); +} + diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c new file mode 100644 index 0000000000..3339287f49 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -0,0 +1,374 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_winsys.h" +#include "i915_batch.h" +#include "i915_reg.h" + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" + +static unsigned translate_format( enum pipe_format format ) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + return COLOR_BUF_ARGB8888; + case PIPE_FORMAT_R5G6B5_UNORM: + return COLOR_BUF_RGB565; + default: + assert(0); + return 0; + } +} + +static unsigned translate_depth_format( enum pipe_format zformat ) +{ + switch (zformat) { + case PIPE_FORMAT_S8Z24_UNORM: + return DEPTH_FRMT_24_FIXED_8_OTHER; + case PIPE_FORMAT_Z16_UNORM: + return DEPTH_FRMT_16_FIXED; + default: + assert(0); + return 0; + } +} + + +/** + * Examine framebuffer state to determine width, height. + */ +static boolean +framebuffer_size(const struct pipe_framebuffer_state *fb, + uint *width, uint *height) +{ + if (fb->cbufs[0]) { + *width = fb->cbufs[0]->width; + *height = fb->cbufs[0]->height; + return TRUE; + } + else if (fb->zsbuf) { + *width = fb->zsbuf->width; + *height = fb->zsbuf->height; + return TRUE; + } + else { + *width = *height = 0; + return FALSE; + } +} + + +/* Push the state into the sarea and/or texture memory. + */ +void +i915_emit_hardware_state(struct i915_context *i915 ) +{ + /* XXX: there must be an easier way */ + const unsigned dwords = ( 14 + + 7 + + I915_MAX_DYNAMIC + + 8 + + 2 + I915_TEX_UNITS*3 + + 2 + I915_TEX_UNITS*3 + + 2 + I915_MAX_CONSTANT*4 + + i915->current.program_len + + 6 + ) * 3/2; /* plus 50% margin */ + const unsigned relocs = ( I915_TEX_UNITS + + 3 + ) * 3/2; /* plus 50% margin */ + +#if 0 + debug_printf("i915_emit_hardware_state: %d dwords, %d relocs\n", dwords, relocs); +#endif + + if(!BEGIN_BATCH(dwords, relocs)) { + FLUSH_BATCH(); + assert(BEGIN_BATCH(dwords, relocs)); + } + + /* 14 dwords, 0 relocs */ + if (i915->hardware_dirty & I915_HW_INVARIENT) + { + OUT_BATCH(_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); + + OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_Z_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS | + CSB_TCB(0, 0) | + CSB_TCB(1, 1) | + CSB_TCB(2, 2) | + CSB_TCB(3, 3) | + CSB_TCB(4, 4) | + CSB_TCB(5, 5) | + CSB_TCB(6, 6) | + CSB_TCB(7, 7)); + + OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | + ENABLE_TEXKILL_3D_4D | + TEXKILL_4D); + + /* Need to initialize this to zero. + */ + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (0)); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE); + + /* disable indirect state for now + */ + OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); + OUT_BATCH(0); + } + + /* 7 dwords, 1 relocs */ + if (i915->hardware_dirty & I915_HW_IMMEDIATE) + { + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(0) | + I1_LOAD_S(1) | + I1_LOAD_S(2) | + I1_LOAD_S(4) | + I1_LOAD_S(5) | + I1_LOAD_S(6) | + (5)); + + if(i915->vbo) + OUT_RELOC(i915->vbo, + I915_BUFFER_ACCESS_READ, + i915->current.immediate[I915_IMMEDIATE_S0]); + else + /* FIXME: we should not do this */ + OUT_BATCH(0); + OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S1]); + OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S2]); + OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S4]); + OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S5]); + OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S6]); + } + + /* I915_MAX_DYNAMIC dwords, 0 relocs */ + if (i915->hardware_dirty & I915_HW_DYNAMIC) + { + int i; + for (i = 0; i < I915_MAX_DYNAMIC; i++) { + OUT_BATCH(i915->current.dynamic[i]); + } + } + + /* 8 dwords, 2 relocs */ + if (i915->hardware_dirty & I915_HW_STATIC) + { + struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; + struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; + + if (cbuf_surface) { + unsigned pitch = (cbuf_surface->pitch * cbuf_surface->cpp); + + OUT_BATCH(_3DSTATE_BUF_INFO_CMD); + + OUT_BATCH(BUF_3D_ID_COLOR_BACK | + BUF_3D_PITCH(pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + OUT_RELOC(cbuf_surface->buffer, + I915_BUFFER_ACCESS_WRITE, + 0); + } + + /* What happens if no zbuf?? + */ + if (depth_surface) { + unsigned zpitch = (depth_surface->pitch * depth_surface->cpp); + + OUT_BATCH(_3DSTATE_BUF_INFO_CMD); + + OUT_BATCH(BUF_3D_ID_DEPTH | + BUF_3D_PITCH(zpitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + OUT_RELOC(depth_surface->buffer, + I915_BUFFER_ACCESS_WRITE, + 0); + } + + { + unsigned cformat, zformat = 0; + + if (cbuf_surface) + cformat = cbuf_surface->format; + else + cformat = PIPE_FORMAT_A8R8G8B8_UNORM; /* arbitrary */ + cformat = translate_format(cformat); + + if (depth_surface) + zformat = translate_depth_format( i915->framebuffer.zsbuf->format ); + + OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); + OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + cformat | + zformat ); + } + } + +#if 01 + /* texture images */ + /* 2 + I915_TEX_UNITS*3 dwords, I915_TEX_UNITS relocs */ + if (i915->hardware_dirty & (I915_HW_MAP | I915_HW_SAMPLER)) + { + /* XXX: we were refering to sampler state + * (current.sampler_enable_nr) below, but only checking + * I915_HW_MAP above. Should probably calculate the enabled + * flags separately - but there will be further rework of + * state so perhaps not necessary yet. + */ + const uint nr = i915->current.sampler_enable_nr; + if (nr) { + const uint enabled = i915->current.sampler_enable_flags; + uint unit; + uint count = 0; + OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr)); + OUT_BATCH(enabled); + for (unit = 0; unit < I915_TEX_UNITS; unit++) { + if (enabled & (1 << unit)) { + struct pipe_buffer *buf = + i915->texture[unit]->buffer; + uint offset = 0; + assert(buf); + + count++; + + OUT_RELOC(buf, + I915_BUFFER_ACCESS_READ, + offset); + OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */ + OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */ + } + } + assert(count == nr); + } + } +#endif + +#if 01 + /* samplers */ + /* 2 + I915_TEX_UNITS*3 dwords, 0 relocs */ + if (i915->hardware_dirty & I915_HW_SAMPLER) + { + if (i915->current.sampler_enable_nr) { + int i; + + OUT_BATCH( _3DSTATE_SAMPLER_STATE | + (3 * i915->current.sampler_enable_nr) ); + + OUT_BATCH( i915->current.sampler_enable_flags ); + + for (i = 0; i < I915_TEX_UNITS; i++) { + if (i915->current.sampler_enable_flags & (1<current.sampler[i][0] ); + OUT_BATCH( i915->current.sampler[i][1] ); + OUT_BATCH( i915->current.sampler[i][2] ); + } + } + } + } +#endif + + /* constants */ + /* 2 + I915_MAX_CONSTANT*4 dwords, 0 relocs */ + if (i915->hardware_dirty & I915_HW_PROGRAM) + { + const uint nr = i915->current.num_constants[PIPE_SHADER_FRAGMENT]; + assert(nr <= I915_MAX_CONSTANT); + if (nr > 0) { + const uint *c + = (const uint *) i915->current.constants[PIPE_SHADER_FRAGMENT]; + uint i; + OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) ); + OUT_BATCH( (1 << (nr - 1)) | ((1 << (nr - 1)) - 1) ); + for (i = 0; i < nr; i++) { + OUT_BATCH(*c++); + OUT_BATCH(*c++); + OUT_BATCH(*c++); + OUT_BATCH(*c++); + } + } + } + + /* Fragment program */ + /* i915->current.program_len dwords, 0 relocs */ + if (i915->hardware_dirty & I915_HW_PROGRAM) + { + uint i; + /* we should always have, at least, a pass-through program */ + assert(i915->current.program_len > 0); + for (i = 0; i < i915->current.program_len; i++) { + OUT_BATCH(i915->current.program[i]); + } + } + + /* drawing surface size */ + /* 6 dwords, 0 relocs */ + { + uint w, h; + boolean k = framebuffer_size(&i915->framebuffer, &w, &h); + assert(k); + + OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(((w - 1) & 0xffff) | ((h - 1) << 16)); + OUT_BATCH(0); + OUT_BATCH(0); + } + + + i915->hardware_dirty = 0; +} diff --git a/src/gallium/drivers/i915simple/i915_state_immediate.c b/src/gallium/drivers/i915simple/i915_state_immediate.c new file mode 100644 index 0000000000..07031fc6c5 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_state_immediate.c @@ -0,0 +1,221 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "i915_state_inlines.h" +#include "i915_context.h" +#include "i915_state.h" +#include "i915_reg.h" +#include "p_util.h" + + +/* All state expressable with the LOAD_STATE_IMMEDIATE_1 packet. + * Would like to opportunistically recombine all these fragments into + * a single packet containing only what has changed, but for now emit + * as multiple packets. + */ + + + + +/*********************************************************************** + * S0,S1: Vertex buffer state. + */ +static void upload_S0S1(struct i915_context *i915) +{ + unsigned LIS0, LIS1; + + /* INTEL_NEW_VBO */ + /* TODO: re-use vertex buffers here? */ + LIS0 = 0; + + /* INTEL_NEW_VERTEX_SIZE -- do this where the vertex size is calculated! + */ + { + unsigned vertex_size = i915->current.vertex_info.size; + + LIS1 = ((vertex_size << 24) | + (vertex_size << 16)); + } + + /* INTEL_NEW_VBO */ + /* TODO: use a vertex generation number to track vbo changes */ + if (1 || + i915->current.immediate[I915_IMMEDIATE_S0] != LIS0 || + i915->current.immediate[I915_IMMEDIATE_S1] != LIS1) + { + i915->current.immediate[I915_IMMEDIATE_S0] = LIS0; + i915->current.immediate[I915_IMMEDIATE_S1] = LIS1; + i915->hardware_dirty |= I915_HW_IMMEDIATE; + } +} + +const struct i915_tracked_state i915_upload_S0S1 = { + I915_NEW_VBO | I915_NEW_VERTEX_FORMAT, + upload_S0S1 +}; + + + + +/*********************************************************************** + * S4: Vertex format, rasterization state + */ +static void upload_S2S4(struct i915_context *i915) +{ + unsigned LIS2, LIS4; + + /* I915_NEW_VERTEX_FORMAT */ + { + LIS2 = i915->current.vertex_info.hwfmt[1]; + LIS4 = i915->current.vertex_info.hwfmt[0]; + /* + debug_printf("LIS2: 0x%x LIS4: 0x%x\n", LIS2, LIS4); + */ + assert(LIS4); /* should never be zero? */ + } + + LIS4 |= i915->rasterizer->LIS4; + + if (LIS2 != i915->current.immediate[I915_IMMEDIATE_S2] || + LIS4 != i915->current.immediate[I915_IMMEDIATE_S4]) { + + i915->current.immediate[I915_IMMEDIATE_S2] = LIS2; + i915->current.immediate[I915_IMMEDIATE_S4] = LIS4; + i915->hardware_dirty |= I915_HW_IMMEDIATE; + } +} + + +const struct i915_tracked_state i915_upload_S2S4 = { + I915_NEW_RASTERIZER | I915_NEW_VERTEX_FORMAT, + upload_S2S4 +}; + + + +/*********************************************************************** + * + */ +static void upload_S5( struct i915_context *i915 ) +{ + unsigned LIS5 = 0; + + LIS5 |= i915->depth_stencil->stencil_LIS5; + + LIS5 |= i915->blend->LIS5; + +#if 0 + /* I915_NEW_RASTERIZER */ + if (i915->state.Polygon->OffsetFill) { + LIS5 |= S5_GLOBAL_DEPTH_OFFSET_ENABLE; + } +#endif + + + if (LIS5 != i915->current.immediate[I915_IMMEDIATE_S5]) { + i915->current.immediate[I915_IMMEDIATE_S5] = LIS5; + i915->hardware_dirty |= I915_HW_IMMEDIATE; + } +} + +const struct i915_tracked_state i915_upload_S5 = { + (I915_NEW_DEPTH_STENCIL | I915_NEW_BLEND | I915_NEW_RASTERIZER), + upload_S5 +}; + + +/*********************************************************************** + */ +static void upload_S6( struct i915_context *i915 ) +{ + unsigned LIS6 = (S6_COLOR_WRITE_ENABLE | + (2 << S6_TRISTRIP_PV_SHIFT)); + + /* I915_NEW_BLEND + */ + LIS6 |= i915->blend->LIS6; + + /* I915_NEW_DEPTH + */ + LIS6 |= i915->depth_stencil->depth_LIS6; + + if (LIS6 != i915->current.immediate[I915_IMMEDIATE_S6]) { + i915->current.immediate[I915_IMMEDIATE_S6] = LIS6; + i915->hardware_dirty |= I915_HW_IMMEDIATE; + } +} + +const struct i915_tracked_state i915_upload_S6 = { + I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL, + upload_S6 +}; + + +/*********************************************************************** + */ +static void upload_S7( struct i915_context *i915 ) +{ + unsigned LIS7; + + /* I915_NEW_RASTERIZER + */ + LIS7 = i915->rasterizer->LIS7; + + if (LIS7 != i915->current.immediate[I915_IMMEDIATE_S7]) { + i915->current.immediate[I915_IMMEDIATE_S7] = LIS7; + i915->hardware_dirty |= I915_HW_IMMEDIATE; + } +} + +const struct i915_tracked_state i915_upload_S7 = { + I915_NEW_RASTERIZER, + upload_S7 +}; + + +static const struct i915_tracked_state *atoms[] = { + &i915_upload_S0S1, + &i915_upload_S2S4, + &i915_upload_S5, + &i915_upload_S6, + &i915_upload_S7 +}; + +/* + */ +void i915_update_immediate( struct i915_context *i915 ) +{ + int i; + + for (i = 0; i < Elements(atoms); i++) + if (i915->dirty & atoms[i]->dirty) + atoms[i]->update( i915 ); +} diff --git a/src/gallium/drivers/i915simple/i915_state_inlines.h b/src/gallium/drivers/i915simple/i915_state_inlines.h new file mode 100644 index 0000000000..0934ac79a4 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_state_inlines.h @@ -0,0 +1,230 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef I915_STATE_INLINES_H +#define I915_STATE_INLINES_H + +#include "p_compiler.h" +#include "p_defines.h" +#include "i915_reg.h" + + +static INLINE unsigned +i915_translate_compare_func(unsigned func) +{ + switch (func) { + case PIPE_FUNC_NEVER: + return COMPAREFUNC_NEVER; + case PIPE_FUNC_LESS: + return COMPAREFUNC_LESS; + case PIPE_FUNC_LEQUAL: + return COMPAREFUNC_LEQUAL; + case PIPE_FUNC_GREATER: + return COMPAREFUNC_GREATER; + case PIPE_FUNC_GEQUAL: + return COMPAREFUNC_GEQUAL; + case PIPE_FUNC_NOTEQUAL: + return COMPAREFUNC_NOTEQUAL; + case PIPE_FUNC_EQUAL: + return COMPAREFUNC_EQUAL; + case PIPE_FUNC_ALWAYS: + return COMPAREFUNC_ALWAYS; + default: + return COMPAREFUNC_ALWAYS; + } +} + +static INLINE unsigned +i915_translate_stencil_op(unsigned op) +{ + switch (op) { + case PIPE_STENCIL_OP_KEEP: + return STENCILOP_KEEP; + case PIPE_STENCIL_OP_ZERO: + return STENCILOP_ZERO; + case PIPE_STENCIL_OP_REPLACE: + return STENCILOP_REPLACE; + case PIPE_STENCIL_OP_INCR: + return STENCILOP_INCRSAT; + case PIPE_STENCIL_OP_DECR: + return STENCILOP_DECRSAT; + case PIPE_STENCIL_OP_INCR_WRAP: + return STENCILOP_INCR; + case PIPE_STENCIL_OP_DECR_WRAP: + return STENCILOP_DECR; + case PIPE_STENCIL_OP_INVERT: + return STENCILOP_INVERT; + default: + return STENCILOP_ZERO; + } +} + +static INLINE unsigned +i915_translate_blend_factor(unsigned factor) +{ + switch (factor) { + case PIPE_BLENDFACTOR_ZERO: + return BLENDFACT_ZERO; + case PIPE_BLENDFACTOR_SRC_ALPHA: + return BLENDFACT_SRC_ALPHA; + case PIPE_BLENDFACTOR_ONE: + return BLENDFACT_ONE; + case PIPE_BLENDFACTOR_SRC_COLOR: + return BLENDFACT_SRC_COLR; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + return BLENDFACT_INV_SRC_COLR; + case PIPE_BLENDFACTOR_DST_COLOR: + return BLENDFACT_DST_COLR; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + return BLENDFACT_INV_DST_COLR; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + return BLENDFACT_INV_SRC_ALPHA; + case PIPE_BLENDFACTOR_DST_ALPHA: + return BLENDFACT_DST_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + return BLENDFACT_INV_DST_ALPHA; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + return BLENDFACT_SRC_ALPHA_SATURATE; + case PIPE_BLENDFACTOR_CONST_COLOR: + return BLENDFACT_CONST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + return BLENDFACT_INV_CONST_COLOR; + case PIPE_BLENDFACTOR_CONST_ALPHA: + return BLENDFACT_CONST_ALPHA; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + return BLENDFACT_INV_CONST_ALPHA; + default: + return BLENDFACT_ZERO; + } +} + +static INLINE unsigned +i915_translate_blend_func(unsigned mode) +{ + switch (mode) { + case PIPE_BLEND_ADD: + return BLENDFUNC_ADD; + case PIPE_BLEND_MIN: + return BLENDFUNC_MIN; + case PIPE_BLEND_MAX: + return BLENDFUNC_MAX; + case PIPE_BLEND_SUBTRACT: + return BLENDFUNC_SUBTRACT; + case PIPE_BLEND_REVERSE_SUBTRACT: + return BLENDFUNC_REVERSE_SUBTRACT; + default: + return 0; + } +} + + +static INLINE unsigned +i915_translate_logic_op(unsigned opcode) +{ + switch (opcode) { + case PIPE_LOGICOP_CLEAR: + return LOGICOP_CLEAR; + case PIPE_LOGICOP_AND: + return LOGICOP_AND; + case PIPE_LOGICOP_AND_REVERSE: + return LOGICOP_AND_RVRSE; + case PIPE_LOGICOP_COPY: + return LOGICOP_COPY; + case PIPE_LOGICOP_COPY_INVERTED: + return LOGICOP_COPY_INV; + case PIPE_LOGICOP_AND_INVERTED: + return LOGICOP_AND_INV; + case PIPE_LOGICOP_NOOP: + return LOGICOP_NOOP; + case PIPE_LOGICOP_XOR: + return LOGICOP_XOR; + case PIPE_LOGICOP_OR: + return LOGICOP_OR; + case PIPE_LOGICOP_OR_INVERTED: + return LOGICOP_OR_INV; + case PIPE_LOGICOP_NOR: + return LOGICOP_NOR; + case PIPE_LOGICOP_EQUIV: + return LOGICOP_EQUIV; + case PIPE_LOGICOP_INVERT: + return LOGICOP_INV; + case PIPE_LOGICOP_OR_REVERSE: + return LOGICOP_OR_RVRSE; + case PIPE_LOGICOP_NAND: + return LOGICOP_NAND; + case PIPE_LOGICOP_SET: + return LOGICOP_SET; + default: + return LOGICOP_SET; + } +} + + + +static INLINE boolean i915_validate_vertices( unsigned hw_prim, unsigned nr ) +{ + boolean ok; + + switch (hw_prim) { + case PRIM3D_POINTLIST: + ok = (nr >= 1); + assert(ok); + break; + case PRIM3D_LINELIST: + ok = (nr >= 2) && (nr % 2) == 0; + assert(ok); + break; + case PRIM3D_LINESTRIP: + ok = (nr >= 2); + assert(ok); + break; + case PRIM3D_TRILIST: + ok = (nr >= 3) && (nr % 3) == 0; + assert(ok); + break; + case PRIM3D_TRISTRIP: + ok = (nr >= 3); + assert(ok); + break; + case PRIM3D_TRIFAN: + ok = (nr >= 3); + assert(ok); + break; + case PRIM3D_POLY: + ok = (nr >= 3); + assert(ok); + break; + default: + assert(0); + ok = 0; + break; + } + + return ok; +} + +#endif diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c new file mode 100644 index 0000000000..9c1a5bbbd6 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -0,0 +1,231 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "i915_state_inlines.h" +#include "i915_context.h" +#include "i915_reg.h" +#include "i915_state.h" + + +/** + * Compute i915 texture sampling state. + * + * Recalculate all state from scratch. Perhaps not the most + * efficient, but this has gotten complex enough that we need + * something which is understandable and reliable. + * \param state returns the 3 words of compute state + */ +static void update_sampler(struct i915_context *i915, + uint unit, + const struct i915_sampler_state *sampler, + const struct i915_texture *tex, + unsigned state[3] ) +{ + const struct pipe_texture *pt = &tex->base; + + /* Need to do this after updating the maps, which call the + * intel_finalize_mipmap_tree and hence can update firstLevel: + */ + state[0] = sampler->state[0]; + state[1] = sampler->state[1]; + state[2] = sampler->state[2]; + + if (pt->format == PIPE_FORMAT_YCBCR || + pt->format == PIPE_FORMAT_YCBCR_REV) + state[0] |= SS2_COLORSPACE_CONVERSION; + + /* 3D textures don't seem to respect the border color. + * Fallback if there's ever a danger that they might refer to + * it. + * + * Effectively this means fallback on 3D clamp or + * clamp_to_border. + * + * XXX: Check if this is true on i945. + * XXX: Check if this bug got fixed in release silicon. + */ +#if 0 + { + const unsigned ws = sampler->templ->wrap_s; + const unsigned wt = sampler->templ->wrap_t; + const unsigned wr = sampler->templ->wrap_r; + if (pt->target == PIPE_TEXTURE_3D && + (sampler->templ->min_img_filter != PIPE_TEX_FILTER_NEAREST || + sampler->templ->mag_img_filter != PIPE_TEX_FILTER_NEAREST) && + (ws == PIPE_TEX_WRAP_CLAMP || + wt == PIPE_TEX_WRAP_CLAMP || + wr == PIPE_TEX_WRAP_CLAMP || + ws == PIPE_TEX_WRAP_CLAMP_TO_BORDER || + wt == PIPE_TEX_WRAP_CLAMP_TO_BORDER || + wr == PIPE_TEX_WRAP_CLAMP_TO_BORDER)) { + if (i915->strict_conformance) { + assert(0); + /* sampler->fallback = true; */ + /* TODO */ + } + } + } +#endif + + state[1] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT); +} + + +void i915_update_samplers( struct i915_context *i915 ) +{ + uint unit; + + i915->current.sampler_enable_nr = 0; + i915->current.sampler_enable_flags = 0x0; + + for (unit = 0; unit < I915_TEX_UNITS; unit++) { + /* determine unit enable/disable by looking for a bound texture */ + /* could also examine the fragment program? */ + if (i915->texture[unit]) { + update_sampler( i915, + unit, + i915->sampler[unit], /* sampler state */ + i915->texture[unit], /* texture */ + i915->current.sampler[unit] /* the result */ + ); + + i915->current.sampler_enable_nr++; + i915->current.sampler_enable_flags |= (1 << unit); + } + } + + i915->hardware_dirty |= I915_HW_SAMPLER; +} + + +static uint +translate_texture_format(enum pipe_format pipeFormat) +{ + switch (pipeFormat) { + case PIPE_FORMAT_U_L8: + return MAPSURF_8BIT | MT_8BIT_L8; + case PIPE_FORMAT_U_I8: + return MAPSURF_8BIT | MT_8BIT_I8; + case PIPE_FORMAT_U_A8: + return MAPSURF_8BIT | MT_8BIT_A8; + case PIPE_FORMAT_U_A8_L8: + return MAPSURF_16BIT | MT_16BIT_AY88; + case PIPE_FORMAT_R5G6B5_UNORM: + return MAPSURF_16BIT | MT_16BIT_RGB565; + case PIPE_FORMAT_A1R5G5B5_UNORM: + return MAPSURF_16BIT | MT_16BIT_ARGB1555; + case PIPE_FORMAT_A4R4G4B4_UNORM: + return MAPSURF_16BIT | MT_16BIT_ARGB4444; + case PIPE_FORMAT_A8R8G8B8_UNORM: + return MAPSURF_32BIT | MT_32BIT_ARGB8888; + case PIPE_FORMAT_YCBCR_REV: + return (MAPSURF_422 | MT_422_YCRCB_NORMAL); + case PIPE_FORMAT_YCBCR: + return (MAPSURF_422 | MT_422_YCRCB_SWAPY); +#if 0 + case PIPE_FORMAT_RGB_FXT1: + case PIPE_FORMAT_RGBA_FXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); +#endif + case PIPE_FORMAT_Z16_UNORM: + return (MAPSURF_16BIT | MT_16BIT_L16); +#if 0 + case PIPE_FORMAT_RGBA_DXT1: + case PIPE_FORMAT_RGB_DXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + case PIPE_FORMAT_RGBA_DXT3: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + case PIPE_FORMAT_RGBA_DXT5: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); +#endif + case PIPE_FORMAT_S8Z24_UNORM: + return (MAPSURF_32BIT | MT_32BIT_xL824); + default: + debug_printf("i915: translate_texture_format() bad image format %x\n", + pipeFormat); + assert(0); + return 0; + } +} + + +static void +i915_update_texture(struct i915_context *i915, uint unit, + uint state[6]) +{ + const struct i915_texture *tex = i915->texture[unit]; + const struct pipe_texture *pt = &tex->base; + uint format, pitch; + const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; + const uint num_levels = pt->last_level; + + assert(tex); + assert(width); + assert(height); + assert(depth); + + format = translate_texture_format(pt->format); + pitch = tex->pitch * pt->cpp; + + assert(format); + assert(pitch); + + /* MS3 state */ + state[0] = + (((height - 1) << MS3_HEIGHT_SHIFT) + | ((width - 1) << MS3_WIDTH_SHIFT) + | format + | MS3_USE_FENCE_REGS); + + /* MS4 state */ + state[1] = + ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) + | MS4_CUBE_FACE_ENA_MASK + | ((num_levels * 4) << MS4_MAX_LOD_SHIFT) + | ((depth - 1) << MS4_VOLUME_DEPTH_SHIFT)); +} + + +void +i915_update_textures(struct i915_context *i915) +{ + uint unit; + + for (unit = 0; unit < I915_TEX_UNITS; unit++) { + /* determine unit enable/disable by looking for a bound texture */ + /* could also examine the fragment program? */ + if (i915->texture[unit]) { + i915_update_texture(i915, unit, i915->current.texbuffer[unit]); + } + } + + i915->hardware_dirty |= I915_HW_MAP; +} diff --git a/src/gallium/drivers/i915simple/i915_strings.c b/src/gallium/drivers/i915simple/i915_strings.c new file mode 100644 index 0000000000..c713bf7208 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_strings.c @@ -0,0 +1,83 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "i915_context.h" +#include "i915_reg.h" + + +static const char *i915_get_vendor( struct pipe_context *pipe ) +{ + return "Tungsten Graphics, Inc."; +} + + +static const char *i915_get_name( struct pipe_context *pipe ) +{ + static char buffer[128]; + const char *chipset; + + switch (i915_context(pipe)->pci_id) { + case PCI_CHIP_I915_G: + chipset = "915G"; + break; + case PCI_CHIP_I915_GM: + chipset = "915GM"; + break; + case PCI_CHIP_I945_G: + chipset = "945G"; + break; + case PCI_CHIP_I945_GM: + chipset = "945GM"; + break; + case PCI_CHIP_I945_GME: + chipset = "945GME"; + break; + case PCI_CHIP_G33_G: + chipset = "G33"; + break; + case PCI_CHIP_Q35_G: + chipset = "Q35"; + break; + case PCI_CHIP_Q33_G: + chipset = "Q33"; + break; + default: + chipset = "unknown"; + break; + } + + sprintf(buffer, "pipe/i915 (chipset: %s)", chipset); + return buffer; +} + + +void +i915_init_string_functions(struct i915_context *i915) +{ + i915->pipe.get_name = i915_get_name; + i915->pipe.get_vendor = i915_get_vendor; +} diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c new file mode 100644 index 0000000000..de0cc5fe06 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -0,0 +1,191 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "i915_context.h" +#include "i915_blit.h" +#include "i915_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" +#include "pipe/util/p_tile.h" + + +/* + * XXX note: same as code in sp_surface.c + */ +static struct pipe_surface * +i915_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct i915_texture *tex = (struct i915_texture *)pt; + struct pipe_surface *ps; + unsigned offset; /* in bytes */ + + offset = tex->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE) { + offset += tex->image_offset[level][face] * pt->cpp; + } + else if (pt->target == PIPE_TEXTURE_3D) { + offset += tex->image_offset[level][zslice] * pt->cpp; + } + else { + assert(face == 0); + assert(zslice == 0); + } + + ps = pipe->winsys->surface_alloc(pipe->winsys); + if (ps) { + assert(ps->refcount); + assert(ps->winsys); + pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = tex->pitch; + ps->offset = offset; + } + return ps; +} + + + +/* Assumes all values are within bounds -- no checking at this level - + * do it higher up if required. + */ +static void +i915_surface_copy(struct pipe_context *pipe, + unsigned do_flip, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, unsigned width, unsigned height) +{ + assert( dst != src ); + assert( dst->cpp == src->cpp ); + + if (0) { + pipe_copy_rect(pipe_surface_map(dst), + dst->cpp, + dst->pitch, + dstx, dsty, + width, height, + pipe_surface_map(src), + do_flip ? -(int) src->pitch : src->pitch, + srcx, do_flip ? 1 - srcy - height : srcy); + + pipe_surface_unmap(src); + pipe_surface_unmap(dst); + } + else { + i915_copy_blit( i915_context(pipe), + do_flip, + dst->cpp, + (short) src->pitch, src->buffer, src->offset, + (short) dst->pitch, dst->buffer, dst->offset, + (short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height ); + } +} + +/* Fill a rectangular sub-region. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ +static void * +get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) +{ + return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; +} + + +static void +i915_surface_fill(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, unsigned value) +{ + if (0) { + unsigned i, j; + void *dst_map = pipe_surface_map(dst); + + switch (dst->cpp) { + case 1: { + ubyte *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + memset(row, value, width); + row += dst->pitch; + } + } + break; + case 2: { + ushort *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = (ushort) value; + row += dst->pitch; + } + } + break; + case 4: { + unsigned *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = value; + row += dst->pitch; + } + } + break; + default: + assert(0); + break; + } + + pipe_surface_unmap( dst ); + } + else { + i915_fill_blit( i915_context(pipe), + dst->cpp, + (short) dst->pitch, + dst->buffer, dst->offset, + (short) dstx, (short) dsty, + (short) width, (short) height, + value ); + } +} + + +void +i915_init_surface_functions(struct i915_context *i915) +{ + i915->pipe.get_tex_surface = i915_get_tex_surface; + + i915->pipe.surface_copy = i915_surface_copy; + i915->pipe.surface_fill = i915_surface_fill; +} diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c new file mode 100644 index 0000000000..6d37ae3d74 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -0,0 +1,536 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell + * Michel Dänzer + */ + +#include "pipe/p_state.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" + +#include "i915_context.h" +#include "i915_texture.h" +#include "i915_debug.h" + + +static unsigned minify( unsigned d ) +{ + return MAX2(1, d>>1); +} + + + +static void +i915_miptree_set_level_info(struct i915_texture *tex, + unsigned level, + unsigned nr_images, + unsigned x, unsigned y, unsigned w, unsigned h, unsigned d) +{ + struct pipe_texture *pt = &tex->base; + + assert(level < PIPE_MAX_TEXTURE_LEVELS); + + pt->width[level] = w; + pt->height[level] = h; + pt->depth[level] = d; + + tex->level_offset[level] = (x + y * tex->pitch) * pt->cpp; + tex->nr_images[level] = nr_images; + + /* + DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, + level, w, h, d, x, y, tex->level_offset[level]); + */ + + /* Not sure when this would happen, but anyway: + */ + if (tex->image_offset[level]) { + FREE(tex->image_offset[level]); + tex->image_offset[level] = NULL; + } + + assert(nr_images); + assert(!tex->image_offset[level]); + + tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned)); + tex->image_offset[level][0] = 0; +} + + +static void +i915_miptree_set_image_offset(struct i915_texture *tex, + unsigned level, unsigned img, unsigned x, unsigned y) +{ + if (img == 0 && level == 0) + assert(x == 0 && y == 0); + + assert(img < tex->nr_images[level]); + + tex->image_offset[level][img] = (x + y * tex->pitch); + + /* + DBG("%s level %d img %d pos %d,%d image_offset %x\n", + __FUNCTION__, level, img, x, y, tex->image_offset[level][img]); + */ +} + + +static void +i945_miptree_layout_2d( struct i915_texture *tex ) +{ + struct pipe_texture *pt = &tex->base; + int align_h = 2, align_w = 4; + unsigned level; + unsigned x = 0; + unsigned y = 0; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + + tex->pitch = pt->width[0]; + + /* May need to adjust pitch to accomodate the placement of + * the 2nd mipmap level. This occurs when the alignment + * constraints of mipmap placement push the right edge of the + * 2nd mipmap level out past the width of its parent. + */ + if (pt->last_level > 0) { + unsigned mip1_width = align_int(minify(pt->width[0]), align_w) + + minify(minify(pt->width[0])); + + if (mip1_width > pt->width[0]) + tex->pitch = mip1_width; + } + + /* Pitch must be a whole number of dwords, even though we + * express it in texels. + */ + tex->pitch = align_int(tex->pitch * pt->cpp, 4) / pt->cpp; + tex->total_height = 0; + + for (level = 0; level <= pt->last_level; level++) { + unsigned img_height; + + i915_miptree_set_level_info(tex, level, 1, x, y, width, height, 1); + + if (pt->compressed) + img_height = MAX2(1, height/4); + else + img_height = align_int(height, align_h); + + + /* Because the images are packed better, the final offset + * might not be the maximal one: + */ + tex->total_height = MAX2(tex->total_height, y + img_height); + + /* Layout_below: step right after second mipmap level. + */ + if (level == 1) { + x += align_int(width, align_w); + } + else { + y += img_height; + } + + width = minify(width); + height = minify(height); + } +} + + +static const int initial_offsets[6][2] = { + {0, 0}, + {0, 2}, + {1, 0}, + {1, 2}, + {1, 1}, + {1, 3} +}; + +static const int step_offsets[6][2] = { + {0, 2}, + {0, 2}, + {-1, 2}, + {-1, 2}, + {-1, 1}, + {-1, 1} +}; + + +static boolean +i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) +{ + struct pipe_texture *pt = &tex->base; + unsigned level; + + switch (pt->target) { + case PIPE_TEXTURE_CUBE: { + const unsigned dim = pt->width[0]; + unsigned face; + unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; + + assert(lvlWidth == lvlHeight); /* cubemap images are square */ + + /* double pitch for cube layouts */ + tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; + tex->total_height = dim * 4; + + for (level = 0; level <= pt->last_level; level++) { + i915_miptree_set_level_info(tex, level, 6, + 0, 0, + /*OLD: tex->pitch, tex->total_height,*/ + lvlWidth, lvlHeight, + 1); + lvlWidth /= 2; + lvlHeight /= 2; + } + + for (face = 0; face < 6; face++) { + unsigned x = initial_offsets[face][0] * dim; + unsigned y = initial_offsets[face][1] * dim; + unsigned d = dim; + + for (level = 0; level <= pt->last_level; level++) { + i915_miptree_set_image_offset(tex, level, face, x, y); + d >>= 1; + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + } + } + break; + } + case PIPE_TEXTURE_3D:{ + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; + unsigned stack_height = 0; + + /* Calculate the size of a single slice. + */ + tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; + + /* XXX: hardware expects/requires 9 levels at minimum. + */ + for (level = 0; level <= MAX2(8, pt->last_level); + level++) { + i915_miptree_set_level_info(tex, level, depth, 0, tex->total_height, + width, height, depth); + + + stack_height += MAX2(2, height); + + width = minify(width); + height = minify(height); + depth = minify(depth); + } + + /* Fixup depth image_offsets: + */ + depth = pt->depth[0]; + for (level = 0; level <= pt->last_level; level++) { + unsigned i; + for (i = 0; i < depth; i++) + i915_miptree_set_image_offset(tex, level, i, + 0, i * stack_height); + + depth = minify(depth); + } + + + /* Multiply slice size by texture depth for total size. It's + * remarkable how wasteful of memory the i915 texture layouts + * are. They are largely fixed in the i945. + */ + tex->total_height = stack_height * pt->depth[0]; + break; + } + + default:{ + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned img_height; + + tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; + tex->total_height = 0; + + for (level = 0; level <= pt->last_level; level++) { + i915_miptree_set_level_info(tex, level, 1, + 0, tex->total_height, + width, height, 1); + + if (pt->compressed) + img_height = MAX2(1, height / 4); + else + img_height = (MAX2(2, height) + 1) & ~1; + + tex->total_height += img_height; + + width = minify(width); + height = minify(height); + } + break; + } + } + /* + DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, + tex->pitch, + tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp); + */ + + return TRUE; +} + + +static boolean +i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) +{ + struct pipe_texture *pt = &tex->base; + unsigned level; + + switch (pt->target) { + case PIPE_TEXTURE_CUBE:{ + const unsigned dim = pt->width[0]; + unsigned face; + unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; + + assert(lvlWidth == lvlHeight); /* cubemap images are square */ + + /* Depending on the size of the largest images, pitch can be + * determined either by the old-style packing of cubemap faces, + * or the final row of 4x4, 2x2 and 1x1 faces below this. + */ + if (dim > 32) + tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; + else + tex->pitch = 14 * 8; + + tex->total_height = dim * 4 + 4; + + /* Set all the levels to effectively occupy the whole rectangular region. + */ + for (level = 0; level <= pt->last_level; level++) { + i915_miptree_set_level_info(tex, level, 6, + 0, 0, + lvlWidth, lvlHeight, 1); + lvlWidth /= 2; + lvlHeight /= 2; + } + + + for (face = 0; face < 6; face++) { + unsigned x = initial_offsets[face][0] * dim; + unsigned y = initial_offsets[face][1] * dim; + unsigned d = dim; + + if (dim == 4 && face >= 4) { + y = tex->total_height - 4; + x = (face - 4) * 8; + } + else if (dim < 4 && (face > 0)) { + y = tex->total_height - 4; + x = face * 8; + } + + for (level = 0; level <= pt->last_level; level++) { + i915_miptree_set_image_offset(tex, level, face, x, y); + + d >>= 1; + + switch (d) { + case 4: + switch (face) { + case PIPE_TEX_FACE_POS_X: + case PIPE_TEX_FACE_NEG_X: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + case PIPE_TEX_FACE_POS_Y: + case PIPE_TEX_FACE_NEG_Y: + y += 12; + x -= 8; + break; + case PIPE_TEX_FACE_POS_Z: + case PIPE_TEX_FACE_NEG_Z: + y = tex->total_height - 4; + x = (face - 4) * 8; + break; + } + + case 2: + y = tex->total_height - 4; + x = 16 + face * 8; + break; + + case 1: + x += 48; + break; + + default: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + } + } + } + break; + } + case PIPE_TEXTURE_3D:{ + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; + unsigned pack_x_pitch, pack_x_nr; + unsigned pack_y_pitch; + unsigned level; + + tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; + tex->total_height = 0; + + pack_y_pitch = MAX2(pt->height[0], 2); + pack_x_pitch = tex->pitch; + pack_x_nr = 1; + + for (level = 0; level <= pt->last_level; level++) { + unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6; + int x = 0; + int y = 0; + unsigned q, j; + + i915_miptree_set_level_info(tex, level, nr_images, + 0, tex->total_height, + width, height, depth); + + for (q = 0; q < nr_images;) { + for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { + i915_miptree_set_image_offset(tex, level, q, x, y); + x += pack_x_pitch; + } + + x = 0; + y += pack_y_pitch; + } + + + tex->total_height += y; + + if (pack_x_pitch > 4) { + pack_x_pitch >>= 1; + pack_x_nr <<= 1; + assert(pack_x_pitch * pack_x_nr <= tex->pitch); + } + + if (pack_y_pitch > 2) { + pack_y_pitch >>= 1; + } + + width = minify(width); + height = minify(height); + depth = minify(depth); + } + break; + } + + case PIPE_TEXTURE_1D: + case PIPE_TEXTURE_2D: +// case PIPE_TEXTURE_RECTANGLE: + i945_miptree_layout_2d(tex); + break; + default: + assert(0); + return FALSE; + } + + /* + DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, + tex->pitch, + tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp); + */ + + return TRUE; +} + + +struct pipe_texture * +i915_texture_create(struct pipe_context *pipe, + const struct pipe_texture *templat) +{ + struct i915_texture *tex = CALLOC_STRUCT(i915_texture); + + if (tex) { + struct i915_context *i915 = i915_context(pipe); + + tex->base = *templat; + + if (i915->flags.is_i945 ? i945_miptree_layout(pipe, tex) : + i915_miptree_layout(pipe, tex)) + tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64, + PIPE_BUFFER_USAGE_PIXEL, + tex->pitch * tex->base.cpp * + tex->total_height); + + if (!tex->buffer) { + FREE(tex); + return NULL; + } + } + + return &tex->base; +} + + +void +i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + if (!*pt) + return; + + /* + DBG("%s %p refcount will be %d\n", + __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); + */ + if (--(*pt)->refcount <= 0) { + struct i915_texture *tex = (struct i915_texture *)*pt; + uint i; + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); + */ + + pipe_buffer_reference(pipe->winsys, &tex->buffer, NULL); + + for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++) + if (tex->image_offset[i]) + FREE(tex->image_offset[i]); + + FREE(tex); + } + *pt = NULL; +} diff --git a/src/gallium/drivers/i915simple/i915_texture.h b/src/gallium/drivers/i915simple/i915_texture.h new file mode 100644 index 0000000000..330d111dc7 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_texture.h @@ -0,0 +1,17 @@ + +#ifndef I915_TEXTURE_H +#define I915_TEXTURE_H + +struct pipe_context; +struct pipe_texture; + + +struct pipe_texture * +i915_texture_create(struct pipe_context *pipe, + const struct pipe_texture *templat); + +extern void +i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); + + +#endif /* I915_TEXTURE_H */ diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h new file mode 100644 index 0000000000..fe49710852 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_winsys.h @@ -0,0 +1,115 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * This is the interface that i915simple requires any window system + * hosting it to implement. This is the only include file in i915simple + * which is public. + * + */ + +#ifndef I915_WINSYS_H +#define I915_WINSYS_H + + +#include "pipe/p_defines.h" + + +/* Pipe drivers are (meant to be!) independent of both GL and the + * window system. The window system provides a buffer manager and a + * set of additional hooks for things like command buffer submission, + * etc. + * + * There clearly has to be some agreement between the window system + * driver and the hardware driver about the format of command buffers, + * etc. + */ + +struct pipe_buffer; +struct pipe_winsys; + + +/** + * Additional winsys interface for i915simple. + * + * It is an over-simple batchbuffer mechanism. Will want to improve the + * performance of this, perhaps based on the cmdstream stuff. It + * would be pretty impossible to implement swz on top of this + * interface. + * + * Will also need additions/changes to implement static/dynamic + * indirect state. + */ +struct i915_winsys { + + /** + * Reserve space on batch buffer. + * + * Returns a null pointer if there is insufficient space in the batch buffer + * to hold the requested number of dwords and relocations. + * + * The number of dwords should also include the number of relocations. + */ + unsigned *(*batch_start)( struct i915_winsys *sws, + unsigned dwords, + unsigned relocs ); + + void (*batch_dword)( struct i915_winsys *sws, + unsigned dword ); + + /** + * Emit a relocation to a buffer. + * + * Used not only when the buffer addresses are not pinned, but also to + * ensure refered buffers will not be destroyed until the current batch + * buffer execution is finished. + * + * The access flags is a combination of I915_BUFFER_ACCESS_WRITE and + * I915_BUFFER_ACCESS_READ macros. + */ + void (*batch_reloc)( struct i915_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta ); + + void (*batch_flush)( struct i915_winsys *sws ); + void (*batch_finish)( struct i915_winsys *sws ); +}; + +#define I915_BUFFER_ACCESS_WRITE 0x1 +#define I915_BUFFER_ACCESS_READ 0x2 + +#define I915_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0) + + +struct pipe_context *i915_create( struct pipe_winsys *, + struct i915_winsys *, + unsigned pci_id ); + + +#endif diff --git a/src/gallium/drivers/i965simple/Makefile b/src/gallium/drivers/i965simple/Makefile new file mode 100644 index 0000000000..48c00ab50b --- /dev/null +++ b/src/gallium/drivers/i965simple/Makefile @@ -0,0 +1,66 @@ + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = i965simple + +DRIVER_SOURCES = \ + brw_blit.c \ + brw_flush.c \ + brw_strings.c \ + brw_surface.c \ + brw_cc.c \ + brw_clip.c \ + brw_clip_line.c \ + brw_clip_point.c \ + brw_clip_state.c \ + brw_clip_tri.c \ + brw_clip_util.c \ + brw_context.c \ + brw_curbe.c \ + brw_draw.c \ + brw_draw_upload.c \ + brw_eu.c \ + brw_eu_debug.c \ + brw_eu_emit.c \ + brw_eu_util.c \ + brw_gs.c \ + brw_gs_emit.c \ + brw_gs_state.c \ + brw_misc_state.c \ + brw_sf.c \ + brw_sf_emit.c \ + brw_sf_state.c \ + brw_shader_info.c \ + brw_state.c \ + brw_state_batch.c \ + brw_state_cache.c \ + brw_state_pool.c \ + brw_state_upload.c \ + brw_tex_layout.c \ + brw_urb.c \ + brw_util.c \ + brw_vs.c \ + brw_vs_emit.c \ + brw_vs_state.c \ + brw_wm.c \ + brw_wm_iz.c \ + brw_wm_decl.c \ + brw_wm_glsl.c \ + brw_wm_sampler_state.c \ + brw_wm_state.c \ + brw_wm_surface_state.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(COMMON_BM_SOURCES) \ + $(MINIGLX_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I. + +include ../Makefile.template + +symlinks: diff --git a/src/gallium/drivers/i965simple/SConscript b/src/gallium/drivers/i965simple/SConscript new file mode 100644 index 0000000000..74621de84c --- /dev/null +++ b/src/gallium/drivers/i965simple/SConscript @@ -0,0 +1,55 @@ +Import('*') + +env = env.Clone() + +i965simple = env.ConvenienceLibrary( + target = 'i965simple', + source = [ + 'brw_blit.c', + 'brw_cc.c', + 'brw_clip.c', + 'brw_clip_line.c', + 'brw_clip_point.c', + 'brw_clip_state.c', + 'brw_clip_tri.c', + 'brw_clip_util.c', + 'brw_context.c', + 'brw_curbe.c', + 'brw_draw.c', + 'brw_draw_upload.c', + 'brw_eu.c', + 'brw_eu_debug.c', + 'brw_eu_emit.c', + 'brw_eu_util.c', + 'brw_flush.c', + 'brw_gs.c', + 'brw_gs_emit.c', + 'brw_gs_state.c', + 'brw_misc_state.c', + 'brw_sf.c', + 'brw_sf_emit.c', + 'brw_sf_state.c', + 'brw_shader_info.c', + 'brw_state.c', + 'brw_state_batch.c', + 'brw_state_cache.c', + 'brw_state_pool.c', + 'brw_state_upload.c', + 'brw_strings.c', + 'brw_surface.c', + 'brw_tex_layout.c', + 'brw_urb.c', + 'brw_util.c', + 'brw_vs.c', + 'brw_vs_emit.c', + 'brw_vs_state.c', + 'brw_wm.c', + 'brw_wm_decl.c', + 'brw_wm_glsl.c', + 'brw_wm_iz.c', + 'brw_wm_sampler_state.c', + 'brw_wm_state.c', + 'brw_wm_surface_state.c', + ]) + +Export('i965simple') diff --git a/src/gallium/drivers/i965simple/brw_batch.h b/src/gallium/drivers/i965simple/brw_batch.h new file mode 100644 index 0000000000..5f5932a488 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_batch.h @@ -0,0 +1,59 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef BRW_BATCH_H +#define BRW_BATCH_H + +#include "brw_winsys.h" + +#define BATCH_LOCALS + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +#define BEGIN_BATCH( dwords, relocs ) \ + brw->winsys->batch_start(brw->winsys, dwords, relocs) + +#define OUT_BATCH( dword ) \ + brw->winsys->batch_dword(brw->winsys, dword) + +#define OUT_RELOC( buf, flags, delta ) \ + brw->winsys->batch_reloc(brw->winsys, buf, flags, delta) + +#define ADVANCE_BATCH() \ + brw->winsys->batch_end( brw->winsys ) + +/* XXX: this is bogus - need proper handling for out-of-memory in batchbuffer. + */ +#define FLUSH_BATCH(fence) do { \ + brw->winsys->batch_flush(brw->winsys, fence); \ + brw->hardware_dirty = ~0; \ +} while (0) + +#define BRW_BATCH_STRUCT(brw, s) brw_batchbuffer_data( brw->winsys, (s), sizeof(*(s))) + +#endif diff --git a/src/gallium/drivers/i965simple/brw_blit.c b/src/gallium/drivers/i965simple/brw_blit.c new file mode 100644 index 0000000000..8494f70493 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_blit.c @@ -0,0 +1,218 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include +#include + +#include "brw_batch.h" +#include "brw_blit.h" +#include "brw_context.h" +#include "brw_reg.h" + +#include "pipe/p_context.h" +#include "pipe/p_winsys.h" + +#define FILE_DEBUG_FLAG DEBUG_BLIT + +void brw_fill_blit(struct brw_context *brw, + unsigned cpp, + short dst_pitch, + struct pipe_buffer *dst_buffer, + unsigned dst_offset, + boolean dst_tiled, + short x, short y, + short w, short h, + unsigned color) +{ + unsigned BR13, CMD; + BATCH_LOCALS; + + dst_pitch *= cpp; + + switch(cpp) { + case 1: + case 2: + case 3: + BR13 = (0xF0 << 16) | (1<<24); + CMD = XY_COLOR_BLT_CMD; + break; + case 4: + BR13 = (0xF0 << 16) | (1<<24) | (1<<25); + CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; + break; + default: + return; + } + + if (dst_tiled) { + CMD |= XY_DST_TILED; + dst_pitch /= 4; + } + + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH( CMD ); + OUT_BATCH( dst_pitch | BR13 ); + OUT_BATCH( (y << 16) | x ); + OUT_BATCH( ((y+h) << 16) | (x+w) ); + OUT_RELOC( dst_buffer, BRW_BUFFER_ACCESS_WRITE, dst_offset ); + OUT_BATCH( color ); + ADVANCE_BATCH(); +} + +static unsigned translate_raster_op(unsigned logicop) +{ + switch(logicop) { + case PIPE_LOGICOP_CLEAR: return 0x00; + case PIPE_LOGICOP_AND: return 0x88; + case PIPE_LOGICOP_AND_REVERSE: return 0x44; + case PIPE_LOGICOP_COPY: return 0xCC; + case PIPE_LOGICOP_AND_INVERTED: return 0x22; + case PIPE_LOGICOP_NOOP: return 0xAA; + case PIPE_LOGICOP_XOR: return 0x66; + case PIPE_LOGICOP_OR: return 0xEE; + case PIPE_LOGICOP_NOR: return 0x11; + case PIPE_LOGICOP_EQUIV: return 0x99; + case PIPE_LOGICOP_INVERT: return 0x55; + case PIPE_LOGICOP_OR_REVERSE: return 0xDD; + case PIPE_LOGICOP_COPY_INVERTED: return 0x33; + case PIPE_LOGICOP_OR_INVERTED: return 0xBB; + case PIPE_LOGICOP_NAND: return 0x77; + case PIPE_LOGICOP_SET: return 0xFF; + default: return 0; + } +} + + +/* Copy BitBlt + */ +void brw_copy_blit(struct brw_context *brw, + unsigned do_flip, + unsigned cpp, + short src_pitch, + struct pipe_buffer *src_buffer, + unsigned src_offset, + boolean src_tiled, + short dst_pitch, + struct pipe_buffer *dst_buffer, + unsigned dst_offset, + boolean dst_tiled, + short src_x, short src_y, + short dst_x, short dst_y, + short w, short h, + unsigned logic_op) +{ + unsigned CMD, BR13; + int dst_y2 = dst_y + h; + int dst_x2 = dst_x + w; + BATCH_LOCALS; + + + DBG("%s src:buf(%d)/%d %d,%d dst:buf(%d)/%d %d,%d sz:%dx%d op:%d\n", + __FUNCTION__, + src_buffer, src_pitch, src_x, src_y, + dst_buffer, dst_pitch, dst_x, dst_y, + w,h,logic_op); + + assert( logic_op - PIPE_LOGICOP_CLEAR >= 0 ); + assert( logic_op - PIPE_LOGICOP_CLEAR < 0x10 ); + + src_pitch *= cpp; + dst_pitch *= cpp; + + switch(cpp) { + case 1: + case 2: + case 3: + BR13 = (translate_raster_op(logic_op) << 16) | (1<<24); + CMD = XY_SRC_COPY_BLT_CMD; + break; + case 4: + BR13 = (translate_raster_op(logic_op) << 16) | (1<<24) | + (1<<25); + CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB; + break; + default: + return; + } + + if (src_tiled) { + CMD |= XY_SRC_TILED; + src_pitch /= 4; + } + + if (dst_tiled) { + CMD |= XY_DST_TILED; + dst_pitch /= 4; + } + + if (dst_y2 < dst_y || + dst_x2 < dst_x) { + return; + } + + dst_pitch &= 0xffff; + src_pitch &= 0xffff; + + /* Initial y values don't seem to work with negative pitches. If + * we adjust the offsets manually (below), it seems to work fine. + * + * On the other hand, if we always adjust, the hardware doesn't + * know which blit directions to use, so overlapping copypixels get + * the wrong result. + */ + if (dst_pitch > 0 && src_pitch > 0) { + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH( CMD ); + OUT_BATCH( dst_pitch | BR13 ); + OUT_BATCH( (dst_y << 16) | dst_x ); + OUT_BATCH( (dst_y2 << 16) | dst_x2 ); + OUT_RELOC( dst_buffer, BRW_BUFFER_ACCESS_WRITE, + dst_offset ); + OUT_BATCH( (src_y << 16) | src_x ); + OUT_BATCH( src_pitch ); + OUT_RELOC( src_buffer, BRW_BUFFER_ACCESS_READ, + src_offset ); + ADVANCE_BATCH(); + } + else { + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH( CMD ); + OUT_BATCH( (dst_pitch & 0xffff) | BR13 ); + OUT_BATCH( (0 << 16) | dst_x ); + OUT_BATCH( (h << 16) | dst_x2 ); + OUT_RELOC( dst_buffer, BRW_BUFFER_ACCESS_WRITE, + dst_offset + dst_y * dst_pitch ); + OUT_BATCH( (src_pitch & 0xffff) ); + OUT_RELOC( src_buffer, BRW_BUFFER_ACCESS_READ, + src_offset + src_y * src_pitch ); + ADVANCE_BATCH(); + } +} + + + diff --git a/src/gallium/drivers/i965simple/brw_blit.h b/src/gallium/drivers/i965simple/brw_blit.h new file mode 100644 index 0000000000..111c5d91d3 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_blit.h @@ -0,0 +1,33 @@ +#ifndef BRW_BLIT_H +#define BRW_BLIT_H + +#include "pipe/p_compiler.h" + +struct pipe_buffer; +struct brw_context; + +void brw_fill_blit(struct brw_context *intel, + unsigned cpp, + short dst_pitch, + struct pipe_buffer *dst_buffer, + unsigned dst_offset, + boolean dst_tiled, + short x, short y, + short w, short h, + unsigned color); +void brw_copy_blit(struct brw_context *intel, + unsigned do_flip, + unsigned cpp, + short src_pitch, + struct pipe_buffer *src_buffer, + unsigned src_offset, + boolean src_tiled, + short dst_pitch, + struct pipe_buffer *dst_buffer, + unsigned dst_offset, + boolean dst_tiled, + short src_x, short src_y, + short dst_x, short dst_y, + short w, short h, + unsigned logic_op); +#endif diff --git a/src/gallium/drivers/i965simple/brw_cc.c b/src/gallium/drivers/i965simple/brw_cc.c new file mode 100644 index 0000000000..337e4f95f6 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_cc.c @@ -0,0 +1,269 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" + +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" +#include "brw_util.h" + + +static int brw_translate_compare_func(int func) +{ + switch(func) { + case PIPE_FUNC_NEVER: + return BRW_COMPAREFUNCTION_NEVER; + case PIPE_FUNC_LESS: + return BRW_COMPAREFUNCTION_LESS; + case PIPE_FUNC_LEQUAL: + return BRW_COMPAREFUNCTION_LEQUAL; + case PIPE_FUNC_GREATER: + return BRW_COMPAREFUNCTION_GREATER; + case PIPE_FUNC_GEQUAL: + return BRW_COMPAREFUNCTION_GEQUAL; + case PIPE_FUNC_NOTEQUAL: + return BRW_COMPAREFUNCTION_NOTEQUAL; + case PIPE_FUNC_EQUAL: + return BRW_COMPAREFUNCTION_EQUAL; + case PIPE_FUNC_ALWAYS: + return BRW_COMPAREFUNCTION_ALWAYS; + } + + debug_printf("Unknown value in %s: %x\n", __FUNCTION__, func); + return BRW_COMPAREFUNCTION_ALWAYS; +} + +static int brw_translate_stencil_op(int op) +{ + switch(op) { + case PIPE_STENCIL_OP_KEEP: + return BRW_STENCILOP_KEEP; + case PIPE_STENCIL_OP_ZERO: + return BRW_STENCILOP_ZERO; + case PIPE_STENCIL_OP_REPLACE: + return BRW_STENCILOP_REPLACE; + case PIPE_STENCIL_OP_INCR: + return BRW_STENCILOP_INCRSAT; + case PIPE_STENCIL_OP_DECR: + return BRW_STENCILOP_DECRSAT; + case PIPE_STENCIL_OP_INCR_WRAP: + return BRW_STENCILOP_INCR; + case PIPE_STENCIL_OP_DECR_WRAP: + return BRW_STENCILOP_DECR; + case PIPE_STENCIL_OP_INVERT: + return BRW_STENCILOP_INVERT; + default: + return BRW_STENCILOP_ZERO; + } +} + + +static int brw_translate_logic_op(int opcode) +{ + switch(opcode) { + case PIPE_LOGICOP_CLEAR: + return BRW_LOGICOPFUNCTION_CLEAR; + case PIPE_LOGICOP_AND: + return BRW_LOGICOPFUNCTION_AND; + case PIPE_LOGICOP_AND_REVERSE: + return BRW_LOGICOPFUNCTION_AND_REVERSE; + case PIPE_LOGICOP_COPY: + return BRW_LOGICOPFUNCTION_COPY; + case PIPE_LOGICOP_COPY_INVERTED: + return BRW_LOGICOPFUNCTION_COPY_INVERTED; + case PIPE_LOGICOP_AND_INVERTED: + return BRW_LOGICOPFUNCTION_AND_INVERTED; + case PIPE_LOGICOP_NOOP: + return BRW_LOGICOPFUNCTION_NOOP; + case PIPE_LOGICOP_XOR: + return BRW_LOGICOPFUNCTION_XOR; + case PIPE_LOGICOP_OR: + return BRW_LOGICOPFUNCTION_OR; + case PIPE_LOGICOP_OR_INVERTED: + return BRW_LOGICOPFUNCTION_OR_INVERTED; + case PIPE_LOGICOP_NOR: + return BRW_LOGICOPFUNCTION_NOR; + case PIPE_LOGICOP_EQUIV: + return BRW_LOGICOPFUNCTION_EQUIV; + case PIPE_LOGICOP_INVERT: + return BRW_LOGICOPFUNCTION_INVERT; + case PIPE_LOGICOP_OR_REVERSE: + return BRW_LOGICOPFUNCTION_OR_REVERSE; + case PIPE_LOGICOP_NAND: + return BRW_LOGICOPFUNCTION_NAND; + case PIPE_LOGICOP_SET: + return BRW_LOGICOPFUNCTION_SET; + default: + return BRW_LOGICOPFUNCTION_SET; + } +} + + +static void upload_cc_vp( struct brw_context *brw ) +{ + struct brw_cc_viewport ccv; + + memset(&ccv, 0, sizeof(ccv)); + + ccv.min_depth = 0.0; + ccv.max_depth = 1.0; + + brw->cc.vp_gs_offset = brw_cache_data( &brw->cache[BRW_CC_VP], &ccv ); +} + +const struct brw_tracked_state brw_cc_vp = { + .dirty = { + .brw = BRW_NEW_SCENE, + .cache = 0 + }, + .update = upload_cc_vp +}; + + +static void upload_cc_unit( struct brw_context *brw ) +{ + struct brw_cc_unit_state cc; + + memset(&cc, 0, sizeof(cc)); + + /* BRW_NEW_DEPTH_STENCIL */ + if (brw->attribs.DepthStencil->stencil[0].enabled) { + cc.cc0.stencil_enable = brw->attribs.DepthStencil->stencil[0].enabled; + cc.cc0.stencil_func = brw_translate_compare_func(brw->attribs.DepthStencil->stencil[0].func); + cc.cc0.stencil_fail_op = brw_translate_stencil_op(brw->attribs.DepthStencil->stencil[0].fail_op); + cc.cc0.stencil_pass_depth_fail_op = brw_translate_stencil_op( + brw->attribs.DepthStencil->stencil[0].zfail_op); + cc.cc0.stencil_pass_depth_pass_op = brw_translate_stencil_op( + brw->attribs.DepthStencil->stencil[0].zpass_op); + cc.cc1.stencil_ref = brw->attribs.DepthStencil->stencil[0].ref_value; + cc.cc1.stencil_write_mask = brw->attribs.DepthStencil->stencil[0].write_mask; + cc.cc1.stencil_test_mask = brw->attribs.DepthStencil->stencil[0].value_mask; + + if (brw->attribs.DepthStencil->stencil[1].enabled) { + cc.cc0.bf_stencil_enable = brw->attribs.DepthStencil->stencil[1].enabled; + cc.cc0.bf_stencil_func = brw_translate_compare_func( + brw->attribs.DepthStencil->stencil[1].func); + cc.cc0.bf_stencil_fail_op = brw_translate_stencil_op( + brw->attribs.DepthStencil->stencil[1].fail_op); + cc.cc0.bf_stencil_pass_depth_fail_op = brw_translate_stencil_op( + brw->attribs.DepthStencil->stencil[1].zfail_op); + cc.cc0.bf_stencil_pass_depth_pass_op = brw_translate_stencil_op( + brw->attribs.DepthStencil->stencil[1].zpass_op); + cc.cc1.bf_stencil_ref = brw->attribs.DepthStencil->stencil[1].ref_value; + cc.cc2.bf_stencil_write_mask = brw->attribs.DepthStencil->stencil[1].write_mask; + cc.cc2.bf_stencil_test_mask = brw->attribs.DepthStencil->stencil[1].value_mask; + } + + /* Not really sure about this: + */ + if (brw->attribs.DepthStencil->stencil[0].write_mask || + brw->attribs.DepthStencil->stencil[1].write_mask) + cc.cc0.stencil_write_enable = 1; + } + + /* BRW_NEW_BLEND */ + if (brw->attribs.Blend->logicop_enable) { + cc.cc2.logicop_enable = 1; + cc.cc5.logicop_func = brw_translate_logic_op( brw->attribs.Blend->logicop_func ); + } + else if (brw->attribs.Blend->blend_enable) { + int eqRGB = brw->attribs.Blend->rgb_func; + int eqA = brw->attribs.Blend->alpha_func; + int srcRGB = brw->attribs.Blend->rgb_src_factor; + int dstRGB = brw->attribs.Blend->rgb_dst_factor; + int srcA = brw->attribs.Blend->alpha_src_factor; + int dstA = brw->attribs.Blend->alpha_dst_factor; + + if (eqRGB == PIPE_BLEND_MIN || eqRGB == PIPE_BLEND_MAX) { + srcRGB = dstRGB = PIPE_BLENDFACTOR_ONE; + } + + if (eqA == PIPE_BLEND_MIN || eqA == PIPE_BLEND_MAX) { + srcA = dstA = PIPE_BLENDFACTOR_ONE; + } + + cc.cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB); + cc.cc6.src_blend_factor = brw_translate_blend_factor(srcRGB); + cc.cc6.blend_function = brw_translate_blend_equation( eqRGB ); + + cc.cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA); + cc.cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA); + cc.cc5.ia_blend_function = brw_translate_blend_equation( eqA ); + + cc.cc3.blend_enable = 1; + cc.cc3.ia_blend_enable = (srcA != srcRGB || + dstA != dstRGB || + eqA != eqRGB); + } + + /* BRW_NEW_ALPHATEST + */ + if (brw->attribs.DepthStencil->alpha.enabled) { + cc.cc3.alpha_test = 1; + cc.cc3.alpha_test_func = + brw_translate_compare_func(brw->attribs.DepthStencil->alpha.func); + + UNCLAMPED_FLOAT_TO_UBYTE(cc.cc7.alpha_ref.ub[0], + brw->attribs.DepthStencil->alpha.ref); + + cc.cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8; + } + + if (brw->attribs.Blend->dither) { + cc.cc5.dither_enable = 1; + cc.cc6.y_dither_offset = 0; + cc.cc6.x_dither_offset = 0; + } + + if (brw->attribs.DepthStencil->depth.enabled) { + cc.cc2.depth_test = brw->attribs.DepthStencil->depth.enabled; + cc.cc2.depth_test_function = brw_translate_compare_func(brw->attribs.DepthStencil->depth.func); + cc.cc2.depth_write_enable = brw->attribs.DepthStencil->depth.writemask; + } + + /* CACHE_NEW_CC_VP */ + cc.cc4.cc_viewport_state_offset = brw->cc.vp_gs_offset >> 5; + + if (BRW_DEBUG & DEBUG_STATS) + cc.cc5.statistics_enable = 1; + + brw->cc.state_gs_offset = brw_cache_data( &brw->cache[BRW_CC_UNIT], &cc ); +} + +const struct brw_tracked_state brw_cc_unit = { + .dirty = { + .brw = BRW_NEW_DEPTH_STENCIL | BRW_NEW_BLEND | BRW_NEW_ALPHA_TEST, + .cache = CACHE_NEW_CC_VP + }, + .update = upload_cc_unit +}; + diff --git a/src/gallium/drivers/i965simple/brw_clip.c b/src/gallium/drivers/i965simple/brw_clip.c new file mode 100644 index 0000000000..268124cc53 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_clip.c @@ -0,0 +1,206 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_util.h" +#include "brw_state.h" +#include "brw_clip.h" + +#define FRONT_UNFILLED_BIT 0x1 +#define BACK_UNFILLED_BIT 0x2 + + +static void compile_clip_prog( struct brw_context *brw, + struct brw_clip_prog_key *key ) +{ + struct brw_clip_compile c; + const unsigned *program; + unsigned program_size; + unsigned delta; + unsigned i; + + memset(&c, 0, sizeof(c)); + + /* Begin the compilation: + */ + brw_init_compile(&c.func); + + c.func.single_program_flow = 1; + + c.key = *key; + + + /* Need to locate the two positions present in vertex + header. + * These are currently hardcoded: + */ + c.header_position_offset = ATTR_SIZE; + + for (i = 0, delta = REG_SIZE; i < PIPE_MAX_SHADER_OUTPUTS; i++) + if (c.key.attrs & (1<primitive) { + case PIPE_PRIM_TRIANGLES: +#if 0 + if (key->do_unfilled) + brw_emit_unfilled_clip( &c ); + else +#endif + brw_emit_tri_clip( &c ); + break; + case PIPE_PRIM_LINES: + brw_emit_line_clip( &c ); + break; + case PIPE_PRIM_POINTS: + brw_emit_point_clip( &c ); + break; + default: + assert(0); + return; + } + + + + /* get the program + */ + program = brw_get_program(&c.func, &program_size); + + /* Upload + */ + brw->clip.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_CLIP_PROG], + &c.key, + sizeof(c.key), + program, + program_size, + &c.prog_data, + &brw->clip.prog_data ); +} + + +static boolean search_cache( struct brw_context *brw, + struct brw_clip_prog_key *key ) +{ + return brw_search_cache(&brw->cache[BRW_CLIP_PROG], + key, sizeof(*key), + &brw->clip.prog_data, + &brw->clip.prog_gs_offset); +} + + + + +/* Calculate interpolants for triangle and line rasterization. + */ +static void upload_clip_prog(struct brw_context *brw) +{ + struct brw_clip_prog_key key; + + memset(&key, 0, sizeof(key)); + + /* Populate the key: + */ + /* BRW_NEW_REDUCED_PRIMITIVE */ + key.primitive = brw->reduced_primitive; + /* CACHE_NEW_VS_PROG */ + key.attrs = brw->vs.prog_data->outputs_written; + /* BRW_NEW_RASTER */ + key.do_flat_shading = (brw->attribs.Raster->flatshade); + /* BRW_NEW_CLIP */ + key.nr_userclip = brw->attribs.Clip.nr; /* XXX */ + +#if 0 + key.clip_mode = BRW_CLIPMODE_NORMAL; + + if (key.primitive == PIPE_PRIM_TRIANGLES) { + if (brw->attribs.Raster->cull_mode == PIPE_WINDING_BOTH) + key.clip_mode = BRW_CLIPMODE_REJECT_ALL; + else { + if (brw->attribs.Raster->fill_cw != PIPE_POLYGON_MODE_FILL || + brw->attribs.Raster->fill_ccw != PIPE_POLYGON_MODE_FILL) + key.do_unfilled = 1; + + /* Most cases the fixed function units will handle. Cases where + * one or more polygon faces are unfilled will require help: + */ + if (key.do_unfilled) { + key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED; + + if (brw->attribs.Raster->offset_cw || + brw->attribs.Raster->offset_ccw) { + key.offset_units = brw->attribs.Raster->offset_units; + key.offset_factor = brw->attribs.Raster->offset_scale; + } + key.fill_ccw = brw->attribs.Raster->fill_ccw; + key.fill_cw = brw->attribs.Raster->fill_cw; + key.offset_ccw = brw->attribs.Raster->offset_ccw; + key.offset_cw = brw->attribs.Raster->offset_cw; + if (brw->attribs.Raster->light_twoside && + key.fill_cw != CLIP_CULL) + key.copy_bfc_cw = 1; + } + } + } +#else + key.clip_mode = BRW_CLIPMODE_ACCEPT_ALL; +#endif + + if (!search_cache(brw, &key)) + compile_clip_prog( brw, &key ); +} + +const struct brw_tracked_state brw_clip_prog = { + .dirty = { + .brw = (BRW_NEW_RASTERIZER | + BRW_NEW_CLIP | + BRW_NEW_REDUCED_PRIMITIVE), + .cache = CACHE_NEW_VS_PROG + }, + .update = upload_clip_prog +}; diff --git a/src/gallium/drivers/i965simple/brw_clip.h b/src/gallium/drivers/i965simple/brw_clip.h new file mode 100644 index 0000000000..a89d08b791 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_clip.h @@ -0,0 +1,170 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#ifndef BRW_CLIP_H +#define BRW_CLIP_H + + +#include "brw_context.h" +#include "brw_eu.h" + +#define MAX_VERTS (3+6+6) + +/* Note that if unfilled primitives are being emitted, we have to fix + * up polygon offset and flatshading at this point: + */ +struct brw_clip_prog_key { + unsigned attrs:32; + unsigned primitive:4; + unsigned nr_userclip:3; + unsigned do_flat_shading:1; + unsigned do_unfilled:1; + unsigned fill_cw:2; /* includes cull information */ + unsigned fill_ccw:2; /* includes cull information */ + unsigned offset_cw:1; + unsigned offset_ccw:1; + unsigned pad0:17; + + unsigned copy_bfc_cw:1; + unsigned copy_bfc_ccw:1; + unsigned clip_mode:3; + unsigned pad1:27; + + float offset_factor; + float offset_units; +}; + + +#define CLIP_LINE 0 +#define CLIP_POINT 1 +#define CLIP_FILL 2 +#define CLIP_CULL 3 + + +#define PRIM_MASK (0x1f) + +struct brw_clip_compile { + struct brw_compile func; + struct brw_clip_prog_key key; + struct brw_clip_prog_data prog_data; + + struct { + struct brw_reg R0; + struct brw_reg vertex[MAX_VERTS]; + + struct brw_reg t; + struct brw_reg t0, t1; + struct brw_reg dp0, dp1; + + struct brw_reg dpPrev; + struct brw_reg dp; + struct brw_reg loopcount; + struct brw_reg nr_verts; + struct brw_reg planemask; + + struct brw_reg inlist; + struct brw_reg outlist; + struct brw_reg freelist; + + struct brw_reg dir; + struct brw_reg tmp0, tmp1; + struct brw_reg offset; + + struct brw_reg fixed_planes; + struct brw_reg plane_equation; + } reg; + + /* 3 different ways of expressing vertex size: + */ + unsigned nr_attrs; + unsigned nr_regs; + unsigned nr_bytes; + + unsigned first_tmp; + unsigned last_tmp; + + boolean need_direction; + + unsigned last_mrf; + + unsigned header_position_offset; + unsigned offset[PIPE_ATTRIB_MAX]; +}; + +#define ATTR_SIZE (4*4) + +/* Points are only culled, so no need for a clip routine, however it + * works out easier to have a dummy one. + */ +void brw_emit_unfilled_clip( struct brw_clip_compile *c ); +void brw_emit_tri_clip( struct brw_clip_compile *c ); +void brw_emit_line_clip( struct brw_clip_compile *c ); +void brw_emit_point_clip( struct brw_clip_compile *c ); + +/* brw_clip_tri.c, for use by the unfilled clip routine: + */ +void brw_clip_tri_init_vertices( struct brw_clip_compile *c ); +void brw_clip_tri_flat_shade( struct brw_clip_compile *c ); +void brw_clip_tri( struct brw_clip_compile *c ); +void brw_clip_tri_emit_polygon( struct brw_clip_compile *c ); +void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, + unsigned nr_verts ); + + +/* Utils: + */ + +void brw_clip_interp_vertex( struct brw_clip_compile *c, + struct brw_indirect dest_ptr, + struct brw_indirect v0_ptr, /* from */ + struct brw_indirect v1_ptr, /* to */ + struct brw_reg t0, + boolean force_edgeflag ); + +void brw_clip_init_planes( struct brw_clip_compile *c ); + +void brw_clip_emit_vue(struct brw_clip_compile *c, + struct brw_indirect vert, + boolean allocate, + boolean eot, + unsigned header); + +void brw_clip_kill_thread(struct brw_clip_compile *c); + +struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c ); +struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c ); + +void brw_clip_copy_colors( struct brw_clip_compile *c, + unsigned to, unsigned from ); + +void brw_clip_init_clipmask( struct brw_clip_compile *c ); + +#endif diff --git a/src/gallium/drivers/i965simple/brw_clip_line.c b/src/gallium/drivers/i965simple/brw_clip_line.c new file mode 100644 index 0000000000..75d9e5fcda --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_clip_line.c @@ -0,0 +1,245 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_util.h" +#include "brw_clip.h" + + + +static void brw_clip_line_alloc_regs( struct brw_clip_compile *c ) +{ + unsigned i = 0,j; + + /* Register usage is static, precompute here: + */ + c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++; + + if (c->key.nr_userclip) { + c->reg.fixed_planes = brw_vec4_grf(i, 0); + i += (6 + c->key.nr_userclip + 1) / 2; + + c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2; + } + else + c->prog_data.curb_read_length = 0; + + + /* Payload vertices plus space for more generated vertices: + */ + for (j = 0; j < 4; j++) { + c->reg.vertex[j] = brw_vec4_grf(i, 0); + i += c->nr_regs; + } + + c->reg.t = brw_vec1_grf(i, 0); + c->reg.t0 = brw_vec1_grf(i, 1); + c->reg.t1 = brw_vec1_grf(i, 2); + c->reg.planemask = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD); + c->reg.plane_equation = brw_vec4_grf(i, 4); + i++; + + c->reg.dp0 = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */ + c->reg.dp1 = brw_vec1_grf(i, 4); + i++; + + if (!c->key.nr_userclip) { + c->reg.fixed_planes = brw_vec8_grf(i, 0); + i++; + } + + + c->first_tmp = i; + c->last_tmp = i; + + c->prog_data.urb_read_length = c->nr_regs; /* ? */ + c->prog_data.total_grf = i; +} + + + +/* Line clipping, more or less following the following algorithm: + * + * for (p=0;p t1) t1 = t; + * } else { + * float t = dp0 / (dp0 - dp1); + * if (t > t0) t0 = t; + * } + * + * if (t0 + t1 >= 1.0) + * return; + * } + * } + * + * interp( ctx, newvtx0, vtx0, vtx1, t0 ); + * interp( ctx, newvtx1, vtx1, vtx0, t1 ); + * + */ +static void clip_and_emit_line( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_indirect vtx0 = brw_indirect(0, 0); + struct brw_indirect vtx1 = brw_indirect(1, 0); + struct brw_indirect newvtx0 = brw_indirect(2, 0); + struct brw_indirect newvtx1 = brw_indirect(3, 0); + struct brw_indirect plane_ptr = brw_indirect(4, 0); + struct brw_instruction *plane_loop; + struct brw_instruction *plane_active; + struct brw_instruction *is_negative; + struct brw_instruction *is_neg2; + struct brw_instruction *not_culled; + struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD); + + brw_MOV(p, get_addr_reg(vtx0), brw_address(c->reg.vertex[0])); + brw_MOV(p, get_addr_reg(vtx1), brw_address(c->reg.vertex[1])); + brw_MOV(p, get_addr_reg(newvtx0), brw_address(c->reg.vertex[2])); + brw_MOV(p, get_addr_reg(newvtx1), brw_address(c->reg.vertex[3])); + brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c)); + + /* Note: init t0, t1 together: + */ + brw_MOV(p, vec2(c->reg.t0), brw_imm_f(0)); + + brw_clip_init_planes(c); + brw_clip_init_clipmask(c); + + /* -ve rhw workaround */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), + brw_imm_ud(1<<20)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + plane_loop = brw_DO(p, BRW_EXECUTE_1); + { + /* if (planemask & 1) + */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1)); + + plane_active = brw_IF(p, BRW_EXECUTE_1); + { + if (c->key.nr_userclip) + brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0)); + else + brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0)); + +#if 0 + /* dp = DP4(vtx->position, plane) + */ + brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation); + + /* if (IS_NEGATIVE(dp1)) + */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_L); + brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation); +#else + #warning "disabled" +#endif + is_negative = brw_IF(p, BRW_EXECUTE_1); + { + brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0)); + brw_math_invert(p, c->reg.t, c->reg.t); + brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1); + + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 ); + brw_MOV(p, c->reg.t1, c->reg.t); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + } + is_negative = brw_ELSE(p, is_negative); + { + /* Coming back in. We know that both cannot be negative + * because the line would have been culled in that case. + */ + + /* If both are positive, do nothing */ + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0)); + is_neg2 = brw_IF(p, BRW_EXECUTE_1); + { + brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1)); + brw_math_invert(p, c->reg.t, c->reg.t); + brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0); + + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 ); + brw_MOV(p, c->reg.t0, c->reg.t); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + } + brw_ENDIF(p, is_neg2); + } + brw_ENDIF(p, is_negative); + } + brw_ENDIF(p, plane_active); + + /* plane_ptr++; + */ + brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c)); + + /* while (planemask>>=1) != 0 + */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1)); + } + brw_WHILE(p, plane_loop); + + brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1); + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0)); + not_culled = brw_IF(p, BRW_EXECUTE_1); + { + brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, FALSE); + brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, FALSE); + + brw_clip_emit_vue(c, newvtx0, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_START); + brw_clip_emit_vue(c, newvtx1, 0, 1, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_END); + } + brw_ENDIF(p, not_culled); + brw_clip_kill_thread(c); +} + + + +void brw_emit_line_clip( struct brw_clip_compile *c ) +{ + brw_clip_line_alloc_regs(c); + + if (c->key.do_flat_shading) + brw_clip_copy_colors(c, 0, 1); + + clip_and_emit_line(c); +} diff --git a/src/gallium/drivers/i965simple/brw_clip_point.c b/src/gallium/drivers/i965simple/brw_clip_point.c new file mode 100644 index 0000000000..6fce7210d1 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_clip_point.c @@ -0,0 +1,47 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_util.h" +#include "brw_clip.h" + + +/* Point clipping, nothing to do? + */ +void brw_emit_point_clip( struct brw_clip_compile *c ) +{ + /* Send an empty message to kill the thread: + */ + brw_clip_tri_alloc_regs(c, 0); + brw_clip_kill_thread(c); +} diff --git a/src/gallium/drivers/i965simple/brw_clip_state.c b/src/gallium/drivers/i965simple/brw_clip_state.c new file mode 100644 index 0000000000..ea5c05a279 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_clip_state.c @@ -0,0 +1,92 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" +#include "pipe/p_util.h" + + +static void upload_clip_unit( struct brw_context *brw ) +{ + struct brw_clip_unit_state clip; + + memset(&clip, 0, sizeof(clip)); + + /* CACHE_NEW_CLIP_PROG */ + clip.thread0.grf_reg_count = + align(brw->clip.prog_data->total_grf, 16) / 16 - 1; + clip.thread0.kernel_start_pointer = brw->clip.prog_gs_offset >> 6; + clip.thread3.urb_entry_read_length = brw->clip.prog_data->urb_read_length; + clip.thread3.const_urb_entry_read_length = brw->clip.prog_data->curb_read_length; + clip.clip5.clip_mode = brw->clip.prog_data->clip_mode; + + /* BRW_NEW_CURBE_OFFSETS */ + clip.thread3.const_urb_entry_read_offset = brw->curbe.clip_start * 2; + + /* BRW_NEW_URB_FENCE */ + clip.thread4.nr_urb_entries = brw->urb.nr_clip_entries; + clip.thread4.urb_entry_allocation_size = brw->urb.vsize - 1; + clip.thread4.max_threads = 1; /* 2 threads */ + + if (BRW_DEBUG & DEBUG_STATS) + clip.thread4.stats_enable = 1; + + /* CONSTANT */ + clip.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; + clip.thread1.single_program_flow = 1; + clip.thread3.dispatch_grf_start_reg = 1; + clip.thread3.urb_entry_read_offset = 0; + clip.clip5.userclip_enable_flags = 0x7f; + clip.clip5.userclip_must_clip = 1; + clip.clip5.guard_band_enable = 0; + clip.clip5.viewport_z_clip_enable = 1; + clip.clip5.viewport_xy_clip_enable = 1; + clip.clip5.vertex_position_space = BRW_CLIP_NDCSPACE; + clip.clip5.api_mode = BRW_CLIP_API_OGL; + clip.clip6.clipper_viewport_state_ptr = 0; + clip.viewport_xmin = -1; + clip.viewport_xmax = 1; + clip.viewport_ymin = -1; + clip.viewport_ymax = 1; + + brw->clip.state_gs_offset = brw_cache_data( &brw->cache[BRW_CLIP_UNIT], &clip ); +} + + +const struct brw_tracked_state brw_clip_unit = { + .dirty = { + .brw = (BRW_NEW_CURBE_OFFSETS | + BRW_NEW_URB_FENCE), + .cache = CACHE_NEW_CLIP_PROG + }, + .update = upload_clip_unit +}; diff --git a/src/gallium/drivers/i965simple/brw_clip_tri.c b/src/gallium/drivers/i965simple/brw_clip_tri.c new file mode 100644 index 0000000000..c5da7b825e --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_clip_tri.c @@ -0,0 +1,566 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_util.h" +#include "brw_clip.h" + +static struct brw_reg get_tmp( struct brw_clip_compile *c ) +{ + struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0); + + if (++c->last_tmp > c->prog_data.total_grf) + c->prog_data.total_grf = c->last_tmp; + + return tmp; +} + +static void release_tmps( struct brw_clip_compile *c ) +{ + c->last_tmp = c->first_tmp; +} + + +void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, + unsigned nr_verts ) +{ + unsigned i = 0,j; + + /* Register usage is static, precompute here: + */ + c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++; + + if (c->key.nr_userclip) { + c->reg.fixed_planes = brw_vec4_grf(i, 0); + i += (6 + c->key.nr_userclip + 1) / 2; + + c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2; + } + else + c->prog_data.curb_read_length = 0; + + + /* Payload vertices plus space for more generated vertices: + */ + for (j = 0; j < nr_verts; j++) { + c->reg.vertex[j] = brw_vec4_grf(i, 0); + i += c->nr_regs; + } + + if (c->nr_attrs & 1) { + for (j = 0; j < 3; j++) { + unsigned delta = c->nr_attrs*16 + 32; + brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0)); + } + } + + c->reg.t = brw_vec1_grf(i, 0); + c->reg.loopcount = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_UD); + c->reg.nr_verts = retype(brw_vec1_grf(i, 2), BRW_REGISTER_TYPE_UD); + c->reg.planemask = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD); + c->reg.plane_equation = brw_vec4_grf(i, 4); + i++; + + c->reg.dpPrev = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */ + c->reg.dp = brw_vec1_grf(i, 4); + i++; + + c->reg.inlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0); + i++; + + c->reg.outlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0); + i++; + + c->reg.freelist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0); + i++; + + if (!c->key.nr_userclip) { + c->reg.fixed_planes = brw_vec8_grf(i, 0); + i++; + } + + if (c->key.do_unfilled) { + c->reg.dir = brw_vec4_grf(i, 0); + c->reg.offset = brw_vec4_grf(i, 4); + i++; + c->reg.tmp0 = brw_vec4_grf(i, 0); + c->reg.tmp1 = brw_vec4_grf(i, 4); + i++; + } + + c->first_tmp = i; + c->last_tmp = i; + + c->prog_data.urb_read_length = c->nr_regs; /* ? */ + c->prog_data.total_grf = i; +} + + + +void brw_clip_tri_init_vertices( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */ + struct brw_instruction *is_rev; + + /* Initial list of indices for incoming vertexes: + */ + brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); + brw_CMP(p, + vec1(brw_null_reg()), + BRW_CONDITIONAL_EQ, + tmp0, + brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE)); + + /* XXX: Is there an easier way to do this? Need to reverse every + * second tristrip element: Can ignore sometimes? + */ + is_rev = brw_IF(p, BRW_EXECUTE_1); + { + brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[1]) ); + brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[0]) ); + if (c->need_direction) + brw_MOV(p, c->reg.dir, brw_imm_f(-1)); + } + is_rev = brw_ELSE(p, is_rev); + { + brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[0]) ); + brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[1]) ); + if (c->need_direction) + brw_MOV(p, c->reg.dir, brw_imm_f(1)); + } + brw_ENDIF(p, is_rev); + + brw_MOV(p, get_element(c->reg.inlist, 2), brw_address(c->reg.vertex[2]) ); + brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0)); + brw_MOV(p, c->reg.nr_verts, brw_imm_ud(3)); +} + + + +void brw_clip_tri_flat_shade( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *is_poly; + struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */ + + brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); + brw_CMP(p, + vec1(brw_null_reg()), + BRW_CONDITIONAL_EQ, + tmp0, + brw_imm_ud(_3DPRIM_POLYGON)); + + is_poly = brw_IF(p, BRW_EXECUTE_1); + { + brw_clip_copy_colors(c, 1, 0); + brw_clip_copy_colors(c, 2, 0); + } + is_poly = brw_ELSE(p, is_poly); + { + brw_clip_copy_colors(c, 0, 2); + brw_clip_copy_colors(c, 1, 2); + } + brw_ENDIF(p, is_poly); +} + + + +/* Use mesa's clipping algorithms, translated to GEN4 assembly. + */ +void brw_clip_tri( struct brw_clip_compile *c ) +{ +#if 0 + struct brw_compile *p = &c->func; + struct brw_indirect vtx = brw_indirect(0, 0); + struct brw_indirect vtxPrev = brw_indirect(1, 0); + struct brw_indirect vtxOut = brw_indirect(2, 0); + struct brw_indirect plane_ptr = brw_indirect(3, 0); + struct brw_indirect inlist_ptr = brw_indirect(4, 0); + struct brw_indirect outlist_ptr = brw_indirect(5, 0); + struct brw_indirect freelist_ptr = brw_indirect(6, 0); + struct brw_instruction *plane_loop; + struct brw_instruction *plane_active; + struct brw_instruction *vertex_loop; + struct brw_instruction *next_test; + struct brw_instruction *prev_test; + + brw_MOV(p, get_addr_reg(vtxPrev), brw_address(c->reg.vertex[2]) ); + brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c)); + brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist)); + brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist)); + + brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) ); + + plane_loop = brw_DO(p, BRW_EXECUTE_1); + { + /* if (planemask & 1) + */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1)); + + plane_active = brw_IF(p, BRW_EXECUTE_1); + { + /* vtxOut = freelist_ptr++ + */ + brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(freelist_ptr) ); + brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE)); + + if (c->key.nr_userclip) + brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0)); + else + brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0)); + + brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); + brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0)); + + vertex_loop = brw_DO(p, BRW_EXECUTE_1); + { + /* vtx = *input_ptr; + */ + brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0)); + + /* IS_NEGATIVE(prev) */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_L); + brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation); + prev_test = brw_IF(p, BRW_EXECUTE_1); + { + /* IS_POSITIVE(next) + */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_GE); + brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation); + next_test = brw_IF(p, BRW_EXECUTE_1); + { + + /* Coming back in. + */ + brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp)); + brw_math_invert(p, c->reg.t, c->reg.t); + brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev); + + /* If (vtxOut == 0) vtxOut = vtxPrev + */ + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) ); + brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev) ); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, FALSE); + + /* *outlist_ptr++ = vtxOut; + * nr_verts++; + * vtxOut = 0; + */ + brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut)); + brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short))); + brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1)); + brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) ); + } + brw_ENDIF(p, next_test); + + } + prev_test = brw_ELSE(p, prev_test); + { + /* *outlist_ptr++ = vtxPrev; + * nr_verts++; + */ + brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev)); + brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short))); + brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1)); + + /* IS_NEGATIVE(next) + */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_L); + brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation); + next_test = brw_IF(p, BRW_EXECUTE_1); + { + /* Going out of bounds. Avoid division by zero as we + * know dp != dpPrev from DIFFERENT_SIGNS, above. + */ + brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev)); + brw_math_invert(p, c->reg.t, c->reg.t); + brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp); + + /* If (vtxOut == 0) vtxOut = vtx + */ + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) ); + brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx) ); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, TRUE); + + /* *outlist_ptr++ = vtxOut; + * nr_verts++; + * vtxOut = 0; + */ + brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut)); + brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short))); + brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1)); + brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) ); + } + brw_ENDIF(p, next_test); + } + brw_ENDIF(p, prev_test); + + /* vtxPrev = vtx; + * inlist_ptr++; + */ + brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx)); + brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short))); + + /* while (--loopcount != 0) + */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); + } + brw_WHILE(p, vertex_loop); + + /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1] + * inlist = outlist + * inlist_ptr = &inlist[0] + * outlist_ptr = &outlist[0] + */ + brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2)); + brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0)); + brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0)); + brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist)); + brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist)); + } + brw_ENDIF(p, plane_active); + + /* plane_ptr++; + */ + brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c)); + + /* nr_verts >= 3 + */ + brw_CMP(p, + vec1(brw_null_reg()), + BRW_CONDITIONAL_GE, + c->reg.nr_verts, + brw_imm_ud(3)); + + /* && (planemask>>=1) != 0 + */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1)); + } + brw_WHILE(p, plane_loop); +#else + #warning "disabled" +#endif +} + + + +void brw_clip_tri_emit_polygon(struct brw_clip_compile *c) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *loop, *if_insn; + + /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--) + */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_G); + brw_ADD(p, + c->reg.loopcount, + c->reg.nr_verts, + brw_imm_d(-2)); + + if_insn = brw_IF(p, BRW_EXECUTE_1); + { + struct brw_indirect v0 = brw_indirect(0, 0); + struct brw_indirect vptr = brw_indirect(1, 0); + + brw_MOV(p, get_addr_reg(vptr), brw_address(c->reg.inlist)); + brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0)); + + brw_clip_emit_vue(c, v0, 1, 0, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_START)); + + brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2)); + brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0)); + + loop = brw_DO(p, BRW_EXECUTE_1); + { + brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_TRIFAN << 2)); + + brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2)); + brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0)); + + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); + } + brw_WHILE(p, loop); + + brw_clip_emit_vue(c, v0, 0, 1, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_END)); + } + brw_ENDIF(p, if_insn); +} + +static void do_clip_tri( struct brw_clip_compile *c ) +{ + brw_clip_init_planes(c); + + brw_clip_tri(c); +} + + +static void maybe_do_clip_tri( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *do_clip; + + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0)); + do_clip = brw_IF(p, BRW_EXECUTE_1); + { + do_clip_tri(c); + } + brw_ENDIF(p, do_clip); +} + +static void brw_clip_test( struct brw_clip_compile *c ) +{ +#if 0 + struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + + struct brw_reg v0 = get_tmp(c); + struct brw_reg v1 = get_tmp(c); + struct brw_reg v2 = get_tmp(c); + + struct brw_indirect vt0 = brw_indirect(0, 0); + struct brw_indirect vt1 = brw_indirect(1, 0); + struct brw_indirect vt2 = brw_indirect(2, 0); + + struct brw_compile *p = &c->func; + + brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0])); + brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1])); + brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2])); + brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS])); + brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS])); + brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS])); + + /* test nearz, xmin, ymin plane */ + brw_CMP(p, t1, BRW_CONDITIONAL_LE, negate(v0), get_element(v0, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t2, BRW_CONDITIONAL_LE, negate(v1), get_element(v1, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t3, BRW_CONDITIONAL_LE, negate(v2), get_element(v2, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_XOR(p, t, t1, t2); + brw_XOR(p, t1, t2, t3); + brw_OR(p, t, t, t1); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 0), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 1), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 2), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + /* test farz, xmax, ymax plane */ + brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, get_element(v0, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, get_element(v1, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, get_element(v2, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + brw_XOR(p, t, t1, t2); + brw_XOR(p, t1, t2, t3); + brw_OR(p, t, t, t1); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 0), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 1), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 2), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + release_tmps(c); +#else + #warning "disabled" +#endif +} + + +void brw_emit_tri_clip( struct brw_clip_compile *c ) +{ + struct brw_instruction *neg_rhw; + struct brw_compile *p = &c->func; + brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6); + brw_clip_tri_init_vertices(c); + brw_clip_init_clipmask(c); + + /* if -ve rhw workaround bit is set, + do cliptest */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), + brw_imm_ud(1<<20)); + neg_rhw = brw_IF(p, BRW_EXECUTE_1); + { + brw_clip_test(c); + } + brw_ENDIF(p, neg_rhw); + + /* Can't push into do_clip_tri because with polygon (or quad) + * flatshading, need to apply the flatshade here because we don't + * respect the PV when converting to trifan for emit: + */ + if (c->key.do_flat_shading) + brw_clip_tri_flat_shade(c); + + if (c->key.clip_mode == BRW_CLIPMODE_NORMAL) + do_clip_tri(c); + else + maybe_do_clip_tri(c); + + brw_clip_tri_emit_polygon(c); + + /* Send an empty message to kill the thread: + */ + brw_clip_kill_thread(c); +} diff --git a/src/gallium/drivers/i965simple/brw_clip_unfilled.c b/src/gallium/drivers/i965simple/brw_clip_unfilled.c new file mode 100644 index 0000000000..b774a76dd6 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_clip_unfilled.c @@ -0,0 +1,477 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_util.h" +#include "brw_clip.h" + + + +/* This is performed against the original triangles, so no indirection + * required: +BZZZT! + */ +static void compute_tri_direction( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_reg e = c->reg.tmp0; + struct brw_reg f = c->reg.tmp1; + struct brw_reg v0 = byte_offset(c->reg.vertex[0], c->offset[VERT_RESULT_HPOS]); + struct brw_reg v1 = byte_offset(c->reg.vertex[1], c->offset[VERT_RESULT_HPOS]); + struct brw_reg v2 = byte_offset(c->reg.vertex[2], c->offset[VERT_RESULT_HPOS]); + + + /* Calculate the vectors of two edges of the triangle: + */ + brw_ADD(p, e, v0, negate(v2)); + brw_ADD(p, f, v1, negate(v2)); + + /* Take their crossproduct: + */ + brw_set_access_mode(p, BRW_ALIGN_16); + brw_MUL(p, vec4(brw_null_reg()), brw_swizzle(e, 1,2,0,3), brw_swizzle(f,2,0,1,3)); + brw_MAC(p, vec4(e), negate(brw_swizzle(e, 2,0,1,3)), brw_swizzle(f,1,2,0,3)); + brw_set_access_mode(p, BRW_ALIGN_1); + + brw_MUL(p, c->reg.dir, c->reg.dir, vec4(e)); +} + + +static void cull_direction( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *ccw; + unsigned conditional; + + assert (!(c->key.fill_ccw == CLIP_CULL && + c->key.fill_cw == CLIP_CULL)); + + if (c->key.fill_ccw == CLIP_CULL) + conditional = BRW_CONDITIONAL_GE; + else + conditional = BRW_CONDITIONAL_L; + + brw_CMP(p, + vec1(brw_null_reg()), + conditional, + get_element(c->reg.dir, 2), + brw_imm_f(0)); + + ccw = brw_IF(p, BRW_EXECUTE_1); + { + brw_clip_kill_thread(c); + } + brw_ENDIF(p, ccw); +} + + + +static void copy_bfc( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *ccw; + unsigned conditional; + + /* Do we have any colors to copy? + */ + if (!(c->offset[VERT_RESULT_COL0] && c->offset[VERT_RESULT_BFC0]) && + !(c->offset[VERT_RESULT_COL1] && c->offset[VERT_RESULT_BFC1])) + return; + + /* In some wierd degnerate cases we can end up testing the + * direction twice, once for culling and once for bfc copying. Oh + * well, that's what you get for setting wierd GL state. + */ + if (c->key.copy_bfc_ccw) + conditional = BRW_CONDITIONAL_GE; + else + conditional = BRW_CONDITIONAL_L; + + brw_CMP(p, + vec1(brw_null_reg()), + conditional, + get_element(c->reg.dir, 2), + brw_imm_f(0)); + + ccw = brw_IF(p, BRW_EXECUTE_1); + { + unsigned i; + + for (i = 0; i < 3; i++) { + if (c->offset[VERT_RESULT_COL0] && c->offset[VERT_RESULT_BFC0]) + brw_MOV(p, + byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_COL0]), + byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_BFC0])); + + if (c->offset[VERT_RESULT_COL1] && c->offset[VERT_RESULT_BFC1]) + brw_MOV(p, + byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_COL1]), + byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_BFC1])); + } + } + brw_ENDIF(p, ccw); +} + + + + +/* + float iz = 1.0 / dir.z; + float ac = dir.x * iz; + float bc = dir.y * iz; + offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE; + offset += MAX2( abs(ac), abs(bc) ) * ctx->Polygon.OffsetFactor; + offset *= MRD; +*/ +static void compute_offset( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_reg off = c->reg.offset; + struct brw_reg dir = c->reg.dir; + + brw_math_invert(p, get_element(off, 2), get_element(dir, 2)); + brw_MUL(p, vec2(off), dir, get_element(off, 2)); + + brw_CMP(p, + vec1(brw_null_reg()), + BRW_CONDITIONAL_GE, + brw_abs(get_element(off, 0)), + brw_abs(get_element(off, 1))); + + brw_SEL(p, vec1(off), brw_abs(get_element(off, 0)), brw_abs(get_element(off, 1))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + brw_MUL(p, vec1(off), off, brw_imm_f(c->key.offset_factor)); + brw_ADD(p, vec1(off), off, brw_imm_f(c->key.offset_units)); +} + + +static void merge_edgeflags( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *is_poly; + struct brw_reg tmp0 = get_element_ud(c->reg.tmp0, 0); + + brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); + brw_CMP(p, + vec1(brw_null_reg()), + BRW_CONDITIONAL_EQ, + tmp0, + brw_imm_ud(_3DPRIM_POLYGON)); + + /* Get away with using reg.vertex because we know that this is not + * a _3DPRIM_TRISTRIP_REVERSE: + */ + is_poly = brw_IF(p, BRW_EXECUTE_1); + { + brw_set_conditionalmod(p, BRW_CONDITIONAL_EQ); + brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<8)); + brw_MOV(p, byte_offset(c->reg.vertex[0], c->offset[VERT_RESULT_EDGE]), brw_imm_f(0)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + brw_set_conditionalmod(p, BRW_CONDITIONAL_EQ); + brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<9)); + brw_MOV(p, byte_offset(c->reg.vertex[2], c->offset[VERT_RESULT_EDGE]), brw_imm_f(0)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + } + brw_ENDIF(p, is_poly); +} + + + +static void apply_one_offset( struct brw_clip_compile *c, + struct brw_indirect vert ) +{ + struct brw_compile *p = &c->func; + struct brw_reg pos = deref_4f(vert, c->offset[VERT_RESULT_HPOS]); + struct brw_reg z = get_element(pos, 2); + + brw_ADD(p, z, z, vec1(c->reg.offset)); +} + + + +/*********************************************************************** + * Output clipped polygon as an unfilled primitive: + */ +static void emit_lines(struct brw_clip_compile *c, + boolean do_offset) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *loop; + struct brw_instruction *draw_edge; + struct brw_indirect v0 = brw_indirect(0, 0); + struct brw_indirect v1 = brw_indirect(1, 0); + struct brw_indirect v0ptr = brw_indirect(2, 0); + struct brw_indirect v1ptr = brw_indirect(3, 0); + + /* Need a seperate loop for offset: + */ + if (do_offset) { + brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); + brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist)); + + loop = brw_DO(p, BRW_EXECUTE_1); + { + brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0)); + brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2)); + + apply_one_offset(c, v0); + + brw_set_conditionalmod(p, BRW_CONDITIONAL_G); + brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); + } + brw_WHILE(p, loop); + } + + /* v1ptr = &inlist[nr_verts] + * *v1ptr = v0 + */ + brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); + brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist)); + brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v0ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW)); + brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v1ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW)); + brw_MOV(p, deref_1uw(v1ptr, 0), deref_1uw(v0ptr, 0)); + + loop = brw_DO(p, BRW_EXECUTE_1); + { + brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0)); + brw_MOV(p, get_addr_reg(v1), deref_1uw(v0ptr, 2)); + brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2)); + + /* draw edge if edgeflag != 0 */ + brw_CMP(p, + vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, + deref_1f(v0, c->offset[VERT_RESULT_EDGE]), + brw_imm_f(0)); + draw_edge = brw_IF(p, BRW_EXECUTE_1); + { + brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_START); + brw_clip_emit_vue(c, v1, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_END); + } + brw_ENDIF(p, draw_edge); + + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); + } + brw_WHILE(p, loop); +} + + + +static void emit_points(struct brw_clip_compile *c, + boolean do_offset ) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *loop; + struct brw_instruction *draw_point; + + struct brw_indirect v0 = brw_indirect(0, 0); + struct brw_indirect v0ptr = brw_indirect(2, 0); + + brw_MOV(p, c->reg.loopcount, c->reg.nr_verts); + brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist)); + + loop = brw_DO(p, BRW_EXECUTE_1); + { + brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0)); + brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2)); + + /* draw if edgeflag != 0 + */ + brw_CMP(p, + vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, + deref_1f(v0, c->offset[VERT_RESULT_EDGE]), + brw_imm_f(0)); + draw_point = brw_IF(p, BRW_EXECUTE_1); + { + if (do_offset) + apply_one_offset(c, v0); + + brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END); + } + brw_ENDIF(p, draw_point); + + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1)); + } + brw_WHILE(p, loop); +} + + + + + + + +static void emit_primitives( struct brw_clip_compile *c, + unsigned mode, + boolean do_offset ) +{ + switch (mode) { + case CLIP_FILL: + brw_clip_tri_emit_polygon(c); + break; + + case CLIP_LINE: + emit_lines(c, do_offset); + break; + + case CLIP_POINT: + emit_points(c, do_offset); + break; + + case CLIP_CULL: + assert(0); + break; + } +} + + + +static void emit_unfilled_primitives( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *ccw; + + /* Direction culling has already been done. + */ + if (c->key.fill_ccw != c->key.fill_cw && + c->key.fill_ccw != CLIP_CULL && + c->key.fill_cw != CLIP_CULL) + { + brw_CMP(p, + vec1(brw_null_reg()), + BRW_CONDITIONAL_GE, + get_element(c->reg.dir, 2), + brw_imm_f(0)); + + ccw = brw_IF(p, BRW_EXECUTE_1); + { + emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw); + } + ccw = brw_ELSE(p, ccw); + { + emit_primitives(c, c->key.fill_cw, c->key.offset_cw); + } + brw_ENDIF(p, ccw); + } + else if (c->key.fill_cw != CLIP_CULL) { + emit_primitives(c, c->key.fill_cw, c->key.offset_cw); + } + else if (c->key.fill_ccw != CLIP_CULL) { + emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw); + } +} + + + + +static void check_nr_verts( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *if_insn; + + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.nr_verts, brw_imm_d(3)); + if_insn = brw_IF(p, BRW_EXECUTE_1); + { + brw_clip_kill_thread(c); + } + brw_ENDIF(p, if_insn); +} + + +void brw_emit_unfilled_clip( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *do_clip; + + + c->need_direction = ((c->key.offset_ccw || c->key.offset_cw) || + (c->key.fill_ccw != c->key.fill_cw) || + c->key.fill_ccw == CLIP_CULL || + c->key.fill_cw == CLIP_CULL || + c->key.copy_bfc_cw || + c->key.copy_bfc_ccw); + + brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6); + brw_clip_tri_init_vertices(c); + + assert(c->offset[VERT_RESULT_EDGE]); + + if (c->key.fill_ccw == CLIP_CULL && + c->key.fill_cw == CLIP_CULL) { + brw_clip_kill_thread(c); + return; + } + + merge_edgeflags(c); + + /* Need to use the inlist indirection here: + */ + if (c->need_direction) + compute_tri_direction(c); + + if (c->key.fill_ccw == CLIP_CULL || + c->key.fill_cw == CLIP_CULL) + cull_direction(c); + + if (c->key.offset_ccw || + c->key.offset_cw) + compute_offset(c); + + if (c->key.copy_bfc_ccw || + c->key.copy_bfc_cw) + copy_bfc(c); + + /* Need to do this whether we clip or not: + */ + if (c->key.do_flat_shading) + brw_clip_tri_flat_shade(c); + + brw_clip_init_clipmask(c); + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0)); + do_clip = brw_IF(p, BRW_EXECUTE_1); + { + brw_clip_init_planes(c); + brw_clip_tri(c); + check_nr_verts(c); + } + brw_ENDIF(p, do_clip); + + emit_unfilled_primitives(c); + brw_clip_kill_thread(c); +} + + + diff --git a/src/gallium/drivers/i965simple/brw_clip_util.c b/src/gallium/drivers/i965simple/brw_clip_util.c new file mode 100644 index 0000000000..6d58ceafff --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_clip_util.c @@ -0,0 +1,351 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_util.h" +#include "brw_clip.h" + + + + + +static struct brw_reg get_tmp( struct brw_clip_compile *c ) +{ + struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0); + + if (++c->last_tmp > c->prog_data.total_grf) + c->prog_data.total_grf = c->last_tmp; + + return tmp; +} + +static void release_tmp( struct brw_clip_compile *c, struct brw_reg tmp ) +{ + if (tmp.nr == c->last_tmp-1) + c->last_tmp--; +} + + +static struct brw_reg make_plane_ud(unsigned x, unsigned y, unsigned z, unsigned w) +{ + return brw_imm_ud((w<<24) | (z<<16) | (y<<8) | x); +} + + +void brw_clip_init_planes( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + + if (!c->key.nr_userclip) { + brw_MOV(p, get_element_ud(c->reg.fixed_planes, 0), make_plane_ud( 0, 0, 0xff, 1)); + brw_MOV(p, get_element_ud(c->reg.fixed_planes, 1), make_plane_ud( 0, 0, 1, 1)); + brw_MOV(p, get_element_ud(c->reg.fixed_planes, 2), make_plane_ud( 0, 0xff, 0, 1)); + brw_MOV(p, get_element_ud(c->reg.fixed_planes, 3), make_plane_ud( 0, 1, 0, 1)); + brw_MOV(p, get_element_ud(c->reg.fixed_planes, 4), make_plane_ud(0xff, 0, 0, 1)); + brw_MOV(p, get_element_ud(c->reg.fixed_planes, 5), make_plane_ud( 1, 0, 0, 1)); + } +} + + + +#define W 3 + +/* Project 'pos' to screen space (or back again), overwrite with results: + */ +static void brw_clip_project_position(struct brw_clip_compile *c, struct brw_reg pos ) +{ + struct brw_compile *p = &c->func; + + /* calc rhw + */ + brw_math_invert(p, get_element(pos, W), get_element(pos, W)); + + /* value.xyz *= value.rhw + */ + brw_set_access_mode(p, BRW_ALIGN_16); + brw_MUL(p, brw_writemask(pos, TGSI_WRITEMASK_XYZ), pos, brw_swizzle1(pos, W)); + brw_set_access_mode(p, BRW_ALIGN_1); +} + + +static void brw_clip_project_vertex( struct brw_clip_compile *c, + struct brw_indirect vert_addr ) +{ +#if 0 + struct brw_compile *p = &c->func; + struct brw_reg tmp = get_tmp(c); + + /* Fixup position. Extract from the original vertex and re-project + * to screen space: + */ + brw_MOV(p, tmp, deref_4f(vert_addr, c->offset[VERT_RESULT_HPOS])); + brw_clip_project_position(c, tmp); + brw_MOV(p, deref_4f(vert_addr, c->header_position_offset), tmp); + + release_tmp(c, tmp); +#else + #warning "disabled" +#endif +} + + + + +/* Interpolate between two vertices and put the result into a0.0. + * Increment a0.0 accordingly. + */ +void brw_clip_interp_vertex( struct brw_clip_compile *c, + struct brw_indirect dest_ptr, + struct brw_indirect v0_ptr, /* from */ + struct brw_indirect v1_ptr, /* to */ + struct brw_reg t0, + boolean force_edgeflag) +{ +#if 0 + struct brw_compile *p = &c->func; + struct brw_reg tmp = get_tmp(c); + unsigned i; + + /* Just copy the vertex header: + */ + brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1); + + /* Iterate over each attribute (could be done in pairs?) + */ + for (i = 0; i < c->nr_attrs; i++) { + unsigned delta = i*16 + 32; + + if (delta == c->offset[VERT_RESULT_EDGE]) { + if (force_edgeflag) + brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1)); + else + brw_MOV(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta)); + } + else { + /* Interpolate: + * + * New = attr0 + t*attr1 - t*attr0 + */ + brw_MUL(p, + vec4(brw_null_reg()), + deref_4f(v1_ptr, delta), + t0); + + brw_MAC(p, + tmp, + negate(deref_4f(v0_ptr, delta)), + t0); + + brw_ADD(p, + deref_4f(dest_ptr, delta), + deref_4f(v0_ptr, delta), + tmp); + } + } + + if (i & 1) { + unsigned delta = i*16 + 32; + brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0)); + } + + release_tmp(c, tmp); + + /* Recreate the projected (NDC) coordinate in the new vertex + * header: + */ + brw_clip_project_vertex(c, dest_ptr ); +#else + #warning "disabled" +#endif +} + + + + +#define MAX_MRF 16 + +void brw_clip_emit_vue(struct brw_clip_compile *c, + struct brw_indirect vert, + boolean allocate, + boolean eot, + unsigned header) +{ + struct brw_compile *p = &c->func; + unsigned start = c->last_mrf; + + assert(!(allocate && eot)); + + /* Cycle through mrf regs - probably futile as we have to wait for + * the allocation response anyway. Also, the order this function + * is invoked doesn't correspond to the order the instructions will + * be executed, so it won't have any effect in many cases. + */ +#if 0 + if (start + c->nr_regs + 1 >= MAX_MRF) + start = 0; + + c->last_mrf = start + c->nr_regs + 1; +#endif + + /* Copy the vertex from vertn into m1..mN+1: + */ + brw_copy_from_indirect(p, brw_message_reg(start+1), vert, c->nr_regs); + + /* Overwrite PrimType and PrimStart in the message header, for + * each vertex in turn: + */ + brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header)); + + + /* Send each vertex as a seperate write to the urb. This + * is different to the concept in brw_sf_emit.c, where + * subsequent writes are used to build up a single urb + * entry. Each of these writes instantiates a seperate + * urb entry - (I think... what about 'allocate'?) + */ + brw_urb_WRITE(p, + allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), + start, + c->reg.R0, + allocate, + 1, /* used */ + c->nr_regs + 1, /* msg length */ + allocate ? 1 : 0, /* response_length */ + eot, /* eot */ + 1, /* writes_complete */ + 0, /* urb offset */ + BRW_URB_SWIZZLE_NONE); +} + + + +void brw_clip_kill_thread(struct brw_clip_compile *c) +{ + struct brw_compile *p = &c->func; + + /* Send an empty message to kill the thread and release any + * allocated urb entry: + */ + brw_urb_WRITE(p, + retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), + 0, + c->reg.R0, + 0, /* allocate */ + 0, /* used */ + 0, /* msg len */ + 0, /* response len */ + 1, /* eot */ + 1, /* writes complete */ + 0, + BRW_URB_SWIZZLE_NONE); +} + + + + +struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c ) +{ + return brw_address(c->reg.fixed_planes); +} + + +struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c ) +{ + if (c->key.nr_userclip) { + return brw_imm_uw(16); + } + else { + return brw_imm_uw(4); + } +} + + +/* If flatshading, distribute color from provoking vertex prior to + * clipping. + */ +void brw_clip_copy_colors( struct brw_clip_compile *c, + unsigned to, unsigned from ) +{ +#if 0 + struct brw_compile *p = &c->func; + + if (c->offset[VERT_RESULT_COL0]) + brw_MOV(p, + byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_COL0]), + byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_COL0])); + + if (c->offset[VERT_RESULT_COL1]) + brw_MOV(p, + byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_COL1]), + byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_COL1])); + + if (c->offset[VERT_RESULT_BFC0]) + brw_MOV(p, + byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_BFC0]), + byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_BFC0])); + + if (c->offset[VERT_RESULT_BFC1]) + brw_MOV(p, + byte_offset(c->reg.vertex[to], c->offset[VERT_RESULT_BFC1]), + byte_offset(c->reg.vertex[from], c->offset[VERT_RESULT_BFC1])); +#else + #warning "disabled" +#endif +} + + + +void brw_clip_init_clipmask( struct brw_clip_compile *c ) +{ + struct brw_compile *p = &c->func; + struct brw_reg incoming = get_element_ud(c->reg.R0, 2); + + /* Shift so that lowest outcode bit is rightmost: + */ + brw_SHR(p, c->reg.planemask, incoming, brw_imm_ud(26)); + + if (c->key.nr_userclip) { + struct brw_reg tmp = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UD); + + /* Rearrange userclip outcodes so that they come directly after + * the fixed plane bits. + */ + brw_AND(p, tmp, incoming, brw_imm_ud(0x3f<<14)); + brw_SHR(p, tmp, tmp, brw_imm_ud(8)); + brw_OR(p, c->reg.planemask, c->reg.planemask, tmp); + + release_tmp(c, tmp); + } +} + diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c new file mode 100644 index 0000000000..5e58701e91 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -0,0 +1,245 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_draw.h" +#include "brw_vs.h" +#include "brw_tex_layout.h" +#include "brw_winsys.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_context.h" +#include "pipe/p_util.h" + +/*************************************** + * Mesa's Driver Functions + ***************************************/ + +#ifndef BRW_DEBUG +int BRW_DEBUG = (0); +#endif + +static void brw_destroy(struct pipe_context *pipe) +{ + struct brw_context *brw = brw_context(pipe); + + FREE(brw); +} + +static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue) +{ + int x, y, w, h; + /* FIXME: corny... */ + + x = 0; + y = 0; + w = ps->width; + h = ps->height; + + pipe->surface_fill(pipe, ps, x, y, w, h, clearValue); +} + + +static int +brw_get_param(struct pipe_context *pipe, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 8; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 0; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 0; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 11; /* max 1024x1024 */ + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 8; /* max 128x128x128 */ + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 11; /* max 1024x1024 */ + default: + return 0; + } +} + + +static float +brw_get_paramf(struct pipe_context *pipe, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 7.5; + + case PIPE_CAP_MAX_POINT_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 255.0; + + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 4.0; + + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0; + + default: + return 0; + } +} + +static boolean +brw_is_format_supported( struct pipe_context *pipe, + enum pipe_format format, uint type ) +{ +#if 0 + /* XXX: This is broken -- rewrite if still needed. */ + static const unsigned tex_supported[] = { + PIPE_FORMAT_U_R8_G8_B8_A8, + PIPE_FORMAT_U_A8_R8_G8_B8, + PIPE_FORMAT_U_R5_G6_B5, + PIPE_FORMAT_U_L8, + PIPE_FORMAT_U_A8, + PIPE_FORMAT_U_I8, + PIPE_FORMAT_U_L8_A8, + PIPE_FORMAT_YCBCR, + PIPE_FORMAT_YCBCR_REV, + PIPE_FORMAT_S8_Z24, + }; + + + /* Actually a lot more than this - add later: + */ + static const unsigned render_supported[] = { + PIPE_FORMAT_U_A8_R8_G8_B8, + PIPE_FORMAT_U_R5_G6_B5, + }; + + /* + */ + static const unsigned z_stencil_supported[] = { + PIPE_FORMAT_U_Z16, + PIPE_FORMAT_U_Z32, + PIPE_FORMAT_S8_Z24, + }; + + switch (type) { + case PIPE_RENDER_FORMAT: + *numFormats = Elements(render_supported); + return render_supported; + + case PIPE_TEX_FORMAT: + *numFormats = Elements(tex_supported); + return render_supported; + + case PIPE_Z_STENCIL_FORMAT: + *numFormats = Elements(render_supported); + return render_supported; + + default: + *numFormats = 0; + return NULL; + } +#else + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: + return TRUE; + default: + return FALSE; + }; + return FALSE; +#endif +} + + + + +struct pipe_context *brw_create(struct pipe_winsys *pipe_winsys, + struct brw_winsys *brw_winsys, + unsigned pci_id) +{ + struct brw_context *brw; + + pipe_winsys->printf(pipe_winsys, + "%s: creating brw_context with pci id 0x%x\n", + __FUNCTION__, pci_id); + + brw = CALLOC_STRUCT(brw_context); + if (brw == NULL) + return NULL; + + brw->winsys = brw_winsys; + brw->pipe.winsys = pipe_winsys; + + brw->pipe.destroy = brw_destroy; + brw->pipe.is_format_supported = brw_is_format_supported; + brw->pipe.get_param = brw_get_param; + brw->pipe.get_paramf = brw_get_paramf; + brw->pipe.clear = brw_clear; + brw->pipe.texture_create = brw_texture_create; + brw->pipe.texture_release = brw_texture_release; + + brw_init_surface_functions(brw); + brw_init_state_functions(brw); + brw_init_flush_functions(brw); + brw_init_string_functions(brw); + brw_init_draw_functions( brw ); + + + brw_init_state( brw ); + + brw->pci_id = pci_id; + brw->dirty = ~0; + brw->hardware_dirty = ~0; + + memset(&brw->wm.bind, ~0, sizeof(brw->wm.bind)); + + return &brw->pipe; +} + diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h new file mode 100644 index 0000000000..65664d853d --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -0,0 +1,690 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRWCONTEXT_INC +#define BRWCONTEXT_INC + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "brw_structs.h" +#include "brw_winsys.h" + + +/* Glossary: + * + * URB - uniform resource buffer. A mid-sized buffer which is + * partitioned between the fixed function units and used for passing + * values (vertices, primitives, constants) between them. + * + * CURBE - constant URB entry. An urb region (entry) used to hold + * constant values which the fixed function units can be instructed to + * preload into the GRF when spawining a thread. + * + * VUE - vertex URB entry. An urb entry holding a vertex and usually + * a vertex header. The header contains control information and + * things like primitive type, Begin/end flags and clip codes. + * + * PUE - primitive URB entry. An urb entry produced by the setup (SF) + * unit holding rasterization and interpolation parameters. + * + * GRF - general register file. One of several register files + * addressable by programmed threads. The inputs (r0, payload, curbe, + * urb) of the thread are preloaded to this area before the thread is + * spawned. The registers are individually 8 dwords wide and suitable + * for general usage. Registers holding thread input values are not + * special and may be overwritten. + * + * MRF - message register file. Threads communicate (and terminate) + * by sending messages. Message parameters are placed in contigous + * MRF registers. All program output is via these messages. URB + * entries are populated by sending a message to the shared URB + * function containing the new data, together with a control word, + * often an unmodified copy of R0. + * + * R0 - GRF register 0. Typically holds control information used when + * sending messages to other threads. + * + * EU or GEN4 EU: The name of the programmable subsystem of the + * i965 hardware. Threads are executed by the EU, the registers + * described above are part of the EU architecture. + * + * Fixed function units: + * + * CS - Command streamer. Notional first unit, little software + * interaction. Holds the URB entries used for constant data, ie the + * CURBEs. + * + * VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of + * this unit is responsible for pulling vertices out of vertex buffers + * in vram and injecting them into the processing pipe as VUEs. If + * enabled, it first passes them to a VS thread which is a good place + * for the driver to implement any active vertex shader. + * + * GS - Geometry Shader. This corresponds to a new DX10 concept. If + * enabled, incoming strips etc are passed to GS threads in individual + * line/triangle/point units. The GS thread may perform arbitary + * computation and emit whatever primtives with whatever vertices it + * chooses. This makes GS an excellent place to implement GL's + * unfilled polygon modes, though of course it is capable of much + * more. Additionally, GS is used to translate away primitives not + * handled by latter units, including Quads and Lineloops. + * + * CS - Clipper. Mesa's clipping algorithms are imported to run on + * this unit. The fixed function part performs cliptesting against + * the 6 fixed clipplanes and makes descisions on whether or not the + * incoming primitive needs to be passed to a thread for clipping. + * User clip planes are handled via cooperation with the VS thread. + * + * SF - Strips Fans or Setup: Triangles are prepared for + * rasterization. Interpolation coefficients are calculated. + * Flatshading and two-side lighting usually performed here. + * + * WM - Windower. Interpolation of vertex attributes performed here. + * Fragment shader implemented here. SIMD aspects of EU taken full + * advantage of, as pixels are processed in blocks of 16. + * + * CC - Color Calculator. No EU threads associated with this unit. + * Handles blending and (presumably) depth and stencil testing. + */ + +#define BRW_MAX_CURBE (32*16) + +struct brw_context; +struct brw_winsys; + + +/* Raised when we receive new state across the pipe interface: + */ +#define BRW_NEW_VIEWPORT 0x1 +#define BRW_NEW_RASTERIZER 0x2 +#define BRW_NEW_FS 0x4 +#define BRW_NEW_BLEND 0x8 +#define BRW_NEW_CLIP 0x10 +#define BRW_NEW_SCISSOR 0x20 +#define BRW_NEW_STIPPLE 0x40 +#define BRW_NEW_FRAMEBUFFER 0x80 +#define BRW_NEW_ALPHA_TEST 0x100 +#define BRW_NEW_DEPTH_STENCIL 0x200 +#define BRW_NEW_SAMPLER 0x400 +#define BRW_NEW_TEXTURE 0x800 +#define BRW_NEW_CONSTANTS 0x1000 +#define BRW_NEW_VBO 0x2000 +#define BRW_NEW_VS 0x4000 + +/* Raised for other internal events: + */ +#define BRW_NEW_URB_FENCE 0x10000 +#define BRW_NEW_PSP 0x20000 +#define BRW_NEW_CURBE_OFFSETS 0x40000 +#define BRW_NEW_REDUCED_PRIMITIVE 0x80000 +#define BRW_NEW_PRIMITIVE 0x100000 +#define BRW_NEW_SCENE 0x200000 +#define BRW_NEW_SF_LINKAGE 0x400000 + +extern int BRW_DEBUG; + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_PRIMS 0x8 +#define DEBUG_VERTS 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_DRI 0x80 +#define DEBUG_DMA 0x100 +#define DEBUG_SANITY 0x200 +#define DEBUG_SYNC 0x400 +#define DEBUG_SLEEP 0x800 +#define DEBUG_PIXEL 0x1000 +#define DEBUG_STATS 0x2000 +#define DEBUG_TILE 0x4000 +#define DEBUG_SINGLE_THREAD 0x8000 +#define DEBUG_WM 0x10000 +#define DEBUG_URB 0x20000 +#define DEBUG_VS 0x40000 +#define DEBUG_BATCH 0x80000 +#define DEBUG_BUFMGR 0x100000 +#define DEBUG_BLIT 0x200000 +#define DEBUG_REGION 0x400000 +#define DEBUG_MIPTREE 0x800000 + +#define DBG(...) do { \ + if (BRW_DEBUG & FILE_DEBUG_FLAG) \ + brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ +} while(0) + +#define PRINT(...) do { \ + brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ +} while(0) + +struct brw_state_flags { + unsigned cache; + unsigned brw; +}; + + +struct brw_shader_info { + int nr_regs[8]; /* TGSI_FILE_* */ +}; + + + +struct brw_vertex_program { + struct pipe_shader_state program; + struct brw_shader_info info; + int id; +}; + + + +struct brw_fragment_program { + struct pipe_shader_state program; + struct brw_shader_info info; + + boolean UsesDepth; + boolean UsesKill; + boolean ComputesDepth; + int id; +}; + + + + +struct pipe_setup_linkage { + struct { + unsigned vp_output:5; + unsigned interp_mode:4; + unsigned bf_vp_output:5; + } fp_input[PIPE_MAX_SHADER_INPUTS]; + + unsigned fp_input_count:5; + unsigned max_vp_output:5; +}; + + + +struct brw_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ + +struct brw_wm_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + + unsigned first_curbe_grf; + unsigned total_grf; + unsigned total_scratch; + + /* Internally generated constants for the CURBE. These are loaded + * ahead of the data from the constant buffer. + */ + const float internal_const[8]; + unsigned nr_internal_consts; + unsigned max_const; + + boolean error; +}; + +struct brw_sf_prog_data { + unsigned urb_read_length; + unsigned total_grf; + + /* Each vertex may have upto 12 attributes, 4 components each, + * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11 + * rows. + * + * Actually we use 4 for each, so call it 12 rows. + */ + unsigned urb_entry_size; +}; + +struct brw_clip_prog_data { + unsigned curb_read_length; /* user planes? */ + unsigned clip_mode; + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_gs_prog_data { + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_vs_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + unsigned total_grf; + unsigned outputs_written; + + unsigned inputs_read; + + unsigned max_const; + + float imm_buf[PIPE_MAX_CONSTANT][4]; + unsigned num_imm; + unsigned num_consts; + + /* Used for calculating urb partitions: + */ + unsigned urb_entry_size; +}; + + +#define BRW_MAX_TEX_UNIT 8 +#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 + +/* Create a fixed sized struct for caching binding tables: + */ +struct brw_surface_binding_table { + unsigned surf_ss_offset[BRW_WM_MAX_SURF]; +}; + + +struct brw_cache; + +struct brw_mem_pool { + struct pipe_buffer *buffer; + + unsigned size; + unsigned offset; /* offset of first free byte */ + + struct brw_context *brw; +}; + +struct brw_cache_item { + unsigned hash; + unsigned key_size; /* for variable-sized keys */ + const void *key; + + unsigned offset; /* offset within pool's buffer */ + unsigned data_size; + + struct brw_cache_item *next; +}; + + + +struct brw_cache { + unsigned id; + + const char *name; + + struct brw_context *brw; + struct brw_mem_pool *pool; + + struct brw_cache_item **items; + unsigned size, n_items; + + unsigned key_size; /* for fixed-size keys */ + unsigned aux_size; + + unsigned last_addr; /* offset of active item */ +}; + + + + +/* Considered adding a member to this struct to document which flags + * an update might raise so that ordering of the state atoms can be + * checked or derived at runtime. Dropped the idea in favor of having + * a debug mode where the state is monitored for flags which are + * raised that have already been tested against. + */ +struct brw_tracked_state { + struct brw_state_flags dirty; + void (*update)( struct brw_context *brw ); +}; + + +/* Flags for brw->state.cache. + */ +#define CACHE_NEW_CC_VP (1< 32. Wouldn't life + * be easier if C allowed arrays of packed elements? + */ +#define ATTRIB_BIT_DWORDS ((PIPE_ATTRIB_MAX+31)/32) + + + + +struct brw_vertex_info { + unsigned varying; /* varying:1[PIPE_ATTRIB_MAX] */ + unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_ATTRIB_MAX] */ +}; + + + + + +struct brw_context +{ + struct pipe_context pipe; + struct brw_winsys *winsys; + + unsigned primitive; + unsigned reduced_primitive; + + boolean emit_state_always; + + struct { + struct brw_state_flags dirty; + } state; + + + struct { + const struct pipe_blend_state *Blend; + const struct pipe_depth_stencil_alpha_state *DepthStencil; + const struct pipe_poly_stipple *PolygonStipple; + const struct pipe_rasterizer_state *Raster; + const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS]; + const struct brw_vertex_program *VertexProgram; + const struct brw_fragment_program *FragmentProgram; + + struct pipe_clip_state Clip; + struct pipe_blend_color BlendColor; + struct pipe_scissor_state Scissor; + struct pipe_viewport_state Viewport; + struct pipe_framebuffer_state FrameBuffer; + + const struct pipe_constant_buffer *Constants[2]; + const struct brw_texture *Texture[PIPE_MAX_SAMPLERS]; + } attribs; + + struct brw_mem_pool pool[BRW_MAX_POOL]; + struct brw_cache cache[BRW_MAX_CACHE]; + struct brw_cached_batch_item *cached_batch_items; + + struct { + + /* Arrays with buffer objects to copy non-bufferobj arrays into + * for upload: + */ + struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX]; + + struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX]; + +#define BRW_NR_UPLOAD_BUFS 17 +#define BRW_UPLOAD_INIT_SIZE (128*1024) + + /* Summary of size and varying of active arrays, so we can check + * for changes to this state: + */ + struct brw_vertex_info info; + } vb; + + + unsigned hardware_dirty; + unsigned dirty; + unsigned pci_id; + /* BRW_NEW_URB_ALLOCATIONS: + */ + struct { + unsigned vsize; /* vertex size plus header in urb registers */ + unsigned csize; /* constant buffer size in urb registers */ + unsigned sfsize; /* setup data size in urb registers */ + + boolean constrained; + + unsigned nr_vs_entries; + unsigned nr_gs_entries; + unsigned nr_clip_entries; + unsigned nr_sf_entries; + unsigned nr_cs_entries; + +/* unsigned vs_size; */ +/* unsigned gs_size; */ +/* unsigned clip_size; */ +/* unsigned sf_size; */ +/* unsigned cs_size; */ + + unsigned vs_start; + unsigned gs_start; + unsigned clip_start; + unsigned sf_start; + unsigned cs_start; + } urb; + + + /* BRW_NEW_CURBE_OFFSETS: + */ + struct { + unsigned wm_start; + unsigned wm_size; + unsigned clip_start; + unsigned clip_size; + unsigned vs_start; + unsigned vs_size; + unsigned total_size; + + unsigned gs_offset; + + float *last_buf; + unsigned last_bufsz; + } curbe; + + struct { + struct brw_vs_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } vs; + + struct { + struct brw_gs_prog_data *prog_data; + + boolean prog_active; + unsigned prog_gs_offset; + unsigned state_gs_offset; + } gs; + + struct { + struct brw_clip_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } clip; + + + struct { + struct brw_sf_prog_data *prog_data; + + struct pipe_setup_linkage linkage; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } sf; + + struct { + struct brw_wm_prog_data *prog_data; + +// struct brw_wm_compiler *compile_data; + + + /** + * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER + * cache + */ + struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; + + unsigned render_surf; + unsigned nr_surfaces; + + unsigned max_threads; + struct pipe_buffer *scratch_buffer; + unsigned scratch_buffer_size; + + unsigned sampler_count; + unsigned sampler_gs_offset; + + struct brw_surface_binding_table bind; + unsigned bind_ss_offset; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } wm; + + + struct { + unsigned vp_gs_offset; + unsigned state_gs_offset; + } cc; + + + /* Used to give every program string a unique id + */ + unsigned program_id; +}; + + +#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a) + + +/*====================================================================== + * brw_vtbl.c + */ +void brw_do_flush( struct brw_context *brw, + unsigned flags ); + + +/*====================================================================== + * brw_state.c + */ +void brw_validate_state(struct brw_context *brw); +void brw_init_state(struct brw_context *brw); +void brw_destroy_state(struct brw_context *brw); + + +/*====================================================================== + * brw_tex.c + */ +void brwUpdateTextureState( struct brw_context *brw ); + + +/* brw_urb.c + */ +void brw_upload_urb_fence(struct brw_context *brw); + +void brw_upload_constant_buffer_state(struct brw_context *brw); + +void brw_init_surface_functions(struct brw_context *brw); +void brw_init_state_functions(struct brw_context *brw); +void brw_init_flush_functions(struct brw_context *brw); +void brw_init_string_functions(struct brw_context *brw); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static inline struct brw_context * +brw_context( struct pipe_context *ctx ) +{ + return (struct brw_context *)ctx; +} + +#endif + diff --git a/src/gallium/drivers/i965simple/brw_curbe.c b/src/gallium/drivers/i965simple/brw_curbe.c new file mode 100644 index 0000000000..52bbd525c1 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_curbe.c @@ -0,0 +1,368 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_state.h" +#include "brw_batch.h" +#include "brw_util.h" +#include "brw_wm.h" +#include "pipe/p_state.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#define FILE_DEBUG_FLAG DEBUG_FALLBACKS + +/* Partition the CURBE between the various users of constant values: + */ +static void calculate_curbe_offsets( struct brw_context *brw ) +{ + /* CACHE_NEW_WM_PROG */ + unsigned nr_fp_regs = align(brw->wm.prog_data->max_const, 16); + + /* BRW_NEW_VERTEX_PROGRAM */ + unsigned nr_vp_regs = align(brw->vs.prog_data->max_const, 16); + unsigned nr_clip_regs = 0; + unsigned total_regs; + +#if 0 + /* BRW_NEW_CLIP ? */ + if (brw->attribs.Transform->ClipPlanesEnabled) { + unsigned nr_planes = 6 + brw_count_bits(brw->attribs.Transform->ClipPlanesEnabled); + nr_clip_regs = align(nr_planes * 4, 16); + } +#endif + + + total_regs = nr_fp_regs + nr_vp_regs + nr_clip_regs; + + /* This can happen - what to do? Probably rather than falling + * back, the best thing to do is emit programs which code the + * constants as immediate values. Could do this either as a static + * cap on WM and VS, or adaptively. + * + * Unfortunately, this is currently dependent on the results of the + * program generation process (in the case of wm), so this would + * introduce the need to re-generate programs in the event of a + * curbe allocation failure. + */ + /* Max size is 32 - just large enough to + * hold the 128 parameters allowed by + * the fragment and vertex program + * api's. It's not clear what happens + * when both VP and FP want to use 128 + * parameters, though. + */ + assert(total_regs <= 32); + + /* Lazy resize: + */ + if (nr_fp_regs > brw->curbe.wm_size || + nr_vp_regs > brw->curbe.vs_size || + nr_clip_regs != brw->curbe.clip_size || + (total_regs < brw->curbe.total_size / 4 && + brw->curbe.total_size > 16)) { + + unsigned reg = 0; + + /* Calculate a new layout: + */ + reg = 0; + brw->curbe.wm_start = reg; + brw->curbe.wm_size = nr_fp_regs; reg += nr_fp_regs; + brw->curbe.clip_start = reg; + brw->curbe.clip_size = nr_clip_regs; reg += nr_clip_regs; + brw->curbe.vs_start = reg; + brw->curbe.vs_size = nr_vp_regs; reg += nr_vp_regs; + brw->curbe.total_size = reg; + +#if 0 + if (0) + DBG("curbe wm %d+%d clip %d+%d vs %d+%d\n", + brw->curbe.wm_start, + brw->curbe.wm_size, + brw->curbe.clip_start, + brw->curbe.clip_size, + brw->curbe.vs_start, + brw->curbe.vs_size ); +#endif + + brw->state.dirty.brw |= BRW_NEW_CURBE_OFFSETS; + } +} + + +const struct brw_tracked_state brw_curbe_offsets = { + .dirty = { + .brw = (BRW_NEW_CLIP | + BRW_NEW_VS), + .cache = CACHE_NEW_WM_PROG + }, + .update = calculate_curbe_offsets +}; + + + +/* Define the number of curbes within CS's urb allocation. Multiple + * urb entries -> multiple curbes. These will be used by + * fixed-function hardware in a double-buffering scheme to avoid a + * pipeline stall each time the contents of the curbe is changed. + */ +void brw_upload_constant_buffer_state(struct brw_context *brw) +{ + struct brw_constant_buffer_state cbs; + memset(&cbs, 0, sizeof(cbs)); + + /* It appears that this is the state packet for the CS unit, ie. the + * urb entries detailed here are housed in the CS range from the + * URB_FENCE command. + */ + cbs.header.opcode = CMD_CONST_BUFFER_STATE; + cbs.header.length = sizeof(cbs)/4 - 2; + + /* BRW_NEW_URB_FENCE */ + cbs.bits0.nr_urb_entries = brw->urb.nr_cs_entries; + cbs.bits0.urb_entry_size = brw->urb.csize - 1; + + assert(brw->urb.nr_cs_entries); + BRW_CACHED_BATCH_STRUCT(brw, &cbs); +} + + +static float fixed_plane[6][4] = { + { 0, 0, -1, 1 }, + { 0, 0, 1, 1 }, + { 0, -1, 0, 1 }, + { 0, 1, 0, 1 }, + {-1, 0, 0, 1 }, + { 1, 0, 0, 1 } +}; + +/* Upload a new set of constants. Too much variability to go into the + * cache mechanism, but maybe would benefit from a comparison against + * the current uploaded set of constants. + */ +static void upload_constant_buffer(struct brw_context *brw) +{ + struct brw_mem_pool *pool = &brw->pool[BRW_GS_POOL]; + unsigned sz = brw->curbe.total_size; + unsigned bufsz = sz * sizeof(float); + float *buf; + unsigned i; + + + if (sz == 0) { + struct brw_constant_buffer cb; + cb.header.opcode = CMD_CONST_BUFFER; + cb.header.length = sizeof(cb)/4 - 2; + cb.header.valid = 0; + cb.bits0.buffer_length = 0; + cb.bits0.buffer_address = 0; + BRW_BATCH_STRUCT(brw, &cb); + + if (brw->curbe.last_buf) { + free(brw->curbe.last_buf); + brw->curbe.last_buf = NULL; + brw->curbe.last_bufsz = 0; + } + + return; + } + + buf = (float *)malloc(bufsz); + + memset(buf, 0, bufsz); + + if (brw->curbe.wm_size) { + unsigned offset = brw->curbe.wm_start * 16; + + /* First the constant buffer constants: + */ + + /* Then any internally generated constants: + */ + for (i = 0; i < brw->wm.prog_data->nr_internal_consts; i++) + buf[offset + i] = brw->wm.prog_data->internal_const[i]; + + assert(brw->wm.prog_data->max_const == + brw->wm.prog_data->nr_internal_consts); + } + + + /* The clipplanes are actually delivered to both CLIP and VS units. + * VS uses them to calculate the outcode bitmasks. + */ + if (brw->curbe.clip_size) { + unsigned offset = brw->curbe.clip_start * 16; + unsigned j; + + /* If any planes are going this way, send them all this way: + */ + for (i = 0; i < 6; i++) { + buf[offset + i * 4 + 0] = fixed_plane[i][0]; + buf[offset + i * 4 + 1] = fixed_plane[i][1]; + buf[offset + i * 4 + 2] = fixed_plane[i][2]; + buf[offset + i * 4 + 3] = fixed_plane[i][3]; + } + + /* Clip planes: BRW_NEW_CLIP: + */ + for (j = 0; j < brw->attribs.Clip.nr; j++) { + buf[offset + i * 4 + 0] = brw->attribs.Clip.ucp[j][0]; + buf[offset + i * 4 + 1] = brw->attribs.Clip.ucp[j][1]; + buf[offset + i * 4 + 2] = brw->attribs.Clip.ucp[j][2]; + buf[offset + i * 4 + 3] = brw->attribs.Clip.ucp[j][3]; + i++; + } + } + + + if (brw->curbe.vs_size) { + unsigned offset = brw->curbe.vs_start * 16; + /*unsigned nr = vp->max_const;*/ + const struct pipe_constant_buffer *cbuffer = brw->attribs.Constants[0]; + struct pipe_winsys *ws = brw->pipe.winsys; + /* FIXME: buffer size is num_consts + num_immediates */ + if (brw->vs.prog_data->num_consts) { + /* map the vertex constant buffer and copy to curbe: */ + void *data = ws->buffer_map(ws, cbuffer->buffer, 0); + /* FIXME: this is wrong. the cbuffer->size currently + * represents size of consts + immediates. so if we'll + * have both we'll copy over the end of the buffer + * with the subsequent memcpy */ + memcpy(&buf[offset], data, cbuffer->size); + ws->buffer_unmap(ws, cbuffer->buffer); + offset += cbuffer->size; + } + /*immediates*/ + if (brw->vs.prog_data->num_imm) { + memcpy(&buf[offset], brw->vs.prog_data->imm_buf, + brw->vs.prog_data->num_imm * 4 * sizeof(float)); + } + } + + if (1) { + for (i = 0; i < sz; i+=4) + debug_printf("curbe %d.%d: %f %f %f %f\n", i/8, i&4, + buf[i+0], buf[i+1], buf[i+2], buf[i+3]); + + debug_printf("last_buf %p buf %p sz %d/%d cmp %d\n", + brw->curbe.last_buf, buf, + bufsz, brw->curbe.last_bufsz, + brw->curbe.last_buf ? memcmp(buf, brw->curbe.last_buf, bufsz) : -1); + } + + if (brw->curbe.last_buf && + bufsz == brw->curbe.last_bufsz && + memcmp(buf, brw->curbe.last_buf, bufsz) == 0) { + free(buf); +/* return; */ + } + else { + if (brw->curbe.last_buf) + free(brw->curbe.last_buf); + brw->curbe.last_buf = buf; + brw->curbe.last_bufsz = bufsz; + + + if (!brw_pool_alloc(pool, + bufsz, + 1 << 6, + &brw->curbe.gs_offset)) { + debug_printf("out of GS memory for curbe\n"); + assert(0); + return; + } + + + /* Copy data to the buffer: + */ + brw->winsys->buffer_subdata_typed(brw->winsys, + pool->buffer, + brw->curbe.gs_offset, + bufsz, + buf, + BRW_CONSTANT_BUFFER ); + } + + /* TODO: only emit the constant_buffer packet when necessary, ie: + - contents have changed + - offset has changed + - hw requirements due to other packets emitted. + */ + { + struct brw_constant_buffer cb; + + memset(&cb, 0, sizeof(cb)); + + cb.header.opcode = CMD_CONST_BUFFER; + cb.header.length = sizeof(cb)/4 - 2; + cb.header.valid = 1; + cb.bits0.buffer_length = sz - 1; + cb.bits0.buffer_address = brw->curbe.gs_offset >> 6; + + /* Because this provokes an action (ie copy the constants into the + * URB), it shouldn't be shortcircuited if identical to the + * previous time - because eg. the urb destination may have + * changed, or the urb contents different to last time. + * + * Note that the data referred to is actually copied internally, + * not just used in place according to passed pointer. + * + * It appears that the CS unit takes care of using each available + * URB entry (Const URB Entry == CURBE) in turn, and issuing + * flushes as necessary when doublebuffering of CURBEs isn't + * possible. + */ + BRW_BATCH_STRUCT(brw, &cb); + } +} + +/* This tracked state is unique in that the state it monitors varies + * dynamically depending on the parameters tracked by the fragment and + * vertex programs. This is the template used as a starting point, + * each context will maintain a copy of this internally and update as + * required. + */ +const struct brw_tracked_state brw_constant_buffer = { + .dirty = { + .brw = (BRW_NEW_CLIP | + BRW_NEW_CONSTANTS | + BRW_NEW_URB_FENCE | /* Implicit - hardware requires this, not used above */ + BRW_NEW_PSP | /* Implicit - hardware requires this, not used above */ + BRW_NEW_CURBE_OFFSETS), + .cache = (CACHE_NEW_WM_PROG) + }, + .update = upload_constant_buffer +}; + diff --git a/src/gallium/drivers/i965simple/brw_defines.h b/src/gallium/drivers/i965simple/brw_defines.h new file mode 100644 index 0000000000..9379a397f6 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_defines.h @@ -0,0 +1,852 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRW_DEFINES_H +#define BRW_DEFINES_H + +/* + */ +#define MI_NOOP 0x00 +#define MI_USER_INTERRUPT 0x02 +#define MI_WAIT_FOR_EVENT 0x03 +#define MI_FLUSH 0x04 +#define MI_REPORT_HEAD 0x07 +#define MI_ARB_ON_OFF 0x08 +#define MI_BATCH_BUFFER_END 0x0A +#define MI_OVERLAY_FLIP 0x11 +#define MI_LOAD_SCAN_LINES_INCL 0x12 +#define MI_LOAD_SCAN_LINES_EXCL 0x13 +#define MI_DISPLAY_BUFFER_INFO 0x14 +#define MI_SET_CONTEXT 0x18 +#define MI_STORE_DATA_IMM 0x20 +#define MI_STORE_DATA_INDEX 0x21 +#define MI_LOAD_REGISTER_IMM 0x22 +#define MI_STORE_REGISTER_MEM 0x24 +#define MI_BATCH_BUFFER_START 0x31 + +#define MI_SYNCHRONOUS_FLIP 0x0 +#define MI_ASYNCHRONOUS_FLIP 0x1 + +#define MI_BUFFER_SECURE 0x0 +#define MI_BUFFER_NONSECURE 0x1 + +#define MI_ARBITRATE_AT_CHAIN_POINTS 0x0 +#define MI_ARBITRATE_BETWEEN_INSTS 0x1 +#define MI_NO_ARBITRATION 0x3 + +#define MI_CONDITION_CODE_WAIT_DISABLED 0x0 +#define MI_CONDITION_CODE_WAIT_0 0x1 +#define MI_CONDITION_CODE_WAIT_1 0x2 +#define MI_CONDITION_CODE_WAIT_2 0x3 +#define MI_CONDITION_CODE_WAIT_3 0x4 +#define MI_CONDITION_CODE_WAIT_4 0x5 + +#define MI_DISPLAY_PIPE_A 0x0 +#define MI_DISPLAY_PIPE_B 0x1 + +#define MI_DISPLAY_PLANE_A 0x0 +#define MI_DISPLAY_PLANE_B 0x1 +#define MI_DISPLAY_PLANE_C 0x2 + +#define MI_STANDARD_FLIP 0x0 +#define MI_ENQUEUE_FLIP_PERFORM_BASE_FRAME_NUMBER_LOAD 0x1 +#define MI_ENQUEUE_FLIP_TARGET_FRAME_NUMBER_RELATIVE 0x2 +#define MI_ENQUEUE_FLIP_ABSOLUTE_TARGET_FRAME_NUMBER 0x3 + +#define MI_PHYSICAL_ADDRESS 0x0 +#define MI_VIRTUAL_ADDRESS 0x1 + +#define MI_BUFFER_MEMORY_MAIN 0x0 +#define MI_BUFFER_MEMORY_GTT 0x2 +#define MI_BUFFER_MEMORY_PER_PROCESS_GTT 0x3 + +#define MI_FLIP_CONTINUE 0x0 +#define MI_FLIP_ON 0x1 +#define MI_FLIP_OFF 0x2 + +#define MI_UNTRUSTED_REGISTER_SPACE 0x0 +#define MI_TRUSTED_REGISTER_SPACE 0x1 + +/* 3D state: + */ +#define _3DOP_3DSTATE_PIPELINED 0x0 +#define _3DOP_3DSTATE_NONPIPELINED 0x1 +#define _3DOP_3DCONTROL 0x2 +#define _3DOP_3DPRIMITIVE 0x3 + +#define _3DSTATE_PIPELINED_POINTERS 0x00 +#define _3DSTATE_BINDING_TABLE_POINTERS 0x01 +#define _3DSTATE_VERTEX_BUFFERS 0x08 +#define _3DSTATE_VERTEX_ELEMENTS 0x09 +#define _3DSTATE_INDEX_BUFFER 0x0A +#define _3DSTATE_VF_STATISTICS 0x0B +#define _3DSTATE_DRAWING_RECTANGLE 0x00 +#define _3DSTATE_CONSTANT_COLOR 0x01 +#define _3DSTATE_SAMPLER_PALETTE_LOAD 0x02 +#define _3DSTATE_CHROMA_KEY 0x04 +#define _3DSTATE_DEPTH_BUFFER 0x05 +#define _3DSTATE_POLY_STIPPLE_OFFSET 0x06 +#define _3DSTATE_POLY_STIPPLE_PATTERN 0x07 +#define _3DSTATE_LINE_STIPPLE 0x08 +#define _3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP 0x09 +#define _3DCONTROL 0x00 +#define _3DPRIMITIVE 0x00 + +#define PIPE_CONTROL_NOWRITE 0x00 +#define PIPE_CONTROL_WRITEIMMEDIATE 0x01 +#define PIPE_CONTROL_WRITEDEPTH 0x02 +#define PIPE_CONTROL_WRITETIMESTAMP 0x03 + +#define PIPE_CONTROL_GTTWRITE_PROCESS_LOCAL 0x00 +#define PIPE_CONTROL_GTTWRITE_GLOBAL 0x01 + +#define _3DPRIM_POINTLIST 0x01 +#define _3DPRIM_LINELIST 0x02 +#define _3DPRIM_LINESTRIP 0x03 +#define _3DPRIM_TRILIST 0x04 +#define _3DPRIM_TRISTRIP 0x05 +#define _3DPRIM_TRIFAN 0x06 +#define _3DPRIM_QUADLIST 0x07 +#define _3DPRIM_QUADSTRIP 0x08 +#define _3DPRIM_LINELIST_ADJ 0x09 +#define _3DPRIM_LINESTRIP_ADJ 0x0A +#define _3DPRIM_TRILIST_ADJ 0x0B +#define _3DPRIM_TRISTRIP_ADJ 0x0C +#define _3DPRIM_TRISTRIP_REVERSE 0x0D +#define _3DPRIM_POLYGON 0x0E +#define _3DPRIM_RECTLIST 0x0F +#define _3DPRIM_LINELOOP 0x10 +#define _3DPRIM_POINTLIST_BF 0x11 +#define _3DPRIM_LINESTRIP_CONT 0x12 +#define _3DPRIM_LINESTRIP_BF 0x13 +#define _3DPRIM_LINESTRIP_CONT_BF 0x14 +#define _3DPRIM_TRIFAN_NOSTIPPLE 0x15 + +#define _3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL 0 +#define _3DPRIM_VERTEXBUFFER_ACCESS_RANDOM 1 + +#define BRW_ANISORATIO_2 0 +#define BRW_ANISORATIO_4 1 +#define BRW_ANISORATIO_6 2 +#define BRW_ANISORATIO_8 3 +#define BRW_ANISORATIO_10 4 +#define BRW_ANISORATIO_12 5 +#define BRW_ANISORATIO_14 6 +#define BRW_ANISORATIO_16 7 + +#define BRW_BLENDFACTOR_ONE 0x1 +#define BRW_BLENDFACTOR_SRC_COLOR 0x2 +#define BRW_BLENDFACTOR_SRC_ALPHA 0x3 +#define BRW_BLENDFACTOR_DST_ALPHA 0x4 +#define BRW_BLENDFACTOR_DST_COLOR 0x5 +#define BRW_BLENDFACTOR_SRC_ALPHA_SATURATE 0x6 +#define BRW_BLENDFACTOR_CONST_COLOR 0x7 +#define BRW_BLENDFACTOR_CONST_ALPHA 0x8 +#define BRW_BLENDFACTOR_SRC1_COLOR 0x9 +#define BRW_BLENDFACTOR_SRC1_ALPHA 0x0A +#define BRW_BLENDFACTOR_ZERO 0x11 +#define BRW_BLENDFACTOR_INV_SRC_COLOR 0x12 +#define BRW_BLENDFACTOR_INV_SRC_ALPHA 0x13 +#define BRW_BLENDFACTOR_INV_DST_ALPHA 0x14 +#define BRW_BLENDFACTOR_INV_DST_COLOR 0x15 +#define BRW_BLENDFACTOR_INV_CONST_COLOR 0x17 +#define BRW_BLENDFACTOR_INV_CONST_ALPHA 0x18 +#define BRW_BLENDFACTOR_INV_SRC1_COLOR 0x19 +#define BRW_BLENDFACTOR_INV_SRC1_ALPHA 0x1A + +#define BRW_BLENDFUNCTION_ADD 0 +#define BRW_BLENDFUNCTION_SUBTRACT 1 +#define BRW_BLENDFUNCTION_REVERSE_SUBTRACT 2 +#define BRW_BLENDFUNCTION_MIN 3 +#define BRW_BLENDFUNCTION_MAX 4 + +#define BRW_ALPHATEST_FORMAT_UNORM8 0 +#define BRW_ALPHATEST_FORMAT_FLOAT32 1 + +#define BRW_CHROMAKEY_KILL_ON_ANY_MATCH 0 +#define BRW_CHROMAKEY_REPLACE_BLACK 1 + +#define BRW_CLIP_API_OGL 0 +#define BRW_CLIP_API_DX 1 + +#define BRW_CLIPMODE_NORMAL 0 +#define BRW_CLIPMODE_CLIP_ALL 1 +#define BRW_CLIPMODE_CLIP_NON_REJECTED 2 +#define BRW_CLIPMODE_REJECT_ALL 3 +#define BRW_CLIPMODE_ACCEPT_ALL 4 + +#define BRW_CLIP_NDCSPACE 0 +#define BRW_CLIP_SCREENSPACE 1 + +#define BRW_COMPAREFUNCTION_ALWAYS 0 +#define BRW_COMPAREFUNCTION_NEVER 1 +#define BRW_COMPAREFUNCTION_LESS 2 +#define BRW_COMPAREFUNCTION_EQUAL 3 +#define BRW_COMPAREFUNCTION_LEQUAL 4 +#define BRW_COMPAREFUNCTION_GREATER 5 +#define BRW_COMPAREFUNCTION_NOTEQUAL 6 +#define BRW_COMPAREFUNCTION_GEQUAL 7 + +#define BRW_COVERAGE_PIXELS_HALF 0 +#define BRW_COVERAGE_PIXELS_1 1 +#define BRW_COVERAGE_PIXELS_2 2 +#define BRW_COVERAGE_PIXELS_4 3 + +#define BRW_CULLMODE_BOTH 0 +#define BRW_CULLMODE_NONE 1 +#define BRW_CULLMODE_FRONT 2 +#define BRW_CULLMODE_BACK 3 + +#define BRW_DEFAULTCOLOR_R8G8B8A8_UNORM 0 +#define BRW_DEFAULTCOLOR_R32G32B32A32_FLOAT 1 + +#define BRW_DEPTHFORMAT_D32_FLOAT_S8X24_UINT 0 +#define BRW_DEPTHFORMAT_D32_FLOAT 1 +#define BRW_DEPTHFORMAT_D24_UNORM_S8_UINT 2 +#define BRW_DEPTHFORMAT_D16_UNORM 5 + +#define BRW_FLOATING_POINT_IEEE_754 0 +#define BRW_FLOATING_POINT_NON_IEEE_754 1 + +#define BRW_FRONTWINDING_CW 0 +#define BRW_FRONTWINDING_CCW 1 + +#define BRW_SPRITE_POINT_ENABLE 16 + +#define BRW_INDEX_BYTE 0 +#define BRW_INDEX_WORD 1 +#define BRW_INDEX_DWORD 2 + +#define BRW_LOGICOPFUNCTION_CLEAR 0 +#define BRW_LOGICOPFUNCTION_NOR 1 +#define BRW_LOGICOPFUNCTION_AND_INVERTED 2 +#define BRW_LOGICOPFUNCTION_COPY_INVERTED 3 +#define BRW_LOGICOPFUNCTION_AND_REVERSE 4 +#define BRW_LOGICOPFUNCTION_INVERT 5 +#define BRW_LOGICOPFUNCTION_XOR 6 +#define BRW_LOGICOPFUNCTION_NAND 7 +#define BRW_LOGICOPFUNCTION_AND 8 +#define BRW_LOGICOPFUNCTION_EQUIV 9 +#define BRW_LOGICOPFUNCTION_NOOP 10 +#define BRW_LOGICOPFUNCTION_OR_INVERTED 11 +#define BRW_LOGICOPFUNCTION_COPY 12 +#define BRW_LOGICOPFUNCTION_OR_REVERSE 13 +#define BRW_LOGICOPFUNCTION_OR 14 +#define BRW_LOGICOPFUNCTION_SET 15 + +#define BRW_MAPFILTER_NEAREST 0x0 +#define BRW_MAPFILTER_LINEAR 0x1 +#define BRW_MAPFILTER_ANISOTROPIC 0x2 + +#define BRW_MIPFILTER_NONE 0 +#define BRW_MIPFILTER_NEAREST 1 +#define BRW_MIPFILTER_LINEAR 3 + +#define BRW_POLYGON_FRONT_FACING 0 +#define BRW_POLYGON_BACK_FACING 1 + +#define BRW_PREFILTER_ALWAYS 0x0 +#define BRW_PREFILTER_NEVER 0x1 +#define BRW_PREFILTER_LESS 0x2 +#define BRW_PREFILTER_EQUAL 0x3 +#define BRW_PREFILTER_LEQUAL 0x4 +#define BRW_PREFILTER_GREATER 0x5 +#define BRW_PREFILTER_NOTEQUAL 0x6 +#define BRW_PREFILTER_GEQUAL 0x7 + +#define BRW_PROVOKING_VERTEX_0 0 +#define BRW_PROVOKING_VERTEX_1 1 +#define BRW_PROVOKING_VERTEX_2 2 + +#define BRW_RASTRULE_UPPER_LEFT 0 +#define BRW_RASTRULE_UPPER_RIGHT 1 + +#define BRW_RENDERTARGET_CLAMPRANGE_UNORM 0 +#define BRW_RENDERTARGET_CLAMPRANGE_SNORM 1 +#define BRW_RENDERTARGET_CLAMPRANGE_FORMAT 2 + +#define BRW_STENCILOP_KEEP 0 +#define BRW_STENCILOP_ZERO 1 +#define BRW_STENCILOP_REPLACE 2 +#define BRW_STENCILOP_INCRSAT 3 +#define BRW_STENCILOP_DECRSAT 4 +#define BRW_STENCILOP_INCR 5 +#define BRW_STENCILOP_DECR 6 +#define BRW_STENCILOP_INVERT 7 + +#define BRW_SURFACE_MIPMAPLAYOUT_BELOW 0 +#define BRW_SURFACE_MIPMAPLAYOUT_RIGHT 1 + +#define BRW_SURFACEFORMAT_R32G32B32A32_FLOAT 0x000 +#define BRW_SURFACEFORMAT_R32G32B32A32_SINT 0x001 +#define BRW_SURFACEFORMAT_R32G32B32A32_UINT 0x002 +#define BRW_SURFACEFORMAT_R32G32B32A32_UNORM 0x003 +#define BRW_SURFACEFORMAT_R32G32B32A32_SNORM 0x004 +#define BRW_SURFACEFORMAT_R64G64_FLOAT 0x005 +#define BRW_SURFACEFORMAT_R32G32B32X32_FLOAT 0x006 +#define BRW_SURFACEFORMAT_R32G32B32A32_SSCALED 0x007 +#define BRW_SURFACEFORMAT_R32G32B32A32_USCALED 0x008 +#define BRW_SURFACEFORMAT_R32G32B32_FLOAT 0x040 +#define BRW_SURFACEFORMAT_R32G32B32_SINT 0x041 +#define BRW_SURFACEFORMAT_R32G32B32_UINT 0x042 +#define BRW_SURFACEFORMAT_R32G32B32_UNORM 0x043 +#define BRW_SURFACEFORMAT_R32G32B32_SNORM 0x044 +#define BRW_SURFACEFORMAT_R32G32B32_SSCALED 0x045 +#define BRW_SURFACEFORMAT_R32G32B32_USCALED 0x046 +#define BRW_SURFACEFORMAT_R16G16B16A16_UNORM 0x080 +#define BRW_SURFACEFORMAT_R16G16B16A16_SNORM 0x081 +#define BRW_SURFACEFORMAT_R16G16B16A16_SINT 0x082 +#define BRW_SURFACEFORMAT_R16G16B16A16_UINT 0x083 +#define BRW_SURFACEFORMAT_R16G16B16A16_FLOAT 0x084 +#define BRW_SURFACEFORMAT_R32G32_FLOAT 0x085 +#define BRW_SURFACEFORMAT_R32G32_SINT 0x086 +#define BRW_SURFACEFORMAT_R32G32_UINT 0x087 +#define BRW_SURFACEFORMAT_R32_FLOAT_X8X24_TYPELESS 0x088 +#define BRW_SURFACEFORMAT_X32_TYPELESS_G8X24_UINT 0x089 +#define BRW_SURFACEFORMAT_L32A32_FLOAT 0x08A +#define BRW_SURFACEFORMAT_R32G32_UNORM 0x08B +#define BRW_SURFACEFORMAT_R32G32_SNORM 0x08C +#define BRW_SURFACEFORMAT_R64_FLOAT 0x08D +#define BRW_SURFACEFORMAT_R16G16B16X16_UNORM 0x08E +#define BRW_SURFACEFORMAT_R16G16B16X16_FLOAT 0x08F +#define BRW_SURFACEFORMAT_A32X32_FLOAT 0x090 +#define BRW_SURFACEFORMAT_L32X32_FLOAT 0x091 +#define BRW_SURFACEFORMAT_I32X32_FLOAT 0x092 +#define BRW_SURFACEFORMAT_R16G16B16A16_SSCALED 0x093 +#define BRW_SURFACEFORMAT_R16G16B16A16_USCALED 0x094 +#define BRW_SURFACEFORMAT_R32G32_SSCALED 0x095 +#define BRW_SURFACEFORMAT_R32G32_USCALED 0x096 +#define BRW_SURFACEFORMAT_B8G8R8A8_UNORM 0x0C0 +#define BRW_SURFACEFORMAT_B8G8R8A8_UNORM_SRGB 0x0C1 +#define BRW_SURFACEFORMAT_R10G10B10A2_UNORM 0x0C2 +#define BRW_SURFACEFORMAT_R10G10B10A2_UNORM_SRGB 0x0C3 +#define BRW_SURFACEFORMAT_R10G10B10A2_UINT 0x0C4 +#define BRW_SURFACEFORMAT_R10G10B10_SNORM_A2_UNORM 0x0C5 +#define BRW_SURFACEFORMAT_R8G8B8A8_UNORM 0x0C7 +#define BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB 0x0C8 +#define BRW_SURFACEFORMAT_R8G8B8A8_SNORM 0x0C9 +#define BRW_SURFACEFORMAT_R8G8B8A8_SINT 0x0CA +#define BRW_SURFACEFORMAT_R8G8B8A8_UINT 0x0CB +#define BRW_SURFACEFORMAT_R16G16_UNORM 0x0CC +#define BRW_SURFACEFORMAT_R16G16_SNORM 0x0CD +#define BRW_SURFACEFORMAT_R16G16_SINT 0x0CE +#define BRW_SURFACEFORMAT_R16G16_UINT 0x0CF +#define BRW_SURFACEFORMAT_R16G16_FLOAT 0x0D0 +#define BRW_SURFACEFORMAT_B10G10R10A2_UNORM 0x0D1 +#define BRW_SURFACEFORMAT_B10G10R10A2_UNORM_SRGB 0x0D2 +#define BRW_SURFACEFORMAT_R11G11B10_FLOAT 0x0D3 +#define BRW_SURFACEFORMAT_R32_SINT 0x0D6 +#define BRW_SURFACEFORMAT_R32_UINT 0x0D7 +#define BRW_SURFACEFORMAT_R32_FLOAT 0x0D8 +#define BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS 0x0D9 +#define BRW_SURFACEFORMAT_X24_TYPELESS_G8_UINT 0x0DA +#define BRW_SURFACEFORMAT_L16A16_UNORM 0x0DF +#define BRW_SURFACEFORMAT_I24X8_UNORM 0x0E0 +#define BRW_SURFACEFORMAT_L24X8_UNORM 0x0E1 +#define BRW_SURFACEFORMAT_A24X8_UNORM 0x0E2 +#define BRW_SURFACEFORMAT_I32_FLOAT 0x0E3 +#define BRW_SURFACEFORMAT_L32_FLOAT 0x0E4 +#define BRW_SURFACEFORMAT_A32_FLOAT 0x0E5 +#define BRW_SURFACEFORMAT_B8G8R8X8_UNORM 0x0E9 +#define BRW_SURFACEFORMAT_B8G8R8X8_UNORM_SRGB 0x0EA +#define BRW_SURFACEFORMAT_R8G8B8X8_UNORM 0x0EB +#define BRW_SURFACEFORMAT_R8G8B8X8_UNORM_SRGB 0x0EC +#define BRW_SURFACEFORMAT_R9G9B9E5_SHAREDEXP 0x0ED +#define BRW_SURFACEFORMAT_B10G10R10X2_UNORM 0x0EE +#define BRW_SURFACEFORMAT_L16A16_FLOAT 0x0F0 +#define BRW_SURFACEFORMAT_R32_UNORM 0x0F1 +#define BRW_SURFACEFORMAT_R32_SNORM 0x0F2 +#define BRW_SURFACEFORMAT_R10G10B10X2_USCALED 0x0F3 +#define BRW_SURFACEFORMAT_R8G8B8A8_SSCALED 0x0F4 +#define BRW_SURFACEFORMAT_R8G8B8A8_USCALED 0x0F5 +#define BRW_SURFACEFORMAT_R16G16_SSCALED 0x0F6 +#define BRW_SURFACEFORMAT_R16G16_USCALED 0x0F7 +#define BRW_SURFACEFORMAT_R32_SSCALED 0x0F8 +#define BRW_SURFACEFORMAT_R32_USCALED 0x0F9 +#define BRW_SURFACEFORMAT_B5G6R5_UNORM 0x100 +#define BRW_SURFACEFORMAT_B5G6R5_UNORM_SRGB 0x101 +#define BRW_SURFACEFORMAT_B5G5R5A1_UNORM 0x102 +#define BRW_SURFACEFORMAT_B5G5R5A1_UNORM_SRGB 0x103 +#define BRW_SURFACEFORMAT_B4G4R4A4_UNORM 0x104 +#define BRW_SURFACEFORMAT_B4G4R4A4_UNORM_SRGB 0x105 +#define BRW_SURFACEFORMAT_R8G8_UNORM 0x106 +#define BRW_SURFACEFORMAT_R8G8_SNORM 0x107 +#define BRW_SURFACEFORMAT_R8G8_SINT 0x108 +#define BRW_SURFACEFORMAT_R8G8_UINT 0x109 +#define BRW_SURFACEFORMAT_R16_UNORM 0x10A +#define BRW_SURFACEFORMAT_R16_SNORM 0x10B +#define BRW_SURFACEFORMAT_R16_SINT 0x10C +#define BRW_SURFACEFORMAT_R16_UINT 0x10D +#define BRW_SURFACEFORMAT_R16_FLOAT 0x10E +#define BRW_SURFACEFORMAT_I16_UNORM 0x111 +#define BRW_SURFACEFORMAT_L16_UNORM 0x112 +#define BRW_SURFACEFORMAT_A16_UNORM 0x113 +#define BRW_SURFACEFORMAT_L8A8_UNORM 0x114 +#define BRW_SURFACEFORMAT_I16_FLOAT 0x115 +#define BRW_SURFACEFORMAT_L16_FLOAT 0x116 +#define BRW_SURFACEFORMAT_A16_FLOAT 0x117 +#define BRW_SURFACEFORMAT_R5G5_SNORM_B6_UNORM 0x119 +#define BRW_SURFACEFORMAT_B5G5R5X1_UNORM 0x11A +#define BRW_SURFACEFORMAT_B5G5R5X1_UNORM_SRGB 0x11B +#define BRW_SURFACEFORMAT_R8G8_SSCALED 0x11C +#define BRW_SURFACEFORMAT_R8G8_USCALED 0x11D +#define BRW_SURFACEFORMAT_R16_SSCALED 0x11E +#define BRW_SURFACEFORMAT_R16_USCALED 0x11F +#define BRW_SURFACEFORMAT_R8_UNORM 0x140 +#define BRW_SURFACEFORMAT_R8_SNORM 0x141 +#define BRW_SURFACEFORMAT_R8_SINT 0x142 +#define BRW_SURFACEFORMAT_R8_UINT 0x143 +#define BRW_SURFACEFORMAT_A8_UNORM 0x144 +#define BRW_SURFACEFORMAT_I8_UNORM 0x145 +#define BRW_SURFACEFORMAT_L8_UNORM 0x146 +#define BRW_SURFACEFORMAT_P4A4_UNORM 0x147 +#define BRW_SURFACEFORMAT_A4P4_UNORM 0x148 +#define BRW_SURFACEFORMAT_R8_SSCALED 0x149 +#define BRW_SURFACEFORMAT_R8_USCALED 0x14A +#define BRW_SURFACEFORMAT_R1_UINT 0x181 +#define BRW_SURFACEFORMAT_YCRCB_NORMAL 0x182 +#define BRW_SURFACEFORMAT_YCRCB_SWAPUVY 0x183 +#define BRW_SURFACEFORMAT_BC1_UNORM 0x186 +#define BRW_SURFACEFORMAT_BC2_UNORM 0x187 +#define BRW_SURFACEFORMAT_BC3_UNORM 0x188 +#define BRW_SURFACEFORMAT_BC4_UNORM 0x189 +#define BRW_SURFACEFORMAT_BC5_UNORM 0x18A +#define BRW_SURFACEFORMAT_BC1_UNORM_SRGB 0x18B +#define BRW_SURFACEFORMAT_BC2_UNORM_SRGB 0x18C +#define BRW_SURFACEFORMAT_BC3_UNORM_SRGB 0x18D +#define BRW_SURFACEFORMAT_MONO8 0x18E +#define BRW_SURFACEFORMAT_YCRCB_SWAPUV 0x18F +#define BRW_SURFACEFORMAT_YCRCB_SWAPY 0x190 +#define BRW_SURFACEFORMAT_DXT1_RGB 0x191 +#define BRW_SURFACEFORMAT_FXT1 0x192 +#define BRW_SURFACEFORMAT_R8G8B8_UNORM 0x193 +#define BRW_SURFACEFORMAT_R8G8B8_SNORM 0x194 +#define BRW_SURFACEFORMAT_R8G8B8_SSCALED 0x195 +#define BRW_SURFACEFORMAT_R8G8B8_USCALED 0x196 +#define BRW_SURFACEFORMAT_R64G64B64A64_FLOAT 0x197 +#define BRW_SURFACEFORMAT_R64G64B64_FLOAT 0x198 +#define BRW_SURFACEFORMAT_BC4_SNORM 0x199 +#define BRW_SURFACEFORMAT_BC5_SNORM 0x19A +#define BRW_SURFACEFORMAT_R16G16B16_UNORM 0x19C +#define BRW_SURFACEFORMAT_R16G16B16_SNORM 0x19D +#define BRW_SURFACEFORMAT_R16G16B16_SSCALED 0x19E +#define BRW_SURFACEFORMAT_R16G16B16_USCALED 0x19F + +#define BRW_SURFACERETURNFORMAT_FLOAT32 0 +#define BRW_SURFACERETURNFORMAT_S1 1 + +#define BRW_SURFACE_1D 0 +#define BRW_SURFACE_2D 1 +#define BRW_SURFACE_3D 2 +#define BRW_SURFACE_CUBE 3 +#define BRW_SURFACE_BUFFER 4 +#define BRW_SURFACE_NULL 7 + +#define BRW_TEXCOORDMODE_WRAP 0 +#define BRW_TEXCOORDMODE_MIRROR 1 +#define BRW_TEXCOORDMODE_CLAMP 2 +#define BRW_TEXCOORDMODE_CUBE 3 +#define BRW_TEXCOORDMODE_CLAMP_BORDER 4 +#define BRW_TEXCOORDMODE_MIRROR_ONCE 5 + +#define BRW_THREAD_PRIORITY_NORMAL 0 +#define BRW_THREAD_PRIORITY_HIGH 1 + +#define BRW_TILEWALK_XMAJOR 0 +#define BRW_TILEWALK_YMAJOR 1 + +#define BRW_VERTEX_SUBPIXEL_PRECISION_8BITS 0 +#define BRW_VERTEX_SUBPIXEL_PRECISION_4BITS 1 + +#define BRW_VERTEXBUFFER_ACCESS_VERTEXDATA 0 +#define BRW_VERTEXBUFFER_ACCESS_INSTANCEDATA 1 + +#define BRW_VFCOMPONENT_NOSTORE 0 +#define BRW_VFCOMPONENT_STORE_SRC 1 +#define BRW_VFCOMPONENT_STORE_0 2 +#define BRW_VFCOMPONENT_STORE_1_FLT 3 +#define BRW_VFCOMPONENT_STORE_1_INT 4 +#define BRW_VFCOMPONENT_STORE_VID 5 +#define BRW_VFCOMPONENT_STORE_IID 6 +#define BRW_VFCOMPONENT_STORE_PID 7 + + + +/* Execution Unit (EU) defines + */ + +#define BRW_ALIGN_1 0 +#define BRW_ALIGN_16 1 + +#define BRW_ADDRESS_DIRECT 0 +#define BRW_ADDRESS_REGISTER_INDIRECT_REGISTER 1 + +#define BRW_CHANNEL_X 0 +#define BRW_CHANNEL_Y 1 +#define BRW_CHANNEL_Z 2 +#define BRW_CHANNEL_W 3 + +#define BRW_COMPRESSION_NONE 0 +#define BRW_COMPRESSION_2NDHALF 1 +#define BRW_COMPRESSION_COMPRESSED 2 + +#define BRW_CONDITIONAL_NONE 0 +#define BRW_CONDITIONAL_Z 1 +#define BRW_CONDITIONAL_NZ 2 +#define BRW_CONDITIONAL_EQ 1 /* Z */ +#define BRW_CONDITIONAL_NEQ 2 /* NZ */ +#define BRW_CONDITIONAL_G 3 +#define BRW_CONDITIONAL_GE 4 +#define BRW_CONDITIONAL_L 5 +#define BRW_CONDITIONAL_LE 6 +#define BRW_CONDITIONAL_C 7 +#define BRW_CONDITIONAL_O 8 + +#define BRW_DEBUG_NONE 0 +#define BRW_DEBUG_BREAKPOINT 1 + +#define BRW_DEPENDENCY_NORMAL 0 +#define BRW_DEPENDENCY_NOTCLEARED 1 +#define BRW_DEPENDENCY_NOTCHECKED 2 +#define BRW_DEPENDENCY_DISABLE 3 + +#define BRW_EXECUTE_1 0 +#define BRW_EXECUTE_2 1 +#define BRW_EXECUTE_4 2 +#define BRW_EXECUTE_8 3 +#define BRW_EXECUTE_16 4 +#define BRW_EXECUTE_32 5 + +#define BRW_HORIZONTAL_STRIDE_0 0 +#define BRW_HORIZONTAL_STRIDE_1 1 +#define BRW_HORIZONTAL_STRIDE_2 2 +#define BRW_HORIZONTAL_STRIDE_4 3 + +#define BRW_INSTRUCTION_NORMAL 0 +#define BRW_INSTRUCTION_SATURATE 1 + +#define BRW_MASK_ENABLE 0 +#define BRW_MASK_DISABLE 1 + +#define BRW_OPCODE_MOV 1 +#define BRW_OPCODE_SEL 2 +#define BRW_OPCODE_NOT 4 +#define BRW_OPCODE_AND 5 +#define BRW_OPCODE_OR 6 +#define BRW_OPCODE_XOR 7 +#define BRW_OPCODE_SHR 8 +#define BRW_OPCODE_SHL 9 +#define BRW_OPCODE_RSR 10 +#define BRW_OPCODE_RSL 11 +#define BRW_OPCODE_ASR 12 +#define BRW_OPCODE_CMP 16 +#define BRW_OPCODE_JMPI 32 +#define BRW_OPCODE_IF 34 +#define BRW_OPCODE_IFF 35 +#define BRW_OPCODE_ELSE 36 +#define BRW_OPCODE_ENDIF 37 +#define BRW_OPCODE_DO 38 +#define BRW_OPCODE_WHILE 39 +#define BRW_OPCODE_BREAK 40 +#define BRW_OPCODE_CONTINUE 41 +#define BRW_OPCODE_HALT 42 +#define BRW_OPCODE_MSAVE 44 +#define BRW_OPCODE_MRESTORE 45 +#define BRW_OPCODE_PUSH 46 +#define BRW_OPCODE_POP 47 +#define BRW_OPCODE_WAIT 48 +#define BRW_OPCODE_SEND 49 +#define BRW_OPCODE_ADD 64 +#define BRW_OPCODE_MUL 65 +#define BRW_OPCODE_AVG 66 +#define BRW_OPCODE_FRC 67 +#define BRW_OPCODE_RNDU 68 +#define BRW_OPCODE_RNDD 69 +#define BRW_OPCODE_RNDE 70 +#define BRW_OPCODE_RNDZ 71 +#define BRW_OPCODE_MAC 72 +#define BRW_OPCODE_MACH 73 +#define BRW_OPCODE_LZD 74 +#define BRW_OPCODE_SAD2 80 +#define BRW_OPCODE_SADA2 81 +#define BRW_OPCODE_DP4 84 +#define BRW_OPCODE_DPH 85 +#define BRW_OPCODE_DP3 86 +#define BRW_OPCODE_DP2 87 +#define BRW_OPCODE_DPA2 88 +#define BRW_OPCODE_LINE 89 +#define BRW_OPCODE_NOP 126 + +#define BRW_PREDICATE_NONE 0 +#define BRW_PREDICATE_NORMAL 1 +#define BRW_PREDICATE_ALIGN1_ANYV 2 +#define BRW_PREDICATE_ALIGN1_ALLV 3 +#define BRW_PREDICATE_ALIGN1_ANY2H 4 +#define BRW_PREDICATE_ALIGN1_ALL2H 5 +#define BRW_PREDICATE_ALIGN1_ANY4H 6 +#define BRW_PREDICATE_ALIGN1_ALL4H 7 +#define BRW_PREDICATE_ALIGN1_ANY8H 8 +#define BRW_PREDICATE_ALIGN1_ALL8H 9 +#define BRW_PREDICATE_ALIGN1_ANY16H 10 +#define BRW_PREDICATE_ALIGN1_ALL16H 11 +#define BRW_PREDICATE_ALIGN16_REPLICATE_X 2 +#define BRW_PREDICATE_ALIGN16_REPLICATE_Y 3 +#define BRW_PREDICATE_ALIGN16_REPLICATE_Z 4 +#define BRW_PREDICATE_ALIGN16_REPLICATE_W 5 +#define BRW_PREDICATE_ALIGN16_ANY4H 6 +#define BRW_PREDICATE_ALIGN16_ALL4H 7 + +#define BRW_ARCHITECTURE_REGISTER_FILE 0 +#define BRW_GENERAL_REGISTER_FILE 1 +#define BRW_MESSAGE_REGISTER_FILE 2 +#define BRW_IMMEDIATE_VALUE 3 + +#define BRW_REGISTER_TYPE_UD 0 +#define BRW_REGISTER_TYPE_D 1 +#define BRW_REGISTER_TYPE_UW 2 +#define BRW_REGISTER_TYPE_W 3 +#define BRW_REGISTER_TYPE_UB 4 +#define BRW_REGISTER_TYPE_B 5 +#define BRW_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */ +#define BRW_REGISTER_TYPE_HF 6 +#define BRW_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */ +#define BRW_REGISTER_TYPE_F 7 + +#define BRW_ARF_NULL 0x00 +#define BRW_ARF_ADDRESS 0x10 +#define BRW_ARF_ACCUMULATOR 0x20 +#define BRW_ARF_FLAG 0x30 +#define BRW_ARF_MASK 0x40 +#define BRW_ARF_MASK_STACK 0x50 +#define BRW_ARF_MASK_STACK_DEPTH 0x60 +#define BRW_ARF_STATE 0x70 +#define BRW_ARF_CONTROL 0x80 +#define BRW_ARF_NOTIFICATION_COUNT 0x90 +#define BRW_ARF_IP 0xA0 + +#define BRW_AMASK 0 +#define BRW_IMASK 1 +#define BRW_LMASK 2 +#define BRW_CMASK 3 + + + +#define BRW_THREAD_NORMAL 0 +#define BRW_THREAD_ATOMIC 1 +#define BRW_THREAD_SWITCH 2 + +#define BRW_VERTICAL_STRIDE_0 0 +#define BRW_VERTICAL_STRIDE_1 1 +#define BRW_VERTICAL_STRIDE_2 2 +#define BRW_VERTICAL_STRIDE_4 3 +#define BRW_VERTICAL_STRIDE_8 4 +#define BRW_VERTICAL_STRIDE_16 5 +#define BRW_VERTICAL_STRIDE_32 6 +#define BRW_VERTICAL_STRIDE_64 7 +#define BRW_VERTICAL_STRIDE_128 8 +#define BRW_VERTICAL_STRIDE_256 9 +#define BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF + +#define BRW_WIDTH_1 0 +#define BRW_WIDTH_2 1 +#define BRW_WIDTH_4 2 +#define BRW_WIDTH_8 3 +#define BRW_WIDTH_16 4 + +#define BRW_STATELESS_BUFFER_BOUNDARY_1K 0 +#define BRW_STATELESS_BUFFER_BOUNDARY_2K 1 +#define BRW_STATELESS_BUFFER_BOUNDARY_4K 2 +#define BRW_STATELESS_BUFFER_BOUNDARY_8K 3 +#define BRW_STATELESS_BUFFER_BOUNDARY_16K 4 +#define BRW_STATELESS_BUFFER_BOUNDARY_32K 5 +#define BRW_STATELESS_BUFFER_BOUNDARY_64K 6 +#define BRW_STATELESS_BUFFER_BOUNDARY_128K 7 +#define BRW_STATELESS_BUFFER_BOUNDARY_256K 8 +#define BRW_STATELESS_BUFFER_BOUNDARY_512K 9 +#define BRW_STATELESS_BUFFER_BOUNDARY_1M 10 +#define BRW_STATELESS_BUFFER_BOUNDARY_2M 11 + +#define BRW_POLYGON_FACING_FRONT 0 +#define BRW_POLYGON_FACING_BACK 1 + +#define BRW_MESSAGE_TARGET_NULL 0 +#define BRW_MESSAGE_TARGET_MATH 1 +#define BRW_MESSAGE_TARGET_SAMPLER 2 +#define BRW_MESSAGE_TARGET_GATEWAY 3 +#define BRW_MESSAGE_TARGET_DATAPORT_READ 4 +#define BRW_MESSAGE_TARGET_DATAPORT_WRITE 5 +#define BRW_MESSAGE_TARGET_URB 6 +#define BRW_MESSAGE_TARGET_THREAD_SPAWNER 7 + +#define BRW_SAMPLER_RETURN_FORMAT_FLOAT32 0 +#define BRW_SAMPLER_RETURN_FORMAT_UINT32 2 +#define BRW_SAMPLER_RETURN_FORMAT_SINT32 3 + +#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE 0 +#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE 0 +#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0 +#define BRW_SAMPLER_MESSAGE_SIMD8_KILLPIX 1 +#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1 +#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1 +#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2 +#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2 +#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0 +#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2 +#define BRW_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2 +#define BRW_SAMPLER_MESSAGE_SIMD8_RESINFO 2 +#define BRW_SAMPLER_MESSAGE_SIMD16_RESINFO 2 +#define BRW_SAMPLER_MESSAGE_SIMD4X2_LD 3 +#define BRW_SAMPLER_MESSAGE_SIMD8_LD 3 +#define BRW_SAMPLER_MESSAGE_SIMD16_LD 3 + +#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0 +#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1 +#define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS 2 +#define BRW_DATAPORT_OWORD_BLOCK_4_OWORDS 3 +#define BRW_DATAPORT_OWORD_BLOCK_8_OWORDS 4 + +#define BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0 +#define BRW_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2 + +#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2 +#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3 + +#define BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ 0 +#define BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 1 +#define BRW_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ 2 +#define BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 3 + +#define BRW_DATAPORT_READ_TARGET_DATA_CACHE 0 +#define BRW_DATAPORT_READ_TARGET_RENDER_CACHE 1 +#define BRW_DATAPORT_READ_TARGET_SAMPLER_CACHE 2 + +#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0 +#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1 +#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2 +#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3 +#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4 + +#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 0 +#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 1 +#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_BLOCK_WRITE 2 +#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 3 +#define BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 4 +#define BRW_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE 5 +#define BRW_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE 7 + +#define BRW_MATH_FUNCTION_INV 1 +#define BRW_MATH_FUNCTION_LOG 2 +#define BRW_MATH_FUNCTION_EXP 3 +#define BRW_MATH_FUNCTION_SQRT 4 +#define BRW_MATH_FUNCTION_RSQ 5 +#define BRW_MATH_FUNCTION_SIN 6 /* was 7 */ +#define BRW_MATH_FUNCTION_COS 7 /* was 8 */ +#define BRW_MATH_FUNCTION_SINCOS 8 /* was 6 */ +#define BRW_MATH_FUNCTION_TAN 9 +#define BRW_MATH_FUNCTION_POW 10 +#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11 +#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT 12 +#define BRW_MATH_FUNCTION_INT_DIV_REMAINDER 13 + +#define BRW_MATH_INTEGER_UNSIGNED 0 +#define BRW_MATH_INTEGER_SIGNED 1 + +#define BRW_MATH_PRECISION_FULL 0 +#define BRW_MATH_PRECISION_PARTIAL 1 + +#define BRW_MATH_SATURATE_NONE 0 +#define BRW_MATH_SATURATE_SATURATE 1 + +#define BRW_MATH_DATA_VECTOR 0 +#define BRW_MATH_DATA_SCALAR 1 + +#define BRW_URB_OPCODE_WRITE 0 + +#define BRW_URB_SWIZZLE_NONE 0 +#define BRW_URB_SWIZZLE_INTERLEAVE 1 +#define BRW_URB_SWIZZLE_TRANSPOSE 2 + +#define BRW_SCRATCH_SPACE_SIZE_1K 0 +#define BRW_SCRATCH_SPACE_SIZE_2K 1 +#define BRW_SCRATCH_SPACE_SIZE_4K 2 +#define BRW_SCRATCH_SPACE_SIZE_8K 3 +#define BRW_SCRATCH_SPACE_SIZE_16K 4 +#define BRW_SCRATCH_SPACE_SIZE_32K 5 +#define BRW_SCRATCH_SPACE_SIZE_64K 6 +#define BRW_SCRATCH_SPACE_SIZE_128K 7 +#define BRW_SCRATCH_SPACE_SIZE_256K 8 +#define BRW_SCRATCH_SPACE_SIZE_512K 9 +#define BRW_SCRATCH_SPACE_SIZE_1M 10 +#define BRW_SCRATCH_SPACE_SIZE_2M 11 + + + + +#define CMD_URB_FENCE 0x6000 +#define CMD_CONST_BUFFER_STATE 0x6001 +#define CMD_CONST_BUFFER 0x6002 + +#define CMD_STATE_BASE_ADDRESS 0x6101 +#define CMD_STATE_INSN_POINTER 0x6102 +#define CMD_PIPELINE_SELECT 0x6104 + +#define CMD_PIPELINED_STATE_POINTERS 0x7800 +#define CMD_BINDING_TABLE_PTRS 0x7801 +#define CMD_VERTEX_BUFFER 0x7808 +#define CMD_VERTEX_ELEMENT 0x7809 +#define CMD_INDEX_BUFFER 0x780a +#define CMD_VF_STATISTICS 0x780b + +#define CMD_DRAW_RECT 0x7900 +#define CMD_BLEND_CONSTANT_COLOR 0x7901 +#define CMD_CHROMA_KEY 0x7904 +#define CMD_DEPTH_BUFFER 0x7905 +#define CMD_POLY_STIPPLE_OFFSET 0x7906 +#define CMD_POLY_STIPPLE_PATTERN 0x7907 +#define CMD_LINE_STIPPLE_PATTERN 0x7908 +#define CMD_GLOBAL_DEPTH_OFFSET_CLAMP 0x7909 + +#define CMD_PIPE_CONTROL 0x7a00 + +#define CMD_3D_PRIM 0x7b00 + +#define CMD_MI_FLUSH 0x0200 + + +/* Various values from the R0 vertex header: + */ +#define R02_PRIM_END 0x1 +#define R02_PRIM_START 0x2 + + + +#endif diff --git a/src/gallium/drivers/i965simple/brw_draw.c b/src/gallium/drivers/i965simple/brw_draw.c new file mode 100644 index 0000000000..7598e3dc8a --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_draw.c @@ -0,0 +1,239 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include "brw_batch.h" +#include "brw_draw.h" +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_state.h" + +#include "pipe/p_context.h" +#include "pipe/p_winsys.h" + +static unsigned hw_prim[PIPE_PRIM_POLYGON+1] = { + _3DPRIM_POINTLIST, + _3DPRIM_LINELIST, + _3DPRIM_LINELOOP, + _3DPRIM_LINESTRIP, + _3DPRIM_TRILIST, + _3DPRIM_TRISTRIP, + _3DPRIM_TRIFAN, + _3DPRIM_QUADLIST, + _3DPRIM_QUADSTRIP, + _3DPRIM_POLYGON +}; + + +static const int reduced_prim[PIPE_PRIM_POLYGON+1] = { + PIPE_PRIM_POINTS, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES +}; + + +/* When the primitive changes, set a state bit and re-validate. Not + * the nicest and would rather deal with this by having all the + * programs be immune to the active primitive (ie. cope with all + * possibilities). That may not be realistic however. + */ +static void brw_set_prim(struct brw_context *brw, int prim) +{ + PRINT("PRIM: %d\n", prim); + + /* Slight optimization to avoid the GS program when not needed: + */ + if (prim == PIPE_PRIM_QUAD_STRIP && + brw->attribs.Raster->flatshade && + brw->attribs.Raster->fill_cw == PIPE_POLYGON_MODE_FILL && + brw->attribs.Raster->fill_ccw == PIPE_POLYGON_MODE_FILL) + prim = PIPE_PRIM_TRIANGLE_STRIP; + + if (prim != brw->primitive) { + brw->primitive = prim; + brw->state.dirty.brw |= BRW_NEW_PRIMITIVE; + + if (reduced_prim[prim] != brw->reduced_primitive) { + brw->reduced_primitive = reduced_prim[prim]; + brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE; + } + + brw_validate_state(brw); + } + +} + + +static unsigned trim(int prim, unsigned length) +{ + if (prim == PIPE_PRIM_QUAD_STRIP) + return length > 3 ? (length - length % 2) : 0; + else if (prim == PIPE_PRIM_QUADS) + return length - length % 4; + else + return length; +} + + + +static boolean brw_emit_prim( struct brw_context *brw, + boolean indexed, + unsigned start, + unsigned count ) + +{ + struct brw_3d_primitive prim_packet; + + if (BRW_DEBUG & DEBUG_PRIMS) + PRINT("PRIM: %d %d %d\n", brw->primitive, start, count); + + prim_packet.header.opcode = CMD_3D_PRIM; + prim_packet.header.length = sizeof(prim_packet)/4 - 2; + prim_packet.header.pad = 0; + prim_packet.header.topology = hw_prim[brw->primitive]; + prim_packet.header.indexed = indexed; + + prim_packet.verts_per_instance = trim(brw->primitive, count); + prim_packet.start_vert_location = start; + prim_packet.instance_count = 1; + prim_packet.start_instance_location = 0; + prim_packet.base_vert_location = 0; + + if (prim_packet.verts_per_instance == 0) + return TRUE; + + return brw_batchbuffer_data( brw->winsys, + &prim_packet, + sizeof(prim_packet) ); +} + + +/* May fail if out of video memory for texture or vbo upload, or on + * fallback conditions. + */ +static boolean brw_try_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *index_buffer, + unsigned index_size, + unsigned mode, + unsigned start, + unsigned count ) +{ + struct brw_context *brw = brw_context(pipe); + + /* Set the first primitive ahead of validate_state: + */ + brw_set_prim(brw, mode); + + /* Upload index, vertex data: + */ + if (index_buffer && + !brw_upload_indices( brw, index_buffer, index_size, start, count )) + return FALSE; + + if (!brw_upload_vertex_buffers(brw)) + return FALSE; + + if (!brw_upload_vertex_elements( brw )) + return FALSE; + + /* XXX: Need to separate validate and upload of state. + */ + if (brw->state.dirty.brw) + brw_validate_state( brw ); + + if (!brw_emit_prim(brw, index_buffer != NULL, + start, count)) + return FALSE; + + return TRUE; +} + + + +static boolean brw_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, + unsigned start, + unsigned count ) +{ + if (!brw_try_draw_elements( pipe, + indexBuffer, + indexSize, + mode, start, count )) + { + /* flush ? */ + + if (!brw_try_draw_elements( pipe, + indexBuffer, + indexSize, + mode, start, + count )) { + assert(0); + return FALSE; + } + } + + return TRUE; +} + + + +static boolean brw_draw_arrays( struct pipe_context *pipe, + unsigned mode, + unsigned start, + unsigned count ) +{ + if (!brw_try_draw_elements( pipe, NULL, 0, mode, start, count )) { + /* flush ? */ + + if (!brw_try_draw_elements( pipe, NULL, 0, mode, start, count )) { + assert(0); + return FALSE; + } + } + + return TRUE; +} + + + +void brw_init_draw_functions( struct brw_context *brw ) +{ + brw->pipe.draw_arrays = brw_draw_arrays; + brw->pipe.draw_elements = brw_draw_elements; +} + + diff --git a/src/gallium/drivers/i965simple/brw_draw.h b/src/gallium/drivers/i965simple/brw_draw.h new file mode 100644 index 0000000000..62fe0d5d0e --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_draw.h @@ -0,0 +1,55 @@ + /************************************************************************** + * + * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef BRW_DRAW_H +#define BRW_DRAW_H + +#include "pipe/p_context.h" + +struct brw_context; + + + +void brw_init_draw_functions( struct brw_context *brw ); + + +boolean brw_upload_vertices( struct brw_context *brw, + unsigned min_index, + unsigned max_index ); + +boolean brw_upload_indices(struct brw_context *brw, + const struct pipe_buffer *index_buffer, + int ib_size, int start, int count); + +boolean brw_upload_vertex_buffers( struct brw_context *brw ); +boolean brw_upload_vertex_elements( struct brw_context *brw ); + +unsigned brw_translate_surface_format( unsigned id ); + + + +#endif diff --git a/src/gallium/drivers/i965simple/brw_draw_upload.c b/src/gallium/drivers/i965simple/brw_draw_upload.c new file mode 100644 index 0000000000..aa85d93866 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_draw_upload.c @@ -0,0 +1,299 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include "brw_batch.h" +#include "brw_draw.h" +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_state.h" + +struct brw_array_state { + union header_union header; + + struct { + union { + struct { + unsigned pitch:11; + unsigned pad:15; + unsigned access_type:1; + unsigned vb_index:5; + } bits; + unsigned dword; + } vb0; + + struct pipe_buffer *buffer; + unsigned offset; + + unsigned max_index; + unsigned instance_data_step_rate; + + } vb[BRW_VBP_MAX]; +}; + + + +unsigned brw_translate_surface_format( unsigned id ) +{ + switch (id) { + case PIPE_FORMAT_R64_FLOAT: + return BRW_SURFACEFORMAT_R64_FLOAT; + case PIPE_FORMAT_R64G64_FLOAT: + return BRW_SURFACEFORMAT_R64G64_FLOAT; + case PIPE_FORMAT_R64G64B64_FLOAT: + return BRW_SURFACEFORMAT_R64G64B64_FLOAT; + case PIPE_FORMAT_R64G64B64A64_FLOAT: + return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT; + + case PIPE_FORMAT_R32_FLOAT: + return BRW_SURFACEFORMAT_R32_FLOAT; + case PIPE_FORMAT_R32G32_FLOAT: + return BRW_SURFACEFORMAT_R32G32_FLOAT; + case PIPE_FORMAT_R32G32B32_FLOAT: + return BRW_SURFACEFORMAT_R32G32B32_FLOAT; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT; + + case PIPE_FORMAT_R32_UNORM: + return BRW_SURFACEFORMAT_R32_UNORM; + case PIPE_FORMAT_R32G32_UNORM: + return BRW_SURFACEFORMAT_R32G32_UNORM; + case PIPE_FORMAT_R32G32B32_UNORM: + return BRW_SURFACEFORMAT_R32G32B32_UNORM; + case PIPE_FORMAT_R32G32B32A32_UNORM: + return BRW_SURFACEFORMAT_R32G32B32A32_UNORM; + + case PIPE_FORMAT_R32_USCALED: + return BRW_SURFACEFORMAT_R32_USCALED; + case PIPE_FORMAT_R32G32_USCALED: + return BRW_SURFACEFORMAT_R32G32_USCALED; + case PIPE_FORMAT_R32G32B32_USCALED: + return BRW_SURFACEFORMAT_R32G32B32_USCALED; + case PIPE_FORMAT_R32G32B32A32_USCALED: + return BRW_SURFACEFORMAT_R32G32B32A32_USCALED; + + case PIPE_FORMAT_R32_SNORM: + return BRW_SURFACEFORMAT_R32_SNORM; + case PIPE_FORMAT_R32G32_SNORM: + return BRW_SURFACEFORMAT_R32G32_SNORM; + case PIPE_FORMAT_R32G32B32_SNORM: + return BRW_SURFACEFORMAT_R32G32B32_SNORM; + case PIPE_FORMAT_R32G32B32A32_SNORM: + return BRW_SURFACEFORMAT_R32G32B32A32_SNORM; + + case PIPE_FORMAT_R32_SSCALED: + return BRW_SURFACEFORMAT_R32_SSCALED; + case PIPE_FORMAT_R32G32_SSCALED: + return BRW_SURFACEFORMAT_R32G32_SSCALED; + case PIPE_FORMAT_R32G32B32_SSCALED: + return BRW_SURFACEFORMAT_R32G32B32_SSCALED; + case PIPE_FORMAT_R32G32B32A32_SSCALED: + return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED; + + case PIPE_FORMAT_R16_UNORM: + return BRW_SURFACEFORMAT_R16_UNORM; + case PIPE_FORMAT_R16G16_UNORM: + return BRW_SURFACEFORMAT_R16G16_UNORM; + case PIPE_FORMAT_R16G16B16_UNORM: + return BRW_SURFACEFORMAT_R16G16B16_UNORM; + case PIPE_FORMAT_R16G16B16A16_UNORM: + return BRW_SURFACEFORMAT_R16G16B16A16_UNORM; + + case PIPE_FORMAT_R16_USCALED: + return BRW_SURFACEFORMAT_R16_USCALED; + case PIPE_FORMAT_R16G16_USCALED: + return BRW_SURFACEFORMAT_R16G16_USCALED; + case PIPE_FORMAT_R16G16B16_USCALED: + return BRW_SURFACEFORMAT_R16G16B16_USCALED; + case PIPE_FORMAT_R16G16B16A16_USCALED: + return BRW_SURFACEFORMAT_R16G16B16A16_USCALED; + + case PIPE_FORMAT_R16_SNORM: + return BRW_SURFACEFORMAT_R16_SNORM; + case PIPE_FORMAT_R16G16_SNORM: + return BRW_SURFACEFORMAT_R16G16_SNORM; + case PIPE_FORMAT_R16G16B16_SNORM: + return BRW_SURFACEFORMAT_R16G16B16_SNORM; + case PIPE_FORMAT_R16G16B16A16_SNORM: + return BRW_SURFACEFORMAT_R16G16B16A16_SNORM; + + case PIPE_FORMAT_R16_SSCALED: + return BRW_SURFACEFORMAT_R16_SSCALED; + case PIPE_FORMAT_R16G16_SSCALED: + return BRW_SURFACEFORMAT_R16G16_SSCALED; + case PIPE_FORMAT_R16G16B16_SSCALED: + return BRW_SURFACEFORMAT_R16G16B16_SSCALED; + case PIPE_FORMAT_R16G16B16A16_SSCALED: + return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED; + + case PIPE_FORMAT_R8_UNORM: + return BRW_SURFACEFORMAT_R8_UNORM; + case PIPE_FORMAT_R8G8_UNORM: + return BRW_SURFACEFORMAT_R8G8_UNORM; + case PIPE_FORMAT_R8G8B8_UNORM: + return BRW_SURFACEFORMAT_R8G8B8_UNORM; + case PIPE_FORMAT_R8G8B8A8_UNORM: + return BRW_SURFACEFORMAT_R8G8B8A8_UNORM; + + case PIPE_FORMAT_R8_USCALED: + return BRW_SURFACEFORMAT_R8_USCALED; + case PIPE_FORMAT_R8G8_USCALED: + return BRW_SURFACEFORMAT_R8G8_USCALED; + case PIPE_FORMAT_R8G8B8_USCALED: + return BRW_SURFACEFORMAT_R8G8B8_USCALED; + case PIPE_FORMAT_R8G8B8A8_USCALED: + return BRW_SURFACEFORMAT_R8G8B8A8_USCALED; + + case PIPE_FORMAT_R8_SNORM: + return BRW_SURFACEFORMAT_R8_SNORM; + case PIPE_FORMAT_R8G8_SNORM: + return BRW_SURFACEFORMAT_R8G8_SNORM; + case PIPE_FORMAT_R8G8B8_SNORM: + return BRW_SURFACEFORMAT_R8G8B8_SNORM; + case PIPE_FORMAT_R8G8B8A8_SNORM: + return BRW_SURFACEFORMAT_R8G8B8A8_SNORM; + + case PIPE_FORMAT_R8_SSCALED: + return BRW_SURFACEFORMAT_R8_SSCALED; + case PIPE_FORMAT_R8G8_SSCALED: + return BRW_SURFACEFORMAT_R8G8_SSCALED; + case PIPE_FORMAT_R8G8B8_SSCALED: + return BRW_SURFACEFORMAT_R8G8B8_SSCALED; + case PIPE_FORMAT_R8G8B8A8_SSCALED: + return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED; + + default: + assert(0); + return 0; + } +} + +static unsigned get_index_type(int type) +{ + switch (type) { + case 1: return BRW_INDEX_BYTE; + case 2: return BRW_INDEX_WORD; + case 4: return BRW_INDEX_DWORD; + default: assert(0); return 0; + } +} + + +boolean brw_upload_vertex_buffers( struct brw_context *brw ) +{ + struct brw_array_state vbp; + unsigned nr_enabled = 0; + unsigned i; + + memset(&vbp, 0, sizeof(vbp)); + + /* This is a hardware limit: + */ + + for (i = 0; i < BRW_VEP_MAX; i++) + { + if (brw->vb.vbo_array[i] == NULL) { + nr_enabled = i; + break; + } + + vbp.vb[i].vb0.bits.pitch = brw->vb.vbo_array[i]->pitch; + vbp.vb[i].vb0.bits.pad = 0; + vbp.vb[i].vb0.bits.access_type = BRW_VERTEXBUFFER_ACCESS_VERTEXDATA; + vbp.vb[i].vb0.bits.vb_index = i; + vbp.vb[i].offset = brw->vb.vbo_array[i]->buffer_offset; + vbp.vb[i].buffer = brw->vb.vbo_array[i]->buffer; + vbp.vb[i].max_index = brw->vb.vbo_array[i]->max_index; + } + + + vbp.header.bits.length = (1 + nr_enabled * 4) - 2; + vbp.header.bits.opcode = CMD_VERTEX_BUFFER; + + BEGIN_BATCH(vbp.header.bits.length+2, 0); + OUT_BATCH( vbp.header.dword ); + + for (i = 0; i < nr_enabled; i++) { + OUT_BATCH( vbp.vb[i].vb0.dword ); + OUT_RELOC( vbp.vb[i].buffer, PIPE_BUFFER_USAGE_GPU_READ, + vbp.vb[i].offset); + OUT_BATCH( vbp.vb[i].max_index ); + OUT_BATCH( vbp.vb[i].instance_data_step_rate ); + } + ADVANCE_BATCH(); + return TRUE; +} + + + +boolean brw_upload_vertex_elements( struct brw_context *brw ) +{ + struct brw_vertex_element_packet vep; + + unsigned i; + unsigned nr_enabled = brw->attribs.VertexProgram->program.num_inputs; + + memset(&vep, 0, sizeof(vep)); + + for (i = 0; i < nr_enabled; i++) + vep.ve[i] = brw->vb.inputs[i]; + + + vep.header.length = (1 + nr_enabled * sizeof(vep.ve[0])/4) - 2; + vep.header.opcode = CMD_VERTEX_ELEMENT; + brw_cached_batch_struct(brw, &vep, 4 + nr_enabled * sizeof(vep.ve[0])); + + return TRUE; +} + +boolean brw_upload_indices( struct brw_context *brw, + const struct pipe_buffer *index_buffer, + int ib_size, int start, int count) +{ + /* Emit the indexbuffer packet: + */ + { + struct brw_indexbuffer ib; + + memset(&ib, 0, sizeof(ib)); + + ib.header.bits.opcode = CMD_INDEX_BUFFER; + ib.header.bits.length = sizeof(ib)/4 - 2; + ib.header.bits.index_format = get_index_type(ib_size); + ib.header.bits.cut_index_enable = 0; + + + BEGIN_BATCH(4, 0); + OUT_BATCH( ib.header.dword ); + OUT_RELOC( index_buffer, PIPE_BUFFER_USAGE_GPU_READ, start); + OUT_RELOC( index_buffer, PIPE_BUFFER_USAGE_GPU_READ, start + count); + OUT_BATCH( 0 ); + ADVANCE_BATCH(); + } + return TRUE; +} diff --git a/src/gallium/drivers/i965simple/brw_eu.c b/src/gallium/drivers/i965simple/brw_eu.c new file mode 100644 index 0000000000..e2002d1821 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_eu.c @@ -0,0 +1,130 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_eu.h" + + + +/* How does predicate control work when execution_size != 8? Do I + * need to test/set for 0xffff when execution_size is 16? + */ +void brw_set_predicate_control_flag_value( struct brw_compile *p, unsigned value ) +{ + p->current->header.predicate_control = BRW_PREDICATE_NONE; + + if (value != 0xff) { + if (value != p->flag_value) { + brw_push_insn_state(p); + brw_MOV(p, brw_flag_reg(), brw_imm_uw(value)); + p->flag_value = value; + brw_pop_insn_state(p); + } + + p->current->header.predicate_control = BRW_PREDICATE_NORMAL; + } +} + +void brw_set_predicate_control( struct brw_compile *p, unsigned pc ) +{ + p->current->header.predicate_control = pc; +} + +void brw_set_conditionalmod( struct brw_compile *p, unsigned conditional ) +{ + p->current->header.destreg__conditonalmod = conditional; +} + +void brw_set_access_mode( struct brw_compile *p, unsigned access_mode ) +{ + p->current->header.access_mode = access_mode; +} + +void brw_set_compression_control( struct brw_compile *p, boolean compression_control ) +{ + p->current->header.compression_control = compression_control; +} + +void brw_set_mask_control( struct brw_compile *p, unsigned value ) +{ + p->current->header.mask_control = value; +} + +void brw_set_saturate( struct brw_compile *p, unsigned value ) +{ + p->current->header.saturate = value; +} + +void brw_push_insn_state( struct brw_compile *p ) +{ + assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]); + memcpy(p->current+1, p->current, sizeof(struct brw_instruction)); + p->current++; +} + +void brw_pop_insn_state( struct brw_compile *p ) +{ + assert(p->current != p->stack); + p->current--; +} + + +/*********************************************************************** + */ +void brw_init_compile( struct brw_compile *p ) +{ + p->nr_insn = 0; + p->current = p->stack; + memset(p->current, 0, sizeof(p->current[0])); + + /* Some defaults? + */ + brw_set_mask_control(p, BRW_MASK_ENABLE); /* what does this do? */ + brw_set_saturate(p, 0); + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + brw_set_predicate_control_flag_value(p, 0xff); +} + + +const unsigned *brw_get_program( struct brw_compile *p, + unsigned *sz ) +{ + unsigned i; + + for (i = 0; i < 8; i++) + brw_NOP(p); + + *sz = p->nr_insn * sizeof(struct brw_instruction); + return (const unsigned *)p->store; +} + diff --git a/src/gallium/drivers/i965simple/brw_eu.h b/src/gallium/drivers/i965simple/brw_eu.h new file mode 100644 index 0000000000..23151ae9ed --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_eu.h @@ -0,0 +1,888 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRW_EU_H +#define BRW_EU_H + +#include "brw_structs.h" +#include "brw_defines.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_shader_tokens.h" + +#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6)) +#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3) + +#define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3) +#define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3) +#define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0) +#define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1) + + +#define REG_SIZE (8*4) + + +/* These aren't hardware structs, just something useful for us to pass around: + * + * Align1 operation has a lot of control over input ranges. Used in + * WM programs to implement shaders decomposed into "channel serial" + * or "structure of array" form: + */ +struct brw_reg +{ + unsigned type:4; + unsigned file:2; + unsigned nr:8; + unsigned subnr:5; /* :1 in align16 */ + unsigned negate:1; /* source only */ + unsigned abs:1; /* source only */ + unsigned vstride:4; /* source only */ + unsigned width:3; /* src only, align1 only */ + unsigned hstride:2; /* src only, align1 only */ + unsigned address_mode:1; /* relative addressing, hopefully! */ + unsigned pad0:1; + + union { + struct { + unsigned swizzle:8; /* src only, align16 only */ + unsigned writemask:4; /* dest only, align16 only */ + int indirect_offset:10; /* relative addressing offset */ + unsigned pad1:10; /* two dwords total */ + } bits; + + float f; + int d; + unsigned ud; + } dw1; +}; + + +struct brw_indirect { + unsigned addr_subnr:4; + int addr_offset:10; + unsigned pad:18; +}; + + +#define BRW_EU_MAX_INSN_STACK 5 +#define BRW_EU_MAX_INSN 1200 + +struct brw_compile { + struct brw_instruction store[BRW_EU_MAX_INSN]; + unsigned nr_insn; + + /* Allow clients to push/pop instruction state: + */ + struct brw_instruction stack[BRW_EU_MAX_INSN_STACK]; + struct brw_instruction *current; + + unsigned flag_value; + boolean single_program_flow; +}; + + + +static __inline int type_sz( unsigned type ) +{ + switch( type ) { + case BRW_REGISTER_TYPE_UD: + case BRW_REGISTER_TYPE_D: + case BRW_REGISTER_TYPE_F: + return 4; + case BRW_REGISTER_TYPE_HF: + case BRW_REGISTER_TYPE_UW: + case BRW_REGISTER_TYPE_W: + return 2; + case BRW_REGISTER_TYPE_UB: + case BRW_REGISTER_TYPE_B: + return 1; + default: + return 0; + } +} + +static __inline struct brw_reg brw_reg( unsigned file, + unsigned nr, + unsigned subnr, + unsigned type, + unsigned vstride, + unsigned width, + unsigned hstride, + unsigned swizzle, + unsigned writemask) +{ + + struct brw_reg reg; + reg.type = type; + reg.file = file; + reg.nr = nr; + reg.subnr = subnr * type_sz(type); + reg.negate = 0; + reg.abs = 0; + reg.vstride = vstride; + reg.width = width; + reg.hstride = hstride; + reg.address_mode = BRW_ADDRESS_DIRECT; + reg.pad0 = 0; + + /* Could do better: If the reg is r5.3<0;1,0>, we probably want to + * set swizzle and writemask to W, as the lower bits of subnr will + * be lost when converted to align16. This is probably too much to + * keep track of as you'd want it adjusted by suboffset(), etc. + * Perhaps fix up when converting to align16? + */ + reg.dw1.bits.swizzle = swizzle; + reg.dw1.bits.writemask = writemask; + reg.dw1.bits.indirect_offset = 0; + reg.dw1.bits.pad1 = 0; + return reg; +} + +static __inline struct brw_reg brw_vec16_reg( unsigned file, + unsigned nr, + unsigned subnr ) +{ + return brw_reg(file, + nr, + subnr, + BRW_REGISTER_TYPE_F, + BRW_VERTICAL_STRIDE_16, + BRW_WIDTH_16, + BRW_HORIZONTAL_STRIDE_1, + BRW_SWIZZLE_XYZW, + TGSI_WRITEMASK_XYZW); +} + +static __inline struct brw_reg brw_vec8_reg( unsigned file, + unsigned nr, + unsigned subnr ) +{ + return brw_reg(file, + nr, + subnr, + BRW_REGISTER_TYPE_F, + BRW_VERTICAL_STRIDE_8, + BRW_WIDTH_8, + BRW_HORIZONTAL_STRIDE_1, + BRW_SWIZZLE_XYZW, + TGSI_WRITEMASK_XYZW); +} + + +static __inline struct brw_reg brw_vec4_reg( unsigned file, + unsigned nr, + unsigned subnr ) +{ + return brw_reg(file, + nr, + subnr, + BRW_REGISTER_TYPE_F, + BRW_VERTICAL_STRIDE_4, + BRW_WIDTH_4, + BRW_HORIZONTAL_STRIDE_1, + BRW_SWIZZLE_XYZW, + TGSI_WRITEMASK_XYZW); +} + + +static __inline struct brw_reg brw_vec2_reg( unsigned file, + unsigned nr, + unsigned subnr ) +{ + return brw_reg(file, + nr, + subnr, + BRW_REGISTER_TYPE_F, + BRW_VERTICAL_STRIDE_2, + BRW_WIDTH_2, + BRW_HORIZONTAL_STRIDE_1, + BRW_SWIZZLE_XYXY, + TGSI_WRITEMASK_XY); +} + +static __inline struct brw_reg brw_vec1_reg( unsigned file, + unsigned nr, + unsigned subnr ) +{ + return brw_reg(file, + nr, + subnr, + BRW_REGISTER_TYPE_F, + BRW_VERTICAL_STRIDE_0, + BRW_WIDTH_1, + BRW_HORIZONTAL_STRIDE_0, + BRW_SWIZZLE_XXXX, + TGSI_WRITEMASK_X); +} + + +static __inline struct brw_reg retype( struct brw_reg reg, + unsigned type ) +{ + reg.type = type; + return reg; +} + +static __inline struct brw_reg suboffset( struct brw_reg reg, + unsigned delta ) +{ + reg.subnr += delta * type_sz(reg.type); + return reg; +} + + +static __inline struct brw_reg offset( struct brw_reg reg, + unsigned delta ) +{ + reg.nr += delta; + return reg; +} + + +static __inline struct brw_reg byte_offset( struct brw_reg reg, + unsigned bytes ) +{ + unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes; + reg.nr = newoffset / REG_SIZE; + reg.subnr = newoffset % REG_SIZE; + return reg; +} + + +static __inline struct brw_reg brw_uw16_reg( unsigned file, + unsigned nr, + unsigned subnr ) +{ + return suboffset(retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); +} + +static __inline struct brw_reg brw_uw8_reg( unsigned file, + unsigned nr, + unsigned subnr ) +{ + return suboffset(retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); +} + +static __inline struct brw_reg brw_uw1_reg( unsigned file, + unsigned nr, + unsigned subnr ) +{ + return suboffset(retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); +} + +static __inline struct brw_reg brw_imm_reg( unsigned type ) +{ + return brw_reg( BRW_IMMEDIATE_VALUE, + 0, + 0, + type, + BRW_VERTICAL_STRIDE_0, + BRW_WIDTH_1, + BRW_HORIZONTAL_STRIDE_0, + 0, + 0); +} + +static __inline struct brw_reg brw_imm_f( float f ) +{ + struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F); + imm.dw1.f = f; + return imm; +} + +static __inline struct brw_reg brw_imm_d( int d ) +{ + struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D); + imm.dw1.d = d; + return imm; +} + +static __inline struct brw_reg brw_imm_ud( unsigned ud ) +{ + struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD); + imm.dw1.ud = ud; + return imm; +} + +static __inline struct brw_reg brw_imm_uw( ushort uw ) +{ + struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW); + imm.dw1.ud = uw; + return imm; +} + +static __inline struct brw_reg brw_imm_w( short w ) +{ + struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W); + imm.dw1.d = w; + return imm; +} + +/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type + * numbers alias with _V and _VF below: + */ + +/* Vector of eight signed half-byte values: + */ +static __inline struct brw_reg brw_imm_v( unsigned v ) +{ + struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V); + imm.vstride = BRW_VERTICAL_STRIDE_0; + imm.width = BRW_WIDTH_8; + imm.hstride = BRW_HORIZONTAL_STRIDE_1; + imm.dw1.ud = v; + return imm; +} + +/* Vector of four 8-bit float values: + */ +static __inline struct brw_reg brw_imm_vf( unsigned v ) +{ + struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF); + imm.vstride = BRW_VERTICAL_STRIDE_0; + imm.width = BRW_WIDTH_4; + imm.hstride = BRW_HORIZONTAL_STRIDE_1; + imm.dw1.ud = v; + return imm; +} + +#define VF_ZERO 0x0 +#define VF_ONE 0x30 +#define VF_NEG (1<<7) + +static __inline struct brw_reg brw_imm_vf4( unsigned v0, + unsigned v1, + unsigned v2, + unsigned v3) +{ + struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF); + imm.vstride = BRW_VERTICAL_STRIDE_0; + imm.width = BRW_WIDTH_4; + imm.hstride = BRW_HORIZONTAL_STRIDE_1; + imm.dw1.ud = ((v0 << 0) | + (v1 << 8) | + (v2 << 16) | + (v3 << 24)); + return imm; +} + + +static __inline struct brw_reg brw_address( struct brw_reg reg ) +{ + return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr); +} + + +static __inline struct brw_reg brw_vec1_grf( unsigned nr, + unsigned subnr ) +{ + return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); +} + +static __inline struct brw_reg brw_vec8_grf( unsigned nr, + unsigned subnr ) +{ + return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); +} + +static __inline struct brw_reg brw_vec4_grf( unsigned nr, + unsigned subnr ) +{ + return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); +} + + +static __inline struct brw_reg brw_vec2_grf( unsigned nr, + unsigned subnr ) +{ + return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); +} + +static __inline struct brw_reg brw_uw8_grf( unsigned nr, + unsigned subnr ) +{ + return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); +} + +static __inline struct brw_reg brw_null_reg( void ) +{ + return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, + BRW_ARF_NULL, + 0); +} + +static __inline struct brw_reg brw_address_reg( unsigned subnr ) +{ + return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, + BRW_ARF_ADDRESS, + subnr); +} + +/* If/else instructions break in align16 mode if writemask & swizzle + * aren't xyzw. This goes against the convention for other scalar + * regs: + */ +static __inline struct brw_reg brw_ip_reg( void ) +{ + return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, + BRW_ARF_IP, + 0, + BRW_REGISTER_TYPE_UD, + BRW_VERTICAL_STRIDE_4, /* ? */ + BRW_WIDTH_1, + BRW_HORIZONTAL_STRIDE_0, + BRW_SWIZZLE_XYZW, /* NOTE! */ + TGSI_WRITEMASK_XYZW); /* NOTE! */ +} + +static __inline struct brw_reg brw_acc_reg( void ) +{ + return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, + BRW_ARF_ACCUMULATOR, + 0); +} + + +static __inline struct brw_reg brw_flag_reg( void ) +{ + return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, + BRW_ARF_FLAG, + 0); +} + + +static __inline struct brw_reg brw_mask_reg( unsigned subnr ) +{ + return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, + BRW_ARF_MASK, + subnr); +} + +static __inline struct brw_reg brw_message_reg( unsigned nr ) +{ + return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, + nr, + 0); +} + + + + +/* This is almost always called with a numeric constant argument, so + * make things easy to evaluate at compile time: + */ +static __inline unsigned cvt( unsigned val ) +{ + switch (val) { + case 0: return 0; + case 1: return 1; + case 2: return 2; + case 4: return 3; + case 8: return 4; + case 16: return 5; + case 32: return 6; + } + return 0; +} + +static __inline struct brw_reg stride( struct brw_reg reg, + unsigned vstride, + unsigned width, + unsigned hstride ) +{ + + reg.vstride = cvt(vstride); + reg.width = cvt(width) - 1; + reg.hstride = cvt(hstride); + return reg; +} + +static __inline struct brw_reg vec16( struct brw_reg reg ) +{ + return stride(reg, 16,16,1); +} + +static __inline struct brw_reg vec8( struct brw_reg reg ) +{ + return stride(reg, 8,8,1); +} + +static __inline struct brw_reg vec4( struct brw_reg reg ) +{ + return stride(reg, 4,4,1); +} + +static __inline struct brw_reg vec2( struct brw_reg reg ) +{ + return stride(reg, 2,2,1); +} + +static __inline struct brw_reg vec1( struct brw_reg reg ) +{ + return stride(reg, 0,1,0); +} + +static __inline struct brw_reg get_element( struct brw_reg reg, unsigned elt ) +{ + return vec1(suboffset(reg, elt)); +} + +static __inline struct brw_reg get_element_ud( struct brw_reg reg, unsigned elt ) +{ + return vec1(suboffset(retype(reg, BRW_REGISTER_TYPE_UD), elt)); +} + + +static __inline struct brw_reg brw_swizzle( struct brw_reg reg, + unsigned x, + unsigned y, + unsigned z, + unsigned w) +{ + reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x), + BRW_GET_SWZ(reg.dw1.bits.swizzle, y), + BRW_GET_SWZ(reg.dw1.bits.swizzle, z), + BRW_GET_SWZ(reg.dw1.bits.swizzle, w)); + return reg; +} + + +static __inline struct brw_reg brw_swizzle1( struct brw_reg reg, + unsigned x ) +{ + return brw_swizzle(reg, x, x, x, x); +} + +static __inline struct brw_reg brw_writemask( struct brw_reg reg, + unsigned mask ) +{ + reg.dw1.bits.writemask &= mask; + return reg; +} + +static __inline struct brw_reg brw_set_writemask( struct brw_reg reg, + unsigned mask ) +{ + reg.dw1.bits.writemask = mask; + return reg; +} + +static __inline struct brw_reg negate( struct brw_reg reg ) +{ + reg.negate ^= 1; + return reg; +} + +static __inline struct brw_reg brw_abs( struct brw_reg reg ) +{ + reg.abs = 1; + return reg; +} + +/*********************************************************************** + */ +static __inline struct brw_reg brw_vec4_indirect( unsigned subnr, + int offset ) +{ + struct brw_reg reg = brw_vec4_grf(0, 0); + reg.subnr = subnr; + reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; + reg.dw1.bits.indirect_offset = offset; + return reg; +} + +static __inline struct brw_reg brw_vec1_indirect( unsigned subnr, + int offset ) +{ + struct brw_reg reg = brw_vec1_grf(0, 0); + reg.subnr = subnr; + reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; + reg.dw1.bits.indirect_offset = offset; + return reg; +} + +static __inline struct brw_reg deref_4f(struct brw_indirect ptr, int offset) +{ + return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset); +} + +static __inline struct brw_reg deref_1f(struct brw_indirect ptr, int offset) +{ + return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset); +} + +static __inline struct brw_reg deref_4b(struct brw_indirect ptr, int offset) +{ + return retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B); +} + +static __inline struct brw_reg deref_1uw(struct brw_indirect ptr, int offset) +{ + return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW); +} + +static __inline struct brw_reg deref_1ud(struct brw_indirect ptr, int offset) +{ + return retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD); +} + +static __inline struct brw_reg get_addr_reg(struct brw_indirect ptr) +{ + return brw_address_reg(ptr.addr_subnr); +} + +static __inline struct brw_indirect brw_indirect_offset( struct brw_indirect ptr, int offset ) +{ + ptr.addr_offset += offset; + return ptr; +} + +static __inline struct brw_indirect brw_indirect( unsigned addr_subnr, int offset ) +{ + struct brw_indirect ptr; + ptr.addr_subnr = addr_subnr; + ptr.addr_offset = offset; + ptr.pad = 0; + return ptr; +} + +static __inline struct brw_instruction *current_insn( struct brw_compile *p) +{ + return &p->store[p->nr_insn]; +} + +void brw_pop_insn_state( struct brw_compile *p ); +void brw_push_insn_state( struct brw_compile *p ); +void brw_set_mask_control( struct brw_compile *p, unsigned value ); +void brw_set_saturate( struct brw_compile *p, unsigned value ); +void brw_set_access_mode( struct brw_compile *p, unsigned access_mode ); +void brw_set_compression_control( struct brw_compile *p, boolean control ); +void brw_set_predicate_control_flag_value( struct brw_compile *p, unsigned value ); +void brw_set_predicate_control( struct brw_compile *p, unsigned pc ); +void brw_set_conditionalmod( struct brw_compile *p, unsigned conditional ); + +void brw_init_compile( struct brw_compile *p ); +const unsigned *brw_get_program( struct brw_compile *p, unsigned *sz ); + + +struct brw_instruction *brw_alu1( struct brw_compile *p, + unsigned opcode, + struct brw_reg dest, + struct brw_reg src ); + +struct brw_instruction *brw_alu2(struct brw_compile *p, + unsigned opcode, + struct brw_reg dest, + struct brw_reg src0, + struct brw_reg src1 ); + +/* Helpers for regular instructions: + */ +#define ALU1(OP) \ +struct brw_instruction *brw_##OP(struct brw_compile *p, \ + struct brw_reg dest, \ + struct brw_reg src0); + +#define ALU2(OP) \ +struct brw_instruction *brw_##OP(struct brw_compile *p, \ + struct brw_reg dest, \ + struct brw_reg src0, \ + struct brw_reg src1); + +ALU1(MOV) +ALU2(SEL) +ALU1(NOT) +ALU2(AND) +ALU2(OR) +ALU2(XOR) +ALU2(SHR) +ALU2(SHL) +ALU2(RSR) +ALU2(RSL) +ALU2(ASR) +ALU2(JMPI) +ALU2(ADD) +ALU2(MUL) +ALU1(FRC) +ALU1(RNDD) +ALU2(MAC) +ALU2(MACH) +ALU1(LZD) +ALU2(DP4) +ALU2(DPH) +ALU2(DP3) +ALU2(DP2) +ALU2(LINE) + +#undef ALU1 +#undef ALU2 + + + +/* Helpers for SEND instruction: + */ +void brw_urb_WRITE(struct brw_compile *p, + struct brw_reg dest, + unsigned msg_reg_nr, + struct brw_reg src0, + boolean allocate, + boolean used, + unsigned msg_length, + unsigned response_length, + boolean eot, + boolean writes_complete, + unsigned offset, + unsigned swizzle); + +void brw_fb_WRITE(struct brw_compile *p, + struct brw_reg dest, + unsigned msg_reg_nr, + struct brw_reg src0, + unsigned binding_table_index, + unsigned msg_length, + unsigned response_length, + boolean eot); + +void brw_SAMPLE(struct brw_compile *p, + struct brw_reg dest, + unsigned msg_reg_nr, + struct brw_reg src0, + unsigned binding_table_index, + unsigned sampler, + unsigned writemask, + unsigned msg_type, + unsigned response_length, + unsigned msg_length, + boolean eot); + +void brw_math_16( struct brw_compile *p, + struct brw_reg dest, + unsigned function, + unsigned saturate, + unsigned msg_reg_nr, + struct brw_reg src, + unsigned precision ); + +void brw_math( struct brw_compile *p, + struct brw_reg dest, + unsigned function, + unsigned saturate, + unsigned msg_reg_nr, + struct brw_reg src, + unsigned data_type, + unsigned precision ); + +void brw_dp_READ_16( struct brw_compile *p, + struct brw_reg dest, + unsigned msg_reg_nr, + unsigned scratch_offset ); + +void brw_dp_WRITE_16( struct brw_compile *p, + struct brw_reg src, + unsigned msg_reg_nr, + unsigned scratch_offset ); + +/* If/else/endif. Works by manipulating the execution flags on each + * channel. + */ +struct brw_instruction *brw_IF(struct brw_compile *p, + unsigned execute_size); + +struct brw_instruction *brw_ELSE(struct brw_compile *p, + struct brw_instruction *if_insn); + +void brw_ENDIF(struct brw_compile *p, + struct brw_instruction *if_or_else_insn); + + +/* DO/WHILE loops: + */ +struct brw_instruction *brw_DO(struct brw_compile *p, + unsigned execute_size); + +struct brw_instruction *brw_WHILE(struct brw_compile *p, + struct brw_instruction *patch_insn); + +struct brw_instruction *brw_BREAK(struct brw_compile *p); +struct brw_instruction *brw_CONT(struct brw_compile *p); +/* Forward jumps: + */ +void brw_land_fwd_jump(struct brw_compile *p, + struct brw_instruction *jmp_insn); + + + +void brw_NOP(struct brw_compile *p); + +/* Special case: there is never a destination, execution size will be + * taken from src0: + */ +void brw_CMP(struct brw_compile *p, + struct brw_reg dest, + unsigned conditional, + struct brw_reg src0, + struct brw_reg src1); + +void brw_print_reg( struct brw_reg reg ); + + +/*********************************************************************** + * brw_eu_util.c: + */ + +void brw_copy_indirect_to_indirect(struct brw_compile *p, + struct brw_indirect dst_ptr, + struct brw_indirect src_ptr, + unsigned count); + +void brw_copy_from_indirect(struct brw_compile *p, + struct brw_reg dst, + struct brw_indirect ptr, + unsigned count); + +void brw_copy4(struct brw_compile *p, + struct brw_reg dst, + struct brw_reg src, + unsigned count); + +void brw_copy8(struct brw_compile *p, + struct brw_reg dst, + struct brw_reg src, + unsigned count); + +void brw_math_invert( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg src); + +void brw_set_src1( struct brw_instruction *insn, + struct brw_reg reg ); +#endif diff --git a/src/gallium/drivers/i965simple/brw_eu_debug.c b/src/gallium/drivers/i965simple/brw_eu_debug.c new file mode 100644 index 0000000000..4a94ddefa6 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_eu_debug.c @@ -0,0 +1,90 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "pipe/p_debug.h" + +#include "brw_eu.h" + +void brw_print_reg( struct brw_reg hwreg ) +{ + static const char *file[] = { + "arf", + "grf", + "msg", + "imm" + }; + + static const char *type[] = { + "ud", + "d", + "uw", + "w", + "ub", + "vf", + "hf", + "f" + }; + + debug_printf("%s%s", + hwreg.abs ? "abs/" : "", + hwreg.negate ? "-" : ""); + + if (hwreg.file == BRW_GENERAL_REGISTER_FILE && + hwreg.nr % 2 == 0 && + hwreg.subnr == 0 && + hwreg.vstride == BRW_VERTICAL_STRIDE_8 && + hwreg.width == BRW_WIDTH_8 && + hwreg.hstride == BRW_HORIZONTAL_STRIDE_1 && + hwreg.type == BRW_REGISTER_TYPE_F) { + debug_printf("vec%d", hwreg.nr); + } + else if (hwreg.file == BRW_GENERAL_REGISTER_FILE && + hwreg.vstride == BRW_VERTICAL_STRIDE_0 && + hwreg.width == BRW_WIDTH_1 && + hwreg.hstride == BRW_HORIZONTAL_STRIDE_0 && + hwreg.type == BRW_REGISTER_TYPE_F) { + debug_printf("scl%d.%d", hwreg.nr, hwreg.subnr / 4); + } + else { + debug_printf("%s%d.%d<%d;%d,%d>:%s", + file[hwreg.file], + hwreg.nr, + hwreg.subnr / type_sz(hwreg.type), + hwreg.vstride ? (1<<(hwreg.vstride-1)) : 0, + 1< + */ + + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_eu.h" + + + + +/*********************************************************************** + * Internal helper for constructing instructions + */ + +static void guess_execution_size( struct brw_instruction *insn, + struct brw_reg reg ) +{ + if (reg.width == BRW_WIDTH_8 && + insn->header.compression_control == BRW_COMPRESSION_COMPRESSED) + insn->header.execution_size = BRW_EXECUTE_16; + else + insn->header.execution_size = reg.width; /* note - definitions are compatible */ +} + + +static void brw_set_dest( struct brw_instruction *insn, + struct brw_reg dest ) +{ + insn->bits1.da1.dest_reg_file = dest.file; + insn->bits1.da1.dest_reg_type = dest.type; + insn->bits1.da1.dest_address_mode = dest.address_mode; + + if (dest.address_mode == BRW_ADDRESS_DIRECT) { + insn->bits1.da1.dest_reg_nr = dest.nr; + + if (insn->header.access_mode == BRW_ALIGN_1) { + insn->bits1.da1.dest_subreg_nr = dest.subnr; + insn->bits1.da1.dest_horiz_stride = BRW_HORIZONTAL_STRIDE_1; + } + else { + insn->bits1.da16.dest_subreg_nr = dest.subnr / 16; + insn->bits1.da16.dest_writemask = dest.dw1.bits.writemask; + } + } + else { + insn->bits1.ia1.dest_subreg_nr = dest.subnr; + + /* These are different sizes in align1 vs align16: + */ + if (insn->header.access_mode == BRW_ALIGN_1) { + insn->bits1.ia1.dest_indirect_offset = dest.dw1.bits.indirect_offset; + insn->bits1.ia1.dest_horiz_stride = BRW_HORIZONTAL_STRIDE_1; + } + else { + insn->bits1.ia16.dest_indirect_offset = dest.dw1.bits.indirect_offset; + } + } + + /* NEW: Set the execution size based on dest.width and + * insn->compression_control: + */ + guess_execution_size(insn, dest); +} + +static void brw_set_src0( struct brw_instruction *insn, + struct brw_reg reg ) +{ + assert(reg.file != BRW_MESSAGE_REGISTER_FILE); + + insn->bits1.da1.src0_reg_file = reg.file; + insn->bits1.da1.src0_reg_type = reg.type; + insn->bits2.da1.src0_abs = reg.abs; + insn->bits2.da1.src0_negate = reg.negate; + insn->bits2.da1.src0_address_mode = reg.address_mode; + + if (reg.file == BRW_IMMEDIATE_VALUE) { + insn->bits3.ud = reg.dw1.ud; + + /* Required to set some fields in src1 as well: + */ + insn->bits1.da1.src1_reg_file = 0; /* arf */ + insn->bits1.da1.src1_reg_type = reg.type; + } + else + { + if (reg.address_mode == BRW_ADDRESS_DIRECT) { + if (insn->header.access_mode == BRW_ALIGN_1) { + insn->bits2.da1.src0_subreg_nr = reg.subnr; + insn->bits2.da1.src0_reg_nr = reg.nr; + } + else { + insn->bits2.da16.src0_subreg_nr = reg.subnr / 16; + insn->bits2.da16.src0_reg_nr = reg.nr; + } + } + else { + insn->bits2.ia1.src0_subreg_nr = reg.subnr; + + if (insn->header.access_mode == BRW_ALIGN_1) { + insn->bits2.ia1.src0_indirect_offset = reg.dw1.bits.indirect_offset; + } + else { + insn->bits2.ia16.src0_subreg_nr = reg.dw1.bits.indirect_offset; + } + } + + if (insn->header.access_mode == BRW_ALIGN_1) { + if (reg.width == BRW_WIDTH_1 && + insn->header.execution_size == BRW_EXECUTE_1) { + insn->bits2.da1.src0_horiz_stride = BRW_HORIZONTAL_STRIDE_0; + insn->bits2.da1.src0_width = BRW_WIDTH_1; + insn->bits2.da1.src0_vert_stride = BRW_VERTICAL_STRIDE_0; + } + else { + insn->bits2.da1.src0_horiz_stride = reg.hstride; + insn->bits2.da1.src0_width = reg.width; + insn->bits2.da1.src0_vert_stride = reg.vstride; + } + } + else { + insn->bits2.da16.src0_swz_x = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_X); + insn->bits2.da16.src0_swz_y = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Y); + insn->bits2.da16.src0_swz_z = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Z); + insn->bits2.da16.src0_swz_w = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_W); + + /* This is an oddity of the fact we're using the same + * descriptions for registers in align_16 as align_1: + */ + if (reg.vstride == BRW_VERTICAL_STRIDE_8) + insn->bits2.da16.src0_vert_stride = BRW_VERTICAL_STRIDE_4; + else + insn->bits2.da16.src0_vert_stride = reg.vstride; + } + } +} + + +void brw_set_src1( struct brw_instruction *insn, + struct brw_reg reg ) +{ + assert(reg.file != BRW_MESSAGE_REGISTER_FILE); + + insn->bits1.da1.src1_reg_file = reg.file; + insn->bits1.da1.src1_reg_type = reg.type; + insn->bits3.da1.src1_abs = reg.abs; + insn->bits3.da1.src1_negate = reg.negate; + + /* Only src1 can be immediate in two-argument instructions. + */ + assert(insn->bits1.da1.src0_reg_file != BRW_IMMEDIATE_VALUE); + + if (reg.file == BRW_IMMEDIATE_VALUE) { + insn->bits3.ud = reg.dw1.ud; + } + else { + /* This is a hardware restriction, which may or may not be lifted + * in the future: + */ + assert (reg.address_mode == BRW_ADDRESS_DIRECT); + //assert (reg.file == BRW_GENERAL_REGISTER_FILE); + + if (insn->header.access_mode == BRW_ALIGN_1) { + insn->bits3.da1.src1_subreg_nr = reg.subnr; + insn->bits3.da1.src1_reg_nr = reg.nr; + } + else { + insn->bits3.da16.src1_subreg_nr = reg.subnr / 16; + insn->bits3.da16.src1_reg_nr = reg.nr; + } + + if (insn->header.access_mode == BRW_ALIGN_1) { + if (reg.width == BRW_WIDTH_1 && + insn->header.execution_size == BRW_EXECUTE_1) { + insn->bits3.da1.src1_horiz_stride = BRW_HORIZONTAL_STRIDE_0; + insn->bits3.da1.src1_width = BRW_WIDTH_1; + insn->bits3.da1.src1_vert_stride = BRW_VERTICAL_STRIDE_0; + } + else { + insn->bits3.da1.src1_horiz_stride = reg.hstride; + insn->bits3.da1.src1_width = reg.width; + insn->bits3.da1.src1_vert_stride = reg.vstride; + } + } + else { + insn->bits3.da16.src1_swz_x = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_X); + insn->bits3.da16.src1_swz_y = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Y); + insn->bits3.da16.src1_swz_z = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_Z); + insn->bits3.da16.src1_swz_w = BRW_GET_SWZ(reg.dw1.bits.swizzle, BRW_CHANNEL_W); + + /* This is an oddity of the fact we're using the same + * descriptions for registers in align_16 as align_1: + */ + if (reg.vstride == BRW_VERTICAL_STRIDE_8) + insn->bits3.da16.src1_vert_stride = BRW_VERTICAL_STRIDE_4; + else + insn->bits3.da16.src1_vert_stride = reg.vstride; + } + } +} + + + +static void brw_set_math_message( struct brw_instruction *insn, + unsigned msg_length, + unsigned response_length, + unsigned function, + unsigned integer_type, + boolean low_precision, + boolean saturate, + unsigned dataType ) +{ + brw_set_src1(insn, brw_imm_d(0)); + + insn->bits3.math.function = function; + insn->bits3.math.int_type = integer_type; + insn->bits3.math.precision = low_precision; + insn->bits3.math.saturate = saturate; + insn->bits3.math.data_type = dataType; + insn->bits3.math.response_length = response_length; + insn->bits3.math.msg_length = msg_length; + insn->bits3.math.msg_target = BRW_MESSAGE_TARGET_MATH; + insn->bits3.math.end_of_thread = 0; +} + +static void brw_set_urb_message( struct brw_instruction *insn, + boolean allocate, + boolean used, + unsigned msg_length, + unsigned response_length, + boolean end_of_thread, + boolean complete, + unsigned offset, + unsigned swizzle_control ) +{ + brw_set_src1(insn, brw_imm_d(0)); + + insn->bits3.urb.opcode = 0; /* ? */ + insn->bits3.urb.offset = offset; + insn->bits3.urb.swizzle_control = swizzle_control; + insn->bits3.urb.allocate = allocate; + insn->bits3.urb.used = used; /* ? */ + insn->bits3.urb.complete = complete; + insn->bits3.urb.response_length = response_length; + insn->bits3.urb.msg_length = msg_length; + insn->bits3.urb.msg_target = BRW_MESSAGE_TARGET_URB; + insn->bits3.urb.end_of_thread = end_of_thread; +} + +static void brw_set_dp_write_message( struct brw_instruction *insn, + unsigned binding_table_index, + unsigned msg_control, + unsigned msg_type, + unsigned msg_length, + unsigned pixel_scoreboard_clear, + unsigned response_length, + unsigned end_of_thread ) +{ + brw_set_src1(insn, brw_imm_d(0)); + + insn->bits3.dp_write.binding_table_index = binding_table_index; + insn->bits3.dp_write.msg_control = msg_control; + insn->bits3.dp_write.pixel_scoreboard_clear = pixel_scoreboard_clear; + insn->bits3.dp_write.msg_type = msg_type; + insn->bits3.dp_write.send_commit_msg = 0; + insn->bits3.dp_write.response_length = response_length; + insn->bits3.dp_write.msg_length = msg_length; + insn->bits3.dp_write.msg_target = BRW_MESSAGE_TARGET_DATAPORT_WRITE; + insn->bits3.urb.end_of_thread = end_of_thread; +} + +static void brw_set_dp_read_message( struct brw_instruction *insn, + unsigned binding_table_index, + unsigned msg_control, + unsigned msg_type, + unsigned target_cache, + unsigned msg_length, + unsigned response_length, + unsigned end_of_thread ) +{ + brw_set_src1(insn, brw_imm_d(0)); + + insn->bits3.dp_read.binding_table_index = binding_table_index; + insn->bits3.dp_read.msg_control = msg_control; + insn->bits3.dp_read.msg_type = msg_type; + insn->bits3.dp_read.target_cache = target_cache; + insn->bits3.dp_read.response_length = response_length; + insn->bits3.dp_read.msg_length = msg_length; + insn->bits3.dp_read.msg_target = BRW_MESSAGE_TARGET_DATAPORT_READ; + insn->bits3.dp_read.end_of_thread = end_of_thread; +} + +static void brw_set_sampler_message( struct brw_instruction *insn, + unsigned binding_table_index, + unsigned sampler, + unsigned msg_type, + unsigned response_length, + unsigned msg_length, + boolean eot) +{ + brw_set_src1(insn, brw_imm_d(0)); + + insn->bits3.sampler.binding_table_index = binding_table_index; + insn->bits3.sampler.sampler = sampler; + insn->bits3.sampler.msg_type = msg_type; + insn->bits3.sampler.return_format = BRW_SAMPLER_RETURN_FORMAT_FLOAT32; + insn->bits3.sampler.response_length = response_length; + insn->bits3.sampler.msg_length = msg_length; + insn->bits3.sampler.end_of_thread = eot; + insn->bits3.sampler.msg_target = BRW_MESSAGE_TARGET_SAMPLER; +} + + + +static struct brw_instruction *next_insn( struct brw_compile *p, + unsigned opcode ) +{ + struct brw_instruction *insn; + + assert(p->nr_insn + 1 < BRW_EU_MAX_INSN); + + insn = &p->store[p->nr_insn++]; + memcpy(insn, p->current, sizeof(*insn)); + + /* Reset this one-shot flag: + */ + + if (p->current->header.destreg__conditonalmod) { + p->current->header.destreg__conditonalmod = 0; + p->current->header.predicate_control = BRW_PREDICATE_NORMAL; + } + + insn->header.opcode = opcode; + return insn; +} + + +struct brw_instruction *brw_alu1( struct brw_compile *p, + unsigned opcode, + struct brw_reg dest, + struct brw_reg src ) +{ + struct brw_instruction *insn = next_insn(p, opcode); + brw_set_dest(insn, dest); + brw_set_src0(insn, src); + return insn; +} + +struct brw_instruction *brw_alu2(struct brw_compile *p, + unsigned opcode, + struct brw_reg dest, + struct brw_reg src0, + struct brw_reg src1 ) +{ + struct brw_instruction *insn = next_insn(p, opcode); + brw_set_dest(insn, dest); + brw_set_src0(insn, src0); + brw_set_src1(insn, src1); + return insn; +} + + +/*********************************************************************** + * Convenience routines. + */ +#define ALU1(OP) \ +struct brw_instruction *brw_##OP(struct brw_compile *p, \ + struct brw_reg dest, \ + struct brw_reg src0) \ +{ \ + return brw_alu1(p, BRW_OPCODE_##OP, dest, src0); \ +} + +#define ALU2(OP) \ +struct brw_instruction *brw_##OP(struct brw_compile *p, \ + struct brw_reg dest, \ + struct brw_reg src0, \ + struct brw_reg src1) \ +{ \ + return brw_alu2(p, BRW_OPCODE_##OP, dest, src0, src1); \ +} + + +ALU1(MOV) +ALU2(SEL) +ALU1(NOT) +ALU2(AND) +ALU2(OR) +ALU2(XOR) +ALU2(SHR) +ALU2(SHL) +ALU2(RSR) +ALU2(RSL) +ALU2(ASR) +ALU2(ADD) +ALU2(MUL) +ALU1(FRC) +ALU1(RNDD) +ALU2(MAC) +ALU2(MACH) +ALU1(LZD) +ALU2(DP4) +ALU2(DPH) +ALU2(DP3) +ALU2(DP2) +ALU2(LINE) + + + + +void brw_NOP(struct brw_compile *p) +{ + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_NOP); + brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src1(insn, brw_imm_ud(0x0)); +} + + + + + +/*********************************************************************** + * Comparisons, if/else/endif + */ + +struct brw_instruction *brw_JMPI(struct brw_compile *p, + struct brw_reg dest, + struct brw_reg src0, + struct brw_reg src1) +{ + struct brw_instruction *insn = brw_alu2(p, BRW_OPCODE_JMPI, dest, src0, src1); + + p->current->header.predicate_control = BRW_PREDICATE_NONE; + + return insn; +} + +/* EU takes the value from the flag register and pushes it onto some + * sort of a stack (presumably merging with any flag value already on + * the stack). Within an if block, the flags at the top of the stack + * control execution on each channel of the unit, eg. on each of the + * 16 pixel values in our wm programs. + * + * When the matching 'else' instruction is reached (presumably by + * countdown of the instruction count patched in by our ELSE/ENDIF + * functions), the relevent flags are inverted. + * + * When the matching 'endif' instruction is reached, the flags are + * popped off. If the stack is now empty, normal execution resumes. + * + * No attempt is made to deal with stack overflow (14 elements?). + */ +struct brw_instruction *brw_IF(struct brw_compile *p, unsigned execute_size) +{ + struct brw_instruction *insn; + + if (p->single_program_flow) { + assert(execute_size == BRW_EXECUTE_1); + + insn = next_insn(p, BRW_OPCODE_ADD); + insn->header.predicate_inverse = 1; + } else { + insn = next_insn(p, BRW_OPCODE_IF); + } + + /* Override the defaults for this instruction: + */ + brw_set_dest(insn, brw_ip_reg()); + brw_set_src0(insn, brw_ip_reg()); + brw_set_src1(insn, brw_imm_d(0x0)); + + insn->header.execution_size = execute_size; + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.predicate_control = BRW_PREDICATE_NORMAL; + insn->header.mask_control = BRW_MASK_ENABLE; + + p->current->header.predicate_control = BRW_PREDICATE_NONE; + + return insn; +} + + +struct brw_instruction *brw_ELSE(struct brw_compile *p, + struct brw_instruction *if_insn) +{ + struct brw_instruction *insn; + + if (p->single_program_flow) { + insn = next_insn(p, BRW_OPCODE_ADD); + } else { + insn = next_insn(p, BRW_OPCODE_ELSE); + } + + brw_set_dest(insn, brw_ip_reg()); + brw_set_src0(insn, brw_ip_reg()); + brw_set_src1(insn, brw_imm_d(0x0)); + + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.execution_size = if_insn->header.execution_size; + insn->header.mask_control = BRW_MASK_ENABLE; + + /* Patch the if instruction to point at this instruction. + */ + if (p->single_program_flow) { + assert(if_insn->header.opcode == BRW_OPCODE_ADD); + + if_insn->bits3.ud = (insn - if_insn + 1) * 16; + } else { + assert(if_insn->header.opcode == BRW_OPCODE_IF); + + if_insn->bits3.if_else.jump_count = insn - if_insn; + if_insn->bits3.if_else.pop_count = 1; + if_insn->bits3.if_else.pad0 = 0; + } + + return insn; +} + +void brw_ENDIF(struct brw_compile *p, + struct brw_instruction *patch_insn) +{ + if (p->single_program_flow) { + /* In single program flow mode, there's no need to execute an ENDIF, + * since we don't need to do any stack operations, and if we're executing + * currently, we want to just continue executing. + */ + struct brw_instruction *next = &p->store[p->nr_insn]; + + assert(patch_insn->header.opcode == BRW_OPCODE_ADD); + + patch_insn->bits3.ud = (next - patch_insn) * 16; + } else { + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ENDIF); + + brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src1(insn, brw_imm_d(0x0)); + + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.execution_size = patch_insn->header.execution_size; + insn->header.mask_control = BRW_MASK_ENABLE; + + assert(patch_insn->bits3.if_else.jump_count == 0); + + /* Patch the if or else instructions to point at this or the next + * instruction respectively. + */ + if (patch_insn->header.opcode == BRW_OPCODE_IF) { + /* Automagically turn it into an IFF: + */ + patch_insn->header.opcode = BRW_OPCODE_IFF; + patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; + patch_insn->bits3.if_else.pop_count = 0; + patch_insn->bits3.if_else.pad0 = 0; + } else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) { + patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; + patch_insn->bits3.if_else.pop_count = 1; + patch_insn->bits3.if_else.pad0 = 0; + } else { + assert(0); + } + + /* Also pop item off the stack in the endif instruction: + */ + insn->bits3.if_else.jump_count = 0; + insn->bits3.if_else.pop_count = 1; + insn->bits3.if_else.pad0 = 0; + } +} + +struct brw_instruction *brw_BREAK(struct brw_compile *p) +{ + struct brw_instruction *insn; + insn = next_insn(p, BRW_OPCODE_BREAK); + brw_set_dest(insn, brw_ip_reg()); + brw_set_src0(insn, brw_ip_reg()); + brw_set_src1(insn, brw_imm_d(0x0)); + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.execution_size = BRW_EXECUTE_8; + insn->header.mask_control = BRW_MASK_DISABLE; + insn->bits3.if_else.pad0 = 0; + return insn; +} + +struct brw_instruction *brw_CONT(struct brw_compile *p) +{ + struct brw_instruction *insn; + insn = next_insn(p, BRW_OPCODE_CONTINUE); + brw_set_dest(insn, brw_ip_reg()); + brw_set_src0(insn, brw_ip_reg()); + brw_set_src1(insn, brw_imm_d(0x0)); + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.execution_size = BRW_EXECUTE_8; + insn->header.mask_control = BRW_MASK_DISABLE; + insn->bits3.if_else.pad0 = 0; + return insn; +} + +/* DO/WHILE loop: + */ +struct brw_instruction *brw_DO(struct brw_compile *p, unsigned execute_size) +{ + if (p->single_program_flow) { + return &p->store[p->nr_insn]; + } else { + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_DO); + + /* Override the defaults for this instruction: + */ + brw_set_dest(insn, brw_null_reg()); + brw_set_src0(insn, brw_null_reg()); + brw_set_src1(insn, brw_null_reg()); + + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.execution_size = execute_size; + insn->header.predicate_control = BRW_PREDICATE_NONE; + /* insn->header.mask_control = BRW_MASK_ENABLE; */ + insn->header.mask_control = BRW_MASK_DISABLE; + + return insn; + } +} + + + +struct brw_instruction *brw_WHILE(struct brw_compile *p, + struct brw_instruction *do_insn) +{ + struct brw_instruction *insn; + + if (p->single_program_flow) + insn = next_insn(p, BRW_OPCODE_ADD); + else + insn = next_insn(p, BRW_OPCODE_WHILE); + + brw_set_dest(insn, brw_ip_reg()); + brw_set_src0(insn, brw_ip_reg()); + brw_set_src1(insn, brw_imm_d(0x0)); + + insn->header.compression_control = BRW_COMPRESSION_NONE; + + if (p->single_program_flow) { + insn->header.execution_size = BRW_EXECUTE_1; + + insn->bits3.d = (do_insn - insn) * 16; + } else { + insn->header.execution_size = do_insn->header.execution_size; + + assert(do_insn->header.opcode == BRW_OPCODE_DO); + insn->bits3.if_else.jump_count = do_insn - insn; + insn->bits3.if_else.pop_count = 0; + insn->bits3.if_else.pad0 = 0; + } + +/* insn->header.mask_control = BRW_MASK_ENABLE; */ + + insn->header.mask_control = BRW_MASK_DISABLE; + p->current->header.predicate_control = BRW_PREDICATE_NONE; + return insn; +} + + +/* FORWARD JUMPS: + */ +void brw_land_fwd_jump(struct brw_compile *p, + struct brw_instruction *jmp_insn) +{ + struct brw_instruction *landing = &p->store[p->nr_insn]; + + assert(jmp_insn->header.opcode == BRW_OPCODE_JMPI); + assert(jmp_insn->bits1.da1.src1_reg_file = BRW_IMMEDIATE_VALUE); + + jmp_insn->bits3.ud = (landing - jmp_insn) - 1; +} + + + +/* To integrate with the above, it makes sense that the comparison + * instruction should populate the flag register. It might be simpler + * just to use the flag reg for most WM tasks? + */ +void brw_CMP(struct brw_compile *p, + struct brw_reg dest, + unsigned conditional, + struct brw_reg src0, + struct brw_reg src1) +{ + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_CMP); + + insn->header.destreg__conditonalmod = conditional; + brw_set_dest(insn, dest); + brw_set_src0(insn, src0); + brw_set_src1(insn, src1); + +/* guess_execution_size(insn, src0); */ + + + /* Make it so that future instructions will use the computed flag + * value until brw_set_predicate_control_flag_value() is called + * again. + */ + if (dest.file == BRW_ARCHITECTURE_REGISTER_FILE && + dest.nr == 0) { + p->current->header.predicate_control = BRW_PREDICATE_NORMAL; + p->flag_value = 0xff; + } +} + + + +/*********************************************************************** + * Helpers for the various SEND message types: + */ + +/* Invert 8 values + */ +void brw_math( struct brw_compile *p, + struct brw_reg dest, + unsigned function, + unsigned saturate, + unsigned msg_reg_nr, + struct brw_reg src, + unsigned data_type, + unsigned precision ) +{ + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); + unsigned msg_length = (function == BRW_MATH_FUNCTION_POW) ? 2 : 1; + unsigned response_length = (function == BRW_MATH_FUNCTION_SINCOS) ? 2 : 1; + + /* Example code doesn't set predicate_control for send + * instructions. + */ + insn->header.predicate_control = 0; + insn->header.destreg__conditonalmod = msg_reg_nr; + + brw_set_dest(insn, dest); + brw_set_src0(insn, src); + brw_set_math_message(insn, + msg_length, response_length, + function, + BRW_MATH_INTEGER_UNSIGNED, + precision, + saturate, + data_type); +} + +/* Use 2 send instructions to invert 16 elements + */ +void brw_math_16( struct brw_compile *p, + struct brw_reg dest, + unsigned function, + unsigned saturate, + unsigned msg_reg_nr, + struct brw_reg src, + unsigned precision ) +{ + struct brw_instruction *insn; + unsigned msg_length = (function == BRW_MATH_FUNCTION_POW) ? 2 : 1; + unsigned response_length = (function == BRW_MATH_FUNCTION_SINCOS) ? 2 : 1; + + /* First instruction: + */ + brw_push_insn_state(p); + brw_set_predicate_control_flag_value(p, 0xff); + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + + insn = next_insn(p, BRW_OPCODE_SEND); + insn->header.destreg__conditonalmod = msg_reg_nr; + + brw_set_dest(insn, dest); + brw_set_src0(insn, src); + brw_set_math_message(insn, + msg_length, response_length, + function, + BRW_MATH_INTEGER_UNSIGNED, + precision, + saturate, + BRW_MATH_DATA_VECTOR); + + /* Second instruction: + */ + insn = next_insn(p, BRW_OPCODE_SEND); + insn->header.compression_control = BRW_COMPRESSION_2NDHALF; + insn->header.destreg__conditonalmod = msg_reg_nr+1; + + brw_set_dest(insn, offset(dest,1)); + brw_set_src0(insn, src); + brw_set_math_message(insn, + msg_length, response_length, + function, + BRW_MATH_INTEGER_UNSIGNED, + precision, + saturate, + BRW_MATH_DATA_VECTOR); + + brw_pop_insn_state(p); +} + + + + +void brw_dp_WRITE_16( struct brw_compile *p, + struct brw_reg src, + unsigned msg_reg_nr, + unsigned scratch_offset ) +{ + { + brw_push_insn_state(p); + brw_set_mask_control(p, BRW_MASK_DISABLE); + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + + brw_MOV(p, + retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_D), + brw_imm_d(scratch_offset)); + + brw_pop_insn_state(p); + } + + { + unsigned msg_length = 3; + struct brw_reg dest = retype(brw_null_reg(), BRW_REGISTER_TYPE_UW); + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); + + insn->header.predicate_control = 0; /* XXX */ + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.destreg__conditonalmod = msg_reg_nr; + + brw_set_dest(insn, dest); + brw_set_src0(insn, src); + + brw_set_dp_write_message(insn, + 255, /* bti */ + BRW_DATAPORT_OWORD_BLOCK_4_OWORDS, /* msg_control */ + BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE, /* msg_type */ + msg_length, + 0, /* pixel scoreboard */ + 0, /* response_length */ + 0); /* eot */ + } + +} + + +void brw_dp_READ_16( struct brw_compile *p, + struct brw_reg dest, + unsigned msg_reg_nr, + unsigned scratch_offset ) +{ + { + brw_push_insn_state(p); + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + brw_set_mask_control(p, BRW_MASK_DISABLE); + + brw_MOV(p, + retype(brw_vec1_grf(0, 2), BRW_REGISTER_TYPE_D), + brw_imm_d(scratch_offset)); + + brw_pop_insn_state(p); + } + + { + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); + + insn->header.predicate_control = 0; /* XXX */ + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.destreg__conditonalmod = msg_reg_nr; + + brw_set_dest(insn, dest); /* UW? */ + brw_set_src0(insn, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW)); + + brw_set_dp_read_message(insn, + 255, /* bti */ + 3, /* msg_control */ + BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */ + 1, /* target cache */ + 1, /* msg_length */ + 2, /* response_length */ + 0); /* eot */ + } +} + + +void brw_fb_WRITE(struct brw_compile *p, + struct brw_reg dest, + unsigned msg_reg_nr, + struct brw_reg src0, + unsigned binding_table_index, + unsigned msg_length, + unsigned response_length, + boolean eot) +{ + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); + + insn->header.predicate_control = 0; /* XXX */ + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.destreg__conditonalmod = msg_reg_nr; + + brw_set_dest(insn, dest); + brw_set_src0(insn, src0); + brw_set_dp_write_message(insn, + binding_table_index, + BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE, /* msg_control */ + BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE, /* msg_type */ + msg_length, + 1, /* pixel scoreboard */ + response_length, + eot); +} + + + +void brw_SAMPLE(struct brw_compile *p, + struct brw_reg dest, + unsigned msg_reg_nr, + struct brw_reg src0, + unsigned binding_table_index, + unsigned sampler, + unsigned writemask, + unsigned msg_type, + unsigned response_length, + unsigned msg_length, + boolean eot) +{ + boolean need_stall = 0; + + if(writemask == 0) { +/* debug_printf("%s: zero writemask??\n", __FUNCTION__); */ + return; + } + + /* Hardware doesn't do destination dependency checking on send + * instructions properly. Add a workaround which generates the + * dependency by other means. In practice it seems like this bug + * only crops up for texture samples, and only where registers are + * written by the send and then written again later without being + * read in between. Luckily for us, we already track that + * information and use it to modify the writemask for the + * instruction, so that is a guide for whether a workaround is + * needed. + */ + if (writemask != TGSI_WRITEMASK_XYZW) { + unsigned dst_offset = 0; + unsigned i, newmask = 0, len = 0; + + for (i = 0; i < 4; i++) { + if (writemask & (1<header.predicate_control = 0; /* XXX */ + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.destreg__conditonalmod = msg_reg_nr; + + brw_set_dest(insn, dest); + brw_set_src0(insn, src0); + brw_set_sampler_message(insn, + binding_table_index, + sampler, + msg_type, + response_length, + msg_length, + eot); + } + + if (need_stall) + { + struct brw_reg reg = vec8(offset(dest, response_length-1)); + + /* mov (8) r9.0<1>:f r9.0<8;8,1>:f { Align1 } + */ + brw_push_insn_state(p); + brw_set_compression_control(p, FALSE); + brw_MOV(p, reg, reg); + brw_pop_insn_state(p); + } + +} + +/* All these variables are pretty confusing - we might be better off + * using bitmasks and macros for this, in the old style. Or perhaps + * just having the caller instantiate the fields in dword3 itself. + */ +void brw_urb_WRITE(struct brw_compile *p, + struct brw_reg dest, + unsigned msg_reg_nr, + struct brw_reg src0, + boolean allocate, + boolean used, + unsigned msg_length, + unsigned response_length, + boolean eot, + boolean writes_complete, + unsigned offset, + unsigned swizzle) +{ + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); + + assert(msg_length < 16); + + brw_set_dest(insn, dest); + brw_set_src0(insn, src0); + brw_set_src1(insn, brw_imm_d(0)); + + insn->header.destreg__conditonalmod = msg_reg_nr; + + brw_set_urb_message(insn, + allocate, + used, + msg_length, + response_length, + eot, + writes_complete, + offset, + swizzle); +} + diff --git a/src/gallium/drivers/i965simple/brw_eu_util.c b/src/gallium/drivers/i965simple/brw_eu_util.c new file mode 100644 index 0000000000..3a65b141f0 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_eu_util.c @@ -0,0 +1,126 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_eu.h" + + +void brw_math_invert( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg src) +{ + brw_math( p, + dst, + BRW_MATH_FUNCTION_INV, + BRW_MATH_SATURATE_NONE, + 0, + src, + BRW_MATH_PRECISION_FULL, + BRW_MATH_DATA_VECTOR ); +} + + + +void brw_copy4(struct brw_compile *p, + struct brw_reg dst, + struct brw_reg src, + unsigned count) +{ + unsigned i; + + dst = vec4(dst); + src = vec4(src); + + for (i = 0; i < count; i++) + { + unsigned delta = i*32; + brw_MOV(p, byte_offset(dst, delta), byte_offset(src, delta)); + brw_MOV(p, byte_offset(dst, delta+16), byte_offset(src, delta+16)); + } +} + + +void brw_copy8(struct brw_compile *p, + struct brw_reg dst, + struct brw_reg src, + unsigned count) +{ + unsigned i; + + dst = vec8(dst); + src = vec8(src); + + for (i = 0; i < count; i++) + { + unsigned delta = i*32; + brw_MOV(p, byte_offset(dst, delta), byte_offset(src, delta)); + } +} + + +void brw_copy_indirect_to_indirect(struct brw_compile *p, + struct brw_indirect dst_ptr, + struct brw_indirect src_ptr, + unsigned count) +{ + unsigned i; + + for (i = 0; i < count; i++) + { + unsigned delta = i*32; + brw_MOV(p, deref_4f(dst_ptr, delta), deref_4f(src_ptr, delta)); + brw_MOV(p, deref_4f(dst_ptr, delta+16), deref_4f(src_ptr, delta+16)); + } +} + + +void brw_copy_from_indirect(struct brw_compile *p, + struct brw_reg dst, + struct brw_indirect ptr, + unsigned count) +{ + unsigned i; + + dst = vec4(dst); + + for (i = 0; i < count; i++) + { + unsigned delta = i*32; + brw_MOV(p, byte_offset(dst, delta), deref_4f(ptr, delta)); + brw_MOV(p, byte_offset(dst, delta+16), deref_4f(ptr, delta+16)); + } +} + + + + diff --git a/src/gallium/drivers/i965simple/brw_flush.c b/src/gallium/drivers/i965simple/brw_flush.c new file mode 100644 index 0000000000..5216c680cf --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_flush.c @@ -0,0 +1,80 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + + +#include "pipe/p_defines.h" +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_batch.h" + + +/** + * In future we may want a fence-like interface instead of finish. + */ +static void brw_flush( struct pipe_context *pipe, + unsigned flags ) +{ + struct brw_context *brw = brw_context(pipe); + struct pipe_fence_handle *fence; + + /* Do we need to emit an MI_FLUSH command to flush the hardware + * caches? + */ + if (flags & (PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE)) { + struct brw_mi_flush flush; + + memset(&flush, 0, sizeof(flush)); + flush.opcode = CMD_MI_FLUSH; + + if (!(flags & PIPE_FLUSH_RENDER_CACHE)) + flush.flags |= BRW_INHIBIT_FLUSH_RENDER_CACHE; + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) + flush.flags |= BRW_FLUSH_READ_CACHE; + + BRW_BATCH_STRUCT(brw, &flush); + } + + /* If there are no flags, just flush pending commands to hardware: + */ + FLUSH_BATCH( &fence ); + + if (flags & PIPE_FLUSH_WAIT) { +// brw->winsys->wait_fence(brw->winsys, fence); + } +} + + + +void brw_init_flush_functions( struct brw_context *brw ) +{ + brw->pipe.flush = brw_flush; +} diff --git a/src/gallium/drivers/i965simple/brw_gs.c b/src/gallium/drivers/i965simple/brw_gs.c new file mode 100644 index 0000000000..de60868ccc --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_gs.c @@ -0,0 +1,196 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_util.h" +#include "brw_state.h" +#include "brw_gs.h" + + + +static void compile_gs_prog( struct brw_context *brw, + struct brw_gs_prog_key *key ) +{ + struct brw_gs_compile c; + const unsigned *program; + unsigned program_size; + + memset(&c, 0, sizeof(c)); + + c.key = *key; + + /* Need to locate the two positions present in vertex + header. + * These are currently hardcoded: + */ + c.nr_attrs = brw_count_bits(c.key.attrs); + c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */ + c.nr_bytes = c.nr_regs * REG_SIZE; + + + /* Begin the compilation: + */ + brw_init_compile(&c.func); + + c.func.single_program_flow = 1; + + /* For some reason the thread is spawned with only 4 channels + * unmasked. + */ + brw_set_mask_control(&c.func, BRW_MASK_DISABLE); + + + /* Note that primitives which don't require a GS program have + * already been weeded out by this stage: + */ + switch (key->primitive) { + case PIPE_PRIM_QUADS: + brw_gs_quads( &c ); + break; + case PIPE_PRIM_QUAD_STRIP: + brw_gs_quad_strip( &c ); + break; + case PIPE_PRIM_LINE_LOOP: + brw_gs_lines( &c ); + break; + case PIPE_PRIM_LINES: + if (key->hint_gs_always) + brw_gs_lines( &c ); + else { + return; + } + break; + case PIPE_PRIM_TRIANGLES: + if (key->hint_gs_always) + brw_gs_tris( &c ); + else { + return; + } + break; + case PIPE_PRIM_POINTS: + if (key->hint_gs_always) + brw_gs_points( &c ); + else { + return; + } + break; + default: + return; + } + + /* get the program + */ + program = brw_get_program(&c.func, &program_size); + + /* Upload + */ + brw->gs.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_GS_PROG], + &c.key, + sizeof(c.key), + program, + program_size, + &c.prog_data, + &brw->gs.prog_data ); +} + + +static boolean search_cache( struct brw_context *brw, + struct brw_gs_prog_key *key ) +{ + return brw_search_cache(&brw->cache[BRW_GS_PROG], + key, sizeof(*key), + &brw->gs.prog_data, + &brw->gs.prog_gs_offset); +} + + +static const int gs_prim[PIPE_PRIM_POLYGON+1] = { + PIPE_PRIM_POINTS, + PIPE_PRIM_LINES, + PIPE_PRIM_LINE_LOOP, + PIPE_PRIM_LINES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_QUADS, + PIPE_PRIM_QUAD_STRIP, + PIPE_PRIM_TRIANGLES +}; + +static void populate_key( struct brw_context *brw, + struct brw_gs_prog_key *key ) +{ + memset(key, 0, sizeof(*key)); + + /* CACHE_NEW_VS_PROG */ + key->attrs = brw->vs.prog_data->outputs_written; + + /* BRW_NEW_PRIMITIVE */ + key->primitive = gs_prim[brw->primitive]; + + key->hint_gs_always = 0; /* debug code? */ + + key->need_gs_prog = (key->hint_gs_always || + brw->primitive == PIPE_PRIM_QUADS || + brw->primitive == PIPE_PRIM_QUAD_STRIP || + brw->primitive == PIPE_PRIM_LINE_LOOP); +} + +/* Calculate interpolants for triangle and line rasterization. + */ +static void upload_gs_prog( struct brw_context *brw ) +{ + struct brw_gs_prog_key key; + + /* Populate the key: + */ + populate_key(brw, &key); + + if (brw->gs.prog_active != key.need_gs_prog) { + brw->state.dirty.cache |= CACHE_NEW_GS_PROG; + brw->gs.prog_active = key.need_gs_prog; + } + + if (brw->gs.prog_active) { + if (!search_cache(brw, &key)) + compile_gs_prog( brw, &key ); + } +} + + +const struct brw_tracked_state brw_gs_prog = { + .dirty = { + .brw = BRW_NEW_PRIMITIVE, + .cache = CACHE_NEW_VS_PROG + }, + .update = upload_gs_prog +}; diff --git a/src/gallium/drivers/i965simple/brw_gs.h b/src/gallium/drivers/i965simple/brw_gs.h new file mode 100644 index 0000000000..f09141c6aa --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_gs.h @@ -0,0 +1,75 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRW_GS_H +#define BRW_GS_H + + +#include "brw_context.h" +#include "brw_eu.h" + +#define MAX_GS_VERTS (4) + +struct brw_gs_prog_key { + unsigned attrs:32; + unsigned primitive:4; + unsigned hint_gs_always:1; + unsigned need_gs_prog:1; + unsigned pad:26; +}; + +struct brw_gs_compile { + struct brw_compile func; + struct brw_gs_prog_key key; + struct brw_gs_prog_data prog_data; + + struct { + struct brw_reg R0; + struct brw_reg vertex[MAX_GS_VERTS]; + } reg; + + /* 3 different ways of expressing vertex size: + */ + unsigned nr_attrs; + unsigned nr_regs; + unsigned nr_bytes; +}; + +#define ATTR_SIZE (4*4) + +void brw_gs_quads( struct brw_gs_compile *c ); +void brw_gs_quad_strip( struct brw_gs_compile *c ); +void brw_gs_tris( struct brw_gs_compile *c ); +void brw_gs_lines( struct brw_gs_compile *c ); +void brw_gs_points( struct brw_gs_compile *c ); + +#endif diff --git a/src/gallium/drivers/i965simple/brw_gs_emit.c b/src/gallium/drivers/i965simple/brw_gs_emit.c new file mode 100644 index 0000000000..c3cc90b10f --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_gs_emit.c @@ -0,0 +1,148 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_util.h" +#include "brw_gs.h" + +static void brw_gs_alloc_regs( struct brw_gs_compile *c, + unsigned nr_verts ) +{ + unsigned i = 0,j; + + /* Register usage is static, precompute here: + */ + c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++; + + /* Payload vertices plus space for more generated vertices: + */ + for (j = 0; j < nr_verts; j++) { + c->reg.vertex[j] = brw_vec4_grf(i, 0); + i += c->nr_regs; + } + + c->prog_data.urb_read_length = c->nr_regs; + c->prog_data.total_grf = i; +} + + +static void brw_gs_emit_vue(struct brw_gs_compile *c, + struct brw_reg vert, + boolean last, + unsigned header) +{ + struct brw_compile *p = &c->func; + boolean allocate = !last; + + /* Overwrite PrimType and PrimStart in the message header, for + * each vertex in turn: + */ + brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header)); + + /* Copy the vertex from vertn into m1..mN+1: + */ + brw_copy8(p, brw_message_reg(1), vert, c->nr_regs); + + /* Send each vertex as a seperate write to the urb. This is + * different to the concept in brw_sf_emit.c, where subsequent + * writes are used to build up a single urb entry. Each of these + * writes instantiates a seperate urb entry, and a new one must be + * allocated each time. + */ + brw_urb_WRITE(p, + allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), + 0, + c->reg.R0, + allocate, + 1, /* used */ + c->nr_regs + 1, /* msg length */ + allocate ? 1 : 0, /* response length */ + allocate ? 0 : 1, /* eot */ + 1, /* writes_complete */ + 0, /* urb offset */ + BRW_URB_SWIZZLE_NONE); +} + + + +void brw_gs_quads( struct brw_gs_compile *c ) +{ + brw_gs_alloc_regs(c, 4); + + /* Use polygons for correct edgeflag behaviour. Note that vertex 3 + * is the PV for quads, but vertex 0 for polygons: + */ + brw_gs_emit_vue(c, c->reg.vertex[3], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START)); + brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2)); + brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_POLYGON << 2)); + brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END)); +} + +void brw_gs_quad_strip( struct brw_gs_compile *c ) +{ + brw_gs_alloc_regs(c, 4); + + brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START)); + brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2)); + brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2)); + brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END)); +} + +void brw_gs_tris( struct brw_gs_compile *c ) +{ + brw_gs_alloc_regs(c, 3); + brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_TRILIST << 2) | R02_PRIM_START)); + brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_TRILIST << 2)); + brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_TRILIST << 2) | R02_PRIM_END)); +} + +void brw_gs_lines( struct brw_gs_compile *c ) +{ + brw_gs_alloc_regs(c, 2); + brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_START)); + brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_END)); +} + +void brw_gs_points( struct brw_gs_compile *c ) +{ + brw_gs_alloc_regs(c, 1); + brw_gs_emit_vue(c, c->reg.vertex[0], 1, ((_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END)); +} + + + + + + + + diff --git a/src/gallium/drivers/i965simple/brw_gs_state.c b/src/gallium/drivers/i965simple/brw_gs_state.c new file mode 100644 index 0000000000..3932e9e939 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_gs_state.c @@ -0,0 +1,89 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + + +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" +#include "pipe/p_util.h" + + + +static void upload_gs_unit( struct brw_context *brw ) +{ + struct brw_gs_unit_state gs; + + memset(&gs, 0, sizeof(gs)); + + /* CACHE_NEW_GS_PROG */ + if (brw->gs.prog_active) { + gs.thread0.grf_reg_count = + align(brw->gs.prog_data->total_grf, 16) / 16 - 1; + gs.thread0.kernel_start_pointer = brw->gs.prog_gs_offset >> 6; + gs.thread3.urb_entry_read_length = brw->gs.prog_data->urb_read_length; + } + else { + gs.thread0.grf_reg_count = 0; + gs.thread0.kernel_start_pointer = 0; + gs.thread3.urb_entry_read_length = 1; + } + + /* BRW_NEW_URB_FENCE */ + gs.thread4.nr_urb_entries = brw->urb.nr_gs_entries; + gs.thread4.urb_entry_allocation_size = brw->urb.vsize - 1; + + gs.thread4.max_threads = 0; /* Hardware requirement */ + + if (BRW_DEBUG & DEBUG_STATS) + gs.thread4.stats_enable = 1; + + /* CONSTANT */ + gs.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; + gs.thread1.single_program_flow = 1; + gs.thread3.dispatch_grf_start_reg = 1; + gs.thread3.const_urb_entry_read_offset = 0; + gs.thread3.const_urb_entry_read_length = 0; + gs.thread3.urb_entry_read_offset = 0; + + + brw->gs.state_gs_offset = brw_cache_data( &brw->cache[BRW_GS_UNIT], &gs ); +} + + +const struct brw_tracked_state brw_gs_unit = { + .dirty = { + .brw = (BRW_NEW_CURBE_OFFSETS | + BRW_NEW_URB_FENCE), + .cache = CACHE_NEW_GS_PROG + }, + .update = upload_gs_unit +}; diff --git a/src/gallium/drivers/i965simple/brw_misc_state.c b/src/gallium/drivers/i965simple/brw_misc_state.c new file mode 100644 index 0000000000..925049ecc1 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_misc_state.c @@ -0,0 +1,486 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_batch.h" +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" + + + + + +/*********************************************************************** + * Blend color + */ + +static void upload_blend_constant_color(struct brw_context *brw) +{ + struct brw_blend_constant_color bcc; + + memset(&bcc, 0, sizeof(bcc)); + bcc.header.opcode = CMD_BLEND_CONSTANT_COLOR; + bcc.header.length = sizeof(bcc)/4-2; + bcc.blend_constant_color[0] = brw->attribs.BlendColor.color[0]; + bcc.blend_constant_color[1] = brw->attribs.BlendColor.color[1]; + bcc.blend_constant_color[2] = brw->attribs.BlendColor.color[2]; + bcc.blend_constant_color[3] = brw->attribs.BlendColor.color[3]; + + BRW_CACHED_BATCH_STRUCT(brw, &bcc); +} + + +const struct brw_tracked_state brw_blend_constant_color = { + .dirty = { + .brw = BRW_NEW_BLEND, + .cache = 0 + }, + .update = upload_blend_constant_color +}; + + +/*********************************************************************** + * Drawing rectangle + */ +static void upload_drawing_rect(struct brw_context *brw) +{ + struct brw_drawrect bdr; + + memset(&bdr, 0, sizeof(bdr)); + bdr.header.opcode = CMD_DRAW_RECT; + bdr.header.length = sizeof(bdr)/4 - 2; + bdr.xmin = 0; + bdr.ymin = 0; + bdr.xmax = brw->attribs.FrameBuffer.cbufs[0]->width; + bdr.ymax = brw->attribs.FrameBuffer.cbufs[0]->height; + bdr.xorg = 0; + bdr.yorg = 0; + + /* Can't use BRW_CACHED_BATCH_STRUCT because this is also emitted + * uncached in brw_draw.c: + */ + BRW_BATCH_STRUCT(brw, &bdr); +} + +const struct brw_tracked_state brw_drawing_rect = { + .dirty = { + .brw = BRW_NEW_SCENE, + .cache = 0 + }, + .update = upload_drawing_rect +}; + +/** + * Upload the binding table pointers, which point each stage's array of surface + * state pointers. + * + * The binding table pointers are relative to the surface state base address, + * which is the BRW_SS_POOL cache buffer. + */ +static void upload_binding_table_pointers(struct brw_context *brw) +{ + struct brw_binding_table_pointers btp; + memset(&btp, 0, sizeof(btp)); + + btp.header.opcode = CMD_BINDING_TABLE_PTRS; + btp.header.length = sizeof(btp)/4 - 2; + btp.vs = 0; + btp.gs = 0; + btp.clp = 0; + btp.sf = 0; + btp.wm = brw->wm.bind_ss_offset; + + BRW_CACHED_BATCH_STRUCT(brw, &btp); +} + +const struct brw_tracked_state brw_binding_table_pointers = { + .dirty = { + .brw = 0, + .cache = CACHE_NEW_SURF_BIND + }, + .update = upload_binding_table_pointers, +}; + + +/** + * Upload pointers to the per-stage state. + * + * The state pointers in this packet are all relative to the general state + * base address set by CMD_STATE_BASE_ADDRESS, which is the BRW_GS_POOL buffer. + */ +static void upload_pipelined_state_pointers(struct brw_context *brw ) +{ + struct brw_pipelined_state_pointers psp; + memset(&psp, 0, sizeof(psp)); + + psp.header.opcode = CMD_PIPELINED_STATE_POINTERS; + psp.header.length = sizeof(psp)/4 - 2; + + psp.vs.offset = brw->vs.state_gs_offset >> 5; + psp.sf.offset = brw->sf.state_gs_offset >> 5; + psp.wm.offset = brw->wm.state_gs_offset >> 5; + psp.cc.offset = brw->cc.state_gs_offset >> 5; + + /* GS gets turned on and off regularly. Need to re-emit URB fence + * after this occurs. + */ + if (brw->gs.prog_active) { + psp.gs.offset = brw->gs.state_gs_offset >> 5; + psp.gs.enable = 1; + } + + if (0) { + psp.clp.offset = brw->clip.state_gs_offset >> 5; + psp.clp.enable = 1; + } + + + if (BRW_CACHED_BATCH_STRUCT(brw, &psp)) + brw->state.dirty.brw |= BRW_NEW_PSP; +} + +const struct brw_tracked_state brw_pipelined_state_pointers = { + .dirty = { + .brw = 0, + .cache = (CACHE_NEW_VS_UNIT | + CACHE_NEW_GS_UNIT | + CACHE_NEW_GS_PROG | + CACHE_NEW_CLIP_UNIT | + CACHE_NEW_SF_UNIT | + CACHE_NEW_WM_UNIT | + CACHE_NEW_CC_UNIT) + }, + .update = upload_pipelined_state_pointers +}; + +static void upload_psp_urb_cbs(struct brw_context *brw ) +{ + upload_pipelined_state_pointers(brw); + brw_upload_urb_fence(brw); + brw_upload_constant_buffer_state(brw); +} + + +const struct brw_tracked_state brw_psp_urb_cbs = { + .dirty = { + .brw = BRW_NEW_URB_FENCE, + .cache = (CACHE_NEW_VS_UNIT | + CACHE_NEW_GS_UNIT | + CACHE_NEW_GS_PROG | + CACHE_NEW_CLIP_UNIT | + CACHE_NEW_SF_UNIT | + CACHE_NEW_WM_UNIT | + CACHE_NEW_CC_UNIT) + }, + .update = upload_psp_urb_cbs +}; + +/** + * Upload the depthbuffer offset and format. + * + * We have to do this per state validation as we need to emit the relocation + * in the batch buffer. + */ +static void upload_depthbuffer(struct brw_context *brw) +{ + struct pipe_surface *depth_surface = brw->attribs.FrameBuffer.zsbuf; + + BEGIN_BATCH(5, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (5 - 2)); + if (depth_surface == NULL) { + OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) | + (BRW_SURFACE_NULL << 29)); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(0); + } else { + unsigned int format; + + switch (depth_surface->cpp) { + case 2: + format = BRW_DEPTHFORMAT_D16_UNORM; + break; + case 4: + if (depth_surface->format == PIPE_FORMAT_Z32_FLOAT) + format = BRW_DEPTHFORMAT_D32_FLOAT; + else + format = BRW_DEPTHFORMAT_D24_UNORM_S8_UINT; + break; + default: + assert(0); + return; + } + + OUT_BATCH(((depth_surface->pitch * depth_surface->cpp) - 1) | + (format << 18) | + (BRW_TILEWALK_YMAJOR << 26) | +// (depth_surface->region->tiled << 27) | + (BRW_SURFACE_2D << 29)); + OUT_RELOC(depth_surface->buffer, + PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE, 0); + OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) | + ((depth_surface->pitch - 1) << 6) | + ((depth_surface->height - 1) << 19)); + OUT_BATCH(0); + } + ADVANCE_BATCH(); +} + +const struct brw_tracked_state brw_depthbuffer = { + .dirty = { + .brw = BRW_NEW_SCENE, + .cache = 0 + }, + .update = upload_depthbuffer, +}; + + + + +/*********************************************************************** + * Polygon stipple packet + */ + +static void upload_polygon_stipple(struct brw_context *brw) +{ + struct brw_polygon_stipple bps; + unsigned i; + + memset(&bps, 0, sizeof(bps)); + bps.header.opcode = CMD_POLY_STIPPLE_PATTERN; + bps.header.length = sizeof(bps)/4-2; + + /* XXX: state tracker should send *all* state down initially! + */ + if (brw->attribs.PolygonStipple) + for (i = 0; i < 32; i++) + bps.stipple[i] = brw->attribs.PolygonStipple->stipple[31 - i]; /* invert */ + + BRW_CACHED_BATCH_STRUCT(brw, &bps); +} + +const struct brw_tracked_state brw_polygon_stipple = { + .dirty = { + .brw = BRW_NEW_STIPPLE, + .cache = 0 + }, + .update = upload_polygon_stipple +}; + + +/*********************************************************************** + * Line stipple packet + */ + +static void upload_line_stipple(struct brw_context *brw) +{ + struct brw_line_stipple bls; + float tmp; + int tmpi; + + memset(&bls, 0, sizeof(bls)); + bls.header.opcode = CMD_LINE_STIPPLE_PATTERN; + bls.header.length = sizeof(bls)/4 - 2; + + bls.bits0.pattern = brw->attribs.Raster->line_stipple_pattern; + bls.bits1.repeat_count = brw->attribs.Raster->line_stipple_factor; + + tmp = 1.0 / (float) brw->attribs.Raster->line_stipple_factor; + tmpi = tmp * (1<<13); + + + bls.bits1.inverse_repeat_count = tmpi; + + BRW_CACHED_BATCH_STRUCT(brw, &bls); +} + +const struct brw_tracked_state brw_line_stipple = { + .dirty = { + .brw = BRW_NEW_STIPPLE, + .cache = 0 + }, + .update = upload_line_stipple +}; + + +/*********************************************************************** + * Misc constant state packets + */ + +static void upload_pipe_control(struct brw_context *brw) +{ + struct brw_pipe_control pc; + + return; + + memset(&pc, 0, sizeof(pc)); + + pc.header.opcode = CMD_PIPE_CONTROL; + pc.header.length = sizeof(pc)/4 - 2; + pc.header.post_sync_operation = PIPE_CONTROL_NOWRITE; + + pc.header.instruction_state_cache_flush_enable = 1; + + pc.bits1.dest_addr_type = PIPE_CONTROL_GTTWRITE_GLOBAL; + + BRW_BATCH_STRUCT(brw, &pc); +} + +const struct brw_tracked_state brw_pipe_control = { + .dirty = { + .brw = BRW_NEW_SCENE, + .cache = 0 + }, + .update = upload_pipe_control +}; + + +/*********************************************************************** + * Misc invarient state packets + */ + +static void upload_invarient_state( struct brw_context *brw ) +{ + { + struct brw_mi_flush flush; + + memset(&flush, 0, sizeof(flush)); + flush.opcode = CMD_MI_FLUSH; + flush.flags = BRW_FLUSH_STATE_CACHE | BRW_FLUSH_READ_CACHE; + BRW_BATCH_STRUCT(brw, &flush); + } + + { + /* 0x61040000 Pipeline Select */ + /* PipelineSelect : 0 */ + struct brw_pipeline_select ps; + + memset(&ps, 0, sizeof(ps)); + ps.header.opcode = CMD_PIPELINE_SELECT; + ps.header.pipeline_select = 0; + BRW_BATCH_STRUCT(brw, &ps); + } + + { + struct brw_global_depth_offset_clamp gdo; + memset(&gdo, 0, sizeof(gdo)); + + /* Disable depth offset clamping. + */ + gdo.header.opcode = CMD_GLOBAL_DEPTH_OFFSET_CLAMP; + gdo.header.length = sizeof(gdo)/4 - 2; + gdo.depth_offset_clamp = 0.0; + + BRW_BATCH_STRUCT(brw, &gdo); + } + + + /* 0x61020000 State Instruction Pointer */ + { + struct brw_system_instruction_pointer sip; + memset(&sip, 0, sizeof(sip)); + + sip.header.opcode = CMD_STATE_INSN_POINTER; + sip.header.length = 0; + sip.bits0.pad = 0; + sip.bits0.system_instruction_pointer = 0; + BRW_BATCH_STRUCT(brw, &sip); + } + + + { + struct brw_vf_statistics vfs; + memset(&vfs, 0, sizeof(vfs)); + + vfs.opcode = CMD_VF_STATISTICS; + if (BRW_DEBUG & DEBUG_STATS) + vfs.statistics_enable = 1; + + BRW_BATCH_STRUCT(brw, &vfs); + } + + + { + struct brw_polygon_stipple_offset bpso; + + memset(&bpso, 0, sizeof(bpso)); + bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET; + bpso.header.length = sizeof(bpso)/4-2; + bpso.bits0.x_offset = 0; + bpso.bits0.y_offset = 0; + + BRW_BATCH_STRUCT(brw, &bpso); + } +} + +const struct brw_tracked_state brw_invarient_state = { + .dirty = { + .brw = BRW_NEW_SCENE, + .cache = 0 + }, + .update = upload_invarient_state +}; + +/** + * Define the base addresses which some state is referenced from. + * + * This allows us to avoid having to emit relocations in many places for + * cached state, and instead emit pointers inside of large, mostly-static + * state pools. This comes at the expense of memory, and more expensive cache + * misses. + */ +static void upload_state_base_address( struct brw_context *brw ) +{ + /* Output the structure (brw_state_base_address) directly to the + * batchbuffer, so we can emit relocations inline. + */ + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2)); + OUT_RELOC(brw->pool[BRW_GS_POOL].buffer, + PIPE_BUFFER_USAGE_GPU_READ, + 1); /* General state base address */ + OUT_RELOC(brw->pool[BRW_SS_POOL].buffer, + PIPE_BUFFER_USAGE_GPU_READ, + 1); /* Surface state base address */ + OUT_BATCH(1); /* Indirect object base address */ + OUT_BATCH(1); /* General state upper bound */ + OUT_BATCH(1); /* Indirect object upper bound */ + ADVANCE_BATCH(); +} + + +const struct brw_tracked_state brw_state_base_address = { + .dirty = { + .brw = BRW_NEW_SCENE, + .cache = 0 + }, + .update = upload_state_base_address +}; diff --git a/src/gallium/drivers/i965simple/brw_reg.h b/src/gallium/drivers/i965simple/brw_reg.h new file mode 100644 index 0000000000..9e885c3b3b --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_reg.h @@ -0,0 +1,76 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#define CMD_MI (0x0 << 29) +#define CMD_2D (0x2 << 29) +#define CMD_3D (0x3 << 29) + +#define MI_BATCH_BUFFER_END (CMD_MI | 0xA << 23) + +/* Stalls command execution waiting for the given events to have occurred. */ +#define MI_WAIT_FOR_EVENT (CMD_MI | (0x3 << 23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + +/* Primitive dispatch on 830-945 */ +#define _3DPRIMITIVE (CMD_3D | (0x1f << 24)) +#define PRIM_INDIRECT (1<<23) +#define PRIM_INLINE (0<<23) +#define PRIM_INDIRECT_SEQUENTIAL (0<<17) +#define PRIM_INDIRECT_ELTS (1<<17) + +#define PRIM3D_TRILIST (0x0<<18) +#define PRIM3D_TRISTRIP (0x1<<18) +#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) +#define PRIM3D_TRIFAN (0x3<<18) +#define PRIM3D_POLY (0x4<<18) +#define PRIM3D_LINELIST (0x5<<18) +#define PRIM3D_LINESTRIP (0x6<<18) +#define PRIM3D_RECTLIST (0x7<<18) +#define PRIM3D_POINTLIST (0x8<<18) +#define PRIM3D_DIB (0x9<<18) +#define PRIM3D_MASK (0x1f<<18) + +#define XY_SETUP_BLT_CMD (CMD_2D | (0x01 << 22) | 6) + +#define XY_COLOR_BLT_CMD (CMD_2D | (0x50 << 22) | 4) + +#define XY_SRC_COPY_BLT_CMD (CMD_2D | (0x53 << 22) | 6) + +/* BR00 */ +#define XY_BLT_WRITE_ALPHA (1 << 21) +#define XY_BLT_WRITE_RGB (1 << 20) +#define XY_SRC_TILED (1 << 15) +#define XY_DST_TILED (1 << 11) + +/* BR13 */ +#define BR13_565 (0x1 << 24) +#define BR13_8888 (0x3 << 24) + +#define FENCE_LINEAR 0 +#define FENCE_XMAJOR 1 +#define FENCE_YMAJOR 2 diff --git a/src/gallium/drivers/i965simple/brw_sf.c b/src/gallium/drivers/i965simple/brw_sf.c new file mode 100644 index 0000000000..7c83b81c85 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_sf.c @@ -0,0 +1,351 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_util.h" +#include "brw_sf.h" +#include "brw_state.h" +#include "tgsi/util/tgsi_parse.h" + + +static void compile_sf_prog( struct brw_context *brw, + struct brw_sf_prog_key *key ) +{ + struct brw_sf_compile c; + const unsigned *program; + unsigned program_size; + + memset(&c, 0, sizeof(c)); + + /* Begin the compilation: + */ + brw_init_compile(&c.func); + + c.key = *key; + + + c.nr_attrs = c.key.vp_output_count; + c.nr_attr_regs = (c.nr_attrs+1)/2; + + c.nr_setup_attrs = c.key.fp_input_count + 1; /* +1 for position */ + c.nr_setup_regs = (c.nr_setup_attrs+1)/2; + + c.prog_data.urb_read_length = c.nr_attr_regs; + c.prog_data.urb_entry_size = c.nr_setup_regs * 2; + + + /* Which primitive? Or all three? + */ + switch (key->primitive) { + case SF_TRIANGLES: + c.nr_verts = 3; + brw_emit_tri_setup( &c ); + break; + case SF_LINES: + c.nr_verts = 2; + brw_emit_line_setup( &c ); + break; + case SF_POINTS: + c.nr_verts = 1; + brw_emit_point_setup( &c ); + break; + + case SF_UNFILLED_TRIS: + default: + assert(0); + return; + } + + + + /* get the program + */ + program = brw_get_program(&c.func, &program_size); + + /* Upload + */ + brw->sf.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_SF_PROG], + &c.key, + sizeof(c.key), + program, + program_size, + &c.prog_data, + &brw->sf.prog_data ); +} + + +static boolean search_cache( struct brw_context *brw, + struct brw_sf_prog_key *key ) +{ + return brw_search_cache(&brw->cache[BRW_SF_PROG], + key, sizeof(*key), + &brw->sf.prog_data, + &brw->sf.prog_gs_offset); +} + + +/* Calculate interpolants for triangle and line rasterization. + */ +static void upload_sf_prog( struct brw_context *brw ) +{ + const struct brw_fragment_program *fs = brw->attribs.FragmentProgram; + struct brw_sf_prog_key key; + struct tgsi_parse_context parse; + int i, done = 0; + + + memset(&key, 0, sizeof(key)); + + /* Populate the key, noting state dependencies: + */ + /* CACHE_NEW_VS_PROG */ + key.vp_output_count = brw->vs.prog_data->outputs_written; + + /* BRW_NEW_FS */ + key.fp_input_count = brw->attribs.FragmentProgram->info.nr_regs[TGSI_FILE_INPUT]; + + + /* BRW_NEW_REDUCED_PRIMITIVE */ + switch (brw->reduced_primitive) { + case PIPE_PRIM_TRIANGLES: +// if (key.attrs & (1<program.tokens ); + while( !done && + !tgsi_parse_end_of_tokens( &parse ) ) + { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_INPUT) + { + int first = parse.FullToken.FullDeclaration.u.DeclarationRange.First; + int last = parse.FullToken.FullDeclaration.u.DeclarationRange.Last; + int interp_mode = parse.FullToken.FullDeclaration.Interpolation.Interpolate; + //int semantic = parse.FullToken.FullDeclaration.Semantic.SemanticName; + //int semantic_index = parse.FullToken.FullDeclaration.Semantic.SemanticIndex; + + debug_printf("fs input %d..%d interp mode %d\n", first, last, interp_mode); + + switch (interp_mode) { + case TGSI_INTERPOLATE_CONSTANT: + for (i = first; i <= last; i++) + key.const_mask |= (1 << i); + break; + case TGSI_INTERPOLATE_LINEAR: + for (i = first; i <= last; i++) + key.linear_mask |= (1 << i); + break; + case TGSI_INTERPOLATE_PERSPECTIVE: + for (i = first; i <= last; i++) + key.persp_mask |= (1 << i); + break; + default: + break; + } + + /* Also need stuff for flat shading, twosided color. + */ + + } + break; + default: + done = 1; + break; + } + } + + /* Hack: Adjust for position. Optimize away when not required (ie + * for perspective interpolation). + */ + key.persp_mask <<= 1; + key.linear_mask <<= 1; + key.linear_mask |= 1; + key.const_mask <<= 1; + + debug_printf("key.persp_mask: %x\n", key.persp_mask); + debug_printf("key.linear_mask: %x\n", key.linear_mask); + debug_printf("key.const_mask: %x\n", key.const_mask); + + +// key.do_point_sprite = brw->attribs.Point->PointSprite; +// key.SpriteOrigin = brw->attribs.Point->SpriteOrigin; + +// key.do_flat_shading = (brw->attribs.Raster->flatshade); +// key.do_twoside_color = (brw->attribs.Light->Enabled && brw->attribs.Light->Model.TwoSide); + +// if (key.do_twoside_color) +// key.frontface_ccw = (brw->attribs.Polygon->FrontFace == GL_CCW); + + + if (!search_cache(brw, &key)) + compile_sf_prog( brw, &key ); +} + + +const struct brw_tracked_state brw_sf_prog = { + .dirty = { + .brw = (BRW_NEW_RASTERIZER | + BRW_NEW_REDUCED_PRIMITIVE | + BRW_NEW_VS | + BRW_NEW_FS), + .cache = 0, + }, + .update = upload_sf_prog +}; + + + +#if 0 +/* Build a struct like the one we'd like the state tracker to pass to + * us. + */ +static void update_sf_linkage( struct brw_context *brw ) +{ + const struct brw_vertex_program *vs = brw->attribs.VertexProgram; + const struct brw_fragment_program *fs = brw->attribs.FragmentProgram; + struct pipe_setup_linkage state; + struct tgsi_parse_context parse; + + int i, j; + int nr_vp_outputs = 0; + int done = 0; + + struct { + unsigned semantic:8; + unsigned semantic_index:16; + } fp_semantic[32], vp_semantic[32]; + + memset(&state, 0, sizeof(state)); + + state.fp_input_count = 0; + + + + + + + assert(state.fp_input_count == fs->program.num_inputs); + + + /* Then scan vp outputs + */ + done = 0; + tgsi_parse_init( &parse, vs->program.tokens ); + while( !done && + !tgsi_parse_end_of_tokens( &parse ) ) + { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_INPUT) + { + int first = parse.FullToken.FullDeclaration.u.DeclarationRange.First; + int last = parse.FullToken.FullDeclaration.u.DeclarationRange.Last; + + for (i = first; i < last; i++) { + vp_semantic[i].semantic = + parse.FullToken.FullDeclaration.Semantic.SemanticName; + vp_semantic[i].semantic_index = + parse.FullToken.FullDeclaration.Semantic.SemanticIndex; + } + + assert(last > nr_vp_outputs); + nr_vp_outputs = last; + } + break; + default: + done = 1; + break; + } + } + + + /* Now match based on semantic information. + */ + for (i = 0; i< state.fp_input_count; i++) { + for (j = 0; j < nr_vp_outputs; j++) { + if (fp_semantic[i].semantic == vp_semantic[j].semantic && + fp_semantic[i].semantic_index == vp_semantic[j].semantic_index) { + state.fp_input[i].vp_output = j; + } + } + if (fp_semantic[i].semantic == TGSI_SEMANTIC_COLOR) { + for (j = 0; j < nr_vp_outputs; j++) { + if (TGSI_SEMANTIC_BCOLOR == vp_semantic[j].semantic && + fp_semantic[i].semantic_index == vp_semantic[j].semantic_index) { + state.fp_input[i].bf_vp_output = j; + } + } + } + } + + if (memcmp(&brw->sf.linkage, &state, sizeof(state)) != 0) { + brw->sf.linkage = state; + brw->state.dirty.brw |= BRW_NEW_SF_LINKAGE; + } +} + + +const struct brw_tracked_state brw_sf_linkage = { + .dirty = { + .brw = (BRW_NEW_VS | + BRW_NEW_FS), + .cache = 0, + }, + .update = update_sf_linkage +}; + + +#endif diff --git a/src/gallium/drivers/i965simple/brw_sf.h b/src/gallium/drivers/i965simple/brw_sf.h new file mode 100644 index 0000000000..b7ada47560 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_sf.h @@ -0,0 +1,122 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRW_SF_H +#define BRW_SF_H + +#include "brw_context.h" +#include "brw_eu.h" + + +#define SF_POINTS 0 +#define SF_LINES 1 +#define SF_TRIANGLES 2 +#define SF_UNFILLED_TRIS 3 + + + +struct brw_sf_prog_key { + unsigned vp_output_count:5; + unsigned fp_input_count:5; + + unsigned primitive:2; + unsigned do_twoside_color:1; + unsigned do_flat_shading:1; + unsigned frontface_ccw:1; + unsigned do_point_sprite:1; + + /* Interpolation masks; + */ + unsigned linear_mask; + unsigned persp_mask; + unsigned const_mask; + + +// int SpriteOrigin; +}; + +struct brw_sf_point_tex { + boolean CoordReplace; +}; + +struct brw_sf_compile { + struct brw_compile func; + struct brw_sf_prog_key key; + struct brw_sf_prog_data prog_data; + + struct brw_reg pv; + struct brw_reg det; + struct brw_reg dx0; + struct brw_reg dx2; + struct brw_reg dy0; + struct brw_reg dy2; + + /* z and 1/w passed in seperately: + */ + struct brw_reg z[3]; + struct brw_reg inv_w[3]; + + /* The vertices: + */ + struct brw_reg vert[3]; + + /* Temporaries, allocated after last vertex reg. + */ + struct brw_reg inv_det; + struct brw_reg a1_sub_a0; + struct brw_reg a2_sub_a0; + struct brw_reg tmp; + + struct brw_reg m1Cx; + struct brw_reg m2Cy; + struct brw_reg m3C0; + + unsigned nr_verts; + unsigned nr_attrs; + unsigned nr_attr_regs; + unsigned nr_setup_attrs; + unsigned nr_setup_regs; +#if 0 + ubyte attr_to_idx[VERT_RESULT_MAX]; + ubyte idx_to_attr[VERT_RESULT_MAX]; + struct brw_sf_point_tex point_attrs[VERT_RESULT_MAX]; +#endif +}; + + +void brw_emit_tri_setup( struct brw_sf_compile *c ); +void brw_emit_line_setup( struct brw_sf_compile *c ); +void brw_emit_point_setup( struct brw_sf_compile *c ); +void brw_emit_point_sprite_setup( struct brw_sf_compile *c ); +void brw_emit_anyprim_setup( struct brw_sf_compile *c ); + +#endif diff --git a/src/gallium/drivers/i965simple/brw_sf_emit.c b/src/gallium/drivers/i965simple/brw_sf_emit.c new file mode 100644 index 0000000000..78d6fa5e9e --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_sf_emit.c @@ -0,0 +1,382 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_defines.h" +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_util.h" +#include "brw_sf.h" + + + +/*********************************************************************** + * Triangle setup. + */ + + +static void alloc_regs( struct brw_sf_compile *c ) +{ + unsigned reg, i; + + /* Values computed by fixed function unit: + */ + c->pv = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_UD); + c->det = brw_vec1_grf(1, 2); + c->dx0 = brw_vec1_grf(1, 3); + c->dx2 = brw_vec1_grf(1, 4); + c->dy0 = brw_vec1_grf(1, 5); + c->dy2 = brw_vec1_grf(1, 6); + + /* z and 1/w passed in seperately: + */ + c->z[0] = brw_vec1_grf(2, 0); + c->inv_w[0] = brw_vec1_grf(2, 1); + c->z[1] = brw_vec1_grf(2, 2); + c->inv_w[1] = brw_vec1_grf(2, 3); + c->z[2] = brw_vec1_grf(2, 4); + c->inv_w[2] = brw_vec1_grf(2, 5); + + /* The vertices: + */ + reg = 3; + for (i = 0; i < c->nr_verts; i++) { + c->vert[i] = brw_vec8_grf(reg, 0); + reg += c->nr_attr_regs; + } + + /* Temporaries, allocated after last vertex reg. + */ + c->inv_det = brw_vec1_grf(reg, 0); reg++; + c->a1_sub_a0 = brw_vec8_grf(reg, 0); reg++; + c->a2_sub_a0 = brw_vec8_grf(reg, 0); reg++; + c->tmp = brw_vec8_grf(reg, 0); reg++; + + /* Note grf allocation: + */ + c->prog_data.total_grf = reg; + + + /* Outputs of this program - interpolation coefficients for + * rasterization: + */ + c->m1Cx = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 1, 0); + c->m2Cy = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 2, 0); + c->m3C0 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 3, 0); +} + + +static void copy_z_inv_w( struct brw_sf_compile *c ) +{ + struct brw_compile *p = &c->func; + unsigned i; + + brw_push_insn_state(p); + + /* Copy both scalars with a single MOV: + */ + for (i = 0; i < c->nr_verts; i++) + brw_MOV(p, vec2(suboffset(c->vert[i], 2)), vec2(c->z[i])); + + brw_pop_insn_state(p); +} + + +static void invert_det( struct brw_sf_compile *c) +{ + brw_math(&c->func, + c->inv_det, + BRW_MATH_FUNCTION_INV, + BRW_MATH_SATURATE_NONE, + 0, + c->det, + BRW_MATH_DATA_SCALAR, + BRW_MATH_PRECISION_FULL); + +} + +#define NON_PERPECTIVE_ATTRS (FRAG_BIT_WPOS | \ + FRAG_BIT_COL0 | \ + FRAG_BIT_COL1) + +static boolean calculate_masks( struct brw_sf_compile *c, + unsigned reg, + ushort *pc, + ushort *pc_persp, + ushort *pc_linear) +{ + boolean is_last_attr = (reg == c->nr_setup_regs - 1); + unsigned persp_mask = c->key.persp_mask; + unsigned linear_mask = c->key.linear_mask; + + debug_printf("persp_mask: %x\n", persp_mask); + debug_printf("linear_mask: %x\n", linear_mask); + + *pc_persp = 0; + *pc_linear = 0; + *pc = 0xf; + + if (persp_mask & (1 << (reg*2))) + *pc_persp = 0xf; + + if (linear_mask & (1 << (reg*2))) + *pc_linear = 0xf; + + /* Maybe only processs one attribute on the final round: + */ + if (reg*2+1 < c->nr_setup_attrs) { + *pc |= 0xf0; + + if (persp_mask & (1 << (reg*2+1))) + *pc_persp |= 0xf0; + + if (linear_mask & (1 << (reg*2+1))) + *pc_linear |= 0xf0; + } + + debug_printf("pc: %x\n", *pc); + debug_printf("pc_persp: %x\n", *pc_persp); + debug_printf("pc_linear: %x\n", *pc_linear); + + + return is_last_attr; +} + + + +void brw_emit_tri_setup( struct brw_sf_compile *c ) +{ + struct brw_compile *p = &c->func; + unsigned i; + + debug_printf("%s START ==============\n", __FUNCTION__); + + c->nr_verts = 3; + alloc_regs(c); + invert_det(c); + copy_z_inv_w(c); + + + for (i = 0; i < c->nr_setup_regs; i++) + { + /* Pair of incoming attributes: + */ + struct brw_reg a0 = offset(c->vert[0], i); + struct brw_reg a1 = offset(c->vert[1], i); + struct brw_reg a2 = offset(c->vert[2], i); + ushort pc = 0, pc_persp = 0, pc_linear = 0; + boolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); + + if (pc_persp) + { + brw_set_predicate_control_flag_value(p, pc_persp); + brw_MUL(p, a0, a0, c->inv_w[0]); + brw_MUL(p, a1, a1, c->inv_w[1]); + brw_MUL(p, a2, a2, c->inv_w[2]); + } + + + /* Calculate coefficients for interpolated values: + */ + if (pc_linear) + { + brw_set_predicate_control_flag_value(p, pc_linear); + + brw_ADD(p, c->a1_sub_a0, a1, negate(a0)); + brw_ADD(p, c->a2_sub_a0, a2, negate(a0)); + + /* calculate dA/dx + */ + brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2); + brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0)); + brw_MUL(p, c->m1Cx, c->tmp, c->inv_det); + + /* calculate dA/dy + */ + brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0); + brw_MAC(p, c->tmp, c->a1_sub_a0, negate(c->dx2)); + brw_MUL(p, c->m2Cy, c->tmp, c->inv_det); + } + + { + brw_set_predicate_control_flag_value(p, pc); + /* start point for interpolation + */ + brw_MOV(p, c->m3C0, a0); + + /* Copy m0..m3 to URB. m0 is implicitly copied from r0 in + * the send instruction: + */ + brw_urb_WRITE(p, + brw_null_reg(), + 0, + brw_vec8_grf(0, 0), /* r0, will be copied to m0 */ + 0, /* allocate */ + 1, /* used */ + 4, /* msg len */ + 0, /* response len */ + last, /* eot */ + last, /* writes complete */ + i*4, /* offset */ + BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */ + } + } + + debug_printf("%s DONE ==============\n", __FUNCTION__); + +} + + + +void brw_emit_line_setup( struct brw_sf_compile *c ) +{ + struct brw_compile *p = &c->func; + unsigned i; + + + c->nr_verts = 2; + alloc_regs(c); + invert_det(c); + copy_z_inv_w(c); + + for (i = 0; i < c->nr_setup_regs; i++) + { + /* Pair of incoming attributes: + */ + struct brw_reg a0 = offset(c->vert[0], i); + struct brw_reg a1 = offset(c->vert[1], i); + ushort pc, pc_persp, pc_linear; + boolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); + + if (pc_persp) + { + brw_set_predicate_control_flag_value(p, pc_persp); + brw_MUL(p, a0, a0, c->inv_w[0]); + brw_MUL(p, a1, a1, c->inv_w[1]); + } + + /* Calculate coefficients for position, color: + */ + if (pc_linear) { + brw_set_predicate_control_flag_value(p, pc_linear); + + brw_ADD(p, c->a1_sub_a0, a1, negate(a0)); + + brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0); + brw_MUL(p, c->m1Cx, c->tmp, c->inv_det); + + brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0); + brw_MUL(p, c->m2Cy, c->tmp, c->inv_det); + } + + { + brw_set_predicate_control_flag_value(p, pc); + + /* start point for interpolation + */ + brw_MOV(p, c->m3C0, a0); + + /* Copy m0..m3 to URB. + */ + brw_urb_WRITE(p, + brw_null_reg(), + 0, + brw_vec8_grf(0, 0), + 0, /* allocate */ + 1, /* used */ + 4, /* msg len */ + 0, /* response len */ + last, /* eot */ + last, /* writes complete */ + i*4, /* urb destination offset */ + BRW_URB_SWIZZLE_TRANSPOSE); + } + } +} + + +/* Points setup - several simplifications as all attributes are + * constant across the face of the point (point sprites excluded!) + */ +void brw_emit_point_setup( struct brw_sf_compile *c ) +{ + struct brw_compile *p = &c->func; + unsigned i; + + c->nr_verts = 1; + alloc_regs(c); + copy_z_inv_w(c); + + brw_MOV(p, c->m1Cx, brw_imm_ud(0)); /* zero - move out of loop */ + brw_MOV(p, c->m2Cy, brw_imm_ud(0)); /* zero - move out of loop */ + + for (i = 0; i < c->nr_setup_regs; i++) + { + struct brw_reg a0 = offset(c->vert[0], i); + ushort pc, pc_persp, pc_linear; + boolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); + + if (pc_persp) + { + /* This seems odd as the values are all constant, but the + * fragment shader will be expecting it: + */ + brw_set_predicate_control_flag_value(p, pc_persp); + brw_MUL(p, a0, a0, c->inv_w[0]); + } + + + /* The delta values are always zero, just send the starting + * coordinate. Again, this is to fit in with the interpolation + * code in the fragment shader. + */ + { + brw_set_predicate_control_flag_value(p, pc); + + brw_MOV(p, c->m3C0, a0); /* constant value */ + + /* Copy m0..m3 to URB. + */ + brw_urb_WRITE(p, + brw_null_reg(), + 0, + brw_vec8_grf(0, 0), + 0, /* allocate */ + 1, /* used */ + 4, /* msg len */ + 0, /* response len */ + last, /* eot */ + last, /* writes complete */ + i*4, /* urb destination offset */ + BRW_URB_SWIZZLE_TRANSPOSE); + } + } +} diff --git a/src/gallium/drivers/i965simple/brw_sf_state.c b/src/gallium/drivers/i965simple/brw_sf_state.c new file mode 100644 index 0000000000..9acd3ea61b --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_sf_state.c @@ -0,0 +1,180 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + + +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" +#include "pipe/p_util.h" + +static void upload_sf_vp(struct brw_context *brw) +{ + struct brw_sf_viewport sfv; + + memset(&sfv, 0, sizeof(sfv)); + + + /* BRW_NEW_VIEWPORT */ + { + const float *scale = brw->attribs.Viewport.scale; + const float *trans = brw->attribs.Viewport.translate; + + sfv.viewport.m00 = scale[0]; + sfv.viewport.m11 = scale[1]; + sfv.viewport.m22 = scale[2]; + sfv.viewport.m30 = trans[0]; + sfv.viewport.m31 = trans[1]; + sfv.viewport.m32 = trans[2]; + } + + /* _NEW_SCISSOR */ + sfv.scissor.xmin = brw->attribs.Scissor.minx; + sfv.scissor.xmax = brw->attribs.Scissor.maxx - 1; + sfv.scissor.ymin = brw->attribs.Scissor.miny; + sfv.scissor.ymax = brw->attribs.Scissor.maxy - 1; + + brw->sf.vp_gs_offset = brw_cache_data( &brw->cache[BRW_SF_VP], &sfv ); +} + +const struct brw_tracked_state brw_sf_vp = { + .dirty = { + .brw = (BRW_NEW_SCISSOR | + BRW_NEW_VIEWPORT), + .cache = 0 + }, + .update = upload_sf_vp +}; + +static void upload_sf_unit( struct brw_context *brw ) +{ + struct brw_sf_unit_state sf; + memset(&sf, 0, sizeof(sf)); + + /* CACHE_NEW_SF_PROG */ + sf.thread0.grf_reg_count = align(brw->sf.prog_data->total_grf, 16) / 16 - 1; + sf.thread0.kernel_start_pointer = brw->sf.prog_gs_offset >> 6; + sf.thread3.urb_entry_read_length = brw->sf.prog_data->urb_read_length; + + sf.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; + sf.thread3.dispatch_grf_start_reg = 3; + sf.thread3.urb_entry_read_offset = 1; + + /* BRW_NEW_URB_FENCE */ + sf.thread4.nr_urb_entries = brw->urb.nr_sf_entries; + sf.thread4.urb_entry_allocation_size = brw->urb.sfsize - 1; + sf.thread4.max_threads = MIN2(12, brw->urb.nr_sf_entries / 2) - 1; + + if (BRW_DEBUG & DEBUG_SINGLE_THREAD) + sf.thread4.max_threads = 0; + + if (BRW_DEBUG & DEBUG_STATS) + sf.thread4.stats_enable = 1; + + /* CACHE_NEW_SF_VP */ + sf.sf5.sf_viewport_state_offset = brw->sf.vp_gs_offset >> 5; + sf.sf5.viewport_transform = 1; + + /* BRW_NEW_RASTER */ + if (brw->attribs.Raster->scissor) + sf.sf6.scissor = 1; + +#if 0 + if (brw->attribs.Polygon->FrontFace == GL_CCW) + sf.sf5.front_winding = BRW_FRONTWINDING_CCW; + else + sf.sf5.front_winding = BRW_FRONTWINDING_CW; + + + if (brw->attribs.Polygon->CullFlag) { + switch (brw->attribs.Polygon->CullFaceMode) { + case GL_FRONT: + sf.sf6.cull_mode = BRW_CULLMODE_FRONT; + break; + case GL_BACK: + sf.sf6.cull_mode = BRW_CULLMODE_BACK; + break; + case GL_FRONT_AND_BACK: + sf.sf6.cull_mode = BRW_CULLMODE_BOTH; + break; + default: + assert(0); + break; + } + } + else + sf.sf6.cull_mode = BRW_CULLMODE_NONE; +#else + sf.sf5.front_winding = BRW_FRONTWINDING_CCW; + sf.sf6.cull_mode = BRW_CULLMODE_NONE; +#endif + + sf.sf6.line_width = CLAMP(brw->attribs.Raster->line_width, 1.0, 5.0) * (1<<1); + + sf.sf6.line_endcap_aa_region_width = 1; + if (brw->attribs.Raster->line_smooth) + sf.sf6.aa_enable = 1; + else if (sf.sf6.line_width <= 0x2) + sf.sf6.line_width = 0; + + sf.sf6.point_rast_rule = 1; /* opengl conventions */ + + sf.sf7.sprite_point = brw->attribs.Raster->point_sprite; + sf.sf7.point_size = CLAMP(brw->attribs.Raster->line_width, 1.0, 255.0) * (1<<3); + sf.sf7.use_point_size_state = !brw->attribs.Raster->point_size_per_vertex; + + /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons: + */ + sf.sf7.trifan_pv = 2; + sf.sf7.linestrip_pv = 1; + sf.sf7.tristrip_pv = 2; + sf.sf7.line_last_pixel_enable = 0; + + /* Set bias for OpenGL rasterization rules: + */ + sf.sf6.dest_org_vbias = 0x8; + sf.sf6.dest_org_hbias = 0x8; + + brw->sf.state_gs_offset = brw_cache_data( &brw->cache[BRW_SF_UNIT], &sf ); +} + + +const struct brw_tracked_state brw_sf_unit = { + .dirty = { + .brw = (BRW_NEW_RASTERIZER | + BRW_NEW_URB_FENCE), + .cache = (CACHE_NEW_SF_VP | + CACHE_NEW_SF_PROG) + }, + .update = upload_sf_unit +}; + + diff --git a/src/gallium/drivers/i965simple/brw_shader_info.c b/src/gallium/drivers/i965simple/brw_shader_info.c new file mode 100644 index 0000000000..431b45466a --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_shader_info.c @@ -0,0 +1,49 @@ + +#include "brw_context.h" +#include "brw_state.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/tgsi/util/tgsi_parse.h" + + + + +void brw_shader_info(const struct tgsi_token *tokens, + struct brw_shader_info *info ) +{ + struct tgsi_parse_context parse; + int done = 0; + + tgsi_parse_init( &parse, tokens ); + + while( !done && + !tgsi_parse_end_of_tokens( &parse ) ) + { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + const struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration; + unsigned last = decl->u.DeclarationRange.Last; + + assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); + + // Broken by crazy wpos init: + //assert( info->nr_regs[decl->Declaration.File] <= last); + + info->nr_regs[decl->Declaration.File] = MAX2(info->nr_regs[decl->Declaration.File], + last+1); + break; + } + case TGSI_TOKEN_TYPE_IMMEDIATE: + case TGSI_TOKEN_TYPE_INSTRUCTION: + default: + done = 1; + break; + } + } + + tgsi_parse_free (&parse); + +} diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c new file mode 100644 index 0000000000..95dfce88e4 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -0,0 +1,424 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Zack Rusin + * Keith Whitwell + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/tgsi/util/tgsi_dump.h" + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_state.h" +#include "brw_draw.h" + + +#define DUP( TYPE, VAL ) \ +do { \ + struct TYPE *x = malloc(sizeof(*x)); \ + memcpy(x, VAL, sizeof(*x) ); \ + return x; \ +} while (0) + +/************************************************************************ + * Blend + */ +static void * +brw_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + DUP( pipe_blend_state, blend ); +} + +static void brw_bind_blend_state(struct pipe_context *pipe, + void *blend) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Blend = (struct pipe_blend_state*)blend; + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + + +static void brw_delete_blend_state(struct pipe_context *pipe, void *blend) +{ + free(blend); +} + +static void brw_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.BlendColor = *blend_color; + + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + +/************************************************************************ + * Sampler + */ + +static void * +brw_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + DUP( pipe_sampler_state, sampler ); +} + +static void brw_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, void *sampler) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Samplers[unit] = sampler; + brw->state.dirty.brw |= BRW_NEW_SAMPLER; +} + +static void brw_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + free(sampler); +} + + +/************************************************************************ + * Depth stencil + */ + +static void * +brw_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + DUP( pipe_depth_stencil_alpha_state, depth_stencil ); +} + +static void brw_bind_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; + + brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL; +} + +static void brw_delete_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + free(depth_stencil); +} + +/************************************************************************ + * Scissor + */ +static void brw_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct brw_context *brw = brw_context(pipe); + + memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) ); + brw->state.dirty.brw |= BRW_NEW_SCISSOR; +} + + +/************************************************************************ + * Stipple + */ + +static void brw_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ +} + + +/************************************************************************ + * Fragment shader + */ + +static void * brw_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program); + + /* XXX: Do I have to duplicate the tokens as well?? + */ + brw_fp->program = *shader; + brw_fp->id = brw_context(pipe)->program_id++; + + brw_shader_info(shader->tokens, + &brw_fp->info); + + tgsi_dump(shader->tokens, 0); + + + return (void *)brw_fp; +} + +static void brw_bind_fs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader; + brw->state.dirty.brw |= BRW_NEW_FS; +} + +static void brw_delete_fs_state(struct pipe_context *pipe, void *shader) +{ + FREE(shader); +} + + +/************************************************************************ + * Vertex shader and other TNL state + */ + +static void *brw_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program); + + /* XXX: Do I have to duplicate the tokens as well?? + */ + brw_vp->program = *shader; + brw_vp->id = brw_context(pipe)->program_id++; + brw_shader_info(shader->tokens, + &brw_vp->info); + + tgsi_dump(shader->tokens, 0); + + return (void *)brw_vp; +} + +static void brw_bind_vs_state(struct pipe_context *pipe, void *vs) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.VertexProgram = (struct brw_vertex_program *)vs; + brw->state.dirty.brw |= BRW_NEW_VS; + + debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n"); +} + +static void brw_delete_vs_state(struct pipe_context *pipe, void *shader) +{ + FREE(shader); +} + + +static void brw_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Clip = *clip; +} + + +static void brw_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Viewport = *viewport; /* struct copy */ + brw->state.dirty.brw |= BRW_NEW_VIEWPORT; + + /* pass the viewport info to the draw module */ + //draw_set_viewport_state(brw->draw, viewport); +} + + +static void brw_set_vertex_buffer( struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_buffer *buffer ) +{ + struct brw_context *brw = brw_context(pipe); + brw->vb.vbo_array[index] = buffer; +} + +static void brw_set_vertex_element(struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_element *element) +{ + /* flush ? */ + struct brw_context *brw = brw_context(pipe); + + assert(index < PIPE_ATTRIB_MAX); + struct brw_vertex_element_state el; + memset(&el, 0, sizeof(el)); + + el.ve0.src_offset = element->src_offset; + el.ve0.src_format = brw_translate_surface_format(element->src_format); + el.ve0.valid = 1; + el.ve0.vertex_buffer_index = element->vertex_buffer_index; + + el.ve1.dst_offset = index * 4; + + el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; + + switch (element->nr_components) { + case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; + case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; + case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; + break; + } + + brw->vb.inputs[index] = el; +} + + + +/************************************************************************ + * Constant buffers + */ + +static void brw_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct brw_context *brw = brw_context(pipe); + + assert(buf == 0 || index == 0); + + brw->attribs.Constants[shader] = buf; + brw->state.dirty.brw |= BRW_NEW_CONSTANTS; +} + + +/************************************************************************ + * Texture surfaces + */ + + +static void brw_set_sampler_texture(struct pipe_context *pipe, + unsigned unit, + struct pipe_texture *texture) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Texture[unit] = (struct brw_texture*)texture; /* ptr, not struct */ + + brw->state.dirty.brw |= BRW_NEW_TEXTURE; +} + + +/************************************************************************ + * Render targets, etc + */ + +static void brw_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FrameBuffer = *fb; /* struct copy */ + + brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER; +} + + + +/************************************************************************ + * Rasterizer state + */ + +static void * +brw_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *rasterizer) +{ + DUP(pipe_rasterizer_state, rasterizer); +} + +static void brw_bind_rasterizer_state( struct pipe_context *pipe, + void *setup ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Raster = (struct pipe_rasterizer_state *)setup; + + /* Also pass-through to draw module: + */ + //draw_set_rasterizer_state(brw->draw, setup); + + brw->state.dirty.brw |= BRW_NEW_RASTERIZER; +} + +static void brw_delete_rasterizer_state(struct pipe_context *pipe, + void *setup) +{ + free(setup); +} + + + +void +brw_init_state_functions( struct brw_context *brw ) +{ + brw->pipe.create_blend_state = brw_create_blend_state; + brw->pipe.bind_blend_state = brw_bind_blend_state; + brw->pipe.delete_blend_state = brw_delete_blend_state; + + brw->pipe.create_sampler_state = brw_create_sampler_state; + brw->pipe.bind_sampler_state = brw_bind_sampler_state; + brw->pipe.delete_sampler_state = brw_delete_sampler_state; + + brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; + brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; + brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; + + brw->pipe.create_rasterizer_state = brw_create_rasterizer_state; + brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state; + brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state; + brw->pipe.create_fs_state = brw_create_fs_state; + brw->pipe.bind_fs_state = brw_bind_fs_state; + brw->pipe.delete_fs_state = brw_delete_fs_state; + brw->pipe.create_vs_state = brw_create_vs_state; + brw->pipe.bind_vs_state = brw_bind_vs_state; + brw->pipe.delete_vs_state = brw_delete_vs_state; + + brw->pipe.set_blend_color = brw_set_blend_color; + brw->pipe.set_clip_state = brw_set_clip_state; + brw->pipe.set_constant_buffer = brw_set_constant_buffer; + brw->pipe.set_framebuffer_state = brw_set_framebuffer_state; + +// brw->pipe.set_feedback_state = brw_set_feedback_state; +// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer; + + brw->pipe.set_polygon_stipple = brw_set_polygon_stipple; + brw->pipe.set_scissor_state = brw_set_scissor_state; + brw->pipe.set_sampler_texture = brw_set_sampler_texture; + brw->pipe.set_viewport_state = brw_set_viewport_state; + brw->pipe.set_vertex_buffer = brw_set_vertex_buffer; + brw->pipe.set_vertex_element = brw_set_vertex_element; +} diff --git a/src/gallium/drivers/i965simple/brw_state.h b/src/gallium/drivers/i965simple/brw_state.h new file mode 100644 index 0000000000..258e9a556e --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_state.h @@ -0,0 +1,158 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRW_STATE_H +#define BRW_STATE_H + +#include "brw_context.h" +#include "brw_winsys.h" + + +const struct brw_tracked_state brw_blend_constant_color; +const struct brw_tracked_state brw_cc_unit; +const struct brw_tracked_state brw_cc_vp; +const struct brw_tracked_state brw_clip_prog; +const struct brw_tracked_state brw_clip_unit; +const struct brw_tracked_state brw_constant_buffer_state; +const struct brw_tracked_state brw_constant_buffer; +const struct brw_tracked_state brw_curbe_offsets; +const struct brw_tracked_state brw_invarient_state; +const struct brw_tracked_state brw_gs_prog; +const struct brw_tracked_state brw_gs_unit; +const struct brw_tracked_state brw_drawing_rect; +const struct brw_tracked_state brw_line_stipple; +const struct brw_tracked_state brw_pipelined_state_pointers; +const struct brw_tracked_state brw_binding_table_pointers; +const struct brw_tracked_state brw_depthbuffer; +const struct brw_tracked_state brw_polygon_stipple_offset; +const struct brw_tracked_state brw_polygon_stipple; +const struct brw_tracked_state brw_program_parameters; +const struct brw_tracked_state brw_recalculate_urb_fence; +const struct brw_tracked_state brw_sf_prog; +const struct brw_tracked_state brw_sf_unit; +const struct brw_tracked_state brw_sf_vp; +const struct brw_tracked_state brw_state_base_address; +const struct brw_tracked_state brw_urb_fence; +const struct brw_tracked_state brw_vertex_state; +const struct brw_tracked_state brw_vs_prog; +const struct brw_tracked_state brw_vs_unit; +const struct brw_tracked_state brw_wm_prog; +const struct brw_tracked_state brw_wm_samplers; +const struct brw_tracked_state brw_wm_surfaces; +const struct brw_tracked_state brw_wm_unit; + +const struct brw_tracked_state brw_psp_urb_cbs; + +const struct brw_tracked_state brw_active_vertprog; +const struct brw_tracked_state brw_tnl_vertprog; +const struct brw_tracked_state brw_pipe_control; + +const struct brw_tracked_state brw_clear_surface_cache; +const struct brw_tracked_state brw_clear_batch_cache; + +/*********************************************************************** + * brw_state_cache.c + */ +unsigned brw_cache_data(struct brw_cache *cache, + const void *data ); + +unsigned brw_cache_data_sz(struct brw_cache *cache, + const void *data, + unsigned data_sz); + +unsigned brw_upload_cache( struct brw_cache *cache, + const void *key, + unsigned key_sz, + const void *data, + unsigned data_sz, + const void *aux, + void *aux_return ); + +boolean brw_search_cache( struct brw_cache *cache, + const void *key, + unsigned key_size, + void *aux_return, + unsigned *offset_return); + +void brw_init_caches( struct brw_context *brw ); +void brw_destroy_caches( struct brw_context *brw ); + +static inline struct pipe_buffer *brw_cache_buffer(struct brw_context *brw, + enum brw_cache_id id) +{ + return brw->cache[id].pool->buffer; +} + +/*********************************************************************** + * brw_state_batch.c + */ +#define BRW_CACHED_BATCH_STRUCT(brw, s) brw_cached_batch_struct( brw, (s), sizeof(*(s)) ) + +boolean brw_cached_batch_struct( struct brw_context *brw, + const void *data, + unsigned sz ); + +void brw_destroy_batch_cache( struct brw_context *brw ); + + +/*********************************************************************** + * brw_state_pool.c + */ +void brw_init_pools( struct brw_context *brw ); +void brw_destroy_pools( struct brw_context *brw ); + +boolean brw_pool_alloc( struct brw_mem_pool *pool, + unsigned size, + unsigned alignment, + unsigned *offset_return); + +void brw_pool_fence( struct brw_context *brw, + struct brw_mem_pool *pool, + unsigned fence ); + + +void brw_pool_check_wrap( struct brw_context *brw, + struct brw_mem_pool *pool ); + +void brw_clear_all_caches( struct brw_context *brw ); +void brw_invalidate_pools( struct brw_context *brw ); +void brw_clear_batch_cache_flush( struct brw_context *brw ); + + +/* brw_shader_info.c + */ + +void brw_shader_info(const struct tgsi_token *tokens, + struct brw_shader_info *info ); + + +#endif diff --git a/src/gallium/drivers/i965simple/brw_state_batch.c b/src/gallium/drivers/i965simple/brw_state_batch.c new file mode 100644 index 0000000000..35db76b594 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_state_batch.c @@ -0,0 +1,113 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_state.h" +#include "brw_winsys.h" + +#include "pipe/p_util.h" + +/* A facility similar to the data caching code above, which aims to + * prevent identical commands being issued repeatedly. + */ +boolean brw_cached_batch_struct( struct brw_context *brw, + const void *data, + unsigned sz ) +{ + struct brw_cached_batch_item *item = brw->cached_batch_items; + struct header *newheader = (struct header *)data; + + if (brw->emit_state_always) { + brw_batchbuffer_data(brw->winsys, data, sz); + return TRUE; + } + + while (item) { + if (item->header->opcode == newheader->opcode) { + if (item->sz == sz && memcmp(item->header, newheader, sz) == 0) + return FALSE; + if (item->sz != sz) { + FREE(item->header); + item->header = MALLOC(sz); + item->sz = sz; + } + goto emit; + } + item = item->next; + } + + assert(!item); + item = CALLOC_STRUCT(brw_cached_batch_item); + item->header = MALLOC(sz); + item->sz = sz; + item->next = brw->cached_batch_items; + brw->cached_batch_items = item; + +emit: + memcpy(item->header, newheader, sz); + brw_batchbuffer_data(brw->winsys, data, sz); + return TRUE; +} + +static void clear_batch_cache( struct brw_context *brw ) +{ + struct brw_cached_batch_item *item = brw->cached_batch_items; + + while (item) { + struct brw_cached_batch_item *next = item->next; + free((void *)item->header); + free(item); + item = next; + } + + brw->cached_batch_items = NULL; + + + brw_clear_all_caches(brw); + + brw_invalidate_pools(brw); +} + +void brw_clear_batch_cache_flush( struct brw_context *brw ) +{ + clear_batch_cache(brw); + +/* brw_do_flush(brw, BRW_FLUSH_STATE_CACHE|BRW_FLUSH_READ_CACHE); */ + + brw->state.dirty.brw |= ~0; + brw->state.dirty.cache |= ~0; +} + + + +void brw_destroy_batch_cache( struct brw_context *brw ) +{ + clear_batch_cache(brw); +} diff --git a/src/gallium/drivers/i965simple/brw_state_cache.c b/src/gallium/drivers/i965simple/brw_state_cache.c new file mode 100644 index 0000000000..b3a5124461 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_state_cache.c @@ -0,0 +1,443 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_state.h" + +#include "brw_wm.h" +#include "brw_vs.h" +#include "brw_clip.h" +#include "brw_sf.h" +#include "brw_gs.h" + +#include "pipe/p_util.h" + + + +/*********************************************************************** + * Check cache for uploaded version of struct, else upload new one. + * Fail when memory is exhausted. + * + * XXX: FIXME: Currently search is so slow it would be quicker to + * regenerate the data every time... + */ + +static unsigned hash_key( const void *key, unsigned key_size ) +{ + unsigned *ikey = (unsigned *)key; + unsigned hash = 0, i; + + assert(key_size % 4 == 0); + + /* I'm sure this can be improved on: + */ + for (i = 0; i < key_size/4; i++) + hash ^= ikey[i]; + + return hash; +} + +static struct brw_cache_item *search_cache( struct brw_cache *cache, + unsigned hash, + const void *key, + unsigned key_size) +{ + struct brw_cache_item *c; + + for (c = cache->items[hash % cache->size]; c; c = c->next) { + if (c->hash == hash && + c->key_size == key_size && + memcmp(c->key, key, key_size) == 0) + return c; + } + + return NULL; +} + + +static void rehash( struct brw_cache *cache ) +{ + struct brw_cache_item **items; + struct brw_cache_item *c, *next; + unsigned size, i; + + size = cache->size * 3; + items = (struct brw_cache_item**) MALLOC(size * sizeof(*items)); + memset(items, 0, size * sizeof(*items)); + + for (i = 0; i < cache->size; i++) + for (c = cache->items[i]; c; c = next) { + next = c->next; + c->next = items[c->hash % size]; + items[c->hash % size] = c; + } + + FREE(cache->items); + cache->items = items; + cache->size = size; +} + + +boolean brw_search_cache( struct brw_cache *cache, + const void *key, + unsigned key_size, + void *aux_return, + unsigned *offset_return) +{ + struct brw_cache_item *item; + unsigned addr = 0; + unsigned hash = hash_key(key, key_size); + + item = search_cache(cache, hash, key, key_size); + + if (item) { + if (aux_return) + *(void **)aux_return = (void *)((char *)item->key + item->key_size); + + *offset_return = addr = item->offset; + } + + if (item == NULL || addr != cache->last_addr) { + cache->brw->state.dirty.cache |= 1<id; + cache->last_addr = addr; + } + + return item != NULL; +} + +unsigned brw_upload_cache( struct brw_cache *cache, + const void *key, + unsigned key_size, + const void *data, + unsigned data_size, + const void *aux, + void *aux_return ) +{ + unsigned offset; + struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item); + unsigned hash = hash_key(key, key_size); + void *tmp = MALLOC(key_size + cache->aux_size); + + if (!brw_pool_alloc(cache->pool, data_size, 1 << 6, &offset)) { + /* Should not be possible: + */ + debug_printf("brw_pool_alloc failed\n"); + exit(1); + } + + memcpy(tmp, key, key_size); + + if (cache->aux_size) + memcpy(tmp+key_size, aux, cache->aux_size); + + item->key = tmp; + item->hash = hash; + item->key_size = key_size; + item->offset = offset; + item->data_size = data_size; + + if (++cache->n_items > cache->size * 1.5) + rehash(cache); + + hash %= cache->size; + item->next = cache->items[hash]; + cache->items[hash] = item; + + if (aux_return) { + assert(cache->aux_size); + *(void **)aux_return = (void *)((char *)item->key + item->key_size); + } + + if (BRW_DEBUG & DEBUG_STATE) + debug_printf("upload %s: %d bytes to pool buffer %p offset %x\n", + cache->name, + data_size, + (void*)cache->pool->buffer, + offset); + + /* Copy data to the buffer: + */ + cache->brw->winsys->buffer_subdata_typed(cache->brw->winsys, + cache->pool->buffer, + offset, + data_size, + data, + cache->id); + + cache->brw->state.dirty.cache |= 1<id; + cache->last_addr = offset; + + return offset; +} + +/* This doesn't really work with aux data. Use search/upload instead + */ +unsigned brw_cache_data_sz(struct brw_cache *cache, + const void *data, + unsigned data_size) +{ + unsigned addr; + + if (!brw_search_cache(cache, data, data_size, NULL, &addr)) { + addr = brw_upload_cache(cache, + data, data_size, + data, data_size, + NULL, NULL); + } + + return addr; +} + +unsigned brw_cache_data(struct brw_cache *cache, + const void *data) +{ + return brw_cache_data_sz(cache, data, cache->key_size); +} + +enum pool_type { + DW_SURFACE_STATE, + DW_GENERAL_STATE +}; + +static void brw_init_cache( struct brw_context *brw, + const char *name, + unsigned id, + unsigned key_size, + unsigned aux_size, + enum pool_type pool_type) +{ + struct brw_cache *cache = &brw->cache[id]; + cache->brw = brw; + cache->id = id; + cache->name = name; + cache->items = NULL; + + cache->size = 7; + cache->n_items = 0; + cache->items = (struct brw_cache_item **) + CALLOC(cache->size, sizeof(struct brw_cache_item)); + + + cache->key_size = key_size; + cache->aux_size = aux_size; + switch (pool_type) { + case DW_GENERAL_STATE: cache->pool = &brw->pool[BRW_GS_POOL]; break; + case DW_SURFACE_STATE: cache->pool = &brw->pool[BRW_SS_POOL]; break; + default: assert(0); break; + } +} + +void brw_init_caches( struct brw_context *brw ) +{ + + brw_init_cache(brw, + "CC_VP", + BRW_CC_VP, + sizeof(struct brw_cc_viewport), + 0, + DW_GENERAL_STATE); + + brw_init_cache(brw, + "CC_UNIT", + BRW_CC_UNIT, + sizeof(struct brw_cc_unit_state), + 0, + DW_GENERAL_STATE); + + brw_init_cache(brw, + "WM_PROG", + BRW_WM_PROG, + sizeof(struct brw_wm_prog_key), + sizeof(struct brw_wm_prog_data), + DW_GENERAL_STATE); + + brw_init_cache(brw, + "SAMPLER_DEFAULT_COLOR", + BRW_SAMPLER_DEFAULT_COLOR, + sizeof(struct brw_sampler_default_color), + 0, + DW_GENERAL_STATE); + + brw_init_cache(brw, + "SAMPLER", + BRW_SAMPLER, + 0, /* variable key/data size */ + 0, + DW_GENERAL_STATE); + + brw_init_cache(brw, + "WM_UNIT", + BRW_WM_UNIT, + sizeof(struct brw_wm_unit_state), + 0, + DW_GENERAL_STATE); + + brw_init_cache(brw, + "SF_PROG", + BRW_SF_PROG, + sizeof(struct brw_sf_prog_key), + sizeof(struct brw_sf_prog_data), + DW_GENERAL_STATE); + + brw_init_cache(brw, + "SF_VP", + BRW_SF_VP, + sizeof(struct brw_sf_viewport), + 0, + DW_GENERAL_STATE); + + brw_init_cache(brw, + "SF_UNIT", + BRW_SF_UNIT, + sizeof(struct brw_sf_unit_state), + 0, + DW_GENERAL_STATE); + + brw_init_cache(brw, + "VS_UNIT", + BRW_VS_UNIT, + sizeof(struct brw_vs_unit_state), + 0, + DW_GENERAL_STATE); + + brw_init_cache(brw, + "VS_PROG", + BRW_VS_PROG, + sizeof(struct brw_vs_prog_key), + sizeof(struct brw_vs_prog_data), + DW_GENERAL_STATE); + + brw_init_cache(brw, + "CLIP_UNIT", + BRW_CLIP_UNIT, + sizeof(struct brw_clip_unit_state), + 0, + DW_GENERAL_STATE); + + brw_init_cache(brw, + "CLIP_PROG", + BRW_CLIP_PROG, + sizeof(struct brw_clip_prog_key), + sizeof(struct brw_clip_prog_data), + DW_GENERAL_STATE); + + brw_init_cache(brw, + "GS_UNIT", + BRW_GS_UNIT, + sizeof(struct brw_gs_unit_state), + 0, + DW_GENERAL_STATE); + + brw_init_cache(brw, + "GS_PROG", + BRW_GS_PROG, + sizeof(struct brw_gs_prog_key), + sizeof(struct brw_gs_prog_data), + DW_GENERAL_STATE); + + brw_init_cache(brw, + "SS_SURFACE", + BRW_SS_SURFACE, + sizeof(struct brw_surface_state), + 0, + DW_SURFACE_STATE); + + brw_init_cache(brw, + "SS_SURF_BIND", + BRW_SS_SURF_BIND, + sizeof(struct brw_surface_binding_table), + 0, + DW_SURFACE_STATE); +} + + +/* When we lose hardware context, need to invalidate the surface cache + * as these structs must be explicitly re-uploaded. They are subject + * to fixup by the memory manager as they contain absolute agp + * offsets, so we need to ensure there is a fresh version of the + * struct available to receive the fixup. + * + * XXX: Need to ensure that there aren't two versions of a surface or + * bufferobj with different backing data active in the same buffer at + * once? Otherwise the cache could confuse them. Maybe better not to + * cache at all? + * + * --> Isn't this the same as saying need to ensure batch is flushed + * before new data is uploaded to an existing buffer? We + * already try to make sure of that. + */ +static void clear_cache( struct brw_cache *cache ) +{ + struct brw_cache_item *c, *next; + unsigned i; + + for (i = 0; i < cache->size; i++) { + for (c = cache->items[i]; c; c = next) { + next = c->next; + free((void *)c->key); + free(c); + } + cache->items[i] = NULL; + } + + cache->n_items = 0; +} + +void brw_clear_all_caches( struct brw_context *brw ) +{ + int i; + + if (BRW_DEBUG & DEBUG_STATE) + debug_printf("%s\n", __FUNCTION__); + + for (i = 0; i < BRW_MAX_CACHE; i++) + clear_cache(&brw->cache[i]); + + if (brw->curbe.last_buf) { + FREE(brw->curbe.last_buf); + brw->curbe.last_buf = NULL; + } + + brw->state.dirty.brw |= ~0; + brw->state.dirty.cache |= ~0; +} + + + + + +void brw_destroy_caches( struct brw_context *brw ) +{ + unsigned i; + + for (i = 0; i < BRW_MAX_CACHE; i++) + clear_cache(&brw->cache[i]); +} diff --git a/src/gallium/drivers/i965simple/brw_state_pool.c b/src/gallium/drivers/i965simple/brw_state_pool.c new file mode 100644 index 0000000000..f3174bfe0a --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_state_pool.c @@ -0,0 +1,137 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +/** @file brw_state_pool.c + * Implements the state pool allocator. + * + * For the 965, we create two state pools for state cache entries. Objects + * will be allocated into the pools depending on which state base address + * their pointer is relative to in other 965 state. + * + * The state pools are relatively simple: As objects are allocated, increment + * the offset to allocate space. When the pool is "full" (rather, close to + * full), we reset the pool and reset the state cache entries that point into + * the pool. + */ + +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "brw_context.h" +#include "brw_state.h" + +boolean brw_pool_alloc( struct brw_mem_pool *pool, + unsigned size, + unsigned alignment, + unsigned *offset_return) +{ + unsigned fixup = align(pool->offset, alignment) - pool->offset; + + size = align(size, 4); + + if (pool->offset + fixup + size >= pool->size) { + debug_printf("%s failed\n", __FUNCTION__); + assert(0); + exit(0); + } + + pool->offset += fixup; + *offset_return = pool->offset; + pool->offset += size; + + return TRUE; +} + +static +void brw_invalidate_pool( struct brw_mem_pool *pool ) +{ + if (BRW_DEBUG & DEBUG_STATE) + debug_printf("\n\n\n %s \n\n\n", __FUNCTION__); + + pool->offset = 0; + + brw_clear_all_caches(pool->brw); +} + + +static void brw_init_pool( struct brw_context *brw, + unsigned pool_id, + unsigned size ) +{ + struct brw_mem_pool *pool = &brw->pool[pool_id]; + + pool->size = size; + pool->brw = brw; + + pool->buffer = brw->pipe.winsys->buffer_create(brw->pipe.winsys, + 4096, + 0 /* DRM_BO_FLAG_MEM_TT */, + size); +} + +static void brw_destroy_pool( struct brw_context *brw, + unsigned pool_id ) +{ + struct brw_mem_pool *pool = &brw->pool[pool_id]; + + pipe_buffer_reference( pool->brw->pipe.winsys, + &pool->buffer, + NULL ); +} + + +void brw_pool_check_wrap( struct brw_context *brw, + struct brw_mem_pool *pool ) +{ + if (pool->offset > (pool->size * 3) / 4) { + brw->state.dirty.brw |= BRW_NEW_SCENE; + } + +} + +void brw_init_pools( struct brw_context *brw ) +{ + brw_init_pool(brw, BRW_GS_POOL, 0x80000); + brw_init_pool(brw, BRW_SS_POOL, 0x80000); +} + +void brw_destroy_pools( struct brw_context *brw ) +{ + brw_destroy_pool(brw, BRW_GS_POOL); + brw_destroy_pool(brw, BRW_SS_POOL); +} + + +void brw_invalidate_pools( struct brw_context *brw ) +{ + brw_invalidate_pool(&brw->pool[BRW_GS_POOL]); + brw_invalidate_pool(&brw->pool[BRW_SS_POOL]); +} diff --git a/src/gallium/drivers/i965simple/brw_state_upload.c b/src/gallium/drivers/i965simple/brw_state_upload.c new file mode 100644 index 0000000000..e727601e1e --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_state_upload.c @@ -0,0 +1,202 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_context.h" +#include "brw_state.h" + +#include "pipe/p_util.h" + +/* This is used to initialize brw->state.atoms[]. We could use this + * list directly except for a single atom, brw_constant_buffer, which + * has a .dirty value which changes according to the parameters of the + * current fragment and vertex programs, and so cannot be a static + * value. + */ +const struct brw_tracked_state *atoms[] = +{ + &brw_vs_prog, + &brw_gs_prog, + &brw_clip_prog, + &brw_sf_prog, + &brw_wm_prog, + + /* Once all the programs are done, we know how large urb entry + * sizes need to be and can decide if we need to change the urb + * layout. + */ + &brw_curbe_offsets, + &brw_recalculate_urb_fence, + + + &brw_cc_vp, + &brw_cc_unit, + + &brw_wm_surfaces, /* must do before samplers */ + &brw_wm_samplers, + + &brw_wm_unit, + &brw_sf_vp, + &brw_sf_unit, + &brw_vs_unit, /* always required, enabled or not */ + &brw_clip_unit, + &brw_gs_unit, + + /* Command packets: + */ + &brw_invarient_state, + &brw_state_base_address, + &brw_pipe_control, + + &brw_binding_table_pointers, + &brw_blend_constant_color, + + &brw_drawing_rect, + &brw_depthbuffer, + + &brw_polygon_stipple, + &brw_line_stipple, + + &brw_psp_urb_cbs, + + &brw_constant_buffer +}; + + +void brw_init_state( struct brw_context *brw ) +{ + brw_init_pools(brw); + brw_init_caches(brw); + + brw->state.dirty.brw = ~0; + brw->emit_state_always = 0; +} + + +void brw_destroy_state( struct brw_context *brw ) +{ + brw_destroy_caches(brw); + brw_destroy_batch_cache(brw); + brw_destroy_pools(brw); +} + +/*********************************************************************** + */ + +static boolean check_state( const struct brw_state_flags *a, + const struct brw_state_flags *b ) +{ + return ((a->brw & b->brw) || + (a->cache & b->cache)); +} + +static void accumulate_state( struct brw_state_flags *a, + const struct brw_state_flags *b ) +{ + a->brw |= b->brw; + a->cache |= b->cache; +} + + +static void xor_states( struct brw_state_flags *result, + const struct brw_state_flags *a, + const struct brw_state_flags *b ) +{ + result->brw = a->brw ^ b->brw; + result->cache = a->cache ^ b->cache; +} + + +/*********************************************************************** + * Emit all state: + */ +void brw_validate_state( struct brw_context *brw ) +{ + struct brw_state_flags *state = &brw->state.dirty; + unsigned i; + + if (brw->emit_state_always) + state->brw |= ~0; + + if (state->cache == 0 && + state->brw == 0) + return; + + if (brw->state.dirty.brw & BRW_NEW_SCENE) + brw_clear_batch_cache_flush(brw); + + if (BRW_DEBUG) { + /* Debug version which enforces various sanity checks on the + * state flags which are generated and checked to help ensure + * state atoms are ordered correctly in the list. + */ + struct brw_state_flags examined, prev; + memset(&examined, 0, sizeof(examined)); + prev = *state; + + for (i = 0; i < Elements(atoms); i++) { + const struct brw_tracked_state *atom = atoms[i]; + struct brw_state_flags generated; + + assert(atom->dirty.brw || + atom->dirty.cache); + assert(atom->update); + + if (check_state(state, &atom->dirty)) { + atom->update( brw ); + } + + accumulate_state(&examined, &atom->dirty); + + /* generated = (prev ^ state) + * if (examined & generated) + * fail; + */ + xor_states(&generated, &prev, state); + assert(!check_state(&examined, &generated)); + prev = *state; + } + } + else { + for (i = 0; i < Elements(atoms); i++) { + const struct brw_tracked_state *atom = atoms[i]; + + assert(atom->dirty.brw || + atom->dirty.cache); + assert(atom->update); + + if (check_state(state, &atom->dirty)) + atom->update( brw ); + } + } + + memset(state, 0, sizeof(*state)); +} diff --git a/src/gallium/drivers/i965simple/brw_strings.c b/src/gallium/drivers/i965simple/brw_strings.c new file mode 100644 index 0000000000..29a41ed1e9 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_strings.c @@ -0,0 +1,72 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "brw_context.h" +#include "brw_reg.h" + + +static const char *brw_get_vendor( struct pipe_context *pipe ) +{ + return "Tungsten Graphics, Inc."; +} + + +static const char *brw_get_name( struct pipe_context *pipe ) +{ + static char buffer[128]; + const char *chipset; + + switch (brw_context(pipe)->pci_id) { + case PCI_CHIP_I965_Q: + chipset = "Intel(R) 965Q"; + break; + case PCI_CHIP_I965_G: + case PCI_CHIP_I965_G_1: + chipset = "Intel(R) 965G"; + break; + case PCI_CHIP_I965_GM: + chipset = "Intel(R) 965GM"; + break; + case PCI_CHIP_I965_GME: + chipset = "Intel(R) 965GME/GLE"; + break; + default: + chipset = "unknown"; + break; + } + + sprintf(buffer, "pipe/i965 (chipset: %s)", chipset); + return buffer; +} + + +void +brw_init_string_functions(struct brw_context *brw) +{ + brw->pipe.get_name = brw_get_name; + brw->pipe.get_vendor = brw_get_vendor; +} diff --git a/src/gallium/drivers/i965simple/brw_structs.h b/src/gallium/drivers/i965simple/brw_structs.h new file mode 100644 index 0000000000..bbb087e95d --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_structs.h @@ -0,0 +1,1348 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRW_STRUCTS_H +#define BRW_STRUCTS_H + +#include "pipe/p_compiler.h" + +/* Command packets: + */ +struct header +{ + unsigned length:16; + unsigned opcode:16; +}; + + +union header_union +{ + struct header bits; + unsigned dword; +}; + +struct brw_3d_control +{ + struct + { + unsigned length:8; + unsigned notify_enable:1; + unsigned pad:3; + unsigned wc_flush_enable:1; + unsigned depth_stall_enable:1; + unsigned operation:2; + unsigned opcode:16; + } header; + + struct + { + unsigned pad:2; + unsigned dest_addr_type:1; + unsigned dest_addr:29; + } dest; + + unsigned dword2; + unsigned dword3; +}; + + +struct brw_3d_primitive +{ + struct + { + unsigned length:8; + unsigned pad:2; + unsigned topology:5; + unsigned indexed:1; + unsigned opcode:16; + } header; + + unsigned verts_per_instance; + unsigned start_vert_location; + unsigned instance_count; + unsigned start_instance_location; + unsigned base_vert_location; +}; + +/* These seem to be passed around as function args, so it works out + * better to keep them as #defines: + */ +#define BRW_FLUSH_READ_CACHE 0x1 +#define BRW_FLUSH_STATE_CACHE 0x2 +#define BRW_INHIBIT_FLUSH_RENDER_CACHE 0x4 +#define BRW_FLUSH_SNAPSHOT_COUNTERS 0x8 + +struct brw_mi_flush +{ + unsigned flags:4; + unsigned pad:12; + unsigned opcode:16; +}; + +struct brw_vf_statistics +{ + unsigned statistics_enable:1; + unsigned pad:15; + unsigned opcode:16; +}; + + + +struct brw_binding_table_pointers +{ + struct header header; + unsigned vs; + unsigned gs; + unsigned clp; + unsigned sf; + unsigned wm; +}; + + +struct brw_blend_constant_color +{ + struct header header; + float blend_constant_color[4]; +}; + + +struct brw_depthbuffer +{ + union header_union header; + + union { + struct { + unsigned pitch:18; + unsigned format:3; + unsigned pad:4; + unsigned depth_offset_disable:1; + unsigned tile_walk:1; + unsigned tiled_surface:1; + unsigned pad2:1; + unsigned surface_type:3; + } bits; + unsigned dword; + } dword1; + + unsigned dword2_base_addr; + + union { + struct { + unsigned pad:1; + unsigned mipmap_layout:1; + unsigned lod:4; + unsigned width:13; + unsigned height:13; + } bits; + unsigned dword; + } dword3; + + union { + struct { + unsigned pad:12; + unsigned min_array_element:9; + unsigned depth:11; + } bits; + unsigned dword; + } dword4; +}; + +struct brw_drawrect +{ + struct header header; + unsigned xmin:16; + unsigned ymin:16; + unsigned xmax:16; + unsigned ymax:16; + unsigned xorg:16; + unsigned yorg:16; +}; + + + + +struct brw_global_depth_offset_clamp +{ + struct header header; + float depth_offset_clamp; +}; + +struct brw_indexbuffer +{ + union { + struct + { + unsigned length:8; + unsigned index_format:2; + unsigned cut_index_enable:1; + unsigned pad:5; + unsigned opcode:16; + } bits; + unsigned dword; + + } header; + + unsigned buffer_start; + unsigned buffer_end; +}; + + +struct brw_line_stipple +{ + struct header header; + + struct + { + unsigned pattern:16; + unsigned pad:16; + } bits0; + + struct + { + unsigned repeat_count:9; + unsigned pad:7; + unsigned inverse_repeat_count:16; + } bits1; +}; + + +struct brw_pipelined_state_pointers +{ + struct header header; + + struct { + unsigned pad:5; + unsigned offset:27; + } vs; + + struct + { + unsigned enable:1; + unsigned pad:4; + unsigned offset:27; + } gs; + + struct + { + unsigned enable:1; + unsigned pad:4; + unsigned offset:27; + } clp; + + struct + { + unsigned pad:5; + unsigned offset:27; + } sf; + + struct + { + unsigned pad:5; + unsigned offset:27; + } wm; + + struct + { + unsigned pad:5; + unsigned offset:27; /* KW: check me! */ + } cc; +}; + + +struct brw_polygon_stipple_offset +{ + struct header header; + + struct { + unsigned y_offset:5; + unsigned pad:3; + unsigned x_offset:5; + unsigned pad0:19; + } bits0; +}; + + + +struct brw_polygon_stipple +{ + struct header header; + unsigned stipple[32]; +}; + + + +struct brw_pipeline_select +{ + struct + { + unsigned pipeline_select:1; + unsigned pad:15; + unsigned opcode:16; + } header; +}; + + +struct brw_pipe_control +{ + struct + { + unsigned length:8; + unsigned notify_enable:1; + unsigned pad:2; + unsigned instruction_state_cache_flush_enable:1; + unsigned write_cache_flush_enable:1; + unsigned depth_stall_enable:1; + unsigned post_sync_operation:2; + + unsigned opcode:16; + } header; + + struct + { + unsigned pad:2; + unsigned dest_addr_type:1; + unsigned dest_addr:29; + } bits1; + + unsigned data0; + unsigned data1; +}; + + +struct brw_urb_fence +{ + struct + { + unsigned length:8; + unsigned vs_realloc:1; + unsigned gs_realloc:1; + unsigned clp_realloc:1; + unsigned sf_realloc:1; + unsigned vfe_realloc:1; + unsigned cs_realloc:1; + unsigned pad:2; + unsigned opcode:16; + } header; + + struct + { + unsigned vs_fence:10; + unsigned gs_fence:10; + unsigned clp_fence:10; + unsigned pad:2; + } bits0; + + struct + { + unsigned sf_fence:10; + unsigned vf_fence:10; + unsigned cs_fence:10; + unsigned pad:2; + } bits1; +}; + +struct brw_constant_buffer_state /* previously brw_command_streamer */ +{ + struct header header; + + struct + { + unsigned nr_urb_entries:3; + unsigned pad:1; + unsigned urb_entry_size:5; + unsigned pad0:23; + } bits0; +}; + +struct brw_constant_buffer +{ + struct + { + unsigned length:8; + unsigned valid:1; + unsigned pad:7; + unsigned opcode:16; + } header; + + struct + { + unsigned buffer_length:6; + unsigned buffer_address:26; + } bits0; +}; + +struct brw_state_base_address +{ + struct header header; + + struct + { + unsigned modify_enable:1; + unsigned pad:4; + unsigned general_state_address:27; + } bits0; + + struct + { + unsigned modify_enable:1; + unsigned pad:4; + unsigned surface_state_address:27; + } bits1; + + struct + { + unsigned modify_enable:1; + unsigned pad:4; + unsigned indirect_object_state_address:27; + } bits2; + + struct + { + unsigned modify_enable:1; + unsigned pad:11; + unsigned general_state_upper_bound:20; + } bits3; + + struct + { + unsigned modify_enable:1; + unsigned pad:11; + unsigned indirect_object_state_upper_bound:20; + } bits4; +}; + +struct brw_state_prefetch +{ + struct header header; + + struct + { + unsigned prefetch_count:3; + unsigned pad:3; + unsigned prefetch_pointer:26; + } bits0; +}; + +struct brw_system_instruction_pointer +{ + struct header header; + + struct + { + unsigned pad:4; + unsigned system_instruction_pointer:28; + } bits0; +}; + + + + +/* State structs for the various fixed function units: + */ + + +struct thread0 +{ + unsigned pad0:1; + unsigned grf_reg_count:3; + unsigned pad1:2; + unsigned kernel_start_pointer:26; +}; + +struct thread1 +{ + unsigned ext_halt_exception_enable:1; + unsigned sw_exception_enable:1; + unsigned mask_stack_exception_enable:1; + unsigned timeout_exception_enable:1; + unsigned illegal_op_exception_enable:1; + unsigned pad0:3; + unsigned depth_coef_urb_read_offset:6; /* WM only */ + unsigned pad1:2; + unsigned floating_point_mode:1; + unsigned thread_priority:1; + unsigned binding_table_entry_count:8; + unsigned pad3:5; + unsigned single_program_flow:1; +}; + +struct thread2 +{ + unsigned per_thread_scratch_space:4; + unsigned pad0:6; + unsigned scratch_space_base_pointer:22; +}; + + +struct thread3 +{ + unsigned dispatch_grf_start_reg:4; + unsigned urb_entry_read_offset:6; + unsigned pad0:1; + unsigned urb_entry_read_length:6; + unsigned pad1:1; + unsigned const_urb_entry_read_offset:6; + unsigned pad2:1; + unsigned const_urb_entry_read_length:6; + unsigned pad3:1; +}; + + + +struct brw_clip_unit_state +{ + struct thread0 thread0; + struct + { + unsigned pad0:7; + unsigned sw_exception_enable:1; + unsigned pad1:3; + unsigned mask_stack_exception_enable:1; + unsigned pad2:1; + unsigned illegal_op_exception_enable:1; + unsigned pad3:2; + unsigned floating_point_mode:1; + unsigned thread_priority:1; + unsigned binding_table_entry_count:8; + unsigned pad4:5; + unsigned single_program_flow:1; + } thread1; + + struct thread2 thread2; + struct thread3 thread3; + + struct + { + unsigned pad0:9; + unsigned gs_output_stats:1; /* not always */ + unsigned stats_enable:1; + unsigned nr_urb_entries:7; + unsigned pad1:1; + unsigned urb_entry_allocation_size:5; + unsigned pad2:1; + unsigned max_threads:1; /* may be less */ + unsigned pad3:6; + } thread4; + + struct + { + unsigned pad0:13; + unsigned clip_mode:3; + unsigned userclip_enable_flags:8; + unsigned userclip_must_clip:1; + unsigned pad1:1; + unsigned guard_band_enable:1; + unsigned viewport_z_clip_enable:1; + unsigned viewport_xy_clip_enable:1; + unsigned vertex_position_space:1; + unsigned api_mode:1; + unsigned pad2:1; + } clip5; + + struct + { + unsigned pad0:5; + unsigned clipper_viewport_state_ptr:27; + } clip6; + + + float viewport_xmin; + float viewport_xmax; + float viewport_ymin; + float viewport_ymax; +}; + + + +struct brw_cc_unit_state +{ + struct + { + unsigned pad0:3; + unsigned bf_stencil_pass_depth_pass_op:3; + unsigned bf_stencil_pass_depth_fail_op:3; + unsigned bf_stencil_fail_op:3; + unsigned bf_stencil_func:3; + unsigned bf_stencil_enable:1; + unsigned pad1:2; + unsigned stencil_write_enable:1; + unsigned stencil_pass_depth_pass_op:3; + unsigned stencil_pass_depth_fail_op:3; + unsigned stencil_fail_op:3; + unsigned stencil_func:3; + unsigned stencil_enable:1; + } cc0; + + + struct + { + unsigned bf_stencil_ref:8; + unsigned stencil_write_mask:8; + unsigned stencil_test_mask:8; + unsigned stencil_ref:8; + } cc1; + + + struct + { + unsigned logicop_enable:1; + unsigned pad0:10; + unsigned depth_write_enable:1; + unsigned depth_test_function:3; + unsigned depth_test:1; + unsigned bf_stencil_write_mask:8; + unsigned bf_stencil_test_mask:8; + } cc2; + + + struct + { + unsigned pad0:8; + unsigned alpha_test_func:3; + unsigned alpha_test:1; + unsigned blend_enable:1; + unsigned ia_blend_enable:1; + unsigned pad1:1; + unsigned alpha_test_format:1; + unsigned pad2:16; + } cc3; + + struct + { + unsigned pad0:5; + unsigned cc_viewport_state_offset:27; + } cc4; + + struct + { + unsigned pad0:2; + unsigned ia_dest_blend_factor:5; + unsigned ia_src_blend_factor:5; + unsigned ia_blend_function:3; + unsigned statistics_enable:1; + unsigned logicop_func:4; + unsigned pad1:11; + unsigned dither_enable:1; + } cc5; + + struct + { + unsigned clamp_post_alpha_blend:1; + unsigned clamp_pre_alpha_blend:1; + unsigned clamp_range:2; + unsigned pad0:11; + unsigned y_dither_offset:2; + unsigned x_dither_offset:2; + unsigned dest_blend_factor:5; + unsigned src_blend_factor:5; + unsigned blend_function:3; + } cc6; + + struct { + union { + float f; + ubyte ub[4]; + } alpha_ref; + } cc7; +}; + + + +struct brw_sf_unit_state +{ + struct thread0 thread0; + struct thread1 thread1; + struct thread2 thread2; + struct thread3 thread3; + + struct + { + unsigned pad0:10; + unsigned stats_enable:1; + unsigned nr_urb_entries:7; + unsigned pad1:1; + unsigned urb_entry_allocation_size:5; + unsigned pad2:1; + unsigned max_threads:6; + unsigned pad3:1; + } thread4; + + struct + { + unsigned front_winding:1; + unsigned viewport_transform:1; + unsigned pad0:3; + unsigned sf_viewport_state_offset:27; + } sf5; + + struct + { + unsigned pad0:9; + unsigned dest_org_vbias:4; + unsigned dest_org_hbias:4; + unsigned scissor:1; + unsigned disable_2x2_trifilter:1; + unsigned disable_zero_pix_trifilter:1; + unsigned point_rast_rule:2; + unsigned line_endcap_aa_region_width:2; + unsigned line_width:4; + unsigned fast_scissor_disable:1; + unsigned cull_mode:2; + unsigned aa_enable:1; + } sf6; + + struct + { + unsigned point_size:11; + unsigned use_point_size_state:1; + unsigned subpixel_precision:1; + unsigned sprite_point:1; + unsigned pad0:11; + unsigned trifan_pv:2; + unsigned linestrip_pv:2; + unsigned tristrip_pv:2; + unsigned line_last_pixel_enable:1; + } sf7; + +}; + + +struct brw_gs_unit_state +{ + struct thread0 thread0; + struct thread1 thread1; + struct thread2 thread2; + struct thread3 thread3; + + struct + { + unsigned pad0:10; + unsigned stats_enable:1; + unsigned nr_urb_entries:7; + unsigned pad1:1; + unsigned urb_entry_allocation_size:5; + unsigned pad2:1; + unsigned max_threads:1; + unsigned pad3:6; + } thread4; + + struct + { + unsigned sampler_count:3; + unsigned pad0:2; + unsigned sampler_state_pointer:27; + } gs5; + + + struct + { + unsigned max_vp_index:4; + unsigned pad0:26; + unsigned reorder_enable:1; + unsigned pad1:1; + } gs6; +}; + + +struct brw_vs_unit_state +{ + struct thread0 thread0; + struct thread1 thread1; + struct thread2 thread2; + struct thread3 thread3; + + struct + { + unsigned pad0:10; + unsigned stats_enable:1; + unsigned nr_urb_entries:7; + unsigned pad1:1; + unsigned urb_entry_allocation_size:5; + unsigned pad2:1; + unsigned max_threads:4; + unsigned pad3:3; + } thread4; + + struct + { + unsigned sampler_count:3; + unsigned pad0:2; + unsigned sampler_state_pointer:27; + } vs5; + + struct + { + unsigned vs_enable:1; + unsigned vert_cache_disable:1; + unsigned pad0:30; + } vs6; +}; + + +struct brw_wm_unit_state +{ + struct thread0 thread0; + struct thread1 thread1; + struct thread2 thread2; + struct thread3 thread3; + + struct { + unsigned stats_enable:1; + unsigned pad0:1; + unsigned sampler_count:3; + unsigned sampler_state_pointer:27; + } wm4; + + struct + { + unsigned enable_8_pix:1; + unsigned enable_16_pix:1; + unsigned enable_32_pix:1; + unsigned pad0:7; + unsigned legacy_global_depth_bias:1; + unsigned line_stipple:1; + unsigned depth_offset:1; + unsigned polygon_stipple:1; + unsigned line_aa_region_width:2; + unsigned line_endcap_aa_region_width:2; + unsigned early_depth_test:1; + unsigned thread_dispatch_enable:1; + unsigned program_uses_depth:1; + unsigned program_computes_depth:1; + unsigned program_uses_killpixel:1; + unsigned legacy_line_rast: 1; + unsigned pad1:1; + unsigned max_threads:6; + unsigned pad2:1; + } wm5; + + float global_depth_offset_constant; + float global_depth_offset_scale; +}; + +struct brw_sampler_default_color { + float color[4]; +}; + +struct brw_sampler_state +{ + + struct + { + unsigned shadow_function:3; + unsigned lod_bias:11; + unsigned min_filter:3; + unsigned mag_filter:3; + unsigned mip_filter:2; + unsigned base_level:5; + unsigned pad:1; + unsigned lod_preclamp:1; + unsigned default_color_mode:1; + unsigned pad0:1; + unsigned disable:1; + } ss0; + + struct + { + unsigned r_wrap_mode:3; + unsigned t_wrap_mode:3; + unsigned s_wrap_mode:3; + unsigned pad:3; + unsigned max_lod:10; + unsigned min_lod:10; + } ss1; + + + struct + { + unsigned pad:5; + unsigned default_color_pointer:27; + } ss2; + + struct + { + unsigned pad:19; + unsigned max_aniso:3; + unsigned chroma_key_mode:1; + unsigned chroma_key_index:2; + unsigned chroma_key_enable:1; + unsigned monochrome_filter_width:3; + unsigned monochrome_filter_height:3; + } ss3; +}; + + +struct brw_clipper_viewport +{ + float xmin; + float xmax; + float ymin; + float ymax; +}; + +struct brw_cc_viewport +{ + float min_depth; + float max_depth; +}; + +struct brw_sf_viewport +{ + struct { + float m00; + float m11; + float m22; + float m30; + float m31; + float m32; + } viewport; + + struct { + short xmin; + short ymin; + short xmax; + short ymax; + } scissor; +}; + +/* Documented in the subsystem/shared-functions/sampler chapter... + */ +struct brw_surface_state +{ + struct { + unsigned cube_pos_z:1; + unsigned cube_neg_z:1; + unsigned cube_pos_y:1; + unsigned cube_neg_y:1; + unsigned cube_pos_x:1; + unsigned cube_neg_x:1; + unsigned pad:4; + unsigned mipmap_layout_mode:1; + unsigned vert_line_stride_ofs:1; + unsigned vert_line_stride:1; + unsigned color_blend:1; + unsigned writedisable_blue:1; + unsigned writedisable_green:1; + unsigned writedisable_red:1; + unsigned writedisable_alpha:1; + unsigned surface_format:9; + unsigned data_return_format:1; + unsigned pad0:1; + unsigned surface_type:3; + } ss0; + + struct { + unsigned base_addr; + } ss1; + + struct { + unsigned pad:2; + unsigned mip_count:4; + unsigned width:13; + unsigned height:13; + } ss2; + + struct { + unsigned tile_walk:1; + unsigned tiled_surface:1; + unsigned pad:1; + unsigned pitch:18; + unsigned depth:11; + } ss3; + + struct { + unsigned pad:19; + unsigned min_array_elt:9; + unsigned min_lod:4; + } ss4; +}; + + + +struct brw_vertex_buffer_state +{ + struct { + unsigned pitch:11; + unsigned pad:15; + unsigned access_type:1; + unsigned vb_index:5; + } vb0; + + unsigned start_addr; + unsigned max_index; +#if 1 + unsigned instance_data_step_rate; /* not included for sequential/random vertices? */ +#endif +}; + +#define BRW_VBP_MAX 17 + +struct brw_vb_array_state { + struct header header; + struct brw_vertex_buffer_state vb[BRW_VBP_MAX]; +}; + + +struct brw_vertex_element_state +{ + struct + { + unsigned src_offset:11; + unsigned pad:5; + unsigned src_format:9; + unsigned pad0:1; + unsigned valid:1; + unsigned vertex_buffer_index:5; + } ve0; + + struct + { + unsigned dst_offset:8; + unsigned pad:8; + unsigned vfcomponent3:4; + unsigned vfcomponent2:4; + unsigned vfcomponent1:4; + unsigned vfcomponent0:4; + } ve1; +}; + +#define BRW_VEP_MAX 18 + +struct brw_vertex_element_packet { + struct header header; + struct brw_vertex_element_state ve[BRW_VEP_MAX]; /* note: less than _TNL_ATTRIB_MAX */ +}; + + +struct brw_urb_immediate { + unsigned opcode:4; + unsigned offset:6; + unsigned swizzle_control:2; + unsigned pad:1; + unsigned allocate:1; + unsigned used:1; + unsigned complete:1; + unsigned response_length:4; + unsigned msg_length:4; + unsigned msg_target:4; + unsigned pad1:3; + unsigned end_of_thread:1; +}; + +/* Instruction format for the execution units: + */ + +struct brw_instruction +{ + struct + { + unsigned opcode:7; + unsigned pad:1; + unsigned access_mode:1; + unsigned mask_control:1; + unsigned dependency_control:2; + unsigned compression_control:2; + unsigned thread_control:2; + unsigned predicate_control:4; + unsigned predicate_inverse:1; + unsigned execution_size:3; + unsigned destreg__conditonalmod:4; /* destreg - send, conditionalmod - others */ + unsigned pad0:2; + unsigned debug_control:1; + unsigned saturate:1; + } header; + + union { + struct + { + unsigned dest_reg_file:2; + unsigned dest_reg_type:3; + unsigned src0_reg_file:2; + unsigned src0_reg_type:3; + unsigned src1_reg_file:2; + unsigned src1_reg_type:3; + unsigned pad:1; + unsigned dest_subreg_nr:5; + unsigned dest_reg_nr:8; + unsigned dest_horiz_stride:2; + unsigned dest_address_mode:1; + } da1; + + struct + { + unsigned dest_reg_file:2; + unsigned dest_reg_type:3; + unsigned src0_reg_file:2; + unsigned src0_reg_type:3; + unsigned pad:6; + int dest_indirect_offset:10; /* offset against the deref'd address reg */ + unsigned dest_subreg_nr:3; /* subnr for the address reg a0.x */ + unsigned dest_horiz_stride:2; + unsigned dest_address_mode:1; + } ia1; + + struct + { + unsigned dest_reg_file:2; + unsigned dest_reg_type:3; + unsigned src0_reg_file:2; + unsigned src0_reg_type:3; + unsigned src1_reg_file:2; + unsigned src1_reg_type:3; + unsigned pad0:1; + unsigned dest_writemask:4; + unsigned dest_subreg_nr:1; + unsigned dest_reg_nr:8; + unsigned pad1:2; + unsigned dest_address_mode:1; + } da16; + + struct + { + unsigned dest_reg_file:2; + unsigned dest_reg_type:3; + unsigned src0_reg_file:2; + unsigned src0_reg_type:3; + unsigned pad0:6; + unsigned dest_writemask:4; + int dest_indirect_offset:6; + unsigned dest_subreg_nr:3; + unsigned pad1:2; + unsigned dest_address_mode:1; + } ia16; + } bits1; + + + union { + struct + { + unsigned src0_subreg_nr:5; + unsigned src0_reg_nr:8; + unsigned src0_abs:1; + unsigned src0_negate:1; + unsigned src0_address_mode:1; + unsigned src0_horiz_stride:2; + unsigned src0_width:3; + unsigned src0_vert_stride:4; + unsigned flag_reg_nr:1; + unsigned pad:6; + } da1; + + struct + { + int src0_indirect_offset:10; + unsigned src0_subreg_nr:3; + unsigned src0_abs:1; + unsigned src0_negate:1; + unsigned src0_address_mode:1; + unsigned src0_horiz_stride:2; + unsigned src0_width:3; + unsigned src0_vert_stride:4; + unsigned flag_reg_nr:1; + unsigned pad:6; + } ia1; + + struct + { + unsigned src0_swz_x:2; + unsigned src0_swz_y:2; + unsigned src0_subreg_nr:1; + unsigned src0_reg_nr:8; + unsigned src0_abs:1; + unsigned src0_negate:1; + unsigned src0_address_mode:1; + unsigned src0_swz_z:2; + unsigned src0_swz_w:2; + unsigned pad0:1; + unsigned src0_vert_stride:4; + unsigned flag_reg_nr:1; + unsigned pad1:6; + } da16; + + struct + { + unsigned src0_swz_x:2; + unsigned src0_swz_y:2; + int src0_indirect_offset:6; + unsigned src0_subreg_nr:3; + unsigned src0_abs:1; + unsigned src0_negate:1; + unsigned src0_address_mode:1; + unsigned src0_swz_z:2; + unsigned src0_swz_w:2; + unsigned pad0:1; + unsigned src0_vert_stride:4; + unsigned flag_reg_nr:1; + unsigned pad1:6; + } ia16; + + } bits2; + + union + { + struct + { + unsigned src1_subreg_nr:5; + unsigned src1_reg_nr:8; + unsigned src1_abs:1; + unsigned src1_negate:1; + unsigned pad:1; + unsigned src1_horiz_stride:2; + unsigned src1_width:3; + unsigned src1_vert_stride:4; + unsigned pad0:7; + } da1; + + struct + { + unsigned src1_swz_x:2; + unsigned src1_swz_y:2; + unsigned src1_subreg_nr:1; + unsigned src1_reg_nr:8; + unsigned src1_abs:1; + unsigned src1_negate:1; + unsigned pad0:1; + unsigned src1_swz_z:2; + unsigned src1_swz_w:2; + unsigned pad1:1; + unsigned src1_vert_stride:4; + unsigned pad2:7; + } da16; + + struct + { + int src1_indirect_offset:10; + unsigned src1_subreg_nr:3; + unsigned src1_abs:1; + unsigned src1_negate:1; + unsigned pad0:1; + unsigned src1_horiz_stride:2; + unsigned src1_width:3; + unsigned src1_vert_stride:4; + unsigned flag_reg_nr:1; + unsigned pad1:6; + } ia1; + + struct + { + unsigned src1_swz_x:2; + unsigned src1_swz_y:2; + int src1_indirect_offset:6; + unsigned src1_subreg_nr:3; + unsigned src1_abs:1; + unsigned src1_negate:1; + unsigned pad0:1; + unsigned src1_swz_z:2; + unsigned src1_swz_w:2; + unsigned pad1:1; + unsigned src1_vert_stride:4; + unsigned flag_reg_nr:1; + unsigned pad2:6; + } ia16; + + + struct + { + int jump_count:16; /* note: signed */ + unsigned pop_count:4; + unsigned pad0:12; + } if_else; + + struct { + unsigned function:4; + unsigned int_type:1; + unsigned precision:1; + unsigned saturate:1; + unsigned data_type:1; + unsigned pad0:8; + unsigned response_length:4; + unsigned msg_length:4; + unsigned msg_target:4; + unsigned pad1:3; + unsigned end_of_thread:1; + } math; + + struct { + unsigned binding_table_index:8; + unsigned sampler:4; + unsigned return_format:2; + unsigned msg_type:2; + unsigned response_length:4; + unsigned msg_length:4; + unsigned msg_target:4; + unsigned pad1:3; + unsigned end_of_thread:1; + } sampler; + + struct brw_urb_immediate urb; + + struct { + unsigned binding_table_index:8; + unsigned msg_control:4; + unsigned msg_type:2; + unsigned target_cache:2; + unsigned response_length:4; + unsigned msg_length:4; + unsigned msg_target:4; + unsigned pad1:3; + unsigned end_of_thread:1; + } dp_read; + + struct { + unsigned binding_table_index:8; + unsigned msg_control:3; + unsigned pixel_scoreboard_clear:1; + unsigned msg_type:3; + unsigned send_commit_msg:1; + unsigned response_length:4; + unsigned msg_length:4; + unsigned msg_target:4; + unsigned pad1:3; + unsigned end_of_thread:1; + } dp_write; + + struct { + unsigned pad:16; + unsigned response_length:4; + unsigned msg_length:4; + unsigned msg_target:4; + unsigned pad1:3; + unsigned end_of_thread:1; + } generic; + + int d; + unsigned ud; + } bits3; +}; + + +#endif diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c new file mode 100644 index 0000000000..518845e4b2 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -0,0 +1,210 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "brw_blit.h" +#include "brw_context.h" +#include "brw_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" +#include "pipe/util/p_tile.h" + + +/* + * XXX note: same as code in sp_surface.c + */ +static struct pipe_surface * +brw_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct brw_texture *tex = (struct brw_texture *)pt; + struct pipe_surface *ps; + unsigned offset; /* in bytes */ + + offset = tex->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE) { + offset += tex->image_offset[level][face] * pt->cpp; + } + else if (pt->target == PIPE_TEXTURE_3D) { + offset += tex->image_offset[level][zslice] * pt->cpp; + } + else { + assert(face == 0); + assert(zslice == 0); + } + + ps = pipe->winsys->surface_alloc(pipe->winsys); + if (ps) { + assert(ps->format); + assert(ps->refcount); + pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = tex->pitch; + ps->offset = offset; + } + return ps; +} + + +/* Upload data to a rectangular sub-region. Lots of choices how to do this: + * + * - memcpy by span to current destination + * - upload data as new buffer and blit + * + * Currently always memcpy. + */ +static void +brw_surface_data(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + const void *src, unsigned src_pitch, + unsigned srcx, unsigned srcy, unsigned width, unsigned height) +{ + pipe_copy_rect(pipe_surface_map(dst) + dst->offset, + dst->cpp, dst->pitch, + dstx, dsty, width, height, src, src_pitch, srcx, srcy); + + pipe_surface_unmap(dst); +} + + +/* Assumes all values are within bounds -- no checking at this level - + * do it higher up if required. + */ +static void +brw_surface_copy(struct pipe_context *pipe, + unsigned do_flip, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, unsigned width, unsigned height) +{ + assert(dst != src); + assert(dst->cpp == src->cpp); + + if (0) { + pipe_copy_rect(pipe_surface_map(dst) + dst->offset, + dst->cpp, + dst->pitch, + dstx, dsty, + width, height, + pipe_surface_map(src) + src->offset, + do_flip ? -src->pitch : src->pitch, + srcx, do_flip ? 1 - srcy - height : srcy); + + pipe_surface_unmap(src); + pipe_surface_unmap(dst); + } + else { + brw_copy_blit(brw_context(pipe), + do_flip, + dst->cpp, + (short) src->pitch, src->buffer, src->offset, FALSE, + (short) dst->pitch, dst->buffer, dst->offset, FALSE, + (short) srcx, (short) srcy, (short) dstx, (short) dsty, + (short) width, (short) height, PIPE_LOGICOP_COPY); + } +} + +/* Fill a rectangular sub-region. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ +static void * +get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) +{ + return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; +} + + +static void +brw_surface_fill(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, unsigned value) +{ + if (0) { + unsigned i, j; + void *dst_map = pipe_surface_map(dst); + + switch (dst->cpp) { + case 1: { + ubyte *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + memset(row, value, width); + row += dst->pitch; + } + } + break; + case 2: { + ushort *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = (ushort) value; + row += dst->pitch; + } + } + break; + case 4: { + unsigned *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = value; + row += dst->pitch; + } + } + break; + default: + assert(0); + break; + } + + pipe_surface_unmap( dst ); + } + else { + brw_fill_blit(brw_context(pipe), + dst->cpp, + (short) dst->pitch, + dst->buffer, dst->offset, FALSE, + (short) dstx, (short) dsty, + (short) width, (short) height, + value); + } +} + +void +brw_init_surface_functions(struct brw_context *brw) +{ + brw->pipe.get_tex_surface = brw_get_tex_surface; + brw->pipe.surface_copy = brw_surface_copy; + brw->pipe.surface_fill = brw_surface_fill; +} diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c new file mode 100644 index 0000000000..90561f1307 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -0,0 +1,353 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +/* Code to layout images in a mipmap tree for i965. + */ + +#include "brw_tex_layout.h" + +#include "pipe/p_state.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" + +#include "brw_context.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +#if 0 +unsigned intel_compressed_alignment(unsigned internalFormat) +{ + unsigned alignment = 4; + + switch (internalFormat) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + alignment = 8; + break; + + default: + break; + } + + return alignment; +} +#endif + +static unsigned minify( unsigned d ) +{ + return MAX2(1, d>>1); +} + + +static boolean brw_miptree_layout(struct pipe_context *, struct brw_texture *); + +static void intel_miptree_set_image_offset(struct brw_texture *tex, + unsigned level, + unsigned img, + unsigned x, unsigned y) +{ + struct pipe_texture *pt = &tex->base; + if (img == 0 && level == 0) + assert(x == 0 && y == 0); + assert(img < tex->nr_images[level]); + + tex->image_offset[level][img] = (x + y * tex->pitch) * pt->cpp; +} + +static void intel_miptree_set_level_info(struct brw_texture *tex, + unsigned level, + unsigned nr_images, + unsigned x, unsigned y, + unsigned w, unsigned h, unsigned d) +{ + struct pipe_texture *pt = &tex->base; + + assert(level < PIPE_MAX_TEXTURE_LEVELS); + + pt->width[level] = w; + pt->height[level] = h; + pt->depth[level] = d; + + tex->level_offset[level] = (x + y * tex->pitch) * pt->cpp; + tex->nr_images[level] = nr_images; + + /* + DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, + level, w, h, d, x, y, tex->level_offset[level]); + */ + + /* Not sure when this would happen, but anyway: + */ + if (tex->image_offset[level]) { + FREE(tex->image_offset[level]); + tex->image_offset[level] = NULL; + } + + assert(nr_images); + assert(!tex->image_offset[level]); + + tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned)); + tex->image_offset[level][0] = 0; +} + +static void i945_miptree_layout_2d(struct brw_texture *tex) +{ + struct pipe_texture *pt = &tex->base; + unsigned align_h = 2, align_w = 4; + unsigned level; + unsigned x = 0; + unsigned y = 0; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + + tex->pitch = pt->width[0]; + +#if 0 + if (pt->compressed) { + align_w = intel_compressed_alignment(pt->internal_format); + tex->pitch = ALIGN(pt->width[0], align_w); + } +#endif + + /* May need to adjust pitch to accomodate the placement of + * the 2nd mipmap. This occurs when the alignment + * constraints of mipmap placement push the right edge of the + * 2nd mipmap out past the width of its parent. + */ + if (pt->last_level > 0) { + unsigned mip1_width; + + if (pt->compressed) { + mip1_width = align(minify(pt->width[0]), align_w) + + align(minify(minify(pt->width[0])), align_w); + } else { + mip1_width = align(minify(pt->width[0]), align_w) + + minify(minify(pt->width[0])); + } + + if (mip1_width > tex->pitch) { + tex->pitch = mip1_width; + } + } + + /* Pitch must be a whole number of dwords, even though we + * express it in texels. + */ + tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp; + tex->total_height = 0; + + for (level = 0; level <= pt->last_level; level++) { + unsigned img_height; + + intel_miptree_set_level_info(tex, level, 1, x, y, width, + height, 1); + + if (pt->compressed) + img_height = MAX2(1, height/4); + else + img_height = align(height, align_h); + + + /* Because the images are packed better, the final offset + * might not be the maximal one: + */ + tex->total_height = MAX2(tex->total_height, y + img_height); + + /* Layout_below: step right after second mipmap. + */ + if (level == 1) { + x += align(width, align_w); + } + else { + y += img_height; + } + + width = minify(width); + height = minify(height); + } +} + +static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture *tex) +{ + struct pipe_texture *pt = &tex->base; + /* XXX: these vary depending on image format: + */ +/* int align_w = 4; */ + + switch (pt->target) { + case PIPE_TEXTURE_CUBE: + case PIPE_TEXTURE_3D: { + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; + unsigned pack_x_pitch, pack_x_nr; + unsigned pack_y_pitch; + unsigned level; + unsigned align_h = 2; + unsigned align_w = 4; + + tex->total_height = 0; +#if 0 + if (pt->compressed) { + align_w = intel_compressed_alignment(pt->internal_format); + pt->pitch = align(width, align_w); + pack_y_pitch = (height + 3) / 4; + } else +#endif + { + tex->pitch = align(pt->width[0] * pt->cpp, 4) / pt->cpp; + pack_y_pitch = align(pt->height[0], align_h); + } + + pack_x_pitch = tex->pitch; + pack_x_nr = 1; + + for (level = 0; level <= pt->last_level; level++) { + unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6; + int x = 0; + int y = 0; + uint q, j; + + intel_miptree_set_level_info(tex, level, nr_images, + 0, tex->total_height, + width, height, depth); + + for (q = 0; q < nr_images;) { + for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { + intel_miptree_set_image_offset(tex, level, q, x, y); + x += pack_x_pitch; + } + + x = 0; + y += pack_y_pitch; + } + + + tex->total_height += y; + width = minify(width); + height = minify(height); + depth = minify(depth); + + if (pt->compressed) { + pack_y_pitch = (height + 3) / 4; + + if (pack_x_pitch > align(width, align_w)) { + pack_x_pitch = align(width, align_w); + pack_x_nr <<= 1; + } + } else { + if (pack_x_pitch > 4) { + pack_x_pitch >>= 1; + pack_x_nr <<= 1; + assert(pack_x_pitch * pack_x_nr <= tex->pitch); + } + + if (pack_y_pitch > 2) { + pack_y_pitch >>= 1; + pack_y_pitch = align(pack_y_pitch, align_h); + } + } + + } + break; + } + + default: + i945_miptree_layout_2d(tex); + break; + } +#if 0 + PRINT("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, + pt->pitch, + pt->total_height, + pt->cpp, + pt->pitch * pt->total_height * pt->cpp ); +#endif + + return TRUE; +} + + +struct pipe_texture * +brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) +{ + struct brw_texture *tex = CALLOC_STRUCT(brw_texture); + + if (tex) { + tex->base = *templat; + + if (brw_miptree_layout(pipe, tex)) + tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64, + PIPE_BUFFER_USAGE_PIXEL, + tex->pitch * tex->base.cpp * + tex->total_height); + + if (!tex->buffer) { + FREE(tex); + return NULL; + } + } + + return &tex->base; +} + +void +brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + if (!*pt) + return; + + /* + DBG("%s %p refcount will be %d\n", + __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); + */ + if (--(*pt)->refcount <= 0) { + struct brw_texture *tex = (struct brw_texture *)*pt; + uint i; + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); + */ + + pipe_buffer_reference(pipe->winsys, &tex->buffer, NULL); + + for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++) + if (tex->image_offset[i]) + free(tex->image_offset[i]); + + free(tex); + } + *pt = NULL; +} diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.h b/src/gallium/drivers/i965simple/brw_tex_layout.h new file mode 100644 index 0000000000..cfd6b1ef3a --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_tex_layout.h @@ -0,0 +1,15 @@ +#ifndef BRW_TEX_LAYOUT_H +#define BRW_TEX_LAYOUT_H + +#include "pipe/p_compiler.h" + +struct pipe_context; +struct pipe_texture; + +extern struct pipe_texture * +brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat); + +extern void +brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); + +#endif diff --git a/src/gallium/drivers/i965simple/brw_urb.c b/src/gallium/drivers/i965simple/brw_urb.c new file mode 100644 index 0000000000..101a4367b9 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_urb.c @@ -0,0 +1,186 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_context.h" +//#include "brw_state.h" +#include "brw_batch.h" +#include "brw_defines.h" + +#define VS 0 +#define GS 1 +#define CLP 2 +#define SF 3 +#define CS 4 + +/* XXX: Are the min_entry_size numbers useful? + * XXX: Verify min_nr_entries, esp for VS. + * XXX: Verify SF min_entry_size. + */ +static const struct { + unsigned min_nr_entries; + unsigned preferred_nr_entries; + unsigned min_entry_size; + unsigned max_entry_size; +} limits[CS+1] = { + { 8, 32, 1, 5 }, /* vs */ + { 4, 8, 1, 5 }, /* gs */ + { 6, 8, 1, 5 }, /* clp */ + { 1, 8, 1, 12 }, /* sf */ + { 1, 4, 1, 32 } /* cs */ +}; + + +static boolean check_urb_layout( struct brw_context *brw ) +{ + brw->urb.vs_start = 0; + brw->urb.gs_start = brw->urb.nr_vs_entries * brw->urb.vsize; + brw->urb.clip_start = brw->urb.gs_start + brw->urb.nr_gs_entries * brw->urb.vsize; + brw->urb.sf_start = brw->urb.clip_start + brw->urb.nr_clip_entries * brw->urb.vsize; + brw->urb.cs_start = brw->urb.sf_start + brw->urb.nr_sf_entries * brw->urb.sfsize; + + return brw->urb.cs_start + brw->urb.nr_cs_entries * brw->urb.csize <= 256; +} + +/* Most minimal update, forces re-emit of URB fence packet after GS + * unit turned on/off. + */ +static void recalculate_urb_fence( struct brw_context *brw ) +{ + unsigned csize = brw->curbe.total_size; + unsigned vsize = brw->vs.prog_data->urb_entry_size; + unsigned sfsize = brw->sf.prog_data->urb_entry_size; + + if (csize < limits[CS].min_entry_size) + csize = limits[CS].min_entry_size; + + if (vsize < limits[VS].min_entry_size) + vsize = limits[VS].min_entry_size; + + if (sfsize < limits[SF].min_entry_size) + sfsize = limits[SF].min_entry_size; + + if (brw->urb.vsize < vsize || + brw->urb.sfsize < sfsize || + brw->urb.csize < csize || + (brw->urb.constrained && (brw->urb.vsize > brw->urb.vsize || + brw->urb.sfsize > brw->urb.sfsize || + brw->urb.csize > brw->urb.csize))) { + + + brw->urb.csize = csize; + brw->urb.sfsize = sfsize; + brw->urb.vsize = vsize; + + brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries; + brw->urb.nr_gs_entries = limits[GS].preferred_nr_entries; + brw->urb.nr_clip_entries = limits[CLP].preferred_nr_entries; + brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries; + brw->urb.nr_cs_entries = limits[CS].preferred_nr_entries; + + if (!check_urb_layout(brw)) { + brw->urb.nr_vs_entries = limits[VS].min_nr_entries; + brw->urb.nr_gs_entries = limits[GS].min_nr_entries; + brw->urb.nr_clip_entries = limits[CLP].min_nr_entries; + brw->urb.nr_sf_entries = limits[SF].min_nr_entries; + brw->urb.nr_cs_entries = limits[CS].min_nr_entries; + + brw->urb.constrained = 1; + + if (!check_urb_layout(brw)) { + /* This is impossible, given the maximal sizes of urb + * entries and the values for minimum nr of entries + * provided above. + */ + debug_printf("couldn't calculate URB layout!\n"); + exit(1); + } + + if (BRW_DEBUG & (DEBUG_URB|DEBUG_FALLBACKS)) + debug_printf("URB CONSTRAINED\n"); + } + else + brw->urb.constrained = 0; + + if (BRW_DEBUG & DEBUG_URB) + debug_printf("URB fence: %d ..VS.. %d ..GS.. %d ..CLP.. %d ..SF.. %d ..CS.. %d\n", + brw->urb.vs_start, + brw->urb.gs_start, + brw->urb.clip_start, + brw->urb.sf_start, + brw->urb.cs_start, + 256); + + brw->state.dirty.brw |= BRW_NEW_URB_FENCE; + } +} + + +const struct brw_tracked_state brw_recalculate_urb_fence = { + .dirty = { + .brw = BRW_NEW_CURBE_OFFSETS, + .cache = (CACHE_NEW_VS_PROG | + CACHE_NEW_SF_PROG) + }, + .update = recalculate_urb_fence +}; + + + + + +void brw_upload_urb_fence(struct brw_context *brw) +{ + struct brw_urb_fence uf; + memset(&uf, 0, sizeof(uf)); + + uf.header.opcode = CMD_URB_FENCE; + uf.header.length = sizeof(uf)/4-2; + uf.header.vs_realloc = 1; + uf.header.gs_realloc = 1; + uf.header.clp_realloc = 1; + uf.header.sf_realloc = 1; + uf.header.vfe_realloc = 1; + uf.header.cs_realloc = 1; + + /* The ordering below is correct, not the layout in the + * instruction. + * + * There are 256 urb reg pairs in total. + */ + uf.bits0.vs_fence = brw->urb.gs_start; + uf.bits0.gs_fence = brw->urb.clip_start; + uf.bits0.clp_fence = brw->urb.sf_start; + uf.bits1.sf_fence = brw->urb.cs_start; + uf.bits1.cs_fence = 256; + + BRW_BATCH_STRUCT(brw, &uf); +} diff --git a/src/gallium/drivers/i965simple/brw_util.c b/src/gallium/drivers/i965simple/brw_util.c new file mode 100644 index 0000000000..42391d7c8c --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_util.c @@ -0,0 +1,104 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_util.h" +#include "brw_defines.h" + +#include "pipe/p_defines.h" + +unsigned brw_count_bits( unsigned val ) +{ + unsigned i; + for (i = 0; val ; val >>= 1) + if (val & 1) + i++; + return i; +} + + +unsigned brw_translate_blend_equation( int mode ) +{ + switch (mode) { + case PIPE_BLEND_ADD: + return BRW_BLENDFUNCTION_ADD; + case PIPE_BLEND_MIN: + return BRW_BLENDFUNCTION_MIN; + case PIPE_BLEND_MAX: + return BRW_BLENDFUNCTION_MAX; + case PIPE_BLEND_SUBTRACT: + return BRW_BLENDFUNCTION_SUBTRACT; + case PIPE_BLEND_REVERSE_SUBTRACT: + return BRW_BLENDFUNCTION_REVERSE_SUBTRACT; + default: + assert(0); + return BRW_BLENDFUNCTION_ADD; + } +} + +unsigned brw_translate_blend_factor( int factor ) +{ + switch(factor) { + case PIPE_BLENDFACTOR_ZERO: + return BRW_BLENDFACTOR_ZERO; + case PIPE_BLENDFACTOR_SRC_ALPHA: + return BRW_BLENDFACTOR_SRC_ALPHA; + case PIPE_BLENDFACTOR_ONE: + return BRW_BLENDFACTOR_ONE; + case PIPE_BLENDFACTOR_SRC_COLOR: + return BRW_BLENDFACTOR_SRC_COLOR; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + return BRW_BLENDFACTOR_INV_SRC_COLOR; + case PIPE_BLENDFACTOR_DST_COLOR: + return BRW_BLENDFACTOR_DST_COLOR; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + return BRW_BLENDFACTOR_INV_DST_COLOR; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + return BRW_BLENDFACTOR_INV_SRC_ALPHA; + case PIPE_BLENDFACTOR_DST_ALPHA: + return BRW_BLENDFACTOR_DST_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + return BRW_BLENDFACTOR_INV_DST_ALPHA; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + return BRW_BLENDFACTOR_SRC_ALPHA_SATURATE; + case PIPE_BLENDFACTOR_CONST_COLOR: + return BRW_BLENDFACTOR_CONST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + return BRW_BLENDFACTOR_INV_CONST_COLOR; + case PIPE_BLENDFACTOR_CONST_ALPHA: + return BRW_BLENDFACTOR_CONST_ALPHA; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + return BRW_BLENDFACTOR_INV_CONST_ALPHA; + default: + assert(0); + return BRW_BLENDFACTOR_ZERO; + } +} diff --git a/src/gallium/drivers/i965simple/brw_util.h b/src/gallium/drivers/i965simple/brw_util.h new file mode 100644 index 0000000000..d60e5934db --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_util.h @@ -0,0 +1,43 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRW_UTIL_H +#define BRW_UTIL_H + +#include "pipe/p_state.h" + +extern unsigned brw_count_bits( unsigned val ); +extern unsigned brw_translate_blend_factor( int factor ); +extern unsigned brw_translate_blend_equation( int mode ); + + +#endif diff --git a/src/gallium/drivers/i965simple/brw_vs.c b/src/gallium/drivers/i965simple/brw_vs.c new file mode 100644 index 0000000000..738c6346d5 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_vs.c @@ -0,0 +1,120 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_context.h" +#include "brw_vs.h" +#include "brw_util.h" +#include "brw_state.h" + + +static void do_vs_prog( struct brw_context *brw, + const struct brw_vertex_program *vp, + struct brw_vs_prog_key *key ) +{ + unsigned program_size; + const unsigned *program; + struct brw_vs_compile c; + + memset(&c, 0, sizeof(c)); + memcpy(&c.key, key, sizeof(*key)); + + brw_init_compile(&c.func); + c.vp = vp; + + c.prog_data.outputs_written = vp->program.num_outputs; + c.prog_data.inputs_read = vp->program.num_inputs; + +#if 0 + if (c.key.copy_edgeflag) { + c.prog_data.outputs_written |= 1<vs.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_VS_PROG], + &c.key, + sizeof(c.key), + program, + program_size, + &c.prog_data, + &brw->vs.prog_data); +} + + +static void brw_upload_vs_prog( struct brw_context *brw ) +{ + struct brw_vs_prog_key key; + const struct brw_vertex_program *vp = brw->attribs.VertexProgram; + + assert(vp); + + memset(&key, 0, sizeof(key)); + + /* Just upload the program verbatim for now. Always send it all + * the inputs it asks for, whether they are varying or not. + */ + key.program_string_id = vp->id; + key.nr_userclip = brw->attribs.Clip.nr; + key.copy_edgeflag = (brw->attribs.Raster->fill_cw != PIPE_POLYGON_MODE_FILL || + brw->attribs.Raster->fill_ccw != PIPE_POLYGON_MODE_FILL); + + /* Make an early check for the key. + */ + if (brw_search_cache(&brw->cache[BRW_VS_PROG], + &key, sizeof(key), + &brw->vs.prog_data, + &brw->vs.prog_gs_offset)) + return; + + do_vs_prog(brw, vp, &key); +} + + +/* See brw_vs.c: + */ +const struct brw_tracked_state brw_vs_prog = { + .dirty = { + .brw = BRW_NEW_VS, + .cache = 0 + }, + .update = brw_upload_vs_prog +}; diff --git a/src/gallium/drivers/i965simple/brw_vs.h b/src/gallium/drivers/i965simple/brw_vs.h new file mode 100644 index 0000000000..0e58f043b0 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_vs.h @@ -0,0 +1,82 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRW_VS_H +#define BRW_VS_H + + +#include "brw_context.h" +#include "brw_eu.h" + + +struct brw_vs_prog_key { + unsigned program_string_id; + unsigned nr_userclip:4; + unsigned copy_edgeflag:1; + unsigned know_w_is_one:1; + unsigned pad:26; +}; + + +struct brw_vs_compile { + struct brw_compile func; + struct brw_vs_prog_key key; + struct brw_vs_prog_data prog_data; + + struct brw_vertex_program *vp; + + unsigned nr_inputs; + + unsigned first_output; + unsigned nr_outputs; + + unsigned first_tmp; + unsigned last_tmp; + + struct brw_reg r0; + struct brw_reg r1; + struct brw_reg regs[12][128]; + struct brw_reg tmp; + struct brw_reg stack; + + struct { + boolean used_in_src; + struct brw_reg reg; + } output_regs[128]; + + struct brw_reg userplane[6]; + +}; + +void brw_vs_emit( struct brw_vs_compile *c ); + +#endif diff --git a/src/gallium/drivers/i965simple/brw_vs_emit.c b/src/gallium/drivers/i965simple/brw_vs_emit.c new file mode 100644 index 0000000000..98915ba101 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_vs_emit.c @@ -0,0 +1,1332 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_context.h" +#include "brw_vs.h" + +#include "pipe/p_shader_tokens.h" +#include "pipe/tgsi/util/tgsi_parse.h" + +struct brw_prog_info { + unsigned num_temps; + unsigned num_addrs; + unsigned num_consts; + + unsigned writes_psize; + + unsigned pos_idx; + unsigned result_edge_idx; + unsigned edge_flag_idx; + unsigned psize_idx; +}; + +/* Do things as simply as possible. Allocate and populate all regs + * ahead of time. + */ +static void brw_vs_alloc_regs( struct brw_vs_compile *c, + struct brw_prog_info *info ) +{ + unsigned i, reg = 0, mrf; + unsigned nr_params; + + /* r0 -- reserved as usual + */ + c->r0 = brw_vec8_grf(reg, 0); reg++; + + /* User clip planes from curbe: + */ + if (c->key.nr_userclip) { + for (i = 0; i < c->key.nr_userclip; i++) { + c->userplane[i] = stride( brw_vec4_grf(reg+3+i/2, (i%2) * 4), 0, 4, 1); + } + + /* Deal with curbe alignment: + */ + reg += ((6+c->key.nr_userclip+3)/4)*2; + } + + /* Vertex program parameters from curbe: + */ + nr_params = c->prog_data.max_const; + for (i = 0; i < nr_params; i++) { + c->regs[TGSI_FILE_CONSTANT][i] = stride(brw_vec4_grf(reg+i/2, (i%2) * 4), 0, 4, 1); + } + reg += (nr_params+1)/2; + c->prog_data.curb_read_length = reg - 1; + + + + /* Allocate input regs: + */ + c->nr_inputs = c->vp->program.num_inputs; + for (i = 0; i < c->nr_inputs; i++) { + c->regs[TGSI_FILE_INPUT][i] = brw_vec8_grf(reg, 0); + reg++; + } + + + /* Allocate outputs: TODO: could organize the non-position outputs + * to go straight into message regs. + */ + c->nr_outputs = 0; + c->first_output = reg; + mrf = 4; + for (i = 0; i < c->vp->program.num_outputs; i++) { + c->nr_outputs++; +#if 0 + if (i == VERT_RESULT_HPOS) { + c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0); + reg++; + } + else if (i == VERT_RESULT_PSIZ) { + c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0); + reg++; + mrf++; /* just a placeholder? XXX fix later stages & remove this */ + } + else { + c->regs[TGSI_FILE_OUTPUT][i] = brw_message_reg(mrf); + mrf++; + } +#else + /*treat pos differently for now */ + if (i == info->pos_idx) { + c->regs[TGSI_FILE_OUTPUT][i] = brw_vec8_grf(reg, 0); + reg++; + } else { + c->regs[TGSI_FILE_OUTPUT][i] = brw_message_reg(mrf); + mrf++; + } +#endif + } + + /* Allocate program temporaries: + */ + for (i = 0; i < info->num_temps; i++) { + c->regs[TGSI_FILE_TEMPORARY][i] = brw_vec8_grf(reg, 0); + reg++; + } + + /* Address reg(s). Don't try to use the internal address reg until + * deref time. + */ + for (i = 0; i < info->num_addrs; i++) { + c->regs[TGSI_FILE_ADDRESS][i] = brw_reg(BRW_GENERAL_REGISTER_FILE, + reg, + 0, + BRW_REGISTER_TYPE_D, + BRW_VERTICAL_STRIDE_8, + BRW_WIDTH_8, + BRW_HORIZONTAL_STRIDE_1, + BRW_SWIZZLE_XXXX, + TGSI_WRITEMASK_X); + reg++; + } + + for (i = 0; i < 128; i++) { + if (c->output_regs[i].used_in_src) { + c->output_regs[i].reg = brw_vec8_grf(reg, 0); + reg++; + } + } + + c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0); + reg += 2; + + + /* Some opcodes need an internal temporary: + */ + c->first_tmp = reg; + c->last_tmp = reg; /* for allocation purposes */ + + /* Each input reg holds data from two vertices. The + * urb_read_length is the number of registers read from *each* + * vertex urb, so is half the amount: + */ + c->prog_data.urb_read_length = (c->nr_inputs+1)/2; + + c->prog_data.urb_entry_size = (c->nr_outputs+2+3)/4; + c->prog_data.total_grf = reg; +} + + +static struct brw_reg get_tmp( struct brw_vs_compile *c ) +{ + struct brw_reg tmp = brw_vec8_grf(c->last_tmp, 0); + + if (++c->last_tmp > c->prog_data.total_grf) + c->prog_data.total_grf = c->last_tmp; + + return tmp; +} + +static void release_tmp( struct brw_vs_compile *c, struct brw_reg tmp ) +{ + if (tmp.nr == c->last_tmp-1) + c->last_tmp--; +} + +static void release_tmps( struct brw_vs_compile *c ) +{ + c->last_tmp = c->first_tmp; +} + + +static void unalias1( struct brw_vs_compile *c, + struct brw_reg dst, + struct brw_reg arg0, + void (*func)( struct brw_vs_compile *, + struct brw_reg, + struct brw_reg )) +{ + if (dst.file == arg0.file && dst.nr == arg0.nr) { + struct brw_compile *p = &c->func; + struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask); + func(c, tmp, arg0); + brw_MOV(p, dst, tmp); + } + else { + func(c, dst, arg0); + } +} + +static void unalias2( struct brw_vs_compile *c, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1, + void (*func)( struct brw_vs_compile *, + struct brw_reg, + struct brw_reg, + struct brw_reg )) +{ + if ((dst.file == arg0.file && dst.nr == arg0.nr) || + (dst.file == arg1.file && dst.nr == arg1.nr)) { + struct brw_compile *p = &c->func; + struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask); + func(c, tmp, arg0, arg1); + brw_MOV(p, dst, tmp); + } + else { + func(c, dst, arg0, arg1); + } +} + +static void emit_sop( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1, + unsigned cond) +{ + brw_push_insn_state(p); + brw_CMP(p, brw_null_reg(), cond, arg0, arg1); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_MOV(p, dst, brw_imm_f(1.0f)); + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + brw_MOV(p, dst, brw_imm_f(0.0f)); + brw_pop_insn_state(p); +} + +static void emit_seq( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_EQ); +} + +static void emit_sne( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_NEQ); +} +static void emit_slt( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L); +} + +static void emit_sle( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_LE); +} + +static void emit_sgt( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_G); +} + +static void emit_sge( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_GE); +} + +static void emit_max( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, arg1); + brw_SEL(p, dst, arg1, arg0); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); +} + +static void emit_min( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1 ) +{ + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, arg1); + brw_SEL(p, dst, arg0, arg1); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); +} + + +static void emit_math1( struct brw_vs_compile *c, + unsigned function, + struct brw_reg dst, + struct brw_reg arg0, + unsigned precision) +{ + /* There are various odd behaviours with SEND on the simulator. In + * addition there are documented issues with the fact that the GEN4 + * processor doesn't do dependency control properly on SEND + * results. So, on balance, this kludge to get around failures + * with writemasked math results looks like it might be necessary + * whether that turns out to be a simulator bug or not: + */ + struct brw_compile *p = &c->func; + struct brw_reg tmp = dst; + boolean need_tmp = (dst.dw1.bits.writemask != 0xf || + dst.file != BRW_GENERAL_REGISTER_FILE); + + if (need_tmp) + tmp = get_tmp(c); + + brw_math(p, + tmp, + function, + BRW_MATH_SATURATE_NONE, + 2, + arg0, + BRW_MATH_DATA_SCALAR, + precision); + + if (need_tmp) { + brw_MOV(p, dst, tmp); + release_tmp(c, tmp); + } +} + +static void emit_math2( struct brw_vs_compile *c, + unsigned function, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1, + unsigned precision) +{ + struct brw_compile *p = &c->func; + struct brw_reg tmp = dst; + boolean need_tmp = (dst.dw1.bits.writemask != 0xf || + dst.file != BRW_GENERAL_REGISTER_FILE); + + if (need_tmp) + tmp = get_tmp(c); + + brw_MOV(p, brw_message_reg(3), arg1); + + brw_math(p, + tmp, + function, + BRW_MATH_SATURATE_NONE, + 2, + arg0, + BRW_MATH_DATA_SCALAR, + precision); + + if (need_tmp) { + brw_MOV(p, dst, tmp); + release_tmp(c, tmp); + } +} + + + +static void emit_exp_noalias( struct brw_vs_compile *c, + struct brw_reg dst, + struct brw_reg arg0 ) +{ + struct brw_compile *p = &c->func; + + + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_X) { + struct brw_reg tmp = get_tmp(c); + struct brw_reg tmp_d = retype(tmp, BRW_REGISTER_TYPE_D); + + /* tmp_d = floor(arg0.x) */ + brw_RNDD(p, tmp_d, brw_swizzle1(arg0, 0)); + + /* result[0] = 2.0 ^ tmp */ + + /* Adjust exponent for floating point: + * exp += 127 + */ + brw_ADD(p, brw_writemask(tmp_d, TGSI_WRITEMASK_X), tmp_d, brw_imm_d(127)); + + /* Install exponent and sign. + * Excess drops off the edge: + */ + brw_SHL(p, brw_writemask(retype(dst, BRW_REGISTER_TYPE_D), TGSI_WRITEMASK_X), + tmp_d, brw_imm_d(23)); + + release_tmp(c, tmp); + } + + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_Y) { + /* result[1] = arg0.x - floor(arg0.x) */ + brw_FRC(p, brw_writemask(dst, TGSI_WRITEMASK_Y), brw_swizzle1(arg0, 0)); + } + + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_Z) { + /* As with the LOG instruction, we might be better off just + * doing a taylor expansion here, seeing as we have to do all + * the prep work. + * + * If mathbox partial precision is too low, consider also: + * result[3] = result[0] * EXP(result[1]) + */ + emit_math1(c, + BRW_MATH_FUNCTION_EXP, + brw_writemask(dst, TGSI_WRITEMASK_Z), + brw_swizzle1(arg0, 0), + BRW_MATH_PRECISION_PARTIAL); + } + + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_W) { + /* result[3] = 1.0; */ + brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_W), brw_imm_f(1)); + } +} + + +static void emit_log_noalias( struct brw_vs_compile *c, + struct brw_reg dst, + struct brw_reg arg0 ) +{ + struct brw_compile *p = &c->func; + struct brw_reg tmp = dst; + struct brw_reg tmp_ud = retype(tmp, BRW_REGISTER_TYPE_UD); + struct brw_reg arg0_ud = retype(arg0, BRW_REGISTER_TYPE_UD); + boolean need_tmp = (dst.dw1.bits.writemask != 0xf || + dst.file != BRW_GENERAL_REGISTER_FILE); + + if (need_tmp) { + tmp = get_tmp(c); + tmp_ud = retype(tmp, BRW_REGISTER_TYPE_UD); + } + + /* Perform mant = frexpf(fabsf(x), &exp), adjust exp and mnt + * according to spec: + * + * These almost look likey they could be joined up, but not really + * practical: + * + * result[0].f = (x.i & ((1<<31)-1) >> 23) - 127 + * result[1].i = (x.i & ((1<<23)-1) + (127<<23) + */ + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_XZ) { + brw_AND(p, + brw_writemask(tmp_ud, TGSI_WRITEMASK_X), + brw_swizzle1(arg0_ud, 0), + brw_imm_ud((1U<<31)-1)); + + brw_SHR(p, + brw_writemask(tmp_ud, TGSI_WRITEMASK_X), + tmp_ud, + brw_imm_ud(23)); + + brw_ADD(p, + brw_writemask(tmp, TGSI_WRITEMASK_X), + retype(tmp_ud, BRW_REGISTER_TYPE_D), /* does it matter? */ + brw_imm_d(-127)); + } + + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_YZ) { + brw_AND(p, + brw_writemask(tmp_ud, TGSI_WRITEMASK_Y), + brw_swizzle1(arg0_ud, 0), + brw_imm_ud((1<<23)-1)); + + brw_OR(p, + brw_writemask(tmp_ud, TGSI_WRITEMASK_Y), + tmp_ud, + brw_imm_ud(127<<23)); + } + + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_Z) { + /* result[2] = result[0] + LOG2(result[1]); */ + + /* Why bother? The above is just a hint how to do this with a + * taylor series. Maybe we *should* use a taylor series as by + * the time all the above has been done it's almost certainly + * quicker than calling the mathbox, even with low precision. + * + * Options are: + * - result[0] + mathbox.LOG2(result[1]) + * - mathbox.LOG2(arg0.x) + * - result[0] + inline_taylor_approx(result[1]) + */ + emit_math1(c, + BRW_MATH_FUNCTION_LOG, + brw_writemask(tmp, TGSI_WRITEMASK_Z), + brw_swizzle1(tmp, 1), + BRW_MATH_PRECISION_FULL); + + brw_ADD(p, + brw_writemask(tmp, TGSI_WRITEMASK_Z), + brw_swizzle1(tmp, 2), + brw_swizzle1(tmp, 0)); + } + + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_W) { + /* result[3] = 1.0; */ + brw_MOV(p, brw_writemask(tmp, TGSI_WRITEMASK_W), brw_imm_f(1)); + } + + if (need_tmp) { + brw_MOV(p, dst, tmp); + release_tmp(c, tmp); + } +} + + + + +/* Need to unalias - consider swizzles: r0 = DST r0.xxxx r1 + */ +static void emit_dst_noalias( struct brw_vs_compile *c, + struct brw_reg dst, + struct brw_reg arg0, + struct brw_reg arg1) +{ + struct brw_compile *p = &c->func; + + /* There must be a better way to do this: + */ + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_X) + brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_X), brw_imm_f(1.0)); + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_Y) + brw_MUL(p, brw_writemask(dst, TGSI_WRITEMASK_Y), arg0, arg1); + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_Z) + brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_Z), arg0); + if (dst.dw1.bits.writemask & TGSI_WRITEMASK_W) + brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_W), arg1); +} + +static void emit_xpd( struct brw_compile *p, + struct brw_reg dst, + struct brw_reg t, + struct brw_reg u) +{ + brw_MUL(p, brw_null_reg(), brw_swizzle(t, 1,2,0,3), brw_swizzle(u,2,0,1,3)); + brw_MAC(p, dst, negate(brw_swizzle(t, 2,0,1,3)), brw_swizzle(u,1,2,0,3)); +} + + + +static void emit_lit_noalias( struct brw_vs_compile *c, + struct brw_reg dst, + struct brw_reg arg0 ) +{ + struct brw_compile *p = &c->func; + struct brw_instruction *if_insn; + struct brw_reg tmp = dst; + boolean need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE); + + if (need_tmp) + tmp = get_tmp(c); + + brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_YZ), brw_imm_f(0)); + brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_XW), brw_imm_f(1)); + + /* Need to use BRW_EXECUTE_8 and also do an 8-wide compare in order + * to get all channels active inside the IF. In the clipping code + * we run with NoMask, so it's not an option and we can use + * BRW_EXECUTE_1 for all comparisions. + */ + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, brw_swizzle1(arg0,0), brw_imm_f(0)); + if_insn = brw_IF(p, BRW_EXECUTE_8); + { + brw_MOV(p, brw_writemask(dst, TGSI_WRITEMASK_Y), brw_swizzle1(arg0,0)); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, brw_swizzle1(arg0,1), brw_imm_f(0)); + brw_MOV(p, brw_writemask(tmp, TGSI_WRITEMASK_Z), brw_swizzle1(arg0,1)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + emit_math2(c, + BRW_MATH_FUNCTION_POW, + brw_writemask(dst, TGSI_WRITEMASK_Z), + brw_swizzle1(tmp, 2), + brw_swizzle1(arg0, 3), + BRW_MATH_PRECISION_PARTIAL); + } + + brw_ENDIF(p, if_insn); +} + + + + + +/* TODO: relative addressing! + */ +static struct brw_reg get_reg( struct brw_vs_compile *c, + unsigned file, + unsigned index ) +{ + switch (file) { + case TGSI_FILE_TEMPORARY: + case TGSI_FILE_INPUT: + case TGSI_FILE_OUTPUT: + assert(c->regs[file][index].nr != 0); + return c->regs[file][index]; + case TGSI_FILE_CONSTANT: + assert(c->regs[TGSI_FILE_CONSTANT][index + c->prog_data.num_imm].nr != 0); + return c->regs[TGSI_FILE_CONSTANT][index + c->prog_data.num_imm]; + case TGSI_FILE_IMMEDIATE: + assert(c->regs[TGSI_FILE_CONSTANT][index].nr != 0); + return c->regs[TGSI_FILE_CONSTANT][index]; + case TGSI_FILE_ADDRESS: + assert(index == 0); + return c->regs[file][index]; + + case TGSI_FILE_NULL: /* undef values */ + return brw_null_reg(); + + default: + assert(0); + return brw_null_reg(); + } +} + + + +static struct brw_reg deref( struct brw_vs_compile *c, + struct brw_reg arg, + int offset) +{ + struct brw_compile *p = &c->func; + struct brw_reg tmp = vec4(get_tmp(c)); + struct brw_reg vp_address = retype(vec1(get_reg(c, TGSI_FILE_ADDRESS, 0)), BRW_REGISTER_TYPE_UW); + unsigned byte_offset = arg.nr * 32 + arg.subnr + offset * 16; + struct brw_reg indirect = brw_vec4_indirect(0,0); + + { + brw_push_insn_state(p); + brw_set_access_mode(p, BRW_ALIGN_1); + + /* This is pretty clunky - load the address register twice and + * fetch each 4-dword value in turn. There must be a way to do + * this in a single pass, but I couldn't get it to work. + */ + brw_ADD(p, brw_address_reg(0), vp_address, brw_imm_d(byte_offset)); + brw_MOV(p, tmp, indirect); + + brw_ADD(p, brw_address_reg(0), suboffset(vp_address, 8), brw_imm_d(byte_offset)); + brw_MOV(p, suboffset(tmp, 4), indirect); + + brw_pop_insn_state(p); + } + + return vec8(tmp); +} + + +static void emit_arl( struct brw_vs_compile *c, + struct brw_reg dst, + struct brw_reg arg0 ) +{ + struct brw_compile *p = &c->func; + struct brw_reg tmp = dst; + boolean need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE); + + if (need_tmp) + tmp = get_tmp(c); + + brw_RNDD(p, tmp, arg0); + brw_MUL(p, dst, tmp, brw_imm_d(16)); + + if (need_tmp) + release_tmp(c, tmp); +} + + +/* Will return mangled results for SWZ op. The emit_swz() function + * ignores this result and recalculates taking extended swizzles into + * account. + */ +static struct brw_reg get_arg( struct brw_vs_compile *c, + struct tgsi_src_register *src ) +{ + struct brw_reg reg; + + if (src->File == TGSI_FILE_NULL) + return brw_null_reg(); + +#if 0 + if (src->RelAddr) + reg = deref(c, c->regs[PROGRAM_STATE_VAR][0], src->Index); + else +#endif + reg = get_reg(c, src->File, src->Index); + + /* Convert 3-bit swizzle to 2-bit. + */ + reg.dw1.bits.swizzle = BRW_SWIZZLE4(src->SwizzleX, + src->SwizzleY, + src->SwizzleZ, + src->SwizzleW); + + /* Note this is ok for non-swizzle instructions: + */ + reg.negate = src->Negate ? 1 : 0; + + return reg; +} + + +static struct brw_reg get_dst( struct brw_vs_compile *c, + const struct tgsi_dst_register *dst ) +{ + struct brw_reg reg = get_reg(c, dst->File, dst->Index); + + reg.dw1.bits.writemask = dst->WriteMask; + + return reg; +} + + + + +static void emit_swz( struct brw_vs_compile *c, + struct brw_reg dst, + struct tgsi_src_register src ) +{ + struct brw_compile *p = &c->func; + unsigned zeros_mask = 0; + unsigned ones_mask = 0; + unsigned src_mask = 0; + ubyte src_swz[4]; + boolean need_tmp = (src.Negate && + dst.file != BRW_GENERAL_REGISTER_FILE); + struct brw_reg tmp = dst; + unsigned i; + + if (need_tmp) + tmp = get_tmp(c); + + for (i = 0; i < 4; i++) { + if (dst.dw1.bits.writemask & (1<regs[PROGRAM_STATE_VAR][0], src.Index); + else +#endif + arg0 = get_reg(c, src.File, src.Index); + + arg0 = brw_swizzle(arg0, + src_swz[0], src_swz[1], + src_swz[2], src_swz[3]); + + brw_MOV(p, brw_writemask(tmp, src_mask), arg0); + } + + if (zeros_mask) + brw_MOV(p, brw_writemask(tmp, zeros_mask), brw_imm_f(0)); + + if (ones_mask) + brw_MOV(p, brw_writemask(tmp, ones_mask), brw_imm_f(1)); + + if (src.Negate) + brw_MOV(p, brw_writemask(tmp, src.Negate), negate(tmp)); + + if (need_tmp) { + brw_MOV(p, dst, tmp); + release_tmp(c, tmp); + } +} + + + +/* Post-vertex-program processing. Send the results to the URB. + */ +static void emit_vertex_write( struct brw_vs_compile *c, struct brw_prog_info *info) +{ + struct brw_compile *p = &c->func; + struct brw_reg m0 = brw_message_reg(0); + struct brw_reg pos = c->regs[TGSI_FILE_OUTPUT][info->pos_idx]; + struct brw_reg ndc; + + if (c->key.copy_edgeflag) { + brw_MOV(p, + get_reg(c, TGSI_FILE_OUTPUT, info->result_edge_idx), + get_reg(c, TGSI_FILE_INPUT, info->edge_flag_idx)); + } + + + /* Build ndc coords? TODO: Shortcircuit when w is known to be one. + */ + if (!c->key.know_w_is_one) { + ndc = get_tmp(c); + emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL); + brw_MUL(p, brw_writemask(ndc, TGSI_WRITEMASK_XYZ), pos, ndc); + } + else { + ndc = pos; + } + + /* This includes the workaround for -ve rhw, so is no longer an + * optional step: + */ + if (info->writes_psize || + c->key.nr_userclip || + !c->key.know_w_is_one) + { + struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + unsigned i; + + brw_MOV(p, header1, brw_imm_ud(0)); + + brw_set_access_mode(p, BRW_ALIGN_16); + + if (info->writes_psize) { + struct brw_reg psiz = c->regs[TGSI_FILE_OUTPUT][info->psize_idx]; + brw_MUL(p, brw_writemask(header1, TGSI_WRITEMASK_W), + brw_swizzle1(psiz, 0), brw_imm_f(1<<11)); + brw_AND(p, brw_writemask(header1, TGSI_WRITEMASK_W), header1, + brw_imm_ud(0x7ff<<8)); + } + + + for (i = 0; i < c->key.nr_userclip; i++) { + brw_set_conditionalmod(p, BRW_CONDITIONAL_L); + brw_DP4(p, brw_null_reg(), pos, c->userplane[i]); + brw_OR(p, brw_writemask(header1, TGSI_WRITEMASK_W), header1, brw_imm_ud(1<key.know_w_is_one) { + brw_CMP(p, + vec8(brw_null_reg()), + BRW_CONDITIONAL_L, + brw_swizzle1(ndc, 3), + brw_imm_f(0)); + + brw_OR(p, brw_writemask(header1, TGSI_WRITEMASK_W), header1, brw_imm_ud(1<<6)); + brw_MOV(p, ndc, brw_imm_f(0)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + } + + brw_set_access_mode(p, BRW_ALIGN_1); /* why? */ + brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), header1); + brw_set_access_mode(p, BRW_ALIGN_16); + + release_tmp(c, header1); + } + else { + brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), brw_imm_ud(0)); + } + + + /* Emit the (interleaved) headers for the two vertices - an 8-reg + * of zeros followed by two sets of NDC coordinates: + */ + brw_set_access_mode(p, BRW_ALIGN_1); + brw_MOV(p, offset(m0, 2), ndc); + brw_MOV(p, offset(m0, 3), pos); + + + brw_urb_WRITE(p, + brw_null_reg(), /* dest */ + 0, /* starting mrf reg nr */ + c->r0, /* src */ + 0, /* allocate */ + 1, /* used */ + c->nr_outputs + 3, /* msg len */ + 0, /* response len */ + 1, /* eot */ + 1, /* writes complete */ + 0, /* urb destination offset */ + BRW_URB_SWIZZLE_INTERLEAVE); + +} + +static void +post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst ) +{ + struct tgsi_parse_context parse; + const struct tgsi_token *tokens = c->vp->program.tokens; + tgsi_parse_init(&parse, tokens); + while (!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + if (parse.FullToken.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION) { +#if 0 + struct brw_instruction *brw_inst1, *brw_inst2; + const struct tgsi_full_instruction *inst1, *inst2; + int offset; + inst1 = &parse.FullToken.FullInstruction; + brw_inst1 = inst1->Data; + switch (inst1->Opcode) { + case TGSI_OPCODE_CAL: + case TGSI_OPCODE_BRA: + target_insn = inst1->BranchTarget; + inst2 = &c->vp->program.Base.Instructions[target_insn]; + brw_inst2 = inst2->Data; + offset = brw_inst2 - brw_inst1; + brw_set_src1(brw_inst1, brw_imm_d(offset*16)); + break; + case TGSI_OPCODE_END: + offset = end_inst - brw_inst1; + brw_set_src1(brw_inst1, brw_imm_d(offset*16)); + break; + default: + break; + } +#endif + } + } + tgsi_parse_free(&parse); +} + +static void process_declaration(const struct tgsi_full_declaration *decl, + struct brw_prog_info *info) +{ + int first = decl->u.DeclarationRange.First; + int last = decl->u.DeclarationRange.Last; + + assert (decl->Declaration.Declare != TGSI_DECLARE_MASK); + + switch(decl->Declaration.File) { + case TGSI_FILE_CONSTANT: + info->num_consts += last - first + 1; + break; + case TGSI_FILE_INPUT: { + } + break; + case TGSI_FILE_OUTPUT: { + assert(last == first); /* for now */ + if (decl->Declaration.Semantic) { + switch (decl->Semantic.SemanticName) { + case TGSI_SEMANTIC_POSITION: { + info->pos_idx = first; + } + break; + case TGSI_SEMANTIC_COLOR: + break; + case TGSI_SEMANTIC_BCOLOR: + break; + case TGSI_SEMANTIC_FOG: + break; + case TGSI_SEMANTIC_PSIZE: { + info->writes_psize = TRUE; + info->psize_idx = first; + } + break; + case TGSI_SEMANTIC_GENERIC: + break; + } + } + } + break; + case TGSI_FILE_TEMPORARY: { + info->num_temps += (last - first) + 1; + } + break; + case TGSI_FILE_SAMPLER: { + } + break; + case TGSI_FILE_ADDRESS: { + info->num_addrs += (last - first) + 1; + } + break; + case TGSI_FILE_IMMEDIATE: { + } + break; + case TGSI_FILE_NULL: { + } + break; + } +} + +static void process_instruction(struct brw_vs_compile *c, + struct tgsi_full_instruction *inst, + struct brw_prog_info *info) +{ + struct brw_reg args[3], dst; + struct brw_compile *p = &c->func; + struct brw_indirect stack_index = brw_indirect(0, 0); + unsigned i; + unsigned index; + unsigned file; + /*FIXME: might not be the only one*/ + const struct tgsi_dst_register *dst_reg = &inst->FullDstRegisters[0].DstRegister; + /* + struct brw_instruction *if_inst[MAX_IFSN]; + unsigned insn, if_insn = 0; + */ + + for (i = 0; i < 3; i++) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + index = src->SrcRegister.Index; + file = src->SrcRegister.File; + if (file == TGSI_FILE_OUTPUT && c->output_regs[index].used_in_src) + args[i] = c->output_regs[index].reg; + else + args[i] = get_arg(c, &src->SrcRegister); + } + + /* Get dest regs. Note that it is possible for a reg to be both + * dst and arg, given the static allocation of registers. So + * care needs to be taken emitting multi-operation instructions. + */ + index = dst_reg->Index; + file = dst_reg->File; + if (file == TGSI_FILE_OUTPUT && c->output_regs[index].used_in_src) + dst = c->output_regs[index].reg; + else + dst = get_dst(c, dst_reg); + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ABS: + brw_MOV(p, dst, brw_abs(args[0])); + break; + case TGSI_OPCODE_ADD: + brw_ADD(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_DP3: + brw_DP3(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_DP4: + brw_DP4(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_DPH: + brw_DPH(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_DST: + unalias2(c, dst, args[0], args[1], emit_dst_noalias); + break; + case TGSI_OPCODE_EXP: + unalias1(c, dst, args[0], emit_exp_noalias); + break; + case TGSI_OPCODE_EX2: + emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, args[0], BRW_MATH_PRECISION_FULL); + break; + case TGSI_OPCODE_ARL: + emit_arl(c, dst, args[0]); + break; + case TGSI_OPCODE_FLR: + brw_RNDD(p, dst, args[0]); + break; + case TGSI_OPCODE_FRC: + brw_FRC(p, dst, args[0]); + break; + case TGSI_OPCODE_LOG: + unalias1(c, dst, args[0], emit_log_noalias); + break; + case TGSI_OPCODE_LG2: + emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, args[0], BRW_MATH_PRECISION_FULL); + break; + case TGSI_OPCODE_LIT: + unalias1(c, dst, args[0], emit_lit_noalias); + break; + case TGSI_OPCODE_MAD: + brw_MOV(p, brw_acc_reg(), args[2]); + brw_MAC(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_MAX: + emit_max(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_MIN: + emit_min(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_MOV: +#if 0 + case TGSI_OPCODE_SWZ: + /* The args[0] value can't be used here as it won't have + * correctly encoded the full swizzle: + */ + emit_swz(c, dst, inst->SrcReg[0] ); +#endif + brw_MOV(p, dst, args[0]); + break; + case TGSI_OPCODE_MUL: + brw_MUL(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_POW: + emit_math2(c, BRW_MATH_FUNCTION_POW, dst, args[0], args[1], BRW_MATH_PRECISION_FULL); + break; + case TGSI_OPCODE_RCP: + emit_math1(c, BRW_MATH_FUNCTION_INV, dst, args[0], BRW_MATH_PRECISION_FULL); + break; + case TGSI_OPCODE_RSQ: + emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL); + break; + + case TGSI_OPCODE_SEQ: + emit_seq(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_SNE: + emit_sne(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_SGE: + emit_sge(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_SGT: + emit_sgt(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_SLT: + emit_slt(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_SLE: + emit_sle(p, dst, args[0], args[1]); + break; + case TGSI_OPCODE_SUB: + brw_ADD(p, dst, args[0], negate(args[1])); + break; + case TGSI_OPCODE_XPD: + emit_xpd(p, dst, args[0], args[1]); + break; +#if 0 + case TGSI_OPCODE_IF: + assert(if_insn < MAX_IFSN); + if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8); + break; + case TGSI_OPCODE_ELSE: + if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]); + break; + case TGSI_OPCODE_ENDIF: + assert(if_insn > 0); + brw_ENDIF(p, if_inst[--if_insn]); + break; + case TGSI_OPCODE_BRA: + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); + brw_set_predicate_control_flag_value(p, 0xff); + break; + case TGSI_OPCODE_CAL: + brw_set_access_mode(p, BRW_ALIGN_1); + brw_ADD(p, deref_1uw(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16)); + brw_set_access_mode(p, BRW_ALIGN_16); + brw_ADD(p, get_addr_reg(stack_index), + get_addr_reg(stack_index), brw_imm_d(4)); + inst->Data = &p->store[p->nr_insn]; + brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); + break; +#endif + case TGSI_OPCODE_RET: +#if 0 + brw_ADD(p, get_addr_reg(stack_index), + get_addr_reg(stack_index), brw_imm_d(-4)); + brw_set_access_mode(p, BRW_ALIGN_1); + brw_MOV(p, brw_ip_reg(), deref_1uw(stack_index, 0)); + brw_set_access_mode(p, BRW_ALIGN_16); +#else + /*brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));*/ +#endif + break; + case TGSI_OPCODE_END: + brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); + break; + case TGSI_OPCODE_BGNSUB: + case TGSI_OPCODE_ENDSUB: + break; + default: + debug_printf("Unsupport opcode %d in vertex shader\n", inst->Instruction.Opcode); + break; + } + + if (dst_reg->File == TGSI_FILE_OUTPUT + && dst_reg->Index != info->pos_idx + && c->output_regs[dst_reg->Index].used_in_src) + brw_MOV(p, get_dst(c, dst_reg), dst); + + release_tmps(c); +} + +/* Emit the fragment program instructions here. + */ +void brw_vs_emit(struct brw_vs_compile *c) +{ +#define MAX_IFSN 32 + struct brw_compile *p = &c->func; + struct brw_instruction *end_inst; + struct tgsi_parse_context parse; + struct brw_indirect stack_index = brw_indirect(0, 0); + const struct tgsi_token *tokens = c->vp->program.tokens; + struct brw_prog_info prog_info; + unsigned allocated_registers = 0; + memset(&prog_info, 0, sizeof(struct brw_prog_info)); + + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + brw_set_access_mode(p, BRW_ALIGN_16); + + tgsi_parse_init(&parse, tokens); + /* Message registers can't be read, so copy the output into GRF register + if they are used in source registers */ + while (!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + unsigned i; + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_INSTRUCTION: { + const struct tgsi_full_instruction *inst = &parse.FullToken.FullInstruction; + for (i = 0; i < 3; ++i) { + const struct tgsi_src_register *src = &inst->FullSrcRegisters[i].SrcRegister; + unsigned index = src->Index; + unsigned file = src->File; + if (file == TGSI_FILE_OUTPUT) + c->output_regs[index].used_in_src = TRUE; + } + } + break; + default: + /* nothing */ + break; + } + } + tgsi_parse_free(&parse); + + tgsi_parse_init(&parse, tokens); + + while (!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: { + struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration; + process_declaration(decl, &prog_info); + } + break; + case TGSI_TOKEN_TYPE_IMMEDIATE: { + struct tgsi_full_immediate *imm = &parse.FullToken.FullImmediate; + /*assert(imm->Immediate.Size == 4);*/ + c->prog_data.imm_buf[c->prog_data.num_imm][0] = imm->u.ImmediateFloat32[0].Float; + c->prog_data.imm_buf[c->prog_data.num_imm][1] = imm->u.ImmediateFloat32[1].Float; + c->prog_data.imm_buf[c->prog_data.num_imm][2] = imm->u.ImmediateFloat32[2].Float; + c->prog_data.imm_buf[c->prog_data.num_imm][3] = imm->u.ImmediateFloat32[3].Float; + c->prog_data.num_imm++; + } + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: { + struct tgsi_full_instruction *inst = &parse.FullToken.FullInstruction; + if (!allocated_registers) { + /* first instruction (declerations finished). + * now that we know what vars are being used allocate + * registers for them.*/ + c->prog_data.num_consts = prog_info.num_consts; + c->prog_data.max_const = prog_info.num_consts + c->prog_data.num_imm; + brw_vs_alloc_regs(c, &prog_info); + + brw_set_access_mode(p, BRW_ALIGN_1); + brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack)); + brw_set_access_mode(p, BRW_ALIGN_16); + allocated_registers = 1; + } + process_instruction(c, inst, &prog_info); + } + break; + } + } + + end_inst = &p->store[p->nr_insn]; + emit_vertex_write(c, &prog_info); + post_vs_emit(c, end_inst); + tgsi_parse_free(&parse); + +} diff --git a/src/gallium/drivers/i965simple/brw_vs_state.c b/src/gallium/drivers/i965simple/brw_vs_state.c new file mode 100644 index 0000000000..c73469929c --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_vs_state.c @@ -0,0 +1,102 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" + +#include "pipe/p_util.h" + +static void upload_vs_unit( struct brw_context *brw ) +{ + struct brw_vs_unit_state vs; + + memset(&vs, 0, sizeof(vs)); + + /* CACHE_NEW_VS_PROG */ + vs.thread0.kernel_start_pointer = brw->vs.prog_gs_offset >> 6; + vs.thread0.grf_reg_count = align(brw->vs.prog_data->total_grf, 16) / 16 - 1; + vs.thread3.urb_entry_read_length = brw->vs.prog_data->urb_read_length; + vs.thread3.const_urb_entry_read_length = brw->vs.prog_data->curb_read_length; + vs.thread3.dispatch_grf_start_reg = 1; + + + /* BRW_NEW_URB_FENCE */ + vs.thread4.nr_urb_entries = brw->urb.nr_vs_entries; + vs.thread4.urb_entry_allocation_size = brw->urb.vsize - 1; + vs.thread4.max_threads = MIN2( + MAX2(0, (brw->urb.nr_vs_entries - 6) / 2 - 1), + 15); + + + + if (BRW_DEBUG & DEBUG_SINGLE_THREAD) + vs.thread4.max_threads = 0; + + /* BRW_NEW_CURBE_OFFSETS, _NEW_TRANSFORM */ + if (0 /*brw->attribs.Clip->ClipPlanesEnabled*/) { + /* Note that we read in the userclip planes as well, hence + * clip_start: + */ + vs.thread3.const_urb_entry_read_offset = brw->curbe.clip_start * 2; + } + else { + vs.thread3.const_urb_entry_read_offset = brw->curbe.vs_start * 2; + } + + vs.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; + vs.thread3.urb_entry_read_offset = 0; + + /* No samplers for ARB_vp programs: + */ + vs.vs5.sampler_count = 0; + + if (BRW_DEBUG & DEBUG_STATS) + vs.thread4.stats_enable = 1; + + /* Vertex program always enabled: + */ + vs.vs6.vs_enable = 1; + + brw->vs.state_gs_offset = brw_cache_data( &brw->cache[BRW_VS_UNIT], &vs ); +} + + +const struct brw_tracked_state brw_vs_unit = { + .dirty = { + .brw = (BRW_NEW_CLIP | + BRW_NEW_CURBE_OFFSETS | + BRW_NEW_URB_FENCE), + .cache = CACHE_NEW_VS_PROG + }, + .update = upload_vs_unit +}; diff --git a/src/gallium/drivers/i965simple/brw_winsys.h b/src/gallium/drivers/i965simple/brw_winsys.h new file mode 100644 index 0000000000..3523a58614 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_winsys.h @@ -0,0 +1,205 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * This is the interface that i965simple requires any window system + * hosting it to implement. This is the only include file in i965simple + * which is public. + * + */ + +#ifndef BRW_WINSYS_H +#define BRW_WINSYS_H + + +#include "pipe/p_defines.h" + + +/* Pipe drivers are (meant to be!) independent of both GL and the + * window system. The window system provides a buffer manager and a + * set of additional hooks for things like command buffer submission, + * etc. + * + * There clearly has to be some agreement between the window system + * driver and the hardware driver about the format of command buffers, + * etc. + */ + +struct pipe_buffer; +struct pipe_fence_handle; +struct pipe_winsys; + +/* The pipe driver currently understands the following chipsets: + */ +#define PCI_CHIP_I965_G 0x29A2 +#define PCI_CHIP_I965_Q 0x2992 +#define PCI_CHIP_I965_G_1 0x2982 +#define PCI_CHIP_I965_GM 0x2A02 +#define PCI_CHIP_I965_GME 0x2A12 + + +/* These are the names of all the state caches managed by the driver. + * + * When data is uploaded to a buffer with buffer_subdata, we use the + * special version of that function below so that information about + * what type of data this is can be passed to the winsys backend. + * That in turn allows the correct flags to be set in the aub file + * dump to allow human-readable file dumps later on. + */ + +enum brw_cache_id { + BRW_CC_VP, + BRW_CC_UNIT, + BRW_WM_PROG, + BRW_SAMPLER_DEFAULT_COLOR, + BRW_SAMPLER, + BRW_WM_UNIT, + BRW_SF_PROG, + BRW_SF_VP, + BRW_SF_UNIT, + BRW_VS_UNIT, + BRW_VS_PROG, + BRW_GS_UNIT, + BRW_GS_PROG, + BRW_CLIP_VP, + BRW_CLIP_UNIT, + BRW_CLIP_PROG, + BRW_SS_SURFACE, + BRW_SS_SURF_BIND, + + BRW_MAX_CACHE +}; + +#define BRW_CONSTANT_BUFFER BRW_MAX_CACHE + +/** + * Additional winsys interface for i965simple. + * + * It is an over-simple batchbuffer mechanism. Will want to improve the + * performance of this, perhaps based on the cmdstream stuff. It + * would be pretty impossible to implement swz on top of this + * interface. + * + * Will also need additions/changes to implement static/dynamic + * indirect state. + */ +struct brw_winsys { + + /** + * Reserve space on batch buffer. + * + * Returns a null pointer if there is insufficient space in the batch buffer + * to hold the requested number of dwords and relocations. + * + * The number of dwords should also include the number of relocations. + */ + unsigned *(*batch_start)(struct brw_winsys *sws, + unsigned dwords, + unsigned relocs); + + void (*batch_dword)(struct brw_winsys *sws, + unsigned dword); + + /** + * Emit a relocation to a buffer. + * + * Used not only when the buffer addresses are not pinned, but also to + * ensure refered buffers will not be destroyed until the current batch + * buffer execution is finished. + * + * The access flags is a combination of I915_BUFFER_ACCESS_WRITE and + * I915_BUFFER_ACCESS_READ macros. + */ + void (*batch_reloc)(struct brw_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta); + + + /* Not used yet, but really want this: + */ + void (*batch_end)( struct brw_winsys *sws ); + + /** + * Flush the batch buffer. + * + * Fence argument must point to NULL or to a previous fence, and the caller + * must call fence_reference when done with the fence. + */ + void (*batch_flush)(struct brw_winsys *sws, + struct pipe_fence_handle **fence); + + + /* A version of buffer_subdata that includes information for the + * simulator: + */ + void (*buffer_subdata_typed)(struct brw_winsys *sws, + struct pipe_buffer *buf, + unsigned long offset, + unsigned long size, + const void *data, + unsigned data_type); + + + /* A cheat so we don't have to think about relocations in a couple + * of places yet: + */ + unsigned (*get_buffer_offset)( struct brw_winsys *sws, + struct pipe_buffer *buf, + unsigned flags ); + +}; + +#define BRW_BUFFER_ACCESS_WRITE 0x1 +#define BRW_BUFFER_ACCESS_READ 0x2 + +#define BRW_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0) + + +struct pipe_context *brw_create(struct pipe_winsys *, + struct brw_winsys *, + unsigned pci_id); + +static inline boolean brw_batchbuffer_data(struct brw_winsys *winsys, + const void *data, + unsigned bytes) +{ + static const unsigned incr = sizeof(unsigned); + uint i; + const unsigned *udata = (const unsigned*)(data); + unsigned size = bytes/incr; + + winsys->batch_start(winsys, size, 0); + for (i = 0; i < size; ++i) { + winsys->batch_dword(winsys, udata[i]); + } + winsys->batch_end(winsys); + + return (i == size); +} +#endif diff --git a/src/gallium/drivers/i965simple/brw_wm.c b/src/gallium/drivers/i965simple/brw_wm.c new file mode 100644 index 0000000000..539b170744 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_wm.c @@ -0,0 +1,210 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_context.h" +#include "brw_util.h" +#include "brw_wm.h" +#include "brw_eu.h" +#include "brw_state.h" +#include "pipe/p_util.h" + + + +static void do_wm_prog( struct brw_context *brw, + struct brw_fragment_program *fp, + struct brw_wm_prog_key *key) +{ + struct brw_wm_compile *c = CALLOC_STRUCT(brw_wm_compile); + const unsigned *program; + unsigned program_size; + + c->key = *key; + c->fp = fp; + + c->delta_xy[0] = brw_null_reg(); + c->delta_xy[1] = brw_null_reg(); + c->pixel_xy[0] = brw_null_reg(); + c->pixel_xy[1] = brw_null_reg(); + c->pixel_w = brw_null_reg(); + + + debug_printf("XXXXXXXX FP\n"); + + brw_wm_glsl_emit(c); + + /* get the program + */ + program = brw_get_program(&c->func, &program_size); + + /* + */ + brw->wm.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_WM_PROG], + &c->key, + sizeof(c->key), + program, + program_size, + &c->prog_data, + &brw->wm.prog_data ); + + FREE(c); +} + + + +static void brw_wm_populate_key( struct brw_context *brw, + struct brw_wm_prog_key *key ) +{ + /* BRW_NEW_FRAGMENT_PROGRAM */ + struct brw_fragment_program *fp = + (struct brw_fragment_program *)brw->attribs.FragmentProgram; + unsigned lookup = 0; + unsigned line_aa; + + memset(key, 0, sizeof(*key)); + + /* Build the index for table lookup + */ + /* BRW_NEW_DEPTH_STENCIL */ + if (fp->UsesKill || + brw->attribs.DepthStencil->alpha.enabled) + lookup |= IZ_PS_KILL_ALPHATEST_BIT; + + if (fp->ComputesDepth) + lookup |= IZ_PS_COMPUTES_DEPTH_BIT; + + if (brw->attribs.DepthStencil->depth.enabled) + lookup |= IZ_DEPTH_TEST_ENABLE_BIT; + + if (brw->attribs.DepthStencil->depth.enabled && + brw->attribs.DepthStencil->depth.writemask) /* ?? */ + lookup |= IZ_DEPTH_WRITE_ENABLE_BIT; + + if (brw->attribs.DepthStencil->stencil[0].enabled) { + lookup |= IZ_STENCIL_TEST_ENABLE_BIT; + + if (brw->attribs.DepthStencil->stencil[0].write_mask || + brw->attribs.DepthStencil->stencil[1].write_mask) + lookup |= IZ_STENCIL_WRITE_ENABLE_BIT; + } + + /* XXX: when should this be disabled? + */ + if (1) + lookup |= IZ_EARLY_DEPTH_TEST_BIT; + + + line_aa = AA_NEVER; + + /* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */ + if (brw->attribs.Raster->line_smooth) { + if (brw->reduced_primitive == PIPE_PRIM_LINES) { + line_aa = AA_ALWAYS; + } + else if (brw->reduced_primitive == PIPE_PRIM_TRIANGLES) { + if (brw->attribs.Raster->fill_ccw == PIPE_POLYGON_MODE_LINE) { + line_aa = AA_SOMETIMES; + + if (brw->attribs.Raster->fill_cw == PIPE_POLYGON_MODE_LINE || + (brw->attribs.Raster->cull_mode == PIPE_WINDING_CW)) + line_aa = AA_ALWAYS; + } + else if (brw->attribs.Raster->fill_cw == PIPE_POLYGON_MODE_LINE) { + line_aa = AA_SOMETIMES; + + if (brw->attribs.Raster->cull_mode == PIPE_WINDING_CCW) + line_aa = AA_ALWAYS; + } + } + } + + brw_wm_lookup_iz(line_aa, + lookup, + key); + + +#if 0 + /* BRW_NEW_SAMPLER + * + * Not doing any of this at the moment: + */ + for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { + const struct pipe_sampler_state *unit = brw->attribs.Samplers[i]; + + if (unit) { + + if (unit->compare && + unit->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + key->shadowtex_mask |= 1<Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA) + key->yuvtex_mask |= 1<program_string_id = fp->id; + +} + + +static void brw_upload_wm_prog( struct brw_context *brw ) +{ + struct brw_wm_prog_key key; + struct brw_fragment_program *fp = (struct brw_fragment_program *) + brw->attribs.FragmentProgram; + + brw_wm_populate_key(brw, &key); + + /* Make an early check for the key. + */ + if (brw_search_cache(&brw->cache[BRW_WM_PROG], + &key, sizeof(key), + &brw->wm.prog_data, + &brw->wm.prog_gs_offset)) + return; + + do_wm_prog(brw, fp, &key); +} + + +const struct brw_tracked_state brw_wm_prog = { + .dirty = { + .brw = (BRW_NEW_FS | + BRW_NEW_REDUCED_PRIMITIVE), + .cache = 0 + }, + .update = brw_upload_wm_prog +}; + diff --git a/src/gallium/drivers/i965simple/brw_wm.h b/src/gallium/drivers/i965simple/brw_wm.h new file mode 100644 index 0000000000..a1ac0f504a --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_wm.h @@ -0,0 +1,142 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRW_WM_H +#define BRW_WM_H + + +#include "brw_context.h" +#include "brw_eu.h" + +/* A big lookup table is used to figure out which and how many + * additional regs will inserted before the main payload in the WM + * program execution. These mainly relate to depth and stencil + * processing and the early-depth-test optimization. + */ +#define IZ_PS_KILL_ALPHATEST_BIT 0x1 +#define IZ_PS_COMPUTES_DEPTH_BIT 0x2 +#define IZ_DEPTH_WRITE_ENABLE_BIT 0x4 +#define IZ_DEPTH_TEST_ENABLE_BIT 0x8 +#define IZ_STENCIL_WRITE_ENABLE_BIT 0x10 +#define IZ_STENCIL_TEST_ENABLE_BIT 0x20 +#define IZ_EARLY_DEPTH_TEST_BIT 0x40 +#define IZ_BIT_MAX 0x80 + +#define AA_NEVER 0 +#define AA_SOMETIMES 1 +#define AA_ALWAYS 2 + +struct brw_wm_prog_key { + unsigned source_depth_reg:3; + unsigned aa_dest_stencil_reg:3; + unsigned dest_depth_reg:3; + unsigned nr_depth_regs:3; + unsigned shadowtex_mask:8; + unsigned computes_depth:1; /* could be derived from program string */ + unsigned source_depth_to_render_target:1; + unsigned runtime_check_aads_emit:1; + + unsigned yuvtex_mask:8; + + unsigned program_string_id; +}; + + + + + +#define PROGRAM_INTERNAL_PARAM +#define MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS 1024 /* 72 for GL_ARB_f_p */ +#define BRW_WM_MAX_INSN (MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS*3 + PIPE_ATTRIB_MAX + 3) +#define BRW_WM_MAX_GRF 128 /* hardware limit */ +#define BRW_WM_MAX_VREG (BRW_WM_MAX_INSN * 4) +#define BRW_WM_MAX_REF (BRW_WM_MAX_INSN * 12) +#define BRW_WM_MAX_PARAM 256 +#define BRW_WM_MAX_CONST 256 +#define BRW_WM_MAX_KILLS MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS + +#define PAYLOAD_DEPTH (PIPE_ATTRIB_MAX) + +#define MAX_IFSN 32 +#define MAX_LOOP_DEPTH 32 + +struct brw_wm_compile { + struct brw_compile func; + struct brw_wm_prog_key key; + struct brw_wm_prog_data prog_data; /* result */ + + struct brw_fragment_program *fp; + + unsigned grf_limit; + unsigned max_wm_grf; + + + struct brw_reg pixel_xy[2]; + struct brw_reg delta_xy[2]; + struct brw_reg pixel_w; + + + struct brw_reg wm_regs[8][32][4]; + + struct brw_reg payload_depth[4]; + struct brw_reg payload_coef[16]; + + struct brw_reg emit_mask_reg; + + struct brw_instruction *if_inst[MAX_IFSN]; + int if_insn; + + struct brw_instruction *loop_inst[MAX_LOOP_DEPTH]; + int loop_insn; + + struct brw_instruction *inst0; + struct brw_instruction *inst1; + + struct brw_reg stack; + struct brw_indirect stack_index; + + unsigned reg_index; + + unsigned tmp_start; + unsigned tmp_index; +}; + + + +void brw_wm_lookup_iz( unsigned line_aa, + unsigned lookup, + struct brw_wm_prog_key *key ); + +void brw_wm_glsl_emit(struct brw_wm_compile *c); +void brw_wm_emit_decls(struct brw_wm_compile *c); + +#endif diff --git a/src/gallium/drivers/i965simple/brw_wm_decl.c b/src/gallium/drivers/i965simple/brw_wm_decl.c new file mode 100644 index 0000000000..b45a333a2e --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_wm_decl.c @@ -0,0 +1,383 @@ + +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_wm.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/tgsi/util/tgsi_parse.h" + +static struct brw_reg alloc_tmp(struct brw_wm_compile *c) +{ + c->tmp_index++; + c->reg_index = MAX2(c->reg_index, c->tmp_start + c->tmp_index); + return brw_vec8_grf(c->tmp_start + c->tmp_index, 0); +} + +static void release_tmps(struct brw_wm_compile *c) +{ + c->tmp_index = 0; +} + + + +static int is_null( struct brw_reg reg ) +{ + return (reg.file == BRW_ARCHITECTURE_REGISTER_FILE && + reg.nr == BRW_ARF_NULL); +} + +static void emit_pixel_xy( struct brw_wm_compile *c ) +{ + if (is_null(c->pixel_xy[0])) { + + struct brw_compile *p = &c->func; + struct brw_reg r1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW); + + c->pixel_xy[0] = vec8(retype(alloc_tmp(c), BRW_REGISTER_TYPE_UW)); + c->pixel_xy[1] = vec8(retype(alloc_tmp(c), BRW_REGISTER_TYPE_UW)); + + /* Calculate pixel centers by adding 1 or 0 to each of the + * micro-tile coordinates passed in r1. + */ + brw_ADD(p, + c->pixel_xy[0], + stride(suboffset(r1_uw, 4), 2, 4, 0), + brw_imm_v(0x10101010)); + + brw_ADD(p, + c->pixel_xy[1], + stride(suboffset(r1_uw, 5), 2, 4, 0), + brw_imm_v(0x11001100)); + } +} + + + + + + +static void emit_delta_xy( struct brw_wm_compile *c ) +{ + if (is_null(c->delta_xy[0])) { + struct brw_compile *p = &c->func; + struct brw_reg r1 = brw_vec1_grf(1, 0); + + emit_pixel_xy(c); + + c->delta_xy[0] = alloc_tmp(c); + c->delta_xy[1] = alloc_tmp(c); + + /* Calc delta X,Y by subtracting origin in r1 from the pixel + * centers. + */ + brw_ADD(p, + c->delta_xy[0], + retype(c->pixel_xy[0], BRW_REGISTER_TYPE_UW), + negate(r1)); + + brw_ADD(p, + c->delta_xy[1], + retype(c->pixel_xy[1], BRW_REGISTER_TYPE_UW), + negate(suboffset(r1,1))); + } +} + + + +#if 0 +static void emit_pixel_w( struct brw_wm_compile *c ) +{ + if (is_null(c->pixel_w)) { + struct brw_compile *p = &c->func; + + struct brw_reg interp_wpos = c->coef_wpos; + + c->pixel_w = alloc_tmp(c); + + emit_delta_xy(c); + + /* Calc 1/w - just linterp wpos[3] optimized by putting the + * result straight into a message reg. + */ + struct brw_reg interp3 = brw_vec1_grf(interp_wpos.nr+1, 4); + brw_LINE(p, brw_null_reg(), interp3, c->delta_xy[0]); + brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), c->delta_xy[1]); + + /* Calc w */ + brw_math_16( p, + c->pixel_w, + BRW_MATH_FUNCTION_INV, + BRW_MATH_SATURATE_NONE, + 2, + brw_null_reg(), + BRW_MATH_PRECISION_FULL); + } +} +#endif + + +static void emit_cinterp(struct brw_wm_compile *c, + int idx, + int mask ) +{ + struct brw_compile *p = &c->func; + struct brw_reg interp[4]; + struct brw_reg coef = c->payload_coef[idx]; + int i; + + interp[0] = brw_vec1_grf(coef.nr, 0); + interp[1] = brw_vec1_grf(coef.nr, 4); + interp[2] = brw_vec1_grf(coef.nr+1, 0); + interp[3] = brw_vec1_grf(coef.nr+1, 4); + + for(i = 0; i < 4; i++ ) { + if (mask & (1<wm_regs[TGSI_FILE_INPUT][idx][i]; + brw_MOV(p, dst, suboffset(interp[i],3)); + } + } +} + +static void emit_linterp(struct brw_wm_compile *c, + int idx, + int mask ) +{ + struct brw_compile *p = &c->func; + struct brw_reg interp[4]; + struct brw_reg coef = c->payload_coef[idx]; + int i; + + emit_delta_xy(c); + + interp[0] = brw_vec1_grf(coef.nr, 0); + interp[1] = brw_vec1_grf(coef.nr, 4); + interp[2] = brw_vec1_grf(coef.nr+1, 0); + interp[3] = brw_vec1_grf(coef.nr+1, 4); + + for(i = 0; i < 4; i++ ) { + if (mask & (1<wm_regs[TGSI_FILE_INPUT][idx][i]; + brw_LINE(p, brw_null_reg(), interp[i], c->delta_xy[0]); + brw_MAC(p, dst, suboffset(interp[i],1), c->delta_xy[1]); + } + } +} + +#if 0 +static void emit_pinterp(struct brw_wm_compile *c, + int idx, + int mask ) +{ + struct brw_compile *p = &c->func; + struct brw_reg interp[4]; + struct brw_reg coef = c->payload_coef[idx]; + int i; + + get_delta_xy(c); + get_pixel_w(c); + + interp[0] = brw_vec1_grf(coef.nr, 0); + interp[1] = brw_vec1_grf(coef.nr, 4); + interp[2] = brw_vec1_grf(coef.nr+1, 0); + interp[3] = brw_vec1_grf(coef.nr+1, 4); + + for(i = 0; i < 4; i++ ) { + if (mask & (1<delta_xy[0]); + brw_MAC(p, dst, suboffset(interp[i],1), c->delta_xy[1]); + brw_MUL(p, dst, dst, c->pixel_w); + } + } +} +#endif + + + +#if 0 +static void emit_wpos( ) +{ + struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx); + struct tgsi_full_src_register interp = src_reg(PROGRAM_PAYLOAD, idx); + struct tgsi_full_src_register deltas = get_delta_xy(c); + struct tgsi_full_src_register arg2; + unsigned opcode; + + opcode = WM_LINTERP; + arg2 = src_undef(); + + /* Have to treat wpos.xy specially: + */ + emit_op(c, + WM_WPOSXY, + dst_mask(dst, WRITEMASK_XY), + 0, 0, 0, + get_pixel_xy(c), + src_undef(), + src_undef()); + + dst = dst_mask(dst, WRITEMASK_ZW); + + /* PROGRAM_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw + */ + emit_op(c, + WM_LINTERP, + dst, + 0, 0, 0, + interp, + deltas, + arg2); +} +#endif + + + + +/* Perform register allocation: + * + * -- r0??? + * -- passthrough depth regs (and stencil/aa??) + * -- curbe ?? + * -- inputs (coefficients) + * + * Use a totally static register allocation. This will perform poorly + * but is an easy way to get started (again). + */ +static void prealloc_reg(struct brw_wm_compile *c) +{ + int i, j; + int nr_curbe_regs = 0; + + /* R0, then some depth related regs: + */ + for (i = 0; i < c->key.nr_depth_regs; i++) { + c->payload_depth[i] = brw_vec8_grf(i*2, 0); + c->reg_index += 2; + } + + + /* Then a copy of our part of the CURBE entry: + */ + { + int nr_constants = c->fp->info.nr_regs[TGSI_FILE_CONSTANT]; + int index = 0; + + c->prog_data.max_const = 4*nr_constants; + for (i = 0; i < nr_constants; i++) { + for (j = 0; j < 4; j++, index++) + c->wm_regs[TGSI_FILE_CONSTANT][i][j] = brw_vec1_grf(c->reg_index + index/8, + index%8); + } + + nr_curbe_regs = 2*((4*nr_constants+15)/16); + c->reg_index += nr_curbe_regs; + } + + /* Adjust for parameter coefficients for position, which are + * currently always provided. + */ +// c->position_coef[i] = brw_vec8_grf(c->reg_index, 0); + c->reg_index += 2; + + /* Next we receive the plane coefficients for parameter + * interpolation: + */ + for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_INPUT]; i++) { + c->payload_coef[i] = brw_vec8_grf(c->reg_index, 0); + c->reg_index += 2; + } + + c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2; + c->prog_data.urb_read_length = (c->fp->program.num_inputs + 1) * 2; + c->prog_data.curb_read_length = nr_curbe_regs; + + /* That's the end of the payload, now we can start allocating registers. + */ + c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0); + c->reg_index++; + + c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0); + c->reg_index += 2; + + /* Now allocate room for the interpolated inputs and staging + * registers for the outputs: + */ + for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_INPUT]; i++) + for (j = 0; j < 4; j++) + c->wm_regs[TGSI_FILE_INPUT][i][j] = brw_vec8_grf( c->reg_index++, 0 ); + + for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_OUTPUT]; i++) + for (j = 0; j < 4; j++) + c->wm_regs[TGSI_FILE_OUTPUT][i][j] = brw_vec8_grf( c->reg_index++, 0 ); + + /* Beyond this we should only need registers for internal temporaries: + */ + c->tmp_start = c->reg_index; +} + + + + + +/* Need to interpolate fragment program inputs in as a preamble to the + * shader. A more sophisticated compiler would do this on demand, but + * we'll do it up front: + */ +void brw_wm_emit_decls(struct brw_wm_compile *c) +{ + struct tgsi_parse_context parse; + int done = 0; + + prealloc_reg(c); + + tgsi_parse_init( &parse, c->fp->program.tokens ); + + while( !done && + !tgsi_parse_end_of_tokens( &parse ) ) + { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + const struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration; + unsigned first = decl->u.DeclarationRange.First; + unsigned last = decl->u.DeclarationRange.Last; + unsigned mask = decl->Declaration.UsageMask; /* ? */ + unsigned i; + + if (decl->Declaration.File != TGSI_FILE_INPUT) + break; + + assert(decl->Declaration.Interpolate); + + for( i = first; i <= last; i++ ) { + switch (decl->Interpolation.Interpolate) { + case TGSI_INTERPOLATE_CONSTANT: + emit_cinterp(c, i, mask); + break; + + case TGSI_INTERPOLATE_LINEAR: + emit_linterp(c, i, mask); + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + //emit_pinterp(c, i, mask); + emit_linterp(c, i, mask); + break; + } + } + break; + } + case TGSI_TOKEN_TYPE_IMMEDIATE: + case TGSI_TOKEN_TYPE_INSTRUCTION: + default: + done = 1; + break; + } + } + + tgsi_parse_free (&parse); + + release_tmps(c); +} diff --git a/src/gallium/drivers/i965simple/brw_wm_glsl.c b/src/gallium/drivers/i965simple/brw_wm_glsl.c new file mode 100644 index 0000000000..d95645d108 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_wm_glsl.c @@ -0,0 +1,1079 @@ + +#include "brw_context.h" +#include "brw_eu.h" +#include "brw_wm.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/tgsi/util/tgsi_parse.h" + + + +static int get_scalar_dst_index(struct tgsi_full_instruction *inst) +{ + struct tgsi_dst_register dst = inst->FullDstRegisters[0].DstRegister; + int i; + for (i = 0; i < 4; i++) + if (dst.WriteMask & (1<tmp_index++; + c->reg_index = MAX2(c->reg_index, c->tmp_index); + return brw_vec8_grf(c->tmp_start + c->tmp_index, 0); +} + +static void release_tmps(struct brw_wm_compile *c) +{ + c->tmp_index = 0; +} + + +static struct brw_reg +get_reg(struct brw_wm_compile *c, int file, int index, int component ) +{ + switch (file) { + case TGSI_FILE_NULL: + return brw_null_reg(); + + case TGSI_FILE_SAMPLER: + /* Should never get here: + */ + assert (0); + return brw_null_reg(); + + case TGSI_FILE_IMMEDIATE: + /* These need a different path: + */ + assert(0); + return brw_null_reg(); + + + case TGSI_FILE_CONSTANT: + case TGSI_FILE_INPUT: + case TGSI_FILE_OUTPUT: + case TGSI_FILE_TEMPORARY: + case TGSI_FILE_ADDRESS: + return c->wm_regs[file][index][component]; + + default: + assert(0); + return brw_null_reg(); + } +} + + +static struct brw_reg get_dst_reg(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst, + int component) +{ + return get_reg(c, + inst->FullDstRegisters[0].DstRegister.File, + inst->FullDstRegisters[0].DstRegister.Index, + component); +} + +static int get_swz( struct tgsi_src_register src, int index ) +{ + switch (index & 3) { + case 0: return src.SwizzleX; + case 1: return src.SwizzleY; + case 2: return src.SwizzleZ; + case 3: return src.SwizzleW; + default: return 0; + } +} + +static int get_ext_swz( struct tgsi_src_register_ext_swz src, int index ) +{ + switch (index & 3) { + case 0: return src.ExtSwizzleX; + case 1: return src.ExtSwizzleY; + case 2: return src.ExtSwizzleZ; + case 3: return src.ExtSwizzleW; + default: return 0; + } +} + +static struct brw_reg get_src_reg(struct brw_wm_compile *c, + struct tgsi_full_src_register *src, + int index) +{ + struct brw_reg reg; + int component = index; + int neg = 0; + int abs = 0; + + if (src->SrcRegister.Negate) + neg = 1; + + component = get_swz(src->SrcRegister, component); + + /* Yes, there are multiple negates: + */ + switch (component & 3) { + case 0: neg ^= src->SrcRegisterExtSwz.NegateX; break; + case 1: neg ^= src->SrcRegisterExtSwz.NegateY; break; + case 2: neg ^= src->SrcRegisterExtSwz.NegateZ; break; + case 3: neg ^= src->SrcRegisterExtSwz.NegateW; break; + } + + /* And multiple swizzles, fun isn't it: + */ + component = get_ext_swz(src->SrcRegisterExtSwz, component); + + /* Can't handle this, don't know if we need to: + */ + assert(src->SrcRegisterExtSwz.ExtDivide == TGSI_EXTSWIZZLE_ONE); + + /* Not handling indirect lookups yet: + */ + assert(src->SrcRegister.Indirect == 0); + + /* Don't know what dimension means: + */ + assert(src->SrcRegister.Dimension == 0); + + /* Will never handle any of this stuff: + */ + assert(src->SrcRegisterExtMod.Complement == 0); + assert(src->SrcRegisterExtMod.Bias == 0); + assert(src->SrcRegisterExtMod.Scale2X == 0); + + if (src->SrcRegisterExtMod.Absolute) + abs = 1; + + /* Another negate! This is a post-absolute negate, which we + * can't do. Need to clean the crap out of tgsi somehow. + */ + assert(src->SrcRegisterExtMod.Negate == 0); + + switch( component ) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + reg = get_reg(c, + src->SrcRegister.File, + src->SrcRegister.Index, + component ); + + if (neg) + reg = negate(reg); + + if (abs) + reg = brw_abs(reg); + + break; + + /* XXX: this won't really work in the general case, but we know + * that the extended swizzle is only allowed in the SWZ + * instruction (right??), in which case using an immediate + * directly will work. + */ + case TGSI_EXTSWIZZLE_ZERO: + reg = brw_imm_f(0); + break; + + case TGSI_EXTSWIZZLE_ONE: + if (neg && !abs) + reg = brw_imm_f(-1.0); + else + reg = brw_imm_f(1.0); + break; + + default: + assert(0); + break; + } + + + return reg; +} + +static void emit_abs( struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + + int i; + struct brw_compile *p = &c->func; + brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE); + for (i = 0; i < 4; i++) { + if (mask & (1<FullSrcRegisters[0], i); + brw_MOV(p, dst, brw_abs(src)); /* NOTE */ + } + } + brw_set_saturate(p, 0); +} + + +static void emit_xpd(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + int i; + struct brw_compile *p = &c->func; + unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + for (i = 0; i < 4; i++) { + unsigned i2 = (i+2)%3; + unsigned i1 = (i+1)%3; + if (mask & (1<FullSrcRegisters[0], i2)); + src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i1); + brw_MUL(p, brw_null_reg(), src0, src1); + src0 = get_src_reg(c, &inst->FullSrcRegisters[0], i1); + src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i2); + brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE); + brw_MAC(p, dst, src0, src1); + brw_set_saturate(p, 0); + } + } + brw_set_saturate(p, 0); +} + +static void emit_dp3(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + struct brw_reg src0[3], src1[3], dst; + int i; + struct brw_compile *p = &c->func; + for (i = 0; i < 3; i++) { + src0[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i); + src1[i] = get_src_reg(c, &inst->FullSrcRegisters[1], i); + } + + dst = get_dst_reg(c, inst, get_scalar_dst_index(inst)); + brw_MUL(p, brw_null_reg(), src0[0], src1[0]); + brw_MAC(p, brw_null_reg(), src0[1], src1[1]); + brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0); + brw_MAC(p, dst, src0[2], src1[2]); + brw_set_saturate(p, 0); +} + +static void emit_dp4(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + struct brw_reg src0[4], src1[4], dst; + int i; + struct brw_compile *p = &c->func; + for (i = 0; i < 4; i++) { + src0[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i); + src1[i] = get_src_reg(c, &inst->FullSrcRegisters[1], i); + } + dst = get_dst_reg(c, inst, get_scalar_dst_index(inst)); + brw_MUL(p, brw_null_reg(), src0[0], src1[0]); + brw_MAC(p, brw_null_reg(), src0[1], src1[1]); + brw_MAC(p, brw_null_reg(), src0[2], src1[2]); + brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0); + brw_MAC(p, dst, src0[3], src1[3]); + brw_set_saturate(p, 0); +} + +static void emit_dph(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + struct brw_reg src0[4], src1[4], dst; + int i; + struct brw_compile *p = &c->func; + for (i = 0; i < 4; i++) { + src0[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i); + src1[i] = get_src_reg(c, &inst->FullSrcRegisters[1], i); + } + dst = get_dst_reg(c, inst, get_scalar_dst_index(inst)); + brw_MUL(p, brw_null_reg(), src0[0], src1[0]); + brw_MAC(p, brw_null_reg(), src0[1], src1[1]); + brw_MAC(p, dst, src0[2], src1[2]); + brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0); + brw_ADD(p, dst, src0[3], src1[3]); + brw_set_saturate(p, 0); +} + +static void emit_math1(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst, unsigned func) +{ + struct brw_compile *p = &c->func; + struct brw_reg src0, dst; + + src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0); + dst = get_dst_reg(c, inst, get_scalar_dst_index(inst)); + brw_MOV(p, brw_message_reg(2), src0); + brw_math(p, + dst, + func, + ((inst->Instruction.Saturate != TGSI_SAT_NONE) + ? BRW_MATH_SATURATE_SATURATE + : BRW_MATH_SATURATE_NONE), + 2, + brw_null_reg(), + BRW_MATH_DATA_VECTOR, + BRW_MATH_PRECISION_FULL); +} + + +static void emit_alu2(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst, + unsigned opcode) +{ + struct brw_compile *p = &c->func; + struct brw_reg src0, src1, dst; + unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + int i; + brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0); + for (i = 0 ; i < 4; i++) { + if (mask & (1<FullSrcRegisters[0], i); + src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i); + brw_alu2(p, opcode, dst, src0, src1); + } + } + brw_set_saturate(p, 0); +} + + +static void emit_alu1(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst, + unsigned opcode) +{ + struct brw_compile *p = &c->func; + struct brw_reg src0, dst; + unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + int i; + brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0); + for (i = 0 ; i < 4; i++) { + if (mask & (1<FullSrcRegisters[0], i); + brw_alu1(p, opcode, dst, src0); + } + } + if (inst->Instruction.Saturate != TGSI_SAT_NONE) + brw_set_saturate(p, 0); +} + + +static void emit_max(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + struct brw_compile *p = &c->func; + unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + struct brw_reg src0, src1, dst; + int i; + brw_push_insn_state(p); + for (i = 0; i < 4; i++) { + if (mask & (1<FullSrcRegisters[0], i); + src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i); + brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0); + brw_MOV(p, dst, src0); + brw_set_saturate(p, 0); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src0, src1); + brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0); + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + brw_MOV(p, dst, src1); + brw_set_saturate(p, 0); + brw_set_predicate_control_flag_value(p, 0xff); + } + } + brw_pop_insn_state(p); +} + +static void emit_min(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + struct brw_compile *p = &c->func; + unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + struct brw_reg src0, src1, dst; + int i; + brw_push_insn_state(p); + for (i = 0; i < 4; i++) { + if (mask & (1<FullSrcRegisters[0], i); + src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i); + brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0); + brw_MOV(p, dst, src0); + brw_set_saturate(p, 0); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, src1, src0); + brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0); + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + brw_MOV(p, dst, src1); + brw_set_saturate(p, 0); + brw_set_predicate_control_flag_value(p, 0xff); + } + } + brw_pop_insn_state(p); +} + +static void emit_pow(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + struct brw_compile *p = &c->func; + struct brw_reg dst, src0, src1; + dst = get_dst_reg(c, inst, get_scalar_dst_index(inst)); + src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0); + src1 = get_src_reg(c, &inst->FullSrcRegisters[1], 0); + + brw_MOV(p, brw_message_reg(2), src0); + brw_MOV(p, brw_message_reg(3), src1); + + brw_math(p, + dst, + BRW_MATH_FUNCTION_POW, + (inst->Instruction.Saturate != TGSI_SAT_NONE + ? BRW_MATH_SATURATE_SATURATE + : BRW_MATH_SATURATE_NONE), + 2, + brw_null_reg(), + BRW_MATH_DATA_VECTOR, + BRW_MATH_PRECISION_FULL); +} + +static void emit_lrp(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + struct brw_compile *p = &c->func; + unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + struct brw_reg dst, tmp1, tmp2, src0, src1, src2; + int i; + for (i = 0; i < 4; i++) { + if (mask & (1<FullSrcRegisters[0], i); + + src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i); + + if (src1.nr == dst.nr) { + tmp1 = alloc_tmp(c); + brw_MOV(p, tmp1, src1); + } else + tmp1 = src1; + + src2 = get_src_reg(c, &inst->FullSrcRegisters[2], i); + if (src2.nr == dst.nr) { + tmp2 = alloc_tmp(c); + brw_MOV(p, tmp2, src2); + } else + tmp2 = src2; + + brw_ADD(p, dst, negate(src0), brw_imm_f(1.0)); + brw_MUL(p, brw_null_reg(), dst, tmp2); + brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0); + brw_MAC(p, dst, src0, tmp1); + brw_set_saturate(p, 0); + } + release_tmps(c); + } +} + +static void emit_kil(struct brw_wm_compile *c) +{ + struct brw_compile *p = &c->func; + struct brw_reg depth = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW); + brw_push_insn_state(p); + brw_set_mask_control(p, BRW_MASK_DISABLE); + brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK + brw_AND(p, depth, c->emit_mask_reg, depth); + brw_pop_insn_state(p); +} + +static void emit_mad(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + struct brw_compile *p = &c->func; + unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + struct brw_reg dst, src0, src1, src2; + int i; + + for (i = 0; i < 4; i++) { + if (mask & (1<FullSrcRegisters[0], i); + src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i); + src2 = get_src_reg(c, &inst->FullSrcRegisters[2], i); + brw_MUL(p, dst, src0, src1); + + brw_set_saturate(p, (inst->Instruction.Saturate != TGSI_SAT_NONE) ? 1 : 0); + brw_ADD(p, dst, dst, src2); + brw_set_saturate(p, 0); + } + } +} + +static void emit_sop(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst, unsigned cond) +{ + struct brw_compile *p = &c->func; + unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + struct brw_reg dst, src0, src1; + int i; + + brw_push_insn_state(p); + for (i = 0; i < 4; i++) { + if (mask & (1<FullSrcRegisters[0], i); + src1 = get_src_reg(c, &inst->FullSrcRegisters[1], i); + brw_CMP(p, brw_null_reg(), cond, src0, src1); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_MOV(p, dst, brw_imm_f(0.0)); + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + brw_MOV(p, dst, brw_imm_f(1.0)); + } + } + brw_pop_insn_state(p); +} + + +static void emit_ddx(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + struct brw_compile *p = &c->func; + unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + struct brw_reg interp[4]; + struct brw_reg dst; + struct brw_reg src0, w; + unsigned nr, i; + src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0); + w = get_src_reg(c, &inst->FullSrcRegisters[1], 3); + nr = src0.nr; + interp[0] = brw_vec1_grf(nr, 0); + interp[1] = brw_vec1_grf(nr, 4); + interp[2] = brw_vec1_grf(nr+1, 0); + interp[3] = brw_vec1_grf(nr+1, 4); + brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE); + for(i = 0; i < 4; i++ ) { + if (mask & (1<func; + unsigned mask = inst->FullDstRegisters[0].DstRegister.WriteMask; + struct brw_reg interp[4]; + struct brw_reg dst; + struct brw_reg src0, w; + unsigned nr, i; + + src0 = get_src_reg(c, &inst->FullSrcRegisters[0], 0); + nr = src0.nr; + w = get_src_reg(c, &inst->FullSrcRegisters[1], 3); + interp[0] = brw_vec1_grf(nr, 0); + interp[1] = brw_vec1_grf(nr, 4); + interp[2] = brw_vec1_grf(nr+1, 0); + interp[3] = brw_vec1_grf(nr+1, 4); + brw_set_saturate(p, inst->Instruction.Saturate != TGSI_SAT_NONE); + for(i = 0; i < 4; i++ ) { + if (mask & (1<func; + struct brw_reg payload_reg = c->payload_depth[0]; + struct brw_reg dst[4], src[4]; + unsigned i; + for (i = 0; i < 4; i++) + dst[i] = get_dst_reg(c, inst, i); + for (i = 0; i < 4; i++) + src[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i); + +#if 0 + switch (inst->TexSrcTarget) { + case TEXTURE_1D_INDEX: + brw_MOV(p, brw_message_reg(2), src[0]); + brw_MOV(p, brw_message_reg(3), brw_imm_f(0)); + brw_MOV(p, brw_message_reg(4), brw_imm_f(0)); + break; + case TEXTURE_2D_INDEX: + case TEXTURE_RECT_INDEX: + brw_MOV(p, brw_message_reg(2), src[0]); + brw_MOV(p, brw_message_reg(3), src[1]); + brw_MOV(p, brw_message_reg(4), brw_imm_f(0)); + break; + default: + brw_MOV(p, brw_message_reg(2), src[0]); + brw_MOV(p, brw_message_reg(3), src[1]); + brw_MOV(p, brw_message_reg(4), src[2]); + break; + } +#else + brw_MOV(p, brw_message_reg(2), src[0]); + brw_MOV(p, brw_message_reg(3), src[1]); + brw_MOV(p, brw_message_reg(4), brw_imm_f(0)); +#endif + + brw_MOV(p, brw_message_reg(5), src[3]); + brw_MOV(p, brw_message_reg(6), brw_imm_f(0)); + brw_SAMPLE(p, + retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), + 1, + retype(payload_reg, BRW_REGISTER_TYPE_UW), + inst->TexSrcUnit + 1, /* surface */ + inst->TexSrcUnit, /* sampler */ + inst->FullDstRegisters[0].DstRegister.WriteMask, + BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS, + 4, + 4, + 0); +#endif +} + +static void emit_tex(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ +#if 0 + struct brw_compile *p = &c->func; + struct brw_reg payload_reg = c->payload_depth[0]; + struct brw_reg dst[4], src[4]; + unsigned msg_len; + unsigned i, nr; + unsigned emit; + boolean shadow = (c->key.shadowtex_mask & (1<TexSrcUnit)) ? 1 : 0; + + for (i = 0; i < 4; i++) + dst[i] = get_dst_reg(c, inst, i); + for (i = 0; i < 4; i++) + src[i] = get_src_reg(c, &inst->FullSrcRegisters[0], i); + +#if 0 + switch (inst->TexSrcTarget) { + case TEXTURE_1D_INDEX: + emit = WRITEMASK_X; + nr = 1; + break; + case TEXTURE_2D_INDEX: + case TEXTURE_RECT_INDEX: + emit = WRITEMASK_XY; + nr = 2; + break; + default: + emit = WRITEMASK_XYZ; + nr = 3; + break; + } +#else + emit = WRITEMASK_XY; + nr = 2; +#endif + + msg_len = 1; + + for (i = 0; i < nr; i++) { + static const unsigned swz[4] = {0,1,2,2}; + if (emit & (1<TexSrcUnit + 1, /* surface */ + inst->TexSrcUnit, /* sampler */ + inst->FullDstRegisters[0].DstRegister.WriteMask, + BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE, + 4, + shadow ? 6 : 4, + 0); + + if (shadow) + brw_MOV(p, dst[3], brw_imm_f(1.0)); +#endif +} + + + + + + + + +static void emit_fb_write(struct brw_wm_compile *c, + struct tgsi_full_instruction *inst) +{ + struct brw_compile *p = &c->func; + int nr = 2; + int channel; + int base_reg = 0; + + // src0 = output color + // src1 = payload_depth[0] + // src2 = output depth + // dst = ??? + + + + /* Reserve a space for AA - may not be needed: + */ + if (c->key.aa_dest_stencil_reg) + nr += 1; + + { + brw_push_insn_state(p); + for (channel = 0; channel < 4; channel++) { + struct brw_reg src0 = c->wm_regs[TGSI_FILE_OUTPUT][0][channel]; + + /* mov (8) m2.0<1>:ud r28.0<8;8,1>:ud { Align1 } */ + /* mov (8) m6.0<1>:ud r29.0<8;8,1>:ud { Align1 SecHalf } */ + brw_MOV(p, brw_message_reg(nr + channel), src0); + } + /* skip over the regs populated above: */ + nr += 8; + brw_pop_insn_state(p); + } + + + /* Pass through control information: + */ + /* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */ + { + brw_push_insn_state(p); + brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */ + brw_MOV(p, + brw_message_reg(base_reg + 1), + brw_vec8_grf(1, 0)); + brw_pop_insn_state(p); + } + + /* Send framebuffer write message: */ + brw_fb_WRITE(p, + retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW), + base_reg, + retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW), + 0, /* render surface always 0 */ + nr, + 0, + 1); + +} + + +static void brw_wm_emit_instruction( struct brw_wm_compile *c, + struct tgsi_full_instruction *inst ) +{ + struct brw_compile *p = &c->func; + +#if 0 + if (inst->CondUpdate) + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + else + brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE); +#else + brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE); +#endif + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ABS: + emit_abs(c, inst); + break; + case TGSI_OPCODE_ADD: + emit_alu2(c, inst, BRW_OPCODE_ADD); + break; + case TGSI_OPCODE_SUB: + assert(0); +// emit_alu2(c, inst, BRW_OPCODE_SUB); + break; + case TGSI_OPCODE_FRC: + emit_alu1(c, inst, BRW_OPCODE_FRC); + break; + case TGSI_OPCODE_FLR: + assert(0); +// emit_alu1(c, inst, BRW_OPCODE_FLR); + break; + case TGSI_OPCODE_LRP: + emit_lrp(c, inst); + break; + case TGSI_OPCODE_INT: + emit_alu1(c, inst, BRW_OPCODE_RNDD); + break; + case TGSI_OPCODE_MOV: + emit_alu1(c, inst, BRW_OPCODE_MOV); + break; + case TGSI_OPCODE_DP3: + emit_dp3(c, inst); + break; + case TGSI_OPCODE_DP4: + emit_dp4(c, inst); + break; + case TGSI_OPCODE_XPD: + emit_xpd(c, inst); + break; + case TGSI_OPCODE_DPH: + emit_dph(c, inst); + break; + case TGSI_OPCODE_RCP: + emit_math1(c, inst, BRW_MATH_FUNCTION_INV); + break; + case TGSI_OPCODE_RSQ: + emit_math1(c, inst, BRW_MATH_FUNCTION_RSQ); + break; + case TGSI_OPCODE_SIN: + emit_math1(c, inst, BRW_MATH_FUNCTION_SIN); + break; + case TGSI_OPCODE_COS: + emit_math1(c, inst, BRW_MATH_FUNCTION_COS); + break; + case TGSI_OPCODE_EX2: + emit_math1(c, inst, BRW_MATH_FUNCTION_EXP); + break; + case TGSI_OPCODE_LG2: + emit_math1(c, inst, BRW_MATH_FUNCTION_LOG); + break; + case TGSI_OPCODE_MAX: + emit_max(c, inst); + break; + case TGSI_OPCODE_MIN: + emit_min(c, inst); + break; + case TGSI_OPCODE_DDX: + emit_ddx(c, inst); + break; + case TGSI_OPCODE_DDY: + emit_ddy(c, inst); + break; + case TGSI_OPCODE_SLT: + emit_sop(c, inst, BRW_CONDITIONAL_L); + break; + case TGSI_OPCODE_SLE: + emit_sop(c, inst, BRW_CONDITIONAL_LE); + break; + case TGSI_OPCODE_SGT: + emit_sop(c, inst, BRW_CONDITIONAL_G); + break; + case TGSI_OPCODE_SGE: + emit_sop(c, inst, BRW_CONDITIONAL_GE); + break; + case TGSI_OPCODE_SEQ: + emit_sop(c, inst, BRW_CONDITIONAL_EQ); + break; + case TGSI_OPCODE_SNE: + emit_sop(c, inst, BRW_CONDITIONAL_NEQ); + break; + case TGSI_OPCODE_MUL: + emit_alu2(c, inst, BRW_OPCODE_MUL); + break; + case TGSI_OPCODE_POW: + emit_pow(c, inst); + break; + case TGSI_OPCODE_MAD: + emit_mad(c, inst); + break; + case TGSI_OPCODE_TEX: + emit_tex(c, inst); + break; + case TGSI_OPCODE_TXB: + emit_txb(c, inst); + break; + case TGSI_OPCODE_TEXKILL: + emit_kil(c); + break; + case TGSI_OPCODE_IF: + assert(c->if_insn < MAX_IFSN); + c->if_inst[c->if_insn++] = brw_IF(p, BRW_EXECUTE_8); + break; + case TGSI_OPCODE_ELSE: + c->if_inst[c->if_insn-1] = brw_ELSE(p, c->if_inst[c->if_insn-1]); + break; + case TGSI_OPCODE_ENDIF: + assert(c->if_insn > 0); + brw_ENDIF(p, c->if_inst[--c->if_insn]); + break; + case TGSI_OPCODE_BGNSUB: + case TGSI_OPCODE_ENDSUB: + break; + case TGSI_OPCODE_CAL: + brw_push_insn_state(p); + brw_set_mask_control(p, BRW_MASK_DISABLE); + brw_set_access_mode(p, BRW_ALIGN_1); + brw_ADD(p, deref_1ud(c->stack_index, 0), brw_ip_reg(), brw_imm_d(3*16)); + brw_set_access_mode(p, BRW_ALIGN_16); + brw_ADD(p, + get_addr_reg(c->stack_index), + get_addr_reg(c->stack_index), brw_imm_d(4)); +// orig_inst = inst->Data; +// orig_inst->Data = &p->store[p->nr_insn]; + assert(0); + brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16)); + brw_pop_insn_state(p); + break; + + case TGSI_OPCODE_RET: +#if 0 + brw_push_insn_state(p); + brw_set_mask_control(p, BRW_MASK_DISABLE); + brw_ADD(p, + get_addr_reg(c->stack_index), + get_addr_reg(c->stack_index), brw_imm_d(-4)); + brw_set_access_mode(p, BRW_ALIGN_1); + brw_MOV(p, brw_ip_reg(), deref_1ud(c->stack_index, 0)); + brw_set_access_mode(p, BRW_ALIGN_16); + brw_pop_insn_state(p); +#else + emit_fb_write(c, inst); +#endif + + break; + case TGSI_OPCODE_LOOP: + c->loop_inst[c->loop_insn++] = brw_DO(p, BRW_EXECUTE_8); + break; + case TGSI_OPCODE_BRK: + brw_BREAK(p); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + break; + case TGSI_OPCODE_CONT: + brw_CONT(p); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + break; + case TGSI_OPCODE_ENDLOOP: + c->loop_insn--; + c->inst0 = c->inst1 = brw_WHILE(p, c->loop_inst[c->loop_insn]); + /* patch all the BREAK instructions from + last BEGINLOOP */ + while (c->inst0 > c->loop_inst[c->loop_insn]) { + c->inst0--; + if (c->inst0->header.opcode == BRW_OPCODE_BREAK) { + c->inst0->bits3.if_else.jump_count = c->inst1 - c->inst0 + 1; + c->inst0->bits3.if_else.pop_count = 0; + } else if (c->inst0->header.opcode == BRW_OPCODE_CONTINUE) { + c->inst0->bits3.if_else.jump_count = c->inst1 - c->inst0; + c->inst0->bits3.if_else.pop_count = 0; + } + } + break; + case TGSI_OPCODE_END: + emit_fb_write(c, inst); + break; + + default: + debug_printf("unsupported IR in fragment shader %d\n", + inst->Instruction.Opcode); + } +#if 0 + if (inst->CondUpdate) + brw_set_predicate_control(p, BRW_PREDICATE_NORMAL); + else + brw_set_predicate_control(p, BRW_PREDICATE_NONE); +#endif +} + + + + + + +void brw_wm_glsl_emit(struct brw_wm_compile *c) +{ + struct tgsi_parse_context parse; + struct brw_compile *p = &c->func; + + brw_init_compile(&c->func); + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + + c->reg_index = 0; + c->if_insn = 0; + c->loop_insn = 0; + c->stack_index = brw_indirect(0,0); + + /* Do static register allocation and parameter interpolation: + */ + brw_wm_emit_decls( c ); + + /* Emit the actual program. All done with very direct translation, + * hopefully we can improve on this shortly... + */ + brw_MOV(p, get_addr_reg(c->stack_index), brw_address(c->stack)); + + tgsi_parse_init( &parse, c->fp->program.tokens ); + + while( !tgsi_parse_end_of_tokens( &parse ) ) + { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + /* already done */ + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + /* not handled yet */ + assert(0); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + brw_wm_emit_instruction(c, &parse.FullToken.FullInstruction); + break; + + default: + assert( 0 ); + } + } + + tgsi_parse_free (&parse); + + /* Fix up call targets: + */ +#if 0 + { + unsigned nr_insns = c->fp->program.Base.NumInstructions; + unsigned insn, target_insn; + struct tgsi_full_instruction *inst1, *inst2; + struct brw_instruction *brw_inst1, *brw_inst2; + int offset; + for (insn = 0; insn < nr_insns; insn++) { + inst1 = &c->fp->program.Base.Instructions[insn]; + brw_inst1 = inst1->Data; + switch (inst1->Opcode) { + case TGSI_OPCODE_CAL: + target_insn = inst1->BranchTarget; + inst2 = &c->fp->program.Base.Instructions[target_insn]; + brw_inst2 = inst2->Data; + offset = brw_inst2 - brw_inst1; + brw_set_src1(brw_inst1, brw_imm_d(offset*16)); + break; + default: + break; + } + } + } +#endif + + c->prog_data.total_grf = c->reg_index; + c->prog_data.total_scratch = 0; +} diff --git a/src/gallium/drivers/i965simple/brw_wm_iz.c b/src/gallium/drivers/i965simple/brw_wm_iz.c new file mode 100644 index 0000000000..6c5f25bf39 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_wm_iz.c @@ -0,0 +1,214 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_wm.h" + + +#undef P /* prompted depth */ +#undef C /* computed */ +#undef N /* non-promoted? */ + +#define P 0 +#define C 1 +#define N 2 + +const struct { + unsigned mode:2; + unsigned sd_present:1; + unsigned sd_to_rt:1; + unsigned dd_present:1; + unsigned ds_present:1; +} wm_iz_table[IZ_BIT_MAX] = +{ + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { C, 0, 1, 0, 0 }, + { C, 0, 1, 0, 0 }, + { C, 1, 1, 0, 0 }, + { C, 1, 1, 0, 0 }, + { C, 0, 1, 0, 0 }, + { C, 0, 1, 0, 0 }, + { C, 1, 1, 1, 0 }, + { C, 1, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { C, 1, 1, 1, 0 }, + { C, 1, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { C, 0, 1, 0, 0 }, + { C, 0, 1, 0, 0 }, + { C, 1, 1, 0, 0 }, + { C, 1, 1, 0, 0 }, + { C, 0, 1, 0, 0 }, + { C, 0, 1, 0, 0 }, + { C, 1, 1, 1, 0 }, + { C, 1, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { C, 1, 1, 1, 0 }, + { C, 1, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { C, 0, 0, 0, 1 }, + { C, 0, 0, 0, 1 }, + { C, 0, 1, 0, 1 }, + { C, 0, 1, 0, 1 }, + { C, 1, 1, 0, 1 }, + { C, 1, 1, 0, 1 }, + { C, 0, 1, 0, 1 }, + { C, 0, 1, 0, 1 }, + { C, 1, 1, 1, 1 }, + { C, 1, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { C, 1, 1, 1, 1 }, + { C, 1, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { C, 0, 0, 0, 1 }, + { C, 0, 0, 0, 1 }, + { C, 0, 1, 0, 1 }, + { C, 0, 1, 0, 1 }, + { C, 1, 1, 0, 1 }, + { C, 1, 1, 0, 1 }, + { C, 0, 1, 0, 1 }, + { C, 0, 1, 0, 1 }, + { C, 1, 1, 1, 1 }, + { C, 1, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { C, 1, 1, 1, 1 }, + { C, 1, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { N, 1, 1, 0, 0 }, + { N, 0, 1, 0, 0 }, + { N, 0, 1, 0, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { C, 0, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { P, 0, 0, 0, 0 }, + { N, 1, 1, 0, 0 }, + { C, 0, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { N, 1, 1, 0, 0 }, + { N, 0, 1, 0, 0 }, + { N, 0, 1, 0, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { C, 0, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { P, 0, 0, 0, 0 }, + { N, 1, 1, 0, 0 }, + { C, 0, 1, 1, 0 }, + { C, 0, 1, 1, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { N, 1, 1, 0, 1 }, + { N, 0, 1, 0, 1 }, + { N, 0, 1, 0, 1 }, + { P, 0, 0, 0, 0 }, + { P, 0, 0, 0, 0 }, + { C, 0, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { P, 0, 0, 0, 0 }, + { N, 1, 1, 0, 1 }, + { C, 0, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { P, 0, 0, 0, 0 }, + { C, 0, 0, 0, 1 }, + { P, 0, 0, 0, 0 }, + { C, 0, 1, 0, 1 }, + { P, 0, 0, 0, 0 }, + { C, 1, 1, 0, 1 }, + { C, 0, 1, 0, 1 }, + { C, 0, 1, 0, 1 }, + { P, 0, 0, 0, 0 }, + { C, 1, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { P, 0, 0, 0, 0 }, + { C, 1, 1, 1, 1 }, + { C, 0, 1, 1, 1 }, + { C, 0, 1, 1, 1 } +}; + +void brw_wm_lookup_iz( unsigned line_aa, + unsigned lookup, + struct brw_wm_prog_key *key ) +{ + unsigned reg = 2; + + assert (lookup < IZ_BIT_MAX); + + if (lookup & IZ_PS_COMPUTES_DEPTH_BIT) + key->computes_depth = 1; + + if (wm_iz_table[lookup].sd_present) { + key->source_depth_reg = reg; + reg += 2; + } + + if (wm_iz_table[lookup].sd_to_rt) + key->source_depth_to_render_target = 1; + + if (wm_iz_table[lookup].ds_present || line_aa != AA_NEVER) { + key->aa_dest_stencil_reg = reg; + key->runtime_check_aads_emit = (!wm_iz_table[lookup].ds_present && + line_aa == AA_SOMETIMES); + reg++; + } + + if (wm_iz_table[lookup].dd_present) { + key->dest_depth_reg = reg; + reg+=2; + } + + key->nr_depth_regs = (reg+1)/2; +} + diff --git a/src/gallium/drivers/i965simple/brw_wm_sampler_state.c b/src/gallium/drivers/i965simple/brw_wm_sampler_state.c new file mode 100644 index 0000000000..de42ffc5b1 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_wm_sampler_state.c @@ -0,0 +1,273 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" + +#include "pipe/p_util.h" + + +#define COMPAREFUNC_ALWAYS 0 +#define COMPAREFUNC_NEVER 0x1 +#define COMPAREFUNC_LESS 0x2 +#define COMPAREFUNC_EQUAL 0x3 +#define COMPAREFUNC_LEQUAL 0x4 +#define COMPAREFUNC_GREATER 0x5 +#define COMPAREFUNC_NOTEQUAL 0x6 +#define COMPAREFUNC_GEQUAL 0x7 + +/* Samplers aren't strictly wm state from the hardware's perspective, + * but that is the only situation in which we use them in this driver. + */ + +static int intel_translate_shadow_compare_func(unsigned func) +{ + switch(func) { + case PIPE_FUNC_NEVER: + return COMPAREFUNC_ALWAYS; + case PIPE_FUNC_LESS: + return COMPAREFUNC_LEQUAL; + case PIPE_FUNC_LEQUAL: + return COMPAREFUNC_LESS; + case PIPE_FUNC_GREATER: + return COMPAREFUNC_GEQUAL; + case PIPE_FUNC_GEQUAL: + return COMPAREFUNC_GREATER; + case PIPE_FUNC_NOTEQUAL: + return COMPAREFUNC_EQUAL; + case PIPE_FUNC_EQUAL: + return COMPAREFUNC_NOTEQUAL; + case PIPE_FUNC_ALWAYS: + return COMPAREFUNC_NEVER; + } + + debug_printf("Unknown value in %s: %x\n", __FUNCTION__, func); + return COMPAREFUNC_NEVER; +} + +/* The brw (and related graphics cores) do not support GL_CLAMP. The + * Intel drivers for "other operating systems" implement GL_CLAMP as + * GL_CLAMP_TO_EDGE, so the same is done here. + */ +static unsigned translate_wrap_mode( int wrap ) +{ + switch( wrap ) { + case PIPE_TEX_WRAP_REPEAT: + return BRW_TEXCOORDMODE_WRAP; + case PIPE_TEX_WRAP_CLAMP: + return BRW_TEXCOORDMODE_CLAMP; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return BRW_TEXCOORDMODE_CLAMP; /* conform likes it this way */ + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return BRW_TEXCOORDMODE_CLAMP_BORDER; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + return BRW_TEXCOORDMODE_MIRROR; + default: + return BRW_TEXCOORDMODE_WRAP; + } +} + + +static unsigned U_FIXED(float value, unsigned frac_bits) +{ + value *= (1<cache[BRW_SAMPLER_DEFAULT_COLOR], &sdc ); +} + + +/* + */ +static void brw_update_sampler_state( const struct pipe_sampler_state *pipe_sampler, + unsigned sdc_gs_offset, + struct brw_sampler_state *sampler) +{ + memset(sampler, 0, sizeof(*sampler)); + + switch (pipe_sampler->min_mip_filter) { + case PIPE_TEX_FILTER_NEAREST: + sampler->ss0.min_filter = BRW_MAPFILTER_NEAREST; + break; + case PIPE_TEX_FILTER_LINEAR: + sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR; + break; + default: + break; + } + + switch (pipe_sampler->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + sampler->ss0.mip_filter = BRW_MIPFILTER_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + sampler->ss0.mip_filter = BRW_MIPFILTER_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + sampler->ss0.mip_filter = BRW_MIPFILTER_NONE; + break; + default: + break; + } + /* Set Anisotropy: + */ + if (pipe_sampler->max_anisotropy > 1.0) { + sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC; + sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC; + + if (pipe_sampler->max_anisotropy > 2.0) { + sampler->ss3.max_aniso = MAX2((pipe_sampler->max_anisotropy - 2) / 2, + BRW_ANISORATIO_16); + } + } + else { + switch (pipe_sampler->mag_img_filter) { + case PIPE_TEX_FILTER_NEAREST: + sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST; + break; + case PIPE_TEX_FILTER_LINEAR: + sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR; + break; + default: + break; + } + } + + sampler->ss1.s_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_s); + sampler->ss1.r_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_r); + sampler->ss1.t_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_t); + + /* Fulsim complains if I don't do this. Hardware doesn't mind: + */ +#if 0 + if (texObj->Target == GL_TEXTURE_CUBE_MAP_ARB) { + sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE; + sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE; + sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE; + } +#endif + + /* Set shadow function: + */ + if (pipe_sampler->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(pipe_sampler->compare_func); + } + + /* Set LOD bias: + */ + sampler->ss0.lod_bias = S_FIXED(CLAMP(pipe_sampler->lod_bias, -16, 15), 6); + + sampler->ss0.lod_preclamp = 1; /* OpenGL mode */ + sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */ + + /* Set BaseMipLevel, MaxLOD, MinLOD: + * + * XXX: I don't think that using firstLevel, lastLevel works, + * because we always setup the surface state as if firstLevel == + * level zero. Probably have to subtract firstLevel from each of + * these: + */ + sampler->ss0.base_level = U_FIXED(0, 1); + + sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(pipe_sampler->max_lod, 0), 13), 6); + sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(pipe_sampler->min_lod, 0), 13), 6); + + sampler->ss2.default_color_pointer = sdc_gs_offset >> 5; +} + + + +/* All samplers must be uploaded in a single contiguous array, which + * complicates various things. However, this is still too confusing - + * FIXME: simplify all the different new texture state flags. + */ +static void upload_wm_samplers(struct brw_context *brw) +{ + unsigned unit; + unsigned sampler_count = 0; + + /* BRW_NEW_SAMPLER */ + for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) { + /* determine unit enable/disable by looking for a bound texture */ + if (brw->attribs.Texture[unit]) { + const struct pipe_sampler_state *sampler = brw->attribs.Samplers[unit]; + unsigned sdc_gs_offset = upload_default_color(brw, sampler->border_color); + + brw_update_sampler_state(sampler, + sdc_gs_offset, + &brw->wm.sampler[unit]); + + sampler_count = unit + 1; + } + } + + if (brw->wm.sampler_count != sampler_count) { + brw->wm.sampler_count = sampler_count; + brw->state.dirty.cache |= CACHE_NEW_SAMPLER; + } + + brw->wm.sampler_gs_offset = 0; + + if (brw->wm.sampler_count) + brw->wm.sampler_gs_offset = + brw_cache_data_sz(&brw->cache[BRW_SAMPLER], + brw->wm.sampler, + sizeof(struct brw_sampler_state) * brw->wm.sampler_count); +} + +const struct brw_tracked_state brw_wm_samplers = { + .dirty = { + .brw = BRW_NEW_SAMPLER, + .cache = 0 + }, + .update = upload_wm_samplers +}; + diff --git a/src/gallium/drivers/i965simple/brw_wm_state.c b/src/gallium/drivers/i965simple/brw_wm_state.c new file mode 100644 index 0000000000..5ccd488842 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_wm_state.c @@ -0,0 +1,194 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" +#include "brw_wm.h" +#include "pipe/p_util.h" + +/*********************************************************************** + * WM unit - fragment programs and rasterization + */ +static void upload_wm_unit(struct brw_context *brw ) +{ + struct brw_wm_unit_state wm; + unsigned max_threads; + unsigned per_thread; + + if (BRW_DEBUG & DEBUG_SINGLE_THREAD) + max_threads = 0; + else + max_threads = 31; + + + memset(&wm, 0, sizeof(wm)); + + /* CACHE_NEW_WM_PROG */ + wm.thread0.grf_reg_count = align(brw->wm.prog_data->total_grf, 16) / 16 - 1; + wm.thread0.kernel_start_pointer = brw->wm.prog_gs_offset >> 6; + wm.thread3.dispatch_grf_start_reg = brw->wm.prog_data->first_curbe_grf; + wm.thread3.urb_entry_read_length = brw->wm.prog_data->urb_read_length; + wm.thread3.const_urb_entry_read_length = brw->wm.prog_data->curb_read_length; + + wm.wm5.max_threads = max_threads; + + per_thread = align(brw->wm.prog_data->total_scratch, 1024); + assert(per_thread <= 12 * 1024); + +#if 0 + if (brw->wm.prog_data->total_scratch) { + unsigned total = per_thread * (max_threads + 1); + + /* Scratch space -- just have to make sure there is sufficient + * allocated for the active program and current number of threads. + */ + brw->wm.scratch_buffer_size = total; + if (brw->wm.scratch_buffer && + brw->wm.scratch_buffer_size > brw->wm.scratch_buffer->size) { + dri_bo_unreference(brw->wm.scratch_buffer); + brw->wm.scratch_buffer = NULL; + } + if (!brw->wm.scratch_buffer) { + brw->wm.scratch_buffer = dri_bo_alloc(intel->intelScreen->bufmgr, + "wm scratch", + brw->wm.scratch_buffer_size, + 4096, DRM_BO_FLAG_MEM_TT); + } + } + /* XXX: Scratch buffers are not implemented correectly. + * + * The scratch offset to be programmed into wm is relative to the general + * state base address. However, using dri_bo_alloc/dri_bo_emit_reloc (or + * the previous bmGenBuffers scheme), we get an offset relative to the + * start of framebuffer. Even before then, it was broken in other ways, + * so just fail for now if we hit that path. + */ + assert(brw->wm.prog_data->total_scratch == 0); +#endif + + /* CACHE_NEW_SURFACE */ + wm.thread1.binding_table_entry_count = brw->wm.nr_surfaces; + + /* BRW_NEW_CURBE_OFFSETS */ + wm.thread3.const_urb_entry_read_offset = brw->curbe.wm_start * 2; + + wm.thread3.urb_entry_read_offset = 0; + wm.thread1.depth_coef_urb_read_offset = 1; + wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; + + /* CACHE_NEW_SAMPLER */ + wm.wm4.sampler_count = (brw->wm.sampler_count + 1) / 4; + wm.wm4.sampler_state_pointer = brw->wm.sampler_gs_offset >> 5; + + /* BRW_NEW_FRAGMENT_PROGRAM */ + { + const struct brw_fragment_program *fp = brw->attribs.FragmentProgram; + + if (fp->UsesDepth) + wm.wm5.program_uses_depth = 1; /* as far as we can tell */ + + if (fp->ComputesDepth) + wm.wm5.program_computes_depth = 1; + + /* BRW_NEW_ALPHA_TEST */ + if (fp->UsesKill || + brw->attribs.DepthStencil->alpha.enabled) + wm.wm5.program_uses_killpixel = 1; + + wm.wm5.enable_8_pix = 1; + } + + wm.wm5.thread_dispatch_enable = 1; /* AKA: color_write */ + wm.wm5.legacy_line_rast = 0; + wm.wm5.legacy_global_depth_bias = 0; + wm.wm5.early_depth_test = 1; /* never need to disable */ + wm.wm5.line_aa_region_width = 0; + wm.wm5.line_endcap_aa_region_width = 1; + + /* BRW_NEW_RASTERIZER */ + if (brw->attribs.Raster->poly_stipple_enable) + wm.wm5.polygon_stipple = 1; + +#if 0 + if (brw->attribs.Polygon->OffsetFill) { + wm.wm5.depth_offset = 1; + /* Something wierd going on with legacy_global_depth_bias, + * offset_constant, scaling and MRD. This value passes glean + * but gives some odd results elsewere (eg. the + * quad-offset-units test). + */ + wm.global_depth_offset_constant = brw->attribs.Polygon->OffsetUnits * 2; + + /* This is the only value that passes glean: + */ + wm.global_depth_offset_scale = brw->attribs.Polygon->OffsetFactor; + } +#endif + + if (brw->attribs.Raster->line_stipple_enable) { + wm.wm5.line_stipple = 1; + } + + if (BRW_DEBUG & DEBUG_STATS) + wm.wm4.stats_enable = 1; + + brw->wm.state_gs_offset = brw_cache_data( &brw->cache[BRW_WM_UNIT], &wm ); + + if (brw->wm.prog_data->total_scratch) { + /* + dri_emit_reloc(brw->cache[BRW_WM_UNIT].pool->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + (per_thread / 1024) - 1, + brw->wm.state_gs_offset + + ((char *)&wm.thread2 - (char *)&wm), + brw->wm.scratch_buffer); + */ + } else { + wm.thread2.scratch_space_base_pointer = 0; + } +} + +const struct brw_tracked_state brw_wm_unit = { + .dirty = { + .brw = (BRW_NEW_RASTERIZER | + BRW_NEW_ALPHA_TEST | + BRW_NEW_FS | + BRW_NEW_CURBE_OFFSETS), + + .cache = (CACHE_NEW_SURFACE | + CACHE_NEW_WM_PROG | + CACHE_NEW_SAMPLER) + }, + .update = upload_wm_unit +}; + diff --git a/src/gallium/drivers/i965simple/brw_wm_surface_state.c b/src/gallium/drivers/i965simple/brw_wm_surface_state.c new file mode 100644 index 0000000000..d16d919bce --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_wm_surface_state.c @@ -0,0 +1,304 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_context.h" +#include "brw_state.h" +#include "brw_defines.h" + +static unsigned translate_tex_target( enum pipe_texture_target target ) +{ + switch (target) { + case PIPE_TEXTURE_1D: + return BRW_SURFACE_1D; + + case PIPE_TEXTURE_2D: + return BRW_SURFACE_2D; + + case PIPE_TEXTURE_3D: + return BRW_SURFACE_3D; + + case PIPE_TEXTURE_CUBE: + return BRW_SURFACE_CUBE; + + default: + assert(0); + return 0; + } +} + +static unsigned translate_tex_format( enum pipe_format pipe_format ) +{ + switch( pipe_format ) { + case PIPE_FORMAT_U_L8: + return BRW_SURFACEFORMAT_L8_UNORM; + + case PIPE_FORMAT_U_I8: + return BRW_SURFACEFORMAT_I8_UNORM; + + case PIPE_FORMAT_U_A8: + return BRW_SURFACEFORMAT_A8_UNORM; + + case PIPE_FORMAT_U_A8_L8: + return BRW_SURFACEFORMAT_L8A8_UNORM; + + case PIPE_FORMAT_R8G8B8_UNORM: + assert(0); /* not supported for sampling */ + return BRW_SURFACEFORMAT_R8G8B8_UNORM; + + case PIPE_FORMAT_B8G8R8A8_UNORM: + return BRW_SURFACEFORMAT_B8G8R8A8_UNORM; + + case PIPE_FORMAT_R8G8B8A8_UNORM: + return BRW_SURFACEFORMAT_R8G8B8A8_UNORM; + + case PIPE_FORMAT_R5G6B5_UNORM: + return BRW_SURFACEFORMAT_B5G6R5_UNORM; + + case PIPE_FORMAT_A1R5G5B5_UNORM: + return BRW_SURFACEFORMAT_B5G5R5A1_UNORM; + + case PIPE_FORMAT_A4R4G4B4_UNORM: + return BRW_SURFACEFORMAT_B4G4R4A4_UNORM; + + case PIPE_FORMAT_YCBCR_REV: + return BRW_SURFACEFORMAT_YCRCB_NORMAL; + + case PIPE_FORMAT_YCBCR: + return BRW_SURFACEFORMAT_YCRCB_SWAPUVY; +#if 0 + case PIPE_FORMAT_RGB_FXT1: + case PIPE_FORMAT_RGBA_FXT1: + return BRW_SURFACEFORMAT_FXT1; +#endif + + case PIPE_FORMAT_Z16_UNORM: + return BRW_SURFACEFORMAT_I16_UNORM; +#if 0 + case PIPE_FORMAT_RGB_DXT1: + return BRW_SURFACEFORMAT_DXT1_RGB; + + case PIPE_FORMAT_RGBA_DXT1: + return BRW_SURFACEFORMAT_BC1_UNORM; + + case PIPE_FORMAT_RGBA_DXT3: + return BRW_SURFACEFORMAT_BC2_UNORM; + + case PIPE_FORMAT_RGBA_DXT5: + return BRW_SURFACEFORMAT_BC3_UNORM; + + case PIPE_FORMAT_SRGBA8: + return BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB; + case PIPE_FORMAT_SRGB_DXT1: + return BRW_SURFACEFORMAT_BC1_UNORM_SRGB; +#endif + + default: + assert(0); + return 0; + } +} + +static unsigned brw_buffer_offset(struct brw_context *brw, + struct pipe_buffer *buffer) +{ + return brw->winsys->get_buffer_offset(brw->winsys, + buffer, + 0); +} + +static +void brw_update_texture_surface( struct brw_context *brw, + unsigned unit ) +{ + const struct brw_texture *tObj = brw->attribs.Texture[unit]; + struct brw_surface_state surf; + + memset(&surf, 0, sizeof(surf)); + + surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW; + surf.ss0.surface_type = translate_tex_target(tObj->base.target); + surf.ss0.surface_format = translate_tex_format(tObj->base.format); + + /* This is ok for all textures with channel width 8bit or less: + */ +/* surf.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */ + + /* Updated in emit_reloc */ + surf.ss1.base_addr = brw_buffer_offset( brw, tObj->buffer ); + + surf.ss2.mip_count = tObj->base.last_level; + surf.ss2.width = tObj->base.width[0] - 1; + surf.ss2.height = tObj->base.height[0] - 1; + + surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR; + surf.ss3.tiled_surface = 0; /* always zero */ + surf.ss3.pitch = tObj->pitch - 1; + surf.ss3.depth = tObj->base.depth[0] - 1; + + surf.ss4.min_lod = 0; + + if (tObj->base.target == PIPE_TEXTURE_CUBE) { + surf.ss0.cube_pos_x = 1; + surf.ss0.cube_pos_y = 1; + surf.ss0.cube_pos_z = 1; + surf.ss0.cube_neg_x = 1; + surf.ss0.cube_neg_y = 1; + surf.ss0.cube_neg_z = 1; + } + + brw->wm.bind.surf_ss_offset[unit + 1] = + brw_cache_data( &brw->cache[BRW_SS_SURFACE], &surf ); +} + + + +#define OFFSET(TYPE, FIELD) ( (unsigned)&(((TYPE *)0)->FIELD) ) + + +static void upload_wm_surfaces(struct brw_context *brw ) +{ + unsigned i; + + { + struct brw_surface_state surf; + + /* BRW_NEW_FRAMEBUFFER + */ + struct pipe_surface *pipe_surface = brw->attribs.FrameBuffer.cbufs[0];/*fixme*/ + + memset(&surf, 0, sizeof(surf)); + + if (pipe_surface != NULL) { + if (pipe_surface->cpp == 4) + surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; + else + surf.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM; + + surf.ss0.surface_type = BRW_SURFACE_2D; + + surf.ss1.base_addr = brw_buffer_offset( brw, pipe_surface->buffer ); + + surf.ss2.width = pipe_surface->width - 1; + surf.ss2.height = pipe_surface->height - 1; + surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR; + surf.ss3.tiled_surface = 0; + surf.ss3.pitch = (pipe_surface->pitch * pipe_surface->cpp) - 1; + } else { + surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; + surf.ss0.surface_type = BRW_SURFACE_NULL; + } + + /* BRW_NEW_BLEND */ + surf.ss0.color_blend = (!brw->attribs.Blend->logicop_enable && + brw->attribs.Blend->blend_enable); + + + surf.ss0.writedisable_red = !(brw->attribs.Blend->colormask & PIPE_MASK_R); + surf.ss0.writedisable_green = !(brw->attribs.Blend->colormask & PIPE_MASK_G); + surf.ss0.writedisable_blue = !(brw->attribs.Blend->colormask & PIPE_MASK_B); + surf.ss0.writedisable_alpha = !(brw->attribs.Blend->colormask & PIPE_MASK_A); + + + + + brw->wm.bind.surf_ss_offset[0] = brw_cache_data( &brw->cache[BRW_SS_SURFACE], &surf ); + + brw->wm.nr_surfaces = 1; + } + + + /* BRW_NEW_TEXTURE + */ + for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { + const struct brw_texture *texUnit = brw->attribs.Texture[i]; + + if (texUnit && + texUnit->base.refcount/*(texUnit->refcount > 0) == really used */) { + + brw_update_texture_surface(brw, i); + + brw->wm.nr_surfaces = i+2; + } + else { + brw->wm.bind.surf_ss_offset[i+1] = 0; + } + } + + brw->wm.bind_ss_offset = brw_cache_data( &brw->cache[BRW_SS_SURF_BIND], + &brw->wm.bind ); +} + + +/* KW: Will find a different way to acheive this, see for example the + * state caches with relocs in the i915 swz driver. + */ +#if 0 +static void emit_reloc_wm_surfaces(struct brw_context *brw) +{ + int unit; + + if (brw->state.draw_region != NULL) { + /* Emit framebuffer relocation */ + dri_emit_reloc(brw_cache_buffer(brw, BRW_SS_SURFACE), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, + brw->wm.bind.surf_ss_offset[0] + + offsetof(struct brw_surface_state, ss1), + brw->state.draw_region->buffer); + } + + /* Emit relocations for texture buffers */ + for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) { + struct gl_texture_unit *texUnit = &brw->attribs.Texture->Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + + if (texUnit->_ReallyEnabled && intelObj->mt != NULL) { + dri_emit_reloc(brw_cache_buffer(brw, BRW_SS_SURFACE), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + 0, + brw->wm.bind.surf_ss_offset[unit + 1] + + offsetof(struct brw_surface_state, ss1), + intelObj->mt->region->buffer); + } + } +} +#endif + +const struct brw_tracked_state brw_wm_surfaces = { + .dirty = { + .brw = (BRW_NEW_FRAMEBUFFER | + BRW_NEW_BLEND | + BRW_NEW_TEXTURE), + .cache = 0 + }, + .update = upload_wm_surfaces, +}; diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile new file mode 100644 index 0000000000..31438a882e --- /dev/null +++ b/src/gallium/drivers/softpipe/Makefile @@ -0,0 +1,50 @@ + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = softpipe + +DRIVER_SOURCES = \ + sp_clear.c \ + sp_flush.c \ + sp_query.c \ + sp_context.c \ + sp_draw_arrays.c \ + sp_prim_setup.c \ + sp_prim_vbuf.c \ + sp_quad.c \ + sp_quad_alpha_test.c \ + sp_quad_blend.c \ + sp_quad_bufloop.c \ + sp_quad_colormask.c \ + sp_quad_coverage.c \ + sp_quad_depth_test.c \ + sp_quad_earlyz.c \ + sp_quad_fs.c \ + sp_quad_occlusion.c \ + sp_quad_output.c \ + sp_quad_stencil.c \ + sp_quad_stipple.c \ + sp_state_blend.c \ + sp_state_clip.c \ + sp_state_derived.c \ + sp_state_fs.c \ + sp_state_sampler.c \ + sp_state_rasterizer.c \ + sp_state_surface.c \ + sp_state_vertex.c \ + sp_texture.c \ + sp_tex_sample.c \ + sp_tile_cache.c \ + sp_surface.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript new file mode 100644 index 0000000000..d581ee8d3c --- /dev/null +++ b/src/gallium/drivers/softpipe/SConscript @@ -0,0 +1,42 @@ +Import('*') + +env = env.Clone() + +softpipe = env.ConvenienceLibrary( + target = 'softpipe', + source = [ + 'sp_clear.c', + 'sp_context.c', + 'sp_draw_arrays.c', + 'sp_flush.c', + 'sp_prim_setup.c', + 'sp_prim_vbuf.c', + 'sp_quad_alpha_test.c', + 'sp_quad_blend.c', + 'sp_quad_bufloop.c', + 'sp_quad.c', + 'sp_quad_colormask.c', + 'sp_quad_coverage.c', + 'sp_quad_depth_test.c', + 'sp_quad_earlyz.c', + 'sp_quad_fs.c', + 'sp_quad_occlusion.c', + 'sp_quad_output.c', + 'sp_quad_stencil.c', + 'sp_quad_stipple.c', + 'sp_query.c', + 'sp_state_blend.c', + 'sp_state_clip.c', + 'sp_state_derived.c', + 'sp_state_fs.c', + 'sp_state_rasterizer.c', + 'sp_state_sampler.c', + 'sp_state_surface.c', + 'sp_state_vertex.c', + 'sp_surface.c', + 'sp_tex_sample.c', + 'sp_texture.c', + 'sp_tile_cache.c', + ]) + +Export('softpipe') \ No newline at end of file diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c new file mode 100644 index 0000000000..8d295a30ca --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_clear.c @@ -0,0 +1,73 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Brian Paul + */ + + +#include "pipe/p_defines.h" +#include "sp_clear.h" +#include "sp_context.h" +#include "sp_surface.h" +#include "sp_state.h" +#include "sp_tile_cache.h" + + +/** + * Clear the given surface to the specified value. + * No masking, no scissor (clear entire buffer). + */ +void +softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint i; + +#if 0 + softpipe_update_derived(softpipe); /* not needed?? */ +#endif + + if (ps == sp_tile_cache_get_surface(softpipe->zsbuf_cache)) { + sp_tile_cache_clear(softpipe->zsbuf_cache, clearValue); +#if TILE_CLEAR_OPTIMIZATION + return; +#endif + } + + for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) { + if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) { + sp_tile_cache_clear(softpipe->cbuf_cache[i], clearValue); + } + } + +#if !TILE_CLEAR_OPTIMIZATION + /* non-cached surface */ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); +#endif +} diff --git a/src/gallium/drivers/softpipe/sp_clear.h b/src/gallium/drivers/softpipe/sp_clear.h new file mode 100644 index 0000000000..a8ed1c4ecc --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_clear.h @@ -0,0 +1,43 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Brian Paul + */ + +#ifndef SP_CLEAR_H +#define SP_CLEAR_H + +#include "pipe/p_state.h" +struct pipe_context; + +extern void +softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + + +#endif /* SP_CLEAR_H */ diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c new file mode 100644 index 0000000000..cea6b90104 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -0,0 +1,333 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + +#include "pipe/draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "sp_clear.h" +#include "sp_context.h" +#include "sp_flush.h" +#include "sp_prim_setup.h" +#include "sp_prim_vbuf.h" +#include "sp_state.h" +#include "sp_surface.h" +#include "sp_tile_cache.h" +#include "sp_texture.h" +#include "sp_winsys.h" +#include "sp_query.h" + + + +/** + * Query format support for creating a texture, drawing surface, etc. + * \param format the format to test + * \param type one of PIPE_TEXTURE, PIPE_SURFACE + */ +static boolean +softpipe_is_format_supported( struct pipe_context *pipe, + enum pipe_format format, uint type ) +{ + switch (type) { + case PIPE_TEXTURE: + /* softpipe supports all texture formats */ + return TRUE; + case PIPE_SURFACE: + /* softpipe supports all (off-screen) surface formats */ + return TRUE; + default: + assert(0); + return FALSE; + } +} + + +/** + * Map any drawing surfaces which aren't already mapped + */ +void +softpipe_map_surfaces(struct softpipe_context *sp) +{ + unsigned i; + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) { + sp_tile_cache_map_surfaces(sp->cbuf_cache[i]); + } + + sp_tile_cache_map_surfaces(sp->zsbuf_cache); +} + + +/** + * Unmap any mapped drawing surfaces + */ +void +softpipe_unmap_surfaces(struct softpipe_context *sp) +{ + uint i; + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) + sp_flush_tile_cache(sp, sp->cbuf_cache[i]); + sp_flush_tile_cache(sp, sp->zsbuf_cache); + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) { + sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]); + } + sp_tile_cache_unmap_surfaces(sp->zsbuf_cache); +} + + +static void softpipe_destroy( struct pipe_context *pipe ) +{ + struct softpipe_context *softpipe = softpipe_context( pipe ); + struct pipe_winsys *ws = pipe->winsys; + uint i; + + draw_destroy( softpipe->draw ); + + softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); + softpipe->quad.earlyz->destroy( softpipe->quad.earlyz ); + softpipe->quad.shade->destroy( softpipe->quad.shade ); + softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test ); + softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); + softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test ); + softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); + softpipe->quad.coverage->destroy( softpipe->quad.coverage ); + softpipe->quad.bufloop->destroy( softpipe->quad.bufloop ); + softpipe->quad.blend->destroy( softpipe->quad.blend ); + softpipe->quad.colormask->destroy( softpipe->quad.colormask ); + softpipe->quad.output->destroy( softpipe->quad.output ); + + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + sp_destroy_tile_cache(softpipe->cbuf_cache[i]); + sp_destroy_tile_cache(softpipe->zsbuf_cache); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + sp_destroy_tile_cache(softpipe->tex_cache[i]); + + for (i = 0; i < Elements(softpipe->constants); i++) { + if (softpipe->constants[i].buffer) { + pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL); + } + } + + FREE( softpipe ); +} + + +static const char *softpipe_get_name( struct pipe_context *pipe ) +{ + return "softpipe"; +} + +static const char *softpipe_get_vendor( struct pipe_context *pipe ) +{ + return "Tungsten Graphics, Inc."; +} + +static int softpipe_get_param(struct pipe_context *pipe, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 8; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 1; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 1; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 1; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 12; /* max 2Kx2K */ + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 8; /* max 128x128x128 */ + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 12; /* max 2Kx2K */ + default: + return 0; + } +} + +static float softpipe_get_paramf(struct pipe_context *pipe, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 255.0; /* arbitrary */ + + case PIPE_CAP_MAX_POINT_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 255.0; /* arbitrary */ + + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 0.0; + + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0; /* arbitrary */ + + default: + return 0; + } +} + +struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, + struct softpipe_winsys *softpipe_winsys ) +{ + struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); + uint i; + +#if defined(__i386__) || defined(__386__) + softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; +#else + softpipe->use_sse = FALSE; +#endif + + softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL; + + softpipe->pipe.winsys = pipe_winsys; + softpipe->pipe.destroy = softpipe_destroy; + + /* queries */ + softpipe->pipe.is_format_supported = softpipe_is_format_supported; + softpipe->pipe.get_name = softpipe_get_name; + softpipe->pipe.get_vendor = softpipe_get_vendor; + softpipe->pipe.get_param = softpipe_get_param; + softpipe->pipe.get_paramf = softpipe_get_paramf; + + /* state setters */ + softpipe->pipe.create_blend_state = softpipe_create_blend_state; + softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; + softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; + + softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; + softpipe->pipe.bind_sampler_state = softpipe_bind_sampler_state; + softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; + + softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state; + softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state; + softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state; + + softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state; + softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state; + softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state; + + softpipe->pipe.create_fs_state = softpipe_create_fs_state; + softpipe->pipe.bind_fs_state = softpipe_bind_fs_state; + softpipe->pipe.delete_fs_state = softpipe_delete_fs_state; + + softpipe->pipe.create_vs_state = softpipe_create_vs_state; + softpipe->pipe.bind_vs_state = softpipe_bind_vs_state; + softpipe->pipe.delete_vs_state = softpipe_delete_vs_state; + + softpipe->pipe.set_blend_color = softpipe_set_blend_color; + softpipe->pipe.set_clip_state = softpipe_set_clip_state; + softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; + softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; + softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; + softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; + softpipe->pipe.set_sampler_texture = softpipe_set_sampler_texture; + softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; + + softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer; + softpipe->pipe.set_vertex_element = softpipe_set_vertex_element; + + softpipe->pipe.draw_arrays = softpipe_draw_arrays; + softpipe->pipe.draw_elements = softpipe_draw_elements; + + softpipe->pipe.clear = softpipe_clear; + softpipe->pipe.flush = softpipe_flush; + + softpipe_init_query_funcs( softpipe ); + + /* textures */ + softpipe->pipe.texture_create = softpipe_texture_create; + softpipe->pipe.texture_release = softpipe_texture_release; + softpipe->pipe.get_tex_surface = softpipe_get_tex_surface; + + /* + * Alloc caches for accessing drawing surfaces and textures. + * Must be before quad stage setup! + */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + softpipe->cbuf_cache[i] = sp_create_tile_cache(); + softpipe->zsbuf_cache = sp_create_tile_cache(); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + softpipe->tex_cache[i] = sp_create_tile_cache(); + + + /* setup quad rendering stages */ + softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); + softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe); + softpipe->quad.shade = sp_quad_shade_stage(softpipe); + softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe); + softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); + softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); + softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); + softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); + softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe); + softpipe->quad.blend = sp_quad_blend_stage(softpipe); + softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); + softpipe->quad.output = sp_quad_output_stage(softpipe); + + softpipe->winsys = softpipe_winsys; + + /* + * Create drawing context and plug our rendering stage into it. + */ + softpipe->draw = draw_create(); + assert(softpipe->draw); + softpipe->setup = sp_draw_render_stage(softpipe); + + if (GETENV( "SP_VBUF" ) != NULL) { + sp_init_vbuf(softpipe); + } + else { + draw_set_rasterize_stage(softpipe->draw, softpipe->setup); + } + + sp_init_surface_functions(softpipe); + + return &softpipe->pipe; +} diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h new file mode 100644 index 0000000000..aff8c2cc5d --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -0,0 +1,152 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_CONTEXT_H +#define SP_CONTEXT_H + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" + +#include "pipe/draw/draw_vertex.h" + +#include "sp_quad.h" + + +struct softpipe_winsys; +struct softpipe_vbuf_render; +struct draw_context; +struct draw_stage; +struct softpipe_tile_cache; +struct sp_fragment_shader_state; +struct sp_vertex_shader_state; + + +struct softpipe_context { + struct pipe_context pipe; /**< base class */ + struct softpipe_winsys *winsys; /**< window system interface */ + + + /* The most recent drawing state as set by the driver: + */ + const struct pipe_blend_state *blend; + const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct pipe_depth_stencil_alpha_state *depth_stencil; + const struct pipe_rasterizer_state *rasterizer; + const struct sp_fragment_shader_state *fs; + const struct sp_vertex_shader_state *vs; + + struct pipe_blend_color blend_color; + struct pipe_clip_state clip; + struct pipe_constant_buffer constants[2]; + struct pipe_framebuffer_state framebuffer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct softpipe_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + unsigned dirty; + + /* Counter for occlusion queries. Note this supports overlapping + * queries. + */ + uint64 occlusion_count; + + /* + * Mapped vertex buffers + */ + ubyte *mapped_vbuffer[PIPE_ATTRIB_MAX]; + + /** Mapped constant buffers */ + void *mapped_constants[PIPE_SHADER_TYPES]; + + /** Vertex format */ + struct vertex_info vertex_info; + struct vertex_info vertex_info_vbuf; + + int psize_slot; + +#if 0 + /* Stipple derived state: + */ + ubyte stipple_masks[16][16]; +#endif + + /** Derived from scissor and surface bounds: */ + struct pipe_scissor_state cliprect; + + unsigned line_stipple_counter; + + /** Software quad rendering pipeline */ + struct { + struct quad_stage *polygon_stipple; + struct quad_stage *earlyz; + struct quad_stage *shade; + struct quad_stage *alpha_test; + struct quad_stage *stencil_test; + struct quad_stage *depth_test; + struct quad_stage *occlusion; + struct quad_stage *coverage; + struct quad_stage *bufloop; + struct quad_stage *blend; + struct quad_stage *colormask; + struct quad_stage *output; + + struct quad_stage *first; /**< points to one of the above stages */ + } quad; + + /** The primitive drawing context */ + struct draw_context *draw; + struct draw_stage *setup; + struct draw_stage *vbuf; + struct softpipe_vbuf_render *vbuf_render; + + uint current_cbuf; /**< current color buffer being written to */ + + struct softpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS]; + struct softpipe_tile_cache *zsbuf_cache; + + struct softpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; + + int use_sse : 1; + int dump_fs : 1; +}; + + + + +static INLINE struct softpipe_context * +softpipe_context( struct pipe_context *pipe ) +{ + return (struct softpipe_context *)pipe; +} + + +#endif /* SP_CONTEXT_H */ diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c new file mode 100644 index 0000000000..71a303a8b5 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -0,0 +1,164 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Brian Paul + * Keith Whitwell + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/p_winsys.h" + +#include "sp_context.h" +#include "sp_state.h" + +#include "pipe/draw/draw_context.h" + + + +static void +softpipe_map_constant_buffers(struct softpipe_context *sp) +{ + struct pipe_winsys *ws = sp->pipe.winsys; + uint i; + for (i = 0; i < 2; i++) { + if (sp->constants[i].size) + sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + } + + draw_set_mapped_constant_buffer(sp->draw, + sp->mapped_constants[PIPE_SHADER_VERTEX]); +} + +static void +softpipe_unmap_constant_buffers(struct softpipe_context *sp) +{ + struct pipe_winsys *ws = sp->pipe.winsys; + uint i; + for (i = 0; i < 2; i++) { + if (sp->constants[i].size) + ws->buffer_unmap(ws, sp->constants[i].buffer); + sp->mapped_constants[i] = NULL; + } +} + + +boolean +softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count) +{ + return softpipe_draw_elements(pipe, NULL, 0, mode, start, count); +} + + + +/** + * Draw vertex arrays, with optional indexing. + * Basically, map the vertex buffers (and drawing surfaces), then hand off + * the drawing to the 'draw' module. + * + * XXX should the element buffer be specified/bound with a separate function? + */ +boolean +softpipe_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + struct softpipe_context *sp = softpipe_context(pipe); + struct draw_context *draw = sp->draw; + unsigned i; + + /* first, check that the primitive is not malformed. It is the + * state tracker's responsibility to do send only correctly formed + * primitives down. It currently isn't doing that though... + */ +#if 1 + count = draw_trim_prim( mode, count ); +#else + if (!draw_validate_prim( mode, count )) + assert(0); +#endif + + + if (sp->dirty) + softpipe_update_derived( sp ); + + softpipe_map_surfaces(sp); + softpipe_map_constant_buffers(sp); + + /* + * Map vertex buffers + */ + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (sp->vertex_buffer[i].buffer) { + void *buf + = pipe->winsys->buffer_map(pipe->winsys, + sp->vertex_buffer[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(draw, i, buf); + } + } + /* Map index buffer, if present */ + if (indexBuffer) { + void *mapped_indexes + = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); + } + else { + /* no index/element buffer */ + draw_set_mapped_element_buffer(draw, 0, NULL); + } + + + /* draw! */ + draw_arrays(draw, mode, start, count); + + /* + * unmap vertex/index buffers - will cause draw module to flush + */ + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (sp->vertex_buffer[i].buffer) { + draw_set_mapped_vertex_buffer(draw, i, NULL); + pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer); + } + } + if (indexBuffer) { + draw_set_mapped_element_buffer(draw, 0, NULL); + pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); + } + + + /* Note: leave drawing surfaces mapped */ + softpipe_unmap_constant_buffers(sp); + + return TRUE; +} diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c new file mode 100644 index 0000000000..ced0d5d098 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -0,0 +1,76 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + + +#include "pipe/p_defines.h" +#include "pipe/draw/draw_context.h" +#include "sp_flush.h" +#include "sp_context.h" +#include "sp_surface.h" +#include "sp_state.h" +#include "sp_tile_cache.h" +#include "sp_winsys.h" + + +/* There will be actual work to do here. In future we may want a + * fence-like interface instead of finish, and perhaps flush will take + * flags to indicate what type of flush is required. + */ +void +softpipe_flush( struct pipe_context *pipe, + unsigned flags ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint i; + + draw_flush(softpipe->draw); + + /* - flush the quad pipeline + * - flush the texture cache + * - flush the render cache + */ + + for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) + if (softpipe->cbuf_cache[i]) + sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]); + + if (softpipe->zsbuf_cache) + sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache); + + /* Need this call for hardware buffers before swapbuffers. + * + * there should probably be another/different flush-type function + * that's called before swapbuffers because we don't always want + * to unmap surfaces when flushing. + */ + softpipe_unmap_surfaces(softpipe); +} + diff --git a/src/gallium/drivers/softpipe/sp_flush.h b/src/gallium/drivers/softpipe/sp_flush.h new file mode 100644 index 0000000000..34ec617866 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_flush.h @@ -0,0 +1,35 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SP_FLUSH_H +#define SP_FLUSH_H + +struct pipe_context; + +void softpipe_flush(struct pipe_context *pipe, unsigned flags ); + +#endif diff --git a/src/gallium/drivers/softpipe/sp_headers.h b/src/gallium/drivers/softpipe/sp_headers.h new file mode 100644 index 0000000000..0ae31d8796 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_headers.h @@ -0,0 +1,82 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_HEADERS_H +#define SP_HEADERS_H + +#include "pipe/tgsi/exec/tgsi_exec.h" + +#define PRIM_POINT 1 +#define PRIM_LINE 2 +#define PRIM_TRI 3 + + +/* The rasterizer generates 2x2 quads of fragment and feeds them to + * the current fp_machine (see below). + * Remember that Y=0=top with Y increasing down the window. + */ +#define QUAD_TOP_LEFT 0 +#define QUAD_TOP_RIGHT 1 +#define QUAD_BOTTOM_LEFT 2 +#define QUAD_BOTTOM_RIGHT 3 + +#define MASK_TOP_LEFT (1 << QUAD_TOP_LEFT) +#define MASK_TOP_RIGHT (1 << QUAD_TOP_RIGHT) +#define MASK_BOTTOM_LEFT (1 << QUAD_BOTTOM_LEFT) +#define MASK_BOTTOM_RIGHT (1 << QUAD_BOTTOM_RIGHT) +#define MASK_ALL 0xf + + +/** + * Encodes everything we need to know about a 2x2 pixel block. Uses + * "Channel-Serial" or "SoA" layout. + */ +struct quad_header { + int x0; + int y0; + unsigned mask:4; + unsigned facing:1; /**< Front (0) or back (1) facing? */ + unsigned prim:2; /**< PRIM_POINT, LINE, TRI */ + + struct { + float color[NUM_CHANNELS][QUAD_SIZE]; /* rrrr, gggg, bbbb, aaaa */ + float depth[QUAD_SIZE]; + } outputs; + + float coverage[QUAD_SIZE]; /** fragment coverage for antialiasing */ + + const struct tgsi_interp_coef *coef; + const struct tgsi_interp_coef *posCoef; + + unsigned nr_attrs; +}; + + +#endif /* SP_HEADERS_H */ diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c new file mode 100644 index 0000000000..2772048661 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -0,0 +1,1247 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Primitive rasterization/rendering (points, lines, triangles) + * + * \author Keith Whitwell + * \author Brian Paul + */ + + +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_quad.h" +#include "sp_state.h" +#include "sp_prim_setup.h" +#include "pipe/draw/draw_private.h" +#include "pipe/draw/draw_vertex.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#define DEBUG_VERTS 0 + +/** + * Triangle edge info + */ +struct edge { + float dx; /**< X(v1) - X(v0), used only during setup */ + float dy; /**< Y(v1) - Y(v0), used only during setup */ + float dxdy; /**< dx/dy */ + float sx, sy; /**< first sample point coord */ + int lines; /**< number of lines on this edge */ +}; + + +/** + * Triangle setup info (derived from draw_stage). + * Also used for line drawing (taking some liberties). + */ +struct setup_stage { + struct draw_stage stage; /**< This must be first (base class) */ + + struct softpipe_context *softpipe; + + /* Vertices are just an array of floats making up each attribute in + * turn. Currently fixed at 4 floats, but should change in time. + * Codegen will help cope with this. + */ + const struct vertex_header *vmax; + const struct vertex_header *vmid; + const struct vertex_header *vmin; + const struct vertex_header *vprovoke; + + struct edge ebot; + struct edge etop; + struct edge emaj; + + float oneoverarea; + + struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS]; + struct tgsi_interp_coef posCoef; /* For Z, W */ + struct quad_header quad; + + struct { + int left[2]; /**< [0] = row0, [1] = row1 */ + int right[2]; + int y; + unsigned y_flags; + unsigned mask; /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */ + } span; +}; + + + +/** + * Basically a cast wrapper. + */ +static INLINE struct setup_stage *setup_stage( struct draw_stage *stage ) +{ + return (struct setup_stage *)stage; +} + + +/** + * Clip setup->quad against the scissor/surface bounds. + */ +static INLINE void +quad_clip(struct setup_stage *setup) +{ + const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect; + const int minx = (int) cliprect->minx; + const int maxx = (int) cliprect->maxx; + const int miny = (int) cliprect->miny; + const int maxy = (int) cliprect->maxy; + + if (setup->quad.x0 >= maxx || + setup->quad.y0 >= maxy || + setup->quad.x0 + 1 < minx || + setup->quad.y0 + 1 < miny) { + /* totally clipped */ + setup->quad.mask = 0x0; + return; + } + if (setup->quad.x0 < minx) + setup->quad.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); + if (setup->quad.y0 < miny) + setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); + if (setup->quad.x0 == maxx - 1) + setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); + if (setup->quad.y0 == maxy - 1) + setup->quad.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); +} + + +/** + * Emit a quad (pass to next stage) with clipping. + */ +static INLINE void +clip_emit_quad(struct setup_stage *setup) +{ + quad_clip(setup); + if (setup->quad.mask) { + struct softpipe_context *sp = setup->softpipe; + sp->quad.first->run(sp->quad.first, &setup->quad); + } +} + + +/** + * Emit a quad (pass to next stage). No clipping is done. + */ +static INLINE void +emit_quad( struct setup_stage *setup, int x, int y, unsigned mask ) +{ + struct softpipe_context *sp = setup->softpipe; + setup->quad.x0 = x; + setup->quad.y0 = y; + setup->quad.mask = mask; + sp->quad.first->run(sp->quad.first, &setup->quad); +} + + +/** + * Given an X or Y coordinate, return the block/quad coordinate that it + * belongs to. + */ +static INLINE int block( int x ) +{ + return x & ~1; +} + + +/** + * Compute mask which indicates which pixels in the 2x2 quad are actually inside + * the triangle's bounds. + * + * this is pretty nasty... may need to rework flush_spans again to + * fix it, if possible. + */ +static unsigned calculate_mask( struct setup_stage *setup, int x ) +{ + unsigned mask = 0x0; + + if (x >= setup->span.left[0] && x < setup->span.right[0]) + mask |= MASK_TOP_LEFT; + + if (x >= setup->span.left[1] && x < setup->span.right[1]) + mask |= MASK_BOTTOM_LEFT; + + if (x+1 >= setup->span.left[0] && x+1 < setup->span.right[0]) + mask |= MASK_TOP_RIGHT; + + if (x+1 >= setup->span.left[1] && x+1 < setup->span.right[1]) + mask |= MASK_BOTTOM_RIGHT; + + return mask; +} + + +/** + * Render a horizontal span of quads + */ +static void flush_spans( struct setup_stage *setup ) +{ + int minleft, maxright; + int x; + + switch (setup->span.y_flags) { + case 0x3: + /* both odd and even lines written (both quad rows) */ + minleft = MIN2(setup->span.left[0], setup->span.left[1]); + maxright = MAX2(setup->span.right[0], setup->span.right[1]); + break; + + case 0x1: + /* only even line written (quad top row) */ + minleft = setup->span.left[0]; + maxright = setup->span.right[0]; + break; + + case 0x2: + /* only odd line written (quad bottom row) */ + minleft = setup->span.left[1]; + maxright = setup->span.right[1]; + break; + + default: + return; + } + + /* XXX this loop could be moved into the above switch cases and + * calculate_mask() could be simplified a bit... + */ + for (x = block(minleft); x <= block(maxright); x += 2) { + emit_quad( setup, x, setup->span.y, + calculate_mask( setup, x ) ); + } + + setup->span.y = 0; + setup->span.y_flags = 0; + setup->span.right[0] = 0; + setup->span.right[1] = 0; +} + +#if DEBUG_VERTS +static void print_vertex(const struct setup_stage *setup, + const struct vertex_header *v) +{ + int i; + debug_printf("Vertex: (%p)\n", v); + for (i = 0; i < setup->quad.nr_attrs; i++) { + debug_printf(" %d: %f %f %f %f\n", i, + v->data[i][0], v->data[i][1], v->data[i][2], v->data[i][3]); + } +} +#endif + +static boolean setup_sort_vertices( struct setup_stage *setup, + const struct prim_header *prim ) +{ + const struct vertex_header *v0 = prim->v[0]; + const struct vertex_header *v1 = prim->v[1]; + const struct vertex_header *v2 = prim->v[2]; + +#if DEBUG_VERTS + debug_printf("Triangle:\n"); + print_vertex(setup, v0); + print_vertex(setup, v1); + print_vertex(setup, v2); +#endif + + setup->vprovoke = v2; + + /* determine bottom to top order of vertices */ + { + float y0 = v0->data[0][1]; + float y1 = v1->data[0][1]; + float y2 = v2->data[0][1]; + if (y0 <= y1) { + if (y1 <= y2) { + /* y0<=y1<=y2 */ + setup->vmin = v0; + setup->vmid = v1; + setup->vmax = v2; + } + else if (y2 <= y0) { + /* y2<=y0<=y1 */ + setup->vmin = v2; + setup->vmid = v0; + setup->vmax = v1; + } + else { + /* y0<=y2<=y1 */ + setup->vmin = v0; + setup->vmid = v2; + setup->vmax = v1; + } + } + else { + if (y0 <= y2) { + /* y1<=y0<=y2 */ + setup->vmin = v1; + setup->vmid = v0; + setup->vmax = v2; + } + else if (y2 <= y1) { + /* y2<=y1<=y0 */ + setup->vmin = v2; + setup->vmid = v1; + setup->vmax = v0; + } + else { + /* y1<=y2<=y0 */ + setup->vmin = v1; + setup->vmid = v2; + setup->vmax = v0; + } + } + } + + setup->ebot.dx = setup->vmid->data[0][0] - setup->vmin->data[0][0]; + setup->ebot.dy = setup->vmid->data[0][1] - setup->vmin->data[0][1]; + setup->emaj.dx = setup->vmax->data[0][0] - setup->vmin->data[0][0]; + setup->emaj.dy = setup->vmax->data[0][1] - setup->vmin->data[0][1]; + setup->etop.dx = setup->vmax->data[0][0] - setup->vmid->data[0][0]; + setup->etop.dy = setup->vmax->data[0][1] - setup->vmid->data[0][1]; + + /* + * Compute triangle's area. Use 1/area to compute partial + * derivatives of attributes later. + * + * The area will be the same as prim->det, but the sign may be + * different depending on how the vertices get sorted above. + * + * To determine whether the primitive is front or back facing we + * use the prim->det value because its sign is correct. + */ + { + const float area = (setup->emaj.dx * setup->ebot.dy - + setup->ebot.dx * setup->emaj.dy); + + setup->oneoverarea = 1.0f / area; + /* + debug_printf("%s one-over-area %f area %f det %f\n", + __FUNCTION__, setup->oneoverarea, area, prim->det ); + */ + } + + /* We need to know if this is a front or back-facing triangle for: + * - the GLSL gl_FrontFacing fragment attribute (bool) + * - two-sided stencil test + */ + setup->quad.facing = (prim->det > 0.0) ^ (setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW); + + return TRUE; +} + + +/** + * Compute a0 for a constant-valued coefficient (GL_FLAT shading). + * The value value comes from vertex->data[slot][i]. + * The result will be put into setup->coef[slot].a0[i]. + * \param slot which attribute slot + * \param i which component of the slot (0..3) + */ +static void const_coeff( struct setup_stage *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + assert(i <= 3); + + coef->dadx[i] = 0; + coef->dady[i] = 0; + + /* need provoking vertex info! + */ + coef->a0[i] = setup->vprovoke->data[vertSlot][i]; +} + + +/** + * Compute a0, dadx and dady for a linearly interpolated coefficient, + * for a triangle. + */ +static void tri_linear_coeff( struct setup_stage *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + float botda = setup->vmid->data[vertSlot][i] - setup->vmin->data[vertSlot][i]; + float majda = setup->vmax->data[vertSlot][i] - setup->vmin->data[vertSlot][i]; + float a = setup->ebot.dy * majda - botda * setup->emaj.dy; + float b = setup->emaj.dx * botda - majda * setup->ebot.dx; + float dadx = a * setup->oneoverarea; + float dady = b * setup->oneoverarea; + + assert(i <= 3); + + coef->dadx[i] = dadx; + coef->dady[i] = dady; + + /* calculate a0 as the value which would be sampled for the + * fragment at (0,0), taking into account that we want to sample at + * pixel centers, in other words (0.5, 0.5). + * + * this is neat but unfortunately not a good way to do things for + * triangles with very large values of dadx or dady as it will + * result in the subtraction and re-addition from a0 of a very + * large number, which means we'll end up loosing a lot of the + * fractional bits and precision from a0. the way to fix this is + * to define a0 as the sample at a pixel center somewhere near vmin + * instead - i'll switch to this later. + */ + coef->a0[i] = (setup->vmin->data[vertSlot][i] - + (dadx * (setup->vmin->data[0][0] - 0.5f) + + dady * (setup->vmin->data[0][1] - 0.5f))); + + /* + debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", + slot, "xyzw"[i], + setup->coef[slot].a0[i], + setup->coef[slot].dadx[i], + setup->coef[slot].dady[i]); + */ +} + + +/** + * Compute a0, dadx and dady for a perspective-corrected interpolant, + * for a triangle. + * We basically multiply the vertex value by 1/w before computing + * the plane coefficients (a0, dadx, dady). + * Later, when we compute the value at a particular fragment position we'll + * divide the interpolated value by the interpolated W at that fragment. + */ +static void tri_persp_coeff( struct setup_stage *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + /* premultiply by 1/w (v->data[0][3] is always W): + */ + float mina = setup->vmin->data[vertSlot][i] * setup->vmin->data[0][3]; + float mida = setup->vmid->data[vertSlot][i] * setup->vmid->data[0][3]; + float maxa = setup->vmax->data[vertSlot][i] * setup->vmax->data[0][3]; + float botda = mida - mina; + float majda = maxa - mina; + float a = setup->ebot.dy * majda - botda * setup->emaj.dy; + float b = setup->emaj.dx * botda - majda * setup->ebot.dx; + float dadx = a * setup->oneoverarea; + float dady = b * setup->oneoverarea; + + /* + debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i, + setup->vmin->data[vertSlot][i], + setup->vmid->data[vertSlot][i], + setup->vmax->data[vertSlot][i] + ); + */ + assert(i <= 3); + + coef->dadx[i] = dadx; + coef->dady[i] = dady; + coef->a0[i] = (mina - + (dadx * (setup->vmin->data[0][0] - 0.5f) + + dady * (setup->vmin->data[0][1] - 0.5f))); +} + + +/** + * Special coefficient setup for gl_FragCoord. + * X and Y are trivial, though Y has to be inverted for OpenGL. + * Z and W are copied from posCoef which should have already been computed. + * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. + */ +static void +setup_fragcoord_coeff(struct setup_stage *setup) +{ + /*X*/ + setup->coef[0].a0[0] = 0; + setup->coef[0].dadx[0] = 1.0; + setup->coef[0].dady[0] = 0.0; + /*Y*/ + if (setup->softpipe->rasterizer->origin_lower_left) { + /* y=0=bottom */ + const int winHeight = setup->softpipe->framebuffer.cbufs[0]->height; + setup->coef[0].a0[1] = (float) (winHeight - 1); + setup->coef[0].dady[1] = -1.0; + } + else { + /* y=0=top */ + setup->coef[0].a0[1] = 0.0; + setup->coef[0].dady[1] = 1.0; + } + setup->coef[0].dadx[1] = 0.0; + /*Z*/ + setup->coef[0].a0[2] = setup->posCoef.a0[2]; + setup->coef[0].dadx[2] = setup->posCoef.dadx[2]; + setup->coef[0].dady[2] = setup->posCoef.dady[2]; + /*W*/ + setup->coef[0].a0[3] = setup->posCoef.a0[3]; + setup->coef[0].dadx[3] = setup->posCoef.dadx[3]; + setup->coef[0].dady[3] = setup->posCoef.dady[3]; +} + + + +/** + * Compute the setup->coef[] array dadx, dady, a0 values. + * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized. + */ +static void setup_tri_coefficients( struct setup_stage *setup ) +{ + struct softpipe_context *softpipe = setup->softpipe; + const struct pipe_shader_state *fs = &softpipe->fs->shader; + const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); + uint fragSlot; + + /* z and w are done by linear interpolation: + */ + tri_linear_coeff(setup, &setup->posCoef, 0, 2); + tri_linear_coeff(setup, &setup->posCoef, 0, 3); + + /* setup interpolation for all the remaining attributes: + */ + for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) { + const uint vertSlot = vinfo->src_index[fragSlot]; + uint j; + + switch (vinfo->interp_mode[fragSlot]) { + case INTERP_CONSTANT: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + assert(fragSlot == 0); + setup_fragcoord_coeff(setup); + break; + default: + assert(0); + } + + if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + /* FOG.y = front/back facing XXX fix this */ + setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; + setup->coef[fragSlot].dadx[1] = 0.0; + setup->coef[fragSlot].dady[1] = 0.0; + } + } +} + + + +static void setup_tri_edges( struct setup_stage *setup ) +{ + float vmin_x = setup->vmin->data[0][0] + 0.5f; + float vmid_x = setup->vmid->data[0][0] + 0.5f; + + float vmin_y = setup->vmin->data[0][1] - 0.5f; + float vmid_y = setup->vmid->data[0][1] - 0.5f; + float vmax_y = setup->vmax->data[0][1] - 0.5f; + + setup->emaj.sy = CEILF(vmin_y); + setup->emaj.lines = (int) CEILF(vmax_y - setup->emaj.sy); + setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy; + setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; + + setup->etop.sy = CEILF(vmid_y); + setup->etop.lines = (int) CEILF(vmax_y - setup->etop.sy); + setup->etop.dxdy = setup->etop.dx / setup->etop.dy; + setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; + + setup->ebot.sy = CEILF(vmin_y); + setup->ebot.lines = (int) CEILF(vmid_y - setup->ebot.sy); + setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy; + setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; +} + + +/** + * Render the upper or lower half of a triangle. + * Scissoring/cliprect is applied here too. + */ +static void subtriangle( struct setup_stage *setup, + struct edge *eleft, + struct edge *eright, + unsigned lines ) +{ + const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect; + const int minx = (int) cliprect->minx; + const int maxx = (int) cliprect->maxx; + const int miny = (int) cliprect->miny; + const int maxy = (int) cliprect->maxy; + int y, start_y, finish_y; + int sy = (int)eleft->sy; + + assert((int)eleft->sy == (int) eright->sy); + + /* clip top/bottom */ + start_y = sy; + finish_y = sy + lines; + + if (start_y < miny) + start_y = miny; + + if (finish_y > maxy) + finish_y = maxy; + + start_y -= sy; + finish_y -= sy; + + /* + debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); + */ + + for (y = start_y; y < finish_y; y++) { + + /* avoid accumulating adds as floats don't have the precision to + * accurately iterate large triangle edges that way. luckily we + * can just multiply these days. + * + * this is all drowned out by the attribute interpolation anyway. + */ + int left = (int)(eleft->sx + y * eleft->dxdy); + int right = (int)(eright->sx + y * eright->dxdy); + + /* clip left/right */ + if (left < minx) + left = minx; + if (right > maxx) + right = maxx; + + if (left < right) { + int _y = sy + y; + if (block(_y) != setup->span.y) { + flush_spans(setup); + setup->span.y = block(_y); + } + + setup->span.left[_y&1] = left; + setup->span.right[_y&1] = right; + setup->span.y_flags |= 1<<(_y&1); + } + } + + + /* save the values so that emaj can be restarted: + */ + eleft->sx += lines * eleft->dxdy; + eright->sx += lines * eright->dxdy; + eleft->sy += lines; + eright->sy += lines; +} + + +/** + * Do setup for triangle rasterization, then render the triangle. + */ +static void setup_tri( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct setup_stage *setup = setup_stage( stage ); + + /* + debug_printf("%s\n", __FUNCTION__ ); + */ + + setup_sort_vertices( setup, prim ); + setup_tri_coefficients( setup ); + setup_tri_edges( setup ); + + setup->quad.prim = PRIM_TRI; + + setup->span.y = 0; + setup->span.y_flags = 0; + setup->span.right[0] = 0; + setup->span.right[1] = 0; + /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ + + /* init_constant_attribs( setup ); */ + + if (setup->oneoverarea < 0.0) { + /* emaj on left: + */ + subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); + subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); + } + else { + /* emaj on right: + */ + subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); + subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); + } + + flush_spans( setup ); +} + + + +/** + * Compute a0, dadx and dady for a linearly interpolated coefficient, + * for a line. + */ +static void +line_linear_coeff(struct setup_stage *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + const float da = setup->vmax->data[vertSlot][i] - setup->vmin->data[vertSlot][i]; + const float dadx = da * setup->emaj.dx * setup->oneoverarea; + const float dady = da * setup->emaj.dy * setup->oneoverarea; + coef->dadx[i] = dadx; + coef->dady[i] = dady; + coef->a0[i] = (setup->vmin->data[vertSlot][i] - + (dadx * (setup->vmin->data[0][0] - 0.5f) + + dady * (setup->vmin->data[0][1] - 0.5f))); +} + + +/** + * Compute a0, dadx and dady for a perspective-corrected interpolant, + * for a line. + */ +static void +line_persp_coeff(struct setup_stage *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + /* XXX double-check/verify this arithmetic */ + const float a0 = setup->vmin->data[vertSlot][i] * setup->vmin->data[0][3]; + const float a1 = setup->vmax->data[vertSlot][i] * setup->vmax->data[0][3]; + const float da = a1 - a0; + const float dadx = da * setup->emaj.dx * setup->oneoverarea; + const float dady = da * setup->emaj.dy * setup->oneoverarea; + coef->dadx[i] = dadx; + coef->dady[i] = dady; + coef->a0[i] = (setup->vmin->data[vertSlot][i] - + (dadx * (setup->vmin->data[0][0] - 0.5f) + + dady * (setup->vmin->data[0][1] - 0.5f))); +} + + +/** + * Compute the setup->coef[] array dadx, dady, a0 values. + * Must be called after setup->vmin,vmax are initialized. + */ +static INLINE void +setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim) +{ + struct softpipe_context *softpipe = setup->softpipe; + const struct pipe_shader_state *fs = &setup->softpipe->fs->shader; + const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); + uint fragSlot; + + /* use setup->vmin, vmax to point to vertices */ + setup->vprovoke = prim->v[1]; + setup->vmin = prim->v[0]; + setup->vmax = prim->v[1]; + + setup->emaj.dx = setup->vmax->data[0][0] - setup->vmin->data[0][0]; + setup->emaj.dy = setup->vmax->data[0][1] - setup->vmin->data[0][1]; + /* NOTE: this is not really 1/area */ + setup->oneoverarea = 1.0f / (setup->emaj.dx * setup->emaj.dx + + setup->emaj.dy * setup->emaj.dy); + + /* z and w are done by linear interpolation: + */ + line_linear_coeff(setup, &setup->posCoef, 0, 2); + line_linear_coeff(setup, &setup->posCoef, 0, 3); + + /* setup interpolation for all the remaining attributes: + */ + for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) { + const uint vertSlot = vinfo->src_index[fragSlot]; + uint j; + + switch (vinfo->interp_mode[fragSlot]) { + case INTERP_CONSTANT: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + assert(fragSlot == 0); + assert(0); /* XXX fix this: */ + setup_fragcoord_coeff(setup); + break; + default: + assert(0); + } + + if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + /* FOG.y = front/back facing XXX fix this */ + setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; + setup->coef[fragSlot].dadx[1] = 0.0; + setup->coef[fragSlot].dady[1] = 0.0; + } + } +} + + +/** + * Plot a pixel in a line segment. + */ +static INLINE void +plot(struct setup_stage *setup, int x, int y) +{ + const int iy = y & 1; + const int ix = x & 1; + const int quadX = x - ix; + const int quadY = y - iy; + const int mask = (1 << ix) << (2 * iy); + + if (quadX != setup->quad.x0 || + quadY != setup->quad.y0) + { + /* flush prev quad, start new quad */ + + if (setup->quad.x0 != -1) + clip_emit_quad(setup); + + setup->quad.x0 = quadX; + setup->quad.y0 = quadY; + setup->quad.mask = 0x0; + } + + setup->quad.mask |= mask; +} + + +/** + * Do setup for line rasterization, then render the line. + * Single-pixel width, no stipple, etc. We rely on the 'draw' module + * to handle stippling and wide lines. + */ +static void +setup_line(struct draw_stage *stage, struct prim_header *prim) +{ + const struct vertex_header *v0 = prim->v[0]; + const struct vertex_header *v1 = prim->v[1]; + struct setup_stage *setup = setup_stage( stage ); + int x0 = (int) v0->data[0][0]; + int x1 = (int) v1->data[0][0]; + int y0 = (int) v0->data[0][1]; + int y1 = (int) v1->data[0][1]; + int dx = x1 - x0; + int dy = y1 - y0; + int xstep, ystep; + + if (dx == 0 && dy == 0) + return; + + setup_line_coefficients(setup, prim); + + if (dx < 0) { + dx = -dx; /* make positive */ + xstep = -1; + } + else { + xstep = 1; + } + + if (dy < 0) { + dy = -dy; /* make positive */ + ystep = -1; + } + else { + ystep = 1; + } + + assert(dx >= 0); + assert(dy >= 0); + + setup->quad.x0 = setup->quad.y0 = -1; + setup->quad.mask = 0x0; + setup->quad.prim = PRIM_LINE; + /* XXX temporary: set coverage to 1.0 so the line appears + * if AA mode happens to be enabled. + */ + setup->quad.coverage[0] = + setup->quad.coverage[1] = + setup->quad.coverage[2] = + setup->quad.coverage[3] = 1.0; + + if (dx > dy) { + /*** X-major line ***/ + int i; + const int errorInc = dy + dy; + int error = errorInc - dx; + const int errorDec = error - dx; + + for (i = 0; i < dx; i++) { + plot(setup, x0, y0); + + x0 += xstep; + if (error < 0) { + error += errorInc; + } + else { + error += errorDec; + y0 += ystep; + } + } + } + else { + /*** Y-major line ***/ + int i; + const int errorInc = dx + dx; + int error = errorInc - dy; + const int errorDec = error - dy; + + for (i = 0; i < dy; i++) { + plot(setup, x0, y0); + + y0 += ystep; + if (error < 0) { + error += errorInc; + } + else { + error += errorDec; + x0 += xstep; + } + } + } + + /* draw final quad */ + if (setup->quad.mask) { + clip_emit_quad(setup); + } +} + + +static void +point_persp_coeff(struct setup_stage *setup, + const struct vertex_header *vert, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + assert(i <= 3); + coef->dadx[i] = 0.0F; + coef->dady[i] = 0.0F; + coef->a0[i] = vert->data[vertSlot][i] * vert->data[0][3]; +} + + +/** + * Do setup for point rasterization, then render the point. + * Round or square points... + * XXX could optimize a lot for 1-pixel points. + */ +static void +setup_point(struct draw_stage *stage, struct prim_header *prim) +{ + struct setup_stage *setup = setup_stage( stage ); + struct softpipe_context *softpipe = setup->softpipe; + const struct pipe_shader_state *fs = &softpipe->fs->shader; + const struct vertex_header *v0 = prim->v[0]; + const int sizeAttr = setup->softpipe->psize_slot; + const float size + = sizeAttr > 0 ? v0->data[sizeAttr][0] + : setup->softpipe->rasterizer->point_size; + const float halfSize = 0.5F * size; + const boolean round = (boolean) setup->softpipe->rasterizer->point_smooth; + const float x = v0->data[0][0]; /* Note: data[0] is always position */ + const float y = v0->data[0][1]; + const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); + uint fragSlot; + + /* For points, all interpolants are constant-valued. + * However, for point sprites, we'll need to setup texcoords appropriately. + * XXX: which coefficients are the texcoords??? + * We may do point sprites as textured quads... + * + * KW: We don't know which coefficients are texcoords - ultimately + * the choice of what interpolation mode to use for each attribute + * should be determined by the fragment program, using + * per-attribute declaration statements that include interpolation + * mode as a parameter. So either the fragment program will have + * to be adjusted for pointsprite vs normal point behaviour, or + * otherwise a special interpolation mode will have to be defined + * which matches the required behaviour for point sprites. But - + * the latter is not a feature of normal hardware, and as such + * probably should be ruled out on that basis. + */ + setup->vprovoke = prim->v[0]; + + /* setup Z, W */ + const_coeff(setup, &setup->posCoef, 0, 2); + const_coeff(setup, &setup->posCoef, 0, 3); + + for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) { + const uint vertSlot = vinfo->src_index[fragSlot]; + uint j; + + switch (vinfo->interp_mode[fragSlot]) { + case INTERP_CONSTANT: + /* fall-through */ + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + point_persp_coeff(setup, setup->vprovoke, + &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + assert(fragSlot == 0); + assert(0); /* XXX fix this: */ + setup_fragcoord_coeff(setup); + break; + default: + assert(0); + } + + if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + /* FOG.y = front/back facing XXX fix this */ + setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; + setup->coef[fragSlot].dadx[1] = 0.0; + setup->coef[fragSlot].dady[1] = 0.0; + } + } + + setup->quad.prim = PRIM_POINT; + + if (halfSize <= 0.5 && !round) { + /* special case for 1-pixel points */ + const int ix = ((int) x) & 1; + const int iy = ((int) y) & 1; + setup->quad.x0 = (int) x - ix; + setup->quad.y0 = (int) y - iy; + setup->quad.mask = (1 << ix) << (2 * iy); + clip_emit_quad(setup); + } + else { + if (round) { + /* rounded points */ + const int ixmin = block((int) (x - halfSize)); + const int ixmax = block((int) (x + halfSize)); + const int iymin = block((int) (y - halfSize)); + const int iymax = block((int) (y + halfSize)); + const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ + const float rmax = halfSize + 0.7071F; + const float rmin2 = MAX2(0.0F, rmin * rmin); + const float rmax2 = rmax * rmax; + const float cscale = 1.0F / (rmax2 - rmin2); + int ix, iy; + + for (iy = iymin; iy <= iymax; iy += 2) { + for (ix = ixmin; ix <= ixmax; ix += 2) { + float dx, dy, dist2, cover; + + setup->quad.mask = 0x0; + + dx = (ix + 0.5f) - x; + dy = (iy + 0.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); + setup->quad.mask |= MASK_TOP_LEFT; + } + + dx = (ix + 1.5f) - x; + dy = (iy + 0.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); + setup->quad.mask |= MASK_TOP_RIGHT; + } + + dx = (ix + 0.5f) - x; + dy = (iy + 1.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); + setup->quad.mask |= MASK_BOTTOM_LEFT; + } + + dx = (ix + 1.5f) - x; + dy = (iy + 1.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); + setup->quad.mask |= MASK_BOTTOM_RIGHT; + } + + if (setup->quad.mask) { + setup->quad.x0 = ix; + setup->quad.y0 = iy; + clip_emit_quad(setup); + } + } + } + } + else { + /* square points */ + const int xmin = (int) (x + 0.75 - halfSize); + const int ymin = (int) (y + 0.25 - halfSize); + const int xmax = xmin + (int) size; + const int ymax = ymin + (int) size; + /* XXX could apply scissor to xmin,ymin,xmax,ymax now */ + const int ixmin = block(xmin); + const int ixmax = block(xmax - 1); + const int iymin = block(ymin); + const int iymax = block(ymax - 1); + int ix, iy; + + /* + debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax); + */ + for (iy = iymin; iy <= iymax; iy += 2) { + uint rowMask = 0xf; + if (iy < ymin) { + /* above the top edge */ + rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); + } + if (iy + 1 >= ymax) { + /* below the bottom edge */ + rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); + } + + for (ix = ixmin; ix <= ixmax; ix += 2) { + uint mask = rowMask; + + if (ix < xmin) { + /* fragment is past left edge of point, turn off left bits */ + mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); + } + if (ix + 1 >= xmax) { + /* past the right edge */ + mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); + } + + setup->quad.mask = mask; + setup->quad.x0 = ix; + setup->quad.y0 = iy; + clip_emit_quad(setup); + } + } + } + } +} + + + +static void setup_begin( struct draw_stage *stage ) +{ + struct setup_stage *setup = setup_stage(stage); + struct softpipe_context *sp = setup->softpipe; + const struct pipe_shader_state *fs = &setup->softpipe->fs->shader; + + setup->quad.nr_attrs = fs->num_inputs; + + sp->quad.first->begin(sp->quad.first); + + stage->point = setup_point; + stage->line = setup_line; + stage->tri = setup_tri; +} + + +static void setup_first_point( struct draw_stage *stage, + struct prim_header *header ) +{ + setup_begin(stage); + stage->point( stage, header ); +} + +static void setup_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + setup_begin(stage); + stage->line( stage, header ); +} + + +static void setup_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + setup_begin(stage); + stage->tri( stage, header ); +} + + + +static void setup_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->point = setup_first_point; + stage->line = setup_first_line; + stage->tri = setup_first_tri; +} + + +static void reset_stipple_counter( struct draw_stage *stage ) +{ +} + + +static void render_destroy( struct draw_stage *stage ) +{ + FREE( stage ); +} + + +/** + * Create a new primitive setup/render stage. + */ +struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe ) +{ + struct setup_stage *setup = CALLOC_STRUCT(setup_stage); + + setup->softpipe = softpipe; + setup->stage.draw = softpipe->draw; + setup->stage.point = setup_first_point; + setup->stage.line = setup_first_line; + setup->stage.tri = setup_first_tri; + setup->stage.flush = setup_flush; + setup->stage.reset_stipple_counter = reset_stipple_counter; + setup->stage.destroy = render_destroy; + + setup->quad.coef = setup->coef; + setup->quad.posCoef = &setup->posCoef; + + return &setup->stage; +} diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.h b/src/gallium/drivers/softpipe/sp_prim_setup.h new file mode 100644 index 0000000000..f3e8a79dd9 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_prim_setup.h @@ -0,0 +1,79 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef SP_PRIM_SETUP_H +#define SP_PRIM_SETUP_H + + +/** + * vbuf is a special stage to gather the stream of triangles, lines, points + * together and reconstruct vertex buffers for hardware upload. + * + * First attempt, work in progress. + * + * TODO: + * - separate out vertex buffer building and primitive emit, ie >1 draw per vb. + * - tell vbuf stage how to build hw vertices directly + * - pass vbuf stage a buffer pointer for direct emit to agp/vram. + * + * + * + * Vertices are just an array of floats, with all the attributes + * packed. We currently assume a layout like: + * + * attr[0][0..3] - window position + * attr[1..n][0..3] - remaining attributes. + * + * Attributes are assumed to be 4 floats wide but are packed so that + * all the enabled attributes run contiguously. + */ + + +struct draw_stage; +struct softpipe_context; + + +typedef void (*vbuf_draw_func)( struct pipe_context *pipe, + unsigned prim, + const ushort *elements, + unsigned nr_elements, + const void *vertex_buffer, + unsigned nr_vertices ); + + +extern struct draw_stage * +sp_draw_render_stage( struct softpipe_context *softpipe ); + + +extern struct draw_stage * +sp_draw_vbuf_stage( struct draw_context *draw_context, + struct pipe_context *pipe, + vbuf_draw_func draw ); + + +#endif /* SP_PRIM_SETUP_H */ diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c new file mode 100644 index 0000000000..7f71fdb6a9 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -0,0 +1,221 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Post-transform vertex buffering. This is an optional part of the + * softpipe rendering pipeline. + * Probably not desired in general, but useful for testing/debuggin. + * Enabled/Disabled with SP_VBUF env var. + * + * Authors + * Brian Paul + */ + + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_prim_vbuf.h" +#include "pipe/draw/draw_context.h" +#include "pipe/draw/draw_private.h" +#include "pipe/draw/draw_vbuf.h" + + +#define SP_MAX_VBUF_INDEXES 1024 +#define SP_MAX_VBUF_SIZE 4096 + + +/** + * Subclass of vbuf_render. + */ +struct softpipe_vbuf_render +{ + struct vbuf_render base; + struct softpipe_context *softpipe; + uint prim; + uint vertex_size; + void *vertex_buffer; +}; + + +/** cast wrapper */ +static struct softpipe_vbuf_render * +softpipe_vbuf_render(struct vbuf_render *vbr) +{ + return (struct softpipe_vbuf_render *) vbr; +} + + + +static const struct vertex_info * +sp_vbuf_get_vertex_info(struct vbuf_render *vbr) +{ + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + return softpipe_get_vbuf_vertex_info(cvbr->softpipe); +} + + +static void * +sp_vbuf_allocate_vertices(struct vbuf_render *vbr, + ushort vertex_size, ushort nr_vertices) +{ + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + assert(!cvbr->vertex_buffer); + cvbr->vertex_buffer = align_malloc(vertex_size * nr_vertices, 16); + cvbr->vertex_size = vertex_size; + return cvbr->vertex_buffer; +} + + +static void +sp_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices, + unsigned vertex_size, unsigned vertices_used) +{ + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + align_free(vertices); + assert(vertices == cvbr->vertex_buffer); + cvbr->vertex_buffer = NULL; +} + + +static void +sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) +{ + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + cvbr->prim = prim; +} + + +/** + * Recalculate prim's determinant. + * XXX is this needed? + */ +static void +calc_det(struct prim_header *header) +{ + /* Window coords: */ + const float *v0 = header->v[0]->data[0]; + const float *v1 = header->v[1]->data[0]; + const float *v2 = header->v[2]->data[0]; + + /* edge vectors e = v0 - v2, f = v1 - v2 */ + const float ex = v0[0] - v2[0]; + const float ey = v0[1] - v2[1]; + const float fx = v1[0] - v2[0]; + const float fy = v1[1] - v2[1]; + + /* det = cross(e,f).z */ + header->det = ex * fy - ey * fx; +} + + +static void +sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) +{ + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + struct softpipe_context *softpipe = cvbr->softpipe; + struct draw_stage *setup = softpipe->setup; + struct prim_header prim; + unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float); + unsigned i, j; + void *vertex_buffer = cvbr->vertex_buffer; + + prim.det = 0; + prim.reset_line_stipple = 0; + prim.edgeflags = 0; + prim.pad = 0; + + switch (cvbr->prim) { + case PIPE_PRIM_TRIANGLES: + for (i = 0; i < nr_indices; i += 3) { + for (j = 0; j < 3; j++) + prim.v[j] = (struct vertex_header *)((char *)vertex_buffer + + indices[i+j] * vertex_size); + + calc_det(&prim); + setup->tri( setup, &prim ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 0; i < nr_indices; i += 2) { + for (j = 0; j < 2; j++) + prim.v[j] = (struct vertex_header *)((char *)vertex_buffer + + indices[i+j] * vertex_size); + + setup->line( setup, &prim ); + } + break; + + case PIPE_PRIM_POINTS: + for (i = 0; i < nr_indices; i++) { + prim.v[0] = (struct vertex_header *)((char *)vertex_buffer + + indices[i] * vertex_size); + setup->point( setup, &prim ); + } + break; + } + + setup->flush( setup, 0 ); +} + + +static void +sp_vbuf_destroy(struct vbuf_render *vbr) +{ + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + cvbr->softpipe->vbuf_render = NULL; + FREE(cvbr); +} + + +/** + * Initialize the post-transform vertex buffer information for the given + * context. + */ +void +sp_init_vbuf(struct softpipe_context *sp) +{ + assert(sp->draw); + + sp->vbuf_render = CALLOC_STRUCT(softpipe_vbuf_render); + + sp->vbuf_render->base.max_indices = SP_MAX_VBUF_INDEXES; + sp->vbuf_render->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE; + + sp->vbuf_render->base.get_vertex_info = sp_vbuf_get_vertex_info; + sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices; + sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive; + sp->vbuf_render->base.draw = sp_vbuf_draw; + sp->vbuf_render->base.release_vertices = sp_vbuf_release_vertices; + sp->vbuf_render->base.destroy = sp_vbuf_destroy; + + sp->vbuf_render->softpipe = sp; + + sp->vbuf = draw_vbuf_stage(sp->draw, &sp->vbuf_render->base); + + draw_set_rasterize_stage(sp->draw, sp->vbuf); +} diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.h b/src/gallium/drivers/softpipe/sp_prim_vbuf.h new file mode 100644 index 0000000000..1de9cc2a89 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SP_VBUF_H +#define SP_VBUF_H + + +struct softpipe_context; + +extern void +sp_init_vbuf(struct softpipe_context *softpipe); + + +#endif /* SP_VBUF_H */ diff --git a/src/gallium/drivers/softpipe/sp_quad.c b/src/gallium/drivers/softpipe/sp_quad.c new file mode 100644 index 0000000000..6bd468a51c --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad.c @@ -0,0 +1,118 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "sp_context.h" +#include "sp_state.h" +#include "pipe/p_shader_tokens.h" + +static void +sp_push_quad_first( + struct softpipe_context *sp, + struct quad_stage *quad ) +{ + quad->next = sp->quad.first; + sp->quad.first = quad; +} + +static void +sp_build_depth_stencil( + struct softpipe_context *sp ) +{ + if (sp->depth_stencil->stencil[0].enabled || + sp->depth_stencil->stencil[1].enabled) { + sp_push_quad_first( sp, sp->quad.stencil_test ); + } + else if (sp->depth_stencil->depth.enabled && + sp->framebuffer.zsbuf) { + sp_push_quad_first( sp, sp->quad.depth_test ); + } +} + +void +sp_build_quad_pipeline(struct softpipe_context *sp) +{ + boolean early_depth_test = + sp->depth_stencil->depth.enabled && + sp->framebuffer.zsbuf && + !sp->depth_stencil->alpha.enabled && + sp->fs->shader.output_semantic_name[0] != TGSI_SEMANTIC_POSITION; + + /* build up the pipeline in reverse order... */ + + sp->quad.first = sp->quad.output; + + if (sp->blend->colormask != 0xf) { + sp_push_quad_first( sp, sp->quad.colormask ); + } + + if (sp->blend->blend_enable || + sp->blend->logicop_enable) { + sp_push_quad_first( sp, sp->quad.blend ); + } + + if (sp->framebuffer.num_cbufs == 1) { + /* the usual case: write to exactly one colorbuf */ + sp->current_cbuf = 0; + } + else { + /* insert bufloop stage */ + sp_push_quad_first( sp, sp->quad.bufloop ); + } + + if (sp->depth_stencil->depth.occlusion_count) { + sp_push_quad_first( sp, sp->quad.occlusion ); + } + + if (sp->rasterizer->poly_smooth || + sp->rasterizer->line_smooth || + sp->rasterizer->point_smooth) { + sp_push_quad_first( sp, sp->quad.coverage ); + } + + if (!early_depth_test) { + sp_build_depth_stencil( sp ); + } + + if (sp->depth_stencil->alpha.enabled) { + sp_push_quad_first( sp, sp->quad.alpha_test ); + } + + /* XXX always enable shader? */ + if (1) { + sp_push_quad_first( sp, sp->quad.shade ); + } + + if (early_depth_test) { + sp_build_depth_stencil( sp ); + sp_push_quad_first( sp, sp->quad.earlyz ); + } + + if (sp->rasterizer->poly_stipple_enable) { + sp_push_quad_first( sp, sp->quad.polygon_stipple ); + } +} diff --git a/src/gallium/drivers/softpipe/sp_quad.h b/src/gallium/drivers/softpipe/sp_quad.h new file mode 100644 index 0000000000..f1e0281764 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad.h @@ -0,0 +1,70 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_QUAD_H +#define SP_QUAD_H + + +struct softpipe_context; +struct quad_header; + + +struct quad_stage { + struct softpipe_context *softpipe; + + struct quad_stage *next; + + void (*begin)(struct quad_stage *qs); + + /** the stage action */ + void (*run)(struct quad_stage *qs, struct quad_header *quad); + + void (*destroy)(struct quad_stage *qs); +}; + + +struct quad_stage *sp_quad_polygon_stipple_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_earlyz_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_alpha_test_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_bufloop_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe ); + +void sp_build_quad_pipeline(struct softpipe_context *sp); + +void sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad); + +#endif /* SP_QUAD_H */ diff --git a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c new file mode 100644 index 0000000000..4ffeac35e1 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c @@ -0,0 +1,108 @@ + +/** + * quad alpha test + */ + +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_quad.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" + + +static void +alpha_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + const float ref = softpipe->depth_stencil->alpha.ref; + unsigned passMask = 0x0, j; + const float *aaaa = quad->outputs.color[3]; + + switch (softpipe->depth_stencil->alpha.func) { + case PIPE_FUNC_NEVER: + quad->mask = 0x0; + break; + case PIPE_FUNC_LESS: + /* + * If mask were an array [4] we could do this SIMD-style: + * passMask = (quad->outputs.color[3] <= vec4(ref)); + */ + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] < ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_EQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] == ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_LEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] <= ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GREATER: + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] > ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_NOTEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] != ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] >= ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_ALWAYS: + passMask = MASK_ALL; + break; + default: + abort(); + } + + quad->mask &= passMask; + + if (quad->mask) + qs->next->run(qs->next, quad); +} + + +static void alpha_test_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void alpha_test_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage * +sp_quad_alpha_test_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->begin = alpha_test_begin; + stage->run = alpha_test_quad; + stage->destroy = alpha_test_destroy; + + return stage; +} diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c new file mode 100644 index 0000000000..17f3ecd0b8 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -0,0 +1,749 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * quad blending + * \author Brian Paul + */ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_tile_cache.h" +#include "sp_quad.h" + + +#define VEC4_COPY(DST, SRC) \ +do { \ + DST[0] = SRC[0]; \ + DST[1] = SRC[1]; \ + DST[2] = SRC[2]; \ + DST[3] = SRC[3]; \ +} while(0) + +#define VEC4_SCALAR(DST, SRC) \ +do { \ + DST[0] = SRC; \ + DST[1] = SRC; \ + DST[2] = SRC; \ + DST[3] = SRC; \ +} while(0) + +#define VEC4_ADD(R, A, B) \ +do { \ + R[0] = A[0] + B[0]; \ + R[1] = A[1] + B[1]; \ + R[2] = A[2] + B[2]; \ + R[3] = A[3] + B[3]; \ +} while (0) + +#define VEC4_SUB(R, A, B) \ +do { \ + R[0] = A[0] - B[0]; \ + R[1] = A[1] - B[1]; \ + R[2] = A[2] - B[2]; \ + R[3] = A[3] - B[3]; \ +} while (0) + +#define VEC4_MUL(R, A, B) \ +do { \ + R[0] = A[0] * B[0]; \ + R[1] = A[1] * B[1]; \ + R[2] = A[2] * B[2]; \ + R[3] = A[3] * B[3]; \ +} while (0) + +#define VEC4_MIN(R, A, B) \ +do { \ + R[0] = (A[0] < B[0]) ? A[0] : B[0]; \ + R[1] = (A[1] < B[1]) ? A[1] : B[1]; \ + R[2] = (A[2] < B[2]) ? A[2] : B[2]; \ + R[3] = (A[3] < B[3]) ? A[3] : B[3]; \ +} while (0) + +#define VEC4_MAX(R, A, B) \ +do { \ + R[0] = (A[0] > B[0]) ? A[0] : B[0]; \ + R[1] = (A[1] > B[1]) ? A[1] : B[1]; \ + R[2] = (A[2] > B[2]) ? A[2] : B[2]; \ + R[3] = (A[3] > B[3]) ? A[3] : B[3]; \ +} while (0) + + + +static void +logicop_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + float dest[4][QUAD_SIZE]; + ubyte src[4][4], dst[4][4], res[4][4]; + uint *src4 = (uint *) src; + uint *dst4 = (uint *) dst; + uint *res4 = (uint *) res; + struct softpipe_cached_tile * + tile = sp_get_cached_tile(softpipe, + softpipe->cbuf_cache[softpipe->current_cbuf], + quad->x0, quad->y0); + float (*quadColor)[4] = quad->outputs.color; + uint i, j; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } + } + + /* convert to ubyte */ + for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */ + UNCLAMPED_FLOAT_TO_UBYTE(dst[j][0], dest[j][0]); /* P0 */ + UNCLAMPED_FLOAT_TO_UBYTE(dst[j][1], dest[j][1]); /* P1 */ + UNCLAMPED_FLOAT_TO_UBYTE(dst[j][2], dest[j][2]); /* P2 */ + UNCLAMPED_FLOAT_TO_UBYTE(dst[j][3], dest[j][3]); /* P3 */ + + UNCLAMPED_FLOAT_TO_UBYTE(src[j][0], quadColor[j][0]); /* P0 */ + UNCLAMPED_FLOAT_TO_UBYTE(src[j][1], quadColor[j][1]); /* P1 */ + UNCLAMPED_FLOAT_TO_UBYTE(src[j][2], quadColor[j][2]); /* P2 */ + UNCLAMPED_FLOAT_TO_UBYTE(src[j][3], quadColor[j][3]); /* P3 */ + } + + switch (softpipe->blend->logicop_func) { + case PIPE_LOGICOP_CLEAR: + for (j = 0; j < 4; j++) + res4[j] = 0; + break; + case PIPE_LOGICOP_NOR: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] | dst4[j]); + break; + case PIPE_LOGICOP_AND_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j] & dst4[j]; + break; + case PIPE_LOGICOP_COPY_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j]; + break; + case PIPE_LOGICOP_AND_REVERSE: + for (j = 0; j < 4; j++) + res4[j] = src4[j] & ~dst4[j]; + break; + case PIPE_LOGICOP_INVERT: + for (j = 0; j < 4; j++) + res4[j] = ~dst4[j]; + break; + case PIPE_LOGICOP_XOR: + for (j = 0; j < 4; j++) + res4[j] = dst4[j] ^ src4[j]; + break; + case PIPE_LOGICOP_NAND: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] & dst4[j]); + break; + case PIPE_LOGICOP_AND: + for (j = 0; j < 4; j++) + res4[j] = src4[j] & dst4[j]; + break; + case PIPE_LOGICOP_EQUIV: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] ^ dst4[j]); + break; + case PIPE_LOGICOP_NOOP: + for (j = 0; j < 4; j++) + res4[j] = dst4[j]; + break; + case PIPE_LOGICOP_OR_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j] | dst4[j]; + break; + case PIPE_LOGICOP_COPY: + for (j = 0; j < 4; j++) + res4[j] = src4[j]; + break; + case PIPE_LOGICOP_OR_REVERSE: + for (j = 0; j < 4; j++) + res4[j] = src4[j] | ~dst4[j]; + break; + case PIPE_LOGICOP_OR: + for (j = 0; j < 4; j++) + res4[j] = src4[j] | dst4[j]; + break; + case PIPE_LOGICOP_SET: + for (j = 0; j < 4; j++) + res4[j] = ~0; + break; + default: + assert(0); + } + + for (j = 0; j < 4; j++) { + quadColor[j][0] = UBYTE_TO_FLOAT(res[j][0]); + quadColor[j][1] = UBYTE_TO_FLOAT(res[j][1]); + quadColor[j][2] = UBYTE_TO_FLOAT(res[j][2]); + quadColor[j][3] = UBYTE_TO_FLOAT(res[j][3]); + } + + /* pass quad to next stage */ + qs->next->run(qs->next, quad); +} + + + + +static void +blend_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + static const float zero[4] = { 0, 0, 0, 0 }; + static const float one[4] = { 1, 1, 1, 1 }; + float source[4][QUAD_SIZE], dest[4][QUAD_SIZE]; + struct softpipe_cached_tile *tile + = sp_get_cached_tile(softpipe, + softpipe->cbuf_cache[softpipe->current_cbuf], + quad->x0, quad->y0); + float (*quadColor)[4] = quad->outputs.color; + uint i, j; + + if (softpipe->blend->logicop_enable) { + logicop_quad(qs, quad); + return; + } + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } + } + + /* + * Compute src/first term RGB + */ + switch (softpipe->blend->rgb_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[0], quadColor[0]); /* R */ + VEC4_COPY(source[1], quadColor[1]); /* G */ + VEC4_COPY(source[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */ + VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */ + VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: + { + const float *alpha = quadColor[3]; + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_DST_COLOR: + VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */ + VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */ + VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */ + break; + case PIPE_BLENDFACTOR_DST_ALPHA: + { + const float *alpha = dest[3]; + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + { + const float *alpha = quadColor[3]; + float diff[4]; + VEC4_SUB(diff, one, dest[3]); + VEC4_MIN(source[0], alpha, diff); /* R */ + VEC4_MIN(source[1], alpha, diff); /* G */ + VEC4_MIN(source[2], alpha, diff); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], comp); /* R */ + VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], comp); /* G */ + VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float alpha[4]; + VEC4_SCALAR(alpha, softpipe->blend_color.color[3]); + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_SRC1_ALPHA: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[0], zero); /* R */ + VEC4_COPY(source[1], zero); /* G */ + VEC4_COPY(source[2], zero); /* B */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, quadColor[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, dest[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, dest[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + { + float inv_comp[4]; + /* R */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); + VEC4_MUL(source[0], quadColor[0], inv_comp); + /* G */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); + VEC4_MUL(source[1], quadColor[1], inv_comp); + /* B */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); + VEC4_MUL(source[2], quadColor[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_alpha[4]; + VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + assert(0); /* to do */ + break; + default: + abort(); + } + + /* + * Compute src/first term A + */ + switch (softpipe->blend->alpha_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[3], quadColor[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC_ALPHA: + { + const float *alpha = quadColor[3]; + VEC4_MUL(source[3], quadColor[3], alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + { + const float *alpha = quadColor[3]; + float diff[4]; + VEC4_SUB(diff, one, dest[3]); + VEC4_MIN(source[3], alpha, diff); /* A */ + } + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ + VEC4_MUL(source[3], quadColor[3], comp); /* A */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[3], zero); /* A */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, quadColor[3]); + VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + /* A */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(source[3], quadColor[3], inv_comp); + } + break; + default: + abort(); + } + + + /* + * Compute dest/second term RGB + */ + switch (softpipe->blend->rgb_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */ + VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */ + VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: + VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */ + break; + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ + break; + case PIPE_BLENDFACTOR_DST_COLOR: + VEC4_MUL(dest[0], dest[0], dest[0]); /* R */ + VEC4_MUL(dest[1], dest[1], dest[1]); /* G */ + VEC4_MUL(dest[2], dest[2], dest[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + assert(0); /* illegal */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ + VEC4_MUL(dest[0], dest[0], comp); /* R */ + VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ + VEC4_MUL(dest[1], dest[1], comp); /* G */ + VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ + VEC4_MUL(dest[2], dest[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ + VEC4_MUL(dest[0], dest[0], comp); /* R */ + VEC4_MUL(dest[1], dest[1], comp); /* G */ + VEC4_MUL(dest[2], dest[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[0], zero); /* R */ + VEC4_COPY(dest[1], zero); /* G */ + VEC4_COPY(dest[2], zero); /* B */ + break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + case PIPE_BLENDFACTOR_SRC1_ALPHA: + /* XXX what are these? */ + assert(0); + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ + VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ + VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ + VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ + VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ + VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float one_minus_alpha[QUAD_SIZE]; + VEC4_SUB(one_minus_alpha, one, quadColor[3]); + VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */ + VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */ + VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, quadColor[3]); /* A */ + VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ + VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ + VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[0]); /* R */ + VEC4_MUL(dest[0], dest[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, dest[1]); /* G */ + VEC4_MUL(dest[1], dest[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, dest[2]); /* B */ + VEC4_MUL(dest[2], dest[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + { + float inv_comp[4]; + /* R */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); + VEC4_MUL(dest[0], dest[0], inv_comp); + /* G */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); + VEC4_MUL(dest[1], dest[1], inv_comp); + /* B */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); + VEC4_MUL(dest[2], dest[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(dest[0], dest[0], inv_comp); + VEC4_MUL(dest[1], dest[1], inv_comp); + VEC4_MUL(dest[2], dest[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + /* XXX what are these? */ + assert(0); + break; + default: + assert(0); + } + + /* + * Compute dest/second term A + */ + switch (softpipe->blend->alpha_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC_ALPHA: + VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */ + break; + case PIPE_BLENDFACTOR_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + assert(0); /* illegal */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ + VEC4_MUL(dest[3], dest[3], comp); /* A */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[3], zero); /* A */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float one_minus_alpha[QUAD_SIZE]; + VEC4_SUB(one_minus_alpha, one, quadColor[3]); + VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[3]); /* A */ + VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(dest[3], dest[3], inv_comp); + } + break; + default: + assert(0); + } + + /* + * Combine RGB terms + */ + switch (softpipe->blend->rgb_func) { + case PIPE_BLEND_ADD: + VEC4_ADD(quadColor[0], source[0], dest[0]); /* R */ + VEC4_ADD(quadColor[1], source[1], dest[1]); /* G */ + VEC4_ADD(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB(quadColor[0], source[0], dest[0]); /* R */ + VEC4_SUB(quadColor[1], source[1], dest[1]); /* G */ + VEC4_SUB(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB(quadColor[0], dest[0], source[0]); /* R */ + VEC4_SUB(quadColor[1], dest[1], source[1]); /* G */ + VEC4_SUB(quadColor[2], dest[2], source[2]); /* B */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */ + VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */ + VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */ + VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */ + VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */ + break; + default: + assert(0); + } + + /* + * Combine A terms + */ + switch (softpipe->blend->alpha_func) { + case PIPE_BLEND_ADD: + VEC4_ADD(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB(quadColor[3], dest[3], source[3]); /* A */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */ + break; + default: + abort(); + } + + /* pass blended quad to next stage */ + qs->next->run(qs->next, quad); +} + + +static void blend_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void blend_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->begin = blend_begin; + stage->run = blend_quad; + stage->destroy = blend_destroy; + + return stage; +} diff --git a/src/gallium/drivers/softpipe/sp_quad_bufloop.c b/src/gallium/drivers/softpipe/sp_quad_bufloop.c new file mode 100644 index 0000000000..2ae4e22a7d --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_bufloop.c @@ -0,0 +1,72 @@ + +#include "pipe/p_util.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" + + +/** + * Loop over colorbuffers, passing quad to next stage each time. + */ +static void +cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + float tmp[4][QUAD_SIZE]; + unsigned i; + + assert(sizeof(quad->outputs.color) == sizeof(tmp)); + assert(softpipe->framebuffer.num_cbufs <= PIPE_MAX_COLOR_BUFS); + + /* make copy of original colors since they can get modified + * by blending and masking. + * XXX we won't have to do this if the fragment program actually emits + * N separate colors and we're drawing to N color buffers (MRT). + * But if we emitted one color and glDrawBuffer(GL_FRONT_AND_BACK) is + * in effect, we need to save/restore colors like this. + */ + memcpy(tmp, quad->outputs.color, sizeof(tmp)); + + for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) { + /* set current cbuffer */ + softpipe->current_cbuf = i; + + /* pass blended quad to next stage */ + qs->next->run(qs->next, quad); + + /* restore quad's colors for next buffer */ + memcpy(quad->outputs.color, tmp, sizeof(tmp)); + } +} + + +static void cbuf_loop_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void cbuf_loop_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +/** + * Create the colorbuffer loop stage. + * This is used to implement multiple render targets and GL_FRONT_AND_BACK + * rendering. + */ +struct quad_stage *sp_quad_bufloop_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->begin = cbuf_loop_begin; + stage->run = cbuf_loop_quad; + stage->destroy = cbuf_loop_destroy; + + return stage; +} + diff --git a/src/gallium/drivers/softpipe/sp_quad_colormask.c b/src/gallium/drivers/softpipe/sp_quad_colormask.c new file mode 100644 index 0000000000..1f09d900ca --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_colormask.c @@ -0,0 +1,110 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief quad colormask stage + * \author Brian Paul + */ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" +#include "sp_tile_cache.h" + + + +/** + * XXX colormask could be rolled into blending... + */ +static void +colormask_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + float dest[4][QUAD_SIZE]; + struct softpipe_cached_tile *tile + = sp_get_cached_tile(softpipe, + softpipe->cbuf_cache[softpipe->current_cbuf], + quad->x0, quad->y0); + float (*quadColor)[4] = quad->outputs.color; + uint i, j; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } + } + + /* R */ + if (!(softpipe->blend->colormask & PIPE_MASK_R)) + COPY_4V(quadColor[0], dest[0]); + + /* G */ + if (!(softpipe->blend->colormask & PIPE_MASK_G)) + COPY_4V(quadColor[1], dest[1]); + + /* B */ + if (!(softpipe->blend->colormask & PIPE_MASK_B)) + COPY_4V(quadColor[2], dest[2]); + + /* A */ + if (!(softpipe->blend->colormask & PIPE_MASK_A)) + COPY_4V(quadColor[3], dest[3]); + + /* pass quad to next stage */ + qs->next->run(qs->next, quad); +} + + +static void colormask_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void colormask_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->begin = colormask_begin; + stage->run = colormask_quad; + stage->destroy = colormask_destroy; + + return stage; +} diff --git a/src/gallium/drivers/softpipe/sp_quad_coverage.c b/src/gallium/drivers/softpipe/sp_quad_coverage.c new file mode 100644 index 0000000000..b3d3fae22f --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_coverage.c @@ -0,0 +1,88 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * \brief Apply AA coverage to quad alpha valus + * \author Brian Paul + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_quad.h" + + +/** + * Multiply quad's alpha values by the fragment coverage. + */ +static void +coverage_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + + if ((softpipe->rasterizer->poly_smooth && quad->prim == PRIM_TRI) || + (softpipe->rasterizer->line_smooth && quad->prim == PRIM_LINE) || + (softpipe->rasterizer->point_smooth && quad->prim == PRIM_POINT)) { + float (*quadColor)[4] = quad->outputs.color; + unsigned j; + for (j = 0; j < QUAD_SIZE; j++) { + assert(quad->coverage[j] >= 0.0); + assert(quad->coverage[j] <= 1.0); + quadColor[3][j] *= quad->coverage[j]; + } + } + + qs->next->run(qs->next, quad); +} + + +static void coverage_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void coverage_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->begin = coverage_begin; + stage->run = coverage_quad; + stage->destroy = coverage_destroy; + + return stage; +} diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c new file mode 100644 index 0000000000..a9a0754f27 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -0,0 +1,276 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Quad depth testing + */ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" +#include "sp_tile_cache.h" + + +/** + * Do depth testing for a quad. + * Not static since it's used by the stencil code. + */ + +/* + * To increase efficiency, we should probably have multiple versions + * of this function that are specifically for Z16, Z32 and FP Z buffers. + * Try to effectively do that with codegen... + */ + +void +sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + struct pipe_surface *ps = softpipe->framebuffer.zsbuf; + const enum pipe_format format = ps->format; + unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */ + unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */ + unsigned zmask = 0; + unsigned j; + struct softpipe_cached_tile *tile + = sp_get_cached_tile(softpipe, softpipe->zsbuf_cache, quad->x0, quad->y0); + + assert(ps); /* shouldn't get here if there's no zbuffer */ + + /* + * Convert quad's float depth values to int depth values (qzzzz). + * If the Z buffer stores integer values, we _have_ to do the depth + * compares with integers (not floats). Otherwise, the float->int->float + * conversion of Z values (which isn't an identity function) will cause + * Z-fighting errors. + * + * Also, get the zbuffer values (bzzzz) from the cached tile. + */ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + { + float scale = 65535.0; + + for (j = 0; j < QUAD_SIZE; j++) { + qzzzz[j] = (unsigned) (quad->outputs.depth[j] * scale); + } + + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + bzzzz[j] = tile->data.depth16[y][x]; + } + } + break; + case PIPE_FORMAT_Z32_UNORM: + { + double scale = (double) (uint) ~0UL; + + for (j = 0; j < QUAD_SIZE; j++) { + qzzzz[j] = (unsigned) (quad->outputs.depth[j] * scale); + } + + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + bzzzz[j] = tile->data.depth32[y][x]; + } + } + break; + case PIPE_FORMAT_S8Z24_UNORM: + { + float scale = (float) ((1 << 24) - 1); + + for (j = 0; j < QUAD_SIZE; j++) { + qzzzz[j] = (unsigned) (quad->outputs.depth[j] * scale); + } + + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + bzzzz[j] = tile->data.depth32[y][x] & 0xffffff; + } + } + break; + case PIPE_FORMAT_Z24S8_UNORM: + { + float scale = (float) ((1 << 24) - 1); + + for (j = 0; j < QUAD_SIZE; j++) { + qzzzz[j] = (unsigned) (quad->outputs.depth[j] * scale); + } + + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + bzzzz[j] = tile->data.depth32[y][x] >> 8; + } + } + break; + default: + assert(0); + } + + switch (softpipe->depth_stencil->depth.func) { + case PIPE_FUNC_NEVER: + /* zmask = 0 */ + break; + case PIPE_FUNC_LESS: + /* Note this is pretty much a single sse or cell instruction. + * Like this: quad->mask &= (quad->outputs.depth < zzzz); + */ + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] < bzzzz[j]) + zmask |= 1 << j; + } + break; + case PIPE_FUNC_EQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] == bzzzz[j]) + zmask |= 1 << j; + } + break; + case PIPE_FUNC_LEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] <= bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_GREATER: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] > bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_NOTEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] != bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_GEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] >= bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_ALWAYS: + zmask = MASK_ALL; + break; + default: + abort(); + } + + quad->mask &= zmask; + + if (softpipe->depth_stencil->depth.writemask) { + + /* This is also efficient with sse / spe instructions: + */ + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->mask & (1 << j)) { + bzzzz[j] = qzzzz[j]; + } + } + + /* put updated Z values back into cached tile */ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + tile->data.depth16[y][x] = (ushort) bzzzz[j]; + } + break; + case PIPE_FORMAT_Z32_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + tile->data.depth32[y][x] = bzzzz[j]; + } + break; + case PIPE_FORMAT_S8Z24_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + uint s8z24 = tile->data.depth32[y][x]; + s8z24 = (s8z24 & 0xff000000) | bzzzz[j]; + tile->data.depth32[y][x] = s8z24; + } + break; + case PIPE_FORMAT_Z24S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + uint z24s8 = tile->data.depth32[y][x]; + z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 24); + tile->data.depth32[y][x] = z24s8; + } + break; + default: + assert(0); + } + } +} + + +static void +depth_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + sp_depth_test_quad(qs, quad); + + if (quad->mask) + qs->next->run(qs->next, quad); +} + + +static void depth_test_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void depth_test_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->begin = depth_test_begin; + stage->run = depth_test_quad; + stage->destroy = depth_test_destroy; + + return stage; +} diff --git a/src/gallium/drivers/softpipe/sp_quad_earlyz.c b/src/gallium/drivers/softpipe/sp_quad_earlyz.c new file mode 100644 index 0000000000..22ea99049f --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_earlyz.c @@ -0,0 +1,88 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Quad early-z testing + */ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "sp_headers.h" +#include "sp_quad.h" + + +/** + * All this stage does is compute the quad's Z values (which is normally + * done by the shading stage). + * The next stage will do the actual depth test. + */ +static void +earlyz_quad( + struct quad_stage *qs, + struct quad_header *quad ) +{ + const float fx = (float) quad->x0; + const float fy = (float) quad->y0; + const float dzdx = quad->posCoef->dadx[2]; + const float dzdy = quad->posCoef->dady[2]; + const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy; + + quad->outputs.depth[0] = z0; + quad->outputs.depth[1] = z0 + dzdx; + quad->outputs.depth[2] = z0 + dzdy; + quad->outputs.depth[3] = z0 + dzdx + dzdy; + + qs->next->run( qs->next, quad ); +} + +static void +earlyz_begin( + struct quad_stage *qs ) +{ + qs->next->begin( qs->next ); +} + +static void +earlyz_destroy( + struct quad_stage *qs ) +{ + FREE( qs ); +} + +struct quad_stage * +sp_quad_earlyz_stage( + struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT( quad_stage ); + + stage->softpipe = softpipe; + stage->begin = earlyz_begin; + stage->run = earlyz_quad; + stage->destroy = earlyz_destroy; + + return stage; +} diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c new file mode 100644 index 0000000000..3316858413 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -0,0 +1,390 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Vertices are just an array of floats, with all the attributes + * packed. We currently assume a layout like: + * + * attr[0][0..3] - window position + * attr[1..n][0..3] - remaining attributes. + * + * Attributes are assumed to be 4 floats wide but are packed so that + * all the enabled attributes run contiguously. + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "x86/rtasm/x86sse.h" + +#ifdef MESA_LLVM +#include "pipe/llvm/gallivm.h" +#endif + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_headers.h" +#include "sp_quad.h" +#include "sp_texture.h" +#include "sp_tex_sample.h" + + +struct quad_shade_stage +{ + struct quad_stage stage; + struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS]; + struct tgsi_exec_machine machine; + struct tgsi_exec_vector *inputs, *outputs; + int colorOutSlot, depthOutSlot; +#ifdef MESA_LLVM + struct gallivm_prog *llvm_prog; +#endif +}; + + +/** cast wrapper */ +static INLINE struct quad_shade_stage * +quad_shade_stage(struct quad_stage *qs) +{ + return (struct quad_shade_stage *) qs; +} + + +/** + * Compute quad X,Y,Z,W for the four fragments in a quad. + * Note that we only need to "compute" X and Y for the upper-left fragment. + * We could do less work if we're not depth testing, or there's no + * perspective-corrected attributes, but that's seldom. + */ +static void +setup_pos_vector(const struct tgsi_interp_coef *coef, + float x, float y, + struct tgsi_exec_vector *quadpos) +{ + uint chan; + /* do X */ + quadpos->xyzw[0].f[0] = x; + /* do Y */ + quadpos->xyzw[1].f[0] = y; + /* do Z and W for all fragments in the quad */ + for (chan = 2; chan < 4; chan++) { + const float dadx = coef->dadx[chan]; + const float dady = coef->dady[chan]; + const float a0 = coef->a0[chan] + dadx * x + dady * y; + quadpos->xyzw[chan].f[0] = a0; + quadpos->xyzw[chan].f[1] = a0 + dadx; + quadpos->xyzw[chan].f[2] = a0 + dady; + quadpos->xyzw[chan].f[3] = a0 + dadx + dady; + } +} + + +typedef void (XSTDCALL *codegen_function)( + const struct tgsi_exec_vector *input, + struct tgsi_exec_vector *output, + float (*constant)[4], + struct tgsi_exec_vector *temporary, + const struct tgsi_interp_coef *coef +#if 0 + ,const struct tgsi_exec_vector *quadPos +#endif + ); + + +/** + * Execute fragment shader for the four fragments in the quad. + */ +static void +shade_quad( + struct quad_stage *qs, + struct quad_header *quad ) +{ + struct quad_shade_stage *qss = quad_shade_stage( qs ); + struct softpipe_context *softpipe = qs->softpipe; + struct tgsi_exec_machine *machine = &qss->machine; + + /* Consts do not require 16 byte alignment. */ + machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; + + machine->InterpCoefs = quad->coef; + + /* Compute X, Y, Z, W vals for this quad */ + setup_pos_vector(quad->posCoef, (float) quad->x0, (float) quad->y0, &machine->QuadPos); + + /* run shader */ +#if defined(__i386__) || defined(__386__) + if( softpipe->use_sse ) { + codegen_function func = (codegen_function) x86_get_func( &softpipe->fs->sse2_program ); + func( + machine->Inputs, + machine->Outputs, + machine->Consts, + machine->Temps, + machine->InterpCoefs +#if 0 + ,machine->QuadPos +#endif + ); + quad->mask &= ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]); + } + else +#endif + { + quad->mask &= tgsi_exec_machine_run( machine ); + } + + /* store result color */ + if (qss->colorOutSlot >= 0) { + /* XXX need to handle multiple color outputs someday */ + assert(qss->stage.softpipe->fs->shader.output_semantic_name[qss->colorOutSlot] + == TGSI_SEMANTIC_COLOR); + memcpy( + quad->outputs.color, + &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0], + sizeof( quad->outputs.color ) ); + } + + /* + * XXX the following code for updating quad->outputs.depth + * isn't really needed if we did early z testing. + */ + + /* store result Z */ + if (qss->depthOutSlot >= 0) { + /* output[slot] is new Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i]; + } + } + else { + /* copy input Z (which was interpolated by the executor) to output Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i]; + /* XXX not sure the above line is always correct. The following + * might be better: + quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i]; + */ + } + } + + /* shader may cull fragments */ + if( quad->mask ) { + qs->next->run( qs->next, quad ); + } +} + +#if 0 +#ifdef MESA_LLVM +#define DLLVM 0 +static void +shade_quad_llvm(struct quad_stage *qs, + struct quad_header *quad) +{ + struct quad_shade_stage *qss = quad_shade_stage(qs); + struct softpipe_context *softpipe = qs->softpipe; + float dests[4][16][4] ALIGN16_ATTRIB; + float inputs[4][16][4] ALIGN16_ATTRIB; + const float fx = (float) quad->x0; + const float fy = (float) quad->y0; + struct gallivm_prog *llvm = qss->llvm_prog; + + inputs[0][0][0] = fx; + inputs[1][0][0] = fx + 1.0f; + inputs[2][0][0] = fx; + inputs[3][0][0] = fx + 1.0f; + + inputs[0][0][1] = fy; + inputs[1][0][1] = fy; + inputs[2][0][1] = fy + 1.0f; + inputs[3][0][1] = fy + 1.0f; +#if DLLVM + debug_printf("MASK = %d\n", quad->mask); +#endif + gallivm_prog_inputs_interpolate(llvm, inputs, quad->coef); +#if DLLVM + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 2; ++j) { + debug_printf("IN(%d,%d) [%f %f %f %f]\n", i, j, + inputs[i][j][0], inputs[i][j][1], inputs[i][j][2], inputs[i][j][3]); + } + } +#endif + + quad->mask &= + gallivm_fragment_shader_exec(llvm, fx, fy, dests, inputs, + softpipe->mapped_constants[PIPE_SHADER_FRAGMENT], + qss->samplers); +#if DLLVM + debug_printf("OUT LLVM = 1[%f %f %f %f], 2[%f %f %f %f]\n", + dests[0][0][0], dests[0][0][1], dests[0][0][2], dests[0][0][3], + dests[0][1][0], dests[0][1][1], dests[0][1][2], dests[0][1][3]); +#endif + + /* store result color */ + if (qss->colorOutSlot >= 0) { + unsigned i; + /* XXX need to handle multiple color outputs someday */ + assert(qss->stage.softpipe->fs->shader.output_semantic_name[qss->colorOutSlot] + == TGSI_SEMANTIC_COLOR); + for (i = 0; i < QUAD_SIZE; ++i) { + quad->outputs.color[0][i] = dests[i][qss->colorOutSlot][0]; + quad->outputs.color[1][i] = dests[i][qss->colorOutSlot][1]; + quad->outputs.color[2][i] = dests[i][qss->colorOutSlot][2]; + quad->outputs.color[3][i] = dests[i][qss->colorOutSlot][3]; + } + } +#if DLLVM + for (int i = 0; i < QUAD_SIZE; ++i) { + debug_printf("QLLVM%d(%d) [%f, %f, %f, %f]\n", i, qss->colorOutSlot, + quad->outputs.color[0][i], + quad->outputs.color[1][i], + quad->outputs.color[2][i], + quad->outputs.color[3][i]); + } +#endif + + /* store result Z */ + if (qss->depthOutSlot >= 0) { + /* output[slot] is new Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = dests[i][0][2]; + } + } + else { + /* copy input Z (which was interpolated by the executor) to output Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = inputs[i][0][2]; + } + } +#if DLLVM + debug_printf("D [%f, %f, %f, %f] mask = %d\n", + quad->outputs.depth[0], + quad->outputs.depth[1], + quad->outputs.depth[2], + quad->outputs.depth[3], quad->mask); +#endif + + /* shader may cull fragments */ + if( quad->mask ) { + qs->next->run( qs->next, quad ); + } +} +#endif /*MESA_LLVM*/ +#endif + +/** + * Per-primitive (or per-begin?) setup + */ +static void shade_begin(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = quad_shade_stage(qs); + struct softpipe_context *softpipe = qs->softpipe; + unsigned i; + + /* set TGSI sampler state that varies */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + qss->samplers[i].state = softpipe->sampler[i]; + qss->samplers[i].texture = &softpipe->texture[i]->base; + } + +#ifdef MESA_LLVM + qss->llvm_prog = softpipe->fs->llvm_prog; +#endif + /* XXX only do this if the fragment shader changes... */ + tgsi_exec_machine_init(&qss->machine, + softpipe->fs->shader.tokens, + PIPE_MAX_SAMPLERS, + qss->samplers ); + + /* find output slots for depth, color */ + qss->colorOutSlot = -1; + qss->depthOutSlot = -1; + for (i = 0; i < qss->stage.softpipe->fs->shader.num_outputs; i++) { + switch (qss->stage.softpipe->fs->shader.output_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + qss->depthOutSlot = i; + break; + case TGSI_SEMANTIC_COLOR: + qss->colorOutSlot = i; + break; + } + } + + qs->next->begin(qs->next); +} + + +static void shade_destroy(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; + + tgsi_exec_machine_free_data(&qss->machine); + FREE( qss->inputs ); + FREE( qss->outputs ); + FREE( qs ); +} + + +struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) +{ + struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); + uint i; + + /* allocate storage for program inputs/outputs, aligned to 16 bytes */ + qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16); + qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16); + qss->machine.Inputs = align16(qss->inputs); + qss->machine.Outputs = align16(qss->outputs); + + qss->stage.softpipe = softpipe; + qss->stage.begin = shade_begin; +#ifdef MESA_LLVM + /* disable until ported to accept + * x/y and soa layout + qss->stage.run = shade_quad_llvm; + */ + softpipe->use_sse = FALSE; + qss->stage.run = shade_quad; +#else + qss->stage.run = shade_quad; +#endif + qss->stage.destroy = shade_destroy; + + /* set TGSI sampler state that's constant */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + assert(softpipe->tex_cache[i]); + qss->samplers[i].get_samples = sp_get_samples; + qss->samplers[i].pipe = &softpipe->pipe; + qss->samplers[i].cache = softpipe->tex_cache[i]; + } + + return &qss->stage; +} diff --git a/src/gallium/drivers/softpipe/sp_quad_occlusion.c b/src/gallium/drivers/softpipe/sp_quad_occlusion.c new file mode 100644 index 0000000000..54254df1f1 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_occlusion.c @@ -0,0 +1,85 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * \brief Quad occlusion counter stage + * \author Brian Paul + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" + +static unsigned count_bits( unsigned val ) +{ + unsigned i; + + for (i = 0; val ; val >>= 1) + i += (val & 1); + + return i; +} + +static void +occlusion_count_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + + softpipe->occlusion_count += count_bits(quad->mask); + + qs->next->run(qs->next, quad); +} + + +static void occlusion_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void occlusion_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->begin = occlusion_begin; + stage->run = occlusion_count_quad; + stage->destroy = occlusion_destroy; + + return stage; +} diff --git a/src/gallium/drivers/softpipe/sp_quad_output.c b/src/gallium/drivers/softpipe/sp_quad_output.c new file mode 100644 index 0000000000..cfe8f11808 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_output.c @@ -0,0 +1,90 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" +#include "sp_tile_cache.h" + + +/** + * Write quad to framebuffer, taking mask into account. + * + * Note that surfaces support only full quad reads and writes. + */ +static void +output_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + struct softpipe_cached_tile *tile + = sp_get_cached_tile(softpipe, + softpipe->cbuf_cache[softpipe->current_cbuf], + quad->x0, quad->y0); + /* in-tile pos: */ + const int itx = quad->x0 % TILE_SIZE; + const int ity = quad->y0 % TILE_SIZE; + float (*quadColor)[4] = quad->outputs.color; + int i, j; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->mask & (1 << j)) { + int x = itx + (j & 1); + int y = ity + (j >> 1); + for (i = 0; i < 4; i++) { /* loop over color chans */ + tile->data.color[y][x][i] = quadColor[i][j]; + } + } + } +} + + +static void output_begin(struct quad_stage *qs) +{ + assert(qs->next == NULL); +} + + +static void output_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->begin = output_begin; + stage->run = output_quad; + stage->destroy = output_destroy; + + return stage; +} diff --git a/src/gallium/drivers/softpipe/sp_quad_stencil.c b/src/gallium/drivers/softpipe/sp_quad_stencil.c new file mode 100644 index 0000000000..92a0da0083 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_stencil.c @@ -0,0 +1,352 @@ + +/** + * \brief Quad stencil testing + */ + + +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_tile_cache.h" +#include "sp_quad.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" + + +/** Only 8-bit stencil supported */ +#define STENCIL_MAX 0xff + + +/** + * Do the basic stencil test (compare stencil buffer values against the + * reference value. + * + * \param stencilVals the stencil values from the stencil buffer + * \param func the stencil func (PIPE_FUNC_x) + * \param ref the stencil reference value + * \param valMask the stencil value mask indicating which bits of the stencil + * values and ref value are to be used. + * \return mask indicating which pixels passed the stencil test + */ +static unsigned +do_stencil_test(const ubyte stencilVals[QUAD_SIZE], unsigned func, + unsigned ref, unsigned valMask) +{ + unsigned passMask = 0x0; + unsigned j; + + ref &= valMask; + + switch (func) { + case PIPE_FUNC_NEVER: + /* passMask = 0x0 */ + break; + case PIPE_FUNC_LESS: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref < (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_EQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref == (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_LEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref <= (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GREATER: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref > (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_NOTEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref != (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref >= (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_ALWAYS: + passMask = MASK_ALL; + break; + default: + assert(0); + } + + return passMask; +} + + +/** + * Apply the stencil operator to stencil values. + * + * \param stencilVals the stencil buffer values (read and written) + * \param mask indicates which pixels to update + * \param op the stencil operator (PIPE_STENCIL_OP_x) + * \param ref the stencil reference value + * \param wrtMask writemask controlling which bits are changed in the + * stencil values + */ +static void +apply_stencil_op(ubyte stencilVals[QUAD_SIZE], + unsigned mask, unsigned op, ubyte ref, ubyte wrtMask) +{ + unsigned j; + ubyte newstencil[QUAD_SIZE]; + + for (j = 0; j < QUAD_SIZE; j++) { + newstencil[j] = stencilVals[j]; + } + + switch (op) { + case PIPE_STENCIL_OP_KEEP: + /* no-op */ + break; + case PIPE_STENCIL_OP_ZERO: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = 0; + } + } + break; + case PIPE_STENCIL_OP_REPLACE: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = ref; + } + } + break; + case PIPE_STENCIL_OP_INCR: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + if (stencilVals[j] < STENCIL_MAX) { + newstencil[j] = stencilVals[j] + 1; + } + } + } + break; + case PIPE_STENCIL_OP_DECR: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + if (stencilVals[j] > 0) { + newstencil[j] = stencilVals[j] - 1; + } + } + } + break; + case PIPE_STENCIL_OP_INCR_WRAP: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = stencilVals[j] + 1; + } + } + break; + case PIPE_STENCIL_OP_DECR_WRAP: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = stencilVals[j] - 1; + } + } + break; + case PIPE_STENCIL_OP_INVERT: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = ~stencilVals[j]; + } + } + break; + default: + assert(0); + } + + /* + * update the stencil values + */ + if (wrtMask != STENCIL_MAX) { + /* apply bit-wise stencil buffer writemask */ + for (j = 0; j < QUAD_SIZE; j++) { + stencilVals[j] = (wrtMask & newstencil[j]) | (~wrtMask & stencilVals[j]); + } + } + else { + for (j = 0; j < QUAD_SIZE; j++) { + stencilVals[j] = newstencil[j]; + } + } +} + + +/** + * Do stencil (and depth) testing. Stenciling depends on the outcome of + * depth testing. + */ +static void +stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + struct pipe_surface *ps = softpipe->framebuffer.zsbuf; + unsigned func, zFailOp, zPassOp, failOp; + ubyte ref, wrtMask, valMask; + ubyte stencilVals[QUAD_SIZE]; + struct softpipe_cached_tile *tile + = sp_get_cached_tile(softpipe, softpipe->zsbuf_cache, quad->x0, quad->y0); + uint j; + uint face = quad->facing; + + if (!softpipe->depth_stencil->stencil[1].enabled) { + /* single-sided stencil test, use front (face=0) state */ + face = 0; + } + + /* choose front or back face function, operator, etc */ + /* XXX we could do these initializations once per primitive */ + func = softpipe->depth_stencil->stencil[face].func; + failOp = softpipe->depth_stencil->stencil[face].fail_op; + zFailOp = softpipe->depth_stencil->stencil[face].zfail_op; + zPassOp = softpipe->depth_stencil->stencil[face].zpass_op; + ref = softpipe->depth_stencil->stencil[face].ref_value; + wrtMask = softpipe->depth_stencil->stencil[face].write_mask; + valMask = softpipe->depth_stencil->stencil[face].value_mask; + + assert(ps); /* shouldn't get here if there's no stencil buffer */ + + /* get stencil values from cached tile */ + switch (ps->format) { + case PIPE_FORMAT_S8Z24_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + stencilVals[j] = tile->data.depth32[y][x] >> 24; + } + break; + case PIPE_FORMAT_Z24S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + stencilVals[j] = tile->data.depth32[y][x] & 0xff; + } + break; + case PIPE_FORMAT_U_S8: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + stencilVals[j] = tile->data.stencil8[y][x]; + } + break; + default: + assert(0); + } + + /* do the stencil test first */ + { + unsigned passMask, failMask; + passMask = do_stencil_test(stencilVals, func, ref, valMask); + failMask = quad->mask & ~passMask; + quad->mask &= passMask; + + if (failOp != PIPE_STENCIL_OP_KEEP) { + apply_stencil_op(stencilVals, failMask, failOp, ref, wrtMask); + } + } + + if (quad->mask) { + /* now the pixels that passed the stencil test are depth tested */ + if (softpipe->depth_stencil->depth.enabled) { + const unsigned origMask = quad->mask; + + sp_depth_test_quad(qs, quad); /* quad->mask is updated */ + + /* update stencil buffer values according to z pass/fail result */ + if (zFailOp != PIPE_STENCIL_OP_KEEP) { + const unsigned failMask = origMask & ~quad->mask; + apply_stencil_op(stencilVals, failMask, zFailOp, ref, wrtMask); + } + + if (zPassOp != PIPE_STENCIL_OP_KEEP) { + const unsigned passMask = origMask & quad->mask; + apply_stencil_op(stencilVals, passMask, zPassOp, ref, wrtMask); + } + } + else { + /* no depth test, apply Zpass operator to stencil buffer values */ + apply_stencil_op(stencilVals, quad->mask, zPassOp, ref, wrtMask); + } + + } + + /* put new stencil values into cached tile */ + switch (ps->format) { + case PIPE_FORMAT_S8Z24_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + uint s8z24 = tile->data.depth32[y][x]; + s8z24 = (stencilVals[j] << 24) | (s8z24 & 0xffffff); + tile->data.depth32[y][x] = s8z24; + } + break; + case PIPE_FORMAT_Z24S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + uint z24s8 = tile->data.depth32[y][x]; + z24s8 = (z24s8 & 0xffffff00) | stencilVals[j]; + tile->data.depth32[y][x] = z24s8; + } + break; + case PIPE_FORMAT_U_S8: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + tile->data.stencil8[y][x] = stencilVals[j]; + } + break; + default: + assert(0); + } + + if (quad->mask) + qs->next->run(qs->next, quad); +} + + +static void stencil_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void stencil_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->begin = stencil_begin; + stage->run = stencil_test_quad; + stage->destroy = stencil_destroy; + + return stage; +} diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c new file mode 100644 index 0000000000..8660432259 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c @@ -0,0 +1,94 @@ + +/** + * quad polygon stipple stage + */ + +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_quad.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" + + +/** + * Apply polygon stipple to quads produced by triangle rasterization + */ +static void +stipple_quad(struct quad_stage *qs, struct quad_header *quad) +{ + static const uint bit31 = 1 << 31; + static const uint bit30 = 1 << 30; + + if (quad->prim == PRIM_TRI) { + struct softpipe_context *softpipe = qs->softpipe; + /* need to invert Y to index into OpenGL's stipple pattern */ + int y0, y1; + uint stipple0, stipple1; + if (softpipe->rasterizer->origin_lower_left) { + y0 = softpipe->framebuffer.cbufs[0]->height - 1 - quad->y0; + y1 = y0 - 1; + } + else { + y0 = quad->y0; + y1 = y0 + 1; + } + stipple0 = softpipe->poly_stipple.stipple[y0 % 32]; + stipple1 = softpipe->poly_stipple.stipple[y1 % 32]; + +#if 1 + { + const int col0 = quad->x0 % 32; + if ((stipple0 & (bit31 >> col0)) == 0) + quad->mask &= ~MASK_TOP_LEFT; + + if ((stipple0 & (bit30 >> col0)) == 0) + quad->mask &= ~MASK_TOP_RIGHT; + + if ((stipple1 & (bit31 >> col0)) == 0) + quad->mask &= ~MASK_BOTTOM_LEFT; + + if ((stipple1 & (bit30 >> col0)) == 0) + quad->mask &= ~MASK_BOTTOM_RIGHT; + } +#else + /* We'd like to use this code, but we'd need to redefine + * MASK_TOP_LEFT to be (1 << 1) and MASK_TOP_RIGHT to be (1 << 0), + * and similarly for the BOTTOM bits. But that may have undesirable + * side effects elsewhere. + */ + const int col0 = 30 - (quad->x0 % 32); + quad->mask &= (((stipple0 >> col0) & 0x3) | + (((stipple1 >> col0) & 0x3) << 2)); +#endif + if (!quad->mask) + return; + } + + qs->next->run(qs->next, quad); +} + + +static void stipple_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void stipple_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage * +sp_quad_polygon_stipple_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->begin = stipple_begin; + stage->run = stipple_quad; + stage->destroy = stipple_destroy; + + return stage; +} diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c new file mode 100644 index 0000000000..6a8a43aeda --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_query.c @@ -0,0 +1,107 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + +#include "pipe/draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "sp_context.h" +#include "sp_query.h" + +struct softpipe_query { + uint64 start; + uint64 end; +}; + + +static struct softpipe_query *softpipe_query( struct pipe_query *p ) +{ + return (struct softpipe_query *)p; +} + +static struct pipe_query * +softpipe_create_query(struct pipe_context *pipe, + unsigned type) +{ + assert(type == PIPE_QUERY_OCCLUSION_COUNTER); + return (struct pipe_query *)CALLOC_STRUCT( softpipe_query ); +} + + +static void +softpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q) +{ + FREE(q); +} + + +static void +softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q) +{ + struct softpipe_context *softpipe = softpipe_context( pipe ); + struct softpipe_query *sq = softpipe_query(q); + + sq->start = softpipe->occlusion_count; +} + + +static void +softpipe_end_query(struct pipe_context *pipe, struct pipe_query *q) +{ + struct softpipe_context *softpipe = softpipe_context( pipe ); + struct softpipe_query *sq = softpipe_query(q); + + sq->end = softpipe->occlusion_count; +} + + +static boolean +softpipe_get_query_result(struct pipe_context *pipe, + struct pipe_query *q, + boolean wait, + uint64 *result ) +{ + struct softpipe_query *sq = softpipe_query(q); + *result = sq->end - sq->start; + return TRUE; +} + + +void softpipe_init_query_funcs(struct softpipe_context *softpipe ) +{ + softpipe->pipe.create_query = softpipe_create_query; + softpipe->pipe.destroy_query = softpipe_destroy_query; + softpipe->pipe.begin_query = softpipe_begin_query; + softpipe->pipe.end_query = softpipe_end_query; + softpipe->pipe.get_query_result = softpipe_get_query_result; +} + + diff --git a/src/gallium/drivers/softpipe/sp_query.h b/src/gallium/drivers/softpipe/sp_query.h new file mode 100644 index 0000000000..05060a4575 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_query.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + +#ifndef SP_QUERY_H +#define SP_QUERY_H + +struct softpipe_context; +extern void softpipe_init_query_funcs(struct softpipe_context * ); + + +#endif /* SP_QUERY_H */ diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h new file mode 100644 index 0000000000..b79db0d1f1 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -0,0 +1,187 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_STATE_H +#define SP_STATE_H + +#include "pipe/p_state.h" + +#include "x86/rtasm/x86sse.h" + + +#define SP_NEW_VIEWPORT 0x1 +#define SP_NEW_RASTERIZER 0x2 +#define SP_NEW_FS 0x4 +#define SP_NEW_BLEND 0x8 +#define SP_NEW_CLIP 0x10 +#define SP_NEW_SCISSOR 0x20 +#define SP_NEW_STIPPLE 0x40 +#define SP_NEW_FRAMEBUFFER 0x80 +#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100 +#define SP_NEW_CONSTANTS 0x200 +#define SP_NEW_SAMPLER 0x400 +#define SP_NEW_TEXTURE 0x800 +#define SP_NEW_VERTEX 0x1000 +#define SP_NEW_VS 0x2000 +#define SP_NEW_QUERY 0x4000 + + + +#ifdef MESA_LLVM +struct gallivm_prog; +#endif + + +struct vertex_info; + + +/** Subclass of pipe_shader_state */ +struct sp_fragment_shader_state { + struct pipe_shader_state shader; +#if defined(__i386__) || defined(__386__) + struct x86_function sse2_program; +#endif +#ifdef MESA_LLVM + struct gallivm_prog *llvm_prog; +#endif +}; + + +/** Subclass of pipe_shader_state */ +struct sp_vertex_shader_state { + struct pipe_shader_state shader; + struct draw_vertex_shader *draw_data; +}; + + + +void * +softpipe_create_blend_state(struct pipe_context *, + const struct pipe_blend_state *); +void softpipe_bind_blend_state(struct pipe_context *, + void *); +void softpipe_delete_blend_state(struct pipe_context *, + void *); + +void * +softpipe_create_sampler_state(struct pipe_context *, + const struct pipe_sampler_state *); +void softpipe_bind_sampler_state(struct pipe_context *, unsigned, void *); +void softpipe_delete_sampler_state(struct pipe_context *, void *); + +void * +softpipe_create_depth_stencil_state(struct pipe_context *, + const struct pipe_depth_stencil_alpha_state *); +void softpipe_bind_depth_stencil_state(struct pipe_context *, void *); +void softpipe_delete_depth_stencil_state(struct pipe_context *, void *); + +void * +softpipe_create_rasterizer_state(struct pipe_context *, + const struct pipe_rasterizer_state *); +void softpipe_bind_rasterizer_state(struct pipe_context *, void *); +void softpipe_delete_rasterizer_state(struct pipe_context *, void *); + +void softpipe_set_framebuffer_state( struct pipe_context *, + const struct pipe_framebuffer_state * ); + +void softpipe_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ); + +void softpipe_set_clip_state( struct pipe_context *, + const struct pipe_clip_state * ); + +void softpipe_set_constant_buffer(struct pipe_context *, + uint shader, uint index, + const struct pipe_constant_buffer *buf); + +void *softpipe_create_fs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_fs_state(struct pipe_context *, void *); +void softpipe_delete_fs_state(struct pipe_context *, void *); +void *softpipe_create_vs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_vs_state(struct pipe_context *, void *); +void softpipe_delete_vs_state(struct pipe_context *, void *); + +void softpipe_set_polygon_stipple( struct pipe_context *, + const struct pipe_poly_stipple * ); + +void softpipe_set_scissor_state( struct pipe_context *, + const struct pipe_scissor_state * ); + +void softpipe_set_sampler_texture( struct pipe_context *, + unsigned unit, + struct pipe_texture * ); + +void softpipe_set_viewport_state( struct pipe_context *, + const struct pipe_viewport_state * ); + +void softpipe_set_vertex_element(struct pipe_context *, + unsigned index, + const struct pipe_vertex_element *); + +void softpipe_set_vertex_buffer(struct pipe_context *, + unsigned index, + const struct pipe_vertex_buffer *); + + +void softpipe_update_derived( struct softpipe_context *softpipe ); + + +boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count); + +boolean softpipe_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count); + + +void +softpipe_map_surfaces(struct softpipe_context *sp); + +void +softpipe_unmap_surfaces(struct softpipe_context *sp); + +void +softpipe_map_texture_surfaces(struct softpipe_context *sp); + +void +softpipe_unmap_texture_surfaces(struct softpipe_context *sp); + + +struct vertex_info * +softpipe_get_vertex_info(struct softpipe_context *softpipe); + +struct vertex_info * +softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe); + + +#endif diff --git a/src/gallium/drivers/softpipe/sp_state_blend.c b/src/gallium/drivers/softpipe/sp_state_blend.c new file mode 100644 index 0000000000..2d40d6bd8f --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_state_blend.c @@ -0,0 +1,98 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "sp_context.h" +#include "sp_state.h" + + +void * +softpipe_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + return mem_dup(blend, sizeof(*blend)); +} + +void softpipe_bind_blend_state( struct pipe_context *pipe, + void *blend ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->blend = (const struct pipe_blend_state *)blend; + + softpipe->dirty |= SP_NEW_BLEND; +} + +void softpipe_delete_blend_state(struct pipe_context *pipe, + void *blend) +{ + FREE( blend ); +} + + +void softpipe_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->blend_color = *blend_color; + + softpipe->dirty |= SP_NEW_BLEND; +} + + +/** XXX move someday? Or consolidate all these simple state setters + * into one file. + */ + + +void * +softpipe_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + return mem_dup(depth_stencil, sizeof(*depth_stencil)); +} + +void +softpipe_bind_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; + + softpipe->dirty |= SP_NEW_DEPTH_STENCIL_ALPHA; +} + +void +softpipe_delete_depth_stencil_state(struct pipe_context *pipe, void *depth) +{ + FREE( depth ); +} diff --git a/src/gallium/drivers/softpipe/sp_state_clip.c b/src/gallium/drivers/softpipe/sp_state_clip.c new file mode 100644 index 0000000000..08c5f06d05 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_state_clip.c @@ -0,0 +1,83 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ +#include "sp_context.h" +#include "sp_state.h" +#include "pipe/draw/draw_context.h" + + +void softpipe_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + /* pass the clip state to the draw module */ + draw_set_clip_state(softpipe->draw, clip); +} + + + +/* Called when driver state tracker notices changes to the viewport + * matrix: + */ +void softpipe_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->viewport = *viewport; /* struct copy */ + softpipe->dirty |= SP_NEW_VIEWPORT; + + /* pass the viewport info to the draw module */ + draw_set_viewport_state(softpipe->draw, viewport); + + /* Using tnl/ and vf/ modules is temporary while getting started. + * Full pipe will have vertex shader, vertex fetch of its own. + */ +} + + +void softpipe_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + memcpy( &softpipe->scissor, scissor, sizeof(*scissor) ); + softpipe->dirty |= SP_NEW_SCISSOR; +} + + +void softpipe_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + memcpy( &softpipe->poly_stipple, stipple, sizeof(*stipple) ); + softpipe->dirty |= SP_NEW_STIPPLE; +} diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c new file mode 100644 index 0000000000..372597869f --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -0,0 +1,235 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/draw/draw_context.h" +#include "pipe/draw/draw_vertex.h" +#include "pipe/draw/draw_private.h" +#include "sp_context.h" +#include "sp_state.h" + + +/** + * Search vertex program's outputs to find a match for the given + * semantic name/index. Return the index of the output slot. + * + * Return 0 if not found. This will cause the fragment program to use + * vertex attrib 0 (position) in the cases where the fragment program + * attempts to use a missing vertex program output. This is an undefined + * condition that users shouldn't hit anyway. + */ +static int +find_vs_output(const struct pipe_shader_state *vs, + uint semantic_name, + uint semantic_index) +{ + uint i; + for (i = 0; i < vs->num_outputs; i++) { + if (vs->output_semantic_name[i] == semantic_name && + vs->output_semantic_index[i] == semantic_index) + return i; + } + return 0; +} + + +/** + * Mark the current vertex layout as "invalid". + * We'll validate the vertex layout later, when we start to actually + * render a point or line or tri. + */ +static void +invalidate_vertex_layout(struct softpipe_context *softpipe) +{ + softpipe->vertex_info.num_attribs = 0; +} + + +/** + * The vertex info describes how to convert the post-transformed vertices + * (simple float[][4]) used by the 'draw' module into vertices for + * rasterization. + * + * This function validates the vertex layout and returns a pointer to a + * vertex_info object. + */ +struct vertex_info * +softpipe_get_vertex_info(struct softpipe_context *softpipe) +{ + struct vertex_info *vinfo = &softpipe->vertex_info; + + if (vinfo->num_attribs == 0) { + /* compute vertex layout now */ + const struct pipe_shader_state *vs = &softpipe->vs->shader; + const struct pipe_shader_state *fs = &softpipe->fs->shader; + const enum interp_mode colorInterp + = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; + uint i; + + if (softpipe->vbuf) { + /* if using the post-transform vertex buffer, tell draw_vbuf to + * simply emit the whole post-xform vertex as-is: + */ + struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; + vinfo_vbuf->num_attribs = 0; + draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0); + vinfo_vbuf->size = 4 * vs->num_outputs + + sizeof(struct vertex_header) / 4; + } + + /* + * Loop over fragment shader inputs, searching for the matching output + * from the vertex shader. + */ + vinfo->num_attribs = 0; + for (i = 0; i < fs->num_inputs; i++) { + int src; + switch (fs->input_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src); + break; + + case TGSI_SEMANTIC_COLOR: + src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, + fs->input_semantic_index[i]); + draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); + break; + + case TGSI_SEMANTIC_FOG: + src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); + break; + + case TGSI_SEMANTIC_GENERIC: + /* this includes texcoords and varying vars */ + src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC, + fs->input_semantic_index[i]); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); + break; + + default: + assert(0); + } + } + + softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0); + if (softpipe->psize_slot > 0) { + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, + softpipe->psize_slot); + } + + draw_compute_vertex_size(vinfo); + } + + return vinfo; +} + + +/** + * Called from vbuf module. + * + * Note that there's actually two different vertex layouts in softpipe. + * + * The normal one is computed in softpipe_get_vertex_info() above and is + * used by the point/line/tri "setup" code. + * + * The other one (this one) is only used by the vbuf module (which is + * not normally used by default but used in testing). For the vbuf module, + * we basically want to pass-through the draw module's vertex layout as-is. + * When the softpipe vbuf code begins drawing, the normal vertex layout + * will come into play again. + */ +struct vertex_info * +softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe) +{ + (void) softpipe_get_vertex_info(softpipe); + return &softpipe->vertex_info_vbuf; +} + + +/** + * Recompute cliprect from scissor bounds, scissor enable and surface size. + */ +static void +compute_cliprect(struct softpipe_context *sp) +{ + unsigned surfWidth, surfHeight; + + if (sp->framebuffer.num_cbufs > 0) { + surfWidth = sp->framebuffer.cbufs[0]->width; + surfHeight = sp->framebuffer.cbufs[0]->height; + } + else { + /* no surface? */ + surfWidth = sp->scissor.maxx; + surfHeight = sp->scissor.maxy; + } + + if (sp->rasterizer->scissor) { + /* clip to scissor rect */ + sp->cliprect.minx = MAX2(sp->scissor.minx, 0); + sp->cliprect.miny = MAX2(sp->scissor.miny, 0); + sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth); + sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight); + } + else { + /* clip to surface bounds */ + sp->cliprect.minx = 0; + sp->cliprect.miny = 0; + sp->cliprect.maxx = surfWidth; + sp->cliprect.maxy = surfHeight; + } +} + + +/* Hopefully this will remain quite simple, otherwise need to pull in + * something like the state tracker mechanism. + */ +void softpipe_update_derived( struct softpipe_context *softpipe ) +{ + if (softpipe->dirty & (SP_NEW_RASTERIZER | + SP_NEW_FS | + SP_NEW_VS)) + invalidate_vertex_layout( softpipe ); + + if (softpipe->dirty & (SP_NEW_SCISSOR | + SP_NEW_DEPTH_STENCIL_ALPHA | + SP_NEW_FRAMEBUFFER)) + compute_cliprect(softpipe); + + if (softpipe->dirty & (SP_NEW_BLEND | + SP_NEW_DEPTH_STENCIL_ALPHA | + SP_NEW_FRAMEBUFFER | + SP_NEW_RASTERIZER | + SP_NEW_FS | + SP_NEW_QUERY)) + sp_build_quad_pipeline(softpipe); + + softpipe->dirty = 0; +} diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c new file mode 100644 index 0000000000..0b814fc284 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -0,0 +1,179 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "sp_context.h" +#include "sp_state.h" + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" +#include "pipe/draw/draw_context.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/llvm/gallivm.h" +#include "pipe/tgsi/util/tgsi_dump.h" +#include "pipe/tgsi/exec/tgsi_sse2.h" + + +void * +softpipe_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + struct sp_fragment_shader_state *state; + + /* Decide whether we'll be codegenerating this shader and if so do + * that now. + */ + + state = CALLOC_STRUCT(sp_fragment_shader_state); + if (!state) + return NULL; + + state->shader = *templ; + + if (softpipe->dump_fs) { + tgsi_dump(state->shader.tokens, 0); + } + +#ifdef MESA_LLVM + state->llvm_prog = 0; + +#if 0 + if (!gallivm_global_cpu_engine()) { + gallivm_cpu_engine_create(state->llvm_prog); + } + else + gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); +#endif + +#elif defined(__i386__) || defined(__386__) + if (softpipe->use_sse) { + x86_init_func( &state->sse2_program ); + tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program ); + } +#endif + + return state; +} + + +void +softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->fs = (struct sp_fragment_shader_state *) fs; + + softpipe->dirty |= SP_NEW_FS; +} + + +void +softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct sp_fragment_shader_state *state = fs; + +#if defined(__i386__) || defined(__386__) + x86_release_func( &state->sse2_program ); +#endif + + FREE( state ); +} + + +void * +softpipe_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + struct sp_vertex_shader_state *state; + + state = CALLOC_STRUCT(sp_vertex_shader_state); + if (state == NULL ) { + return NULL; + } + + state->shader = *templ; + + state->draw_data = draw_create_vertex_shader(softpipe->draw, + &state->shader); + if (state->draw_data == NULL) { + FREE( state ); + return NULL; + } + + return state; +} + + +void +softpipe_bind_vs_state(struct pipe_context *pipe, void *vs) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->vs = (const struct sp_vertex_shader_state *)vs; + + draw_bind_vertex_shader(softpipe->draw, softpipe->vs->draw_data); + + softpipe->dirty |= SP_NEW_VS; +} + + +void +softpipe_delete_vs_state(struct pipe_context *pipe, void *vs) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + struct sp_vertex_shader_state *state = + (struct sp_vertex_shader_state *)vs; + + draw_delete_vertex_shader(softpipe->draw, state->draw_data); + FREE( state ); +} + + + +void +softpipe_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + + assert(shader < PIPE_SHADER_TYPES); + assert(index == 0); + + /* note: reference counting */ + pipe_buffer_reference(ws, + &softpipe->constants[shader].buffer, + buf->buffer); + softpipe->constants[shader].size = buf->size; + + softpipe->dirty |= SP_NEW_CONSTANTS; +} diff --git a/src/gallium/drivers/softpipe/sp_state_rasterizer.c b/src/gallium/drivers/softpipe/sp_state_rasterizer.c new file mode 100644 index 0000000000..53755099dd --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_state_rasterizer.c @@ -0,0 +1,62 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "sp_context.h" +#include "sp_state.h" +#include "pipe/draw/draw_context.h" + + + +void * +softpipe_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *rast) +{ + return mem_dup(rast, sizeof(*rast)); +} + +void softpipe_bind_rasterizer_state(struct pipe_context *pipe, + void *setup) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + /* pass-through to draw module */ + draw_set_rasterizer_state(softpipe->draw, setup); + + softpipe->rasterizer = (struct pipe_rasterizer_state *)setup; + + softpipe->dirty |= SP_NEW_RASTERIZER; +} + +void softpipe_delete_rasterizer_state(struct pipe_context *pipe, + void *rasterizer) +{ + FREE( rasterizer ); +} + + diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c new file mode 100644 index 0000000000..ea348c7e95 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -0,0 +1,93 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: + * Brian Paul + */ + +#include "pipe/p_util.h" + +#include "pipe/draw/draw_context.h" + +#include "sp_context.h" +#include "sp_context.h" +#include "sp_state.h" +#include "sp_texture.h" +#include "sp_tile_cache.h" +#include "pipe/draw/draw_context.h" + + + +void * +softpipe_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + return mem_dup(sampler, sizeof(*sampler)); +} + +void +softpipe_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, void *sampler) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + draw_flush(softpipe->draw); + + assert(unit < PIPE_MAX_SAMPLERS); + softpipe->sampler[unit] = (struct pipe_sampler_state *)sampler; + + softpipe->dirty |= SP_NEW_SAMPLER; +} + + +void +softpipe_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + FREE( sampler ); +} + + +void +softpipe_set_sampler_texture(struct pipe_context *pipe, + unsigned unit, + struct pipe_texture *texture) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + draw_flush(softpipe->draw); + + assert(unit < PIPE_MAX_SAMPLERS); + softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */ + + sp_tile_cache_set_texture(softpipe->tex_cache[unit], texture); + + softpipe->dirty |= SP_NEW_TEXTURE; +} + + + diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c new file mode 100644 index 0000000000..e2c6893e9f --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -0,0 +1,109 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ +#include "p_inlines.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_surface.h" +#include "sp_tile_cache.h" + + +/** + * XXX this might get moved someday + * Set the framebuffer surface info: color buffers, zbuffer, stencil buffer. + * Here, we flush the old surfaces and update the tile cache to point to the new + * surfaces. + */ +void +softpipe_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct softpipe_context *sp = softpipe_context(pipe); + uint i; + + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { + /* check if changing cbuf */ + if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) { + /* flush old */ + sp_flush_tile_cache(sp, sp->cbuf_cache[i]); + + /* assign new */ + sp->framebuffer.cbufs[i] = fb->cbufs[i]; + + /* update cache */ + sp_tile_cache_set_surface(sp->cbuf_cache[i], fb->cbufs[i]); + } + } + + sp->framebuffer.num_cbufs = fb->num_cbufs; + + /* zbuf changing? */ + if (sp->framebuffer.zsbuf != fb->zsbuf) { + /* flush old */ + sp_flush_tile_cache(sp, sp->zsbuf_cache); + + /* assign new */ + sp->framebuffer.zsbuf = fb->zsbuf; + + /* update cache */ + sp_tile_cache_set_surface(sp->zsbuf_cache, fb->zsbuf); + } + +#if 0 + /* XXX combined depth/stencil here */ + + /* sbuf changing? */ + if (sp->framebuffer.sbuf != fb->sbuf) { + /* flush old */ + sp_flush_tile_cache(sp, sp->sbuf_cache_sep); + + /* assign new */ + sp->framebuffer.sbuf = fb->sbuf; + + /* update cache */ + if (fb->sbuf != fb->zbuf) { + /* separate stencil buf */ + sp->sbuf_cache = sp->sbuf_cache_sep; + sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf); + } + else { + /* combined depth/stencil */ + sp->sbuf_cache = sp->zbuf_cache; + sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf); + } + } +#endif + + sp->dirty |= SP_NEW_FRAMEBUFFER; +} + + + + diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c new file mode 100644 index 0000000000..09ff540ccf --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -0,0 +1,64 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_surface.h" + +#include "pipe/draw/draw_context.h" + + +void +softpipe_set_vertex_element(struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_element *attrib) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + assert(index < PIPE_ATTRIB_MAX); + softpipe->vertex_element[index] = *attrib; /* struct copy */ + softpipe->dirty |= SP_NEW_VERTEX; + + draw_set_vertex_element(softpipe->draw, index, attrib); +} + + +void +softpipe_set_vertex_buffer(struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_buffer *buffer) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + assert(index < PIPE_ATTRIB_MAX); + softpipe->vertex_buffer[index] = *buffer; /* struct copy */ + softpipe->dirty |= SP_NEW_VERTEX; + + draw_set_vertex_buffer(softpipe->draw, index, buffer); +} diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c new file mode 100644 index 0000000000..8802ced187 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -0,0 +1,159 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" +#include "pipe/util/p_tile.h" +#include "sp_context.h" +#include "sp_surface.h" + + + +/* Assumes all values are within bounds -- no checking at this level - + * do it higher up if required. + */ +static void +sp_surface_copy(struct pipe_context *pipe, + unsigned do_flip, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, unsigned width, unsigned height) +{ + assert( dst->cpp == src->cpp ); + + pipe_copy_rect(pipe_surface_map(dst), + dst->cpp, + dst->pitch, + dstx, dsty, + width, height, + pipe_surface_map(src), + do_flip ? -(int) src->pitch : src->pitch, + srcx, do_flip ? 1 - srcy - height : srcy); + + pipe_surface_unmap(src); + pipe_surface_unmap(dst); +} + + +static void * +get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) +{ + return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; +} + + +#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8)) + + +/** + * Fill a rectangular sub-region. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ +static void +sp_surface_fill(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, unsigned value) +{ + unsigned i, j; + void *dst_map = pipe_surface_map(dst); + + assert(dst->pitch > 0); + assert(width <= dst->pitch); + + + switch (dst->cpp) { + case 1: + { + ubyte *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + memset(row, value, width); + row += dst->pitch; + } + } + break; + case 2: + { + ushort *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = (ushort) value; + row += dst->pitch; + } + } + break; + case 4: + { + unsigned *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = value; + row += dst->pitch; + } + } + break; + case 8: + { + /* expand the 4-byte clear value to an 8-byte value */ + ushort *row = (ushort *) get_pointer(dst, dst_map, dstx, dsty); + ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff); + ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff); + ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff); + ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff); + val0 = (val0 << 8) | val0; + val1 = (val1 << 8) | val1; + val2 = (val2 << 8) | val2; + val3 = (val3 << 8) | val3; + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + row[j*4+0] = val0; + row[j*4+1] = val1; + row[j*4+2] = val2; + row[j*4+3] = val3; + } + row += dst->pitch * 4; + } + } + break; + default: + assert(0); + break; + } + + pipe_surface_unmap( dst ); +} + + +void +sp_init_surface_functions(struct softpipe_context *sp) +{ + sp->pipe.surface_copy = sp_surface_copy; + sp->pipe.surface_fill = sp_surface_fill; +} diff --git a/src/gallium/drivers/softpipe/sp_surface.h b/src/gallium/drivers/softpipe/sp_surface.h new file mode 100644 index 0000000000..22de3ba43f --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_surface.h @@ -0,0 +1,42 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_SURFACE_H +#define SP_SURFACE_H + + +struct softpipe_context; + + +extern void +sp_init_surface_functions(struct softpipe_context *sp); + + +#endif /* SP_SURFACE_H */ diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c new file mode 100644 index 0000000000..325bdb86da --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -0,0 +1,916 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Texture sampling + * + * Authors: + * Brian Paul + */ + +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_tex_sample.h" +#include "sp_tile_cache.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/tgsi/exec/tgsi_exec.h" + + +/* + * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes + * see 1-pixel bands of improperly weighted linear-filtered textures. + * The tests/texwrap.c demo is a good test. + * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. + * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). + */ +#define FRAC(f) ((f) - ifloor(f)) + + +/** + * Linear interpolation macro + */ +#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) + + +/** + * Do 2D/biliner interpolation of float values. + * v00, v10, v01 and v11 are typically four texture samples in a square/box. + * a and b are the horizontal and vertical interpolants. + * It's important that this function is inlined when compiled with + * optimization! If we find that's not true on some systems, convert + * to a macro. + */ +static INLINE float +lerp_2d(float a, float b, + float v00, float v10, float v01, float v11) +{ + const float temp0 = LERP(a, v00, v10); + const float temp1 = LERP(a, v01, v11); + return LERP(b, temp0, temp1); +} + + +/** + * If A is a signed integer, A % B doesn't give the right value for A < 0 + * (in terms of texture repeat). Just casting to unsigned fixes that. + */ +#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B)) + + +/** + * Apply texture coord wrapping mode and return integer texture index. + * \param wrapMode PIPE_TEX_WRAP_x + * \param s the texcoord + * \param size the texture image size + * \return integer texture index + */ +static INLINE int +nearest_texcoord(unsigned wrapMode, float s, unsigned size) +{ + int i; + switch (wrapMode) { + case PIPE_TEX_WRAP_REPEAT: + /* s limited to [0,1) */ + /* i limited to [0,size-1] */ + i = ifloor(s * size); + i = REMAINDER(i, size); + return i; + case PIPE_TEX_WRAP_CLAMP: + /* s limited to [0,1] */ + /* i limited to [0,size-1] */ + if (s <= 0.0F) + i = 0; + else if (s >= 1.0F) + i = size - 1; + else + i = ifloor(s * size); + return i; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const float min = 1.0F / (2.0F * size); + const float max = 1.0F - min; + if (s < min) + i = 0; + else if (s > max) + i = size - 1; + else + i = ifloor(s * size); + } + return i; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + { + /* s limited to [min,max] */ + /* i limited to [-1, size] */ + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + if (s <= min) + i = -1; + else if (s >= max) + i = size; + else + i = ifloor(s * size); + } + return i; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + { + const float min = 1.0F / (2.0F * size); + const float max = 1.0F - min; + const int flr = ifloor(s); + float u; + if (flr & 1) + u = 1.0F - (s - (float) flr); + else + u = s - (float) flr; + if (u < min) + i = 0; + else if (u > max) + i = size - 1; + else + i = ifloor(u * size); + } + return i; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + { + /* s limited to [0,1] */ + /* i limited to [0,size-1] */ + const float u = FABSF(s); + if (u <= 0.0F) + i = 0; + else if (u >= 1.0F) + i = size - 1; + else + i = ifloor(u * size); + } + return i; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const float min = 1.0F / (2.0F * size); + const float max = 1.0F - min; + const float u = FABSF(s); + if (u < min) + i = 0; + else if (u > max) + i = size - 1; + else + i = ifloor(u * size); + } + return i; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + const float u = FABSF(s); + if (u < min) + i = -1; + else if (u > max) + i = size; + else + i = ifloor(u * size); + } + return i; + default: + assert(0); + return 0; + } +} + + +/** + * Used to compute texel locations for linear sampling. + * \param wrapMode PIPE_TEX_WRAP_x + * \param s the texcoord + * \param size the texture image size + * \param i0 returns first texture index + * \param i1 returns second texture index (usually *i0 + 1) + * \param a returns blend factor/weight between texture indexes + */ +static INLINE void +linear_texcoord(unsigned wrapMode, float s, unsigned size, + int *i0, int *i1, float *a) +{ + float u; + switch (wrapMode) { + case PIPE_TEX_WRAP_REPEAT: + u = s * size - 0.5F; + *i0 = REMAINDER(ifloor(u), size); + *i1 = REMAINDER(*i0 + 1, size); + break; + case PIPE_TEX_WRAP_CLAMP: + if (s <= 0.0F) + u = 0.0F; + else if (s >= 1.0F) + u = (float) size; + else + u = s * size; + u -= 0.5F; + *i0 = ifloor(u); + *i1 = *i0 + 1; + break; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + if (s <= 0.0F) + u = 0.0F; + else if (s >= 1.0F) + u = (float) size; + else + u = s * size; + u -= 0.5F; + *i0 = ifloor(u); + *i1 = *i0 + 1; + if (*i0 < 0) + *i0 = 0; + if (*i1 >= (int) size) + *i1 = size - 1; + break; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + { + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + if (s <= min) + u = min * size; + else if (s >= max) + u = max * size; + else + u = s * size; + u -= 0.5F; + *i0 = ifloor(u); + *i1 = *i0 + 1; + } + break; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + { + const int flr = ifloor(s); + if (flr & 1) + u = 1.0F - (s - (float) flr); + else + u = s - (float) flr; + u = (u * size) - 0.5F; + *i0 = ifloor(u); + *i1 = *i0 + 1; + if (*i0 < 0) + *i0 = 0; + if (*i1 >= (int) size) + *i1 = size - 1; + } + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + u = FABSF(s); + if (u >= 1.0F) + u = (float) size; + else + u *= size; + u -= 0.5F; + *i0 = ifloor(u); + *i1 = *i0 + 1; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + u = FABSF(s); + if (u >= 1.0F) + u = (float) size; + else + u *= size; + u -= 0.5F; + *i0 = ifloor(u); + *i1 = *i0 + 1; + if (*i0 < 0) + *i0 = 0; + if (*i1 >= (int) size) + *i1 = size - 1; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + { + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + u = FABSF(s); + if (u <= min) + u = min * size; + else if (u >= max) + u = max * size; + else + u *= size; + u -= 0.5F; + *i0 = ifloor(u); + *i1 = *i0 + 1; + } + break; + default: + assert(0); + } + *a = FRAC(u); +} + + +static unsigned +choose_cube_face(float rx, float ry, float rz, float *newS, float *newT) +{ + /* + major axis + direction target sc tc ma + ---------- ------------------------------- --- --- --- + +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx + -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx + +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry + -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry + +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz + -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz + */ + const float arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz); + unsigned face; + float sc, tc, ma; + + if (arx > ary && arx > arz) { + if (rx >= 0.0F) { + face = PIPE_TEX_FACE_POS_X; + sc = -rz; + tc = -ry; + ma = arx; + } + else { + face = PIPE_TEX_FACE_NEG_X; + sc = rz; + tc = -ry; + ma = arx; + } + } + else if (ary > arx && ary > arz) { + if (ry >= 0.0F) { + face = PIPE_TEX_FACE_POS_Y; + sc = rx; + tc = rz; + ma = ary; + } + else { + face = PIPE_TEX_FACE_NEG_Y; + sc = rx; + tc = -rz; + ma = ary; + } + } + else { + if (rz > 0.0F) { + face = PIPE_TEX_FACE_POS_Z; + sc = rx; + tc = -ry; + ma = arz; + } + else { + face = PIPE_TEX_FACE_NEG_Z; + sc = -rx; + tc = -ry; + ma = arz; + } + } + + *newS = ( sc / ma + 1.0F ) * 0.5F; + *newT = ( tc / ma + 1.0F ) * 0.5F; + + return face; +} + + +/** + * Examine the quad's texture coordinates to compute the partial + * derivatives w.r.t X and Y, then compute lambda (level of detail). + * + * This is only done for fragment shaders, not vertex shaders. + */ +static float +compute_lambda(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias) +{ + float rho, lambda; + + assert(s); + { + float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; + float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; + dsdx = FABSF(dsdx); + dsdy = FABSF(dsdy); + rho = MAX2(dsdx, dsdy); + if (sampler->state->normalized_coords) + rho *= sampler->texture->width[0]; + } + if (t) { + float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; + float dtdy = t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]; + float max; + dtdx = FABSF(dtdx); + dtdy = FABSF(dtdy); + max = MAX2(dtdx, dtdy); + if (sampler->state->normalized_coords) + max *= sampler->texture->height[0]; + rho = MAX2(rho, max); + } + if (p) { + float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]; + float dpdy = p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]; + float max; + dpdx = FABSF(dpdx); + dpdy = FABSF(dpdy); + max = MAX2(dpdx, dpdy); + if (sampler->state->normalized_coords) + max *= sampler->texture->depth[0]; + rho = MAX2(rho, max); + } + + lambda = LOG2(rho); + lambda += lodbias + sampler->state->lod_bias; + lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod); + + return lambda; +} + + +/** + * Do several things here: + * 1. Compute lambda from the texcoords, if needed + * 2. Determine if we're minifying or magnifying + * 3. If minifying, choose mipmap levels + * 4. Return image filter to use within mipmap images + */ +static void +choose_mipmap_levels(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + unsigned *level0, unsigned *level1, float *levelBlend, + unsigned *imgFilter) +{ + if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { + /* no mipmap selection needed */ + *imgFilter = sampler->state->mag_img_filter; + *level0 = *level1 = (int) sampler->state->min_lod; + } + else { + float lambda; + + if (1) + /* fragment shader */ + lambda = compute_lambda(sampler, s, t, p, lodbias); + else + /* vertex shader */ + lambda = lodbias; /* not really a bias, but absolute LOD */ + + if (lambda < 0.0) { /* XXX threshold depends on the filter */ + /* magnifying */ + *imgFilter = sampler->state->mag_img_filter; + *level0 = *level1 = 0; + } + else { + /* minifying */ + *imgFilter = sampler->state->min_img_filter; + + /* choose mipmap level(s) and compute the blend factor between them */ + if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) { + /* Nearest mipmap level */ + const int lvl = (int) (lambda + 0.5); + *level0 = + *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level); + } + else { + /* Linear interpolation between mipmap levels */ + const int lvl = (int) lambda; + *level0 = CLAMP(lvl, 0, (int) sampler->texture->last_level); + *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level); + *levelBlend = FRAC(lambda); /* blending weight between levels */ + } + } + } +} + + +/** + * Get a texel from a texture, using the texture tile cache. + * + * \param face the cube face in 0..5 + * \param level the mipmap level + * \param x the x coord of texel within 2D image + * \param y the y coord of texel within 2D image + * \param z which slice of a 3D texture + * \param rgba the quad to put the texel/color into + * \param j which element of the rgba quad to write to + * + * XXX maybe move this into sp_tile_cache.c and merge with the + * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... + */ +static void +get_texel(struct tgsi_sampler *sampler, + unsigned face, unsigned level, int x, int y, int z, + float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) +{ + const int tx = x % TILE_SIZE; + const int ty = y % TILE_SIZE; + const struct softpipe_cached_tile *tile + = sp_get_cached_tile_tex(sampler->pipe, sampler->cache, + x, y, z, face, level); + rgba[0][j] = tile->data.color[ty][tx][0]; + rgba[1][j] = tile->data.color[ty][tx][1]; + rgba[2][j] = tile->data.color[ty][tx][2]; + rgba[3][j] = tile->data.color[ty][tx][3]; +} + + +/** + * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' + * When we sampled the depth texture, the depth value was put into all + * RGBA channels. We look at the red channel here. + */ +static INLINE void +shadow_compare(uint compare_func, + float rgba[NUM_CHANNELS][QUAD_SIZE], + const float p[QUAD_SIZE], + uint j) +{ + int k; + switch (compare_func) { + case PIPE_FUNC_LESS: + k = p[j] < rgba[0][j]; + break; + case PIPE_FUNC_LEQUAL: + k = p[j] <= rgba[0][j]; + break; + case PIPE_FUNC_GREATER: + k = p[j] > rgba[0][j]; + break; + case PIPE_FUNC_GEQUAL: + k = p[j] >= rgba[0][j]; + break; + case PIPE_FUNC_EQUAL: + k = p[j] == rgba[0][j]; + break; + case PIPE_FUNC_NOTEQUAL: + k = p[j] != rgba[0][j]; + break; + case PIPE_FUNC_ALWAYS: + k = 1; + break; + case PIPE_FUNC_NEVER: + k = 0; + break; + default: + assert(0); + } + + rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; +} + + +/** + * Common code for sampling 1D/2D/cube textures. + * Could probably extend for 3D... + */ +static void +sp_get_samples_2d_common(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE], + const unsigned faces[4]) +{ + const uint compare_func = sampler->state->compare_func; + unsigned level0, level1, j, imgFilter; + int width, height; + float levelBlend; + + choose_mipmap_levels(sampler, s, t, p, lodbias, + &level0, &level1, &levelBlend, &imgFilter); + + if (sampler->state->normalized_coords) { + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; + } + else { + width = height = 1; + } + + assert(width > 0); + + switch (imgFilter) { + case PIPE_TEX_FILTER_NEAREST: + for (j = 0; j < QUAD_SIZE; j++) { + int x = nearest_texcoord(sampler->state->wrap_s, s[j], width); + int y = nearest_texcoord(sampler->state->wrap_t, t[j], height); + get_texel(sampler, faces[j], level0, x, y, 0, rgba, j); + if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + shadow_compare(compare_func, rgba, p, j); + } + + if (level0 != level1) { + /* get texels from second mipmap level and blend */ + float rgba2[4][4]; + unsigned c; + x = x / 2; + y = y / 2; + get_texel(sampler, faces[j], level1, x, y, 0, rgba2, j); + if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ + shadow_compare(compare_func, rgba2, p, j); + } + + for (c = 0; c < NUM_CHANNELS; c++) { + rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); + } + } + } + break; + case PIPE_TEX_FILTER_LINEAR: + for (j = 0; j < QUAD_SIZE; j++) { + float tx[4][4], a, b; + int x0, y0, x1, y1, c; + linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &a); + linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &b); + get_texel(sampler, faces[j], level0, x0, y0, 0, tx, 0); + get_texel(sampler, faces[j], level0, x1, y0, 0, tx, 1); + get_texel(sampler, faces[j], level0, x0, y1, 0, tx, 2); + get_texel(sampler, faces[j], level0, x1, y1, 0, tx, 3); + if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + shadow_compare(compare_func, tx, p, 0); + shadow_compare(compare_func, tx, p, 1); + shadow_compare(compare_func, tx, p, 2); + shadow_compare(compare_func, tx, p, 3); + } + + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]); + } + + if (level0 != level1) { + /* get texels from second mipmap level and blend */ + float rgba2[4][4]; + x0 = x0 / 2; + y0 = y0 / 2; + x1 = x1 / 2; + y1 = y1 / 2; + get_texel(sampler, faces[j], level1, x0, y0, 0, tx, 0); + get_texel(sampler, faces[j], level1, x1, y0, 0, tx, 1); + get_texel(sampler, faces[j], level1, x0, y1, 0, tx, 2); + get_texel(sampler, faces[j], level1, x1, y1, 0, tx, 3); + if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ + shadow_compare(compare_func, tx, p, 0); + shadow_compare(compare_func, tx, p, 1); + shadow_compare(compare_func, tx, p, 2); + shadow_compare(compare_func, tx, p, 3); + } + + for (c = 0; c < 4; c++) { + rgba2[c][j] = lerp_2d(a, b, + tx[c][0], tx[c][1], tx[c][2], tx[c][3]); + } + + for (c = 0; c < NUM_CHANNELS; c++) { + rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); + } + } + } + break; + default: + assert(0); + } +} + + +static void +sp_get_samples_1d(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + static const unsigned faces[4] = {0, 0, 0, 0}; + static const float tzero[4] = {0, 0, 0, 0}; + sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces); +} + + +static void +sp_get_samples_2d(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + static const unsigned faces[4] = {0, 0, 0, 0}; + sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); +} + + +static void +sp_get_samples_3d(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + /* get/map pipe_surfaces corresponding to 3D tex slices */ + unsigned level0, level1, j, imgFilter; + int width, height, depth; + float levelBlend; + const uint face = 0; + + choose_mipmap_levels(sampler, s, t, p, lodbias, + &level0, &level1, &levelBlend, &imgFilter); + + if (sampler->state->normalized_coords) { + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; + depth = sampler->texture->depth[level0]; + } + else { + width = height = depth = 1; + } + + assert(width > 0); + assert(height > 0); + assert(depth > 0); + + switch (imgFilter) { + case PIPE_TEX_FILTER_NEAREST: + for (j = 0; j < QUAD_SIZE; j++) { + int x = nearest_texcoord(sampler->state->wrap_s, s[j], width); + int y = nearest_texcoord(sampler->state->wrap_t, t[j], height); + int z = nearest_texcoord(sampler->state->wrap_r, p[j], depth); + get_texel(sampler, face, level0, x, y, z, rgba, j); + + if (level0 != level1) { + /* get texels from second mipmap level and blend */ + float rgba2[4][4]; + unsigned c; + x /= 2; + y /= 2; + z /= 2; + get_texel(sampler, face, level1, x, y, z, rgba2, j); + for (c = 0; c < NUM_CHANNELS; c++) { + rgba[c][j] = LERP(levelBlend, rgba2[c][j], rgba[c][j]); + } + } + } + break; + case PIPE_TEX_FILTER_LINEAR: + for (j = 0; j < QUAD_SIZE; j++) { + float texel0[4][4], texel1[4][4]; + float xw, yw, zw; /* interpolation weights */ + int x0, x1, y0, y1, z0, z1, c; + linear_texcoord(sampler->state->wrap_s, s[j], width, &x0, &x1, &xw); + linear_texcoord(sampler->state->wrap_t, t[j], height, &y0, &y1, &yw); + linear_texcoord(sampler->state->wrap_r, p[j], depth, &z0, &z1, &zw); + get_texel(sampler, face, level0, x0, y0, z0, texel0, 0); + get_texel(sampler, face, level0, x1, y0, z0, texel0, 1); + get_texel(sampler, face, level0, x0, y1, z0, texel0, 2); + get_texel(sampler, face, level0, x1, y1, z0, texel0, 3); + get_texel(sampler, face, level0, x0, y0, z1, texel1, 0); + get_texel(sampler, face, level0, x1, y0, z1, texel1, 1); + get_texel(sampler, face, level0, x0, y1, z1, texel1, 2); + get_texel(sampler, face, level0, x1, y1, z1, texel1, 3); + + /* 3D lerp */ + for (c = 0; c < 4; c++) { + float ctemp0[4][4], ctemp1[4][4]; + ctemp0[c][j] = lerp_2d(xw, yw, + texel0[c][0], texel0[c][1], + texel0[c][2], texel0[c][3]); + ctemp1[c][j] = lerp_2d(xw, yw, + texel1[c][0], texel1[c][1], + texel1[c][2], texel1[c][3]); + rgba[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]); + } + + if (level0 != level1) { + /* get texels from second mipmap level and blend */ + float rgba2[4][4]; + x0 /= 2; + y0 /= 2; + z0 /= 2; + x1 /= 2; + y1 /= 2; + z1 /= 2; + get_texel(sampler, face, level1, x0, y0, z0, texel0, 0); + get_texel(sampler, face, level1, x1, y0, z0, texel0, 1); + get_texel(sampler, face, level1, x0, y1, z0, texel0, 2); + get_texel(sampler, face, level1, x1, y1, z0, texel0, 3); + get_texel(sampler, face, level1, x0, y0, z1, texel1, 0); + get_texel(sampler, face, level1, x1, y0, z1, texel1, 1); + get_texel(sampler, face, level1, x0, y1, z1, texel1, 2); + get_texel(sampler, face, level1, x1, y1, z1, texel1, 3); + + /* 3D lerp */ + for (c = 0; c < 4; c++) { + float ctemp0[4][4], ctemp1[4][4]; + ctemp0[c][j] = lerp_2d(xw, yw, + texel0[c][0], texel0[c][1], + texel0[c][2], texel0[c][3]); + ctemp1[c][j] = lerp_2d(xw, yw, + texel1[c][0], texel1[c][1], + texel1[c][2], texel1[c][3]); + rgba2[c][j] = LERP(zw, ctemp0[c][j], ctemp1[c][j]); + } + + /* blend mipmap levels */ + for (c = 0; c < NUM_CHANNELS; c++) { + rgba[c][j] = LERP(levelBlend, rgba[c][j], rgba2[c][j]); + } + } + } + break; + default: + assert(0); + } +} + + +static void +sp_get_samples_cube(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + unsigned faces[QUAD_SIZE], j; + float ssss[4], tttt[4]; + for (j = 0; j < QUAD_SIZE; j++) { + faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j); + } + sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces); +} + + +/** + * Called via tgsi_sampler::get_samples() + * Use the sampler's state setting to get a filtered RGBA value + * from the sampler's texture. + * + * XXX we can implement many versions of this function, each + * tightly coded for a specific combination of sampler state + * (nearest + repeat), (bilinear mipmap + clamp), etc. + * + * The update_samplers() function in st_atom_sampler.c could create + * a new tgsi_sampler object for each state combo it finds.... + */ +void +sp_get_samples(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + if (!sampler->texture) + return; + + switch (sampler->texture->target) { + case PIPE_TEXTURE_1D: + sp_get_samples_1d(sampler, s, t, p, lodbias, rgba); + break; + case PIPE_TEXTURE_2D: + sp_get_samples_2d(sampler, s, t, p, lodbias, rgba); + break; + case PIPE_TEXTURE_3D: + sp_get_samples_3d(sampler, s, t, p, lodbias, rgba); + break; + case PIPE_TEXTURE_CUBE: + sp_get_samples_cube(sampler, s, t, p, lodbias, rgba); + break; + default: + assert(0); + } +} + diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h new file mode 100644 index 0000000000..404bfd0c36 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -0,0 +1,17 @@ +#ifndef SP_TEX_SAMPLE_H +#define SP_TEX_SAMPLE_H + + +struct tgsi_sampler; + + +extern void +sp_get_samples(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]); + + +#endif /* SP_TEX_SAMPLE_H */ diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c new file mode 100644 index 0000000000..6de7a9b543 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -0,0 +1,166 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell + * Michel Dänzer + */ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_texture.h" + + +/* Simple, maximally packed layout. + */ + +static unsigned minify( unsigned d ) +{ + return MAX2(1, d>>1); +} + + +static void +softpipe_texture_layout(struct softpipe_texture * spt) +{ + struct pipe_texture *pt = &spt->base; + unsigned level; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; + + spt->buffer_size = 0; + + for (level = 0; level <= pt->last_level; level++) { + pt->width[level] = width; + pt->height[level] = height; + pt->depth[level] = depth; + + spt->level_offset[level] = spt->buffer_size; + + spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * + ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * + width * pt->cpp; + + width = minify(width); + height = minify(height); + depth = minify(depth); + } +} + + +struct pipe_texture * +softpipe_texture_create(struct pipe_context *pipe, + const struct pipe_texture *templat) +{ + struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); + if (!spt) + return NULL; + + spt->base = *templat; + + softpipe_texture_layout(spt); + + spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32, + PIPE_BUFFER_USAGE_PIXEL, + spt->buffer_size); + if (!spt->buffer) { + FREE(spt); + return NULL; + } + + return &spt->base; +} + + +void +softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + if (!*pt) + return; + + /* + DBG("%s %p refcount will be %d\n", + __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); + */ + if (--(*pt)->refcount <= 0) { + struct softpipe_texture *spt = softpipe_texture(*pt); + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); + */ + + pipe_buffer_reference(pipe->winsys, &spt->buffer, NULL); + + FREE(spt); + } + *pt = NULL; +} + + +/** + * Called via pipe->get_tex_surface() + */ +struct pipe_surface * +softpipe_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct softpipe_texture *spt = softpipe_texture(pt); + struct pipe_surface *ps; + + assert(level <= pt->last_level); + + ps = pipe->winsys->surface_alloc(pipe->winsys); + if (ps) { + assert(ps->refcount); + assert(ps->winsys); + pipe_buffer_reference(pipe->winsys, &ps->buffer, spt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = ps->width; + ps->offset = spt->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { + ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * + (pt->compressed ? ps->height/4 : ps->height) * + ps->width * ps->cpp; + } else { + assert(face == 0); + assert(zslice == 0); + } + } + return ps; +} diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h new file mode 100644 index 0000000000..fa646c0de9 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -0,0 +1,71 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SP_TEXTURE_H +#define SP_TEXTURE_H + + +struct pipe_context; +struct pipe_texture; + + +struct softpipe_texture +{ + struct pipe_texture base; + + unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; + unsigned long buffer_size; +}; + + +/** cast wrapper */ +static INLINE struct softpipe_texture * +softpipe_texture(struct pipe_texture *pt) +{ + return (struct softpipe_texture *) pt; +} + + + +extern struct pipe_texture * +softpipe_texture_create(struct pipe_context *pipe, + const struct pipe_texture *templat); + +extern void +softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); + +extern struct pipe_surface * +softpipe_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice); + + +#endif /* SP_TEXTURE */ diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c new file mode 100644 index 0000000000..1597361b82 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -0,0 +1,585 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Framebuffer/surface tile caching. + * + * Author: + * Brian Paul + */ + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/util/p_tile.h" +#include "sp_context.h" +#include "sp_surface.h" +#include "sp_tile_cache.h" + +#define NUM_ENTRIES 30 + + +/** XXX move these */ +#define MAX_WIDTH 2048 +#define MAX_HEIGHT 2048 + + +struct softpipe_tile_cache +{ + struct pipe_surface *surface; /**< the surface we're caching */ + void *surface_map; + struct pipe_texture *texture; /**< if caching a texture */ + struct softpipe_cached_tile entries[NUM_ENTRIES]; + uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; + float clear_color[4]; + uint clear_val; + boolean depth_stencil; /** Is the surface a depth/stencil format? */ + + struct pipe_surface *tex_surf; + void *tex_surf_map; + int tex_face, tex_level, tex_z; + + struct softpipe_cached_tile tile; /**< scratch tile for clears */ +}; + + +/** + * Return the position in the cache for the tile that contains win pos (x,y). + * We currently use a direct mapped cache so this is like a hack key. + * At some point we should investige something more sophisticated, like + * a LRU replacement policy. + */ +#define CACHE_POS(x, y) \ + (((x) / TILE_SIZE + ((y) / TILE_SIZE) * 5) % NUM_ENTRIES) + + + +/** + * Is the tile at (x,y) in cleared state? + */ +static INLINE uint +is_clear_flag_set(const uint *bitvec, int x, int y) +{ + int pos, bit; + x /= TILE_SIZE; + y /= TILE_SIZE; + pos = y * (MAX_WIDTH / TILE_SIZE) + x; + assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32); + bit = bitvec[pos / 32] & (1 << (pos & 31)); + return bit; +} + + +/** + * Mark the tile at (x,y) as not cleared. + */ +static INLINE void +clear_clear_flag(uint *bitvec, int x, int y) +{ + int pos; + x /= TILE_SIZE; + y /= TILE_SIZE; + pos = y * (MAX_WIDTH / TILE_SIZE) + x; + assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32); + bitvec[pos / 32] &= ~(1 << (pos & 31)); +} + + +struct softpipe_tile_cache * +sp_create_tile_cache(void) +{ + struct softpipe_tile_cache *tc; + uint pos; + + tc = CALLOC_STRUCT( softpipe_tile_cache ); + if (tc) { + for (pos = 0; pos < NUM_ENTRIES; pos++) { + tc->entries[pos].x = + tc->entries[pos].y = -1; + } + } + return tc; +} + + +void +sp_destroy_tile_cache(struct softpipe_tile_cache *tc) +{ + uint pos; + + for (pos = 0; pos < NUM_ENTRIES; pos++) { + //assert(tc->entries[pos].x < 0); + } + if (tc->surface) { + pipe_surface_reference(&tc->surface, NULL); + } + if (tc->tex_surf) { + pipe_surface_reference(&tc->tex_surf, NULL); + } + + FREE( tc ); +} + + +/** + * Specify the surface to cache. + */ +void +sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, + struct pipe_surface *ps) +{ + assert(!tc->texture); + + if (tc->surface_map) { + /*assert(tc->surface != ps);*/ + pipe_surface_unmap(tc->surface); + } + + pipe_surface_reference(&tc->surface, ps); + + if (ps) { + if (tc->surface_map) + tc->surface_map = pipe_surface_map(ps); + + tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || + ps->format == PIPE_FORMAT_Z16_UNORM || + ps->format == PIPE_FORMAT_Z32_UNORM || + ps->format == PIPE_FORMAT_U_S8); + } +} + + +/** + * Return the surface being cached. + */ +struct pipe_surface * +sp_tile_cache_get_surface(struct softpipe_tile_cache *tc) +{ + return tc->surface; +} + + +void +sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc) +{ + if (tc->surface && !tc->surface_map) + tc->surface_map = pipe_surface_map(tc->surface); + + if (tc->tex_surf && !tc->tex_surf_map) + tc->tex_surf_map = pipe_surface_map(tc->tex_surf); +} + + +void +sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc) +{ + if (tc->surface_map) { + pipe_surface_unmap(tc->surface); + tc->surface_map = NULL; + } + + if (tc->tex_surf_map) { + pipe_surface_unmap(tc->tex_surf); + tc->tex_surf_map = NULL; + } +} + + +/** + * Specify the texture to cache. + */ +void +sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, + struct pipe_texture *texture) +{ + uint i; + + assert(!tc->surface); + + tc->texture = texture; + + if (tc->tex_surf_map) { + pipe_surface_unmap(tc->tex_surf); + tc->tex_surf_map = NULL; + } + pipe_surface_reference(&tc->tex_surf, NULL); + + /* mark as entries as invalid/empty */ + /* XXX we should try to avoid this when the teximage hasn't changed */ + for (i = 0; i < NUM_ENTRIES; i++) { + tc->entries[i].x = -1; + } + + tc->tex_face = -1; /* any invalid value here */ +} + + +/** + * Set pixels in a tile to the given clear color/value, float. + */ +static void +clear_tile_rgba(struct softpipe_cached_tile *tile, + enum pipe_format format, + const float clear_value[4]) +{ + if (clear_value[0] == 0.0 && + clear_value[1] == 0.0 && + clear_value[2] == 0.0 && + clear_value[3] == 0.0) { + memset(tile->data.color, 0, sizeof(tile->data.color)); + } + else { + uint i, j; + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.color[i][j][0] = clear_value[0]; + tile->data.color[i][j][1] = clear_value[1]; + tile->data.color[i][j][2] = clear_value[2]; + tile->data.color[i][j][3] = clear_value[3]; + } + } + } +} + + +/** + * Set a tile to a solid value/color. + */ +static void +clear_tile(struct softpipe_cached_tile *tile, + enum pipe_format format, + uint clear_value) +{ + uint i, j; + + switch (pf_get_size(format)) { + case 1: + memset(tile->data.any, 0, TILE_SIZE * TILE_SIZE); + break; + case 2: + if (clear_value == 0) { + memset(tile->data.any, 0, 2 * TILE_SIZE * TILE_SIZE); + } + else { + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.depth16[i][j] = (ushort) clear_value; + } + } + } + break; + case 4: + if (clear_value == 0) { + memset(tile->data.any, 0, 4 * TILE_SIZE * TILE_SIZE); + } + else { + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.color32[i][j] = clear_value; + } + } + } + break; + default: + assert(0); + } +} + + +/** + * Actually clear the tiles which were flagged as being in a clear state. + */ +static void +sp_tile_cache_flush_clear(struct pipe_context *pipe, + struct softpipe_tile_cache *tc) +{ + struct pipe_surface *ps = tc->surface; + const uint w = tc->surface->width; + const uint h = tc->surface->height; + uint x, y; + uint numCleared = 0; + + /* clear the scratch tile to the clear value */ + clear_tile(&tc->tile, ps->format, tc->clear_val); + + /* push the tile to all positions marked as clear */ + for (y = 0; y < h; y += TILE_SIZE) { + for (x = 0; x < w; x += TILE_SIZE) { + if (is_clear_flag_set(tc->clear_flags, x, y)) { + pipe_put_tile_raw(pipe, ps, + x, y, TILE_SIZE, TILE_SIZE, + tc->tile.data.color32, 0/*STRIDE*/); + + /* do this? */ + clear_clear_flag(tc->clear_flags, x, y); + + numCleared++; + } + } + } +#if 0 + debug_printf("num cleared: %u\n", numCleared); +#endif +} + + +/** + * Flush the tile cache: write all dirty tiles back to the surface. + * any tiles "flagged" as cleared will be "really" cleared. + */ +void +sp_flush_tile_cache(struct softpipe_context *softpipe, + struct softpipe_tile_cache *tc) +{ + struct pipe_context *pipe = &softpipe->pipe; + struct pipe_surface *ps = tc->surface; + int inuse = 0, pos; + + if (!ps || !ps->buffer) + return; + + for (pos = 0; pos < NUM_ENTRIES; pos++) { + struct softpipe_cached_tile *tile = tc->entries + pos; + if (tile->x >= 0) { + if (tc->depth_stencil) { + pipe_put_tile_raw(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->data.depth32, 0/*STRIDE*/); + } + else { + pipe_put_tile_rgba(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); + } + tile->x = tile->y = -1; /* mark as empty */ + inuse++; + } + } + +#if TILE_CLEAR_OPTIMIZATION + sp_tile_cache_flush_clear(&softpipe->pipe, tc); +#endif + +#if 0 + debug_printf("flushed tiles in use: %d\n", inuse); +#endif +} + + +/** + * Get a tile from the cache. + * \param x, y position of tile, in pixels + */ +struct softpipe_cached_tile * +sp_get_cached_tile(struct softpipe_context *softpipe, + struct softpipe_tile_cache *tc, int x, int y) +{ + struct pipe_context *pipe = &softpipe->pipe; + struct pipe_surface *ps = tc->surface; + + /* tile pos in framebuffer: */ + const int tile_x = x & ~(TILE_SIZE - 1); + const int tile_y = y & ~(TILE_SIZE - 1); + + /* cache pos/entry: */ + const int pos = CACHE_POS(x, y); + struct softpipe_cached_tile *tile = tc->entries + pos; + + if (tile_x != tile->x || + tile_y != tile->y) { + + if (tile->x != -1) { + /* put dirty tile back in framebuffer */ + if (tc->depth_stencil) { + pipe_put_tile_raw(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->data.depth32, 0/*STRIDE*/); + } + else { + pipe_put_tile_rgba(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); + } + } + + tile->x = tile_x; + tile->y = tile_y; + + if (is_clear_flag_set(tc->clear_flags, x, y)) { + /* don't get tile from framebuffer, just clear it */ + if (tc->depth_stencil) { + clear_tile(tile, ps->format, tc->clear_val); + } + else { + clear_tile_rgba(tile, ps->format, tc->clear_color); + } + clear_clear_flag(tc->clear_flags, x, y); + } + else { + /* get new tile data from surface */ + if (tc->depth_stencil) { + pipe_get_tile_raw(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->data.depth32, 0/*STRIDE*/); + } + else { + pipe_get_tile_rgba(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); + } + } + } + + return tile; +} + + +/** + * Given the texture face, level, zslice, x and y values, compute + * the cache entry position/index where we'd hope to find the + * cached texture tile. + * This is basically a direct-map cache. + * XXX There's probably lots of ways in which we can improve this. + */ +static INLINE uint +tex_cache_pos(int x, int y, int z, int face, int level) +{ + uint entry = x + y * 5 + z * 4 + face + level; + return entry % NUM_ENTRIES; +} + + +/** + * Similar to sp_get_cached_tile() but for textures. + * Tiles are read-only and indexed with more params. + */ +const struct softpipe_cached_tile * +sp_get_cached_tile_tex(struct pipe_context *pipe, + struct softpipe_tile_cache *tc, int x, int y, int z, + int face, int level) +{ + /* tile pos in framebuffer: */ + const int tile_x = x & ~(TILE_SIZE - 1); + const int tile_y = y & ~(TILE_SIZE - 1); + /* cache pos/entry: */ + const uint pos = tex_cache_pos(x / TILE_SIZE, y / TILE_SIZE, z, + face, level); + struct softpipe_cached_tile *tile = tc->entries + pos; + + if (tile_x != tile->x || + tile_y != tile->y || + z != tile->z || + face != tile->face || + level != tile->level) { + /* cache miss */ + + /* check if we need to get a new surface */ + if (!tc->tex_surf || + tc->tex_face != face || + tc->tex_level != level || + tc->tex_z != z) { + /* get new surface (view into texture) */ + + if (tc->tex_surf_map) + pipe_surface_unmap(tc->tex_surf); + + tc->tex_surf = pipe->get_tex_surface(pipe, tc->texture, face, level, z); + tc->tex_surf_map = pipe_surface_map(tc->tex_surf); + + tc->tex_face = face; + tc->tex_level = level; + tc->tex_z = z; + } + + /* get tile from the surface (view into texture) */ + pipe_get_tile_rgba(pipe, tc->tex_surf, + tile_x, tile_y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); + tile->x = tile_x; + tile->y = tile_y; + tile->z = z; + tile->face = face; + tile->level = level; + } + + return tile; +} + + +/** + * When a whole surface is being cleared to a value we can avoid + * fetching tiles above. + * Save the color and set a 'clearflag' for each tile of the screen. + */ +void +sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue) +{ + uint r, g, b, a; + uint pos; + + tc->clear_val = clearValue; + + switch (tc->surface->format) { + case PIPE_FORMAT_R8G8B8A8_UNORM: + r = (clearValue >> 24) & 0xff; + g = (clearValue >> 16) & 0xff; + b = (clearValue >> 8) & 0xff; + a = (clearValue ) & 0xff; + break; + case PIPE_FORMAT_A8R8G8B8_UNORM: + r = (clearValue >> 16) & 0xff; + g = (clearValue >> 8) & 0xff; + b = (clearValue ) & 0xff; + a = (clearValue >> 24) & 0xff; + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + r = (clearValue >> 8) & 0xff; + g = (clearValue >> 16) & 0xff; + b = (clearValue >> 24) & 0xff; + a = (clearValue ) & 0xff; + break; + default: + r = g = b = a = 0; + } + + tc->clear_color[0] = r / 255.0f; + tc->clear_color[1] = g / 255.0f; + tc->clear_color[2] = b / 255.0f; + tc->clear_color[3] = a / 255.0f; + +#if TILE_CLEAR_OPTIMIZATION + /* set flags to indicate all the tiles are cleared */ + memset(tc->clear_flags, 255, sizeof(tc->clear_flags)); +#else + /* disable the optimization */ + memset(tc->clear_flags, 0, sizeof(tc->clear_flags)); +#endif + + for (pos = 0; pos < NUM_ENTRIES; pos++) { + struct softpipe_cached_tile *tile = tc->entries + pos; + tile->x = tile->y = -1; + } +} diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h new file mode 100644 index 0000000000..7fd1081286 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -0,0 +1,104 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SP_TILE_CACHE_H +#define SP_TILE_CACHE_H + +#define TILE_CLEAR_OPTIMIZATION 1 + + +#include "pipe/p_compiler.h" + + +struct softpipe_context; +struct softpipe_tile_cache; + + +/** + * Cache tile size (width and height). This needs to be a power of two. + */ +#define TILE_SIZE 64 + + + +struct softpipe_cached_tile +{ + int x, y; /**< pos of tile in window coords */ + int z, face, level; /**< Extra texture indexes */ + union { + float color[TILE_SIZE][TILE_SIZE][4]; + uint color32[TILE_SIZE][TILE_SIZE]; + uint depth32[TILE_SIZE][TILE_SIZE]; + ushort depth16[TILE_SIZE][TILE_SIZE]; + ubyte stencil8[TILE_SIZE][TILE_SIZE]; + ubyte any[1]; + } data; +}; + + +extern struct softpipe_tile_cache * +sp_create_tile_cache(void); + +extern void +sp_destroy_tile_cache(struct softpipe_tile_cache *tc); + +extern void +sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, + struct pipe_surface *sps); + +extern struct pipe_surface * +sp_tile_cache_get_surface(struct softpipe_tile_cache *tc); + +extern void +sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc); + +extern void +sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc); + +extern void +sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, + struct pipe_texture *texture); + +extern void +sp_flush_tile_cache(struct softpipe_context *softpipe, + struct softpipe_tile_cache *tc); + +extern void +sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue); + +extern struct softpipe_cached_tile * +sp_get_cached_tile(struct softpipe_context *softpipe, + struct softpipe_tile_cache *tc, int x, int y); + +extern const struct softpipe_cached_tile * +sp_get_cached_tile_tex(struct pipe_context *pipe, + struct softpipe_tile_cache *tc, int x, int y, int z, + int face, int level); + + +#endif /* SP_TILE_CACHE_H */ + diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h new file mode 100644 index 0000000000..d6b379f58c --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_winsys.h @@ -0,0 +1,57 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* This is the interface that softpipe requires any window system + * hosting it to implement. This is the only include file in softpipe + * which is public. + */ + + +#ifndef SP_WINSYS_H +#define SP_WINSYS_H + + +#include "pipe/p_compiler.h" /* for boolean */ + +enum pipe_format; + +struct softpipe_winsys { + /** test if the given format is supported for front/back color bufs */ + boolean (*is_format_supported)( struct softpipe_winsys *sws, + enum pipe_format format ); + +}; + +struct pipe_winsys; +struct pipe_context; + + +struct pipe_context *softpipe_create( struct pipe_winsys *, + struct softpipe_winsys * ); + + +#endif /* SP_WINSYS_H */ diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h new file mode 100644 index 0000000000..30cd729c56 --- /dev/null +++ b/src/gallium/include/pipe/p_compiler.h @@ -0,0 +1,116 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef P_COMPILER_H +#define P_COMPILER_H + + +#include +#include + + +#if defined(_WIN32) && !defined(__WIN32__) +#define __WIN32__ +#endif + +#if defined(_MSC_VER) && !defined(__MSC__) +#define __MSC__ +#endif + + +typedef unsigned int uint; +typedef unsigned char ubyte; +typedef unsigned char boolean; +typedef unsigned short ushort; +typedef unsigned long long uint64; + + +#if defined(__MSC__) + +typedef char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef long int32_t; +typedef unsigned long uint32_t; +typedef long long int64_t; +typedef unsigned long long uint64_t; + +#if defined(_WIN64) +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif + +#else +#include +#endif + + +#define TRUE 1 +#define FALSE 0 + + +/* Function inlining */ +#if defined(__GNUC__) +# define INLINE __inline__ +#elif defined(__MSC__) +# define INLINE __inline +#elif defined(__ICL) +# define INLINE __inline +#elif defined(__INTEL_COMPILER) +# define INLINE inline +#elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100) +# define INLINE __inline +#else +# define INLINE +#endif + + +#if defined __GNUC__ +#define ALIGN16_DECL(TYPE, NAME, SIZE) TYPE NAME##___aligned[SIZE] __attribute__(( aligned( 16 ) )) +#define ALIGN16_ASSIGN(NAME) NAME##___aligned +#define ALIGN16_ATTRIB __attribute__(( aligned( 16 ) )) +#else +#define ALIGN16_DECL(TYPE, NAME, SIZE) TYPE NAME##___unaligned[SIZE + 1] +#define ALIGN16_ASSIGN(NAME) align16(NAME##___unaligned) +#define ALIGN16_ATTRIB +#endif + + + +/** For calling code-gen'd functions */ +#if !defined(XSTDCALL) +#if defined(WIN32) +#define XSTDCALL __stdcall +#else +#define XSTDCALL +#endif +#endif + + +#endif /* P_COMPILER_H */ diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h new file mode 100644 index 0000000000..39f95695fb --- /dev/null +++ b/src/gallium/include/pipe/p_context.h @@ -0,0 +1,221 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef PIPE_CONTEXT_H +#define PIPE_CONTEXT_H + +#include "p_state.h" + + +struct pipe_state_cache; + +/* Opaque driver handles: + */ +struct pipe_query; + +/** + * Gallium rendering context. Basically: + * - state setting functions + * - VBO drawing functions + * - surface functions + * - device queries + */ +struct pipe_context { + struct pipe_winsys *winsys; + + void *priv; /** context private data (for DRI for example) */ + + void (*destroy)( struct pipe_context * ); + + /* + * Queries + */ + /** type is one of PIPE_SURFACE, PIPE_TEXTURE, etc. */ + boolean (*is_format_supported)( struct pipe_context *pipe, + enum pipe_format format, uint type ); + + const char *(*get_name)( struct pipe_context *pipe ); + + const char *(*get_vendor)( struct pipe_context *pipe ); + + int (*get_param)( struct pipe_context *pipe, int param ); + float (*get_paramf)( struct pipe_context *pipe, int param ); + + + /* + * Drawing. + * Return false on fallbacks (temporary??) + */ + boolean (*draw_arrays)( struct pipe_context *pipe, + unsigned mode, unsigned start, unsigned count); + + boolean (*draw_elements)( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count); + + + /** + * Query objects + */ + struct pipe_query *(*create_query)( struct pipe_context *pipe, + unsigned query_type ); + + void (*destroy_query)(struct pipe_context *pipe, + struct pipe_query *q); + + void (*begin_query)(struct pipe_context *pipe, struct pipe_query *q); + void (*end_query)(struct pipe_context *pipe, struct pipe_query *q); + + boolean (*get_query_result)(struct pipe_context *pipe, + struct pipe_query *q, + boolean wait, + uint64 *result); + + /* + * State functions + */ + void * (*create_blend_state)(struct pipe_context *, + const struct pipe_blend_state *); + void (*bind_blend_state)(struct pipe_context *, void *); + void (*delete_blend_state)(struct pipe_context *, void *); + + void * (*create_sampler_state)(struct pipe_context *, + const struct pipe_sampler_state *); + void (*bind_sampler_state)(struct pipe_context *, unsigned unit, void *); + void (*delete_sampler_state)(struct pipe_context *, void *); + + void * (*create_rasterizer_state)(struct pipe_context *, + const struct pipe_rasterizer_state *); + void (*bind_rasterizer_state)(struct pipe_context *, void *); + void (*delete_rasterizer_state)(struct pipe_context *, void *); + + void * (*create_depth_stencil_alpha_state)(struct pipe_context *, + const struct pipe_depth_stencil_alpha_state *); + void (*bind_depth_stencil_alpha_state)(struct pipe_context *, void *); + void (*delete_depth_stencil_alpha_state)(struct pipe_context *, void *); + + void * (*create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*bind_fs_state)(struct pipe_context *, void *); + void (*delete_fs_state)(struct pipe_context *, void *); + + void * (*create_vs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*bind_vs_state)(struct pipe_context *, void *); + void (*delete_vs_state)(struct pipe_context *, void *); + + /* The following look more properties than states. + * maybe combine a few of them into states or pass them + * in the bind calls to the state */ + void (*set_blend_color)( struct pipe_context *, + const struct pipe_blend_color * ); + + void (*set_clip_state)( struct pipe_context *, + const struct pipe_clip_state * ); + + void (*set_constant_buffer)( struct pipe_context *, + uint shader, uint index, + const struct pipe_constant_buffer *buf ); + + void (*set_framebuffer_state)( struct pipe_context *, + const struct pipe_framebuffer_state * ); + + void (*set_polygon_stipple)( struct pipe_context *, + const struct pipe_poly_stipple * ); + + void (*set_scissor_state)( struct pipe_context *, + const struct pipe_scissor_state * ); + + + /* Currently a sampler is constrained to sample from a single texture: + */ + void (*set_sampler_texture)( struct pipe_context *, + unsigned sampler, + struct pipe_texture * ); + + void (*set_viewport_state)( struct pipe_context *, + const struct pipe_viewport_state * ); + + /* + * Vertex arrays + */ + void (*set_vertex_buffer)( struct pipe_context *, + unsigned index, + const struct pipe_vertex_buffer * ); + + void (*set_vertex_element)( struct pipe_context *, + unsigned index, + const struct pipe_vertex_element * ); + + + /* + * Surface functions + */ + + void (*surface_copy)(struct pipe_context *pipe, + unsigned do_flip, /*<< flip surface contents vertically */ + struct pipe_surface *dest, + unsigned destx, unsigned desty, + struct pipe_surface *src, /* don't make this const - + need to map/unmap */ + unsigned srcx, unsigned srcy, + unsigned width, unsigned height); + + void (*surface_fill)(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + unsigned value); + + void (*clear)(struct pipe_context *pipe, + struct pipe_surface *ps, + unsigned clearValue); + + + /* + * Texture functions + */ + struct pipe_texture * (*texture_create)(struct pipe_context *pipe, + const struct pipe_texture *templat); + + void (*texture_release)(struct pipe_context *pipe, + struct pipe_texture **pt); + + /** Get a surface which is a "view" into a texture */ + struct pipe_surface *(*get_tex_surface)(struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level, + unsigned zslice); + + /* Flush rendering: + */ + void (*flush)( struct pipe_context *pipe, + unsigned flags ); +}; + +#endif /* PIPE_CONTEXT_H */ diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h new file mode 100644 index 0000000000..2a11627b36 --- /dev/null +++ b/src/gallium/include/pipe/p_debug.h @@ -0,0 +1,86 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Cross-platform debugging helpers. + * + * For now it just has assert and printf replacements, but it might be extended + * with stack trace reports and more advanced logging in the near future. + * + * @author Jose Fonseca + */ + +#ifndef P_DEBUG_H_ +#define P_DEBUG_H_ + + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef DBG +#ifndef DEBUG +#define DEBUG 1 +#endif +#else +#ifndef NDEBUG +#define NDEBUG 1 +#endif +#endif + + +void debug_printf(const char *format, ...); + +void debug_vprintf(const char *format, va_list ap); + +void debug_assert_fail(const char *expr, const char *file, unsigned line); + + +/** Assert macro */ +#ifdef DEBUG +#define debug_assert(expr) ((expr) ? (void)0 : debug_assert_fail(#expr, __FILE__, __LINE__)) +#else +#define debug_assert(expr) ((void)0) +#endif + + +#ifdef assert +#undef assert +#endif +#define assert(expr) debug_assert(expr) + + +#ifdef __cplusplus +} +#endif + +#endif /* P_DEBUG_H_ */ diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h new file mode 100644 index 0000000000..0bf53ecb79 --- /dev/null +++ b/src/gallium/include/pipe/p_defines.h @@ -0,0 +1,270 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef PIPE_DEFINES_H +#define PIPE_DEFINES_H + +#include "p_format.h" + +#define PIPE_BLENDFACTOR_ONE 0x1 +#define PIPE_BLENDFACTOR_SRC_COLOR 0x2 +#define PIPE_BLENDFACTOR_SRC_ALPHA 0x3 +#define PIPE_BLENDFACTOR_DST_ALPHA 0x4 +#define PIPE_BLENDFACTOR_DST_COLOR 0x5 +#define PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE 0x6 +#define PIPE_BLENDFACTOR_CONST_COLOR 0x7 +#define PIPE_BLENDFACTOR_CONST_ALPHA 0x8 +#define PIPE_BLENDFACTOR_SRC1_COLOR 0x9 +#define PIPE_BLENDFACTOR_SRC1_ALPHA 0x0A +#define PIPE_BLENDFACTOR_ZERO 0x11 +#define PIPE_BLENDFACTOR_INV_SRC_COLOR 0x12 +#define PIPE_BLENDFACTOR_INV_SRC_ALPHA 0x13 +#define PIPE_BLENDFACTOR_INV_DST_ALPHA 0x14 +#define PIPE_BLENDFACTOR_INV_DST_COLOR 0x15 +#define PIPE_BLENDFACTOR_INV_CONST_COLOR 0x17 +#define PIPE_BLENDFACTOR_INV_CONST_ALPHA 0x18 +#define PIPE_BLENDFACTOR_INV_SRC1_COLOR 0x19 +#define PIPE_BLENDFACTOR_INV_SRC1_ALPHA 0x1A + +#define PIPE_BLEND_ADD 0 +#define PIPE_BLEND_SUBTRACT 1 +#define PIPE_BLEND_REVERSE_SUBTRACT 2 +#define PIPE_BLEND_MIN 3 +#define PIPE_BLEND_MAX 4 + +#define PIPE_LOGICOP_CLEAR 0 +#define PIPE_LOGICOP_NOR 1 +#define PIPE_LOGICOP_AND_INVERTED 2 +#define PIPE_LOGICOP_COPY_INVERTED 3 +#define PIPE_LOGICOP_AND_REVERSE 4 +#define PIPE_LOGICOP_INVERT 5 +#define PIPE_LOGICOP_XOR 6 +#define PIPE_LOGICOP_NAND 7 +#define PIPE_LOGICOP_AND 8 +#define PIPE_LOGICOP_EQUIV 9 +#define PIPE_LOGICOP_NOOP 10 +#define PIPE_LOGICOP_OR_INVERTED 11 +#define PIPE_LOGICOP_COPY 12 +#define PIPE_LOGICOP_OR_REVERSE 13 +#define PIPE_LOGICOP_OR 14 +#define PIPE_LOGICOP_SET 15 + +#define PIPE_MASK_R 0x1 +#define PIPE_MASK_G 0x2 +#define PIPE_MASK_B 0x4 +#define PIPE_MASK_A 0x8 +#define PIPE_MASK_RGBA 0xf + + +/** + * Inequality functions. Used for depth test, stencil compare, alpha + * test, shadow compare, etc. + */ +#define PIPE_FUNC_NEVER 0 +#define PIPE_FUNC_LESS 1 +#define PIPE_FUNC_EQUAL 2 +#define PIPE_FUNC_LEQUAL 3 +#define PIPE_FUNC_GREATER 4 +#define PIPE_FUNC_NOTEQUAL 5 +#define PIPE_FUNC_GEQUAL 6 +#define PIPE_FUNC_ALWAYS 7 + +/** Polygon fill mode */ +#define PIPE_POLYGON_MODE_FILL 0 +#define PIPE_POLYGON_MODE_LINE 1 +#define PIPE_POLYGON_MODE_POINT 2 + +/** Polygon front/back window, also for culling */ +#define PIPE_WINDING_NONE 0 +#define PIPE_WINDING_CW 1 +#define PIPE_WINDING_CCW 2 +#define PIPE_WINDING_BOTH (PIPE_WINDING_CW | PIPE_WINDING_CCW) + +/** Stencil ops */ +#define PIPE_STENCIL_OP_KEEP 0 +#define PIPE_STENCIL_OP_ZERO 1 +#define PIPE_STENCIL_OP_REPLACE 2 +#define PIPE_STENCIL_OP_INCR 3 +#define PIPE_STENCIL_OP_DECR 4 +#define PIPE_STENCIL_OP_INCR_WRAP 5 +#define PIPE_STENCIL_OP_DECR_WRAP 6 +#define PIPE_STENCIL_OP_INVERT 7 + +/** Texture types */ +enum pipe_texture_target { + PIPE_TEXTURE_1D = 0, + PIPE_TEXTURE_2D = 1, + PIPE_TEXTURE_3D = 2, + PIPE_TEXTURE_CUBE = 3 +}; + +#define PIPE_TEX_FACE_POS_X 0 +#define PIPE_TEX_FACE_NEG_X 1 +#define PIPE_TEX_FACE_POS_Y 2 +#define PIPE_TEX_FACE_NEG_Y 3 +#define PIPE_TEX_FACE_POS_Z 4 +#define PIPE_TEX_FACE_NEG_Z 5 + +#define PIPE_TEX_WRAP_REPEAT 0 +#define PIPE_TEX_WRAP_CLAMP 1 +#define PIPE_TEX_WRAP_CLAMP_TO_EDGE 2 +#define PIPE_TEX_WRAP_CLAMP_TO_BORDER 3 +#define PIPE_TEX_WRAP_MIRROR_REPEAT 4 +#define PIPE_TEX_WRAP_MIRROR_CLAMP 5 +#define PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE 6 +#define PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER 7 + +/* Between mipmaps, ie mipfilter + */ +#define PIPE_TEX_MIPFILTER_NEAREST 0 +#define PIPE_TEX_MIPFILTER_LINEAR 1 +#define PIPE_TEX_MIPFILTER_NONE 2 + +/* Within a mipmap, ie min/mag filter + */ +#define PIPE_TEX_FILTER_NEAREST 0 +#define PIPE_TEX_FILTER_LINEAR 1 +//#define PIPE_TEX_FILTER_ANISO 2 + + +#define PIPE_TEX_COMPARE_NONE 0 +#define PIPE_TEX_COMPARE_R_TO_TEXTURE 1 + +#define PIPE_TEX_FACE_POS_X 0 +#define PIPE_TEX_FACE_NEG_X 1 +#define PIPE_TEX_FACE_POS_Y 2 +#define PIPE_TEX_FACE_NEG_Y 3 +#define PIPE_TEX_FACE_POS_Z 4 +#define PIPE_TEX_FACE_NEG_Z 5 +#define PIPE_TEX_FACE_MAX 6 + +/** + * Surfaces, textures, etc. (others may be added) + */ +#define PIPE_TEXTURE 1 +#define PIPE_SURFACE 2 /**< user-created surfaces */ + + +/** + * Surface status + */ +#define PIPE_SURFACE_STATUS_UNDEFINED 0 +#define PIPE_SURFACE_STATUS_DEFINED 1 +#define PIPE_SURFACE_STATUS_CLEAR 2 + + +/** + * Buffer usage flags + */ +#define PIPE_BUFFER_USAGE_CPU_READ (1 << 0) +#define PIPE_BUFFER_USAGE_CPU_WRITE (1 << 1) +#define PIPE_BUFFER_USAGE_GPU_READ (1 << 2) +#define PIPE_BUFFER_USAGE_GPU_WRITE (1 << 3) +#define PIPE_BUFFER_USAGE_PIXEL (1 << 4) +#define PIPE_BUFFER_USAGE_VERTEX (1 << 5) +#define PIPE_BUFFER_USAGE_INDEX (1 << 6) +#define PIPE_BUFFER_USAGE_CONSTANT (1 << 7) +/** Pipe driver custam usage flags should be greater or equal to this value */ +#define PIPE_BUFFER_USAGE_CUSTOM (1 << 16) + + +/** + * Flush types: + */ +#define PIPE_FLUSH_RENDER_CACHE 0x1 +#define PIPE_FLUSH_TEXTURE_CACHE 0x2 +#define PIPE_FLUSH_WAIT 0x4 +#define PIPE_FLUSH_SWAPBUFFERS 0x8 + + +/** + * Shaders + */ +#define PIPE_SHADER_VERTEX 0 +#define PIPE_SHADER_FRAGMENT 1 +#define PIPE_SHADER_TYPES 2 + + +/** + * Primitive types: + */ +#define PIPE_PRIM_POINTS 0 +#define PIPE_PRIM_LINES 1 +#define PIPE_PRIM_LINE_LOOP 2 +#define PIPE_PRIM_LINE_STRIP 3 +#define PIPE_PRIM_TRIANGLES 4 +#define PIPE_PRIM_TRIANGLE_STRIP 5 +#define PIPE_PRIM_TRIANGLE_FAN 6 +#define PIPE_PRIM_QUADS 7 +#define PIPE_PRIM_QUAD_STRIP 8 +#define PIPE_PRIM_POLYGON 9 + + +/** + * Query object types + */ +#define PIPE_QUERY_OCCLUSION_COUNTER 0 +#define PIPE_QUERY_PRIMITIVES_GENERATED 1 +#define PIPE_QUERY_PRIMITIVES_EMITTED 2 +#define PIPE_QUERY_TYPES 3 + + +/** + * Point sprite coord modes + */ +#define PIPE_SPRITE_COORD_NONE 0 +#define PIPE_SPRITE_COORD_UPPER_LEFT 1 +#define PIPE_SPRITE_COORD_LOWER_LEFT 2 + + +/** + * Implementation capabilities/limits + * Passed to pipe->get_param() + * XXX this will need some fine tuning... + */ +#define PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS 1 +#define PIPE_CAP_NPOT_TEXTURES 2 +#define PIPE_CAP_TWO_SIDED_STENCIL 3 +#define PIPE_CAP_GLSL 4 /* XXX need something better */ +#define PIPE_CAP_S3TC 5 +#define PIPE_CAP_ANISOTROPIC_FILTER 6 +#define PIPE_CAP_POINT_SPRITE 7 +#define PIPE_CAP_MAX_RENDER_TARGETS 8 +#define PIPE_CAP_OCCLUSION_QUERY 9 +#define PIPE_CAP_TEXTURE_SHADOW_MAP 10 +#define PIPE_CAP_MAX_TEXTURE_2D_LEVELS 11 +#define PIPE_CAP_MAX_TEXTURE_3D_LEVELS 12 +#define PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS 13 +#define PIPE_CAP_MAX_LINE_WIDTH 14 +#define PIPE_CAP_MAX_LINE_WIDTH_AA 15 +#define PIPE_CAP_MAX_POINT_WIDTH 16 +#define PIPE_CAP_MAX_POINT_WIDTH_AA 17 +#define PIPE_CAP_MAX_TEXTURE_ANISOTROPY 18 +#define PIPE_CAP_MAX_TEXTURE_LOD_BIAS 19 +#define PIPE_CAP_BITMAP_TEXCOORD_BIAS 20 + +#endif diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h new file mode 100644 index 0000000000..c9ad324315 --- /dev/null +++ b/src/gallium/include/pipe/p_format.h @@ -0,0 +1,421 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef PIPE_FORMAT_H +#define PIPE_FORMAT_H + +#include // for sprintf + +#include "p_compiler.h" +#include "p_debug.h" + +/** + * The PIPE_FORMAT is a 32-bit wide bitfield that encodes all the information + * needed to uniquely describe a pixel format. + */ + +/** + * Possible format layouts -- occupy first 2 bits. The interpretation of + * the remaining 30 bits depends on a particual format layout. + */ +#define PIPE_FORMAT_LAYOUT_RGBAZS 0 +#define PIPE_FORMAT_LAYOUT_YCBCR 1 + +static INLINE uint pf_layout(uint f) /**< PIPE_FORMAT_LAYOUT_ */ +{ + return f & 0x3; +} + +/** + * RGBAZS Format Layout. + */ + +/** + * Format component selectors for RGBAZS layout. + */ +#define PIPE_FORMAT_COMP_R 0 +#define PIPE_FORMAT_COMP_G 1 +#define PIPE_FORMAT_COMP_B 2 +#define PIPE_FORMAT_COMP_A 3 +#define PIPE_FORMAT_COMP_0 4 +#define PIPE_FORMAT_COMP_1 5 +#define PIPE_FORMAT_COMP_Z 6 +#define PIPE_FORMAT_COMP_S 7 + +/** + * Format types for RGBAZS layout. + */ +#define PIPE_FORMAT_TYPE_UNKNOWN 0 +#define PIPE_FORMAT_TYPE_FLOAT 1 +#define PIPE_FORMAT_TYPE_UNORM 2 +#define PIPE_FORMAT_TYPE_SNORM 3 +#define PIPE_FORMAT_TYPE_USCALED 4 +#define PIPE_FORMAT_TYPE_SSCALED 5 + +/** + * Because the destination vector is assumed to be RGBA FLOAT, we + * need to know how to swizzle and expand components from the source + * vector. + * Let's take U_A1_R5_G5_B5 as an example. X swizzle is A, X size + * is 1 bit and type is UNORM. So we take the most significant bit + * from source vector, convert 0 to 0.0 and 1 to 1.0 and save it + * in the last component of the destination RGBA component. + * Next, Y swizzle is R, Y size is 5 and type is UNORM. We normalize + * those 5 bits into [0.0; 1.0] range and put it into second + * component of the destination vector. Rinse and repeat for + * components Z and W. + * If any of size fields is zero, it means the source format contains + * less than four components. + * If any swizzle is 0 or 1, the corresponding destination component + * should be filled with 0.0 and 1.0, respectively. + */ +typedef uint pipe_format_rgbazs_t; + +static INLINE uint pf_get(pipe_format_rgbazs_t f, uint shift, uint mask) +{ + return (f >> shift) & mask; +} + +/* XXX: The bit layout needs to be revised, can't currently encode 10-bit components. */ + +#define pf_swizzle_x(f) pf_get(f, 2, 0x7) /**< PIPE_FORMAT_COMP_ */ +#define pf_swizzle_y(f) pf_get(f, 5, 0x7) /**< PIPE_FORMAT_COMP_ */ +#define pf_swizzle_z(f) pf_get(f, 8, 0x7) /**< PIPE_FORMAT_COMP_ */ +#define pf_swizzle_w(f) pf_get(f, 11, 0x7) /**< PIPE_FORMAT_COMP_ */ +#define pf_swizzle_xyzw(f,i) pf_get(f, 2+((i)*3), 0x7) +#define pf_size_x(f) pf_get(f, 14, 0x7) /**< Size of X */ +#define pf_size_y(f) pf_get(f, 17, 0x7) /**< Size of Y */ +#define pf_size_z(f) pf_get(f, 20, 0x7) /**< Size of Z */ +#define pf_size_w(f) pf_get(f, 23, 0x7) /**< Size of W */ +#define pf_size_xyzw(f,i) pf_get(f, 14+((i)*3), 0x7) +#define pf_exp8(f) pf_get(f, 26, 0x3) /**< Scale size by 8 ^ exp8 */ +#define pf_type(f) pf_get(f, 28, 0xf) /**< PIPE_FORMAT_TYPE_ */ + +/** + * Helper macro to encode the above structure into a 32-bit value. + */ +#define _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, EXP8, TYPE ) (\ + (PIPE_FORMAT_LAYOUT_RGBAZS << 0) |\ + ((SWZ) << 2) |\ + ((SIZEX) << 14) |\ + ((SIZEY) << 17) |\ + ((SIZEZ) << 20) |\ + ((SIZEW) << 23) |\ + ((EXP8) << 26) |\ + ((TYPE) << 28) ) + +/** + * Helper macro to encode the swizzle part of the structure above. + */ +#define _PIPE_FORMAT_SWZ( SWZX, SWZY, SWZZ, SWZW ) (((SWZX) << 0) | ((SWZY) << 3) | ((SWZZ) << 6) | ((SWZW) << 9)) + +/** + * Shorthand macro for RGBAZS layout with component sizes in 1-bit units. + */ +#define _PIPE_FORMAT_RGBAZS_1( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\ + _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 0, TYPE ) + +/** + * Shorthand macro for RGBAZS layout with component sizes in 8-bit units. + */ +#define _PIPE_FORMAT_RGBAZS_8( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\ + _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 1, TYPE ) + +/** + * Shorthand macro for RGBAZS layout with component sizes in 64-bit units. + */ +#define _PIPE_FORMAT_RGBAZS_64( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\ + _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 2, TYPE ) + +/** + * Shorthand macro for common format swizzles. + */ +#define _PIPE_FORMAT_R000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) +#define _PIPE_FORMAT_RG00 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) +#define _PIPE_FORMAT_RGB0 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_0 ) +#define _PIPE_FORMAT_RGBA _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_A ) +#define _PIPE_FORMAT_ARGB _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_A, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B ) +#define _PIPE_FORMAT_BGRA _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_A ) +#define _PIPE_FORMAT_0000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) +#define _PIPE_FORMAT_000R _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_R ) +#define _PIPE_FORMAT_RRR1 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_1 ) +#define _PIPE_FORMAT_RRRR _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R ) +#define _PIPE_FORMAT_RRRG _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G ) +#define _PIPE_FORMAT_Z000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) +#define _PIPE_FORMAT_SZ00 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) +#define _PIPE_FORMAT_ZS00 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) +#define _PIPE_FORMAT_S000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) + +/** + * YCBCR Format Layout. + */ + +/** + * This only contains a flag that indicates whether the format is reversed or + * not. + */ +typedef uint pipe_format_ycbcr_t; + +/** + * Helper macro to encode the above structure into a 32-bit value. + */ +#define _PIPE_FORMAT_YCBCR( REV ) (\ + (PIPE_FORMAT_LAYOUT_YCBCR << 0) |\ + ((REV) << 2) ) + +static INLINE uint pf_rev(pipe_format_ycbcr_t f) +{ + return (f >> 2) & 0x1; +} + +/** + * Texture/surface image formats (preliminary) + */ + +/* KW: Added lots of surface formats to support vertex element layout + * definitions, and eventually render-to-vertex-buffer. Could + * consider making float/int/uint/scaled/normalized a separate + * parameter, but on the other hand there are special cases like + * z24s8, compressed textures, ycbcr, etc that won't fit that model. + */ + +enum pipe_format { + PIPE_FORMAT_NONE = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_0000, 0, 0, 0, 0, PIPE_FORMAT_TYPE_UNKNOWN ), + PIPE_FORMAT_A8R8G8B8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_ARGB, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_B8G8R8A8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGRA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_A1R5G5B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 1, 5, 5, 5, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_A4R4G4B4_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R5G6B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_RGB0, 5, 6, 5, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_U_L8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte luminance */ + PIPE_FORMAT_U_A8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_000R, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha */ + PIPE_FORMAT_U_I8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRR, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte intensity */ + PIPE_FORMAT_U_A8_L8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha, luminance */ + PIPE_FORMAT_YCBCR = _PIPE_FORMAT_YCBCR( 0 ), + PIPE_FORMAT_YCBCR_REV = _PIPE_FORMAT_YCBCR( 1 ), + PIPE_FORMAT_Z16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_Z32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_Z32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_S8Z24_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_SZ00, 1, 3, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_Z24S8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_ZS00, 3, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_S8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_S000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte stencil */ + PIPE_FORMAT_R64_FLOAT = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R64G64_FLOAT = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R64G64B64_FLOAT = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R64G64B64A64_FLOAT = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R32G32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 4, 4, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R32G32B32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 4, 4, 4, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R32G32B32A32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R32G32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 4, 4, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R32G32B32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 4, 4, 4, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R32G32B32A32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R32_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R32G32_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 4, 4, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R32G32B32_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 4, 4, 4, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R32G32B32A32_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R32_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R32G32_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 4, 4, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R32G32B32_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 4, 4, 4, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R32G32B32A32_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R32_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R32G32_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 4, 4, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R32G32B32_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 4, 4, 4, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R32G32B32A32_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R16G16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 2, 2, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R16G16B16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 2, 2, 2, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R16G16B16A16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R16_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R16G16_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 2, 2, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R16G16B16_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 2, 2, 2, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R16G16B16A16_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R16_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R16G16_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 2, 2, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R16G16B16_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 2, 2, 2, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R16G16B16A16_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R16_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R16G16_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 2, 2, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R16G16B16_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 2, 2, 2, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R16G16B16A16_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R8G8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R8G8B8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R8G8B8A8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R8G8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R8G8B8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R8G8B8A8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R8G8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R8G8B8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R8G8B8A8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R8G8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R8G8B8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R8G8B8A8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ) +}; + + +/** + * XXX should remove this, but S8_UNORM is a poor name + */ +#define PIPE_FORMAT_U_S8 PIPE_FORMAT_S8_UNORM + + +/** + * Builds pipe format name from format token. + */ +static INLINE char *pf_sprint_name( char *str, uint format ) +{ + strcpy( str, "PIPE_FORMAT_" ); + switch (pf_layout( format )) { + case PIPE_FORMAT_LAYOUT_RGBAZS: { + pipe_format_rgbazs_t rgbazs = (pipe_format_rgbazs_t) format; + uint i; + uint scale = 1 << (pf_exp8( rgbazs ) * 3); + + for (i = 0; i < 4; i++) { + uint size = pf_size_xyzw( rgbazs, i ); + + if (size == 0) { + break; + } + switch (pf_swizzle_xyzw( rgbazs, i )) { + case PIPE_FORMAT_COMP_R: + strcat( str, "R" ); + break; + case PIPE_FORMAT_COMP_G: + strcat( str, "G" ); + break; + case PIPE_FORMAT_COMP_B: + strcat( str, "B" ); + break; + case PIPE_FORMAT_COMP_A: + strcat( str, "A" ); + break; + case PIPE_FORMAT_COMP_0: + strcat( str, "0" ); + break; + case PIPE_FORMAT_COMP_1: + strcat( str, "1" ); + break; + case PIPE_FORMAT_COMP_Z: + strcat( str, "Z" ); + break; + case PIPE_FORMAT_COMP_S: + strcat( str, "S" ); + break; + } + sprintf( &str[strlen( str )], "%u", size * scale ); + } + if (i != 0) { + strcat( str, "_" ); + } + switch (pf_type( rgbazs )) { + case PIPE_FORMAT_TYPE_UNKNOWN: + strcat( str, "NONE" ); + break; + case PIPE_FORMAT_TYPE_FLOAT: + strcat( str, "FLOAT" ); + break; + case PIPE_FORMAT_TYPE_UNORM: + strcat( str, "UNORM" ); + break; + case PIPE_FORMAT_TYPE_SNORM: + strcat( str, "SNORM" ); + break; + case PIPE_FORMAT_TYPE_USCALED: + strcat( str, "USCALED" ); + break; + case PIPE_FORMAT_TYPE_SSCALED: + strcat( str, "SSCALED" ); + break; + } + } + break; + case PIPE_FORMAT_LAYOUT_YCBCR: { + pipe_format_ycbcr_t ycbcr = (pipe_format_ycbcr_t) format; + + strcat( str, "YCBCR" ); + if (pf_rev( ycbcr )) { + strcat( str, "_REV" ); + } + } + break; + } + return str; +} + +static INLINE uint pf_get_component_bits( enum pipe_format format, uint comp ) +{ + uint size; + + if (pf_swizzle_x(format) == comp) { + size = pf_size_x(format); + } + else if (pf_swizzle_y(format) == comp) { + size = pf_size_y(format); + } + else if (pf_swizzle_z(format) == comp) { + size = pf_size_z(format); + } + else if (pf_swizzle_w(format) == comp) { + size = pf_size_w(format); + } + else { + size = 0; + } + return size << (pf_exp8(format) * 3); +} + +static INLINE uint pf_get_bits( enum pipe_format format ) +{ + if (pf_layout(format) == PIPE_FORMAT_LAYOUT_RGBAZS) { + return + pf_get_component_bits( format, PIPE_FORMAT_COMP_R ) + + pf_get_component_bits( format, PIPE_FORMAT_COMP_G ) + + pf_get_component_bits( format, PIPE_FORMAT_COMP_B ) + + pf_get_component_bits( format, PIPE_FORMAT_COMP_A ) + + pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) + + pf_get_component_bits( format, PIPE_FORMAT_COMP_S ); + } + else { + assert( pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR ); + + /* TODO */ + assert( 0 ); + return 0; + } +} + +static INLINE uint pf_get_size( enum pipe_format format ) { + assert(pf_get_bits(format) % 8 == 0); + return pf_get_bits(format) / 8; +} + +#endif diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h new file mode 100644 index 0000000000..ebf6ed86bc --- /dev/null +++ b/src/gallium/include/pipe/p_inlines.h @@ -0,0 +1,112 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef P_INLINES_H +#define P_INLINES_H + +#include "p_context.h" +#include "p_defines.h" +#include "p_winsys.h" + + +static INLINE void * +pipe_surface_map(struct pipe_surface *surface) +{ + return (char *)surface->winsys->buffer_map( surface->winsys, surface->buffer, + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_CPU_READ ) + + surface->offset; +} + +static INLINE void +pipe_surface_unmap(struct pipe_surface *surface) +{ + surface->winsys->buffer_unmap( surface->winsys, surface->buffer ); +} + +/** + * Set 'ptr' to point to 'surf' and update reference counting. + * The old thing pointed to, if any, will be unreferenced first. + * 'surf' may be NULL. + */ +static INLINE void +pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) +{ + /* bump the refcount first */ + if (surf) + surf->refcount++; + + if (*ptr /* && --(*ptr)->refcount == 0 */) { + struct pipe_winsys *winsys = (*ptr)->winsys; + winsys->surface_release(winsys, ptr); + assert(!*ptr); + } + + *ptr = surf; +} + + +/* XXX: thread safety issues! + */ +static INLINE void +pipe_buffer_reference(struct pipe_winsys *winsys, + struct pipe_buffer **ptr, + struct pipe_buffer *buf) +{ + if (buf) + buf->refcount++; + + if (*ptr && --(*ptr)->refcount == 0) + winsys->buffer_destroy( winsys, *ptr ); + + *ptr = buf; +} + + + +/** + * \sa pipe_surface_reference + */ +static INLINE void +pipe_texture_reference(struct pipe_context *pipe, struct pipe_texture **ptr, + struct pipe_texture *pt) +{ + assert(ptr); + + if (pt) + pt->refcount++; + + if (*ptr) { + pipe->texture_release(pipe, ptr); + assert(!*ptr); + } + + *ptr = pt; +} + + +#endif /* P_INLINES_H */ diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h new file mode 100644 index 0000000000..3ce35310f6 --- /dev/null +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -0,0 +1,806 @@ +#if !defined TGSI_TOKEN_H +#define TGSI_TOKEN_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +struct tgsi_version +{ + unsigned MajorVersion : 8; + unsigned MinorVersion : 8; + unsigned Padding : 16; +}; + +struct tgsi_header +{ + unsigned HeaderSize : 8; + unsigned BodySize : 24; +}; + +#define TGSI_PROCESSOR_FRAGMENT 0 +#define TGSI_PROCESSOR_VERTEX 1 +#define TGSI_PROCESSOR_GEOMETRY 2 + +struct tgsi_processor +{ + unsigned Processor : 4; /* TGSI_PROCESSOR_ */ + unsigned Padding : 28; +}; + +#define TGSI_TOKEN_TYPE_DECLARATION 0 +#define TGSI_TOKEN_TYPE_IMMEDIATE 1 +#define TGSI_TOKEN_TYPE_INSTRUCTION 2 + +struct tgsi_token +{ + unsigned Type : 4; /* TGSI_TOKEN_TYPE_ */ + unsigned Size : 8; /* UINT */ + unsigned Padding : 19; + unsigned Extended : 1; /* BOOL */ +}; + +#define TGSI_FILE_NULL 0 +#define TGSI_FILE_CONSTANT 1 +#define TGSI_FILE_INPUT 2 +#define TGSI_FILE_OUTPUT 3 +#define TGSI_FILE_TEMPORARY 4 +#define TGSI_FILE_SAMPLER 5 +#define TGSI_FILE_ADDRESS 6 +#define TGSI_FILE_IMMEDIATE 7 + +#define TGSI_DECLARE_RANGE 0 +#define TGSI_DECLARE_MASK 1 + +#define TGSI_WRITEMASK_NONE 0x00 +#define TGSI_WRITEMASK_X 0x01 +#define TGSI_WRITEMASK_Y 0x02 +#define TGSI_WRITEMASK_XY 0x03 +#define TGSI_WRITEMASK_Z 0x04 +#define TGSI_WRITEMASK_XZ 0x05 +#define TGSI_WRITEMASK_YZ 0x06 +#define TGSI_WRITEMASK_XYZ 0x07 +#define TGSI_WRITEMASK_W 0x08 +#define TGSI_WRITEMASK_XW 0x09 +#define TGSI_WRITEMASK_YW 0x0A +#define TGSI_WRITEMASK_XYW 0x0B +#define TGSI_WRITEMASK_ZW 0x0C +#define TGSI_WRITEMASK_XZW 0x0D +#define TGSI_WRITEMASK_YZW 0x0E +#define TGSI_WRITEMASK_XYZW 0x0F + +struct tgsi_declaration +{ + unsigned Type : 4; /* TGSI_TOKEN_TYPE_DECLARATION */ + unsigned Size : 8; /* UINT */ + unsigned File : 4; /* one of TGSI_FILE_x */ + unsigned Declare : 4; /* one of TGSI_DECLARE_x */ + unsigned UsageMask : 4; /* bitmask of TGSI_WRITEMASK_x flags */ + unsigned Interpolate : 1; /* BOOL, any interpolation info? */ + unsigned Semantic : 1; /* BOOL, any semantic info? */ + unsigned Padding : 5; + unsigned Extended : 1; /* BOOL */ +}; + +struct tgsi_declaration_range +{ + unsigned First : 16; /* UINT */ + unsigned Last : 16; /* UINT */ +}; + +struct tgsi_declaration_mask +{ + unsigned Mask : 32; /* UINT */ +}; + +#define TGSI_INTERPOLATE_CONSTANT 0 +#define TGSI_INTERPOLATE_LINEAR 1 +#define TGSI_INTERPOLATE_PERSPECTIVE 2 + +struct tgsi_declaration_interpolation +{ + unsigned Interpolate : 4; /* TGSI_INTERPOLATE_ */ + unsigned Padding : 28; +}; + +#define TGSI_SEMANTIC_POSITION 0 +#define TGSI_SEMANTIC_COLOR 1 +#define TGSI_SEMANTIC_BCOLOR 2 /**< back-face color */ +#define TGSI_SEMANTIC_FOG 3 +#define TGSI_SEMANTIC_PSIZE 4 +#define TGSI_SEMANTIC_GENERIC 5 +#define TGSI_SEMANTIC_NORMAL 6 +#define TGSI_SEMANTIC_COUNT 7 /**< number of semantic values */ + +struct tgsi_declaration_semantic +{ + unsigned SemanticName : 8; /* one of TGSI_SEMANTIC_ */ + unsigned SemanticIndex : 16; /* UINT */ + unsigned Padding : 8; +}; + +#define TGSI_IMM_FLOAT32 0 + +struct tgsi_immediate +{ + unsigned Type : 4; /* TGSI_TOKEN_TYPE_IMMEDIATE */ + unsigned Size : 8; /* UINT */ + unsigned DataType : 4; /* TGSI_IMM_ */ + unsigned Padding : 15; + unsigned Extended : 1; /* BOOL */ +}; + +struct tgsi_immediate_float32 +{ + float Float; +}; + +/* + * GL_NV_vertex_program + */ +#define TGSI_OPCODE_ARL 0 +#define TGSI_OPCODE_MOV 1 +#define TGSI_OPCODE_LIT 2 +#define TGSI_OPCODE_RCP 3 +#define TGSI_OPCODE_RSQ 4 +#define TGSI_OPCODE_EXP 5 +#define TGSI_OPCODE_LOG 6 +#define TGSI_OPCODE_MUL 7 +#define TGSI_OPCODE_ADD 8 +#define TGSI_OPCODE_DP3 9 +#define TGSI_OPCODE_DP4 10 +#define TGSI_OPCODE_DST 11 +#define TGSI_OPCODE_MIN 12 +#define TGSI_OPCODE_MAX 13 +#define TGSI_OPCODE_SLT 14 +#define TGSI_OPCODE_SGE 15 +#define TGSI_OPCODE_MAD 16 + +/* + * GL_ATI_fragment_shader + */ +#define TGSI_OPCODE_SUB 17 +#define TGSI_OPCODE_DOT3 TGSI_OPCODE_DP3 +#define TGSI_OPCODE_DOT4 TGSI_OPCODE_DP4 +#define TGSI_OPCODE_LERP 18 +#define TGSI_OPCODE_CND 19 +#define TGSI_OPCODE_CND0 20 +#define TGSI_OPCODE_DOT2ADD 21 + +/* + * GL_EXT_vertex_shader + */ +#define TGSI_OPCODE_INDEX 22 +#define TGSI_OPCODE_NEGATE 23 +#define TGSI_OPCODE_MADD TGSI_OPCODE_MAD +#define TGSI_OPCODE_FRAC 24 +#define TGSI_OPCODE_SETGE TGSI_OPCODE_SGE +#define TGSI_OPCODE_SETLT TGSI_OPCODE_SLT +#define TGSI_OPCODE_CLAMP 25 +#define TGSI_OPCODE_FLOOR 26 +#define TGSI_OPCODE_ROUND 27 +#define TGSI_OPCODE_EXPBASE2 28 +#define TGSI_OPCODE_LOGBASE2 29 +#define TGSI_OPCODE_POWER 30 +#define TGSI_OPCODE_RECIP TGSI_OPCODE_RCP +#define TGSI_OPCODE_RECIPSQRT TGSI_OPCODE_RSQ +#define TGSI_OPCODE_CROSSPRODUCT 31 +#define TGSI_OPCODE_MULTIPLYMATRIX 32 + +/* + * GL_NV_vertex_program1_1 + */ +#define TGSI_OPCODE_ABS 33 +#define TGSI_OPCODE_RCC 34 +#define TGSI_OPCODE_DPH 35 + +/* + * GL_NV_fragment_program + */ +#define TGSI_OPCODE_COS 36 +#define TGSI_OPCODE_DDX 37 +#define TGSI_OPCODE_DDY 38 +#define TGSI_OPCODE_EX2 TGSI_OPCODE_EXPBASE2 +#define TGSI_OPCODE_FLR TGSI_OPCODE_FLOOR +#define TGSI_OPCODE_FRC TGSI_OPCODE_FRAC +#define TGSI_OPCODE_KILP 39 /* predicated kill */ +#define TGSI_OPCODE_LG2 TGSI_OPCODE_LOGBASE2 +#define TGSI_OPCODE_LRP TGSI_OPCODE_LERP +#define TGSI_OPCODE_PK2H 40 +#define TGSI_OPCODE_PK2US 41 +#define TGSI_OPCODE_PK4B 42 +#define TGSI_OPCODE_PK4UB 43 +#define TGSI_OPCODE_POW TGSI_OPCODE_POWER +#define TGSI_OPCODE_RFL 44 +#define TGSI_OPCODE_SEQ 45 +#define TGSI_OPCODE_SFL 46 +#define TGSI_OPCODE_SGT 47 +#define TGSI_OPCODE_SIN 48 +#define TGSI_OPCODE_SLE 49 +#define TGSI_OPCODE_SNE 50 +#define TGSI_OPCODE_STR 51 +#define TGSI_OPCODE_TEX 52 +#define TGSI_OPCODE_TXD 53 +#define TGSI_OPCODE_UP2H 54 +#define TGSI_OPCODE_UP2US 55 +#define TGSI_OPCODE_UP4B 56 +#define TGSI_OPCODE_UP4UB 57 +#define TGSI_OPCODE_X2D 58 + +/* + * GL_NV_vertex_program2 + */ +#define TGSI_OPCODE_ARA 59 +#define TGSI_OPCODE_ARR 60 +#define TGSI_OPCODE_BRA 61 +#define TGSI_OPCODE_CAL 62 +#define TGSI_OPCODE_RET 63 +#define TGSI_OPCODE_SSG 64 + +/* + * GL_ARB_vertex_program + */ +#define TGSI_OPCODE_SWZ TGSI_OPCODE_MOV +#define TGSI_OPCODE_XPD TGSI_OPCODE_CROSSPRODUCT + +/* + * GL_ARB_fragment_program + */ +#define TGSI_OPCODE_CMP 65 +#define TGSI_OPCODE_SCS 66 +#define TGSI_OPCODE_TXB 67 + +/* + * GL_NV_fragment_program_option + */ +/* No new opcode */ + +/* + * GL_NV_fragment_program2 + */ +#define TGSI_OPCODE_NRM 68 +#define TGSI_OPCODE_DIV 69 +#define TGSI_OPCODE_DP2 70 +#define TGSI_OPCODE_DP2A TGSI_OPCODE_DOT2ADD +#define TGSI_OPCODE_TXL 71 +#define TGSI_OPCODE_BRK 72 +#define TGSI_OPCODE_IF 73 +#define TGSI_OPCODE_LOOP 74 +#define TGSI_OPCODE_REP 75 +#define TGSI_OPCODE_ELSE 76 +#define TGSI_OPCODE_ENDIF 77 +#define TGSI_OPCODE_ENDLOOP 78 +#define TGSI_OPCODE_ENDREP 79 + +/* + * GL_NV_vertex_program2_option + */ + +/* + * GL_NV_vertex_program3 + */ +#define TGSI_OPCODE_PUSHA 80 +#define TGSI_OPCODE_POPA 81 + +/* + * GL_NV_gpu_program4 + */ +#define TGSI_OPCODE_CEIL 82 +#define TGSI_OPCODE_I2F 83 +#define TGSI_OPCODE_NOT 84 +#define TGSI_OPCODE_TRUNC 85 +#define TGSI_OPCODE_SHL 86 +#define TGSI_OPCODE_SHR 87 +#define TGSI_OPCODE_AND 88 +#define TGSI_OPCODE_OR 89 +#define TGSI_OPCODE_MOD 90 +#define TGSI_OPCODE_XOR 91 +#define TGSI_OPCODE_SAD 92 +#define TGSI_OPCODE_TXF 93 +#define TGSI_OPCODE_TXQ 94 +#define TGSI_OPCODE_CONT 95 + +/* + * GL_NV_vertex_program4 + */ +/* Same as GL_NV_gpu_program4 */ + +/* + * GL_NV_fragment_program4 + */ +/* Same as GL_NV_gpu_program4 */ + +/* + * GL_NV_geometry_program4 + */ +/* Same as GL_NV_gpu_program4 */ +#define TGSI_OPCODE_EMIT 96 +#define TGSI_OPCODE_ENDPRIM 97 + +/* + * GLSL + */ +#define TGSI_OPCODE_BGNLOOP2 98 +#define TGSI_OPCODE_BGNSUB 99 +#define TGSI_OPCODE_ENDLOOP2 100 +#define TGSI_OPCODE_ENDSUB 101 +#define TGSI_OPCODE_INT TGSI_OPCODE_TRUNC +#define TGSI_OPCODE_NOISE1 102 +#define TGSI_OPCODE_NOISE2 103 +#define TGSI_OPCODE_NOISE3 104 +#define TGSI_OPCODE_NOISE4 105 +#define TGSI_OPCODE_NOP 106 + +/* + * ps_1_1 + */ +#define TGSI_OPCODE_TEXCOORD TGSI_OPCODE_NOP +#define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KIL +#define TGSI_OPCODE_TEXBEM 107 +#define TGSI_OPCODE_TEXBEML 108 +#define TGSI_OPCODE_TEXREG2AR 109 +#define TGSI_OPCODE_TEXM3X2PAD 110 +#define TGSI_OPCODE_TEXM3X2TEX 111 +#define TGSI_OPCODE_TEXM3X3PAD 112 +#define TGSI_OPCODE_TEXM3X3TEX 113 +#define TGSI_OPCODE_TEXM3X3SPEC 114 +#define TGSI_OPCODE_TEXM3X3VSPEC 115 + +/* + * ps_1_2 + */ +#define TGSI_OPCODE_TEXREG2GB 116 +#define TGSI_OPCODE_TEXREG2RGB 117 +#define TGSI_OPCODE_TEXDP3TEX 118 +#define TGSI_OPCODE_TEXDP3 119 +#define TGSI_OPCODE_TEXM3X3 120 +/* CMP - use TGSI_OPCODE_CND0 */ + +/* + * ps_1_3 + */ +#define TGSI_OPCODE_TEXM3X2DEPTH 121 +/* CMP - use TGSI_OPCODE_CND0 */ + +/* + * ps_1_4 + */ +#define TGSI_OPCODE_TEXCRD TGSI_OPCODE_TEXCOORD +#define TGSI_OPCODE_TEXLD TGSI_OPCODE_TEX +#define TGSI_OPCODE_TEXDEPTH 122 +#define TGSI_OPCODE_BEM 123 + +/* + * ps_2_0 + */ +#define TGSI_OPCODE_M4X4 TGSI_OPCODE_MULTIPLYMATRIX +#define TGSI_OPCODE_M4X3 124 +#define TGSI_OPCODE_M3X4 125 +#define TGSI_OPCODE_M3X3 126 +#define TGSI_OPCODE_M3X2 127 +#define TGSI_OPCODE_CRS TGSI_OPCODE_XPD +#define TGSI_OPCODE_NRM4 128 +#define TGSI_OPCODE_SINCOS TGSI_OPCODE_SCS +#define TGSI_OPCODE_TEXLDB TGSI_OPCODE_TXB +#define TGSI_OPCODE_DP2ADD TGSI_OPCODE_DP2A + +/* + * ps_2_x + */ +#define TGSI_OPCODE_CALL TGSI_OPCODE_CAL +#define TGSI_OPCODE_CALLNZ 129 +#define TGSI_OPCODE_IFC 130 +#define TGSI_OPCODE_BREAK TGSI_OPCODE_BRK +#define TGSI_OPCODE_BREAKC 131 +#define TGSI_OPCODE_DSX TGSI_OPCODE_DDX +#define TGSI_OPCODE_DSY TGSI_OPCODE_DDY +#define TGSI_OPCODE_TEXLDD TGSI_OPCODE_TXD + +/* + * vs_1_1 + */ +#define TGSI_OPCODE_EXPP TGSI_OPCODE_EXP +#define TGSI_OPCODE_LOGP TGSI_OPCODE_LG2 + +/* + * vs_2_0 + */ +#define TGSI_OPCODE_SGN TGSI_OPCODE_SSG +#define TGSI_OPCODE_MOVA TGSI_OPCODE_ARR + +/* + * vs_2_x + */ + +#define TGSI_OPCODE_KIL 132 /* unpredicated kill */ +#define TGSI_OPCODE_END 133 /* aka HALT */ + +#define TGSI_OPCODE_LAST 134 + +#define TGSI_SAT_NONE 0 /* do not saturate */ +#define TGSI_SAT_ZERO_ONE 1 /* clamp to [0,1] */ +#define TGSI_SAT_MINUS_PLUS_ONE 2 /* clamp to [-1,1] */ + +/* + * Opcode is the operation code to execute. A given operation defines the + * semantics how the source registers (if any) are interpreted and what is + * written to the destination registers (if any) as a result of execution. + * + * NumDstRegs and NumSrcRegs is the number of destination and source registers, + * respectively. For a given operation code, those numbers are fixed and are + * present here only for convenience. + * + * If Extended is TRUE, it is now executed. + * + * Saturate controls how are final results in destination registers modified. + */ + +struct tgsi_instruction +{ + unsigned Type : 4; /* TGSI_TOKEN_TYPE_INSTRUCTION */ + unsigned Size : 8; /* UINT */ + unsigned Opcode : 8; /* TGSI_OPCODE_ */ + unsigned Saturate : 2; /* TGSI_SAT_ */ + unsigned NumDstRegs : 2; /* UINT */ + unsigned NumSrcRegs : 4; /* UINT */ + unsigned Padding : 3; + unsigned Extended : 1; /* BOOL */ +}; + +/* + * If tgsi_instruction::Extended is TRUE, tgsi_instruction_ext follows. + * + * Then, tgsi_instruction::NumDstRegs of tgsi_dst_register follow. + * + * Then, tgsi_instruction::NumSrcRegs of tgsi_src_register follow. + * + * tgsi_instruction::Size contains the total number of words that make the + * instruction, including the instruction word. + */ + +#define TGSI_INSTRUCTION_EXT_TYPE_NV 0 +#define TGSI_INSTRUCTION_EXT_TYPE_LABEL 1 +#define TGSI_INSTRUCTION_EXT_TYPE_TEXTURE 2 +#define TGSI_INSTRUCTION_EXT_TYPE_PREDICATE 3 + +struct tgsi_instruction_ext +{ + unsigned Type : 4; /* TGSI_INSTRUCTION_EXT_TYPE_ */ + unsigned Padding : 27; + unsigned Extended : 1; /* BOOL */ +}; + +/* + * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_NV, it should + * be cast to tgsi_instruction_ext_nv. + * + * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_LABEL, it + * should be cast to tgsi_instruction_ext_label. + * + * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_TEXTURE, it + * should be cast to tgsi_instruction_ext_texture. + * + * If tgsi_instruction_ext::Type is TGSI_INSTRUCTION_EXT_TYPE_PREDICATE, it + * should be cast to tgsi_instruction_ext_predicate. + * + * If tgsi_instruction_ext::Extended is TRUE, another tgsi_instruction_ext + * follows. + */ + +#define TGSI_PRECISION_DEFAULT 0 +#define TGSI_PRECISION_FLOAT32 1 +#define TGSI_PRECISION_FLOAT16 2 +#define TGSI_PRECISION_FIXED12 3 + +#define TGSI_CC_GT 0 +#define TGSI_CC_EQ 1 +#define TGSI_CC_LT 2 +#define TGSI_CC_UN 3 +#define TGSI_CC_GE 4 +#define TGSI_CC_LE 5 +#define TGSI_CC_NE 6 +#define TGSI_CC_TR 7 +#define TGSI_CC_FL 8 + +#define TGSI_SWIZZLE_X 0 +#define TGSI_SWIZZLE_Y 1 +#define TGSI_SWIZZLE_Z 2 +#define TGSI_SWIZZLE_W 3 + +/* + * Precision controls the precision at which the operation should be executed. + * + * CondDstUpdate enables condition code register writes. When this field is + * TRUE, CondDstIndex specifies the index of the condition code register to + * update. + * + * CondFlowEnable enables conditional execution of the operation. When this + * field is TRUE, CondFlowIndex specifies the index of the condition code + * register to test against CondMask with component swizzle controled by + * CondSwizzleX, CondSwizzleY, CondSwizzleZ and CondSwizzleW. If the test fails, + * the operation is not executed. + */ + +struct tgsi_instruction_ext_nv +{ + unsigned Type : 4; /* TGSI_INSTRUCTION_EXT_TYPE_NV */ + unsigned Precision : 4; /* TGSI_PRECISION_ */ + unsigned CondDstIndex : 4; /* UINT */ + unsigned CondFlowIndex : 4; /* UINT */ + unsigned CondMask : 4; /* TGSI_CC_ */ + unsigned CondSwizzleX : 2; /* TGSI_SWIZZLE_ */ + unsigned CondSwizzleY : 2; /* TGSI_SWIZZLE_ */ + unsigned CondSwizzleZ : 2; /* TGSI_SWIZZLE_ */ + unsigned CondSwizzleW : 2; /* TGSI_SWIZZLE_ */ + unsigned CondDstUpdate : 1; /* BOOL */ + unsigned CondFlowEnable : 1; /* BOOL */ + unsigned Padding : 1; + unsigned Extended : 1; /* BOOL */ +}; + +struct tgsi_instruction_ext_label +{ + unsigned Type : 4; /* TGSI_INSTRUCTION_EXT_TYPE_LABEL */ + unsigned Label : 24; /* UINT */ + unsigned Padding : 3; + unsigned Extended : 1; /* BOOL */ +}; + +#define TGSI_TEXTURE_UNKNOWN 0 +#define TGSI_TEXTURE_1D 1 +#define TGSI_TEXTURE_2D 2 +#define TGSI_TEXTURE_3D 3 +#define TGSI_TEXTURE_CUBE 4 +#define TGSI_TEXTURE_RECT 5 +#define TGSI_TEXTURE_SHADOW1D 6 +#define TGSI_TEXTURE_SHADOW2D 7 +#define TGSI_TEXTURE_SHADOWRECT 8 + +struct tgsi_instruction_ext_texture +{ + unsigned Type : 4; /* TGSI_INSTRUCTION_EXT_TYPE_TEXTURE */ + unsigned Texture : 8; /* TGSI_TEXTURE_ */ + unsigned Padding : 19; + unsigned Extended : 1; /* BOOL */ +}; + +struct tgsi_instruction_ext_predicate +{ + unsigned Type : 4; /* TGSI_INSTRUCTION_EXT_TYPE_PREDICATE */ + unsigned PredDstIndex : 4; /* UINT */ + unsigned PredWriteMask : 4; /* TGSI_WRITEMASK_ */ + unsigned Padding : 19; + unsigned Extended : 1; /* BOOL */ +}; + +/* + * File specifies the register array to access. + * + * Index specifies the element number of a register in the register file. + * + * If Indirect is TRUE, Index should be offset by the X component of a source + * register that follows. The register can be now fetched into local storage + * for further processing. + * + * If Negate is TRUE, all components of the fetched register are negated. + * + * The fetched register components are swizzled according to SwizzleX, SwizzleY, + * SwizzleZ and SwizzleW. + * + * If Extended is TRUE, any further modifications to the source register are + * made to this temporary storage. + */ + +struct tgsi_src_register +{ + unsigned File : 4; /* TGSI_FILE_ */ + unsigned SwizzleX : 2; /* TGSI_SWIZZLE_ */ + unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */ + unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */ + unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */ + unsigned Negate : 1; /* BOOL */ + unsigned Indirect : 1; /* BOOL */ + unsigned Dimension : 1; /* BOOL */ + int Index : 16; /* SINT */ + unsigned Extended : 1; /* BOOL */ +}; + +/* + * If tgsi_src_register::Extended is TRUE, tgsi_src_register_ext follows. + * + * Then, if tgsi_src_register::Indirect is TRUE, another tgsi_src_register + * follows. + * + * Then, if tgsi_src_register::Dimension is TRUE, tgsi_dimension follows. + */ + +#define TGSI_SRC_REGISTER_EXT_TYPE_SWZ 0 +#define TGSI_SRC_REGISTER_EXT_TYPE_MOD 1 + +struct tgsi_src_register_ext +{ + unsigned Type : 4; /* TGSI_SRC_REGISTER_EXT_TYPE_ */ + unsigned Padding : 27; + unsigned Extended : 1; /* BOOL */ +}; + +/* + * If tgsi_src_register_ext::Type is TGSI_SRC_REGISTER_EXT_TYPE_SWZ, + * it should be cast to tgsi_src_register_ext_swz. + * + * If tgsi_src_register_ext::Type is TGSI_SRC_REGISTER_EXT_TYPE_MOD, + * it should be cast to tgsi_src_register_ext_mod. + * + * If tgsi_dst_register_ext::Extended is TRUE, another tgsi_dst_register_ext + * follows. + */ + +#define TGSI_EXTSWIZZLE_X TGSI_SWIZZLE_X +#define TGSI_EXTSWIZZLE_Y TGSI_SWIZZLE_Y +#define TGSI_EXTSWIZZLE_Z TGSI_SWIZZLE_Z +#define TGSI_EXTSWIZZLE_W TGSI_SWIZZLE_W +#define TGSI_EXTSWIZZLE_ZERO 4 +#define TGSI_EXTSWIZZLE_ONE 5 + +/* + * ExtSwizzleX, ExtSwizzleY, ExtSwizzleZ and ExtSwizzleW swizzle the source + * register in an extended manner. + * + * NegateX, NegateY, NegateZ and NegateW negate individual components of the + * source register. + * + * ExtDivide specifies which component is used to divide all components of the + * source register. + */ + +struct tgsi_src_register_ext_swz +{ + unsigned Type : 4; /* TGSI_SRC_REGISTER_EXT_TYPE_SWZ */ + unsigned ExtSwizzleX : 4; /* TGSI_EXTSWIZZLE_ */ + unsigned ExtSwizzleY : 4; /* TGSI_EXTSWIZZLE_ */ + unsigned ExtSwizzleZ : 4; /* TGSI_EXTSWIZZLE_ */ + unsigned ExtSwizzleW : 4; /* TGSI_EXTSWIZZLE_ */ + unsigned NegateX : 1; /* BOOL */ + unsigned NegateY : 1; /* BOOL */ + unsigned NegateZ : 1; /* BOOL */ + unsigned NegateW : 1; /* BOOL */ + unsigned ExtDivide : 4; /* TGSI_EXTSWIZZLE_ */ + unsigned Padding : 3; + unsigned Extended : 1; /* BOOL */ +}; + +/** + * Extra src register modifiers + * + * If Complement is TRUE, the source register is modified by subtracting it + * from 1.0. + * + * If Bias is TRUE, the source register is modified by subtracting 0.5 from it. + * + * If Scale2X is TRUE, the source register is modified by multiplying it by 2.0. + * + * If Absolute is TRUE, the source register is modified by removing the sign. + * + * If Negate is TRUE, the source register is modified by negating it. + */ + +struct tgsi_src_register_ext_mod +{ + unsigned Type : 4; /* TGSI_SRC_REGISTER_EXT_TYPE_MOD */ + unsigned Complement : 1; /* BOOL */ + unsigned Bias : 1; /* BOOL */ + unsigned Scale2X : 1; /* BOOL */ + unsigned Absolute : 1; /* BOOL */ + unsigned Negate : 1; /* BOOL */ + unsigned Padding : 22; + unsigned Extended : 1; /* BOOL */ +}; + +struct tgsi_dimension +{ + unsigned Indirect : 1; /* BOOL */ + unsigned Dimension : 1; /* BOOL */ + unsigned Padding : 13; + int Index : 16; /* SINT */ + unsigned Extended : 1; /* BOOL */ +}; + +struct tgsi_dst_register +{ + unsigned File : 4; /* TGSI_FILE_ */ + unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */ + unsigned Indirect : 1; /* BOOL */ + unsigned Dimension : 1; /* BOOL */ + int Index : 16; /* SINT */ + unsigned Padding : 5; + unsigned Extended : 1; /* BOOL */ +}; + +/* + * If tgsi_dst_register::Extended is TRUE, tgsi_dst_register_ext follows. + * + * Then, if tgsi_dst_register::Indirect is TRUE, tgsi_src_register follows. + */ + +#define TGSI_DST_REGISTER_EXT_TYPE_CONDCODE 0 +#define TGSI_DST_REGISTER_EXT_TYPE_MODULATE 1 +#define TGSI_DST_REGISTER_EXT_TYPE_PREDICATE 2 + +struct tgsi_dst_register_ext +{ + unsigned Type : 4; /* TGSI_DST_REGISTER_EXT_TYPE_ */ + unsigned Padding : 27; + unsigned Extended : 1; /* BOOL */ +}; + +/** + * Extra destination register modifiers + * + * If tgsi_dst_register_ext::Type is TGSI_DST_REGISTER_EXT_TYPE_CONDCODE, + * it should be cast to tgsi_dst_register_ext_condcode. + * + * If tgsi_dst_register_ext::Type is TGSI_DST_REGISTER_EXT_TYPE_MODULATE, + * it should be cast to tgsi_dst_register_ext_modulate. + * + * If tgsi_dst_register_ext::Type is TGSI_DST_REGISTER_EXT_TYPE_PREDICATE, + * it should be cast to tgsi_dst_register_ext_predicate. + * + * If tgsi_dst_register_ext::Extended is TRUE, another tgsi_dst_register_ext + * follows. + */ +struct tgsi_dst_register_ext_concode +{ + unsigned Type : 4; /* TGSI_DST_REGISTER_EXT_TYPE_CONDCODE */ + unsigned CondMask : 4; /* TGSI_CC_ */ + unsigned CondSwizzleX : 2; /* TGSI_SWIZZLE_ */ + unsigned CondSwizzleY : 2; /* TGSI_SWIZZLE_ */ + unsigned CondSwizzleZ : 2; /* TGSI_SWIZZLE_ */ + unsigned CondSwizzleW : 2; /* TGSI_SWIZZLE_ */ + unsigned CondSrcIndex : 4; /* UINT */ + unsigned Padding : 11; + unsigned Extended : 1; /* BOOL */ +}; + +#define TGSI_MODULATE_1X 0 +#define TGSI_MODULATE_2X 1 +#define TGSI_MODULATE_4X 2 +#define TGSI_MODULATE_8X 3 +#define TGSI_MODULATE_HALF 4 +#define TGSI_MODULATE_QUARTER 5 +#define TGSI_MODULATE_EIGHTH 6 + +struct tgsi_dst_register_ext_modulate +{ + unsigned Type : 4; /* TGSI_DST_REGISTER_EXT_TYPE_MODULATE */ + unsigned Modulate : 4; /* TGSI_MODULATE_ */ + unsigned Padding : 23; + unsigned Extended : 1; /* BOOL */ +}; + +/* + * Currently, the following constraints apply. + * + * - PredSwizzleXYZW is either set to identity or replicate. + * - PredSrcIndex is 0. + */ + +struct tgsi_dst_register_ext_predicate +{ + unsigned Type : 4; /* TGSI_DST_REGISTER_EXT_TYPE_PREDICATE */ + unsigned PredSwizzleX : 2; /* TGSI_SWIZZLE_ */ + unsigned PredSwizzleY : 2; /* TGSI_SWIZZLE_ */ + unsigned PredSwizzleZ : 2; /* TGSI_SWIZZLE_ */ + unsigned PredSwizzleW : 2; /* TGSI_SWIZZLE_ */ + unsigned PredSrcIndex : 4; /* UINT */ + unsigned Negate : 1; /* BOOL */ + unsigned Padding : 14; + unsigned Extended : 1; /* BOOL */ +}; + + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_TOKEN_H + diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h new file mode 100644 index 0000000000..4d3a6b2f41 --- /dev/null +++ b/src/gallium/include/pipe/p_state.h @@ -0,0 +1,322 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Abstract graphics pipe state objects. + * + * Basic notes: + * 1. Want compact representations, so we use bitfields. + * 2. Put bitfields before other (GLfloat) fields. + */ + + +#ifndef PIPE_STATE_H +#define PIPE_STATE_H + +#include "p_compiler.h" +#include "p_defines.h" +#include "p_format.h" + +/** + * Implementation limits + */ +#define PIPE_MAX_SAMPLERS 8 +#define PIPE_MAX_CLIP_PLANES 6 +#define PIPE_MAX_CONSTANT 32 +#define PIPE_ATTRIB_MAX 32 +#define PIPE_MAX_COLOR_BUFS 8 +#define PIPE_MAX_TEXTURE_LEVELS 16 +#define PIPE_MAX_FEEDBACK_ATTRIBS 16 +#define PIPE_MAX_SHADER_INPUTS 16 +#define PIPE_MAX_SHADER_OUTPUTS 16 + + +/* fwd decls */ +struct pipe_surface; +struct pipe_winsys; + + + +/** + * The driver will certainly subclass this to include actual memory + * management information. + */ +struct pipe_buffer { + unsigned alignment; + unsigned usage; + unsigned size; + + /** Reference count */ + unsigned refcount; +}; + + + + +/** + * Primitive (point/line/tri) rasterization info + */ +struct pipe_rasterizer_state +{ + unsigned flatshade:1; + unsigned light_twoside:1; + unsigned front_winding:2; /**< PIPE_WINDING_x */ + unsigned cull_mode:2; /**< PIPE_WINDING_x */ + unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */ + unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */ + unsigned offset_cw:1; + unsigned offset_ccw:1; + unsigned scissor:1; + unsigned poly_smooth:1; + unsigned poly_stipple_enable:1; + unsigned point_smooth:1; + unsigned point_sprite:1; + unsigned point_size_per_vertex:1; /**< size computed in vertex shader */ + unsigned multisample:1; /* XXX maybe more ms state in future */ + unsigned line_smooth:1; + unsigned line_stipple_enable:1; + unsigned line_stipple_factor:8; /**< [1..256] actually */ + unsigned line_stipple_pattern:16; + unsigned bypass_clipping:1; + unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ + + float line_width; + float point_size; /**< used when no per-vertex size */ + float offset_units; + float offset_scale; + ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */ +}; + + +struct pipe_poly_stipple { + unsigned stipple[32]; +}; + + +struct pipe_viewport_state { + float scale[4]; + float translate[4]; +}; + + +struct pipe_scissor_state { + unsigned minx:16; + unsigned miny:16; + unsigned maxx:16; + unsigned maxy:16; +}; + + +struct pipe_clip_state { + float ucp[PIPE_MAX_CLIP_PLANES][4]; + unsigned nr; +}; + + +/** + * Constants for vertex/fragment shaders + */ +struct pipe_constant_buffer { + struct pipe_buffer *buffer; + unsigned size; /** in bytes */ +}; + + +struct pipe_shader_state { + const struct tgsi_token *tokens; + ubyte num_inputs; + ubyte num_outputs; + ubyte input_map[PIPE_MAX_SHADER_INPUTS]; /* XXX this may be temporary */ + ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */ + ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; + ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */ + ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; +}; + + +struct pipe_depth_stencil_alpha_state +{ + struct { + unsigned enabled:1; /**< depth test enabled? */ + unsigned writemask:1; /**< allow depth buffer writes? */ + unsigned func:3; /**< depth test func (PIPE_FUNC_x) */ + unsigned occlusion_count:1; /**< do occlusion counting? */ + } depth; + struct { + unsigned enabled:1; + unsigned func:3; /**< PIPE_FUNC_x */ + unsigned fail_op:3; /**< PIPE_STENCIL_OP_x */ + unsigned zpass_op:3; /**< PIPE_STENCIL_OP_x */ + unsigned zfail_op:3; /**< PIPE_STENCIL_OP_x */ + ubyte ref_value; + ubyte value_mask; + ubyte write_mask; + } stencil[2]; /**< [0] = front, [1] = back */ + struct { + unsigned enabled:1; + unsigned func:3; /**< PIPE_FUNC_x */ + float ref; /**< reference value */ + } alpha; +}; + + +struct pipe_blend_state { + unsigned blend_enable:1; + + unsigned rgb_func:3; /**< PIPE_BLEND_x */ + unsigned rgb_src_factor:5; /**< PIPE_BLENDFACTOR_x */ + unsigned rgb_dst_factor:5; /**< PIPE_BLENDFACTOR_x */ + + unsigned alpha_func:3; /**< PIPE_BLEND_x */ + unsigned alpha_src_factor:5; /**< PIPE_BLENDFACTOR_x */ + unsigned alpha_dst_factor:5; /**< PIPE_BLENDFACTOR_x */ + + unsigned logicop_enable:1; + unsigned logicop_func:4; /**< PIPE_LOGICOP_x */ + + unsigned colormask:4; /**< bitmask of PIPE_MASK_R/G/B/A */ + unsigned dither:1; +}; + + +struct pipe_blend_color { + float color[4]; +}; + + +struct pipe_framebuffer_state +{ + /** multiple colorbuffers for multiple render targets */ + unsigned num_cbufs; + struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS]; + + struct pipe_surface *zsbuf; /**< Z/stencil buffer */ +}; + + +/** + * Texture sampler state. + */ +struct pipe_sampler_state +{ + unsigned wrap_s:3; /**< PIPE_TEX_WRAP_x */ + unsigned wrap_t:3; /**< PIPE_TEX_WRAP_x */ + unsigned wrap_r:3; /**< PIPE_TEX_WRAP_x */ + unsigned min_img_filter:2; /**< PIPE_TEX_FILTER_x */ + unsigned min_mip_filter:2; /**< PIPE_TEX_MIPFILTER_x */ + unsigned mag_img_filter:2; /**< PIPE_TEX_FILTER_x */ + unsigned compare:1; /**< shadow/depth compare enabled? */ + unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ + unsigned compare_func:3; /**< PIPE_FUNC_x */ + unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ + float shadow_ambient; /**< shadow test fail color/intensity */ + float lod_bias; /**< LOD/lambda bias */ + float min_lod, max_lod; /**< LOD clamp range, after bias */ + float border_color[4]; + float max_anisotropy; +}; + + +/** + * 2D surface. This is basically a view into a memory buffer. + * May be a renderbuffer, texture mipmap level, etc. + */ +struct pipe_surface +{ + struct pipe_buffer *buffer; /**< driver private buffer handle */ + enum pipe_format format; /**< PIPE_FORMAT_x */ + unsigned status; /**< PIPE_SURFACE_STATUS_x */ + unsigned clear_value; /**< may be temporary */ + unsigned cpp; /**< bytes per pixel */ + unsigned width, height; + unsigned pitch; /**< in pixels */ + unsigned offset; /**< offset from start of buffer, in bytes */ + unsigned refcount; + struct pipe_winsys *winsys; /**< winsys which owns/created the surface */ +}; + + +/** + * Texture. Represents one or several texture images on one or several mipmap + * levels. + */ +struct pipe_texture +{ + /* Effectively the key: + */ + enum pipe_texture_target target; /**< PIPE_TEXTURE_x */ + enum pipe_format format; /**< PIPE_FORMAT_x */ + + unsigned last_level; /**< Index of last mipmap level present/defined */ + + unsigned width[PIPE_MAX_TEXTURE_LEVELS]; + unsigned height[PIPE_MAX_TEXTURE_LEVELS]; + unsigned depth[PIPE_MAX_TEXTURE_LEVELS]; + unsigned cpp; + + unsigned compressed:1; + + /* These are also refcounted: + */ + unsigned refcount; +}; + + +/** + * A vertex buffer. Typically, all the vertex data/attributes for + * drawing something will be in one buffer. But it's also possible, for + * example, to put colors in one buffer and texcoords in another. + */ +struct pipe_vertex_buffer +{ + unsigned pitch:11; /**< stride to same attrib in next vertex, in bytes */ + unsigned max_index; /**< number of vertices in this buffer */ + unsigned buffer_offset; /**< offset to start of data in buffer, in bytes */ + struct pipe_buffer *buffer; /**< the actual buffer */ +}; + + +/** + * Information to describe a vertex attribute (position, color, etc) + */ +struct pipe_vertex_element +{ + /** Offset of this attribute, in bytes, from the start of the vertex */ + unsigned src_offset:11; + + /** Which vertex_buffer (as given to pipe->set_vertex_buffer()) does + * this attribute live in? + */ + unsigned vertex_buffer_index:5; + unsigned nr_components:3; + + enum pipe_format src_format; /**< PIPE_FORMAT_* */ +}; + + +#endif diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/include/pipe/p_thread.h new file mode 100644 index 0000000000..cd432c547c --- /dev/null +++ b/src/gallium/include/pipe/p_thread.h @@ -0,0 +1,54 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef P_THREAD_H +#define P_THREAD_H + +#include "p_compiler.h" + +/* + * XXX: We should come up with a system-independent thread definitions. + * XXX: Patching glthread defs for now. + */ + +#ifndef __MSC__ + +#include "glapi/glthread.h" + +#else /* __MSC__ */ + +typedef int _glthread_Mutex; + +#define _glthread_INIT_MUTEX( M ) ((void) (M)) +#define _glthread_LOCK_MUTEX( M ) ((void) (M)) +#define _glthread_UNLOCK_MUTEX( M ) ((void) (M)) + +#define sched_yield() ((void) 0) + +#endif /* __MSC__ */ + +#endif /* P_THREAD_H */ diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h new file mode 100644 index 0000000000..d7da2801c9 --- /dev/null +++ b/src/gallium/include/pipe/p_util.h @@ -0,0 +1,408 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef P_UTIL_H +#define P_UTIL_H + +#include "p_compiler.h" +#include "p_debug.h" +#include + + +#ifdef WIN32 + +#ifdef __cplusplus +extern "C" +{ +#endif + +void * __stdcall +EngAllocMem( + unsigned long Flags, + unsigned long MemSize, + unsigned long Tag ); + +void __stdcall +EngFreeMem( + void *Mem ); + +#ifdef __cplusplus +} +#endif + +static INLINE void * +MALLOC( unsigned size ) +{ + return EngAllocMem( 0, size, 'D3AG' ); +} + +static INLINE void * +CALLOC( unsigned count, unsigned size ) +{ + void *ptr = MALLOC( count * size ); + if( ptr ) { + memset( ptr, 0, count * size ); + } + return ptr; +} + +static INLINE void +FREE( void *ptr ) +{ + if( ptr ) { + EngFreeMem( ptr ); + } +} + +static INLINE void * +REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) +{ + void *new_ptr; + if( new_size <= old_size ) { + return old_ptr; + } + new_ptr = MALLOC( new_size ); + if( new_ptr ) { + memcpy( new_ptr, old_ptr, old_size ); + } + FREE( old_ptr ); + return new_ptr; +} + +#define GETENV( X ) NULL + +#else /* WIN32 */ + +#define MALLOC( SIZE ) malloc( SIZE ) + +#define CALLOC( COUNT, SIZE ) calloc( COUNT, SIZE ) + +#define FREE( PTR ) free( PTR ) + +#define REALLOC( OLDPTR, OLDSIZE, NEWSIZE ) realloc( OLDPTR, NEWSIZE ) + +#define GETENV( X ) getenv( X ) + +#endif /* WIN32 */ + +#define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T)) + +#define CALLOC_STRUCT(T) (struct T *) CALLOC(1, sizeof(struct T)) + + +/** + * Return a pointer aligned to next multiple of N bytes. + */ +static INLINE void * +align_pointer( void *unaligned, uint alignment ) +{ + if (sizeof(void *) == 64) { + union { + void *p; + uint64 u; + } pu; + pu.p = unaligned; + pu.u = (pu.u + alignment - 1) & ~(uint64) (alignment - 1); + return pu.p; + } + else { + /* 32-bit pointers */ + union { + void *p; + uint u; + } pu; + pu.p = unaligned; + pu.u = (pu.u + alignment - 1) & ~(alignment - 1); + return pu.p; + } +} + +/** + * Return memory on given byte alignment + */ +static INLINE void * +align_malloc(size_t bytes, uint alignment) +{ +#if defined(HAVE_POSIX_MEMALIGN) + void *mem; + (void) posix_memalign(& mem, alignment, bytes); + return mem; +#else + char *ptr, *buf; + + assert( alignment > 0 ); + + ptr = (char *) MALLOC(bytes + alignment + sizeof(void *)); + if (!ptr) + return NULL; + + buf = (char *) align_pointer( ptr + sizeof(void *), alignment ); + *(char **)(buf - sizeof(void *)) = ptr; + + return buf; +#endif /* defined(HAVE_POSIX_MEMALIGN) */ +} + +/** + * Free memory returned by align_malloc(). + */ +static INLINE void +align_free(void *ptr) +{ +#if defined(HAVE_POSIX_MEMALIGN) + FREE(ptr); +#else + void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); + void *realAddr = *cubbyHole; + FREE(realAddr); +#endif /* defined(HAVE_POSIX_MEMALIGN) */ +} + + + +/** + * Duplicate a block of memory. + */ +static INLINE void * +mem_dup(const void *src, uint size) +{ + void *dup = MALLOC(size); + if (dup) + memcpy(dup, src, size); + return dup; +} + + + +#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) +#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) +#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) + +#define Elements(x) sizeof(x)/sizeof(*(x)) +#define Offset(TYPE, MEMBER) ((unsigned)&(((TYPE *)NULL)->MEMBER)) + +/** + * Return a pointer aligned to next multiple of 16 bytes. + */ +static INLINE void * +align16( void *unaligned ) +{ + return align_pointer( unaligned, 16 ); +} + + +static INLINE int align_int(int x, int align) +{ + return (x + align - 1) & ~(align - 1); +} + + + +#if defined(__MSC__) && defined(__WIN32__) +static INLINE unsigned ffs( unsigned u ) +{ + unsigned i; + + if( u == 0 ) { + return 0; + } + + __asm bsf eax, [u] + __asm inc eax + __asm mov [i], eax + + return i; +} +#endif + +union fi { + float f; + int i; + unsigned ui; +}; + +#define UBYTE_TO_FLOAT( ub ) ((float)(ub) / 255.0F) + +#define IEEE_0996 0x3f7f0000 /* 0.996 or so */ + +/* This function/macro is sensitive to precision. Test very carefully + * if you change it! + */ +#define UNCLAMPED_FLOAT_TO_UBYTE(UB, F) \ + do { \ + union fi __tmp; \ + __tmp.f = (F); \ + if (__tmp.i < 0) \ + UB = (ubyte) 0; \ + else if (__tmp.i >= IEEE_0996) \ + UB = (ubyte) 255; \ + else { \ + __tmp.f = __tmp.f * (255.0f/256.0f) + 32768.0f; \ + UB = (ubyte) __tmp.i; \ + } \ + } while (0) + + + +static INLINE unsigned pack_ub4( unsigned char b0, + unsigned char b1, + unsigned char b2, + unsigned char b3 ) +{ + return ((((unsigned int)b0) << 0) | + (((unsigned int)b1) << 8) | + (((unsigned int)b2) << 16) | + (((unsigned int)b3) << 24)); +} + +static INLINE unsigned fui( float f ) +{ + union fi fi; + fi.f = f; + return fi.ui; +} + +static INLINE unsigned char float_to_ubyte( float f ) +{ + unsigned char ub; + UNCLAMPED_FLOAT_TO_UBYTE(ub, f); + return ub; +} + +static INLINE unsigned pack_ui32_float4( float a, + float b, + float c, + float d ) +{ + return pack_ub4( float_to_ubyte(a), + float_to_ubyte(b), + float_to_ubyte(c), + float_to_ubyte(d) ); +} + +#define COPY_4V( DST, SRC ) \ +do { \ + (DST)[0] = (SRC)[0]; \ + (DST)[1] = (SRC)[1]; \ + (DST)[2] = (SRC)[2]; \ + (DST)[3] = (SRC)[3]; \ +} while (0) + + +#define COPY_4FV( DST, SRC ) COPY_4V(DST, SRC) + + +#define ASSIGN_4V( DST, V0, V1, V2, V3 ) \ +do { \ + (DST)[0] = (V0); \ + (DST)[1] = (V1); \ + (DST)[2] = (V2); \ + (DST)[3] = (V3); \ +} while (0) + + +static INLINE int ifloor(float f) +{ + int ai, bi; + double af, bf; + union fi u; + + af = (3 << 22) + 0.5 + (double)f; + bf = (3 << 22) + 0.5 - (double)f; + u.f = (float) af; ai = u.i; + u.f = (float) bf; bi = u.i; + return (ai - bi) >> 1; +} + + +#if defined(__GNUC__) && defined(__i386__) +static INLINE int iround(float f) +{ + int r; + __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st"); + return r; +} +#elif defined(__MSC__) && defined(__WIN32__) +static INLINE int iround(float f) +{ + int r; + _asm { + fld f + fistp r + } + return r; +} +#else +#define IROUND(f) ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F))) +#endif + + +/* Could maybe have an inline version of this? + */ +#if defined(__GNUC__) +#define FABSF(x) fabsf(x) +#else +#define FABSF(x) ((float) fabs(x)) +#endif + +/* Pretty fast, and accurate. + * Based on code from http://www.flipcode.com/totd/ + */ +static INLINE float LOG2(float val) +{ + union fi num; + int log_2; + + num.f = val; + log_2 = ((num.i >> 23) & 255) - 128; + num.i &= ~(255 << 23); + num.i += 127 << 23; + num.f = ((-1.0f/3) * num.f + 2) * num.f - 2.0f/3; + return num.f + log_2; +} + +#if defined(__GNUC__) +#define CEILF(x) ceilf(x) +#else +#define CEILF(x) ((float) ceil(x)) +#endif + +static INLINE int align(int value, int alignment) +{ + return (value + alignment - 1) & ~(alignment - 1); +} + + +/* util/p_util.c + */ +extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, + unsigned dst_x, unsigned dst_y, unsigned width, + unsigned height, const ubyte * src, + int src_pitch, unsigned src_x, int src_y); + + +#endif diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h new file mode 100644 index 0000000000..1e81eebd78 --- /dev/null +++ b/src/gallium/include/pipe/p_winsys.h @@ -0,0 +1,160 @@ + /************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef P_WINSYS_H +#define P_WINSYS_H + + +#include "p_format.h" + +/** + * \file + * This is the interface that Gallium3D requires any window system + * hosting it to implement. This is the only include file in Gallium3D + * which is public. + */ + + +/** Opaque type */ +struct pipe_fence_handle; + +struct pipe_surface; + + +/** + * Gallium3D drivers are (meant to be!) independent of both GL and the + * window system. The window system provides a buffer manager and a + * set of additional hooks for things like command buffer submission, + * etc. + * + * There clearly has to be some agreement between the window system + * driver and the hardware driver about the format of command buffers, + * etc. + */ +struct pipe_winsys +{ + /** Returns name of this winsys interface */ + const char *(*get_name)( struct pipe_winsys *sws ); + + /** + * Do any special operations to ensure frontbuffer contents are + * displayed, eg copy fake frontbuffer. + */ + void (*flush_frontbuffer)( struct pipe_winsys *sws, + struct pipe_surface *surf, + void *context_private ); + + /** Debug output */ + void (*printf)( struct pipe_winsys *sws, + const char *, ... ); + + + /** allocate a new surface (no context dependency) */ + struct pipe_surface *(*surface_alloc)(struct pipe_winsys *ws); + + /** + * Allocate storage for a pipe_surface. + * Returns 0 if succeeds. + */ + int (*surface_alloc_storage)(struct pipe_winsys *ws, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags); + + void (*surface_release)(struct pipe_winsys *ws, struct pipe_surface **s); + + + /** + * Buffer management. Buffer attributes are mostly fixed over its lifetime. + * + * Remember that gallium gets to choose the interface it needs, and the + * window systems must then implement that interface (rather than the + * other way around...). + * + * usage is a bitmask of PIPE_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This + * usage argument is only an optimization hint, not a guarantee, therefore + * proper behavior must be observed in all circumstances. + */ + struct pipe_buffer *(*buffer_create)( struct pipe_winsys *sws, + unsigned alignment, + unsigned usage, + unsigned size ); + + /** Create a buffer that wraps user-space data */ + struct pipe_buffer *(*user_buffer_create)(struct pipe_winsys *sws, + void *ptr, + unsigned bytes); + + /** + * Map the entire data store of a buffer object into the client's address. + * flags is bitmask of PIPE_BUFFER_USAGE_CPU_READ/WRITE flags. + */ + void *(*buffer_map)( struct pipe_winsys *sws, + struct pipe_buffer *buf, + unsigned usage ); + + void (*buffer_unmap)( struct pipe_winsys *sws, + struct pipe_buffer *buf ); + + void (*buffer_destroy)( struct pipe_winsys *sws, + struct pipe_buffer *buf ); + + + /** Set ptr = fence, with reference counting */ + void (*fence_reference)( struct pipe_winsys *sws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence ); + + /** + * Checks whether the fence has been signalled. + * + * The meaning of flag is pipe-driver specific. + * + * Returns zero if it has. + */ + int (*fence_signalled)( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ); + + /** + * Wait for the fence to finish. + * + * The meaning of flag is pipe-driver specific. + * + * Returns zero on success. + */ + int (*fence_finish)( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ); + + +}; + + + +#endif /* P_WINSYS_H */ diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile new file mode 100644 index 0000000000..9ae0f01325 --- /dev/null +++ b/src/gallium/winsys/dri/intel/Makefile @@ -0,0 +1,38 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = i915tex_dri.so + +MINIGLX_SOURCES = server/intel_dri.c + +PIPE_DRIVERS = \ + $(TOP)/src/mesa/pipe/softpipe/libsoftpipe.a \ + $(TOP)/src/mesa/pipe/i915simple/libi915simple.a + +DRIVER_SOURCES = \ + intel_winsys_pipe.c \ + intel_winsys_softpipe.c \ + intel_winsys_i915.c \ + intel_batchbuffer.c \ + intel_swapbuffers.c \ + intel_context.c \ + intel_lock.c \ + intel_screen.c \ + intel_batchpool.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(COMMON_BM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") + +include ../Makefile.template + +intel_tex_layout.o: ../intel/intel_tex_layout.c + +symlinks: diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript new file mode 100644 index 0000000000..a7cc10450e --- /dev/null +++ b/src/gallium/winsys/dri/intel/SConscript @@ -0,0 +1,41 @@ +Import('*') + +env = drienv.Clone() + +env.Append(CPPPATH = [ + '../intel', + 'server' +]) + +#MINIGLX_SOURCES = server/intel_dri.c + +pipe_drivers = [ + softpipe, + i915simple +] + +DRIVER_SOURCES = [ + 'intel_winsys_pipe.c', + 'intel_winsys_softpipe.c', + 'intel_winsys_i915.c', + 'intel_batchbuffer.c', + 'intel_swapbuffers.c', + 'intel_context.c', + 'intel_lock.c', + 'intel_screen.c', + 'intel_batchpool.c', +] + +sources = \ + COMMON_GALLIUM_SOURCES + \ + COMMON_BM_SOURCES + \ + DRIVER_SOURCES + +# DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ +# && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") + +env.SharedLibrary( + target ='i915tex_dri.so', + source = sources, + LIBS = pipe_drivers + env['LIBS'], +) \ No newline at end of file diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c new file mode 100644 index 0000000000..49e04d81ec --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -0,0 +1,357 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include +#include "intel_batchbuffer.h" +#include "intel_context.h" +#include "intel_screen.h" +#include "intel_reg.h" +#include "drm.h" + +/* Relocations in kernel space: + * - pass dma buffer seperately + * - memory manager knows how to patch + * - pass list of dependent buffers + * - pass relocation list + * + * Either: + * - get back an offset for buffer to fire + * - memory manager knows how to fire buffer + * + * Really want the buffer to be AGP and pinned. + * + */ + +/* Cliprect fence: The highest fence protecting a dma buffer + * containing explicit cliprect information. Like the old drawable + * lock but irq-driven. X server must wait for this fence to expire + * before changing cliprects [and then doing sw rendering?]. For + * other dma buffers, the scheduler will grab current cliprect info + * and mix into buffer. X server must hold the lock while changing + * cliprects??? Make per-drawable. Need cliprects in shared memory + * -- beats storing them with every cmd buffer in the queue. + * + * ==> X server must wait for this fence to expire before touching the + * framebuffer with new cliprects. + * + * ==> Cliprect-dependent buffers associated with a + * cliprect-timestamp. All of the buffers associated with a timestamp + * must go to hardware before any buffer with a newer timestamp. + * + * ==> Dma should be queued per-drawable for correct X/GL + * synchronization. Or can fences be used for this? + * + * Applies to: Blit operations, metaops, X server operations -- X + * server automatically waits on its own dma to complete before + * modifying cliprects ??? + */ + +static void +intel_dump_batchbuffer(uint offset, uint * ptr, uint count) +{ + int i; + printf("\n\n\nSTART BATCH (%d dwords):\n", count / 4); + for (i = 0; i < count / 4; i += 1) + printf("\t0x%08x\n", ptr[i]); + printf("END BATCH\n\n\n"); +} + + +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) +{ + int i; + + if (batch->map) { + driBOUnmap(batch->buffer); + batch->map = NULL; + } + + /* + * Get a new, free batchbuffer. + */ + batch->size = BATCH_SZ; + driBOData(batch->buffer, batch->size, NULL, 0); + + driBOResetList(&batch->list); + + /* + * Unreference buffers previously on the relocation list. + */ + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + driBOUnReference(r->buf); + } + + batch->list_count = 0; + batch->nr_relocs = 0; + batch->flags = 0; + + /* + * We don't refcount the batchbuffer itself since we can't destroy it + * while it's on the list. + */ + + driBOAddListItem(&batch->list, batch->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE); + + + batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->ptr = batch->map; +} + + +/*====================================================================== + * Public functions + */ +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_context *intel) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + + driGenBuffers(intel->intelScreen->batchPool, "batchbuffer", 1, + &batch->buffer, 4096, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); + batch->last_fence = NULL; + driBOCreateList(20, &batch->list); + intel_batchbuffer_reset(batch); + return batch; +} + + +void +intel_batchbuffer_free(struct intel_batchbuffer *batch) +{ + if (batch->last_fence) { + driFenceFinish(batch->last_fence, + DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, + GL_FALSE); + driFenceUnReference(batch->last_fence); + batch->last_fence = NULL; + } + if (batch->map) { + driBOUnmap(batch->buffer); + batch->map = NULL; + } + driBOUnReference(batch->buffer); + batch->buffer = NULL; + free(batch); +} + + +static void +intel_batch_ioctl(struct intel_context *intel, + uint start_offset, uint used, boolean allow_unlock) +{ + drmI830BatchBuffer batch; + + batch.start = start_offset; + batch.used = used; + batch.cliprects = NULL; /* unused */ + batch.num_cliprects = 0; + batch.DR1 = 0; + batch.DR4 = 0; /* still need this ? */ + + DBG(IOCTL, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n", + __FUNCTION__, + batch.start, + batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); + + if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, + sizeof(batch))) { + printf("DRM_I830_BATCHBUFFER: %d\n", -errno); + UNLOCK_HARDWARE(intel); + exit(1); + } +} + + +/* TODO: Push this whole function into bufmgr. + */ +static void +do_flush_locked(struct intel_batchbuffer *batch, + uint used, boolean allow_unlock) +{ + uint *ptr; + uint i, fenceFlags; + struct _DriFenceObject *fo; + + driBOValidateList(batch->intel->driFd, &batch->list); + + /* Apply the relocations. This nasty map indicates to me that the + * whole task should be done internally by the memory manager, and + * that dma buffers probably need to be pinned within agp space. + */ + ptr = (uint *) driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_ALLOW_UNFENCED_MAP); + + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + + ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta; + } + + if (0) + intel_dump_batchbuffer(0, ptr, used); + + driBOUnmap(batch->buffer); + batch->map = NULL; + + intel_batch_ioctl(batch->intel, + driBOOffset(batch->buffer), + used, allow_unlock); + + /* + * Kernel fencing. The flags tells the kernel that we've + * programmed an MI_FLUSH. + */ + fenceFlags = DRM_I915_FENCE_FLAG_FLUSHED; + fo = driFenceBuffers(batch->intel->driFd, "Batch fence", fenceFlags); + + /* + * User space fencing. + */ + driBOFence(batch->buffer, fo); + + if (driFenceType(fo) == DRM_FENCE_TYPE_EXE) { + /* + * Oops. We only validated a batch buffer. This means we + * didn't do any proper rendering. Discard this fence object. + */ + driFenceUnReference(fo); + } + else { + driFenceUnReference(batch->last_fence); + batch->last_fence = fo; + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + driBOFence(r->buf, fo); + } + } +} + + +struct _DriFenceObject * +intel_batchbuffer_flush(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + uint used = batch->ptr - batch->map; + const boolean was_locked = intel->locked; + + if (used == 0) + return batch->last_fence; + +#define MI_FLUSH ((0 << 29) | (4 << 23)) + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ + if (used & 4) { + ((int *) batch->ptr)[0] = MI_FLUSH; + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = MI_FLUSH; + ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } + + driBOUnmap(batch->buffer); + batch->ptr = NULL; + batch->map = NULL; + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!was_locked) + LOCK_HARDWARE(intel); + + do_flush_locked(batch, used, GL_FALSE); + + if (!was_locked) + UNLOCK_HARDWARE(intel); + + /* Reset the buffer: + */ + intel_batchbuffer_reset(batch); + return batch->last_fence; +} + + +void +intel_batchbuffer_finish(struct intel_batchbuffer *batch) +{ + struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); + if (fence) { + driFenceReference(fence); + driFenceFinish(fence, + DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, + GL_FALSE); + driFenceUnReference(fence); + } +} + + +/* This is the only way buffers get added to the validate list. + */ +boolean +intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + struct _DriBufferObject *buffer, + uint flags, uint mask, uint delta) +{ + assert(batch->nr_relocs < MAX_RELOCS); + + driBOAddListItem(&batch->list, buffer, flags, mask); + + { + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; + driBOReference(buffer); + r->buf = buffer; + r->offset = batch->ptr - batch->map; + r->delta = delta; + *(uint *) batch->ptr = 0x12345678; + } + + batch->ptr += 4; + return GL_TRUE; +} + + +void +intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, uint bytes, uint flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h new file mode 100644 index 0000000000..82feafa21f --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -0,0 +1,149 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "pipe/p_compiler.h" +#include "dri_bufmgr.h" + +struct intel_context; + +#define BATCH_SZ 16384 +#define BATCH_RESERVED 16 + +#define MAX_RELOCS 4096 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct buffer_reloc +{ + struct _DriBufferObject *buf; + uint offset; + uint delta; /* not needed? */ +}; + +struct intel_batchbuffer +{ + struct bufmgr *bm; + struct intel_context *intel; + + struct _DriBufferObject *buffer; + struct _DriFenceObject *last_fence; + uint flags; + + drmBOList list; + uint list_count; + ubyte *map; + ubyte *ptr; + + struct buffer_reloc reloc[MAX_RELOCS]; + uint nr_relocs; + uint size; +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context *intel); + +void intel_batchbuffer_free(struct intel_batchbuffer *batch); + + +void intel_batchbuffer_finish(struct intel_batchbuffer *batch); + +struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer + *batch); + +void intel_batchbuffer_reset(struct intel_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multiple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, uint bytes, uint flags); + +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + uint bytes); + +boolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + struct _DriBufferObject *buffer, + uint flags, + uint mask, uint offset); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE uint +intel_batchbuffer_space(struct intel_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, uint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(uint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + uint sz, uint flags) +{ + assert(sz < batch->size - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) + intel_batchbuffer_flush(batch); + + batch->flags |= flags; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, flags) do { \ + intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ +} while (0) + +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf,flags,mask,delta) do { \ + assert((delta) >= 0); \ + intel_batchbuffer_emit_reloc(intel->batch, buf, flags, mask, delta); \ +} while (0) + +#define ADVANCE_BATCH() do { } while(0) + + +#endif diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.c b/src/gallium/winsys/dri/intel/intel_batchpool.c new file mode 100644 index 0000000000..33b56817f6 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_batchpool.c @@ -0,0 +1,424 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +/** + * XXX NOTE: there are no intel dependencies in this file. + * Rename to dri_batchpool.c? + */ + +#include +#include +#include +#include "imports.h" +#include "glthread.h" +#include "dri_bufpool.h" +#include "dri_bufmgr.h" +#include "intel_batchpool.h" + + +typedef struct +{ + drmMMListHead head; + struct _BPool *parent; + struct _DriFenceObject *fence; + unsigned long start; + int unfenced; + int mapped; +} BBuf; + +typedef struct _BPool +{ + _glthread_Mutex mutex; + unsigned long bufSize; + unsigned poolSize; + unsigned numFree; + unsigned numTot; + unsigned numDelayed; + unsigned checkDelayed; + drmMMListHead free; + drmMMListHead delayed; + drmMMListHead head; + drmBO kernelBO; + void *virtual; + BBuf *bufs; +} BPool; + + +static BPool * +createBPool(int fd, unsigned long bufSize, unsigned numBufs, unsigned flags, + unsigned checkDelayed) +{ + BPool *p = (BPool *) malloc(sizeof(*p)); + BBuf *buf; + int i; + + if (!p) + return NULL; + + p->bufs = (BBuf *) malloc(numBufs * sizeof(*p->bufs)); + if (!p->bufs) { + free(p); + return NULL; + } + + DRMINITLISTHEAD(&p->free); + DRMINITLISTHEAD(&p->head); + DRMINITLISTHEAD(&p->delayed); + + p->numTot = numBufs; + p->numFree = numBufs; + p->bufSize = bufSize; + p->numDelayed = 0; + p->checkDelayed = checkDelayed; + + _glthread_INIT_MUTEX(p->mutex); + + if (drmBOCreate(fd, 0, numBufs * bufSize, 0, NULL, drm_bo_type_dc, + flags, DRM_BO_HINT_DONT_FENCE, &p->kernelBO)) { + free(p->bufs); + free(p); + return NULL; + } + if (drmBOMap(fd, &p->kernelBO, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, + &p->virtual)) { + drmBODestroy(fd, &p->kernelBO); + free(p->bufs); + free(p); + return NULL; + } + + /* + * We unmap the buffer so that we can validate it later. Note that this is + * just a synchronizing operation. The buffer will have a virtual mapping + * until it is destroyed. + */ + + drmBOUnmap(fd, &p->kernelBO); + + buf = p->bufs; + for (i = 0; i < numBufs; ++i) { + buf->parent = p; + buf->fence = NULL; + buf->start = i * bufSize; + buf->mapped = 0; + buf->unfenced = 0; + DRMLISTADDTAIL(&buf->head, &p->free); + buf++; + } + + return p; +} + + +static void +pool_checkFree(BPool * p, int wait) +{ + drmMMListHead *list, *prev; + BBuf *buf; + int signaled = 0; + int i; + + list = p->delayed.next; + + if (p->numDelayed > 3) { + for (i = 0; i < p->numDelayed; i += 3) { + list = list->next; + } + } + + prev = list->prev; + for (; list != &p->delayed; list = prev, prev = list->prev) { + + buf = DRMLISTENTRY(BBuf, list, head); + + if (!signaled) { + if (wait) { + driFenceFinish(buf->fence, DRM_FENCE_TYPE_EXE, 1); + signaled = 1; + } + else { + signaled = driFenceSignaled(buf->fence, DRM_FENCE_TYPE_EXE); + } + } + + if (!signaled) + break; + + driFenceUnReference(buf->fence); + buf->fence = NULL; + DRMLISTDEL(list); + p->numDelayed--; + DRMLISTADD(list, &p->free); + p->numFree++; + } +} + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, unsigned flags, unsigned hint, + unsigned alignment) +{ + BPool *p = (BPool *) pool->data; + + drmMMListHead *item; + + if (alignment && (alignment != 4096)) + return NULL; + + _glthread_LOCK_MUTEX(p->mutex); + + if (p->numFree == 0) + pool_checkFree(p, GL_TRUE); + + if (p->numFree == 0) { + fprintf(stderr, "Out of fixed size buffer objects\n"); + BM_CKFATAL(-ENOMEM); + } + + item = p->free.next; + + if (item == &p->free) { + fprintf(stderr, "Fixed size buffer pool corruption\n"); + } + + DRMLISTDEL(item); + --p->numFree; + + _glthread_UNLOCK_MUTEX(p->mutex); + return (void *) DRMLISTENTRY(BBuf, item, head); +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + + if (buf->fence) { + DRMLISTADDTAIL(&buf->head, &p->delayed); + p->numDelayed++; + } + else { + buf->unfenced = 0; + DRMLISTADD(&buf->head, &p->free); + p->numFree++; + } + + if ((p->numDelayed % p->checkDelayed) == 0) + pool_checkFree(p, 0); + + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, void **virtual) +{ + + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + + /* + * Currently Mesa doesn't have any condition variables to resolve this + * cleanly in a multithreading environment. + * We bail out instead. + */ + + if (buf->mapped) { + fprintf(stderr, "Trying to map already mapped buffer object\n"); + BM_CKFATAL(-EINVAL); + } + +#if 0 + if (buf->unfenced && !(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) { + fprintf(stderr, "Trying to map an unfenced buffer object 0x%08x" + " 0x%08x %d\n", hint, flags, buf->start); + BM_CKFATAL(-EINVAL); + } + +#endif + + if (buf->fence) { + _glthread_UNLOCK_MUTEX(p->mutex); + return -EBUSY; + } + + buf->mapped = GL_TRUE; + *virtual = (unsigned char *) p->virtual + buf->start; + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) +{ + BBuf *buf = (BBuf *) private; + driFenceFinish(buf->fence, 0x0, lazy); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + + buf->mapped = 0; + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + return p->kernelBO.offset + buf->start; +} + +static unsigned +pool_flags(struct _DriBufferPool *pool, void *private) +{ + BPool *p = (BPool *) pool->data; + + return p->kernelBO.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + BPool *p = (BPool *) pool->data; + + return p->bufSize; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + if (buf->fence) { + driFenceUnReference(buf->fence); + } + buf->fence = fence; + buf->unfenced = 0; + driFenceReference(buf->fence); + _glthread_UNLOCK_MUTEX(p->mutex); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + return &p->kernelBO; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + _glthread_LOCK_MUTEX(p->mutex); + buf->unfenced = GL_TRUE; + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + BPool *p = (BPool *) pool->data; + + /* + * Wait on outstanding fences. + */ + + _glthread_LOCK_MUTEX(p->mutex); + while ((p->numFree < p->numTot) && p->numDelayed) { + _glthread_UNLOCK_MUTEX(p->mutex); + sched_yield(); + pool_checkFree(p, GL_TRUE); + _glthread_LOCK_MUTEX(p->mutex); + } + + drmBODestroy(pool->fd, &p->kernelBO); + free(p->bufs); + _glthread_UNLOCK_MUTEX(p->mutex); + free(p); + free(pool); +} + + +struct _DriBufferPool * +driBatchPoolInit(int fd, unsigned flags, + unsigned long bufSize, + unsigned numBufs, unsigned checkDelayed) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = createBPool(fd, bufSize, numBufs, flags, checkDelayed); + if (!pool->data) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = &pool_validate; + pool->waitIdle = &pool_waitIdle; + pool->setstatic = NULL; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.h b/src/gallium/winsys/dri/intel/intel_batchpool.h new file mode 100644 index 0000000000..f6a95723bc --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_batchpool.h @@ -0,0 +1,37 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_BATCHPOOL_H +#define INTEL_BATCHPOOL_H + +extern struct _DriBufferPool *driBatchPoolInit(int fd, unsigned flags, + unsigned long bufSize, + unsigned numBufs, + unsigned checkDelayed); + + +#endif /* INTEL_BATCHPOOL_H */ diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c new file mode 100644 index 0000000000..c033f2a592 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -0,0 +1,304 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "i830_dri.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" +#include "intel_winsys.h" +#include "intel_batchbuffer.h" + +#include "state_tracker/st_public.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" + +#include "utils.h" + + +#ifdef DEBUG +int __intel_debug = 0; +#endif + + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +/** + * Extension strings exported by the intel driver. + * + * \note + * It appears that ARB_texture_env_crossbar has "disappeared" compared to the + * old i830-specific driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, + {"GL_SGIS_generate_mipmap", NULL }, + {NULL, NULL} +}; + + + +#ifdef DEBUG +static const struct dri_debug_control debug_control[] = { + {"ioctl", DEBUG_IOCTL}, + {"bat", DEBUG_BATCH}, + {"lock", DEBUG_LOCK}, + {"swap", DEBUG_SWAP}, + {NULL, 0} +}; +#endif + + + +GLboolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct intel_context *intel = CALLOC_STRUCT(intel_context); + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *saPriv = intelScreen->sarea; + int fthrottle_mode; + GLboolean havePools; + struct pipe_context *pipe; + struct st_context *st_share = NULL; + + if (sharedContextPrivate) { + st_share = ((struct intel_context *) sharedContextPrivate)->st; + } + + driContextPriv->driverPrivate = intel; + intel->intelScreen = intelScreen; + intel->driScreen = sPriv; + intel->sarea = saPriv; + + driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i915"); + + + /* + * memory pools + */ + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + havePools = intelCreatePools(sPriv); + DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + if (!havePools) + return GL_FALSE; + + + /* Dri stuff */ + intel->hHWContext = driContextPriv->hHWContext; + intel->driFd = sPriv->fd; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + + fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); + intel->iw.irq_seq = -1; + intel->irqsEmitted = 0; + + intel->batch = intel_batchbuffer_alloc(intel); + intel->last_swap_fence = NULL; + intel->first_swap_fence = NULL; + +#ifdef DEBUG + __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); +#endif + + /* + * Pipe-related setup + */ + if (!getenv("INTEL_HW")) { + pipe = intel_create_softpipe( intel, intelScreen->winsys ); + } + else { + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q33_G: + case PCI_CHIP_Q35_G: + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + pipe = intel_create_i915simple( intel, intelScreen->winsys ); + break; + default: + fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", + intel->intelScreen->deviceID, __FUNCTION__); + + pipe = intel_create_softpipe( intel, intelScreen->winsys ); + break; + } + } + + pipe->priv = intel; + + intel->st = st_create_context(pipe, visual, st_share); + + return GL_TRUE; +} + + +void +intelDestroyContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + + assert(intel); /* should never be null */ + if (intel) { + st_flush(intel->st, PIPE_FLUSH_WAIT); + + intel_batchbuffer_free(intel->batch); + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + if (intel->first_swap_fence) { + driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(intel->first_swap_fence); + intel->first_swap_fence = NULL; + } + + if (intel->intelScreen->dummyContext == intel) + intel->intelScreen->dummyContext = NULL; + + st_destroy_context(intel->st); + free(intel); + } +} + + +GLboolean +intelUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + st_flush(intel->st, 0x0); + /* XXX make_current(NULL)? */ + return GL_TRUE; +} + + +GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + if (driContextPriv) { + struct intel_context *intel = intel_context(driContextPriv); + struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv); + struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv); + + assert(draw_fb->stfb); + assert(read_fb->stfb); + + /* This is for situations in which we need a rendering context but + * there may not be any currently bound. + */ + intel->intelScreen->dummyContext = intel; + + st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); + + if ((intel->driDrawable != driDrawPriv) || + (intel->lastStamp != driDrawPriv->lastStamp)) { + intel->driDrawable = driDrawPriv; + intelUpdateWindowSize(driDrawPriv); + intel->lastStamp = driDrawPriv->lastStamp; + } + + /* The size of the draw buffer will have been updated above. + * If the readbuffer is a different window, check/update its size now. + */ + if (driReadPriv != driDrawPriv) { + intelUpdateWindowSize(driReadPriv); + } + + } + else { + st_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h new file mode 100644 index 0000000000..b01370c049 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -0,0 +1,158 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_CONTEXT_H +#define INTEL_CONTEXT_H + + +#include "drm.h" +#include "intel_screen.h" +#include "i915_drm.h" + + +struct pipe_context; +struct intel_context; +struct _DriBufferObject; +struct st_context; + + +#define INTEL_MAX_FIXUP 64 + +/** + * Intel rendering context, contains a state tracker and intel-specific info. + */ +struct intel_context +{ + struct st_context *st; + + struct _DriFenceObject *last_swap_fence; + struct _DriFenceObject *first_swap_fence; + + struct intel_batchbuffer *batch; + + boolean locked; + char *prevLockFile; + int prevLockLine; + + uint irqsEmitted; + drm_i915_irq_wait_t iw; + + drm_context_t hHWContext; + drmLock *driHwLock; + int driFd; + + __DRIdrawablePrivate *driDrawable; + __DRIscreenPrivate *driScreen; + struct intel_screen *intelScreen; + drmI830Sarea *sarea; + + uint lastStamp; + + /** + * Configuration cache + */ + driOptionCache optionCache; +}; + + + +/** + * Intel framebuffer. + */ +struct intel_framebuffer +{ + struct st_framebuffer *stfb; + + /* other fields TBD */ + int other; +}; + + + + +/* These are functions now: + */ +void LOCK_HARDWARE( struct intel_context *intel ); +void UNLOCK_HARDWARE( struct intel_context *intel ); + +extern char *__progname; + + + +/* ================================================================ + * Debugging: + */ +#ifdef DEBUG +extern int __intel_debug; + +#define DEBUG_SWAP 0x1 +#define DEBUG_LOCK 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BATCH 0x8 + +#define DBG(flag, ...) do { \ + if (__intel_debug & (DEBUG_##flag)) \ + printf(__VA_ARGS__); \ +} while(0) + +#else +#define DBG(flag, ...) +#endif + + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_Q33_G 0x29D2 + + +/** Cast wrapper */ +static INLINE struct intel_context * +intel_context(__DRIcontextPrivate *driContextPriv) +{ + return (struct intel_context *) driContextPriv->driverPrivate; +} + + +/** Cast wrapper */ +static INLINE struct intel_framebuffer * +intel_framebuffer(__DRIdrawablePrivate * driDrawPriv) +{ + return (struct intel_framebuffer *) driDrawPriv->driverPrivate; +} + + +#endif diff --git a/src/gallium/winsys/dri/intel/intel_lock.c b/src/gallium/winsys/dri/intel/intel_lock.c new file mode 100644 index 0000000000..70aa7ea5f4 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_lock.c @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "main/glheader.h" +#include "glapi/glthread.h" +#include +#include "state_tracker/st_public.h" +#include "intel_context.h" +#include "i830_dri.h" + + + +_glthread_DECLARE_STATIC_MUTEX( lockMutex ); + + +static void +intelContendedLock(struct intel_context *intel, uint flags) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIscreenPrivate *sPriv = intel->driScreen; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *sarea = intel->sarea; + + drmGetLock(intel->driFd, intel->hHWContext, flags); + + DBG(LOCK, "%s - got contended lock\n", __progname); + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + if (dPriv) + DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + + if (sarea->width != intelScreen->front.width || + sarea->height != intelScreen->front.height) { + + intelUpdateScreenRotation(sPriv, sarea); + } +} + + +/* Lock the hardware and validate our state. + */ +void LOCK_HARDWARE( struct intel_context *intel ) +{ + char __ret = 0; + + _glthread_LOCK_MUTEX(lockMutex); + assert(!intel->locked); + + DRM_CAS(intel->driHwLock, intel->hHWContext, + (DRM_LOCK_HELD|intel->hHWContext), __ret); + + if (__ret) + intelContendedLock( intel, 0 ); + + DBG(LOCK, "%s - locked\n", __progname); + + intel->locked = 1; +} + + +/* Unlock the hardware using the global current context + */ +void UNLOCK_HARDWARE( struct intel_context *intel ) +{ + assert(intel->locked); + intel->locked = 0; + + DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); + + _glthread_UNLOCK_MUTEX(lockMutex); + + DBG(LOCK, "%s - unlocked\n", __progname); +} diff --git a/src/gallium/winsys/dri/intel/intel_reg.h b/src/gallium/winsys/dri/intel/intel_reg.h new file mode 100644 index 0000000000..f37c24fda9 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_reg.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef _INTEL_REG_H_ +#define _INTEL_REG_H_ + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + +#define MI_BATCH_BUFFER_END (0xA<<23) + + +#endif diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c new file mode 100644 index 0000000000..9e31c013a9 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -0,0 +1,537 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "utils.h" +#include "vblank.h" +#include "xmlpool.h" + +#include "intel_context.h" +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_batchpool.h" +#include "intel_swapbuffers.h" +#include "intel_winsys.h" + +#include "i830_dri.h" +#include "dri_bufpool.h" + +#include "pipe/p_context.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_cb_fbo.h" + + + +PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY + DRI_CONF_FORCE_S3TC_ENABLE(false) + DRI_CONF_ALLOW_LARGE_TEXTURES(1) + DRI_CONF_SECTION_END DRI_CONF_END; + +const uint __driNConfigOptions = 4; + +#ifdef USE_NEW_INTERFACE +static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; +#endif /*USE_NEW_INTERFACE */ + +extern const struct dri_extension card_extensions[]; + + + + +static void +intelPrintDRIInfo(struct intel_screen * intelScreen, + __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) +{ + fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->front.size, intelScreen->front.offset, + intelScreen->front.pitch); + fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); +} + + +#if 0 +static void +intelPrintSAREA(const drmI830Sarea * sarea) +{ + fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, + sarea->height); + fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); + fprintf(stderr, + "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->front_offset, sarea->front_size, + (unsigned) sarea->front_handle); + fprintf(stderr, + "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->back_offset, sarea->back_size, + (unsigned) sarea->back_handle); + fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->depth_offset, sarea->depth_size, + (unsigned) sarea->depth_handle); + fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); + fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); + fprintf(stderr, + "SAREA: rotated offset: 0x%08x size: 0x%x\n", + sarea->rotated_offset, sarea->rotated_size); + fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); +} +#endif + + +/** + * Use the information in the sarea to update the screen parameters + * related to screen rotation. Needs to be called locked. + */ +void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->front.map) { + drmUnmap(intelScreen->front.map, intelScreen->front.size); + intelScreen->front.map = NULL; + } + + if (intelScreen->front.buffer) + driDeleteBuffers(1, &intelScreen->front.buffer); + + intelScreen->front.width = sarea->width; + intelScreen->front.height = sarea->height; + intelScreen->front.offset = sarea->front_offset; + intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp; + intelScreen->front.size = sarea->front_size; + intelScreen->front.handle = sarea->front_handle; + + assert( sarea->front_size >= + intelScreen->front.pitch * intelScreen->front.height ); + + if (!sarea->front_handle) + return; + + if (drmMap(sPriv->fd, + sarea->front_handle, + intelScreen->front.size, + (drmAddress *) & intelScreen->front.map) != 0) { + fprintf(stderr, "drmMap(frontbuffer) failed!\n"); + return; + } + + if (intelScreen->staticPool) { + driGenBuffers(intelScreen->staticPool, "static region", 1, + &intelScreen->front.buffer, 64, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + + driBOSetStatic(intelScreen->front.buffer, + intelScreen->front.offset, + intelScreen->front.pitch * intelScreen->front.height, + intelScreen->front.map, 0); + } +} + + +boolean +intelCreatePools(__DRIscreenPrivate * sPriv) +{ + unsigned batchPoolSize = 1024*1024; + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->havePools) + return GL_TRUE; + + intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); + if (!intelScreen->staticPool) + return GL_FALSE; + + batchPoolSize /= BATCH_SZ; + intelScreen->batchPool = driBatchPoolInit(sPriv->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_LOCAL, + BATCH_SZ, + batchPoolSize, 5); + if (!intelScreen->batchPool) { + fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); + return GL_FALSE; + } + + intelScreen->havePools = GL_TRUE; + + intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + return GL_TRUE; +} + + +static boolean +intelInitDriver(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen; + I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; + + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> + getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; + + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { + fprintf(stderr, + "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + + /* Allocate the private area */ + intelScreen = CALLOC_STRUCT(intel_screen); + if (!intelScreen) + return GL_FALSE; + + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + sPriv->private = (void *) intelScreen; + + intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + + gDRIPriv->sarea_priv_offset); + intelScreen->deviceID = gDRIPriv->deviceID; + intelScreen->front.cpp = gDRIPriv->cpp; + intelScreen->drmMinor = sPriv->drmMinor; + + assert(gDRIPriv->bitsPerPixel == 16 || + gDRIPriv->bitsPerPixel == 32); + + intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + if (0) + intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); + + if (glx_enable_extension != NULL) { + (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); + (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); + (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); + } + + intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd); + + return GL_TRUE; +} + + +static void +intelDestroyScreen(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + /* intelUnmapScreenRegions(intelScreen); */ + + if (intelScreen->havePools) { + driPoolTakeDown(intelScreen->staticPool); + driPoolTakeDown(intelScreen->batchPool); + } + FREE(intelScreen); + sPriv->private = NULL; +} + + +/** + * This is called when we need to set up GL rendering to a new X window. + */ +static boolean +intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + const __GLcontextModes * visual, boolean isPixmap) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + driDrawPriv->w, + driDrawPriv->h, + (void*) intelfb); + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + driDrawPriv->driverPrivate = (void *) intelfb; + return GL_TRUE; + } +} + +static void +intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv); + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); +} + + +/** + * Get information about previous buffer swaps. + */ +static int +intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) +{ + if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) + || (sInfo == NULL)) { + return -1; + } + + return 0; +} + + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +static const struct __DriverAPIRec intelAPI = { + .InitDriver = intelInitDriver, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = intelCopySubBuffer, + .setTexOffset = intelSetTexOffset, +}; + + +static __GLcontextModes * +intelFillInModes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, boolean have_back_buffer) +{ + __GLcontextModes *modes; + __GLcontextModes *m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[3]; + u_int8_t stencil_bits_array[3]; + + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + depth_bits_array[2] = depth_bits; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. It will be a sw fallback, but some apps won't + * care about that. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = 0; + if (depth_bits == 24) + stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; + + stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + if (pixel_bits == 16) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + modes = + (*dri_interface->createContextModes) (num_modes, + sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for (m = modes; m != NULL; m = m->next) { + if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, + __DRIscreen * psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 7, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 7, 0 }; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("i915", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &intelAPI); + + if (psp != NULL) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create + * is called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + } + + return (void *) psp; +} + diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h new file mode 100644 index 0000000000..3396f9e564 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -0,0 +1,113 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _INTEL_SCREEN_H_ +#define _INTEL_SCREEN_H_ + +#include "dri_util.h" +#include "i830_common.h" +#include "xmlconfig.h" +#include "dri_bufpool.h" + +#include "pipe/p_compiler.h" + + +struct intel_screen +{ + struct { + drm_handle_t handle; + + /* We create a static dri buffer for the frontbuffer. + */ + struct _DriBufferObject *buffer; + + char *map; /* memory map */ + int offset; /* from start of video mem, in bytes */ + int pitch; /* row stride, in bytes */ + int width; + int height; + int size; + int cpp; /* for front and back buffers */ + } front; + + int deviceID; + int drmMinor; + + drmI830Sarea *sarea; + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; + + struct _DriBufferPool *batchPool; + struct _DriBufferPool *staticPool; /** for the X screen/framebuffer */ + boolean havePools; + + /** + * Temporary(?) context to use for SwapBuffers or other situations in + * which we need a rendering context, but none is currently bound. + */ + struct intel_context *dummyContext; + + struct pipe_winsys *winsys; +}; + + + +/** cast wrapper */ +static INLINE struct intel_screen * +intel_screen(__DRIscreenPrivate *sPriv) +{ + return (struct intel_screen *) sPriv->private; +} + + +extern void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); + + +extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); + +extern boolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); + +extern boolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + + +extern boolean +intelCreatePools(__DRIscreenPrivate *sPriv); + +extern boolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + + +#endif diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c new file mode 100644 index 0000000000..56b86d6a63 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -0,0 +1,253 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" +#include "intel_winsys.h" + +#include "pipe/p_context.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_fbo.h" + + +/** + * Display a colorbuffer surface in an X window. + * Used for SwapBuffers and flushing front buffer rendering. + * + * \param dPriv the window/drawable to display into + * \param surf the surface to display + * \param rect optional subrect of surface to display (may be NULL). + */ +void +intelDisplaySurface(__DRIdrawablePrivate *dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + struct intel_context *intel = intelScreen->dummyContext; + + DBG(SWAP, "%s\n", __FUNCTION__); + + if (!intel) { + /* XXX this is where some kind of extra/meta context could be useful */ + return; + } + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceUnReference(intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + /* if this drawable isn't currently bound the LOCK_HARDWARE done on the + * current context (which is what intelScreenContext should return) might + * not get a contended lock and thus cliprects not updated (tests/manywin) + */ + if (intel_context(dPriv->driContextPriv) != intel) + DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); + + + if (dPriv && dPriv->numClipRects) { + const int srcWidth = surf->width; + const int srcHeight = surf->height; + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; + const int cpp = intelScreen->front.cpp; + const int srcpitch = surf->pitch; + int BR13, CMD; + int i; + + ASSERT(surf->buffer); + ASSERT(surf->cpp == cpp); + + DBG(SWAP, "screen pitch %d src surface pitch %d\n", + pitch, surf->pitch); + + if (cpp == 2) { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + } + else { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + } + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + drm_clip_rect_t sbox; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->front.width || + pbox->y2 > intelScreen->front.height) { + /* invalid cliprect, skip it */ + continue; + } + + box = *pbox; + + if (rect) { + /* intersect cliprect with user-provided src rect */ + drm_clip_rect_t rrect; + + rrect.x1 = dPriv->x + rect->x1; + rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; + rrect.x2 = rect->x2 + rrect.x1; + rrect.y2 = rect->y2 + rrect.y1; + if (rrect.x1 > box.x1) + box.x1 = rrect.x1; + if (rrect.y1 > box.y1) + box.y1 = rrect.y1; + if (rrect.x2 < box.x2) + box.x2 = rrect.x2; + if (rrect.y2 < box.y2) + box.y2 = rrect.y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + /* restrict blit to size of actually rendered area */ + if (box.x2 - box.x1 > srcWidth) + box.x2 = srcWidth + box.x1; + if (box.y2 - box.y1 > srcHeight) + box.y2 = srcHeight + box.y1; + + DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", + box.x1, box.x2, box.y1, box.y2); + + sbox.x1 = box.x1 - dPriv->x; + sbox.y1 = box.y1 - dPriv->y; + + assert(box.x1 < box.x2); + assert(box.y1 < box.y2); + + /* XXX this could be done with pipe->surface_copy() */ + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((box.y1 << 16) | box.x1); + OUT_BATCH((box.y2 << 16) | box.x2); + + OUT_RELOC(intelScreen->front.buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + OUT_BATCH((sbox.y1 << 16) | sbox.x1); + OUT_BATCH((srcpitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + ADVANCE_BATCH(); + } + + if (intel->first_swap_fence) + driFenceUnReference(intel->first_swap_fence); + intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); + driFenceReference(intel->first_swap_fence); + } + + UNLOCK_HARDWARE(intel); + + if (intel->lastStamp != dPriv->lastStamp) { + intelUpdateWindowSize(dPriv); + intel->lastStamp = dPriv->lastStamp; + } +} + + + +/** + * This will be called whenever the currently bound window is moved/resized. + */ +void +intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(dPriv); + assert(intelfb->stfb); + st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); +} + + + +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, NULL); + st_notify_swapbuffers_complete(intel_fb->stfb); + } +} + + +/** + * Called via glXCopySubBufferMESA() to copy a subrect of the back + * buffer to the front buffer/screen. + */ +void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + drm_clip_rect_t rect; + rect.x1 = x; + rect.y1 = y; + rect.x2 = w; + rect.y2 = h; + + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, &rect); + } +} diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.h b/src/gallium/winsys/dri/intel/intel_swapbuffers.h new file mode 100644 index 0000000000..7ae5fd15a5 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_SWAPBUFFERS_H +#define INTEL_SWAPBUFFERS_H + + +struct pipe_surface; + + +extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t * rect); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, + int x, int y, int w, int h); + +extern void intelUpdateWindowSize(__DRIdrawablePrivate *dPriv); + + +#endif /* INTEL_SWAPBUFFERS_H */ diff --git a/src/gallium/winsys/dri/intel/intel_winsys.h b/src/gallium/winsys/dri/intel/intel_winsys.h new file mode 100644 index 0000000000..ffc40782be --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_winsys.h @@ -0,0 +1,73 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_WINSYS_H +#define INTEL_WINSYS_H + +#include "pipe/p_state.h" + +struct intel_context; +struct pipe_context; +struct pipe_winsys; +struct pipe_buffer; +struct _DriBufferObject; + +struct pipe_winsys * +intel_create_pipe_winsys( int fd ); + +void +intel_destroy_pipe_winsys( struct pipe_winsys *winsys ); + +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ); + +struct pipe_context * +intel_create_i915simple( struct intel_context *intel, + struct pipe_winsys *winsys ); + + +struct intel_buffer { + struct pipe_buffer base; + struct _DriBufferObject *driBO; +}; + +static INLINE struct intel_buffer * +intel_buffer( struct pipe_buffer *buf ) +{ + return (struct intel_buffer *)buf; +} + +static INLINE struct _DriBufferObject * +dri_bo( struct pipe_buffer *buf ) +{ + return intel_buffer(buf)->driBO; +} + + + +#endif diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c new file mode 100644 index 0000000000..1ba6a9e1b2 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -0,0 +1,154 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include +#include +#include "dri_bufpool.h" +#include "dri_bufmgr.h" + +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_winsys.h" + +#include "pipe/p_util.h" +#include "pipe/i915simple/i915_winsys.h" + + +struct intel_i915_winsys { + struct i915_winsys winsys; /**< batch buffer funcs */ + struct intel_context *intel; +}; + + +/* Turn a i915simple winsys into an intel/i915simple winsys: + */ +static inline struct intel_i915_winsys * +intel_i915_winsys( struct i915_winsys *sws ) +{ + return (struct intel_i915_winsys *)sws; +} + + +/* Simple batchbuffer interface: + */ + +static unsigned *intel_i915_batch_start( struct i915_winsys *sws, + unsigned dwords, + unsigned relocs ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + + /* XXX: check relocs. + */ + if (intel_batchbuffer_space( intel->batch ) >= dwords * 4) { + /* XXX: Hmm, the driver can't really do much with this pointer: + */ + return (unsigned *)intel->batch->ptr; + } + else + return NULL; +} + +static void intel_i915_batch_dword( struct i915_winsys *sws, + unsigned dword ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + intel_batchbuffer_emit_dword( intel->batch, dword ); +} + +static void intel_i915_batch_reloc( struct i915_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + unsigned flags = DRM_BO_FLAG_MEM_TT; + unsigned mask = DRM_BO_MASK_MEM; + + if (access_flags & I915_BUFFER_ACCESS_WRITE) { + flags |= DRM_BO_FLAG_WRITE; + mask |= DRM_BO_FLAG_WRITE; + } + + if (access_flags & I915_BUFFER_ACCESS_READ) { + flags |= DRM_BO_FLAG_READ; + mask |= DRM_BO_FLAG_READ; + } + + intel_batchbuffer_emit_reloc( intel->batch, + dri_bo( buf ), + flags, mask, + delta ); +} + + + +static void intel_i915_batch_flush( struct i915_winsys *sws ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + + intel_batchbuffer_flush( intel->batch ); +// if (0) intel_i915_batch_wait_idle( sws ); +} + + +static void intel_i915_batch_finish( struct i915_winsys *sws ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + intel_batchbuffer_finish( intel->batch ); +} + + +/** + * Create i915 hardware rendering context. + */ +struct pipe_context * +intel_create_i915simple( struct intel_context *intel, + struct pipe_winsys *winsys ) +{ + struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys ); + + /* Fill in this struct with callbacks that i915simple will need to + * communicate with the window system, buffer manager, etc. + */ + iws->winsys.batch_start = intel_i915_batch_start; + iws->winsys.batch_dword = intel_i915_batch_dword; + iws->winsys.batch_reloc = intel_i915_batch_reloc; + iws->winsys.batch_flush = intel_i915_batch_flush; + iws->winsys.batch_finish = intel_i915_batch_finish; + iws->intel = intel; + + /* Create the i915simple context: + */ + return i915_create( winsys, + &iws->winsys, + intel->intelScreen->deviceID ); +} diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c new file mode 100644 index 0000000000..789a386500 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -0,0 +1,302 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include +#include +#include "dri_bufpool.h" +#include "dri_bufmgr.h" + +#include "intel_context.h" +#include "intel_winsys.h" +#include "intel_swapbuffers.h" +#include "intel_batchbuffer.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + + + +struct intel_pipe_winsys { + struct pipe_winsys winsys; + struct _DriBufferPool *regionPool; +}; + + + +/* Turn a pipe winsys into an intel/pipe winsys: + */ +static inline struct intel_pipe_winsys * +intel_pipe_winsys( struct pipe_winsys *winsys ) +{ + return (struct intel_pipe_winsys *)winsys; +} + + +/* Most callbacks map direcly onto dri_bufmgr operations: + */ +static void *intel_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags ) +{ + unsigned drm_flags = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + drm_flags |= DRM_BO_FLAG_WRITE; + + if (flags & PIPE_BUFFER_USAGE_CPU_READ) + drm_flags |= DRM_BO_FLAG_READ; + + return driBOMap( dri_bo(buf), drm_flags, 0 ); +} + +static void intel_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnmap( dri_bo(buf) ); +} + + +static void +intel_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnReference( dri_bo(buf) ); +} + + +/* Pipe has no concept of pools. We choose the tex/region pool + * for all buffers. + * Grabs the hardware lock! + */ +static struct pipe_buffer * +intel_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size ) +{ + struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + unsigned flags = 0; + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (usage & (PIPE_BUFFER_USAGE_VERTEX /*| IWS_BUFFER_USAGE_LOCAL*/)) { + flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + } else { + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + } + + if (usage & PIPE_BUFFER_USAGE_GPU_READ) + flags |= DRM_BO_FLAG_READ; + + if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) + flags |= DRM_BO_FLAG_WRITE; + + /* drm complains if we don't set any read/write flags. + */ + if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) + flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + +#if 0 + if (flags & IWS_BUFFER_USAGE_EXE) + flags |= DRM_BO_FLAG_EXE; + + if (usage & IWS_BUFFER_USAGE_CACHED) + flags |= DRM_BO_FLAG_CACHED; +#endif + + driGenBuffers( iws->regionPool, + "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); + + driBOData( buffer->driBO, size, NULL, 0 ); + + return &buffer->base; +} + + +static struct pipe_buffer * +intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) +{ + struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + + driGenUserBuffer( iws->regionPool, + "pipe user buffer", &buffer->driBO, ptr, bytes); + + return &buffer->base; +} + + +/* The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +intel_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + intelDisplaySurface(dPriv, surf, NULL); +} + + +static struct pipe_surface * +intel_i915_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); + if (surf) { + surf->refcount = 1; + surf->winsys = winsys; + } + return surf; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +/** + * Copied from xm_winsys.c + */ +static int +intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags) +{ + const unsigned alignment = 64; + int ret; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + + +static void +intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + + +static void +intel_printf( struct pipe_winsys *winsys, const char *fmtString, ... ) +{ + va_list args; + va_start( args, fmtString ); + vfprintf(stderr, fmtString, args); + va_end( args ); +} + +static const char * +intel_get_name( struct pipe_winsys *winsys ) +{ + return "Intel/DRI/ttm"; +} + + +struct pipe_winsys * +intel_create_pipe_winsys( int fd ) +{ + struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys ); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + * + * Pipe would be happy with a malloc based memory manager, but + * the SwapBuffers implementation in this winsys driver requires + * that rendering be done to an appropriate _DriBufferObject. + */ + iws->winsys.buffer_create = intel_buffer_create; + iws->winsys.user_buffer_create = intel_user_buffer_create; + iws->winsys.buffer_map = intel_buffer_map; + iws->winsys.buffer_unmap = intel_buffer_unmap; + iws->winsys.buffer_destroy = intel_buffer_destroy; + iws->winsys.flush_frontbuffer = intel_flush_frontbuffer; + iws->winsys.printf = intel_printf; + iws->winsys.get_name = intel_get_name; + iws->winsys.surface_alloc = intel_i915_surface_alloc; + iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; + iws->winsys.surface_release = intel_i915_surface_release; + + if (fd) + iws->regionPool = driDRMPoolInit(fd); + + return &iws->winsys; +} + + +void +intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) +{ + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + if (iws->regionPool) { + driPoolTakeDown(iws->regionPool); + } + free(iws); +} + diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c new file mode 100644 index 0000000000..cec3437831 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c @@ -0,0 +1,81 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include "intel_context.h" +#include "intel_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_format.h" +#include "pipe/softpipe/sp_winsys.h" + + +struct intel_softpipe_winsys { + struct softpipe_winsys sws; + struct intel_context *intel; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean +intel_is_format_supported(struct softpipe_winsys *sws, + enum pipe_format format) +{ + switch(format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: + return TRUE; + default: + return FALSE; + } +} + + +/** + * Create rendering context which uses software rendering. + */ +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ) +{ + struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); + + /* Fill in this struct with callbacks that softpipe will need to + * communicate with the window system, buffer manager, etc. + */ + isws->sws.is_format_supported = intel_is_format_supported; + isws->intel = intel; + + /* Create the softpipe context: + */ + return softpipe_create( winsys, &isws->sws ); +} diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h new file mode 100644 index 0000000000..d4d58886ce --- /dev/null +++ b/src/gallium/winsys/dri/intel/server/i830_common.h @@ -0,0 +1,226 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. +Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ + +#ifndef _I830_COMMON_H_ +#define _I830_COMMON_H_ + + +#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ +#define I830_LOG_MIN_TEX_REGION_SIZE 14 + + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_I830_INIT 0x00 +#define DRM_I830_FLUSH 0x01 +#define DRM_I830_FLIP 0x02 +#define DRM_I830_BATCHBUFFER 0x03 +#define DRM_I830_IRQ_EMIT 0x04 +#define DRM_I830_IRQ_WAIT 0x05 +#define DRM_I830_GETPARAM 0x06 +#define DRM_I830_SETPARAM 0x07 +#define DRM_I830_ALLOC 0x08 +#define DRM_I830_FREE 0x09 +#define DRM_I830_INIT_HEAP 0x0a +#define DRM_I830_CMDBUFFER 0x0b +#define DRM_I830_DESTROY_HEAP 0x0c +#define DRM_I830_SET_VBLANK_PIPE 0x0d +#define DRM_I830_GET_VBLANK_PIPE 0x0e + +typedef struct { + enum { + I830_INIT_DMA = 0x01, + I830_CLEANUP_DMA = 0x02, + I830_RESUME_DMA = 0x03 + } func; + unsigned int mmio_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; + unsigned int back_pitch; + unsigned int depth_pitch; + unsigned int cpp; + unsigned int chipset; +} drmI830Init; + +typedef struct { + drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; + int last_upload; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int ctxOwner; /* last context to upload state */ + int texAge; + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + int perf_boxes; /* performance boxes to be displayed */ + int width, height; /* screen size in pixels */ + + drm_handle_t front_handle; + int front_offset; + int front_size; + + drm_handle_t back_handle; + int back_offset; + int back_size; + + drm_handle_t depth_handle; + int depth_offset; + int depth_size; + + drm_handle_t tex_handle; + int tex_offset; + int tex_size; + int log_tex_granularity; + int pitch; + int rotation; /* 0, 90, 180 or 270 */ + int rotated_offset; + int rotated_size; + int rotated_pitch; + int virtualX, virtualY; + + unsigned int front_tiled; + unsigned int back_tiled; + unsigned int depth_tiled; + unsigned int rotated_tiled; + unsigned int rotated2_tiled; + + int pipeA_x; + int pipeA_y; + int pipeA_w; + int pipeA_h; + int pipeB_x; + int pipeB_y; + int pipeB_w; + int pipeB_h; + + /* Triple buffering */ + drm_handle_t third_handle; + int third_offset; + int third_size; + unsigned int third_tiled; +} drmI830Sarea; + +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + + +typedef struct { + int start; /* agp offset */ + int used; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830BatchBuffer; + +typedef struct { + char *buf; /* agp offset */ + int sz; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830CmdBuffer; + +typedef struct { + int *irq_seq; +} drmI830IrqEmit; + +typedef struct { + int irq_seq; +} drmI830IrqWait; + +typedef struct { + int param; + int *value; +} drmI830GetParam; + +#define I830_PARAM_IRQ_ACTIVE 1 +#define I830_PARAM_ALLOW_BATCHBUFFER 2 + +typedef struct { + int param; + int value; +} drmI830SetParam; + +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 +#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 +#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 + + +/* A memory manager for regions of shared memory: + */ +#define I830_MEM_REGION_AGP 1 + +typedef struct { + int region; + int alignment; + int size; + int *region_offset; /* offset from start of fb or agp */ +} drmI830MemAlloc; + +typedef struct { + int region; + int region_offset; +} drmI830MemFree; + +typedef struct { + int region; + int size; + int start; +} drmI830MemInitHeap; + +typedef struct { + int region; +} drmI830MemDestroyHeap; + +#define DRM_I830_VBLANK_PIPE_A 1 +#define DRM_I830_VBLANK_PIPE_B 2 + +typedef struct { + int pipe; +} drmI830VBlankPipe; + +#endif /* _I830_DRM_H_ */ diff --git a/src/gallium/winsys/dri/intel/server/i830_dri.h b/src/gallium/winsys/dri/intel/server/i830_dri.h new file mode 100644 index 0000000000..c2a3af8cbf --- /dev/null +++ b/src/gallium/winsys/dri/intel/server/i830_dri.h @@ -0,0 +1,63 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ + +#ifndef _I830_DRI_H +#define _I830_DRI_H + +#include "xf86drm.h" +#include "i830_common.h" + +#define I830_MAX_DRAWABLES 256 + +#define I830_MAJOR_VERSION 1 +#define I830_MINOR_VERSION 7 +#define I830_PATCHLEVEL 2 + +#define I830_REG_SIZE 0x80000 + +typedef struct _I830DRIRec { + drm_handle_t regs; + drmSize regsSize; + + drmSize unused1; /* backbufferSize */ + drm_handle_t unused2; /* backbuffer */ + + drmSize unused3; /* depthbufferSize */ + drm_handle_t unused4; /* depthbuffer */ + + drmSize unused5; /* rotatedSize */ + drm_handle_t unused6; /* rotatedbuffer */ + + drm_handle_t unused7; /* textures */ + int unused8; /* textureSize */ + + drm_handle_t unused9; /* agp_buffers */ + drmSize unused10; /* agp_buf_size */ + + int deviceID; + int width; + int height; + int mem; + int cpp; + int bitsPerPixel; + + int unused11[8]; /* was front/back/depth/rotated offset/pitch */ + + int unused12; /* logTextureGranularity */ + int unused13; /* textureOffset */ + + int irq; + int sarea_priv_offset; +} I830DRIRec, *I830DRIPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830ConfigPrivRec, *I830ConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830DRIContextRec, *I830DRIContextPtr; + + +#endif diff --git a/src/gallium/winsys/dri/intel/server/intel.h b/src/gallium/winsys/dri/intel/server/intel.h new file mode 100644 index 0000000000..6ea72499c1 --- /dev/null +++ b/src/gallium/winsys/dri/intel/server/intel.h @@ -0,0 +1,331 @@ +#ifndef _INTEL_H_ +#define _INTEL_H_ + +#include "xf86drm.h" /* drm_handle_t, etc */ + +/* Intel */ +#ifndef PCI_CHIP_I810 +#define PCI_CHIP_I810 0x7121 +#define PCI_CHIP_I810_DC100 0x7123 +#define PCI_CHIP_I810_E 0x7125 +#define PCI_CHIP_I815 0x1132 +#define PCI_CHIP_I810_BRIDGE 0x7120 +#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 +#define PCI_CHIP_I810_E_BRIDGE 0x7124 +#define PCI_CHIP_I815_BRIDGE 0x1130 +#endif + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 + +#ifndef PCI_CHIP_I855_GM +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I855_GM_BRIDGE 0x3580 +#endif + +#ifndef PCI_CHIP_I865_G +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I865_G_BRIDGE 0x2570 +#endif + +#ifndef PCI_CHIP_I915_G +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_G_BRIDGE 0x2580 +#endif + +#ifndef PCI_CHIP_I915_GM +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I915_GM_BRIDGE 0x2590 +#endif + +#ifndef PCI_CHIP_E7221_G +#define PCI_CHIP_E7221_G 0x258A +/* Same as I915_G_BRIDGE */ +#define PCI_CHIP_E7221_G_BRIDGE 0x2580 +#endif + +#ifndef PCI_CHIP_I945_G +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_G_BRIDGE 0x2770 +#endif + +#ifndef PCI_CHIP_I945_GM +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 +#endif + +#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ + pI810->Chipset == PCI_CHIP_I810_DC100 || \ + pI810->Chipset == PCI_CHIP_I810_E) +#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) +#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) +#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) +#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) +#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) +#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) +#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) + +#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) +#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) +#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) +#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) +#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) + +#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) + +#define I830_GMCH_CTRL 0x52 + +#define I830_GMCH_MEM_MASK 0x1 +#define I830_GMCH_MEM_64M 0x1 +#define I830_GMCH_MEM_128M 0 + +#define I830_GMCH_GMS_MASK 0x70 +#define I830_GMCH_GMS_DISABLED 0x00 +#define I830_GMCH_GMS_LOCAL 0x10 +#define I830_GMCH_GMS_STOLEN_512 0x20 +#define I830_GMCH_GMS_STOLEN_1024 0x30 +#define I830_GMCH_GMS_STOLEN_8192 0x40 + +#define I855_GMCH_GMS_MASK (0x7 << 4) +#define I855_GMCH_GMS_DISABLED 0x00 +#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) +#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) +#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) +#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) +#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) +#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) +#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) + +typedef unsigned char Bool; +#define TRUE 1 +#define FALSE 0 + +#define PIPE_NONE 0<<0 +#define PIPE_CRT 1<<0 +#define PIPE_TV 1<<1 +#define PIPE_DFP 1<<2 +#define PIPE_LFP 1<<3 +#define PIPE_CRT2 1<<4 +#define PIPE_TV2 1<<5 +#define PIPE_DFP2 1<<6 +#define PIPE_LFP2 1<<7 + +typedef struct _I830MemPool *I830MemPoolPtr; +typedef struct _I830MemRange *I830MemRangePtr; +typedef struct _I830MemRange { + long Start; + long End; + long Size; + unsigned long Physical; + unsigned long Offset; /* Offset of AGP-allocated portion */ + unsigned long Alignment; + drm_handle_t Key; + unsigned long Pitch; // add pitch + I830MemPoolPtr Pool; +} I830MemRange; + +typedef struct _I830MemPool { + I830MemRange Total; + I830MemRange Free; + I830MemRange Fixed; + I830MemRange Allocated; +} I830MemPool; + +typedef struct { + int tail_mask; + I830MemRange mem; + unsigned char *virtual_start; + int head; + int tail; + int space; +} I830RingBuffer; + +typedef struct _I830Rec { + unsigned char *MMIOBase; + unsigned char *FbBase; + int cpp; + uint32_t aper_size; + unsigned int bios_version; + + /* These are set in PreInit and never changed. */ + long FbMapSize; + long TotalVideoRam; + I830MemRange StolenMemory; /* pre-allocated memory */ + long BIOSMemorySize; /* min stolen pool size */ + int BIOSMemSizeLoc; + + /* These change according to what has been allocated. */ + long FreeMemory; + I830MemRange MemoryAperture; + I830MemPool StolenPool; + long allocatedMemory; + + /* Regions allocated either from the above pools, or from agpgart. */ + /* for single and dual head configurations */ + I830MemRange FrontBuffer; + I830MemRange FrontBuffer2; + I830MemRange Scratch; + I830MemRange Scratch2; + + I830RingBuffer *LpRing; + + I830MemRange BackBuffer; + I830MemRange DepthBuffer; + I830MemRange TexMem; + int TexGranularity; + I830MemRange ContextMem; + int drmMinor; + Bool have3DWindows; + + Bool NeedRingBufferLow; + Bool allowPageFlip; + Bool disableTiling; + + int Chipset; + unsigned long LinearAddr; + unsigned long MMIOAddr; + + drmSize registerSize; /**< \brief MMIO register map size */ + drm_handle_t registerHandle; /**< \brief MMIO register map handle */ + // IOADDRESS ioBase; + int irq; /**< \brief IRQ number */ + int GttBound; + + drm_handle_t ring_map; + unsigned int Fence[8]; + +} I830Rec; + +/* + * 12288 is set as the maximum, chosen because it is enough for + * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. + */ +#define I830_MAXIMUM_VBIOS_MEM 12288 +#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) +#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) + +/* Flags for memory allocation function */ +#define FROM_ANYWHERE 0x00000000 +#define FROM_POOL_ONLY 0x00000001 +#define FROM_NEW_ONLY 0x00000002 +#define FROM_MASK 0x0000000f + +#define ALLOCATE_AT_TOP 0x00000010 +#define ALLOCATE_AT_BOTTOM 0x00000020 +#define FORCE_GAPS 0x00000040 + +#define NEED_PHYSICAL_ADDR 0x00000100 +#define ALIGN_BOTH_ENDS 0x00000200 +#define FORCE_LOW 0x00000400 + +#define ALLOC_NO_TILING 0x00001000 +#define ALLOC_INITIAL 0x00002000 + +#define ALLOCATE_DRY_RUN 0x80000000 + +/* Chipset registers for VIDEO BIOS memory RW access */ +#define _855_DRAM_RW_CONTROL 0x58 +#define _845_DRAM_RW_CONTROL 0x90 +#define DRAM_WRITE 0x33330000 + +#define KB(x) ((x) * 1024) +#define MB(x) ((x) * KB(1024)) + +#define GTT_PAGE_SIZE KB(4) +#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) +#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) +#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) +#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) +#define PRIMARY_RINGBUFFER_SIZE KB(128) + + +/* Ring buffer registers, p277, overview p19 + */ +#define LP_RING 0x2030 +#define HP_RING 0x2040 + +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x000FFFF8 +#define I830_TAIL_MASK 0x001FFFF8 + +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define I830_HEAD_MASK 0x001FFFFC + +#define RING_START 0x08 +#define START_ADDR 0x03FFFFF8 +#define I830_RING_START_MASK 0xFFFFF000 + +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x001FF000 +#define I830_RING_NR_PAGES 0x001FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + + +/* Fence/Tiling ranges [0..7] + */ +#define FENCE 0x2000 +#define FENCE_NR 8 + +#define I915G_FENCE_START_MASK 0x0ff00000 + +#define I830_FENCE_START_MASK 0x07f80000 + +#define FENCE_START_MASK 0x03F80000 +#define FENCE_X_MAJOR 0x00000000 +#define FENCE_Y_MAJOR 0x00001000 +#define FENCE_SIZE_MASK 0x00000700 +#define FENCE_SIZE_512K 0x00000000 +#define FENCE_SIZE_1M 0x00000100 +#define FENCE_SIZE_2M 0x00000200 +#define FENCE_SIZE_4M 0x00000300 +#define FENCE_SIZE_8M 0x00000400 +#define FENCE_SIZE_16M 0x00000500 +#define FENCE_SIZE_32M 0x00000600 +#define FENCE_SIZE_64M 0x00000700 +#define I915G_FENCE_SIZE_1M 0x00000000 +#define I915G_FENCE_SIZE_2M 0x00000100 +#define I915G_FENCE_SIZE_4M 0x00000200 +#define I915G_FENCE_SIZE_8M 0x00000300 +#define I915G_FENCE_SIZE_16M 0x00000400 +#define I915G_FENCE_SIZE_32M 0x00000500 +#define I915G_FENCE_SIZE_64M 0x00000600 +#define I915G_FENCE_SIZE_128M 0x00000700 +#define FENCE_PITCH_1 0x00000000 +#define FENCE_PITCH_2 0x00000010 +#define FENCE_PITCH_4 0x00000020 +#define FENCE_PITCH_8 0x00000030 +#define FENCE_PITCH_16 0x00000040 +#define FENCE_PITCH_32 0x00000050 +#define FENCE_PITCH_64 0x00000060 +#define FENCE_VALID 0x00000001 + +#include + +# define MMIO_IN8(base, offset) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) +# define MMIO_IN32(base, offset) \ + read_MMIO_LE32(base, offset) +# define MMIO_OUT8(base, offset, val) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) +# define MMIO_OUT32(base, offset, val) \ + *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) + + + /* Memory mapped register access macros */ +#define INREG8(addr) MMIO_IN8(MMIO, addr) +#define INREG(addr) MMIO_IN32(MMIO, addr) +#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) + +#define DSPABASE 0x70184 + +#endif diff --git a/src/gallium/winsys/dri/intel/server/intel_dri.c b/src/gallium/winsys/dri/intel/server/intel_dri.c new file mode 100644 index 0000000000..e49c4214ad --- /dev/null +++ b/src/gallium/winsys/dri/intel/server/intel_dri.c @@ -0,0 +1,1306 @@ +/** + * \file server/intel_dri.c + * \brief File to perform the device-specific initialization tasks typically + * done in the X server. + * + * Here they are converted to run in the client (or perhaps a standalone + * process), and to work with the frame buffer device rather than the X + * server infrastructure. + * + * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sub license, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial portions + of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include +#include +#include + +#include "driver.h" +#include "drm.h" + +#include "intel.h" +#include "i830_dri.h" + +#include "memops.h" +#include "pciaccess.h" + +static size_t drm_page_size; +static int nextTile = 0; +#define xf86DrvMsg(...) do {} while(0) + +static const int pitches[] = { + 128 * 8, + 128 * 16, + 128 * 32, + 128 * 64, + 0 +}; + +static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); + +static unsigned long +GetBestTileAlignment(unsigned long size) +{ + unsigned long i; + + for (i = KB(512); i < size; i <<= 1) + ; + + if (i > MB(64)) + i = MB(64); + + return i; +} + +static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) +{ + int i; + unsigned char *MMIO = ctx->MMIOAddress; + + for (i = 0; i < 8; i++) { + OUTREG(FENCE + i * 4, pI830->Fence[i]); + // if (I810_DEBUG & DEBUG_VERBOSE_VGA) + fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); + } +} + +/* Tiled memory is good... really, really good... + * + * Need to make it less likely that we miss out on this - probably + * need to move the frontbuffer away from the 'guarenteed' alignment + * of the first memory segment, or perhaps allocate a discontigous + * framebuffer to get more alignment 'sweet spots'. + */ +static void +SetFence(const DRIDriverContext *ctx, I830Rec *pI830, + int nr, unsigned int start, unsigned int pitch, + unsigned int size) +{ + unsigned int val; + unsigned int fence_mask = 0; + unsigned int fence_pitch; + + if (nr < 0 || nr > 7) { + fprintf(stderr, + "SetFence: fence %d out of range\n",nr); + return; + } + + pI830->Fence[nr] = 0; + + if (IS_I9XX(pI830)) + fence_mask = ~I915G_FENCE_START_MASK; + else + fence_mask = ~I830_FENCE_START_MASK; + + if (start & fence_mask) { + fprintf(stderr, + "SetFence: %d: start (0x%08x) is not %s aligned\n", + nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); + return; + } + + if (start % size) { + fprintf(stderr, + "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", + nr, start, size / 1024); + return; + } + + if (pitch & 127) { + fprintf(stderr, + "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", + nr, pitch); + return; + } + + val = (start | FENCE_X_MAJOR | FENCE_VALID); + + if (IS_I9XX(pI830)) { + switch (size) { + case MB(1): + val |= I915G_FENCE_SIZE_1M; + break; + case MB(2): + val |= I915G_FENCE_SIZE_2M; + break; + case MB(4): + val |= I915G_FENCE_SIZE_4M; + break; + case MB(8): + val |= I915G_FENCE_SIZE_8M; + break; + case MB(16): + val |= I915G_FENCE_SIZE_16M; + break; + case MB(32): + val |= I915G_FENCE_SIZE_32M; + break; + case MB(64): + val |= I915G_FENCE_SIZE_64M; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); + return; + } + } else { + switch (size) { + case KB(512): + val |= FENCE_SIZE_512K; + break; + case MB(1): + val |= FENCE_SIZE_1M; + break; + case MB(2): + val |= FENCE_SIZE_2M; + break; + case MB(4): + val |= FENCE_SIZE_4M; + break; + case MB(8): + val |= FENCE_SIZE_8M; + break; + case MB(16): + val |= FENCE_SIZE_16M; + break; + case MB(32): + val |= FENCE_SIZE_32M; + break; + case MB(64): + val |= FENCE_SIZE_64M; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); + return; + } + } + + if (IS_I9XX(pI830)) + fence_pitch = pitch / 512; + else + fence_pitch = pitch / 128; + + switch (fence_pitch) { + case 1: + val |= FENCE_PITCH_1; + break; + case 2: + val |= FENCE_PITCH_2; + break; + case 4: + val |= FENCE_PITCH_4; + break; + case 8: + val |= FENCE_PITCH_8; + break; + case 16: + val |= FENCE_PITCH_16; + break; + case 32: + val |= FENCE_PITCH_32; + break; + case 64: + val |= FENCE_PITCH_64; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal pitch (%d)\n", nr, pitch); + return; + } + + pI830->Fence[nr] = val; +} + +static Bool +MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) +{ + int pitch, ntiles, i; + + pitch = pMem->Pitch * ctx->cpp; + /* + * Simply try to break the region up into at most four pieces of size + * equal to the alignment. + */ + ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; + if (ntiles >= 4) { + return FALSE; + } + + for (i = 0; i < ntiles; i++, nextTile++) { + SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, + pitch, pMem->Alignment); + } + return TRUE; +} + +static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) +{ + int i; + + /* Clear out */ + for (i = 0; i < 8; i++) + pI830->Fence[i] = 0; + + nextTile = 0; + + if (pI830->BackBuffer.Alignment >= KB(512)) { + if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { + fprintf(stderr, + "Activating tiled memory for the back buffer.\n"); + } else { + fprintf(stderr, + "MakeTiles failed for the back buffer.\n"); + pI830->allowPageFlip = FALSE; + } + } + + if (pI830->DepthBuffer.Alignment >= KB(512)) { + if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { + fprintf(stderr, + "Activating tiled memory for the depth buffer.\n"); + } else { + fprintf(stderr, + "MakeTiles failed for the depth buffer.\n"); + } + } + + return; +} + +static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + struct pci_device host_bridge, ig_dev; + uint32_t gmch_ctrl; + int memsize = 0; + int range; + uint32_t aper_size; + uint32_t membase2 = 0; + + memset(&host_bridge, 0, sizeof(host_bridge)); + memset(&ig_dev, 0, sizeof(ig_dev)); + + ig_dev.dev = 2; + + pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); + + if (IS_I830(pI830) || IS_845G(pI830)) { + if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { + aper_size = 0x80000000; + } else { + aper_size = 0x40000000; + } + } else { + if (IS_I9XX(pI830)) { + int ret; + ret = pci_device_cfg_read_u32(&ig_dev, &membase2, 0x18); + if (membase2 & 0x08000000) + aper_size = 0x8000000; + else + aper_size = 0x10000000; + + fprintf(stderr,"aper size is %08X %08x %d\n", aper_size, membase2, ret); + } else + aper_size = 0x8000000; + } + + pI830->aper_size = aper_size; + + + /* We need to reduce the stolen size, by the GTT and the popup. + * The GTT varying according the the FbMapSize and the popup is 4KB */ + range = (ctx->shared.fbSize / (1024*1024)) + 4; + + if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I855_GMCH_GMS_STOLEN_1M: + memsize = MB(1) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_4M: + memsize = MB(4) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_8M: + memsize = MB(8) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_16M: + memsize = MB(16) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_32M: + memsize = MB(32) - KB(range); + break; + case I915G_GMCH_GMS_STOLEN_48M: + if (IS_I9XX(pI830)) + memsize = MB(48) - KB(range); + break; + case I915G_GMCH_GMS_STOLEN_64M: + if (IS_I9XX(pI830)) + memsize = MB(64) - KB(range); + break; + } + } else { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I830_GMCH_GMS_STOLEN_512: + memsize = KB(512) - KB(range); + break; + case I830_GMCH_GMS_STOLEN_1024: + memsize = MB(1) - KB(range); + break; + case I830_GMCH_GMS_STOLEN_8192: + memsize = MB(8) - KB(range); + break; + case I830_GMCH_GMS_LOCAL: + memsize = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Local memory found, but won't be used.\n"); + break; + } + } + if (memsize > 0) { + fprintf(stderr, + "detected %d kB stolen memory.\n", memsize / 1024); + } else { + fprintf(stderr, + "no video memory detected.\n"); + } + return memsize; +} + +static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) +{ + unsigned long mode = 0x4; + + if (drmAgpAcquire(ctx->drmFD) < 0) { + fprintf(stderr, "[gart] AGP not available\n"); + return 0; + } + + if (drmAgpEnable(ctx->drmFD, mode) < 0) { + fprintf(stderr, "[gart] AGP not enabled\n"); + drmAgpRelease(ctx->drmFD); + return 0; + } + else + fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); + + return 1; +} + +/* + * Allocate memory from the given pool. Grow the pool if needed and if + * possible. + */ +static unsigned long +AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, + I830MemRange *result, I830MemPool *pool, + long size, unsigned long alignment, int flags) +{ + long needed, start, end; + + if (!result || !pool || !size) + return 0; + + /* Calculate how much space is needed. */ + if (alignment <= GTT_PAGE_SIZE) + needed = size; + else { + start = ROUND_TO(pool->Free.Start, alignment); + end = ROUND_TO(start + size, alignment); + needed = end - pool->Free.Start; + } + if (needed > pool->Free.Size) { + return 0; + } + + result->Start = ROUND_TO(pool->Free.Start, alignment); + pool->Free.Start += needed; + result->End = pool->Free.Start; + + pool->Free.Size = pool->Free.End - pool->Free.Start; + result->Size = result->End - result->Start; + result->Pool = pool; + result->Alignment = alignment; + return needed; +} + +static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) +{ + unsigned long start, end; + unsigned long newApStart, newApEnd; + int ret; + if (!result || !size) + return 0; + + if (!alignment) + alignment = 4; + + start = ROUND_TO(pI830->MemoryAperture.Start, alignment); + end = ROUND_TO(start + size, alignment); + newApStart = end; + newApEnd = pI830->MemoryAperture.End; + + ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); + + if (ret) + { + fprintf(stderr,"drmAgpAlloc failed %d\n", ret); + return 0; + } + pI830->allocatedMemory += size; + pI830->MemoryAperture.Start = newApStart; + pI830->MemoryAperture.End = newApEnd; + pI830->MemoryAperture.Size = newApEnd - newApStart; + // pI830->FreeMemory -= size; + result->Start = start; + result->End = start + size; + result->Size = size; + result->Offset = start; + result->Alignment = alignment; + result->Pool = NULL; + + return size; +} + +unsigned long +I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, + I830MemRange *result, I830MemPool *pool, long size, + unsigned long alignment, int flags) +{ + unsigned long ret; + + if (!result) + return 0; + + /* Make sure these are initialised. */ + result->Size = 0; + result->Key = -1; + + if (!size) { + return 0; + } + + if (pool->Free.Size < size) { + ret = AllocFromAGP(ctx, pI830, size, alignment, result); + } + else { + ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); + if (ret == 0) + ret = AllocFromAGP(ctx, pI830, size, alignment, result); + } + return ret; +} + +static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) +{ + if (!mem) + return FALSE; + + if (mem->Key == -1) + return TRUE; + + return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); +} + +/* simple memory allocation routines needed */ +/* put ring buffer in low memory */ +/* need to allocate front, back, depth buffers aligned correctly, + allocate ring buffer, +*/ + +/* */ +static Bool +I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned long size, ret; + unsigned long lines, lineSize, align; + + /* allocate ring buffer */ + memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); + pI830->LpRing->mem.Key = -1; + + size = PRIMARY_RINGBUFFER_SIZE; + + ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); + + if (ret != size) + { + fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); + return FALSE; + } + + pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; + + + /* allocate front buffer */ + memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); + pI830->FrontBuffer.Key = -1; + pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; + + align = KB(512); + + lineSize = ctx->shared.virtualWidth * ctx->cpp; + lines = (ctx->shared.virtualHeight + 15) / 16 * 16; + size = lineSize * lines; + size = ROUND_TO_PAGE(size); + + align = GetBestTileAlignment(size); + + ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate front buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); + pI830->BackBuffer.Key = -1; + pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; + + ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate back buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); + pI830->DepthBuffer.Key = -1; + pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; + + ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); + pI830->ContextMem.Key = -1; + size = KB(32); + + ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate context buffer %ld\n", ret); + return FALSE; + } + +#if 0 + memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); + pI830->TexMem.Key = -1; + + size = 32768 * 1024; + ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); + if (ret < size) + { + fprintf(stderr,"unable to allocate texture memory %ld\n", ret); + return FALSE; + } +#endif + + return TRUE; +} + +static Bool +I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + if (!BindAgpRange(ctx, &pI830->LpRing->mem)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->FrontBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->BackBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->DepthBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->ContextMem)) + return FALSE; +#if 0 + if (!BindAgpRange(ctx, &pI830->TexMem)) + return FALSE; +#endif + return TRUE; +} + +static void SetupDRIMM(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned long aperEnd = ROUND_DOWN_TO(pI830->aper_size, GTT_PAGE_SIZE) / GTT_PAGE_SIZE; + unsigned long aperStart = ROUND_TO(pI830->aper_size - KB(32768), GTT_PAGE_SIZE) / GTT_PAGE_SIZE; + + fprintf(stderr, "aper size is %08X\n", ctx->shared.fbSize); + if (drmMMInit(ctx->drmFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) { + fprintf(stderr, + "DRM MM Initialization Failed\n"); + } else { + fprintf(stderr, + "DRM MM Initialized at offset 0x%lx length %d page\n", aperStart, aperEnd-aperStart); + } + +} + +static Bool +I830CleanupDma(const DRIDriverContext *ctx) +{ + drmI830Init info; + + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_CLEANUP_DMA; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { + fprintf(stderr, "I830 Dma Cleanup Failed\n"); + return FALSE; + } + + return TRUE; +} + +static Bool +I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) +{ + I830RingBuffer *ring = pI830->LpRing; + drmI830Init info; + + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_INIT_DMA; + + info.ring_start = ring->mem.Start + pI830->LinearAddr; + info.ring_end = ring->mem.End + pI830->LinearAddr; + info.ring_size = ring->mem.Size; + + info.mmio_offset = (unsigned int)ctx->MMIOStart; + + info.sarea_priv_offset = sizeof(drm_sarea_t); + + info.front_offset = pI830->FrontBuffer.Start; + info.back_offset = pI830->BackBuffer.Start; + info.depth_offset = pI830->DepthBuffer.Start; + info.w = ctx->shared.virtualWidth; + info.h = ctx->shared.virtualHeight; + info.pitch = ctx->shared.virtualWidth; + info.back_pitch = pI830->BackBuffer.Pitch; + info.depth_pitch = pI830->DepthBuffer.Pitch; + info.cpp = ctx->cpp; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { + fprintf(stderr, + "I830 Dma Initialization Failed\n"); + return FALSE; + } + + return TRUE; +} + +static int I830CheckDRMVersion( const DRIDriverContext *ctx, + I830Rec *pI830 ) +{ + drmVersionPtr version; + + version = drmGetVersion(ctx->drmFD); + + if (version) { + int req_minor, req_patch; + + req_minor = 4; + req_patch = 0; + + if (version->version_major != 1 || + version->version_minor < req_minor || + (version->version_minor == req_minor && + version->version_patchlevel < req_patch)) { + /* Incompatible drm version */ + fprintf(stderr, + "[dri] I830DRIScreenInit failed because of a version " + "mismatch.\n" + "[dri] i915.o kernel module version is %d.%d.%d " + "but version 1.%d.%d or newer is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel, + req_minor, + req_patch); + drmFreeVersion(version); + return 0; + } + + pI830->drmMinor = version->version_minor; + drmFreeVersion(version); + } + return 1; +} + +static void +I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned int itemp; + unsigned char *MMIO = ctx->MMIOAddress; + + OUTREG(LP_RING + RING_LEN, 0); + OUTREG(LP_RING + RING_TAIL, 0); + OUTREG(LP_RING + RING_HEAD, 0); + + if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != + pI830->LpRing->mem.Start) { + fprintf(stderr, + "I830SetRingRegs: Ring buffer start (%lx) violates its " + "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); + } + /* Don't care about the old value. Reserved bits must be zero anyway. */ + itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; + OUTREG(LP_RING + RING_START, itemp); + + if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != + pI830->LpRing->mem.Size - 4096) { + fprintf(stderr, + "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " + "mask (%x)\n", pI830->LpRing->mem.Size - 4096, + I830_RING_NR_PAGES); + } + /* Don't care about the old value. Reserved bits must be zero anyway. */ + itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; + itemp |= (RING_NO_REPORT | RING_VALID); + OUTREG(LP_RING + RING_LEN, itemp); + + pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; + pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); + pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); + if (pI830->LpRing->space < 0) + pI830->LpRing->space += pI830->LpRing->mem.Size; + + SetFenceRegs(ctx, pI830); + + /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky + hacky hacky */ + OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); + +} + +static Bool +I830SetParam(const DRIDriverContext *ctx, int param, int value) +{ + drmI830SetParam sp; + + memset(&sp, 0, sizeof(sp)); + sp.param = param; + sp.value = value; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { + fprintf(stderr, "I830 SetParam Failed\n"); + return FALSE; + } + + return TRUE; +} + +static Bool +I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + fprintf(stderr, + "[drm] Mapping front buffer\n"); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), + sarea->front_size, + DRM_FRAME_BUFFER, /*DRM_AGP,*/ + 0, + &sarea->front_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); + return FALSE; + } + ctx->shared.hFrameBuffer = sarea->front_handle; + ctx->shared.fbSize = sarea->front_size; + fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", + sarea->front_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)(sarea->back_offset), + sarea->back_size, DRM_AGP, 0, + &sarea->back_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", + sarea->back_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)sarea->depth_offset, + sarea->depth_size, DRM_AGP, 0, + &sarea->depth_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", + sarea->depth_handle); + +#if 0 + if (drmAddMap(ctx->drmFD, + (drm_handle_t)sarea->tex_offset, + sarea->tex_size, DRM_AGP, 0, + &sarea->tex_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] textures = 0x%08x\n", + sarea->tex_handle); +#endif + return TRUE; +} + + +static void +I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ +#if 1 + if (sarea->front_handle) { + drmRmMap(ctx->drmFD, sarea->front_handle); + sarea->front_handle = 0; + } +#endif + if (sarea->back_handle) { + drmRmMap(ctx->drmFD, sarea->back_handle); + sarea->back_handle = 0; + } + if (sarea->depth_handle) { + drmRmMap(ctx->drmFD, sarea->depth_handle); + sarea->depth_handle = 0; + } + if (sarea->tex_handle) { + drmRmMap(ctx->drmFD, sarea->tex_handle); + sarea->tex_handle = 0; + } +} + +static Bool +I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + if (drmAddMap(ctx->drmFD, + (drm_handle_t)pI830->LpRing->mem.Start, + pI830->LpRing->mem.Size, DRM_AGP, 0, + &pI830->ring_map) < 0) { + fprintf(stderr, + "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] ring buffer = 0x%08x\n", + pI830->ring_map); + + if (I830InitDma(ctx, pI830) == FALSE) { + return FALSE; + } + + /* init to zero to be safe */ + + I830DRIMapScreenRegions(ctx, pI830, sarea); + SetupDRIMM(ctx, pI830); + + if (ctx->pciDevice != PCI_CHIP_845_G && + ctx->pciDevice != PCI_CHIP_I830_M) { + I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); + } + + /* Okay now initialize the dma engine */ + { + pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, + ctx->pciBus, + ctx->pciDevice, + ctx->pciFunc); + + if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { + fprintf(stderr, + "[drm] failure adding irq handler\n"); + pI830->irq = 0; + return FALSE; + } + else + fprintf(stderr, + "[drm] dma control initialized, using IRQ %d\n", + pI830->irq); + } + + fprintf(stderr, "[dri] visual configs initialized\n"); + + return TRUE; +} + +static Bool +I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + /* need to drmMap front and back buffers and zero them */ + drmAddress map_addr; + int ret; + + ret = drmMap(ctx->drmFD, + sarea->front_handle, + sarea->front_size, + &map_addr); + + if (ret) + { + fprintf(stderr, "Unable to map front buffer\n"); + return FALSE; + } + + drimemsetio((char *)map_addr, + 0, + sarea->front_size); + drmUnmap(map_addr, sarea->front_size); + + + ret = drmMap(ctx->drmFD, + sarea->back_handle, + sarea->back_size, + &map_addr); + + if (ret) + { + fprintf(stderr, "Unable to map back buffer\n"); + return FALSE; + } + + drimemsetio((char *)map_addr, + 0, + sarea->back_size); + drmUnmap(map_addr, sarea->back_size); + + return TRUE; +} + +static Bool +I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) + +{ + I830DRIPtr pI830DRI; + drmI830Sarea *pSAREAPriv; + int err; + + drm_page_size = getpagesize(); + + pI830->registerSize = ctx->MMIOSize; + /* This is a hack for now. We have to have more than a 4k page here + * because of the size of the state. However, the state should be + * in a per-context mapping. This will be added in the Mesa 3.5 port + * of the I830 driver. + */ + ctx->shared.SAREASize = SAREA_MAX; + + /* Note that drmOpen will try to load the kernel module, if needed. */ + ctx->drmFD = drmOpen("i915", NULL ); + if (ctx->drmFD < 0) { + fprintf(stderr, "[drm] drmOpen failed\n"); + return 0; + } + + if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { + fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", + ctx->drmFD, ctx->pciBusID, strerror(-err)); + return 0; + } + + if (drmAddMap( ctx->drmFD, + 0, + ctx->shared.SAREASize, + DRM_SHM, + DRM_CONTAINS_LOCK, + &ctx->shared.hSAREA) < 0) + { + fprintf(stderr, "[drm] drmAddMap failed\n"); + return 0; + } + + fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", + ctx->shared.SAREASize, ctx->shared.hSAREA); + + if (drmMap( ctx->drmFD, + ctx->shared.hSAREA, + ctx->shared.SAREASize, + (drmAddressPtr)(&ctx->pSAREA)) < 0) + { + fprintf(stderr, "[drm] drmMap failed\n"); + return 0; + + } + + memset(ctx->pSAREA, 0, ctx->shared.SAREASize); + fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", + ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); + + + if (drmAddMap(ctx->drmFD, + ctx->MMIOStart, + ctx->MMIOSize, + DRM_REGISTERS, + DRM_READ_ONLY, + &pI830->registerHandle) < 0) { + fprintf(stderr, "[drm] drmAddMap mmio failed\n"); + return 0; + } + fprintf(stderr, + "[drm] register handle = 0x%08x\n", pI830->registerHandle); + + + if (!I830CheckDRMVersion(ctx, pI830)) { + return FALSE; + } + + /* Create a 'server' context so we can grab the lock for + * initialization ioctls. + */ + if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { + fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); + return 0; + } + + DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); + + /* Initialize the SAREA private data structure */ + pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + + sizeof(drm_sarea_t)); + memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + + pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); + pI830->StolenMemory.Start = 0; + pI830->StolenMemory.End = pI830->StolenMemory.Size; + + pI830->MemoryAperture.Start = pI830->StolenMemory.End; + pI830->MemoryAperture.End = KB(40000); + pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; + + pI830->StolenPool.Fixed = pI830->StolenMemory; + pI830->StolenPool.Total = pI830->StolenMemory; + pI830->StolenPool.Free = pI830->StolenPool.Total; + pI830->FreeMemory = pI830->StolenPool.Total.Size; + + if (!AgpInit(ctx, pI830)) + return FALSE; + + if (I830AllocateMemory(ctx, pI830) == FALSE) + { + return FALSE; + } + + if (I830BindMemory(ctx, pI830) == FALSE) + { + return FALSE; + } + + pSAREAPriv->rotated_offset = -1; + pSAREAPriv->rotated_size = 0; + pSAREAPriv->rotated_pitch = ctx->shared.virtualWidth; + + pSAREAPriv->front_offset = pI830->FrontBuffer.Start; + pSAREAPriv->front_size = pI830->FrontBuffer.Size; + pSAREAPriv->width = ctx->shared.virtualWidth; + pSAREAPriv->height = ctx->shared.virtualHeight; + pSAREAPriv->pitch = ctx->shared.virtualWidth; + pSAREAPriv->virtualX = ctx->shared.virtualWidth; + pSAREAPriv->virtualY = ctx->shared.virtualHeight; + pSAREAPriv->back_offset = pI830->BackBuffer.Start; + pSAREAPriv->back_size = pI830->BackBuffer.Size; + pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; + pSAREAPriv->depth_size = pI830->DepthBuffer.Size; +#if 0 + pSAREAPriv->tex_offset = pI830->TexMem.Start; + pSAREAPriv->tex_size = pI830->TexMem.Size; +#endif + pSAREAPriv->log_tex_granularity = pI830->TexGranularity; + + ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); + ctx->driverClientMsgSize = sizeof(I830DRIRec); + pI830DRI = (I830DRIPtr)ctx->driverClientMsg; + pI830DRI->deviceID = pI830->Chipset; + pI830DRI->regsSize = I830_REG_SIZE; + pI830DRI->width = ctx->shared.virtualWidth; + pI830DRI->height = ctx->shared.virtualHeight; + pI830DRI->mem = ctx->shared.fbSize; + pI830DRI->cpp = ctx->cpp; + + pI830DRI->bitsPerPixel = ctx->bpp; + pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); + + err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); + if (err == FALSE) + return FALSE; + + I830SetupMemoryTiling(ctx, pI830); + + /* Quick hack to clear the front & back buffers. Could also use + * the clear ioctl to do this, but would need to setup hw state + * first. + */ + I830ClearScreen(ctx, pI830, pSAREAPriv); + + I830SetRingRegs(ctx, pI830); + + return TRUE; +} + + +/** + * \brief Validate the fbdev mode. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Saves some registers and returns 1. + * + * \sa radeonValidateMode(). + */ +static int i830ValidateMode( const DRIDriverContext *ctx ) +{ + return 1; +} + +/** + * \brief Examine mode returned by fbdev. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Restores registers that fbdev has clobbered and returns 1. + * + * \sa i810ValidateMode(). + */ +static int i830PostValidateMode( const DRIDriverContext *ctx ) +{ + I830Rec *pI830 = ctx->driverPrivate; + + I830SetRingRegs(ctx, pI830); + return 1; +} + + +/** + * \brief Initialize the framebuffer device mode + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Fills in \p info with some default values and some information from \p ctx + * and then calls I810ScreenInit() for the screen initialization. + * + * Before exiting clears the framebuffer memory accessing it directly. + */ +static int i830InitFBDev( DRIDriverContext *ctx ) +{ + I830Rec *pI830 = calloc(1, sizeof(I830Rec)); + int i; + + { + int dummy = ctx->shared.virtualWidth; + + switch (ctx->bpp / 8) { + case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; + case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; + case 3: + case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; + } + + ctx->shared.virtualWidth = dummy; + ctx->shared.Width = ctx->shared.virtualWidth; + } + + + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= ctx->shared.virtualWidth) { + ctx->shared.virtualWidth = pitches[i]; + break; + } + } + + ctx->driverPrivate = (void *)pI830; + + pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); + pI830->Chipset = ctx->chipset; + pI830->LinearAddr = ctx->FBStart; + + if (!I830ScreenInit( ctx, pI830 )) + return 0; + + + return 1; +} + + +/** + * \brief The screen is being closed, so clean up any state and free any + * resources used by the DRI. + * + * \param ctx display handle. + * + * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver + * private data. + */ +static void i830HaltFBDev( DRIDriverContext *ctx ) +{ + drmI830Sarea *pSAREAPriv; + I830Rec *pI830 = ctx->driverPrivate; + + if (pI830->irq) { + drmCtlUninstHandler(ctx->drmFD); + pI830->irq = 0; } + + I830CleanupDma(ctx); + + pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + + sizeof(drm_sarea_t)); + + I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); + drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); + drmClose(ctx->drmFD); + + if (ctx->driverPrivate) { + free(ctx->driverPrivate); + ctx->driverPrivate = 0; + } +} + + +extern void i810NotifyFocus( int ); + +/** + * \brief Exported driver interface for Mini GLX. + * + * \sa DRIDriverRec. + */ +const struct DRIDriverRec __driDriver = { + i830ValidateMode, + i830PostValidateMode, + i830InitFBDev, + i830HaltFBDev, + NULL,//I830EngineShutdown, + NULL, //I830EngineRestore, +#ifndef _EMBEDDED + 0, +#else + i810NotifyFocus, +#endif +}; diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c new file mode 100644 index 0000000000..541d50c6e4 --- /dev/null +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -0,0 +1,392 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#include "brw_aub.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "imports.h" +//#include "intel_winsys.h" + + +struct brw_aubfile { + FILE *file; + unsigned next_free_page; +}; + + +extern char *__progname; + + +struct aub_file_header { + unsigned int instruction_type; + unsigned int pad0:16; + unsigned int minor:8; + unsigned int major:8; + unsigned char application[8*4]; + unsigned int day:8; + unsigned int month:8; + unsigned int year:16; + unsigned int timezone:8; + unsigned int second:8; + unsigned int minute:8; + unsigned int hour:8; + unsigned int comment_length:16; + unsigned int pad1:16; +}; + +struct aub_block_header { + unsigned int instruction_type; + unsigned int operation:8; + unsigned int type:8; + unsigned int address_space:8; + unsigned int pad0:8; + unsigned int general_state_type:8; + unsigned int surface_state_type:8; + unsigned int pad1:16; + unsigned int address; + unsigned int length; +}; + +struct aub_dump_bmp { + unsigned int instruction_type; + unsigned int xmin:16; + unsigned int ymin:16; + unsigned int pitch:16; + unsigned int bpp:8; + unsigned int format:8; + unsigned int xsize:16; + unsigned int ysize:16; + unsigned int addr; + unsigned int unknown; +}; + +enum bh_operation { + BH_COMMENT, + BH_DATA_WRITE, + BH_COMMAND_WRITE, + BH_MMI0_WRITE32, + BH_END_SCENE, + BH_CONFIG_MEMORY_MAP, + BH_MAX_OPERATION +}; + +enum command_write_type { + CW_HWB_RING = 1, + CW_PRIMARY_RING_A, + CW_PRIMARY_RING_B, /* XXX - disagreement with listaub! */ + CW_PRIMARY_RING_C, + CW_MAX_TYPE +}; + +enum memory_map_type { + MM_DEFAULT, + MM_DYNAMIC, + MM_MAX_TYPE +}; + +enum address_space { + ADDR_GTT, + ADDR_LOCAL, + ADDR_MAIN, + ADDR_MAX +}; + + +#define AUB_FILE_HEADER 0xe085000b +#define AUB_BLOCK_HEADER 0xe0c10003 +#define AUB_DUMP_BMP 0xe09e0004 + +/* Registers to control page table + */ +#define PGETBL_CTL 0x2020 +#define PGETBL_ENABLED 0x1 + +#define NR_GTT_ENTRIES 65536 /* 256 mb */ + +#define FAIL \ +do { \ + fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \ + exit(1); \ +} while (0) + + +/* Emit the headers at the top of each aubfile. Initialize the GTT. + */ +static void init_aubfile( FILE *aub_file ) +{ + struct aub_file_header fh; + struct aub_block_header bh; + unsigned int data; + + static int nr; + + nr++; + + /* Emit the aub header: + */ + memset(&fh, 0, sizeof(fh)); + + fh.instruction_type = AUB_FILE_HEADER; + fh.minor = 0x0; + fh.major = 0x7; + memcpy(fh.application, __progname, sizeof(fh.application)); + fh.day = (nr>>24) & 0xff; + fh.month = 0x0; + fh.year = 0x0; + fh.timezone = 0x0; + fh.second = nr & 0xff; + fh.minute = (nr>>8) & 0xff; + fh.hour = (nr>>16) & 0xff; + fh.comment_length = 0x0; + + if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0) + FAIL; + + /* Setup the GTT starting at main memory address zero (!): + */ + memset(&bh, 0, sizeof(bh)); + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_MMI0_WRITE32; + bh.type = 0x0; + bh.address_space = ADDR_GTT; /* ??? */ + bh.general_state_type = 0x0; + bh.surface_state_type = 0x0; + bh.address = PGETBL_CTL; + bh.length = 0x4; + + if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) + FAIL; + + data = 0x0 | PGETBL_ENABLED; + + if (fwrite(&data, sizeof(data), 1, aub_file) < 0) + FAIL; +} + + +static void init_aub_gtt( struct brw_aubfile *aubfile, + unsigned start_offset, + unsigned size ) +{ + FILE *aub_file = aubfile->file; + struct aub_block_header bh; + unsigned int i; + + assert(start_offset + size < NR_GTT_ENTRIES * 4096); + + + memset(&bh, 0, sizeof(bh)); + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_DATA_WRITE; + bh.type = 0x0; + bh.address_space = ADDR_MAIN; + bh.general_state_type = 0x0; + bh.surface_state_type = 0x0; + bh.address = start_offset / 4096 * 4; + bh.length = size / 4096 * 4; + + if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) + FAIL; + + for (i = 0; i < size / 4096; i++) { + unsigned data = aubfile->next_free_page | 1; + + aubfile->next_free_page += 4096; + + if (fwrite(&data, sizeof(data), 1, aub_file) < 0) + FAIL; + } + +} + +static void write_block_header( FILE *aub_file, + struct aub_block_header *bh, + const unsigned *data, + unsigned sz ) +{ + sz = (sz + 3) & ~3; + + if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0) + FAIL; + + if (fwrite(data, sz, 1, aub_file) < 0) + FAIL; + + fflush(aub_file); +} + + +static void write_dump_bmp( FILE *aub_file, + struct aub_dump_bmp *db ) +{ + if (fwrite(db, sizeof(*db), 1, aub_file) < 0) + FAIL; + + fflush(aub_file); +} + + + +void brw_aub_gtt_data( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz, + unsigned type, + unsigned state_type ) +{ + struct aub_block_header bh; + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_DATA_WRITE; + bh.type = type; + bh.address_space = ADDR_GTT; + bh.pad0 = 0; + + if (type == DW_GENERAL_STATE) { + bh.general_state_type = state_type; + bh.surface_state_type = 0; + } + else { + bh.general_state_type = 0; + bh.surface_state_type = state_type; + } + + bh.pad1 = 0; + bh.address = offset; + bh.length = sz; + + write_block_header(aubfile->file, &bh, data, sz); +} + + + +void brw_aub_gtt_cmds( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz ) +{ + struct aub_block_header bh; + unsigned type = CW_PRIMARY_RING_A; + + + bh.instruction_type = AUB_BLOCK_HEADER; + bh.operation = BH_COMMAND_WRITE; + bh.type = type; + bh.address_space = ADDR_GTT; + bh.pad0 = 0; + bh.general_state_type = 0; + bh.surface_state_type = 0; + bh.pad1 = 0; + bh.address = offset; + bh.length = sz; + + write_block_header(aubfile->file, &bh, data, sz); +} + +void brw_aub_dump_bmp( struct brw_aubfile *aubfile, + struct pipe_surface *surface, + unsigned gtt_offset ) +{ + struct aub_dump_bmp db; + unsigned format; + + if (surface->cpp == 4) + format = 0x7; + else + format = 0x3; + + db.instruction_type = AUB_DUMP_BMP; + db.xmin = 0; + db.ymin = 0; + db.format = format; + db.bpp = surface->cpp * 8; + db.pitch = surface->pitch; + db.xsize = surface->width; + db.ysize = surface->height; + db.addr = gtt_offset; + db.unknown = /* surface->tiled ? 0x4 : */ 0x0; + + write_dump_bmp(aubfile->file, &db); +} + + + +struct brw_aubfile *brw_aubfile_create( void ) +{ + struct brw_aubfile *aubfile = CALLOC_STRUCT(brw_aubfile); + char filename[80]; + int val; + static int i = 0; + + i++; + + if (_mesa_getenv("INTEL_AUBFILE")) { + val = snprintf(filename, sizeof(filename), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i%4); + _mesa_printf("--> Aub file: %s\n", filename); + aubfile->file = fopen(filename, "w"); + } + else { + val = snprintf(filename, sizeof(filename), "%s.aub", __progname); + if (val < 0 || val > sizeof(filename)) + strcpy(filename, "default.aub"); + + _mesa_printf("--> Aub file: %s\n", filename); + aubfile->file = fopen(filename, "w"); + } + + if (!aubfile->file) { + _mesa_printf("couldn't open aubfile\n"); + exit(1); + } + + init_aubfile(aubfile->file); + + /* The GTT is located starting address zero in main memory. Pages + * to populate the gtt start after this point. + */ + aubfile->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095; + + /* More or less correspond with all the agp regions mapped by the + * driver: + */ + init_aub_gtt(aubfile, 0, 4096*4); + init_aub_gtt(aubfile, AUB_BUF_START, AUB_BUF_SIZE); + + return aubfile; +} + +void brw_aub_destroy( struct brw_aubfile *aubfile ) +{ + fclose(aubfile->file); + FREE(aubfile); +} diff --git a/src/gallium/winsys/xlib/brw_aub.h b/src/gallium/winsys/xlib/brw_aub.h new file mode 100644 index 0000000000..f5c60c7be2 --- /dev/null +++ b/src/gallium/winsys/xlib/brw_aub.h @@ -0,0 +1,114 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + +#ifndef BRW_AUB_H +#define BRW_AUB_H + +/* We set up this region, buffers may be allocated here: + */ +#define AUB_BUF_START (4096*4) +#define AUB_BUF_SIZE (8*1024*1024) + +struct intel_context; +struct pipe_surface; + +struct brw_aubfile *brw_aubfile_create( void ); + +void brw_aub_destroy( struct brw_aubfile *aubfile ); + +void brw_aub_gtt_data( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz, + unsigned type, + unsigned state_type ); + +void brw_aub_gtt_cmds( struct brw_aubfile *aubfile, + unsigned offset, + const void *data, + unsigned sz ); + +void brw_aub_dump_bmp( struct brw_aubfile *aubfile, + struct pipe_surface *surface, + unsigned gtt_offset ); + + +enum data_write_type { + DW_NOTYPE, + DW_BATCH_BUFFER, + DW_BIN_BUFFER, + DW_BIN_POINTER_LIST, + DW_SLOW_STATE_BUFFER, + DW_VERTEX_BUFFER, + DW_2D_MAP, + DW_CUBE_MAP, + DW_INDIRECT_STATE_BUFFER, + DW_VOLUME_MAP, + DW_1D_MAP, + DW_CONSTANT_BUFFER, + DW_CONSTANT_URB_ENTRY, + DW_INDEX_BUFFER, + DW_GENERAL_STATE, + DW_SURFACE_STATE, + DW_MEDIA_OBJECT_INDIRECT_DATA, + DW_MAX_TYPE +}; + +enum data_write_general_state_type { + DWGS_NOTYPE, + DWGS_VERTEX_SHADER_STATE, + DWGS_GEOMETRY_SHADER_STATE , + DWGS_CLIPPER_STATE, + DWGS_STRIPS_FANS_STATE, + DWGS_WINDOWER_IZ_STATE, + DWGS_COLOR_CALC_STATE, + DWGS_CLIPPER_VIEWPORT_STATE, /* was 0x7 */ + DWGS_STRIPS_FANS_VIEWPORT_STATE, + DWGS_COLOR_CALC_VIEWPORT_STATE, /* was 0x9 */ + DWGS_SAMPLER_STATE, + DWGS_KERNEL_INSTRUCTIONS, + DWGS_SCRATCH_SPACE, + DWGS_SAMPLER_DEFAULT_COLOR, + DWGS_INTERFACE_DESCRIPTOR, + DWGS_VLD_STATE, + DWGS_VFE_STATE, + DWGS_MAX_TYPE +}; + +enum data_write_surface_state_type { + DWSS_NOTYPE, + DWSS_BINDING_TABLE_STATE, + DWSS_SURFACE_STATE, + DWSS_MAX_TYPE +}; + + +#endif diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c new file mode 100644 index 0000000000..902a755075 --- /dev/null +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -0,0 +1,3188 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* + * This is an emulation of the GLX API which allows Mesa/GLX-based programs + * to run on X servers which do not have the real GLX extension. + * + * Thanks to the contributors: + * + * Initial version: Philip Brown (phil@bolthole.com) + * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu) + * Further visual-handling refinements: Wolfram Gloger + * (wmglo@Dent.MED.Uni-Muenchen.DE). + * + * Notes: + * Don't be fooled, stereo isn't supported yet. + */ + + + +#include "glxheader.h" +#include "glxapi.h" +#include "GL/xmesa.h" +#include "context.h" +#include "config.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" +#include "version.h" +#include "xfonts.h" +#include "xmesaP.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_public.h" + + +#ifdef __VMS +#define _mesa_sprintf sprintf +#endif + +/* This indicates the client-side GLX API and GLX encoder version. */ +#define CLIENT_MAJOR_VERSION 1 +#define CLIENT_MINOR_VERSION 4 /* but don't have 1.3's pbuffers, etc yet */ + +/* This indicates the server-side GLX decoder version. + * GLX 1.4 indicates OpenGL 1.3 support + */ +#define SERVER_MAJOR_VERSION 1 +#define SERVER_MINOR_VERSION 4 + +/* This is appended onto the glXGetClient/ServerString version strings. */ +#define MESA_GLX_VERSION "Mesa " MESA_VERSION_STRING + +/* Who implemented this GLX? */ +#define VENDOR "Brian Paul" + +#define EXTENSIONS \ + "GLX_MESA_set_3dfx_mode " \ + "GLX_MESA_copy_sub_buffer " \ + "GLX_MESA_pixmap_colormap " \ + "GLX_MESA_release_buffers " \ + "GLX_ARB_get_proc_address " \ + "GLX_EXT_texture_from_pixmap " \ + "GLX_EXT_visual_info " \ + "GLX_EXT_visual_rating " \ + /*"GLX_SGI_video_sync "*/ \ + "GLX_SGIX_fbconfig " \ + "GLX_SGIX_pbuffer " + +/* + * Our fake GLX context will contain a "real" GLX context and an XMesa context. + * + * Note that a pointer to a __GLXcontext is a pointer to a fake_glx_context, + * and vice versa. + * + * We really just need this structure in order to make the libGL functions + * glXGetCurrentContext(), glXGetCurrentDrawable() and glXGetCurrentDisplay() + * work correctly. + */ +struct fake_glx_context { + __GLXcontext glxContext; /* this MUST be first! */ + XMesaContext xmesaContext; +}; + + + +/**********************************************************************/ +/*** GLX Visual Code ***/ +/**********************************************************************/ + +#define DONT_CARE -1 + + +static XMesaVisual *VisualTable = NULL; +static int NumVisuals = 0; + + +/* + * This struct and some code fragments borrowed + * from Mark Kilgard's GLUT library. + */ +typedef struct _OverlayInfo { + /* Avoid 64-bit portability problems by being careful to use + longs due to the way XGetWindowProperty is specified. Note + that these parameters are passed as CARD32s over X + protocol. */ + unsigned long overlay_visual; + long transparent_type; + long value; + long layer; +} OverlayInfo; + + + +/* Macro to handle c_class vs class field name in XVisualInfo struct */ +#if defined(__cplusplus) || defined(c_plusplus) +#define CLASS c_class +#else +#define CLASS class +#endif + + + +/* + * Test if the given XVisualInfo is usable for Mesa rendering. + */ +static GLboolean +is_usable_visual( XVisualInfo *vinfo ) +{ + switch (vinfo->CLASS) { + case StaticGray: + case GrayScale: + /* Any StaticGray/GrayScale visual works in RGB or CI mode */ + return GL_TRUE; + case StaticColor: + case PseudoColor: + /* Any StaticColor/PseudoColor visual of at least 4 bits */ + if (vinfo->depth>=4) { + return GL_TRUE; + } + else { + return GL_FALSE; + } + case TrueColor: + case DirectColor: + /* Any depth of TrueColor or DirectColor works in RGB mode */ + return GL_TRUE; + default: + /* This should never happen */ + return GL_FALSE; + } +} + + + +/** + * Get an array OverlayInfo records for specified screen. + * \param dpy the display + * \param screen screen number + * \param numOverlays returns numver of OverlayInfo records + * \return pointer to OverlayInfo array, free with XFree() + */ +static OverlayInfo * +GetOverlayInfo(Display *dpy, int screen, int *numOverlays) +{ + Atom overlayVisualsAtom; + Atom actualType; + Status status; + unsigned char *ovInfo; + unsigned long sizeData, bytesLeft; + int actualFormat; + + /* + * The SERVER_OVERLAY_VISUALS property on the root window contains + * a list of overlay visuals. Get that list now. + */ + overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True); + if (overlayVisualsAtom == None) { + return 0; + } + + status = XGetWindowProperty(dpy, RootWindow(dpy, screen), + overlayVisualsAtom, 0L, (long) 10000, False, + overlayVisualsAtom, &actualType, &actualFormat, + &sizeData, &bytesLeft, + &ovInfo); + + if (status != Success || actualType != overlayVisualsAtom || + actualFormat != 32 || sizeData < 4) { + /* something went wrong */ + XFree((void *) ovInfo); + *numOverlays = 0; + return NULL; + } + + *numOverlays = sizeData / 4; + return (OverlayInfo *) ovInfo; +} + + + +/** + * Return the level (overlay, normal, underlay) of a given XVisualInfo. + * Input: dpy - the X display + * vinfo - the XVisualInfo to test + * Return: level of the visual: + * 0 = normal planes + * >0 = overlay planes + * <0 = underlay planes + */ +static int +level_of_visual( Display *dpy, XVisualInfo *vinfo ) +{ + OverlayInfo *overlay_info; + int numOverlaysPerScreen, i; + + overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); + if (!overlay_info) { + return 0; + } + + /* search the overlay visual list for the visual ID of interest */ + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *ov = overlay_info + i; + if (ov->overlay_visual == vinfo->visualid) { + /* found the visual */ + if (/*ov->transparent_type==1 &&*/ ov->layer!=0) { + int level = ov->layer; + XFree((void *) overlay_info); + return level; + } + else { + XFree((void *) overlay_info); + return 0; + } + } + } + + /* The visual ID was not found in the overlay list. */ + XFree((void *) overlay_info); + return 0; +} + + + + +/* + * Given an XVisualInfo and RGB, Double, and Depth buffer flags, save the + * configuration in our list of GLX visuals. + */ +static XMesaVisual +save_glx_visual( Display *dpy, XVisualInfo *vinfo, + GLboolean rgbFlag, GLboolean alphaFlag, GLboolean dbFlag, + GLboolean stereoFlag, + GLint depth_size, GLint stencil_size, + GLint accumRedSize, GLint accumGreenSize, + GLint accumBlueSize, GLint accumAlphaSize, + GLint level, GLint numAuxBuffers ) +{ + GLboolean ximageFlag = GL_TRUE; + XMesaVisual xmvis; + GLint i; + GLboolean comparePointers; + + if (dbFlag) { + /* Check if the MESA_BACK_BUFFER env var is set */ + char *backbuffer = _mesa_getenv("MESA_BACK_BUFFER"); + if (backbuffer) { + if (backbuffer[0]=='p' || backbuffer[0]=='P') { + ximageFlag = GL_FALSE; + } + else if (backbuffer[0]=='x' || backbuffer[0]=='X') { + ximageFlag = GL_TRUE; + } + else { + _mesa_warning(NULL, "Mesa: invalid value for MESA_BACK_BUFFER environment variable, using an XImage."); + } + } + } + + if (stereoFlag) { + /* stereo not supported */ + return NULL; + } + + /* Comparing IDs uses less memory but sometimes fails. */ + /* XXX revisit this after 3.0 is finished. */ + if (_mesa_getenv("MESA_GLX_VISUAL_HACK")) + comparePointers = GL_TRUE; + else + comparePointers = GL_FALSE; + + /* Force the visual to have an alpha channel */ + if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA")) + alphaFlag = GL_TRUE; + + /* First check if a matching visual is already in the list */ + for (i=0; idisplay == dpy + && v->mesa_visual.level == level + && v->mesa_visual.numAuxBuffers == numAuxBuffers + && v->ximage_flag == ximageFlag + && v->mesa_visual.rgbMode == rgbFlag + && v->mesa_visual.doubleBufferMode == dbFlag + && v->mesa_visual.stereoMode == stereoFlag + && (v->mesa_visual.alphaBits > 0) == alphaFlag + && (v->mesa_visual.depthBits >= depth_size || depth_size == 0) + && (v->mesa_visual.stencilBits >= stencil_size || stencil_size == 0) + && (v->mesa_visual.accumRedBits >= accumRedSize || accumRedSize == 0) + && (v->mesa_visual.accumGreenBits >= accumGreenSize || accumGreenSize == 0) + && (v->mesa_visual.accumBlueBits >= accumBlueSize || accumBlueSize == 0) + && (v->mesa_visual.accumAlphaBits >= accumAlphaSize || accumAlphaSize == 0)) { + /* now either compare XVisualInfo pointers or visual IDs */ + if ((!comparePointers && v->visinfo->visualid == vinfo->visualid) + || (comparePointers && v->vishandle == vinfo)) { + return v; + } + } + } + + /* Create a new visual and add it to the list. */ + + xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag, + stereoFlag, ximageFlag, + depth_size, stencil_size, + accumRedSize, accumBlueSize, + accumBlueSize, accumAlphaSize, 0, level, + GLX_NONE_EXT ); + if (xmvis) { + /* Save a copy of the pointer now so we can find this visual again + * if we need to search for it in find_glx_visual(). + */ + xmvis->vishandle = vinfo; + /* Allocate more space for additional visual */ + VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable, + sizeof(XMesaVisual) * NumVisuals, + sizeof(XMesaVisual) * (NumVisuals + 1)); + /* add xmvis to the list */ + VisualTable[NumVisuals] = xmvis; + NumVisuals++; + /* XXX minor hack, because XMesaCreateVisual doesn't support an + * aux buffers parameter. + */ + xmvis->mesa_visual.numAuxBuffers = numAuxBuffers; + } + return xmvis; +} + + +/** + * Return the default number of bits for the Z buffer. + * If defined, use the MESA_GLX_DEPTH_BITS env var value. + * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant. + * XXX probably do the same thing for stencil, accum, etc. + */ +static GLint +default_depth_bits(void) +{ + int zBits; + const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS"); + if (zEnv) + zBits = _mesa_atoi(zEnv); + else + zBits = DEFAULT_SOFTWARE_DEPTH_BITS; + return zBits; +} + +static GLint +default_alpha_bits(void) +{ + int aBits; + const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS"); + if (aEnv) + aBits = _mesa_atoi(aEnv); + else + aBits = 0; + return aBits; +} + +static GLint +default_accum_bits(void) +{ + return 16; +} + + + +/* + * Create a GLX visual from a regular XVisualInfo. + * This is called when Fake GLX is given an XVisualInfo which wasn't + * returned by glXChooseVisual. Since this is the first time we're + * considering this visual we'll take a guess at reasonable values + * for depth buffer size, stencil size, accum size, etc. + * This is the best we can do with a client-side emulation of GLX. + */ +static XMesaVisual +create_glx_visual( Display *dpy, XVisualInfo *visinfo ) +{ + int vislevel; + GLint zBits = 24; /*default_depth_bits();*/ + GLint accBits = default_accum_bits(); + GLboolean alphaFlag = default_alpha_bits() > 0; + + vislevel = level_of_visual( dpy, visinfo ); + if (vislevel) { + /* Configure this visual as a CI, single-buffered overlay */ + return save_glx_visual( dpy, visinfo, + GL_FALSE, /* rgb */ + GL_FALSE, /* alpha */ + GL_FALSE, /* double */ + GL_FALSE, /* stereo */ + 0, /* depth bits */ + 0, /* stencil bits */ + 0,0,0,0, /* accum bits */ + vislevel, /* level */ + 0 /* numAux */ + ); + } + else if (is_usable_visual( visinfo )) { + if (_mesa_getenv("MESA_GLX_FORCE_CI")) { + /* Configure this visual as a COLOR INDEX visual. */ + return save_glx_visual( dpy, visinfo, + GL_FALSE, /* rgb */ + GL_FALSE, /* alpha */ + GL_TRUE, /* double */ + GL_FALSE, /* stereo */ + zBits, + STENCIL_BITS, + 0, 0, 0, 0, /* accum bits */ + 0, /* level */ + 0 /* numAux */ + ); + } + else { + /* Configure this visual as RGB, double-buffered, depth-buffered. */ + /* This is surely wrong for some people's needs but what else */ + /* can be done? They should use glXChooseVisual(). */ + return save_glx_visual( dpy, visinfo, + GL_TRUE, /* rgb */ + alphaFlag, /* alpha */ + GL_TRUE, /* double */ + GL_FALSE, /* stereo */ + zBits, + STENCIL_BITS, + accBits, /* r */ + accBits, /* g */ + accBits, /* b */ + accBits, /* a */ + 0, /* level */ + 0 /* numAux */ + ); + } + } + else { + _mesa_warning(NULL, "Mesa: error in glXCreateContext: bad visual\n"); + return NULL; + } +} + + + +/* + * Find the GLX visual associated with an XVisualInfo. + */ +static XMesaVisual +find_glx_visual( Display *dpy, XVisualInfo *vinfo ) +{ + int i; + + /* try to match visual id */ + for (i=0;idisplay==dpy + && VisualTable[i]->visinfo->visualid == vinfo->visualid) { + return VisualTable[i]; + } + } + + /* if that fails, try to match pointers */ + for (i=0;idisplay==dpy && VisualTable[i]->vishandle==vinfo) { + return VisualTable[i]; + } + } + + return NULL; +} + + + +/** + * Return the transparent pixel value for a GLX visual. + * Input: glxvis - the glx_visual + * Return: a pixel value or -1 if no transparent pixel + */ +static int +transparent_pixel( XMesaVisual glxvis ) +{ + Display *dpy = glxvis->display; + XVisualInfo *vinfo = glxvis->visinfo; + OverlayInfo *overlay_info; + int numOverlaysPerScreen, i; + + overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); + if (!overlay_info) { + return -1; + } + + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *ov = overlay_info + i; + if (ov->overlay_visual == vinfo->visualid) { + /* found it! */ + if (ov->transparent_type == 0) { + /* type 0 indicates no transparency */ + XFree((void *) overlay_info); + return -1; + } + else { + /* ov->value is the transparent pixel */ + XFree((void *) overlay_info); + return ov->value; + } + } + } + + /* The visual ID was not found in the overlay list. */ + XFree((void *) overlay_info); + return -1; +} + + + +/** + * Try to get an X visual which matches the given arguments. + */ +static XVisualInfo * +get_visual( Display *dpy, int scr, unsigned int depth, int xclass ) +{ + XVisualInfo temp, *vis; + long mask; + int n; + unsigned int default_depth; + int default_class; + + mask = VisualScreenMask | VisualDepthMask | VisualClassMask; + temp.screen = scr; + temp.depth = depth; + temp.CLASS = xclass; + + default_depth = DefaultDepth(dpy,scr); + default_class = DefaultVisual(dpy,scr)->CLASS; + + if (depth==default_depth && xclass==default_class) { + /* try to get root window's visual */ + temp.visualid = DefaultVisual(dpy,scr)->visualid; + mask |= VisualIDMask; + } + + vis = XGetVisualInfo( dpy, mask, &temp, &n ); + + /* In case bits/pixel > 24, make sure color channels are still <=8 bits. + * An SGI Infinite Reality system, for example, can have 30bpp pixels: + * 10 bits per color channel. Mesa's limited to a max of 8 bits/channel. + */ + if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) { + if (_mesa_bitcount((GLuint) vis->red_mask ) <= 8 && + _mesa_bitcount((GLuint) vis->green_mask) <= 8 && + _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) { + return vis; + } + else { + XFree((void *) vis); + return NULL; + } + } + + return vis; +} + + + +/* + * Retrieve the value of the given environment variable and find + * the X visual which matches it. + * Input: dpy - the display + * screen - the screen number + * varname - the name of the environment variable + * Return: an XVisualInfo pointer to NULL if error. + */ +static XVisualInfo * +get_env_visual(Display *dpy, int scr, const char *varname) +{ + char value[100], type[100]; + int depth, xclass = -1; + XVisualInfo *vis; + + if (!_mesa_getenv( varname )) { + return NULL; + } + + _mesa_strncpy( value, _mesa_getenv(varname), 100 ); + value[99] = 0; + + sscanf( value, "%s %d", type, &depth ); + + if (_mesa_strcmp(type,"TrueColor")==0) xclass = TrueColor; + else if (_mesa_strcmp(type,"DirectColor")==0) xclass = DirectColor; + else if (_mesa_strcmp(type,"PseudoColor")==0) xclass = PseudoColor; + else if (_mesa_strcmp(type,"StaticColor")==0) xclass = StaticColor; + else if (_mesa_strcmp(type,"GrayScale")==0) xclass = GrayScale; + else if (_mesa_strcmp(type,"StaticGray")==0) xclass = StaticGray; + + if (xclass>-1 && depth>0) { + vis = get_visual( dpy, scr, depth, xclass ); + if (vis) { + return vis; + } + } + + _mesa_warning(NULL, "GLX unable to find visual class=%s, depth=%d.", + type, depth); + + return NULL; +} + + + +/* + * Select an X visual which satisfies the RGBA/CI flag and minimum depth. + * Input: dpy, screen - X display and screen number + * rgba - GL_TRUE = RGBA mode, GL_FALSE = CI mode + * min_depth - minimum visual depth + * preferred_class - preferred GLX visual class or DONT_CARE + * Return: pointer to an XVisualInfo or NULL. + */ +static XVisualInfo * +choose_x_visual( Display *dpy, int screen, GLboolean rgba, int min_depth, + int preferred_class ) +{ + XVisualInfo *vis; + int xclass, visclass = 0; + int depth; + + if (rgba) { + Atom hp_cr_maps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", True); + /* First see if the MESA_RGB_VISUAL env var is defined */ + vis = get_env_visual( dpy, screen, "MESA_RGB_VISUAL" ); + if (vis) { + return vis; + } + /* Otherwise, search for a suitable visual */ + if (preferred_class==DONT_CARE) { + for (xclass=0;xclass<6;xclass++) { + switch (xclass) { + case 0: visclass = TrueColor; break; + case 1: visclass = DirectColor; break; + case 2: visclass = PseudoColor; break; + case 3: visclass = StaticColor; break; + case 4: visclass = GrayScale; break; + case 5: visclass = StaticGray; break; + } + if (min_depth==0) { + /* start with shallowest */ + for (depth=0;depth<=32;depth++) { + if (visclass==TrueColor && depth==8 && !hp_cr_maps) { + /* Special case: try to get 8-bit PseudoColor before */ + /* 8-bit TrueColor */ + vis = get_visual( dpy, screen, 8, PseudoColor ); + if (vis) { + return vis; + } + } + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + else { + /* start with deepest */ + for (depth=32;depth>=min_depth;depth--) { + if (visclass==TrueColor && depth==8 && !hp_cr_maps) { + /* Special case: try to get 8-bit PseudoColor before */ + /* 8-bit TrueColor */ + vis = get_visual( dpy, screen, 8, PseudoColor ); + if (vis) { + return vis; + } + } + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + } + } + else { + /* search for a specific visual class */ + switch (preferred_class) { + case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; + case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; + case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break; + case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break; + case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; + case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; + default: return NULL; + } + if (min_depth==0) { + /* start with shallowest */ + for (depth=0;depth<=32;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + else { + /* start with deepest */ + for (depth=32;depth>=min_depth;depth--) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + } + } + else { + /* First see if the MESA_CI_VISUAL env var is defined */ + vis = get_env_visual( dpy, screen, "MESA_CI_VISUAL" ); + if (vis) { + return vis; + } + /* Otherwise, search for a suitable visual, starting with shallowest */ + if (preferred_class==DONT_CARE) { + for (xclass=0;xclass<4;xclass++) { + switch (xclass) { + case 0: visclass = PseudoColor; break; + case 1: visclass = StaticColor; break; + case 2: visclass = GrayScale; break; + case 3: visclass = StaticGray; break; + } + /* try 8-bit up through 16-bit */ + for (depth=8;depth<=16;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + /* try min_depth up to 8-bit */ + for (depth=min_depth;depth<8;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + } + else { + /* search for a specific visual class */ + switch (preferred_class) { + case GLX_TRUE_COLOR_EXT: visclass = TrueColor; break; + case GLX_DIRECT_COLOR_EXT: visclass = DirectColor; break; + case GLX_PSEUDO_COLOR_EXT: visclass = PseudoColor; break; + case GLX_STATIC_COLOR_EXT: visclass = StaticColor; break; + case GLX_GRAY_SCALE_EXT: visclass = GrayScale; break; + case GLX_STATIC_GRAY_EXT: visclass = StaticGray; break; + default: return NULL; + } + /* try 8-bit up through 16-bit */ + for (depth=8;depth<=16;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + /* try min_depth up to 8-bit */ + for (depth=min_depth;depth<8;depth++) { + vis = get_visual( dpy, screen, depth, visclass ); + if (vis) { + return vis; + } + } + } + } + + /* didn't find a visual */ + return NULL; +} + + + +/* + * Find the deepest X over/underlay visual of at least min_depth. + * Input: dpy, screen - X display and screen number + * level - the over/underlay level + * trans_type - transparent pixel type: GLX_NONE_EXT, + * GLX_TRANSPARENT_RGB_EXT, GLX_TRANSPARENT_INDEX_EXT, + * or DONT_CARE + * trans_value - transparent pixel value or DONT_CARE + * min_depth - minimum visual depth + * preferred_class - preferred GLX visual class or DONT_CARE + * Return: pointer to an XVisualInfo or NULL. + */ +static XVisualInfo * +choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag, + int level, int trans_type, int trans_value, + int min_depth, int preferred_class ) +{ + OverlayInfo *overlay_info; + int numOverlaysPerScreen; + int i; + XVisualInfo *deepvis; + int deepest; + + /*DEBUG int tt, tv; */ + + switch (preferred_class) { + case GLX_TRUE_COLOR_EXT: preferred_class = TrueColor; break; + case GLX_DIRECT_COLOR_EXT: preferred_class = DirectColor; break; + case GLX_PSEUDO_COLOR_EXT: preferred_class = PseudoColor; break; + case GLX_STATIC_COLOR_EXT: preferred_class = StaticColor; break; + case GLX_GRAY_SCALE_EXT: preferred_class = GrayScale; break; + case GLX_STATIC_GRAY_EXT: preferred_class = StaticGray; break; + default: preferred_class = DONT_CARE; + } + + overlay_info = GetOverlayInfo(dpy, scr, &numOverlaysPerScreen); + if (!overlay_info) { + return NULL; + } + + /* Search for the deepest overlay which satisifies all criteria. */ + deepest = min_depth; + deepvis = NULL; + + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *ov = overlay_info + i; + XVisualInfo *vislist, vistemplate; + int count; + + if (ov->layer!=level) { + /* failed overlay level criteria */ + continue; + } + if (!(trans_type==DONT_CARE + || (trans_type==GLX_TRANSPARENT_INDEX_EXT + && ov->transparent_type>0) + || (trans_type==GLX_NONE_EXT && ov->transparent_type==0))) { + /* failed transparent pixel type criteria */ + continue; + } + if (trans_value!=DONT_CARE && trans_value!=ov->value) { + /* failed transparent pixel value criteria */ + continue; + } + + /* get XVisualInfo and check the depth */ + vistemplate.visualid = ov->overlay_visual; + vistemplate.screen = scr; + vislist = XGetVisualInfo( dpy, VisualIDMask | VisualScreenMask, + &vistemplate, &count ); + + if (count!=1) { + /* something went wrong */ + continue; + } + if (preferred_class!=DONT_CARE && preferred_class!=vislist->CLASS) { + /* wrong visual class */ + continue; + } + + /* if RGB was requested, make sure we have True/DirectColor */ + if (rgbFlag && vislist->CLASS != TrueColor + && vislist->CLASS != DirectColor) + continue; + + /* if CI was requested, make sure we have a color indexed visual */ + if (!rgbFlag + && (vislist->CLASS == TrueColor || vislist->CLASS == DirectColor)) + continue; + + if (deepvis==NULL || vislist->depth > deepest) { + /* YES! found a satisfactory visual */ + if (deepvis) { + XFree( deepvis ); + } + deepest = vislist->depth; + deepvis = vislist; + /* DEBUG tt = ov->transparent_type;*/ + /* DEBUG tv = ov->value; */ + } + } + +/*DEBUG + if (deepvis) { + printf("chose 0x%x: layer=%d depth=%d trans_type=%d trans_value=%d\n", + deepvis->visualid, level, deepvis->depth, tt, tv ); + } +*/ + return deepvis; +} + + +/**********************************************************************/ +/*** Display-related functions ***/ +/**********************************************************************/ + + +/** + * Free all XMesaVisuals which are associated with the given display. + */ +static void +destroy_visuals_on_display(Display *dpy) +{ + int i; + for (i = 0; i < NumVisuals; i++) { + if (VisualTable[i]->display == dpy) { + /* remove this visual */ + int j; + free(VisualTable[i]); + for (j = i; j < NumVisuals - 1; j++) + VisualTable[j] = VisualTable[j + 1]; + NumVisuals--; + } + } +} + + +/** + * Called from XCloseDisplay() to let us free our display-related data. + */ +static int +close_display_callback(Display *dpy, XExtCodes *codes) +{ + destroy_visuals_on_display(dpy); + xmesa_destroy_buffers_on_display(dpy); + return 0; +} + + +/** + * Look for the named extension on given display and return a pointer + * to the _XExtension data, or NULL if extension not found. + */ +static _XExtension * +lookup_extension(Display *dpy, const char *extName) +{ + _XExtension *ext; + for (ext = dpy->ext_procs; ext; ext = ext->next) { + if (ext->name && strcmp(ext->name, extName) == 0) { + return ext; + } + } + return NULL; +} + + +/** + * Whenever we're given a new Display pointer, call this function to + * register our close_display_callback function. + */ +static void +register_with_display(Display *dpy) +{ + const char *extName = "MesaGLX"; + _XExtension *ext; + + ext = lookup_extension(dpy, extName); + if (!ext) { + XExtCodes *c = XAddExtension(dpy); + ext = dpy->ext_procs; /* new extension is at head of list */ + assert(c->extension == ext->codes.extension); + ext->name = _mesa_strdup(extName); + ext->close_display = close_display_callback; + } +} + + +/**********************************************************************/ +/*** Begin Fake GLX API Functions ***/ +/**********************************************************************/ + + +/** + * Helper used by glXChooseVisual and glXChooseFBConfig. + * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for + * the later. + * In either case, the attribute list is terminated with the value 'None'. + */ +static XMesaVisual +choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) +{ + const GLboolean rgbModeDefault = fbConfig; + const int *parselist; + XVisualInfo *vis; + int min_ci = 0; + int min_red=0, min_green=0, min_blue=0; + GLboolean rgb_flag = rgbModeDefault; + GLboolean alpha_flag = GL_FALSE; + GLboolean double_flag = GL_FALSE; + GLboolean stereo_flag = GL_FALSE; + GLint depth_size = 0; + GLint stencil_size = 0; + GLint accumRedSize = 0; + GLint accumGreenSize = 0; + GLint accumBlueSize = 0; + GLint accumAlphaSize = 0; + int level = 0; + int visual_type = DONT_CARE; + int trans_type = DONT_CARE; + int trans_value = DONT_CARE; + GLint caveat = DONT_CARE; + XMesaVisual xmvis = NULL; + int desiredVisualID = -1; + int numAux = 0; + + parselist = list; + + while (*parselist) { + + switch (*parselist) { + case GLX_USE_GL: + if (fbConfig) { + /* invalid token */ + return NULL; + } + else { + /* skip */ + parselist++; + } + break; + case GLX_BUFFER_SIZE: + parselist++; + min_ci = *parselist++; + break; + case GLX_LEVEL: + parselist++; + level = *parselist++; + break; + case GLX_RGBA: + if (fbConfig) { + /* invalid token */ + return NULL; + } + else { + rgb_flag = GL_TRUE; + parselist++; + } + break; + case GLX_DOUBLEBUFFER: + parselist++; + if (fbConfig) { + double_flag = *parselist++; + } + else { + double_flag = GL_TRUE; + } + break; + case GLX_STEREO: + parselist++; + if (fbConfig) { + stereo_flag = *parselist++; + } + else { + stereo_flag = GL_TRUE; + } + break; + case GLX_AUX_BUFFERS: + parselist++; + numAux = *parselist++; + if (numAux > MAX_AUX_BUFFERS) + return NULL; + break; + case GLX_RED_SIZE: + parselist++; + min_red = *parselist++; + break; + case GLX_GREEN_SIZE: + parselist++; + min_green = *parselist++; + break; + case GLX_BLUE_SIZE: + parselist++; + min_blue = *parselist++; + break; + case GLX_ALPHA_SIZE: + parselist++; + { + GLint size = *parselist++; + alpha_flag = size ? GL_TRUE : GL_FALSE; + } + break; + case GLX_DEPTH_SIZE: + parselist++; + depth_size = *parselist++; + break; + case GLX_STENCIL_SIZE: + parselist++; + stencil_size = *parselist++; + break; + case GLX_ACCUM_RED_SIZE: + parselist++; + { + GLint size = *parselist++; + accumRedSize = MAX2( accumRedSize, size ); + } + break; + case GLX_ACCUM_GREEN_SIZE: + parselist++; + { + GLint size = *parselist++; + accumGreenSize = MAX2( accumGreenSize, size ); + } + break; + case GLX_ACCUM_BLUE_SIZE: + parselist++; + { + GLint size = *parselist++; + accumBlueSize = MAX2( accumBlueSize, size ); + } + break; + case GLX_ACCUM_ALPHA_SIZE: + parselist++; + { + GLint size = *parselist++; + accumAlphaSize = MAX2( accumAlphaSize, size ); + } + break; + + /* + * GLX_EXT_visual_info extension + */ + case GLX_X_VISUAL_TYPE_EXT: + parselist++; + visual_type = *parselist++; + break; + case GLX_TRANSPARENT_TYPE_EXT: + parselist++; + trans_type = *parselist++; + break; + case GLX_TRANSPARENT_INDEX_VALUE_EXT: + parselist++; + trans_value = *parselist++; + break; + case GLX_TRANSPARENT_RED_VALUE_EXT: + case GLX_TRANSPARENT_GREEN_VALUE_EXT: + case GLX_TRANSPARENT_BLUE_VALUE_EXT: + case GLX_TRANSPARENT_ALPHA_VALUE_EXT: + /* ignore */ + parselist++; + parselist++; + break; + + /* + * GLX_EXT_visual_info extension + */ + case GLX_VISUAL_CAVEAT_EXT: + parselist++; + caveat = *parselist++; /* ignored for now */ + break; + + /* + * GLX_ARB_multisample + */ + case GLX_SAMPLE_BUFFERS_ARB: + /* ms not supported */ + return NULL; + case GLX_SAMPLES_ARB: + /* ms not supported */ + return NULL; + + /* + * FBConfig attribs. + */ + case GLX_RENDER_TYPE: + if (!fbConfig) + return NULL; + parselist++; + if (*parselist == GLX_RGBA_BIT) { + rgb_flag = GL_TRUE; + } + else if (*parselist == GLX_COLOR_INDEX_BIT) { + rgb_flag = GL_FALSE; + } + else if (*parselist == 0) { + rgb_flag = GL_TRUE; + } + parselist++; + break; + case GLX_DRAWABLE_TYPE: + if (!fbConfig) + return NULL; + parselist++; + if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) { + return NULL; /* bad bit */ + } + parselist++; + break; + case GLX_FBCONFIG_ID: + if (!fbConfig) + return NULL; + parselist++; + desiredVisualID = *parselist++; + break; + case GLX_X_RENDERABLE: + if (!fbConfig) + return NULL; + parselist += 2; + /* ignore */ + break; + +#ifdef GLX_EXT_texture_from_pixmap + case GLX_BIND_TO_TEXTURE_RGB_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + parselist++; + if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT | + GLX_TEXTURE_2D_BIT_EXT | + GLX_TEXTURE_RECTANGLE_BIT_EXT)) { + /* invalid bit */ + return NULL; + } + break; + case GLX_Y_INVERTED_EXT: + parselist++; /*skip*/ + break; +#endif + + case None: + /* end of list */ + break; + + default: + /* undefined attribute */ + _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()", + *parselist); + return NULL; + } + } + + (void) caveat; + + /* + * Since we're only simulating the GLX extension this function will never + * find any real GL visuals. Instead, all we can do is try to find an RGB + * or CI visual of appropriate depth. Other requested attributes such as + * double buffering, depth buffer, etc. will be associated with the X + * visual and stored in the VisualTable[]. + */ + if (desiredVisualID != -1) { + /* try to get a specific visual, by visualID */ + XVisualInfo temp; + int n; + temp.visualid = desiredVisualID; + temp.screen = screen; + vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n); + if (vis) { + /* give the visual some useful GLX attributes */ + double_flag = GL_TRUE; + if (vis->depth > 8) + rgb_flag = GL_TRUE; + depth_size = 24; /*default_depth_bits();*/ + stencil_size = STENCIL_BITS; + /* XXX accum??? */ + } + } + else if (level==0) { + /* normal color planes */ + if (rgb_flag) { + /* Get an RGB visual */ + int min_rgb = min_red + min_green + min_blue; + if (min_rgb>1 && min_rgb<8) { + /* a special case to be sure we can get a monochrome visual */ + min_rgb = 1; + } + vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type ); + } + else { + /* Get a color index visual */ + vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type ); + accumRedSize = accumGreenSize = accumBlueSize = accumAlphaSize = 0; + } + } + else { + /* over/underlay planes */ + if (rgb_flag) { + /* rgba overlay */ + int min_rgb = min_red + min_green + min_blue; + if (min_rgb>1 && min_rgb<8) { + /* a special case to be sure we can get a monochrome visual */ + min_rgb = 1; + } + vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level, + trans_type, trans_value, min_rgb, visual_type ); + } + else { + /* color index overlay */ + vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level, + trans_type, trans_value, min_ci, visual_type ); + } + } + + if (vis) { + /* Note: we're not exactly obeying the glXChooseVisual rules here. + * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the + * largest depth buffer size, which is 32bits/value. Instead, we + * return 16 to maintain performance with earlier versions of Mesa. + */ + if (stencil_size > 0) + depth_size = 24; /* if Z and stencil, always use 24+8 format */ + else if (depth_size > 24) + depth_size = 32; + else if (depth_size > 16) + depth_size = 24; + else if (depth_size > 0) { + depth_size = default_depth_bits(); + } + + if (!alpha_flag) { + alpha_flag = default_alpha_bits() > 0; + } + + /* we only support one size of stencil and accum buffers. */ + if (stencil_size > 0) + stencil_size = STENCIL_BITS; + if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 || + accumAlphaSize > 0) { + accumRedSize = + accumGreenSize = + accumBlueSize = default_accum_bits(); + accumAlphaSize = alpha_flag ? accumRedSize : 0; + } + + xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag, + stereo_flag, depth_size, stencil_size, + accumRedSize, accumGreenSize, + accumBlueSize, accumAlphaSize, level, numAux ); + } + + return xmvis; +} + + +static XVisualInfo * +Fake_glXChooseVisual( Display *dpy, int screen, int *list ) +{ + XMesaVisual xmvis; + + /* register ourselves as an extension on this display */ + register_with_display(dpy); + + xmvis = choose_visual(dpy, screen, list, GL_FALSE); + if (xmvis) { +#if 0 + return xmvis->vishandle; +#else + /* create a new vishandle - the cached one may be stale */ + xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); + if (xmvis->vishandle) { + _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); + } + return xmvis->vishandle; +#endif + } + else + return NULL; +} + + +static GLXContext +Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, + GLXContext share_list, Bool direct ) +{ + XMesaVisual xmvis; + struct fake_glx_context *glxCtx; + struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; + + if (!dpy || !visinfo) + return 0; + + glxCtx = CALLOC_STRUCT(fake_glx_context); + if (!glxCtx) + return 0; + + /* deallocate unused windows/buffers */ +#if 0 + XMesaGarbageCollect(); +#endif + + xmvis = find_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* This visual wasn't found with glXChooseVisual() */ + xmvis = create_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* unusable visual */ + _mesa_free(glxCtx); + return NULL; + } + } + + glxCtx->xmesaContext = XMesaCreateContext(xmvis, + shareCtx ? shareCtx->xmesaContext : NULL); + if (!glxCtx->xmesaContext) { + _mesa_free(glxCtx); + return NULL; + } + + glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.currentDpy = dpy; + glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ + + assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + + return (GLXContext) glxCtx; +} + + +/* XXX these may have to be removed due to thread-safety issues. */ +static GLXContext MakeCurrent_PrevContext = 0; +static GLXDrawable MakeCurrent_PrevDrawable = 0; +static GLXDrawable MakeCurrent_PrevReadable = 0; +static XMesaBuffer MakeCurrent_PrevDrawBuffer = 0; +static XMesaBuffer MakeCurrent_PrevReadBuffer = 0; + + +/* GLX 1.3 and later */ +static Bool +Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, + GLXDrawable read, GLXContext ctx ) +{ + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + + if (ctx && draw && read) { + XMesaBuffer drawBuffer, readBuffer; + XMesaContext xmctx = glxCtx->xmesaContext; + + /* Find the XMesaBuffer which corresponds to the GLXDrawable 'draw' */ + if (ctx == MakeCurrent_PrevContext + && draw == MakeCurrent_PrevDrawable) { + drawBuffer = MakeCurrent_PrevDrawBuffer; + } + else { + drawBuffer = XMesaFindBuffer( dpy, draw ); + } + if (!drawBuffer) { + /* drawable must be a new window! */ + drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw ); + if (!drawBuffer) { + /* Out of memory, or context/drawable depth mismatch */ + return False; + } +#ifdef FX + FXcreateContext( xmctx->xm_visual, draw, xmctx, drawBuffer ); +#endif + } + + /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */ + if (ctx == MakeCurrent_PrevContext + && read == MakeCurrent_PrevReadable) { + readBuffer = MakeCurrent_PrevReadBuffer; + } + else { + readBuffer = XMesaFindBuffer( dpy, read ); + } + if (!readBuffer) { + /* drawable must be a new window! */ + readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read ); + if (!readBuffer) { + /* Out of memory, or context/drawable depth mismatch */ + return False; + } +#ifdef FX + FXcreateContext( xmctx->xm_visual, read, xmctx, readBuffer ); +#endif + } + + MakeCurrent_PrevContext = ctx; + MakeCurrent_PrevDrawable = draw; + MakeCurrent_PrevReadable = read; + MakeCurrent_PrevDrawBuffer = drawBuffer; + MakeCurrent_PrevReadBuffer = readBuffer; + + /* Now make current! */ + if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) { + ((__GLXcontext *) ctx)->currentDpy = dpy; + ((__GLXcontext *) ctx)->currentDrawable = draw; + ((__GLXcontext *) ctx)->currentReadable = read; + return True; + } + else { + return False; + } + } + else if (!ctx && !draw && !read) { + /* release current context w/out assigning new one. */ + XMesaMakeCurrent( NULL, NULL ); + MakeCurrent_PrevContext = 0; + MakeCurrent_PrevDrawable = 0; + MakeCurrent_PrevReadable = 0; + MakeCurrent_PrevDrawBuffer = 0; + MakeCurrent_PrevReadBuffer = 0; + return True; + } + else { + /* The args must either all be non-zero or all zero. + * This is an error. + */ + return False; + } +} + + +static Bool +Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) +{ + return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx ); +} + + +static GLXPixmap +Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) +{ + XMesaVisual v; + XMesaBuffer b; + + v = find_glx_visual( dpy, visinfo ); + if (!v) { + v = create_glx_visual( dpy, visinfo ); + if (!v) { + /* unusable visual */ + return 0; + } + } + + b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); + if (!b) { + return 0; + } + return b->drawable; +} + + +/*** GLX_MESA_pixmap_colormap ***/ + +static GLXPixmap +Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, + Pixmap pixmap, Colormap cmap ) +{ + XMesaVisual v; + XMesaBuffer b; + + v = find_glx_visual( dpy, visinfo ); + if (!v) { + v = create_glx_visual( dpy, visinfo ); + if (!v) { + /* unusable visual */ + return 0; + } + } + + b = XMesaCreatePixmapBuffer( v, pixmap, cmap ); + if (!b) { + return 0; + } + return b->drawable; +} + + +static void +Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, pixmap); + if (b) { + XMesaDestroyBuffer(b); + } + else if (_mesa_getenv("MESA_DEBUG")) { + _mesa_warning(NULL, "Mesa: glXDestroyGLXPixmap: invalid pixmap\n"); + } +} + + +static void +Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, + unsigned long mask ) +{ + struct fake_glx_context *fakeSrc = (struct fake_glx_context *) src; + struct fake_glx_context *fakeDst = (struct fake_glx_context *) dst; + XMesaContext xm_src = fakeSrc->xmesaContext; + XMesaContext xm_dst = fakeDst->xmesaContext; + (void) dpy; + if (MakeCurrent_PrevContext == src) { + _mesa_Flush(); + } + st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask ); +} + + +static Bool +Fake_glXQueryExtension( Display *dpy, int *errorb, int *event ) +{ + /* Mesa's GLX isn't really an X extension but we try to act like one. */ + (void) dpy; + (void) errorb; + (void) event; + return True; +} + + +extern void _kw_ungrab_all( Display *dpy ); +void _kw_ungrab_all( Display *dpy ) +{ + XUngrabPointer( dpy, CurrentTime ); + XUngrabKeyboard( dpy, CurrentTime ); +} + + +static void +Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) +{ + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + (void) dpy; + MakeCurrent_PrevContext = 0; + MakeCurrent_PrevDrawable = 0; + MakeCurrent_PrevReadable = 0; + MakeCurrent_PrevDrawBuffer = 0; + MakeCurrent_PrevReadBuffer = 0; + XMesaDestroyContext( glxCtx->xmesaContext ); + XMesaGarbageCollect(); + _mesa_free(glxCtx); +} + + +static Bool +Fake_glXIsDirect( Display *dpy, GLXContext ctx ) +{ + (void) dpy; + (void) ctx; + return False; +} + + + +static void +Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) +{ + XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); + + if (buffer) { + XMesaSwapBuffers(buffer); + } + else if (_mesa_getenv("MESA_DEBUG")) { + _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n", + (int) drawable); + } +} + + + +/*** GLX_MESA_copy_sub_buffer ***/ + +static void +Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, + int x, int y, int width, int height ) +{ + XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); + if (buffer) { + XMesaCopySubBuffer(buffer, x, y, width, height); + } + else if (_mesa_getenv("MESA_DEBUG")) { + _mesa_warning(NULL, "Mesa: glXCopySubBufferMESA: invalid drawable\n"); + } +} + + +static Bool +Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) +{ + (void) dpy; + /* Return GLX version, not Mesa version */ + assert(CLIENT_MAJOR_VERSION == SERVER_MAJOR_VERSION); + *maj = CLIENT_MAJOR_VERSION; + *min = MIN2( CLIENT_MINOR_VERSION, SERVER_MINOR_VERSION ); + return True; +} + + +/* + * Query the GLX attributes of the given XVisualInfo. + */ +static int +get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) +{ + ASSERT(xmvis); + switch(attrib) { + case GLX_USE_GL: + if (fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = (int) True; + return 0; + case GLX_BUFFER_SIZE: + *value = xmvis->visinfo->depth; + return 0; + case GLX_LEVEL: + *value = xmvis->mesa_visual.level; + return 0; + case GLX_RGBA: + if (fbconfig) + return GLX_BAD_ATTRIBUTE; + if (xmvis->mesa_visual.rgbMode) { + *value = True; + } + else { + *value = False; + } + return 0; + case GLX_DOUBLEBUFFER: + *value = (int) xmvis->mesa_visual.doubleBufferMode; + return 0; + case GLX_STEREO: + *value = (int) xmvis->mesa_visual.stereoMode; + return 0; + case GLX_AUX_BUFFERS: + *value = xmvis->mesa_visual.numAuxBuffers; + return 0; + case GLX_RED_SIZE: + *value = xmvis->mesa_visual.redBits; + return 0; + case GLX_GREEN_SIZE: + *value = xmvis->mesa_visual.greenBits; + return 0; + case GLX_BLUE_SIZE: + *value = xmvis->mesa_visual.blueBits; + return 0; + case GLX_ALPHA_SIZE: + *value = xmvis->mesa_visual.alphaBits; + return 0; + case GLX_DEPTH_SIZE: + *value = xmvis->mesa_visual.depthBits; + return 0; + case GLX_STENCIL_SIZE: + *value = xmvis->mesa_visual.stencilBits; + return 0; + case GLX_ACCUM_RED_SIZE: + *value = xmvis->mesa_visual.accumRedBits; + return 0; + case GLX_ACCUM_GREEN_SIZE: + *value = xmvis->mesa_visual.accumGreenBits; + return 0; + case GLX_ACCUM_BLUE_SIZE: + *value = xmvis->mesa_visual.accumBlueBits; + return 0; + case GLX_ACCUM_ALPHA_SIZE: + *value = xmvis->mesa_visual.accumAlphaBits; + return 0; + + /* + * GLX_EXT_visual_info extension + */ + case GLX_X_VISUAL_TYPE_EXT: + switch (xmvis->visinfo->CLASS) { + case StaticGray: *value = GLX_STATIC_GRAY_EXT; return 0; + case GrayScale: *value = GLX_GRAY_SCALE_EXT; return 0; + case StaticColor: *value = GLX_STATIC_GRAY_EXT; return 0; + case PseudoColor: *value = GLX_PSEUDO_COLOR_EXT; return 0; + case TrueColor: *value = GLX_TRUE_COLOR_EXT; return 0; + case DirectColor: *value = GLX_DIRECT_COLOR_EXT; return 0; + } + return 0; + case GLX_TRANSPARENT_TYPE_EXT: + if (xmvis->mesa_visual.level==0) { + /* normal planes */ + *value = GLX_NONE_EXT; + } + else if (xmvis->mesa_visual.level>0) { + /* overlay */ + if (xmvis->mesa_visual.rgbMode) { + *value = GLX_TRANSPARENT_RGB_EXT; + } + else { + *value = GLX_TRANSPARENT_INDEX_EXT; + } + } + else if (xmvis->mesa_visual.level<0) { + /* underlay */ + *value = GLX_NONE_EXT; + } + return 0; + case GLX_TRANSPARENT_INDEX_VALUE_EXT: + { + int pixel = transparent_pixel( xmvis ); + if (pixel>=0) { + *value = pixel; + } + /* else undefined */ + } + return 0; + case GLX_TRANSPARENT_RED_VALUE_EXT: + /* undefined */ + return 0; + case GLX_TRANSPARENT_GREEN_VALUE_EXT: + /* undefined */ + return 0; + case GLX_TRANSPARENT_BLUE_VALUE_EXT: + /* undefined */ + return 0; + case GLX_TRANSPARENT_ALPHA_VALUE_EXT: + /* undefined */ + return 0; + + /* + * GLX_EXT_visual_info extension + */ + case GLX_VISUAL_CAVEAT_EXT: + /* test for zero, just in case */ + if (xmvis->mesa_visual.visualRating > 0) + *value = xmvis->mesa_visual.visualRating; + else + *value = GLX_NONE_EXT; + return 0; + + /* + * GLX_ARB_multisample + */ + case GLX_SAMPLE_BUFFERS_ARB: + *value = 0; + return 0; + case GLX_SAMPLES_ARB: + *value = 0; + return 0; + + /* + * For FBConfigs: + */ + case GLX_SCREEN_EXT: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = xmvis->visinfo->screen; + break; + case GLX_DRAWABLE_TYPE: /*SGIX too */ + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; + break; + case GLX_RENDER_TYPE_SGIX: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + if (xmvis->mesa_visual.rgbMode) + *value = GLX_RGBA_BIT; + else + *value = GLX_COLOR_INDEX_BIT; + break; + case GLX_X_RENDERABLE_SGIX: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = True; /* XXX really? */ + break; + case GLX_FBCONFIG_ID_SGIX: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = xmvis->visinfo->visualid; + break; + case GLX_MAX_PBUFFER_WIDTH: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + /* XXX or MAX_WIDTH? */ + *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen); + break; + case GLX_MAX_PBUFFER_HEIGHT: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = DisplayHeight(xmvis->display, xmvis->visinfo->screen); + break; + case GLX_MAX_PBUFFER_PIXELS: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = DisplayWidth(xmvis->display, xmvis->visinfo->screen) * + DisplayHeight(xmvis->display, xmvis->visinfo->screen); + break; + case GLX_VISUAL_ID: + if (!fbconfig) + return GLX_BAD_ATTRIBUTE; + *value = xmvis->visinfo->visualid; + break; + +#ifdef GLX_EXT_texture_from_pixmap + case GLX_BIND_TO_TEXTURE_RGB_EXT: + *value = True; /*XXX*/ + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + /* XXX review */ + *value = xmvis->mesa_visual.alphaBits > 0 ? True : False; + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + *value = True; /*XXX*/ + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + *value = (GLX_TEXTURE_1D_BIT_EXT | + GLX_TEXTURE_2D_BIT_EXT | + GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/ + break; + case GLX_Y_INVERTED_EXT: + *value = True; /*XXX*/ + break; +#endif + + default: + return GLX_BAD_ATTRIBUTE; + } + return Success; +} + + +static int +Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, + int attrib, int *value ) +{ + XMesaVisual xmvis; + int k; + if (!dpy || !visinfo) + return GLX_BAD_ATTRIBUTE; + + xmvis = find_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* this visual wasn't obtained with glXChooseVisual */ + xmvis = create_glx_visual( dpy, visinfo ); + if (!xmvis) { + /* this visual can't be used for GL rendering */ + if (attrib==GLX_USE_GL) { + *value = (int) False; + return 0; + } + else { + return GLX_BAD_VISUAL; + } + } + } + + k = get_config(xmvis, attrib, value, GL_FALSE); + return k; +} + + +static void +Fake_glXWaitGL( void ) +{ + XMesaContext xmesa = XMesaGetCurrentContext(); + XMesaFlush( xmesa ); +} + + + +static void +Fake_glXWaitX( void ) +{ + XMesaContext xmesa = XMesaGetCurrentContext(); + XMesaFlush( xmesa ); +} + + +static const char * +get_extensions( void ) +{ +#ifdef FX + const char *fx = _mesa_getenv("MESA_GLX_FX"); + if (fx && fx[0] != 'd') { + return EXTENSIONS; + } +#endif + return EXTENSIONS + 23; /* skip "GLX_MESA_set_3dfx_mode" */ +} + + + +/* GLX 1.1 and later */ +static const char * +Fake_glXQueryExtensionsString( Display *dpy, int screen ) +{ + (void) dpy; + (void) screen; + return get_extensions(); +} + + + +/* GLX 1.1 and later */ +static const char * +Fake_glXQueryServerString( Display *dpy, int screen, int name ) +{ + static char version[1000]; + _mesa_sprintf(version, "%d.%d %s", + SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION); + + (void) dpy; + (void) screen; + + switch (name) { + case GLX_EXTENSIONS: + return get_extensions(); + case GLX_VENDOR: + return VENDOR; + case GLX_VERSION: + return version; + default: + return NULL; + } +} + + + +/* GLX 1.1 and later */ +static const char * +Fake_glXGetClientString( Display *dpy, int name ) +{ + static char version[1000]; + _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION, + CLIENT_MINOR_VERSION, MESA_GLX_VERSION); + + (void) dpy; + + switch (name) { + case GLX_EXTENSIONS: + return get_extensions(); + case GLX_VENDOR: + return VENDOR; + case GLX_VERSION: + return version; + default: + return NULL; + } +} + + + +/* + * GLX 1.3 and later + */ + + +static int +Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, + int attribute, int *value ) +{ + XMesaVisual v = (XMesaVisual) config; + (void) dpy; + (void) config; + + if (!dpy || !config || !value) + return -1; + + return get_config(v, attribute, value, GL_TRUE); +} + + +static GLXFBConfig * +Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) +{ + XVisualInfo *visuals, visTemplate; + const long visMask = VisualScreenMask; + int i; + + /* Get list of all X visuals */ + visTemplate.screen = screen; + visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements); + if (*nelements > 0) { + XMesaVisual *results; + results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual)); + if (!results) { + *nelements = 0; + return NULL; + } + for (i = 0; i < *nelements; i++) { + results[i] = create_glx_visual(dpy, visuals + i); + } + return (GLXFBConfig *) results; + } + return NULL; +} + + +static GLXFBConfig * +Fake_glXChooseFBConfig( Display *dpy, int screen, + const int *attribList, int *nitems ) +{ + XMesaVisual xmvis; + + if (!attribList || !attribList[0]) { + /* return list of all configs (per GLX_SGIX_fbconfig spec) */ + return Fake_glXGetFBConfigs(dpy, screen, nitems); + } + + xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); + if (xmvis) { + GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual)); + if (!config) { + *nitems = 0; + return NULL; + } + *nitems = 1; + config[0] = (GLXFBConfig) xmvis; + return (GLXFBConfig *) config; + } + else { + *nitems = 0; + return NULL; + } +} + + +static XVisualInfo * +Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) +{ + if (dpy && config) { + XMesaVisual xmvis = (XMesaVisual) config; +#if 0 + return xmvis->vishandle; +#else + /* create a new vishandle - the cached one may be stale */ + xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); + if (xmvis->vishandle) { + _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); + } + return xmvis->vishandle; +#endif + } + else { + return NULL; + } +} + + +static GLXWindow +Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, + const int *attribList ) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf; + if (!xmvis) + return 0; + + xmbuf = XMesaCreateWindowBuffer(xmvis, win); + if (!xmbuf) + return 0; + +#ifdef FX + /* XXX this will segfault if actually called */ + FXcreateContext(xmvis, win, NULL, xmbuf); +#endif + + (void) dpy; + (void) attribList; /* Ignored in GLX 1.3 */ + + return win; /* A hack for now */ +} + + +static void +Fake_glXDestroyWindow( Display *dpy, GLXWindow window ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable) window); + if (b) + XMesaDestroyBuffer(b); + /* don't destroy X window */ +} + + +/* XXX untested */ +static GLXPixmap +Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, + const int *attribList ) +{ + XMesaVisual v = (XMesaVisual) config; + XMesaBuffer b; + const int *attr; + int target = 0, format = 0, mipmap = 0; + int value; + + if (!dpy || !config || !pixmap) + return 0; + + for (attr = attribList; *attr; attr++) { + switch (*attr) { + case GLX_TEXTURE_FORMAT_EXT: + attr++; + switch (*attr) { + case GLX_TEXTURE_FORMAT_NONE_EXT: + case GLX_TEXTURE_FORMAT_RGB_EXT: + case GLX_TEXTURE_FORMAT_RGBA_EXT: + format = *attr; + break; + default: + /* error */ + return 0; + } + break; + case GLX_TEXTURE_TARGET_EXT: + attr++; + switch (*attr) { + case GLX_TEXTURE_1D_EXT: + case GLX_TEXTURE_2D_EXT: + case GLX_TEXTURE_RECTANGLE_EXT: + target = *attr; + break; + default: + /* error */ + return 0; + } + break; + case GLX_MIPMAP_TEXTURE_EXT: + attr++; + if (*attr) + mipmap = 1; + break; + default: + /* error */ + return 0; + } + } + + if (format == GLX_TEXTURE_FORMAT_RGB_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + if (mipmap) { + if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + if (target == GLX_TEXTURE_1D_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + else if (target == GLX_TEXTURE_2D_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + if (target == GLX_TEXTURE_RECTANGLE_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + + if (format || target || mipmap) { + /* texture from pixmap */ + b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap); + } + else { + b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); + } + if (!b) { + return 0; + } + + return pixmap; +} + + +static void +Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, (XMesaDrawable)pixmap); + if (b) + XMesaDestroyBuffer(b); + /* don't destroy X pixmap */ +} + + +static GLXPbuffer +Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, + const int *attribList ) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf; + const int *attrib; + int width = 0, height = 0; + GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; + + (void) dpy; + + for (attrib = attribList; *attrib; attrib++) { + switch (*attrib) { + case GLX_PBUFFER_WIDTH: + attrib++; + width = *attrib; + break; + case GLX_PBUFFER_HEIGHT: + attrib++; + height = *attrib; + break; + case GLX_PRESERVED_CONTENTS: + attrib++; + preserveContents = *attrib; /* ignored */ + break; + case GLX_LARGEST_PBUFFER: + attrib++; + useLargest = *attrib; /* ignored */ + break; + default: + return 0; + } + } + + /* not used at this time */ + (void) useLargest; + (void) preserveContents; + + if (width == 0 || height == 0) + return 0; + + xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); + /* A GLXPbuffer handle must be an X Drawable because that's what + * glXMakeCurrent takes. + */ + if (xmbuf) + return (GLXPbuffer) xmbuf->drawable; + else + return 0; +} + + +static void +Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, pbuf); + if (b) { + XMesaDestroyBuffer(b); + } +} + + +static void +Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, + unsigned int *value ) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw); + if (!xmbuf) + return; + + switch (attribute) { + case GLX_WIDTH: + *value = xmesa_buffer_width(xmbuf); + break; + case GLX_HEIGHT: + *value = xmesa_buffer_width(xmbuf); + break; + case GLX_PRESERVED_CONTENTS: + *value = True; + break; + case GLX_LARGEST_PBUFFER: + *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf); + break; + case GLX_FBCONFIG_ID: + *value = xmbuf->xm_visual->visinfo->visualid; + return; +#ifdef GLX_EXT_texture_from_pixmap + case GLX_TEXTURE_FORMAT_EXT: + *value = xmbuf->TextureFormat; + break; + case GLX_TEXTURE_TARGET_EXT: + *value = xmbuf->TextureTarget; + break; + case GLX_MIPMAP_TEXTURE_EXT: + *value = xmbuf->TextureMipmap; + break; +#endif + + default: + return; /* raise BadValue error */ + } +} + + +static GLXContext +Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, + int renderType, GLXContext shareList, Bool direct ) +{ + struct fake_glx_context *glxCtx; + struct fake_glx_context *shareCtx = (struct fake_glx_context *) shareList; + XMesaVisual xmvis = (XMesaVisual) config; + + if (!dpy || !config || + (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE)) + return 0; + + glxCtx = CALLOC_STRUCT(fake_glx_context); + if (!glxCtx) + return 0; + + /* deallocate unused windows/buffers */ + XMesaGarbageCollect(); + + glxCtx->xmesaContext = XMesaCreateContext(xmvis, + shareCtx ? shareCtx->xmesaContext : NULL); + if (!glxCtx->xmesaContext) { + _mesa_free(glxCtx); + return NULL; + } + + glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.currentDpy = dpy; + glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ + + assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + + return (GLXContext) glxCtx; +} + + +static int +Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ) +{ + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + XMesaContext xmctx = glxCtx->xmesaContext; + + (void) dpy; + (void) ctx; + + switch (attribute) { + case GLX_FBCONFIG_ID: + *value = xmctx->xm_visual->visinfo->visualid; + break; + case GLX_RENDER_TYPE: + if (xmctx->xm_visual->mesa_visual.rgbMode) + *value = GLX_RGBA_BIT; + else + *value = GLX_COLOR_INDEX_BIT; + break; + case GLX_SCREEN: + *value = 0; + return Success; + default: + return GLX_BAD_ATTRIBUTE; + } + return 0; +} + + +static void +Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) + xmbuf->selectedEvents = mask; +} + + +static void +Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, + unsigned long *mask ) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) + *mask = xmbuf->selectedEvents; + else + *mask = 0; +} + + + +/*** GLX_SGI_swap_control ***/ + +static int +Fake_glXSwapIntervalSGI(int interval) +{ + (void) interval; + return 0; +} + + + +/*** GLX_SGI_video_sync ***/ + +static unsigned int FrameCounter = 0; + +static int +Fake_glXGetVideoSyncSGI(unsigned int *count) +{ + /* this is a bogus implementation */ + *count = FrameCounter++; + return 0; +} + +static int +Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) +{ + if (divisor <= 0 || remainder < 0) + return GLX_BAD_VALUE; + /* this is a bogus implementation */ + FrameCounter++; + while (FrameCounter % divisor != remainder) + FrameCounter++; + *count = FrameCounter; + return 0; +} + + + +/*** GLX_SGI_make_current_read ***/ + +static Bool +Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +{ + return Fake_glXMakeContextCurrent( dpy, draw, read, ctx ); +} + +/* not used +static GLXDrawable +Fake_glXGetCurrentReadDrawableSGI(void) +{ + return 0; +} +*/ + + +/*** GLX_SGIX_video_source ***/ +#if defined(_VL_H) + +static GLXVideoSourceSGIX +Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) +{ + (void) dpy; + (void) screen; + (void) server; + (void) path; + (void) nodeClass; + (void) drainNode; + return 0; +} + +static void +Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) +{ + (void) dpy; + (void) src; +} + +#endif + + +/*** GLX_EXT_import_context ***/ + +static void +Fake_glXFreeContextEXT(Display *dpy, GLXContext context) +{ + (void) dpy; + (void) context; +} + +static GLXContextID +Fake_glXGetContextIDEXT(const GLXContext context) +{ + (void) context; + return 0; +} + +static GLXContext +Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID) +{ + (void) dpy; + (void) contextID; + return 0; +} + +static int +Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value) +{ + (void) dpy; + (void) context; + (void) attribute; + (void) value; + return 0; +} + + + +/*** GLX_SGIX_fbconfig ***/ + +static int +Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) +{ + return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value); +} + +static GLXFBConfigSGIX * +Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) +{ + return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements); +} + + +static GLXPixmap +Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); + return xmbuf->drawable; /* need to return an X ID */ +} + + +static GLXContext +Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) +{ + XMesaVisual xmvis = (XMesaVisual) config; + struct fake_glx_context *glxCtx; + struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list; + + glxCtx = CALLOC_STRUCT(fake_glx_context); + if (!glxCtx) + return 0; + + /* deallocate unused windows/buffers */ + XMesaGarbageCollect(); + + glxCtx->xmesaContext = XMesaCreateContext(xmvis, + shareCtx ? shareCtx->xmesaContext : NULL); + if (!glxCtx->xmesaContext) { + _mesa_free(glxCtx); + return NULL; + } + + glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.currentDpy = dpy; + glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ + + assert((void *) glxCtx == (void *) &(glxCtx->glxContext)); + + return (GLXContext) glxCtx; +} + + +static XVisualInfo * +Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) +{ + return Fake_glXGetVisualFromFBConfig(dpy, config); +} + + +static GLXFBConfigSGIX +Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) +{ + XMesaVisual xmvis = find_glx_visual(dpy, vis); + if (!xmvis) { + /* This visual wasn't found with glXChooseVisual() */ + xmvis = create_glx_visual(dpy, vis); + } + + return (GLXFBConfigSGIX) xmvis; +} + + + +/*** GLX_SGIX_pbuffer ***/ + +static GLXPbufferSGIX +Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, + unsigned int width, unsigned int height, + int *attribList) +{ + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf; + const int *attrib; + GLboolean useLargest = GL_FALSE, preserveContents = GL_FALSE; + + (void) dpy; + + for (attrib = attribList; attrib && *attrib; attrib++) { + switch (*attrib) { + case GLX_PRESERVED_CONTENTS_SGIX: + attrib++; + preserveContents = *attrib; /* ignored */ + break; + case GLX_LARGEST_PBUFFER_SGIX: + attrib++; + useLargest = *attrib; /* ignored */ + break; + default: + return 0; + } + } + + /* not used at this time */ + (void) useLargest; + (void) preserveContents; + + xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); + /* A GLXPbuffer handle must be an X Drawable because that's what + * glXMakeCurrent takes. + */ + return (GLXPbuffer) xmbuf->drawable; +} + + +static void +Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); + if (xmbuf) { + XMesaDestroyBuffer(xmbuf); + } +} + + +static int +Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) +{ + const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); + + if (!xmbuf) { + /* Generate GLXBadPbufferSGIX for bad pbuffer */ + return 0; + } + + switch (attribute) { + case GLX_PRESERVED_CONTENTS_SGIX: + *value = True; + break; + case GLX_LARGEST_PBUFFER_SGIX: + *value = xmesa_buffer_width(xmbuf) * xmesa_buffer_height(xmbuf); + break; + case GLX_WIDTH_SGIX: + *value = xmesa_buffer_width(xmbuf); + break; + case GLX_HEIGHT_SGIX: + *value = xmesa_buffer_height(xmbuf); + break; + case GLX_EVENT_MASK_SGIX: + *value = 0; /* XXX might be wrong */ + break; + default: + *value = 0; + } + return 0; +} + + +static void +Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) { + /* Note: we'll never generate clobber events */ + xmbuf->selectedEvents = mask; + } +} + + +static void +Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) +{ + XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); + if (xmbuf) { + *mask = xmbuf->selectedEvents; + } + else { + *mask = 0; + } +} + + + +/*** GLX_SGI_cushion ***/ + +static void +Fake_glXCushionSGI(Display *dpy, Window win, float cushion) +{ + (void) dpy; + (void) win; + (void) cushion; +} + + + +/*** GLX_SGIX_video_resize ***/ + +static int +Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) window; + return 0; +} + +static int +Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) x; + (void) y; + (void) w; + (void) h; + return 0; +} + +static int +Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) x; + (void) y; + (void) w; + (void) h; + return 0; +} + +static int +Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) dx; + (void) dy; + (void) dw; + (void) dh; + return 0; +} + +static int +Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) +{ + (void) dpy; + (void) screen; + (void) channel; + (void) synctype; + return 0; +} + + + +/*** GLX_SGIX_dmbuffer **/ + +#if defined(_DM_BUFFER_H_) +static Bool +Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) +{ + (void) dpy; + (void) pbuffer; + (void) params; + (void) dmbuffer; + return False; +} +#endif + + +/*** GLX_SGIX_swap_group ***/ + +static void +Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) +{ + (void) dpy; + (void) drawable; + (void) member; +} + + + +/*** GLX_SGIX_swap_barrier ***/ + +static void +Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) +{ + (void) dpy; + (void) drawable; + (void) barrier; +} + +static Bool +Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) +{ + (void) dpy; + (void) screen; + (void) max; + return False; +} + + + +/*** GLX_SUN_get_transparent_index ***/ + +static Status +Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) +{ + (void) dpy; + (void) overlay; + (void) underlay; + (void) pTransparent; + return 0; +} + + + +/*** GLX_MESA_release_buffers ***/ + +/* + * Release the depth, stencil, accum buffers attached to a GLXDrawable + * (a window or pixmap) prior to destroying the GLXDrawable. + */ +static Bool +Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, d); + if (b) { + XMesaDestroyBuffer(b); + return True; + } + return False; +} + + + +/*** GLX_MESA_set_3dfx_mode ***/ + +static Bool +Fake_glXSet3DfxModeMESA( int mode ) +{ + return XMesaSetFXmode( mode ); +} + + + +/*** GLX_NV_vertex_array range ***/ +static void * +Fake_glXAllocateMemoryNV( GLsizei size, + GLfloat readFrequency, + GLfloat writeFrequency, + GLfloat priority ) +{ + (void) size; + (void) readFrequency; + (void) writeFrequency; + (void) priority; + return NULL; +} + + +static void +Fake_glXFreeMemoryNV( GLvoid *pointer ) +{ + (void) pointer; +} + + +/*** GLX_MESA_agp_offset ***/ + +static GLuint +Fake_glXGetAGPOffsetMESA( const GLvoid *pointer ) +{ + (void) pointer; + return ~0; +} + + +/*** GLX_EXT_texture_from_pixmap ***/ + +static void +Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, + const int *attrib_list) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, drawable); + if (b) + XMesaBindTexImage(dpy, b, buffer, attrib_list); +} + +static void +Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, drawable); + if (b) + XMesaReleaseTexImage(dpy, b, buffer); +} + + +/* silence warning */ +extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); + + +/** + * Create a new GLX API dispatch table with its function pointers + * initialized to point to Mesa's "fake" GLX API functions. + * Note: there's a similar function (_real_GetGLXDispatchTable) that + * returns a new dispatch table with all pointers initalized to point + * to "real" GLX functions (which understand GLX wire protocol, etc). + */ +struct _glxapi_table * +_mesa_GetGLXDispatchTable(void) +{ + static struct _glxapi_table glx; + + /* be sure our dispatch table size <= libGL's table */ + { + GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); + (void) size; + assert(_glxapi_get_dispatch_table_size() >= size); + } + + /* initialize the whole table to no-ops */ + _glxapi_set_no_op_table(&glx); + + /* now initialize the table with the functions I implement */ + glx.ChooseVisual = Fake_glXChooseVisual; + glx.CopyContext = Fake_glXCopyContext; + glx.CreateContext = Fake_glXCreateContext; + glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap; + glx.DestroyContext = Fake_glXDestroyContext; + glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap; + glx.GetConfig = Fake_glXGetConfig; + /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/ + /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/ + glx.IsDirect = Fake_glXIsDirect; + glx.MakeCurrent = Fake_glXMakeCurrent; + glx.QueryExtension = Fake_glXQueryExtension; + glx.QueryVersion = Fake_glXQueryVersion; + glx.SwapBuffers = Fake_glXSwapBuffers; + glx.UseXFont = Fake_glXUseXFont; + glx.WaitGL = Fake_glXWaitGL; + glx.WaitX = Fake_glXWaitX; + + /*** GLX_VERSION_1_1 ***/ + glx.GetClientString = Fake_glXGetClientString; + glx.QueryExtensionsString = Fake_glXQueryExtensionsString; + glx.QueryServerString = Fake_glXQueryServerString; + + /*** GLX_VERSION_1_2 ***/ + /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/ + + /*** GLX_VERSION_1_3 ***/ + glx.ChooseFBConfig = Fake_glXChooseFBConfig; + glx.CreateNewContext = Fake_glXCreateNewContext; + glx.CreatePbuffer = Fake_glXCreatePbuffer; + glx.CreatePixmap = Fake_glXCreatePixmap; + glx.CreateWindow = Fake_glXCreateWindow; + glx.DestroyPbuffer = Fake_glXDestroyPbuffer; + glx.DestroyPixmap = Fake_glXDestroyPixmap; + glx.DestroyWindow = Fake_glXDestroyWindow; + /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/ + glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib; + glx.GetFBConfigs = Fake_glXGetFBConfigs; + glx.GetSelectedEvent = Fake_glXGetSelectedEvent; + glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig; + glx.MakeContextCurrent = Fake_glXMakeContextCurrent; + glx.QueryContext = Fake_glXQueryContext; + glx.QueryDrawable = Fake_glXQueryDrawable; + glx.SelectEvent = Fake_glXSelectEvent; + + /*** GLX_SGI_swap_control ***/ + glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI; + + /*** GLX_SGI_video_sync ***/ + glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI; + glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI; + + /*** GLX_SGI_make_current_read ***/ + glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI; + /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/ + +/*** GLX_SGIX_video_source ***/ +#if defined(_VL_H) + glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX; + glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX; +#endif + + /*** GLX_EXT_import_context ***/ + glx.FreeContextEXT = Fake_glXFreeContextEXT; + glx.GetContextIDEXT = Fake_glXGetContextIDEXT; + /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/ + glx.ImportContextEXT = Fake_glXImportContextEXT; + glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT; + + /*** GLX_SGIX_fbconfig ***/ + glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX; + glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX; + glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX; + glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX; + glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX; + glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX; + + /*** GLX_SGIX_pbuffer ***/ + glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX; + glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX; + glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX; + glx.SelectEventSGIX = Fake_glXSelectEventSGIX; + glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX; + + /*** GLX_SGI_cushion ***/ + glx.CushionSGI = Fake_glXCushionSGI; + + /*** GLX_SGIX_video_resize ***/ + glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX; + glx.ChannelRectSGIX = Fake_glXChannelRectSGIX; + glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX; + glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX; + glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX; + + /*** GLX_SGIX_dmbuffer **/ +#if defined(_DM_BUFFER_H_) + glx.AssociateDMPbufferSGIX = NULL; +#endif + + /*** GLX_SGIX_swap_group ***/ + glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX; + + /*** GLX_SGIX_swap_barrier ***/ + glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX; + glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX; + + /*** GLX_SUN_get_transparent_index ***/ + glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN; + + /*** GLX_MESA_copy_sub_buffer ***/ + glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA; + + /*** GLX_MESA_release_buffers ***/ + glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA; + + /*** GLX_MESA_pixmap_colormap ***/ + glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA; + + /*** GLX_MESA_set_3dfx_mode ***/ + glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA; + + /*** GLX_NV_vertex_array_range ***/ + glx.AllocateMemoryNV = Fake_glXAllocateMemoryNV; + glx.FreeMemoryNV = Fake_glXFreeMemoryNV; + + /*** GLX_MESA_agp_offset ***/ + glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA; + + /*** GLX_EXT_texture_from_pixmap ***/ + glx.BindTexImageEXT = Fake_glXBindTexImageEXT; + glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT; + + return &glx; +} diff --git a/src/gallium/winsys/xlib/glxapi.c b/src/gallium/winsys/xlib/glxapi.c new file mode 100644 index 0000000000..c2ccce6f52 --- /dev/null +++ b/src/gallium/winsys/xlib/glxapi.c @@ -0,0 +1,1408 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* + * This is the GLX API dispatcher. Calls to the glX* functions are + * either routed to the real GLX encoders or to Mesa's pseudo-GLX functions. + * See the glxapi.h file for more details. + */ + + +#include +#include +#include +#include +#include "main/glheader.h" +#include "glapi/glapi.h" +#include "glxapi.h" + + +extern struct _glxapi_table *_real_GetGLXDispatchTable(void); +extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); + + +struct display_dispatch { + Display *Dpy; + struct _glxapi_table *Table; + struct display_dispatch *Next; +}; + +static struct display_dispatch *DispatchList = NULL; + + +/* Display -> Dispatch caching */ +static Display *prevDisplay = NULL; +static struct _glxapi_table *prevTable = NULL; + + +static struct _glxapi_table * +get_dispatch(Display *dpy) +{ + if (!dpy) + return NULL; + + /* search list of display/dispatch pairs for this display */ + { + const struct display_dispatch *d = DispatchList; + while (d) { + if (d->Dpy == dpy) { + prevDisplay = dpy; + prevTable = d->Table; + return d->Table; /* done! */ + } + d = d->Next; + } + } + + /* A new display, determine if we should use real GLX + * or Mesa's pseudo-GLX. + */ + { + struct _glxapi_table *t = _mesa_GetGLXDispatchTable(); + + if (t) { + struct display_dispatch *d; + d = (struct display_dispatch *) malloc(sizeof(struct display_dispatch)); + if (d) { + d->Dpy = dpy; + d->Table = t; + /* insert at head of list */ + d->Next = DispatchList; + DispatchList = d; + /* update cache */ + prevDisplay = dpy; + prevTable = t; + return t; + } + } + } + + /* If we get here that means we can't use real GLX on this display + * and the Mesa pseudo-GLX software renderer wasn't compiled in. + * Or, we ran out of memory! + */ + return NULL; +} + + +/* Don't use the GET_DISPATCH defined in glthread.h */ +#undef GET_DISPATCH + +#define GET_DISPATCH(DPY, TABLE) \ + if (DPY == prevDisplay) { \ + TABLE = prevTable; \ + } \ + else if (!DPY) { \ + TABLE = NULL; \ + } \ + else { \ + TABLE = get_dispatch(DPY); \ + } + + + + +/** + * GLX API current context. + */ +#if defined(GLX_USE_TLS) +PUBLIC __thread void * CurrentContext + __attribute__((tls_model("initial-exec"))); +#elif defined(THREADS) +static _glthread_TSD ContextTSD; /**< Per-thread context pointer */ +#else +static GLXContext CurrentContext = 0; +#endif + + +static void +SetCurrentContext(GLXContext c) +{ +#if defined(GLX_USE_TLS) + CurrentContext = c; +#elif defined(THREADS) + _glthread_SetTSD(&ContextTSD, c); +#else + CurrentContext = c; +#endif +} + + +/* + * GLX API entrypoints + */ + +/*** GLX_VERSION_1_0 ***/ + +XVisualInfo PUBLIC * +glXChooseVisual(Display *dpy, int screen, int *list) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->ChooseVisual)(dpy, screen, list); +} + + +void PUBLIC +glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->CopyContext)(dpy, src, dst, mask); +} + + +GLXContext PUBLIC +glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateContext)(dpy, visinfo, shareList, direct); +} + + +GLXPixmap PUBLIC +glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPixmap)(dpy, visinfo, pixmap); +} + + +void PUBLIC +glXDestroyContext(Display *dpy, GLXContext ctx) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + if (glXGetCurrentContext() == ctx) + SetCurrentContext(NULL); + (t->DestroyContext)(dpy, ctx); +} + + +void PUBLIC +glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyGLXPixmap)(dpy, pixmap); +} + + +int PUBLIC +glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return GLX_NO_EXTENSION; + return (t->GetConfig)(dpy, visinfo, attrib, value); +} + + +GLXContext PUBLIC +glXGetCurrentContext(void) +{ +#if defined(GLX_USE_TLS) + return CurrentContext; +#elif defined(THREADS) + return (GLXContext) _glthread_GetTSD(&ContextTSD); +#else + return CurrentContext; +#endif +} + + +GLXDrawable PUBLIC +glXGetCurrentDrawable(void) +{ + __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); + return gc ? gc->currentDrawable : 0; +} + + +Bool PUBLIC +glXIsDirect(Display *dpy, GLXContext ctx) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->IsDirect)(dpy, ctx); +} + + +Bool PUBLIC +glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) +{ + Bool b; + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) { + return False; + } + b = (*t->MakeCurrent)(dpy, drawable, ctx); + if (b) { + SetCurrentContext(ctx); + } + return b; +} + + +Bool PUBLIC +glXQueryExtension(Display *dpy, int *errorb, int *event) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->QueryExtension)(dpy, errorb, event); +} + + +Bool PUBLIC +glXQueryVersion(Display *dpy, int *maj, int *min) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->QueryVersion)(dpy, maj, min); +} + + +void PUBLIC +glXSwapBuffers(Display *dpy, GLXDrawable drawable) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->SwapBuffers)(dpy, drawable); +} + + +void PUBLIC +glXUseXFont(Font font, int first, int count, int listBase) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->UseXFont)(font, first, count, listBase); +} + + +void PUBLIC +glXWaitGL(void) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->WaitGL)(); +} + + +void PUBLIC +glXWaitX(void) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->WaitX)(); +} + + + +/*** GLX_VERSION_1_1 ***/ + +const char PUBLIC * +glXGetClientString(Display *dpy, int name) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->GetClientString)(dpy, name); +} + + +const char PUBLIC * +glXQueryExtensionsString(Display *dpy, int screen) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->QueryExtensionsString)(dpy, screen); +} + + +const char PUBLIC * +glXQueryServerString(Display *dpy, int screen, int name) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->QueryServerString)(dpy, screen, name); +} + + +/*** GLX_VERSION_1_2 ***/ + +Display PUBLIC * +glXGetCurrentDisplay(void) +{ + /* Same code as in libGL's glxext.c */ + __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); + if (NULL == gc) return NULL; + return gc->currentDpy; +} + + + +/*** GLX_VERSION_1_3 ***/ + +GLXFBConfig PUBLIC * +glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChooseFBConfig)(dpy, screen, attribList, nitems); +} + + +GLXContext PUBLIC +glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateNewContext)(dpy, config, renderType, shareList, direct); +} + + +GLXPbuffer PUBLIC +glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreatePbuffer)(dpy, config, attribList); +} + + +GLXPixmap PUBLIC +glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreatePixmap)(dpy, config, pixmap, attribList); +} + + +GLXWindow PUBLIC +glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateWindow)(dpy, config, win, attribList); +} + + +void PUBLIC +glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyPbuffer)(dpy, pbuf); +} + + +void PUBLIC +glXDestroyPixmap(Display *dpy, GLXPixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyPixmap)(dpy, pixmap); +} + + +void PUBLIC +glXDestroyWindow(Display *dpy, GLXWindow window) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyWindow)(dpy, window); +} + + +GLXDrawable PUBLIC +glXGetCurrentReadDrawable(void) +{ + __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext(); + return gc ? gc->currentReadable : 0; +} + + +int PUBLIC +glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return GLX_NO_EXTENSION; + return (t->GetFBConfigAttrib)(dpy, config, attribute, value); +} + + +GLXFBConfig PUBLIC * +glXGetFBConfigs(Display *dpy, int screen, int *nelements) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetFBConfigs)(dpy, screen, nelements); +} + +void PUBLIC +glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->GetSelectedEvent)(dpy, drawable, mask); +} + + +XVisualInfo PUBLIC * +glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->GetVisualFromFBConfig)(dpy, config); +} + + +Bool PUBLIC +glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +{ + Bool b; + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + b = (t->MakeContextCurrent)(dpy, draw, read, ctx); + if (b) { + SetCurrentContext(ctx); + } + return b; +} + + +int PUBLIC +glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + assert(t); + if (!t) + return 0; /* XXX correct? */ + return (t->QueryContext)(dpy, ctx, attribute, value); +} + + +void PUBLIC +glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->QueryDrawable)(dpy, draw, attribute, value); +} + + +void PUBLIC +glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->SelectEvent)(dpy, drawable, mask); +} + + + +/*** GLX_SGI_swap_control ***/ + +int PUBLIC +glXSwapIntervalSGI(int interval) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->SwapIntervalSGI)(interval); +} + + + +/*** GLX_SGI_video_sync ***/ + +int PUBLIC +glXGetVideoSyncSGI(unsigned int *count) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t || !glXGetCurrentContext()) + return GLX_BAD_CONTEXT; + return (t->GetVideoSyncSGI)(count); +} + +int PUBLIC +glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t || !glXGetCurrentContext()) + return GLX_BAD_CONTEXT; + return (t->WaitVideoSyncSGI)(divisor, remainder, count); +} + + + +/*** GLX_SGI_make_current_read ***/ + +Bool PUBLIC +glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->MakeCurrentReadSGI)(dpy, draw, read, ctx); +} + +GLXDrawable PUBLIC +glXGetCurrentReadDrawableSGI(void) +{ + return glXGetCurrentReadDrawable(); +} + + +#if defined(_VL_H) + +GLXVideoSourceSGIX PUBLIC +glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXVideoSourceSGIX)(dpy, screen, server, path, nodeClass, drainNode); +} + +void PUBLIC +glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->DestroyGLXVideoSourceSGIX)(dpy, src); +} + +#endif + + +/*** GLX_EXT_import_context ***/ + +void PUBLIC +glXFreeContextEXT(Display *dpy, GLXContext context) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->FreeContextEXT)(dpy, context); +} + +GLXContextID PUBLIC +glXGetContextIDEXT(const GLXContext context) +{ + return ((__GLXcontext *) context)->xid; +} + +Display PUBLIC * +glXGetCurrentDisplayEXT(void) +{ + return glXGetCurrentDisplay(); +} + +GLXContext PUBLIC +glXImportContextEXT(Display *dpy, GLXContextID contextID) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ImportContextEXT)(dpy, contextID); +} + +int PUBLIC +glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; /* XXX ok? */ + return (t->QueryContextInfoEXT)(dpy, context, attribute, value); +} + + + +/*** GLX_SGIX_fbconfig ***/ + +int PUBLIC +glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetFBConfigAttribSGIX)(dpy, config, attribute, value); +} + +GLXFBConfigSGIX PUBLIC * +glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChooseFBConfigSGIX)(dpy, screen, attrib_list, nelements); +} + +GLXPixmap PUBLIC +glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPixmapWithConfigSGIX)(dpy, config, pixmap); +} + +GLXContext PUBLIC +glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateContextWithConfigSGIX)(dpy, config, render_type, share_list, direct); +} + +XVisualInfo PUBLIC * +glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetVisualFromFBConfigSGIX)(dpy, config); +} + +GLXFBConfigSGIX PUBLIC +glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->GetFBConfigFromVisualSGIX)(dpy, vis); +} + + + +/*** GLX_SGIX_pbuffer ***/ + +GLXPbufferSGIX PUBLIC +glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPbufferSGIX)(dpy, config, width, height, attrib_list); +} + +void PUBLIC +glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->DestroyGLXPbufferSGIX)(dpy, pbuf); +} + +int PUBLIC +glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->QueryGLXPbufferSGIX)(dpy, pbuf, attribute, value); +} + +void PUBLIC +glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->SelectEventSGIX)(dpy, drawable, mask); +} + +void PUBLIC +glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->GetSelectedEventSGIX)(dpy, drawable, mask); +} + + + +/*** GLX_SGI_cushion ***/ + +void PUBLIC +glXCushionSGI(Display *dpy, Window win, float cushion) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->CushionSGI)(dpy, win, cushion); +} + + + +/*** GLX_SGIX_video_resize ***/ + +int PUBLIC +glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->BindChannelToWindowSGIX)(dpy, screen, channel, window); +} + +int PUBLIC +glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChannelRectSGIX)(dpy, screen, channel, x, y, w, h); +} + +int PUBLIC +glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->QueryChannelRectSGIX)(dpy, screen, channel, x, y, w, h); +} + +int PUBLIC +glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->QueryChannelDeltasSGIX)(dpy, screen, channel, dx, dy, dw, dh); +} + +int PUBLIC +glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->ChannelRectSyncSGIX)(dpy, screen, channel, synctype); +} + + + +#if defined(_DM_BUFFER_H_) + +Bool PUBLIC +glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->AssociateDMPbufferSGIX)(dpy, pbuffer, params, dmbuffer); +} + +#endif + + +/*** GLX_SGIX_swap_group ***/ + +void PUBLIC +glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (*t->JoinSwapGroupSGIX)(dpy, drawable, member); +} + + +/*** GLX_SGIX_swap_barrier ***/ + +void PUBLIC +glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (*t->BindSwapBarrierSGIX)(dpy, drawable, barrier); +} + +Bool PUBLIC +glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (*t->QueryMaxSwapBarriersSGIX)(dpy, screen, max); +} + + + +/*** GLX_SUN_get_transparent_index ***/ + +Status PUBLIC +glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (*t->GetTransparentIndexSUN)(dpy, overlay, underlay, pTransparent); +} + + + +/*** GLX_MESA_copy_sub_buffer ***/ + +void PUBLIC +glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height); +} + + + +/*** GLX_MESA_release_buffers ***/ + +Bool PUBLIC +glXReleaseBuffersMESA(Display *dpy, Window w) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->ReleaseBuffersMESA)(dpy, w); +} + + + +/*** GLX_MESA_pixmap_colormap ***/ + +GLXPixmap PUBLIC +glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (!t) + return 0; + return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap); +} + + + +/*** GLX_MESA_set_3dfx_mode ***/ + +Bool PUBLIC +glXSet3DfxModeMESA(int mode) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return False; + return (t->Set3DfxModeMESA)(mode); +} + + + +/*** GLX_NV_vertex_array_range ***/ + +void PUBLIC * +glXAllocateMemoryNV( GLsizei size, + GLfloat readFrequency, + GLfloat writeFrequency, + GLfloat priority ) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return NULL; + return (t->AllocateMemoryNV)(size, readFrequency, writeFrequency, priority); +} + + +void PUBLIC +glXFreeMemoryNV( GLvoid *pointer ) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return; + (t->FreeMemoryNV)(pointer); +} + + + + +/*** GLX_MESA_agp_offset */ + +GLuint PUBLIC +glXGetAGPOffsetMESA( const GLvoid *pointer ) +{ + struct _glxapi_table *t; + Display *dpy = glXGetCurrentDisplay(); + GET_DISPATCH(dpy, t); + if (!t) + return ~0; + return (t->GetAGPOffsetMESA)(pointer); +} + + +/*** GLX_MESA_allocate_memory */ + +void * +glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, + float readfreq, float writefreq, float priority) +{ + /* dummy */ + return NULL; +} + +void +glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer) +{ + /* dummy */ +} + + +GLuint +glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer) +{ + /* dummy */ + return 0; +} + + +/*** GLX_EXT_texture_from_pixmap */ + +void +glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, + const int *attrib_list) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (t) + t->BindTexImageEXT(dpy, drawable, buffer, attrib_list); +} + +void +glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (t) + t->ReleaseTexImageEXT(dpy, drawable, buffer); +} + + +/**********************************************************************/ +/* GLX API management functions */ +/**********************************************************************/ + + +const char * +_glxapi_get_version(void) +{ + return "1.3"; +} + + +/* + * Return array of extension strings. + */ +const char ** +_glxapi_get_extensions(void) +{ + static const char *extensions[] = { +#ifdef GLX_EXT_import_context + "GLX_EXT_import_context", +#endif +#ifdef GLX_SGI_video_sync + "GLX_SGI_video_sync", +#endif +#ifdef GLX_MESA_copy_sub_buffer + "GLX_MESA_copy_sub_buffer", +#endif +#ifdef GLX_MESA_release_buffers + "GLX_MESA_release_buffers", +#endif +#ifdef GLX_MESA_pixmap_colormap + "GLX_MESA_pixmap_colormap", +#endif +#ifdef GLX_MESA_set_3dfx_mode + "GLX_MESA_set_3dfx_mode", +#endif +#ifdef GLX_SGIX_fbconfig + "GLX_SGIX_fbconfig", +#endif +#ifdef GLX_SGIX_pbuffer + "GLX_SGIX_pbuffer", +#endif +#ifdef GLX_EXT_texture_from_pixmap + "GLX_EXT_texture_from_pixmap", +#endif + NULL + }; + return extensions; +} + + +/* + * Return size of the GLX dispatch table, in entries, not bytes. + */ +GLuint +_glxapi_get_dispatch_table_size(void) +{ + return sizeof(struct _glxapi_table) / sizeof(void *); +} + + +static int +generic_no_op_func(void) +{ + return 0; +} + + +/* + * Initialize all functions in given dispatch table to be no-ops + */ +void +_glxapi_set_no_op_table(struct _glxapi_table *t) +{ + typedef int (*nop_func)(void); + nop_func *dispatch = (nop_func *) t; + GLuint n = _glxapi_get_dispatch_table_size(); + GLuint i; + for (i = 0; i < n; i++) { + dispatch[i] = generic_no_op_func; + } +} + + +struct name_address_pair { + const char *Name; + __GLXextFuncPtr Address; +}; + +static struct name_address_pair GLX_functions[] = { + /*** GLX_VERSION_1_0 ***/ + { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual }, + { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext }, + { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext }, + { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap }, + { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext }, + { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap }, + { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig }, + { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext }, + { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable }, + { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect }, + { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent }, + { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension }, + { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion }, + { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers }, + { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont }, + { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL }, + { "glXWaitX", (__GLXextFuncPtr) glXWaitX }, + + /*** GLX_VERSION_1_1 ***/ + { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString }, + { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString }, + { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString }, + + /*** GLX_VERSION_1_2 ***/ + { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay }, + + /*** GLX_VERSION_1_3 ***/ + { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig }, + { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext }, + { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer }, + { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap }, + { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow }, + { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer }, + { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap }, + { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow }, + { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable }, + { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib }, + { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs }, + { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent }, + { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig }, + { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent }, + { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext }, + { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable }, + { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent }, + + /*** GLX_VERSION_1_4 ***/ + { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress }, + + /*** GLX_SGI_swap_control ***/ + { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI }, + + /*** GLX_SGI_video_sync ***/ + { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI }, + { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI }, + + /*** GLX_SGI_make_current_read ***/ + { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI }, + { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI }, + + /*** GLX_SGIX_video_source ***/ +#if defined(_VL_H) + { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX }, + { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX }, +#endif + + /*** GLX_EXT_import_context ***/ + { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT }, + { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT }, + { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT }, + { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT }, + { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT }, + + /*** GLX_SGIX_fbconfig ***/ + { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX }, + { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX }, + { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX }, + { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX }, + { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX }, + { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX }, + + /*** GLX_SGIX_pbuffer ***/ + { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX }, + { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX }, + { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX }, + { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX }, + { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX }, + + /*** GLX_SGI_cushion ***/ + { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI }, + + /*** GLX_SGIX_video_resize ***/ + { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX }, + { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX }, + { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX }, + { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX }, + { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX }, + + /*** GLX_SGIX_dmbuffer **/ +#if defined(_DM_BUFFER_H_) + { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX }, +#endif + + /*** GLX_SGIX_swap_group ***/ + { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX }, + + /*** GLX_SGIX_swap_barrier ***/ + { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX }, + { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX }, + + /*** GLX_SUN_get_transparent_index ***/ + { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN }, + + /*** GLX_MESA_copy_sub_buffer ***/ + { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA }, + + /*** GLX_MESA_pixmap_colormap ***/ + { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA }, + + /*** GLX_MESA_release_buffers ***/ + { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA }, + + /*** GLX_MESA_set_3dfx_mode ***/ + { "glXSet3DfxModeMESA", (__GLXextFuncPtr) glXSet3DfxModeMESA }, + + /*** GLX_ARB_get_proc_address ***/ + { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB }, + + /*** GLX_NV_vertex_array_range ***/ + { "glXAllocateMemoryNV", (__GLXextFuncPtr) glXAllocateMemoryNV }, + { "glXFreeMemoryNV", (__GLXextFuncPtr) glXFreeMemoryNV }, + + /*** GLX_MESA_agp_offset ***/ + { "glXGetAGPOffsetMESA", (__GLXextFuncPtr) glXGetAGPOffsetMESA }, + + /*** GLX_MESA_allocate_memory ***/ + { "glXAllocateMemoryMESA", (__GLXextFuncPtr) glXAllocateMemoryMESA }, + { "glXFreeMemoryMESA", (__GLXextFuncPtr) glXFreeMemoryMESA }, + { "glXGetMemoryOffsetMESA", (__GLXextFuncPtr) glXGetMemoryOffsetMESA }, + + /*** GLX_EXT_texture_from_pixmap ***/ + { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT }, + { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT }, + + { NULL, NULL } /* end of list */ +}; + + + +/* + * Return address of named glX function, or NULL if not found. + */ +__GLXextFuncPtr +_glxapi_get_proc_address(const char *funcName) +{ + GLuint i; + for (i = 0; GLX_functions[i].Name; i++) { + if (strcmp(GLX_functions[i].Name, funcName) == 0) + return GLX_functions[i].Address; + } + return NULL; +} + + + +/* + * This function does not get dispatched through the dispatch table + * since it's really a "meta" function. + */ +__GLXextFuncPtr +glXGetProcAddressARB(const GLubyte *procName) +{ + __GLXextFuncPtr f; + + f = _glxapi_get_proc_address((const char *) procName); + if (f) { + return f; + } + + f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName); + return f; +} + + +/* GLX 1.4 */ +void (*glXGetProcAddress(const GLubyte *procName))() +{ + return glXGetProcAddressARB(procName); +} diff --git a/src/gallium/winsys/xlib/glxapi.h b/src/gallium/winsys/xlib/glxapi.h new file mode 100644 index 0000000000..37de81e55a --- /dev/null +++ b/src/gallium/winsys/xlib/glxapi.h @@ -0,0 +1,228 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef _glxapi_h_ +#define _glxapi_h_ + + +#define GLX_GLXEXT_PROTOTYPES +#include "GL/glx.h" + + +/* The GLX API dispatcher (i.e. this code) is being built into stand-alone + * Mesa. We don't know anything about XFree86 or real GLX so we define a + * minimal __GLXContextRec here so some of the functions in this file can + * work properly. + */ +typedef struct __GLXcontextRec { + Display *currentDpy; + GLboolean isDirect; + GLXDrawable currentDrawable; + GLXDrawable currentReadable; + XID xid; +} __GLXcontext; + + +/* + * Almost all the GLX API functions get routed through this dispatch table. + * The exceptions are the glXGetCurrentXXX() functions. + * + * This dispatch table allows multiple GLX client-side modules to coexist. + * Specifically, a real GLX library (like SGI's or the Utah GLX) and Mesa's + * pseudo-GLX can be present at the same time. The former being used on + * GLX-enabled X servers and the later on non-GLX X servers. + * + * Red Hat has been using this since Red Hat Linux 7.0 (I think). + * This'll be a standard feature in XFree86 4.3. It basically allows one + * libGL to do both DRI-rendering and "fake GLX" rendering to X displays + * that lack the GLX extension. + */ +struct _glxapi_table { + /*** GLX_VERSION_1_0 ***/ + XVisualInfo *(*ChooseVisual)(Display *dpy, int screen, int *list); + void (*CopyContext)(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask); + GLXContext (*CreateContext)(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct); + GLXPixmap (*CreateGLXPixmap)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap); + void (*DestroyContext)(Display *dpy, GLXContext ctx); + void (*DestroyGLXPixmap)(Display *dpy, GLXPixmap pixmap); + int (*GetConfig)(Display *dpy, XVisualInfo *visinfo, int attrib, int *value); + /*GLXContext (*GetCurrentContext)(void);*/ + /*GLXDrawable (*GetCurrentDrawable)(void);*/ + Bool (*IsDirect)(Display *dpy, GLXContext ctx); + Bool (*MakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx); + Bool (*QueryExtension)(Display *dpy, int *errorb, int *event); + Bool (*QueryVersion)(Display *dpy, int *maj, int *min); + void (*SwapBuffers)(Display *dpy, GLXDrawable drawable); + void (*UseXFont)(Font font, int first, int count, int listBase); + void (*WaitGL)(void); + void (*WaitX)(void); + + /*** GLX_VERSION_1_1 ***/ + const char *(*GetClientString)(Display *dpy, int name); + const char *(*QueryExtensionsString)(Display *dpy, int screen); + const char *(*QueryServerString)(Display *dpy, int screen, int name); + + /*** GLX_VERSION_1_2 ***/ + /*Display *(*GetCurrentDisplay)(void);*/ + + /*** GLX_VERSION_1_3 ***/ + GLXFBConfig *(*ChooseFBConfig)(Display *dpy, int screen, const int *attribList, int *nitems); + GLXContext (*CreateNewContext)(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct); + GLXPbuffer (*CreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attribList); + GLXPixmap (*CreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList); + GLXWindow (*CreateWindow)(Display *dpy, GLXFBConfig config, Window win, const int *attribList); + void (*DestroyPbuffer)(Display *dpy, GLXPbuffer pbuf); + void (*DestroyPixmap)(Display *dpy, GLXPixmap pixmap); + void (*DestroyWindow)(Display *dpy, GLXWindow window); + /*GLXDrawable (*GetCurrentReadDrawable)(void);*/ + int (*GetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value); + GLXFBConfig *(*GetFBConfigs)(Display *dpy, int screen, int *nelements); + void (*GetSelectedEvent)(Display *dpy, GLXDrawable drawable, unsigned long *mask); + XVisualInfo *(*GetVisualFromFBConfig)(Display *dpy, GLXFBConfig config); + Bool (*MakeContextCurrent)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + int (*QueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value); + void (*QueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); + void (*SelectEvent)(Display *dpy, GLXDrawable drawable, unsigned long mask); + + /*** GLX_SGI_swap_control ***/ + int (*SwapIntervalSGI)(int); + + /*** GLX_SGI_video_sync ***/ + int (*GetVideoSyncSGI)(unsigned int *count); + int (*WaitVideoSyncSGI)(int divisor, int remainder, unsigned int *count); + + /*** GLX_SGI_make_current_read ***/ + Bool (*MakeCurrentReadSGI)(Display *, GLXDrawable, GLXDrawable, GLXContext); + /*GLXDrawable (*GetCurrentReadDrawableSGI)(void);*/ + + /*** GLX_SGIX_video_source (needs video library) ***/ +#if defined(_VL_H_) + GLXVideoSourceSGIX (*CreateGLXVideoSourceSGIX)(Display *, int, VLServer, VLPath, int, VLNode); + void (*DestroyGLXVideoSourceSGIX)(Display *, GLXVideoSourceSGIX); +#else + void *CreateGLXVideoSourceSGIX; + void *DestroyGLXVideoSourceSGIX; +#endif + + /*** GLX_EXT_import_context ***/ + void (*FreeContextEXT)(Display *dpy, GLXContext context); + GLXContextID (*GetContextIDEXT)(const GLXContext context); + /*Display *(*GetCurrentDisplayEXT)(void);*/ + GLXContext (*ImportContextEXT)(Display *dpy, GLXContextID contextID); + int (*QueryContextInfoEXT)(Display *dpy, GLXContext context, int attribute,int *value); + + /*** GLX_SGIX_fbconfig ***/ + int (*GetFBConfigAttribSGIX)(Display *, GLXFBConfigSGIX, int, int *); + GLXFBConfigSGIX * (*ChooseFBConfigSGIX)(Display *, int, int *, int *); + GLXPixmap (*CreateGLXPixmapWithConfigSGIX)(Display *, GLXFBConfigSGIX, Pixmap); + GLXContext (*CreateContextWithConfigSGIX)(Display *, GLXFBConfigSGIX, int, GLXContext, Bool); + XVisualInfo * (*GetVisualFromFBConfigSGIX)(Display *, GLXFBConfigSGIX); + GLXFBConfigSGIX (*GetFBConfigFromVisualSGIX)(Display *, XVisualInfo *); + + /*** GLX_SGIX_pbuffer ***/ + GLXPbufferSGIX (*CreateGLXPbufferSGIX)(Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *); + void (*DestroyGLXPbufferSGIX)(Display *, GLXPbufferSGIX); + int (*QueryGLXPbufferSGIX)(Display *, GLXPbufferSGIX, int, unsigned int *); + void (*SelectEventSGIX)(Display *, GLXDrawable, unsigned long); + void (*GetSelectedEventSGIX)(Display *, GLXDrawable, unsigned long *); + + /*** GLX_SGI_cushion ***/ + void (*CushionSGI)(Display *, Window, float); + + /*** GLX_SGIX_video_resize ***/ + int (*BindChannelToWindowSGIX)(Display *, int, int, Window); + int (*ChannelRectSGIX)(Display *, int, int, int, int, int, int); + int (*QueryChannelRectSGIX)(Display *, int, int, int *, int *, int *, int *); + int (*QueryChannelDeltasSGIX)(Display *, int, int, int *, int *, int *, int *); + int (*ChannelRectSyncSGIX)(Display *, int, int, GLenum); + + /*** GLX_SGIX_dmbuffer (needs dmedia library) ***/ +#if defined (_DM_BUFFER_H_) + Bool (*AssociateDMPbufferSGIX)(Display *, GLXPbufferSGIX, DMparams *, DMbuffer); +#else + void *AssociciateDMPbufferSGIX; +#endif + + /*** GLX_SGIX_swap_group ***/ + void (*JoinSwapGroupSGIX)(Display *, GLXDrawable, GLXDrawable); + + /*** GLX_SGIX_swap_barrier ***/ + void (*BindSwapBarrierSGIX)(Display *, GLXDrawable, int); + Bool (*QueryMaxSwapBarriersSGIX)(Display *, int, int *); + + /*** GLX_SUN_get_transparent_index ***/ + Status (*GetTransparentIndexSUN)(Display *, Window, Window, long *); + + /*** GLX_MESA_copy_sub_buffer ***/ + void (*CopySubBufferMESA)(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); + + /*** GLX_MESA_release_buffers ***/ + Bool (*ReleaseBuffersMESA)(Display *dpy, Window w); + + /*** GLX_MESA_pixmap_colormap ***/ + GLXPixmap (*CreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap); + + /*** GLX_MESA_set_3dfx_mode ***/ + Bool (*Set3DfxModeMESA)(int mode); + + /*** GLX_NV_vertex_array_range ***/ + void * (*AllocateMemoryNV)( GLsizei size, + GLfloat readFrequency, + GLfloat writeFrequency, + GLfloat priority ); + void (*FreeMemoryNV)( GLvoid *pointer ); + + /*** GLX_MESA_agp_offset ***/ + GLuint (*GetAGPOffsetMESA)( const GLvoid *pointer ); + + /*** GLX_EXT_texture_from_pixmap ***/ + void (*BindTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer, + const int *attrib_list); + void (*ReleaseTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer); +}; + + + +extern const char * +_glxapi_get_version(void); + + +extern const char ** +_glxapi_get_extensions(void); + + +extern GLuint +_glxapi_get_dispatch_table_size(void); + + +extern void +_glxapi_set_no_op_table(struct _glxapi_table *t); + + +extern __GLXextFuncPtr +_glxapi_get_proc_address(const char *funcName); + + +#endif diff --git a/src/gallium/winsys/xlib/glxheader.h b/src/gallium/winsys/xlib/glxheader.h new file mode 100644 index 0000000000..a402191f13 --- /dev/null +++ b/src/gallium/winsys/xlib/glxheader.h @@ -0,0 +1,62 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.1 + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef GLX_HEADER_H +#define GLX_HEADER_H + +#ifdef __VMS +#include +#endif + +#include "glheader.h" + +#ifdef XFree86Server + +# include "resource.h" +# include "windowstr.h" + +#else + +# include +# include +# include +# ifdef USE_XSHM /* was SHM */ +# include +# include +# include +# endif +# include +# include + +#endif + + + +/* this silences a compiler warning on several systems */ +struct timespec; +struct itimerspec; + + +#endif /*GLX_HEADER*/ diff --git a/src/gallium/winsys/xlib/realglx.c b/src/gallium/winsys/xlib/realglx.c new file mode 100644 index 0000000000..30adb7465b --- /dev/null +++ b/src/gallium/winsys/xlib/realglx.c @@ -0,0 +1,180 @@ + +/* + * Mesa 3-D graphics library + * Version: 5.1 + * + * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include +#include +#include "realglx.h" +#include "glxapi.h" + + +struct _glxapi_table * +_real_GetGLXDispatchTable(void) +{ + static struct _glxapi_table glx; + + /* be sure our dispatch table size <= libGL's table */ + { + GLuint size = sizeof(struct _glxapi_table) / sizeof(void *); + (void) size; + assert(_glxapi_get_dispatch_table_size() >= size); + } + + /* initialize the whole table to no-ops */ + _glxapi_set_no_op_table(&glx); + + /* now initialize the table with the functions I implement */ + + /*** GLX_VERSION_1_0 ***/ + glx.ChooseVisual = _real_glXChooseVisual; + glx.CopyContext = _real_glXCopyContext; + glx.CreateContext = _real_glXCreateContext; + glx.CreateGLXPixmap = _real_glXCreateGLXPixmap; + glx.DestroyContext = _real_glXDestroyContext; + glx.DestroyGLXPixmap = _real_glXDestroyGLXPixmap; + glx.GetConfig = _real_glXGetConfig; + /*glx.GetCurrentContext = _real_glXGetCurrentContext;*/ + /*glx.GetCurrentDrawable = _real_glXGetCurrentDrawable;*/ + glx.IsDirect = _real_glXIsDirect; + glx.MakeCurrent = _real_glXMakeCurrent; + glx.QueryExtension = _real_glXQueryExtension; + glx.QueryVersion = _real_glXQueryVersion; + glx.SwapBuffers = _real_glXSwapBuffers; + glx.UseXFont = _real_glXUseXFont; + glx.WaitGL = _real_glXWaitGL; + glx.WaitX = _real_glXWaitX; + + /*** GLX_VERSION_1_1 ***/ + glx.GetClientString = _real_glXGetClientString; + glx.QueryExtensionsString = _real_glXQueryExtensionsString; + glx.QueryServerString = _real_glXQueryServerString; + + /*** GLX_VERSION_1_2 ***/ + /*glx.GetCurrentDisplay = _real_glXGetCurrentDisplay;*/ + + /*** GLX_VERSION_1_3 ***/ + glx.ChooseFBConfig = _real_glXChooseFBConfig; + glx.CreateNewContext = _real_glXCreateNewContext; + glx.CreatePbuffer = _real_glXCreatePbuffer; + glx.CreatePixmap = _real_glXCreatePixmap; + glx.CreateWindow = _real_glXCreateWindow; + glx.DestroyPbuffer = _real_glXDestroyPbuffer; + glx.DestroyPixmap = _real_glXDestroyPixmap; + glx.DestroyWindow = _real_glXDestroyWindow; + /*glx.GetCurrentReadDrawable = _real_glXGetCurrentReadDrawable;*/ + glx.GetFBConfigAttrib = _real_glXGetFBConfigAttrib; + glx.GetFBConfigs = _real_glXGetFBConfigs; + glx.GetSelectedEvent = _real_glXGetSelectedEvent; + glx.GetVisualFromFBConfig = _real_glXGetVisualFromFBConfig; + glx.MakeContextCurrent = _real_glXMakeContextCurrent; + glx.QueryContext = _real_glXQueryContext; + glx.QueryDrawable = _real_glXQueryDrawable; + glx.SelectEvent = _real_glXSelectEvent; + + /*** GLX_SGI_swap_control ***/ + glx.SwapIntervalSGI = _real_glXSwapIntervalSGI; + + /*** GLX_SGI_video_sync ***/ + glx.GetVideoSyncSGI = _real_glXGetVideoSyncSGI; + glx.WaitVideoSyncSGI = _real_glXWaitVideoSyncSGI; + + /*** GLX_SGI_make_current_read ***/ + glx.MakeCurrentReadSGI = _real_glXMakeCurrentReadSGI; + /*glx.GetCurrentReadDrawableSGI = _real_glXGetCurrentReadDrawableSGI;*/ + +#if defined(_VL_H) + /*** GLX_SGIX_video_source ***/ + glx.CreateGLXVideoSourceSGIX = _real_glXCreateGLXVideoSourceSGIX; + glx.DestroyGLXVideoSourceSGIX = _real_glXDestroyGLXVideoSourceSGIX; +#endif + + /*** GLX_EXT_import_context ***/ + glx.FreeContextEXT = _real_glXFreeContextEXT; + /*glx.GetContextIDEXT = _real_glXGetContextIDEXT;*/ + /*glx.GetCurrentDisplayEXT = _real_glXGetCurrentDisplayEXT;*/ + glx.ImportContextEXT = _real_glXImportContextEXT; + glx.QueryContextInfoEXT = _real_glXQueryContextInfoEXT; + + /*** GLX_SGIX_fbconfig ***/ + glx.GetFBConfigAttribSGIX = _real_glXGetFBConfigAttribSGIX; + glx.ChooseFBConfigSGIX = _real_glXChooseFBConfigSGIX; + glx.CreateGLXPixmapWithConfigSGIX = _real_glXCreateGLXPixmapWithConfigSGIX; + glx.CreateContextWithConfigSGIX = _real_glXCreateContextWithConfigSGIX; + glx.GetVisualFromFBConfigSGIX = _real_glXGetVisualFromFBConfigSGIX; + glx.GetFBConfigFromVisualSGIX = _real_glXGetFBConfigFromVisualSGIX; + + /*** GLX_SGIX_pbuffer ***/ + glx.CreateGLXPbufferSGIX = _real_glXCreateGLXPbufferSGIX; + glx.DestroyGLXPbufferSGIX = _real_glXDestroyGLXPbufferSGIX; + glx.QueryGLXPbufferSGIX = _real_glXQueryGLXPbufferSGIX; + glx.SelectEventSGIX = _real_glXSelectEventSGIX; + glx.GetSelectedEventSGIX = _real_glXGetSelectedEventSGIX; + + /*** GLX_SGI_cushion ***/ + glx.CushionSGI = _real_glXCushionSGI; + + /*** GLX_SGIX_video_resize ***/ + glx.BindChannelToWindowSGIX = _real_glXBindChannelToWindowSGIX; + glx.ChannelRectSGIX = _real_glXChannelRectSGIX; + glx.QueryChannelRectSGIX = _real_glXQueryChannelRectSGIX; + glx.QueryChannelDeltasSGIX = _real_glXQueryChannelDeltasSGIX; + glx.ChannelRectSyncSGIX = _real_glXChannelRectSyncSGIX; + +#if defined(_DM_BUFFER_H_) + /*** (GLX_SGIX_dmbuffer ***/ + glx.AssociateDMPbufferSGIX = NULL; +#endif + + /*** GLX_SGIX_swap_group ***/ + glx.JoinSwapGroupSGIX = _real_glXJoinSwapGroupSGIX; + + /*** GLX_SGIX_swap_barrier ***/ + glx.BindSwapBarrierSGIX = _real_glXBindSwapBarrierSGIX; + glx.QueryMaxSwapBarriersSGIX = _real_glXQueryMaxSwapBarriersSGIX; + + /*** GLX_SUN_get_transparent_index ***/ + glx.GetTransparentIndexSUN = _real_glXGetTransparentIndexSUN; + + /*** GLX_MESA_copy_sub_buffer ***/ + glx.CopySubBufferMESA = _real_glXCopySubBufferMESA; + + /*** GLX_MESA_release_buffers ***/ + glx.ReleaseBuffersMESA = _real_glXReleaseBuffersMESA; + + /*** GLX_MESA_pixmap_colormap ***/ + glx.CreateGLXPixmapMESA = _real_glXCreateGLXPixmapMESA; + + /*** GLX_MESA_set_3dfx_mode ***/ + glx.Set3DfxModeMESA = _real_glXSet3DfxModeMESA; + + /*** GLX_NV_vertex_array_range ***/ + glx.AllocateMemoryNV = _real_glXAllocateMemoryNV; + glx.FreeMemoryNV = _real_glXFreeMemoryNV; + + /*** GLX_MESA_agp_offset ***/ + glx.GetAGPOffsetMESA = _real_glXGetAGPOffsetMESA; + + return &glx; +} diff --git a/src/gallium/winsys/xlib/realglx.h b/src/gallium/winsys/xlib/realglx.h new file mode 100644 index 0000000000..150129db68 --- /dev/null +++ b/src/gallium/winsys/xlib/realglx.h @@ -0,0 +1,326 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef REALGLX_H +#define REALGLX_H + + +extern struct _glxapi_table * +_real_GetGLXDispatchTable(void); + + +/* + * Basically just need these to prevent compiler warnings. + */ + + +extern XVisualInfo * +_real_glXChooseVisual( Display *dpy, int screen, int *list ); + +extern GLXContext +_real_glXCreateContext( Display *dpy, XVisualInfo *visinfo, + GLXContext share_list, Bool direct ); + +extern GLXPixmap +_real_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ); + +extern GLXPixmap +_real_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, + Pixmap pixmap, Colormap cmap ); + +extern void +_real_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ); + +extern void +_real_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, + unsigned long mask ); + +extern Bool +_real_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ); + +extern Bool +_real_glXQueryExtension( Display *dpy, int *errorb, int *event ); + +extern void +_real_glXDestroyContext( Display *dpy, GLXContext ctx ); + +extern Bool +_real_glXIsDirect( Display *dpy, GLXContext ctx ); + +extern void +_real_glXSwapBuffers( Display *dpy, GLXDrawable drawable ); + +extern void +_real_glXUseXFont( Font font, int first, int count, int listbase ); + +extern Bool +_real_glXQueryVersion( Display *dpy, int *maj, int *min ); + +extern int +_real_glXGetConfig( Display *dpy, XVisualInfo *visinfo, + int attrib, int *value ); + +extern void +_real_glXWaitGL( void ); + + +extern void +_real_glXWaitX( void ); + +/* GLX 1.1 and later */ +extern const char * +_real_glXQueryExtensionsString( Display *dpy, int screen ); + +/* GLX 1.1 and later */ +extern const char * +_real_glXQueryServerString( Display *dpy, int screen, int name ); + +/* GLX 1.1 and later */ +extern const char * +_real_glXGetClientString( Display *dpy, int name ); + + +/* + * GLX 1.3 and later + */ + +extern GLXFBConfig * +_real_glXChooseFBConfig( Display *dpy, int screen, + const int *attribList, int *nitems ); + +extern int +_real_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, + int attribute, int *value ); + +extern GLXFBConfig * +_real_glXGetFBConfigs( Display *dpy, int screen, int *nelements ); + +extern XVisualInfo * +_real_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ); + +extern GLXWindow +_real_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, + const int *attribList ); + +extern void +_real_glXDestroyWindow( Display *dpy, GLXWindow window ); + +extern GLXPixmap +_real_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, + const int *attribList ); + +extern void +_real_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ); + +extern GLXPbuffer +_real_glXCreatePbuffer( Display *dpy, GLXFBConfig config, + const int *attribList ); + +extern void +_real_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ); + +extern void +_real_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, + unsigned int *value ); + +extern GLXContext +_real_glXCreateNewContext( Display *dpy, GLXFBConfig config, + int renderType, GLXContext shareList, Bool direct ); + + +extern Bool +_real_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, + GLXDrawable read, GLXContext ctx ); + +extern int +_real_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value ); + +extern void +_real_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ); + +extern void +_real_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, + unsigned long *mask ); + +#ifdef GLX_SGI_swap_control +extern int +_real_glXSwapIntervalSGI(int interval); +#endif + + +#ifdef GLX_SGI_video_sync +extern int +_real_glXGetVideoSyncSGI(unsigned int *count); + +extern int +_real_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count); +#endif + + +#ifdef GLX_SGI_make_current_read +extern Bool +_real_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + +extern GLXDrawable +_real_glXGetCurrentReadDrawableSGI(void); +#endif + +#if defined(_VL_H) && defined(GLX_SGIX_video_source) +extern GLXVideoSourceSGIX +_real_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode); + +extern void +_real_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src); +#endif + +#ifdef GLX_EXT_import_context +extern void +_real_glXFreeContextEXT(Display *dpy, GLXContext context); + +extern GLXContextID +_real_glXGetContextIDEXT(const GLXContext context); + +extern Display * +_real_glXGetCurrentDisplayEXT(void); + +extern GLXContext +_real_glXImportContextEXT(Display *dpy, GLXContextID contextID); + +extern int +_real_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value); +#endif + +#ifdef GLX_SGIX_fbconfig +extern int +_real_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); + +extern GLXFBConfigSGIX * +_real_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements); + +extern GLXPixmap +_real_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); + +extern GLXContext +_real_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); + +extern XVisualInfo * +_real_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config); + +extern GLXFBConfigSGIX +_real_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis); +#endif + +#ifdef GLX_SGIX_pbuffer +extern GLXPbufferSGIX +_real_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); + +extern void +_real_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf); + +extern int +_real_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); + +extern void +_real_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask); + +extern void +_real_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask); +#endif + +#ifdef GLX_SGI_cushion +extern void +_real_glXCushionSGI(Display *dpy, Window win, float cushion); +#endif + +#ifdef GLX_SGIX_video_resize +extern int +_real_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window); + +extern int +_real_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h); + +extern int +_real_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h); + +extern int +_real_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh); + +extern int +_real_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype); +#endif + +#if defined(_DM_BUFFER_H_) && defined(GLX_SGIX_dmbuffer) +extern Bool +_real_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer); +#endif + +#ifdef GLX_SGIX_swap_group +extern void +_real_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member); +#endif + +#ifdef GLX_SGIX_swap_barrier +extern void +_real_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier); + +extern Bool +_real_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max); +#endif + +#ifdef GLX_SUN_get_transparent_index +extern Status +_real_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent); +#endif + +#ifdef GLX_MESA_release_buffers +extern Bool +_real_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d ); +#endif + +#ifdef GLX_MESA_set_3dfx_mode +extern Bool +_real_glXSet3DfxModeMESA( int mode ); +#endif + +#ifdef GLX_NV_vertex_array_range +extern void * +_real_glXAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +extern void +_real_glXFreeMemoryNV(GLvoid *pointer); +#endif + +#ifdef GLX_MESA_agp_offset +extern GLuint +_real_glXGetAGPOffsetMESA(const GLvoid *pointer); +#endif + +#ifdef GLX_MESA_copy_sub_buffer +extern void +_real_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, + int x, int y, int width, int height ); +#endif + +#endif /* REALGLX_H */ diff --git a/src/gallium/winsys/xlib/xfonts.c b/src/gallium/winsys/xlib/xfonts.c new file mode 100644 index 0000000000..d72c600bd1 --- /dev/null +++ b/src/gallium/winsys/xlib/xfonts.c @@ -0,0 +1,377 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* xfonts.c -- glXUseXFont() for Mesa written by + * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de + */ + +#ifdef __VMS +#include +#endif + +#include "glxheader.h" +#include "context.h" +#include "imports.h" +#include "xfonts.h" + + +/* Some debugging info. */ + +#ifdef DEBUG +#undef _R +#undef _G +#undef _B +#include + +int debug_xfonts = 0; + +static void +dump_char_struct(XCharStruct * ch, char *prefix) +{ + printf("%slbearing = %d, rbearing = %d, width = %d\n", + prefix, ch->lbearing, ch->rbearing, ch->width); + printf("%sascent = %d, descent = %d, attributes = %u\n", + prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes); +} + +static void +dump_font_struct(XFontStruct * font) +{ + printf("ascent = %d, descent = %d\n", font->ascent, font->descent); + printf("char_or_byte2 = (%u,%u)\n", + font->min_char_or_byte2, font->max_char_or_byte2); + printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1); + printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False"); + printf("default_char = %c (\\%03o)\n", + (char) (isprint(font->default_char) ? font->default_char : ' '), + font->default_char); + dump_char_struct(&font->min_bounds, "min> "); + dump_char_struct(&font->max_bounds, "max> "); +#if 0 + for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) { + char prefix[8]; + sprintf(prefix, "%d> ", c); + dump_char_struct(&font->per_char[c], prefix); + } +#endif +} + +static void +dump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap) +{ + unsigned int x, y; + + printf(" "); + for (x = 0; x < 8 * width; x++) + printf("%o", 7 - (x % 8)); + putchar('\n'); + for (y = 0; y < height; y++) { + printf("%3o:", y); + for (x = 0; x < 8 * width; x++) + putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x % + 8)))) + ? '*' : '.'); + printf(" "); + for (x = 0; x < width; x++) + printf("0x%02x, ", bitmap[width * (height - y - 1) + x]); + putchar('\n'); + } +} +#endif /* DEBUG */ + + +/* Implementation. */ + +/* Fill a BITMAP with a character C from thew current font + in the graphics context GC. WIDTH is the width in bytes + and HEIGHT is the height in bits. + + Note that the generated bitmaps must be used with + + glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE); + glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); + glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei (GL_UNPACK_ALIGNMENT, 1); + + Possible optimizations: + + * use only one reusable pixmap with the maximum dimensions. + * draw the entire font into a single pixmap (careful with + proportional fonts!). +*/ + + +/* + * Generate OpenGL-compatible bitmap. + */ +static void +fill_bitmap(Display * dpy, Window win, GC gc, + unsigned int width, unsigned int height, + int x0, int y0, unsigned int c, GLubyte * bitmap) +{ + XImage *image; + unsigned int x, y; + Pixmap pixmap; + XChar2b char2b; + + pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1); + XSetForeground(dpy, gc, 0); + XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height); + XSetForeground(dpy, gc, 1); + + char2b.byte1 = (c >> 8) & 0xff; + char2b.byte2 = (c & 0xff); + + XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1); + + image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap); + if (image) { + /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */ + for (y = 0; y < height; y++) + for (x = 0; x < 8 * width; x++) + if (XGetPixel(image, x, y)) + bitmap[width * (height - y - 1) + x / 8] |= + (1 << (7 - (x % 8))); + XDestroyImage(image); + } + + XFreePixmap(dpy, pixmap); +} + +/* + * determine if a given glyph is valid and return the + * corresponding XCharStruct. + */ +static XCharStruct * +isvalid(XFontStruct * fs, unsigned int which) +{ + unsigned int rows, pages; + unsigned int byte1 = 0, byte2 = 0; + int i, valid = 1; + + rows = fs->max_byte1 - fs->min_byte1 + 1; + pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; + + if (rows == 1) { + /* "linear" fonts */ + if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which)) + valid = 0; + } + else { + /* "matrix" fonts */ + byte2 = which & 0xff; + byte1 = which >> 8; + if ((fs->min_char_or_byte2 > byte2) || + (fs->max_char_or_byte2 < byte2) || + (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1)) + valid = 0; + } + + if (valid) { + if (fs->per_char) { + if (rows == 1) { + /* "linear" fonts */ + return (fs->per_char + (which - fs->min_char_or_byte2)); + } + else { + /* "matrix" fonts */ + i = ((byte1 - fs->min_byte1) * pages) + + (byte2 - fs->min_char_or_byte2); + return (fs->per_char + i); + } + } + else { + return (&fs->min_bounds); + } + } + return (NULL); +} + + +void +Fake_glXUseXFont(Font font, int first, int count, int listbase) +{ + Display *dpy; + Window win; + Pixmap pixmap; + GC gc; + XGCValues values; + unsigned long valuemask; + XFontStruct *fs; + GLint swapbytes, lsbfirst, rowlength; + GLint skiprows, skippixels, alignment; + unsigned int max_width, max_height, max_bm_width, max_bm_height; + GLubyte *bm; + int i; + + dpy = glXGetCurrentDisplay(); + if (!dpy) + return; /* I guess glXMakeCurrent wasn't called */ + win = RootWindow(dpy, DefaultScreen(dpy)); + + fs = XQueryFont(dpy, font); + if (!fs) { + _mesa_error(NULL, GL_INVALID_VALUE, + "Couldn't get font structure information"); + return; + } + + /* Allocate a bitmap that can fit all characters. */ + max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing; + max_height = fs->max_bounds.ascent + fs->max_bounds.descent; + max_bm_width = (max_width + 7) / 8; + max_bm_height = max_height; + + bm = (GLubyte *) MALLOC((max_bm_width * max_bm_height) * sizeof(GLubyte)); + if (!bm) { + XFreeFontInfo(NULL, fs, 1); + _mesa_error(NULL, GL_OUT_OF_MEMORY, + "Couldn't allocate bitmap in glXUseXFont()"); + return; + } + +#if 0 + /* get the page info */ + pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1; + firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2; + lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2; + rows = fs->max_byte1 - fs->min_byte1 + 1; + unsigned int first_char, last_char, pages, rows; +#endif + + /* Save the current packing mode for bitmaps. */ + glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes); + glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst); + glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength); + glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows); + glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels); + glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); + + /* Enforce a standard packing mode which is compatible with + fill_bitmap() from above. This is actually the default mode, + except for the (non)alignment. */ + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + pixmap = XCreatePixmap(dpy, win, 10, 10, 1); + values.foreground = BlackPixel(dpy, DefaultScreen(dpy)); + values.background = WhitePixel(dpy, DefaultScreen(dpy)); + values.font = fs->fid; + valuemask = GCForeground | GCBackground | GCFont; + gc = XCreateGC(dpy, pixmap, valuemask, &values); + XFreePixmap(dpy, pixmap); + +#ifdef DEBUG + if (debug_xfonts) + dump_font_struct(fs); +#endif + + for (i = 0; i < count; i++) { + unsigned int width, height, bm_width, bm_height; + GLfloat x0, y0, dx, dy; + XCharStruct *ch; + int x, y; + unsigned int c = first + i; + int list = listbase + i; + int valid; + + /* check on index validity and get the bounds */ + ch = isvalid(fs, c); + if (!ch) { + ch = &fs->max_bounds; + valid = 0; + } + else { + valid = 1; + } + +#ifdef DEBUG + if (debug_xfonts) { + char s[7]; + sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c); + dump_char_struct(ch, s); + } +#endif + + /* glBitmap()' parameters: + straight from the glXUseXFont(3) manpage. */ + width = ch->rbearing - ch->lbearing; + height = ch->ascent + ch->descent; + x0 = -ch->lbearing; + y0 = ch->descent - 0; /* XXX used to subtract 1 here */ + /* but that caused a conformace failure */ + dx = ch->width; + dy = 0; + + /* X11's starting point. */ + x = -ch->lbearing; + y = ch->ascent; + + /* Round the width to a multiple of eight. We will use this also + for the pixmap for capturing the X11 font. This is slightly + inefficient, but it makes the OpenGL part real easy. */ + bm_width = (width + 7) / 8; + bm_height = height; + + glNewList(list, GL_COMPILE); + if (valid && (bm_width > 0) && (bm_height > 0)) { + + MEMSET(bm, '\0', bm_width * bm_height); + fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm); + + glBitmap(width, height, x0, y0, dx, dy, bm); +#ifdef DEBUG + if (debug_xfonts) { + printf("width/height = %u/%u\n", width, height); + printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height); + dump_bitmap(bm_width, bm_height, bm); + } +#endif + } + else { + glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL); + } + glEndList(); + } + + FREE(bm); + XFreeFontInfo(NULL, fs, 1); + XFreeGC(dpy, gc); + + /* Restore saved packing modes. */ + glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes); + glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst); + glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength); + glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels); + glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); +} diff --git a/src/gallium/winsys/xlib/xfonts.h b/src/gallium/winsys/xlib/xfonts.h new file mode 100644 index 0000000000..e36f42f817 --- /dev/null +++ b/src/gallium/winsys/xlib/xfonts.h @@ -0,0 +1,41 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef XFONTS_H +#define XFONTS_H + +#ifdef __VMS +#include +#endif + +#include + + +extern void Fake_glXUseXFont( Font font, int first, int count, int listbase ); + + +#endif + diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c new file mode 100644 index 0000000000..e5fef1d7a8 --- /dev/null +++ b/src/gallium/winsys/xlib/xm_api.c @@ -0,0 +1,1380 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file xm_api.c + * + * All the XMesa* API functions. + * + * + * NOTES: + * + * The window coordinate system origin (0,0) is in the lower-left corner + * of the window. X11's window coordinate origin is in the upper-left + * corner of the window. Therefore, most drawing functions in this + * file have to flip Y coordinates. + * + * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile + * in support for the MIT Shared Memory extension. If enabled, when you + * use an Ximage for the back buffer in double buffered mode, the "swap" + * operation will be faster. You must also link with -lXext. + * + * Byte swapping: If the Mesa host and the X display use a different + * byte order then there's some trickiness to be aware of when using + * XImages. The byte ordering used for the XImage is that of the X + * display, not the Mesa host. + * The color-to-pixel encoding for True/DirectColor must be done + * according to the display's visual red_mask, green_mask, and blue_mask. + * If XPutPixel is used to put a pixel into an XImage then XPutPixel will + * do byte swapping if needed. If one wants to directly "poke" the pixel + * into the XImage's buffer then the pixel must be byte swapped first. + * + */ + +#ifdef __CYGWIN__ +#undef WIN32 +#undef __WIN32__ +#endif + +#include "glxheader.h" +#include "GL/xmesa.h" +#include "xmesaP.h" +#include "main/context.h" +#include "main/framebuffer.h" +#include "glapi/glthread.h" + +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" + +#include "xm_winsys_aub.h" + +/** + * Global X driver lock + */ +_glthread_Mutex _xmesa_lock; + + +int xmesa_mode; + + +/**********************************************************************/ +/***** X Utility Functions *****/ +/**********************************************************************/ + + +/** + * Return the host's byte order as LSBFirst or MSBFirst ala X. + */ +#ifndef XFree86Server +static int host_byte_order( void ) +{ + int i = 1; + char *cptr = (char *) &i; + return (*cptr==1) ? LSBFirst : MSBFirst; +} +#endif + + +/** + * Check if the X Shared Memory extension is available. + * Return: 0 = not available + * 1 = shared XImage support available + * 2 = shared Pixmap support available also + */ +static int check_for_xshm( XMesaDisplay *display ) +{ +#if defined(USE_XSHM) && !defined(XFree86Server) + int major, minor, ignore; + Bool pixmaps; + + if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { + if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { + return (pixmaps==True) ? 2 : 1; + } + else { + return 0; + } + } + else { + return 0; + } +#else + /* No XSHM support */ + return 0; +#endif +} + + +/** + * Return the true number of bits per pixel for XImages. + * For example, if we request a 24-bit deep visual we may actually need/get + * 32bpp XImages. This function returns the appropriate bpp. + * Input: dpy - the X display + * visinfo - desribes the visual to be used for XImages + * Return: true number of bits per pixel for XImages + */ +static int +bits_per_pixel( XMesaVisual xmv ) +{ +#ifdef XFree86Server + const int depth = xmv->nplanes; + int i; + assert(depth > 0); + for (i = 0; i < screenInfo.numPixmapFormats; i++) { + if (screenInfo.formats[i].depth == depth) + return screenInfo.formats[i].bitsPerPixel; + } + return depth; /* should never get here, but this should be safe */ +#else + XMesaDisplay *dpy = xmv->display; + XMesaVisualInfo visinfo = xmv->visinfo; + XMesaImage *img; + int bitsPerPixel; + /* Create a temporary XImage */ + img = XCreateImage( dpy, visinfo->visual, visinfo->depth, + ZPixmap, 0, /*format, offset*/ + (char*) MALLOC(8), /*data*/ + 1, 1, /*width, height*/ + 32, /*bitmap_pad*/ + 0 /*bytes_per_line*/ + ); + assert(img); + /* grab the bits/pixel value */ + bitsPerPixel = img->bits_per_pixel; + /* free the XImage */ + _mesa_free( img->data ); + img->data = NULL; + XMesaDestroyImage( img ); + return bitsPerPixel; +#endif +} + + + +/* + * Determine if a given X window ID is valid (window exists). + * Do this by calling XGetWindowAttributes() for the window and + * checking if we catch an X error. + * Input: dpy - the display + * win - the window to check for existance + * Return: GL_TRUE - window exists + * GL_FALSE - window doesn't exist + */ +#ifndef XFree86Server +static GLboolean WindowExistsFlag; + +static int window_exists_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr ) +{ + (void) dpy; + if (xerr->error_code == BadWindow) { + WindowExistsFlag = GL_FALSE; + } + return 0; +} + +static GLboolean window_exists( XMesaDisplay *dpy, Window win ) +{ + XWindowAttributes wa; + int (*old_handler)( XMesaDisplay*, XErrorEvent* ); + WindowExistsFlag = GL_TRUE; + old_handler = XSetErrorHandler(window_exists_err_handler); + XGetWindowAttributes( dpy, win, &wa ); /* dummy request */ + XSetErrorHandler(old_handler); + return WindowExistsFlag; +} + +static Status +get_drawable_size( XMesaDisplay *dpy, Drawable d, uint *width, uint *height ) +{ + Window root; + Status stat; + int xpos, ypos; + unsigned int w, h, bw, depth; + stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); + *width = w; + *height = h; + return stat; +} +#endif + + +/** + * Return the size of the window (or pixmap) that corresponds to the + * given XMesaBuffer. + * \param width returns width in pixels + * \param height returns height in pixels + */ +static void +xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b, + GLuint *width, GLuint *height) +{ +#ifdef XFree86Server + *width = MIN2(b->drawable->width, MAX_WIDTH); + *height = MIN2(b->drawable->height, MAX_HEIGHT); +#else + Status stat; + + _glthread_LOCK_MUTEX(_xmesa_lock); + XSync(b->xm_visual->display, 0); /* added for Chromium */ + stat = get_drawable_size(dpy, b->drawable, width, height); + _glthread_UNLOCK_MUTEX(_xmesa_lock); + + if (!stat) { + /* probably querying a window that's recently been destroyed */ + _mesa_warning(NULL, "XGetGeometry failed!\n"); + *width = *height = 1; + } +#endif +} + + +/** + * Choose the pixel format for the given visual. + * This will tell the gallium driver how to pack pixel data into + * drawing surfaces. + */ +static GLuint +choose_pixel_format(XMesaVisual v) +{ + if ( GET_REDMASK(v) == 0x0000ff + && GET_GREENMASK(v) == 0x00ff00 + && GET_BLUEMASK(v) == 0xff0000 + && v->BitsPerPixel == 32) { + if (CHECK_BYTE_ORDER(v)) { + /* no byteswapping needed */ + return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; + } + else { + return PIPE_FORMAT_R8G8B8A8_UNORM; + } + } + else if ( GET_REDMASK(v) == 0xff0000 + && GET_GREENMASK(v) == 0x00ff00 + && GET_BLUEMASK(v) == 0x0000ff + && v->BitsPerPixel == 32) { + if (CHECK_BYTE_ORDER(v)) { + /* no byteswapping needed */ + return PIPE_FORMAT_A8R8G8B8_UNORM; + } + else { + return PIPE_FORMAT_B8G8R8A8_UNORM; + } + } + else if ( GET_REDMASK(v) == 0xf800 + && GET_GREENMASK(v) == 0x07e0 + && GET_BLUEMASK(v) == 0x001f + && CHECK_BYTE_ORDER(v) + && v->BitsPerPixel == 16) { + /* 5-6-5 RGB */ + return PIPE_FORMAT_R5G6B5_UNORM; + } + + assert(0); + return 0; +} + + + +/**********************************************************************/ +/***** Linked list of XMesaBuffers *****/ +/**********************************************************************/ + +XMesaBuffer XMesaBufferList = NULL; + + +/** + * Allocate a new XMesaBuffer object which corresponds to the given drawable. + * Note that XMesaBuffer is derived from GLframebuffer. + * The new XMesaBuffer will not have any size (Width=Height=0). + * + * \param d the corresponding X drawable (window or pixmap) + * \param type either WINDOW, PIXMAP or PBUFFER, describing d + * \param vis the buffer's visual + * \param cmap the window's colormap, if known. + * \return new XMesaBuffer or NULL if any problem + */ +static XMesaBuffer +create_xmesa_buffer(XMesaDrawable d, BufferType type, + XMesaVisual vis, XMesaColormap cmap) +{ + XMesaBuffer b; + GLframebuffer *fb; + enum pipe_format colorFormat, depthFormat, stencilFormat; + uint width, height; + + ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER); + + b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer); + if (!b) + return NULL; + + b->drawable = d; + + b->xm_visual = vis; + b->type = type; + b->cmap = cmap; + + /* determine PIPE_FORMATs for buffers */ + colorFormat = choose_pixel_format(vis); + + if (vis->mesa_visual.depthBits == 0) + depthFormat = PIPE_FORMAT_NONE; + else if (vis->mesa_visual.depthBits <= 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (vis->mesa_visual.depthBits <= 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_Z32_UNORM; + + if (vis->mesa_visual.stencilBits == 8) { + if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) + stencilFormat = depthFormat; + else + stencilFormat = PIPE_FORMAT_S8_UNORM; + } + else { + stencilFormat = PIPE_FORMAT_NONE; + } + + + get_drawable_size(vis->display, d, &width, &height); + + /* + * Create framebuffer, but we'll plug in our own renderbuffers below. + */ + b->stfb = st_create_framebuffer(&vis->mesa_visual, + colorFormat, depthFormat, stencilFormat, + width, height, + (void *) b); + fb = &b->stfb->Base; + + /* + * Create scratch XImage for xmesa_display_surface() + */ + b->tempImage = XCreateImage(vis->display, + vis->visinfo->visual, + vis->visinfo->depth, + ZPixmap, 0, /* format, offset */ + NULL, /* data */ + 0, 0, /* size */ + 32, /* bitmap_pad */ + 0); /* bytes_per_line */ + + /* GLX_EXT_texture_from_pixmap */ + b->TextureTarget = 0; + b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT; + b->TextureMipmap = 0; + + /* insert buffer into linked list */ + b->Next = XMesaBufferList; + XMesaBufferList = b; + + return b; +} + + +/** + * Find an XMesaBuffer by matching X display and colormap but NOT matching + * the notThis buffer. + */ +XMesaBuffer +xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis) +{ + XMesaBuffer b; + for (b = XMesaBufferList; b; b = b->Next) { + if (b->xm_visual->display == dpy && + b->cmap == cmap && + b != notThis) { + return b; + } + } + return NULL; +} + + +/** + * Remove buffer from linked list, delete if no longer referenced. + */ +static void +xmesa_free_buffer(XMesaBuffer buffer) +{ + XMesaBuffer prev = NULL, b; + + for (b = XMesaBufferList; b; b = b->Next) { + if (b == buffer) { + struct gl_framebuffer *fb = &buffer->stfb->Base; + + /* unlink buffer from list */ + if (prev) + prev->Next = buffer->Next; + else + XMesaBufferList = buffer->Next; + + /* mark as delete pending */ + fb->DeletePending = GL_TRUE; + + /* Since the X window for the XMesaBuffer is going away, we don't + * want to dereference this pointer in the future. + */ + b->drawable = 0; + + buffer->tempImage->data = NULL; + XDestroyImage(buffer->tempImage); + + /* Unreference. If count = zero we'll really delete the buffer */ + _mesa_unreference_framebuffer(&fb); + + XFreeGC(b->xm_visual->display, b->gc); + + free(buffer); + + return; + } + /* continue search */ + prev = b; + } + /* buffer not found in XMesaBufferList */ + _mesa_problem(NULL,"xmesa_free_buffer() - buffer not found\n"); +} + + + +/**********************************************************************/ +/***** Misc Private Functions *****/ +/**********************************************************************/ + + +/** + * When a context is bound for the first time, we can finally finish + * initializing the context's visual and buffer information. + * \param v the XMesaVisual to initialize + * \param b the XMesaBuffer to initialize (may be NULL) + * \param rgb_flag TRUE = RGBA mode, FALSE = color index mode + * \param window the window/pixmap we're rendering into + * \param cmap the colormap associated with the window/pixmap + * \return GL_TRUE=success, GL_FALSE=failure + */ +static GLboolean +initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, + GLboolean rgb_flag, XMesaDrawable window, + XMesaColormap cmap) +{ +#ifdef XFree86Server + int client = (window) ? CLIENT_ID(window->id) : 0; +#endif + + ASSERT(!b || b->xm_visual == v); + + /* Save true bits/pixel */ + v->BitsPerPixel = bits_per_pixel(v); + assert(v->BitsPerPixel > 0); + + if (rgb_flag == GL_FALSE) { + /* COLOR-INDEXED WINDOW: not supported*/ + return GL_FALSE; + } + else { + /* RGB WINDOW: + * We support RGB rendering into almost any kind of visual. + */ + const int xclass = v->mesa_visual.visualType; + if (xclass != GLX_TRUE_COLOR && xclass == !GLX_DIRECT_COLOR) { + _mesa_warning(NULL, + "XMesa: RGB mode rendering not supported in given visual.\n"); + return GL_FALSE; + } + v->mesa_visual.indexBits = 0; + } + + /* + * If MESA_INFO env var is set print out some debugging info + * which can help Brian figure out what's going on when a user + * reports bugs. + */ + if (_mesa_getenv("MESA_INFO")) { + _mesa_printf("X/Mesa visual = %p\n", (void *) v); + _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level); + _mesa_printf("X/Mesa depth = %d\n", GET_VISUAL_DEPTH(v)); + _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); + } + + if (b && window) { + /* these should have been set in create_xmesa_buffer */ + ASSERT(b->drawable == window); + + /* Setup for single/double buffering */ + if (v->mesa_visual.doubleBufferMode) { + /* Double buffered */ + b->shm = check_for_xshm( v->display ); + } + + /* X11 graphics context */ +#ifdef XFree86Server + b->gc = CreateScratchGC(v->display, window->depth); +#else + b->gc = XCreateGC( v->display, window, 0, NULL ); +#endif + XMesaSetFunction( v->display, b->gc, GXcopy ); + } + + return GL_TRUE; +} + + + +#define NUM_VISUAL_TYPES 6 + +/** + * Convert an X visual type to a GLX visual type. + * + * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) + * to be converted. + * \return If \c visualType is a valid X visual type, a GLX visual type will + * be returned. Otherwise \c GLX_NONE will be returned. + * + * \note + * This code was lifted directly from lib/GL/glx/glcontextmodes.c in the + * DRI CVS tree. + */ +static GLint +xmesa_convert_from_x_visual_type( int visualType ) +{ + static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { + GLX_STATIC_GRAY, GLX_GRAY_SCALE, + GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, + GLX_TRUE_COLOR, GLX_DIRECT_COLOR + }; + + return ( (unsigned) visualType < NUM_VISUAL_TYPES ) + ? glx_visual_types[ visualType ] : GLX_NONE; +} + + +/**********************************************************************/ +/***** Public Functions *****/ +/**********************************************************************/ + + +/* + * Create a new X/Mesa visual. + * Input: display - X11 display + * visinfo - an XVisualInfo pointer + * rgb_flag - GL_TRUE = RGB mode, + * GL_FALSE = color index mode + * alpha_flag - alpha buffer requested? + * db_flag - GL_TRUE = double-buffered, + * GL_FALSE = single buffered + * stereo_flag - stereo visual? + * ximage_flag - GL_TRUE = use an XImage for back buffer, + * GL_FALSE = use an off-screen pixmap for back buffer + * depth_size - requested bits/depth values, or zero + * stencil_size - requested bits/stencil values, or zero + * accum_red_size - requested bits/red accum values, or zero + * accum_green_size - requested bits/green accum values, or zero + * accum_blue_size - requested bits/blue accum values, or zero + * accum_alpha_size - requested bits/alpha accum values, or zero + * num_samples - number of samples/pixel if multisampling, or zero + * level - visual level, usually 0 + * visualCaveat - ala the GLX extension, usually GLX_NONE + * Return; a new XMesaVisual or 0 if error. + */ +PUBLIC +XMesaVisual XMesaCreateVisual( XMesaDisplay *display, + XMesaVisualInfo visinfo, + GLboolean rgb_flag, + GLboolean alpha_flag, + GLboolean db_flag, + GLboolean stereo_flag, + GLboolean ximage_flag, + GLint depth_size, + GLint stencil_size, + GLint accum_red_size, + GLint accum_green_size, + GLint accum_blue_size, + GLint accum_alpha_size, + GLint num_samples, + GLint level, + GLint visualCaveat ) +{ + XMesaVisual v; + GLint red_bits, green_bits, blue_bits, alpha_bits; + +#ifndef XFree86Server + /* For debugging only */ + if (_mesa_getenv("MESA_XSYNC")) { + /* This makes debugging X easier. + * In your debugger, set a breakpoint on _XError to stop when an + * X protocol error is generated. + */ + XSynchronize( display, 1 ); + } +#endif + + v = (XMesaVisual) CALLOC_STRUCT(xmesa_visual); + if (!v) { + return NULL; + } + + v->display = display; + + /* Save a copy of the XVisualInfo struct because the user may X_mesa_free() + * the struct but we may need some of the information contained in it + * at a later time. + */ +#ifndef XFree86Server + v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo)); + if(!v->visinfo) { + _mesa_free(v); + return NULL; + } + MEMCPY(v->visinfo, visinfo, sizeof(*visinfo)); +#endif + + v->ximage_flag = ximage_flag; + +#ifdef XFree86Server + /* We could calculate these values by ourselves. nplanes is either the sum + * of the red, green, and blue bits or the number index bits. + * ColormapEntries is either (1U << index_bits) or + * (1U << max(redBits, greenBits, blueBits)). + */ + assert(visinfo->nplanes > 0); + v->nplanes = visinfo->nplanes; + v->ColormapEntries = visinfo->ColormapEntries; + + v->mesa_visual.redMask = visinfo->redMask; + v->mesa_visual.greenMask = visinfo->greenMask; + v->mesa_visual.blueMask = visinfo->blueMask; + v->mesa_visual.visualID = visinfo->vid; + v->mesa_visual.screen = 0; /* FIXME: What should be done here? */ +#else + v->mesa_visual.redMask = visinfo->red_mask; + v->mesa_visual.greenMask = visinfo->green_mask; + v->mesa_visual.blueMask = visinfo->blue_mask; + v->mesa_visual.visualID = visinfo->visualid; + v->mesa_visual.screen = visinfo->screen; +#endif + +#if defined(XFree86Server) || !(defined(__cplusplus) || defined(c_plusplus)) + v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->class); +#else + v->mesa_visual.visualType = xmesa_convert_from_x_visual_type(visinfo->c_class); +#endif + + v->mesa_visual.visualRating = visualCaveat; + + if (alpha_flag) + v->mesa_visual.alphaBits = 8; + + (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 ); + + { + const int xclass = v->mesa_visual.visualType; + if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { + red_bits = _mesa_bitcount(GET_REDMASK(v)); + green_bits = _mesa_bitcount(GET_GREENMASK(v)); + blue_bits = _mesa_bitcount(GET_BLUEMASK(v)); + } + else { + /* this is an approximation */ + int depth; + depth = GET_VISUAL_DEPTH(v); + red_bits = depth / 3; + depth -= red_bits; + green_bits = depth / 2; + depth -= green_bits; + blue_bits = depth; + alpha_bits = 0; + assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) ); + } + alpha_bits = v->mesa_visual.alphaBits; + } + + _mesa_initialize_visual( &v->mesa_visual, + rgb_flag, db_flag, stereo_flag, + red_bits, green_bits, + blue_bits, alpha_bits, + v->mesa_visual.indexBits, + depth_size, + stencil_size, + accum_red_size, accum_green_size, + accum_blue_size, accum_alpha_size, + 0 ); + + /* XXX minor hack */ + v->mesa_visual.level = level; + return v; +} + + +PUBLIC +void XMesaDestroyVisual( XMesaVisual v ) +{ +#ifndef XFree86Server + _mesa_free(v->visinfo); +#endif + _mesa_free(v); +} + + + +/** + * Create a new XMesaContext. + * \param v the XMesaVisual + * \param share_list another XMesaContext with which to share display + * lists or NULL if no sharing is wanted. + * \return an XMesaContext or NULL if error. + */ +PUBLIC +XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) +{ + static GLboolean firstTime = GL_TRUE; + struct pipe_context *pipe; + XMesaContext c; + GLcontext *mesaCtx; + uint pf; + + if (firstTime) { + _glthread_INIT_MUTEX(_xmesa_lock); + firstTime = GL_FALSE; + } + + /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */ + c = (XMesaContext) CALLOC_STRUCT(xmesa_context); + if (!c) + return NULL; + + pf = choose_pixel_format(v); + assert(pf); + + if (!getenv("XM_AUB")) { + xmesa_mode = XMESA_SOFTPIPE; + pipe = xmesa_create_pipe_context( c, pf ); + } + else { + xmesa_mode = XMESA_AUB; + pipe = xmesa_create_i965simple( xmesa_get_pipe_winsys_aub() ); + } + + c->st = st_create_context(pipe, &v->mesa_visual, + share_list ? share_list->st : NULL); + mesaCtx = c->st->ctx; + c->st->ctx->DriverCtx = c; + +#if 00 + _mesa_enable_sw_extensions(mesaCtx); + _mesa_enable_1_3_extensions(mesaCtx); + _mesa_enable_1_4_extensions(mesaCtx); + _mesa_enable_1_5_extensions(mesaCtx); + _mesa_enable_2_0_extensions(mesaCtx); +#endif + +#ifdef XFree86Server + /* If we're running in the X server, do bounds checking to prevent + * segfaults and server crashes! + */ + mesaCtx->Const.CheckArrayBounds = GL_TRUE; +#endif + + /* finish up xmesa context initializations */ + c->xm_visual = v; + c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ + + c->st->haveFramebufferSurfaces = GL_TRUE; + + return c; +} + + + +PUBLIC +void XMesaDestroyContext( XMesaContext c ) +{ + st_destroy_context(c->st); + _mesa_free(c); +} + + + +/** + * Private function for creating an XMesaBuffer which corresponds to an + * X window or pixmap. + * \param v the window's XMesaVisual + * \param w the window we're wrapping + * \return new XMesaBuffer or NULL if error + */ +PUBLIC XMesaBuffer +XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w) +{ +#ifndef XFree86Server + XWindowAttributes attr; +#endif + XMesaBuffer b; + XMesaColormap cmap; + int depth; + + assert(v); + assert(w); + + /* Check that window depth matches visual depth */ +#ifdef XFree86Server + depth = ((XMesaDrawable)w)->depth; +#else + XGetWindowAttributes( v->display, w, &attr ); + depth = attr.depth; +#endif + if (GET_VISUAL_DEPTH(v) != depth) { + _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", + GET_VISUAL_DEPTH(v), depth); + return NULL; + } + + /* Find colormap */ +#ifdef XFree86Server + cmap = (ColormapPtr)LookupIDByType(wColormap(w), RT_COLORMAP); +#else + if (attr.colormap) { + cmap = attr.colormap; + } + else { + _mesa_warning(NULL, "Window %u has no colormap!\n", (unsigned int) w); + /* this is weird, a window w/out a colormap!? */ + /* OK, let's just allocate a new one and hope for the best */ + cmap = XCreateColormap(v->display, w, attr.visual, AllocNone); + } +#endif + + b = create_xmesa_buffer((XMesaDrawable) w, WINDOW, v, cmap); + if (!b) + return NULL; + + if (!initialize_visual_and_buffer( v, b, v->mesa_visual.rgbMode, + (XMesaDrawable) w, cmap )) { + xmesa_free_buffer(b); + return NULL; + } + + return b; +} + + + +/** + * Create a new XMesaBuffer from an X pixmap. + * + * \param v the XMesaVisual + * \param p the pixmap + * \param cmap the colormap, may be 0 if using a \c GLX_TRUE_COLOR or + * \c GLX_DIRECT_COLOR visual for the pixmap + * \returns new XMesaBuffer or NULL if error + */ +PUBLIC XMesaBuffer +XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap) +{ + XMesaBuffer b; + + assert(v); + + b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap); + if (!b) + return NULL; + + if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, + (XMesaDrawable) p, cmap)) { + xmesa_free_buffer(b); + return NULL; + } + + return b; +} + + +/** + * For GLX_EXT_texture_from_pixmap + */ +XMesaBuffer +XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p, + XMesaColormap cmap, + int format, int target, int mipmap) +{ + GET_CURRENT_CONTEXT(ctx); + XMesaBuffer b; + GLuint width, height; + + assert(v); + + b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap); + if (!b) + return NULL; + + /* get pixmap size, update framebuffer/renderbuffer dims */ + xmesa_get_window_size(v->display, b, &width, &height); + _mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height); + + if (target == 0) { + /* examine dims */ + if (ctx->Extensions.ARB_texture_non_power_of_two) { + target = GLX_TEXTURE_2D_EXT; + } + else if ( _mesa_bitcount(width) == 1 + && _mesa_bitcount(height) == 1) { + /* power of two size */ + if (height == 1) { + target = GLX_TEXTURE_1D_EXT; + } + else { + target = GLX_TEXTURE_2D_EXT; + } + } + else if (ctx->Extensions.NV_texture_rectangle) { + target = GLX_TEXTURE_RECTANGLE_EXT; + } + else { + /* non power of two textures not supported */ + XMesaDestroyBuffer(b); + return 0; + } + } + + b->TextureTarget = target; + b->TextureFormat = format; + b->TextureMipmap = mipmap; + + if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, + (XMesaDrawable) p, cmap)) { + xmesa_free_buffer(b); + return NULL; + } + + return b; +} + + + +XMesaBuffer +XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, + unsigned int width, unsigned int height) +{ +#ifndef XFree86Server + XMesaWindow root; + XMesaDrawable drawable; /* X Pixmap Drawable */ + XMesaBuffer b; + + /* allocate pixmap for front buffer */ + root = RootWindow( v->display, v->visinfo->screen ); + drawable = XCreatePixmap(v->display, root, width, height, + v->visinfo->depth); + if (!drawable) + return NULL; + + b = create_xmesa_buffer(drawable, PBUFFER, v, cmap); + if (!b) + return NULL; + + if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, + drawable, cmap)) { + xmesa_free_buffer(b); + return NULL; + } + + return b; +#else + return 0; +#endif +} + + + +/* + * Deallocate an XMesaBuffer structure and all related info. + */ +PUBLIC void +XMesaDestroyBuffer(XMesaBuffer b) +{ + xmesa_free_buffer(b); +} + + +/** + * Query the current window size and update the corresponding GLframebuffer + * and all attached renderbuffers. + * Called when: + * 1. the first time a buffer is bound to a context. + * 2. from the XMesaResizeBuffers() API function. + * 3. SwapBuffers. XXX probabaly from xm_flush_frontbuffer() too... + * Note: it's possible (and legal) for xmctx to be NULL. That can happen + * when resizing a buffer when no rendering context is bound. + */ +void +xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer) +{ + GLuint width, height; + xmesa_get_window_size(drawBuffer->xm_visual->display, drawBuffer, &width, &height); + st_resize_framebuffer(drawBuffer->stfb, width, height); +} + + +/* + * Bind buffer b to context c and make c the current rendering context. + */ +GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b ) +{ + return XMesaMakeCurrent2( c, b, b ); +} + + +/* + * Bind buffer b to context c and make c the current rendering context. + */ +PUBLIC +GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, + XMesaBuffer readBuffer ) +{ + if (c) { + if (!drawBuffer || !readBuffer) + return GL_FALSE; /* must specify buffers! */ + +#if 0 + /* XXX restore this optimization */ + if (&(c->mesa) == _mesa_get_current_context() + && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer + && c->mesa.ReadBuffer == &readBuffer->mesa_buffer + && xmesa_buffer(c->mesa.DrawBuffer)->wasCurrent) { + /* same context and buffer, do nothing */ + return GL_TRUE; + } +#endif + + c->xm_buffer = drawBuffer; + + /* Call this periodically to detect when the user has begun using + * GL rendering from multiple threads. + */ + _glapi_check_multithread(); + + st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb); + + xmesa_check_and_update_buffer_size(c, drawBuffer); + if (readBuffer != drawBuffer) + xmesa_check_and_update_buffer_size(c, readBuffer); + + /* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */ + drawBuffer->wasCurrent = GL_TRUE; + } + else { + /* Detach */ + st_make_current( NULL, NULL, NULL ); + } + return GL_TRUE; +} + + +/* + * Unbind the context c from its buffer. + */ +GLboolean XMesaUnbindContext( XMesaContext c ) +{ + /* A no-op for XFree86 integration purposes */ + return GL_TRUE; +} + + +XMesaContext XMesaGetCurrentContext( void ) +{ + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + XMesaContext xmesa = xmesa_context(ctx); + return xmesa; + } + else { + return 0; + } +} + + +XMesaBuffer XMesaGetCurrentBuffer( void ) +{ + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + XMesaBuffer xmbuf = xmesa_buffer(ctx->DrawBuffer); + return xmbuf; + } + else { + return 0; + } +} + + +/* New in Mesa 3.1 */ +XMesaBuffer XMesaGetCurrentReadBuffer( void ) +{ + GET_CURRENT_CONTEXT(ctx); + if (ctx) { + return xmesa_buffer(ctx->ReadBuffer); + } + else { + return 0; + } +} + + +#ifdef XFree86Server +PUBLIC +GLboolean XMesaForceCurrent(XMesaContext c) +{ + if (c) { + _glapi_set_dispatch(c->mesa.CurrentDispatch); + + if (&(c->mesa) != _mesa_get_current_context()) { + _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer); + } + } + else { + _mesa_make_current(NULL, NULL, NULL); + } + return GL_TRUE; +} + + +PUBLIC +GLboolean XMesaLoseCurrent(XMesaContext c) +{ + (void) c; + _mesa_make_current(NULL, NULL, NULL); + return GL_TRUE; +} + + +PUBLIC +GLboolean XMesaCopyContext( XMesaContext xm_src, XMesaContext xm_dst, GLuint mask ) +{ + _mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask); + return GL_TRUE; +} +#endif /* XFree86Server */ + + +#ifndef FX +GLboolean XMesaSetFXmode( GLint mode ) +{ + (void) mode; + return GL_FALSE; +} +#endif + + + +/* + * Copy the back buffer to the front buffer. If there's no back buffer + * this is a no-op. + */ +PUBLIC +void XMesaSwapBuffers( XMesaBuffer b ) +{ + struct pipe_surface *surf; + + /* If we're swapping the buffer associated with the current context + * we have to flush any pending rendering commands first. + */ + st_notify_swapbuffers(b->stfb); + + surf = st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT); + if (surf) { + if (xmesa_mode == XMESA_AUB) + xmesa_display_aub( surf ); + else + xmesa_display_surface(b, surf); + } + + xmesa_check_and_update_buffer_size(NULL, b); +} + + + +/* + * Copy sub-region of back buffer to front buffer + */ +void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) +{ + struct pipe_surface *surf_front + = st_get_framebuffer_surface(b->stfb, ST_SURFACE_FRONT_LEFT); + struct pipe_surface *surf_back + = st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT); + struct pipe_context *pipe = NULL; /* XXX fix */ + + if (!surf_front || !surf_back) + return; + + pipe->surface_copy(pipe, + FALSE, + surf_front, x, y, /* dest */ + surf_back, x, y, /* src */ + width, height); +} + + + +/* + * Return the depth buffer associated with an XMesaBuffer. + * Input: b - the XMesa buffer handle + * Output: width, height - size of buffer in pixels + * bytesPerValue - bytes per depth value (2 or 4) + * buffer - pointer to depth buffer values + * Return: GL_TRUE or GL_FALSE to indicate success or failure. + */ +GLboolean XMesaGetDepthBuffer( XMesaBuffer b, GLint *width, GLint *height, + GLint *bytesPerValue, void **buffer ) +{ + *width = 0; + *height = 0; + *bytesPerValue = 0; + *buffer = 0; + return GL_FALSE; +} + + +void XMesaFlush( XMesaContext c ) +{ + if (c && c->xm_visual->display) { +#ifdef XFree86Server + /* NOT_NEEDED */ +#else + XSync( c->xm_visual->display, False ); +#endif + } +} + + + +const char *XMesaGetString( XMesaContext c, int name ) +{ + (void) c; + if (name==XMESA_VERSION) { + return "5.0"; + } + else if (name==XMESA_EXTENSIONS) { + return ""; + } + else { + return NULL; + } +} + + + +XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy, XMesaDrawable d ) +{ + XMesaBuffer b; + for (b=XMesaBufferList; b; b=b->Next) { + if (b->drawable == d && b->xm_visual->display == dpy) { + return b; + } + } + return NULL; +} + + +/** + * Free/destroy all XMesaBuffers associated with given display. + */ +void xmesa_destroy_buffers_on_display(XMesaDisplay *dpy) +{ + XMesaBuffer b, next; + for (b = XMesaBufferList; b; b = next) { + next = b->Next; + if (b->xm_visual->display == dpy) { + xmesa_free_buffer(b); + } + } +} + + +/* + * Look for XMesaBuffers whose X window has been destroyed. + * Deallocate any such XMesaBuffers. + */ +void XMesaGarbageCollect( void ) +{ + XMesaBuffer b, next; + for (b=XMesaBufferList; b; b=next) { + next = b->Next; + if (b->xm_visual && + b->xm_visual->display && + b->drawable && + b->type == WINDOW) { +#ifdef XFree86Server + /* NOT_NEEDED */ +#else + XSync(b->xm_visual->display, False); + if (!window_exists( b->xm_visual->display, b->drawable )) { + /* found a dead window, free the ancillary info */ + XMesaDestroyBuffer( b ); + } +#endif + } + } +} + + +unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y, + GLfloat red, GLfloat green, + GLfloat blue, GLfloat alpha ) +{ + /* no longer supported */ + return 0; +} + + +/* + * This is typically called when the window size changes and we need + * to reallocate the buffer's back/depth/stencil/accum buffers. + */ +PUBLIC void +XMesaResizeBuffers( XMesaBuffer b ) +{ + GET_CURRENT_CONTEXT(ctx); + XMesaContext xmctx = xmesa_context(ctx); + if (!xmctx) + return; + xmesa_check_and_update_buffer_size(xmctx, b); +} + + + + +PUBLIC void +XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer, + const int *attrib_list) +{ +} + + + +PUBLIC void +XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer) +{ +} + diff --git a/src/gallium/winsys/xlib/xm_image.c b/src/gallium/winsys/xlib/xm_image.c new file mode 100644 index 0000000000..087b4e4c3a --- /dev/null +++ b/src/gallium/winsys/xlib/xm_image.c @@ -0,0 +1,133 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Brian Paul + */ + +#include +#include + +#include "glxheader.h" +#include "xmesaP.h" + +#ifdef XFree86Server + +#ifdef ROUNDUP +#undef ROUNDUP +#endif + +#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3)) + +XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height, char *data) +{ + XMesaImage *image; + + image = (XMesaImage *)xalloc(sizeof(XMesaImage)); + + if (image) { + image->width = width; + image->height = height; + image->data = data; + /* Always pad to 32 bits */ + image->bytes_per_line = ROUNDUP((bitsPerPixel * width), 32); + image->bits_per_pixel = bitsPerPixel; + } + + return image; +} + +void XMesaDestroyImage(XMesaImage *image) +{ + if (image->data) + free(image->data); + xfree(image); +} + +unsigned long XMesaGetPixel(XMesaImage *image, int x, int y) +{ + CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line); + CARD8 *i8; + CARD16 *i16; + CARD32 *i32; + switch (image->bits_per_pixel) { + case 8: + i8 = (CARD8 *)row; + return i8[x]; + break; + case 15: + case 16: + i16 = (CARD16 *)row; + return i16[x]; + break; + case 24: /* WARNING: architecture specific code */ + i8 = (CARD8 *)row; + return (((CARD32)i8[x*3]) | + (((CARD32)i8[x*3+1])<<8) | + (((CARD32)i8[x*3+2])<<16)); + break; + case 32: + i32 = (CARD32 *)row; + return i32[x]; + break; + } + return 0; +} + +#ifndef XMESA_USE_PUTPIXEL_MACRO +void XMesaPutPixel(XMesaImage *image, int x, int y, unsigned long pixel) +{ + CARD8 *row = (CARD8 *)(image->data + y*image->bytes_per_line); + CARD8 *i8; + CARD16 *i16; + CARD32 *i32; + switch (image->bits_per_pixel) { + case 8: + i8 = (CARD8 *)row; + i8[x] = (CARD8)pixel; + break; + case 15: + case 16: + i16 = (CARD16 *)row; + i16[x] = (CARD16)pixel; + break; + case 24: /* WARNING: architecture specific code */ + i8 = (CARD8 *)__row; + i8[x*3] = (CARD8)(p); + i8[x*3+1] = (CARD8)(p>>8); + i8[x*3+2] = (CARD8)(p>>16); + case 32: + i32 = (CARD32 *)row; + i32[x] = (CARD32)pixel; + break; + } +} +#endif + +#endif /* XFree86Server */ diff --git a/src/gallium/winsys/xlib/xm_image.h b/src/gallium/winsys/xlib/xm_image.h new file mode 100644 index 0000000000..2a5e0f3777 --- /dev/null +++ b/src/gallium/winsys/xlib/xm_image.h @@ -0,0 +1,77 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Brian Paul + */ + +#ifndef _XM_IMAGE_H_ +#define _XM_IMAGE_H_ + +#define XMESA_USE_PUTPIXEL_MACRO + +extern XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height, + char *data); +extern void XMesaDestroyImage(XMesaImage *image); +extern unsigned long XMesaGetPixel(XMesaImage *image, int x, int y); +#ifdef XMESA_USE_PUTPIXEL_MACRO +#define XMesaPutPixel(__i,__x,__y,__p) \ +{ \ + CARD8 *__row = (CARD8 *)(__i->data + __y*__i->bytes_per_line); \ + CARD8 *__i8; \ + CARD16 *__i16; \ + CARD32 *__i32; \ + switch (__i->bits_per_pixel) { \ + case 8: \ + __i8 = (CARD8 *)__row; \ + __i8[__x] = (CARD8)__p; \ + break; \ + case 15: \ + case 16: \ + __i16 = (CARD16 *)__row; \ + __i16[__x] = (CARD16)__p; \ + break; \ + case 24: /* WARNING: architecture specific code */ \ + __i8 = (CARD8 *)__row; \ + __i8[__x*3] = (CARD8)(__p); \ + __i8[__x*3+1] = (CARD8)(__p>>8); \ + __i8[__x*3+2] = (CARD8)(__p>>16); \ + break; \ + case 32: \ + __i32 = (CARD32 *)__row; \ + __i32[__x] = (CARD32)__p; \ + break; \ + } \ +} +#else +extern void XMesaPutPixel(XMesaImage *image, int x, int y, + unsigned long pixel); +#endif + +#endif /* _XM_IMAGE_H_ */ diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c new file mode 100644 index 0000000000..c3cd22eea3 --- /dev/null +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -0,0 +1,466 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * Brian Paul + */ + + +#include "glxheader.h" +#include "xmesaP.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/softpipe/sp_winsys.h" + +#ifdef GALLIUM_CELL +#include "pipe/cell/ppu/cell_context.h" +#include "pipe/cell/ppu/cell_winsys.h" +#else +#define TILE_SIZE 32 /* avoid compilation errors */ +#endif + +#include "xm_winsys_aub.h" + + +/** + * Low-level OS/window system memory buffer + */ +struct xm_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + + +struct xmesa_surface +{ + struct pipe_surface surface; + + int tileSize; +}; + + +/** + * Derived from softpipe_winsys. + * We just need one extra field which indicates the pixel format to use for + * drawing surfaces so that we're compatible with the XVisual/window format. + */ +struct xmesa_softpipe_winsys +{ + struct softpipe_winsys spws; + enum pipe_format pixelformat; +}; + + + +/** Cast wrapper */ +static INLINE struct xmesa_surface * +xmesa_surface(struct pipe_surface *ps) +{ +// assert(0); + return (struct xmesa_surface *) ps; +} + +/** cast wrapper */ +static INLINE struct xmesa_softpipe_winsys * +xmesa_softpipe_winsys(struct softpipe_winsys *spws) +{ + return (struct xmesa_softpipe_winsys *) spws; +} + +/** + * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque + * buffer pointer... + */ +static INLINE struct xm_buffer * +xm_buffer( struct pipe_buffer *buf ) +{ + return (struct xm_buffer *)buf; +} + + + +/* Most callbacks map direcly onto dri_bufmgr operations: + */ +static void * +xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, + unsigned flags) +{ + struct xm_buffer *xm_buf = xm_buffer(buf); + xm_buf->mapped = xm_buf->data; + return xm_buf->mapped; +} + +static void +xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct xm_buffer *xm_buf = xm_buffer(buf); + xm_buf->mapped = NULL; +} + +static void +xm_buffer_destroy(struct pipe_winsys *pws, + struct pipe_buffer *buf) +{ + struct xm_buffer *oldBuf = xm_buffer(buf); + + if (oldBuf->data) { + if (!oldBuf->userBuffer) + align_free(oldBuf->data); + oldBuf->data = NULL; + } + + free(oldBuf); +} + + +/** + * Display a surface that's in a tiled configuration. That is, all the + * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory. + */ +static void +xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) +{ + XImage *ximage = b->tempImage; + struct xm_buffer *xm_buf = xm_buffer(surf->buffer); + const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE; + uint x, y; + + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + + /* update XImage's fields */ + ximage->width = TILE_SIZE; + ximage->height = TILE_SIZE; + ximage->bytes_per_line = TILE_SIZE * 4; + + for (y = 0; y < surf->height; y += TILE_SIZE) { + for (x = 0; x < surf->width; x += TILE_SIZE) { + int dx = x; + int dy = y; + int tx = x / TILE_SIZE; + int ty = y / TILE_SIZE; + int offset = ty * tilesPerRow + tx; + + offset *= 4 * TILE_SIZE * TILE_SIZE; + + ximage->data = (char *) xm_buf->data + offset; + + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, dx, dy, TILE_SIZE, TILE_SIZE); + } + } +} + + +/** + * Display/copy the image in the surface into the X window specified + * by the XMesaBuffer. + */ +void +xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) +{ + XImage *ximage = b->tempImage; + struct xm_buffer *xm_buf = xm_buffer(surf->buffer); + const struct xmesa_surface *xm_surf + = xmesa_surface((struct pipe_surface *) surf); + + if (xm_surf->tileSize) { + xmesa_display_surface_tiled(b, surf); + return; + } + + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + + /* update XImage's fields */ + ximage->width = surf->width; + ximage->height = surf->height; + ximage->bytes_per_line = surf->pitch * (ximage->bits_per_pixel / 8); + ximage->data = xm_buf->data; + + /* display image in Window */ + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, 0, 0, surf->width, surf->height); +} + + +static void +xm_flush_frontbuffer(struct pipe_winsys *pws, + struct pipe_surface *surf, + void *context_private) +{ + /* The Xlib driver's front color surfaces are actually X Windows so + * this flush is a no-op. + * If we instead did front buffer rendering to a temporary XImage, + * this would be the place to copy the Ximage to the on-screen Window. + */ + XMesaContext xmctx = (XMesaContext) context_private; + xmesa_display_surface(xmctx->xm_buffer, surf); +} + + + +static void +xm_printf(struct pipe_winsys *pws, const char *fmtString, ...) +{ + va_list args; + va_start( args, fmtString ); + vfprintf(stderr, fmtString, args); + va_end( args ); +} + + +static const char * +xm_get_name(struct pipe_winsys *pws) +{ + return "Xlib"; +} + + +static struct pipe_buffer * +xm_buffer_create(struct pipe_winsys *pws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + /* align to 16-byte multiple for Cell */ + buffer->data = align_malloc(size, max(alignment, 16)); + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) +{ + struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +xm_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + +#ifdef GALLIUM_CELL /* XXX a bit of a hack */ + height = round_up(height, TILE_SIZE); +#endif + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + + +/** + * Called via pipe->surface_alloc() to create new surfaces (textures, + * renderbuffers, etc. + */ +static struct pipe_surface * +xm_surface_alloc(struct pipe_winsys *ws) +{ + struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface); + + assert(ws); + + xms->surface.refcount = 1; + xms->surface.winsys = ws; + +#ifdef GALLIUM_CELL + if (!getenv("GALLIUM_NOCELL")) { + xms->tileSize = 32; /** probably temporary */ + } +#endif + + return &xms->surface; +} + + + +static void +xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + + +/** + * Return pointer to a pipe_winsys object. + * For Xlib, this is a singleton object. + * Nothing special for the Xlib driver so no subclassing or anything. + */ +struct pipe_winsys * +xmesa_get_pipe_winsys_aub(void) +{ + static struct pipe_winsys *ws = NULL; + + if (!ws && getenv("XM_AUB")) { + ws = xmesa_create_pipe_winsys_aub(); + } + else if (!ws) { + ws = CALLOC_STRUCT(pipe_winsys); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + */ + ws->buffer_create = xm_buffer_create; + ws->user_buffer_create = xm_user_buffer_create; + ws->buffer_map = xm_buffer_map; + ws->buffer_unmap = xm_buffer_unmap; + ws->buffer_destroy = xm_buffer_destroy; + + ws->surface_alloc = xm_surface_alloc; + ws->surface_alloc_storage = xm_surface_alloc_storage; + ws->surface_release = xm_surface_release; + + ws->flush_frontbuffer = xm_flush_frontbuffer; + ws->printf = xm_printf; + ws->get_name = xm_get_name; + } + + return ws; +} + + +/** + * Called via softpipe_winsys->is_format_supported(). + * This function is only called to test formats for front/back color surfaces. + * The winsys being queried will have been created at glXCreateContext + * time, with a pixel format corresponding to the context's visual. + */ +static boolean +xmesa_is_format_supported(struct softpipe_winsys *sws, + enum pipe_format format) +{ + struct xmesa_softpipe_winsys *xmws = xmesa_softpipe_winsys(sws); + return (format == xmws->pixelformat); +} + + +/** + * Return pointer to a softpipe_winsys object. + */ +static struct softpipe_winsys * +xmesa_get_softpipe_winsys(uint pixelformat) +{ + struct xmesa_softpipe_winsys *xmws + = CALLOC_STRUCT(xmesa_softpipe_winsys); + if (!xmws) + return NULL; + + xmws->spws.is_format_supported = xmesa_is_format_supported; + xmws->pixelformat = pixelformat; + + return &xmws->spws; +} + + +struct pipe_context * +xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) +{ + struct pipe_winsys *pws = xmesa_get_pipe_winsys_aub(); + struct pipe_context *pipe; + +#ifdef GALLIUM_CELL + if (!getenv("GALLIUM_NOCELL")) { + struct cell_winsys *cws = cell_get_winsys(pixelformat); + pipe = cell_create_context(pws, cws); + if (pipe) + pipe->priv = xmesa; + return pipe; + } + else +#endif + { + struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat); + pipe = softpipe_create( pws, spws ); + if (pipe) + pipe->priv = xmesa; + + return pipe; + } +} diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c new file mode 100644 index 0000000000..bf41570257 --- /dev/null +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -0,0 +1,589 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * Brian Paul + */ + + +#include "glxheader.h" +#include "xmesaP.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/i965simple/brw_winsys.h" +#include "brw_aub.h" +#include "xm_winsys_aub.h" + + + +struct aub_buffer { + char *data; + unsigned offset; + unsigned size; + unsigned refcount; + unsigned map_count; + boolean dump_on_unmap; +}; + + + +struct aub_pipe_winsys { + struct pipe_winsys winsys; + + struct brw_aubfile *aubfile; + + /* This is simple, isn't it: + */ + char *pool; + unsigned size; + unsigned used; +}; + + +/* Turn a pipe winsys into an aub/pipe winsys: + */ +static inline struct aub_pipe_winsys * +aub_pipe_winsys( struct pipe_winsys *winsys ) +{ + return (struct aub_pipe_winsys *)winsys; +} + + + +static INLINE struct aub_buffer * +aub_bo( struct pipe_buffer *bo ) +{ + return (struct aub_buffer *)bo; +} + +static INLINE struct pipe_buffer * +pipe_bo( struct aub_buffer *bo ) +{ + return (struct pipe_buffer *)bo; +} + + + + +static void *aub_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags ) +{ + struct aub_buffer *sbo = aub_bo(buf); + + assert(sbo->data); + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + sbo->dump_on_unmap = 1; + + sbo->map_count++; + return sbo->data; +} + +static void aub_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + struct aub_buffer *sbo = aub_bo(buf); + + sbo->map_count--; + + if (sbo->map_count == 0 && + sbo->dump_on_unmap) { + + sbo->dump_on_unmap = 0; + + brw_aub_gtt_data( iws->aubfile, + sbo->offset, + sbo->data, + sbo->size, + 0, + 0); + } +} + + +static void +aub_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + free(buf); +} + + +void xmesa_buffer_subdata_aub(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned long offset, + unsigned long size, + const void *data, + unsigned aub_type, + unsigned aub_sub_type) +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + struct aub_buffer *sbo = aub_bo(buf); + + assert(sbo->size > offset + size); + memcpy(sbo->data + offset, data, size); + + brw_aub_gtt_data( iws->aubfile, + sbo->offset + offset, + sbo->data + offset, + size, + aub_type, + aub_sub_type ); +} + +void xmesa_commands_aub(struct pipe_winsys *winsys, + unsigned *cmds, + unsigned nr_dwords) +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + unsigned size = nr_dwords * 4; + + assert(iws->used + size < iws->size); + + brw_aub_gtt_cmds( iws->aubfile, + AUB_BUF_START + iws->used, + cmds, + nr_dwords * sizeof(int) ); + + iws->used += align(size, 4096); +} + + +static struct aub_pipe_winsys *global_winsys = NULL; + +void xmesa_display_aub( /* struct pipe_winsys *winsys, */ + struct pipe_surface *surface ) +{ +// struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + brw_aub_dump_bmp( global_winsys->aubfile, + surface, + aub_bo(surface->buffer)->offset ); +} + + + +/* Pipe has no concept of pools. We choose the tex/region pool + * for all buffers. + */ +static struct pipe_buffer * +aub_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + struct aub_buffer *sbo = CALLOC_STRUCT(aub_buffer); + + sbo->refcount = 1; + + /* Could reuse buffers that are not referenced in current + * batchbuffer. Can't do that atm, so always reallocate: + */ + assert(iws->used + size < iws->size); + sbo->data = iws->pool + iws->used; + sbo->offset = AUB_BUF_START + iws->used; + iws->used += align(size, 4096); + + sbo->size = size; + + return pipe_bo(sbo); +} + + +static struct pipe_buffer * +aub_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) +{ + struct aub_buffer *sbo; + + /* Lets hope this is meant for upload, not as a result! + */ + sbo = aub_bo(aub_buffer_create( winsys, 0, 0, 0 )); + + sbo->data = ptr; + sbo->size = bytes; + + return pipe_bo(sbo); +} + + +/* The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +aub_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ + xmesa_display_aub( surf ); +} + +static struct pipe_surface * +aub_i915_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); + if (surf) { + surf->refcount = 1; + surf->winsys = winsys; + } + return surf; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +aub_i915_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + +static void +aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + + +static void +aub_printf( struct pipe_winsys *winsys, const char *fmtString, ... ) +{ + va_list args; + va_start( args, fmtString ); + vfprintf(stderr, fmtString, args); + va_end( args ); +} + +static const char * +aub_get_name( struct pipe_winsys *winsys ) +{ + return "Aub/xlib"; +} + +struct pipe_winsys * +xmesa_create_pipe_winsys_aub( void ) +{ + struct aub_pipe_winsys *iws = CALLOC_STRUCT( aub_pipe_winsys ); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + * + * Pipe would be happy with a malloc based memory manager, but + * the SwapBuffers implementation in this winsys driver requires + * that rendering be done to an appropriate _DriBufferObject. + */ + iws->winsys.buffer_create = aub_buffer_create; + iws->winsys.user_buffer_create = aub_user_buffer_create; + iws->winsys.buffer_map = aub_buffer_map; + iws->winsys.buffer_unmap = aub_buffer_unmap; + iws->winsys.buffer_destroy = aub_buffer_destroy; + iws->winsys.flush_frontbuffer = aub_flush_frontbuffer; + iws->winsys.printf = aub_printf; + iws->winsys.get_name = aub_get_name; + + iws->winsys.surface_alloc = aub_i915_surface_alloc; + iws->winsys.surface_alloc_storage = aub_i915_surface_alloc_storage; + iws->winsys.surface_release = aub_i915_surface_release; + + iws->aubfile = brw_aubfile_create(); + iws->size = AUB_BUF_SIZE; + iws->pool = malloc(AUB_BUF_SIZE); + + /* HACK: static copy of this pointer: + */ + assert(global_winsys == NULL); + global_winsys = iws; + + return &iws->winsys; +} + + +void +xmesa_destroy_pipe_winsys_aub( struct pipe_winsys *winsys ) + +{ + struct aub_pipe_winsys *iws = aub_pipe_winsys(winsys); + brw_aub_destroy(iws->aubfile); + free(iws->pool); + free(iws); +} + + + + + + + +#define IWS_BATCHBUFFER_SIZE 1024 + +struct aub_brw_winsys { + struct brw_winsys winsys; /**< batch buffer funcs */ + struct aub_context *aub; + + struct pipe_winsys *pipe_winsys; + + unsigned batch_data[IWS_BATCHBUFFER_SIZE]; + unsigned batch_nr; + unsigned batch_size; + unsigned batch_alloc; +}; + + +/* Turn a i965simple winsys into an aub/i965simple winsys: + */ +static inline struct aub_brw_winsys * +aub_brw_winsys( struct brw_winsys *sws ) +{ + return (struct aub_brw_winsys *)sws; +} + + +/* Simple batchbuffer interface: + */ + +static unsigned *aub_i965_batch_start( struct brw_winsys *sws, + unsigned dwords, + unsigned relocs ) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(sws); + + if (iws->batch_size < iws->batch_nr + dwords) + return NULL; + + iws->batch_alloc = iws->batch_nr + dwords; + return (void *)1; /* not a valid pointer! */ +} + +static void aub_i965_batch_dword( struct brw_winsys *sws, + unsigned dword ) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(sws); + + assert(iws->batch_nr < iws->batch_alloc); + iws->batch_data[iws->batch_nr++] = dword; +} + +static void aub_i965_batch_reloc( struct brw_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta ) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(sws); + + assert(iws->batch_nr < iws->batch_alloc); + iws->batch_data[iws->batch_nr++] = aub_bo(buf)->offset + delta; +} + +static unsigned aub_i965_get_buffer_offset( struct brw_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags ) +{ + return aub_bo(buf)->offset; +} + +static void aub_i965_batch_end( struct brw_winsys *sws ) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(sws); + + assert(iws->batch_nr <= iws->batch_alloc); + iws->batch_alloc = 0; +} + +static void aub_i965_batch_flush( struct brw_winsys *sws, + struct pipe_fence_handle **fence ) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(sws); + assert(iws->batch_nr <= iws->batch_size); + + if (iws->batch_nr) { + xmesa_commands_aub( iws->pipe_winsys, + iws->batch_data, + iws->batch_nr ); + } + + iws->batch_nr = 0; +} + + + +static void aub_i965_buffer_subdata_typed(struct brw_winsys *winsys, + struct pipe_buffer *buf, + unsigned long offset, + unsigned long size, + const void *data, + unsigned data_type) +{ + struct aub_brw_winsys *iws = aub_brw_winsys(winsys); + unsigned aub_type = DW_GENERAL_STATE; + unsigned aub_sub_type; + + switch (data_type) { + case BRW_CC_VP: + aub_sub_type = DWGS_COLOR_CALC_VIEWPORT_STATE; + break; + case BRW_CC_UNIT: + aub_sub_type = DWGS_COLOR_CALC_STATE; + break; + case BRW_WM_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_SAMPLER_DEFAULT_COLOR: + aub_sub_type = DWGS_SAMPLER_DEFAULT_COLOR; + break; + case BRW_SAMPLER: + aub_sub_type = DWGS_SAMPLER_STATE; + break; + case BRW_WM_UNIT: + aub_sub_type = DWGS_WINDOWER_IZ_STATE; + break; + case BRW_SF_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_SF_VP: + aub_sub_type = DWGS_STRIPS_FANS_VIEWPORT_STATE; + break; + case BRW_SF_UNIT: + aub_sub_type = DWGS_STRIPS_FANS_STATE; + break; + case BRW_VS_UNIT: + aub_sub_type = DWGS_VERTEX_SHADER_STATE; + break; + case BRW_VS_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_GS_UNIT: + aub_sub_type = DWGS_GEOMETRY_SHADER_STATE; + break; + case BRW_GS_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_CLIP_VP: + aub_sub_type = DWGS_CLIPPER_VIEWPORT_STATE; + break; + case BRW_CLIP_UNIT: + aub_sub_type = DWGS_CLIPPER_STATE; + break; + case BRW_CLIP_PROG: + aub_sub_type = DWGS_KERNEL_INSTRUCTIONS; + break; + case BRW_SS_SURFACE: + aub_type = DW_SURFACE_STATE; + aub_sub_type = DWSS_SURFACE_STATE; + break; + case BRW_SS_SURF_BIND: + aub_type = DW_SURFACE_STATE; + aub_sub_type = DWSS_BINDING_TABLE_STATE; + break; + case BRW_CONSTANT_BUFFER: + aub_type = DW_CONSTANT_URB_ENTRY; + aub_sub_type = 0; + break; + + default: + assert(0); + break; + } + + xmesa_buffer_subdata_aub( iws->pipe_winsys, + buf, + offset, + size, + data, + aub_type, + aub_sub_type ); +} + +/** + * Create i965 hardware rendering context. + */ +struct pipe_context * +xmesa_create_i965simple( struct pipe_winsys *winsys ) +{ + struct aub_brw_winsys *iws = CALLOC_STRUCT( aub_brw_winsys ); + + /* Fill in this struct with callbacks that i965simple will need to + * communicate with the window system, buffer manager, etc. + */ + iws->winsys.batch_start = aub_i965_batch_start; + iws->winsys.batch_dword = aub_i965_batch_dword; + iws->winsys.batch_reloc = aub_i965_batch_reloc; + iws->winsys.batch_end = aub_i965_batch_end; + iws->winsys.batch_flush = aub_i965_batch_flush; + iws->winsys.buffer_subdata_typed = aub_i965_buffer_subdata_typed; + iws->winsys.get_buffer_offset = aub_i965_get_buffer_offset; + + iws->pipe_winsys = winsys; + + iws->batch_size = IWS_BATCHBUFFER_SIZE; + + /* Create the i965simple context: + */ + return brw_create( winsys, + &iws->winsys, + 0 ); +} diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.h b/src/gallium/winsys/xlib/xm_winsys_aub.h new file mode 100644 index 0000000000..7bee199116 --- /dev/null +++ b/src/gallium/winsys/xlib/xm_winsys_aub.h @@ -0,0 +1,67 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef AUB_WINSYS_H +#define AUB_WINSYS_H + +struct pipe_context; +struct pipe_winsys; +struct pipe_buffer; +struct pipe_surface; + +struct pipe_winsys * +xmesa_create_pipe_winsys_aub( void ); + +void +xmesa_destroy_pipe_winsys_aub( struct pipe_winsys *winsys ); + + + +struct pipe_context * +xmesa_create_i965simple( struct pipe_winsys *winsys ); + + + +void xmesa_buffer_subdata_aub(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned long offset, + unsigned long size, + const void *data, + unsigned aub_type, + unsigned aub_sub_type); + +void xmesa_commands_aub(struct pipe_winsys *winsys, + unsigned *cmds, + unsigned nr_dwords); + + +void xmesa_display_aub( /* struct pipe_winsys *winsys, */ + struct pipe_surface *surface ); + +struct pipe_winsys *xmesa_get_pipe_winsys_aub(void); + +#endif diff --git a/src/gallium/winsys/xlib/xmesaP.h b/src/gallium/winsys/xlib/xmesaP.h new file mode 100644 index 0000000000..fa8d1f14b9 --- /dev/null +++ b/src/gallium/winsys/xlib/xmesaP.h @@ -0,0 +1,176 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef XMESAP_H +#define XMESAP_H + + +#include "GL/xmesa.h" +#include "mtypes.h" +#ifdef XFree86Server +#include "xm_image.h" +#endif + +#include "state_tracker/st_context.h" +#include "state_tracker/st_public.h" + + +extern _glthread_Mutex _xmesa_lock; + +extern XMesaBuffer XMesaBufferList; + +/* + */ +#define XMESA_SOFTPIPE 1 +#define XMESA_AUB 2 +extern int xmesa_mode; + + +/** + * Visual inforation, derived from GLvisual. + * Basically corresponds to an XVisualInfo. + */ +struct xmesa_visual { + GLvisual mesa_visual; /* Device independent visual parameters */ + XMesaDisplay *display; /* The X11 display */ +#ifdef XFree86Server + GLint ColormapEntries; + GLint nplanes; +#else + XMesaVisualInfo visinfo; /* X's visual info (pointer to private copy) */ + XVisualInfo *vishandle; /* Only used in fakeglx.c */ +#endif + GLint BitsPerPixel; /* True bits per pixel for XImages */ + + GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */ +}; + + +/** + * Context info, derived from st_context. + * Basically corresponds to a GLXContext. + */ +struct xmesa_context { + struct st_context *st; + XMesaVisual xm_visual; /** pixel format info */ + XMesaBuffer xm_buffer; /** current drawbuffer */ +}; + + +/** + * Types of X/GLX drawables we might render into. + */ +typedef enum { + WINDOW, /* An X window */ + GLXWINDOW, /* GLX window */ + PIXMAP, /* GLX pixmap */ + PBUFFER /* GLX Pbuffer */ +} BufferType; + + +/** + * Framebuffer information, derived from. + * Basically corresponds to a GLXDrawable. + */ +struct xmesa_buffer { + struct st_framebuffer *stfb; + + GLboolean wasCurrent; /* was ever the current buffer? */ + XMesaVisual xm_visual; /* the X/Mesa visual */ + XMesaDrawable drawable; /* Usually the X window ID */ + XMesaColormap cmap; /* the X colormap */ + BufferType type; /* window, pixmap, pbuffer or glxwindow */ + + XMesaImage *tempImage; + unsigned long selectedEvents;/* for pbuffers only */ + + GLuint shm; /* X Shared Memory extension status: */ + /* 0 = not available */ + /* 1 = XImage support available */ + /* 2 = Pixmap support available too */ +#if defined(USE_XSHM) && !defined(XFree86Server) + XShmSegmentInfo shminfo; +#endif + + XMesaGC gc; /* scratch GC for span, line, tri drawing */ + + /* GLX_EXT_texture_from_pixmap */ + GLint TextureTarget; /** GLX_TEXTURE_1D_EXT, for example */ + GLint TextureFormat; /** GLX_TEXTURE_FORMAT_RGB_EXT, for example */ + GLint TextureMipmap; /** 0 or 1 */ + + struct xmesa_buffer *Next; /* Linked list pointer: */ +}; + + + +/** cast wrapper */ +static INLINE XMesaContext +xmesa_context(GLcontext *ctx) +{ + return (XMesaContext) ctx->DriverCtx; +} + + +/** cast wrapper */ +static INLINE XMesaBuffer +xmesa_buffer(GLframebuffer *fb) +{ + struct st_framebuffer *stfb = (struct st_framebuffer *) fb; + return (XMesaBuffer) st_framebuffer_private(stfb); +} + + +extern void +xmesa_delete_framebuffer(struct gl_framebuffer *fb); + +extern XMesaBuffer +xmesa_find_buffer(XMesaDisplay *dpy, XMesaColormap cmap, XMesaBuffer notThis); + +extern void +xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer); + +extern void +xmesa_destroy_buffers_on_display(XMesaDisplay *dpy); + +extern struct pipe_context * +xmesa_create_pipe_context(XMesaContext xm, uint pixelformat); + +static INLINE GLuint +xmesa_buffer_width(XMesaBuffer b) +{ + return b->stfb->Base.Width; +} + +static INLINE GLuint +xmesa_buffer_height(XMesaBuffer b) +{ + return b->stfb->Base.Height; +} + +extern void +xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf); + +#endif -- cgit v1.2.3 From 6acd63a4980951727939c0dd545a0324965b3834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Feb 2008 17:50:12 +0900 Subject: Code reorganization: update build. Update the Makefiles and includes for the new paths. Note that there hasn't been no separation of the Makefiles yet, and make is jumping all over the place. That will be taken care shortly. But for now, make should work. It was tested with linux and linux-dri. Linux-cell and linux-llvm might require some minor tweaks. --- src/gallium/Makefile | 12 +-- src/gallium/Makefile.template | 7 +- src/gallium/aux/Makefile | 24 +++++ src/gallium/aux/draw/draw_private.h | 2 +- src/gallium/aux/draw/draw_vertex.c | 4 +- src/gallium/aux/draw/draw_vertex_shader.c | 4 +- src/gallium/aux/llvm/Makefile | 4 +- src/gallium/aux/llvm/gallivm.cpp | 4 +- src/gallium/aux/llvm/gallivm_cpu.cpp | 4 +- src/gallium/aux/llvm/tgsitollvm.cpp | 10 +- src/gallium/aux/pipebuffer/Makefile | 2 +- src/gallium/aux/tgsi/exec/tgsi_exec.c | 4 +- src/gallium/aux/tgsi/exec/tgsi_sse2.c | 4 +- src/gallium/aux/tgsi/util/tgsi_transform.h | 4 +- src/gallium/drivers/Makefile | 24 +++++ src/gallium/drivers/cell/ppu/Makefile | 7 +- src/gallium/drivers/cell/ppu/cell_clear.c | 2 +- src/gallium/drivers/cell/ppu/cell_context.c | 6 +- src/gallium/drivers/cell/ppu/cell_context.h | 6 +- src/gallium/drivers/cell/ppu/cell_draw_arrays.c | 2 +- src/gallium/drivers/cell/ppu/cell_flush.c | 2 +- src/gallium/drivers/cell/ppu/cell_render.c | 2 +- src/gallium/drivers/cell/ppu/cell_spu.c | 2 +- src/gallium/drivers/cell/ppu/cell_spu.h | 2 +- src/gallium/drivers/cell/ppu/cell_state_blend.c | 2 +- src/gallium/drivers/cell/ppu/cell_state_clip.c | 2 +- src/gallium/drivers/cell/ppu/cell_state_derived.c | 4 +- src/gallium/drivers/cell/ppu/cell_state_fs.c | 8 +- .../drivers/cell/ppu/cell_state_rasterizer.c | 2 +- src/gallium/drivers/cell/ppu/cell_state_sampler.c | 2 +- src/gallium/drivers/cell/ppu/cell_state_vertex.c | 2 +- src/gallium/drivers/cell/ppu/cell_surface.c | 2 +- src/gallium/drivers/cell/ppu/cell_vbuf.c | 2 +- src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 6 +- src/gallium/drivers/cell/spu/Makefile | 6 +- src/gallium/drivers/cell/spu/spu_exec.c | 4 +- src/gallium/drivers/cell/spu/spu_exec.h | 2 +- src/gallium/drivers/cell/spu/spu_main.c | 2 +- src/gallium/drivers/cell/spu/spu_main.h | 4 +- src/gallium/drivers/cell/spu/spu_render.c | 2 +- src/gallium/drivers/cell/spu/spu_render.h | 2 +- src/gallium/drivers/cell/spu/spu_tile.h | 2 +- src/gallium/drivers/cell/spu/spu_util.c | 4 +- src/gallium/drivers/cell/spu/spu_vertex_shader.c | 6 +- src/gallium/drivers/failover/Makefile | 2 +- src/gallium/drivers/i915simple/Makefile | 2 +- src/gallium/drivers/i915simple/i915_context.c | 2 +- src/gallium/drivers/i915simple/i915_context.h | 2 +- .../drivers/i915simple/i915_fpc_translate.c | 4 +- src/gallium/drivers/i915simple/i915_prim_emit.c | 2 +- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 2 +- src/gallium/drivers/i915simple/i915_state.c | 2 +- .../drivers/i915simple/i915_state_derived.c | 4 +- src/gallium/drivers/i915simple/i915_strings.c | 2 +- src/gallium/drivers/i915simple/i915_surface.c | 2 +- src/gallium/drivers/i965simple/Makefile | 2 +- src/gallium/drivers/i965simple/brw_shader_info.c | 2 +- src/gallium/drivers/i965simple/brw_state.c | 2 +- src/gallium/drivers/i965simple/brw_strings.c | 2 +- src/gallium/drivers/i965simple/brw_surface.c | 2 +- src/gallium/drivers/i965simple/brw_vs_emit.c | 2 +- src/gallium/drivers/i965simple/brw_wm_decl.c | 2 +- src/gallium/drivers/i965simple/brw_wm_glsl.c | 2 +- src/gallium/drivers/softpipe/Makefile | 2 +- src/gallium/drivers/softpipe/sp_context.c | 2 +- src/gallium/drivers/softpipe/sp_context.h | 2 +- src/gallium/drivers/softpipe/sp_draw_arrays.c | 2 +- src/gallium/drivers/softpipe/sp_flush.c | 2 +- src/gallium/drivers/softpipe/sp_headers.h | 2 +- src/gallium/drivers/softpipe/sp_prim_setup.c | 4 +- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 6 +- src/gallium/drivers/softpipe/sp_quad_fs.c | 2 +- src/gallium/drivers/softpipe/sp_query.c | 2 +- src/gallium/drivers/softpipe/sp_state_clip.c | 2 +- src/gallium/drivers/softpipe/sp_state_derived.c | 6 +- src/gallium/drivers/softpipe/sp_state_fs.c | 8 +- src/gallium/drivers/softpipe/sp_state_rasterizer.c | 2 +- src/gallium/drivers/softpipe/sp_state_sampler.c | 4 +- src/gallium/drivers/softpipe/sp_state_vertex.c | 2 +- src/gallium/drivers/softpipe/sp_surface.c | 2 +- src/gallium/drivers/softpipe/sp_tex_sample.c | 2 +- src/gallium/drivers/softpipe/sp_tile_cache.c | 2 +- src/gallium/winsys/dri/Makefile | 38 +++++++ src/gallium/winsys/dri/Makefile.template | 113 +++++++++++++++++++++ src/gallium/winsys/dri/intel/Makefile | 8 +- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 2 +- .../winsys/dri/intel/intel_winsys_softpipe.c | 2 +- src/gallium/winsys/xlib/xm_winsys.c | 6 +- src/gallium/winsys/xlib/xm_winsys_aub.c | 2 +- 89 files changed, 341 insertions(+), 138 deletions(-) create mode 100644 src/gallium/aux/Makefile create mode 100644 src/gallium/drivers/Makefile create mode 100644 src/gallium/winsys/dri/Makefile create mode 100644 src/gallium/winsys/dri/Makefile.template (limited to 'src/gallium') diff --git a/src/gallium/Makefile b/src/gallium/Makefile index d880d090c1..a13b9a52d3 100644 --- a/src/gallium/Makefile +++ b/src/gallium/Makefile @@ -1,16 +1,8 @@ -TOP = ../../.. +TOP = ../.. include $(TOP)/configs/current -ifeq ($(CONFIG_NAME), linux-cell) -CELL_DIR = cell -endif - -ifeq ($(CONFIG_NAME), linux-llvm) -LLVM_DIR = llvm -endif - -SUBDIRS = softpipe i915simple i965simple failover pipebuffer $(CELL_DIR) $(LLVM_DIR) +SUBDIRS = aux drivers default: subdirs diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 8e84f8eb2d..0717ed8dd2 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -15,7 +15,10 @@ OBJECTS = $(C_SOURCES:.c=.o) \ ### Include directories INCLUDES = \ -I. \ - -I$(TOP)/src/mesa/pipe \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/include/pipe \ + -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/mesa \ -I$(TOP)/include \ $(DRIVER_INCLUDES) @@ -38,7 +41,7 @@ INCLUDES = \ default: depend symlinks $(LIBNAME) -$(LIBNAME): $(OBJECTS) Makefile $(TOP)/src/mesa/pipe/Makefile.template +$(LIBNAME): $(OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) diff --git a/src/gallium/aux/Makefile b/src/gallium/aux/Makefile new file mode 100644 index 0000000000..da68498aa1 --- /dev/null +++ b/src/gallium/aux/Makefile @@ -0,0 +1,24 @@ +TOP = ../../.. +include $(TOP)/configs/current + + +ifeq ($(CONFIG_NAME), linux-llvm) +LLVM_DIR = llvm +endif + +SUBDIRS = pipebuffer $(LLVM_DIR) + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` diff --git a/src/gallium/aux/draw/draw_private.h b/src/gallium/aux/draw/draw_private.h index b17eaaed65..3d09aef87c 100644 --- a/src/gallium/aux/draw/draw_private.h +++ b/src/gallium/aux/draw/draw_private.h @@ -45,7 +45,7 @@ #include "pipe/p_defines.h" #include "x86/rtasm/x86sse.h" -#include "pipe/tgsi/exec/tgsi_exec.h" +#include "tgsi/exec/tgsi_exec.h" struct gallivm_prog; diff --git a/src/gallium/aux/draw/draw_vertex.c b/src/gallium/aux/draw/draw_vertex.c index 2d6592150f..daf1ef4b80 100644 --- a/src/gallium/aux/draw/draw_vertex.c +++ b/src/gallium/aux/draw/draw_vertex.c @@ -34,8 +34,8 @@ */ -#include "pipe/draw/draw_private.h" -#include "pipe/draw/draw_vertex.h" +#include "draw/draw_private.h" +#include "draw/draw_vertex.h" /** diff --git a/src/gallium/aux/draw/draw_vertex_shader.c b/src/gallium/aux/draw/draw_vertex_shader.c index c824c1407e..377ecbb931 100644 --- a/src/gallium/aux/draw/draw_vertex_shader.c +++ b/src/gallium/aux/draw/draw_vertex_shader.c @@ -34,13 +34,13 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #if defined(__i386__) || defined(__386__) -#include "pipe/tgsi/exec/tgsi_sse2.h" +#include "tgsi/exec/tgsi_sse2.h" #endif #include "draw_private.h" #include "draw_context.h" #include "x86/rtasm/x86sse.h" -#include "pipe/llvm/gallivm.h" +#include "llvm/gallivm.h" #define DBG_VS 0 diff --git a/src/gallium/aux/llvm/Makefile b/src/gallium/aux/llvm/Makefile index 9c6e16d86b..e6ac399d08 100644 --- a/src/gallium/aux/llvm/Makefile +++ b/src/gallium/aux/llvm/Makefile @@ -30,7 +30,9 @@ OBJECTS = $(C_SOURCES:.c=.o) \ ### Include directories INCLUDES = \ -I. \ - -I$(TOP)/src/mesa/pipe \ + -I$(TOP)/src/gallium/drivers + -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/include \ -I$(TOP)/src/mesa \ -I$(TOP)/include diff --git a/src/gallium/aux/llvm/gallivm.cpp b/src/gallium/aux/llvm/gallivm.cpp index da0105c2c9..d14bb3b99a 100644 --- a/src/gallium/aux/llvm/gallivm.cpp +++ b/src/gallium/aux/llvm/gallivm.cpp @@ -42,8 +42,8 @@ #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/exec/tgsi_exec.h" -#include "pipe/tgsi/util/tgsi_dump.h" +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_dump.h" #include #include diff --git a/src/gallium/aux/llvm/gallivm_cpu.cpp b/src/gallium/aux/llvm/gallivm_cpu.cpp index dc4d92a72a..8f9830d0b1 100644 --- a/src/gallium/aux/llvm/gallivm_cpu.cpp +++ b/src/gallium/aux/llvm/gallivm_cpu.cpp @@ -42,8 +42,8 @@ #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/exec/tgsi_exec.h" -#include "pipe/tgsi/util/tgsi_dump.h" +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_dump.h" #include #include diff --git a/src/gallium/aux/llvm/tgsitollvm.cpp b/src/gallium/aux/llvm/tgsitollvm.cpp index 0de595e678..2cb4acce32 100644 --- a/src/gallium/aux/llvm/tgsitollvm.cpp +++ b/src/gallium/aux/llvm/tgsitollvm.cpp @@ -10,11 +10,11 @@ #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_parse.h" -#include "pipe/tgsi/exec/tgsi_exec.h" -#include "pipe/tgsi/util/tgsi_util.h" -#include "pipe/tgsi/util/tgsi_build.h" -#include "pipe/tgsi/util/tgsi_dump.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_util.h" +#include "tgsi/util/tgsi_build.h" +#include "tgsi/util/tgsi_dump.h" #include diff --git a/src/gallium/aux/pipebuffer/Makefile b/src/gallium/aux/pipebuffer/Makefile index 75764a9a18..588629e870 100644 --- a/src/gallium/aux/pipebuffer/Makefile +++ b/src/gallium/aux/pipebuffer/Makefile @@ -17,7 +17,7 @@ C_SOURCES = \ ASM_SOURCES = -include ../Makefile.template +include ../../Makefile.template symlinks: diff --git a/src/gallium/aux/tgsi/exec/tgsi_exec.c b/src/gallium/aux/tgsi/exec/tgsi_exec.c index 37e6007068..a8f64c2287 100644 --- a/src/gallium/aux/tgsi/exec/tgsi_exec.c +++ b/src/gallium/aux/tgsi/exec/tgsi_exec.c @@ -54,8 +54,8 @@ #include "pipe/p_state.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_parse.h" -#include "pipe/tgsi/util/tgsi_util.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" #include "tgsi_exec.h" #define TILE_TOP_LEFT 0 diff --git a/src/gallium/aux/tgsi/exec/tgsi_sse2.c b/src/gallium/aux/tgsi/exec/tgsi_sse2.c index 1e56e4afb6..593464db3e 100755 --- a/src/gallium/aux/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/aux/tgsi/exec/tgsi_sse2.c @@ -27,8 +27,8 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_parse.h" -#include "pipe/tgsi/util/tgsi_util.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" #include "tgsi_exec.h" #include "tgsi_sse2.h" diff --git a/src/gallium/aux/tgsi/util/tgsi_transform.h b/src/gallium/aux/tgsi/util/tgsi_transform.h index 365d8c298c..fcf85d603b 100644 --- a/src/gallium/aux/tgsi/util/tgsi_transform.h +++ b/src/gallium/aux/tgsi/util/tgsi_transform.h @@ -31,8 +31,8 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_parse.h" -#include "pipe/tgsi/util/tgsi_build.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_build.h" diff --git a/src/gallium/drivers/Makefile b/src/gallium/drivers/Makefile new file mode 100644 index 0000000000..c0345a9cb5 --- /dev/null +++ b/src/gallium/drivers/Makefile @@ -0,0 +1,24 @@ +TOP = ../../.. +include $(TOP)/configs/current + + +ifeq ($(CONFIG_NAME), linux-cell) +CELL_DIR = cell +endif + +SUBDIRS = softpipe i915simple i965simple failover pipebuffer $(CELL_DIR) + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index 50060f5cd3..011863c11e 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -40,8 +40,11 @@ SOURCES = \ OBJECTS = $(SOURCES:.c=.o) \ -INCLUDE_DIRS = -I$(TOP)/src/mesa - +INCLUDE_DIRS = \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/drivers .c.o: $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c index 07b908eec5..e588a30d5b 100644 --- a/src/gallium/drivers/cell/ppu/cell_clear.c +++ b/src/gallium/drivers/cell/ppu/cell_clear.c @@ -35,7 +35,7 @@ #include #include "pipe/p_inlines.h" #include "pipe/p_util.h" -#include "pipe/cell/common.h" +#include "cell/common.h" #include "cell_clear.h" #include "cell_context.h" #include "cell_batch.h" diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index bbe1fd7a11..e1eb22f468 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -37,9 +37,9 @@ #include "pipe/p_format.h" #include "pipe/p_util.h" #include "pipe/p_winsys.h" -#include "pipe/cell/common.h" -#include "pipe/draw/draw_context.h" -#include "pipe/draw/draw_private.h" +#include "cell/common.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" #include "cell_clear.h" #include "cell_context.h" #include "cell_draw_arrays.h" diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 3b63419b5e..6196c0c72f 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -32,10 +32,10 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/draw/draw_vertex.h" -#include "pipe/draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_vbuf.h" #include "cell_winsys.h" -#include "pipe/cell/common.h" +#include "cell/common.h" struct cell_vbuf_render; diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index 717cd8370f..f12613649b 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -39,7 +39,7 @@ #include "cell_draw_arrays.h" #include "cell_state.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c index f62bc4650c..20f27531fc 100644 --- a/src/gallium/drivers/cell/ppu/cell_flush.c +++ b/src/gallium/drivers/cell/ppu/cell_flush.c @@ -31,7 +31,7 @@ #include "cell_flush.h" #include "cell_spu.h" #include "cell_render.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" void diff --git a/src/gallium/drivers/cell/ppu/cell_render.c b/src/gallium/drivers/cell/ppu/cell_render.c index 4ab277a4b2..b663b37622 100644 --- a/src/gallium/drivers/cell/ppu/cell_render.c +++ b/src/gallium/drivers/cell/ppu/cell_render.c @@ -34,7 +34,7 @@ #include "cell_render.h" #include "cell_spu.h" #include "pipe/p_util.h" -#include "pipe/draw/draw_private.h" +#include "draw/draw_private.h" struct render_stage { diff --git a/src/gallium/drivers/cell/ppu/cell_spu.c b/src/gallium/drivers/cell/ppu/cell_spu.c index 7c83a47e57..419e74dc40 100644 --- a/src/gallium/drivers/cell/ppu/cell_spu.c +++ b/src/gallium/drivers/cell/ppu/cell_spu.c @@ -31,7 +31,7 @@ #include "cell_spu.h" #include "pipe/p_format.h" #include "pipe/p_state.h" -#include "pipe/cell/common.h" +#include "cell/common.h" /* diff --git a/src/gallium/drivers/cell/ppu/cell_spu.h b/src/gallium/drivers/cell/ppu/cell_spu.h index 19eff94f96..137f26612e 100644 --- a/src/gallium/drivers/cell/ppu/cell_spu.h +++ b/src/gallium/drivers/cell/ppu/cell_spu.h @@ -31,7 +31,7 @@ #include #include -#include "pipe/cell/common.h" +#include "cell/common.h" #include "cell_context.h" diff --git a/src/gallium/drivers/cell/ppu/cell_state_blend.c b/src/gallium/drivers/cell/ppu/cell_state_blend.c index 4fc60548c8..b6d6d71f0c 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_blend.c +++ b/src/gallium/drivers/cell/ppu/cell_state_blend.c @@ -29,7 +29,7 @@ */ #include "pipe/p_util.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" #include "cell_context.h" #include "cell_state.h" diff --git a/src/gallium/drivers/cell/ppu/cell_state_clip.c b/src/gallium/drivers/cell/ppu/cell_state_clip.c index 4f43665941..0482f87e88 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_clip.c +++ b/src/gallium/drivers/cell/ppu/cell_state_clip.c @@ -30,7 +30,7 @@ #include "cell_context.h" #include "cell_state.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" void cell_set_clip_state( struct pipe_context *pipe, diff --git a/src/gallium/drivers/cell/ppu/cell_state_derived.c b/src/gallium/drivers/cell/ppu/cell_state_derived.c index 56daf5dfde..0c46829258 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_derived.c +++ b/src/gallium/drivers/cell/ppu/cell_state_derived.c @@ -27,8 +27,8 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "pipe/draw/draw_context.h" -#include "pipe/draw/draw_vertex.h" +#include "draw/draw_context.h" +#include "draw/draw_vertex.h" #include "cell_context.h" #include "cell_batch.h" #include "cell_state.h" diff --git a/src/gallium/drivers/cell/ppu/cell_state_fs.c b/src/gallium/drivers/cell/ppu/cell_state_fs.c index 3f46a87d18..b2ed699a5b 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_fs.c +++ b/src/gallium/drivers/cell/ppu/cell_state_fs.c @@ -29,12 +29,12 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" #if 0 #include "pipe/p_shader_tokens.h" -#include "pipe/llvm/gallivm.h" -#include "pipe/tgsi/util/tgsi_dump.h" -#include "pipe/tgsi/exec/tgsi_sse2.h" +#include "llvm/gallivm.h" +#include "tgsi/util/tgsi_dump.h" +#include "tgsi/exec/tgsi_sse2.h" #endif #include "cell_context.h" diff --git a/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c b/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c index d8128ece54..7eca5b5765 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c +++ b/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c @@ -27,7 +27,7 @@ #include "pipe/p_defines.h" #include "pipe/p_util.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" #include "cell_context.h" #include "cell_state.h" diff --git a/src/gallium/drivers/cell/ppu/cell_state_sampler.c b/src/gallium/drivers/cell/ppu/cell_state_sampler.c index ade6cc8338..a33421a4ad 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_sampler.c +++ b/src/gallium/drivers/cell/ppu/cell_state_sampler.c @@ -30,7 +30,7 @@ */ #include "pipe/p_util.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" #include "cell_context.h" #include "cell_state.h" #include "cell_texture.h" diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c index 0f01e920f9..563831b62d 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c +++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c @@ -32,7 +32,7 @@ #include "cell_context.h" #include "cell_state.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" void diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c index fca93e4742..a35db0ef99 100644 --- a/src/gallium/drivers/cell/ppu/cell_surface.c +++ b/src/gallium/drivers/cell/ppu/cell_surface.c @@ -29,7 +29,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "pipe/util/p_tile.h" +#include "util/p_tile.h" #include "cell_context.h" #include "cell_surface.h" diff --git a/src/gallium/drivers/cell/ppu/cell_vbuf.c b/src/gallium/drivers/cell/ppu/cell_vbuf.c index e9fafe492e..cc727ff4ed 100644 --- a/src/gallium/drivers/cell/ppu/cell_vbuf.c +++ b/src/gallium/drivers/cell/ppu/cell_vbuf.c @@ -36,7 +36,7 @@ #include "cell_flush.h" #include "cell_spu.h" #include "cell_vbuf.h" -#include "pipe/draw/draw_vbuf.h" +#include "draw/draw_vbuf.h" /** Allow vertex data to be inlined after RENDER command */ diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index 80dd500b34..0ba4506505 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -38,9 +38,9 @@ #include "cell_spu.h" #include "cell_batch.h" -#include "pipe/cell/common.h" -#include "pipe/draw/draw_context.h" -#include "pipe/draw/draw_private.h" +#include "cell/common.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" /** * Run the vertex shader on all vertices in the vertex queue. diff --git a/src/gallium/drivers/cell/spu/Makefile b/src/gallium/drivers/cell/spu/Makefile index f202971d73..7aa947299e 100644 --- a/src/gallium/drivers/cell/spu/Makefile +++ b/src/gallium/drivers/cell/spu/Makefile @@ -31,7 +31,11 @@ SPU_OBJECTS = $(SOURCES:.c=.o) \ SPU_ASM_OUT = $(SOURCES:.c=.s) \ -INCLUDE_DIRS = -I$(TOP)/src/mesa +INCLUDE_DIRS = \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/drivers .c.o: diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index e51008b9b3..109540b1f7 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -67,8 +67,8 @@ #include "pipe/p_state.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_parse.h" -#include "pipe/tgsi/util/tgsi_util.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" #include "spu_exec.h" #include "spu_main.h" #include "spu_vertex_shader.h" diff --git a/src/gallium/drivers/cell/spu/spu_exec.h b/src/gallium/drivers/cell/spu/spu_exec.h index b4c7661ef6..3e17c490d2 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.h +++ b/src/gallium/drivers/cell/spu/spu_exec.h @@ -29,7 +29,7 @@ #define SPU_EXEC_H #include "pipe/p_compiler.h" -#include "pipe/tgsi/exec/tgsi_exec.h" +#include "tgsi/exec/tgsi_exec.h" #if defined __cplusplus extern "C" { diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index e375197fe6..1e7243b863 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -38,7 +38,7 @@ #include "spu_tile.h" //#include "spu_test.h" #include "spu_vertex_shader.h" -#include "pipe/cell/common.h" +#include "cell/common.h" #include "pipe/p_defines.h" diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index 1710a17512..5c95d112ac 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -31,8 +31,8 @@ #include -#include "pipe/cell/common.h" -#include "pipe/draw/draw_vertex.h" +#include "cell/common.h" +#include "draw/draw_vertex.h" #include "pipe/p_state.h" diff --git a/src/gallium/drivers/cell/spu/spu_render.c b/src/gallium/drivers/cell/spu/spu_render.c index 932fb500b3..20e77aa2e6 100644 --- a/src/gallium/drivers/cell/spu/spu_render.c +++ b/src/gallium/drivers/cell/spu/spu_render.c @@ -34,7 +34,7 @@ #include "spu_render.h" #include "spu_tri.h" #include "spu_tile.h" -#include "pipe/cell/common.h" +#include "cell/common.h" diff --git a/src/gallium/drivers/cell/spu/spu_render.h b/src/gallium/drivers/cell/spu/spu_render.h index fbcdc5ec31..493434f087 100644 --- a/src/gallium/drivers/cell/spu/spu_render.h +++ b/src/gallium/drivers/cell/spu/spu_render.h @@ -29,7 +29,7 @@ #ifndef SPU_RENDER_H #define SPU_RENDER_H -#include "pipe/cell/common.h" +#include "cell/common.h" extern void cmd_render(const struct cell_command_render *render, uint *pos_incr); diff --git a/src/gallium/drivers/cell/spu/spu_tile.h b/src/gallium/drivers/cell/spu/spu_tile.h index e53340a55a..3105b848fd 100644 --- a/src/gallium/drivers/cell/spu/spu_tile.h +++ b/src/gallium/drivers/cell/spu/spu_tile.h @@ -32,7 +32,7 @@ #include #include #include "spu_main.h" -#include "pipe/cell/common.h" +#include "cell/common.h" diff --git a/src/gallium/drivers/cell/spu/spu_util.c b/src/gallium/drivers/cell/spu/spu_util.c index ac373240c1..ea4274a0a7 100644 --- a/src/gallium/drivers/cell/spu/spu_util.c +++ b/src/gallium/drivers/cell/spu/spu_util.c @@ -1,8 +1,8 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_parse.h" //#include "tgsi_build.h" -#include "pipe/tgsi/util/tgsi_util.h" +#include "tgsi/util/tgsi_util.h" unsigned tgsi_util_get_src_register_swizzle( diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c index c1cbbb6d1e..3f5bf41aa2 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c @@ -39,9 +39,9 @@ #include "pipe/p_shader_tokens.h" #include "spu_vertex_shader.h" #include "spu_exec.h" -#include "pipe/draw/draw_private.h" -#include "pipe/draw/draw_context.h" -#include "pipe/cell/common.h" +#include "draw/draw_private.h" +#include "draw/draw_context.h" +#include "cell/common.h" #include "spu_main.h" static INLINE unsigned diff --git a/src/gallium/drivers/failover/Makefile b/src/gallium/drivers/failover/Makefile index 72d0895c74..14389bd055 100644 --- a/src/gallium/drivers/failover/Makefile +++ b/src/gallium/drivers/failover/Makefile @@ -15,7 +15,7 @@ C_SOURCES = \ ASM_SOURCES = -include ../Makefile.template +include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/i915simple/Makefile b/src/gallium/drivers/i915simple/Makefile index 2f91de3afc..ee22ba86f9 100644 --- a/src/gallium/drivers/i915simple/Makefile +++ b/src/gallium/drivers/i915simple/Makefile @@ -32,7 +32,7 @@ C_SOURCES = \ ASM_SOURCES = -include ../Makefile.template +include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 497623a700..7f71f8fd4f 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -32,7 +32,7 @@ #include "i915_texture.h" #include "i915_reg.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" #include "pipe/p_defines.h" #include "pipe/p_winsys.h" #include "pipe/p_util.h" diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index b4ea63c3e7..2d876925b2 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -33,7 +33,7 @@ #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "pipe/draw/draw_vertex.h" +#include "draw/draw_vertex.h" #define I915_TEX_UNITS 8 diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 868f0c7e04..6c1524c768 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -33,9 +33,9 @@ #include "i915_fpc.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_parse.h" -#include "pipe/draw/draw_vertex.h" +#include "draw/draw_vertex.h" /** diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c index c4a706c37d..44c4325936 100644 --- a/src/gallium/drivers/i915simple/i915_prim_emit.c +++ b/src/gallium/drivers/i915simple/i915_prim_emit.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "pipe/draw/draw_private.h" +#include "draw/draw_private.h" #include "pipe/p_util.h" #include "i915_context.h" diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index e069773fd4..c5bf6174f6 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -38,7 +38,7 @@ */ -#include "pipe/draw/draw_vbuf.h" +#include "draw/draw_vbuf.h" #include "pipe/p_debug.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index abd5571b88..294e6fad03 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -29,7 +29,7 @@ */ -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" #include "pipe/p_winsys.h" #include "pipe/p_util.h" diff --git a/src/gallium/drivers/i915simple/i915_state_derived.c b/src/gallium/drivers/i915simple/i915_state_derived.c index 653983e4a9..4767584fc6 100644 --- a/src/gallium/drivers/i915simple/i915_state_derived.c +++ b/src/gallium/drivers/i915simple/i915_state_derived.c @@ -27,8 +27,8 @@ #include "pipe/p_util.h" -#include "pipe/draw/draw_context.h" -#include "pipe/draw/draw_vertex.h" +#include "draw/draw_context.h" +#include "draw/draw_vertex.h" #include "i915_context.h" #include "i915_state.h" #include "i915_reg.h" diff --git a/src/gallium/drivers/i915simple/i915_strings.c b/src/gallium/drivers/i915simple/i915_strings.c index c713bf7208..301fedea19 100644 --- a/src/gallium/drivers/i915simple/i915_strings.c +++ b/src/gallium/drivers/i915simple/i915_strings.c @@ -70,7 +70,7 @@ static const char *i915_get_name( struct pipe_context *pipe ) break; } - sprintf(buffer, "pipe/i915 (chipset: %s)", chipset); + sprintf(buffer, "i915 (chipset: %s)", chipset); return buffer; } diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index de0cc5fe06..17fd27895a 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -33,7 +33,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "pipe/util/p_tile.h" +#include "util/p_tile.h" /* diff --git a/src/gallium/drivers/i965simple/Makefile b/src/gallium/drivers/i965simple/Makefile index 48c00ab50b..1dec1f9749 100644 --- a/src/gallium/drivers/i965simple/Makefile +++ b/src/gallium/drivers/i965simple/Makefile @@ -61,6 +61,6 @@ ASM_SOURCES = DRIVER_DEFINES = -I. -include ../Makefile.template +include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/i965simple/brw_shader_info.c b/src/gallium/drivers/i965simple/brw_shader_info.c index 431b45466a..a762a870fe 100644 --- a/src/gallium/drivers/i965simple/brw_shader_info.c +++ b/src/gallium/drivers/i965simple/brw_shader_info.c @@ -3,7 +3,7 @@ #include "brw_state.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_parse.h" diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index 95dfce88e4..f746d1cc57 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -33,7 +33,7 @@ #include "pipe/p_winsys.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_dump.h" +#include "tgsi/util/tgsi_dump.h" #include "brw_context.h" #include "brw_defines.h" diff --git a/src/gallium/drivers/i965simple/brw_strings.c b/src/gallium/drivers/i965simple/brw_strings.c index 29a41ed1e9..3d9c50961f 100644 --- a/src/gallium/drivers/i965simple/brw_strings.c +++ b/src/gallium/drivers/i965simple/brw_strings.c @@ -59,7 +59,7 @@ static const char *brw_get_name( struct pipe_context *pipe ) break; } - sprintf(buffer, "pipe/i965 (chipset: %s)", chipset); + sprintf(buffer, "i965 (chipset: %s)", chipset); return buffer; } diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index 518845e4b2..376a42b1a6 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -32,7 +32,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "pipe/util/p_tile.h" +#include "util/p_tile.h" /* diff --git a/src/gallium/drivers/i965simple/brw_vs_emit.c b/src/gallium/drivers/i965simple/brw_vs_emit.c index 98915ba101..05df4860ed 100644 --- a/src/gallium/drivers/i965simple/brw_vs_emit.c +++ b/src/gallium/drivers/i965simple/brw_vs_emit.c @@ -33,7 +33,7 @@ #include "brw_vs.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_parse.h" struct brw_prog_info { unsigned num_temps; diff --git a/src/gallium/drivers/i965simple/brw_wm_decl.c b/src/gallium/drivers/i965simple/brw_wm_decl.c index b45a333a2e..97418a52e7 100644 --- a/src/gallium/drivers/i965simple/brw_wm_decl.c +++ b/src/gallium/drivers/i965simple/brw_wm_decl.c @@ -4,7 +4,7 @@ #include "brw_wm.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_parse.h" static struct brw_reg alloc_tmp(struct brw_wm_compile *c) { diff --git a/src/gallium/drivers/i965simple/brw_wm_glsl.c b/src/gallium/drivers/i965simple/brw_wm_glsl.c index d95645d108..44f946ea74 100644 --- a/src/gallium/drivers/i965simple/brw_wm_glsl.c +++ b/src/gallium/drivers/i965simple/brw_wm_glsl.c @@ -4,7 +4,7 @@ #include "brw_wm.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "pipe/tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_parse.h" diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index 31438a882e..2304ea4246 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -44,7 +44,7 @@ C_SOURCES = \ ASM_SOURCES = -include ../Makefile.template +include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index cea6b90104..5e98f190bb 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -29,7 +29,7 @@ * Keith Whitwell */ -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "pipe/p_util.h" diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index aff8c2cc5d..8c79cb3ce4 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -34,7 +34,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/draw/draw_vertex.h" +#include "draw/draw_vertex.h" #include "sp_quad.h" diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 71a303a8b5..2049afda34 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -38,7 +38,7 @@ #include "sp_context.h" #include "sp_state.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index ced0d5d098..2cbd0d7cab 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -31,7 +31,7 @@ #include "pipe/p_defines.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" #include "sp_flush.h" #include "sp_context.h" #include "sp_surface.h" diff --git a/src/gallium/drivers/softpipe/sp_headers.h b/src/gallium/drivers/softpipe/sp_headers.h index 0ae31d8796..9cf8222133 100644 --- a/src/gallium/drivers/softpipe/sp_headers.h +++ b/src/gallium/drivers/softpipe/sp_headers.h @@ -31,7 +31,7 @@ #ifndef SP_HEADERS_H #define SP_HEADERS_H -#include "pipe/tgsi/exec/tgsi_exec.h" +#include "tgsi/exec/tgsi_exec.h" #define PRIM_POINT 1 #define PRIM_LINE 2 diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 2772048661..d73521ccbe 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -38,8 +38,8 @@ #include "sp_quad.h" #include "sp_state.h" #include "sp_prim_setup.h" -#include "pipe/draw/draw_private.h" -#include "pipe/draw/draw_vertex.h" +#include "draw/draw_private.h" +#include "draw/draw_vertex.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 7f71fdb6a9..69bea8a8f5 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -39,9 +39,9 @@ #include "sp_context.h" #include "sp_state.h" #include "sp_prim_vbuf.h" -#include "pipe/draw/draw_context.h" -#include "pipe/draw/draw_private.h" -#include "pipe/draw/draw_vbuf.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" #define SP_MAX_VBUF_INDEXES 1024 diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 3316858413..b4c01a7ea8 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -42,7 +42,7 @@ #include "x86/rtasm/x86sse.h" #ifdef MESA_LLVM -#include "pipe/llvm/gallivm.h" +#include "llvm/gallivm.h" #endif #include "sp_context.h" diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c index 6a8a43aeda..adf9ccf64c 100644 --- a/src/gallium/drivers/softpipe/sp_query.c +++ b/src/gallium/drivers/softpipe/sp_query.c @@ -29,7 +29,7 @@ * Keith Whitwell */ -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "pipe/p_util.h" diff --git a/src/gallium/drivers/softpipe/sp_state_clip.c b/src/gallium/drivers/softpipe/sp_state_clip.c index 08c5f06d05..c797c0dd3b 100644 --- a/src/gallium/drivers/softpipe/sp_state_clip.c +++ b/src/gallium/drivers/softpipe/sp_state_clip.c @@ -29,7 +29,7 @@ */ #include "sp_context.h" #include "sp_state.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" void softpipe_set_clip_state( struct pipe_context *pipe, diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 372597869f..9d8fd8b750 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -27,9 +27,9 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "pipe/draw/draw_context.h" -#include "pipe/draw/draw_vertex.h" -#include "pipe/draw/draw_private.h" +#include "draw/draw_context.h" +#include "draw/draw_vertex.h" +#include "draw/draw_private.h" #include "sp_context.h" #include "sp_state.h" diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 0b814fc284..1e3cadd43d 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -32,11 +32,11 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" #include "pipe/p_shader_tokens.h" -#include "pipe/llvm/gallivm.h" -#include "pipe/tgsi/util/tgsi_dump.h" -#include "pipe/tgsi/exec/tgsi_sse2.h" +#include "llvm/gallivm.h" +#include "tgsi/util/tgsi_dump.h" +#include "tgsi/exec/tgsi_sse2.h" void * diff --git a/src/gallium/drivers/softpipe/sp_state_rasterizer.c b/src/gallium/drivers/softpipe/sp_state_rasterizer.c index 53755099dd..98e04352db 100644 --- a/src/gallium/drivers/softpipe/sp_state_rasterizer.c +++ b/src/gallium/drivers/softpipe/sp_state_rasterizer.c @@ -29,7 +29,7 @@ #include "pipe/p_util.h" #include "sp_context.h" #include "sp_state.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index ea348c7e95..460adccec4 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -31,14 +31,14 @@ #include "pipe/p_util.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" #include "sp_context.h" #include "sp_context.h" #include "sp_state.h" #include "sp_texture.h" #include "sp_tile_cache.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index 09ff540ccf..f01a10de3b 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -33,7 +33,7 @@ #include "sp_state.h" #include "sp_surface.h" -#include "pipe/draw/draw_context.h" +#include "draw/draw_context.h" void diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index 8802ced187..653449c4f1 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -29,7 +29,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "pipe/util/p_tile.h" +#include "util/p_tile.h" #include "sp_context.h" #include "sp_surface.h" diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 325bdb86da..2f82fd6abe 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -40,7 +40,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" -#include "pipe/tgsi/exec/tgsi_exec.h" +#include "tgsi/exec/tgsi_exec.h" /* diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 1597361b82..dde3fabc81 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -34,7 +34,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "pipe/util/p_tile.h" +#include "util/p_tile.h" #include "sp_context.h" #include "sp_surface.h" #include "sp_tile_cache.h" diff --git a/src/gallium/winsys/dri/Makefile b/src/gallium/winsys/dri/Makefile new file mode 100644 index 0000000000..f466ce6c3c --- /dev/null +++ b/src/gallium/winsys/dri/Makefile @@ -0,0 +1,38 @@ +# src/mesa/drivers/dri/Makefile + +TOP = ../../../.. + +include $(TOP)/configs/current + + + +default: $(TOP)/$(LIB_DIR) subdirs + + +$(TOP)/$(LIB_DIR): + -mkdir $(TOP)/$(LIB_DIR) + + +subdirs: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +install: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) install) || exit 1 ; \ + fi \ + done + + +clean: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) clean) ; \ + fi \ + done + -rm -f common/*.o diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template new file mode 100644 index 0000000000..b96305c094 --- /dev/null +++ b/src/gallium/winsys/dri/Makefile.template @@ -0,0 +1,113 @@ +# -*-makefile-*- + +MESA_MODULES = $(TOP)/src/mesa/libmesa.a + +COMMON_GALLIUM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/utils.c \ + $(TOP)/src/mesa/drivers/dri/common/vblank.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_util.c \ + $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c + +COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ + $(TOP)/src/mesa/drivers/common/driverfuncs.c \ + $(TOP)/src/mesa/drivers/dri/common/texmem.c \ + $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c + +COMMON_BM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/dri_bufmgr.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_drmpool.c + + +ifeq ($(WINDOW_SYSTEM),dri) +WINOBJ= +WINLIB= +INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) + +else +# miniglx +WINOBJ= +WINLIB=-L$(MESA)/src/glx/mini +MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini +INCLUDES = $(MINIGLX_INCLUDES) \ + $(SHARED_INCLUDES) \ + $(PCIACCESS_CFLAGS) + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(MINIGLX_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) +endif + + +### Include directories +SHARED_INCLUDES = \ + -I. \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -Iserver \ + -I$(TOP)/include \ + -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/mesa/math \ + -I$(TOP)/src/mesa/transform \ + -I$(TOP)/src/mesa/shader \ + -I$(TOP)/src/mesa/swrast \ + -I$(TOP)/src/mesa/swrast_setup \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/src/egl/drivers/dri \ + $(LIBDRM_CFLAGS) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) + + +$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template + $(TOP)/bin/mklib -noprefix -o $@ \ + $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) + + +$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) + $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) + + +depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +install: $(LIBNAME) + $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + + +include depend diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index 9ae0f01325..40654bb2ac 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -7,8 +7,8 @@ LIBNAME = i915tex_dri.so MINIGLX_SOURCES = server/intel_dri.c PIPE_DRIVERS = \ - $(TOP)/src/mesa/pipe/softpipe/libsoftpipe.a \ - $(TOP)/src/mesa/pipe/i915simple/libi915simple.a + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a DRIVER_SOURCES = \ intel_winsys_pipe.c \ @@ -28,11 +28,11 @@ C_SOURCES = \ ASM_SOURCES = -DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ +DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") include ../Makefile.template -intel_tex_layout.o: ../intel/intel_tex_layout.c +intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c symlinks: diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index 1ba6a9e1b2..0ed3890e93 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -39,7 +39,7 @@ #include "intel_winsys.h" #include "pipe/p_util.h" -#include "pipe/i915simple/i915_winsys.h" +#include "i915simple/i915_winsys.h" struct intel_i915_winsys { diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c index cec3437831..9e483bdc9f 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c @@ -34,7 +34,7 @@ #include "pipe/p_defines.h" #include "pipe/p_util.h" #include "pipe/p_format.h" -#include "pipe/softpipe/sp_winsys.h" +#include "softpipe/sp_winsys.h" struct intel_softpipe_winsys { diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index c3cd22eea3..8da596d419 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -41,11 +41,11 @@ #include "pipe/p_context.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "pipe/softpipe/sp_winsys.h" +#include "softpipe/sp_winsys.h" #ifdef GALLIUM_CELL -#include "pipe/cell/ppu/cell_context.h" -#include "pipe/cell/ppu/cell_winsys.h" +#include "cell/ppu/cell_context.h" +#include "cell/ppu/cell_winsys.h" #else #define TILE_SIZE 32 /* avoid compilation errors */ #endif diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index bf41570257..dbfd37bda2 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -39,7 +39,7 @@ #include "pipe/p_winsys.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "pipe/i965simple/brw_winsys.h" +#include "i965simple/brw_winsys.h" #include "brw_aub.h" #include "xm_winsys_aub.h" -- cgit v1.2.3 From 6d3831b11d9f5aaba61cc2fb8ade61437ad7c335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Feb 2008 17:52:14 +0900 Subject: Code reorganization: placeholder for state-trackers. This is meant for temporarily holding state-trackers, until they eventually find their way out of gallium tree. --- src/gallium/state_trackers/README | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/gallium/state_trackers/README (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/README b/src/gallium/state_trackers/README new file mode 100644 index 0000000000..28dd27bbd5 --- /dev/null +++ b/src/gallium/state_trackers/README @@ -0,0 +1,2 @@ +This directory is a placeholder for incubating state-trackers. Mesa's +state-tracker is in src/mesa. -- cgit v1.2.3 From 92fcbf6e7bc622dcace226bb70ff6d5cdbdbaecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Feb 2008 20:07:18 +0900 Subject: Code reorganization: s/aux/auxiliary/. "aux" is a reserved name on Windows (X_X) --- src/gallium/aux/Makefile | 24 - src/gallium/aux/cso_cache/cso_cache.c | 181 -- src/gallium/aux/cso_cache/cso_cache.h | 107 - src/gallium/aux/cso_cache/cso_hash.c | 388 --- src/gallium/aux/cso_cache/cso_hash.h | 62 - src/gallium/aux/draw/Makefile | 2 - src/gallium/aux/draw/draw_clip.c | 488 ---- src/gallium/aux/draw/draw_context.c | 293 --- src/gallium/aux/draw/draw_context.h | 142 -- src/gallium/aux/draw/draw_cull.c | 150 -- src/gallium/aux/draw/draw_debug.c | 113 - src/gallium/aux/draw/draw_flatshade.c | 205 -- src/gallium/aux/draw/draw_offset.c | 186 -- src/gallium/aux/draw/draw_prim.c | 482 ---- src/gallium/aux/draw/draw_private.h | 346 --- src/gallium/aux/draw/draw_stipple.c | 239 -- src/gallium/aux/draw/draw_twoside.c | 203 -- src/gallium/aux/draw/draw_unfilled.c | 206 -- src/gallium/aux/draw/draw_validate.c | 185 -- src/gallium/aux/draw/draw_vbuf.c | 570 ----- src/gallium/aux/draw/draw_vbuf.h | 106 - src/gallium/aux/draw/draw_vertex.c | 79 - src/gallium/aux/draw/draw_vertex.h | 111 - src/gallium/aux/draw/draw_vertex_cache.c | 196 -- src/gallium/aux/draw/draw_vertex_fetch.c | 510 ---- src/gallium/aux/draw/draw_vertex_shader.c | 325 --- src/gallium/aux/draw/draw_vf.c | 428 ---- src/gallium/aux/draw/draw_vf.h | 236 -- src/gallium/aux/draw/draw_vf_generic.c | 585 ----- src/gallium/aux/draw/draw_vf_sse.c | 614 ----- src/gallium/aux/draw/draw_wide_prims.c | 432 ---- src/gallium/aux/llvm/Makefile | 85 - src/gallium/aux/llvm/gallivm.cpp | 327 --- src/gallium/aux/llvm/gallivm.h | 103 - src/gallium/aux/llvm/gallivm_builtins.cpp | 567 ----- src/gallium/aux/llvm/gallivm_cpu.cpp | 202 -- src/gallium/aux/llvm/gallivm_p.h | 110 - src/gallium/aux/llvm/instructions.cpp | 889 ------- src/gallium/aux/llvm/instructions.h | 152 -- src/gallium/aux/llvm/instructionssoa.cpp | 121 - src/gallium/aux/llvm/instructionssoa.h | 74 - src/gallium/aux/llvm/llvm_builtins.c | 115 - src/gallium/aux/llvm/loweringpass.cpp | 17 - src/gallium/aux/llvm/loweringpass.h | 15 - src/gallium/aux/llvm/storage.cpp | 364 --- src/gallium/aux/llvm/storage.h | 133 -- src/gallium/aux/llvm/storagesoa.cpp | 389 --- src/gallium/aux/llvm/storagesoa.h | 111 - src/gallium/aux/llvm/tgsitollvm.cpp | 1221 ---------- src/gallium/aux/llvm/tgsitollvm.h | 20 - src/gallium/aux/pipebuffer/Makefile | 23 - src/gallium/aux/pipebuffer/linked_list.h | 91 - src/gallium/aux/pipebuffer/pb_buffer.h | 202 -- src/gallium/aux/pipebuffer/pb_buffer_fenced.c | 299 --- src/gallium/aux/pipebuffer/pb_buffer_fenced.h | 117 - src/gallium/aux/pipebuffer/pb_buffer_malloc.c | 127 - src/gallium/aux/pipebuffer/pb_bufmgr.h | 126 - src/gallium/aux/pipebuffer/pb_bufmgr_fenced.c | 131 -- src/gallium/aux/pipebuffer/pb_bufmgr_mm.c | 593 ----- src/gallium/aux/pipebuffer/pb_bufmgr_pool.c | 288 --- src/gallium/aux/pipebuffer/pb_winsys.c | 170 -- src/gallium/aux/tgsi/Makefile | 3 - src/gallium/aux/tgsi/exec/Makefile | 3 - src/gallium/aux/tgsi/exec/tgsi_exec.c | 2485 -------------------- src/gallium/aux/tgsi/exec/tgsi_exec.h | 239 -- src/gallium/aux/tgsi/exec/tgsi_sse2.c | 2378 ------------------- src/gallium/aux/tgsi/exec/tgsi_sse2.h | 26 - src/gallium/aux/tgsi/util/tgsi_build.c | 1371 ----------- src/gallium/aux/tgsi/util/tgsi_build.h | 320 --- src/gallium/aux/tgsi/util/tgsi_dump.c | 1581 ------------- src/gallium/aux/tgsi/util/tgsi_dump.h | 28 - src/gallium/aux/tgsi/util/tgsi_parse.c | 319 --- src/gallium/aux/tgsi/util/tgsi_parse.h | 121 - src/gallium/aux/tgsi/util/tgsi_transform.c | 199 -- src/gallium/aux/tgsi/util/tgsi_transform.h | 93 - src/gallium/aux/tgsi/util/tgsi_util.c | 274 --- src/gallium/aux/tgsi/util/tgsi_util.h | 70 - src/gallium/aux/util/p_debug.c | 76 - src/gallium/aux/util/p_tile.c | 699 ------ src/gallium/aux/util/p_tile.h | 81 - src/gallium/aux/util/p_util.c | 73 - src/gallium/auxiliary/Makefile | 24 + src/gallium/auxiliary/cso_cache/cso_cache.c | 181 ++ src/gallium/auxiliary/cso_cache/cso_cache.h | 107 + src/gallium/auxiliary/cso_cache/cso_hash.c | 388 +++ src/gallium/auxiliary/cso_cache/cso_hash.h | 62 + src/gallium/auxiliary/draw/Makefile | 2 + src/gallium/auxiliary/draw/draw_clip.c | 488 ++++ src/gallium/auxiliary/draw/draw_context.c | 293 +++ src/gallium/auxiliary/draw/draw_context.h | 142 ++ src/gallium/auxiliary/draw/draw_cull.c | 150 ++ src/gallium/auxiliary/draw/draw_debug.c | 113 + src/gallium/auxiliary/draw/draw_flatshade.c | 205 ++ src/gallium/auxiliary/draw/draw_offset.c | 186 ++ src/gallium/auxiliary/draw/draw_prim.c | 482 ++++ src/gallium/auxiliary/draw/draw_private.h | 346 +++ src/gallium/auxiliary/draw/draw_stipple.c | 239 ++ src/gallium/auxiliary/draw/draw_twoside.c | 203 ++ src/gallium/auxiliary/draw/draw_unfilled.c | 206 ++ src/gallium/auxiliary/draw/draw_validate.c | 185 ++ src/gallium/auxiliary/draw/draw_vbuf.c | 570 +++++ src/gallium/auxiliary/draw/draw_vbuf.h | 106 + src/gallium/auxiliary/draw/draw_vertex.c | 79 + src/gallium/auxiliary/draw/draw_vertex.h | 111 + src/gallium/auxiliary/draw/draw_vertex_cache.c | 196 ++ src/gallium/auxiliary/draw/draw_vertex_fetch.c | 510 ++++ src/gallium/auxiliary/draw/draw_vertex_shader.c | 325 +++ src/gallium/auxiliary/draw/draw_vf.c | 428 ++++ src/gallium/auxiliary/draw/draw_vf.h | 236 ++ src/gallium/auxiliary/draw/draw_vf_generic.c | 585 +++++ src/gallium/auxiliary/draw/draw_vf_sse.c | 614 +++++ src/gallium/auxiliary/draw/draw_wide_prims.c | 432 ++++ src/gallium/auxiliary/llvm/Makefile | 85 + src/gallium/auxiliary/llvm/gallivm.cpp | 327 +++ src/gallium/auxiliary/llvm/gallivm.h | 103 + src/gallium/auxiliary/llvm/gallivm_builtins.cpp | 567 +++++ src/gallium/auxiliary/llvm/gallivm_cpu.cpp | 202 ++ src/gallium/auxiliary/llvm/gallivm_p.h | 110 + src/gallium/auxiliary/llvm/instructions.cpp | 889 +++++++ src/gallium/auxiliary/llvm/instructions.h | 152 ++ src/gallium/auxiliary/llvm/instructionssoa.cpp | 121 + src/gallium/auxiliary/llvm/instructionssoa.h | 74 + src/gallium/auxiliary/llvm/llvm_builtins.c | 115 + src/gallium/auxiliary/llvm/loweringpass.cpp | 17 + src/gallium/auxiliary/llvm/loweringpass.h | 15 + src/gallium/auxiliary/llvm/storage.cpp | 364 +++ src/gallium/auxiliary/llvm/storage.h | 133 ++ src/gallium/auxiliary/llvm/storagesoa.cpp | 389 +++ src/gallium/auxiliary/llvm/storagesoa.h | 111 + src/gallium/auxiliary/llvm/tgsitollvm.cpp | 1221 ++++++++++ src/gallium/auxiliary/llvm/tgsitollvm.h | 20 + src/gallium/auxiliary/pipebuffer/Makefile | 23 + src/gallium/auxiliary/pipebuffer/linked_list.h | 91 + src/gallium/auxiliary/pipebuffer/pb_buffer.h | 202 ++ .../auxiliary/pipebuffer/pb_buffer_fenced.c | 299 +++ .../auxiliary/pipebuffer/pb_buffer_fenced.h | 117 + .../auxiliary/pipebuffer/pb_buffer_malloc.c | 127 + src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 126 + .../auxiliary/pipebuffer/pb_bufmgr_fenced.c | 131 ++ src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 593 +++++ src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 288 +++ src/gallium/auxiliary/pipebuffer/pb_winsys.c | 170 ++ src/gallium/auxiliary/tgsi/Makefile | 3 + src/gallium/auxiliary/tgsi/exec/Makefile | 3 + src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 2485 ++++++++++++++++++++ src/gallium/auxiliary/tgsi/exec/tgsi_exec.h | 239 ++ src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2378 +++++++++++++++++++ src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h | 26 + src/gallium/auxiliary/tgsi/util/tgsi_build.c | 1371 +++++++++++ src/gallium/auxiliary/tgsi/util/tgsi_build.h | 320 +++ src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 1581 +++++++++++++ src/gallium/auxiliary/tgsi/util/tgsi_dump.h | 28 + src/gallium/auxiliary/tgsi/util/tgsi_parse.c | 319 +++ src/gallium/auxiliary/tgsi/util/tgsi_parse.h | 121 + src/gallium/auxiliary/tgsi/util/tgsi_transform.c | 199 ++ src/gallium/auxiliary/tgsi/util/tgsi_transform.h | 93 + src/gallium/auxiliary/tgsi/util/tgsi_util.c | 274 +++ src/gallium/auxiliary/tgsi/util/tgsi_util.h | 70 + src/gallium/auxiliary/util/p_debug.c | 76 + src/gallium/auxiliary/util/p_tile.c | 699 ++++++ src/gallium/auxiliary/util/p_tile.h | 81 + src/gallium/auxiliary/util/p_util.c | 73 + 162 files changed, 25815 insertions(+), 25815 deletions(-) delete mode 100644 src/gallium/aux/Makefile delete mode 100644 src/gallium/aux/cso_cache/cso_cache.c delete mode 100644 src/gallium/aux/cso_cache/cso_cache.h delete mode 100644 src/gallium/aux/cso_cache/cso_hash.c delete mode 100644 src/gallium/aux/cso_cache/cso_hash.h delete mode 100644 src/gallium/aux/draw/Makefile delete mode 100644 src/gallium/aux/draw/draw_clip.c delete mode 100644 src/gallium/aux/draw/draw_context.c delete mode 100644 src/gallium/aux/draw/draw_context.h delete mode 100644 src/gallium/aux/draw/draw_cull.c delete mode 100644 src/gallium/aux/draw/draw_debug.c delete mode 100644 src/gallium/aux/draw/draw_flatshade.c delete mode 100644 src/gallium/aux/draw/draw_offset.c delete mode 100644 src/gallium/aux/draw/draw_prim.c delete mode 100644 src/gallium/aux/draw/draw_private.h delete mode 100644 src/gallium/aux/draw/draw_stipple.c delete mode 100644 src/gallium/aux/draw/draw_twoside.c delete mode 100644 src/gallium/aux/draw/draw_unfilled.c delete mode 100644 src/gallium/aux/draw/draw_validate.c delete mode 100644 src/gallium/aux/draw/draw_vbuf.c delete mode 100644 src/gallium/aux/draw/draw_vbuf.h delete mode 100644 src/gallium/aux/draw/draw_vertex.c delete mode 100644 src/gallium/aux/draw/draw_vertex.h delete mode 100644 src/gallium/aux/draw/draw_vertex_cache.c delete mode 100644 src/gallium/aux/draw/draw_vertex_fetch.c delete mode 100644 src/gallium/aux/draw/draw_vertex_shader.c delete mode 100644 src/gallium/aux/draw/draw_vf.c delete mode 100644 src/gallium/aux/draw/draw_vf.h delete mode 100644 src/gallium/aux/draw/draw_vf_generic.c delete mode 100644 src/gallium/aux/draw/draw_vf_sse.c delete mode 100644 src/gallium/aux/draw/draw_wide_prims.c delete mode 100644 src/gallium/aux/llvm/Makefile delete mode 100644 src/gallium/aux/llvm/gallivm.cpp delete mode 100644 src/gallium/aux/llvm/gallivm.h delete mode 100644 src/gallium/aux/llvm/gallivm_builtins.cpp delete mode 100644 src/gallium/aux/llvm/gallivm_cpu.cpp delete mode 100644 src/gallium/aux/llvm/gallivm_p.h delete mode 100644 src/gallium/aux/llvm/instructions.cpp delete mode 100644 src/gallium/aux/llvm/instructions.h delete mode 100644 src/gallium/aux/llvm/instructionssoa.cpp delete mode 100644 src/gallium/aux/llvm/instructionssoa.h delete mode 100644 src/gallium/aux/llvm/llvm_builtins.c delete mode 100644 src/gallium/aux/llvm/loweringpass.cpp delete mode 100644 src/gallium/aux/llvm/loweringpass.h delete mode 100644 src/gallium/aux/llvm/storage.cpp delete mode 100644 src/gallium/aux/llvm/storage.h delete mode 100644 src/gallium/aux/llvm/storagesoa.cpp delete mode 100644 src/gallium/aux/llvm/storagesoa.h delete mode 100644 src/gallium/aux/llvm/tgsitollvm.cpp delete mode 100644 src/gallium/aux/llvm/tgsitollvm.h delete mode 100644 src/gallium/aux/pipebuffer/Makefile delete mode 100644 src/gallium/aux/pipebuffer/linked_list.h delete mode 100644 src/gallium/aux/pipebuffer/pb_buffer.h delete mode 100644 src/gallium/aux/pipebuffer/pb_buffer_fenced.c delete mode 100644 src/gallium/aux/pipebuffer/pb_buffer_fenced.h delete mode 100644 src/gallium/aux/pipebuffer/pb_buffer_malloc.c delete mode 100644 src/gallium/aux/pipebuffer/pb_bufmgr.h delete mode 100644 src/gallium/aux/pipebuffer/pb_bufmgr_fenced.c delete mode 100644 src/gallium/aux/pipebuffer/pb_bufmgr_mm.c delete mode 100644 src/gallium/aux/pipebuffer/pb_bufmgr_pool.c delete mode 100644 src/gallium/aux/pipebuffer/pb_winsys.c delete mode 100644 src/gallium/aux/tgsi/Makefile delete mode 100644 src/gallium/aux/tgsi/exec/Makefile delete mode 100644 src/gallium/aux/tgsi/exec/tgsi_exec.c delete mode 100644 src/gallium/aux/tgsi/exec/tgsi_exec.h delete mode 100755 src/gallium/aux/tgsi/exec/tgsi_sse2.c delete mode 100755 src/gallium/aux/tgsi/exec/tgsi_sse2.h delete mode 100644 src/gallium/aux/tgsi/util/tgsi_build.c delete mode 100644 src/gallium/aux/tgsi/util/tgsi_build.h delete mode 100644 src/gallium/aux/tgsi/util/tgsi_dump.c delete mode 100644 src/gallium/aux/tgsi/util/tgsi_dump.h delete mode 100644 src/gallium/aux/tgsi/util/tgsi_parse.c delete mode 100644 src/gallium/aux/tgsi/util/tgsi_parse.h delete mode 100644 src/gallium/aux/tgsi/util/tgsi_transform.c delete mode 100644 src/gallium/aux/tgsi/util/tgsi_transform.h delete mode 100644 src/gallium/aux/tgsi/util/tgsi_util.c delete mode 100644 src/gallium/aux/tgsi/util/tgsi_util.h delete mode 100644 src/gallium/aux/util/p_debug.c delete mode 100644 src/gallium/aux/util/p_tile.c delete mode 100644 src/gallium/aux/util/p_tile.h delete mode 100644 src/gallium/aux/util/p_util.c create mode 100644 src/gallium/auxiliary/Makefile create mode 100644 src/gallium/auxiliary/cso_cache/cso_cache.c create mode 100644 src/gallium/auxiliary/cso_cache/cso_cache.h create mode 100644 src/gallium/auxiliary/cso_cache/cso_hash.c create mode 100644 src/gallium/auxiliary/cso_cache/cso_hash.h create mode 100644 src/gallium/auxiliary/draw/Makefile create mode 100644 src/gallium/auxiliary/draw/draw_clip.c create mode 100644 src/gallium/auxiliary/draw/draw_context.c create mode 100644 src/gallium/auxiliary/draw/draw_context.h create mode 100644 src/gallium/auxiliary/draw/draw_cull.c create mode 100644 src/gallium/auxiliary/draw/draw_debug.c create mode 100644 src/gallium/auxiliary/draw/draw_flatshade.c create mode 100644 src/gallium/auxiliary/draw/draw_offset.c create mode 100644 src/gallium/auxiliary/draw/draw_prim.c create mode 100644 src/gallium/auxiliary/draw/draw_private.h create mode 100644 src/gallium/auxiliary/draw/draw_stipple.c create mode 100644 src/gallium/auxiliary/draw/draw_twoside.c create mode 100644 src/gallium/auxiliary/draw/draw_unfilled.c create mode 100644 src/gallium/auxiliary/draw/draw_validate.c create mode 100644 src/gallium/auxiliary/draw/draw_vbuf.c create mode 100644 src/gallium/auxiliary/draw/draw_vbuf.h create mode 100644 src/gallium/auxiliary/draw/draw_vertex.c create mode 100644 src/gallium/auxiliary/draw/draw_vertex.h create mode 100644 src/gallium/auxiliary/draw/draw_vertex_cache.c create mode 100644 src/gallium/auxiliary/draw/draw_vertex_fetch.c create mode 100644 src/gallium/auxiliary/draw/draw_vertex_shader.c create mode 100644 src/gallium/auxiliary/draw/draw_vf.c create mode 100644 src/gallium/auxiliary/draw/draw_vf.h create mode 100644 src/gallium/auxiliary/draw/draw_vf_generic.c create mode 100644 src/gallium/auxiliary/draw/draw_vf_sse.c create mode 100644 src/gallium/auxiliary/draw/draw_wide_prims.c create mode 100644 src/gallium/auxiliary/llvm/Makefile create mode 100644 src/gallium/auxiliary/llvm/gallivm.cpp create mode 100644 src/gallium/auxiliary/llvm/gallivm.h create mode 100644 src/gallium/auxiliary/llvm/gallivm_builtins.cpp create mode 100644 src/gallium/auxiliary/llvm/gallivm_cpu.cpp create mode 100644 src/gallium/auxiliary/llvm/gallivm_p.h create mode 100644 src/gallium/auxiliary/llvm/instructions.cpp create mode 100644 src/gallium/auxiliary/llvm/instructions.h create mode 100644 src/gallium/auxiliary/llvm/instructionssoa.cpp create mode 100644 src/gallium/auxiliary/llvm/instructionssoa.h create mode 100644 src/gallium/auxiliary/llvm/llvm_builtins.c create mode 100644 src/gallium/auxiliary/llvm/loweringpass.cpp create mode 100644 src/gallium/auxiliary/llvm/loweringpass.h create mode 100644 src/gallium/auxiliary/llvm/storage.cpp create mode 100644 src/gallium/auxiliary/llvm/storage.h create mode 100644 src/gallium/auxiliary/llvm/storagesoa.cpp create mode 100644 src/gallium/auxiliary/llvm/storagesoa.h create mode 100644 src/gallium/auxiliary/llvm/tgsitollvm.cpp create mode 100644 src/gallium/auxiliary/llvm/tgsitollvm.h create mode 100644 src/gallium/auxiliary/pipebuffer/Makefile create mode 100644 src/gallium/auxiliary/pipebuffer/linked_list.h create mode 100644 src/gallium/auxiliary/pipebuffer/pb_buffer.h create mode 100644 src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c create mode 100644 src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h create mode 100644 src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c create mode 100644 src/gallium/auxiliary/pipebuffer/pb_bufmgr.h create mode 100644 src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c create mode 100644 src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c create mode 100644 src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c create mode 100644 src/gallium/auxiliary/pipebuffer/pb_winsys.c create mode 100644 src/gallium/auxiliary/tgsi/Makefile create mode 100644 src/gallium/auxiliary/tgsi/exec/Makefile create mode 100644 src/gallium/auxiliary/tgsi/exec/tgsi_exec.c create mode 100644 src/gallium/auxiliary/tgsi/exec/tgsi_exec.h create mode 100755 src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c create mode 100755 src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_build.c create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_build.h create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_dump.c create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_dump.h create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_parse.c create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_parse.h create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_transform.c create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_transform.h create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_util.c create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_util.h create mode 100644 src/gallium/auxiliary/util/p_debug.c create mode 100644 src/gallium/auxiliary/util/p_tile.c create mode 100644 src/gallium/auxiliary/util/p_tile.h create mode 100644 src/gallium/auxiliary/util/p_util.c (limited to 'src/gallium') diff --git a/src/gallium/aux/Makefile b/src/gallium/aux/Makefile deleted file mode 100644 index da68498aa1..0000000000 --- a/src/gallium/aux/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -TOP = ../../.. -include $(TOP)/configs/current - - -ifeq ($(CONFIG_NAME), linux-llvm) -LLVM_DIR = llvm -endif - -SUBDIRS = pipebuffer $(LLVM_DIR) - - -default: subdirs - - -subdirs: - @for dir in $(SUBDIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE)) || exit 1 ; \ - fi \ - done - - -clean: - rm -f `find . -name \*.[oa]` diff --git a/src/gallium/aux/cso_cache/cso_cache.c b/src/gallium/aux/cso_cache/cso_cache.c deleted file mode 100644 index 9e77e0774d..0000000000 --- a/src/gallium/aux/cso_cache/cso_cache.c +++ /dev/null @@ -1,181 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Zack Rusin - */ - -#include "cso_cache.h" -#include "cso_hash.h" - -#if 1 -static unsigned hash_key(const void *key, unsigned key_size) -{ - unsigned *ikey = (unsigned *)key; - unsigned hash = 0, i; - - assert(key_size % 4 == 0); - - /* I'm sure this can be improved on: - */ - for (i = 0; i < key_size/4; i++) - hash ^= ikey[i]; - - return hash; -} -#else -static unsigned hash_key(const unsigned char *p, int n) -{ - unsigned h = 0; - unsigned g; - - while (n--) { - h = (h << 4) + *p++; - if ((g = (h & 0xf0000000)) != 0) - h ^= g >> 23; - h &= ~g; - } - return h; -} -#endif - -unsigned cso_construct_key(void *item, int item_size) -{ - return hash_key((item), item_size); -} - -static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_type type) -{ - struct cso_hash *hash = 0; - - switch(type) { - case CSO_BLEND: - hash = sc->blend_hash; - break; - case CSO_SAMPLER: - hash = sc->sampler_hash; - break; - case CSO_DEPTH_STENCIL_ALPHA: - hash = sc->depth_stencil_hash; - break; - case CSO_RASTERIZER: - hash = sc->rasterizer_hash; - break; - case CSO_FRAGMENT_SHADER: - hash = sc->fs_hash; - break; - case CSO_VERTEX_SHADER: - hash = sc->vs_hash; - break; - } - - return hash; -} - -static int _cso_size_for_type(enum cso_cache_type type) -{ - switch(type) { - case CSO_BLEND: - return sizeof(struct pipe_blend_state); - case CSO_SAMPLER: - return sizeof(struct pipe_sampler_state); - case CSO_DEPTH_STENCIL_ALPHA: - return sizeof(struct pipe_depth_stencil_alpha_state); - case CSO_RASTERIZER: - return sizeof(struct pipe_rasterizer_state); - case CSO_FRAGMENT_SHADER: - return sizeof(struct pipe_shader_state); - case CSO_VERTEX_SHADER: - return sizeof(struct pipe_shader_state); - } - return 0; -} - -struct cso_hash_iter -cso_insert_state(struct cso_cache *sc, - unsigned hash_key, enum cso_cache_type type, - void *state) -{ - struct cso_hash *hash = _cso_hash_for_type(sc, type); - return cso_hash_insert(hash, hash_key, state); -} - -struct cso_hash_iter -cso_find_state(struct cso_cache *sc, - unsigned hash_key, enum cso_cache_type type) -{ - struct cso_hash *hash = _cso_hash_for_type(sc, type); - - return cso_hash_find(hash, hash_key); -} - -struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, - unsigned hash_key, enum cso_cache_type type, - void *templ) -{ - struct cso_hash_iter iter = cso_find_state(sc, hash_key, type); - int size = _cso_size_for_type(type); - while (!cso_hash_iter_is_null(iter)) { - void *iter_data = cso_hash_iter_data(iter); - if (!memcmp(iter_data, templ, size)) - return iter; - iter = cso_hash_iter_next(iter); - } - return iter; -} - -void * cso_take_state(struct cso_cache *sc, - unsigned hash_key, enum cso_cache_type type) -{ - struct cso_hash *hash = _cso_hash_for_type(sc, type); - return cso_hash_take(hash, hash_key); -} - -struct cso_cache *cso_cache_create(void) -{ - struct cso_cache *sc = malloc(sizeof(struct cso_cache)); - - sc->blend_hash = cso_hash_create(); - sc->sampler_hash = cso_hash_create(); - sc->depth_stencil_hash = cso_hash_create(); - sc->rasterizer_hash = cso_hash_create(); - sc->fs_hash = cso_hash_create(); - sc->vs_hash = cso_hash_create(); - - return sc; -} - -void cso_cache_delete(struct cso_cache *sc) -{ - assert(sc); - cso_hash_delete(sc->blend_hash); - cso_hash_delete(sc->sampler_hash); - cso_hash_delete(sc->depth_stencil_hash); - cso_hash_delete(sc->rasterizer_hash); - cso_hash_delete(sc->fs_hash); - cso_hash_delete(sc->vs_hash); - free(sc); -} diff --git a/src/gallium/aux/cso_cache/cso_cache.h b/src/gallium/aux/cso_cache/cso_cache.h deleted file mode 100644 index 116e2eaa2c..0000000000 --- a/src/gallium/aux/cso_cache/cso_cache.h +++ /dev/null @@ -1,107 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin - */ - -#ifndef CSO_CACHE_H -#define CSO_CACHE_H - -#include "pipe/p_context.h" -#include "pipe/p_state.h" - - -struct cso_hash; - -struct cso_cache { - struct cso_hash *blend_hash; - struct cso_hash *depth_stencil_hash; - struct cso_hash *fs_hash; - struct cso_hash *vs_hash; - struct cso_hash *rasterizer_hash; - struct cso_hash *sampler_hash; -}; - -struct cso_blend { - struct pipe_blend_state state; - void *data; -}; - -struct cso_depth_stencil_alpha { - struct pipe_depth_stencil_alpha_state state; - void *data; -}; - -struct cso_rasterizer { - struct pipe_rasterizer_state state; - void *data; -}; - -struct cso_fragment_shader { - struct pipe_shader_state state; - void *data; -}; - -struct cso_vertex_shader { - struct pipe_shader_state state; - void *data; -}; - -struct cso_sampler { - struct pipe_sampler_state state; - void *data; -}; - - -enum cso_cache_type { - CSO_BLEND, - CSO_SAMPLER, - CSO_DEPTH_STENCIL_ALPHA, - CSO_RASTERIZER, - CSO_FRAGMENT_SHADER, - CSO_VERTEX_SHADER -}; - -unsigned cso_construct_key(void *item, int item_size); - -struct cso_cache *cso_cache_create(void); -void cso_cache_delete(struct cso_cache *sc); - -struct cso_hash_iter cso_insert_state(struct cso_cache *sc, - unsigned hash_key, enum cso_cache_type type, - void *state); -struct cso_hash_iter cso_find_state(struct cso_cache *sc, - unsigned hash_key, enum cso_cache_type type); -struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, - unsigned hash_key, enum cso_cache_type type, - void *templ); -void * cso_take_state(struct cso_cache *sc, unsigned hash_key, - enum cso_cache_type type); - -#endif diff --git a/src/gallium/aux/cso_cache/cso_hash.c b/src/gallium/aux/cso_cache/cso_hash.c deleted file mode 100644 index 0338cb3b47..0000000000 --- a/src/gallium/aux/cso_cache/cso_hash.c +++ /dev/null @@ -1,388 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin - */ - -#include "cso_hash.h" - -#include -#include -#include -#include - -#define MAX(a, b) ((a > b) ? (a) : (b)) - -static const int MinNumBits = 4; - -static const unsigned char prime_deltas[] = { - 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3, - 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0 -}; - -static int primeForNumBits(int numBits) -{ - return (1 << numBits) + prime_deltas[numBits]; -} - -/* - Returns the smallest integer n such that - primeForNumBits(n) >= hint. -*/ -static int countBits(int hint) -{ - int numBits = 0; - int bits = hint; - - while (bits > 1) { - bits >>= 1; - numBits++; - } - - if (numBits >= (int)sizeof(prime_deltas)) { - numBits = sizeof(prime_deltas) - 1; - } else if (primeForNumBits(numBits) < hint) { - ++numBits; - } - return numBits; -} - -struct cso_node { - struct cso_node *next; - unsigned key; - void *value; -}; - -struct cso_hash_data { - struct cso_node *fakeNext; - struct cso_node **buckets; - int size; - int nodeSize; - short userNumBits; - short numBits; - int numBuckets; -}; - -struct cso_hash { - union { - struct cso_hash_data *d; - struct cso_node *e; - } data; -}; - -static void *cso_data_allocate_node(struct cso_hash_data *hash) -{ - return malloc(hash->nodeSize); -} - -static void cso_data_free_node(struct cso_node *node) -{ - /* XXX still a leak here. - * Need to cast value ptr to original cso type, then free the - * driver-specific data hanging off of it. For example: - struct cso_sampler *csamp = (struct cso_sampler *) node->value; - free(csamp->data); - */ - free(node->value); - free(node); -} - -static struct cso_node * -cso_hash_create_node(struct cso_hash *hash, - unsigned akey, void *avalue, - struct cso_node **anextNode) -{ - struct cso_node *node = cso_data_allocate_node(hash->data.d); - node->key = akey; - node->value = avalue; - - node->next = (struct cso_node*)(*anextNode); - *anextNode = node; - ++hash->data.d->size; - return node; -} - -static void cso_data_rehash(struct cso_hash_data *hash, int hint) -{ - if (hint < 0) { - hint = countBits(-hint); - if (hint < MinNumBits) - hint = MinNumBits; - hash->userNumBits = hint; - while (primeForNumBits(hint) < (hash->size >> 1)) - ++hint; - } else if (hint < MinNumBits) { - hint = MinNumBits; - } - - if (hash->numBits != hint) { - struct cso_node *e = (struct cso_node *)(hash); - struct cso_node **oldBuckets = hash->buckets; - int oldNumBuckets = hash->numBuckets; - int i = 0; - - hash->numBits = hint; - hash->numBuckets = primeForNumBits(hint); - hash->buckets = malloc(sizeof(struct cso_node*) * hash->numBuckets); - for (i = 0; i < hash->numBuckets; ++i) - hash->buckets[i] = e; - - for (i = 0; i < oldNumBuckets; ++i) { - struct cso_node *firstNode = oldBuckets[i]; - while (firstNode != e) { - unsigned h = firstNode->key; - struct cso_node *lastNode = firstNode; - while (lastNode->next != e && lastNode->next->key == h) - lastNode = lastNode->next; - - struct cso_node *afterLastNode = lastNode->next; - struct cso_node **beforeFirstNode = &hash->buckets[h % hash->numBuckets]; - while (*beforeFirstNode != e) - beforeFirstNode = &(*beforeFirstNode)->next; - lastNode->next = *beforeFirstNode; - *beforeFirstNode = firstNode; - firstNode = afterLastNode; - } - } - free(oldBuckets); - } -} - -static void cso_data_might_grow(struct cso_hash_data *hash) -{ - if (hash->size >= hash->numBuckets) - cso_data_rehash(hash, hash->numBits + 1); -} - -static void cso_data_has_shrunk(struct cso_hash_data *hash) -{ - if (hash->size <= (hash->numBuckets >> 3) && - hash->numBits > hash->userNumBits) { - int max = MAX(hash->numBits-2, hash->userNumBits); - cso_data_rehash(hash, max); - } -} - -static struct cso_node *cso_data_first_node(struct cso_hash_data *hash) -{ - struct cso_node *e = (struct cso_node *)(hash); - struct cso_node **bucket = hash->buckets; - int n = hash->numBuckets; - while (n--) { - if (*bucket != e) - return *bucket; - ++bucket; - } - return e; -} - -static struct cso_node **cso_hash_find_node(struct cso_hash *hash, unsigned akey) -{ - struct cso_node **node; - - if (hash->data.d->numBuckets) { - node = (struct cso_node **)(&hash->data.d->buckets[akey % hash->data.d->numBuckets]); - assert(*node == hash->data.e || (*node)->next); - while (*node != hash->data.e && (*node)->key != akey) - node = &(*node)->next; - } else { - node = (struct cso_node **)((const struct cso_node * const *)(&hash->data.e)); - } - return node; -} - -struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, - unsigned key, void *data) -{ - cso_data_might_grow(hash->data.d); - - struct cso_node **nextNode = cso_hash_find_node(hash, key); - struct cso_node *node = cso_hash_create_node(hash, key, data, nextNode); - struct cso_hash_iter iter = {hash, node}; - return iter; -} - -struct cso_hash * cso_hash_create(void) -{ - struct cso_hash *hash = malloc(sizeof(struct cso_hash)); - hash->data.d = malloc(sizeof(struct cso_hash_data)); - hash->data.d->fakeNext = 0; - hash->data.d->buckets = 0; - hash->data.d->size = 0; - hash->data.d->nodeSize = sizeof(struct cso_node); - hash->data.d->userNumBits = MinNumBits; - hash->data.d->numBits = 0; - hash->data.d->numBuckets = 0; - - return hash; -} - -void cso_hash_delete(struct cso_hash *hash) -{ - struct cso_node *e_for_x = (struct cso_node *)(hash->data.d); - struct cso_node **bucket = (struct cso_node **)(hash->data.d->buckets); - int n = hash->data.d->numBuckets; - while (n--) { - struct cso_node *cur = *bucket++; - while (cur != e_for_x) { - struct cso_node *next = cur->next; - cso_data_free_node(cur); - cur = next; - } - } - free(hash->data.d->buckets); - free(hash->data.d); - free(hash); -} - -struct cso_hash_iter cso_hash_find(struct cso_hash *hash, - unsigned key) -{ - struct cso_node **nextNode = cso_hash_find_node(hash, key); - struct cso_hash_iter iter = {hash, *nextNode}; - return iter; -} - -unsigned cso_hash_iter_key(struct cso_hash_iter iter) -{ - if (!iter.node || iter.hash->data.e == iter.node) - return 0; - return iter.node->key; -} - -void * cso_hash_iter_data(struct cso_hash_iter iter) -{ - if (!iter.node || iter.hash->data.e == iter.node) - return 0; - return iter.node->value; -} - -static struct cso_node *cso_hash_data_next(struct cso_node *node) -{ - union { - struct cso_node *next; - struct cso_node *e; - struct cso_hash_data *d; - } a; - a.next = node->next; - if (!a.next) { - fprintf(stderr, "iterating beyond the last element\n"); - return 0; - } - if (a.next->next) - return a.next; - - int start = (node->key % a.d->numBuckets) + 1; - struct cso_node **bucket = a.d->buckets + start; - int n = a.d->numBuckets - start; - while (n--) { - if (*bucket != a.e) - return *bucket; - ++bucket; - } - return a.e; -} - - -static struct cso_node *cso_hash_data_prev(struct cso_node *node) -{ - union { - struct cso_node *e; - struct cso_hash_data *d; - } a; - - a.e = node; - while (a.e->next) - a.e = a.e->next; - - int start; - if (node == a.e) - start = a.d->numBuckets - 1; - else - start = node->key % a.d->numBuckets; - - struct cso_node *sentinel = node; - struct cso_node **bucket = a.d->buckets + start; - while (start >= 0) { - if (*bucket != sentinel) { - struct cso_node *prev = *bucket; - while (prev->next != sentinel) - prev = prev->next; - return prev; - } - - sentinel = a.e; - --bucket; - --start; - } - fprintf(stderr, "iterating backward beyond first element\n"); - return a.e; -} - -struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter) -{ - struct cso_hash_iter next = {iter.hash, cso_hash_data_next(iter.node)}; - return next; -} - -int cso_hash_iter_is_null(struct cso_hash_iter iter) -{ - if (!iter.node || iter.node == iter.hash->data.e) - return 1; - return 0; -} - -void * cso_hash_take(struct cso_hash *hash, - unsigned akey) -{ - struct cso_node **node = cso_hash_find_node(hash, akey); - if (*node != hash->data.e) { - void *t = (*node)->value; - struct cso_node *next = (*node)->next; - cso_data_free_node(*node); - *node = next; - --hash->data.d->size; - cso_data_has_shrunk(hash->data.d); - return t; - } - return 0; -} - -struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter) -{ - struct cso_hash_iter prev = {iter.hash, - cso_hash_data_prev(iter.node)}; - return prev; -} - -struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash) -{ - struct cso_hash_iter iter = {hash, cso_data_first_node(hash->data.d)}; - return iter; -} diff --git a/src/gallium/aux/cso_cache/cso_hash.h b/src/gallium/aux/cso_cache/cso_hash.h deleted file mode 100644 index b4aa111860..0000000000 --- a/src/gallium/aux/cso_cache/cso_hash.h +++ /dev/null @@ -1,62 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin - */ - -#ifndef CSO_HASH_H -#define CSO_HASH_H - -struct cso_hash; -struct cso_node; - -struct cso_hash_iter { - struct cso_hash *hash; - struct cso_node *node; -}; - -struct cso_hash *cso_hash_create(void); -void cso_hash_delete(struct cso_hash *hash); - -struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, unsigned key, - void *data); -void *cso_hash_take(struct cso_hash *hash, unsigned key); - -struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash); -struct cso_hash_iter cso_hash_find(struct cso_hash *hash, unsigned key); - - -int cso_hash_iter_is_null(struct cso_hash_iter iter); -unsigned cso_hash_iter_key(struct cso_hash_iter iter); -void *cso_hash_iter_data(struct cso_hash_iter iter); - -struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter); -struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter); - -#endif diff --git a/src/gallium/aux/draw/Makefile b/src/gallium/aux/draw/Makefile deleted file mode 100644 index 451911a354..0000000000 --- a/src/gallium/aux/draw/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -default: - cd .. ; make diff --git a/src/gallium/aux/draw/draw_clip.c b/src/gallium/aux/draw/draw_clip.c deleted file mode 100644 index e3051507ea..0000000000 --- a/src/gallium/aux/draw/draw_clip.c +++ /dev/null @@ -1,488 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief Clipping stage - * - * \author Keith Whitwell - */ - - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" - -#include "draw_context.h" -#include "draw_private.h" - - -#ifndef IS_NEGATIVE -#define IS_NEGATIVE(X) ((X) < 0.0) -#endif - -#ifndef DIFFERENT_SIGNS -#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F) -#endif - -#ifndef MAX_CLIPPED_VERTICES -#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1) -#endif - - - -struct clipper { - struct draw_stage stage; /**< base class */ - - /* Basically duplicate some of the flatshading logic here: - */ - boolean flat; - uint num_color_attribs; - uint color_attribs[4]; /* front/back primary/secondary colors */ - - float (*plane)[4]; -}; - - -/* This is a bit confusing: - */ -static INLINE struct clipper *clipper_stage( struct draw_stage *stage ) -{ - return (struct clipper *)stage; -} - - -#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT))) - - -/* All attributes are float[4], so this is easy: - */ -static void interp_attr( float *fdst, - float t, - const float *fin, - const float *fout ) -{ - fdst[0] = LINTERP( t, fout[0], fin[0] ); - fdst[1] = LINTERP( t, fout[1], fin[1] ); - fdst[2] = LINTERP( t, fout[2], fin[2] ); - fdst[3] = LINTERP( t, fout[3], fin[3] ); -} - -static void copy_colors( struct draw_stage *stage, - struct vertex_header *dst, - const struct vertex_header *src ) -{ - const struct clipper *clipper = clipper_stage(stage); - uint i; - for (i = 0; i < clipper->num_color_attribs; i++) { - const uint attr = clipper->color_attribs[i]; - COPY_4FV(dst->data[attr], src->data[attr]); - } -} - - - -/* Interpolate between two vertices to produce a third. - */ -static void interp( const struct clipper *clip, - struct vertex_header *dst, - float t, - const struct vertex_header *out, - const struct vertex_header *in ) -{ - const unsigned nr_attrs = clip->stage.draw->num_vs_outputs; - unsigned j; - - /* Vertex header. - */ - { - dst->clipmask = 0; - dst->edgeflag = 0; - dst->pad = 0; - dst->vertex_id = UNDEFINED_VERTEX_ID; - } - - /* Clip coordinates: interpolate normally - */ - { - interp_attr(dst->clip, t, in->clip, out->clip); - } - - /* Do the projective divide and insert window coordinates: - */ - { - const float *pos = dst->clip; - const float *scale = clip->stage.draw->viewport.scale; - const float *trans = clip->stage.draw->viewport.translate; - const float oow = 1.0f / pos[3]; - - dst->data[0][0] = pos[0] * oow * scale[0] + trans[0]; - dst->data[0][1] = pos[1] * oow * scale[1] + trans[1]; - dst->data[0][2] = pos[2] * oow * scale[2] + trans[2]; - dst->data[0][3] = oow; - } - - /* Other attributes - * Note: start at 1 to skip winpos (data[0]) since we just computed - * it above. - */ - for (j = 1; j < nr_attrs; j++) { - interp_attr(dst->data[j], t, in->data[j], out->data[j]); - } -} - - -static void emit_poly( struct draw_stage *stage, - struct vertex_header **inlist, - unsigned n, - const struct prim_header *origPrim) -{ - struct prim_header header; - unsigned i; - - /* later stages may need the determinant, but only the sign matters */ - header.det = origPrim->det; - - for (i = 2; i < n; i++) { - header.v[0] = inlist[i-1]; - header.v[1] = inlist[i]; - header.v[2] = inlist[0]; /* keep in v[2] for flatshading */ - - { - unsigned tmp1 = header.v[1]->edgeflag; - unsigned tmp2 = header.v[2]->edgeflag; - - if (i != n-1) header.v[1]->edgeflag = 0; - if (i != 2) header.v[2]->edgeflag = 0; - - header.edgeflags = ((header.v[0]->edgeflag << 0) | - (header.v[1]->edgeflag << 1) | - (header.v[2]->edgeflag << 2)); - - stage->next->tri( stage->next, &header ); - - header.v[1]->edgeflag = tmp1; - header.v[2]->edgeflag = tmp2; - } - } -} - - - - -/* Clip a triangle against the viewport and user clip planes. - */ -static void -do_clip_tri( struct draw_stage *stage, - struct prim_header *header, - unsigned clipmask ) -{ - struct clipper *clipper = clipper_stage( stage ); - struct vertex_header *a[MAX_CLIPPED_VERTICES]; - struct vertex_header *b[MAX_CLIPPED_VERTICES]; - struct vertex_header **inlist = a; - struct vertex_header **outlist = b; - unsigned tmpnr = 0; - unsigned n = 3; - unsigned i; - - inlist[0] = header->v[0]; - inlist[1] = header->v[1]; - inlist[2] = header->v[2]; - - while (clipmask && n >= 3) { - const unsigned plane_idx = ffs(clipmask)-1; - const float *plane = clipper->plane[plane_idx]; - struct vertex_header *vert_prev = inlist[0]; - float dp_prev = dot4( vert_prev->clip, plane ); - unsigned outcount = 0; - - clipmask &= ~(1<clip, plane ); - - if (!IS_NEGATIVE(dp_prev)) { - outlist[outcount++] = vert_prev; - } - - if (DIFFERENT_SIGNS(dp, dp_prev)) { - struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++]; - outlist[outcount++] = new_vert; - - if (IS_NEGATIVE(dp)) { - /* Going out of bounds. Avoid division by zero as we - * know dp != dp_prev from DIFFERENT_SIGNS, above. - */ - float t = dp / (dp - dp_prev); - interp( clipper, new_vert, t, vert, vert_prev ); - - /* Force edgeflag true in this case: - */ - new_vert->edgeflag = 1; - } else { - /* Coming back in. - */ - float t = dp_prev / (dp_prev - dp); - interp( clipper, new_vert, t, vert_prev, vert ); - - /* Copy starting vert's edgeflag: - */ - new_vert->edgeflag = vert_prev->edgeflag; - } - } - - vert_prev = vert; - dp_prev = dp; - } - - { - struct vertex_header **tmp = inlist; - inlist = outlist; - outlist = tmp; - n = outcount; - } - } - - /* If flat-shading, copy color to new provoking vertex. - */ - if (clipper->flat && inlist[0] != header->v[2]) { - if (1) { - inlist[0] = dup_vert(stage, inlist[0], tmpnr++); - } - - copy_colors(stage, inlist[0], header->v[2]); - } - - - - /* Emit the polygon as triangles to the setup stage: - */ - if (n >= 3) - emit_poly( stage, inlist, n, header ); -} - - -/* Clip a line against the viewport and user clip planes. - */ -static void -do_clip_line( struct draw_stage *stage, - struct prim_header *header, - unsigned clipmask ) -{ - const struct clipper *clipper = clipper_stage( stage ); - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - const float *pos0 = v0->clip; - const float *pos1 = v1->clip; - float t0 = 0.0F; - float t1 = 0.0F; - struct prim_header newprim; - - while (clipmask) { - const unsigned plane_idx = ffs(clipmask)-1; - const float *plane = clipper->plane[plane_idx]; - const float dp0 = dot4( pos0, plane ); - const float dp1 = dot4( pos1, plane ); - - if (dp1 < 0.0F) { - float t = dp1 / (dp1 - dp0); - t1 = MAX2(t1, t); - } - - if (dp0 < 0.0F) { - float t = dp0 / (dp0 - dp1); - t0 = MAX2(t0, t); - } - - if (t0 + t1 >= 1.0F) - return; /* discard */ - - clipmask &= ~(1 << plane_idx); /* turn off this plane's bit */ - } - - if (v0->clipmask) { - interp( clipper, stage->tmp[0], t0, v0, v1 ); - - if (clipper->flat) - copy_colors(stage, stage->tmp[0], v0); - - newprim.v[0] = stage->tmp[0]; - } - else { - newprim.v[0] = v0; - } - - if (v1->clipmask) { - interp( clipper, stage->tmp[1], t1, v1, v0 ); - newprim.v[1] = stage->tmp[1]; - } - else { - newprim.v[1] = v1; - } - - stage->next->line( stage->next, &newprim ); -} - - -static void -clip_point( struct draw_stage *stage, - struct prim_header *header ) -{ - if (header->v[0]->clipmask == 0) - stage->next->point( stage->next, header ); -} - - -static void -clip_line( struct draw_stage *stage, - struct prim_header *header ) -{ - unsigned clipmask = (header->v[0]->clipmask | - header->v[1]->clipmask); - - if (clipmask == 0) { - /* no clipping needed */ - stage->next->line( stage->next, header ); - } - else if ((header->v[0]->clipmask & - header->v[1]->clipmask) == 0) { - do_clip_line(stage, header, clipmask); - } - /* else, totally clipped */ -} - - -static void -clip_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - unsigned clipmask = (header->v[0]->clipmask | - header->v[1]->clipmask | - header->v[2]->clipmask); - - if (clipmask == 0) { - /* no clipping needed */ - stage->next->tri( stage->next, header ); - } - else if ((header->v[0]->clipmask & - header->v[1]->clipmask & - header->v[2]->clipmask) == 0) { - do_clip_tri(stage, header, clipmask); - } -} - -/* Update state. Could further delay this until we hit the first - * primitive that really requires clipping. - */ -static void -clip_init_state( struct draw_stage *stage ) -{ - struct clipper *clipper = clipper_stage( stage ); - - clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE; - - if (clipper->flat) { - const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; - uint i; - - clipper->num_color_attribs = 0; - for (i = 0; i < vs->num_outputs; i++) { - if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR || - vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { - clipper->color_attribs[clipper->num_color_attribs++] = i; - } - } - } - - stage->tri = clip_tri; - stage->line = clip_line; -} - - - -static void clip_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - clip_init_state( stage ); - stage->tri( stage, header ); -} - -static void clip_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - clip_init_state( stage ); - stage->line( stage, header ); -} - - -static void clip_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->tri = clip_first_tri; - stage->line = clip_first_line; - stage->next->flush( stage->next, flags ); -} - - -static void clip_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void clip_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Allocate a new clipper stage. - * \return pointer to new stage object - */ -struct draw_stage *draw_clip_stage( struct draw_context *draw ) -{ - struct clipper *clipper = CALLOC_STRUCT(clipper); - - draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ); - - clipper->stage.draw = draw; - clipper->stage.point = clip_point; - clipper->stage.line = clip_first_line; - clipper->stage.tri = clip_first_tri; - clipper->stage.flush = clip_flush; - clipper->stage.reset_stipple_counter = clip_reset_stipple_counter; - clipper->stage.destroy = clip_destroy; - - clipper->plane = draw->plane; - - return &clipper->stage; -} diff --git a/src/gallium/aux/draw/draw_context.c b/src/gallium/aux/draw/draw_context.c deleted file mode 100644 index 4be3830316..0000000000 --- a/src/gallium/aux/draw/draw_context.c +++ /dev/null @@ -1,293 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - - -#include "pipe/p_util.h" -#include "draw_context.h" -#include "draw_private.h" - - - -struct draw_context *draw_create( void ) -{ - struct draw_context *draw = CALLOC_STRUCT( draw_context ); - -#if defined(__i386__) || defined(__386__) - draw->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; -#else - draw->use_sse = FALSE; -#endif - - /* create pipeline stages */ - draw->pipeline.wide = draw_wide_stage( draw ); - draw->pipeline.stipple = draw_stipple_stage( draw ); - draw->pipeline.unfilled = draw_unfilled_stage( draw ); - draw->pipeline.twoside = draw_twoside_stage( draw ); - draw->pipeline.offset = draw_offset_stage( draw ); - draw->pipeline.clip = draw_clip_stage( draw ); - draw->pipeline.flatshade = draw_flatshade_stage( draw ); - draw->pipeline.cull = draw_cull_stage( draw ); - draw->pipeline.validate = draw_validate_stage( draw ); - draw->pipeline.first = draw->pipeline.validate; - - 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 ); - ASSIGN_4V( draw->plane[3], 0, 1, 0, 1 ); - ASSIGN_4V( draw->plane[4], 0, 0, 1, 1 ); /* yes these are correct */ - ASSIGN_4V( draw->plane[5], 0, 0, -1, 1 ); /* mesa's a bit wonky */ - draw->nr_planes = 6; - - /* Statically allocate maximum sized vertices for the cache - could be cleverer... - */ - { - uint i; - const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; - char *tmp = align_malloc(Elements(draw->vcache.vertex) * size, 16); - - for (i = 0; i < Elements(draw->vcache.vertex); i++) - draw->vcache.vertex[i] = (struct vertex_header *)(tmp + i * size); - } - - draw->shader_queue_flush = draw_vertex_shader_queue_flush; - - draw->convert_wide_points = TRUE; - draw->convert_wide_lines = TRUE; - - draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ - - draw_vertex_cache_invalidate( draw ); - draw_set_mapped_element_buffer( draw, 0, NULL ); - - return draw; -} - - -void draw_destroy( struct draw_context *draw ) -{ - draw->pipeline.wide->destroy( draw->pipeline.wide ); - draw->pipeline.stipple->destroy( draw->pipeline.stipple ); - draw->pipeline.unfilled->destroy( draw->pipeline.unfilled ); - draw->pipeline.twoside->destroy( draw->pipeline.twoside ); - draw->pipeline.offset->destroy( draw->pipeline.offset ); - draw->pipeline.clip->destroy( draw->pipeline.clip ); - draw->pipeline.flatshade->destroy( draw->pipeline.flatshade ); - draw->pipeline.cull->destroy( draw->pipeline.cull ); - draw->pipeline.validate->destroy( draw->pipeline.validate ); - if (draw->pipeline.rasterize) - draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); - tgsi_exec_machine_free_data(&draw->machine); - align_free( draw->vcache.vertex[0] ); /* Frees all the vertices. */ - FREE( draw ); -} - - - -void draw_flush( struct draw_context *draw ) -{ - draw_do_flush( draw, DRAW_FLUSH_BACKEND ); -} - - - -/** - * Register new primitive rasterization/rendering state. - * This causes the drawing pipeline to be rebuilt. - */ -void draw_set_rasterizer_state( struct draw_context *draw, - const struct pipe_rasterizer_state *raster ) -{ - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - - draw->rasterizer = raster; -} - - -/** - * Plug in the primitive rendering/rasterization stage (which is the last - * stage in the drawing pipeline). - * This is provided by the device driver. - */ -void draw_set_rasterize_stage( struct draw_context *draw, - struct draw_stage *stage ) -{ - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - - draw->pipeline.rasterize = stage; -} - - -/** - * Set the draw module's clipping state. - */ -void draw_set_clip_state( struct draw_context *draw, - const struct pipe_clip_state *clip ) -{ - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - - assert(clip->nr <= PIPE_MAX_CLIP_PLANES); - memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0])); - draw->nr_planes = 6 + clip->nr; -} - - -/** - * Set the draw module's viewport state. - */ -void draw_set_viewport_state( struct draw_context *draw, - const struct pipe_viewport_state *viewport ) -{ - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->viewport = *viewport; /* struct copy */ -} - - - -void -draw_set_vertex_buffer(struct draw_context *draw, - unsigned attr, - const struct pipe_vertex_buffer *buffer) -{ - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - assert(attr < PIPE_ATTRIB_MAX); - draw->vertex_buffer[attr] = *buffer; -} - - -void -draw_set_vertex_element(struct draw_context *draw, - unsigned attr, - const struct pipe_vertex_element *element) -{ - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - assert(attr < PIPE_ATTRIB_MAX); - draw->vertex_element[attr] = *element; -} - - -/** - * Tell drawing context where to find mapped vertex buffers. - */ -void -draw_set_mapped_vertex_buffer(struct draw_context *draw, - unsigned attr, const void *buffer) -{ - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - draw->user.vbuffer[attr] = buffer; -} - - -void -draw_set_mapped_constant_buffer(struct draw_context *draw, - const void *buffer) -{ - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - draw->user.constants = buffer; -} - - -/** - * Tells the draw module whether to convert wide points (size != 1) - * into triangles. - */ -void -draw_convert_wide_points(struct draw_context *draw, boolean enable) -{ - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->convert_wide_points = enable; -} - - -/** - * Tells the draw module whether to convert wide lines (width != 1) - * into triangles. - */ -void -draw_convert_wide_lines(struct draw_context *draw, boolean enable) -{ - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->convert_wide_lines = enable; -} - - -/** - * Allocate space for temporary post-transform vertices, such as for clipping. - */ -void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) -{ - assert(!stage->tmp); - - stage->nr_tmps = nr; - - if (nr) { - ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); - unsigned i; - - stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); - - for (i = 0; i < nr; i++) - stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); - } -} - - -void draw_free_temp_verts( struct draw_stage *stage ) -{ - if (stage->tmp) { - FREE( stage->tmp[0] ); - FREE( stage->tmp ); - stage->tmp = NULL; - } -} - - -boolean draw_use_sse(struct draw_context *draw) -{ - return (boolean) draw->use_sse; -} - - -void draw_reset_vertex_ids(struct draw_context *draw) -{ - struct draw_stage *stage = draw->pipeline.first; - - while (stage) { - unsigned i; - - for (i = 0; i < stage->nr_tmps; i++) - stage->tmp[i]->vertex_id = UNDEFINED_VERTEX_ID; - - stage = stage->next; - } - - draw_vertex_cache_reset_vertex_ids(draw); -} diff --git a/src/gallium/aux/draw/draw_context.h b/src/gallium/aux/draw/draw_context.h deleted file mode 100644 index ddeb184497..0000000000 --- a/src/gallium/aux/draw/draw_context.h +++ /dev/null @@ -1,142 +0,0 @@ - -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief Public interface into the drawing module. - */ - -/* Authors: Keith Whitwell - */ - - -#ifndef DRAW_CONTEXT_H -#define DRAW_CONTEXT_H - - -#include "pipe/p_state.h" - - -struct vertex_buffer; -struct vertex_info; -struct draw_context; -struct draw_stage; -struct draw_vertex_shader; - - -/** - * Clipmask flags - */ -/*@{*/ -#define CLIP_RIGHT_BIT 0x01 -#define CLIP_LEFT_BIT 0x02 -#define CLIP_TOP_BIT 0x04 -#define CLIP_BOTTOM_BIT 0x08 -#define CLIP_NEAR_BIT 0x10 -#define CLIP_FAR_BIT 0x20 -/*@}*/ - -/** - * Bitshift for each clip flag - */ -/*@{*/ -#define CLIP_RIGHT_SHIFT 0 -#define CLIP_LEFT_SHIFT 1 -#define CLIP_TOP_SHIFT 2 -#define CLIP_BOTTOM_SHIFT 3 -#define CLIP_NEAR_SHIFT 4 -#define CLIP_FAR_SHIFT 5 -/*@}*/ - - -struct draw_context *draw_create( void ); - -void draw_destroy( struct draw_context *draw ); - -void draw_set_viewport_state( struct draw_context *draw, - const struct pipe_viewport_state *viewport ); - -void draw_set_clip_state( struct draw_context *pipe, - const struct pipe_clip_state *clip ); - -void draw_set_rasterizer_state( struct draw_context *draw, - const struct pipe_rasterizer_state *raster ); - -void draw_set_rasterize_stage( struct draw_context *draw, - struct draw_stage *stage ); - -void draw_convert_wide_points(struct draw_context *draw, boolean enable); - -void draw_convert_wide_lines(struct draw_context *draw, boolean enable); - - -struct draw_vertex_shader * -draw_create_vertex_shader(struct draw_context *draw, - const struct pipe_shader_state *shader); -void draw_bind_vertex_shader(struct draw_context *draw, - struct draw_vertex_shader *dvs); -void draw_delete_vertex_shader(struct draw_context *draw, - struct draw_vertex_shader *dvs); - -boolean draw_use_sse(struct draw_context *draw); - -void draw_set_vertex_buffer(struct draw_context *draw, - unsigned attr, - const struct pipe_vertex_buffer *buffer); - -void draw_set_vertex_element(struct draw_context *draw, - unsigned attr, - const struct pipe_vertex_element *element); - -void draw_set_mapped_element_buffer( struct draw_context *draw, - unsigned eltSize, void *elements ); - -void draw_set_mapped_vertex_buffer(struct draw_context *draw, - unsigned attr, const void *buffer); - -void draw_set_mapped_constant_buffer(struct draw_context *draw, - const void *buffer); - - -/*********************************************************************** - * draw_prim.c - */ - -void draw_arrays(struct draw_context *draw, unsigned prim, - unsigned start, unsigned count); - -void draw_flush(struct draw_context *draw); - -/*********************************************************************** - * draw_debug.c - */ -boolean draw_validate_prim( unsigned prim, unsigned length ); -unsigned draw_trim_prim( unsigned mode, unsigned count ); - - - -#endif /* DRAW_CONTEXT_H */ diff --git a/src/gallium/aux/draw/draw_cull.c b/src/gallium/aux/draw/draw_cull.c deleted file mode 100644 index 8177b0ac86..0000000000 --- a/src/gallium/aux/draw/draw_cull.c +++ /dev/null @@ -1,150 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief Drawing stage for polygon culling - */ - -/* Authors: Keith Whitwell - */ - - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "draw_private.h" - - -struct cull_stage { - struct draw_stage stage; - unsigned winding; /**< which winding(s) to cull (one of PIPE_WINDING_x) */ -}; - - -static INLINE struct cull_stage *cull_stage( struct draw_stage *stage ) -{ - return (struct cull_stage *)stage; -} - - - - -static void cull_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - /* Window coords: */ - const float *v0 = header->v[0]->data[0]; - const float *v1 = header->v[1]->data[0]; - const float *v2 = header->v[2]->data[0]; - - /* edge vectors e = v0 - v2, f = v1 - v2 */ - const float ex = v0[0] - v2[0]; - const float ey = v0[1] - v2[1]; - const float fx = v1[0] - v2[0]; - const float fy = v1[1] - v2[1]; - - /* det = cross(e,f).z */ - header->det = ex * fy - ey * fx; - - if (header->det != 0) { - /* if (det < 0 then Z points toward camera and triangle is - * counter-clockwise winding. - */ - unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; - - if ((winding & cull_stage(stage)->winding) == 0) { - /* triangle is not culled, pass to next stage */ - stage->next->tri( stage->next, header ); - } - } -} - -static void cull_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct cull_stage *cull = cull_stage(stage); - - cull->winding = stage->draw->rasterizer->cull_mode; - - stage->tri = cull_tri; - stage->tri( stage, header ); -} - - - -static void cull_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void cull_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void cull_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->tri = cull_first_tri; - stage->next->flush( stage->next, flags ); -} - -static void cull_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void cull_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create a new polygon culling stage. - */ -struct draw_stage *draw_cull_stage( struct draw_context *draw ) -{ - struct cull_stage *cull = CALLOC_STRUCT(cull_stage); - - draw_alloc_temp_verts( &cull->stage, 0 ); - - cull->stage.draw = draw; - cull->stage.next = NULL; - cull->stage.point = cull_point; - cull->stage.line = cull_line; - cull->stage.tri = cull_first_tri; - cull->stage.flush = cull_flush; - cull->stage.reset_stipple_counter = cull_reset_stipple_counter; - cull->stage.destroy = cull_destroy; - - return &cull->stage; -} diff --git a/src/gallium/aux/draw/draw_debug.c b/src/gallium/aux/draw/draw_debug.c deleted file mode 100644 index d6220b5f62..0000000000 --- a/src/gallium/aux/draw/draw_debug.c +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#include "draw_private.h" -#include "draw_context.h" - - - -static void -draw_prim_info(unsigned prim, unsigned *first, unsigned *incr) -{ - assert(prim >= PIPE_PRIM_POINTS); - assert(prim <= PIPE_PRIM_POLYGON); - - switch (prim) { - case PIPE_PRIM_POINTS: - *first = 1; - *incr = 1; - break; - case PIPE_PRIM_LINES: - *first = 2; - *incr = 2; - break; - case PIPE_PRIM_LINE_STRIP: - *first = 2; - *incr = 1; - break; - case PIPE_PRIM_LINE_LOOP: - *first = 2; - *incr = 1; - break; - case PIPE_PRIM_TRIANGLES: - *first = 3; - *incr = 3; - break; - case PIPE_PRIM_TRIANGLE_STRIP: - *first = 3; - *incr = 1; - break; - case PIPE_PRIM_TRIANGLE_FAN: - case PIPE_PRIM_POLYGON: - *first = 3; - *incr = 1; - break; - case PIPE_PRIM_QUADS: - *first = 4; - *incr = 4; - break; - case PIPE_PRIM_QUAD_STRIP: - *first = 4; - *incr = 2; - break; - default: - assert(0); - *first = 1; - *incr = 1; - break; - } -} - - -unsigned -draw_trim_prim( unsigned mode, unsigned count ) -{ - unsigned length, first, incr; - - draw_prim_info( mode, &first, &incr ); - - if (count < first) - length = 0; - else - length = count - (count - first) % incr; - - return length; -} - - -boolean -draw_validate_prim( unsigned mode, unsigned count ) -{ - return (count > 0 && - count == draw_trim_prim( mode, count )); -} - diff --git a/src/gallium/aux/draw/draw_flatshade.c b/src/gallium/aux/draw/draw_flatshade.c deleted file mode 100644 index 4398abbc60..0000000000 --- a/src/gallium/aux/draw/draw_flatshade.c +++ /dev/null @@ -1,205 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -/** subclass of draw_stage */ -struct flat_stage -{ - struct draw_stage stage; - - uint num_color_attribs; - uint color_attribs[4]; /* front/back primary/secondary colors */ -}; - - -static INLINE struct flat_stage * -flat_stage(struct draw_stage *stage) -{ - return (struct flat_stage *) stage; -} - - -/** Copy all the color attributes from 'src' vertex to 'dst' vertex */ -static INLINE void copy_colors( struct draw_stage *stage, - struct vertex_header *dst, - const struct vertex_header *src ) -{ - const struct flat_stage *flat = flat_stage(stage); - uint i; - for (i = 0; i < flat->num_color_attribs; i++) { - const uint attr = flat->color_attribs[i]; - COPY_4FV(dst->data[attr], src->data[attr]); - } -} - - -/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */ -static INLINE void copy_colors2( struct draw_stage *stage, - struct vertex_header *dst0, - struct vertex_header *dst1, - const struct vertex_header *src ) -{ - const struct flat_stage *flat = flat_stage(stage); - uint i; - for (i = 0; i < flat->num_color_attribs; i++) { - const uint attr = flat->color_attribs[i]; - COPY_4FV(dst0->data[attr], src->data[attr]); - COPY_4FV(dst1->data[attr], src->data[attr]); - } -} - - -/** - * Flatshade tri. Required for clipping and when unfilled tris are - * active, otherwise handled by hardware. - */ -static void flatshade_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.det = header->det; - tmp.edgeflags = header->edgeflags; - tmp.v[0] = dup_vert(stage, header->v[0], 0); - tmp.v[1] = dup_vert(stage, header->v[1], 1); - tmp.v[2] = header->v[2]; - - copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]); - - stage->next->tri( stage->next, &tmp ); -} - - -/** - * Flatshade line. Required for clipping. - */ -static void flatshade_line( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.v[0] = dup_vert(stage, header->v[0], 0); - tmp.v[1] = header->v[1]; - - copy_colors(stage, tmp.v[0], tmp.v[1]); - - stage->next->line( stage->next, &tmp ); -} - - -static void flatshade_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void flatshade_init_state( struct draw_stage *stage ) -{ - struct flat_stage *flat = flat_stage(stage); - const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; - uint i; - - /* Find which vertex shader outputs are colors, make a list */ - flat->num_color_attribs = 0; - for (i = 0; i < vs->num_outputs; i++) { - if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR || - vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { - flat->color_attribs[flat->num_color_attribs++] = i; - } - } - - stage->line = flatshade_line; - stage->tri = flatshade_tri; -} - -static void flatshade_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - flatshade_init_state( stage ); - stage->tri( stage, header ); -} - -static void flatshade_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - flatshade_init_state( stage ); - stage->line( stage, header ); -} - - -static void flatshade_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->tri = flatshade_first_tri; - stage->line = flatshade_first_line; - stage->next->flush( stage->next, flags ); -} - - -static void flatshade_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void flatshade_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create flatshading drawing stage. - */ -struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) -{ - struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage); - - draw_alloc_temp_verts( &flatshade->stage, 2 ); - - flatshade->stage.draw = draw; - flatshade->stage.next = NULL; - flatshade->stage.point = flatshade_point; - flatshade->stage.line = flatshade_first_line; - flatshade->stage.tri = flatshade_first_tri; - flatshade->stage.flush = flatshade_flush; - flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter; - flatshade->stage.destroy = flatshade_destroy; - - return &flatshade->stage; -} - - diff --git a/src/gallium/aux/draw/draw_offset.c b/src/gallium/aux/draw/draw_offset.c deleted file mode 100644 index dbc676deae..0000000000 --- a/src/gallium/aux/draw/draw_offset.c +++ /dev/null @@ -1,186 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief polygon offset state - * - * \author Keith Whitwell - * \author Brian Paul - */ - -#include "pipe/p_util.h" -#include "draw_private.h" - - - -struct offset_stage { - struct draw_stage stage; - - float scale; - float units; -}; - - - -static INLINE struct offset_stage *offset_stage( struct draw_stage *stage ) -{ - return (struct offset_stage *) stage; -} - - - - - -/** - * Offset tri Z. Some hardware can handle this, but not usually when - * doing unfilled rendering. - */ -static void do_offset_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct offset_stage *offset = offset_stage(stage); - float inv_det = 1.0f / header->det; - - /* Window coords: - */ - float *v0 = header->v[0]->data[0]; - float *v1 = header->v[1]->data[0]; - float *v2 = header->v[2]->data[0]; - - /* edge vectors e = v0 - v2, f = v1 - v2 */ - float ex = v0[0] - v2[0]; - float ey = v0[1] - v2[1]; - float ez = v0[2] - v2[2]; - float fx = v1[0] - v2[0]; - float fy = v1[1] - v2[1]; - float fz = v1[2] - v2[2]; - - /* (a,b) = cross(e,f).xy */ - float a = ey*fz - ez*fy; - float b = ez*fx - ex*fz; - - float dzdx = FABSF(a * inv_det); - float dzdy = FABSF(b * inv_det); - - float zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale; - - /* - * Note: we're applying the offset and clamping per-vertex. - * Ideally, the offset is applied per-fragment prior to fragment shading. - */ - v0[2] = CLAMP(v0[2] + zoffset, 0.0f, 1.0f); - v1[2] = CLAMP(v1[2] + zoffset, 0.0f, 1.0f); - v2[2] = CLAMP(v2[2] + zoffset, 0.0f, 1.0f); - - stage->next->tri( stage->next, header ); -} - - -static void offset_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.det = header->det; - tmp.edgeflags = header->edgeflags; - tmp.v[0] = dup_vert(stage, header->v[0], 0); - tmp.v[1] = dup_vert(stage, header->v[1], 1); - tmp.v[2] = dup_vert(stage, header->v[2], 2); - - do_offset_tri( stage, &tmp ); -} - - -static void offset_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct offset_stage *offset = offset_stage(stage); - float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */ - - offset->units = stage->draw->rasterizer->offset_units * mrd; - offset->scale = stage->draw->rasterizer->offset_scale; - - stage->tri = offset_tri; - stage->tri( stage, header ); -} - - -static void offset_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void offset_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void offset_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->tri = offset_first_tri; - stage->next->flush( stage->next, flags ); -} - - -static void offset_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void offset_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create polygon offset drawing stage. - */ -struct draw_stage *draw_offset_stage( struct draw_context *draw ) -{ - struct offset_stage *offset = CALLOC_STRUCT(offset_stage); - - draw_alloc_temp_verts( &offset->stage, 3 ); - - offset->stage.draw = draw; - offset->stage.next = NULL; - offset->stage.point = offset_point; - offset->stage.line = offset_line; - offset->stage.tri = offset_first_tri; - offset->stage.flush = offset_flush; - offset->stage.reset_stipple_counter = offset_reset_stipple_counter; - offset->stage.destroy = offset_destroy; - - return &offset->stage; -} diff --git a/src/gallium/aux/draw/draw_prim.c b/src/gallium/aux/draw/draw_prim.c deleted file mode 100644 index 51e2242719..0000000000 --- a/src/gallium/aux/draw/draw_prim.c +++ /dev/null @@ -1,482 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#include "pipe/p_debug.h" - -#include "draw_private.h" -#include "draw_context.h" - - - -#define RP_NONE 0 -#define RP_POINT 1 -#define RP_LINE 2 -#define RP_TRI 3 - - -static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { - RP_POINT, - RP_LINE, - RP_LINE, - RP_LINE, - RP_TRI, - RP_TRI, - RP_TRI, - RP_TRI, - RP_TRI, - RP_TRI -}; - - -static void draw_prim_queue_flush( struct draw_context *draw ) -{ - unsigned i; - - if (0) - debug_printf("Flushing with %d prims, %d verts\n", - draw->pq.queue_nr, draw->vs.queue_nr); - - assert (draw->pq.queue_nr != 0); - - /* NOTE: we cannot save draw->pipeline->first in a local var because - * draw->pipeline->first is often changed by the first call to tri(), - * line(), etc. - */ - if (draw->rasterizer->line_stipple_enable) { - switch (draw->reduced_prim) { - case RP_TRI: - for (i = 0; i < draw->pq.queue_nr; i++) { - if (draw->pq.queue[i].reset_line_stipple) - draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); - - draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] ); - } - break; - case RP_LINE: - for (i = 0; i < draw->pq.queue_nr; i++) { - if (draw->pq.queue[i].reset_line_stipple) - draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); - - draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] ); - } - break; - case RP_POINT: - draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] ); - break; - } - } - else { - switch (draw->reduced_prim) { - case RP_TRI: - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] ); - break; - case RP_LINE: - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] ); - break; - case RP_POINT: - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] ); - break; - } - } - - draw->pq.queue_nr = 0; - draw_vertex_cache_unreference( draw ); -} - - - -void draw_do_flush( struct draw_context *draw, unsigned flags ) -{ - if (0) - debug_printf("Flushing with %d verts, %d prims\n", - draw->vs.queue_nr, - draw->pq.queue_nr ); - - - if (flags >= DRAW_FLUSH_SHADER_QUEUE) { - if (draw->vs.queue_nr) - (*draw->shader_queue_flush)(draw); - - if (flags >= DRAW_FLUSH_PRIM_QUEUE) { - if (draw->pq.queue_nr) - draw_prim_queue_flush(draw); - - if (flags >= DRAW_FLUSH_VERTEX_CACHE) { - draw_vertex_cache_invalidate(draw); - - if (flags >= DRAW_FLUSH_STATE_CHANGE) { - draw->pipeline.first->flush( draw->pipeline.first, flags ); - draw->pipeline.first = draw->pipeline.validate; - draw->reduced_prim = ~0; - } - } - } - } -} - - - -/* Return a pointer to a freshly queued primitive header. Ensure that - * there is room in the vertex cache for a maximum of "nr_verts" new - * vertices. Flush primitive and/or vertex queues if necessary to - * make space. - */ -static struct prim_header *get_queued_prim( struct draw_context *draw, - unsigned nr_verts ) -{ - if (!draw_vertex_cache_check_space( draw, nr_verts )) { -// debug_printf("v"); - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE ); - } - else if (draw->pq.queue_nr == PRIM_QUEUE_LENGTH) { -// debug_printf("p"); - draw_do_flush( draw, DRAW_FLUSH_PRIM_QUEUE ); - } - - assert(draw->pq.queue_nr < PRIM_QUEUE_LENGTH); - - return &draw->pq.queue[draw->pq.queue_nr++]; -} - - - -/** - * Add a point to the primitive queue. - * \param i0 index into user's vertex arrays - */ -static void do_point( struct draw_context *draw, - unsigned i0 ) -{ - struct prim_header *prim = get_queued_prim( draw, 1 ); - - prim->reset_line_stipple = 0; - prim->edgeflags = 1; - prim->pad = 0; - prim->v[0] = draw->vcache.get_vertex( draw, i0 ); -} - - -/** - * Add a line to the primitive queue. - * \param i0 index into user's vertex arrays - * \param i1 index into user's vertex arrays - */ -static void do_line( struct draw_context *draw, - boolean reset_stipple, - unsigned i0, - unsigned i1 ) -{ - struct prim_header *prim = get_queued_prim( draw, 2 ); - - prim->reset_line_stipple = reset_stipple; - prim->edgeflags = 1; - prim->pad = 0; - prim->v[0] = draw->vcache.get_vertex( draw, i0 ); - prim->v[1] = draw->vcache.get_vertex( draw, i1 ); -} - -/** - * Add a triangle to the primitive queue. - */ -static void do_triangle( struct draw_context *draw, - unsigned i0, - unsigned i1, - unsigned i2 ) -{ - struct prim_header *prim = get_queued_prim( draw, 3 ); - - prim->reset_line_stipple = 1; - prim->edgeflags = ~0; - prim->pad = 0; - prim->v[0] = draw->vcache.get_vertex( draw, i0 ); - prim->v[1] = draw->vcache.get_vertex( draw, i1 ); - prim->v[2] = draw->vcache.get_vertex( draw, i2 ); -} - -static void do_ef_triangle( struct draw_context *draw, - boolean reset_stipple, - unsigned ef_mask, - unsigned i0, - unsigned i1, - unsigned i2 ) -{ - struct prim_header *prim = get_queued_prim( draw, 3 ); - struct vertex_header *v0 = draw->vcache.get_vertex( draw, i0 ); - struct vertex_header *v1 = draw->vcache.get_vertex( draw, i1 ); - struct vertex_header *v2 = draw->vcache.get_vertex( draw, i2 ); - - prim->reset_line_stipple = reset_stipple; - - prim->edgeflags = ef_mask & ((v0->edgeflag << 0) | - (v1->edgeflag << 1) | - (v2->edgeflag << 2)); - prim->pad = 0; - prim->v[0] = v0; - prim->v[1] = v1; - prim->v[2] = v2; -} - - -static void do_ef_quad( struct draw_context *draw, - unsigned v0, - unsigned v1, - unsigned v2, - unsigned v3 ) -{ - const unsigned omitEdge2 = ~(1 << 1); - const unsigned omitEdge3 = ~(1 << 2); - do_ef_triangle( draw, 1, omitEdge2, v0, v1, v3 ); - do_ef_triangle( draw, 0, omitEdge3, v1, v2, v3 ); -} - -static void do_quad( struct draw_context *draw, - unsigned v0, - unsigned v1, - unsigned v2, - unsigned v3 ) -{ - do_triangle( draw, v0, v1, v3 ); - do_triangle( draw, v1, v2, v3 ); -} - - -/** - * Main entrypoint to draw some number of points/lines/triangles - */ -static void -draw_prim( struct draw_context *draw, - unsigned prim, unsigned start, unsigned count ) -{ - unsigned i; - boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL); - -// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count ); - - switch (prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i ++) { - do_point( draw, - start + i ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - do_line( draw, - TRUE, - start + i + 0, - start + i + 1); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - for (i = 1; i < count; i++) { - do_line( draw, - i == 1, /* XXX: only if vb not split */ - start + i - 1, - start + i ); - } - - do_line( draw, - 0, - start + count - 1, - start + 0 ); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < count; i++) { - do_line( draw, - i == 1, - start + i - 1, - start + i ); - } - break; - - case PIPE_PRIM_TRIANGLES: - if (unfilled) { - for (i = 0; i+2 < count; i += 3) { - do_ef_triangle( draw, - 1, - ~0, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - else { - for (i = 0; i+2 < count; i += 3) { - do_triangle( draw, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 0; i+2 < count; i++) { - if (i & 1) { - do_triangle( draw, - start + i + 1, - start + i + 0, - start + i + 2 ); - } - else { - do_triangle( draw, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - for (i = 0; i+2 < count; i++) { - do_triangle( draw, - start + 0, - start + i + 1, - start + i + 2 ); - } - } - break; - - - case PIPE_PRIM_QUADS: - if (unfilled) { - for (i = 0; i+3 < count; i += 4) { - do_ef_quad( draw, - start + i + 0, - start + i + 1, - start + i + 2, - start + i + 3); - } - } - else { - for (i = 0; i+3 < count; i += 4) { - do_quad( draw, - start + i + 0, - start + i + 1, - start + i + 2, - start + i + 3); - } - } - break; - - case PIPE_PRIM_QUAD_STRIP: - if (unfilled) { - for (i = 0; i+3 < count; i += 2) { - do_ef_quad( draw, - start + i + 2, - start + i + 0, - start + i + 1, - start + i + 3); - } - } - else { - for (i = 0; i+3 < count; i += 2) { - do_quad( draw, - start + i + 2, - start + i + 0, - start + i + 1, - start + i + 3); - } - } - break; - - case PIPE_PRIM_POLYGON: - if (unfilled) { - unsigned ef_mask = (1<<2) | (1<<0); - - for (i = 0; i+2 < count; i++) { - - if (i + 3 >= count) - ef_mask |= (1<<1); - - do_ef_triangle( draw, - i == 0, - ef_mask, - start + i + 1, - start + i + 2, - start + 0); - - ef_mask &= ~(1<<2); - } - } - else { - for (i = 0; i+2 < count; i++) { - do_triangle( draw, - start + i + 1, - start + i + 2, - start + 0); - } - } - break; - - default: - assert(0); - break; - } -} - - - - -/** - * Draw vertex arrays - * This is the main entrypoint into the drawing module. - * \param prim one of PIPE_PRIM_x - * \param start index of first vertex to draw - * \param count number of vertices to draw - */ -void -draw_arrays(struct draw_context *draw, unsigned prim, - unsigned start, unsigned count) -{ - if (reduced_prim[prim] != draw->reduced_prim) { - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->reduced_prim = reduced_prim[prim]; - } - - /* drawing done here: */ - draw_prim(draw, prim, start, count); -} - - diff --git a/src/gallium/aux/draw/draw_private.h b/src/gallium/aux/draw/draw_private.h deleted file mode 100644 index 3d09aef87c..0000000000 --- a/src/gallium/aux/draw/draw_private.h +++ /dev/null @@ -1,346 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * Private data structures, etc for the draw module. - */ - - -/** - * Authors: - * Keith Whitwell - * Brian Paul - */ - - -#ifndef DRAW_PRIVATE_H -#define DRAW_PRIVATE_H - - -#include "pipe/p_state.h" -#include "pipe/p_defines.h" - -#include "x86/rtasm/x86sse.h" -#include "tgsi/exec/tgsi_exec.h" - - -struct gallivm_prog; -struct gallivm_cpu_engine; - -/** - * Basic vertex info. - * Carry some useful information around with the vertices in the prim pipe. - */ -struct vertex_header { - unsigned clipmask:12; - unsigned edgeflag:1; - unsigned pad:3; - unsigned vertex_id:16; - - float clip[4]; - - float data[][4]; /* Note variable size */ -}; - -/* NOTE: It should match vertex_id size above */ -#define UNDEFINED_VERTEX_ID 0xffff - -/* XXX This is too large */ -#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) - - - -/** - * Basic info for a point/line/triangle primitive. - */ -struct prim_header { - float det; /**< front/back face determinant */ - unsigned reset_line_stipple:1; - unsigned edgeflags:3; - unsigned pad:28; - struct vertex_header *v[3]; /**< 1 to 3 vertex pointers */ -}; - - - -struct draw_context; - -/** - * Base class for all primitive drawing stages. - */ -struct draw_stage -{ - struct draw_context *draw; /**< parent context */ - - struct draw_stage *next; /**< next stage in pipeline */ - - struct vertex_header **tmp; /**< temp vert storage, such as for clipping */ - unsigned nr_tmps; - - void (*point)( struct draw_stage *, - struct prim_header * ); - - void (*line)( struct draw_stage *, - struct prim_header * ); - - void (*tri)( struct draw_stage *, - struct prim_header * ); - - void (*flush)( struct draw_stage *, - unsigned flags ); - - void (*reset_stipple_counter)( struct draw_stage * ); - - void (*destroy)( struct draw_stage * ); -}; - - -#define PRIM_QUEUE_LENGTH 16 -#define VCACHE_SIZE 32 -#define VCACHE_OVERFLOW 4 -#define VS_QUEUE_LENGTH (VCACHE_SIZE + VCACHE_OVERFLOW + 1) /* can never fill up */ - -/** - * Private version of the compiled vertex_shader - */ -struct draw_vertex_shader { - const struct pipe_shader_state *state; -#if defined(__i386__) || defined(__386__) - struct x86_function sse2_program; -#endif -#ifdef MESA_LLVM - struct gallivm_prog *llvm_prog; -#endif -}; - - -/* Internal function for vertex fetch. - */ -typedef void (*fetch_func)(const void *ptr, float *attrib); -typedef void (*full_fetch_func)( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ); - - - -/** - * Private context for the drawing module. - */ -struct draw_context -{ - /** Drawing/primitive pipeline stages */ - struct { - struct draw_stage *first; /**< one of the following */ - - struct draw_stage *validate; - - /* stages (in logical order) */ - struct draw_stage *flatshade; - struct draw_stage *clip; - struct draw_stage *cull; - struct draw_stage *twoside; - struct draw_stage *offset; - struct draw_stage *unfilled; - struct draw_stage *stipple; - struct draw_stage *wide; - struct draw_stage *rasterize; - } pipeline; - - /* pipe state that we need: */ - const struct pipe_rasterizer_state *rasterizer; - struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; - struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; - const struct draw_vertex_shader *vertex_shader; - - uint num_vs_outputs; /**< convenience, from vertex_shader */ - - /* user-space vertex data, buffers */ - struct { - /** vertex element/index buffer (ex: glDrawElements) */ - const void *elts; - /** bytes per index (0, 1, 2 or 4) */ - unsigned eltSize; - - /** vertex arrays */ - const void *vbuffer[PIPE_ATTRIB_MAX]; - - /** constant buffer (for vertex shader) */ - const void *constants; - } user; - - /* Clip derived state: - */ - float plane[12][4]; - unsigned nr_planes; - - boolean convert_wide_points; /**< convert wide points to tris? */ - boolean convert_wide_lines; /**< convert side lines to tris? */ - - unsigned reduced_prim; - - /** TGSI program interpreter runtime state */ - struct tgsi_exec_machine machine; - - /* Vertex fetch internal state - */ - struct { - const ubyte *src_ptr[PIPE_ATTRIB_MAX]; - unsigned pitch[PIPE_ATTRIB_MAX]; - fetch_func fetch[PIPE_ATTRIB_MAX]; - unsigned nr_attrs; - full_fetch_func fetch_func; - } vertex_fetch; - - /* Post-tnl vertex cache: - */ - struct { - unsigned referenced; /**< bitfield */ - unsigned idx[VCACHE_SIZE + VCACHE_OVERFLOW]; - struct vertex_header *vertex[VCACHE_SIZE + VCACHE_OVERFLOW]; - unsigned overflow; - - /** To find space in the vertex cache: */ - struct vertex_header *(*get_vertex)( struct draw_context *draw, - unsigned i ); - } vcache; - - /* Vertex shader queue: - */ - struct { - struct { - unsigned elt; /**< index into the user's vertex arrays */ - struct vertex_header *dest; /**< points into vcache.vertex[] array */ - } queue[VS_QUEUE_LENGTH]; - unsigned queue_nr; - } vs; - - /** - * Run the vertex shader on all vertices in the vertex queue. - */ - void (*shader_queue_flush)(struct draw_context *draw); - - /* Prim pipeline queue: - */ - struct { - /* Need to queue up primitives until their vertices have been - * transformed by a vs queue flush. - */ - struct prim_header queue[PRIM_QUEUE_LENGTH]; - unsigned queue_nr; - } pq; - - int use_sse : 1; -#ifdef MESA_LLVM - struct gallivm_cpu_engine *engine; -#endif - - void *driver_private; -}; - - - -extern struct draw_stage *draw_unfilled_stage( struct draw_context *context ); -extern struct draw_stage *draw_twoside_stage( struct draw_context *context ); -extern struct draw_stage *draw_offset_stage( struct draw_context *context ); -extern struct draw_stage *draw_clip_stage( struct draw_context *context ); -extern struct draw_stage *draw_flatshade_stage( struct draw_context *context ); -extern struct draw_stage *draw_cull_stage( struct draw_context *context ); -extern struct draw_stage *draw_stipple_stage( struct draw_context *context ); -extern struct draw_stage *draw_wide_stage( struct draw_context *context ); -extern struct draw_stage *draw_validate_stage( struct draw_context *context ); - - -extern void draw_free_temp_verts( struct draw_stage *stage ); - -extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); - -extern void draw_reset_vertex_ids( struct draw_context *draw ); - - -extern int draw_vertex_cache_check_space( struct draw_context *draw, - unsigned nr_verts ); - -extern void draw_vertex_cache_invalidate( struct draw_context *draw ); -extern void draw_vertex_cache_unreference( struct draw_context *draw ); -extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ); - - -extern void draw_vertex_shader_queue_flush( struct draw_context *draw ); -#ifdef MESA_LLVM -extern void draw_vertex_shader_queue_flush_llvm( struct draw_context *draw ); -#endif - -struct tgsi_exec_machine; - -extern void draw_update_vertex_fetch( struct draw_context *draw ); - - -#define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ -#define DRAW_FLUSH_PRIM_QUEUE 0x2 -#define DRAW_FLUSH_VERTEX_CACHE 0x4 -#define DRAW_FLUSH_STATE_CHANGE 0x8 -#define DRAW_FLUSH_BACKEND 0x10 - - -void draw_do_flush( struct draw_context *draw, unsigned flags ); - - - -/** - * Get a writeable copy of a vertex. - * \param stage drawing stage info - * \param vert the vertex to copy (source) - * \param idx index into stage's tmp[] array to put the copy (dest) - * \return pointer to the copied vertex - */ -static INLINE struct vertex_header * -dup_vert( struct draw_stage *stage, - const struct vertex_header *vert, - unsigned idx ) -{ - struct vertex_header *tmp = stage->tmp[idx]; - const uint vsize = sizeof(struct vertex_header) - + stage->draw->num_vs_outputs * 4 * sizeof(float); - memcpy(tmp, vert, vsize); - tmp->vertex_id = UNDEFINED_VERTEX_ID; - return tmp; -} - -static INLINE float -dot4(const float *a, const float *b) -{ - float result = (a[0]*b[0] + - a[1]*b[1] + - a[2]*b[2] + - a[3]*b[3]); - - return result; -} - -#endif /* DRAW_PRIVATE_H */ diff --git a/src/gallium/aux/draw/draw_stipple.c b/src/gallium/aux/draw/draw_stipple.c deleted file mode 100644 index 506f33512c..0000000000 --- a/src/gallium/aux/draw/draw_stipple.c +++ /dev/null @@ -1,239 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -/* Implement line stipple by cutting lines up into smaller lines. - * There are hundreds of ways to implement line stipple, this is one - * choice that should work in all situations, requires no state - * manipulations, but with a penalty in terms of large amounts of - * generated geometry. - */ - - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -/** Subclass of draw_stage */ -struct stipple_stage { - struct draw_stage stage; - float counter; - uint pattern; - uint factor; -}; - - -static INLINE struct stipple_stage * -stipple_stage(struct draw_stage *stage) -{ - return (struct stipple_stage *) stage; -} - - -/** - * Compute interpolated vertex attributes for 'dst' at position 't' - * between 'v0' and 'v1'. - * XXX using linear interpolation for all attribs at this time. - */ -static void -screen_interp( struct draw_context *draw, - struct vertex_header *dst, - float t, - const struct vertex_header *v0, - const struct vertex_header *v1 ) -{ - uint attr; - for (attr = 0; attr < draw->num_vs_outputs; attr++) { - const float *val0 = v0->data[attr]; - const float *val1 = v1->data[attr]; - float *newv = dst->data[attr]; - uint i; - for (i = 0; i < 4; i++) { - newv[i] = val0[i] + t * (val1[i] - val0[i]); - } - } -} - - -static void -emit_segment(struct draw_stage *stage, struct prim_header *header, - float t0, float t1) -{ - struct vertex_header *v0new = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1new = dup_vert(stage, header->v[1], 1); - struct prim_header newprim = *header; - - if (t0 > 0.0) { - screen_interp( stage->draw, v0new, t0, header->v[0], header->v[1] ); - newprim.v[0] = v0new; - } - - if (t1 < 1.0) { - screen_interp( stage->draw, v1new, t1, header->v[0], header->v[1] ); - newprim.v[1] = v1new; - } - - stage->next->line( stage->next, &newprim ); -} - - -static INLINE unsigned -stipple_test(int counter, ushort pattern, int factor) -{ - int b = (counter / factor) & 0xf; - return (1 << b) & pattern; -} - - -static void -stipple_line(struct draw_stage *stage, struct prim_header *header) -{ - struct stipple_stage *stipple = stipple_stage(stage); - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - const float *pos0 = v0->data[0]; - const float *pos1 = v1->data[0]; - float start = 0; - int state = 0; - - float x0 = pos0[0]; - float x1 = pos1[0]; - float y0 = pos0[1]; - float y1 = pos1[1]; - - float dx = x0 > x1 ? x0 - x1 : x1 - x0; - float dy = y0 > y1 ? y0 - y1 : y1 - y0; - - float length = MAX2(dx, dy); - int i; - - /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table. - */ - for (i = 0; i < length; i++) { - int result = stipple_test( (int) stipple->counter+i, - (ushort) stipple->pattern, stipple->factor ); - if (result != state) { - /* changing from "off" to "on" or vice versa */ - if (state) { - if (start != i) { - /* finishing an "on" segment */ - emit_segment( stage, header, start / length, i / length ); - } - } - else { - /* starting an "on" segment */ - start = (float) i; - } - state = result; - } - } - - if (state && start < length) - emit_segment( stage, header, start / length, 1.0 ); - - stipple->counter += length; -} - - -static void -reset_stipple_counter(struct draw_stage *stage) -{ - struct stipple_stage *stipple = stipple_stage(stage); - stipple->counter = 0; - stage->next->reset_stipple_counter( stage->next ); -} - - -static void -stipple_first_line(struct draw_stage *stage, - struct prim_header *header) -{ - struct stipple_stage *stipple = stipple_stage(stage); - struct draw_context *draw = stage->draw; - - stipple->pattern = draw->rasterizer->line_stipple_pattern; - stipple->factor = draw->rasterizer->line_stipple_factor + 1; - - stage->line = stipple_line; - stage->line( stage, header ); -} - - -static void -stipple_flush(struct draw_stage *stage, unsigned flags) -{ - stage->line = stipple_first_line; - stage->next->flush( stage->next, flags ); -} - - -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point( stage->next, header ); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} - - -static void -stipple_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create line stippler stage - */ -struct draw_stage *draw_stipple_stage( struct draw_context *draw ) -{ - struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage); - - draw_alloc_temp_verts( &stipple->stage, 2 ); - - stipple->stage.draw = draw; - stipple->stage.next = NULL; - stipple->stage.point = passthrough_point; - stipple->stage.line = stipple_first_line; - stipple->stage.tri = passthrough_tri; - stipple->stage.reset_stipple_counter = reset_stipple_counter; - stipple->stage.flush = stipple_flush; - stipple->stage.destroy = stipple_destroy; - - return &stipple->stage; -} diff --git a/src/gallium/aux/draw/draw_twoside.c b/src/gallium/aux/draw/draw_twoside.c deleted file mode 100644 index 1c38957987..0000000000 --- a/src/gallium/aux/draw/draw_twoside.c +++ /dev/null @@ -1,203 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -struct twoside_stage { - struct draw_stage stage; - float sign; /**< +1 or -1 */ - uint attrib_front0, attrib_back0; - uint attrib_front1, attrib_back1; -}; - - -static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage ) -{ - return (struct twoside_stage *)stage; -} - - - - -/** - * Copy back color(s) to front color(s). - */ -static INLINE struct vertex_header * -copy_bfc( struct twoside_stage *twoside, - const struct vertex_header *v, - unsigned idx ) -{ - struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx ); - - if (twoside->attrib_back0) { - COPY_4FV(tmp->data[twoside->attrib_front0], - tmp->data[twoside->attrib_back0]); - } - if (twoside->attrib_back1) { - COPY_4FV(tmp->data[twoside->attrib_front1], - tmp->data[twoside->attrib_back1]); - } - - return tmp; -} - - -/* Twoside tri: - */ -static void twoside_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct twoside_stage *twoside = twoside_stage(stage); - - if (header->det * twoside->sign < 0.0) { - /* this is a back-facing triangle */ - struct prim_header tmp; - - tmp.det = header->det; - tmp.edgeflags = header->edgeflags; - /* copy back attribs to front attribs */ - tmp.v[0] = copy_bfc(twoside, header->v[0], 0); - tmp.v[1] = copy_bfc(twoside, header->v[1], 1); - tmp.v[2] = copy_bfc(twoside, header->v[2], 2); - - stage->next->tri( stage->next, &tmp ); - } - else { - stage->next->tri( stage->next, header ); - } -} - - -static void twoside_line( struct draw_stage *stage, - struct prim_header *header ) -{ - /* pass-through */ - stage->next->line( stage->next, header ); -} - - -static void twoside_point( struct draw_stage *stage, - struct prim_header *header ) -{ - /* pass-through */ - stage->next->point( stage->next, header ); -} - - -static void twoside_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct twoside_stage *twoside = twoside_stage(stage); - const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; - uint i; - - twoside->attrib_front0 = 0; - twoside->attrib_front1 = 0; - twoside->attrib_back0 = 0; - twoside->attrib_back1 = 0; - - /* Find which vertex shader outputs are front/back colors */ - for (i = 0; i < vs->num_outputs; i++) { - if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR) { - if (vs->output_semantic_index[i] == 0) - twoside->attrib_front0 = i; - else - twoside->attrib_front1 = i; - } - if (vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { - if (vs->output_semantic_index[i] == 0) - twoside->attrib_back0 = i; - else - twoside->attrib_back1 = i; - } - } - - if (!twoside->attrib_back0) - twoside->attrib_front0 = 0; - - if (!twoside->attrib_back1) - twoside->attrib_front1 = 0; - - /* - * We'll multiply the primitive's determinant by this sign to determine - * if the triangle is back-facing (negative). - * sign = -1 for CCW, +1 for CW - */ - twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f; - - stage->tri = twoside_tri; - stage->tri( stage, header ); -} - - -static void twoside_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->tri = twoside_first_tri; - stage->next->flush( stage->next, flags ); -} - - -static void twoside_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void twoside_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create twoside pipeline stage. - */ -struct draw_stage *draw_twoside_stage( struct draw_context *draw ) -{ - struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage); - - draw_alloc_temp_verts( &twoside->stage, 3 ); - - twoside->stage.draw = draw; - twoside->stage.next = NULL; - twoside->stage.point = twoside_point; - twoside->stage.line = twoside_line; - twoside->stage.tri = twoside_first_tri; - twoside->stage.flush = twoside_flush; - twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter; - twoside->stage.destroy = twoside_destroy; - - return &twoside->stage; -} diff --git a/src/gallium/aux/draw/draw_unfilled.c b/src/gallium/aux/draw/draw_unfilled.c deleted file mode 100644 index 8777cfdfc8..0000000000 --- a/src/gallium/aux/draw/draw_unfilled.c +++ /dev/null @@ -1,206 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief Drawing stage for handling glPolygonMode(line/point). - * Convert triangles to points or lines as needed. - */ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "draw_private.h" - - -struct unfilled_stage { - struct draw_stage stage; - - /** [0] = front face, [1] = back face. - * legal values: PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE, - * and PIPE_POLYGON_MODE_POINT, - */ - unsigned mode[2]; -}; - - -static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage ) -{ - return (struct unfilled_stage *)stage; -} - - - -static void point( struct draw_stage *stage, - struct vertex_header *v0 ) -{ - struct prim_header tmp; - tmp.v[0] = v0; - stage->next->point( stage->next, &tmp ); -} - -static void line( struct draw_stage *stage, - struct vertex_header *v0, - struct vertex_header *v1 ) -{ - struct prim_header tmp; - tmp.v[0] = v0; - tmp.v[1] = v1; - stage->next->line( stage->next, &tmp ); -} - - -static void points( struct draw_stage *stage, - struct prim_header *header ) -{ - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - struct vertex_header *v2 = header->v[2]; - - if (header->edgeflags & 0x1) point( stage, v0 ); - if (header->edgeflags & 0x2) point( stage, v1 ); - if (header->edgeflags & 0x4) point( stage, v2 ); -} - - -static void lines( struct draw_stage *stage, - struct prim_header *header ) -{ - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - struct vertex_header *v2 = header->v[2]; - -#if 0 - assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag); - assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag); - assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag); -#endif - - if (header->edgeflags & 0x1) line( stage, v0, v1 ); - if (header->edgeflags & 0x2) line( stage, v1, v2 ); - if (header->edgeflags & 0x4) line( stage, v2, v0 ); -} - - -/* Unfilled tri: - * - * Note edgeflags in the vertex struct is not sufficient as we will - * need to manipulate them when decomposing primitives??? - */ -static void unfilled_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct unfilled_stage *unfilled = unfilled_stage(stage); - unsigned mode = unfilled->mode[header->det >= 0.0]; - - switch (mode) { - case PIPE_POLYGON_MODE_FILL: - stage->next->tri( stage->next, header ); - break; - case PIPE_POLYGON_MODE_LINE: - lines( stage, header ); - break; - case PIPE_POLYGON_MODE_POINT: - points( stage, header ); - break; - default: - abort(); - } -} - - -static void unfilled_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct unfilled_stage *unfilled = unfilled_stage(stage); - - unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */ - unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */ - - stage->tri = unfilled_tri; - stage->tri( stage, header ); -} - - -static void unfilled_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void unfilled_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void unfilled_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->next->flush( stage->next, flags ); - - stage->tri = unfilled_first_tri; -} - - -static void unfilled_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void unfilled_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create unfilled triangle stage. - */ -struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) -{ - struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage); - - draw_alloc_temp_verts( &unfilled->stage, 0 ); - - unfilled->stage.draw = draw; - unfilled->stage.next = NULL; - unfilled->stage.tmp = NULL; - unfilled->stage.point = unfilled_point; - unfilled->stage.line = unfilled_line; - unfilled->stage.tri = unfilled_first_tri; - unfilled->stage.flush = unfilled_flush; - unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter; - unfilled->stage.destroy = unfilled_destroy; - - return &unfilled->stage; -} diff --git a/src/gallium/aux/draw/draw_validate.c b/src/gallium/aux/draw/draw_validate.c deleted file mode 100644 index 4375ebabbc..0000000000 --- a/src/gallium/aux/draw/draw_validate.c +++ /dev/null @@ -1,185 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "draw_private.h" - - - - - -/** - * Rebuild the rendering pipeline. - */ -static struct draw_stage *validate_pipeline( struct draw_stage *stage ) -{ - struct draw_context *draw = stage->draw; - struct draw_stage *next = draw->pipeline.rasterize; - int need_det = 0; - int precalc_flat = 0; - - /* Set the validate's next stage to the rasterize stage, so that it - * can be found later if needed for flushing. - */ - stage->next = next; - - /* - * NOTE: we build up the pipeline in end-to-start order. - * - * TODO: make the current primitive part of the state and build - * shorter pipelines for lines & points. - */ - - if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines) || - (draw->rasterizer->point_size != 1.0 && draw->convert_wide_points) || - draw->rasterizer->point_sprite) { - draw->pipeline.wide->next = next; - next = draw->pipeline.wide; - } - - if (draw->rasterizer->line_stipple_enable) { - draw->pipeline.stipple->next = next; - next = draw->pipeline.stipple; - precalc_flat = 1; /* only needed for lines really */ - } - - if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { - draw->pipeline.unfilled->next = next; - next = draw->pipeline.unfilled; - precalc_flat = 1; /* only needed for triangles really */ - need_det = 1; - } - - if (draw->rasterizer->flatshade && precalc_flat) { - draw->pipeline.flatshade->next = next; - next = draw->pipeline.flatshade; - } - - if (draw->rasterizer->offset_cw || - draw->rasterizer->offset_ccw) { - draw->pipeline.offset->next = next; - next = draw->pipeline.offset; - need_det = 1; - } - - if (draw->rasterizer->light_twoside) { - draw->pipeline.twoside->next = next; - next = draw->pipeline.twoside; - need_det = 1; - } - - /* Always run the cull stage as we calculate determinant there - * also. - * - * This can actually be a win as culling out the triangles can lead - * to less work emitting vertices, smaller vertex buffers, etc. - * It's difficult to say whether this will be true in general. - */ - if (need_det || draw->rasterizer->cull_mode) { - draw->pipeline.cull->next = next; - next = draw->pipeline.cull; - } - - /* Clip stage - */ - if (!draw->rasterizer->bypass_clipping) - { - draw->pipeline.clip->next = next; - next = draw->pipeline.clip; - } - - - draw->pipeline.first = next; - return next; -} - -static void validate_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->tri( pipeline, header ); -} - -static void validate_line( struct draw_stage *stage, - struct prim_header *header ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->line( pipeline, header ); -} - -static void validate_point( struct draw_stage *stage, - struct prim_header *header ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->point( pipeline, header ); -} - -static void validate_reset_stipple_counter( struct draw_stage *stage ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->reset_stipple_counter( pipeline ); -} - -static void validate_flush( struct draw_stage *stage, - unsigned flags ) -{ - /* May need to pass a backend flush on to the rasterize stage. - */ - if (stage->next) - stage->next->flush( stage->next, flags ); -} - - -static void validate_destroy( struct draw_stage *stage ) -{ - FREE( stage ); -} - - -/** - * Create validate pipeline stage. - */ -struct draw_stage *draw_validate_stage( struct draw_context *draw ) -{ - struct draw_stage *stage = CALLOC_STRUCT(draw_stage); - - stage->draw = draw; - stage->next = NULL; - stage->point = validate_point; - stage->line = validate_line; - stage->tri = validate_tri; - stage->flush = validate_flush; - stage->reset_stipple_counter = validate_reset_stipple_counter; - stage->destroy = validate_destroy; - - return stage; -} diff --git a/src/gallium/aux/draw/draw_vbuf.c b/src/gallium/aux/draw/draw_vbuf.c deleted file mode 100644 index 71ac73912b..0000000000 --- a/src/gallium/aux/draw/draw_vbuf.c +++ /dev/null @@ -1,570 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file - * Vertex buffer drawing stage. - * - * \author José Fonseca - * \author Keith Whitwell - */ - - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" - -#include "draw_vbuf.h" -#include "draw_private.h" -#include "draw_vertex.h" -#include "draw_vf.h" - - -/** - * Vertex buffer emit stage. - */ -struct vbuf_stage { - struct draw_stage stage; /**< This must be first (base class) */ - - struct vbuf_render *render; - - const struct vertex_info *vinfo; - - /** Vertex size in bytes */ - unsigned vertex_size; - - struct draw_vertex_fetch *vf; - - /* FIXME: we have no guarantee that 'unsigned' is 32bit */ - - /** Vertices in hardware format */ - unsigned *vertices; - unsigned *vertex_ptr; - unsigned max_vertices; - unsigned nr_vertices; - - /** Indices */ - ushort *indices; - unsigned max_indices; - unsigned nr_indices; - - /** Pipe primitive */ - unsigned prim; -}; - - -/** - * Basically a cast wrapper. - */ -static INLINE struct vbuf_stage * -vbuf_stage( struct draw_stage *stage ) -{ - assert(stage); - return (struct vbuf_stage *)stage; -} - - -static void vbuf_flush_indices( struct vbuf_stage *vbuf ); -static void vbuf_flush_vertices( struct vbuf_stage *vbuf ); -static void vbuf_alloc_vertices( struct vbuf_stage *vbuf ); - - -static INLINE boolean -overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz ) -{ - unsigned long used = (unsigned long) ((char *)ptr - (char *)map); - return (used + bytes) > bufsz; -} - - -static INLINE void -check_space( struct vbuf_stage *vbuf, unsigned nr ) -{ - if (vbuf->nr_vertices + nr > vbuf->max_vertices ) { - vbuf_flush_vertices(vbuf); - vbuf_alloc_vertices(vbuf); - } - - if (vbuf->nr_indices + nr > vbuf->max_indices ) - vbuf_flush_indices(vbuf); -} - - -#if 0 -static INLINE void -dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) -{ - assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); - unsigned i, j, k; - - for (i = 0; i < vinfo->num_attribs; i++) { - j = vinfo->src_index[i]; - switch (vinfo->emit[i]) { - case EMIT_OMIT: - debug_printf("EMIT_OMIT:"); - break; - case EMIT_ALL: - assert(i == 0); - assert(j == 0); - debug_printf("EMIT_ALL:\t"); - for(k = 0; k < vinfo->size*4; ++k) - debug_printf("%02x ", *data++); - break; - case EMIT_1F: - debug_printf("EMIT_1F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_1F_PSIZE: - debug_printf("EMIT_1F_PSIZE:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_2F: - debug_printf("EMIT_2F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_3F: - debug_printf("EMIT_3F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - data += sizeof(float); - break; - case EMIT_4F: - debug_printf("EMIT_4F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_4UB: - debug_printf("EMIT_4UB:\t"); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - break; - default: - assert(0); - } - debug_printf("\n"); - } - debug_printf("\n"); -} -#endif - - -/** - * Extract the needed fields from post-transformed vertex and emit - * a hardware(driver) vertex. - * Recall that the vertices are constructed by the 'draw' module and - * have a couple of slots at the beginning (1-dword header, 4-dword - * clip pos) that we ignore here. We only use the vertex->data[] fields. - */ -static INLINE void -emit_vertex( struct vbuf_stage *vbuf, - struct vertex_header *vertex ) -{ -#if 0 - debug_printf("emit vertex %d to %p\n", - vbuf->nr_vertices, vbuf->vertex_ptr); -#endif - - if(vertex->vertex_id != UNDEFINED_VERTEX_ID) { - if(vertex->vertex_id < vbuf->nr_vertices) - return; - else - debug_printf("Bad vertex id 0x%04x (>= 0x%04x)\n", - vertex->vertex_id, vbuf->nr_vertices); - return; - } - - vertex->vertex_id = vbuf->nr_vertices++; - - if(!vbuf->vf) { - const struct vertex_info *vinfo = vbuf->vinfo; - uint i; - uint count = 0; /* for debug/sanity */ - - assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); - - for (i = 0; i < vinfo->num_attribs; i++) { - uint j = vinfo->src_index[i]; - switch (vinfo->emit[i]) { - case EMIT_OMIT: - /* no-op */ - break; - case EMIT_ALL: - /* just copy the whole vertex as-is to the vbuf */ - assert(i == 0); - assert(j == 0); - memcpy(vbuf->vertex_ptr, vertex, vinfo->size * 4); - vbuf->vertex_ptr += vinfo->size; - count += vinfo->size; - break; - case EMIT_1F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - count++; - break; - case EMIT_1F_PSIZE: - *vbuf->vertex_ptr++ = fui(vbuf->stage.draw->rasterizer->point_size); - count++; - break; - case EMIT_2F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); - count += 2; - break; - case EMIT_3F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); - count += 3; - break; - case EMIT_4F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][3]); - count += 4; - break; - case EMIT_4UB: - *vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[j][2] ), - float_to_ubyte( vertex->data[j][1] ), - float_to_ubyte( vertex->data[j][0] ), - float_to_ubyte( vertex->data[j][3] )); - count += 1; - break; - default: - assert(0); - } - } - assert(count == vinfo->size); -#if 0 - { - static float data[256]; - draw_vf_emit_vertex(vbuf->vf, vertex, data); - if(memcmp((uint8_t *)vbuf->vertex_ptr - vbuf->vertex_size, data, vbuf->vertex_size)) { - debug_printf("With VF:\n"); - dump_emitted_vertex(vbuf->vinfo, (uint8_t *)data); - debug_printf("Without VF:\n"); - dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr - vbuf->vertex_size); - assert(0); - } - } -#endif - } - else { - draw_vf_emit_vertex(vbuf->vf, vertex, vbuf->vertex_ptr); - - vbuf->vertex_ptr += vbuf->vertex_size/4; - } -} - - -static void -vbuf_tri( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - unsigned i; - - check_space( vbuf, 3 ); - - for (i = 0; i < 3; i++) { - emit_vertex( vbuf, prim->v[i] ); - - vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[i]->vertex_id; - } -} - - -static void -vbuf_line( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - unsigned i; - - check_space( vbuf, 2 ); - - for (i = 0; i < 2; i++) { - emit_vertex( vbuf, prim->v[i] ); - - vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[i]->vertex_id; - } -} - - -static void -vbuf_point( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - check_space( vbuf, 1 ); - - emit_vertex( vbuf, prim->v[0] ); - - vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[0]->vertex_id; -} - - -/** - * Set the prim type for subsequent vertices. - * This may result in a new vertex size. The existing vbuffer (if any) - * will be flushed if needed and a new one allocated. - */ -static void -vbuf_set_prim( struct vbuf_stage *vbuf, uint newprim ) -{ - const struct vertex_info *vinfo; - unsigned vertex_size; - - assert(newprim == PIPE_PRIM_POINTS || - newprim == PIPE_PRIM_LINES || - newprim == PIPE_PRIM_TRIANGLES); - - vbuf->prim = newprim; - vbuf->render->set_primitive(vbuf->render, newprim); - - vinfo = vbuf->render->get_vertex_info(vbuf->render); - vertex_size = vinfo->size * sizeof(float); - - if (vertex_size != vbuf->vertex_size) - vbuf_flush_vertices(vbuf); - - vbuf->vinfo = vinfo; - vbuf->vertex_size = vertex_size; - if(vbuf->vf) - draw_vf_set_vertex_info(vbuf->vf, - vbuf->vinfo, - vbuf->stage.draw->rasterizer->point_size); - - if (!vbuf->vertices) - vbuf_alloc_vertices(vbuf); -} - - -static void -vbuf_first_tri( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - stage->tri = vbuf_tri; - vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES); - stage->tri( stage, prim ); -} - - -static void -vbuf_first_line( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - stage->line = vbuf_line; - vbuf_set_prim(vbuf, PIPE_PRIM_LINES); - stage->line( stage, prim ); -} - - -static void -vbuf_first_point( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - stage->point = vbuf_point; - vbuf_set_prim(vbuf, PIPE_PRIM_POINTS); - stage->point( stage, prim ); -} - - -static void -vbuf_flush_indices( struct vbuf_stage *vbuf ) -{ - if(!vbuf->nr_indices) - return; - - assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == - vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned)); - - switch(vbuf->prim) { - case PIPE_PRIM_POINTS: - break; - case PIPE_PRIM_LINES: - assert(vbuf->nr_indices % 2 == 0); - break; - case PIPE_PRIM_TRIANGLES: - assert(vbuf->nr_indices % 3 == 0); - break; - default: - assert(0); - } - - vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices); - - vbuf->nr_indices = 0; - - /* don't need to reset point/line/tri functions */ -#if 0 - stage->point = vbuf_first_point; - stage->line = vbuf_first_line; - stage->tri = vbuf_first_tri; -#endif -} - - -/** - * Flush existing vertex buffer and allocate a new one. - * - * XXX: We separate flush-on-index-full and flush-on-vb-full, but may - * raise issues uploading vertices if the hardware wants to flush when - * we flush. - */ -static void -vbuf_flush_vertices( struct vbuf_stage *vbuf ) -{ - if(vbuf->vertices) { - vbuf_flush_indices(vbuf); - - /* Reset temporary vertices ids */ - if(vbuf->nr_vertices) - draw_reset_vertex_ids( vbuf->stage.draw ); - - /* Free the vertex buffer */ - vbuf->render->release_vertices(vbuf->render, - vbuf->vertices, - vbuf->vertex_size, - vbuf->nr_vertices); - vbuf->max_vertices = vbuf->nr_vertices = 0; - vbuf->vertex_ptr = vbuf->vertices = NULL; - - } -} - - -static void -vbuf_alloc_vertices( struct vbuf_stage *vbuf ) -{ - assert(!vbuf->nr_indices); - assert(!vbuf->vertices); - - /* Allocate a new vertex buffer */ - vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; - vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, - (ushort) vbuf->vertex_size, - (ushort) vbuf->max_vertices); - vbuf->vertex_ptr = vbuf->vertices; -} - - - -static void -vbuf_flush( struct draw_stage *stage, unsigned flags ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - - stage->point = vbuf_first_point; - stage->line = vbuf_first_line; - stage->tri = vbuf_first_tri; - - if (flags & DRAW_FLUSH_BACKEND) - vbuf_flush_vertices( vbuf ); -} - - -static void -vbuf_reset_stipple_counter( struct draw_stage *stage ) -{ - /* XXX: Need to do something here for hardware with linestipple. - */ - (void) stage; -} - - -static void vbuf_destroy( struct draw_stage *stage ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - if(vbuf->indices) - align_free( vbuf->indices ); - - if(vbuf->vf) - draw_vf_destroy( vbuf->vf ); - - if (vbuf->render) - vbuf->render->destroy( vbuf->render ); - - FREE( stage ); -} - - -/** - * Create a new primitive vbuf/render stage. - */ -struct draw_stage *draw_vbuf_stage( struct draw_context *draw, - struct vbuf_render *render ) -{ - struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); - - if(!vbuf) - return NULL; - - vbuf->stage.draw = draw; - vbuf->stage.point = vbuf_first_point; - vbuf->stage.line = vbuf_first_line; - vbuf->stage.tri = vbuf_first_tri; - vbuf->stage.flush = vbuf_flush; - vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter; - vbuf->stage.destroy = vbuf_destroy; - - vbuf->render = render; - - assert(render->max_indices < UNDEFINED_VERTEX_ID); - vbuf->max_indices = render->max_indices; - vbuf->indices = (ushort *) - align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 ); - if(!vbuf->indices) - vbuf_destroy(&vbuf->stage); - - vbuf->vertices = NULL; - vbuf->vertex_ptr = vbuf->vertices; - - vbuf->prim = ~0; - - if(!GETENV("GALLIUM_NOVF")) - vbuf->vf = draw_vf_create(); - - return &vbuf->stage; -} diff --git a/src/gallium/aux/draw/draw_vbuf.h b/src/gallium/aux/draw/draw_vbuf.h deleted file mode 100644 index cfd2b9820c..0000000000 --- a/src/gallium/aux/draw/draw_vbuf.h +++ /dev/null @@ -1,106 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file - * Vertex buffer drawing stage. - * - * \author Keith Whitwell - * \author José Fonseca - */ - -#ifndef DRAW_VBUF_H_ -#define DRAW_VBUF_H_ - - -#include "pipe/p_util.h" - - -struct draw_context; -struct vertex_info; - - -/** - * Interface for hardware vertex buffer rendering. - */ -struct vbuf_render { - - /** - * Driver limits. May be tuned lower to improve cache hits on - * index list. - */ - unsigned max_indices; - unsigned max_vertex_buffer_bytes; - - /** - * Get the hardware vertex format. - * - * XXX: have this in draw_context instead? - */ - const struct vertex_info *(*get_vertex_info)( struct vbuf_render * ); - - /** - * Request a destination for vertices. - * Hardware renderers will use ttm memory, others will just malloc - * something. - */ - void *(*allocate_vertices)( struct vbuf_render *, - ushort vertex_size, - ushort nr_vertices ); - - /** - * Notify the renderer of the current primitive when it changes. - * Prim is restricted to TRIANGLES, LINES and POINTS. - */ - void (*set_primitive)( struct vbuf_render *, unsigned prim ); - - /** - * DrawElements, note indices are ushort: - */ - void (*draw)( struct vbuf_render *, - const ushort *indices, - uint nr_indices ); - - /** - * Called when vbuf is done with this set of vertices: - */ - void (*release_vertices)( struct vbuf_render *, - void *vertices, - unsigned vertex_size, - unsigned vertices_used ); - - void (*destroy)( struct vbuf_render * ); -}; - - - -struct draw_stage * -draw_vbuf_stage( struct draw_context *draw, - struct vbuf_render *render ); - - -#endif /*DRAW_VBUF_H_*/ diff --git a/src/gallium/aux/draw/draw_vertex.c b/src/gallium/aux/draw/draw_vertex.c deleted file mode 100644 index daf1ef4b80..0000000000 --- a/src/gallium/aux/draw/draw_vertex.c +++ /dev/null @@ -1,79 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* - * Functions for specifying the post-transformation vertex layout. - * - * Author: - * Brian Paul - * Keith Whitwell - */ - - -#include "draw/draw_private.h" -#include "draw/draw_vertex.h" - - -/** - * Compute the size of a vertex, in dwords/floats, to update the - * vinfo->size field. - */ -void -draw_compute_vertex_size(struct vertex_info *vinfo) -{ - uint i; - - vinfo->size = 0; - for (i = 0; i < vinfo->num_attribs; i++) { - switch (vinfo->emit[i]) { - case EMIT_OMIT: - break; - case EMIT_4UB: - /* fall-through */ - case EMIT_1F_PSIZE: - /* fall-through */ - case EMIT_1F: - vinfo->size += 1; - break; - case EMIT_2F: - vinfo->size += 2; - break; - case EMIT_3F: - vinfo->size += 3; - break; - case EMIT_4F: - vinfo->size += 4; - break; - case EMIT_ALL: - /* fall-through */ - default: - assert(0); - } - } - - assert(vinfo->size * 4 <= MAX_VERTEX_SIZE); -} diff --git a/src/gallium/aux/draw/draw_vertex.h b/src/gallium/aux/draw/draw_vertex.h deleted file mode 100644 index 267c74203b..0000000000 --- a/src/gallium/aux/draw/draw_vertex.h +++ /dev/null @@ -1,111 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * Post-transform vertex format info. The vertex_info struct is used by - * the draw_vbuf code to emit hardware-specific vertex layouts into hw - * vertex buffers. - * - * Author: - * Brian Paul - */ - - -#ifndef DRAW_VERTEX_H -#define DRAW_VERTEX_H - - -#include "pipe/p_state.h" - - -/** - * Vertex attribute emit modes - */ -enum attrib_emit { - EMIT_OMIT, /**< don't emit the attribute */ - EMIT_ALL, /**< emit whole post-xform vertex, w/ header */ - EMIT_1F, - EMIT_1F_PSIZE, /**< insert constant point size */ - EMIT_2F, - EMIT_3F, - EMIT_4F, - EMIT_4UB /**< XXX may need variations for RGBA vs BGRA, etc */ -}; - - -/** - * Attribute interpolation mode - */ -enum interp_mode { - INTERP_NONE, /**< never interpolate vertex header info */ - INTERP_POS, /**< special case for frag position */ - INTERP_CONSTANT, - INTERP_LINEAR, - INTERP_PERSPECTIVE -}; - - -/** - * Information about hardware/rasterization vertex layout. - */ -struct vertex_info -{ - uint num_attribs; - uint hwfmt[4]; /**< hardware format info for this format */ - enum interp_mode interp_mode[PIPE_MAX_SHADER_INPUTS]; - enum attrib_emit emit[PIPE_MAX_SHADER_INPUTS]; /**< EMIT_x */ - uint src_index[PIPE_MAX_SHADER_INPUTS]; /**< map to post-xform attribs */ - uint size; /**< total vertex size in dwords */ -}; - - - -/** - * Add another attribute to the given vertex_info object. - * \param src_index indicates which post-transformed vertex attrib slot - * corresponds to this attribute. - * \return slot in which the attribute was added - */ -static INLINE uint -draw_emit_vertex_attr(struct vertex_info *vinfo, - enum attrib_emit emit, enum interp_mode interp, - uint src_index) -{ - const uint n = vinfo->num_attribs; - assert(n < PIPE_MAX_SHADER_INPUTS); - vinfo->emit[n] = emit; - vinfo->interp_mode[n] = interp; - vinfo->src_index[n] = src_index; - vinfo->num_attribs++; - return n; -} - - -extern void draw_compute_vertex_size(struct vertex_info *vinfo); - - -#endif /* DRAW_VERTEX_H */ diff --git a/src/gallium/aux/draw/draw_vertex_cache.c b/src/gallium/aux/draw/draw_vertex_cache.c deleted file mode 100644 index 44427999cc..0000000000 --- a/src/gallium/aux/draw/draw_vertex_cache.c +++ /dev/null @@ -1,196 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "draw_private.h" -#include "draw_context.h" - - -void draw_vertex_cache_invalidate( struct draw_context *draw ) -{ - assert(draw->pq.queue_nr == 0); - assert(draw->vs.queue_nr == 0); - assert(draw->vcache.referenced == 0); - - memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx)); -} - - -/** - * Check if vertex is in cache, otherwise add it. It won't go through - * VS yet, not until there is a flush operation or the VS queue fills up. - * - * Note that cache entries are basically just two pointers: the first - * an index into the user's vertex arrays, the second a location in - * the vertex shader cache for the post-transformed vertex. - * - * \return pointer to location of (post-transformed) vertex header in the cache - */ -static struct vertex_header *get_vertex( struct draw_context *draw, - unsigned i ) -{ - unsigned slot = (i + (i>>5)) % VCACHE_SIZE; - - assert(slot < 32); /* so we don't exceed the bitfield size below */ - - /* Cache miss? - */ - if (draw->vcache.idx[slot] != i) { - - /* If slot is in use, use the overflow area: - */ - if (draw->vcache.referenced & (1 << slot)) { - slot = VCACHE_SIZE + draw->vcache.overflow++; - } - - assert(slot < Elements(draw->vcache.idx)); - - draw->vcache.idx[slot] = i; - - /* Add to vertex shader queue: - */ - assert(draw->vs.queue_nr < VS_QUEUE_LENGTH); - draw->vs.queue[draw->vs.queue_nr].dest = draw->vcache.vertex[slot]; - draw->vs.queue[draw->vs.queue_nr].elt = i; - draw->vs.queue_nr++; - - /* Need to set the vertex's edge flag here. If we're being called - * by do_ef_triangle(), that function needs edge flag info! - */ - draw->vcache.vertex[slot]->clipmask = 0; - draw->vcache.vertex[slot]->edgeflag = 1; /*XXX use user's edge flag! */ - draw->vcache.vertex[slot]->pad = 0; - draw->vcache.vertex[slot]->vertex_id = UNDEFINED_VERTEX_ID; - } - - - /* primitive flushing may have cleared the bitfield but did not - * clear the idx[] array values. Set the bit now. This fixes a - * bug found when drawing long triangle fans. - */ - draw->vcache.referenced |= (1 << slot); - return draw->vcache.vertex[slot]; -} - - -static struct vertex_header *get_uint_elt_vertex( struct draw_context *draw, - unsigned i ) -{ - const unsigned *elts = (const unsigned *) draw->user.elts; - return get_vertex( draw, elts[i] ); -} - - -static struct vertex_header *get_ushort_elt_vertex( struct draw_context *draw, - unsigned i ) -{ - const ushort *elts = (const ushort *) draw->user.elts; - return get_vertex( draw, elts[i] ); -} - - -static struct vertex_header *get_ubyte_elt_vertex( struct draw_context *draw, - unsigned i ) -{ - const ubyte *elts = (const ubyte *) draw->user.elts; - return get_vertex( draw, elts[i] ); -} - - -void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ) -{ - unsigned i; - - for (i = 0; i < Elements(draw->vcache.vertex); i++) - draw->vcache.vertex[i]->vertex_id = UNDEFINED_VERTEX_ID; -} - - -void draw_vertex_cache_unreference( struct draw_context *draw ) -{ - draw->vcache.referenced = 0; - draw->vcache.overflow = 0; -} - - -int draw_vertex_cache_check_space( struct draw_context *draw, - unsigned nr_verts ) -{ - if (draw->vcache.overflow + nr_verts < VCACHE_OVERFLOW) { - /* The vs queue is sized so that this can never happen: - */ - assert(draw->vs.queue_nr + nr_verts < VS_QUEUE_LENGTH); - return TRUE; - } - else - return FALSE; -} - - - -/** - * Tell the drawing context about the index/element buffer to use - * (ala glDrawElements) - * If no element buffer is to be used (i.e. glDrawArrays) then this - * should be called with eltSize=0 and elements=NULL. - * - * \param draw the drawing context - * \param eltSize size of each element (1, 2 or 4 bytes) - * \param elements the element buffer ptr - */ -void -draw_set_mapped_element_buffer( struct draw_context *draw, - unsigned eltSize, void *elements ) -{ -// draw_statechange( draw ); - - /* choose the get_vertex() function to use */ - switch (eltSize) { - case 0: - draw->vcache.get_vertex = get_vertex; - break; - case 1: - draw->vcache.get_vertex = get_ubyte_elt_vertex; - break; - case 2: - draw->vcache.get_vertex = get_ushort_elt_vertex; - break; - case 4: - draw->vcache.get_vertex = get_uint_elt_vertex; - break; - default: - assert(0); - } - draw->user.elts = elements; - draw->user.eltSize = eltSize; -} - diff --git a/src/gallium/aux/draw/draw_vertex_fetch.c b/src/gallium/aux/draw/draw_vertex_fetch.c deleted file mode 100644 index e13df04605..0000000000 --- a/src/gallium/aux/draw/draw_vertex_fetch.c +++ /dev/null @@ -1,510 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" -#include "draw_context.h" - - -#define DRAW_DBG 0 - - -/** - * Fetch a float[4] vertex attribute from memory, doing format/type - * conversion as needed. - * - * This is probably needed/dupliocated elsewhere, eg format - * conversion, texture sampling etc. - */ -#define FETCH_ATTRIB( NAME, SZ, CVT ) \ -static void \ -fetch_##NAME(const void *ptr, float *attrib) \ -{ \ - static const float defaults[4] = { 0,0,0,1 }; \ - int i; \ - \ - for (i = 0; i < SZ; i++) { \ - attrib[i] = CVT; \ - } \ - \ - for (; i < 4; i++) { \ - attrib[i] = defaults[i]; \ - } \ -} - -#define CVT_64_FLOAT (float) ((double *) ptr)[i] -#define CVT_32_FLOAT ((float *) ptr)[i] - -#define CVT_8_USCALED (float) ((unsigned char *) ptr)[i] -#define CVT_16_USCALED (float) ((unsigned short *) ptr)[i] -#define CVT_32_USCALED (float) ((unsigned int *) ptr)[i] - -#define CVT_8_SSCALED (float) ((char *) ptr)[i] -#define CVT_16_SSCALED (float) ((short *) ptr)[i] -#define CVT_32_SSCALED (float) ((int *) ptr)[i] - -#define CVT_8_UNORM (float) ((unsigned char *) ptr)[i] / 255.0f -#define CVT_16_UNORM (float) ((unsigned short *) ptr)[i] / 65535.0f -#define CVT_32_UNORM (float) ((unsigned int *) ptr)[i] / 4294967295.0f - -#define CVT_8_SNORM (float) ((char *) ptr)[i] / 127.0f -#define CVT_16_SNORM (float) ((short *) ptr)[i] / 32767.0f -#define CVT_32_SNORM (float) ((int *) ptr)[i] / 2147483647.0f - -FETCH_ATTRIB( R64G64B64A64_FLOAT, 4, CVT_64_FLOAT ) -FETCH_ATTRIB( R64G64B64_FLOAT, 3, CVT_64_FLOAT ) -FETCH_ATTRIB( R64G64_FLOAT, 2, CVT_64_FLOAT ) -FETCH_ATTRIB( R64_FLOAT, 1, CVT_64_FLOAT ) - -FETCH_ATTRIB( R32G32B32A32_FLOAT, 4, CVT_32_FLOAT ) -FETCH_ATTRIB( R32G32B32_FLOAT, 3, CVT_32_FLOAT ) -FETCH_ATTRIB( R32G32_FLOAT, 2, CVT_32_FLOAT ) -FETCH_ATTRIB( R32_FLOAT, 1, CVT_32_FLOAT ) - -FETCH_ATTRIB( R32G32B32A32_USCALED, 4, CVT_32_USCALED ) -FETCH_ATTRIB( R32G32B32_USCALED, 3, CVT_32_USCALED ) -FETCH_ATTRIB( R32G32_USCALED, 2, CVT_32_USCALED ) -FETCH_ATTRIB( R32_USCALED, 1, CVT_32_USCALED ) - -FETCH_ATTRIB( R32G32B32A32_SSCALED, 4, CVT_32_SSCALED ) -FETCH_ATTRIB( R32G32B32_SSCALED, 3, CVT_32_SSCALED ) -FETCH_ATTRIB( R32G32_SSCALED, 2, CVT_32_SSCALED ) -FETCH_ATTRIB( R32_SSCALED, 1, CVT_32_SSCALED ) - -FETCH_ATTRIB( R32G32B32A32_UNORM, 4, CVT_32_UNORM ) -FETCH_ATTRIB( R32G32B32_UNORM, 3, CVT_32_UNORM ) -FETCH_ATTRIB( R32G32_UNORM, 2, CVT_32_UNORM ) -FETCH_ATTRIB( R32_UNORM, 1, CVT_32_UNORM ) - -FETCH_ATTRIB( R32G32B32A32_SNORM, 4, CVT_32_SNORM ) -FETCH_ATTRIB( R32G32B32_SNORM, 3, CVT_32_SNORM ) -FETCH_ATTRIB( R32G32_SNORM, 2, CVT_32_SNORM ) -FETCH_ATTRIB( R32_SNORM, 1, CVT_32_SNORM ) - -FETCH_ATTRIB( R16G16B16A16_USCALED, 4, CVT_16_USCALED ) -FETCH_ATTRIB( R16G16B16_USCALED, 3, CVT_16_USCALED ) -FETCH_ATTRIB( R16G16_USCALED, 2, CVT_16_USCALED ) -FETCH_ATTRIB( R16_USCALED, 1, CVT_16_USCALED ) - -FETCH_ATTRIB( R16G16B16A16_SSCALED, 4, CVT_16_SSCALED ) -FETCH_ATTRIB( R16G16B16_SSCALED, 3, CVT_16_SSCALED ) -FETCH_ATTRIB( R16G16_SSCALED, 2, CVT_16_SSCALED ) -FETCH_ATTRIB( R16_SSCALED, 1, CVT_16_SSCALED ) - -FETCH_ATTRIB( R16G16B16A16_UNORM, 4, CVT_16_UNORM ) -FETCH_ATTRIB( R16G16B16_UNORM, 3, CVT_16_UNORM ) -FETCH_ATTRIB( R16G16_UNORM, 2, CVT_16_UNORM ) -FETCH_ATTRIB( R16_UNORM, 1, CVT_16_UNORM ) - -FETCH_ATTRIB( R16G16B16A16_SNORM, 4, CVT_16_SNORM ) -FETCH_ATTRIB( R16G16B16_SNORM, 3, CVT_16_SNORM ) -FETCH_ATTRIB( R16G16_SNORM, 2, CVT_16_SNORM ) -FETCH_ATTRIB( R16_SNORM, 1, CVT_16_SNORM ) - -FETCH_ATTRIB( R8G8B8A8_USCALED, 4, CVT_8_USCALED ) -FETCH_ATTRIB( R8G8B8_USCALED, 3, CVT_8_USCALED ) -FETCH_ATTRIB( R8G8_USCALED, 2, CVT_8_USCALED ) -FETCH_ATTRIB( R8_USCALED, 1, CVT_8_USCALED ) - -FETCH_ATTRIB( R8G8B8A8_SSCALED, 4, CVT_8_SSCALED ) -FETCH_ATTRIB( R8G8B8_SSCALED, 3, CVT_8_SSCALED ) -FETCH_ATTRIB( R8G8_SSCALED, 2, CVT_8_SSCALED ) -FETCH_ATTRIB( R8_SSCALED, 1, CVT_8_SSCALED ) - -FETCH_ATTRIB( R8G8B8A8_UNORM, 4, CVT_8_UNORM ) -FETCH_ATTRIB( R8G8B8_UNORM, 3, CVT_8_UNORM ) -FETCH_ATTRIB( R8G8_UNORM, 2, CVT_8_UNORM ) -FETCH_ATTRIB( R8_UNORM, 1, CVT_8_UNORM ) - -FETCH_ATTRIB( R8G8B8A8_SNORM, 4, CVT_8_SNORM ) -FETCH_ATTRIB( R8G8B8_SNORM, 3, CVT_8_SNORM ) -FETCH_ATTRIB( R8G8_SNORM, 2, CVT_8_SNORM ) -FETCH_ATTRIB( R8_SNORM, 1, CVT_8_SNORM ) - -FETCH_ATTRIB( A8R8G8B8_UNORM, 4, CVT_8_UNORM ) -//FETCH_ATTRIB( R8G8B8A8_UNORM, 4, CVT_8_UNORM ) - - - -static fetch_func get_fetch_func( enum pipe_format format ) -{ -#if 0 - { - char tmp[80]; - pf_sprint_name(tmp, format); - debug_printf("%s: %s\n", __FUNCTION__, tmp); - } -#endif - - switch (format) { - case PIPE_FORMAT_R64_FLOAT: - return fetch_R64_FLOAT; - case PIPE_FORMAT_R64G64_FLOAT: - return fetch_R64G64_FLOAT; - case PIPE_FORMAT_R64G64B64_FLOAT: - return fetch_R64G64B64_FLOAT; - case PIPE_FORMAT_R64G64B64A64_FLOAT: - return fetch_R64G64B64A64_FLOAT; - - case PIPE_FORMAT_R32_FLOAT: - return fetch_R32_FLOAT; - case PIPE_FORMAT_R32G32_FLOAT: - return fetch_R32G32_FLOAT; - case PIPE_FORMAT_R32G32B32_FLOAT: - return fetch_R32G32B32_FLOAT; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - return fetch_R32G32B32A32_FLOAT; - - case PIPE_FORMAT_R32_UNORM: - return fetch_R32_UNORM; - case PIPE_FORMAT_R32G32_UNORM: - return fetch_R32G32_UNORM; - case PIPE_FORMAT_R32G32B32_UNORM: - return fetch_R32G32B32_UNORM; - case PIPE_FORMAT_R32G32B32A32_UNORM: - return fetch_R32G32B32A32_UNORM; - - case PIPE_FORMAT_R32_USCALED: - return fetch_R32_USCALED; - case PIPE_FORMAT_R32G32_USCALED: - return fetch_R32G32_USCALED; - case PIPE_FORMAT_R32G32B32_USCALED: - return fetch_R32G32B32_USCALED; - case PIPE_FORMAT_R32G32B32A32_USCALED: - return fetch_R32G32B32A32_USCALED; - - case PIPE_FORMAT_R32_SNORM: - return fetch_R32_SNORM; - case PIPE_FORMAT_R32G32_SNORM: - return fetch_R32G32_SNORM; - case PIPE_FORMAT_R32G32B32_SNORM: - return fetch_R32G32B32_SNORM; - case PIPE_FORMAT_R32G32B32A32_SNORM: - return fetch_R32G32B32A32_SNORM; - - case PIPE_FORMAT_R32_SSCALED: - return fetch_R32_SSCALED; - case PIPE_FORMAT_R32G32_SSCALED: - return fetch_R32G32_SSCALED; - case PIPE_FORMAT_R32G32B32_SSCALED: - return fetch_R32G32B32_SSCALED; - case PIPE_FORMAT_R32G32B32A32_SSCALED: - return fetch_R32G32B32A32_SSCALED; - - case PIPE_FORMAT_R16_UNORM: - return fetch_R16_UNORM; - case PIPE_FORMAT_R16G16_UNORM: - return fetch_R16G16_UNORM; - case PIPE_FORMAT_R16G16B16_UNORM: - return fetch_R16G16B16_UNORM; - case PIPE_FORMAT_R16G16B16A16_UNORM: - return fetch_R16G16B16A16_UNORM; - - case PIPE_FORMAT_R16_USCALED: - return fetch_R16_USCALED; - case PIPE_FORMAT_R16G16_USCALED: - return fetch_R16G16_USCALED; - case PIPE_FORMAT_R16G16B16_USCALED: - return fetch_R16G16B16_USCALED; - case PIPE_FORMAT_R16G16B16A16_USCALED: - return fetch_R16G16B16A16_USCALED; - - case PIPE_FORMAT_R16_SNORM: - return fetch_R16_SNORM; - case PIPE_FORMAT_R16G16_SNORM: - return fetch_R16G16_SNORM; - case PIPE_FORMAT_R16G16B16_SNORM: - return fetch_R16G16B16_SNORM; - case PIPE_FORMAT_R16G16B16A16_SNORM: - return fetch_R16G16B16A16_SNORM; - - case PIPE_FORMAT_R16_SSCALED: - return fetch_R16_SSCALED; - case PIPE_FORMAT_R16G16_SSCALED: - return fetch_R16G16_SSCALED; - case PIPE_FORMAT_R16G16B16_SSCALED: - return fetch_R16G16B16_SSCALED; - case PIPE_FORMAT_R16G16B16A16_SSCALED: - return fetch_R16G16B16A16_SSCALED; - - case PIPE_FORMAT_R8_UNORM: - return fetch_R8_UNORM; - case PIPE_FORMAT_R8G8_UNORM: - return fetch_R8G8_UNORM; - case PIPE_FORMAT_R8G8B8_UNORM: - return fetch_R8G8B8_UNORM; - case PIPE_FORMAT_R8G8B8A8_UNORM: - return fetch_R8G8B8A8_UNORM; - - case PIPE_FORMAT_R8_USCALED: - return fetch_R8_USCALED; - case PIPE_FORMAT_R8G8_USCALED: - return fetch_R8G8_USCALED; - case PIPE_FORMAT_R8G8B8_USCALED: - return fetch_R8G8B8_USCALED; - case PIPE_FORMAT_R8G8B8A8_USCALED: - return fetch_R8G8B8A8_USCALED; - - case PIPE_FORMAT_R8_SNORM: - return fetch_R8_SNORM; - case PIPE_FORMAT_R8G8_SNORM: - return fetch_R8G8_SNORM; - case PIPE_FORMAT_R8G8B8_SNORM: - return fetch_R8G8B8_SNORM; - case PIPE_FORMAT_R8G8B8A8_SNORM: - return fetch_R8G8B8A8_SNORM; - - case PIPE_FORMAT_R8_SSCALED: - return fetch_R8_SSCALED; - case PIPE_FORMAT_R8G8_SSCALED: - return fetch_R8G8_SSCALED; - case PIPE_FORMAT_R8G8B8_SSCALED: - return fetch_R8G8B8_SSCALED; - case PIPE_FORMAT_R8G8B8A8_SSCALED: - return fetch_R8G8B8A8_SSCALED; - - case PIPE_FORMAT_A8R8G8B8_UNORM: - return fetch_A8R8G8B8_UNORM; - - case 0: - return NULL; /* not sure why this is needed */ - - default: - assert(0); - return NULL; - } -} - - -static void -transpose_4x4( float *out, const float *in ) -{ - /* This can be achieved in 12 sse instructions, plus the final - * stores I guess. This is probably a bit more than that - maybe - * 32 or so? - */ - out[0] = in[0]; out[1] = in[4]; out[2] = in[8]; out[3] = in[12]; - out[4] = in[1]; out[5] = in[5]; out[6] = in[9]; out[7] = in[13]; - out[8] = in[2]; out[9] = in[6]; out[10] = in[10]; out[11] = in[14]; - out[12] = in[3]; out[13] = in[7]; out[14] = in[11]; out[15] = in[15]; -} - - - -static void fetch_xyz_rgb( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ) -{ - const unsigned *pitch = draw->vertex_fetch.pitch; - const ubyte **src = draw->vertex_fetch.src_ptr; - int i; - - assert(count <= 4); - -// debug_printf("%s\n", __FUNCTION__); - - /* loop over vertex attributes (vertex shader inputs) - */ - - for (i = 0; i < 4; i++) { - { - const float *in = (const float *)(src[0] + elts[i] * pitch[0]); - float *out = &machine->Inputs[0].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - - { - const float *in = (const float *)(src[1] + elts[i] * pitch[1]); - float *out = &machine->Inputs[1].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - } -} - - - - -static void fetch_xyz_rgb_st( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ) -{ - const unsigned *pitch = draw->vertex_fetch.pitch; - const ubyte **src = draw->vertex_fetch.src_ptr; - int i; - - assert(count <= 4); - - /* loop over vertex attributes (vertex shader inputs) - */ - - for (i = 0; i < 4; i++) { - { - const float *in = (const float *)(src[0] + elts[i] * pitch[0]); - float *out = &machine->Inputs[0].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - - { - const float *in = (const float *)(src[1] + elts[i] * pitch[1]); - float *out = &machine->Inputs[1].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - - { - const float *in = (const float *)(src[2] + elts[i] * pitch[2]); - float *out = &machine->Inputs[2].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = 0.0f; - out[12] = 1.0f; - } - } -} - - - - -/** - * Fetch vertex attributes for 'count' vertices. - */ -static void generic_vertex_fetch( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ) -{ - unsigned nr_attrs = draw->vertex_fetch.nr_attrs; - unsigned attr; - - assert(count <= 4); - -// debug_printf("%s %d\n", __FUNCTION__, count); - - /* loop over vertex attributes (vertex shader inputs) - */ - for (attr = 0; attr < nr_attrs; attr++) { - - const unsigned pitch = draw->vertex_fetch.pitch[attr]; - const ubyte *src = draw->vertex_fetch.src_ptr[attr]; - const fetch_func fetch = draw->vertex_fetch.fetch[attr]; - unsigned i; - float p[4][4]; - - - /* Fetch four attributes for four vertices. - * - * Could fetch directly into AOS format, but this is meant to be - * a prototype for an sse implementation, which would have - * difficulties doing that. - */ - for (i = 0; i < count; i++) - fetch( src + elts[i] * pitch, p[i] ); - - /* Be nice and zero out any missing vertices: - */ - for ( ; i < 4; i++) - p[i][0] = p[i][1] = p[i][2] = p[i][3] = 0; - - /* Transpose/swizzle into sse-friendly format. Currently - * assuming that all vertex shader inputs are float[4], but this - * isn't true -- if the vertex shader only wants tex0.xy, we - * could optimize for that. - * - * To do so fully without codegen would probably require an - * excessive number of fetch functions, but we could at least - * minimize the transpose step: - */ - transpose_4x4( (float *)&machine->Inputs[attr].xyzw[0].f[0], (float *)p ); - } -} - - - -void draw_update_vertex_fetch( struct draw_context *draw ) -{ - unsigned nr_attrs, i; - -// debug_printf("%s\n", __FUNCTION__); - - /* this may happend during context init */ - if (!draw->vertex_shader) - return; - - nr_attrs = draw->vertex_shader->state->num_inputs; - - for (i = 0; i < nr_attrs; i++) { - unsigned buf = draw->vertex_element[i].vertex_buffer_index; - enum pipe_format format = draw->vertex_element[i].src_format; - - draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] + - draw->vertex_buffer[buf].buffer_offset + - draw->vertex_element[i].src_offset; - - draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch; - draw->vertex_fetch.fetch[i] = get_fetch_func( format ); - } - - draw->vertex_fetch.nr_attrs = nr_attrs; - - draw->vertex_fetch.fetch_func = generic_vertex_fetch; - - switch (nr_attrs) { - case 2: - if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT && - draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT) - draw->vertex_fetch.fetch_func = fetch_xyz_rgb; - break; - case 3: - if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT && - draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT && - draw->vertex_element[2].src_format == PIPE_FORMAT_R32G32_FLOAT) - draw->vertex_fetch.fetch_func = fetch_xyz_rgb_st; - break; - default: - break; - } - -} diff --git a/src/gallium/aux/draw/draw_vertex_shader.c b/src/gallium/aux/draw/draw_vertex_shader.c deleted file mode 100644 index 377ecbb931..0000000000 --- a/src/gallium/aux/draw/draw_vertex_shader.c +++ /dev/null @@ -1,325 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - * Brian Paul - */ - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#if defined(__i386__) || defined(__386__) -#include "tgsi/exec/tgsi_sse2.h" -#endif -#include "draw_private.h" -#include "draw_context.h" - -#include "x86/rtasm/x86sse.h" -#include "llvm/gallivm.h" - - -#define DBG_VS 0 - - -static INLINE unsigned -compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) -{ - unsigned mask = 0; - unsigned i; - - /* Do the hardwired planes first: - */ - if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; - if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; - if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; - if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; - if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; - if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; - - /* Followed by any remaining ones: - */ - for (i = 6; i < nr; i++) { - if (dot4(clip, plane[i]) < 0) - mask |= (1<machine; - unsigned int j; - - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); - const float *scale = draw->viewport.scale; - const float *trans = draw->viewport.translate; - - assert(count <= 4); - assert(draw->vertex_shader->state->output_semantic_name[0] - == TGSI_SEMANTIC_POSITION); - - /* Consts does not require 16 byte alignment. */ - machine->Consts = (float (*)[4]) draw->user.constants; - - machine->Inputs = ALIGN16_ASSIGN(inputs); - machine->Outputs = ALIGN16_ASSIGN(outputs); - - draw->vertex_fetch.fetch_func( draw, machine, elts, count ); - - /* run shader */ -#ifdef MESA_LLVM - if (1) { - struct gallivm_prog *prog = draw->vertex_shader->llvm_prog; - gallivm_cpu_vs_exec(prog, - machine->Inputs, - machine->Outputs, - machine->Consts, - machine->Temps); - } else -#elif defined(__i386__) || defined(__386__) - if (draw->use_sse) { - /* SSE */ - /* cast away const */ - struct draw_vertex_shader *shader - = (struct draw_vertex_shader *)draw->vertex_shader; - codegen_function func - = (codegen_function) x86_get_func( &shader->sse2_program ); - - if (func) - func( - machine->Inputs, - machine->Outputs, - machine->Consts, - machine->Temps ); - else - /* interpreter */ - tgsi_exec_machine_run( machine ); - } - else -#endif - { - /* interpreter */ - tgsi_exec_machine_run( machine ); - } - - /* store machine results */ - for (j = 0; j < count; j++) { - unsigned slot; - float x, y, z, w; - - /* Handle attr[0] (position) specially: - * - * XXX: Computing the clipmask should be done in the vertex - * program as a set of DP4 instructions appended to the - * user-provided code. - */ - x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; - - vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); - vOut[j]->edgeflag = 1; - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - - /* Viewport mapping */ - vOut[j]->data[0][0] = x * scale[0] + trans[0]; - vOut[j]->data[0][1] = y * scale[1] + trans[1]; - vOut[j]->data[0][2] = z * scale[2] + trans[2]; - vOut[j]->data[0][3] = w; - -#if DBG_VS - debug_printf("output[%d]win: %f %f %f %f\n", j, - vOut[j]->data[0][0], - vOut[j]->data[0][1], - vOut[j]->data[0][2], - vOut[j]->data[0][3]); -#endif - /* Remaining attributes are packed into sequential post-transform - * vertex attrib slots. - */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; -#if DBG_VS - debug_printf("output[%d][%d]: %f %f %f %f\n", j, slot, - vOut[j]->data[slot][0], - vOut[j]->data[slot][1], - vOut[j]->data[slot][2], - vOut[j]->data[slot][3]); -#endif - } - } /* loop over vertices */ -} - - -/** - * Run the vertex shader on all vertices in the vertex queue. - * Called by the draw module when the vertx cache needs to be flushed. - */ -void -draw_vertex_shader_queue_flush(struct draw_context *draw) -{ - unsigned i; - - assert(draw->vs.queue_nr != 0); - - /* XXX: do this on statechange: - */ - draw_update_vertex_fetch( draw ); - -// fprintf(stderr, " q(%d) ", draw->vs.queue_nr ); - - /* run vertex shader on vertex cache entries, four per invokation */ - for (i = 0; i < draw->vs.queue_nr; i += 4) { - struct vertex_header *dests[4]; - unsigned elts[4]; - int j, n = MIN2(4, draw->vs.queue_nr - i); - - for (j = 0; j < n; j++) { - elts[j] = draw->vs.queue[i + j].elt; - dests[j] = draw->vs.queue[i + j].dest; - } - - for ( ; j < 4; j++) { - elts[j] = elts[0]; - dests[j] = dests[0]; - } - - assert(n > 0); - assert(n <= 4); - - run_vertex_program(draw, elts, n, dests); - } - - draw->vs.queue_nr = 0; -} - - -struct draw_vertex_shader * -draw_create_vertex_shader(struct draw_context *draw, - const struct pipe_shader_state *shader) -{ - struct draw_vertex_shader *vs; - - vs = CALLOC_STRUCT( draw_vertex_shader ); - if (vs == NULL) { - return NULL; - } - - vs->state = shader; - -#ifdef MESA_LLVM - struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); - gallivm_ir_set_layout(ir, GALLIVM_SOA); - gallivm_ir_set_components(ir, 4); - gallivm_ir_fill_from_tgsi(ir, shader->tokens); - vs->llvm_prog = gallivm_ir_compile(ir); - gallivm_ir_delete(ir); - - draw->engine = gallivm_global_cpu_engine(); - if (!draw->engine) { - draw->engine = gallivm_cpu_engine_create(vs->llvm_prog); - } - else { - gallivm_cpu_jit_compile(draw->engine, vs->llvm_prog); - } -#elif defined(__i386__) || defined(__386__) - if (draw->use_sse) { - /* cast-away const */ - struct pipe_shader_state *sh = (struct pipe_shader_state *) shader; - - x86_init_func( &vs->sse2_program ); - if (!tgsi_emit_sse2( (struct tgsi_token *) sh->tokens, - &vs->sse2_program )) { - x86_release_func( (struct x86_function *) &vs->sse2_program ); - fprintf(stdout /*err*/, - "tgsi_emit_sse2() failed, falling back to interpreter\n"); - } - } -#endif - - return vs; -} - - -void -draw_bind_vertex_shader(struct draw_context *draw, - struct draw_vertex_shader *dvs) -{ - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - - draw->vertex_shader = dvs; - draw->num_vs_outputs = dvs->state->num_outputs; - - /* specify the vertex program to interpret/execute */ - tgsi_exec_machine_init(&draw->machine, - draw->vertex_shader->state->tokens, - PIPE_MAX_SAMPLERS, - NULL /*samplers*/ ); -} - - -void -draw_delete_vertex_shader(struct draw_context *draw, - struct draw_vertex_shader *dvs) -{ -#if defined(__i386__) || defined(__386__) - x86_release_func( (struct x86_function *) &dvs->sse2_program ); -#endif - - FREE( dvs ); -} diff --git a/src/gallium/aux/draw/draw_vf.c b/src/gallium/aux/draw/draw_vf.c deleted file mode 100644 index dc3a5ecd21..0000000000 --- a/src/gallium/aux/draw/draw_vf.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Copyright 2003 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - */ - - -#include - -#include "pipe/p_compiler.h" -#include "pipe/p_util.h" - -#include "draw_vf.h" - - -#define DRAW_VF_DBG 0 - - -/* TODO: remove this */ -extern void -_mesa_exec_free( void *addr ); - - -static boolean match_fastpath( struct draw_vertex_fetch *vf, - const struct draw_vf_fastpath *fp) -{ - unsigned j; - - if (vf->attr_count != fp->attr_count) - return FALSE; - - for (j = 0; j < vf->attr_count; j++) - if (vf->attr[j].format != fp->attr[j].format || - vf->attr[j].inputsize != fp->attr[j].size || - vf->attr[j].vertoffset != fp->attr[j].offset) - return FALSE; - - if (fp->match_strides) { - if (vf->vertex_stride != fp->vertex_stride) - return FALSE; - - for (j = 0; j < vf->attr_count; j++) - if (vf->attr[j].inputstride != fp->attr[j].stride) - return FALSE; - } - - return TRUE; -} - -static boolean search_fastpath_emit( struct draw_vertex_fetch *vf ) -{ - struct draw_vf_fastpath *fp = vf->fastpath; - - for ( ; fp ; fp = fp->next) { - if (match_fastpath(vf, fp)) { - vf->emit = fp->func; - return TRUE; - } - } - - return FALSE; -} - -void draw_vf_register_fastpath( struct draw_vertex_fetch *vf, - boolean match_strides ) -{ - struct draw_vf_fastpath *fastpath = CALLOC_STRUCT(draw_vf_fastpath); - unsigned i; - - fastpath->vertex_stride = vf->vertex_stride; - fastpath->attr_count = vf->attr_count; - fastpath->match_strides = match_strides; - fastpath->func = vf->emit; - fastpath->attr = (struct draw_vf_attr_type *) - MALLOC(vf->attr_count * sizeof(fastpath->attr[0])); - - for (i = 0; i < vf->attr_count; i++) { - fastpath->attr[i].format = vf->attr[i].format; - fastpath->attr[i].stride = vf->attr[i].inputstride; - fastpath->attr[i].size = vf->attr[i].inputsize; - fastpath->attr[i].offset = vf->attr[i].vertoffset; - } - - fastpath->next = vf->fastpath; - vf->fastpath = fastpath; -} - - - - -/*********************************************************************** - * Build codegen functions or return generic ones: - */ -static void choose_emit_func( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *dest) -{ - vf->emit = NULL; - - /* Does this match an existing (hardwired, codegen or known-bad) - * fastpath? - */ - if (search_fastpath_emit(vf)) { - /* Use this result. If it is null, then it is already known - * that the current state will fail for codegen and there is no - * point trying again. - */ - } - else if (vf->codegen_emit) { - vf->codegen_emit( vf ); - } - - if (!vf->emit) { - draw_vf_generate_hardwired_emit(vf); - } - - /* Otherwise use the generic version: - */ - if (!vf->emit) - vf->emit = draw_vf_generic_emit; - - vf->emit( vf, count, dest ); -} - - - - - -/*********************************************************************** - * Public entrypoints, mostly dispatch to the above: - */ - - - -static unsigned -draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, - const struct draw_vf_attr_map *map, - unsigned nr, - unsigned vertex_stride ) -{ - unsigned offset = 0; - unsigned i, j; - - assert(nr < PIPE_ATTRIB_MAX); - - for (j = 0, i = 0; i < nr; i++) { - const unsigned format = map[i].format; - if (format == DRAW_EMIT_PAD) { -#if (DRAW_VF_DBG) - debug_printf("%d: pad %d, offset %d\n", i, - map[i].offset, offset); -#endif - - offset += map[i].offset; - - } - else { - vf->attr[j].attrib = map[i].attrib; - vf->attr[j].format = format; - vf->attr[j].insert = draw_vf_format_info[format].insert; - vf->attr[j].vertattrsize = draw_vf_format_info[format].attrsize; - vf->attr[j].vertoffset = offset; - vf->attr[j].isconst = draw_vf_format_info[format].isconst; - if(vf->attr[j].isconst) - memcpy(vf->attr[j].data, &map[i].data, vf->attr[j].vertattrsize); - -#if (DRAW_VF_DBG) - debug_printf("%d: %s, offset %d\n", i, - draw_vf_format_info[format].name, - vf->attr[j].vertoffset); -#endif - - offset += draw_vf_format_info[format].attrsize; - j++; - } - } - - vf->attr_count = j; - vf->vertex_stride = vertex_stride ? vertex_stride : offset; - vf->emit = choose_emit_func; - - assert(vf->vertex_stride >= offset); - return vf->vertex_stride; -} - - -void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, - const struct vertex_info *vinfo, - float point_size ) -{ - unsigned i, j, k; - struct draw_vf_attr *a = vf->attr; - struct draw_vf_attr_map attrs[PIPE_MAX_SHADER_INPUTS]; - unsigned count = 0; /* for debug/sanity */ - unsigned nr_attrs = 0; - - for (i = 0; i < vinfo->num_attribs; i++) { - j = vinfo->src_index[i]; - switch (vinfo->emit[i]) { - case EMIT_OMIT: - /* no-op */ - break; - case EMIT_ALL: { - /* just copy the whole vertex as-is to the vbuf */ - unsigned s = vinfo->size; - assert(i == 0); - assert(j == 0); - /* copy the vertex header */ - /* XXX: we actually don't copy the header, just pad it */ - attrs[nr_attrs].attrib = 0; - attrs[nr_attrs].format = DRAW_EMIT_PAD; - attrs[nr_attrs].offset = offsetof(struct vertex_header, data); - s -= offsetof(struct vertex_header, data)/4; - count += offsetof(struct vertex_header, data)/4; - nr_attrs++; - /* copy the vertex data */ - for(k = 0; k < (s & ~0x3); k += 4) { - attrs[nr_attrs].attrib = k/4; - attrs[nr_attrs].format = DRAW_EMIT_4F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 4; - } - /* tail */ - /* XXX: actually, this shouldn't be needed */ - attrs[nr_attrs].attrib = k/4; - attrs[nr_attrs].offset = 0; - switch(s & 0x3) { - case 0: - break; - case 1: - attrs[nr_attrs].format = DRAW_EMIT_1F; - nr_attrs++; - count += 1; - break; - case 2: - attrs[nr_attrs].format = DRAW_EMIT_2F; - nr_attrs++; - count += 2; - break; - case 3: - attrs[nr_attrs].format = DRAW_EMIT_3F; - nr_attrs++; - count += 3; - break; - } - break; - } - case EMIT_1F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_1F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count++; - break; - case EMIT_1F_PSIZE: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_1F_CONST; - attrs[nr_attrs].offset = 0; - attrs[nr_attrs].data.f[0] = point_size; - nr_attrs++; - count++; - break; - case EMIT_2F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_2F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 2; - break; - case EMIT_3F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_3F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 3; - break; - case EMIT_4F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_4F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 4; - break; - case EMIT_4UB: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_4UB_4F_BGRA; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 1; - break; - default: - assert(0); - } - } - - assert(count == vinfo->size); - - draw_vf_set_vertex_attributes(vf, - attrs, - nr_attrs, - vinfo->size * sizeof(float) ); - - for (j = 0; j < vf->attr_count; j++) { - a[j].inputsize = 4; - a[j].do_insert = a[j].insert[4 - 1]; - if(a[j].isconst) { - a[j].inputptr = a[j].data; - a[j].inputstride = 0; - } - } -} - - -#if 0 -/* Set attribute pointers, adjusted for start position: - */ -void draw_vf_set_sources( struct draw_vertex_fetch *vf, - GLvector4f * const sources[], - unsigned start ) -{ - struct draw_vf_attr *a = vf->attr; - unsigned j; - - for (j = 0; j < vf->attr_count; j++) { - const GLvector4f *vptr = sources[a[j].attrib]; - - if ((a[j].inputstride != vptr->stride) || - (a[j].inputsize != vptr->size)) - vf->emit = choose_emit_func; - - a[j].inputstride = vptr->stride; - a[j].inputsize = vptr->size; - a[j].do_insert = a[j].insert[vptr->size - 1]; - a[j].inputptr = ((uint8_t *)vptr->data) + start * vptr->stride; - } -} -#endif - - -/** - * Emit a vertex to dest. - */ -void draw_vf_emit_vertex( struct draw_vertex_fetch *vf, - struct vertex_header *vertex, - void *dest ) -{ - struct draw_vf_attr *a = vf->attr; - unsigned j; - - for (j = 0; j < vf->attr_count; j++) { - if (!a[j].isconst) { - a[j].inputptr = (uint8_t *)&vertex->data[a[j].attrib][0]; - a[j].inputstride = 0; /* XXX: one-vertex-max ATM */ - } - } - - vf->emit( vf, 1, (uint8_t*) dest ); -} - - - -struct draw_vertex_fetch *draw_vf_create( void ) -{ - struct draw_vertex_fetch *vf = CALLOC_STRUCT(draw_vertex_fetch); - unsigned i; - - for (i = 0; i < PIPE_ATTRIB_MAX; i++) - vf->attr[i].vf = vf; - - vf->identity[0] = 0.0; - vf->identity[1] = 0.0; - vf->identity[2] = 0.0; - vf->identity[3] = 1.0; - - vf->codegen_emit = NULL; - -#ifdef USE_SSE_ASM - if (!GETENV("GALLIUM_NO_CODEGEN")) - vf->codegen_emit = draw_vf_generate_sse_emit; -#endif - - return vf; -} - - -void draw_vf_destroy( struct draw_vertex_fetch *vf ) -{ - struct draw_vf_fastpath *fp, *tmp; - - for (fp = vf->fastpath ; fp ; fp = tmp) { - tmp = fp->next; - FREE(fp->attr); - - /* KW: At the moment, fp->func is constrained to be allocated by - * _mesa_exec_alloc(), as the hardwired fastpaths in - * t_vertex_generic.c are handled specially. It would be nice - * to unify them, but this probably won't change until this - * module gets another overhaul. - */ - //_mesa_exec_free((void *) fp->func); - FREE(fp); - } - - vf->fastpath = NULL; - FREE(vf); -} diff --git a/src/gallium/aux/draw/draw_vf.h b/src/gallium/aux/draw/draw_vf.h deleted file mode 100644 index 011c8f0ff1..0000000000 --- a/src/gallium/aux/draw/draw_vf.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2008 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * Vertex fetch/store/convert code. This functionality is used in two places: - * 1. Vertex fetch/convert - to grab vertex data from incoming vertex - * arrays and convert to format needed by vertex shaders. - * 2. Vertex store/emit - to convert simple float[][4] vertex attributes - * (which is the organization used throughout the draw/prim pipeline) to - * hardware-specific formats and emit into hardware vertex buffers. - * - * - * Authors: - * Keith Whitwell - */ - -#ifndef DRAW_VF_H -#define DRAW_VF_H - - -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" - -#include "draw_vertex.h" -#include "draw_private.h" /* for vertex_header */ - - -enum draw_vf_attr_format { - DRAW_EMIT_1F, - DRAW_EMIT_2F, - DRAW_EMIT_3F, - DRAW_EMIT_4F, - DRAW_EMIT_3F_XYW, /**< for projective texture */ - DRAW_EMIT_1UB_1F, /**< for fog coordinate */ - DRAW_EMIT_3UB_3F_RGB, /**< for specular color */ - DRAW_EMIT_3UB_3F_BGR, /**< for specular color */ - DRAW_EMIT_4UB_4F_RGBA, /**< for color */ - DRAW_EMIT_4UB_4F_BGRA, /**< for color */ - DRAW_EMIT_4UB_4F_ARGB, /**< for color */ - DRAW_EMIT_4UB_4F_ABGR, /**< for color */ - DRAW_EMIT_1F_CONST, - DRAW_EMIT_2F_CONST, - DRAW_EMIT_3F_CONST, - DRAW_EMIT_4F_CONST, - DRAW_EMIT_PAD, /**< leave a hole of 'offset' bytes */ - DRAW_EMIT_MAX -}; - -struct draw_vf_attr_map -{ - /** Input attribute number */ - unsigned attrib; - - enum draw_vf_attr_format format; - - unsigned offset; - - /** - * Constant data for DRAW_EMIT_*_CONST - */ - union { - uint8_t ub[4]; - float f[4]; - } data; -}; - -struct draw_vertex_fetch; - - - -#if 0 -unsigned -draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, - const struct draw_vf_attr_map *map, - unsigned nr, - unsigned vertex_stride ); -#endif - -void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, - const struct vertex_info *vinfo, - float point_size ); - -#if 0 -void -draw_vf_set_sources( struct draw_vertex_fetch *vf, - GLvector4f * const attrib[], - unsigned start ); -#endif - -void -draw_vf_emit_vertex( struct draw_vertex_fetch *vf, - struct vertex_header *vertex, - void *dest ); - -struct draw_vertex_fetch * -draw_vf_create( void ); - -void -draw_vf_destroy( struct draw_vertex_fetch *vf ); - - - -/*********************************************************************** - * Internal functions and structs: - */ - -struct draw_vf_attr; - -typedef void (*draw_vf_extract_func)( const struct draw_vf_attr *a, - float *out, - const uint8_t *v ); - -typedef void (*draw_vf_insert_func)( const struct draw_vf_attr *a, - uint8_t *v, - const float *in ); - -typedef void (*draw_vf_emit_func)( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *dest ); - - - -/** - * Describes how to convert/move a vertex attribute from a vertex - * array to a vertex structure. - */ -struct draw_vf_attr -{ - struct draw_vertex_fetch *vf; - - unsigned format; - unsigned inputsize; - unsigned inputstride; - unsigned vertoffset; /**< position of the attrib in the vertex struct */ - - boolean isconst; /**< read from const data below */ - uint8_t data[16]; - - unsigned attrib; /**< which vertex attrib (0=position, etc) */ - unsigned vertattrsize; /**< size of the attribute in bytes */ - - uint8_t *inputptr; - const draw_vf_insert_func *insert; - draw_vf_insert_func do_insert; - draw_vf_extract_func extract; -}; - -struct draw_vertex_fetch -{ - struct draw_vf_attr attr[PIPE_ATTRIB_MAX]; - unsigned attr_count; - unsigned vertex_stride; - - draw_vf_emit_func emit; - - /* Parameters and constants for codegen: - */ - float identity[4]; - - struct draw_vf_fastpath *fastpath; - - void (*codegen_emit)( struct draw_vertex_fetch *vf ); -}; - - -struct draw_vf_attr_type { - unsigned format; - unsigned size; - unsigned stride; - unsigned offset; -}; - -/** XXX this could be moved into draw_vf.c */ -struct draw_vf_fastpath { - unsigned vertex_stride; - unsigned attr_count; - boolean match_strides; - - struct draw_vf_attr_type *attr; - - draw_vf_emit_func func; - struct draw_vf_fastpath *next; -}; - - -void -draw_vf_register_fastpath( struct draw_vertex_fetch *vtx, - boolean match_strides ); - -void -draw_vf_generic_emit( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *v ); - -void -draw_vf_generate_hardwired_emit( struct draw_vertex_fetch *vf ); - -void -draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ); - - -/** XXX this type and function could probably be moved into draw_vf.c */ -struct draw_vf_format_info { - const char *name; - draw_vf_insert_func insert[4]; - const unsigned attrsize; - const boolean isconst; -}; - -extern const struct draw_vf_format_info -draw_vf_format_info[DRAW_EMIT_MAX]; - - -#endif diff --git a/src/gallium/aux/draw/draw_vf_generic.c b/src/gallium/aux/draw/draw_vf_generic.c deleted file mode 100644 index 7a60a9db9c..0000000000 --- a/src/gallium/aux/draw/draw_vf_generic.c +++ /dev/null @@ -1,585 +0,0 @@ - -/* - * Copyright 2003 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - */ - - -#include "pipe/p_compiler.h" -#include "pipe/p_debug.h" -#include "pipe/p_util.h" - -#include "draw_vf.h" - - - -static INLINE void insert_4f_4( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; -} - -static INLINE void insert_4f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = 1; -} - -static INLINE void insert_4f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = 0; - out[3] = 1; -} - -static INLINE void insert_4f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = 0; - out[2] = 0; - out[3] = 1; -} - -static INLINE void insert_3f_xyw_4( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[3]; -} - -static INLINE void insert_3f_xyw_err( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - (void) a; (void) v; (void) in; - assert(0); -} - -static INLINE void insert_3f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; -} - -static INLINE void insert_3f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = 0; -} - -static INLINE void insert_3f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = 0; - out[2] = 0; -} - - -static INLINE void insert_2f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; -} - -static INLINE void insert_2f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = 0; -} - -static INLINE void insert_1f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; -} - -static INLINE void insert_null( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - (void) a; (void) v; (void) in; -} - -static INLINE void insert_4ub_4f_rgba_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); -} - -static INLINE void insert_4ub_4f_rgba_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_rgba_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[2] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_rgba_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - v[1] = 0; - v[2] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_bgra_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); -} - -static INLINE void insert_4ub_4f_bgra_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_bgra_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[0] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_bgra_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - v[1] = 0; - v[0] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_argb_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); -} - -static INLINE void insert_4ub_4f_argb_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_argb_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - v[3] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_argb_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - v[2] = 0x00; - v[3] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_abgr_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); -} - -static INLINE void insert_4ub_4f_abgr_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_abgr_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - v[1] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_abgr_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - v[2] = 0x00; - v[1] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_3ub_3f_rgb_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); -} - -static INLINE void insert_3ub_3f_rgb_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[2] = 0; -} - -static INLINE void insert_3ub_3f_rgb_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - v[1] = 0; - v[2] = 0; -} - -static INLINE void insert_3ub_3f_bgr_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); -} - -static INLINE void insert_3ub_3f_bgr_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[0] = 0; -} - -static INLINE void insert_3ub_3f_bgr_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - v[1] = 0; - v[0] = 0; -} - - -static INLINE void insert_1ub_1f_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); -} - - -const struct draw_vf_format_info draw_vf_format_info[DRAW_EMIT_MAX] = -{ - { "1f", - { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, - sizeof(float), FALSE }, - - { "2f", - { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, - 2 * sizeof(float), FALSE }, - - { "3f", - { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, - 3 * sizeof(float), FALSE }, - - { "4f", - { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, - 4 * sizeof(float), FALSE }, - - { "3f_xyw", - { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err, - insert_3f_xyw_4 }, - 3 * sizeof(float), FALSE }, - - { "1ub_1f", - { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 }, - sizeof(uint8_t), FALSE }, - - { "3ub_3f_rgb", - { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3, - insert_3ub_3f_rgb_3 }, - 3 * sizeof(uint8_t), FALSE }, - - { "3ub_3f_bgr", - { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3, - insert_3ub_3f_bgr_3 }, - 3 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_rgba", - { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3, - insert_4ub_4f_rgba_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_bgra", - { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3, - insert_4ub_4f_bgra_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_argb", - { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3, - insert_4ub_4f_argb_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_abgr", - { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3, - insert_4ub_4f_abgr_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "1f_const", - { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, - sizeof(float), TRUE }, - - { "2f_const", - { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, - 2 * sizeof(float), TRUE }, - - { "3f_const", - { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, - 3 * sizeof(float), TRUE }, - - { "4f_const", - { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, - 4 * sizeof(float), TRUE }, - - { "pad", - { NULL, NULL, NULL, NULL }, - 0, FALSE }, - -}; - - - - -/*********************************************************************** - * Hardwired fastpaths for emitting whole vertices or groups of - * vertices - */ -#define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \ -static void NAME( struct draw_vertex_fetch *vf, \ - unsigned count, \ - uint8_t *v ) \ -{ \ - struct draw_vf_attr *a = vf->attr; \ - unsigned i; \ - \ - for (i = 0 ; i < count ; i++, v += vf->vertex_stride) { \ - if (NR > 0) { \ - F0( &a[0], v + a[0].vertoffset, (float *)a[0].inputptr ); \ - a[0].inputptr += a[0].inputstride; \ - } \ - \ - if (NR > 1) { \ - F1( &a[1], v + a[1].vertoffset, (float *)a[1].inputptr ); \ - a[1].inputptr += a[1].inputstride; \ - } \ - \ - if (NR > 2) { \ - F2( &a[2], v + a[2].vertoffset, (float *)a[2].inputptr ); \ - a[2].inputptr += a[2].inputstride; \ - } \ - \ - if (NR > 3) { \ - F3( &a[3], v + a[3].vertoffset, (float *)a[3].inputptr ); \ - a[3].inputptr += a[3].inputstride; \ - } \ - \ - if (NR > 4) { \ - F4( &a[4], v + a[4].vertoffset, (float *)a[4].inputptr ); \ - a[4].inputptr += a[4].inputstride; \ - } \ - } \ -} - - -#define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \ - insert_null, insert_null, NAME) - -#define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \ - insert_null, NAME) - -#define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \ - insert_null, NAME) - - -EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4) - -EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2) - -EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2) - - -/* Use the codegen paths to select one of a number of hardwired - * fastpaths. - */ -void draw_vf_generate_hardwired_emit( struct draw_vertex_fetch *vf ) -{ - draw_vf_emit_func func = NULL; - - /* Does it fit a hardwired fastpath? Help! this is growing out of - * control! - */ - switch (vf->attr_count) { - case 2: - if (vf->attr[0].do_insert == insert_3f_3 && - vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { - func = emit_xyz3_rgba4; - } - break; - case 3: - if (vf->attr[2].do_insert == insert_2f_2) { - if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { - if (vf->attr[0].do_insert == insert_4f_4) - func = emit_xyzw4_rgba4_st2; - } - } - break; - case 4: - if (vf->attr[2].do_insert == insert_2f_2 && - vf->attr[3].do_insert == insert_2f_2) { - if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { - if (vf->attr[0].do_insert == insert_4f_4) - func = emit_xyzw4_rgba4_st2_st2; - } - } - break; - } - - vf->emit = func; -} - -/*********************************************************************** - * Generic (non-codegen) functions for whole vertices or groups of - * vertices - */ - -void draw_vf_generic_emit( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *v ) -{ - struct draw_vf_attr *a = vf->attr; - const unsigned attr_count = vf->attr_count; - const unsigned stride = vf->vertex_stride; - unsigned i, j; - - for (i = 0 ; i < count ; i++, v += stride) { - for (j = 0; j < attr_count; j++) { - float *in = (float *)a[j].inputptr; - a[j].inputptr += a[j].inputstride; - a[j].do_insert( &a[j], v + a[j].vertoffset, in ); - } - } -} - - diff --git a/src/gallium/aux/draw/draw_vf_sse.c b/src/gallium/aux/draw/draw_vf_sse.c deleted file mode 100644 index 1ad2ae756d..0000000000 --- a/src/gallium/aux/draw/draw_vf_sse.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright 2003 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - */ - - -#include "simple_list.h" - -#include "pipe/p_compiler.h" - -#include "draw_vf.h" - - -#if defined(USE_SSE_ASM) - -#include "x86/rtasm/x86sse.h" -#include "x86/common_x86_asm.h" - - -#define X 0 -#define Y 1 -#define Z 2 -#define W 3 - - -struct x86_program { - struct x86_function func; - - struct draw_vertex_fetch *vf; - boolean inputs_safe; - boolean outputs_safe; - boolean have_sse2; - - struct x86_reg identity; - struct x86_reg chan0; -}; - - -static struct x86_reg get_identity( struct x86_program *p ) -{ - return p->identity; -} - -static void emit_load4f_4( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movups(&p->func, dest, arg0); -} - -static void emit_load4f_3( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Have to jump through some hoops: - * - * c 0 0 0 - * c 0 0 1 - * 0 0 c 1 - * a b c 1 - */ - sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); - sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); - sse_shufps(&p->func, dest, dest, SHUF(Y,Z,X,W) ); - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load4f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Initialize from identity, then pull in low two words: - */ - sse_movups(&p->func, dest, get_identity(p)); - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load4f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Pull in low word, then swizzle in identity */ - sse_movss(&p->func, dest, arg0); - sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); -} - - - -static void emit_load3f_3( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Over-reads by 1 dword - potential SEGV if input is a vertex - * array. - */ - if (p->inputs_safe) { - sse_movups(&p->func, dest, arg0); - } - else { - /* c 0 0 0 - * c c c c - * a b c c - */ - sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); - sse_shufps(&p->func, dest, dest, SHUF(X,X,X,X)); - sse_movlps(&p->func, dest, arg0); - } -} - -static void emit_load3f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - emit_load4f_2(p, dest, arg0); -} - -static void emit_load3f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - emit_load4f_1(p, dest, arg0); -} - -static void emit_load2f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load2f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - emit_load4f_1(p, dest, arg0); -} - -static void emit_load1f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movss(&p->func, dest, arg0); -} - -static void (*load[4][4])( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) = { - { emit_load1f_1, - emit_load1f_1, - emit_load1f_1, - emit_load1f_1 }, - - { emit_load2f_1, - emit_load2f_2, - emit_load2f_2, - emit_load2f_2 }, - - { emit_load3f_1, - emit_load3f_2, - emit_load3f_3, - emit_load3f_3 }, - - { emit_load4f_1, - emit_load4f_2, - emit_load4f_3, - emit_load4f_4 } -}; - -static void emit_load( struct x86_program *p, - struct x86_reg dest, - unsigned sz, - struct x86_reg src, - unsigned src_sz) -{ - load[sz-1][src_sz-1](p, dest, src); -} - -static void emit_store4f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movups(&p->func, dest, arg0); -} - -static void emit_store3f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - if (p->outputs_safe) { - /* Emit the extra dword anyway. This may hurt writecombining, - * may cause other problems. - */ - sse_movups(&p->func, dest, arg0); - } - else { - /* Alternate strategy - emit two, shuffle, emit one. - */ - sse_movlps(&p->func, dest, arg0); - sse_shufps(&p->func, arg0, arg0, SHUF(Z,Z,Z,Z) ); /* NOTE! destructive */ - sse_movss(&p->func, x86_make_disp(dest,8), arg0); - } -} - -static void emit_store2f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movlps(&p->func, dest, arg0); -} - -static void emit_store1f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movss(&p->func, dest, arg0); -} - - -static void (*store[4])( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) = -{ - emit_store1f, - emit_store2f, - emit_store3f, - emit_store4f -}; - -static void emit_store( struct x86_program *p, - struct x86_reg dest, - unsigned sz, - struct x86_reg temp ) - -{ - store[sz-1](p, dest, temp); -} - -static void emit_pack_store_4ub( struct x86_program *p, - struct x86_reg dest, - struct x86_reg temp ) -{ - /* Scale by 255.0 - */ - sse_mulps(&p->func, temp, p->chan0); - - if (p->have_sse2) { - sse2_cvtps2dq(&p->func, temp, temp); - sse2_packssdw(&p->func, temp, temp); - sse2_packuswb(&p->func, temp, temp); - sse_movss(&p->func, dest, temp); - } - else { - struct x86_reg mmx0 = x86_make_reg(file_MMX, 0); - struct x86_reg mmx1 = x86_make_reg(file_MMX, 1); - sse_cvtps2pi(&p->func, mmx0, temp); - sse_movhlps(&p->func, temp, temp); - sse_cvtps2pi(&p->func, mmx1, temp); - mmx_packssdw(&p->func, mmx0, mmx1); - mmx_packuswb(&p->func, mmx0, mmx0); - mmx_movd(&p->func, dest, mmx0); - } -} - -static int get_offset( const void *a, const void *b ) -{ - return (const char *)b - (const char *)a; -} - -/* Not much happens here. Eventually use this function to try and - * avoid saving/reloading the source pointers each vertex (if some of - * them can fit in registers). - */ -static void get_src_ptr( struct x86_program *p, - struct x86_reg srcREG, - struct x86_reg vfREG, - struct draw_vf_attr *a ) -{ - struct draw_vertex_fetch *vf = p->vf; - struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr)); - - /* Load current a[j].inputptr - */ - x86_mov(&p->func, srcREG, ptr_to_src); -} - -static void update_src_ptr( struct x86_program *p, - struct x86_reg srcREG, - struct x86_reg vfREG, - struct draw_vf_attr *a ) -{ - if (a->inputstride) { - struct draw_vertex_fetch *vf = p->vf; - struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr)); - - /* add a[j].inputstride (hardcoded value - could just as easily - * pull the stride value from memory each time). - */ - x86_lea(&p->func, srcREG, x86_make_disp(srcREG, a->inputstride)); - - /* save new value of a[j].inputptr - */ - x86_mov(&p->func, ptr_to_src, srcREG); - } -} - - -/* Lots of hardcoding - * - * EAX -- pointer to current output vertex - * ECX -- pointer to current attribute - * - */ -static boolean build_vertex_emit( struct x86_program *p ) -{ - struct draw_vertex_fetch *vf = p->vf; - unsigned j = 0; - - struct x86_reg vertexEAX = x86_make_reg(file_REG32, reg_AX); - struct x86_reg srcECX = x86_make_reg(file_REG32, reg_CX); - struct x86_reg countEBP = x86_make_reg(file_REG32, reg_BP); - struct x86_reg vfESI = x86_make_reg(file_REG32, reg_SI); - struct x86_reg temp = x86_make_reg(file_XMM, 0); - uint8_t *fixup, *label; - - /* Push a few regs? - */ - x86_push(&p->func, countEBP); - x86_push(&p->func, vfESI); - - - /* Get vertex count, compare to zero - */ - x86_xor(&p->func, srcECX, srcECX); - x86_mov(&p->func, countEBP, x86_fn_arg(&p->func, 2)); - x86_cmp(&p->func, countEBP, srcECX); - fixup = x86_jcc_forward(&p->func, cc_E); - - /* Initialize destination register. - */ - x86_mov(&p->func, vertexEAX, x86_fn_arg(&p->func, 3)); - - /* Move argument 1 (vf) into a reg: - */ - x86_mov(&p->func, vfESI, x86_fn_arg(&p->func, 1)); - - - /* always load, needed or not: - */ - sse_movups(&p->func, p->identity, x86_make_disp(vfESI, get_offset(vf, &vf->identity[0]))); - - /* Note address for loop jump */ - label = x86_get_label(&p->func); - - /* Emit code for each of the attributes. Currently routes - * everything through SSE registers, even when it might be more - * efficient to stick with regular old x86. No optimization or - * other tricks - enough new ground to cover here just getting - * things working. - */ - while (j < vf->attr_count) { - struct draw_vf_attr *a = &vf->attr[j]; - struct x86_reg dest = x86_make_disp(vertexEAX, a->vertoffset); - - /* Now, load an XMM reg from src, perhaps transform, then save. - * Could be shortcircuited in specific cases: - */ - switch (a->format) { - case DRAW_EMIT_1F: - case DRAW_EMIT_1F_CONST: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 1, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_2F: - case DRAW_EMIT_2F_CONST: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 2, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_3F: - case DRAW_EMIT_3F_CONST: - /* Potentially the worst case - hardcode 2+1 copying: - */ - if (0) { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 3, temp); - update_src_ptr(p, srcECX, vfESI, a); - } - else { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 2, temp); - if (a->inputsize > 2) { - emit_load(p, temp, 1, x86_make_disp(srcECX, 8), 1); - emit_store(p, x86_make_disp(dest,8), 1, temp); - } - else { - sse_movss(&p->func, x86_make_disp(dest,8), get_identity(p)); - } - update_src_ptr(p, srcECX, vfESI, a); - } - break; - case DRAW_EMIT_4F: - case DRAW_EMIT_4F_CONST: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 4, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_3F_XYW: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(X,Y,W,Z)); - emit_store(p, dest, 3, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - - case DRAW_EMIT_1UB_1F: - /* Test for PAD3 + 1UB: - */ - if (j > 0 && - a[-1].vertoffset + a[-1].vertattrsize <= a->vertoffset - 3) - { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(X,X,X,X)); - emit_pack_store_4ub(p, x86_make_disp(dest, -3), temp); /* overkill! */ - update_src_ptr(p, srcECX, vfESI, a); - } - else { - debug_printf("Can't emit 1ub %x %x %d\n", - a->vertoffset, a[-1].vertoffset, a[-1].vertattrsize ); - return FALSE; - } - break; - case DRAW_EMIT_3UB_3F_RGB: - case DRAW_EMIT_3UB_3F_BGR: - /* Test for 3UB + PAD1: - */ - if (j == vf->attr_count - 1 || - a[1].vertoffset >= a->vertoffset + 4) { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - if (a->format == DRAW_EMIT_3UB_3F_BGR) - sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - } - /* Test for 3UB + 1UB: - */ - else if (j < vf->attr_count - 1 && - a[1].format == DRAW_EMIT_1UB_1F && - a[1].vertoffset == a->vertoffset + 3) { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - update_src_ptr(p, srcECX, vfESI, a); - - /* Make room for incoming value: - */ - sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); - - get_src_ptr(p, srcECX, vfESI, &a[1]); - emit_load(p, temp, 1, x86_deref(srcECX), a[1].inputsize); - update_src_ptr(p, srcECX, vfESI, &a[1]); - - /* Rearrange and possibly do BGR conversion: - */ - if (a->format == DRAW_EMIT_3UB_3F_BGR) - sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); - else - sse_shufps(&p->func, temp, temp, SHUF(Y,Z,W,X)); - - emit_pack_store_4ub(p, dest, temp); - j++; /* NOTE: two attrs consumed */ - } - else { - debug_printf("Can't emit 3ub\n"); - } - return FALSE; /* add this later */ - break; - - case DRAW_EMIT_4UB_4F_RGBA: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_4UB_4F_BGRA: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_4UB_4F_ARGB: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_4UB_4F_ABGR: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - default: - debug_printf("unknown a[%d].format %d\n", j, a->format); - return FALSE; /* catch any new opcodes */ - } - - /* Increment j by at least 1 - may have been incremented above also: - */ - j++; - } - - /* Next vertex: - */ - x86_lea(&p->func, vertexEAX, x86_make_disp(vertexEAX, vf->vertex_stride)); - - /* decr count, loop if not zero - */ - x86_dec(&p->func, countEBP); - x86_test(&p->func, countEBP, countEBP); - x86_jcc(&p->func, cc_NZ, label); - - /* Exit mmx state? - */ - if (p->func.need_emms) - mmx_emms(&p->func); - - /* Land forward jump here: - */ - x86_fixup_fwd_jump(&p->func, fixup); - - /* Pop regs and return - */ - x86_pop(&p->func, x86_get_base_reg(vfESI)); - x86_pop(&p->func, countEBP); - x86_ret(&p->func); - - vf->emit = (draw_vf_emit_func)x86_get_func(&p->func); - return TRUE; -} - - - -void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) -{ - struct x86_program p; - - if (!cpu_has_xmm) { - vf->codegen_emit = NULL; - return; - } - - memset(&p, 0, sizeof(p)); - - p.vf = vf; - p.inputs_safe = 0; /* for now */ - p.outputs_safe = 1; /* for now */ - p.have_sse2 = cpu_has_xmm2; - p.identity = x86_make_reg(file_XMM, 6); - p.chan0 = x86_make_reg(file_XMM, 7); - - x86_init_func(&p.func); - - if (build_vertex_emit(&p)) { - draw_vf_register_fastpath( vf, TRUE ); - } - else { - /* Note the failure so that we don't keep trying to codegen an - * impossible state: - */ - draw_vf_register_fastpath( vf, FALSE ); - x86_release_func(&p.func); - } -} - -#else - -void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) -{ - /* Dummy version for when USE_SSE_ASM not defined */ -} - -#endif diff --git a/src/gallium/aux/draw/draw_wide_prims.c b/src/gallium/aux/draw/draw_wide_prims.c deleted file mode 100644 index 655774b155..0000000000 --- a/src/gallium/aux/draw/draw_wide_prims.c +++ /dev/null @@ -1,432 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -struct wide_stage { - struct draw_stage stage; - - float half_line_width; - float half_point_size; - - uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; - uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; - uint num_texcoords; - - int psize_slot; -}; - - - -static INLINE struct wide_stage *wide_stage( struct draw_stage *stage ) -{ - return (struct wide_stage *)stage; -} - - -static void passthrough_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - -static void passthrough_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line(stage->next, header); -} - -static void passthrough_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Draw a wide line by drawing a quad (two triangles). - * XXX need to disable polygon stipple. - */ -static void wide_line( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct wide_stage *wide = wide_stage(stage); - const float half_width = wide->half_line_width; - - struct prim_header tri; - - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - const float dx = FABSF(pos0[0] - pos2[0]); - const float dy = FABSF(pos0[1] - pos2[1]); - - /* - * Draw wide line as a quad (two tris) by "stretching" the line along - * X or Y. - * We need to tweak coords in several ways to be conformant here. - */ - - if (dx > dy) { - /* x-major line */ - pos0[1] = pos0[1] - half_width - 0.25f; - pos1[1] = pos1[1] + half_width - 0.25f; - pos2[1] = pos2[1] - half_width - 0.25f; - pos3[1] = pos3[1] + half_width - 0.25f; - if (pos0[0] < pos2[0]) { - /* left to right line */ - pos0[0] -= 0.5f; - pos1[0] -= 0.5f; - pos2[0] -= 0.5f; - pos3[0] -= 0.5f; - } - else { - /* right to left line */ - pos0[0] += 0.5f; - pos1[0] += 0.5f; - pos2[0] += 0.5f; - pos3[0] += 0.5f; - } - } - else { - /* y-major line */ - pos0[0] = pos0[0] - half_width + 0.25f; - pos1[0] = pos1[0] + half_width + 0.25f; - pos2[0] = pos2[0] - half_width + 0.25f; - pos3[0] = pos3[0] + half_width + 0.25f; - if (pos0[1] < pos2[1]) { - /* top to bottom line */ - pos0[1] -= 0.5f; - pos1[1] -= 0.5f; - pos2[1] -= 0.5f; - pos3[1] -= 0.5f; - } - else { - /* bottom to top line */ - pos0[1] += 0.5f; - pos1[1] += 0.5f; - pos2[1] += 0.5f; - pos3[1] += 0.5f; - } - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -/** - * Draw a wide line by drawing a quad, using geometry which will - * fullfill GL's antialiased line requirements. - */ -static void wide_line_aa(struct draw_stage *stage, - struct prim_header *header) -{ - const struct wide_stage *wide = wide_stage(stage); - const float half_width = wide->half_line_width; - struct prim_header tri; - struct vertex_header *v[4]; - float *pos; - float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; - float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; - const float len = (float) sqrt(dx * dx + dy * dy); - uint i; - - dx = dx * half_width / len; - dy = dy * half_width / len; - - /* allocate/dup new verts */ - for (i = 0; i < 4; i++) { - v[i] = dup_vert(stage, header->v[i/2], i); - } - - /* - * Quad for line from v0 to v1: - * - * 1 3 - * +-------------------------+ - * | | - * *v0 v1* - * | | - * +-------------------------+ - * 0 2 - */ - - pos = v[0]->data[0]; - pos[0] += dy; - pos[1] -= dx; - - pos = v[1]->data[0]; - pos[0] -= dy; - pos[1] += dx; - - pos = v[2]->data[0]; - pos[0] += dy; - pos[1] -= dx; - - pos = v[3]->data[0]; - pos[0] -= dy; - pos[1] += dx; - - tri.det = header->det; /* only the sign matters */ - - tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2]; - stage->next->tri( stage->next, &tri ); - -} - - -/** - * Set the vertex texcoords for sprite mode. - * Coords may be left untouched or set to a right-side-up or upside-down - * orientation. - */ -static void set_texcoords(const struct wide_stage *wide, - struct vertex_header *v, const float tc[4]) -{ - uint i; - for (i = 0; i < wide->num_texcoords; i++) { - if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { - uint j = wide->texcoord_slot[i]; - v->data[j][0] = tc[0]; - if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) - v->data[j][1] = 1.0f - tc[1]; - else - v->data[j][1] = tc[1]; - v->data[j][2] = tc[2]; - v->data[j][3] = tc[3]; - } - } -} - - -/* If there are lots of sprite points (and why wouldn't there be?) it - * would probably be more sensible to change hardware setup to - * optimize this rather than doing the whole thing in software like - * this. - */ -static void wide_point( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct wide_stage *wide = wide_stage(stage); - const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; - float half_size; - float left_adj, right_adj; - - struct prim_header tri; - - /* four dups of original vertex */ - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - /* point size is either per-vertex or fixed size */ - if (wide->psize_slot >= 0) { - half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; - } - else { - half_size = wide->half_point_size; - } - - left_adj = -half_size + 0.25f; - right_adj = half_size + 0.25f; - - pos0[0] += left_adj; - pos0[1] -= half_size; - - pos1[0] += left_adj; - pos1[1] += half_size; - - pos2[0] += right_adj; - pos2[1] -= half_size; - - pos3[0] += right_adj; - pos3[1] += half_size; - - if (sprite) { - static const float tex00[4] = { 0, 0, 0, 1 }; - static const float tex01[4] = { 0, 1, 0, 1 }; - static const float tex11[4] = { 1, 1, 0, 1 }; - static const float tex10[4] = { 1, 0, 0, 1 }; - set_texcoords( wide, v0, tex00 ); - set_texcoords( wide, v1, tex01 ); - set_texcoords( wide, v2, tex10 ); - set_texcoords( wide, v3, tex11 ); - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -static void wide_first_point( struct draw_stage *stage, - struct prim_header *header ) -{ - struct wide_stage *wide = wide_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_point_size = 0.5f * draw->rasterizer->point_size; - - if (draw->rasterizer->point_size != 1.0) { - stage->point = wide_point; - } - else { - stage->point = passthrough_point; - } - - if (draw->rasterizer->point_sprite) { - /* find vertex shader texcoord outputs */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i, j = 0; - for (i = 0; i < vs->state->num_outputs; i++) { - if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { - wide->texcoord_slot[j] = i; - wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; - j++; - } - } - wide->num_texcoords = j; - } - - wide->psize_slot = -1; - - if (draw->rasterizer->point_size_per_vertex) { - /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i; - for (i = 0; i < vs->state->num_outputs; i++) { - if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { - wide->psize_slot = i; - break; - } - } - } - - stage->point( stage, header ); -} - - - -static void wide_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - struct wide_stage *wide = wide_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_line_width = 0.5f * draw->rasterizer->line_width; - - if (draw->rasterizer->line_width != 1.0) { - if (draw->rasterizer->line_smooth) - wide->stage.line = wide_line_aa; - else - wide->stage.line = wide_line; - } - else { - wide->stage.line = passthrough_line; - } - - stage->line( stage, header ); -} - - -static void wide_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->line = wide_first_line; - stage->point = wide_first_point; - stage->next->flush( stage->next, flags ); -} - - -static void wide_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void wide_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -struct draw_stage *draw_wide_stage( struct draw_context *draw ) -{ - struct wide_stage *wide = CALLOC_STRUCT(wide_stage); - - draw_alloc_temp_verts( &wide->stage, 4 ); - - wide->stage.draw = draw; - wide->stage.next = NULL; - wide->stage.point = wide_first_point; - wide->stage.line = wide_first_line; - wide->stage.tri = passthrough_tri; - wide->stage.flush = wide_flush; - wide->stage.reset_stipple_counter = wide_reset_stipple_counter; - wide->stage.destroy = wide_destroy; - - return &wide->stage; -} diff --git a/src/gallium/aux/llvm/Makefile b/src/gallium/aux/llvm/Makefile deleted file mode 100644 index e6ac399d08..0000000000 --- a/src/gallium/aux/llvm/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -# -*-makefile-*- -TOP = ../../../.. -include $(TOP)/configs/current - -LIBNAME = gallivm - - -GALLIVM_SOURCES = \ - gallivm.cpp \ - gallivm_cpu.cpp \ - instructions.cpp \ - loweringpass.cpp \ - tgsitollvm.cpp \ - storage.cpp \ - storagesoa.cpp \ - instructionssoa.cpp - -INC_SOURCES = gallivm_builtins.cpp - -CPP_SOURCES = \ - $(GALLIVM_SOURCES) - -C_SOURCES = -ASM_SOURCES = - -OBJECTS = $(C_SOURCES:.c=.o) \ - $(CPP_SOURCES:.cpp=.o) \ - $(ASM_SOURCES:.S=.o) - -### Include directories -INCLUDES = \ - -I. \ - -I$(TOP)/src/gallium/drivers - -I$(TOP)/src/gallium/aux \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/mesa \ - -I$(TOP)/include - - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(LLVM_CFLAGS) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.cpp.o: - $(CXX) -c $(INCLUDES) $(LLVM_CXXFLAGS) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -##### TARGETS ##### - -default:: depend symlinks $(LIBNAME) - - -$(LIBNAME): $(OBJECTS) Makefile - $(TOP)/bin/mklib -o $@ -static $(OBJECTS) - - -depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ - $(ASM_SOURCES) $(INC_SOURCES) 2> /dev/null - - -gallivm_builtins.cpp: llvm_builtins.c - clang --emit-llvm $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` `find ../include` - - -# Remove .o and backup files -clean: - -rm -f *.o */*.o *~ *.so *~ server/*.o - -rm -f depend depend.bak - -rm -f gallivm_builtins.cpp - -symlinks: - - -include depend diff --git a/src/gallium/aux/llvm/gallivm.cpp b/src/gallium/aux/llvm/gallivm.cpp deleted file mode 100644 index d14bb3b99a..0000000000 --- a/src/gallium/aux/llvm/gallivm.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "instructions.h" -#include "loweringpass.h" -#include "storage.h" -#include "tgsitollvm.h" - -#include "pipe/p_context.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_dump.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static int GLOBAL_ID = 0; - -using namespace llvm; - -static inline -void AddStandardCompilePasses(PassManager &PM) -{ - PM.add(new LoweringPass()); - PM.add(createVerifierPass()); // Verify that input is correct - - PM.add(createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp - - //PM.add(createStripSymbolsPass(true)); - - PM.add(createRaiseAllocationsPass()); // call %malloc -> malloc inst - PM.add(createCFGSimplificationPass()); // Clean up disgusting code - PM.add(createPromoteMemoryToRegisterPass());// Kill useless allocas - PM.add(createGlobalOptimizerPass()); // Optimize out global vars - PM.add(createGlobalDCEPass()); // Remove unused fns and globs - PM.add(createIPConstantPropagationPass());// IP Constant Propagation - PM.add(createDeadArgEliminationPass()); // Dead argument elimination - PM.add(createInstructionCombiningPass()); // Clean up after IPCP & DAE - PM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE - - PM.add(createPruneEHPass()); // Remove dead EH info - - PM.add(createFunctionInliningPass()); // Inline small functions - PM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args - - PM.add(createTailDuplicationPass()); // Simplify cfg by copying code - PM.add(createInstructionCombiningPass()); // Cleanup for scalarrepl. - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createScalarReplAggregatesPass()); // Break up aggregate allocas - PM.add(createInstructionCombiningPass()); // Combine silly seq's - PM.add(createCondPropagationPass()); // Propagate conditionals - - PM.add(createTailCallEliminationPass()); // Eliminate tail calls - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createReassociatePass()); // Reassociate expressions - PM.add(createLoopRotatePass()); - PM.add(createLICMPass()); // Hoist loop invariants - PM.add(createLoopUnswitchPass()); // Unswitch loops. - PM.add(createLoopIndexSplitPass()); // Index split loops. - PM.add(createInstructionCombiningPass()); // Clean up after LICM/reassoc - PM.add(createIndVarSimplifyPass()); // Canonicalize indvars - PM.add(createLoopUnrollPass()); // Unroll small loops - PM.add(createInstructionCombiningPass()); // Clean up after the unroller - PM.add(createGVNPass()); // Remove redundancies - PM.add(createSCCPPass()); // Constant prop with SCCP - - // Run instcombine after redundancy elimination to exploit opportunities - // opened up by them. - PM.add(createInstructionCombiningPass()); - PM.add(createCondPropagationPass()); // Propagate conditionals - - PM.add(createDeadStoreEliminationPass()); // Delete dead stores - PM.add(createAggressiveDCEPass()); // SSA based 'Aggressive DCE' - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createSimplifyLibCallsPass()); // Library Call Optimizations - PM.add(createDeadTypeEliminationPass()); // Eliminate dead types - PM.add(createConstantMergePass()); // Merge dup global constants -} - -void gallivm_prog_delete(struct gallivm_prog *prog) -{ - delete prog->module; - prog->module = 0; - prog->function = 0; - free(prog); -} - -static inline void -constant_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan) -{ - unsigned i; - - for (i = 0; i < QUAD_SIZE; ++i) { - inputs[i][attrib][chan] = coefs[attrib].a0[chan]; - } -} - -static inline void -linear_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan) -{ - unsigned i; - - for( i = 0; i < QUAD_SIZE; i++ ) { - const float x = inputs[i][0][0]; - const float y = inputs[i][0][1]; - - inputs[i][attrib][chan] = - coefs[attrib].a0[chan] + - coefs[attrib].dadx[chan] * x + - coefs[attrib].dady[chan] * y; - } -} - -static inline void -perspective_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan ) -{ - unsigned i; - - for( i = 0; i < QUAD_SIZE; i++ ) { - const float x = inputs[i][0][0]; - const float y = inputs[i][0][1]; - /* WPOS.w here is really 1/w */ - const float w = 1.0f / inputs[i][0][3]; - assert(inputs[i][0][3] != 0.0); - - inputs[i][attrib][chan] = - (coefs[attrib].a0[chan] + - coefs[attrib].dadx[chan] * x + - coefs[attrib].dady[chan] * y) * w; - } -} - -void gallivm_ir_dump(struct gallivm_ir *ir, const char *file_prefix) -{ - if (!ir || !ir->module) - return; - - if (file_prefix) { - std::ostringstream stream; - stream << file_prefix; - stream << ir->id; - stream << ".ll"; - std::string name = stream.str(); - std::ofstream out(name.c_str()); - if (!out) { - std::cerr<<"Can't open file : "<module); - out.close(); - } else { - const llvm::Module::FunctionListType &funcs = ir->module->getFunctionList(); - llvm::Module::FunctionListType::const_iterator itr; - std::cout<<"; ---------- Start shader "<id<id<num_interp; ++i) { - const gallivm_interpolate &interp = prog->interpolators[i]; - switch (interp.type) { - case TGSI_INTERPOLATE_CONSTANT: - constant_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - case TGSI_INTERPOLATE_LINEAR: - linear_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - case TGSI_INTERPOLATE_PERSPECTIVE: - perspective_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - default: - assert( 0 ); - } - } -} - - -struct gallivm_ir * gallivm_ir_new(enum gallivm_shader_type type) -{ - struct gallivm_ir *ir = - (struct gallivm_ir *)calloc(1, sizeof(struct gallivm_ir)); - ++GLOBAL_ID; - ir->id = GLOBAL_ID; - ir->type = type; - - return ir; -} - -void gallivm_ir_set_layout(struct gallivm_ir *ir, - enum gallivm_vector_layout layout) -{ - ir->layout = layout; -} - -void gallivm_ir_set_components(struct gallivm_ir *ir, int num) -{ - ir->num_components = num; -} - -void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, - const struct tgsi_token *tokens) -{ - std::cout << "Creating llvm from: " <module = mod; - gallivm_ir_dump(ir, 0); -} - -void gallivm_ir_delete(struct gallivm_ir *ir) -{ - delete ir->module; - free(ir); -} - -struct gallivm_prog * gallivm_ir_compile(struct gallivm_ir *ir) -{ - struct gallivm_prog *prog = - (struct gallivm_prog *)calloc(1, sizeof(struct gallivm_prog)); - llvm::Module *mod = llvm::CloneModule(ir->module); - prog->num_consts = ir->num_consts; - memcpy(prog->interpolators, ir->interpolators, sizeof(prog->interpolators)); - prog->num_interp = ir->num_interp; - - /* Run optimization passes over it */ - PassManager passes; - passes.add(new TargetData(mod)); - AddStandardCompilePasses(passes); - passes.run(*mod); - prog->module = mod; - - std::cout << "After optimizations:"<dump(); - - return prog; -} - -#endif /* MESA_LLVM */ diff --git a/src/gallium/aux/llvm/gallivm.h b/src/gallium/aux/llvm/gallivm.h deleted file mode 100644 index 92da4bca7f..0000000000 --- a/src/gallium/aux/llvm/gallivm.h +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef GALLIVM_H -#define GALLIVM_H - -#if defined __cplusplus -extern "C" { -#endif - -#include "pipe/p_state.h" - -#ifdef MESA_LLVM - -struct tgsi_token; - -struct gallivm_ir; -struct gallivm_prog; -struct gallivm_cpu_engine; -struct tgsi_interp_coef; -struct tgsi_sampler; -struct tgsi_exec_vector; - -enum gallivm_shader_type { - GALLIVM_VS, - GALLIVM_FS -}; - -enum gallivm_vector_layout { - GALLIVM_AOS, - GALLIVM_SOA -}; - -struct gallivm_ir *gallivm_ir_new(enum gallivm_shader_type type); -void gallivm_ir_set_layout(struct gallivm_ir *ir, - enum gallivm_vector_layout layout); -void gallivm_ir_set_components(struct gallivm_ir *ir, int num); -void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, - const struct tgsi_token *tokens); -void gallivm_ir_delete(struct gallivm_ir *ir); - - -struct gallivm_prog *gallivm_ir_compile(struct gallivm_ir *ir); - -void gallivm_prog_inputs_interpolate(struct gallivm_prog *prog, - float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], - const struct tgsi_interp_coef *coefs); -void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix); - - -struct gallivm_cpu_engine *gallivm_cpu_engine_create(struct gallivm_prog *prog); -struct gallivm_cpu_engine *gallivm_global_cpu_engine(); -int gallivm_cpu_vs_exec(struct gallivm_prog *prog, - struct tgsi_exec_vector *inputs, - struct tgsi_exec_vector *dests, - float (*consts)[4], - struct tgsi_exec_vector *temps); -int gallivm_cpu_fs_exec(struct gallivm_prog *prog, - float x, float y, - float (*dests)[PIPE_MAX_SHADER_INPUTS][4], - float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], - float (*consts)[4], - struct tgsi_sampler *samplers); -void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *ee, struct gallivm_prog *prog); -void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *ee); - - -#endif /* MESA_LLVM */ - -#if defined __cplusplus -} // extern "C" -#endif - -#endif diff --git a/src/gallium/aux/llvm/gallivm_builtins.cpp b/src/gallium/aux/llvm/gallivm_builtins.cpp deleted file mode 100644 index 1796f0a177..0000000000 --- a/src/gallium/aux/llvm/gallivm_builtins.cpp +++ /dev/null @@ -1,567 +0,0 @@ -// Generated by llvm2cpp - DO NOT MODIFY! - - -Module* createGallivmBuiltins(Module *mod) { - -mod->setModuleIdentifier("shader"); - -// Type Definitions -ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(8), 25); - -PointerType* PointerTy_1 = PointerType::get(ArrayTy_0, 0); - -std::vectorFuncTy_2_args; -FuncTy_2_args.push_back(Type::FloatTy); -FuncTy_2_args.push_back(Type::FloatTy); -FunctionType* FuncTy_2 = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/FuncTy_2_args, - /*isVarArg=*/false); - -PointerType* PointerTy_3 = PointerType::get(FuncTy_2, 0); - -VectorType* VectorTy_4 = VectorType::get(Type::FloatTy, 4); - -std::vectorFuncTy_5_args; -FuncTy_5_args.push_back(VectorTy_4); -FunctionType* FuncTy_5 = FunctionType::get( - /*Result=*/VectorTy_4, - /*Params=*/FuncTy_5_args, - /*isVarArg=*/false); - -std::vectorFuncTy_6_args; -FuncTy_6_args.push_back(VectorTy_4); -FuncTy_6_args.push_back(VectorTy_4); -FuncTy_6_args.push_back(VectorTy_4); -FunctionType* FuncTy_6 = FunctionType::get( - /*Result=*/VectorTy_4, - /*Params=*/FuncTy_6_args, - /*isVarArg=*/false); - -VectorType* VectorTy_7 = VectorType::get(IntegerType::get(32), 4); - -std::vectorFuncTy_9_args; -FunctionType* FuncTy_9 = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/FuncTy_9_args, - /*isVarArg=*/true); - -PointerType* PointerTy_8 = PointerType::get(FuncTy_9, 0); - -PointerType* PointerTy_10 = PointerType::get(IntegerType::get(8), 0); - -std::vectorFuncTy_12_args; -FuncTy_12_args.push_back(Type::FloatTy); -FunctionType* FuncTy_12 = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/FuncTy_12_args, - /*isVarArg=*/false); - -PointerType* PointerTy_11 = PointerType::get(FuncTy_12, 0); - -std::vectorFuncTy_13_args; -FuncTy_13_args.push_back(VectorTy_4); -FunctionType* FuncTy_13 = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/FuncTy_13_args, - /*isVarArg=*/false); - - -// Function Declarations - -Function* func_approx = new Function( - /*Type=*/FuncTy_2, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"approx", mod); -func_approx->setCallingConv(CallingConv::C); -const ParamAttrsList *func_approx_PAL = 0; -func_approx->setParamAttrs(func_approx_PAL); - -Function* func_powf = new Function( - /*Type=*/FuncTy_2, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"powf", mod); // (external, no body) -func_powf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_powf_PAL = 0; -func_powf->setParamAttrs(func_powf_PAL); - -Function* func_lit = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"lit", mod); -func_lit->setCallingConv(CallingConv::C); -const ParamAttrsList *func_lit_PAL = 0; -func_lit->setParamAttrs(func_lit_PAL); - -Function* func_cmp = new Function( - /*Type=*/FuncTy_6, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"cmp", mod); -func_cmp->setCallingConv(CallingConv::C); -const ParamAttrsList *func_cmp_PAL = 0; -{ - ParamAttrsVector Attrs; - ParamAttrsWithIndex PAWI; - PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; - Attrs.push_back(PAWI); - func_cmp_PAL = ParamAttrsList::get(Attrs); - -} -func_cmp->setParamAttrs(func_cmp_PAL); - -Function* func_vcos = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"vcos", mod); -func_vcos->setCallingConv(CallingConv::C); -const ParamAttrsList *func_vcos_PAL = 0; -func_vcos->setParamAttrs(func_vcos_PAL); - -Function* func_printf = new Function( - /*Type=*/FuncTy_9, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"printf", mod); // (external, no body) -func_printf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_printf_PAL = 0; -func_printf->setParamAttrs(func_printf_PAL); - -Function* func_cosf = new Function( - /*Type=*/FuncTy_12, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"cosf", mod); // (external, no body) -func_cosf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_cosf_PAL = 0; -func_cosf->setParamAttrs(func_cosf_PAL); - -Function* func_scs = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"scs", mod); -func_scs->setCallingConv(CallingConv::C); -const ParamAttrsList *func_scs_PAL = 0; -func_scs->setParamAttrs(func_scs_PAL); - -Function* func_sinf = new Function( - /*Type=*/FuncTy_12, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"sinf", mod); // (external, no body) -func_sinf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_sinf_PAL = 0; -func_sinf->setParamAttrs(func_sinf_PAL); - -Function* func_vsin = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"vsin", mod); -func_vsin->setCallingConv(CallingConv::C); -const ParamAttrsList *func_vsin_PAL = 0; -func_vsin->setParamAttrs(func_vsin_PAL); - -Function* func_kilp = new Function( - /*Type=*/FuncTy_13, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"kilp", mod); -func_kilp->setCallingConv(CallingConv::C); -const ParamAttrsList *func_kilp_PAL = 0; -{ - ParamAttrsVector Attrs; - ParamAttrsWithIndex PAWI; - PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; - Attrs.push_back(PAWI); - func_kilp_PAL = ParamAttrsList::get(Attrs); - -} -func_kilp->setParamAttrs(func_kilp_PAL); - -// Global Variable Declarations - - -GlobalVariable* gvar_array__str = new GlobalVariable( -/*Type=*/ArrayTy_0, -/*isConstant=*/true, -/*Linkage=*/GlobalValue::InternalLinkage, -/*Initializer=*/0, // has initializer, specified below -/*Name=*/".str", -mod); - -GlobalVariable* gvar_array__str1 = new GlobalVariable( -/*Type=*/ArrayTy_0, -/*isConstant=*/true, -/*Linkage=*/GlobalValue::InternalLinkage, -/*Initializer=*/0, // has initializer, specified below -/*Name=*/".str1", -mod); - -// Constant Definitions -Constant* const_array_14 = ConstantArray::get("VEC IN is %f %f %f %f\x0A", true); -Constant* const_array_15 = ConstantArray::get("VEC OUT is %f %f %f %f\x0A", true); -ConstantFP* const_float_16 = ConstantFP::get(Type::FloatTy, APFloat(-1.280000e+02f)); -ConstantFP* const_float_17 = ConstantFP::get(Type::FloatTy, APFloat(1.280000e+02f)); -Constant* const_float_18 = Constant::getNullValue(Type::FloatTy); -Constant* const_int32_19 = Constant::getNullValue(IntegerType::get(32)); -std::vector const_packed_20_elems; -ConstantFP* const_float_21 = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); -const_packed_20_elems.push_back(const_float_21); -UndefValue* const_float_22 = UndefValue::get(Type::FloatTy); -const_packed_20_elems.push_back(const_float_22); -const_packed_20_elems.push_back(const_float_22); -const_packed_20_elems.push_back(const_float_21); -Constant* const_packed_20 = ConstantVector::get(VectorTy_4, const_packed_20_elems); -ConstantInt* const_int32_23 = ConstantInt::get(APInt(32, "1", 10)); -ConstantInt* const_int32_24 = ConstantInt::get(APInt(32, "3", 10)); -ConstantInt* const_int32_25 = ConstantInt::get(APInt(32, "2", 10)); -std::vector const_packed_26_elems; -const_packed_26_elems.push_back(const_float_21); -const_packed_26_elems.push_back(const_float_18); -const_packed_26_elems.push_back(const_float_18); -const_packed_26_elems.push_back(const_float_21); -Constant* const_packed_26 = ConstantVector::get(VectorTy_4, const_packed_26_elems); -Constant* const_double_27 = Constant::getNullValue(Type::DoubleTy); -std::vector const_packed_28_elems; -const_packed_28_elems.push_back(const_int32_19); -ConstantInt* const_int32_29 = ConstantInt::get(APInt(32, "5", 10)); -const_packed_28_elems.push_back(const_int32_29); -const_packed_28_elems.push_back(const_int32_25); -const_packed_28_elems.push_back(const_int32_24); -Constant* const_packed_28 = ConstantVector::get(VectorTy_7, const_packed_28_elems); -std::vector const_packed_30_elems; -const_packed_30_elems.push_back(const_int32_19); -const_packed_30_elems.push_back(const_int32_23); -ConstantInt* const_int32_31 = ConstantInt::get(APInt(32, "6", 10)); -const_packed_30_elems.push_back(const_int32_31); -const_packed_30_elems.push_back(const_int32_24); -Constant* const_packed_30 = ConstantVector::get(VectorTy_7, const_packed_30_elems); -std::vector const_packed_32_elems; -const_packed_32_elems.push_back(const_int32_19); -const_packed_32_elems.push_back(const_int32_23); -const_packed_32_elems.push_back(const_int32_25); -ConstantInt* const_int32_33 = ConstantInt::get(APInt(32, "7", 10)); -const_packed_32_elems.push_back(const_int32_33); -Constant* const_packed_32 = ConstantVector::get(VectorTy_7, const_packed_32_elems); -std::vector const_ptr_34_indices; -const_ptr_34_indices.push_back(const_int32_19); -const_ptr_34_indices.push_back(const_int32_19); -Constant* const_ptr_34 = ConstantExpr::getGetElementPtr(gvar_array__str, &const_ptr_34_indices[0], const_ptr_34_indices.size() ); -UndefValue* const_packed_35 = UndefValue::get(VectorTy_4); -std::vector const_ptr_36_indices; -const_ptr_36_indices.push_back(const_int32_19); -const_ptr_36_indices.push_back(const_int32_19); -Constant* const_ptr_36 = ConstantExpr::getGetElementPtr(gvar_array__str1, &const_ptr_36_indices[0], const_ptr_36_indices.size() ); - -// Global Variable Definitions -gvar_array__str->setInitializer(const_array_14); -gvar_array__str1->setInitializer(const_array_15); - -// Function Definitions - -// Function: approx (func_approx) -{ - Function::arg_iterator args = func_approx->arg_begin(); - Value* float_a = args++; - float_a->setName("a"); - Value* float_b = args++; - float_b->setName("b"); - - BasicBlock* label_entry = new BasicBlock("entry",func_approx,0); - - // Block entry (label_entry) - FCmpInst* int1_cmp = new FCmpInst(FCmpInst::FCMP_OLT, float_b, const_float_16, "cmp", label_entry); - SelectInst* float_b_addr_0 = new SelectInst(int1_cmp, const_float_16, float_b, "b.addr.0", label_entry); - FCmpInst* int1_cmp3 = new FCmpInst(FCmpInst::FCMP_OGT, float_b_addr_0, const_float_17, "cmp3", label_entry); - SelectInst* float_b_addr_1 = new SelectInst(int1_cmp3, const_float_17, float_b_addr_0, "b.addr.1", label_entry); - FCmpInst* int1_cmp7 = new FCmpInst(FCmpInst::FCMP_OLT, float_a, const_float_18, "cmp7", label_entry); - SelectInst* float_a_addr_0 = new SelectInst(int1_cmp7, const_float_18, float_a, "a.addr.0", label_entry); - std::vector float_call_params; - float_call_params.push_back(float_a_addr_0); - float_call_params.push_back(float_b_addr_1); - CallInst* float_call = new CallInst(func_powf, float_call_params.begin(), float_call_params.end(), "call", label_entry); - float_call->setCallingConv(CallingConv::C); - float_call->setTailCall(true);const ParamAttrsList *float_call_PAL = 0; - float_call->setParamAttrs(float_call_PAL); - - new ReturnInst(float_call, label_entry); - -} - -// Function: lit (func_lit) -{ - Function::arg_iterator args = func_lit->arg_begin(); - Value* packed_tmp = args++; - packed_tmp->setName("tmp"); - - BasicBlock* label_entry_38 = new BasicBlock("entry",func_lit,0); - BasicBlock* label_ifthen = new BasicBlock("ifthen",func_lit,0); - BasicBlock* label_UnifiedReturnBlock = new BasicBlock("UnifiedReturnBlock",func_lit,0); - - // Block entry (label_entry_38) - ExtractElementInst* float_tmp6 = new ExtractElementInst(packed_tmp, const_int32_19, "tmp6", label_entry_38); - FCmpInst* int1_cmp_39 = new FCmpInst(FCmpInst::FCMP_OGT, float_tmp6, const_float_18, "cmp", label_entry_38); - new BranchInst(label_ifthen, label_UnifiedReturnBlock, int1_cmp_39, label_entry_38); - - // Block ifthen (label_ifthen) - InsertElementInst* packed_tmp10 = new InsertElementInst(const_packed_20, float_tmp6, const_int32_23, "tmp10", label_ifthen); - ExtractElementInst* float_tmp12 = new ExtractElementInst(packed_tmp, const_int32_23, "tmp12", label_ifthen); - ExtractElementInst* float_tmp14 = new ExtractElementInst(packed_tmp, const_int32_24, "tmp14", label_ifthen); - std::vector float_call_41_params; - float_call_41_params.push_back(float_tmp12); - float_call_41_params.push_back(float_tmp14); - CallInst* float_call_41 = new CallInst(func_approx, float_call_41_params.begin(), float_call_41_params.end(), "call", label_ifthen); - float_call_41->setCallingConv(CallingConv::C); - float_call_41->setTailCall(true);const ParamAttrsList *float_call_41_PAL = 0; - float_call_41->setParamAttrs(float_call_41_PAL); - - InsertElementInst* packed_tmp16 = new InsertElementInst(packed_tmp10, float_call_41, const_int32_25, "tmp16", label_ifthen); - new ReturnInst(packed_tmp16, label_ifthen); - - // Block UnifiedReturnBlock (label_UnifiedReturnBlock) - new ReturnInst(const_packed_26, label_UnifiedReturnBlock); - -} - -// Function: cmp (func_cmp) -{ - Function::arg_iterator args = func_cmp->arg_begin(); - Value* packed_tmp0 = args++; - packed_tmp0->setName("tmp0"); - Value* packed_tmp1 = args++; - packed_tmp1->setName("tmp1"); - Value* packed_tmp2 = args++; - packed_tmp2->setName("tmp2"); - - BasicBlock* label_entry_44 = new BasicBlock("entry",func_cmp,0); - BasicBlock* label_cond__14 = new BasicBlock("cond.?14",func_cmp,0); - BasicBlock* label_cond_cont20 = new BasicBlock("cond.cont20",func_cmp,0); - BasicBlock* label_cond__28 = new BasicBlock("cond.?28",func_cmp,0); - BasicBlock* label_cond_cont34 = new BasicBlock("cond.cont34",func_cmp,0); - BasicBlock* label_cond__42 = new BasicBlock("cond.?42",func_cmp,0); - BasicBlock* label_cond_cont48 = new BasicBlock("cond.cont48",func_cmp,0); - - // Block entry (label_entry_44) - ExtractElementInst* float_tmp3 = new ExtractElementInst(packed_tmp0, const_int32_19, "tmp3", label_entry_44); - CastInst* double_conv = new FPExtInst(float_tmp3, Type::DoubleTy, "conv", label_entry_44); - FCmpInst* int1_cmp_45 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv, const_double_27, "cmp", label_entry_44); - ExtractElementInst* float_tmp11 = new ExtractElementInst(packed_tmp0, const_int32_23, "tmp11", label_entry_44); - CastInst* double_conv12 = new FPExtInst(float_tmp11, Type::DoubleTy, "conv12", label_entry_44); - FCmpInst* int1_cmp13 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv12, const_double_27, "cmp13", label_entry_44); - SelectInst* packed_tmp1_tmp2 = new SelectInst(int1_cmp_45, packed_tmp1, packed_tmp2, "tmp1.tmp2", label_entry_44); - new BranchInst(label_cond__14, label_cond_cont20, int1_cmp13, label_entry_44); - - // Block cond.?14 (label_cond__14) - ShuffleVectorInst* packed_tmp233 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp1, const_packed_28, "tmp233", label_cond__14); - ExtractElementInst* float_tmp254 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp254", label_cond__14); - CastInst* double_conv265 = new FPExtInst(float_tmp254, Type::DoubleTy, "conv265", label_cond__14); - FCmpInst* int1_cmp276 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv265, const_double_27, "cmp276", label_cond__14); - new BranchInst(label_cond__28, label_cond_cont34, int1_cmp276, label_cond__14); - - // Block cond.cont20 (label_cond_cont20) - ShuffleVectorInst* packed_tmp23 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp2, const_packed_28, "tmp23", label_cond_cont20); - ExtractElementInst* float_tmp25 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp25", label_cond_cont20); - CastInst* double_conv26 = new FPExtInst(float_tmp25, Type::DoubleTy, "conv26", label_cond_cont20); - FCmpInst* int1_cmp27 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv26, const_double_27, "cmp27", label_cond_cont20); - new BranchInst(label_cond__28, label_cond_cont34, int1_cmp27, label_cond_cont20); - - // Block cond.?28 (label_cond__28) - PHINode* packed_tmp23_reg2mem_0 = new PHINode(VectorTy_4, "tmp23.reg2mem.0", label_cond__28); - packed_tmp23_reg2mem_0->reserveOperandSpace(2); - packed_tmp23_reg2mem_0->addIncoming(packed_tmp233, label_cond__14); - packed_tmp23_reg2mem_0->addIncoming(packed_tmp23, label_cond_cont20); - - ShuffleVectorInst* packed_tmp378 = new ShuffleVectorInst(packed_tmp23_reg2mem_0, packed_tmp1, const_packed_30, "tmp378", label_cond__28); - ExtractElementInst* float_tmp399 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp399", label_cond__28); - CastInst* double_conv4010 = new FPExtInst(float_tmp399, Type::DoubleTy, "conv4010", label_cond__28); - FCmpInst* int1_cmp4111 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv4010, const_double_27, "cmp4111", label_cond__28); - new BranchInst(label_cond__42, label_cond_cont48, int1_cmp4111, label_cond__28); - - // Block cond.cont34 (label_cond_cont34) - PHINode* packed_tmp23_reg2mem_1 = new PHINode(VectorTy_4, "tmp23.reg2mem.1", label_cond_cont34); - packed_tmp23_reg2mem_1->reserveOperandSpace(2); - packed_tmp23_reg2mem_1->addIncoming(packed_tmp233, label_cond__14); - packed_tmp23_reg2mem_1->addIncoming(packed_tmp23, label_cond_cont20); - - ShuffleVectorInst* packed_tmp37 = new ShuffleVectorInst(packed_tmp23_reg2mem_1, packed_tmp2, const_packed_30, "tmp37", label_cond_cont34); - ExtractElementInst* float_tmp39 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp39", label_cond_cont34); - CastInst* double_conv40 = new FPExtInst(float_tmp39, Type::DoubleTy, "conv40", label_cond_cont34); - FCmpInst* int1_cmp41 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv40, const_double_27, "cmp41", label_cond_cont34); - new BranchInst(label_cond__42, label_cond_cont48, int1_cmp41, label_cond_cont34); - - // Block cond.?42 (label_cond__42) - PHINode* packed_tmp37_reg2mem_0 = new PHINode(VectorTy_4, "tmp37.reg2mem.0", label_cond__42); - packed_tmp37_reg2mem_0->reserveOperandSpace(2); - packed_tmp37_reg2mem_0->addIncoming(packed_tmp378, label_cond__28); - packed_tmp37_reg2mem_0->addIncoming(packed_tmp37, label_cond_cont34); - - ShuffleVectorInst* packed_tmp5113 = new ShuffleVectorInst(packed_tmp37_reg2mem_0, packed_tmp1, const_packed_32, "tmp5113", label_cond__42); - new ReturnInst(packed_tmp5113, label_cond__42); - - // Block cond.cont48 (label_cond_cont48) - PHINode* packed_tmp37_reg2mem_1 = new PHINode(VectorTy_4, "tmp37.reg2mem.1", label_cond_cont48); - packed_tmp37_reg2mem_1->reserveOperandSpace(2); - packed_tmp37_reg2mem_1->addIncoming(packed_tmp378, label_cond__28); - packed_tmp37_reg2mem_1->addIncoming(packed_tmp37, label_cond_cont34); - - ShuffleVectorInst* packed_tmp51 = new ShuffleVectorInst(packed_tmp37_reg2mem_1, packed_tmp2, const_packed_32, "tmp51", label_cond_cont48); - new ReturnInst(packed_tmp51, label_cond_cont48); - -} - -// Function: vcos (func_vcos) -{ - Function::arg_iterator args = func_vcos->arg_begin(); - Value* packed_val = args++; - packed_val->setName("val"); - - BasicBlock* label_entry_53 = new BasicBlock("entry",func_vcos,0); - - // Block entry (label_entry_53) - ExtractElementInst* float_tmp1 = new ExtractElementInst(packed_val, const_int32_19, "tmp1", label_entry_53); - CastInst* double_conv_54 = new FPExtInst(float_tmp1, Type::DoubleTy, "conv", label_entry_53); - ExtractElementInst* float_tmp3_55 = new ExtractElementInst(packed_val, const_int32_23, "tmp3", label_entry_53); - CastInst* double_conv4 = new FPExtInst(float_tmp3_55, Type::DoubleTy, "conv4", label_entry_53); - ExtractElementInst* float_tmp6_56 = new ExtractElementInst(packed_val, const_int32_25, "tmp6", label_entry_53); - CastInst* double_conv7 = new FPExtInst(float_tmp6_56, Type::DoubleTy, "conv7", label_entry_53); - ExtractElementInst* float_tmp9 = new ExtractElementInst(packed_val, const_int32_24, "tmp9", label_entry_53); - CastInst* double_conv10 = new FPExtInst(float_tmp9, Type::DoubleTy, "conv10", label_entry_53); - std::vector int32_call_params; - int32_call_params.push_back(const_ptr_34); - int32_call_params.push_back(double_conv_54); - int32_call_params.push_back(double_conv4); - int32_call_params.push_back(double_conv7); - int32_call_params.push_back(double_conv10); - CallInst* int32_call = new CallInst(func_printf, int32_call_params.begin(), int32_call_params.end(), "call", label_entry_53); - int32_call->setCallingConv(CallingConv::C); - int32_call->setTailCall(true);const ParamAttrsList *int32_call_PAL = 0; - int32_call->setParamAttrs(int32_call_PAL); - - CallInst* float_call13 = new CallInst(func_cosf, float_tmp1, "call13", label_entry_53); - float_call13->setCallingConv(CallingConv::C); - float_call13->setTailCall(true);const ParamAttrsList *float_call13_PAL = 0; - float_call13->setParamAttrs(float_call13_PAL); - - InsertElementInst* packed_tmp15 = new InsertElementInst(const_packed_35, float_call13, const_int32_19, "tmp15", label_entry_53); - CallInst* float_call18 = new CallInst(func_cosf, float_tmp1, "call18", label_entry_53); - float_call18->setCallingConv(CallingConv::C); - float_call18->setTailCall(true);const ParamAttrsList *float_call18_PAL = 0; - float_call18->setParamAttrs(float_call18_PAL); - - InsertElementInst* packed_tmp20 = new InsertElementInst(packed_tmp15, float_call18, const_int32_23, "tmp20", label_entry_53); - CallInst* float_call23 = new CallInst(func_cosf, float_tmp1, "call23", label_entry_53); - float_call23->setCallingConv(CallingConv::C); - float_call23->setTailCall(true);const ParamAttrsList *float_call23_PAL = 0; - float_call23->setParamAttrs(float_call23_PAL); - - InsertElementInst* packed_tmp25 = new InsertElementInst(packed_tmp20, float_call23, const_int32_25, "tmp25", label_entry_53); - CallInst* float_call28 = new CallInst(func_cosf, float_tmp1, "call28", label_entry_53); - float_call28->setCallingConv(CallingConv::C); - float_call28->setTailCall(true);const ParamAttrsList *float_call28_PAL = 0; - float_call28->setParamAttrs(float_call28_PAL); - - InsertElementInst* packed_tmp30 = new InsertElementInst(packed_tmp25, float_call28, const_int32_24, "tmp30", label_entry_53); - CastInst* double_conv33 = new FPExtInst(float_call13, Type::DoubleTy, "conv33", label_entry_53); - CastInst* double_conv36 = new FPExtInst(float_call18, Type::DoubleTy, "conv36", label_entry_53); - CastInst* double_conv39 = new FPExtInst(float_call23, Type::DoubleTy, "conv39", label_entry_53); - CastInst* double_conv42 = new FPExtInst(float_call28, Type::DoubleTy, "conv42", label_entry_53); - std::vector int32_call43_params; - int32_call43_params.push_back(const_ptr_36); - int32_call43_params.push_back(double_conv33); - int32_call43_params.push_back(double_conv36); - int32_call43_params.push_back(double_conv39); - int32_call43_params.push_back(double_conv42); - CallInst* int32_call43 = new CallInst(func_printf, int32_call43_params.begin(), int32_call43_params.end(), "call43", label_entry_53); - int32_call43->setCallingConv(CallingConv::C); - int32_call43->setTailCall(true);const ParamAttrsList *int32_call43_PAL = 0; - int32_call43->setParamAttrs(int32_call43_PAL); - - new ReturnInst(packed_tmp30, label_entry_53); - -} - -// Function: scs (func_scs) -{ - Function::arg_iterator args = func_scs->arg_begin(); - Value* packed_val_58 = args++; - packed_val_58->setName("val"); - - BasicBlock* label_entry_59 = new BasicBlock("entry",func_scs,0); - - // Block entry (label_entry_59) - ExtractElementInst* float_tmp2 = new ExtractElementInst(packed_val_58, const_int32_19, "tmp2", label_entry_59); - CallInst* float_call_60 = new CallInst(func_cosf, float_tmp2, "call", label_entry_59); - float_call_60->setCallingConv(CallingConv::C); - float_call_60->setTailCall(true);const ParamAttrsList *float_call_60_PAL = 0; - float_call_60->setParamAttrs(float_call_60_PAL); - - InsertElementInst* packed_tmp5 = new InsertElementInst(const_packed_35, float_call_60, const_int32_19, "tmp5", label_entry_59); - CallInst* float_call7 = new CallInst(func_sinf, float_tmp2, "call7", label_entry_59); - float_call7->setCallingConv(CallingConv::C); - float_call7->setTailCall(true);const ParamAttrsList *float_call7_PAL = 0; - float_call7->setParamAttrs(float_call7_PAL); - - InsertElementInst* packed_tmp9 = new InsertElementInst(packed_tmp5, float_call7, const_int32_23, "tmp9", label_entry_59); - new ReturnInst(packed_tmp9, label_entry_59); - -} - -// Function: vsin (func_vsin) -{ - Function::arg_iterator args = func_vsin->arg_begin(); - Value* packed_val_62 = args++; - packed_val_62->setName("val"); - - BasicBlock* label_entry_63 = new BasicBlock("entry",func_vsin,0); - - // Block entry (label_entry_63) - ExtractElementInst* float_tmp2_64 = new ExtractElementInst(packed_val_62, const_int32_19, "tmp2", label_entry_63); - CallInst* float_call_65 = new CallInst(func_sinf, float_tmp2_64, "call", label_entry_63); - float_call_65->setCallingConv(CallingConv::C); - float_call_65->setTailCall(true);const ParamAttrsList *float_call_65_PAL = 0; - float_call_65->setParamAttrs(float_call_65_PAL); - - InsertElementInst* packed_tmp6 = new InsertElementInst(const_packed_35, float_call_65, const_int32_19, "tmp6", label_entry_63); - InsertElementInst* packed_tmp9_66 = new InsertElementInst(packed_tmp6, float_call_65, const_int32_23, "tmp9", label_entry_63); - InsertElementInst* packed_tmp12 = new InsertElementInst(packed_tmp9_66, float_call_65, const_int32_25, "tmp12", label_entry_63); - InsertElementInst* packed_tmp15_67 = new InsertElementInst(packed_tmp12, float_call_65, const_int32_24, "tmp15", label_entry_63); - new ReturnInst(packed_tmp15_67, label_entry_63); - -} - -// Function: kilp (func_kilp) -{ - Function::arg_iterator args = func_kilp->arg_begin(); - Value* packed_val_69 = args++; - packed_val_69->setName("val"); - - BasicBlock* label_entry_70 = new BasicBlock("entry",func_kilp,0); - BasicBlock* label_lor_rhs = new BasicBlock("lor_rhs",func_kilp,0); - BasicBlock* label_lor_rhs5 = new BasicBlock("lor_rhs5",func_kilp,0); - BasicBlock* label_lor_rhs11 = new BasicBlock("lor_rhs11",func_kilp,0); - BasicBlock* label_UnifiedReturnBlock_71 = new BasicBlock("UnifiedReturnBlock",func_kilp,0); - - // Block entry (label_entry_70) - ExtractElementInst* float_tmp1_72 = new ExtractElementInst(packed_val_69, const_int32_19, "tmp1", label_entry_70); - FCmpInst* int1_cmp_73 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp1_72, const_float_18, "cmp", label_entry_70); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs, int1_cmp_73, label_entry_70); - - // Block lor_rhs (label_lor_rhs) - ExtractElementInst* float_tmp3_75 = new ExtractElementInst(packed_val_69, const_int32_23, "tmp3", label_lor_rhs); - FCmpInst* int1_cmp4 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp3_75, const_float_18, "cmp4", label_lor_rhs); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs5, int1_cmp4, label_lor_rhs); - - // Block lor_rhs5 (label_lor_rhs5) - ExtractElementInst* float_tmp7 = new ExtractElementInst(packed_val_69, const_int32_25, "tmp7", label_lor_rhs5); - FCmpInst* int1_cmp8 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp7, const_float_18, "cmp8", label_lor_rhs5); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs11, int1_cmp8, label_lor_rhs5); - - // Block lor_rhs11 (label_lor_rhs11) - ExtractElementInst* float_tmp13 = new ExtractElementInst(packed_val_69, const_int32_24, "tmp13", label_lor_rhs11); - FCmpInst* int1_cmp14 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp13, const_float_18, "cmp14", label_lor_rhs11); - CastInst* int32_retval = new ZExtInst(int1_cmp14, IntegerType::get(32), "retval", label_lor_rhs11); - new ReturnInst(int32_retval, label_lor_rhs11); - - // Block UnifiedReturnBlock (label_UnifiedReturnBlock_71) - new ReturnInst(const_int32_23, label_UnifiedReturnBlock_71); - -} - -return mod; - -} diff --git a/src/gallium/aux/llvm/gallivm_cpu.cpp b/src/gallium/aux/llvm/gallivm_cpu.cpp deleted file mode 100644 index 8f9830d0b1..0000000000 --- a/src/gallium/aux/llvm/gallivm_cpu.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "instructions.h" -#include "loweringpass.h" -#include "storage.h" -#include "tgsitollvm.h" - -#include "pipe/p_context.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_dump.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -struct gallivm_cpu_engine { - llvm::ExecutionEngine *engine; -}; - -static struct gallivm_cpu_engine *CPU = 0; - -typedef int (*fragment_shader_runner)(float x, float y, - float (*dests)[16][4], - float (*inputs)[16][4], - int num_attribs, - float (*consts)[4], int num_consts, - struct tgsi_sampler *samplers); - -int gallivm_cpu_fs_exec(struct gallivm_prog *prog, - float fx, float fy, - float (*dests)[16][4], - float (*inputs)[16][4], - float (*consts)[4], - struct tgsi_sampler *samplers) -{ - fragment_shader_runner runner = reinterpret_cast(prog->function); - assert(runner); - - return runner(fx, fy, dests, inputs, prog->num_interp, - consts, prog->num_consts, - samplers); -} - -static inline llvm::Function *func_for_shader(struct gallivm_prog *prog) -{ - llvm::Module *mod = prog->module; - llvm::Function *func = 0; - - switch (prog->type) { - case GALLIVM_VS: - func = mod->getFunction("vs_shader"); - break; - case GALLIVM_FS: - func = mod->getFunction("fs_shader"); - break; - default: - assert(!"Unknown shader type!"); - break; - } - return func; -} - -/*! - This function creates a CPU based execution engine for the given gallivm_prog. - gallivm_cpu_engine should be used as a singleton throughout the library. Before - executing gallivm_prog_exec one needs to call gallivm_cpu_jit_compile. - The gallivm_prog instance which is being passed to the constructor is being - automatically JIT compiled so one shouldn't call gallivm_cpu_jit_compile - with it again. - */ -struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog) -{ - struct gallivm_cpu_engine *cpu = (struct gallivm_cpu_engine *) - calloc(1, sizeof(struct gallivm_cpu_engine)); - llvm::Module *mod = static_cast(prog->module); - llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); - llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false); - ee->DisableLazyCompilation(); - cpu->engine = ee; - - llvm::Function *func = func_for_shader(prog); - - prog->function = ee->getPointerToFunction(func); - CPU = cpu; - return cpu; -} - - -/*! - This function JIT compiles the given gallivm_prog with the given cpu based execution engine. - The reference to the generated machine code entry point will be stored - in the gallivm_prog program. After executing this function one can call gallivm_prog_exec - in order to execute the gallivm_prog on the CPU. - */ -void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog *prog) -{ - llvm::Module *mod = static_cast(prog->module); - llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); - llvm::ExecutionEngine *ee = cpu->engine; - assert(ee); - /*FIXME : remove */ - ee->DisableLazyCompilation(); - ee->addModuleProvider(mp); - - llvm::Function *func = func_for_shader(prog); - prog->function = ee->getPointerToFunction(func); -} - -void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu) -{ - free(cpu); -} - -struct gallivm_cpu_engine * gallivm_global_cpu_engine() -{ - return CPU; -} - - -typedef void (*vertex_shader_runner)(void *ainputs, - void *dests, - float (*aconsts)[4], - void *temps); - - -/*! - This function is used to execute the gallivm_prog in software. Before calling - this function the gallivm_prog has to be JIT compiled with the gallivm_cpu_jit_compile - function. - */ -int gallivm_cpu_vs_exec(struct gallivm_prog *prog, - struct tgsi_exec_vector *inputs, - struct tgsi_exec_vector *dests, - float (*consts)[4], - struct tgsi_exec_vector *temps) -{ - vertex_shader_runner runner = reinterpret_cast(prog->function); - assert(runner); - /*FIXME*/ - runner(inputs, dests, consts, temps); - - return 0; -} - -#endif diff --git a/src/gallium/aux/llvm/gallivm_p.h b/src/gallium/aux/llvm/gallivm_p.h deleted file mode 100644 index cfe7b1901b..0000000000 --- a/src/gallium/aux/llvm/gallivm_p.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef GALLIVM_P_H -#define GALLIVM_P_H - -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "pipe/p_shader_tokens.h" -#include "pipe/p_compiler.h" - -namespace llvm { - class Module; -} - -#if defined __cplusplus -extern "C" { -#endif - -enum gallivm_shader_type; -enum gallivm_vector_layout; - -struct gallivm_interpolate { - int attrib; - int chan; - int type; -}; - -struct gallivm_ir { - llvm::Module *module; - int id; - enum gallivm_shader_type type; - enum gallivm_vector_layout layout; - int num_components; - int num_consts; - - //FIXME: this might not be enough for some shaders - struct gallivm_interpolate interpolators[32*4]; - int num_interp; -}; - -struct gallivm_prog { - llvm::Module *module; - void *function; - - int id; - enum gallivm_shader_type type; - - int num_consts; - - //FIXME: this might not be enough for some shaders - struct gallivm_interpolate interpolators[32*4]; - int num_interp; -}; - -static INLINE void gallivm_swizzle_components(int swizzle, - int *xc, int *yc, - int *zc, int *wc) -{ - int x = swizzle / 1000; swizzle -= x * 1000; - int y = swizzle / 100; swizzle -= y * 100; - int z = swizzle / 10; swizzle -= z * 10; - int w = swizzle; - - if (xc) *xc = x; - if (yc) *yc = y; - if (zc) *zc = z; - if (wc) *wc = w; -} - -static INLINE boolean gallivm_is_swizzle(int swizzle) -{ - const int NO_SWIZZLE = TGSI_SWIZZLE_X * 1000 + TGSI_SWIZZLE_Y * 100 + - TGSI_SWIZZLE_Z * 10 + TGSI_SWIZZLE_W; - return swizzle != NO_SWIZZLE; -} - -static INLINE int gallivm_x_swizzle(int swizzle) -{ - int x; - gallivm_swizzle_components(swizzle, &x, 0, 0, 0); - return x; -} - -static INLINE int gallivm_y_swizzle(int swizzle) -{ - int y; - gallivm_swizzle_components(swizzle, 0, &y, 0, 0); - return y; -} - -static INLINE int gallivm_z_swizzle(int swizzle) -{ - int z; - gallivm_swizzle_components(swizzle, 0, 0, &z, 0); - return z; -} - -static INLINE int gallivm_w_swizzle(int swizzle) -{ - int w; - gallivm_swizzle_components(swizzle, 0, 0, 0, &w); - return w; -} - -#endif /* MESA_LLVM */ - -#if defined __cplusplus -} // extern "C" -#endif - -#endif diff --git a/src/gallium/aux/llvm/instructions.cpp b/src/gallium/aux/llvm/instructions.cpp deleted file mode 100644 index 55d39fa5f1..0000000000 --- a/src/gallium/aux/llvm/instructions.cpp +++ /dev/null @@ -1,889 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "instructions.h" - -#include "storage.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -using namespace llvm; - -#include "gallivm_builtins.cpp" - -static inline std::string createFuncName(int label) -{ - std::ostringstream stream; - stream << "function"; - stream << label; - return stream.str(); -} - -Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, - Storage *storage) - : m_mod(mod), m_func(func), m_builder(block), m_idx(0), - m_storage(storage) -{ - m_floatVecType = VectorType::get(Type::FloatTy, 4); - - m_llvmFSqrt = 0; - m_llvmFAbs = 0; - m_llvmPow = 0; - m_llvmFloor = 0; - m_llvmFlog = 0; - m_llvmLit = 0; - m_fmtPtr = 0; - - createGallivmBuiltins(m_mod); -} - -llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2) -{ - return m_builder.CreateAdd(in1, in2, name("add")); -} - -llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3) -{ - Value *mulRes = mul(in1, in2); - return add(mulRes, in3); -} - -llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2) -{ - return m_builder.CreateMul(in1, in2, name("mul")); -} - -const char * Instructions::name(const char *prefix) -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - Value *x = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(0), - name("extractx")); - Value *y = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(1), - name("extracty")); - Value *z = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(2), - name("extractz")); - Value *xy = m_builder.CreateAdd(x, y,name("xy")); - Value *dot3 = m_builder.CreateAdd(xy, z, name("dot3")); - return vectorFromVals(dot3, dot3, dot3, dot3); -} - -llvm::Value *Instructions::callFSqrt(llvm::Value *val) -{ - if (!m_llvmFSqrt) { - // predeclare the intrinsic - std::vector fsqrtArgs; - fsqrtArgs.push_back(Type::FloatTy); - ParamAttrsList *fsqrtPal = 0; - FunctionType* fsqrtType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/fsqrtArgs, - /*isVarArg=*/false); - m_llvmFSqrt = new Function( - /*Type=*/fsqrtType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"llvm.sqrt.f32", m_mod); - m_llvmFSqrt->setCallingConv(CallingConv::C); - m_llvmFSqrt->setParamAttrs(fsqrtPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFSqrt, val, - name("sqrt")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::rsq(llvm::Value *in1) -{ - Value *x = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("extractx")); - Value *abs = callFAbs(x); - Value *sqrt = callFSqrt(abs); - - Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, - APFloat(1.f)), - sqrt, - name("rsqrt")); - return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt); -} - -llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w) -{ - Constant *const_vec = Constant::getNullValue(m_floatVecType); - Value *res = m_builder.CreateInsertElement(const_vec, x, - m_storage->constantInt(0), - name("vecx")); - res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), - name("vecxy")); - res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), - name("vecxyz")); - if (w) - res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), - name("vecxyzw")); - return res; -} - -llvm::Value *Instructions::callFAbs(llvm::Value *val) -{ - if (!m_llvmFAbs) { - // predeclare the intrinsic - std::vector fabsArgs; - fabsArgs.push_back(Type::FloatTy); - ParamAttrsList *fabsPal = 0; - FunctionType* fabsType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/fabsArgs, - /*isVarArg=*/false); - m_llvmFAbs = new Function( - /*Type=*/fabsType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"fabs", m_mod); - m_llvmFAbs->setCallingConv(CallingConv::C); - m_llvmFAbs->setParamAttrs(fabsPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFAbs, val, - name("fabs")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::lit(llvm::Value *in) -{ - if (!m_llvmLit) { - m_llvmLit = m_mod->getFunction("lit"); - } - CallInst *call = m_builder.CreateCall(m_llvmLit, in, name("litres")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2) -{ - Value *res = m_builder.CreateSub(in1, in2, name("sub")); - return res; -} - -llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2) -{ - if (!m_llvmPow) { - // predeclare the intrinsic - std::vector powArgs; - powArgs.push_back(Type::FloatTy); - powArgs.push_back(Type::FloatTy); - ParamAttrsList *powPal = 0; - FunctionType* powType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/powArgs, - /*isVarArg=*/false); - m_llvmPow = new Function( - /*Type=*/powType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"llvm.pow.f32", m_mod); - m_llvmPow->setCallingConv(CallingConv::C); - m_llvmPow->setParamAttrs(powPal); - } - std::vector params; - params.push_back(val1); - params.push_back(val2); - CallInst *call = m_builder.CreateCall(m_llvmPow, params.begin(), params.end(), - name("pow")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *x2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(0), - name("x2")); - llvm::Value *val = callPow(x1, x2); - return vectorFromVals(val, val, val, val); -} - -llvm::Value * Instructions::rcp(llvm::Value *in1) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *res = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, - APFloat(1.f)), - x1, name("rcp")); - return vectorFromVals(res, res, res, res); -} - -llvm::Value * Instructions::dp4(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - std::vector vec = extractVector(mulRes); - Value *xy = m_builder.CreateAdd(vec[0], vec[1], name("xy")); - Value *xyz = m_builder.CreateAdd(xy, vec[2], name("xyz")); - Value *dot4 = m_builder.CreateAdd(xyz, vec[3], name("dot4")); - return vectorFromVals(dot4, dot4, dot4, dot4); -} - -llvm::Value * Instructions::dph(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - std::vector vec1 = extractVector(mulRes); - Value *xy = m_builder.CreateAdd(vec1[0], vec1[1], name("xy")); - Value *xyz = m_builder.CreateAdd(xy, vec1[2], name("xyz")); - Value *dph = m_builder.CreateAdd(xyz, vec1[3], name("dph")); - return vectorFromVals(dph, dph, dph, dph); -} - -llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2) -{ - Value *y1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(1), - name("y1")); - Value *z = m_builder.CreateExtractElement(in1, - m_storage->constantInt(2), - name("z")); - Value *y2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(1), - name("y2")); - Value *w = m_builder.CreateExtractElement(in2, - m_storage->constantInt(3), - name("w")); - Value *ry = m_builder.CreateMul(y1, y2, name("tyuy")); - return vectorFromVals(ConstantFP::get(Type::FloatTy, APFloat(1.f)), - ry, z, w); -} - -llvm::Value * Instructions::ex2(llvm::Value *in) -{ - llvm::Value *val = callPow(ConstantFP::get(Type::FloatTy, APFloat(2.f)), - m_builder.CreateExtractElement( - in, m_storage->constantInt(0), - name("x1"))); - return vectorFromVals(val, val, val, val); -} - -llvm::Value * Instructions::callFloor(llvm::Value *val) -{ - if (!m_llvmFloor) { - // predeclare the intrinsic - std::vector floorArgs; - floorArgs.push_back(Type::FloatTy); - ParamAttrsList *floorPal = 0; - FunctionType* floorType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/floorArgs, - /*isVarArg=*/false); - m_llvmFloor = new Function( - /*Type=*/floorType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"floorf", m_mod); - m_llvmFloor->setCallingConv(CallingConv::C); - m_llvmFloor->setParamAttrs(floorPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFloor, val, - name("floorf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::floor(llvm::Value *in) -{ - std::vector vec = extractVector(in); - return vectorFromVals(callFloor(vec[0]), callFloor(vec[1]), - callFloor(vec[2]), callFloor(vec[3])); -} - -llvm::Value * Instructions::arl(llvm::Value *in) -{ - return floor(in); -} - -llvm::Value * Instructions::frc(llvm::Value *in) -{ - llvm::Value *flr = floor(in); - return sub(in, flr); -} - -llvm::Value * Instructions::callFLog(llvm::Value *val) -{ - if (!m_llvmFlog) { - // predeclare the intrinsic - std::vector flogArgs; - flogArgs.push_back(Type::FloatTy); - ParamAttrsList *flogPal = 0; - FunctionType* flogType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/flogArgs, - /*isVarArg=*/false); - m_llvmFlog = new Function( - /*Type=*/flogType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"logf", m_mod); - m_llvmFlog->setCallingConv(CallingConv::C); - m_llvmFlog->setParamAttrs(flogPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFlog, val, - name("logf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::lg2(llvm::Value *in) -{ - std::vector vec = extractVector(in); - llvm::Value *const_vec = constVector(1.442695f, 1.442695f, - 1.442695f, 1.442695f); - return mul(vectorFromVals(callFLog(vec[0]), callFLog(vec[1]), - callFLog(vec[2]), callFLog(vec[3])), const_vec); -} - -llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2) -{ - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); - Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], - name("selx")); - - Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); - Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], - name("sely")); - - Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); - Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], - name("selz")); - - Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); - Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], - name("selw")); - - return vectorFromVals(selx, sely, selz, selw); -} - -llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2) -{ - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], - name("xcmp")); - Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], - name("selx")); - - Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], - name("ycmp")); - Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], - name("sely")); - - Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], - name("zcmp")); - Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], - name("selz")); - - Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], - name("wcmp")); - Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], - name("selw")); - - return vectorFromVals(selx, sely, selz, selw); -} - -void Instructions::printVector(llvm::Value *val) -{ - static const char *frmt = "Vector is [%f, %f, %f, %f]\x0A"; - - if (!m_fmtPtr) { - Constant *format = ConstantArray::get(frmt, true); - ArrayType *arrayTy = ArrayType::get(IntegerType::get(8), strlen(frmt) + 1); - GlobalVariable* globalFormat = new GlobalVariable( - /*Type=*/arrayTy, - /*isConstant=*/true, - /*Linkage=*/GlobalValue::InternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name(".str"), - m_mod); - globalFormat->setInitializer(format); - - Constant* const_int0 = Constant::getNullValue(IntegerType::get(32)); - std::vector const_ptr_21_indices; - const_ptr_21_indices.push_back(const_int0); - const_ptr_21_indices.push_back(const_int0); - m_fmtPtr = ConstantExpr::getGetElementPtr(globalFormat, - &const_ptr_21_indices[0], const_ptr_21_indices.size()); - } - - Function *func_printf = m_mod->getFunction("printf"); - if (!func_printf) - func_printf = declarePrintf(); - assert(func_printf); - std::vector vec = extractVector(val); - Value *dx = m_builder.CreateFPExt(vec[0], Type::DoubleTy, name("dx")); - Value *dy = m_builder.CreateFPExt(vec[1], Type::DoubleTy, name("dy")); - Value *dz = m_builder.CreateFPExt(vec[2], Type::DoubleTy, name("dz")); - Value *dw = m_builder.CreateFPExt(vec[3], Type::DoubleTy, name("dw")); - std::vector params; - params.push_back(m_fmtPtr); - params.push_back(dx); - params.push_back(dy); - params.push_back(dz); - params.push_back(dw); - CallInst *call = m_builder.CreateCall(func_printf, params.begin(), params.end(), - name("printf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(true); -} - -llvm::Function * Instructions::declarePrintf() -{ - std::vector args; - ParamAttrsList *params = 0; - FunctionType* funcTy = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/args, - /*isVarArg=*/true); - Function* func_printf = new Function( - /*Type=*/funcTy, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"printf", m_mod); - func_printf->setCallingConv(CallingConv::C); - func_printf->setParamAttrs(params); - return func_printf; -} - - -llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} -llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - - -llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - -llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *y1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(1), - name("y1")); - Value *z1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(2), - name("z1")); - - Value *x2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(0), - name("x2")); - Value *y2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(1), - name("y2")); - Value *z2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(2), - name("z2")); - Value *y1z2 = mul(y1, z2); - Value *z1y2 = mul(z1, y2); - - Value *z1x2 = mul(z1, x2); - Value *x1z2 = mul(x1, z2); - - Value *x1y2 = mul(x1, y2); - Value *y1x2 = mul(y1, x2); - - return vectorFromVals(sub(y1z2, z1y2), sub(z1x2, x1z2), sub(x1y2, y1x2)); -} - - -llvm::Value * Instructions::abs(llvm::Value *in) -{ - std::vector vec = extractVector(in); - Value *xabs = callFAbs(vec[0]); - Value *yabs = callFAbs(vec[1]); - Value *zabs = callFAbs(vec[2]); - Value *wabs = callFAbs(vec[3]); - return vectorFromVals(xabs, yabs, zabs, wabs); -} - -void Instructions::ifop(llvm::Value *in) -{ - BasicBlock *ifthen = new BasicBlock(name("ifthen"), m_func,0); - BasicBlock *ifend = new BasicBlock(name("ifthenend"), m_func,0); - - //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0); - //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0); - //BasicBlock *wblock = new BasicBlock(name("wblock"), m_func,0); - - Constant *float0 = Constant::getNullValue(Type::FloatTy); - - Value *x = m_builder.CreateExtractElement(in, m_storage->constantInt(0), - name("extractx")); - Value *xcmp = m_builder.CreateFCmpUNE(x, float0, name("xcmp")); - m_builder.CreateCondBr(xcmp, ifthen, ifend); - //m_builder.SetInsertPoint(yblock); - - m_builder.SetInsertPoint(ifthen); - m_ifStack.push(ifend); -} - -llvm::BasicBlock * Instructions::currentBlock() const -{ - return m_builder.GetInsertBlock(); -} - -void Instructions::elseop() -{ - assert(!m_ifStack.empty()); - BasicBlock *ifend = new BasicBlock(name("ifend"), m_func,0); - m_builder.CreateBr(ifend); - m_builder.SetInsertPoint(m_ifStack.top()); - currentBlock()->setName(name("ifelse")); - m_ifStack.pop(); - m_ifStack.push(ifend); -} - -void Instructions::endif() -{ - assert(!m_ifStack.empty()); - m_builder.CreateBr(m_ifStack.top()); - m_builder.SetInsertPoint(m_ifStack.top()); - m_ifStack.pop(); -} - -llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3) -{ - llvm::Value *m = mul(in1, in2); - llvm::Value *vec1 = constVector(1.f, 1.f, 1.f, 1.f); - llvm::Value *s = sub(vec1, in1); - return add(m, mul(s, in3)); -} - -void Instructions::beginLoop() -{ - BasicBlock *begin = new BasicBlock(name("loop"), m_func,0); - BasicBlock *end = new BasicBlock(name("endloop"), m_func,0); - - m_builder.CreateBr(begin); - Loop loop; - loop.begin = begin; - loop.end = end; - m_builder.SetInsertPoint(begin); - m_loopStack.push(loop); -} - -void Instructions::endLoop() -{ - assert(!m_loopStack.empty()); - Loop loop = m_loopStack.top(); - m_builder.CreateBr(loop.begin); - loop.end->moveAfter(currentBlock()); - m_builder.SetInsertPoint(loop.end); - m_loopStack.pop(); -} - -void Instructions::brk() -{ - assert(!m_loopStack.empty()); - BasicBlock *unr = new BasicBlock(name("unreachable"), m_func,0); - m_builder.CreateBr(m_loopStack.top().end); - m_builder.SetInsertPoint(unr); -} - -llvm::Value * Instructions::trunc(llvm::Value *in) -{ - std::vector vec = extractVector(in); - Value *icastx = m_builder.CreateFPToSI(vec[0], IntegerType::get(32), - name("ftoix")); - Value *icasty = m_builder.CreateFPToSI(vec[1], IntegerType::get(32), - name("ftoiy")); - Value *icastz = m_builder.CreateFPToSI(vec[2], IntegerType::get(32), - name("ftoiz")); - Value *icastw = m_builder.CreateFPToSI(vec[3], IntegerType::get(32), - name("ftoiw")); - Value *fx = m_builder.CreateSIToFP(icastx, Type::FloatTy, - name("fx")); - Value *fy = m_builder.CreateSIToFP(icasty, Type::FloatTy, - name("fy")); - Value *fz = m_builder.CreateSIToFP(icastz, Type::FloatTy, - name("fz")); - Value *fw = m_builder.CreateSIToFP(icastw, Type::FloatTy, - name("fw")); - return vectorFromVals(fx, fy, fz, fw); -} - -void Instructions::end() -{ - m_builder.CreateRetVoid(); -} - -void Instructions::cal(int label, llvm::Value *input) -{ - std::vector params; - params.push_back(input); - llvm::Function *func = findFunction(label); - - m_builder.CreateCall(func, params.begin(), params.end()); -} - -llvm::Function * Instructions::declareFunc(int label) -{ - PointerType *vecPtr = PointerType::getUnqual(m_floatVecType); - std::vector args; - args.push_back(vecPtr); - args.push_back(vecPtr); - args.push_back(vecPtr); - args.push_back(vecPtr); - ParamAttrsList *params = 0; - FunctionType *funcType = FunctionType::get( - /*Result=*/Type::VoidTy, - /*Params=*/args, - /*isVarArg=*/false); - std::string name = createFuncName(label); - Function *func = new Function( - /*Type=*/funcType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/name.c_str(), m_mod); - func->setCallingConv(CallingConv::C); - func->setParamAttrs(params); - return func; -} - -void Instructions::bgnSub(unsigned label) -{ - llvm::Function *func = findFunction(label); - - Function::arg_iterator args = func->arg_begin(); - Value *ptr_INPUT = args++; - ptr_INPUT->setName("INPUT"); - m_storage->pushArguments(ptr_INPUT); - - llvm::BasicBlock *entry = new BasicBlock("entry", func, 0); - - m_func = func; - m_builder.SetInsertPoint(entry); -} - -void Instructions::endSub() -{ - m_func = 0; - m_builder.SetInsertPoint(0); -} - -llvm::Function * Instructions::findFunction(int label) -{ - llvm::Function *func = m_functions[label]; - if (!func) { - func = declareFunc(label); - m_functions[label] = func; - } - return func; -} - -llvm::Value * Instructions::constVector(float x, float y, float z, float w) -{ - std::vector vec(4); - vec[0] = ConstantFP::get(Type::FloatTy, APFloat(x)); - vec[1] = ConstantFP::get(Type::FloatTy, APFloat(y)); - vec[2] = ConstantFP::get(Type::FloatTy, APFloat(z)); - vec[3] = ConstantFP::get(Type::FloatTy, APFloat(w)); - return ConstantVector::get(m_floatVecType, vec); -} - - -std::vector Instructions::extractVector(llvm::Value *vec) -{ - std::vector elems(4); - elems[0] = m_builder.CreateExtractElement(vec, m_storage->constantInt(0), - name("x")); - elems[1] = m_builder.CreateExtractElement(vec, m_storage->constantInt(1), - name("y")); - elems[2] = m_builder.CreateExtractElement(vec, m_storage->constantInt(2), - name("z")); - elems[3] = m_builder.CreateExtractElement(vec, m_storage->constantInt(3), - name("w")); - return elems; -} - -llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) -{ - llvm::Function *func = m_mod->getFunction("cmp"); - assert(func); - - std::vector params; - params.push_back(in1); - params.push_back(in2); - params.push_back(in3); - CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), name("cmpres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::cos(llvm::Value *in) -{ -#if 0 - llvm::Function *func = m_mod->getFunction("vcos"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("cosres")); - call->setTailCall(false); - return call; -#else - std::vector elems = extractVector(in); - Function *func = m_mod->getFunction("cosf"); - assert(func); - CallInst *cos = m_builder.CreateCall(func, elems[0], name("cosres")); - cos->setCallingConv(CallingConv::C); - cos->setTailCall(true); - return vectorFromVals(cos, cos, cos, cos); -#endif -} - -llvm::Value * Instructions::scs(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("scs"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("scsres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::kilp(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("kilp"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("kilpres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::sin(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("vsin"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("sinres")); - call->setTailCall(false); - return call; -} -#endif //MESA_LLVM - - diff --git a/src/gallium/aux/llvm/instructions.h b/src/gallium/aux/llvm/instructions.h deleted file mode 100644 index 9ebc17dd8e..0000000000 --- a/src/gallium/aux/llvm/instructions.h +++ /dev/null @@ -1,152 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef INSTRUCTIONS_H -#define INSTRUCTIONS_H - -#include -#include -#include -#include - -#include -#include - -namespace llvm { - class VectorType; - class Function; -} - -class Storage; - -class Instructions -{ -public: - Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, - Storage *storage); - - llvm::BasicBlock *currentBlock() const; - - llvm::Value *abs(llvm::Value *in1); - llvm::Value *arl(llvm::Value *in1); - llvm::Value *add(llvm::Value *in1, llvm::Value *in2); - void beginLoop(); - void bgnSub(unsigned); - void brk(); - void cal(int label, llvm::Value *input); - llvm::Value *cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); - llvm::Value *cos(llvm::Value *in); - llvm::Value *cross(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dp3(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dp4(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dph(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dst(llvm::Value *in1, llvm::Value *in2); - void elseop(); - void endif(); - void endLoop(); - void end(); - void endSub(); - llvm::Value *ex2(llvm::Value *in); - llvm::Value *floor(llvm::Value *in); - llvm::Value *frc(llvm::Value *in); - void ifop(llvm::Value *in); - llvm::Value *kilp(llvm::Value *in); - llvm::Value *lerp(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3); - llvm::Value *lit(llvm::Value *in); - llvm::Value *lg2(llvm::Value *in); - llvm::Value *madd(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in2); - llvm::Value *min(llvm::Value *in1, llvm::Value *in2); - llvm::Value *max(llvm::Value *in1, llvm::Value *in2); - llvm::Value *mul(llvm::Value *in1, llvm::Value *in2); - llvm::Value *pow(llvm::Value *in1, llvm::Value *in2); - llvm::Value *rcp(llvm::Value *in); - llvm::Value *rsq(llvm::Value *in); - llvm::Value *scs(llvm::Value *in); - llvm::Value *sge(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sgt(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sin(llvm::Value *in); - llvm::Value *slt(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sub(llvm::Value *in1, llvm::Value *in2); - llvm::Value *trunc(llvm::Value *in); - - void printVector(llvm::Value *val); -private: - const char *name(const char *prefix); - - llvm::Value *callFAbs(llvm::Value *val); - llvm::Value *callFloor(llvm::Value *val); - llvm::Value *callFSqrt(llvm::Value *val); - llvm::Value *callFLog(llvm::Value *val); - llvm::Value *callPow(llvm::Value *val1, llvm::Value *val2); - - llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w=0); - - llvm::Value *constVector(float x, float y, float z, float w); - - llvm::Function *declarePrintf(); - llvm::Function *declareFunc(int label); - - llvm::Function *findFunction(int label); - - std::vector extractVector(llvm::Value *vec); -private: - llvm::Module *m_mod; - llvm::Function *m_func; - char m_name[32]; - llvm::LLVMFoldingBuilder m_builder; - int m_idx; - - llvm::VectorType *m_floatVecType; - - llvm::Function *m_llvmFSqrt; - llvm::Function *m_llvmFAbs; - llvm::Function *m_llvmPow; - llvm::Function *m_llvmFloor; - llvm::Function *m_llvmFlog; - llvm::Function *m_llvmLit; - - llvm::Constant *m_fmtPtr; - - std::stack m_ifStack; - struct Loop { - llvm::BasicBlock *begin; - llvm::BasicBlock *end; - }; - std::stack m_loopStack; - std::map m_functions; - Storage *m_storage; -}; - -#endif diff --git a/src/gallium/aux/llvm/instructionssoa.cpp b/src/gallium/aux/llvm/instructionssoa.cpp deleted file mode 100644 index a4d5046637..0000000000 --- a/src/gallium/aux/llvm/instructionssoa.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "instructionssoa.h" - -#include "storagesoa.h" - -#include - -using namespace llvm; - -InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, - llvm::BasicBlock *block, StorageSoa *storage) - : m_builder(block), - m_storage(storage), - m_idx(0) -{ -} - -const char * InstructionsSoa::name(const char *prefix) const -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - Constant *constVector = Constant::getNullValue(vectorType); - Value *res = m_builder.CreateInsertElement(constVector, x, - m_storage->constantInt(0), - name("vecx")); - res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), - name("vecxy")); - res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), - name("vecxyz")); - if (w) - res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), - name("vecxyzw")); - return res; -} - -std::vector InstructionsSoa::arl(const std::vector in) -{ - std::vector res(4); - - //Extract x's - llvm::Value *x1 = m_builder.CreateExtractElement(in[0], - m_storage->constantInt(0), - name("extractX")); - //cast it to an unsigned int - x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast")); - - res[0] = x1;//vectorFromVals(x1, x2, x3, x4); - //only x is valid. the others shouldn't be necessary - /* - res[1] = Constant::getNullValue(m_floatVecType); - res[2] = Constant::getNullValue(m_floatVecType); - res[3] = Constant::getNullValue(m_floatVecType); - */ - - return res; -} - - -std::vector InstructionsSoa::add(const std::vector in1, - const std::vector in2) -{ - std::vector res(4); - - res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx")); - res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy")); - res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz")); - res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw")); - - return res; -} - -std::vector InstructionsSoa::mul(const std::vector in1, - const std::vector in2) -{ - std::vector res(4); - - res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx")); - res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly")); - res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz")); - res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw")); - - return res; -} - -void InstructionsSoa::end() -{ - m_builder.CreateRetVoid(); -} - -std::vector InstructionsSoa::madd(const std::vector in1, - const std::vector in2, - const std::vector in3) -{ - std::vector res = mul(in1, in2); - return add(res, in3); -} - -std::vector InstructionsSoa::extractVector(llvm::Value *vector) -{ - std::vector res(4); - res[0] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(0), - name("extract1X")); - res[1] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(1), - name("extract2X")); - res[2] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(2), - name("extract3X")); - res[3] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(3), - name("extract4X")); - - return res; -} diff --git a/src/gallium/aux/llvm/instructionssoa.h b/src/gallium/aux/llvm/instructionssoa.h deleted file mode 100644 index 4169dcbb2e..0000000000 --- a/src/gallium/aux/llvm/instructionssoa.h +++ /dev/null @@ -1,74 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INSTRUCTIONSSOA_H -#define INSTRUCTIONSSOA_H - -#include - -#include - -namespace llvm { - class Module; - class Function; - class BasicBlock; - class Value; -} -class StorageSoa; - -class InstructionsSoa -{ -public: - InstructionsSoa(llvm::Module *mod, llvm::Function *func, - llvm::BasicBlock *block, StorageSoa *storage); - - std::vector arl(const std::vector in); - - std::vector add(const std::vector in1, - const std::vector in2); - std::vector madd(const std::vector in1, - const std::vector in2, - const std::vector in3); - std::vector mul(const std::vector in1, - const std::vector in2); - void end(); - - std::vector extractVector(llvm::Value *vector); -private: - const char * name(const char *prefix) const; - llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w); -private: - llvm::LLVMFoldingBuilder m_builder; - StorageSoa *m_storage; -private: - mutable int m_idx; - mutable char m_name[32]; -}; - - -#endif diff --git a/src/gallium/aux/llvm/llvm_builtins.c b/src/gallium/aux/llvm/llvm_builtins.c deleted file mode 100644 index 4f98d754ba..0000000000 --- a/src/gallium/aux/llvm/llvm_builtins.c +++ /dev/null @@ -1,115 +0,0 @@ -/*clang --emit-llvm llvm_builtins.c |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=gallivm_builtins.cpp -f -for=shader -funcname=createGallivmBuiltins*/ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -typedef __attribute__(( ocu_vector_type(4) )) float float4; - -extern float powf(float a, float b); - -inline float approx(float a, float b) -{ - if (b < -128.0f) b = -128.0f; - if (b > 128.0f) b = 128.0f; - if (a < 0) a = 0; - return powf(a, b); -} - -inline float4 lit(float4 tmp) -{ - float4 result; - result.x = 1.0; - result.w = 1.0; - if (tmp.x > 0) { - result.y = tmp.x; - result.z = approx(tmp.y, tmp.w); - } else { - result.y = 0; - result.z = 0; - } - return result; -} - -inline float4 cmp(float4 tmp0, float4 tmp1, float4 tmp2) -{ - float4 result; - - result.x = (tmp0.x < 0.0) ? tmp1.x : tmp2.x; - result.y = (tmp0.y < 0.0) ? tmp1.y : tmp2.y; - result.z = (tmp0.z < 0.0) ? tmp1.z : tmp2.z; - result.w = (tmp0.w < 0.0) ? tmp1.w : tmp2.w; - - return result; -} - -extern float cosf(float val); -extern float sinf(float val); - -inline float4 vcos(float4 val) -{ - float4 result; - printf("VEC IN is %f %f %f %f\n", val.x, val.y, val.z, val.w); - result.x = cosf(val.x); - result.y = cosf(val.x); - result.z = cosf(val.x); - result.w = cosf(val.x); - printf("VEC OUT is %f %f %f %f\n", result.x, result.y, result.z, result.w); - return result; -} - -inline float4 scs(float4 val) -{ - float4 result; - float tmp = val.x; - result.x = cosf(tmp); - result.y = sinf(tmp); - return result; -} - - -inline float4 vsin(float4 val) -{ - float4 result; - float tmp = val.x; - float res = sinf(tmp); - result.x = res; - result.y = res; - result.z = res; - result.w = res; - return result; -} - -inline int kilp(float4 val) -{ - if (val.x < 0 || val.y < 0 || val.z < 0 || val.w < 0) - return 1; - else - return 0; -} diff --git a/src/gallium/aux/llvm/loweringpass.cpp b/src/gallium/aux/llvm/loweringpass.cpp deleted file mode 100644 index 556dbec366..0000000000 --- a/src/gallium/aux/llvm/loweringpass.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "loweringpass.h" - -using namespace llvm; - -char LoweringPass::ID = 0; -RegisterPass X("lowering", "Lowering Pass"); - -LoweringPass::LoweringPass() - : ModulePass((intptr_t)&ID) -{ -} - -bool LoweringPass::runOnModule(Module &m) -{ - llvm::cerr << "Hello: " << m.getModuleIdentifier() << "\n"; - return false; -} diff --git a/src/gallium/aux/llvm/loweringpass.h b/src/gallium/aux/llvm/loweringpass.h deleted file mode 100644 index f62dcf6ba7..0000000000 --- a/src/gallium/aux/llvm/loweringpass.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LOWERINGPASS_H -#define LOWERINGPASS_H - -#include "llvm/Pass.h" -#include "llvm/Module.h" - -struct LoweringPass : public llvm::ModulePass -{ - static char ID; - LoweringPass(); - - virtual bool runOnModule(llvm::Module &m); -}; - -#endif diff --git a/src/gallium/aux/llvm/storage.cpp b/src/gallium/aux/llvm/storage.cpp deleted file mode 100644 index c4326de8c5..0000000000 --- a/src/gallium/aux/llvm/storage.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "storage.h" - -#include "gallivm_p.h" - -#include "pipe/p_shader_tokens.h" -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace llvm; - -Storage::Storage(llvm::BasicBlock *block, llvm::Value *input) - : m_block(block), - m_INPUT(input), - m_addrs(32), - m_idx(0) -{ - m_floatVecType = VectorType::get(Type::FloatTy, 4); - m_intVecType = VectorType::get(IntegerType::get(32), 4); - - m_undefFloatVec = UndefValue::get(m_floatVecType); - m_undefIntVec = UndefValue::get(m_intVecType); - m_extSwizzleVec = 0; - - m_numConsts = 0; -} - -//can only build vectors with all members in the [0, 9] range -llvm::Constant *Storage::shuffleMask(int vec) -{ - if (!m_extSwizzleVec) { - std::vector elems; - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); - m_extSwizzleVec = ConstantVector::get(m_floatVecType, elems); - } - - if (m_intVecs.find(vec) != m_intVecs.end()) { - return m_intVecs[vec]; - } - int origVec = vec; - Constant* const_vec = 0; - if (origVec == 0) { - const_vec = Constant::getNullValue(m_intVecType); - } else { - int x = gallivm_x_swizzle(vec); - int y = gallivm_y_swizzle(vec); - int z = gallivm_z_swizzle(vec); - int w = gallivm_w_swizzle(vec); - std::vector elems; - elems.push_back(constantInt(x)); - elems.push_back(constantInt(y)); - elems.push_back(constantInt(z)); - elems.push_back(constantInt(w)); - const_vec = ConstantVector::get(m_intVecType, elems); - } - - m_intVecs[origVec] = const_vec; - return const_vec; -} - -llvm::ConstantInt *Storage::constantInt(int idx) -{ - if (m_constInts.find(idx) != m_constInts.end()) { - return m_constInts[idx]; - } - ConstantInt *const_int = ConstantInt::get(APInt(32, idx)); - m_constInts[idx] = const_int; - return const_int; -} - -llvm::Value *Storage::inputElement(int idx, llvm::Value *indIdx) -{ - Value *val = element(InputsArg, idx, indIdx); - LoadInst *load = new LoadInst(val, name("input"), false, m_block); - load->setAlignment(8); - - return load; -} - -llvm::Value *Storage::constElement(int idx, llvm::Value *indIdx) -{ - m_numConsts = ((idx + 1) > m_numConsts) ? (idx + 1) : m_numConsts; - - Value *elem = element(ConstsArg, idx, indIdx); - LoadInst *load = new LoadInst(elem, name("const"), false, m_block); - load->setAlignment(8); - return load; -} - -llvm::Value *Storage::shuffleVector(llvm::Value *vec, int shuffle) -{ - Constant *mask = shuffleMask(shuffle); - ShuffleVectorInst *res = - new ShuffleVectorInst(vec, m_extSwizzleVec, mask, - name("shuffle"), m_block); - return res; -} - - -llvm::Value *Storage::tempElement(int idx, llvm::Value *indIdx) -{ - Value *elem = element(TempsArg, idx, indIdx); - - LoadInst *load = new LoadInst(elem, name("temp"), false, m_block); - load->setAlignment(8); - - return load; -} - -void Storage::setTempElement(int idx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = 0; - if (m_tempWriteMap[idx]) - templ = tempElement(idx); - val = maskWrite(val, mask, templ); - } - Value *elem = element(TempsArg, idx); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); - m_tempWriteMap[idx] = true; -} - -void Storage::setOutputElement(int dstIdx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = 0; - if (m_destWriteMap[dstIdx]) - templ = outputElement(dstIdx); - val = maskWrite(val, mask, templ); - } - - Value *elem = element(DestsArg, dstIdx); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); - m_destWriteMap[dstIdx] = true; -} - -llvm::Value *Storage::maskWrite(llvm::Value *src, int mask, llvm::Value *templ) -{ - llvm::Value *dst = templ; - if (!dst) - dst = Constant::getNullValue(m_floatVecType); - if ((mask & TGSI_WRITEMASK_X)) { - llvm::Value *x = new ExtractElementInst(src, unsigned(0), - name("x"), m_block); - dst = new InsertElementInst(dst, x, unsigned(0), - name("dstx"), m_block); - } - if ((mask & TGSI_WRITEMASK_Y)) { - llvm::Value *y = new ExtractElementInst(src, unsigned(1), - name("y"), m_block); - dst = new InsertElementInst(dst, y, unsigned(1), - name("dsty"), m_block); - } - if ((mask & TGSI_WRITEMASK_Z)) { - llvm::Value *z = new ExtractElementInst(src, unsigned(2), - name("z"), m_block); - dst = new InsertElementInst(dst, z, unsigned(2), - name("dstz"), m_block); - } - if ((mask & TGSI_WRITEMASK_W)) { - llvm::Value *w = new ExtractElementInst(src, unsigned(3), - name("w"), m_block); - dst = new InsertElementInst(dst, w, unsigned(3), - name("dstw"), m_block); - } - return dst; -} - -const char * Storage::name(const char *prefix) -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -int Storage::numConsts() const -{ - return m_numConsts; -} - -llvm::Value * Storage::addrElement(int idx) const -{ - Value *ret = m_addrs[idx]; - if (!ret) - return m_undefFloatVec; - return ret; -} - -void Storage::setAddrElement(int idx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = m_addrs[idx]; - val = maskWrite(val, mask, templ); - } - m_addrs[idx] = val; -} - -llvm::Value * Storage::extractIndex(llvm::Value *vec) -{ - llvm::Value *x = new ExtractElementInst(vec, unsigned(0), - name("x"), m_block); - return new FPToSIInst(x, IntegerType::get(32), name("intidx"), m_block); -} - -void Storage::setCurrentBlock(llvm::BasicBlock *block) -{ - m_block = block; -} - -llvm::Value * Storage::outputElement(int idx, llvm::Value *indIdx) -{ - Value *elem = element(DestsArg, idx, indIdx); - LoadInst *load = new LoadInst(elem, name("output"), false, m_block); - load->setAlignment(8); - - return load; -} - -llvm::Value * Storage::inputPtr() const -{ - return m_INPUT; -} - -void Storage::pushArguments(llvm::Value *input) -{ - m_argStack.push(m_INPUT); - - m_INPUT = input; -} - -void Storage::popArguments() -{ - m_INPUT = m_argStack.top(); - m_argStack.pop(); -} - -void Storage::pushTemps() -{ - m_extSwizzleVec = 0; -} - -void Storage::popTemps() -{ -} - -llvm::Value * Storage::immediateElement(int idx) -{ - return m_immediates[idx]; -} - -void Storage::addImmediate(float *val) -{ - std::vector vec(4); - vec[0] = ConstantFP::get(Type::FloatTy, APFloat(val[0])); - vec[1] = ConstantFP::get(Type::FloatTy, APFloat(val[1])); - vec[2] = ConstantFP::get(Type::FloatTy, APFloat(val[2])); - vec[3] = ConstantFP::get(Type::FloatTy, APFloat(val[3])); - m_immediates.push_back(ConstantVector::get(m_floatVecType, vec)); -} - - -llvm::Value * Storage::elemPtr(Args arg) -{ - std::vector indices; - indices.push_back(constantInt(0)); - indices.push_back(constantInt(static_cast(arg))); - GetElementPtrInst *getElem = new GetElementPtrInst(m_INPUT, - indices.begin(), - indices.end(), - name("input_ptr"), - m_block); - return new LoadInst(getElem, name("input_field"), false, m_block); -} - -llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, - llvm::Value *indIdx ) -{ - GetElementPtrInst *getElem = 0; - - if (indIdx) { - getElem = new GetElementPtrInst(ptr, - BinaryOperator::create(Instruction::Add, - indIdx, - constantInt(idx), - name("add"), - m_block), - name("field"), - m_block); - } else { - getElem = new GetElementPtrInst(ptr, - constantInt(idx), - name("field"), - m_block); - } - return getElem; -} - -llvm::Value * Storage::element(Args arg, int idx, llvm::Value *indIdx ) -{ - Value *val = elemPtr(arg); - return elemIdx(val, idx, indIdx); -} - -void Storage::setKilElement(llvm::Value *val) -{ - std::vector indices; - indices.push_back(constantInt(0)); - indices.push_back(constantInt(static_cast(KilArg))); - GetElementPtrInst *elem = new GetElementPtrInst(m_INPUT, - indices.begin(), - indices.end(), - name("kil_ptr"), - m_block); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); -} - -#endif //MESA_LLVM - - diff --git a/src/gallium/aux/llvm/storage.h b/src/gallium/aux/llvm/storage.h deleted file mode 100644 index 8574f7554e..0000000000 --- a/src/gallium/aux/llvm/storage.h +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef STORAGE_H -#define STORAGE_H - -#include -#include -#include -#include - -namespace llvm { - class BasicBlock; - class Constant; - class ConstantInt; - class LoadInst; - class Value; - class VectorType; -} - -class Storage -{ -public: - Storage(llvm::BasicBlock *block, - llvm::Value *input); - - llvm::Value *inputPtr() const; - - void setCurrentBlock(llvm::BasicBlock *block); - - llvm::ConstantInt *constantInt(int); - llvm::Constant *shuffleMask(int vec); - llvm::Value *inputElement(int idx, llvm::Value *indIdx =0); - llvm::Value *constElement(int idx, llvm::Value *indIdx =0); - llvm::Value *outputElement(int idx, llvm::Value *indIdx =0); - llvm::Value *tempElement(int idx, llvm::Value *indIdx =0); - llvm::Value *immediateElement(int idx); - - void setOutputElement(int dstIdx, llvm::Value *val, int mask); - void setTempElement(int idx, llvm::Value *val, int mask); - - llvm::Value *addrElement(int idx) const; - void setAddrElement(int idx, llvm::Value *val, int mask); - - void setKilElement(llvm::Value *val); - - llvm::Value *shuffleVector(llvm::Value *vec, int shuffle); - - llvm::Value *extractIndex(llvm::Value *vec); - - int numConsts() const; - - void pushArguments(llvm::Value *input); - void popArguments(); - void pushTemps(); - void popTemps(); - - void addImmediate(float *val); - -private: - llvm::Value *maskWrite(llvm::Value *src, int mask, llvm::Value *templ); - const char *name(const char *prefix); - - enum Args { - DestsArg = 0, - InputsArg = 1, - TempsArg = 2, - ConstsArg = 3, - KilArg = 4 - }; - llvm::Value *elemPtr(Args arg); - llvm::Value *elemIdx(llvm::Value *ptr, int idx, - llvm::Value *indIdx = 0); - llvm::Value *element(Args arg, int idx, llvm::Value *indIdx = 0); - -private: - llvm::BasicBlock *m_block; - llvm::Value *m_INPUT; - - std::map m_constInts; - std::map m_intVecs; - std::vector m_addrs; - std::vector m_immediates; - - llvm::VectorType *m_floatVecType; - llvm::VectorType *m_intVecType; - - char m_name[32]; - int m_idx; - - int m_numConsts; - - std::map m_destWriteMap; - std::map m_tempWriteMap; - - llvm::Value *m_undefFloatVec; - llvm::Value *m_undefIntVec; - llvm::Value *m_extSwizzleVec; - - std::stack m_argStack; - std::stack > m_tempStack; -}; - -#endif diff --git a/src/gallium/aux/llvm/storagesoa.cpp b/src/gallium/aux/llvm/storagesoa.cpp deleted file mode 100644 index ed0674a96f..0000000000 --- a/src/gallium/aux/llvm/storagesoa.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "storagesoa.h" - -#include "gallivm_p.h" - -#include "pipe/p_shader_tokens.h" -#include "pipe/p_debug.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace llvm; - - -StorageSoa::StorageSoa(llvm::BasicBlock *block, - llvm::Value *input, - llvm::Value *output, - llvm::Value *consts, - llvm::Value *temps) - : m_block(block), - m_input(input), - m_output(output), - m_consts(consts), - m_temps(temps), - m_immediates(0), - m_idx(0) -{ -} - -void StorageSoa::addImmediate(float *vec) -{ - std::vector vals(4); - vals[0] = vec[0]; - vals[1] = vec[1]; - vals[2] = vec[2]; - vals[3] = vec[3]; - m_immediatesToFlush.push_back(vals); -} - -void StorageSoa::declareImmediates() -{ - if (m_immediatesToFlush.empty()) - return; - - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - ArrayType *vectorChannels = ArrayType::get(vectorType, 4); - ArrayType *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size()); - - m_immediates = new GlobalVariable( - /*Type=*/arrayType, - /*isConstant=*/false, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name("immediates"), - currentModule()); - - std::vector arrayVals; - for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) { - std::vector vec = m_immediatesToFlush[i]; - std::vector vals(4); - std::vector channelArray; - - vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0]; - llvm::Constant *xChannel = createConstGlobalVector(vals); - - vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1]; - llvm::Constant *yChannel = createConstGlobalVector(vals); - - vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2]; - llvm::Constant *zChannel = createConstGlobalVector(vals); - - vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3]; - llvm::Constant *wChannel = createConstGlobalVector(vals); - channelArray.push_back(xChannel); - channelArray.push_back(yChannel); - channelArray.push_back(zChannel); - channelArray.push_back(wChannel); - Constant *constChannels = ConstantArray::get(vectorChannels, - channelArray); - arrayVals.push_back(constChannels); - } - Constant *constArray = ConstantArray::get(arrayType, arrayVals); - m_immediates->setInitializer(constArray); - - m_immediatesToFlush.clear(); -} - -llvm::Value *StorageSoa::addrElement(int idx) const -{ - std::map::const_iterator itr = m_addresses.find(idx); - if (itr == m_addresses.end()) { - debug_printf("Trying to access invalid shader 'address'\n"); - return 0; - } - llvm::Value * res = (*itr).second; - - res = new LoadInst(res, name("addr"), false, m_block); - - return res; -} - -std::vector StorageSoa::inputElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_input, idx, 0); - res[1] = element(m_input, idx, 1); - res[2] = element(m_input, idx, 2); - res[3] = element(m_input, idx, 3); - - return res; -} - -std::vector StorageSoa::constElement(llvm::Value *idx) -{ - std::vector res(4); - llvm::Value *xChannel, *yChannel, *zChannel, *wChannel; - - xChannel = elementPointer(m_consts, idx, 0); - yChannel = elementPointer(m_consts, idx, 1); - zChannel = elementPointer(m_consts, idx, 2); - wChannel = elementPointer(m_consts, idx, 3); - - res[0] = alignedArrayLoad(xChannel); - res[1] = alignedArrayLoad(yChannel); - res[2] = alignedArrayLoad(zChannel); - res[3] = alignedArrayLoad(wChannel); - - return res; -} - -std::vector StorageSoa::outputElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_output, idx, 0); - res[1] = element(m_output, idx, 1); - res[2] = element(m_output, idx, 2); - res[3] = element(m_output, idx, 3); - - return res; -} - -std::vector StorageSoa::tempElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_temps, idx, 0); - res[1] = element(m_temps, idx, 1); - res[2] = element(m_temps, idx, 2); - res[3] = element(m_temps, idx, 3); - - return res; -} - -std::vector StorageSoa::immediateElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_immediates, idx, 0); - res[1] = element(m_immediates, idx, 1); - res[2] = element(m_immediates, idx, 2); - res[3] = element(m_immediates, idx, 3); - - return res; -} - -llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, llvm::Value *index, - int channel) const -{ - std::vector indices; - if (m_immediates == ptr) - indices.push_back(constantInt(0)); - indices.push_back(index); - indices.push_back(constantInt(channel)); - - GetElementPtrInst *getElem = new GetElementPtrInst(ptr, - indices.begin(), - indices.end(), - name("ptr"), - m_block); - return getElem; -} - -llvm::Value * StorageSoa::element(llvm::Value *ptr, llvm::Value *index, - int channel) const -{ - llvm::Value *res = elementPointer(ptr, index, channel); - LoadInst *load = new LoadInst(res, name("element"), false, m_block); - //load->setAlignment(8); - return load; -} - -const char * StorageSoa::name(const char *prefix) const -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::ConstantInt * StorageSoa::constantInt(int idx) const -{ - if (m_constInts.find(idx) != m_constInts.end()) { - return m_constInts[idx]; - } - ConstantInt *constInt = ConstantInt::get(APInt(32, idx)); - m_constInts[idx] = constInt; - return constInt; -} - -llvm::Value *StorageSoa::alignedArrayLoad(llvm::Value *val) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - PointerType *vectorPtr = PointerType::get(vectorType, 0); - - CastInst *cast = new BitCastInst(val, vectorPtr, name("toVector"), m_block); - LoadInst *load = new LoadInst(cast, name("alignLoad"), false, m_block); - load->setAlignment(8); - return load; -} - -llvm::Module * StorageSoa::currentModule() const -{ - if (!m_block || !m_block->getParent()) - return 0; - - return m_block->getParent()->getParent(); -} - -llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &vec) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - std::vector immValues; - ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0])); - ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1])); - ConstantFP *constz = ConstantFP::get(Type::FloatTy, APFloat(vec[2])); - ConstantFP *constw = ConstantFP::get(Type::FloatTy, APFloat(vec[3])); - immValues.push_back(constx); - immValues.push_back(consty); - immValues.push_back(constz); - immValues.push_back(constw); - Constant *constVector = ConstantVector::get(vectorType, immValues); - - return constVector; -} - -std::vector StorageSoa::load(Argument type, int idx, int swizzle, - llvm::Value *indIdx) -{ - std::vector val(4); - - //if we have an indirect index, always use that - // if not use the integer offset to create one - llvm::Value *realIndex = 0; - if (indIdx) - realIndex = indIdx; - else - realIndex = constantInt(idx); - debug_printf("XXXXXXXXX realIdx = %p, indIdx = %p\n", realIndex, indIdx); - - switch(type) { - case Input: - val = inputElement(realIndex); - break; - case Output: - val = outputElement(realIndex); - break; - case Temp: - val = tempElement(realIndex); - break; - case Const: - val = constElement(realIndex); - break; - case Immediate: - val = immediateElement(realIndex); - break; - case Address: - debug_printf("Address not handled in the load phase!\n"); - assert(0); - break; - } - if (!gallivm_is_swizzle(swizzle)) - return val; - - std::vector res(4); - - res[0] = val[gallivm_x_swizzle(swizzle)]; - res[1] = val[gallivm_y_swizzle(swizzle)]; - res[2] = val[gallivm_z_swizzle(swizzle)]; - res[3] = val[gallivm_w_swizzle(swizzle)]; - return res; -} - -void StorageSoa::store(Argument type, int idx, const std::vector &val, - int mask) -{ - llvm::Value *out = 0; - switch(type) { - case Output: - out = m_output; - break; - case Temp: - out = m_temps; - break; - case Input: - out = m_input; - break; - case Address: { - llvm::Value *addr = m_addresses[idx]; - if (!addr) { - addAddress(idx); - addr = m_addresses[idx]; - assert(addr); - } - new StoreInst(val[0], addr, false, m_block); - return; - break; - } - default: - debug_printf("Can't save output of this type: %d !\n", type); - assert(0); - break; - } - llvm::Value *realIndex = constantInt(idx); - if ((mask & TGSI_WRITEMASK_X)) { - llvm::Value *xChannel = elementPointer(out, realIndex, 0); - new StoreInst(val[0], xChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_Y)) { - llvm::Value *yChannel = elementPointer(out, realIndex, 1); - new StoreInst(val[1], yChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_Z)) { - llvm::Value *zChannel = elementPointer(out, realIndex, 2); - new StoreInst(val[2], zChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_W)) { - llvm::Value *wChannel = elementPointer(out, realIndex, 3); - new StoreInst(val[3], wChannel, false, m_block); - } -} - -void StorageSoa::addAddress(int idx) -{ - GlobalVariable *val = new GlobalVariable( - /*Type=*/IntegerType::get(32), - /*isConstant=*/false, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name("address"), - currentModule()); - val->setInitializer(Constant::getNullValue(IntegerType::get(32))); - - debug_printf("adding to %d\n", idx); - m_addresses[idx] = val; -} diff --git a/src/gallium/aux/llvm/storagesoa.h b/src/gallium/aux/llvm/storagesoa.h deleted file mode 100644 index 6443351f27..0000000000 --- a/src/gallium/aux/llvm/storagesoa.h +++ /dev/null @@ -1,111 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef STORAGESOA_H -#define STORAGESOA_H - -#include -#include -#include - -namespace llvm { - class BasicBlock; - class Constant; - class ConstantInt; - class GlobalVariable; - class LoadInst; - class Value; - class VectorType; - class Module; -} - -class StorageSoa -{ -public: - enum Argument { - Input, - Output, - Temp, - Const, - Immediate, - Address - }; -public: - StorageSoa(llvm::BasicBlock *block, - llvm::Value *input, - llvm::Value *output, - llvm::Value *consts, - llvm::Value *temps); - - - std::vector load(Argument type, int idx, int swizzle, - llvm::Value *indIdx =0); - void store(Argument type, int idx, const std::vector &val, - int mask); - - void addImmediate(float *vec); - void declareImmediates(); - - void addAddress(int idx); - - llvm::Value * addrElement(int idx) const; - - llvm::ConstantInt *constantInt(int) const; -private: - llvm::Value *elementPointer(llvm::Value *ptr, llvm::Value *indIdx, - int channel) const; - llvm::Value *element(llvm::Value *ptr, llvm::Value *idx, - int channel) const; - const char *name(const char *prefix) const; - llvm::Value *alignedArrayLoad(llvm::Value *val); - llvm::Module *currentModule() const; - llvm::Constant *createConstGlobalVector(const std::vector &vec); - - std::vector inputElement(llvm::Value *indIdx); - std::vector constElement(llvm::Value *indIdx); - std::vector outputElement(llvm::Value *indIdx); - std::vector tempElement(llvm::Value *indIdx); - std::vector immediateElement(llvm::Value *indIdx); -private: - llvm::BasicBlock *m_block; - - llvm::Value *m_input; - llvm::Value *m_output; - llvm::Value *m_consts; - llvm::Value *m_temps; - llvm::GlobalVariable *m_immediates; - - std::map m_addresses; - - std::vector > m_immediatesToFlush; - - mutable std::map m_constInts; - mutable char m_name[32]; - mutable int m_idx; -}; - -#endif diff --git a/src/gallium/aux/llvm/tgsitollvm.cpp b/src/gallium/aux/llvm/tgsitollvm.cpp deleted file mode 100644 index 2cb4acce32..0000000000 --- a/src/gallium/aux/llvm/tgsitollvm.cpp +++ /dev/null @@ -1,1221 +0,0 @@ -#include "tgsitollvm.h" - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "storage.h" -#include "instructions.h" -#include "storagesoa.h" -#include "instructionssoa.h" - -#include "pipe/p_shader_tokens.h" - -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_util.h" -#include "tgsi/util/tgsi_build.h" -#include "tgsi/util/tgsi_dump.h" - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include - -using namespace llvm; - -static inline FunctionType *vertexShaderFunctionType() -{ - //Function takes three arguments, - // the calling code has to make sure the types it will - // pass are castable to the following: - // [4 x <4 x float>] inputs, - // [4 x <4 x float>] output, - // [4 x [4 x float]] consts, - // [4 x <4 x float>] temps - - std::vector funcArgs; - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - ArrayType *vectorArray = ArrayType::get(vectorType, 4); - PointerType *vectorArrayPtr = PointerType::get(vectorArray, 0); - - ArrayType *floatArray = ArrayType::get(Type::FloatTy, 4); - ArrayType *constsArray = ArrayType::get(floatArray, 4); - PointerType *constsArrayPtr = PointerType::get(constsArray, 0); - - funcArgs.push_back(vectorArrayPtr);//inputs - funcArgs.push_back(vectorArrayPtr);//output - funcArgs.push_back(constsArrayPtr);//consts - funcArgs.push_back(vectorArrayPtr);//temps - - FunctionType *functionType = FunctionType::get( - /*Result=*/Type::VoidTy, - /*Params=*/funcArgs, - /*isVarArg=*/false); - - return functionType; -} - -static inline void -add_interpolator(struct gallivm_ir *ir, - struct gallivm_interpolate *interp) -{ - ir->interpolators[ir->num_interp] = *interp; - ++ir->num_interp; -} - -static void -translate_declaration(struct gallivm_ir *prog, - llvm::Module *module, - Storage *storage, - struct tgsi_full_declaration *decl, - struct tgsi_full_declaration *fd) -{ - if (decl->Declaration.File == TGSI_FILE_INPUT) { - unsigned first, last, mask; - uint interp_method; - - assert(decl->Declaration.Declare == TGSI_DECLARE_RANGE); - - first = decl->u.DeclarationRange.First; - last = decl->u.DeclarationRange.Last; - mask = decl->Declaration.UsageMask; - - /* Do not touch WPOS.xy */ - if (first == 0) { - mask &= ~TGSI_WRITEMASK_XY; - if (mask == TGSI_WRITEMASK_NONE) { - first++; - if (first > last) { - return; - } - } - } - - interp_method = decl->Interpolation.Interpolate; - - if (mask == TGSI_WRITEMASK_XYZW) { - unsigned i, j; - - for (i = first; i <= last; i++) { - for (j = 0; j < NUM_CHANNELS; j++) { - //interp( mach, i, j ); - struct gallivm_interpolate interp; - interp.type = interp_method; - interp.attrib = i; - interp.chan = j; - add_interpolator(prog, &interp); - } - } - } else { - unsigned i, j; - for( j = 0; j < NUM_CHANNELS; j++ ) { - if( mask & (1 << j) ) { - for( i = first; i <= last; i++ ) { - struct gallivm_interpolate interp; - interp.type = interp_method; - interp.attrib = i; - interp.chan = j; - add_interpolator(prog, &interp); - } - } - } - } - } -} - -static void -translate_declarationir(struct gallivm_ir *, - llvm::Module *, - StorageSoa *storage, - struct tgsi_full_declaration *decl, - struct tgsi_full_declaration *) -{ - if (decl->Declaration.File == TGSI_FILE_ADDRESS) { - int idx = decl->u.DeclarationRange.First; - storage->addAddress(idx); - } -} - -static void -translate_immediate(Storage *storage, - struct tgsi_full_immediate *imm) -{ - float vec[4]; - int i; - for (i = 0; i < imm->Immediate.Size - 1; ++i) { - switch (imm->Immediate.DataType) { - case TGSI_IMM_FLOAT32: - vec[i] = imm->u.ImmediateFloat32[i].Float; - break; - default: - assert(0); - } - } - storage->addImmediate(vec); -} - - -static void -translate_immediateir(StorageSoa *storage, - struct tgsi_full_immediate *imm) -{ - float vec[4]; - int i; - for (i = 0; i < imm->Immediate.Size - 1; ++i) { - switch (imm->Immediate.DataType) { - case TGSI_IMM_FLOAT32: - vec[i] = imm->u.ImmediateFloat32[i].Float; - break; - default: - assert(0); - } - } - storage->addImmediate(vec); -} - -static inline int -swizzleInt(struct tgsi_full_src_register *src) -{ - int swizzle = 0; - int start = 1000; - - for (int k = 0; k < 4; ++k) { - swizzle += tgsi_util_get_full_src_register_extswizzle(src, k) * start; - start /= 10; - } - return swizzle; -} - -static inline llvm::Value * -swizzleVector(llvm::Value *val, struct tgsi_full_src_register *src, - Storage *storage) -{ - int swizzle = swizzleInt(src); - - if (gallivm_is_swizzle(swizzle)) { - /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/ - val = storage->shuffleVector(val, swizzle); - } - return val; -} - -static void -translate_instruction(llvm::Module *module, - Storage *storage, - Instructions *instr, - struct tgsi_full_instruction *inst, - struct tgsi_full_instruction *fi, - unsigned instno) -{ - llvm::Value *inputs[4]; - inputs[0] = 0; - inputs[1] = 0; - inputs[2] = 0; - inputs[3] = 0; - - for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - llvm::Value *val = 0; - llvm::Value *indIdx = 0; - - if (src->SrcRegister.Indirect) { - indIdx = storage->addrElement(src->SrcRegisterInd.Index); - indIdx = storage->extractIndex(indIdx); - } - if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { - val = storage->constElement(src->SrcRegister.Index, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { - val = storage->inputElement(src->SrcRegister.Index, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { - val = storage->tempElement(src->SrcRegister.Index); - } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { - val = storage->outputElement(src->SrcRegister.Index, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { - val = storage->immediateElement(src->SrcRegister.Index); - } else { - fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); - return; - } - - inputs[i] = swizzleVector(val, src, storage); - } - - /*if (inputs[0]) - instr->printVector(inputs[0]); - if (inputs[1]) - instr->printVector(inputs[1]);*/ - llvm::Value *out = 0; - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_ARL: { - out = instr->arl(inputs[0]); - } - break; - case TGSI_OPCODE_MOV: { - out = inputs[0]; - } - break; - case TGSI_OPCODE_LIT: { - out = instr->lit(inputs[0]); - } - break; - case TGSI_OPCODE_RCP: { - out = instr->rcp(inputs[0]); - } - break; - case TGSI_OPCODE_RSQ: { - out = instr->rsq(inputs[0]); - } - break; - case TGSI_OPCODE_EXP: - break; - case TGSI_OPCODE_LOG: - break; - case TGSI_OPCODE_MUL: { - out = instr->mul(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_ADD: { - out = instr->add(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP3: { - out = instr->dp3(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP4: { - out = instr->dp4(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DST: { - out = instr->dst(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MIN: { - out = instr->min(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MAX: { - out = instr->max(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SLT: { - out = instr->slt(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SGE: { - out = instr->sge(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MAD: { - out = instr->madd(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SUB: { - out = instr->sub(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_LERP: { - out = instr->lerp(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_CND: - break; - case TGSI_OPCODE_CND0: - break; - case TGSI_OPCODE_DOT2ADD: - break; - case TGSI_OPCODE_INDEX: - break; - case TGSI_OPCODE_NEGATE: - break; - case TGSI_OPCODE_FRAC: { - out = instr->frc(inputs[0]); - } - break; - case TGSI_OPCODE_CLAMP: - break; - case TGSI_OPCODE_FLOOR: { - out = instr->floor(inputs[0]); - } - break; - case TGSI_OPCODE_ROUND: - break; - case TGSI_OPCODE_EXPBASE2: { - out = instr->ex2(inputs[0]); - } - break; - case TGSI_OPCODE_LOGBASE2: { - out = instr->lg2(inputs[0]); - } - break; - case TGSI_OPCODE_POWER: { - out = instr->pow(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_CROSSPRODUCT: { - out = instr->cross(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MULTIPLYMATRIX: - break; - case TGSI_OPCODE_ABS: { - out = instr->abs(inputs[0]); - } - break; - case TGSI_OPCODE_RCC: - break; - case TGSI_OPCODE_DPH: { - out = instr->dph(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_COS: { - out = instr->cos(inputs[0]); - } - break; - case TGSI_OPCODE_DDX: - break; - case TGSI_OPCODE_DDY: - break; - case TGSI_OPCODE_KILP: { - out = instr->kilp(inputs[0]); - storage->setKilElement(out); - return; - } - break; - case TGSI_OPCODE_PK2H: - break; - case TGSI_OPCODE_PK2US: - break; - case TGSI_OPCODE_PK4B: - break; - case TGSI_OPCODE_PK4UB: - break; - case TGSI_OPCODE_RFL: - break; - case TGSI_OPCODE_SEQ: - break; - case TGSI_OPCODE_SFL: - break; - case TGSI_OPCODE_SGT: { - out = instr->sgt(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SIN: { - out = instr->sin(inputs[0]); - } - break; - case TGSI_OPCODE_SLE: - break; - case TGSI_OPCODE_SNE: - break; - case TGSI_OPCODE_STR: - break; - case TGSI_OPCODE_TEX: - break; - case TGSI_OPCODE_TXD: - break; - case TGSI_OPCODE_UP2H: - break; - case TGSI_OPCODE_UP2US: - break; - case TGSI_OPCODE_UP4B: - break; - case TGSI_OPCODE_UP4UB: - break; - case TGSI_OPCODE_X2D: - break; - case TGSI_OPCODE_ARA: - break; - case TGSI_OPCODE_ARR: - break; - case TGSI_OPCODE_BRA: - break; - case TGSI_OPCODE_CAL: { - instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr()); - return; - } - break; - case TGSI_OPCODE_RET: { - instr->end(); - return; - } - break; - case TGSI_OPCODE_SSG: - break; - case TGSI_OPCODE_CMP: { - out = instr->cmp(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SCS: { - out = instr->scs(inputs[0]); - } - break; - case TGSI_OPCODE_TXB: - break; - case TGSI_OPCODE_NRM: - break; - case TGSI_OPCODE_DIV: - break; - case TGSI_OPCODE_DP2: - break; - case TGSI_OPCODE_TXL: - break; - case TGSI_OPCODE_BRK: { - instr->brk(); - return; - } - break; - case TGSI_OPCODE_IF: { - instr->ifop(inputs[0]); - storage->setCurrentBlock(instr->currentBlock()); - return; //just update the state - } - break; - case TGSI_OPCODE_LOOP: - break; - case TGSI_OPCODE_REP: - break; - case TGSI_OPCODE_ELSE: { - instr->elseop(); - storage->setCurrentBlock(instr->currentBlock()); - return; //only state update - } - break; - case TGSI_OPCODE_ENDIF: { - instr->endif(); - storage->setCurrentBlock(instr->currentBlock()); - return; //just update the state - } - break; - case TGSI_OPCODE_ENDLOOP: - break; - case TGSI_OPCODE_ENDREP: - break; - case TGSI_OPCODE_PUSHA: - break; - case TGSI_OPCODE_POPA: - break; - case TGSI_OPCODE_CEIL: - break; - case TGSI_OPCODE_I2F: - break; - case TGSI_OPCODE_NOT: - break; - case TGSI_OPCODE_TRUNC: { - out = instr->trunc(inputs[0]); - } - break; - case TGSI_OPCODE_SHL: - break; - case TGSI_OPCODE_SHR: - break; - case TGSI_OPCODE_AND: - break; - case TGSI_OPCODE_OR: - break; - case TGSI_OPCODE_MOD: - break; - case TGSI_OPCODE_XOR: - break; - case TGSI_OPCODE_SAD: - break; - case TGSI_OPCODE_TXF: - break; - case TGSI_OPCODE_TXQ: - break; - case TGSI_OPCODE_CONT: - break; - case TGSI_OPCODE_EMIT: - break; - case TGSI_OPCODE_ENDPRIM: - break; - case TGSI_OPCODE_BGNLOOP2: { - instr->beginLoop(); - storage->setCurrentBlock(instr->currentBlock()); - return; - } - break; - case TGSI_OPCODE_BGNSUB: { - instr->bgnSub(instno); - storage->setCurrentBlock(instr->currentBlock()); - storage->pushTemps(); - return; - } - break; - case TGSI_OPCODE_ENDLOOP2: { - instr->endLoop(); - storage->setCurrentBlock(instr->currentBlock()); - return; - } - break; - case TGSI_OPCODE_ENDSUB: { - instr->endSub(); - storage->setCurrentBlock(instr->currentBlock()); - storage->popArguments(); - storage->popTemps(); - return; - } - break; - case TGSI_OPCODE_NOISE1: - break; - case TGSI_OPCODE_NOISE2: - break; - case TGSI_OPCODE_NOISE3: - break; - case TGSI_OPCODE_NOISE4: - break; - case TGSI_OPCODE_NOP: - break; - case TGSI_OPCODE_TEXBEM: - break; - case TGSI_OPCODE_TEXBEML: - break; - case TGSI_OPCODE_TEXREG2AR: - break; - case TGSI_OPCODE_TEXM3X2PAD: - break; - case TGSI_OPCODE_TEXM3X2TEX: - break; - case TGSI_OPCODE_TEXM3X3PAD: - break; - case TGSI_OPCODE_TEXM3X3TEX: - break; - case TGSI_OPCODE_TEXM3X3SPEC: - break; - case TGSI_OPCODE_TEXM3X3VSPEC: - break; - case TGSI_OPCODE_TEXREG2GB: - break; - case TGSI_OPCODE_TEXREG2RGB: - break; - case TGSI_OPCODE_TEXDP3TEX: - break; - case TGSI_OPCODE_TEXDP3: - break; - case TGSI_OPCODE_TEXM3X3: - break; - case TGSI_OPCODE_TEXM3X2DEPTH: - break; - case TGSI_OPCODE_TEXDEPTH: - break; - case TGSI_OPCODE_BEM: - break; - case TGSI_OPCODE_M4X3: - break; - case TGSI_OPCODE_M3X4: - break; - case TGSI_OPCODE_M3X3: - break; - case TGSI_OPCODE_M3X2: - break; - case TGSI_OPCODE_NRM4: - break; - case TGSI_OPCODE_CALLNZ: - break; - case TGSI_OPCODE_IFC: - break; - case TGSI_OPCODE_BREAKC: - break; - case TGSI_OPCODE_KIL: - break; - case TGSI_OPCODE_END: - instr->end(); - return; - break; - default: - fprintf(stderr, "ERROR: Unknown opcode %d\n", - inst->Instruction.Opcode); - assert(0); - break; - } - - if (!out) { - fprintf(stderr, "ERROR: unsupported opcode %d\n", - inst->Instruction.Opcode); - assert(!"Unsupported opcode"); - } - - /* # not sure if we need this */ - switch( inst->Instruction.Saturate ) { - case TGSI_SAT_NONE: - break; - case TGSI_SAT_ZERO_ONE: - /*TXT( "_SAT" );*/ - break; - case TGSI_SAT_MINUS_PLUS_ONE: - /*TXT( "_SAT[-1,1]" );*/ - break; - default: - assert( 0 ); - } - - /* store results */ - for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - - if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { - storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { - storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { - storage->setAddrElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else { - fprintf(stderr, "ERROR: unsupported LLVM destination!"); - assert(!"wrong destination"); - } - } -} - - -static void -translate_instructionir(llvm::Module *module, - StorageSoa *storage, - InstructionsSoa *instr, - struct tgsi_full_instruction *inst, - struct tgsi_full_instruction *fi, - unsigned instno) -{ - std::vector< std::vector > inputs(inst->Instruction.NumSrcRegs); - - for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - std::vector val; - llvm::Value *indIdx = 0; - int swizzle = swizzleInt(src); - - if (src->SrcRegister.Indirect) { - indIdx = storage->addrElement(src->SrcRegisterInd.Index); - } - if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { - val = storage->load(StorageSoa::Const, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { - val = storage->load(StorageSoa::Input, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { - val = storage->load(StorageSoa::Temp, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { - val = storage->load(StorageSoa::Output, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { - val = storage->load(StorageSoa::Immediate, - src->SrcRegister.Index, swizzle, indIdx); - } else { - fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); - return; - } - - inputs[i] = val; - } - - std::vector out(4); - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_ARL: { - out = instr->arl(inputs[0]); - } - break; - case TGSI_OPCODE_MOV: { - out = inputs[0]; - } - break; - case TGSI_OPCODE_LIT: { - } - break; - case TGSI_OPCODE_RCP: { - } - break; - case TGSI_OPCODE_RSQ: { - } - break; - case TGSI_OPCODE_EXP: - break; - case TGSI_OPCODE_LOG: - break; - case TGSI_OPCODE_MUL: { - out = instr->mul(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_ADD: { - out = instr->add(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP3: { - } - break; - case TGSI_OPCODE_DP4: { - } - break; - case TGSI_OPCODE_DST: { - } - break; - case TGSI_OPCODE_MIN: { - } - break; - case TGSI_OPCODE_MAX: { - } - break; - case TGSI_OPCODE_SLT: { - } - break; - case TGSI_OPCODE_SGE: { - } - break; - case TGSI_OPCODE_MAD: { - out = instr->madd(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SUB: { - } - break; - case TGSI_OPCODE_LERP: { - } - break; - case TGSI_OPCODE_CND: - break; - case TGSI_OPCODE_CND0: - break; - case TGSI_OPCODE_DOT2ADD: - break; - case TGSI_OPCODE_INDEX: - break; - case TGSI_OPCODE_NEGATE: - break; - case TGSI_OPCODE_FRAC: { - } - break; - case TGSI_OPCODE_CLAMP: - break; - case TGSI_OPCODE_FLOOR: { - } - break; - case TGSI_OPCODE_ROUND: - break; - case TGSI_OPCODE_EXPBASE2: { - } - break; - case TGSI_OPCODE_LOGBASE2: { - } - break; - case TGSI_OPCODE_POWER: { - } - break; - case TGSI_OPCODE_CROSSPRODUCT: { - } - break; - case TGSI_OPCODE_MULTIPLYMATRIX: - break; - case TGSI_OPCODE_ABS: { - } - break; - case TGSI_OPCODE_RCC: - break; - case TGSI_OPCODE_DPH: { - } - break; - case TGSI_OPCODE_COS: { - } - break; - case TGSI_OPCODE_DDX: - break; - case TGSI_OPCODE_DDY: - break; - case TGSI_OPCODE_KILP: { - } - break; - case TGSI_OPCODE_PK2H: - break; - case TGSI_OPCODE_PK2US: - break; - case TGSI_OPCODE_PK4B: - break; - case TGSI_OPCODE_PK4UB: - break; - case TGSI_OPCODE_RFL: - break; - case TGSI_OPCODE_SEQ: - break; - case TGSI_OPCODE_SFL: - break; - case TGSI_OPCODE_SGT: { - } - break; - case TGSI_OPCODE_SIN: { - } - break; - case TGSI_OPCODE_SLE: - break; - case TGSI_OPCODE_SNE: - break; - case TGSI_OPCODE_STR: - break; - case TGSI_OPCODE_TEX: - break; - case TGSI_OPCODE_TXD: - break; - case TGSI_OPCODE_UP2H: - break; - case TGSI_OPCODE_UP2US: - break; - case TGSI_OPCODE_UP4B: - break; - case TGSI_OPCODE_UP4UB: - break; - case TGSI_OPCODE_X2D: - break; - case TGSI_OPCODE_ARA: - break; - case TGSI_OPCODE_ARR: - break; - case TGSI_OPCODE_BRA: - break; - case TGSI_OPCODE_CAL: { - } - break; - case TGSI_OPCODE_RET: { - } - break; - case TGSI_OPCODE_SSG: - break; - case TGSI_OPCODE_CMP: { - } - break; - case TGSI_OPCODE_SCS: { - } - break; - case TGSI_OPCODE_TXB: - break; - case TGSI_OPCODE_NRM: - break; - case TGSI_OPCODE_DIV: - break; - case TGSI_OPCODE_DP2: - break; - case TGSI_OPCODE_TXL: - break; - case TGSI_OPCODE_BRK: { - } - break; - case TGSI_OPCODE_IF: { - } - break; - case TGSI_OPCODE_LOOP: - break; - case TGSI_OPCODE_REP: - break; - case TGSI_OPCODE_ELSE: { - } - break; - case TGSI_OPCODE_ENDIF: { - } - break; - case TGSI_OPCODE_ENDLOOP: - break; - case TGSI_OPCODE_ENDREP: - break; - case TGSI_OPCODE_PUSHA: - break; - case TGSI_OPCODE_POPA: - break; - case TGSI_OPCODE_CEIL: - break; - case TGSI_OPCODE_I2F: - break; - case TGSI_OPCODE_NOT: - break; - case TGSI_OPCODE_TRUNC: { - } - break; - case TGSI_OPCODE_SHL: - break; - case TGSI_OPCODE_SHR: - break; - case TGSI_OPCODE_AND: - break; - case TGSI_OPCODE_OR: - break; - case TGSI_OPCODE_MOD: - break; - case TGSI_OPCODE_XOR: - break; - case TGSI_OPCODE_SAD: - break; - case TGSI_OPCODE_TXF: - break; - case TGSI_OPCODE_TXQ: - break; - case TGSI_OPCODE_CONT: - break; - case TGSI_OPCODE_EMIT: - break; - case TGSI_OPCODE_ENDPRIM: - break; - case TGSI_OPCODE_BGNLOOP2: { - } - break; - case TGSI_OPCODE_BGNSUB: { - } - break; - case TGSI_OPCODE_ENDLOOP2: { - } - break; - case TGSI_OPCODE_ENDSUB: { - } - break; - case TGSI_OPCODE_NOISE1: - break; - case TGSI_OPCODE_NOISE2: - break; - case TGSI_OPCODE_NOISE3: - break; - case TGSI_OPCODE_NOISE4: - break; - case TGSI_OPCODE_NOP: - break; - case TGSI_OPCODE_TEXBEM: - break; - case TGSI_OPCODE_TEXBEML: - break; - case TGSI_OPCODE_TEXREG2AR: - break; - case TGSI_OPCODE_TEXM3X2PAD: - break; - case TGSI_OPCODE_TEXM3X2TEX: - break; - case TGSI_OPCODE_TEXM3X3PAD: - break; - case TGSI_OPCODE_TEXM3X3TEX: - break; - case TGSI_OPCODE_TEXM3X3SPEC: - break; - case TGSI_OPCODE_TEXM3X3VSPEC: - break; - case TGSI_OPCODE_TEXREG2GB: - break; - case TGSI_OPCODE_TEXREG2RGB: - break; - case TGSI_OPCODE_TEXDP3TEX: - break; - case TGSI_OPCODE_TEXDP3: - break; - case TGSI_OPCODE_TEXM3X3: - break; - case TGSI_OPCODE_TEXM3X2DEPTH: - break; - case TGSI_OPCODE_TEXDEPTH: - break; - case TGSI_OPCODE_BEM: - break; - case TGSI_OPCODE_M4X3: - break; - case TGSI_OPCODE_M3X4: - break; - case TGSI_OPCODE_M3X3: - break; - case TGSI_OPCODE_M3X2: - break; - case TGSI_OPCODE_NRM4: - break; - case TGSI_OPCODE_CALLNZ: - break; - case TGSI_OPCODE_IFC: - break; - case TGSI_OPCODE_BREAKC: - break; - case TGSI_OPCODE_KIL: - break; - case TGSI_OPCODE_END: - instr->end(); - return; - break; - default: - fprintf(stderr, "ERROR: Unknown opcode %d\n", - inst->Instruction.Opcode); - assert(0); - break; - } - - if (!out[0]) { - fprintf(stderr, "ERROR: unsupported opcode %d\n", - inst->Instruction.Opcode); - assert(!"Unsupported opcode"); - } - - /* store results */ - for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - - if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { - storage->store(StorageSoa::Output, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { - storage->store(StorageSoa::Temp, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { - storage->store(StorageSoa::Address, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else { - fprintf(stderr, "ERROR: unsupported LLVM destination!"); - assert(!"wrong destination"); - } - } -} - -llvm::Module * -tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens) -{ - llvm::Module *mod = new Module("shader"); - struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - unsigned instno = 0; - Function* shader = mod->getFunction("execute_shader"); - std::ostringstream stream; - if (ir->type == GALLIVM_VS) { - stream << "vs_shader"; - } else { - stream << "fs_shader"; - } - stream << ir->id; - std::string func_name = stream.str(); - shader->setName(func_name.c_str()); - - Function::arg_iterator args = shader->arg_begin(); - Value *ptr_INPUT = args++; - ptr_INPUT->setName("input"); - - BasicBlock *label_entry = new BasicBlock("entry", shader, 0); - - tgsi_parse_init(&parse, tokens); - - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - Storage storage(label_entry, ptr_INPUT); - Instructions instr(mod, shader, label_entry, &storage); - while(!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - translate_declaration(ir, mod, &storage, - &parse.FullToken.FullDeclaration, - &fd); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - translate_immediate(&storage, - &parse.FullToken.FullImmediate); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - translate_instruction(mod, &storage, &instr, - &parse.FullToken.FullInstruction, - &fi, instno); - ++instno; - break; - - default: - assert(0); - } - } - - tgsi_parse_free(&parse); - - ir->num_consts = storage.numConsts(); - return mod; -} - -llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, - const struct tgsi_token *tokens) -{ - llvm::Module *mod = new Module("shader"); - struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - unsigned instno = 0; - std::ostringstream stream; - if (ir->type == GALLIVM_VS) { - stream << "vs_shader"; - } else { - stream << "fs_shader"; - } - //stream << ir->id; - std::string func_name = stream.str(); - Function *shader = llvm::cast(mod->getOrInsertFunction( - func_name.c_str(), - vertexShaderFunctionType())); - - Function::arg_iterator args = shader->arg_begin(); - Value *input = args++; - input->setName("inputs"); - Value *output = args++; - output->setName("outputs"); - Value *consts = args++; - consts->setName("consts"); - Value *temps = args++; - temps->setName("temps"); - - BasicBlock *label_entry = new BasicBlock("entry", shader, 0); - - tgsi_parse_init(&parse, tokens); - - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - - StorageSoa storage(label_entry, input, output, consts, temps); - InstructionsSoa instr(mod, shader, label_entry, &storage); - - while(!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - translate_declarationir(ir, mod, &storage, - &parse.FullToken.FullDeclaration, - &fd); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - translate_immediateir(&storage, - &parse.FullToken.FullImmediate); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - storage.declareImmediates(); - translate_instructionir(mod, &storage, &instr, - &parse.FullToken.FullInstruction, - &fi, instno); - ++instno; - break; - - default: - assert(0); - } - } - - tgsi_parse_free(&parse); - - return mod; -} diff --git a/src/gallium/aux/llvm/tgsitollvm.h b/src/gallium/aux/llvm/tgsitollvm.h deleted file mode 100644 index 7ada04d629..0000000000 --- a/src/gallium/aux/llvm/tgsitollvm.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef TGSITOLLVM_H -#define TGSITOLLVM_H - - -namespace llvm { - class Module; -} - -struct gallivm_ir; -struct tgsi_token; - - -llvm::Module * tgsi_to_llvm(struct gallivm_ir *ir, - const struct tgsi_token *tokens); - - -llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, - const struct tgsi_token *tokens); - -#endif diff --git a/src/gallium/aux/pipebuffer/Makefile b/src/gallium/aux/pipebuffer/Makefile deleted file mode 100644 index 588629e870..0000000000 --- a/src/gallium/aux/pipebuffer/Makefile +++ /dev/null @@ -1,23 +0,0 @@ - -TOP = ../../../.. -include $(TOP)/configs/current - -LIBNAME = pipebuffer - -DRIVER_SOURCES = \ - pb_buffer_fenced.c \ - pb_buffer_malloc.c \ - pb_bufmgr_fenced.c \ - pb_bufmgr_mm.c \ - pb_bufmgr_pool.c \ - pb_winsys.c - -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - -include ../../Makefile.template - -symlinks: - diff --git a/src/gallium/aux/pipebuffer/linked_list.h b/src/gallium/aux/pipebuffer/linked_list.h deleted file mode 100644 index e99817fb13..0000000000 --- a/src/gallium/aux/pipebuffer/linked_list.h +++ /dev/null @@ -1,91 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - **************************************************************************/ - -/** - * \file - * List macros heavily inspired by the Linux kernel - * list handling. No list looping yet. - * - * Is not threadsafe, so common operations need to - * be protected using an external mutex. - */ - -#ifndef LINKED_LIST_H_ -#define LINKED_LIST_H_ - - -#include - - -struct list_head -{ - struct list_head *prev; - struct list_head *next; -}; - - -#define LIST_INITHEAD(__item) \ - do { \ - (__item)->prev = (__item); \ - (__item)->next = (__item); \ - } while (0) - -#define LIST_ADD(__item, __list) \ - do { \ - (__item)->prev = (__list); \ - (__item)->next = (__list)->next; \ - (__list)->next->prev = (__item); \ - (__list)->next = (__item); \ - } while (0) - -#define LIST_ADDTAIL(__item, __list) \ - do { \ - (__item)->next = (__list); \ - (__item)->prev = (__list)->prev; \ - (__list)->prev->next = (__item); \ - (__list)->prev = (__item); \ - } while(0) - -#define LIST_DEL(__item) \ - do { \ - (__item)->prev->next = (__item)->next; \ - (__item)->next->prev = (__item)->prev; \ - } while(0) - -#define LIST_DELINIT(__item) \ - do { \ - (__item)->prev->next = (__item)->next; \ - (__item)->next->prev = (__item)->prev; \ - (__item)->next = (__item); \ - (__item)->prev = (__item); \ - } while(0) - -#define LIST_ENTRY(__type, __item, __field) \ - ((__type *)(((char *)(__item)) - offsetof(__type, __field))) - - -#endif /*LINKED_LIST_H_*/ diff --git a/src/gallium/aux/pipebuffer/pb_buffer.h b/src/gallium/aux/pipebuffer/pb_buffer.h deleted file mode 100644 index 97beb5f72a..0000000000 --- a/src/gallium/aux/pipebuffer/pb_buffer.h +++ /dev/null @@ -1,202 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file - * Generic code for buffers. - * - * Behind a pipe buffle handle there can be DMA buffers, client (or user) - * buffers, regular malloced buffers, etc. This file provides an abstract base - * buffer handle that allows the driver to cope with all those kinds of buffers - * in a more flexible way. - * - * There is no obligation of a winsys driver to use this library. And a pipe - * driver should be completly agnostic about it. - * - * \author José Fonseca - */ - -#ifndef PB_BUFFER_H_ -#define PB_BUFFER_H_ - - -#include "pipe/p_compiler.h" -#include "pipe/p_debug.h" -#include "pipe/p_state.h" -#include "pipe/p_inlines.h" - - -struct pb_vtbl; - -/** - * Buffer description. - * - * Used when allocating the buffer. - */ -struct pb_desc -{ - unsigned alignment; - unsigned usage; -}; - - -/** - * Base class for all pb_* buffers. - */ -struct pb_buffer -{ - struct pipe_buffer base; - - /** - * Pointer to the virtual function table. - * - * Avoid accessing this table directly. Use the inline functions below - * instead to avoid mistakes. - */ - const struct pb_vtbl *vtbl; -}; - - -/** - * Virtual function table for the buffer storage operations. - * - * Note that creation is not done through this table. - */ -struct pb_vtbl -{ - void (*destroy)( struct pb_buffer *buf ); - - /** - * Map the entire data store of a buffer object into the client's address. - * flags is bitmask of PIPE_BUFFER_FLAG_READ/WRITE. - */ - void *(*map)( struct pb_buffer *buf, - unsigned flags ); - - void (*unmap)( struct pb_buffer *buf ); - - /** - * Get the base buffer and the offset. - * - * A buffer can be subdivided in smaller buffers. This method should return - * the underlaying buffer, and the relative offset. - * - * Buffers without an underlaying base buffer should return themselves, with - * a zero offset. - * - * Note that this will increase the reference count of the base buffer. - */ - void (*get_base_buffer)( struct pb_buffer *buf, - struct pb_buffer **base_buf, - unsigned *offset ); -}; - - -static INLINE struct pipe_buffer * -pb_pipe_buffer( struct pb_buffer *pbuf ) -{ - assert(pbuf); - return &pbuf->base; -} - - -static INLINE struct pb_buffer * -pb_buffer( struct pipe_buffer *buf ) -{ - assert(buf); - /* Could add a magic cookie check on debug builds. - */ - return (struct pb_buffer *)buf; -} - - -/* Accessor functions for pb->vtbl: - */ -static INLINE void * -pb_map(struct pb_buffer *buf, - unsigned flags) -{ - assert(buf); - return buf->vtbl->map(buf, flags); -} - - -static INLINE void -pb_unmap(struct pb_buffer *buf) -{ - assert(buf); - buf->vtbl->unmap(buf); -} - - -static INLINE void -pb_get_base_buffer( struct pb_buffer *buf, - struct pb_buffer **base_buf, - unsigned *offset ) -{ - buf->vtbl->get_base_buffer(buf, base_buf, offset); -} - - -static INLINE void -pb_destroy(struct pb_buffer *buf) -{ - assert(buf); - buf->vtbl->destroy(buf); -} - - -/* XXX: thread safety issues! - */ -static INLINE void -pb_reference(struct pb_buffer **dst, - struct pb_buffer *src) -{ - if (src) - src->base.refcount++; - - if (*dst && --(*dst)->base.refcount == 0) - pb_destroy( *dst ); - - *dst = src; -} - - -/** - * Malloc-based buffer to store data that can't be used by the graphics - * hardware. - */ -struct pb_buffer * -pb_malloc_buffer_create(size_t size, - const struct pb_desc *desc); - - -void -pb_init_winsys(struct pipe_winsys *winsys); - - -#endif /*PB_BUFFER_H_*/ diff --git a/src/gallium/aux/pipebuffer/pb_buffer_fenced.c b/src/gallium/aux/pipebuffer/pb_buffer_fenced.c deleted file mode 100644 index f4fc3f6d71..0000000000 --- a/src/gallium/aux/pipebuffer/pb_buffer_fenced.c +++ /dev/null @@ -1,299 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file - * Implementation of fenced buffers. - * - * \author José Fonseca - * \author Thomas Hellström - */ - - -#include "linked_list.h" - -#include "p_compiler.h" -#include "p_debug.h" -#include "p_winsys.h" -#include "p_thread.h" -#include "p_util.h" - -#include "pb_buffer.h" -#include "pb_buffer_fenced.h" - -#ifndef __MSC__ -#include -#endif - - -/** - * Convenience macro (type safe). - */ -#define SUPER(__derived) (&(__derived)->base) - - -struct fenced_buffer_list -{ - _glthread_Mutex mutex; - - struct pipe_winsys *winsys; - - size_t numDelayed; - size_t checkDelayed; - - struct list_head delayed; -}; - - -/** - * Wrapper around a pipe buffer which adds fencing and reference counting. - */ -struct fenced_buffer -{ - struct pb_buffer base; - - struct pb_buffer *buffer; - - struct pipe_fence_handle *fence; - - struct list_head head; - struct fenced_buffer_list *list; -}; - - -static INLINE struct fenced_buffer * -fenced_buffer(struct pb_buffer *buf) -{ - assert(buf); - assert(buf->vtbl == &fenced_buffer_vtbl); - return (struct fenced_buffer *)buf; -} - - - - -static void -_fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, - int wait) -{ - struct pipe_winsys *winsys = fenced_list->winsys; - struct fenced_buffer *fenced_buf; - struct list_head *list, *prev; - int signaled = -1; - - list = fenced_list->delayed.next; - - if (fenced_list->numDelayed > 3) { - unsigned i; - - for (i = 0; i < fenced_list->numDelayed; i += 3) { - list = list->next; - } - } - - prev = list->prev; - for (; list != &fenced_list->delayed; list = prev, prev = list->prev) { - - fenced_buf = LIST_ENTRY(struct fenced_buffer, list, head); - - if (signaled != 0) { - if (wait) { - signaled = winsys->fence_finish(winsys, fenced_buf->fence, 0); - } - else { - signaled = winsys->fence_signalled(winsys, fenced_buf->fence, 0); - } - } - - if (signaled != 0) - /* XXX: we are assuming that buffers are freed in the same order they - * are fenced which may not always be true... - */ - break; - - winsys->fence_reference(winsys, &fenced_buf->fence, NULL); - - LIST_DEL(list); - fenced_list->numDelayed--; - - /* Do the delayed destroy: - */ - pb_reference(&fenced_buf->buffer, NULL); - FREE(fenced_buf); - } -} - - -static void -fenced_buffer_destroy(struct pb_buffer *buf) -{ - struct fenced_buffer *fenced_buf = fenced_buffer(buf); - struct fenced_buffer_list *fenced_list = fenced_buf->list; - - if (fenced_buf->fence) { - LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); - fenced_list->numDelayed++; - } - else { - pb_reference(&fenced_buf->buffer, NULL); - FREE(fenced_buf); - } - - if ((fenced_list->numDelayed % fenced_list->checkDelayed) == 0) - _fenced_buffer_list_check_free(fenced_list, 0); -} - - -static void * -fenced_buffer_map(struct pb_buffer *buf, - unsigned flags) -{ - struct fenced_buffer *fenced_buf = fenced_buffer(buf); - return pb_map(fenced_buf->buffer, flags); -} - - -static void -fenced_buffer_unmap(struct pb_buffer *buf) -{ - struct fenced_buffer *fenced_buf = fenced_buffer(buf); - pb_unmap(fenced_buf->buffer); -} - - -static void -fenced_buffer_get_base_buffer(struct pb_buffer *buf, - struct pb_buffer **base_buf, - unsigned *offset) -{ - struct fenced_buffer *fenced_buf = fenced_buffer(buf); - pb_get_base_buffer(fenced_buf->buffer, base_buf, offset); -} - - -const struct pb_vtbl -fenced_buffer_vtbl = { - fenced_buffer_destroy, - fenced_buffer_map, - fenced_buffer_unmap, - fenced_buffer_get_base_buffer -}; - - -struct pb_buffer * -fenced_buffer_create(struct fenced_buffer_list *fenced_list, - struct pb_buffer *buffer) -{ - struct fenced_buffer *buf; - - if(!buffer) - return NULL; - - buf = CALLOC_STRUCT(fenced_buffer); - if(!buf) - return NULL; - - buf->base.base.refcount = 1; - buf->base.base.alignment = buffer->base.alignment; - buf->base.base.usage = buffer->base.usage; - buf->base.base.size = buffer->base.size; - - buf->base.vtbl = &fenced_buffer_vtbl; - buf->buffer = buffer; - buf->list = fenced_list; - - return &buf->base; -} - - -void -buffer_fence(struct pb_buffer *buf, - struct pipe_fence_handle *fence) -{ - struct fenced_buffer *fenced_buf = fenced_buffer(buf); - struct fenced_buffer_list *fenced_list = fenced_buf->list; - struct pipe_winsys *winsys = fenced_list->winsys; - - _glthread_LOCK_MUTEX(fenced_list->mutex); - winsys->fence_reference(winsys, &fenced_buf->fence, fence); - _glthread_UNLOCK_MUTEX(fenced_list->mutex); -} - - -struct fenced_buffer_list * -fenced_buffer_list_create(struct pipe_winsys *winsys) -{ - struct fenced_buffer_list *fenced_list; - - fenced_list = (struct fenced_buffer_list *)CALLOC(1, sizeof(*fenced_list)); - if (!fenced_list) - return NULL; - - fenced_list->winsys = winsys; - - LIST_INITHEAD(&fenced_list->delayed); - - fenced_list->numDelayed = 0; - - /* TODO: don't hard code this */ - fenced_list->checkDelayed = 5; - - _glthread_INIT_MUTEX(fenced_list->mutex); - - return fenced_list; -} - - -void -fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, - int wait) -{ - _glthread_LOCK_MUTEX(fenced_list->mutex); - _fenced_buffer_list_check_free(fenced_list, wait); - _glthread_UNLOCK_MUTEX(fenced_list->mutex); -} - - -void -fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list) -{ - _glthread_LOCK_MUTEX(fenced_list->mutex); - - /* Wait on outstanding fences */ - while (fenced_list->numDelayed) { - _glthread_UNLOCK_MUTEX(fenced_list->mutex); - sched_yield(); - _fenced_buffer_list_check_free(fenced_list, 1); - _glthread_LOCK_MUTEX(fenced_list->mutex); - } - - _glthread_UNLOCK_MUTEX(fenced_list->mutex); - - FREE(fenced_list); -} - - diff --git a/src/gallium/aux/pipebuffer/pb_buffer_fenced.h b/src/gallium/aux/pipebuffer/pb_buffer_fenced.h deleted file mode 100644 index c40b9c75e1..0000000000 --- a/src/gallium/aux/pipebuffer/pb_buffer_fenced.h +++ /dev/null @@ -1,117 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file - * Buffer fencing. - * - * "Fenced buffers" is actually a misnomer. They should be referred as - * "fenceable buffers", i.e, buffers that can be fenced, but I couldn't find - * the word "fenceable" in the dictionary. - * - * A "fenced buffer" is a decorator around a normal buffer, which adds two - * special properties: - * - the ability for the destruction to be delayed by a fence; - * - reference counting. - * - * Usually DMA buffers have a life-time that will extend the life-time of its - * handle. The end-of-life is dictated by the fence signalling. - * - * Between the handle's destruction, and the fence signalling, the buffer is - * stored in a fenced buffer list. - * - * \author José Fonseca - */ - -#ifndef PB_BUFFER_FENCED_H_ -#define PB_BUFFER_FENCED_H_ - - -#include "pipe/p_debug.h" - - -struct pipe_winsys; -struct pipe_buffer; -struct pipe_fence_handle; - - -/** - * List of buffers which are awaiting fence signalling. - */ -struct fenced_buffer_list; - - -/** - * The fenced buffer's virtual function table. - * - * NOTE: Made public for debugging purposes. - */ -extern const struct pb_vtbl fenced_buffer_vtbl; - - -/** - * Create a fenced buffer list. - * - * See also fenced_bufmgr_create for a more convenient way to use this. - */ -struct fenced_buffer_list * -fenced_buffer_list_create(struct pipe_winsys *winsys); - - -/** - * Walk the fenced buffer list to check and free signalled buffers. - */ -void -fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, - int wait); - -void -fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list); - - -/** - * Wrap a buffer in a fenced buffer. - * - * NOTE: this will not increase the buffer reference count. - */ -struct pb_buffer * -fenced_buffer_create(struct fenced_buffer_list *fenced, - struct pb_buffer *buffer); - - -/** - * Set a buffer's fence. - * - * NOTE: Although it takes a generic pb_buffer argument, it will fail - * on everything but buffers returned by fenced_buffer_create. - */ -void -buffer_fence(struct pb_buffer *buf, - struct pipe_fence_handle *fence); - - -#endif /*PB_BUFFER_FENCED_H_*/ diff --git a/src/gallium/aux/pipebuffer/pb_buffer_malloc.c b/src/gallium/aux/pipebuffer/pb_buffer_malloc.c deleted file mode 100644 index 9e8244f909..0000000000 --- a/src/gallium/aux/pipebuffer/pb_buffer_malloc.c +++ /dev/null @@ -1,127 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file - * Implementation of malloc-based buffers to store data that can't be processed - * by the hardware. - * - * \author José Fonseca - */ - - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" -#include "pb_buffer.h" - - -struct malloc_buffer -{ - struct pb_buffer base; - void *data; -}; - - -extern const struct pb_vtbl malloc_buffer_vtbl; - -static INLINE struct malloc_buffer * -malloc_buffer(struct pb_buffer *buf) -{ - assert(buf); - assert(buf->vtbl == &malloc_buffer_vtbl); - return (struct malloc_buffer *)buf; -} - - -static void -malloc_buffer_destroy(struct pb_buffer *buf) -{ - align_free(malloc_buffer(buf)->data); - FREE(buf); -} - - -static void * -malloc_buffer_map(struct pb_buffer *buf, - unsigned flags) -{ - return malloc_buffer(buf)->data; -} - - -static void -malloc_buffer_unmap(struct pb_buffer *buf) -{ - /* No-op */ -} - - -static void -malloc_buffer_get_base_buffer(struct pb_buffer *buf, - struct pb_buffer **base_buf, - unsigned *offset) -{ - *base_buf = buf; - *offset = 0; -} - - -const struct pb_vtbl -malloc_buffer_vtbl = { - malloc_buffer_destroy, - malloc_buffer_map, - malloc_buffer_unmap, - malloc_buffer_get_base_buffer -}; - - -struct pb_buffer * -pb_malloc_buffer_create(size_t size, - const struct pb_desc *desc) -{ - struct malloc_buffer *buf; - - /* TODO: do a single allocation */ - - buf = CALLOC_STRUCT(malloc_buffer); - if(!buf) - return NULL; - - buf->base.base.refcount = 1; - buf->base.base.alignment = desc->alignment; - buf->base.base.usage = desc->usage; - buf->base.base.size = size; - buf->base.vtbl = &malloc_buffer_vtbl; - - buf->data = align_malloc(size, desc->alignment < sizeof(void*) ? sizeof(void*) : desc->alignment); - if(!buf->data) { - align_free(buf); - return NULL; - } - - return &buf->base; -} diff --git a/src/gallium/aux/pipebuffer/pb_bufmgr.h b/src/gallium/aux/pipebuffer/pb_bufmgr.h deleted file mode 100644 index 1ddf784c97..0000000000 --- a/src/gallium/aux/pipebuffer/pb_bufmgr.h +++ /dev/null @@ -1,126 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file - * Buffer management. - * - * A buffer manager does only one basic thing: it creates buffers. Actually, - * "buffer factory" would probably a more accurate description. - * - * You can chain buffer managers so that you can have a finer grained memory - * management and pooling. - * - * For example, for a simple batch buffer manager you would chain: - * - the native buffer manager, which provides DMA memory from the graphics - * memory space; - * - the pool buffer manager, which keep around a pool of equally sized buffers - * to avoid latency associated with the native buffer manager; - * - the fenced buffer manager, which will delay buffer destruction until the - * the moment the card finishing processing it. - * - * \author José Fonseca - */ - -#ifndef PB_BUFMGR_H_ -#define PB_BUFMGR_H_ - - -#include - - -struct pb_desc; -struct pipe_buffer; -struct pipe_winsys; - - -/** - * Abstract base class for all buffer managers. - */ -struct pb_manager -{ - /* XXX: we will likely need more allocation flags */ - struct pb_buffer * - (*create_buffer)( struct pb_manager *mgr, - size_t size, - const struct pb_desc *desc); - - void - (*destroy)( struct pb_manager *mgr ); -}; - - -/** - * Static buffer pool manager. - * - * Manages the allocation of equally sized buffers. It does so by allocating - * a single big buffer and divide it equally sized buffers. - * - * It is meant to manage the allocation of batch buffer pools. - */ -struct pb_manager * -pool_bufmgr_create(struct pb_manager *provider, - size_t n, size_t size, - const struct pb_desc *desc); - - -/** - * Wraper around the old memory manager. - * - * It managers buffers of different sizes. It does so by allocating a buffer - * with the size of the heap, and then using the old mm memory manager to manage - * that heap. - */ -struct pb_manager * -mm_bufmgr_create(struct pb_manager *provider, - size_t size, size_t align2); - -/** - * Same as mm_bufmgr_create. - * - * Buffer will be release when the manager is destroyed. - */ -struct pb_manager * -mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, - size_t size, size_t align2); - - -/** - * Fenced buffer manager. - * - * This manager is just meant for convenience. It wraps the buffers returned - * by another manager in fenced buffers, so that - * - * NOTE: the buffer manager that provides the buffers will be destroyed - * at the same time. - */ -struct pb_manager * -fenced_bufmgr_create(struct pb_manager *provider, - struct pipe_winsys *winsys); - - -#endif /*PB_BUFMGR_H_*/ diff --git a/src/gallium/aux/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/aux/pipebuffer/pb_bufmgr_fenced.c deleted file mode 100644 index c535d3276c..0000000000 --- a/src/gallium/aux/pipebuffer/pb_bufmgr_fenced.c +++ /dev/null @@ -1,131 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ - -/** - * \file - * A buffer manager that wraps buffers in fenced buffers. - * - * \author José Fonseca - */ - - -#include "p_debug.h" -#include "p_util.h" - -#include "pb_buffer.h" -#include "pb_buffer_fenced.h" -#include "pb_bufmgr.h" - - -struct fenced_pb_manager -{ - struct pb_manager base; - - struct pb_manager *provider; - - struct fenced_buffer_list *fenced_list; -}; - - -static INLINE struct fenced_pb_manager * -fenced_pb_manager(struct pb_manager *mgr) -{ - assert(mgr); - return (struct fenced_pb_manager *)mgr; -} - - -static struct pb_buffer * -fenced_bufmgr_create_buffer(struct pb_manager *mgr, - size_t size, - const struct pb_desc *desc) -{ - struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr); - struct pb_buffer *buf; - struct pb_buffer *fenced_buf; - - /* check for free buffers before allocating new ones */ - fenced_buffer_list_check_free(fenced_mgr->fenced_list, 0); - - buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc); - if(!buf) { - /* try harder to get a buffer */ - fenced_buffer_list_check_free(fenced_mgr->fenced_list, 1); - - buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc); - if(!buf) { - /* give up */ - return NULL; - } - } - - fenced_buf = fenced_buffer_create(fenced_mgr->fenced_list, buf); - if(!fenced_buf) { - assert(buf->base.refcount == 1); - pb_destroy(buf); - } - - return fenced_buf; -} - - -static void -fenced_bufmgr_destroy(struct pb_manager *mgr) -{ - struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr); - - fenced_buffer_list_destroy(fenced_mgr->fenced_list); - - fenced_mgr->provider->destroy(fenced_mgr->provider); - - FREE(fenced_mgr); -} - - -struct pb_manager * -fenced_bufmgr_create(struct pb_manager *provider, - struct pipe_winsys *winsys) -{ - struct fenced_pb_manager *fenced_mgr; - - fenced_mgr = (struct fenced_pb_manager *)CALLOC(1, sizeof(*fenced_mgr)); - if (!fenced_mgr) - return NULL; - - fenced_mgr->base.destroy = fenced_bufmgr_destroy; - fenced_mgr->base.create_buffer = fenced_bufmgr_create_buffer; - - fenced_mgr->provider = provider; - fenced_mgr->fenced_list = fenced_buffer_list_create(winsys); - if(!fenced_mgr->fenced_list) { - FREE(fenced_mgr); - return NULL; - } - - return &fenced_mgr->base; -} diff --git a/src/gallium/aux/pipebuffer/pb_bufmgr_mm.c b/src/gallium/aux/pipebuffer/pb_bufmgr_mm.c deleted file mode 100644 index 8b1b51c0e2..0000000000 --- a/src/gallium/aux/pipebuffer/pb_bufmgr_mm.c +++ /dev/null @@ -1,593 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 1999 Wittawat Yamwong - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file - * Buffer manager using the old texture memory manager. - * - * \author José Fonseca - */ - - -#include "linked_list.h" - -#include "p_defines.h" -#include "p_debug.h" -#include "p_thread.h" -#include "p_util.h" -#include "pb_buffer.h" -#include "pb_bufmgr.h" - - -/** - * Convenience macro (type safe). - */ -#define SUPER(__derived) (&(__derived)->base) - - -struct mem_block -{ - struct mem_block *next, *prev; - struct mem_block *next_free, *prev_free; - struct mem_block *heap; - int ofs, size; - unsigned int free:1; - unsigned int reserved:1; -}; - - -#ifdef DEBUG -/** - * For debugging purposes. - */ -static void -mmDumpMemInfo(const struct mem_block *heap) -{ - debug_printf("Memory heap %p:\n", (void *)heap); - if (heap == 0) { - debug_printf(" heap == 0\n"); - } else { - const struct mem_block *p; - - for(p = heap->next; p != heap; p = p->next) { - debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - debug_printf("\nFree list:\n"); - - for(p = heap->next_free; p != heap; p = p->next_free) { - debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - } - debug_printf("End of memory blocks\n"); -} -#endif - - -/** - * input: total size in bytes - * return: a heap pointer if OK, NULL if error - */ -static struct mem_block * -mmInit(int ofs, int size) -{ - struct mem_block *heap, *block; - - if (size <= 0) - return NULL; - - heap = CALLOC_STRUCT(mem_block); - if (!heap) - return NULL; - - block = CALLOC_STRUCT(mem_block); - if (!block) { - FREE(heap); - return NULL; - } - - heap->next = block; - heap->prev = block; - heap->next_free = block; - heap->prev_free = block; - - block->heap = heap; - block->next = heap; - block->prev = heap; - block->next_free = heap; - block->prev_free = heap; - - block->ofs = ofs; - block->size = size; - block->free = 1; - - return heap; -} - - -static struct mem_block * -SliceBlock(struct mem_block *p, - int startofs, int size, - int reserved, int alignment) -{ - struct mem_block *newblock; - - /* break left [p, newblock, p->next], then p = newblock */ - if (startofs > p->ofs) { - newblock = CALLOC_STRUCT(mem_block); - if (!newblock) - return NULL; - newblock->ofs = startofs; - newblock->size = p->size - (startofs - p->ofs); - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - - newblock->next_free = p->next_free; - newblock->prev_free = p; - p->next_free->prev_free = newblock; - p->next_free = newblock; - - p->size -= newblock->size; - p = newblock; - } - - /* break right, also [p, newblock, p->next] */ - if (size < p->size) { - newblock = CALLOC_STRUCT(mem_block); - if (!newblock) - return NULL; - newblock->ofs = startofs + size; - newblock->size = p->size - size; - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - - newblock->next_free = p->next_free; - newblock->prev_free = p; - p->next_free->prev_free = newblock; - p->next_free = newblock; - - p->size = size; - } - - /* p = middle block */ - p->free = 0; - - /* Remove p from the free list: - */ - p->next_free->prev_free = p->prev_free; - p->prev_free->next_free = p->next_free; - - p->next_free = 0; - p->prev_free = 0; - - p->reserved = reserved; - return p; -} - - -/** - * Allocate 'size' bytes with 2^align2 bytes alignment, - * restrict the search to free memory after 'startSearch' - * depth and back buffers should be in different 4mb banks - * to get better page hits if possible - * input: size = size of block - * align2 = 2^align2 bytes alignment - * startSearch = linear offset from start of heap to begin search - * return: pointer to the allocated block, 0 if error - */ -static struct mem_block * -mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) -{ - struct mem_block *p; - const int mask = (1 << align2)-1; - int startofs = 0; - int endofs; - - if (!heap || align2 < 0 || size <= 0) - return NULL; - - for (p = heap->next_free; p != heap; p = p->next_free) { - assert(p->free); - - startofs = (p->ofs + mask) & ~mask; - if ( startofs < startSearch ) { - startofs = startSearch; - } - endofs = startofs+size; - if (endofs <= (p->ofs+p->size)) - break; - } - - if (p == heap) - return NULL; - - assert(p->free); - p = SliceBlock(p,startofs,size,0,mask+1); - - return p; -} - - -#if 0 -/** - * Free block starts at offset - * input: pointer to a heap, start offset - * return: pointer to a block - */ -static struct mem_block * -mmFindBlock(struct mem_block *heap, int start) -{ - struct mem_block *p; - - for (p = heap->next; p != heap; p = p->next) { - if (p->ofs == start) - return p; - } - - return NULL; -} -#endif - - -static INLINE int -Join2Blocks(struct mem_block *p) -{ - /* XXX there should be some assertions here */ - - /* NOTE: heap->free == 0 */ - - if (p->free && p->next->free) { - struct mem_block *q = p->next; - - assert(p->ofs + p->size == q->ofs); - p->size += q->size; - - p->next = q->next; - q->next->prev = p; - - q->next_free->prev_free = q->prev_free; - q->prev_free->next_free = q->next_free; - - FREE(q); - return 1; - } - return 0; -} - - -/** - * Free block starts at offset - * input: pointer to a block - * return: 0 if OK, -1 if error - */ -static int -mmFreeMem(struct mem_block *b) -{ - if (!b) - return 0; - - if (b->free) { - debug_printf("block already free\n"); - return -1; - } - if (b->reserved) { - debug_printf("block is reserved\n"); - return -1; - } - - b->free = 1; - b->next_free = b->heap->next_free; - b->prev_free = b->heap; - b->next_free->prev_free = b; - b->prev_free->next_free = b; - - Join2Blocks(b); - if (b->prev != b->heap) - Join2Blocks(b->prev); - - return 0; -} - - -/** - * destroy MM - */ -static void -mmDestroy(struct mem_block *heap) -{ - struct mem_block *p; - - if (!heap) - return; - - for (p = heap->next; p != heap; ) { - struct mem_block *next = p->next; - FREE(p); - p = next; - } - - FREE(heap); -} - - -struct mm_pb_manager -{ - struct pb_manager base; - - _glthread_Mutex mutex; - - size_t size; - struct mem_block *heap; - - size_t align2; - - struct pb_buffer *buffer; - void *map; -}; - - -static INLINE struct mm_pb_manager * -mm_pb_manager(struct pb_manager *mgr) -{ - assert(mgr); - return (struct mm_pb_manager *)mgr; -} - - -struct mm_buffer -{ - struct pb_buffer base; - - struct mm_pb_manager *mgr; - - struct mem_block *block; -}; - - -static INLINE struct mm_buffer * -mm_buffer(struct pb_buffer *buf) -{ - assert(buf); - return (struct mm_buffer *)buf; -} - - -static void -mm_buffer_destroy(struct pb_buffer *buf) -{ - struct mm_buffer *mm_buf = mm_buffer(buf); - struct mm_pb_manager *mm = mm_buf->mgr; - - assert(buf->base.refcount == 0); - - _glthread_LOCK_MUTEX(mm->mutex); - mmFreeMem(mm_buf->block); - FREE(buf); - _glthread_UNLOCK_MUTEX(mm->mutex); -} - - -static void * -mm_buffer_map(struct pb_buffer *buf, - unsigned flags) -{ - struct mm_buffer *mm_buf = mm_buffer(buf); - struct mm_pb_manager *mm = mm_buf->mgr; - - return (unsigned char *) mm->map + mm_buf->block->ofs; -} - - -static void -mm_buffer_unmap(struct pb_buffer *buf) -{ - /* No-op */ -} - - -static void -mm_buffer_get_base_buffer(struct pb_buffer *buf, - struct pb_buffer **base_buf, - unsigned *offset) -{ - struct mm_buffer *mm_buf = mm_buffer(buf); - struct mm_pb_manager *mm = mm_buf->mgr; - pb_get_base_buffer(mm->buffer, base_buf, offset); - *offset += mm_buf->block->ofs; -} - - -static const struct pb_vtbl -mm_buffer_vtbl = { - mm_buffer_destroy, - mm_buffer_map, - mm_buffer_unmap, - mm_buffer_get_base_buffer -}; - - -static struct pb_buffer * -mm_bufmgr_create_buffer(struct pb_manager *mgr, - size_t size, - const struct pb_desc *desc) -{ - struct mm_pb_manager *mm = mm_pb_manager(mgr); - struct mm_buffer *mm_buf; - - /* We don't handle alignments larger then the one initially setup */ - assert(desc->alignment % (1 << mm->align2) == 0); - if(desc->alignment % (1 << mm->align2)) - return NULL; - - _glthread_LOCK_MUTEX(mm->mutex); - - mm_buf = CALLOC_STRUCT(mm_buffer); - if (!mm_buf) { - _glthread_UNLOCK_MUTEX(mm->mutex); - return NULL; - } - - mm_buf->base.base.refcount = 1; - mm_buf->base.base.alignment = desc->alignment; - mm_buf->base.base.usage = desc->usage; - mm_buf->base.base.size = size; - - mm_buf->base.vtbl = &mm_buffer_vtbl; - - mm_buf->mgr = mm; - - mm_buf->block = mmAllocMem(mm->heap, size, mm->align2, 0); - if(!mm_buf->block) { - debug_printf("warning: heap full\n"); -#if 0 - mmDumpMemInfo(mm->heap); -#endif - - mm_buf->block = mmAllocMem(mm->heap, size, mm->align2, 0); - if(!mm_buf->block) { - assert(0); - FREE(mm_buf); - _glthread_UNLOCK_MUTEX(mm->mutex); - return NULL; - } - } - - /* Some sanity checks */ - assert(0 <= mm_buf->block->ofs && mm_buf->block->ofs < mm->size); - assert(size <= mm_buf->block->size && mm_buf->block->ofs + mm_buf->block->size <= mm->size); - - _glthread_UNLOCK_MUTEX(mm->mutex); - return SUPER(mm_buf); -} - - -static void -mm_bufmgr_destroy(struct pb_manager *mgr) -{ - struct mm_pb_manager *mm = mm_pb_manager(mgr); - - _glthread_LOCK_MUTEX(mm->mutex); - - mmDestroy(mm->heap); - - pb_unmap(mm->buffer); - pb_reference(&mm->buffer, NULL); - - _glthread_UNLOCK_MUTEX(mm->mutex); - - FREE(mgr); -} - - -struct pb_manager * -mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, - size_t size, size_t align2) -{ - struct mm_pb_manager *mm; - - if(!buffer) - return NULL; - - mm = CALLOC_STRUCT(mm_pb_manager); - if (!mm) - return NULL; - - mm->base.create_buffer = mm_bufmgr_create_buffer; - mm->base.destroy = mm_bufmgr_destroy; - - mm->size = size; - mm->align2 = align2; /* 64-byte alignment */ - - _glthread_INIT_MUTEX(mm->mutex); - - mm->buffer = buffer; - - mm->map = pb_map(mm->buffer, - PIPE_BUFFER_USAGE_CPU_READ | - PIPE_BUFFER_USAGE_CPU_WRITE); - if(!mm->map) - goto failure; - - mm->heap = mmInit(0, size); - if (!mm->heap) - goto failure; - - return SUPER(mm); - -failure: -if(mm->heap) - mmDestroy(mm->heap); - if(mm->map) - pb_unmap(mm->buffer); - if(mm) - FREE(mm); - return NULL; -} - - -struct pb_manager * -mm_bufmgr_create(struct pb_manager *provider, - size_t size, size_t align2) -{ - struct pb_buffer *buffer; - struct pb_manager *mgr; - struct pb_desc desc; - - assert(provider); - assert(provider->create_buffer); - - memset(&desc, 0, sizeof(desc)); - desc.alignment = 1 << align2; - - buffer = provider->create_buffer(provider, size, &desc); - if (!buffer) - return NULL; - - mgr = mm_bufmgr_create_from_buffer(buffer, size, align2); - if (!mgr) { - pb_reference(&buffer, NULL); - return NULL; - } - - return mgr; -} diff --git a/src/gallium/aux/pipebuffer/pb_bufmgr_pool.c b/src/gallium/aux/pipebuffer/pb_bufmgr_pool.c deleted file mode 100644 index 04477a865a..0000000000 --- a/src/gallium/aux/pipebuffer/pb_bufmgr_pool.c +++ /dev/null @@ -1,288 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ - -/** - * \file - * Batch buffer pool management. - * - * \author José Fonseca - * \author Thomas Hellström - */ - - -#include "linked_list.h" - -#include "p_compiler.h" -#include "p_debug.h" -#include "p_thread.h" -#include "p_defines.h" -#include "p_util.h" - -#include "pb_buffer.h" -#include "pb_bufmgr.h" - - -/** - * Convenience macro (type safe). - */ -#define SUPER(__derived) (&(__derived)->base) - - -struct pool_pb_manager -{ - struct pb_manager base; - - _glthread_Mutex mutex; - - size_t bufSize; - size_t bufAlign; - - size_t numFree; - size_t numTot; - - struct list_head free; - - struct pb_buffer *buffer; - void *map; - - struct pool_buffer *bufs; -}; - - -static INLINE struct pool_pb_manager * -pool_pb_manager(struct pb_manager *mgr) -{ - assert(mgr); - return (struct pool_pb_manager *)mgr; -} - - -struct pool_buffer -{ - struct pb_buffer base; - - struct pool_pb_manager *mgr; - - struct list_head head; - - size_t start; -}; - - -static INLINE struct pool_buffer * -pool_buffer(struct pb_buffer *buf) -{ - assert(buf); - return (struct pool_buffer *)buf; -} - - - -static void -pool_buffer_destroy(struct pb_buffer *buf) -{ - struct pool_buffer *pool_buf = pool_buffer(buf); - struct pool_pb_manager *pool = pool_buf->mgr; - - assert(pool_buf->base.base.refcount == 0); - - _glthread_LOCK_MUTEX(pool->mutex); - LIST_ADD(&pool_buf->head, &pool->free); - pool->numFree++; - _glthread_UNLOCK_MUTEX(pool->mutex); -} - - -static void * -pool_buffer_map(struct pb_buffer *buf, unsigned flags) -{ - struct pool_buffer *pool_buf = pool_buffer(buf); - struct pool_pb_manager *pool = pool_buf->mgr; - void *map; - - _glthread_LOCK_MUTEX(pool->mutex); - map = (unsigned char *) pool->map + pool_buf->start; - _glthread_UNLOCK_MUTEX(pool->mutex); - return map; -} - - -static void -pool_buffer_unmap(struct pb_buffer *buf) -{ - /* No-op */ -} - - -static void -pool_buffer_get_base_buffer(struct pb_buffer *buf, - struct pb_buffer **base_buf, - unsigned *offset) -{ - struct pool_buffer *pool_buf = pool_buffer(buf); - struct pool_pb_manager *pool = pool_buf->mgr; - pb_get_base_buffer(pool->buffer, base_buf, offset); - *offset += pool_buf->start; -} - - -static const struct pb_vtbl -pool_buffer_vtbl = { - pool_buffer_destroy, - pool_buffer_map, - pool_buffer_unmap, - pool_buffer_get_base_buffer -}; - - -static struct pb_buffer * -pool_bufmgr_create_buffer(struct pb_manager *mgr, - size_t size, - const struct pb_desc *desc) -{ - struct pool_pb_manager *pool = pool_pb_manager(mgr); - struct pool_buffer *pool_buf; - struct list_head *item; - - assert(size == pool->bufSize); - assert(pool->bufAlign % desc->alignment == 0); - - _glthread_LOCK_MUTEX(pool->mutex); - - if (pool->numFree == 0) { - _glthread_UNLOCK_MUTEX(pool->mutex); - debug_printf("warning: out of fixed size buffer objects\n"); - return NULL; - } - - item = pool->free.next; - - if (item == &pool->free) { - _glthread_UNLOCK_MUTEX(pool->mutex); - debug_printf("error: fixed size buffer pool corruption\n"); - return NULL; - } - - LIST_DEL(item); - --pool->numFree; - - _glthread_UNLOCK_MUTEX(pool->mutex); - - pool_buf = LIST_ENTRY(struct pool_buffer, item, head); - assert(pool_buf->base.base.refcount == 0); - pool_buf->base.base.refcount = 1; - pool_buf->base.base.alignment = desc->alignment; - pool_buf->base.base.usage = desc->usage; - - return SUPER(pool_buf); -} - - -static void -pool_bufmgr_destroy(struct pb_manager *mgr) -{ - struct pool_pb_manager *pool = pool_pb_manager(mgr); - _glthread_LOCK_MUTEX(pool->mutex); - - FREE(pool->bufs); - - pb_unmap(pool->buffer); - pb_reference(&pool->buffer, NULL); - - _glthread_UNLOCK_MUTEX(pool->mutex); - - FREE(mgr); -} - - -struct pb_manager * -pool_bufmgr_create(struct pb_manager *provider, - size_t numBufs, - size_t bufSize, - const struct pb_desc *desc) -{ - struct pool_pb_manager *pool; - struct pool_buffer *pool_buf; - size_t i; - - pool = (struct pool_pb_manager *)CALLOC(1, sizeof(*pool)); - if (!pool) - return NULL; - - pool->base.destroy = pool_bufmgr_destroy; - pool->base.create_buffer = pool_bufmgr_create_buffer; - - LIST_INITHEAD(&pool->free); - - pool->numTot = numBufs; - pool->numFree = numBufs; - pool->bufSize = bufSize; - pool->bufAlign = desc->alignment; - - _glthread_INIT_MUTEX(pool->mutex); - - pool->buffer = provider->create_buffer(provider, numBufs*bufSize, desc); - if (!pool->buffer) - goto failure; - - pool->map = pb_map(pool->buffer, - PIPE_BUFFER_USAGE_CPU_READ | - PIPE_BUFFER_USAGE_CPU_WRITE); - if(!pool->map) - goto failure; - - pool->bufs = (struct pool_buffer *)CALLOC(numBufs, sizeof(*pool->bufs)); - if (!pool->bufs) - goto failure; - - pool_buf = pool->bufs; - for (i = 0; i < numBufs; ++i) { - pool_buf->base.base.refcount = 0; - pool_buf->base.base.alignment = 0; - pool_buf->base.base.usage = 0; - pool_buf->base.base.size = bufSize; - pool_buf->base.vtbl = &pool_buffer_vtbl; - pool_buf->mgr = pool; - pool_buf->start = i * bufSize; - LIST_ADDTAIL(&pool_buf->head, &pool->free); - pool_buf++; - } - - return SUPER(pool); - -failure: - if(pool->bufs) - FREE(pool->bufs); - if(pool->map) - pb_unmap(pool->buffer); - if(pool->buffer) - pb_reference(&pool->buffer, NULL); - if(pool) - FREE(pool); - return NULL; -} diff --git a/src/gallium/aux/pipebuffer/pb_winsys.c b/src/gallium/aux/pipebuffer/pb_winsys.c deleted file mode 100644 index 978944091f..0000000000 --- a/src/gallium/aux/pipebuffer/pb_winsys.c +++ /dev/null @@ -1,170 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file - * Implementation of client buffer (also designated as "user buffers"), which - * are just state-tracker owned data masqueraded as buffers. - * - * \author José Fonseca - */ - - -#include "pipe/p_winsys.h" -#include "pipe/p_util.h" - -#include "pb_buffer.h" - - -/** - * User buffers are special buffers that initially reference memory - * held by the user but which may if necessary copy that memory into - * device memory behind the scenes, for submission to hardware. - * - * These are particularly useful when the referenced data is never - * submitted to hardware at all, in the particular case of software - * vertex processing. - */ -struct pb_user_buffer -{ - struct pb_buffer base; - void *data; -}; - - -extern const struct pb_vtbl pb_user_buffer_vtbl; - - -static INLINE struct pb_user_buffer * -pb_user_buffer(struct pb_buffer *buf) -{ - assert(buf); - assert(buf->vtbl == &pb_user_buffer_vtbl); - return (struct pb_user_buffer *)buf; -} - - -static void -pb_user_buffer_destroy(struct pb_buffer *buf) -{ - assert(buf); - FREE(buf); -} - - -static void * -pb_user_buffer_map(struct pb_buffer *buf, - unsigned flags) -{ - return pb_user_buffer(buf)->data; -} - - -static void -pb_user_buffer_unmap(struct pb_buffer *buf) -{ - /* No-op */ -} - - -static void -pb_user_buffer_get_base_buffer(struct pb_buffer *buf, - struct pb_buffer **base_buf, - unsigned *offset) -{ - *base_buf = buf; - *offset = 0; -} - - -const struct pb_vtbl -pb_user_buffer_vtbl = { - pb_user_buffer_destroy, - pb_user_buffer_map, - pb_user_buffer_unmap, - pb_user_buffer_get_base_buffer -}; - - -static struct pipe_buffer * -pb_winsys_user_buffer_create(struct pipe_winsys *winsys, - void *data, - unsigned bytes) -{ - struct pb_user_buffer *buf = CALLOC_STRUCT(pb_user_buffer); - - if(!buf) - return NULL; - - buf->base.base.refcount = 1; - buf->base.base.size = bytes; - buf->base.base.alignment = 0; - buf->base.base.usage = 0; - - buf->base.vtbl = &pb_user_buffer_vtbl; - buf->data = data; - - return &buf->base.base; -} - - -static void * -pb_winsys_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags) -{ - (void)winsys; - return pb_map(pb_buffer(buf), flags); -} - - -static void -pb_winsys_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - (void)winsys; - pb_unmap(pb_buffer(buf)); -} - - -static void -pb_winsys_buffer_destroy(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - (void)winsys; - pb_destroy(pb_buffer(buf)); -} - - -void -pb_init_winsys(struct pipe_winsys *winsys) -{ - winsys->user_buffer_create = pb_winsys_user_buffer_create; - winsys->buffer_map = pb_winsys_buffer_map; - winsys->buffer_unmap = pb_winsys_buffer_unmap; - winsys->buffer_destroy = pb_winsys_buffer_destroy; -} diff --git a/src/gallium/aux/tgsi/Makefile b/src/gallium/aux/tgsi/Makefile deleted file mode 100644 index 12a8bd0409..0000000000 --- a/src/gallium/aux/tgsi/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -default: - cd ../.. ; make - diff --git a/src/gallium/aux/tgsi/exec/Makefile b/src/gallium/aux/tgsi/exec/Makefile deleted file mode 100644 index eb8b14e0e8..0000000000 --- a/src/gallium/aux/tgsi/exec/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -default: - cd ../../.. ; make - diff --git a/src/gallium/aux/tgsi/exec/tgsi_exec.c b/src/gallium/aux/tgsi/exec/tgsi_exec.c deleted file mode 100644 index a8f64c2287..0000000000 --- a/src/gallium/aux/tgsi/exec/tgsi_exec.c +++ /dev/null @@ -1,2485 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * TGSI interpretor/executor. - * - * Flow control information: - * - * Since we operate on 'quads' (4 pixels or 4 vertices in parallel) - * flow control statements (IF/ELSE/ENDIF, LOOP/ENDLOOP) require special - * care since a condition may be true for some quad components but false - * for other components. - * - * We basically execute all statements (even if they're in the part of - * an IF/ELSE clause that's "not taken") and use a special mask to - * control writing to destination registers. This is the ExecMask. - * See store_dest(). - * - * The ExecMask is computed from three other masks (CondMask, LoopMask and - * ContMask) which are controlled by the flow control instructions (namely: - * (IF/ELSE/ENDIF, LOOP/ENDLOOP and CONT). - * - * - * Authors: - * Michal Krol - * Brian Paul - */ - -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" -#include "tgsi_exec.h" - -#define TILE_TOP_LEFT 0 -#define TILE_TOP_RIGHT 1 -#define TILE_BOTTOM_LEFT 2 -#define TILE_BOTTOM_RIGHT 3 - -/* - * Shorthand locations of various utility registers (_I = Index, _C = Channel) - */ -#define TEMP_0_I TGSI_EXEC_TEMP_00000000_I -#define TEMP_0_C TGSI_EXEC_TEMP_00000000_C -#define TEMP_7F_I TGSI_EXEC_TEMP_7FFFFFFF_I -#define TEMP_7F_C TGSI_EXEC_TEMP_7FFFFFFF_C -#define TEMP_80_I TGSI_EXEC_TEMP_80000000_I -#define TEMP_80_C TGSI_EXEC_TEMP_80000000_C -#define TEMP_FF_I TGSI_EXEC_TEMP_FFFFFFFF_I -#define TEMP_FF_C TGSI_EXEC_TEMP_FFFFFFFF_C -#define TEMP_1_I TGSI_EXEC_TEMP_ONE_I -#define TEMP_1_C TGSI_EXEC_TEMP_ONE_C -#define TEMP_2_I TGSI_EXEC_TEMP_TWO_I -#define TEMP_2_C TGSI_EXEC_TEMP_TWO_C -#define TEMP_128_I TGSI_EXEC_TEMP_128_I -#define TEMP_128_C TGSI_EXEC_TEMP_128_C -#define TEMP_M128_I TGSI_EXEC_TEMP_MINUS_128_I -#define TEMP_M128_C TGSI_EXEC_TEMP_MINUS_128_C -#define TEMP_KILMASK_I TGSI_EXEC_TEMP_KILMASK_I -#define TEMP_KILMASK_C TGSI_EXEC_TEMP_KILMASK_C -#define TEMP_OUTPUT_I TGSI_EXEC_TEMP_OUTPUT_I -#define TEMP_OUTPUT_C TGSI_EXEC_TEMP_OUTPUT_C -#define TEMP_PRIMITIVE_I TGSI_EXEC_TEMP_PRIMITIVE_I -#define TEMP_PRIMITIVE_C TGSI_EXEC_TEMP_PRIMITIVE_C -#define TEMP_R0 TGSI_EXEC_TEMP_R0 - -#define FOR_EACH_CHANNEL(CHAN)\ - for (CHAN = 0; CHAN < 4; CHAN++) - -#define IS_CHANNEL_ENABLED(INST, CHAN)\ - ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) - -#define IS_CHANNEL_ENABLED2(INST, CHAN)\ - ((INST).FullDstRegisters[1].DstRegister.WriteMask & (1 << (CHAN))) - -#define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\ - FOR_EACH_CHANNEL( CHAN )\ - if (IS_CHANNEL_ENABLED( INST, CHAN )) - -#define FOR_EACH_ENABLED_CHANNEL2(INST, CHAN)\ - FOR_EACH_CHANNEL( CHAN )\ - if (IS_CHANNEL_ENABLED2( INST, CHAN )) - - -/** The execution mask depends on the conditional mask and the loop mask */ -#define UPDATE_EXEC_MASK(MACH) \ - MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask - - -#define CHAN_X 0 -#define CHAN_Y 1 -#define CHAN_Z 2 -#define CHAN_W 3 - - - -static void -tgsi_exec_prepare( struct tgsi_exec_machine *mach ) -{ - struct tgsi_exec_labels *labels = &mach->Labels; - struct tgsi_parse_context parse; - struct tgsi_full_instruction *instructions; - struct tgsi_full_declaration *declarations; - uint maxInstructions = 10, numInstructions = 0; - uint maxDeclarations = 10, numDeclarations = 0; - uint k; - uint instno = 0; - - mach->ImmLimit = 0; - labels->count = 0; - - declarations = (struct tgsi_full_declaration *) - MALLOC( maxDeclarations * sizeof(struct tgsi_full_declaration) ); - - instructions = (struct tgsi_full_instruction *) - MALLOC( maxInstructions * sizeof(struct tgsi_full_instruction) ); - - k = tgsi_parse_init( &parse, mach->Tokens ); - if (k != TGSI_PARSE_OK) { - debug_printf("Problem parsing!\n"); - return; - } - - while( !tgsi_parse_end_of_tokens( &parse ) ) { - uint pointer = parse.Position; - uint i; - - tgsi_parse_token( &parse ); - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - /* save expanded declaration */ - if (numDeclarations == maxDeclarations) { - declarations = REALLOC(declarations, - maxDeclarations - * sizeof(struct tgsi_full_declaration), - (maxDeclarations + 10) - * sizeof(struct tgsi_full_declaration)); - maxDeclarations += 10; - } - memcpy(declarations + numDeclarations, - &parse.FullToken.FullDeclaration, - sizeof(declarations[0])); - numDeclarations++; - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - { - uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; - assert( size % 4 == 0 ); - assert( mach->ImmLimit + size / 4 <= TGSI_EXEC_NUM_IMMEDIATES ); - - for( i = 0; i < size; i++ ) { - mach->Imms[mach->ImmLimit + i / 4][i % 4] = parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; - } - mach->ImmLimit += size / 4; - } - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - assert( labels->count < 128 ); - - labels->labels[labels->count][0] = instno; - labels->labels[labels->count][1] = pointer; - labels->count++; - - /* save expanded instruction */ - if (numInstructions == maxInstructions) { - instructions = REALLOC(instructions, - maxInstructions - * sizeof(struct tgsi_full_instruction), - (maxInstructions + 10) - * sizeof(struct tgsi_full_instruction)); - maxInstructions += 10; - } - memcpy(instructions + numInstructions, - &parse.FullToken.FullInstruction, - sizeof(instructions[0])); - numInstructions++; - break; - - default: - assert( 0 ); - } - } - tgsi_parse_free (&parse); - - if (mach->Declarations) { - FREE( mach->Declarations ); - } - mach->Declarations = declarations; - mach->NumDeclarations = numDeclarations; - - if (mach->Instructions) { - FREE( mach->Instructions ); - } - mach->Instructions = instructions; - mach->NumInstructions = numInstructions; -} - - -/** - * Initialize machine state by expanding tokens to full instructions, - * allocating temporary storage, setting up constants, etc. - * After this, we can call tgsi_exec_machine_run() many times. - */ -void -tgsi_exec_machine_init( - struct tgsi_exec_machine *mach, - const struct tgsi_token *tokens, - uint numSamplers, - struct tgsi_sampler *samplers) -{ - uint i, k; - struct tgsi_parse_context parse; - -#if 0 - tgsi_dump(tokens, 0); -#endif - - mach->Tokens = tokens; - - mach->Samplers = samplers; - - k = tgsi_parse_init (&parse, mach->Tokens); - if (k != TGSI_PARSE_OK) { - debug_printf( "Problem parsing!\n" ); - return; - } - - mach->Processor = parse.FullHeader.Processor.Processor; - tgsi_parse_free (&parse); - - mach->Temps = (struct tgsi_exec_vector *) tgsi_align_128bit( mach->_Temps); - mach->Addrs = &mach->Temps[TGSI_EXEC_NUM_TEMPS]; - - /* Setup constants. */ - for( i = 0; i < 4; i++ ) { - mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].u[i] = 0x00000000; - mach->Temps[TEMP_7F_I].xyzw[TEMP_7F_C].u[i] = 0x7FFFFFFF; - mach->Temps[TEMP_80_I].xyzw[TEMP_80_C].u[i] = 0x80000000; - mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].u[i] = 0xFFFFFFFF; - mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].f[i] = 1.0f; - mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].f[i] = 2.0f; - mach->Temps[TEMP_128_I].xyzw[TEMP_128_C].f[i] = 128.0f; - mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C].f[i] = -128.0f; - } - - tgsi_exec_prepare( mach ); -} - - -void -tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach) -{ - if (mach->Instructions) { - FREE(mach->Instructions); - mach->Instructions = NULL; - mach->NumInstructions = 0; - } - if (mach->Declarations) { - FREE(mach->Declarations); - mach->Declarations = NULL; - mach->NumDeclarations = 0; - } -} - - -static void -micro_abs( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) fabs( (double) src->f[0] ); - dst->f[1] = (float) fabs( (double) src->f[1] ); - dst->f[2] = (float) fabs( (double) src->f[2] ); - dst->f[3] = (float) fabs( (double) src->f[3] ); -} - -static void -micro_add( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] + src1->f[0]; - dst->f[1] = src0->f[1] + src1->f[1]; - dst->f[2] = src0->f[2] + src1->f[2]; - dst->f[3] = src0->f[3] + src1->f[3]; -} - -static void -micro_iadd( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] + src1->i[0]; - dst->i[1] = src0->i[1] + src1->i[1]; - dst->i[2] = src0->i[2] + src1->i[2]; - dst->i[3] = src0->i[3] + src1->i[3]; -} - -static void -micro_and( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] & src1->u[0]; - dst->u[1] = src0->u[1] & src1->u[1]; - dst->u[2] = src0->u[2] & src1->u[2]; - dst->u[3] = src0->u[3] & src1->u[3]; -} - -static void -micro_ceil( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) ceil( (double) src->f[0] ); - dst->f[1] = (float) ceil( (double) src->f[1] ); - dst->f[2] = (float) ceil( (double) src->f[2] ); - dst->f[3] = (float) ceil( (double) src->f[3] ); -} - -static void -micro_cos( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) cos( (double) src->f[0] ); - dst->f[1] = (float) cos( (double) src->f[1] ); - dst->f[2] = (float) cos( (double) src->f[2] ); - dst->f[3] = (float) cos( (double) src->f[3] ); -} - -static void -micro_ddx( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = - dst->f[1] = - dst->f[2] = - dst->f[3] = src->f[TILE_BOTTOM_RIGHT] - src->f[TILE_BOTTOM_LEFT]; -} - -static void -micro_ddy( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = - dst->f[1] = - dst->f[2] = - dst->f[3] = src->f[TILE_TOP_LEFT] - src->f[TILE_BOTTOM_LEFT]; -} - -static void -micro_div( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] / src1->f[0]; - dst->f[1] = src0->f[1] / src1->f[1]; - dst->f[2] = src0->f[2] / src1->f[2]; - dst->f[3] = src0->f[3] / src1->f[3]; -} - -static void -micro_udiv( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] / src1->u[0]; - dst->u[1] = src0->u[1] / src1->u[1]; - dst->u[2] = src0->u[2] / src1->u[2]; - dst->u[3] = src0->u[3] / src1->u[3]; -} - -static void -micro_eq( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->f[0] = src0->f[0] == src1->f[0] ? src2->f[0] : src3->f[0]; - dst->f[1] = src0->f[1] == src1->f[1] ? src2->f[1] : src3->f[1]; - dst->f[2] = src0->f[2] == src1->f[2] ? src2->f[2] : src3->f[2]; - dst->f[3] = src0->f[3] == src1->f[3] ? src2->f[3] : src3->f[3]; -} - -static void -micro_ieq( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->i[0] = src0->i[0] == src1->i[0] ? src2->i[0] : src3->i[0]; - dst->i[1] = src0->i[1] == src1->i[1] ? src2->i[1] : src3->i[1]; - dst->i[2] = src0->i[2] == src1->i[2] ? src2->i[2] : src3->i[2]; - dst->i[3] = src0->i[3] == src1->i[3] ? src2->i[3] : src3->i[3]; -} - -static void -micro_exp2( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src) -{ - dst->f[0] = (float) pow( 2.0, (double) src->f[0] ); - dst->f[1] = (float) pow( 2.0, (double) src->f[1] ); - dst->f[2] = (float) pow( 2.0, (double) src->f[2] ); - dst->f[3] = (float) pow( 2.0, (double) src->f[3] ); -} - -static void -micro_f2it( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->i[0] = (int) src->f[0]; - dst->i[1] = (int) src->f[1]; - dst->i[2] = (int) src->f[2]; - dst->i[3] = (int) src->f[3]; -} - -static void -micro_f2ut( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->u[0] = (uint) src->f[0]; - dst->u[1] = (uint) src->f[1]; - dst->u[2] = (uint) src->f[2]; - dst->u[3] = (uint) src->f[3]; -} - -static void -micro_flr( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) floor( (double) src->f[0] ); - dst->f[1] = (float) floor( (double) src->f[1] ); - dst->f[2] = (float) floor( (double) src->f[2] ); - dst->f[3] = (float) floor( (double) src->f[3] ); -} - -static void -micro_frc( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = src->f[0] - (float) floor( (double) src->f[0] ); - dst->f[1] = src->f[1] - (float) floor( (double) src->f[1] ); - dst->f[2] = src->f[2] - (float) floor( (double) src->f[2] ); - dst->f[3] = src->f[3] - (float) floor( (double) src->f[3] ); -} - -static void -micro_ge( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->f[0] = src0->f[0] >= src1->f[0] ? src2->f[0] : src3->f[0]; - dst->f[1] = src0->f[1] >= src1->f[1] ? src2->f[1] : src3->f[1]; - dst->f[2] = src0->f[2] >= src1->f[2] ? src2->f[2] : src3->f[2]; - dst->f[3] = src0->f[3] >= src1->f[3] ? src2->f[3] : src3->f[3]; -} - -static void -micro_i2f( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) src->i[0]; - dst->f[1] = (float) src->i[1]; - dst->f[2] = (float) src->i[2]; - dst->f[3] = (float) src->i[3]; -} - -static void -micro_lg2( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) log( (double) src->f[0] ) * 1.442695f; - dst->f[1] = (float) log( (double) src->f[1] ) * 1.442695f; - dst->f[2] = (float) log( (double) src->f[2] ) * 1.442695f; - dst->f[3] = (float) log( (double) src->f[3] ) * 1.442695f; -} - -static void -micro_lt( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->f[0] = src0->f[0] < src1->f[0] ? src2->f[0] : src3->f[0]; - dst->f[1] = src0->f[1] < src1->f[1] ? src2->f[1] : src3->f[1]; - dst->f[2] = src0->f[2] < src1->f[2] ? src2->f[2] : src3->f[2]; - dst->f[3] = src0->f[3] < src1->f[3] ? src2->f[3] : src3->f[3]; -} - -static void -micro_ilt( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->i[0] = src0->i[0] < src1->i[0] ? src2->i[0] : src3->i[0]; - dst->i[1] = src0->i[1] < src1->i[1] ? src2->i[1] : src3->i[1]; - dst->i[2] = src0->i[2] < src1->i[2] ? src2->i[2] : src3->i[2]; - dst->i[3] = src0->i[3] < src1->i[3] ? src2->i[3] : src3->i[3]; -} - -static void -micro_ult( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->u[0] = src0->u[0] < src1->u[0] ? src2->u[0] : src3->u[0]; - dst->u[1] = src0->u[1] < src1->u[1] ? src2->u[1] : src3->u[1]; - dst->u[2] = src0->u[2] < src1->u[2] ? src2->u[2] : src3->u[2]; - dst->u[3] = src0->u[3] < src1->u[3] ? src2->u[3] : src3->u[3]; -} - -static void -micro_max( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] > src1->f[0] ? src0->f[0] : src1->f[0]; - dst->f[1] = src0->f[1] > src1->f[1] ? src0->f[1] : src1->f[1]; - dst->f[2] = src0->f[2] > src1->f[2] ? src0->f[2] : src1->f[2]; - dst->f[3] = src0->f[3] > src1->f[3] ? src0->f[3] : src1->f[3]; -} - -static void -micro_imax( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] > src1->i[0] ? src0->i[0] : src1->i[0]; - dst->i[1] = src0->i[1] > src1->i[1] ? src0->i[1] : src1->i[1]; - dst->i[2] = src0->i[2] > src1->i[2] ? src0->i[2] : src1->i[2]; - dst->i[3] = src0->i[3] > src1->i[3] ? src0->i[3] : src1->i[3]; -} - -static void -micro_umax( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] > src1->u[0] ? src0->u[0] : src1->u[0]; - dst->u[1] = src0->u[1] > src1->u[1] ? src0->u[1] : src1->u[1]; - dst->u[2] = src0->u[2] > src1->u[2] ? src0->u[2] : src1->u[2]; - dst->u[3] = src0->u[3] > src1->u[3] ? src0->u[3] : src1->u[3]; -} - -static void -micro_min( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] < src1->f[0] ? src0->f[0] : src1->f[0]; - dst->f[1] = src0->f[1] < src1->f[1] ? src0->f[1] : src1->f[1]; - dst->f[2] = src0->f[2] < src1->f[2] ? src0->f[2] : src1->f[2]; - dst->f[3] = src0->f[3] < src1->f[3] ? src0->f[3] : src1->f[3]; -} - -static void -micro_imin( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] < src1->i[0] ? src0->i[0] : src1->i[0]; - dst->i[1] = src0->i[1] < src1->i[1] ? src0->i[1] : src1->i[1]; - dst->i[2] = src0->i[2] < src1->i[2] ? src0->i[2] : src1->i[2]; - dst->i[3] = src0->i[3] < src1->i[3] ? src0->i[3] : src1->i[3]; -} - -static void -micro_umin( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] < src1->u[0] ? src0->u[0] : src1->u[0]; - dst->u[1] = src0->u[1] < src1->u[1] ? src0->u[1] : src1->u[1]; - dst->u[2] = src0->u[2] < src1->u[2] ? src0->u[2] : src1->u[2]; - dst->u[3] = src0->u[3] < src1->u[3] ? src0->u[3] : src1->u[3]; -} - -static void -micro_umod( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] % src1->u[0]; - dst->u[1] = src0->u[1] % src1->u[1]; - dst->u[2] = src0->u[2] % src1->u[2]; - dst->u[3] = src0->u[3] % src1->u[3]; -} - -static void -micro_mul( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] * src1->f[0]; - dst->f[1] = src0->f[1] * src1->f[1]; - dst->f[2] = src0->f[2] * src1->f[2]; - dst->f[3] = src0->f[3] * src1->f[3]; -} - -static void -micro_imul( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] * src1->i[0]; - dst->i[1] = src0->i[1] * src1->i[1]; - dst->i[2] = src0->i[2] * src1->i[2]; - dst->i[3] = src0->i[3] * src1->i[3]; -} - -static void -micro_imul64( - union tgsi_exec_channel *dst0, - union tgsi_exec_channel *dst1, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst1->i[0] = src0->i[0] * src1->i[0]; - dst1->i[1] = src0->i[1] * src1->i[1]; - dst1->i[2] = src0->i[2] * src1->i[2]; - dst1->i[3] = src0->i[3] * src1->i[3]; - dst0->i[0] = 0; - dst0->i[1] = 0; - dst0->i[2] = 0; - dst0->i[3] = 0; -} - -static void -micro_umul64( - union tgsi_exec_channel *dst0, - union tgsi_exec_channel *dst1, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst1->u[0] = src0->u[0] * src1->u[0]; - dst1->u[1] = src0->u[1] * src1->u[1]; - dst1->u[2] = src0->u[2] * src1->u[2]; - dst1->u[3] = src0->u[3] * src1->u[3]; - dst0->u[0] = 0; - dst0->u[1] = 0; - dst0->u[2] = 0; - dst0->u[3] = 0; -} - -static void -micro_movc( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2 ) -{ - dst->u[0] = src0->u[0] ? src1->u[0] : src2->u[0]; - dst->u[1] = src0->u[1] ? src1->u[1] : src2->u[1]; - dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2]; - dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3]; -} - -static void -micro_neg( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = -src->f[0]; - dst->f[1] = -src->f[1]; - dst->f[2] = -src->f[2]; - dst->f[3] = -src->f[3]; -} - -static void -micro_ineg( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->i[0] = -src->i[0]; - dst->i[1] = -src->i[1]; - dst->i[2] = -src->i[2]; - dst->i[3] = -src->i[3]; -} - -static void -micro_not( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->u[0] = ~src->u[0]; - dst->u[1] = ~src->u[1]; - dst->u[2] = ~src->u[2]; - dst->u[3] = ~src->u[3]; -} - -static void -micro_or( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] | src1->u[0]; - dst->u[1] = src0->u[1] | src1->u[1]; - dst->u[2] = src0->u[2] | src1->u[2]; - dst->u[3] = src0->u[3] | src1->u[3]; -} - -static void -micro_pow( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = (float) pow( (double) src0->f[0], (double) src1->f[0] ); - dst->f[1] = (float) pow( (double) src0->f[1], (double) src1->f[1] ); - dst->f[2] = (float) pow( (double) src0->f[2], (double) src1->f[2] ); - dst->f[3] = (float) pow( (double) src0->f[3], (double) src1->f[3] ); -} - -static void -micro_rnd( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) floor( (double) (src->f[0] + 0.5f) ); - dst->f[1] = (float) floor( (double) (src->f[1] + 0.5f) ); - dst->f[2] = (float) floor( (double) (src->f[2] + 0.5f) ); - dst->f[3] = (float) floor( (double) (src->f[3] + 0.5f) ); -} - -static void -micro_shl( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] << src1->i[0]; - dst->i[1] = src0->i[1] << src1->i[1]; - dst->i[2] = src0->i[2] << src1->i[2]; - dst->i[3] = src0->i[3] << src1->i[3]; -} - -static void -micro_ishr( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] >> src1->i[0]; - dst->i[1] = src0->i[1] >> src1->i[1]; - dst->i[2] = src0->i[2] >> src1->i[2]; - dst->i[3] = src0->i[3] >> src1->i[3]; -} - -static void -micro_trunc( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0 ) -{ - dst->f[0] = (float) (int) src0->f[0]; - dst->f[1] = (float) (int) src0->f[1]; - dst->f[2] = (float) (int) src0->f[2]; - dst->f[3] = (float) (int) src0->f[3]; -} - -static void -micro_ushr( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] >> src1->u[0]; - dst->u[1] = src0->u[1] >> src1->u[1]; - dst->u[2] = src0->u[2] >> src1->u[2]; - dst->u[3] = src0->u[3] >> src1->u[3]; -} - -static void -micro_sin( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) sin( (double) src->f[0] ); - dst->f[1] = (float) sin( (double) src->f[1] ); - dst->f[2] = (float) sin( (double) src->f[2] ); - dst->f[3] = (float) sin( (double) src->f[3] ); -} - -static void -micro_sqrt( union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) sqrt( (double) src->f[0] ); - dst->f[1] = (float) sqrt( (double) src->f[1] ); - dst->f[2] = (float) sqrt( (double) src->f[2] ); - dst->f[3] = (float) sqrt( (double) src->f[3] ); -} - -static void -micro_sub( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] - src1->f[0]; - dst->f[1] = src0->f[1] - src1->f[1]; - dst->f[2] = src0->f[2] - src1->f[2]; - dst->f[3] = src0->f[3] - src1->f[3]; -} - -static void -micro_u2f( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) src->u[0]; - dst->f[1] = (float) src->u[1]; - dst->f[2] = (float) src->u[2]; - dst->f[3] = (float) src->u[3]; -} - -static void -micro_xor( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] ^ src1->u[0]; - dst->u[1] = src0->u[1] ^ src1->u[1]; - dst->u[2] = src0->u[2] ^ src1->u[2]; - dst->u[3] = src0->u[3] ^ src1->u[3]; -} - -static void -fetch_src_file_channel( - const struct tgsi_exec_machine *mach, - const uint file, - const uint swizzle, - const union tgsi_exec_channel *index, - union tgsi_exec_channel *chan ) -{ - switch( swizzle ) { - case TGSI_EXTSWIZZLE_X: - case TGSI_EXTSWIZZLE_Y: - case TGSI_EXTSWIZZLE_Z: - case TGSI_EXTSWIZZLE_W: - switch( file ) { - case TGSI_FILE_CONSTANT: - chan->f[0] = mach->Consts[index->i[0]][swizzle]; - chan->f[1] = mach->Consts[index->i[1]][swizzle]; - chan->f[2] = mach->Consts[index->i[2]][swizzle]; - chan->f[3] = mach->Consts[index->i[3]][swizzle]; - break; - - case TGSI_FILE_INPUT: - chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Inputs[index->i[3]].xyzw[swizzle].u[3]; - break; - - case TGSI_FILE_TEMPORARY: - chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Temps[index->i[3]].xyzw[swizzle].u[3]; - break; - - case TGSI_FILE_IMMEDIATE: - assert( index->i[0] < (int) mach->ImmLimit ); - chan->f[0] = mach->Imms[index->i[0]][swizzle]; - assert( index->i[1] < (int) mach->ImmLimit ); - chan->f[1] = mach->Imms[index->i[1]][swizzle]; - assert( index->i[2] < (int) mach->ImmLimit ); - chan->f[2] = mach->Imms[index->i[2]][swizzle]; - assert( index->i[3] < (int) mach->ImmLimit ); - chan->f[3] = mach->Imms[index->i[3]][swizzle]; - break; - - case TGSI_FILE_ADDRESS: - chan->u[0] = mach->Addrs[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Addrs[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Addrs[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Addrs[index->i[3]].xyzw[swizzle].u[3]; - break; - - case TGSI_FILE_OUTPUT: - /* vertex/fragment output vars can be read too */ - chan->u[0] = mach->Outputs[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Outputs[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Outputs[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Outputs[index->i[3]].xyzw[swizzle].u[3]; - break; - - default: - assert( 0 ); - } - break; - - case TGSI_EXTSWIZZLE_ZERO: - *chan = mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]; - break; - - case TGSI_EXTSWIZZLE_ONE: - *chan = mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]; - break; - - default: - assert( 0 ); - } -} - -static void -fetch_source( - const struct tgsi_exec_machine *mach, - union tgsi_exec_channel *chan, - const struct tgsi_full_src_register *reg, - const uint chan_index ) -{ - union tgsi_exec_channel index; - uint swizzle; - - index.i[0] = - index.i[1] = - index.i[2] = - index.i[3] = reg->SrcRegister.Index; - - if (reg->SrcRegister.Indirect) { - union tgsi_exec_channel index2; - union tgsi_exec_channel indir_index; - - index2.i[0] = - index2.i[1] = - index2.i[2] = - index2.i[3] = reg->SrcRegisterInd.Index; - - swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterInd, CHAN_X ); - fetch_src_file_channel( - mach, - reg->SrcRegisterInd.File, - swizzle, - &index2, - &indir_index ); - - index.i[0] += indir_index.i[0]; - index.i[1] += indir_index.i[1]; - index.i[2] += indir_index.i[2]; - index.i[3] += indir_index.i[3]; - } - - if( reg->SrcRegister.Dimension ) { - switch( reg->SrcRegister.File ) { - case TGSI_FILE_INPUT: - index.i[0] *= 17; - index.i[1] *= 17; - index.i[2] *= 17; - index.i[3] *= 17; - break; - case TGSI_FILE_CONSTANT: - index.i[0] *= 4096; - index.i[1] *= 4096; - index.i[2] *= 4096; - index.i[3] *= 4096; - break; - default: - assert( 0 ); - } - - index.i[0] += reg->SrcRegisterDim.Index; - index.i[1] += reg->SrcRegisterDim.Index; - index.i[2] += reg->SrcRegisterDim.Index; - index.i[3] += reg->SrcRegisterDim.Index; - - if (reg->SrcRegisterDim.Indirect) { - union tgsi_exec_channel index2; - union tgsi_exec_channel indir_index; - - index2.i[0] = - index2.i[1] = - index2.i[2] = - index2.i[3] = reg->SrcRegisterDimInd.Index; - - swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterDimInd, CHAN_X ); - fetch_src_file_channel( - mach, - reg->SrcRegisterDimInd.File, - swizzle, - &index2, - &indir_index ); - - index.i[0] += indir_index.i[0]; - index.i[1] += indir_index.i[1]; - index.i[2] += indir_index.i[2]; - index.i[3] += indir_index.i[3]; - } - } - - swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); - fetch_src_file_channel( - mach, - reg->SrcRegister.File, - swizzle, - &index, - chan ); - - switch (tgsi_util_get_full_src_register_sign_mode( reg, chan_index )) { - case TGSI_UTIL_SIGN_CLEAR: - micro_abs( chan, chan ); - break; - - case TGSI_UTIL_SIGN_SET: - micro_abs( chan, chan ); - micro_neg( chan, chan ); - break; - - case TGSI_UTIL_SIGN_TOGGLE: - micro_neg( chan, chan ); - break; - - case TGSI_UTIL_SIGN_KEEP: - break; - } - - if (reg->SrcRegisterExtMod.Complement) { - micro_sub( chan, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], chan ); - } -} - -static void -store_dest( - struct tgsi_exec_machine *mach, - const union tgsi_exec_channel *chan, - const struct tgsi_full_dst_register *reg, - const struct tgsi_full_instruction *inst, - uint chan_index ) -{ - union tgsi_exec_channel *dst; - - switch( reg->DstRegister.File ) { - case TGSI_FILE_NULL: - return; - - case TGSI_FILE_OUTPUT: - dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] - + reg->DstRegister.Index].xyzw[chan_index]; - break; - - case TGSI_FILE_TEMPORARY: - dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index]; - break; - - case TGSI_FILE_ADDRESS: - dst = &mach->Addrs[reg->DstRegister.Index].xyzw[chan_index]; - break; - - default: - assert( 0 ); - return; - } - - switch (inst->Instruction.Saturate) - { - case TGSI_SAT_NONE: - if (mach->ExecMask & 0x1) - dst->i[0] = chan->i[0]; - if (mach->ExecMask & 0x2) - dst->i[1] = chan->i[1]; - if (mach->ExecMask & 0x4) - dst->i[2] = chan->i[2]; - if (mach->ExecMask & 0x8) - dst->i[3] = chan->i[3]; - break; - - case TGSI_SAT_ZERO_ONE: - /* XXX need to obey ExecMask here */ - micro_max(dst, chan, &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]); - micro_min(dst, dst, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]); - break; - - case TGSI_SAT_MINUS_PLUS_ONE: - assert( 0 ); - break; - - default: - assert( 0 ); - } -} - -#define FETCH(VAL,INDEX,CHAN)\ - fetch_source (mach, VAL, &inst->FullSrcRegisters[INDEX], CHAN) - -#define STORE(VAL,INDEX,CHAN)\ - store_dest (mach, VAL, &inst->FullDstRegisters[INDEX], inst, CHAN ) - - -/** - * Execute ARB-style KIL which is predicated by a src register. - * Kill fragment if any of the four values is less than zero. - */ -static void -exec_kilp(struct tgsi_exec_machine *mach, - const struct tgsi_full_instruction *inst) -{ - uint uniquemask; - uint chan_index; - uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ - union tgsi_exec_channel r[1]; - - /* This mask stores component bits that were already tested. Note that - * we test if the value is less than zero, so 1.0 and 0.0 need not to be - * tested. */ - uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); - - for (chan_index = 0; chan_index < 4; chan_index++) - { - uint swizzle; - uint i; - - /* unswizzle channel */ - swizzle = tgsi_util_get_full_src_register_extswizzle ( - &inst->FullSrcRegisters[0], - chan_index); - - /* check if the component has not been already tested */ - if (uniquemask & (1 << swizzle)) - continue; - uniquemask |= 1 << swizzle; - - FETCH(&r[0], 0, chan_index); - for (i = 0; i < 4; i++) - if (r[0].f[i] < 0.0f) - kilmask |= 1 << i; - } - - mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; -} - - -/* - * Fetch a texel using STR texture coordinates. - */ -static void -fetch_texel( struct tgsi_sampler *sampler, - const union tgsi_exec_channel *s, - const union tgsi_exec_channel *t, - const union tgsi_exec_channel *p, - float lodbias, /* XXX should be float[4] */ - union tgsi_exec_channel *r, - union tgsi_exec_channel *g, - union tgsi_exec_channel *b, - union tgsi_exec_channel *a ) -{ - uint j; - float rgba[NUM_CHANNELS][QUAD_SIZE]; - - sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, rgba); - - for (j = 0; j < 4; j++) { - r->f[j] = rgba[0][j]; - g->f[j] = rgba[1][j]; - b->f[j] = rgba[2][j]; - a->f[j] = rgba[3][j]; - } -} - - -static void -exec_tex(struct tgsi_exec_machine *mach, - const struct tgsi_full_instruction *inst, - boolean biasLod) -{ - const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; - union tgsi_exec_channel r[8]; - uint chan_index; - float lodBias; - - /* debug_printf("Sampler %u unit %u\n", sampler, unit); */ - - switch (inst->InstructionExtTexture.Texture) { - case TGSI_TEXTURE_1D: - - FETCH(&r[0], 0, CHAN_X); - - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: - FETCH(&r[1], 0, CHAN_W); - micro_div( &r[0], &r[0], &r[1] ); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); - } - - if (biasLod) { - FETCH(&r[1], 0, CHAN_W); - lodBias = r[2].f[0]; - } - else - lodBias = 0.0; - - fetch_texel(&mach->Samplers[unit], - &r[0], NULL, NULL, lodBias, /* S, T, P, BIAS */ - &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */ - break; - - case TGSI_TEXTURE_2D: - case TGSI_TEXTURE_RECT: - - FETCH(&r[0], 0, CHAN_X); - FETCH(&r[1], 0, CHAN_Y); - FETCH(&r[2], 0, CHAN_Z); - - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: - FETCH(&r[3], 0, CHAN_W); - micro_div( &r[0], &r[0], &r[3] ); - micro_div( &r[1], &r[1], &r[3] ); - micro_div( &r[2], &r[2], &r[3] ); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); - } - - if (biasLod) { - FETCH(&r[3], 0, CHAN_W); - lodBias = r[3].f[0]; - } - else - lodBias = 0.0; - - fetch_texel(&mach->Samplers[unit], - &r[0], &r[1], &r[2], lodBias, /* inputs */ - &r[0], &r[1], &r[2], &r[3]); /* outputs */ - break; - - case TGSI_TEXTURE_3D: - case TGSI_TEXTURE_CUBE: - - FETCH(&r[0], 0, CHAN_X); - FETCH(&r[1], 0, CHAN_Y); - FETCH(&r[2], 0, CHAN_Z); - - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: - FETCH(&r[3], 0, CHAN_W); - micro_div( &r[0], &r[0], &r[3] ); - micro_div( &r[1], &r[1], &r[3] ); - micro_div( &r[2], &r[2], &r[3] ); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); - } - - if (biasLod) { - FETCH(&r[3], 0, CHAN_W); - lodBias = r[3].f[0]; - } - else - lodBias = 0.0; - - fetch_texel(&mach->Samplers[unit], - &r[0], &r[1], &r[2], lodBias, - &r[0], &r[1], &r[2], &r[3]); - break; - - default: - assert (0); - } - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[chan_index], 0, chan_index ); - } -} - - -/** - * Evaluate a constant-valued coefficient at the position of the - * current quad. - */ -static void -eval_constant_coef( - struct tgsi_exec_machine *mach, - unsigned attrib, - unsigned chan ) -{ - unsigned i; - - for( i = 0; i < QUAD_SIZE; i++ ) { - mach->Inputs[attrib].xyzw[chan].f[i] = mach->InterpCoefs[attrib].a0[chan]; - } -} - -/** - * Evaluate a linear-valued coefficient at the position of the - * current quad. - */ -static void -eval_linear_coef( - struct tgsi_exec_machine *mach, - unsigned attrib, - unsigned chan ) -{ - const float x = mach->QuadPos.xyzw[0].f[0]; - const float y = mach->QuadPos.xyzw[1].f[0]; - const float dadx = mach->InterpCoefs[attrib].dadx[chan]; - const float dady = mach->InterpCoefs[attrib].dady[chan]; - const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; - mach->Inputs[attrib].xyzw[chan].f[0] = a0; - mach->Inputs[attrib].xyzw[chan].f[1] = a0 + dadx; - mach->Inputs[attrib].xyzw[chan].f[2] = a0 + dady; - mach->Inputs[attrib].xyzw[chan].f[3] = a0 + dadx + dady; -} - -/** - * Evaluate a perspective-valued coefficient at the position of the - * current quad. - */ -static void -eval_perspective_coef( - struct tgsi_exec_machine *mach, - unsigned attrib, - unsigned chan ) -{ - const float x = mach->QuadPos.xyzw[0].f[0]; - const float y = mach->QuadPos.xyzw[1].f[0]; - const float dadx = mach->InterpCoefs[attrib].dadx[chan]; - const float dady = mach->InterpCoefs[attrib].dady[chan]; - const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; - const float *w = mach->QuadPos.xyzw[3].f; - /* divide by W here */ - mach->Inputs[attrib].xyzw[chan].f[0] = a0 / w[0]; - mach->Inputs[attrib].xyzw[chan].f[1] = (a0 + dadx) / w[1]; - mach->Inputs[attrib].xyzw[chan].f[2] = (a0 + dady) / w[2]; - mach->Inputs[attrib].xyzw[chan].f[3] = (a0 + dadx + dady) / w[3]; -} - - -typedef void (* eval_coef_func)( - struct tgsi_exec_machine *mach, - unsigned attrib, - unsigned chan ); - -static void -exec_declaration( - struct tgsi_exec_machine *mach, - const struct tgsi_full_declaration *decl ) -{ - if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { - if( decl->Declaration.File == TGSI_FILE_INPUT ) { - unsigned first, last, mask; - eval_coef_func eval; - - assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); - - first = decl->u.DeclarationRange.First; - last = decl->u.DeclarationRange.Last; - mask = decl->Declaration.UsageMask; - - switch( decl->Interpolation.Interpolate ) { - case TGSI_INTERPOLATE_CONSTANT: - eval = eval_constant_coef; - break; - - case TGSI_INTERPOLATE_LINEAR: - eval = eval_linear_coef; - break; - - case TGSI_INTERPOLATE_PERSPECTIVE: - eval = eval_perspective_coef; - break; - - default: - assert( 0 ); - } - - if( mask == TGSI_WRITEMASK_XYZW ) { - unsigned i, j; - - for( i = first; i <= last; i++ ) { - for( j = 0; j < NUM_CHANNELS; j++ ) { - eval( mach, i, j ); - } - } - } - else { - unsigned i, j; - - for( j = 0; j < NUM_CHANNELS; j++ ) { - if( mask & (1 << j) ) { - for( i = first; i <= last; i++ ) { - eval( mach, i, j ); - } - } - } - } - } - } -} - -static void -exec_instruction( - struct tgsi_exec_machine *mach, - const struct tgsi_full_instruction *inst, - int *pc ) -{ - uint chan_index; - union tgsi_exec_channel r[8]; - - (*pc)++; - - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_ARL: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_f2it( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_MOV: - /* TGSI_OPCODE_SWZ */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_LIT: - if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y ) || IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - FETCH( &r[0], 0, CHAN_X ); - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - micro_max( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - STORE( &r[0], 0, CHAN_Y ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - FETCH( &r[1], 0, CHAN_Y ); - micro_max( &r[1], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - - FETCH( &r[2], 0, CHAN_W ); - micro_min( &r[2], &r[2], &mach->Temps[TEMP_128_I].xyzw[TEMP_128_C] ); - micro_max( &r[2], &r[2], &mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C] ); - micro_pow( &r[1], &r[1], &r[2] ); - micro_lt( &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - STORE( &r[0], 0, CHAN_Z ); - } - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_RCP: - /* TGSI_OPCODE_RECIP */ - FETCH( &r[0], 0, CHAN_X ); - micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_RSQ: - /* TGSI_OPCODE_RECIPSQRT */ - FETCH( &r[0], 0, CHAN_X ); - micro_sqrt( &r[0], &r[0] ); - micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_EXP: - assert (0); - break; - - case TGSI_OPCODE_LOG: - assert (0); - break; - - case TGSI_OPCODE_MUL: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) - { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - - micro_mul( &r[0], &r[0], &r[1] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_ADD: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_add( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_DP3: - /* TGSI_OPCODE_DOT3 */ - FETCH( &r[0], 0, CHAN_X ); - FETCH( &r[1], 1, CHAN_X ); - micro_mul( &r[0], &r[0], &r[1] ); - - FETCH( &r[1], 0, CHAN_Y ); - FETCH( &r[2], 1, CHAN_Y ); - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FETCH( &r[1], 0, CHAN_Z ); - FETCH( &r[2], 1, CHAN_Z ); - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_DP4: - /* TGSI_OPCODE_DOT4 */ - FETCH(&r[0], 0, CHAN_X); - FETCH(&r[1], 1, CHAN_X); - - micro_mul( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 0, CHAN_Y); - FETCH(&r[2], 1, CHAN_Y); - - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 0, CHAN_Z); - FETCH(&r[2], 1, CHAN_Z); - - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 0, CHAN_W); - FETCH(&r[2], 1, CHAN_W); - - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_DST: - if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - FETCH( &r[0], 0, CHAN_Y ); - FETCH( &r[1], 1, CHAN_Y); - micro_mul( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, CHAN_Y ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - FETCH( &r[0], 0, CHAN_Z ); - STORE( &r[0], 0, CHAN_Z ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - FETCH( &r[0], 1, CHAN_W ); - STORE( &r[0], 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_MIN: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - - /* XXX use micro_min()?? */ - micro_lt( &r[0], &r[0], &r[1], &r[0], &r[1] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_MAX: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - - /* XXX use micro_max()?? */ - micro_lt( &r[0], &r[0], &r[1], &r[1], &r[0] ); - - STORE(&r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SLT: - /* TGSI_OPCODE_SETLT */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SGE: - /* TGSI_OPCODE_SETGE */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_ge( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_MAD: - /* TGSI_OPCODE_MADD */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_mul( &r[0], &r[0], &r[1] ); - FETCH( &r[1], 2, chan_index ); - micro_add( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SUB: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - - micro_sub( &r[0], &r[0], &r[1] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_LERP: - /* TGSI_OPCODE_LRP */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - FETCH(&r[2], 2, chan_index); - - micro_sub( &r[1], &r[1], &r[2] ); - micro_mul( &r[0], &r[0], &r[1] ); - micro_add( &r[0], &r[0], &r[2] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_CND: - assert (0); - break; - - case TGSI_OPCODE_CND0: - assert (0); - break; - - case TGSI_OPCODE_DOT2ADD: - /* TGSI_OPCODE_DP2A */ - assert (0); - break; - - case TGSI_OPCODE_INDEX: - assert (0); - break; - - case TGSI_OPCODE_NEGATE: - assert (0); - break; - - case TGSI_OPCODE_FRAC: - /* TGSI_OPCODE_FRC */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_frc( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_CLAMP: - assert (0); - break; - - case TGSI_OPCODE_FLOOR: - /* TGSI_OPCODE_FLR */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_flr( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_ROUND: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_rnd( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_EXPBASE2: - /* TGSI_OPCODE_EX2 */ - FETCH(&r[0], 0, CHAN_X); - - micro_pow( &r[0], &mach->Temps[TEMP_2_I].xyzw[TEMP_2_C], &r[0] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_LOGBASE2: - /* TGSI_OPCODE_LG2 */ - FETCH( &r[0], 0, CHAN_X ); - micro_lg2( &r[0], &r[0] ); - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_POWER: - /* TGSI_OPCODE_POW */ - FETCH(&r[0], 0, CHAN_X); - FETCH(&r[1], 1, CHAN_X); - - micro_pow( &r[0], &r[0], &r[1] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_CROSSPRODUCT: - /* TGSI_OPCODE_XPD */ - FETCH(&r[0], 0, CHAN_Y); - FETCH(&r[1], 1, CHAN_Z); - - micro_mul( &r[2], &r[0], &r[1] ); - - FETCH(&r[3], 0, CHAN_Z); - FETCH(&r[4], 1, CHAN_Y); - - micro_mul( &r[5], &r[3], &r[4] ); - micro_sub( &r[2], &r[2], &r[5] ); - - if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - STORE( &r[2], 0, CHAN_X ); - } - - FETCH(&r[2], 1, CHAN_X); - - micro_mul( &r[3], &r[3], &r[2] ); - - FETCH(&r[5], 0, CHAN_X); - - micro_mul( &r[1], &r[1], &r[5] ); - micro_sub( &r[3], &r[3], &r[1] ); - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - STORE( &r[3], 0, CHAN_Y ); - } - - micro_mul( &r[5], &r[5], &r[4] ); - micro_mul( &r[0], &r[0], &r[2] ); - micro_sub( &r[5], &r[5], &r[0] ); - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - STORE( &r[5], 0, CHAN_Z ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_MULTIPLYMATRIX: - assert (0); - break; - - case TGSI_OPCODE_ABS: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - - micro_abs( &r[0], &r[0] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_RCC: - assert (0); - break; - - case TGSI_OPCODE_DPH: - FETCH(&r[0], 0, CHAN_X); - FETCH(&r[1], 1, CHAN_X); - - micro_mul( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 0, CHAN_Y); - FETCH(&r[2], 1, CHAN_Y); - - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 0, CHAN_Z); - FETCH(&r[2], 1, CHAN_Z); - - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 1, CHAN_W); - - micro_add( &r[0], &r[0], &r[1] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_COS: - FETCH(&r[0], 0, CHAN_X); - - micro_cos( &r[0], &r[0] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_DDX: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_ddx( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_DDY: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_ddy( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_KILP: - exec_kilp (mach, inst); - break; - - case TGSI_OPCODE_KIL: - /* for enabled ExecMask bits, set the killed bit */ - mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= mach->ExecMask; - break; - - case TGSI_OPCODE_PK2H: - assert (0); - break; - - case TGSI_OPCODE_PK2US: - assert (0); - break; - - case TGSI_OPCODE_PK4B: - assert (0); - break; - - case TGSI_OPCODE_PK4UB: - assert (0); - break; - - case TGSI_OPCODE_RFL: - assert (0); - break; - - case TGSI_OPCODE_SEQ: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_eq( &r[0], &r[0], &r[1], - &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], - &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SFL: - assert (0); - break; - - case TGSI_OPCODE_SGT: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SIN: - FETCH( &r[0], 0, CHAN_X ); - micro_sin( &r[0], &r[0] ); - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SLE: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_ge( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SNE: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_eq( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_STR: - assert (0); - break; - - case TGSI_OPCODE_TEX: - /* simple texture lookup */ - /* src[0] = texcoord */ - /* src[1] = sampler unit */ - exec_tex(mach, inst, FALSE); - break; - - case TGSI_OPCODE_TXB: - /* Texture lookup with lod bias */ - /* src[0] = texcoord (src[0].w = LOD bias) */ - /* src[1] = sampler unit */ - exec_tex(mach, inst, TRUE); - break; - - case TGSI_OPCODE_TXD: - /* Texture lookup with explict partial derivatives */ - /* src[0] = texcoord */ - /* src[1] = d[strq]/dx */ - /* src[2] = d[strq]/dy */ - /* src[3] = sampler unit */ - assert (0); - break; - - case TGSI_OPCODE_TXL: - /* Texture lookup with explit LOD */ - /* src[0] = texcoord (src[0].w = LOD) */ - /* src[1] = sampler unit */ - exec_tex(mach, inst, TRUE); - break; - - case TGSI_OPCODE_UP2H: - assert (0); - break; - - case TGSI_OPCODE_UP2US: - assert (0); - break; - - case TGSI_OPCODE_UP4B: - assert (0); - break; - - case TGSI_OPCODE_UP4UB: - assert (0); - break; - - case TGSI_OPCODE_X2D: - assert (0); - break; - - case TGSI_OPCODE_ARA: - assert (0); - break; - - case TGSI_OPCODE_ARR: - assert (0); - break; - - case TGSI_OPCODE_BRA: - assert (0); - break; - - case TGSI_OPCODE_CAL: - /* skip the call if no execution channels are enabled */ - if (mach->ExecMask) { - /* do the call */ - - /* push the Cond, Loop, Cont stacks */ - assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); - mach->CondStack[mach->CondStackTop++] = mach->CondMask; - assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); - mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; - assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); - mach->ContStack[mach->ContStackTop++] = mach->ContMask; - - assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING); - mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask; - - /* note that PC was already incremented above */ - mach->CallStack[mach->CallStackTop++] = *pc; - *pc = inst->InstructionExtLabel.Label; - } - break; - - case TGSI_OPCODE_RET: - mach->FuncMask &= ~mach->ExecMask; - UPDATE_EXEC_MASK(mach); - - if (mach->ExecMask == 0x0) { - /* really return now (otherwise, keep executing */ - - if (mach->CallStackTop == 0) { - /* returning from main() */ - *pc = -1; - return; - } - *pc = mach->CallStack[--mach->CallStackTop]; - - /* pop the Cond, Loop, Cont stacks */ - assert(mach->CondStackTop > 0); - mach->CondMask = mach->CondStack[--mach->CondStackTop]; - assert(mach->LoopStackTop > 0); - mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; - assert(mach->ContStackTop > 0); - mach->ContMask = mach->ContStack[--mach->ContStackTop]; - assert(mach->FuncStackTop > 0); - mach->FuncMask = mach->FuncStack[--mach->FuncStackTop]; - - UPDATE_EXEC_MASK(mach); - } - break; - - case TGSI_OPCODE_SSG: - assert (0); - break; - - case TGSI_OPCODE_CMP: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - FETCH(&r[2], 2, chan_index); - - micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_SCS: - if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) || IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { - FETCH( &r[0], 0, CHAN_X ); - } - if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) ) { - micro_cos( &r[1], &r[0] ); - STORE( &r[1], 0, CHAN_X ); - } - if( IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { - micro_sin( &r[1], &r[0] ); - STORE( &r[1], 0, CHAN_Y ); - } - if( IS_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { - STORE( &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], 0, CHAN_Z ); - } - if( IS_CHANNEL_ENABLED( *inst, CHAN_W ) ) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_NRM: - assert (0); - break; - - case TGSI_OPCODE_DIV: - assert( 0 ); - break; - - case TGSI_OPCODE_DP2: - FETCH( &r[0], 0, CHAN_X ); - FETCH( &r[1], 1, CHAN_X ); - micro_mul( &r[0], &r[0], &r[1] ); - - FETCH( &r[1], 0, CHAN_Y ); - FETCH( &r[2], 1, CHAN_Y ); - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_IF: - /* push CondMask */ - assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); - mach->CondStack[mach->CondStackTop++] = mach->CondMask; - FETCH( &r[0], 0, CHAN_X ); - /* update CondMask */ - if( ! r[0].u[0] ) { - mach->CondMask &= ~0x1; - } - if( ! r[0].u[1] ) { - mach->CondMask &= ~0x2; - } - if( ! r[0].u[2] ) { - mach->CondMask &= ~0x4; - } - if( ! r[0].u[3] ) { - mach->CondMask &= ~0x8; - } - UPDATE_EXEC_MASK(mach); - /* Todo: If CondMask==0, jump to ELSE */ - break; - - case TGSI_OPCODE_ELSE: - /* invert CondMask wrt previous mask */ - { - uint prevMask; - assert(mach->CondStackTop > 0); - prevMask = mach->CondStack[mach->CondStackTop - 1]; - mach->CondMask = ~mach->CondMask & prevMask; - UPDATE_EXEC_MASK(mach); - /* Todo: If CondMask==0, jump to ENDIF */ - } - break; - - case TGSI_OPCODE_ENDIF: - /* pop CondMask */ - assert(mach->CondStackTop > 0); - mach->CondMask = mach->CondStack[--mach->CondStackTop]; - UPDATE_EXEC_MASK(mach); - break; - - case TGSI_OPCODE_END: - /* halt execution */ - *pc = -1; - break; - - case TGSI_OPCODE_REP: - assert (0); - break; - - case TGSI_OPCODE_ENDREP: - assert (0); - break; - - case TGSI_OPCODE_PUSHA: - assert (0); - break; - - case TGSI_OPCODE_POPA: - assert (0); - break; - - case TGSI_OPCODE_CEIL: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_ceil( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_I2F: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_i2f( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_NOT: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_not( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_TRUNC: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_trunc( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SHL: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_shl( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SHR: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_ishr( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_AND: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_and( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_OR: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_or( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_MOD: - assert (0); - break; - - case TGSI_OPCODE_XOR: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_xor( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SAD: - assert (0); - break; - - case TGSI_OPCODE_TXF: - assert (0); - break; - - case TGSI_OPCODE_TXQ: - assert (0); - break; - - case TGSI_OPCODE_EMIT: - mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16; - mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++; - break; - - case TGSI_OPCODE_ENDPRIM: - mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++; - mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0; - break; - - case TGSI_OPCODE_LOOP: - /* fall-through (for now) */ - case TGSI_OPCODE_BGNLOOP2: - /* push LoopMask and ContMasks */ - assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); - mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; - assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); - mach->ContStack[mach->ContStackTop++] = mach->ContMask; - break; - - case TGSI_OPCODE_ENDLOOP: - /* fall-through (for now at least) */ - case TGSI_OPCODE_ENDLOOP2: - /* Restore ContMask, but don't pop */ - assert(mach->ContStackTop > 0); - mach->ContMask = mach->ContStack[mach->ContStackTop - 1]; - if (mach->LoopMask) { - /* repeat loop: jump to instruction just past BGNLOOP */ - *pc = inst->InstructionExtLabel.Label + 1; - } - else { - /* exit loop: pop LoopMask */ - assert(mach->LoopStackTop > 0); - mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; - /* pop ContMask */ - assert(mach->ContStackTop > 0); - mach->ContMask = mach->ContStack[--mach->ContStackTop]; - } - UPDATE_EXEC_MASK(mach); - break; - - case TGSI_OPCODE_BRK: - /* turn off loop channels for each enabled exec channel */ - mach->LoopMask &= ~mach->ExecMask; - /* Todo: if mach->LoopMask == 0, jump to end of loop */ - UPDATE_EXEC_MASK(mach); - break; - - case TGSI_OPCODE_CONT: - /* turn off cont channels for each enabled exec channel */ - mach->ContMask &= ~mach->ExecMask; - /* Todo: if mach->LoopMask == 0, jump to end of loop */ - UPDATE_EXEC_MASK(mach); - break; - - case TGSI_OPCODE_BGNSUB: - /* no-op */ - break; - - case TGSI_OPCODE_ENDSUB: - /* no-op */ - break; - - case TGSI_OPCODE_NOISE1: - assert( 0 ); - break; - - case TGSI_OPCODE_NOISE2: - assert( 0 ); - break; - - case TGSI_OPCODE_NOISE3: - assert( 0 ); - break; - - case TGSI_OPCODE_NOISE4: - assert( 0 ); - break; - - case TGSI_OPCODE_NOP: - break; - - default: - assert( 0 ); - } -} - - -/** - * Run TGSI interpreter. - * \return bitmask of "alive" quad components - */ -uint -tgsi_exec_machine_run( struct tgsi_exec_machine *mach ) -{ - uint i; - int pc = 0; - - mach->CondMask = 0xf; - mach->LoopMask = 0xf; - mach->ContMask = 0xf; - mach->FuncMask = 0xf; - mach->ExecMask = 0xf; - - mach->CondStackTop = 0; /* temporarily subvert this assertion */ - assert(mach->CondStackTop == 0); - assert(mach->LoopStackTop == 0); - assert(mach->ContStackTop == 0); - assert(mach->CallStackTop == 0); - - mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0; - mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0; - - if( mach->Processor == TGSI_PROCESSOR_GEOMETRY ) { - mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0] = 0; - mach->Primitives[0] = 0; - } - - - /* execute declarations (interpolants) */ - for (i = 0; i < mach->NumDeclarations; i++) { - exec_declaration( mach, mach->Declarations+i ); - } - - /* execute instructions, until pc is set to -1 */ - while (pc != -1) { - assert(pc < mach->NumInstructions); - exec_instruction( mach, mach->Instructions + pc, &pc ); - } - -#if 0 - /* we scale from floats in [0,1] to Zbuffer ints in sp_quad_depth_test.c */ - if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) { - /* - * Scale back depth component. - */ - for (i = 0; i < 4; i++) - mach->Outputs[0].xyzw[2].f[i] *= ctx->DrawBuffer->_DepthMaxF; - } -#endif - - return ~mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0]; -} - - diff --git a/src/gallium/aux/tgsi/exec/tgsi_exec.h b/src/gallium/aux/tgsi/exec/tgsi_exec.h deleted file mode 100644 index 1fb66ee960..0000000000 --- a/src/gallium/aux/tgsi/exec/tgsi_exec.h +++ /dev/null @@ -1,239 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#if !defined TGSI_EXEC_H -#define TGSI_EXEC_H - -#include "pipe/p_compiler.h" - -#if defined __cplusplus -extern "C" { -#endif - -#define NUM_CHANNELS 4 /* R,G,B,A */ -#define QUAD_SIZE 4 /* 4 pixel/quad */ - -/** - * Registers may be treated as float, signed int or unsigned int. - */ -union tgsi_exec_channel -{ - float f[QUAD_SIZE]; - int i[QUAD_SIZE]; - unsigned u[QUAD_SIZE]; -}; - -/** - * A vector[RGBA] of channels[4 pixels] - */ -struct tgsi_exec_vector -{ - union tgsi_exec_channel xyzw[NUM_CHANNELS]; -}; - -/** - * For fragment programs, information for computing fragment input - * values from plane equation of the triangle/line. - */ -struct tgsi_interp_coef -{ - float a0[NUM_CHANNELS]; /* in an xyzw layout */ - float dadx[NUM_CHANNELS]; - float dady[NUM_CHANNELS]; -}; - - -struct softpipe_tile_cache; /**< Opaque to TGSI */ - -/** - * Information for sampling textures, which must be implemented - * by code outside the TGSI executor. - */ -struct tgsi_sampler -{ - const struct pipe_sampler_state *state; - struct pipe_texture *texture; - /** Get samples for four fragments in a quad */ - void (*get_samples)(struct tgsi_sampler *sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]); - void *pipe; /*XXX temporary*/ - struct softpipe_tile_cache *cache; -}; - -/** - * For branching/calling subroutines. - */ -struct tgsi_exec_labels -{ - unsigned labels[128][2]; - unsigned count; -}; - -/* - * Locations of various utility registers (_I = Index, _C = Channel) - */ -#define TGSI_EXEC_TEMP_00000000_I 32 -#define TGSI_EXEC_TEMP_00000000_C 0 - -#define TGSI_EXEC_TEMP_7FFFFFFF_I 32 -#define TGSI_EXEC_TEMP_7FFFFFFF_C 1 - -#define TGSI_EXEC_TEMP_80000000_I 32 -#define TGSI_EXEC_TEMP_80000000_C 2 - -#define TGSI_EXEC_TEMP_FFFFFFFF_I 32 -#define TGSI_EXEC_TEMP_FFFFFFFF_C 3 - -#define TGSI_EXEC_TEMP_ONE_I 33 -#define TGSI_EXEC_TEMP_ONE_C 0 - -#define TGSI_EXEC_TEMP_TWO_I 33 -#define TGSI_EXEC_TEMP_TWO_C 1 - -#define TGSI_EXEC_TEMP_128_I 33 -#define TGSI_EXEC_TEMP_128_C 2 - -#define TGSI_EXEC_TEMP_MINUS_128_I 33 -#define TGSI_EXEC_TEMP_MINUS_128_C 3 - -#define TGSI_EXEC_TEMP_KILMASK_I 34 -#define TGSI_EXEC_TEMP_KILMASK_C 0 - -#define TGSI_EXEC_TEMP_OUTPUT_I 34 -#define TGSI_EXEC_TEMP_OUTPUT_C 1 - -#define TGSI_EXEC_TEMP_PRIMITIVE_I 34 -#define TGSI_EXEC_TEMP_PRIMITIVE_C 2 - -#define TGSI_EXEC_TEMP_R0 35 - -#define TGSI_EXEC_NUM_TEMPS (32 + 4) -#define TGSI_EXEC_NUM_ADDRS 1 -#define TGSI_EXEC_NUM_IMMEDIATES 256 - -#define TGSI_EXEC_MAX_COND_NESTING 10 -#define TGSI_EXEC_MAX_LOOP_NESTING 10 -#define TGSI_EXEC_MAX_CALL_NESTING 10 - -/** - * Run-time virtual machine state for executing TGSI shader. - */ -struct tgsi_exec_machine -{ - /* - * 32 program temporaries - * 4 internal temporaries - * 1 address - * 1 temporary of padding to align to 16 bytes - */ - struct tgsi_exec_vector _Temps[TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_ADDRS + 1]; - - /* - * This will point to _Temps after aligning to 16B boundary. - */ - struct tgsi_exec_vector *Temps; - struct tgsi_exec_vector *Addrs; - - struct tgsi_sampler *Samplers; - - float Imms[TGSI_EXEC_NUM_IMMEDIATES][4]; - unsigned ImmLimit; - float (*Consts)[4]; - struct tgsi_exec_vector *Inputs; - struct tgsi_exec_vector *Outputs; - const struct tgsi_token *Tokens; - unsigned Processor; - - /* GEOMETRY processor only. */ - unsigned *Primitives; - - /* FRAGMENT processor only. */ - const struct tgsi_interp_coef *InterpCoefs; - struct tgsi_exec_vector QuadPos; - - /* Conditional execution masks */ - uint CondMask; /**< For IF/ELSE/ENDIF */ - uint LoopMask; /**< For BGNLOOP/ENDLOOP */ - uint ContMask; /**< For loop CONT statements */ - uint FuncMask; /**< For function calls */ - uint ExecMask; /**< = CondMask & LoopMask */ - - /** Condition mask stack (for nested conditionals) */ - uint CondStack[TGSI_EXEC_MAX_COND_NESTING]; - int CondStackTop; - - /** Loop mask stack (for nested loops) */ - uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING]; - int LoopStackTop; - - /** Loop continue mask stack (see comments in tgsi_exec.c) */ - uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING]; - int ContStackTop; - - /** Function execution mask stack (for executing subroutine code) */ - uint FuncStack[TGSI_EXEC_MAX_CALL_NESTING]; - int FuncStackTop; - - /** Function call stack for saving/restoring the program counter */ - uint CallStack[TGSI_EXEC_MAX_CALL_NESTING]; - int CallStackTop; - - struct tgsi_full_instruction *Instructions; - uint NumInstructions; - - struct tgsi_full_declaration *Declarations; - uint NumDeclarations; - - struct tgsi_exec_labels Labels; -}; - - -void -tgsi_exec_machine_init( - struct tgsi_exec_machine *mach, - const struct tgsi_token *tokens, - unsigned numSamplers, - struct tgsi_sampler *samplers); - -uint -tgsi_exec_machine_run( - struct tgsi_exec_machine *mach ); - - -void -tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach); - - -#if defined __cplusplus -} /* extern "C" */ -#endif - -#endif /* TGSI_EXEC_H */ diff --git a/src/gallium/aux/tgsi/exec/tgsi_sse2.c b/src/gallium/aux/tgsi/exec/tgsi_sse2.c deleted file mode 100755 index 593464db3e..0000000000 --- a/src/gallium/aux/tgsi/exec/tgsi_sse2.c +++ /dev/null @@ -1,2378 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" -#include "tgsi_exec.h" -#include "tgsi_sse2.h" - -#include "x86/rtasm/x86sse.h" - -#if defined(__i386__) || defined(__386__) - -#define DUMP_SSE 0 - -#if DUMP_SSE - -static void -_print_reg( - struct x86_reg reg ) -{ - if (reg.mod != mod_REG) - debug_printf( "[" ); - - switch( reg.file ) { - case file_REG32: - switch( reg.idx ) { - case reg_AX: - debug_printf( "EAX" ); - break; - case reg_CX: - debug_printf( "ECX" ); - break; - case reg_DX: - debug_printf( "EDX" ); - break; - case reg_BX: - debug_printf( "EBX" ); - break; - case reg_SP: - debug_printf( "ESP" ); - break; - case reg_BP: - debug_printf( "EBP" ); - break; - case reg_SI: - debug_printf( "ESI" ); - break; - case reg_DI: - debug_printf( "EDI" ); - break; - } - break; - case file_MMX: - assert( 0 ); - break; - case file_XMM: - debug_printf( "XMM%u", reg.idx ); - break; - case file_x87: - assert( 0 ); - break; - } - - if (reg.mod == mod_DISP8 || - reg.mod == mod_DISP32) - debug_printf("+%d", reg.disp); - - if (reg.mod != mod_REG) - debug_printf( "]" ); -} - -static void -_fill( - const char *op ) -{ - unsigned count = 10 - strlen( op ); - - while( count-- ) { - debug_printf( " " ); - } -} - -#define DUMP_START() debug_printf( "\nsse-dump start ----------------" ) -#define DUMP_END() debug_printf( "\nsse-dump end ----------------\n" ) -#define DUMP( OP ) debug_printf( "\n%s", OP ) -#define DUMP_I( OP, I ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - debug_printf( "%u", I ); } while( 0 ) -#define DUMP_R( OP, R0 ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - _print_reg( R0 ); } while( 0 ) -#define DUMP_RR( OP, R0, R1 ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - _print_reg( R0 );\ - debug_printf( ", " );\ - _print_reg( R1 ); } while( 0 ) -#define DUMP_RRI( OP, R0, R1, I ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - _print_reg( R0 );\ - debug_printf( ", " );\ - _print_reg( R1 );\ - debug_printf( ", " );\ - debug_printf( "%u", I ); } while( 0 ) - -#else - -#define DUMP_START() -#define DUMP_END() -#define DUMP( OP ) -#define DUMP_I( OP, I ) -#define DUMP_R( OP, R0 ) -#define DUMP_RR( OP, R0, R1 ) -#define DUMP_RRI( OP, R0, R1, I ) - -#endif - -#define FOR_EACH_CHANNEL( CHAN )\ - for( CHAN = 0; CHAN < 4; CHAN++ ) - -#define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ - ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) - -#define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ - if( IS_DST0_CHANNEL_ENABLED( INST, CHAN )) - -#define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\ - FOR_EACH_CHANNEL( CHAN )\ - IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN ) - -#define CHAN_X 0 -#define CHAN_Y 1 -#define CHAN_Z 2 -#define CHAN_W 3 - -#define TEMP_R0 TGSI_EXEC_TEMP_R0 - -/** - * X86 utility functions. - */ - -static struct x86_reg -make_xmm( - unsigned xmm ) -{ - return x86_make_reg( - file_XMM, - (enum x86_reg_name) xmm ); -} - -/** - * X86 register mapping helpers. - */ - -static struct x86_reg -get_const_base( void ) -{ - return x86_make_reg( - file_REG32, - reg_CX ); -} - -static struct x86_reg -get_input_base( void ) -{ - return x86_make_reg( - file_REG32, - reg_AX ); -} - -static struct x86_reg -get_output_base( void ) -{ - return x86_make_reg( - file_REG32, - reg_DX ); -} - -static struct x86_reg -get_temp_base( void ) -{ -#ifdef WIN32 - return x86_make_reg( - file_REG32, - reg_BX ); -#else - return x86_make_reg( - file_REG32, - reg_SI ); -#endif -} - -static struct x86_reg -get_coef_base( void ) -{ - return get_output_base(); -} - -/** - * Data access helpers. - */ - -static struct x86_reg -get_argument( - unsigned index ) -{ - return x86_make_disp( - x86_make_reg( file_REG32, reg_SP ), - (index + 1) * 4 ); -} - -static struct x86_reg -get_const( - unsigned vec, - unsigned chan ) -{ - return x86_make_disp( - get_const_base(), - (vec * 4 + chan) * 4 ); -} - -static struct x86_reg -get_input( - unsigned vec, - unsigned chan ) -{ - return x86_make_disp( - get_input_base(), - (vec * 4 + chan) * 16 ); -} - -static struct x86_reg -get_output( - unsigned vec, - unsigned chan ) -{ - return x86_make_disp( - get_output_base(), - (vec * 4 + chan) * 16 ); -} - -static struct x86_reg -get_temp( - unsigned vec, - unsigned chan ) -{ - return x86_make_disp( - get_temp_base(), - (vec * 4 + chan) * 16 ); -} - -static struct x86_reg -get_coef( - unsigned vec, - unsigned chan, - unsigned member ) -{ - return x86_make_disp( - get_coef_base(), - ((vec * 3 + member) * 4 + chan) * 4 ); -} - -/** - * X86 rtasm wrappers. - */ - -static void -emit_addps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ADDPS", dst, src ); - sse_addps( func, dst, src ); -} - -static void -emit_andnps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ANDNPS", dst, src ); - sse_andnps( func, dst, src ); -} - -static void -emit_andps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ANDPS", dst, src ); - sse_andps( func, dst, src ); -} - -static void -emit_call( - struct x86_function *func, - void (* addr)() ) -{ - struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); - - DUMP_I( "CALL", addr ); - x86_mov_reg_imm( func, ecx, (unsigned long) addr ); - x86_call( func, ecx ); -} - -static void -emit_cmpps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src, - enum sse_cc cc ) -{ - DUMP_RRI( "CMPPS", dst, src, cc ); - sse_cmpps( func, dst, src, cc ); -} - -static void -emit_cvttps2dq( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "CVTTPS2DQ", dst, src ); - sse2_cvttps2dq( func, dst, src ); -} - -static void -emit_maxps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MAXPS", dst, src ); - sse_maxps( func, dst, src ); -} - -static void -emit_minps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MINPS", dst, src ); - sse_minps( func, dst, src ); -} - -static void -emit_mov( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOV", dst, src ); - x86_mov( func, dst, src ); -} - -static void -emit_movaps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOVAPS", dst, src ); - sse_movaps( func, dst, src ); -} - -static void -emit_movss( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOVSS", dst, src ); - sse_movss( func, dst, src ); -} - -static void -emit_movups( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOVUPS", dst, src ); - sse_movups( func, dst, src ); -} - -static void -emit_mulps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MULPS", dst, src ); - sse_mulps( func, dst, src ); -} - -static void -emit_or( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "OR", dst, src ); - x86_or( func, dst, src ); -} - -static void -emit_orps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ORPS", dst, src ); - sse_orps( func, dst, src ); -} - -static void -emit_pmovmskb( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "PMOVMSKB", dst, src ); - sse_pmovmskb( func, dst, src ); -} - -static void -emit_pop( - struct x86_function *func, - struct x86_reg dst ) -{ - DUMP_R( "POP", dst ); - x86_pop( func, dst ); -} - -static void -emit_push( - struct x86_function *func, - struct x86_reg dst ) -{ - DUMP_R( "PUSH", dst ); - x86_push( func, dst ); -} - -static void -emit_rcpps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "RCPPS", dst, src ); - sse2_rcpps( func, dst, src ); -} - -#ifdef WIN32 -static void -emit_retw( - struct x86_function *func, - unsigned size ) -{ - DUMP_I( "RET", size ); - x86_retw( func, size ); -} -#else -static void -emit_ret( - struct x86_function *func ) -{ - DUMP( "RET" ); - x86_ret( func ); -} -#endif - -static void -emit_rsqrtps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "RSQRTPS", dst, src ); - sse_rsqrtps( func, dst, src ); -} - -static void -emit_shufps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src, - unsigned char shuf ) -{ - DUMP_RRI( "SHUFPS", dst, src, shuf ); - sse_shufps( func, dst, src, shuf ); -} - -static void -emit_subps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "SUBPS", dst, src ); - sse_subps( func, dst, src ); -} - -static void -emit_xorps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "XORPS", dst, src ); - sse_xorps( func, dst, src ); -} - -/** - * Data fetch helpers. - */ - -static void -emit_const( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_movss( - func, - make_xmm( xmm ), - get_const( vec, chan ) ); - emit_shufps( - func, - make_xmm( xmm ), - make_xmm( xmm ), - SHUF( 0, 0, 0, 0 ) ); -} - -static void -emit_inputf( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_movups( - func, - make_xmm( xmm ), - get_input( vec, chan ) ); -} - -static void -emit_output( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_movups( - func, - get_output( vec, chan ), - make_xmm( xmm ) ); -} - -static void -emit_tempf( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_movaps( - func, - make_xmm( xmm ), - get_temp( vec, chan ) ); -} - -static void -emit_coef( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan, - unsigned member ) -{ - emit_movss( - func, - make_xmm( xmm ), - get_coef( vec, chan, member ) ); - emit_shufps( - func, - make_xmm( xmm ), - make_xmm( xmm ), - SHUF( 0, 0, 0, 0 ) ); -} - -/** - * Data store helpers. - */ - -static void -emit_inputs( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_movups( - func, - get_input( vec, chan ), - make_xmm( xmm ) ); -} - -static void -emit_temps( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_movaps( - func, - get_temp( vec, chan ), - make_xmm( xmm ) ); -} - -static void -emit_addrs( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_temps( - func, - xmm, - vec + TGSI_EXEC_NUM_TEMPS, - chan ); -} - -/** - * Coefficent fetch helpers. - */ - -static void -emit_coef_a0( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_coef( - func, - xmm, - vec, - chan, - 0 ); -} - -static void -emit_coef_dadx( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_coef( - func, - xmm, - vec, - chan, - 1 ); -} - -static void -emit_coef_dady( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_coef( - func, - xmm, - vec, - chan, - 2 ); -} - -/** - * Function call helpers. - */ - -static void -emit_push_gp( - struct x86_function *func ) -{ - emit_push( - func, - get_const_base() ); - emit_push( - func, - get_input_base() ); - emit_push( - func, - get_output_base() ); - - /* It is important on non-win32 platforms that temp base is pushed last. - */ - emit_push( - func, - get_temp_base() ); -} - -static void -emit_pop_gp( - struct x86_function *func ) -{ - /* Restore GP registers in a reverse order. - */ - emit_pop( - func, - get_temp_base() ); - emit_pop( - func, - get_output_base() ); - emit_pop( - func, - get_input_base() ); - emit_pop( - func, - get_const_base() ); -} - -static void -emit_func_call_dst( - struct x86_function *func, - unsigned xmm_dst, - void (*code)() ) -{ - emit_movaps( - func, - get_temp( TEMP_R0, 0 ), - make_xmm( xmm_dst ) ); - - emit_push_gp( - func ); - -#ifdef WIN32 - emit_push( - func, - get_temp( TEMP_R0, 0 ) ); -#endif - - emit_call( - func, - code ); - - emit_pop_gp( - func ); - - emit_movaps( - func, - make_xmm( xmm_dst ), - get_temp( TEMP_R0, 0 ) ); -} - -static void -emit_func_call_dst_src( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src, - void (*code)() ) -{ - emit_movaps( - func, - get_temp( TEMP_R0, 1 ), - make_xmm( xmm_src ) ); - - emit_func_call_dst( - func, - xmm_dst, - code ); -} - -/** - * Low-level instruction translators. - */ - -static void -emit_abs( - struct x86_function *func, - unsigned xmm ) -{ - emit_andps( - func, - make_xmm( xmm ), - get_temp( - TGSI_EXEC_TEMP_7FFFFFFF_I, - TGSI_EXEC_TEMP_7FFFFFFF_C ) ); -} - -static void -emit_add( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ - emit_addps( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -} - -static void XSTDCALL -cos4f( - float *store ) -{ -#ifdef WIN32 - store[0] = (float) cos( (double) store[0] ); - store[1] = (float) cos( (double) store[1] ); - store[2] = (float) cos( (double) store[2] ); - store[3] = (float) cos( (double) store[3] ); -#else - const unsigned X = TEMP_R0 * 16; - store[X + 0] = cosf( store[X + 0] ); - store[X + 1] = cosf( store[X + 1] ); - store[X + 2] = cosf( store[X + 2] ); - store[X + 3] = cosf( store[X + 3] ); -#endif -} - -static void -emit_cos( - struct x86_function *func, - unsigned xmm_dst ) -{ - emit_func_call_dst( - func, - xmm_dst, - cos4f ); -} - -static void XSTDCALL -ex24f( - float *store ) -{ -#ifdef WIN32 - store[0] = (float) pow( 2.0, (double) store[0] ); - store[1] = (float) pow( 2.0, (double) store[1] ); - store[2] = (float) pow( 2.0, (double) store[2] ); - store[3] = (float) pow( 2.0, (double) store[3] ); -#else - const unsigned X = TEMP_R0 * 16; - store[X + 0] = powf( 2.0f, store[X + 0] ); - store[X + 1] = powf( 2.0f, store[X + 1] ); - store[X + 2] = powf( 2.0f, store[X + 2] ); - store[X + 3] = powf( 2.0f, store[X + 3] ); -#endif -} - -static void -emit_ex2( - struct x86_function *func, - unsigned xmm_dst ) -{ - emit_func_call_dst( - func, - xmm_dst, - ex24f ); -} - -static void -emit_f2it( - struct x86_function *func, - unsigned xmm ) -{ - emit_cvttps2dq( - func, - make_xmm( xmm ), - make_xmm( xmm ) ); -} - -static void XSTDCALL -flr4f( - float *store ) -{ -#ifdef WIN32 - const unsigned X = 0; -#else - const unsigned X = TEMP_R0 * 16; -#endif - store[X + 0] = (float) floor( (double) store[X + 0] ); - store[X + 1] = (float) floor( (double) store[X + 1] ); - store[X + 2] = (float) floor( (double) store[X + 2] ); - store[X + 3] = (float) floor( (double) store[X + 3] ); -} - -static void -emit_flr( - struct x86_function *func, - unsigned xmm_dst ) -{ - emit_func_call_dst( - func, - xmm_dst, - flr4f ); -} - -static void XSTDCALL -frc4f( - float *store ) -{ -#ifdef WIN32 - const unsigned X = 0; -#else - const unsigned X = TEMP_R0 * 16; -#endif - store[X + 0] -= (float) floor( (double) store[X + 0] ); - store[X + 1] -= (float) floor( (double) store[X + 1] ); - store[X + 2] -= (float) floor( (double) store[X + 2] ); - store[X + 3] -= (float) floor( (double) store[X + 3] ); -} - -static void -emit_frc( - struct x86_function *func, - unsigned xmm_dst ) -{ - emit_func_call_dst( - func, - xmm_dst, - frc4f ); -} - -static void XSTDCALL -lg24f( - float *store ) -{ -#ifdef WIN32 - const unsigned X = 0; -#else - const unsigned X = TEMP_R0 * 16; -#endif - store[X + 0] = LOG2( store[X + 0] ); - store[X + 1] = LOG2( store[X + 1] ); - store[X + 2] = LOG2( store[X + 2] ); - store[X + 3] = LOG2( store[X + 3] ); -} - -static void -emit_lg2( - struct x86_function *func, - unsigned xmm_dst ) -{ - emit_func_call_dst( - func, - xmm_dst, - lg24f ); -} - -static void -emit_MOV( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ - emit_movups( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -} - -static void -emit_mul (struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src) -{ - emit_mulps( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -} - -static void -emit_neg( - struct x86_function *func, - unsigned xmm ) -{ - emit_xorps( - func, - make_xmm( xmm ), - get_temp( - TGSI_EXEC_TEMP_80000000_I, - TGSI_EXEC_TEMP_80000000_C ) ); -} - -static void XSTDCALL -pow4f( - float *store ) -{ -#ifdef WIN32 - store[0] = (float) pow( (double) store[0], (double) store[4] ); - store[1] = (float) pow( (double) store[1], (double) store[5] ); - store[2] = (float) pow( (double) store[2], (double) store[6] ); - store[3] = (float) pow( (double) store[3], (double) store[7] ); -#else - const unsigned X = TEMP_R0 * 16; - store[X + 0] = powf( store[X + 0], store[X + 4] ); - store[X + 1] = powf( store[X + 1], store[X + 5] ); - store[X + 2] = powf( store[X + 2], store[X + 6] ); - store[X + 3] = powf( store[X + 3], store[X + 7] ); -#endif -} - -static void -emit_pow( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ - emit_func_call_dst_src( - func, - xmm_dst, - xmm_src, - pow4f ); -} - -static void -emit_rcp ( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ - emit_rcpps( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -} - -static void -emit_rsqrt( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ - emit_rsqrtps( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -} - -static void -emit_setsign( - struct x86_function *func, - unsigned xmm ) -{ - emit_orps( - func, - make_xmm( xmm ), - get_temp( - TGSI_EXEC_TEMP_80000000_I, - TGSI_EXEC_TEMP_80000000_C ) ); -} - -static void XSTDCALL -sin4f( - float *store ) -{ -#ifdef WIN32 - store[0] = (float) sin( (double) store[0] ); - store[1] = (float) sin( (double) store[1] ); - store[2] = (float) sin( (double) store[2] ); - store[3] = (float) sin( (double) store[3] ); -#else - const unsigned X = TEMP_R0 * 16; - store[X + 0] = sinf( store[X + 0] ); - store[X + 1] = sinf( store[X + 1] ); - store[X + 2] = sinf( store[X + 2] ); - store[X + 3] = sinf( store[X + 3] ); -#endif -} - -static void -emit_sin (struct x86_function *func, - unsigned xmm_dst) -{ - emit_func_call_dst( - func, - xmm_dst, - sin4f ); -} - -static void -emit_sub( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ - emit_subps( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -} - -/** - * Register fetch. - */ - -static void -emit_fetch( - struct x86_function *func, - unsigned xmm, - const struct tgsi_full_src_register *reg, - const unsigned chan_index ) -{ - unsigned swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); - - switch( swizzle ) { - case TGSI_EXTSWIZZLE_X: - case TGSI_EXTSWIZZLE_Y: - case TGSI_EXTSWIZZLE_Z: - case TGSI_EXTSWIZZLE_W: - switch( reg->SrcRegister.File ) { - case TGSI_FILE_CONSTANT: - emit_const( - func, - xmm, - reg->SrcRegister.Index, - swizzle ); - break; - - case TGSI_FILE_INPUT: - emit_inputf( - func, - xmm, - reg->SrcRegister.Index, - swizzle ); - break; - - case TGSI_FILE_TEMPORARY: - emit_tempf( - func, - xmm, - reg->SrcRegister.Index, - swizzle ); - break; - - default: - assert( 0 ); - } - break; - - case TGSI_EXTSWIZZLE_ZERO: - emit_tempf( - func, - xmm, - TGSI_EXEC_TEMP_00000000_I, - TGSI_EXEC_TEMP_00000000_C ); - break; - - case TGSI_EXTSWIZZLE_ONE: - emit_tempf( - func, - xmm, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); - break; - - default: - assert( 0 ); - } - - switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) { - case TGSI_UTIL_SIGN_CLEAR: - emit_abs( func, xmm ); - break; - - case TGSI_UTIL_SIGN_SET: - emit_setsign( func, xmm ); - break; - - case TGSI_UTIL_SIGN_TOGGLE: - emit_neg( func, xmm ); - break; - - case TGSI_UTIL_SIGN_KEEP: - break; - } -} - -#define FETCH( FUNC, INST, XMM, INDEX, CHAN )\ - emit_fetch( FUNC, XMM, &(INST).FullSrcRegisters[INDEX], CHAN ) - -/** - * Register store. - */ - -static void -emit_store( - struct x86_function *func, - unsigned xmm, - const struct tgsi_full_dst_register *reg, - const struct tgsi_full_instruction *inst, - unsigned chan_index ) -{ - switch( reg->DstRegister.File ) { - case TGSI_FILE_OUTPUT: - emit_output( - func, - xmm, - reg->DstRegister.Index, - chan_index ); - break; - - case TGSI_FILE_TEMPORARY: - emit_temps( - func, - xmm, - reg->DstRegister.Index, - chan_index ); - break; - - case TGSI_FILE_ADDRESS: - emit_addrs( - func, - xmm, - reg->DstRegister.Index, - chan_index ); - break; - - default: - assert( 0 ); - } - - switch( inst->Instruction.Saturate ) { - case TGSI_SAT_NONE: - break; - - case TGSI_SAT_ZERO_ONE: -// assert( 0 ); - break; - - case TGSI_SAT_MINUS_PLUS_ONE: - assert( 0 ); - break; - } -} - -#define STORE( FUNC, INST, XMM, INDEX, CHAN )\ - emit_store( FUNC, XMM, &(INST).FullDstRegisters[INDEX], &(INST), CHAN ) - -/** - * High-level instruction translators. - */ - -static void -emit_kil( - struct x86_function *func, - const struct tgsi_full_src_register *reg ) -{ - unsigned uniquemask; - unsigned registers[4]; - unsigned nextregister = 0; - unsigned firstchan = ~0; - unsigned chan_index; - - /* This mask stores component bits that were already tested. Note that - * we test if the value is less than zero, so 1.0 and 0.0 need not to be - * tested. */ - uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); - - FOR_EACH_CHANNEL( chan_index ) { - unsigned swizzle; - - /* unswizzle channel */ - swizzle = tgsi_util_get_full_src_register_extswizzle( - reg, - chan_index ); - - /* check if the component has not been already tested */ - if( !(uniquemask & (1 << swizzle)) ) { - uniquemask |= 1 << swizzle; - - /* allocate register */ - registers[chan_index] = nextregister; - emit_fetch( - func, - nextregister, - reg, - chan_index ); - nextregister++; - - /* mark the first channel used */ - if( firstchan == ~0 ) { - firstchan = chan_index; - } - } - } - - emit_push( - func, - x86_make_reg( file_REG32, reg_AX ) ); - emit_push( - func, - x86_make_reg( file_REG32, reg_DX ) ); - - FOR_EACH_CHANNEL( chan_index ) { - if( uniquemask & (1 << chan_index) ) { - emit_cmpps( - func, - make_xmm( registers[chan_index] ), - get_temp( - TGSI_EXEC_TEMP_00000000_I, - TGSI_EXEC_TEMP_00000000_C ), - cc_LessThan ); - - if( chan_index == firstchan ) { - emit_pmovmskb( - func, - x86_make_reg( file_REG32, reg_AX ), - make_xmm( registers[chan_index] ) ); - } - else { - emit_pmovmskb( - func, - x86_make_reg( file_REG32, reg_DX ), - make_xmm( registers[chan_index] ) ); - emit_or( - func, - x86_make_reg( file_REG32, reg_AX ), - x86_make_reg( file_REG32, reg_DX ) ); - } - } - } - - emit_or( - func, - get_temp( - TGSI_EXEC_TEMP_KILMASK_I, - TGSI_EXEC_TEMP_KILMASK_C ), - x86_make_reg( file_REG32, reg_AX ) ); - - emit_pop( - func, - x86_make_reg( file_REG32, reg_DX ) ); - emit_pop( - func, - x86_make_reg( file_REG32, reg_AX ) ); -} - -static void -emit_setcc( - struct x86_function *func, - struct tgsi_full_instruction *inst, - enum sse_cc cc ) -{ - unsigned chan_index; - - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - emit_cmpps( - func, - make_xmm( 0 ), - make_xmm( 1 ), - cc ); - emit_andps( - func, - make_xmm( 0 ), - get_temp( - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ) ); - STORE( func, *inst, 0, 0, chan_index ); - } -} - -static void -emit_cmp( - struct x86_function *func, - struct tgsi_full_instruction *inst ) -{ - unsigned chan_index; - - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - FETCH( func, *inst, 2, 2, chan_index ); - emit_cmpps( - func, - make_xmm( 0 ), - get_temp( - TGSI_EXEC_TEMP_00000000_I, - TGSI_EXEC_TEMP_00000000_C ), - cc_LessThan ); - emit_andps( - func, - make_xmm( 1 ), - make_xmm( 0 ) ); - emit_andnps( - func, - make_xmm( 0 ), - make_xmm( 2 ) ); - emit_orps( - func, - make_xmm( 0 ), - make_xmm( 1 ) ); - STORE( func, *inst, 0, 0, chan_index ); - } -} - -static int -emit_instruction( - struct x86_function *func, - struct tgsi_full_instruction *inst ) -{ - unsigned chan_index; - - switch( inst->Instruction.Opcode ) { - case TGSI_OPCODE_ARL: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - emit_f2it( func, 0 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_MOV: - /* TGSI_OPCODE_SWZ */ - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_LIT: - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || - IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) { - emit_tempf( - func, - 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C); - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ) { - STORE( func, *inst, 0, 0, CHAN_X ); - } - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) { - STORE( func, *inst, 0, 0, CHAN_W ); - } - } - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || - IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_maxps( - func, - make_xmm( 0 ), - get_temp( - TGSI_EXEC_TEMP_00000000_I, - TGSI_EXEC_TEMP_00000000_C ) ); - STORE( func, *inst, 0, 0, CHAN_Y ); - } - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { - FETCH( func, *inst, 1, 0, CHAN_Y ); - emit_maxps( - func, - make_xmm( 1 ), - get_temp( - TGSI_EXEC_TEMP_00000000_I, - TGSI_EXEC_TEMP_00000000_C ) ); - FETCH( func, *inst, 2, 0, CHAN_W ); - emit_minps( - func, - make_xmm( 2 ), - get_temp( - TGSI_EXEC_TEMP_128_I, - TGSI_EXEC_TEMP_128_C ) ); - emit_maxps( - func, - make_xmm( 2 ), - get_temp( - TGSI_EXEC_TEMP_MINUS_128_I, - TGSI_EXEC_TEMP_MINUS_128_C ) ); - emit_pow( func, 1, 2 ); - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_xorps( - func, - make_xmm( 2 ), - make_xmm( 2 ) ); - emit_cmpps( - func, - make_xmm( 2 ), - make_xmm( 0 ), - cc_LessThanEqual ); - emit_andps( - func, - make_xmm( 2 ), - make_xmm( 1 ) ); - STORE( func, *inst, 2, 0, CHAN_Z ); - } - } - break; - - case TGSI_OPCODE_RCP: - /* TGSI_OPCODE_RECIP */ - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_rcp( func, 0, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_RSQ: - /* TGSI_OPCODE_RECIPSQRT */ - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_rsqrt( func, 0, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_EXP: - return 0; - break; - - case TGSI_OPCODE_LOG: - return 0; - break; - - case TGSI_OPCODE_MUL: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - emit_mul( func, 0, 1 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_ADD: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - emit_add( func, 0, 1 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_DP3: - /* TGSI_OPCODE_DOT3 */ - FETCH( func, *inst, 0, 0, CHAN_X ); - FETCH( func, *inst, 1, 1, CHAN_X ); - emit_mul( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Y ); - FETCH( func, *inst, 2, 1, CHAN_Y ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Z ); - FETCH( func, *inst, 2, 1, CHAN_Z ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_DP4: - /* TGSI_OPCODE_DOT4 */ - FETCH( func, *inst, 0, 0, CHAN_X ); - FETCH( func, *inst, 1, 1, CHAN_X ); - emit_mul( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Y ); - FETCH( func, *inst, 2, 1, CHAN_Y ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Z ); - FETCH( func, *inst, 2, 1, CHAN_Z ); - emit_mul(func, 1, 2 ); - emit_add(func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_W ); - FETCH( func, *inst, 2, 1, CHAN_W ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_DST: - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { - emit_tempf( - func, - 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); - STORE( func, *inst, 0, 0, CHAN_X ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { - FETCH( func, *inst, 0, 0, CHAN_Y ); - FETCH( func, *inst, 1, 1, CHAN_Y ); - emit_mul( func, 0, 1 ); - STORE( func, *inst, 0, 0, CHAN_Y ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { - FETCH( func, *inst, 0, 0, CHAN_Z ); - STORE( func, *inst, 0, 0, CHAN_Z ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { - FETCH( func, *inst, 0, 1, CHAN_W ); - STORE( func, *inst, 0, 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_MIN: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - emit_minps( - func, - make_xmm( 0 ), - make_xmm( 1 ) ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_MAX: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - emit_maxps( - func, - make_xmm( 0 ), - make_xmm( 1 ) ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_SLT: - /* TGSI_OPCODE_SETLT */ - emit_setcc( func, inst, cc_LessThan ); - break; - - case TGSI_OPCODE_SGE: - /* TGSI_OPCODE_SETGE */ - emit_setcc( func, inst, cc_NotLessThan ); - break; - - case TGSI_OPCODE_MAD: - /* TGSI_OPCODE_MADD */ - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - FETCH( func, *inst, 2, 2, chan_index ); - emit_mul( func, 0, 1 ); - emit_add( func, 0, 2 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_SUB: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - emit_sub( func, 0, 1 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_LERP: - /* TGSI_OPCODE_LRP */ - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - FETCH( func, *inst, 2, 2, chan_index ); - emit_sub( func, 1, 2 ); - emit_mul( func, 0, 1 ); - emit_add( func, 0, 2 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_CND: - return 0; - break; - - case TGSI_OPCODE_CND0: - return 0; - break; - - case TGSI_OPCODE_DOT2ADD: - /* TGSI_OPCODE_DP2A */ - return 0; - break; - - case TGSI_OPCODE_INDEX: - return 0; - break; - - case TGSI_OPCODE_NEGATE: - return 0; - break; - - case TGSI_OPCODE_FRAC: - /* TGSI_OPCODE_FRC */ - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - emit_frc( func, 0 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_CLAMP: - return 0; - break; - - case TGSI_OPCODE_FLOOR: - /* TGSI_OPCODE_FLR */ - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - emit_flr( func, 0 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_ROUND: - return 0; - break; - - case TGSI_OPCODE_EXPBASE2: - /* TGSI_OPCODE_EX2 */ - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_ex2( func, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_LOGBASE2: - /* TGSI_OPCODE_LG2 */ - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_lg2( func, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_POWER: - /* TGSI_OPCODE_POW */ - FETCH( func, *inst, 0, 0, CHAN_X ); - FETCH( func, *inst, 1, 1, CHAN_X ); - emit_pow( func, 0, 1 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_CROSSPRODUCT: - /* TGSI_OPCODE_XPD */ - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || - IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { - FETCH( func, *inst, 1, 1, CHAN_Z ); - FETCH( func, *inst, 3, 0, CHAN_Z ); - } - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || - IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { - FETCH( func, *inst, 0, 0, CHAN_Y ); - FETCH( func, *inst, 4, 1, CHAN_Y ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { - emit_MOV( func, 2, 0 ); - emit_mul( func, 2, 1 ); - emit_MOV( func, 5, 3 ); - emit_mul( func, 5, 4 ); - emit_sub( func, 2, 5 ); - STORE( func, *inst, 2, 0, CHAN_X ); - } - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || - IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { - FETCH( func, *inst, 2, 1, CHAN_X ); - FETCH( func, *inst, 5, 0, CHAN_X ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { - emit_mul( func, 3, 2 ); - emit_mul( func, 1, 5 ); - emit_sub( func, 3, 1 ); - STORE( func, *inst, 3, 0, CHAN_Y ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { - emit_mul( func, 5, 4 ); - emit_mul( func, 0, 2 ); - emit_sub( func, 5, 0 ); - STORE( func, *inst, 5, 0, CHAN_Z ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { - FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C ); - STORE( func, *inst, 0, 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_MULTIPLYMATRIX: - return 0; - break; - - case TGSI_OPCODE_ABS: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - emit_abs( func, 0) ; - - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_RCC: - return 0; - break; - - case TGSI_OPCODE_DPH: - FETCH( func, *inst, 0, 0, CHAN_X ); - FETCH( func, *inst, 1, 1, CHAN_X ); - emit_mul( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Y ); - FETCH( func, *inst, 2, 1, CHAN_Y ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Z ); - FETCH( func, *inst, 2, 1, CHAN_Z ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FETCH( func, *inst, 1, 1, CHAN_W ); - emit_add( func, 0, 1 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_COS: - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_cos( func, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_DDX: - return 0; - break; - - case TGSI_OPCODE_DDY: - return 0; - break; - - case TGSI_OPCODE_KIL: - emit_kil( func, &inst->FullSrcRegisters[0] ); - break; - - case TGSI_OPCODE_PK2H: - return 0; - break; - - case TGSI_OPCODE_PK2US: - return 0; - break; - - case TGSI_OPCODE_PK4B: - return 0; - break; - - case TGSI_OPCODE_PK4UB: - return 0; - break; - - case TGSI_OPCODE_RFL: - return 0; - break; - - case TGSI_OPCODE_SEQ: - return 0; - break; - - case TGSI_OPCODE_SFL: - return 0; - break; - - case TGSI_OPCODE_SGT: - return 0; - break; - - case TGSI_OPCODE_SIN: - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_sin( func, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_SLE: - return 0; - break; - - case TGSI_OPCODE_SNE: - return 0; - break; - - case TGSI_OPCODE_STR: - return 0; - break; - - case TGSI_OPCODE_TEX: - emit_tempf( - func, - 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_TXD: - return 0; - break; - - case TGSI_OPCODE_UP2H: - return 0; - break; - - case TGSI_OPCODE_UP2US: - return 0; - break; - - case TGSI_OPCODE_UP4B: - return 0; - break; - - case TGSI_OPCODE_UP4UB: - return 0; - break; - - case TGSI_OPCODE_X2D: - return 0; - break; - - case TGSI_OPCODE_ARA: - return 0; - break; - - case TGSI_OPCODE_ARR: - return 0; - break; - - case TGSI_OPCODE_BRA: - return 0; - break; - - case TGSI_OPCODE_CAL: - return 0; - break; - - case TGSI_OPCODE_RET: - case TGSI_OPCODE_END: -#ifdef WIN32 - emit_retw( func, 16 ); -#else - emit_ret( func ); -#endif - break; - - case TGSI_OPCODE_SSG: - return 0; - break; - - case TGSI_OPCODE_CMP: - emit_cmp (func, inst); - break; - - case TGSI_OPCODE_SCS: - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_cos( func, 0 ); - STORE( func, *inst, 0, 0, CHAN_X ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { - FETCH( func, *inst, 0, 0, CHAN_Y ); - emit_sin( func, 0 ); - STORE( func, *inst, 0, 0, CHAN_Y ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { - FETCH( func, *inst, 0, TGSI_EXEC_TEMP_00000000_I, TGSI_EXEC_TEMP_00000000_C ); - STORE( func, *inst, 0, 0, CHAN_Z ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { - FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C ); - STORE( func, *inst, 0, 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_TXB: - return 0; - break; - - case TGSI_OPCODE_NRM: - return 0; - break; - - case TGSI_OPCODE_DIV: - return 0; - break; - - case TGSI_OPCODE_DP2: - return 0; - break; - - case TGSI_OPCODE_TXL: - return 0; - break; - - case TGSI_OPCODE_BRK: - return 0; - break; - - case TGSI_OPCODE_IF: - return 0; - break; - - case TGSI_OPCODE_LOOP: - return 0; - break; - - case TGSI_OPCODE_REP: - return 0; - break; - - case TGSI_OPCODE_ELSE: - return 0; - break; - - case TGSI_OPCODE_ENDIF: - return 0; - break; - - case TGSI_OPCODE_ENDLOOP: - return 0; - break; - - case TGSI_OPCODE_ENDREP: - return 0; - break; - - case TGSI_OPCODE_PUSHA: - return 0; - break; - - case TGSI_OPCODE_POPA: - return 0; - break; - - case TGSI_OPCODE_CEIL: - return 0; - break; - - case TGSI_OPCODE_I2F: - return 0; - break; - - case TGSI_OPCODE_NOT: - return 0; - break; - - case TGSI_OPCODE_TRUNC: - return 0; - break; - - case TGSI_OPCODE_SHL: - return 0; - break; - - case TGSI_OPCODE_SHR: - return 0; - break; - - case TGSI_OPCODE_AND: - return 0; - break; - - case TGSI_OPCODE_OR: - return 0; - break; - - case TGSI_OPCODE_MOD: - return 0; - break; - - case TGSI_OPCODE_XOR: - return 0; - break; - - case TGSI_OPCODE_SAD: - return 0; - break; - - case TGSI_OPCODE_TXF: - return 0; - break; - - case TGSI_OPCODE_TXQ: - return 0; - break; - - case TGSI_OPCODE_CONT: - return 0; - break; - - case TGSI_OPCODE_EMIT: - return 0; - break; - - case TGSI_OPCODE_ENDPRIM: - return 0; - break; - - default: - return 0; - } - - return 1; -} - -static void -emit_declaration( - struct x86_function *func, - struct tgsi_full_declaration *decl ) -{ - if( decl->Declaration.File == TGSI_FILE_INPUT ) { - unsigned first, last, mask; - unsigned i, j; - - assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); - - first = decl->u.DeclarationRange.First; - last = decl->u.DeclarationRange.Last; - mask = decl->Declaration.UsageMask; - - /* Do not touch WPOS.xy */ - if( first == 0 ) { - mask &= ~TGSI_WRITEMASK_XY; - if( mask == TGSI_WRITEMASK_NONE ) { - first++; - } - } - - for( i = first; i <= last; i++ ) { - for( j = 0; j < NUM_CHANNELS; j++ ) { - if( mask & (1 << j) ) { - switch( decl->Interpolation.Interpolate ) { - case TGSI_INTERPOLATE_CONSTANT: - emit_coef_a0( func, 0, i, j ); - emit_inputs( func, 0, i, j ); - break; - - case TGSI_INTERPOLATE_LINEAR: - emit_inputf( func, 0, 0, TGSI_SWIZZLE_X ); - emit_coef_dadx( func, 1, i, j ); - emit_inputf( func, 2, 0, TGSI_SWIZZLE_Y ); - emit_coef_dady( func, 3, i, j ); - emit_mul( func, 0, 1 ); /* x * dadx */ - emit_coef_a0( func, 4, i, j ); - emit_mul( func, 2, 3 ); /* y * dady */ - emit_add( func, 0, 4 ); /* x * dadx + a0 */ - emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */ - emit_inputs( func, 0, i, j ); - break; - - case TGSI_INTERPOLATE_PERSPECTIVE: - emit_inputf( func, 0, 0, TGSI_SWIZZLE_X ); - emit_coef_dadx( func, 1, i, j ); - emit_inputf( func, 2, 0, TGSI_SWIZZLE_Y ); - emit_coef_dady( func, 3, i, j ); - emit_mul( func, 0, 1 ); /* x * dadx */ - emit_inputf( func, 4, 0, TGSI_SWIZZLE_W ); - emit_coef_a0( func, 5, i, j ); - emit_rcp( func, 4, 4 ); /* 1.0 / w */ - emit_mul( func, 2, 3 ); /* y * dady */ - emit_add( func, 0, 5 ); /* x * dadx + a0 */ - emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */ - emit_mul( func, 0, 4 ); /* (x * dadx + y * dady + a0) / w */ - emit_inputs( func, 0, i, j ); - break; - - default: - assert( 0 ); - break; - } - } - } - } - } -} - -unsigned -tgsi_emit_sse2( - struct tgsi_token *tokens, - struct x86_function *func ) -{ - struct tgsi_parse_context parse; - unsigned ok = 1; - - DUMP_START(); - - func->csr = func->store; - - emit_mov( - func, - get_input_base(), - get_argument( 0 ) ); - emit_mov( - func, - get_output_base(), - get_argument( 1 ) ); - emit_mov( - func, - get_const_base(), - get_argument( 2 ) ); - emit_mov( - func, - get_temp_base(), - get_argument( 3 ) ); - - tgsi_parse_init( &parse, tokens ); - - while( !tgsi_parse_end_of_tokens( &parse ) && ok ) { - tgsi_parse_token( &parse ); - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - ok = emit_instruction( - func, - &parse.FullToken.FullInstruction ); - - if (!ok) { - debug_printf("failed to translate tgsi opcode %d\n", - parse.FullToken.FullInstruction.Instruction.Opcode ); - } - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - /* XXX implement this */ - ok = 0; - debug_printf("failed to emit immediate value\n"); - break; - - default: - assert( 0 ); - ok = 0; - break; - } - } - - tgsi_parse_free( &parse ); - - DUMP_END(); - - return ok; -} - -/** - * Fragment shaders are responsible for interpolating shader inputs. Because on - * x86 we have only 4 GP registers, and here we have 5 shader arguments (input, - * output, const, temp and coef), the code is split into two phases -- - * DECLARATION and INSTRUCTION phase. - * GP register holding the output argument is aliased with the coeff argument, - * as outputs are not needed in the DECLARATION phase. - */ -unsigned -tgsi_emit_sse2_fs( - struct tgsi_token *tokens, - struct x86_function *func ) -{ - struct tgsi_parse_context parse; - boolean instruction_phase = FALSE; - - DUMP_START(); - - func->csr = func->store; - - /* DECLARATION phase, do not load output argument. */ - emit_mov( - func, - get_input_base(), - get_argument( 0 ) ); - emit_mov( - func, - get_const_base(), - get_argument( 2 ) ); - emit_mov( - func, - get_temp_base(), - get_argument( 3 ) ); - emit_mov( - func, - get_coef_base(), - get_argument( 4 ) ); - - tgsi_parse_init( &parse, tokens ); - - while( !tgsi_parse_end_of_tokens( &parse ) ) { - tgsi_parse_token( &parse ); - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - emit_declaration( - func, - &parse.FullToken.FullDeclaration ); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - if( !instruction_phase ) { - /* INSTRUCTION phase, overwrite coeff with output. */ - instruction_phase = TRUE; - emit_mov( - func, - get_output_base(), - get_argument( 1 ) ); - } - emit_instruction( - func, - &parse.FullToken.FullInstruction ); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - /* XXX implement this */ - assert(0); - break; - - default: - assert( 0 ); - } - } - - tgsi_parse_free( &parse ); - - DUMP_END(); - - return 1; -} - -#endif /* i386 */ diff --git a/src/gallium/aux/tgsi/exec/tgsi_sse2.h b/src/gallium/aux/tgsi/exec/tgsi_sse2.h deleted file mode 100755 index 9bee371766..0000000000 --- a/src/gallium/aux/tgsi/exec/tgsi_sse2.h +++ /dev/null @@ -1,26 +0,0 @@ -#if !defined TGSI_SSE2_H -#define TGSI_SSE2_H - -#if defined __cplusplus -extern "C" { -#endif // defined __cplusplus - -struct tgsi_token; -struct x86_function; - -unsigned -tgsi_emit_sse2( - struct tgsi_token *tokens, - struct x86_function *function ); - -unsigned -tgsi_emit_sse2_fs( - struct tgsi_token *tokens, - struct x86_function *function ); - -#if defined __cplusplus -} // extern "C" -#endif // defined __cplusplus - -#endif // !defined TGSI_SSE2_H - diff --git a/src/gallium/aux/tgsi/util/tgsi_build.c b/src/gallium/aux/tgsi/util/tgsi_build.c deleted file mode 100644 index a00ff1c2a5..0000000000 --- a/src/gallium/aux/tgsi/util/tgsi_build.c +++ /dev/null @@ -1,1371 +0,0 @@ -#include "pipe/p_debug.h" -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi_build.h" -#include "tgsi_parse.h" - -/* - * version - */ - -struct tgsi_version -tgsi_build_version( void ) -{ - struct tgsi_version version; - - version.MajorVersion = 1; - version.MinorVersion = 1; - version.Padding = 0; - - return version; -} - -/* - * header - */ - -struct tgsi_header -tgsi_build_header( void ) -{ - struct tgsi_header header; - - header.HeaderSize = 1; - header.BodySize = 0; - - return header; -} - -static void -header_headersize_grow( struct tgsi_header *header ) -{ - assert( header->HeaderSize < 0xFF ); - assert( header->BodySize == 0 ); - - header->HeaderSize++; -} - -static void -header_bodysize_grow( struct tgsi_header *header ) -{ - assert( header->BodySize < 0xFFFFFF ); - - header->BodySize++; -} - -struct tgsi_processor -tgsi_default_processor( void ) -{ - struct tgsi_processor processor; - - processor.Processor = TGSI_PROCESSOR_FRAGMENT; - processor.Padding = 0; - - return processor; -} - -struct tgsi_processor -tgsi_build_processor( - unsigned type, - struct tgsi_header *header ) -{ - struct tgsi_processor processor; - - processor = tgsi_default_processor(); - processor.Processor = type; - - header_headersize_grow( header ); - - return processor; -} - -/* - * declaration - */ - -struct tgsi_declaration -tgsi_default_declaration( void ) -{ - struct tgsi_declaration declaration; - - declaration.Type = TGSI_TOKEN_TYPE_DECLARATION; - declaration.Size = 1; - declaration.File = TGSI_FILE_NULL; - declaration.Declare = TGSI_DECLARE_RANGE; - declaration.UsageMask = TGSI_WRITEMASK_XYZW; - declaration.Interpolate = 0; - declaration.Semantic = 0; - declaration.Padding = 0; - declaration.Extended = 0; - - return declaration; -} - -struct tgsi_declaration -tgsi_build_declaration( - unsigned file, - unsigned declare, - unsigned usage_mask, - unsigned interpolate, - unsigned semantic, - struct tgsi_header *header ) -{ - struct tgsi_declaration declaration; - - assert( file <= TGSI_FILE_IMMEDIATE ); - assert( declare <= TGSI_DECLARE_MASK ); - - declaration = tgsi_default_declaration(); - declaration.File = file; - declaration.Declare = declare; - declaration.UsageMask = usage_mask; - declaration.Interpolate = interpolate; - declaration.Semantic = semantic; - - header_bodysize_grow( header ); - - return declaration; -} - -static void -declaration_grow( - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - assert( declaration->Size < 0xFF ); - - declaration->Size++; - - header_bodysize_grow( header ); -} - -struct tgsi_full_declaration -tgsi_default_full_declaration( void ) -{ - struct tgsi_full_declaration full_declaration; - - full_declaration.Declaration = tgsi_default_declaration(); - full_declaration.Interpolation = tgsi_default_declaration_interpolation(); - full_declaration.Semantic = tgsi_default_declaration_semantic(); - - return full_declaration; -} - -unsigned -tgsi_build_full_declaration( - const struct tgsi_full_declaration *full_decl, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ) -{ - unsigned size = 0; - struct tgsi_declaration *declaration; - - if( maxsize <= size ) - return 0; - declaration = (struct tgsi_declaration *) &tokens[size]; - size++; - - *declaration = tgsi_build_declaration( - full_decl->Declaration.File, - full_decl->Declaration.Declare, - full_decl->Declaration.UsageMask, - full_decl->Declaration.Interpolate, - full_decl->Declaration.Semantic, - header ); - - switch( full_decl->Declaration.Declare ) { - case TGSI_DECLARE_RANGE: - { - struct tgsi_declaration_range *dr; - - if( maxsize <= size ) - return 0; - dr = (struct tgsi_declaration_range *) &tokens[size]; - size++; - - *dr = tgsi_build_declaration_range( - full_decl->u.DeclarationRange.First, - full_decl->u.DeclarationRange.Last, - declaration, - header ); - break; - } - - case TGSI_DECLARE_MASK: - { - struct tgsi_declaration_mask *dm; - - if( maxsize <= size ) - return 0; - dm = (struct tgsi_declaration_mask *) &tokens[size]; - size++; - - *dm = tgsi_build_declaration_mask( - full_decl->u.DeclarationMask.Mask, - declaration, - header ); - break; - } - - default: - assert( 0 ); - } - - if( full_decl->Declaration.Interpolate ) { - struct tgsi_declaration_interpolation *di; - - if( maxsize <= size ) - return 0; - di = (struct tgsi_declaration_interpolation *) &tokens[size]; - size++; - - *di = tgsi_build_declaration_interpolation( - full_decl->Interpolation.Interpolate, - declaration, - header ); - } - - if( full_decl->Declaration.Semantic ) { - struct tgsi_declaration_semantic *ds; - - if( maxsize <= size ) - return 0; - ds = (struct tgsi_declaration_semantic *) &tokens[size]; - size++; - - *ds = tgsi_build_declaration_semantic( - full_decl->Semantic.SemanticName, - full_decl->Semantic.SemanticIndex, - declaration, - header ); - } - - return size; -} - -struct tgsi_declaration_range -tgsi_build_declaration_range( - unsigned first, - unsigned last, - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - struct tgsi_declaration_range declaration_range; - - assert( last >= first ); - assert( last <= 0xFFFF ); - - declaration_range.First = first; - declaration_range.Last = last; - - declaration_grow( declaration, header ); - - return declaration_range; -} - -struct tgsi_declaration_mask -tgsi_build_declaration_mask( - unsigned mask, - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - struct tgsi_declaration_mask declaration_mask; - - declaration_mask.Mask = mask; - - declaration_grow( declaration, header ); - - return declaration_mask; -} - -struct tgsi_declaration_interpolation -tgsi_default_declaration_interpolation( void ) -{ - struct tgsi_declaration_interpolation di; - - di.Interpolate = TGSI_INTERPOLATE_CONSTANT; - di.Padding = 0; - - return di; -} - -struct tgsi_declaration_interpolation -tgsi_build_declaration_interpolation( - unsigned interpolate, - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - struct tgsi_declaration_interpolation di; - - assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE ); - - di = tgsi_default_declaration_interpolation(); - di.Interpolate = interpolate; - - declaration_grow( declaration, header ); - - return di; -} - -struct tgsi_declaration_semantic -tgsi_default_declaration_semantic( void ) -{ - struct tgsi_declaration_semantic ds; - - ds.SemanticName = TGSI_SEMANTIC_POSITION; - ds.SemanticIndex = 0; - ds.Padding = 0; - - return ds; -} - -struct tgsi_declaration_semantic -tgsi_build_declaration_semantic( - unsigned semantic_name, - unsigned semantic_index, - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - struct tgsi_declaration_semantic ds; - - assert( semantic_name <= TGSI_SEMANTIC_COUNT ); - assert( semantic_index <= 0xFFFF ); - - ds = tgsi_default_declaration_semantic(); - ds.SemanticName = semantic_name; - ds.SemanticIndex = semantic_index; - - declaration_grow( declaration, header ); - - return ds; -} - -/* - * immediate - */ - -struct tgsi_immediate -tgsi_default_immediate( void ) -{ - struct tgsi_immediate immediate; - - immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE; - immediate.Size = 1; - immediate.DataType = TGSI_IMM_FLOAT32; - immediate.Padding = 0; - immediate.Extended = 0; - - return immediate; -} - -struct tgsi_immediate -tgsi_build_immediate( - struct tgsi_header *header ) -{ - struct tgsi_immediate immediate; - - immediate = tgsi_default_immediate(); - - header_bodysize_grow( header ); - - return immediate; -} - -struct tgsi_full_immediate -tgsi_default_full_immediate( void ) -{ - struct tgsi_full_immediate fullimm; - - fullimm.Immediate = tgsi_default_immediate(); - fullimm.u.Pointer = (void *) 0; - - return fullimm; -} - -static void -immediate_grow( - struct tgsi_immediate *immediate, - struct tgsi_header *header ) -{ - assert( immediate->Size < 0xFF ); - - immediate->Size++; - - header_bodysize_grow( header ); -} - -struct tgsi_immediate_float32 -tgsi_build_immediate_float32( - float value, - struct tgsi_immediate *immediate, - struct tgsi_header *header ) -{ - struct tgsi_immediate_float32 immediate_float32; - - immediate_float32.Float = value; - - immediate_grow( immediate, header ); - - return immediate_float32; -} - -unsigned -tgsi_build_full_immediate( - const struct tgsi_full_immediate *full_imm, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ) -{ - unsigned size = 0, i; - struct tgsi_immediate *immediate; - - if( maxsize <= size ) - return 0; - immediate = (struct tgsi_immediate *) &tokens[size]; - size++; - - *immediate = tgsi_build_immediate( header ); - - for( i = 0; i < full_imm->Immediate.Size - 1; i++ ) { - struct tgsi_immediate_float32 *if32; - - if( maxsize <= size ) - return 0; - if32 = (struct tgsi_immediate_float32 *) &tokens[size]; - size++; - - *if32 = tgsi_build_immediate_float32( - full_imm->u.ImmediateFloat32[i].Float, - immediate, - header ); - } - - return size; -} - -/* - * instruction - */ - -struct tgsi_instruction -tgsi_default_instruction( void ) -{ - struct tgsi_instruction instruction; - - instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; - instruction.Size = 1; - instruction.Opcode = TGSI_OPCODE_MOV; - instruction.Saturate = TGSI_SAT_NONE; - instruction.NumDstRegs = 1; - instruction.NumSrcRegs = 1; - instruction.Padding = 0; - instruction.Extended = 0; - - return instruction; -} - -struct tgsi_instruction -tgsi_build_instruction( - unsigned opcode, - unsigned saturate, - unsigned num_dst_regs, - unsigned num_src_regs, - struct tgsi_header *header ) -{ - struct tgsi_instruction instruction; - - assert (opcode <= TGSI_OPCODE_LAST); - assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE); - assert (num_dst_regs <= 3); - assert (num_src_regs <= 15); - - instruction = tgsi_default_instruction(); - instruction.Opcode = opcode; - instruction.Saturate = saturate; - instruction.NumDstRegs = num_dst_regs; - instruction.NumSrcRegs = num_src_regs; - - header_bodysize_grow( header ); - - return instruction; -} - -static void -instruction_grow( - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - assert (instruction->Size < 0xFF); - - instruction->Size++; - - header_bodysize_grow( header ); -} - -struct tgsi_full_instruction -tgsi_default_full_instruction( void ) -{ - struct tgsi_full_instruction full_instruction; - unsigned i; - - full_instruction.Instruction = tgsi_default_instruction(); - full_instruction.InstructionExtNv = tgsi_default_instruction_ext_nv(); - full_instruction.InstructionExtLabel = tgsi_default_instruction_ext_label(); - full_instruction.InstructionExtTexture = tgsi_default_instruction_ext_texture(); - for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) { - full_instruction.FullDstRegisters[i] = tgsi_default_full_dst_register(); - } - for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) { - full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register(); - } - - return full_instruction; -} - -unsigned -tgsi_build_full_instruction( - const struct tgsi_full_instruction *full_inst, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ) -{ - unsigned size = 0; - unsigned i; - struct tgsi_instruction *instruction; - struct tgsi_token *prev_token; - - if( maxsize <= size ) - return 0; - instruction = (struct tgsi_instruction *) &tokens[size]; - size++; - - *instruction = tgsi_build_instruction( - full_inst->Instruction.Opcode, - full_inst->Instruction.Saturate, - full_inst->Instruction.NumDstRegs, - full_inst->Instruction.NumSrcRegs, - header ); - prev_token = (struct tgsi_token *) instruction; - - if( tgsi_compare_instruction_ext_nv( - full_inst->InstructionExtNv, - tgsi_default_instruction_ext_nv() ) ) { - struct tgsi_instruction_ext_nv *instruction_ext_nv; - - if( maxsize <= size ) - return 0; - instruction_ext_nv = - (struct tgsi_instruction_ext_nv *) &tokens[size]; - size++; - - *instruction_ext_nv = tgsi_build_instruction_ext_nv( - full_inst->InstructionExtNv.Precision, - full_inst->InstructionExtNv.CondDstIndex, - full_inst->InstructionExtNv.CondFlowIndex, - full_inst->InstructionExtNv.CondMask, - full_inst->InstructionExtNv.CondSwizzleX, - full_inst->InstructionExtNv.CondSwizzleY, - full_inst->InstructionExtNv.CondSwizzleZ, - full_inst->InstructionExtNv.CondSwizzleW, - full_inst->InstructionExtNv.CondDstUpdate, - full_inst->InstructionExtNv.CondFlowEnable, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) instruction_ext_nv; - } - - if( tgsi_compare_instruction_ext_label( - full_inst->InstructionExtLabel, - tgsi_default_instruction_ext_label() ) ) { - struct tgsi_instruction_ext_label *instruction_ext_label; - - if( maxsize <= size ) - return 0; - instruction_ext_label = - (struct tgsi_instruction_ext_label *) &tokens[size]; - size++; - - *instruction_ext_label = tgsi_build_instruction_ext_label( - full_inst->InstructionExtLabel.Label, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) instruction_ext_label; - } - - if( tgsi_compare_instruction_ext_texture( - full_inst->InstructionExtTexture, - tgsi_default_instruction_ext_texture() ) ) { - struct tgsi_instruction_ext_texture *instruction_ext_texture; - - if( maxsize <= size ) - return 0; - instruction_ext_texture = - (struct tgsi_instruction_ext_texture *) &tokens[size]; - size++; - - *instruction_ext_texture = tgsi_build_instruction_ext_texture( - full_inst->InstructionExtTexture.Texture, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) instruction_ext_texture; - } - - for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { - const struct tgsi_full_dst_register *reg = &full_inst->FullDstRegisters[i]; - struct tgsi_dst_register *dst_register; - struct tgsi_token *prev_token; - - if( maxsize <= size ) - return 0; - dst_register = (struct tgsi_dst_register *) &tokens[size]; - size++; - - *dst_register = tgsi_build_dst_register( - reg->DstRegister.File, - reg->DstRegister.WriteMask, - reg->DstRegister.Index, - instruction, - header ); - prev_token = (struct tgsi_token *) dst_register; - - if( tgsi_compare_dst_register_ext_concode( - reg->DstRegisterExtConcode, - tgsi_default_dst_register_ext_concode() ) ) { - struct tgsi_dst_register_ext_concode *dst_register_ext_concode; - - if( maxsize <= size ) - return 0; - dst_register_ext_concode = - (struct tgsi_dst_register_ext_concode *) &tokens[size]; - size++; - - *dst_register_ext_concode = tgsi_build_dst_register_ext_concode( - reg->DstRegisterExtConcode.CondMask, - reg->DstRegisterExtConcode.CondSwizzleX, - reg->DstRegisterExtConcode.CondSwizzleY, - reg->DstRegisterExtConcode.CondSwizzleZ, - reg->DstRegisterExtConcode.CondSwizzleW, - reg->DstRegisterExtConcode.CondSrcIndex, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) dst_register_ext_concode; - } - - if( tgsi_compare_dst_register_ext_modulate( - reg->DstRegisterExtModulate, - tgsi_default_dst_register_ext_modulate() ) ) { - struct tgsi_dst_register_ext_modulate *dst_register_ext_modulate; - - if( maxsize <= size ) - return 0; - dst_register_ext_modulate = - (struct tgsi_dst_register_ext_modulate *) &tokens[size]; - size++; - - *dst_register_ext_modulate = tgsi_build_dst_register_ext_modulate( - reg->DstRegisterExtModulate.Modulate, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) dst_register_ext_modulate; - } - } - - for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { - const struct tgsi_full_src_register *reg = &full_inst->FullSrcRegisters[i]; - struct tgsi_src_register *src_register; - struct tgsi_token *prev_token; - - if( maxsize <= size ) - return 0; - src_register = (struct tgsi_src_register *) &tokens[size]; - size++; - - *src_register = tgsi_build_src_register( - reg->SrcRegister.File, - reg->SrcRegister.SwizzleX, - reg->SrcRegister.SwizzleY, - reg->SrcRegister.SwizzleZ, - reg->SrcRegister.SwizzleW, - reg->SrcRegister.Negate, - reg->SrcRegister.Indirect, - reg->SrcRegister.Dimension, - reg->SrcRegister.Index, - instruction, - header ); - prev_token = (struct tgsi_token *) src_register; - - if( tgsi_compare_src_register_ext_swz( - reg->SrcRegisterExtSwz, - tgsi_default_src_register_ext_swz() ) ) { - struct tgsi_src_register_ext_swz *src_register_ext_swz; - - if( maxsize <= size ) - return 0; - src_register_ext_swz = - (struct tgsi_src_register_ext_swz *) &tokens[size]; - size++; - - *src_register_ext_swz = tgsi_build_src_register_ext_swz( - reg->SrcRegisterExtSwz.ExtSwizzleX, - reg->SrcRegisterExtSwz.ExtSwizzleY, - reg->SrcRegisterExtSwz.ExtSwizzleZ, - reg->SrcRegisterExtSwz.ExtSwizzleW, - reg->SrcRegisterExtSwz.NegateX, - reg->SrcRegisterExtSwz.NegateY, - reg->SrcRegisterExtSwz.NegateZ, - reg->SrcRegisterExtSwz.NegateW, - reg->SrcRegisterExtSwz.ExtDivide, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) src_register_ext_swz; - } - - if( tgsi_compare_src_register_ext_mod( - reg->SrcRegisterExtMod, - tgsi_default_src_register_ext_mod() ) ) { - struct tgsi_src_register_ext_mod *src_register_ext_mod; - - if( maxsize <= size ) - return 0; - src_register_ext_mod = - (struct tgsi_src_register_ext_mod *) &tokens[size]; - size++; - - *src_register_ext_mod = tgsi_build_src_register_ext_mod( - reg->SrcRegisterExtMod.Complement, - reg->SrcRegisterExtMod.Bias, - reg->SrcRegisterExtMod.Scale2X, - reg->SrcRegisterExtMod.Absolute, - reg->SrcRegisterExtMod.Negate, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) src_register_ext_mod; - } - - if( reg->SrcRegister.Indirect ) { - struct tgsi_src_register *ind; - - if( maxsize <= size ) - return 0; - ind = (struct tgsi_src_register *) &tokens[size]; - size++; - - *ind = tgsi_build_src_register( - reg->SrcRegisterInd.File, - reg->SrcRegisterInd.SwizzleX, - reg->SrcRegisterInd.SwizzleY, - reg->SrcRegisterInd.SwizzleZ, - reg->SrcRegisterInd.SwizzleW, - reg->SrcRegisterInd.Negate, - reg->SrcRegisterInd.Indirect, - reg->SrcRegisterInd.Dimension, - reg->SrcRegisterInd.Index, - instruction, - header ); - } - - if( reg->SrcRegister.Dimension ) { - struct tgsi_dimension *dim; - - assert( !reg->SrcRegisterDim.Dimension ); - - if( maxsize <= size ) - return 0; - dim = (struct tgsi_dimension *) &tokens[size]; - size++; - - *dim = tgsi_build_dimension( - reg->SrcRegisterDim.Indirect, - reg->SrcRegisterDim.Index, - instruction, - header ); - - if( reg->SrcRegisterDim.Indirect ) { - struct tgsi_src_register *ind; - - if( maxsize <= size ) - return 0; - ind = (struct tgsi_src_register *) &tokens[size]; - size++; - - *ind = tgsi_build_src_register( - reg->SrcRegisterDimInd.File, - reg->SrcRegisterDimInd.SwizzleX, - reg->SrcRegisterDimInd.SwizzleY, - reg->SrcRegisterDimInd.SwizzleZ, - reg->SrcRegisterDimInd.SwizzleW, - reg->SrcRegisterDimInd.Negate, - reg->SrcRegisterDimInd.Indirect, - reg->SrcRegisterDimInd.Dimension, - reg->SrcRegisterDimInd.Index, - instruction, - header ); - } - } - } - - return size; -} - -struct tgsi_instruction_ext_nv -tgsi_default_instruction_ext_nv( void ) -{ - struct tgsi_instruction_ext_nv instruction_ext_nv; - - instruction_ext_nv.Type = TGSI_INSTRUCTION_EXT_TYPE_NV; - instruction_ext_nv.Precision = TGSI_PRECISION_DEFAULT; - instruction_ext_nv.CondDstIndex = 0; - instruction_ext_nv.CondFlowIndex = 0; - instruction_ext_nv.CondMask = TGSI_CC_TR; - instruction_ext_nv.CondSwizzleX = TGSI_SWIZZLE_X; - instruction_ext_nv.CondSwizzleY = TGSI_SWIZZLE_Y; - instruction_ext_nv.CondSwizzleZ = TGSI_SWIZZLE_Z; - instruction_ext_nv.CondSwizzleW = TGSI_SWIZZLE_W; - instruction_ext_nv.CondDstUpdate = 0; - instruction_ext_nv.CondFlowEnable = 0; - instruction_ext_nv.Padding = 0; - instruction_ext_nv.Extended = 0; - - return instruction_ext_nv; -} - -union token_u32 -{ - unsigned u32; -}; - -unsigned -tgsi_compare_instruction_ext_nv( - struct tgsi_instruction_ext_nv a, - struct tgsi_instruction_ext_nv b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_instruction_ext_nv -tgsi_build_instruction_ext_nv( - unsigned precision, - unsigned cond_dst_index, - unsigned cond_flow_index, - unsigned cond_mask, - unsigned cond_swizzle_x, - unsigned cond_swizzle_y, - unsigned cond_swizzle_z, - unsigned cond_swizzle_w, - unsigned cond_dst_update, - unsigned cond_flow_update, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_instruction_ext_nv instruction_ext_nv; - - instruction_ext_nv = tgsi_default_instruction_ext_nv(); - instruction_ext_nv.Precision = precision; - instruction_ext_nv.CondDstIndex = cond_dst_index; - instruction_ext_nv.CondFlowIndex = cond_flow_index; - instruction_ext_nv.CondMask = cond_mask; - instruction_ext_nv.CondSwizzleX = cond_swizzle_x; - instruction_ext_nv.CondSwizzleY = cond_swizzle_y; - instruction_ext_nv.CondSwizzleZ = cond_swizzle_z; - instruction_ext_nv.CondSwizzleW = cond_swizzle_w; - instruction_ext_nv.CondDstUpdate = cond_dst_update; - instruction_ext_nv.CondFlowEnable = cond_flow_update; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return instruction_ext_nv; -} - -struct tgsi_instruction_ext_label -tgsi_default_instruction_ext_label( void ) -{ - struct tgsi_instruction_ext_label instruction_ext_label; - - instruction_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL; - instruction_ext_label.Label = 0; - instruction_ext_label.Padding = 0; - instruction_ext_label.Extended = 0; - - return instruction_ext_label; -} - -unsigned -tgsi_compare_instruction_ext_label( - struct tgsi_instruction_ext_label a, - struct tgsi_instruction_ext_label b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_instruction_ext_label -tgsi_build_instruction_ext_label( - unsigned label, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_instruction_ext_label instruction_ext_label; - - instruction_ext_label = tgsi_default_instruction_ext_label(); - instruction_ext_label.Label = label; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return instruction_ext_label; -} - -struct tgsi_instruction_ext_texture -tgsi_default_instruction_ext_texture( void ) -{ - struct tgsi_instruction_ext_texture instruction_ext_texture; - - instruction_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE; - instruction_ext_texture.Texture = TGSI_TEXTURE_UNKNOWN; - instruction_ext_texture.Padding = 0; - instruction_ext_texture.Extended = 0; - - return instruction_ext_texture; -} - -unsigned -tgsi_compare_instruction_ext_texture( - struct tgsi_instruction_ext_texture a, - struct tgsi_instruction_ext_texture b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_instruction_ext_texture -tgsi_build_instruction_ext_texture( - unsigned texture, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_instruction_ext_texture instruction_ext_texture; - - instruction_ext_texture = tgsi_default_instruction_ext_texture(); - instruction_ext_texture.Texture = texture; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return instruction_ext_texture; -} - -struct tgsi_src_register -tgsi_default_src_register( void ) -{ - struct tgsi_src_register src_register; - - src_register.File = TGSI_FILE_NULL; - src_register.SwizzleX = TGSI_SWIZZLE_X; - src_register.SwizzleY = TGSI_SWIZZLE_Y; - src_register.SwizzleZ = TGSI_SWIZZLE_Z; - src_register.SwizzleW = TGSI_SWIZZLE_W; - src_register.Negate = 0; - src_register.Indirect = 0; - src_register.Dimension = 0; - src_register.Index = 0; - src_register.Extended = 0; - - return src_register; -} - -struct tgsi_src_register -tgsi_build_src_register( - unsigned file, - unsigned swizzle_x, - unsigned swizzle_y, - unsigned swizzle_z, - unsigned swizzle_w, - unsigned negate, - unsigned indirect, - unsigned dimension, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_src_register src_register; - - assert( file <= TGSI_FILE_IMMEDIATE ); - assert( swizzle_x <= TGSI_SWIZZLE_W ); - assert( swizzle_y <= TGSI_SWIZZLE_W ); - assert( swizzle_z <= TGSI_SWIZZLE_W ); - assert( swizzle_w <= TGSI_SWIZZLE_W ); - assert( negate <= 1 ); - assert( index >= -0x8000 && index <= 0x7FFF ); - - src_register = tgsi_default_src_register(); - src_register.File = file; - src_register.SwizzleX = swizzle_x; - src_register.SwizzleY = swizzle_y; - src_register.SwizzleZ = swizzle_z; - src_register.SwizzleW = swizzle_w; - src_register.Negate = negate; - src_register.Indirect = indirect; - src_register.Dimension = dimension; - src_register.Index = index; - - instruction_grow( instruction, header ); - - return src_register; -} - -struct tgsi_full_src_register -tgsi_default_full_src_register( void ) -{ - struct tgsi_full_src_register full_src_register; - - full_src_register.SrcRegister = tgsi_default_src_register(); - full_src_register.SrcRegisterExtSwz = tgsi_default_src_register_ext_swz(); - full_src_register.SrcRegisterExtMod = tgsi_default_src_register_ext_mod(); - full_src_register.SrcRegisterInd = tgsi_default_src_register(); - full_src_register.SrcRegisterDim = tgsi_default_dimension(); - full_src_register.SrcRegisterDimInd = tgsi_default_src_register(); - - return full_src_register; -} - -struct tgsi_src_register_ext_swz -tgsi_default_src_register_ext_swz( void ) -{ - struct tgsi_src_register_ext_swz src_register_ext_swz; - - src_register_ext_swz.Type = TGSI_SRC_REGISTER_EXT_TYPE_SWZ; - src_register_ext_swz.ExtSwizzleX = TGSI_EXTSWIZZLE_X; - src_register_ext_swz.ExtSwizzleY = TGSI_EXTSWIZZLE_Y; - src_register_ext_swz.ExtSwizzleZ = TGSI_EXTSWIZZLE_Z; - src_register_ext_swz.ExtSwizzleW = TGSI_EXTSWIZZLE_W; - src_register_ext_swz.NegateX = 0; - src_register_ext_swz.NegateY = 0; - src_register_ext_swz.NegateZ = 0; - src_register_ext_swz.NegateW = 0; - src_register_ext_swz.ExtDivide = TGSI_EXTSWIZZLE_ONE; - src_register_ext_swz.Padding = 0; - src_register_ext_swz.Extended = 0; - - return src_register_ext_swz; -} - -unsigned -tgsi_compare_src_register_ext_swz( - struct tgsi_src_register_ext_swz a, - struct tgsi_src_register_ext_swz b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_src_register_ext_swz -tgsi_build_src_register_ext_swz( - unsigned ext_swizzle_x, - unsigned ext_swizzle_y, - unsigned ext_swizzle_z, - unsigned ext_swizzle_w, - unsigned negate_x, - unsigned negate_y, - unsigned negate_z, - unsigned negate_w, - unsigned ext_divide, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_src_register_ext_swz src_register_ext_swz; - - assert( ext_swizzle_x <= TGSI_EXTSWIZZLE_ONE ); - assert( ext_swizzle_y <= TGSI_EXTSWIZZLE_ONE ); - assert( ext_swizzle_z <= TGSI_EXTSWIZZLE_ONE ); - assert( ext_swizzle_w <= TGSI_EXTSWIZZLE_ONE ); - assert( negate_x <= 1 ); - assert( negate_y <= 1 ); - assert( negate_z <= 1 ); - assert( negate_w <= 1 ); - assert( ext_divide <= TGSI_EXTSWIZZLE_ONE ); - - src_register_ext_swz = tgsi_default_src_register_ext_swz(); - src_register_ext_swz.ExtSwizzleX = ext_swizzle_x; - src_register_ext_swz.ExtSwizzleY = ext_swizzle_y; - src_register_ext_swz.ExtSwizzleZ = ext_swizzle_z; - src_register_ext_swz.ExtSwizzleW = ext_swizzle_w; - src_register_ext_swz.NegateX = negate_x; - src_register_ext_swz.NegateY = negate_y; - src_register_ext_swz.NegateZ = negate_z; - src_register_ext_swz.NegateW = negate_w; - src_register_ext_swz.ExtDivide = ext_divide; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return src_register_ext_swz; -} - -struct tgsi_src_register_ext_mod -tgsi_default_src_register_ext_mod( void ) -{ - struct tgsi_src_register_ext_mod src_register_ext_mod; - - src_register_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD; - src_register_ext_mod.Complement = 0; - src_register_ext_mod.Bias = 0; - src_register_ext_mod.Scale2X = 0; - src_register_ext_mod.Absolute = 0; - src_register_ext_mod.Negate = 0; - src_register_ext_mod.Padding = 0; - src_register_ext_mod.Extended = 0; - - return src_register_ext_mod; -} - -unsigned -tgsi_compare_src_register_ext_mod( - struct tgsi_src_register_ext_mod a, - struct tgsi_src_register_ext_mod b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_src_register_ext_mod -tgsi_build_src_register_ext_mod( - unsigned complement, - unsigned bias, - unsigned scale_2x, - unsigned absolute, - unsigned negate, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_src_register_ext_mod src_register_ext_mod; - - assert( complement <= 1 ); - assert( bias <= 1 ); - assert( scale_2x <= 1 ); - assert( absolute <= 1 ); - assert( negate <= 1 ); - - src_register_ext_mod = tgsi_default_src_register_ext_mod(); - src_register_ext_mod.Complement = complement; - src_register_ext_mod.Bias = bias; - src_register_ext_mod.Scale2X = scale_2x; - src_register_ext_mod.Absolute = absolute; - src_register_ext_mod.Negate = negate; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return src_register_ext_mod; -} - -struct tgsi_dimension -tgsi_default_dimension( void ) -{ - struct tgsi_dimension dimension; - - dimension.Indirect = 0; - dimension.Dimension = 0; - dimension.Padding = 0; - dimension.Index = 0; - dimension.Extended = 0; - - return dimension; -} - -struct tgsi_dimension -tgsi_build_dimension( - unsigned indirect, - unsigned index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_dimension dimension; - - dimension = tgsi_default_dimension(); - dimension.Indirect = indirect; - dimension.Index = index; - - instruction_grow( instruction, header ); - - return dimension; -} - -struct tgsi_dst_register -tgsi_default_dst_register( void ) -{ - struct tgsi_dst_register dst_register; - - dst_register.File = TGSI_FILE_NULL; - dst_register.WriteMask = TGSI_WRITEMASK_XYZW; - dst_register.Indirect = 0; - dst_register.Dimension = 0; - dst_register.Index = 0; - dst_register.Padding = 0; - dst_register.Extended = 0; - - return dst_register; -} - -struct tgsi_dst_register -tgsi_build_dst_register( - unsigned file, - unsigned mask, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_dst_register dst_register; - - assert( file <= TGSI_FILE_IMMEDIATE ); - assert( mask <= TGSI_WRITEMASK_XYZW ); - assert( index >= -32768 && index <= 32767 ); - - dst_register = tgsi_default_dst_register(); - dst_register.File = file; - dst_register.WriteMask = mask; - dst_register.Index = index; - - instruction_grow( instruction, header ); - - return dst_register; -} - -struct tgsi_full_dst_register -tgsi_default_full_dst_register( void ) -{ - struct tgsi_full_dst_register full_dst_register; - - full_dst_register.DstRegister = tgsi_default_dst_register(); - full_dst_register.DstRegisterExtConcode = - tgsi_default_dst_register_ext_concode(); - full_dst_register.DstRegisterExtModulate = - tgsi_default_dst_register_ext_modulate(); - - return full_dst_register; -} - -struct tgsi_dst_register_ext_concode -tgsi_default_dst_register_ext_concode( void ) -{ - struct tgsi_dst_register_ext_concode dst_register_ext_concode; - - dst_register_ext_concode.Type = TGSI_DST_REGISTER_EXT_TYPE_CONDCODE; - dst_register_ext_concode.CondMask = TGSI_CC_TR; - dst_register_ext_concode.CondSwizzleX = TGSI_SWIZZLE_X; - dst_register_ext_concode.CondSwizzleY = TGSI_SWIZZLE_Y; - dst_register_ext_concode.CondSwizzleZ = TGSI_SWIZZLE_Z; - dst_register_ext_concode.CondSwizzleW = TGSI_SWIZZLE_W; - dst_register_ext_concode.CondSrcIndex = 0; - dst_register_ext_concode.Padding = 0; - dst_register_ext_concode.Extended = 0; - - return dst_register_ext_concode; -} - -unsigned -tgsi_compare_dst_register_ext_concode( - struct tgsi_dst_register_ext_concode a, - struct tgsi_dst_register_ext_concode b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_dst_register_ext_concode -tgsi_build_dst_register_ext_concode( - unsigned cc, - unsigned swizzle_x, - unsigned swizzle_y, - unsigned swizzle_z, - unsigned swizzle_w, - int index, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_dst_register_ext_concode dst_register_ext_concode; - - assert( cc <= TGSI_CC_FL ); - assert( swizzle_x <= TGSI_SWIZZLE_W ); - assert( swizzle_y <= TGSI_SWIZZLE_W ); - assert( swizzle_z <= TGSI_SWIZZLE_W ); - assert( swizzle_w <= TGSI_SWIZZLE_W ); - assert( index >= -32768 && index <= 32767 ); - - dst_register_ext_concode = tgsi_default_dst_register_ext_concode(); - dst_register_ext_concode.CondMask = cc; - dst_register_ext_concode.CondSwizzleX = swizzle_x; - dst_register_ext_concode.CondSwizzleY = swizzle_y; - dst_register_ext_concode.CondSwizzleZ = swizzle_z; - dst_register_ext_concode.CondSwizzleW = swizzle_w; - dst_register_ext_concode.CondSrcIndex = index; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return dst_register_ext_concode; -} - -struct tgsi_dst_register_ext_modulate -tgsi_default_dst_register_ext_modulate( void ) -{ - struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; - - dst_register_ext_modulate.Type = TGSI_DST_REGISTER_EXT_TYPE_MODULATE; - dst_register_ext_modulate.Modulate = TGSI_MODULATE_1X; - dst_register_ext_modulate.Padding = 0; - dst_register_ext_modulate.Extended = 0; - - return dst_register_ext_modulate; -} - -unsigned -tgsi_compare_dst_register_ext_modulate( - struct tgsi_dst_register_ext_modulate a, - struct tgsi_dst_register_ext_modulate b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_dst_register_ext_modulate -tgsi_build_dst_register_ext_modulate( - unsigned modulate, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; - - assert( modulate <= TGSI_MODULATE_EIGHTH ); - - dst_register_ext_modulate = tgsi_default_dst_register_ext_modulate(); - dst_register_ext_modulate.Modulate = modulate; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return dst_register_ext_modulate; -} - diff --git a/src/gallium/aux/tgsi/util/tgsi_build.h b/src/gallium/aux/tgsi/util/tgsi_build.h deleted file mode 100644 index 116c78abf3..0000000000 --- a/src/gallium/aux/tgsi/util/tgsi_build.h +++ /dev/null @@ -1,320 +0,0 @@ -#if !defined TGSI_BUILD_H -#define TGSI_BUILD_H - -#if defined __cplusplus -extern "C" { -#endif // defined __cplusplus - -/* - * version - */ - -struct tgsi_version -tgsi_build_version( void ); - -/* - * header - */ - -struct tgsi_header -tgsi_build_header( void ); - -struct tgsi_processor -tgsi_default_processor( void ); - -struct tgsi_processor -tgsi_build_processor( - unsigned processor, - struct tgsi_header *header ); - -/* - * declaration - */ - -struct tgsi_declaration -tgsi_default_declaration( void ); - -struct tgsi_declaration -tgsi_build_declaration( - unsigned file, - unsigned declare, - unsigned usage_mask, - unsigned interpolate, - unsigned semantic, - struct tgsi_header *header ); - -struct tgsi_full_declaration -tgsi_default_full_declaration( void ); - -unsigned -tgsi_build_full_declaration( - const struct tgsi_full_declaration *full_decl, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ); - -struct tgsi_declaration_range -tgsi_build_declaration_range( - unsigned first, - unsigned last, - struct tgsi_declaration *declaration, - struct tgsi_header *header ); - -struct tgsi_declaration_mask -tgsi_build_declaration_mask( - unsigned mask, - struct tgsi_declaration *declaration, - struct tgsi_header *header ); - -struct tgsi_declaration_interpolation -tgsi_default_declaration_interpolation( void ); - -struct tgsi_declaration_interpolation -tgsi_build_declaration_interpolation( - unsigned interpolate, - struct tgsi_declaration *declaration, - struct tgsi_header *header ); - -struct tgsi_declaration_semantic -tgsi_default_declaration_semantic( void ); - -struct tgsi_declaration_semantic -tgsi_build_declaration_semantic( - unsigned semantic_name, - unsigned semantic_index, - struct tgsi_declaration *declaration, - struct tgsi_header *header ); - -/* - * immediate - */ - -struct tgsi_immediate -tgsi_default_immediate( void ); - -struct tgsi_immediate -tgsi_build_immediate( - struct tgsi_header *header ); - -struct tgsi_full_immediate -tgsi_default_full_immediate( void ); - -struct tgsi_immediate_float32 -tgsi_build_immediate_float32( - float value, - struct tgsi_immediate *immediate, - struct tgsi_header *header ); - -unsigned -tgsi_build_full_immediate( - const struct tgsi_full_immediate *full_imm, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ); - -/* - * instruction - */ - -struct tgsi_instruction -tgsi_default_instruction( void ); - -struct tgsi_instruction -tgsi_build_instruction( - unsigned opcode, - unsigned saturate, - unsigned num_dst_regs, - unsigned num_src_regs, - struct tgsi_header *header ); - -struct tgsi_full_instruction -tgsi_default_full_instruction( void ); - -unsigned -tgsi_build_full_instruction( - const struct tgsi_full_instruction *full_inst, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ); - -struct tgsi_instruction_ext_nv -tgsi_default_instruction_ext_nv( void ); - -unsigned -tgsi_compare_instruction_ext_nv( - struct tgsi_instruction_ext_nv a, - struct tgsi_instruction_ext_nv b ); - -struct tgsi_instruction_ext_nv -tgsi_build_instruction_ext_nv( - unsigned precision, - unsigned cond_dst_index, - unsigned cond_flow_index, - unsigned cond_mask, - unsigned cond_swizzle_x, - unsigned cond_swizzle_y, - unsigned cond_swizzle_z, - unsigned cond_swizzle_w, - unsigned cond_dst_update, - unsigned cond_flow_update, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_instruction_ext_label -tgsi_default_instruction_ext_label( void ); - -unsigned -tgsi_compare_instruction_ext_label( - struct tgsi_instruction_ext_label a, - struct tgsi_instruction_ext_label b ); - -struct tgsi_instruction_ext_label -tgsi_build_instruction_ext_label( - unsigned label, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_instruction_ext_texture -tgsi_default_instruction_ext_texture( void ); - -unsigned -tgsi_compare_instruction_ext_texture( - struct tgsi_instruction_ext_texture a, - struct tgsi_instruction_ext_texture b ); - -struct tgsi_instruction_ext_texture -tgsi_build_instruction_ext_texture( - unsigned texture, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_src_register -tgsi_default_src_register( void ); - -struct tgsi_src_register -tgsi_build_src_register( - unsigned file, - unsigned swizzle_x, - unsigned swizzle_y, - unsigned swizzle_z, - unsigned swizzle_w, - unsigned negate, - unsigned indirect, - unsigned dimension, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_full_src_register -tgsi_default_full_src_register( void ); - -struct tgsi_src_register_ext_swz -tgsi_default_src_register_ext_swz( void ); - -unsigned -tgsi_compare_src_register_ext_swz( - struct tgsi_src_register_ext_swz a, - struct tgsi_src_register_ext_swz b ); - -struct tgsi_src_register_ext_swz -tgsi_build_src_register_ext_swz( - unsigned ext_swizzle_x, - unsigned ext_swizzle_y, - unsigned ext_swizzle_z, - unsigned ext_swizzle_w, - unsigned negate_x, - unsigned negate_y, - unsigned negate_z, - unsigned negate_w, - unsigned ext_divide, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_src_register_ext_mod -tgsi_default_src_register_ext_mod( void ); - -unsigned -tgsi_compare_src_register_ext_mod( - struct tgsi_src_register_ext_mod a, - struct tgsi_src_register_ext_mod b ); - -struct tgsi_src_register_ext_mod -tgsi_build_src_register_ext_mod( - unsigned complement, - unsigned bias, - unsigned scale_2x, - unsigned absolute, - unsigned negate, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_dimension -tgsi_default_dimension( void ); - -struct tgsi_dimension -tgsi_build_dimension( - unsigned indirect, - unsigned index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_dst_register -tgsi_default_dst_register( void ); - -struct tgsi_dst_register -tgsi_build_dst_register( - unsigned file, - unsigned mask, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_full_dst_register -tgsi_default_full_dst_register( void ); - -struct tgsi_dst_register_ext_concode -tgsi_default_dst_register_ext_concode( void ); - -unsigned -tgsi_compare_dst_register_ext_concode( - struct tgsi_dst_register_ext_concode a, - struct tgsi_dst_register_ext_concode b ); - -struct tgsi_dst_register_ext_concode -tgsi_build_dst_register_ext_concode( - unsigned cc, - unsigned swizzle_x, - unsigned swizzle_y, - unsigned swizzle_z, - unsigned swizzle_w, - int index, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_dst_register_ext_modulate -tgsi_default_dst_register_ext_modulate( void ); - -unsigned -tgsi_compare_dst_register_ext_modulate( - struct tgsi_dst_register_ext_modulate a, - struct tgsi_dst_register_ext_modulate b ); - -struct tgsi_dst_register_ext_modulate -tgsi_build_dst_register_ext_modulate( - unsigned modulate, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -#if defined __cplusplus -} // extern "C" -#endif // defined __cplusplus - -#endif // !defined TGSI_BUILD_H - diff --git a/src/gallium/aux/tgsi/util/tgsi_dump.c b/src/gallium/aux/tgsi/util/tgsi_dump.c deleted file mode 100644 index b5c54847e0..0000000000 --- a/src/gallium/aux/tgsi/util/tgsi_dump.c +++ /dev/null @@ -1,1581 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi_dump.h" -#include "tgsi_parse.h" -#include "tgsi_build.h" - -struct gen_dump -{ - unsigned tabs; - void (* write)( - struct gen_dump *dump, - const void *data, - unsigned size ); -}; - -struct text_dump -{ - struct gen_dump base; - char *text; - unsigned length; - unsigned capacity; -}; - -static void -_text_dump_write( - struct gen_dump *dump, - const void *data, - unsigned size ) -{ - struct text_dump *td = (struct text_dump *) dump; - unsigned new_length = td->length + size; - - if( new_length >= td->capacity ) { - unsigned new_capacity = td->capacity; - - do { - if( new_capacity == 0 ) { - new_capacity = 256; - } - else { - new_capacity *= 2; - } - } while( new_length >= new_capacity ); - td->text = (char *) REALLOC( - td->text, - td->capacity, - new_capacity ); - td->capacity = new_capacity; - } - memcpy( - &td->text[td->length], - data, - size ); - td->length = new_length; - td->text[td->length] = '\0'; -} - -struct file_dump -{ - struct gen_dump base; - FILE *file; -}; - -static void -_file_dump_write( - struct gen_dump *dump, - const void *data, - unsigned size ) -{ - struct file_dump *fd = (struct file_dump *) dump; - -#if 0 - fwrite( data, 1, size, fd->file ); -#else - { - unsigned i; - - for (i = 0; i < size; i++ ) { - fprintf( fd->file, "%c", ((const char *) data)[i] ); - } - } -#endif -} - -static void -gen_dump_str( - struct gen_dump *dump, - const char *str ) -{ - unsigned i; - size_t len = strlen( str ); - - for (i = 0; i < len; i++) { - dump->write( dump, &str[i], 1 ); - if (str[i] == '\n') { - unsigned i; - - for (i = 0; i < dump->tabs; i++) { - dump->write( dump, " ", 4 ); - } - } - } -} - -static void -gen_dump_chr( - struct gen_dump *dump, - const char chr ) -{ - dump->write( dump, &chr, 1 ); -} - -static void -gen_dump_uix( - struct gen_dump *dump, - const unsigned ui ) -{ - char str[36]; - - sprintf( str, "0x%x", ui ); - gen_dump_str( dump, str ); -} - -static void -gen_dump_uid( - struct gen_dump *dump, - const unsigned ui ) -{ - char str[16]; - - sprintf( str, "%u", ui ); - gen_dump_str( dump, str ); -} - -static void -gen_dump_sid( - struct gen_dump *dump, - const int si ) -{ - char str[16]; - - sprintf( str, "%d", si ); - gen_dump_str( dump, str ); -} - -static void -gen_dump_flt( - struct gen_dump *dump, - const float flt ) -{ - char str[48]; - - sprintf( str, "%10.4f", flt ); - gen_dump_str( dump, str ); -} - -static void -gen_dump_enum( - struct gen_dump *dump, - const unsigned e, - const char **enums, - const unsigned enums_count ) -{ - if (e >= enums_count) { - gen_dump_uid( dump, e ); - } - else { - gen_dump_str( dump, enums[e] ); - } -} - -static void -gen_dump_tab( - struct gen_dump *dump ) -{ - ++dump->tabs; -} - -static void -gen_dump_untab( - struct gen_dump *dump ) -{ - assert( dump->tabs > 0 ); - - --dump->tabs; -} - -#define TXT(S) gen_dump_str( dump, S ) -#define CHR(C) gen_dump_chr( dump, C ) -#define UIX(I) gen_dump_uix( dump, I ) -#define UID(I) gen_dump_uid( dump, I ) -#define SID(I) gen_dump_sid( dump, I ) -#define FLT(F) gen_dump_flt( dump, F ) -#define TAB() gen_dump_tab( dump ) -#define UNT() gen_dump_untab( dump ) -#define ENM(E,ENUMS) gen_dump_enum( dump, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) - -static const char *TGSI_PROCESSOR_TYPES[] = -{ - "PROCESSOR_FRAGMENT", - "PROCESSOR_VERTEX", - "PROCESSOR_GEOMETRY" -}; - -static const char *TGSI_PROCESSOR_TYPES_SHORT[] = -{ - "FRAG", - "VERT", - "GEOM" -}; - -static const char *TGSI_TOKEN_TYPES[] = -{ - "TOKEN_TYPE_DECLARATION", - "TOKEN_TYPE_IMMEDIATE", - "TOKEN_TYPE_INSTRUCTION" -}; - -static const char *TGSI_FILES[] = -{ - "FILE_NULL", - "FILE_CONSTANT", - "FILE_INPUT", - "FILE_OUTPUT", - "FILE_TEMPORARY", - "FILE_SAMPLER", - "FILE_ADDRESS", - "FILE_IMMEDIATE" -}; - -static const char *TGSI_FILES_SHORT[] = -{ - "NULL", - "CONST", - "IN", - "OUT", - "TEMP", - "SAMP", - "ADDR", - "IMM" -}; - -static const char *TGSI_DECLARES[] = -{ - "DECLARE_RANGE", - "DECLARE_MASK" -}; - -static const char *TGSI_INTERPOLATES[] = -{ - "INTERPOLATE_CONSTANT", - "INTERPOLATE_LINEAR", - "INTERPOLATE_PERSPECTIVE", - "INTERPOLATE_ATTRIB" -}; - -static const char *TGSI_INTERPOLATES_SHORT[] = -{ - "CONSTANT", - "LINEAR", - "PERSPECTIVE", - "ATTRIB" -}; - -static const char *TGSI_SEMANTICS[] = -{ - "SEMANTIC_POSITION", - "SEMANTIC_COLOR", - "SEMANTIC_BCOLOR", - "SEMANTIC_FOG", - "SEMANTIC_PSIZE", - "SEMANTIC_GENERIC," -}; - -static const char *TGSI_SEMANTICS_SHORT[] = -{ - "POSITION", - "COLOR", - "BCOLOR", - "FOG", - "PSIZE", - "GENERIC", -}; - -static const char *TGSI_IMMS[] = -{ - "IMM_FLOAT32" -}; - -static const char *TGSI_IMMS_SHORT[] = -{ - "FLT32" -}; - -static const char *TGSI_OPCODES[] = -{ - "OPCODE_ARL", - "OPCODE_MOV", - "OPCODE_LIT", - "OPCODE_RCP", - "OPCODE_RSQ", - "OPCODE_EXP", - "OPCODE_LOG", - "OPCODE_MUL", - "OPCODE_ADD", - "OPCODE_DP3", - "OPCODE_DP4", - "OPCODE_DST", - "OPCODE_MIN", - "OPCODE_MAX", - "OPCODE_SLT", - "OPCODE_SGE", - "OPCODE_MAD", - "OPCODE_SUB", - "OPCODE_LERP", - "OPCODE_CND", - "OPCODE_CND0", - "OPCODE_DOT2ADD", - "OPCODE_INDEX", - "OPCODE_NEGATE", - "OPCODE_FRAC", - "OPCODE_CLAMP", - "OPCODE_FLOOR", - "OPCODE_ROUND", - "OPCODE_EXPBASE2", - "OPCODE_LOGBASE2", - "OPCODE_POWER", - "OPCODE_CROSSPRODUCT", - "OPCODE_MULTIPLYMATRIX", - "OPCODE_ABS", - "OPCODE_RCC", - "OPCODE_DPH", - "OPCODE_COS", - "OPCODE_DDX", - "OPCODE_DDY", - "OPCODE_KILP", - "OPCODE_PK2H", - "OPCODE_PK2US", - "OPCODE_PK4B", - "OPCODE_PK4UB", - "OPCODE_RFL", - "OPCODE_SEQ", - "OPCODE_SFL", - "OPCODE_SGT", - "OPCODE_SIN", - "OPCODE_SLE", - "OPCODE_SNE", - "OPCODE_STR", - "OPCODE_TEX", - "OPCODE_TXD", - "OPCODE_UP2H", - "OPCODE_UP2US", - "OPCODE_UP4B", - "OPCODE_UP4UB", - "OPCODE_X2D", - "OPCODE_ARA", - "OPCODE_ARR", - "OPCODE_BRA", - "OPCODE_CAL", - "OPCODE_RET", - "OPCODE_SSG", - "OPCODE_CMP", - "OPCODE_SCS", - "OPCODE_TXB", - "OPCODE_NRM", - "OPCODE_DIV", - "OPCODE_DP2", - "OPCODE_TXL", - "OPCODE_BRK", - "OPCODE_IF", - "OPCODE_LOOP", - "OPCODE_REP", - "OPCODE_ELSE", - "OPCODE_ENDIF", - "OPCODE_ENDLOOP", - "OPCODE_ENDREP", - "OPCODE_PUSHA", - "OPCODE_POPA", - "OPCODE_CEIL", - "OPCODE_I2F", - "OPCODE_NOT", - "OPCODE_TRUNC", - "OPCODE_SHL", - "OPCODE_SHR", - "OPCODE_AND", - "OPCODE_OR", - "OPCODE_MOD", - "OPCODE_XOR", - "OPCODE_SAD", - "OPCODE_TXF", - "OPCODE_TXQ", - "OPCODE_CONT", - "OPCODE_EMIT", - "OPCODE_ENDPRIM", - "OPCODE_BGNLOOP2", - "OPCODE_BGNSUB", - "OPCODE_ENDLOOP2", - "OPCODE_ENDSUB", - "OPCODE_NOISE1", - "OPCODE_NOISE2", - "OPCODE_NOISE3", - "OPCODE_NOISE4", - "OPCODE_NOP", - "OPCODE_TEXBEM", - "OPCODE_TEXBEML", - "OPCODE_TEXREG2AR", - "OPCODE_TEXM3X2PAD", - "OPCODE_TEXM3X2TEX", - "OPCODE_TEXM3X3PAD", - "OPCODE_TEXM3X3TEX", - "OPCODE_TEXM3X3SPEC", - "OPCODE_TEXM3X3VSPEC", - "OPCODE_TEXREG2GB", - "OPCODE_TEXREG2RGB", - "OPCODE_TEXDP3TEX", - "OPCODE_TEXDP3", - "OPCODE_TEXM3X3", - "OPCODE_TEXM3X2DEPTH", - "OPCODE_TEXDEPTH", - "OPCODE_BEM", - "OPCODE_M4X3", - "OPCODE_M3X4", - "OPCODE_M3X3", - "OPCODE_M3X2", - "OPCODE_NRM4", - "OPCODE_CALLNZ", - "OPCODE_IFC", - "OPCODE_BREAKC", - "OPCODE_KIL", - "OPCODE_END" -}; - -static const char *TGSI_OPCODES_SHORT[] = -{ - "ARL", - "MOV", - "LIT", - "RCP", - "RSQ", - "EXP", - "LOG", - "MUL", - "ADD", - "DP3", - "DP4", - "DST", - "MIN", - "MAX", - "SLT", - "SGE", - "MAD", - "SUB", - "LERP", - "CND", - "CND0", - "DOT2ADD", - "INDEX", - "NEGATE", - "FRAC", - "CLAMP", - "FLOOR", - "ROUND", - "EXPBASE2", - "LOGBASE2", - "POWER", - "CROSSPRODUCT", - "MULTIPLYMATRIX", - "ABS", - "RCC", - "DPH", - "COS", - "DDX", - "DDY", - "KILP", - "PK2H", - "PK2US", - "PK4B", - "PK4UB", - "RFL", - "SEQ", - "SFL", - "SGT", - "SIN", - "SLE", - "SNE", - "STR", - "TEX", - "TXD", - "UP2H", - "UP2US", - "UP4B", - "UP4UB", - "X2D", - "ARA", - "ARR", - "BRA", - "CAL", - "RET", - "SSG", - "CMP", - "SCS", - "TXB", - "NRM", - "DIV", - "DP2", - "TXL", - "BRK", - "IF", - "LOOP", - "REP", - "ELSE", - "ENDIF", - "ENDLOOP", - "ENDREP", - "PUSHA", - "POPA", - "CEIL", - "I2F", - "NOT", - "TRUNC", - "SHL", - "SHR", - "AND", - "OR", - "MOD", - "XOR", - "SAD", - "TXF", - "TXQ", - "CONT", - "EMIT", - "ENDPRIM", - "BGNLOOP2", - "BGNSUB", - "ENDLOOP2", - "ENDSUB", - "NOISE1", - "NOISE2", - "NOISE3", - "NOISE4", - "NOP", - "TEXBEM", - "TEXBEML", - "TEXREG2AR", - "TEXM3X2PAD", - "TEXM3X2TEX", - "TEXM3X3PAD", - "TEXM3X3TEX", - "TEXM3X3SPEC", - "TEXM3X3VSPEC", - "TEXREG2GB", - "TEXREG2RGB", - "TEXDP3TEX", - "TEXDP3", - "TEXM3X3", - "TEXM3X2DEPTH", - "TEXDEPTH", - "BEM", - "M4X3", - "M3X4", - "M3X3", - "M3X2", - "NRM4", - "CALLNZ", - "IFC", - "BREAKC", - "KIL", - "END" -}; - -static const char *TGSI_SATS[] = -{ - "SAT_NONE", - "SAT_ZERO_ONE", - "SAT_MINUS_PLUS_ONE" -}; - -static const char *TGSI_INSTRUCTION_EXTS[] = -{ - "INSTRUCTION_EXT_TYPE_NV", - "INSTRUCTION_EXT_TYPE_LABEL", - "INSTRUCTION_EXT_TYPE_TEXTURE" -}; - -static const char *TGSI_PRECISIONS[] = -{ - "PRECISION_DEFAULT", - "TGSI_PRECISION_FLOAT32", - "TGSI_PRECISION_FLOAT16", - "TGSI_PRECISION_FIXED12" -}; - -static const char *TGSI_CCS[] = -{ - "CC_GT", - "CC_EQ", - "CC_LT", - "CC_UN", - "CC_GE", - "CC_LE", - "CC_NE", - "CC_TR", - "CC_FL" -}; - -static const char *TGSI_SWIZZLES[] = -{ - "SWIZZLE_X", - "SWIZZLE_Y", - "SWIZZLE_Z", - "SWIZZLE_W" -}; - -static const char *TGSI_SWIZZLES_SHORT[] = -{ - "x", - "y", - "z", - "w" -}; - -static const char *TGSI_TEXTURES[] = -{ - "TEXTURE_UNKNOWN", - "TEXTURE_1D", - "TEXTURE_2D", - "TEXTURE_3D", - "TEXTURE_CUBE", - "TEXTURE_RECT", - "TEXTURE_SHADOW1D", - "TEXTURE_SHADOW2D", - "TEXTURE_SHADOWRECT" -}; - -static const char *TGSI_SRC_REGISTER_EXTS[] = -{ - "SRC_REGISTER_EXT_TYPE_SWZ", - "SRC_REGISTER_EXT_TYPE_MOD" -}; - -static const char *TGSI_EXTSWIZZLES[] = -{ - "EXTSWIZZLE_X", - "EXTSWIZZLE_Y", - "EXTSWIZZLE_Z", - "EXTSWIZZLE_W", - "EXTSWIZZLE_ZERO", - "EXTSWIZZLE_ONE" -}; - -static const char *TGSI_EXTSWIZZLES_SHORT[] = -{ - "x", - "y", - "z", - "w", - "0", - "1" -}; - -static const char *TGSI_WRITEMASKS[] = -{ - "0", - "WRITEMASK_X", - "WRITEMASK_Y", - "WRITEMASK_XY", - "WRITEMASK_Z", - "WRITEMASK_XZ", - "WRITEMASK_YZ", - "WRITEMASK_XYZ", - "WRITEMASK_W", - "WRITEMASK_XW", - "WRITEMASK_YW", - "WRITEMASK_XYW", - "WRITEMASK_ZW", - "WRITEMASK_XZW", - "WRITEMASK_YZW", - "WRITEMASK_XYZW" -}; - -static const char *TGSI_DST_REGISTER_EXTS[] = -{ - "DST_REGISTER_EXT_TYPE_CONDCODE", - "DST_REGISTER_EXT_TYPE_MODULATE" -}; - -static const char *TGSI_MODULATES[] = -{ - "MODULATE_1X", - "MODULATE_2X", - "MODULATE_4X", - "MODULATE_8X", - "MODULATE_HALF", - "MODULATE_QUARTER", - "MODULATE_EIGHTH" -}; - -static void -dump_declaration_short( - struct gen_dump *dump, - struct tgsi_full_declaration *decl ) -{ - TXT( "\nDCL " ); - ENM( decl->Declaration.File, TGSI_FILES_SHORT ); - - switch( decl->Declaration.Declare ) { - case TGSI_DECLARE_RANGE: - CHR( '[' ); - UID( decl->u.DeclarationRange.First ); - if( decl->u.DeclarationRange.First != decl->u.DeclarationRange.Last ) { - TXT( ".." ); - UID( decl->u.DeclarationRange.Last ); - } - CHR( ']' ); - break; - default: - assert( 0 ); - } - - if( decl->Declaration.UsageMask != TGSI_WRITEMASK_XYZW ) { - CHR( '.' ); - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { - CHR( 'x' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { - CHR( 'y' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { - CHR( 'z' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { - CHR( 'w' ); - } - } - - if( decl->Declaration.Interpolate ) { - TXT( ", " ); - ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES_SHORT ); - } - - if( decl->Declaration.Semantic ) { - TXT( ", " ); - ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT ); - CHR( '[' ); - UID( decl->Semantic.SemanticIndex ); - CHR( ']' ); - } -} - -static void -dump_declaration_verbose( - struct gen_dump *dump, - struct tgsi_full_declaration *decl, - unsigned ignored, - unsigned deflt, - struct tgsi_full_declaration *fd ) -{ - TXT( "\nFile : " ); - ENM( decl->Declaration.File, TGSI_FILES ); - TXT( "\nDeclare : " ); - ENM( decl->Declaration.Declare, TGSI_DECLARES ); - if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) { - TXT( "\nUsageMask : " ); - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { - CHR( 'X' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { - CHR( 'Y' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { - CHR( 'Z' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { - CHR( 'W' ); - } - } - if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) { - TXT( "\nInterpolate: " ); - UID( decl->Declaration.Interpolate ); - } - if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) { - TXT( "\nSemantic : " ); - UID( decl->Declaration.Semantic ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( decl->Declaration.Padding ); - } - - CHR( '\n' ); - switch( decl->Declaration.Declare ) { - case TGSI_DECLARE_RANGE: - TXT( "\nFirst: " ); - UID( decl->u.DeclarationRange.First ); - TXT( "\nLast : " ); - UID( decl->u.DeclarationRange.Last ); - break; - - case TGSI_DECLARE_MASK: - TXT( "\nMask: " ); - UIX( decl->u.DeclarationMask.Mask ); - break; - - default: - assert( 0 ); - } - - if( decl->Declaration.Interpolate ) { - CHR( '\n' ); - TXT( "\nInterpolate: " ); - ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES ); - if( ignored ) { - TXT( "\nPadding : " ); - UIX( decl->Interpolation.Padding ); - } - } - - if( decl->Declaration.Semantic ) { - CHR( '\n' ); - TXT( "\nSemanticName : " ); - ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS ); - TXT( "\nSemanticIndex: " ); - UID( decl->Semantic.SemanticIndex ); - if( ignored ) { - TXT( "\nPadding : " ); - UIX( decl->Semantic.Padding ); - } - } -} - -static void -dump_immediate_short( - struct gen_dump *dump, - struct tgsi_full_immediate *imm ) -{ - unsigned i; - - TXT( "\nIMM " ); - ENM( imm->Immediate.DataType, TGSI_IMMS_SHORT ); - - TXT( " { " ); - for( i = 0; i < imm->Immediate.Size - 1; i++ ) { - switch( imm->Immediate.DataType ) { - case TGSI_IMM_FLOAT32: - FLT( imm->u.ImmediateFloat32[i].Float ); - break; - - default: - assert( 0 ); - } - - if( i < imm->Immediate.Size - 2 ) { - TXT( ", " ); - } - } - TXT( " }" ); -} - -static void -dump_immediate_verbose( - struct gen_dump *dump, - struct tgsi_full_immediate *imm, - unsigned ignored ) -{ - unsigned i; - - TXT( "\nDataType : " ); - ENM( imm->Immediate.DataType, TGSI_IMMS ); - if( ignored ) { - TXT( "\nPadding : " ); - UIX( imm->Immediate.Padding ); - } - - for( i = 0; i < imm->Immediate.Size - 1; i++ ) { - CHR( '\n' ); - switch( imm->Immediate.DataType ) { - case TGSI_IMM_FLOAT32: - TXT( "\nFloat: " ); - FLT( imm->u.ImmediateFloat32[i].Float ); - break; - - default: - assert( 0 ); - } - } -} - -static void -dump_instruction_short( - struct gen_dump *dump, - struct tgsi_full_instruction *inst, - unsigned instno ) -{ - unsigned i; - boolean first_reg = TRUE; - - CHR( '\n' ); - UID( instno ); - CHR( ':' ); - ENM( inst->Instruction.Opcode, TGSI_OPCODES_SHORT ); - - switch( inst->Instruction.Saturate ) { - case TGSI_SAT_NONE: - break; - case TGSI_SAT_ZERO_ONE: - TXT( "_SAT" ); - break; - case TGSI_SAT_MINUS_PLUS_ONE: - TXT( "_SAT[-1,1]" ); - break; - default: - assert( 0 ); - } - - for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - - if( !first_reg ) { - CHR( ',' ); - } - CHR( ' ' ); - - ENM( dst->DstRegister.File, TGSI_FILES_SHORT ); - - CHR( '[' ); - SID( dst->DstRegister.Index ); - CHR( ']' ); - - if( dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW ) { - CHR( '.' ); - if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_X ) { - CHR( 'x' ); - } - if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_Y ) { - CHR( 'y' ); - } - if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_Z ) { - CHR( 'z' ); - } - if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_W ) { - CHR( 'w' ); - } - } - - first_reg = FALSE; - } - - for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - - if( !first_reg ) { - CHR( ',' ); - } - CHR( ' ' ); - - if( src->SrcRegisterExtMod.Complement ) { - TXT( "(1 - " ); - } - if( src->SrcRegisterExtMod.Negate ) { - CHR( '-' ); - } - if( src->SrcRegisterExtMod.Absolute ) { - CHR( '|' ); - } - if( src->SrcRegister.Negate ) { - CHR( '-' ); - } - - ENM( src->SrcRegister.File, TGSI_FILES_SHORT ); - - CHR( '[' ); - SID( src->SrcRegister.Index ); - CHR( ']' ); - - if (src->SrcRegister.Extended) { - if (src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || - src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || - src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || - src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) { - CHR( '.' ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES_SHORT ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES_SHORT ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES_SHORT ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES_SHORT ); - } - } - else if( src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || - src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || - src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || - src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W ) { - CHR( '.' ); - ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES_SHORT ); - ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES_SHORT ); - ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES_SHORT ); - ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES_SHORT ); - } - - if( src->SrcRegisterExtMod.Absolute ) { - CHR( '|' ); - } - if( src->SrcRegisterExtMod.Complement ) { - CHR( ')' ); - } - - first_reg = FALSE; - } - - switch( inst->Instruction.Opcode ) { - case TGSI_OPCODE_IF: - case TGSI_OPCODE_ELSE: - case TGSI_OPCODE_BGNLOOP2: - case TGSI_OPCODE_ENDLOOP2: - case TGSI_OPCODE_CAL: - TXT( " :" ); - UID( inst->InstructionExtLabel.Label ); - break; - } -} - -static void -dump_instruction_verbose( - struct gen_dump *dump, - struct tgsi_full_instruction *inst, - unsigned ignored, - unsigned deflt, - struct tgsi_full_instruction *fi ) -{ - unsigned i; - - TXT( "\nOpcode : " ); - ENM( inst->Instruction.Opcode, TGSI_OPCODES ); - if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) { - TXT( "\nSaturate : " ); - ENM( inst->Instruction.Saturate, TGSI_SATS ); - } - if( deflt || fi->Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) { - TXT( "\nNumDstRegs : " ); - UID( inst->Instruction.NumDstRegs ); - } - if( deflt || fi->Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) { - TXT( "\nNumSrcRegs : " ); - UID( inst->Instruction.NumSrcRegs ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->Instruction.Padding ); - } - - if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi->InstructionExtNv ) ) { - CHR( '\n' ); - TXT( "\nType : " ); - ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS ); - if( deflt || fi->InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) { - TXT( "\nPrecision : " ); - ENM( inst->InstructionExtNv.Precision, TGSI_PRECISIONS ); - } - if( deflt || fi->InstructionExtNv.CondDstIndex != inst->InstructionExtNv.CondDstIndex ) { - TXT( "\nCondDstIndex : " ); - UID( inst->InstructionExtNv.CondDstIndex ); - } - if( deflt || fi->InstructionExtNv.CondFlowIndex != inst->InstructionExtNv.CondFlowIndex ) { - TXT( "\nCondFlowIndex : " ); - UID( inst->InstructionExtNv.CondFlowIndex ); - } - if( deflt || fi->InstructionExtNv.CondMask != inst->InstructionExtNv.CondMask ) { - TXT( "\nCondMask : " ); - ENM( inst->InstructionExtNv.CondMask, TGSI_CCS ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleX != inst->InstructionExtNv.CondSwizzleX ) { - TXT( "\nCondSwizzleX : " ); - ENM( inst->InstructionExtNv.CondSwizzleX, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleY != inst->InstructionExtNv.CondSwizzleY ) { - TXT( "\nCondSwizzleY : " ); - ENM( inst->InstructionExtNv.CondSwizzleY, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleZ != inst->InstructionExtNv.CondSwizzleZ ) { - TXT( "\nCondSwizzleZ : " ); - ENM( inst->InstructionExtNv.CondSwizzleZ, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleW != inst->InstructionExtNv.CondSwizzleW ) { - TXT( "\nCondSwizzleW : " ); - ENM( inst->InstructionExtNv.CondSwizzleW, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondDstUpdate != inst->InstructionExtNv.CondDstUpdate ) { - TXT( "\nCondDstUpdate : " ); - UID( inst->InstructionExtNv.CondDstUpdate ); - } - if( deflt || fi->InstructionExtNv.CondFlowEnable != inst->InstructionExtNv.CondFlowEnable ) { - TXT( "\nCondFlowEnable: " ); - UID( inst->InstructionExtNv.CondFlowEnable ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->InstructionExtNv.Padding ); - if( deflt || fi->InstructionExtNv.Extended != inst->InstructionExtNv.Extended ) { - TXT( "\nExtended : " ); - UID( inst->InstructionExtNv.Extended ); - } - } - } - - if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) { - CHR( '\n' ); - TXT( "\nType : " ); - ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS ); - if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) { - TXT( "\nLabel : " ); - UID( inst->InstructionExtLabel.Label ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->InstructionExtLabel.Padding ); - if( deflt || fi->InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) { - TXT( "\nExtended: " ); - UID( inst->InstructionExtLabel.Extended ); - } - } - } - - if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) { - CHR( '\n' ); - TXT( "\nType : " ); - ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS ); - if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) { - TXT( "\nTexture : " ); - ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->InstructionExtTexture.Padding ); - if( deflt || fi->InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) { - TXT( "\nExtended: " ); - UID( inst->InstructionExtTexture.Extended ); - } - } - } - - for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i]; - - CHR( '\n' ); - TXT( "\nFile : " ); - ENM( dst->DstRegister.File, TGSI_FILES ); - if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) { - TXT( "\nWriteMask: " ); - ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS ); - } - if( ignored ) { - if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) { - TXT( "\nIndirect : " ); - UID( dst->DstRegister.Indirect ); - } - if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) { - TXT( "\nDimension: " ); - UID( dst->DstRegister.Dimension ); - } - } - if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) { - TXT( "\nIndex : " ); - SID( dst->DstRegister.Index ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( dst->DstRegister.Padding ); - if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) { - TXT( "\nExtended : " ); - UID( dst->DstRegister.Extended ); - } - } - - if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) { - CHR( '\n' ); - TXT( "\nType : " ); - ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS ); - if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) { - TXT( "\nCondMask : " ); - ENM( dst->DstRegisterExtConcode.CondMask, TGSI_CCS ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleX != dst->DstRegisterExtConcode.CondSwizzleX ) { - TXT( "\nCondSwizzleX: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleX, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleY != dst->DstRegisterExtConcode.CondSwizzleY ) { - TXT( "\nCondSwizzleY: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleY, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleZ != dst->DstRegisterExtConcode.CondSwizzleZ ) { - TXT( "\nCondSwizzleZ: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleZ, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleW != dst->DstRegisterExtConcode.CondSwizzleW ) { - TXT( "\nCondSwizzleW: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleW, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSrcIndex != dst->DstRegisterExtConcode.CondSrcIndex ) { - TXT( "\nCondSrcIndex: " ); - UID( dst->DstRegisterExtConcode.CondSrcIndex ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( dst->DstRegisterExtConcode.Padding ); - if( deflt || fd->DstRegisterExtConcode.Extended != dst->DstRegisterExtConcode.Extended ) { - TXT( "\nExtended : " ); - UID( dst->DstRegisterExtConcode.Extended ); - } - } - } - - if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) { - CHR( '\n' ); - TXT( "\nType : " ); - ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS ); - if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) { - TXT( "\nModulate: " ); - ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( dst->DstRegisterExtModulate.Padding ); - if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) { - TXT( "\nExtended: " ); - UID( dst->DstRegisterExtModulate.Extended ); - } - } - } - } - - for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i]; - - CHR( '\n' ); - TXT( "\nFile : "); - ENM( src->SrcRegister.File, TGSI_FILES ); - if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) { - TXT( "\nSwizzleX : " ); - ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) { - TXT( "\nSwizzleY : " ); - ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) { - TXT( "\nSwizzleZ : " ); - ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) { - TXT( "\nSwizzleW : " ); - ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) { - TXT( "\nNegate : " ); - UID( src->SrcRegister.Negate ); - } - if( ignored ) { - if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) { - TXT( "\nIndirect : " ); - UID( src->SrcRegister.Indirect ); - } - if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) { - TXT( "\nDimension: " ); - UID( src->SrcRegister.Dimension ); - } - } - if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) { - TXT( "\nIndex : " ); - SID( src->SrcRegister.Index ); - } - if( ignored ) { - if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) { - TXT( "\nExtended : " ); - UID( src->SrcRegister.Extended ); - } - } - - if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) { - CHR( '\n' ); - TXT( "\nType : " ); - ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS ); - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) { - TXT( "\nExtSwizzleX: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleY != src->SrcRegisterExtSwz.ExtSwizzleY ) { - TXT( "\nExtSwizzleY: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleZ != src->SrcRegisterExtSwz.ExtSwizzleZ ) { - TXT( "\nExtSwizzleZ: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleW != src->SrcRegisterExtSwz.ExtSwizzleW ) { - TXT( "\nExtSwizzleW: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateX != src->SrcRegisterExtSwz.NegateX ) { - TXT( "\nNegateX : " ); - UID( src->SrcRegisterExtSwz.NegateX ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateY != src->SrcRegisterExtSwz.NegateY ) { - TXT( "\nNegateY : " ); - UID( src->SrcRegisterExtSwz.NegateY ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateZ != src->SrcRegisterExtSwz.NegateZ ) { - TXT( "\nNegateZ : " ); - UID( src->SrcRegisterExtSwz.NegateZ ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateW != src->SrcRegisterExtSwz.NegateW ) { - TXT( "\nNegateW : " ); - UID( src->SrcRegisterExtSwz.NegateW ); - } - if( deflt || fs->SrcRegisterExtSwz.ExtDivide != src->SrcRegisterExtSwz.ExtDivide ) { - TXT( "\nExtDivide : " ); - ENM( src->SrcRegisterExtSwz.ExtDivide, TGSI_EXTSWIZZLES ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( src->SrcRegisterExtSwz.Padding ); - if( deflt || fs->SrcRegisterExtSwz.Extended != src->SrcRegisterExtSwz.Extended ) { - TXT( "\nExtended : " ); - UID( src->SrcRegisterExtSwz.Extended ); - } - } - } - - if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) { - CHR( '\n' ); - TXT( "\nType : " ); - ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS ); - if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) { - TXT( "\nComplement: " ); - UID( src->SrcRegisterExtMod.Complement ); - } - if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) { - TXT( "\nBias : " ); - UID( src->SrcRegisterExtMod.Bias ); - } - if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) { - TXT( "\nScale2X : " ); - UID( src->SrcRegisterExtMod.Scale2X ); - } - if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) { - TXT( "\nAbsolute : " ); - UID( src->SrcRegisterExtMod.Absolute ); - } - if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) { - TXT( "\nNegate : " ); - UID( src->SrcRegisterExtMod.Negate ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( src->SrcRegisterExtMod.Padding ); - if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) { - TXT( "\nExtended : " ); - UID( src->SrcRegisterExtMod.Extended ); - } - } - } - } -} - -static void -dump_gen( - struct gen_dump *dump, - const struct tgsi_token *tokens, - unsigned flags ) -{ - struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - unsigned verbose = flags & TGSI_DUMP_VERBOSE; - unsigned ignored = !(flags & TGSI_DUMP_NO_IGNORED); - unsigned deflt = !(flags & TGSI_DUMP_NO_DEFAULT); - unsigned instno = 0; - - dump->tabs = 0; - - /* sanity check */ - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); - - tgsi_parse_init( &parse, tokens ); - - TXT( "tgsi-dump begin -----------------" ); - - CHR( '\n' ); - ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES_SHORT ); - CHR( ' ' ); - UID( parse.FullVersion.Version.MajorVersion ); - CHR( '.' ); - UID( parse.FullVersion.Version.MinorVersion ); - - if( verbose ) { - TXT( "\nMajorVersion: " ); - UID( parse.FullVersion.Version.MajorVersion ); - TXT( "\nMinorVersion: " ); - UID( parse.FullVersion.Version.MinorVersion ); - CHR( '\n' ); - - TXT( "\nHeaderSize: " ); - UID( parse.FullHeader.Header.HeaderSize ); - TXT( "\nBodySize : " ); - UID( parse.FullHeader.Header.BodySize ); - TXT( "\nProcessor : " ); - ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); - CHR( '\n' ); - } - - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - - while( !tgsi_parse_end_of_tokens( &parse ) ) { - tgsi_parse_token( &parse ); - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - dump_declaration_short( - dump, - &parse.FullToken.FullDeclaration ); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - dump_immediate_short( - dump, - &parse.FullToken.FullImmediate ); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - dump_instruction_short( - dump, - &parse.FullToken.FullInstruction, - instno ); - instno++; - break; - - default: - assert( 0 ); - } - - if( verbose ) { - TXT( "\nType : " ); - ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES ); - if( ignored ) { - TXT( "\nSize : " ); - UID( parse.FullToken.Token.Size ); - if( deflt || parse.FullToken.Token.Extended ) { - TXT( "\nExtended : " ); - UID( parse.FullToken.Token.Extended ); - } - } - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - dump_declaration_verbose( - dump, - &parse.FullToken.FullDeclaration, - ignored, - deflt, - &fd ); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - dump_immediate_verbose( - dump, - &parse.FullToken.FullImmediate, - ignored ); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - dump_instruction_verbose( - dump, - &parse.FullToken.FullInstruction, - ignored, - deflt, - &fi ); - break; - - default: - assert( 0 ); - } - - CHR( '\n' ); - } - } - - TXT( "\ntgsi-dump end -------------------\n" ); - - tgsi_parse_free( &parse ); -} - - -static void -sanity_checks(void) -{ - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); - assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "END") == 0); -} - - -void -tgsi_dump( - const struct tgsi_token *tokens, - unsigned flags ) -{ - struct file_dump dump; - - sanity_checks(); - - dump.base.write = _file_dump_write; -#if 0 - { - static unsigned counter = 0; - char buffer[64]; - sprintf( buffer, "tgsi-dump-%.4u.txt", counter++ ); - dump.file = fopen( buffer, "wt" ); - } -#else - dump.file = stderr; -#endif - - dump_gen( - &dump.base, - tokens, - flags ); - -#if 0 - fclose( dump.file ); -#endif -} - -void -tgsi_dump_str( - char **str, - const struct tgsi_token *tokens, - unsigned flags ) -{ - struct text_dump dump; - - dump.base.write = _text_dump_write; - dump.text = NULL; - dump.length = 0; - dump.capacity = 0; - - dump_gen( - &dump.base, - tokens, - flags ); - - *str = dump.text; -} diff --git a/src/gallium/aux/tgsi/util/tgsi_dump.h b/src/gallium/aux/tgsi/util/tgsi_dump.h deleted file mode 100644 index 1adc9db251..0000000000 --- a/src/gallium/aux/tgsi/util/tgsi_dump.h +++ /dev/null @@ -1,28 +0,0 @@ -#if !defined TGSI_DUMP_H -#define TGSI_DUMP_H - -#if defined __cplusplus -extern "C" { -#endif // defined __cplusplus - -#define TGSI_DUMP_VERBOSE 1 -#define TGSI_DUMP_NO_IGNORED 2 -#define TGSI_DUMP_NO_DEFAULT 4 - -void -tgsi_dump( - const struct tgsi_token *tokens, - unsigned flags ); - -void -tgsi_dump_str( - char **str, - const struct tgsi_token *tokens, - unsigned flags ); - -#if defined __cplusplus -} // extern "C" -#endif // defined __cplusplus - -#endif // !defined TGSI_DUMP_H - diff --git a/src/gallium/aux/tgsi/util/tgsi_parse.c b/src/gallium/aux/tgsi/util/tgsi_parse.c deleted file mode 100644 index bf6b89ce56..0000000000 --- a/src/gallium/aux/tgsi/util/tgsi_parse.c +++ /dev/null @@ -1,319 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi_parse.h" -#include "tgsi_build.h" - -void -tgsi_full_token_init( - union tgsi_full_token *full_token ) -{ - full_token->Token.Type = TGSI_TOKEN_TYPE_DECLARATION; -} - -void -tgsi_full_token_free( - union tgsi_full_token *full_token ) -{ - if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE ) { - FREE( full_token->FullImmediate.u.Pointer ); - } -} - -unsigned -tgsi_parse_init( - struct tgsi_parse_context *ctx, - const struct tgsi_token *tokens ) -{ - ctx->FullVersion.Version = *(struct tgsi_version *) &tokens[0]; - if( ctx->FullVersion.Version.MajorVersion > 1 ) { - return TGSI_PARSE_ERROR; - } - - ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[1]; - if( ctx->FullHeader.Header.HeaderSize >= 2 ) { - ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[2]; - } - else { - ctx->FullHeader.Processor = tgsi_default_processor(); - } - - ctx->Tokens = tokens; - ctx->Position = 1 + ctx->FullHeader.Header.HeaderSize; - - tgsi_full_token_init( &ctx->FullToken ); - - return TGSI_PARSE_OK; -} - -void -tgsi_parse_free( - struct tgsi_parse_context *ctx ) -{ - tgsi_full_token_free( &ctx->FullToken ); -} - -boolean -tgsi_parse_end_of_tokens( - struct tgsi_parse_context *ctx ) -{ - return ctx->Position >= - 1 + ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize; -} - -static void -next_token( - struct tgsi_parse_context *ctx, - void *token ) -{ - assert( !tgsi_parse_end_of_tokens( ctx ) ); - - *(struct tgsi_token *) token = ctx->Tokens[ctx->Position++]; -} - -void -tgsi_parse_token( - struct tgsi_parse_context *ctx ) -{ - struct tgsi_token token; - unsigned i; - - tgsi_full_token_free( &ctx->FullToken ); - tgsi_full_token_init( &ctx->FullToken ); - - next_token( ctx, &token ); - - switch( token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - { - struct tgsi_full_declaration *decl = &ctx->FullToken.FullDeclaration; - - *decl = tgsi_default_full_declaration(); - decl->Declaration = *(struct tgsi_declaration *) &token; - - switch( decl->Declaration.Type ) { - case TGSI_DECLARE_RANGE: - next_token( ctx, &decl->u.DeclarationRange ); - break; - - case TGSI_DECLARE_MASK: - next_token( ctx, &decl->u.DeclarationMask ); - break; - - default: - assert (0); - } - - if( decl->Declaration.Interpolate ) { - next_token( ctx, &decl->Interpolation ); - } - - if( decl->Declaration.Semantic ) { - next_token( ctx, &decl->Semantic ); - } - - break; - } - - case TGSI_TOKEN_TYPE_IMMEDIATE: - { - struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate; - - *imm = tgsi_default_full_immediate(); - imm->Immediate = *(struct tgsi_immediate *) &token; - - assert( !imm->Immediate.Extended ); - - switch (imm->Immediate.DataType) { - case TGSI_IMM_FLOAT32: - imm->u.Pointer = MALLOC( - sizeof( struct tgsi_immediate_float32 ) * (imm->Immediate.Size - 1) ); - for( i = 0; i < imm->Immediate.Size - 1; i++ ) { - next_token( ctx, &imm->u.ImmediateFloat32[i] ); - } - break; - - default: - assert( 0 ); - } - - break; - } - - case TGSI_TOKEN_TYPE_INSTRUCTION: - { - struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction; - unsigned extended; - - *inst = tgsi_default_full_instruction(); - inst->Instruction = *(struct tgsi_instruction *) &token; - - extended = inst->Instruction.Extended; - - while( extended ) { - struct tgsi_src_register_ext token; - - next_token( ctx, &token ); - - switch( token.Type ) { - case TGSI_INSTRUCTION_EXT_TYPE_NV: - inst->InstructionExtNv = - *(struct tgsi_instruction_ext_nv *) &token; - break; - - case TGSI_INSTRUCTION_EXT_TYPE_LABEL: - inst->InstructionExtLabel = - *(struct tgsi_instruction_ext_label *) &token; - break; - - case TGSI_INSTRUCTION_EXT_TYPE_TEXTURE: - inst->InstructionExtTexture = - *(struct tgsi_instruction_ext_texture *) &token; - break; - - default: - assert( 0 ); - } - - extended = token.Extended; - } - - assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS ); - - for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { - unsigned extended; - - next_token( ctx, &inst->FullDstRegisters[i].DstRegister ); - - /* - * No support for indirect or multi-dimensional addressing. - */ - assert( !inst->FullDstRegisters[i].DstRegister.Indirect ); - assert( !inst->FullDstRegisters[i].DstRegister.Dimension ); - - extended = inst->FullDstRegisters[i].DstRegister.Extended; - - while( extended ) { - struct tgsi_src_register_ext token; - - next_token( ctx, &token ); - - switch( token.Type ) { - case TGSI_DST_REGISTER_EXT_TYPE_CONDCODE: - inst->FullDstRegisters[i].DstRegisterExtConcode = - *(struct tgsi_dst_register_ext_concode *) &token; - break; - - case TGSI_DST_REGISTER_EXT_TYPE_MODULATE: - inst->FullDstRegisters[i].DstRegisterExtModulate = - *(struct tgsi_dst_register_ext_modulate *) &token; - break; - - default: - assert( 0 ); - } - - extended = token.Extended; - } - } - - assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS ); - - for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { - unsigned extended; - - next_token( ctx, &inst->FullSrcRegisters[i].SrcRegister ); - - extended = inst->FullSrcRegisters[i].SrcRegister.Extended; - - while( extended ) { - struct tgsi_src_register_ext token; - - next_token( ctx, &token ); - - switch( token.Type ) { - case TGSI_SRC_REGISTER_EXT_TYPE_SWZ: - inst->FullSrcRegisters[i].SrcRegisterExtSwz = - *(struct tgsi_src_register_ext_swz *) &token; - break; - - case TGSI_SRC_REGISTER_EXT_TYPE_MOD: - inst->FullSrcRegisters[i].SrcRegisterExtMod = - *(struct tgsi_src_register_ext_mod *) &token; - break; - - default: - assert( 0 ); - } - - extended = token.Extended; - } - - if( inst->FullSrcRegisters[i].SrcRegister.Indirect ) { - next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterInd ); - - /* - * No support for indirect or multi-dimensional addressing. - */ - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); - } - - if( inst->FullSrcRegisters[i].SrcRegister.Dimension ) { - next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDim ); - - /* - * No support for multi-dimensional addressing. - */ - assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Dimension ); - assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Extended ); - - if( inst->FullSrcRegisters[i].SrcRegisterDim.Indirect ) { - next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDimInd ); - - /* - * No support for indirect or multi-dimensional addressing. - */ - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); - } - } - } - - break; - } - - default: - assert( 0 ); - } -} - diff --git a/src/gallium/aux/tgsi/util/tgsi_parse.h b/src/gallium/aux/tgsi/util/tgsi_parse.h deleted file mode 100644 index 9372da8d5d..0000000000 --- a/src/gallium/aux/tgsi/util/tgsi_parse.h +++ /dev/null @@ -1,121 +0,0 @@ -#if !defined TGSI_PARSE_H -#define TGSI_PARSE_H - -#if defined __cplusplus -extern "C" { -#endif // defined __cplusplus - -struct tgsi_full_version -{ - struct tgsi_version Version; -}; - -struct tgsi_full_header -{ - struct tgsi_header Header; - struct tgsi_processor Processor; -}; - -struct tgsi_full_dst_register -{ - struct tgsi_dst_register DstRegister; - struct tgsi_dst_register_ext_concode DstRegisterExtConcode; - struct tgsi_dst_register_ext_modulate DstRegisterExtModulate; -}; - -struct tgsi_full_src_register -{ - struct tgsi_src_register SrcRegister; - struct tgsi_src_register_ext_swz SrcRegisterExtSwz; - struct tgsi_src_register_ext_mod SrcRegisterExtMod; - struct tgsi_src_register SrcRegisterInd; - struct tgsi_dimension SrcRegisterDim; - struct tgsi_src_register SrcRegisterDimInd; -}; - -struct tgsi_full_declaration -{ - struct tgsi_declaration Declaration; - union - { - struct tgsi_declaration_range DeclarationRange; - struct tgsi_declaration_mask DeclarationMask; - } u; - struct tgsi_declaration_interpolation Interpolation; - struct tgsi_declaration_semantic Semantic; -}; - -struct tgsi_full_immediate -{ - struct tgsi_immediate Immediate; - union - { - void *Pointer; - struct tgsi_immediate_float32 *ImmediateFloat32; - } u; -}; - -#define TGSI_FULL_MAX_DST_REGISTERS 2 -#define TGSI_FULL_MAX_SRC_REGISTERS 3 - -struct tgsi_full_instruction -{ - struct tgsi_instruction Instruction; - struct tgsi_instruction_ext_nv InstructionExtNv; - struct tgsi_instruction_ext_label InstructionExtLabel; - struct tgsi_instruction_ext_texture InstructionExtTexture; - struct tgsi_full_dst_register FullDstRegisters[TGSI_FULL_MAX_DST_REGISTERS]; - struct tgsi_full_src_register FullSrcRegisters[TGSI_FULL_MAX_SRC_REGISTERS]; -}; - -union tgsi_full_token -{ - struct tgsi_token Token; - struct tgsi_full_declaration FullDeclaration; - struct tgsi_full_immediate FullImmediate; - struct tgsi_full_instruction FullInstruction; -}; - -void -tgsi_full_token_init( - union tgsi_full_token *full_token ); - -void -tgsi_full_token_free( - union tgsi_full_token *full_token ); - -struct tgsi_parse_context -{ - const struct tgsi_token *Tokens; - unsigned Position; - struct tgsi_full_version FullVersion; - struct tgsi_full_header FullHeader; - union tgsi_full_token FullToken; -}; - -#define TGSI_PARSE_OK 0 -#define TGSI_PARSE_ERROR 1 - -unsigned -tgsi_parse_init( - struct tgsi_parse_context *ctx, - const struct tgsi_token *tokens ); - -void -tgsi_parse_free( - struct tgsi_parse_context *ctx ); - -boolean -tgsi_parse_end_of_tokens( - struct tgsi_parse_context *ctx ); - -void -tgsi_parse_token( - struct tgsi_parse_context *ctx ); - -#if defined __cplusplus -} // extern "C" -#endif // defined __cplusplus - -#endif // !defined TGSI_PARSE_H - diff --git a/src/gallium/aux/tgsi/util/tgsi_transform.c b/src/gallium/aux/tgsi/util/tgsi_transform.c deleted file mode 100644 index 357f77b05a..0000000000 --- a/src/gallium/aux/tgsi/util/tgsi_transform.c +++ /dev/null @@ -1,199 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * TGSI program transformation utility. - * - * Authors: Brian Paul - */ - - -#include "tgsi_transform.h" - - - -static void -emit_instruction(struct tgsi_transform_context *ctx, - const struct tgsi_full_instruction *inst) -{ - uint ti = ctx->ti; - - ti += tgsi_build_full_instruction(inst, - ctx->tokens_out + ti, - ctx->header, - ctx->max_tokens_out - ti); - ctx->ti = ti; -} - - -static void -emit_declaration(struct tgsi_transform_context *ctx, - const struct tgsi_full_declaration *decl) -{ - uint ti = ctx->ti; - - ti += tgsi_build_full_declaration(decl, - ctx->tokens_out + ti, - ctx->header, - ctx->max_tokens_out - ti); - ctx->ti = ti; -} - - -static void -emit_immediate(struct tgsi_transform_context *ctx, - const struct tgsi_full_immediate *imm) -{ - uint ti = ctx->ti; - - ti += tgsi_build_full_immediate(imm, - ctx->tokens_out + ti, - ctx->header, - ctx->max_tokens_out - ti); - ctx->ti = ti; -} - - - -/** - * Apply user-defined transformations to the input shader to produce - * the output shader. - * For example, a register search-and-replace operation could be applied - * by defining a transform_instruction() callback that examined and changed - * the instruction src/dest regs. - * - * \return number of tokens emitted - */ -int -tgsi_transform_shader(const struct tgsi_token *tokens_in, - struct tgsi_token *tokens_out, - uint max_tokens_out, - struct tgsi_transform_context *ctx) -{ - uint procType; - - /* input shader */ - struct tgsi_parse_context parse; - - /* output shader */ - struct tgsi_processor *processor; - - - /** - ** callback context init - **/ - ctx->emit_instruction = emit_instruction; - ctx->emit_declaration = emit_declaration; - ctx->emit_immediate = emit_immediate; - ctx->tokens_out = tokens_out; - ctx->max_tokens_out = max_tokens_out; - - - /** - ** Setup to begin parsing input shader - **/ - if (tgsi_parse_init( &parse, tokens_in ) != TGSI_PARSE_OK) { - debug_printf("tgsi_parse_init() failed in tgsi_transform_shader()!\n"); - return -1; - } - procType = parse.FullHeader.Processor.Processor; - assert(procType == TGSI_PROCESSOR_FRAGMENT || - procType == TGSI_PROCESSOR_VERTEX || - procType == TGSI_PROCESSOR_GEOMETRY); - - - /** - ** Setup output shader - **/ - *(struct tgsi_version *) &tokens_out[0] = tgsi_build_version(); - - ctx->header = (struct tgsi_header *) (tokens_out + 1); - *ctx->header = tgsi_build_header(); - - processor = (struct tgsi_processor *) (tokens_out + 2); - *processor = tgsi_build_processor( procType, ctx->header ); - - ctx->ti = 3; - - - /** - ** Loop over incoming program tokens/instructions - */ - while( !tgsi_parse_end_of_tokens( &parse ) ) { - - tgsi_parse_token( &parse ); - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_INSTRUCTION: - { - struct tgsi_full_instruction *fullinst - = &parse.FullToken.FullInstruction; - - if (ctx->transform_instruction) - ctx->transform_instruction(ctx, fullinst); - else - ctx->emit_instruction(ctx, fullinst); - } - break; - - case TGSI_TOKEN_TYPE_DECLARATION: - { - struct tgsi_full_declaration *fulldecl - = &parse.FullToken.FullDeclaration; - - if (ctx->transform_declaration) - ctx->transform_declaration(ctx, fulldecl); - else - ctx->emit_declaration(ctx, fulldecl); - } - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - { - struct tgsi_full_immediate *fullimm - = &parse.FullToken.FullImmediate; - - if (ctx->transform_immediate) - ctx->transform_immediate(ctx, fullimm); - else - ctx->emit_immediate(ctx, fullimm); - } - break; - - default: - assert( 0 ); - } - } - - if (ctx->epilog) { - ctx->epilog(ctx); - } - - tgsi_parse_free (&parse); - - return ctx->ti; -} diff --git a/src/gallium/aux/tgsi/util/tgsi_transform.h b/src/gallium/aux/tgsi/util/tgsi_transform.h deleted file mode 100644 index fcf85d603b..0000000000 --- a/src/gallium/aux/tgsi/util/tgsi_transform.h +++ /dev/null @@ -1,93 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_TRANSFORM_H -#define TGSI_TRANSFORM_H - - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_build.h" - - - -/** - * Subclass this to add caller-specific data - */ -struct tgsi_transform_context -{ -/**** PUBLIC ***/ - - /** - * User-defined callbacks invoked per instruction. - */ - void (*transform_instruction)(struct tgsi_transform_context *ctx, - struct tgsi_full_instruction *inst); - - void (*transform_declaration)(struct tgsi_transform_context *ctx, - struct tgsi_full_declaration *decl); - - void (*transform_immediate)(struct tgsi_transform_context *ctx, - struct tgsi_full_immediate *imm); - - /** - * Called at end of input program to allow caller to append extra - * instructions. Return number of tokens emitted. - */ - void (*epilog)(struct tgsi_transform_context *ctx); - - -/*** PRIVATE ***/ - - /** - * These are setup by tgsi_transform_shader() and cannot be overridden. - * Meant to be called from in the above user callback functions. - */ - void (*emit_instruction)(struct tgsi_transform_context *ctx, - const struct tgsi_full_instruction *inst); - void (*emit_declaration)(struct tgsi_transform_context *ctx, - const struct tgsi_full_declaration *decl); - void (*emit_immediate)(struct tgsi_transform_context *ctx, - const struct tgsi_full_immediate *imm); - - struct tgsi_header *header; - uint max_tokens_out; - struct tgsi_token *tokens_out; - uint ti; -}; - - - -extern int -tgsi_transform_shader(const struct tgsi_token *tokens_in, - struct tgsi_token *tokens_out, - uint max_tokens_out, - struct tgsi_transform_context *ctx); - - -#endif /* TGSI_TRANSFORM_H */ diff --git a/src/gallium/aux/tgsi/util/tgsi_util.c b/src/gallium/aux/tgsi/util/tgsi_util.c deleted file mode 100644 index 4cdd89182a..0000000000 --- a/src/gallium/aux/tgsi/util/tgsi_util.c +++ /dev/null @@ -1,274 +0,0 @@ -#include "pipe/p_debug.h" -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi_parse.h" -#include "tgsi_build.h" -#include "tgsi_util.h" - -union pointer_hack -{ - void *pointer; - unsigned long long uint64; -}; - -void * -tgsi_align_128bit( - void *unaligned ) -{ - union pointer_hack ph; - - ph.uint64 = 0; - ph.pointer = unaligned; - ph.uint64 = (ph.uint64 + 15) & ~15; - return ph.pointer; -} - -unsigned -tgsi_util_get_src_register_swizzle( - const struct tgsi_src_register *reg, - unsigned component ) -{ - switch( component ) { - case 0: - return reg->SwizzleX; - case 1: - return reg->SwizzleY; - case 2: - return reg->SwizzleZ; - case 3: - return reg->SwizzleW; - default: - assert( 0 ); - } - return 0; -} - -unsigned -tgsi_util_get_src_register_extswizzle( - const struct tgsi_src_register_ext_swz *reg, - unsigned component ) -{ - switch( component ) { - case 0: - return reg->ExtSwizzleX; - case 1: - return reg->ExtSwizzleY; - case 2: - return reg->ExtSwizzleZ; - case 3: - return reg->ExtSwizzleW; - default: - assert( 0 ); - } - return 0; -} - -unsigned -tgsi_util_get_full_src_register_extswizzle( - const struct tgsi_full_src_register *reg, - unsigned component ) -{ - unsigned swizzle; - - /* - * First, calculate the extended swizzle for a given channel. This will give - * us either a channel index into the simple swizzle or a constant 1 or 0. - */ - swizzle = tgsi_util_get_src_register_extswizzle( - ®->SrcRegisterExtSwz, - component ); - - assert (TGSI_SWIZZLE_X == TGSI_EXTSWIZZLE_X); - assert (TGSI_SWIZZLE_Y == TGSI_EXTSWIZZLE_Y); - assert (TGSI_SWIZZLE_Z == TGSI_EXTSWIZZLE_Z); - assert (TGSI_SWIZZLE_W == TGSI_EXTSWIZZLE_W); - assert (TGSI_EXTSWIZZLE_ZERO > TGSI_SWIZZLE_W); - assert (TGSI_EXTSWIZZLE_ONE > TGSI_SWIZZLE_W); - - /* - * Second, calculate the simple swizzle for the unswizzled channel index. - * Leave the constants intact, they are not affected by the simple swizzle. - */ - if( swizzle <= TGSI_SWIZZLE_W ) { - swizzle = tgsi_util_get_src_register_swizzle( - ®->SrcRegister, - component ); - } - - return swizzle; -} - -void -tgsi_util_set_src_register_swizzle( - struct tgsi_src_register *reg, - unsigned swizzle, - unsigned component ) -{ - switch( component ) { - case 0: - reg->SwizzleX = swizzle; - break; - case 1: - reg->SwizzleY = swizzle; - break; - case 2: - reg->SwizzleZ = swizzle; - break; - case 3: - reg->SwizzleW = swizzle; - break; - default: - assert( 0 ); - } -} - -void -tgsi_util_set_src_register_extswizzle( - struct tgsi_src_register_ext_swz *reg, - unsigned swizzle, - unsigned component ) -{ - switch( component ) { - case 0: - reg->ExtSwizzleX = swizzle; - break; - case 1: - reg->ExtSwizzleY = swizzle; - break; - case 2: - reg->ExtSwizzleZ = swizzle; - break; - case 3: - reg->ExtSwizzleW = swizzle; - break; - default: - assert( 0 ); - } -} - -unsigned -tgsi_util_get_src_register_extnegate( - const struct tgsi_src_register_ext_swz *reg, - unsigned component ) -{ - switch( component ) { - case 0: - return reg->NegateX; - case 1: - return reg->NegateY; - case 2: - return reg->NegateZ; - case 3: - return reg->NegateW; - default: - assert( 0 ); - } - return 0; -} - -void -tgsi_util_set_src_register_extnegate( - struct tgsi_src_register_ext_swz *reg, - unsigned negate, - unsigned component ) -{ - switch( component ) { - case 0: - reg->NegateX = negate; - break; - case 1: - reg->NegateY = negate; - break; - case 2: - reg->NegateZ = negate; - break; - case 3: - reg->NegateW = negate; - break; - default: - assert( 0 ); - } -} - -unsigned -tgsi_util_get_full_src_register_sign_mode( - const struct tgsi_full_src_register *reg, - unsigned component ) -{ - unsigned sign_mode; - - if( reg->SrcRegisterExtMod.Absolute ) { - /* Consider only the post-abs negation. */ - - if( reg->SrcRegisterExtMod.Negate ) { - sign_mode = TGSI_UTIL_SIGN_SET; - } - else { - sign_mode = TGSI_UTIL_SIGN_CLEAR; - } - } - else { - /* Accumulate the three negations. */ - - unsigned negate; - - negate = reg->SrcRegister.Negate; - if( tgsi_util_get_src_register_extnegate( ®->SrcRegisterExtSwz, component ) ) { - negate = !negate; - } - if( reg->SrcRegisterExtMod.Negate ) { - negate = !negate; - } - - if( negate ) { - sign_mode = TGSI_UTIL_SIGN_TOGGLE; - } - else { - sign_mode = TGSI_UTIL_SIGN_KEEP; - } - } - - return sign_mode; -} - -void -tgsi_util_set_full_src_register_sign_mode( - struct tgsi_full_src_register *reg, - unsigned sign_mode ) -{ - reg->SrcRegisterExtSwz.NegateX = 0; - reg->SrcRegisterExtSwz.NegateY = 0; - reg->SrcRegisterExtSwz.NegateZ = 0; - reg->SrcRegisterExtSwz.NegateW = 0; - - switch (sign_mode) - { - case TGSI_UTIL_SIGN_CLEAR: - reg->SrcRegister.Negate = 0; - reg->SrcRegisterExtMod.Absolute = 1; - reg->SrcRegisterExtMod.Negate = 0; - break; - - case TGSI_UTIL_SIGN_SET: - reg->SrcRegister.Negate = 0; - reg->SrcRegisterExtMod.Absolute = 1; - reg->SrcRegisterExtMod.Negate = 1; - break; - - case TGSI_UTIL_SIGN_TOGGLE: - reg->SrcRegister.Negate = 1; - reg->SrcRegisterExtMod.Absolute = 0; - reg->SrcRegisterExtMod.Negate = 0; - break; - - case TGSI_UTIL_SIGN_KEEP: - reg->SrcRegister.Negate = 0; - reg->SrcRegisterExtMod.Absolute = 0; - reg->SrcRegisterExtMod.Negate = 0; - break; - - default: - assert( 0 ); - } -} - diff --git a/src/gallium/aux/tgsi/util/tgsi_util.h b/src/gallium/aux/tgsi/util/tgsi_util.h deleted file mode 100644 index ef14446f0e..0000000000 --- a/src/gallium/aux/tgsi/util/tgsi_util.h +++ /dev/null @@ -1,70 +0,0 @@ -#if !defined TGSI_UTIL_H -#define TGSI_UTIL_H - -#if defined __cplusplus -extern "C" { -#endif // defined __cplusplus - -void * -tgsi_align_128bit( - void *unaligned ); - -unsigned -tgsi_util_get_src_register_swizzle( - const struct tgsi_src_register *reg, - unsigned component ); - -unsigned -tgsi_util_get_src_register_extswizzle( - const struct tgsi_src_register_ext_swz *reg, - unsigned component); - -unsigned -tgsi_util_get_full_src_register_extswizzle( - const struct tgsi_full_src_register *reg, - unsigned component ); - -void -tgsi_util_set_src_register_swizzle( - struct tgsi_src_register *reg, - unsigned swizzle, - unsigned component ); - -void -tgsi_util_set_src_register_extswizzle( - struct tgsi_src_register_ext_swz *reg, - unsigned swizzle, - unsigned component ); - -unsigned -tgsi_util_get_src_register_extnegate( - const struct tgsi_src_register_ext_swz *reg, - unsigned component ); - -void -tgsi_util_set_src_register_extnegate( - struct tgsi_src_register_ext_swz *reg, - unsigned negate, - unsigned component ); - -#define TGSI_UTIL_SIGN_CLEAR 0 /* Force positive */ -#define TGSI_UTIL_SIGN_SET 1 /* Force negative */ -#define TGSI_UTIL_SIGN_TOGGLE 2 /* Negate */ -#define TGSI_UTIL_SIGN_KEEP 3 /* No change */ - -unsigned -tgsi_util_get_full_src_register_sign_mode( - const struct tgsi_full_src_register *reg, - unsigned component ); - -void -tgsi_util_set_full_src_register_sign_mode( - struct tgsi_full_src_register *reg, - unsigned sign_mode ); - -#if defined __cplusplus -} // extern "C" -#endif // defined __cplusplus - -#endif // !defined TGSI_UTIL_H - diff --git a/src/gallium/aux/util/p_debug.c b/src/gallium/aux/util/p_debug.c deleted file mode 100644 index b9607a6ba7..0000000000 --- a/src/gallium/aux/util/p_debug.c +++ /dev/null @@ -1,76 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include - -#ifdef WIN32 -#include -#include -#else -#include -#include -#endif - -#include "pipe/p_debug.h" -#include "pipe/p_compiler.h" - - -void debug_vprintf(const char *format, va_list ap) -{ -#ifdef WIN32 - EngDebugPrint("Gallium3D: ", (PCHAR)format, ap); -#else - vfprintf(stderr, format, ap); -#endif -} - - -void debug_printf(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - debug_vprintf(format, ap); - va_end(ap); -} - - -static INLINE void debug_abort(void) -{ -#ifdef WIN32 - EngDebugBreak(); -#else - abort(); -#endif -} - - -void debug_assert_fail(const char *expr, const char *file, unsigned line) -{ - debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr); - debug_abort(); -} diff --git a/src/gallium/aux/util/p_tile.c b/src/gallium/aux/util/p_tile.c deleted file mode 100644 index 3f795a3898..0000000000 --- a/src/gallium/aux/util/p_tile.c +++ /dev/null @@ -1,699 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * RGBA/float tile get/put functions. - * Usable both by drivers and state trackers. - * Surfaces should already be in a mapped state. - */ - - -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" - -#include "p_tile.h" - - - -/** - * Move raw block of pixels from surface to user memory. - * This should be usable by any hw driver that has mappable surfaces. - */ -void -pipe_get_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - void *p, int dst_stride) -{ - const uint cpp = ps->cpp; - const ubyte *pSrc; - const uint src_stride = ps->pitch * cpp; - ubyte *pDest; - uint i; - - if (dst_stride == 0) { - dst_stride = w * cpp; - } - - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - - pSrc = (const ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; - pDest = (ubyte *) p; - - for (i = 0; i < h; i++) { - memcpy(pDest, pSrc, w * cpp); - pDest += dst_stride; - pSrc += src_stride; - } - - pipe_surface_unmap(ps); -} - - -/** - * Move raw block of pixels from user memory to surface. - * This should be usable by any hw driver that has mappable surfaces. - */ -void -pipe_put_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const void *p, int src_stride) -{ - const uint cpp = ps->cpp; - const ubyte *pSrc; - const uint dst_stride = ps->pitch * cpp; - ubyte *pDest; - uint i; - - if (src_stride == 0) { - src_stride = w * cpp; - } - - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - - pSrc = (const ubyte *) p; - pDest = (ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; - - for (i = 0; i < h; i++) { - memcpy(pDest, pSrc, w * cpp); - pDest += dst_stride; - pSrc += src_stride; - } - - pipe_surface_unmap(ps); -} - - - - -/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */ -#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) - -#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \ - us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) - - - -/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ - -static void -a8r8g8b8_get_tile_rgba(unsigned *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - const unsigned pixel = *src++; - pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); - pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); - pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); - pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); - } - p += dst_stride; - } -} - - -static void -a8r8g8b8_put_tile_rgba(unsigned *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - unsigned r, g, b, a; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); - UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); - *dst++ = (a << 24) | (r << 16) | (g << 8) | b; - } - p += src_stride; - } -} - - -/*** PIPE_FORMAT_B8G8R8A8_UNORM ***/ - -static void -b8g8r8a8_get_tile_rgba(unsigned *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - const unsigned pixel = *src++; - pRow[0] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); - pRow[1] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); - pRow[2] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); - pRow[3] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); - } - p += dst_stride; - } -} - - -static void -b8g8r8a8_put_tile_rgba(unsigned *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - unsigned r, g, b, a; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); - UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); - *dst++ = (b << 24) | (g << 16) | (r << 8) | a; - } - p += src_stride; - } -} - - -/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/ - -static void -a1r5g5b5_get_tile_rgba(ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - const ushort pixel = *src++; - pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f); - pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f); - pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); - pRow[3] = ((pixel >> 15) ) * 1.0f; - } - p += dst_stride; - } -} - - -/*** PIPE_FORMAT_A4R4G4B4_UNORM ***/ - -static void -a4r4g4b4_get_tile_rgba(ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - const ushort pixel = *src++; - pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f); - pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f); - pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f); - pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f); - } - p += dst_stride; - } -} - - -/*** PIPE_FORMAT_R5G6B5_UNORM ***/ - -static void -r5g6b5_get_tile_rgba(ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - const ushort pixel = *src++; - pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f); - pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f); - pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); - pRow[3] = 1.0f; - } - p += dst_stride; - } -} - - -static void -r5g5b5_put_tile_rgba(ushort *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0); - uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0); - uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0); - *dst++ = (r << 11) | (g << 5) | (b); - } - p += src_stride; - } -} - - - -/*** PIPE_FORMAT_Z16_UNORM ***/ - -/** - * Return each Z value as four floats in [0,1]. - */ -static void -z16_get_tile_rgba(ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - const float scale = 1.0f / 65535.0f; - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = - pRow[3] = *src++ * scale; - } - p += dst_stride; - } -} - - - - -/*** PIPE_FORMAT_U_L8 ***/ - -static void -l8_get_tile_rgba(ubyte *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, src++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = UBYTE_TO_FLOAT(*src); - pRow[3] = 1.0; - } - p += dst_stride; - } -} - - -/*** PIPE_FORMAT_U_A8 ***/ - -static void -a8_get_tile_rgba(ubyte *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, src++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = 0.0; - pRow[3] = UBYTE_TO_FLOAT(*src); - } - p += dst_stride; - } -} - - -/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ - -static void -r16g16b16a16_get_tile_rgba(short *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, src += 4, pRow += 4) { - pRow[0] = SHORT_TO_FLOAT(src[0]); - pRow[1] = SHORT_TO_FLOAT(src[1]); - pRow[2] = SHORT_TO_FLOAT(src[2]); - pRow[3] = SHORT_TO_FLOAT(src[3]); - } - p += dst_stride; - } -} - - -static void -r16g16b16a16_put_tile_rgba(short *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, dst += 4, pRow += 4) { - UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); - UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]); - UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]); - UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]); - } - p += src_stride; - } -} - - - -/*** PIPE_FORMAT_U_I8 ***/ - -static void -i8_get_tile_rgba(ubyte *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, src++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = - pRow[3] = UBYTE_TO_FLOAT(*src); - } - p += dst_stride; - } -} - - -/*** PIPE_FORMAT_U_A8_L8 ***/ - -static void -a8_l8_get_tile_rgba(ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - ushort p = *src++; - pRow[0] = - pRow[1] = - pRow[2] = UBYTE_TO_FLOAT(p & 0xff); - pRow[3] = UBYTE_TO_FLOAT(p >> 8); - } - p += dst_stride; - } -} - - - - -/*** PIPE_FORMAT_Z32_UNORM ***/ - -/** - * Return each Z value as four floats in [0,1]. - */ -static void -z32_get_tile_rgba(unsigned *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - const double scale = 1.0 / (double) 0xffffffff; - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = - pRow[3] = (float) (*src++ * scale); - } - p += dst_stride; - } -} - - -/*** PIPE_FORMAT_S8Z24_UNORM ***/ - -/** - * Return Z component as four float in [0,1]. Stencil part ignored. - */ -static void -s8z24_get_tile_rgba(unsigned *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - const double scale = 1.0 / ((1 << 24) - 1); - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = - pRow[3] = (float) (scale * (*src++ & 0xffffff)); - } - p += dst_stride; - } -} - - -/*** PIPE_FORMAT_Z24S8_UNORM ***/ - -/** - * Return Z component as four float in [0,1]. Stencil part ignored. - */ -static void -z24s8_get_tile_rgba(unsigned *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - const double scale = 1.0 / ((1 << 24) - 1); - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = - pRow[3] = (float) (scale * (*src++ >> 8)); - } - p += dst_stride; - } -} - - -void -pipe_get_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - float *p) -{ - unsigned dst_stride = w * 4; - void *packed; - - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - - packed = MALLOC(h * w * ps->cpp); - - if (!packed) - return; - - pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp); - - switch (ps->format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - a8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_B8G8R8A8_UNORM: - b8g8r8a8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_A1R5G5B5_UNORM: - a1r5g5b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_A4R4G4B4_UNORM: - a4r4g4b4_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_R5G6B5_UNORM: - r5g6b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_U_L8: - l8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_U_A8: - a8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_U_I8: - i8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_U_A8_L8: - a8_l8_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_R16G16B16A16_SNORM: - r16g16b16a16_get_tile_rgba((short *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_Z16_UNORM: - z16_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_Z32_UNORM: - z32_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_S8Z24_UNORM: - s8z24_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); - break; - case PIPE_FORMAT_Z24S8_UNORM: - z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); - break; - default: - assert(0); - } - - FREE(packed); -} - - -void -pipe_put_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const float *p) -{ - unsigned src_stride = w * 4; - void *packed; - - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - - packed = MALLOC(h * w * ps->cpp); - - if (!packed) - return; - - switch (ps->format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_B8G8R8A8_UNORM: - b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_A1R5G5B5_UNORM: - /*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_R5G6B5_UNORM: - r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_R8G8B8A8_UNORM: - break; - case PIPE_FORMAT_U_L8: - /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_U_A8: - /*a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_U_I8: - /*i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_U_A8_L8: - /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_R16G16B16A16_SNORM: - r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_Z16_UNORM: - /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_Z32_UNORM: - /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_S8Z24_UNORM: - /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_Z24S8_UNORM: - /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ - break; - default: - assert(0); - } - - pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp); - - FREE(packed); -} diff --git a/src/gallium/aux/util/p_tile.h b/src/gallium/aux/util/p_tile.h deleted file mode 100644 index cd8124bf11..0000000000 --- a/src/gallium/aux/util/p_tile.h +++ /dev/null @@ -1,81 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef P_TILE_H -#define P_TILE_H - -#include "pipe/p_compiler.h" - -struct pipe_context; -struct pipe_surface; - - -/** - * Clip tile against surface dims. - * \return TRUE if tile is totally clipped, FALSE otherwise - */ -static INLINE boolean -pipe_clip_tile(uint x, uint y, uint *w, uint *h, const struct pipe_surface *ps) -{ - if (x >= ps->width) - return TRUE; - if (y >= ps->height) - return TRUE; - if (x + *w > ps->width) - *w = ps->width - x; - if (y + *h > ps->height) - *h = ps->height - y; - return FALSE; -} - - -extern void -pipe_get_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - void *p, int dst_stride); - -extern void -pipe_put_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const void *p, int src_stride); - - -extern void -pipe_get_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - float *p); - -extern void -pipe_put_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const float *p); - -#endif diff --git a/src/gallium/aux/util/p_util.c b/src/gallium/aux/util/p_util.c deleted file mode 100644 index 2a92f8e408..0000000000 --- a/src/gallium/aux/util/p_util.c +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * Miscellaneous utility functions. - */ - - -#include "pipe/p_defines.h" -#include "pipe/p_util.h" - - -/** - * Copy 2D rect from one place to another. - * Position and sizes are in pixels. - */ -void -pipe_copy_rect(ubyte * dst, - unsigned cpp, - unsigned dst_pitch, - unsigned dst_x, - unsigned dst_y, - unsigned width, - unsigned height, - const ubyte * src, - int src_pitch, - unsigned src_x, - int src_y) -{ - unsigned i; - - dst_pitch *= cpp; - src_pitch *= cpp; - dst += dst_x * cpp; - src += src_x * cpp; - dst += dst_y * dst_pitch; - src += src_y * src_pitch; - width *= cpp; - - if (width == dst_pitch && width == src_pitch) - memcpy(dst, src, height * width); - else { - for (i = 0; i < height; i++) { - memcpy(dst, src, width); - dst += dst_pitch; - src += src_pitch; - } - } -} diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile new file mode 100644 index 0000000000..da68498aa1 --- /dev/null +++ b/src/gallium/auxiliary/Makefile @@ -0,0 +1,24 @@ +TOP = ../../.. +include $(TOP)/configs/current + + +ifeq ($(CONFIG_NAME), linux-llvm) +LLVM_DIR = llvm +endif + +SUBDIRS = pipebuffer $(LLVM_DIR) + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c new file mode 100644 index 0000000000..9e77e0774d --- /dev/null +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -0,0 +1,181 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Zack Rusin + */ + +#include "cso_cache.h" +#include "cso_hash.h" + +#if 1 +static unsigned hash_key(const void *key, unsigned key_size) +{ + unsigned *ikey = (unsigned *)key; + unsigned hash = 0, i; + + assert(key_size % 4 == 0); + + /* I'm sure this can be improved on: + */ + for (i = 0; i < key_size/4; i++) + hash ^= ikey[i]; + + return hash; +} +#else +static unsigned hash_key(const unsigned char *p, int n) +{ + unsigned h = 0; + unsigned g; + + while (n--) { + h = (h << 4) + *p++; + if ((g = (h & 0xf0000000)) != 0) + h ^= g >> 23; + h &= ~g; + } + return h; +} +#endif + +unsigned cso_construct_key(void *item, int item_size) +{ + return hash_key((item), item_size); +} + +static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_type type) +{ + struct cso_hash *hash = 0; + + switch(type) { + case CSO_BLEND: + hash = sc->blend_hash; + break; + case CSO_SAMPLER: + hash = sc->sampler_hash; + break; + case CSO_DEPTH_STENCIL_ALPHA: + hash = sc->depth_stencil_hash; + break; + case CSO_RASTERIZER: + hash = sc->rasterizer_hash; + break; + case CSO_FRAGMENT_SHADER: + hash = sc->fs_hash; + break; + case CSO_VERTEX_SHADER: + hash = sc->vs_hash; + break; + } + + return hash; +} + +static int _cso_size_for_type(enum cso_cache_type type) +{ + switch(type) { + case CSO_BLEND: + return sizeof(struct pipe_blend_state); + case CSO_SAMPLER: + return sizeof(struct pipe_sampler_state); + case CSO_DEPTH_STENCIL_ALPHA: + return sizeof(struct pipe_depth_stencil_alpha_state); + case CSO_RASTERIZER: + return sizeof(struct pipe_rasterizer_state); + case CSO_FRAGMENT_SHADER: + return sizeof(struct pipe_shader_state); + case CSO_VERTEX_SHADER: + return sizeof(struct pipe_shader_state); + } + return 0; +} + +struct cso_hash_iter +cso_insert_state(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type, + void *state) +{ + struct cso_hash *hash = _cso_hash_for_type(sc, type); + return cso_hash_insert(hash, hash_key, state); +} + +struct cso_hash_iter +cso_find_state(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type) +{ + struct cso_hash *hash = _cso_hash_for_type(sc, type); + + return cso_hash_find(hash, hash_key); +} + +struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type, + void *templ) +{ + struct cso_hash_iter iter = cso_find_state(sc, hash_key, type); + int size = _cso_size_for_type(type); + while (!cso_hash_iter_is_null(iter)) { + void *iter_data = cso_hash_iter_data(iter); + if (!memcmp(iter_data, templ, size)) + return iter; + iter = cso_hash_iter_next(iter); + } + return iter; +} + +void * cso_take_state(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type) +{ + struct cso_hash *hash = _cso_hash_for_type(sc, type); + return cso_hash_take(hash, hash_key); +} + +struct cso_cache *cso_cache_create(void) +{ + struct cso_cache *sc = malloc(sizeof(struct cso_cache)); + + sc->blend_hash = cso_hash_create(); + sc->sampler_hash = cso_hash_create(); + sc->depth_stencil_hash = cso_hash_create(); + sc->rasterizer_hash = cso_hash_create(); + sc->fs_hash = cso_hash_create(); + sc->vs_hash = cso_hash_create(); + + return sc; +} + +void cso_cache_delete(struct cso_cache *sc) +{ + assert(sc); + cso_hash_delete(sc->blend_hash); + cso_hash_delete(sc->sampler_hash); + cso_hash_delete(sc->depth_stencil_hash); + cso_hash_delete(sc->rasterizer_hash); + cso_hash_delete(sc->fs_hash); + cso_hash_delete(sc->vs_hash); + free(sc); +} diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h new file mode 100644 index 0000000000..116e2eaa2c --- /dev/null +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -0,0 +1,107 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin + */ + +#ifndef CSO_CACHE_H +#define CSO_CACHE_H + +#include "pipe/p_context.h" +#include "pipe/p_state.h" + + +struct cso_hash; + +struct cso_cache { + struct cso_hash *blend_hash; + struct cso_hash *depth_stencil_hash; + struct cso_hash *fs_hash; + struct cso_hash *vs_hash; + struct cso_hash *rasterizer_hash; + struct cso_hash *sampler_hash; +}; + +struct cso_blend { + struct pipe_blend_state state; + void *data; +}; + +struct cso_depth_stencil_alpha { + struct pipe_depth_stencil_alpha_state state; + void *data; +}; + +struct cso_rasterizer { + struct pipe_rasterizer_state state; + void *data; +}; + +struct cso_fragment_shader { + struct pipe_shader_state state; + void *data; +}; + +struct cso_vertex_shader { + struct pipe_shader_state state; + void *data; +}; + +struct cso_sampler { + struct pipe_sampler_state state; + void *data; +}; + + +enum cso_cache_type { + CSO_BLEND, + CSO_SAMPLER, + CSO_DEPTH_STENCIL_ALPHA, + CSO_RASTERIZER, + CSO_FRAGMENT_SHADER, + CSO_VERTEX_SHADER +}; + +unsigned cso_construct_key(void *item, int item_size); + +struct cso_cache *cso_cache_create(void); +void cso_cache_delete(struct cso_cache *sc); + +struct cso_hash_iter cso_insert_state(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type, + void *state); +struct cso_hash_iter cso_find_state(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type); +struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, + unsigned hash_key, enum cso_cache_type type, + void *templ); +void * cso_take_state(struct cso_cache *sc, unsigned hash_key, + enum cso_cache_type type); + +#endif diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c new file mode 100644 index 0000000000..0338cb3b47 --- /dev/null +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -0,0 +1,388 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin + */ + +#include "cso_hash.h" + +#include +#include +#include +#include + +#define MAX(a, b) ((a > b) ? (a) : (b)) + +static const int MinNumBits = 4; + +static const unsigned char prime_deltas[] = { + 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3, + 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0 +}; + +static int primeForNumBits(int numBits) +{ + return (1 << numBits) + prime_deltas[numBits]; +} + +/* + Returns the smallest integer n such that + primeForNumBits(n) >= hint. +*/ +static int countBits(int hint) +{ + int numBits = 0; + int bits = hint; + + while (bits > 1) { + bits >>= 1; + numBits++; + } + + if (numBits >= (int)sizeof(prime_deltas)) { + numBits = sizeof(prime_deltas) - 1; + } else if (primeForNumBits(numBits) < hint) { + ++numBits; + } + return numBits; +} + +struct cso_node { + struct cso_node *next; + unsigned key; + void *value; +}; + +struct cso_hash_data { + struct cso_node *fakeNext; + struct cso_node **buckets; + int size; + int nodeSize; + short userNumBits; + short numBits; + int numBuckets; +}; + +struct cso_hash { + union { + struct cso_hash_data *d; + struct cso_node *e; + } data; +}; + +static void *cso_data_allocate_node(struct cso_hash_data *hash) +{ + return malloc(hash->nodeSize); +} + +static void cso_data_free_node(struct cso_node *node) +{ + /* XXX still a leak here. + * Need to cast value ptr to original cso type, then free the + * driver-specific data hanging off of it. For example: + struct cso_sampler *csamp = (struct cso_sampler *) node->value; + free(csamp->data); + */ + free(node->value); + free(node); +} + +static struct cso_node * +cso_hash_create_node(struct cso_hash *hash, + unsigned akey, void *avalue, + struct cso_node **anextNode) +{ + struct cso_node *node = cso_data_allocate_node(hash->data.d); + node->key = akey; + node->value = avalue; + + node->next = (struct cso_node*)(*anextNode); + *anextNode = node; + ++hash->data.d->size; + return node; +} + +static void cso_data_rehash(struct cso_hash_data *hash, int hint) +{ + if (hint < 0) { + hint = countBits(-hint); + if (hint < MinNumBits) + hint = MinNumBits; + hash->userNumBits = hint; + while (primeForNumBits(hint) < (hash->size >> 1)) + ++hint; + } else if (hint < MinNumBits) { + hint = MinNumBits; + } + + if (hash->numBits != hint) { + struct cso_node *e = (struct cso_node *)(hash); + struct cso_node **oldBuckets = hash->buckets; + int oldNumBuckets = hash->numBuckets; + int i = 0; + + hash->numBits = hint; + hash->numBuckets = primeForNumBits(hint); + hash->buckets = malloc(sizeof(struct cso_node*) * hash->numBuckets); + for (i = 0; i < hash->numBuckets; ++i) + hash->buckets[i] = e; + + for (i = 0; i < oldNumBuckets; ++i) { + struct cso_node *firstNode = oldBuckets[i]; + while (firstNode != e) { + unsigned h = firstNode->key; + struct cso_node *lastNode = firstNode; + while (lastNode->next != e && lastNode->next->key == h) + lastNode = lastNode->next; + + struct cso_node *afterLastNode = lastNode->next; + struct cso_node **beforeFirstNode = &hash->buckets[h % hash->numBuckets]; + while (*beforeFirstNode != e) + beforeFirstNode = &(*beforeFirstNode)->next; + lastNode->next = *beforeFirstNode; + *beforeFirstNode = firstNode; + firstNode = afterLastNode; + } + } + free(oldBuckets); + } +} + +static void cso_data_might_grow(struct cso_hash_data *hash) +{ + if (hash->size >= hash->numBuckets) + cso_data_rehash(hash, hash->numBits + 1); +} + +static void cso_data_has_shrunk(struct cso_hash_data *hash) +{ + if (hash->size <= (hash->numBuckets >> 3) && + hash->numBits > hash->userNumBits) { + int max = MAX(hash->numBits-2, hash->userNumBits); + cso_data_rehash(hash, max); + } +} + +static struct cso_node *cso_data_first_node(struct cso_hash_data *hash) +{ + struct cso_node *e = (struct cso_node *)(hash); + struct cso_node **bucket = hash->buckets; + int n = hash->numBuckets; + while (n--) { + if (*bucket != e) + return *bucket; + ++bucket; + } + return e; +} + +static struct cso_node **cso_hash_find_node(struct cso_hash *hash, unsigned akey) +{ + struct cso_node **node; + + if (hash->data.d->numBuckets) { + node = (struct cso_node **)(&hash->data.d->buckets[akey % hash->data.d->numBuckets]); + assert(*node == hash->data.e || (*node)->next); + while (*node != hash->data.e && (*node)->key != akey) + node = &(*node)->next; + } else { + node = (struct cso_node **)((const struct cso_node * const *)(&hash->data.e)); + } + return node; +} + +struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, + unsigned key, void *data) +{ + cso_data_might_grow(hash->data.d); + + struct cso_node **nextNode = cso_hash_find_node(hash, key); + struct cso_node *node = cso_hash_create_node(hash, key, data, nextNode); + struct cso_hash_iter iter = {hash, node}; + return iter; +} + +struct cso_hash * cso_hash_create(void) +{ + struct cso_hash *hash = malloc(sizeof(struct cso_hash)); + hash->data.d = malloc(sizeof(struct cso_hash_data)); + hash->data.d->fakeNext = 0; + hash->data.d->buckets = 0; + hash->data.d->size = 0; + hash->data.d->nodeSize = sizeof(struct cso_node); + hash->data.d->userNumBits = MinNumBits; + hash->data.d->numBits = 0; + hash->data.d->numBuckets = 0; + + return hash; +} + +void cso_hash_delete(struct cso_hash *hash) +{ + struct cso_node *e_for_x = (struct cso_node *)(hash->data.d); + struct cso_node **bucket = (struct cso_node **)(hash->data.d->buckets); + int n = hash->data.d->numBuckets; + while (n--) { + struct cso_node *cur = *bucket++; + while (cur != e_for_x) { + struct cso_node *next = cur->next; + cso_data_free_node(cur); + cur = next; + } + } + free(hash->data.d->buckets); + free(hash->data.d); + free(hash); +} + +struct cso_hash_iter cso_hash_find(struct cso_hash *hash, + unsigned key) +{ + struct cso_node **nextNode = cso_hash_find_node(hash, key); + struct cso_hash_iter iter = {hash, *nextNode}; + return iter; +} + +unsigned cso_hash_iter_key(struct cso_hash_iter iter) +{ + if (!iter.node || iter.hash->data.e == iter.node) + return 0; + return iter.node->key; +} + +void * cso_hash_iter_data(struct cso_hash_iter iter) +{ + if (!iter.node || iter.hash->data.e == iter.node) + return 0; + return iter.node->value; +} + +static struct cso_node *cso_hash_data_next(struct cso_node *node) +{ + union { + struct cso_node *next; + struct cso_node *e; + struct cso_hash_data *d; + } a; + a.next = node->next; + if (!a.next) { + fprintf(stderr, "iterating beyond the last element\n"); + return 0; + } + if (a.next->next) + return a.next; + + int start = (node->key % a.d->numBuckets) + 1; + struct cso_node **bucket = a.d->buckets + start; + int n = a.d->numBuckets - start; + while (n--) { + if (*bucket != a.e) + return *bucket; + ++bucket; + } + return a.e; +} + + +static struct cso_node *cso_hash_data_prev(struct cso_node *node) +{ + union { + struct cso_node *e; + struct cso_hash_data *d; + } a; + + a.e = node; + while (a.e->next) + a.e = a.e->next; + + int start; + if (node == a.e) + start = a.d->numBuckets - 1; + else + start = node->key % a.d->numBuckets; + + struct cso_node *sentinel = node; + struct cso_node **bucket = a.d->buckets + start; + while (start >= 0) { + if (*bucket != sentinel) { + struct cso_node *prev = *bucket; + while (prev->next != sentinel) + prev = prev->next; + return prev; + } + + sentinel = a.e; + --bucket; + --start; + } + fprintf(stderr, "iterating backward beyond first element\n"); + return a.e; +} + +struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter) +{ + struct cso_hash_iter next = {iter.hash, cso_hash_data_next(iter.node)}; + return next; +} + +int cso_hash_iter_is_null(struct cso_hash_iter iter) +{ + if (!iter.node || iter.node == iter.hash->data.e) + return 1; + return 0; +} + +void * cso_hash_take(struct cso_hash *hash, + unsigned akey) +{ + struct cso_node **node = cso_hash_find_node(hash, akey); + if (*node != hash->data.e) { + void *t = (*node)->value; + struct cso_node *next = (*node)->next; + cso_data_free_node(*node); + *node = next; + --hash->data.d->size; + cso_data_has_shrunk(hash->data.d); + return t; + } + return 0; +} + +struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter) +{ + struct cso_hash_iter prev = {iter.hash, + cso_hash_data_prev(iter.node)}; + return prev; +} + +struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash) +{ + struct cso_hash_iter iter = {hash, cso_data_first_node(hash->data.d)}; + return iter; +} diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h new file mode 100644 index 0000000000..b4aa111860 --- /dev/null +++ b/src/gallium/auxiliary/cso_cache/cso_hash.h @@ -0,0 +1,62 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin + */ + +#ifndef CSO_HASH_H +#define CSO_HASH_H + +struct cso_hash; +struct cso_node; + +struct cso_hash_iter { + struct cso_hash *hash; + struct cso_node *node; +}; + +struct cso_hash *cso_hash_create(void); +void cso_hash_delete(struct cso_hash *hash); + +struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, unsigned key, + void *data); +void *cso_hash_take(struct cso_hash *hash, unsigned key); + +struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash); +struct cso_hash_iter cso_hash_find(struct cso_hash *hash, unsigned key); + + +int cso_hash_iter_is_null(struct cso_hash_iter iter); +unsigned cso_hash_iter_key(struct cso_hash_iter iter); +void *cso_hash_iter_data(struct cso_hash_iter iter); + +struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter); +struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter); + +#endif diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile new file mode 100644 index 0000000000..451911a354 --- /dev/null +++ b/src/gallium/auxiliary/draw/Makefile @@ -0,0 +1,2 @@ +default: + cd .. ; make diff --git a/src/gallium/auxiliary/draw/draw_clip.c b/src/gallium/auxiliary/draw/draw_clip.c new file mode 100644 index 0000000000..e3051507ea --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_clip.c @@ -0,0 +1,488 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Clipping stage + * + * \author Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#include "draw_context.h" +#include "draw_private.h" + + +#ifndef IS_NEGATIVE +#define IS_NEGATIVE(X) ((X) < 0.0) +#endif + +#ifndef DIFFERENT_SIGNS +#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F) +#endif + +#ifndef MAX_CLIPPED_VERTICES +#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1) +#endif + + + +struct clipper { + struct draw_stage stage; /**< base class */ + + /* Basically duplicate some of the flatshading logic here: + */ + boolean flat; + uint num_color_attribs; + uint color_attribs[4]; /* front/back primary/secondary colors */ + + float (*plane)[4]; +}; + + +/* This is a bit confusing: + */ +static INLINE struct clipper *clipper_stage( struct draw_stage *stage ) +{ + return (struct clipper *)stage; +} + + +#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT))) + + +/* All attributes are float[4], so this is easy: + */ +static void interp_attr( float *fdst, + float t, + const float *fin, + const float *fout ) +{ + fdst[0] = LINTERP( t, fout[0], fin[0] ); + fdst[1] = LINTERP( t, fout[1], fin[1] ); + fdst[2] = LINTERP( t, fout[2], fin[2] ); + fdst[3] = LINTERP( t, fout[3], fin[3] ); +} + +static void copy_colors( struct draw_stage *stage, + struct vertex_header *dst, + const struct vertex_header *src ) +{ + const struct clipper *clipper = clipper_stage(stage); + uint i; + for (i = 0; i < clipper->num_color_attribs; i++) { + const uint attr = clipper->color_attribs[i]; + COPY_4FV(dst->data[attr], src->data[attr]); + } +} + + + +/* Interpolate between two vertices to produce a third. + */ +static void interp( const struct clipper *clip, + struct vertex_header *dst, + float t, + const struct vertex_header *out, + const struct vertex_header *in ) +{ + const unsigned nr_attrs = clip->stage.draw->num_vs_outputs; + unsigned j; + + /* Vertex header. + */ + { + dst->clipmask = 0; + dst->edgeflag = 0; + dst->pad = 0; + dst->vertex_id = UNDEFINED_VERTEX_ID; + } + + /* Clip coordinates: interpolate normally + */ + { + interp_attr(dst->clip, t, in->clip, out->clip); + } + + /* Do the projective divide and insert window coordinates: + */ + { + const float *pos = dst->clip; + const float *scale = clip->stage.draw->viewport.scale; + const float *trans = clip->stage.draw->viewport.translate; + const float oow = 1.0f / pos[3]; + + dst->data[0][0] = pos[0] * oow * scale[0] + trans[0]; + dst->data[0][1] = pos[1] * oow * scale[1] + trans[1]; + dst->data[0][2] = pos[2] * oow * scale[2] + trans[2]; + dst->data[0][3] = oow; + } + + /* Other attributes + * Note: start at 1 to skip winpos (data[0]) since we just computed + * it above. + */ + for (j = 1; j < nr_attrs; j++) { + interp_attr(dst->data[j], t, in->data[j], out->data[j]); + } +} + + +static void emit_poly( struct draw_stage *stage, + struct vertex_header **inlist, + unsigned n, + const struct prim_header *origPrim) +{ + struct prim_header header; + unsigned i; + + /* later stages may need the determinant, but only the sign matters */ + header.det = origPrim->det; + + for (i = 2; i < n; i++) { + header.v[0] = inlist[i-1]; + header.v[1] = inlist[i]; + header.v[2] = inlist[0]; /* keep in v[2] for flatshading */ + + { + unsigned tmp1 = header.v[1]->edgeflag; + unsigned tmp2 = header.v[2]->edgeflag; + + if (i != n-1) header.v[1]->edgeflag = 0; + if (i != 2) header.v[2]->edgeflag = 0; + + header.edgeflags = ((header.v[0]->edgeflag << 0) | + (header.v[1]->edgeflag << 1) | + (header.v[2]->edgeflag << 2)); + + stage->next->tri( stage->next, &header ); + + header.v[1]->edgeflag = tmp1; + header.v[2]->edgeflag = tmp2; + } + } +} + + + + +/* Clip a triangle against the viewport and user clip planes. + */ +static void +do_clip_tri( struct draw_stage *stage, + struct prim_header *header, + unsigned clipmask ) +{ + struct clipper *clipper = clipper_stage( stage ); + struct vertex_header *a[MAX_CLIPPED_VERTICES]; + struct vertex_header *b[MAX_CLIPPED_VERTICES]; + struct vertex_header **inlist = a; + struct vertex_header **outlist = b; + unsigned tmpnr = 0; + unsigned n = 3; + unsigned i; + + inlist[0] = header->v[0]; + inlist[1] = header->v[1]; + inlist[2] = header->v[2]; + + while (clipmask && n >= 3) { + const unsigned plane_idx = ffs(clipmask)-1; + const float *plane = clipper->plane[plane_idx]; + struct vertex_header *vert_prev = inlist[0]; + float dp_prev = dot4( vert_prev->clip, plane ); + unsigned outcount = 0; + + clipmask &= ~(1<clip, plane ); + + if (!IS_NEGATIVE(dp_prev)) { + outlist[outcount++] = vert_prev; + } + + if (DIFFERENT_SIGNS(dp, dp_prev)) { + struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++]; + outlist[outcount++] = new_vert; + + if (IS_NEGATIVE(dp)) { + /* Going out of bounds. Avoid division by zero as we + * know dp != dp_prev from DIFFERENT_SIGNS, above. + */ + float t = dp / (dp - dp_prev); + interp( clipper, new_vert, t, vert, vert_prev ); + + /* Force edgeflag true in this case: + */ + new_vert->edgeflag = 1; + } else { + /* Coming back in. + */ + float t = dp_prev / (dp_prev - dp); + interp( clipper, new_vert, t, vert_prev, vert ); + + /* Copy starting vert's edgeflag: + */ + new_vert->edgeflag = vert_prev->edgeflag; + } + } + + vert_prev = vert; + dp_prev = dp; + } + + { + struct vertex_header **tmp = inlist; + inlist = outlist; + outlist = tmp; + n = outcount; + } + } + + /* If flat-shading, copy color to new provoking vertex. + */ + if (clipper->flat && inlist[0] != header->v[2]) { + if (1) { + inlist[0] = dup_vert(stage, inlist[0], tmpnr++); + } + + copy_colors(stage, inlist[0], header->v[2]); + } + + + + /* Emit the polygon as triangles to the setup stage: + */ + if (n >= 3) + emit_poly( stage, inlist, n, header ); +} + + +/* Clip a line against the viewport and user clip planes. + */ +static void +do_clip_line( struct draw_stage *stage, + struct prim_header *header, + unsigned clipmask ) +{ + const struct clipper *clipper = clipper_stage( stage ); + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + const float *pos0 = v0->clip; + const float *pos1 = v1->clip; + float t0 = 0.0F; + float t1 = 0.0F; + struct prim_header newprim; + + while (clipmask) { + const unsigned plane_idx = ffs(clipmask)-1; + const float *plane = clipper->plane[plane_idx]; + const float dp0 = dot4( pos0, plane ); + const float dp1 = dot4( pos1, plane ); + + if (dp1 < 0.0F) { + float t = dp1 / (dp1 - dp0); + t1 = MAX2(t1, t); + } + + if (dp0 < 0.0F) { + float t = dp0 / (dp0 - dp1); + t0 = MAX2(t0, t); + } + + if (t0 + t1 >= 1.0F) + return; /* discard */ + + clipmask &= ~(1 << plane_idx); /* turn off this plane's bit */ + } + + if (v0->clipmask) { + interp( clipper, stage->tmp[0], t0, v0, v1 ); + + if (clipper->flat) + copy_colors(stage, stage->tmp[0], v0); + + newprim.v[0] = stage->tmp[0]; + } + else { + newprim.v[0] = v0; + } + + if (v1->clipmask) { + interp( clipper, stage->tmp[1], t1, v1, v0 ); + newprim.v[1] = stage->tmp[1]; + } + else { + newprim.v[1] = v1; + } + + stage->next->line( stage->next, &newprim ); +} + + +static void +clip_point( struct draw_stage *stage, + struct prim_header *header ) +{ + if (header->v[0]->clipmask == 0) + stage->next->point( stage->next, header ); +} + + +static void +clip_line( struct draw_stage *stage, + struct prim_header *header ) +{ + unsigned clipmask = (header->v[0]->clipmask | + header->v[1]->clipmask); + + if (clipmask == 0) { + /* no clipping needed */ + stage->next->line( stage->next, header ); + } + else if ((header->v[0]->clipmask & + header->v[1]->clipmask) == 0) { + do_clip_line(stage, header, clipmask); + } + /* else, totally clipped */ +} + + +static void +clip_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + unsigned clipmask = (header->v[0]->clipmask | + header->v[1]->clipmask | + header->v[2]->clipmask); + + if (clipmask == 0) { + /* no clipping needed */ + stage->next->tri( stage->next, header ); + } + else if ((header->v[0]->clipmask & + header->v[1]->clipmask & + header->v[2]->clipmask) == 0) { + do_clip_tri(stage, header, clipmask); + } +} + +/* Update state. Could further delay this until we hit the first + * primitive that really requires clipping. + */ +static void +clip_init_state( struct draw_stage *stage ) +{ + struct clipper *clipper = clipper_stage( stage ); + + clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE; + + if (clipper->flat) { + const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; + uint i; + + clipper->num_color_attribs = 0; + for (i = 0; i < vs->num_outputs; i++) { + if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR || + vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + clipper->color_attribs[clipper->num_color_attribs++] = i; + } + } + } + + stage->tri = clip_tri; + stage->line = clip_line; +} + + + +static void clip_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + clip_init_state( stage ); + stage->tri( stage, header ); +} + +static void clip_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + clip_init_state( stage ); + stage->line( stage, header ); +} + + +static void clip_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = clip_first_tri; + stage->line = clip_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void clip_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void clip_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Allocate a new clipper stage. + * \return pointer to new stage object + */ +struct draw_stage *draw_clip_stage( struct draw_context *draw ) +{ + struct clipper *clipper = CALLOC_STRUCT(clipper); + + draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ); + + clipper->stage.draw = draw; + clipper->stage.point = clip_point; + clipper->stage.line = clip_first_line; + clipper->stage.tri = clip_first_tri; + clipper->stage.flush = clip_flush; + clipper->stage.reset_stipple_counter = clip_reset_stipple_counter; + clipper->stage.destroy = clip_destroy; + + clipper->plane = draw->plane; + + return &clipper->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c new file mode 100644 index 0000000000..4be3830316 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -0,0 +1,293 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "draw_context.h" +#include "draw_private.h" + + + +struct draw_context *draw_create( void ) +{ + struct draw_context *draw = CALLOC_STRUCT( draw_context ); + +#if defined(__i386__) || defined(__386__) + draw->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; +#else + draw->use_sse = FALSE; +#endif + + /* create pipeline stages */ + draw->pipeline.wide = draw_wide_stage( draw ); + draw->pipeline.stipple = draw_stipple_stage( draw ); + draw->pipeline.unfilled = draw_unfilled_stage( draw ); + draw->pipeline.twoside = draw_twoside_stage( draw ); + draw->pipeline.offset = draw_offset_stage( draw ); + draw->pipeline.clip = draw_clip_stage( draw ); + draw->pipeline.flatshade = draw_flatshade_stage( draw ); + draw->pipeline.cull = draw_cull_stage( draw ); + draw->pipeline.validate = draw_validate_stage( draw ); + draw->pipeline.first = draw->pipeline.validate; + + 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 ); + ASSIGN_4V( draw->plane[3], 0, 1, 0, 1 ); + ASSIGN_4V( draw->plane[4], 0, 0, 1, 1 ); /* yes these are correct */ + ASSIGN_4V( draw->plane[5], 0, 0, -1, 1 ); /* mesa's a bit wonky */ + draw->nr_planes = 6; + + /* Statically allocate maximum sized vertices for the cache - could be cleverer... + */ + { + uint i; + const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; + char *tmp = align_malloc(Elements(draw->vcache.vertex) * size, 16); + + for (i = 0; i < Elements(draw->vcache.vertex); i++) + draw->vcache.vertex[i] = (struct vertex_header *)(tmp + i * size); + } + + draw->shader_queue_flush = draw_vertex_shader_queue_flush; + + draw->convert_wide_points = TRUE; + draw->convert_wide_lines = TRUE; + + draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ + + draw_vertex_cache_invalidate( draw ); + draw_set_mapped_element_buffer( draw, 0, NULL ); + + return draw; +} + + +void draw_destroy( struct draw_context *draw ) +{ + draw->pipeline.wide->destroy( draw->pipeline.wide ); + draw->pipeline.stipple->destroy( draw->pipeline.stipple ); + draw->pipeline.unfilled->destroy( draw->pipeline.unfilled ); + draw->pipeline.twoside->destroy( draw->pipeline.twoside ); + draw->pipeline.offset->destroy( draw->pipeline.offset ); + draw->pipeline.clip->destroy( draw->pipeline.clip ); + draw->pipeline.flatshade->destroy( draw->pipeline.flatshade ); + draw->pipeline.cull->destroy( draw->pipeline.cull ); + draw->pipeline.validate->destroy( draw->pipeline.validate ); + if (draw->pipeline.rasterize) + draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); + tgsi_exec_machine_free_data(&draw->machine); + align_free( draw->vcache.vertex[0] ); /* Frees all the vertices. */ + FREE( draw ); +} + + + +void draw_flush( struct draw_context *draw ) +{ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); +} + + + +/** + * Register new primitive rasterization/rendering state. + * This causes the drawing pipeline to be rebuilt. + */ +void draw_set_rasterizer_state( struct draw_context *draw, + const struct pipe_rasterizer_state *raster ) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + draw->rasterizer = raster; +} + + +/** + * Plug in the primitive rendering/rasterization stage (which is the last + * stage in the drawing pipeline). + * This is provided by the device driver. + */ +void draw_set_rasterize_stage( struct draw_context *draw, + struct draw_stage *stage ) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + draw->pipeline.rasterize = stage; +} + + +/** + * Set the draw module's clipping state. + */ +void draw_set_clip_state( struct draw_context *draw, + const struct pipe_clip_state *clip ) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + assert(clip->nr <= PIPE_MAX_CLIP_PLANES); + memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0])); + draw->nr_planes = 6 + clip->nr; +} + + +/** + * Set the draw module's viewport state. + */ +void draw_set_viewport_state( struct draw_context *draw, + const struct pipe_viewport_state *viewport ) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->viewport = *viewport; /* struct copy */ +} + + + +void +draw_set_vertex_buffer(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_buffer *buffer) +{ + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); + assert(attr < PIPE_ATTRIB_MAX); + draw->vertex_buffer[attr] = *buffer; +} + + +void +draw_set_vertex_element(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_element *element) +{ + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); + assert(attr < PIPE_ATTRIB_MAX); + draw->vertex_element[attr] = *element; +} + + +/** + * Tell drawing context where to find mapped vertex buffers. + */ +void +draw_set_mapped_vertex_buffer(struct draw_context *draw, + unsigned attr, const void *buffer) +{ + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); + draw->user.vbuffer[attr] = buffer; +} + + +void +draw_set_mapped_constant_buffer(struct draw_context *draw, + const void *buffer) +{ + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); + draw->user.constants = buffer; +} + + +/** + * Tells the draw module whether to convert wide points (size != 1) + * into triangles. + */ +void +draw_convert_wide_points(struct draw_context *draw, boolean enable) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->convert_wide_points = enable; +} + + +/** + * Tells the draw module whether to convert wide lines (width != 1) + * into triangles. + */ +void +draw_convert_wide_lines(struct draw_context *draw, boolean enable) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->convert_wide_lines = enable; +} + + +/** + * Allocate space for temporary post-transform vertices, such as for clipping. + */ +void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) +{ + assert(!stage->tmp); + + stage->nr_tmps = nr; + + if (nr) { + ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); + unsigned i; + + stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); + + for (i = 0; i < nr; i++) + stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + } +} + + +void draw_free_temp_verts( struct draw_stage *stage ) +{ + if (stage->tmp) { + FREE( stage->tmp[0] ); + FREE( stage->tmp ); + stage->tmp = NULL; + } +} + + +boolean draw_use_sse(struct draw_context *draw) +{ + return (boolean) draw->use_sse; +} + + +void draw_reset_vertex_ids(struct draw_context *draw) +{ + struct draw_stage *stage = draw->pipeline.first; + + while (stage) { + unsigned i; + + for (i = 0; i < stage->nr_tmps; i++) + stage->tmp[i]->vertex_id = UNDEFINED_VERTEX_ID; + + stage = stage->next; + } + + draw_vertex_cache_reset_vertex_ids(draw); +} diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h new file mode 100644 index 0000000000..ddeb184497 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -0,0 +1,142 @@ + +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Public interface into the drawing module. + */ + +/* Authors: Keith Whitwell + */ + + +#ifndef DRAW_CONTEXT_H +#define DRAW_CONTEXT_H + + +#include "pipe/p_state.h" + + +struct vertex_buffer; +struct vertex_info; +struct draw_context; +struct draw_stage; +struct draw_vertex_shader; + + +/** + * Clipmask flags + */ +/*@{*/ +#define CLIP_RIGHT_BIT 0x01 +#define CLIP_LEFT_BIT 0x02 +#define CLIP_TOP_BIT 0x04 +#define CLIP_BOTTOM_BIT 0x08 +#define CLIP_NEAR_BIT 0x10 +#define CLIP_FAR_BIT 0x20 +/*@}*/ + +/** + * Bitshift for each clip flag + */ +/*@{*/ +#define CLIP_RIGHT_SHIFT 0 +#define CLIP_LEFT_SHIFT 1 +#define CLIP_TOP_SHIFT 2 +#define CLIP_BOTTOM_SHIFT 3 +#define CLIP_NEAR_SHIFT 4 +#define CLIP_FAR_SHIFT 5 +/*@}*/ + + +struct draw_context *draw_create( void ); + +void draw_destroy( struct draw_context *draw ); + +void draw_set_viewport_state( struct draw_context *draw, + const struct pipe_viewport_state *viewport ); + +void draw_set_clip_state( struct draw_context *pipe, + const struct pipe_clip_state *clip ); + +void draw_set_rasterizer_state( struct draw_context *draw, + const struct pipe_rasterizer_state *raster ); + +void draw_set_rasterize_stage( struct draw_context *draw, + struct draw_stage *stage ); + +void draw_convert_wide_points(struct draw_context *draw, boolean enable); + +void draw_convert_wide_lines(struct draw_context *draw, boolean enable); + + +struct draw_vertex_shader * +draw_create_vertex_shader(struct draw_context *draw, + const struct pipe_shader_state *shader); +void draw_bind_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs); +void draw_delete_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs); + +boolean draw_use_sse(struct draw_context *draw); + +void draw_set_vertex_buffer(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_buffer *buffer); + +void draw_set_vertex_element(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_element *element); + +void draw_set_mapped_element_buffer( struct draw_context *draw, + unsigned eltSize, void *elements ); + +void draw_set_mapped_vertex_buffer(struct draw_context *draw, + unsigned attr, const void *buffer); + +void draw_set_mapped_constant_buffer(struct draw_context *draw, + const void *buffer); + + +/*********************************************************************** + * draw_prim.c + */ + +void draw_arrays(struct draw_context *draw, unsigned prim, + unsigned start, unsigned count); + +void draw_flush(struct draw_context *draw); + +/*********************************************************************** + * draw_debug.c + */ +boolean draw_validate_prim( unsigned prim, unsigned length ); +unsigned draw_trim_prim( unsigned mode, unsigned count ); + + + +#endif /* DRAW_CONTEXT_H */ diff --git a/src/gallium/auxiliary/draw/draw_cull.c b/src/gallium/auxiliary/draw/draw_cull.c new file mode 100644 index 0000000000..8177b0ac86 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_cull.c @@ -0,0 +1,150 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Drawing stage for polygon culling + */ + +/* Authors: Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + + +struct cull_stage { + struct draw_stage stage; + unsigned winding; /**< which winding(s) to cull (one of PIPE_WINDING_x) */ +}; + + +static INLINE struct cull_stage *cull_stage( struct draw_stage *stage ) +{ + return (struct cull_stage *)stage; +} + + + + +static void cull_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + /* Window coords: */ + const float *v0 = header->v[0]->data[0]; + const float *v1 = header->v[1]->data[0]; + const float *v2 = header->v[2]->data[0]; + + /* edge vectors e = v0 - v2, f = v1 - v2 */ + const float ex = v0[0] - v2[0]; + const float ey = v0[1] - v2[1]; + const float fx = v1[0] - v2[0]; + const float fy = v1[1] - v2[1]; + + /* det = cross(e,f).z */ + header->det = ex * fy - ey * fx; + + if (header->det != 0) { + /* if (det < 0 then Z points toward camera and triangle is + * counter-clockwise winding. + */ + unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; + + if ((winding & cull_stage(stage)->winding) == 0) { + /* triangle is not culled, pass to next stage */ + stage->next->tri( stage->next, header ); + } + } +} + +static void cull_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct cull_stage *cull = cull_stage(stage); + + cull->winding = stage->draw->rasterizer->cull_mode; + + stage->tri = cull_tri; + stage->tri( stage, header ); +} + + + +static void cull_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void cull_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void cull_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->tri = cull_first_tri; + stage->next->flush( stage->next, flags ); +} + +static void cull_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void cull_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create a new polygon culling stage. + */ +struct draw_stage *draw_cull_stage( struct draw_context *draw ) +{ + struct cull_stage *cull = CALLOC_STRUCT(cull_stage); + + draw_alloc_temp_verts( &cull->stage, 0 ); + + cull->stage.draw = draw; + cull->stage.next = NULL; + cull->stage.point = cull_point; + cull->stage.line = cull_line; + cull->stage.tri = cull_first_tri; + cull->stage.flush = cull_flush; + cull->stage.reset_stipple_counter = cull_reset_stipple_counter; + cull->stage.destroy = cull_destroy; + + return &cull->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_debug.c b/src/gallium/auxiliary/draw/draw_debug.c new file mode 100644 index 0000000000..d6220b5f62 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_debug.c @@ -0,0 +1,113 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "draw_private.h" +#include "draw_context.h" + + + +static void +draw_prim_info(unsigned prim, unsigned *first, unsigned *incr) +{ + assert(prim >= PIPE_PRIM_POINTS); + assert(prim <= PIPE_PRIM_POLYGON); + + switch (prim) { + case PIPE_PRIM_POINTS: + *first = 1; + *incr = 1; + break; + case PIPE_PRIM_LINES: + *first = 2; + *incr = 2; + break; + case PIPE_PRIM_LINE_STRIP: + *first = 2; + *incr = 1; + break; + case PIPE_PRIM_LINE_LOOP: + *first = 2; + *incr = 1; + break; + case PIPE_PRIM_TRIANGLES: + *first = 3; + *incr = 3; + break; + case PIPE_PRIM_TRIANGLE_STRIP: + *first = 3; + *incr = 1; + break; + case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_POLYGON: + *first = 3; + *incr = 1; + break; + case PIPE_PRIM_QUADS: + *first = 4; + *incr = 4; + break; + case PIPE_PRIM_QUAD_STRIP: + *first = 4; + *incr = 2; + break; + default: + assert(0); + *first = 1; + *incr = 1; + break; + } +} + + +unsigned +draw_trim_prim( unsigned mode, unsigned count ) +{ + unsigned length, first, incr; + + draw_prim_info( mode, &first, &incr ); + + if (count < first) + length = 0; + else + length = count - (count - first) % incr; + + return length; +} + + +boolean +draw_validate_prim( unsigned mode, unsigned count ) +{ + return (count > 0 && + count == draw_trim_prim( mode, count )); +} + diff --git a/src/gallium/auxiliary/draw/draw_flatshade.c b/src/gallium/auxiliary/draw/draw_flatshade.c new file mode 100644 index 0000000000..4398abbc60 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_flatshade.c @@ -0,0 +1,205 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +/** subclass of draw_stage */ +struct flat_stage +{ + struct draw_stage stage; + + uint num_color_attribs; + uint color_attribs[4]; /* front/back primary/secondary colors */ +}; + + +static INLINE struct flat_stage * +flat_stage(struct draw_stage *stage) +{ + return (struct flat_stage *) stage; +} + + +/** Copy all the color attributes from 'src' vertex to 'dst' vertex */ +static INLINE void copy_colors( struct draw_stage *stage, + struct vertex_header *dst, + const struct vertex_header *src ) +{ + const struct flat_stage *flat = flat_stage(stage); + uint i; + for (i = 0; i < flat->num_color_attribs; i++) { + const uint attr = flat->color_attribs[i]; + COPY_4FV(dst->data[attr], src->data[attr]); + } +} + + +/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */ +static INLINE void copy_colors2( struct draw_stage *stage, + struct vertex_header *dst0, + struct vertex_header *dst1, + const struct vertex_header *src ) +{ + const struct flat_stage *flat = flat_stage(stage); + uint i; + for (i = 0; i < flat->num_color_attribs; i++) { + const uint attr = flat->color_attribs[i]; + COPY_4FV(dst0->data[attr], src->data[attr]); + COPY_4FV(dst1->data[attr], src->data[attr]); + } +} + + +/** + * Flatshade tri. Required for clipping and when unfilled tris are + * active, otherwise handled by hardware. + */ +static void flatshade_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = dup_vert(stage, header->v[1], 1); + tmp.v[2] = header->v[2]; + + copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]); + + stage->next->tri( stage->next, &tmp ); +} + + +/** + * Flatshade line. Required for clipping. + */ +static void flatshade_line( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = header->v[1]; + + copy_colors(stage, tmp.v[0], tmp.v[1]); + + stage->next->line( stage->next, &tmp ); +} + + +static void flatshade_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void flatshade_init_state( struct draw_stage *stage ) +{ + struct flat_stage *flat = flat_stage(stage); + const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; + uint i; + + /* Find which vertex shader outputs are colors, make a list */ + flat->num_color_attribs = 0; + for (i = 0; i < vs->num_outputs; i++) { + if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR || + vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + flat->color_attribs[flat->num_color_attribs++] = i; + } + } + + stage->line = flatshade_line; + stage->tri = flatshade_tri; +} + +static void flatshade_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + flatshade_init_state( stage ); + stage->tri( stage, header ); +} + +static void flatshade_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + flatshade_init_state( stage ); + stage->line( stage, header ); +} + + +static void flatshade_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = flatshade_first_tri; + stage->line = flatshade_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void flatshade_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void flatshade_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create flatshading drawing stage. + */ +struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) +{ + struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage); + + draw_alloc_temp_verts( &flatshade->stage, 2 ); + + flatshade->stage.draw = draw; + flatshade->stage.next = NULL; + flatshade->stage.point = flatshade_point; + flatshade->stage.line = flatshade_first_line; + flatshade->stage.tri = flatshade_first_tri; + flatshade->stage.flush = flatshade_flush; + flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter; + flatshade->stage.destroy = flatshade_destroy; + + return &flatshade->stage; +} + + diff --git a/src/gallium/auxiliary/draw/draw_offset.c b/src/gallium/auxiliary/draw/draw_offset.c new file mode 100644 index 0000000000..dbc676deae --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_offset.c @@ -0,0 +1,186 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief polygon offset state + * + * \author Keith Whitwell + * \author Brian Paul + */ + +#include "pipe/p_util.h" +#include "draw_private.h" + + + +struct offset_stage { + struct draw_stage stage; + + float scale; + float units; +}; + + + +static INLINE struct offset_stage *offset_stage( struct draw_stage *stage ) +{ + return (struct offset_stage *) stage; +} + + + + + +/** + * Offset tri Z. Some hardware can handle this, but not usually when + * doing unfilled rendering. + */ +static void do_offset_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct offset_stage *offset = offset_stage(stage); + float inv_det = 1.0f / header->det; + + /* Window coords: + */ + float *v0 = header->v[0]->data[0]; + float *v1 = header->v[1]->data[0]; + float *v2 = header->v[2]->data[0]; + + /* edge vectors e = v0 - v2, f = v1 - v2 */ + float ex = v0[0] - v2[0]; + float ey = v0[1] - v2[1]; + float ez = v0[2] - v2[2]; + float fx = v1[0] - v2[0]; + float fy = v1[1] - v2[1]; + float fz = v1[2] - v2[2]; + + /* (a,b) = cross(e,f).xy */ + float a = ey*fz - ez*fy; + float b = ez*fx - ex*fz; + + float dzdx = FABSF(a * inv_det); + float dzdy = FABSF(b * inv_det); + + float zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale; + + /* + * Note: we're applying the offset and clamping per-vertex. + * Ideally, the offset is applied per-fragment prior to fragment shading. + */ + v0[2] = CLAMP(v0[2] + zoffset, 0.0f, 1.0f); + v1[2] = CLAMP(v1[2] + zoffset, 0.0f, 1.0f); + v2[2] = CLAMP(v2[2] + zoffset, 0.0f, 1.0f); + + stage->next->tri( stage->next, header ); +} + + +static void offset_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = dup_vert(stage, header->v[1], 1); + tmp.v[2] = dup_vert(stage, header->v[2], 2); + + do_offset_tri( stage, &tmp ); +} + + +static void offset_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct offset_stage *offset = offset_stage(stage); + float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */ + + offset->units = stage->draw->rasterizer->offset_units * mrd; + offset->scale = stage->draw->rasterizer->offset_scale; + + stage->tri = offset_tri; + stage->tri( stage, header ); +} + + +static void offset_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void offset_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void offset_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = offset_first_tri; + stage->next->flush( stage->next, flags ); +} + + +static void offset_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void offset_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create polygon offset drawing stage. + */ +struct draw_stage *draw_offset_stage( struct draw_context *draw ) +{ + struct offset_stage *offset = CALLOC_STRUCT(offset_stage); + + draw_alloc_temp_verts( &offset->stage, 3 ); + + offset->stage.draw = draw; + offset->stage.next = NULL; + offset->stage.point = offset_point; + offset->stage.line = offset_line; + offset->stage.tri = offset_first_tri; + offset->stage.flush = offset_flush; + offset->stage.reset_stipple_counter = offset_reset_stipple_counter; + offset->stage.destroy = offset_destroy; + + return &offset->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c new file mode 100644 index 0000000000..51e2242719 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -0,0 +1,482 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_debug.h" + +#include "draw_private.h" +#include "draw_context.h" + + + +#define RP_NONE 0 +#define RP_POINT 1 +#define RP_LINE 2 +#define RP_TRI 3 + + +static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { + RP_POINT, + RP_LINE, + RP_LINE, + RP_LINE, + RP_TRI, + RP_TRI, + RP_TRI, + RP_TRI, + RP_TRI, + RP_TRI +}; + + +static void draw_prim_queue_flush( struct draw_context *draw ) +{ + unsigned i; + + if (0) + debug_printf("Flushing with %d prims, %d verts\n", + draw->pq.queue_nr, draw->vs.queue_nr); + + assert (draw->pq.queue_nr != 0); + + /* NOTE: we cannot save draw->pipeline->first in a local var because + * draw->pipeline->first is often changed by the first call to tri(), + * line(), etc. + */ + if (draw->rasterizer->line_stipple_enable) { + switch (draw->reduced_prim) { + case RP_TRI: + for (i = 0; i < draw->pq.queue_nr; i++) { + if (draw->pq.queue[i].reset_line_stipple) + draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); + + draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] ); + } + break; + case RP_LINE: + for (i = 0; i < draw->pq.queue_nr; i++) { + if (draw->pq.queue[i].reset_line_stipple) + draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); + + draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] ); + } + break; + case RP_POINT: + draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); + for (i = 0; i < draw->pq.queue_nr; i++) + draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] ); + break; + } + } + else { + switch (draw->reduced_prim) { + case RP_TRI: + for (i = 0; i < draw->pq.queue_nr; i++) + draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] ); + break; + case RP_LINE: + for (i = 0; i < draw->pq.queue_nr; i++) + draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] ); + break; + case RP_POINT: + for (i = 0; i < draw->pq.queue_nr; i++) + draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] ); + break; + } + } + + draw->pq.queue_nr = 0; + draw_vertex_cache_unreference( draw ); +} + + + +void draw_do_flush( struct draw_context *draw, unsigned flags ) +{ + if (0) + debug_printf("Flushing with %d verts, %d prims\n", + draw->vs.queue_nr, + draw->pq.queue_nr ); + + + if (flags >= DRAW_FLUSH_SHADER_QUEUE) { + if (draw->vs.queue_nr) + (*draw->shader_queue_flush)(draw); + + if (flags >= DRAW_FLUSH_PRIM_QUEUE) { + if (draw->pq.queue_nr) + draw_prim_queue_flush(draw); + + if (flags >= DRAW_FLUSH_VERTEX_CACHE) { + draw_vertex_cache_invalidate(draw); + + if (flags >= DRAW_FLUSH_STATE_CHANGE) { + draw->pipeline.first->flush( draw->pipeline.first, flags ); + draw->pipeline.first = draw->pipeline.validate; + draw->reduced_prim = ~0; + } + } + } + } +} + + + +/* Return a pointer to a freshly queued primitive header. Ensure that + * there is room in the vertex cache for a maximum of "nr_verts" new + * vertices. Flush primitive and/or vertex queues if necessary to + * make space. + */ +static struct prim_header *get_queued_prim( struct draw_context *draw, + unsigned nr_verts ) +{ + if (!draw_vertex_cache_check_space( draw, nr_verts )) { +// debug_printf("v"); + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE ); + } + else if (draw->pq.queue_nr == PRIM_QUEUE_LENGTH) { +// debug_printf("p"); + draw_do_flush( draw, DRAW_FLUSH_PRIM_QUEUE ); + } + + assert(draw->pq.queue_nr < PRIM_QUEUE_LENGTH); + + return &draw->pq.queue[draw->pq.queue_nr++]; +} + + + +/** + * Add a point to the primitive queue. + * \param i0 index into user's vertex arrays + */ +static void do_point( struct draw_context *draw, + unsigned i0 ) +{ + struct prim_header *prim = get_queued_prim( draw, 1 ); + + prim->reset_line_stipple = 0; + prim->edgeflags = 1; + prim->pad = 0; + prim->v[0] = draw->vcache.get_vertex( draw, i0 ); +} + + +/** + * Add a line to the primitive queue. + * \param i0 index into user's vertex arrays + * \param i1 index into user's vertex arrays + */ +static void do_line( struct draw_context *draw, + boolean reset_stipple, + unsigned i0, + unsigned i1 ) +{ + struct prim_header *prim = get_queued_prim( draw, 2 ); + + prim->reset_line_stipple = reset_stipple; + prim->edgeflags = 1; + prim->pad = 0; + prim->v[0] = draw->vcache.get_vertex( draw, i0 ); + prim->v[1] = draw->vcache.get_vertex( draw, i1 ); +} + +/** + * Add a triangle to the primitive queue. + */ +static void do_triangle( struct draw_context *draw, + unsigned i0, + unsigned i1, + unsigned i2 ) +{ + struct prim_header *prim = get_queued_prim( draw, 3 ); + + prim->reset_line_stipple = 1; + prim->edgeflags = ~0; + prim->pad = 0; + prim->v[0] = draw->vcache.get_vertex( draw, i0 ); + prim->v[1] = draw->vcache.get_vertex( draw, i1 ); + prim->v[2] = draw->vcache.get_vertex( draw, i2 ); +} + +static void do_ef_triangle( struct draw_context *draw, + boolean reset_stipple, + unsigned ef_mask, + unsigned i0, + unsigned i1, + unsigned i2 ) +{ + struct prim_header *prim = get_queued_prim( draw, 3 ); + struct vertex_header *v0 = draw->vcache.get_vertex( draw, i0 ); + struct vertex_header *v1 = draw->vcache.get_vertex( draw, i1 ); + struct vertex_header *v2 = draw->vcache.get_vertex( draw, i2 ); + + prim->reset_line_stipple = reset_stipple; + + prim->edgeflags = ef_mask & ((v0->edgeflag << 0) | + (v1->edgeflag << 1) | + (v2->edgeflag << 2)); + prim->pad = 0; + prim->v[0] = v0; + prim->v[1] = v1; + prim->v[2] = v2; +} + + +static void do_ef_quad( struct draw_context *draw, + unsigned v0, + unsigned v1, + unsigned v2, + unsigned v3 ) +{ + const unsigned omitEdge2 = ~(1 << 1); + const unsigned omitEdge3 = ~(1 << 2); + do_ef_triangle( draw, 1, omitEdge2, v0, v1, v3 ); + do_ef_triangle( draw, 0, omitEdge3, v1, v2, v3 ); +} + +static void do_quad( struct draw_context *draw, + unsigned v0, + unsigned v1, + unsigned v2, + unsigned v3 ) +{ + do_triangle( draw, v0, v1, v3 ); + do_triangle( draw, v1, v2, v3 ); +} + + +/** + * Main entrypoint to draw some number of points/lines/triangles + */ +static void +draw_prim( struct draw_context *draw, + unsigned prim, unsigned start, unsigned count ) +{ + unsigned i; + boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL); + +// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count ); + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i ++) { + do_point( draw, + start + i ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) { + do_line( draw, + TRUE, + start + i + 0, + start + i + 1); + } + break; + + case PIPE_PRIM_LINE_LOOP: + if (count >= 2) { + for (i = 1; i < count; i++) { + do_line( draw, + i == 1, /* XXX: only if vb not split */ + start + i - 1, + start + i ); + } + + do_line( draw, + 0, + start + count - 1, + start + 0 ); + } + break; + + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < count; i++) { + do_line( draw, + i == 1, + start + i - 1, + start + i ); + } + break; + + case PIPE_PRIM_TRIANGLES: + if (unfilled) { + for (i = 0; i+2 < count; i += 3) { + do_ef_triangle( draw, + 1, + ~0, + start + i + 0, + start + i + 1, + start + i + 2 ); + } + } + else { + for (i = 0; i+2 < count; i += 3) { + do_triangle( draw, + start + i + 0, + start + i + 1, + start + i + 2 ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + for (i = 0; i+2 < count; i++) { + if (i & 1) { + do_triangle( draw, + start + i + 1, + start + i + 0, + start + i + 2 ); + } + else { + do_triangle( draw, + start + i + 0, + start + i + 1, + start + i + 2 ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (count >= 3) { + for (i = 0; i+2 < count; i++) { + do_triangle( draw, + start + 0, + start + i + 1, + start + i + 2 ); + } + } + break; + + + case PIPE_PRIM_QUADS: + if (unfilled) { + for (i = 0; i+3 < count; i += 4) { + do_ef_quad( draw, + start + i + 0, + start + i + 1, + start + i + 2, + start + i + 3); + } + } + else { + for (i = 0; i+3 < count; i += 4) { + do_quad( draw, + start + i + 0, + start + i + 1, + start + i + 2, + start + i + 3); + } + } + break; + + case PIPE_PRIM_QUAD_STRIP: + if (unfilled) { + for (i = 0; i+3 < count; i += 2) { + do_ef_quad( draw, + start + i + 2, + start + i + 0, + start + i + 1, + start + i + 3); + } + } + else { + for (i = 0; i+3 < count; i += 2) { + do_quad( draw, + start + i + 2, + start + i + 0, + start + i + 1, + start + i + 3); + } + } + break; + + case PIPE_PRIM_POLYGON: + if (unfilled) { + unsigned ef_mask = (1<<2) | (1<<0); + + for (i = 0; i+2 < count; i++) { + + if (i + 3 >= count) + ef_mask |= (1<<1); + + do_ef_triangle( draw, + i == 0, + ef_mask, + start + i + 1, + start + i + 2, + start + 0); + + ef_mask &= ~(1<<2); + } + } + else { + for (i = 0; i+2 < count; i++) { + do_triangle( draw, + start + i + 1, + start + i + 2, + start + 0); + } + } + break; + + default: + assert(0); + break; + } +} + + + + +/** + * Draw vertex arrays + * This is the main entrypoint into the drawing module. + * \param prim one of PIPE_PRIM_x + * \param start index of first vertex to draw + * \param count number of vertices to draw + */ +void +draw_arrays(struct draw_context *draw, unsigned prim, + unsigned start, unsigned count) +{ + if (reduced_prim[prim] != draw->reduced_prim) { + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->reduced_prim = reduced_prim[prim]; + } + + /* drawing done here: */ + draw_prim(draw, prim, start, count); +} + + diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h new file mode 100644 index 0000000000..3d09aef87c --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -0,0 +1,346 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Private data structures, etc for the draw module. + */ + + +/** + * Authors: + * Keith Whitwell + * Brian Paul + */ + + +#ifndef DRAW_PRIVATE_H +#define DRAW_PRIVATE_H + + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" + +#include "x86/rtasm/x86sse.h" +#include "tgsi/exec/tgsi_exec.h" + + +struct gallivm_prog; +struct gallivm_cpu_engine; + +/** + * Basic vertex info. + * Carry some useful information around with the vertices in the prim pipe. + */ +struct vertex_header { + unsigned clipmask:12; + unsigned edgeflag:1; + unsigned pad:3; + unsigned vertex_id:16; + + float clip[4]; + + float data[][4]; /* Note variable size */ +}; + +/* NOTE: It should match vertex_id size above */ +#define UNDEFINED_VERTEX_ID 0xffff + +/* XXX This is too large */ +#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) + + + +/** + * Basic info for a point/line/triangle primitive. + */ +struct prim_header { + float det; /**< front/back face determinant */ + unsigned reset_line_stipple:1; + unsigned edgeflags:3; + unsigned pad:28; + struct vertex_header *v[3]; /**< 1 to 3 vertex pointers */ +}; + + + +struct draw_context; + +/** + * Base class for all primitive drawing stages. + */ +struct draw_stage +{ + struct draw_context *draw; /**< parent context */ + + struct draw_stage *next; /**< next stage in pipeline */ + + struct vertex_header **tmp; /**< temp vert storage, such as for clipping */ + unsigned nr_tmps; + + void (*point)( struct draw_stage *, + struct prim_header * ); + + void (*line)( struct draw_stage *, + struct prim_header * ); + + void (*tri)( struct draw_stage *, + struct prim_header * ); + + void (*flush)( struct draw_stage *, + unsigned flags ); + + void (*reset_stipple_counter)( struct draw_stage * ); + + void (*destroy)( struct draw_stage * ); +}; + + +#define PRIM_QUEUE_LENGTH 16 +#define VCACHE_SIZE 32 +#define VCACHE_OVERFLOW 4 +#define VS_QUEUE_LENGTH (VCACHE_SIZE + VCACHE_OVERFLOW + 1) /* can never fill up */ + +/** + * Private version of the compiled vertex_shader + */ +struct draw_vertex_shader { + const struct pipe_shader_state *state; +#if defined(__i386__) || defined(__386__) + struct x86_function sse2_program; +#endif +#ifdef MESA_LLVM + struct gallivm_prog *llvm_prog; +#endif +}; + + +/* Internal function for vertex fetch. + */ +typedef void (*fetch_func)(const void *ptr, float *attrib); +typedef void (*full_fetch_func)( struct draw_context *draw, + struct tgsi_exec_machine *machine, + const unsigned *elts, + unsigned count ); + + + +/** + * Private context for the drawing module. + */ +struct draw_context +{ + /** Drawing/primitive pipeline stages */ + struct { + struct draw_stage *first; /**< one of the following */ + + struct draw_stage *validate; + + /* stages (in logical order) */ + struct draw_stage *flatshade; + struct draw_stage *clip; + struct draw_stage *cull; + struct draw_stage *twoside; + struct draw_stage *offset; + struct draw_stage *unfilled; + struct draw_stage *stipple; + struct draw_stage *wide; + struct draw_stage *rasterize; + } pipeline; + + /* pipe state that we need: */ + const struct pipe_rasterizer_state *rasterizer; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + const struct draw_vertex_shader *vertex_shader; + + uint num_vs_outputs; /**< convenience, from vertex_shader */ + + /* user-space vertex data, buffers */ + struct { + /** vertex element/index buffer (ex: glDrawElements) */ + const void *elts; + /** bytes per index (0, 1, 2 or 4) */ + unsigned eltSize; + + /** vertex arrays */ + const void *vbuffer[PIPE_ATTRIB_MAX]; + + /** constant buffer (for vertex shader) */ + const void *constants; + } user; + + /* Clip derived state: + */ + float plane[12][4]; + unsigned nr_planes; + + boolean convert_wide_points; /**< convert wide points to tris? */ + boolean convert_wide_lines; /**< convert side lines to tris? */ + + unsigned reduced_prim; + + /** TGSI program interpreter runtime state */ + struct tgsi_exec_machine machine; + + /* Vertex fetch internal state + */ + struct { + const ubyte *src_ptr[PIPE_ATTRIB_MAX]; + unsigned pitch[PIPE_ATTRIB_MAX]; + fetch_func fetch[PIPE_ATTRIB_MAX]; + unsigned nr_attrs; + full_fetch_func fetch_func; + } vertex_fetch; + + /* Post-tnl vertex cache: + */ + struct { + unsigned referenced; /**< bitfield */ + unsigned idx[VCACHE_SIZE + VCACHE_OVERFLOW]; + struct vertex_header *vertex[VCACHE_SIZE + VCACHE_OVERFLOW]; + unsigned overflow; + + /** To find space in the vertex cache: */ + struct vertex_header *(*get_vertex)( struct draw_context *draw, + unsigned i ); + } vcache; + + /* Vertex shader queue: + */ + struct { + struct { + unsigned elt; /**< index into the user's vertex arrays */ + struct vertex_header *dest; /**< points into vcache.vertex[] array */ + } queue[VS_QUEUE_LENGTH]; + unsigned queue_nr; + } vs; + + /** + * Run the vertex shader on all vertices in the vertex queue. + */ + void (*shader_queue_flush)(struct draw_context *draw); + + /* Prim pipeline queue: + */ + struct { + /* Need to queue up primitives until their vertices have been + * transformed by a vs queue flush. + */ + struct prim_header queue[PRIM_QUEUE_LENGTH]; + unsigned queue_nr; + } pq; + + int use_sse : 1; +#ifdef MESA_LLVM + struct gallivm_cpu_engine *engine; +#endif + + void *driver_private; +}; + + + +extern struct draw_stage *draw_unfilled_stage( struct draw_context *context ); +extern struct draw_stage *draw_twoside_stage( struct draw_context *context ); +extern struct draw_stage *draw_offset_stage( struct draw_context *context ); +extern struct draw_stage *draw_clip_stage( struct draw_context *context ); +extern struct draw_stage *draw_flatshade_stage( struct draw_context *context ); +extern struct draw_stage *draw_cull_stage( struct draw_context *context ); +extern struct draw_stage *draw_stipple_stage( struct draw_context *context ); +extern struct draw_stage *draw_wide_stage( struct draw_context *context ); +extern struct draw_stage *draw_validate_stage( struct draw_context *context ); + + +extern void draw_free_temp_verts( struct draw_stage *stage ); + +extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); + +extern void draw_reset_vertex_ids( struct draw_context *draw ); + + +extern int draw_vertex_cache_check_space( struct draw_context *draw, + unsigned nr_verts ); + +extern void draw_vertex_cache_invalidate( struct draw_context *draw ); +extern void draw_vertex_cache_unreference( struct draw_context *draw ); +extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ); + + +extern void draw_vertex_shader_queue_flush( struct draw_context *draw ); +#ifdef MESA_LLVM +extern void draw_vertex_shader_queue_flush_llvm( struct draw_context *draw ); +#endif + +struct tgsi_exec_machine; + +extern void draw_update_vertex_fetch( struct draw_context *draw ); + + +#define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ +#define DRAW_FLUSH_PRIM_QUEUE 0x2 +#define DRAW_FLUSH_VERTEX_CACHE 0x4 +#define DRAW_FLUSH_STATE_CHANGE 0x8 +#define DRAW_FLUSH_BACKEND 0x10 + + +void draw_do_flush( struct draw_context *draw, unsigned flags ); + + + +/** + * Get a writeable copy of a vertex. + * \param stage drawing stage info + * \param vert the vertex to copy (source) + * \param idx index into stage's tmp[] array to put the copy (dest) + * \return pointer to the copied vertex + */ +static INLINE struct vertex_header * +dup_vert( struct draw_stage *stage, + const struct vertex_header *vert, + unsigned idx ) +{ + struct vertex_header *tmp = stage->tmp[idx]; + const uint vsize = sizeof(struct vertex_header) + + stage->draw->num_vs_outputs * 4 * sizeof(float); + memcpy(tmp, vert, vsize); + tmp->vertex_id = UNDEFINED_VERTEX_ID; + return tmp; +} + +static INLINE float +dot4(const float *a, const float *b) +{ + float result = (a[0]*b[0] + + a[1]*b[1] + + a[2]*b[2] + + a[3]*b[3]); + + return result; +} + +#endif /* DRAW_PRIVATE_H */ diff --git a/src/gallium/auxiliary/draw/draw_stipple.c b/src/gallium/auxiliary/draw/draw_stipple.c new file mode 100644 index 0000000000..506f33512c --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_stipple.c @@ -0,0 +1,239 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +/* Implement line stipple by cutting lines up into smaller lines. + * There are hundreds of ways to implement line stipple, this is one + * choice that should work in all situations, requires no state + * manipulations, but with a penalty in terms of large amounts of + * generated geometry. + */ + + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +/** Subclass of draw_stage */ +struct stipple_stage { + struct draw_stage stage; + float counter; + uint pattern; + uint factor; +}; + + +static INLINE struct stipple_stage * +stipple_stage(struct draw_stage *stage) +{ + return (struct stipple_stage *) stage; +} + + +/** + * Compute interpolated vertex attributes for 'dst' at position 't' + * between 'v0' and 'v1'. + * XXX using linear interpolation for all attribs at this time. + */ +static void +screen_interp( struct draw_context *draw, + struct vertex_header *dst, + float t, + const struct vertex_header *v0, + const struct vertex_header *v1 ) +{ + uint attr; + for (attr = 0; attr < draw->num_vs_outputs; attr++) { + const float *val0 = v0->data[attr]; + const float *val1 = v1->data[attr]; + float *newv = dst->data[attr]; + uint i; + for (i = 0; i < 4; i++) { + newv[i] = val0[i] + t * (val1[i] - val0[i]); + } + } +} + + +static void +emit_segment(struct draw_stage *stage, struct prim_header *header, + float t0, float t1) +{ + struct vertex_header *v0new = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1new = dup_vert(stage, header->v[1], 1); + struct prim_header newprim = *header; + + if (t0 > 0.0) { + screen_interp( stage->draw, v0new, t0, header->v[0], header->v[1] ); + newprim.v[0] = v0new; + } + + if (t1 < 1.0) { + screen_interp( stage->draw, v1new, t1, header->v[0], header->v[1] ); + newprim.v[1] = v1new; + } + + stage->next->line( stage->next, &newprim ); +} + + +static INLINE unsigned +stipple_test(int counter, ushort pattern, int factor) +{ + int b = (counter / factor) & 0xf; + return (1 << b) & pattern; +} + + +static void +stipple_line(struct draw_stage *stage, struct prim_header *header) +{ + struct stipple_stage *stipple = stipple_stage(stage); + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + const float *pos0 = v0->data[0]; + const float *pos1 = v1->data[0]; + float start = 0; + int state = 0; + + float x0 = pos0[0]; + float x1 = pos1[0]; + float y0 = pos0[1]; + float y1 = pos1[1]; + + float dx = x0 > x1 ? x0 - x1 : x1 - x0; + float dy = y0 > y1 ? y0 - y1 : y1 - y0; + + float length = MAX2(dx, dy); + int i; + + /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table. + */ + for (i = 0; i < length; i++) { + int result = stipple_test( (int) stipple->counter+i, + (ushort) stipple->pattern, stipple->factor ); + if (result != state) { + /* changing from "off" to "on" or vice versa */ + if (state) { + if (start != i) { + /* finishing an "on" segment */ + emit_segment( stage, header, start / length, i / length ); + } + } + else { + /* starting an "on" segment */ + start = (float) i; + } + state = result; + } + } + + if (state && start < length) + emit_segment( stage, header, start / length, 1.0 ); + + stipple->counter += length; +} + + +static void +reset_stipple_counter(struct draw_stage *stage) +{ + struct stipple_stage *stipple = stipple_stage(stage); + stipple->counter = 0; + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +stipple_first_line(struct draw_stage *stage, + struct prim_header *header) +{ + struct stipple_stage *stipple = stipple_stage(stage); + struct draw_context *draw = stage->draw; + + stipple->pattern = draw->rasterizer->line_stipple_pattern; + stipple->factor = draw->rasterizer->line_stipple_factor + 1; + + stage->line = stipple_line; + stage->line( stage, header ); +} + + +static void +stipple_flush(struct draw_stage *stage, unsigned flags) +{ + stage->line = stipple_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point( stage->next, header ); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +static void +stipple_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create line stippler stage + */ +struct draw_stage *draw_stipple_stage( struct draw_context *draw ) +{ + struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage); + + draw_alloc_temp_verts( &stipple->stage, 2 ); + + stipple->stage.draw = draw; + stipple->stage.next = NULL; + stipple->stage.point = passthrough_point; + stipple->stage.line = stipple_first_line; + stipple->stage.tri = passthrough_tri; + stipple->stage.reset_stipple_counter = reset_stipple_counter; + stipple->stage.flush = stipple_flush; + stipple->stage.destroy = stipple_destroy; + + return &stipple->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_twoside.c b/src/gallium/auxiliary/draw/draw_twoside.c new file mode 100644 index 0000000000..1c38957987 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_twoside.c @@ -0,0 +1,203 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +struct twoside_stage { + struct draw_stage stage; + float sign; /**< +1 or -1 */ + uint attrib_front0, attrib_back0; + uint attrib_front1, attrib_back1; +}; + + +static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage ) +{ + return (struct twoside_stage *)stage; +} + + + + +/** + * Copy back color(s) to front color(s). + */ +static INLINE struct vertex_header * +copy_bfc( struct twoside_stage *twoside, + const struct vertex_header *v, + unsigned idx ) +{ + struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx ); + + if (twoside->attrib_back0) { + COPY_4FV(tmp->data[twoside->attrib_front0], + tmp->data[twoside->attrib_back0]); + } + if (twoside->attrib_back1) { + COPY_4FV(tmp->data[twoside->attrib_front1], + tmp->data[twoside->attrib_back1]); + } + + return tmp; +} + + +/* Twoside tri: + */ +static void twoside_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct twoside_stage *twoside = twoside_stage(stage); + + if (header->det * twoside->sign < 0.0) { + /* this is a back-facing triangle */ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + /* copy back attribs to front attribs */ + tmp.v[0] = copy_bfc(twoside, header->v[0], 0); + tmp.v[1] = copy_bfc(twoside, header->v[1], 1); + tmp.v[2] = copy_bfc(twoside, header->v[2], 2); + + stage->next->tri( stage->next, &tmp ); + } + else { + stage->next->tri( stage->next, header ); + } +} + + +static void twoside_line( struct draw_stage *stage, + struct prim_header *header ) +{ + /* pass-through */ + stage->next->line( stage->next, header ); +} + + +static void twoside_point( struct draw_stage *stage, + struct prim_header *header ) +{ + /* pass-through */ + stage->next->point( stage->next, header ); +} + + +static void twoside_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct twoside_stage *twoside = twoside_stage(stage); + const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; + uint i; + + twoside->attrib_front0 = 0; + twoside->attrib_front1 = 0; + twoside->attrib_back0 = 0; + twoside->attrib_back1 = 0; + + /* Find which vertex shader outputs are front/back colors */ + for (i = 0; i < vs->num_outputs; i++) { + if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR) { + if (vs->output_semantic_index[i] == 0) + twoside->attrib_front0 = i; + else + twoside->attrib_front1 = i; + } + if (vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + if (vs->output_semantic_index[i] == 0) + twoside->attrib_back0 = i; + else + twoside->attrib_back1 = i; + } + } + + if (!twoside->attrib_back0) + twoside->attrib_front0 = 0; + + if (!twoside->attrib_back1) + twoside->attrib_front1 = 0; + + /* + * We'll multiply the primitive's determinant by this sign to determine + * if the triangle is back-facing (negative). + * sign = -1 for CCW, +1 for CW + */ + twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f; + + stage->tri = twoside_tri; + stage->tri( stage, header ); +} + + +static void twoside_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->tri = twoside_first_tri; + stage->next->flush( stage->next, flags ); +} + + +static void twoside_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void twoside_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create twoside pipeline stage. + */ +struct draw_stage *draw_twoside_stage( struct draw_context *draw ) +{ + struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage); + + draw_alloc_temp_verts( &twoside->stage, 3 ); + + twoside->stage.draw = draw; + twoside->stage.next = NULL; + twoside->stage.point = twoside_point; + twoside->stage.line = twoside_line; + twoside->stage.tri = twoside_first_tri; + twoside->stage.flush = twoside_flush; + twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter; + twoside->stage.destroy = twoside_destroy; + + return &twoside->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_unfilled.c b/src/gallium/auxiliary/draw/draw_unfilled.c new file mode 100644 index 0000000000..8777cfdfc8 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_unfilled.c @@ -0,0 +1,206 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Drawing stage for handling glPolygonMode(line/point). + * Convert triangles to points or lines as needed. + */ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + + +struct unfilled_stage { + struct draw_stage stage; + + /** [0] = front face, [1] = back face. + * legal values: PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE, + * and PIPE_POLYGON_MODE_POINT, + */ + unsigned mode[2]; +}; + + +static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage ) +{ + return (struct unfilled_stage *)stage; +} + + + +static void point( struct draw_stage *stage, + struct vertex_header *v0 ) +{ + struct prim_header tmp; + tmp.v[0] = v0; + stage->next->point( stage->next, &tmp ); +} + +static void line( struct draw_stage *stage, + struct vertex_header *v0, + struct vertex_header *v1 ) +{ + struct prim_header tmp; + tmp.v[0] = v0; + tmp.v[1] = v1; + stage->next->line( stage->next, &tmp ); +} + + +static void points( struct draw_stage *stage, + struct prim_header *header ) +{ + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + struct vertex_header *v2 = header->v[2]; + + if (header->edgeflags & 0x1) point( stage, v0 ); + if (header->edgeflags & 0x2) point( stage, v1 ); + if (header->edgeflags & 0x4) point( stage, v2 ); +} + + +static void lines( struct draw_stage *stage, + struct prim_header *header ) +{ + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + struct vertex_header *v2 = header->v[2]; + +#if 0 + assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag); + assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag); + assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag); +#endif + + if (header->edgeflags & 0x1) line( stage, v0, v1 ); + if (header->edgeflags & 0x2) line( stage, v1, v2 ); + if (header->edgeflags & 0x4) line( stage, v2, v0 ); +} + + +/* Unfilled tri: + * + * Note edgeflags in the vertex struct is not sufficient as we will + * need to manipulate them when decomposing primitives??? + */ +static void unfilled_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct unfilled_stage *unfilled = unfilled_stage(stage); + unsigned mode = unfilled->mode[header->det >= 0.0]; + + switch (mode) { + case PIPE_POLYGON_MODE_FILL: + stage->next->tri( stage->next, header ); + break; + case PIPE_POLYGON_MODE_LINE: + lines( stage, header ); + break; + case PIPE_POLYGON_MODE_POINT: + points( stage, header ); + break; + default: + abort(); + } +} + + +static void unfilled_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct unfilled_stage *unfilled = unfilled_stage(stage); + + unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */ + unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */ + + stage->tri = unfilled_tri; + stage->tri( stage, header ); +} + + +static void unfilled_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void unfilled_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void unfilled_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->next->flush( stage->next, flags ); + + stage->tri = unfilled_first_tri; +} + + +static void unfilled_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void unfilled_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create unfilled triangle stage. + */ +struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) +{ + struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage); + + draw_alloc_temp_verts( &unfilled->stage, 0 ); + + unfilled->stage.draw = draw; + unfilled->stage.next = NULL; + unfilled->stage.tmp = NULL; + unfilled->stage.point = unfilled_point; + unfilled->stage.line = unfilled_line; + unfilled->stage.tri = unfilled_first_tri; + unfilled->stage.flush = unfilled_flush; + unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter; + unfilled->stage.destroy = unfilled_destroy; + + return &unfilled->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c new file mode 100644 index 0000000000..4375ebabbc --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -0,0 +1,185 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + + + + + +/** + * Rebuild the rendering pipeline. + */ +static struct draw_stage *validate_pipeline( struct draw_stage *stage ) +{ + struct draw_context *draw = stage->draw; + struct draw_stage *next = draw->pipeline.rasterize; + int need_det = 0; + int precalc_flat = 0; + + /* Set the validate's next stage to the rasterize stage, so that it + * can be found later if needed for flushing. + */ + stage->next = next; + + /* + * NOTE: we build up the pipeline in end-to-start order. + * + * TODO: make the current primitive part of the state and build + * shorter pipelines for lines & points. + */ + + if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines) || + (draw->rasterizer->point_size != 1.0 && draw->convert_wide_points) || + draw->rasterizer->point_sprite) { + draw->pipeline.wide->next = next; + next = draw->pipeline.wide; + } + + if (draw->rasterizer->line_stipple_enable) { + draw->pipeline.stipple->next = next; + next = draw->pipeline.stipple; + precalc_flat = 1; /* only needed for lines really */ + } + + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { + draw->pipeline.unfilled->next = next; + next = draw->pipeline.unfilled; + precalc_flat = 1; /* only needed for triangles really */ + need_det = 1; + } + + if (draw->rasterizer->flatshade && precalc_flat) { + draw->pipeline.flatshade->next = next; + next = draw->pipeline.flatshade; + } + + if (draw->rasterizer->offset_cw || + draw->rasterizer->offset_ccw) { + draw->pipeline.offset->next = next; + next = draw->pipeline.offset; + need_det = 1; + } + + if (draw->rasterizer->light_twoside) { + draw->pipeline.twoside->next = next; + next = draw->pipeline.twoside; + need_det = 1; + } + + /* Always run the cull stage as we calculate determinant there + * also. + * + * This can actually be a win as culling out the triangles can lead + * to less work emitting vertices, smaller vertex buffers, etc. + * It's difficult to say whether this will be true in general. + */ + if (need_det || draw->rasterizer->cull_mode) { + draw->pipeline.cull->next = next; + next = draw->pipeline.cull; + } + + /* Clip stage + */ + if (!draw->rasterizer->bypass_clipping) + { + draw->pipeline.clip->next = next; + next = draw->pipeline.clip; + } + + + draw->pipeline.first = next; + return next; +} + +static void validate_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->tri( pipeline, header ); +} + +static void validate_line( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->line( pipeline, header ); +} + +static void validate_point( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->point( pipeline, header ); +} + +static void validate_reset_stipple_counter( struct draw_stage *stage ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->reset_stipple_counter( pipeline ); +} + +static void validate_flush( struct draw_stage *stage, + unsigned flags ) +{ + /* May need to pass a backend flush on to the rasterize stage. + */ + if (stage->next) + stage->next->flush( stage->next, flags ); +} + + +static void validate_destroy( struct draw_stage *stage ) +{ + FREE( stage ); +} + + +/** + * Create validate pipeline stage. + */ +struct draw_stage *draw_validate_stage( struct draw_context *draw ) +{ + struct draw_stage *stage = CALLOC_STRUCT(draw_stage); + + stage->draw = draw; + stage->next = NULL; + stage->point = validate_point; + stage->line = validate_line; + stage->tri = validate_tri; + stage->flush = validate_flush; + stage->reset_stipple_counter = validate_reset_stipple_counter; + stage->destroy = validate_destroy; + + return stage; +} diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c new file mode 100644 index 0000000000..71ac73912b --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vbuf.c @@ -0,0 +1,570 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Vertex buffer drawing stage. + * + * \author José Fonseca + * \author Keith Whitwell + */ + + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" + +#include "draw_vbuf.h" +#include "draw_private.h" +#include "draw_vertex.h" +#include "draw_vf.h" + + +/** + * Vertex buffer emit stage. + */ +struct vbuf_stage { + struct draw_stage stage; /**< This must be first (base class) */ + + struct vbuf_render *render; + + const struct vertex_info *vinfo; + + /** Vertex size in bytes */ + unsigned vertex_size; + + struct draw_vertex_fetch *vf; + + /* FIXME: we have no guarantee that 'unsigned' is 32bit */ + + /** Vertices in hardware format */ + unsigned *vertices; + unsigned *vertex_ptr; + unsigned max_vertices; + unsigned nr_vertices; + + /** Indices */ + ushort *indices; + unsigned max_indices; + unsigned nr_indices; + + /** Pipe primitive */ + unsigned prim; +}; + + +/** + * Basically a cast wrapper. + */ +static INLINE struct vbuf_stage * +vbuf_stage( struct draw_stage *stage ) +{ + assert(stage); + return (struct vbuf_stage *)stage; +} + + +static void vbuf_flush_indices( struct vbuf_stage *vbuf ); +static void vbuf_flush_vertices( struct vbuf_stage *vbuf ); +static void vbuf_alloc_vertices( struct vbuf_stage *vbuf ); + + +static INLINE boolean +overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz ) +{ + unsigned long used = (unsigned long) ((char *)ptr - (char *)map); + return (used + bytes) > bufsz; +} + + +static INLINE void +check_space( struct vbuf_stage *vbuf, unsigned nr ) +{ + if (vbuf->nr_vertices + nr > vbuf->max_vertices ) { + vbuf_flush_vertices(vbuf); + vbuf_alloc_vertices(vbuf); + } + + if (vbuf->nr_indices + nr > vbuf->max_indices ) + vbuf_flush_indices(vbuf); +} + + +#if 0 +static INLINE void +dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) +{ + assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); + unsigned i, j, k; + + for (i = 0; i < vinfo->num_attribs; i++) { + j = vinfo->src_index[i]; + switch (vinfo->emit[i]) { + case EMIT_OMIT: + debug_printf("EMIT_OMIT:"); + break; + case EMIT_ALL: + assert(i == 0); + assert(j == 0); + debug_printf("EMIT_ALL:\t"); + for(k = 0; k < vinfo->size*4; ++k) + debug_printf("%02x ", *data++); + break; + case EMIT_1F: + debug_printf("EMIT_1F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_1F_PSIZE: + debug_printf("EMIT_1F_PSIZE:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_2F: + debug_printf("EMIT_2F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_3F: + debug_printf("EMIT_3F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + data += sizeof(float); + break; + case EMIT_4F: + debug_printf("EMIT_4F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_4UB: + debug_printf("EMIT_4UB:\t"); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + break; + default: + assert(0); + } + debug_printf("\n"); + } + debug_printf("\n"); +} +#endif + + +/** + * Extract the needed fields from post-transformed vertex and emit + * a hardware(driver) vertex. + * Recall that the vertices are constructed by the 'draw' module and + * have a couple of slots at the beginning (1-dword header, 4-dword + * clip pos) that we ignore here. We only use the vertex->data[] fields. + */ +static INLINE void +emit_vertex( struct vbuf_stage *vbuf, + struct vertex_header *vertex ) +{ +#if 0 + debug_printf("emit vertex %d to %p\n", + vbuf->nr_vertices, vbuf->vertex_ptr); +#endif + + if(vertex->vertex_id != UNDEFINED_VERTEX_ID) { + if(vertex->vertex_id < vbuf->nr_vertices) + return; + else + debug_printf("Bad vertex id 0x%04x (>= 0x%04x)\n", + vertex->vertex_id, vbuf->nr_vertices); + return; + } + + vertex->vertex_id = vbuf->nr_vertices++; + + if(!vbuf->vf) { + const struct vertex_info *vinfo = vbuf->vinfo; + uint i; + uint count = 0; /* for debug/sanity */ + + assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); + + for (i = 0; i < vinfo->num_attribs; i++) { + uint j = vinfo->src_index[i]; + switch (vinfo->emit[i]) { + case EMIT_OMIT: + /* no-op */ + break; + case EMIT_ALL: + /* just copy the whole vertex as-is to the vbuf */ + assert(i == 0); + assert(j == 0); + memcpy(vbuf->vertex_ptr, vertex, vinfo->size * 4); + vbuf->vertex_ptr += vinfo->size; + count += vinfo->size; + break; + case EMIT_1F: + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + count++; + break; + case EMIT_1F_PSIZE: + *vbuf->vertex_ptr++ = fui(vbuf->stage.draw->rasterizer->point_size); + count++; + break; + case EMIT_2F: + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); + count += 2; + break; + case EMIT_3F: + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); + count += 3; + break; + case EMIT_4F: + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][3]); + count += 4; + break; + case EMIT_4UB: + *vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[j][2] ), + float_to_ubyte( vertex->data[j][1] ), + float_to_ubyte( vertex->data[j][0] ), + float_to_ubyte( vertex->data[j][3] )); + count += 1; + break; + default: + assert(0); + } + } + assert(count == vinfo->size); +#if 0 + { + static float data[256]; + draw_vf_emit_vertex(vbuf->vf, vertex, data); + if(memcmp((uint8_t *)vbuf->vertex_ptr - vbuf->vertex_size, data, vbuf->vertex_size)) { + debug_printf("With VF:\n"); + dump_emitted_vertex(vbuf->vinfo, (uint8_t *)data); + debug_printf("Without VF:\n"); + dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr - vbuf->vertex_size); + assert(0); + } + } +#endif + } + else { + draw_vf_emit_vertex(vbuf->vf, vertex, vbuf->vertex_ptr); + + vbuf->vertex_ptr += vbuf->vertex_size/4; + } +} + + +static void +vbuf_tri( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + unsigned i; + + check_space( vbuf, 3 ); + + for (i = 0; i < 3; i++) { + emit_vertex( vbuf, prim->v[i] ); + + vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[i]->vertex_id; + } +} + + +static void +vbuf_line( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + unsigned i; + + check_space( vbuf, 2 ); + + for (i = 0; i < 2; i++) { + emit_vertex( vbuf, prim->v[i] ); + + vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[i]->vertex_id; + } +} + + +static void +vbuf_point( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + check_space( vbuf, 1 ); + + emit_vertex( vbuf, prim->v[0] ); + + vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[0]->vertex_id; +} + + +/** + * Set the prim type for subsequent vertices. + * This may result in a new vertex size. The existing vbuffer (if any) + * will be flushed if needed and a new one allocated. + */ +static void +vbuf_set_prim( struct vbuf_stage *vbuf, uint newprim ) +{ + const struct vertex_info *vinfo; + unsigned vertex_size; + + assert(newprim == PIPE_PRIM_POINTS || + newprim == PIPE_PRIM_LINES || + newprim == PIPE_PRIM_TRIANGLES); + + vbuf->prim = newprim; + vbuf->render->set_primitive(vbuf->render, newprim); + + vinfo = vbuf->render->get_vertex_info(vbuf->render); + vertex_size = vinfo->size * sizeof(float); + + if (vertex_size != vbuf->vertex_size) + vbuf_flush_vertices(vbuf); + + vbuf->vinfo = vinfo; + vbuf->vertex_size = vertex_size; + if(vbuf->vf) + draw_vf_set_vertex_info(vbuf->vf, + vbuf->vinfo, + vbuf->stage.draw->rasterizer->point_size); + + if (!vbuf->vertices) + vbuf_alloc_vertices(vbuf); +} + + +static void +vbuf_first_tri( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->tri = vbuf_tri; + vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES); + stage->tri( stage, prim ); +} + + +static void +vbuf_first_line( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->line = vbuf_line; + vbuf_set_prim(vbuf, PIPE_PRIM_LINES); + stage->line( stage, prim ); +} + + +static void +vbuf_first_point( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->point = vbuf_point; + vbuf_set_prim(vbuf, PIPE_PRIM_POINTS); + stage->point( stage, prim ); +} + + +static void +vbuf_flush_indices( struct vbuf_stage *vbuf ) +{ + if(!vbuf->nr_indices) + return; + + assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == + vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned)); + + switch(vbuf->prim) { + case PIPE_PRIM_POINTS: + break; + case PIPE_PRIM_LINES: + assert(vbuf->nr_indices % 2 == 0); + break; + case PIPE_PRIM_TRIANGLES: + assert(vbuf->nr_indices % 3 == 0); + break; + default: + assert(0); + } + + vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices); + + vbuf->nr_indices = 0; + + /* don't need to reset point/line/tri functions */ +#if 0 + stage->point = vbuf_first_point; + stage->line = vbuf_first_line; + stage->tri = vbuf_first_tri; +#endif +} + + +/** + * Flush existing vertex buffer and allocate a new one. + * + * XXX: We separate flush-on-index-full and flush-on-vb-full, but may + * raise issues uploading vertices if the hardware wants to flush when + * we flush. + */ +static void +vbuf_flush_vertices( struct vbuf_stage *vbuf ) +{ + if(vbuf->vertices) { + vbuf_flush_indices(vbuf); + + /* Reset temporary vertices ids */ + if(vbuf->nr_vertices) + draw_reset_vertex_ids( vbuf->stage.draw ); + + /* Free the vertex buffer */ + vbuf->render->release_vertices(vbuf->render, + vbuf->vertices, + vbuf->vertex_size, + vbuf->nr_vertices); + vbuf->max_vertices = vbuf->nr_vertices = 0; + vbuf->vertex_ptr = vbuf->vertices = NULL; + + } +} + + +static void +vbuf_alloc_vertices( struct vbuf_stage *vbuf ) +{ + assert(!vbuf->nr_indices); + assert(!vbuf->vertices); + + /* Allocate a new vertex buffer */ + vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; + vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, + (ushort) vbuf->vertex_size, + (ushort) vbuf->max_vertices); + vbuf->vertex_ptr = vbuf->vertices; +} + + + +static void +vbuf_flush( struct draw_stage *stage, unsigned flags ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + + stage->point = vbuf_first_point; + stage->line = vbuf_first_line; + stage->tri = vbuf_first_tri; + + if (flags & DRAW_FLUSH_BACKEND) + vbuf_flush_vertices( vbuf ); +} + + +static void +vbuf_reset_stipple_counter( struct draw_stage *stage ) +{ + /* XXX: Need to do something here for hardware with linestipple. + */ + (void) stage; +} + + +static void vbuf_destroy( struct draw_stage *stage ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + if(vbuf->indices) + align_free( vbuf->indices ); + + if(vbuf->vf) + draw_vf_destroy( vbuf->vf ); + + if (vbuf->render) + vbuf->render->destroy( vbuf->render ); + + FREE( stage ); +} + + +/** + * Create a new primitive vbuf/render stage. + */ +struct draw_stage *draw_vbuf_stage( struct draw_context *draw, + struct vbuf_render *render ) +{ + struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); + + if(!vbuf) + return NULL; + + vbuf->stage.draw = draw; + vbuf->stage.point = vbuf_first_point; + vbuf->stage.line = vbuf_first_line; + vbuf->stage.tri = vbuf_first_tri; + vbuf->stage.flush = vbuf_flush; + vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter; + vbuf->stage.destroy = vbuf_destroy; + + vbuf->render = render; + + assert(render->max_indices < UNDEFINED_VERTEX_ID); + vbuf->max_indices = render->max_indices; + vbuf->indices = (ushort *) + align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 ); + if(!vbuf->indices) + vbuf_destroy(&vbuf->stage); + + vbuf->vertices = NULL; + vbuf->vertex_ptr = vbuf->vertices; + + vbuf->prim = ~0; + + if(!GETENV("GALLIUM_NOVF")) + vbuf->vf = draw_vf_create(); + + return &vbuf->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_vbuf.h b/src/gallium/auxiliary/draw/draw_vbuf.h new file mode 100644 index 0000000000..cfd2b9820c --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vbuf.h @@ -0,0 +1,106 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Vertex buffer drawing stage. + * + * \author Keith Whitwell + * \author José Fonseca + */ + +#ifndef DRAW_VBUF_H_ +#define DRAW_VBUF_H_ + + +#include "pipe/p_util.h" + + +struct draw_context; +struct vertex_info; + + +/** + * Interface for hardware vertex buffer rendering. + */ +struct vbuf_render { + + /** + * Driver limits. May be tuned lower to improve cache hits on + * index list. + */ + unsigned max_indices; + unsigned max_vertex_buffer_bytes; + + /** + * Get the hardware vertex format. + * + * XXX: have this in draw_context instead? + */ + const struct vertex_info *(*get_vertex_info)( struct vbuf_render * ); + + /** + * Request a destination for vertices. + * Hardware renderers will use ttm memory, others will just malloc + * something. + */ + void *(*allocate_vertices)( struct vbuf_render *, + ushort vertex_size, + ushort nr_vertices ); + + /** + * Notify the renderer of the current primitive when it changes. + * Prim is restricted to TRIANGLES, LINES and POINTS. + */ + void (*set_primitive)( struct vbuf_render *, unsigned prim ); + + /** + * DrawElements, note indices are ushort: + */ + void (*draw)( struct vbuf_render *, + const ushort *indices, + uint nr_indices ); + + /** + * Called when vbuf is done with this set of vertices: + */ + void (*release_vertices)( struct vbuf_render *, + void *vertices, + unsigned vertex_size, + unsigned vertices_used ); + + void (*destroy)( struct vbuf_render * ); +}; + + + +struct draw_stage * +draw_vbuf_stage( struct draw_context *draw, + struct vbuf_render *render ); + + +#endif /*DRAW_VBUF_H_*/ diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c new file mode 100644 index 0000000000..daf1ef4b80 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vertex.c @@ -0,0 +1,79 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* + * Functions for specifying the post-transformation vertex layout. + * + * Author: + * Brian Paul + * Keith Whitwell + */ + + +#include "draw/draw_private.h" +#include "draw/draw_vertex.h" + + +/** + * Compute the size of a vertex, in dwords/floats, to update the + * vinfo->size field. + */ +void +draw_compute_vertex_size(struct vertex_info *vinfo) +{ + uint i; + + vinfo->size = 0; + for (i = 0; i < vinfo->num_attribs; i++) { + switch (vinfo->emit[i]) { + case EMIT_OMIT: + break; + case EMIT_4UB: + /* fall-through */ + case EMIT_1F_PSIZE: + /* fall-through */ + case EMIT_1F: + vinfo->size += 1; + break; + case EMIT_2F: + vinfo->size += 2; + break; + case EMIT_3F: + vinfo->size += 3; + break; + case EMIT_4F: + vinfo->size += 4; + break; + case EMIT_ALL: + /* fall-through */ + default: + assert(0); + } + } + + assert(vinfo->size * 4 <= MAX_VERTEX_SIZE); +} diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h new file mode 100644 index 0000000000..267c74203b --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Post-transform vertex format info. The vertex_info struct is used by + * the draw_vbuf code to emit hardware-specific vertex layouts into hw + * vertex buffers. + * + * Author: + * Brian Paul + */ + + +#ifndef DRAW_VERTEX_H +#define DRAW_VERTEX_H + + +#include "pipe/p_state.h" + + +/** + * Vertex attribute emit modes + */ +enum attrib_emit { + EMIT_OMIT, /**< don't emit the attribute */ + EMIT_ALL, /**< emit whole post-xform vertex, w/ header */ + EMIT_1F, + EMIT_1F_PSIZE, /**< insert constant point size */ + EMIT_2F, + EMIT_3F, + EMIT_4F, + EMIT_4UB /**< XXX may need variations for RGBA vs BGRA, etc */ +}; + + +/** + * Attribute interpolation mode + */ +enum interp_mode { + INTERP_NONE, /**< never interpolate vertex header info */ + INTERP_POS, /**< special case for frag position */ + INTERP_CONSTANT, + INTERP_LINEAR, + INTERP_PERSPECTIVE +}; + + +/** + * Information about hardware/rasterization vertex layout. + */ +struct vertex_info +{ + uint num_attribs; + uint hwfmt[4]; /**< hardware format info for this format */ + enum interp_mode interp_mode[PIPE_MAX_SHADER_INPUTS]; + enum attrib_emit emit[PIPE_MAX_SHADER_INPUTS]; /**< EMIT_x */ + uint src_index[PIPE_MAX_SHADER_INPUTS]; /**< map to post-xform attribs */ + uint size; /**< total vertex size in dwords */ +}; + + + +/** + * Add another attribute to the given vertex_info object. + * \param src_index indicates which post-transformed vertex attrib slot + * corresponds to this attribute. + * \return slot in which the attribute was added + */ +static INLINE uint +draw_emit_vertex_attr(struct vertex_info *vinfo, + enum attrib_emit emit, enum interp_mode interp, + uint src_index) +{ + const uint n = vinfo->num_attribs; + assert(n < PIPE_MAX_SHADER_INPUTS); + vinfo->emit[n] = emit; + vinfo->interp_mode[n] = interp; + vinfo->src_index[n] = src_index; + vinfo->num_attribs++; + return n; +} + + +extern void draw_compute_vertex_size(struct vertex_info *vinfo); + + +#endif /* DRAW_VERTEX_H */ diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c new file mode 100644 index 0000000000..44427999cc --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vertex_cache.c @@ -0,0 +1,196 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw_private.h" +#include "draw_context.h" + + +void draw_vertex_cache_invalidate( struct draw_context *draw ) +{ + assert(draw->pq.queue_nr == 0); + assert(draw->vs.queue_nr == 0); + assert(draw->vcache.referenced == 0); + + memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx)); +} + + +/** + * Check if vertex is in cache, otherwise add it. It won't go through + * VS yet, not until there is a flush operation or the VS queue fills up. + * + * Note that cache entries are basically just two pointers: the first + * an index into the user's vertex arrays, the second a location in + * the vertex shader cache for the post-transformed vertex. + * + * \return pointer to location of (post-transformed) vertex header in the cache + */ +static struct vertex_header *get_vertex( struct draw_context *draw, + unsigned i ) +{ + unsigned slot = (i + (i>>5)) % VCACHE_SIZE; + + assert(slot < 32); /* so we don't exceed the bitfield size below */ + + /* Cache miss? + */ + if (draw->vcache.idx[slot] != i) { + + /* If slot is in use, use the overflow area: + */ + if (draw->vcache.referenced & (1 << slot)) { + slot = VCACHE_SIZE + draw->vcache.overflow++; + } + + assert(slot < Elements(draw->vcache.idx)); + + draw->vcache.idx[slot] = i; + + /* Add to vertex shader queue: + */ + assert(draw->vs.queue_nr < VS_QUEUE_LENGTH); + draw->vs.queue[draw->vs.queue_nr].dest = draw->vcache.vertex[slot]; + draw->vs.queue[draw->vs.queue_nr].elt = i; + draw->vs.queue_nr++; + + /* Need to set the vertex's edge flag here. If we're being called + * by do_ef_triangle(), that function needs edge flag info! + */ + draw->vcache.vertex[slot]->clipmask = 0; + draw->vcache.vertex[slot]->edgeflag = 1; /*XXX use user's edge flag! */ + draw->vcache.vertex[slot]->pad = 0; + draw->vcache.vertex[slot]->vertex_id = UNDEFINED_VERTEX_ID; + } + + + /* primitive flushing may have cleared the bitfield but did not + * clear the idx[] array values. Set the bit now. This fixes a + * bug found when drawing long triangle fans. + */ + draw->vcache.referenced |= (1 << slot); + return draw->vcache.vertex[slot]; +} + + +static struct vertex_header *get_uint_elt_vertex( struct draw_context *draw, + unsigned i ) +{ + const unsigned *elts = (const unsigned *) draw->user.elts; + return get_vertex( draw, elts[i] ); +} + + +static struct vertex_header *get_ushort_elt_vertex( struct draw_context *draw, + unsigned i ) +{ + const ushort *elts = (const ushort *) draw->user.elts; + return get_vertex( draw, elts[i] ); +} + + +static struct vertex_header *get_ubyte_elt_vertex( struct draw_context *draw, + unsigned i ) +{ + const ubyte *elts = (const ubyte *) draw->user.elts; + return get_vertex( draw, elts[i] ); +} + + +void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ) +{ + unsigned i; + + for (i = 0; i < Elements(draw->vcache.vertex); i++) + draw->vcache.vertex[i]->vertex_id = UNDEFINED_VERTEX_ID; +} + + +void draw_vertex_cache_unreference( struct draw_context *draw ) +{ + draw->vcache.referenced = 0; + draw->vcache.overflow = 0; +} + + +int draw_vertex_cache_check_space( struct draw_context *draw, + unsigned nr_verts ) +{ + if (draw->vcache.overflow + nr_verts < VCACHE_OVERFLOW) { + /* The vs queue is sized so that this can never happen: + */ + assert(draw->vs.queue_nr + nr_verts < VS_QUEUE_LENGTH); + return TRUE; + } + else + return FALSE; +} + + + +/** + * Tell the drawing context about the index/element buffer to use + * (ala glDrawElements) + * If no element buffer is to be used (i.e. glDrawArrays) then this + * should be called with eltSize=0 and elements=NULL. + * + * \param draw the drawing context + * \param eltSize size of each element (1, 2 or 4 bytes) + * \param elements the element buffer ptr + */ +void +draw_set_mapped_element_buffer( struct draw_context *draw, + unsigned eltSize, void *elements ) +{ +// draw_statechange( draw ); + + /* choose the get_vertex() function to use */ + switch (eltSize) { + case 0: + draw->vcache.get_vertex = get_vertex; + break; + case 1: + draw->vcache.get_vertex = get_ubyte_elt_vertex; + break; + case 2: + draw->vcache.get_vertex = get_ushort_elt_vertex; + break; + case 4: + draw->vcache.get_vertex = get_uint_elt_vertex; + break; + default: + assert(0); + } + draw->user.elts = elements; + draw->user.eltSize = eltSize; +} + diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c new file mode 100644 index 0000000000..e13df04605 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c @@ -0,0 +1,510 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" +#include "draw_context.h" + + +#define DRAW_DBG 0 + + +/** + * Fetch a float[4] vertex attribute from memory, doing format/type + * conversion as needed. + * + * This is probably needed/dupliocated elsewhere, eg format + * conversion, texture sampling etc. + */ +#define FETCH_ATTRIB( NAME, SZ, CVT ) \ +static void \ +fetch_##NAME(const void *ptr, float *attrib) \ +{ \ + static const float defaults[4] = { 0,0,0,1 }; \ + int i; \ + \ + for (i = 0; i < SZ; i++) { \ + attrib[i] = CVT; \ + } \ + \ + for (; i < 4; i++) { \ + attrib[i] = defaults[i]; \ + } \ +} + +#define CVT_64_FLOAT (float) ((double *) ptr)[i] +#define CVT_32_FLOAT ((float *) ptr)[i] + +#define CVT_8_USCALED (float) ((unsigned char *) ptr)[i] +#define CVT_16_USCALED (float) ((unsigned short *) ptr)[i] +#define CVT_32_USCALED (float) ((unsigned int *) ptr)[i] + +#define CVT_8_SSCALED (float) ((char *) ptr)[i] +#define CVT_16_SSCALED (float) ((short *) ptr)[i] +#define CVT_32_SSCALED (float) ((int *) ptr)[i] + +#define CVT_8_UNORM (float) ((unsigned char *) ptr)[i] / 255.0f +#define CVT_16_UNORM (float) ((unsigned short *) ptr)[i] / 65535.0f +#define CVT_32_UNORM (float) ((unsigned int *) ptr)[i] / 4294967295.0f + +#define CVT_8_SNORM (float) ((char *) ptr)[i] / 127.0f +#define CVT_16_SNORM (float) ((short *) ptr)[i] / 32767.0f +#define CVT_32_SNORM (float) ((int *) ptr)[i] / 2147483647.0f + +FETCH_ATTRIB( R64G64B64A64_FLOAT, 4, CVT_64_FLOAT ) +FETCH_ATTRIB( R64G64B64_FLOAT, 3, CVT_64_FLOAT ) +FETCH_ATTRIB( R64G64_FLOAT, 2, CVT_64_FLOAT ) +FETCH_ATTRIB( R64_FLOAT, 1, CVT_64_FLOAT ) + +FETCH_ATTRIB( R32G32B32A32_FLOAT, 4, CVT_32_FLOAT ) +FETCH_ATTRIB( R32G32B32_FLOAT, 3, CVT_32_FLOAT ) +FETCH_ATTRIB( R32G32_FLOAT, 2, CVT_32_FLOAT ) +FETCH_ATTRIB( R32_FLOAT, 1, CVT_32_FLOAT ) + +FETCH_ATTRIB( R32G32B32A32_USCALED, 4, CVT_32_USCALED ) +FETCH_ATTRIB( R32G32B32_USCALED, 3, CVT_32_USCALED ) +FETCH_ATTRIB( R32G32_USCALED, 2, CVT_32_USCALED ) +FETCH_ATTRIB( R32_USCALED, 1, CVT_32_USCALED ) + +FETCH_ATTRIB( R32G32B32A32_SSCALED, 4, CVT_32_SSCALED ) +FETCH_ATTRIB( R32G32B32_SSCALED, 3, CVT_32_SSCALED ) +FETCH_ATTRIB( R32G32_SSCALED, 2, CVT_32_SSCALED ) +FETCH_ATTRIB( R32_SSCALED, 1, CVT_32_SSCALED ) + +FETCH_ATTRIB( R32G32B32A32_UNORM, 4, CVT_32_UNORM ) +FETCH_ATTRIB( R32G32B32_UNORM, 3, CVT_32_UNORM ) +FETCH_ATTRIB( R32G32_UNORM, 2, CVT_32_UNORM ) +FETCH_ATTRIB( R32_UNORM, 1, CVT_32_UNORM ) + +FETCH_ATTRIB( R32G32B32A32_SNORM, 4, CVT_32_SNORM ) +FETCH_ATTRIB( R32G32B32_SNORM, 3, CVT_32_SNORM ) +FETCH_ATTRIB( R32G32_SNORM, 2, CVT_32_SNORM ) +FETCH_ATTRIB( R32_SNORM, 1, CVT_32_SNORM ) + +FETCH_ATTRIB( R16G16B16A16_USCALED, 4, CVT_16_USCALED ) +FETCH_ATTRIB( R16G16B16_USCALED, 3, CVT_16_USCALED ) +FETCH_ATTRIB( R16G16_USCALED, 2, CVT_16_USCALED ) +FETCH_ATTRIB( R16_USCALED, 1, CVT_16_USCALED ) + +FETCH_ATTRIB( R16G16B16A16_SSCALED, 4, CVT_16_SSCALED ) +FETCH_ATTRIB( R16G16B16_SSCALED, 3, CVT_16_SSCALED ) +FETCH_ATTRIB( R16G16_SSCALED, 2, CVT_16_SSCALED ) +FETCH_ATTRIB( R16_SSCALED, 1, CVT_16_SSCALED ) + +FETCH_ATTRIB( R16G16B16A16_UNORM, 4, CVT_16_UNORM ) +FETCH_ATTRIB( R16G16B16_UNORM, 3, CVT_16_UNORM ) +FETCH_ATTRIB( R16G16_UNORM, 2, CVT_16_UNORM ) +FETCH_ATTRIB( R16_UNORM, 1, CVT_16_UNORM ) + +FETCH_ATTRIB( R16G16B16A16_SNORM, 4, CVT_16_SNORM ) +FETCH_ATTRIB( R16G16B16_SNORM, 3, CVT_16_SNORM ) +FETCH_ATTRIB( R16G16_SNORM, 2, CVT_16_SNORM ) +FETCH_ATTRIB( R16_SNORM, 1, CVT_16_SNORM ) + +FETCH_ATTRIB( R8G8B8A8_USCALED, 4, CVT_8_USCALED ) +FETCH_ATTRIB( R8G8B8_USCALED, 3, CVT_8_USCALED ) +FETCH_ATTRIB( R8G8_USCALED, 2, CVT_8_USCALED ) +FETCH_ATTRIB( R8_USCALED, 1, CVT_8_USCALED ) + +FETCH_ATTRIB( R8G8B8A8_SSCALED, 4, CVT_8_SSCALED ) +FETCH_ATTRIB( R8G8B8_SSCALED, 3, CVT_8_SSCALED ) +FETCH_ATTRIB( R8G8_SSCALED, 2, CVT_8_SSCALED ) +FETCH_ATTRIB( R8_SSCALED, 1, CVT_8_SSCALED ) + +FETCH_ATTRIB( R8G8B8A8_UNORM, 4, CVT_8_UNORM ) +FETCH_ATTRIB( R8G8B8_UNORM, 3, CVT_8_UNORM ) +FETCH_ATTRIB( R8G8_UNORM, 2, CVT_8_UNORM ) +FETCH_ATTRIB( R8_UNORM, 1, CVT_8_UNORM ) + +FETCH_ATTRIB( R8G8B8A8_SNORM, 4, CVT_8_SNORM ) +FETCH_ATTRIB( R8G8B8_SNORM, 3, CVT_8_SNORM ) +FETCH_ATTRIB( R8G8_SNORM, 2, CVT_8_SNORM ) +FETCH_ATTRIB( R8_SNORM, 1, CVT_8_SNORM ) + +FETCH_ATTRIB( A8R8G8B8_UNORM, 4, CVT_8_UNORM ) +//FETCH_ATTRIB( R8G8B8A8_UNORM, 4, CVT_8_UNORM ) + + + +static fetch_func get_fetch_func( enum pipe_format format ) +{ +#if 0 + { + char tmp[80]; + pf_sprint_name(tmp, format); + debug_printf("%s: %s\n", __FUNCTION__, tmp); + } +#endif + + switch (format) { + case PIPE_FORMAT_R64_FLOAT: + return fetch_R64_FLOAT; + case PIPE_FORMAT_R64G64_FLOAT: + return fetch_R64G64_FLOAT; + case PIPE_FORMAT_R64G64B64_FLOAT: + return fetch_R64G64B64_FLOAT; + case PIPE_FORMAT_R64G64B64A64_FLOAT: + return fetch_R64G64B64A64_FLOAT; + + case PIPE_FORMAT_R32_FLOAT: + return fetch_R32_FLOAT; + case PIPE_FORMAT_R32G32_FLOAT: + return fetch_R32G32_FLOAT; + case PIPE_FORMAT_R32G32B32_FLOAT: + return fetch_R32G32B32_FLOAT; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return fetch_R32G32B32A32_FLOAT; + + case PIPE_FORMAT_R32_UNORM: + return fetch_R32_UNORM; + case PIPE_FORMAT_R32G32_UNORM: + return fetch_R32G32_UNORM; + case PIPE_FORMAT_R32G32B32_UNORM: + return fetch_R32G32B32_UNORM; + case PIPE_FORMAT_R32G32B32A32_UNORM: + return fetch_R32G32B32A32_UNORM; + + case PIPE_FORMAT_R32_USCALED: + return fetch_R32_USCALED; + case PIPE_FORMAT_R32G32_USCALED: + return fetch_R32G32_USCALED; + case PIPE_FORMAT_R32G32B32_USCALED: + return fetch_R32G32B32_USCALED; + case PIPE_FORMAT_R32G32B32A32_USCALED: + return fetch_R32G32B32A32_USCALED; + + case PIPE_FORMAT_R32_SNORM: + return fetch_R32_SNORM; + case PIPE_FORMAT_R32G32_SNORM: + return fetch_R32G32_SNORM; + case PIPE_FORMAT_R32G32B32_SNORM: + return fetch_R32G32B32_SNORM; + case PIPE_FORMAT_R32G32B32A32_SNORM: + return fetch_R32G32B32A32_SNORM; + + case PIPE_FORMAT_R32_SSCALED: + return fetch_R32_SSCALED; + case PIPE_FORMAT_R32G32_SSCALED: + return fetch_R32G32_SSCALED; + case PIPE_FORMAT_R32G32B32_SSCALED: + return fetch_R32G32B32_SSCALED; + case PIPE_FORMAT_R32G32B32A32_SSCALED: + return fetch_R32G32B32A32_SSCALED; + + case PIPE_FORMAT_R16_UNORM: + return fetch_R16_UNORM; + case PIPE_FORMAT_R16G16_UNORM: + return fetch_R16G16_UNORM; + case PIPE_FORMAT_R16G16B16_UNORM: + return fetch_R16G16B16_UNORM; + case PIPE_FORMAT_R16G16B16A16_UNORM: + return fetch_R16G16B16A16_UNORM; + + case PIPE_FORMAT_R16_USCALED: + return fetch_R16_USCALED; + case PIPE_FORMAT_R16G16_USCALED: + return fetch_R16G16_USCALED; + case PIPE_FORMAT_R16G16B16_USCALED: + return fetch_R16G16B16_USCALED; + case PIPE_FORMAT_R16G16B16A16_USCALED: + return fetch_R16G16B16A16_USCALED; + + case PIPE_FORMAT_R16_SNORM: + return fetch_R16_SNORM; + case PIPE_FORMAT_R16G16_SNORM: + return fetch_R16G16_SNORM; + case PIPE_FORMAT_R16G16B16_SNORM: + return fetch_R16G16B16_SNORM; + case PIPE_FORMAT_R16G16B16A16_SNORM: + return fetch_R16G16B16A16_SNORM; + + case PIPE_FORMAT_R16_SSCALED: + return fetch_R16_SSCALED; + case PIPE_FORMAT_R16G16_SSCALED: + return fetch_R16G16_SSCALED; + case PIPE_FORMAT_R16G16B16_SSCALED: + return fetch_R16G16B16_SSCALED; + case PIPE_FORMAT_R16G16B16A16_SSCALED: + return fetch_R16G16B16A16_SSCALED; + + case PIPE_FORMAT_R8_UNORM: + return fetch_R8_UNORM; + case PIPE_FORMAT_R8G8_UNORM: + return fetch_R8G8_UNORM; + case PIPE_FORMAT_R8G8B8_UNORM: + return fetch_R8G8B8_UNORM; + case PIPE_FORMAT_R8G8B8A8_UNORM: + return fetch_R8G8B8A8_UNORM; + + case PIPE_FORMAT_R8_USCALED: + return fetch_R8_USCALED; + case PIPE_FORMAT_R8G8_USCALED: + return fetch_R8G8_USCALED; + case PIPE_FORMAT_R8G8B8_USCALED: + return fetch_R8G8B8_USCALED; + case PIPE_FORMAT_R8G8B8A8_USCALED: + return fetch_R8G8B8A8_USCALED; + + case PIPE_FORMAT_R8_SNORM: + return fetch_R8_SNORM; + case PIPE_FORMAT_R8G8_SNORM: + return fetch_R8G8_SNORM; + case PIPE_FORMAT_R8G8B8_SNORM: + return fetch_R8G8B8_SNORM; + case PIPE_FORMAT_R8G8B8A8_SNORM: + return fetch_R8G8B8A8_SNORM; + + case PIPE_FORMAT_R8_SSCALED: + return fetch_R8_SSCALED; + case PIPE_FORMAT_R8G8_SSCALED: + return fetch_R8G8_SSCALED; + case PIPE_FORMAT_R8G8B8_SSCALED: + return fetch_R8G8B8_SSCALED; + case PIPE_FORMAT_R8G8B8A8_SSCALED: + return fetch_R8G8B8A8_SSCALED; + + case PIPE_FORMAT_A8R8G8B8_UNORM: + return fetch_A8R8G8B8_UNORM; + + case 0: + return NULL; /* not sure why this is needed */ + + default: + assert(0); + return NULL; + } +} + + +static void +transpose_4x4( float *out, const float *in ) +{ + /* This can be achieved in 12 sse instructions, plus the final + * stores I guess. This is probably a bit more than that - maybe + * 32 or so? + */ + out[0] = in[0]; out[1] = in[4]; out[2] = in[8]; out[3] = in[12]; + out[4] = in[1]; out[5] = in[5]; out[6] = in[9]; out[7] = in[13]; + out[8] = in[2]; out[9] = in[6]; out[10] = in[10]; out[11] = in[14]; + out[12] = in[3]; out[13] = in[7]; out[14] = in[11]; out[15] = in[15]; +} + + + +static void fetch_xyz_rgb( struct draw_context *draw, + struct tgsi_exec_machine *machine, + const unsigned *elts, + unsigned count ) +{ + const unsigned *pitch = draw->vertex_fetch.pitch; + const ubyte **src = draw->vertex_fetch.src_ptr; + int i; + + assert(count <= 4); + +// debug_printf("%s\n", __FUNCTION__); + + /* loop over vertex attributes (vertex shader inputs) + */ + + for (i = 0; i < 4; i++) { + { + const float *in = (const float *)(src[0] + elts[i] * pitch[0]); + float *out = &machine->Inputs[0].xyzw[0].f[i]; + out[0] = in[0]; + out[4] = in[1]; + out[8] = in[2]; + out[12] = 1.0f; + } + + { + const float *in = (const float *)(src[1] + elts[i] * pitch[1]); + float *out = &machine->Inputs[1].xyzw[0].f[i]; + out[0] = in[0]; + out[4] = in[1]; + out[8] = in[2]; + out[12] = 1.0f; + } + } +} + + + + +static void fetch_xyz_rgb_st( struct draw_context *draw, + struct tgsi_exec_machine *machine, + const unsigned *elts, + unsigned count ) +{ + const unsigned *pitch = draw->vertex_fetch.pitch; + const ubyte **src = draw->vertex_fetch.src_ptr; + int i; + + assert(count <= 4); + + /* loop over vertex attributes (vertex shader inputs) + */ + + for (i = 0; i < 4; i++) { + { + const float *in = (const float *)(src[0] + elts[i] * pitch[0]); + float *out = &machine->Inputs[0].xyzw[0].f[i]; + out[0] = in[0]; + out[4] = in[1]; + out[8] = in[2]; + out[12] = 1.0f; + } + + { + const float *in = (const float *)(src[1] + elts[i] * pitch[1]); + float *out = &machine->Inputs[1].xyzw[0].f[i]; + out[0] = in[0]; + out[4] = in[1]; + out[8] = in[2]; + out[12] = 1.0f; + } + + { + const float *in = (const float *)(src[2] + elts[i] * pitch[2]); + float *out = &machine->Inputs[2].xyzw[0].f[i]; + out[0] = in[0]; + out[4] = in[1]; + out[8] = 0.0f; + out[12] = 1.0f; + } + } +} + + + + +/** + * Fetch vertex attributes for 'count' vertices. + */ +static void generic_vertex_fetch( struct draw_context *draw, + struct tgsi_exec_machine *machine, + const unsigned *elts, + unsigned count ) +{ + unsigned nr_attrs = draw->vertex_fetch.nr_attrs; + unsigned attr; + + assert(count <= 4); + +// debug_printf("%s %d\n", __FUNCTION__, count); + + /* loop over vertex attributes (vertex shader inputs) + */ + for (attr = 0; attr < nr_attrs; attr++) { + + const unsigned pitch = draw->vertex_fetch.pitch[attr]; + const ubyte *src = draw->vertex_fetch.src_ptr[attr]; + const fetch_func fetch = draw->vertex_fetch.fetch[attr]; + unsigned i; + float p[4][4]; + + + /* Fetch four attributes for four vertices. + * + * Could fetch directly into AOS format, but this is meant to be + * a prototype for an sse implementation, which would have + * difficulties doing that. + */ + for (i = 0; i < count; i++) + fetch( src + elts[i] * pitch, p[i] ); + + /* Be nice and zero out any missing vertices: + */ + for ( ; i < 4; i++) + p[i][0] = p[i][1] = p[i][2] = p[i][3] = 0; + + /* Transpose/swizzle into sse-friendly format. Currently + * assuming that all vertex shader inputs are float[4], but this + * isn't true -- if the vertex shader only wants tex0.xy, we + * could optimize for that. + * + * To do so fully without codegen would probably require an + * excessive number of fetch functions, but we could at least + * minimize the transpose step: + */ + transpose_4x4( (float *)&machine->Inputs[attr].xyzw[0].f[0], (float *)p ); + } +} + + + +void draw_update_vertex_fetch( struct draw_context *draw ) +{ + unsigned nr_attrs, i; + +// debug_printf("%s\n", __FUNCTION__); + + /* this may happend during context init */ + if (!draw->vertex_shader) + return; + + nr_attrs = draw->vertex_shader->state->num_inputs; + + for (i = 0; i < nr_attrs; i++) { + unsigned buf = draw->vertex_element[i].vertex_buffer_index; + enum pipe_format format = draw->vertex_element[i].src_format; + + draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] + + draw->vertex_buffer[buf].buffer_offset + + draw->vertex_element[i].src_offset; + + draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch; + draw->vertex_fetch.fetch[i] = get_fetch_func( format ); + } + + draw->vertex_fetch.nr_attrs = nr_attrs; + + draw->vertex_fetch.fetch_func = generic_vertex_fetch; + + switch (nr_attrs) { + case 2: + if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT && + draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT) + draw->vertex_fetch.fetch_func = fetch_xyz_rgb; + break; + case 3: + if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT && + draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT && + draw->vertex_element[2].src_format == PIPE_FORMAT_R32G32_FLOAT) + draw->vertex_fetch.fetch_func = fetch_xyz_rgb_st; + break; + default: + break; + } + +} diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c new file mode 100644 index 0000000000..377ecbb931 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -0,0 +1,325 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + * Brian Paul + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#if defined(__i386__) || defined(__386__) +#include "tgsi/exec/tgsi_sse2.h" +#endif +#include "draw_private.h" +#include "draw_context.h" + +#include "x86/rtasm/x86sse.h" +#include "llvm/gallivm.h" + + +#define DBG_VS 0 + + +static INLINE unsigned +compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) +{ + unsigned mask = 0; + unsigned i; + + /* Do the hardwired planes first: + */ + if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; + if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; + if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; + if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; + if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; + if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; + + /* Followed by any remaining ones: + */ + for (i = 6; i < nr; i++) { + if (dot4(clip, plane[i]) < 0) + mask |= (1<machine; + unsigned int j; + + ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); + ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); + const float *scale = draw->viewport.scale; + const float *trans = draw->viewport.translate; + + assert(count <= 4); + assert(draw->vertex_shader->state->output_semantic_name[0] + == TGSI_SEMANTIC_POSITION); + + /* Consts does not require 16 byte alignment. */ + machine->Consts = (float (*)[4]) draw->user.constants; + + machine->Inputs = ALIGN16_ASSIGN(inputs); + machine->Outputs = ALIGN16_ASSIGN(outputs); + + draw->vertex_fetch.fetch_func( draw, machine, elts, count ); + + /* run shader */ +#ifdef MESA_LLVM + if (1) { + struct gallivm_prog *prog = draw->vertex_shader->llvm_prog; + gallivm_cpu_vs_exec(prog, + machine->Inputs, + machine->Outputs, + machine->Consts, + machine->Temps); + } else +#elif defined(__i386__) || defined(__386__) + if (draw->use_sse) { + /* SSE */ + /* cast away const */ + struct draw_vertex_shader *shader + = (struct draw_vertex_shader *)draw->vertex_shader; + codegen_function func + = (codegen_function) x86_get_func( &shader->sse2_program ); + + if (func) + func( + machine->Inputs, + machine->Outputs, + machine->Consts, + machine->Temps ); + else + /* interpreter */ + tgsi_exec_machine_run( machine ); + } + else +#endif + { + /* interpreter */ + tgsi_exec_machine_run( machine ); + } + + /* store machine results */ + for (j = 0; j < count; j++) { + unsigned slot; + float x, y, z, w; + + /* Handle attr[0] (position) specially: + * + * XXX: Computing the clipmask should be done in the vertex + * program as a set of DP4 instructions appended to the + * user-provided code. + */ + x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + + vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + vOut[j]->edgeflag = 1; + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; + + /* Viewport mapping */ + vOut[j]->data[0][0] = x * scale[0] + trans[0]; + vOut[j]->data[0][1] = y * scale[1] + trans[1]; + vOut[j]->data[0][2] = z * scale[2] + trans[2]; + vOut[j]->data[0][3] = w; + +#if DBG_VS + debug_printf("output[%d]win: %f %f %f %f\n", j, + vOut[j]->data[0][0], + vOut[j]->data[0][1], + vOut[j]->data[0][2], + vOut[j]->data[0][3]); +#endif + /* Remaining attributes are packed into sequential post-transform + * vertex attrib slots. + */ + for (slot = 1; slot < draw->num_vs_outputs; slot++) { + vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; +#if DBG_VS + debug_printf("output[%d][%d]: %f %f %f %f\n", j, slot, + vOut[j]->data[slot][0], + vOut[j]->data[slot][1], + vOut[j]->data[slot][2], + vOut[j]->data[slot][3]); +#endif + } + } /* loop over vertices */ +} + + +/** + * Run the vertex shader on all vertices in the vertex queue. + * Called by the draw module when the vertx cache needs to be flushed. + */ +void +draw_vertex_shader_queue_flush(struct draw_context *draw) +{ + unsigned i; + + assert(draw->vs.queue_nr != 0); + + /* XXX: do this on statechange: + */ + draw_update_vertex_fetch( draw ); + +// fprintf(stderr, " q(%d) ", draw->vs.queue_nr ); + + /* run vertex shader on vertex cache entries, four per invokation */ + for (i = 0; i < draw->vs.queue_nr; i += 4) { + struct vertex_header *dests[4]; + unsigned elts[4]; + int j, n = MIN2(4, draw->vs.queue_nr - i); + + for (j = 0; j < n; j++) { + elts[j] = draw->vs.queue[i + j].elt; + dests[j] = draw->vs.queue[i + j].dest; + } + + for ( ; j < 4; j++) { + elts[j] = elts[0]; + dests[j] = dests[0]; + } + + assert(n > 0); + assert(n <= 4); + + run_vertex_program(draw, elts, n, dests); + } + + draw->vs.queue_nr = 0; +} + + +struct draw_vertex_shader * +draw_create_vertex_shader(struct draw_context *draw, + const struct pipe_shader_state *shader) +{ + struct draw_vertex_shader *vs; + + vs = CALLOC_STRUCT( draw_vertex_shader ); + if (vs == NULL) { + return NULL; + } + + vs->state = shader; + +#ifdef MESA_LLVM + struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); + gallivm_ir_set_layout(ir, GALLIVM_SOA); + gallivm_ir_set_components(ir, 4); + gallivm_ir_fill_from_tgsi(ir, shader->tokens); + vs->llvm_prog = gallivm_ir_compile(ir); + gallivm_ir_delete(ir); + + draw->engine = gallivm_global_cpu_engine(); + if (!draw->engine) { + draw->engine = gallivm_cpu_engine_create(vs->llvm_prog); + } + else { + gallivm_cpu_jit_compile(draw->engine, vs->llvm_prog); + } +#elif defined(__i386__) || defined(__386__) + if (draw->use_sse) { + /* cast-away const */ + struct pipe_shader_state *sh = (struct pipe_shader_state *) shader; + + x86_init_func( &vs->sse2_program ); + if (!tgsi_emit_sse2( (struct tgsi_token *) sh->tokens, + &vs->sse2_program )) { + x86_release_func( (struct x86_function *) &vs->sse2_program ); + fprintf(stdout /*err*/, + "tgsi_emit_sse2() failed, falling back to interpreter\n"); + } + } +#endif + + return vs; +} + + +void +draw_bind_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + draw->vertex_shader = dvs; + draw->num_vs_outputs = dvs->state->num_outputs; + + /* specify the vertex program to interpret/execute */ + tgsi_exec_machine_init(&draw->machine, + draw->vertex_shader->state->tokens, + PIPE_MAX_SAMPLERS, + NULL /*samplers*/ ); +} + + +void +draw_delete_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs) +{ +#if defined(__i386__) || defined(__386__) + x86_release_func( (struct x86_function *) &dvs->sse2_program ); +#endif + + FREE( dvs ); +} diff --git a/src/gallium/auxiliary/draw/draw_vf.c b/src/gallium/auxiliary/draw/draw_vf.c new file mode 100644 index 0000000000..dc3a5ecd21 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vf.c @@ -0,0 +1,428 @@ +/* + * Copyright 2003 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + + +#include + +#include "pipe/p_compiler.h" +#include "pipe/p_util.h" + +#include "draw_vf.h" + + +#define DRAW_VF_DBG 0 + + +/* TODO: remove this */ +extern void +_mesa_exec_free( void *addr ); + + +static boolean match_fastpath( struct draw_vertex_fetch *vf, + const struct draw_vf_fastpath *fp) +{ + unsigned j; + + if (vf->attr_count != fp->attr_count) + return FALSE; + + for (j = 0; j < vf->attr_count; j++) + if (vf->attr[j].format != fp->attr[j].format || + vf->attr[j].inputsize != fp->attr[j].size || + vf->attr[j].vertoffset != fp->attr[j].offset) + return FALSE; + + if (fp->match_strides) { + if (vf->vertex_stride != fp->vertex_stride) + return FALSE; + + for (j = 0; j < vf->attr_count; j++) + if (vf->attr[j].inputstride != fp->attr[j].stride) + return FALSE; + } + + return TRUE; +} + +static boolean search_fastpath_emit( struct draw_vertex_fetch *vf ) +{ + struct draw_vf_fastpath *fp = vf->fastpath; + + for ( ; fp ; fp = fp->next) { + if (match_fastpath(vf, fp)) { + vf->emit = fp->func; + return TRUE; + } + } + + return FALSE; +} + +void draw_vf_register_fastpath( struct draw_vertex_fetch *vf, + boolean match_strides ) +{ + struct draw_vf_fastpath *fastpath = CALLOC_STRUCT(draw_vf_fastpath); + unsigned i; + + fastpath->vertex_stride = vf->vertex_stride; + fastpath->attr_count = vf->attr_count; + fastpath->match_strides = match_strides; + fastpath->func = vf->emit; + fastpath->attr = (struct draw_vf_attr_type *) + MALLOC(vf->attr_count * sizeof(fastpath->attr[0])); + + for (i = 0; i < vf->attr_count; i++) { + fastpath->attr[i].format = vf->attr[i].format; + fastpath->attr[i].stride = vf->attr[i].inputstride; + fastpath->attr[i].size = vf->attr[i].inputsize; + fastpath->attr[i].offset = vf->attr[i].vertoffset; + } + + fastpath->next = vf->fastpath; + vf->fastpath = fastpath; +} + + + + +/*********************************************************************** + * Build codegen functions or return generic ones: + */ +static void choose_emit_func( struct draw_vertex_fetch *vf, + unsigned count, + uint8_t *dest) +{ + vf->emit = NULL; + + /* Does this match an existing (hardwired, codegen or known-bad) + * fastpath? + */ + if (search_fastpath_emit(vf)) { + /* Use this result. If it is null, then it is already known + * that the current state will fail for codegen and there is no + * point trying again. + */ + } + else if (vf->codegen_emit) { + vf->codegen_emit( vf ); + } + + if (!vf->emit) { + draw_vf_generate_hardwired_emit(vf); + } + + /* Otherwise use the generic version: + */ + if (!vf->emit) + vf->emit = draw_vf_generic_emit; + + vf->emit( vf, count, dest ); +} + + + + + +/*********************************************************************** + * Public entrypoints, mostly dispatch to the above: + */ + + + +static unsigned +draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, + const struct draw_vf_attr_map *map, + unsigned nr, + unsigned vertex_stride ) +{ + unsigned offset = 0; + unsigned i, j; + + assert(nr < PIPE_ATTRIB_MAX); + + for (j = 0, i = 0; i < nr; i++) { + const unsigned format = map[i].format; + if (format == DRAW_EMIT_PAD) { +#if (DRAW_VF_DBG) + debug_printf("%d: pad %d, offset %d\n", i, + map[i].offset, offset); +#endif + + offset += map[i].offset; + + } + else { + vf->attr[j].attrib = map[i].attrib; + vf->attr[j].format = format; + vf->attr[j].insert = draw_vf_format_info[format].insert; + vf->attr[j].vertattrsize = draw_vf_format_info[format].attrsize; + vf->attr[j].vertoffset = offset; + vf->attr[j].isconst = draw_vf_format_info[format].isconst; + if(vf->attr[j].isconst) + memcpy(vf->attr[j].data, &map[i].data, vf->attr[j].vertattrsize); + +#if (DRAW_VF_DBG) + debug_printf("%d: %s, offset %d\n", i, + draw_vf_format_info[format].name, + vf->attr[j].vertoffset); +#endif + + offset += draw_vf_format_info[format].attrsize; + j++; + } + } + + vf->attr_count = j; + vf->vertex_stride = vertex_stride ? vertex_stride : offset; + vf->emit = choose_emit_func; + + assert(vf->vertex_stride >= offset); + return vf->vertex_stride; +} + + +void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, + const struct vertex_info *vinfo, + float point_size ) +{ + unsigned i, j, k; + struct draw_vf_attr *a = vf->attr; + struct draw_vf_attr_map attrs[PIPE_MAX_SHADER_INPUTS]; + unsigned count = 0; /* for debug/sanity */ + unsigned nr_attrs = 0; + + for (i = 0; i < vinfo->num_attribs; i++) { + j = vinfo->src_index[i]; + switch (vinfo->emit[i]) { + case EMIT_OMIT: + /* no-op */ + break; + case EMIT_ALL: { + /* just copy the whole vertex as-is to the vbuf */ + unsigned s = vinfo->size; + assert(i == 0); + assert(j == 0); + /* copy the vertex header */ + /* XXX: we actually don't copy the header, just pad it */ + attrs[nr_attrs].attrib = 0; + attrs[nr_attrs].format = DRAW_EMIT_PAD; + attrs[nr_attrs].offset = offsetof(struct vertex_header, data); + s -= offsetof(struct vertex_header, data)/4; + count += offsetof(struct vertex_header, data)/4; + nr_attrs++; + /* copy the vertex data */ + for(k = 0; k < (s & ~0x3); k += 4) { + attrs[nr_attrs].attrib = k/4; + attrs[nr_attrs].format = DRAW_EMIT_4F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 4; + } + /* tail */ + /* XXX: actually, this shouldn't be needed */ + attrs[nr_attrs].attrib = k/4; + attrs[nr_attrs].offset = 0; + switch(s & 0x3) { + case 0: + break; + case 1: + attrs[nr_attrs].format = DRAW_EMIT_1F; + nr_attrs++; + count += 1; + break; + case 2: + attrs[nr_attrs].format = DRAW_EMIT_2F; + nr_attrs++; + count += 2; + break; + case 3: + attrs[nr_attrs].format = DRAW_EMIT_3F; + nr_attrs++; + count += 3; + break; + } + break; + } + case EMIT_1F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_1F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count++; + break; + case EMIT_1F_PSIZE: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_1F_CONST; + attrs[nr_attrs].offset = 0; + attrs[nr_attrs].data.f[0] = point_size; + nr_attrs++; + count++; + break; + case EMIT_2F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_2F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 2; + break; + case EMIT_3F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_3F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 3; + break; + case EMIT_4F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_4F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 4; + break; + case EMIT_4UB: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_4UB_4F_BGRA; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 1; + break; + default: + assert(0); + } + } + + assert(count == vinfo->size); + + draw_vf_set_vertex_attributes(vf, + attrs, + nr_attrs, + vinfo->size * sizeof(float) ); + + for (j = 0; j < vf->attr_count; j++) { + a[j].inputsize = 4; + a[j].do_insert = a[j].insert[4 - 1]; + if(a[j].isconst) { + a[j].inputptr = a[j].data; + a[j].inputstride = 0; + } + } +} + + +#if 0 +/* Set attribute pointers, adjusted for start position: + */ +void draw_vf_set_sources( struct draw_vertex_fetch *vf, + GLvector4f * const sources[], + unsigned start ) +{ + struct draw_vf_attr *a = vf->attr; + unsigned j; + + for (j = 0; j < vf->attr_count; j++) { + const GLvector4f *vptr = sources[a[j].attrib]; + + if ((a[j].inputstride != vptr->stride) || + (a[j].inputsize != vptr->size)) + vf->emit = choose_emit_func; + + a[j].inputstride = vptr->stride; + a[j].inputsize = vptr->size; + a[j].do_insert = a[j].insert[vptr->size - 1]; + a[j].inputptr = ((uint8_t *)vptr->data) + start * vptr->stride; + } +} +#endif + + +/** + * Emit a vertex to dest. + */ +void draw_vf_emit_vertex( struct draw_vertex_fetch *vf, + struct vertex_header *vertex, + void *dest ) +{ + struct draw_vf_attr *a = vf->attr; + unsigned j; + + for (j = 0; j < vf->attr_count; j++) { + if (!a[j].isconst) { + a[j].inputptr = (uint8_t *)&vertex->data[a[j].attrib][0]; + a[j].inputstride = 0; /* XXX: one-vertex-max ATM */ + } + } + + vf->emit( vf, 1, (uint8_t*) dest ); +} + + + +struct draw_vertex_fetch *draw_vf_create( void ) +{ + struct draw_vertex_fetch *vf = CALLOC_STRUCT(draw_vertex_fetch); + unsigned i; + + for (i = 0; i < PIPE_ATTRIB_MAX; i++) + vf->attr[i].vf = vf; + + vf->identity[0] = 0.0; + vf->identity[1] = 0.0; + vf->identity[2] = 0.0; + vf->identity[3] = 1.0; + + vf->codegen_emit = NULL; + +#ifdef USE_SSE_ASM + if (!GETENV("GALLIUM_NO_CODEGEN")) + vf->codegen_emit = draw_vf_generate_sse_emit; +#endif + + return vf; +} + + +void draw_vf_destroy( struct draw_vertex_fetch *vf ) +{ + struct draw_vf_fastpath *fp, *tmp; + + for (fp = vf->fastpath ; fp ; fp = tmp) { + tmp = fp->next; + FREE(fp->attr); + + /* KW: At the moment, fp->func is constrained to be allocated by + * _mesa_exec_alloc(), as the hardwired fastpaths in + * t_vertex_generic.c are handled specially. It would be nice + * to unify them, but this probably won't change until this + * module gets another overhaul. + */ + //_mesa_exec_free((void *) fp->func); + FREE(fp); + } + + vf->fastpath = NULL; + FREE(vf); +} diff --git a/src/gallium/auxiliary/draw/draw_vf.h b/src/gallium/auxiliary/draw/draw_vf.h new file mode 100644 index 0000000000..011c8f0ff1 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vf.h @@ -0,0 +1,236 @@ +/* + * Copyright 2008 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * Vertex fetch/store/convert code. This functionality is used in two places: + * 1. Vertex fetch/convert - to grab vertex data from incoming vertex + * arrays and convert to format needed by vertex shaders. + * 2. Vertex store/emit - to convert simple float[][4] vertex attributes + * (which is the organization used throughout the draw/prim pipeline) to + * hardware-specific formats and emit into hardware vertex buffers. + * + * + * Authors: + * Keith Whitwell + */ + +#ifndef DRAW_VF_H +#define DRAW_VF_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "draw_vertex.h" +#include "draw_private.h" /* for vertex_header */ + + +enum draw_vf_attr_format { + DRAW_EMIT_1F, + DRAW_EMIT_2F, + DRAW_EMIT_3F, + DRAW_EMIT_4F, + DRAW_EMIT_3F_XYW, /**< for projective texture */ + DRAW_EMIT_1UB_1F, /**< for fog coordinate */ + DRAW_EMIT_3UB_3F_RGB, /**< for specular color */ + DRAW_EMIT_3UB_3F_BGR, /**< for specular color */ + DRAW_EMIT_4UB_4F_RGBA, /**< for color */ + DRAW_EMIT_4UB_4F_BGRA, /**< for color */ + DRAW_EMIT_4UB_4F_ARGB, /**< for color */ + DRAW_EMIT_4UB_4F_ABGR, /**< for color */ + DRAW_EMIT_1F_CONST, + DRAW_EMIT_2F_CONST, + DRAW_EMIT_3F_CONST, + DRAW_EMIT_4F_CONST, + DRAW_EMIT_PAD, /**< leave a hole of 'offset' bytes */ + DRAW_EMIT_MAX +}; + +struct draw_vf_attr_map +{ + /** Input attribute number */ + unsigned attrib; + + enum draw_vf_attr_format format; + + unsigned offset; + + /** + * Constant data for DRAW_EMIT_*_CONST + */ + union { + uint8_t ub[4]; + float f[4]; + } data; +}; + +struct draw_vertex_fetch; + + + +#if 0 +unsigned +draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, + const struct draw_vf_attr_map *map, + unsigned nr, + unsigned vertex_stride ); +#endif + +void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, + const struct vertex_info *vinfo, + float point_size ); + +#if 0 +void +draw_vf_set_sources( struct draw_vertex_fetch *vf, + GLvector4f * const attrib[], + unsigned start ); +#endif + +void +draw_vf_emit_vertex( struct draw_vertex_fetch *vf, + struct vertex_header *vertex, + void *dest ); + +struct draw_vertex_fetch * +draw_vf_create( void ); + +void +draw_vf_destroy( struct draw_vertex_fetch *vf ); + + + +/*********************************************************************** + * Internal functions and structs: + */ + +struct draw_vf_attr; + +typedef void (*draw_vf_extract_func)( const struct draw_vf_attr *a, + float *out, + const uint8_t *v ); + +typedef void (*draw_vf_insert_func)( const struct draw_vf_attr *a, + uint8_t *v, + const float *in ); + +typedef void (*draw_vf_emit_func)( struct draw_vertex_fetch *vf, + unsigned count, + uint8_t *dest ); + + + +/** + * Describes how to convert/move a vertex attribute from a vertex + * array to a vertex structure. + */ +struct draw_vf_attr +{ + struct draw_vertex_fetch *vf; + + unsigned format; + unsigned inputsize; + unsigned inputstride; + unsigned vertoffset; /**< position of the attrib in the vertex struct */ + + boolean isconst; /**< read from const data below */ + uint8_t data[16]; + + unsigned attrib; /**< which vertex attrib (0=position, etc) */ + unsigned vertattrsize; /**< size of the attribute in bytes */ + + uint8_t *inputptr; + const draw_vf_insert_func *insert; + draw_vf_insert_func do_insert; + draw_vf_extract_func extract; +}; + +struct draw_vertex_fetch +{ + struct draw_vf_attr attr[PIPE_ATTRIB_MAX]; + unsigned attr_count; + unsigned vertex_stride; + + draw_vf_emit_func emit; + + /* Parameters and constants for codegen: + */ + float identity[4]; + + struct draw_vf_fastpath *fastpath; + + void (*codegen_emit)( struct draw_vertex_fetch *vf ); +}; + + +struct draw_vf_attr_type { + unsigned format; + unsigned size; + unsigned stride; + unsigned offset; +}; + +/** XXX this could be moved into draw_vf.c */ +struct draw_vf_fastpath { + unsigned vertex_stride; + unsigned attr_count; + boolean match_strides; + + struct draw_vf_attr_type *attr; + + draw_vf_emit_func func; + struct draw_vf_fastpath *next; +}; + + +void +draw_vf_register_fastpath( struct draw_vertex_fetch *vtx, + boolean match_strides ); + +void +draw_vf_generic_emit( struct draw_vertex_fetch *vf, + unsigned count, + uint8_t *v ); + +void +draw_vf_generate_hardwired_emit( struct draw_vertex_fetch *vf ); + +void +draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ); + + +/** XXX this type and function could probably be moved into draw_vf.c */ +struct draw_vf_format_info { + const char *name; + draw_vf_insert_func insert[4]; + const unsigned attrsize; + const boolean isconst; +}; + +extern const struct draw_vf_format_info +draw_vf_format_info[DRAW_EMIT_MAX]; + + +#endif diff --git a/src/gallium/auxiliary/draw/draw_vf_generic.c b/src/gallium/auxiliary/draw/draw_vf_generic.c new file mode 100644 index 0000000000..7a60a9db9c --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vf_generic.c @@ -0,0 +1,585 @@ + +/* + * Copyright 2003 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" + +#include "draw_vf.h" + + + +static INLINE void insert_4f_4( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +static INLINE void insert_4f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = 1; +} + +static INLINE void insert_4f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = 0; + out[3] = 1; +} + +static INLINE void insert_4f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = 0; + out[2] = 0; + out[3] = 1; +} + +static INLINE void insert_3f_xyw_4( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[3]; +} + +static INLINE void insert_3f_xyw_err( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + (void) a; (void) v; (void) in; + assert(0); +} + +static INLINE void insert_3f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; +} + +static INLINE void insert_3f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; + out[2] = 0; +} + +static INLINE void insert_3f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = 0; + out[2] = 0; +} + + +static INLINE void insert_2f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = in[1]; +} + +static INLINE void insert_2f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; + out[1] = 0; +} + +static INLINE void insert_1f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + float *out = (float *)(v); + (void) a; + + out[0] = in[0]; +} + +static INLINE void insert_null( const struct draw_vf_attr *a, uint8_t *v, const float *in ) +{ + (void) a; (void) v; (void) in; +} + +static INLINE void insert_4ub_4f_rgba_4( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); +} + +static INLINE void insert_4ub_4f_rgba_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_rgba_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + v[2] = 0; + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_rgba_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + v[1] = 0; + v[2] = 0; + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_bgra_4( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); +} + +static INLINE void insert_4ub_4f_bgra_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_bgra_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + v[0] = 0; + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_bgra_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + v[1] = 0; + v[0] = 0; + v[3] = 0xff; +} + +static INLINE void insert_4ub_4f_argb_4( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); +} + +static INLINE void insert_4ub_4f_argb_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); + v[0] = 0xff; +} + +static INLINE void insert_4ub_4f_argb_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + v[3] = 0x00; + v[0] = 0xff; +} + +static INLINE void insert_4ub_4f_argb_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); + v[2] = 0x00; + v[3] = 0x00; + v[0] = 0xff; +} + +static INLINE void insert_4ub_4f_abgr_4( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); +} + +static INLINE void insert_4ub_4f_abgr_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); + v[0] = 0xff; +} + +static INLINE void insert_4ub_4f_abgr_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); + v[1] = 0x00; + v[0] = 0xff; +} + +static INLINE void insert_4ub_4f_abgr_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); + v[2] = 0x00; + v[1] = 0x00; + v[0] = 0xff; +} + +static INLINE void insert_3ub_3f_rgb_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); +} + +static INLINE void insert_3ub_3f_rgb_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + v[2] = 0; +} + +static INLINE void insert_3ub_3f_rgb_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); + v[1] = 0; + v[2] = 0; +} + +static INLINE void insert_3ub_3f_bgr_3( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); +} + +static INLINE void insert_3ub_3f_bgr_2( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); + v[0] = 0; +} + +static INLINE void insert_3ub_3f_bgr_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); + v[1] = 0; + v[0] = 0; +} + + +static INLINE void insert_1ub_1f_1( const struct draw_vf_attr *a, uint8_t *v, + const float *in ) +{ + (void) a; + UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); +} + + +const struct draw_vf_format_info draw_vf_format_info[DRAW_EMIT_MAX] = +{ + { "1f", + { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, + sizeof(float), FALSE }, + + { "2f", + { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, + 2 * sizeof(float), FALSE }, + + { "3f", + { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, + 3 * sizeof(float), FALSE }, + + { "4f", + { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, + 4 * sizeof(float), FALSE }, + + { "3f_xyw", + { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err, + insert_3f_xyw_4 }, + 3 * sizeof(float), FALSE }, + + { "1ub_1f", + { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 }, + sizeof(uint8_t), FALSE }, + + { "3ub_3f_rgb", + { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3, + insert_3ub_3f_rgb_3 }, + 3 * sizeof(uint8_t), FALSE }, + + { "3ub_3f_bgr", + { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3, + insert_3ub_3f_bgr_3 }, + 3 * sizeof(uint8_t), FALSE }, + + { "4ub_4f_rgba", + { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3, + insert_4ub_4f_rgba_4 }, + 4 * sizeof(uint8_t), FALSE }, + + { "4ub_4f_bgra", + { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3, + insert_4ub_4f_bgra_4 }, + 4 * sizeof(uint8_t), FALSE }, + + { "4ub_4f_argb", + { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3, + insert_4ub_4f_argb_4 }, + 4 * sizeof(uint8_t), FALSE }, + + { "4ub_4f_abgr", + { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3, + insert_4ub_4f_abgr_4 }, + 4 * sizeof(uint8_t), FALSE }, + + { "1f_const", + { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, + sizeof(float), TRUE }, + + { "2f_const", + { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, + 2 * sizeof(float), TRUE }, + + { "3f_const", + { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, + 3 * sizeof(float), TRUE }, + + { "4f_const", + { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, + 4 * sizeof(float), TRUE }, + + { "pad", + { NULL, NULL, NULL, NULL }, + 0, FALSE }, + +}; + + + + +/*********************************************************************** + * Hardwired fastpaths for emitting whole vertices or groups of + * vertices + */ +#define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \ +static void NAME( struct draw_vertex_fetch *vf, \ + unsigned count, \ + uint8_t *v ) \ +{ \ + struct draw_vf_attr *a = vf->attr; \ + unsigned i; \ + \ + for (i = 0 ; i < count ; i++, v += vf->vertex_stride) { \ + if (NR > 0) { \ + F0( &a[0], v + a[0].vertoffset, (float *)a[0].inputptr ); \ + a[0].inputptr += a[0].inputstride; \ + } \ + \ + if (NR > 1) { \ + F1( &a[1], v + a[1].vertoffset, (float *)a[1].inputptr ); \ + a[1].inputptr += a[1].inputstride; \ + } \ + \ + if (NR > 2) { \ + F2( &a[2], v + a[2].vertoffset, (float *)a[2].inputptr ); \ + a[2].inputptr += a[2].inputstride; \ + } \ + \ + if (NR > 3) { \ + F3( &a[3], v + a[3].vertoffset, (float *)a[3].inputptr ); \ + a[3].inputptr += a[3].inputstride; \ + } \ + \ + if (NR > 4) { \ + F4( &a[4], v + a[4].vertoffset, (float *)a[4].inputptr ); \ + a[4].inputptr += a[4].inputstride; \ + } \ + } \ +} + + +#define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \ + insert_null, insert_null, NAME) + +#define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \ + insert_null, NAME) + +#define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \ + insert_null, NAME) + + +EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4) + +EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2) + +EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2) + + +/* Use the codegen paths to select one of a number of hardwired + * fastpaths. + */ +void draw_vf_generate_hardwired_emit( struct draw_vertex_fetch *vf ) +{ + draw_vf_emit_func func = NULL; + + /* Does it fit a hardwired fastpath? Help! this is growing out of + * control! + */ + switch (vf->attr_count) { + case 2: + if (vf->attr[0].do_insert == insert_3f_3 && + vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { + func = emit_xyz3_rgba4; + } + break; + case 3: + if (vf->attr[2].do_insert == insert_2f_2) { + if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { + if (vf->attr[0].do_insert == insert_4f_4) + func = emit_xyzw4_rgba4_st2; + } + } + break; + case 4: + if (vf->attr[2].do_insert == insert_2f_2 && + vf->attr[3].do_insert == insert_2f_2) { + if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { + if (vf->attr[0].do_insert == insert_4f_4) + func = emit_xyzw4_rgba4_st2_st2; + } + } + break; + } + + vf->emit = func; +} + +/*********************************************************************** + * Generic (non-codegen) functions for whole vertices or groups of + * vertices + */ + +void draw_vf_generic_emit( struct draw_vertex_fetch *vf, + unsigned count, + uint8_t *v ) +{ + struct draw_vf_attr *a = vf->attr; + const unsigned attr_count = vf->attr_count; + const unsigned stride = vf->vertex_stride; + unsigned i, j; + + for (i = 0 ; i < count ; i++, v += stride) { + for (j = 0; j < attr_count; j++) { + float *in = (float *)a[j].inputptr; + a[j].inputptr += a[j].inputstride; + a[j].do_insert( &a[j], v + a[j].vertoffset, in ); + } + } +} + + diff --git a/src/gallium/auxiliary/draw/draw_vf_sse.c b/src/gallium/auxiliary/draw/draw_vf_sse.c new file mode 100644 index 0000000000..1ad2ae756d --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vf_sse.c @@ -0,0 +1,614 @@ +/* + * Copyright 2003 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + + +#include "simple_list.h" + +#include "pipe/p_compiler.h" + +#include "draw_vf.h" + + +#if defined(USE_SSE_ASM) + +#include "x86/rtasm/x86sse.h" +#include "x86/common_x86_asm.h" + + +#define X 0 +#define Y 1 +#define Z 2 +#define W 3 + + +struct x86_program { + struct x86_function func; + + struct draw_vertex_fetch *vf; + boolean inputs_safe; + boolean outputs_safe; + boolean have_sse2; + + struct x86_reg identity; + struct x86_reg chan0; +}; + + +static struct x86_reg get_identity( struct x86_program *p ) +{ + return p->identity; +} + +static void emit_load4f_4( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movups(&p->func, dest, arg0); +} + +static void emit_load4f_3( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + /* Have to jump through some hoops: + * + * c 0 0 0 + * c 0 0 1 + * 0 0 c 1 + * a b c 1 + */ + sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); + sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); + sse_shufps(&p->func, dest, dest, SHUF(Y,Z,X,W) ); + sse_movlps(&p->func, dest, arg0); +} + +static void emit_load4f_2( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + /* Initialize from identity, then pull in low two words: + */ + sse_movups(&p->func, dest, get_identity(p)); + sse_movlps(&p->func, dest, arg0); +} + +static void emit_load4f_1( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + /* Pull in low word, then swizzle in identity */ + sse_movss(&p->func, dest, arg0); + sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); +} + + + +static void emit_load3f_3( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + /* Over-reads by 1 dword - potential SEGV if input is a vertex + * array. + */ + if (p->inputs_safe) { + sse_movups(&p->func, dest, arg0); + } + else { + /* c 0 0 0 + * c c c c + * a b c c + */ + sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); + sse_shufps(&p->func, dest, dest, SHUF(X,X,X,X)); + sse_movlps(&p->func, dest, arg0); + } +} + +static void emit_load3f_2( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + emit_load4f_2(p, dest, arg0); +} + +static void emit_load3f_1( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + emit_load4f_1(p, dest, arg0); +} + +static void emit_load2f_2( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movlps(&p->func, dest, arg0); +} + +static void emit_load2f_1( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + emit_load4f_1(p, dest, arg0); +} + +static void emit_load1f_1( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movss(&p->func, dest, arg0); +} + +static void (*load[4][4])( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) = { + { emit_load1f_1, + emit_load1f_1, + emit_load1f_1, + emit_load1f_1 }, + + { emit_load2f_1, + emit_load2f_2, + emit_load2f_2, + emit_load2f_2 }, + + { emit_load3f_1, + emit_load3f_2, + emit_load3f_3, + emit_load3f_3 }, + + { emit_load4f_1, + emit_load4f_2, + emit_load4f_3, + emit_load4f_4 } +}; + +static void emit_load( struct x86_program *p, + struct x86_reg dest, + unsigned sz, + struct x86_reg src, + unsigned src_sz) +{ + load[sz-1][src_sz-1](p, dest, src); +} + +static void emit_store4f( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movups(&p->func, dest, arg0); +} + +static void emit_store3f( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + if (p->outputs_safe) { + /* Emit the extra dword anyway. This may hurt writecombining, + * may cause other problems. + */ + sse_movups(&p->func, dest, arg0); + } + else { + /* Alternate strategy - emit two, shuffle, emit one. + */ + sse_movlps(&p->func, dest, arg0); + sse_shufps(&p->func, arg0, arg0, SHUF(Z,Z,Z,Z) ); /* NOTE! destructive */ + sse_movss(&p->func, x86_make_disp(dest,8), arg0); + } +} + +static void emit_store2f( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movlps(&p->func, dest, arg0); +} + +static void emit_store1f( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) +{ + sse_movss(&p->func, dest, arg0); +} + + +static void (*store[4])( struct x86_program *p, + struct x86_reg dest, + struct x86_reg arg0 ) = +{ + emit_store1f, + emit_store2f, + emit_store3f, + emit_store4f +}; + +static void emit_store( struct x86_program *p, + struct x86_reg dest, + unsigned sz, + struct x86_reg temp ) + +{ + store[sz-1](p, dest, temp); +} + +static void emit_pack_store_4ub( struct x86_program *p, + struct x86_reg dest, + struct x86_reg temp ) +{ + /* Scale by 255.0 + */ + sse_mulps(&p->func, temp, p->chan0); + + if (p->have_sse2) { + sse2_cvtps2dq(&p->func, temp, temp); + sse2_packssdw(&p->func, temp, temp); + sse2_packuswb(&p->func, temp, temp); + sse_movss(&p->func, dest, temp); + } + else { + struct x86_reg mmx0 = x86_make_reg(file_MMX, 0); + struct x86_reg mmx1 = x86_make_reg(file_MMX, 1); + sse_cvtps2pi(&p->func, mmx0, temp); + sse_movhlps(&p->func, temp, temp); + sse_cvtps2pi(&p->func, mmx1, temp); + mmx_packssdw(&p->func, mmx0, mmx1); + mmx_packuswb(&p->func, mmx0, mmx0); + mmx_movd(&p->func, dest, mmx0); + } +} + +static int get_offset( const void *a, const void *b ) +{ + return (const char *)b - (const char *)a; +} + +/* Not much happens here. Eventually use this function to try and + * avoid saving/reloading the source pointers each vertex (if some of + * them can fit in registers). + */ +static void get_src_ptr( struct x86_program *p, + struct x86_reg srcREG, + struct x86_reg vfREG, + struct draw_vf_attr *a ) +{ + struct draw_vertex_fetch *vf = p->vf; + struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr)); + + /* Load current a[j].inputptr + */ + x86_mov(&p->func, srcREG, ptr_to_src); +} + +static void update_src_ptr( struct x86_program *p, + struct x86_reg srcREG, + struct x86_reg vfREG, + struct draw_vf_attr *a ) +{ + if (a->inputstride) { + struct draw_vertex_fetch *vf = p->vf; + struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr)); + + /* add a[j].inputstride (hardcoded value - could just as easily + * pull the stride value from memory each time). + */ + x86_lea(&p->func, srcREG, x86_make_disp(srcREG, a->inputstride)); + + /* save new value of a[j].inputptr + */ + x86_mov(&p->func, ptr_to_src, srcREG); + } +} + + +/* Lots of hardcoding + * + * EAX -- pointer to current output vertex + * ECX -- pointer to current attribute + * + */ +static boolean build_vertex_emit( struct x86_program *p ) +{ + struct draw_vertex_fetch *vf = p->vf; + unsigned j = 0; + + struct x86_reg vertexEAX = x86_make_reg(file_REG32, reg_AX); + struct x86_reg srcECX = x86_make_reg(file_REG32, reg_CX); + struct x86_reg countEBP = x86_make_reg(file_REG32, reg_BP); + struct x86_reg vfESI = x86_make_reg(file_REG32, reg_SI); + struct x86_reg temp = x86_make_reg(file_XMM, 0); + uint8_t *fixup, *label; + + /* Push a few regs? + */ + x86_push(&p->func, countEBP); + x86_push(&p->func, vfESI); + + + /* Get vertex count, compare to zero + */ + x86_xor(&p->func, srcECX, srcECX); + x86_mov(&p->func, countEBP, x86_fn_arg(&p->func, 2)); + x86_cmp(&p->func, countEBP, srcECX); + fixup = x86_jcc_forward(&p->func, cc_E); + + /* Initialize destination register. + */ + x86_mov(&p->func, vertexEAX, x86_fn_arg(&p->func, 3)); + + /* Move argument 1 (vf) into a reg: + */ + x86_mov(&p->func, vfESI, x86_fn_arg(&p->func, 1)); + + + /* always load, needed or not: + */ + sse_movups(&p->func, p->identity, x86_make_disp(vfESI, get_offset(vf, &vf->identity[0]))); + + /* Note address for loop jump */ + label = x86_get_label(&p->func); + + /* Emit code for each of the attributes. Currently routes + * everything through SSE registers, even when it might be more + * efficient to stick with regular old x86. No optimization or + * other tricks - enough new ground to cover here just getting + * things working. + */ + while (j < vf->attr_count) { + struct draw_vf_attr *a = &vf->attr[j]; + struct x86_reg dest = x86_make_disp(vertexEAX, a->vertoffset); + + /* Now, load an XMM reg from src, perhaps transform, then save. + * Could be shortcircuited in specific cases: + */ + switch (a->format) { + case DRAW_EMIT_1F: + case DRAW_EMIT_1F_CONST: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); + emit_store(p, dest, 1, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_2F: + case DRAW_EMIT_2F_CONST: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); + emit_store(p, dest, 2, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_3F: + case DRAW_EMIT_3F_CONST: + /* Potentially the worst case - hardcode 2+1 copying: + */ + if (0) { + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); + emit_store(p, dest, 3, temp); + update_src_ptr(p, srcECX, vfESI, a); + } + else { + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); + emit_store(p, dest, 2, temp); + if (a->inputsize > 2) { + emit_load(p, temp, 1, x86_make_disp(srcECX, 8), 1); + emit_store(p, x86_make_disp(dest,8), 1, temp); + } + else { + sse_movss(&p->func, x86_make_disp(dest,8), get_identity(p)); + } + update_src_ptr(p, srcECX, vfESI, a); + } + break; + case DRAW_EMIT_4F: + case DRAW_EMIT_4F_CONST: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + emit_store(p, dest, 4, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_3F_XYW: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + sse_shufps(&p->func, temp, temp, SHUF(X,Y,W,Z)); + emit_store(p, dest, 3, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + + case DRAW_EMIT_1UB_1F: + /* Test for PAD3 + 1UB: + */ + if (j > 0 && + a[-1].vertoffset + a[-1].vertattrsize <= a->vertoffset - 3) + { + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); + sse_shufps(&p->func, temp, temp, SHUF(X,X,X,X)); + emit_pack_store_4ub(p, x86_make_disp(dest, -3), temp); /* overkill! */ + update_src_ptr(p, srcECX, vfESI, a); + } + else { + debug_printf("Can't emit 1ub %x %x %d\n", + a->vertoffset, a[-1].vertoffset, a[-1].vertattrsize ); + return FALSE; + } + break; + case DRAW_EMIT_3UB_3F_RGB: + case DRAW_EMIT_3UB_3F_BGR: + /* Test for 3UB + PAD1: + */ + if (j == vf->attr_count - 1 || + a[1].vertoffset >= a->vertoffset + 4) { + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); + if (a->format == DRAW_EMIT_3UB_3F_BGR) + sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); + emit_pack_store_4ub(p, dest, temp); + update_src_ptr(p, srcECX, vfESI, a); + } + /* Test for 3UB + 1UB: + */ + else if (j < vf->attr_count - 1 && + a[1].format == DRAW_EMIT_1UB_1F && + a[1].vertoffset == a->vertoffset + 3) { + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); + update_src_ptr(p, srcECX, vfESI, a); + + /* Make room for incoming value: + */ + sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); + + get_src_ptr(p, srcECX, vfESI, &a[1]); + emit_load(p, temp, 1, x86_deref(srcECX), a[1].inputsize); + update_src_ptr(p, srcECX, vfESI, &a[1]); + + /* Rearrange and possibly do BGR conversion: + */ + if (a->format == DRAW_EMIT_3UB_3F_BGR) + sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); + else + sse_shufps(&p->func, temp, temp, SHUF(Y,Z,W,X)); + + emit_pack_store_4ub(p, dest, temp); + j++; /* NOTE: two attrs consumed */ + } + else { + debug_printf("Can't emit 3ub\n"); + } + return FALSE; /* add this later */ + break; + + case DRAW_EMIT_4UB_4F_RGBA: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + emit_pack_store_4ub(p, dest, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_4UB_4F_BGRA: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); + emit_pack_store_4ub(p, dest, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_4UB_4F_ARGB: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); + emit_pack_store_4ub(p, dest, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + case DRAW_EMIT_4UB_4F_ABGR: + get_src_ptr(p, srcECX, vfESI, a); + emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); + sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); + emit_pack_store_4ub(p, dest, temp); + update_src_ptr(p, srcECX, vfESI, a); + break; + default: + debug_printf("unknown a[%d].format %d\n", j, a->format); + return FALSE; /* catch any new opcodes */ + } + + /* Increment j by at least 1 - may have been incremented above also: + */ + j++; + } + + /* Next vertex: + */ + x86_lea(&p->func, vertexEAX, x86_make_disp(vertexEAX, vf->vertex_stride)); + + /* decr count, loop if not zero + */ + x86_dec(&p->func, countEBP); + x86_test(&p->func, countEBP, countEBP); + x86_jcc(&p->func, cc_NZ, label); + + /* Exit mmx state? + */ + if (p->func.need_emms) + mmx_emms(&p->func); + + /* Land forward jump here: + */ + x86_fixup_fwd_jump(&p->func, fixup); + + /* Pop regs and return + */ + x86_pop(&p->func, x86_get_base_reg(vfESI)); + x86_pop(&p->func, countEBP); + x86_ret(&p->func); + + vf->emit = (draw_vf_emit_func)x86_get_func(&p->func); + return TRUE; +} + + + +void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) +{ + struct x86_program p; + + if (!cpu_has_xmm) { + vf->codegen_emit = NULL; + return; + } + + memset(&p, 0, sizeof(p)); + + p.vf = vf; + p.inputs_safe = 0; /* for now */ + p.outputs_safe = 1; /* for now */ + p.have_sse2 = cpu_has_xmm2; + p.identity = x86_make_reg(file_XMM, 6); + p.chan0 = x86_make_reg(file_XMM, 7); + + x86_init_func(&p.func); + + if (build_vertex_emit(&p)) { + draw_vf_register_fastpath( vf, TRUE ); + } + else { + /* Note the failure so that we don't keep trying to codegen an + * impossible state: + */ + draw_vf_register_fastpath( vf, FALSE ); + x86_release_func(&p.func); + } +} + +#else + +void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) +{ + /* Dummy version for when USE_SSE_ASM not defined */ +} + +#endif diff --git a/src/gallium/auxiliary/draw/draw_wide_prims.c b/src/gallium/auxiliary/draw/draw_wide_prims.c new file mode 100644 index 0000000000..655774b155 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_wide_prims.c @@ -0,0 +1,432 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +struct wide_stage { + struct draw_stage stage; + + float half_line_width; + float half_point_size; + + uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; + uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; + uint num_texcoords; + + int psize_slot; +}; + + + +static INLINE struct wide_stage *wide_stage( struct draw_stage *stage ) +{ + return (struct wide_stage *)stage; +} + + +static void passthrough_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + +static void passthrough_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line(stage->next, header); +} + +static void passthrough_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw a wide line by drawing a quad (two triangles). + * XXX need to disable polygon stipple. + */ +static void wide_line( struct draw_stage *stage, + struct prim_header *header ) +{ + const struct wide_stage *wide = wide_stage(stage); + const float half_width = wide->half_line_width; + + struct prim_header tri; + + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + const float dx = FABSF(pos0[0] - pos2[0]); + const float dy = FABSF(pos0[1] - pos2[1]); + + /* + * Draw wide line as a quad (two tris) by "stretching" the line along + * X or Y. + * We need to tweak coords in several ways to be conformant here. + */ + + if (dx > dy) { + /* x-major line */ + pos0[1] = pos0[1] - half_width - 0.25f; + pos1[1] = pos1[1] + half_width - 0.25f; + pos2[1] = pos2[1] - half_width - 0.25f; + pos3[1] = pos3[1] + half_width - 0.25f; + if (pos0[0] < pos2[0]) { + /* left to right line */ + pos0[0] -= 0.5f; + pos1[0] -= 0.5f; + pos2[0] -= 0.5f; + pos3[0] -= 0.5f; + } + else { + /* right to left line */ + pos0[0] += 0.5f; + pos1[0] += 0.5f; + pos2[0] += 0.5f; + pos3[0] += 0.5f; + } + } + else { + /* y-major line */ + pos0[0] = pos0[0] - half_width + 0.25f; + pos1[0] = pos1[0] + half_width + 0.25f; + pos2[0] = pos2[0] - half_width + 0.25f; + pos3[0] = pos3[0] + half_width + 0.25f; + if (pos0[1] < pos2[1]) { + /* top to bottom line */ + pos0[1] -= 0.5f; + pos1[1] -= 0.5f; + pos2[1] -= 0.5f; + pos3[1] -= 0.5f; + } + else { + /* bottom to top line */ + pos0[1] += 0.5f; + pos1[1] += 0.5f; + pos2[1] += 0.5f; + pos3[1] += 0.5f; + } + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +/** + * Draw a wide line by drawing a quad, using geometry which will + * fullfill GL's antialiased line requirements. + */ +static void wide_line_aa(struct draw_stage *stage, + struct prim_header *header) +{ + const struct wide_stage *wide = wide_stage(stage); + const float half_width = wide->half_line_width; + struct prim_header tri; + struct vertex_header *v[4]; + float *pos; + float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; + float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; + const float len = (float) sqrt(dx * dx + dy * dy); + uint i; + + dx = dx * half_width / len; + dy = dy * half_width / len; + + /* allocate/dup new verts */ + for (i = 0; i < 4; i++) { + v[i] = dup_vert(stage, header->v[i/2], i); + } + + /* + * Quad for line from v0 to v1: + * + * 1 3 + * +-------------------------+ + * | | + * *v0 v1* + * | | + * +-------------------------+ + * 0 2 + */ + + pos = v[0]->data[0]; + pos[0] += dy; + pos[1] -= dx; + + pos = v[1]->data[0]; + pos[0] -= dy; + pos[1] += dx; + + pos = v[2]->data[0]; + pos[0] += dy; + pos[1] -= dx; + + pos = v[3]->data[0]; + pos[0] -= dy; + pos[1] += dx; + + tri.det = header->det; /* only the sign matters */ + + tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + +} + + +/** + * Set the vertex texcoords for sprite mode. + * Coords may be left untouched or set to a right-side-up or upside-down + * orientation. + */ +static void set_texcoords(const struct wide_stage *wide, + struct vertex_header *v, const float tc[4]) +{ + uint i; + for (i = 0; i < wide->num_texcoords; i++) { + if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { + uint j = wide->texcoord_slot[i]; + v->data[j][0] = tc[0]; + if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) + v->data[j][1] = 1.0f - tc[1]; + else + v->data[j][1] = tc[1]; + v->data[j][2] = tc[2]; + v->data[j][3] = tc[3]; + } + } +} + + +/* If there are lots of sprite points (and why wouldn't there be?) it + * would probably be more sensible to change hardware setup to + * optimize this rather than doing the whole thing in software like + * this. + */ +static void wide_point( struct draw_stage *stage, + struct prim_header *header ) +{ + const struct wide_stage *wide = wide_stage(stage); + const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; + float half_size; + float left_adj, right_adj; + + struct prim_header tri; + + /* four dups of original vertex */ + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + /* point size is either per-vertex or fixed size */ + if (wide->psize_slot >= 0) { + half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; + } + else { + half_size = wide->half_point_size; + } + + left_adj = -half_size + 0.25f; + right_adj = half_size + 0.25f; + + pos0[0] += left_adj; + pos0[1] -= half_size; + + pos1[0] += left_adj; + pos1[1] += half_size; + + pos2[0] += right_adj; + pos2[1] -= half_size; + + pos3[0] += right_adj; + pos3[1] += half_size; + + if (sprite) { + static const float tex00[4] = { 0, 0, 0, 1 }; + static const float tex01[4] = { 0, 1, 0, 1 }; + static const float tex11[4] = { 1, 1, 0, 1 }; + static const float tex10[4] = { 1, 0, 0, 1 }; + set_texcoords( wide, v0, tex00 ); + set_texcoords( wide, v1, tex01 ); + set_texcoords( wide, v2, tex10 ); + set_texcoords( wide, v3, tex11 ); + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +static void wide_first_point( struct draw_stage *stage, + struct prim_header *header ) +{ + struct wide_stage *wide = wide_stage(stage); + struct draw_context *draw = stage->draw; + + wide->half_point_size = 0.5f * draw->rasterizer->point_size; + + if (draw->rasterizer->point_size != 1.0) { + stage->point = wide_point; + } + else { + stage->point = passthrough_point; + } + + if (draw->rasterizer->point_sprite) { + /* find vertex shader texcoord outputs */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i, j = 0; + for (i = 0; i < vs->state->num_outputs; i++) { + if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { + wide->texcoord_slot[j] = i; + wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; + j++; + } + } + wide->num_texcoords = j; + } + + wide->psize_slot = -1; + + if (draw->rasterizer->point_size_per_vertex) { + /* find PSIZ vertex output */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i; + for (i = 0; i < vs->state->num_outputs; i++) { + if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + wide->psize_slot = i; + break; + } + } + } + + stage->point( stage, header ); +} + + + +static void wide_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + struct wide_stage *wide = wide_stage(stage); + struct draw_context *draw = stage->draw; + + wide->half_line_width = 0.5f * draw->rasterizer->line_width; + + if (draw->rasterizer->line_width != 1.0) { + if (draw->rasterizer->line_smooth) + wide->stage.line = wide_line_aa; + else + wide->stage.line = wide_line; + } + else { + wide->stage.line = passthrough_line; + } + + stage->line( stage, header ); +} + + +static void wide_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->line = wide_first_line; + stage->point = wide_first_point; + stage->next->flush( stage->next, flags ); +} + + +static void wide_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void wide_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +struct draw_stage *draw_wide_stage( struct draw_context *draw ) +{ + struct wide_stage *wide = CALLOC_STRUCT(wide_stage); + + draw_alloc_temp_verts( &wide->stage, 4 ); + + wide->stage.draw = draw; + wide->stage.next = NULL; + wide->stage.point = wide_first_point; + wide->stage.line = wide_first_line; + wide->stage.tri = passthrough_tri; + wide->stage.flush = wide_flush; + wide->stage.reset_stipple_counter = wide_reset_stipple_counter; + wide->stage.destroy = wide_destroy; + + return &wide->stage; +} diff --git a/src/gallium/auxiliary/llvm/Makefile b/src/gallium/auxiliary/llvm/Makefile new file mode 100644 index 0000000000..e6ac399d08 --- /dev/null +++ b/src/gallium/auxiliary/llvm/Makefile @@ -0,0 +1,85 @@ +# -*-makefile-*- +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = gallivm + + +GALLIVM_SOURCES = \ + gallivm.cpp \ + gallivm_cpu.cpp \ + instructions.cpp \ + loweringpass.cpp \ + tgsitollvm.cpp \ + storage.cpp \ + storagesoa.cpp \ + instructionssoa.cpp + +INC_SOURCES = gallivm_builtins.cpp + +CPP_SOURCES = \ + $(GALLIVM_SOURCES) + +C_SOURCES = +ASM_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(CPP_SOURCES:.cpp=.o) \ + $(ASM_SOURCES:.S=.o) + +### Include directories +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/drivers + -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/include + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(LLVM_CFLAGS) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(LLVM_CXXFLAGS) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +##### TARGETS ##### + +default:: depend symlinks $(LIBNAME) + + +$(LIBNAME): $(OBJECTS) Makefile + $(TOP)/bin/mklib -o $@ -static $(OBJECTS) + + +depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ + $(ASM_SOURCES) $(INC_SOURCES) 2> /dev/null + + +gallivm_builtins.cpp: llvm_builtins.c + clang --emit-llvm $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.so *~ server/*.o + -rm -f depend depend.bak + -rm -f gallivm_builtins.cpp + +symlinks: + + +include depend diff --git a/src/gallium/auxiliary/llvm/gallivm.cpp b/src/gallium/auxiliary/llvm/gallivm.cpp new file mode 100644 index 0000000000..d14bb3b99a --- /dev/null +++ b/src/gallium/auxiliary/llvm/gallivm.cpp @@ -0,0 +1,327 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "instructions.h" +#include "loweringpass.h" +#include "storage.h" +#include "tgsitollvm.h" + +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_dump.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int GLOBAL_ID = 0; + +using namespace llvm; + +static inline +void AddStandardCompilePasses(PassManager &PM) +{ + PM.add(new LoweringPass()); + PM.add(createVerifierPass()); // Verify that input is correct + + PM.add(createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp + + //PM.add(createStripSymbolsPass(true)); + + PM.add(createRaiseAllocationsPass()); // call %malloc -> malloc inst + PM.add(createCFGSimplificationPass()); // Clean up disgusting code + PM.add(createPromoteMemoryToRegisterPass());// Kill useless allocas + PM.add(createGlobalOptimizerPass()); // Optimize out global vars + PM.add(createGlobalDCEPass()); // Remove unused fns and globs + PM.add(createIPConstantPropagationPass());// IP Constant Propagation + PM.add(createDeadArgEliminationPass()); // Dead argument elimination + PM.add(createInstructionCombiningPass()); // Clean up after IPCP & DAE + PM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE + + PM.add(createPruneEHPass()); // Remove dead EH info + + PM.add(createFunctionInliningPass()); // Inline small functions + PM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args + + PM.add(createTailDuplicationPass()); // Simplify cfg by copying code + PM.add(createInstructionCombiningPass()); // Cleanup for scalarrepl. + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createScalarReplAggregatesPass()); // Break up aggregate allocas + PM.add(createInstructionCombiningPass()); // Combine silly seq's + PM.add(createCondPropagationPass()); // Propagate conditionals + + PM.add(createTailCallEliminationPass()); // Eliminate tail calls + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createReassociatePass()); // Reassociate expressions + PM.add(createLoopRotatePass()); + PM.add(createLICMPass()); // Hoist loop invariants + PM.add(createLoopUnswitchPass()); // Unswitch loops. + PM.add(createLoopIndexSplitPass()); // Index split loops. + PM.add(createInstructionCombiningPass()); // Clean up after LICM/reassoc + PM.add(createIndVarSimplifyPass()); // Canonicalize indvars + PM.add(createLoopUnrollPass()); // Unroll small loops + PM.add(createInstructionCombiningPass()); // Clean up after the unroller + PM.add(createGVNPass()); // Remove redundancies + PM.add(createSCCPPass()); // Constant prop with SCCP + + // Run instcombine after redundancy elimination to exploit opportunities + // opened up by them. + PM.add(createInstructionCombiningPass()); + PM.add(createCondPropagationPass()); // Propagate conditionals + + PM.add(createDeadStoreEliminationPass()); // Delete dead stores + PM.add(createAggressiveDCEPass()); // SSA based 'Aggressive DCE' + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createSimplifyLibCallsPass()); // Library Call Optimizations + PM.add(createDeadTypeEliminationPass()); // Eliminate dead types + PM.add(createConstantMergePass()); // Merge dup global constants +} + +void gallivm_prog_delete(struct gallivm_prog *prog) +{ + delete prog->module; + prog->module = 0; + prog->function = 0; + free(prog); +} + +static inline void +constant_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan) +{ + unsigned i; + + for (i = 0; i < QUAD_SIZE; ++i) { + inputs[i][attrib][chan] = coefs[attrib].a0[chan]; + } +} + +static inline void +linear_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + const float x = inputs[i][0][0]; + const float y = inputs[i][0][1]; + + inputs[i][attrib][chan] = + coefs[attrib].a0[chan] + + coefs[attrib].dadx[chan] * x + + coefs[attrib].dady[chan] * y; + } +} + +static inline void +perspective_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan ) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + const float x = inputs[i][0][0]; + const float y = inputs[i][0][1]; + /* WPOS.w here is really 1/w */ + const float w = 1.0f / inputs[i][0][3]; + assert(inputs[i][0][3] != 0.0); + + inputs[i][attrib][chan] = + (coefs[attrib].a0[chan] + + coefs[attrib].dadx[chan] * x + + coefs[attrib].dady[chan] * y) * w; + } +} + +void gallivm_ir_dump(struct gallivm_ir *ir, const char *file_prefix) +{ + if (!ir || !ir->module) + return; + + if (file_prefix) { + std::ostringstream stream; + stream << file_prefix; + stream << ir->id; + stream << ".ll"; + std::string name = stream.str(); + std::ofstream out(name.c_str()); + if (!out) { + std::cerr<<"Can't open file : "<module); + out.close(); + } else { + const llvm::Module::FunctionListType &funcs = ir->module->getFunctionList(); + llvm::Module::FunctionListType::const_iterator itr; + std::cout<<"; ---------- Start shader "<id<id<num_interp; ++i) { + const gallivm_interpolate &interp = prog->interpolators[i]; + switch (interp.type) { + case TGSI_INTERPOLATE_CONSTANT: + constant_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + case TGSI_INTERPOLATE_LINEAR: + linear_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + perspective_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + default: + assert( 0 ); + } + } +} + + +struct gallivm_ir * gallivm_ir_new(enum gallivm_shader_type type) +{ + struct gallivm_ir *ir = + (struct gallivm_ir *)calloc(1, sizeof(struct gallivm_ir)); + ++GLOBAL_ID; + ir->id = GLOBAL_ID; + ir->type = type; + + return ir; +} + +void gallivm_ir_set_layout(struct gallivm_ir *ir, + enum gallivm_vector_layout layout) +{ + ir->layout = layout; +} + +void gallivm_ir_set_components(struct gallivm_ir *ir, int num) +{ + ir->num_components = num; +} + +void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, + const struct tgsi_token *tokens) +{ + std::cout << "Creating llvm from: " <module = mod; + gallivm_ir_dump(ir, 0); +} + +void gallivm_ir_delete(struct gallivm_ir *ir) +{ + delete ir->module; + free(ir); +} + +struct gallivm_prog * gallivm_ir_compile(struct gallivm_ir *ir) +{ + struct gallivm_prog *prog = + (struct gallivm_prog *)calloc(1, sizeof(struct gallivm_prog)); + llvm::Module *mod = llvm::CloneModule(ir->module); + prog->num_consts = ir->num_consts; + memcpy(prog->interpolators, ir->interpolators, sizeof(prog->interpolators)); + prog->num_interp = ir->num_interp; + + /* Run optimization passes over it */ + PassManager passes; + passes.add(new TargetData(mod)); + AddStandardCompilePasses(passes); + passes.run(*mod); + prog->module = mod; + + std::cout << "After optimizations:"<dump(); + + return prog; +} + +#endif /* MESA_LLVM */ diff --git a/src/gallium/auxiliary/llvm/gallivm.h b/src/gallium/auxiliary/llvm/gallivm.h new file mode 100644 index 0000000000..92da4bca7f --- /dev/null +++ b/src/gallium/auxiliary/llvm/gallivm.h @@ -0,0 +1,103 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef GALLIVM_H +#define GALLIVM_H + +#if defined __cplusplus +extern "C" { +#endif + +#include "pipe/p_state.h" + +#ifdef MESA_LLVM + +struct tgsi_token; + +struct gallivm_ir; +struct gallivm_prog; +struct gallivm_cpu_engine; +struct tgsi_interp_coef; +struct tgsi_sampler; +struct tgsi_exec_vector; + +enum gallivm_shader_type { + GALLIVM_VS, + GALLIVM_FS +}; + +enum gallivm_vector_layout { + GALLIVM_AOS, + GALLIVM_SOA +}; + +struct gallivm_ir *gallivm_ir_new(enum gallivm_shader_type type); +void gallivm_ir_set_layout(struct gallivm_ir *ir, + enum gallivm_vector_layout layout); +void gallivm_ir_set_components(struct gallivm_ir *ir, int num); +void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, + const struct tgsi_token *tokens); +void gallivm_ir_delete(struct gallivm_ir *ir); + + +struct gallivm_prog *gallivm_ir_compile(struct gallivm_ir *ir); + +void gallivm_prog_inputs_interpolate(struct gallivm_prog *prog, + float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], + const struct tgsi_interp_coef *coefs); +void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix); + + +struct gallivm_cpu_engine *gallivm_cpu_engine_create(struct gallivm_prog *prog); +struct gallivm_cpu_engine *gallivm_global_cpu_engine(); +int gallivm_cpu_vs_exec(struct gallivm_prog *prog, + struct tgsi_exec_vector *inputs, + struct tgsi_exec_vector *dests, + float (*consts)[4], + struct tgsi_exec_vector *temps); +int gallivm_cpu_fs_exec(struct gallivm_prog *prog, + float x, float y, + float (*dests)[PIPE_MAX_SHADER_INPUTS][4], + float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], + float (*consts)[4], + struct tgsi_sampler *samplers); +void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *ee, struct gallivm_prog *prog); +void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *ee); + + +#endif /* MESA_LLVM */ + +#if defined __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/gallium/auxiliary/llvm/gallivm_builtins.cpp b/src/gallium/auxiliary/llvm/gallivm_builtins.cpp new file mode 100644 index 0000000000..1796f0a177 --- /dev/null +++ b/src/gallium/auxiliary/llvm/gallivm_builtins.cpp @@ -0,0 +1,567 @@ +// Generated by llvm2cpp - DO NOT MODIFY! + + +Module* createGallivmBuiltins(Module *mod) { + +mod->setModuleIdentifier("shader"); + +// Type Definitions +ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(8), 25); + +PointerType* PointerTy_1 = PointerType::get(ArrayTy_0, 0); + +std::vectorFuncTy_2_args; +FuncTy_2_args.push_back(Type::FloatTy); +FuncTy_2_args.push_back(Type::FloatTy); +FunctionType* FuncTy_2 = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/FuncTy_2_args, + /*isVarArg=*/false); + +PointerType* PointerTy_3 = PointerType::get(FuncTy_2, 0); + +VectorType* VectorTy_4 = VectorType::get(Type::FloatTy, 4); + +std::vectorFuncTy_5_args; +FuncTy_5_args.push_back(VectorTy_4); +FunctionType* FuncTy_5 = FunctionType::get( + /*Result=*/VectorTy_4, + /*Params=*/FuncTy_5_args, + /*isVarArg=*/false); + +std::vectorFuncTy_6_args; +FuncTy_6_args.push_back(VectorTy_4); +FuncTy_6_args.push_back(VectorTy_4); +FuncTy_6_args.push_back(VectorTy_4); +FunctionType* FuncTy_6 = FunctionType::get( + /*Result=*/VectorTy_4, + /*Params=*/FuncTy_6_args, + /*isVarArg=*/false); + +VectorType* VectorTy_7 = VectorType::get(IntegerType::get(32), 4); + +std::vectorFuncTy_9_args; +FunctionType* FuncTy_9 = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/FuncTy_9_args, + /*isVarArg=*/true); + +PointerType* PointerTy_8 = PointerType::get(FuncTy_9, 0); + +PointerType* PointerTy_10 = PointerType::get(IntegerType::get(8), 0); + +std::vectorFuncTy_12_args; +FuncTy_12_args.push_back(Type::FloatTy); +FunctionType* FuncTy_12 = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/FuncTy_12_args, + /*isVarArg=*/false); + +PointerType* PointerTy_11 = PointerType::get(FuncTy_12, 0); + +std::vectorFuncTy_13_args; +FuncTy_13_args.push_back(VectorTy_4); +FunctionType* FuncTy_13 = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/FuncTy_13_args, + /*isVarArg=*/false); + + +// Function Declarations + +Function* func_approx = new Function( + /*Type=*/FuncTy_2, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"approx", mod); +func_approx->setCallingConv(CallingConv::C); +const ParamAttrsList *func_approx_PAL = 0; +func_approx->setParamAttrs(func_approx_PAL); + +Function* func_powf = new Function( + /*Type=*/FuncTy_2, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"powf", mod); // (external, no body) +func_powf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_powf_PAL = 0; +func_powf->setParamAttrs(func_powf_PAL); + +Function* func_lit = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"lit", mod); +func_lit->setCallingConv(CallingConv::C); +const ParamAttrsList *func_lit_PAL = 0; +func_lit->setParamAttrs(func_lit_PAL); + +Function* func_cmp = new Function( + /*Type=*/FuncTy_6, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"cmp", mod); +func_cmp->setCallingConv(CallingConv::C); +const ParamAttrsList *func_cmp_PAL = 0; +{ + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; + Attrs.push_back(PAWI); + func_cmp_PAL = ParamAttrsList::get(Attrs); + +} +func_cmp->setParamAttrs(func_cmp_PAL); + +Function* func_vcos = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"vcos", mod); +func_vcos->setCallingConv(CallingConv::C); +const ParamAttrsList *func_vcos_PAL = 0; +func_vcos->setParamAttrs(func_vcos_PAL); + +Function* func_printf = new Function( + /*Type=*/FuncTy_9, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"printf", mod); // (external, no body) +func_printf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_printf_PAL = 0; +func_printf->setParamAttrs(func_printf_PAL); + +Function* func_cosf = new Function( + /*Type=*/FuncTy_12, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"cosf", mod); // (external, no body) +func_cosf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_cosf_PAL = 0; +func_cosf->setParamAttrs(func_cosf_PAL); + +Function* func_scs = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"scs", mod); +func_scs->setCallingConv(CallingConv::C); +const ParamAttrsList *func_scs_PAL = 0; +func_scs->setParamAttrs(func_scs_PAL); + +Function* func_sinf = new Function( + /*Type=*/FuncTy_12, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"sinf", mod); // (external, no body) +func_sinf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_sinf_PAL = 0; +func_sinf->setParamAttrs(func_sinf_PAL); + +Function* func_vsin = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"vsin", mod); +func_vsin->setCallingConv(CallingConv::C); +const ParamAttrsList *func_vsin_PAL = 0; +func_vsin->setParamAttrs(func_vsin_PAL); + +Function* func_kilp = new Function( + /*Type=*/FuncTy_13, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"kilp", mod); +func_kilp->setCallingConv(CallingConv::C); +const ParamAttrsList *func_kilp_PAL = 0; +{ + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; + Attrs.push_back(PAWI); + func_kilp_PAL = ParamAttrsList::get(Attrs); + +} +func_kilp->setParamAttrs(func_kilp_PAL); + +// Global Variable Declarations + + +GlobalVariable* gvar_array__str = new GlobalVariable( +/*Type=*/ArrayTy_0, +/*isConstant=*/true, +/*Linkage=*/GlobalValue::InternalLinkage, +/*Initializer=*/0, // has initializer, specified below +/*Name=*/".str", +mod); + +GlobalVariable* gvar_array__str1 = new GlobalVariable( +/*Type=*/ArrayTy_0, +/*isConstant=*/true, +/*Linkage=*/GlobalValue::InternalLinkage, +/*Initializer=*/0, // has initializer, specified below +/*Name=*/".str1", +mod); + +// Constant Definitions +Constant* const_array_14 = ConstantArray::get("VEC IN is %f %f %f %f\x0A", true); +Constant* const_array_15 = ConstantArray::get("VEC OUT is %f %f %f %f\x0A", true); +ConstantFP* const_float_16 = ConstantFP::get(Type::FloatTy, APFloat(-1.280000e+02f)); +ConstantFP* const_float_17 = ConstantFP::get(Type::FloatTy, APFloat(1.280000e+02f)); +Constant* const_float_18 = Constant::getNullValue(Type::FloatTy); +Constant* const_int32_19 = Constant::getNullValue(IntegerType::get(32)); +std::vector const_packed_20_elems; +ConstantFP* const_float_21 = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); +const_packed_20_elems.push_back(const_float_21); +UndefValue* const_float_22 = UndefValue::get(Type::FloatTy); +const_packed_20_elems.push_back(const_float_22); +const_packed_20_elems.push_back(const_float_22); +const_packed_20_elems.push_back(const_float_21); +Constant* const_packed_20 = ConstantVector::get(VectorTy_4, const_packed_20_elems); +ConstantInt* const_int32_23 = ConstantInt::get(APInt(32, "1", 10)); +ConstantInt* const_int32_24 = ConstantInt::get(APInt(32, "3", 10)); +ConstantInt* const_int32_25 = ConstantInt::get(APInt(32, "2", 10)); +std::vector const_packed_26_elems; +const_packed_26_elems.push_back(const_float_21); +const_packed_26_elems.push_back(const_float_18); +const_packed_26_elems.push_back(const_float_18); +const_packed_26_elems.push_back(const_float_21); +Constant* const_packed_26 = ConstantVector::get(VectorTy_4, const_packed_26_elems); +Constant* const_double_27 = Constant::getNullValue(Type::DoubleTy); +std::vector const_packed_28_elems; +const_packed_28_elems.push_back(const_int32_19); +ConstantInt* const_int32_29 = ConstantInt::get(APInt(32, "5", 10)); +const_packed_28_elems.push_back(const_int32_29); +const_packed_28_elems.push_back(const_int32_25); +const_packed_28_elems.push_back(const_int32_24); +Constant* const_packed_28 = ConstantVector::get(VectorTy_7, const_packed_28_elems); +std::vector const_packed_30_elems; +const_packed_30_elems.push_back(const_int32_19); +const_packed_30_elems.push_back(const_int32_23); +ConstantInt* const_int32_31 = ConstantInt::get(APInt(32, "6", 10)); +const_packed_30_elems.push_back(const_int32_31); +const_packed_30_elems.push_back(const_int32_24); +Constant* const_packed_30 = ConstantVector::get(VectorTy_7, const_packed_30_elems); +std::vector const_packed_32_elems; +const_packed_32_elems.push_back(const_int32_19); +const_packed_32_elems.push_back(const_int32_23); +const_packed_32_elems.push_back(const_int32_25); +ConstantInt* const_int32_33 = ConstantInt::get(APInt(32, "7", 10)); +const_packed_32_elems.push_back(const_int32_33); +Constant* const_packed_32 = ConstantVector::get(VectorTy_7, const_packed_32_elems); +std::vector const_ptr_34_indices; +const_ptr_34_indices.push_back(const_int32_19); +const_ptr_34_indices.push_back(const_int32_19); +Constant* const_ptr_34 = ConstantExpr::getGetElementPtr(gvar_array__str, &const_ptr_34_indices[0], const_ptr_34_indices.size() ); +UndefValue* const_packed_35 = UndefValue::get(VectorTy_4); +std::vector const_ptr_36_indices; +const_ptr_36_indices.push_back(const_int32_19); +const_ptr_36_indices.push_back(const_int32_19); +Constant* const_ptr_36 = ConstantExpr::getGetElementPtr(gvar_array__str1, &const_ptr_36_indices[0], const_ptr_36_indices.size() ); + +// Global Variable Definitions +gvar_array__str->setInitializer(const_array_14); +gvar_array__str1->setInitializer(const_array_15); + +// Function Definitions + +// Function: approx (func_approx) +{ + Function::arg_iterator args = func_approx->arg_begin(); + Value* float_a = args++; + float_a->setName("a"); + Value* float_b = args++; + float_b->setName("b"); + + BasicBlock* label_entry = new BasicBlock("entry",func_approx,0); + + // Block entry (label_entry) + FCmpInst* int1_cmp = new FCmpInst(FCmpInst::FCMP_OLT, float_b, const_float_16, "cmp", label_entry); + SelectInst* float_b_addr_0 = new SelectInst(int1_cmp, const_float_16, float_b, "b.addr.0", label_entry); + FCmpInst* int1_cmp3 = new FCmpInst(FCmpInst::FCMP_OGT, float_b_addr_0, const_float_17, "cmp3", label_entry); + SelectInst* float_b_addr_1 = new SelectInst(int1_cmp3, const_float_17, float_b_addr_0, "b.addr.1", label_entry); + FCmpInst* int1_cmp7 = new FCmpInst(FCmpInst::FCMP_OLT, float_a, const_float_18, "cmp7", label_entry); + SelectInst* float_a_addr_0 = new SelectInst(int1_cmp7, const_float_18, float_a, "a.addr.0", label_entry); + std::vector float_call_params; + float_call_params.push_back(float_a_addr_0); + float_call_params.push_back(float_b_addr_1); + CallInst* float_call = new CallInst(func_powf, float_call_params.begin(), float_call_params.end(), "call", label_entry); + float_call->setCallingConv(CallingConv::C); + float_call->setTailCall(true);const ParamAttrsList *float_call_PAL = 0; + float_call->setParamAttrs(float_call_PAL); + + new ReturnInst(float_call, label_entry); + +} + +// Function: lit (func_lit) +{ + Function::arg_iterator args = func_lit->arg_begin(); + Value* packed_tmp = args++; + packed_tmp->setName("tmp"); + + BasicBlock* label_entry_38 = new BasicBlock("entry",func_lit,0); + BasicBlock* label_ifthen = new BasicBlock("ifthen",func_lit,0); + BasicBlock* label_UnifiedReturnBlock = new BasicBlock("UnifiedReturnBlock",func_lit,0); + + // Block entry (label_entry_38) + ExtractElementInst* float_tmp6 = new ExtractElementInst(packed_tmp, const_int32_19, "tmp6", label_entry_38); + FCmpInst* int1_cmp_39 = new FCmpInst(FCmpInst::FCMP_OGT, float_tmp6, const_float_18, "cmp", label_entry_38); + new BranchInst(label_ifthen, label_UnifiedReturnBlock, int1_cmp_39, label_entry_38); + + // Block ifthen (label_ifthen) + InsertElementInst* packed_tmp10 = new InsertElementInst(const_packed_20, float_tmp6, const_int32_23, "tmp10", label_ifthen); + ExtractElementInst* float_tmp12 = new ExtractElementInst(packed_tmp, const_int32_23, "tmp12", label_ifthen); + ExtractElementInst* float_tmp14 = new ExtractElementInst(packed_tmp, const_int32_24, "tmp14", label_ifthen); + std::vector float_call_41_params; + float_call_41_params.push_back(float_tmp12); + float_call_41_params.push_back(float_tmp14); + CallInst* float_call_41 = new CallInst(func_approx, float_call_41_params.begin(), float_call_41_params.end(), "call", label_ifthen); + float_call_41->setCallingConv(CallingConv::C); + float_call_41->setTailCall(true);const ParamAttrsList *float_call_41_PAL = 0; + float_call_41->setParamAttrs(float_call_41_PAL); + + InsertElementInst* packed_tmp16 = new InsertElementInst(packed_tmp10, float_call_41, const_int32_25, "tmp16", label_ifthen); + new ReturnInst(packed_tmp16, label_ifthen); + + // Block UnifiedReturnBlock (label_UnifiedReturnBlock) + new ReturnInst(const_packed_26, label_UnifiedReturnBlock); + +} + +// Function: cmp (func_cmp) +{ + Function::arg_iterator args = func_cmp->arg_begin(); + Value* packed_tmp0 = args++; + packed_tmp0->setName("tmp0"); + Value* packed_tmp1 = args++; + packed_tmp1->setName("tmp1"); + Value* packed_tmp2 = args++; + packed_tmp2->setName("tmp2"); + + BasicBlock* label_entry_44 = new BasicBlock("entry",func_cmp,0); + BasicBlock* label_cond__14 = new BasicBlock("cond.?14",func_cmp,0); + BasicBlock* label_cond_cont20 = new BasicBlock("cond.cont20",func_cmp,0); + BasicBlock* label_cond__28 = new BasicBlock("cond.?28",func_cmp,0); + BasicBlock* label_cond_cont34 = new BasicBlock("cond.cont34",func_cmp,0); + BasicBlock* label_cond__42 = new BasicBlock("cond.?42",func_cmp,0); + BasicBlock* label_cond_cont48 = new BasicBlock("cond.cont48",func_cmp,0); + + // Block entry (label_entry_44) + ExtractElementInst* float_tmp3 = new ExtractElementInst(packed_tmp0, const_int32_19, "tmp3", label_entry_44); + CastInst* double_conv = new FPExtInst(float_tmp3, Type::DoubleTy, "conv", label_entry_44); + FCmpInst* int1_cmp_45 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv, const_double_27, "cmp", label_entry_44); + ExtractElementInst* float_tmp11 = new ExtractElementInst(packed_tmp0, const_int32_23, "tmp11", label_entry_44); + CastInst* double_conv12 = new FPExtInst(float_tmp11, Type::DoubleTy, "conv12", label_entry_44); + FCmpInst* int1_cmp13 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv12, const_double_27, "cmp13", label_entry_44); + SelectInst* packed_tmp1_tmp2 = new SelectInst(int1_cmp_45, packed_tmp1, packed_tmp2, "tmp1.tmp2", label_entry_44); + new BranchInst(label_cond__14, label_cond_cont20, int1_cmp13, label_entry_44); + + // Block cond.?14 (label_cond__14) + ShuffleVectorInst* packed_tmp233 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp1, const_packed_28, "tmp233", label_cond__14); + ExtractElementInst* float_tmp254 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp254", label_cond__14); + CastInst* double_conv265 = new FPExtInst(float_tmp254, Type::DoubleTy, "conv265", label_cond__14); + FCmpInst* int1_cmp276 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv265, const_double_27, "cmp276", label_cond__14); + new BranchInst(label_cond__28, label_cond_cont34, int1_cmp276, label_cond__14); + + // Block cond.cont20 (label_cond_cont20) + ShuffleVectorInst* packed_tmp23 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp2, const_packed_28, "tmp23", label_cond_cont20); + ExtractElementInst* float_tmp25 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp25", label_cond_cont20); + CastInst* double_conv26 = new FPExtInst(float_tmp25, Type::DoubleTy, "conv26", label_cond_cont20); + FCmpInst* int1_cmp27 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv26, const_double_27, "cmp27", label_cond_cont20); + new BranchInst(label_cond__28, label_cond_cont34, int1_cmp27, label_cond_cont20); + + // Block cond.?28 (label_cond__28) + PHINode* packed_tmp23_reg2mem_0 = new PHINode(VectorTy_4, "tmp23.reg2mem.0", label_cond__28); + packed_tmp23_reg2mem_0->reserveOperandSpace(2); + packed_tmp23_reg2mem_0->addIncoming(packed_tmp233, label_cond__14); + packed_tmp23_reg2mem_0->addIncoming(packed_tmp23, label_cond_cont20); + + ShuffleVectorInst* packed_tmp378 = new ShuffleVectorInst(packed_tmp23_reg2mem_0, packed_tmp1, const_packed_30, "tmp378", label_cond__28); + ExtractElementInst* float_tmp399 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp399", label_cond__28); + CastInst* double_conv4010 = new FPExtInst(float_tmp399, Type::DoubleTy, "conv4010", label_cond__28); + FCmpInst* int1_cmp4111 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv4010, const_double_27, "cmp4111", label_cond__28); + new BranchInst(label_cond__42, label_cond_cont48, int1_cmp4111, label_cond__28); + + // Block cond.cont34 (label_cond_cont34) + PHINode* packed_tmp23_reg2mem_1 = new PHINode(VectorTy_4, "tmp23.reg2mem.1", label_cond_cont34); + packed_tmp23_reg2mem_1->reserveOperandSpace(2); + packed_tmp23_reg2mem_1->addIncoming(packed_tmp233, label_cond__14); + packed_tmp23_reg2mem_1->addIncoming(packed_tmp23, label_cond_cont20); + + ShuffleVectorInst* packed_tmp37 = new ShuffleVectorInst(packed_tmp23_reg2mem_1, packed_tmp2, const_packed_30, "tmp37", label_cond_cont34); + ExtractElementInst* float_tmp39 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp39", label_cond_cont34); + CastInst* double_conv40 = new FPExtInst(float_tmp39, Type::DoubleTy, "conv40", label_cond_cont34); + FCmpInst* int1_cmp41 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv40, const_double_27, "cmp41", label_cond_cont34); + new BranchInst(label_cond__42, label_cond_cont48, int1_cmp41, label_cond_cont34); + + // Block cond.?42 (label_cond__42) + PHINode* packed_tmp37_reg2mem_0 = new PHINode(VectorTy_4, "tmp37.reg2mem.0", label_cond__42); + packed_tmp37_reg2mem_0->reserveOperandSpace(2); + packed_tmp37_reg2mem_0->addIncoming(packed_tmp378, label_cond__28); + packed_tmp37_reg2mem_0->addIncoming(packed_tmp37, label_cond_cont34); + + ShuffleVectorInst* packed_tmp5113 = new ShuffleVectorInst(packed_tmp37_reg2mem_0, packed_tmp1, const_packed_32, "tmp5113", label_cond__42); + new ReturnInst(packed_tmp5113, label_cond__42); + + // Block cond.cont48 (label_cond_cont48) + PHINode* packed_tmp37_reg2mem_1 = new PHINode(VectorTy_4, "tmp37.reg2mem.1", label_cond_cont48); + packed_tmp37_reg2mem_1->reserveOperandSpace(2); + packed_tmp37_reg2mem_1->addIncoming(packed_tmp378, label_cond__28); + packed_tmp37_reg2mem_1->addIncoming(packed_tmp37, label_cond_cont34); + + ShuffleVectorInst* packed_tmp51 = new ShuffleVectorInst(packed_tmp37_reg2mem_1, packed_tmp2, const_packed_32, "tmp51", label_cond_cont48); + new ReturnInst(packed_tmp51, label_cond_cont48); + +} + +// Function: vcos (func_vcos) +{ + Function::arg_iterator args = func_vcos->arg_begin(); + Value* packed_val = args++; + packed_val->setName("val"); + + BasicBlock* label_entry_53 = new BasicBlock("entry",func_vcos,0); + + // Block entry (label_entry_53) + ExtractElementInst* float_tmp1 = new ExtractElementInst(packed_val, const_int32_19, "tmp1", label_entry_53); + CastInst* double_conv_54 = new FPExtInst(float_tmp1, Type::DoubleTy, "conv", label_entry_53); + ExtractElementInst* float_tmp3_55 = new ExtractElementInst(packed_val, const_int32_23, "tmp3", label_entry_53); + CastInst* double_conv4 = new FPExtInst(float_tmp3_55, Type::DoubleTy, "conv4", label_entry_53); + ExtractElementInst* float_tmp6_56 = new ExtractElementInst(packed_val, const_int32_25, "tmp6", label_entry_53); + CastInst* double_conv7 = new FPExtInst(float_tmp6_56, Type::DoubleTy, "conv7", label_entry_53); + ExtractElementInst* float_tmp9 = new ExtractElementInst(packed_val, const_int32_24, "tmp9", label_entry_53); + CastInst* double_conv10 = new FPExtInst(float_tmp9, Type::DoubleTy, "conv10", label_entry_53); + std::vector int32_call_params; + int32_call_params.push_back(const_ptr_34); + int32_call_params.push_back(double_conv_54); + int32_call_params.push_back(double_conv4); + int32_call_params.push_back(double_conv7); + int32_call_params.push_back(double_conv10); + CallInst* int32_call = new CallInst(func_printf, int32_call_params.begin(), int32_call_params.end(), "call", label_entry_53); + int32_call->setCallingConv(CallingConv::C); + int32_call->setTailCall(true);const ParamAttrsList *int32_call_PAL = 0; + int32_call->setParamAttrs(int32_call_PAL); + + CallInst* float_call13 = new CallInst(func_cosf, float_tmp1, "call13", label_entry_53); + float_call13->setCallingConv(CallingConv::C); + float_call13->setTailCall(true);const ParamAttrsList *float_call13_PAL = 0; + float_call13->setParamAttrs(float_call13_PAL); + + InsertElementInst* packed_tmp15 = new InsertElementInst(const_packed_35, float_call13, const_int32_19, "tmp15", label_entry_53); + CallInst* float_call18 = new CallInst(func_cosf, float_tmp1, "call18", label_entry_53); + float_call18->setCallingConv(CallingConv::C); + float_call18->setTailCall(true);const ParamAttrsList *float_call18_PAL = 0; + float_call18->setParamAttrs(float_call18_PAL); + + InsertElementInst* packed_tmp20 = new InsertElementInst(packed_tmp15, float_call18, const_int32_23, "tmp20", label_entry_53); + CallInst* float_call23 = new CallInst(func_cosf, float_tmp1, "call23", label_entry_53); + float_call23->setCallingConv(CallingConv::C); + float_call23->setTailCall(true);const ParamAttrsList *float_call23_PAL = 0; + float_call23->setParamAttrs(float_call23_PAL); + + InsertElementInst* packed_tmp25 = new InsertElementInst(packed_tmp20, float_call23, const_int32_25, "tmp25", label_entry_53); + CallInst* float_call28 = new CallInst(func_cosf, float_tmp1, "call28", label_entry_53); + float_call28->setCallingConv(CallingConv::C); + float_call28->setTailCall(true);const ParamAttrsList *float_call28_PAL = 0; + float_call28->setParamAttrs(float_call28_PAL); + + InsertElementInst* packed_tmp30 = new InsertElementInst(packed_tmp25, float_call28, const_int32_24, "tmp30", label_entry_53); + CastInst* double_conv33 = new FPExtInst(float_call13, Type::DoubleTy, "conv33", label_entry_53); + CastInst* double_conv36 = new FPExtInst(float_call18, Type::DoubleTy, "conv36", label_entry_53); + CastInst* double_conv39 = new FPExtInst(float_call23, Type::DoubleTy, "conv39", label_entry_53); + CastInst* double_conv42 = new FPExtInst(float_call28, Type::DoubleTy, "conv42", label_entry_53); + std::vector int32_call43_params; + int32_call43_params.push_back(const_ptr_36); + int32_call43_params.push_back(double_conv33); + int32_call43_params.push_back(double_conv36); + int32_call43_params.push_back(double_conv39); + int32_call43_params.push_back(double_conv42); + CallInst* int32_call43 = new CallInst(func_printf, int32_call43_params.begin(), int32_call43_params.end(), "call43", label_entry_53); + int32_call43->setCallingConv(CallingConv::C); + int32_call43->setTailCall(true);const ParamAttrsList *int32_call43_PAL = 0; + int32_call43->setParamAttrs(int32_call43_PAL); + + new ReturnInst(packed_tmp30, label_entry_53); + +} + +// Function: scs (func_scs) +{ + Function::arg_iterator args = func_scs->arg_begin(); + Value* packed_val_58 = args++; + packed_val_58->setName("val"); + + BasicBlock* label_entry_59 = new BasicBlock("entry",func_scs,0); + + // Block entry (label_entry_59) + ExtractElementInst* float_tmp2 = new ExtractElementInst(packed_val_58, const_int32_19, "tmp2", label_entry_59); + CallInst* float_call_60 = new CallInst(func_cosf, float_tmp2, "call", label_entry_59); + float_call_60->setCallingConv(CallingConv::C); + float_call_60->setTailCall(true);const ParamAttrsList *float_call_60_PAL = 0; + float_call_60->setParamAttrs(float_call_60_PAL); + + InsertElementInst* packed_tmp5 = new InsertElementInst(const_packed_35, float_call_60, const_int32_19, "tmp5", label_entry_59); + CallInst* float_call7 = new CallInst(func_sinf, float_tmp2, "call7", label_entry_59); + float_call7->setCallingConv(CallingConv::C); + float_call7->setTailCall(true);const ParamAttrsList *float_call7_PAL = 0; + float_call7->setParamAttrs(float_call7_PAL); + + InsertElementInst* packed_tmp9 = new InsertElementInst(packed_tmp5, float_call7, const_int32_23, "tmp9", label_entry_59); + new ReturnInst(packed_tmp9, label_entry_59); + +} + +// Function: vsin (func_vsin) +{ + Function::arg_iterator args = func_vsin->arg_begin(); + Value* packed_val_62 = args++; + packed_val_62->setName("val"); + + BasicBlock* label_entry_63 = new BasicBlock("entry",func_vsin,0); + + // Block entry (label_entry_63) + ExtractElementInst* float_tmp2_64 = new ExtractElementInst(packed_val_62, const_int32_19, "tmp2", label_entry_63); + CallInst* float_call_65 = new CallInst(func_sinf, float_tmp2_64, "call", label_entry_63); + float_call_65->setCallingConv(CallingConv::C); + float_call_65->setTailCall(true);const ParamAttrsList *float_call_65_PAL = 0; + float_call_65->setParamAttrs(float_call_65_PAL); + + InsertElementInst* packed_tmp6 = new InsertElementInst(const_packed_35, float_call_65, const_int32_19, "tmp6", label_entry_63); + InsertElementInst* packed_tmp9_66 = new InsertElementInst(packed_tmp6, float_call_65, const_int32_23, "tmp9", label_entry_63); + InsertElementInst* packed_tmp12 = new InsertElementInst(packed_tmp9_66, float_call_65, const_int32_25, "tmp12", label_entry_63); + InsertElementInst* packed_tmp15_67 = new InsertElementInst(packed_tmp12, float_call_65, const_int32_24, "tmp15", label_entry_63); + new ReturnInst(packed_tmp15_67, label_entry_63); + +} + +// Function: kilp (func_kilp) +{ + Function::arg_iterator args = func_kilp->arg_begin(); + Value* packed_val_69 = args++; + packed_val_69->setName("val"); + + BasicBlock* label_entry_70 = new BasicBlock("entry",func_kilp,0); + BasicBlock* label_lor_rhs = new BasicBlock("lor_rhs",func_kilp,0); + BasicBlock* label_lor_rhs5 = new BasicBlock("lor_rhs5",func_kilp,0); + BasicBlock* label_lor_rhs11 = new BasicBlock("lor_rhs11",func_kilp,0); + BasicBlock* label_UnifiedReturnBlock_71 = new BasicBlock("UnifiedReturnBlock",func_kilp,0); + + // Block entry (label_entry_70) + ExtractElementInst* float_tmp1_72 = new ExtractElementInst(packed_val_69, const_int32_19, "tmp1", label_entry_70); + FCmpInst* int1_cmp_73 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp1_72, const_float_18, "cmp", label_entry_70); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs, int1_cmp_73, label_entry_70); + + // Block lor_rhs (label_lor_rhs) + ExtractElementInst* float_tmp3_75 = new ExtractElementInst(packed_val_69, const_int32_23, "tmp3", label_lor_rhs); + FCmpInst* int1_cmp4 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp3_75, const_float_18, "cmp4", label_lor_rhs); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs5, int1_cmp4, label_lor_rhs); + + // Block lor_rhs5 (label_lor_rhs5) + ExtractElementInst* float_tmp7 = new ExtractElementInst(packed_val_69, const_int32_25, "tmp7", label_lor_rhs5); + FCmpInst* int1_cmp8 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp7, const_float_18, "cmp8", label_lor_rhs5); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs11, int1_cmp8, label_lor_rhs5); + + // Block lor_rhs11 (label_lor_rhs11) + ExtractElementInst* float_tmp13 = new ExtractElementInst(packed_val_69, const_int32_24, "tmp13", label_lor_rhs11); + FCmpInst* int1_cmp14 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp13, const_float_18, "cmp14", label_lor_rhs11); + CastInst* int32_retval = new ZExtInst(int1_cmp14, IntegerType::get(32), "retval", label_lor_rhs11); + new ReturnInst(int32_retval, label_lor_rhs11); + + // Block UnifiedReturnBlock (label_UnifiedReturnBlock_71) + new ReturnInst(const_int32_23, label_UnifiedReturnBlock_71); + +} + +return mod; + +} diff --git a/src/gallium/auxiliary/llvm/gallivm_cpu.cpp b/src/gallium/auxiliary/llvm/gallivm_cpu.cpp new file mode 100644 index 0000000000..8f9830d0b1 --- /dev/null +++ b/src/gallium/auxiliary/llvm/gallivm_cpu.cpp @@ -0,0 +1,202 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "instructions.h" +#include "loweringpass.h" +#include "storage.h" +#include "tgsitollvm.h" + +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_dump.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct gallivm_cpu_engine { + llvm::ExecutionEngine *engine; +}; + +static struct gallivm_cpu_engine *CPU = 0; + +typedef int (*fragment_shader_runner)(float x, float y, + float (*dests)[16][4], + float (*inputs)[16][4], + int num_attribs, + float (*consts)[4], int num_consts, + struct tgsi_sampler *samplers); + +int gallivm_cpu_fs_exec(struct gallivm_prog *prog, + float fx, float fy, + float (*dests)[16][4], + float (*inputs)[16][4], + float (*consts)[4], + struct tgsi_sampler *samplers) +{ + fragment_shader_runner runner = reinterpret_cast(prog->function); + assert(runner); + + return runner(fx, fy, dests, inputs, prog->num_interp, + consts, prog->num_consts, + samplers); +} + +static inline llvm::Function *func_for_shader(struct gallivm_prog *prog) +{ + llvm::Module *mod = prog->module; + llvm::Function *func = 0; + + switch (prog->type) { + case GALLIVM_VS: + func = mod->getFunction("vs_shader"); + break; + case GALLIVM_FS: + func = mod->getFunction("fs_shader"); + break; + default: + assert(!"Unknown shader type!"); + break; + } + return func; +} + +/*! + This function creates a CPU based execution engine for the given gallivm_prog. + gallivm_cpu_engine should be used as a singleton throughout the library. Before + executing gallivm_prog_exec one needs to call gallivm_cpu_jit_compile. + The gallivm_prog instance which is being passed to the constructor is being + automatically JIT compiled so one shouldn't call gallivm_cpu_jit_compile + with it again. + */ +struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog) +{ + struct gallivm_cpu_engine *cpu = (struct gallivm_cpu_engine *) + calloc(1, sizeof(struct gallivm_cpu_engine)); + llvm::Module *mod = static_cast(prog->module); + llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); + llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false); + ee->DisableLazyCompilation(); + cpu->engine = ee; + + llvm::Function *func = func_for_shader(prog); + + prog->function = ee->getPointerToFunction(func); + CPU = cpu; + return cpu; +} + + +/*! + This function JIT compiles the given gallivm_prog with the given cpu based execution engine. + The reference to the generated machine code entry point will be stored + in the gallivm_prog program. After executing this function one can call gallivm_prog_exec + in order to execute the gallivm_prog on the CPU. + */ +void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog *prog) +{ + llvm::Module *mod = static_cast(prog->module); + llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); + llvm::ExecutionEngine *ee = cpu->engine; + assert(ee); + /*FIXME : remove */ + ee->DisableLazyCompilation(); + ee->addModuleProvider(mp); + + llvm::Function *func = func_for_shader(prog); + prog->function = ee->getPointerToFunction(func); +} + +void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu) +{ + free(cpu); +} + +struct gallivm_cpu_engine * gallivm_global_cpu_engine() +{ + return CPU; +} + + +typedef void (*vertex_shader_runner)(void *ainputs, + void *dests, + float (*aconsts)[4], + void *temps); + + +/*! + This function is used to execute the gallivm_prog in software. Before calling + this function the gallivm_prog has to be JIT compiled with the gallivm_cpu_jit_compile + function. + */ +int gallivm_cpu_vs_exec(struct gallivm_prog *prog, + struct tgsi_exec_vector *inputs, + struct tgsi_exec_vector *dests, + float (*consts)[4], + struct tgsi_exec_vector *temps) +{ + vertex_shader_runner runner = reinterpret_cast(prog->function); + assert(runner); + /*FIXME*/ + runner(inputs, dests, consts, temps); + + return 0; +} + +#endif diff --git a/src/gallium/auxiliary/llvm/gallivm_p.h b/src/gallium/auxiliary/llvm/gallivm_p.h new file mode 100644 index 0000000000..cfe7b1901b --- /dev/null +++ b/src/gallium/auxiliary/llvm/gallivm_p.h @@ -0,0 +1,110 @@ +#ifndef GALLIVM_P_H +#define GALLIVM_P_H + +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_compiler.h" + +namespace llvm { + class Module; +} + +#if defined __cplusplus +extern "C" { +#endif + +enum gallivm_shader_type; +enum gallivm_vector_layout; + +struct gallivm_interpolate { + int attrib; + int chan; + int type; +}; + +struct gallivm_ir { + llvm::Module *module; + int id; + enum gallivm_shader_type type; + enum gallivm_vector_layout layout; + int num_components; + int num_consts; + + //FIXME: this might not be enough for some shaders + struct gallivm_interpolate interpolators[32*4]; + int num_interp; +}; + +struct gallivm_prog { + llvm::Module *module; + void *function; + + int id; + enum gallivm_shader_type type; + + int num_consts; + + //FIXME: this might not be enough for some shaders + struct gallivm_interpolate interpolators[32*4]; + int num_interp; +}; + +static INLINE void gallivm_swizzle_components(int swizzle, + int *xc, int *yc, + int *zc, int *wc) +{ + int x = swizzle / 1000; swizzle -= x * 1000; + int y = swizzle / 100; swizzle -= y * 100; + int z = swizzle / 10; swizzle -= z * 10; + int w = swizzle; + + if (xc) *xc = x; + if (yc) *yc = y; + if (zc) *zc = z; + if (wc) *wc = w; +} + +static INLINE boolean gallivm_is_swizzle(int swizzle) +{ + const int NO_SWIZZLE = TGSI_SWIZZLE_X * 1000 + TGSI_SWIZZLE_Y * 100 + + TGSI_SWIZZLE_Z * 10 + TGSI_SWIZZLE_W; + return swizzle != NO_SWIZZLE; +} + +static INLINE int gallivm_x_swizzle(int swizzle) +{ + int x; + gallivm_swizzle_components(swizzle, &x, 0, 0, 0); + return x; +} + +static INLINE int gallivm_y_swizzle(int swizzle) +{ + int y; + gallivm_swizzle_components(swizzle, 0, &y, 0, 0); + return y; +} + +static INLINE int gallivm_z_swizzle(int swizzle) +{ + int z; + gallivm_swizzle_components(swizzle, 0, 0, &z, 0); + return z; +} + +static INLINE int gallivm_w_swizzle(int swizzle) +{ + int w; + gallivm_swizzle_components(swizzle, 0, 0, 0, &w); + return w; +} + +#endif /* MESA_LLVM */ + +#if defined __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/gallium/auxiliary/llvm/instructions.cpp b/src/gallium/auxiliary/llvm/instructions.cpp new file mode 100644 index 0000000000..55d39fa5f1 --- /dev/null +++ b/src/gallium/auxiliary/llvm/instructions.cpp @@ -0,0 +1,889 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "instructions.h" + +#include "storage.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace llvm; + +#include "gallivm_builtins.cpp" + +static inline std::string createFuncName(int label) +{ + std::ostringstream stream; + stream << "function"; + stream << label; + return stream.str(); +} + +Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, + Storage *storage) + : m_mod(mod), m_func(func), m_builder(block), m_idx(0), + m_storage(storage) +{ + m_floatVecType = VectorType::get(Type::FloatTy, 4); + + m_llvmFSqrt = 0; + m_llvmFAbs = 0; + m_llvmPow = 0; + m_llvmFloor = 0; + m_llvmFlog = 0; + m_llvmLit = 0; + m_fmtPtr = 0; + + createGallivmBuiltins(m_mod); +} + +llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2) +{ + return m_builder.CreateAdd(in1, in2, name("add")); +} + +llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3) +{ + Value *mulRes = mul(in1, in2); + return add(mulRes, in3); +} + +llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2) +{ + return m_builder.CreateMul(in1, in2, name("mul")); +} + +const char * Instructions::name(const char *prefix) +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + Value *x = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(0), + name("extractx")); + Value *y = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(1), + name("extracty")); + Value *z = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(2), + name("extractz")); + Value *xy = m_builder.CreateAdd(x, y,name("xy")); + Value *dot3 = m_builder.CreateAdd(xy, z, name("dot3")); + return vectorFromVals(dot3, dot3, dot3, dot3); +} + +llvm::Value *Instructions::callFSqrt(llvm::Value *val) +{ + if (!m_llvmFSqrt) { + // predeclare the intrinsic + std::vector fsqrtArgs; + fsqrtArgs.push_back(Type::FloatTy); + ParamAttrsList *fsqrtPal = 0; + FunctionType* fsqrtType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/fsqrtArgs, + /*isVarArg=*/false); + m_llvmFSqrt = new Function( + /*Type=*/fsqrtType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"llvm.sqrt.f32", m_mod); + m_llvmFSqrt->setCallingConv(CallingConv::C); + m_llvmFSqrt->setParamAttrs(fsqrtPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFSqrt, val, + name("sqrt")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::rsq(llvm::Value *in1) +{ + Value *x = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("extractx")); + Value *abs = callFAbs(x); + Value *sqrt = callFSqrt(abs); + + Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, + APFloat(1.f)), + sqrt, + name("rsqrt")); + return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt); +} + +llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w) +{ + Constant *const_vec = Constant::getNullValue(m_floatVecType); + Value *res = m_builder.CreateInsertElement(const_vec, x, + m_storage->constantInt(0), + name("vecx")); + res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), + name("vecxy")); + res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), + name("vecxyz")); + if (w) + res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), + name("vecxyzw")); + return res; +} + +llvm::Value *Instructions::callFAbs(llvm::Value *val) +{ + if (!m_llvmFAbs) { + // predeclare the intrinsic + std::vector fabsArgs; + fabsArgs.push_back(Type::FloatTy); + ParamAttrsList *fabsPal = 0; + FunctionType* fabsType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/fabsArgs, + /*isVarArg=*/false); + m_llvmFAbs = new Function( + /*Type=*/fabsType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"fabs", m_mod); + m_llvmFAbs->setCallingConv(CallingConv::C); + m_llvmFAbs->setParamAttrs(fabsPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFAbs, val, + name("fabs")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::lit(llvm::Value *in) +{ + if (!m_llvmLit) { + m_llvmLit = m_mod->getFunction("lit"); + } + CallInst *call = m_builder.CreateCall(m_llvmLit, in, name("litres")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2) +{ + Value *res = m_builder.CreateSub(in1, in2, name("sub")); + return res; +} + +llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2) +{ + if (!m_llvmPow) { + // predeclare the intrinsic + std::vector powArgs; + powArgs.push_back(Type::FloatTy); + powArgs.push_back(Type::FloatTy); + ParamAttrsList *powPal = 0; + FunctionType* powType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/powArgs, + /*isVarArg=*/false); + m_llvmPow = new Function( + /*Type=*/powType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"llvm.pow.f32", m_mod); + m_llvmPow->setCallingConv(CallingConv::C); + m_llvmPow->setParamAttrs(powPal); + } + std::vector params; + params.push_back(val1); + params.push_back(val2); + CallInst *call = m_builder.CreateCall(m_llvmPow, params.begin(), params.end(), + name("pow")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *x2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(0), + name("x2")); + llvm::Value *val = callPow(x1, x2); + return vectorFromVals(val, val, val, val); +} + +llvm::Value * Instructions::rcp(llvm::Value *in1) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *res = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, + APFloat(1.f)), + x1, name("rcp")); + return vectorFromVals(res, res, res, res); +} + +llvm::Value * Instructions::dp4(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + std::vector vec = extractVector(mulRes); + Value *xy = m_builder.CreateAdd(vec[0], vec[1], name("xy")); + Value *xyz = m_builder.CreateAdd(xy, vec[2], name("xyz")); + Value *dot4 = m_builder.CreateAdd(xyz, vec[3], name("dot4")); + return vectorFromVals(dot4, dot4, dot4, dot4); +} + +llvm::Value * Instructions::dph(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + std::vector vec1 = extractVector(mulRes); + Value *xy = m_builder.CreateAdd(vec1[0], vec1[1], name("xy")); + Value *xyz = m_builder.CreateAdd(xy, vec1[2], name("xyz")); + Value *dph = m_builder.CreateAdd(xyz, vec1[3], name("dph")); + return vectorFromVals(dph, dph, dph, dph); +} + +llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2) +{ + Value *y1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(1), + name("y1")); + Value *z = m_builder.CreateExtractElement(in1, + m_storage->constantInt(2), + name("z")); + Value *y2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(1), + name("y2")); + Value *w = m_builder.CreateExtractElement(in2, + m_storage->constantInt(3), + name("w")); + Value *ry = m_builder.CreateMul(y1, y2, name("tyuy")); + return vectorFromVals(ConstantFP::get(Type::FloatTy, APFloat(1.f)), + ry, z, w); +} + +llvm::Value * Instructions::ex2(llvm::Value *in) +{ + llvm::Value *val = callPow(ConstantFP::get(Type::FloatTy, APFloat(2.f)), + m_builder.CreateExtractElement( + in, m_storage->constantInt(0), + name("x1"))); + return vectorFromVals(val, val, val, val); +} + +llvm::Value * Instructions::callFloor(llvm::Value *val) +{ + if (!m_llvmFloor) { + // predeclare the intrinsic + std::vector floorArgs; + floorArgs.push_back(Type::FloatTy); + ParamAttrsList *floorPal = 0; + FunctionType* floorType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/floorArgs, + /*isVarArg=*/false); + m_llvmFloor = new Function( + /*Type=*/floorType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"floorf", m_mod); + m_llvmFloor->setCallingConv(CallingConv::C); + m_llvmFloor->setParamAttrs(floorPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFloor, val, + name("floorf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::floor(llvm::Value *in) +{ + std::vector vec = extractVector(in); + return vectorFromVals(callFloor(vec[0]), callFloor(vec[1]), + callFloor(vec[2]), callFloor(vec[3])); +} + +llvm::Value * Instructions::arl(llvm::Value *in) +{ + return floor(in); +} + +llvm::Value * Instructions::frc(llvm::Value *in) +{ + llvm::Value *flr = floor(in); + return sub(in, flr); +} + +llvm::Value * Instructions::callFLog(llvm::Value *val) +{ + if (!m_llvmFlog) { + // predeclare the intrinsic + std::vector flogArgs; + flogArgs.push_back(Type::FloatTy); + ParamAttrsList *flogPal = 0; + FunctionType* flogType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/flogArgs, + /*isVarArg=*/false); + m_llvmFlog = new Function( + /*Type=*/flogType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"logf", m_mod); + m_llvmFlog->setCallingConv(CallingConv::C); + m_llvmFlog->setParamAttrs(flogPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFlog, val, + name("logf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::lg2(llvm::Value *in) +{ + std::vector vec = extractVector(in); + llvm::Value *const_vec = constVector(1.442695f, 1.442695f, + 1.442695f, 1.442695f); + return mul(vectorFromVals(callFLog(vec[0]), callFLog(vec[1]), + callFLog(vec[2]), callFLog(vec[3])), const_vec); +} + +llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2) +{ + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); + Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], + name("selx")); + + Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); + Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], + name("sely")); + + Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); + Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], + name("selz")); + + Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); + Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], + name("selw")); + + return vectorFromVals(selx, sely, selz, selw); +} + +llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2) +{ + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], + name("xcmp")); + Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], + name("selx")); + + Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], + name("ycmp")); + Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], + name("sely")); + + Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], + name("zcmp")); + Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], + name("selz")); + + Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], + name("wcmp")); + Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], + name("selw")); + + return vectorFromVals(selx, sely, selz, selw); +} + +void Instructions::printVector(llvm::Value *val) +{ + static const char *frmt = "Vector is [%f, %f, %f, %f]\x0A"; + + if (!m_fmtPtr) { + Constant *format = ConstantArray::get(frmt, true); + ArrayType *arrayTy = ArrayType::get(IntegerType::get(8), strlen(frmt) + 1); + GlobalVariable* globalFormat = new GlobalVariable( + /*Type=*/arrayTy, + /*isConstant=*/true, + /*Linkage=*/GlobalValue::InternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name(".str"), + m_mod); + globalFormat->setInitializer(format); + + Constant* const_int0 = Constant::getNullValue(IntegerType::get(32)); + std::vector const_ptr_21_indices; + const_ptr_21_indices.push_back(const_int0); + const_ptr_21_indices.push_back(const_int0); + m_fmtPtr = ConstantExpr::getGetElementPtr(globalFormat, + &const_ptr_21_indices[0], const_ptr_21_indices.size()); + } + + Function *func_printf = m_mod->getFunction("printf"); + if (!func_printf) + func_printf = declarePrintf(); + assert(func_printf); + std::vector vec = extractVector(val); + Value *dx = m_builder.CreateFPExt(vec[0], Type::DoubleTy, name("dx")); + Value *dy = m_builder.CreateFPExt(vec[1], Type::DoubleTy, name("dy")); + Value *dz = m_builder.CreateFPExt(vec[2], Type::DoubleTy, name("dz")); + Value *dw = m_builder.CreateFPExt(vec[3], Type::DoubleTy, name("dw")); + std::vector params; + params.push_back(m_fmtPtr); + params.push_back(dx); + params.push_back(dy); + params.push_back(dz); + params.push_back(dw); + CallInst *call = m_builder.CreateCall(func_printf, params.begin(), params.end(), + name("printf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(true); +} + +llvm::Function * Instructions::declarePrintf() +{ + std::vector args; + ParamAttrsList *params = 0; + FunctionType* funcTy = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/args, + /*isVarArg=*/true); + Function* func_printf = new Function( + /*Type=*/funcTy, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"printf", m_mod); + func_printf->setCallingConv(CallingConv::C); + func_printf->setParamAttrs(params); + return func_printf; +} + + +llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} +llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} + + +llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} + +llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *y1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(1), + name("y1")); + Value *z1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(2), + name("z1")); + + Value *x2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(0), + name("x2")); + Value *y2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(1), + name("y2")); + Value *z2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(2), + name("z2")); + Value *y1z2 = mul(y1, z2); + Value *z1y2 = mul(z1, y2); + + Value *z1x2 = mul(z1, x2); + Value *x1z2 = mul(x1, z2); + + Value *x1y2 = mul(x1, y2); + Value *y1x2 = mul(y1, x2); + + return vectorFromVals(sub(y1z2, z1y2), sub(z1x2, x1z2), sub(x1y2, y1x2)); +} + + +llvm::Value * Instructions::abs(llvm::Value *in) +{ + std::vector vec = extractVector(in); + Value *xabs = callFAbs(vec[0]); + Value *yabs = callFAbs(vec[1]); + Value *zabs = callFAbs(vec[2]); + Value *wabs = callFAbs(vec[3]); + return vectorFromVals(xabs, yabs, zabs, wabs); +} + +void Instructions::ifop(llvm::Value *in) +{ + BasicBlock *ifthen = new BasicBlock(name("ifthen"), m_func,0); + BasicBlock *ifend = new BasicBlock(name("ifthenend"), m_func,0); + + //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0); + //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0); + //BasicBlock *wblock = new BasicBlock(name("wblock"), m_func,0); + + Constant *float0 = Constant::getNullValue(Type::FloatTy); + + Value *x = m_builder.CreateExtractElement(in, m_storage->constantInt(0), + name("extractx")); + Value *xcmp = m_builder.CreateFCmpUNE(x, float0, name("xcmp")); + m_builder.CreateCondBr(xcmp, ifthen, ifend); + //m_builder.SetInsertPoint(yblock); + + m_builder.SetInsertPoint(ifthen); + m_ifStack.push(ifend); +} + +llvm::BasicBlock * Instructions::currentBlock() const +{ + return m_builder.GetInsertBlock(); +} + +void Instructions::elseop() +{ + assert(!m_ifStack.empty()); + BasicBlock *ifend = new BasicBlock(name("ifend"), m_func,0); + m_builder.CreateBr(ifend); + m_builder.SetInsertPoint(m_ifStack.top()); + currentBlock()->setName(name("ifelse")); + m_ifStack.pop(); + m_ifStack.push(ifend); +} + +void Instructions::endif() +{ + assert(!m_ifStack.empty()); + m_builder.CreateBr(m_ifStack.top()); + m_builder.SetInsertPoint(m_ifStack.top()); + m_ifStack.pop(); +} + +llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3) +{ + llvm::Value *m = mul(in1, in2); + llvm::Value *vec1 = constVector(1.f, 1.f, 1.f, 1.f); + llvm::Value *s = sub(vec1, in1); + return add(m, mul(s, in3)); +} + +void Instructions::beginLoop() +{ + BasicBlock *begin = new BasicBlock(name("loop"), m_func,0); + BasicBlock *end = new BasicBlock(name("endloop"), m_func,0); + + m_builder.CreateBr(begin); + Loop loop; + loop.begin = begin; + loop.end = end; + m_builder.SetInsertPoint(begin); + m_loopStack.push(loop); +} + +void Instructions::endLoop() +{ + assert(!m_loopStack.empty()); + Loop loop = m_loopStack.top(); + m_builder.CreateBr(loop.begin); + loop.end->moveAfter(currentBlock()); + m_builder.SetInsertPoint(loop.end); + m_loopStack.pop(); +} + +void Instructions::brk() +{ + assert(!m_loopStack.empty()); + BasicBlock *unr = new BasicBlock(name("unreachable"), m_func,0); + m_builder.CreateBr(m_loopStack.top().end); + m_builder.SetInsertPoint(unr); +} + +llvm::Value * Instructions::trunc(llvm::Value *in) +{ + std::vector vec = extractVector(in); + Value *icastx = m_builder.CreateFPToSI(vec[0], IntegerType::get(32), + name("ftoix")); + Value *icasty = m_builder.CreateFPToSI(vec[1], IntegerType::get(32), + name("ftoiy")); + Value *icastz = m_builder.CreateFPToSI(vec[2], IntegerType::get(32), + name("ftoiz")); + Value *icastw = m_builder.CreateFPToSI(vec[3], IntegerType::get(32), + name("ftoiw")); + Value *fx = m_builder.CreateSIToFP(icastx, Type::FloatTy, + name("fx")); + Value *fy = m_builder.CreateSIToFP(icasty, Type::FloatTy, + name("fy")); + Value *fz = m_builder.CreateSIToFP(icastz, Type::FloatTy, + name("fz")); + Value *fw = m_builder.CreateSIToFP(icastw, Type::FloatTy, + name("fw")); + return vectorFromVals(fx, fy, fz, fw); +} + +void Instructions::end() +{ + m_builder.CreateRetVoid(); +} + +void Instructions::cal(int label, llvm::Value *input) +{ + std::vector params; + params.push_back(input); + llvm::Function *func = findFunction(label); + + m_builder.CreateCall(func, params.begin(), params.end()); +} + +llvm::Function * Instructions::declareFunc(int label) +{ + PointerType *vecPtr = PointerType::getUnqual(m_floatVecType); + std::vector args; + args.push_back(vecPtr); + args.push_back(vecPtr); + args.push_back(vecPtr); + args.push_back(vecPtr); + ParamAttrsList *params = 0; + FunctionType *funcType = FunctionType::get( + /*Result=*/Type::VoidTy, + /*Params=*/args, + /*isVarArg=*/false); + std::string name = createFuncName(label); + Function *func = new Function( + /*Type=*/funcType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/name.c_str(), m_mod); + func->setCallingConv(CallingConv::C); + func->setParamAttrs(params); + return func; +} + +void Instructions::bgnSub(unsigned label) +{ + llvm::Function *func = findFunction(label); + + Function::arg_iterator args = func->arg_begin(); + Value *ptr_INPUT = args++; + ptr_INPUT->setName("INPUT"); + m_storage->pushArguments(ptr_INPUT); + + llvm::BasicBlock *entry = new BasicBlock("entry", func, 0); + + m_func = func; + m_builder.SetInsertPoint(entry); +} + +void Instructions::endSub() +{ + m_func = 0; + m_builder.SetInsertPoint(0); +} + +llvm::Function * Instructions::findFunction(int label) +{ + llvm::Function *func = m_functions[label]; + if (!func) { + func = declareFunc(label); + m_functions[label] = func; + } + return func; +} + +llvm::Value * Instructions::constVector(float x, float y, float z, float w) +{ + std::vector vec(4); + vec[0] = ConstantFP::get(Type::FloatTy, APFloat(x)); + vec[1] = ConstantFP::get(Type::FloatTy, APFloat(y)); + vec[2] = ConstantFP::get(Type::FloatTy, APFloat(z)); + vec[3] = ConstantFP::get(Type::FloatTy, APFloat(w)); + return ConstantVector::get(m_floatVecType, vec); +} + + +std::vector Instructions::extractVector(llvm::Value *vec) +{ + std::vector elems(4); + elems[0] = m_builder.CreateExtractElement(vec, m_storage->constantInt(0), + name("x")); + elems[1] = m_builder.CreateExtractElement(vec, m_storage->constantInt(1), + name("y")); + elems[2] = m_builder.CreateExtractElement(vec, m_storage->constantInt(2), + name("z")); + elems[3] = m_builder.CreateExtractElement(vec, m_storage->constantInt(3), + name("w")); + return elems; +} + +llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) +{ + llvm::Function *func = m_mod->getFunction("cmp"); + assert(func); + + std::vector params; + params.push_back(in1); + params.push_back(in2); + params.push_back(in3); + CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), name("cmpres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::cos(llvm::Value *in) +{ +#if 0 + llvm::Function *func = m_mod->getFunction("vcos"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("cosres")); + call->setTailCall(false); + return call; +#else + std::vector elems = extractVector(in); + Function *func = m_mod->getFunction("cosf"); + assert(func); + CallInst *cos = m_builder.CreateCall(func, elems[0], name("cosres")); + cos->setCallingConv(CallingConv::C); + cos->setTailCall(true); + return vectorFromVals(cos, cos, cos, cos); +#endif +} + +llvm::Value * Instructions::scs(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("scs"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("scsres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::kilp(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("kilp"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("kilpres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::sin(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("vsin"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("sinres")); + call->setTailCall(false); + return call; +} +#endif //MESA_LLVM + + diff --git a/src/gallium/auxiliary/llvm/instructions.h b/src/gallium/auxiliary/llvm/instructions.h new file mode 100644 index 0000000000..9ebc17dd8e --- /dev/null +++ b/src/gallium/auxiliary/llvm/instructions.h @@ -0,0 +1,152 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef INSTRUCTIONS_H +#define INSTRUCTIONS_H + +#include +#include +#include +#include + +#include +#include + +namespace llvm { + class VectorType; + class Function; +} + +class Storage; + +class Instructions +{ +public: + Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, + Storage *storage); + + llvm::BasicBlock *currentBlock() const; + + llvm::Value *abs(llvm::Value *in1); + llvm::Value *arl(llvm::Value *in1); + llvm::Value *add(llvm::Value *in1, llvm::Value *in2); + void beginLoop(); + void bgnSub(unsigned); + void brk(); + void cal(int label, llvm::Value *input); + llvm::Value *cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); + llvm::Value *cos(llvm::Value *in); + llvm::Value *cross(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dp3(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dp4(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dph(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dst(llvm::Value *in1, llvm::Value *in2); + void elseop(); + void endif(); + void endLoop(); + void end(); + void endSub(); + llvm::Value *ex2(llvm::Value *in); + llvm::Value *floor(llvm::Value *in); + llvm::Value *frc(llvm::Value *in); + void ifop(llvm::Value *in); + llvm::Value *kilp(llvm::Value *in); + llvm::Value *lerp(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3); + llvm::Value *lit(llvm::Value *in); + llvm::Value *lg2(llvm::Value *in); + llvm::Value *madd(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in2); + llvm::Value *min(llvm::Value *in1, llvm::Value *in2); + llvm::Value *max(llvm::Value *in1, llvm::Value *in2); + llvm::Value *mul(llvm::Value *in1, llvm::Value *in2); + llvm::Value *pow(llvm::Value *in1, llvm::Value *in2); + llvm::Value *rcp(llvm::Value *in); + llvm::Value *rsq(llvm::Value *in); + llvm::Value *scs(llvm::Value *in); + llvm::Value *sge(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sgt(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sin(llvm::Value *in); + llvm::Value *slt(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sub(llvm::Value *in1, llvm::Value *in2); + llvm::Value *trunc(llvm::Value *in); + + void printVector(llvm::Value *val); +private: + const char *name(const char *prefix); + + llvm::Value *callFAbs(llvm::Value *val); + llvm::Value *callFloor(llvm::Value *val); + llvm::Value *callFSqrt(llvm::Value *val); + llvm::Value *callFLog(llvm::Value *val); + llvm::Value *callPow(llvm::Value *val1, llvm::Value *val2); + + llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w=0); + + llvm::Value *constVector(float x, float y, float z, float w); + + llvm::Function *declarePrintf(); + llvm::Function *declareFunc(int label); + + llvm::Function *findFunction(int label); + + std::vector extractVector(llvm::Value *vec); +private: + llvm::Module *m_mod; + llvm::Function *m_func; + char m_name[32]; + llvm::LLVMFoldingBuilder m_builder; + int m_idx; + + llvm::VectorType *m_floatVecType; + + llvm::Function *m_llvmFSqrt; + llvm::Function *m_llvmFAbs; + llvm::Function *m_llvmPow; + llvm::Function *m_llvmFloor; + llvm::Function *m_llvmFlog; + llvm::Function *m_llvmLit; + + llvm::Constant *m_fmtPtr; + + std::stack m_ifStack; + struct Loop { + llvm::BasicBlock *begin; + llvm::BasicBlock *end; + }; + std::stack m_loopStack; + std::map m_functions; + Storage *m_storage; +}; + +#endif diff --git a/src/gallium/auxiliary/llvm/instructionssoa.cpp b/src/gallium/auxiliary/llvm/instructionssoa.cpp new file mode 100644 index 0000000000..a4d5046637 --- /dev/null +++ b/src/gallium/auxiliary/llvm/instructionssoa.cpp @@ -0,0 +1,121 @@ +#include "instructionssoa.h" + +#include "storagesoa.h" + +#include + +using namespace llvm; + +InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, + llvm::BasicBlock *block, StorageSoa *storage) + : m_builder(block), + m_storage(storage), + m_idx(0) +{ +} + +const char * InstructionsSoa::name(const char *prefix) const +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + Constant *constVector = Constant::getNullValue(vectorType); + Value *res = m_builder.CreateInsertElement(constVector, x, + m_storage->constantInt(0), + name("vecx")); + res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), + name("vecxy")); + res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), + name("vecxyz")); + if (w) + res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), + name("vecxyzw")); + return res; +} + +std::vector InstructionsSoa::arl(const std::vector in) +{ + std::vector res(4); + + //Extract x's + llvm::Value *x1 = m_builder.CreateExtractElement(in[0], + m_storage->constantInt(0), + name("extractX")); + //cast it to an unsigned int + x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast")); + + res[0] = x1;//vectorFromVals(x1, x2, x3, x4); + //only x is valid. the others shouldn't be necessary + /* + res[1] = Constant::getNullValue(m_floatVecType); + res[2] = Constant::getNullValue(m_floatVecType); + res[3] = Constant::getNullValue(m_floatVecType); + */ + + return res; +} + + +std::vector InstructionsSoa::add(const std::vector in1, + const std::vector in2) +{ + std::vector res(4); + + res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx")); + res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy")); + res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz")); + res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw")); + + return res; +} + +std::vector InstructionsSoa::mul(const std::vector in1, + const std::vector in2) +{ + std::vector res(4); + + res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx")); + res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly")); + res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz")); + res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw")); + + return res; +} + +void InstructionsSoa::end() +{ + m_builder.CreateRetVoid(); +} + +std::vector InstructionsSoa::madd(const std::vector in1, + const std::vector in2, + const std::vector in3) +{ + std::vector res = mul(in1, in2); + return add(res, in3); +} + +std::vector InstructionsSoa::extractVector(llvm::Value *vector) +{ + std::vector res(4); + res[0] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(0), + name("extract1X")); + res[1] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(1), + name("extract2X")); + res[2] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(2), + name("extract3X")); + res[3] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(3), + name("extract4X")); + + return res; +} diff --git a/src/gallium/auxiliary/llvm/instructionssoa.h b/src/gallium/auxiliary/llvm/instructionssoa.h new file mode 100644 index 0000000000..4169dcbb2e --- /dev/null +++ b/src/gallium/auxiliary/llvm/instructionssoa.h @@ -0,0 +1,74 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INSTRUCTIONSSOA_H +#define INSTRUCTIONSSOA_H + +#include + +#include + +namespace llvm { + class Module; + class Function; + class BasicBlock; + class Value; +} +class StorageSoa; + +class InstructionsSoa +{ +public: + InstructionsSoa(llvm::Module *mod, llvm::Function *func, + llvm::BasicBlock *block, StorageSoa *storage); + + std::vector arl(const std::vector in); + + std::vector add(const std::vector in1, + const std::vector in2); + std::vector madd(const std::vector in1, + const std::vector in2, + const std::vector in3); + std::vector mul(const std::vector in1, + const std::vector in2); + void end(); + + std::vector extractVector(llvm::Value *vector); +private: + const char * name(const char *prefix) const; + llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w); +private: + llvm::LLVMFoldingBuilder m_builder; + StorageSoa *m_storage; +private: + mutable int m_idx; + mutable char m_name[32]; +}; + + +#endif diff --git a/src/gallium/auxiliary/llvm/llvm_builtins.c b/src/gallium/auxiliary/llvm/llvm_builtins.c new file mode 100644 index 0000000000..4f98d754ba --- /dev/null +++ b/src/gallium/auxiliary/llvm/llvm_builtins.c @@ -0,0 +1,115 @@ +/*clang --emit-llvm llvm_builtins.c |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=gallivm_builtins.cpp -f -for=shader -funcname=createGallivmBuiltins*/ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +typedef __attribute__(( ocu_vector_type(4) )) float float4; + +extern float powf(float a, float b); + +inline float approx(float a, float b) +{ + if (b < -128.0f) b = -128.0f; + if (b > 128.0f) b = 128.0f; + if (a < 0) a = 0; + return powf(a, b); +} + +inline float4 lit(float4 tmp) +{ + float4 result; + result.x = 1.0; + result.w = 1.0; + if (tmp.x > 0) { + result.y = tmp.x; + result.z = approx(tmp.y, tmp.w); + } else { + result.y = 0; + result.z = 0; + } + return result; +} + +inline float4 cmp(float4 tmp0, float4 tmp1, float4 tmp2) +{ + float4 result; + + result.x = (tmp0.x < 0.0) ? tmp1.x : tmp2.x; + result.y = (tmp0.y < 0.0) ? tmp1.y : tmp2.y; + result.z = (tmp0.z < 0.0) ? tmp1.z : tmp2.z; + result.w = (tmp0.w < 0.0) ? tmp1.w : tmp2.w; + + return result; +} + +extern float cosf(float val); +extern float sinf(float val); + +inline float4 vcos(float4 val) +{ + float4 result; + printf("VEC IN is %f %f %f %f\n", val.x, val.y, val.z, val.w); + result.x = cosf(val.x); + result.y = cosf(val.x); + result.z = cosf(val.x); + result.w = cosf(val.x); + printf("VEC OUT is %f %f %f %f\n", result.x, result.y, result.z, result.w); + return result; +} + +inline float4 scs(float4 val) +{ + float4 result; + float tmp = val.x; + result.x = cosf(tmp); + result.y = sinf(tmp); + return result; +} + + +inline float4 vsin(float4 val) +{ + float4 result; + float tmp = val.x; + float res = sinf(tmp); + result.x = res; + result.y = res; + result.z = res; + result.w = res; + return result; +} + +inline int kilp(float4 val) +{ + if (val.x < 0 || val.y < 0 || val.z < 0 || val.w < 0) + return 1; + else + return 0; +} diff --git a/src/gallium/auxiliary/llvm/loweringpass.cpp b/src/gallium/auxiliary/llvm/loweringpass.cpp new file mode 100644 index 0000000000..556dbec366 --- /dev/null +++ b/src/gallium/auxiliary/llvm/loweringpass.cpp @@ -0,0 +1,17 @@ +#include "loweringpass.h" + +using namespace llvm; + +char LoweringPass::ID = 0; +RegisterPass X("lowering", "Lowering Pass"); + +LoweringPass::LoweringPass() + : ModulePass((intptr_t)&ID) +{ +} + +bool LoweringPass::runOnModule(Module &m) +{ + llvm::cerr << "Hello: " << m.getModuleIdentifier() << "\n"; + return false; +} diff --git a/src/gallium/auxiliary/llvm/loweringpass.h b/src/gallium/auxiliary/llvm/loweringpass.h new file mode 100644 index 0000000000..f62dcf6ba7 --- /dev/null +++ b/src/gallium/auxiliary/llvm/loweringpass.h @@ -0,0 +1,15 @@ +#ifndef LOWERINGPASS_H +#define LOWERINGPASS_H + +#include "llvm/Pass.h" +#include "llvm/Module.h" + +struct LoweringPass : public llvm::ModulePass +{ + static char ID; + LoweringPass(); + + virtual bool runOnModule(llvm::Module &m); +}; + +#endif diff --git a/src/gallium/auxiliary/llvm/storage.cpp b/src/gallium/auxiliary/llvm/storage.cpp new file mode 100644 index 0000000000..c4326de8c5 --- /dev/null +++ b/src/gallium/auxiliary/llvm/storage.cpp @@ -0,0 +1,364 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "storage.h" + +#include "gallivm_p.h" + +#include "pipe/p_shader_tokens.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace llvm; + +Storage::Storage(llvm::BasicBlock *block, llvm::Value *input) + : m_block(block), + m_INPUT(input), + m_addrs(32), + m_idx(0) +{ + m_floatVecType = VectorType::get(Type::FloatTy, 4); + m_intVecType = VectorType::get(IntegerType::get(32), 4); + + m_undefFloatVec = UndefValue::get(m_floatVecType); + m_undefIntVec = UndefValue::get(m_intVecType); + m_extSwizzleVec = 0; + + m_numConsts = 0; +} + +//can only build vectors with all members in the [0, 9] range +llvm::Constant *Storage::shuffleMask(int vec) +{ + if (!m_extSwizzleVec) { + std::vector elems; + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); + m_extSwizzleVec = ConstantVector::get(m_floatVecType, elems); + } + + if (m_intVecs.find(vec) != m_intVecs.end()) { + return m_intVecs[vec]; + } + int origVec = vec; + Constant* const_vec = 0; + if (origVec == 0) { + const_vec = Constant::getNullValue(m_intVecType); + } else { + int x = gallivm_x_swizzle(vec); + int y = gallivm_y_swizzle(vec); + int z = gallivm_z_swizzle(vec); + int w = gallivm_w_swizzle(vec); + std::vector elems; + elems.push_back(constantInt(x)); + elems.push_back(constantInt(y)); + elems.push_back(constantInt(z)); + elems.push_back(constantInt(w)); + const_vec = ConstantVector::get(m_intVecType, elems); + } + + m_intVecs[origVec] = const_vec; + return const_vec; +} + +llvm::ConstantInt *Storage::constantInt(int idx) +{ + if (m_constInts.find(idx) != m_constInts.end()) { + return m_constInts[idx]; + } + ConstantInt *const_int = ConstantInt::get(APInt(32, idx)); + m_constInts[idx] = const_int; + return const_int; +} + +llvm::Value *Storage::inputElement(int idx, llvm::Value *indIdx) +{ + Value *val = element(InputsArg, idx, indIdx); + LoadInst *load = new LoadInst(val, name("input"), false, m_block); + load->setAlignment(8); + + return load; +} + +llvm::Value *Storage::constElement(int idx, llvm::Value *indIdx) +{ + m_numConsts = ((idx + 1) > m_numConsts) ? (idx + 1) : m_numConsts; + + Value *elem = element(ConstsArg, idx, indIdx); + LoadInst *load = new LoadInst(elem, name("const"), false, m_block); + load->setAlignment(8); + return load; +} + +llvm::Value *Storage::shuffleVector(llvm::Value *vec, int shuffle) +{ + Constant *mask = shuffleMask(shuffle); + ShuffleVectorInst *res = + new ShuffleVectorInst(vec, m_extSwizzleVec, mask, + name("shuffle"), m_block); + return res; +} + + +llvm::Value *Storage::tempElement(int idx, llvm::Value *indIdx) +{ + Value *elem = element(TempsArg, idx, indIdx); + + LoadInst *load = new LoadInst(elem, name("temp"), false, m_block); + load->setAlignment(8); + + return load; +} + +void Storage::setTempElement(int idx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = 0; + if (m_tempWriteMap[idx]) + templ = tempElement(idx); + val = maskWrite(val, mask, templ); + } + Value *elem = element(TempsArg, idx); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); + m_tempWriteMap[idx] = true; +} + +void Storage::setOutputElement(int dstIdx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = 0; + if (m_destWriteMap[dstIdx]) + templ = outputElement(dstIdx); + val = maskWrite(val, mask, templ); + } + + Value *elem = element(DestsArg, dstIdx); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); + m_destWriteMap[dstIdx] = true; +} + +llvm::Value *Storage::maskWrite(llvm::Value *src, int mask, llvm::Value *templ) +{ + llvm::Value *dst = templ; + if (!dst) + dst = Constant::getNullValue(m_floatVecType); + if ((mask & TGSI_WRITEMASK_X)) { + llvm::Value *x = new ExtractElementInst(src, unsigned(0), + name("x"), m_block); + dst = new InsertElementInst(dst, x, unsigned(0), + name("dstx"), m_block); + } + if ((mask & TGSI_WRITEMASK_Y)) { + llvm::Value *y = new ExtractElementInst(src, unsigned(1), + name("y"), m_block); + dst = new InsertElementInst(dst, y, unsigned(1), + name("dsty"), m_block); + } + if ((mask & TGSI_WRITEMASK_Z)) { + llvm::Value *z = new ExtractElementInst(src, unsigned(2), + name("z"), m_block); + dst = new InsertElementInst(dst, z, unsigned(2), + name("dstz"), m_block); + } + if ((mask & TGSI_WRITEMASK_W)) { + llvm::Value *w = new ExtractElementInst(src, unsigned(3), + name("w"), m_block); + dst = new InsertElementInst(dst, w, unsigned(3), + name("dstw"), m_block); + } + return dst; +} + +const char * Storage::name(const char *prefix) +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +int Storage::numConsts() const +{ + return m_numConsts; +} + +llvm::Value * Storage::addrElement(int idx) const +{ + Value *ret = m_addrs[idx]; + if (!ret) + return m_undefFloatVec; + return ret; +} + +void Storage::setAddrElement(int idx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = m_addrs[idx]; + val = maskWrite(val, mask, templ); + } + m_addrs[idx] = val; +} + +llvm::Value * Storage::extractIndex(llvm::Value *vec) +{ + llvm::Value *x = new ExtractElementInst(vec, unsigned(0), + name("x"), m_block); + return new FPToSIInst(x, IntegerType::get(32), name("intidx"), m_block); +} + +void Storage::setCurrentBlock(llvm::BasicBlock *block) +{ + m_block = block; +} + +llvm::Value * Storage::outputElement(int idx, llvm::Value *indIdx) +{ + Value *elem = element(DestsArg, idx, indIdx); + LoadInst *load = new LoadInst(elem, name("output"), false, m_block); + load->setAlignment(8); + + return load; +} + +llvm::Value * Storage::inputPtr() const +{ + return m_INPUT; +} + +void Storage::pushArguments(llvm::Value *input) +{ + m_argStack.push(m_INPUT); + + m_INPUT = input; +} + +void Storage::popArguments() +{ + m_INPUT = m_argStack.top(); + m_argStack.pop(); +} + +void Storage::pushTemps() +{ + m_extSwizzleVec = 0; +} + +void Storage::popTemps() +{ +} + +llvm::Value * Storage::immediateElement(int idx) +{ + return m_immediates[idx]; +} + +void Storage::addImmediate(float *val) +{ + std::vector vec(4); + vec[0] = ConstantFP::get(Type::FloatTy, APFloat(val[0])); + vec[1] = ConstantFP::get(Type::FloatTy, APFloat(val[1])); + vec[2] = ConstantFP::get(Type::FloatTy, APFloat(val[2])); + vec[3] = ConstantFP::get(Type::FloatTy, APFloat(val[3])); + m_immediates.push_back(ConstantVector::get(m_floatVecType, vec)); +} + + +llvm::Value * Storage::elemPtr(Args arg) +{ + std::vector indices; + indices.push_back(constantInt(0)); + indices.push_back(constantInt(static_cast(arg))); + GetElementPtrInst *getElem = new GetElementPtrInst(m_INPUT, + indices.begin(), + indices.end(), + name("input_ptr"), + m_block); + return new LoadInst(getElem, name("input_field"), false, m_block); +} + +llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, + llvm::Value *indIdx ) +{ + GetElementPtrInst *getElem = 0; + + if (indIdx) { + getElem = new GetElementPtrInst(ptr, + BinaryOperator::create(Instruction::Add, + indIdx, + constantInt(idx), + name("add"), + m_block), + name("field"), + m_block); + } else { + getElem = new GetElementPtrInst(ptr, + constantInt(idx), + name("field"), + m_block); + } + return getElem; +} + +llvm::Value * Storage::element(Args arg, int idx, llvm::Value *indIdx ) +{ + Value *val = elemPtr(arg); + return elemIdx(val, idx, indIdx); +} + +void Storage::setKilElement(llvm::Value *val) +{ + std::vector indices; + indices.push_back(constantInt(0)); + indices.push_back(constantInt(static_cast(KilArg))); + GetElementPtrInst *elem = new GetElementPtrInst(m_INPUT, + indices.begin(), + indices.end(), + name("kil_ptr"), + m_block); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); +} + +#endif //MESA_LLVM + + diff --git a/src/gallium/auxiliary/llvm/storage.h b/src/gallium/auxiliary/llvm/storage.h new file mode 100644 index 0000000000..8574f7554e --- /dev/null +++ b/src/gallium/auxiliary/llvm/storage.h @@ -0,0 +1,133 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef STORAGE_H +#define STORAGE_H + +#include +#include +#include +#include + +namespace llvm { + class BasicBlock; + class Constant; + class ConstantInt; + class LoadInst; + class Value; + class VectorType; +} + +class Storage +{ +public: + Storage(llvm::BasicBlock *block, + llvm::Value *input); + + llvm::Value *inputPtr() const; + + void setCurrentBlock(llvm::BasicBlock *block); + + llvm::ConstantInt *constantInt(int); + llvm::Constant *shuffleMask(int vec); + llvm::Value *inputElement(int idx, llvm::Value *indIdx =0); + llvm::Value *constElement(int idx, llvm::Value *indIdx =0); + llvm::Value *outputElement(int idx, llvm::Value *indIdx =0); + llvm::Value *tempElement(int idx, llvm::Value *indIdx =0); + llvm::Value *immediateElement(int idx); + + void setOutputElement(int dstIdx, llvm::Value *val, int mask); + void setTempElement(int idx, llvm::Value *val, int mask); + + llvm::Value *addrElement(int idx) const; + void setAddrElement(int idx, llvm::Value *val, int mask); + + void setKilElement(llvm::Value *val); + + llvm::Value *shuffleVector(llvm::Value *vec, int shuffle); + + llvm::Value *extractIndex(llvm::Value *vec); + + int numConsts() const; + + void pushArguments(llvm::Value *input); + void popArguments(); + void pushTemps(); + void popTemps(); + + void addImmediate(float *val); + +private: + llvm::Value *maskWrite(llvm::Value *src, int mask, llvm::Value *templ); + const char *name(const char *prefix); + + enum Args { + DestsArg = 0, + InputsArg = 1, + TempsArg = 2, + ConstsArg = 3, + KilArg = 4 + }; + llvm::Value *elemPtr(Args arg); + llvm::Value *elemIdx(llvm::Value *ptr, int idx, + llvm::Value *indIdx = 0); + llvm::Value *element(Args arg, int idx, llvm::Value *indIdx = 0); + +private: + llvm::BasicBlock *m_block; + llvm::Value *m_INPUT; + + std::map m_constInts; + std::map m_intVecs; + std::vector m_addrs; + std::vector m_immediates; + + llvm::VectorType *m_floatVecType; + llvm::VectorType *m_intVecType; + + char m_name[32]; + int m_idx; + + int m_numConsts; + + std::map m_destWriteMap; + std::map m_tempWriteMap; + + llvm::Value *m_undefFloatVec; + llvm::Value *m_undefIntVec; + llvm::Value *m_extSwizzleVec; + + std::stack m_argStack; + std::stack > m_tempStack; +}; + +#endif diff --git a/src/gallium/auxiliary/llvm/storagesoa.cpp b/src/gallium/auxiliary/llvm/storagesoa.cpp new file mode 100644 index 0000000000..ed0674a96f --- /dev/null +++ b/src/gallium/auxiliary/llvm/storagesoa.cpp @@ -0,0 +1,389 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "storagesoa.h" + +#include "gallivm_p.h" + +#include "pipe/p_shader_tokens.h" +#include "pipe/p_debug.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace llvm; + + +StorageSoa::StorageSoa(llvm::BasicBlock *block, + llvm::Value *input, + llvm::Value *output, + llvm::Value *consts, + llvm::Value *temps) + : m_block(block), + m_input(input), + m_output(output), + m_consts(consts), + m_temps(temps), + m_immediates(0), + m_idx(0) +{ +} + +void StorageSoa::addImmediate(float *vec) +{ + std::vector vals(4); + vals[0] = vec[0]; + vals[1] = vec[1]; + vals[2] = vec[2]; + vals[3] = vec[3]; + m_immediatesToFlush.push_back(vals); +} + +void StorageSoa::declareImmediates() +{ + if (m_immediatesToFlush.empty()) + return; + + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + ArrayType *vectorChannels = ArrayType::get(vectorType, 4); + ArrayType *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size()); + + m_immediates = new GlobalVariable( + /*Type=*/arrayType, + /*isConstant=*/false, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name("immediates"), + currentModule()); + + std::vector arrayVals; + for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) { + std::vector vec = m_immediatesToFlush[i]; + std::vector vals(4); + std::vector channelArray; + + vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0]; + llvm::Constant *xChannel = createConstGlobalVector(vals); + + vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1]; + llvm::Constant *yChannel = createConstGlobalVector(vals); + + vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2]; + llvm::Constant *zChannel = createConstGlobalVector(vals); + + vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3]; + llvm::Constant *wChannel = createConstGlobalVector(vals); + channelArray.push_back(xChannel); + channelArray.push_back(yChannel); + channelArray.push_back(zChannel); + channelArray.push_back(wChannel); + Constant *constChannels = ConstantArray::get(vectorChannels, + channelArray); + arrayVals.push_back(constChannels); + } + Constant *constArray = ConstantArray::get(arrayType, arrayVals); + m_immediates->setInitializer(constArray); + + m_immediatesToFlush.clear(); +} + +llvm::Value *StorageSoa::addrElement(int idx) const +{ + std::map::const_iterator itr = m_addresses.find(idx); + if (itr == m_addresses.end()) { + debug_printf("Trying to access invalid shader 'address'\n"); + return 0; + } + llvm::Value * res = (*itr).second; + + res = new LoadInst(res, name("addr"), false, m_block); + + return res; +} + +std::vector StorageSoa::inputElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_input, idx, 0); + res[1] = element(m_input, idx, 1); + res[2] = element(m_input, idx, 2); + res[3] = element(m_input, idx, 3); + + return res; +} + +std::vector StorageSoa::constElement(llvm::Value *idx) +{ + std::vector res(4); + llvm::Value *xChannel, *yChannel, *zChannel, *wChannel; + + xChannel = elementPointer(m_consts, idx, 0); + yChannel = elementPointer(m_consts, idx, 1); + zChannel = elementPointer(m_consts, idx, 2); + wChannel = elementPointer(m_consts, idx, 3); + + res[0] = alignedArrayLoad(xChannel); + res[1] = alignedArrayLoad(yChannel); + res[2] = alignedArrayLoad(zChannel); + res[3] = alignedArrayLoad(wChannel); + + return res; +} + +std::vector StorageSoa::outputElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_output, idx, 0); + res[1] = element(m_output, idx, 1); + res[2] = element(m_output, idx, 2); + res[3] = element(m_output, idx, 3); + + return res; +} + +std::vector StorageSoa::tempElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_temps, idx, 0); + res[1] = element(m_temps, idx, 1); + res[2] = element(m_temps, idx, 2); + res[3] = element(m_temps, idx, 3); + + return res; +} + +std::vector StorageSoa::immediateElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_immediates, idx, 0); + res[1] = element(m_immediates, idx, 1); + res[2] = element(m_immediates, idx, 2); + res[3] = element(m_immediates, idx, 3); + + return res; +} + +llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, llvm::Value *index, + int channel) const +{ + std::vector indices; + if (m_immediates == ptr) + indices.push_back(constantInt(0)); + indices.push_back(index); + indices.push_back(constantInt(channel)); + + GetElementPtrInst *getElem = new GetElementPtrInst(ptr, + indices.begin(), + indices.end(), + name("ptr"), + m_block); + return getElem; +} + +llvm::Value * StorageSoa::element(llvm::Value *ptr, llvm::Value *index, + int channel) const +{ + llvm::Value *res = elementPointer(ptr, index, channel); + LoadInst *load = new LoadInst(res, name("element"), false, m_block); + //load->setAlignment(8); + return load; +} + +const char * StorageSoa::name(const char *prefix) const +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::ConstantInt * StorageSoa::constantInt(int idx) const +{ + if (m_constInts.find(idx) != m_constInts.end()) { + return m_constInts[idx]; + } + ConstantInt *constInt = ConstantInt::get(APInt(32, idx)); + m_constInts[idx] = constInt; + return constInt; +} + +llvm::Value *StorageSoa::alignedArrayLoad(llvm::Value *val) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + PointerType *vectorPtr = PointerType::get(vectorType, 0); + + CastInst *cast = new BitCastInst(val, vectorPtr, name("toVector"), m_block); + LoadInst *load = new LoadInst(cast, name("alignLoad"), false, m_block); + load->setAlignment(8); + return load; +} + +llvm::Module * StorageSoa::currentModule() const +{ + if (!m_block || !m_block->getParent()) + return 0; + + return m_block->getParent()->getParent(); +} + +llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &vec) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + std::vector immValues; + ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0])); + ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1])); + ConstantFP *constz = ConstantFP::get(Type::FloatTy, APFloat(vec[2])); + ConstantFP *constw = ConstantFP::get(Type::FloatTy, APFloat(vec[3])); + immValues.push_back(constx); + immValues.push_back(consty); + immValues.push_back(constz); + immValues.push_back(constw); + Constant *constVector = ConstantVector::get(vectorType, immValues); + + return constVector; +} + +std::vector StorageSoa::load(Argument type, int idx, int swizzle, + llvm::Value *indIdx) +{ + std::vector val(4); + + //if we have an indirect index, always use that + // if not use the integer offset to create one + llvm::Value *realIndex = 0; + if (indIdx) + realIndex = indIdx; + else + realIndex = constantInt(idx); + debug_printf("XXXXXXXXX realIdx = %p, indIdx = %p\n", realIndex, indIdx); + + switch(type) { + case Input: + val = inputElement(realIndex); + break; + case Output: + val = outputElement(realIndex); + break; + case Temp: + val = tempElement(realIndex); + break; + case Const: + val = constElement(realIndex); + break; + case Immediate: + val = immediateElement(realIndex); + break; + case Address: + debug_printf("Address not handled in the load phase!\n"); + assert(0); + break; + } + if (!gallivm_is_swizzle(swizzle)) + return val; + + std::vector res(4); + + res[0] = val[gallivm_x_swizzle(swizzle)]; + res[1] = val[gallivm_y_swizzle(swizzle)]; + res[2] = val[gallivm_z_swizzle(swizzle)]; + res[3] = val[gallivm_w_swizzle(swizzle)]; + return res; +} + +void StorageSoa::store(Argument type, int idx, const std::vector &val, + int mask) +{ + llvm::Value *out = 0; + switch(type) { + case Output: + out = m_output; + break; + case Temp: + out = m_temps; + break; + case Input: + out = m_input; + break; + case Address: { + llvm::Value *addr = m_addresses[idx]; + if (!addr) { + addAddress(idx); + addr = m_addresses[idx]; + assert(addr); + } + new StoreInst(val[0], addr, false, m_block); + return; + break; + } + default: + debug_printf("Can't save output of this type: %d !\n", type); + assert(0); + break; + } + llvm::Value *realIndex = constantInt(idx); + if ((mask & TGSI_WRITEMASK_X)) { + llvm::Value *xChannel = elementPointer(out, realIndex, 0); + new StoreInst(val[0], xChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_Y)) { + llvm::Value *yChannel = elementPointer(out, realIndex, 1); + new StoreInst(val[1], yChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_Z)) { + llvm::Value *zChannel = elementPointer(out, realIndex, 2); + new StoreInst(val[2], zChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_W)) { + llvm::Value *wChannel = elementPointer(out, realIndex, 3); + new StoreInst(val[3], wChannel, false, m_block); + } +} + +void StorageSoa::addAddress(int idx) +{ + GlobalVariable *val = new GlobalVariable( + /*Type=*/IntegerType::get(32), + /*isConstant=*/false, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name("address"), + currentModule()); + val->setInitializer(Constant::getNullValue(IntegerType::get(32))); + + debug_printf("adding to %d\n", idx); + m_addresses[idx] = val; +} diff --git a/src/gallium/auxiliary/llvm/storagesoa.h b/src/gallium/auxiliary/llvm/storagesoa.h new file mode 100644 index 0000000000..6443351f27 --- /dev/null +++ b/src/gallium/auxiliary/llvm/storagesoa.h @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STORAGESOA_H +#define STORAGESOA_H + +#include +#include +#include + +namespace llvm { + class BasicBlock; + class Constant; + class ConstantInt; + class GlobalVariable; + class LoadInst; + class Value; + class VectorType; + class Module; +} + +class StorageSoa +{ +public: + enum Argument { + Input, + Output, + Temp, + Const, + Immediate, + Address + }; +public: + StorageSoa(llvm::BasicBlock *block, + llvm::Value *input, + llvm::Value *output, + llvm::Value *consts, + llvm::Value *temps); + + + std::vector load(Argument type, int idx, int swizzle, + llvm::Value *indIdx =0); + void store(Argument type, int idx, const std::vector &val, + int mask); + + void addImmediate(float *vec); + void declareImmediates(); + + void addAddress(int idx); + + llvm::Value * addrElement(int idx) const; + + llvm::ConstantInt *constantInt(int) const; +private: + llvm::Value *elementPointer(llvm::Value *ptr, llvm::Value *indIdx, + int channel) const; + llvm::Value *element(llvm::Value *ptr, llvm::Value *idx, + int channel) const; + const char *name(const char *prefix) const; + llvm::Value *alignedArrayLoad(llvm::Value *val); + llvm::Module *currentModule() const; + llvm::Constant *createConstGlobalVector(const std::vector &vec); + + std::vector inputElement(llvm::Value *indIdx); + std::vector constElement(llvm::Value *indIdx); + std::vector outputElement(llvm::Value *indIdx); + std::vector tempElement(llvm::Value *indIdx); + std::vector immediateElement(llvm::Value *indIdx); +private: + llvm::BasicBlock *m_block; + + llvm::Value *m_input; + llvm::Value *m_output; + llvm::Value *m_consts; + llvm::Value *m_temps; + llvm::GlobalVariable *m_immediates; + + std::map m_addresses; + + std::vector > m_immediatesToFlush; + + mutable std::map m_constInts; + mutable char m_name[32]; + mutable int m_idx; +}; + +#endif diff --git a/src/gallium/auxiliary/llvm/tgsitollvm.cpp b/src/gallium/auxiliary/llvm/tgsitollvm.cpp new file mode 100644 index 0000000000..2cb4acce32 --- /dev/null +++ b/src/gallium/auxiliary/llvm/tgsitollvm.cpp @@ -0,0 +1,1221 @@ +#include "tgsitollvm.h" + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "storage.h" +#include "instructions.h" +#include "storagesoa.h" +#include "instructionssoa.h" + +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_util.h" +#include "tgsi/util/tgsi_build.h" +#include "tgsi/util/tgsi_dump.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +using namespace llvm; + +static inline FunctionType *vertexShaderFunctionType() +{ + //Function takes three arguments, + // the calling code has to make sure the types it will + // pass are castable to the following: + // [4 x <4 x float>] inputs, + // [4 x <4 x float>] output, + // [4 x [4 x float]] consts, + // [4 x <4 x float>] temps + + std::vector funcArgs; + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + ArrayType *vectorArray = ArrayType::get(vectorType, 4); + PointerType *vectorArrayPtr = PointerType::get(vectorArray, 0); + + ArrayType *floatArray = ArrayType::get(Type::FloatTy, 4); + ArrayType *constsArray = ArrayType::get(floatArray, 4); + PointerType *constsArrayPtr = PointerType::get(constsArray, 0); + + funcArgs.push_back(vectorArrayPtr);//inputs + funcArgs.push_back(vectorArrayPtr);//output + funcArgs.push_back(constsArrayPtr);//consts + funcArgs.push_back(vectorArrayPtr);//temps + + FunctionType *functionType = FunctionType::get( + /*Result=*/Type::VoidTy, + /*Params=*/funcArgs, + /*isVarArg=*/false); + + return functionType; +} + +static inline void +add_interpolator(struct gallivm_ir *ir, + struct gallivm_interpolate *interp) +{ + ir->interpolators[ir->num_interp] = *interp; + ++ir->num_interp; +} + +static void +translate_declaration(struct gallivm_ir *prog, + llvm::Module *module, + Storage *storage, + struct tgsi_full_declaration *decl, + struct tgsi_full_declaration *fd) +{ + if (decl->Declaration.File == TGSI_FILE_INPUT) { + unsigned first, last, mask; + uint interp_method; + + assert(decl->Declaration.Declare == TGSI_DECLARE_RANGE); + + first = decl->u.DeclarationRange.First; + last = decl->u.DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + /* Do not touch WPOS.xy */ + if (first == 0) { + mask &= ~TGSI_WRITEMASK_XY; + if (mask == TGSI_WRITEMASK_NONE) { + first++; + if (first > last) { + return; + } + } + } + + interp_method = decl->Interpolation.Interpolate; + + if (mask == TGSI_WRITEMASK_XYZW) { + unsigned i, j; + + for (i = first; i <= last; i++) { + for (j = 0; j < NUM_CHANNELS; j++) { + //interp( mach, i, j ); + struct gallivm_interpolate interp; + interp.type = interp_method; + interp.attrib = i; + interp.chan = j; + add_interpolator(prog, &interp); + } + } + } else { + unsigned i, j; + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + for( i = first; i <= last; i++ ) { + struct gallivm_interpolate interp; + interp.type = interp_method; + interp.attrib = i; + interp.chan = j; + add_interpolator(prog, &interp); + } + } + } + } + } +} + +static void +translate_declarationir(struct gallivm_ir *, + llvm::Module *, + StorageSoa *storage, + struct tgsi_full_declaration *decl, + struct tgsi_full_declaration *) +{ + if (decl->Declaration.File == TGSI_FILE_ADDRESS) { + int idx = decl->u.DeclarationRange.First; + storage->addAddress(idx); + } +} + +static void +translate_immediate(Storage *storage, + struct tgsi_full_immediate *imm) +{ + float vec[4]; + int i; + for (i = 0; i < imm->Immediate.Size - 1; ++i) { + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + vec[i] = imm->u.ImmediateFloat32[i].Float; + break; + default: + assert(0); + } + } + storage->addImmediate(vec); +} + + +static void +translate_immediateir(StorageSoa *storage, + struct tgsi_full_immediate *imm) +{ + float vec[4]; + int i; + for (i = 0; i < imm->Immediate.Size - 1; ++i) { + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + vec[i] = imm->u.ImmediateFloat32[i].Float; + break; + default: + assert(0); + } + } + storage->addImmediate(vec); +} + +static inline int +swizzleInt(struct tgsi_full_src_register *src) +{ + int swizzle = 0; + int start = 1000; + + for (int k = 0; k < 4; ++k) { + swizzle += tgsi_util_get_full_src_register_extswizzle(src, k) * start; + start /= 10; + } + return swizzle; +} + +static inline llvm::Value * +swizzleVector(llvm::Value *val, struct tgsi_full_src_register *src, + Storage *storage) +{ + int swizzle = swizzleInt(src); + + if (gallivm_is_swizzle(swizzle)) { + /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/ + val = storage->shuffleVector(val, swizzle); + } + return val; +} + +static void +translate_instruction(llvm::Module *module, + Storage *storage, + Instructions *instr, + struct tgsi_full_instruction *inst, + struct tgsi_full_instruction *fi, + unsigned instno) +{ + llvm::Value *inputs[4]; + inputs[0] = 0; + inputs[1] = 0; + inputs[2] = 0; + inputs[3] = 0; + + for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + llvm::Value *val = 0; + llvm::Value *indIdx = 0; + + if (src->SrcRegister.Indirect) { + indIdx = storage->addrElement(src->SrcRegisterInd.Index); + indIdx = storage->extractIndex(indIdx); + } + if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { + val = storage->constElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { + val = storage->inputElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { + val = storage->tempElement(src->SrcRegister.Index); + } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { + val = storage->outputElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { + val = storage->immediateElement(src->SrcRegister.Index); + } else { + fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); + return; + } + + inputs[i] = swizzleVector(val, src, storage); + } + + /*if (inputs[0]) + instr->printVector(inputs[0]); + if (inputs[1]) + instr->printVector(inputs[1]);*/ + llvm::Value *out = 0; + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: { + out = instr->arl(inputs[0]); + } + break; + case TGSI_OPCODE_MOV: { + out = inputs[0]; + } + break; + case TGSI_OPCODE_LIT: { + out = instr->lit(inputs[0]); + } + break; + case TGSI_OPCODE_RCP: { + out = instr->rcp(inputs[0]); + } + break; + case TGSI_OPCODE_RSQ: { + out = instr->rsq(inputs[0]); + } + break; + case TGSI_OPCODE_EXP: + break; + case TGSI_OPCODE_LOG: + break; + case TGSI_OPCODE_MUL: { + out = instr->mul(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_ADD: { + out = instr->add(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP3: { + out = instr->dp3(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP4: { + out = instr->dp4(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DST: { + out = instr->dst(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MIN: { + out = instr->min(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MAX: { + out = instr->max(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SLT: { + out = instr->slt(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SGE: { + out = instr->sge(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MAD: { + out = instr->madd(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SUB: { + out = instr->sub(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_LERP: { + out = instr->lerp(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_CND: + break; + case TGSI_OPCODE_CND0: + break; + case TGSI_OPCODE_DOT2ADD: + break; + case TGSI_OPCODE_INDEX: + break; + case TGSI_OPCODE_NEGATE: + break; + case TGSI_OPCODE_FRAC: { + out = instr->frc(inputs[0]); + } + break; + case TGSI_OPCODE_CLAMP: + break; + case TGSI_OPCODE_FLOOR: { + out = instr->floor(inputs[0]); + } + break; + case TGSI_OPCODE_ROUND: + break; + case TGSI_OPCODE_EXPBASE2: { + out = instr->ex2(inputs[0]); + } + break; + case TGSI_OPCODE_LOGBASE2: { + out = instr->lg2(inputs[0]); + } + break; + case TGSI_OPCODE_POWER: { + out = instr->pow(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_CROSSPRODUCT: { + out = instr->cross(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MULTIPLYMATRIX: + break; + case TGSI_OPCODE_ABS: { + out = instr->abs(inputs[0]); + } + break; + case TGSI_OPCODE_RCC: + break; + case TGSI_OPCODE_DPH: { + out = instr->dph(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_COS: { + out = instr->cos(inputs[0]); + } + break; + case TGSI_OPCODE_DDX: + break; + case TGSI_OPCODE_DDY: + break; + case TGSI_OPCODE_KILP: { + out = instr->kilp(inputs[0]); + storage->setKilElement(out); + return; + } + break; + case TGSI_OPCODE_PK2H: + break; + case TGSI_OPCODE_PK2US: + break; + case TGSI_OPCODE_PK4B: + break; + case TGSI_OPCODE_PK4UB: + break; + case TGSI_OPCODE_RFL: + break; + case TGSI_OPCODE_SEQ: + break; + case TGSI_OPCODE_SFL: + break; + case TGSI_OPCODE_SGT: { + out = instr->sgt(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SIN: { + out = instr->sin(inputs[0]); + } + break; + case TGSI_OPCODE_SLE: + break; + case TGSI_OPCODE_SNE: + break; + case TGSI_OPCODE_STR: + break; + case TGSI_OPCODE_TEX: + break; + case TGSI_OPCODE_TXD: + break; + case TGSI_OPCODE_UP2H: + break; + case TGSI_OPCODE_UP2US: + break; + case TGSI_OPCODE_UP4B: + break; + case TGSI_OPCODE_UP4UB: + break; + case TGSI_OPCODE_X2D: + break; + case TGSI_OPCODE_ARA: + break; + case TGSI_OPCODE_ARR: + break; + case TGSI_OPCODE_BRA: + break; + case TGSI_OPCODE_CAL: { + instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr()); + return; + } + break; + case TGSI_OPCODE_RET: { + instr->end(); + return; + } + break; + case TGSI_OPCODE_SSG: + break; + case TGSI_OPCODE_CMP: { + out = instr->cmp(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SCS: { + out = instr->scs(inputs[0]); + } + break; + case TGSI_OPCODE_TXB: + break; + case TGSI_OPCODE_NRM: + break; + case TGSI_OPCODE_DIV: + break; + case TGSI_OPCODE_DP2: + break; + case TGSI_OPCODE_TXL: + break; + case TGSI_OPCODE_BRK: { + instr->brk(); + return; + } + break; + case TGSI_OPCODE_IF: { + instr->ifop(inputs[0]); + storage->setCurrentBlock(instr->currentBlock()); + return; //just update the state + } + break; + case TGSI_OPCODE_LOOP: + break; + case TGSI_OPCODE_REP: + break; + case TGSI_OPCODE_ELSE: { + instr->elseop(); + storage->setCurrentBlock(instr->currentBlock()); + return; //only state update + } + break; + case TGSI_OPCODE_ENDIF: { + instr->endif(); + storage->setCurrentBlock(instr->currentBlock()); + return; //just update the state + } + break; + case TGSI_OPCODE_ENDLOOP: + break; + case TGSI_OPCODE_ENDREP: + break; + case TGSI_OPCODE_PUSHA: + break; + case TGSI_OPCODE_POPA: + break; + case TGSI_OPCODE_CEIL: + break; + case TGSI_OPCODE_I2F: + break; + case TGSI_OPCODE_NOT: + break; + case TGSI_OPCODE_TRUNC: { + out = instr->trunc(inputs[0]); + } + break; + case TGSI_OPCODE_SHL: + break; + case TGSI_OPCODE_SHR: + break; + case TGSI_OPCODE_AND: + break; + case TGSI_OPCODE_OR: + break; + case TGSI_OPCODE_MOD: + break; + case TGSI_OPCODE_XOR: + break; + case TGSI_OPCODE_SAD: + break; + case TGSI_OPCODE_TXF: + break; + case TGSI_OPCODE_TXQ: + break; + case TGSI_OPCODE_CONT: + break; + case TGSI_OPCODE_EMIT: + break; + case TGSI_OPCODE_ENDPRIM: + break; + case TGSI_OPCODE_BGNLOOP2: { + instr->beginLoop(); + storage->setCurrentBlock(instr->currentBlock()); + return; + } + break; + case TGSI_OPCODE_BGNSUB: { + instr->bgnSub(instno); + storage->setCurrentBlock(instr->currentBlock()); + storage->pushTemps(); + return; + } + break; + case TGSI_OPCODE_ENDLOOP2: { + instr->endLoop(); + storage->setCurrentBlock(instr->currentBlock()); + return; + } + break; + case TGSI_OPCODE_ENDSUB: { + instr->endSub(); + storage->setCurrentBlock(instr->currentBlock()); + storage->popArguments(); + storage->popTemps(); + return; + } + break; + case TGSI_OPCODE_NOISE1: + break; + case TGSI_OPCODE_NOISE2: + break; + case TGSI_OPCODE_NOISE3: + break; + case TGSI_OPCODE_NOISE4: + break; + case TGSI_OPCODE_NOP: + break; + case TGSI_OPCODE_TEXBEM: + break; + case TGSI_OPCODE_TEXBEML: + break; + case TGSI_OPCODE_TEXREG2AR: + break; + case TGSI_OPCODE_TEXM3X2PAD: + break; + case TGSI_OPCODE_TEXM3X2TEX: + break; + case TGSI_OPCODE_TEXM3X3PAD: + break; + case TGSI_OPCODE_TEXM3X3TEX: + break; + case TGSI_OPCODE_TEXM3X3SPEC: + break; + case TGSI_OPCODE_TEXM3X3VSPEC: + break; + case TGSI_OPCODE_TEXREG2GB: + break; + case TGSI_OPCODE_TEXREG2RGB: + break; + case TGSI_OPCODE_TEXDP3TEX: + break; + case TGSI_OPCODE_TEXDP3: + break; + case TGSI_OPCODE_TEXM3X3: + break; + case TGSI_OPCODE_TEXM3X2DEPTH: + break; + case TGSI_OPCODE_TEXDEPTH: + break; + case TGSI_OPCODE_BEM: + break; + case TGSI_OPCODE_M4X3: + break; + case TGSI_OPCODE_M3X4: + break; + case TGSI_OPCODE_M3X3: + break; + case TGSI_OPCODE_M3X2: + break; + case TGSI_OPCODE_NRM4: + break; + case TGSI_OPCODE_CALLNZ: + break; + case TGSI_OPCODE_IFC: + break; + case TGSI_OPCODE_BREAKC: + break; + case TGSI_OPCODE_KIL: + break; + case TGSI_OPCODE_END: + instr->end(); + return; + break; + default: + fprintf(stderr, "ERROR: Unknown opcode %d\n", + inst->Instruction.Opcode); + assert(0); + break; + } + + if (!out) { + fprintf(stderr, "ERROR: unsupported opcode %d\n", + inst->Instruction.Opcode); + assert(!"Unsupported opcode"); + } + + /* # not sure if we need this */ + switch( inst->Instruction.Saturate ) { + case TGSI_SAT_NONE: + break; + case TGSI_SAT_ZERO_ONE: + /*TXT( "_SAT" );*/ + break; + case TGSI_SAT_MINUS_PLUS_ONE: + /*TXT( "_SAT[-1,1]" );*/ + break; + default: + assert( 0 ); + } + + /* store results */ + for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + + if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { + storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { + storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { + storage->setAddrElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else { + fprintf(stderr, "ERROR: unsupported LLVM destination!"); + assert(!"wrong destination"); + } + } +} + + +static void +translate_instructionir(llvm::Module *module, + StorageSoa *storage, + InstructionsSoa *instr, + struct tgsi_full_instruction *inst, + struct tgsi_full_instruction *fi, + unsigned instno) +{ + std::vector< std::vector > inputs(inst->Instruction.NumSrcRegs); + + for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + std::vector val; + llvm::Value *indIdx = 0; + int swizzle = swizzleInt(src); + + if (src->SrcRegister.Indirect) { + indIdx = storage->addrElement(src->SrcRegisterInd.Index); + } + if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { + val = storage->load(StorageSoa::Const, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { + val = storage->load(StorageSoa::Input, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { + val = storage->load(StorageSoa::Temp, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { + val = storage->load(StorageSoa::Output, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { + val = storage->load(StorageSoa::Immediate, + src->SrcRegister.Index, swizzle, indIdx); + } else { + fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); + return; + } + + inputs[i] = val; + } + + std::vector out(4); + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: { + out = instr->arl(inputs[0]); + } + break; + case TGSI_OPCODE_MOV: { + out = inputs[0]; + } + break; + case TGSI_OPCODE_LIT: { + } + break; + case TGSI_OPCODE_RCP: { + } + break; + case TGSI_OPCODE_RSQ: { + } + break; + case TGSI_OPCODE_EXP: + break; + case TGSI_OPCODE_LOG: + break; + case TGSI_OPCODE_MUL: { + out = instr->mul(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_ADD: { + out = instr->add(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP3: { + } + break; + case TGSI_OPCODE_DP4: { + } + break; + case TGSI_OPCODE_DST: { + } + break; + case TGSI_OPCODE_MIN: { + } + break; + case TGSI_OPCODE_MAX: { + } + break; + case TGSI_OPCODE_SLT: { + } + break; + case TGSI_OPCODE_SGE: { + } + break; + case TGSI_OPCODE_MAD: { + out = instr->madd(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SUB: { + } + break; + case TGSI_OPCODE_LERP: { + } + break; + case TGSI_OPCODE_CND: + break; + case TGSI_OPCODE_CND0: + break; + case TGSI_OPCODE_DOT2ADD: + break; + case TGSI_OPCODE_INDEX: + break; + case TGSI_OPCODE_NEGATE: + break; + case TGSI_OPCODE_FRAC: { + } + break; + case TGSI_OPCODE_CLAMP: + break; + case TGSI_OPCODE_FLOOR: { + } + break; + case TGSI_OPCODE_ROUND: + break; + case TGSI_OPCODE_EXPBASE2: { + } + break; + case TGSI_OPCODE_LOGBASE2: { + } + break; + case TGSI_OPCODE_POWER: { + } + break; + case TGSI_OPCODE_CROSSPRODUCT: { + } + break; + case TGSI_OPCODE_MULTIPLYMATRIX: + break; + case TGSI_OPCODE_ABS: { + } + break; + case TGSI_OPCODE_RCC: + break; + case TGSI_OPCODE_DPH: { + } + break; + case TGSI_OPCODE_COS: { + } + break; + case TGSI_OPCODE_DDX: + break; + case TGSI_OPCODE_DDY: + break; + case TGSI_OPCODE_KILP: { + } + break; + case TGSI_OPCODE_PK2H: + break; + case TGSI_OPCODE_PK2US: + break; + case TGSI_OPCODE_PK4B: + break; + case TGSI_OPCODE_PK4UB: + break; + case TGSI_OPCODE_RFL: + break; + case TGSI_OPCODE_SEQ: + break; + case TGSI_OPCODE_SFL: + break; + case TGSI_OPCODE_SGT: { + } + break; + case TGSI_OPCODE_SIN: { + } + break; + case TGSI_OPCODE_SLE: + break; + case TGSI_OPCODE_SNE: + break; + case TGSI_OPCODE_STR: + break; + case TGSI_OPCODE_TEX: + break; + case TGSI_OPCODE_TXD: + break; + case TGSI_OPCODE_UP2H: + break; + case TGSI_OPCODE_UP2US: + break; + case TGSI_OPCODE_UP4B: + break; + case TGSI_OPCODE_UP4UB: + break; + case TGSI_OPCODE_X2D: + break; + case TGSI_OPCODE_ARA: + break; + case TGSI_OPCODE_ARR: + break; + case TGSI_OPCODE_BRA: + break; + case TGSI_OPCODE_CAL: { + } + break; + case TGSI_OPCODE_RET: { + } + break; + case TGSI_OPCODE_SSG: + break; + case TGSI_OPCODE_CMP: { + } + break; + case TGSI_OPCODE_SCS: { + } + break; + case TGSI_OPCODE_TXB: + break; + case TGSI_OPCODE_NRM: + break; + case TGSI_OPCODE_DIV: + break; + case TGSI_OPCODE_DP2: + break; + case TGSI_OPCODE_TXL: + break; + case TGSI_OPCODE_BRK: { + } + break; + case TGSI_OPCODE_IF: { + } + break; + case TGSI_OPCODE_LOOP: + break; + case TGSI_OPCODE_REP: + break; + case TGSI_OPCODE_ELSE: { + } + break; + case TGSI_OPCODE_ENDIF: { + } + break; + case TGSI_OPCODE_ENDLOOP: + break; + case TGSI_OPCODE_ENDREP: + break; + case TGSI_OPCODE_PUSHA: + break; + case TGSI_OPCODE_POPA: + break; + case TGSI_OPCODE_CEIL: + break; + case TGSI_OPCODE_I2F: + break; + case TGSI_OPCODE_NOT: + break; + case TGSI_OPCODE_TRUNC: { + } + break; + case TGSI_OPCODE_SHL: + break; + case TGSI_OPCODE_SHR: + break; + case TGSI_OPCODE_AND: + break; + case TGSI_OPCODE_OR: + break; + case TGSI_OPCODE_MOD: + break; + case TGSI_OPCODE_XOR: + break; + case TGSI_OPCODE_SAD: + break; + case TGSI_OPCODE_TXF: + break; + case TGSI_OPCODE_TXQ: + break; + case TGSI_OPCODE_CONT: + break; + case TGSI_OPCODE_EMIT: + break; + case TGSI_OPCODE_ENDPRIM: + break; + case TGSI_OPCODE_BGNLOOP2: { + } + break; + case TGSI_OPCODE_BGNSUB: { + } + break; + case TGSI_OPCODE_ENDLOOP2: { + } + break; + case TGSI_OPCODE_ENDSUB: { + } + break; + case TGSI_OPCODE_NOISE1: + break; + case TGSI_OPCODE_NOISE2: + break; + case TGSI_OPCODE_NOISE3: + break; + case TGSI_OPCODE_NOISE4: + break; + case TGSI_OPCODE_NOP: + break; + case TGSI_OPCODE_TEXBEM: + break; + case TGSI_OPCODE_TEXBEML: + break; + case TGSI_OPCODE_TEXREG2AR: + break; + case TGSI_OPCODE_TEXM3X2PAD: + break; + case TGSI_OPCODE_TEXM3X2TEX: + break; + case TGSI_OPCODE_TEXM3X3PAD: + break; + case TGSI_OPCODE_TEXM3X3TEX: + break; + case TGSI_OPCODE_TEXM3X3SPEC: + break; + case TGSI_OPCODE_TEXM3X3VSPEC: + break; + case TGSI_OPCODE_TEXREG2GB: + break; + case TGSI_OPCODE_TEXREG2RGB: + break; + case TGSI_OPCODE_TEXDP3TEX: + break; + case TGSI_OPCODE_TEXDP3: + break; + case TGSI_OPCODE_TEXM3X3: + break; + case TGSI_OPCODE_TEXM3X2DEPTH: + break; + case TGSI_OPCODE_TEXDEPTH: + break; + case TGSI_OPCODE_BEM: + break; + case TGSI_OPCODE_M4X3: + break; + case TGSI_OPCODE_M3X4: + break; + case TGSI_OPCODE_M3X3: + break; + case TGSI_OPCODE_M3X2: + break; + case TGSI_OPCODE_NRM4: + break; + case TGSI_OPCODE_CALLNZ: + break; + case TGSI_OPCODE_IFC: + break; + case TGSI_OPCODE_BREAKC: + break; + case TGSI_OPCODE_KIL: + break; + case TGSI_OPCODE_END: + instr->end(); + return; + break; + default: + fprintf(stderr, "ERROR: Unknown opcode %d\n", + inst->Instruction.Opcode); + assert(0); + break; + } + + if (!out[0]) { + fprintf(stderr, "ERROR: unsupported opcode %d\n", + inst->Instruction.Opcode); + assert(!"Unsupported opcode"); + } + + /* store results */ + for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + + if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { + storage->store(StorageSoa::Output, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { + storage->store(StorageSoa::Temp, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { + storage->store(StorageSoa::Address, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else { + fprintf(stderr, "ERROR: unsupported LLVM destination!"); + assert(!"wrong destination"); + } + } +} + +llvm::Module * +tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens) +{ + llvm::Module *mod = new Module("shader"); + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + unsigned instno = 0; + Function* shader = mod->getFunction("execute_shader"); + std::ostringstream stream; + if (ir->type == GALLIVM_VS) { + stream << "vs_shader"; + } else { + stream << "fs_shader"; + } + stream << ir->id; + std::string func_name = stream.str(); + shader->setName(func_name.c_str()); + + Function::arg_iterator args = shader->arg_begin(); + Value *ptr_INPUT = args++; + ptr_INPUT->setName("input"); + + BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + + tgsi_parse_init(&parse, tokens); + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + Storage storage(label_entry, ptr_INPUT); + Instructions instr(mod, shader, label_entry, &storage); + while(!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + translate_declaration(ir, mod, &storage, + &parse.FullToken.FullDeclaration, + &fd); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + translate_immediate(&storage, + &parse.FullToken.FullImmediate); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + translate_instruction(mod, &storage, &instr, + &parse.FullToken.FullInstruction, + &fi, instno); + ++instno; + break; + + default: + assert(0); + } + } + + tgsi_parse_free(&parse); + + ir->num_consts = storage.numConsts(); + return mod; +} + +llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, + const struct tgsi_token *tokens) +{ + llvm::Module *mod = new Module("shader"); + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + unsigned instno = 0; + std::ostringstream stream; + if (ir->type == GALLIVM_VS) { + stream << "vs_shader"; + } else { + stream << "fs_shader"; + } + //stream << ir->id; + std::string func_name = stream.str(); + Function *shader = llvm::cast(mod->getOrInsertFunction( + func_name.c_str(), + vertexShaderFunctionType())); + + Function::arg_iterator args = shader->arg_begin(); + Value *input = args++; + input->setName("inputs"); + Value *output = args++; + output->setName("outputs"); + Value *consts = args++; + consts->setName("consts"); + Value *temps = args++; + temps->setName("temps"); + + BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + + tgsi_parse_init(&parse, tokens); + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + + StorageSoa storage(label_entry, input, output, consts, temps); + InstructionsSoa instr(mod, shader, label_entry, &storage); + + while(!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + translate_declarationir(ir, mod, &storage, + &parse.FullToken.FullDeclaration, + &fd); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + translate_immediateir(&storage, + &parse.FullToken.FullImmediate); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + storage.declareImmediates(); + translate_instructionir(mod, &storage, &instr, + &parse.FullToken.FullInstruction, + &fi, instno); + ++instno; + break; + + default: + assert(0); + } + } + + tgsi_parse_free(&parse); + + return mod; +} diff --git a/src/gallium/auxiliary/llvm/tgsitollvm.h b/src/gallium/auxiliary/llvm/tgsitollvm.h new file mode 100644 index 0000000000..7ada04d629 --- /dev/null +++ b/src/gallium/auxiliary/llvm/tgsitollvm.h @@ -0,0 +1,20 @@ +#ifndef TGSITOLLVM_H +#define TGSITOLLVM_H + + +namespace llvm { + class Module; +} + +struct gallivm_ir; +struct tgsi_token; + + +llvm::Module * tgsi_to_llvm(struct gallivm_ir *ir, + const struct tgsi_token *tokens); + + +llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, + const struct tgsi_token *tokens); + +#endif diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile new file mode 100644 index 0000000000..588629e870 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/Makefile @@ -0,0 +1,23 @@ + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = pipebuffer + +DRIVER_SOURCES = \ + pb_buffer_fenced.c \ + pb_buffer_malloc.c \ + pb_bufmgr_fenced.c \ + pb_bufmgr_mm.c \ + pb_bufmgr_pool.c \ + pb_winsys.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/auxiliary/pipebuffer/linked_list.h b/src/gallium/auxiliary/pipebuffer/linked_list.h new file mode 100644 index 0000000000..e99817fb13 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/linked_list.h @@ -0,0 +1,91 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + +/** + * \file + * List macros heavily inspired by the Linux kernel + * list handling. No list looping yet. + * + * Is not threadsafe, so common operations need to + * be protected using an external mutex. + */ + +#ifndef LINKED_LIST_H_ +#define LINKED_LIST_H_ + + +#include + + +struct list_head +{ + struct list_head *prev; + struct list_head *next; +}; + + +#define LIST_INITHEAD(__item) \ + do { \ + (__item)->prev = (__item); \ + (__item)->next = (__item); \ + } while (0) + +#define LIST_ADD(__item, __list) \ + do { \ + (__item)->prev = (__list); \ + (__item)->next = (__list)->next; \ + (__list)->next->prev = (__item); \ + (__list)->next = (__item); \ + } while (0) + +#define LIST_ADDTAIL(__item, __list) \ + do { \ + (__item)->next = (__list); \ + (__item)->prev = (__list)->prev; \ + (__list)->prev->next = (__item); \ + (__list)->prev = (__item); \ + } while(0) + +#define LIST_DEL(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + } while(0) + +#define LIST_DELINIT(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + (__item)->next = (__item); \ + (__item)->prev = (__item); \ + } while(0) + +#define LIST_ENTRY(__type, __item, __field) \ + ((__type *)(((char *)(__item)) - offsetof(__type, __field))) + + +#endif /*LINKED_LIST_H_*/ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h new file mode 100644 index 0000000000..97beb5f72a --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -0,0 +1,202 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Generic code for buffers. + * + * Behind a pipe buffle handle there can be DMA buffers, client (or user) + * buffers, regular malloced buffers, etc. This file provides an abstract base + * buffer handle that allows the driver to cope with all those kinds of buffers + * in a more flexible way. + * + * There is no obligation of a winsys driver to use this library. And a pipe + * driver should be completly agnostic about it. + * + * \author José Fonseca + */ + +#ifndef PB_BUFFER_H_ +#define PB_BUFFER_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" + + +struct pb_vtbl; + +/** + * Buffer description. + * + * Used when allocating the buffer. + */ +struct pb_desc +{ + unsigned alignment; + unsigned usage; +}; + + +/** + * Base class for all pb_* buffers. + */ +struct pb_buffer +{ + struct pipe_buffer base; + + /** + * Pointer to the virtual function table. + * + * Avoid accessing this table directly. Use the inline functions below + * instead to avoid mistakes. + */ + const struct pb_vtbl *vtbl; +}; + + +/** + * Virtual function table for the buffer storage operations. + * + * Note that creation is not done through this table. + */ +struct pb_vtbl +{ + void (*destroy)( struct pb_buffer *buf ); + + /** + * Map the entire data store of a buffer object into the client's address. + * flags is bitmask of PIPE_BUFFER_FLAG_READ/WRITE. + */ + void *(*map)( struct pb_buffer *buf, + unsigned flags ); + + void (*unmap)( struct pb_buffer *buf ); + + /** + * Get the base buffer and the offset. + * + * A buffer can be subdivided in smaller buffers. This method should return + * the underlaying buffer, and the relative offset. + * + * Buffers without an underlaying base buffer should return themselves, with + * a zero offset. + * + * Note that this will increase the reference count of the base buffer. + */ + void (*get_base_buffer)( struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset ); +}; + + +static INLINE struct pipe_buffer * +pb_pipe_buffer( struct pb_buffer *pbuf ) +{ + assert(pbuf); + return &pbuf->base; +} + + +static INLINE struct pb_buffer * +pb_buffer( struct pipe_buffer *buf ) +{ + assert(buf); + /* Could add a magic cookie check on debug builds. + */ + return (struct pb_buffer *)buf; +} + + +/* Accessor functions for pb->vtbl: + */ +static INLINE void * +pb_map(struct pb_buffer *buf, + unsigned flags) +{ + assert(buf); + return buf->vtbl->map(buf, flags); +} + + +static INLINE void +pb_unmap(struct pb_buffer *buf) +{ + assert(buf); + buf->vtbl->unmap(buf); +} + + +static INLINE void +pb_get_base_buffer( struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset ) +{ + buf->vtbl->get_base_buffer(buf, base_buf, offset); +} + + +static INLINE void +pb_destroy(struct pb_buffer *buf) +{ + assert(buf); + buf->vtbl->destroy(buf); +} + + +/* XXX: thread safety issues! + */ +static INLINE void +pb_reference(struct pb_buffer **dst, + struct pb_buffer *src) +{ + if (src) + src->base.refcount++; + + if (*dst && --(*dst)->base.refcount == 0) + pb_destroy( *dst ); + + *dst = src; +} + + +/** + * Malloc-based buffer to store data that can't be used by the graphics + * hardware. + */ +struct pb_buffer * +pb_malloc_buffer_create(size_t size, + const struct pb_desc *desc); + + +void +pb_init_winsys(struct pipe_winsys *winsys); + + +#endif /*PB_BUFFER_H_*/ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c new file mode 100644 index 0000000000..f4fc3f6d71 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -0,0 +1,299 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Implementation of fenced buffers. + * + * \author José Fonseca + * \author Thomas Hellström + */ + + +#include "linked_list.h" + +#include "p_compiler.h" +#include "p_debug.h" +#include "p_winsys.h" +#include "p_thread.h" +#include "p_util.h" + +#include "pb_buffer.h" +#include "pb_buffer_fenced.h" + +#ifndef __MSC__ +#include +#endif + + +/** + * Convenience macro (type safe). + */ +#define SUPER(__derived) (&(__derived)->base) + + +struct fenced_buffer_list +{ + _glthread_Mutex mutex; + + struct pipe_winsys *winsys; + + size_t numDelayed; + size_t checkDelayed; + + struct list_head delayed; +}; + + +/** + * Wrapper around a pipe buffer which adds fencing and reference counting. + */ +struct fenced_buffer +{ + struct pb_buffer base; + + struct pb_buffer *buffer; + + struct pipe_fence_handle *fence; + + struct list_head head; + struct fenced_buffer_list *list; +}; + + +static INLINE struct fenced_buffer * +fenced_buffer(struct pb_buffer *buf) +{ + assert(buf); + assert(buf->vtbl == &fenced_buffer_vtbl); + return (struct fenced_buffer *)buf; +} + + + + +static void +_fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, + int wait) +{ + struct pipe_winsys *winsys = fenced_list->winsys; + struct fenced_buffer *fenced_buf; + struct list_head *list, *prev; + int signaled = -1; + + list = fenced_list->delayed.next; + + if (fenced_list->numDelayed > 3) { + unsigned i; + + for (i = 0; i < fenced_list->numDelayed; i += 3) { + list = list->next; + } + } + + prev = list->prev; + for (; list != &fenced_list->delayed; list = prev, prev = list->prev) { + + fenced_buf = LIST_ENTRY(struct fenced_buffer, list, head); + + if (signaled != 0) { + if (wait) { + signaled = winsys->fence_finish(winsys, fenced_buf->fence, 0); + } + else { + signaled = winsys->fence_signalled(winsys, fenced_buf->fence, 0); + } + } + + if (signaled != 0) + /* XXX: we are assuming that buffers are freed in the same order they + * are fenced which may not always be true... + */ + break; + + winsys->fence_reference(winsys, &fenced_buf->fence, NULL); + + LIST_DEL(list); + fenced_list->numDelayed--; + + /* Do the delayed destroy: + */ + pb_reference(&fenced_buf->buffer, NULL); + FREE(fenced_buf); + } +} + + +static void +fenced_buffer_destroy(struct pb_buffer *buf) +{ + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + struct fenced_buffer_list *fenced_list = fenced_buf->list; + + if (fenced_buf->fence) { + LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); + fenced_list->numDelayed++; + } + else { + pb_reference(&fenced_buf->buffer, NULL); + FREE(fenced_buf); + } + + if ((fenced_list->numDelayed % fenced_list->checkDelayed) == 0) + _fenced_buffer_list_check_free(fenced_list, 0); +} + + +static void * +fenced_buffer_map(struct pb_buffer *buf, + unsigned flags) +{ + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + return pb_map(fenced_buf->buffer, flags); +} + + +static void +fenced_buffer_unmap(struct pb_buffer *buf) +{ + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + pb_unmap(fenced_buf->buffer); +} + + +static void +fenced_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + pb_get_base_buffer(fenced_buf->buffer, base_buf, offset); +} + + +const struct pb_vtbl +fenced_buffer_vtbl = { + fenced_buffer_destroy, + fenced_buffer_map, + fenced_buffer_unmap, + fenced_buffer_get_base_buffer +}; + + +struct pb_buffer * +fenced_buffer_create(struct fenced_buffer_list *fenced_list, + struct pb_buffer *buffer) +{ + struct fenced_buffer *buf; + + if(!buffer) + return NULL; + + buf = CALLOC_STRUCT(fenced_buffer); + if(!buf) + return NULL; + + buf->base.base.refcount = 1; + buf->base.base.alignment = buffer->base.alignment; + buf->base.base.usage = buffer->base.usage; + buf->base.base.size = buffer->base.size; + + buf->base.vtbl = &fenced_buffer_vtbl; + buf->buffer = buffer; + buf->list = fenced_list; + + return &buf->base; +} + + +void +buffer_fence(struct pb_buffer *buf, + struct pipe_fence_handle *fence) +{ + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + struct fenced_buffer_list *fenced_list = fenced_buf->list; + struct pipe_winsys *winsys = fenced_list->winsys; + + _glthread_LOCK_MUTEX(fenced_list->mutex); + winsys->fence_reference(winsys, &fenced_buf->fence, fence); + _glthread_UNLOCK_MUTEX(fenced_list->mutex); +} + + +struct fenced_buffer_list * +fenced_buffer_list_create(struct pipe_winsys *winsys) +{ + struct fenced_buffer_list *fenced_list; + + fenced_list = (struct fenced_buffer_list *)CALLOC(1, sizeof(*fenced_list)); + if (!fenced_list) + return NULL; + + fenced_list->winsys = winsys; + + LIST_INITHEAD(&fenced_list->delayed); + + fenced_list->numDelayed = 0; + + /* TODO: don't hard code this */ + fenced_list->checkDelayed = 5; + + _glthread_INIT_MUTEX(fenced_list->mutex); + + return fenced_list; +} + + +void +fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, + int wait) +{ + _glthread_LOCK_MUTEX(fenced_list->mutex); + _fenced_buffer_list_check_free(fenced_list, wait); + _glthread_UNLOCK_MUTEX(fenced_list->mutex); +} + + +void +fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list) +{ + _glthread_LOCK_MUTEX(fenced_list->mutex); + + /* Wait on outstanding fences */ + while (fenced_list->numDelayed) { + _glthread_UNLOCK_MUTEX(fenced_list->mutex); + sched_yield(); + _fenced_buffer_list_check_free(fenced_list, 1); + _glthread_LOCK_MUTEX(fenced_list->mutex); + } + + _glthread_UNLOCK_MUTEX(fenced_list->mutex); + + FREE(fenced_list); +} + + diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h new file mode 100644 index 0000000000..c40b9c75e1 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h @@ -0,0 +1,117 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Buffer fencing. + * + * "Fenced buffers" is actually a misnomer. They should be referred as + * "fenceable buffers", i.e, buffers that can be fenced, but I couldn't find + * the word "fenceable" in the dictionary. + * + * A "fenced buffer" is a decorator around a normal buffer, which adds two + * special properties: + * - the ability for the destruction to be delayed by a fence; + * - reference counting. + * + * Usually DMA buffers have a life-time that will extend the life-time of its + * handle. The end-of-life is dictated by the fence signalling. + * + * Between the handle's destruction, and the fence signalling, the buffer is + * stored in a fenced buffer list. + * + * \author José Fonseca + */ + +#ifndef PB_BUFFER_FENCED_H_ +#define PB_BUFFER_FENCED_H_ + + +#include "pipe/p_debug.h" + + +struct pipe_winsys; +struct pipe_buffer; +struct pipe_fence_handle; + + +/** + * List of buffers which are awaiting fence signalling. + */ +struct fenced_buffer_list; + + +/** + * The fenced buffer's virtual function table. + * + * NOTE: Made public for debugging purposes. + */ +extern const struct pb_vtbl fenced_buffer_vtbl; + + +/** + * Create a fenced buffer list. + * + * See also fenced_bufmgr_create for a more convenient way to use this. + */ +struct fenced_buffer_list * +fenced_buffer_list_create(struct pipe_winsys *winsys); + + +/** + * Walk the fenced buffer list to check and free signalled buffers. + */ +void +fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, + int wait); + +void +fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list); + + +/** + * Wrap a buffer in a fenced buffer. + * + * NOTE: this will not increase the buffer reference count. + */ +struct pb_buffer * +fenced_buffer_create(struct fenced_buffer_list *fenced, + struct pb_buffer *buffer); + + +/** + * Set a buffer's fence. + * + * NOTE: Although it takes a generic pb_buffer argument, it will fail + * on everything but buffers returned by fenced_buffer_create. + */ +void +buffer_fence(struct pb_buffer *buf, + struct pipe_fence_handle *fence); + + +#endif /*PB_BUFFER_FENCED_H_*/ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c new file mode 100644 index 0000000000..9e8244f909 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c @@ -0,0 +1,127 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Implementation of malloc-based buffers to store data that can't be processed + * by the hardware. + * + * \author José Fonseca + */ + + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pb_buffer.h" + + +struct malloc_buffer +{ + struct pb_buffer base; + void *data; +}; + + +extern const struct pb_vtbl malloc_buffer_vtbl; + +static INLINE struct malloc_buffer * +malloc_buffer(struct pb_buffer *buf) +{ + assert(buf); + assert(buf->vtbl == &malloc_buffer_vtbl); + return (struct malloc_buffer *)buf; +} + + +static void +malloc_buffer_destroy(struct pb_buffer *buf) +{ + align_free(malloc_buffer(buf)->data); + FREE(buf); +} + + +static void * +malloc_buffer_map(struct pb_buffer *buf, + unsigned flags) +{ + return malloc_buffer(buf)->data; +} + + +static void +malloc_buffer_unmap(struct pb_buffer *buf) +{ + /* No-op */ +} + + +static void +malloc_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + *base_buf = buf; + *offset = 0; +} + + +const struct pb_vtbl +malloc_buffer_vtbl = { + malloc_buffer_destroy, + malloc_buffer_map, + malloc_buffer_unmap, + malloc_buffer_get_base_buffer +}; + + +struct pb_buffer * +pb_malloc_buffer_create(size_t size, + const struct pb_desc *desc) +{ + struct malloc_buffer *buf; + + /* TODO: do a single allocation */ + + buf = CALLOC_STRUCT(malloc_buffer); + if(!buf) + return NULL; + + buf->base.base.refcount = 1; + buf->base.base.alignment = desc->alignment; + buf->base.base.usage = desc->usage; + buf->base.base.size = size; + buf->base.vtbl = &malloc_buffer_vtbl; + + buf->data = align_malloc(size, desc->alignment < sizeof(void*) ? sizeof(void*) : desc->alignment); + if(!buf->data) { + align_free(buf); + return NULL; + } + + return &buf->base; +} diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h new file mode 100644 index 0000000000..1ddf784c97 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -0,0 +1,126 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Buffer management. + * + * A buffer manager does only one basic thing: it creates buffers. Actually, + * "buffer factory" would probably a more accurate description. + * + * You can chain buffer managers so that you can have a finer grained memory + * management and pooling. + * + * For example, for a simple batch buffer manager you would chain: + * - the native buffer manager, which provides DMA memory from the graphics + * memory space; + * - the pool buffer manager, which keep around a pool of equally sized buffers + * to avoid latency associated with the native buffer manager; + * - the fenced buffer manager, which will delay buffer destruction until the + * the moment the card finishing processing it. + * + * \author José Fonseca + */ + +#ifndef PB_BUFMGR_H_ +#define PB_BUFMGR_H_ + + +#include + + +struct pb_desc; +struct pipe_buffer; +struct pipe_winsys; + + +/** + * Abstract base class for all buffer managers. + */ +struct pb_manager +{ + /* XXX: we will likely need more allocation flags */ + struct pb_buffer * + (*create_buffer)( struct pb_manager *mgr, + size_t size, + const struct pb_desc *desc); + + void + (*destroy)( struct pb_manager *mgr ); +}; + + +/** + * Static buffer pool manager. + * + * Manages the allocation of equally sized buffers. It does so by allocating + * a single big buffer and divide it equally sized buffers. + * + * It is meant to manage the allocation of batch buffer pools. + */ +struct pb_manager * +pool_bufmgr_create(struct pb_manager *provider, + size_t n, size_t size, + const struct pb_desc *desc); + + +/** + * Wraper around the old memory manager. + * + * It managers buffers of different sizes. It does so by allocating a buffer + * with the size of the heap, and then using the old mm memory manager to manage + * that heap. + */ +struct pb_manager * +mm_bufmgr_create(struct pb_manager *provider, + size_t size, size_t align2); + +/** + * Same as mm_bufmgr_create. + * + * Buffer will be release when the manager is destroyed. + */ +struct pb_manager * +mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, + size_t size, size_t align2); + + +/** + * Fenced buffer manager. + * + * This manager is just meant for convenience. It wraps the buffers returned + * by another manager in fenced buffers, so that + * + * NOTE: the buffer manager that provides the buffers will be destroyed + * at the same time. + */ +struct pb_manager * +fenced_bufmgr_create(struct pb_manager *provider, + struct pipe_winsys *winsys); + + +#endif /*PB_BUFMGR_H_*/ diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c new file mode 100644 index 0000000000..c535d3276c --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c @@ -0,0 +1,131 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * \file + * A buffer manager that wraps buffers in fenced buffers. + * + * \author José Fonseca + */ + + +#include "p_debug.h" +#include "p_util.h" + +#include "pb_buffer.h" +#include "pb_buffer_fenced.h" +#include "pb_bufmgr.h" + + +struct fenced_pb_manager +{ + struct pb_manager base; + + struct pb_manager *provider; + + struct fenced_buffer_list *fenced_list; +}; + + +static INLINE struct fenced_pb_manager * +fenced_pb_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct fenced_pb_manager *)mgr; +} + + +static struct pb_buffer * +fenced_bufmgr_create_buffer(struct pb_manager *mgr, + size_t size, + const struct pb_desc *desc) +{ + struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr); + struct pb_buffer *buf; + struct pb_buffer *fenced_buf; + + /* check for free buffers before allocating new ones */ + fenced_buffer_list_check_free(fenced_mgr->fenced_list, 0); + + buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc); + if(!buf) { + /* try harder to get a buffer */ + fenced_buffer_list_check_free(fenced_mgr->fenced_list, 1); + + buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc); + if(!buf) { + /* give up */ + return NULL; + } + } + + fenced_buf = fenced_buffer_create(fenced_mgr->fenced_list, buf); + if(!fenced_buf) { + assert(buf->base.refcount == 1); + pb_destroy(buf); + } + + return fenced_buf; +} + + +static void +fenced_bufmgr_destroy(struct pb_manager *mgr) +{ + struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr); + + fenced_buffer_list_destroy(fenced_mgr->fenced_list); + + fenced_mgr->provider->destroy(fenced_mgr->provider); + + FREE(fenced_mgr); +} + + +struct pb_manager * +fenced_bufmgr_create(struct pb_manager *provider, + struct pipe_winsys *winsys) +{ + struct fenced_pb_manager *fenced_mgr; + + fenced_mgr = (struct fenced_pb_manager *)CALLOC(1, sizeof(*fenced_mgr)); + if (!fenced_mgr) + return NULL; + + fenced_mgr->base.destroy = fenced_bufmgr_destroy; + fenced_mgr->base.create_buffer = fenced_bufmgr_create_buffer; + + fenced_mgr->provider = provider; + fenced_mgr->fenced_list = fenced_buffer_list_create(winsys); + if(!fenced_mgr->fenced_list) { + FREE(fenced_mgr); + return NULL; + } + + return &fenced_mgr->base; +} diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c new file mode 100644 index 0000000000..8b1b51c0e2 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -0,0 +1,593 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 1999 Wittawat Yamwong + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Buffer manager using the old texture memory manager. + * + * \author José Fonseca + */ + + +#include "linked_list.h" + +#include "p_defines.h" +#include "p_debug.h" +#include "p_thread.h" +#include "p_util.h" +#include "pb_buffer.h" +#include "pb_bufmgr.h" + + +/** + * Convenience macro (type safe). + */ +#define SUPER(__derived) (&(__derived)->base) + + +struct mem_block +{ + struct mem_block *next, *prev; + struct mem_block *next_free, *prev_free; + struct mem_block *heap; + int ofs, size; + unsigned int free:1; + unsigned int reserved:1; +}; + + +#ifdef DEBUG +/** + * For debugging purposes. + */ +static void +mmDumpMemInfo(const struct mem_block *heap) +{ + debug_printf("Memory heap %p:\n", (void *)heap); + if (heap == 0) { + debug_printf(" heap == 0\n"); + } else { + const struct mem_block *p; + + for(p = heap->next; p != heap; p = p->next) { + debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + debug_printf("\nFree list:\n"); + + for(p = heap->next_free; p != heap; p = p->next_free) { + debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + } + debug_printf("End of memory blocks\n"); +} +#endif + + +/** + * input: total size in bytes + * return: a heap pointer if OK, NULL if error + */ +static struct mem_block * +mmInit(int ofs, int size) +{ + struct mem_block *heap, *block; + + if (size <= 0) + return NULL; + + heap = CALLOC_STRUCT(mem_block); + if (!heap) + return NULL; + + block = CALLOC_STRUCT(mem_block); + if (!block) { + FREE(heap); + return NULL; + } + + heap->next = block; + heap->prev = block; + heap->next_free = block; + heap->prev_free = block; + + block->heap = heap; + block->next = heap; + block->prev = heap; + block->next_free = heap; + block->prev_free = heap; + + block->ofs = ofs; + block->size = size; + block->free = 1; + + return heap; +} + + +static struct mem_block * +SliceBlock(struct mem_block *p, + int startofs, int size, + int reserved, int alignment) +{ + struct mem_block *newblock; + + /* break left [p, newblock, p->next], then p = newblock */ + if (startofs > p->ofs) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs; + newblock->size = p->size - (startofs - p->ofs); + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size -= newblock->size; + p = newblock; + } + + /* break right, also [p, newblock, p->next] */ + if (size < p->size) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs + size; + newblock->size = p->size - size; + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size = size; + } + + /* p = middle block */ + p->free = 0; + + /* Remove p from the free list: + */ + p->next_free->prev_free = p->prev_free; + p->prev_free->next_free = p->next_free; + + p->next_free = 0; + p->prev_free = 0; + + p->reserved = reserved; + return p; +} + + +/** + * Allocate 'size' bytes with 2^align2 bytes alignment, + * restrict the search to free memory after 'startSearch' + * depth and back buffers should be in different 4mb banks + * to get better page hits if possible + * input: size = size of block + * align2 = 2^align2 bytes alignment + * startSearch = linear offset from start of heap to begin search + * return: pointer to the allocated block, 0 if error + */ +static struct mem_block * +mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) +{ + struct mem_block *p; + const int mask = (1 << align2)-1; + int startofs = 0; + int endofs; + + if (!heap || align2 < 0 || size <= 0) + return NULL; + + for (p = heap->next_free; p != heap; p = p->next_free) { + assert(p->free); + + startofs = (p->ofs + mask) & ~mask; + if ( startofs < startSearch ) { + startofs = startSearch; + } + endofs = startofs+size; + if (endofs <= (p->ofs+p->size)) + break; + } + + if (p == heap) + return NULL; + + assert(p->free); + p = SliceBlock(p,startofs,size,0,mask+1); + + return p; +} + + +#if 0 +/** + * Free block starts at offset + * input: pointer to a heap, start offset + * return: pointer to a block + */ +static struct mem_block * +mmFindBlock(struct mem_block *heap, int start) +{ + struct mem_block *p; + + for (p = heap->next; p != heap; p = p->next) { + if (p->ofs == start) + return p; + } + + return NULL; +} +#endif + + +static INLINE int +Join2Blocks(struct mem_block *p) +{ + /* XXX there should be some assertions here */ + + /* NOTE: heap->free == 0 */ + + if (p->free && p->next->free) { + struct mem_block *q = p->next; + + assert(p->ofs + p->size == q->ofs); + p->size += q->size; + + p->next = q->next; + q->next->prev = p; + + q->next_free->prev_free = q->prev_free; + q->prev_free->next_free = q->next_free; + + FREE(q); + return 1; + } + return 0; +} + + +/** + * Free block starts at offset + * input: pointer to a block + * return: 0 if OK, -1 if error + */ +static int +mmFreeMem(struct mem_block *b) +{ + if (!b) + return 0; + + if (b->free) { + debug_printf("block already free\n"); + return -1; + } + if (b->reserved) { + debug_printf("block is reserved\n"); + return -1; + } + + b->free = 1; + b->next_free = b->heap->next_free; + b->prev_free = b->heap; + b->next_free->prev_free = b; + b->prev_free->next_free = b; + + Join2Blocks(b); + if (b->prev != b->heap) + Join2Blocks(b->prev); + + return 0; +} + + +/** + * destroy MM + */ +static void +mmDestroy(struct mem_block *heap) +{ + struct mem_block *p; + + if (!heap) + return; + + for (p = heap->next; p != heap; ) { + struct mem_block *next = p->next; + FREE(p); + p = next; + } + + FREE(heap); +} + + +struct mm_pb_manager +{ + struct pb_manager base; + + _glthread_Mutex mutex; + + size_t size; + struct mem_block *heap; + + size_t align2; + + struct pb_buffer *buffer; + void *map; +}; + + +static INLINE struct mm_pb_manager * +mm_pb_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct mm_pb_manager *)mgr; +} + + +struct mm_buffer +{ + struct pb_buffer base; + + struct mm_pb_manager *mgr; + + struct mem_block *block; +}; + + +static INLINE struct mm_buffer * +mm_buffer(struct pb_buffer *buf) +{ + assert(buf); + return (struct mm_buffer *)buf; +} + + +static void +mm_buffer_destroy(struct pb_buffer *buf) +{ + struct mm_buffer *mm_buf = mm_buffer(buf); + struct mm_pb_manager *mm = mm_buf->mgr; + + assert(buf->base.refcount == 0); + + _glthread_LOCK_MUTEX(mm->mutex); + mmFreeMem(mm_buf->block); + FREE(buf); + _glthread_UNLOCK_MUTEX(mm->mutex); +} + + +static void * +mm_buffer_map(struct pb_buffer *buf, + unsigned flags) +{ + struct mm_buffer *mm_buf = mm_buffer(buf); + struct mm_pb_manager *mm = mm_buf->mgr; + + return (unsigned char *) mm->map + mm_buf->block->ofs; +} + + +static void +mm_buffer_unmap(struct pb_buffer *buf) +{ + /* No-op */ +} + + +static void +mm_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + struct mm_buffer *mm_buf = mm_buffer(buf); + struct mm_pb_manager *mm = mm_buf->mgr; + pb_get_base_buffer(mm->buffer, base_buf, offset); + *offset += mm_buf->block->ofs; +} + + +static const struct pb_vtbl +mm_buffer_vtbl = { + mm_buffer_destroy, + mm_buffer_map, + mm_buffer_unmap, + mm_buffer_get_base_buffer +}; + + +static struct pb_buffer * +mm_bufmgr_create_buffer(struct pb_manager *mgr, + size_t size, + const struct pb_desc *desc) +{ + struct mm_pb_manager *mm = mm_pb_manager(mgr); + struct mm_buffer *mm_buf; + + /* We don't handle alignments larger then the one initially setup */ + assert(desc->alignment % (1 << mm->align2) == 0); + if(desc->alignment % (1 << mm->align2)) + return NULL; + + _glthread_LOCK_MUTEX(mm->mutex); + + mm_buf = CALLOC_STRUCT(mm_buffer); + if (!mm_buf) { + _glthread_UNLOCK_MUTEX(mm->mutex); + return NULL; + } + + mm_buf->base.base.refcount = 1; + mm_buf->base.base.alignment = desc->alignment; + mm_buf->base.base.usage = desc->usage; + mm_buf->base.base.size = size; + + mm_buf->base.vtbl = &mm_buffer_vtbl; + + mm_buf->mgr = mm; + + mm_buf->block = mmAllocMem(mm->heap, size, mm->align2, 0); + if(!mm_buf->block) { + debug_printf("warning: heap full\n"); +#if 0 + mmDumpMemInfo(mm->heap); +#endif + + mm_buf->block = mmAllocMem(mm->heap, size, mm->align2, 0); + if(!mm_buf->block) { + assert(0); + FREE(mm_buf); + _glthread_UNLOCK_MUTEX(mm->mutex); + return NULL; + } + } + + /* Some sanity checks */ + assert(0 <= mm_buf->block->ofs && mm_buf->block->ofs < mm->size); + assert(size <= mm_buf->block->size && mm_buf->block->ofs + mm_buf->block->size <= mm->size); + + _glthread_UNLOCK_MUTEX(mm->mutex); + return SUPER(mm_buf); +} + + +static void +mm_bufmgr_destroy(struct pb_manager *mgr) +{ + struct mm_pb_manager *mm = mm_pb_manager(mgr); + + _glthread_LOCK_MUTEX(mm->mutex); + + mmDestroy(mm->heap); + + pb_unmap(mm->buffer); + pb_reference(&mm->buffer, NULL); + + _glthread_UNLOCK_MUTEX(mm->mutex); + + FREE(mgr); +} + + +struct pb_manager * +mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, + size_t size, size_t align2) +{ + struct mm_pb_manager *mm; + + if(!buffer) + return NULL; + + mm = CALLOC_STRUCT(mm_pb_manager); + if (!mm) + return NULL; + + mm->base.create_buffer = mm_bufmgr_create_buffer; + mm->base.destroy = mm_bufmgr_destroy; + + mm->size = size; + mm->align2 = align2; /* 64-byte alignment */ + + _glthread_INIT_MUTEX(mm->mutex); + + mm->buffer = buffer; + + mm->map = pb_map(mm->buffer, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + if(!mm->map) + goto failure; + + mm->heap = mmInit(0, size); + if (!mm->heap) + goto failure; + + return SUPER(mm); + +failure: +if(mm->heap) + mmDestroy(mm->heap); + if(mm->map) + pb_unmap(mm->buffer); + if(mm) + FREE(mm); + return NULL; +} + + +struct pb_manager * +mm_bufmgr_create(struct pb_manager *provider, + size_t size, size_t align2) +{ + struct pb_buffer *buffer; + struct pb_manager *mgr; + struct pb_desc desc; + + assert(provider); + assert(provider->create_buffer); + + memset(&desc, 0, sizeof(desc)); + desc.alignment = 1 << align2; + + buffer = provider->create_buffer(provider, size, &desc); + if (!buffer) + return NULL; + + mgr = mm_bufmgr_create_from_buffer(buffer, size, align2); + if (!mgr) { + pb_reference(&buffer, NULL); + return NULL; + } + + return mgr; +} diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c new file mode 100644 index 0000000000..04477a865a --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -0,0 +1,288 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * \file + * Batch buffer pool management. + * + * \author José Fonseca + * \author Thomas Hellström + */ + + +#include "linked_list.h" + +#include "p_compiler.h" +#include "p_debug.h" +#include "p_thread.h" +#include "p_defines.h" +#include "p_util.h" + +#include "pb_buffer.h" +#include "pb_bufmgr.h" + + +/** + * Convenience macro (type safe). + */ +#define SUPER(__derived) (&(__derived)->base) + + +struct pool_pb_manager +{ + struct pb_manager base; + + _glthread_Mutex mutex; + + size_t bufSize; + size_t bufAlign; + + size_t numFree; + size_t numTot; + + struct list_head free; + + struct pb_buffer *buffer; + void *map; + + struct pool_buffer *bufs; +}; + + +static INLINE struct pool_pb_manager * +pool_pb_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct pool_pb_manager *)mgr; +} + + +struct pool_buffer +{ + struct pb_buffer base; + + struct pool_pb_manager *mgr; + + struct list_head head; + + size_t start; +}; + + +static INLINE struct pool_buffer * +pool_buffer(struct pb_buffer *buf) +{ + assert(buf); + return (struct pool_buffer *)buf; +} + + + +static void +pool_buffer_destroy(struct pb_buffer *buf) +{ + struct pool_buffer *pool_buf = pool_buffer(buf); + struct pool_pb_manager *pool = pool_buf->mgr; + + assert(pool_buf->base.base.refcount == 0); + + _glthread_LOCK_MUTEX(pool->mutex); + LIST_ADD(&pool_buf->head, &pool->free); + pool->numFree++; + _glthread_UNLOCK_MUTEX(pool->mutex); +} + + +static void * +pool_buffer_map(struct pb_buffer *buf, unsigned flags) +{ + struct pool_buffer *pool_buf = pool_buffer(buf); + struct pool_pb_manager *pool = pool_buf->mgr; + void *map; + + _glthread_LOCK_MUTEX(pool->mutex); + map = (unsigned char *) pool->map + pool_buf->start; + _glthread_UNLOCK_MUTEX(pool->mutex); + return map; +} + + +static void +pool_buffer_unmap(struct pb_buffer *buf) +{ + /* No-op */ +} + + +static void +pool_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + struct pool_buffer *pool_buf = pool_buffer(buf); + struct pool_pb_manager *pool = pool_buf->mgr; + pb_get_base_buffer(pool->buffer, base_buf, offset); + *offset += pool_buf->start; +} + + +static const struct pb_vtbl +pool_buffer_vtbl = { + pool_buffer_destroy, + pool_buffer_map, + pool_buffer_unmap, + pool_buffer_get_base_buffer +}; + + +static struct pb_buffer * +pool_bufmgr_create_buffer(struct pb_manager *mgr, + size_t size, + const struct pb_desc *desc) +{ + struct pool_pb_manager *pool = pool_pb_manager(mgr); + struct pool_buffer *pool_buf; + struct list_head *item; + + assert(size == pool->bufSize); + assert(pool->bufAlign % desc->alignment == 0); + + _glthread_LOCK_MUTEX(pool->mutex); + + if (pool->numFree == 0) { + _glthread_UNLOCK_MUTEX(pool->mutex); + debug_printf("warning: out of fixed size buffer objects\n"); + return NULL; + } + + item = pool->free.next; + + if (item == &pool->free) { + _glthread_UNLOCK_MUTEX(pool->mutex); + debug_printf("error: fixed size buffer pool corruption\n"); + return NULL; + } + + LIST_DEL(item); + --pool->numFree; + + _glthread_UNLOCK_MUTEX(pool->mutex); + + pool_buf = LIST_ENTRY(struct pool_buffer, item, head); + assert(pool_buf->base.base.refcount == 0); + pool_buf->base.base.refcount = 1; + pool_buf->base.base.alignment = desc->alignment; + pool_buf->base.base.usage = desc->usage; + + return SUPER(pool_buf); +} + + +static void +pool_bufmgr_destroy(struct pb_manager *mgr) +{ + struct pool_pb_manager *pool = pool_pb_manager(mgr); + _glthread_LOCK_MUTEX(pool->mutex); + + FREE(pool->bufs); + + pb_unmap(pool->buffer); + pb_reference(&pool->buffer, NULL); + + _glthread_UNLOCK_MUTEX(pool->mutex); + + FREE(mgr); +} + + +struct pb_manager * +pool_bufmgr_create(struct pb_manager *provider, + size_t numBufs, + size_t bufSize, + const struct pb_desc *desc) +{ + struct pool_pb_manager *pool; + struct pool_buffer *pool_buf; + size_t i; + + pool = (struct pool_pb_manager *)CALLOC(1, sizeof(*pool)); + if (!pool) + return NULL; + + pool->base.destroy = pool_bufmgr_destroy; + pool->base.create_buffer = pool_bufmgr_create_buffer; + + LIST_INITHEAD(&pool->free); + + pool->numTot = numBufs; + pool->numFree = numBufs; + pool->bufSize = bufSize; + pool->bufAlign = desc->alignment; + + _glthread_INIT_MUTEX(pool->mutex); + + pool->buffer = provider->create_buffer(provider, numBufs*bufSize, desc); + if (!pool->buffer) + goto failure; + + pool->map = pb_map(pool->buffer, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + if(!pool->map) + goto failure; + + pool->bufs = (struct pool_buffer *)CALLOC(numBufs, sizeof(*pool->bufs)); + if (!pool->bufs) + goto failure; + + pool_buf = pool->bufs; + for (i = 0; i < numBufs; ++i) { + pool_buf->base.base.refcount = 0; + pool_buf->base.base.alignment = 0; + pool_buf->base.base.usage = 0; + pool_buf->base.base.size = bufSize; + pool_buf->base.vtbl = &pool_buffer_vtbl; + pool_buf->mgr = pool; + pool_buf->start = i * bufSize; + LIST_ADDTAIL(&pool_buf->head, &pool->free); + pool_buf++; + } + + return SUPER(pool); + +failure: + if(pool->bufs) + FREE(pool->bufs); + if(pool->map) + pb_unmap(pool->buffer); + if(pool->buffer) + pb_reference(&pool->buffer, NULL); + if(pool) + FREE(pool); + return NULL; +} diff --git a/src/gallium/auxiliary/pipebuffer/pb_winsys.c b/src/gallium/auxiliary/pipebuffer/pb_winsys.c new file mode 100644 index 0000000000..978944091f --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_winsys.c @@ -0,0 +1,170 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Implementation of client buffer (also designated as "user buffers"), which + * are just state-tracker owned data masqueraded as buffers. + * + * \author José Fonseca + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "pb_buffer.h" + + +/** + * User buffers are special buffers that initially reference memory + * held by the user but which may if necessary copy that memory into + * device memory behind the scenes, for submission to hardware. + * + * These are particularly useful when the referenced data is never + * submitted to hardware at all, in the particular case of software + * vertex processing. + */ +struct pb_user_buffer +{ + struct pb_buffer base; + void *data; +}; + + +extern const struct pb_vtbl pb_user_buffer_vtbl; + + +static INLINE struct pb_user_buffer * +pb_user_buffer(struct pb_buffer *buf) +{ + assert(buf); + assert(buf->vtbl == &pb_user_buffer_vtbl); + return (struct pb_user_buffer *)buf; +} + + +static void +pb_user_buffer_destroy(struct pb_buffer *buf) +{ + assert(buf); + FREE(buf); +} + + +static void * +pb_user_buffer_map(struct pb_buffer *buf, + unsigned flags) +{ + return pb_user_buffer(buf)->data; +} + + +static void +pb_user_buffer_unmap(struct pb_buffer *buf) +{ + /* No-op */ +} + + +static void +pb_user_buffer_get_base_buffer(struct pb_buffer *buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + *base_buf = buf; + *offset = 0; +} + + +const struct pb_vtbl +pb_user_buffer_vtbl = { + pb_user_buffer_destroy, + pb_user_buffer_map, + pb_user_buffer_unmap, + pb_user_buffer_get_base_buffer +}; + + +static struct pipe_buffer * +pb_winsys_user_buffer_create(struct pipe_winsys *winsys, + void *data, + unsigned bytes) +{ + struct pb_user_buffer *buf = CALLOC_STRUCT(pb_user_buffer); + + if(!buf) + return NULL; + + buf->base.base.refcount = 1; + buf->base.base.size = bytes; + buf->base.base.alignment = 0; + buf->base.base.usage = 0; + + buf->base.vtbl = &pb_user_buffer_vtbl; + buf->data = data; + + return &buf->base.base; +} + + +static void * +pb_winsys_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags) +{ + (void)winsys; + return pb_map(pb_buffer(buf), flags); +} + + +static void +pb_winsys_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + (void)winsys; + pb_unmap(pb_buffer(buf)); +} + + +static void +pb_winsys_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + (void)winsys; + pb_destroy(pb_buffer(buf)); +} + + +void +pb_init_winsys(struct pipe_winsys *winsys) +{ + winsys->user_buffer_create = pb_winsys_user_buffer_create; + winsys->buffer_map = pb_winsys_buffer_map; + winsys->buffer_unmap = pb_winsys_buffer_unmap; + winsys->buffer_destroy = pb_winsys_buffer_destroy; +} diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile new file mode 100644 index 0000000000..12a8bd0409 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -0,0 +1,3 @@ +default: + cd ../.. ; make + diff --git a/src/gallium/auxiliary/tgsi/exec/Makefile b/src/gallium/auxiliary/tgsi/exec/Makefile new file mode 100644 index 0000000000..eb8b14e0e8 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/exec/Makefile @@ -0,0 +1,3 @@ +default: + cd ../../.. ; make + diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c new file mode 100644 index 0000000000..a8f64c2287 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -0,0 +1,2485 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * TGSI interpretor/executor. + * + * Flow control information: + * + * Since we operate on 'quads' (4 pixels or 4 vertices in parallel) + * flow control statements (IF/ELSE/ENDIF, LOOP/ENDLOOP) require special + * care since a condition may be true for some quad components but false + * for other components. + * + * We basically execute all statements (even if they're in the part of + * an IF/ELSE clause that's "not taken") and use a special mask to + * control writing to destination registers. This is the ExecMask. + * See store_dest(). + * + * The ExecMask is computed from three other masks (CondMask, LoopMask and + * ContMask) which are controlled by the flow control instructions (namely: + * (IF/ELSE/ENDIF, LOOP/ENDLOOP and CONT). + * + * + * Authors: + * Michal Krol + * Brian Paul + */ + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" +#include "tgsi_exec.h" + +#define TILE_TOP_LEFT 0 +#define TILE_TOP_RIGHT 1 +#define TILE_BOTTOM_LEFT 2 +#define TILE_BOTTOM_RIGHT 3 + +/* + * Shorthand locations of various utility registers (_I = Index, _C = Channel) + */ +#define TEMP_0_I TGSI_EXEC_TEMP_00000000_I +#define TEMP_0_C TGSI_EXEC_TEMP_00000000_C +#define TEMP_7F_I TGSI_EXEC_TEMP_7FFFFFFF_I +#define TEMP_7F_C TGSI_EXEC_TEMP_7FFFFFFF_C +#define TEMP_80_I TGSI_EXEC_TEMP_80000000_I +#define TEMP_80_C TGSI_EXEC_TEMP_80000000_C +#define TEMP_FF_I TGSI_EXEC_TEMP_FFFFFFFF_I +#define TEMP_FF_C TGSI_EXEC_TEMP_FFFFFFFF_C +#define TEMP_1_I TGSI_EXEC_TEMP_ONE_I +#define TEMP_1_C TGSI_EXEC_TEMP_ONE_C +#define TEMP_2_I TGSI_EXEC_TEMP_TWO_I +#define TEMP_2_C TGSI_EXEC_TEMP_TWO_C +#define TEMP_128_I TGSI_EXEC_TEMP_128_I +#define TEMP_128_C TGSI_EXEC_TEMP_128_C +#define TEMP_M128_I TGSI_EXEC_TEMP_MINUS_128_I +#define TEMP_M128_C TGSI_EXEC_TEMP_MINUS_128_C +#define TEMP_KILMASK_I TGSI_EXEC_TEMP_KILMASK_I +#define TEMP_KILMASK_C TGSI_EXEC_TEMP_KILMASK_C +#define TEMP_OUTPUT_I TGSI_EXEC_TEMP_OUTPUT_I +#define TEMP_OUTPUT_C TGSI_EXEC_TEMP_OUTPUT_C +#define TEMP_PRIMITIVE_I TGSI_EXEC_TEMP_PRIMITIVE_I +#define TEMP_PRIMITIVE_C TGSI_EXEC_TEMP_PRIMITIVE_C +#define TEMP_R0 TGSI_EXEC_TEMP_R0 + +#define FOR_EACH_CHANNEL(CHAN)\ + for (CHAN = 0; CHAN < 4; CHAN++) + +#define IS_CHANNEL_ENABLED(INST, CHAN)\ + ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) + +#define IS_CHANNEL_ENABLED2(INST, CHAN)\ + ((INST).FullDstRegisters[1].DstRegister.WriteMask & (1 << (CHAN))) + +#define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\ + FOR_EACH_CHANNEL( CHAN )\ + if (IS_CHANNEL_ENABLED( INST, CHAN )) + +#define FOR_EACH_ENABLED_CHANNEL2(INST, CHAN)\ + FOR_EACH_CHANNEL( CHAN )\ + if (IS_CHANNEL_ENABLED2( INST, CHAN )) + + +/** The execution mask depends on the conditional mask and the loop mask */ +#define UPDATE_EXEC_MASK(MACH) \ + MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask + + +#define CHAN_X 0 +#define CHAN_Y 1 +#define CHAN_Z 2 +#define CHAN_W 3 + + + +static void +tgsi_exec_prepare( struct tgsi_exec_machine *mach ) +{ + struct tgsi_exec_labels *labels = &mach->Labels; + struct tgsi_parse_context parse; + struct tgsi_full_instruction *instructions; + struct tgsi_full_declaration *declarations; + uint maxInstructions = 10, numInstructions = 0; + uint maxDeclarations = 10, numDeclarations = 0; + uint k; + uint instno = 0; + + mach->ImmLimit = 0; + labels->count = 0; + + declarations = (struct tgsi_full_declaration *) + MALLOC( maxDeclarations * sizeof(struct tgsi_full_declaration) ); + + instructions = (struct tgsi_full_instruction *) + MALLOC( maxInstructions * sizeof(struct tgsi_full_instruction) ); + + k = tgsi_parse_init( &parse, mach->Tokens ); + if (k != TGSI_PARSE_OK) { + debug_printf("Problem parsing!\n"); + return; + } + + while( !tgsi_parse_end_of_tokens( &parse ) ) { + uint pointer = parse.Position; + uint i; + + tgsi_parse_token( &parse ); + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + /* save expanded declaration */ + if (numDeclarations == maxDeclarations) { + declarations = REALLOC(declarations, + maxDeclarations + * sizeof(struct tgsi_full_declaration), + (maxDeclarations + 10) + * sizeof(struct tgsi_full_declaration)); + maxDeclarations += 10; + } + memcpy(declarations + numDeclarations, + &parse.FullToken.FullDeclaration, + sizeof(declarations[0])); + numDeclarations++; + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; + assert( size % 4 == 0 ); + assert( mach->ImmLimit + size / 4 <= TGSI_EXEC_NUM_IMMEDIATES ); + + for( i = 0; i < size; i++ ) { + mach->Imms[mach->ImmLimit + i / 4][i % 4] = parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; + } + mach->ImmLimit += size / 4; + } + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + assert( labels->count < 128 ); + + labels->labels[labels->count][0] = instno; + labels->labels[labels->count][1] = pointer; + labels->count++; + + /* save expanded instruction */ + if (numInstructions == maxInstructions) { + instructions = REALLOC(instructions, + maxInstructions + * sizeof(struct tgsi_full_instruction), + (maxInstructions + 10) + * sizeof(struct tgsi_full_instruction)); + maxInstructions += 10; + } + memcpy(instructions + numInstructions, + &parse.FullToken.FullInstruction, + sizeof(instructions[0])); + numInstructions++; + break; + + default: + assert( 0 ); + } + } + tgsi_parse_free (&parse); + + if (mach->Declarations) { + FREE( mach->Declarations ); + } + mach->Declarations = declarations; + mach->NumDeclarations = numDeclarations; + + if (mach->Instructions) { + FREE( mach->Instructions ); + } + mach->Instructions = instructions; + mach->NumInstructions = numInstructions; +} + + +/** + * Initialize machine state by expanding tokens to full instructions, + * allocating temporary storage, setting up constants, etc. + * After this, we can call tgsi_exec_machine_run() many times. + */ +void +tgsi_exec_machine_init( + struct tgsi_exec_machine *mach, + const struct tgsi_token *tokens, + uint numSamplers, + struct tgsi_sampler *samplers) +{ + uint i, k; + struct tgsi_parse_context parse; + +#if 0 + tgsi_dump(tokens, 0); +#endif + + mach->Tokens = tokens; + + mach->Samplers = samplers; + + k = tgsi_parse_init (&parse, mach->Tokens); + if (k != TGSI_PARSE_OK) { + debug_printf( "Problem parsing!\n" ); + return; + } + + mach->Processor = parse.FullHeader.Processor.Processor; + tgsi_parse_free (&parse); + + mach->Temps = (struct tgsi_exec_vector *) tgsi_align_128bit( mach->_Temps); + mach->Addrs = &mach->Temps[TGSI_EXEC_NUM_TEMPS]; + + /* Setup constants. */ + for( i = 0; i < 4; i++ ) { + mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].u[i] = 0x00000000; + mach->Temps[TEMP_7F_I].xyzw[TEMP_7F_C].u[i] = 0x7FFFFFFF; + mach->Temps[TEMP_80_I].xyzw[TEMP_80_C].u[i] = 0x80000000; + mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].u[i] = 0xFFFFFFFF; + mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].f[i] = 1.0f; + mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].f[i] = 2.0f; + mach->Temps[TEMP_128_I].xyzw[TEMP_128_C].f[i] = 128.0f; + mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C].f[i] = -128.0f; + } + + tgsi_exec_prepare( mach ); +} + + +void +tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach) +{ + if (mach->Instructions) { + FREE(mach->Instructions); + mach->Instructions = NULL; + mach->NumInstructions = 0; + } + if (mach->Declarations) { + FREE(mach->Declarations); + mach->Declarations = NULL; + mach->NumDeclarations = 0; + } +} + + +static void +micro_abs( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) fabs( (double) src->f[0] ); + dst->f[1] = (float) fabs( (double) src->f[1] ); + dst->f[2] = (float) fabs( (double) src->f[2] ); + dst->f[3] = (float) fabs( (double) src->f[3] ); +} + +static void +micro_add( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] + src1->f[0]; + dst->f[1] = src0->f[1] + src1->f[1]; + dst->f[2] = src0->f[2] + src1->f[2]; + dst->f[3] = src0->f[3] + src1->f[3]; +} + +static void +micro_iadd( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] + src1->i[0]; + dst->i[1] = src0->i[1] + src1->i[1]; + dst->i[2] = src0->i[2] + src1->i[2]; + dst->i[3] = src0->i[3] + src1->i[3]; +} + +static void +micro_and( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] & src1->u[0]; + dst->u[1] = src0->u[1] & src1->u[1]; + dst->u[2] = src0->u[2] & src1->u[2]; + dst->u[3] = src0->u[3] & src1->u[3]; +} + +static void +micro_ceil( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) ceil( (double) src->f[0] ); + dst->f[1] = (float) ceil( (double) src->f[1] ); + dst->f[2] = (float) ceil( (double) src->f[2] ); + dst->f[3] = (float) ceil( (double) src->f[3] ); +} + +static void +micro_cos( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) cos( (double) src->f[0] ); + dst->f[1] = (float) cos( (double) src->f[1] ); + dst->f[2] = (float) cos( (double) src->f[2] ); + dst->f[3] = (float) cos( (double) src->f[3] ); +} + +static void +micro_ddx( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = + dst->f[1] = + dst->f[2] = + dst->f[3] = src->f[TILE_BOTTOM_RIGHT] - src->f[TILE_BOTTOM_LEFT]; +} + +static void +micro_ddy( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = + dst->f[1] = + dst->f[2] = + dst->f[3] = src->f[TILE_TOP_LEFT] - src->f[TILE_BOTTOM_LEFT]; +} + +static void +micro_div( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] / src1->f[0]; + dst->f[1] = src0->f[1] / src1->f[1]; + dst->f[2] = src0->f[2] / src1->f[2]; + dst->f[3] = src0->f[3] / src1->f[3]; +} + +static void +micro_udiv( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] / src1->u[0]; + dst->u[1] = src0->u[1] / src1->u[1]; + dst->u[2] = src0->u[2] / src1->u[2]; + dst->u[3] = src0->u[3] / src1->u[3]; +} + +static void +micro_eq( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] == src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] == src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] == src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] == src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_ieq( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->i[0] = src0->i[0] == src1->i[0] ? src2->i[0] : src3->i[0]; + dst->i[1] = src0->i[1] == src1->i[1] ? src2->i[1] : src3->i[1]; + dst->i[2] = src0->i[2] == src1->i[2] ? src2->i[2] : src3->i[2]; + dst->i[3] = src0->i[3] == src1->i[3] ? src2->i[3] : src3->i[3]; +} + +static void +micro_exp2( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src) +{ + dst->f[0] = (float) pow( 2.0, (double) src->f[0] ); + dst->f[1] = (float) pow( 2.0, (double) src->f[1] ); + dst->f[2] = (float) pow( 2.0, (double) src->f[2] ); + dst->f[3] = (float) pow( 2.0, (double) src->f[3] ); +} + +static void +micro_f2it( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->i[0] = (int) src->f[0]; + dst->i[1] = (int) src->f[1]; + dst->i[2] = (int) src->f[2]; + dst->i[3] = (int) src->f[3]; +} + +static void +micro_f2ut( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->u[0] = (uint) src->f[0]; + dst->u[1] = (uint) src->f[1]; + dst->u[2] = (uint) src->f[2]; + dst->u[3] = (uint) src->f[3]; +} + +static void +micro_flr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) floor( (double) src->f[0] ); + dst->f[1] = (float) floor( (double) src->f[1] ); + dst->f[2] = (float) floor( (double) src->f[2] ); + dst->f[3] = (float) floor( (double) src->f[3] ); +} + +static void +micro_frc( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = src->f[0] - (float) floor( (double) src->f[0] ); + dst->f[1] = src->f[1] - (float) floor( (double) src->f[1] ); + dst->f[2] = src->f[2] - (float) floor( (double) src->f[2] ); + dst->f[3] = src->f[3] - (float) floor( (double) src->f[3] ); +} + +static void +micro_ge( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] >= src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] >= src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] >= src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] >= src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_i2f( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) src->i[0]; + dst->f[1] = (float) src->i[1]; + dst->f[2] = (float) src->i[2]; + dst->f[3] = (float) src->i[3]; +} + +static void +micro_lg2( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) log( (double) src->f[0] ) * 1.442695f; + dst->f[1] = (float) log( (double) src->f[1] ) * 1.442695f; + dst->f[2] = (float) log( (double) src->f[2] ) * 1.442695f; + dst->f[3] = (float) log( (double) src->f[3] ) * 1.442695f; +} + +static void +micro_lt( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] < src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] < src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] < src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] < src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_ilt( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->i[0] = src0->i[0] < src1->i[0] ? src2->i[0] : src3->i[0]; + dst->i[1] = src0->i[1] < src1->i[1] ? src2->i[1] : src3->i[1]; + dst->i[2] = src0->i[2] < src1->i[2] ? src2->i[2] : src3->i[2]; + dst->i[3] = src0->i[3] < src1->i[3] ? src2->i[3] : src3->i[3]; +} + +static void +micro_ult( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->u[0] = src0->u[0] < src1->u[0] ? src2->u[0] : src3->u[0]; + dst->u[1] = src0->u[1] < src1->u[1] ? src2->u[1] : src3->u[1]; + dst->u[2] = src0->u[2] < src1->u[2] ? src2->u[2] : src3->u[2]; + dst->u[3] = src0->u[3] < src1->u[3] ? src2->u[3] : src3->u[3]; +} + +static void +micro_max( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] > src1->f[0] ? src0->f[0] : src1->f[0]; + dst->f[1] = src0->f[1] > src1->f[1] ? src0->f[1] : src1->f[1]; + dst->f[2] = src0->f[2] > src1->f[2] ? src0->f[2] : src1->f[2]; + dst->f[3] = src0->f[3] > src1->f[3] ? src0->f[3] : src1->f[3]; +} + +static void +micro_imax( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] > src1->i[0] ? src0->i[0] : src1->i[0]; + dst->i[1] = src0->i[1] > src1->i[1] ? src0->i[1] : src1->i[1]; + dst->i[2] = src0->i[2] > src1->i[2] ? src0->i[2] : src1->i[2]; + dst->i[3] = src0->i[3] > src1->i[3] ? src0->i[3] : src1->i[3]; +} + +static void +micro_umax( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] > src1->u[0] ? src0->u[0] : src1->u[0]; + dst->u[1] = src0->u[1] > src1->u[1] ? src0->u[1] : src1->u[1]; + dst->u[2] = src0->u[2] > src1->u[2] ? src0->u[2] : src1->u[2]; + dst->u[3] = src0->u[3] > src1->u[3] ? src0->u[3] : src1->u[3]; +} + +static void +micro_min( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] < src1->f[0] ? src0->f[0] : src1->f[0]; + dst->f[1] = src0->f[1] < src1->f[1] ? src0->f[1] : src1->f[1]; + dst->f[2] = src0->f[2] < src1->f[2] ? src0->f[2] : src1->f[2]; + dst->f[3] = src0->f[3] < src1->f[3] ? src0->f[3] : src1->f[3]; +} + +static void +micro_imin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] < src1->i[0] ? src0->i[0] : src1->i[0]; + dst->i[1] = src0->i[1] < src1->i[1] ? src0->i[1] : src1->i[1]; + dst->i[2] = src0->i[2] < src1->i[2] ? src0->i[2] : src1->i[2]; + dst->i[3] = src0->i[3] < src1->i[3] ? src0->i[3] : src1->i[3]; +} + +static void +micro_umin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] < src1->u[0] ? src0->u[0] : src1->u[0]; + dst->u[1] = src0->u[1] < src1->u[1] ? src0->u[1] : src1->u[1]; + dst->u[2] = src0->u[2] < src1->u[2] ? src0->u[2] : src1->u[2]; + dst->u[3] = src0->u[3] < src1->u[3] ? src0->u[3] : src1->u[3]; +} + +static void +micro_umod( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] % src1->u[0]; + dst->u[1] = src0->u[1] % src1->u[1]; + dst->u[2] = src0->u[2] % src1->u[2]; + dst->u[3] = src0->u[3] % src1->u[3]; +} + +static void +micro_mul( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] * src1->f[0]; + dst->f[1] = src0->f[1] * src1->f[1]; + dst->f[2] = src0->f[2] * src1->f[2]; + dst->f[3] = src0->f[3] * src1->f[3]; +} + +static void +micro_imul( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] * src1->i[0]; + dst->i[1] = src0->i[1] * src1->i[1]; + dst->i[2] = src0->i[2] * src1->i[2]; + dst->i[3] = src0->i[3] * src1->i[3]; +} + +static void +micro_imul64( + union tgsi_exec_channel *dst0, + union tgsi_exec_channel *dst1, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst1->i[0] = src0->i[0] * src1->i[0]; + dst1->i[1] = src0->i[1] * src1->i[1]; + dst1->i[2] = src0->i[2] * src1->i[2]; + dst1->i[3] = src0->i[3] * src1->i[3]; + dst0->i[0] = 0; + dst0->i[1] = 0; + dst0->i[2] = 0; + dst0->i[3] = 0; +} + +static void +micro_umul64( + union tgsi_exec_channel *dst0, + union tgsi_exec_channel *dst1, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst1->u[0] = src0->u[0] * src1->u[0]; + dst1->u[1] = src0->u[1] * src1->u[1]; + dst1->u[2] = src0->u[2] * src1->u[2]; + dst1->u[3] = src0->u[3] * src1->u[3]; + dst0->u[0] = 0; + dst0->u[1] = 0; + dst0->u[2] = 0; + dst0->u[3] = 0; +} + +static void +micro_movc( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2 ) +{ + dst->u[0] = src0->u[0] ? src1->u[0] : src2->u[0]; + dst->u[1] = src0->u[1] ? src1->u[1] : src2->u[1]; + dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2]; + dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3]; +} + +static void +micro_neg( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = -src->f[0]; + dst->f[1] = -src->f[1]; + dst->f[2] = -src->f[2]; + dst->f[3] = -src->f[3]; +} + +static void +micro_ineg( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->i[0] = -src->i[0]; + dst->i[1] = -src->i[1]; + dst->i[2] = -src->i[2]; + dst->i[3] = -src->i[3]; +} + +static void +micro_not( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->u[0] = ~src->u[0]; + dst->u[1] = ~src->u[1]; + dst->u[2] = ~src->u[2]; + dst->u[3] = ~src->u[3]; +} + +static void +micro_or( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] | src1->u[0]; + dst->u[1] = src0->u[1] | src1->u[1]; + dst->u[2] = src0->u[2] | src1->u[2]; + dst->u[3] = src0->u[3] | src1->u[3]; +} + +static void +micro_pow( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = (float) pow( (double) src0->f[0], (double) src1->f[0] ); + dst->f[1] = (float) pow( (double) src0->f[1], (double) src1->f[1] ); + dst->f[2] = (float) pow( (double) src0->f[2], (double) src1->f[2] ); + dst->f[3] = (float) pow( (double) src0->f[3], (double) src1->f[3] ); +} + +static void +micro_rnd( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) floor( (double) (src->f[0] + 0.5f) ); + dst->f[1] = (float) floor( (double) (src->f[1] + 0.5f) ); + dst->f[2] = (float) floor( (double) (src->f[2] + 0.5f) ); + dst->f[3] = (float) floor( (double) (src->f[3] + 0.5f) ); +} + +static void +micro_shl( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] << src1->i[0]; + dst->i[1] = src0->i[1] << src1->i[1]; + dst->i[2] = src0->i[2] << src1->i[2]; + dst->i[3] = src0->i[3] << src1->i[3]; +} + +static void +micro_ishr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] >> src1->i[0]; + dst->i[1] = src0->i[1] >> src1->i[1]; + dst->i[2] = src0->i[2] >> src1->i[2]; + dst->i[3] = src0->i[3] >> src1->i[3]; +} + +static void +micro_trunc( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0 ) +{ + dst->f[0] = (float) (int) src0->f[0]; + dst->f[1] = (float) (int) src0->f[1]; + dst->f[2] = (float) (int) src0->f[2]; + dst->f[3] = (float) (int) src0->f[3]; +} + +static void +micro_ushr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] >> src1->u[0]; + dst->u[1] = src0->u[1] >> src1->u[1]; + dst->u[2] = src0->u[2] >> src1->u[2]; + dst->u[3] = src0->u[3] >> src1->u[3]; +} + +static void +micro_sin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) sin( (double) src->f[0] ); + dst->f[1] = (float) sin( (double) src->f[1] ); + dst->f[2] = (float) sin( (double) src->f[2] ); + dst->f[3] = (float) sin( (double) src->f[3] ); +} + +static void +micro_sqrt( union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) sqrt( (double) src->f[0] ); + dst->f[1] = (float) sqrt( (double) src->f[1] ); + dst->f[2] = (float) sqrt( (double) src->f[2] ); + dst->f[3] = (float) sqrt( (double) src->f[3] ); +} + +static void +micro_sub( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] - src1->f[0]; + dst->f[1] = src0->f[1] - src1->f[1]; + dst->f[2] = src0->f[2] - src1->f[2]; + dst->f[3] = src0->f[3] - src1->f[3]; +} + +static void +micro_u2f( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) src->u[0]; + dst->f[1] = (float) src->u[1]; + dst->f[2] = (float) src->u[2]; + dst->f[3] = (float) src->u[3]; +} + +static void +micro_xor( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] ^ src1->u[0]; + dst->u[1] = src0->u[1] ^ src1->u[1]; + dst->u[2] = src0->u[2] ^ src1->u[2]; + dst->u[3] = src0->u[3] ^ src1->u[3]; +} + +static void +fetch_src_file_channel( + const struct tgsi_exec_machine *mach, + const uint file, + const uint swizzle, + const union tgsi_exec_channel *index, + union tgsi_exec_channel *chan ) +{ + switch( swizzle ) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + switch( file ) { + case TGSI_FILE_CONSTANT: + chan->f[0] = mach->Consts[index->i[0]][swizzle]; + chan->f[1] = mach->Consts[index->i[1]][swizzle]; + chan->f[2] = mach->Consts[index->i[2]][swizzle]; + chan->f[3] = mach->Consts[index->i[3]][swizzle]; + break; + + case TGSI_FILE_INPUT: + chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Inputs[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_TEMPORARY: + chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Temps[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_IMMEDIATE: + assert( index->i[0] < (int) mach->ImmLimit ); + chan->f[0] = mach->Imms[index->i[0]][swizzle]; + assert( index->i[1] < (int) mach->ImmLimit ); + chan->f[1] = mach->Imms[index->i[1]][swizzle]; + assert( index->i[2] < (int) mach->ImmLimit ); + chan->f[2] = mach->Imms[index->i[2]][swizzle]; + assert( index->i[3] < (int) mach->ImmLimit ); + chan->f[3] = mach->Imms[index->i[3]][swizzle]; + break; + + case TGSI_FILE_ADDRESS: + chan->u[0] = mach->Addrs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Addrs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Addrs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Addrs[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_OUTPUT: + /* vertex/fragment output vars can be read too */ + chan->u[0] = mach->Outputs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Outputs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Outputs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Outputs[index->i[3]].xyzw[swizzle].u[3]; + break; + + default: + assert( 0 ); + } + break; + + case TGSI_EXTSWIZZLE_ZERO: + *chan = mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]; + break; + + case TGSI_EXTSWIZZLE_ONE: + *chan = mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]; + break; + + default: + assert( 0 ); + } +} + +static void +fetch_source( + const struct tgsi_exec_machine *mach, + union tgsi_exec_channel *chan, + const struct tgsi_full_src_register *reg, + const uint chan_index ) +{ + union tgsi_exec_channel index; + uint swizzle; + + index.i[0] = + index.i[1] = + index.i[2] = + index.i[3] = reg->SrcRegister.Index; + + if (reg->SrcRegister.Indirect) { + union tgsi_exec_channel index2; + union tgsi_exec_channel indir_index; + + index2.i[0] = + index2.i[1] = + index2.i[2] = + index2.i[3] = reg->SrcRegisterInd.Index; + + swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterInd, CHAN_X ); + fetch_src_file_channel( + mach, + reg->SrcRegisterInd.File, + swizzle, + &index2, + &indir_index ); + + index.i[0] += indir_index.i[0]; + index.i[1] += indir_index.i[1]; + index.i[2] += indir_index.i[2]; + index.i[3] += indir_index.i[3]; + } + + if( reg->SrcRegister.Dimension ) { + switch( reg->SrcRegister.File ) { + case TGSI_FILE_INPUT: + index.i[0] *= 17; + index.i[1] *= 17; + index.i[2] *= 17; + index.i[3] *= 17; + break; + case TGSI_FILE_CONSTANT: + index.i[0] *= 4096; + index.i[1] *= 4096; + index.i[2] *= 4096; + index.i[3] *= 4096; + break; + default: + assert( 0 ); + } + + index.i[0] += reg->SrcRegisterDim.Index; + index.i[1] += reg->SrcRegisterDim.Index; + index.i[2] += reg->SrcRegisterDim.Index; + index.i[3] += reg->SrcRegisterDim.Index; + + if (reg->SrcRegisterDim.Indirect) { + union tgsi_exec_channel index2; + union tgsi_exec_channel indir_index; + + index2.i[0] = + index2.i[1] = + index2.i[2] = + index2.i[3] = reg->SrcRegisterDimInd.Index; + + swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterDimInd, CHAN_X ); + fetch_src_file_channel( + mach, + reg->SrcRegisterDimInd.File, + swizzle, + &index2, + &indir_index ); + + index.i[0] += indir_index.i[0]; + index.i[1] += indir_index.i[1]; + index.i[2] += indir_index.i[2]; + index.i[3] += indir_index.i[3]; + } + } + + swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); + fetch_src_file_channel( + mach, + reg->SrcRegister.File, + swizzle, + &index, + chan ); + + switch (tgsi_util_get_full_src_register_sign_mode( reg, chan_index )) { + case TGSI_UTIL_SIGN_CLEAR: + micro_abs( chan, chan ); + break; + + case TGSI_UTIL_SIGN_SET: + micro_abs( chan, chan ); + micro_neg( chan, chan ); + break; + + case TGSI_UTIL_SIGN_TOGGLE: + micro_neg( chan, chan ); + break; + + case TGSI_UTIL_SIGN_KEEP: + break; + } + + if (reg->SrcRegisterExtMod.Complement) { + micro_sub( chan, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], chan ); + } +} + +static void +store_dest( + struct tgsi_exec_machine *mach, + const union tgsi_exec_channel *chan, + const struct tgsi_full_dst_register *reg, + const struct tgsi_full_instruction *inst, + uint chan_index ) +{ + union tgsi_exec_channel *dst; + + switch( reg->DstRegister.File ) { + case TGSI_FILE_NULL: + return; + + case TGSI_FILE_OUTPUT: + dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] + + reg->DstRegister.Index].xyzw[chan_index]; + break; + + case TGSI_FILE_TEMPORARY: + dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index]; + break; + + case TGSI_FILE_ADDRESS: + dst = &mach->Addrs[reg->DstRegister.Index].xyzw[chan_index]; + break; + + default: + assert( 0 ); + return; + } + + switch (inst->Instruction.Saturate) + { + case TGSI_SAT_NONE: + if (mach->ExecMask & 0x1) + dst->i[0] = chan->i[0]; + if (mach->ExecMask & 0x2) + dst->i[1] = chan->i[1]; + if (mach->ExecMask & 0x4) + dst->i[2] = chan->i[2]; + if (mach->ExecMask & 0x8) + dst->i[3] = chan->i[3]; + break; + + case TGSI_SAT_ZERO_ONE: + /* XXX need to obey ExecMask here */ + micro_max(dst, chan, &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]); + micro_min(dst, dst, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]); + break; + + case TGSI_SAT_MINUS_PLUS_ONE: + assert( 0 ); + break; + + default: + assert( 0 ); + } +} + +#define FETCH(VAL,INDEX,CHAN)\ + fetch_source (mach, VAL, &inst->FullSrcRegisters[INDEX], CHAN) + +#define STORE(VAL,INDEX,CHAN)\ + store_dest (mach, VAL, &inst->FullDstRegisters[INDEX], inst, CHAN ) + + +/** + * Execute ARB-style KIL which is predicated by a src register. + * Kill fragment if any of the four values is less than zero. + */ +static void +exec_kilp(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + uint uniquemask; + uint chan_index; + uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ + union tgsi_exec_channel r[1]; + + /* This mask stores component bits that were already tested. Note that + * we test if the value is less than zero, so 1.0 and 0.0 need not to be + * tested. */ + uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); + + for (chan_index = 0; chan_index < 4; chan_index++) + { + uint swizzle; + uint i; + + /* unswizzle channel */ + swizzle = tgsi_util_get_full_src_register_extswizzle ( + &inst->FullSrcRegisters[0], + chan_index); + + /* check if the component has not been already tested */ + if (uniquemask & (1 << swizzle)) + continue; + uniquemask |= 1 << swizzle; + + FETCH(&r[0], 0, chan_index); + for (i = 0; i < 4; i++) + if (r[0].f[i] < 0.0f) + kilmask |= 1 << i; + } + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; +} + + +/* + * Fetch a texel using STR texture coordinates. + */ +static void +fetch_texel( struct tgsi_sampler *sampler, + const union tgsi_exec_channel *s, + const union tgsi_exec_channel *t, + const union tgsi_exec_channel *p, + float lodbias, /* XXX should be float[4] */ + union tgsi_exec_channel *r, + union tgsi_exec_channel *g, + union tgsi_exec_channel *b, + union tgsi_exec_channel *a ) +{ + uint j; + float rgba[NUM_CHANNELS][QUAD_SIZE]; + + sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, rgba); + + for (j = 0; j < 4; j++) { + r->f[j] = rgba[0][j]; + g->f[j] = rgba[1][j]; + b->f[j] = rgba[2][j]; + a->f[j] = rgba[3][j]; + } +} + + +static void +exec_tex(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst, + boolean biasLod) +{ + const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; + union tgsi_exec_channel r[8]; + uint chan_index; + float lodBias; + + /* debug_printf("Sampler %u unit %u\n", sampler, unit); */ + + switch (inst->InstructionExtTexture.Texture) { + case TGSI_TEXTURE_1D: + + FETCH(&r[0], 0, CHAN_X); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[1], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[1] ); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } + + if (biasLod) { + FETCH(&r[1], 0, CHAN_W); + lodBias = r[2].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], NULL, NULL, lodBias, /* S, T, P, BIAS */ + &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */ + break; + + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_RECT: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[3], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[3] ); + micro_div( &r[1], &r[1], &r[3] ); + micro_div( &r[2], &r[2], &r[3] ); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } + + if (biasLod) { + FETCH(&r[3], 0, CHAN_W); + lodBias = r[3].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], &r[1], &r[2], lodBias, /* inputs */ + &r[0], &r[1], &r[2], &r[3]); /* outputs */ + break; + + case TGSI_TEXTURE_3D: + case TGSI_TEXTURE_CUBE: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { + case TGSI_EXTSWIZZLE_W: + FETCH(&r[3], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[3] ); + micro_div( &r[1], &r[1], &r[3] ); + micro_div( &r[2], &r[2], &r[3] ); + break; + + case TGSI_EXTSWIZZLE_ONE: + break; + + default: + assert (0); + } + + if (biasLod) { + FETCH(&r[3], 0, CHAN_W); + lodBias = r[3].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], &r[1], &r[2], lodBias, + &r[0], &r[1], &r[2], &r[3]); + break; + + default: + assert (0); + } + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[chan_index], 0, chan_index ); + } +} + + +/** + * Evaluate a constant-valued coefficient at the position of the + * current quad. + */ +static void +eval_constant_coef( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + mach->Inputs[attrib].xyzw[chan].f[i] = mach->InterpCoefs[attrib].a0[chan]; + } +} + +/** + * Evaluate a linear-valued coefficient at the position of the + * current quad. + */ +static void +eval_linear_coef( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + const float x = mach->QuadPos.xyzw[0].f[0]; + const float y = mach->QuadPos.xyzw[1].f[0]; + const float dadx = mach->InterpCoefs[attrib].dadx[chan]; + const float dady = mach->InterpCoefs[attrib].dady[chan]; + const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; + mach->Inputs[attrib].xyzw[chan].f[0] = a0; + mach->Inputs[attrib].xyzw[chan].f[1] = a0 + dadx; + mach->Inputs[attrib].xyzw[chan].f[2] = a0 + dady; + mach->Inputs[attrib].xyzw[chan].f[3] = a0 + dadx + dady; +} + +/** + * Evaluate a perspective-valued coefficient at the position of the + * current quad. + */ +static void +eval_perspective_coef( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + const float x = mach->QuadPos.xyzw[0].f[0]; + const float y = mach->QuadPos.xyzw[1].f[0]; + const float dadx = mach->InterpCoefs[attrib].dadx[chan]; + const float dady = mach->InterpCoefs[attrib].dady[chan]; + const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; + const float *w = mach->QuadPos.xyzw[3].f; + /* divide by W here */ + mach->Inputs[attrib].xyzw[chan].f[0] = a0 / w[0]; + mach->Inputs[attrib].xyzw[chan].f[1] = (a0 + dadx) / w[1]; + mach->Inputs[attrib].xyzw[chan].f[2] = (a0 + dady) / w[2]; + mach->Inputs[attrib].xyzw[chan].f[3] = (a0 + dadx + dady) / w[3]; +} + + +typedef void (* eval_coef_func)( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ); + +static void +exec_declaration( + struct tgsi_exec_machine *mach, + const struct tgsi_full_declaration *decl ) +{ + if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { + if( decl->Declaration.File == TGSI_FILE_INPUT ) { + unsigned first, last, mask; + eval_coef_func eval; + + assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); + + first = decl->u.DeclarationRange.First; + last = decl->u.DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + switch( decl->Interpolation.Interpolate ) { + case TGSI_INTERPOLATE_CONSTANT: + eval = eval_constant_coef; + break; + + case TGSI_INTERPOLATE_LINEAR: + eval = eval_linear_coef; + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + eval = eval_perspective_coef; + break; + + default: + assert( 0 ); + } + + if( mask == TGSI_WRITEMASK_XYZW ) { + unsigned i, j; + + for( i = first; i <= last; i++ ) { + for( j = 0; j < NUM_CHANNELS; j++ ) { + eval( mach, i, j ); + } + } + } + else { + unsigned i, j; + + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + for( i = first; i <= last; i++ ) { + eval( mach, i, j ); + } + } + } + } + } + } +} + +static void +exec_instruction( + struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst, + int *pc ) +{ + uint chan_index; + union tgsi_exec_channel r[8]; + + (*pc)++; + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_f2it( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOV: + /* TGSI_OPCODE_SWZ */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_LIT: + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y ) || IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[0], 0, CHAN_X ); + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + micro_max( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, CHAN_Y ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[1], 0, CHAN_Y ); + micro_max( &r[1], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + + FETCH( &r[2], 0, CHAN_W ); + micro_min( &r[2], &r[2], &mach->Temps[TEMP_128_I].xyzw[TEMP_128_C] ); + micro_max( &r[2], &r[2], &mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C] ); + micro_pow( &r[1], &r[1], &r[2] ); + micro_lt( &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, CHAN_Z ); + } + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_RCP: + /* TGSI_OPCODE_RECIP */ + FETCH( &r[0], 0, CHAN_X ); + micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_RSQ: + /* TGSI_OPCODE_RECIPSQRT */ + FETCH( &r[0], 0, CHAN_X ); + micro_sqrt( &r[0], &r[0] ); + micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXP: + assert (0); + break; + + case TGSI_OPCODE_LOG: + assert (0); + break; + + case TGSI_OPCODE_MUL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + micro_mul( &r[0], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_ADD: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_add( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP3: + /* TGSI_OPCODE_DOT3 */ + FETCH( &r[0], 0, CHAN_X ); + FETCH( &r[1], 1, CHAN_X ); + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Y ); + FETCH( &r[2], 1, CHAN_Y ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Z ); + FETCH( &r[2], 1, CHAN_Z ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP4: + /* TGSI_OPCODE_DOT4 */ + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 1, CHAN_Y); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Z); + FETCH(&r[2], 1, CHAN_Z); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_W); + FETCH(&r[2], 1, CHAN_W); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DST: + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + FETCH( &r[0], 0, CHAN_Y ); + FETCH( &r[1], 1, CHAN_Y); + micro_mul( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, CHAN_Y ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[0], 0, CHAN_Z ); + STORE( &r[0], 0, CHAN_Z ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + FETCH( &r[0], 1, CHAN_W ); + STORE( &r[0], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MIN: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + /* XXX use micro_min()?? */ + micro_lt( &r[0], &r[0], &r[1], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_MAX: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + /* XXX use micro_max()?? */ + micro_lt( &r[0], &r[0], &r[1], &r[1], &r[0] ); + + STORE(&r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLT: + /* TGSI_OPCODE_SETLT */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SGE: + /* TGSI_OPCODE_SETGE */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_ge( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MAD: + /* TGSI_OPCODE_MADD */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_mul( &r[0], &r[0], &r[1] ); + FETCH( &r[1], 2, chan_index ); + micro_add( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SUB: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + micro_sub( &r[0], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_LERP: + /* TGSI_OPCODE_LRP */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + FETCH(&r[2], 2, chan_index); + + micro_sub( &r[1], &r[1], &r[2] ); + micro_mul( &r[0], &r[0], &r[1] ); + micro_add( &r[0], &r[0], &r[2] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_CND: + assert (0); + break; + + case TGSI_OPCODE_CND0: + assert (0); + break; + + case TGSI_OPCODE_DOT2ADD: + /* TGSI_OPCODE_DP2A */ + assert (0); + break; + + case TGSI_OPCODE_INDEX: + assert (0); + break; + + case TGSI_OPCODE_NEGATE: + assert (0); + break; + + case TGSI_OPCODE_FRAC: + /* TGSI_OPCODE_FRC */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_frc( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_CLAMP: + assert (0); + break; + + case TGSI_OPCODE_FLOOR: + /* TGSI_OPCODE_FLR */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_flr( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_ROUND: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_rnd( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXPBASE2: + /* TGSI_OPCODE_EX2 */ + FETCH(&r[0], 0, CHAN_X); + + micro_pow( &r[0], &mach->Temps[TEMP_2_I].xyzw[TEMP_2_C], &r[0] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_LOGBASE2: + /* TGSI_OPCODE_LG2 */ + FETCH( &r[0], 0, CHAN_X ); + micro_lg2( &r[0], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_POWER: + /* TGSI_OPCODE_POW */ + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_pow( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_CROSSPRODUCT: + /* TGSI_OPCODE_XPD */ + FETCH(&r[0], 0, CHAN_Y); + FETCH(&r[1], 1, CHAN_Z); + + micro_mul( &r[2], &r[0], &r[1] ); + + FETCH(&r[3], 0, CHAN_Z); + FETCH(&r[4], 1, CHAN_Y); + + micro_mul( &r[5], &r[3], &r[4] ); + micro_sub( &r[2], &r[2], &r[5] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &r[2], 0, CHAN_X ); + } + + FETCH(&r[2], 1, CHAN_X); + + micro_mul( &r[3], &r[3], &r[2] ); + + FETCH(&r[5], 0, CHAN_X); + + micro_mul( &r[1], &r[1], &r[5] ); + micro_sub( &r[3], &r[3], &r[1] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + STORE( &r[3], 0, CHAN_Y ); + } + + micro_mul( &r[5], &r[5], &r[4] ); + micro_mul( &r[0], &r[0], &r[2] ); + micro_sub( &r[5], &r[5], &r[0] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + STORE( &r[5], 0, CHAN_Z ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MULTIPLYMATRIX: + assert (0); + break; + + case TGSI_OPCODE_ABS: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + + micro_abs( &r[0], &r[0] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_RCC: + assert (0); + break; + + case TGSI_OPCODE_DPH: + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 1, CHAN_Y); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Z); + FETCH(&r[2], 1, CHAN_Z); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 1, CHAN_W); + + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_COS: + FETCH(&r[0], 0, CHAN_X); + + micro_cos( &r[0], &r[0] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDX: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_ddx( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDY: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_ddy( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_KILP: + exec_kilp (mach, inst); + break; + + case TGSI_OPCODE_KIL: + /* for enabled ExecMask bits, set the killed bit */ + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= mach->ExecMask; + break; + + case TGSI_OPCODE_PK2H: + assert (0); + break; + + case TGSI_OPCODE_PK2US: + assert (0); + break; + + case TGSI_OPCODE_PK4B: + assert (0); + break; + + case TGSI_OPCODE_PK4UB: + assert (0); + break; + + case TGSI_OPCODE_RFL: + assert (0); + break; + + case TGSI_OPCODE_SEQ: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_eq( &r[0], &r[0], &r[1], + &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], + &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SFL: + assert (0); + break; + + case TGSI_OPCODE_SGT: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SIN: + FETCH( &r[0], 0, CHAN_X ); + micro_sin( &r[0], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLE: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_ge( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SNE: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_eq( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_STR: + assert (0); + break; + + case TGSI_OPCODE_TEX: + /* simple texture lookup */ + /* src[0] = texcoord */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, FALSE); + break; + + case TGSI_OPCODE_TXB: + /* Texture lookup with lod bias */ + /* src[0] = texcoord (src[0].w = LOD bias) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, TRUE); + break; + + case TGSI_OPCODE_TXD: + /* Texture lookup with explict partial derivatives */ + /* src[0] = texcoord */ + /* src[1] = d[strq]/dx */ + /* src[2] = d[strq]/dy */ + /* src[3] = sampler unit */ + assert (0); + break; + + case TGSI_OPCODE_TXL: + /* Texture lookup with explit LOD */ + /* src[0] = texcoord (src[0].w = LOD) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, TRUE); + break; + + case TGSI_OPCODE_UP2H: + assert (0); + break; + + case TGSI_OPCODE_UP2US: + assert (0); + break; + + case TGSI_OPCODE_UP4B: + assert (0); + break; + + case TGSI_OPCODE_UP4UB: + assert (0); + break; + + case TGSI_OPCODE_X2D: + assert (0); + break; + + case TGSI_OPCODE_ARA: + assert (0); + break; + + case TGSI_OPCODE_ARR: + assert (0); + break; + + case TGSI_OPCODE_BRA: + assert (0); + break; + + case TGSI_OPCODE_CAL: + /* skip the call if no execution channels are enabled */ + if (mach->ExecMask) { + /* do the call */ + + /* push the Cond, Loop, Cont stacks */ + assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); + mach->CondStack[mach->CondStackTop++] = mach->CondMask; + assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; + assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->ContStack[mach->ContStackTop++] = mach->ContMask; + + assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING); + mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask; + + /* note that PC was already incremented above */ + mach->CallStack[mach->CallStackTop++] = *pc; + *pc = inst->InstructionExtLabel.Label; + } + break; + + case TGSI_OPCODE_RET: + mach->FuncMask &= ~mach->ExecMask; + UPDATE_EXEC_MASK(mach); + + if (mach->ExecMask == 0x0) { + /* really return now (otherwise, keep executing */ + + if (mach->CallStackTop == 0) { + /* returning from main() */ + *pc = -1; + return; + } + *pc = mach->CallStack[--mach->CallStackTop]; + + /* pop the Cond, Loop, Cont stacks */ + assert(mach->CondStackTop > 0); + mach->CondMask = mach->CondStack[--mach->CondStackTop]; + assert(mach->LoopStackTop > 0); + mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[--mach->ContStackTop]; + assert(mach->FuncStackTop > 0); + mach->FuncMask = mach->FuncStack[--mach->FuncStackTop]; + + UPDATE_EXEC_MASK(mach); + } + break; + + case TGSI_OPCODE_SSG: + assert (0); + break; + + case TGSI_OPCODE_CMP: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + FETCH(&r[2], 2, chan_index); + + micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_SCS: + if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) || IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + FETCH( &r[0], 0, CHAN_X ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) ) { + micro_cos( &r[1], &r[0] ); + STORE( &r[1], 0, CHAN_X ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + micro_sin( &r[1], &r[0] ); + STORE( &r[1], 0, CHAN_Y ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + STORE( &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], 0, CHAN_Z ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_W ) ) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_NRM: + assert (0); + break; + + case TGSI_OPCODE_DIV: + assert( 0 ); + break; + + case TGSI_OPCODE_DP2: + FETCH( &r[0], 0, CHAN_X ); + FETCH( &r[1], 1, CHAN_X ); + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Y ); + FETCH( &r[2], 1, CHAN_Y ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_IF: + /* push CondMask */ + assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); + mach->CondStack[mach->CondStackTop++] = mach->CondMask; + FETCH( &r[0], 0, CHAN_X ); + /* update CondMask */ + if( ! r[0].u[0] ) { + mach->CondMask &= ~0x1; + } + if( ! r[0].u[1] ) { + mach->CondMask &= ~0x2; + } + if( ! r[0].u[2] ) { + mach->CondMask &= ~0x4; + } + if( ! r[0].u[3] ) { + mach->CondMask &= ~0x8; + } + UPDATE_EXEC_MASK(mach); + /* Todo: If CondMask==0, jump to ELSE */ + break; + + case TGSI_OPCODE_ELSE: + /* invert CondMask wrt previous mask */ + { + uint prevMask; + assert(mach->CondStackTop > 0); + prevMask = mach->CondStack[mach->CondStackTop - 1]; + mach->CondMask = ~mach->CondMask & prevMask; + UPDATE_EXEC_MASK(mach); + /* Todo: If CondMask==0, jump to ENDIF */ + } + break; + + case TGSI_OPCODE_ENDIF: + /* pop CondMask */ + assert(mach->CondStackTop > 0); + mach->CondMask = mach->CondStack[--mach->CondStackTop]; + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_END: + /* halt execution */ + *pc = -1; + break; + + case TGSI_OPCODE_REP: + assert (0); + break; + + case TGSI_OPCODE_ENDREP: + assert (0); + break; + + case TGSI_OPCODE_PUSHA: + assert (0); + break; + + case TGSI_OPCODE_POPA: + assert (0); + break; + + case TGSI_OPCODE_CEIL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_ceil( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_I2F: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_i2f( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_NOT: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_not( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_TRUNC: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_trunc( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SHL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_shl( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SHR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_ishr( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_AND: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_and( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_OR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_or( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOD: + assert (0); + break; + + case TGSI_OPCODE_XOR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_xor( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SAD: + assert (0); + break; + + case TGSI_OPCODE_TXF: + assert (0); + break; + + case TGSI_OPCODE_TXQ: + assert (0); + break; + + case TGSI_OPCODE_EMIT: + mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16; + mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++; + break; + + case TGSI_OPCODE_ENDPRIM: + mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++; + mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0; + break; + + case TGSI_OPCODE_LOOP: + /* fall-through (for now) */ + case TGSI_OPCODE_BGNLOOP2: + /* push LoopMask and ContMasks */ + assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; + assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->ContStack[mach->ContStackTop++] = mach->ContMask; + break; + + case TGSI_OPCODE_ENDLOOP: + /* fall-through (for now at least) */ + case TGSI_OPCODE_ENDLOOP2: + /* Restore ContMask, but don't pop */ + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[mach->ContStackTop - 1]; + if (mach->LoopMask) { + /* repeat loop: jump to instruction just past BGNLOOP */ + *pc = inst->InstructionExtLabel.Label + 1; + } + else { + /* exit loop: pop LoopMask */ + assert(mach->LoopStackTop > 0); + mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; + /* pop ContMask */ + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[--mach->ContStackTop]; + } + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_BRK: + /* turn off loop channels for each enabled exec channel */ + mach->LoopMask &= ~mach->ExecMask; + /* Todo: if mach->LoopMask == 0, jump to end of loop */ + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_CONT: + /* turn off cont channels for each enabled exec channel */ + mach->ContMask &= ~mach->ExecMask; + /* Todo: if mach->LoopMask == 0, jump to end of loop */ + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_BGNSUB: + /* no-op */ + break; + + case TGSI_OPCODE_ENDSUB: + /* no-op */ + break; + + case TGSI_OPCODE_NOISE1: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE2: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE3: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE4: + assert( 0 ); + break; + + case TGSI_OPCODE_NOP: + break; + + default: + assert( 0 ); + } +} + + +/** + * Run TGSI interpreter. + * \return bitmask of "alive" quad components + */ +uint +tgsi_exec_machine_run( struct tgsi_exec_machine *mach ) +{ + uint i; + int pc = 0; + + mach->CondMask = 0xf; + mach->LoopMask = 0xf; + mach->ContMask = 0xf; + mach->FuncMask = 0xf; + mach->ExecMask = 0xf; + + mach->CondStackTop = 0; /* temporarily subvert this assertion */ + assert(mach->CondStackTop == 0); + assert(mach->LoopStackTop == 0); + assert(mach->ContStackTop == 0); + assert(mach->CallStackTop == 0); + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0; + mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0; + + if( mach->Processor == TGSI_PROCESSOR_GEOMETRY ) { + mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0] = 0; + mach->Primitives[0] = 0; + } + + + /* execute declarations (interpolants) */ + for (i = 0; i < mach->NumDeclarations; i++) { + exec_declaration( mach, mach->Declarations+i ); + } + + /* execute instructions, until pc is set to -1 */ + while (pc != -1) { + assert(pc < mach->NumInstructions); + exec_instruction( mach, mach->Instructions + pc, &pc ); + } + +#if 0 + /* we scale from floats in [0,1] to Zbuffer ints in sp_quad_depth_test.c */ + if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) { + /* + * Scale back depth component. + */ + for (i = 0; i < 4; i++) + mach->Outputs[0].xyzw[2].f[i] *= ctx->DrawBuffer->_DepthMaxF; + } +#endif + + return ~mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0]; +} + + diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h new file mode 100644 index 0000000000..1fb66ee960 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h @@ -0,0 +1,239 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#if !defined TGSI_EXEC_H +#define TGSI_EXEC_H + +#include "pipe/p_compiler.h" + +#if defined __cplusplus +extern "C" { +#endif + +#define NUM_CHANNELS 4 /* R,G,B,A */ +#define QUAD_SIZE 4 /* 4 pixel/quad */ + +/** + * Registers may be treated as float, signed int or unsigned int. + */ +union tgsi_exec_channel +{ + float f[QUAD_SIZE]; + int i[QUAD_SIZE]; + unsigned u[QUAD_SIZE]; +}; + +/** + * A vector[RGBA] of channels[4 pixels] + */ +struct tgsi_exec_vector +{ + union tgsi_exec_channel xyzw[NUM_CHANNELS]; +}; + +/** + * For fragment programs, information for computing fragment input + * values from plane equation of the triangle/line. + */ +struct tgsi_interp_coef +{ + float a0[NUM_CHANNELS]; /* in an xyzw layout */ + float dadx[NUM_CHANNELS]; + float dady[NUM_CHANNELS]; +}; + + +struct softpipe_tile_cache; /**< Opaque to TGSI */ + +/** + * Information for sampling textures, which must be implemented + * by code outside the TGSI executor. + */ +struct tgsi_sampler +{ + const struct pipe_sampler_state *state; + struct pipe_texture *texture; + /** Get samples for four fragments in a quad */ + void (*get_samples)(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]); + void *pipe; /*XXX temporary*/ + struct softpipe_tile_cache *cache; +}; + +/** + * For branching/calling subroutines. + */ +struct tgsi_exec_labels +{ + unsigned labels[128][2]; + unsigned count; +}; + +/* + * Locations of various utility registers (_I = Index, _C = Channel) + */ +#define TGSI_EXEC_TEMP_00000000_I 32 +#define TGSI_EXEC_TEMP_00000000_C 0 + +#define TGSI_EXEC_TEMP_7FFFFFFF_I 32 +#define TGSI_EXEC_TEMP_7FFFFFFF_C 1 + +#define TGSI_EXEC_TEMP_80000000_I 32 +#define TGSI_EXEC_TEMP_80000000_C 2 + +#define TGSI_EXEC_TEMP_FFFFFFFF_I 32 +#define TGSI_EXEC_TEMP_FFFFFFFF_C 3 + +#define TGSI_EXEC_TEMP_ONE_I 33 +#define TGSI_EXEC_TEMP_ONE_C 0 + +#define TGSI_EXEC_TEMP_TWO_I 33 +#define TGSI_EXEC_TEMP_TWO_C 1 + +#define TGSI_EXEC_TEMP_128_I 33 +#define TGSI_EXEC_TEMP_128_C 2 + +#define TGSI_EXEC_TEMP_MINUS_128_I 33 +#define TGSI_EXEC_TEMP_MINUS_128_C 3 + +#define TGSI_EXEC_TEMP_KILMASK_I 34 +#define TGSI_EXEC_TEMP_KILMASK_C 0 + +#define TGSI_EXEC_TEMP_OUTPUT_I 34 +#define TGSI_EXEC_TEMP_OUTPUT_C 1 + +#define TGSI_EXEC_TEMP_PRIMITIVE_I 34 +#define TGSI_EXEC_TEMP_PRIMITIVE_C 2 + +#define TGSI_EXEC_TEMP_R0 35 + +#define TGSI_EXEC_NUM_TEMPS (32 + 4) +#define TGSI_EXEC_NUM_ADDRS 1 +#define TGSI_EXEC_NUM_IMMEDIATES 256 + +#define TGSI_EXEC_MAX_COND_NESTING 10 +#define TGSI_EXEC_MAX_LOOP_NESTING 10 +#define TGSI_EXEC_MAX_CALL_NESTING 10 + +/** + * Run-time virtual machine state for executing TGSI shader. + */ +struct tgsi_exec_machine +{ + /* + * 32 program temporaries + * 4 internal temporaries + * 1 address + * 1 temporary of padding to align to 16 bytes + */ + struct tgsi_exec_vector _Temps[TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_ADDRS + 1]; + + /* + * This will point to _Temps after aligning to 16B boundary. + */ + struct tgsi_exec_vector *Temps; + struct tgsi_exec_vector *Addrs; + + struct tgsi_sampler *Samplers; + + float Imms[TGSI_EXEC_NUM_IMMEDIATES][4]; + unsigned ImmLimit; + float (*Consts)[4]; + struct tgsi_exec_vector *Inputs; + struct tgsi_exec_vector *Outputs; + const struct tgsi_token *Tokens; + unsigned Processor; + + /* GEOMETRY processor only. */ + unsigned *Primitives; + + /* FRAGMENT processor only. */ + const struct tgsi_interp_coef *InterpCoefs; + struct tgsi_exec_vector QuadPos; + + /* Conditional execution masks */ + uint CondMask; /**< For IF/ELSE/ENDIF */ + uint LoopMask; /**< For BGNLOOP/ENDLOOP */ + uint ContMask; /**< For loop CONT statements */ + uint FuncMask; /**< For function calls */ + uint ExecMask; /**< = CondMask & LoopMask */ + + /** Condition mask stack (for nested conditionals) */ + uint CondStack[TGSI_EXEC_MAX_COND_NESTING]; + int CondStackTop; + + /** Loop mask stack (for nested loops) */ + uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING]; + int LoopStackTop; + + /** Loop continue mask stack (see comments in tgsi_exec.c) */ + uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING]; + int ContStackTop; + + /** Function execution mask stack (for executing subroutine code) */ + uint FuncStack[TGSI_EXEC_MAX_CALL_NESTING]; + int FuncStackTop; + + /** Function call stack for saving/restoring the program counter */ + uint CallStack[TGSI_EXEC_MAX_CALL_NESTING]; + int CallStackTop; + + struct tgsi_full_instruction *Instructions; + uint NumInstructions; + + struct tgsi_full_declaration *Declarations; + uint NumDeclarations; + + struct tgsi_exec_labels Labels; +}; + + +void +tgsi_exec_machine_init( + struct tgsi_exec_machine *mach, + const struct tgsi_token *tokens, + unsigned numSamplers, + struct tgsi_sampler *samplers); + +uint +tgsi_exec_machine_run( + struct tgsi_exec_machine *mach ); + + +void +tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach); + + +#if defined __cplusplus +} /* extern "C" */ +#endif + +#endif /* TGSI_EXEC_H */ diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c new file mode 100755 index 0000000000..593464db3e --- /dev/null +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -0,0 +1,2378 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" +#include "tgsi_exec.h" +#include "tgsi_sse2.h" + +#include "x86/rtasm/x86sse.h" + +#if defined(__i386__) || defined(__386__) + +#define DUMP_SSE 0 + +#if DUMP_SSE + +static void +_print_reg( + struct x86_reg reg ) +{ + if (reg.mod != mod_REG) + debug_printf( "[" ); + + switch( reg.file ) { + case file_REG32: + switch( reg.idx ) { + case reg_AX: + debug_printf( "EAX" ); + break; + case reg_CX: + debug_printf( "ECX" ); + break; + case reg_DX: + debug_printf( "EDX" ); + break; + case reg_BX: + debug_printf( "EBX" ); + break; + case reg_SP: + debug_printf( "ESP" ); + break; + case reg_BP: + debug_printf( "EBP" ); + break; + case reg_SI: + debug_printf( "ESI" ); + break; + case reg_DI: + debug_printf( "EDI" ); + break; + } + break; + case file_MMX: + assert( 0 ); + break; + case file_XMM: + debug_printf( "XMM%u", reg.idx ); + break; + case file_x87: + assert( 0 ); + break; + } + + if (reg.mod == mod_DISP8 || + reg.mod == mod_DISP32) + debug_printf("+%d", reg.disp); + + if (reg.mod != mod_REG) + debug_printf( "]" ); +} + +static void +_fill( + const char *op ) +{ + unsigned count = 10 - strlen( op ); + + while( count-- ) { + debug_printf( " " ); + } +} + +#define DUMP_START() debug_printf( "\nsse-dump start ----------------" ) +#define DUMP_END() debug_printf( "\nsse-dump end ----------------\n" ) +#define DUMP( OP ) debug_printf( "\n%s", OP ) +#define DUMP_I( OP, I ) do {\ + debug_printf( "\n%s", OP );\ + _fill( OP );\ + debug_printf( "%u", I ); } while( 0 ) +#define DUMP_R( OP, R0 ) do {\ + debug_printf( "\n%s", OP );\ + _fill( OP );\ + _print_reg( R0 ); } while( 0 ) +#define DUMP_RR( OP, R0, R1 ) do {\ + debug_printf( "\n%s", OP );\ + _fill( OP );\ + _print_reg( R0 );\ + debug_printf( ", " );\ + _print_reg( R1 ); } while( 0 ) +#define DUMP_RRI( OP, R0, R1, I ) do {\ + debug_printf( "\n%s", OP );\ + _fill( OP );\ + _print_reg( R0 );\ + debug_printf( ", " );\ + _print_reg( R1 );\ + debug_printf( ", " );\ + debug_printf( "%u", I ); } while( 0 ) + +#else + +#define DUMP_START() +#define DUMP_END() +#define DUMP( OP ) +#define DUMP_I( OP, I ) +#define DUMP_R( OP, R0 ) +#define DUMP_RR( OP, R0, R1 ) +#define DUMP_RRI( OP, R0, R1, I ) + +#endif + +#define FOR_EACH_CHANNEL( CHAN )\ + for( CHAN = 0; CHAN < 4; CHAN++ ) + +#define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ + ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) + +#define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ + if( IS_DST0_CHANNEL_ENABLED( INST, CHAN )) + +#define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\ + FOR_EACH_CHANNEL( CHAN )\ + IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN ) + +#define CHAN_X 0 +#define CHAN_Y 1 +#define CHAN_Z 2 +#define CHAN_W 3 + +#define TEMP_R0 TGSI_EXEC_TEMP_R0 + +/** + * X86 utility functions. + */ + +static struct x86_reg +make_xmm( + unsigned xmm ) +{ + return x86_make_reg( + file_XMM, + (enum x86_reg_name) xmm ); +} + +/** + * X86 register mapping helpers. + */ + +static struct x86_reg +get_const_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_CX ); +} + +static struct x86_reg +get_input_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_AX ); +} + +static struct x86_reg +get_output_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_DX ); +} + +static struct x86_reg +get_temp_base( void ) +{ +#ifdef WIN32 + return x86_make_reg( + file_REG32, + reg_BX ); +#else + return x86_make_reg( + file_REG32, + reg_SI ); +#endif +} + +static struct x86_reg +get_coef_base( void ) +{ + return get_output_base(); +} + +/** + * Data access helpers. + */ + +static struct x86_reg +get_argument( + unsigned index ) +{ + return x86_make_disp( + x86_make_reg( file_REG32, reg_SP ), + (index + 1) * 4 ); +} + +static struct x86_reg +get_const( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_const_base(), + (vec * 4 + chan) * 4 ); +} + +static struct x86_reg +get_input( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_input_base(), + (vec * 4 + chan) * 16 ); +} + +static struct x86_reg +get_output( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_output_base(), + (vec * 4 + chan) * 16 ); +} + +static struct x86_reg +get_temp( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_temp_base(), + (vec * 4 + chan) * 16 ); +} + +static struct x86_reg +get_coef( + unsigned vec, + unsigned chan, + unsigned member ) +{ + return x86_make_disp( + get_coef_base(), + ((vec * 3 + member) * 4 + chan) * 4 ); +} + +/** + * X86 rtasm wrappers. + */ + +static void +emit_addps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "ADDPS", dst, src ); + sse_addps( func, dst, src ); +} + +static void +emit_andnps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "ANDNPS", dst, src ); + sse_andnps( func, dst, src ); +} + +static void +emit_andps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "ANDPS", dst, src ); + sse_andps( func, dst, src ); +} + +static void +emit_call( + struct x86_function *func, + void (* addr)() ) +{ + struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); + + DUMP_I( "CALL", addr ); + x86_mov_reg_imm( func, ecx, (unsigned long) addr ); + x86_call( func, ecx ); +} + +static void +emit_cmpps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src, + enum sse_cc cc ) +{ + DUMP_RRI( "CMPPS", dst, src, cc ); + sse_cmpps( func, dst, src, cc ); +} + +static void +emit_cvttps2dq( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "CVTTPS2DQ", dst, src ); + sse2_cvttps2dq( func, dst, src ); +} + +static void +emit_maxps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MAXPS", dst, src ); + sse_maxps( func, dst, src ); +} + +static void +emit_minps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MINPS", dst, src ); + sse_minps( func, dst, src ); +} + +static void +emit_mov( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MOV", dst, src ); + x86_mov( func, dst, src ); +} + +static void +emit_movaps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MOVAPS", dst, src ); + sse_movaps( func, dst, src ); +} + +static void +emit_movss( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MOVSS", dst, src ); + sse_movss( func, dst, src ); +} + +static void +emit_movups( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MOVUPS", dst, src ); + sse_movups( func, dst, src ); +} + +static void +emit_mulps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "MULPS", dst, src ); + sse_mulps( func, dst, src ); +} + +static void +emit_or( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "OR", dst, src ); + x86_or( func, dst, src ); +} + +static void +emit_orps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "ORPS", dst, src ); + sse_orps( func, dst, src ); +} + +static void +emit_pmovmskb( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "PMOVMSKB", dst, src ); + sse_pmovmskb( func, dst, src ); +} + +static void +emit_pop( + struct x86_function *func, + struct x86_reg dst ) +{ + DUMP_R( "POP", dst ); + x86_pop( func, dst ); +} + +static void +emit_push( + struct x86_function *func, + struct x86_reg dst ) +{ + DUMP_R( "PUSH", dst ); + x86_push( func, dst ); +} + +static void +emit_rcpps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "RCPPS", dst, src ); + sse2_rcpps( func, dst, src ); +} + +#ifdef WIN32 +static void +emit_retw( + struct x86_function *func, + unsigned size ) +{ + DUMP_I( "RET", size ); + x86_retw( func, size ); +} +#else +static void +emit_ret( + struct x86_function *func ) +{ + DUMP( "RET" ); + x86_ret( func ); +} +#endif + +static void +emit_rsqrtps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "RSQRTPS", dst, src ); + sse_rsqrtps( func, dst, src ); +} + +static void +emit_shufps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src, + unsigned char shuf ) +{ + DUMP_RRI( "SHUFPS", dst, src, shuf ); + sse_shufps( func, dst, src, shuf ); +} + +static void +emit_subps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "SUBPS", dst, src ); + sse_subps( func, dst, src ); +} + +static void +emit_xorps( + struct x86_function *func, + struct x86_reg dst, + struct x86_reg src ) +{ + DUMP_RR( "XORPS", dst, src ); + sse_xorps( func, dst, src ); +} + +/** + * Data fetch helpers. + */ + +static void +emit_const( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movss( + func, + make_xmm( xmm ), + get_const( vec, chan ) ); + emit_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); +} + +static void +emit_inputf( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movups( + func, + make_xmm( xmm ), + get_input( vec, chan ) ); +} + +static void +emit_output( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movups( + func, + get_output( vec, chan ), + make_xmm( xmm ) ); +} + +static void +emit_tempf( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movaps( + func, + make_xmm( xmm ), + get_temp( vec, chan ) ); +} + +static void +emit_coef( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan, + unsigned member ) +{ + emit_movss( + func, + make_xmm( xmm ), + get_coef( vec, chan, member ) ); + emit_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); +} + +/** + * Data store helpers. + */ + +static void +emit_inputs( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movups( + func, + get_input( vec, chan ), + make_xmm( xmm ) ); +} + +static void +emit_temps( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movaps( + func, + get_temp( vec, chan ), + make_xmm( xmm ) ); +} + +static void +emit_addrs( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_temps( + func, + xmm, + vec + TGSI_EXEC_NUM_TEMPS, + chan ); +} + +/** + * Coefficent fetch helpers. + */ + +static void +emit_coef_a0( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_coef( + func, + xmm, + vec, + chan, + 0 ); +} + +static void +emit_coef_dadx( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_coef( + func, + xmm, + vec, + chan, + 1 ); +} + +static void +emit_coef_dady( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_coef( + func, + xmm, + vec, + chan, + 2 ); +} + +/** + * Function call helpers. + */ + +static void +emit_push_gp( + struct x86_function *func ) +{ + emit_push( + func, + get_const_base() ); + emit_push( + func, + get_input_base() ); + emit_push( + func, + get_output_base() ); + + /* It is important on non-win32 platforms that temp base is pushed last. + */ + emit_push( + func, + get_temp_base() ); +} + +static void +emit_pop_gp( + struct x86_function *func ) +{ + /* Restore GP registers in a reverse order. + */ + emit_pop( + func, + get_temp_base() ); + emit_pop( + func, + get_output_base() ); + emit_pop( + func, + get_input_base() ); + emit_pop( + func, + get_const_base() ); +} + +static void +emit_func_call_dst( + struct x86_function *func, + unsigned xmm_dst, + void (*code)() ) +{ + emit_movaps( + func, + get_temp( TEMP_R0, 0 ), + make_xmm( xmm_dst ) ); + + emit_push_gp( + func ); + +#ifdef WIN32 + emit_push( + func, + get_temp( TEMP_R0, 0 ) ); +#endif + + emit_call( + func, + code ); + + emit_pop_gp( + func ); + + emit_movaps( + func, + make_xmm( xmm_dst ), + get_temp( TEMP_R0, 0 ) ); +} + +static void +emit_func_call_dst_src( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src, + void (*code)() ) +{ + emit_movaps( + func, + get_temp( TEMP_R0, 1 ), + make_xmm( xmm_src ) ); + + emit_func_call_dst( + func, + xmm_dst, + code ); +} + +/** + * Low-level instruction translators. + */ + +static void +emit_abs( + struct x86_function *func, + unsigned xmm ) +{ + emit_andps( + func, + make_xmm( xmm ), + get_temp( + TGSI_EXEC_TEMP_7FFFFFFF_I, + TGSI_EXEC_TEMP_7FFFFFFF_C ) ); +} + +static void +emit_add( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_addps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void XSTDCALL +cos4f( + float *store ) +{ +#ifdef WIN32 + store[0] = (float) cos( (double) store[0] ); + store[1] = (float) cos( (double) store[1] ); + store[2] = (float) cos( (double) store[2] ); + store[3] = (float) cos( (double) store[3] ); +#else + const unsigned X = TEMP_R0 * 16; + store[X + 0] = cosf( store[X + 0] ); + store[X + 1] = cosf( store[X + 1] ); + store[X + 2] = cosf( store[X + 2] ); + store[X + 3] = cosf( store[X + 3] ); +#endif +} + +static void +emit_cos( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + cos4f ); +} + +static void XSTDCALL +ex24f( + float *store ) +{ +#ifdef WIN32 + store[0] = (float) pow( 2.0, (double) store[0] ); + store[1] = (float) pow( 2.0, (double) store[1] ); + store[2] = (float) pow( 2.0, (double) store[2] ); + store[3] = (float) pow( 2.0, (double) store[3] ); +#else + const unsigned X = TEMP_R0 * 16; + store[X + 0] = powf( 2.0f, store[X + 0] ); + store[X + 1] = powf( 2.0f, store[X + 1] ); + store[X + 2] = powf( 2.0f, store[X + 2] ); + store[X + 3] = powf( 2.0f, store[X + 3] ); +#endif +} + +static void +emit_ex2( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + ex24f ); +} + +static void +emit_f2it( + struct x86_function *func, + unsigned xmm ) +{ + emit_cvttps2dq( + func, + make_xmm( xmm ), + make_xmm( xmm ) ); +} + +static void XSTDCALL +flr4f( + float *store ) +{ +#ifdef WIN32 + const unsigned X = 0; +#else + const unsigned X = TEMP_R0 * 16; +#endif + store[X + 0] = (float) floor( (double) store[X + 0] ); + store[X + 1] = (float) floor( (double) store[X + 1] ); + store[X + 2] = (float) floor( (double) store[X + 2] ); + store[X + 3] = (float) floor( (double) store[X + 3] ); +} + +static void +emit_flr( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + flr4f ); +} + +static void XSTDCALL +frc4f( + float *store ) +{ +#ifdef WIN32 + const unsigned X = 0; +#else + const unsigned X = TEMP_R0 * 16; +#endif + store[X + 0] -= (float) floor( (double) store[X + 0] ); + store[X + 1] -= (float) floor( (double) store[X + 1] ); + store[X + 2] -= (float) floor( (double) store[X + 2] ); + store[X + 3] -= (float) floor( (double) store[X + 3] ); +} + +static void +emit_frc( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + frc4f ); +} + +static void XSTDCALL +lg24f( + float *store ) +{ +#ifdef WIN32 + const unsigned X = 0; +#else + const unsigned X = TEMP_R0 * 16; +#endif + store[X + 0] = LOG2( store[X + 0] ); + store[X + 1] = LOG2( store[X + 1] ); + store[X + 2] = LOG2( store[X + 2] ); + store[X + 3] = LOG2( store[X + 3] ); +} + +static void +emit_lg2( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + lg24f ); +} + +static void +emit_MOV( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_movups( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void +emit_mul (struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src) +{ + emit_mulps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void +emit_neg( + struct x86_function *func, + unsigned xmm ) +{ + emit_xorps( + func, + make_xmm( xmm ), + get_temp( + TGSI_EXEC_TEMP_80000000_I, + TGSI_EXEC_TEMP_80000000_C ) ); +} + +static void XSTDCALL +pow4f( + float *store ) +{ +#ifdef WIN32 + store[0] = (float) pow( (double) store[0], (double) store[4] ); + store[1] = (float) pow( (double) store[1], (double) store[5] ); + store[2] = (float) pow( (double) store[2], (double) store[6] ); + store[3] = (float) pow( (double) store[3], (double) store[7] ); +#else + const unsigned X = TEMP_R0 * 16; + store[X + 0] = powf( store[X + 0], store[X + 4] ); + store[X + 1] = powf( store[X + 1], store[X + 5] ); + store[X + 2] = powf( store[X + 2], store[X + 6] ); + store[X + 3] = powf( store[X + 3], store[X + 7] ); +#endif +} + +static void +emit_pow( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_func_call_dst_src( + func, + xmm_dst, + xmm_src, + pow4f ); +} + +static void +emit_rcp ( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_rcpps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void +emit_rsqrt( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_rsqrtps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void +emit_setsign( + struct x86_function *func, + unsigned xmm ) +{ + emit_orps( + func, + make_xmm( xmm ), + get_temp( + TGSI_EXEC_TEMP_80000000_I, + TGSI_EXEC_TEMP_80000000_C ) ); +} + +static void XSTDCALL +sin4f( + float *store ) +{ +#ifdef WIN32 + store[0] = (float) sin( (double) store[0] ); + store[1] = (float) sin( (double) store[1] ); + store[2] = (float) sin( (double) store[2] ); + store[3] = (float) sin( (double) store[3] ); +#else + const unsigned X = TEMP_R0 * 16; + store[X + 0] = sinf( store[X + 0] ); + store[X + 1] = sinf( store[X + 1] ); + store[X + 2] = sinf( store[X + 2] ); + store[X + 3] = sinf( store[X + 3] ); +#endif +} + +static void +emit_sin (struct x86_function *func, + unsigned xmm_dst) +{ + emit_func_call_dst( + func, + xmm_dst, + sin4f ); +} + +static void +emit_sub( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_subps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +/** + * Register fetch. + */ + +static void +emit_fetch( + struct x86_function *func, + unsigned xmm, + const struct tgsi_full_src_register *reg, + const unsigned chan_index ) +{ + unsigned swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); + + switch( swizzle ) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + switch( reg->SrcRegister.File ) { + case TGSI_FILE_CONSTANT: + emit_const( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + + case TGSI_FILE_INPUT: + emit_inputf( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + + case TGSI_FILE_TEMPORARY: + emit_tempf( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + + default: + assert( 0 ); + } + break; + + case TGSI_EXTSWIZZLE_ZERO: + emit_tempf( + func, + xmm, + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ); + break; + + case TGSI_EXTSWIZZLE_ONE: + emit_tempf( + func, + xmm, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); + break; + + default: + assert( 0 ); + } + + switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) { + case TGSI_UTIL_SIGN_CLEAR: + emit_abs( func, xmm ); + break; + + case TGSI_UTIL_SIGN_SET: + emit_setsign( func, xmm ); + break; + + case TGSI_UTIL_SIGN_TOGGLE: + emit_neg( func, xmm ); + break; + + case TGSI_UTIL_SIGN_KEEP: + break; + } +} + +#define FETCH( FUNC, INST, XMM, INDEX, CHAN )\ + emit_fetch( FUNC, XMM, &(INST).FullSrcRegisters[INDEX], CHAN ) + +/** + * Register store. + */ + +static void +emit_store( + struct x86_function *func, + unsigned xmm, + const struct tgsi_full_dst_register *reg, + const struct tgsi_full_instruction *inst, + unsigned chan_index ) +{ + switch( reg->DstRegister.File ) { + case TGSI_FILE_OUTPUT: + emit_output( + func, + xmm, + reg->DstRegister.Index, + chan_index ); + break; + + case TGSI_FILE_TEMPORARY: + emit_temps( + func, + xmm, + reg->DstRegister.Index, + chan_index ); + break; + + case TGSI_FILE_ADDRESS: + emit_addrs( + func, + xmm, + reg->DstRegister.Index, + chan_index ); + break; + + default: + assert( 0 ); + } + + switch( inst->Instruction.Saturate ) { + case TGSI_SAT_NONE: + break; + + case TGSI_SAT_ZERO_ONE: +// assert( 0 ); + break; + + case TGSI_SAT_MINUS_PLUS_ONE: + assert( 0 ); + break; + } +} + +#define STORE( FUNC, INST, XMM, INDEX, CHAN )\ + emit_store( FUNC, XMM, &(INST).FullDstRegisters[INDEX], &(INST), CHAN ) + +/** + * High-level instruction translators. + */ + +static void +emit_kil( + struct x86_function *func, + const struct tgsi_full_src_register *reg ) +{ + unsigned uniquemask; + unsigned registers[4]; + unsigned nextregister = 0; + unsigned firstchan = ~0; + unsigned chan_index; + + /* This mask stores component bits that were already tested. Note that + * we test if the value is less than zero, so 1.0 and 0.0 need not to be + * tested. */ + uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); + + FOR_EACH_CHANNEL( chan_index ) { + unsigned swizzle; + + /* unswizzle channel */ + swizzle = tgsi_util_get_full_src_register_extswizzle( + reg, + chan_index ); + + /* check if the component has not been already tested */ + if( !(uniquemask & (1 << swizzle)) ) { + uniquemask |= 1 << swizzle; + + /* allocate register */ + registers[chan_index] = nextregister; + emit_fetch( + func, + nextregister, + reg, + chan_index ); + nextregister++; + + /* mark the first channel used */ + if( firstchan == ~0 ) { + firstchan = chan_index; + } + } + } + + emit_push( + func, + x86_make_reg( file_REG32, reg_AX ) ); + emit_push( + func, + x86_make_reg( file_REG32, reg_DX ) ); + + FOR_EACH_CHANNEL( chan_index ) { + if( uniquemask & (1 << chan_index) ) { + emit_cmpps( + func, + make_xmm( registers[chan_index] ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ), + cc_LessThan ); + + if( chan_index == firstchan ) { + emit_pmovmskb( + func, + x86_make_reg( file_REG32, reg_AX ), + make_xmm( registers[chan_index] ) ); + } + else { + emit_pmovmskb( + func, + x86_make_reg( file_REG32, reg_DX ), + make_xmm( registers[chan_index] ) ); + emit_or( + func, + x86_make_reg( file_REG32, reg_AX ), + x86_make_reg( file_REG32, reg_DX ) ); + } + } + } + + emit_or( + func, + get_temp( + TGSI_EXEC_TEMP_KILMASK_I, + TGSI_EXEC_TEMP_KILMASK_C ), + x86_make_reg( file_REG32, reg_AX ) ); + + emit_pop( + func, + x86_make_reg( file_REG32, reg_DX ) ); + emit_pop( + func, + x86_make_reg( file_REG32, reg_AX ) ); +} + +static void +emit_setcc( + struct x86_function *func, + struct tgsi_full_instruction *inst, + enum sse_cc cc ) +{ + unsigned chan_index; + + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_cmpps( + func, + make_xmm( 0 ), + make_xmm( 1 ), + cc ); + emit_andps( + func, + make_xmm( 0 ), + get_temp( + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ) ); + STORE( func, *inst, 0, 0, chan_index ); + } +} + +static void +emit_cmp( + struct x86_function *func, + struct tgsi_full_instruction *inst ) +{ + unsigned chan_index; + + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + FETCH( func, *inst, 2, 2, chan_index ); + emit_cmpps( + func, + make_xmm( 0 ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ), + cc_LessThan ); + emit_andps( + func, + make_xmm( 1 ), + make_xmm( 0 ) ); + emit_andnps( + func, + make_xmm( 0 ), + make_xmm( 2 ) ); + emit_orps( + func, + make_xmm( 0 ), + make_xmm( 1 ) ); + STORE( func, *inst, 0, 0, chan_index ); + } +} + +static int +emit_instruction( + struct x86_function *func, + struct tgsi_full_instruction *inst ) +{ + unsigned chan_index; + + switch( inst->Instruction.Opcode ) { + case TGSI_OPCODE_ARL: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_f2it( func, 0 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOV: + /* TGSI_OPCODE_SWZ */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_LIT: + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) { + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C); + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ) { + STORE( func, *inst, 0, 0, CHAN_X ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) { + STORE( func, *inst, 0, 0, CHAN_W ); + } + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_maxps( + func, + make_xmm( 0 ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ) ); + STORE( func, *inst, 0, 0, CHAN_Y ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + FETCH( func, *inst, 1, 0, CHAN_Y ); + emit_maxps( + func, + make_xmm( 1 ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ) ); + FETCH( func, *inst, 2, 0, CHAN_W ); + emit_minps( + func, + make_xmm( 2 ), + get_temp( + TGSI_EXEC_TEMP_128_I, + TGSI_EXEC_TEMP_128_C ) ); + emit_maxps( + func, + make_xmm( 2 ), + get_temp( + TGSI_EXEC_TEMP_MINUS_128_I, + TGSI_EXEC_TEMP_MINUS_128_C ) ); + emit_pow( func, 1, 2 ); + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_xorps( + func, + make_xmm( 2 ), + make_xmm( 2 ) ); + emit_cmpps( + func, + make_xmm( 2 ), + make_xmm( 0 ), + cc_LessThanEqual ); + emit_andps( + func, + make_xmm( 2 ), + make_xmm( 1 ) ); + STORE( func, *inst, 2, 0, CHAN_Z ); + } + } + break; + + case TGSI_OPCODE_RCP: + /* TGSI_OPCODE_RECIP */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_rcp( func, 0, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_RSQ: + /* TGSI_OPCODE_RECIPSQRT */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_rsqrt( func, 0, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXP: + return 0; + break; + + case TGSI_OPCODE_LOG: + return 0; + break; + + case TGSI_OPCODE_MUL: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_mul( func, 0, 1 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_ADD: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_add( func, 0, 1 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP3: + /* TGSI_OPCODE_DOT3 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_mul( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Y ); + FETCH( func, *inst, 2, 1, CHAN_Y ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Z ); + FETCH( func, *inst, 2, 1, CHAN_Z ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP4: + /* TGSI_OPCODE_DOT4 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_mul( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Y ); + FETCH( func, *inst, 2, 1, CHAN_Y ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Z ); + FETCH( func, *inst, 2, 1, CHAN_Z ); + emit_mul(func, 1, 2 ); + emit_add(func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_W ); + FETCH( func, *inst, 2, 1, CHAN_W ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DST: + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); + STORE( func, *inst, 0, 0, CHAN_X ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { + FETCH( func, *inst, 0, 0, CHAN_Y ); + FETCH( func, *inst, 1, 1, CHAN_Y ); + emit_mul( func, 0, 1 ); + STORE( func, *inst, 0, 0, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { + FETCH( func, *inst, 0, 0, CHAN_Z ); + STORE( func, *inst, 0, 0, CHAN_Z ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { + FETCH( func, *inst, 0, 1, CHAN_W ); + STORE( func, *inst, 0, 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MIN: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_minps( + func, + make_xmm( 0 ), + make_xmm( 1 ) ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_MAX: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_maxps( + func, + make_xmm( 0 ), + make_xmm( 1 ) ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLT: + /* TGSI_OPCODE_SETLT */ + emit_setcc( func, inst, cc_LessThan ); + break; + + case TGSI_OPCODE_SGE: + /* TGSI_OPCODE_SETGE */ + emit_setcc( func, inst, cc_NotLessThan ); + break; + + case TGSI_OPCODE_MAD: + /* TGSI_OPCODE_MADD */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + FETCH( func, *inst, 2, 2, chan_index ); + emit_mul( func, 0, 1 ); + emit_add( func, 0, 2 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_SUB: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_sub( func, 0, 1 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_LERP: + /* TGSI_OPCODE_LRP */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + FETCH( func, *inst, 2, 2, chan_index ); + emit_sub( func, 1, 2 ); + emit_mul( func, 0, 1 ); + emit_add( func, 0, 2 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_CND: + return 0; + break; + + case TGSI_OPCODE_CND0: + return 0; + break; + + case TGSI_OPCODE_DOT2ADD: + /* TGSI_OPCODE_DP2A */ + return 0; + break; + + case TGSI_OPCODE_INDEX: + return 0; + break; + + case TGSI_OPCODE_NEGATE: + return 0; + break; + + case TGSI_OPCODE_FRAC: + /* TGSI_OPCODE_FRC */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_frc( func, 0 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_CLAMP: + return 0; + break; + + case TGSI_OPCODE_FLOOR: + /* TGSI_OPCODE_FLR */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_flr( func, 0 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_ROUND: + return 0; + break; + + case TGSI_OPCODE_EXPBASE2: + /* TGSI_OPCODE_EX2 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_ex2( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_LOGBASE2: + /* TGSI_OPCODE_LG2 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_lg2( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_POWER: + /* TGSI_OPCODE_POW */ + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_pow( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_CROSSPRODUCT: + /* TGSI_OPCODE_XPD */ + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + FETCH( func, *inst, 1, 1, CHAN_Z ); + FETCH( func, *inst, 3, 0, CHAN_Z ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + FETCH( func, *inst, 0, 0, CHAN_Y ); + FETCH( func, *inst, 4, 1, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { + emit_MOV( func, 2, 0 ); + emit_mul( func, 2, 1 ); + emit_MOV( func, 5, 3 ); + emit_mul( func, 5, 4 ); + emit_sub( func, 2, 5 ); + STORE( func, *inst, 2, 0, CHAN_X ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + FETCH( func, *inst, 2, 1, CHAN_X ); + FETCH( func, *inst, 5, 0, CHAN_X ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { + emit_mul( func, 3, 2 ); + emit_mul( func, 1, 5 ); + emit_sub( func, 3, 1 ); + STORE( func, *inst, 3, 0, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { + emit_mul( func, 5, 4 ); + emit_mul( func, 0, 2 ); + emit_sub( func, 5, 0 ); + STORE( func, *inst, 5, 0, CHAN_Z ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { + FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C ); + STORE( func, *inst, 0, 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MULTIPLYMATRIX: + return 0; + break; + + case TGSI_OPCODE_ABS: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_abs( func, 0) ; + + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_RCC: + return 0; + break; + + case TGSI_OPCODE_DPH: + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_mul( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Y ); + FETCH( func, *inst, 2, 1, CHAN_Y ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Z ); + FETCH( func, *inst, 2, 1, CHAN_Z ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 1, CHAN_W ); + emit_add( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_COS: + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_cos( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDX: + return 0; + break; + + case TGSI_OPCODE_DDY: + return 0; + break; + + case TGSI_OPCODE_KIL: + emit_kil( func, &inst->FullSrcRegisters[0] ); + break; + + case TGSI_OPCODE_PK2H: + return 0; + break; + + case TGSI_OPCODE_PK2US: + return 0; + break; + + case TGSI_OPCODE_PK4B: + return 0; + break; + + case TGSI_OPCODE_PK4UB: + return 0; + break; + + case TGSI_OPCODE_RFL: + return 0; + break; + + case TGSI_OPCODE_SEQ: + return 0; + break; + + case TGSI_OPCODE_SFL: + return 0; + break; + + case TGSI_OPCODE_SGT: + return 0; + break; + + case TGSI_OPCODE_SIN: + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_sin( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLE: + return 0; + break; + + case TGSI_OPCODE_SNE: + return 0; + break; + + case TGSI_OPCODE_STR: + return 0; + break; + + case TGSI_OPCODE_TEX: + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_TXD: + return 0; + break; + + case TGSI_OPCODE_UP2H: + return 0; + break; + + case TGSI_OPCODE_UP2US: + return 0; + break; + + case TGSI_OPCODE_UP4B: + return 0; + break; + + case TGSI_OPCODE_UP4UB: + return 0; + break; + + case TGSI_OPCODE_X2D: + return 0; + break; + + case TGSI_OPCODE_ARA: + return 0; + break; + + case TGSI_OPCODE_ARR: + return 0; + break; + + case TGSI_OPCODE_BRA: + return 0; + break; + + case TGSI_OPCODE_CAL: + return 0; + break; + + case TGSI_OPCODE_RET: + case TGSI_OPCODE_END: +#ifdef WIN32 + emit_retw( func, 16 ); +#else + emit_ret( func ); +#endif + break; + + case TGSI_OPCODE_SSG: + return 0; + break; + + case TGSI_OPCODE_CMP: + emit_cmp (func, inst); + break; + + case TGSI_OPCODE_SCS: + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_cos( func, 0 ); + STORE( func, *inst, 0, 0, CHAN_X ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { + FETCH( func, *inst, 0, 0, CHAN_Y ); + emit_sin( func, 0 ); + STORE( func, *inst, 0, 0, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { + FETCH( func, *inst, 0, TGSI_EXEC_TEMP_00000000_I, TGSI_EXEC_TEMP_00000000_C ); + STORE( func, *inst, 0, 0, CHAN_Z ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { + FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C ); + STORE( func, *inst, 0, 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_TXB: + return 0; + break; + + case TGSI_OPCODE_NRM: + return 0; + break; + + case TGSI_OPCODE_DIV: + return 0; + break; + + case TGSI_OPCODE_DP2: + return 0; + break; + + case TGSI_OPCODE_TXL: + return 0; + break; + + case TGSI_OPCODE_BRK: + return 0; + break; + + case TGSI_OPCODE_IF: + return 0; + break; + + case TGSI_OPCODE_LOOP: + return 0; + break; + + case TGSI_OPCODE_REP: + return 0; + break; + + case TGSI_OPCODE_ELSE: + return 0; + break; + + case TGSI_OPCODE_ENDIF: + return 0; + break; + + case TGSI_OPCODE_ENDLOOP: + return 0; + break; + + case TGSI_OPCODE_ENDREP: + return 0; + break; + + case TGSI_OPCODE_PUSHA: + return 0; + break; + + case TGSI_OPCODE_POPA: + return 0; + break; + + case TGSI_OPCODE_CEIL: + return 0; + break; + + case TGSI_OPCODE_I2F: + return 0; + break; + + case TGSI_OPCODE_NOT: + return 0; + break; + + case TGSI_OPCODE_TRUNC: + return 0; + break; + + case TGSI_OPCODE_SHL: + return 0; + break; + + case TGSI_OPCODE_SHR: + return 0; + break; + + case TGSI_OPCODE_AND: + return 0; + break; + + case TGSI_OPCODE_OR: + return 0; + break; + + case TGSI_OPCODE_MOD: + return 0; + break; + + case TGSI_OPCODE_XOR: + return 0; + break; + + case TGSI_OPCODE_SAD: + return 0; + break; + + case TGSI_OPCODE_TXF: + return 0; + break; + + case TGSI_OPCODE_TXQ: + return 0; + break; + + case TGSI_OPCODE_CONT: + return 0; + break; + + case TGSI_OPCODE_EMIT: + return 0; + break; + + case TGSI_OPCODE_ENDPRIM: + return 0; + break; + + default: + return 0; + } + + return 1; +} + +static void +emit_declaration( + struct x86_function *func, + struct tgsi_full_declaration *decl ) +{ + if( decl->Declaration.File == TGSI_FILE_INPUT ) { + unsigned first, last, mask; + unsigned i, j; + + assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); + + first = decl->u.DeclarationRange.First; + last = decl->u.DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + /* Do not touch WPOS.xy */ + if( first == 0 ) { + mask &= ~TGSI_WRITEMASK_XY; + if( mask == TGSI_WRITEMASK_NONE ) { + first++; + } + } + + for( i = first; i <= last; i++ ) { + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + switch( decl->Interpolation.Interpolate ) { + case TGSI_INTERPOLATE_CONSTANT: + emit_coef_a0( func, 0, i, j ); + emit_inputs( func, 0, i, j ); + break; + + case TGSI_INTERPOLATE_LINEAR: + emit_inputf( func, 0, 0, TGSI_SWIZZLE_X ); + emit_coef_dadx( func, 1, i, j ); + emit_inputf( func, 2, 0, TGSI_SWIZZLE_Y ); + emit_coef_dady( func, 3, i, j ); + emit_mul( func, 0, 1 ); /* x * dadx */ + emit_coef_a0( func, 4, i, j ); + emit_mul( func, 2, 3 ); /* y * dady */ + emit_add( func, 0, 4 ); /* x * dadx + a0 */ + emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */ + emit_inputs( func, 0, i, j ); + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + emit_inputf( func, 0, 0, TGSI_SWIZZLE_X ); + emit_coef_dadx( func, 1, i, j ); + emit_inputf( func, 2, 0, TGSI_SWIZZLE_Y ); + emit_coef_dady( func, 3, i, j ); + emit_mul( func, 0, 1 ); /* x * dadx */ + emit_inputf( func, 4, 0, TGSI_SWIZZLE_W ); + emit_coef_a0( func, 5, i, j ); + emit_rcp( func, 4, 4 ); /* 1.0 / w */ + emit_mul( func, 2, 3 ); /* y * dady */ + emit_add( func, 0, 5 ); /* x * dadx + a0 */ + emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */ + emit_mul( func, 0, 4 ); /* (x * dadx + y * dady + a0) / w */ + emit_inputs( func, 0, i, j ); + break; + + default: + assert( 0 ); + break; + } + } + } + } + } +} + +unsigned +tgsi_emit_sse2( + struct tgsi_token *tokens, + struct x86_function *func ) +{ + struct tgsi_parse_context parse; + unsigned ok = 1; + + DUMP_START(); + + func->csr = func->store; + + emit_mov( + func, + get_input_base(), + get_argument( 0 ) ); + emit_mov( + func, + get_output_base(), + get_argument( 1 ) ); + emit_mov( + func, + get_const_base(), + get_argument( 2 ) ); + emit_mov( + func, + get_temp_base(), + get_argument( 3 ) ); + + tgsi_parse_init( &parse, tokens ); + + while( !tgsi_parse_end_of_tokens( &parse ) && ok ) { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + ok = emit_instruction( + func, + &parse.FullToken.FullInstruction ); + + if (!ok) { + debug_printf("failed to translate tgsi opcode %d\n", + parse.FullToken.FullInstruction.Instruction.Opcode ); + } + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + /* XXX implement this */ + ok = 0; + debug_printf("failed to emit immediate value\n"); + break; + + default: + assert( 0 ); + ok = 0; + break; + } + } + + tgsi_parse_free( &parse ); + + DUMP_END(); + + return ok; +} + +/** + * Fragment shaders are responsible for interpolating shader inputs. Because on + * x86 we have only 4 GP registers, and here we have 5 shader arguments (input, + * output, const, temp and coef), the code is split into two phases -- + * DECLARATION and INSTRUCTION phase. + * GP register holding the output argument is aliased with the coeff argument, + * as outputs are not needed in the DECLARATION phase. + */ +unsigned +tgsi_emit_sse2_fs( + struct tgsi_token *tokens, + struct x86_function *func ) +{ + struct tgsi_parse_context parse; + boolean instruction_phase = FALSE; + + DUMP_START(); + + func->csr = func->store; + + /* DECLARATION phase, do not load output argument. */ + emit_mov( + func, + get_input_base(), + get_argument( 0 ) ); + emit_mov( + func, + get_const_base(), + get_argument( 2 ) ); + emit_mov( + func, + get_temp_base(), + get_argument( 3 ) ); + emit_mov( + func, + get_coef_base(), + get_argument( 4 ) ); + + tgsi_parse_init( &parse, tokens ); + + while( !tgsi_parse_end_of_tokens( &parse ) ) { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + emit_declaration( + func, + &parse.FullToken.FullDeclaration ); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + if( !instruction_phase ) { + /* INSTRUCTION phase, overwrite coeff with output. */ + instruction_phase = TRUE; + emit_mov( + func, + get_output_base(), + get_argument( 1 ) ); + } + emit_instruction( + func, + &parse.FullToken.FullInstruction ); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + /* XXX implement this */ + assert(0); + break; + + default: + assert( 0 ); + } + } + + tgsi_parse_free( &parse ); + + DUMP_END(); + + return 1; +} + +#endif /* i386 */ diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h new file mode 100755 index 0000000000..9bee371766 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h @@ -0,0 +1,26 @@ +#if !defined TGSI_SSE2_H +#define TGSI_SSE2_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +struct tgsi_token; +struct x86_function; + +unsigned +tgsi_emit_sse2( + struct tgsi_token *tokens, + struct x86_function *function ); + +unsigned +tgsi_emit_sse2_fs( + struct tgsi_token *tokens, + struct x86_function *function ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_SSE2_H + diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.c b/src/gallium/auxiliary/tgsi/util/tgsi_build.c new file mode 100644 index 0000000000..a00ff1c2a5 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.c @@ -0,0 +1,1371 @@ +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi_build.h" +#include "tgsi_parse.h" + +/* + * version + */ + +struct tgsi_version +tgsi_build_version( void ) +{ + struct tgsi_version version; + + version.MajorVersion = 1; + version.MinorVersion = 1; + version.Padding = 0; + + return version; +} + +/* + * header + */ + +struct tgsi_header +tgsi_build_header( void ) +{ + struct tgsi_header header; + + header.HeaderSize = 1; + header.BodySize = 0; + + return header; +} + +static void +header_headersize_grow( struct tgsi_header *header ) +{ + assert( header->HeaderSize < 0xFF ); + assert( header->BodySize == 0 ); + + header->HeaderSize++; +} + +static void +header_bodysize_grow( struct tgsi_header *header ) +{ + assert( header->BodySize < 0xFFFFFF ); + + header->BodySize++; +} + +struct tgsi_processor +tgsi_default_processor( void ) +{ + struct tgsi_processor processor; + + processor.Processor = TGSI_PROCESSOR_FRAGMENT; + processor.Padding = 0; + + return processor; +} + +struct tgsi_processor +tgsi_build_processor( + unsigned type, + struct tgsi_header *header ) +{ + struct tgsi_processor processor; + + processor = tgsi_default_processor(); + processor.Processor = type; + + header_headersize_grow( header ); + + return processor; +} + +/* + * declaration + */ + +struct tgsi_declaration +tgsi_default_declaration( void ) +{ + struct tgsi_declaration declaration; + + declaration.Type = TGSI_TOKEN_TYPE_DECLARATION; + declaration.Size = 1; + declaration.File = TGSI_FILE_NULL; + declaration.Declare = TGSI_DECLARE_RANGE; + declaration.UsageMask = TGSI_WRITEMASK_XYZW; + declaration.Interpolate = 0; + declaration.Semantic = 0; + declaration.Padding = 0; + declaration.Extended = 0; + + return declaration; +} + +struct tgsi_declaration +tgsi_build_declaration( + unsigned file, + unsigned declare, + unsigned usage_mask, + unsigned interpolate, + unsigned semantic, + struct tgsi_header *header ) +{ + struct tgsi_declaration declaration; + + assert( file <= TGSI_FILE_IMMEDIATE ); + assert( declare <= TGSI_DECLARE_MASK ); + + declaration = tgsi_default_declaration(); + declaration.File = file; + declaration.Declare = declare; + declaration.UsageMask = usage_mask; + declaration.Interpolate = interpolate; + declaration.Semantic = semantic; + + header_bodysize_grow( header ); + + return declaration; +} + +static void +declaration_grow( + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + assert( declaration->Size < 0xFF ); + + declaration->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_full_declaration +tgsi_default_full_declaration( void ) +{ + struct tgsi_full_declaration full_declaration; + + full_declaration.Declaration = tgsi_default_declaration(); + full_declaration.Interpolation = tgsi_default_declaration_interpolation(); + full_declaration.Semantic = tgsi_default_declaration_semantic(); + + return full_declaration; +} + +unsigned +tgsi_build_full_declaration( + const struct tgsi_full_declaration *full_decl, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ) +{ + unsigned size = 0; + struct tgsi_declaration *declaration; + + if( maxsize <= size ) + return 0; + declaration = (struct tgsi_declaration *) &tokens[size]; + size++; + + *declaration = tgsi_build_declaration( + full_decl->Declaration.File, + full_decl->Declaration.Declare, + full_decl->Declaration.UsageMask, + full_decl->Declaration.Interpolate, + full_decl->Declaration.Semantic, + header ); + + switch( full_decl->Declaration.Declare ) { + case TGSI_DECLARE_RANGE: + { + struct tgsi_declaration_range *dr; + + if( maxsize <= size ) + return 0; + dr = (struct tgsi_declaration_range *) &tokens[size]; + size++; + + *dr = tgsi_build_declaration_range( + full_decl->u.DeclarationRange.First, + full_decl->u.DeclarationRange.Last, + declaration, + header ); + break; + } + + case TGSI_DECLARE_MASK: + { + struct tgsi_declaration_mask *dm; + + if( maxsize <= size ) + return 0; + dm = (struct tgsi_declaration_mask *) &tokens[size]; + size++; + + *dm = tgsi_build_declaration_mask( + full_decl->u.DeclarationMask.Mask, + declaration, + header ); + break; + } + + default: + assert( 0 ); + } + + if( full_decl->Declaration.Interpolate ) { + struct tgsi_declaration_interpolation *di; + + if( maxsize <= size ) + return 0; + di = (struct tgsi_declaration_interpolation *) &tokens[size]; + size++; + + *di = tgsi_build_declaration_interpolation( + full_decl->Interpolation.Interpolate, + declaration, + header ); + } + + if( full_decl->Declaration.Semantic ) { + struct tgsi_declaration_semantic *ds; + + if( maxsize <= size ) + return 0; + ds = (struct tgsi_declaration_semantic *) &tokens[size]; + size++; + + *ds = tgsi_build_declaration_semantic( + full_decl->Semantic.SemanticName, + full_decl->Semantic.SemanticIndex, + declaration, + header ); + } + + return size; +} + +struct tgsi_declaration_range +tgsi_build_declaration_range( + unsigned first, + unsigned last, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_range declaration_range; + + assert( last >= first ); + assert( last <= 0xFFFF ); + + declaration_range.First = first; + declaration_range.Last = last; + + declaration_grow( declaration, header ); + + return declaration_range; +} + +struct tgsi_declaration_mask +tgsi_build_declaration_mask( + unsigned mask, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_mask declaration_mask; + + declaration_mask.Mask = mask; + + declaration_grow( declaration, header ); + + return declaration_mask; +} + +struct tgsi_declaration_interpolation +tgsi_default_declaration_interpolation( void ) +{ + struct tgsi_declaration_interpolation di; + + di.Interpolate = TGSI_INTERPOLATE_CONSTANT; + di.Padding = 0; + + return di; +} + +struct tgsi_declaration_interpolation +tgsi_build_declaration_interpolation( + unsigned interpolate, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_interpolation di; + + assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE ); + + di = tgsi_default_declaration_interpolation(); + di.Interpolate = interpolate; + + declaration_grow( declaration, header ); + + return di; +} + +struct tgsi_declaration_semantic +tgsi_default_declaration_semantic( void ) +{ + struct tgsi_declaration_semantic ds; + + ds.SemanticName = TGSI_SEMANTIC_POSITION; + ds.SemanticIndex = 0; + ds.Padding = 0; + + return ds; +} + +struct tgsi_declaration_semantic +tgsi_build_declaration_semantic( + unsigned semantic_name, + unsigned semantic_index, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_semantic ds; + + assert( semantic_name <= TGSI_SEMANTIC_COUNT ); + assert( semantic_index <= 0xFFFF ); + + ds = tgsi_default_declaration_semantic(); + ds.SemanticName = semantic_name; + ds.SemanticIndex = semantic_index; + + declaration_grow( declaration, header ); + + return ds; +} + +/* + * immediate + */ + +struct tgsi_immediate +tgsi_default_immediate( void ) +{ + struct tgsi_immediate immediate; + + immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE; + immediate.Size = 1; + immediate.DataType = TGSI_IMM_FLOAT32; + immediate.Padding = 0; + immediate.Extended = 0; + + return immediate; +} + +struct tgsi_immediate +tgsi_build_immediate( + struct tgsi_header *header ) +{ + struct tgsi_immediate immediate; + + immediate = tgsi_default_immediate(); + + header_bodysize_grow( header ); + + return immediate; +} + +struct tgsi_full_immediate +tgsi_default_full_immediate( void ) +{ + struct tgsi_full_immediate fullimm; + + fullimm.Immediate = tgsi_default_immediate(); + fullimm.u.Pointer = (void *) 0; + + return fullimm; +} + +static void +immediate_grow( + struct tgsi_immediate *immediate, + struct tgsi_header *header ) +{ + assert( immediate->Size < 0xFF ); + + immediate->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_immediate_float32 +tgsi_build_immediate_float32( + float value, + struct tgsi_immediate *immediate, + struct tgsi_header *header ) +{ + struct tgsi_immediate_float32 immediate_float32; + + immediate_float32.Float = value; + + immediate_grow( immediate, header ); + + return immediate_float32; +} + +unsigned +tgsi_build_full_immediate( + const struct tgsi_full_immediate *full_imm, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ) +{ + unsigned size = 0, i; + struct tgsi_immediate *immediate; + + if( maxsize <= size ) + return 0; + immediate = (struct tgsi_immediate *) &tokens[size]; + size++; + + *immediate = tgsi_build_immediate( header ); + + for( i = 0; i < full_imm->Immediate.Size - 1; i++ ) { + struct tgsi_immediate_float32 *if32; + + if( maxsize <= size ) + return 0; + if32 = (struct tgsi_immediate_float32 *) &tokens[size]; + size++; + + *if32 = tgsi_build_immediate_float32( + full_imm->u.ImmediateFloat32[i].Float, + immediate, + header ); + } + + return size; +} + +/* + * instruction + */ + +struct tgsi_instruction +tgsi_default_instruction( void ) +{ + struct tgsi_instruction instruction; + + instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; + instruction.Size = 1; + instruction.Opcode = TGSI_OPCODE_MOV; + instruction.Saturate = TGSI_SAT_NONE; + instruction.NumDstRegs = 1; + instruction.NumSrcRegs = 1; + instruction.Padding = 0; + instruction.Extended = 0; + + return instruction; +} + +struct tgsi_instruction +tgsi_build_instruction( + unsigned opcode, + unsigned saturate, + unsigned num_dst_regs, + unsigned num_src_regs, + struct tgsi_header *header ) +{ + struct tgsi_instruction instruction; + + assert (opcode <= TGSI_OPCODE_LAST); + assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE); + assert (num_dst_regs <= 3); + assert (num_src_regs <= 15); + + instruction = tgsi_default_instruction(); + instruction.Opcode = opcode; + instruction.Saturate = saturate; + instruction.NumDstRegs = num_dst_regs; + instruction.NumSrcRegs = num_src_regs; + + header_bodysize_grow( header ); + + return instruction; +} + +static void +instruction_grow( + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + assert (instruction->Size < 0xFF); + + instruction->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_full_instruction +tgsi_default_full_instruction( void ) +{ + struct tgsi_full_instruction full_instruction; + unsigned i; + + full_instruction.Instruction = tgsi_default_instruction(); + full_instruction.InstructionExtNv = tgsi_default_instruction_ext_nv(); + full_instruction.InstructionExtLabel = tgsi_default_instruction_ext_label(); + full_instruction.InstructionExtTexture = tgsi_default_instruction_ext_texture(); + for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) { + full_instruction.FullDstRegisters[i] = tgsi_default_full_dst_register(); + } + for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) { + full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register(); + } + + return full_instruction; +} + +unsigned +tgsi_build_full_instruction( + const struct tgsi_full_instruction *full_inst, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ) +{ + unsigned size = 0; + unsigned i; + struct tgsi_instruction *instruction; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + instruction = (struct tgsi_instruction *) &tokens[size]; + size++; + + *instruction = tgsi_build_instruction( + full_inst->Instruction.Opcode, + full_inst->Instruction.Saturate, + full_inst->Instruction.NumDstRegs, + full_inst->Instruction.NumSrcRegs, + header ); + prev_token = (struct tgsi_token *) instruction; + + if( tgsi_compare_instruction_ext_nv( + full_inst->InstructionExtNv, + tgsi_default_instruction_ext_nv() ) ) { + struct tgsi_instruction_ext_nv *instruction_ext_nv; + + if( maxsize <= size ) + return 0; + instruction_ext_nv = + (struct tgsi_instruction_ext_nv *) &tokens[size]; + size++; + + *instruction_ext_nv = tgsi_build_instruction_ext_nv( + full_inst->InstructionExtNv.Precision, + full_inst->InstructionExtNv.CondDstIndex, + full_inst->InstructionExtNv.CondFlowIndex, + full_inst->InstructionExtNv.CondMask, + full_inst->InstructionExtNv.CondSwizzleX, + full_inst->InstructionExtNv.CondSwizzleY, + full_inst->InstructionExtNv.CondSwizzleZ, + full_inst->InstructionExtNv.CondSwizzleW, + full_inst->InstructionExtNv.CondDstUpdate, + full_inst->InstructionExtNv.CondFlowEnable, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_nv; + } + + if( tgsi_compare_instruction_ext_label( + full_inst->InstructionExtLabel, + tgsi_default_instruction_ext_label() ) ) { + struct tgsi_instruction_ext_label *instruction_ext_label; + + if( maxsize <= size ) + return 0; + instruction_ext_label = + (struct tgsi_instruction_ext_label *) &tokens[size]; + size++; + + *instruction_ext_label = tgsi_build_instruction_ext_label( + full_inst->InstructionExtLabel.Label, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_label; + } + + if( tgsi_compare_instruction_ext_texture( + full_inst->InstructionExtTexture, + tgsi_default_instruction_ext_texture() ) ) { + struct tgsi_instruction_ext_texture *instruction_ext_texture; + + if( maxsize <= size ) + return 0; + instruction_ext_texture = + (struct tgsi_instruction_ext_texture *) &tokens[size]; + size++; + + *instruction_ext_texture = tgsi_build_instruction_ext_texture( + full_inst->InstructionExtTexture.Texture, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_texture; + } + + for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { + const struct tgsi_full_dst_register *reg = &full_inst->FullDstRegisters[i]; + struct tgsi_dst_register *dst_register; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + dst_register = (struct tgsi_dst_register *) &tokens[size]; + size++; + + *dst_register = tgsi_build_dst_register( + reg->DstRegister.File, + reg->DstRegister.WriteMask, + reg->DstRegister.Index, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register; + + if( tgsi_compare_dst_register_ext_concode( + reg->DstRegisterExtConcode, + tgsi_default_dst_register_ext_concode() ) ) { + struct tgsi_dst_register_ext_concode *dst_register_ext_concode; + + if( maxsize <= size ) + return 0; + dst_register_ext_concode = + (struct tgsi_dst_register_ext_concode *) &tokens[size]; + size++; + + *dst_register_ext_concode = tgsi_build_dst_register_ext_concode( + reg->DstRegisterExtConcode.CondMask, + reg->DstRegisterExtConcode.CondSwizzleX, + reg->DstRegisterExtConcode.CondSwizzleY, + reg->DstRegisterExtConcode.CondSwizzleZ, + reg->DstRegisterExtConcode.CondSwizzleW, + reg->DstRegisterExtConcode.CondSrcIndex, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register_ext_concode; + } + + if( tgsi_compare_dst_register_ext_modulate( + reg->DstRegisterExtModulate, + tgsi_default_dst_register_ext_modulate() ) ) { + struct tgsi_dst_register_ext_modulate *dst_register_ext_modulate; + + if( maxsize <= size ) + return 0; + dst_register_ext_modulate = + (struct tgsi_dst_register_ext_modulate *) &tokens[size]; + size++; + + *dst_register_ext_modulate = tgsi_build_dst_register_ext_modulate( + reg->DstRegisterExtModulate.Modulate, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register_ext_modulate; + } + } + + for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { + const struct tgsi_full_src_register *reg = &full_inst->FullSrcRegisters[i]; + struct tgsi_src_register *src_register; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + src_register = (struct tgsi_src_register *) &tokens[size]; + size++; + + *src_register = tgsi_build_src_register( + reg->SrcRegister.File, + reg->SrcRegister.SwizzleX, + reg->SrcRegister.SwizzleY, + reg->SrcRegister.SwizzleZ, + reg->SrcRegister.SwizzleW, + reg->SrcRegister.Negate, + reg->SrcRegister.Indirect, + reg->SrcRegister.Dimension, + reg->SrcRegister.Index, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register; + + if( tgsi_compare_src_register_ext_swz( + reg->SrcRegisterExtSwz, + tgsi_default_src_register_ext_swz() ) ) { + struct tgsi_src_register_ext_swz *src_register_ext_swz; + + if( maxsize <= size ) + return 0; + src_register_ext_swz = + (struct tgsi_src_register_ext_swz *) &tokens[size]; + size++; + + *src_register_ext_swz = tgsi_build_src_register_ext_swz( + reg->SrcRegisterExtSwz.ExtSwizzleX, + reg->SrcRegisterExtSwz.ExtSwizzleY, + reg->SrcRegisterExtSwz.ExtSwizzleZ, + reg->SrcRegisterExtSwz.ExtSwizzleW, + reg->SrcRegisterExtSwz.NegateX, + reg->SrcRegisterExtSwz.NegateY, + reg->SrcRegisterExtSwz.NegateZ, + reg->SrcRegisterExtSwz.NegateW, + reg->SrcRegisterExtSwz.ExtDivide, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register_ext_swz; + } + + if( tgsi_compare_src_register_ext_mod( + reg->SrcRegisterExtMod, + tgsi_default_src_register_ext_mod() ) ) { + struct tgsi_src_register_ext_mod *src_register_ext_mod; + + if( maxsize <= size ) + return 0; + src_register_ext_mod = + (struct tgsi_src_register_ext_mod *) &tokens[size]; + size++; + + *src_register_ext_mod = tgsi_build_src_register_ext_mod( + reg->SrcRegisterExtMod.Complement, + reg->SrcRegisterExtMod.Bias, + reg->SrcRegisterExtMod.Scale2X, + reg->SrcRegisterExtMod.Absolute, + reg->SrcRegisterExtMod.Negate, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register_ext_mod; + } + + if( reg->SrcRegister.Indirect ) { + struct tgsi_src_register *ind; + + if( maxsize <= size ) + return 0; + ind = (struct tgsi_src_register *) &tokens[size]; + size++; + + *ind = tgsi_build_src_register( + reg->SrcRegisterInd.File, + reg->SrcRegisterInd.SwizzleX, + reg->SrcRegisterInd.SwizzleY, + reg->SrcRegisterInd.SwizzleZ, + reg->SrcRegisterInd.SwizzleW, + reg->SrcRegisterInd.Negate, + reg->SrcRegisterInd.Indirect, + reg->SrcRegisterInd.Dimension, + reg->SrcRegisterInd.Index, + instruction, + header ); + } + + if( reg->SrcRegister.Dimension ) { + struct tgsi_dimension *dim; + + assert( !reg->SrcRegisterDim.Dimension ); + + if( maxsize <= size ) + return 0; + dim = (struct tgsi_dimension *) &tokens[size]; + size++; + + *dim = tgsi_build_dimension( + reg->SrcRegisterDim.Indirect, + reg->SrcRegisterDim.Index, + instruction, + header ); + + if( reg->SrcRegisterDim.Indirect ) { + struct tgsi_src_register *ind; + + if( maxsize <= size ) + return 0; + ind = (struct tgsi_src_register *) &tokens[size]; + size++; + + *ind = tgsi_build_src_register( + reg->SrcRegisterDimInd.File, + reg->SrcRegisterDimInd.SwizzleX, + reg->SrcRegisterDimInd.SwizzleY, + reg->SrcRegisterDimInd.SwizzleZ, + reg->SrcRegisterDimInd.SwizzleW, + reg->SrcRegisterDimInd.Negate, + reg->SrcRegisterDimInd.Indirect, + reg->SrcRegisterDimInd.Dimension, + reg->SrcRegisterDimInd.Index, + instruction, + header ); + } + } + } + + return size; +} + +struct tgsi_instruction_ext_nv +tgsi_default_instruction_ext_nv( void ) +{ + struct tgsi_instruction_ext_nv instruction_ext_nv; + + instruction_ext_nv.Type = TGSI_INSTRUCTION_EXT_TYPE_NV; + instruction_ext_nv.Precision = TGSI_PRECISION_DEFAULT; + instruction_ext_nv.CondDstIndex = 0; + instruction_ext_nv.CondFlowIndex = 0; + instruction_ext_nv.CondMask = TGSI_CC_TR; + instruction_ext_nv.CondSwizzleX = TGSI_SWIZZLE_X; + instruction_ext_nv.CondSwizzleY = TGSI_SWIZZLE_Y; + instruction_ext_nv.CondSwizzleZ = TGSI_SWIZZLE_Z; + instruction_ext_nv.CondSwizzleW = TGSI_SWIZZLE_W; + instruction_ext_nv.CondDstUpdate = 0; + instruction_ext_nv.CondFlowEnable = 0; + instruction_ext_nv.Padding = 0; + instruction_ext_nv.Extended = 0; + + return instruction_ext_nv; +} + +union token_u32 +{ + unsigned u32; +}; + +unsigned +tgsi_compare_instruction_ext_nv( + struct tgsi_instruction_ext_nv a, + struct tgsi_instruction_ext_nv b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_instruction_ext_nv +tgsi_build_instruction_ext_nv( + unsigned precision, + unsigned cond_dst_index, + unsigned cond_flow_index, + unsigned cond_mask, + unsigned cond_swizzle_x, + unsigned cond_swizzle_y, + unsigned cond_swizzle_z, + unsigned cond_swizzle_w, + unsigned cond_dst_update, + unsigned cond_flow_update, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_nv instruction_ext_nv; + + instruction_ext_nv = tgsi_default_instruction_ext_nv(); + instruction_ext_nv.Precision = precision; + instruction_ext_nv.CondDstIndex = cond_dst_index; + instruction_ext_nv.CondFlowIndex = cond_flow_index; + instruction_ext_nv.CondMask = cond_mask; + instruction_ext_nv.CondSwizzleX = cond_swizzle_x; + instruction_ext_nv.CondSwizzleY = cond_swizzle_y; + instruction_ext_nv.CondSwizzleZ = cond_swizzle_z; + instruction_ext_nv.CondSwizzleW = cond_swizzle_w; + instruction_ext_nv.CondDstUpdate = cond_dst_update; + instruction_ext_nv.CondFlowEnable = cond_flow_update; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_nv; +} + +struct tgsi_instruction_ext_label +tgsi_default_instruction_ext_label( void ) +{ + struct tgsi_instruction_ext_label instruction_ext_label; + + instruction_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL; + instruction_ext_label.Label = 0; + instruction_ext_label.Padding = 0; + instruction_ext_label.Extended = 0; + + return instruction_ext_label; +} + +unsigned +tgsi_compare_instruction_ext_label( + struct tgsi_instruction_ext_label a, + struct tgsi_instruction_ext_label b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_instruction_ext_label +tgsi_build_instruction_ext_label( + unsigned label, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_label instruction_ext_label; + + instruction_ext_label = tgsi_default_instruction_ext_label(); + instruction_ext_label.Label = label; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_label; +} + +struct tgsi_instruction_ext_texture +tgsi_default_instruction_ext_texture( void ) +{ + struct tgsi_instruction_ext_texture instruction_ext_texture; + + instruction_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE; + instruction_ext_texture.Texture = TGSI_TEXTURE_UNKNOWN; + instruction_ext_texture.Padding = 0; + instruction_ext_texture.Extended = 0; + + return instruction_ext_texture; +} + +unsigned +tgsi_compare_instruction_ext_texture( + struct tgsi_instruction_ext_texture a, + struct tgsi_instruction_ext_texture b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_instruction_ext_texture +tgsi_build_instruction_ext_texture( + unsigned texture, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_texture instruction_ext_texture; + + instruction_ext_texture = tgsi_default_instruction_ext_texture(); + instruction_ext_texture.Texture = texture; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_texture; +} + +struct tgsi_src_register +tgsi_default_src_register( void ) +{ + struct tgsi_src_register src_register; + + src_register.File = TGSI_FILE_NULL; + src_register.SwizzleX = TGSI_SWIZZLE_X; + src_register.SwizzleY = TGSI_SWIZZLE_Y; + src_register.SwizzleZ = TGSI_SWIZZLE_Z; + src_register.SwizzleW = TGSI_SWIZZLE_W; + src_register.Negate = 0; + src_register.Indirect = 0; + src_register.Dimension = 0; + src_register.Index = 0; + src_register.Extended = 0; + + return src_register; +} + +struct tgsi_src_register +tgsi_build_src_register( + unsigned file, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + unsigned negate, + unsigned indirect, + unsigned dimension, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register src_register; + + assert( file <= TGSI_FILE_IMMEDIATE ); + assert( swizzle_x <= TGSI_SWIZZLE_W ); + assert( swizzle_y <= TGSI_SWIZZLE_W ); + assert( swizzle_z <= TGSI_SWIZZLE_W ); + assert( swizzle_w <= TGSI_SWIZZLE_W ); + assert( negate <= 1 ); + assert( index >= -0x8000 && index <= 0x7FFF ); + + src_register = tgsi_default_src_register(); + src_register.File = file; + src_register.SwizzleX = swizzle_x; + src_register.SwizzleY = swizzle_y; + src_register.SwizzleZ = swizzle_z; + src_register.SwizzleW = swizzle_w; + src_register.Negate = negate; + src_register.Indirect = indirect; + src_register.Dimension = dimension; + src_register.Index = index; + + instruction_grow( instruction, header ); + + return src_register; +} + +struct tgsi_full_src_register +tgsi_default_full_src_register( void ) +{ + struct tgsi_full_src_register full_src_register; + + full_src_register.SrcRegister = tgsi_default_src_register(); + full_src_register.SrcRegisterExtSwz = tgsi_default_src_register_ext_swz(); + full_src_register.SrcRegisterExtMod = tgsi_default_src_register_ext_mod(); + full_src_register.SrcRegisterInd = tgsi_default_src_register(); + full_src_register.SrcRegisterDim = tgsi_default_dimension(); + full_src_register.SrcRegisterDimInd = tgsi_default_src_register(); + + return full_src_register; +} + +struct tgsi_src_register_ext_swz +tgsi_default_src_register_ext_swz( void ) +{ + struct tgsi_src_register_ext_swz src_register_ext_swz; + + src_register_ext_swz.Type = TGSI_SRC_REGISTER_EXT_TYPE_SWZ; + src_register_ext_swz.ExtSwizzleX = TGSI_EXTSWIZZLE_X; + src_register_ext_swz.ExtSwizzleY = TGSI_EXTSWIZZLE_Y; + src_register_ext_swz.ExtSwizzleZ = TGSI_EXTSWIZZLE_Z; + src_register_ext_swz.ExtSwizzleW = TGSI_EXTSWIZZLE_W; + src_register_ext_swz.NegateX = 0; + src_register_ext_swz.NegateY = 0; + src_register_ext_swz.NegateZ = 0; + src_register_ext_swz.NegateW = 0; + src_register_ext_swz.ExtDivide = TGSI_EXTSWIZZLE_ONE; + src_register_ext_swz.Padding = 0; + src_register_ext_swz.Extended = 0; + + return src_register_ext_swz; +} + +unsigned +tgsi_compare_src_register_ext_swz( + struct tgsi_src_register_ext_swz a, + struct tgsi_src_register_ext_swz b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_src_register_ext_swz +tgsi_build_src_register_ext_swz( + unsigned ext_swizzle_x, + unsigned ext_swizzle_y, + unsigned ext_swizzle_z, + unsigned ext_swizzle_w, + unsigned negate_x, + unsigned negate_y, + unsigned negate_z, + unsigned negate_w, + unsigned ext_divide, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register_ext_swz src_register_ext_swz; + + assert( ext_swizzle_x <= TGSI_EXTSWIZZLE_ONE ); + assert( ext_swizzle_y <= TGSI_EXTSWIZZLE_ONE ); + assert( ext_swizzle_z <= TGSI_EXTSWIZZLE_ONE ); + assert( ext_swizzle_w <= TGSI_EXTSWIZZLE_ONE ); + assert( negate_x <= 1 ); + assert( negate_y <= 1 ); + assert( negate_z <= 1 ); + assert( negate_w <= 1 ); + assert( ext_divide <= TGSI_EXTSWIZZLE_ONE ); + + src_register_ext_swz = tgsi_default_src_register_ext_swz(); + src_register_ext_swz.ExtSwizzleX = ext_swizzle_x; + src_register_ext_swz.ExtSwizzleY = ext_swizzle_y; + src_register_ext_swz.ExtSwizzleZ = ext_swizzle_z; + src_register_ext_swz.ExtSwizzleW = ext_swizzle_w; + src_register_ext_swz.NegateX = negate_x; + src_register_ext_swz.NegateY = negate_y; + src_register_ext_swz.NegateZ = negate_z; + src_register_ext_swz.NegateW = negate_w; + src_register_ext_swz.ExtDivide = ext_divide; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return src_register_ext_swz; +} + +struct tgsi_src_register_ext_mod +tgsi_default_src_register_ext_mod( void ) +{ + struct tgsi_src_register_ext_mod src_register_ext_mod; + + src_register_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD; + src_register_ext_mod.Complement = 0; + src_register_ext_mod.Bias = 0; + src_register_ext_mod.Scale2X = 0; + src_register_ext_mod.Absolute = 0; + src_register_ext_mod.Negate = 0; + src_register_ext_mod.Padding = 0; + src_register_ext_mod.Extended = 0; + + return src_register_ext_mod; +} + +unsigned +tgsi_compare_src_register_ext_mod( + struct tgsi_src_register_ext_mod a, + struct tgsi_src_register_ext_mod b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_src_register_ext_mod +tgsi_build_src_register_ext_mod( + unsigned complement, + unsigned bias, + unsigned scale_2x, + unsigned absolute, + unsigned negate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register_ext_mod src_register_ext_mod; + + assert( complement <= 1 ); + assert( bias <= 1 ); + assert( scale_2x <= 1 ); + assert( absolute <= 1 ); + assert( negate <= 1 ); + + src_register_ext_mod = tgsi_default_src_register_ext_mod(); + src_register_ext_mod.Complement = complement; + src_register_ext_mod.Bias = bias; + src_register_ext_mod.Scale2X = scale_2x; + src_register_ext_mod.Absolute = absolute; + src_register_ext_mod.Negate = negate; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return src_register_ext_mod; +} + +struct tgsi_dimension +tgsi_default_dimension( void ) +{ + struct tgsi_dimension dimension; + + dimension.Indirect = 0; + dimension.Dimension = 0; + dimension.Padding = 0; + dimension.Index = 0; + dimension.Extended = 0; + + return dimension; +} + +struct tgsi_dimension +tgsi_build_dimension( + unsigned indirect, + unsigned index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dimension dimension; + + dimension = tgsi_default_dimension(); + dimension.Indirect = indirect; + dimension.Index = index; + + instruction_grow( instruction, header ); + + return dimension; +} + +struct tgsi_dst_register +tgsi_default_dst_register( void ) +{ + struct tgsi_dst_register dst_register; + + dst_register.File = TGSI_FILE_NULL; + dst_register.WriteMask = TGSI_WRITEMASK_XYZW; + dst_register.Indirect = 0; + dst_register.Dimension = 0; + dst_register.Index = 0; + dst_register.Padding = 0; + dst_register.Extended = 0; + + return dst_register; +} + +struct tgsi_dst_register +tgsi_build_dst_register( + unsigned file, + unsigned mask, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register dst_register; + + assert( file <= TGSI_FILE_IMMEDIATE ); + assert( mask <= TGSI_WRITEMASK_XYZW ); + assert( index >= -32768 && index <= 32767 ); + + dst_register = tgsi_default_dst_register(); + dst_register.File = file; + dst_register.WriteMask = mask; + dst_register.Index = index; + + instruction_grow( instruction, header ); + + return dst_register; +} + +struct tgsi_full_dst_register +tgsi_default_full_dst_register( void ) +{ + struct tgsi_full_dst_register full_dst_register; + + full_dst_register.DstRegister = tgsi_default_dst_register(); + full_dst_register.DstRegisterExtConcode = + tgsi_default_dst_register_ext_concode(); + full_dst_register.DstRegisterExtModulate = + tgsi_default_dst_register_ext_modulate(); + + return full_dst_register; +} + +struct tgsi_dst_register_ext_concode +tgsi_default_dst_register_ext_concode( void ) +{ + struct tgsi_dst_register_ext_concode dst_register_ext_concode; + + dst_register_ext_concode.Type = TGSI_DST_REGISTER_EXT_TYPE_CONDCODE; + dst_register_ext_concode.CondMask = TGSI_CC_TR; + dst_register_ext_concode.CondSwizzleX = TGSI_SWIZZLE_X; + dst_register_ext_concode.CondSwizzleY = TGSI_SWIZZLE_Y; + dst_register_ext_concode.CondSwizzleZ = TGSI_SWIZZLE_Z; + dst_register_ext_concode.CondSwizzleW = TGSI_SWIZZLE_W; + dst_register_ext_concode.CondSrcIndex = 0; + dst_register_ext_concode.Padding = 0; + dst_register_ext_concode.Extended = 0; + + return dst_register_ext_concode; +} + +unsigned +tgsi_compare_dst_register_ext_concode( + struct tgsi_dst_register_ext_concode a, + struct tgsi_dst_register_ext_concode b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_dst_register_ext_concode +tgsi_build_dst_register_ext_concode( + unsigned cc, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + int index, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register_ext_concode dst_register_ext_concode; + + assert( cc <= TGSI_CC_FL ); + assert( swizzle_x <= TGSI_SWIZZLE_W ); + assert( swizzle_y <= TGSI_SWIZZLE_W ); + assert( swizzle_z <= TGSI_SWIZZLE_W ); + assert( swizzle_w <= TGSI_SWIZZLE_W ); + assert( index >= -32768 && index <= 32767 ); + + dst_register_ext_concode = tgsi_default_dst_register_ext_concode(); + dst_register_ext_concode.CondMask = cc; + dst_register_ext_concode.CondSwizzleX = swizzle_x; + dst_register_ext_concode.CondSwizzleY = swizzle_y; + dst_register_ext_concode.CondSwizzleZ = swizzle_z; + dst_register_ext_concode.CondSwizzleW = swizzle_w; + dst_register_ext_concode.CondSrcIndex = index; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return dst_register_ext_concode; +} + +struct tgsi_dst_register_ext_modulate +tgsi_default_dst_register_ext_modulate( void ) +{ + struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; + + dst_register_ext_modulate.Type = TGSI_DST_REGISTER_EXT_TYPE_MODULATE; + dst_register_ext_modulate.Modulate = TGSI_MODULATE_1X; + dst_register_ext_modulate.Padding = 0; + dst_register_ext_modulate.Extended = 0; + + return dst_register_ext_modulate; +} + +unsigned +tgsi_compare_dst_register_ext_modulate( + struct tgsi_dst_register_ext_modulate a, + struct tgsi_dst_register_ext_modulate b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_dst_register_ext_modulate +tgsi_build_dst_register_ext_modulate( + unsigned modulate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; + + assert( modulate <= TGSI_MODULATE_EIGHTH ); + + dst_register_ext_modulate = tgsi_default_dst_register_ext_modulate(); + dst_register_ext_modulate.Modulate = modulate; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return dst_register_ext_modulate; +} + diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.h b/src/gallium/auxiliary/tgsi/util/tgsi_build.h new file mode 100644 index 0000000000..116c78abf3 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.h @@ -0,0 +1,320 @@ +#if !defined TGSI_BUILD_H +#define TGSI_BUILD_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +/* + * version + */ + +struct tgsi_version +tgsi_build_version( void ); + +/* + * header + */ + +struct tgsi_header +tgsi_build_header( void ); + +struct tgsi_processor +tgsi_default_processor( void ); + +struct tgsi_processor +tgsi_build_processor( + unsigned processor, + struct tgsi_header *header ); + +/* + * declaration + */ + +struct tgsi_declaration +tgsi_default_declaration( void ); + +struct tgsi_declaration +tgsi_build_declaration( + unsigned file, + unsigned declare, + unsigned usage_mask, + unsigned interpolate, + unsigned semantic, + struct tgsi_header *header ); + +struct tgsi_full_declaration +tgsi_default_full_declaration( void ); + +unsigned +tgsi_build_full_declaration( + const struct tgsi_full_declaration *full_decl, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ); + +struct tgsi_declaration_range +tgsi_build_declaration_range( + unsigned first, + unsigned last, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +struct tgsi_declaration_mask +tgsi_build_declaration_mask( + unsigned mask, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +struct tgsi_declaration_interpolation +tgsi_default_declaration_interpolation( void ); + +struct tgsi_declaration_interpolation +tgsi_build_declaration_interpolation( + unsigned interpolate, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +struct tgsi_declaration_semantic +tgsi_default_declaration_semantic( void ); + +struct tgsi_declaration_semantic +tgsi_build_declaration_semantic( + unsigned semantic_name, + unsigned semantic_index, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +/* + * immediate + */ + +struct tgsi_immediate +tgsi_default_immediate( void ); + +struct tgsi_immediate +tgsi_build_immediate( + struct tgsi_header *header ); + +struct tgsi_full_immediate +tgsi_default_full_immediate( void ); + +struct tgsi_immediate_float32 +tgsi_build_immediate_float32( + float value, + struct tgsi_immediate *immediate, + struct tgsi_header *header ); + +unsigned +tgsi_build_full_immediate( + const struct tgsi_full_immediate *full_imm, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ); + +/* + * instruction + */ + +struct tgsi_instruction +tgsi_default_instruction( void ); + +struct tgsi_instruction +tgsi_build_instruction( + unsigned opcode, + unsigned saturate, + unsigned num_dst_regs, + unsigned num_src_regs, + struct tgsi_header *header ); + +struct tgsi_full_instruction +tgsi_default_full_instruction( void ); + +unsigned +tgsi_build_full_instruction( + const struct tgsi_full_instruction *full_inst, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ); + +struct tgsi_instruction_ext_nv +tgsi_default_instruction_ext_nv( void ); + +unsigned +tgsi_compare_instruction_ext_nv( + struct tgsi_instruction_ext_nv a, + struct tgsi_instruction_ext_nv b ); + +struct tgsi_instruction_ext_nv +tgsi_build_instruction_ext_nv( + unsigned precision, + unsigned cond_dst_index, + unsigned cond_flow_index, + unsigned cond_mask, + unsigned cond_swizzle_x, + unsigned cond_swizzle_y, + unsigned cond_swizzle_z, + unsigned cond_swizzle_w, + unsigned cond_dst_update, + unsigned cond_flow_update, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_instruction_ext_label +tgsi_default_instruction_ext_label( void ); + +unsigned +tgsi_compare_instruction_ext_label( + struct tgsi_instruction_ext_label a, + struct tgsi_instruction_ext_label b ); + +struct tgsi_instruction_ext_label +tgsi_build_instruction_ext_label( + unsigned label, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_instruction_ext_texture +tgsi_default_instruction_ext_texture( void ); + +unsigned +tgsi_compare_instruction_ext_texture( + struct tgsi_instruction_ext_texture a, + struct tgsi_instruction_ext_texture b ); + +struct tgsi_instruction_ext_texture +tgsi_build_instruction_ext_texture( + unsigned texture, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_src_register +tgsi_default_src_register( void ); + +struct tgsi_src_register +tgsi_build_src_register( + unsigned file, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + unsigned negate, + unsigned indirect, + unsigned dimension, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_full_src_register +tgsi_default_full_src_register( void ); + +struct tgsi_src_register_ext_swz +tgsi_default_src_register_ext_swz( void ); + +unsigned +tgsi_compare_src_register_ext_swz( + struct tgsi_src_register_ext_swz a, + struct tgsi_src_register_ext_swz b ); + +struct tgsi_src_register_ext_swz +tgsi_build_src_register_ext_swz( + unsigned ext_swizzle_x, + unsigned ext_swizzle_y, + unsigned ext_swizzle_z, + unsigned ext_swizzle_w, + unsigned negate_x, + unsigned negate_y, + unsigned negate_z, + unsigned negate_w, + unsigned ext_divide, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_src_register_ext_mod +tgsi_default_src_register_ext_mod( void ); + +unsigned +tgsi_compare_src_register_ext_mod( + struct tgsi_src_register_ext_mod a, + struct tgsi_src_register_ext_mod b ); + +struct tgsi_src_register_ext_mod +tgsi_build_src_register_ext_mod( + unsigned complement, + unsigned bias, + unsigned scale_2x, + unsigned absolute, + unsigned negate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dimension +tgsi_default_dimension( void ); + +struct tgsi_dimension +tgsi_build_dimension( + unsigned indirect, + unsigned index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dst_register +tgsi_default_dst_register( void ); + +struct tgsi_dst_register +tgsi_build_dst_register( + unsigned file, + unsigned mask, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_full_dst_register +tgsi_default_full_dst_register( void ); + +struct tgsi_dst_register_ext_concode +tgsi_default_dst_register_ext_concode( void ); + +unsigned +tgsi_compare_dst_register_ext_concode( + struct tgsi_dst_register_ext_concode a, + struct tgsi_dst_register_ext_concode b ); + +struct tgsi_dst_register_ext_concode +tgsi_build_dst_register_ext_concode( + unsigned cc, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + int index, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dst_register_ext_modulate +tgsi_default_dst_register_ext_modulate( void ); + +unsigned +tgsi_compare_dst_register_ext_modulate( + struct tgsi_dst_register_ext_modulate a, + struct tgsi_dst_register_ext_modulate b ); + +struct tgsi_dst_register_ext_modulate +tgsi_build_dst_register_ext_modulate( + unsigned modulate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_BUILD_H + diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c new file mode 100644 index 0000000000..b5c54847e0 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -0,0 +1,1581 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi_dump.h" +#include "tgsi_parse.h" +#include "tgsi_build.h" + +struct gen_dump +{ + unsigned tabs; + void (* write)( + struct gen_dump *dump, + const void *data, + unsigned size ); +}; + +struct text_dump +{ + struct gen_dump base; + char *text; + unsigned length; + unsigned capacity; +}; + +static void +_text_dump_write( + struct gen_dump *dump, + const void *data, + unsigned size ) +{ + struct text_dump *td = (struct text_dump *) dump; + unsigned new_length = td->length + size; + + if( new_length >= td->capacity ) { + unsigned new_capacity = td->capacity; + + do { + if( new_capacity == 0 ) { + new_capacity = 256; + } + else { + new_capacity *= 2; + } + } while( new_length >= new_capacity ); + td->text = (char *) REALLOC( + td->text, + td->capacity, + new_capacity ); + td->capacity = new_capacity; + } + memcpy( + &td->text[td->length], + data, + size ); + td->length = new_length; + td->text[td->length] = '\0'; +} + +struct file_dump +{ + struct gen_dump base; + FILE *file; +}; + +static void +_file_dump_write( + struct gen_dump *dump, + const void *data, + unsigned size ) +{ + struct file_dump *fd = (struct file_dump *) dump; + +#if 0 + fwrite( data, 1, size, fd->file ); +#else + { + unsigned i; + + for (i = 0; i < size; i++ ) { + fprintf( fd->file, "%c", ((const char *) data)[i] ); + } + } +#endif +} + +static void +gen_dump_str( + struct gen_dump *dump, + const char *str ) +{ + unsigned i; + size_t len = strlen( str ); + + for (i = 0; i < len; i++) { + dump->write( dump, &str[i], 1 ); + if (str[i] == '\n') { + unsigned i; + + for (i = 0; i < dump->tabs; i++) { + dump->write( dump, " ", 4 ); + } + } + } +} + +static void +gen_dump_chr( + struct gen_dump *dump, + const char chr ) +{ + dump->write( dump, &chr, 1 ); +} + +static void +gen_dump_uix( + struct gen_dump *dump, + const unsigned ui ) +{ + char str[36]; + + sprintf( str, "0x%x", ui ); + gen_dump_str( dump, str ); +} + +static void +gen_dump_uid( + struct gen_dump *dump, + const unsigned ui ) +{ + char str[16]; + + sprintf( str, "%u", ui ); + gen_dump_str( dump, str ); +} + +static void +gen_dump_sid( + struct gen_dump *dump, + const int si ) +{ + char str[16]; + + sprintf( str, "%d", si ); + gen_dump_str( dump, str ); +} + +static void +gen_dump_flt( + struct gen_dump *dump, + const float flt ) +{ + char str[48]; + + sprintf( str, "%10.4f", flt ); + gen_dump_str( dump, str ); +} + +static void +gen_dump_enum( + struct gen_dump *dump, + const unsigned e, + const char **enums, + const unsigned enums_count ) +{ + if (e >= enums_count) { + gen_dump_uid( dump, e ); + } + else { + gen_dump_str( dump, enums[e] ); + } +} + +static void +gen_dump_tab( + struct gen_dump *dump ) +{ + ++dump->tabs; +} + +static void +gen_dump_untab( + struct gen_dump *dump ) +{ + assert( dump->tabs > 0 ); + + --dump->tabs; +} + +#define TXT(S) gen_dump_str( dump, S ) +#define CHR(C) gen_dump_chr( dump, C ) +#define UIX(I) gen_dump_uix( dump, I ) +#define UID(I) gen_dump_uid( dump, I ) +#define SID(I) gen_dump_sid( dump, I ) +#define FLT(F) gen_dump_flt( dump, F ) +#define TAB() gen_dump_tab( dump ) +#define UNT() gen_dump_untab( dump ) +#define ENM(E,ENUMS) gen_dump_enum( dump, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) + +static const char *TGSI_PROCESSOR_TYPES[] = +{ + "PROCESSOR_FRAGMENT", + "PROCESSOR_VERTEX", + "PROCESSOR_GEOMETRY" +}; + +static const char *TGSI_PROCESSOR_TYPES_SHORT[] = +{ + "FRAG", + "VERT", + "GEOM" +}; + +static const char *TGSI_TOKEN_TYPES[] = +{ + "TOKEN_TYPE_DECLARATION", + "TOKEN_TYPE_IMMEDIATE", + "TOKEN_TYPE_INSTRUCTION" +}; + +static const char *TGSI_FILES[] = +{ + "FILE_NULL", + "FILE_CONSTANT", + "FILE_INPUT", + "FILE_OUTPUT", + "FILE_TEMPORARY", + "FILE_SAMPLER", + "FILE_ADDRESS", + "FILE_IMMEDIATE" +}; + +static const char *TGSI_FILES_SHORT[] = +{ + "NULL", + "CONST", + "IN", + "OUT", + "TEMP", + "SAMP", + "ADDR", + "IMM" +}; + +static const char *TGSI_DECLARES[] = +{ + "DECLARE_RANGE", + "DECLARE_MASK" +}; + +static const char *TGSI_INTERPOLATES[] = +{ + "INTERPOLATE_CONSTANT", + "INTERPOLATE_LINEAR", + "INTERPOLATE_PERSPECTIVE", + "INTERPOLATE_ATTRIB" +}; + +static const char *TGSI_INTERPOLATES_SHORT[] = +{ + "CONSTANT", + "LINEAR", + "PERSPECTIVE", + "ATTRIB" +}; + +static const char *TGSI_SEMANTICS[] = +{ + "SEMANTIC_POSITION", + "SEMANTIC_COLOR", + "SEMANTIC_BCOLOR", + "SEMANTIC_FOG", + "SEMANTIC_PSIZE", + "SEMANTIC_GENERIC," +}; + +static const char *TGSI_SEMANTICS_SHORT[] = +{ + "POSITION", + "COLOR", + "BCOLOR", + "FOG", + "PSIZE", + "GENERIC", +}; + +static const char *TGSI_IMMS[] = +{ + "IMM_FLOAT32" +}; + +static const char *TGSI_IMMS_SHORT[] = +{ + "FLT32" +}; + +static const char *TGSI_OPCODES[] = +{ + "OPCODE_ARL", + "OPCODE_MOV", + "OPCODE_LIT", + "OPCODE_RCP", + "OPCODE_RSQ", + "OPCODE_EXP", + "OPCODE_LOG", + "OPCODE_MUL", + "OPCODE_ADD", + "OPCODE_DP3", + "OPCODE_DP4", + "OPCODE_DST", + "OPCODE_MIN", + "OPCODE_MAX", + "OPCODE_SLT", + "OPCODE_SGE", + "OPCODE_MAD", + "OPCODE_SUB", + "OPCODE_LERP", + "OPCODE_CND", + "OPCODE_CND0", + "OPCODE_DOT2ADD", + "OPCODE_INDEX", + "OPCODE_NEGATE", + "OPCODE_FRAC", + "OPCODE_CLAMP", + "OPCODE_FLOOR", + "OPCODE_ROUND", + "OPCODE_EXPBASE2", + "OPCODE_LOGBASE2", + "OPCODE_POWER", + "OPCODE_CROSSPRODUCT", + "OPCODE_MULTIPLYMATRIX", + "OPCODE_ABS", + "OPCODE_RCC", + "OPCODE_DPH", + "OPCODE_COS", + "OPCODE_DDX", + "OPCODE_DDY", + "OPCODE_KILP", + "OPCODE_PK2H", + "OPCODE_PK2US", + "OPCODE_PK4B", + "OPCODE_PK4UB", + "OPCODE_RFL", + "OPCODE_SEQ", + "OPCODE_SFL", + "OPCODE_SGT", + "OPCODE_SIN", + "OPCODE_SLE", + "OPCODE_SNE", + "OPCODE_STR", + "OPCODE_TEX", + "OPCODE_TXD", + "OPCODE_UP2H", + "OPCODE_UP2US", + "OPCODE_UP4B", + "OPCODE_UP4UB", + "OPCODE_X2D", + "OPCODE_ARA", + "OPCODE_ARR", + "OPCODE_BRA", + "OPCODE_CAL", + "OPCODE_RET", + "OPCODE_SSG", + "OPCODE_CMP", + "OPCODE_SCS", + "OPCODE_TXB", + "OPCODE_NRM", + "OPCODE_DIV", + "OPCODE_DP2", + "OPCODE_TXL", + "OPCODE_BRK", + "OPCODE_IF", + "OPCODE_LOOP", + "OPCODE_REP", + "OPCODE_ELSE", + "OPCODE_ENDIF", + "OPCODE_ENDLOOP", + "OPCODE_ENDREP", + "OPCODE_PUSHA", + "OPCODE_POPA", + "OPCODE_CEIL", + "OPCODE_I2F", + "OPCODE_NOT", + "OPCODE_TRUNC", + "OPCODE_SHL", + "OPCODE_SHR", + "OPCODE_AND", + "OPCODE_OR", + "OPCODE_MOD", + "OPCODE_XOR", + "OPCODE_SAD", + "OPCODE_TXF", + "OPCODE_TXQ", + "OPCODE_CONT", + "OPCODE_EMIT", + "OPCODE_ENDPRIM", + "OPCODE_BGNLOOP2", + "OPCODE_BGNSUB", + "OPCODE_ENDLOOP2", + "OPCODE_ENDSUB", + "OPCODE_NOISE1", + "OPCODE_NOISE2", + "OPCODE_NOISE3", + "OPCODE_NOISE4", + "OPCODE_NOP", + "OPCODE_TEXBEM", + "OPCODE_TEXBEML", + "OPCODE_TEXREG2AR", + "OPCODE_TEXM3X2PAD", + "OPCODE_TEXM3X2TEX", + "OPCODE_TEXM3X3PAD", + "OPCODE_TEXM3X3TEX", + "OPCODE_TEXM3X3SPEC", + "OPCODE_TEXM3X3VSPEC", + "OPCODE_TEXREG2GB", + "OPCODE_TEXREG2RGB", + "OPCODE_TEXDP3TEX", + "OPCODE_TEXDP3", + "OPCODE_TEXM3X3", + "OPCODE_TEXM3X2DEPTH", + "OPCODE_TEXDEPTH", + "OPCODE_BEM", + "OPCODE_M4X3", + "OPCODE_M3X4", + "OPCODE_M3X3", + "OPCODE_M3X2", + "OPCODE_NRM4", + "OPCODE_CALLNZ", + "OPCODE_IFC", + "OPCODE_BREAKC", + "OPCODE_KIL", + "OPCODE_END" +}; + +static const char *TGSI_OPCODES_SHORT[] = +{ + "ARL", + "MOV", + "LIT", + "RCP", + "RSQ", + "EXP", + "LOG", + "MUL", + "ADD", + "DP3", + "DP4", + "DST", + "MIN", + "MAX", + "SLT", + "SGE", + "MAD", + "SUB", + "LERP", + "CND", + "CND0", + "DOT2ADD", + "INDEX", + "NEGATE", + "FRAC", + "CLAMP", + "FLOOR", + "ROUND", + "EXPBASE2", + "LOGBASE2", + "POWER", + "CROSSPRODUCT", + "MULTIPLYMATRIX", + "ABS", + "RCC", + "DPH", + "COS", + "DDX", + "DDY", + "KILP", + "PK2H", + "PK2US", + "PK4B", + "PK4UB", + "RFL", + "SEQ", + "SFL", + "SGT", + "SIN", + "SLE", + "SNE", + "STR", + "TEX", + "TXD", + "UP2H", + "UP2US", + "UP4B", + "UP4UB", + "X2D", + "ARA", + "ARR", + "BRA", + "CAL", + "RET", + "SSG", + "CMP", + "SCS", + "TXB", + "NRM", + "DIV", + "DP2", + "TXL", + "BRK", + "IF", + "LOOP", + "REP", + "ELSE", + "ENDIF", + "ENDLOOP", + "ENDREP", + "PUSHA", + "POPA", + "CEIL", + "I2F", + "NOT", + "TRUNC", + "SHL", + "SHR", + "AND", + "OR", + "MOD", + "XOR", + "SAD", + "TXF", + "TXQ", + "CONT", + "EMIT", + "ENDPRIM", + "BGNLOOP2", + "BGNSUB", + "ENDLOOP2", + "ENDSUB", + "NOISE1", + "NOISE2", + "NOISE3", + "NOISE4", + "NOP", + "TEXBEM", + "TEXBEML", + "TEXREG2AR", + "TEXM3X2PAD", + "TEXM3X2TEX", + "TEXM3X3PAD", + "TEXM3X3TEX", + "TEXM3X3SPEC", + "TEXM3X3VSPEC", + "TEXREG2GB", + "TEXREG2RGB", + "TEXDP3TEX", + "TEXDP3", + "TEXM3X3", + "TEXM3X2DEPTH", + "TEXDEPTH", + "BEM", + "M4X3", + "M3X4", + "M3X3", + "M3X2", + "NRM4", + "CALLNZ", + "IFC", + "BREAKC", + "KIL", + "END" +}; + +static const char *TGSI_SATS[] = +{ + "SAT_NONE", + "SAT_ZERO_ONE", + "SAT_MINUS_PLUS_ONE" +}; + +static const char *TGSI_INSTRUCTION_EXTS[] = +{ + "INSTRUCTION_EXT_TYPE_NV", + "INSTRUCTION_EXT_TYPE_LABEL", + "INSTRUCTION_EXT_TYPE_TEXTURE" +}; + +static const char *TGSI_PRECISIONS[] = +{ + "PRECISION_DEFAULT", + "TGSI_PRECISION_FLOAT32", + "TGSI_PRECISION_FLOAT16", + "TGSI_PRECISION_FIXED12" +}; + +static const char *TGSI_CCS[] = +{ + "CC_GT", + "CC_EQ", + "CC_LT", + "CC_UN", + "CC_GE", + "CC_LE", + "CC_NE", + "CC_TR", + "CC_FL" +}; + +static const char *TGSI_SWIZZLES[] = +{ + "SWIZZLE_X", + "SWIZZLE_Y", + "SWIZZLE_Z", + "SWIZZLE_W" +}; + +static const char *TGSI_SWIZZLES_SHORT[] = +{ + "x", + "y", + "z", + "w" +}; + +static const char *TGSI_TEXTURES[] = +{ + "TEXTURE_UNKNOWN", + "TEXTURE_1D", + "TEXTURE_2D", + "TEXTURE_3D", + "TEXTURE_CUBE", + "TEXTURE_RECT", + "TEXTURE_SHADOW1D", + "TEXTURE_SHADOW2D", + "TEXTURE_SHADOWRECT" +}; + +static const char *TGSI_SRC_REGISTER_EXTS[] = +{ + "SRC_REGISTER_EXT_TYPE_SWZ", + "SRC_REGISTER_EXT_TYPE_MOD" +}; + +static const char *TGSI_EXTSWIZZLES[] = +{ + "EXTSWIZZLE_X", + "EXTSWIZZLE_Y", + "EXTSWIZZLE_Z", + "EXTSWIZZLE_W", + "EXTSWIZZLE_ZERO", + "EXTSWIZZLE_ONE" +}; + +static const char *TGSI_EXTSWIZZLES_SHORT[] = +{ + "x", + "y", + "z", + "w", + "0", + "1" +}; + +static const char *TGSI_WRITEMASKS[] = +{ + "0", + "WRITEMASK_X", + "WRITEMASK_Y", + "WRITEMASK_XY", + "WRITEMASK_Z", + "WRITEMASK_XZ", + "WRITEMASK_YZ", + "WRITEMASK_XYZ", + "WRITEMASK_W", + "WRITEMASK_XW", + "WRITEMASK_YW", + "WRITEMASK_XYW", + "WRITEMASK_ZW", + "WRITEMASK_XZW", + "WRITEMASK_YZW", + "WRITEMASK_XYZW" +}; + +static const char *TGSI_DST_REGISTER_EXTS[] = +{ + "DST_REGISTER_EXT_TYPE_CONDCODE", + "DST_REGISTER_EXT_TYPE_MODULATE" +}; + +static const char *TGSI_MODULATES[] = +{ + "MODULATE_1X", + "MODULATE_2X", + "MODULATE_4X", + "MODULATE_8X", + "MODULATE_HALF", + "MODULATE_QUARTER", + "MODULATE_EIGHTH" +}; + +static void +dump_declaration_short( + struct gen_dump *dump, + struct tgsi_full_declaration *decl ) +{ + TXT( "\nDCL " ); + ENM( decl->Declaration.File, TGSI_FILES_SHORT ); + + switch( decl->Declaration.Declare ) { + case TGSI_DECLARE_RANGE: + CHR( '[' ); + UID( decl->u.DeclarationRange.First ); + if( decl->u.DeclarationRange.First != decl->u.DeclarationRange.Last ) { + TXT( ".." ); + UID( decl->u.DeclarationRange.Last ); + } + CHR( ']' ); + break; + default: + assert( 0 ); + } + + if( decl->Declaration.UsageMask != TGSI_WRITEMASK_XYZW ) { + CHR( '.' ); + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { + CHR( 'x' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { + CHR( 'y' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { + CHR( 'z' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { + CHR( 'w' ); + } + } + + if( decl->Declaration.Interpolate ) { + TXT( ", " ); + ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES_SHORT ); + } + + if( decl->Declaration.Semantic ) { + TXT( ", " ); + ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT ); + CHR( '[' ); + UID( decl->Semantic.SemanticIndex ); + CHR( ']' ); + } +} + +static void +dump_declaration_verbose( + struct gen_dump *dump, + struct tgsi_full_declaration *decl, + unsigned ignored, + unsigned deflt, + struct tgsi_full_declaration *fd ) +{ + TXT( "\nFile : " ); + ENM( decl->Declaration.File, TGSI_FILES ); + TXT( "\nDeclare : " ); + ENM( decl->Declaration.Declare, TGSI_DECLARES ); + if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) { + TXT( "\nUsageMask : " ); + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { + CHR( 'X' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { + CHR( 'Y' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { + CHR( 'Z' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { + CHR( 'W' ); + } + } + if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) { + TXT( "\nInterpolate: " ); + UID( decl->Declaration.Interpolate ); + } + if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) { + TXT( "\nSemantic : " ); + UID( decl->Declaration.Semantic ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Declaration.Padding ); + } + + CHR( '\n' ); + switch( decl->Declaration.Declare ) { + case TGSI_DECLARE_RANGE: + TXT( "\nFirst: " ); + UID( decl->u.DeclarationRange.First ); + TXT( "\nLast : " ); + UID( decl->u.DeclarationRange.Last ); + break; + + case TGSI_DECLARE_MASK: + TXT( "\nMask: " ); + UIX( decl->u.DeclarationMask.Mask ); + break; + + default: + assert( 0 ); + } + + if( decl->Declaration.Interpolate ) { + CHR( '\n' ); + TXT( "\nInterpolate: " ); + ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Interpolation.Padding ); + } + } + + if( decl->Declaration.Semantic ) { + CHR( '\n' ); + TXT( "\nSemanticName : " ); + ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS ); + TXT( "\nSemanticIndex: " ); + UID( decl->Semantic.SemanticIndex ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Semantic.Padding ); + } + } +} + +static void +dump_immediate_short( + struct gen_dump *dump, + struct tgsi_full_immediate *imm ) +{ + unsigned i; + + TXT( "\nIMM " ); + ENM( imm->Immediate.DataType, TGSI_IMMS_SHORT ); + + TXT( " { " ); + for( i = 0; i < imm->Immediate.Size - 1; i++ ) { + switch( imm->Immediate.DataType ) { + case TGSI_IMM_FLOAT32: + FLT( imm->u.ImmediateFloat32[i].Float ); + break; + + default: + assert( 0 ); + } + + if( i < imm->Immediate.Size - 2 ) { + TXT( ", " ); + } + } + TXT( " }" ); +} + +static void +dump_immediate_verbose( + struct gen_dump *dump, + struct tgsi_full_immediate *imm, + unsigned ignored ) +{ + unsigned i; + + TXT( "\nDataType : " ); + ENM( imm->Immediate.DataType, TGSI_IMMS ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( imm->Immediate.Padding ); + } + + for( i = 0; i < imm->Immediate.Size - 1; i++ ) { + CHR( '\n' ); + switch( imm->Immediate.DataType ) { + case TGSI_IMM_FLOAT32: + TXT( "\nFloat: " ); + FLT( imm->u.ImmediateFloat32[i].Float ); + break; + + default: + assert( 0 ); + } + } +} + +static void +dump_instruction_short( + struct gen_dump *dump, + struct tgsi_full_instruction *inst, + unsigned instno ) +{ + unsigned i; + boolean first_reg = TRUE; + + CHR( '\n' ); + UID( instno ); + CHR( ':' ); + ENM( inst->Instruction.Opcode, TGSI_OPCODES_SHORT ); + + switch( inst->Instruction.Saturate ) { + case TGSI_SAT_NONE: + break; + case TGSI_SAT_ZERO_ONE: + TXT( "_SAT" ); + break; + case TGSI_SAT_MINUS_PLUS_ONE: + TXT( "_SAT[-1,1]" ); + break; + default: + assert( 0 ); + } + + for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + + if( !first_reg ) { + CHR( ',' ); + } + CHR( ' ' ); + + ENM( dst->DstRegister.File, TGSI_FILES_SHORT ); + + CHR( '[' ); + SID( dst->DstRegister.Index ); + CHR( ']' ); + + if( dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW ) { + CHR( '.' ); + if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_X ) { + CHR( 'x' ); + } + if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_Y ) { + CHR( 'y' ); + } + if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_Z ) { + CHR( 'z' ); + } + if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_W ) { + CHR( 'w' ); + } + } + + first_reg = FALSE; + } + + for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + + if( !first_reg ) { + CHR( ',' ); + } + CHR( ' ' ); + + if( src->SrcRegisterExtMod.Complement ) { + TXT( "(1 - " ); + } + if( src->SrcRegisterExtMod.Negate ) { + CHR( '-' ); + } + if( src->SrcRegisterExtMod.Absolute ) { + CHR( '|' ); + } + if( src->SrcRegister.Negate ) { + CHR( '-' ); + } + + ENM( src->SrcRegister.File, TGSI_FILES_SHORT ); + + CHR( '[' ); + SID( src->SrcRegister.Index ); + CHR( ']' ); + + if (src->SrcRegister.Extended) { + if (src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || + src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || + src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || + src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) { + CHR( '.' ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES_SHORT ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES_SHORT ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES_SHORT ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES_SHORT ); + } + } + else if( src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || + src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || + src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || + src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W ) { + CHR( '.' ); + ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES_SHORT ); + ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES_SHORT ); + ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES_SHORT ); + ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES_SHORT ); + } + + if( src->SrcRegisterExtMod.Absolute ) { + CHR( '|' ); + } + if( src->SrcRegisterExtMod.Complement ) { + CHR( ')' ); + } + + first_reg = FALSE; + } + + switch( inst->Instruction.Opcode ) { + case TGSI_OPCODE_IF: + case TGSI_OPCODE_ELSE: + case TGSI_OPCODE_BGNLOOP2: + case TGSI_OPCODE_ENDLOOP2: + case TGSI_OPCODE_CAL: + TXT( " :" ); + UID( inst->InstructionExtLabel.Label ); + break; + } +} + +static void +dump_instruction_verbose( + struct gen_dump *dump, + struct tgsi_full_instruction *inst, + unsigned ignored, + unsigned deflt, + struct tgsi_full_instruction *fi ) +{ + unsigned i; + + TXT( "\nOpcode : " ); + ENM( inst->Instruction.Opcode, TGSI_OPCODES ); + if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) { + TXT( "\nSaturate : " ); + ENM( inst->Instruction.Saturate, TGSI_SATS ); + } + if( deflt || fi->Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) { + TXT( "\nNumDstRegs : " ); + UID( inst->Instruction.NumDstRegs ); + } + if( deflt || fi->Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) { + TXT( "\nNumSrcRegs : " ); + UID( inst->Instruction.NumSrcRegs ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->Instruction.Padding ); + } + + if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi->InstructionExtNv ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) { + TXT( "\nPrecision : " ); + ENM( inst->InstructionExtNv.Precision, TGSI_PRECISIONS ); + } + if( deflt || fi->InstructionExtNv.CondDstIndex != inst->InstructionExtNv.CondDstIndex ) { + TXT( "\nCondDstIndex : " ); + UID( inst->InstructionExtNv.CondDstIndex ); + } + if( deflt || fi->InstructionExtNv.CondFlowIndex != inst->InstructionExtNv.CondFlowIndex ) { + TXT( "\nCondFlowIndex : " ); + UID( inst->InstructionExtNv.CondFlowIndex ); + } + if( deflt || fi->InstructionExtNv.CondMask != inst->InstructionExtNv.CondMask ) { + TXT( "\nCondMask : " ); + ENM( inst->InstructionExtNv.CondMask, TGSI_CCS ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleX != inst->InstructionExtNv.CondSwizzleX ) { + TXT( "\nCondSwizzleX : " ); + ENM( inst->InstructionExtNv.CondSwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleY != inst->InstructionExtNv.CondSwizzleY ) { + TXT( "\nCondSwizzleY : " ); + ENM( inst->InstructionExtNv.CondSwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleZ != inst->InstructionExtNv.CondSwizzleZ ) { + TXT( "\nCondSwizzleZ : " ); + ENM( inst->InstructionExtNv.CondSwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleW != inst->InstructionExtNv.CondSwizzleW ) { + TXT( "\nCondSwizzleW : " ); + ENM( inst->InstructionExtNv.CondSwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondDstUpdate != inst->InstructionExtNv.CondDstUpdate ) { + TXT( "\nCondDstUpdate : " ); + UID( inst->InstructionExtNv.CondDstUpdate ); + } + if( deflt || fi->InstructionExtNv.CondFlowEnable != inst->InstructionExtNv.CondFlowEnable ) { + TXT( "\nCondFlowEnable: " ); + UID( inst->InstructionExtNv.CondFlowEnable ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtNv.Padding ); + if( deflt || fi->InstructionExtNv.Extended != inst->InstructionExtNv.Extended ) { + TXT( "\nExtended : " ); + UID( inst->InstructionExtNv.Extended ); + } + } + } + + if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) { + TXT( "\nLabel : " ); + UID( inst->InstructionExtLabel.Label ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtLabel.Padding ); + if( deflt || fi->InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) { + TXT( "\nExtended: " ); + UID( inst->InstructionExtLabel.Extended ); + } + } + } + + if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) { + TXT( "\nTexture : " ); + ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtTexture.Padding ); + if( deflt || fi->InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) { + TXT( "\nExtended: " ); + UID( inst->InstructionExtTexture.Extended ); + } + } + } + + for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i]; + + CHR( '\n' ); + TXT( "\nFile : " ); + ENM( dst->DstRegister.File, TGSI_FILES ); + if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) { + TXT( "\nWriteMask: " ); + ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS ); + } + if( ignored ) { + if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) { + TXT( "\nIndirect : " ); + UID( dst->DstRegister.Indirect ); + } + if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) { + TXT( "\nDimension: " ); + UID( dst->DstRegister.Dimension ); + } + } + if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) { + TXT( "\nIndex : " ); + SID( dst->DstRegister.Index ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegister.Padding ); + if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) { + TXT( "\nExtended : " ); + UID( dst->DstRegister.Extended ); + } + } + + if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS ); + if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) { + TXT( "\nCondMask : " ); + ENM( dst->DstRegisterExtConcode.CondMask, TGSI_CCS ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleX != dst->DstRegisterExtConcode.CondSwizzleX ) { + TXT( "\nCondSwizzleX: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleY != dst->DstRegisterExtConcode.CondSwizzleY ) { + TXT( "\nCondSwizzleY: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleZ != dst->DstRegisterExtConcode.CondSwizzleZ ) { + TXT( "\nCondSwizzleZ: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleW != dst->DstRegisterExtConcode.CondSwizzleW ) { + TXT( "\nCondSwizzleW: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSrcIndex != dst->DstRegisterExtConcode.CondSrcIndex ) { + TXT( "\nCondSrcIndex: " ); + UID( dst->DstRegisterExtConcode.CondSrcIndex ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegisterExtConcode.Padding ); + if( deflt || fd->DstRegisterExtConcode.Extended != dst->DstRegisterExtConcode.Extended ) { + TXT( "\nExtended : " ); + UID( dst->DstRegisterExtConcode.Extended ); + } + } + } + + if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS ); + if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) { + TXT( "\nModulate: " ); + ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegisterExtModulate.Padding ); + if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) { + TXT( "\nExtended: " ); + UID( dst->DstRegisterExtModulate.Extended ); + } + } + } + } + + for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i]; + + CHR( '\n' ); + TXT( "\nFile : "); + ENM( src->SrcRegister.File, TGSI_FILES ); + if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) { + TXT( "\nSwizzleX : " ); + ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) { + TXT( "\nSwizzleY : " ); + ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) { + TXT( "\nSwizzleZ : " ); + ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) { + TXT( "\nSwizzleW : " ); + ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) { + TXT( "\nNegate : " ); + UID( src->SrcRegister.Negate ); + } + if( ignored ) { + if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) { + TXT( "\nIndirect : " ); + UID( src->SrcRegister.Indirect ); + } + if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) { + TXT( "\nDimension: " ); + UID( src->SrcRegister.Dimension ); + } + } + if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) { + TXT( "\nIndex : " ); + SID( src->SrcRegister.Index ); + } + if( ignored ) { + if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegister.Extended ); + } + } + + if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS ); + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) { + TXT( "\nExtSwizzleX: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleY != src->SrcRegisterExtSwz.ExtSwizzleY ) { + TXT( "\nExtSwizzleY: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleZ != src->SrcRegisterExtSwz.ExtSwizzleZ ) { + TXT( "\nExtSwizzleZ: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleW != src->SrcRegisterExtSwz.ExtSwizzleW ) { + TXT( "\nExtSwizzleW: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateX != src->SrcRegisterExtSwz.NegateX ) { + TXT( "\nNegateX : " ); + UID( src->SrcRegisterExtSwz.NegateX ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateY != src->SrcRegisterExtSwz.NegateY ) { + TXT( "\nNegateY : " ); + UID( src->SrcRegisterExtSwz.NegateY ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateZ != src->SrcRegisterExtSwz.NegateZ ) { + TXT( "\nNegateZ : " ); + UID( src->SrcRegisterExtSwz.NegateZ ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateW != src->SrcRegisterExtSwz.NegateW ) { + TXT( "\nNegateW : " ); + UID( src->SrcRegisterExtSwz.NegateW ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtDivide != src->SrcRegisterExtSwz.ExtDivide ) { + TXT( "\nExtDivide : " ); + ENM( src->SrcRegisterExtSwz.ExtDivide, TGSI_EXTSWIZZLES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( src->SrcRegisterExtSwz.Padding ); + if( deflt || fs->SrcRegisterExtSwz.Extended != src->SrcRegisterExtSwz.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegisterExtSwz.Extended ); + } + } + } + + if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) { + CHR( '\n' ); + TXT( "\nType : " ); + ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS ); + if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) { + TXT( "\nComplement: " ); + UID( src->SrcRegisterExtMod.Complement ); + } + if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) { + TXT( "\nBias : " ); + UID( src->SrcRegisterExtMod.Bias ); + } + if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) { + TXT( "\nScale2X : " ); + UID( src->SrcRegisterExtMod.Scale2X ); + } + if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) { + TXT( "\nAbsolute : " ); + UID( src->SrcRegisterExtMod.Absolute ); + } + if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) { + TXT( "\nNegate : " ); + UID( src->SrcRegisterExtMod.Negate ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( src->SrcRegisterExtMod.Padding ); + if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegisterExtMod.Extended ); + } + } + } + } +} + +static void +dump_gen( + struct gen_dump *dump, + const struct tgsi_token *tokens, + unsigned flags ) +{ + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + unsigned verbose = flags & TGSI_DUMP_VERBOSE; + unsigned ignored = !(flags & TGSI_DUMP_NO_IGNORED); + unsigned deflt = !(flags & TGSI_DUMP_NO_DEFAULT); + unsigned instno = 0; + + dump->tabs = 0; + + /* sanity check */ + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); + + tgsi_parse_init( &parse, tokens ); + + TXT( "tgsi-dump begin -----------------" ); + + CHR( '\n' ); + ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES_SHORT ); + CHR( ' ' ); + UID( parse.FullVersion.Version.MajorVersion ); + CHR( '.' ); + UID( parse.FullVersion.Version.MinorVersion ); + + if( verbose ) { + TXT( "\nMajorVersion: " ); + UID( parse.FullVersion.Version.MajorVersion ); + TXT( "\nMinorVersion: " ); + UID( parse.FullVersion.Version.MinorVersion ); + CHR( '\n' ); + + TXT( "\nHeaderSize: " ); + UID( parse.FullHeader.Header.HeaderSize ); + TXT( "\nBodySize : " ); + UID( parse.FullHeader.Header.BodySize ); + TXT( "\nProcessor : " ); + ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); + CHR( '\n' ); + } + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + + while( !tgsi_parse_end_of_tokens( &parse ) ) { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + dump_declaration_short( + dump, + &parse.FullToken.FullDeclaration ); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + dump_immediate_short( + dump, + &parse.FullToken.FullImmediate ); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + dump_instruction_short( + dump, + &parse.FullToken.FullInstruction, + instno ); + instno++; + break; + + default: + assert( 0 ); + } + + if( verbose ) { + TXT( "\nType : " ); + ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES ); + if( ignored ) { + TXT( "\nSize : " ); + UID( parse.FullToken.Token.Size ); + if( deflt || parse.FullToken.Token.Extended ) { + TXT( "\nExtended : " ); + UID( parse.FullToken.Token.Extended ); + } + } + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + dump_declaration_verbose( + dump, + &parse.FullToken.FullDeclaration, + ignored, + deflt, + &fd ); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + dump_immediate_verbose( + dump, + &parse.FullToken.FullImmediate, + ignored ); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + dump_instruction_verbose( + dump, + &parse.FullToken.FullInstruction, + ignored, + deflt, + &fi ); + break; + + default: + assert( 0 ); + } + + CHR( '\n' ); + } + } + + TXT( "\ntgsi-dump end -------------------\n" ); + + tgsi_parse_free( &parse ); +} + + +static void +sanity_checks(void) +{ + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); + assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "END") == 0); +} + + +void +tgsi_dump( + const struct tgsi_token *tokens, + unsigned flags ) +{ + struct file_dump dump; + + sanity_checks(); + + dump.base.write = _file_dump_write; +#if 0 + { + static unsigned counter = 0; + char buffer[64]; + sprintf( buffer, "tgsi-dump-%.4u.txt", counter++ ); + dump.file = fopen( buffer, "wt" ); + } +#else + dump.file = stderr; +#endif + + dump_gen( + &dump.base, + tokens, + flags ); + +#if 0 + fclose( dump.file ); +#endif +} + +void +tgsi_dump_str( + char **str, + const struct tgsi_token *tokens, + unsigned flags ) +{ + struct text_dump dump; + + dump.base.write = _text_dump_write; + dump.text = NULL; + dump.length = 0; + dump.capacity = 0; + + dump_gen( + &dump.base, + tokens, + flags ); + + *str = dump.text; +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h new file mode 100644 index 0000000000..1adc9db251 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h @@ -0,0 +1,28 @@ +#if !defined TGSI_DUMP_H +#define TGSI_DUMP_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +#define TGSI_DUMP_VERBOSE 1 +#define TGSI_DUMP_NO_IGNORED 2 +#define TGSI_DUMP_NO_DEFAULT 4 + +void +tgsi_dump( + const struct tgsi_token *tokens, + unsigned flags ); + +void +tgsi_dump_str( + char **str, + const struct tgsi_token *tokens, + unsigned flags ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_DUMP_H + diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c new file mode 100644 index 0000000000..bf6b89ce56 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c @@ -0,0 +1,319 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi_parse.h" +#include "tgsi_build.h" + +void +tgsi_full_token_init( + union tgsi_full_token *full_token ) +{ + full_token->Token.Type = TGSI_TOKEN_TYPE_DECLARATION; +} + +void +tgsi_full_token_free( + union tgsi_full_token *full_token ) +{ + if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE ) { + FREE( full_token->FullImmediate.u.Pointer ); + } +} + +unsigned +tgsi_parse_init( + struct tgsi_parse_context *ctx, + const struct tgsi_token *tokens ) +{ + ctx->FullVersion.Version = *(struct tgsi_version *) &tokens[0]; + if( ctx->FullVersion.Version.MajorVersion > 1 ) { + return TGSI_PARSE_ERROR; + } + + ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[1]; + if( ctx->FullHeader.Header.HeaderSize >= 2 ) { + ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[2]; + } + else { + ctx->FullHeader.Processor = tgsi_default_processor(); + } + + ctx->Tokens = tokens; + ctx->Position = 1 + ctx->FullHeader.Header.HeaderSize; + + tgsi_full_token_init( &ctx->FullToken ); + + return TGSI_PARSE_OK; +} + +void +tgsi_parse_free( + struct tgsi_parse_context *ctx ) +{ + tgsi_full_token_free( &ctx->FullToken ); +} + +boolean +tgsi_parse_end_of_tokens( + struct tgsi_parse_context *ctx ) +{ + return ctx->Position >= + 1 + ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize; +} + +static void +next_token( + struct tgsi_parse_context *ctx, + void *token ) +{ + assert( !tgsi_parse_end_of_tokens( ctx ) ); + + *(struct tgsi_token *) token = ctx->Tokens[ctx->Position++]; +} + +void +tgsi_parse_token( + struct tgsi_parse_context *ctx ) +{ + struct tgsi_token token; + unsigned i; + + tgsi_full_token_free( &ctx->FullToken ); + tgsi_full_token_init( &ctx->FullToken ); + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + struct tgsi_full_declaration *decl = &ctx->FullToken.FullDeclaration; + + *decl = tgsi_default_full_declaration(); + decl->Declaration = *(struct tgsi_declaration *) &token; + + switch( decl->Declaration.Type ) { + case TGSI_DECLARE_RANGE: + next_token( ctx, &decl->u.DeclarationRange ); + break; + + case TGSI_DECLARE_MASK: + next_token( ctx, &decl->u.DeclarationMask ); + break; + + default: + assert (0); + } + + if( decl->Declaration.Interpolate ) { + next_token( ctx, &decl->Interpolation ); + } + + if( decl->Declaration.Semantic ) { + next_token( ctx, &decl->Semantic ); + } + + break; + } + + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate; + + *imm = tgsi_default_full_immediate(); + imm->Immediate = *(struct tgsi_immediate *) &token; + + assert( !imm->Immediate.Extended ); + + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + imm->u.Pointer = MALLOC( + sizeof( struct tgsi_immediate_float32 ) * (imm->Immediate.Size - 1) ); + for( i = 0; i < imm->Immediate.Size - 1; i++ ) { + next_token( ctx, &imm->u.ImmediateFloat32[i] ); + } + break; + + default: + assert( 0 ); + } + + break; + } + + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction; + unsigned extended; + + *inst = tgsi_default_full_instruction(); + inst->Instruction = *(struct tgsi_instruction *) &token; + + extended = inst->Instruction.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_INSTRUCTION_EXT_TYPE_NV: + inst->InstructionExtNv = + *(struct tgsi_instruction_ext_nv *) &token; + break; + + case TGSI_INSTRUCTION_EXT_TYPE_LABEL: + inst->InstructionExtLabel = + *(struct tgsi_instruction_ext_label *) &token; + break; + + case TGSI_INSTRUCTION_EXT_TYPE_TEXTURE: + inst->InstructionExtTexture = + *(struct tgsi_instruction_ext_texture *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + + assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS ); + + for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + unsigned extended; + + next_token( ctx, &inst->FullDstRegisters[i].DstRegister ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullDstRegisters[i].DstRegister.Indirect ); + assert( !inst->FullDstRegisters[i].DstRegister.Dimension ); + + extended = inst->FullDstRegisters[i].DstRegister.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_DST_REGISTER_EXT_TYPE_CONDCODE: + inst->FullDstRegisters[i].DstRegisterExtConcode = + *(struct tgsi_dst_register_ext_concode *) &token; + break; + + case TGSI_DST_REGISTER_EXT_TYPE_MODULATE: + inst->FullDstRegisters[i].DstRegisterExtModulate = + *(struct tgsi_dst_register_ext_modulate *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + } + + assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS ); + + for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + unsigned extended; + + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegister ); + + extended = inst->FullSrcRegisters[i].SrcRegister.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_SRC_REGISTER_EXT_TYPE_SWZ: + inst->FullSrcRegisters[i].SrcRegisterExtSwz = + *(struct tgsi_src_register_ext_swz *) &token; + break; + + case TGSI_SRC_REGISTER_EXT_TYPE_MOD: + inst->FullSrcRegisters[i].SrcRegisterExtMod = + *(struct tgsi_src_register_ext_mod *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + + if( inst->FullSrcRegisters[i].SrcRegister.Indirect ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterInd ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); + } + + if( inst->FullSrcRegisters[i].SrcRegister.Dimension ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDim ); + + /* + * No support for multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Extended ); + + if( inst->FullSrcRegisters[i].SrcRegisterDim.Indirect ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDimInd ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); + } + } + } + + break; + } + + default: + assert( 0 ); + } +} + diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h new file mode 100644 index 0000000000..9372da8d5d --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h @@ -0,0 +1,121 @@ +#if !defined TGSI_PARSE_H +#define TGSI_PARSE_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +struct tgsi_full_version +{ + struct tgsi_version Version; +}; + +struct tgsi_full_header +{ + struct tgsi_header Header; + struct tgsi_processor Processor; +}; + +struct tgsi_full_dst_register +{ + struct tgsi_dst_register DstRegister; + struct tgsi_dst_register_ext_concode DstRegisterExtConcode; + struct tgsi_dst_register_ext_modulate DstRegisterExtModulate; +}; + +struct tgsi_full_src_register +{ + struct tgsi_src_register SrcRegister; + struct tgsi_src_register_ext_swz SrcRegisterExtSwz; + struct tgsi_src_register_ext_mod SrcRegisterExtMod; + struct tgsi_src_register SrcRegisterInd; + struct tgsi_dimension SrcRegisterDim; + struct tgsi_src_register SrcRegisterDimInd; +}; + +struct tgsi_full_declaration +{ + struct tgsi_declaration Declaration; + union + { + struct tgsi_declaration_range DeclarationRange; + struct tgsi_declaration_mask DeclarationMask; + } u; + struct tgsi_declaration_interpolation Interpolation; + struct tgsi_declaration_semantic Semantic; +}; + +struct tgsi_full_immediate +{ + struct tgsi_immediate Immediate; + union + { + void *Pointer; + struct tgsi_immediate_float32 *ImmediateFloat32; + } u; +}; + +#define TGSI_FULL_MAX_DST_REGISTERS 2 +#define TGSI_FULL_MAX_SRC_REGISTERS 3 + +struct tgsi_full_instruction +{ + struct tgsi_instruction Instruction; + struct tgsi_instruction_ext_nv InstructionExtNv; + struct tgsi_instruction_ext_label InstructionExtLabel; + struct tgsi_instruction_ext_texture InstructionExtTexture; + struct tgsi_full_dst_register FullDstRegisters[TGSI_FULL_MAX_DST_REGISTERS]; + struct tgsi_full_src_register FullSrcRegisters[TGSI_FULL_MAX_SRC_REGISTERS]; +}; + +union tgsi_full_token +{ + struct tgsi_token Token; + struct tgsi_full_declaration FullDeclaration; + struct tgsi_full_immediate FullImmediate; + struct tgsi_full_instruction FullInstruction; +}; + +void +tgsi_full_token_init( + union tgsi_full_token *full_token ); + +void +tgsi_full_token_free( + union tgsi_full_token *full_token ); + +struct tgsi_parse_context +{ + const struct tgsi_token *Tokens; + unsigned Position; + struct tgsi_full_version FullVersion; + struct tgsi_full_header FullHeader; + union tgsi_full_token FullToken; +}; + +#define TGSI_PARSE_OK 0 +#define TGSI_PARSE_ERROR 1 + +unsigned +tgsi_parse_init( + struct tgsi_parse_context *ctx, + const struct tgsi_token *tokens ); + +void +tgsi_parse_free( + struct tgsi_parse_context *ctx ); + +boolean +tgsi_parse_end_of_tokens( + struct tgsi_parse_context *ctx ); + +void +tgsi_parse_token( + struct tgsi_parse_context *ctx ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_PARSE_H + diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_transform.c b/src/gallium/auxiliary/tgsi/util/tgsi_transform.c new file mode 100644 index 0000000000..357f77b05a --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_transform.c @@ -0,0 +1,199 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * TGSI program transformation utility. + * + * Authors: Brian Paul + */ + + +#include "tgsi_transform.h" + + + +static void +emit_instruction(struct tgsi_transform_context *ctx, + const struct tgsi_full_instruction *inst) +{ + uint ti = ctx->ti; + + ti += tgsi_build_full_instruction(inst, + ctx->tokens_out + ti, + ctx->header, + ctx->max_tokens_out - ti); + ctx->ti = ti; +} + + +static void +emit_declaration(struct tgsi_transform_context *ctx, + const struct tgsi_full_declaration *decl) +{ + uint ti = ctx->ti; + + ti += tgsi_build_full_declaration(decl, + ctx->tokens_out + ti, + ctx->header, + ctx->max_tokens_out - ti); + ctx->ti = ti; +} + + +static void +emit_immediate(struct tgsi_transform_context *ctx, + const struct tgsi_full_immediate *imm) +{ + uint ti = ctx->ti; + + ti += tgsi_build_full_immediate(imm, + ctx->tokens_out + ti, + ctx->header, + ctx->max_tokens_out - ti); + ctx->ti = ti; +} + + + +/** + * Apply user-defined transformations to the input shader to produce + * the output shader. + * For example, a register search-and-replace operation could be applied + * by defining a transform_instruction() callback that examined and changed + * the instruction src/dest regs. + * + * \return number of tokens emitted + */ +int +tgsi_transform_shader(const struct tgsi_token *tokens_in, + struct tgsi_token *tokens_out, + uint max_tokens_out, + struct tgsi_transform_context *ctx) +{ + uint procType; + + /* input shader */ + struct tgsi_parse_context parse; + + /* output shader */ + struct tgsi_processor *processor; + + + /** + ** callback context init + **/ + ctx->emit_instruction = emit_instruction; + ctx->emit_declaration = emit_declaration; + ctx->emit_immediate = emit_immediate; + ctx->tokens_out = tokens_out; + ctx->max_tokens_out = max_tokens_out; + + + /** + ** Setup to begin parsing input shader + **/ + if (tgsi_parse_init( &parse, tokens_in ) != TGSI_PARSE_OK) { + debug_printf("tgsi_parse_init() failed in tgsi_transform_shader()!\n"); + return -1; + } + procType = parse.FullHeader.Processor.Processor; + assert(procType == TGSI_PROCESSOR_FRAGMENT || + procType == TGSI_PROCESSOR_VERTEX || + procType == TGSI_PROCESSOR_GEOMETRY); + + + /** + ** Setup output shader + **/ + *(struct tgsi_version *) &tokens_out[0] = tgsi_build_version(); + + ctx->header = (struct tgsi_header *) (tokens_out + 1); + *ctx->header = tgsi_build_header(); + + processor = (struct tgsi_processor *) (tokens_out + 2); + *processor = tgsi_build_processor( procType, ctx->header ); + + ctx->ti = 3; + + + /** + ** Loop over incoming program tokens/instructions + */ + while( !tgsi_parse_end_of_tokens( &parse ) ) { + + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *fullinst + = &parse.FullToken.FullInstruction; + + if (ctx->transform_instruction) + ctx->transform_instruction(ctx, fullinst); + else + ctx->emit_instruction(ctx, fullinst); + } + break; + + case TGSI_TOKEN_TYPE_DECLARATION: + { + struct tgsi_full_declaration *fulldecl + = &parse.FullToken.FullDeclaration; + + if (ctx->transform_declaration) + ctx->transform_declaration(ctx, fulldecl); + else + ctx->emit_declaration(ctx, fulldecl); + } + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + struct tgsi_full_immediate *fullimm + = &parse.FullToken.FullImmediate; + + if (ctx->transform_immediate) + ctx->transform_immediate(ctx, fullimm); + else + ctx->emit_immediate(ctx, fullimm); + } + break; + + default: + assert( 0 ); + } + } + + if (ctx->epilog) { + ctx->epilog(ctx); + } + + tgsi_parse_free (&parse); + + return ctx->ti; +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_transform.h b/src/gallium/auxiliary/tgsi/util/tgsi_transform.h new file mode 100644 index 0000000000..fcf85d603b --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_transform.h @@ -0,0 +1,93 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_TRANSFORM_H +#define TGSI_TRANSFORM_H + + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_build.h" + + + +/** + * Subclass this to add caller-specific data + */ +struct tgsi_transform_context +{ +/**** PUBLIC ***/ + + /** + * User-defined callbacks invoked per instruction. + */ + void (*transform_instruction)(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst); + + void (*transform_declaration)(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl); + + void (*transform_immediate)(struct tgsi_transform_context *ctx, + struct tgsi_full_immediate *imm); + + /** + * Called at end of input program to allow caller to append extra + * instructions. Return number of tokens emitted. + */ + void (*epilog)(struct tgsi_transform_context *ctx); + + +/*** PRIVATE ***/ + + /** + * These are setup by tgsi_transform_shader() and cannot be overridden. + * Meant to be called from in the above user callback functions. + */ + void (*emit_instruction)(struct tgsi_transform_context *ctx, + const struct tgsi_full_instruction *inst); + void (*emit_declaration)(struct tgsi_transform_context *ctx, + const struct tgsi_full_declaration *decl); + void (*emit_immediate)(struct tgsi_transform_context *ctx, + const struct tgsi_full_immediate *imm); + + struct tgsi_header *header; + uint max_tokens_out; + struct tgsi_token *tokens_out; + uint ti; +}; + + + +extern int +tgsi_transform_shader(const struct tgsi_token *tokens_in, + struct tgsi_token *tokens_out, + uint max_tokens_out, + struct tgsi_transform_context *ctx); + + +#endif /* TGSI_TRANSFORM_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.c b/src/gallium/auxiliary/tgsi/util/tgsi_util.c new file mode 100644 index 0000000000..4cdd89182a --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_util.c @@ -0,0 +1,274 @@ +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi_parse.h" +#include "tgsi_build.h" +#include "tgsi_util.h" + +union pointer_hack +{ + void *pointer; + unsigned long long uint64; +}; + +void * +tgsi_align_128bit( + void *unaligned ) +{ + union pointer_hack ph; + + ph.uint64 = 0; + ph.pointer = unaligned; + ph.uint64 = (ph.uint64 + 15) & ~15; + return ph.pointer; +} + +unsigned +tgsi_util_get_src_register_swizzle( + const struct tgsi_src_register *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->SwizzleX; + case 1: + return reg->SwizzleY; + case 2: + return reg->SwizzleZ; + case 3: + return reg->SwizzleW; + default: + assert( 0 ); + } + return 0; +} + +unsigned +tgsi_util_get_src_register_extswizzle( + const struct tgsi_src_register_ext_swz *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->ExtSwizzleX; + case 1: + return reg->ExtSwizzleY; + case 2: + return reg->ExtSwizzleZ; + case 3: + return reg->ExtSwizzleW; + default: + assert( 0 ); + } + return 0; +} + +unsigned +tgsi_util_get_full_src_register_extswizzle( + const struct tgsi_full_src_register *reg, + unsigned component ) +{ + unsigned swizzle; + + /* + * First, calculate the extended swizzle for a given channel. This will give + * us either a channel index into the simple swizzle or a constant 1 or 0. + */ + swizzle = tgsi_util_get_src_register_extswizzle( + ®->SrcRegisterExtSwz, + component ); + + assert (TGSI_SWIZZLE_X == TGSI_EXTSWIZZLE_X); + assert (TGSI_SWIZZLE_Y == TGSI_EXTSWIZZLE_Y); + assert (TGSI_SWIZZLE_Z == TGSI_EXTSWIZZLE_Z); + assert (TGSI_SWIZZLE_W == TGSI_EXTSWIZZLE_W); + assert (TGSI_EXTSWIZZLE_ZERO > TGSI_SWIZZLE_W); + assert (TGSI_EXTSWIZZLE_ONE > TGSI_SWIZZLE_W); + + /* + * Second, calculate the simple swizzle for the unswizzled channel index. + * Leave the constants intact, they are not affected by the simple swizzle. + */ + if( swizzle <= TGSI_SWIZZLE_W ) { + swizzle = tgsi_util_get_src_register_swizzle( + ®->SrcRegister, + component ); + } + + return swizzle; +} + +void +tgsi_util_set_src_register_swizzle( + struct tgsi_src_register *reg, + unsigned swizzle, + unsigned component ) +{ + switch( component ) { + case 0: + reg->SwizzleX = swizzle; + break; + case 1: + reg->SwizzleY = swizzle; + break; + case 2: + reg->SwizzleZ = swizzle; + break; + case 3: + reg->SwizzleW = swizzle; + break; + default: + assert( 0 ); + } +} + +void +tgsi_util_set_src_register_extswizzle( + struct tgsi_src_register_ext_swz *reg, + unsigned swizzle, + unsigned component ) +{ + switch( component ) { + case 0: + reg->ExtSwizzleX = swizzle; + break; + case 1: + reg->ExtSwizzleY = swizzle; + break; + case 2: + reg->ExtSwizzleZ = swizzle; + break; + case 3: + reg->ExtSwizzleW = swizzle; + break; + default: + assert( 0 ); + } +} + +unsigned +tgsi_util_get_src_register_extnegate( + const struct tgsi_src_register_ext_swz *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->NegateX; + case 1: + return reg->NegateY; + case 2: + return reg->NegateZ; + case 3: + return reg->NegateW; + default: + assert( 0 ); + } + return 0; +} + +void +tgsi_util_set_src_register_extnegate( + struct tgsi_src_register_ext_swz *reg, + unsigned negate, + unsigned component ) +{ + switch( component ) { + case 0: + reg->NegateX = negate; + break; + case 1: + reg->NegateY = negate; + break; + case 2: + reg->NegateZ = negate; + break; + case 3: + reg->NegateW = negate; + break; + default: + assert( 0 ); + } +} + +unsigned +tgsi_util_get_full_src_register_sign_mode( + const struct tgsi_full_src_register *reg, + unsigned component ) +{ + unsigned sign_mode; + + if( reg->SrcRegisterExtMod.Absolute ) { + /* Consider only the post-abs negation. */ + + if( reg->SrcRegisterExtMod.Negate ) { + sign_mode = TGSI_UTIL_SIGN_SET; + } + else { + sign_mode = TGSI_UTIL_SIGN_CLEAR; + } + } + else { + /* Accumulate the three negations. */ + + unsigned negate; + + negate = reg->SrcRegister.Negate; + if( tgsi_util_get_src_register_extnegate( ®->SrcRegisterExtSwz, component ) ) { + negate = !negate; + } + if( reg->SrcRegisterExtMod.Negate ) { + negate = !negate; + } + + if( negate ) { + sign_mode = TGSI_UTIL_SIGN_TOGGLE; + } + else { + sign_mode = TGSI_UTIL_SIGN_KEEP; + } + } + + return sign_mode; +} + +void +tgsi_util_set_full_src_register_sign_mode( + struct tgsi_full_src_register *reg, + unsigned sign_mode ) +{ + reg->SrcRegisterExtSwz.NegateX = 0; + reg->SrcRegisterExtSwz.NegateY = 0; + reg->SrcRegisterExtSwz.NegateZ = 0; + reg->SrcRegisterExtSwz.NegateW = 0; + + switch (sign_mode) + { + case TGSI_UTIL_SIGN_CLEAR: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 1; + reg->SrcRegisterExtMod.Negate = 0; + break; + + case TGSI_UTIL_SIGN_SET: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 1; + reg->SrcRegisterExtMod.Negate = 1; + break; + + case TGSI_UTIL_SIGN_TOGGLE: + reg->SrcRegister.Negate = 1; + reg->SrcRegisterExtMod.Absolute = 0; + reg->SrcRegisterExtMod.Negate = 0; + break; + + case TGSI_UTIL_SIGN_KEEP: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 0; + reg->SrcRegisterExtMod.Negate = 0; + break; + + default: + assert( 0 ); + } +} + diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.h b/src/gallium/auxiliary/tgsi/util/tgsi_util.h new file mode 100644 index 0000000000..ef14446f0e --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_util.h @@ -0,0 +1,70 @@ +#if !defined TGSI_UTIL_H +#define TGSI_UTIL_H + +#if defined __cplusplus +extern "C" { +#endif // defined __cplusplus + +void * +tgsi_align_128bit( + void *unaligned ); + +unsigned +tgsi_util_get_src_register_swizzle( + const struct tgsi_src_register *reg, + unsigned component ); + +unsigned +tgsi_util_get_src_register_extswizzle( + const struct tgsi_src_register_ext_swz *reg, + unsigned component); + +unsigned +tgsi_util_get_full_src_register_extswizzle( + const struct tgsi_full_src_register *reg, + unsigned component ); + +void +tgsi_util_set_src_register_swizzle( + struct tgsi_src_register *reg, + unsigned swizzle, + unsigned component ); + +void +tgsi_util_set_src_register_extswizzle( + struct tgsi_src_register_ext_swz *reg, + unsigned swizzle, + unsigned component ); + +unsigned +tgsi_util_get_src_register_extnegate( + const struct tgsi_src_register_ext_swz *reg, + unsigned component ); + +void +tgsi_util_set_src_register_extnegate( + struct tgsi_src_register_ext_swz *reg, + unsigned negate, + unsigned component ); + +#define TGSI_UTIL_SIGN_CLEAR 0 /* Force positive */ +#define TGSI_UTIL_SIGN_SET 1 /* Force negative */ +#define TGSI_UTIL_SIGN_TOGGLE 2 /* Negate */ +#define TGSI_UTIL_SIGN_KEEP 3 /* No change */ + +unsigned +tgsi_util_get_full_src_register_sign_mode( + const struct tgsi_full_src_register *reg, + unsigned component ); + +void +tgsi_util_set_full_src_register_sign_mode( + struct tgsi_full_src_register *reg, + unsigned sign_mode ); + +#if defined __cplusplus +} // extern "C" +#endif // defined __cplusplus + +#endif // !defined TGSI_UTIL_H + diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c new file mode 100644 index 0000000000..b9607a6ba7 --- /dev/null +++ b/src/gallium/auxiliary/util/p_debug.c @@ -0,0 +1,76 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include + +#ifdef WIN32 +#include +#include +#else +#include +#include +#endif + +#include "pipe/p_debug.h" +#include "pipe/p_compiler.h" + + +void debug_vprintf(const char *format, va_list ap) +{ +#ifdef WIN32 + EngDebugPrint("Gallium3D: ", (PCHAR)format, ap); +#else + vfprintf(stderr, format, ap); +#endif +} + + +void debug_printf(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + debug_vprintf(format, ap); + va_end(ap); +} + + +static INLINE void debug_abort(void) +{ +#ifdef WIN32 + EngDebugBreak(); +#else + abort(); +#endif +} + + +void debug_assert_fail(const char *expr, const char *file, unsigned line) +{ + debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr); + debug_abort(); +} diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c new file mode 100644 index 0000000000..3f795a3898 --- /dev/null +++ b/src/gallium/auxiliary/util/p_tile.c @@ -0,0 +1,699 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * RGBA/float tile get/put functions. + * Usable both by drivers and state trackers. + * Surfaces should already be in a mapped state. + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "p_tile.h" + + + +/** + * Move raw block of pixels from surface to user memory. + * This should be usable by any hw driver that has mappable surfaces. + */ +void +pipe_get_tile_raw(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + void *p, int dst_stride) +{ + const uint cpp = ps->cpp; + const ubyte *pSrc; + const uint src_stride = ps->pitch * cpp; + ubyte *pDest; + uint i; + + if (dst_stride == 0) { + dst_stride = w * cpp; + } + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + pSrc = (const ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; + pDest = (ubyte *) p; + + for (i = 0; i < h; i++) { + memcpy(pDest, pSrc, w * cpp); + pDest += dst_stride; + pSrc += src_stride; + } + + pipe_surface_unmap(ps); +} + + +/** + * Move raw block of pixels from user memory to surface. + * This should be usable by any hw driver that has mappable surfaces. + */ +void +pipe_put_tile_raw(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const void *p, int src_stride) +{ + const uint cpp = ps->cpp; + const ubyte *pSrc; + const uint dst_stride = ps->pitch * cpp; + ubyte *pDest; + uint i; + + if (src_stride == 0) { + src_stride = w * cpp; + } + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + pSrc = (const ubyte *) p; + pDest = (ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; + + for (i = 0; i < h; i++) { + memcpy(pDest, pSrc, w * cpp); + pDest += dst_stride; + pSrc += src_stride; + } + + pipe_surface_unmap(ps); +} + + + + +/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */ +#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) + +#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \ + us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) + + + +/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ + +static void +a8r8g8b8_get_tile_rgba(unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const unsigned pixel = *src++; + pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); + pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); + pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); + pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); + } + p += dst_stride; + } +} + + +static void +a8r8g8b8_put_tile_rgba(unsigned *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b, a; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + *dst++ = (a << 24) | (r << 16) | (g << 8) | b; + } + p += src_stride; + } +} + + +/*** PIPE_FORMAT_B8G8R8A8_UNORM ***/ + +static void +b8g8r8a8_get_tile_rgba(unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const unsigned pixel = *src++; + pRow[0] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); + pRow[1] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); + pRow[2] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); + pRow[3] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); + } + p += dst_stride; + } +} + + +static void +b8g8r8a8_put_tile_rgba(unsigned *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b, a; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + *dst++ = (b << 24) | (g << 16) | (r << 8) | a; + } + p += src_stride; + } +} + + +/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/ + +static void +a1r5g5b5_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const ushort pixel = *src++; + pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f); + pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f); + pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); + pRow[3] = ((pixel >> 15) ) * 1.0f; + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_A4R4G4B4_UNORM ***/ + +static void +a4r4g4b4_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const ushort pixel = *src++; + pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f); + pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f); + pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f); + pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_R5G6B5_UNORM ***/ + +static void +r5g6b5_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const ushort pixel = *src++; + pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f); + pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f); + pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); + pRow[3] = 1.0f; + } + p += dst_stride; + } +} + + +static void +r5g5b5_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0); + uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0); + uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0); + *dst++ = (r << 11) | (g << 5) | (b); + } + p += src_stride; + } +} + + + +/*** PIPE_FORMAT_Z16_UNORM ***/ + +/** + * Return each Z value as four floats in [0,1]. + */ +static void +z16_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const float scale = 1.0f / 65535.0f; + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = *src++ * scale; + } + p += dst_stride; + } +} + + + + +/*** PIPE_FORMAT_U_L8 ***/ + +static void +l8_get_tile_rgba(ubyte *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = UBYTE_TO_FLOAT(*src); + pRow[3] = 1.0; + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_U_A8 ***/ + +static void +a8_get_tile_rgba(ubyte *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = 0.0; + pRow[3] = UBYTE_TO_FLOAT(*src); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ + +static void +r16g16b16a16_get_tile_rgba(short *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src += 4, pRow += 4) { + pRow[0] = SHORT_TO_FLOAT(src[0]); + pRow[1] = SHORT_TO_FLOAT(src[1]); + pRow[2] = SHORT_TO_FLOAT(src[2]); + pRow[3] = SHORT_TO_FLOAT(src[3]); + } + p += dst_stride; + } +} + + +static void +r16g16b16a16_put_tile_rgba(short *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, dst += 4, pRow += 4) { + UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); + UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]); + UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]); + UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]); + } + p += src_stride; + } +} + + + +/*** PIPE_FORMAT_U_I8 ***/ + +static void +i8_get_tile_rgba(ubyte *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = UBYTE_TO_FLOAT(*src); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_U_A8_L8 ***/ + +static void +a8_l8_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + ushort p = *src++; + pRow[0] = + pRow[1] = + pRow[2] = UBYTE_TO_FLOAT(p & 0xff); + pRow[3] = UBYTE_TO_FLOAT(p >> 8); + } + p += dst_stride; + } +} + + + + +/*** PIPE_FORMAT_Z32_UNORM ***/ + +/** + * Return each Z value as four floats in [0,1]. + */ +static void +z32_get_tile_rgba(unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const double scale = 1.0 / (double) 0xffffffff; + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = (float) (*src++ * scale); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_S8Z24_UNORM ***/ + +/** + * Return Z component as four float in [0,1]. Stencil part ignored. + */ +static void +s8z24_get_tile_rgba(unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const double scale = 1.0 / ((1 << 24) - 1); + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = (float) (scale * (*src++ & 0xffffff)); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_Z24S8_UNORM ***/ + +/** + * Return Z component as four float in [0,1]. Stencil part ignored. + */ +static void +z24s8_get_tile_rgba(unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const double scale = 1.0 / ((1 << 24) - 1); + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = (float) (scale * (*src++ >> 8)); + } + p += dst_stride; + } +} + + +void +pipe_get_tile_rgba(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + float *p) +{ + unsigned dst_stride = w * 4; + void *packed; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + packed = MALLOC(h * w * ps->cpp); + + if (!packed) + return; + + pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp); + + switch (ps->format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + a8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + b8g8r8a8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_A1R5G5B5_UNORM: + a1r5g5b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_A4R4G4B4_UNORM: + a4r4g4b4_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_R5G6B5_UNORM: + r5g6b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_U_L8: + l8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_U_A8: + a8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_U_I8: + i8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_U_A8_L8: + a8_l8_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_R16G16B16A16_SNORM: + r16g16b16a16_get_tile_rgba((short *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_Z16_UNORM: + z16_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_Z32_UNORM: + z32_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_S8Z24_UNORM: + s8z24_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + break; + case PIPE_FORMAT_Z24S8_UNORM: + z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + break; + default: + assert(0); + } + + FREE(packed); +} + + +void +pipe_put_tile_rgba(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const float *p) +{ + unsigned src_stride = w * 4; + void *packed; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + packed = MALLOC(h * w * ps->cpp); + + if (!packed) + return; + + switch (ps->format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_A1R5G5B5_UNORM: + /*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_R5G6B5_UNORM: + r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + break; + case PIPE_FORMAT_U_L8: + /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_U_A8: + /*a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_U_I8: + /*i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_U_A8_L8: + /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_R16G16B16A16_SNORM: + r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_Z16_UNORM: + /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_Z32_UNORM: + /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_S8Z24_UNORM: + /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_Z24S8_UNORM: + /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ + break; + default: + assert(0); + } + + pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp); + + FREE(packed); +} diff --git a/src/gallium/auxiliary/util/p_tile.h b/src/gallium/auxiliary/util/p_tile.h new file mode 100644 index 0000000000..cd8124bf11 --- /dev/null +++ b/src/gallium/auxiliary/util/p_tile.h @@ -0,0 +1,81 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef P_TILE_H +#define P_TILE_H + +#include "pipe/p_compiler.h" + +struct pipe_context; +struct pipe_surface; + + +/** + * Clip tile against surface dims. + * \return TRUE if tile is totally clipped, FALSE otherwise + */ +static INLINE boolean +pipe_clip_tile(uint x, uint y, uint *w, uint *h, const struct pipe_surface *ps) +{ + if (x >= ps->width) + return TRUE; + if (y >= ps->height) + return TRUE; + if (x + *w > ps->width) + *w = ps->width - x; + if (y + *h > ps->height) + *h = ps->height - y; + return FALSE; +} + + +extern void +pipe_get_tile_raw(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + void *p, int dst_stride); + +extern void +pipe_put_tile_raw(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const void *p, int src_stride); + + +extern void +pipe_get_tile_rgba(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + float *p); + +extern void +pipe_put_tile_rgba(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const float *p); + +#endif diff --git a/src/gallium/auxiliary/util/p_util.c b/src/gallium/auxiliary/util/p_util.c new file mode 100644 index 0000000000..2a92f8e408 --- /dev/null +++ b/src/gallium/auxiliary/util/p_util.c @@ -0,0 +1,73 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Miscellaneous utility functions. + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" + + +/** + * Copy 2D rect from one place to another. + * Position and sizes are in pixels. + */ +void +pipe_copy_rect(ubyte * dst, + unsigned cpp, + unsigned dst_pitch, + unsigned dst_x, + unsigned dst_y, + unsigned width, + unsigned height, + const ubyte * src, + int src_pitch, + unsigned src_x, + int src_y) +{ + unsigned i; + + dst_pitch *= cpp; + src_pitch *= cpp; + dst += dst_x * cpp; + src += src_x * cpp; + dst += dst_y * dst_pitch; + src += src_y * src_pitch; + width *= cpp; + + if (width == dst_pitch && width == src_pitch) + memcpy(dst, src, height * width); + else { + for (i = 0; i < height; i++) { + memcpy(dst, src, width); + dst += dst_pitch; + src += src_pitch; + } + } +} -- cgit v1.2.3 From 66f22aa3bf7fa546e946b45156aa578e202982c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Feb 2008 20:11:40 +0900 Subject: Code reorganization: s/aux/auxiliary/ -- update build. --- src/gallium/Makefile | 2 +- src/gallium/Makefile.template | 2 +- src/gallium/auxiliary/llvm/Makefile | 2 +- src/gallium/drivers/cell/ppu/Makefile | 2 +- src/gallium/drivers/cell/spu/Makefile | 2 +- src/gallium/winsys/dri/Makefile.template | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/Makefile b/src/gallium/Makefile index a13b9a52d3..89e068a449 100644 --- a/src/gallium/Makefile +++ b/src/gallium/Makefile @@ -2,7 +2,7 @@ TOP = ../.. include $(TOP)/configs/current -SUBDIRS = aux drivers +SUBDIRS = auxiliary drivers default: subdirs diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 0717ed8dd2..83b25f9b47 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -17,7 +17,7 @@ INCLUDES = \ -I. \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/include/pipe \ - -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/mesa \ -I$(TOP)/include \ diff --git a/src/gallium/auxiliary/llvm/Makefile b/src/gallium/auxiliary/llvm/Makefile index e6ac399d08..e0abf860c1 100644 --- a/src/gallium/auxiliary/llvm/Makefile +++ b/src/gallium/auxiliary/llvm/Makefile @@ -31,7 +31,7 @@ OBJECTS = $(C_SOURCES:.c=.o) \ INCLUDES = \ -I. \ -I$(TOP)/src/gallium/drivers - -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/mesa \ -I$(TOP)/include diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index 011863c11e..a4c3f29e8a 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -43,7 +43,7 @@ OBJECTS = $(SOURCES:.c=.o) \ INCLUDE_DIRS = \ -I$(TOP)/src/mesa \ -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers .c.o: diff --git a/src/gallium/drivers/cell/spu/Makefile b/src/gallium/drivers/cell/spu/Makefile index 7aa947299e..30ef2450ec 100644 --- a/src/gallium/drivers/cell/spu/Makefile +++ b/src/gallium/drivers/cell/spu/Makefile @@ -34,7 +34,7 @@ SPU_ASM_OUT = $(SOURCES:.c=.s) \ INCLUDE_DIRS = \ -I$(TOP)/src/mesa \ -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index b96305c094..2a261ed669 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -49,7 +49,7 @@ SHARED_INCLUDES = \ -I$(TOP)/include \ -I$(TOP)/include/GL/internal \ -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/aux \ + -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/main \ -- cgit v1.2.3 From e822e09b89407d6cb8cd4a79e1c5c1e0955caf64 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 15 Feb 2008 13:35:46 +0000 Subject: softpipe: rename some functions to disambiguate --- src/gallium/drivers/softpipe/sp_fs_sse.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 28c5d8c556..d90066e025 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -100,7 +100,7 @@ sp_setup_pos_vector(const struct tgsi_interp_coef *coef, static void -sse_prepare( struct sp_fragment_shader *base, +fs_sse_prepare( struct sp_fragment_shader *base, struct tgsi_exec_machine *machine, struct tgsi_sampler *samplers ) { @@ -113,7 +113,7 @@ sse_prepare( struct sp_fragment_shader *base, * TODO: process >1 quad at a time */ static unsigned -sse_run( struct sp_fragment_shader *base, +fs_sse_run( struct sp_fragment_shader *base, struct tgsi_exec_machine *machine, struct quad_header *quad ) { @@ -137,7 +137,7 @@ sse_run( struct sp_fragment_shader *base, static void -sse_delete( struct sp_fragment_shader *base ) +fs_sse_delete( struct sp_fragment_shader *base ) { struct sp_sse_fragment_shader *shader = (struct sp_sse_fragment_shader *) base; @@ -170,9 +170,9 @@ softpipe_create_fs_sse(struct softpipe_context *softpipe, assert(shader->func); shader->base.shader = *templ; - shader->base.prepare = sse_prepare; - shader->base.run = sse_run; - shader->base.delete = sse_delete; + shader->base.prepare = fs_sse_prepare; + shader->base.run = fs_sse_run; + shader->base.delete = fs_sse_delete; return &shader->base; } -- cgit v1.2.3 From b29d8d27292c2ad956d3f0a307603f00ee01af28 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 15 Feb 2008 13:37:01 +0000 Subject: draw: subclass vertex shaders according to execution method Create new files for shaders compiled/executed with llvm, sse, exec respectively --- src/gallium/auxiliary/draw/Makefile | 2 +- src/gallium/auxiliary/draw/draw_private.h | 40 ++-- src/gallium/auxiliary/draw/draw_vertex_shader.c | 229 ++------------------- src/gallium/auxiliary/draw/draw_vs.h | 50 +++++ src/gallium/auxiliary/draw/draw_vs_exec.c | 186 ++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_llvm.c | 237 ++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_sse.c | 251 ++++++++++++++++++++++++ 7 files changed, 763 insertions(+), 232 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_vs.h create mode 100644 src/gallium/auxiliary/draw/draw_vs_exec.c create mode 100644 src/gallium/auxiliary/draw/draw_vs_llvm.c create mode 100644 src/gallium/auxiliary/draw/draw_vs_sse.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 451911a354..fe9b150f30 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -1,2 +1,2 @@ default: - cd .. ; make + cd ../../../mesa ; make diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 3d09aef87c..bc11259cb2 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -128,13 +128,25 @@ struct draw_stage * Private version of the compiled vertex_shader */ struct draw_vertex_shader { + + /* This member will disappear shortly: + */ const struct pipe_shader_state *state; -#if defined(__i386__) || defined(__386__) - struct x86_function sse2_program; -#endif -#ifdef MESA_LLVM - struct gallivm_prog *llvm_prog; -#endif + + void (*prepare)( struct draw_vertex_shader *shader, + struct draw_context *draw ); + + /* Run the shader - this interface will get cleaned up in the + * future: + */ + void (*run)( struct draw_vertex_shader *shader, + struct draw_context *draw, + const unsigned *elts, + unsigned count, + struct vertex_header *vOut[] ); + + + void (*delete)( struct draw_vertex_shader * ); }; @@ -176,7 +188,7 @@ struct draw_context struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; - const struct draw_vertex_shader *vertex_shader; + struct draw_vertex_shader *vertex_shader; uint num_vs_outputs; /**< convenience, from vertex_shader */ @@ -201,6 +213,7 @@ struct draw_context boolean convert_wide_points; /**< convert wide points to tris? */ boolean convert_wide_lines; /**< convert side lines to tris? */ + boolean use_sse; unsigned reduced_prim; @@ -255,11 +268,10 @@ struct draw_context unsigned queue_nr; } pq; - int use_sse : 1; -#ifdef MESA_LLVM - struct gallivm_cpu_engine *engine; -#endif - + + /* This (and the tgsi_exec_machine struct) probably need to be moved somewhere private. + */ + struct gallivm_cpu_engine *engine; void *driver_private; }; @@ -290,11 +302,7 @@ extern void draw_vertex_cache_invalidate( struct draw_context *draw ); extern void draw_vertex_cache_unreference( struct draw_context *draw ); extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ); - extern void draw_vertex_shader_queue_flush( struct draw_context *draw ); -#ifdef MESA_LLVM -extern void draw_vertex_shader_queue_flush_llvm( struct draw_context *draw ); -#endif struct tgsi_exec_machine; diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index 9413f8b43a..f68f6e3244 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -33,177 +33,10 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#if defined(__i386__) || defined(__386__) -#include "tgsi/exec/tgsi_sse2.h" -#endif #include "draw_private.h" #include "draw_context.h" +#include "draw_vs.h" -#include "x86/rtasm/x86sse.h" -#include "llvm/gallivm.h" - - -#define DBG_VS 0 - - -static INLINE unsigned -compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) -{ - unsigned mask = 0; - unsigned i; - - /* Do the hardwired planes first: - */ - if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; - if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; - if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; - if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; - if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; - if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; - - /* Followed by any remaining ones: - */ - for (i = 6; i < nr; i++) { - if (dot4(clip, plane[i]) < 0) - mask |= (1<machine; - unsigned int j; - - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); - const float *scale = draw->viewport.scale; - const float *trans = draw->viewport.translate; - - assert(count <= 4); - assert(draw->vertex_shader->state->output_semantic_name[0] - == TGSI_SEMANTIC_POSITION); - - /* Consts does not require 16 byte alignment. */ - machine->Consts = (float (*)[4]) draw->user.constants; - - machine->Inputs = ALIGN16_ASSIGN(inputs); - machine->Outputs = ALIGN16_ASSIGN(outputs); - - draw->vertex_fetch.fetch_func( draw, machine, elts, count ); - - /* run shader */ -#ifdef MESA_LLVM - if (1) { - struct gallivm_prog *prog = draw->vertex_shader->llvm_prog; - gallivm_cpu_vs_exec(prog, - machine->Inputs, - machine->Outputs, - machine->Consts, - machine->Temps); - } else -#elif defined(__i386__) || defined(__386__) - if (draw->use_sse) { - /* SSE */ - /* cast away const */ - struct draw_vertex_shader *shader - = (struct draw_vertex_shader *)draw->vertex_shader; - codegen_function func - = (codegen_function) x86_get_func( &shader->sse2_program ); - - if (func) - func( - machine->Inputs, - machine->Outputs, - machine->Consts, - machine->Temps ); - else - /* interpreter */ - tgsi_exec_machine_run( machine ); - } - else -#endif - { - /* interpreter */ - tgsi_exec_machine_run( machine ); - } - - /* store machine results */ - for (j = 0; j < count; j++) { - unsigned slot; - float x, y, z, w; - - /* Handle attr[0] (position) specially: - * - * XXX: Computing the clipmask should be done in the vertex - * program as a set of DP4 instructions appended to the - * user-provided code. - */ - x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; - - vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); - vOut[j]->edgeflag = 1; - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - - /* Viewport mapping */ - vOut[j]->data[0][0] = x * scale[0] + trans[0]; - vOut[j]->data[0][1] = y * scale[1] + trans[1]; - vOut[j]->data[0][2] = z * scale[2] + trans[2]; - vOut[j]->data[0][3] = w; - -#if DBG_VS - debug_printf("output[%d]win: %f %f %f %f\n", j, - vOut[j]->data[0][0], - vOut[j]->data[0][1], - vOut[j]->data[0][2], - vOut[j]->data[0][3]); -#endif - /* Remaining attributes are packed into sequential post-transform - * vertex attrib slots. - */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; -#if DBG_VS - debug_printf("output[%d][%d]: %f %f %f %f\n", j, slot, - vOut[j]->data[slot][0], - vOut[j]->data[slot][1], - vOut[j]->data[slot][2], - vOut[j]->data[slot][3]); -#endif - } - } /* loop over vertices */ -} /** @@ -213,13 +46,14 @@ run_vertex_program(struct draw_context *draw, void draw_vertex_shader_queue_flush(struct draw_context *draw) { + struct draw_vertex_shader *shader = draw->vertex_shader; unsigned i; assert(draw->vs.queue_nr != 0); /* XXX: do this on statechange: */ - draw_update_vertex_fetch( draw ); + shader->prepare( shader, draw ); // fprintf(stderr, " q(%d) ", draw->vs.queue_nr ); @@ -242,7 +76,7 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) assert(n > 0); assert(n <= 4); - run_vertex_program(draw, elts, n, dests); + shader->run(shader, draw, elts, n, dests); } draw->vs.queue_nr = 0; @@ -255,43 +89,16 @@ draw_create_vertex_shader(struct draw_context *draw, { struct draw_vertex_shader *vs; - vs = CALLOC_STRUCT( draw_vertex_shader ); - if (vs == NULL) { - return NULL; - } - - vs->state = shader; + vs = draw_create_vs_llvm( draw, shader ); + if (vs) + return vs; -#ifdef MESA_LLVM - struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); - gallivm_ir_set_layout(ir, GALLIVM_SOA); - gallivm_ir_set_components(ir, 4); - gallivm_ir_fill_from_tgsi(ir, shader->tokens); - vs->llvm_prog = gallivm_ir_compile(ir); - gallivm_ir_delete(ir); - - draw->engine = gallivm_global_cpu_engine(); - if (!draw->engine) { - draw->engine = gallivm_cpu_engine_create(vs->llvm_prog); - } - else { - gallivm_cpu_jit_compile(draw->engine, vs->llvm_prog); - } -#elif defined(__i386__) || defined(__386__) - if (draw->use_sse) { - /* cast-away const */ - struct pipe_shader_state *sh = (struct pipe_shader_state *) shader; - - x86_init_func( &vs->sse2_program ); - if (!tgsi_emit_sse2( (struct tgsi_token *) sh->tokens, - &vs->sse2_program )) { - x86_release_func( (struct x86_function *) &vs->sse2_program ); - fprintf(stdout /*err*/, - "tgsi_emit_sse2() failed, falling back to interpreter\n"); - } - } -#endif + vs = draw_create_vs_sse( draw, shader ); + if (vs) + return vs; + vs = draw_create_vs_exec( draw, shader ); + assert(vs); return vs; } @@ -307,11 +114,7 @@ draw_bind_vertex_shader(struct draw_context *draw, tgsi_exec_machine_init(&draw->machine); - /* specify the vertex program to interpret/execute */ - tgsi_exec_machine_bind_shader(&draw->machine, - draw->vertex_shader->state->tokens, - PIPE_MAX_SAMPLERS, - NULL /*samplers*/ ); + dvs->prepare( dvs, draw ); } @@ -319,9 +122,5 @@ void draw_delete_vertex_shader(struct draw_context *draw, struct draw_vertex_shader *dvs) { -#if defined(__i386__) || defined(__386__) - x86_release_func( (struct x86_function *) &dvs->sse2_program ); -#endif - - FREE( dvs ); + dvs->delete( dvs ); } diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h new file mode 100644 index 0000000000..4ee7e705e9 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -0,0 +1,50 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef DRAW_VS_H +#define DRAW_VS_H + +struct draw_vertex_shader; +struct draw_context; +struct pipe_shader_state; + +struct draw_vertex_shader * +draw_create_vs_exec(struct draw_context *draw, + const struct pipe_shader_state *templ); + +struct draw_vertex_shader * +draw_create_vs_sse(struct draw_context *draw, + const struct pipe_shader_state *templ); + +struct draw_vertex_shader * +draw_create_vs_llvm(struct draw_context *draw, + const struct pipe_shader_state *templ); + +#endif diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c new file mode 100644 index 0000000000..8588879400 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -0,0 +1,186 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + * Brian Paul + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#include "draw_private.h" +#include "draw_context.h" +#include "draw_vs.h" + + +static INLINE unsigned +compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) +{ + unsigned mask = 0; + unsigned i; + + /* Do the hardwired planes first: + */ + if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; + if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; + if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; + if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; + if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; + if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; + + /* Followed by any remaining ones: + */ + for (i = 6; i < nr; i++) { + if (dot4(clip, plane[i]) < 0) + mask |= (1<machine, + shader->state->tokens, + PIPE_MAX_SAMPLERS, + NULL /*samplers*/ ); + + draw_update_vertex_fetch( draw ); +} + + +/** + * Transform vertices with the current vertex program/shader + * Up to four vertices can be shaded at a time. + * \param vbuffer the input vertex data + * \param elts indexes of four input vertices + * \param count number of vertices to shade [1..4] + * \param vOut array of pointers to four output vertices + */ +static void +vs_exec_run( struct draw_vertex_shader *shader, + struct draw_context *draw, + const unsigned *elts, + unsigned count, + struct vertex_header *vOut[] ) +{ + struct tgsi_exec_machine *machine = &draw->machine; + unsigned int j; + + ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); + ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); + const float *scale = draw->viewport.scale; + const float *trans = draw->viewport.translate; + + assert(count <= 4); + assert(draw->vertex_shader->state->output_semantic_name[0] + == TGSI_SEMANTIC_POSITION); + + machine->Consts = (float (*)[4]) draw->user.constants; + machine->Inputs = ALIGN16_ASSIGN(inputs); + machine->Outputs = ALIGN16_ASSIGN(outputs); + + draw->vertex_fetch.fetch_func( draw, machine, elts, count ); + + /* run interpreter */ + tgsi_exec_machine_run( machine ); + + + /* store machine results */ + for (j = 0; j < count; j++) { + unsigned slot; + float x, y, z, w; + + /* Handle attr[0] (position) specially: + * + * XXX: Computing the clipmask should be done in the vertex + * program as a set of DP4 instructions appended to the + * user-provided code. + */ + x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + + vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + vOut[j]->edgeflag = 1; + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; + + /* Viewport mapping */ + vOut[j]->data[0][0] = x * scale[0] + trans[0]; + vOut[j]->data[0][1] = y * scale[1] + trans[1]; + vOut[j]->data[0][2] = z * scale[2] + trans[2]; + vOut[j]->data[0][3] = w; + + /* Remaining attributes are packed into sequential post-transform + * vertex attrib slots. + */ + for (slot = 1; slot < draw->num_vs_outputs; slot++) { + vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + } /* loop over vertices */ +} + + + +static void +vs_exec_delete( struct draw_vertex_shader *dvs ) +{ + FREE( dvs ); +} + + +struct draw_vertex_shader * +draw_create_vs_exec(struct draw_context *draw, + const struct pipe_shader_state *state) +{ + struct draw_vertex_shader *vs = CALLOC_STRUCT( draw_vertex_shader ); + + if (vs == NULL) + return NULL; + + vs->state = state; + vs->prepare = vs_exec_prepare; + vs->run = vs_exec_run; + vs->delete = vs_exec_delete; + + return vs; +} diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c new file mode 100644 index 0000000000..44022b6e07 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -0,0 +1,237 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin + * Keith Whitwell + * Brian Paul + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" +#include "draw_context.h" +#include "draw_vs.h" + +#ifdef MESA_LLVM + +#include "llvm/gallivm.h" + +struct draw_llvm_vertex_shader { + struct draw_vertex_shader base; + struct gallivm_prog *llvm_prog; +}; + + +static INLINE unsigned +compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) +{ + unsigned mask = 0; + unsigned i; + + /* Do the hardwired planes first: + */ + if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; + if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; + if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; + if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; + if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; + if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; + + /* Followed by any remaining ones: + */ + for (i = 6; i < nr; i++) { + if (dot4(clip, plane[i]) < 0) + mask |= (1<machine; + unsigned int j; + + ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); + ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); + const float *scale = draw->viewport.scale; + const float *trans = draw->viewport.translate; + + + assert(count <= 4); + assert(draw->vertex_shader->state->output_semantic_name[0] + == TGSI_SEMANTIC_POSITION); + + /* Consts does not require 16 byte alignment. */ + machine->Consts = (float (*)[4]) draw->user.constants; + + machine->Inputs = ALIGN16_ASSIGN(inputs); + machine->Outputs = ALIGN16_ASSIGN(outputs); + + draw->vertex_fetch.fetch_func( draw, machine, elts, count ); + + /* run shader */ + gallivm_cpu_vs_exec(shader->llvm_prog, + machine->Inputs, + machine->Outputs, + machine->Consts, + machine->Temps); + + /* store machine results */ + for (j = 0; j < count; j++) { + unsigned slot; + float x, y, z, w; + + x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + + vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + vOut[j]->edgeflag = 1; + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; + + /* Viewport mapping */ + vOut[j]->data[0][0] = x * scale[0] + trans[0]; + vOut[j]->data[0][1] = y * scale[1] + trans[1]; + vOut[j]->data[0][2] = z * scale[2] + trans[2]; + vOut[j]->data[0][3] = w; + + /* Remaining attributes are packed into sequential post-transform + * vertex attrib slots. + */ + for (slot = 1; slot < draw->num_vs_outputs; slot++) { + vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + } /* loop over vertices */ +} + +static void +vs_llvm_delete( struct draw_vertex_shader *base ) +{ + struct draw_llvm_vertex_shader *shader = + (struct draw_llvm_vertex_shader *)base; + + /* Do something to free compiled shader: + */ + + FREE( shader ); +} + + + + +struct draw_vertex_shader * +draw_create_vs_llvm(struct draw_context *draw, + const struct pipe_shader_state *templ) +{ + struct draw_llvm_vertex_shader *vs; + + vs = CALLOC_STRUCT( draw_llvm_vertex_shader ); + if (vs == NULL) + return NULL; + + vs->base.state = templ; + vs->base.prepare = vs_llvm_prepare; + vs->base.run = vs_llvm_run; + vs->base.delete = vs_llvm_delete; + + { + struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); + gallivm_ir_set_layout(ir, GALLIVM_SOA); + gallivm_ir_set_components(ir, 4); + gallivm_ir_fill_from_tgsi(ir, vs->base.state->tokens); + vs->llvm_prog = gallivm_ir_compile(ir); + gallivm_ir_delete(ir); + } + + draw->engine = gallivm_global_cpu_engine(); + + /* XXX: Why are there two versions of this? Shouldn't creating the + * engine be a separate operation to compiling a shader? + */ + if (!draw->engine) { + draw->engine = gallivm_cpu_engine_create(vs->llvm_prog); + } + else { + gallivm_cpu_jit_compile(draw->engine, vs->llvm_prog); + } + + return &vs->base; +} + + + + + +#else + +struct draw_vertex_shader * +draw_create_vs_llvm(struct draw_context *draw, + const struct pipe_shader_state *shader) +{ + return NULL; +} + +#endif diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c new file mode 100644 index 0000000000..04349cb404 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -0,0 +1,251 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + * Brian Paul + */ + +#include "draw_vs.h" + +#if defined(__i386__) || defined(__386__) + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#include "draw_private.h" +#include "draw_context.h" + +#include "x86/rtasm/x86sse.h" +#include "tgsi/exec/tgsi_sse2.h" + + +typedef void (XSTDCALL *codegen_function) ( + const struct tgsi_exec_vector *input, + struct tgsi_exec_vector *output, + float (*constant)[4], + struct tgsi_exec_vector *temporary ); + + +struct draw_sse_vertex_shader { + struct draw_vertex_shader base; + struct x86_function sse2_program; + codegen_function func; +}; + + +/* Should be part of the generated shader: + */ +static INLINE unsigned +compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) +{ + unsigned mask = 0; + unsigned i; + + /* Do the hardwired planes first: + */ + if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; + if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; + if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; + if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; + if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; + if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; + + /* Followed by any remaining ones: + */ + for (i = 6; i < nr; i++) { + if (dot4(clip, plane[i]) < 0) + mask |= (1<machine; + unsigned int j; + + ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); + ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); + const float *scale = draw->viewport.scale; + const float *trans = draw->viewport.translate; + + assert(count <= 4); + assert(draw->vertex_shader->state->output_semantic_name[0] + == TGSI_SEMANTIC_POSITION); + + /* Consts does not require 16 byte alignment. */ + machine->Consts = (float (*)[4]) draw->user.constants; + machine->Inputs = ALIGN16_ASSIGN(inputs); + machine->Outputs = ALIGN16_ASSIGN(outputs); + + + /* Fetch vertices. This may at some point be integrated into the + * compiled shader -- that would require a reorganization where + * multiple versions of the compiled shader might exist, + * specialized for each fetch state. + */ + draw->vertex_fetch.fetch_func( draw, machine, elts, count ); + + + /* run compiled shader + */ + shader->func( + machine->Inputs, + machine->Outputs, + machine->Consts, + machine->Temps ); + + + /* XXX: Computing the clipmask and emitting results should be done + * in the vertex program as a set of instructions appended to + * the user-provided code. + */ + for (j = 0; j < count; j++) { + unsigned slot; + float x, y, z, w; + + x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + + vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + vOut[j]->edgeflag = 1; + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; + + /* Viewport mapping */ + vOut[j]->data[0][0] = x * scale[0] + trans[0]; + vOut[j]->data[0][1] = y * scale[1] + trans[1]; + vOut[j]->data[0][2] = z * scale[2] + trans[2]; + vOut[j]->data[0][3] = w; + + /* Remaining attributes are packed into sequential post-transform + * vertex attrib slots. + */ + for (slot = 1; slot < draw->num_vs_outputs; slot++) { + vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + } +} + + + +static void +vs_sse_delete( struct draw_vertex_shader *base ) +{ + struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; + + x86_release_func( &shader->sse2_program ); + + FREE( shader ); +} + + +struct draw_vertex_shader * +draw_create_vs_sse(struct draw_context *draw, + const struct pipe_shader_state *templ) +{ + struct draw_sse_vertex_shader *vs; + + if (!draw->use_sse) + return NULL; + + vs = CALLOC_STRUCT( draw_sse_vertex_shader ); + if (vs == NULL) + return NULL; + + vs->base.state = templ; + vs->base.prepare = vs_sse_prepare; + vs->base.run = vs_sse_run; + vs->base.delete = vs_sse_delete; + + x86_init_func( &vs->sse2_program ); + + if (!tgsi_emit_sse2( (struct tgsi_token *) vs->base.state->tokens, + &vs->sse2_program )) + goto fail; + + vs->func = (codegen_function) x86_get_func( &vs->sse2_program ); + + return &vs->base; + +fail: + fprintf(stderr, "tgsi_emit_sse2() failed, falling back to interpreter\n"); + + x86_release_func( &vs->sse2_program ); + + FREE(vs); + return NULL; +} + + + +#else + +struct draw_vertex_shader * +draw_create_vs_sse( struct draw_context *draw, + const struct pipe_shader_state *templ ) +{ + return NULL; +} + + +#endif + -- cgit v1.2.3 From c179bc990108a8ea691ceab03fd68a12396ab538 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 15 Feb 2008 13:39:24 +0000 Subject: tgsi: pass through failure to sse-codegenerate for fragment programs too. In particular, will fallback to interpreted execution for shaders with TEX instructions. --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 79209575bc..62c6a69c63 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -2308,6 +2308,7 @@ tgsi_emit_sse2_fs( { struct tgsi_parse_context parse; boolean instruction_phase = FALSE; + unsigned ok = 1; DUMP_START(); @@ -2333,7 +2334,7 @@ tgsi_emit_sse2_fs( tgsi_parse_init( &parse, tokens ); - while( !tgsi_parse_end_of_tokens( &parse ) ) { + while( !tgsi_parse_end_of_tokens( &parse ) && ok ) { tgsi_parse_token( &parse ); switch( parse.FullToken.Token.Type ) { @@ -2352,17 +2353,18 @@ tgsi_emit_sse2_fs( get_output_base(), get_argument( 1 ) ); } - emit_instruction( + ok = emit_instruction( func, &parse.FullToken.FullInstruction ); break; case TGSI_TOKEN_TYPE_IMMEDIATE: /* XXX implement this */ - assert(0); + ok = 0; break; default: + ok = 0; assert( 0 ); } } @@ -2371,7 +2373,7 @@ tgsi_emit_sse2_fs( DUMP_END(); - return 1; + return ok; } #endif /* i386 */ -- cgit v1.2.3 From 397b81bd1c7984b1667af7ef954e053263a7a661 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 15 Feb 2008 09:43:13 -0800 Subject: Move cell_vertex_fetch.c for recent code reorg. --- src/gallium/drivers/cell/ppu/cell_vertex_fetch.c | 392 +++++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 src/gallium/drivers/cell/ppu/cell_vertex_fetch.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c new file mode 100644 index 0000000000..f2432f4ff5 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c @@ -0,0 +1,392 @@ +/* + * (C) Copyright IBM Corporation 2008 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/p_format.h" + +#include "pipe/draw/draw_context.h" +#include "pipe/draw/draw_private.h" + +#include "pipe/cell/ppu/cell_context.h" +#include "ppc/rtasm/spe_asm.h" + +typedef uint64_t register_mask; + +int allocate_available_register(register_mask *m) +{ + unsigned i; + for (i = 0; i < 64; i++) { + const uint64_t mask = (1ULL << i); + + if ((m[0] & mask) != 0) { + m[0] &= ~mask; + return i; + } + } + + return -1; +} + + +int allocate_register(register_mask *m, unsigned reg) +{ + assert((m[0] & (1ULL << reg)) != 0); + + m[0] &= ~(1ULL << reg); + return reg; +} + + +void release_register(register_mask *m, unsigned reg) +{ + assert((m[0] & (1ULL << reg)) == 0); + + m[0] |= (1ULL << reg); +} + + +/** + * Emit a 4x4 matrix transpose operation + * + * \param p Function that the transpose operation is to be appended to + * \param m Live register mask + * \param row0 Register containing row 0 of the source matrix + * \param row1 Register containing row 1 of the source matrix + * \param row2 Register containing row 2 of the source matrix + * \param row3 Register containing row 3 of the source matrix + * \param dest_ptr Register containing the address of the destination matrix + * \param shuf_ptr Register containing the address of the shuffled data + * \param count Number of colums to actually be written to the destination + * + * \note + * This function assumes that the registers named by \c row0, \c row1, + * \c row2, and \c row3 are scratch and can be modified by the generated code. + * Furthermore, these registers will be released, via calls to + * \c release_register, by this function. + * + * \note + * This function requires that four temporary are available on entry. + */ +static void +emit_matrix_transpose(struct spe_function *p, register_mask *m, + unsigned row0, unsigned row1, unsigned row2, + unsigned row3, unsigned dest_ptr, + unsigned shuf_ptr, unsigned count) +{ + int shuf_hi = allocate_available_register(m); + int shuf_lo = allocate_available_register(m); + int t1 = allocate_available_register(m); + int t2 = allocate_available_register(m); + int t3; + int t4; + int col0; + int col1; + int col2; + int col3; + + + spe_lqd(p, shuf_hi, shuf_ptr, 3); + spe_lqd(p, shuf_lo, shuf_ptr, 4); + spe_shufb(p, t1, row0, row2, shuf_hi); + spe_shufb(p, t2, row0, row2, shuf_lo); + + + /* row0 and row2 are now no longer needed. Re-use those registers as + * temporaries. + */ + t3 = row0; + t4 = row2; + + spe_shufb(p, t3, row1, row3, shuf_hi); + spe_shufb(p, t4, row1, row3, shuf_lo); + + + /* row1 and row3 are now no longer needed. Re-use those registers as + * temporaries. + */ + col0 = row1; + col1 = row3; + + spe_shufb(p, col0, t1, t3, shuf_hi); + if (count > 1) { + spe_shufb(p, col1, t1, t3, shuf_lo); + } + + /* t1 and t3 are now no longer needed. Re-use those registers as + * temporaries. + */ + col2 = t1; + col3 = t3; + + if (count > 2) { + spe_shufb(p, col2, t2, t4, shuf_hi); + } + + if (count > 3) { + spe_shufb(p, col3, t2, t4, shuf_lo); + } + + + /* Store the results. Remember that the stqd instruction is encoded using + * the qword offset (stand-alone assemblers to the byte-offset to + * qword-offset conversion for you), so the byte-offset needs be divided by + * 16. + */ + switch (count) { + case 4: + spe_stqd(p, col3, dest_ptr, 3); + case 3: + spe_stqd(p, col2, dest_ptr, 2); + case 2: + spe_stqd(p, col1, dest_ptr, 1); + case 1: + spe_stqd(p, col0, dest_ptr, 0); + } + + + /* Release all of the temporary registers used. + */ + release_register(m, col0); + release_register(m, col1); + release_register(m, col2); + release_register(m, col3); + release_register(m, shuf_hi); + release_register(m, shuf_lo); + release_register(m, t2); + release_register(m, t4); +} + + +static void +emit_fetch(struct spe_function *p, register_mask *m, + unsigned in_ptr, unsigned *offset, + unsigned out_ptr, unsigned shuf_ptr, + enum pipe_format format) +{ + const unsigned count = (pf_size_x(format) != 0) + (pf_size_y(format) != 0) + + (pf_size_z(format) != 0) + (pf_size_w(format) != 0); + const unsigned type = pf_type(format); + const unsigned bytes = pf_size_x(format); + + int v0 = allocate_available_register(m); + int v1 = allocate_available_register(m); + int v2 = allocate_available_register(m); + int v3 = allocate_available_register(m); + int tmp = allocate_available_register(m); + int float_zero = -1; + int float_one = -1; + float scale_signed = 0.0; + float scale_unsigned = 0.0; + + spe_lqd(p, v0, in_ptr, 0 + offset[0]); + spe_lqd(p, v1, in_ptr, 1 + offset[0]); + spe_lqd(p, v2, in_ptr, 2 + offset[0]); + spe_lqd(p, v3, in_ptr, 3 + offset[0]); + offset[0] += 4; + + switch (bytes) { + case 1: + scale_signed = 1.0f / 127.0f; + scale_unsigned = 1.0f / 255.0f; + spe_lqd(p, tmp, shuf_ptr, 1); + spe_shufb(p, v0, v0, v0, tmp); + spe_shufb(p, v1, v1, v1, tmp); + spe_shufb(p, v2, v2, v2, tmp); + spe_shufb(p, v3, v3, v3, tmp); + break; + case 2: + scale_signed = 1.0f / 32767.0f; + scale_unsigned = 1.0f / 65535.0f; + spe_lqd(p, tmp, shuf_ptr, 2); + spe_shufb(p, v0, v0, v0, tmp); + spe_shufb(p, v1, v1, v1, tmp); + spe_shufb(p, v2, v2, v2, tmp); + spe_shufb(p, v3, v3, v3, tmp); + break; + case 4: + scale_signed = 1.0f / 2147483647.0f; + scale_unsigned = 1.0f / 4294967295.0f; + break; + default: + assert(0); + break; + } + + switch (type) { + case PIPE_FORMAT_TYPE_FLOAT: + break; + case PIPE_FORMAT_TYPE_UNORM: + spe_ilhu(p, tmp, ((unsigned) scale_unsigned) >> 16); + spe_iohl(p, tmp, ((unsigned) scale_unsigned) & 0x0ffff); + spe_cuflt(p, v0, v0, 0); + spe_fm(p, v0, v0, tmp); + break; + case PIPE_FORMAT_TYPE_SNORM: + spe_ilhu(p, tmp, ((unsigned) scale_signed) >> 16); + spe_iohl(p, tmp, ((unsigned) scale_signed) & 0x0ffff); + spe_csflt(p, v0, v0, 0); + spe_fm(p, v0, v0, tmp); + break; + case PIPE_FORMAT_TYPE_USCALED: + spe_cuflt(p, v0, v0, 0); + break; + case PIPE_FORMAT_TYPE_SSCALED: + spe_csflt(p, v0, v0, 0); + break; + } + + + if (count < 4) { + float_one = allocate_available_register(m); + spe_il(p, float_one, 1); + spe_cuflt(p, float_one, float_one, 0); + + if (count < 3) { + float_zero = allocate_available_register(m); + spe_il(p, float_zero, 0); + } + } + + release_register(m, tmp); + + emit_matrix_transpose(p, m, v0, v1, v2, v3, out_ptr, shuf_ptr, count); + + switch (count) { + case 1: + spe_stqd(p, float_zero, out_ptr, 1); + case 2: + spe_stqd(p, float_zero, out_ptr, 2); + case 3: + spe_stqd(p, float_one, out_ptr, 3); + } + + if (float_zero != -1) { + release_register(m, float_zero); + } + + if (float_one != -1) { + release_register(m, float_one); + } +} + + +void cell_update_vertex_fetch(struct draw_context *draw) +{ + struct cell_context *const cell = + (struct cell_context *) draw->driver_private; + register_mask m = ~0; + struct spe_function *p = &cell->attrib_fetch; + unsigned function_index[PIPE_ATTRIB_MAX]; + unsigned unique_attr_formats; + int out_ptr; + int in_ptr; + int shuf_ptr; + unsigned i; + unsigned j; + + + /* Determine how many unique input attribute formats there are. At the + * same time, store the index of the lowest numbered attribute that has + * the same format as any non-unique format. + */ + unique_attr_formats = 1; + function_index[0] = 0; + for (i = 1; i < draw->vertex_fetch.nr_attrs; i++) { + const enum pipe_format curr_fmt = draw->vertex_element[i].src_format; + + for (j = 0; j < i; j++) { + if (curr_fmt == draw->vertex_element[j].src_format) { + break; + } + } + + if (j == i) { + unique_attr_formats++; + } + + function_index[i] = j; + } + + + /* Each fetch function can be a maximum of 34 instructions (note: this is + * actually a slight over-estimate). That means (34 * 4) = 136 bytes + * each maximum. + */ + spe_init_func(p, 136 * unique_attr_formats); + + + /* Registers 0, 1, and 2 are reserved by the ABI. + */ + allocate_register(&m, 0); + allocate_register(&m, 1); + allocate_register(&m, 2); + + + /* Allocate registers for the function's input parameters. + */ + out_ptr = allocate_register(&m, 3); + in_ptr = allocate_register(&m, 4); + shuf_ptr = allocate_register(&m, 5); + + + /* Generate code for the individual attribute fetch functions. + */ + for (i = 0; i < draw->vertex_fetch.nr_attrs; i++) { + unsigned offset; + + if (function_index[i] == i) { + cell->attrib_fetch_offsets[i] = (unsigned) ((void *) p->csr + - (void *) p->store); + + offset = 0; + emit_fetch(p, & m, in_ptr, &offset, out_ptr, shuf_ptr, + draw->vertex_element[i].src_format); + spe_bi(p, 0, 0, 0); + + /* Round up to the next 16-byte boundary. + */ + if ((((unsigned) p->store) & 0x0f) != 0) { + const unsigned align = ((unsigned) p->store) & 0x0f; + p->store = (uint32_t *) (((void *) p->store) + align); + } + } else { + /* Use the same function entry-point as a previously seen attribute + * with the same format. + */ + cell->attrib_fetch_offsets[i] = + cell->attrib_fetch_offsets[function_index[i]]; + } + } + + static first_time = 1; + if (first_time) { + first_time = 0; + const unsigned instructions = p->csr - p->store; + for (i = 0; i < instructions; i++) { + printf("\t.long\t0x%08x\n", p->store[i]); + } + } +} -- cgit v1.2.3 From b08d3fa249c830d274dca362b8f824b75fe26945 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 15 Feb 2008 10:00:31 -0800 Subject: Make this file build on non-SSE builds (e.g., Cell) --- src/gallium/auxiliary/draw/draw_vs_sse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 04349cb404..27bc66812c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -243,7 +243,7 @@ struct draw_vertex_shader * draw_create_vs_sse( struct draw_context *draw, const struct pipe_shader_state *templ ) { - return NULL; + return (void *) 0; } -- cgit v1.2.3 From 3320b1874e810583f95b93a89697b2955987b84f Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 15 Feb 2008 11:03:54 -0800 Subject: Cell: Enable code gen for SPE attribute fetch Doubles are still unsupported. --- src/gallium/drivers/cell/common.h | 15 +- src/gallium/drivers/cell/ppu/Makefile | 1 + src/gallium/drivers/cell/ppu/cell_context.h | 4 + src/gallium/drivers/cell/ppu/cell_vertex_fetch.c | 15 +- src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 21 +- src/gallium/drivers/cell/spu/spu_main.c | 22 +- src/gallium/drivers/cell/spu/spu_vertex_fetch.c | 477 +--------------------- src/gallium/drivers/cell/spu/spu_vertex_shader.h | 6 +- 8 files changed, 71 insertions(+), 490 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index 4de514c358..74b131fbef 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -90,6 +90,7 @@ #define CELL_CMD_STATE_VS_ARRAY_INFO 16 #define CELL_CMD_STATE_BLEND 17 #define CELL_CMD_VS_EXECUTE 18 +#define CELL_CMD_STATE_ATTRIB_FETCH 19 #define CELL_NUM_BUFFERS 4 @@ -128,13 +129,19 @@ struct cell_command_clear_surface */ struct cell_array_info { - uint64_t base; /**< Base address of the 0th element. */ - uint attr; /**< Attribute that this state is for. */ - uint pitch; /**< Byte pitch from one entry to the next. */ - uint format; /**< Pipe format of each entry. */ + uint64_t base; /**< Base address of the 0th element. */ + uint attr; /**< Attribute that this state is for. */ + uint pitch; /**< Byte pitch from one entry to the next. */ + uint size; + uint function_offset; } ALIGN16_ATTRIB; +struct cell_attribute_fetch_code { + uint64_t base; + uint size; +}; + struct cell_shader_info { unsigned num_outputs; diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index a4c3f29e8a..196ab777f5 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -34,6 +34,7 @@ SOURCES = \ cell_surface.c \ cell_texture.c \ cell_vbuf.c \ + cell_vertex_fetch.c \ cell_vertex_shader.c \ cell_winsys.c diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 6196c0c72f..91f8e542a2 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -36,6 +36,7 @@ #include "draw/draw_vbuf.h" #include "cell_winsys.h" #include "cell/common.h" +#include "ppc/rtasm/spe_asm.h" struct cell_vbuf_render; @@ -111,6 +112,9 @@ struct cell_context /** [4] to ensure 16-byte alignment for each status word */ uint buffer_status[CELL_MAX_SPUS][CELL_NUM_BUFFERS][4] ALIGN16_ATTRIB; + + struct spe_function attrib_fetch; + unsigned attrib_fetch_offsets[PIPE_ATTRIB_MAX]; }; diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c index f2432f4ff5..f10689a959 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c @@ -27,10 +27,10 @@ #include "pipe/p_context.h" #include "pipe/p_format.h" -#include "pipe/draw/draw_context.h" -#include "pipe/draw/draw_private.h" +#include "../auxiliary/draw/draw_context.h" +#include "../auxiliary/draw/draw_private.h" -#include "pipe/cell/ppu/cell_context.h" +#include "cell_context.h" #include "ppc/rtasm/spe_asm.h" typedef uint64_t register_mask; @@ -380,13 +380,4 @@ void cell_update_vertex_fetch(struct draw_context *draw) cell->attrib_fetch_offsets[function_index[i]]; } } - - static first_time = 1; - if (first_time) { - first_time = 0; - const unsigned instructions = p->csr - p->store; - for (i = 0; i < instructions; i++) { - printf("\t.long\t0x%08x\n", p->store[i]); - } - } } diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index 0ba4506505..6a1d3bc20a 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -55,14 +55,32 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) uint64_t *batch; struct cell_array_info *array_info; unsigned i, j; + struct cell_attribute_fetch_code *cf; assert(draw->vs.queue_nr != 0); /* XXX: do this on statechange: */ draw_update_vertex_fetch(draw); + cell_update_vertex_fetch(draw); + + + batch = cell_batch_alloc(cell, sizeof(batch[0]) + sizeof(*cf)); + batch[0] = CELL_CMD_STATE_ATTRIB_FETCH; + cf = (struct cell_attribute_fetch_code *) (&batch[1]); + cf->base = cell->attrib_fetch.store; + cf->size = ROUNDUP16((unsigned)((void *) cell->attrib_fetch.csr + - (void *) cell->attrib_fetch.store)); + for (i = 0; i < draw->vertex_fetch.nr_attrs; i++) { + const enum pipe_format format = draw->vertex_element[i].src_format; + const unsigned count = ((pf_size_x(format) != 0) + + (pf_size_y(format) != 0) + + (pf_size_z(format) != 0) + + (pf_size_w(format) != 0)); + const unsigned size = pf_size_x(format) * count; + batch = cell_batch_alloc(cell, sizeof(batch[0]) + sizeof(*array_info)); batch[0] = CELL_CMD_STATE_VS_ARRAY_INFO; @@ -72,7 +90,8 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) array_info->base = (uintptr_t) draw->vertex_fetch.src_ptr[i]; array_info->attr = i; array_info->pitch = draw->vertex_fetch.pitch[i]; - array_info->format = draw->vertex_element[i].src_format; + array_info->size = size; + array_info->function_offset = cell->attrib_fetch_offsets[i]; } batch = cell_batch_alloc(cell, sizeof(batch[0]) diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 1e7243b863..fcbf0f841e 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -54,6 +54,9 @@ struct spu_global spu; struct spu_vs_context draw; +static unsigned char attribute_fetch_code_buffer[136 * PIPE_ATTRIB_MAX] + ALIGN16_ATTRIB; + /** * Tell the PPU that this SPU has finished copying a buffer to * local store and that it may be reused by the PPU. @@ -306,7 +309,8 @@ cmd_state_vs_array_info(const struct cell_array_info *vs_info) ASSERT(attr < PIPE_ATTRIB_MAX); draw.vertex_fetch.src_ptr[attr] = vs_info->base; draw.vertex_fetch.pitch[attr] = vs_info->pitch; - draw.vertex_fetch.format[attr] = vs_info->format; + draw.vertex_fetch.size[attr] = vs_info->size; + draw.vertex_fetch.code_offset[attr] = vs_info->function_offset; draw.vertex_fetch.dirty = 1; } @@ -433,6 +437,22 @@ cmd_batch(uint opcode) cmd_state_vs_array_info((struct cell_array_info *) &buffer[pos+1]); pos += (1 + ROUNDUP8(sizeof(struct cell_array_info)) / 8); break; + case CELL_CMD_STATE_ATTRIB_FETCH: { + struct cell_attribute_fetch_code *code = + (struct cell_attribute_fetch_code *) &buffer[pos+1]; + + mfc_get(attribute_fetch_code_buffer, + (unsigned int) code->base, /* src */ + code->size, + TAG_BATCH_BUFFER, + 0, /* tid */ + 0 /* rid */); + wait_on_mask(1 << TAG_BATCH_BUFFER); + + draw.vertex_fetch.code = attribute_fetch_code_buffer; + pos += (1 + ROUNDUP8(sizeof(struct cell_attribute_fetch_code)) / 8); + break; + } default: printf("SPU %u: bad opcode: 0x%llx\n", spu.init.id, buffer[pos]); ASSERT(0); diff --git a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c index 45e3c26c00..55c6c28717 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c @@ -1,6 +1,7 @@ /************************************************************************** * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * (C) Copyright IBM Corporation 2008 * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -28,10 +29,10 @@ /* * Authors: * Keith Whitwell + * Ian Romanick */ #include -#include #include "pipe/p_util.h" #include "pipe/p_state.h" @@ -59,6 +60,10 @@ #define DRAW_DBG 0 +typedef void (*spu_fetch_func)(qword *out, const qword *in, + const qword *shuffle_data); + + static const qword fetch_shuffle_data[] = { /* Shuffle used by CVT_64_FLOAT */ @@ -97,22 +102,6 @@ static const qword fetch_shuffle_data[] = { }; -static INLINE void -trans4x4(qword row0, qword row1, qword row2, qword row3, qword *out, - const qword *shuffle) -{ - qword t1 = si_shufb(row0, row2, shuffle[3]); - qword t2 = si_shufb(row0, row2, shuffle[4]); - qword t3 = si_shufb(row1, row3, shuffle[3]); - qword t4 = si_shufb(row1, row3, shuffle[4]); - - out[0] = si_shufb(t1, t3, shuffle[3]); - out[1] = si_shufb(t1, t3, shuffle[4]); - out[2] = si_shufb(t2, t4, shuffle[3]); - out[3] = si_shufb(t2, t4, shuffle[4]); -} - - /** * Fetch between 1 and 32 bytes from an unaligned address */ @@ -151,446 +140,6 @@ fetch_unaligned(qword *dst, unsigned ea, unsigned size) } -#define CVT_32_FLOAT(q, s) (*(q)) - -static INLINE qword -CVT_64_FLOAT(const qword *qw, const qword *shuffle) -{ - qword a = si_frds(qw[0]); - qword b = si_frds(si_rotqbyi(qw[0], 8)); - qword c = si_frds(qw[1]); - qword d = si_frds(si_rotqbyi(qw[1], 8)); - - qword ab = si_shufb(a, b, shuffle[0]); - qword cd = si_shufb(c, d, si_rotqbyi(shuffle[0], 8)); - - return si_or(ab, cd); -} - - -static INLINE qword -CVT_8_USCALED(const qword *qw, const qword *shuffle) -{ - return si_cuflt(si_shufb(*qw, *qw, shuffle[1]), 0); -} - - -static INLINE qword -CVT_16_USCALED(const qword *qw, const qword *shuffle) -{ - return si_cuflt(si_shufb(*qw, *qw, shuffle[2]), 0); -} - - -static INLINE qword -CVT_32_USCALED(const qword *qw, const qword *shuffle) -{ - (void) shuffle; - return si_cuflt(*qw, 0); -} - -static INLINE qword -CVT_8_SSCALED(const qword *qw, const qword *shuffle) -{ - return si_csflt(si_shufb(*qw, *qw, shuffle[1]), 0); -} - - -static INLINE qword -CVT_16_SSCALED(const qword *qw, const qword *shuffle) -{ - return si_csflt(si_shufb(*qw, *qw, shuffle[2]), 0); -} - - -static INLINE qword -CVT_32_SSCALED(const qword *qw, const qword *shuffle) -{ - (void) shuffle; - return si_csflt(*qw, 0); -} - - -static INLINE qword -CVT_8_UNORM(const qword *qw, const qword *shuffle) -{ - const qword scale = (qword) spu_splats(1.0f / 255.0f); - return si_fm(CVT_8_USCALED(qw, shuffle), scale); -} - - -static INLINE qword -CVT_16_UNORM(const qword *qw, const qword *shuffle) -{ - const qword scale = (qword) spu_splats(1.0f / 65535.0f); - return si_fm(CVT_16_USCALED(qw, shuffle), scale); -} - - -static INLINE qword -CVT_32_UNORM(const qword *qw, const qword *shuffle) -{ - const qword scale = (qword) spu_splats(1.0f / 4294967295.0f); - return si_fm(CVT_32_USCALED(qw, shuffle), scale); -} - - -static INLINE qword -CVT_8_SNORM(const qword *qw, const qword *shuffle) -{ - const qword scale = (qword) spu_splats(1.0f / 127.0f); - return si_fm(CVT_8_SSCALED(qw, shuffle), scale); -} - - -static INLINE qword -CVT_16_SNORM(const qword *qw, const qword *shuffle) -{ - const qword scale = (qword) spu_splats(1.0f / 32767.0f); - return si_fm(CVT_16_SSCALED(qw, shuffle), scale); -} - - -static INLINE qword -CVT_32_SNORM(const qword *qw, const qword *shuffle) -{ - const qword scale = (qword) spu_splats(1.0f / 2147483647.0f); - return si_fm(CVT_32_SSCALED(qw, shuffle), scale); -} - -#define SZ_4 si_il(0U) -#define SZ_3 si_fsmbi(0x000f) -#define SZ_2 si_fsmbi(0x00ff) -#define SZ_1 si_fsmbi(0x0fff) - -/** - * Fetch a float[4] vertex attribute from memory, doing format/type - * conversion as needed. - * - * This is probably needed/dupliocated elsewhere, eg format - * conversion, texture sampling etc. - */ -#define FETCH_ATTRIB( NAME, SZ, CVT, N ) \ -static void \ -fetch_##NAME(qword *out, const qword *in, qword defaults, \ - const qword *shuffle) \ -{ \ - qword tmp[4]; \ - \ - tmp[0] = si_selb(CVT(in + (0 * N), shuffle), defaults, SZ); \ - tmp[1] = si_selb(CVT(in + (1 * N), shuffle), defaults, SZ); \ - tmp[2] = si_selb(CVT(in + (2 * N), shuffle), defaults, SZ); \ - tmp[3] = si_selb(CVT(in + (3 * N), shuffle), defaults, SZ); \ - trans4x4(tmp[0], tmp[1], tmp[2], tmp[3], out, shuffle); \ -} - - -FETCH_ATTRIB( R64G64B64A64_FLOAT, SZ_4, CVT_64_FLOAT, 2 ) -FETCH_ATTRIB( R64G64B64_FLOAT, SZ_3, CVT_64_FLOAT, 2 ) -FETCH_ATTRIB( R64G64_FLOAT, SZ_2, CVT_64_FLOAT, 2 ) -FETCH_ATTRIB( R64_FLOAT, SZ_1, CVT_64_FLOAT, 2 ) - -FETCH_ATTRIB( R32G32B32A32_FLOAT, SZ_4, CVT_32_FLOAT, 1 ) -FETCH_ATTRIB( R32G32B32_FLOAT, SZ_3, CVT_32_FLOAT, 1 ) -FETCH_ATTRIB( R32G32_FLOAT, SZ_2, CVT_32_FLOAT, 1 ) -FETCH_ATTRIB( R32_FLOAT, SZ_1, CVT_32_FLOAT, 1 ) - -FETCH_ATTRIB( R32G32B32A32_USCALED, SZ_4, CVT_32_USCALED, 1 ) -FETCH_ATTRIB( R32G32B32_USCALED, SZ_3, CVT_32_USCALED, 1 ) -FETCH_ATTRIB( R32G32_USCALED, SZ_2, CVT_32_USCALED, 1 ) -FETCH_ATTRIB( R32_USCALED, SZ_1, CVT_32_USCALED, 1 ) - -FETCH_ATTRIB( R32G32B32A32_SSCALED, SZ_4, CVT_32_SSCALED, 1 ) -FETCH_ATTRIB( R32G32B32_SSCALED, SZ_3, CVT_32_SSCALED, 1 ) -FETCH_ATTRIB( R32G32_SSCALED, SZ_2, CVT_32_SSCALED, 1 ) -FETCH_ATTRIB( R32_SSCALED, SZ_1, CVT_32_SSCALED, 1 ) - -FETCH_ATTRIB( R32G32B32A32_UNORM, SZ_4, CVT_32_UNORM, 1 ) -FETCH_ATTRIB( R32G32B32_UNORM, SZ_3, CVT_32_UNORM, 1 ) -FETCH_ATTRIB( R32G32_UNORM, SZ_2, CVT_32_UNORM, 1 ) -FETCH_ATTRIB( R32_UNORM, SZ_1, CVT_32_UNORM, 1 ) - -FETCH_ATTRIB( R32G32B32A32_SNORM, SZ_4, CVT_32_SNORM, 1 ) -FETCH_ATTRIB( R32G32B32_SNORM, SZ_3, CVT_32_SNORM, 1 ) -FETCH_ATTRIB( R32G32_SNORM, SZ_2, CVT_32_SNORM, 1 ) -FETCH_ATTRIB( R32_SNORM, SZ_1, CVT_32_SNORM, 1 ) - -FETCH_ATTRIB( R16G16B16A16_USCALED, SZ_4, CVT_16_USCALED, 1 ) -FETCH_ATTRIB( R16G16B16_USCALED, SZ_3, CVT_16_USCALED, 1 ) -FETCH_ATTRIB( R16G16_USCALED, SZ_2, CVT_16_USCALED, 1 ) -FETCH_ATTRIB( R16_USCALED, SZ_1, CVT_16_USCALED, 1 ) - -FETCH_ATTRIB( R16G16B16A16_SSCALED, SZ_4, CVT_16_SSCALED, 1 ) -FETCH_ATTRIB( R16G16B16_SSCALED, SZ_3, CVT_16_SSCALED, 1 ) -FETCH_ATTRIB( R16G16_SSCALED, SZ_2, CVT_16_SSCALED, 1 ) -FETCH_ATTRIB( R16_SSCALED, SZ_1, CVT_16_SSCALED, 1 ) - -FETCH_ATTRIB( R16G16B16A16_UNORM, SZ_4, CVT_16_UNORM, 1 ) -FETCH_ATTRIB( R16G16B16_UNORM, SZ_3, CVT_16_UNORM, 1 ) -FETCH_ATTRIB( R16G16_UNORM, SZ_2, CVT_16_UNORM, 1 ) -FETCH_ATTRIB( R16_UNORM, SZ_1, CVT_16_UNORM, 1 ) - -FETCH_ATTRIB( R16G16B16A16_SNORM, SZ_4, CVT_16_SNORM, 1 ) -FETCH_ATTRIB( R16G16B16_SNORM, SZ_3, CVT_16_SNORM, 1 ) -FETCH_ATTRIB( R16G16_SNORM, SZ_2, CVT_16_SNORM, 1 ) -FETCH_ATTRIB( R16_SNORM, SZ_1, CVT_16_SNORM, 1 ) - -FETCH_ATTRIB( R8G8B8A8_USCALED, SZ_4, CVT_8_USCALED, 1 ) -FETCH_ATTRIB( R8G8B8_USCALED, SZ_3, CVT_8_USCALED, 1 ) -FETCH_ATTRIB( R8G8_USCALED, SZ_2, CVT_8_USCALED, 1 ) -FETCH_ATTRIB( R8_USCALED, SZ_1, CVT_8_USCALED, 1 ) - -FETCH_ATTRIB( R8G8B8A8_SSCALED, SZ_4, CVT_8_SSCALED, 1 ) -FETCH_ATTRIB( R8G8B8_SSCALED, SZ_3, CVT_8_SSCALED, 1 ) -FETCH_ATTRIB( R8G8_SSCALED, SZ_2, CVT_8_SSCALED, 1 ) -FETCH_ATTRIB( R8_SSCALED, SZ_1, CVT_8_SSCALED, 1 ) - -FETCH_ATTRIB( R8G8B8A8_UNORM, SZ_4, CVT_8_UNORM, 1 ) -FETCH_ATTRIB( R8G8B8_UNORM, SZ_3, CVT_8_UNORM, 1 ) -FETCH_ATTRIB( R8G8_UNORM, SZ_2, CVT_8_UNORM, 1 ) -FETCH_ATTRIB( R8_UNORM, SZ_1, CVT_8_UNORM, 1 ) - -FETCH_ATTRIB( R8G8B8A8_SNORM, SZ_4, CVT_8_SNORM, 1 ) -FETCH_ATTRIB( R8G8B8_SNORM, SZ_3, CVT_8_SNORM, 1 ) -FETCH_ATTRIB( R8G8_SNORM, SZ_2, CVT_8_SNORM, 1 ) -FETCH_ATTRIB( R8_SNORM, SZ_1, CVT_8_SNORM, 1 ) - -FETCH_ATTRIB( A8R8G8B8_UNORM, SZ_4, CVT_8_UNORM, 1 ) - - - -static spu_fetch_func get_fetch_func( enum pipe_format format ) -{ - switch (format) { - case PIPE_FORMAT_R64_FLOAT: - return fetch_R64_FLOAT; - case PIPE_FORMAT_R64G64_FLOAT: - return fetch_R64G64_FLOAT; - case PIPE_FORMAT_R64G64B64_FLOAT: - return fetch_R64G64B64_FLOAT; - case PIPE_FORMAT_R64G64B64A64_FLOAT: - return fetch_R64G64B64A64_FLOAT; - - case PIPE_FORMAT_R32_FLOAT: - return fetch_R32_FLOAT; - case PIPE_FORMAT_R32G32_FLOAT: - return fetch_R32G32_FLOAT; - case PIPE_FORMAT_R32G32B32_FLOAT: - return fetch_R32G32B32_FLOAT; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - return fetch_R32G32B32A32_FLOAT; - - case PIPE_FORMAT_R32_UNORM: - return fetch_R32_UNORM; - case PIPE_FORMAT_R32G32_UNORM: - return fetch_R32G32_UNORM; - case PIPE_FORMAT_R32G32B32_UNORM: - return fetch_R32G32B32_UNORM; - case PIPE_FORMAT_R32G32B32A32_UNORM: - return fetch_R32G32B32A32_UNORM; - - case PIPE_FORMAT_R32_USCALED: - return fetch_R32_USCALED; - case PIPE_FORMAT_R32G32_USCALED: - return fetch_R32G32_USCALED; - case PIPE_FORMAT_R32G32B32_USCALED: - return fetch_R32G32B32_USCALED; - case PIPE_FORMAT_R32G32B32A32_USCALED: - return fetch_R32G32B32A32_USCALED; - - case PIPE_FORMAT_R32_SNORM: - return fetch_R32_SNORM; - case PIPE_FORMAT_R32G32_SNORM: - return fetch_R32G32_SNORM; - case PIPE_FORMAT_R32G32B32_SNORM: - return fetch_R32G32B32_SNORM; - case PIPE_FORMAT_R32G32B32A32_SNORM: - return fetch_R32G32B32A32_SNORM; - - case PIPE_FORMAT_R32_SSCALED: - return fetch_R32_SSCALED; - case PIPE_FORMAT_R32G32_SSCALED: - return fetch_R32G32_SSCALED; - case PIPE_FORMAT_R32G32B32_SSCALED: - return fetch_R32G32B32_SSCALED; - case PIPE_FORMAT_R32G32B32A32_SSCALED: - return fetch_R32G32B32A32_SSCALED; - - case PIPE_FORMAT_R16_UNORM: - return fetch_R16_UNORM; - case PIPE_FORMAT_R16G16_UNORM: - return fetch_R16G16_UNORM; - case PIPE_FORMAT_R16G16B16_UNORM: - return fetch_R16G16B16_UNORM; - case PIPE_FORMAT_R16G16B16A16_UNORM: - return fetch_R16G16B16A16_UNORM; - - case PIPE_FORMAT_R16_USCALED: - return fetch_R16_USCALED; - case PIPE_FORMAT_R16G16_USCALED: - return fetch_R16G16_USCALED; - case PIPE_FORMAT_R16G16B16_USCALED: - return fetch_R16G16B16_USCALED; - case PIPE_FORMAT_R16G16B16A16_USCALED: - return fetch_R16G16B16A16_USCALED; - - case PIPE_FORMAT_R16_SNORM: - return fetch_R16_SNORM; - case PIPE_FORMAT_R16G16_SNORM: - return fetch_R16G16_SNORM; - case PIPE_FORMAT_R16G16B16_SNORM: - return fetch_R16G16B16_SNORM; - case PIPE_FORMAT_R16G16B16A16_SNORM: - return fetch_R16G16B16A16_SNORM; - - case PIPE_FORMAT_R16_SSCALED: - return fetch_R16_SSCALED; - case PIPE_FORMAT_R16G16_SSCALED: - return fetch_R16G16_SSCALED; - case PIPE_FORMAT_R16G16B16_SSCALED: - return fetch_R16G16B16_SSCALED; - case PIPE_FORMAT_R16G16B16A16_SSCALED: - return fetch_R16G16B16A16_SSCALED; - - case PIPE_FORMAT_R8_UNORM: - return fetch_R8_UNORM; - case PIPE_FORMAT_R8G8_UNORM: - return fetch_R8G8_UNORM; - case PIPE_FORMAT_R8G8B8_UNORM: - return fetch_R8G8B8_UNORM; - case PIPE_FORMAT_R8G8B8A8_UNORM: - return fetch_R8G8B8A8_UNORM; - - case PIPE_FORMAT_R8_USCALED: - return fetch_R8_USCALED; - case PIPE_FORMAT_R8G8_USCALED: - return fetch_R8G8_USCALED; - case PIPE_FORMAT_R8G8B8_USCALED: - return fetch_R8G8B8_USCALED; - case PIPE_FORMAT_R8G8B8A8_USCALED: - return fetch_R8G8B8A8_USCALED; - - case PIPE_FORMAT_R8_SNORM: - return fetch_R8_SNORM; - case PIPE_FORMAT_R8G8_SNORM: - return fetch_R8G8_SNORM; - case PIPE_FORMAT_R8G8B8_SNORM: - return fetch_R8G8B8_SNORM; - case PIPE_FORMAT_R8G8B8A8_SNORM: - return fetch_R8G8B8A8_SNORM; - - case PIPE_FORMAT_R8_SSCALED: - return fetch_R8_SSCALED; - case PIPE_FORMAT_R8G8_SSCALED: - return fetch_R8G8_SSCALED; - case PIPE_FORMAT_R8G8B8_SSCALED: - return fetch_R8G8B8_SSCALED; - case PIPE_FORMAT_R8G8B8A8_SSCALED: - return fetch_R8G8B8A8_SSCALED; - - case PIPE_FORMAT_A8R8G8B8_UNORM: - return fetch_A8R8G8B8_UNORM; - - case 0: - return NULL; /* not sure why this is needed */ - - default: - assert(0); - return NULL; - } -} - - -static unsigned get_vertex_size( enum pipe_format format ) -{ - switch (format) { - case PIPE_FORMAT_R64_FLOAT: - return 8; - case PIPE_FORMAT_R64G64_FLOAT: - return 2 * 8; - case PIPE_FORMAT_R64G64B64_FLOAT: - return 3 * 8; - case PIPE_FORMAT_R64G64B64A64_FLOAT: - return 4 * 8; - - case PIPE_FORMAT_R32_SSCALED: - case PIPE_FORMAT_R32_SNORM: - case PIPE_FORMAT_R32_USCALED: - case PIPE_FORMAT_R32_UNORM: - case PIPE_FORMAT_R32_FLOAT: - return 4; - case PIPE_FORMAT_R32G32_SSCALED: - case PIPE_FORMAT_R32G32_SNORM: - case PIPE_FORMAT_R32G32_USCALED: - case PIPE_FORMAT_R32G32_UNORM: - case PIPE_FORMAT_R32G32_FLOAT: - return 2 * 4; - case PIPE_FORMAT_R32G32B32_SSCALED: - case PIPE_FORMAT_R32G32B32_SNORM: - case PIPE_FORMAT_R32G32B32_USCALED: - case PIPE_FORMAT_R32G32B32_UNORM: - case PIPE_FORMAT_R32G32B32_FLOAT: - return 3 * 4; - case PIPE_FORMAT_R32G32B32A32_SSCALED: - case PIPE_FORMAT_R32G32B32A32_SNORM: - case PIPE_FORMAT_R32G32B32A32_USCALED: - case PIPE_FORMAT_R32G32B32A32_UNORM: - case PIPE_FORMAT_R32G32B32A32_FLOAT: - return 4 * 4; - - case PIPE_FORMAT_R16_SSCALED: - case PIPE_FORMAT_R16_SNORM: - case PIPE_FORMAT_R16_UNORM: - case PIPE_FORMAT_R16_USCALED: - return 2; - case PIPE_FORMAT_R16G16_SSCALED: - case PIPE_FORMAT_R16G16_SNORM: - case PIPE_FORMAT_R16G16_USCALED: - case PIPE_FORMAT_R16G16_UNORM: - return 2 * 2; - case PIPE_FORMAT_R16G16B16_SSCALED: - case PIPE_FORMAT_R16G16B16_SNORM: - case PIPE_FORMAT_R16G16B16_USCALED: - case PIPE_FORMAT_R16G16B16_UNORM: - return 3 * 2; - case PIPE_FORMAT_R16G16B16A16_SSCALED: - case PIPE_FORMAT_R16G16B16A16_SNORM: - case PIPE_FORMAT_R16G16B16A16_USCALED: - case PIPE_FORMAT_R16G16B16A16_UNORM: - return 4 * 2; - - case PIPE_FORMAT_R8_SSCALED: - case PIPE_FORMAT_R8_SNORM: - case PIPE_FORMAT_R8_USCALED: - case PIPE_FORMAT_R8_UNORM: - return 1; - case PIPE_FORMAT_R8G8_SSCALED: - case PIPE_FORMAT_R8G8_SNORM: - case PIPE_FORMAT_R8G8_USCALED: - case PIPE_FORMAT_R8G8_UNORM: - return 2 * 1; - case PIPE_FORMAT_R8G8B8_SSCALED: - case PIPE_FORMAT_R8G8B8_SNORM: - case PIPE_FORMAT_R8G8B8_USCALED: - case PIPE_FORMAT_R8G8B8_UNORM: - return 3 * 1; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R8G8B8A8_SSCALED: - case PIPE_FORMAT_R8G8B8A8_SNORM: - case PIPE_FORMAT_R8G8B8A8_USCALED: - case PIPE_FORMAT_R8G8B8A8_UNORM: - return 4 * 1; - - case 0: - return 0; /* not sure why this is needed */ - - default: - assert(0); - return 0; - } -} - - /** * Fetch vertex attributes for 'count' vertices. */ @@ -612,10 +161,10 @@ static void generic_vertex_fetch(struct spu_vs_context *draw, /* loop over vertex attributes (vertex shader inputs) */ for (attr = 0; attr < nr_attrs; attr++) { - const qword default_values = (qword)(vec_float4){ 0.0, 0.0, 0.0, 1.0 }; const unsigned pitch = draw->vertex_fetch.pitch[attr]; const uint64_t src = draw->vertex_fetch.src_ptr[attr]; - const spu_fetch_func fetch = draw->vertex_fetch.fetch[attr]; + const spu_fetch_func fetch = (spu_fetch_func) + (draw->vertex_fetch.code + draw->vertex_fetch.code_offset[attr]); unsigned i; unsigned idx; const unsigned bytes_per_entry = draw->vertex_fetch.size[attr]; @@ -644,8 +193,7 @@ static void generic_vertex_fetch(struct spu_vs_context *draw, /* Convert all 4 vertices to vectors of float. */ - (*fetch)(&machine->Inputs[attr].xyzw[0].q, in, default_values, - fetch_shuffle_data); + (*fetch)(&machine->Inputs[attr].xyzw[0].q, in, fetch_shuffle_data); } } @@ -662,12 +210,5 @@ void spu_update_vertex_fetch( struct spu_vs_context *draw ) } - for (i = 0; i < draw->vertex_fetch.nr_attrs; i++) { - draw->vertex_fetch.fetch[i] = - get_fetch_func(draw->vertex_fetch.format[i]); - draw->vertex_fetch.size[i] = - get_vertex_size(draw->vertex_fetch.format[i]); - } - draw->vertex_fetch.fetch_func = generic_vertex_fetch; } diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.h b/src/gallium/drivers/cell/spu/spu_vertex_shader.h index b5bf31e67d..0fb0bc28d0 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.h +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.h @@ -6,8 +6,6 @@ struct spu_vs_context; -typedef void (*spu_fetch_func)(qword *out, const qword *in, qword defaults, - const qword *shuffle_data); typedef void (*spu_full_fetch_func)( struct spu_vs_context *draw, struct spu_exec_machine *machine, const unsigned *elts, @@ -20,12 +18,12 @@ struct spu_vs_context { uint64_t src_ptr[PIPE_ATTRIB_MAX]; unsigned pitch[PIPE_ATTRIB_MAX]; unsigned size[PIPE_ATTRIB_MAX]; - enum pipe_format format[PIPE_ATTRIB_MAX]; + unsigned code_offset[PIPE_ATTRIB_MAX]; unsigned nr_attrs; boolean dirty; - spu_fetch_func fetch[PIPE_ATTRIB_MAX]; spu_full_fetch_func fetch_func; + void *code; } vertex_fetch; /* Clip derived state: -- cgit v1.2.3 From 08c9534107fcaf06f9b801551524ed5dc724db13 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 16 Feb 2008 10:05:01 -0700 Subject: gallium: implement min vs. mag filter determination for non-mipmapped textures Fixes tests/minmag.c --- src/gallium/drivers/softpipe/sp_tex_sample.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 2f82fd6abe..c0128f81d7 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -476,6 +476,19 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, /* no mipmap selection needed */ *imgFilter = sampler->state->mag_img_filter; *level0 = *level1 = (int) sampler->state->min_lod; + + if (sampler->state->min_img_filter != sampler->state->mag_img_filter) { + /* non-mipmapped texture, but still need to determine if doing + * minification or magnification. + */ + float lambda = compute_lambda(sampler, s, t, p, lodbias); + if (lambda < 0.5) { /* XXX this may need tweaking... */ + *imgFilter = sampler->state->mag_img_filter; + } + else { + *imgFilter = sampler->state->min_img_filter; + } + } } else { float lambda; -- cgit v1.2.3 From 3b2a291888d8e62787de03f8529806fb562bd186 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 16 Feb 2008 13:50:31 -0700 Subject: gallium: tweak texture filter min/mag thresholds --- src/gallium/drivers/softpipe/sp_tex_sample.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index c0128f81d7..a15bd43166 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -474,7 +474,6 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, { if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { /* no mipmap selection needed */ - *imgFilter = sampler->state->mag_img_filter; *level0 = *level1 = (int) sampler->state->min_lod; if (sampler->state->min_img_filter != sampler->state->mag_img_filter) { @@ -482,13 +481,16 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, * minification or magnification. */ float lambda = compute_lambda(sampler, s, t, p, lodbias); - if (lambda < 0.5) { /* XXX this may need tweaking... */ + if (lambda <= 0.0) { *imgFilter = sampler->state->mag_img_filter; } else { *imgFilter = sampler->state->min_img_filter; } } + else { + *imgFilter = sampler->state->mag_img_filter; + } } else { float lambda; @@ -500,7 +502,7 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, /* vertex shader */ lambda = lodbias; /* not really a bias, but absolute LOD */ - if (lambda < 0.0) { /* XXX threshold depends on the filter */ + if (lambda <= 0.0) { /* XXX threshold depends on the filter */ /* magnifying */ *imgFilter = sampler->state->mag_img_filter; *level0 = *level1 = 0; -- cgit v1.2.3 From 0c6bbd41bd6dc1041eaca7c907d3768d107c1afa Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 16 Feb 2008 13:55:47 -0700 Subject: gallium: add missing mip level clamp --- src/gallium/drivers/softpipe/sp_tex_sample.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index a15bd43166..c54e9d385c 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -474,7 +474,8 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, { if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { /* no mipmap selection needed */ - *level0 = *level1 = (int) sampler->state->min_lod; + *level0 = *level1 = CLAMP((int) sampler->state->min_lod, + 0, (int) sampler->texture->last_level); if (sampler->state->min_img_filter != sampler->state->mag_img_filter) { /* non-mipmapped texture, but still need to determine if doing -- cgit v1.2.3 From 4a79156812d574249b51e1692f4615aa31bf0e50 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sun, 17 Feb 2008 09:42:26 -0500 Subject: fix the build --- src/gallium/auxiliary/llvm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/llvm/Makefile b/src/gallium/auxiliary/llvm/Makefile index e0abf860c1..39fac6ea4a 100644 --- a/src/gallium/auxiliary/llvm/Makefile +++ b/src/gallium/auxiliary/llvm/Makefile @@ -30,7 +30,7 @@ OBJECTS = $(C_SOURCES:.c=.o) \ ### Include directories INCLUDES = \ -I. \ - -I$(TOP)/src/gallium/drivers + -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/mesa \ -- cgit v1.2.3 From bfd5916eafb9a97ad10f1d4a8738e7dcb02e04f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Feb 2008 14:25:04 +0900 Subject: Code reorganization: split gallium and mesa makefiles. In other words, don't build src/gallium source code from within src/mesa/Makefile. Also, allow to customize which gallium auxiliary dirs, driver driver, winsys dirs get built from the config/* files. --- src/gallium/Makefile.template | 1 + src/gallium/auxiliary/Makefile | 6 +- src/gallium/auxiliary/cso_cache/Makefile | 18 +++++ src/gallium/auxiliary/draw/Makefile | 41 ++++++++++- src/gallium/auxiliary/tgsi/Makefile | 24 ++++++- src/gallium/auxiliary/tgsi/exec/Makefile | 3 - src/gallium/auxiliary/util/Makefile | 20 ++++++ src/gallium/drivers/Makefile | 6 +- src/gallium/winsys/Makefile | 20 ++++++ src/gallium/winsys/dri/Makefile.template | 6 +- src/gallium/winsys/xlib/Makefile | 113 +++++++++++++++++++++++++++++++ 11 files changed, 239 insertions(+), 19 deletions(-) create mode 100644 src/gallium/auxiliary/cso_cache/Makefile delete mode 100644 src/gallium/auxiliary/tgsi/exec/Makefile create mode 100644 src/gallium/auxiliary/util/Makefile create mode 100644 src/gallium/winsys/Makefile create mode 100644 src/gallium/winsys/xlib/Makefile (limited to 'src/gallium') diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 83b25f9b47..6ad58c205c 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -20,6 +20,7 @@ INCLUDES = \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ -I$(TOP)/include \ $(DRIVER_INCLUDES) diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index da68498aa1..eaa0f2fe4e 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -2,11 +2,7 @@ TOP = ../../.. include $(TOP)/configs/current -ifeq ($(CONFIG_NAME), linux-llvm) -LLVM_DIR = llvm -endif - -SUBDIRS = pipebuffer $(LLVM_DIR) +SUBDIRS = $(GALLIUM_AUXILIARY_DIRS) default: subdirs diff --git a/src/gallium/auxiliary/cso_cache/Makefile b/src/gallium/auxiliary/cso_cache/Makefile new file mode 100644 index 0000000000..8248b097fd --- /dev/null +++ b/src/gallium/auxiliary/cso_cache/Makefile @@ -0,0 +1,18 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = cso_cache + +DRIVER_SOURCES = \ + cso_cache.c \ + cso_hash.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index fe9b150f30..c56b63d85b 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -1,2 +1,39 @@ -default: - cd ../../../mesa ; make +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = draw + +DRIVER_SOURCES = \ + draw_clip.c \ + draw_vs_exec.c \ + draw_vs_sse.c \ + draw_vs_llvm.c \ + draw_context.c\ + draw_cull.c \ + draw_debug.c \ + draw_flatshade.c \ + draw_offset.c \ + draw_prim.c \ + draw_stipple.c \ + draw_twoside.c \ + draw_unfilled.c \ + draw_validate.c \ + draw_vbuf.c \ + draw_vertex.c \ + draw_vertex_cache.c \ + draw_vertex_fetch.c \ + draw_vertex_shader.c \ + draw_vf.c \ + draw_vf_generic.c \ + draw_vf_sse.c \ + draw_wide_prims.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index 12a8bd0409..c10ab396d8 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -1,3 +1,23 @@ -default: - cd ../.. ; make + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = tgsi + +DRIVER_SOURCES = \ + exec/tgsi_exec.c \ + exec/tgsi_sse2.c \ + util/tgsi_build.c \ + util/tgsi_dump.c \ + util/tgsi_parse.c \ + util/tgsi_util.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: diff --git a/src/gallium/auxiliary/tgsi/exec/Makefile b/src/gallium/auxiliary/tgsi/exec/Makefile deleted file mode 100644 index eb8b14e0e8..0000000000 --- a/src/gallium/auxiliary/tgsi/exec/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -default: - cd ../../.. ; make - diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile new file mode 100644 index 0000000000..b8cb148c4f --- /dev/null +++ b/src/gallium/auxiliary/util/Makefile @@ -0,0 +1,20 @@ + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = util + +DRIVER_SOURCES = \ + p_debug.c \ + p_tile.c \ + p_util.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/Makefile b/src/gallium/drivers/Makefile index c0345a9cb5..8dcfb18a16 100644 --- a/src/gallium/drivers/Makefile +++ b/src/gallium/drivers/Makefile @@ -2,11 +2,7 @@ TOP = ../../.. include $(TOP)/configs/current -ifeq ($(CONFIG_NAME), linux-cell) -CELL_DIR = cell -endif - -SUBDIRS = softpipe i915simple i965simple failover pipebuffer $(CELL_DIR) +SUBDIRS = softpipe i915simple i965simple failover default: subdirs diff --git a/src/gallium/winsys/Makefile b/src/gallium/winsys/Makefile new file mode 100644 index 0000000000..3dc5ea5744 --- /dev/null +++ b/src/gallium/winsys/Makefile @@ -0,0 +1,20 @@ +TOP = ../../.. +include $(TOP)/configs/current + + +SUBDIRS = $(GALLIUM_WINSYS_DIRS) + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 2a261ed669..65a93bd53e 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -1,7 +1,9 @@ # -*-makefile-*- -MESA_MODULES = $(TOP)/src/mesa/libmesa.a - +MESA_MODULES = \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + COMMON_GALLIUM_SOURCES = \ $(TOP)/src/mesa/drivers/dri/common/utils.c \ $(TOP)/src/mesa/drivers/dri/common/vblank.c \ diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile new file mode 100644 index 0000000000..2664ac47ce --- /dev/null +++ b/src/gallium/winsys/xlib/Makefile @@ -0,0 +1,113 @@ +# src/mesa/Makefile + +TOP = ../../../.. +include $(TOP)/configs/current + + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/auxiliary + +X11_DRIVER_SOURCES = \ + glxapi.c \ + fakeglx.c \ + xfonts.c \ + xm_api.c \ + xm_winsys.c \ + xm_winsys_aub.c \ + brw_aub.c + + +GL_MAJOR = 1 +GL_MINOR = 5 +GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) + + +PIPE_LIB = \ + $(GALLIUM_DRIVERS) \ + $(TOP)/src/mesa/libglapi.a \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + +ifeq ($(CONFIG_NAME), linux-cell) +CELL_LIB = $(TOP)/src/gallium/drivers/cell/ppu/libcell.a +CELL_LIB_SPU = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a +endif + +ifeq ($(CONFIG_NAME), linux-llvm) +LLVM_LIB = $(TOP)/src/gallium/auxiliary/llvm/libgallivm.a +endif + + +.SUFFIXES : .cpp + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + + +default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) + + +###################################################################### +# Stand-alone Mesa libGL and libOSMesa +STAND_ALONE_DRIVER_SOURCES = \ + $(X11_DRIVER_SOURCES) + +STAND_ALONE_DRIVER_OBJECTS = $(STAND_ALONE_DRIVER_SOURCES:.c=.o) + +STAND_ALONE_OBJECTS = \ + $(STAND_ALONE_DRIVER_OBJECTS) + +# Make the GL library +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(LLVM_LIB) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) + $(TOP)/bin/mklib -o $(GL_LIB) \ + -linker "$(CC)" \ + -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ + -install $(TOP)/$(LIB_DIR) \ + $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ + --start-group $(PIPE_LIB) $(LLVM_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) + + +###################################################################### +# Generic stuff + +depend: $(ALL_SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend # workaround oops on gutsy?!? + @ touch depend + @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \ + > /dev/null 2>/dev/null + + +install: default + $(INSTALL) -d $(INSTALL_DIR)/include/GL + $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL + @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \ + $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \ + fi + +## NOT INSTALLED YET: +## $(INSTALL) -d $(INSTALL_DIR)/include/GLES +## $(INSTALL) -m 644 include/GLES/*.h $(INSTALL_DIR)/include/GLES + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h + +clean: + -rm -f *.o + + +include depend -- cgit v1.2.3 From 39fe5851a57a7218eafce7dab971738bdb780166 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Feb 2008 15:07:17 +0900 Subject: Actually use GALLIUM_DRIVER_DIRS. --- src/gallium/drivers/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/Makefile b/src/gallium/drivers/Makefile index 8dcfb18a16..6161cb6ff8 100644 --- a/src/gallium/drivers/Makefile +++ b/src/gallium/drivers/Makefile @@ -2,7 +2,7 @@ TOP = ../../.. include $(TOP)/configs/current -SUBDIRS = softpipe i915simple i965simple failover +SUBDIRS = $(GALLIUM_DRIVER_DIRS) default: subdirs -- cgit v1.2.3 From 8450b14676a2f5c6423b16bc4bc7a1ec5a6a987e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Feb 2008 15:37:52 +0900 Subject: Cleanup depend files. --- src/gallium/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/Makefile b/src/gallium/Makefile index 89e068a449..568747e157 100644 --- a/src/gallium/Makefile +++ b/src/gallium/Makefile @@ -18,3 +18,4 @@ subdirs: clean: rm -f `find . -name \*.[oa]` + rm -f `find . -name depend` -- cgit v1.2.3 From 33ceb6716a2166db75659fa66d85fb4cfb9633c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Feb 2008 10:52:44 +0000 Subject: Update scons build for new code layout. --- src/gallium/SConscript | 23 ++++++++++--- src/gallium/auxiliary/cso_cache/SConscript | 10 ++++++ src/gallium/auxiliary/draw/SConscript | 31 ++++++++++++++++++ src/gallium/auxiliary/pipebuffer/SConscript | 14 ++++++++ src/gallium/auxiliary/tgsi/SConscript | 14 ++++++++ src/gallium/auxiliary/util/SConscript | 11 +++++++ src/gallium/drivers/failover/SConscript | 13 ++++++++ src/gallium/winsys/SConscript | 10 ++++++ src/gallium/winsys/dri/SConscript | 51 +++++++++++++++++++++++++++++ src/gallium/winsys/dri/intel/SConscript | 14 ++++---- src/gallium/winsys/xlib/SConscript | 28 ++++++++++++++++ 11 files changed, 207 insertions(+), 12 deletions(-) create mode 100644 src/gallium/auxiliary/cso_cache/SConscript create mode 100644 src/gallium/auxiliary/draw/SConscript create mode 100644 src/gallium/auxiliary/pipebuffer/SConscript create mode 100644 src/gallium/auxiliary/tgsi/SConscript create mode 100644 src/gallium/auxiliary/util/SConscript create mode 100644 src/gallium/drivers/failover/SConscript create mode 100644 src/gallium/winsys/SConscript create mode 100644 src/gallium/winsys/dri/SConscript create mode 100644 src/gallium/winsys/xlib/SConscript (limited to 'src/gallium') diff --git a/src/gallium/SConscript b/src/gallium/SConscript index d9c20e0100..a835f6d661 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -1,9 +1,24 @@ Import('*') -#env = env.Clone() +env = env.Clone() + +auxiliaries = [] + +Export('auxiliaries') + SConscript([ - 'softpipe/SConscript', - 'i915simple/SConscript', - 'i965simple/SConscript', + # NOTE: order matters! + 'auxiliary/util/SConscript', + 'auxiliary/tgsi/SConscript', + 'auxiliary/cso_cache/SConscript', + 'auxiliary/draw/SConscript', + #'auxiliary/llvm/SConscript', + 'auxiliary/pipebuffer/SConscript', + + 'drivers/softpipe/SConscript', + 'drivers/i915simple/SConscript', + 'drivers/i965simple/SConscript', + 'drivers/failover/SConscript', + #'drivers/cell/SConscript', ]) diff --git a/src/gallium/auxiliary/cso_cache/SConscript b/src/gallium/auxiliary/cso_cache/SConscript new file mode 100644 index 0000000000..9751881613 --- /dev/null +++ b/src/gallium/auxiliary/cso_cache/SConscript @@ -0,0 +1,10 @@ +Import('*') + +cso_cache = env.ConvenienceLibrary( + target = 'cso_cache', + source = [ + 'cso_cache.c', + 'cso_hash.c', + ]) + +auxiliaries.insert(0, cso_cache) diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript new file mode 100644 index 0000000000..8e3a8caa74 --- /dev/null +++ b/src/gallium/auxiliary/draw/SConscript @@ -0,0 +1,31 @@ +Import('*') + +draw = env.ConvenienceLibrary( + target = 'draw', + source = [ + 'draw_clip.c', + 'draw_vs_exec.c', + 'draw_vs_sse.c', + 'draw_vs_llvm.c', + 'draw_context.c', + 'draw_cull.c', + 'draw_debug.c', + 'draw_flatshade.c', + 'draw_offset.c', + 'draw_prim.c', + 'draw_stipple.c', + 'draw_twoside.c', + 'draw_unfilled.c', + 'draw_validate.c', + 'draw_vbuf.c', + 'draw_vertex.c', + 'draw_vertex_cache.c', + 'draw_vertex_fetch.c', + 'draw_vertex_shader.c', + 'draw_vf.c', + 'draw_vf_generic.c', + 'draw_vf_sse.c', + 'draw_wide_prims.c', + ]) + +auxiliaries.insert(0, draw) diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript new file mode 100644 index 0000000000..3d41fd84a6 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/SConscript @@ -0,0 +1,14 @@ +Import('*') + +pipebuffer = env.ConvenienceLibrary( + target = 'pipebuffer', + source = [ + 'pb_buffer_fenced.c', + 'pb_buffer_malloc.c', + 'pb_bufmgr_fenced.c', + 'pb_bufmgr_mm.c', + 'pb_bufmgr_pool.c', + 'pb_winsys.c', + ]) + +auxiliaries.insert(0, pipebuffer) diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript new file mode 100644 index 0000000000..8464bfe944 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -0,0 +1,14 @@ +Import('*') + +tgsi = env.ConvenienceLibrary( + target = 'tgsi', + source = [ + 'exec/tgsi_exec.c', + 'exec/tgsi_sse2.c', + 'util/tgsi_build.c', + 'util/tgsi_dump.c', + 'util/tgsi_parse.c', + 'util/tgsi_util.c', + ]) + +auxiliaries.insert(0, tgsi) diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript new file mode 100644 index 0000000000..b126cf44d6 --- /dev/null +++ b/src/gallium/auxiliary/util/SConscript @@ -0,0 +1,11 @@ +Import('*') + +util = env.ConvenienceLibrary( + target = 'util', + source = [ + 'p_debug.c', + 'p_tile.c', + 'p_util.c', + ]) + +auxiliaries.insert(0, util) diff --git a/src/gallium/drivers/failover/SConscript b/src/gallium/drivers/failover/SConscript new file mode 100644 index 0000000000..f8e9b1b491 --- /dev/null +++ b/src/gallium/drivers/failover/SConscript @@ -0,0 +1,13 @@ +Import('*') + +env = env.Clone() + +failover = env.ConvenienceLibrary( + target = 'failover', + source = [ + 'fo_state.c', + 'fo_state_emit.c', + 'fo_context.c', + ]) + +Export('failover') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript new file mode 100644 index 0000000000..32215d8d58 --- /dev/null +++ b/src/gallium/winsys/SConscript @@ -0,0 +1,10 @@ +Import('*') + +if dri: + SConscript([ + 'dri/SConscript', + ]) +else: + SConscript([ + 'xlib/SConscript', + ]) diff --git a/src/gallium/winsys/dri/SConscript b/src/gallium/winsys/dri/SConscript new file mode 100644 index 0000000000..8c56ce917c --- /dev/null +++ b/src/gallium/winsys/dri/SConscript @@ -0,0 +1,51 @@ +Import('*') + +drienv = env.Clone() + +drienv.Replace(CPPPATH = [ + '#src/mesa/drivers/dri/common', + '#include', + '#include/GL/internal', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', +]) + +drienv.ParseConfig('pkg-config --cflags --libs libdrm') + +COMMON_GALLIUM_SOURCES = [ + '#src/mesa/drivers/dri/common/utils.c', + '#src/mesa/drivers/dri/common/vblank.c', + '#src/mesa/drivers/dri/common/dri_util.c', + '#src/mesa/drivers/dri/common/xmlconfig.c', +] + +COMMON_BM_SOURCES = [ + '#src/mesa/drivers/dri/common/dri_bufmgr.c', + '#src/mesa/drivers/dri/common/dri_drmpool.c', +] + +Export([ + 'drienv', + 'COMMON_GALLIUM_SOURCES', + 'COMMON_BM_SOURCES', +]) + +# TODO: Installation +#install: $(LIBNAME) +# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) +# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + +SConscript([ + 'intel/SConscript', +]) diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index a7cc10450e..525ba580e8 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -9,11 +9,6 @@ env.Append(CPPPATH = [ #MINIGLX_SOURCES = server/intel_dri.c -pipe_drivers = [ - softpipe, - i915simple -] - DRIVER_SOURCES = [ 'intel_winsys_pipe.c', 'intel_winsys_softpipe.c', @@ -31,11 +26,14 @@ sources = \ COMMON_BM_SOURCES + \ DRIVER_SOURCES -# DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ -# && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +drivers = [ + softpipe, + i915simple +] +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions env.SharedLibrary( target ='i915tex_dri.so', source = sources, - LIBS = pipe_drivers + env['LIBS'], + LIBS = mesa + drivers + auxiliaries + env['LIBS'], ) \ No newline at end of file diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript new file mode 100644 index 0000000000..f8aa5ef945 --- /dev/null +++ b/src/gallium/winsys/xlib/SConscript @@ -0,0 +1,28 @@ +####################################################################### +# SConscript for xlib winsys + +Import('*') + + +sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'xm_winsys.c', + 'xm_winsys_aub.c', + 'brw_aub.c', +] + +drivers = [ + softpipe, + i915simple, + i965simple, +] + +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions +env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], +) -- cgit v1.2.3 From 687a8b96ef13658bbe779d0011ce1144844f1972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Feb 2008 20:02:42 +0900 Subject: Standardize on using the pipe/ include prefix. --- src/gallium/Makefile.template | 1 - src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 10 +++++----- src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c | 4 ++-- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 8 ++++---- src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 10 +++++----- src/gallium/drivers/i915simple/i915_state_immediate.c | 2 +- src/gallium/drivers/i915simple/i915_state_inlines.h | 4 ++-- src/gallium/drivers/softpipe/sp_state_surface.c | 2 +- 8 files changed, 20 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 6ad58c205c..6698212e77 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -16,7 +16,6 @@ OBJECTS = $(C_SOURCES:.c=.o) \ INCLUDES = \ -I. \ -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/include/pipe \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/mesa \ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index f4fc3f6d71..bc85c4b19f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -36,11 +36,11 @@ #include "linked_list.h" -#include "p_compiler.h" -#include "p_debug.h" -#include "p_winsys.h" -#include "p_thread.h" -#include "p_util.h" +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_winsys.h" +#include "pipe/p_thread.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_buffer_fenced.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c index c535d3276c..bffca5b244 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c @@ -34,8 +34,8 @@ */ -#include "p_debug.h" -#include "p_util.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_buffer_fenced.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 8b1b51c0e2..969aab51b5 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -36,10 +36,10 @@ #include "linked_list.h" -#include "p_defines.h" -#include "p_debug.h" -#include "p_thread.h" -#include "p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_debug.h" +#include "pipe/p_thread.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index 04477a865a..beb145b7cb 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -37,11 +37,11 @@ #include "linked_list.h" -#include "p_compiler.h" -#include "p_debug.h" -#include "p_thread.h" -#include "p_defines.h" -#include "p_util.h" +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_thread.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/drivers/i915simple/i915_state_immediate.c b/src/gallium/drivers/i915simple/i915_state_immediate.c index 07031fc6c5..dfbbcab624 100644 --- a/src/gallium/drivers/i915simple/i915_state_immediate.c +++ b/src/gallium/drivers/i915simple/i915_state_immediate.c @@ -33,7 +33,7 @@ #include "i915_context.h" #include "i915_state.h" #include "i915_reg.h" -#include "p_util.h" +#include "pipe/p_util.h" /* All state expressable with the LOAD_STATE_IMMEDIATE_1 packet. diff --git a/src/gallium/drivers/i915simple/i915_state_inlines.h b/src/gallium/drivers/i915simple/i915_state_inlines.h index 0934ac79a4..378de8f9c4 100644 --- a/src/gallium/drivers/i915simple/i915_state_inlines.h +++ b/src/gallium/drivers/i915simple/i915_state_inlines.h @@ -28,8 +28,8 @@ #ifndef I915_STATE_INLINES_H #define I915_STATE_INLINES_H -#include "p_compiler.h" -#include "p_defines.h" +#include "pipe/p_compiler.h" +#include "pipe/p_defines.h" #include "i915_reg.h" diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index e2c6893e9f..124b18b708 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -27,7 +27,7 @@ /* Authors: Keith Whitwell */ -#include "p_inlines.h" +#include "pipe/p_inlines.h" #include "sp_context.h" #include "sp_state.h" -- cgit v1.2.3 From 3f3b09d6d86cfd277c5837d15466ee703897aa3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Feb 2008 20:05:06 +0900 Subject: Rename llvm -> gallivm. Following the directory == library name policy simplifies the build system. --- src/gallium/auxiliary/gallivm/Makefile | 85 ++ src/gallium/auxiliary/gallivm/gallivm.cpp | 327 ++++++ src/gallium/auxiliary/gallivm/gallivm.h | 103 ++ src/gallium/auxiliary/gallivm/gallivm_builtins.cpp | 567 +++++++++ src/gallium/auxiliary/gallivm/gallivm_cpu.cpp | 202 ++++ src/gallium/auxiliary/gallivm/gallivm_p.h | 110 ++ src/gallium/auxiliary/gallivm/instructions.cpp | 889 ++++++++++++++ src/gallium/auxiliary/gallivm/instructions.h | 152 +++ src/gallium/auxiliary/gallivm/instructionssoa.cpp | 121 ++ src/gallium/auxiliary/gallivm/instructionssoa.h | 74 ++ src/gallium/auxiliary/gallivm/llvm_builtins.c | 115 ++ src/gallium/auxiliary/gallivm/loweringpass.cpp | 17 + src/gallium/auxiliary/gallivm/loweringpass.h | 15 + src/gallium/auxiliary/gallivm/storage.cpp | 364 ++++++ src/gallium/auxiliary/gallivm/storage.h | 133 +++ src/gallium/auxiliary/gallivm/storagesoa.cpp | 389 +++++++ src/gallium/auxiliary/gallivm/storagesoa.h | 111 ++ src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 1221 ++++++++++++++++++++ src/gallium/auxiliary/gallivm/tgsitollvm.h | 20 + src/gallium/auxiliary/llvm/Makefile | 85 -- src/gallium/auxiliary/llvm/gallivm.cpp | 327 ------ src/gallium/auxiliary/llvm/gallivm.h | 103 -- src/gallium/auxiliary/llvm/gallivm_builtins.cpp | 567 --------- src/gallium/auxiliary/llvm/gallivm_cpu.cpp | 202 ---- src/gallium/auxiliary/llvm/gallivm_p.h | 110 -- src/gallium/auxiliary/llvm/instructions.cpp | 889 -------------- src/gallium/auxiliary/llvm/instructions.h | 152 --- src/gallium/auxiliary/llvm/instructionssoa.cpp | 121 -- src/gallium/auxiliary/llvm/instructionssoa.h | 74 -- src/gallium/auxiliary/llvm/llvm_builtins.c | 115 -- src/gallium/auxiliary/llvm/loweringpass.cpp | 17 - src/gallium/auxiliary/llvm/loweringpass.h | 15 - src/gallium/auxiliary/llvm/storage.cpp | 364 ------ src/gallium/auxiliary/llvm/storage.h | 133 --- src/gallium/auxiliary/llvm/storagesoa.cpp | 389 ------- src/gallium/auxiliary/llvm/storagesoa.h | 111 -- src/gallium/auxiliary/llvm/tgsitollvm.cpp | 1221 -------------------- src/gallium/auxiliary/llvm/tgsitollvm.h | 20 - 38 files changed, 5015 insertions(+), 5015 deletions(-) create mode 100644 src/gallium/auxiliary/gallivm/Makefile create mode 100644 src/gallium/auxiliary/gallivm/gallivm.cpp create mode 100644 src/gallium/auxiliary/gallivm/gallivm.h create mode 100644 src/gallium/auxiliary/gallivm/gallivm_builtins.cpp create mode 100644 src/gallium/auxiliary/gallivm/gallivm_cpu.cpp create mode 100644 src/gallium/auxiliary/gallivm/gallivm_p.h create mode 100644 src/gallium/auxiliary/gallivm/instructions.cpp create mode 100644 src/gallium/auxiliary/gallivm/instructions.h create mode 100644 src/gallium/auxiliary/gallivm/instructionssoa.cpp create mode 100644 src/gallium/auxiliary/gallivm/instructionssoa.h create mode 100644 src/gallium/auxiliary/gallivm/llvm_builtins.c create mode 100644 src/gallium/auxiliary/gallivm/loweringpass.cpp create mode 100644 src/gallium/auxiliary/gallivm/loweringpass.h create mode 100644 src/gallium/auxiliary/gallivm/storage.cpp create mode 100644 src/gallium/auxiliary/gallivm/storage.h create mode 100644 src/gallium/auxiliary/gallivm/storagesoa.cpp create mode 100644 src/gallium/auxiliary/gallivm/storagesoa.h create mode 100644 src/gallium/auxiliary/gallivm/tgsitollvm.cpp create mode 100644 src/gallium/auxiliary/gallivm/tgsitollvm.h delete mode 100644 src/gallium/auxiliary/llvm/Makefile delete mode 100644 src/gallium/auxiliary/llvm/gallivm.cpp delete mode 100644 src/gallium/auxiliary/llvm/gallivm.h delete mode 100644 src/gallium/auxiliary/llvm/gallivm_builtins.cpp delete mode 100644 src/gallium/auxiliary/llvm/gallivm_cpu.cpp delete mode 100644 src/gallium/auxiliary/llvm/gallivm_p.h delete mode 100644 src/gallium/auxiliary/llvm/instructions.cpp delete mode 100644 src/gallium/auxiliary/llvm/instructions.h delete mode 100644 src/gallium/auxiliary/llvm/instructionssoa.cpp delete mode 100644 src/gallium/auxiliary/llvm/instructionssoa.h delete mode 100644 src/gallium/auxiliary/llvm/llvm_builtins.c delete mode 100644 src/gallium/auxiliary/llvm/loweringpass.cpp delete mode 100644 src/gallium/auxiliary/llvm/loweringpass.h delete mode 100644 src/gallium/auxiliary/llvm/storage.cpp delete mode 100644 src/gallium/auxiliary/llvm/storage.h delete mode 100644 src/gallium/auxiliary/llvm/storagesoa.cpp delete mode 100644 src/gallium/auxiliary/llvm/storagesoa.h delete mode 100644 src/gallium/auxiliary/llvm/tgsitollvm.cpp delete mode 100644 src/gallium/auxiliary/llvm/tgsitollvm.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/Makefile b/src/gallium/auxiliary/gallivm/Makefile new file mode 100644 index 0000000000..39fac6ea4a --- /dev/null +++ b/src/gallium/auxiliary/gallivm/Makefile @@ -0,0 +1,85 @@ +# -*-makefile-*- +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = gallivm + + +GALLIVM_SOURCES = \ + gallivm.cpp \ + gallivm_cpu.cpp \ + instructions.cpp \ + loweringpass.cpp \ + tgsitollvm.cpp \ + storage.cpp \ + storagesoa.cpp \ + instructionssoa.cpp + +INC_SOURCES = gallivm_builtins.cpp + +CPP_SOURCES = \ + $(GALLIVM_SOURCES) + +C_SOURCES = +ASM_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(CPP_SOURCES:.cpp=.o) \ + $(ASM_SOURCES:.S=.o) + +### Include directories +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/include + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(LLVM_CFLAGS) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(LLVM_CXXFLAGS) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +##### TARGETS ##### + +default:: depend symlinks $(LIBNAME) + + +$(LIBNAME): $(OBJECTS) Makefile + $(TOP)/bin/mklib -o $@ -static $(OBJECTS) + + +depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ + $(ASM_SOURCES) $(INC_SOURCES) 2> /dev/null + + +gallivm_builtins.cpp: llvm_builtins.c + clang --emit-llvm $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.so *~ server/*.o + -rm -f depend depend.bak + -rm -f gallivm_builtins.cpp + +symlinks: + + +include depend diff --git a/src/gallium/auxiliary/gallivm/gallivm.cpp b/src/gallium/auxiliary/gallivm/gallivm.cpp new file mode 100644 index 0000000000..d14bb3b99a --- /dev/null +++ b/src/gallium/auxiliary/gallivm/gallivm.cpp @@ -0,0 +1,327 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "instructions.h" +#include "loweringpass.h" +#include "storage.h" +#include "tgsitollvm.h" + +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_dump.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int GLOBAL_ID = 0; + +using namespace llvm; + +static inline +void AddStandardCompilePasses(PassManager &PM) +{ + PM.add(new LoweringPass()); + PM.add(createVerifierPass()); // Verify that input is correct + + PM.add(createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp + + //PM.add(createStripSymbolsPass(true)); + + PM.add(createRaiseAllocationsPass()); // call %malloc -> malloc inst + PM.add(createCFGSimplificationPass()); // Clean up disgusting code + PM.add(createPromoteMemoryToRegisterPass());// Kill useless allocas + PM.add(createGlobalOptimizerPass()); // Optimize out global vars + PM.add(createGlobalDCEPass()); // Remove unused fns and globs + PM.add(createIPConstantPropagationPass());// IP Constant Propagation + PM.add(createDeadArgEliminationPass()); // Dead argument elimination + PM.add(createInstructionCombiningPass()); // Clean up after IPCP & DAE + PM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE + + PM.add(createPruneEHPass()); // Remove dead EH info + + PM.add(createFunctionInliningPass()); // Inline small functions + PM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args + + PM.add(createTailDuplicationPass()); // Simplify cfg by copying code + PM.add(createInstructionCombiningPass()); // Cleanup for scalarrepl. + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createScalarReplAggregatesPass()); // Break up aggregate allocas + PM.add(createInstructionCombiningPass()); // Combine silly seq's + PM.add(createCondPropagationPass()); // Propagate conditionals + + PM.add(createTailCallEliminationPass()); // Eliminate tail calls + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createReassociatePass()); // Reassociate expressions + PM.add(createLoopRotatePass()); + PM.add(createLICMPass()); // Hoist loop invariants + PM.add(createLoopUnswitchPass()); // Unswitch loops. + PM.add(createLoopIndexSplitPass()); // Index split loops. + PM.add(createInstructionCombiningPass()); // Clean up after LICM/reassoc + PM.add(createIndVarSimplifyPass()); // Canonicalize indvars + PM.add(createLoopUnrollPass()); // Unroll small loops + PM.add(createInstructionCombiningPass()); // Clean up after the unroller + PM.add(createGVNPass()); // Remove redundancies + PM.add(createSCCPPass()); // Constant prop with SCCP + + // Run instcombine after redundancy elimination to exploit opportunities + // opened up by them. + PM.add(createInstructionCombiningPass()); + PM.add(createCondPropagationPass()); // Propagate conditionals + + PM.add(createDeadStoreEliminationPass()); // Delete dead stores + PM.add(createAggressiveDCEPass()); // SSA based 'Aggressive DCE' + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createSimplifyLibCallsPass()); // Library Call Optimizations + PM.add(createDeadTypeEliminationPass()); // Eliminate dead types + PM.add(createConstantMergePass()); // Merge dup global constants +} + +void gallivm_prog_delete(struct gallivm_prog *prog) +{ + delete prog->module; + prog->module = 0; + prog->function = 0; + free(prog); +} + +static inline void +constant_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan) +{ + unsigned i; + + for (i = 0; i < QUAD_SIZE; ++i) { + inputs[i][attrib][chan] = coefs[attrib].a0[chan]; + } +} + +static inline void +linear_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + const float x = inputs[i][0][0]; + const float y = inputs[i][0][1]; + + inputs[i][attrib][chan] = + coefs[attrib].a0[chan] + + coefs[attrib].dadx[chan] * x + + coefs[attrib].dady[chan] * y; + } +} + +static inline void +perspective_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan ) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + const float x = inputs[i][0][0]; + const float y = inputs[i][0][1]; + /* WPOS.w here is really 1/w */ + const float w = 1.0f / inputs[i][0][3]; + assert(inputs[i][0][3] != 0.0); + + inputs[i][attrib][chan] = + (coefs[attrib].a0[chan] + + coefs[attrib].dadx[chan] * x + + coefs[attrib].dady[chan] * y) * w; + } +} + +void gallivm_ir_dump(struct gallivm_ir *ir, const char *file_prefix) +{ + if (!ir || !ir->module) + return; + + if (file_prefix) { + std::ostringstream stream; + stream << file_prefix; + stream << ir->id; + stream << ".ll"; + std::string name = stream.str(); + std::ofstream out(name.c_str()); + if (!out) { + std::cerr<<"Can't open file : "<module); + out.close(); + } else { + const llvm::Module::FunctionListType &funcs = ir->module->getFunctionList(); + llvm::Module::FunctionListType::const_iterator itr; + std::cout<<"; ---------- Start shader "<id<id<num_interp; ++i) { + const gallivm_interpolate &interp = prog->interpolators[i]; + switch (interp.type) { + case TGSI_INTERPOLATE_CONSTANT: + constant_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + case TGSI_INTERPOLATE_LINEAR: + linear_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + perspective_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + default: + assert( 0 ); + } + } +} + + +struct gallivm_ir * gallivm_ir_new(enum gallivm_shader_type type) +{ + struct gallivm_ir *ir = + (struct gallivm_ir *)calloc(1, sizeof(struct gallivm_ir)); + ++GLOBAL_ID; + ir->id = GLOBAL_ID; + ir->type = type; + + return ir; +} + +void gallivm_ir_set_layout(struct gallivm_ir *ir, + enum gallivm_vector_layout layout) +{ + ir->layout = layout; +} + +void gallivm_ir_set_components(struct gallivm_ir *ir, int num) +{ + ir->num_components = num; +} + +void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, + const struct tgsi_token *tokens) +{ + std::cout << "Creating llvm from: " <module = mod; + gallivm_ir_dump(ir, 0); +} + +void gallivm_ir_delete(struct gallivm_ir *ir) +{ + delete ir->module; + free(ir); +} + +struct gallivm_prog * gallivm_ir_compile(struct gallivm_ir *ir) +{ + struct gallivm_prog *prog = + (struct gallivm_prog *)calloc(1, sizeof(struct gallivm_prog)); + llvm::Module *mod = llvm::CloneModule(ir->module); + prog->num_consts = ir->num_consts; + memcpy(prog->interpolators, ir->interpolators, sizeof(prog->interpolators)); + prog->num_interp = ir->num_interp; + + /* Run optimization passes over it */ + PassManager passes; + passes.add(new TargetData(mod)); + AddStandardCompilePasses(passes); + passes.run(*mod); + prog->module = mod; + + std::cout << "After optimizations:"<dump(); + + return prog; +} + +#endif /* MESA_LLVM */ diff --git a/src/gallium/auxiliary/gallivm/gallivm.h b/src/gallium/auxiliary/gallivm/gallivm.h new file mode 100644 index 0000000000..92da4bca7f --- /dev/null +++ b/src/gallium/auxiliary/gallivm/gallivm.h @@ -0,0 +1,103 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef GALLIVM_H +#define GALLIVM_H + +#if defined __cplusplus +extern "C" { +#endif + +#include "pipe/p_state.h" + +#ifdef MESA_LLVM + +struct tgsi_token; + +struct gallivm_ir; +struct gallivm_prog; +struct gallivm_cpu_engine; +struct tgsi_interp_coef; +struct tgsi_sampler; +struct tgsi_exec_vector; + +enum gallivm_shader_type { + GALLIVM_VS, + GALLIVM_FS +}; + +enum gallivm_vector_layout { + GALLIVM_AOS, + GALLIVM_SOA +}; + +struct gallivm_ir *gallivm_ir_new(enum gallivm_shader_type type); +void gallivm_ir_set_layout(struct gallivm_ir *ir, + enum gallivm_vector_layout layout); +void gallivm_ir_set_components(struct gallivm_ir *ir, int num); +void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, + const struct tgsi_token *tokens); +void gallivm_ir_delete(struct gallivm_ir *ir); + + +struct gallivm_prog *gallivm_ir_compile(struct gallivm_ir *ir); + +void gallivm_prog_inputs_interpolate(struct gallivm_prog *prog, + float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], + const struct tgsi_interp_coef *coefs); +void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix); + + +struct gallivm_cpu_engine *gallivm_cpu_engine_create(struct gallivm_prog *prog); +struct gallivm_cpu_engine *gallivm_global_cpu_engine(); +int gallivm_cpu_vs_exec(struct gallivm_prog *prog, + struct tgsi_exec_vector *inputs, + struct tgsi_exec_vector *dests, + float (*consts)[4], + struct tgsi_exec_vector *temps); +int gallivm_cpu_fs_exec(struct gallivm_prog *prog, + float x, float y, + float (*dests)[PIPE_MAX_SHADER_INPUTS][4], + float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], + float (*consts)[4], + struct tgsi_sampler *samplers); +void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *ee, struct gallivm_prog *prog); +void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *ee); + + +#endif /* MESA_LLVM */ + +#if defined __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp new file mode 100644 index 0000000000..1796f0a177 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp @@ -0,0 +1,567 @@ +// Generated by llvm2cpp - DO NOT MODIFY! + + +Module* createGallivmBuiltins(Module *mod) { + +mod->setModuleIdentifier("shader"); + +// Type Definitions +ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(8), 25); + +PointerType* PointerTy_1 = PointerType::get(ArrayTy_0, 0); + +std::vectorFuncTy_2_args; +FuncTy_2_args.push_back(Type::FloatTy); +FuncTy_2_args.push_back(Type::FloatTy); +FunctionType* FuncTy_2 = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/FuncTy_2_args, + /*isVarArg=*/false); + +PointerType* PointerTy_3 = PointerType::get(FuncTy_2, 0); + +VectorType* VectorTy_4 = VectorType::get(Type::FloatTy, 4); + +std::vectorFuncTy_5_args; +FuncTy_5_args.push_back(VectorTy_4); +FunctionType* FuncTy_5 = FunctionType::get( + /*Result=*/VectorTy_4, + /*Params=*/FuncTy_5_args, + /*isVarArg=*/false); + +std::vectorFuncTy_6_args; +FuncTy_6_args.push_back(VectorTy_4); +FuncTy_6_args.push_back(VectorTy_4); +FuncTy_6_args.push_back(VectorTy_4); +FunctionType* FuncTy_6 = FunctionType::get( + /*Result=*/VectorTy_4, + /*Params=*/FuncTy_6_args, + /*isVarArg=*/false); + +VectorType* VectorTy_7 = VectorType::get(IntegerType::get(32), 4); + +std::vectorFuncTy_9_args; +FunctionType* FuncTy_9 = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/FuncTy_9_args, + /*isVarArg=*/true); + +PointerType* PointerTy_8 = PointerType::get(FuncTy_9, 0); + +PointerType* PointerTy_10 = PointerType::get(IntegerType::get(8), 0); + +std::vectorFuncTy_12_args; +FuncTy_12_args.push_back(Type::FloatTy); +FunctionType* FuncTy_12 = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/FuncTy_12_args, + /*isVarArg=*/false); + +PointerType* PointerTy_11 = PointerType::get(FuncTy_12, 0); + +std::vectorFuncTy_13_args; +FuncTy_13_args.push_back(VectorTy_4); +FunctionType* FuncTy_13 = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/FuncTy_13_args, + /*isVarArg=*/false); + + +// Function Declarations + +Function* func_approx = new Function( + /*Type=*/FuncTy_2, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"approx", mod); +func_approx->setCallingConv(CallingConv::C); +const ParamAttrsList *func_approx_PAL = 0; +func_approx->setParamAttrs(func_approx_PAL); + +Function* func_powf = new Function( + /*Type=*/FuncTy_2, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"powf", mod); // (external, no body) +func_powf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_powf_PAL = 0; +func_powf->setParamAttrs(func_powf_PAL); + +Function* func_lit = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"lit", mod); +func_lit->setCallingConv(CallingConv::C); +const ParamAttrsList *func_lit_PAL = 0; +func_lit->setParamAttrs(func_lit_PAL); + +Function* func_cmp = new Function( + /*Type=*/FuncTy_6, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"cmp", mod); +func_cmp->setCallingConv(CallingConv::C); +const ParamAttrsList *func_cmp_PAL = 0; +{ + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; + Attrs.push_back(PAWI); + func_cmp_PAL = ParamAttrsList::get(Attrs); + +} +func_cmp->setParamAttrs(func_cmp_PAL); + +Function* func_vcos = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"vcos", mod); +func_vcos->setCallingConv(CallingConv::C); +const ParamAttrsList *func_vcos_PAL = 0; +func_vcos->setParamAttrs(func_vcos_PAL); + +Function* func_printf = new Function( + /*Type=*/FuncTy_9, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"printf", mod); // (external, no body) +func_printf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_printf_PAL = 0; +func_printf->setParamAttrs(func_printf_PAL); + +Function* func_cosf = new Function( + /*Type=*/FuncTy_12, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"cosf", mod); // (external, no body) +func_cosf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_cosf_PAL = 0; +func_cosf->setParamAttrs(func_cosf_PAL); + +Function* func_scs = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"scs", mod); +func_scs->setCallingConv(CallingConv::C); +const ParamAttrsList *func_scs_PAL = 0; +func_scs->setParamAttrs(func_scs_PAL); + +Function* func_sinf = new Function( + /*Type=*/FuncTy_12, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"sinf", mod); // (external, no body) +func_sinf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_sinf_PAL = 0; +func_sinf->setParamAttrs(func_sinf_PAL); + +Function* func_vsin = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"vsin", mod); +func_vsin->setCallingConv(CallingConv::C); +const ParamAttrsList *func_vsin_PAL = 0; +func_vsin->setParamAttrs(func_vsin_PAL); + +Function* func_kilp = new Function( + /*Type=*/FuncTy_13, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"kilp", mod); +func_kilp->setCallingConv(CallingConv::C); +const ParamAttrsList *func_kilp_PAL = 0; +{ + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; + Attrs.push_back(PAWI); + func_kilp_PAL = ParamAttrsList::get(Attrs); + +} +func_kilp->setParamAttrs(func_kilp_PAL); + +// Global Variable Declarations + + +GlobalVariable* gvar_array__str = new GlobalVariable( +/*Type=*/ArrayTy_0, +/*isConstant=*/true, +/*Linkage=*/GlobalValue::InternalLinkage, +/*Initializer=*/0, // has initializer, specified below +/*Name=*/".str", +mod); + +GlobalVariable* gvar_array__str1 = new GlobalVariable( +/*Type=*/ArrayTy_0, +/*isConstant=*/true, +/*Linkage=*/GlobalValue::InternalLinkage, +/*Initializer=*/0, // has initializer, specified below +/*Name=*/".str1", +mod); + +// Constant Definitions +Constant* const_array_14 = ConstantArray::get("VEC IN is %f %f %f %f\x0A", true); +Constant* const_array_15 = ConstantArray::get("VEC OUT is %f %f %f %f\x0A", true); +ConstantFP* const_float_16 = ConstantFP::get(Type::FloatTy, APFloat(-1.280000e+02f)); +ConstantFP* const_float_17 = ConstantFP::get(Type::FloatTy, APFloat(1.280000e+02f)); +Constant* const_float_18 = Constant::getNullValue(Type::FloatTy); +Constant* const_int32_19 = Constant::getNullValue(IntegerType::get(32)); +std::vector const_packed_20_elems; +ConstantFP* const_float_21 = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); +const_packed_20_elems.push_back(const_float_21); +UndefValue* const_float_22 = UndefValue::get(Type::FloatTy); +const_packed_20_elems.push_back(const_float_22); +const_packed_20_elems.push_back(const_float_22); +const_packed_20_elems.push_back(const_float_21); +Constant* const_packed_20 = ConstantVector::get(VectorTy_4, const_packed_20_elems); +ConstantInt* const_int32_23 = ConstantInt::get(APInt(32, "1", 10)); +ConstantInt* const_int32_24 = ConstantInt::get(APInt(32, "3", 10)); +ConstantInt* const_int32_25 = ConstantInt::get(APInt(32, "2", 10)); +std::vector const_packed_26_elems; +const_packed_26_elems.push_back(const_float_21); +const_packed_26_elems.push_back(const_float_18); +const_packed_26_elems.push_back(const_float_18); +const_packed_26_elems.push_back(const_float_21); +Constant* const_packed_26 = ConstantVector::get(VectorTy_4, const_packed_26_elems); +Constant* const_double_27 = Constant::getNullValue(Type::DoubleTy); +std::vector const_packed_28_elems; +const_packed_28_elems.push_back(const_int32_19); +ConstantInt* const_int32_29 = ConstantInt::get(APInt(32, "5", 10)); +const_packed_28_elems.push_back(const_int32_29); +const_packed_28_elems.push_back(const_int32_25); +const_packed_28_elems.push_back(const_int32_24); +Constant* const_packed_28 = ConstantVector::get(VectorTy_7, const_packed_28_elems); +std::vector const_packed_30_elems; +const_packed_30_elems.push_back(const_int32_19); +const_packed_30_elems.push_back(const_int32_23); +ConstantInt* const_int32_31 = ConstantInt::get(APInt(32, "6", 10)); +const_packed_30_elems.push_back(const_int32_31); +const_packed_30_elems.push_back(const_int32_24); +Constant* const_packed_30 = ConstantVector::get(VectorTy_7, const_packed_30_elems); +std::vector const_packed_32_elems; +const_packed_32_elems.push_back(const_int32_19); +const_packed_32_elems.push_back(const_int32_23); +const_packed_32_elems.push_back(const_int32_25); +ConstantInt* const_int32_33 = ConstantInt::get(APInt(32, "7", 10)); +const_packed_32_elems.push_back(const_int32_33); +Constant* const_packed_32 = ConstantVector::get(VectorTy_7, const_packed_32_elems); +std::vector const_ptr_34_indices; +const_ptr_34_indices.push_back(const_int32_19); +const_ptr_34_indices.push_back(const_int32_19); +Constant* const_ptr_34 = ConstantExpr::getGetElementPtr(gvar_array__str, &const_ptr_34_indices[0], const_ptr_34_indices.size() ); +UndefValue* const_packed_35 = UndefValue::get(VectorTy_4); +std::vector const_ptr_36_indices; +const_ptr_36_indices.push_back(const_int32_19); +const_ptr_36_indices.push_back(const_int32_19); +Constant* const_ptr_36 = ConstantExpr::getGetElementPtr(gvar_array__str1, &const_ptr_36_indices[0], const_ptr_36_indices.size() ); + +// Global Variable Definitions +gvar_array__str->setInitializer(const_array_14); +gvar_array__str1->setInitializer(const_array_15); + +// Function Definitions + +// Function: approx (func_approx) +{ + Function::arg_iterator args = func_approx->arg_begin(); + Value* float_a = args++; + float_a->setName("a"); + Value* float_b = args++; + float_b->setName("b"); + + BasicBlock* label_entry = new BasicBlock("entry",func_approx,0); + + // Block entry (label_entry) + FCmpInst* int1_cmp = new FCmpInst(FCmpInst::FCMP_OLT, float_b, const_float_16, "cmp", label_entry); + SelectInst* float_b_addr_0 = new SelectInst(int1_cmp, const_float_16, float_b, "b.addr.0", label_entry); + FCmpInst* int1_cmp3 = new FCmpInst(FCmpInst::FCMP_OGT, float_b_addr_0, const_float_17, "cmp3", label_entry); + SelectInst* float_b_addr_1 = new SelectInst(int1_cmp3, const_float_17, float_b_addr_0, "b.addr.1", label_entry); + FCmpInst* int1_cmp7 = new FCmpInst(FCmpInst::FCMP_OLT, float_a, const_float_18, "cmp7", label_entry); + SelectInst* float_a_addr_0 = new SelectInst(int1_cmp7, const_float_18, float_a, "a.addr.0", label_entry); + std::vector float_call_params; + float_call_params.push_back(float_a_addr_0); + float_call_params.push_back(float_b_addr_1); + CallInst* float_call = new CallInst(func_powf, float_call_params.begin(), float_call_params.end(), "call", label_entry); + float_call->setCallingConv(CallingConv::C); + float_call->setTailCall(true);const ParamAttrsList *float_call_PAL = 0; + float_call->setParamAttrs(float_call_PAL); + + new ReturnInst(float_call, label_entry); + +} + +// Function: lit (func_lit) +{ + Function::arg_iterator args = func_lit->arg_begin(); + Value* packed_tmp = args++; + packed_tmp->setName("tmp"); + + BasicBlock* label_entry_38 = new BasicBlock("entry",func_lit,0); + BasicBlock* label_ifthen = new BasicBlock("ifthen",func_lit,0); + BasicBlock* label_UnifiedReturnBlock = new BasicBlock("UnifiedReturnBlock",func_lit,0); + + // Block entry (label_entry_38) + ExtractElementInst* float_tmp6 = new ExtractElementInst(packed_tmp, const_int32_19, "tmp6", label_entry_38); + FCmpInst* int1_cmp_39 = new FCmpInst(FCmpInst::FCMP_OGT, float_tmp6, const_float_18, "cmp", label_entry_38); + new BranchInst(label_ifthen, label_UnifiedReturnBlock, int1_cmp_39, label_entry_38); + + // Block ifthen (label_ifthen) + InsertElementInst* packed_tmp10 = new InsertElementInst(const_packed_20, float_tmp6, const_int32_23, "tmp10", label_ifthen); + ExtractElementInst* float_tmp12 = new ExtractElementInst(packed_tmp, const_int32_23, "tmp12", label_ifthen); + ExtractElementInst* float_tmp14 = new ExtractElementInst(packed_tmp, const_int32_24, "tmp14", label_ifthen); + std::vector float_call_41_params; + float_call_41_params.push_back(float_tmp12); + float_call_41_params.push_back(float_tmp14); + CallInst* float_call_41 = new CallInst(func_approx, float_call_41_params.begin(), float_call_41_params.end(), "call", label_ifthen); + float_call_41->setCallingConv(CallingConv::C); + float_call_41->setTailCall(true);const ParamAttrsList *float_call_41_PAL = 0; + float_call_41->setParamAttrs(float_call_41_PAL); + + InsertElementInst* packed_tmp16 = new InsertElementInst(packed_tmp10, float_call_41, const_int32_25, "tmp16", label_ifthen); + new ReturnInst(packed_tmp16, label_ifthen); + + // Block UnifiedReturnBlock (label_UnifiedReturnBlock) + new ReturnInst(const_packed_26, label_UnifiedReturnBlock); + +} + +// Function: cmp (func_cmp) +{ + Function::arg_iterator args = func_cmp->arg_begin(); + Value* packed_tmp0 = args++; + packed_tmp0->setName("tmp0"); + Value* packed_tmp1 = args++; + packed_tmp1->setName("tmp1"); + Value* packed_tmp2 = args++; + packed_tmp2->setName("tmp2"); + + BasicBlock* label_entry_44 = new BasicBlock("entry",func_cmp,0); + BasicBlock* label_cond__14 = new BasicBlock("cond.?14",func_cmp,0); + BasicBlock* label_cond_cont20 = new BasicBlock("cond.cont20",func_cmp,0); + BasicBlock* label_cond__28 = new BasicBlock("cond.?28",func_cmp,0); + BasicBlock* label_cond_cont34 = new BasicBlock("cond.cont34",func_cmp,0); + BasicBlock* label_cond__42 = new BasicBlock("cond.?42",func_cmp,0); + BasicBlock* label_cond_cont48 = new BasicBlock("cond.cont48",func_cmp,0); + + // Block entry (label_entry_44) + ExtractElementInst* float_tmp3 = new ExtractElementInst(packed_tmp0, const_int32_19, "tmp3", label_entry_44); + CastInst* double_conv = new FPExtInst(float_tmp3, Type::DoubleTy, "conv", label_entry_44); + FCmpInst* int1_cmp_45 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv, const_double_27, "cmp", label_entry_44); + ExtractElementInst* float_tmp11 = new ExtractElementInst(packed_tmp0, const_int32_23, "tmp11", label_entry_44); + CastInst* double_conv12 = new FPExtInst(float_tmp11, Type::DoubleTy, "conv12", label_entry_44); + FCmpInst* int1_cmp13 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv12, const_double_27, "cmp13", label_entry_44); + SelectInst* packed_tmp1_tmp2 = new SelectInst(int1_cmp_45, packed_tmp1, packed_tmp2, "tmp1.tmp2", label_entry_44); + new BranchInst(label_cond__14, label_cond_cont20, int1_cmp13, label_entry_44); + + // Block cond.?14 (label_cond__14) + ShuffleVectorInst* packed_tmp233 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp1, const_packed_28, "tmp233", label_cond__14); + ExtractElementInst* float_tmp254 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp254", label_cond__14); + CastInst* double_conv265 = new FPExtInst(float_tmp254, Type::DoubleTy, "conv265", label_cond__14); + FCmpInst* int1_cmp276 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv265, const_double_27, "cmp276", label_cond__14); + new BranchInst(label_cond__28, label_cond_cont34, int1_cmp276, label_cond__14); + + // Block cond.cont20 (label_cond_cont20) + ShuffleVectorInst* packed_tmp23 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp2, const_packed_28, "tmp23", label_cond_cont20); + ExtractElementInst* float_tmp25 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp25", label_cond_cont20); + CastInst* double_conv26 = new FPExtInst(float_tmp25, Type::DoubleTy, "conv26", label_cond_cont20); + FCmpInst* int1_cmp27 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv26, const_double_27, "cmp27", label_cond_cont20); + new BranchInst(label_cond__28, label_cond_cont34, int1_cmp27, label_cond_cont20); + + // Block cond.?28 (label_cond__28) + PHINode* packed_tmp23_reg2mem_0 = new PHINode(VectorTy_4, "tmp23.reg2mem.0", label_cond__28); + packed_tmp23_reg2mem_0->reserveOperandSpace(2); + packed_tmp23_reg2mem_0->addIncoming(packed_tmp233, label_cond__14); + packed_tmp23_reg2mem_0->addIncoming(packed_tmp23, label_cond_cont20); + + ShuffleVectorInst* packed_tmp378 = new ShuffleVectorInst(packed_tmp23_reg2mem_0, packed_tmp1, const_packed_30, "tmp378", label_cond__28); + ExtractElementInst* float_tmp399 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp399", label_cond__28); + CastInst* double_conv4010 = new FPExtInst(float_tmp399, Type::DoubleTy, "conv4010", label_cond__28); + FCmpInst* int1_cmp4111 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv4010, const_double_27, "cmp4111", label_cond__28); + new BranchInst(label_cond__42, label_cond_cont48, int1_cmp4111, label_cond__28); + + // Block cond.cont34 (label_cond_cont34) + PHINode* packed_tmp23_reg2mem_1 = new PHINode(VectorTy_4, "tmp23.reg2mem.1", label_cond_cont34); + packed_tmp23_reg2mem_1->reserveOperandSpace(2); + packed_tmp23_reg2mem_1->addIncoming(packed_tmp233, label_cond__14); + packed_tmp23_reg2mem_1->addIncoming(packed_tmp23, label_cond_cont20); + + ShuffleVectorInst* packed_tmp37 = new ShuffleVectorInst(packed_tmp23_reg2mem_1, packed_tmp2, const_packed_30, "tmp37", label_cond_cont34); + ExtractElementInst* float_tmp39 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp39", label_cond_cont34); + CastInst* double_conv40 = new FPExtInst(float_tmp39, Type::DoubleTy, "conv40", label_cond_cont34); + FCmpInst* int1_cmp41 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv40, const_double_27, "cmp41", label_cond_cont34); + new BranchInst(label_cond__42, label_cond_cont48, int1_cmp41, label_cond_cont34); + + // Block cond.?42 (label_cond__42) + PHINode* packed_tmp37_reg2mem_0 = new PHINode(VectorTy_4, "tmp37.reg2mem.0", label_cond__42); + packed_tmp37_reg2mem_0->reserveOperandSpace(2); + packed_tmp37_reg2mem_0->addIncoming(packed_tmp378, label_cond__28); + packed_tmp37_reg2mem_0->addIncoming(packed_tmp37, label_cond_cont34); + + ShuffleVectorInst* packed_tmp5113 = new ShuffleVectorInst(packed_tmp37_reg2mem_0, packed_tmp1, const_packed_32, "tmp5113", label_cond__42); + new ReturnInst(packed_tmp5113, label_cond__42); + + // Block cond.cont48 (label_cond_cont48) + PHINode* packed_tmp37_reg2mem_1 = new PHINode(VectorTy_4, "tmp37.reg2mem.1", label_cond_cont48); + packed_tmp37_reg2mem_1->reserveOperandSpace(2); + packed_tmp37_reg2mem_1->addIncoming(packed_tmp378, label_cond__28); + packed_tmp37_reg2mem_1->addIncoming(packed_tmp37, label_cond_cont34); + + ShuffleVectorInst* packed_tmp51 = new ShuffleVectorInst(packed_tmp37_reg2mem_1, packed_tmp2, const_packed_32, "tmp51", label_cond_cont48); + new ReturnInst(packed_tmp51, label_cond_cont48); + +} + +// Function: vcos (func_vcos) +{ + Function::arg_iterator args = func_vcos->arg_begin(); + Value* packed_val = args++; + packed_val->setName("val"); + + BasicBlock* label_entry_53 = new BasicBlock("entry",func_vcos,0); + + // Block entry (label_entry_53) + ExtractElementInst* float_tmp1 = new ExtractElementInst(packed_val, const_int32_19, "tmp1", label_entry_53); + CastInst* double_conv_54 = new FPExtInst(float_tmp1, Type::DoubleTy, "conv", label_entry_53); + ExtractElementInst* float_tmp3_55 = new ExtractElementInst(packed_val, const_int32_23, "tmp3", label_entry_53); + CastInst* double_conv4 = new FPExtInst(float_tmp3_55, Type::DoubleTy, "conv4", label_entry_53); + ExtractElementInst* float_tmp6_56 = new ExtractElementInst(packed_val, const_int32_25, "tmp6", label_entry_53); + CastInst* double_conv7 = new FPExtInst(float_tmp6_56, Type::DoubleTy, "conv7", label_entry_53); + ExtractElementInst* float_tmp9 = new ExtractElementInst(packed_val, const_int32_24, "tmp9", label_entry_53); + CastInst* double_conv10 = new FPExtInst(float_tmp9, Type::DoubleTy, "conv10", label_entry_53); + std::vector int32_call_params; + int32_call_params.push_back(const_ptr_34); + int32_call_params.push_back(double_conv_54); + int32_call_params.push_back(double_conv4); + int32_call_params.push_back(double_conv7); + int32_call_params.push_back(double_conv10); + CallInst* int32_call = new CallInst(func_printf, int32_call_params.begin(), int32_call_params.end(), "call", label_entry_53); + int32_call->setCallingConv(CallingConv::C); + int32_call->setTailCall(true);const ParamAttrsList *int32_call_PAL = 0; + int32_call->setParamAttrs(int32_call_PAL); + + CallInst* float_call13 = new CallInst(func_cosf, float_tmp1, "call13", label_entry_53); + float_call13->setCallingConv(CallingConv::C); + float_call13->setTailCall(true);const ParamAttrsList *float_call13_PAL = 0; + float_call13->setParamAttrs(float_call13_PAL); + + InsertElementInst* packed_tmp15 = new InsertElementInst(const_packed_35, float_call13, const_int32_19, "tmp15", label_entry_53); + CallInst* float_call18 = new CallInst(func_cosf, float_tmp1, "call18", label_entry_53); + float_call18->setCallingConv(CallingConv::C); + float_call18->setTailCall(true);const ParamAttrsList *float_call18_PAL = 0; + float_call18->setParamAttrs(float_call18_PAL); + + InsertElementInst* packed_tmp20 = new InsertElementInst(packed_tmp15, float_call18, const_int32_23, "tmp20", label_entry_53); + CallInst* float_call23 = new CallInst(func_cosf, float_tmp1, "call23", label_entry_53); + float_call23->setCallingConv(CallingConv::C); + float_call23->setTailCall(true);const ParamAttrsList *float_call23_PAL = 0; + float_call23->setParamAttrs(float_call23_PAL); + + InsertElementInst* packed_tmp25 = new InsertElementInst(packed_tmp20, float_call23, const_int32_25, "tmp25", label_entry_53); + CallInst* float_call28 = new CallInst(func_cosf, float_tmp1, "call28", label_entry_53); + float_call28->setCallingConv(CallingConv::C); + float_call28->setTailCall(true);const ParamAttrsList *float_call28_PAL = 0; + float_call28->setParamAttrs(float_call28_PAL); + + InsertElementInst* packed_tmp30 = new InsertElementInst(packed_tmp25, float_call28, const_int32_24, "tmp30", label_entry_53); + CastInst* double_conv33 = new FPExtInst(float_call13, Type::DoubleTy, "conv33", label_entry_53); + CastInst* double_conv36 = new FPExtInst(float_call18, Type::DoubleTy, "conv36", label_entry_53); + CastInst* double_conv39 = new FPExtInst(float_call23, Type::DoubleTy, "conv39", label_entry_53); + CastInst* double_conv42 = new FPExtInst(float_call28, Type::DoubleTy, "conv42", label_entry_53); + std::vector int32_call43_params; + int32_call43_params.push_back(const_ptr_36); + int32_call43_params.push_back(double_conv33); + int32_call43_params.push_back(double_conv36); + int32_call43_params.push_back(double_conv39); + int32_call43_params.push_back(double_conv42); + CallInst* int32_call43 = new CallInst(func_printf, int32_call43_params.begin(), int32_call43_params.end(), "call43", label_entry_53); + int32_call43->setCallingConv(CallingConv::C); + int32_call43->setTailCall(true);const ParamAttrsList *int32_call43_PAL = 0; + int32_call43->setParamAttrs(int32_call43_PAL); + + new ReturnInst(packed_tmp30, label_entry_53); + +} + +// Function: scs (func_scs) +{ + Function::arg_iterator args = func_scs->arg_begin(); + Value* packed_val_58 = args++; + packed_val_58->setName("val"); + + BasicBlock* label_entry_59 = new BasicBlock("entry",func_scs,0); + + // Block entry (label_entry_59) + ExtractElementInst* float_tmp2 = new ExtractElementInst(packed_val_58, const_int32_19, "tmp2", label_entry_59); + CallInst* float_call_60 = new CallInst(func_cosf, float_tmp2, "call", label_entry_59); + float_call_60->setCallingConv(CallingConv::C); + float_call_60->setTailCall(true);const ParamAttrsList *float_call_60_PAL = 0; + float_call_60->setParamAttrs(float_call_60_PAL); + + InsertElementInst* packed_tmp5 = new InsertElementInst(const_packed_35, float_call_60, const_int32_19, "tmp5", label_entry_59); + CallInst* float_call7 = new CallInst(func_sinf, float_tmp2, "call7", label_entry_59); + float_call7->setCallingConv(CallingConv::C); + float_call7->setTailCall(true);const ParamAttrsList *float_call7_PAL = 0; + float_call7->setParamAttrs(float_call7_PAL); + + InsertElementInst* packed_tmp9 = new InsertElementInst(packed_tmp5, float_call7, const_int32_23, "tmp9", label_entry_59); + new ReturnInst(packed_tmp9, label_entry_59); + +} + +// Function: vsin (func_vsin) +{ + Function::arg_iterator args = func_vsin->arg_begin(); + Value* packed_val_62 = args++; + packed_val_62->setName("val"); + + BasicBlock* label_entry_63 = new BasicBlock("entry",func_vsin,0); + + // Block entry (label_entry_63) + ExtractElementInst* float_tmp2_64 = new ExtractElementInst(packed_val_62, const_int32_19, "tmp2", label_entry_63); + CallInst* float_call_65 = new CallInst(func_sinf, float_tmp2_64, "call", label_entry_63); + float_call_65->setCallingConv(CallingConv::C); + float_call_65->setTailCall(true);const ParamAttrsList *float_call_65_PAL = 0; + float_call_65->setParamAttrs(float_call_65_PAL); + + InsertElementInst* packed_tmp6 = new InsertElementInst(const_packed_35, float_call_65, const_int32_19, "tmp6", label_entry_63); + InsertElementInst* packed_tmp9_66 = new InsertElementInst(packed_tmp6, float_call_65, const_int32_23, "tmp9", label_entry_63); + InsertElementInst* packed_tmp12 = new InsertElementInst(packed_tmp9_66, float_call_65, const_int32_25, "tmp12", label_entry_63); + InsertElementInst* packed_tmp15_67 = new InsertElementInst(packed_tmp12, float_call_65, const_int32_24, "tmp15", label_entry_63); + new ReturnInst(packed_tmp15_67, label_entry_63); + +} + +// Function: kilp (func_kilp) +{ + Function::arg_iterator args = func_kilp->arg_begin(); + Value* packed_val_69 = args++; + packed_val_69->setName("val"); + + BasicBlock* label_entry_70 = new BasicBlock("entry",func_kilp,0); + BasicBlock* label_lor_rhs = new BasicBlock("lor_rhs",func_kilp,0); + BasicBlock* label_lor_rhs5 = new BasicBlock("lor_rhs5",func_kilp,0); + BasicBlock* label_lor_rhs11 = new BasicBlock("lor_rhs11",func_kilp,0); + BasicBlock* label_UnifiedReturnBlock_71 = new BasicBlock("UnifiedReturnBlock",func_kilp,0); + + // Block entry (label_entry_70) + ExtractElementInst* float_tmp1_72 = new ExtractElementInst(packed_val_69, const_int32_19, "tmp1", label_entry_70); + FCmpInst* int1_cmp_73 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp1_72, const_float_18, "cmp", label_entry_70); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs, int1_cmp_73, label_entry_70); + + // Block lor_rhs (label_lor_rhs) + ExtractElementInst* float_tmp3_75 = new ExtractElementInst(packed_val_69, const_int32_23, "tmp3", label_lor_rhs); + FCmpInst* int1_cmp4 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp3_75, const_float_18, "cmp4", label_lor_rhs); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs5, int1_cmp4, label_lor_rhs); + + // Block lor_rhs5 (label_lor_rhs5) + ExtractElementInst* float_tmp7 = new ExtractElementInst(packed_val_69, const_int32_25, "tmp7", label_lor_rhs5); + FCmpInst* int1_cmp8 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp7, const_float_18, "cmp8", label_lor_rhs5); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs11, int1_cmp8, label_lor_rhs5); + + // Block lor_rhs11 (label_lor_rhs11) + ExtractElementInst* float_tmp13 = new ExtractElementInst(packed_val_69, const_int32_24, "tmp13", label_lor_rhs11); + FCmpInst* int1_cmp14 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp13, const_float_18, "cmp14", label_lor_rhs11); + CastInst* int32_retval = new ZExtInst(int1_cmp14, IntegerType::get(32), "retval", label_lor_rhs11); + new ReturnInst(int32_retval, label_lor_rhs11); + + // Block UnifiedReturnBlock (label_UnifiedReturnBlock_71) + new ReturnInst(const_int32_23, label_UnifiedReturnBlock_71); + +} + +return mod; + +} diff --git a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp new file mode 100644 index 0000000000..8f9830d0b1 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp @@ -0,0 +1,202 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "instructions.h" +#include "loweringpass.h" +#include "storage.h" +#include "tgsitollvm.h" + +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_dump.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct gallivm_cpu_engine { + llvm::ExecutionEngine *engine; +}; + +static struct gallivm_cpu_engine *CPU = 0; + +typedef int (*fragment_shader_runner)(float x, float y, + float (*dests)[16][4], + float (*inputs)[16][4], + int num_attribs, + float (*consts)[4], int num_consts, + struct tgsi_sampler *samplers); + +int gallivm_cpu_fs_exec(struct gallivm_prog *prog, + float fx, float fy, + float (*dests)[16][4], + float (*inputs)[16][4], + float (*consts)[4], + struct tgsi_sampler *samplers) +{ + fragment_shader_runner runner = reinterpret_cast(prog->function); + assert(runner); + + return runner(fx, fy, dests, inputs, prog->num_interp, + consts, prog->num_consts, + samplers); +} + +static inline llvm::Function *func_for_shader(struct gallivm_prog *prog) +{ + llvm::Module *mod = prog->module; + llvm::Function *func = 0; + + switch (prog->type) { + case GALLIVM_VS: + func = mod->getFunction("vs_shader"); + break; + case GALLIVM_FS: + func = mod->getFunction("fs_shader"); + break; + default: + assert(!"Unknown shader type!"); + break; + } + return func; +} + +/*! + This function creates a CPU based execution engine for the given gallivm_prog. + gallivm_cpu_engine should be used as a singleton throughout the library. Before + executing gallivm_prog_exec one needs to call gallivm_cpu_jit_compile. + The gallivm_prog instance which is being passed to the constructor is being + automatically JIT compiled so one shouldn't call gallivm_cpu_jit_compile + with it again. + */ +struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog) +{ + struct gallivm_cpu_engine *cpu = (struct gallivm_cpu_engine *) + calloc(1, sizeof(struct gallivm_cpu_engine)); + llvm::Module *mod = static_cast(prog->module); + llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); + llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false); + ee->DisableLazyCompilation(); + cpu->engine = ee; + + llvm::Function *func = func_for_shader(prog); + + prog->function = ee->getPointerToFunction(func); + CPU = cpu; + return cpu; +} + + +/*! + This function JIT compiles the given gallivm_prog with the given cpu based execution engine. + The reference to the generated machine code entry point will be stored + in the gallivm_prog program. After executing this function one can call gallivm_prog_exec + in order to execute the gallivm_prog on the CPU. + */ +void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog *prog) +{ + llvm::Module *mod = static_cast(prog->module); + llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); + llvm::ExecutionEngine *ee = cpu->engine; + assert(ee); + /*FIXME : remove */ + ee->DisableLazyCompilation(); + ee->addModuleProvider(mp); + + llvm::Function *func = func_for_shader(prog); + prog->function = ee->getPointerToFunction(func); +} + +void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu) +{ + free(cpu); +} + +struct gallivm_cpu_engine * gallivm_global_cpu_engine() +{ + return CPU; +} + + +typedef void (*vertex_shader_runner)(void *ainputs, + void *dests, + float (*aconsts)[4], + void *temps); + + +/*! + This function is used to execute the gallivm_prog in software. Before calling + this function the gallivm_prog has to be JIT compiled with the gallivm_cpu_jit_compile + function. + */ +int gallivm_cpu_vs_exec(struct gallivm_prog *prog, + struct tgsi_exec_vector *inputs, + struct tgsi_exec_vector *dests, + float (*consts)[4], + struct tgsi_exec_vector *temps) +{ + vertex_shader_runner runner = reinterpret_cast(prog->function); + assert(runner); + /*FIXME*/ + runner(inputs, dests, consts, temps); + + return 0; +} + +#endif diff --git a/src/gallium/auxiliary/gallivm/gallivm_p.h b/src/gallium/auxiliary/gallivm/gallivm_p.h new file mode 100644 index 0000000000..cfe7b1901b --- /dev/null +++ b/src/gallium/auxiliary/gallivm/gallivm_p.h @@ -0,0 +1,110 @@ +#ifndef GALLIVM_P_H +#define GALLIVM_P_H + +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_compiler.h" + +namespace llvm { + class Module; +} + +#if defined __cplusplus +extern "C" { +#endif + +enum gallivm_shader_type; +enum gallivm_vector_layout; + +struct gallivm_interpolate { + int attrib; + int chan; + int type; +}; + +struct gallivm_ir { + llvm::Module *module; + int id; + enum gallivm_shader_type type; + enum gallivm_vector_layout layout; + int num_components; + int num_consts; + + //FIXME: this might not be enough for some shaders + struct gallivm_interpolate interpolators[32*4]; + int num_interp; +}; + +struct gallivm_prog { + llvm::Module *module; + void *function; + + int id; + enum gallivm_shader_type type; + + int num_consts; + + //FIXME: this might not be enough for some shaders + struct gallivm_interpolate interpolators[32*4]; + int num_interp; +}; + +static INLINE void gallivm_swizzle_components(int swizzle, + int *xc, int *yc, + int *zc, int *wc) +{ + int x = swizzle / 1000; swizzle -= x * 1000; + int y = swizzle / 100; swizzle -= y * 100; + int z = swizzle / 10; swizzle -= z * 10; + int w = swizzle; + + if (xc) *xc = x; + if (yc) *yc = y; + if (zc) *zc = z; + if (wc) *wc = w; +} + +static INLINE boolean gallivm_is_swizzle(int swizzle) +{ + const int NO_SWIZZLE = TGSI_SWIZZLE_X * 1000 + TGSI_SWIZZLE_Y * 100 + + TGSI_SWIZZLE_Z * 10 + TGSI_SWIZZLE_W; + return swizzle != NO_SWIZZLE; +} + +static INLINE int gallivm_x_swizzle(int swizzle) +{ + int x; + gallivm_swizzle_components(swizzle, &x, 0, 0, 0); + return x; +} + +static INLINE int gallivm_y_swizzle(int swizzle) +{ + int y; + gallivm_swizzle_components(swizzle, 0, &y, 0, 0); + return y; +} + +static INLINE int gallivm_z_swizzle(int swizzle) +{ + int z; + gallivm_swizzle_components(swizzle, 0, 0, &z, 0); + return z; +} + +static INLINE int gallivm_w_swizzle(int swizzle) +{ + int w; + gallivm_swizzle_components(swizzle, 0, 0, 0, &w); + return w; +} + +#endif /* MESA_LLVM */ + +#if defined __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp new file mode 100644 index 0000000000..55d39fa5f1 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -0,0 +1,889 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "instructions.h" + +#include "storage.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace llvm; + +#include "gallivm_builtins.cpp" + +static inline std::string createFuncName(int label) +{ + std::ostringstream stream; + stream << "function"; + stream << label; + return stream.str(); +} + +Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, + Storage *storage) + : m_mod(mod), m_func(func), m_builder(block), m_idx(0), + m_storage(storage) +{ + m_floatVecType = VectorType::get(Type::FloatTy, 4); + + m_llvmFSqrt = 0; + m_llvmFAbs = 0; + m_llvmPow = 0; + m_llvmFloor = 0; + m_llvmFlog = 0; + m_llvmLit = 0; + m_fmtPtr = 0; + + createGallivmBuiltins(m_mod); +} + +llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2) +{ + return m_builder.CreateAdd(in1, in2, name("add")); +} + +llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3) +{ + Value *mulRes = mul(in1, in2); + return add(mulRes, in3); +} + +llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2) +{ + return m_builder.CreateMul(in1, in2, name("mul")); +} + +const char * Instructions::name(const char *prefix) +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + Value *x = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(0), + name("extractx")); + Value *y = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(1), + name("extracty")); + Value *z = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(2), + name("extractz")); + Value *xy = m_builder.CreateAdd(x, y,name("xy")); + Value *dot3 = m_builder.CreateAdd(xy, z, name("dot3")); + return vectorFromVals(dot3, dot3, dot3, dot3); +} + +llvm::Value *Instructions::callFSqrt(llvm::Value *val) +{ + if (!m_llvmFSqrt) { + // predeclare the intrinsic + std::vector fsqrtArgs; + fsqrtArgs.push_back(Type::FloatTy); + ParamAttrsList *fsqrtPal = 0; + FunctionType* fsqrtType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/fsqrtArgs, + /*isVarArg=*/false); + m_llvmFSqrt = new Function( + /*Type=*/fsqrtType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"llvm.sqrt.f32", m_mod); + m_llvmFSqrt->setCallingConv(CallingConv::C); + m_llvmFSqrt->setParamAttrs(fsqrtPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFSqrt, val, + name("sqrt")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::rsq(llvm::Value *in1) +{ + Value *x = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("extractx")); + Value *abs = callFAbs(x); + Value *sqrt = callFSqrt(abs); + + Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, + APFloat(1.f)), + sqrt, + name("rsqrt")); + return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt); +} + +llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w) +{ + Constant *const_vec = Constant::getNullValue(m_floatVecType); + Value *res = m_builder.CreateInsertElement(const_vec, x, + m_storage->constantInt(0), + name("vecx")); + res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), + name("vecxy")); + res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), + name("vecxyz")); + if (w) + res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), + name("vecxyzw")); + return res; +} + +llvm::Value *Instructions::callFAbs(llvm::Value *val) +{ + if (!m_llvmFAbs) { + // predeclare the intrinsic + std::vector fabsArgs; + fabsArgs.push_back(Type::FloatTy); + ParamAttrsList *fabsPal = 0; + FunctionType* fabsType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/fabsArgs, + /*isVarArg=*/false); + m_llvmFAbs = new Function( + /*Type=*/fabsType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"fabs", m_mod); + m_llvmFAbs->setCallingConv(CallingConv::C); + m_llvmFAbs->setParamAttrs(fabsPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFAbs, val, + name("fabs")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::lit(llvm::Value *in) +{ + if (!m_llvmLit) { + m_llvmLit = m_mod->getFunction("lit"); + } + CallInst *call = m_builder.CreateCall(m_llvmLit, in, name("litres")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2) +{ + Value *res = m_builder.CreateSub(in1, in2, name("sub")); + return res; +} + +llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2) +{ + if (!m_llvmPow) { + // predeclare the intrinsic + std::vector powArgs; + powArgs.push_back(Type::FloatTy); + powArgs.push_back(Type::FloatTy); + ParamAttrsList *powPal = 0; + FunctionType* powType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/powArgs, + /*isVarArg=*/false); + m_llvmPow = new Function( + /*Type=*/powType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"llvm.pow.f32", m_mod); + m_llvmPow->setCallingConv(CallingConv::C); + m_llvmPow->setParamAttrs(powPal); + } + std::vector params; + params.push_back(val1); + params.push_back(val2); + CallInst *call = m_builder.CreateCall(m_llvmPow, params.begin(), params.end(), + name("pow")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *x2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(0), + name("x2")); + llvm::Value *val = callPow(x1, x2); + return vectorFromVals(val, val, val, val); +} + +llvm::Value * Instructions::rcp(llvm::Value *in1) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *res = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, + APFloat(1.f)), + x1, name("rcp")); + return vectorFromVals(res, res, res, res); +} + +llvm::Value * Instructions::dp4(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + std::vector vec = extractVector(mulRes); + Value *xy = m_builder.CreateAdd(vec[0], vec[1], name("xy")); + Value *xyz = m_builder.CreateAdd(xy, vec[2], name("xyz")); + Value *dot4 = m_builder.CreateAdd(xyz, vec[3], name("dot4")); + return vectorFromVals(dot4, dot4, dot4, dot4); +} + +llvm::Value * Instructions::dph(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + std::vector vec1 = extractVector(mulRes); + Value *xy = m_builder.CreateAdd(vec1[0], vec1[1], name("xy")); + Value *xyz = m_builder.CreateAdd(xy, vec1[2], name("xyz")); + Value *dph = m_builder.CreateAdd(xyz, vec1[3], name("dph")); + return vectorFromVals(dph, dph, dph, dph); +} + +llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2) +{ + Value *y1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(1), + name("y1")); + Value *z = m_builder.CreateExtractElement(in1, + m_storage->constantInt(2), + name("z")); + Value *y2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(1), + name("y2")); + Value *w = m_builder.CreateExtractElement(in2, + m_storage->constantInt(3), + name("w")); + Value *ry = m_builder.CreateMul(y1, y2, name("tyuy")); + return vectorFromVals(ConstantFP::get(Type::FloatTy, APFloat(1.f)), + ry, z, w); +} + +llvm::Value * Instructions::ex2(llvm::Value *in) +{ + llvm::Value *val = callPow(ConstantFP::get(Type::FloatTy, APFloat(2.f)), + m_builder.CreateExtractElement( + in, m_storage->constantInt(0), + name("x1"))); + return vectorFromVals(val, val, val, val); +} + +llvm::Value * Instructions::callFloor(llvm::Value *val) +{ + if (!m_llvmFloor) { + // predeclare the intrinsic + std::vector floorArgs; + floorArgs.push_back(Type::FloatTy); + ParamAttrsList *floorPal = 0; + FunctionType* floorType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/floorArgs, + /*isVarArg=*/false); + m_llvmFloor = new Function( + /*Type=*/floorType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"floorf", m_mod); + m_llvmFloor->setCallingConv(CallingConv::C); + m_llvmFloor->setParamAttrs(floorPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFloor, val, + name("floorf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::floor(llvm::Value *in) +{ + std::vector vec = extractVector(in); + return vectorFromVals(callFloor(vec[0]), callFloor(vec[1]), + callFloor(vec[2]), callFloor(vec[3])); +} + +llvm::Value * Instructions::arl(llvm::Value *in) +{ + return floor(in); +} + +llvm::Value * Instructions::frc(llvm::Value *in) +{ + llvm::Value *flr = floor(in); + return sub(in, flr); +} + +llvm::Value * Instructions::callFLog(llvm::Value *val) +{ + if (!m_llvmFlog) { + // predeclare the intrinsic + std::vector flogArgs; + flogArgs.push_back(Type::FloatTy); + ParamAttrsList *flogPal = 0; + FunctionType* flogType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/flogArgs, + /*isVarArg=*/false); + m_llvmFlog = new Function( + /*Type=*/flogType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"logf", m_mod); + m_llvmFlog->setCallingConv(CallingConv::C); + m_llvmFlog->setParamAttrs(flogPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFlog, val, + name("logf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::lg2(llvm::Value *in) +{ + std::vector vec = extractVector(in); + llvm::Value *const_vec = constVector(1.442695f, 1.442695f, + 1.442695f, 1.442695f); + return mul(vectorFromVals(callFLog(vec[0]), callFLog(vec[1]), + callFLog(vec[2]), callFLog(vec[3])), const_vec); +} + +llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2) +{ + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); + Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], + name("selx")); + + Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); + Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], + name("sely")); + + Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); + Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], + name("selz")); + + Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); + Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], + name("selw")); + + return vectorFromVals(selx, sely, selz, selw); +} + +llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2) +{ + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], + name("xcmp")); + Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], + name("selx")); + + Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], + name("ycmp")); + Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], + name("sely")); + + Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], + name("zcmp")); + Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], + name("selz")); + + Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], + name("wcmp")); + Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], + name("selw")); + + return vectorFromVals(selx, sely, selz, selw); +} + +void Instructions::printVector(llvm::Value *val) +{ + static const char *frmt = "Vector is [%f, %f, %f, %f]\x0A"; + + if (!m_fmtPtr) { + Constant *format = ConstantArray::get(frmt, true); + ArrayType *arrayTy = ArrayType::get(IntegerType::get(8), strlen(frmt) + 1); + GlobalVariable* globalFormat = new GlobalVariable( + /*Type=*/arrayTy, + /*isConstant=*/true, + /*Linkage=*/GlobalValue::InternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name(".str"), + m_mod); + globalFormat->setInitializer(format); + + Constant* const_int0 = Constant::getNullValue(IntegerType::get(32)); + std::vector const_ptr_21_indices; + const_ptr_21_indices.push_back(const_int0); + const_ptr_21_indices.push_back(const_int0); + m_fmtPtr = ConstantExpr::getGetElementPtr(globalFormat, + &const_ptr_21_indices[0], const_ptr_21_indices.size()); + } + + Function *func_printf = m_mod->getFunction("printf"); + if (!func_printf) + func_printf = declarePrintf(); + assert(func_printf); + std::vector vec = extractVector(val); + Value *dx = m_builder.CreateFPExt(vec[0], Type::DoubleTy, name("dx")); + Value *dy = m_builder.CreateFPExt(vec[1], Type::DoubleTy, name("dy")); + Value *dz = m_builder.CreateFPExt(vec[2], Type::DoubleTy, name("dz")); + Value *dw = m_builder.CreateFPExt(vec[3], Type::DoubleTy, name("dw")); + std::vector params; + params.push_back(m_fmtPtr); + params.push_back(dx); + params.push_back(dy); + params.push_back(dz); + params.push_back(dw); + CallInst *call = m_builder.CreateCall(func_printf, params.begin(), params.end(), + name("printf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(true); +} + +llvm::Function * Instructions::declarePrintf() +{ + std::vector args; + ParamAttrsList *params = 0; + FunctionType* funcTy = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/args, + /*isVarArg=*/true); + Function* func_printf = new Function( + /*Type=*/funcTy, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"printf", m_mod); + func_printf->setCallingConv(CallingConv::C); + func_printf->setParamAttrs(params); + return func_printf; +} + + +llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} +llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} + + +llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} + +llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *y1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(1), + name("y1")); + Value *z1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(2), + name("z1")); + + Value *x2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(0), + name("x2")); + Value *y2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(1), + name("y2")); + Value *z2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(2), + name("z2")); + Value *y1z2 = mul(y1, z2); + Value *z1y2 = mul(z1, y2); + + Value *z1x2 = mul(z1, x2); + Value *x1z2 = mul(x1, z2); + + Value *x1y2 = mul(x1, y2); + Value *y1x2 = mul(y1, x2); + + return vectorFromVals(sub(y1z2, z1y2), sub(z1x2, x1z2), sub(x1y2, y1x2)); +} + + +llvm::Value * Instructions::abs(llvm::Value *in) +{ + std::vector vec = extractVector(in); + Value *xabs = callFAbs(vec[0]); + Value *yabs = callFAbs(vec[1]); + Value *zabs = callFAbs(vec[2]); + Value *wabs = callFAbs(vec[3]); + return vectorFromVals(xabs, yabs, zabs, wabs); +} + +void Instructions::ifop(llvm::Value *in) +{ + BasicBlock *ifthen = new BasicBlock(name("ifthen"), m_func,0); + BasicBlock *ifend = new BasicBlock(name("ifthenend"), m_func,0); + + //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0); + //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0); + //BasicBlock *wblock = new BasicBlock(name("wblock"), m_func,0); + + Constant *float0 = Constant::getNullValue(Type::FloatTy); + + Value *x = m_builder.CreateExtractElement(in, m_storage->constantInt(0), + name("extractx")); + Value *xcmp = m_builder.CreateFCmpUNE(x, float0, name("xcmp")); + m_builder.CreateCondBr(xcmp, ifthen, ifend); + //m_builder.SetInsertPoint(yblock); + + m_builder.SetInsertPoint(ifthen); + m_ifStack.push(ifend); +} + +llvm::BasicBlock * Instructions::currentBlock() const +{ + return m_builder.GetInsertBlock(); +} + +void Instructions::elseop() +{ + assert(!m_ifStack.empty()); + BasicBlock *ifend = new BasicBlock(name("ifend"), m_func,0); + m_builder.CreateBr(ifend); + m_builder.SetInsertPoint(m_ifStack.top()); + currentBlock()->setName(name("ifelse")); + m_ifStack.pop(); + m_ifStack.push(ifend); +} + +void Instructions::endif() +{ + assert(!m_ifStack.empty()); + m_builder.CreateBr(m_ifStack.top()); + m_builder.SetInsertPoint(m_ifStack.top()); + m_ifStack.pop(); +} + +llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3) +{ + llvm::Value *m = mul(in1, in2); + llvm::Value *vec1 = constVector(1.f, 1.f, 1.f, 1.f); + llvm::Value *s = sub(vec1, in1); + return add(m, mul(s, in3)); +} + +void Instructions::beginLoop() +{ + BasicBlock *begin = new BasicBlock(name("loop"), m_func,0); + BasicBlock *end = new BasicBlock(name("endloop"), m_func,0); + + m_builder.CreateBr(begin); + Loop loop; + loop.begin = begin; + loop.end = end; + m_builder.SetInsertPoint(begin); + m_loopStack.push(loop); +} + +void Instructions::endLoop() +{ + assert(!m_loopStack.empty()); + Loop loop = m_loopStack.top(); + m_builder.CreateBr(loop.begin); + loop.end->moveAfter(currentBlock()); + m_builder.SetInsertPoint(loop.end); + m_loopStack.pop(); +} + +void Instructions::brk() +{ + assert(!m_loopStack.empty()); + BasicBlock *unr = new BasicBlock(name("unreachable"), m_func,0); + m_builder.CreateBr(m_loopStack.top().end); + m_builder.SetInsertPoint(unr); +} + +llvm::Value * Instructions::trunc(llvm::Value *in) +{ + std::vector vec = extractVector(in); + Value *icastx = m_builder.CreateFPToSI(vec[0], IntegerType::get(32), + name("ftoix")); + Value *icasty = m_builder.CreateFPToSI(vec[1], IntegerType::get(32), + name("ftoiy")); + Value *icastz = m_builder.CreateFPToSI(vec[2], IntegerType::get(32), + name("ftoiz")); + Value *icastw = m_builder.CreateFPToSI(vec[3], IntegerType::get(32), + name("ftoiw")); + Value *fx = m_builder.CreateSIToFP(icastx, Type::FloatTy, + name("fx")); + Value *fy = m_builder.CreateSIToFP(icasty, Type::FloatTy, + name("fy")); + Value *fz = m_builder.CreateSIToFP(icastz, Type::FloatTy, + name("fz")); + Value *fw = m_builder.CreateSIToFP(icastw, Type::FloatTy, + name("fw")); + return vectorFromVals(fx, fy, fz, fw); +} + +void Instructions::end() +{ + m_builder.CreateRetVoid(); +} + +void Instructions::cal(int label, llvm::Value *input) +{ + std::vector params; + params.push_back(input); + llvm::Function *func = findFunction(label); + + m_builder.CreateCall(func, params.begin(), params.end()); +} + +llvm::Function * Instructions::declareFunc(int label) +{ + PointerType *vecPtr = PointerType::getUnqual(m_floatVecType); + std::vector args; + args.push_back(vecPtr); + args.push_back(vecPtr); + args.push_back(vecPtr); + args.push_back(vecPtr); + ParamAttrsList *params = 0; + FunctionType *funcType = FunctionType::get( + /*Result=*/Type::VoidTy, + /*Params=*/args, + /*isVarArg=*/false); + std::string name = createFuncName(label); + Function *func = new Function( + /*Type=*/funcType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/name.c_str(), m_mod); + func->setCallingConv(CallingConv::C); + func->setParamAttrs(params); + return func; +} + +void Instructions::bgnSub(unsigned label) +{ + llvm::Function *func = findFunction(label); + + Function::arg_iterator args = func->arg_begin(); + Value *ptr_INPUT = args++; + ptr_INPUT->setName("INPUT"); + m_storage->pushArguments(ptr_INPUT); + + llvm::BasicBlock *entry = new BasicBlock("entry", func, 0); + + m_func = func; + m_builder.SetInsertPoint(entry); +} + +void Instructions::endSub() +{ + m_func = 0; + m_builder.SetInsertPoint(0); +} + +llvm::Function * Instructions::findFunction(int label) +{ + llvm::Function *func = m_functions[label]; + if (!func) { + func = declareFunc(label); + m_functions[label] = func; + } + return func; +} + +llvm::Value * Instructions::constVector(float x, float y, float z, float w) +{ + std::vector vec(4); + vec[0] = ConstantFP::get(Type::FloatTy, APFloat(x)); + vec[1] = ConstantFP::get(Type::FloatTy, APFloat(y)); + vec[2] = ConstantFP::get(Type::FloatTy, APFloat(z)); + vec[3] = ConstantFP::get(Type::FloatTy, APFloat(w)); + return ConstantVector::get(m_floatVecType, vec); +} + + +std::vector Instructions::extractVector(llvm::Value *vec) +{ + std::vector elems(4); + elems[0] = m_builder.CreateExtractElement(vec, m_storage->constantInt(0), + name("x")); + elems[1] = m_builder.CreateExtractElement(vec, m_storage->constantInt(1), + name("y")); + elems[2] = m_builder.CreateExtractElement(vec, m_storage->constantInt(2), + name("z")); + elems[3] = m_builder.CreateExtractElement(vec, m_storage->constantInt(3), + name("w")); + return elems; +} + +llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) +{ + llvm::Function *func = m_mod->getFunction("cmp"); + assert(func); + + std::vector params; + params.push_back(in1); + params.push_back(in2); + params.push_back(in3); + CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), name("cmpres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::cos(llvm::Value *in) +{ +#if 0 + llvm::Function *func = m_mod->getFunction("vcos"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("cosres")); + call->setTailCall(false); + return call; +#else + std::vector elems = extractVector(in); + Function *func = m_mod->getFunction("cosf"); + assert(func); + CallInst *cos = m_builder.CreateCall(func, elems[0], name("cosres")); + cos->setCallingConv(CallingConv::C); + cos->setTailCall(true); + return vectorFromVals(cos, cos, cos, cos); +#endif +} + +llvm::Value * Instructions::scs(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("scs"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("scsres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::kilp(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("kilp"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("kilpres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::sin(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("vsin"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("sinres")); + call->setTailCall(false); + return call; +} +#endif //MESA_LLVM + + diff --git a/src/gallium/auxiliary/gallivm/instructions.h b/src/gallium/auxiliary/gallivm/instructions.h new file mode 100644 index 0000000000..9ebc17dd8e --- /dev/null +++ b/src/gallium/auxiliary/gallivm/instructions.h @@ -0,0 +1,152 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef INSTRUCTIONS_H +#define INSTRUCTIONS_H + +#include +#include +#include +#include + +#include +#include + +namespace llvm { + class VectorType; + class Function; +} + +class Storage; + +class Instructions +{ +public: + Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, + Storage *storage); + + llvm::BasicBlock *currentBlock() const; + + llvm::Value *abs(llvm::Value *in1); + llvm::Value *arl(llvm::Value *in1); + llvm::Value *add(llvm::Value *in1, llvm::Value *in2); + void beginLoop(); + void bgnSub(unsigned); + void brk(); + void cal(int label, llvm::Value *input); + llvm::Value *cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); + llvm::Value *cos(llvm::Value *in); + llvm::Value *cross(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dp3(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dp4(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dph(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dst(llvm::Value *in1, llvm::Value *in2); + void elseop(); + void endif(); + void endLoop(); + void end(); + void endSub(); + llvm::Value *ex2(llvm::Value *in); + llvm::Value *floor(llvm::Value *in); + llvm::Value *frc(llvm::Value *in); + void ifop(llvm::Value *in); + llvm::Value *kilp(llvm::Value *in); + llvm::Value *lerp(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3); + llvm::Value *lit(llvm::Value *in); + llvm::Value *lg2(llvm::Value *in); + llvm::Value *madd(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in2); + llvm::Value *min(llvm::Value *in1, llvm::Value *in2); + llvm::Value *max(llvm::Value *in1, llvm::Value *in2); + llvm::Value *mul(llvm::Value *in1, llvm::Value *in2); + llvm::Value *pow(llvm::Value *in1, llvm::Value *in2); + llvm::Value *rcp(llvm::Value *in); + llvm::Value *rsq(llvm::Value *in); + llvm::Value *scs(llvm::Value *in); + llvm::Value *sge(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sgt(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sin(llvm::Value *in); + llvm::Value *slt(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sub(llvm::Value *in1, llvm::Value *in2); + llvm::Value *trunc(llvm::Value *in); + + void printVector(llvm::Value *val); +private: + const char *name(const char *prefix); + + llvm::Value *callFAbs(llvm::Value *val); + llvm::Value *callFloor(llvm::Value *val); + llvm::Value *callFSqrt(llvm::Value *val); + llvm::Value *callFLog(llvm::Value *val); + llvm::Value *callPow(llvm::Value *val1, llvm::Value *val2); + + llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w=0); + + llvm::Value *constVector(float x, float y, float z, float w); + + llvm::Function *declarePrintf(); + llvm::Function *declareFunc(int label); + + llvm::Function *findFunction(int label); + + std::vector extractVector(llvm::Value *vec); +private: + llvm::Module *m_mod; + llvm::Function *m_func; + char m_name[32]; + llvm::LLVMFoldingBuilder m_builder; + int m_idx; + + llvm::VectorType *m_floatVecType; + + llvm::Function *m_llvmFSqrt; + llvm::Function *m_llvmFAbs; + llvm::Function *m_llvmPow; + llvm::Function *m_llvmFloor; + llvm::Function *m_llvmFlog; + llvm::Function *m_llvmLit; + + llvm::Constant *m_fmtPtr; + + std::stack m_ifStack; + struct Loop { + llvm::BasicBlock *begin; + llvm::BasicBlock *end; + }; + std::stack m_loopStack; + std::map m_functions; + Storage *m_storage; +}; + +#endif diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp new file mode 100644 index 0000000000..a4d5046637 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -0,0 +1,121 @@ +#include "instructionssoa.h" + +#include "storagesoa.h" + +#include + +using namespace llvm; + +InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, + llvm::BasicBlock *block, StorageSoa *storage) + : m_builder(block), + m_storage(storage), + m_idx(0) +{ +} + +const char * InstructionsSoa::name(const char *prefix) const +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + Constant *constVector = Constant::getNullValue(vectorType); + Value *res = m_builder.CreateInsertElement(constVector, x, + m_storage->constantInt(0), + name("vecx")); + res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), + name("vecxy")); + res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), + name("vecxyz")); + if (w) + res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), + name("vecxyzw")); + return res; +} + +std::vector InstructionsSoa::arl(const std::vector in) +{ + std::vector res(4); + + //Extract x's + llvm::Value *x1 = m_builder.CreateExtractElement(in[0], + m_storage->constantInt(0), + name("extractX")); + //cast it to an unsigned int + x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast")); + + res[0] = x1;//vectorFromVals(x1, x2, x3, x4); + //only x is valid. the others shouldn't be necessary + /* + res[1] = Constant::getNullValue(m_floatVecType); + res[2] = Constant::getNullValue(m_floatVecType); + res[3] = Constant::getNullValue(m_floatVecType); + */ + + return res; +} + + +std::vector InstructionsSoa::add(const std::vector in1, + const std::vector in2) +{ + std::vector res(4); + + res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx")); + res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy")); + res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz")); + res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw")); + + return res; +} + +std::vector InstructionsSoa::mul(const std::vector in1, + const std::vector in2) +{ + std::vector res(4); + + res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx")); + res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly")); + res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz")); + res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw")); + + return res; +} + +void InstructionsSoa::end() +{ + m_builder.CreateRetVoid(); +} + +std::vector InstructionsSoa::madd(const std::vector in1, + const std::vector in2, + const std::vector in3) +{ + std::vector res = mul(in1, in2); + return add(res, in3); +} + +std::vector InstructionsSoa::extractVector(llvm::Value *vector) +{ + std::vector res(4); + res[0] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(0), + name("extract1X")); + res[1] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(1), + name("extract2X")); + res[2] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(2), + name("extract3X")); + res[3] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(3), + name("extract4X")); + + return res; +} diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h new file mode 100644 index 0000000000..4169dcbb2e --- /dev/null +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -0,0 +1,74 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INSTRUCTIONSSOA_H +#define INSTRUCTIONSSOA_H + +#include + +#include + +namespace llvm { + class Module; + class Function; + class BasicBlock; + class Value; +} +class StorageSoa; + +class InstructionsSoa +{ +public: + InstructionsSoa(llvm::Module *mod, llvm::Function *func, + llvm::BasicBlock *block, StorageSoa *storage); + + std::vector arl(const std::vector in); + + std::vector add(const std::vector in1, + const std::vector in2); + std::vector madd(const std::vector in1, + const std::vector in2, + const std::vector in3); + std::vector mul(const std::vector in1, + const std::vector in2); + void end(); + + std::vector extractVector(llvm::Value *vector); +private: + const char * name(const char *prefix) const; + llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w); +private: + llvm::LLVMFoldingBuilder m_builder; + StorageSoa *m_storage; +private: + mutable int m_idx; + mutable char m_name[32]; +}; + + +#endif diff --git a/src/gallium/auxiliary/gallivm/llvm_builtins.c b/src/gallium/auxiliary/gallivm/llvm_builtins.c new file mode 100644 index 0000000000..4f98d754ba --- /dev/null +++ b/src/gallium/auxiliary/gallivm/llvm_builtins.c @@ -0,0 +1,115 @@ +/*clang --emit-llvm llvm_builtins.c |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=gallivm_builtins.cpp -f -for=shader -funcname=createGallivmBuiltins*/ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +typedef __attribute__(( ocu_vector_type(4) )) float float4; + +extern float powf(float a, float b); + +inline float approx(float a, float b) +{ + if (b < -128.0f) b = -128.0f; + if (b > 128.0f) b = 128.0f; + if (a < 0) a = 0; + return powf(a, b); +} + +inline float4 lit(float4 tmp) +{ + float4 result; + result.x = 1.0; + result.w = 1.0; + if (tmp.x > 0) { + result.y = tmp.x; + result.z = approx(tmp.y, tmp.w); + } else { + result.y = 0; + result.z = 0; + } + return result; +} + +inline float4 cmp(float4 tmp0, float4 tmp1, float4 tmp2) +{ + float4 result; + + result.x = (tmp0.x < 0.0) ? tmp1.x : tmp2.x; + result.y = (tmp0.y < 0.0) ? tmp1.y : tmp2.y; + result.z = (tmp0.z < 0.0) ? tmp1.z : tmp2.z; + result.w = (tmp0.w < 0.0) ? tmp1.w : tmp2.w; + + return result; +} + +extern float cosf(float val); +extern float sinf(float val); + +inline float4 vcos(float4 val) +{ + float4 result; + printf("VEC IN is %f %f %f %f\n", val.x, val.y, val.z, val.w); + result.x = cosf(val.x); + result.y = cosf(val.x); + result.z = cosf(val.x); + result.w = cosf(val.x); + printf("VEC OUT is %f %f %f %f\n", result.x, result.y, result.z, result.w); + return result; +} + +inline float4 scs(float4 val) +{ + float4 result; + float tmp = val.x; + result.x = cosf(tmp); + result.y = sinf(tmp); + return result; +} + + +inline float4 vsin(float4 val) +{ + float4 result; + float tmp = val.x; + float res = sinf(tmp); + result.x = res; + result.y = res; + result.z = res; + result.w = res; + return result; +} + +inline int kilp(float4 val) +{ + if (val.x < 0 || val.y < 0 || val.z < 0 || val.w < 0) + return 1; + else + return 0; +} diff --git a/src/gallium/auxiliary/gallivm/loweringpass.cpp b/src/gallium/auxiliary/gallivm/loweringpass.cpp new file mode 100644 index 0000000000..556dbec366 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/loweringpass.cpp @@ -0,0 +1,17 @@ +#include "loweringpass.h" + +using namespace llvm; + +char LoweringPass::ID = 0; +RegisterPass X("lowering", "Lowering Pass"); + +LoweringPass::LoweringPass() + : ModulePass((intptr_t)&ID) +{ +} + +bool LoweringPass::runOnModule(Module &m) +{ + llvm::cerr << "Hello: " << m.getModuleIdentifier() << "\n"; + return false; +} diff --git a/src/gallium/auxiliary/gallivm/loweringpass.h b/src/gallium/auxiliary/gallivm/loweringpass.h new file mode 100644 index 0000000000..f62dcf6ba7 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/loweringpass.h @@ -0,0 +1,15 @@ +#ifndef LOWERINGPASS_H +#define LOWERINGPASS_H + +#include "llvm/Pass.h" +#include "llvm/Module.h" + +struct LoweringPass : public llvm::ModulePass +{ + static char ID; + LoweringPass(); + + virtual bool runOnModule(llvm::Module &m); +}; + +#endif diff --git a/src/gallium/auxiliary/gallivm/storage.cpp b/src/gallium/auxiliary/gallivm/storage.cpp new file mode 100644 index 0000000000..c4326de8c5 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/storage.cpp @@ -0,0 +1,364 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "storage.h" + +#include "gallivm_p.h" + +#include "pipe/p_shader_tokens.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace llvm; + +Storage::Storage(llvm::BasicBlock *block, llvm::Value *input) + : m_block(block), + m_INPUT(input), + m_addrs(32), + m_idx(0) +{ + m_floatVecType = VectorType::get(Type::FloatTy, 4); + m_intVecType = VectorType::get(IntegerType::get(32), 4); + + m_undefFloatVec = UndefValue::get(m_floatVecType); + m_undefIntVec = UndefValue::get(m_intVecType); + m_extSwizzleVec = 0; + + m_numConsts = 0; +} + +//can only build vectors with all members in the [0, 9] range +llvm::Constant *Storage::shuffleMask(int vec) +{ + if (!m_extSwizzleVec) { + std::vector elems; + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); + m_extSwizzleVec = ConstantVector::get(m_floatVecType, elems); + } + + if (m_intVecs.find(vec) != m_intVecs.end()) { + return m_intVecs[vec]; + } + int origVec = vec; + Constant* const_vec = 0; + if (origVec == 0) { + const_vec = Constant::getNullValue(m_intVecType); + } else { + int x = gallivm_x_swizzle(vec); + int y = gallivm_y_swizzle(vec); + int z = gallivm_z_swizzle(vec); + int w = gallivm_w_swizzle(vec); + std::vector elems; + elems.push_back(constantInt(x)); + elems.push_back(constantInt(y)); + elems.push_back(constantInt(z)); + elems.push_back(constantInt(w)); + const_vec = ConstantVector::get(m_intVecType, elems); + } + + m_intVecs[origVec] = const_vec; + return const_vec; +} + +llvm::ConstantInt *Storage::constantInt(int idx) +{ + if (m_constInts.find(idx) != m_constInts.end()) { + return m_constInts[idx]; + } + ConstantInt *const_int = ConstantInt::get(APInt(32, idx)); + m_constInts[idx] = const_int; + return const_int; +} + +llvm::Value *Storage::inputElement(int idx, llvm::Value *indIdx) +{ + Value *val = element(InputsArg, idx, indIdx); + LoadInst *load = new LoadInst(val, name("input"), false, m_block); + load->setAlignment(8); + + return load; +} + +llvm::Value *Storage::constElement(int idx, llvm::Value *indIdx) +{ + m_numConsts = ((idx + 1) > m_numConsts) ? (idx + 1) : m_numConsts; + + Value *elem = element(ConstsArg, idx, indIdx); + LoadInst *load = new LoadInst(elem, name("const"), false, m_block); + load->setAlignment(8); + return load; +} + +llvm::Value *Storage::shuffleVector(llvm::Value *vec, int shuffle) +{ + Constant *mask = shuffleMask(shuffle); + ShuffleVectorInst *res = + new ShuffleVectorInst(vec, m_extSwizzleVec, mask, + name("shuffle"), m_block); + return res; +} + + +llvm::Value *Storage::tempElement(int idx, llvm::Value *indIdx) +{ + Value *elem = element(TempsArg, idx, indIdx); + + LoadInst *load = new LoadInst(elem, name("temp"), false, m_block); + load->setAlignment(8); + + return load; +} + +void Storage::setTempElement(int idx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = 0; + if (m_tempWriteMap[idx]) + templ = tempElement(idx); + val = maskWrite(val, mask, templ); + } + Value *elem = element(TempsArg, idx); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); + m_tempWriteMap[idx] = true; +} + +void Storage::setOutputElement(int dstIdx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = 0; + if (m_destWriteMap[dstIdx]) + templ = outputElement(dstIdx); + val = maskWrite(val, mask, templ); + } + + Value *elem = element(DestsArg, dstIdx); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); + m_destWriteMap[dstIdx] = true; +} + +llvm::Value *Storage::maskWrite(llvm::Value *src, int mask, llvm::Value *templ) +{ + llvm::Value *dst = templ; + if (!dst) + dst = Constant::getNullValue(m_floatVecType); + if ((mask & TGSI_WRITEMASK_X)) { + llvm::Value *x = new ExtractElementInst(src, unsigned(0), + name("x"), m_block); + dst = new InsertElementInst(dst, x, unsigned(0), + name("dstx"), m_block); + } + if ((mask & TGSI_WRITEMASK_Y)) { + llvm::Value *y = new ExtractElementInst(src, unsigned(1), + name("y"), m_block); + dst = new InsertElementInst(dst, y, unsigned(1), + name("dsty"), m_block); + } + if ((mask & TGSI_WRITEMASK_Z)) { + llvm::Value *z = new ExtractElementInst(src, unsigned(2), + name("z"), m_block); + dst = new InsertElementInst(dst, z, unsigned(2), + name("dstz"), m_block); + } + if ((mask & TGSI_WRITEMASK_W)) { + llvm::Value *w = new ExtractElementInst(src, unsigned(3), + name("w"), m_block); + dst = new InsertElementInst(dst, w, unsigned(3), + name("dstw"), m_block); + } + return dst; +} + +const char * Storage::name(const char *prefix) +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +int Storage::numConsts() const +{ + return m_numConsts; +} + +llvm::Value * Storage::addrElement(int idx) const +{ + Value *ret = m_addrs[idx]; + if (!ret) + return m_undefFloatVec; + return ret; +} + +void Storage::setAddrElement(int idx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = m_addrs[idx]; + val = maskWrite(val, mask, templ); + } + m_addrs[idx] = val; +} + +llvm::Value * Storage::extractIndex(llvm::Value *vec) +{ + llvm::Value *x = new ExtractElementInst(vec, unsigned(0), + name("x"), m_block); + return new FPToSIInst(x, IntegerType::get(32), name("intidx"), m_block); +} + +void Storage::setCurrentBlock(llvm::BasicBlock *block) +{ + m_block = block; +} + +llvm::Value * Storage::outputElement(int idx, llvm::Value *indIdx) +{ + Value *elem = element(DestsArg, idx, indIdx); + LoadInst *load = new LoadInst(elem, name("output"), false, m_block); + load->setAlignment(8); + + return load; +} + +llvm::Value * Storage::inputPtr() const +{ + return m_INPUT; +} + +void Storage::pushArguments(llvm::Value *input) +{ + m_argStack.push(m_INPUT); + + m_INPUT = input; +} + +void Storage::popArguments() +{ + m_INPUT = m_argStack.top(); + m_argStack.pop(); +} + +void Storage::pushTemps() +{ + m_extSwizzleVec = 0; +} + +void Storage::popTemps() +{ +} + +llvm::Value * Storage::immediateElement(int idx) +{ + return m_immediates[idx]; +} + +void Storage::addImmediate(float *val) +{ + std::vector vec(4); + vec[0] = ConstantFP::get(Type::FloatTy, APFloat(val[0])); + vec[1] = ConstantFP::get(Type::FloatTy, APFloat(val[1])); + vec[2] = ConstantFP::get(Type::FloatTy, APFloat(val[2])); + vec[3] = ConstantFP::get(Type::FloatTy, APFloat(val[3])); + m_immediates.push_back(ConstantVector::get(m_floatVecType, vec)); +} + + +llvm::Value * Storage::elemPtr(Args arg) +{ + std::vector indices; + indices.push_back(constantInt(0)); + indices.push_back(constantInt(static_cast(arg))); + GetElementPtrInst *getElem = new GetElementPtrInst(m_INPUT, + indices.begin(), + indices.end(), + name("input_ptr"), + m_block); + return new LoadInst(getElem, name("input_field"), false, m_block); +} + +llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, + llvm::Value *indIdx ) +{ + GetElementPtrInst *getElem = 0; + + if (indIdx) { + getElem = new GetElementPtrInst(ptr, + BinaryOperator::create(Instruction::Add, + indIdx, + constantInt(idx), + name("add"), + m_block), + name("field"), + m_block); + } else { + getElem = new GetElementPtrInst(ptr, + constantInt(idx), + name("field"), + m_block); + } + return getElem; +} + +llvm::Value * Storage::element(Args arg, int idx, llvm::Value *indIdx ) +{ + Value *val = elemPtr(arg); + return elemIdx(val, idx, indIdx); +} + +void Storage::setKilElement(llvm::Value *val) +{ + std::vector indices; + indices.push_back(constantInt(0)); + indices.push_back(constantInt(static_cast(KilArg))); + GetElementPtrInst *elem = new GetElementPtrInst(m_INPUT, + indices.begin(), + indices.end(), + name("kil_ptr"), + m_block); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); +} + +#endif //MESA_LLVM + + diff --git a/src/gallium/auxiliary/gallivm/storage.h b/src/gallium/auxiliary/gallivm/storage.h new file mode 100644 index 0000000000..8574f7554e --- /dev/null +++ b/src/gallium/auxiliary/gallivm/storage.h @@ -0,0 +1,133 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef STORAGE_H +#define STORAGE_H + +#include +#include +#include +#include + +namespace llvm { + class BasicBlock; + class Constant; + class ConstantInt; + class LoadInst; + class Value; + class VectorType; +} + +class Storage +{ +public: + Storage(llvm::BasicBlock *block, + llvm::Value *input); + + llvm::Value *inputPtr() const; + + void setCurrentBlock(llvm::BasicBlock *block); + + llvm::ConstantInt *constantInt(int); + llvm::Constant *shuffleMask(int vec); + llvm::Value *inputElement(int idx, llvm::Value *indIdx =0); + llvm::Value *constElement(int idx, llvm::Value *indIdx =0); + llvm::Value *outputElement(int idx, llvm::Value *indIdx =0); + llvm::Value *tempElement(int idx, llvm::Value *indIdx =0); + llvm::Value *immediateElement(int idx); + + void setOutputElement(int dstIdx, llvm::Value *val, int mask); + void setTempElement(int idx, llvm::Value *val, int mask); + + llvm::Value *addrElement(int idx) const; + void setAddrElement(int idx, llvm::Value *val, int mask); + + void setKilElement(llvm::Value *val); + + llvm::Value *shuffleVector(llvm::Value *vec, int shuffle); + + llvm::Value *extractIndex(llvm::Value *vec); + + int numConsts() const; + + void pushArguments(llvm::Value *input); + void popArguments(); + void pushTemps(); + void popTemps(); + + void addImmediate(float *val); + +private: + llvm::Value *maskWrite(llvm::Value *src, int mask, llvm::Value *templ); + const char *name(const char *prefix); + + enum Args { + DestsArg = 0, + InputsArg = 1, + TempsArg = 2, + ConstsArg = 3, + KilArg = 4 + }; + llvm::Value *elemPtr(Args arg); + llvm::Value *elemIdx(llvm::Value *ptr, int idx, + llvm::Value *indIdx = 0); + llvm::Value *element(Args arg, int idx, llvm::Value *indIdx = 0); + +private: + llvm::BasicBlock *m_block; + llvm::Value *m_INPUT; + + std::map m_constInts; + std::map m_intVecs; + std::vector m_addrs; + std::vector m_immediates; + + llvm::VectorType *m_floatVecType; + llvm::VectorType *m_intVecType; + + char m_name[32]; + int m_idx; + + int m_numConsts; + + std::map m_destWriteMap; + std::map m_tempWriteMap; + + llvm::Value *m_undefFloatVec; + llvm::Value *m_undefIntVec; + llvm::Value *m_extSwizzleVec; + + std::stack m_argStack; + std::stack > m_tempStack; +}; + +#endif diff --git a/src/gallium/auxiliary/gallivm/storagesoa.cpp b/src/gallium/auxiliary/gallivm/storagesoa.cpp new file mode 100644 index 0000000000..ed0674a96f --- /dev/null +++ b/src/gallium/auxiliary/gallivm/storagesoa.cpp @@ -0,0 +1,389 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "storagesoa.h" + +#include "gallivm_p.h" + +#include "pipe/p_shader_tokens.h" +#include "pipe/p_debug.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace llvm; + + +StorageSoa::StorageSoa(llvm::BasicBlock *block, + llvm::Value *input, + llvm::Value *output, + llvm::Value *consts, + llvm::Value *temps) + : m_block(block), + m_input(input), + m_output(output), + m_consts(consts), + m_temps(temps), + m_immediates(0), + m_idx(0) +{ +} + +void StorageSoa::addImmediate(float *vec) +{ + std::vector vals(4); + vals[0] = vec[0]; + vals[1] = vec[1]; + vals[2] = vec[2]; + vals[3] = vec[3]; + m_immediatesToFlush.push_back(vals); +} + +void StorageSoa::declareImmediates() +{ + if (m_immediatesToFlush.empty()) + return; + + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + ArrayType *vectorChannels = ArrayType::get(vectorType, 4); + ArrayType *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size()); + + m_immediates = new GlobalVariable( + /*Type=*/arrayType, + /*isConstant=*/false, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name("immediates"), + currentModule()); + + std::vector arrayVals; + for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) { + std::vector vec = m_immediatesToFlush[i]; + std::vector vals(4); + std::vector channelArray; + + vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0]; + llvm::Constant *xChannel = createConstGlobalVector(vals); + + vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1]; + llvm::Constant *yChannel = createConstGlobalVector(vals); + + vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2]; + llvm::Constant *zChannel = createConstGlobalVector(vals); + + vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3]; + llvm::Constant *wChannel = createConstGlobalVector(vals); + channelArray.push_back(xChannel); + channelArray.push_back(yChannel); + channelArray.push_back(zChannel); + channelArray.push_back(wChannel); + Constant *constChannels = ConstantArray::get(vectorChannels, + channelArray); + arrayVals.push_back(constChannels); + } + Constant *constArray = ConstantArray::get(arrayType, arrayVals); + m_immediates->setInitializer(constArray); + + m_immediatesToFlush.clear(); +} + +llvm::Value *StorageSoa::addrElement(int idx) const +{ + std::map::const_iterator itr = m_addresses.find(idx); + if (itr == m_addresses.end()) { + debug_printf("Trying to access invalid shader 'address'\n"); + return 0; + } + llvm::Value * res = (*itr).second; + + res = new LoadInst(res, name("addr"), false, m_block); + + return res; +} + +std::vector StorageSoa::inputElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_input, idx, 0); + res[1] = element(m_input, idx, 1); + res[2] = element(m_input, idx, 2); + res[3] = element(m_input, idx, 3); + + return res; +} + +std::vector StorageSoa::constElement(llvm::Value *idx) +{ + std::vector res(4); + llvm::Value *xChannel, *yChannel, *zChannel, *wChannel; + + xChannel = elementPointer(m_consts, idx, 0); + yChannel = elementPointer(m_consts, idx, 1); + zChannel = elementPointer(m_consts, idx, 2); + wChannel = elementPointer(m_consts, idx, 3); + + res[0] = alignedArrayLoad(xChannel); + res[1] = alignedArrayLoad(yChannel); + res[2] = alignedArrayLoad(zChannel); + res[3] = alignedArrayLoad(wChannel); + + return res; +} + +std::vector StorageSoa::outputElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_output, idx, 0); + res[1] = element(m_output, idx, 1); + res[2] = element(m_output, idx, 2); + res[3] = element(m_output, idx, 3); + + return res; +} + +std::vector StorageSoa::tempElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_temps, idx, 0); + res[1] = element(m_temps, idx, 1); + res[2] = element(m_temps, idx, 2); + res[3] = element(m_temps, idx, 3); + + return res; +} + +std::vector StorageSoa::immediateElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_immediates, idx, 0); + res[1] = element(m_immediates, idx, 1); + res[2] = element(m_immediates, idx, 2); + res[3] = element(m_immediates, idx, 3); + + return res; +} + +llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, llvm::Value *index, + int channel) const +{ + std::vector indices; + if (m_immediates == ptr) + indices.push_back(constantInt(0)); + indices.push_back(index); + indices.push_back(constantInt(channel)); + + GetElementPtrInst *getElem = new GetElementPtrInst(ptr, + indices.begin(), + indices.end(), + name("ptr"), + m_block); + return getElem; +} + +llvm::Value * StorageSoa::element(llvm::Value *ptr, llvm::Value *index, + int channel) const +{ + llvm::Value *res = elementPointer(ptr, index, channel); + LoadInst *load = new LoadInst(res, name("element"), false, m_block); + //load->setAlignment(8); + return load; +} + +const char * StorageSoa::name(const char *prefix) const +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::ConstantInt * StorageSoa::constantInt(int idx) const +{ + if (m_constInts.find(idx) != m_constInts.end()) { + return m_constInts[idx]; + } + ConstantInt *constInt = ConstantInt::get(APInt(32, idx)); + m_constInts[idx] = constInt; + return constInt; +} + +llvm::Value *StorageSoa::alignedArrayLoad(llvm::Value *val) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + PointerType *vectorPtr = PointerType::get(vectorType, 0); + + CastInst *cast = new BitCastInst(val, vectorPtr, name("toVector"), m_block); + LoadInst *load = new LoadInst(cast, name("alignLoad"), false, m_block); + load->setAlignment(8); + return load; +} + +llvm::Module * StorageSoa::currentModule() const +{ + if (!m_block || !m_block->getParent()) + return 0; + + return m_block->getParent()->getParent(); +} + +llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &vec) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + std::vector immValues; + ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0])); + ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1])); + ConstantFP *constz = ConstantFP::get(Type::FloatTy, APFloat(vec[2])); + ConstantFP *constw = ConstantFP::get(Type::FloatTy, APFloat(vec[3])); + immValues.push_back(constx); + immValues.push_back(consty); + immValues.push_back(constz); + immValues.push_back(constw); + Constant *constVector = ConstantVector::get(vectorType, immValues); + + return constVector; +} + +std::vector StorageSoa::load(Argument type, int idx, int swizzle, + llvm::Value *indIdx) +{ + std::vector val(4); + + //if we have an indirect index, always use that + // if not use the integer offset to create one + llvm::Value *realIndex = 0; + if (indIdx) + realIndex = indIdx; + else + realIndex = constantInt(idx); + debug_printf("XXXXXXXXX realIdx = %p, indIdx = %p\n", realIndex, indIdx); + + switch(type) { + case Input: + val = inputElement(realIndex); + break; + case Output: + val = outputElement(realIndex); + break; + case Temp: + val = tempElement(realIndex); + break; + case Const: + val = constElement(realIndex); + break; + case Immediate: + val = immediateElement(realIndex); + break; + case Address: + debug_printf("Address not handled in the load phase!\n"); + assert(0); + break; + } + if (!gallivm_is_swizzle(swizzle)) + return val; + + std::vector res(4); + + res[0] = val[gallivm_x_swizzle(swizzle)]; + res[1] = val[gallivm_y_swizzle(swizzle)]; + res[2] = val[gallivm_z_swizzle(swizzle)]; + res[3] = val[gallivm_w_swizzle(swizzle)]; + return res; +} + +void StorageSoa::store(Argument type, int idx, const std::vector &val, + int mask) +{ + llvm::Value *out = 0; + switch(type) { + case Output: + out = m_output; + break; + case Temp: + out = m_temps; + break; + case Input: + out = m_input; + break; + case Address: { + llvm::Value *addr = m_addresses[idx]; + if (!addr) { + addAddress(idx); + addr = m_addresses[idx]; + assert(addr); + } + new StoreInst(val[0], addr, false, m_block); + return; + break; + } + default: + debug_printf("Can't save output of this type: %d !\n", type); + assert(0); + break; + } + llvm::Value *realIndex = constantInt(idx); + if ((mask & TGSI_WRITEMASK_X)) { + llvm::Value *xChannel = elementPointer(out, realIndex, 0); + new StoreInst(val[0], xChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_Y)) { + llvm::Value *yChannel = elementPointer(out, realIndex, 1); + new StoreInst(val[1], yChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_Z)) { + llvm::Value *zChannel = elementPointer(out, realIndex, 2); + new StoreInst(val[2], zChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_W)) { + llvm::Value *wChannel = elementPointer(out, realIndex, 3); + new StoreInst(val[3], wChannel, false, m_block); + } +} + +void StorageSoa::addAddress(int idx) +{ + GlobalVariable *val = new GlobalVariable( + /*Type=*/IntegerType::get(32), + /*isConstant=*/false, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name("address"), + currentModule()); + val->setInitializer(Constant::getNullValue(IntegerType::get(32))); + + debug_printf("adding to %d\n", idx); + m_addresses[idx] = val; +} diff --git a/src/gallium/auxiliary/gallivm/storagesoa.h b/src/gallium/auxiliary/gallivm/storagesoa.h new file mode 100644 index 0000000000..6443351f27 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/storagesoa.h @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STORAGESOA_H +#define STORAGESOA_H + +#include +#include +#include + +namespace llvm { + class BasicBlock; + class Constant; + class ConstantInt; + class GlobalVariable; + class LoadInst; + class Value; + class VectorType; + class Module; +} + +class StorageSoa +{ +public: + enum Argument { + Input, + Output, + Temp, + Const, + Immediate, + Address + }; +public: + StorageSoa(llvm::BasicBlock *block, + llvm::Value *input, + llvm::Value *output, + llvm::Value *consts, + llvm::Value *temps); + + + std::vector load(Argument type, int idx, int swizzle, + llvm::Value *indIdx =0); + void store(Argument type, int idx, const std::vector &val, + int mask); + + void addImmediate(float *vec); + void declareImmediates(); + + void addAddress(int idx); + + llvm::Value * addrElement(int idx) const; + + llvm::ConstantInt *constantInt(int) const; +private: + llvm::Value *elementPointer(llvm::Value *ptr, llvm::Value *indIdx, + int channel) const; + llvm::Value *element(llvm::Value *ptr, llvm::Value *idx, + int channel) const; + const char *name(const char *prefix) const; + llvm::Value *alignedArrayLoad(llvm::Value *val); + llvm::Module *currentModule() const; + llvm::Constant *createConstGlobalVector(const std::vector &vec); + + std::vector inputElement(llvm::Value *indIdx); + std::vector constElement(llvm::Value *indIdx); + std::vector outputElement(llvm::Value *indIdx); + std::vector tempElement(llvm::Value *indIdx); + std::vector immediateElement(llvm::Value *indIdx); +private: + llvm::BasicBlock *m_block; + + llvm::Value *m_input; + llvm::Value *m_output; + llvm::Value *m_consts; + llvm::Value *m_temps; + llvm::GlobalVariable *m_immediates; + + std::map m_addresses; + + std::vector > m_immediatesToFlush; + + mutable std::map m_constInts; + mutable char m_name[32]; + mutable int m_idx; +}; + +#endif diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp new file mode 100644 index 0000000000..2cb4acce32 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -0,0 +1,1221 @@ +#include "tgsitollvm.h" + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "storage.h" +#include "instructions.h" +#include "storagesoa.h" +#include "instructionssoa.h" + +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_util.h" +#include "tgsi/util/tgsi_build.h" +#include "tgsi/util/tgsi_dump.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +using namespace llvm; + +static inline FunctionType *vertexShaderFunctionType() +{ + //Function takes three arguments, + // the calling code has to make sure the types it will + // pass are castable to the following: + // [4 x <4 x float>] inputs, + // [4 x <4 x float>] output, + // [4 x [4 x float]] consts, + // [4 x <4 x float>] temps + + std::vector funcArgs; + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + ArrayType *vectorArray = ArrayType::get(vectorType, 4); + PointerType *vectorArrayPtr = PointerType::get(vectorArray, 0); + + ArrayType *floatArray = ArrayType::get(Type::FloatTy, 4); + ArrayType *constsArray = ArrayType::get(floatArray, 4); + PointerType *constsArrayPtr = PointerType::get(constsArray, 0); + + funcArgs.push_back(vectorArrayPtr);//inputs + funcArgs.push_back(vectorArrayPtr);//output + funcArgs.push_back(constsArrayPtr);//consts + funcArgs.push_back(vectorArrayPtr);//temps + + FunctionType *functionType = FunctionType::get( + /*Result=*/Type::VoidTy, + /*Params=*/funcArgs, + /*isVarArg=*/false); + + return functionType; +} + +static inline void +add_interpolator(struct gallivm_ir *ir, + struct gallivm_interpolate *interp) +{ + ir->interpolators[ir->num_interp] = *interp; + ++ir->num_interp; +} + +static void +translate_declaration(struct gallivm_ir *prog, + llvm::Module *module, + Storage *storage, + struct tgsi_full_declaration *decl, + struct tgsi_full_declaration *fd) +{ + if (decl->Declaration.File == TGSI_FILE_INPUT) { + unsigned first, last, mask; + uint interp_method; + + assert(decl->Declaration.Declare == TGSI_DECLARE_RANGE); + + first = decl->u.DeclarationRange.First; + last = decl->u.DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + /* Do not touch WPOS.xy */ + if (first == 0) { + mask &= ~TGSI_WRITEMASK_XY; + if (mask == TGSI_WRITEMASK_NONE) { + first++; + if (first > last) { + return; + } + } + } + + interp_method = decl->Interpolation.Interpolate; + + if (mask == TGSI_WRITEMASK_XYZW) { + unsigned i, j; + + for (i = first; i <= last; i++) { + for (j = 0; j < NUM_CHANNELS; j++) { + //interp( mach, i, j ); + struct gallivm_interpolate interp; + interp.type = interp_method; + interp.attrib = i; + interp.chan = j; + add_interpolator(prog, &interp); + } + } + } else { + unsigned i, j; + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + for( i = first; i <= last; i++ ) { + struct gallivm_interpolate interp; + interp.type = interp_method; + interp.attrib = i; + interp.chan = j; + add_interpolator(prog, &interp); + } + } + } + } + } +} + +static void +translate_declarationir(struct gallivm_ir *, + llvm::Module *, + StorageSoa *storage, + struct tgsi_full_declaration *decl, + struct tgsi_full_declaration *) +{ + if (decl->Declaration.File == TGSI_FILE_ADDRESS) { + int idx = decl->u.DeclarationRange.First; + storage->addAddress(idx); + } +} + +static void +translate_immediate(Storage *storage, + struct tgsi_full_immediate *imm) +{ + float vec[4]; + int i; + for (i = 0; i < imm->Immediate.Size - 1; ++i) { + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + vec[i] = imm->u.ImmediateFloat32[i].Float; + break; + default: + assert(0); + } + } + storage->addImmediate(vec); +} + + +static void +translate_immediateir(StorageSoa *storage, + struct tgsi_full_immediate *imm) +{ + float vec[4]; + int i; + for (i = 0; i < imm->Immediate.Size - 1; ++i) { + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + vec[i] = imm->u.ImmediateFloat32[i].Float; + break; + default: + assert(0); + } + } + storage->addImmediate(vec); +} + +static inline int +swizzleInt(struct tgsi_full_src_register *src) +{ + int swizzle = 0; + int start = 1000; + + for (int k = 0; k < 4; ++k) { + swizzle += tgsi_util_get_full_src_register_extswizzle(src, k) * start; + start /= 10; + } + return swizzle; +} + +static inline llvm::Value * +swizzleVector(llvm::Value *val, struct tgsi_full_src_register *src, + Storage *storage) +{ + int swizzle = swizzleInt(src); + + if (gallivm_is_swizzle(swizzle)) { + /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/ + val = storage->shuffleVector(val, swizzle); + } + return val; +} + +static void +translate_instruction(llvm::Module *module, + Storage *storage, + Instructions *instr, + struct tgsi_full_instruction *inst, + struct tgsi_full_instruction *fi, + unsigned instno) +{ + llvm::Value *inputs[4]; + inputs[0] = 0; + inputs[1] = 0; + inputs[2] = 0; + inputs[3] = 0; + + for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + llvm::Value *val = 0; + llvm::Value *indIdx = 0; + + if (src->SrcRegister.Indirect) { + indIdx = storage->addrElement(src->SrcRegisterInd.Index); + indIdx = storage->extractIndex(indIdx); + } + if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { + val = storage->constElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { + val = storage->inputElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { + val = storage->tempElement(src->SrcRegister.Index); + } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { + val = storage->outputElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { + val = storage->immediateElement(src->SrcRegister.Index); + } else { + fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); + return; + } + + inputs[i] = swizzleVector(val, src, storage); + } + + /*if (inputs[0]) + instr->printVector(inputs[0]); + if (inputs[1]) + instr->printVector(inputs[1]);*/ + llvm::Value *out = 0; + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: { + out = instr->arl(inputs[0]); + } + break; + case TGSI_OPCODE_MOV: { + out = inputs[0]; + } + break; + case TGSI_OPCODE_LIT: { + out = instr->lit(inputs[0]); + } + break; + case TGSI_OPCODE_RCP: { + out = instr->rcp(inputs[0]); + } + break; + case TGSI_OPCODE_RSQ: { + out = instr->rsq(inputs[0]); + } + break; + case TGSI_OPCODE_EXP: + break; + case TGSI_OPCODE_LOG: + break; + case TGSI_OPCODE_MUL: { + out = instr->mul(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_ADD: { + out = instr->add(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP3: { + out = instr->dp3(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP4: { + out = instr->dp4(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DST: { + out = instr->dst(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MIN: { + out = instr->min(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MAX: { + out = instr->max(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SLT: { + out = instr->slt(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SGE: { + out = instr->sge(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MAD: { + out = instr->madd(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SUB: { + out = instr->sub(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_LERP: { + out = instr->lerp(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_CND: + break; + case TGSI_OPCODE_CND0: + break; + case TGSI_OPCODE_DOT2ADD: + break; + case TGSI_OPCODE_INDEX: + break; + case TGSI_OPCODE_NEGATE: + break; + case TGSI_OPCODE_FRAC: { + out = instr->frc(inputs[0]); + } + break; + case TGSI_OPCODE_CLAMP: + break; + case TGSI_OPCODE_FLOOR: { + out = instr->floor(inputs[0]); + } + break; + case TGSI_OPCODE_ROUND: + break; + case TGSI_OPCODE_EXPBASE2: { + out = instr->ex2(inputs[0]); + } + break; + case TGSI_OPCODE_LOGBASE2: { + out = instr->lg2(inputs[0]); + } + break; + case TGSI_OPCODE_POWER: { + out = instr->pow(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_CROSSPRODUCT: { + out = instr->cross(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MULTIPLYMATRIX: + break; + case TGSI_OPCODE_ABS: { + out = instr->abs(inputs[0]); + } + break; + case TGSI_OPCODE_RCC: + break; + case TGSI_OPCODE_DPH: { + out = instr->dph(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_COS: { + out = instr->cos(inputs[0]); + } + break; + case TGSI_OPCODE_DDX: + break; + case TGSI_OPCODE_DDY: + break; + case TGSI_OPCODE_KILP: { + out = instr->kilp(inputs[0]); + storage->setKilElement(out); + return; + } + break; + case TGSI_OPCODE_PK2H: + break; + case TGSI_OPCODE_PK2US: + break; + case TGSI_OPCODE_PK4B: + break; + case TGSI_OPCODE_PK4UB: + break; + case TGSI_OPCODE_RFL: + break; + case TGSI_OPCODE_SEQ: + break; + case TGSI_OPCODE_SFL: + break; + case TGSI_OPCODE_SGT: { + out = instr->sgt(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SIN: { + out = instr->sin(inputs[0]); + } + break; + case TGSI_OPCODE_SLE: + break; + case TGSI_OPCODE_SNE: + break; + case TGSI_OPCODE_STR: + break; + case TGSI_OPCODE_TEX: + break; + case TGSI_OPCODE_TXD: + break; + case TGSI_OPCODE_UP2H: + break; + case TGSI_OPCODE_UP2US: + break; + case TGSI_OPCODE_UP4B: + break; + case TGSI_OPCODE_UP4UB: + break; + case TGSI_OPCODE_X2D: + break; + case TGSI_OPCODE_ARA: + break; + case TGSI_OPCODE_ARR: + break; + case TGSI_OPCODE_BRA: + break; + case TGSI_OPCODE_CAL: { + instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr()); + return; + } + break; + case TGSI_OPCODE_RET: { + instr->end(); + return; + } + break; + case TGSI_OPCODE_SSG: + break; + case TGSI_OPCODE_CMP: { + out = instr->cmp(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SCS: { + out = instr->scs(inputs[0]); + } + break; + case TGSI_OPCODE_TXB: + break; + case TGSI_OPCODE_NRM: + break; + case TGSI_OPCODE_DIV: + break; + case TGSI_OPCODE_DP2: + break; + case TGSI_OPCODE_TXL: + break; + case TGSI_OPCODE_BRK: { + instr->brk(); + return; + } + break; + case TGSI_OPCODE_IF: { + instr->ifop(inputs[0]); + storage->setCurrentBlock(instr->currentBlock()); + return; //just update the state + } + break; + case TGSI_OPCODE_LOOP: + break; + case TGSI_OPCODE_REP: + break; + case TGSI_OPCODE_ELSE: { + instr->elseop(); + storage->setCurrentBlock(instr->currentBlock()); + return; //only state update + } + break; + case TGSI_OPCODE_ENDIF: { + instr->endif(); + storage->setCurrentBlock(instr->currentBlock()); + return; //just update the state + } + break; + case TGSI_OPCODE_ENDLOOP: + break; + case TGSI_OPCODE_ENDREP: + break; + case TGSI_OPCODE_PUSHA: + break; + case TGSI_OPCODE_POPA: + break; + case TGSI_OPCODE_CEIL: + break; + case TGSI_OPCODE_I2F: + break; + case TGSI_OPCODE_NOT: + break; + case TGSI_OPCODE_TRUNC: { + out = instr->trunc(inputs[0]); + } + break; + case TGSI_OPCODE_SHL: + break; + case TGSI_OPCODE_SHR: + break; + case TGSI_OPCODE_AND: + break; + case TGSI_OPCODE_OR: + break; + case TGSI_OPCODE_MOD: + break; + case TGSI_OPCODE_XOR: + break; + case TGSI_OPCODE_SAD: + break; + case TGSI_OPCODE_TXF: + break; + case TGSI_OPCODE_TXQ: + break; + case TGSI_OPCODE_CONT: + break; + case TGSI_OPCODE_EMIT: + break; + case TGSI_OPCODE_ENDPRIM: + break; + case TGSI_OPCODE_BGNLOOP2: { + instr->beginLoop(); + storage->setCurrentBlock(instr->currentBlock()); + return; + } + break; + case TGSI_OPCODE_BGNSUB: { + instr->bgnSub(instno); + storage->setCurrentBlock(instr->currentBlock()); + storage->pushTemps(); + return; + } + break; + case TGSI_OPCODE_ENDLOOP2: { + instr->endLoop(); + storage->setCurrentBlock(instr->currentBlock()); + return; + } + break; + case TGSI_OPCODE_ENDSUB: { + instr->endSub(); + storage->setCurrentBlock(instr->currentBlock()); + storage->popArguments(); + storage->popTemps(); + return; + } + break; + case TGSI_OPCODE_NOISE1: + break; + case TGSI_OPCODE_NOISE2: + break; + case TGSI_OPCODE_NOISE3: + break; + case TGSI_OPCODE_NOISE4: + break; + case TGSI_OPCODE_NOP: + break; + case TGSI_OPCODE_TEXBEM: + break; + case TGSI_OPCODE_TEXBEML: + break; + case TGSI_OPCODE_TEXREG2AR: + break; + case TGSI_OPCODE_TEXM3X2PAD: + break; + case TGSI_OPCODE_TEXM3X2TEX: + break; + case TGSI_OPCODE_TEXM3X3PAD: + break; + case TGSI_OPCODE_TEXM3X3TEX: + break; + case TGSI_OPCODE_TEXM3X3SPEC: + break; + case TGSI_OPCODE_TEXM3X3VSPEC: + break; + case TGSI_OPCODE_TEXREG2GB: + break; + case TGSI_OPCODE_TEXREG2RGB: + break; + case TGSI_OPCODE_TEXDP3TEX: + break; + case TGSI_OPCODE_TEXDP3: + break; + case TGSI_OPCODE_TEXM3X3: + break; + case TGSI_OPCODE_TEXM3X2DEPTH: + break; + case TGSI_OPCODE_TEXDEPTH: + break; + case TGSI_OPCODE_BEM: + break; + case TGSI_OPCODE_M4X3: + break; + case TGSI_OPCODE_M3X4: + break; + case TGSI_OPCODE_M3X3: + break; + case TGSI_OPCODE_M3X2: + break; + case TGSI_OPCODE_NRM4: + break; + case TGSI_OPCODE_CALLNZ: + break; + case TGSI_OPCODE_IFC: + break; + case TGSI_OPCODE_BREAKC: + break; + case TGSI_OPCODE_KIL: + break; + case TGSI_OPCODE_END: + instr->end(); + return; + break; + default: + fprintf(stderr, "ERROR: Unknown opcode %d\n", + inst->Instruction.Opcode); + assert(0); + break; + } + + if (!out) { + fprintf(stderr, "ERROR: unsupported opcode %d\n", + inst->Instruction.Opcode); + assert(!"Unsupported opcode"); + } + + /* # not sure if we need this */ + switch( inst->Instruction.Saturate ) { + case TGSI_SAT_NONE: + break; + case TGSI_SAT_ZERO_ONE: + /*TXT( "_SAT" );*/ + break; + case TGSI_SAT_MINUS_PLUS_ONE: + /*TXT( "_SAT[-1,1]" );*/ + break; + default: + assert( 0 ); + } + + /* store results */ + for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + + if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { + storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { + storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { + storage->setAddrElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else { + fprintf(stderr, "ERROR: unsupported LLVM destination!"); + assert(!"wrong destination"); + } + } +} + + +static void +translate_instructionir(llvm::Module *module, + StorageSoa *storage, + InstructionsSoa *instr, + struct tgsi_full_instruction *inst, + struct tgsi_full_instruction *fi, + unsigned instno) +{ + std::vector< std::vector > inputs(inst->Instruction.NumSrcRegs); + + for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + std::vector val; + llvm::Value *indIdx = 0; + int swizzle = swizzleInt(src); + + if (src->SrcRegister.Indirect) { + indIdx = storage->addrElement(src->SrcRegisterInd.Index); + } + if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { + val = storage->load(StorageSoa::Const, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { + val = storage->load(StorageSoa::Input, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { + val = storage->load(StorageSoa::Temp, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { + val = storage->load(StorageSoa::Output, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { + val = storage->load(StorageSoa::Immediate, + src->SrcRegister.Index, swizzle, indIdx); + } else { + fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); + return; + } + + inputs[i] = val; + } + + std::vector out(4); + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: { + out = instr->arl(inputs[0]); + } + break; + case TGSI_OPCODE_MOV: { + out = inputs[0]; + } + break; + case TGSI_OPCODE_LIT: { + } + break; + case TGSI_OPCODE_RCP: { + } + break; + case TGSI_OPCODE_RSQ: { + } + break; + case TGSI_OPCODE_EXP: + break; + case TGSI_OPCODE_LOG: + break; + case TGSI_OPCODE_MUL: { + out = instr->mul(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_ADD: { + out = instr->add(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP3: { + } + break; + case TGSI_OPCODE_DP4: { + } + break; + case TGSI_OPCODE_DST: { + } + break; + case TGSI_OPCODE_MIN: { + } + break; + case TGSI_OPCODE_MAX: { + } + break; + case TGSI_OPCODE_SLT: { + } + break; + case TGSI_OPCODE_SGE: { + } + break; + case TGSI_OPCODE_MAD: { + out = instr->madd(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SUB: { + } + break; + case TGSI_OPCODE_LERP: { + } + break; + case TGSI_OPCODE_CND: + break; + case TGSI_OPCODE_CND0: + break; + case TGSI_OPCODE_DOT2ADD: + break; + case TGSI_OPCODE_INDEX: + break; + case TGSI_OPCODE_NEGATE: + break; + case TGSI_OPCODE_FRAC: { + } + break; + case TGSI_OPCODE_CLAMP: + break; + case TGSI_OPCODE_FLOOR: { + } + break; + case TGSI_OPCODE_ROUND: + break; + case TGSI_OPCODE_EXPBASE2: { + } + break; + case TGSI_OPCODE_LOGBASE2: { + } + break; + case TGSI_OPCODE_POWER: { + } + break; + case TGSI_OPCODE_CROSSPRODUCT: { + } + break; + case TGSI_OPCODE_MULTIPLYMATRIX: + break; + case TGSI_OPCODE_ABS: { + } + break; + case TGSI_OPCODE_RCC: + break; + case TGSI_OPCODE_DPH: { + } + break; + case TGSI_OPCODE_COS: { + } + break; + case TGSI_OPCODE_DDX: + break; + case TGSI_OPCODE_DDY: + break; + case TGSI_OPCODE_KILP: { + } + break; + case TGSI_OPCODE_PK2H: + break; + case TGSI_OPCODE_PK2US: + break; + case TGSI_OPCODE_PK4B: + break; + case TGSI_OPCODE_PK4UB: + break; + case TGSI_OPCODE_RFL: + break; + case TGSI_OPCODE_SEQ: + break; + case TGSI_OPCODE_SFL: + break; + case TGSI_OPCODE_SGT: { + } + break; + case TGSI_OPCODE_SIN: { + } + break; + case TGSI_OPCODE_SLE: + break; + case TGSI_OPCODE_SNE: + break; + case TGSI_OPCODE_STR: + break; + case TGSI_OPCODE_TEX: + break; + case TGSI_OPCODE_TXD: + break; + case TGSI_OPCODE_UP2H: + break; + case TGSI_OPCODE_UP2US: + break; + case TGSI_OPCODE_UP4B: + break; + case TGSI_OPCODE_UP4UB: + break; + case TGSI_OPCODE_X2D: + break; + case TGSI_OPCODE_ARA: + break; + case TGSI_OPCODE_ARR: + break; + case TGSI_OPCODE_BRA: + break; + case TGSI_OPCODE_CAL: { + } + break; + case TGSI_OPCODE_RET: { + } + break; + case TGSI_OPCODE_SSG: + break; + case TGSI_OPCODE_CMP: { + } + break; + case TGSI_OPCODE_SCS: { + } + break; + case TGSI_OPCODE_TXB: + break; + case TGSI_OPCODE_NRM: + break; + case TGSI_OPCODE_DIV: + break; + case TGSI_OPCODE_DP2: + break; + case TGSI_OPCODE_TXL: + break; + case TGSI_OPCODE_BRK: { + } + break; + case TGSI_OPCODE_IF: { + } + break; + case TGSI_OPCODE_LOOP: + break; + case TGSI_OPCODE_REP: + break; + case TGSI_OPCODE_ELSE: { + } + break; + case TGSI_OPCODE_ENDIF: { + } + break; + case TGSI_OPCODE_ENDLOOP: + break; + case TGSI_OPCODE_ENDREP: + break; + case TGSI_OPCODE_PUSHA: + break; + case TGSI_OPCODE_POPA: + break; + case TGSI_OPCODE_CEIL: + break; + case TGSI_OPCODE_I2F: + break; + case TGSI_OPCODE_NOT: + break; + case TGSI_OPCODE_TRUNC: { + } + break; + case TGSI_OPCODE_SHL: + break; + case TGSI_OPCODE_SHR: + break; + case TGSI_OPCODE_AND: + break; + case TGSI_OPCODE_OR: + break; + case TGSI_OPCODE_MOD: + break; + case TGSI_OPCODE_XOR: + break; + case TGSI_OPCODE_SAD: + break; + case TGSI_OPCODE_TXF: + break; + case TGSI_OPCODE_TXQ: + break; + case TGSI_OPCODE_CONT: + break; + case TGSI_OPCODE_EMIT: + break; + case TGSI_OPCODE_ENDPRIM: + break; + case TGSI_OPCODE_BGNLOOP2: { + } + break; + case TGSI_OPCODE_BGNSUB: { + } + break; + case TGSI_OPCODE_ENDLOOP2: { + } + break; + case TGSI_OPCODE_ENDSUB: { + } + break; + case TGSI_OPCODE_NOISE1: + break; + case TGSI_OPCODE_NOISE2: + break; + case TGSI_OPCODE_NOISE3: + break; + case TGSI_OPCODE_NOISE4: + break; + case TGSI_OPCODE_NOP: + break; + case TGSI_OPCODE_TEXBEM: + break; + case TGSI_OPCODE_TEXBEML: + break; + case TGSI_OPCODE_TEXREG2AR: + break; + case TGSI_OPCODE_TEXM3X2PAD: + break; + case TGSI_OPCODE_TEXM3X2TEX: + break; + case TGSI_OPCODE_TEXM3X3PAD: + break; + case TGSI_OPCODE_TEXM3X3TEX: + break; + case TGSI_OPCODE_TEXM3X3SPEC: + break; + case TGSI_OPCODE_TEXM3X3VSPEC: + break; + case TGSI_OPCODE_TEXREG2GB: + break; + case TGSI_OPCODE_TEXREG2RGB: + break; + case TGSI_OPCODE_TEXDP3TEX: + break; + case TGSI_OPCODE_TEXDP3: + break; + case TGSI_OPCODE_TEXM3X3: + break; + case TGSI_OPCODE_TEXM3X2DEPTH: + break; + case TGSI_OPCODE_TEXDEPTH: + break; + case TGSI_OPCODE_BEM: + break; + case TGSI_OPCODE_M4X3: + break; + case TGSI_OPCODE_M3X4: + break; + case TGSI_OPCODE_M3X3: + break; + case TGSI_OPCODE_M3X2: + break; + case TGSI_OPCODE_NRM4: + break; + case TGSI_OPCODE_CALLNZ: + break; + case TGSI_OPCODE_IFC: + break; + case TGSI_OPCODE_BREAKC: + break; + case TGSI_OPCODE_KIL: + break; + case TGSI_OPCODE_END: + instr->end(); + return; + break; + default: + fprintf(stderr, "ERROR: Unknown opcode %d\n", + inst->Instruction.Opcode); + assert(0); + break; + } + + if (!out[0]) { + fprintf(stderr, "ERROR: unsupported opcode %d\n", + inst->Instruction.Opcode); + assert(!"Unsupported opcode"); + } + + /* store results */ + for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + + if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { + storage->store(StorageSoa::Output, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { + storage->store(StorageSoa::Temp, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { + storage->store(StorageSoa::Address, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else { + fprintf(stderr, "ERROR: unsupported LLVM destination!"); + assert(!"wrong destination"); + } + } +} + +llvm::Module * +tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens) +{ + llvm::Module *mod = new Module("shader"); + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + unsigned instno = 0; + Function* shader = mod->getFunction("execute_shader"); + std::ostringstream stream; + if (ir->type == GALLIVM_VS) { + stream << "vs_shader"; + } else { + stream << "fs_shader"; + } + stream << ir->id; + std::string func_name = stream.str(); + shader->setName(func_name.c_str()); + + Function::arg_iterator args = shader->arg_begin(); + Value *ptr_INPUT = args++; + ptr_INPUT->setName("input"); + + BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + + tgsi_parse_init(&parse, tokens); + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + Storage storage(label_entry, ptr_INPUT); + Instructions instr(mod, shader, label_entry, &storage); + while(!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + translate_declaration(ir, mod, &storage, + &parse.FullToken.FullDeclaration, + &fd); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + translate_immediate(&storage, + &parse.FullToken.FullImmediate); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + translate_instruction(mod, &storage, &instr, + &parse.FullToken.FullInstruction, + &fi, instno); + ++instno; + break; + + default: + assert(0); + } + } + + tgsi_parse_free(&parse); + + ir->num_consts = storage.numConsts(); + return mod; +} + +llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, + const struct tgsi_token *tokens) +{ + llvm::Module *mod = new Module("shader"); + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + unsigned instno = 0; + std::ostringstream stream; + if (ir->type == GALLIVM_VS) { + stream << "vs_shader"; + } else { + stream << "fs_shader"; + } + //stream << ir->id; + std::string func_name = stream.str(); + Function *shader = llvm::cast(mod->getOrInsertFunction( + func_name.c_str(), + vertexShaderFunctionType())); + + Function::arg_iterator args = shader->arg_begin(); + Value *input = args++; + input->setName("inputs"); + Value *output = args++; + output->setName("outputs"); + Value *consts = args++; + consts->setName("consts"); + Value *temps = args++; + temps->setName("temps"); + + BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + + tgsi_parse_init(&parse, tokens); + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + + StorageSoa storage(label_entry, input, output, consts, temps); + InstructionsSoa instr(mod, shader, label_entry, &storage); + + while(!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + translate_declarationir(ir, mod, &storage, + &parse.FullToken.FullDeclaration, + &fd); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + translate_immediateir(&storage, + &parse.FullToken.FullImmediate); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + storage.declareImmediates(); + translate_instructionir(mod, &storage, &instr, + &parse.FullToken.FullInstruction, + &fi, instno); + ++instno; + break; + + default: + assert(0); + } + } + + tgsi_parse_free(&parse); + + return mod; +} diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.h b/src/gallium/auxiliary/gallivm/tgsitollvm.h new file mode 100644 index 0000000000..7ada04d629 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.h @@ -0,0 +1,20 @@ +#ifndef TGSITOLLVM_H +#define TGSITOLLVM_H + + +namespace llvm { + class Module; +} + +struct gallivm_ir; +struct tgsi_token; + + +llvm::Module * tgsi_to_llvm(struct gallivm_ir *ir, + const struct tgsi_token *tokens); + + +llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, + const struct tgsi_token *tokens); + +#endif diff --git a/src/gallium/auxiliary/llvm/Makefile b/src/gallium/auxiliary/llvm/Makefile deleted file mode 100644 index 39fac6ea4a..0000000000 --- a/src/gallium/auxiliary/llvm/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -# -*-makefile-*- -TOP = ../../../.. -include $(TOP)/configs/current - -LIBNAME = gallivm - - -GALLIVM_SOURCES = \ - gallivm.cpp \ - gallivm_cpu.cpp \ - instructions.cpp \ - loweringpass.cpp \ - tgsitollvm.cpp \ - storage.cpp \ - storagesoa.cpp \ - instructionssoa.cpp - -INC_SOURCES = gallivm_builtins.cpp - -CPP_SOURCES = \ - $(GALLIVM_SOURCES) - -C_SOURCES = -ASM_SOURCES = - -OBJECTS = $(C_SOURCES:.c=.o) \ - $(CPP_SOURCES:.cpp=.o) \ - $(ASM_SOURCES:.S=.o) - -### Include directories -INCLUDES = \ - -I. \ - -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/mesa \ - -I$(TOP)/include - - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(LLVM_CFLAGS) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.cpp.o: - $(CXX) -c $(INCLUDES) $(LLVM_CXXFLAGS) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -##### TARGETS ##### - -default:: depend symlinks $(LIBNAME) - - -$(LIBNAME): $(OBJECTS) Makefile - $(TOP)/bin/mklib -o $@ -static $(OBJECTS) - - -depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ - $(ASM_SOURCES) $(INC_SOURCES) 2> /dev/null - - -gallivm_builtins.cpp: llvm_builtins.c - clang --emit-llvm $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` `find ../include` - - -# Remove .o and backup files -clean: - -rm -f *.o */*.o *~ *.so *~ server/*.o - -rm -f depend depend.bak - -rm -f gallivm_builtins.cpp - -symlinks: - - -include depend diff --git a/src/gallium/auxiliary/llvm/gallivm.cpp b/src/gallium/auxiliary/llvm/gallivm.cpp deleted file mode 100644 index d14bb3b99a..0000000000 --- a/src/gallium/auxiliary/llvm/gallivm.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "instructions.h" -#include "loweringpass.h" -#include "storage.h" -#include "tgsitollvm.h" - -#include "pipe/p_context.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_dump.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static int GLOBAL_ID = 0; - -using namespace llvm; - -static inline -void AddStandardCompilePasses(PassManager &PM) -{ - PM.add(new LoweringPass()); - PM.add(createVerifierPass()); // Verify that input is correct - - PM.add(createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp - - //PM.add(createStripSymbolsPass(true)); - - PM.add(createRaiseAllocationsPass()); // call %malloc -> malloc inst - PM.add(createCFGSimplificationPass()); // Clean up disgusting code - PM.add(createPromoteMemoryToRegisterPass());// Kill useless allocas - PM.add(createGlobalOptimizerPass()); // Optimize out global vars - PM.add(createGlobalDCEPass()); // Remove unused fns and globs - PM.add(createIPConstantPropagationPass());// IP Constant Propagation - PM.add(createDeadArgEliminationPass()); // Dead argument elimination - PM.add(createInstructionCombiningPass()); // Clean up after IPCP & DAE - PM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE - - PM.add(createPruneEHPass()); // Remove dead EH info - - PM.add(createFunctionInliningPass()); // Inline small functions - PM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args - - PM.add(createTailDuplicationPass()); // Simplify cfg by copying code - PM.add(createInstructionCombiningPass()); // Cleanup for scalarrepl. - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createScalarReplAggregatesPass()); // Break up aggregate allocas - PM.add(createInstructionCombiningPass()); // Combine silly seq's - PM.add(createCondPropagationPass()); // Propagate conditionals - - PM.add(createTailCallEliminationPass()); // Eliminate tail calls - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createReassociatePass()); // Reassociate expressions - PM.add(createLoopRotatePass()); - PM.add(createLICMPass()); // Hoist loop invariants - PM.add(createLoopUnswitchPass()); // Unswitch loops. - PM.add(createLoopIndexSplitPass()); // Index split loops. - PM.add(createInstructionCombiningPass()); // Clean up after LICM/reassoc - PM.add(createIndVarSimplifyPass()); // Canonicalize indvars - PM.add(createLoopUnrollPass()); // Unroll small loops - PM.add(createInstructionCombiningPass()); // Clean up after the unroller - PM.add(createGVNPass()); // Remove redundancies - PM.add(createSCCPPass()); // Constant prop with SCCP - - // Run instcombine after redundancy elimination to exploit opportunities - // opened up by them. - PM.add(createInstructionCombiningPass()); - PM.add(createCondPropagationPass()); // Propagate conditionals - - PM.add(createDeadStoreEliminationPass()); // Delete dead stores - PM.add(createAggressiveDCEPass()); // SSA based 'Aggressive DCE' - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createSimplifyLibCallsPass()); // Library Call Optimizations - PM.add(createDeadTypeEliminationPass()); // Eliminate dead types - PM.add(createConstantMergePass()); // Merge dup global constants -} - -void gallivm_prog_delete(struct gallivm_prog *prog) -{ - delete prog->module; - prog->module = 0; - prog->function = 0; - free(prog); -} - -static inline void -constant_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan) -{ - unsigned i; - - for (i = 0; i < QUAD_SIZE; ++i) { - inputs[i][attrib][chan] = coefs[attrib].a0[chan]; - } -} - -static inline void -linear_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan) -{ - unsigned i; - - for( i = 0; i < QUAD_SIZE; i++ ) { - const float x = inputs[i][0][0]; - const float y = inputs[i][0][1]; - - inputs[i][attrib][chan] = - coefs[attrib].a0[chan] + - coefs[attrib].dadx[chan] * x + - coefs[attrib].dady[chan] * y; - } -} - -static inline void -perspective_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan ) -{ - unsigned i; - - for( i = 0; i < QUAD_SIZE; i++ ) { - const float x = inputs[i][0][0]; - const float y = inputs[i][0][1]; - /* WPOS.w here is really 1/w */ - const float w = 1.0f / inputs[i][0][3]; - assert(inputs[i][0][3] != 0.0); - - inputs[i][attrib][chan] = - (coefs[attrib].a0[chan] + - coefs[attrib].dadx[chan] * x + - coefs[attrib].dady[chan] * y) * w; - } -} - -void gallivm_ir_dump(struct gallivm_ir *ir, const char *file_prefix) -{ - if (!ir || !ir->module) - return; - - if (file_prefix) { - std::ostringstream stream; - stream << file_prefix; - stream << ir->id; - stream << ".ll"; - std::string name = stream.str(); - std::ofstream out(name.c_str()); - if (!out) { - std::cerr<<"Can't open file : "<module); - out.close(); - } else { - const llvm::Module::FunctionListType &funcs = ir->module->getFunctionList(); - llvm::Module::FunctionListType::const_iterator itr; - std::cout<<"; ---------- Start shader "<id<id<num_interp; ++i) { - const gallivm_interpolate &interp = prog->interpolators[i]; - switch (interp.type) { - case TGSI_INTERPOLATE_CONSTANT: - constant_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - case TGSI_INTERPOLATE_LINEAR: - linear_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - case TGSI_INTERPOLATE_PERSPECTIVE: - perspective_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - default: - assert( 0 ); - } - } -} - - -struct gallivm_ir * gallivm_ir_new(enum gallivm_shader_type type) -{ - struct gallivm_ir *ir = - (struct gallivm_ir *)calloc(1, sizeof(struct gallivm_ir)); - ++GLOBAL_ID; - ir->id = GLOBAL_ID; - ir->type = type; - - return ir; -} - -void gallivm_ir_set_layout(struct gallivm_ir *ir, - enum gallivm_vector_layout layout) -{ - ir->layout = layout; -} - -void gallivm_ir_set_components(struct gallivm_ir *ir, int num) -{ - ir->num_components = num; -} - -void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, - const struct tgsi_token *tokens) -{ - std::cout << "Creating llvm from: " <module = mod; - gallivm_ir_dump(ir, 0); -} - -void gallivm_ir_delete(struct gallivm_ir *ir) -{ - delete ir->module; - free(ir); -} - -struct gallivm_prog * gallivm_ir_compile(struct gallivm_ir *ir) -{ - struct gallivm_prog *prog = - (struct gallivm_prog *)calloc(1, sizeof(struct gallivm_prog)); - llvm::Module *mod = llvm::CloneModule(ir->module); - prog->num_consts = ir->num_consts; - memcpy(prog->interpolators, ir->interpolators, sizeof(prog->interpolators)); - prog->num_interp = ir->num_interp; - - /* Run optimization passes over it */ - PassManager passes; - passes.add(new TargetData(mod)); - AddStandardCompilePasses(passes); - passes.run(*mod); - prog->module = mod; - - std::cout << "After optimizations:"<dump(); - - return prog; -} - -#endif /* MESA_LLVM */ diff --git a/src/gallium/auxiliary/llvm/gallivm.h b/src/gallium/auxiliary/llvm/gallivm.h deleted file mode 100644 index 92da4bca7f..0000000000 --- a/src/gallium/auxiliary/llvm/gallivm.h +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef GALLIVM_H -#define GALLIVM_H - -#if defined __cplusplus -extern "C" { -#endif - -#include "pipe/p_state.h" - -#ifdef MESA_LLVM - -struct tgsi_token; - -struct gallivm_ir; -struct gallivm_prog; -struct gallivm_cpu_engine; -struct tgsi_interp_coef; -struct tgsi_sampler; -struct tgsi_exec_vector; - -enum gallivm_shader_type { - GALLIVM_VS, - GALLIVM_FS -}; - -enum gallivm_vector_layout { - GALLIVM_AOS, - GALLIVM_SOA -}; - -struct gallivm_ir *gallivm_ir_new(enum gallivm_shader_type type); -void gallivm_ir_set_layout(struct gallivm_ir *ir, - enum gallivm_vector_layout layout); -void gallivm_ir_set_components(struct gallivm_ir *ir, int num); -void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, - const struct tgsi_token *tokens); -void gallivm_ir_delete(struct gallivm_ir *ir); - - -struct gallivm_prog *gallivm_ir_compile(struct gallivm_ir *ir); - -void gallivm_prog_inputs_interpolate(struct gallivm_prog *prog, - float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], - const struct tgsi_interp_coef *coefs); -void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix); - - -struct gallivm_cpu_engine *gallivm_cpu_engine_create(struct gallivm_prog *prog); -struct gallivm_cpu_engine *gallivm_global_cpu_engine(); -int gallivm_cpu_vs_exec(struct gallivm_prog *prog, - struct tgsi_exec_vector *inputs, - struct tgsi_exec_vector *dests, - float (*consts)[4], - struct tgsi_exec_vector *temps); -int gallivm_cpu_fs_exec(struct gallivm_prog *prog, - float x, float y, - float (*dests)[PIPE_MAX_SHADER_INPUTS][4], - float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], - float (*consts)[4], - struct tgsi_sampler *samplers); -void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *ee, struct gallivm_prog *prog); -void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *ee); - - -#endif /* MESA_LLVM */ - -#if defined __cplusplus -} // extern "C" -#endif - -#endif diff --git a/src/gallium/auxiliary/llvm/gallivm_builtins.cpp b/src/gallium/auxiliary/llvm/gallivm_builtins.cpp deleted file mode 100644 index 1796f0a177..0000000000 --- a/src/gallium/auxiliary/llvm/gallivm_builtins.cpp +++ /dev/null @@ -1,567 +0,0 @@ -// Generated by llvm2cpp - DO NOT MODIFY! - - -Module* createGallivmBuiltins(Module *mod) { - -mod->setModuleIdentifier("shader"); - -// Type Definitions -ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(8), 25); - -PointerType* PointerTy_1 = PointerType::get(ArrayTy_0, 0); - -std::vectorFuncTy_2_args; -FuncTy_2_args.push_back(Type::FloatTy); -FuncTy_2_args.push_back(Type::FloatTy); -FunctionType* FuncTy_2 = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/FuncTy_2_args, - /*isVarArg=*/false); - -PointerType* PointerTy_3 = PointerType::get(FuncTy_2, 0); - -VectorType* VectorTy_4 = VectorType::get(Type::FloatTy, 4); - -std::vectorFuncTy_5_args; -FuncTy_5_args.push_back(VectorTy_4); -FunctionType* FuncTy_5 = FunctionType::get( - /*Result=*/VectorTy_4, - /*Params=*/FuncTy_5_args, - /*isVarArg=*/false); - -std::vectorFuncTy_6_args; -FuncTy_6_args.push_back(VectorTy_4); -FuncTy_6_args.push_back(VectorTy_4); -FuncTy_6_args.push_back(VectorTy_4); -FunctionType* FuncTy_6 = FunctionType::get( - /*Result=*/VectorTy_4, - /*Params=*/FuncTy_6_args, - /*isVarArg=*/false); - -VectorType* VectorTy_7 = VectorType::get(IntegerType::get(32), 4); - -std::vectorFuncTy_9_args; -FunctionType* FuncTy_9 = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/FuncTy_9_args, - /*isVarArg=*/true); - -PointerType* PointerTy_8 = PointerType::get(FuncTy_9, 0); - -PointerType* PointerTy_10 = PointerType::get(IntegerType::get(8), 0); - -std::vectorFuncTy_12_args; -FuncTy_12_args.push_back(Type::FloatTy); -FunctionType* FuncTy_12 = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/FuncTy_12_args, - /*isVarArg=*/false); - -PointerType* PointerTy_11 = PointerType::get(FuncTy_12, 0); - -std::vectorFuncTy_13_args; -FuncTy_13_args.push_back(VectorTy_4); -FunctionType* FuncTy_13 = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/FuncTy_13_args, - /*isVarArg=*/false); - - -// Function Declarations - -Function* func_approx = new Function( - /*Type=*/FuncTy_2, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"approx", mod); -func_approx->setCallingConv(CallingConv::C); -const ParamAttrsList *func_approx_PAL = 0; -func_approx->setParamAttrs(func_approx_PAL); - -Function* func_powf = new Function( - /*Type=*/FuncTy_2, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"powf", mod); // (external, no body) -func_powf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_powf_PAL = 0; -func_powf->setParamAttrs(func_powf_PAL); - -Function* func_lit = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"lit", mod); -func_lit->setCallingConv(CallingConv::C); -const ParamAttrsList *func_lit_PAL = 0; -func_lit->setParamAttrs(func_lit_PAL); - -Function* func_cmp = new Function( - /*Type=*/FuncTy_6, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"cmp", mod); -func_cmp->setCallingConv(CallingConv::C); -const ParamAttrsList *func_cmp_PAL = 0; -{ - ParamAttrsVector Attrs; - ParamAttrsWithIndex PAWI; - PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; - Attrs.push_back(PAWI); - func_cmp_PAL = ParamAttrsList::get(Attrs); - -} -func_cmp->setParamAttrs(func_cmp_PAL); - -Function* func_vcos = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"vcos", mod); -func_vcos->setCallingConv(CallingConv::C); -const ParamAttrsList *func_vcos_PAL = 0; -func_vcos->setParamAttrs(func_vcos_PAL); - -Function* func_printf = new Function( - /*Type=*/FuncTy_9, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"printf", mod); // (external, no body) -func_printf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_printf_PAL = 0; -func_printf->setParamAttrs(func_printf_PAL); - -Function* func_cosf = new Function( - /*Type=*/FuncTy_12, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"cosf", mod); // (external, no body) -func_cosf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_cosf_PAL = 0; -func_cosf->setParamAttrs(func_cosf_PAL); - -Function* func_scs = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"scs", mod); -func_scs->setCallingConv(CallingConv::C); -const ParamAttrsList *func_scs_PAL = 0; -func_scs->setParamAttrs(func_scs_PAL); - -Function* func_sinf = new Function( - /*Type=*/FuncTy_12, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"sinf", mod); // (external, no body) -func_sinf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_sinf_PAL = 0; -func_sinf->setParamAttrs(func_sinf_PAL); - -Function* func_vsin = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"vsin", mod); -func_vsin->setCallingConv(CallingConv::C); -const ParamAttrsList *func_vsin_PAL = 0; -func_vsin->setParamAttrs(func_vsin_PAL); - -Function* func_kilp = new Function( - /*Type=*/FuncTy_13, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"kilp", mod); -func_kilp->setCallingConv(CallingConv::C); -const ParamAttrsList *func_kilp_PAL = 0; -{ - ParamAttrsVector Attrs; - ParamAttrsWithIndex PAWI; - PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; - Attrs.push_back(PAWI); - func_kilp_PAL = ParamAttrsList::get(Attrs); - -} -func_kilp->setParamAttrs(func_kilp_PAL); - -// Global Variable Declarations - - -GlobalVariable* gvar_array__str = new GlobalVariable( -/*Type=*/ArrayTy_0, -/*isConstant=*/true, -/*Linkage=*/GlobalValue::InternalLinkage, -/*Initializer=*/0, // has initializer, specified below -/*Name=*/".str", -mod); - -GlobalVariable* gvar_array__str1 = new GlobalVariable( -/*Type=*/ArrayTy_0, -/*isConstant=*/true, -/*Linkage=*/GlobalValue::InternalLinkage, -/*Initializer=*/0, // has initializer, specified below -/*Name=*/".str1", -mod); - -// Constant Definitions -Constant* const_array_14 = ConstantArray::get("VEC IN is %f %f %f %f\x0A", true); -Constant* const_array_15 = ConstantArray::get("VEC OUT is %f %f %f %f\x0A", true); -ConstantFP* const_float_16 = ConstantFP::get(Type::FloatTy, APFloat(-1.280000e+02f)); -ConstantFP* const_float_17 = ConstantFP::get(Type::FloatTy, APFloat(1.280000e+02f)); -Constant* const_float_18 = Constant::getNullValue(Type::FloatTy); -Constant* const_int32_19 = Constant::getNullValue(IntegerType::get(32)); -std::vector const_packed_20_elems; -ConstantFP* const_float_21 = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); -const_packed_20_elems.push_back(const_float_21); -UndefValue* const_float_22 = UndefValue::get(Type::FloatTy); -const_packed_20_elems.push_back(const_float_22); -const_packed_20_elems.push_back(const_float_22); -const_packed_20_elems.push_back(const_float_21); -Constant* const_packed_20 = ConstantVector::get(VectorTy_4, const_packed_20_elems); -ConstantInt* const_int32_23 = ConstantInt::get(APInt(32, "1", 10)); -ConstantInt* const_int32_24 = ConstantInt::get(APInt(32, "3", 10)); -ConstantInt* const_int32_25 = ConstantInt::get(APInt(32, "2", 10)); -std::vector const_packed_26_elems; -const_packed_26_elems.push_back(const_float_21); -const_packed_26_elems.push_back(const_float_18); -const_packed_26_elems.push_back(const_float_18); -const_packed_26_elems.push_back(const_float_21); -Constant* const_packed_26 = ConstantVector::get(VectorTy_4, const_packed_26_elems); -Constant* const_double_27 = Constant::getNullValue(Type::DoubleTy); -std::vector const_packed_28_elems; -const_packed_28_elems.push_back(const_int32_19); -ConstantInt* const_int32_29 = ConstantInt::get(APInt(32, "5", 10)); -const_packed_28_elems.push_back(const_int32_29); -const_packed_28_elems.push_back(const_int32_25); -const_packed_28_elems.push_back(const_int32_24); -Constant* const_packed_28 = ConstantVector::get(VectorTy_7, const_packed_28_elems); -std::vector const_packed_30_elems; -const_packed_30_elems.push_back(const_int32_19); -const_packed_30_elems.push_back(const_int32_23); -ConstantInt* const_int32_31 = ConstantInt::get(APInt(32, "6", 10)); -const_packed_30_elems.push_back(const_int32_31); -const_packed_30_elems.push_back(const_int32_24); -Constant* const_packed_30 = ConstantVector::get(VectorTy_7, const_packed_30_elems); -std::vector const_packed_32_elems; -const_packed_32_elems.push_back(const_int32_19); -const_packed_32_elems.push_back(const_int32_23); -const_packed_32_elems.push_back(const_int32_25); -ConstantInt* const_int32_33 = ConstantInt::get(APInt(32, "7", 10)); -const_packed_32_elems.push_back(const_int32_33); -Constant* const_packed_32 = ConstantVector::get(VectorTy_7, const_packed_32_elems); -std::vector const_ptr_34_indices; -const_ptr_34_indices.push_back(const_int32_19); -const_ptr_34_indices.push_back(const_int32_19); -Constant* const_ptr_34 = ConstantExpr::getGetElementPtr(gvar_array__str, &const_ptr_34_indices[0], const_ptr_34_indices.size() ); -UndefValue* const_packed_35 = UndefValue::get(VectorTy_4); -std::vector const_ptr_36_indices; -const_ptr_36_indices.push_back(const_int32_19); -const_ptr_36_indices.push_back(const_int32_19); -Constant* const_ptr_36 = ConstantExpr::getGetElementPtr(gvar_array__str1, &const_ptr_36_indices[0], const_ptr_36_indices.size() ); - -// Global Variable Definitions -gvar_array__str->setInitializer(const_array_14); -gvar_array__str1->setInitializer(const_array_15); - -// Function Definitions - -// Function: approx (func_approx) -{ - Function::arg_iterator args = func_approx->arg_begin(); - Value* float_a = args++; - float_a->setName("a"); - Value* float_b = args++; - float_b->setName("b"); - - BasicBlock* label_entry = new BasicBlock("entry",func_approx,0); - - // Block entry (label_entry) - FCmpInst* int1_cmp = new FCmpInst(FCmpInst::FCMP_OLT, float_b, const_float_16, "cmp", label_entry); - SelectInst* float_b_addr_0 = new SelectInst(int1_cmp, const_float_16, float_b, "b.addr.0", label_entry); - FCmpInst* int1_cmp3 = new FCmpInst(FCmpInst::FCMP_OGT, float_b_addr_0, const_float_17, "cmp3", label_entry); - SelectInst* float_b_addr_1 = new SelectInst(int1_cmp3, const_float_17, float_b_addr_0, "b.addr.1", label_entry); - FCmpInst* int1_cmp7 = new FCmpInst(FCmpInst::FCMP_OLT, float_a, const_float_18, "cmp7", label_entry); - SelectInst* float_a_addr_0 = new SelectInst(int1_cmp7, const_float_18, float_a, "a.addr.0", label_entry); - std::vector float_call_params; - float_call_params.push_back(float_a_addr_0); - float_call_params.push_back(float_b_addr_1); - CallInst* float_call = new CallInst(func_powf, float_call_params.begin(), float_call_params.end(), "call", label_entry); - float_call->setCallingConv(CallingConv::C); - float_call->setTailCall(true);const ParamAttrsList *float_call_PAL = 0; - float_call->setParamAttrs(float_call_PAL); - - new ReturnInst(float_call, label_entry); - -} - -// Function: lit (func_lit) -{ - Function::arg_iterator args = func_lit->arg_begin(); - Value* packed_tmp = args++; - packed_tmp->setName("tmp"); - - BasicBlock* label_entry_38 = new BasicBlock("entry",func_lit,0); - BasicBlock* label_ifthen = new BasicBlock("ifthen",func_lit,0); - BasicBlock* label_UnifiedReturnBlock = new BasicBlock("UnifiedReturnBlock",func_lit,0); - - // Block entry (label_entry_38) - ExtractElementInst* float_tmp6 = new ExtractElementInst(packed_tmp, const_int32_19, "tmp6", label_entry_38); - FCmpInst* int1_cmp_39 = new FCmpInst(FCmpInst::FCMP_OGT, float_tmp6, const_float_18, "cmp", label_entry_38); - new BranchInst(label_ifthen, label_UnifiedReturnBlock, int1_cmp_39, label_entry_38); - - // Block ifthen (label_ifthen) - InsertElementInst* packed_tmp10 = new InsertElementInst(const_packed_20, float_tmp6, const_int32_23, "tmp10", label_ifthen); - ExtractElementInst* float_tmp12 = new ExtractElementInst(packed_tmp, const_int32_23, "tmp12", label_ifthen); - ExtractElementInst* float_tmp14 = new ExtractElementInst(packed_tmp, const_int32_24, "tmp14", label_ifthen); - std::vector float_call_41_params; - float_call_41_params.push_back(float_tmp12); - float_call_41_params.push_back(float_tmp14); - CallInst* float_call_41 = new CallInst(func_approx, float_call_41_params.begin(), float_call_41_params.end(), "call", label_ifthen); - float_call_41->setCallingConv(CallingConv::C); - float_call_41->setTailCall(true);const ParamAttrsList *float_call_41_PAL = 0; - float_call_41->setParamAttrs(float_call_41_PAL); - - InsertElementInst* packed_tmp16 = new InsertElementInst(packed_tmp10, float_call_41, const_int32_25, "tmp16", label_ifthen); - new ReturnInst(packed_tmp16, label_ifthen); - - // Block UnifiedReturnBlock (label_UnifiedReturnBlock) - new ReturnInst(const_packed_26, label_UnifiedReturnBlock); - -} - -// Function: cmp (func_cmp) -{ - Function::arg_iterator args = func_cmp->arg_begin(); - Value* packed_tmp0 = args++; - packed_tmp0->setName("tmp0"); - Value* packed_tmp1 = args++; - packed_tmp1->setName("tmp1"); - Value* packed_tmp2 = args++; - packed_tmp2->setName("tmp2"); - - BasicBlock* label_entry_44 = new BasicBlock("entry",func_cmp,0); - BasicBlock* label_cond__14 = new BasicBlock("cond.?14",func_cmp,0); - BasicBlock* label_cond_cont20 = new BasicBlock("cond.cont20",func_cmp,0); - BasicBlock* label_cond__28 = new BasicBlock("cond.?28",func_cmp,0); - BasicBlock* label_cond_cont34 = new BasicBlock("cond.cont34",func_cmp,0); - BasicBlock* label_cond__42 = new BasicBlock("cond.?42",func_cmp,0); - BasicBlock* label_cond_cont48 = new BasicBlock("cond.cont48",func_cmp,0); - - // Block entry (label_entry_44) - ExtractElementInst* float_tmp3 = new ExtractElementInst(packed_tmp0, const_int32_19, "tmp3", label_entry_44); - CastInst* double_conv = new FPExtInst(float_tmp3, Type::DoubleTy, "conv", label_entry_44); - FCmpInst* int1_cmp_45 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv, const_double_27, "cmp", label_entry_44); - ExtractElementInst* float_tmp11 = new ExtractElementInst(packed_tmp0, const_int32_23, "tmp11", label_entry_44); - CastInst* double_conv12 = new FPExtInst(float_tmp11, Type::DoubleTy, "conv12", label_entry_44); - FCmpInst* int1_cmp13 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv12, const_double_27, "cmp13", label_entry_44); - SelectInst* packed_tmp1_tmp2 = new SelectInst(int1_cmp_45, packed_tmp1, packed_tmp2, "tmp1.tmp2", label_entry_44); - new BranchInst(label_cond__14, label_cond_cont20, int1_cmp13, label_entry_44); - - // Block cond.?14 (label_cond__14) - ShuffleVectorInst* packed_tmp233 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp1, const_packed_28, "tmp233", label_cond__14); - ExtractElementInst* float_tmp254 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp254", label_cond__14); - CastInst* double_conv265 = new FPExtInst(float_tmp254, Type::DoubleTy, "conv265", label_cond__14); - FCmpInst* int1_cmp276 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv265, const_double_27, "cmp276", label_cond__14); - new BranchInst(label_cond__28, label_cond_cont34, int1_cmp276, label_cond__14); - - // Block cond.cont20 (label_cond_cont20) - ShuffleVectorInst* packed_tmp23 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp2, const_packed_28, "tmp23", label_cond_cont20); - ExtractElementInst* float_tmp25 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp25", label_cond_cont20); - CastInst* double_conv26 = new FPExtInst(float_tmp25, Type::DoubleTy, "conv26", label_cond_cont20); - FCmpInst* int1_cmp27 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv26, const_double_27, "cmp27", label_cond_cont20); - new BranchInst(label_cond__28, label_cond_cont34, int1_cmp27, label_cond_cont20); - - // Block cond.?28 (label_cond__28) - PHINode* packed_tmp23_reg2mem_0 = new PHINode(VectorTy_4, "tmp23.reg2mem.0", label_cond__28); - packed_tmp23_reg2mem_0->reserveOperandSpace(2); - packed_tmp23_reg2mem_0->addIncoming(packed_tmp233, label_cond__14); - packed_tmp23_reg2mem_0->addIncoming(packed_tmp23, label_cond_cont20); - - ShuffleVectorInst* packed_tmp378 = new ShuffleVectorInst(packed_tmp23_reg2mem_0, packed_tmp1, const_packed_30, "tmp378", label_cond__28); - ExtractElementInst* float_tmp399 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp399", label_cond__28); - CastInst* double_conv4010 = new FPExtInst(float_tmp399, Type::DoubleTy, "conv4010", label_cond__28); - FCmpInst* int1_cmp4111 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv4010, const_double_27, "cmp4111", label_cond__28); - new BranchInst(label_cond__42, label_cond_cont48, int1_cmp4111, label_cond__28); - - // Block cond.cont34 (label_cond_cont34) - PHINode* packed_tmp23_reg2mem_1 = new PHINode(VectorTy_4, "tmp23.reg2mem.1", label_cond_cont34); - packed_tmp23_reg2mem_1->reserveOperandSpace(2); - packed_tmp23_reg2mem_1->addIncoming(packed_tmp233, label_cond__14); - packed_tmp23_reg2mem_1->addIncoming(packed_tmp23, label_cond_cont20); - - ShuffleVectorInst* packed_tmp37 = new ShuffleVectorInst(packed_tmp23_reg2mem_1, packed_tmp2, const_packed_30, "tmp37", label_cond_cont34); - ExtractElementInst* float_tmp39 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp39", label_cond_cont34); - CastInst* double_conv40 = new FPExtInst(float_tmp39, Type::DoubleTy, "conv40", label_cond_cont34); - FCmpInst* int1_cmp41 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv40, const_double_27, "cmp41", label_cond_cont34); - new BranchInst(label_cond__42, label_cond_cont48, int1_cmp41, label_cond_cont34); - - // Block cond.?42 (label_cond__42) - PHINode* packed_tmp37_reg2mem_0 = new PHINode(VectorTy_4, "tmp37.reg2mem.0", label_cond__42); - packed_tmp37_reg2mem_0->reserveOperandSpace(2); - packed_tmp37_reg2mem_0->addIncoming(packed_tmp378, label_cond__28); - packed_tmp37_reg2mem_0->addIncoming(packed_tmp37, label_cond_cont34); - - ShuffleVectorInst* packed_tmp5113 = new ShuffleVectorInst(packed_tmp37_reg2mem_0, packed_tmp1, const_packed_32, "tmp5113", label_cond__42); - new ReturnInst(packed_tmp5113, label_cond__42); - - // Block cond.cont48 (label_cond_cont48) - PHINode* packed_tmp37_reg2mem_1 = new PHINode(VectorTy_4, "tmp37.reg2mem.1", label_cond_cont48); - packed_tmp37_reg2mem_1->reserveOperandSpace(2); - packed_tmp37_reg2mem_1->addIncoming(packed_tmp378, label_cond__28); - packed_tmp37_reg2mem_1->addIncoming(packed_tmp37, label_cond_cont34); - - ShuffleVectorInst* packed_tmp51 = new ShuffleVectorInst(packed_tmp37_reg2mem_1, packed_tmp2, const_packed_32, "tmp51", label_cond_cont48); - new ReturnInst(packed_tmp51, label_cond_cont48); - -} - -// Function: vcos (func_vcos) -{ - Function::arg_iterator args = func_vcos->arg_begin(); - Value* packed_val = args++; - packed_val->setName("val"); - - BasicBlock* label_entry_53 = new BasicBlock("entry",func_vcos,0); - - // Block entry (label_entry_53) - ExtractElementInst* float_tmp1 = new ExtractElementInst(packed_val, const_int32_19, "tmp1", label_entry_53); - CastInst* double_conv_54 = new FPExtInst(float_tmp1, Type::DoubleTy, "conv", label_entry_53); - ExtractElementInst* float_tmp3_55 = new ExtractElementInst(packed_val, const_int32_23, "tmp3", label_entry_53); - CastInst* double_conv4 = new FPExtInst(float_tmp3_55, Type::DoubleTy, "conv4", label_entry_53); - ExtractElementInst* float_tmp6_56 = new ExtractElementInst(packed_val, const_int32_25, "tmp6", label_entry_53); - CastInst* double_conv7 = new FPExtInst(float_tmp6_56, Type::DoubleTy, "conv7", label_entry_53); - ExtractElementInst* float_tmp9 = new ExtractElementInst(packed_val, const_int32_24, "tmp9", label_entry_53); - CastInst* double_conv10 = new FPExtInst(float_tmp9, Type::DoubleTy, "conv10", label_entry_53); - std::vector int32_call_params; - int32_call_params.push_back(const_ptr_34); - int32_call_params.push_back(double_conv_54); - int32_call_params.push_back(double_conv4); - int32_call_params.push_back(double_conv7); - int32_call_params.push_back(double_conv10); - CallInst* int32_call = new CallInst(func_printf, int32_call_params.begin(), int32_call_params.end(), "call", label_entry_53); - int32_call->setCallingConv(CallingConv::C); - int32_call->setTailCall(true);const ParamAttrsList *int32_call_PAL = 0; - int32_call->setParamAttrs(int32_call_PAL); - - CallInst* float_call13 = new CallInst(func_cosf, float_tmp1, "call13", label_entry_53); - float_call13->setCallingConv(CallingConv::C); - float_call13->setTailCall(true);const ParamAttrsList *float_call13_PAL = 0; - float_call13->setParamAttrs(float_call13_PAL); - - InsertElementInst* packed_tmp15 = new InsertElementInst(const_packed_35, float_call13, const_int32_19, "tmp15", label_entry_53); - CallInst* float_call18 = new CallInst(func_cosf, float_tmp1, "call18", label_entry_53); - float_call18->setCallingConv(CallingConv::C); - float_call18->setTailCall(true);const ParamAttrsList *float_call18_PAL = 0; - float_call18->setParamAttrs(float_call18_PAL); - - InsertElementInst* packed_tmp20 = new InsertElementInst(packed_tmp15, float_call18, const_int32_23, "tmp20", label_entry_53); - CallInst* float_call23 = new CallInst(func_cosf, float_tmp1, "call23", label_entry_53); - float_call23->setCallingConv(CallingConv::C); - float_call23->setTailCall(true);const ParamAttrsList *float_call23_PAL = 0; - float_call23->setParamAttrs(float_call23_PAL); - - InsertElementInst* packed_tmp25 = new InsertElementInst(packed_tmp20, float_call23, const_int32_25, "tmp25", label_entry_53); - CallInst* float_call28 = new CallInst(func_cosf, float_tmp1, "call28", label_entry_53); - float_call28->setCallingConv(CallingConv::C); - float_call28->setTailCall(true);const ParamAttrsList *float_call28_PAL = 0; - float_call28->setParamAttrs(float_call28_PAL); - - InsertElementInst* packed_tmp30 = new InsertElementInst(packed_tmp25, float_call28, const_int32_24, "tmp30", label_entry_53); - CastInst* double_conv33 = new FPExtInst(float_call13, Type::DoubleTy, "conv33", label_entry_53); - CastInst* double_conv36 = new FPExtInst(float_call18, Type::DoubleTy, "conv36", label_entry_53); - CastInst* double_conv39 = new FPExtInst(float_call23, Type::DoubleTy, "conv39", label_entry_53); - CastInst* double_conv42 = new FPExtInst(float_call28, Type::DoubleTy, "conv42", label_entry_53); - std::vector int32_call43_params; - int32_call43_params.push_back(const_ptr_36); - int32_call43_params.push_back(double_conv33); - int32_call43_params.push_back(double_conv36); - int32_call43_params.push_back(double_conv39); - int32_call43_params.push_back(double_conv42); - CallInst* int32_call43 = new CallInst(func_printf, int32_call43_params.begin(), int32_call43_params.end(), "call43", label_entry_53); - int32_call43->setCallingConv(CallingConv::C); - int32_call43->setTailCall(true);const ParamAttrsList *int32_call43_PAL = 0; - int32_call43->setParamAttrs(int32_call43_PAL); - - new ReturnInst(packed_tmp30, label_entry_53); - -} - -// Function: scs (func_scs) -{ - Function::arg_iterator args = func_scs->arg_begin(); - Value* packed_val_58 = args++; - packed_val_58->setName("val"); - - BasicBlock* label_entry_59 = new BasicBlock("entry",func_scs,0); - - // Block entry (label_entry_59) - ExtractElementInst* float_tmp2 = new ExtractElementInst(packed_val_58, const_int32_19, "tmp2", label_entry_59); - CallInst* float_call_60 = new CallInst(func_cosf, float_tmp2, "call", label_entry_59); - float_call_60->setCallingConv(CallingConv::C); - float_call_60->setTailCall(true);const ParamAttrsList *float_call_60_PAL = 0; - float_call_60->setParamAttrs(float_call_60_PAL); - - InsertElementInst* packed_tmp5 = new InsertElementInst(const_packed_35, float_call_60, const_int32_19, "tmp5", label_entry_59); - CallInst* float_call7 = new CallInst(func_sinf, float_tmp2, "call7", label_entry_59); - float_call7->setCallingConv(CallingConv::C); - float_call7->setTailCall(true);const ParamAttrsList *float_call7_PAL = 0; - float_call7->setParamAttrs(float_call7_PAL); - - InsertElementInst* packed_tmp9 = new InsertElementInst(packed_tmp5, float_call7, const_int32_23, "tmp9", label_entry_59); - new ReturnInst(packed_tmp9, label_entry_59); - -} - -// Function: vsin (func_vsin) -{ - Function::arg_iterator args = func_vsin->arg_begin(); - Value* packed_val_62 = args++; - packed_val_62->setName("val"); - - BasicBlock* label_entry_63 = new BasicBlock("entry",func_vsin,0); - - // Block entry (label_entry_63) - ExtractElementInst* float_tmp2_64 = new ExtractElementInst(packed_val_62, const_int32_19, "tmp2", label_entry_63); - CallInst* float_call_65 = new CallInst(func_sinf, float_tmp2_64, "call", label_entry_63); - float_call_65->setCallingConv(CallingConv::C); - float_call_65->setTailCall(true);const ParamAttrsList *float_call_65_PAL = 0; - float_call_65->setParamAttrs(float_call_65_PAL); - - InsertElementInst* packed_tmp6 = new InsertElementInst(const_packed_35, float_call_65, const_int32_19, "tmp6", label_entry_63); - InsertElementInst* packed_tmp9_66 = new InsertElementInst(packed_tmp6, float_call_65, const_int32_23, "tmp9", label_entry_63); - InsertElementInst* packed_tmp12 = new InsertElementInst(packed_tmp9_66, float_call_65, const_int32_25, "tmp12", label_entry_63); - InsertElementInst* packed_tmp15_67 = new InsertElementInst(packed_tmp12, float_call_65, const_int32_24, "tmp15", label_entry_63); - new ReturnInst(packed_tmp15_67, label_entry_63); - -} - -// Function: kilp (func_kilp) -{ - Function::arg_iterator args = func_kilp->arg_begin(); - Value* packed_val_69 = args++; - packed_val_69->setName("val"); - - BasicBlock* label_entry_70 = new BasicBlock("entry",func_kilp,0); - BasicBlock* label_lor_rhs = new BasicBlock("lor_rhs",func_kilp,0); - BasicBlock* label_lor_rhs5 = new BasicBlock("lor_rhs5",func_kilp,0); - BasicBlock* label_lor_rhs11 = new BasicBlock("lor_rhs11",func_kilp,0); - BasicBlock* label_UnifiedReturnBlock_71 = new BasicBlock("UnifiedReturnBlock",func_kilp,0); - - // Block entry (label_entry_70) - ExtractElementInst* float_tmp1_72 = new ExtractElementInst(packed_val_69, const_int32_19, "tmp1", label_entry_70); - FCmpInst* int1_cmp_73 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp1_72, const_float_18, "cmp", label_entry_70); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs, int1_cmp_73, label_entry_70); - - // Block lor_rhs (label_lor_rhs) - ExtractElementInst* float_tmp3_75 = new ExtractElementInst(packed_val_69, const_int32_23, "tmp3", label_lor_rhs); - FCmpInst* int1_cmp4 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp3_75, const_float_18, "cmp4", label_lor_rhs); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs5, int1_cmp4, label_lor_rhs); - - // Block lor_rhs5 (label_lor_rhs5) - ExtractElementInst* float_tmp7 = new ExtractElementInst(packed_val_69, const_int32_25, "tmp7", label_lor_rhs5); - FCmpInst* int1_cmp8 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp7, const_float_18, "cmp8", label_lor_rhs5); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs11, int1_cmp8, label_lor_rhs5); - - // Block lor_rhs11 (label_lor_rhs11) - ExtractElementInst* float_tmp13 = new ExtractElementInst(packed_val_69, const_int32_24, "tmp13", label_lor_rhs11); - FCmpInst* int1_cmp14 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp13, const_float_18, "cmp14", label_lor_rhs11); - CastInst* int32_retval = new ZExtInst(int1_cmp14, IntegerType::get(32), "retval", label_lor_rhs11); - new ReturnInst(int32_retval, label_lor_rhs11); - - // Block UnifiedReturnBlock (label_UnifiedReturnBlock_71) - new ReturnInst(const_int32_23, label_UnifiedReturnBlock_71); - -} - -return mod; - -} diff --git a/src/gallium/auxiliary/llvm/gallivm_cpu.cpp b/src/gallium/auxiliary/llvm/gallivm_cpu.cpp deleted file mode 100644 index 8f9830d0b1..0000000000 --- a/src/gallium/auxiliary/llvm/gallivm_cpu.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "instructions.h" -#include "loweringpass.h" -#include "storage.h" -#include "tgsitollvm.h" - -#include "pipe/p_context.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_dump.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -struct gallivm_cpu_engine { - llvm::ExecutionEngine *engine; -}; - -static struct gallivm_cpu_engine *CPU = 0; - -typedef int (*fragment_shader_runner)(float x, float y, - float (*dests)[16][4], - float (*inputs)[16][4], - int num_attribs, - float (*consts)[4], int num_consts, - struct tgsi_sampler *samplers); - -int gallivm_cpu_fs_exec(struct gallivm_prog *prog, - float fx, float fy, - float (*dests)[16][4], - float (*inputs)[16][4], - float (*consts)[4], - struct tgsi_sampler *samplers) -{ - fragment_shader_runner runner = reinterpret_cast(prog->function); - assert(runner); - - return runner(fx, fy, dests, inputs, prog->num_interp, - consts, prog->num_consts, - samplers); -} - -static inline llvm::Function *func_for_shader(struct gallivm_prog *prog) -{ - llvm::Module *mod = prog->module; - llvm::Function *func = 0; - - switch (prog->type) { - case GALLIVM_VS: - func = mod->getFunction("vs_shader"); - break; - case GALLIVM_FS: - func = mod->getFunction("fs_shader"); - break; - default: - assert(!"Unknown shader type!"); - break; - } - return func; -} - -/*! - This function creates a CPU based execution engine for the given gallivm_prog. - gallivm_cpu_engine should be used as a singleton throughout the library. Before - executing gallivm_prog_exec one needs to call gallivm_cpu_jit_compile. - The gallivm_prog instance which is being passed to the constructor is being - automatically JIT compiled so one shouldn't call gallivm_cpu_jit_compile - with it again. - */ -struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog) -{ - struct gallivm_cpu_engine *cpu = (struct gallivm_cpu_engine *) - calloc(1, sizeof(struct gallivm_cpu_engine)); - llvm::Module *mod = static_cast(prog->module); - llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); - llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false); - ee->DisableLazyCompilation(); - cpu->engine = ee; - - llvm::Function *func = func_for_shader(prog); - - prog->function = ee->getPointerToFunction(func); - CPU = cpu; - return cpu; -} - - -/*! - This function JIT compiles the given gallivm_prog with the given cpu based execution engine. - The reference to the generated machine code entry point will be stored - in the gallivm_prog program. After executing this function one can call gallivm_prog_exec - in order to execute the gallivm_prog on the CPU. - */ -void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog *prog) -{ - llvm::Module *mod = static_cast(prog->module); - llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); - llvm::ExecutionEngine *ee = cpu->engine; - assert(ee); - /*FIXME : remove */ - ee->DisableLazyCompilation(); - ee->addModuleProvider(mp); - - llvm::Function *func = func_for_shader(prog); - prog->function = ee->getPointerToFunction(func); -} - -void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu) -{ - free(cpu); -} - -struct gallivm_cpu_engine * gallivm_global_cpu_engine() -{ - return CPU; -} - - -typedef void (*vertex_shader_runner)(void *ainputs, - void *dests, - float (*aconsts)[4], - void *temps); - - -/*! - This function is used to execute the gallivm_prog in software. Before calling - this function the gallivm_prog has to be JIT compiled with the gallivm_cpu_jit_compile - function. - */ -int gallivm_cpu_vs_exec(struct gallivm_prog *prog, - struct tgsi_exec_vector *inputs, - struct tgsi_exec_vector *dests, - float (*consts)[4], - struct tgsi_exec_vector *temps) -{ - vertex_shader_runner runner = reinterpret_cast(prog->function); - assert(runner); - /*FIXME*/ - runner(inputs, dests, consts, temps); - - return 0; -} - -#endif diff --git a/src/gallium/auxiliary/llvm/gallivm_p.h b/src/gallium/auxiliary/llvm/gallivm_p.h deleted file mode 100644 index cfe7b1901b..0000000000 --- a/src/gallium/auxiliary/llvm/gallivm_p.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef GALLIVM_P_H -#define GALLIVM_P_H - -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "pipe/p_shader_tokens.h" -#include "pipe/p_compiler.h" - -namespace llvm { - class Module; -} - -#if defined __cplusplus -extern "C" { -#endif - -enum gallivm_shader_type; -enum gallivm_vector_layout; - -struct gallivm_interpolate { - int attrib; - int chan; - int type; -}; - -struct gallivm_ir { - llvm::Module *module; - int id; - enum gallivm_shader_type type; - enum gallivm_vector_layout layout; - int num_components; - int num_consts; - - //FIXME: this might not be enough for some shaders - struct gallivm_interpolate interpolators[32*4]; - int num_interp; -}; - -struct gallivm_prog { - llvm::Module *module; - void *function; - - int id; - enum gallivm_shader_type type; - - int num_consts; - - //FIXME: this might not be enough for some shaders - struct gallivm_interpolate interpolators[32*4]; - int num_interp; -}; - -static INLINE void gallivm_swizzle_components(int swizzle, - int *xc, int *yc, - int *zc, int *wc) -{ - int x = swizzle / 1000; swizzle -= x * 1000; - int y = swizzle / 100; swizzle -= y * 100; - int z = swizzle / 10; swizzle -= z * 10; - int w = swizzle; - - if (xc) *xc = x; - if (yc) *yc = y; - if (zc) *zc = z; - if (wc) *wc = w; -} - -static INLINE boolean gallivm_is_swizzle(int swizzle) -{ - const int NO_SWIZZLE = TGSI_SWIZZLE_X * 1000 + TGSI_SWIZZLE_Y * 100 + - TGSI_SWIZZLE_Z * 10 + TGSI_SWIZZLE_W; - return swizzle != NO_SWIZZLE; -} - -static INLINE int gallivm_x_swizzle(int swizzle) -{ - int x; - gallivm_swizzle_components(swizzle, &x, 0, 0, 0); - return x; -} - -static INLINE int gallivm_y_swizzle(int swizzle) -{ - int y; - gallivm_swizzle_components(swizzle, 0, &y, 0, 0); - return y; -} - -static INLINE int gallivm_z_swizzle(int swizzle) -{ - int z; - gallivm_swizzle_components(swizzle, 0, 0, &z, 0); - return z; -} - -static INLINE int gallivm_w_swizzle(int swizzle) -{ - int w; - gallivm_swizzle_components(swizzle, 0, 0, 0, &w); - return w; -} - -#endif /* MESA_LLVM */ - -#if defined __cplusplus -} // extern "C" -#endif - -#endif diff --git a/src/gallium/auxiliary/llvm/instructions.cpp b/src/gallium/auxiliary/llvm/instructions.cpp deleted file mode 100644 index 55d39fa5f1..0000000000 --- a/src/gallium/auxiliary/llvm/instructions.cpp +++ /dev/null @@ -1,889 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "instructions.h" - -#include "storage.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -using namespace llvm; - -#include "gallivm_builtins.cpp" - -static inline std::string createFuncName(int label) -{ - std::ostringstream stream; - stream << "function"; - stream << label; - return stream.str(); -} - -Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, - Storage *storage) - : m_mod(mod), m_func(func), m_builder(block), m_idx(0), - m_storage(storage) -{ - m_floatVecType = VectorType::get(Type::FloatTy, 4); - - m_llvmFSqrt = 0; - m_llvmFAbs = 0; - m_llvmPow = 0; - m_llvmFloor = 0; - m_llvmFlog = 0; - m_llvmLit = 0; - m_fmtPtr = 0; - - createGallivmBuiltins(m_mod); -} - -llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2) -{ - return m_builder.CreateAdd(in1, in2, name("add")); -} - -llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3) -{ - Value *mulRes = mul(in1, in2); - return add(mulRes, in3); -} - -llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2) -{ - return m_builder.CreateMul(in1, in2, name("mul")); -} - -const char * Instructions::name(const char *prefix) -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - Value *x = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(0), - name("extractx")); - Value *y = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(1), - name("extracty")); - Value *z = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(2), - name("extractz")); - Value *xy = m_builder.CreateAdd(x, y,name("xy")); - Value *dot3 = m_builder.CreateAdd(xy, z, name("dot3")); - return vectorFromVals(dot3, dot3, dot3, dot3); -} - -llvm::Value *Instructions::callFSqrt(llvm::Value *val) -{ - if (!m_llvmFSqrt) { - // predeclare the intrinsic - std::vector fsqrtArgs; - fsqrtArgs.push_back(Type::FloatTy); - ParamAttrsList *fsqrtPal = 0; - FunctionType* fsqrtType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/fsqrtArgs, - /*isVarArg=*/false); - m_llvmFSqrt = new Function( - /*Type=*/fsqrtType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"llvm.sqrt.f32", m_mod); - m_llvmFSqrt->setCallingConv(CallingConv::C); - m_llvmFSqrt->setParamAttrs(fsqrtPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFSqrt, val, - name("sqrt")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::rsq(llvm::Value *in1) -{ - Value *x = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("extractx")); - Value *abs = callFAbs(x); - Value *sqrt = callFSqrt(abs); - - Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, - APFloat(1.f)), - sqrt, - name("rsqrt")); - return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt); -} - -llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w) -{ - Constant *const_vec = Constant::getNullValue(m_floatVecType); - Value *res = m_builder.CreateInsertElement(const_vec, x, - m_storage->constantInt(0), - name("vecx")); - res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), - name("vecxy")); - res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), - name("vecxyz")); - if (w) - res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), - name("vecxyzw")); - return res; -} - -llvm::Value *Instructions::callFAbs(llvm::Value *val) -{ - if (!m_llvmFAbs) { - // predeclare the intrinsic - std::vector fabsArgs; - fabsArgs.push_back(Type::FloatTy); - ParamAttrsList *fabsPal = 0; - FunctionType* fabsType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/fabsArgs, - /*isVarArg=*/false); - m_llvmFAbs = new Function( - /*Type=*/fabsType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"fabs", m_mod); - m_llvmFAbs->setCallingConv(CallingConv::C); - m_llvmFAbs->setParamAttrs(fabsPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFAbs, val, - name("fabs")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::lit(llvm::Value *in) -{ - if (!m_llvmLit) { - m_llvmLit = m_mod->getFunction("lit"); - } - CallInst *call = m_builder.CreateCall(m_llvmLit, in, name("litres")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2) -{ - Value *res = m_builder.CreateSub(in1, in2, name("sub")); - return res; -} - -llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2) -{ - if (!m_llvmPow) { - // predeclare the intrinsic - std::vector powArgs; - powArgs.push_back(Type::FloatTy); - powArgs.push_back(Type::FloatTy); - ParamAttrsList *powPal = 0; - FunctionType* powType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/powArgs, - /*isVarArg=*/false); - m_llvmPow = new Function( - /*Type=*/powType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"llvm.pow.f32", m_mod); - m_llvmPow->setCallingConv(CallingConv::C); - m_llvmPow->setParamAttrs(powPal); - } - std::vector params; - params.push_back(val1); - params.push_back(val2); - CallInst *call = m_builder.CreateCall(m_llvmPow, params.begin(), params.end(), - name("pow")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *x2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(0), - name("x2")); - llvm::Value *val = callPow(x1, x2); - return vectorFromVals(val, val, val, val); -} - -llvm::Value * Instructions::rcp(llvm::Value *in1) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *res = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, - APFloat(1.f)), - x1, name("rcp")); - return vectorFromVals(res, res, res, res); -} - -llvm::Value * Instructions::dp4(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - std::vector vec = extractVector(mulRes); - Value *xy = m_builder.CreateAdd(vec[0], vec[1], name("xy")); - Value *xyz = m_builder.CreateAdd(xy, vec[2], name("xyz")); - Value *dot4 = m_builder.CreateAdd(xyz, vec[3], name("dot4")); - return vectorFromVals(dot4, dot4, dot4, dot4); -} - -llvm::Value * Instructions::dph(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - std::vector vec1 = extractVector(mulRes); - Value *xy = m_builder.CreateAdd(vec1[0], vec1[1], name("xy")); - Value *xyz = m_builder.CreateAdd(xy, vec1[2], name("xyz")); - Value *dph = m_builder.CreateAdd(xyz, vec1[3], name("dph")); - return vectorFromVals(dph, dph, dph, dph); -} - -llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2) -{ - Value *y1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(1), - name("y1")); - Value *z = m_builder.CreateExtractElement(in1, - m_storage->constantInt(2), - name("z")); - Value *y2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(1), - name("y2")); - Value *w = m_builder.CreateExtractElement(in2, - m_storage->constantInt(3), - name("w")); - Value *ry = m_builder.CreateMul(y1, y2, name("tyuy")); - return vectorFromVals(ConstantFP::get(Type::FloatTy, APFloat(1.f)), - ry, z, w); -} - -llvm::Value * Instructions::ex2(llvm::Value *in) -{ - llvm::Value *val = callPow(ConstantFP::get(Type::FloatTy, APFloat(2.f)), - m_builder.CreateExtractElement( - in, m_storage->constantInt(0), - name("x1"))); - return vectorFromVals(val, val, val, val); -} - -llvm::Value * Instructions::callFloor(llvm::Value *val) -{ - if (!m_llvmFloor) { - // predeclare the intrinsic - std::vector floorArgs; - floorArgs.push_back(Type::FloatTy); - ParamAttrsList *floorPal = 0; - FunctionType* floorType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/floorArgs, - /*isVarArg=*/false); - m_llvmFloor = new Function( - /*Type=*/floorType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"floorf", m_mod); - m_llvmFloor->setCallingConv(CallingConv::C); - m_llvmFloor->setParamAttrs(floorPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFloor, val, - name("floorf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::floor(llvm::Value *in) -{ - std::vector vec = extractVector(in); - return vectorFromVals(callFloor(vec[0]), callFloor(vec[1]), - callFloor(vec[2]), callFloor(vec[3])); -} - -llvm::Value * Instructions::arl(llvm::Value *in) -{ - return floor(in); -} - -llvm::Value * Instructions::frc(llvm::Value *in) -{ - llvm::Value *flr = floor(in); - return sub(in, flr); -} - -llvm::Value * Instructions::callFLog(llvm::Value *val) -{ - if (!m_llvmFlog) { - // predeclare the intrinsic - std::vector flogArgs; - flogArgs.push_back(Type::FloatTy); - ParamAttrsList *flogPal = 0; - FunctionType* flogType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/flogArgs, - /*isVarArg=*/false); - m_llvmFlog = new Function( - /*Type=*/flogType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"logf", m_mod); - m_llvmFlog->setCallingConv(CallingConv::C); - m_llvmFlog->setParamAttrs(flogPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFlog, val, - name("logf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::lg2(llvm::Value *in) -{ - std::vector vec = extractVector(in); - llvm::Value *const_vec = constVector(1.442695f, 1.442695f, - 1.442695f, 1.442695f); - return mul(vectorFromVals(callFLog(vec[0]), callFLog(vec[1]), - callFLog(vec[2]), callFLog(vec[3])), const_vec); -} - -llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2) -{ - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); - Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], - name("selx")); - - Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); - Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], - name("sely")); - - Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); - Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], - name("selz")); - - Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); - Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], - name("selw")); - - return vectorFromVals(selx, sely, selz, selw); -} - -llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2) -{ - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], - name("xcmp")); - Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], - name("selx")); - - Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], - name("ycmp")); - Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], - name("sely")); - - Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], - name("zcmp")); - Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], - name("selz")); - - Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], - name("wcmp")); - Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], - name("selw")); - - return vectorFromVals(selx, sely, selz, selw); -} - -void Instructions::printVector(llvm::Value *val) -{ - static const char *frmt = "Vector is [%f, %f, %f, %f]\x0A"; - - if (!m_fmtPtr) { - Constant *format = ConstantArray::get(frmt, true); - ArrayType *arrayTy = ArrayType::get(IntegerType::get(8), strlen(frmt) + 1); - GlobalVariable* globalFormat = new GlobalVariable( - /*Type=*/arrayTy, - /*isConstant=*/true, - /*Linkage=*/GlobalValue::InternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name(".str"), - m_mod); - globalFormat->setInitializer(format); - - Constant* const_int0 = Constant::getNullValue(IntegerType::get(32)); - std::vector const_ptr_21_indices; - const_ptr_21_indices.push_back(const_int0); - const_ptr_21_indices.push_back(const_int0); - m_fmtPtr = ConstantExpr::getGetElementPtr(globalFormat, - &const_ptr_21_indices[0], const_ptr_21_indices.size()); - } - - Function *func_printf = m_mod->getFunction("printf"); - if (!func_printf) - func_printf = declarePrintf(); - assert(func_printf); - std::vector vec = extractVector(val); - Value *dx = m_builder.CreateFPExt(vec[0], Type::DoubleTy, name("dx")); - Value *dy = m_builder.CreateFPExt(vec[1], Type::DoubleTy, name("dy")); - Value *dz = m_builder.CreateFPExt(vec[2], Type::DoubleTy, name("dz")); - Value *dw = m_builder.CreateFPExt(vec[3], Type::DoubleTy, name("dw")); - std::vector params; - params.push_back(m_fmtPtr); - params.push_back(dx); - params.push_back(dy); - params.push_back(dz); - params.push_back(dw); - CallInst *call = m_builder.CreateCall(func_printf, params.begin(), params.end(), - name("printf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(true); -} - -llvm::Function * Instructions::declarePrintf() -{ - std::vector args; - ParamAttrsList *params = 0; - FunctionType* funcTy = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/args, - /*isVarArg=*/true); - Function* func_printf = new Function( - /*Type=*/funcTy, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"printf", m_mod); - func_printf->setCallingConv(CallingConv::C); - func_printf->setParamAttrs(params); - return func_printf; -} - - -llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} -llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - - -llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - -llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *y1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(1), - name("y1")); - Value *z1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(2), - name("z1")); - - Value *x2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(0), - name("x2")); - Value *y2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(1), - name("y2")); - Value *z2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(2), - name("z2")); - Value *y1z2 = mul(y1, z2); - Value *z1y2 = mul(z1, y2); - - Value *z1x2 = mul(z1, x2); - Value *x1z2 = mul(x1, z2); - - Value *x1y2 = mul(x1, y2); - Value *y1x2 = mul(y1, x2); - - return vectorFromVals(sub(y1z2, z1y2), sub(z1x2, x1z2), sub(x1y2, y1x2)); -} - - -llvm::Value * Instructions::abs(llvm::Value *in) -{ - std::vector vec = extractVector(in); - Value *xabs = callFAbs(vec[0]); - Value *yabs = callFAbs(vec[1]); - Value *zabs = callFAbs(vec[2]); - Value *wabs = callFAbs(vec[3]); - return vectorFromVals(xabs, yabs, zabs, wabs); -} - -void Instructions::ifop(llvm::Value *in) -{ - BasicBlock *ifthen = new BasicBlock(name("ifthen"), m_func,0); - BasicBlock *ifend = new BasicBlock(name("ifthenend"), m_func,0); - - //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0); - //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0); - //BasicBlock *wblock = new BasicBlock(name("wblock"), m_func,0); - - Constant *float0 = Constant::getNullValue(Type::FloatTy); - - Value *x = m_builder.CreateExtractElement(in, m_storage->constantInt(0), - name("extractx")); - Value *xcmp = m_builder.CreateFCmpUNE(x, float0, name("xcmp")); - m_builder.CreateCondBr(xcmp, ifthen, ifend); - //m_builder.SetInsertPoint(yblock); - - m_builder.SetInsertPoint(ifthen); - m_ifStack.push(ifend); -} - -llvm::BasicBlock * Instructions::currentBlock() const -{ - return m_builder.GetInsertBlock(); -} - -void Instructions::elseop() -{ - assert(!m_ifStack.empty()); - BasicBlock *ifend = new BasicBlock(name("ifend"), m_func,0); - m_builder.CreateBr(ifend); - m_builder.SetInsertPoint(m_ifStack.top()); - currentBlock()->setName(name("ifelse")); - m_ifStack.pop(); - m_ifStack.push(ifend); -} - -void Instructions::endif() -{ - assert(!m_ifStack.empty()); - m_builder.CreateBr(m_ifStack.top()); - m_builder.SetInsertPoint(m_ifStack.top()); - m_ifStack.pop(); -} - -llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3) -{ - llvm::Value *m = mul(in1, in2); - llvm::Value *vec1 = constVector(1.f, 1.f, 1.f, 1.f); - llvm::Value *s = sub(vec1, in1); - return add(m, mul(s, in3)); -} - -void Instructions::beginLoop() -{ - BasicBlock *begin = new BasicBlock(name("loop"), m_func,0); - BasicBlock *end = new BasicBlock(name("endloop"), m_func,0); - - m_builder.CreateBr(begin); - Loop loop; - loop.begin = begin; - loop.end = end; - m_builder.SetInsertPoint(begin); - m_loopStack.push(loop); -} - -void Instructions::endLoop() -{ - assert(!m_loopStack.empty()); - Loop loop = m_loopStack.top(); - m_builder.CreateBr(loop.begin); - loop.end->moveAfter(currentBlock()); - m_builder.SetInsertPoint(loop.end); - m_loopStack.pop(); -} - -void Instructions::brk() -{ - assert(!m_loopStack.empty()); - BasicBlock *unr = new BasicBlock(name("unreachable"), m_func,0); - m_builder.CreateBr(m_loopStack.top().end); - m_builder.SetInsertPoint(unr); -} - -llvm::Value * Instructions::trunc(llvm::Value *in) -{ - std::vector vec = extractVector(in); - Value *icastx = m_builder.CreateFPToSI(vec[0], IntegerType::get(32), - name("ftoix")); - Value *icasty = m_builder.CreateFPToSI(vec[1], IntegerType::get(32), - name("ftoiy")); - Value *icastz = m_builder.CreateFPToSI(vec[2], IntegerType::get(32), - name("ftoiz")); - Value *icastw = m_builder.CreateFPToSI(vec[3], IntegerType::get(32), - name("ftoiw")); - Value *fx = m_builder.CreateSIToFP(icastx, Type::FloatTy, - name("fx")); - Value *fy = m_builder.CreateSIToFP(icasty, Type::FloatTy, - name("fy")); - Value *fz = m_builder.CreateSIToFP(icastz, Type::FloatTy, - name("fz")); - Value *fw = m_builder.CreateSIToFP(icastw, Type::FloatTy, - name("fw")); - return vectorFromVals(fx, fy, fz, fw); -} - -void Instructions::end() -{ - m_builder.CreateRetVoid(); -} - -void Instructions::cal(int label, llvm::Value *input) -{ - std::vector params; - params.push_back(input); - llvm::Function *func = findFunction(label); - - m_builder.CreateCall(func, params.begin(), params.end()); -} - -llvm::Function * Instructions::declareFunc(int label) -{ - PointerType *vecPtr = PointerType::getUnqual(m_floatVecType); - std::vector args; - args.push_back(vecPtr); - args.push_back(vecPtr); - args.push_back(vecPtr); - args.push_back(vecPtr); - ParamAttrsList *params = 0; - FunctionType *funcType = FunctionType::get( - /*Result=*/Type::VoidTy, - /*Params=*/args, - /*isVarArg=*/false); - std::string name = createFuncName(label); - Function *func = new Function( - /*Type=*/funcType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/name.c_str(), m_mod); - func->setCallingConv(CallingConv::C); - func->setParamAttrs(params); - return func; -} - -void Instructions::bgnSub(unsigned label) -{ - llvm::Function *func = findFunction(label); - - Function::arg_iterator args = func->arg_begin(); - Value *ptr_INPUT = args++; - ptr_INPUT->setName("INPUT"); - m_storage->pushArguments(ptr_INPUT); - - llvm::BasicBlock *entry = new BasicBlock("entry", func, 0); - - m_func = func; - m_builder.SetInsertPoint(entry); -} - -void Instructions::endSub() -{ - m_func = 0; - m_builder.SetInsertPoint(0); -} - -llvm::Function * Instructions::findFunction(int label) -{ - llvm::Function *func = m_functions[label]; - if (!func) { - func = declareFunc(label); - m_functions[label] = func; - } - return func; -} - -llvm::Value * Instructions::constVector(float x, float y, float z, float w) -{ - std::vector vec(4); - vec[0] = ConstantFP::get(Type::FloatTy, APFloat(x)); - vec[1] = ConstantFP::get(Type::FloatTy, APFloat(y)); - vec[2] = ConstantFP::get(Type::FloatTy, APFloat(z)); - vec[3] = ConstantFP::get(Type::FloatTy, APFloat(w)); - return ConstantVector::get(m_floatVecType, vec); -} - - -std::vector Instructions::extractVector(llvm::Value *vec) -{ - std::vector elems(4); - elems[0] = m_builder.CreateExtractElement(vec, m_storage->constantInt(0), - name("x")); - elems[1] = m_builder.CreateExtractElement(vec, m_storage->constantInt(1), - name("y")); - elems[2] = m_builder.CreateExtractElement(vec, m_storage->constantInt(2), - name("z")); - elems[3] = m_builder.CreateExtractElement(vec, m_storage->constantInt(3), - name("w")); - return elems; -} - -llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) -{ - llvm::Function *func = m_mod->getFunction("cmp"); - assert(func); - - std::vector params; - params.push_back(in1); - params.push_back(in2); - params.push_back(in3); - CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), name("cmpres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::cos(llvm::Value *in) -{ -#if 0 - llvm::Function *func = m_mod->getFunction("vcos"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("cosres")); - call->setTailCall(false); - return call; -#else - std::vector elems = extractVector(in); - Function *func = m_mod->getFunction("cosf"); - assert(func); - CallInst *cos = m_builder.CreateCall(func, elems[0], name("cosres")); - cos->setCallingConv(CallingConv::C); - cos->setTailCall(true); - return vectorFromVals(cos, cos, cos, cos); -#endif -} - -llvm::Value * Instructions::scs(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("scs"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("scsres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::kilp(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("kilp"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("kilpres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::sin(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("vsin"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("sinres")); - call->setTailCall(false); - return call; -} -#endif //MESA_LLVM - - diff --git a/src/gallium/auxiliary/llvm/instructions.h b/src/gallium/auxiliary/llvm/instructions.h deleted file mode 100644 index 9ebc17dd8e..0000000000 --- a/src/gallium/auxiliary/llvm/instructions.h +++ /dev/null @@ -1,152 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef INSTRUCTIONS_H -#define INSTRUCTIONS_H - -#include -#include -#include -#include - -#include -#include - -namespace llvm { - class VectorType; - class Function; -} - -class Storage; - -class Instructions -{ -public: - Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, - Storage *storage); - - llvm::BasicBlock *currentBlock() const; - - llvm::Value *abs(llvm::Value *in1); - llvm::Value *arl(llvm::Value *in1); - llvm::Value *add(llvm::Value *in1, llvm::Value *in2); - void beginLoop(); - void bgnSub(unsigned); - void brk(); - void cal(int label, llvm::Value *input); - llvm::Value *cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); - llvm::Value *cos(llvm::Value *in); - llvm::Value *cross(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dp3(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dp4(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dph(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dst(llvm::Value *in1, llvm::Value *in2); - void elseop(); - void endif(); - void endLoop(); - void end(); - void endSub(); - llvm::Value *ex2(llvm::Value *in); - llvm::Value *floor(llvm::Value *in); - llvm::Value *frc(llvm::Value *in); - void ifop(llvm::Value *in); - llvm::Value *kilp(llvm::Value *in); - llvm::Value *lerp(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3); - llvm::Value *lit(llvm::Value *in); - llvm::Value *lg2(llvm::Value *in); - llvm::Value *madd(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in2); - llvm::Value *min(llvm::Value *in1, llvm::Value *in2); - llvm::Value *max(llvm::Value *in1, llvm::Value *in2); - llvm::Value *mul(llvm::Value *in1, llvm::Value *in2); - llvm::Value *pow(llvm::Value *in1, llvm::Value *in2); - llvm::Value *rcp(llvm::Value *in); - llvm::Value *rsq(llvm::Value *in); - llvm::Value *scs(llvm::Value *in); - llvm::Value *sge(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sgt(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sin(llvm::Value *in); - llvm::Value *slt(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sub(llvm::Value *in1, llvm::Value *in2); - llvm::Value *trunc(llvm::Value *in); - - void printVector(llvm::Value *val); -private: - const char *name(const char *prefix); - - llvm::Value *callFAbs(llvm::Value *val); - llvm::Value *callFloor(llvm::Value *val); - llvm::Value *callFSqrt(llvm::Value *val); - llvm::Value *callFLog(llvm::Value *val); - llvm::Value *callPow(llvm::Value *val1, llvm::Value *val2); - - llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w=0); - - llvm::Value *constVector(float x, float y, float z, float w); - - llvm::Function *declarePrintf(); - llvm::Function *declareFunc(int label); - - llvm::Function *findFunction(int label); - - std::vector extractVector(llvm::Value *vec); -private: - llvm::Module *m_mod; - llvm::Function *m_func; - char m_name[32]; - llvm::LLVMFoldingBuilder m_builder; - int m_idx; - - llvm::VectorType *m_floatVecType; - - llvm::Function *m_llvmFSqrt; - llvm::Function *m_llvmFAbs; - llvm::Function *m_llvmPow; - llvm::Function *m_llvmFloor; - llvm::Function *m_llvmFlog; - llvm::Function *m_llvmLit; - - llvm::Constant *m_fmtPtr; - - std::stack m_ifStack; - struct Loop { - llvm::BasicBlock *begin; - llvm::BasicBlock *end; - }; - std::stack m_loopStack; - std::map m_functions; - Storage *m_storage; -}; - -#endif diff --git a/src/gallium/auxiliary/llvm/instructionssoa.cpp b/src/gallium/auxiliary/llvm/instructionssoa.cpp deleted file mode 100644 index a4d5046637..0000000000 --- a/src/gallium/auxiliary/llvm/instructionssoa.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "instructionssoa.h" - -#include "storagesoa.h" - -#include - -using namespace llvm; - -InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, - llvm::BasicBlock *block, StorageSoa *storage) - : m_builder(block), - m_storage(storage), - m_idx(0) -{ -} - -const char * InstructionsSoa::name(const char *prefix) const -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - Constant *constVector = Constant::getNullValue(vectorType); - Value *res = m_builder.CreateInsertElement(constVector, x, - m_storage->constantInt(0), - name("vecx")); - res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), - name("vecxy")); - res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), - name("vecxyz")); - if (w) - res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), - name("vecxyzw")); - return res; -} - -std::vector InstructionsSoa::arl(const std::vector in) -{ - std::vector res(4); - - //Extract x's - llvm::Value *x1 = m_builder.CreateExtractElement(in[0], - m_storage->constantInt(0), - name("extractX")); - //cast it to an unsigned int - x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast")); - - res[0] = x1;//vectorFromVals(x1, x2, x3, x4); - //only x is valid. the others shouldn't be necessary - /* - res[1] = Constant::getNullValue(m_floatVecType); - res[2] = Constant::getNullValue(m_floatVecType); - res[3] = Constant::getNullValue(m_floatVecType); - */ - - return res; -} - - -std::vector InstructionsSoa::add(const std::vector in1, - const std::vector in2) -{ - std::vector res(4); - - res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx")); - res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy")); - res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz")); - res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw")); - - return res; -} - -std::vector InstructionsSoa::mul(const std::vector in1, - const std::vector in2) -{ - std::vector res(4); - - res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx")); - res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly")); - res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz")); - res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw")); - - return res; -} - -void InstructionsSoa::end() -{ - m_builder.CreateRetVoid(); -} - -std::vector InstructionsSoa::madd(const std::vector in1, - const std::vector in2, - const std::vector in3) -{ - std::vector res = mul(in1, in2); - return add(res, in3); -} - -std::vector InstructionsSoa::extractVector(llvm::Value *vector) -{ - std::vector res(4); - res[0] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(0), - name("extract1X")); - res[1] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(1), - name("extract2X")); - res[2] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(2), - name("extract3X")); - res[3] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(3), - name("extract4X")); - - return res; -} diff --git a/src/gallium/auxiliary/llvm/instructionssoa.h b/src/gallium/auxiliary/llvm/instructionssoa.h deleted file mode 100644 index 4169dcbb2e..0000000000 --- a/src/gallium/auxiliary/llvm/instructionssoa.h +++ /dev/null @@ -1,74 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INSTRUCTIONSSOA_H -#define INSTRUCTIONSSOA_H - -#include - -#include - -namespace llvm { - class Module; - class Function; - class BasicBlock; - class Value; -} -class StorageSoa; - -class InstructionsSoa -{ -public: - InstructionsSoa(llvm::Module *mod, llvm::Function *func, - llvm::BasicBlock *block, StorageSoa *storage); - - std::vector arl(const std::vector in); - - std::vector add(const std::vector in1, - const std::vector in2); - std::vector madd(const std::vector in1, - const std::vector in2, - const std::vector in3); - std::vector mul(const std::vector in1, - const std::vector in2); - void end(); - - std::vector extractVector(llvm::Value *vector); -private: - const char * name(const char *prefix) const; - llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w); -private: - llvm::LLVMFoldingBuilder m_builder; - StorageSoa *m_storage; -private: - mutable int m_idx; - mutable char m_name[32]; -}; - - -#endif diff --git a/src/gallium/auxiliary/llvm/llvm_builtins.c b/src/gallium/auxiliary/llvm/llvm_builtins.c deleted file mode 100644 index 4f98d754ba..0000000000 --- a/src/gallium/auxiliary/llvm/llvm_builtins.c +++ /dev/null @@ -1,115 +0,0 @@ -/*clang --emit-llvm llvm_builtins.c |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=gallivm_builtins.cpp -f -for=shader -funcname=createGallivmBuiltins*/ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -typedef __attribute__(( ocu_vector_type(4) )) float float4; - -extern float powf(float a, float b); - -inline float approx(float a, float b) -{ - if (b < -128.0f) b = -128.0f; - if (b > 128.0f) b = 128.0f; - if (a < 0) a = 0; - return powf(a, b); -} - -inline float4 lit(float4 tmp) -{ - float4 result; - result.x = 1.0; - result.w = 1.0; - if (tmp.x > 0) { - result.y = tmp.x; - result.z = approx(tmp.y, tmp.w); - } else { - result.y = 0; - result.z = 0; - } - return result; -} - -inline float4 cmp(float4 tmp0, float4 tmp1, float4 tmp2) -{ - float4 result; - - result.x = (tmp0.x < 0.0) ? tmp1.x : tmp2.x; - result.y = (tmp0.y < 0.0) ? tmp1.y : tmp2.y; - result.z = (tmp0.z < 0.0) ? tmp1.z : tmp2.z; - result.w = (tmp0.w < 0.0) ? tmp1.w : tmp2.w; - - return result; -} - -extern float cosf(float val); -extern float sinf(float val); - -inline float4 vcos(float4 val) -{ - float4 result; - printf("VEC IN is %f %f %f %f\n", val.x, val.y, val.z, val.w); - result.x = cosf(val.x); - result.y = cosf(val.x); - result.z = cosf(val.x); - result.w = cosf(val.x); - printf("VEC OUT is %f %f %f %f\n", result.x, result.y, result.z, result.w); - return result; -} - -inline float4 scs(float4 val) -{ - float4 result; - float tmp = val.x; - result.x = cosf(tmp); - result.y = sinf(tmp); - return result; -} - - -inline float4 vsin(float4 val) -{ - float4 result; - float tmp = val.x; - float res = sinf(tmp); - result.x = res; - result.y = res; - result.z = res; - result.w = res; - return result; -} - -inline int kilp(float4 val) -{ - if (val.x < 0 || val.y < 0 || val.z < 0 || val.w < 0) - return 1; - else - return 0; -} diff --git a/src/gallium/auxiliary/llvm/loweringpass.cpp b/src/gallium/auxiliary/llvm/loweringpass.cpp deleted file mode 100644 index 556dbec366..0000000000 --- a/src/gallium/auxiliary/llvm/loweringpass.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "loweringpass.h" - -using namespace llvm; - -char LoweringPass::ID = 0; -RegisterPass X("lowering", "Lowering Pass"); - -LoweringPass::LoweringPass() - : ModulePass((intptr_t)&ID) -{ -} - -bool LoweringPass::runOnModule(Module &m) -{ - llvm::cerr << "Hello: " << m.getModuleIdentifier() << "\n"; - return false; -} diff --git a/src/gallium/auxiliary/llvm/loweringpass.h b/src/gallium/auxiliary/llvm/loweringpass.h deleted file mode 100644 index f62dcf6ba7..0000000000 --- a/src/gallium/auxiliary/llvm/loweringpass.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LOWERINGPASS_H -#define LOWERINGPASS_H - -#include "llvm/Pass.h" -#include "llvm/Module.h" - -struct LoweringPass : public llvm::ModulePass -{ - static char ID; - LoweringPass(); - - virtual bool runOnModule(llvm::Module &m); -}; - -#endif diff --git a/src/gallium/auxiliary/llvm/storage.cpp b/src/gallium/auxiliary/llvm/storage.cpp deleted file mode 100644 index c4326de8c5..0000000000 --- a/src/gallium/auxiliary/llvm/storage.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "storage.h" - -#include "gallivm_p.h" - -#include "pipe/p_shader_tokens.h" -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace llvm; - -Storage::Storage(llvm::BasicBlock *block, llvm::Value *input) - : m_block(block), - m_INPUT(input), - m_addrs(32), - m_idx(0) -{ - m_floatVecType = VectorType::get(Type::FloatTy, 4); - m_intVecType = VectorType::get(IntegerType::get(32), 4); - - m_undefFloatVec = UndefValue::get(m_floatVecType); - m_undefIntVec = UndefValue::get(m_intVecType); - m_extSwizzleVec = 0; - - m_numConsts = 0; -} - -//can only build vectors with all members in the [0, 9] range -llvm::Constant *Storage::shuffleMask(int vec) -{ - if (!m_extSwizzleVec) { - std::vector elems; - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); - m_extSwizzleVec = ConstantVector::get(m_floatVecType, elems); - } - - if (m_intVecs.find(vec) != m_intVecs.end()) { - return m_intVecs[vec]; - } - int origVec = vec; - Constant* const_vec = 0; - if (origVec == 0) { - const_vec = Constant::getNullValue(m_intVecType); - } else { - int x = gallivm_x_swizzle(vec); - int y = gallivm_y_swizzle(vec); - int z = gallivm_z_swizzle(vec); - int w = gallivm_w_swizzle(vec); - std::vector elems; - elems.push_back(constantInt(x)); - elems.push_back(constantInt(y)); - elems.push_back(constantInt(z)); - elems.push_back(constantInt(w)); - const_vec = ConstantVector::get(m_intVecType, elems); - } - - m_intVecs[origVec] = const_vec; - return const_vec; -} - -llvm::ConstantInt *Storage::constantInt(int idx) -{ - if (m_constInts.find(idx) != m_constInts.end()) { - return m_constInts[idx]; - } - ConstantInt *const_int = ConstantInt::get(APInt(32, idx)); - m_constInts[idx] = const_int; - return const_int; -} - -llvm::Value *Storage::inputElement(int idx, llvm::Value *indIdx) -{ - Value *val = element(InputsArg, idx, indIdx); - LoadInst *load = new LoadInst(val, name("input"), false, m_block); - load->setAlignment(8); - - return load; -} - -llvm::Value *Storage::constElement(int idx, llvm::Value *indIdx) -{ - m_numConsts = ((idx + 1) > m_numConsts) ? (idx + 1) : m_numConsts; - - Value *elem = element(ConstsArg, idx, indIdx); - LoadInst *load = new LoadInst(elem, name("const"), false, m_block); - load->setAlignment(8); - return load; -} - -llvm::Value *Storage::shuffleVector(llvm::Value *vec, int shuffle) -{ - Constant *mask = shuffleMask(shuffle); - ShuffleVectorInst *res = - new ShuffleVectorInst(vec, m_extSwizzleVec, mask, - name("shuffle"), m_block); - return res; -} - - -llvm::Value *Storage::tempElement(int idx, llvm::Value *indIdx) -{ - Value *elem = element(TempsArg, idx, indIdx); - - LoadInst *load = new LoadInst(elem, name("temp"), false, m_block); - load->setAlignment(8); - - return load; -} - -void Storage::setTempElement(int idx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = 0; - if (m_tempWriteMap[idx]) - templ = tempElement(idx); - val = maskWrite(val, mask, templ); - } - Value *elem = element(TempsArg, idx); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); - m_tempWriteMap[idx] = true; -} - -void Storage::setOutputElement(int dstIdx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = 0; - if (m_destWriteMap[dstIdx]) - templ = outputElement(dstIdx); - val = maskWrite(val, mask, templ); - } - - Value *elem = element(DestsArg, dstIdx); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); - m_destWriteMap[dstIdx] = true; -} - -llvm::Value *Storage::maskWrite(llvm::Value *src, int mask, llvm::Value *templ) -{ - llvm::Value *dst = templ; - if (!dst) - dst = Constant::getNullValue(m_floatVecType); - if ((mask & TGSI_WRITEMASK_X)) { - llvm::Value *x = new ExtractElementInst(src, unsigned(0), - name("x"), m_block); - dst = new InsertElementInst(dst, x, unsigned(0), - name("dstx"), m_block); - } - if ((mask & TGSI_WRITEMASK_Y)) { - llvm::Value *y = new ExtractElementInst(src, unsigned(1), - name("y"), m_block); - dst = new InsertElementInst(dst, y, unsigned(1), - name("dsty"), m_block); - } - if ((mask & TGSI_WRITEMASK_Z)) { - llvm::Value *z = new ExtractElementInst(src, unsigned(2), - name("z"), m_block); - dst = new InsertElementInst(dst, z, unsigned(2), - name("dstz"), m_block); - } - if ((mask & TGSI_WRITEMASK_W)) { - llvm::Value *w = new ExtractElementInst(src, unsigned(3), - name("w"), m_block); - dst = new InsertElementInst(dst, w, unsigned(3), - name("dstw"), m_block); - } - return dst; -} - -const char * Storage::name(const char *prefix) -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -int Storage::numConsts() const -{ - return m_numConsts; -} - -llvm::Value * Storage::addrElement(int idx) const -{ - Value *ret = m_addrs[idx]; - if (!ret) - return m_undefFloatVec; - return ret; -} - -void Storage::setAddrElement(int idx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = m_addrs[idx]; - val = maskWrite(val, mask, templ); - } - m_addrs[idx] = val; -} - -llvm::Value * Storage::extractIndex(llvm::Value *vec) -{ - llvm::Value *x = new ExtractElementInst(vec, unsigned(0), - name("x"), m_block); - return new FPToSIInst(x, IntegerType::get(32), name("intidx"), m_block); -} - -void Storage::setCurrentBlock(llvm::BasicBlock *block) -{ - m_block = block; -} - -llvm::Value * Storage::outputElement(int idx, llvm::Value *indIdx) -{ - Value *elem = element(DestsArg, idx, indIdx); - LoadInst *load = new LoadInst(elem, name("output"), false, m_block); - load->setAlignment(8); - - return load; -} - -llvm::Value * Storage::inputPtr() const -{ - return m_INPUT; -} - -void Storage::pushArguments(llvm::Value *input) -{ - m_argStack.push(m_INPUT); - - m_INPUT = input; -} - -void Storage::popArguments() -{ - m_INPUT = m_argStack.top(); - m_argStack.pop(); -} - -void Storage::pushTemps() -{ - m_extSwizzleVec = 0; -} - -void Storage::popTemps() -{ -} - -llvm::Value * Storage::immediateElement(int idx) -{ - return m_immediates[idx]; -} - -void Storage::addImmediate(float *val) -{ - std::vector vec(4); - vec[0] = ConstantFP::get(Type::FloatTy, APFloat(val[0])); - vec[1] = ConstantFP::get(Type::FloatTy, APFloat(val[1])); - vec[2] = ConstantFP::get(Type::FloatTy, APFloat(val[2])); - vec[3] = ConstantFP::get(Type::FloatTy, APFloat(val[3])); - m_immediates.push_back(ConstantVector::get(m_floatVecType, vec)); -} - - -llvm::Value * Storage::elemPtr(Args arg) -{ - std::vector indices; - indices.push_back(constantInt(0)); - indices.push_back(constantInt(static_cast(arg))); - GetElementPtrInst *getElem = new GetElementPtrInst(m_INPUT, - indices.begin(), - indices.end(), - name("input_ptr"), - m_block); - return new LoadInst(getElem, name("input_field"), false, m_block); -} - -llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, - llvm::Value *indIdx ) -{ - GetElementPtrInst *getElem = 0; - - if (indIdx) { - getElem = new GetElementPtrInst(ptr, - BinaryOperator::create(Instruction::Add, - indIdx, - constantInt(idx), - name("add"), - m_block), - name("field"), - m_block); - } else { - getElem = new GetElementPtrInst(ptr, - constantInt(idx), - name("field"), - m_block); - } - return getElem; -} - -llvm::Value * Storage::element(Args arg, int idx, llvm::Value *indIdx ) -{ - Value *val = elemPtr(arg); - return elemIdx(val, idx, indIdx); -} - -void Storage::setKilElement(llvm::Value *val) -{ - std::vector indices; - indices.push_back(constantInt(0)); - indices.push_back(constantInt(static_cast(KilArg))); - GetElementPtrInst *elem = new GetElementPtrInst(m_INPUT, - indices.begin(), - indices.end(), - name("kil_ptr"), - m_block); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); -} - -#endif //MESA_LLVM - - diff --git a/src/gallium/auxiliary/llvm/storage.h b/src/gallium/auxiliary/llvm/storage.h deleted file mode 100644 index 8574f7554e..0000000000 --- a/src/gallium/auxiliary/llvm/storage.h +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef STORAGE_H -#define STORAGE_H - -#include -#include -#include -#include - -namespace llvm { - class BasicBlock; - class Constant; - class ConstantInt; - class LoadInst; - class Value; - class VectorType; -} - -class Storage -{ -public: - Storage(llvm::BasicBlock *block, - llvm::Value *input); - - llvm::Value *inputPtr() const; - - void setCurrentBlock(llvm::BasicBlock *block); - - llvm::ConstantInt *constantInt(int); - llvm::Constant *shuffleMask(int vec); - llvm::Value *inputElement(int idx, llvm::Value *indIdx =0); - llvm::Value *constElement(int idx, llvm::Value *indIdx =0); - llvm::Value *outputElement(int idx, llvm::Value *indIdx =0); - llvm::Value *tempElement(int idx, llvm::Value *indIdx =0); - llvm::Value *immediateElement(int idx); - - void setOutputElement(int dstIdx, llvm::Value *val, int mask); - void setTempElement(int idx, llvm::Value *val, int mask); - - llvm::Value *addrElement(int idx) const; - void setAddrElement(int idx, llvm::Value *val, int mask); - - void setKilElement(llvm::Value *val); - - llvm::Value *shuffleVector(llvm::Value *vec, int shuffle); - - llvm::Value *extractIndex(llvm::Value *vec); - - int numConsts() const; - - void pushArguments(llvm::Value *input); - void popArguments(); - void pushTemps(); - void popTemps(); - - void addImmediate(float *val); - -private: - llvm::Value *maskWrite(llvm::Value *src, int mask, llvm::Value *templ); - const char *name(const char *prefix); - - enum Args { - DestsArg = 0, - InputsArg = 1, - TempsArg = 2, - ConstsArg = 3, - KilArg = 4 - }; - llvm::Value *elemPtr(Args arg); - llvm::Value *elemIdx(llvm::Value *ptr, int idx, - llvm::Value *indIdx = 0); - llvm::Value *element(Args arg, int idx, llvm::Value *indIdx = 0); - -private: - llvm::BasicBlock *m_block; - llvm::Value *m_INPUT; - - std::map m_constInts; - std::map m_intVecs; - std::vector m_addrs; - std::vector m_immediates; - - llvm::VectorType *m_floatVecType; - llvm::VectorType *m_intVecType; - - char m_name[32]; - int m_idx; - - int m_numConsts; - - std::map m_destWriteMap; - std::map m_tempWriteMap; - - llvm::Value *m_undefFloatVec; - llvm::Value *m_undefIntVec; - llvm::Value *m_extSwizzleVec; - - std::stack m_argStack; - std::stack > m_tempStack; -}; - -#endif diff --git a/src/gallium/auxiliary/llvm/storagesoa.cpp b/src/gallium/auxiliary/llvm/storagesoa.cpp deleted file mode 100644 index ed0674a96f..0000000000 --- a/src/gallium/auxiliary/llvm/storagesoa.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "storagesoa.h" - -#include "gallivm_p.h" - -#include "pipe/p_shader_tokens.h" -#include "pipe/p_debug.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace llvm; - - -StorageSoa::StorageSoa(llvm::BasicBlock *block, - llvm::Value *input, - llvm::Value *output, - llvm::Value *consts, - llvm::Value *temps) - : m_block(block), - m_input(input), - m_output(output), - m_consts(consts), - m_temps(temps), - m_immediates(0), - m_idx(0) -{ -} - -void StorageSoa::addImmediate(float *vec) -{ - std::vector vals(4); - vals[0] = vec[0]; - vals[1] = vec[1]; - vals[2] = vec[2]; - vals[3] = vec[3]; - m_immediatesToFlush.push_back(vals); -} - -void StorageSoa::declareImmediates() -{ - if (m_immediatesToFlush.empty()) - return; - - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - ArrayType *vectorChannels = ArrayType::get(vectorType, 4); - ArrayType *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size()); - - m_immediates = new GlobalVariable( - /*Type=*/arrayType, - /*isConstant=*/false, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name("immediates"), - currentModule()); - - std::vector arrayVals; - for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) { - std::vector vec = m_immediatesToFlush[i]; - std::vector vals(4); - std::vector channelArray; - - vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0]; - llvm::Constant *xChannel = createConstGlobalVector(vals); - - vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1]; - llvm::Constant *yChannel = createConstGlobalVector(vals); - - vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2]; - llvm::Constant *zChannel = createConstGlobalVector(vals); - - vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3]; - llvm::Constant *wChannel = createConstGlobalVector(vals); - channelArray.push_back(xChannel); - channelArray.push_back(yChannel); - channelArray.push_back(zChannel); - channelArray.push_back(wChannel); - Constant *constChannels = ConstantArray::get(vectorChannels, - channelArray); - arrayVals.push_back(constChannels); - } - Constant *constArray = ConstantArray::get(arrayType, arrayVals); - m_immediates->setInitializer(constArray); - - m_immediatesToFlush.clear(); -} - -llvm::Value *StorageSoa::addrElement(int idx) const -{ - std::map::const_iterator itr = m_addresses.find(idx); - if (itr == m_addresses.end()) { - debug_printf("Trying to access invalid shader 'address'\n"); - return 0; - } - llvm::Value * res = (*itr).second; - - res = new LoadInst(res, name("addr"), false, m_block); - - return res; -} - -std::vector StorageSoa::inputElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_input, idx, 0); - res[1] = element(m_input, idx, 1); - res[2] = element(m_input, idx, 2); - res[3] = element(m_input, idx, 3); - - return res; -} - -std::vector StorageSoa::constElement(llvm::Value *idx) -{ - std::vector res(4); - llvm::Value *xChannel, *yChannel, *zChannel, *wChannel; - - xChannel = elementPointer(m_consts, idx, 0); - yChannel = elementPointer(m_consts, idx, 1); - zChannel = elementPointer(m_consts, idx, 2); - wChannel = elementPointer(m_consts, idx, 3); - - res[0] = alignedArrayLoad(xChannel); - res[1] = alignedArrayLoad(yChannel); - res[2] = alignedArrayLoad(zChannel); - res[3] = alignedArrayLoad(wChannel); - - return res; -} - -std::vector StorageSoa::outputElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_output, idx, 0); - res[1] = element(m_output, idx, 1); - res[2] = element(m_output, idx, 2); - res[3] = element(m_output, idx, 3); - - return res; -} - -std::vector StorageSoa::tempElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_temps, idx, 0); - res[1] = element(m_temps, idx, 1); - res[2] = element(m_temps, idx, 2); - res[3] = element(m_temps, idx, 3); - - return res; -} - -std::vector StorageSoa::immediateElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_immediates, idx, 0); - res[1] = element(m_immediates, idx, 1); - res[2] = element(m_immediates, idx, 2); - res[3] = element(m_immediates, idx, 3); - - return res; -} - -llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, llvm::Value *index, - int channel) const -{ - std::vector indices; - if (m_immediates == ptr) - indices.push_back(constantInt(0)); - indices.push_back(index); - indices.push_back(constantInt(channel)); - - GetElementPtrInst *getElem = new GetElementPtrInst(ptr, - indices.begin(), - indices.end(), - name("ptr"), - m_block); - return getElem; -} - -llvm::Value * StorageSoa::element(llvm::Value *ptr, llvm::Value *index, - int channel) const -{ - llvm::Value *res = elementPointer(ptr, index, channel); - LoadInst *load = new LoadInst(res, name("element"), false, m_block); - //load->setAlignment(8); - return load; -} - -const char * StorageSoa::name(const char *prefix) const -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::ConstantInt * StorageSoa::constantInt(int idx) const -{ - if (m_constInts.find(idx) != m_constInts.end()) { - return m_constInts[idx]; - } - ConstantInt *constInt = ConstantInt::get(APInt(32, idx)); - m_constInts[idx] = constInt; - return constInt; -} - -llvm::Value *StorageSoa::alignedArrayLoad(llvm::Value *val) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - PointerType *vectorPtr = PointerType::get(vectorType, 0); - - CastInst *cast = new BitCastInst(val, vectorPtr, name("toVector"), m_block); - LoadInst *load = new LoadInst(cast, name("alignLoad"), false, m_block); - load->setAlignment(8); - return load; -} - -llvm::Module * StorageSoa::currentModule() const -{ - if (!m_block || !m_block->getParent()) - return 0; - - return m_block->getParent()->getParent(); -} - -llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &vec) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - std::vector immValues; - ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0])); - ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1])); - ConstantFP *constz = ConstantFP::get(Type::FloatTy, APFloat(vec[2])); - ConstantFP *constw = ConstantFP::get(Type::FloatTy, APFloat(vec[3])); - immValues.push_back(constx); - immValues.push_back(consty); - immValues.push_back(constz); - immValues.push_back(constw); - Constant *constVector = ConstantVector::get(vectorType, immValues); - - return constVector; -} - -std::vector StorageSoa::load(Argument type, int idx, int swizzle, - llvm::Value *indIdx) -{ - std::vector val(4); - - //if we have an indirect index, always use that - // if not use the integer offset to create one - llvm::Value *realIndex = 0; - if (indIdx) - realIndex = indIdx; - else - realIndex = constantInt(idx); - debug_printf("XXXXXXXXX realIdx = %p, indIdx = %p\n", realIndex, indIdx); - - switch(type) { - case Input: - val = inputElement(realIndex); - break; - case Output: - val = outputElement(realIndex); - break; - case Temp: - val = tempElement(realIndex); - break; - case Const: - val = constElement(realIndex); - break; - case Immediate: - val = immediateElement(realIndex); - break; - case Address: - debug_printf("Address not handled in the load phase!\n"); - assert(0); - break; - } - if (!gallivm_is_swizzle(swizzle)) - return val; - - std::vector res(4); - - res[0] = val[gallivm_x_swizzle(swizzle)]; - res[1] = val[gallivm_y_swizzle(swizzle)]; - res[2] = val[gallivm_z_swizzle(swizzle)]; - res[3] = val[gallivm_w_swizzle(swizzle)]; - return res; -} - -void StorageSoa::store(Argument type, int idx, const std::vector &val, - int mask) -{ - llvm::Value *out = 0; - switch(type) { - case Output: - out = m_output; - break; - case Temp: - out = m_temps; - break; - case Input: - out = m_input; - break; - case Address: { - llvm::Value *addr = m_addresses[idx]; - if (!addr) { - addAddress(idx); - addr = m_addresses[idx]; - assert(addr); - } - new StoreInst(val[0], addr, false, m_block); - return; - break; - } - default: - debug_printf("Can't save output of this type: %d !\n", type); - assert(0); - break; - } - llvm::Value *realIndex = constantInt(idx); - if ((mask & TGSI_WRITEMASK_X)) { - llvm::Value *xChannel = elementPointer(out, realIndex, 0); - new StoreInst(val[0], xChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_Y)) { - llvm::Value *yChannel = elementPointer(out, realIndex, 1); - new StoreInst(val[1], yChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_Z)) { - llvm::Value *zChannel = elementPointer(out, realIndex, 2); - new StoreInst(val[2], zChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_W)) { - llvm::Value *wChannel = elementPointer(out, realIndex, 3); - new StoreInst(val[3], wChannel, false, m_block); - } -} - -void StorageSoa::addAddress(int idx) -{ - GlobalVariable *val = new GlobalVariable( - /*Type=*/IntegerType::get(32), - /*isConstant=*/false, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name("address"), - currentModule()); - val->setInitializer(Constant::getNullValue(IntegerType::get(32))); - - debug_printf("adding to %d\n", idx); - m_addresses[idx] = val; -} diff --git a/src/gallium/auxiliary/llvm/storagesoa.h b/src/gallium/auxiliary/llvm/storagesoa.h deleted file mode 100644 index 6443351f27..0000000000 --- a/src/gallium/auxiliary/llvm/storagesoa.h +++ /dev/null @@ -1,111 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef STORAGESOA_H -#define STORAGESOA_H - -#include -#include -#include - -namespace llvm { - class BasicBlock; - class Constant; - class ConstantInt; - class GlobalVariable; - class LoadInst; - class Value; - class VectorType; - class Module; -} - -class StorageSoa -{ -public: - enum Argument { - Input, - Output, - Temp, - Const, - Immediate, - Address - }; -public: - StorageSoa(llvm::BasicBlock *block, - llvm::Value *input, - llvm::Value *output, - llvm::Value *consts, - llvm::Value *temps); - - - std::vector load(Argument type, int idx, int swizzle, - llvm::Value *indIdx =0); - void store(Argument type, int idx, const std::vector &val, - int mask); - - void addImmediate(float *vec); - void declareImmediates(); - - void addAddress(int idx); - - llvm::Value * addrElement(int idx) const; - - llvm::ConstantInt *constantInt(int) const; -private: - llvm::Value *elementPointer(llvm::Value *ptr, llvm::Value *indIdx, - int channel) const; - llvm::Value *element(llvm::Value *ptr, llvm::Value *idx, - int channel) const; - const char *name(const char *prefix) const; - llvm::Value *alignedArrayLoad(llvm::Value *val); - llvm::Module *currentModule() const; - llvm::Constant *createConstGlobalVector(const std::vector &vec); - - std::vector inputElement(llvm::Value *indIdx); - std::vector constElement(llvm::Value *indIdx); - std::vector outputElement(llvm::Value *indIdx); - std::vector tempElement(llvm::Value *indIdx); - std::vector immediateElement(llvm::Value *indIdx); -private: - llvm::BasicBlock *m_block; - - llvm::Value *m_input; - llvm::Value *m_output; - llvm::Value *m_consts; - llvm::Value *m_temps; - llvm::GlobalVariable *m_immediates; - - std::map m_addresses; - - std::vector > m_immediatesToFlush; - - mutable std::map m_constInts; - mutable char m_name[32]; - mutable int m_idx; -}; - -#endif diff --git a/src/gallium/auxiliary/llvm/tgsitollvm.cpp b/src/gallium/auxiliary/llvm/tgsitollvm.cpp deleted file mode 100644 index 2cb4acce32..0000000000 --- a/src/gallium/auxiliary/llvm/tgsitollvm.cpp +++ /dev/null @@ -1,1221 +0,0 @@ -#include "tgsitollvm.h" - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "storage.h" -#include "instructions.h" -#include "storagesoa.h" -#include "instructionssoa.h" - -#include "pipe/p_shader_tokens.h" - -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_util.h" -#include "tgsi/util/tgsi_build.h" -#include "tgsi/util/tgsi_dump.h" - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include - -using namespace llvm; - -static inline FunctionType *vertexShaderFunctionType() -{ - //Function takes three arguments, - // the calling code has to make sure the types it will - // pass are castable to the following: - // [4 x <4 x float>] inputs, - // [4 x <4 x float>] output, - // [4 x [4 x float]] consts, - // [4 x <4 x float>] temps - - std::vector funcArgs; - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - ArrayType *vectorArray = ArrayType::get(vectorType, 4); - PointerType *vectorArrayPtr = PointerType::get(vectorArray, 0); - - ArrayType *floatArray = ArrayType::get(Type::FloatTy, 4); - ArrayType *constsArray = ArrayType::get(floatArray, 4); - PointerType *constsArrayPtr = PointerType::get(constsArray, 0); - - funcArgs.push_back(vectorArrayPtr);//inputs - funcArgs.push_back(vectorArrayPtr);//output - funcArgs.push_back(constsArrayPtr);//consts - funcArgs.push_back(vectorArrayPtr);//temps - - FunctionType *functionType = FunctionType::get( - /*Result=*/Type::VoidTy, - /*Params=*/funcArgs, - /*isVarArg=*/false); - - return functionType; -} - -static inline void -add_interpolator(struct gallivm_ir *ir, - struct gallivm_interpolate *interp) -{ - ir->interpolators[ir->num_interp] = *interp; - ++ir->num_interp; -} - -static void -translate_declaration(struct gallivm_ir *prog, - llvm::Module *module, - Storage *storage, - struct tgsi_full_declaration *decl, - struct tgsi_full_declaration *fd) -{ - if (decl->Declaration.File == TGSI_FILE_INPUT) { - unsigned first, last, mask; - uint interp_method; - - assert(decl->Declaration.Declare == TGSI_DECLARE_RANGE); - - first = decl->u.DeclarationRange.First; - last = decl->u.DeclarationRange.Last; - mask = decl->Declaration.UsageMask; - - /* Do not touch WPOS.xy */ - if (first == 0) { - mask &= ~TGSI_WRITEMASK_XY; - if (mask == TGSI_WRITEMASK_NONE) { - first++; - if (first > last) { - return; - } - } - } - - interp_method = decl->Interpolation.Interpolate; - - if (mask == TGSI_WRITEMASK_XYZW) { - unsigned i, j; - - for (i = first; i <= last; i++) { - for (j = 0; j < NUM_CHANNELS; j++) { - //interp( mach, i, j ); - struct gallivm_interpolate interp; - interp.type = interp_method; - interp.attrib = i; - interp.chan = j; - add_interpolator(prog, &interp); - } - } - } else { - unsigned i, j; - for( j = 0; j < NUM_CHANNELS; j++ ) { - if( mask & (1 << j) ) { - for( i = first; i <= last; i++ ) { - struct gallivm_interpolate interp; - interp.type = interp_method; - interp.attrib = i; - interp.chan = j; - add_interpolator(prog, &interp); - } - } - } - } - } -} - -static void -translate_declarationir(struct gallivm_ir *, - llvm::Module *, - StorageSoa *storage, - struct tgsi_full_declaration *decl, - struct tgsi_full_declaration *) -{ - if (decl->Declaration.File == TGSI_FILE_ADDRESS) { - int idx = decl->u.DeclarationRange.First; - storage->addAddress(idx); - } -} - -static void -translate_immediate(Storage *storage, - struct tgsi_full_immediate *imm) -{ - float vec[4]; - int i; - for (i = 0; i < imm->Immediate.Size - 1; ++i) { - switch (imm->Immediate.DataType) { - case TGSI_IMM_FLOAT32: - vec[i] = imm->u.ImmediateFloat32[i].Float; - break; - default: - assert(0); - } - } - storage->addImmediate(vec); -} - - -static void -translate_immediateir(StorageSoa *storage, - struct tgsi_full_immediate *imm) -{ - float vec[4]; - int i; - for (i = 0; i < imm->Immediate.Size - 1; ++i) { - switch (imm->Immediate.DataType) { - case TGSI_IMM_FLOAT32: - vec[i] = imm->u.ImmediateFloat32[i].Float; - break; - default: - assert(0); - } - } - storage->addImmediate(vec); -} - -static inline int -swizzleInt(struct tgsi_full_src_register *src) -{ - int swizzle = 0; - int start = 1000; - - for (int k = 0; k < 4; ++k) { - swizzle += tgsi_util_get_full_src_register_extswizzle(src, k) * start; - start /= 10; - } - return swizzle; -} - -static inline llvm::Value * -swizzleVector(llvm::Value *val, struct tgsi_full_src_register *src, - Storage *storage) -{ - int swizzle = swizzleInt(src); - - if (gallivm_is_swizzle(swizzle)) { - /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/ - val = storage->shuffleVector(val, swizzle); - } - return val; -} - -static void -translate_instruction(llvm::Module *module, - Storage *storage, - Instructions *instr, - struct tgsi_full_instruction *inst, - struct tgsi_full_instruction *fi, - unsigned instno) -{ - llvm::Value *inputs[4]; - inputs[0] = 0; - inputs[1] = 0; - inputs[2] = 0; - inputs[3] = 0; - - for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - llvm::Value *val = 0; - llvm::Value *indIdx = 0; - - if (src->SrcRegister.Indirect) { - indIdx = storage->addrElement(src->SrcRegisterInd.Index); - indIdx = storage->extractIndex(indIdx); - } - if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { - val = storage->constElement(src->SrcRegister.Index, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { - val = storage->inputElement(src->SrcRegister.Index, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { - val = storage->tempElement(src->SrcRegister.Index); - } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { - val = storage->outputElement(src->SrcRegister.Index, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { - val = storage->immediateElement(src->SrcRegister.Index); - } else { - fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); - return; - } - - inputs[i] = swizzleVector(val, src, storage); - } - - /*if (inputs[0]) - instr->printVector(inputs[0]); - if (inputs[1]) - instr->printVector(inputs[1]);*/ - llvm::Value *out = 0; - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_ARL: { - out = instr->arl(inputs[0]); - } - break; - case TGSI_OPCODE_MOV: { - out = inputs[0]; - } - break; - case TGSI_OPCODE_LIT: { - out = instr->lit(inputs[0]); - } - break; - case TGSI_OPCODE_RCP: { - out = instr->rcp(inputs[0]); - } - break; - case TGSI_OPCODE_RSQ: { - out = instr->rsq(inputs[0]); - } - break; - case TGSI_OPCODE_EXP: - break; - case TGSI_OPCODE_LOG: - break; - case TGSI_OPCODE_MUL: { - out = instr->mul(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_ADD: { - out = instr->add(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP3: { - out = instr->dp3(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP4: { - out = instr->dp4(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DST: { - out = instr->dst(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MIN: { - out = instr->min(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MAX: { - out = instr->max(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SLT: { - out = instr->slt(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SGE: { - out = instr->sge(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MAD: { - out = instr->madd(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SUB: { - out = instr->sub(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_LERP: { - out = instr->lerp(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_CND: - break; - case TGSI_OPCODE_CND0: - break; - case TGSI_OPCODE_DOT2ADD: - break; - case TGSI_OPCODE_INDEX: - break; - case TGSI_OPCODE_NEGATE: - break; - case TGSI_OPCODE_FRAC: { - out = instr->frc(inputs[0]); - } - break; - case TGSI_OPCODE_CLAMP: - break; - case TGSI_OPCODE_FLOOR: { - out = instr->floor(inputs[0]); - } - break; - case TGSI_OPCODE_ROUND: - break; - case TGSI_OPCODE_EXPBASE2: { - out = instr->ex2(inputs[0]); - } - break; - case TGSI_OPCODE_LOGBASE2: { - out = instr->lg2(inputs[0]); - } - break; - case TGSI_OPCODE_POWER: { - out = instr->pow(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_CROSSPRODUCT: { - out = instr->cross(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MULTIPLYMATRIX: - break; - case TGSI_OPCODE_ABS: { - out = instr->abs(inputs[0]); - } - break; - case TGSI_OPCODE_RCC: - break; - case TGSI_OPCODE_DPH: { - out = instr->dph(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_COS: { - out = instr->cos(inputs[0]); - } - break; - case TGSI_OPCODE_DDX: - break; - case TGSI_OPCODE_DDY: - break; - case TGSI_OPCODE_KILP: { - out = instr->kilp(inputs[0]); - storage->setKilElement(out); - return; - } - break; - case TGSI_OPCODE_PK2H: - break; - case TGSI_OPCODE_PK2US: - break; - case TGSI_OPCODE_PK4B: - break; - case TGSI_OPCODE_PK4UB: - break; - case TGSI_OPCODE_RFL: - break; - case TGSI_OPCODE_SEQ: - break; - case TGSI_OPCODE_SFL: - break; - case TGSI_OPCODE_SGT: { - out = instr->sgt(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SIN: { - out = instr->sin(inputs[0]); - } - break; - case TGSI_OPCODE_SLE: - break; - case TGSI_OPCODE_SNE: - break; - case TGSI_OPCODE_STR: - break; - case TGSI_OPCODE_TEX: - break; - case TGSI_OPCODE_TXD: - break; - case TGSI_OPCODE_UP2H: - break; - case TGSI_OPCODE_UP2US: - break; - case TGSI_OPCODE_UP4B: - break; - case TGSI_OPCODE_UP4UB: - break; - case TGSI_OPCODE_X2D: - break; - case TGSI_OPCODE_ARA: - break; - case TGSI_OPCODE_ARR: - break; - case TGSI_OPCODE_BRA: - break; - case TGSI_OPCODE_CAL: { - instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr()); - return; - } - break; - case TGSI_OPCODE_RET: { - instr->end(); - return; - } - break; - case TGSI_OPCODE_SSG: - break; - case TGSI_OPCODE_CMP: { - out = instr->cmp(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SCS: { - out = instr->scs(inputs[0]); - } - break; - case TGSI_OPCODE_TXB: - break; - case TGSI_OPCODE_NRM: - break; - case TGSI_OPCODE_DIV: - break; - case TGSI_OPCODE_DP2: - break; - case TGSI_OPCODE_TXL: - break; - case TGSI_OPCODE_BRK: { - instr->brk(); - return; - } - break; - case TGSI_OPCODE_IF: { - instr->ifop(inputs[0]); - storage->setCurrentBlock(instr->currentBlock()); - return; //just update the state - } - break; - case TGSI_OPCODE_LOOP: - break; - case TGSI_OPCODE_REP: - break; - case TGSI_OPCODE_ELSE: { - instr->elseop(); - storage->setCurrentBlock(instr->currentBlock()); - return; //only state update - } - break; - case TGSI_OPCODE_ENDIF: { - instr->endif(); - storage->setCurrentBlock(instr->currentBlock()); - return; //just update the state - } - break; - case TGSI_OPCODE_ENDLOOP: - break; - case TGSI_OPCODE_ENDREP: - break; - case TGSI_OPCODE_PUSHA: - break; - case TGSI_OPCODE_POPA: - break; - case TGSI_OPCODE_CEIL: - break; - case TGSI_OPCODE_I2F: - break; - case TGSI_OPCODE_NOT: - break; - case TGSI_OPCODE_TRUNC: { - out = instr->trunc(inputs[0]); - } - break; - case TGSI_OPCODE_SHL: - break; - case TGSI_OPCODE_SHR: - break; - case TGSI_OPCODE_AND: - break; - case TGSI_OPCODE_OR: - break; - case TGSI_OPCODE_MOD: - break; - case TGSI_OPCODE_XOR: - break; - case TGSI_OPCODE_SAD: - break; - case TGSI_OPCODE_TXF: - break; - case TGSI_OPCODE_TXQ: - break; - case TGSI_OPCODE_CONT: - break; - case TGSI_OPCODE_EMIT: - break; - case TGSI_OPCODE_ENDPRIM: - break; - case TGSI_OPCODE_BGNLOOP2: { - instr->beginLoop(); - storage->setCurrentBlock(instr->currentBlock()); - return; - } - break; - case TGSI_OPCODE_BGNSUB: { - instr->bgnSub(instno); - storage->setCurrentBlock(instr->currentBlock()); - storage->pushTemps(); - return; - } - break; - case TGSI_OPCODE_ENDLOOP2: { - instr->endLoop(); - storage->setCurrentBlock(instr->currentBlock()); - return; - } - break; - case TGSI_OPCODE_ENDSUB: { - instr->endSub(); - storage->setCurrentBlock(instr->currentBlock()); - storage->popArguments(); - storage->popTemps(); - return; - } - break; - case TGSI_OPCODE_NOISE1: - break; - case TGSI_OPCODE_NOISE2: - break; - case TGSI_OPCODE_NOISE3: - break; - case TGSI_OPCODE_NOISE4: - break; - case TGSI_OPCODE_NOP: - break; - case TGSI_OPCODE_TEXBEM: - break; - case TGSI_OPCODE_TEXBEML: - break; - case TGSI_OPCODE_TEXREG2AR: - break; - case TGSI_OPCODE_TEXM3X2PAD: - break; - case TGSI_OPCODE_TEXM3X2TEX: - break; - case TGSI_OPCODE_TEXM3X3PAD: - break; - case TGSI_OPCODE_TEXM3X3TEX: - break; - case TGSI_OPCODE_TEXM3X3SPEC: - break; - case TGSI_OPCODE_TEXM3X3VSPEC: - break; - case TGSI_OPCODE_TEXREG2GB: - break; - case TGSI_OPCODE_TEXREG2RGB: - break; - case TGSI_OPCODE_TEXDP3TEX: - break; - case TGSI_OPCODE_TEXDP3: - break; - case TGSI_OPCODE_TEXM3X3: - break; - case TGSI_OPCODE_TEXM3X2DEPTH: - break; - case TGSI_OPCODE_TEXDEPTH: - break; - case TGSI_OPCODE_BEM: - break; - case TGSI_OPCODE_M4X3: - break; - case TGSI_OPCODE_M3X4: - break; - case TGSI_OPCODE_M3X3: - break; - case TGSI_OPCODE_M3X2: - break; - case TGSI_OPCODE_NRM4: - break; - case TGSI_OPCODE_CALLNZ: - break; - case TGSI_OPCODE_IFC: - break; - case TGSI_OPCODE_BREAKC: - break; - case TGSI_OPCODE_KIL: - break; - case TGSI_OPCODE_END: - instr->end(); - return; - break; - default: - fprintf(stderr, "ERROR: Unknown opcode %d\n", - inst->Instruction.Opcode); - assert(0); - break; - } - - if (!out) { - fprintf(stderr, "ERROR: unsupported opcode %d\n", - inst->Instruction.Opcode); - assert(!"Unsupported opcode"); - } - - /* # not sure if we need this */ - switch( inst->Instruction.Saturate ) { - case TGSI_SAT_NONE: - break; - case TGSI_SAT_ZERO_ONE: - /*TXT( "_SAT" );*/ - break; - case TGSI_SAT_MINUS_PLUS_ONE: - /*TXT( "_SAT[-1,1]" );*/ - break; - default: - assert( 0 ); - } - - /* store results */ - for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - - if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { - storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { - storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { - storage->setAddrElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else { - fprintf(stderr, "ERROR: unsupported LLVM destination!"); - assert(!"wrong destination"); - } - } -} - - -static void -translate_instructionir(llvm::Module *module, - StorageSoa *storage, - InstructionsSoa *instr, - struct tgsi_full_instruction *inst, - struct tgsi_full_instruction *fi, - unsigned instno) -{ - std::vector< std::vector > inputs(inst->Instruction.NumSrcRegs); - - for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - std::vector val; - llvm::Value *indIdx = 0; - int swizzle = swizzleInt(src); - - if (src->SrcRegister.Indirect) { - indIdx = storage->addrElement(src->SrcRegisterInd.Index); - } - if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { - val = storage->load(StorageSoa::Const, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { - val = storage->load(StorageSoa::Input, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { - val = storage->load(StorageSoa::Temp, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { - val = storage->load(StorageSoa::Output, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { - val = storage->load(StorageSoa::Immediate, - src->SrcRegister.Index, swizzle, indIdx); - } else { - fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); - return; - } - - inputs[i] = val; - } - - std::vector out(4); - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_ARL: { - out = instr->arl(inputs[0]); - } - break; - case TGSI_OPCODE_MOV: { - out = inputs[0]; - } - break; - case TGSI_OPCODE_LIT: { - } - break; - case TGSI_OPCODE_RCP: { - } - break; - case TGSI_OPCODE_RSQ: { - } - break; - case TGSI_OPCODE_EXP: - break; - case TGSI_OPCODE_LOG: - break; - case TGSI_OPCODE_MUL: { - out = instr->mul(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_ADD: { - out = instr->add(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP3: { - } - break; - case TGSI_OPCODE_DP4: { - } - break; - case TGSI_OPCODE_DST: { - } - break; - case TGSI_OPCODE_MIN: { - } - break; - case TGSI_OPCODE_MAX: { - } - break; - case TGSI_OPCODE_SLT: { - } - break; - case TGSI_OPCODE_SGE: { - } - break; - case TGSI_OPCODE_MAD: { - out = instr->madd(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SUB: { - } - break; - case TGSI_OPCODE_LERP: { - } - break; - case TGSI_OPCODE_CND: - break; - case TGSI_OPCODE_CND0: - break; - case TGSI_OPCODE_DOT2ADD: - break; - case TGSI_OPCODE_INDEX: - break; - case TGSI_OPCODE_NEGATE: - break; - case TGSI_OPCODE_FRAC: { - } - break; - case TGSI_OPCODE_CLAMP: - break; - case TGSI_OPCODE_FLOOR: { - } - break; - case TGSI_OPCODE_ROUND: - break; - case TGSI_OPCODE_EXPBASE2: { - } - break; - case TGSI_OPCODE_LOGBASE2: { - } - break; - case TGSI_OPCODE_POWER: { - } - break; - case TGSI_OPCODE_CROSSPRODUCT: { - } - break; - case TGSI_OPCODE_MULTIPLYMATRIX: - break; - case TGSI_OPCODE_ABS: { - } - break; - case TGSI_OPCODE_RCC: - break; - case TGSI_OPCODE_DPH: { - } - break; - case TGSI_OPCODE_COS: { - } - break; - case TGSI_OPCODE_DDX: - break; - case TGSI_OPCODE_DDY: - break; - case TGSI_OPCODE_KILP: { - } - break; - case TGSI_OPCODE_PK2H: - break; - case TGSI_OPCODE_PK2US: - break; - case TGSI_OPCODE_PK4B: - break; - case TGSI_OPCODE_PK4UB: - break; - case TGSI_OPCODE_RFL: - break; - case TGSI_OPCODE_SEQ: - break; - case TGSI_OPCODE_SFL: - break; - case TGSI_OPCODE_SGT: { - } - break; - case TGSI_OPCODE_SIN: { - } - break; - case TGSI_OPCODE_SLE: - break; - case TGSI_OPCODE_SNE: - break; - case TGSI_OPCODE_STR: - break; - case TGSI_OPCODE_TEX: - break; - case TGSI_OPCODE_TXD: - break; - case TGSI_OPCODE_UP2H: - break; - case TGSI_OPCODE_UP2US: - break; - case TGSI_OPCODE_UP4B: - break; - case TGSI_OPCODE_UP4UB: - break; - case TGSI_OPCODE_X2D: - break; - case TGSI_OPCODE_ARA: - break; - case TGSI_OPCODE_ARR: - break; - case TGSI_OPCODE_BRA: - break; - case TGSI_OPCODE_CAL: { - } - break; - case TGSI_OPCODE_RET: { - } - break; - case TGSI_OPCODE_SSG: - break; - case TGSI_OPCODE_CMP: { - } - break; - case TGSI_OPCODE_SCS: { - } - break; - case TGSI_OPCODE_TXB: - break; - case TGSI_OPCODE_NRM: - break; - case TGSI_OPCODE_DIV: - break; - case TGSI_OPCODE_DP2: - break; - case TGSI_OPCODE_TXL: - break; - case TGSI_OPCODE_BRK: { - } - break; - case TGSI_OPCODE_IF: { - } - break; - case TGSI_OPCODE_LOOP: - break; - case TGSI_OPCODE_REP: - break; - case TGSI_OPCODE_ELSE: { - } - break; - case TGSI_OPCODE_ENDIF: { - } - break; - case TGSI_OPCODE_ENDLOOP: - break; - case TGSI_OPCODE_ENDREP: - break; - case TGSI_OPCODE_PUSHA: - break; - case TGSI_OPCODE_POPA: - break; - case TGSI_OPCODE_CEIL: - break; - case TGSI_OPCODE_I2F: - break; - case TGSI_OPCODE_NOT: - break; - case TGSI_OPCODE_TRUNC: { - } - break; - case TGSI_OPCODE_SHL: - break; - case TGSI_OPCODE_SHR: - break; - case TGSI_OPCODE_AND: - break; - case TGSI_OPCODE_OR: - break; - case TGSI_OPCODE_MOD: - break; - case TGSI_OPCODE_XOR: - break; - case TGSI_OPCODE_SAD: - break; - case TGSI_OPCODE_TXF: - break; - case TGSI_OPCODE_TXQ: - break; - case TGSI_OPCODE_CONT: - break; - case TGSI_OPCODE_EMIT: - break; - case TGSI_OPCODE_ENDPRIM: - break; - case TGSI_OPCODE_BGNLOOP2: { - } - break; - case TGSI_OPCODE_BGNSUB: { - } - break; - case TGSI_OPCODE_ENDLOOP2: { - } - break; - case TGSI_OPCODE_ENDSUB: { - } - break; - case TGSI_OPCODE_NOISE1: - break; - case TGSI_OPCODE_NOISE2: - break; - case TGSI_OPCODE_NOISE3: - break; - case TGSI_OPCODE_NOISE4: - break; - case TGSI_OPCODE_NOP: - break; - case TGSI_OPCODE_TEXBEM: - break; - case TGSI_OPCODE_TEXBEML: - break; - case TGSI_OPCODE_TEXREG2AR: - break; - case TGSI_OPCODE_TEXM3X2PAD: - break; - case TGSI_OPCODE_TEXM3X2TEX: - break; - case TGSI_OPCODE_TEXM3X3PAD: - break; - case TGSI_OPCODE_TEXM3X3TEX: - break; - case TGSI_OPCODE_TEXM3X3SPEC: - break; - case TGSI_OPCODE_TEXM3X3VSPEC: - break; - case TGSI_OPCODE_TEXREG2GB: - break; - case TGSI_OPCODE_TEXREG2RGB: - break; - case TGSI_OPCODE_TEXDP3TEX: - break; - case TGSI_OPCODE_TEXDP3: - break; - case TGSI_OPCODE_TEXM3X3: - break; - case TGSI_OPCODE_TEXM3X2DEPTH: - break; - case TGSI_OPCODE_TEXDEPTH: - break; - case TGSI_OPCODE_BEM: - break; - case TGSI_OPCODE_M4X3: - break; - case TGSI_OPCODE_M3X4: - break; - case TGSI_OPCODE_M3X3: - break; - case TGSI_OPCODE_M3X2: - break; - case TGSI_OPCODE_NRM4: - break; - case TGSI_OPCODE_CALLNZ: - break; - case TGSI_OPCODE_IFC: - break; - case TGSI_OPCODE_BREAKC: - break; - case TGSI_OPCODE_KIL: - break; - case TGSI_OPCODE_END: - instr->end(); - return; - break; - default: - fprintf(stderr, "ERROR: Unknown opcode %d\n", - inst->Instruction.Opcode); - assert(0); - break; - } - - if (!out[0]) { - fprintf(stderr, "ERROR: unsupported opcode %d\n", - inst->Instruction.Opcode); - assert(!"Unsupported opcode"); - } - - /* store results */ - for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - - if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { - storage->store(StorageSoa::Output, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { - storage->store(StorageSoa::Temp, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { - storage->store(StorageSoa::Address, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else { - fprintf(stderr, "ERROR: unsupported LLVM destination!"); - assert(!"wrong destination"); - } - } -} - -llvm::Module * -tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens) -{ - llvm::Module *mod = new Module("shader"); - struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - unsigned instno = 0; - Function* shader = mod->getFunction("execute_shader"); - std::ostringstream stream; - if (ir->type == GALLIVM_VS) { - stream << "vs_shader"; - } else { - stream << "fs_shader"; - } - stream << ir->id; - std::string func_name = stream.str(); - shader->setName(func_name.c_str()); - - Function::arg_iterator args = shader->arg_begin(); - Value *ptr_INPUT = args++; - ptr_INPUT->setName("input"); - - BasicBlock *label_entry = new BasicBlock("entry", shader, 0); - - tgsi_parse_init(&parse, tokens); - - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - Storage storage(label_entry, ptr_INPUT); - Instructions instr(mod, shader, label_entry, &storage); - while(!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - translate_declaration(ir, mod, &storage, - &parse.FullToken.FullDeclaration, - &fd); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - translate_immediate(&storage, - &parse.FullToken.FullImmediate); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - translate_instruction(mod, &storage, &instr, - &parse.FullToken.FullInstruction, - &fi, instno); - ++instno; - break; - - default: - assert(0); - } - } - - tgsi_parse_free(&parse); - - ir->num_consts = storage.numConsts(); - return mod; -} - -llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, - const struct tgsi_token *tokens) -{ - llvm::Module *mod = new Module("shader"); - struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - unsigned instno = 0; - std::ostringstream stream; - if (ir->type == GALLIVM_VS) { - stream << "vs_shader"; - } else { - stream << "fs_shader"; - } - //stream << ir->id; - std::string func_name = stream.str(); - Function *shader = llvm::cast(mod->getOrInsertFunction( - func_name.c_str(), - vertexShaderFunctionType())); - - Function::arg_iterator args = shader->arg_begin(); - Value *input = args++; - input->setName("inputs"); - Value *output = args++; - output->setName("outputs"); - Value *consts = args++; - consts->setName("consts"); - Value *temps = args++; - temps->setName("temps"); - - BasicBlock *label_entry = new BasicBlock("entry", shader, 0); - - tgsi_parse_init(&parse, tokens); - - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - - StorageSoa storage(label_entry, input, output, consts, temps); - InstructionsSoa instr(mod, shader, label_entry, &storage); - - while(!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - translate_declarationir(ir, mod, &storage, - &parse.FullToken.FullDeclaration, - &fd); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - translate_immediateir(&storage, - &parse.FullToken.FullImmediate); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - storage.declareImmediates(); - translate_instructionir(mod, &storage, &instr, - &parse.FullToken.FullInstruction, - &fi, instno); - ++instno; - break; - - default: - assert(0); - } - } - - tgsi_parse_free(&parse); - - return mod; -} diff --git a/src/gallium/auxiliary/llvm/tgsitollvm.h b/src/gallium/auxiliary/llvm/tgsitollvm.h deleted file mode 100644 index 7ada04d629..0000000000 --- a/src/gallium/auxiliary/llvm/tgsitollvm.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef TGSITOLLVM_H -#define TGSITOLLVM_H - - -namespace llvm { - class Module; -} - -struct gallivm_ir; -struct tgsi_token; - - -llvm::Module * tgsi_to_llvm(struct gallivm_ir *ir, - const struct tgsi_token *tokens); - - -llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, - const struct tgsi_token *tokens); - -#endif -- cgit v1.2.3 From 0448dbd64a2ef217349f4ada4777d432bc82e46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Feb 2008 12:33:34 +0000 Subject: Update for llvm -> gallivm rename. --- src/gallium/SConscript | 2 +- src/gallium/auxiliary/draw/draw_vs_llvm.c | 2 +- src/gallium/winsys/xlib/Makefile | 8 ++------ 3 files changed, 4 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/SConscript b/src/gallium/SConscript index a835f6d661..ea55ed2ed5 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -13,7 +13,7 @@ SConscript([ 'auxiliary/tgsi/SConscript', 'auxiliary/cso_cache/SConscript', 'auxiliary/draw/SConscript', - #'auxiliary/llvm/SConscript', + #'auxiliary/gallivm/SConscript', 'auxiliary/pipebuffer/SConscript', 'drivers/softpipe/SConscript', diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 44022b6e07..0fd557d667 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -40,7 +40,7 @@ #ifdef MESA_LLVM -#include "llvm/gallivm.h" +#include "gallivm/gallivm.h" struct draw_llvm_vertex_shader { struct draw_vertex_shader base; diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 2664ac47ce..17405388ee 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -38,10 +38,6 @@ CELL_LIB = $(TOP)/src/gallium/drivers/cell/ppu/libcell.a CELL_LIB_SPU = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a endif -ifeq ($(CONFIG_NAME), linux-llvm) -LLVM_LIB = $(TOP)/src/gallium/auxiliary/llvm/libgallivm.a -endif - .SUFFIXES : .cpp @@ -69,13 +65,13 @@ STAND_ALONE_OBJECTS = \ $(STAND_ALONE_DRIVER_OBJECTS) # Make the GL library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(LLVM_LIB) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ - --start-group $(PIPE_LIB) $(LLVM_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) + --start-group $(PIPE_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) ###################################################################### -- cgit v1.2.3 From aceeb80d4f706980aaf71b8e098d4c6718d8ac90 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 18 Feb 2008 16:19:05 -0700 Subject: gallium: antialiased line drawing New draw/prim stage: draw_aaline. When installed, lines are replaced by textured quads to do antialiasing. The current user-defined fragment shader is modified to do a texture fetch and modulate fragment alpha. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_aaline.c | 832 ++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_context.c | 22 + src/gallium/auxiliary/draw/draw_context.h | 21 +- src/gallium/auxiliary/draw/draw_prim.c | 7 + src/gallium/auxiliary/draw/draw_private.h | 12 +- src/gallium/auxiliary/draw/draw_validate.c | 8 +- src/gallium/auxiliary/tgsi/Makefile | 1 + src/gallium/drivers/softpipe/sp_context.c | 3 + src/gallium/drivers/softpipe/sp_state_derived.c | 17 +- 10 files changed, 914 insertions(+), 10 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_aaline.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index c56b63d85b..c8000cbe9c 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -4,6 +4,7 @@ include $(TOP)/configs/current LIBNAME = draw DRIVER_SOURCES = \ + draw_aaline.c \ draw_clip.c \ draw_vs_exec.c \ draw_vs_sse.c \ diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c new file mode 100644 index 0000000000..f1fee4f8ba --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -0,0 +1,832 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * AA line stage: AA lines are converted to texture mapped triangles. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_private.h" + + +/** + * Max texture level for the alpha texture used for antialiasing + */ +#define MAX_TEXTURE_LEVEL 5 /* 32 x 32 */ + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct aaline_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; + void *aaline_fs; + void *aapoint_fs; /* not yet */ + void *sprite_fs; /* not yet */ +}; + + +/** + * Subclass of draw_stage + */ +struct aaline_stage +{ + struct draw_stage stage; + + float half_line_width; + + /** For AA lines, this is the vertex attrib slot for the new texcoords */ + uint tex_slot; + + void *sampler_cso; + struct pipe_texture *texture; + uint sampler_unit; + + + /* + * Currently bound state + */ + struct aaline_fragment_shader *fs; + struct { + void *sampler[PIPE_MAX_SAMPLERS]; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + } state; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *); + + void (*driver_set_sampler_texture)(struct pipe_context *, + unsigned sampler, + struct pipe_texture *); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct aa_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int colorOutput; /**< which output is the primary color */ + int maxSampler; /**< max sampler index found */ + int maxInput, maxGeneric; /**< max input index found */ + int colorTemp, texTemp; /**< temp registers */ + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for a free sampler, a free input attrib, and two free temp regs. + */ +static void +aa_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_OUTPUT && + decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && + decl->Semantic.SemanticIndex == 0) { + aactx->colorOutput = decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_SAMPLER) { + if (decl->u.DeclarationRange.Last > aactx->maxSampler) + aactx->maxSampler = decl->u.DeclarationRange.Last + 1; + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + if (decl->u.DeclarationRange.Last > aactx->maxInput) + aactx->maxInput = decl->u.DeclarationRange.Last; + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && + decl->Semantic.SemanticIndex > aactx->maxGeneric) { + aactx->maxGeneric = decl->Semantic.SemanticIndex; + } + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + aactx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +aa_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (aactx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + uint i; + + /* find two free temp regs */ + for (i = 0; i < 32; i++) { + if ((aactx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (aactx->colorTemp < 0) + aactx->colorTemp = i; + else if (aactx->texTemp < 0) + aactx->texTemp = i; + else + break; + } + } + assert(aactx->colorTemp >= 0); + assert(aactx->texTemp >= 0); + + /* declare new generic input/texcoord */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; + decl.Declaration.Interpolate = 1; + /* XXX this could be linear... */ + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->maxInput + 1; + ctx->emit_declaration(ctx, &decl); + + /* declare new sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->maxSampler + 1; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->texTemp; + ctx->emit_declaration(ctx, &decl); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->colorTemp; + ctx->emit_declaration(ctx, &decl); + + aactx->firstInstruction = FALSE; + } + + if (inst->Instruction.Opcode == TGSI_OPCODE_END && + aactx->colorOutput != -1) { + struct tgsi_full_instruction newInst; + + /* TEX */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_TEX; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->maxSampler + 1; + + ctx->emit_instruction(ctx, &newInst); + + /* MOV rgb */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MOV; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + ctx->emit_instruction(ctx, &newInst); + + /* MUL alpha */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->texTemp; + ctx->emit_instruction(ctx, &newInst); + + /* END */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_END; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 0; + ctx->emit_instruction(ctx, &newInst); + } + else { + /* Not an END instruction. + * Look for writes to result.color and replace with colorTemp reg. + */ + uint i; + + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + if (dst->DstRegister.File == TGSI_FILE_OUTPUT && + dst->DstRegister.Index == aactx->colorOutput) { + dst->DstRegister.File = TGSI_FILE_TEMPORARY; + dst->DstRegister.Index = aactx->colorTemp; + } + } + + ctx->emit_instruction(ctx, inst); + } +} + + +/** + * Generate the frag shader we'll use for drawing AA lines. + * This will be the user's shader plus some texture/modulate instructions. + */ +static void +generate_aaline_fs(struct aaline_stage *aaline) +{ + const struct pipe_shader_state *orig_fs = &aaline->fs->state; + struct draw_context *draw = aaline->stage.draw; + struct pipe_shader_state aaline_fs; + struct aa_transform_context transform; + +#define MAX 1000 + + aaline_fs = *orig_fs; /* copy to init */ + aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.colorOutput = -1; + transform.maxSampler = -1; + transform.maxInput = -1; + transform.maxGeneric = -1; + transform.colorTemp = -1; + transform.texTemp = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = aa_transform_inst; + transform.base.transform_declaration = aa_transform_decl; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) aaline_fs.tokens, + MAX, &transform.base); + +#if 0 /* DEBUG */ + tgsi_dump(orig_fs->tokens, 0); + tgsi_dump(aaline_fs.tokens, 0); +#endif + + aaline_fs.input_semantic_name[aaline_fs.num_inputs] = TGSI_SEMANTIC_GENERIC; + aaline_fs.input_semantic_index[aaline_fs.num_inputs] = transform.maxGeneric + 1; + aaline_fs.num_inputs++; + + aaline->fs->aaline_fs + = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); + + /* advertise the extra post-transform vertex attributes which will have + * the texcoords. + */ + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; + draw->extra_vp_outputs.semantic_index = transform.maxGeneric + 1; +} + + +/** + * Create the texture map we'll use for antialiasing the lines. + */ +static void +aaline_create_texture(struct aaline_stage *aaline) +{ + struct pipe_context *pipe = aaline->pipe; + struct pipe_texture texTemp; + uint level; + + memset(&texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ + texTemp.last_level = MAX_TEXTURE_LEVEL; + texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL; + texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL; + texTemp.depth[0] = 1; + texTemp.cpp = 1; + + aaline->texture = pipe->texture_create(pipe, &texTemp); + + /* Fill in mipmap images. + * Basically each level is solid opaque, except for the outermost + * texels which are zero. Special case the 1x1 and 2x2 levels. + */ + for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) { + struct pipe_surface *surface; + const uint size = aaline->texture->width[level]; + ubyte *data; + uint i, j; + + assert(aaline->texture->width[level] == aaline->texture->height[level]); + + surface = pipe->get_tex_surface(pipe, aaline->texture, 0, level, 0); + data = pipe_surface_map(surface); + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + uint d; + if (size == 1) { + d = 255; + } + else if (size == 2) { + d = 200; /* tuneable */ + } + else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) { + d = 0; + } + else { + d = 255; + } + data[i * surface->pitch + j] = d; + } + } + + /* unmap */ + pipe_surface_unmap(surface); + pipe_surface_reference(&surface, NULL); + } +} + + +/** + * Create the sampler CSO that'll be used for antialiasing. + * By using a mipmapped texture, we don't have to generate a different + * texture image for each line size. + */ +static void +aaline_create_sampler(struct aaline_stage *aaline) +{ + struct pipe_sampler_state sampler; + struct pipe_context *pipe = aaline->pipe; + + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR; + sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.normalized_coords = 1; + sampler.min_lod = 0.0f; + sampler.max_lod = MAX_TEXTURE_LEVEL; + + aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler); +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_aaline_fragment_shader(struct aaline_stage *aaline) +{ + if (!aaline->fs->aaline_fs) { + generate_aaline_fs(aaline); + } + aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs); +} + + + +static INLINE struct aaline_stage * +aaline_stage( struct draw_stage *stage ) +{ + return (struct aaline_stage *) stage; +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw a wide line by drawing a quad, using geometry which will + * fullfill GL's antialiased line requirements. + */ +static void +aaline_line(struct draw_stage *stage, struct prim_header *header) +{ + const struct aaline_stage *aaline = aaline_stage(stage); + const float half_width = aaline->half_line_width; + struct prim_header tri; + struct vertex_header *v[8]; + uint texPos = aaline->tex_slot; + float *pos, *tex; + float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; + float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; + float a = atan2(dy, dx); + float c_a = cos(a), s_a = sin(a); + uint i; + + /* XXX the ends of lines aren't quite perfect yet, but probably passable */ + dx = 0.5 * half_width; + dy = half_width; + + /* allocate/dup new verts */ + for (i = 0; i < 8; i++) { + v[i] = dup_vert(stage, header->v[i/4], i); + } + + /* + * Quad strip for line from v0 to v1 (*=endpoints): + * + * 1 3 5 7 + * +---+---------------------+---+ + * | | + * | *v0 v1* | + * | | + * +---+---------------------+---+ + * 0 2 4 6 + */ + + /* new verts */ + pos = v[0]->data[0]; + pos[0] += (-dx * c_a - dy * s_a); + pos[1] += (-dx * s_a + dy * c_a); + + pos = v[1]->data[0]; + pos[0] += (-dx * c_a - -dy * s_a); + pos[1] += (-dx * s_a + -dy * c_a); + + pos = v[2]->data[0]; + pos[0] += ( dx * c_a - dy * s_a); + pos[1] += ( dx * s_a + dy * c_a); + + pos = v[3]->data[0]; + pos[0] += ( dx * c_a - -dy * s_a); + pos[1] += ( dx * s_a + -dy * c_a); + + pos = v[4]->data[0]; + pos[0] += (-dx * c_a - dy * s_a); + pos[1] += (-dx * s_a + dy * c_a); + + pos = v[5]->data[0]; + pos[0] += (-dx * c_a - -dy * s_a); + pos[1] += (-dx * s_a + -dy * c_a); + + pos = v[6]->data[0]; + pos[0] += ( dx * c_a - dy * s_a); + pos[1] += ( dx * s_a + dy * c_a); + + pos = v[7]->data[0]; + pos[0] += ( dx * c_a - -dy * s_a); + pos[1] += ( dx * s_a + -dy * c_a); + + /* new texcoords */ + tex = v[0]->data[texPos]; + ASSIGN_4V(tex, 0, 0, 0, 1); + + tex = v[1]->data[texPos]; + ASSIGN_4V(tex, 0, 1, 0, 1); + + tex = v[2]->data[texPos]; + ASSIGN_4V(tex, .5, 0, 0, 1); + + tex = v[3]->data[texPos]; + ASSIGN_4V(tex, .5, 1, 0, 1); + + tex = v[4]->data[texPos]; + ASSIGN_4V(tex, .5, 0, 0, 1); + + tex = v[5]->data[texPos]; + ASSIGN_4V(tex, .5, 1, 0, 1); + + tex = v[6]->data[texPos]; + ASSIGN_4V(tex, 1, 0, 0, 1); + + tex = v[7]->data[texPos]; + ASSIGN_4V(tex, 1, 1, 0, 1); + + /* emit 6 tris for the quad strip */ + tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[4]; tri.v[1] = v[3]; tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[5]; tri.v[1] = v[3]; tri.v[2] = v[4]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[6]; tri.v[1] = v[5]; tri.v[2] = v[4]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[7]; tri.v[1] = v[5]; tri.v[2] = v[6]; + stage->next->tri( stage->next, &tri ); +} + + +static void +aaline_first_line(struct draw_stage *stage, struct prim_header *header) +{ + auto struct aaline_stage *aaline = aaline_stage(stage); + struct draw_context *draw = stage->draw; + struct pipe_context *pipe = aaline->pipe; + + assert(draw->rasterizer->line_smooth); + + if (draw->rasterizer->line_width <= 3.0) + aaline->half_line_width = 1.5f; + else + aaline->half_line_width = 0.5f * draw->rasterizer->line_width; + + aaline->tex_slot = draw->num_vs_outputs; + assert(aaline->tex_slot > 0); /* output[0] is vertex pos */ + draw->extra_vp_outputs.slot = aaline->tex_slot; + + /* + * Bind our fragprog, sampler and texture + */ + bind_aaline_fragment_shader(aaline); + + aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit, aaline->sampler_cso); + aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit, aaline->texture); + + /* now really draw first line */ + stage->line = aaline_line; + stage->line(stage, header); +} + + +static void +aaline_flush(struct draw_stage *stage, unsigned flags) +{ + struct draw_context *draw = stage->draw; + struct aaline_stage *aaline = aaline_stage(stage); + struct pipe_context *pipe = aaline->pipe; + + stage->line = aaline_first_line; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); + + /* XXX restore original texture, sampler state */ + aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit, + aaline->state.sampler[aaline->sampler_unit]); + aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit, + aaline->state.texture[aaline->sampler_unit]); + + draw->extra_vp_outputs.slot = 0; +} + + +static void +aaline_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +aaline_destroy(struct draw_stage *stage) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +static struct aaline_stage * +draw_aaline_stage(struct draw_context *draw) +{ + struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage); + + draw_alloc_temp_verts( &aaline->stage, 8 ); + + aaline->stage.draw = draw; + aaline->stage.next = NULL; + aaline->stage.point = passthrough_point; + aaline->stage.line = aaline_first_line; + aaline->stage.tri = passthrough_tri; + aaline->stage.flush = aaline_flush; + aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter; + aaline->stage.destroy = aaline_destroy; + + return aaline; +} + + +/* + * XXX temporary? solution to mapping a pipe_context to a aaline_stage. + */ + +#define MAX_CONTEXTS 10 + +static struct pipe_context *Pipe[MAX_CONTEXTS]; +static struct aaline_stage *Stage[MAX_CONTEXTS]; +static uint NumContexts; + +static void +add_aa_pipe_context(struct pipe_context *pipe, struct aaline_stage *aa) +{ + assert(NumContexts < MAX_CONTEXTS); + Pipe[NumContexts] = pipe; + Stage[NumContexts] = aa; + NumContexts++; +} + +static struct aaline_stage * +aaline_stage_from_pipe(struct pipe_context *pipe) +{ + uint i; + for (i = 0; i < NumContexts; i++) { + if (Pipe[i] == pipe) + return Stage[i]; + } + assert(0); + return NULL; +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +aaline_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs); + } + + return aafs; +} + + +static void +aaline_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; + /* save current */ + aaline->fs = aafs; + /* pass-through */ + aaline->driver_bind_fs_state(aaline->pipe, aafs->driver_fs); +} + + +static void +aaline_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; + /* pass-through */ + aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs); + FREE(aafs); +} + + +static void +aaline_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, void *sampler) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + /* save current */ + aaline->state.sampler[unit] = sampler; + /* pass-through */ + aaline->driver_bind_sampler_state(aaline->pipe, unit, sampler); +} + + +static void +aaline_set_sampler_texture(struct pipe_context *pipe, + unsigned sampler, struct pipe_texture *texture) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + /* save current */ + aaline->state.texture[sampler] = texture; + /* pass-through */ + aaline->driver_set_sampler_texture(aaline->pipe, sampler, texture); +} + + +/** + * Called by drivers that want to install this AA line prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA lines. + */ +void +draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) +{ + struct aaline_stage *aaline; + + /* + * Create / install AA line drawing / prim stage + */ + aaline = draw_aaline_stage( draw ); + assert(aaline); + draw->pipeline.aaline = &aaline->stage; + + aaline->pipe = pipe; + + /* create special texture, sampler state */ + aaline_create_texture(aaline); + aaline_create_sampler(aaline); + + /* save original driver functions */ + aaline->driver_create_fs_state = pipe->create_fs_state; + aaline->driver_bind_fs_state = pipe->bind_fs_state; + aaline->driver_delete_fs_state = pipe->delete_fs_state; + + aaline->driver_bind_sampler_state = pipe->bind_sampler_state; + aaline->driver_set_sampler_texture = pipe->set_sampler_texture; + + /* override the driver's functions */ + pipe->create_fs_state = aaline_create_fs_state; + pipe->bind_fs_state = aaline_bind_fs_state; + pipe->delete_fs_state = aaline_delete_fs_state; + + pipe->bind_sampler_state = aaline_bind_sampler_state; + pipe->set_sampler_texture = aaline_set_sampler_texture; + + add_aa_pipe_context(pipe, aaline); +} diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 4be3830316..a7f3b4aecb 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -103,6 +103,8 @@ void draw_destroy( struct draw_context *draw ) draw->pipeline.flatshade->destroy( draw->pipeline.flatshade ); draw->pipeline.cull->destroy( draw->pipeline.cull ); draw->pipeline.validate->destroy( draw->pipeline.validate ); + if (draw->pipeline.aaline) + draw->pipeline.aaline->destroy( draw->pipeline.aaline ); if (draw->pipeline.rasterize) draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); tgsi_exec_machine_free_data(&draw->machine); @@ -239,6 +241,26 @@ draw_convert_wide_lines(struct draw_context *draw, boolean enable) } +/** + * The draw module may sometimes generate vertices with extra attributes + * (such as texcoords for AA lines). The driver can call this function + * to find those attributes. + */ +int +draw_find_vs_output(struct draw_context *draw, + uint semantic_name, uint semantic_index) +{ + /* XXX there may be more than one extra vertex attrib. + * For example, simulated gl_FragCoord and gl_PointCoord. + */ + if (draw->extra_vp_outputs.semantic_name == semantic_name && + draw->extra_vp_outputs.semantic_index == semantic_index) { + return draw->extra_vp_outputs.slot; + } + return 0; +} + + /** * Allocate space for temporary post-transform vertices, such as for clipping. */ diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index ddeb184497..82035aa8ad 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -41,6 +41,7 @@ #include "pipe/p_state.h" +struct pipe_context; struct vertex_buffer; struct vertex_info; struct draw_context; @@ -93,6 +94,20 @@ void draw_convert_wide_points(struct draw_context *draw, boolean enable); void draw_convert_wide_lines(struct draw_context *draw, boolean enable); +boolean draw_use_sse(struct draw_context *draw); + +void +draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); + + +int +draw_find_vs_output(struct draw_context *draw, + uint semantic_name, uint semantic_index); + + +/* + * Vertex shader functions + */ struct draw_vertex_shader * draw_create_vertex_shader(struct draw_context *draw, @@ -102,7 +117,11 @@ void draw_bind_vertex_shader(struct draw_context *draw, void draw_delete_vertex_shader(struct draw_context *draw, struct draw_vertex_shader *dvs); -boolean draw_use_sse(struct draw_context *draw); + + +/* + * Vertex data functions + */ void draw_set_vertex_buffer(struct draw_context *draw, unsigned attr, diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index 51e2242719..dd9a848863 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -121,11 +121,15 @@ static void draw_prim_queue_flush( struct draw_context *draw ) void draw_do_flush( struct draw_context *draw, unsigned flags ) { + static boolean flushing = FALSE; + if (0) debug_printf("Flushing with %d verts, %d prims\n", draw->vs.queue_nr, draw->pq.queue_nr ); + if (!flushing) { + flushing = TRUE; if (flags >= DRAW_FLUSH_SHADER_QUEUE) { if (draw->vs.queue_nr) @@ -146,6 +150,9 @@ void draw_do_flush( struct draw_context *draw, unsigned flags ) } } } + + flushing = FALSE; + } } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index bc11259cb2..dd75f9aefc 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -48,6 +48,7 @@ #include "tgsi/exec/tgsi_exec.h" +struct pipe_context; struct gallivm_prog; struct gallivm_cpu_engine; @@ -179,6 +180,7 @@ struct draw_context struct draw_stage *offset; struct draw_stage *unfilled; struct draw_stage *stipple; + struct draw_stage *aaline; struct draw_stage *wide; struct draw_stage *rasterize; } pipeline; @@ -212,9 +214,17 @@ struct draw_context unsigned nr_planes; boolean convert_wide_points; /**< convert wide points to tris? */ - boolean convert_wide_lines; /**< convert side lines to tris? */ + boolean convert_wide_lines; /**< convert wide lines to tris? */ boolean use_sse; + /* If a prim stage introduces new vertex attributes, they'll be stored here + */ + struct { + uint semantic_name; + uint semantic_index; + int slot; + } extra_vp_outputs; + unsigned reduced_prim; /** TGSI program interpreter runtime state */ diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index 4375ebabbc..97e40e372b 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -58,7 +58,13 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) * shorter pipelines for lines & points. */ - if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines) || + if (draw->rasterizer->line_smooth && draw->pipeline.aaline) { + draw->pipeline.aaline->next = next; + next = draw->pipeline.aaline; + } + + if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines + && !draw->rasterizer->line_smooth) || (draw->rasterizer->point_size != 1.0 && draw->convert_wide_points) || draw->rasterizer->point_sprite) { draw->pipeline.wide->next = next; diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index c10ab396d8..8bb62b2a0a 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -10,6 +10,7 @@ DRIVER_SOURCES = \ util/tgsi_build.c \ util/tgsi_dump.c \ util/tgsi_parse.c \ + util/tgsi_transform.c \ util/tgsi_util.c C_SOURCES = \ diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 5e98f190bb..254c6adca4 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -327,6 +327,9 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, draw_set_rasterize_stage(softpipe->draw, softpipe->setup); } + /* enable aaline stage */ + draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); + sp_init_surface_functions(softpipe); return &softpipe->pipe; diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 9d8fd8b750..f9f2c5eaa8 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -44,7 +44,8 @@ * condition that users shouldn't hit anyway. */ static int -find_vs_output(const struct pipe_shader_state *vs, +find_vs_output(struct softpipe_context *sp, + const struct pipe_shader_state *vs, uint semantic_name, uint semantic_index) { @@ -54,7 +55,9 @@ find_vs_output(const struct pipe_shader_state *vs, vs->output_semantic_index[i] == semantic_index) return i; } - return 0; + + /* See if the draw module is introducing a new attribute... */ + return draw_find_vs_output(sp->draw, semantic_name, semantic_index); } @@ -111,24 +114,24 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) int src; switch (fs->input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: - src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0); + src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_POSITION, 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src); break; case TGSI_SEMANTIC_COLOR: - src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, + src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_COLOR, fs->input_semantic_index[i]); draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); break; case TGSI_SEMANTIC_FOG: - src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0); + src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_FOG, 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); break; case TGSI_SEMANTIC_GENERIC: /* this includes texcoords and varying vars */ - src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC, + src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_GENERIC, fs->input_semantic_index[i]); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); break; @@ -138,7 +141,7 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) } } - softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0); + softpipe->psize_slot = find_vs_output(softpipe, vs, TGSI_SEMANTIC_PSIZE, 0); if (softpipe->psize_slot > 0) { draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, softpipe->psize_slot); -- cgit v1.2.3 From 478c14453b33b20724bcdb70cf1f54f4addb71ab Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 18 Feb 2008 16:50:07 -0700 Subject: gallium: remove the prototype/unused wide_line_aa() function --- src/gallium/auxiliary/draw/draw_wide_prims.c | 69 +--------------------------- 1 file changed, 1 insertion(+), 68 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_wide_prims.c b/src/gallium/auxiliary/draw/draw_wide_prims.c index 655774b155..1f8069bdca 100644 --- a/src/gallium/auxiliary/draw/draw_wide_prims.c +++ b/src/gallium/auxiliary/draw/draw_wide_prims.c @@ -161,70 +161,6 @@ static void wide_line( struct draw_stage *stage, } -/** - * Draw a wide line by drawing a quad, using geometry which will - * fullfill GL's antialiased line requirements. - */ -static void wide_line_aa(struct draw_stage *stage, - struct prim_header *header) -{ - const struct wide_stage *wide = wide_stage(stage); - const float half_width = wide->half_line_width; - struct prim_header tri; - struct vertex_header *v[4]; - float *pos; - float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; - float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; - const float len = (float) sqrt(dx * dx + dy * dy); - uint i; - - dx = dx * half_width / len; - dy = dy * half_width / len; - - /* allocate/dup new verts */ - for (i = 0; i < 4; i++) { - v[i] = dup_vert(stage, header->v[i/2], i); - } - - /* - * Quad for line from v0 to v1: - * - * 1 3 - * +-------------------------+ - * | | - * *v0 v1* - * | | - * +-------------------------+ - * 0 2 - */ - - pos = v[0]->data[0]; - pos[0] += dy; - pos[1] -= dx; - - pos = v[1]->data[0]; - pos[0] -= dy; - pos[1] += dx; - - pos = v[2]->data[0]; - pos[0] += dy; - pos[1] -= dx; - - pos = v[3]->data[0]; - pos[0] -= dy; - pos[1] += dx; - - tri.det = header->det; /* only the sign matters */ - - tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2]; - stage->next->tri( stage->next, &tri ); - -} - - /** * Set the vertex texcoords for sprite mode. * Coords may be left untouched or set to a right-side-up or upside-down @@ -379,10 +315,7 @@ static void wide_first_line( struct draw_stage *stage, wide->half_line_width = 0.5f * draw->rasterizer->line_width; if (draw->rasterizer->line_width != 1.0) { - if (draw->rasterizer->line_smooth) - wide->stage.line = wide_line_aa; - else - wide->stage.line = wide_line; + wide->stage.line = wide_line; } else { wide->stage.line = passthrough_line; -- cgit v1.2.3 From ae9931dad24703d99530b2761c759cef1cbc0fb5 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 18 Feb 2008 18:36:20 -0700 Subject: gallium: call draw_flush() for scissor/stipple state changes --- src/gallium/drivers/softpipe/sp_state_clip.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state_clip.c b/src/gallium/drivers/softpipe/sp_state_clip.c index c797c0dd3b..d8ea979957 100644 --- a/src/gallium/drivers/softpipe/sp_state_clip.c +++ b/src/gallium/drivers/softpipe/sp_state_clip.c @@ -68,6 +68,8 @@ void softpipe_set_scissor_state( struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); + draw_flush(softpipe->draw); + memcpy( &softpipe->scissor, scissor, sizeof(*scissor) ); softpipe->dirty |= SP_NEW_SCISSOR; } @@ -78,6 +80,8 @@ void softpipe_set_polygon_stipple( struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); + draw_flush(softpipe->draw); + memcpy( &softpipe->poly_stipple, stipple, sizeof(*stipple) ); softpipe->dirty |= SP_NEW_STIPPLE; } -- cgit v1.2.3 From 6c7f663cb96cac4873129f835614181405bd3f6e Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 18 Feb 2008 18:39:55 -0700 Subject: gallium: move draw_set_viewport_state() call, plus code clean-up, remove obsolete comments --- src/gallium/drivers/softpipe/sp_state_clip.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state_clip.c b/src/gallium/drivers/softpipe/sp_state_clip.c index d8ea979957..4946c776e3 100644 --- a/src/gallium/drivers/softpipe/sp_state_clip.c +++ b/src/gallium/drivers/softpipe/sp_state_clip.c @@ -42,24 +42,16 @@ void softpipe_set_clip_state( struct pipe_context *pipe, } - -/* Called when driver state tracker notices changes to the viewport - * matrix: - */ void softpipe_set_viewport_state( struct pipe_context *pipe, const struct pipe_viewport_state *viewport ) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->viewport = *viewport; /* struct copy */ - softpipe->dirty |= SP_NEW_VIEWPORT; - /* pass the viewport info to the draw module */ draw_set_viewport_state(softpipe->draw, viewport); - /* Using tnl/ and vf/ modules is temporary while getting started. - * Full pipe will have vertex shader, vertex fetch of its own. - */ + softpipe->viewport = *viewport; /* struct copy */ + softpipe->dirty |= SP_NEW_VIEWPORT; } @@ -70,7 +62,7 @@ void softpipe_set_scissor_state( struct pipe_context *pipe, draw_flush(softpipe->draw); - memcpy( &softpipe->scissor, scissor, sizeof(*scissor) ); + softpipe->scissor = *scissor; /* struct copy */ softpipe->dirty |= SP_NEW_SCISSOR; } @@ -82,6 +74,6 @@ void softpipe_set_polygon_stipple( struct pipe_context *pipe, draw_flush(softpipe->draw); - memcpy( &softpipe->poly_stipple, stipple, sizeof(*stipple) ); + softpipe->poly_stipple = *stipple; /* struct copy */ softpipe->dirty |= SP_NEW_STIPPLE; } -- cgit v1.2.3 From e279b1c57ac8d17703d80f1b644fd1d4f115101b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Feb 2008 14:35:19 +0000 Subject: More llvm -> gallivm. Forgot this one on the last commit. --- src/gallium/drivers/cell/ppu/cell_state_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_fs.c b/src/gallium/drivers/cell/ppu/cell_state_fs.c index b2ed699a5b..f3958fa429 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_fs.c +++ b/src/gallium/drivers/cell/ppu/cell_state_fs.c @@ -32,7 +32,7 @@ #include "draw/draw_context.h" #if 0 #include "pipe/p_shader_tokens.h" -#include "llvm/gallivm.h" +#include "gallivm/gallivm.h" #include "tgsi/util/tgsi_dump.h" #include "tgsi/exec/tgsi_sse2.h" #endif -- cgit v1.2.3 From e773a813cf475e2a7ad79ea1ec698bf2530d0433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 10:50:39 +0900 Subject: Initial scons support to build gallivm. Not yet complete. --- src/gallium/SConscript | 6 +++++- src/gallium/auxiliary/gallivm/SConscript | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/gallivm/SConscript (limited to 'src/gallium') diff --git a/src/gallium/SConscript b/src/gallium/SConscript index ea55ed2ed5..c505eee792 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -13,9 +13,13 @@ SConscript([ 'auxiliary/tgsi/SConscript', 'auxiliary/cso_cache/SConscript', 'auxiliary/draw/SConscript', - #'auxiliary/gallivm/SConscript', 'auxiliary/pipebuffer/SConscript', +]) + +if llvm: + SConscript(['auxiliary/gallivm/SConscript']) +SConscript([ 'drivers/softpipe/SConscript', 'drivers/i915simple/SConscript', 'drivers/i965simple/SConscript', diff --git a/src/gallium/auxiliary/gallivm/SConscript b/src/gallium/auxiliary/gallivm/SConscript new file mode 100644 index 0000000000..c0aa51b90a --- /dev/null +++ b/src/gallium/auxiliary/gallivm/SConscript @@ -0,0 +1,16 @@ +Import('*') + +gallivm = env.ConvenienceLibrary( + target = 'gallivm', + source = [ + 'gallivm.cpp', + 'gallivm_cpu.cpp', + 'instructions.cpp', + 'loweringpass.cpp', + 'tgsitollvm.cpp', + 'storage.cpp', + 'storagesoa.cpp', + 'instructionssoa.cpp', + ]) + +auxiliaries.insert(0, gallivm) -- cgit v1.2.3 From df8ab3140ce05599e1dc983ac211a30fc845d9b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 11:49:48 +0900 Subject: Bring rtasm from mesa to gallium. --- src/gallium/SConscript | 1 + src/gallium/auxiliary/rtasm/Makefile | 20 + src/gallium/auxiliary/rtasm/SConscript | 11 + src/gallium/auxiliary/rtasm/execmem.c | 133 ++++ src/gallium/auxiliary/rtasm/execmem.h | 45 ++ src/gallium/auxiliary/rtasm/mm.c | 283 ++++++++ src/gallium/auxiliary/rtasm/mm.h | 89 +++ src/gallium/auxiliary/rtasm/x86sse.c | 1195 ++++++++++++++++++++++++++++++++ src/gallium/auxiliary/rtasm/x86sse.h | 256 +++++++ 9 files changed, 2033 insertions(+) create mode 100644 src/gallium/auxiliary/rtasm/Makefile create mode 100644 src/gallium/auxiliary/rtasm/SConscript create mode 100644 src/gallium/auxiliary/rtasm/execmem.c create mode 100644 src/gallium/auxiliary/rtasm/execmem.h create mode 100644 src/gallium/auxiliary/rtasm/mm.c create mode 100644 src/gallium/auxiliary/rtasm/mm.h create mode 100644 src/gallium/auxiliary/rtasm/x86sse.c create mode 100644 src/gallium/auxiliary/rtasm/x86sse.h (limited to 'src/gallium') diff --git a/src/gallium/SConscript b/src/gallium/SConscript index c505eee792..a08b4b830e 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -10,6 +10,7 @@ Export('auxiliaries') SConscript([ # NOTE: order matters! 'auxiliary/util/SConscript', + 'auxiliary/rtasm/SConscript', 'auxiliary/tgsi/SConscript', 'auxiliary/cso_cache/SConscript', 'auxiliary/draw/SConscript', diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile new file mode 100644 index 0000000000..b3b9934e10 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -0,0 +1,20 @@ + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = rtasm + +DRIVER_SOURCES = \ + x86sse.c \ + mm.c \ + execmem.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript new file mode 100644 index 0000000000..c5b1551786 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/SConscript @@ -0,0 +1,11 @@ +Import('*') + +rtasm = env.ConvenienceLibrary( + target = 'rtasm', + source = [ + 'x86sse.c', + 'mm.c', + 'execmem.c', + ]) + +auxiliaries.insert(0, rtasm) diff --git a/src/gallium/auxiliary/rtasm/execmem.c b/src/gallium/auxiliary/rtasm/execmem.c new file mode 100644 index 0000000000..c7c35f7ef2 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/execmem.c @@ -0,0 +1,133 @@ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * \file exemem.c + * Functions for allocating executable memory. + * + * \author Keith Whitwell + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_thread.h" + +#include "execmem.h" + + +#if defined(__linux__) + +/* + * Allocate a large block of memory which can hold code then dole it out + * in pieces by means of the generic memory manager code. +*/ + +#include +#include +#include "mm.h" + +#define EXEC_HEAP_SIZE (10*1024*1024) + +_glthread_DECLARE_STATIC_MUTEX(exec_mutex); + +static struct mem_block *exec_heap = NULL; +static unsigned char *exec_mem = NULL; + + +static void +init_heap(void) +{ + if (!exec_heap) + exec_heap = mmInit( 0, EXEC_HEAP_SIZE ); + + if (!exec_mem) + exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +} + + +void * +_mesa_exec_malloc(size_t size) +{ + struct mem_block *block = NULL; + void *addr = NULL; + + _glthread_LOCK_MUTEX(exec_mutex); + + init_heap(); + + if (exec_heap) { + size = (size + 31) & ~31; + block = mmAllocMem( exec_heap, size, 32, 0 ); + } + + if (block) + addr = exec_mem + block->ofs; + else + debug_printf("_mesa_exec_malloc failed\n"); + + _glthread_UNLOCK_MUTEX(exec_mutex); + + return addr; +} + + +void +_mesa_exec_free(void *addr) +{ + _glthread_LOCK_MUTEX(exec_mutex); + + if (exec_heap) { + struct mem_block *block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem); + + if (block) + mmFreeMem(block); + } + + _glthread_UNLOCK_MUTEX(exec_mutex); +} + + +#else + +/* + * Just use regular memory. + */ + +void * +_mesa_exec_malloc(GLuint size) +{ + return _mesa_malloc( size ); +} + + +void +_mesa_exec_free(void *addr) +{ + _mesa_free(addr); +} + + +#endif diff --git a/src/gallium/auxiliary/rtasm/execmem.h b/src/gallium/auxiliary/rtasm/execmem.h new file mode 100644 index 0000000000..9fd4569165 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/execmem.h @@ -0,0 +1,45 @@ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file exemem.c + * Functions for allocating executable memory. + * + * \author Keith Whitwell + */ + +#ifndef _EXECMEM_H_ +#define _EXECMEM_H_ + +#include "pipe/p_compiler.h" + + +extern void * +_mesa_exec_malloc( size_t size ); + + +extern void +_mesa_exec_free( void *addr ); + + +#endif diff --git a/src/gallium/auxiliary/rtasm/mm.c b/src/gallium/auxiliary/rtasm/mm.c new file mode 100644 index 0000000000..15f50491da --- /dev/null +++ b/src/gallium/auxiliary/rtasm/mm.c @@ -0,0 +1,283 @@ +/* + * GLX Hardware Device Driver common code + * Copyright (C) 1999 Wittawat Yamwong + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" + +#include "mm.h" + + +void +mmDumpMemInfo(const struct mem_block *heap) +{ + debug_printf("Memory heap %p:\n", (void *)heap); + if (heap == 0) { + debug_printf(" heap == 0\n"); + } else { + const struct mem_block *p; + + for(p = heap->next; p != heap; p = p->next) { + debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + debug_printf("\nFree list:\n"); + + for(p = heap->next_free; p != heap; p = p->next_free) { + debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + } + debug_printf("End of memory blocks\n"); +} + +struct mem_block * +mmInit(int ofs, int size) +{ + struct mem_block *heap, *block; + + if (size <= 0) + return NULL; + + heap = CALLOC_STRUCT(mem_block); + if (!heap) + return NULL; + + block = CALLOC_STRUCT(mem_block); + if (!block) { + FREE(heap); + return NULL; + } + + heap->next = block; + heap->prev = block; + heap->next_free = block; + heap->prev_free = block; + + block->heap = heap; + block->next = heap; + block->prev = heap; + block->next_free = heap; + block->prev_free = heap; + + block->ofs = ofs; + block->size = size; + block->free = 1; + + return heap; +} + + +static struct mem_block * +SliceBlock(struct mem_block *p, + int startofs, int size, + int reserved, int alignment) +{ + struct mem_block *newblock; + + /* break left [p, newblock, p->next], then p = newblock */ + if (startofs > p->ofs) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs; + newblock->size = p->size - (startofs - p->ofs); + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size -= newblock->size; + p = newblock; + } + + /* break right, also [p, newblock, p->next] */ + if (size < p->size) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs + size; + newblock->size = p->size - size; + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size = size; + } + + /* p = middle block */ + p->free = 0; + + /* Remove p from the free list: + */ + p->next_free->prev_free = p->prev_free; + p->prev_free->next_free = p->next_free; + + p->next_free = 0; + p->prev_free = 0; + + p->reserved = reserved; + return p; +} + + +struct mem_block * +mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) +{ + struct mem_block *p; + const int mask = (1 << align2)-1; + int startofs = 0; + int endofs; + + if (!heap || align2 < 0 || size <= 0) + return NULL; + + for (p = heap->next_free; p != heap; p = p->next_free) { + assert(p->free); + + startofs = (p->ofs + mask) & ~mask; + if ( startofs < startSearch ) { + startofs = startSearch; + } + endofs = startofs+size; + if (endofs <= (p->ofs+p->size)) + break; + } + + if (p == heap) + return NULL; + + assert(p->free); + p = SliceBlock(p,startofs,size,0,mask+1); + + return p; +} + + +struct mem_block * +mmFindBlock(struct mem_block *heap, int start) +{ + struct mem_block *p; + + for (p = heap->next; p != heap; p = p->next) { + if (p->ofs == start) + return p; + } + + return NULL; +} + + +static INLINE int +Join2Blocks(struct mem_block *p) +{ + /* XXX there should be some assertions here */ + + /* NOTE: heap->free == 0 */ + + if (p->free && p->next->free) { + struct mem_block *q = p->next; + + assert(p->ofs + p->size == q->ofs); + p->size += q->size; + + p->next = q->next; + q->next->prev = p; + + q->next_free->prev_free = q->prev_free; + q->prev_free->next_free = q->next_free; + + FREE(q); + return 1; + } + return 0; +} + +int +mmFreeMem(struct mem_block *b) +{ + if (!b) + return 0; + + if (b->free) { + debug_printf("block already free\n"); + return -1; + } + if (b->reserved) { + debug_printf("block is reserved\n"); + return -1; + } + + b->free = 1; + b->next_free = b->heap->next_free; + b->prev_free = b->heap; + b->next_free->prev_free = b; + b->prev_free->next_free = b; + + Join2Blocks(b); + if (b->prev != b->heap) + Join2Blocks(b->prev); + + return 0; +} + + +void +mmDestroy(struct mem_block *heap) +{ + struct mem_block *p; + + if (!heap) + return; + + for (p = heap->next; p != heap; ) { + struct mem_block *next = p->next; + FREE(p); + p = next; + } + + FREE(heap); +} diff --git a/src/gallium/auxiliary/rtasm/mm.h b/src/gallium/auxiliary/rtasm/mm.h new file mode 100644 index 0000000000..f469b18d3e --- /dev/null +++ b/src/gallium/auxiliary/rtasm/mm.h @@ -0,0 +1,89 @@ +/* + * GLX Hardware Device Driver common code + * Copyright (C) 1999 Wittawat Yamwong + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * Memory manager code. Primarily used by device drivers to manage texture + * heaps, etc. + */ + + +#ifndef MM_H +#define MM_H + + +struct mem_block { + struct mem_block *next, *prev; + struct mem_block *next_free, *prev_free; + struct mem_block *heap; + int ofs,size; + unsigned int free:1; + unsigned int reserved:1; +}; + + + +/** + * input: total size in bytes + * return: a heap pointer if OK, NULL if error + */ +extern struct mem_block *mmInit(int ofs, int size); + +/** + * Allocate 'size' bytes with 2^align2 bytes alignment, + * restrict the search to free memory after 'startSearch' + * depth and back buffers should be in different 4mb banks + * to get better page hits if possible + * input: size = size of block + * align2 = 2^align2 bytes alignment + * startSearch = linear offset from start of heap to begin search + * return: pointer to the allocated block, 0 if error + */ +extern struct mem_block *mmAllocMem(struct mem_block *heap, int size, int align2, + int startSearch); + +/** + * Free block starts at offset + * input: pointer to a block + * return: 0 if OK, -1 if error + */ +extern int mmFreeMem(struct mem_block *b); + +/** + * Free block starts at offset + * input: pointer to a heap, start offset + * return: pointer to a block + */ +extern struct mem_block *mmFindBlock(struct mem_block *heap, int start); + +/** + * destroy MM + */ +extern void mmDestroy(struct mem_block *mmInit); + +/** + * For debuging purpose. + */ +extern void mmDumpMemInfo(const struct mem_block *mmInit); + +#endif diff --git a/src/gallium/auxiliary/rtasm/x86sse.c b/src/gallium/auxiliary/rtasm/x86sse.c new file mode 100644 index 0000000000..fff6f77a6b --- /dev/null +++ b/src/gallium/auxiliary/rtasm/x86sse.c @@ -0,0 +1,1195 @@ +#if defined(__i386__) || defined(__386__) + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" + +#include "x86sse.h" + +#define DISASSEM 0 +#define X86_TWOB 0x0f + +static unsigned char *cptr( void (*label)() ) +{ + return (unsigned char *)(unsigned long)label; +} + + +static void do_realloc( struct x86_function *p ) +{ + if (p->size == 0) { + p->size = 1024; + p->store = _mesa_exec_malloc(p->size); + p->csr = p->store; + } + else { + unsigned used = p->csr - p->store; + unsigned char *tmp = p->store; + p->size *= 2; + p->store = _mesa_exec_malloc(p->size); + memcpy(p->store, tmp, used); + p->csr = p->store + used; + _mesa_exec_free(tmp); + } +} + +/* Emit bytes to the instruction stream: + */ +static unsigned char *reserve( struct x86_function *p, int bytes ) +{ + if (p->csr + bytes - p->store > p->size) + do_realloc(p); + + { + unsigned char *csr = p->csr; + p->csr += bytes; + return csr; + } +} + + + +static void emit_1b( struct x86_function *p, char b0 ) +{ + char *csr = (char *)reserve(p, 1); + *csr = b0; +} + +static void emit_1i( struct x86_function *p, int i0 ) +{ + int *icsr = (int *)reserve(p, sizeof(i0)); + *icsr = i0; +} + +static void emit_1ub( struct x86_function *p, unsigned char b0 ) +{ + unsigned char *csr = reserve(p, 1); + *csr++ = b0; +} + +static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 ) +{ + unsigned char *csr = reserve(p, 2); + *csr++ = b0; + *csr++ = b1; +} + +static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 ) +{ + unsigned char *csr = reserve(p, 3); + *csr++ = b0; + *csr++ = b1; + *csr++ = b2; +} + + +/* Build a modRM byte + possible displacement. No treatment of SIB + * indexing. BZZT - no way to encode an absolute address. + */ +static void emit_modrm( struct x86_function *p, + struct x86_reg reg, + struct x86_reg regmem ) +{ + unsigned char val = 0; + + assert(reg.mod == mod_REG); + + val |= regmem.mod << 6; /* mod field */ + val |= reg.idx << 3; /* reg field */ + val |= regmem.idx; /* r/m field */ + + emit_1ub(p, val); + + /* Oh-oh we've stumbled into the SIB thing. + */ + if (regmem.file == file_REG32 && + regmem.idx == reg_SP) { + emit_1ub(p, 0x24); /* simplistic! */ + } + + switch (regmem.mod) { + case mod_REG: + case mod_INDIRECT: + break; + case mod_DISP8: + emit_1b(p, regmem.disp); + break; + case mod_DISP32: + emit_1i(p, regmem.disp); + break; + default: + assert(0); + break; + } +} + + +static void emit_modrm_noreg( struct x86_function *p, + unsigned op, + struct x86_reg regmem ) +{ + struct x86_reg dummy = x86_make_reg(file_REG32, op); + emit_modrm(p, dummy, regmem); +} + +/* Many x86 instructions have two opcodes to cope with the situations + * where the destination is a register or memory reference + * respectively. This function selects the correct opcode based on + * the arguments presented. + */ +static void emit_op_modrm( struct x86_function *p, + unsigned char op_dst_is_reg, + unsigned char op_dst_is_mem, + struct x86_reg dst, + struct x86_reg src ) +{ + switch (dst.mod) { + case mod_REG: + emit_1ub(p, op_dst_is_reg); + emit_modrm(p, dst, src); + break; + case mod_INDIRECT: + case mod_DISP32: + case mod_DISP8: + assert(src.mod == mod_REG); + emit_1ub(p, op_dst_is_mem); + emit_modrm(p, src, dst); + break; + default: + assert(0); + break; + } +} + + + + + + + +/* Create and manipulate registers and regmem values: + */ +struct x86_reg x86_make_reg( enum x86_reg_file file, + enum x86_reg_name idx ) +{ + struct x86_reg reg; + + reg.file = file; + reg.idx = idx; + reg.mod = mod_REG; + reg.disp = 0; + + return reg; +} + +struct x86_reg x86_make_disp( struct x86_reg reg, + int disp ) +{ + assert(reg.file == file_REG32); + + if (reg.mod == mod_REG) + reg.disp = disp; + else + reg.disp += disp; + + if (reg.disp == 0) + reg.mod = mod_INDIRECT; + else if (reg.disp <= 127 && reg.disp >= -128) + reg.mod = mod_DISP8; + else + reg.mod = mod_DISP32; + + return reg; +} + +struct x86_reg x86_deref( struct x86_reg reg ) +{ + return x86_make_disp(reg, 0); +} + +struct x86_reg x86_get_base_reg( struct x86_reg reg ) +{ + return x86_make_reg( reg.file, reg.idx ); +} + +unsigned char *x86_get_label( struct x86_function *p ) +{ + return p->csr; +} + + + +/*********************************************************************** + * x86 instructions + */ + + +void x86_jcc( struct x86_function *p, + enum x86_cc cc, + unsigned char *label ) +{ + int offset = label - (x86_get_label(p) + 2); + + if (offset <= 127 && offset >= -128) { + emit_1ub(p, 0x70 + cc); + emit_1b(p, (char) offset); + } + else { + offset = label - (x86_get_label(p) + 6); + emit_2ub(p, 0x0f, 0x80 + cc); + emit_1i(p, offset); + } +} + +/* Always use a 32bit offset for forward jumps: + */ +unsigned char *x86_jcc_forward( struct x86_function *p, + enum x86_cc cc ) +{ + emit_2ub(p, 0x0f, 0x80 + cc); + emit_1i(p, 0); + return x86_get_label(p); +} + +unsigned char *x86_jmp_forward( struct x86_function *p) +{ + emit_1ub(p, 0xe9); + emit_1i(p, 0); + return x86_get_label(p); +} + +unsigned char *x86_call_forward( struct x86_function *p) +{ + emit_1ub(p, 0xe8); + emit_1i(p, 0); + return x86_get_label(p); +} + +/* Fixup offset from forward jump: + */ +void x86_fixup_fwd_jump( struct x86_function *p, + unsigned char *fixup ) +{ + *(int *)(fixup - 4) = x86_get_label(p) - fixup; +} + +void x86_jmp( struct x86_function *p, unsigned char *label) +{ + emit_1ub(p, 0xe9); + emit_1i(p, label - x86_get_label(p) - 4); +} + +#if 0 +/* This doesn't work once we start reallocating & copying the + * generated code on buffer fills, because the call is relative to the + * current pc. + */ +void x86_call( struct x86_function *p, void (*label)()) +{ + emit_1ub(p, 0xe8); + emit_1i(p, cptr(label) - x86_get_label(p) - 4); +} +#else +void x86_call( struct x86_function *p, struct x86_reg reg) +{ + emit_1ub(p, 0xff); + emit_modrm(p, reg, reg); +} +#endif + + +/* michal: + * Temporary. As I need immediate operands, and dont want to mess with the codegen, + * I load the immediate into general purpose register and use it. + */ +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) +{ + assert(dst.mod == mod_REG); + emit_1ub(p, 0xb8 + dst.idx); + emit_1i(p, imm); +} + +void x86_push( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x50 + reg.idx); + p->stack_offset += 4; +} + +void x86_pop( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x58 + reg.idx); + p->stack_offset -= 4; +} + +void x86_inc( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x40 + reg.idx); +} + +void x86_dec( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x48 + reg.idx); +} + +void x86_ret( struct x86_function *p ) +{ + emit_1ub(p, 0xc3); +} + +void x86_sahf( struct x86_function *p ) +{ + emit_1ub(p, 0x9e); +} + +void x86_mov( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x8b, 0x89, dst, src ); +} + +void x86_xor( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x33, 0x31, dst, src ); +} + +void x86_cmp( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x3b, 0x39, dst, src ); +} + +void x86_lea( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, 0x8d); + emit_modrm( p, dst, src ); +} + +void x86_test( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, 0x85); + emit_modrm( p, dst, src ); +} + +void x86_add( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm(p, 0x03, 0x01, dst, src ); +} + +void x86_mul( struct x86_function *p, + struct x86_reg src ) +{ + assert (src.file == file_REG32 && src.mod == mod_REG); + emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src ); +} + +void x86_sub( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm(p, 0x2b, 0x29, dst, src ); +} + +void x86_or( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x0b, 0x09, dst, src ); +} + +void x86_and( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x23, 0x21, dst, src ); +} + + + +/*********************************************************************** + * SSE instructions + */ + + +void sse_movss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, 0xF3, X86_TWOB); + emit_op_modrm( p, 0x10, 0x11, dst, src ); +} + +void sse_movaps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x28, 0x29, dst, src ); +} + +void sse_movups( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x10, 0x11, dst, src ); +} + +void sse_movhps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod != mod_REG || src.mod != mod_REG); + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ +} + +void sse_movlps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod != mod_REG || src.mod != mod_REG); + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ +} + +void sse_maxps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5F); + emit_modrm( p, dst, src ); +} + +void sse_maxss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x5F); + emit_modrm( p, dst, src ); +} + +void sse_divss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x5E); + emit_modrm( p, dst, src ); +} + +void sse_minps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5D); + emit_modrm( p, dst, src ); +} + +void sse_subps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5C); + emit_modrm( p, dst, src ); +} + +void sse_mulps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x59); + emit_modrm( p, dst, src ); +} + +void sse_mulss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x59); + emit_modrm( p, dst, src ); +} + +void sse_addps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x58); + emit_modrm( p, dst, src ); +} + +void sse_addss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x58); + emit_modrm( p, dst, src ); +} + +void sse_andnps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x55); + emit_modrm( p, dst, src ); +} + +void sse_andps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x54); + emit_modrm( p, dst, src ); +} + +void sse_rsqrtps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x52); + emit_modrm( p, dst, src ); +} + +void sse_rsqrtss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x52); + emit_modrm( p, dst, src ); + +} + +void sse_movhlps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod == mod_REG && src.mod == mod_REG); + emit_2ub(p, X86_TWOB, 0x12); + emit_modrm( p, dst, src ); +} + +void sse_movlhps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod == mod_REG && src.mod == mod_REG); + emit_2ub(p, X86_TWOB, 0x16); + emit_modrm( p, dst, src ); +} + +void sse_orps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x56); + emit_modrm( p, dst, src ); +} + +void sse_xorps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x57); + emit_modrm( p, dst, src ); +} + +void sse_cvtps2pi( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_XMM || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x2d); + emit_modrm( p, dst, src ); +} + + +/* Shufps can also be used to implement a reduced swizzle when dest == + * arg0. + */ +void sse_shufps( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char shuf) +{ + emit_2ub(p, X86_TWOB, 0xC6); + emit_modrm(p, dest, arg0); + emit_1ub(p, shuf); +} + +void sse_cmpps( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char cc) +{ + emit_2ub(p, X86_TWOB, 0xC2); + emit_modrm(p, dest, arg0); + emit_1ub(p, cc); +} + +void sse_pmovmskb( struct x86_function *p, + struct x86_reg dest, + struct x86_reg src) +{ + emit_3ub(p, 0x66, X86_TWOB, 0xD7); + emit_modrm(p, dest, src); +} + +/*********************************************************************** + * SSE2 instructions + */ + +/** + * Perform a reduced swizzle: + */ +void sse2_pshufd( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char shuf) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x70); + emit_modrm(p, dest, arg0); + emit_1ub(p, shuf); +} + +void sse2_cvttps2dq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); + emit_modrm( p, dst, src ); +} + +void sse2_cvtps2dq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x5B); + emit_modrm( p, dst, src ); +} + +void sse2_packssdw( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x6B); + emit_modrm( p, dst, src ); +} + +void sse2_packsswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x63); + emit_modrm( p, dst, src ); +} + +void sse2_packuswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x67); + emit_modrm( p, dst, src ); +} + +void sse2_rcpps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x53); + emit_modrm( p, dst, src ); +} + +void sse2_rcpss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x53); + emit_modrm( p, dst, src ); +} + +void sse2_movd( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, 0x66, X86_TWOB); + emit_op_modrm( p, 0x6e, 0x7e, dst, src ); +} + + + + +/*********************************************************************** + * x87 instructions + */ +void x87_fist( struct x86_function *p, struct x86_reg dst ) +{ + emit_1ub(p, 0xdb); + emit_modrm_noreg(p, 2, dst); +} + +void x87_fistp( struct x86_function *p, struct x86_reg dst ) +{ + emit_1ub(p, 0xdb); + emit_modrm_noreg(p, 3, dst); +} + +void x87_fild( struct x86_function *p, struct x86_reg arg ) +{ + emit_1ub(p, 0xdf); + emit_modrm_noreg(p, 0, arg); +} + +void x87_fldz( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xee); +} + + +void x87_fldcw( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_REG32); + assert(arg.mod != mod_REG); + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 5, arg); +} + +void x87_fld1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe8); +} + +void x87_fldl2e( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xea); +} + +void x87_fldln2( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xed); +} + +void x87_fwait( struct x86_function *p ) +{ + emit_1ub(p, 0x9b); +} + +void x87_fnclex( struct x86_function *p ) +{ + emit_2ub(p, 0xdb, 0xe2); +} + +void x87_fclex( struct x86_function *p ) +{ + x87_fwait(p); + x87_fnclex(p); +} + + +static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg, + unsigned char dst0ub0, + unsigned char dst0ub1, + unsigned char arg0ub0, + unsigned char arg0ub1, + unsigned char argmem_noreg) +{ + assert(dst.file == file_x87); + + if (arg.file == file_x87) { + if (dst.idx == 0) + emit_2ub(p, dst0ub0, dst0ub1+arg.idx); + else if (arg.idx == 0) + emit_2ub(p, arg0ub0, arg0ub1+arg.idx); + else + assert(0); + } + else if (dst.idx == 0) { + assert(arg.file == file_REG32); + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, argmem_noreg, arg); + } + else + assert(0); +} + +void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xc8, + 0xdc, 0xc8, + 4); +} + +void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xe0, + 0xdc, 0xe8, + 4); +} + +void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xe8, + 0xdc, 0xe0, + 5); +} + +void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xc0, + 0xdc, 0xc0, + 0); +} + +void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xf0, + 0xdc, 0xf8, + 6); +} + +void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xf8, + 0xdc, 0xf0, + 7); +} + +void x87_fmulp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xc8+dst.idx); +} + +void x87_fsubp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xe8+dst.idx); +} + +void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xe0+dst.idx); +} + +void x87_faddp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xc0+dst.idx); +} + +void x87_fdivp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xf8+dst.idx); +} + +void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xf0+dst.idx); +} + +void x87_fucom( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xdd, 0xe0+arg.idx); +} + +void x87_fucomp( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xdd, 0xe8+arg.idx); +} + +void x87_fucompp( struct x86_function *p ) +{ + emit_2ub(p, 0xda, 0xe9); +} + +void x87_fxch( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xd9, 0xc8+arg.idx); +} + +void x87_fabs( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe1); +} + +void x87_fchs( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe0); +} + +void x87_fcos( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xff); +} + + +void x87_fprndint( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfc); +} + +void x87_fscale( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfd); +} + +void x87_fsin( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfe); +} + +void x87_fsincos( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfb); +} + +void x87_fsqrt( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfa); +} + +void x87_fxtract( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf4); +} + +/* st0 = (2^st0)-1 + * + * Restrictions: -1.0 <= st0 <= 1.0 + */ +void x87_f2xm1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf0); +} + +/* st1 = st1 * log2(st0); + * pop_stack; + */ +void x87_fyl2x( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf1); +} + +/* st1 = st1 * log2(st0 + 1.0); + * pop_stack; + * + * A fast operation, with restrictions: -.29 < st0 < .29 + */ +void x87_fyl2xp1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf9); +} + + +void x87_fld( struct x86_function *p, struct x86_reg arg ) +{ + if (arg.file == file_x87) + emit_2ub(p, 0xd9, 0xc0 + arg.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 0, arg); + } +} + +void x87_fst( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xdd, 0xd0 + dst.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 2, dst); + } +} + +void x87_fstp( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xdd, 0xd8 + dst.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 3, dst); + } +} + +void x87_fcom( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xd8, 0xd0 + dst.idx); + else { + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, 2, dst); + } +} + +void x87_fcomp( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xd8, 0xd8 + dst.idx); + else { + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, 3, dst); + } +} + + +void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_REG32); + + if (dst.idx == reg_AX && + dst.mod == mod_REG) + emit_2ub(p, 0xdf, 0xe0); + else { + emit_1ub(p, 0xdd); + emit_modrm_noreg(p, 7, dst); + } +} + + + + +/*********************************************************************** + * MMX instructions + */ + +void mmx_emms( struct x86_function *p ) +{ + assert(p->need_emms); + emit_2ub(p, 0x0f, 0x77); + p->need_emms = 0; +} + +void mmx_packssdw( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_MMX || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x6b); + emit_modrm( p, dst, src ); +} + +void mmx_packuswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_MMX || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x67); + emit_modrm( p, dst, src ); +} + +void mmx_movd( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + p->need_emms = 1; + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x6e, 0x7e, dst, src ); +} + +void mmx_movq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + p->need_emms = 1; + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x6f, 0x7f, dst, src ); +} + + +/*********************************************************************** + * Helper functions + */ + + +/* Retreive a reference to one of the function arguments, taking into + * account any push/pop activity: + */ +struct x86_reg x86_fn_arg( struct x86_function *p, + unsigned arg ) +{ + return x86_make_disp(x86_make_reg(file_REG32, reg_SP), + p->stack_offset + arg * 4); /* ??? */ +} + + +void x86_init_func( struct x86_function *p ) +{ + p->size = 0; + p->store = NULL; + p->csr = p->store; +} + +void x86_init_func_size( struct x86_function *p, unsigned code_size ) +{ + p->size = code_size; + p->store = _mesa_exec_malloc(code_size); + p->csr = p->store; +} + +void x86_release_func( struct x86_function *p ) +{ + _mesa_exec_free(p->store); + p->store = NULL; + p->csr = NULL; + p->size = 0; +} + + +void (*x86_get_func( struct x86_function *p ))(void) +{ + if (DISASSEM && p->store) + _mesa_printf("disassemble %p %p\n", p->store, p->csr); + return (void (*)(void)) (unsigned long) p->store; +} + +#else + +void x86sse_dummy( void ) +{ +} + +#endif diff --git a/src/gallium/auxiliary/rtasm/x86sse.h b/src/gallium/auxiliary/rtasm/x86sse.h new file mode 100644 index 0000000000..c2aa416492 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/x86sse.h @@ -0,0 +1,256 @@ + +#ifndef _X86SSE_H_ +#define _X86SSE_H_ + +#if defined(__i386__) || defined(__386__) + +/* It is up to the caller to ensure that instructions issued are + * suitable for the host cpu. There are no checks made in this module + * for mmx/sse/sse2 support on the cpu. + */ +struct x86_reg { + unsigned file:3; + unsigned idx:3; + unsigned mod:2; /* mod_REG if this is just a register */ + int disp:24; /* only +/- 23bits of offset - should be enough... */ +}; + +struct x86_function { + unsigned size; + unsigned char *store; + unsigned char *csr; + unsigned stack_offset; + int need_emms; + const char *fn; +}; + +enum x86_reg_file { + file_REG32, + file_MMX, + file_XMM, + file_x87 +}; + +/* Values for mod field of modr/m byte + */ +enum x86_reg_mod { + mod_INDIRECT, + mod_DISP8, + mod_DISP32, + mod_REG +}; + +enum x86_reg_name { + reg_AX, + reg_CX, + reg_DX, + reg_BX, + reg_SP, + reg_BP, + reg_SI, + reg_DI +}; + + +enum x86_cc { + cc_O, /* overflow */ + cc_NO, /* not overflow */ + cc_NAE, /* not above or equal / carry */ + cc_AE, /* above or equal / not carry */ + cc_E, /* equal / zero */ + cc_NE /* not equal / not zero */ +}; + +enum sse_cc { + cc_Equal, + cc_LessThan, + cc_LessThanEqual, + cc_Unordered, + cc_NotEqual, + cc_NotLessThan, + cc_NotLessThanEqual, + cc_Ordered +}; + +#define cc_Z cc_E +#define cc_NZ cc_NE + +/* Begin/end/retreive function creation: + */ + + +void x86_init_func( struct x86_function *p ); +void x86_init_func_size( struct x86_function *p, unsigned code_size ); +void x86_release_func( struct x86_function *p ); +void (*x86_get_func( struct x86_function *p ))( void ); + + + +/* Create and manipulate registers and regmem values: + */ +struct x86_reg x86_make_reg( enum x86_reg_file file, + enum x86_reg_name idx ); + +struct x86_reg x86_make_disp( struct x86_reg reg, + int disp ); + +struct x86_reg x86_deref( struct x86_reg reg ); + +struct x86_reg x86_get_base_reg( struct x86_reg reg ); + + +/* Labels, jumps and fixup: + */ +unsigned char *x86_get_label( struct x86_function *p ); + +void x86_jcc( struct x86_function *p, + enum x86_cc cc, + unsigned char *label ); + +unsigned char *x86_jcc_forward( struct x86_function *p, + enum x86_cc cc ); + +unsigned char *x86_jmp_forward( struct x86_function *p); + +unsigned char *x86_call_forward( struct x86_function *p); + +void x86_fixup_fwd_jump( struct x86_function *p, + unsigned char *fixup ); + +void x86_jmp( struct x86_function *p, unsigned char *label ); + +/* void x86_call( struct x86_function *p, void (*label)() ); */ +void x86_call( struct x86_function *p, struct x86_reg reg); + +/* michal: + * Temporary. As I need immediate operands, and dont want to mess with the codegen, + * I load the immediate into general purpose register and use it. + */ +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ); + + +/* Macro for sse_shufps() and sse2_pshufd(): + */ +#define SHUF(_x,_y,_z,_w) (((_x)<<0) | ((_y)<<2) | ((_z)<<4) | ((_w)<<6)) +#define SHUF_NOOP RSW(0,1,2,3) +#define GET_SHUF(swz, idx) (((swz) >> ((idx)*2)) & 0x3) + +void mmx_emms( struct x86_function *p ); +void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); + +void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, + unsigned char shuf ); +void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); + +void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, + unsigned char cc ); +void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, + unsigned char shuf ); +void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src ); + +void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_dec( struct x86_function *p, struct x86_reg reg ); +void x86_inc( struct x86_function *p, struct x86_reg reg ); +void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_mul( struct x86_function *p, struct x86_reg src ); +void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_pop( struct x86_function *p, struct x86_reg reg ); +void x86_push( struct x86_function *p, struct x86_reg reg ); +void x86_ret( struct x86_function *p ); +void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_sahf( struct x86_function *p ); + +void x87_f2xm1( struct x86_function *p ); +void x87_fabs( struct x86_function *p ); +void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_faddp( struct x86_function *p, struct x86_reg dst ); +void x87_fchs( struct x86_function *p ); +void x87_fclex( struct x86_function *p ); +void x87_fcom( struct x86_function *p, struct x86_reg dst ); +void x87_fcomp( struct x86_function *p, struct x86_reg dst ); +void x87_fcos( struct x86_function *p ); +void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fdivp( struct x86_function *p, struct x86_reg dst ); +void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fdivrp( struct x86_function *p, struct x86_reg dst ); +void x87_fild( struct x86_function *p, struct x86_reg arg ); +void x87_fist( struct x86_function *p, struct x86_reg dst ); +void x87_fistp( struct x86_function *p, struct x86_reg dst ); +void x87_fld( struct x86_function *p, struct x86_reg arg ); +void x87_fld1( struct x86_function *p ); +void x87_fldcw( struct x86_function *p, struct x86_reg arg ); +void x87_fldl2e( struct x86_function *p ); +void x87_fldln2( struct x86_function *p ); +void x87_fldz( struct x86_function *p ); +void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fmulp( struct x86_function *p, struct x86_reg dst ); +void x87_fnclex( struct x86_function *p ); +void x87_fprndint( struct x86_function *p ); +void x87_fscale( struct x86_function *p ); +void x87_fsin( struct x86_function *p ); +void x87_fsincos( struct x86_function *p ); +void x87_fsqrt( struct x86_function *p ); +void x87_fst( struct x86_function *p, struct x86_reg dst ); +void x87_fstp( struct x86_function *p, struct x86_reg dst ); +void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fsubp( struct x86_function *p, struct x86_reg dst ); +void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fsubrp( struct x86_function *p, struct x86_reg dst ); +void x87_fxch( struct x86_function *p, struct x86_reg dst ); +void x87_fxtract( struct x86_function *p ); +void x87_fyl2x( struct x86_function *p ); +void x87_fyl2xp1( struct x86_function *p ); +void x87_fwait( struct x86_function *p ); +void x87_fnstsw( struct x86_function *p, struct x86_reg dst ); +void x87_fucompp( struct x86_function *p ); +void x87_fucomp( struct x86_function *p, struct x86_reg arg ); +void x87_fucom( struct x86_function *p, struct x86_reg arg ); + + + +/* Retreive a reference to one of the function arguments, taking into + * account any push/pop activity. Note - doesn't track explict + * manipulation of ESP by other instructions. + */ +struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg ); + +#endif +#endif -- cgit v1.2.3 From 39ea0308425ad04618061129c63c22ac0efb0692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 12:00:48 +0900 Subject: Rename rtasm files. --- src/gallium/auxiliary/rtasm/Makefile | 4 +- src/gallium/auxiliary/rtasm/SConscript | 4 +- src/gallium/auxiliary/rtasm/execmem.c | 133 --- src/gallium/auxiliary/rtasm/execmem.h | 45 - src/gallium/auxiliary/rtasm/rtasm_execmem.c | 134 +++ src/gallium/auxiliary/rtasm/rtasm_execmem.h | 45 + src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 1196 +++++++++++++++++++++++++++ src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 256 ++++++ src/gallium/auxiliary/rtasm/x86sse.c | 1195 -------------------------- src/gallium/auxiliary/rtasm/x86sse.h | 256 ------ 10 files changed, 1635 insertions(+), 1633 deletions(-) delete mode 100644 src/gallium/auxiliary/rtasm/execmem.c delete mode 100644 src/gallium/auxiliary/rtasm/execmem.h create mode 100644 src/gallium/auxiliary/rtasm/rtasm_execmem.c create mode 100644 src/gallium/auxiliary/rtasm/rtasm_execmem.h create mode 100644 src/gallium/auxiliary/rtasm/rtasm_x86sse.c create mode 100644 src/gallium/auxiliary/rtasm/rtasm_x86sse.h delete mode 100644 src/gallium/auxiliary/rtasm/x86sse.c delete mode 100644 src/gallium/auxiliary/rtasm/x86sse.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile index b3b9934e10..7c8ac60794 100644 --- a/src/gallium/auxiliary/rtasm/Makefile +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -5,9 +5,9 @@ include $(TOP)/configs/current LIBNAME = rtasm DRIVER_SOURCES = \ + execmem.c \ x86sse.c \ - mm.c \ - execmem.c + mm.c C_SOURCES = \ $(DRIVER_SOURCES) diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript index c5b1551786..de8456e0ca 100644 --- a/src/gallium/auxiliary/rtasm/SConscript +++ b/src/gallium/auxiliary/rtasm/SConscript @@ -3,9 +3,9 @@ Import('*') rtasm = env.ConvenienceLibrary( target = 'rtasm', source = [ - 'x86sse.c', + 'rtasm_execmem.c', + 'rtasm_x86sse.c', 'mm.c', - 'execmem.c', ]) auxiliaries.insert(0, rtasm) diff --git a/src/gallium/auxiliary/rtasm/execmem.c b/src/gallium/auxiliary/rtasm/execmem.c deleted file mode 100644 index c7c35f7ef2..0000000000 --- a/src/gallium/auxiliary/rtasm/execmem.c +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * \file exemem.c - * Functions for allocating executable memory. - * - * \author Keith Whitwell - */ - - -#include "pipe/p_compiler.h" -#include "pipe/p_thread.h" - -#include "execmem.h" - - -#if defined(__linux__) - -/* - * Allocate a large block of memory which can hold code then dole it out - * in pieces by means of the generic memory manager code. -*/ - -#include -#include -#include "mm.h" - -#define EXEC_HEAP_SIZE (10*1024*1024) - -_glthread_DECLARE_STATIC_MUTEX(exec_mutex); - -static struct mem_block *exec_heap = NULL; -static unsigned char *exec_mem = NULL; - - -static void -init_heap(void) -{ - if (!exec_heap) - exec_heap = mmInit( 0, EXEC_HEAP_SIZE ); - - if (!exec_mem) - exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -} - - -void * -_mesa_exec_malloc(size_t size) -{ - struct mem_block *block = NULL; - void *addr = NULL; - - _glthread_LOCK_MUTEX(exec_mutex); - - init_heap(); - - if (exec_heap) { - size = (size + 31) & ~31; - block = mmAllocMem( exec_heap, size, 32, 0 ); - } - - if (block) - addr = exec_mem + block->ofs; - else - debug_printf("_mesa_exec_malloc failed\n"); - - _glthread_UNLOCK_MUTEX(exec_mutex); - - return addr; -} - - -void -_mesa_exec_free(void *addr) -{ - _glthread_LOCK_MUTEX(exec_mutex); - - if (exec_heap) { - struct mem_block *block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem); - - if (block) - mmFreeMem(block); - } - - _glthread_UNLOCK_MUTEX(exec_mutex); -} - - -#else - -/* - * Just use regular memory. - */ - -void * -_mesa_exec_malloc(GLuint size) -{ - return _mesa_malloc( size ); -} - - -void -_mesa_exec_free(void *addr) -{ - _mesa_free(addr); -} - - -#endif diff --git a/src/gallium/auxiliary/rtasm/execmem.h b/src/gallium/auxiliary/rtasm/execmem.h deleted file mode 100644 index 9fd4569165..0000000000 --- a/src/gallium/auxiliary/rtasm/execmem.h +++ /dev/null @@ -1,45 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file exemem.c - * Functions for allocating executable memory. - * - * \author Keith Whitwell - */ - -#ifndef _EXECMEM_H_ -#define _EXECMEM_H_ - -#include "pipe/p_compiler.h" - - -extern void * -_mesa_exec_malloc( size_t size ); - - -extern void -_mesa_exec_free( void *addr ); - - -#endif diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c new file mode 100644 index 0000000000..cb13db2498 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c @@ -0,0 +1,134 @@ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * \file exemem.c + * Functions for allocating executable memory. + * + * \author Keith Whitwell + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_thread.h" + +#include "rtasm_execmem.h" + + +#if defined(__linux__) + +/* + * Allocate a large block of memory which can hold code then dole it out + * in pieces by means of the generic memory manager code. +*/ + +#include +#include +#include "mm.h" + +#define EXEC_HEAP_SIZE (10*1024*1024) + +_glthread_DECLARE_STATIC_MUTEX(exec_mutex); + +static struct mem_block *exec_heap = NULL; +static unsigned char *exec_mem = NULL; + + +static void +init_heap(void) +{ + if (!exec_heap) + exec_heap = mmInit( 0, EXEC_HEAP_SIZE ); + + if (!exec_mem) + exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +} + + +void * +rtasm_exec_malloc(size_t size) +{ + struct mem_block *block = NULL; + void *addr = NULL; + + _glthread_LOCK_MUTEX(exec_mutex); + + init_heap(); + + if (exec_heap) { + size = (size + 31) & ~31; + block = mmAllocMem( exec_heap, size, 32, 0 ); + } + + if (block) + addr = exec_mem + block->ofs; + else + debug_printf("rtasm_exec_malloc failed\n"); + + _glthread_UNLOCK_MUTEX(exec_mutex); + + return addr; +} + + +void +rtasm_exec_free(void *addr) +{ + _glthread_LOCK_MUTEX(exec_mutex); + + if (exec_heap) { + struct mem_block *block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem); + + if (block) + mmFreeMem(block); + } + + _glthread_UNLOCK_MUTEX(exec_mutex); +} + + +#else + +/* + * Just use regular memory. + */ + +void * +rtasm_exec_malloc(GLuint size) +{ + return MALLOC( size ); +} + + +void +rtasm_exec_free(void *addr) +{ + FREE(addr); +} + + +#endif diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.h b/src/gallium/auxiliary/rtasm/rtasm_execmem.h new file mode 100644 index 0000000000..155c6d34e0 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.h @@ -0,0 +1,45 @@ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file exemem.c + * Functions for allocating executable memory. + * + * \author Keith Whitwell + */ + +#ifndef _RTASM_EXECMEM_H_ +#define _RTASM_EXECMEM_H_ + +#include "pipe/p_compiler.h" + + +extern void * +rtasm_exec_malloc( size_t size ); + + +extern void +rtasm_exec_free( void *addr ); + + +#endif diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c new file mode 100644 index 0000000000..3c885a9fff --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -0,0 +1,1196 @@ +#if defined(__i386__) || defined(__386__) + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" + +#include "rtasm_execmem.h" +#include "rtasm_x86sse.h" + +#define DISASSEM 0 +#define X86_TWOB 0x0f + +static unsigned char *cptr( void (*label)() ) +{ + return (unsigned char *)(unsigned long)label; +} + + +static void do_realloc( struct x86_function *p ) +{ + if (p->size == 0) { + p->size = 1024; + p->store = rtasm_exec_malloc(p->size); + p->csr = p->store; + } + else { + unsigned used = p->csr - p->store; + unsigned char *tmp = p->store; + p->size *= 2; + p->store = rtasm_exec_malloc(p->size); + memcpy(p->store, tmp, used); + p->csr = p->store + used; + rtasm_exec_free(tmp); + } +} + +/* Emit bytes to the instruction stream: + */ +static unsigned char *reserve( struct x86_function *p, int bytes ) +{ + if (p->csr + bytes - p->store > p->size) + do_realloc(p); + + { + unsigned char *csr = p->csr; + p->csr += bytes; + return csr; + } +} + + + +static void emit_1b( struct x86_function *p, char b0 ) +{ + char *csr = (char *)reserve(p, 1); + *csr = b0; +} + +static void emit_1i( struct x86_function *p, int i0 ) +{ + int *icsr = (int *)reserve(p, sizeof(i0)); + *icsr = i0; +} + +static void emit_1ub( struct x86_function *p, unsigned char b0 ) +{ + unsigned char *csr = reserve(p, 1); + *csr++ = b0; +} + +static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 ) +{ + unsigned char *csr = reserve(p, 2); + *csr++ = b0; + *csr++ = b1; +} + +static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 ) +{ + unsigned char *csr = reserve(p, 3); + *csr++ = b0; + *csr++ = b1; + *csr++ = b2; +} + + +/* Build a modRM byte + possible displacement. No treatment of SIB + * indexing. BZZT - no way to encode an absolute address. + */ +static void emit_modrm( struct x86_function *p, + struct x86_reg reg, + struct x86_reg regmem ) +{ + unsigned char val = 0; + + assert(reg.mod == mod_REG); + + val |= regmem.mod << 6; /* mod field */ + val |= reg.idx << 3; /* reg field */ + val |= regmem.idx; /* r/m field */ + + emit_1ub(p, val); + + /* Oh-oh we've stumbled into the SIB thing. + */ + if (regmem.file == file_REG32 && + regmem.idx == reg_SP) { + emit_1ub(p, 0x24); /* simplistic! */ + } + + switch (regmem.mod) { + case mod_REG: + case mod_INDIRECT: + break; + case mod_DISP8: + emit_1b(p, regmem.disp); + break; + case mod_DISP32: + emit_1i(p, regmem.disp); + break; + default: + assert(0); + break; + } +} + + +static void emit_modrm_noreg( struct x86_function *p, + unsigned op, + struct x86_reg regmem ) +{ + struct x86_reg dummy = x86_make_reg(file_REG32, op); + emit_modrm(p, dummy, regmem); +} + +/* Many x86 instructions have two opcodes to cope with the situations + * where the destination is a register or memory reference + * respectively. This function selects the correct opcode based on + * the arguments presented. + */ +static void emit_op_modrm( struct x86_function *p, + unsigned char op_dst_is_reg, + unsigned char op_dst_is_mem, + struct x86_reg dst, + struct x86_reg src ) +{ + switch (dst.mod) { + case mod_REG: + emit_1ub(p, op_dst_is_reg); + emit_modrm(p, dst, src); + break; + case mod_INDIRECT: + case mod_DISP32: + case mod_DISP8: + assert(src.mod == mod_REG); + emit_1ub(p, op_dst_is_mem); + emit_modrm(p, src, dst); + break; + default: + assert(0); + break; + } +} + + + + + + + +/* Create and manipulate registers and regmem values: + */ +struct x86_reg x86_make_reg( enum x86_reg_file file, + enum x86_reg_name idx ) +{ + struct x86_reg reg; + + reg.file = file; + reg.idx = idx; + reg.mod = mod_REG; + reg.disp = 0; + + return reg; +} + +struct x86_reg x86_make_disp( struct x86_reg reg, + int disp ) +{ + assert(reg.file == file_REG32); + + if (reg.mod == mod_REG) + reg.disp = disp; + else + reg.disp += disp; + + if (reg.disp == 0) + reg.mod = mod_INDIRECT; + else if (reg.disp <= 127 && reg.disp >= -128) + reg.mod = mod_DISP8; + else + reg.mod = mod_DISP32; + + return reg; +} + +struct x86_reg x86_deref( struct x86_reg reg ) +{ + return x86_make_disp(reg, 0); +} + +struct x86_reg x86_get_base_reg( struct x86_reg reg ) +{ + return x86_make_reg( reg.file, reg.idx ); +} + +unsigned char *x86_get_label( struct x86_function *p ) +{ + return p->csr; +} + + + +/*********************************************************************** + * x86 instructions + */ + + +void x86_jcc( struct x86_function *p, + enum x86_cc cc, + unsigned char *label ) +{ + int offset = label - (x86_get_label(p) + 2); + + if (offset <= 127 && offset >= -128) { + emit_1ub(p, 0x70 + cc); + emit_1b(p, (char) offset); + } + else { + offset = label - (x86_get_label(p) + 6); + emit_2ub(p, 0x0f, 0x80 + cc); + emit_1i(p, offset); + } +} + +/* Always use a 32bit offset for forward jumps: + */ +unsigned char *x86_jcc_forward( struct x86_function *p, + enum x86_cc cc ) +{ + emit_2ub(p, 0x0f, 0x80 + cc); + emit_1i(p, 0); + return x86_get_label(p); +} + +unsigned char *x86_jmp_forward( struct x86_function *p) +{ + emit_1ub(p, 0xe9); + emit_1i(p, 0); + return x86_get_label(p); +} + +unsigned char *x86_call_forward( struct x86_function *p) +{ + emit_1ub(p, 0xe8); + emit_1i(p, 0); + return x86_get_label(p); +} + +/* Fixup offset from forward jump: + */ +void x86_fixup_fwd_jump( struct x86_function *p, + unsigned char *fixup ) +{ + *(int *)(fixup - 4) = x86_get_label(p) - fixup; +} + +void x86_jmp( struct x86_function *p, unsigned char *label) +{ + emit_1ub(p, 0xe9); + emit_1i(p, label - x86_get_label(p) - 4); +} + +#if 0 +/* This doesn't work once we start reallocating & copying the + * generated code on buffer fills, because the call is relative to the + * current pc. + */ +void x86_call( struct x86_function *p, void (*label)()) +{ + emit_1ub(p, 0xe8); + emit_1i(p, cptr(label) - x86_get_label(p) - 4); +} +#else +void x86_call( struct x86_function *p, struct x86_reg reg) +{ + emit_1ub(p, 0xff); + emit_modrm(p, reg, reg); +} +#endif + + +/* michal: + * Temporary. As I need immediate operands, and dont want to mess with the codegen, + * I load the immediate into general purpose register and use it. + */ +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) +{ + assert(dst.mod == mod_REG); + emit_1ub(p, 0xb8 + dst.idx); + emit_1i(p, imm); +} + +void x86_push( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x50 + reg.idx); + p->stack_offset += 4; +} + +void x86_pop( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x58 + reg.idx); + p->stack_offset -= 4; +} + +void x86_inc( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x40 + reg.idx); +} + +void x86_dec( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x48 + reg.idx); +} + +void x86_ret( struct x86_function *p ) +{ + emit_1ub(p, 0xc3); +} + +void x86_sahf( struct x86_function *p ) +{ + emit_1ub(p, 0x9e); +} + +void x86_mov( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x8b, 0x89, dst, src ); +} + +void x86_xor( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x33, 0x31, dst, src ); +} + +void x86_cmp( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x3b, 0x39, dst, src ); +} + +void x86_lea( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, 0x8d); + emit_modrm( p, dst, src ); +} + +void x86_test( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, 0x85); + emit_modrm( p, dst, src ); +} + +void x86_add( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm(p, 0x03, 0x01, dst, src ); +} + +void x86_mul( struct x86_function *p, + struct x86_reg src ) +{ + assert (src.file == file_REG32 && src.mod == mod_REG); + emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src ); +} + +void x86_sub( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm(p, 0x2b, 0x29, dst, src ); +} + +void x86_or( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x0b, 0x09, dst, src ); +} + +void x86_and( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x23, 0x21, dst, src ); +} + + + +/*********************************************************************** + * SSE instructions + */ + + +void sse_movss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, 0xF3, X86_TWOB); + emit_op_modrm( p, 0x10, 0x11, dst, src ); +} + +void sse_movaps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x28, 0x29, dst, src ); +} + +void sse_movups( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x10, 0x11, dst, src ); +} + +void sse_movhps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod != mod_REG || src.mod != mod_REG); + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ +} + +void sse_movlps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod != mod_REG || src.mod != mod_REG); + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ +} + +void sse_maxps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5F); + emit_modrm( p, dst, src ); +} + +void sse_maxss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x5F); + emit_modrm( p, dst, src ); +} + +void sse_divss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x5E); + emit_modrm( p, dst, src ); +} + +void sse_minps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5D); + emit_modrm( p, dst, src ); +} + +void sse_subps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5C); + emit_modrm( p, dst, src ); +} + +void sse_mulps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x59); + emit_modrm( p, dst, src ); +} + +void sse_mulss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x59); + emit_modrm( p, dst, src ); +} + +void sse_addps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x58); + emit_modrm( p, dst, src ); +} + +void sse_addss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x58); + emit_modrm( p, dst, src ); +} + +void sse_andnps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x55); + emit_modrm( p, dst, src ); +} + +void sse_andps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x54); + emit_modrm( p, dst, src ); +} + +void sse_rsqrtps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x52); + emit_modrm( p, dst, src ); +} + +void sse_rsqrtss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x52); + emit_modrm( p, dst, src ); + +} + +void sse_movhlps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod == mod_REG && src.mod == mod_REG); + emit_2ub(p, X86_TWOB, 0x12); + emit_modrm( p, dst, src ); +} + +void sse_movlhps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod == mod_REG && src.mod == mod_REG); + emit_2ub(p, X86_TWOB, 0x16); + emit_modrm( p, dst, src ); +} + +void sse_orps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x56); + emit_modrm( p, dst, src ); +} + +void sse_xorps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x57); + emit_modrm( p, dst, src ); +} + +void sse_cvtps2pi( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_XMM || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x2d); + emit_modrm( p, dst, src ); +} + + +/* Shufps can also be used to implement a reduced swizzle when dest == + * arg0. + */ +void sse_shufps( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char shuf) +{ + emit_2ub(p, X86_TWOB, 0xC6); + emit_modrm(p, dest, arg0); + emit_1ub(p, shuf); +} + +void sse_cmpps( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char cc) +{ + emit_2ub(p, X86_TWOB, 0xC2); + emit_modrm(p, dest, arg0); + emit_1ub(p, cc); +} + +void sse_pmovmskb( struct x86_function *p, + struct x86_reg dest, + struct x86_reg src) +{ + emit_3ub(p, 0x66, X86_TWOB, 0xD7); + emit_modrm(p, dest, src); +} + +/*********************************************************************** + * SSE2 instructions + */ + +/** + * Perform a reduced swizzle: + */ +void sse2_pshufd( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char shuf) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x70); + emit_modrm(p, dest, arg0); + emit_1ub(p, shuf); +} + +void sse2_cvttps2dq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); + emit_modrm( p, dst, src ); +} + +void sse2_cvtps2dq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x5B); + emit_modrm( p, dst, src ); +} + +void sse2_packssdw( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x6B); + emit_modrm( p, dst, src ); +} + +void sse2_packsswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x63); + emit_modrm( p, dst, src ); +} + +void sse2_packuswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x67); + emit_modrm( p, dst, src ); +} + +void sse2_rcpps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x53); + emit_modrm( p, dst, src ); +} + +void sse2_rcpss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x53); + emit_modrm( p, dst, src ); +} + +void sse2_movd( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, 0x66, X86_TWOB); + emit_op_modrm( p, 0x6e, 0x7e, dst, src ); +} + + + + +/*********************************************************************** + * x87 instructions + */ +void x87_fist( struct x86_function *p, struct x86_reg dst ) +{ + emit_1ub(p, 0xdb); + emit_modrm_noreg(p, 2, dst); +} + +void x87_fistp( struct x86_function *p, struct x86_reg dst ) +{ + emit_1ub(p, 0xdb); + emit_modrm_noreg(p, 3, dst); +} + +void x87_fild( struct x86_function *p, struct x86_reg arg ) +{ + emit_1ub(p, 0xdf); + emit_modrm_noreg(p, 0, arg); +} + +void x87_fldz( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xee); +} + + +void x87_fldcw( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_REG32); + assert(arg.mod != mod_REG); + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 5, arg); +} + +void x87_fld1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe8); +} + +void x87_fldl2e( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xea); +} + +void x87_fldln2( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xed); +} + +void x87_fwait( struct x86_function *p ) +{ + emit_1ub(p, 0x9b); +} + +void x87_fnclex( struct x86_function *p ) +{ + emit_2ub(p, 0xdb, 0xe2); +} + +void x87_fclex( struct x86_function *p ) +{ + x87_fwait(p); + x87_fnclex(p); +} + + +static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg, + unsigned char dst0ub0, + unsigned char dst0ub1, + unsigned char arg0ub0, + unsigned char arg0ub1, + unsigned char argmem_noreg) +{ + assert(dst.file == file_x87); + + if (arg.file == file_x87) { + if (dst.idx == 0) + emit_2ub(p, dst0ub0, dst0ub1+arg.idx); + else if (arg.idx == 0) + emit_2ub(p, arg0ub0, arg0ub1+arg.idx); + else + assert(0); + } + else if (dst.idx == 0) { + assert(arg.file == file_REG32); + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, argmem_noreg, arg); + } + else + assert(0); +} + +void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xc8, + 0xdc, 0xc8, + 4); +} + +void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xe0, + 0xdc, 0xe8, + 4); +} + +void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xe8, + 0xdc, 0xe0, + 5); +} + +void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xc0, + 0xdc, 0xc0, + 0); +} + +void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xf0, + 0xdc, 0xf8, + 6); +} + +void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xf8, + 0xdc, 0xf0, + 7); +} + +void x87_fmulp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xc8+dst.idx); +} + +void x87_fsubp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xe8+dst.idx); +} + +void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xe0+dst.idx); +} + +void x87_faddp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xc0+dst.idx); +} + +void x87_fdivp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xf8+dst.idx); +} + +void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xf0+dst.idx); +} + +void x87_fucom( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xdd, 0xe0+arg.idx); +} + +void x87_fucomp( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xdd, 0xe8+arg.idx); +} + +void x87_fucompp( struct x86_function *p ) +{ + emit_2ub(p, 0xda, 0xe9); +} + +void x87_fxch( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xd9, 0xc8+arg.idx); +} + +void x87_fabs( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe1); +} + +void x87_fchs( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe0); +} + +void x87_fcos( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xff); +} + + +void x87_fprndint( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfc); +} + +void x87_fscale( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfd); +} + +void x87_fsin( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfe); +} + +void x87_fsincos( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfb); +} + +void x87_fsqrt( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfa); +} + +void x87_fxtract( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf4); +} + +/* st0 = (2^st0)-1 + * + * Restrictions: -1.0 <= st0 <= 1.0 + */ +void x87_f2xm1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf0); +} + +/* st1 = st1 * log2(st0); + * pop_stack; + */ +void x87_fyl2x( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf1); +} + +/* st1 = st1 * log2(st0 + 1.0); + * pop_stack; + * + * A fast operation, with restrictions: -.29 < st0 < .29 + */ +void x87_fyl2xp1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf9); +} + + +void x87_fld( struct x86_function *p, struct x86_reg arg ) +{ + if (arg.file == file_x87) + emit_2ub(p, 0xd9, 0xc0 + arg.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 0, arg); + } +} + +void x87_fst( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xdd, 0xd0 + dst.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 2, dst); + } +} + +void x87_fstp( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xdd, 0xd8 + dst.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 3, dst); + } +} + +void x87_fcom( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xd8, 0xd0 + dst.idx); + else { + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, 2, dst); + } +} + +void x87_fcomp( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xd8, 0xd8 + dst.idx); + else { + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, 3, dst); + } +} + + +void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_REG32); + + if (dst.idx == reg_AX && + dst.mod == mod_REG) + emit_2ub(p, 0xdf, 0xe0); + else { + emit_1ub(p, 0xdd); + emit_modrm_noreg(p, 7, dst); + } +} + + + + +/*********************************************************************** + * MMX instructions + */ + +void mmx_emms( struct x86_function *p ) +{ + assert(p->need_emms); + emit_2ub(p, 0x0f, 0x77); + p->need_emms = 0; +} + +void mmx_packssdw( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_MMX || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x6b); + emit_modrm( p, dst, src ); +} + +void mmx_packuswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_MMX || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x67); + emit_modrm( p, dst, src ); +} + +void mmx_movd( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + p->need_emms = 1; + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x6e, 0x7e, dst, src ); +} + +void mmx_movq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + p->need_emms = 1; + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x6f, 0x7f, dst, src ); +} + + +/*********************************************************************** + * Helper functions + */ + + +/* Retreive a reference to one of the function arguments, taking into + * account any push/pop activity: + */ +struct x86_reg x86_fn_arg( struct x86_function *p, + unsigned arg ) +{ + return x86_make_disp(x86_make_reg(file_REG32, reg_SP), + p->stack_offset + arg * 4); /* ??? */ +} + + +void x86_init_func( struct x86_function *p ) +{ + p->size = 0; + p->store = NULL; + p->csr = p->store; +} + +void x86_init_func_size( struct x86_function *p, unsigned code_size ) +{ + p->size = code_size; + p->store = rtasm_exec_malloc(code_size); + p->csr = p->store; +} + +void x86_release_func( struct x86_function *p ) +{ + rtasm_exec_free(p->store); + p->store = NULL; + p->csr = NULL; + p->size = 0; +} + + +void (*x86_get_func( struct x86_function *p ))(void) +{ + if (DISASSEM && p->store) + debug_printf("disassemble %p %p\n", p->store, p->csr); + return (void (*)(void)) (unsigned long) p->store; +} + +#else + +void x86sse_dummy( void ) +{ +} + +#endif diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h new file mode 100644 index 0000000000..c2aa416492 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -0,0 +1,256 @@ + +#ifndef _X86SSE_H_ +#define _X86SSE_H_ + +#if defined(__i386__) || defined(__386__) + +/* It is up to the caller to ensure that instructions issued are + * suitable for the host cpu. There are no checks made in this module + * for mmx/sse/sse2 support on the cpu. + */ +struct x86_reg { + unsigned file:3; + unsigned idx:3; + unsigned mod:2; /* mod_REG if this is just a register */ + int disp:24; /* only +/- 23bits of offset - should be enough... */ +}; + +struct x86_function { + unsigned size; + unsigned char *store; + unsigned char *csr; + unsigned stack_offset; + int need_emms; + const char *fn; +}; + +enum x86_reg_file { + file_REG32, + file_MMX, + file_XMM, + file_x87 +}; + +/* Values for mod field of modr/m byte + */ +enum x86_reg_mod { + mod_INDIRECT, + mod_DISP8, + mod_DISP32, + mod_REG +}; + +enum x86_reg_name { + reg_AX, + reg_CX, + reg_DX, + reg_BX, + reg_SP, + reg_BP, + reg_SI, + reg_DI +}; + + +enum x86_cc { + cc_O, /* overflow */ + cc_NO, /* not overflow */ + cc_NAE, /* not above or equal / carry */ + cc_AE, /* above or equal / not carry */ + cc_E, /* equal / zero */ + cc_NE /* not equal / not zero */ +}; + +enum sse_cc { + cc_Equal, + cc_LessThan, + cc_LessThanEqual, + cc_Unordered, + cc_NotEqual, + cc_NotLessThan, + cc_NotLessThanEqual, + cc_Ordered +}; + +#define cc_Z cc_E +#define cc_NZ cc_NE + +/* Begin/end/retreive function creation: + */ + + +void x86_init_func( struct x86_function *p ); +void x86_init_func_size( struct x86_function *p, unsigned code_size ); +void x86_release_func( struct x86_function *p ); +void (*x86_get_func( struct x86_function *p ))( void ); + + + +/* Create and manipulate registers and regmem values: + */ +struct x86_reg x86_make_reg( enum x86_reg_file file, + enum x86_reg_name idx ); + +struct x86_reg x86_make_disp( struct x86_reg reg, + int disp ); + +struct x86_reg x86_deref( struct x86_reg reg ); + +struct x86_reg x86_get_base_reg( struct x86_reg reg ); + + +/* Labels, jumps and fixup: + */ +unsigned char *x86_get_label( struct x86_function *p ); + +void x86_jcc( struct x86_function *p, + enum x86_cc cc, + unsigned char *label ); + +unsigned char *x86_jcc_forward( struct x86_function *p, + enum x86_cc cc ); + +unsigned char *x86_jmp_forward( struct x86_function *p); + +unsigned char *x86_call_forward( struct x86_function *p); + +void x86_fixup_fwd_jump( struct x86_function *p, + unsigned char *fixup ); + +void x86_jmp( struct x86_function *p, unsigned char *label ); + +/* void x86_call( struct x86_function *p, void (*label)() ); */ +void x86_call( struct x86_function *p, struct x86_reg reg); + +/* michal: + * Temporary. As I need immediate operands, and dont want to mess with the codegen, + * I load the immediate into general purpose register and use it. + */ +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ); + + +/* Macro for sse_shufps() and sse2_pshufd(): + */ +#define SHUF(_x,_y,_z,_w) (((_x)<<0) | ((_y)<<2) | ((_z)<<4) | ((_w)<<6)) +#define SHUF_NOOP RSW(0,1,2,3) +#define GET_SHUF(swz, idx) (((swz) >> ((idx)*2)) & 0x3) + +void mmx_emms( struct x86_function *p ); +void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); + +void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, + unsigned char shuf ); +void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); + +void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, + unsigned char cc ); +void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, + unsigned char shuf ); +void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src ); + +void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_dec( struct x86_function *p, struct x86_reg reg ); +void x86_inc( struct x86_function *p, struct x86_reg reg ); +void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_mul( struct x86_function *p, struct x86_reg src ); +void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_pop( struct x86_function *p, struct x86_reg reg ); +void x86_push( struct x86_function *p, struct x86_reg reg ); +void x86_ret( struct x86_function *p ); +void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_sahf( struct x86_function *p ); + +void x87_f2xm1( struct x86_function *p ); +void x87_fabs( struct x86_function *p ); +void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_faddp( struct x86_function *p, struct x86_reg dst ); +void x87_fchs( struct x86_function *p ); +void x87_fclex( struct x86_function *p ); +void x87_fcom( struct x86_function *p, struct x86_reg dst ); +void x87_fcomp( struct x86_function *p, struct x86_reg dst ); +void x87_fcos( struct x86_function *p ); +void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fdivp( struct x86_function *p, struct x86_reg dst ); +void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fdivrp( struct x86_function *p, struct x86_reg dst ); +void x87_fild( struct x86_function *p, struct x86_reg arg ); +void x87_fist( struct x86_function *p, struct x86_reg dst ); +void x87_fistp( struct x86_function *p, struct x86_reg dst ); +void x87_fld( struct x86_function *p, struct x86_reg arg ); +void x87_fld1( struct x86_function *p ); +void x87_fldcw( struct x86_function *p, struct x86_reg arg ); +void x87_fldl2e( struct x86_function *p ); +void x87_fldln2( struct x86_function *p ); +void x87_fldz( struct x86_function *p ); +void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fmulp( struct x86_function *p, struct x86_reg dst ); +void x87_fnclex( struct x86_function *p ); +void x87_fprndint( struct x86_function *p ); +void x87_fscale( struct x86_function *p ); +void x87_fsin( struct x86_function *p ); +void x87_fsincos( struct x86_function *p ); +void x87_fsqrt( struct x86_function *p ); +void x87_fst( struct x86_function *p, struct x86_reg dst ); +void x87_fstp( struct x86_function *p, struct x86_reg dst ); +void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fsubp( struct x86_function *p, struct x86_reg dst ); +void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fsubrp( struct x86_function *p, struct x86_reg dst ); +void x87_fxch( struct x86_function *p, struct x86_reg dst ); +void x87_fxtract( struct x86_function *p ); +void x87_fyl2x( struct x86_function *p ); +void x87_fyl2xp1( struct x86_function *p ); +void x87_fwait( struct x86_function *p ); +void x87_fnstsw( struct x86_function *p, struct x86_reg dst ); +void x87_fucompp( struct x86_function *p ); +void x87_fucomp( struct x86_function *p, struct x86_reg arg ); +void x87_fucom( struct x86_function *p, struct x86_reg arg ); + + + +/* Retreive a reference to one of the function arguments, taking into + * account any push/pop activity. Note - doesn't track explict + * manipulation of ESP by other instructions. + */ +struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg ); + +#endif +#endif diff --git a/src/gallium/auxiliary/rtasm/x86sse.c b/src/gallium/auxiliary/rtasm/x86sse.c deleted file mode 100644 index fff6f77a6b..0000000000 --- a/src/gallium/auxiliary/rtasm/x86sse.c +++ /dev/null @@ -1,1195 +0,0 @@ -#if defined(__i386__) || defined(__386__) - -#include "pipe/p_compiler.h" -#include "pipe/p_debug.h" - -#include "x86sse.h" - -#define DISASSEM 0 -#define X86_TWOB 0x0f - -static unsigned char *cptr( void (*label)() ) -{ - return (unsigned char *)(unsigned long)label; -} - - -static void do_realloc( struct x86_function *p ) -{ - if (p->size == 0) { - p->size = 1024; - p->store = _mesa_exec_malloc(p->size); - p->csr = p->store; - } - else { - unsigned used = p->csr - p->store; - unsigned char *tmp = p->store; - p->size *= 2; - p->store = _mesa_exec_malloc(p->size); - memcpy(p->store, tmp, used); - p->csr = p->store + used; - _mesa_exec_free(tmp); - } -} - -/* Emit bytes to the instruction stream: - */ -static unsigned char *reserve( struct x86_function *p, int bytes ) -{ - if (p->csr + bytes - p->store > p->size) - do_realloc(p); - - { - unsigned char *csr = p->csr; - p->csr += bytes; - return csr; - } -} - - - -static void emit_1b( struct x86_function *p, char b0 ) -{ - char *csr = (char *)reserve(p, 1); - *csr = b0; -} - -static void emit_1i( struct x86_function *p, int i0 ) -{ - int *icsr = (int *)reserve(p, sizeof(i0)); - *icsr = i0; -} - -static void emit_1ub( struct x86_function *p, unsigned char b0 ) -{ - unsigned char *csr = reserve(p, 1); - *csr++ = b0; -} - -static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 ) -{ - unsigned char *csr = reserve(p, 2); - *csr++ = b0; - *csr++ = b1; -} - -static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 ) -{ - unsigned char *csr = reserve(p, 3); - *csr++ = b0; - *csr++ = b1; - *csr++ = b2; -} - - -/* Build a modRM byte + possible displacement. No treatment of SIB - * indexing. BZZT - no way to encode an absolute address. - */ -static void emit_modrm( struct x86_function *p, - struct x86_reg reg, - struct x86_reg regmem ) -{ - unsigned char val = 0; - - assert(reg.mod == mod_REG); - - val |= regmem.mod << 6; /* mod field */ - val |= reg.idx << 3; /* reg field */ - val |= regmem.idx; /* r/m field */ - - emit_1ub(p, val); - - /* Oh-oh we've stumbled into the SIB thing. - */ - if (regmem.file == file_REG32 && - regmem.idx == reg_SP) { - emit_1ub(p, 0x24); /* simplistic! */ - } - - switch (regmem.mod) { - case mod_REG: - case mod_INDIRECT: - break; - case mod_DISP8: - emit_1b(p, regmem.disp); - break; - case mod_DISP32: - emit_1i(p, regmem.disp); - break; - default: - assert(0); - break; - } -} - - -static void emit_modrm_noreg( struct x86_function *p, - unsigned op, - struct x86_reg regmem ) -{ - struct x86_reg dummy = x86_make_reg(file_REG32, op); - emit_modrm(p, dummy, regmem); -} - -/* Many x86 instructions have two opcodes to cope with the situations - * where the destination is a register or memory reference - * respectively. This function selects the correct opcode based on - * the arguments presented. - */ -static void emit_op_modrm( struct x86_function *p, - unsigned char op_dst_is_reg, - unsigned char op_dst_is_mem, - struct x86_reg dst, - struct x86_reg src ) -{ - switch (dst.mod) { - case mod_REG: - emit_1ub(p, op_dst_is_reg); - emit_modrm(p, dst, src); - break; - case mod_INDIRECT: - case mod_DISP32: - case mod_DISP8: - assert(src.mod == mod_REG); - emit_1ub(p, op_dst_is_mem); - emit_modrm(p, src, dst); - break; - default: - assert(0); - break; - } -} - - - - - - - -/* Create and manipulate registers and regmem values: - */ -struct x86_reg x86_make_reg( enum x86_reg_file file, - enum x86_reg_name idx ) -{ - struct x86_reg reg; - - reg.file = file; - reg.idx = idx; - reg.mod = mod_REG; - reg.disp = 0; - - return reg; -} - -struct x86_reg x86_make_disp( struct x86_reg reg, - int disp ) -{ - assert(reg.file == file_REG32); - - if (reg.mod == mod_REG) - reg.disp = disp; - else - reg.disp += disp; - - if (reg.disp == 0) - reg.mod = mod_INDIRECT; - else if (reg.disp <= 127 && reg.disp >= -128) - reg.mod = mod_DISP8; - else - reg.mod = mod_DISP32; - - return reg; -} - -struct x86_reg x86_deref( struct x86_reg reg ) -{ - return x86_make_disp(reg, 0); -} - -struct x86_reg x86_get_base_reg( struct x86_reg reg ) -{ - return x86_make_reg( reg.file, reg.idx ); -} - -unsigned char *x86_get_label( struct x86_function *p ) -{ - return p->csr; -} - - - -/*********************************************************************** - * x86 instructions - */ - - -void x86_jcc( struct x86_function *p, - enum x86_cc cc, - unsigned char *label ) -{ - int offset = label - (x86_get_label(p) + 2); - - if (offset <= 127 && offset >= -128) { - emit_1ub(p, 0x70 + cc); - emit_1b(p, (char) offset); - } - else { - offset = label - (x86_get_label(p) + 6); - emit_2ub(p, 0x0f, 0x80 + cc); - emit_1i(p, offset); - } -} - -/* Always use a 32bit offset for forward jumps: - */ -unsigned char *x86_jcc_forward( struct x86_function *p, - enum x86_cc cc ) -{ - emit_2ub(p, 0x0f, 0x80 + cc); - emit_1i(p, 0); - return x86_get_label(p); -} - -unsigned char *x86_jmp_forward( struct x86_function *p) -{ - emit_1ub(p, 0xe9); - emit_1i(p, 0); - return x86_get_label(p); -} - -unsigned char *x86_call_forward( struct x86_function *p) -{ - emit_1ub(p, 0xe8); - emit_1i(p, 0); - return x86_get_label(p); -} - -/* Fixup offset from forward jump: - */ -void x86_fixup_fwd_jump( struct x86_function *p, - unsigned char *fixup ) -{ - *(int *)(fixup - 4) = x86_get_label(p) - fixup; -} - -void x86_jmp( struct x86_function *p, unsigned char *label) -{ - emit_1ub(p, 0xe9); - emit_1i(p, label - x86_get_label(p) - 4); -} - -#if 0 -/* This doesn't work once we start reallocating & copying the - * generated code on buffer fills, because the call is relative to the - * current pc. - */ -void x86_call( struct x86_function *p, void (*label)()) -{ - emit_1ub(p, 0xe8); - emit_1i(p, cptr(label) - x86_get_label(p) - 4); -} -#else -void x86_call( struct x86_function *p, struct x86_reg reg) -{ - emit_1ub(p, 0xff); - emit_modrm(p, reg, reg); -} -#endif - - -/* michal: - * Temporary. As I need immediate operands, and dont want to mess with the codegen, - * I load the immediate into general purpose register and use it. - */ -void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) -{ - assert(dst.mod == mod_REG); - emit_1ub(p, 0xb8 + dst.idx); - emit_1i(p, imm); -} - -void x86_push( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x50 + reg.idx); - p->stack_offset += 4; -} - -void x86_pop( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x58 + reg.idx); - p->stack_offset -= 4; -} - -void x86_inc( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x40 + reg.idx); -} - -void x86_dec( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x48 + reg.idx); -} - -void x86_ret( struct x86_function *p ) -{ - emit_1ub(p, 0xc3); -} - -void x86_sahf( struct x86_function *p ) -{ - emit_1ub(p, 0x9e); -} - -void x86_mov( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x8b, 0x89, dst, src ); -} - -void x86_xor( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x33, 0x31, dst, src ); -} - -void x86_cmp( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x3b, 0x39, dst, src ); -} - -void x86_lea( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, 0x8d); - emit_modrm( p, dst, src ); -} - -void x86_test( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, 0x85); - emit_modrm( p, dst, src ); -} - -void x86_add( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm(p, 0x03, 0x01, dst, src ); -} - -void x86_mul( struct x86_function *p, - struct x86_reg src ) -{ - assert (src.file == file_REG32 && src.mod == mod_REG); - emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src ); -} - -void x86_sub( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm(p, 0x2b, 0x29, dst, src ); -} - -void x86_or( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x0b, 0x09, dst, src ); -} - -void x86_and( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x23, 0x21, dst, src ); -} - - - -/*********************************************************************** - * SSE instructions - */ - - -void sse_movss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, 0xF3, X86_TWOB); - emit_op_modrm( p, 0x10, 0x11, dst, src ); -} - -void sse_movaps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x28, 0x29, dst, src ); -} - -void sse_movups( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x10, 0x11, dst, src ); -} - -void sse_movhps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod != mod_REG || src.mod != mod_REG); - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ -} - -void sse_movlps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod != mod_REG || src.mod != mod_REG); - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ -} - -void sse_maxps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5F); - emit_modrm( p, dst, src ); -} - -void sse_maxss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x5F); - emit_modrm( p, dst, src ); -} - -void sse_divss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x5E); - emit_modrm( p, dst, src ); -} - -void sse_minps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5D); - emit_modrm( p, dst, src ); -} - -void sse_subps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5C); - emit_modrm( p, dst, src ); -} - -void sse_mulps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x59); - emit_modrm( p, dst, src ); -} - -void sse_mulss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x59); - emit_modrm( p, dst, src ); -} - -void sse_addps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x58); - emit_modrm( p, dst, src ); -} - -void sse_addss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x58); - emit_modrm( p, dst, src ); -} - -void sse_andnps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x55); - emit_modrm( p, dst, src ); -} - -void sse_andps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x54); - emit_modrm( p, dst, src ); -} - -void sse_rsqrtps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x52); - emit_modrm( p, dst, src ); -} - -void sse_rsqrtss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x52); - emit_modrm( p, dst, src ); - -} - -void sse_movhlps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod == mod_REG && src.mod == mod_REG); - emit_2ub(p, X86_TWOB, 0x12); - emit_modrm( p, dst, src ); -} - -void sse_movlhps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod == mod_REG && src.mod == mod_REG); - emit_2ub(p, X86_TWOB, 0x16); - emit_modrm( p, dst, src ); -} - -void sse_orps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x56); - emit_modrm( p, dst, src ); -} - -void sse_xorps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x57); - emit_modrm( p, dst, src ); -} - -void sse_cvtps2pi( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_XMM || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x2d); - emit_modrm( p, dst, src ); -} - - -/* Shufps can also be used to implement a reduced swizzle when dest == - * arg0. - */ -void sse_shufps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char shuf) -{ - emit_2ub(p, X86_TWOB, 0xC6); - emit_modrm(p, dest, arg0); - emit_1ub(p, shuf); -} - -void sse_cmpps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char cc) -{ - emit_2ub(p, X86_TWOB, 0xC2); - emit_modrm(p, dest, arg0); - emit_1ub(p, cc); -} - -void sse_pmovmskb( struct x86_function *p, - struct x86_reg dest, - struct x86_reg src) -{ - emit_3ub(p, 0x66, X86_TWOB, 0xD7); - emit_modrm(p, dest, src); -} - -/*********************************************************************** - * SSE2 instructions - */ - -/** - * Perform a reduced swizzle: - */ -void sse2_pshufd( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char shuf) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x70); - emit_modrm(p, dest, arg0); - emit_1ub(p, shuf); -} - -void sse2_cvttps2dq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); - emit_modrm( p, dst, src ); -} - -void sse2_cvtps2dq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x5B); - emit_modrm( p, dst, src ); -} - -void sse2_packssdw( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x6B); - emit_modrm( p, dst, src ); -} - -void sse2_packsswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x63); - emit_modrm( p, dst, src ); -} - -void sse2_packuswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x67); - emit_modrm( p, dst, src ); -} - -void sse2_rcpps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x53); - emit_modrm( p, dst, src ); -} - -void sse2_rcpss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x53); - emit_modrm( p, dst, src ); -} - -void sse2_movd( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, 0x66, X86_TWOB); - emit_op_modrm( p, 0x6e, 0x7e, dst, src ); -} - - - - -/*********************************************************************** - * x87 instructions - */ -void x87_fist( struct x86_function *p, struct x86_reg dst ) -{ - emit_1ub(p, 0xdb); - emit_modrm_noreg(p, 2, dst); -} - -void x87_fistp( struct x86_function *p, struct x86_reg dst ) -{ - emit_1ub(p, 0xdb); - emit_modrm_noreg(p, 3, dst); -} - -void x87_fild( struct x86_function *p, struct x86_reg arg ) -{ - emit_1ub(p, 0xdf); - emit_modrm_noreg(p, 0, arg); -} - -void x87_fldz( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xee); -} - - -void x87_fldcw( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_REG32); - assert(arg.mod != mod_REG); - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 5, arg); -} - -void x87_fld1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe8); -} - -void x87_fldl2e( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xea); -} - -void x87_fldln2( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xed); -} - -void x87_fwait( struct x86_function *p ) -{ - emit_1ub(p, 0x9b); -} - -void x87_fnclex( struct x86_function *p ) -{ - emit_2ub(p, 0xdb, 0xe2); -} - -void x87_fclex( struct x86_function *p ) -{ - x87_fwait(p); - x87_fnclex(p); -} - - -static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg, - unsigned char dst0ub0, - unsigned char dst0ub1, - unsigned char arg0ub0, - unsigned char arg0ub1, - unsigned char argmem_noreg) -{ - assert(dst.file == file_x87); - - if (arg.file == file_x87) { - if (dst.idx == 0) - emit_2ub(p, dst0ub0, dst0ub1+arg.idx); - else if (arg.idx == 0) - emit_2ub(p, arg0ub0, arg0ub1+arg.idx); - else - assert(0); - } - else if (dst.idx == 0) { - assert(arg.file == file_REG32); - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, argmem_noreg, arg); - } - else - assert(0); -} - -void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xc8, - 0xdc, 0xc8, - 4); -} - -void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xe0, - 0xdc, 0xe8, - 4); -} - -void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xe8, - 0xdc, 0xe0, - 5); -} - -void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xc0, - 0xdc, 0xc0, - 0); -} - -void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xf0, - 0xdc, 0xf8, - 6); -} - -void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xf8, - 0xdc, 0xf0, - 7); -} - -void x87_fmulp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xc8+dst.idx); -} - -void x87_fsubp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xe8+dst.idx); -} - -void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xe0+dst.idx); -} - -void x87_faddp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xc0+dst.idx); -} - -void x87_fdivp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xf8+dst.idx); -} - -void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xf0+dst.idx); -} - -void x87_fucom( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xdd, 0xe0+arg.idx); -} - -void x87_fucomp( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xdd, 0xe8+arg.idx); -} - -void x87_fucompp( struct x86_function *p ) -{ - emit_2ub(p, 0xda, 0xe9); -} - -void x87_fxch( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xd9, 0xc8+arg.idx); -} - -void x87_fabs( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe1); -} - -void x87_fchs( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe0); -} - -void x87_fcos( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xff); -} - - -void x87_fprndint( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfc); -} - -void x87_fscale( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfd); -} - -void x87_fsin( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfe); -} - -void x87_fsincos( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfb); -} - -void x87_fsqrt( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfa); -} - -void x87_fxtract( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf4); -} - -/* st0 = (2^st0)-1 - * - * Restrictions: -1.0 <= st0 <= 1.0 - */ -void x87_f2xm1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf0); -} - -/* st1 = st1 * log2(st0); - * pop_stack; - */ -void x87_fyl2x( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf1); -} - -/* st1 = st1 * log2(st0 + 1.0); - * pop_stack; - * - * A fast operation, with restrictions: -.29 < st0 < .29 - */ -void x87_fyl2xp1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf9); -} - - -void x87_fld( struct x86_function *p, struct x86_reg arg ) -{ - if (arg.file == file_x87) - emit_2ub(p, 0xd9, 0xc0 + arg.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 0, arg); - } -} - -void x87_fst( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xdd, 0xd0 + dst.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 2, dst); - } -} - -void x87_fstp( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xdd, 0xd8 + dst.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 3, dst); - } -} - -void x87_fcom( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xd8, 0xd0 + dst.idx); - else { - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, 2, dst); - } -} - -void x87_fcomp( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xd8, 0xd8 + dst.idx); - else { - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, 3, dst); - } -} - - -void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_REG32); - - if (dst.idx == reg_AX && - dst.mod == mod_REG) - emit_2ub(p, 0xdf, 0xe0); - else { - emit_1ub(p, 0xdd); - emit_modrm_noreg(p, 7, dst); - } -} - - - - -/*********************************************************************** - * MMX instructions - */ - -void mmx_emms( struct x86_function *p ) -{ - assert(p->need_emms); - emit_2ub(p, 0x0f, 0x77); - p->need_emms = 0; -} - -void mmx_packssdw( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_MMX || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x6b); - emit_modrm( p, dst, src ); -} - -void mmx_packuswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_MMX || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x67); - emit_modrm( p, dst, src ); -} - -void mmx_movd( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - p->need_emms = 1; - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x6e, 0x7e, dst, src ); -} - -void mmx_movq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - p->need_emms = 1; - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x6f, 0x7f, dst, src ); -} - - -/*********************************************************************** - * Helper functions - */ - - -/* Retreive a reference to one of the function arguments, taking into - * account any push/pop activity: - */ -struct x86_reg x86_fn_arg( struct x86_function *p, - unsigned arg ) -{ - return x86_make_disp(x86_make_reg(file_REG32, reg_SP), - p->stack_offset + arg * 4); /* ??? */ -} - - -void x86_init_func( struct x86_function *p ) -{ - p->size = 0; - p->store = NULL; - p->csr = p->store; -} - -void x86_init_func_size( struct x86_function *p, unsigned code_size ) -{ - p->size = code_size; - p->store = _mesa_exec_malloc(code_size); - p->csr = p->store; -} - -void x86_release_func( struct x86_function *p ) -{ - _mesa_exec_free(p->store); - p->store = NULL; - p->csr = NULL; - p->size = 0; -} - - -void (*x86_get_func( struct x86_function *p ))(void) -{ - if (DISASSEM && p->store) - _mesa_printf("disassemble %p %p\n", p->store, p->csr); - return (void (*)(void)) (unsigned long) p->store; -} - -#else - -void x86sse_dummy( void ) -{ -} - -#endif diff --git a/src/gallium/auxiliary/rtasm/x86sse.h b/src/gallium/auxiliary/rtasm/x86sse.h deleted file mode 100644 index c2aa416492..0000000000 --- a/src/gallium/auxiliary/rtasm/x86sse.h +++ /dev/null @@ -1,256 +0,0 @@ - -#ifndef _X86SSE_H_ -#define _X86SSE_H_ - -#if defined(__i386__) || defined(__386__) - -/* It is up to the caller to ensure that instructions issued are - * suitable for the host cpu. There are no checks made in this module - * for mmx/sse/sse2 support on the cpu. - */ -struct x86_reg { - unsigned file:3; - unsigned idx:3; - unsigned mod:2; /* mod_REG if this is just a register */ - int disp:24; /* only +/- 23bits of offset - should be enough... */ -}; - -struct x86_function { - unsigned size; - unsigned char *store; - unsigned char *csr; - unsigned stack_offset; - int need_emms; - const char *fn; -}; - -enum x86_reg_file { - file_REG32, - file_MMX, - file_XMM, - file_x87 -}; - -/* Values for mod field of modr/m byte - */ -enum x86_reg_mod { - mod_INDIRECT, - mod_DISP8, - mod_DISP32, - mod_REG -}; - -enum x86_reg_name { - reg_AX, - reg_CX, - reg_DX, - reg_BX, - reg_SP, - reg_BP, - reg_SI, - reg_DI -}; - - -enum x86_cc { - cc_O, /* overflow */ - cc_NO, /* not overflow */ - cc_NAE, /* not above or equal / carry */ - cc_AE, /* above or equal / not carry */ - cc_E, /* equal / zero */ - cc_NE /* not equal / not zero */ -}; - -enum sse_cc { - cc_Equal, - cc_LessThan, - cc_LessThanEqual, - cc_Unordered, - cc_NotEqual, - cc_NotLessThan, - cc_NotLessThanEqual, - cc_Ordered -}; - -#define cc_Z cc_E -#define cc_NZ cc_NE - -/* Begin/end/retreive function creation: - */ - - -void x86_init_func( struct x86_function *p ); -void x86_init_func_size( struct x86_function *p, unsigned code_size ); -void x86_release_func( struct x86_function *p ); -void (*x86_get_func( struct x86_function *p ))( void ); - - - -/* Create and manipulate registers and regmem values: - */ -struct x86_reg x86_make_reg( enum x86_reg_file file, - enum x86_reg_name idx ); - -struct x86_reg x86_make_disp( struct x86_reg reg, - int disp ); - -struct x86_reg x86_deref( struct x86_reg reg ); - -struct x86_reg x86_get_base_reg( struct x86_reg reg ); - - -/* Labels, jumps and fixup: - */ -unsigned char *x86_get_label( struct x86_function *p ); - -void x86_jcc( struct x86_function *p, - enum x86_cc cc, - unsigned char *label ); - -unsigned char *x86_jcc_forward( struct x86_function *p, - enum x86_cc cc ); - -unsigned char *x86_jmp_forward( struct x86_function *p); - -unsigned char *x86_call_forward( struct x86_function *p); - -void x86_fixup_fwd_jump( struct x86_function *p, - unsigned char *fixup ); - -void x86_jmp( struct x86_function *p, unsigned char *label ); - -/* void x86_call( struct x86_function *p, void (*label)() ); */ -void x86_call( struct x86_function *p, struct x86_reg reg); - -/* michal: - * Temporary. As I need immediate operands, and dont want to mess with the codegen, - * I load the immediate into general purpose register and use it. - */ -void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ); - - -/* Macro for sse_shufps() and sse2_pshufd(): - */ -#define SHUF(_x,_y,_z,_w) (((_x)<<0) | ((_y)<<2) | ((_z)<<4) | ((_w)<<6)) -#define SHUF_NOOP RSW(0,1,2,3) -#define GET_SHUF(swz, idx) (((swz) >> ((idx)*2)) & 0x3) - -void mmx_emms( struct x86_function *p ); -void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); - -void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, - unsigned char shuf ); -void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); - -void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, - unsigned char cc ); -void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, - unsigned char shuf ); -void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src ); - -void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_dec( struct x86_function *p, struct x86_reg reg ); -void x86_inc( struct x86_function *p, struct x86_reg reg ); -void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_mul( struct x86_function *p, struct x86_reg src ); -void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_pop( struct x86_function *p, struct x86_reg reg ); -void x86_push( struct x86_function *p, struct x86_reg reg ); -void x86_ret( struct x86_function *p ); -void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_sahf( struct x86_function *p ); - -void x87_f2xm1( struct x86_function *p ); -void x87_fabs( struct x86_function *p ); -void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_faddp( struct x86_function *p, struct x86_reg dst ); -void x87_fchs( struct x86_function *p ); -void x87_fclex( struct x86_function *p ); -void x87_fcom( struct x86_function *p, struct x86_reg dst ); -void x87_fcomp( struct x86_function *p, struct x86_reg dst ); -void x87_fcos( struct x86_function *p ); -void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fdivp( struct x86_function *p, struct x86_reg dst ); -void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fdivrp( struct x86_function *p, struct x86_reg dst ); -void x87_fild( struct x86_function *p, struct x86_reg arg ); -void x87_fist( struct x86_function *p, struct x86_reg dst ); -void x87_fistp( struct x86_function *p, struct x86_reg dst ); -void x87_fld( struct x86_function *p, struct x86_reg arg ); -void x87_fld1( struct x86_function *p ); -void x87_fldcw( struct x86_function *p, struct x86_reg arg ); -void x87_fldl2e( struct x86_function *p ); -void x87_fldln2( struct x86_function *p ); -void x87_fldz( struct x86_function *p ); -void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fmulp( struct x86_function *p, struct x86_reg dst ); -void x87_fnclex( struct x86_function *p ); -void x87_fprndint( struct x86_function *p ); -void x87_fscale( struct x86_function *p ); -void x87_fsin( struct x86_function *p ); -void x87_fsincos( struct x86_function *p ); -void x87_fsqrt( struct x86_function *p ); -void x87_fst( struct x86_function *p, struct x86_reg dst ); -void x87_fstp( struct x86_function *p, struct x86_reg dst ); -void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fsubp( struct x86_function *p, struct x86_reg dst ); -void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fsubrp( struct x86_function *p, struct x86_reg dst ); -void x87_fxch( struct x86_function *p, struct x86_reg dst ); -void x87_fxtract( struct x86_function *p ); -void x87_fyl2x( struct x86_function *p ); -void x87_fyl2xp1( struct x86_function *p ); -void x87_fwait( struct x86_function *p ); -void x87_fnstsw( struct x86_function *p, struct x86_reg dst ); -void x87_fucompp( struct x86_function *p ); -void x87_fucomp( struct x86_function *p, struct x86_reg arg ); -void x87_fucom( struct x86_function *p, struct x86_reg arg ); - - - -/* Retreive a reference to one of the function arguments, taking into - * account any push/pop activity. Note - doesn't track explict - * manipulation of ESP by other instructions. - */ -struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg ); - -#endif -#endif -- cgit v1.2.3 From d2f6c9ab10656f6ecda131a6785a60565026d249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 12:05:32 +0900 Subject: Add copyright headers to all rtasm source files. --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 23 +++++++++++++++++++++++ src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 28 +++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 3c885a9fff..b332192a62 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -1,3 +1,26 @@ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #if defined(__i386__) || defined(__386__) #include "pipe/p_compiler.h" diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index c2aa416492..e4576001bf 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -1,6 +1,28 @@ - -#ifndef _X86SSE_H_ -#define _X86SSE_H_ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _RTASM_X86SSE_H_ +#define _RTASM_X86SSE_H_ #if defined(__i386__) || defined(__386__) -- cgit v1.2.3 From 17158c2f00f5bee29ec8239367fd5498f22e4a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 12:24:42 +0900 Subject: Move mm.c code into util module. Using the u_ prefix to distingish the c source files that support gallium interfaces and those that have really no relation with gallium itself. --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 302 +----------------------- src/gallium/auxiliary/rtasm/Makefile | 5 +- src/gallium/auxiliary/rtasm/SConscript | 3 +- src/gallium/auxiliary/rtasm/mm.c | 283 ---------------------- src/gallium/auxiliary/rtasm/mm.h | 89 ------- src/gallium/auxiliary/rtasm/rtasm_execmem.c | 2 +- src/gallium/auxiliary/util/Makefile | 3 +- src/gallium/auxiliary/util/SConscript | 1 + src/gallium/auxiliary/util/u_mm.c | 283 ++++++++++++++++++++++ src/gallium/auxiliary/util/u_mm.h | 91 +++++++ 10 files changed, 382 insertions(+), 680 deletions(-) delete mode 100644 src/gallium/auxiliary/rtasm/mm.c delete mode 100644 src/gallium/auxiliary/rtasm/mm.h create mode 100644 src/gallium/auxiliary/util/u_mm.c create mode 100644 src/gallium/auxiliary/util/u_mm.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 969aab51b5..983a105347 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -1,7 +1,6 @@ /************************************************************************** * * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 1999 Wittawat Yamwong * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -40,6 +39,7 @@ #include "pipe/p_debug.h" #include "pipe/p_thread.h" #include "pipe/p_util.h" +#include "util/u_mm.h" #include "pb_buffer.h" #include "pb_bufmgr.h" @@ -50,306 +50,6 @@ #define SUPER(__derived) (&(__derived)->base) -struct mem_block -{ - struct mem_block *next, *prev; - struct mem_block *next_free, *prev_free; - struct mem_block *heap; - int ofs, size; - unsigned int free:1; - unsigned int reserved:1; -}; - - -#ifdef DEBUG -/** - * For debugging purposes. - */ -static void -mmDumpMemInfo(const struct mem_block *heap) -{ - debug_printf("Memory heap %p:\n", (void *)heap); - if (heap == 0) { - debug_printf(" heap == 0\n"); - } else { - const struct mem_block *p; - - for(p = heap->next; p != heap; p = p->next) { - debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - debug_printf("\nFree list:\n"); - - for(p = heap->next_free; p != heap; p = p->next_free) { - debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - } - debug_printf("End of memory blocks\n"); -} -#endif - - -/** - * input: total size in bytes - * return: a heap pointer if OK, NULL if error - */ -static struct mem_block * -mmInit(int ofs, int size) -{ - struct mem_block *heap, *block; - - if (size <= 0) - return NULL; - - heap = CALLOC_STRUCT(mem_block); - if (!heap) - return NULL; - - block = CALLOC_STRUCT(mem_block); - if (!block) { - FREE(heap); - return NULL; - } - - heap->next = block; - heap->prev = block; - heap->next_free = block; - heap->prev_free = block; - - block->heap = heap; - block->next = heap; - block->prev = heap; - block->next_free = heap; - block->prev_free = heap; - - block->ofs = ofs; - block->size = size; - block->free = 1; - - return heap; -} - - -static struct mem_block * -SliceBlock(struct mem_block *p, - int startofs, int size, - int reserved, int alignment) -{ - struct mem_block *newblock; - - /* break left [p, newblock, p->next], then p = newblock */ - if (startofs > p->ofs) { - newblock = CALLOC_STRUCT(mem_block); - if (!newblock) - return NULL; - newblock->ofs = startofs; - newblock->size = p->size - (startofs - p->ofs); - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - - newblock->next_free = p->next_free; - newblock->prev_free = p; - p->next_free->prev_free = newblock; - p->next_free = newblock; - - p->size -= newblock->size; - p = newblock; - } - - /* break right, also [p, newblock, p->next] */ - if (size < p->size) { - newblock = CALLOC_STRUCT(mem_block); - if (!newblock) - return NULL; - newblock->ofs = startofs + size; - newblock->size = p->size - size; - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - - newblock->next_free = p->next_free; - newblock->prev_free = p; - p->next_free->prev_free = newblock; - p->next_free = newblock; - - p->size = size; - } - - /* p = middle block */ - p->free = 0; - - /* Remove p from the free list: - */ - p->next_free->prev_free = p->prev_free; - p->prev_free->next_free = p->next_free; - - p->next_free = 0; - p->prev_free = 0; - - p->reserved = reserved; - return p; -} - - -/** - * Allocate 'size' bytes with 2^align2 bytes alignment, - * restrict the search to free memory after 'startSearch' - * depth and back buffers should be in different 4mb banks - * to get better page hits if possible - * input: size = size of block - * align2 = 2^align2 bytes alignment - * startSearch = linear offset from start of heap to begin search - * return: pointer to the allocated block, 0 if error - */ -static struct mem_block * -mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) -{ - struct mem_block *p; - const int mask = (1 << align2)-1; - int startofs = 0; - int endofs; - - if (!heap || align2 < 0 || size <= 0) - return NULL; - - for (p = heap->next_free; p != heap; p = p->next_free) { - assert(p->free); - - startofs = (p->ofs + mask) & ~mask; - if ( startofs < startSearch ) { - startofs = startSearch; - } - endofs = startofs+size; - if (endofs <= (p->ofs+p->size)) - break; - } - - if (p == heap) - return NULL; - - assert(p->free); - p = SliceBlock(p,startofs,size,0,mask+1); - - return p; -} - - -#if 0 -/** - * Free block starts at offset - * input: pointer to a heap, start offset - * return: pointer to a block - */ -static struct mem_block * -mmFindBlock(struct mem_block *heap, int start) -{ - struct mem_block *p; - - for (p = heap->next; p != heap; p = p->next) { - if (p->ofs == start) - return p; - } - - return NULL; -} -#endif - - -static INLINE int -Join2Blocks(struct mem_block *p) -{ - /* XXX there should be some assertions here */ - - /* NOTE: heap->free == 0 */ - - if (p->free && p->next->free) { - struct mem_block *q = p->next; - - assert(p->ofs + p->size == q->ofs); - p->size += q->size; - - p->next = q->next; - q->next->prev = p; - - q->next_free->prev_free = q->prev_free; - q->prev_free->next_free = q->next_free; - - FREE(q); - return 1; - } - return 0; -} - - -/** - * Free block starts at offset - * input: pointer to a block - * return: 0 if OK, -1 if error - */ -static int -mmFreeMem(struct mem_block *b) -{ - if (!b) - return 0; - - if (b->free) { - debug_printf("block already free\n"); - return -1; - } - if (b->reserved) { - debug_printf("block is reserved\n"); - return -1; - } - - b->free = 1; - b->next_free = b->heap->next_free; - b->prev_free = b->heap; - b->next_free->prev_free = b; - b->prev_free->next_free = b; - - Join2Blocks(b); - if (b->prev != b->heap) - Join2Blocks(b->prev); - - return 0; -} - - -/** - * destroy MM - */ -static void -mmDestroy(struct mem_block *heap) -{ - struct mem_block *p; - - if (!heap) - return; - - for (p = heap->next; p != heap; ) { - struct mem_block *next = p->next; - FREE(p); - p = next; - } - - FREE(heap); -} - - struct mm_pb_manager { struct pb_manager base; diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile index 7c8ac60794..edfae2a204 100644 --- a/src/gallium/auxiliary/rtasm/Makefile +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -5,9 +5,8 @@ include $(TOP)/configs/current LIBNAME = rtasm DRIVER_SOURCES = \ - execmem.c \ - x86sse.c \ - mm.c + rtasm_execmem.c \ + rtasm_x86sse.c C_SOURCES = \ $(DRIVER_SOURCES) diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript index de8456e0ca..6eca1fe4c0 100644 --- a/src/gallium/auxiliary/rtasm/SConscript +++ b/src/gallium/auxiliary/rtasm/SConscript @@ -4,8 +4,7 @@ rtasm = env.ConvenienceLibrary( target = 'rtasm', source = [ 'rtasm_execmem.c', - 'rtasm_x86sse.c', - 'mm.c', + 'rtasm_x86sse.c' ]) auxiliaries.insert(0, rtasm) diff --git a/src/gallium/auxiliary/rtasm/mm.c b/src/gallium/auxiliary/rtasm/mm.c deleted file mode 100644 index 15f50491da..0000000000 --- a/src/gallium/auxiliary/rtasm/mm.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * GLX Hardware Device Driver common code - * Copyright (C) 1999 Wittawat Yamwong - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - - -#include "pipe/p_compiler.h" -#include "pipe/p_util.h" -#include "pipe/p_debug.h" - -#include "mm.h" - - -void -mmDumpMemInfo(const struct mem_block *heap) -{ - debug_printf("Memory heap %p:\n", (void *)heap); - if (heap == 0) { - debug_printf(" heap == 0\n"); - } else { - const struct mem_block *p; - - for(p = heap->next; p != heap; p = p->next) { - debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - debug_printf("\nFree list:\n"); - - for(p = heap->next_free; p != heap; p = p->next_free) { - debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - } - debug_printf("End of memory blocks\n"); -} - -struct mem_block * -mmInit(int ofs, int size) -{ - struct mem_block *heap, *block; - - if (size <= 0) - return NULL; - - heap = CALLOC_STRUCT(mem_block); - if (!heap) - return NULL; - - block = CALLOC_STRUCT(mem_block); - if (!block) { - FREE(heap); - return NULL; - } - - heap->next = block; - heap->prev = block; - heap->next_free = block; - heap->prev_free = block; - - block->heap = heap; - block->next = heap; - block->prev = heap; - block->next_free = heap; - block->prev_free = heap; - - block->ofs = ofs; - block->size = size; - block->free = 1; - - return heap; -} - - -static struct mem_block * -SliceBlock(struct mem_block *p, - int startofs, int size, - int reserved, int alignment) -{ - struct mem_block *newblock; - - /* break left [p, newblock, p->next], then p = newblock */ - if (startofs > p->ofs) { - newblock = CALLOC_STRUCT(mem_block); - if (!newblock) - return NULL; - newblock->ofs = startofs; - newblock->size = p->size - (startofs - p->ofs); - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - - newblock->next_free = p->next_free; - newblock->prev_free = p; - p->next_free->prev_free = newblock; - p->next_free = newblock; - - p->size -= newblock->size; - p = newblock; - } - - /* break right, also [p, newblock, p->next] */ - if (size < p->size) { - newblock = CALLOC_STRUCT(mem_block); - if (!newblock) - return NULL; - newblock->ofs = startofs + size; - newblock->size = p->size - size; - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - - newblock->next_free = p->next_free; - newblock->prev_free = p; - p->next_free->prev_free = newblock; - p->next_free = newblock; - - p->size = size; - } - - /* p = middle block */ - p->free = 0; - - /* Remove p from the free list: - */ - p->next_free->prev_free = p->prev_free; - p->prev_free->next_free = p->next_free; - - p->next_free = 0; - p->prev_free = 0; - - p->reserved = reserved; - return p; -} - - -struct mem_block * -mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) -{ - struct mem_block *p; - const int mask = (1 << align2)-1; - int startofs = 0; - int endofs; - - if (!heap || align2 < 0 || size <= 0) - return NULL; - - for (p = heap->next_free; p != heap; p = p->next_free) { - assert(p->free); - - startofs = (p->ofs + mask) & ~mask; - if ( startofs < startSearch ) { - startofs = startSearch; - } - endofs = startofs+size; - if (endofs <= (p->ofs+p->size)) - break; - } - - if (p == heap) - return NULL; - - assert(p->free); - p = SliceBlock(p,startofs,size,0,mask+1); - - return p; -} - - -struct mem_block * -mmFindBlock(struct mem_block *heap, int start) -{ - struct mem_block *p; - - for (p = heap->next; p != heap; p = p->next) { - if (p->ofs == start) - return p; - } - - return NULL; -} - - -static INLINE int -Join2Blocks(struct mem_block *p) -{ - /* XXX there should be some assertions here */ - - /* NOTE: heap->free == 0 */ - - if (p->free && p->next->free) { - struct mem_block *q = p->next; - - assert(p->ofs + p->size == q->ofs); - p->size += q->size; - - p->next = q->next; - q->next->prev = p; - - q->next_free->prev_free = q->prev_free; - q->prev_free->next_free = q->next_free; - - FREE(q); - return 1; - } - return 0; -} - -int -mmFreeMem(struct mem_block *b) -{ - if (!b) - return 0; - - if (b->free) { - debug_printf("block already free\n"); - return -1; - } - if (b->reserved) { - debug_printf("block is reserved\n"); - return -1; - } - - b->free = 1; - b->next_free = b->heap->next_free; - b->prev_free = b->heap; - b->next_free->prev_free = b; - b->prev_free->next_free = b; - - Join2Blocks(b); - if (b->prev != b->heap) - Join2Blocks(b->prev); - - return 0; -} - - -void -mmDestroy(struct mem_block *heap) -{ - struct mem_block *p; - - if (!heap) - return; - - for (p = heap->next; p != heap; ) { - struct mem_block *next = p->next; - FREE(p); - p = next; - } - - FREE(heap); -} diff --git a/src/gallium/auxiliary/rtasm/mm.h b/src/gallium/auxiliary/rtasm/mm.h deleted file mode 100644 index f469b18d3e..0000000000 --- a/src/gallium/auxiliary/rtasm/mm.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * GLX Hardware Device Driver common code - * Copyright (C) 1999 Wittawat Yamwong - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * Memory manager code. Primarily used by device drivers to manage texture - * heaps, etc. - */ - - -#ifndef MM_H -#define MM_H - - -struct mem_block { - struct mem_block *next, *prev; - struct mem_block *next_free, *prev_free; - struct mem_block *heap; - int ofs,size; - unsigned int free:1; - unsigned int reserved:1; -}; - - - -/** - * input: total size in bytes - * return: a heap pointer if OK, NULL if error - */ -extern struct mem_block *mmInit(int ofs, int size); - -/** - * Allocate 'size' bytes with 2^align2 bytes alignment, - * restrict the search to free memory after 'startSearch' - * depth and back buffers should be in different 4mb banks - * to get better page hits if possible - * input: size = size of block - * align2 = 2^align2 bytes alignment - * startSearch = linear offset from start of heap to begin search - * return: pointer to the allocated block, 0 if error - */ -extern struct mem_block *mmAllocMem(struct mem_block *heap, int size, int align2, - int startSearch); - -/** - * Free block starts at offset - * input: pointer to a block - * return: 0 if OK, -1 if error - */ -extern int mmFreeMem(struct mem_block *b); - -/** - * Free block starts at offset - * input: pointer to a heap, start offset - * return: pointer to a block - */ -extern struct mem_block *mmFindBlock(struct mem_block *heap, int start); - -/** - * destroy MM - */ -extern void mmDestroy(struct mem_block *mmInit); - -/** - * For debuging purpose. - */ -extern void mmDumpMemInfo(const struct mem_block *mmInit); - -#endif diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c index cb13db2498..9c78fa5626 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c @@ -46,7 +46,7 @@ #include #include -#include "mm.h" +#include "util/u_mm.h" #define EXEC_HEAP_SIZE (10*1024*1024) diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index b8cb148c4f..7cc2aa44f9 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -7,7 +7,8 @@ LIBNAME = util DRIVER_SOURCES = \ p_debug.c \ p_tile.c \ - p_util.c + p_util.c \ + u_mm.c C_SOURCES = \ $(DRIVER_SOURCES) diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index b126cf44d6..4717941434 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -6,6 +6,7 @@ util = env.ConvenienceLibrary( 'p_debug.c', 'p_tile.c', 'p_util.c', + 'u_mm.c', ]) auxiliaries.insert(0, util) diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c new file mode 100644 index 0000000000..b49ae074e0 --- /dev/null +++ b/src/gallium/auxiliary/util/u_mm.c @@ -0,0 +1,283 @@ +/************************************************************************** + * + * Copyright (C) 1999 Wittawat Yamwong + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_compiler.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" + +#include "util/u_mm.h" + + +void +mmDumpMemInfo(const struct mem_block *heap) +{ + debug_printf("Memory heap %p:\n", (void *)heap); + if (heap == 0) { + debug_printf(" heap == 0\n"); + } else { + const struct mem_block *p; + + for(p = heap->next; p != heap; p = p->next) { + debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + debug_printf("\nFree list:\n"); + + for(p = heap->next_free; p != heap; p = p->next_free) { + debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + } + debug_printf("End of memory blocks\n"); +} + +struct mem_block * +mmInit(int ofs, int size) +{ + struct mem_block *heap, *block; + + if (size <= 0) + return NULL; + + heap = CALLOC_STRUCT(mem_block); + if (!heap) + return NULL; + + block = CALLOC_STRUCT(mem_block); + if (!block) { + FREE(heap); + return NULL; + } + + heap->next = block; + heap->prev = block; + heap->next_free = block; + heap->prev_free = block; + + block->heap = heap; + block->next = heap; + block->prev = heap; + block->next_free = heap; + block->prev_free = heap; + + block->ofs = ofs; + block->size = size; + block->free = 1; + + return heap; +} + + +static struct mem_block * +SliceBlock(struct mem_block *p, + int startofs, int size, + int reserved, int alignment) +{ + struct mem_block *newblock; + + /* break left [p, newblock, p->next], then p = newblock */ + if (startofs > p->ofs) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs; + newblock->size = p->size - (startofs - p->ofs); + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size -= newblock->size; + p = newblock; + } + + /* break right, also [p, newblock, p->next] */ + if (size < p->size) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs + size; + newblock->size = p->size - size; + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size = size; + } + + /* p = middle block */ + p->free = 0; + + /* Remove p from the free list: + */ + p->next_free->prev_free = p->prev_free; + p->prev_free->next_free = p->next_free; + + p->next_free = 0; + p->prev_free = 0; + + p->reserved = reserved; + return p; +} + + +struct mem_block * +mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) +{ + struct mem_block *p; + const int mask = (1 << align2)-1; + int startofs = 0; + int endofs; + + if (!heap || align2 < 0 || size <= 0) + return NULL; + + for (p = heap->next_free; p != heap; p = p->next_free) { + assert(p->free); + + startofs = (p->ofs + mask) & ~mask; + if ( startofs < startSearch ) { + startofs = startSearch; + } + endofs = startofs+size; + if (endofs <= (p->ofs+p->size)) + break; + } + + if (p == heap) + return NULL; + + assert(p->free); + p = SliceBlock(p,startofs,size,0,mask+1); + + return p; +} + + +struct mem_block * +mmFindBlock(struct mem_block *heap, int start) +{ + struct mem_block *p; + + for (p = heap->next; p != heap; p = p->next) { + if (p->ofs == start) + return p; + } + + return NULL; +} + + +static INLINE int +Join2Blocks(struct mem_block *p) +{ + /* XXX there should be some assertions here */ + + /* NOTE: heap->free == 0 */ + + if (p->free && p->next->free) { + struct mem_block *q = p->next; + + assert(p->ofs + p->size == q->ofs); + p->size += q->size; + + p->next = q->next; + q->next->prev = p; + + q->next_free->prev_free = q->prev_free; + q->prev_free->next_free = q->next_free; + + FREE(q); + return 1; + } + return 0; +} + +int +mmFreeMem(struct mem_block *b) +{ + if (!b) + return 0; + + if (b->free) { + debug_printf("block already free\n"); + return -1; + } + if (b->reserved) { + debug_printf("block is reserved\n"); + return -1; + } + + b->free = 1; + b->next_free = b->heap->next_free; + b->prev_free = b->heap; + b->next_free->prev_free = b; + b->prev_free->next_free = b; + + Join2Blocks(b); + if (b->prev != b->heap) + Join2Blocks(b->prev); + + return 0; +} + + +void +mmDestroy(struct mem_block *heap) +{ + struct mem_block *p; + + if (!heap) + return; + + for (p = heap->next; p != heap; ) { + struct mem_block *next = p->next; + FREE(p); + p = next; + } + + FREE(heap); +} diff --git a/src/gallium/auxiliary/util/u_mm.h b/src/gallium/auxiliary/util/u_mm.h new file mode 100644 index 0000000000..b226b101cb --- /dev/null +++ b/src/gallium/auxiliary/util/u_mm.h @@ -0,0 +1,91 @@ +/************************************************************************** + * + * Copyright (C) 1999 Wittawat Yamwong + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * @file + * Memory manager code. Primarily used by device drivers to manage texture + * heaps, etc. + */ + + +#ifndef _U_MM_H_ +#define _U_MM_H_ + + +struct mem_block { + struct mem_block *next, *prev; + struct mem_block *next_free, *prev_free; + struct mem_block *heap; + int ofs,size; + unsigned int free:1; + unsigned int reserved:1; +}; + + + +/** + * input: total size in bytes + * return: a heap pointer if OK, NULL if error + */ +extern struct mem_block *mmInit(int ofs, int size); + +/** + * Allocate 'size' bytes with 2^align2 bytes alignment, + * restrict the search to free memory after 'startSearch' + * depth and back buffers should be in different 4mb banks + * to get better page hits if possible + * input: size = size of block + * align2 = 2^align2 bytes alignment + * startSearch = linear offset from start of heap to begin search + * return: pointer to the allocated block, 0 if error + */ +extern struct mem_block *mmAllocMem(struct mem_block *heap, int size, int align2, + int startSearch); + +/** + * Free block starts at offset + * input: pointer to a block + * return: 0 if OK, -1 if error + */ +extern int mmFreeMem(struct mem_block *b); + +/** + * Free block starts at offset + * input: pointer to a heap, start offset + * return: pointer to a block + */ +extern struct mem_block *mmFindBlock(struct mem_block *heap, int start); + +/** + * destroy MM + */ +extern void mmDestroy(struct mem_block *mmInit); + +/** + * For debuging purpose. + */ +extern void mmDumpMemInfo(const struct mem_block *mmInit); + +#endif -- cgit v1.2.3 From f430d95a36d55141cd9ef911aab70364ce4a4108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 12:52:28 +0900 Subject: Use gallium's rtasm module. --- src/gallium/auxiliary/draw/draw_private.h | 2 +- src/gallium/auxiliary/draw/draw_vf.c | 10 +++------- src/gallium/auxiliary/draw/draw_vf_sse.c | 2 +- src/gallium/auxiliary/draw/draw_vs_sse.c | 2 +- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2 +- src/gallium/drivers/softpipe/sp_fs_sse.c | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index dd75f9aefc..6c7e860861 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -44,7 +44,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "x86/rtasm/x86sse.h" +#include "rtasm/rtasm_x86sse.h" #include "tgsi/exec/tgsi_exec.h" diff --git a/src/gallium/auxiliary/draw/draw_vf.c b/src/gallium/auxiliary/draw/draw_vf.c index dc3a5ecd21..901ff20a7e 100644 --- a/src/gallium/auxiliary/draw/draw_vf.c +++ b/src/gallium/auxiliary/draw/draw_vf.c @@ -30,6 +30,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_util.h" +#include "rtasm/rtasm_execmem.h" #include "draw_vf.h" @@ -37,11 +38,6 @@ #define DRAW_VF_DBG 0 -/* TODO: remove this */ -extern void -_mesa_exec_free( void *addr ); - - static boolean match_fastpath( struct draw_vertex_fetch *vf, const struct draw_vf_fastpath *fp) { @@ -414,12 +410,12 @@ void draw_vf_destroy( struct draw_vertex_fetch *vf ) FREE(fp->attr); /* KW: At the moment, fp->func is constrained to be allocated by - * _mesa_exec_alloc(), as the hardwired fastpaths in + * rtasm_exec_alloc(), as the hardwired fastpaths in * t_vertex_generic.c are handled specially. It would be nice * to unify them, but this probably won't change until this * module gets another overhaul. */ - //_mesa_exec_free((void *) fp->func); + //rtasm_exec_free((void *) fp->func); FREE(fp); } diff --git a/src/gallium/auxiliary/draw/draw_vf_sse.c b/src/gallium/auxiliary/draw/draw_vf_sse.c index 1ad2ae756d..1e889deeea 100644 --- a/src/gallium/auxiliary/draw/draw_vf_sse.c +++ b/src/gallium/auxiliary/draw/draw_vf_sse.c @@ -35,7 +35,7 @@ #if defined(USE_SSE_ASM) -#include "x86/rtasm/x86sse.h" +#include "rtasm/rtasm_x86sse.h" #include "x86/common_x86_asm.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 27bc66812c..11ef0c503d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -41,7 +41,7 @@ #include "draw_private.h" #include "draw_context.h" -#include "x86/rtasm/x86sse.h" +#include "rtasm/rtasm_x86sse.h" #include "tgsi/exec/tgsi_sse2.h" diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 62c6a69c63..29a7f842ed 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -32,7 +32,7 @@ #include "tgsi_exec.h" #include "tgsi_sse2.h" -#include "x86/rtasm/x86sse.h" +#include "rtasm/rtasm_x86sse.h" #if defined(__i386__) || defined(__386__) diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index d90066e025..b18772f4e6 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -42,7 +42,7 @@ #if defined(__i386__) || defined(__386__) -#include "x86/rtasm/x86sse.h" +#include "rtasm/rtasm_x86sse.h" /* Surely this should be defined somewhere in a tgsi header: */ -- cgit v1.2.3 From 90b2beb661f630966788a6e909dc759c99e38973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 13:27:13 +0900 Subject: Simplify makefile boilerplate code. Don't define ASM_SOURCES variable globally -- reserve that variable to be defined locally by makefiles, together with C_SOURCES and CPP_SOURCES. --- src/gallium/auxiliary/cso_cache/Makefile | 7 +------ src/gallium/auxiliary/draw/Makefile | 7 +------ src/gallium/auxiliary/pipebuffer/Makefile | 8 +------- src/gallium/auxiliary/rtasm/Makefile | 8 +------- src/gallium/auxiliary/tgsi/Makefile | 8 +------- src/gallium/auxiliary/util/Makefile | 8 +------- src/gallium/drivers/failover/Makefile | 9 +-------- src/gallium/drivers/i915simple/Makefile | 9 +-------- src/gallium/drivers/i965simple/Makefile | 25 +++++++------------------ src/gallium/drivers/softpipe/Makefile | 9 +-------- src/gallium/winsys/dri/Makefile.template | 5 +++-- 11 files changed, 19 insertions(+), 84 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/Makefile b/src/gallium/auxiliary/cso_cache/Makefile index 8248b097fd..3e49266163 100644 --- a/src/gallium/auxiliary/cso_cache/Makefile +++ b/src/gallium/auxiliary/cso_cache/Makefile @@ -3,15 +3,10 @@ include $(TOP)/configs/current LIBNAME = cso_cache -DRIVER_SOURCES = \ +C_SOURCES = \ cso_cache.c \ cso_hash.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index c8000cbe9c..1ee9eca0ca 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -3,7 +3,7 @@ include $(TOP)/configs/current LIBNAME = draw -DRIVER_SOURCES = \ +C_SOURCES = \ draw_aaline.c \ draw_clip.c \ draw_vs_exec.c \ @@ -29,11 +29,6 @@ DRIVER_SOURCES = \ draw_vf_sse.c \ draw_wide_prims.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile index 588629e870..a9fa518c67 100644 --- a/src/gallium/auxiliary/pipebuffer/Makefile +++ b/src/gallium/auxiliary/pipebuffer/Makefile @@ -1,10 +1,9 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = pipebuffer -DRIVER_SOURCES = \ +C_SOURCES = \ pb_buffer_fenced.c \ pb_buffer_malloc.c \ pb_bufmgr_fenced.c \ @@ -12,11 +11,6 @@ DRIVER_SOURCES = \ pb_bufmgr_pool.c \ pb_winsys.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile index edfae2a204..bc339d2aa6 100644 --- a/src/gallium/auxiliary/rtasm/Makefile +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -1,18 +1,12 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = rtasm -DRIVER_SOURCES = \ +C_SOURCES = \ rtasm_execmem.c \ rtasm_x86sse.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index 8bb62b2a0a..71f64b747c 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -1,10 +1,9 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = tgsi -DRIVER_SOURCES = \ +C_SOURCES = \ exec/tgsi_exec.c \ exec/tgsi_sse2.c \ util/tgsi_build.c \ @@ -13,11 +12,6 @@ DRIVER_SOURCES = \ util/tgsi_transform.c \ util/tgsi_util.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index 7cc2aa44f9..906a46d6b4 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -1,20 +1,14 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = util -DRIVER_SOURCES = \ +C_SOURCES = \ p_debug.c \ p_tile.c \ p_util.c \ u_mm.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/failover/Makefile b/src/gallium/drivers/failover/Makefile index 14389bd055..f08b8df07a 100644 --- a/src/gallium/drivers/failover/Makefile +++ b/src/gallium/drivers/failover/Makefile @@ -1,20 +1,13 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = failover -DRIVER_SOURCES = \ +C_SOURCES = \ fo_state.c \ fo_state_emit.c \ fo_context.c -C_SOURCES = \ - $(COMMON_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/i915simple/Makefile b/src/gallium/drivers/i915simple/Makefile index ee22ba86f9..2a75f5d57c 100644 --- a/src/gallium/drivers/i915simple/Makefile +++ b/src/gallium/drivers/i915simple/Makefile @@ -1,10 +1,9 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = i915simple -DRIVER_SOURCES = \ +C_SOURCES = \ i915_blit.c \ i915_clear.c \ i915_flush.c \ @@ -26,12 +25,6 @@ DRIVER_SOURCES = \ i915_fpc_translate.c \ i915_surface.c -C_SOURCES = \ - $(COMMON_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/i965simple/Makefile b/src/gallium/drivers/i965simple/Makefile index 1dec1f9749..cc8580836c 100644 --- a/src/gallium/drivers/i965simple/Makefile +++ b/src/gallium/drivers/i965simple/Makefile @@ -1,14 +1,13 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = i965simple -DRIVER_SOURCES = \ - brw_blit.c \ - brw_flush.c \ - brw_strings.c \ - brw_surface.c \ +C_SOURCES = \ + brw_blit.c \ + brw_flush.c \ + brw_strings.c \ + brw_surface.c \ brw_cc.c \ brw_clip.c \ brw_clip_line.c \ @@ -31,8 +30,8 @@ DRIVER_SOURCES = \ brw_sf.c \ brw_sf_emit.c \ brw_sf_state.c \ - brw_shader_info.c \ - brw_state.c \ + brw_shader_info.c \ + brw_state.c \ brw_state_batch.c \ brw_state_cache.c \ brw_state_pool.c \ @@ -51,16 +50,6 @@ DRIVER_SOURCES = \ brw_wm_state.c \ brw_wm_surface_state.c -C_SOURCES = \ - $(COMMON_SOURCES) \ - $(COMMON_BM_SOURCES) \ - $(MINIGLX_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - -DRIVER_DEFINES = -I. - include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index 5479daf8ea..539ffb77f5 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -1,10 +1,9 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = softpipe -DRIVER_SOURCES = \ +C_SOURCES = \ sp_fs_exec.c \ sp_fs_sse.c \ sp_fs_llvm.c \ @@ -41,12 +40,6 @@ DRIVER_SOURCES = \ sp_tile_cache.c \ sp_surface.c -C_SOURCES = \ - $(COMMON_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 65a93bd53e..3bc1fdd4d4 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -25,8 +25,9 @@ WINOBJ= WINLIB= INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) -OBJECTS = $(C_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) +OBJECTS = \ + $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) else # miniglx -- cgit v1.2.3 From b0eef0dc2557febea7d425fee1f9c2da382898a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 13:41:38 +0900 Subject: Add run-time cpu capabilities detection stubs. --- src/gallium/auxiliary/draw/draw_vf_sse.c | 6 ++-- src/gallium/auxiliary/rtasm/Makefile | 1 + src/gallium/auxiliary/rtasm/SConscript | 1 + src/gallium/auxiliary/rtasm/rtasm_cpu.c | 50 ++++++++++++++++++++++++++++++++ src/gallium/auxiliary/rtasm/rtasm_cpu.h | 42 +++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 src/gallium/auxiliary/rtasm/rtasm_cpu.c create mode 100644 src/gallium/auxiliary/rtasm/rtasm_cpu.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vf_sse.c b/src/gallium/auxiliary/draw/draw_vf_sse.c index 1e889deeea..6076f9849d 100644 --- a/src/gallium/auxiliary/draw/draw_vf_sse.c +++ b/src/gallium/auxiliary/draw/draw_vf_sse.c @@ -35,8 +35,8 @@ #if defined(USE_SSE_ASM) +#include "rtasm/rtasm_cpu.h" #include "rtasm/rtasm_x86sse.h" -#include "x86/common_x86_asm.h" #define X 0 @@ -576,7 +576,7 @@ void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) { struct x86_program p; - if (!cpu_has_xmm) { + if (!rtasm_cpu_has_sse()) { vf->codegen_emit = NULL; return; } @@ -586,7 +586,7 @@ void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) p.vf = vf; p.inputs_safe = 0; /* for now */ p.outputs_safe = 1; /* for now */ - p.have_sse2 = cpu_has_xmm2; + p.have_sse2 = rtasm_cpu_has_sse2(); p.identity = x86_make_reg(file_XMM, 6); p.chan0 = x86_make_reg(file_XMM, 7); diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile index bc339d2aa6..9b972f8f86 100644 --- a/src/gallium/auxiliary/rtasm/Makefile +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -4,6 +4,7 @@ include $(TOP)/configs/current LIBNAME = rtasm C_SOURCES = \ + rtasm_cpu.c \ rtasm_execmem.c \ rtasm_x86sse.c diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript index 6eca1fe4c0..ac41a4f212 100644 --- a/src/gallium/auxiliary/rtasm/SConscript +++ b/src/gallium/auxiliary/rtasm/SConscript @@ -3,6 +3,7 @@ Import('*') rtasm = env.ConvenienceLibrary( target = 'rtasm', source = [ + 'rtasm_cpu.c', 'rtasm_execmem.c', 'rtasm_x86sse.c' ]) diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c new file mode 100644 index 0000000000..eb3359750b --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c @@ -0,0 +1,50 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "rtasm_cpu.h" + + +int rtasm_cpu_has_sse(void) +{ + /* FIXME: actually detect this at run-time */ +#if defined(__i386__) || defined(__386__) + return 1; +#else + return 0; +#endif +} + +int rtasm_cpu_has_sse2(void) +{ + /* FIXME: actually detect this at run-time */ +#if defined(__i386__) || defined(__386__) + return 1; +#else + return 0; +#endif +} diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.h b/src/gallium/auxiliary/rtasm/rtasm_cpu.h new file mode 100644 index 0000000000..ebc71634fd --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.h @@ -0,0 +1,42 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Runtime detection of CPU capabilities. + */ + +#ifndef _RTASM_CPU_H_ +#define _RTASM_CPU_H_ + + +int rtasm_cpu_has_sse(void); + +int rtasm_cpu_has_sse2(void); + + +#endif /* _RTASM_CPU_H_ */ -- cgit v1.2.3 From 5d78212d752e021555356bbb9cc5993ad6d9e847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 14:00:16 +0900 Subject: Bring in ppc spe rtasm into gallium's rtasm module. Moving files since these are not being used outside gallium. --- src/gallium/auxiliary/rtasm/Makefile | 3 +- src/gallium/auxiliary/rtasm/SConscript | 3 +- src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c | 386 +++++++++++++++++++++++ src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h | 314 ++++++++++++++++++ src/gallium/drivers/cell/ppu/cell_context.h | 2 +- src/gallium/drivers/cell/ppu/cell_vertex_fetch.c | 2 +- 6 files changed, 706 insertions(+), 4 deletions(-) create mode 100644 src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c create mode 100644 src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile index 9b972f8f86..39b8a4dbd7 100644 --- a/src/gallium/auxiliary/rtasm/Makefile +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -6,7 +6,8 @@ LIBNAME = rtasm C_SOURCES = \ rtasm_cpu.c \ rtasm_execmem.c \ - rtasm_x86sse.c + rtasm_x86sse.c \ + rtasm_ppc_spe.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript index ac41a4f212..8ea25922aa 100644 --- a/src/gallium/auxiliary/rtasm/SConscript +++ b/src/gallium/auxiliary/rtasm/SConscript @@ -5,7 +5,8 @@ rtasm = env.ConvenienceLibrary( source = [ 'rtasm_cpu.c', 'rtasm_execmem.c', - 'rtasm_x86sse.c' + 'rtasm_x86sse.c', + 'rtasm_ppc_spe.c', ]) auxiliaries.insert(0, rtasm) diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c new file mode 100644 index 0000000000..95a2d6fcbb --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c @@ -0,0 +1,386 @@ +/* + * (C) Copyright IBM Corporation 2008 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file + * Real-time assembly generation interface for Cell B.E. SPEs. + * + * \author Ian Romanick + */ + +#include "pipe/p_compiler.h" +#include "pipe/p_util.h" +#include "rtasm_ppc_spe.h" + +#ifdef GALLIUM_CELL +/** + * SPE instruction types + * + * There are 6 primary instruction encodings used on the Cell's SPEs. Each of + * the following unions encodes one type. + * + * \bug + * If, at some point, we start generating SPE code from a little-endian host + * these unions will not work. + */ +/*@{*/ +/** + * Encode one output register with two input registers + */ +union spe_inst_RR { + uint32_t bits; + struct { + unsigned op:11; + unsigned rB:7; + unsigned rA:7; + unsigned rT:7; + } inst; +}; + + +/** + * Encode one output register with three input registers + */ +union spe_inst_RRR { + uint32_t bits; + struct { + unsigned op:4; + unsigned rT:7; + unsigned rB:7; + unsigned rA:7; + unsigned rC:7; + } inst; +}; + + +/** + * Encode one output register with one input reg. and a 7-bit signed immed + */ +union spe_inst_RI7 { + uint32_t bits; + struct { + unsigned op:11; + unsigned i7:7; + unsigned rA:7; + unsigned rT:7; + } inst; +}; + + +/** + * Encode one output register with one input reg. and an 8-bit signed immed + */ +union spe_inst_RI8 { + uint32_t bits; + struct { + unsigned op:10; + unsigned i8:8; + unsigned rA:7; + unsigned rT:7; + } inst; +}; + + +/** + * Encode one output register with one input reg. and a 10-bit signed immed + */ +union spe_inst_RI10 { + uint32_t bits; + struct { + unsigned op:8; + unsigned i10:10; + unsigned rA:7; + unsigned rT:7; + } inst; +}; + + +/** + * Encode one output register with a 16-bit signed immediate + */ +union spe_inst_RI16 { + uint32_t bits; + struct { + unsigned op:9; + unsigned i16:16; + unsigned rT:7; + } inst; +}; + + +/** + * Encode one output register with a 18-bit signed immediate + */ +union spe_inst_RI18 { + uint32_t bits; + struct { + unsigned op:7; + unsigned i18:18; + unsigned rT:7; + } inst; +}; +/*@}*/ + + +static void emit_RR(struct spe_function *p, unsigned op, unsigned rT, + unsigned rA, unsigned rB) +{ + union spe_inst_RR inst; + inst.inst.op = op; + inst.inst.rB = rB; + inst.inst.rA = rA; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + +static void emit_RRR(struct spe_function *p, unsigned op, unsigned rT, + unsigned rA, unsigned rB, unsigned rC) +{ + union spe_inst_RRR inst; + inst.inst.op = op; + inst.inst.rT = rT; + inst.inst.rB = rB; + inst.inst.rA = rA; + inst.inst.rC = rC; + *p->csr = inst.bits; + p->csr++; +} + + +static void emit_RI7(struct spe_function *p, unsigned op, unsigned rT, + unsigned rA, int imm) +{ + union spe_inst_RI7 inst; + inst.inst.op = op; + inst.inst.i7 = imm; + inst.inst.rA = rA; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + + +static void emit_RI8(struct spe_function *p, unsigned op, unsigned rT, + unsigned rA, int imm) +{ + union spe_inst_RI8 inst; + inst.inst.op = op; + inst.inst.i8 = imm; + inst.inst.rA = rA; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + + +static void emit_RI10(struct spe_function *p, unsigned op, unsigned rT, + unsigned rA, int imm) +{ + union spe_inst_RI10 inst; + inst.inst.op = op; + inst.inst.i10 = imm; + inst.inst.rA = rA; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + +static void emit_RI16(struct spe_function *p, unsigned op, unsigned rT, + int imm) +{ + union spe_inst_RI16 inst; + inst.inst.op = op; + inst.inst.i16 = imm; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + +static void emit_RI18(struct spe_function *p, unsigned op, unsigned rT, + int imm) +{ + union spe_inst_RI18 inst; + inst.inst.op = op; + inst.inst.i18 = imm; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + + + +#define EMIT_(_name, _op) \ +void _name (struct spe_function *p, unsigned rT) \ +{ \ + emit_RR(p, _op, rT, 0, 0); \ +} + +#define EMIT_R(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA) \ +{ \ + emit_RR(p, _op, rT, rA, 0); \ +} + +#define EMIT_RR(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB) \ +{ \ + emit_RR(p, _op, rT, rA, rB); \ +} + +#define EMIT_RRR(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB, unsigned rC) \ +{ \ + emit_RRR(p, _op, rT, rA, rB, rC); \ +} + +#define EMIT_RI7(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \ +{ \ + emit_RI7(p, _op, rT, rA, imm); \ +} + +#define EMIT_RI8(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \ +{ \ + emit_RI8(p, _op, rT, rA, 155 - imm); \ +} + +#define EMIT_RI10(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \ +{ \ + emit_RI10(p, _op, rT, rA, imm); \ +} + +#define EMIT_RI16(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, int imm) \ +{ \ + emit_RI16(p, _op, rT, imm); \ +} + +#define EMIT_RI18(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, int imm) \ +{ \ + emit_RI18(p, _op, rT, imm); \ +} + +#define EMIT_I16(_name, _op) \ +void _name (struct spe_function *p, int imm) \ +{ \ + emit_RI16(p, _op, 0, imm); \ +} + +#include "rtasm_ppc_spe.h" + + +/* + */ +void spe_init_func(struct spe_function *p, unsigned code_size) +{ + p->store = align_malloc(code_size, 16); + p->csr = p->store; +} + + +void spe_release_func(struct spe_function *p) +{ + align_free(p->store); + p->store = NULL; + p->csr = NULL; +} + + +void spe_bi(struct spe_function *p, unsigned rA, int d, int e) +{ + emit_RI7(p, 0x1a8, 0, rA, (d << 5) | (e << 4)); +} + +void spe_iret(struct spe_function *p, unsigned rA, int d, int e) +{ + emit_RI7(p, 0x1aa, 0, rA, (d << 5) | (e << 4)); +} + +void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA, int d, + int e) +{ + emit_RI7(p, 0x1ab, rT, rA, (d << 5) | (e << 4)); +} + +void spe_bisl(struct spe_function *p, unsigned rT, unsigned rA, int d, + int e) +{ + emit_RI7(p, 0x1a9, rT, rA, (d << 5) | (e << 4)); +} + +void spe_biz(struct spe_function *p, unsigned rT, unsigned rA, int d, + int e) +{ + emit_RI7(p, 0x128, rT, rA, (d << 5) | (e << 4)); +} + +void spe_binz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e) +{ + emit_RI7(p, 0x129, rT, rA, (d << 5) | (e << 4)); +} + +void spe_bihz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e) +{ + emit_RI7(p, 0x12a, rT, rA, (d << 5) | (e << 4)); +} + +void spe_bihnz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e) +{ + emit_RI7(p, 0x12b, rT, rA, (d << 5) | (e << 4)); +} + + +/* Hint-for-branch instructions + */ +#if 0 +hbr; +hbra; +hbrr; +#endif + + +/* Control instructions + */ +#if 0 +stop; +EMIT_RR (spe_stopd, 0x140); +EMIT_ (spe_lnop, 0x001); +EMIT_ (spe_nop, 0x201); +sync; +EMIT_ (spe_dsync, 0x003); +EMIT_R (spe_mfspr, 0x00c); +EMIT_R (spe_mtspr, 0x10c); +#endif + +#endif /* GALLIUM_CELL */ diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h new file mode 100644 index 0000000000..10ce44b3a0 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h @@ -0,0 +1,314 @@ +/* + * (C) Copyright IBM Corporation 2008 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file + * Real-time assembly generation interface for Cell B.E. SPEs. + * + * \author Ian Romanick + */ + +#ifndef RTASM_PPC_SPE_H +#define RTASM_PPC_SPE_H + +struct spe_function { + /** + * + */ + uint32_t *store; + uint32_t *csr; + const char *fn; +}; + +extern void spe_init_func(struct spe_function *p, unsigned code_size); +extern void spe_release_func(struct spe_function *p); + +#endif /* RTASM_PPC_SPE_H */ + +#ifndef EMIT_ +#define EMIT_(name, _op) \ + extern void _name (struct spe_function *p, unsigned rT) +#define EMIT_R(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA) +#define EMIT_RR(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ + unsigned rB) +#define EMIT_RRR(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ + unsigned rB, unsigned rC) +#define EMIT_RI7(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ + int imm) +#define EMIT_RI8(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ + int imm) +#define EMIT_RI10(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ + int imm) +#define EMIT_RI16(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, int imm) +#define EMIT_RI18(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, int imm) +#define EMIT_I16(_name, _op) \ + extern void _name (struct spe_function *p, int imm) +#define UNDEF_EMIT_MACROS +#endif /* EMIT_ */ + + +/* Memory load / store instructions + */ +EMIT_RI10(spe_lqd, 0x034); +EMIT_RR (spe_lqx, 0x1c4); +EMIT_RI16(spe_lqa, 0x061); +EMIT_RI16(spe_lqr, 0x067); +EMIT_RI10(spe_stqd, 0x024); +EMIT_RR (spe_stqx, 0x144); +EMIT_RI16(spe_stqa, 0x041); +EMIT_RI16(spe_stqr, 0x047); +EMIT_RI7 (spe_cbd, 0x1f4); +EMIT_RR (spe_cbx, 0x1d4); +EMIT_RI7 (spe_chd, 0x1f5); +EMIT_RI7 (spe_chx, 0x1d5); +EMIT_RI7 (spe_cwd, 0x1f6); +EMIT_RI7 (spe_cwx, 0x1d6); +EMIT_RI7 (spe_cdd, 0x1f7); +EMIT_RI7 (spe_cdx, 0x1d7); + + +/* Constant formation instructions + */ +EMIT_RI16(spe_ilh, 0x083); +EMIT_RI16(spe_ilhu, 0x082); +EMIT_RI16(spe_il, 0x081); +EMIT_RI18(spe_ila, 0x021); +EMIT_RI16(spe_iohl, 0x0c1); +EMIT_RI16(spe_fsmbi, 0x0c5); + + +/* Integer and logical instructions + */ +EMIT_RR (spe_ah, 0x0c8); +EMIT_RI10(spe_ahi, 0x01d); +EMIT_RR (spe_a, 0x0c0); +EMIT_RI10(spe_ai, 0x01c); +EMIT_RR (spe_sfh, 0x048); +EMIT_RI10(spe_sfhi, 0x00d); +EMIT_RR (spe_sf, 0x040); +EMIT_RI10(spe_sfi, 0x00c); +EMIT_RR (spe_addx, 0x340); +EMIT_RR (spe_cg, 0x0c2); +EMIT_RR (spe_cgx, 0x342); +EMIT_RR (spe_sfx, 0x341); +EMIT_RR (spe_bg, 0x042); +EMIT_RR (spe_bgx, 0x343); +EMIT_RR (spe_mpy, 0x3c4); +EMIT_RR (spe_mpyu, 0x3cc); +EMIT_RI10(spe_mpyi, 0x074); +EMIT_RI10(spe_mpyui, 0x075); +EMIT_RRR (spe_mpya, 0x00c); +EMIT_RR (spe_mpyh, 0x3c5); +EMIT_RR (spe_mpys, 0x3c7); +EMIT_RR (spe_mpyhh, 0x3c6); +EMIT_RR (spe_mpyhha, 0x346); +EMIT_RR (spe_mpyhhu, 0x3ce); +EMIT_RR (spe_mpyhhau, 0x34e); +EMIT_R (spe_clz, 0x2a5); +EMIT_R (spe_cntb, 0x2b4); +EMIT_R (spe_fsmb, 0x1b6); +EMIT_R (spe_fsmh, 0x1b5); +EMIT_R (spe_fsm, 0x1b4); +EMIT_R (spe_gbb, 0x1b2); +EMIT_R (spe_gbh, 0x1b1); +EMIT_R (spe_gb, 0x1b0); +EMIT_RR (spe_avgb, 0x0d3); +EMIT_RR (spe_absdb, 0x053); +EMIT_RR (spe_sumb, 0x253); +EMIT_R (spe_xsbh, 0x2b6); +EMIT_R (spe_xshw, 0x2ae); +EMIT_R (spe_xswd, 0x2a6); +EMIT_RR (spe_and, 0x0c1); +EMIT_RR (spe_andc, 0x2c1); +EMIT_RI10(spe_andbi, 0x016); +EMIT_RI10(spe_andhi, 0x015); +EMIT_RI10(spe_andi, 0x014); +EMIT_RR (spe_or, 0x041); +EMIT_RR (spe_orc, 0x2c9); +EMIT_RI10(spe_orbi, 0x006); +EMIT_RI10(spe_orhi, 0x005); +EMIT_RI10(spe_ori, 0x004); +EMIT_R (spe_orx, 0x1f0); +EMIT_RR (spe_xor, 0x241); +EMIT_RI10(spe_xorbi, 0x026); +EMIT_RI10(spe_xorhi, 0x025); +EMIT_RI10(spe_xori, 0x024); +EMIT_RR (spe_nand, 0x0c9); +EMIT_RR (spe_nor, 0x049); +EMIT_RR (spe_eqv, 0x249); +EMIT_RRR (spe_selb, 0x008); +EMIT_RRR (spe_shufb, 0x00b); + + +/* Shift and rotate instructions + */ +EMIT_RR (spe_shlh, 0x05f); +EMIT_RI7 (spe_shlhi, 0x07f); +EMIT_RR (spe_shl, 0x05b); +EMIT_RI7 (spe_shli, 0x07b); +EMIT_RR (spe_shlqbi, 0x1db); +EMIT_RI7 (spe_shlqbii, 0x1fb); +EMIT_RR (spe_shlqby, 0x1df); +EMIT_RI7 (spe_shlqbyi, 0x1ff); +EMIT_RR (spe_shlqbybi, 0x1cf); +EMIT_RR (spe_roth, 0x05c); +EMIT_RI7 (spe_rothi, 0x07c); +EMIT_RR (spe_rot, 0x058); +EMIT_RI7 (spe_roti, 0x078); +EMIT_RR (spe_rotqby, 0x1dc); +EMIT_RI7 (spe_rotqbyi, 0x1fc); +EMIT_RR (spe_rotqbybi, 0x1cc); +EMIT_RR (spe_rotqbi, 0x1d8); +EMIT_RI7 (spe_rotqbii, 0x1f8); +EMIT_RR (spe_rothm, 0x05d); +EMIT_RI7 (spe_rothmi, 0x07d); +EMIT_RR (spe_rotm, 0x059); +EMIT_RI7 (spe_rotmi, 0x079); +EMIT_RR (spe_rotqmby, 0x1dd); +EMIT_RI7 (spe_rotqmbyi, 0x1fd); +EMIT_RR (spe_rotqmbybi, 0x1cd); +EMIT_RR (spe_rotqmbi, 0x1c9); +EMIT_RI7 (spe_rotqmbii, 0x1f9); +EMIT_RR (spe_rotmah, 0x05e); +EMIT_RI7 (spe_rotmahi, 0x07e); +EMIT_RR (spe_rotma, 0x05a); +EMIT_RI7 (spe_rotmai, 0x07a); + + +/* Compare, branch, and halt instructions + */ +EMIT_RR (spe_heq, 0x3d8); +EMIT_RI10(spe_heqi, 0x07f); +EMIT_RR (spe_hgt, 0x258); +EMIT_RI10(spe_hgti, 0x04f); +EMIT_RR (spe_hlgt, 0x2d8); +EMIT_RI10(spe_hlgti, 0x05f); +EMIT_RR (spe_ceqb, 0x3d0); +EMIT_RI10(spe_ceqbi, 0x07e); +EMIT_RR (spe_ceqh, 0x3c8); +EMIT_RI10(spe_ceqhi, 0x07d); +EMIT_RR (spe_ceq, 0x3c0); +EMIT_RI10(spe_ceqi, 0x07c); +EMIT_RR (spe_cgtb, 0x250); +EMIT_RI10(spe_cgtbi, 0x04e); +EMIT_RR (spe_cgth, 0x248); +EMIT_RI10(spe_cgthi, 0x04d); +EMIT_RR (spe_cgt, 0x240); +EMIT_RI10(spe_cgti, 0x04c); +EMIT_RR (spe_clgtb, 0x2d0); +EMIT_RI10(spe_clgtbi, 0x05e); +EMIT_RR (spe_clgth, 0x2c8); +EMIT_RI10(spe_clgthi, 0x05d); +EMIT_RR (spe_clgt, 0x2c0); +EMIT_RI10(spe_clgti, 0x05c); +EMIT_I16 (spe_br, 0x064); +EMIT_I16 (spe_bra, 0x060); +EMIT_RI16(spe_brsl, 0x066); +EMIT_RI16(spe_brasl, 0x062); +EMIT_RI16(spe_brnz, 0x042); +EMIT_RI16(spe_brz, 0x040); +EMIT_RI16(spe_brhnz, 0x046); +EMIT_RI16(spe_brhz, 0x044); + +extern void spe_bi(struct spe_function *p, unsigned rA, int d, int e); +extern void spe_iret(struct spe_function *p, unsigned rA, int d, int e); +extern void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); +extern void spe_bisl(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); +extern void spe_biz(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); +extern void spe_binz(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); +extern void spe_bihz(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); +extern void spe_bihnz(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); + + +/* Floating-point instructions + */ +EMIT_RR (spe_fa, 0x2c4); +EMIT_RR (spe_dfa, 0x2cc); +EMIT_RR (spe_fs, 0x2c5); +EMIT_RR (spe_dfs, 0x2cd); +EMIT_RR (spe_fm, 0x2c6); +EMIT_RR (spe_dfm, 0x2ce); +EMIT_RRR (spe_fma, 0x00e); +EMIT_RR (spe_dfma, 0x35c); +EMIT_RRR (spe_fnms, 0x00d); +EMIT_RR (spe_dfnms, 0x35e); +EMIT_RRR (spe_fms, 0x00f); +EMIT_RR (spe_dfms, 0x35d); +EMIT_RR (spe_dfnma, 0x35f); +EMIT_R (spe_frest, 0x1b8); +EMIT_R (spe_frsqest, 0x1b9); +EMIT_RR (spe_fi, 0x3d4); +EMIT_RI8 (spe_csflt, 0x1da); +EMIT_RI8 (spe_cflts, 0x1d8); +EMIT_RI8 (spe_cuflt, 0x1db); +EMIT_RI8 (spe_cfltu, 0x1d9); +EMIT_R (spe_frds, 0x3b9); +EMIT_R (spe_fesd, 0x3b8); +EMIT_RR (spe_dfceq, 0x3c3); +EMIT_RR (spe_dfcmeq, 0x3cb); +EMIT_RR (spe_dfcgt, 0x2c3); +EMIT_RR (spe_dfcmgt, 0x2cb); +EMIT_RI7 (spe_dftsv, 0x3bf); +EMIT_RR (spe_fceq, 0x3c2); +EMIT_RR (spe_fcmeq, 0x3ca); +EMIT_RR (spe_fcgt, 0x2c2); +EMIT_RR (spe_fcmgt, 0x2ca); +EMIT_R (spe_fscrwr, 0x3ba); +EMIT_ (spe_fscrrd, 0x398); + + +/* Channel instructions + */ +EMIT_R (spe_rdch, 0x00d); +EMIT_R (spe_rdchcnt, 0x00f); +EMIT_R (spe_wrch, 0x10d); + + +#ifdef UNDEF_EMIT_MACROS +#undef EMIT_ +#undef EMIT_R +#undef EMIT_RR +#undef EMIT_RRR +#undef EMIT_RI7 +#undef EMIT_RI8 +#undef EMIT_RI10 +#undef EMIT_RI16 +#undef EMIT_RI18 +#undef EMIT_I16 +#undef UNDEF_EMIT_MACROS +#endif /* EMIT_ */ diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 91f8e542a2..3b687bb868 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -36,7 +36,7 @@ #include "draw/draw_vbuf.h" #include "cell_winsys.h" #include "cell/common.h" -#include "ppc/rtasm/spe_asm.h" +#include "rtasm/rtasm_ppc_spe.h" struct cell_vbuf_render; diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c index f10689a959..9cf74bab47 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c @@ -31,7 +31,7 @@ #include "../auxiliary/draw/draw_private.h" #include "cell_context.h" -#include "ppc/rtasm/spe_asm.h" +#include "rtasm/rtasm_ppc_spe.h" typedef uint64_t register_mask; -- cgit v1.2.3 From b9da3791c934e05b82063a8c79c423a0a8e29a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 15:07:53 +0900 Subject: Remove src/mesa and src/mesa/main from gallium source include paths. --- src/gallium/Makefile.template | 2 - src/gallium/auxiliary/draw/draw_vf_sse.c | 3 +- src/gallium/auxiliary/pipebuffer/linked_list.h | 91 ------ .../auxiliary/pipebuffer/pb_buffer_fenced.c | 3 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 3 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 3 +- src/gallium/auxiliary/util/u_double_list.h | 91 ++++++ src/gallium/auxiliary/util/u_simple_list.h | 197 +++++++++++++ src/gallium/drivers/i915simple/i915_debug.c | 2 - src/gallium/include/pipe/p_thread.h | 327 +++++++++++++++++++-- src/gallium/winsys/dri/intel/SConscript | 2 +- src/gallium/winsys/dri/intel/intel_batchpool.c | 15 +- src/gallium/winsys/xlib/SConscript | 6 + src/gallium/winsys/xlib/brw_aub.c | 16 +- 14 files changed, 612 insertions(+), 149 deletions(-) delete mode 100644 src/gallium/auxiliary/pipebuffer/linked_list.h create mode 100644 src/gallium/auxiliary/util/u_double_list.h create mode 100644 src/gallium/auxiliary/util/u_simple_list.h (limited to 'src/gallium') diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 6698212e77..4e462b5c97 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -18,8 +18,6 @@ INCLUDES = \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/main \ -I$(TOP)/include \ $(DRIVER_INCLUDES) diff --git a/src/gallium/auxiliary/draw/draw_vf_sse.c b/src/gallium/auxiliary/draw/draw_vf_sse.c index 6076f9849d..aff4ffd985 100644 --- a/src/gallium/auxiliary/draw/draw_vf_sse.c +++ b/src/gallium/auxiliary/draw/draw_vf_sse.c @@ -26,9 +26,8 @@ */ -#include "simple_list.h" - #include "pipe/p_compiler.h" +#include "util/u_simple_list.h" #include "draw_vf.h" diff --git a/src/gallium/auxiliary/pipebuffer/linked_list.h b/src/gallium/auxiliary/pipebuffer/linked_list.h deleted file mode 100644 index e99817fb13..0000000000 --- a/src/gallium/auxiliary/pipebuffer/linked_list.h +++ /dev/null @@ -1,91 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - **************************************************************************/ - -/** - * \file - * List macros heavily inspired by the Linux kernel - * list handling. No list looping yet. - * - * Is not threadsafe, so common operations need to - * be protected using an external mutex. - */ - -#ifndef LINKED_LIST_H_ -#define LINKED_LIST_H_ - - -#include - - -struct list_head -{ - struct list_head *prev; - struct list_head *next; -}; - - -#define LIST_INITHEAD(__item) \ - do { \ - (__item)->prev = (__item); \ - (__item)->next = (__item); \ - } while (0) - -#define LIST_ADD(__item, __list) \ - do { \ - (__item)->prev = (__list); \ - (__item)->next = (__list)->next; \ - (__list)->next->prev = (__item); \ - (__list)->next = (__item); \ - } while (0) - -#define LIST_ADDTAIL(__item, __list) \ - do { \ - (__item)->next = (__list); \ - (__item)->prev = (__list)->prev; \ - (__list)->prev->next = (__item); \ - (__list)->prev = (__item); \ - } while(0) - -#define LIST_DEL(__item) \ - do { \ - (__item)->prev->next = (__item)->next; \ - (__item)->next->prev = (__item)->prev; \ - } while(0) - -#define LIST_DELINIT(__item) \ - do { \ - (__item)->prev->next = (__item)->next; \ - (__item)->next->prev = (__item)->prev; \ - (__item)->next = (__item); \ - (__item)->prev = (__item); \ - } while(0) - -#define LIST_ENTRY(__type, __item, __field) \ - ((__type *)(((char *)(__item)) - offsetof(__type, __field))) - - -#endif /*LINKED_LIST_H_*/ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index bc85c4b19f..e2ee72ed1f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -34,13 +34,12 @@ */ -#include "linked_list.h" - #include "pipe/p_compiler.h" #include "pipe/p_debug.h" #include "pipe/p_winsys.h" #include "pipe/p_thread.h" #include "pipe/p_util.h" +#include "util/u_double_list.h" #include "pb_buffer.h" #include "pb_buffer_fenced.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 983a105347..ff4fd123f3 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -33,12 +33,11 @@ */ -#include "linked_list.h" - #include "pipe/p_defines.h" #include "pipe/p_debug.h" #include "pipe/p_thread.h" #include "pipe/p_util.h" +#include "util/u_double_list.h" #include "util/u_mm.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index beb145b7cb..528e9528f6 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -35,13 +35,12 @@ */ -#include "linked_list.h" - #include "pipe/p_compiler.h" #include "pipe/p_debug.h" #include "pipe/p_thread.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "util/u_double_list.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/auxiliary/util/u_double_list.h b/src/gallium/auxiliary/util/u_double_list.h new file mode 100644 index 0000000000..8cb10c9820 --- /dev/null +++ b/src/gallium/auxiliary/util/u_double_list.h @@ -0,0 +1,91 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + +/** + * \file + * List macros heavily inspired by the Linux kernel + * list handling. No list looping yet. + * + * Is not threadsafe, so common operations need to + * be protected using an external mutex. + */ + +#ifndef _U_DOUBLE_LIST_H_ +#define _U_DOUBLE_LIST_H_ + + +#include + + +struct list_head +{ + struct list_head *prev; + struct list_head *next; +}; + + +#define LIST_INITHEAD(__item) \ + do { \ + (__item)->prev = (__item); \ + (__item)->next = (__item); \ + } while (0) + +#define LIST_ADD(__item, __list) \ + do { \ + (__item)->prev = (__list); \ + (__item)->next = (__list)->next; \ + (__list)->next->prev = (__item); \ + (__list)->next = (__item); \ + } while (0) + +#define LIST_ADDTAIL(__item, __list) \ + do { \ + (__item)->next = (__list); \ + (__item)->prev = (__list)->prev; \ + (__list)->prev->next = (__item); \ + (__list)->prev = (__item); \ + } while(0) + +#define LIST_DEL(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + } while(0) + +#define LIST_DELINIT(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + (__item)->next = (__item); \ + (__item)->prev = (__item); \ + } while(0) + +#define LIST_ENTRY(__type, __item, __field) \ + ((__type *)(((char *)(__item)) - offsetof(__type, __field))) + + +#endif /*_U_DOUBLE_LIST_H_*/ diff --git a/src/gallium/auxiliary/util/u_simple_list.h b/src/gallium/auxiliary/util/u_simple_list.h new file mode 100644 index 0000000000..f5f43b0faa --- /dev/null +++ b/src/gallium/auxiliary/util/u_simple_list.h @@ -0,0 +1,197 @@ +/** + * \file simple_list.h + * Simple macros for type-safe, intrusive lists. + * + * Intended to work with a list sentinal which is created as an empty + * list. Insert & delete are O(1). + * + * \author + * (C) 1997, Keith Whitwell + */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef _U_SIMPLE_LIST_H_ +#define _U_SIMPLE_LIST_H_ + +/** + * Remove an element from list. + * + * \param elem element to remove. + */ +#define remove_from_list(elem) \ +do { \ + (elem)->next->prev = (elem)->prev; \ + (elem)->prev->next = (elem)->next; \ +} while (0) + +/** + * Insert an element to the list head. + * + * \param list list. + * \param elem element to insert. + */ +#define insert_at_head(list, elem) \ +do { \ + (elem)->prev = list; \ + (elem)->next = (list)->next; \ + (list)->next->prev = elem; \ + (list)->next = elem; \ +} while(0) + +/** + * Insert an element to the list tail. + * + * \param list list. + * \param elem element to insert. + */ +#define insert_at_tail(list, elem) \ +do { \ + (elem)->next = list; \ + (elem)->prev = (list)->prev; \ + (list)->prev->next = elem; \ + (list)->prev = elem; \ +} while(0) + +/** + * Move an element to the list head. + * + * \param list list. + * \param elem element to move. + */ +#define move_to_head(list, elem) \ +do { \ + remove_from_list(elem); \ + insert_at_head(list, elem); \ +} while (0) + +/** + * Move an element to the list tail. + * + * \param list list. + * \param elem element to move. + */ +#define move_to_tail(list, elem) \ +do { \ + remove_from_list(elem); \ + insert_at_tail(list, elem); \ +} while (0) + +/** + * Make a empty list empty. + * + * \param sentinal list (sentinal element). + */ +#define make_empty_list(sentinal) \ +do { \ + (sentinal)->next = sentinal; \ + (sentinal)->prev = sentinal; \ +} while (0) + +/** + * Get list first element. + * + * \param list list. + * + * \return pointer to first element. + */ +#define first_elem(list) ((list)->next) + +/** + * Get list last element. + * + * \param list list. + * + * \return pointer to last element. + */ +#define last_elem(list) ((list)->prev) + +/** + * Get next element. + * + * \param elem element. + * + * \return pointer to next element. + */ +#define next_elem(elem) ((elem)->next) + +/** + * Get previous element. + * + * \param elem element. + * + * \return pointer to previous element. + */ +#define prev_elem(elem) ((elem)->prev) + +/** + * Test whether element is at end of the list. + * + * \param list list. + * \param elem element. + * + * \return non-zero if element is at end of list, or zero otherwise. + */ +#define at_end(list, elem) ((elem) == (list)) + +/** + * Test if a list is empty. + * + * \param list list. + * + * \return non-zero if list empty, or zero otherwise. + */ +#define is_empty_list(list) ((list)->next == (list)) + +/** + * Walk through the elements of a list. + * + * \param ptr pointer to the current element. + * \param list list. + * + * \note It should be followed by a { } block or a single statement, as in a \c + * for loop. + */ +#define foreach(ptr, list) \ + for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next ) + +/** + * Walk through the elements of a list. + * + * Same as #foreach but lets you unlink the current value during a list + * traversal. Useful for freeing a list, element by element. + * + * \param ptr pointer to the current element. + * \param t temporary pointer. + * \param list list. + * + * \note It should be followed by a { } block or a single statement, as in a \c + * for loop. + */ +#define foreach_s(ptr, t, list) \ + for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next) + +#endif /* _U_SIMPLE_LIST_H_ */ diff --git a/src/gallium/drivers/i915simple/i915_debug.c b/src/gallium/drivers/i915simple/i915_debug.c index 94db44e1aa..78102dbac2 100644 --- a/src/gallium/drivers/i915simple/i915_debug.c +++ b/src/gallium/drivers/i915simple/i915_debug.c @@ -25,8 +25,6 @@ * **************************************************************************/ -//#include "imports.h" - #include "i915_reg.h" #include "i915_context.h" #include "i915_winsys.h" diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/include/pipe/p_thread.h index cd432c547c..4325abc951 100644 --- a/src/gallium/include/pipe/p_thread.h +++ b/src/gallium/include/pipe/p_thread.h @@ -1,54 +1,317 @@ /************************************************************************** * + * Copyright 1999-2006 Brian Paul * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ -#ifndef P_THREAD_H -#define P_THREAD_H +/** + * @file + * Thread + * + * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) + * and Christoph Poliwoda (poliwoda@volumegraphics.com) + * Revised by Keith Whitwell + * Adapted for new gl dispatcher by Brian Paul + * + * + * + * DOCUMENTATION + * + * This thread module exports the following types: + * _glthread_TSD Thread-specific data area + * _glthread_Thread Thread datatype + * _glthread_Mutex Mutual exclusion lock + * + * Macros: + * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex + * _glthread_INIT_MUTEX(name) Initialize a mutex + * _glthread_LOCK_MUTEX(name) Lock a mutex + * _glthread_UNLOCK_MUTEX(name) Unlock a mutex + * + * Functions: + * _glthread_GetID(v) Get integer thread ID + * _glthread_InitTSD() Initialize thread-specific data + * _glthread_GetTSD() Get thread-specific data + * _glthread_SetTSD() Set thread-specific data + * + * If this file is accidentally included by a non-threaded build, + * it should not cause the build to fail, or otherwise cause problems. + * In general, it should only be included when needed however. + */ + +#ifndef _P_THREAD_H_ +#define _P_THREAD_H_ + + +#if defined(USE_MGL_NAMESPACE) +#define _glapi_Dispatch _mglapi_Dispatch +#endif + + + +#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ + defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ + && !defined(THREADS) +# define THREADS +#endif + +#ifdef VMS +#include +#endif + +/* + * POSIX threads. This should be your choice in the Unix world + * whenever possible. When building with POSIX threads, be sure + * to enable any compiler flags which will cause the MT-safe + * libc (if one exists) to be used when linking, as well as any + * header macros for MT-safe errno, etc. For Solaris, this is the -mt + * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable + * proper compiling for MT-safe libc etc. + */ +#if defined(PTHREADS) +#include /* POSIX threads headers */ + +typedef struct { + pthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef pthread_t _glthread_Thread; + +typedef pthread_mutex_t _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER + +#define _glthread_INIT_MUTEX(name) \ + pthread_mutex_init(&(name), NULL) + +#define _glthread_DESTROY_MUTEX(name) \ + pthread_mutex_destroy(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) pthread_mutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) pthread_mutex_unlock(&(name)) + +#endif /* PTHREADS */ + + + + +/* + * Solaris threads. Use only up to Solaris 2.4. + * Solaris 2.5 and higher provide POSIX threads. + * Be sure to compile with -mt on the Solaris compilers, or + * use -D_REENTRANT if using gcc. + */ +#ifdef SOLARIS_THREADS +#include + +typedef struct { + thread_key_t key; + mutex_t keylock; + int initMagic; +} _glthread_TSD; + +typedef thread_t _glthread_Thread; + +typedef mutex_t _glthread_Mutex; + +/* XXX need to really implement mutex-related macros */ +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 +#define _glthread_INIT_MUTEX(name) (void) name +#define _glthread_DESTROY_MUTEX(name) (void) name +#define _glthread_LOCK_MUTEX(name) (void) name +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* SOLARIS_THREADS */ + + + + +/* + * Windows threads. Should work with Windows NT and 95. + * IMPORTANT: Link with multithreaded runtime library when THREADS are + * used! + */ +#ifdef WIN32_THREADS +#include + +typedef struct { + DWORD key; + int initMagic; +} _glthread_TSD; + +typedef HANDLE _glthread_Thread; + +typedef CRITICAL_SECTION _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) /*static*/ _glthread_Mutex name = {0,0,0,0,0,0} +#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name) +#define _glthread_DESTROY_MUTEX(name) DeleteCriticalSection(&name) +#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name) +#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name) + +#endif /* WIN32_THREADS */ + + -#include "p_compiler.h" /* - * XXX: We should come up with a system-independent thread definitions. - * XXX: Patching glthread defs for now. + * XFree86 has its own thread wrapper, Xthreads.h + * We wrap it again for GL. */ +#ifdef USE_XTHREADS +#include + +typedef struct { + xthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef xthread_t _glthread_Thread; + +typedef xmutex_rec _glthread_Mutex; + +#ifdef XMUTEX_INITIALIZER +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = XMUTEX_INITIALIZER +#else +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name +#endif + +#define _glthread_INIT_MUTEX(name) \ + xmutex_init(&(name)) + +#define _glthread_DESTROY_MUTEX(name) \ + xmutex_clear(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) xmutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) xmutex_unlock(&(name)) + +#endif /* USE_XTHREADS */ + + + +/* + * BeOS threads. R5.x required. + */ +#ifdef BEOS_THREADS + +#include +#include + +typedef struct { + int32 key; + int initMagic; +} _glthread_TSD; + +typedef thread_id _glthread_Thread; + +/* Use Benaphore, aka speeder semaphore */ +typedef struct { + int32 lock; + sem_id sem; +} benaphore; +typedef benaphore _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = { 0, 0 } +#define _glthread_INIT_MUTEX(name) name.sem = create_sem(0, #name"_benaphore"), name.lock = 0 +#define _glthread_DESTROY_MUTEX(name) delete_sem(name.sem), name.lock = 0 +#define _glthread_LOCK_MUTEX(name) if (name.sem == 0) _glthread_INIT_MUTEX(name); \ + if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem) +#define _glthread_UNLOCK_MUTEX(name) if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem) + +#endif /* BEOS_THREADS */ + + + +#ifndef THREADS + +/* + * THREADS not defined + */ + +typedef unsigned _glthread_TSD; + +typedef unsigned _glthread_Thread; + +typedef unsigned _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 + +#define _glthread_INIT_MUTEX(name) (void) name + +#define _glthread_DESTROY_MUTEX(name) (void) name + +#define _glthread_LOCK_MUTEX(name) (void) name + +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* THREADS */ + + + +/* + * Platform independent thread specific data API. + */ + +extern unsigned long +_glthread_GetID(void); + + +extern void +_glthread_InitTSD(_glthread_TSD *); + + +extern void * +_glthread_GetTSD(_glthread_TSD *); -#ifndef __MSC__ -#include "glapi/glthread.h" +extern void +_glthread_SetTSD(_glthread_TSD *, void *); -#else /* __MSC__ */ +#if defined(GLX_USE_TLS) -typedef int _glthread_Mutex; +extern __thread struct _glapi_table * _glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))); -#define _glthread_INIT_MUTEX( M ) ((void) (M)) -#define _glthread_LOCK_MUTEX( M ) ((void) (M)) -#define _glthread_UNLOCK_MUTEX( M ) ((void) (M)) +#define GET_DISPATCH() _glapi_tls_Dispatch -#define sched_yield() ((void) 0) +#elif !defined(GL_CALL) +# if defined(THREADS) +# define GET_DISPATCH() \ + ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ + ? _glapi_Dispatch : _glapi_get_dispatch()) +# else +# define GET_DISPATCH() _glapi_Dispatch +# endif /* defined(THREADS) */ +#endif /* ndef GL_CALL */ -#endif /* __MSC__ */ -#endif /* P_THREAD_H */ +#endif /* _P_THREAD_H_ */ diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index 525ba580e8..0ad19d42a8 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -35,5 +35,5 @@ drivers = [ env.SharedLibrary( target ='i915tex_dri.so', source = sources, - LIBS = mesa + drivers + auxiliaries + env['LIBS'], + LIBS = drivers + mesa + auxiliaries + env['LIBS'], ) \ No newline at end of file diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.c b/src/gallium/winsys/dri/intel/intel_batchpool.c index 33b56817f6..ce154c7b88 100644 --- a/src/gallium/winsys/dri/intel/intel_batchpool.c +++ b/src/gallium/winsys/dri/intel/intel_batchpool.c @@ -36,9 +36,12 @@ #include #include +#include #include -#include "imports.h" -#include "glthread.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_thread.h" + #include "dri_bufpool.h" #include "dri_bufmgr.h" #include "intel_batchpool.h" @@ -196,7 +199,7 @@ pool_create(struct _DriBufferPool *pool, _glthread_LOCK_MUTEX(p->mutex); if (p->numFree == 0) - pool_checkFree(p, GL_TRUE); + pool_checkFree(p, TRUE); if (p->numFree == 0) { fprintf(stderr, "Out of fixed size buffer objects\n"); @@ -278,7 +281,7 @@ pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, return -EBUSY; } - buf->mapped = GL_TRUE; + buf->mapped = TRUE; *virtual = (unsigned char *) p->virtual + buf->start; _glthread_UNLOCK_MUTEX(p->mutex); return 0; @@ -361,7 +364,7 @@ pool_validate(struct _DriBufferPool *pool, void *private) BBuf *buf = (BBuf *) private; BPool *p = buf->parent; _glthread_LOCK_MUTEX(p->mutex); - buf->unfenced = GL_TRUE; + buf->unfenced = TRUE; _glthread_UNLOCK_MUTEX(p->mutex); return 0; } @@ -379,7 +382,7 @@ pool_takedown(struct _DriBufferPool *pool) while ((p->numFree < p->numTot) && p->numDelayed) { _glthread_UNLOCK_MUTEX(p->mutex); sched_yield(); - pool_checkFree(p, GL_TRUE); + pool_checkFree(p, TRUE); _glthread_LOCK_MUTEX(p->mutex); } diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index f8aa5ef945..c38b5be52c 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -3,6 +3,12 @@ Import('*') +env = env.Clone() + +env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', +]) sources = [ 'glxapi.c', diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index 541d50c6e4..10eedd8402 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -29,11 +29,13 @@ * Keith Whitwell */ +#include +#include #include "brw_aub.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "imports.h" -//#include "intel_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" struct brw_aubfile { @@ -350,9 +352,9 @@ struct brw_aubfile *brw_aubfile_create( void ) i++; - if (_mesa_getenv("INTEL_AUBFILE")) { - val = snprintf(filename, sizeof(filename), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i%4); - _mesa_printf("--> Aub file: %s\n", filename); + if (getenv("INTEL_AUBFILE")) { + val = snprintf(filename, sizeof(filename), "%s%d.aub", getenv("INTEL_AUBFILE"), i%4); + debug_printf("--> Aub file: %s\n", filename); aubfile->file = fopen(filename, "w"); } else { @@ -360,12 +362,12 @@ struct brw_aubfile *brw_aubfile_create( void ) if (val < 0 || val > sizeof(filename)) strcpy(filename, "default.aub"); - _mesa_printf("--> Aub file: %s\n", filename); + debug_printf("--> Aub file: %s\n", filename); aubfile->file = fopen(filename, "w"); } if (!aubfile->file) { - _mesa_printf("couldn't open aubfile\n"); + debug_printf("couldn't open aubfile\n"); exit(1); } -- cgit v1.2.3 From b62f0ddd09f8ef9c400feca321412b3f0bc77e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 18:56:55 +0900 Subject: Portability fixes. Eliminate C99/C++ constructs. (We should actually disable gcc C99 syntax options if we are serious about portability.) --- src/gallium/auxiliary/cso_cache/cso_hash.c | 35 ++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index 0338cb3b47..b40217c524 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -158,11 +158,14 @@ static void cso_data_rehash(struct cso_hash_data *hash, int hint) while (firstNode != e) { unsigned h = firstNode->key; struct cso_node *lastNode = firstNode; + struct cso_node *afterLastNode; + struct cso_node **beforeFirstNode; + while (lastNode->next != e && lastNode->next->key == h) lastNode = lastNode->next; - struct cso_node *afterLastNode = lastNode->next; - struct cso_node **beforeFirstNode = &hash->buckets[h % hash->numBuckets]; + afterLastNode = lastNode->next; + beforeFirstNode = &hash->buckets[h % hash->numBuckets]; while (*beforeFirstNode != e) beforeFirstNode = &(*beforeFirstNode)->next; lastNode->next = *beforeFirstNode; @@ -222,10 +225,12 @@ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, { cso_data_might_grow(hash->data.d); - struct cso_node **nextNode = cso_hash_find_node(hash, key); - struct cso_node *node = cso_hash_create_node(hash, key, data, nextNode); - struct cso_hash_iter iter = {hash, node}; - return iter; + { + struct cso_node **nextNode = cso_hash_find_node(hash, key); + struct cso_node *node = cso_hash_create_node(hash, key, data, nextNode); + struct cso_hash_iter iter = {hash, node}; + return iter; + } } struct cso_hash * cso_hash_create(void) @@ -290,6 +295,10 @@ static struct cso_node *cso_hash_data_next(struct cso_node *node) struct cso_node *e; struct cso_hash_data *d; } a; + int start; + struct cso_node **bucket; + int n; + a.next = node->next; if (!a.next) { fprintf(stderr, "iterating beyond the last element\n"); @@ -298,9 +307,9 @@ static struct cso_node *cso_hash_data_next(struct cso_node *node) if (a.next->next) return a.next; - int start = (node->key % a.d->numBuckets) + 1; - struct cso_node **bucket = a.d->buckets + start; - int n = a.d->numBuckets - start; + start = (node->key % a.d->numBuckets) + 1; + bucket = a.d->buckets + start; + n = a.d->numBuckets - start; while (n--) { if (*bucket != a.e) return *bucket; @@ -316,19 +325,21 @@ static struct cso_node *cso_hash_data_prev(struct cso_node *node) struct cso_node *e; struct cso_hash_data *d; } a; + int start; + struct cso_node *sentinel; + struct cso_node **bucket; a.e = node; while (a.e->next) a.e = a.e->next; - int start; if (node == a.e) start = a.d->numBuckets - 1; else start = node->key % a.d->numBuckets; - struct cso_node *sentinel = node; - struct cso_node **bucket = a.d->buckets + start; + sentinel = node; + bucket = a.d->buckets + start; while (start >= 0) { if (*bucket != sentinel) { struct cso_node *prev = *bucket; -- cgit v1.2.3 From 5480a6bc13a555f99a89fc801cfe153182697dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Feb 2008 18:57:25 +0900 Subject: Fix windows build. --- src/gallium/auxiliary/rtasm/rtasm_execmem.c | 3 ++- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 2 +- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c index 9c78fa5626..300c1c2d9d 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c @@ -33,6 +33,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_debug.h" #include "pipe/p_thread.h" +#include "pipe/p_util.h" #include "rtasm_execmem.h" @@ -118,7 +119,7 @@ rtasm_exec_free(void *addr) */ void * -rtasm_exec_malloc(GLuint size) +rtasm_exec_malloc(size_t size) { return MALLOC( size ); } diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index b332192a62..dcbf76f600 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -21,7 +21,7 @@ * **************************************************************************/ -#if defined(__i386__) || defined(__386__) +#if defined(__i386__) || defined(__386__) || defined(i386) #include "pipe/p_compiler.h" #include "pipe/p_debug.h" diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index e4576001bf..606b41eb35 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -24,7 +24,7 @@ #ifndef _RTASM_X86SSE_H_ #define _RTASM_X86SSE_H_ -#if defined(__i386__) || defined(__386__) +#if defined(__i386__) || defined(__386__) || defined(i386) /* It is up to the caller to ensure that instructions issued are * suitable for the host cpu. There are no checks made in this module -- cgit v1.2.3 From 4362c6e59d575a039e654e1520bbff89b73fc8f2 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 18 Feb 2008 18:51:57 -0800 Subject: Cell: trivial clean-ups --- src/gallium/drivers/cell/spu/spu_exec.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 109540b1f7..0eb5ea1a3f 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -146,17 +146,13 @@ spu_exec_machine_init(struct spu_exec_machine *mach, struct spu_sampler *samplers, unsigned processor) { - qword zero; - qword not_zero; - uint i; + const qword zero = si_il(0); + const qword not_zero = si_il(~0); mach->Samplers = samplers; mach->Processor = processor; mach->Addrs = &mach->Temps[TGSI_EXEC_NUM_TEMPS]; - zero = si_xor(zero, zero); - not_zero = si_xori(zero, 0xff); - /* Setup constants. */ mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].q = zero; mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].q = not_zero; -- cgit v1.2.3 From 66be2810c3be07dd1ee45a60cfc632725837f2cd Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 18 Feb 2008 18:55:39 -0800 Subject: Cell: emit vertex shaders and uniforms more intelligently --- src/gallium/drivers/cell/common.h | 22 ++++---- src/gallium/drivers/cell/ppu/cell_state_emit.c | 18 ++++++ src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 17 +++--- src/gallium/drivers/cell/spu/spu_main.c | 9 +++ src/gallium/drivers/cell/spu/spu_vertex_fetch.c | 6 +- src/gallium/drivers/cell/spu/spu_vertex_shader.c | 68 ++++++++++------------- src/gallium/drivers/cell/spu/spu_vertex_shader.h | 5 ++ 7 files changed, 85 insertions(+), 60 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index 74b131fbef..cf892206c6 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -87,10 +87,12 @@ #define CELL_CMD_STATE_TEXTURE 13 #define CELL_CMD_STATE_VERTEX_INFO 14 #define CELL_CMD_STATE_VIEWPORT 15 -#define CELL_CMD_STATE_VS_ARRAY_INFO 16 -#define CELL_CMD_STATE_BLEND 17 -#define CELL_CMD_VS_EXECUTE 18 -#define CELL_CMD_STATE_ATTRIB_FETCH 19 +#define CELL_CMD_STATE_UNIFORMS 16 +#define CELL_CMD_STATE_VS_ARRAY_INFO 17 +#define CELL_CMD_STATE_BIND_VS 18 +#define CELL_CMD_STATE_BLEND 19 +#define CELL_CMD_STATE_ATTRIB_FETCH 20 +#define CELL_CMD_VS_EXECUTE 21 #define CELL_NUM_BUFFERS 4 @@ -144,14 +146,13 @@ struct cell_attribute_fetch_code { struct cell_shader_info { - unsigned num_outputs; - uint64_t declarations; - unsigned num_declarations; uint64_t instructions; - unsigned num_instructions; - uint64_t uniforms; uint64_t immediates; + + unsigned num_outputs; + unsigned num_declarations; + unsigned num_instructions; unsigned num_immediates; } ALIGN16_ATTRIB; @@ -160,10 +161,9 @@ struct cell_shader_info struct cell_command_vs { uint64_t opcode; /**< CELL_CMD_VS_EXECUTE */ - struct cell_shader_info shader; + uint64_t vOut[SPU_VERTS_PER_BATCH]; unsigned num_elts; unsigned elts[SPU_VERTS_PER_BATCH]; - uint64_t vOut[SPU_VERTS_PER_BATCH]; float plane[12][4]; unsigned nr_planes; unsigned nr_attrs; diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 5d2a786449..49c0d130c5 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -31,6 +31,8 @@ #include "cell_state_emit.h" #include "cell_batch.h" #include "cell_texture.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" static void @@ -100,4 +102,20 @@ cell_emit_state(struct cell_context *cell) emit_state_cmd(cell, CELL_CMD_STATE_VERTEX_INFO, &cell->vertex_info, sizeof(struct vertex_info)); } + + if (cell->dirty & CELL_NEW_VS) { + const struct draw_context *const draw = cell->draw; + struct cell_shader_info info; + + info.num_outputs = draw->num_vs_outputs; + info.declarations = (uintptr_t) draw->machine.Declarations; + info.num_declarations = draw->machine.NumDeclarations; + info.instructions = (uintptr_t) draw->machine.Instructions; + info.num_instructions = draw->machine.NumInstructions; + info.immediates = (uintptr_t) draw->machine.Imms; + info.num_immediates = draw->machine.ImmLimit / 4; + + emit_state_cmd(cell, CELL_CMD_STATE_BIND_VS, + & info, sizeof(info)); + } } diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index 6a1d3bc20a..64c7821c19 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -54,6 +54,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) struct cell_command_vs *const vs = &cell_global.command[0].vs; uint64_t *batch; struct cell_array_info *array_info; + struct cell_shader_info *shader_info; unsigned i, j; struct cell_attribute_fetch_code *cf; @@ -100,17 +101,17 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) (void) memcpy(&batch[1], &draw->viewport, sizeof(struct pipe_viewport_state)); + { + uint64_t uniforms = (uintptr_t) draw->user.constants; + + batch = cell_batch_alloc(cell, 2 *sizeof(batch[0])); + batch[0] = CELL_CMD_STATE_UNIFORMS; + batch[1] = uniforms; + } + cell_batch_flush(cell); vs->opcode = CELL_CMD_VS_EXECUTE; - vs->shader.num_outputs = draw->num_vs_outputs; - vs->shader.declarations = (uintptr_t) draw->machine.Declarations; - vs->shader.num_declarations = draw->machine.NumDeclarations; - vs->shader.instructions = (uintptr_t) draw->machine.Instructions; - vs->shader.num_instructions = draw->machine.NumInstructions; - vs->shader.uniforms = (uintptr_t) draw->user.constants; - vs->shader.immediates = (uintptr_t) draw->machine.Imms; - vs->shader.num_immediates = draw->machine.ImmLimit / 4; vs->nr_attrs = draw->vertex_fetch.nr_attrs; (void) memcpy(vs->plane, draw->plane, sizeof(draw->plane)); diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index fcbf0f841e..dbc3705c24 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -433,10 +433,19 @@ cmd_batch(uint opcode) sizeof(struct pipe_viewport_state)); pos += (1 + ROUNDUP8(sizeof(struct pipe_viewport_state)) / 8); break; + case CELL_CMD_STATE_UNIFORMS: + draw.constants = (float (*)[4]) (uintptr_t) buffer[pos + 1]; + pos += 2; + break; case CELL_CMD_STATE_VS_ARRAY_INFO: cmd_state_vs_array_info((struct cell_array_info *) &buffer[pos+1]); pos += (1 + ROUNDUP8(sizeof(struct cell_array_info)) / 8); break; + case CELL_CMD_STATE_BIND_VS: + spu_bind_vertex_shader(&draw, + (struct cell_shader_info *) &buffer[pos+1]); + pos += (1 + ROUNDUP8(sizeof(struct cell_shader_info)) / 8); + break; case CELL_CMD_STATE_ATTRIB_FETCH: { struct cell_attribute_fetch_code *code = (struct cell_attribute_fetch_code *) &buffer[pos+1]; diff --git a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c index 55c6c28717..e5d9910ff3 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c @@ -64,7 +64,7 @@ typedef void (*spu_fetch_func)(qword *out, const qword *in, const qword *shuffle_data); -static const qword fetch_shuffle_data[] = { +static const qword fetch_shuffle_data[5] ALIGN16_ATTRIB = { /* Shuffle used by CVT_64_FLOAT */ { @@ -108,7 +108,7 @@ static const qword fetch_shuffle_data[] = { static INLINE void fetch_unaligned(qword *dst, unsigned ea, unsigned size) { - qword tmp[4]; + qword tmp[4] ALIGN16_ATTRIB; const int shift = ea & 0x0f; const unsigned aligned_start_ea = ea & ~0x0f; const unsigned aligned_end_ea = (ea + size) & ~0x0f; @@ -169,7 +169,7 @@ static void generic_vertex_fetch(struct spu_vs_context *draw, unsigned idx; const unsigned bytes_per_entry = draw->vertex_fetch.size[attr]; const unsigned quads_per_entry = (bytes_per_entry + 15) / 16; - qword in[2 * 4]; + qword in[2 * 4] ALIGN16_ATTRIB; /* Fetch four attributes for four vertices. diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c index 3f5bf41aa2..8363efeeb6 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c @@ -165,63 +165,55 @@ run_vertex_program(struct spu_vs_context *draw, } -static void -spu_bind_vertex_shader(struct spu_vs_context *draw, - void *uniforms, - void *planes, - unsigned nr_planes, - unsigned num_outputs - ) -{ - draw->constants = (float (*)[4]) uniforms; - - (void) memcpy(draw->plane, planes, sizeof(float) * 4 * nr_planes); - draw->nr_planes = nr_planes; - draw->num_vs_outputs = num_outputs; - - /* specify the shader to interpret/execute */ - spu_exec_machine_init(&draw->machine, - PIPE_MAX_SAMPLERS, - NULL /*samplers*/, - PIPE_SHADER_VERTEX); -} - - unsigned char immediates[(sizeof(float) * 4 * TGSI_EXEC_NUM_IMMEDIATES) + 32] ALIGN16_ATTRIB; + void -spu_execute_vertex_shader(struct spu_vs_context *draw, - const struct cell_command_vs *vs) +spu_bind_vertex_shader(struct spu_vs_context *draw, + struct cell_shader_info *vs) { - unsigned i; - - const uint64_t immediate_addr = vs->shader.immediates; + const unsigned immediate_addr = vs->immediates; const unsigned immediate_size = - ROUNDUP16((sizeof(float) * 4 * vs->shader.num_immediates) - + (immediate_addr & 0x0f)); + ROUNDUP16((sizeof(float) * 4 * vs->num_immediates) + + (immediate_addr & 0x0f)); + mfc_get(immediates, immediate_addr & ~0x0f, immediate_size, TAG_VERTEX_BUFFER, 0, 0); draw->machine.Instructions = (struct tgsi_full_instruction *) - vs->shader.instructions; - draw->machine.NumInstructions = vs->shader.num_instructions; + vs->instructions; + draw->machine.NumInstructions = vs->num_instructions; draw->machine.Declarations = (struct tgsi_full_declaration *) - vs->shader.declarations; - draw->machine.NumDeclarations = vs->shader.num_declarations; + vs->declarations; + draw->machine.NumDeclarations = vs->num_declarations; - draw->vertex_fetch.nr_attrs = vs->nr_attrs; + draw->num_vs_outputs = vs->num_outputs; + + /* specify the shader to interpret/execute */ + spu_exec_machine_init(&draw->machine, + PIPE_MAX_SAMPLERS, + NULL /*samplers*/, + PIPE_SHADER_VERTEX); wait_on_mask(1 << TAG_VERTEX_BUFFER); (void) memcpy(& draw->machine.Imms, &immediates[immediate_addr & 0x0f], - sizeof(float) * 4 * vs->shader.num_immediates); + sizeof(float) * 4 * vs->num_immediates); +} - spu_bind_vertex_shader(draw, vs->shader.uniforms, - vs->plane, vs->nr_planes, - vs->shader.num_outputs); + +void +spu_execute_vertex_shader(struct spu_vs_context *draw, + const struct cell_command_vs *vs) +{ + unsigned i; + + (void) memcpy(draw->plane, vs->plane, sizeof(float) * 4 * vs->nr_planes); + draw->nr_planes = vs->nr_planes; + draw->vertex_fetch.nr_attrs = vs->nr_attrs; for (i = 0; i < vs->num_elts; i += 4) { const unsigned batch_size = MIN2(vs->num_elts - i, 4); diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.h b/src/gallium/drivers/cell/spu/spu_vertex_shader.h index 0fb0bc28d0..54a4b8d9b9 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.h +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.h @@ -1,6 +1,7 @@ #ifndef SPU_VERTEX_SHADER_H #define SPU_VERTEX_SHADER_H +#include "cell/common.h" #include "pipe/p_format.h" #include "spu_exec.h" @@ -54,6 +55,10 @@ static INLINE void spu_vertex_fetch(struct spu_vs_context *draw, struct cell_command_vs; +extern void +spu_bind_vertex_shader(struct spu_vs_context *draw, + struct cell_shader_info *vs); + extern void spu_execute_vertex_shader(struct spu_vs_context *draw, const struct cell_command_vs *vs); -- cgit v1.2.3 From 3e329ea7e41e8d97de5b5f345ecab0833c8afe70 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 11:14:54 -0700 Subject: gallium: updated cell build Building on Ian's Cell build fix. Put libcell.a in the gallium/drivers/cell/ directory. General Makefile clean-up, simplification, updated comments. --- src/gallium/drivers/cell/ppu/Makefile | 12 ++++++++---- src/gallium/winsys/xlib/Makefile | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index 196ab777f5..3c3f622a2f 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -1,6 +1,6 @@ # Gallium3D Cell driver: PPU code -# This makefile builds the g3dcell.a library which gets pulled into +# This makefile builds the libcell.a library which gets pulled into # the main libGL.so library @@ -8,10 +8,14 @@ TOP = ../../../../.. include $(TOP)/configs/linux-cell -#PROG = gl4 +# This is the "top-level" cell PPU driver code, will get pulled into libGL.so +# by the winsys Makefile. +CELL_LIB = ../libcell.a -CELL_LIB = libcell.a +# This is the SPU code. We'd like to be able to put this into the libcell.a +# archive with the PPU code, but nesting .a libs doesn't seem to work. +# So, it's pulled into libGL.so in gallium/winsys/xlib/Makefile SPU_CODE_MODULE = ../spu/g3d_spu.a @@ -56,7 +60,7 @@ default: $(CELL_LIB) $(CELL_LIB): $(OBJECTS) $(SPU_CODE_MODULE) -# ar -ru $(CELL_LIB) $(OBJECTS) $(SPU_CODE_MODULE) +# ar -ru $(CELL_LIB) $(OBJECTS) $(SPU_CODE_MODULE) # doesn't work ar -ru $(CELL_LIB) $(OBJECTS) #$(PROG): $(PPU_OBJECTS) diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 17405388ee..09f10e5ea8 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -1,4 +1,4 @@ -# src/mesa/Makefile +# src/gallium/winsys/xlib/Makefile TOP = ../../../.. include $(TOP)/configs/current @@ -27,16 +27,17 @@ GL_MINOR = 5 GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) +ifeq ($(CONFIG_NAME), linux-cell) +# The SPU code is in a separate .a file, unfortunately +CELL_SPU_LIB = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a +endif + PIPE_LIB = \ $(GALLIUM_DRIVERS) \ $(TOP)/src/mesa/libglapi.a \ $(TOP)/src/mesa/libmesa.a \ - $(GALLIUM_AUXILIARIES) - -ifeq ($(CONFIG_NAME), linux-cell) -CELL_LIB = $(TOP)/src/gallium/drivers/cell/ppu/libcell.a -CELL_LIB_SPU = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a -endif + $(GALLIUM_AUXILIARIES) \ + $(CELL_SPU_LIB) \ .SUFFIXES : .cpp @@ -65,13 +66,13 @@ STAND_ALONE_OBJECTS = \ $(STAND_ALONE_DRIVER_OBJECTS) # Make the GL library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ - --start-group $(PIPE_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) + --start-group $(PIPE_LIB) --end-group $(GL_LIB_DEPS) ###################################################################### -- cgit v1.2.3 From b1c8fa5b6002296d9abe21c06d5cb81a3f70828a Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 14:55:18 -0700 Subject: gallium: implement correct sampling for RECT targets / unnormalized texcoords --- src/gallium/drivers/softpipe/sp_tex_sample.c | 168 +++++++++++++++++++++++---- 1 file changed, 143 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index c54e9d385c..ff872f360e 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -332,6 +332,61 @@ linear_texcoord(unsigned wrapMode, float s, unsigned size, } +/** + * For RECT textures / unnormalized texcoords + * Only a subset of wrap modes supported. + */ +static INLINE int +nearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size) +{ + int i; + switch (wrapMode) { + case PIPE_TEX_WRAP_CLAMP: + i = ifloor(s); + return CLAMP(i, 0, size-1); + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + /* fall-through */ + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return ifloor( CLAMP(s, 0.5F, size - 0.5F) ); + default: + assert(0); + return 0; + } +} + + +/** + * For RECT textures / unnormalized texcoords. + * Only a subset of wrap modes supported. + */ +static INLINE void +linear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size, + int *i0, int *i1, float *a) +{ + switch (wrapMode) { + case PIPE_TEX_WRAP_CLAMP: + /* Not exactly what the spec says, but it matches NVIDIA output */ + s = CLAMP(s - 0.5F, 0.0, size - 1.0); + *i0 = ifloor(s); + *i1 = *i0 + 1; + break; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + /* fall-through */ + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + s = CLAMP(s, 0.5F, size - 0.5F); + s -= 0.5F; + *i0 = ifloor(s); + *i1 = *i0 + 1; + if (*i1 > size - 1) + *i1 = size - 1; + break; + default: + assert(0); + } + *a = FRAC(s); +} + + static unsigned choose_cube_face(float rx, float ry, float rz, float *newS, float *newT) { @@ -415,15 +470,15 @@ compute_lambda(struct tgsi_sampler *sampler, { float rho, lambda; + assert(sampler->state->normalized_coords); + assert(s); { float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; dsdx = FABSF(dsdx); dsdy = FABSF(dsdy); - rho = MAX2(dsdx, dsdy); - if (sampler->state->normalized_coords) - rho *= sampler->texture->width[0]; + rho = MAX2(dsdx, dsdy) * sampler->texture->width[0]; } if (t) { float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; @@ -431,9 +486,7 @@ compute_lambda(struct tgsi_sampler *sampler, float max; dtdx = FABSF(dtdx); dtdy = FABSF(dtdy); - max = MAX2(dtdx, dtdy); - if (sampler->state->normalized_coords) - max *= sampler->texture->height[0]; + max = MAX2(dtdx, dtdy) * sampler->texture->height[0]; rho = MAX2(rho, max); } if (p) { @@ -442,9 +495,7 @@ compute_lambda(struct tgsi_sampler *sampler, float max; dpdx = FABSF(dpdx); dpdy = FABSF(dpdy); - max = MAX2(dpdx, dpdy); - if (sampler->state->normalized_coords) - max *= sampler->texture->depth[0]; + max = MAX2(dpdx, dpdy) * sampler->texture->depth[0]; rho = MAX2(rho, max); } @@ -628,13 +679,10 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler, choose_mipmap_levels(sampler, s, t, p, lodbias, &level0, &level1, &levelBlend, &imgFilter); - if (sampler->state->normalized_coords) { - width = sampler->texture->width[level0]; - height = sampler->texture->height[level0]; - } - else { - width = height = 1; - } + assert(sampler->state->normalized_coords); + + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; assert(width > 0); @@ -765,14 +813,11 @@ sp_get_samples_3d(struct tgsi_sampler *sampler, choose_mipmap_levels(sampler, s, t, p, lodbias, &level0, &level1, &levelBlend, &imgFilter); - if (sampler->state->normalized_coords) { - width = sampler->texture->width[level0]; - height = sampler->texture->height[level0]; - depth = sampler->texture->depth[level0]; - } - else { - width = height = depth = 1; - } + assert(sampler->state->normalized_coords); + + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; + depth = sampler->texture->depth[level0]; assert(width > 0); assert(height > 0); @@ -889,6 +934,73 @@ sp_get_samples_cube(struct tgsi_sampler *sampler, } +static void +sp_get_samples_rect(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + //sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); + static const uint face = 0; + const uint compare_func = sampler->state->compare_func; + unsigned level0, level1, j, imgFilter; + int width, height; + float levelBlend; + + choose_mipmap_levels(sampler, s, t, p, lodbias, + &level0, &level1, &levelBlend, &imgFilter); + + /* texture RECTS cannot be mipmapped */ + assert(level0 == level1); + + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; + + assert(width > 0); + + switch (imgFilter) { + case PIPE_TEX_FILTER_NEAREST: + for (j = 0; j < QUAD_SIZE; j++) { + int x = nearest_texcoord_unnorm(sampler->state->wrap_s, s[j], width); + int y = nearest_texcoord_unnorm(sampler->state->wrap_t, t[j], height); + get_texel(sampler, face, level0, x, y, 0, rgba, j); + if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + shadow_compare(compare_func, rgba, p, j); + } + } + break; + case PIPE_TEX_FILTER_LINEAR: + for (j = 0; j < QUAD_SIZE; j++) { + float tx[4][4], a, b; + int x0, y0, x1, y1, c; + linear_texcoord_unnorm(sampler->state->wrap_s, s[j], width, &x0, &x1, &a); + linear_texcoord_unnorm(sampler->state->wrap_t, t[j], height, &y0, &y1, &b); + get_texel(sampler, face, level0, x0, y0, 0, tx, 0); + get_texel(sampler, face, level0, x1, y0, 0, tx, 1); + get_texel(sampler, face, level0, x0, y1, 0, tx, 2); + get_texel(sampler, face, level0, x1, y1, 0, tx, 3); + if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + shadow_compare(compare_func, tx, p, 0); + shadow_compare(compare_func, tx, p, 1); + shadow_compare(compare_func, tx, p, 2); + shadow_compare(compare_func, tx, p, 3); + } + + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]); + } + } + break; + default: + assert(0); + } +} + + + + /** * Called via tgsi_sampler::get_samples() * Use the sampler's state setting to get a filtered RGBA value @@ -914,15 +1026,21 @@ sp_get_samples(struct tgsi_sampler *sampler, switch (sampler->texture->target) { case PIPE_TEXTURE_1D: + assert(sampler->state->normalized_coords); sp_get_samples_1d(sampler, s, t, p, lodbias, rgba); break; case PIPE_TEXTURE_2D: - sp_get_samples_2d(sampler, s, t, p, lodbias, rgba); + if (sampler->state->normalized_coords) + sp_get_samples_2d(sampler, s, t, p, lodbias, rgba); + else + sp_get_samples_rect(sampler, s, t, p, lodbias, rgba); break; case PIPE_TEXTURE_3D: + assert(sampler->state->normalized_coords); sp_get_samples_3d(sampler, s, t, p, lodbias, rgba); break; case PIPE_TEXTURE_CUBE: + assert(sampler->state->normalized_coords); sp_get_samples_cube(sampler, s, t, p, lodbias, rgba); break; default: -- cgit v1.2.3 From a2c06c5b5c8b3fb9f6d65bcd288d62e112e6a603 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 14:56:01 -0700 Subject: gallium: don't hard-code attrib slot=0 in setup_fragcoord_coeff() --- src/gallium/drivers/softpipe/sp_prim_setup.c | 41 ++++++++++++---------------- 1 file changed, 18 insertions(+), 23 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index d73521ccbe..7b1e131ee1 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -476,33 +476,33 @@ static void tri_persp_coeff( struct setup_stage *setup, * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. */ static void -setup_fragcoord_coeff(struct setup_stage *setup) +setup_fragcoord_coeff(struct setup_stage *setup, uint slot) { /*X*/ - setup->coef[0].a0[0] = 0; - setup->coef[0].dadx[0] = 1.0; - setup->coef[0].dady[0] = 0.0; + setup->coef[slot].a0[0] = 0; + setup->coef[slot].dadx[0] = 1.0; + setup->coef[slot].dady[0] = 0.0; /*Y*/ if (setup->softpipe->rasterizer->origin_lower_left) { /* y=0=bottom */ const int winHeight = setup->softpipe->framebuffer.cbufs[0]->height; - setup->coef[0].a0[1] = (float) (winHeight - 1); - setup->coef[0].dady[1] = -1.0; + setup->coef[slot].a0[1] = (float) (winHeight - 1); + setup->coef[slot].dady[1] = -1.0; } else { /* y=0=top */ - setup->coef[0].a0[1] = 0.0; - setup->coef[0].dady[1] = 1.0; + setup->coef[slot].a0[1] = 0.0; + setup->coef[slot].dady[1] = 1.0; } - setup->coef[0].dadx[1] = 0.0; + setup->coef[slot].dadx[1] = 0.0; /*Z*/ - setup->coef[0].a0[2] = setup->posCoef.a0[2]; - setup->coef[0].dadx[2] = setup->posCoef.dadx[2]; - setup->coef[0].dady[2] = setup->posCoef.dady[2]; + setup->coef[slot].a0[2] = setup->posCoef.a0[2]; + setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; + setup->coef[slot].dady[2] = setup->posCoef.dady[2]; /*W*/ - setup->coef[0].a0[3] = setup->posCoef.a0[3]; - setup->coef[0].dadx[3] = setup->posCoef.dadx[3]; - setup->coef[0].dady[3] = setup->posCoef.dady[3]; + setup->coef[slot].a0[3] = setup->posCoef.a0[3]; + setup->coef[slot].dadx[3] = setup->posCoef.dadx[3]; + setup->coef[slot].dady[3] = setup->posCoef.dady[3]; } @@ -543,8 +543,7 @@ static void setup_tri_coefficients( struct setup_stage *setup ) tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_POS: - assert(fragSlot == 0); - setup_fragcoord_coeff(setup); + setup_fragcoord_coeff(setup, fragSlot); break; default: assert(0); @@ -798,9 +797,7 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim) line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_POS: - assert(fragSlot == 0); - assert(0); /* XXX fix this: */ - setup_fragcoord_coeff(setup); + setup_fragcoord_coeff(setup, fragSlot); break; default: assert(0); @@ -1022,9 +1019,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim) &setup->coef[fragSlot], vertSlot, j); break; case INTERP_POS: - assert(fragSlot == 0); - assert(0); /* XXX fix this: */ - setup_fragcoord_coeff(setup); + setup_fragcoord_coeff(setup, fragSlot); break; default: assert(0); -- cgit v1.2.3 From 4ec46e4869b60b60c7ddf43168604713b5c4c359 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 14:58:23 -0700 Subject: gallium: add some casts to prevent likely msvc warnings --- src/gallium/drivers/softpipe/sp_tex_sample.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index ff872f360e..43d5085895 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -347,7 +347,7 @@ nearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size) case PIPE_TEX_WRAP_CLAMP_TO_EDGE: /* fall-through */ case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - return ifloor( CLAMP(s, 0.5F, size - 0.5F) ); + return ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) ); default: assert(0); return 0; @@ -366,14 +366,14 @@ linear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size, switch (wrapMode) { case PIPE_TEX_WRAP_CLAMP: /* Not exactly what the spec says, but it matches NVIDIA output */ - s = CLAMP(s - 0.5F, 0.0, size - 1.0); + s = CLAMP(s - 0.5F, 0.0, (float) size - 1.0); *i0 = ifloor(s); *i1 = *i0 + 1; break; case PIPE_TEX_WRAP_CLAMP_TO_EDGE: /* fall-through */ case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - s = CLAMP(s, 0.5F, size - 0.5F); + s = CLAMP(s, 0.5F, (float) size - 0.5F); s -= 0.5F; *i0 = ifloor(s); *i1 = *i0 + 1; -- cgit v1.2.3 From 75a4524f2c6444b27055e539da052827670b62cf Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 16:28:25 -0700 Subject: gallium: initialize the killmask register to zero before running shader This fixes mysterious missing fragments when running with SSE. --- src/gallium/drivers/softpipe/sp_fs_sse.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index b18772f4e6..53050b7823 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -124,6 +124,9 @@ fs_sse_run( struct sp_fragment_shader *base, (float)quad->x0, (float)quad->y0, machine->Temps); + /* init kill mask */ + machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0] = 0x0; + shader->func( machine->Inputs, machine->Outputs, machine->Consts, -- cgit v1.2.3 From 49c3f3b537cdad847eaa24f90d01c4b1f604f724 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 16:51:19 -0700 Subject: gallium: general clean-up of xlib winsys Makefile --- src/gallium/winsys/xlib/Makefile | 41 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 09f10e5ea8..c443330942 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -4,6 +4,11 @@ TOP = ../../../.. include $(TOP)/configs/current +GL_MAJOR = 1 +GL_MINOR = 5 +GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) + + INCLUDE_DIRS = \ -I$(TOP)/include \ -I$(TOP)/src/mesa \ @@ -12,7 +17,7 @@ INCLUDE_DIRS = \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/gallium/auxiliary -X11_DRIVER_SOURCES = \ +XLIB_WINSYS_SOURCES = \ glxapi.c \ fakeglx.c \ xfonts.c \ @@ -21,10 +26,7 @@ X11_DRIVER_SOURCES = \ xm_winsys_aub.c \ brw_aub.c - -GL_MAJOR = 1 -GL_MINOR = 5 -GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) +XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o) ifeq ($(CONFIG_NAME), linux-cell) @@ -32,7 +34,7 @@ ifeq ($(CONFIG_NAME), linux-cell) CELL_SPU_LIB = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a endif -PIPE_LIB = \ +LIBS = \ $(GALLIUM_DRIVERS) \ $(TOP)/src/mesa/libglapi.a \ $(TOP)/src/mesa/libmesa.a \ @@ -48,35 +50,20 @@ PIPE_LIB = \ .cpp.o: $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@ -.S.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) -###################################################################### -# Stand-alone Mesa libGL and libOSMesa -STAND_ALONE_DRIVER_SOURCES = \ - $(X11_DRIVER_SOURCES) - -STAND_ALONE_DRIVER_OBJECTS = $(STAND_ALONE_DRIVER_SOURCES:.c=.o) - -STAND_ALONE_OBJECTS = \ - $(STAND_ALONE_DRIVER_OBJECTS) - -# Make the GL library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) +# Make the libGL.so library +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ - $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ - --start-group $(PIPE_LIB) --end-group $(GL_LIB_DEPS) - + $(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \ + --start-group $(LIBS) --end-group $(GL_LIB_DEPS) -###################################################################### -# Generic stuff depend: $(ALL_SOURCES) @ echo "running $(MKDEP)" @@ -94,10 +81,6 @@ install: default $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \ fi -## NOT INSTALLED YET: -## $(INSTALL) -d $(INSTALL_DIR)/include/GLES -## $(INSTALL) -m 644 include/GLES/*.h $(INSTALL_DIR)/include/GLES - # Emacs tags tags: -- cgit v1.2.3 From 22a0b85eaebf767f5b03bf899596e09f5cc03876 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 11:15:59 -0700 Subject: gallium: use pipe_texture_reference() in sp_tile_cache_set_texture() --- src/gallium/drivers/softpipe/sp_state_sampler.c | 2 +- src/gallium/drivers/softpipe/sp_tile_cache.c | 5 +++-- src/gallium/drivers/softpipe/sp_tile_cache.h | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 460adccec4..9246915e19 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -84,7 +84,7 @@ softpipe_set_sampler_texture(struct pipe_context *pipe, assert(unit < PIPE_MAX_SAMPLERS); softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */ - sp_tile_cache_set_texture(softpipe->tex_cache[unit], texture); + sp_tile_cache_set_texture(pipe, softpipe->tex_cache[unit], texture); softpipe->dirty |= SP_NEW_TEXTURE; } diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index dde3fabc81..9ed3c5072d 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -212,14 +212,15 @@ sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc) * Specify the texture to cache. */ void -sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, +sp_tile_cache_set_texture(struct pipe_context *pipe, + struct softpipe_tile_cache *tc, struct pipe_texture *texture) { uint i; assert(!tc->surface); - tc->texture = texture; + pipe_texture_reference(pipe, &tc->texture, texture); if (tc->tex_surf_map) { pipe_surface_unmap(tc->tex_surf); diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 7fd1081286..2631e29a3a 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -80,7 +80,8 @@ extern void sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc); extern void -sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, +sp_tile_cache_set_texture(struct pipe_context *pipe, + struct softpipe_tile_cache *tc, struct pipe_texture *texture); extern void -- cgit v1.2.3 From d5640a2dbdc4454d0405f2cd5b18fc49b1ca7694 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 13:24:52 -0700 Subject: gallium: new pipe->texture_update() function Called whenever texture data is changed (glTexImage, glTexSubImage, glCopyTexSubImage, etc). --- src/gallium/drivers/cell/ppu/cell_context.c | 1 + src/gallium/drivers/cell/ppu/cell_texture.c | 8 +++++ src/gallium/drivers/cell/ppu/cell_texture.h | 3 ++ src/gallium/drivers/failover/fo_context.c | 9 +++-- src/gallium/drivers/i915simple/i915_context.c | 1 + src/gallium/drivers/i915simple/i915_texture.c | 7 ++++ src/gallium/drivers/i915simple/i915_texture.h | 4 +++ src/gallium/drivers/i965simple/brw_context.c | 1 + src/gallium/drivers/i965simple/brw_tex_layout.c | 8 +++++ src/gallium/drivers/i965simple/brw_tex_layout.h | 3 ++ src/gallium/drivers/softpipe/sp_context.c | 1 + src/gallium/drivers/softpipe/sp_texture.c | 15 +++++++++ src/gallium/drivers/softpipe/sp_texture.h | 4 +++ src/gallium/drivers/softpipe/sp_tile_cache.c | 45 ++++++++++++++----------- src/gallium/include/pipe/p_context.h | 8 +++++ 15 files changed, 94 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index e1eb22f468..b6ba14578c 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -244,6 +244,7 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) /* textures */ cell->pipe.texture_create = cell_texture_create; cell->pipe.texture_release = cell_texture_release; + cell->pipe.texture_update = cell_texture_update; cell->pipe.get_tex_surface = cell_get_tex_surface; cell->pipe.set_sampler_texture = cell_set_sampler_texture; diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index c8ef36002f..4629eb1320 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -128,6 +128,14 @@ cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } +void +cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +{ + /* XXX TO DO: re-tile the texture data ... */ + +} + + /** * Called via pipe->get_tex_surface() */ diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h index 0264fed88e..07e81582f4 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.h +++ b/src/gallium/drivers/cell/ppu/cell_texture.h @@ -67,6 +67,9 @@ cell_texture_create(struct pipe_context *pipe, extern void cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); +extern void +cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); + extern struct pipe_surface * cell_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index 7ce4a7df17..156f7399b0 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -137,15 +137,14 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover_init_state_functions( failover ); -#if 0 - failover->pipe.surface_alloc = hw->surface_alloc; -#endif - failover->pipe.get_tex_surface = hw->get_tex_surface; - failover->pipe.surface_copy = hw->surface_copy; failover->pipe.surface_fill = hw->surface_fill; + failover->pipe.texture_create = hw->texture_create; failover->pipe.texture_release = hw->texture_release; + failover->pipe.texture_update = hw->texture_update; + failover->pipe.get_tex_surface = hw->get_tex_surface; + failover->pipe.flush = hw->flush; failover->dirty = 0; diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 7f71f8fd4f..97773f1256 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -302,6 +302,7 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, i915->pipe.texture_create = i915_texture_create; i915->pipe.texture_release = i915_texture_release; + i915->pipe.texture_update = i915_texture_update; i915->dirty = ~0; i915->hardware_dirty = ~0; diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 6d37ae3d74..4ba76d19ad 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -534,3 +534,10 @@ i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } *pt = NULL; } + + +void +i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +{ + /* no-op? */ +} diff --git a/src/gallium/drivers/i915simple/i915_texture.h b/src/gallium/drivers/i915simple/i915_texture.h index 330d111dc7..0312977552 100644 --- a/src/gallium/drivers/i915simple/i915_texture.h +++ b/src/gallium/drivers/i915simple/i915_texture.h @@ -14,4 +14,8 @@ extern void i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); +extern void +i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); + + #endif /* I915_TEXTURE_H */ diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index 5e58701e91..2e2380a8d6 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -224,6 +224,7 @@ struct pipe_context *brw_create(struct pipe_winsys *pipe_winsys, brw->pipe.clear = brw_clear; brw->pipe.texture_create = brw_texture_create; brw->pipe.texture_release = brw_texture_release; + brw->pipe.texture_update = brw_texture_update; brw_init_surface_functions(brw); brw_init_state_functions(brw); diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 90561f1307..220591da9a 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -351,3 +351,11 @@ brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } *pt = NULL; } + + +void +brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +{ + /* no-op? */ +} + diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.h b/src/gallium/drivers/i965simple/brw_tex_layout.h index cfd6b1ef3a..7d118d0fa8 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.h +++ b/src/gallium/drivers/i965simple/brw_tex_layout.h @@ -12,4 +12,7 @@ brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat extern void brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); +extern void +brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); + #endif diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 254c6adca4..316020cba6 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -283,6 +283,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, /* textures */ softpipe->pipe.texture_create = softpipe_texture_create; softpipe->pipe.texture_release = softpipe_texture_release; + softpipe->pipe.texture_update = softpipe_texture_update; softpipe->pipe.get_tex_surface = softpipe_get_tex_surface; /* diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 6de7a9b543..8f31f05e47 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -39,6 +39,7 @@ #include "sp_context.h" #include "sp_state.h" #include "sp_texture.h" +#include "sp_tile_cache.h" /* Simple, maximally packed layout. @@ -128,6 +129,20 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } +void +softpipe_texture_update(struct pipe_context *pipe, + struct pipe_texture *texture) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint unit; + for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { + if (softpipe->texture[unit] == texture) { + sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); + } + } +} + + /** * Called via pipe->get_tex_surface() */ diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index fa646c0de9..50fc100427 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -62,6 +62,10 @@ softpipe_texture_create(struct pipe_context *pipe, extern void softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); +extern void +softpipe_texture_update(struct pipe_context *pipe, + struct pipe_texture *texture); + extern struct pipe_surface * softpipe_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 9ed3c5072d..da30dd6c48 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -359,30 +359,37 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, struct pipe_surface *ps = tc->surface; int inuse = 0, pos; - if (!ps || !ps->buffer) - return; - - for (pos = 0; pos < NUM_ENTRIES; pos++) { - struct softpipe_cached_tile *tile = tc->entries + pos; - if (tile->x >= 0) { - if (tc->depth_stencil) { - pipe_put_tile_raw(pipe, ps, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, - tile->data.depth32, 0/*STRIDE*/); - } - else { - pipe_put_tile_rgba(pipe, ps, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, - (float *) tile->data.color); + if (ps && ps->buffer) { + /* caching a drawing surface */ + for (pos = 0; pos < NUM_ENTRIES; pos++) { + struct softpipe_cached_tile *tile = tc->entries + pos; + if (tile->x >= 0) { + if (tc->depth_stencil) { + pipe_put_tile_raw(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->data.depth32, 0/*STRIDE*/); + } + else { + pipe_put_tile_rgba(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); + } + tile->x = tile->y = -1; /* mark as empty */ + inuse++; } - tile->x = tile->y = -1; /* mark as empty */ - inuse++; } - } #if TILE_CLEAR_OPTIMIZATION - sp_tile_cache_flush_clear(&softpipe->pipe, tc); + sp_tile_cache_flush_clear(&softpipe->pipe, tc); #endif + } + else if (tc->texture) { + /* caching a texture, mark all entries as embpy */ + for (pos = 0; pos < NUM_ENTRIES; pos++) { + tc->entries[pos].x = -1; + } + tc->tex_face = -1; + } #if 0 debug_printf("flushed tiles in use: %d\n", inuse); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 39f95695fb..036c4c8964 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -206,6 +206,14 @@ struct pipe_context { void (*texture_release)(struct pipe_context *pipe, struct pipe_texture **pt); + /** + * Called when texture data is changed. + * Note: we could pass some hints about which mip levels or cube faces + * have changed... + */ + void (*texture_update)(struct pipe_context *pipe, + struct pipe_texture *texture); + /** Get a surface which is a "view" into a texture */ struct pipe_surface *(*get_tex_surface)(struct pipe_context *pipe, struct pipe_texture *texture, -- cgit v1.2.3 From 882a4b505484a50f1ccc2cf3ae0c3a52d4ec1be3 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:00:42 -0700 Subject: gallium: minor re-org of 915 surface/texture code --- src/gallium/drivers/i915simple/i915_context.c | 4 +- src/gallium/drivers/i915simple/i915_surface.c | 45 +-------------------- src/gallium/drivers/i915simple/i915_texture.c | 58 +++++++++++++++++++++++++-- src/gallium/drivers/i915simple/i915_texture.h | 37 ++++++++++++----- 4 files changed, 84 insertions(+), 60 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 97773f1256..acfa349439 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -296,13 +296,11 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, i915_init_state_functions(i915); i915_init_flush_functions(i915); i915_init_string_functions(i915); + i915_init_texture_functions(i915); i915->pci_id = pci_id; i915->flags.is_i945 = is_i945; - i915->pipe.texture_create = i915_texture_create; - i915->pipe.texture_release = i915_texture_release; - i915->pipe.texture_update = i915_texture_update; i915->dirty = ~0; i915->hardware_dirty = ~0; diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index 17fd27895a..f4fbedbe9b 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -36,48 +36,6 @@ #include "util/p_tile.h" -/* - * XXX note: same as code in sp_surface.c - */ -static struct pipe_surface * -i915_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct i915_texture *tex = (struct i915_texture *)pt; - struct pipe_surface *ps; - unsigned offset; /* in bytes */ - - offset = tex->level_offset[level]; - - if (pt->target == PIPE_TEXTURE_CUBE) { - offset += tex->image_offset[level][face] * pt->cpp; - } - else if (pt->target == PIPE_TEXTURE_3D) { - offset += tex->image_offset[level][zslice] * pt->cpp; - } - else { - assert(face == 0); - assert(zslice == 0); - } - - ps = pipe->winsys->surface_alloc(pipe->winsys); - if (ps) { - assert(ps->refcount); - assert(ps->winsys); - pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); - ps->format = pt->format; - ps->cpp = pt->cpp; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - ps->pitch = tex->pitch; - ps->offset = offset; - } - return ps; -} - - - /* Assumes all values are within bounds -- no checking at this level - * do it higher up if required. */ @@ -115,6 +73,7 @@ i915_surface_copy(struct pipe_context *pipe, } } + /* Fill a rectangular sub-region. Need better logic about when to * push buffers into AGP - will currently do so whenever possible. */ @@ -184,8 +143,6 @@ i915_surface_fill(struct pipe_context *pipe, void i915_init_surface_functions(struct i915_context *i915) { - i915->pipe.get_tex_surface = i915_get_tex_surface; - i915->pipe.surface_copy = i915_surface_copy; i915->pipe.surface_fill = i915_surface_fill; } diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 4ba76d19ad..b235fae96d 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -478,7 +478,7 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) } -struct pipe_texture * +static struct pipe_texture * i915_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) { @@ -506,7 +506,7 @@ i915_texture_create(struct pipe_context *pipe, } -void +static void i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) { if (!*pt) @@ -536,8 +536,60 @@ i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } -void +static void i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) { /* no-op? */ } + + +/* + * XXX note: same as code in sp_surface.c + */ +static struct pipe_surface * +i915_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct i915_texture *tex = (struct i915_texture *)pt; + struct pipe_surface *ps; + unsigned offset; /* in bytes */ + + offset = tex->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE) { + offset += tex->image_offset[level][face] * pt->cpp; + } + else if (pt->target == PIPE_TEXTURE_3D) { + offset += tex->image_offset[level][zslice] * pt->cpp; + } + else { + assert(face == 0); + assert(zslice == 0); + } + + ps = pipe->winsys->surface_alloc(pipe->winsys); + if (ps) { + assert(ps->refcount); + assert(ps->winsys); + pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = tex->pitch; + ps->offset = offset; + } + return ps; +} + + + +void +i915_init_texture_functions(struct i915_context *i915) +{ + i915->pipe.texture_create = i915_texture_create; + i915->pipe.texture_release = i915_texture_release; + i915->pipe.texture_update = i915_texture_update; + i915->pipe.get_tex_surface = i915_get_tex_surface; +} diff --git a/src/gallium/drivers/i915simple/i915_texture.h b/src/gallium/drivers/i915simple/i915_texture.h index 0312977552..6d8d41178f 100644 --- a/src/gallium/drivers/i915simple/i915_texture.h +++ b/src/gallium/drivers/i915simple/i915_texture.h @@ -1,21 +1,38 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ #ifndef I915_TEXTURE_H #define I915_TEXTURE_H struct pipe_context; -struct pipe_texture; - - -struct pipe_texture * -i915_texture_create(struct pipe_context *pipe, - const struct pipe_texture *templat); - -extern void -i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); extern void -i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); +i915_init_texture_functions(struct i915_context *i915); #endif /* I915_TEXTURE_H */ -- cgit v1.2.3 From 4eae65c8e052976a130564560699e60e1a3a9cc3 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:04:05 -0700 Subject: gallium: re-org of i965 texture/surface code, functions --- src/gallium/drivers/i965simple/brw_context.c | 4 +- src/gallium/drivers/i965simple/brw_surface.c | 43 +----------------- src/gallium/drivers/i965simple/brw_tex_layout.c | 60 +++++++++++++++++++++++-- src/gallium/drivers/i965simple/brw_tex_layout.h | 10 +---- 4 files changed, 60 insertions(+), 57 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index 2e2380a8d6..6fb840708e 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -222,11 +222,9 @@ struct pipe_context *brw_create(struct pipe_winsys *pipe_winsys, brw->pipe.get_param = brw_get_param; brw->pipe.get_paramf = brw_get_paramf; brw->pipe.clear = brw_clear; - brw->pipe.texture_create = brw_texture_create; - brw->pipe.texture_release = brw_texture_release; - brw->pipe.texture_update = brw_texture_update; brw_init_surface_functions(brw); + brw_init_texture_functions(brw); brw_init_state_functions(brw); brw_init_flush_functions(brw); brw_init_string_functions(brw); diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index 376a42b1a6..dc4846d39f 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -35,47 +35,6 @@ #include "util/p_tile.h" -/* - * XXX note: same as code in sp_surface.c - */ -static struct pipe_surface * -brw_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct brw_texture *tex = (struct brw_texture *)pt; - struct pipe_surface *ps; - unsigned offset; /* in bytes */ - - offset = tex->level_offset[level]; - - if (pt->target == PIPE_TEXTURE_CUBE) { - offset += tex->image_offset[level][face] * pt->cpp; - } - else if (pt->target == PIPE_TEXTURE_3D) { - offset += tex->image_offset[level][zslice] * pt->cpp; - } - else { - assert(face == 0); - assert(zslice == 0); - } - - ps = pipe->winsys->surface_alloc(pipe->winsys); - if (ps) { - assert(ps->format); - assert(ps->refcount); - pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); - ps->format = pt->format; - ps->cpp = pt->cpp; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - ps->pitch = tex->pitch; - ps->offset = offset; - } - return ps; -} - - /* Upload data to a rectangular sub-region. Lots of choices how to do this: * * - memcpy by span to current destination @@ -201,10 +160,10 @@ brw_surface_fill(struct pipe_context *pipe, } } + void brw_init_surface_functions(struct brw_context *brw) { - brw->pipe.get_tex_surface = brw_get_tex_surface; brw->pipe.surface_copy = brw_surface_copy; brw->pipe.surface_fill = brw_surface_fill; } diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 220591da9a..043a2ff9a4 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -300,8 +300,9 @@ static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture } -struct pipe_texture * -brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) +static struct pipe_texture * +brw_texture_create(struct pipe_context *pipe, + const struct pipe_texture *templat) { struct brw_texture *tex = CALLOC_STRUCT(brw_texture); @@ -323,7 +324,8 @@ brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat return &tex->base; } -void + +static void brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) { if (!*pt) @@ -353,9 +355,59 @@ brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } -void +static void brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) { /* no-op? */ } + +/* + * XXX note: same as code in sp_surface.c + */ +static struct pipe_surface * +brw_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct brw_texture *tex = (struct brw_texture *)pt; + struct pipe_surface *ps; + unsigned offset; /* in bytes */ + + offset = tex->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE) { + offset += tex->image_offset[level][face] * pt->cpp; + } + else if (pt->target == PIPE_TEXTURE_3D) { + offset += tex->image_offset[level][zslice] * pt->cpp; + } + else { + assert(face == 0); + assert(zslice == 0); + } + + ps = pipe->winsys->surface_alloc(pipe->winsys); + if (ps) { + assert(ps->format); + assert(ps->refcount); + pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = tex->pitch; + ps->offset = offset; + } + return ps; +} + + +void +brw_init_texture_functions(struct brw_context *brw) +{ + brw->pipe.texture_create = brw_texture_create; + brw->pipe.texture_release = brw_texture_release; + brw->pipe.texture_update = brw_texture_update; + brw->pipe.get_tex_surface = brw_get_tex_surface; +} diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.h b/src/gallium/drivers/i965simple/brw_tex_layout.h index 7d118d0fa8..ed49baeef8 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.h +++ b/src/gallium/drivers/i965simple/brw_tex_layout.h @@ -1,18 +1,12 @@ #ifndef BRW_TEX_LAYOUT_H #define BRW_TEX_LAYOUT_H -#include "pipe/p_compiler.h" -struct pipe_context; -struct pipe_texture; +struct brw_context; -extern struct pipe_texture * -brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat); extern void -brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); +brw_init_texture_functions(struct brw_context *brw); -extern void -brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); #endif -- cgit v1.2.3 From 9171e63f414866aef155b17d3c85c9a236a872d6 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:21:45 -0700 Subject: cell: put most simple state-setter functions in new cell_pipe_state.c file Also, re-org of texture/surface functions. --- src/gallium/drivers/cell/ppu/Makefile | 6 +- src/gallium/drivers/cell/ppu/cell_context.c | 35 +-- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 323 +++++++++++++++++++++++++ src/gallium/drivers/cell/ppu/cell_pipe_state.h | 39 +++ src/gallium/drivers/cell/ppu/cell_state.h | 69 +----- src/gallium/drivers/cell/ppu/cell_texture.c | 21 +- src/gallium/drivers/cell/ppu/cell_texture.h | 20 +- 7 files changed, 389 insertions(+), 124 deletions(-) create mode 100644 src/gallium/drivers/cell/ppu/cell_pipe_state.c create mode 100644 src/gallium/drivers/cell/ppu/cell_pipe_state.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index 3c3f622a2f..6b6dfca890 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -25,14 +25,10 @@ SOURCES = \ cell_context.c \ cell_draw_arrays.c \ cell_flush.c \ - cell_state_blend.c \ - cell_state_clip.c \ cell_state_derived.c \ cell_state_emit.c \ cell_state_fs.c \ - cell_state_rasterizer.c \ - cell_state_sampler.c \ - cell_state_surface.c \ + cell_pipe_state.c \ cell_state_vertex.c \ cell_spu.c \ cell_surface.c \ diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index b6ba14578c..9f0ecb2be8 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -48,6 +48,7 @@ #include "cell_state.h" #include "cell_surface.h" #include "cell_spu.h" +#include "cell_pipe_state.h" #include "cell_texture.h" #include "cell_vbuf.h" @@ -198,22 +199,6 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) /* state setters */ - cell->pipe.create_blend_state = cell_create_blend_state; - cell->pipe.bind_blend_state = cell_bind_blend_state; - cell->pipe.delete_blend_state = cell_delete_blend_state; - - cell->pipe.create_sampler_state = cell_create_sampler_state; - cell->pipe.bind_sampler_state = cell_bind_sampler_state; - cell->pipe.delete_sampler_state = cell_delete_sampler_state; - - cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state; - cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state; - cell->pipe.delete_depth_stencil_alpha_state = cell_delete_depth_stencil_alpha_state; - - cell->pipe.create_rasterizer_state = cell_create_rasterizer_state; - cell->pipe.bind_rasterizer_state = cell_bind_rasterizer_state; - cell->pipe.delete_rasterizer_state = cell_delete_rasterizer_state; - cell->pipe.create_fs_state = cell_create_fs_state; cell->pipe.bind_fs_state = cell_bind_fs_state; cell->pipe.delete_fs_state = cell_delete_fs_state; @@ -222,16 +207,8 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) cell->pipe.bind_vs_state = cell_bind_vs_state; cell->pipe.delete_vs_state = cell_delete_vs_state; - cell->pipe.set_blend_color = cell_set_blend_color; - cell->pipe.set_clip_state = cell_set_clip_state; cell->pipe.set_constant_buffer = cell_set_constant_buffer; - cell->pipe.set_framebuffer_state = cell_set_framebuffer_state; - - cell->pipe.set_polygon_stipple = cell_set_polygon_stipple; - cell->pipe.set_scissor_state = cell_set_scissor_state; - cell->pipe.set_viewport_state = cell_set_viewport_state; - cell->pipe.set_vertex_buffer = cell_set_vertex_buffer; cell->pipe.set_vertex_element = cell_set_vertex_element; @@ -241,21 +218,15 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) cell->pipe.clear = cell_clear_surface; cell->pipe.flush = cell_flush; - /* textures */ - cell->pipe.texture_create = cell_texture_create; - cell->pipe.texture_release = cell_texture_release; - cell->pipe.texture_update = cell_texture_update; - cell->pipe.get_tex_surface = cell_get_tex_surface; - - cell->pipe.set_sampler_texture = cell_set_sampler_texture; - #if 0 cell->pipe.begin_query = cell_begin_query; cell->pipe.end_query = cell_end_query; cell->pipe.wait_query = cell_wait_query; #endif + cell_init_state_functions(cell); cell_init_surface_functions(cell); + cell_init_texture_functions(cell); cell->draw = cell_draw_create(cell); diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c new file mode 100644 index 0000000000..aef50725e8 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -0,0 +1,323 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: + * Keith Whitwell + * Brian Paul + */ + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "draw/draw_context.h" +#include "cell_context.h" +#include "cell_state.h" +#include "cell_texture.h" + + + +static void * +cell_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + return mem_dup(blend, sizeof(*blend)); +} + + +static void +cell_bind_blend_state(struct pipe_context *pipe, void *blend) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->blend = (const struct pipe_blend_state *)blend; + + cell->dirty |= CELL_NEW_BLEND; +} + + +static void +cell_delete_blend_state(struct pipe_context *pipe, void *blend) +{ + FREE(blend); +} + + +static void +cell_set_blend_color(struct pipe_context *pipe, + const struct pipe_blend_color *blend_color) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->blend_color = *blend_color; + + cell->dirty |= CELL_NEW_BLEND; +} + + + + +static void * +cell_create_depth_stencil_alpha_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + return mem_dup(depth_stencil, sizeof(*depth_stencil)); +} + + +static void +cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->depth_stencil + = (const struct pipe_depth_stencil_alpha_state *) depth_stencil; + + cell->dirty |= CELL_NEW_DEPTH_STENCIL; +} + + +static void +cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth) +{ + FREE(depth); +} + + +static void cell_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct cell_context *cell = cell_context(pipe); + + /* pass the clip state to the draw module */ + draw_set_clip_state(cell->draw, clip); +} + + + +/* Called when driver state tracker notices changes to the viewport + * matrix: + */ +static void +cell_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct cell_context *cell = cell_context(pipe); + + cell->viewport = *viewport; /* struct copy */ + cell->dirty |= CELL_NEW_VIEWPORT; + + /* pass the viewport info to the draw module */ + draw_set_viewport_state(cell->draw, viewport); + + /* Using tnl/ and vf/ modules is temporary while getting started. + * Full pipe will have vertex shader, vertex fetch of its own. + */ +} + + +static void +cell_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct cell_context *cell = cell_context(pipe); + + memcpy( &cell->scissor, scissor, sizeof(*scissor) ); + cell->dirty |= CELL_NEW_SCISSOR; +} + + +static void +cell_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ + struct cell_context *cell = cell_context(pipe); + + memcpy( &cell->poly_stipple, stipple, sizeof(*stipple) ); + cell->dirty |= CELL_NEW_STIPPLE; +} + + + +static void * +cell_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *setup) +{ + struct pipe_rasterizer_state *state + = MALLOC(sizeof(struct pipe_rasterizer_state)); + memcpy(state, setup, sizeof(struct pipe_rasterizer_state)); + return state; +} + + +static void +cell_bind_rasterizer_state(struct pipe_context *pipe, void *setup) +{ + struct cell_context *cell = cell_context(pipe); + + /* pass-through to draw module */ + draw_set_rasterizer_state(cell->draw, setup); + + cell->rasterizer = (struct pipe_rasterizer_state *)setup; + + cell->dirty |= CELL_NEW_RASTERIZER; +} + + +static void +cell_delete_rasterizer_state(struct pipe_context *pipe, void *rasterizer) +{ + FREE(rasterizer); +} + + + +static void * +cell_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + return mem_dup(sampler, sizeof(*sampler)); +} + + +static void +cell_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, void *sampler) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + assert(unit < PIPE_MAX_SAMPLERS); + cell->sampler[unit] = (struct pipe_sampler_state *)sampler; + + cell->dirty |= CELL_NEW_SAMPLER; +} + + +static void +cell_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + FREE( sampler ); +} + + + +static void +cell_set_sampler_texture(struct pipe_context *pipe, + unsigned sampler, + struct pipe_texture *texture) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->texture[sampler] = cell_texture(texture); + + cell_update_texture_mapping(cell); + + cell->dirty |= CELL_NEW_TEXTURE; +} + + + +static void +cell_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct cell_context *cell = cell_context(pipe); + + if (1 /*memcmp(&cell->framebuffer, fb, sizeof(*fb))*/) { + struct pipe_surface *csurf = fb->cbufs[0]; + struct pipe_surface *zsurf = fb->zsbuf; + uint i; + + /* unmap old surfaces */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { + if (cell->framebuffer.cbufs[i] && cell->cbuf_map[i]) { + pipe_surface_unmap(cell->framebuffer.cbufs[i]); + cell->cbuf_map[i] = NULL; + } + } + + if (cell->framebuffer.zsbuf && cell->zsbuf_map) { + pipe_surface_unmap(cell->framebuffer.zsbuf); + cell->zsbuf_map = NULL; + } + + /* update my state */ + cell->framebuffer = *fb; + + /* map new surfaces */ + if (csurf) + cell->cbuf_map[0] = pipe_surface_map(csurf); + + if (zsurf) + cell->zsbuf_map = pipe_surface_map(zsurf); + + cell->dirty |= CELL_NEW_FRAMEBUFFER; + } +} + + + +void +cell_init_state_functions(struct cell_context *cell) +{ + cell->pipe.create_blend_state = cell_create_blend_state; + cell->pipe.bind_blend_state = cell_bind_blend_state; + cell->pipe.delete_blend_state = cell_delete_blend_state; + + cell->pipe.create_sampler_state = cell_create_sampler_state; + cell->pipe.bind_sampler_state = cell_bind_sampler_state; + cell->pipe.delete_sampler_state = cell_delete_sampler_state; + + cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state; + cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state; + cell->pipe.delete_depth_stencil_alpha_state = cell_delete_depth_stencil_alpha_state; + + cell->pipe.create_rasterizer_state = cell_create_rasterizer_state; + cell->pipe.bind_rasterizer_state = cell_bind_rasterizer_state; + cell->pipe.delete_rasterizer_state = cell_delete_rasterizer_state; + + cell->pipe.set_blend_color = cell_set_blend_color; + cell->pipe.set_clip_state = cell_set_clip_state; + cell->pipe.set_constant_buffer = cell_set_constant_buffer; + + cell->pipe.set_framebuffer_state = cell_set_framebuffer_state; + + cell->pipe.set_polygon_stipple = cell_set_polygon_stipple; + cell->pipe.set_scissor_state = cell_set_scissor_state; + cell->pipe.set_viewport_state = cell_set_viewport_state; +} + diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.h b/src/gallium/drivers/cell/ppu/cell_pipe_state.h new file mode 100644 index 0000000000..1889bd52ff --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef CELL_PIPE_STATE_H +#define CELL_PIPE_STATE_H + + +struct cell_context; + +extern void +cell_init_state_functions(struct cell_context *cell); + + +#endif /* CELL_PIPE_STATE_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_state.h b/src/gallium/drivers/cell/ppu/cell_state.h index 3a71ba14fa..2af7770ebb 100644 --- a/src/gallium/drivers/cell/ppu/cell_state.h +++ b/src/gallium/drivers/cell/ppu/cell_state.h @@ -23,42 +23,6 @@ -extern void -cell_set_framebuffer_state( struct pipe_context *, - const struct pipe_framebuffer_state * ); - - - -extern void * -cell_create_blend_state(struct pipe_context *, const struct pipe_blend_state *); -extern void cell_bind_blend_state(struct pipe_context *, void *); -extern void cell_delete_blend_state(struct pipe_context *, void *); - -extern void cell_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ); - - -void * -cell_create_sampler_state(struct pipe_context *, - const struct pipe_sampler_state *); - -extern void -cell_bind_sampler_state(struct pipe_context *, unsigned, void *); - -extern void -cell_delete_sampler_state(struct pipe_context *, void *); - - -extern void * -cell_create_depth_stencil_alpha_state(struct pipe_context *, - const struct pipe_depth_stencil_alpha_state *); - -extern void -cell_bind_depth_stencil_alpha_state(struct pipe_context *, void *); - -extern void -cell_delete_depth_stencil_alpha_state(struct pipe_context *, void *); - void *cell_create_fs_state(struct pipe_context *, const struct pipe_shader_state *); @@ -69,34 +33,11 @@ void *cell_create_vs_state(struct pipe_context *, void cell_bind_vs_state(struct pipe_context *, void *); void cell_delete_vs_state(struct pipe_context *, void *); - -void * -cell_create_rasterizer_state(struct pipe_context *, - const struct pipe_rasterizer_state *); -void cell_bind_rasterizer_state(struct pipe_context *, void *); -void cell_delete_rasterizer_state(struct pipe_context *, void *); - - -void cell_set_clip_state( struct pipe_context *, - const struct pipe_clip_state * ); - -void cell_set_constant_buffer(struct pipe_context *pipe, - uint shader, uint index, - const struct pipe_constant_buffer *buf); - -void cell_set_polygon_stipple( struct pipe_context *, - const struct pipe_poly_stipple * ); - void -cell_set_sampler_texture(struct pipe_context *pipe, - unsigned sampler, - struct pipe_texture *texture); - -void cell_set_scissor_state( struct pipe_context *, - const struct pipe_scissor_state * ); +cell_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf); -void cell_set_texture_state( struct pipe_context *, - unsigned unit, struct pipe_texture * ); void cell_set_vertex_element(struct pipe_context *, unsigned index, @@ -106,10 +47,6 @@ void cell_set_vertex_buffer(struct pipe_context *, unsigned index, const struct pipe_vertex_buffer *); -void cell_set_viewport_state( struct pipe_context *, - const struct pipe_viewport_state * ); - - void cell_update_derived( struct cell_context *softpipe ); #endif diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index 4629eb1320..e1b91075b2 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -79,8 +79,9 @@ cell_texture_layout(struct cell_texture * spt) } -struct pipe_texture * -cell_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) +static struct pipe_texture * +cell_texture_create(struct pipe_context *pipe, + const struct pipe_texture *templat) { struct cell_texture *spt = CALLOC_STRUCT(cell_texture); if (!spt) @@ -103,7 +104,7 @@ cell_texture_create(struct pipe_context *pipe, const struct pipe_texture *templa } -void +static void cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) { if (!*pt) @@ -128,7 +129,7 @@ cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } -void +static void cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) { /* XXX TO DO: re-tile the texture data ... */ @@ -139,7 +140,7 @@ cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) /** * Called via pipe->get_tex_surface() */ -struct pipe_surface * +static struct pipe_surface * cell_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) @@ -258,3 +259,13 @@ cell_update_texture_mapping(struct cell_context *cell) cell->tex_map = pipe_surface_map(cell->tex_surf); #endif } + + +void +cell_init_texture_functions(struct cell_context *cell) +{ + cell->pipe.texture_create = cell_texture_create; + cell->pipe.texture_release = cell_texture_release; + cell->pipe.texture_update = cell_texture_update; + cell->pipe.get_tex_surface = cell_get_tex_surface; +} diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h index 07e81582f4..824fb3e20f 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.h +++ b/src/gallium/drivers/cell/ppu/cell_texture.h @@ -29,7 +29,7 @@ #define CELL_TEXTURE_H -struct pipe_context; +struct cell_context; struct pipe_texture; @@ -60,24 +60,12 @@ cell_texture(struct pipe_texture *pt) -extern struct pipe_texture * -cell_texture_create(struct pipe_context *pipe, - const struct pipe_texture *templat); - -extern void -cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); - extern void -cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); - -extern struct pipe_surface * -cell_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice); +cell_update_texture_mapping(struct cell_context *cell); extern void -cell_update_texture_mapping(struct cell_context *cell); +cell_init_texture_functions(struct cell_context *cell); -#endif /* CELL_TEXTURE */ +#endif /* CELL_TEXTURE_H */ -- cgit v1.2.3 From acd2253ae80d133bc84a5e78909ec72464e3f901 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:24:46 -0700 Subject: Remove obsolete files replaced by cell_pipe_state.c --- src/gallium/drivers/cell/ppu/cell_state_blend.c | 109 --------------------- src/gallium/drivers/cell/ppu/cell_state_clip.c | 84 ---------------- .../drivers/cell/ppu/cell_state_rasterizer.c | 106 -------------------- src/gallium/drivers/cell/ppu/cell_state_sampler.c | 84 ---------------- src/gallium/drivers/cell/ppu/cell_state_surface.c | 71 -------------- 5 files changed, 454 deletions(-) delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_blend.c delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_clip.c delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_rasterizer.c delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_sampler.c delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_surface.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_blend.c b/src/gallium/drivers/cell/ppu/cell_state_blend.c deleted file mode 100644 index b6d6d71f0c..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_blend.c +++ /dev/null @@ -1,109 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "cell_context.h" -#include "cell_state.h" - - - -void * -cell_create_blend_state(struct pipe_context *pipe, - const struct pipe_blend_state *blend) -{ - return mem_dup(blend, sizeof(*blend)); -} - - -void -cell_bind_blend_state(struct pipe_context *pipe, void *blend) -{ - struct cell_context *cell = cell_context(pipe); - - draw_flush(cell->draw); - - cell->blend = (const struct pipe_blend_state *)blend; - - cell->dirty |= CELL_NEW_BLEND; -} - - -void -cell_delete_blend_state(struct pipe_context *pipe, void *blend) -{ - FREE(blend); -} - - -void -cell_set_blend_color(struct pipe_context *pipe, - const struct pipe_blend_color *blend_color) -{ - struct cell_context *cell = cell_context(pipe); - - draw_flush(cell->draw); - - cell->blend_color = *blend_color; - - cell->dirty |= CELL_NEW_BLEND; -} - - - - -void * -cell_create_depth_stencil_alpha_state(struct pipe_context *pipe, - const struct pipe_depth_stencil_alpha_state *depth_stencil) -{ - return mem_dup(depth_stencil, sizeof(*depth_stencil)); -} - - -void -cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe, - void *depth_stencil) -{ - struct cell_context *cell = cell_context(pipe); - - draw_flush(cell->draw); - - cell->depth_stencil - = (const struct pipe_depth_stencil_alpha_state *) depth_stencil; - - cell->dirty |= CELL_NEW_DEPTH_STENCIL; -} - - -void -cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth) -{ - FREE(depth); -} diff --git a/src/gallium/drivers/cell/ppu/cell_state_clip.c b/src/gallium/drivers/cell/ppu/cell_state_clip.c deleted file mode 100644 index 0482f87e88..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_clip.c +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "cell_context.h" -#include "cell_state.h" -#include "draw/draw_context.h" - - -void cell_set_clip_state( struct pipe_context *pipe, - const struct pipe_clip_state *clip ) -{ - struct cell_context *cell = cell_context(pipe); - - /* pass the clip state to the draw module */ - draw_set_clip_state(cell->draw, clip); -} - - - -/* Called when driver state tracker notices changes to the viewport - * matrix: - */ -void cell_set_viewport_state( struct pipe_context *pipe, - const struct pipe_viewport_state *viewport ) -{ - struct cell_context *cell = cell_context(pipe); - - cell->viewport = *viewport; /* struct copy */ - cell->dirty |= CELL_NEW_VIEWPORT; - - /* pass the viewport info to the draw module */ - draw_set_viewport_state(cell->draw, viewport); - - /* Using tnl/ and vf/ modules is temporary while getting started. - * Full pipe will have vertex shader, vertex fetch of its own. - */ -} - - -void cell_set_scissor_state( struct pipe_context *pipe, - const struct pipe_scissor_state *scissor ) -{ - struct cell_context *cell = cell_context(pipe); - - memcpy( &cell->scissor, scissor, sizeof(*scissor) ); - cell->dirty |= CELL_NEW_SCISSOR; -} - - -void cell_set_polygon_stipple( struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple ) -{ - struct cell_context *cell = cell_context(pipe); - - memcpy( &cell->poly_stipple, stipple, sizeof(*stipple) ); - cell->dirty |= CELL_NEW_STIPPLE; -} diff --git a/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c b/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c deleted file mode 100644 index 7eca5b5765..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c +++ /dev/null @@ -1,106 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "cell_context.h" -#include "cell_state.h" - - - -struct spu_rasterizer_state -{ - unsigned flatshade:1; -#if 0 - unsigned light_twoside:1; - unsigned front_winding:2; /**< PIPE_WINDING_x */ - unsigned cull_mode:2; /**< PIPE_WINDING_x */ - unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */ - unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */ - unsigned offset_cw:1; - unsigned offset_ccw:1; -#endif - unsigned scissor:1; - unsigned poly_smooth:1; - unsigned poly_stipple_enable:1; - unsigned point_smooth:1; -#if 0 - unsigned point_sprite:1; - unsigned point_size_per_vertex:1; /**< size computed in vertex shader */ -#endif - unsigned multisample:1; /* XXX maybe more ms state in future */ - unsigned line_smooth:1; - unsigned line_stipple_enable:1; - unsigned line_stipple_factor:8; /**< [1..256] actually */ - unsigned line_stipple_pattern:16; -#if 0 - unsigned bypass_clipping:1; -#endif - unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ - - float line_width; - float point_size; /**< used when no per-vertex size */ -#if 0 - float offset_units; - float offset_scale; - ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */ -#endif -}; - - - -void * -cell_create_rasterizer_state(struct pipe_context *pipe, - const struct pipe_rasterizer_state *setup) -{ - struct pipe_rasterizer_state *state - = MALLOC(sizeof(struct pipe_rasterizer_state)); - memcpy(state, setup, sizeof(struct pipe_rasterizer_state)); - return state; -} - - -void -cell_bind_rasterizer_state(struct pipe_context *pipe, void *setup) -{ - struct cell_context *cell = cell_context(pipe); - - /* pass-through to draw module */ - draw_set_rasterizer_state(cell->draw, setup); - - cell->rasterizer = (struct pipe_rasterizer_state *)setup; - - cell->dirty |= CELL_NEW_RASTERIZER; -} - - -void -cell_delete_rasterizer_state(struct pipe_context *pipe, void *rasterizer) -{ - FREE(rasterizer); -} diff --git a/src/gallium/drivers/cell/ppu/cell_state_sampler.c b/src/gallium/drivers/cell/ppu/cell_state_sampler.c deleted file mode 100644 index a33421a4ad..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_sampler.c +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: - * Brian Paul - */ - -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "cell_context.h" -#include "cell_state.h" -#include "cell_texture.h" - - -void * -cell_create_sampler_state(struct pipe_context *pipe, - const struct pipe_sampler_state *sampler) -{ - return mem_dup(sampler, sizeof(*sampler)); -} - -void -cell_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) -{ - struct cell_context *cell = cell_context(pipe); - - draw_flush(cell->draw); - - assert(unit < PIPE_MAX_SAMPLERS); - cell->sampler[unit] = (struct pipe_sampler_state *)sampler; - - cell->dirty |= CELL_NEW_SAMPLER; -} - - -void -cell_delete_sampler_state(struct pipe_context *pipe, - void *sampler) -{ - FREE( sampler ); -} - - - -void -cell_set_sampler_texture(struct pipe_context *pipe, - unsigned sampler, - struct pipe_texture *texture) -{ - struct cell_context *cell = cell_context(pipe); - - draw_flush(cell->draw); - - cell->texture[sampler] = texture; - - cell_update_texture_mapping(cell); - - cell->dirty |= CELL_NEW_TEXTURE; -} diff --git a/src/gallium/drivers/cell/ppu/cell_state_surface.c b/src/gallium/drivers/cell/ppu/cell_state_surface.c deleted file mode 100644 index 287610b76b..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_surface.c +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "pipe/p_inlines.h" -#include "cell_context.h" -#include "cell_state.h" - - -void -cell_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) -{ - struct cell_context *cell = cell_context(pipe); - - if (1 /*memcmp(&cell->framebuffer, fb, sizeof(*fb))*/) { - struct pipe_surface *csurf = fb->cbufs[0]; - struct pipe_surface *zsurf = fb->zsbuf; - uint i; - - /* unmap old surfaces */ - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { - if (cell->framebuffer.cbufs[i] && cell->cbuf_map[i]) { - pipe_surface_unmap(cell->framebuffer.cbufs[i]); - cell->cbuf_map[i] = NULL; - } - } - - if (cell->framebuffer.zsbuf && cell->zsbuf_map) { - pipe_surface_unmap(cell->framebuffer.zsbuf); - cell->zsbuf_map = NULL; - } - - /* update my state */ - cell->framebuffer = *fb; - - /* map new surfaces */ - if (csurf) - cell->cbuf_map[0] = pipe_surface_map(csurf); - - if (zsurf) - cell->zsbuf_map = pipe_surface_map(zsurf); - - cell->dirty |= CELL_NEW_FRAMEBUFFER; - } -} - -- cgit v1.2.3 From f6e1654e22d983ec9015fe4e7445e03df1227c71 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:25:07 -0700 Subject: cell: plug in cell_set_sampler_texture --- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index aef50725e8..c5ddf6a09e 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -302,6 +302,8 @@ cell_init_state_functions(struct cell_context *cell) cell->pipe.bind_sampler_state = cell_bind_sampler_state; cell->pipe.delete_sampler_state = cell_delete_sampler_state; + cell->pipe.set_sampler_texture = cell_set_sampler_texture; + cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state; cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state; cell->pipe.delete_depth_stencil_alpha_state = cell_delete_depth_stencil_alpha_state; -- cgit v1.2.3 From 9e57e70b42471ff587441fb8c1b5de728521fafd Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:27:08 -0700 Subject: cell: #includes to silence warnings --- src/gallium/drivers/cell/ppu/cell_clear.c | 1 + src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c index e588a30d5b..3ffe09add6 100644 --- a/src/gallium/drivers/cell/ppu/cell_clear.c +++ b/src/gallium/drivers/cell/ppu/cell_clear.c @@ -41,6 +41,7 @@ #include "cell_batch.h" #include "cell_flush.h" #include "cell_spu.h" +#include "cell_state.h" void diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index 64c7821c19..f7ef72e5a2 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -35,6 +35,7 @@ #include "cell_context.h" #include "cell_draw_arrays.h" +#include "cell_flush.h" #include "cell_spu.h" #include "cell_batch.h" -- cgit v1.2.3 From 64683473753de6eb978245e348e9b20cd1d42883 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:30:50 -0700 Subject: cell: init shader-related functions in cell_init_shader_functions() --- src/gallium/drivers/cell/ppu/cell_context.c | 11 +----- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 1 - src/gallium/drivers/cell/ppu/cell_state.h | 50 ++++++++++++++++---------- src/gallium/drivers/cell/ppu/cell_state_fs.c | 29 +++++++++++---- 4 files changed, 55 insertions(+), 36 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index 9f0ecb2be8..98c314f45c 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -199,16 +199,6 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) /* state setters */ - cell->pipe.create_fs_state = cell_create_fs_state; - cell->pipe.bind_fs_state = cell_bind_fs_state; - cell->pipe.delete_fs_state = cell_delete_fs_state; - - cell->pipe.create_vs_state = cell_create_vs_state; - cell->pipe.bind_vs_state = cell_bind_vs_state; - cell->pipe.delete_vs_state = cell_delete_vs_state; - - cell->pipe.set_constant_buffer = cell_set_constant_buffer; - cell->pipe.set_vertex_buffer = cell_set_vertex_buffer; cell->pipe.set_vertex_element = cell_set_vertex_element; @@ -225,6 +215,7 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) #endif cell_init_state_functions(cell); + cell_init_shader_functions(cell); cell_init_surface_functions(cell); cell_init_texture_functions(cell); diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index c5ddf6a09e..35e88f79b1 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -314,7 +314,6 @@ cell_init_state_functions(struct cell_context *cell) cell->pipe.set_blend_color = cell_set_blend_color; cell->pipe.set_clip_state = cell_set_clip_state; - cell->pipe.set_constant_buffer = cell_set_constant_buffer; cell->pipe.set_framebuffer_state = cell_set_framebuffer_state; diff --git a/src/gallium/drivers/cell/ppu/cell_state.h b/src/gallium/drivers/cell/ppu/cell_state.h index 2af7770ebb..31ce505e21 100644 --- a/src/gallium/drivers/cell/ppu/cell_state.h +++ b/src/gallium/drivers/cell/ppu/cell_state.h @@ -1,3 +1,29 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ #ifndef CELL_STATE_H @@ -22,23 +48,6 @@ #define CELL_NEW_VERTEX_INFO 0x8000 - - -void *cell_create_fs_state(struct pipe_context *, - const struct pipe_shader_state *); -void cell_bind_fs_state(struct pipe_context *, void *); -void cell_delete_fs_state(struct pipe_context *, void *); -void *cell_create_vs_state(struct pipe_context *, - const struct pipe_shader_state *); -void cell_bind_vs_state(struct pipe_context *, void *); -void cell_delete_vs_state(struct pipe_context *, void *); - -void -cell_set_constant_buffer(struct pipe_context *pipe, - uint shader, uint index, - const struct pipe_constant_buffer *buf); - - void cell_set_vertex_element(struct pipe_context *, unsigned index, const struct pipe_vertex_element *); @@ -49,4 +58,9 @@ void cell_set_vertex_buffer(struct pipe_context *, void cell_update_derived( struct cell_context *softpipe ); -#endif + +void +cell_init_shader_functions(struct cell_context *cell); + +#endif /* CELL_STATE_H */ + diff --git a/src/gallium/drivers/cell/ppu/cell_state_fs.c b/src/gallium/drivers/cell/ppu/cell_state_fs.c index f3958fa429..935501441b 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_fs.c +++ b/src/gallium/drivers/cell/ppu/cell_state_fs.c @@ -41,7 +41,7 @@ #include "cell_state.h" -void * +static void * cell_create_fs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) { @@ -80,7 +80,7 @@ cell_create_fs_state(struct pipe_context *pipe, } -void +static void cell_bind_fs_state(struct pipe_context *pipe, void *fs) { struct cell_context *cell = cell_context(pipe); @@ -91,7 +91,7 @@ cell_bind_fs_state(struct pipe_context *pipe, void *fs) } -void +static void cell_delete_fs_state(struct pipe_context *pipe, void *fs) { struct cell_fragment_shader_state *state = @@ -101,7 +101,7 @@ cell_delete_fs_state(struct pipe_context *pipe, void *fs) } -void * +static void * cell_create_vs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) { @@ -124,7 +124,7 @@ cell_create_vs_state(struct pipe_context *pipe, } -void +static void cell_bind_vs_state(struct pipe_context *pipe, void *vs) { struct cell_context *cell = cell_context(pipe); @@ -137,7 +137,7 @@ cell_bind_vs_state(struct pipe_context *pipe, void *vs) } -void +static void cell_delete_vs_state(struct pipe_context *pipe, void *vs) { struct cell_context *cell = cell_context(pipe); @@ -150,7 +150,7 @@ cell_delete_vs_state(struct pipe_context *pipe, void *vs) } -void +static void cell_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, const struct pipe_constant_buffer *buf) @@ -169,3 +169,18 @@ cell_set_constant_buffer(struct pipe_context *pipe, cell->dirty |= CELL_NEW_CONSTANTS; } + + +void +cell_init_shader_functions(struct cell_context *cell) +{ + cell->pipe.create_fs_state = cell_create_fs_state; + cell->pipe.bind_fs_state = cell_bind_fs_state; + cell->pipe.delete_fs_state = cell_delete_fs_state; + + cell->pipe.create_vs_state = cell_create_vs_state; + cell->pipe.bind_vs_state = cell_bind_vs_state; + cell->pipe.delete_vs_state = cell_delete_vs_state; + + cell->pipe.set_constant_buffer = cell_set_constant_buffer; +} -- cgit v1.2.3 From fd4bdd020a9e1999b87d553b50151405c054a619 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:32:43 -0700 Subject: cell: rename cell_state_fs.c -> cell_state_shader.c --- src/gallium/drivers/cell/ppu/Makefile | 2 +- src/gallium/drivers/cell/ppu/cell_state_fs.c | 186 ----------------------- src/gallium/drivers/cell/ppu/cell_state_shader.c | 186 +++++++++++++++++++++++ 3 files changed, 187 insertions(+), 187 deletions(-) delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_fs.c create mode 100644 src/gallium/drivers/cell/ppu/cell_state_shader.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index 6b6dfca890..164dde762c 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -27,7 +27,7 @@ SOURCES = \ cell_flush.c \ cell_state_derived.c \ cell_state_emit.c \ - cell_state_fs.c \ + cell_state_shader.c \ cell_pipe_state.c \ cell_state_vertex.c \ cell_spu.c \ diff --git a/src/gallium/drivers/cell/ppu/cell_state_fs.c b/src/gallium/drivers/cell/ppu/cell_state_fs.c deleted file mode 100644 index 935501441b..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_fs.c +++ /dev/null @@ -1,186 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_winsys.h" -#include "draw/draw_context.h" -#if 0 -#include "pipe/p_shader_tokens.h" -#include "gallivm/gallivm.h" -#include "tgsi/util/tgsi_dump.h" -#include "tgsi/exec/tgsi_sse2.h" -#endif - -#include "cell_context.h" -#include "cell_state.h" - - -static void * -cell_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *templ) -{ - /*struct cell_context *cell = cell_context(pipe);*/ - struct cell_fragment_shader_state *state; - - state = CALLOC_STRUCT(cell_fragment_shader_state); - if (!state) - return NULL; - - state->shader = *templ; - -#if 0 - if (cell->dump_fs) { - tgsi_dump(state->shader.tokens, 0); - } - -#if defined(__i386__) || defined(__386__) - if (cell->use_sse) { - x86_init_func( &state->sse2_program ); - tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program ); - } -#endif - -#ifdef MESA_LLVM - state->llvm_prog = 0; - if (!gallivm_global_cpu_engine()) { - gallivm_cpu_engine_create(state->llvm_prog); - } - else - gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); -#endif -#endif - - return state; -} - - -static void -cell_bind_fs_state(struct pipe_context *pipe, void *fs) -{ - struct cell_context *cell = cell_context(pipe); - - cell->fs = (struct cell_fragment_shader_state *) fs; - - cell->dirty |= CELL_NEW_FS; -} - - -static void -cell_delete_fs_state(struct pipe_context *pipe, void *fs) -{ - struct cell_fragment_shader_state *state = - (struct cell_fragment_shader_state *) fs; - - FREE( state ); -} - - -static void * -cell_create_vs_state(struct pipe_context *pipe, - const struct pipe_shader_state *templ) -{ - struct cell_context *cell = cell_context(pipe); - struct cell_vertex_shader_state *state; - - state = CALLOC_STRUCT(cell_vertex_shader_state); - if (!state) - return NULL; - - state->shader = *templ; - - state->draw_data = draw_create_vertex_shader(cell->draw, &state->shader); - if (state->draw_data == NULL) { - FREE( state ); - return NULL; - } - - return state; -} - - -static void -cell_bind_vs_state(struct pipe_context *pipe, void *vs) -{ - struct cell_context *cell = cell_context(pipe); - - cell->vs = (const struct cell_vertex_shader_state *) vs; - - draw_bind_vertex_shader(cell->draw, cell->vs->draw_data); - - cell->dirty |= CELL_NEW_VS; -} - - -static void -cell_delete_vs_state(struct pipe_context *pipe, void *vs) -{ - struct cell_context *cell = cell_context(pipe); - - struct cell_vertex_shader_state *state = - (struct cell_vertex_shader_state *) vs; - - draw_delete_vertex_shader(cell->draw, state->draw_data); - FREE( state ); -} - - -static void -cell_set_constant_buffer(struct pipe_context *pipe, - uint shader, uint index, - const struct pipe_constant_buffer *buf) -{ - struct cell_context *cell = cell_context(pipe); - struct pipe_winsys *ws = pipe->winsys; - - assert(shader < PIPE_SHADER_TYPES); - assert(index == 0); - - /* note: reference counting */ - pipe_buffer_reference(ws, - &cell->constants[shader].buffer, - buf->buffer); - cell->constants[shader].size = buf->size; - - cell->dirty |= CELL_NEW_CONSTANTS; -} - - -void -cell_init_shader_functions(struct cell_context *cell) -{ - cell->pipe.create_fs_state = cell_create_fs_state; - cell->pipe.bind_fs_state = cell_bind_fs_state; - cell->pipe.delete_fs_state = cell_delete_fs_state; - - cell->pipe.create_vs_state = cell_create_vs_state; - cell->pipe.bind_vs_state = cell_bind_vs_state; - cell->pipe.delete_vs_state = cell_delete_vs_state; - - cell->pipe.set_constant_buffer = cell_set_constant_buffer; -} diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c new file mode 100644 index 0000000000..935501441b --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -0,0 +1,186 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" +#include "draw/draw_context.h" +#if 0 +#include "pipe/p_shader_tokens.h" +#include "gallivm/gallivm.h" +#include "tgsi/util/tgsi_dump.h" +#include "tgsi/exec/tgsi_sse2.h" +#endif + +#include "cell_context.h" +#include "cell_state.h" + + +static void * +cell_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + /*struct cell_context *cell = cell_context(pipe);*/ + struct cell_fragment_shader_state *state; + + state = CALLOC_STRUCT(cell_fragment_shader_state); + if (!state) + return NULL; + + state->shader = *templ; + +#if 0 + if (cell->dump_fs) { + tgsi_dump(state->shader.tokens, 0); + } + +#if defined(__i386__) || defined(__386__) + if (cell->use_sse) { + x86_init_func( &state->sse2_program ); + tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program ); + } +#endif + +#ifdef MESA_LLVM + state->llvm_prog = 0; + if (!gallivm_global_cpu_engine()) { + gallivm_cpu_engine_create(state->llvm_prog); + } + else + gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); +#endif +#endif + + return state; +} + + +static void +cell_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct cell_context *cell = cell_context(pipe); + + cell->fs = (struct cell_fragment_shader_state *) fs; + + cell->dirty |= CELL_NEW_FS; +} + + +static void +cell_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct cell_fragment_shader_state *state = + (struct cell_fragment_shader_state *) fs; + + FREE( state ); +} + + +static void * +cell_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct cell_context *cell = cell_context(pipe); + struct cell_vertex_shader_state *state; + + state = CALLOC_STRUCT(cell_vertex_shader_state); + if (!state) + return NULL; + + state->shader = *templ; + + state->draw_data = draw_create_vertex_shader(cell->draw, &state->shader); + if (state->draw_data == NULL) { + FREE( state ); + return NULL; + } + + return state; +} + + +static void +cell_bind_vs_state(struct pipe_context *pipe, void *vs) +{ + struct cell_context *cell = cell_context(pipe); + + cell->vs = (const struct cell_vertex_shader_state *) vs; + + draw_bind_vertex_shader(cell->draw, cell->vs->draw_data); + + cell->dirty |= CELL_NEW_VS; +} + + +static void +cell_delete_vs_state(struct pipe_context *pipe, void *vs) +{ + struct cell_context *cell = cell_context(pipe); + + struct cell_vertex_shader_state *state = + (struct cell_vertex_shader_state *) vs; + + draw_delete_vertex_shader(cell->draw, state->draw_data); + FREE( state ); +} + + +static void +cell_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct cell_context *cell = cell_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + + assert(shader < PIPE_SHADER_TYPES); + assert(index == 0); + + /* note: reference counting */ + pipe_buffer_reference(ws, + &cell->constants[shader].buffer, + buf->buffer); + cell->constants[shader].size = buf->size; + + cell->dirty |= CELL_NEW_CONSTANTS; +} + + +void +cell_init_shader_functions(struct cell_context *cell) +{ + cell->pipe.create_fs_state = cell_create_fs_state; + cell->pipe.bind_fs_state = cell_bind_fs_state; + cell->pipe.delete_fs_state = cell_delete_fs_state; + + cell->pipe.create_vs_state = cell_create_vs_state; + cell->pipe.bind_vs_state = cell_bind_vs_state; + cell->pipe.delete_vs_state = cell_delete_vs_state; + + cell->pipe.set_constant_buffer = cell_set_constant_buffer; +} -- cgit v1.2.3 From fce61f341faf6a2e1a8497ab963985ddbffa8b0a Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:44:15 -0700 Subject: gallium: fix bad ptr comparison --- src/gallium/drivers/softpipe/sp_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 8f31f05e47..295704c05f 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -136,7 +136,7 @@ softpipe_texture_update(struct pipe_context *pipe, struct softpipe_context *softpipe = softpipe_context(pipe); uint unit; for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { - if (softpipe->texture[unit] == texture) { + if (softpipe->texture[unit] == softpipe_texture(texture)) { sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); } } -- cgit v1.2.3 From 25ea1901b44107a5bc5351487e18d52d75df8ffd Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 15:09:27 -0700 Subject: gallium: replace some ordinary assignments with pipe_reference_texture() This fixes at least one instance of dereferencing an invalid texture pointer. --- src/gallium/drivers/cell/ppu/cell_texture.c | 1 + src/gallium/drivers/i915simple/i915_state.c | 5 ++++- src/gallium/drivers/i915simple/i915_texture.c | 1 + src/gallium/drivers/i965simple/brw_state.c | 4 +++- src/gallium/drivers/i965simple/brw_tex_layout.c | 1 + src/gallium/drivers/softpipe/sp_context.h | 2 +- src/gallium/drivers/softpipe/sp_quad_fs.c | 2 +- src/gallium/drivers/softpipe/sp_state_sampler.c | 3 ++- src/gallium/drivers/softpipe/sp_texture.c | 5 ++++- 9 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index e1b91075b2..0edefa5f05 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -88,6 +88,7 @@ cell_texture_create(struct pipe_context *pipe, return NULL; spt->base = *templat; + spt->base.refcount = 1; cell_texture_layout(spt); diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 294e6fad03..e055eed7e0 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -32,6 +32,7 @@ #include "draw/draw_context.h" #include "pipe/p_winsys.h" #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "i915_context.h" #include "i915_reg.h" @@ -505,7 +506,9 @@ static void i915_set_sampler_texture(struct pipe_context *pipe, { struct i915_context *i915 = i915_context(pipe); - i915->texture[sampler] = (struct i915_texture*)texture; /* ptr, not struct */ + pipe_texture_reference(pipe, + (struct pipe_texture **) &i915->texture[sampler], + texture); i915->dirty |= I915_NEW_TEXTURE; } diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index b235fae96d..1b415a94d4 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -488,6 +488,7 @@ i915_texture_create(struct pipe_context *pipe, struct i915_context *i915 = i915_context(pipe); tex->base = *templat; + tex->base.refcount = 1; if (i915->flags.is_i945 ? i945_miptree_layout(pipe, tex) : i915_miptree_layout(pipe, tex)) diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index f746d1cc57..f269b2882c 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -327,7 +327,9 @@ static void brw_set_sampler_texture(struct pipe_context *pipe, { struct brw_context *brw = brw_context(pipe); - brw->attribs.Texture[unit] = (struct brw_texture*)texture; /* ptr, not struct */ + pipe_reference_texture(pipe, + (struct pipe_texture **) &brw->attribs.Texture[unit], + texture); brw->state.dirty.brw |= BRW_NEW_TEXTURE; } diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 043a2ff9a4..86ce3d0cc3 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -308,6 +308,7 @@ brw_texture_create(struct pipe_context *pipe, if (tex) { tex->base = *templat; + tex->base.refcount = 1; if (brw_miptree_layout(pipe, tex)) tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64, diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index b70d4fea85..a50cee7648 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -68,7 +68,7 @@ struct softpipe_context { struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct softpipe_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index cf1b1eff75..2f40e09d5c 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -142,7 +142,7 @@ static void shade_begin(struct quad_stage *qs) /* set TGSI sampler state that varies */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { qss->samplers[i].state = softpipe->sampler[i]; - qss->samplers[i].texture = &softpipe->texture[i]->base; + qss->samplers[i].texture = softpipe->texture[i]; } /* find output slots for depth, color */ diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 9246915e19..18669a1c6e 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -30,6 +30,7 @@ */ #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "draw/draw_context.h" @@ -82,7 +83,7 @@ softpipe_set_sampler_texture(struct pipe_context *pipe, draw_flush(softpipe->draw); assert(unit < PIPE_MAX_SAMPLERS); - softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */ + pipe_texture_reference(pipe, &softpipe->texture[unit], texture); sp_tile_cache_set_texture(pipe, softpipe->tex_cache[unit], texture); diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 295704c05f..6ba0f09e0a 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -89,6 +89,7 @@ softpipe_texture_create(struct pipe_context *pipe, return NULL; spt->base = *templat; + spt->base.refcount = 1; softpipe_texture_layout(spt); @@ -100,6 +101,8 @@ softpipe_texture_create(struct pipe_context *pipe, return NULL; } + assert(spt->base.refcount == 1); + return &spt->base; } @@ -136,7 +139,7 @@ softpipe_texture_update(struct pipe_context *pipe, struct softpipe_context *softpipe = softpipe_context(pipe); uint unit; for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { - if (softpipe->texture[unit] == softpipe_texture(texture)) { + if (softpipe->texture[unit] == texture) { sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); } } -- cgit v1.2.3 From e523ef72044d7f8137a298d60597b8913bae9145 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 15:13:33 -0700 Subject: cell: use pipe_texture_reference() --- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 35e88f79b1..95bfc29fbe 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -242,7 +242,9 @@ cell_set_sampler_texture(struct pipe_context *pipe, draw_flush(cell->draw); - cell->texture[sampler] = cell_texture(texture); + pipe_texture_reference(pipe, + (struct pipe_texture **) &cell->texture[sampler], + texture); cell_update_texture_mapping(cell); -- cgit v1.2.3 From 228f6b978804268a482718e762ebfccbba784949 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 15:32:41 -0700 Subject: gallium: re-fix some msvc warnings --- src/gallium/auxiliary/draw/draw_aaline.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index f1fee4f8ba..73a02a32e4 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -140,14 +140,14 @@ aa_transform_decl(struct tgsi_transform_context *ctx, aactx->colorOutput = decl->u.DeclarationRange.First; } else if (decl->Declaration.File == TGSI_FILE_SAMPLER) { - if (decl->u.DeclarationRange.Last > aactx->maxSampler) + if ((int) decl->u.DeclarationRange.Last > aactx->maxSampler) aactx->maxSampler = decl->u.DeclarationRange.Last + 1; } else if (decl->Declaration.File == TGSI_FILE_INPUT) { - if (decl->u.DeclarationRange.Last > aactx->maxInput) + if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) aactx->maxInput = decl->u.DeclarationRange.Last; - if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && - decl->Semantic.SemanticIndex > aactx->maxGeneric) { + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && + (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { aactx->maxGeneric = decl->Semantic.SemanticIndex; } } @@ -393,7 +393,7 @@ aaline_create_texture(struct aaline_stage *aaline) for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { - uint d; + ubyte d; if (size == 1) { d = 255; } @@ -494,12 +494,12 @@ aaline_line(struct draw_stage *stage, struct prim_header *header) float *pos, *tex; float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; - float a = atan2(dy, dx); - float c_a = cos(a), s_a = sin(a); + double a = atan2(dy, dx); + float c_a = (float) cos(a), s_a = (float) sin(a); uint i; /* XXX the ends of lines aren't quite perfect yet, but probably passable */ - dx = 0.5 * half_width; + dx = 0.5F * half_width; dy = half_width; /* allocate/dup new verts */ -- cgit v1.2.3 From d3b7d26b0bab6587cfad64735aefa28d8377c358 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 17:57:40 -0700 Subject: gallium: s/pipe_reference_texture/pipe_texture_reference/ --- src/gallium/drivers/i965simple/brw_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index f269b2882c..254e3f7245 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -327,7 +327,7 @@ static void brw_set_sampler_texture(struct pipe_context *pipe, { struct brw_context *brw = brw_context(pipe); - pipe_reference_texture(pipe, + pipe_texture_reference(pipe, (struct pipe_texture **) &brw->attribs.Texture[unit], texture); -- cgit v1.2.3 From 8be9bc08e1da31619f1b1c49aa6280d44f94c442 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 18:00:03 -0700 Subject: gallium: include p_inlines.h --- src/gallium/drivers/i965simple/brw_state.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index 254e3f7245..2fc048bde0 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -32,6 +32,7 @@ #include "pipe/p_winsys.h" #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "pipe/p_shader_tokens.h" #include "tgsi/util/tgsi_dump.h" -- cgit v1.2.3 From 7c74037852a484a8a50e8bc540b954a624de4d33 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 20 Feb 2008 14:32:25 -0800 Subject: Cell: Initial pass at unified data cache --- src/gallium/drivers/cell/common.h | 8 ++ src/gallium/drivers/cell/ppu/cell_draw_arrays.c | 6 +- src/gallium/drivers/cell/ppu/cell_flush.c | 14 ++++ src/gallium/drivers/cell/spu/spu_dcache.c | 100 ++++++++++++++++++++++++ src/gallium/drivers/cell/spu/spu_dcache.h | 34 ++++++++ src/gallium/drivers/cell/spu/spu_exec.c | 49 ++++++------ src/gallium/drivers/cell/spu/spu_main.c | 8 ++ src/gallium/drivers/cell/spu/spu_vertex_fetch.c | 70 +---------------- 8 files changed, 194 insertions(+), 95 deletions(-) create mode 100644 src/gallium/drivers/cell/spu/spu_dcache.c create mode 100644 src/gallium/drivers/cell/spu/spu_dcache.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index cf892206c6..f32ad5bfbe 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -93,6 +93,7 @@ #define CELL_CMD_STATE_BLEND 19 #define CELL_CMD_STATE_ATTRIB_FETCH 20 #define CELL_CMD_VS_EXECUTE 21 +#define CELL_CMD_FLUSH_BUFFER_RANGE 22 #define CELL_NUM_BUFFERS 4 @@ -144,6 +145,13 @@ struct cell_attribute_fetch_code { uint size; }; + +struct cell_buffer_range { + uint64_t base; + unsigned size; +}; + + struct cell_shader_info { uint64_t declarations; diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index f12613649b..cbd387f014 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -49,9 +49,12 @@ cell_map_constant_buffers(struct cell_context *sp) struct pipe_winsys *ws = sp->pipe.winsys; uint i; for (i = 0; i < 2; i++) { - if (sp->constants[i].size) + if (sp->constants[i].size) { sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, PIPE_BUFFER_USAGE_CPU_READ); + cell_flush_buffer_range(sp, sp->mapped_constants[i], + sp->constants[i].buffer->size); + } } draw_set_mapped_constant_buffer(sp->draw, @@ -124,6 +127,7 @@ cell_draw_elements(struct pipe_context *pipe, void *buf = pipe->winsys->buffer_map(pipe->winsys, sp->vertex_buffer[i].buffer, PIPE_BUFFER_USAGE_CPU_READ); + cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size); draw_set_mapped_vertex_buffer(draw, i, buf); } } diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c index 20f27531fc..66a5627d84 100644 --- a/src/gallium/drivers/cell/ppu/cell_flush.c +++ b/src/gallium/drivers/cell/ppu/cell_flush.c @@ -82,3 +82,17 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags) flushing = FALSE; } + + +void +cell_flush_buffer_range(struct cell_context *cell, void *ptr, + unsigned size) +{ + uint64_t batch[1 + (ROUNDUP8(sizeof(struct cell_buffer_range)) / 8)]; + struct cell_buffer_range *br = (struct cell_buffer_range *) & batch[1]; + + batch[0] = CELL_CMD_FLUSH_BUFFER_RANGE; + br->base = (uintptr_t) ptr; + br->size = size; + cell_batch_append(cell, batch, sizeof(batch)); +} diff --git a/src/gallium/drivers/cell/spu/spu_dcache.c b/src/gallium/drivers/cell/spu/spu_dcache.c new file mode 100644 index 0000000000..9e30e17880 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_dcache.c @@ -0,0 +1,100 @@ +/* + * (C) Copyright IBM Corporation 2008 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "spu_main.h" +#include "spu_dcache.h" + +#define CACHE_NAME data +#define CACHED_TYPE qword +#define CACHE_TYPE CACHE_TYPE_RO +#define CACHE_SET_TAGID(set) TAG_VERTEX_BUFFER +#define CACHE_LOG2NNWAY 2 +#define CACHE_LOG2NSETS 6 +#include + +/* Yes folks, this is ugly. + */ +#undef CACHE_NWAY +#undef CACHE_NSETS +#define CACHE_NAME data +#define CACHE_NWAY 4 +#define CACHE_NSETS (1U << 6) + + +/** + * Fetch between arbitrary number of bytes from an unaligned address + */ +void +spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size) +{ + const int shift = ea & 0x0f; + const unsigned aligned_start_ea = ea & ~0x0f; + const unsigned aligned_end_ea = (ea + size) & ~0x0f; + const unsigned num_entries = ((aligned_end_ea - aligned_start_ea) / 16) + 1; + unsigned i; + + + if (shift == 0) { + /* Data is already aligned. Fetch directly into the destination buffer. + */ + for (i = 0; i < num_entries; i++) { + dst[i] = cache_rd(data, (ea & ~0x0f) + (i * 16)); + } + } else { + qword tmp[2] ALIGN16_ATTRIB; + + + tmp[0] = cache_rd(data, (ea & ~0x0f)); + for (i = 0; i < (num_entries & ~1); i++) { + const unsigned curr = i & 1; + const unsigned next = curr ^ 1; + + tmp[next] = cache_rd(data, (ea & ~0x0f) + (next * 16)); + + dst[i] = si_or((qword) spu_slqwbyte(tmp[curr], shift), + (qword) spu_rlmaskqwbyte(tmp[next], shift - 16)); + } + + if (i < num_entries) { + dst[i] = si_or((qword) spu_slqwbyte(tmp[(i & 1)], shift), + si_il(0)); + } + } +} + + +void +spu_dcache_mark_dirty(unsigned ea, unsigned size) +{ + unsigned i; + + (void) ea; + (void) size; + + /* Invalidate the whole cache for now. + */ + for (i = 0; i < (CACHE_NWAY * CACHE_NSETS); i++) { + CACHELINE_CLEARVALID(i); + } +} diff --git a/src/gallium/drivers/cell/spu/spu_dcache.h b/src/gallium/drivers/cell/spu/spu_dcache.h new file mode 100644 index 0000000000..7a06b8c25a --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_dcache.h @@ -0,0 +1,34 @@ +/* + * (C) Copyright IBM Corporation 2008 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SPU_DCACHE_H +#define SPU_DCACHE_H + +extern void +spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size); + +extern void +spu_dcache_mark_dirty(unsigned ea, unsigned size); + +#endif /* SPU_DCACHE_H */ diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 0eb5ea1a3f..94ac6a2885 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -72,6 +72,7 @@ #include "spu_exec.h" #include "spu_main.h" #include "spu_vertex_shader.h" +#include "spu_dcache.h" #define TILE_TOP_LEFT 0 #define TILE_TOP_RIGHT 1 @@ -352,19 +353,17 @@ fetch_src_file_channel( case TGSI_EXTSWIZZLE_W: switch( file ) { case TGSI_FILE_CONSTANT: { - unsigned char buffer[32] ALIGN16_ATTRIB; unsigned i; for (i = 0; i < 4; i++) { const float *ptr = mach->Consts[index->i[i]]; - const uint64_t addr = (uint64_t)(uintptr_t) ptr; - const unsigned size = ((addr & 0x0f) == 0) ? 16 : 32; + float tmp[4]; - mfc_get(buffer, addr & ~0x0f, size, TAG_VERTEX_BUFFER, 0, 0); - wait_on_mask(1 << TAG_VERTEX_BUFFER); + spu_dcache_fetch_unaligned((qword *) tmp, + (uintptr_t)(ptr + swizzle), + sizeof(float)); - (void) memcpy(& chan->f[i], &buffer[(addr & 0x0f) - + (sizeof(float) * swizzle)], sizeof(float)); + chan->f[i] = tmp[0]; } break; } @@ -1899,32 +1898,30 @@ spu_exec_machine_run( struct spu_exec_machine *mach ) /* execute declarations (interpolants) */ if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { for (i = 0; i < mach->NumDeclarations; i++) { - uint8_t buffer[sizeof(struct tgsi_full_declaration) + 32] ALIGN16_ATTRIB; - struct tgsi_full_declaration decl; - unsigned long decl_addr = (unsigned long) (mach->Declarations+i); - unsigned size = ((sizeof(decl) + (decl_addr & 0x0f) + 0x0f) & ~0x0f); + union { + struct tgsi_full_declaration decl; + qword buffer[2 * ((sizeof(struct tgsi_full_declaration) + 31) + / 32)]; + } d ALIGN16_ATTRIB; + unsigned ea = (unsigned) (mach->Declarations + pc); - mfc_get(buffer, decl_addr & ~0x0f, size, TAG_INSTRUCTION_FETCH, 0, 0); - wait_on_mask(1 << TAG_INSTRUCTION_FETCH); + spu_dcache_fetch_unaligned(d.buffer, ea, sizeof(d.decl)); - memcpy(& decl, buffer + (decl_addr & 0x0f), sizeof(decl)); - exec_declaration( mach, &decl ); + exec_declaration( mach, &d.decl ); } } /* execute instructions, until pc is set to -1 */ while (pc != -1) { - uint8_t buffer[sizeof(struct tgsi_full_instruction) + 32] ALIGN16_ATTRIB; - struct tgsi_full_instruction inst; - unsigned long inst_addr = (unsigned long) (mach->Instructions + pc); - unsigned size = ((sizeof(inst) + (inst_addr & 0x0f) + 0x0f) & ~0x0f); - - assert(pc < mach->NumInstructions); - mfc_get(buffer, inst_addr & ~0x0f, size, TAG_INSTRUCTION_FETCH, 0, 0); - wait_on_mask(1 << TAG_INSTRUCTION_FETCH); - - memcpy(& inst, buffer + (inst_addr & 0x0f), sizeof(inst)); - exec_instruction( mach, & inst, &pc ); + union { + struct tgsi_full_instruction inst; + qword buffer[2 * ((sizeof(struct tgsi_full_instruction) + 31) + / 32)]; + } i ALIGN16_ATTRIB; + unsigned ea = (unsigned) (mach->Instructions + pc); + + spu_dcache_fetch_unaligned(i.buffer, ea, sizeof(i.inst)); + exec_instruction( mach, & i.inst, &pc ); } #if 0 diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index dbc3705c24..1136dba62d 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -462,6 +462,14 @@ cmd_batch(uint opcode) pos += (1 + ROUNDUP8(sizeof(struct cell_attribute_fetch_code)) / 8); break; } + case CELL_CMD_FLUSH_BUFFER_RANGE: { + struct cell_buffer_range *br = (struct cell_buffer_range *) + &buffer[pos+1]; + + spu_dcache_mark_dirty((unsigned) br->base, br->size); + pos += (1 + ROUNDUP8(sizeof(struct cell_buffer_range)) / 8); + break; + } default: printf("SPU %u: bad opcode: 0x%llx\n", spu.init.id, buffer[pos]); ASSERT(0); diff --git a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c index e5d9910ff3..f7e4e653e3 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c @@ -40,25 +40,7 @@ #include "spu_exec.h" #include "spu_vertex_shader.h" #include "spu_main.h" - -#define CACHE_NAME attribute -#define CACHED_TYPE qword -#define CACHE_TYPE CACHE_TYPE_RO -#define CACHE_SET_TAGID(set) TAG_VERTEX_BUFFER -#define CACHE_LOG2NNWAY 2 -#define CACHE_LOG2NSETS 6 -#include - -/* Yes folks, this is ugly. - */ -#undef CACHE_NWAY -#undef CACHE_NSETS -#define CACHE_NAME attribute -#define CACHE_NWAY 4 -#define CACHE_NSETS (1U << 6) - - -#define DRAW_DBG 0 +#include "spu_dcache.h" typedef void (*spu_fetch_func)(qword *out, const qword *in, const qword *shuffle_data); @@ -102,44 +84,6 @@ static const qword fetch_shuffle_data[5] ALIGN16_ATTRIB = { }; -/** - * Fetch between 1 and 32 bytes from an unaligned address - */ -static INLINE void -fetch_unaligned(qword *dst, unsigned ea, unsigned size) -{ - qword tmp[4] ALIGN16_ATTRIB; - const int shift = ea & 0x0f; - const unsigned aligned_start_ea = ea & ~0x0f; - const unsigned aligned_end_ea = (ea + size) & ~0x0f; - const unsigned num_entries = ((aligned_end_ea - aligned_start_ea) / 16) + 1; - unsigned i; - - - if (shift == 0) { - /* Data is already aligned. Fetch directly into the destination buffer. - */ - for (i = 0; i < num_entries; i++) { - dst[i] = cache_rd(attribute, (ea & ~0x0f) + (i * 16)); - } - } else { - /* Fetch data from the cache to the local buffer. - */ - for (i = 0; i < num_entries; i++) { - tmp[i] = cache_rd(attribute, (ea & ~0x0f) + (i * 16)); - } - - - /* Fix the alignment of the data and write to the destination buffer. - */ - for (i = 0; i < ((size + 15) / 16); i++) { - dst[i] = si_or((qword) spu_slqwbyte(tmp[i], shift), - (qword) spu_rlmaskqwbyte(tmp[i + 1], shift - 16)); - } - } -} - - /** * Fetch vertex attributes for 'count' vertices. */ @@ -182,7 +126,7 @@ static void generic_vertex_fetch(struct spu_vs_context *draw, printf("SPU: fetching = 0x%llx\n", addr); #endif - fetch_unaligned(& in[idx], addr, bytes_per_entry); + spu_dcache_fetch_unaligned(& in[idx], addr, bytes_per_entry); idx += quads_per_entry; } @@ -200,15 +144,5 @@ static void generic_vertex_fetch(struct spu_vs_context *draw, void spu_update_vertex_fetch( struct spu_vs_context *draw ) { - unsigned i; - - - /* Invalidate the vertex cache. - */ - for (i = 0; i < (CACHE_NWAY * CACHE_NSETS); i++) { - CACHELINE_CLEARVALID(i); - } - - draw->vertex_fetch.fetch_func = generic_vertex_fetch; } -- cgit v1.2.3 From 2d1f086c12b6d64f5c3fb80474f26775aeb71370 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 20 Feb 2008 14:45:08 -0800 Subject: Cell: Fix off-by-one error in spu_dcache_fetch_unaligned An off-by-one error caused an extra qword to be fetched under certain alignment / size combinations. --- src/gallium/drivers/cell/spu/spu_dcache.c | 5 +++-- src/gallium/drivers/cell/spu/spu_exec.c | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_dcache.c b/src/gallium/drivers/cell/spu/spu_dcache.c index 9e30e17880..68aa5c4ae8 100644 --- a/src/gallium/drivers/cell/spu/spu_dcache.c +++ b/src/gallium/drivers/cell/spu/spu_dcache.c @@ -22,6 +22,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "cell/common.h" #include "spu_main.h" #include "spu_dcache.h" @@ -50,8 +51,8 @@ spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size) { const int shift = ea & 0x0f; const unsigned aligned_start_ea = ea & ~0x0f; - const unsigned aligned_end_ea = (ea + size) & ~0x0f; - const unsigned num_entries = ((aligned_end_ea - aligned_start_ea) / 16) + 1; + const unsigned aligned_end_ea = ROUNDUP16(ea + size); + const unsigned num_entries = (aligned_end_ea - aligned_start_ea) / 16; unsigned i; diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 94ac6a2885..cf81bee8fd 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -73,6 +73,7 @@ #include "spu_main.h" #include "spu_vertex_shader.h" #include "spu_dcache.h" +#include "cell/common.h" #define TILE_TOP_LEFT 0 #define TILE_TOP_RIGHT 1 @@ -1900,8 +1901,7 @@ spu_exec_machine_run( struct spu_exec_machine *mach ) for (i = 0; i < mach->NumDeclarations; i++) { union { struct tgsi_full_declaration decl; - qword buffer[2 * ((sizeof(struct tgsi_full_declaration) + 31) - / 32)]; + qword buffer[ROUNDUP16(sizeof(struct tgsi_full_declaration)) / 16]; } d ALIGN16_ATTRIB; unsigned ea = (unsigned) (mach->Declarations + pc); @@ -1915,8 +1915,7 @@ spu_exec_machine_run( struct spu_exec_machine *mach ) while (pc != -1) { union { struct tgsi_full_instruction inst; - qword buffer[2 * ((sizeof(struct tgsi_full_instruction) + 31) - / 32)]; + qword buffer[ROUNDUP16(sizeof(struct tgsi_full_instruction)) / 16]; } i ALIGN16_ATTRIB; unsigned ea = (unsigned) (mach->Instructions + pc); -- cgit v1.2.3 From e78fc9f2f4d89b0cae0d56d84dd16cb76a6757dc Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 21 Feb 2008 09:03:29 -0800 Subject: Cell: Initial scalar implementation of spu_dcache_mark_dirty --- src/gallium/drivers/cell/spu/spu_dcache.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_dcache.c b/src/gallium/drivers/cell/spu/spu_dcache.c index 68aa5c4ae8..698a5790bb 100644 --- a/src/gallium/drivers/cell/spu/spu_dcache.c +++ b/src/gallium/drivers/cell/spu/spu_dcache.c @@ -26,6 +26,10 @@ #include "spu_main.h" #include "spu_dcache.h" +#define CACHELINE_LOG2SIZE 7 +#define LINE_SIZE (1U << 7) +#define ALIGN_MASK (~(LINE_SIZE - 1)) + #define CACHE_NAME data #define CACHED_TYPE qword #define CACHE_TYPE CACHE_TYPE_RO @@ -60,7 +64,7 @@ spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size) /* Data is already aligned. Fetch directly into the destination buffer. */ for (i = 0; i < num_entries; i++) { - dst[i] = cache_rd(data, (ea & ~0x0f) + (i * 16)); + dst[i] = cache_rd(data, ea + (i * 16)); } } else { qword tmp[2] ALIGN16_ATTRIB; @@ -85,17 +89,23 @@ spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size) } +/** + * Notify the cache that a range of main memory may have been modified + */ void spu_dcache_mark_dirty(unsigned ea, unsigned size) { unsigned i; + const unsigned aligned_start = (ea & ALIGN_MASK); + const unsigned aligned_end = (ea + size + (LINE_SIZE - 1)) + & ALIGN_MASK; - (void) ea; - (void) size; - /* Invalidate the whole cache for now. - */ for (i = 0; i < (CACHE_NWAY * CACHE_NSETS); i++) { - CACHELINE_CLEARVALID(i); + const unsigned entry = __cache_dir[i]; + const unsigned addr = entry & ~0x0f; + + __cache_dir[i] = ((addr >= aligned_start) && (addr < aligned_end)) + ? (entry & ~CACHELINE_VALID) : entry; } } -- cgit v1.2.3 From 6dd47c264a8642a4e3dbe0b4fc194174743c64fc Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 21 Feb 2008 10:24:29 -0800 Subject: Cell: Add spu_dcache.c to Makefile. This was erroneously missing in previous commits. --- src/gallium/drivers/cell/spu/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/Makefile b/src/gallium/drivers/cell/spu/Makefile index 30ef2450ec..c071de1900 100644 --- a/src/gallium/drivers/cell/spu/Makefile +++ b/src/gallium/drivers/cell/spu/Makefile @@ -18,6 +18,7 @@ PROG_SPU_EMBED_O = $(PROG)_spu-embed.o SOURCES = \ spu_main.c \ spu_blend.c \ + spu_dcache.c \ spu_render.c \ spu_texture.c \ spu_tile.c \ -- cgit v1.2.3 From de5c64e0af0b1a1ce3ee12f361341880dc260868 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 21 Feb 2008 10:32:02 -0800 Subject: Cell: Remove erroneous ALIGN16_ATTRIB attributes If a structure is marked as being aligned the SPE compiler performs extra optimizations (sadly, only -O2 is used) when reading the structure. Since most of the structures sent in batch buffers are only 8-byte aligned, this resulted in mysterous bugs with -O2. --- src/gallium/drivers/cell/common.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index f32ad5bfbe..9a4004535e 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -137,7 +137,7 @@ struct cell_array_info uint pitch; /**< Byte pitch from one entry to the next. */ uint size; uint function_offset; -} ALIGN16_ATTRIB; +}; struct cell_attribute_fetch_code { @@ -162,7 +162,7 @@ struct cell_shader_info unsigned num_declarations; unsigned num_instructions; unsigned num_immediates; -} ALIGN16_ATTRIB; +}; #define SPU_VERTS_PER_BATCH 64 @@ -175,7 +175,7 @@ struct cell_command_vs float plane[12][4]; unsigned nr_planes; unsigned nr_attrs; -} ALIGN16_ATTRIB; +}; struct cell_command_render -- cgit v1.2.3 From 1eaf7b775ba0dacff8a3debd7c0f260970e5a61d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 15 Feb 2008 18:54:00 +0000 Subject: tgsi: print debug messages on failure to codegenerate --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 29a7f842ed..779b901f2b 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -2356,11 +2356,17 @@ tgsi_emit_sse2_fs( ok = emit_instruction( func, &parse.FullToken.FullInstruction ); + + if (!ok) { + debug_printf("failed to translate tgsi opcode %d\n", + parse.FullToken.FullInstruction.Instruction.Opcode ); + } break; case TGSI_TOKEN_TYPE_IMMEDIATE: /* XXX implement this */ ok = 0; + debug_printf("failed to emit immediate value\n"); break; default: -- cgit v1.2.3 From 30479ef11004c9498c4ef09048efc56227f104cc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 15 Feb 2008 18:56:41 +0000 Subject: draw: vertex cache rework Take a baby step to straightening out vertex paths. --- src/gallium/auxiliary/draw/draw_context.c | 8 ++-- src/gallium/auxiliary/draw/draw_prim.c | 2 + src/gallium/auxiliary/draw/draw_private.h | 13 ++++-- src/gallium/auxiliary/draw/draw_vertex_cache.c | 60 ++++++++++++++----------- src/gallium/auxiliary/draw/draw_vertex_shader.c | 7 +-- 5 files changed, 53 insertions(+), 37 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index a7f3b4aecb..b90a9f474d 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -72,10 +72,10 @@ struct draw_context *draw_create( void ) { uint i; const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; - char *tmp = align_malloc(Elements(draw->vcache.vertex) * size, 16); + char *tmp = align_malloc(Elements(draw->vs.queue) * size, 16); - for (i = 0; i < Elements(draw->vcache.vertex); i++) - draw->vcache.vertex[i] = (struct vertex_header *)(tmp + i * size); + for (i = 0; i < Elements(draw->vs.queue); i++) + draw->vs.queue[i].vertex = (struct vertex_header *)(tmp + i * size); } draw->shader_queue_flush = draw_vertex_shader_queue_flush; @@ -108,7 +108,7 @@ void draw_destroy( struct draw_context *draw ) if (draw->pipeline.rasterize) draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); tgsi_exec_machine_free_data(&draw->machine); - align_free( draw->vcache.vertex[0] ); /* Frees all the vertices. */ + align_free( draw->vs.queue[0].vertex ); /* Frees all the vertices. */ FREE( draw ); } diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index dd9a848863..7d6cd43410 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -114,6 +114,7 @@ static void draw_prim_queue_flush( struct draw_context *draw ) } draw->pq.queue_nr = 0; + draw->vs.post_nr = 0; draw_vertex_cache_unreference( draw ); } @@ -226,6 +227,7 @@ static void do_triangle( struct draw_context *draw, { struct prim_header *prim = get_queued_prim( draw, 3 ); +// _mesa_printf("tri %d %d %d\n", i0, i1, i2); prim->reset_line_stipple = 1; prim->edgeflags = ~0; prim->pad = 0; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 6c7e860861..492c152ff9 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -120,7 +120,7 @@ struct draw_stage }; -#define PRIM_QUEUE_LENGTH 16 +#define PRIM_QUEUE_LENGTH 32 #define VCACHE_SIZE 32 #define VCACHE_OVERFLOW 4 #define VS_QUEUE_LENGTH (VCACHE_SIZE + VCACHE_OVERFLOW + 1) /* can never fill up */ @@ -244,8 +244,12 @@ struct draw_context */ struct { unsigned referenced; /**< bitfield */ - unsigned idx[VCACHE_SIZE + VCACHE_OVERFLOW]; - struct vertex_header *vertex[VCACHE_SIZE + VCACHE_OVERFLOW]; + + struct { + unsigned in; /* client array element */ + unsigned out; /* index in vs queue/array */ + } idx[VCACHE_SIZE + VCACHE_OVERFLOW]; + unsigned overflow; /** To find space in the vertex cache: */ @@ -258,9 +262,10 @@ struct draw_context struct { struct { unsigned elt; /**< index into the user's vertex arrays */ - struct vertex_header *dest; /**< points into vcache.vertex[] array */ + struct vertex_header *vertex; } queue[VS_QUEUE_LENGTH]; unsigned queue_nr; + unsigned post_nr; } vs; /** diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c index 44427999cc..53f8bbec44 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_cache.c +++ b/src/gallium/auxiliary/draw/draw_vertex_cache.c @@ -41,7 +41,7 @@ void draw_vertex_cache_invalidate( struct draw_context *draw ) assert(draw->vs.queue_nr == 0); assert(draw->vcache.referenced == 0); - memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx)); +// memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx)); } @@ -62,43 +62,51 @@ static struct vertex_header *get_vertex( struct draw_context *draw, assert(slot < 32); /* so we don't exceed the bitfield size below */ - /* Cache miss? - */ - if (draw->vcache.idx[slot] != i) { - - /* If slot is in use, use the overflow area: + if (draw->vcache.referenced & (1<vcache.referenced & (1 << slot)) { - slot = VCACHE_SIZE + draw->vcache.overflow++; + if (draw->vcache.idx[slot].in == i) { +// _mesa_printf("HIT %d %d\n", slot, i); + assert(draw->vcache.idx[slot].out < draw->vs.queue_nr); + return draw->vs.queue[draw->vcache.idx[slot].out].vertex; } + /* Otherwise a collision + */ + slot = VCACHE_SIZE + draw->vcache.overflow++; +// _mesa_printf("XXX %d --> %d\n", i, slot); + } + + /* Deal with the cache miss: + */ + { + unsigned out; + assert(slot < Elements(draw->vcache.idx)); - draw->vcache.idx[slot] = i; +// _mesa_printf("NEW %d %d\n", slot, i); + draw->vcache.idx[slot].in = i; + draw->vcache.idx[slot].out = out = draw->vs.queue_nr++; + draw->vcache.referenced |= (1 << slot); + /* Add to vertex shader queue: */ assert(draw->vs.queue_nr < VS_QUEUE_LENGTH); - draw->vs.queue[draw->vs.queue_nr].dest = draw->vcache.vertex[slot]; - draw->vs.queue[draw->vs.queue_nr].elt = i; - draw->vs.queue_nr++; + + draw->vs.queue[out].elt = i; + draw->vs.queue[out].vertex->clipmask = 0; + draw->vs.queue[out].vertex->edgeflag = 1; /*XXX use user's edge flag! */ + draw->vs.queue[out].vertex->pad = 0; + draw->vs.queue[out].vertex->vertex_id = UNDEFINED_VERTEX_ID; /* Need to set the vertex's edge flag here. If we're being called * by do_ef_triangle(), that function needs edge flag info! */ - draw->vcache.vertex[slot]->clipmask = 0; - draw->vcache.vertex[slot]->edgeflag = 1; /*XXX use user's edge flag! */ - draw->vcache.vertex[slot]->pad = 0; - draw->vcache.vertex[slot]->vertex_id = UNDEFINED_VERTEX_ID; - } - - /* primitive flushing may have cleared the bitfield but did not - * clear the idx[] array values. Set the bit now. This fixes a - * bug found when drawing long triangle fans. - */ - draw->vcache.referenced |= (1 << slot); - return draw->vcache.vertex[slot]; + return draw->vs.queue[draw->vcache.idx[slot].out].vertex; + } } @@ -130,8 +138,8 @@ void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ) { unsigned i; - for (i = 0; i < Elements(draw->vcache.vertex); i++) - draw->vcache.vertex[i]->vertex_id = UNDEFINED_VERTEX_ID; + for (i = 0; i < draw->vs.post_nr; i++) + draw->vs.queue[i].vertex->vertex_id = UNDEFINED_VERTEX_ID; } diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index f68f6e3244..5d2f5c9c43 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -55,7 +55,7 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) */ shader->prepare( shader, draw ); -// fprintf(stderr, " q(%d) ", draw->vs.queue_nr ); +// fprintf(stderr, "%s %d\n", __FUNCTION__, draw->vs.queue_nr ); /* run vertex shader on vertex cache entries, four per invokation */ for (i = 0; i < draw->vs.queue_nr; i += 4) { @@ -65,12 +65,12 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) for (j = 0; j < n; j++) { elts[j] = draw->vs.queue[i + j].elt; - dests[j] = draw->vs.queue[i + j].dest; + dests[j] = draw->vs.queue[i + j].vertex; } for ( ; j < 4; j++) { elts[j] = elts[0]; - dests[j] = dests[0]; + dests[j] = draw->vs.queue[i + j].vertex; } assert(n > 0); @@ -79,6 +79,7 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) shader->run(shader, draw, elts, n, dests); } + draw->vs.post_nr = draw->vs.queue_nr; draw->vs.queue_nr = 0; } -- cgit v1.2.3 From 4339744c1676f925d42251bd32795bba9928cd5f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 21 Feb 2008 10:07:58 +0000 Subject: [PATCH] gallium: include p_compiler.h for boolean defn --- src/gallium/include/pipe/p_shader_tokens.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 3ce35310f6..10c47e0ef0 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -5,6 +5,8 @@ extern "C" { #endif // defined __cplusplus +#include "p_compiler.h" + struct tgsi_version { unsigned MajorVersion : 8; -- cgit v1.2.3 From 20fbcbf5801c28865c0bfab3cda45302c8474a66 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 21 Feb 2008 19:07:31 +0000 Subject: [PATCH] softpipe: unbreak sp_setup_pos_vector on non-x86 systems --- src/gallium/drivers/softpipe/sp_fs_exec.c | 35 +++++++++++++++++++++++++++++++ src/gallium/drivers/softpipe/sp_fs_sse.c | 35 ------------------------------- 2 files changed, 35 insertions(+), 35 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index 9ad30a7681..8cb0534342 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -44,6 +44,41 @@ struct sp_exec_fragment_shader { +/** + * Compute quad X,Y,Z,W for the four fragments in a quad. + * + * This should really be part of the compiled shader. + */ +void +sp_setup_pos_vector(const struct tgsi_interp_coef *coef, + float x, float y, + struct tgsi_exec_vector *quadpos) +{ + uint chan; + /* do X */ + quadpos->xyzw[0].f[0] = x; + quadpos->xyzw[0].f[1] = x + 1; + quadpos->xyzw[0].f[2] = x; + quadpos->xyzw[0].f[3] = x + 1; + + /* do Y */ + quadpos->xyzw[1].f[0] = y; + quadpos->xyzw[1].f[1] = y; + quadpos->xyzw[1].f[2] = y + 1; + quadpos->xyzw[1].f[3] = y + 1; + + /* do Z and W for all fragments in the quad */ + for (chan = 2; chan < 4; chan++) { + const float dadx = coef->dadx[chan]; + const float dady = coef->dady[chan]; + const float a0 = coef->a0[chan] + dadx * x + dady * y; + quadpos->xyzw[chan].f[0] = a0; + quadpos->xyzw[chan].f[1] = a0 + dadx; + quadpos->xyzw[chan].f[2] = a0 + dady; + quadpos->xyzw[chan].f[3] = a0 + dadx + dady; + } +} + static void exec_prepare( struct sp_fragment_shader *base, diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 53050b7823..8095d662ee 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -63,41 +63,6 @@ struct sp_sse_fragment_shader { }; -/** - * Compute quad X,Y,Z,W for the four fragments in a quad. - * - * This should really be part of the compiled shader. - */ -void -sp_setup_pos_vector(const struct tgsi_interp_coef *coef, - float x, float y, - struct tgsi_exec_vector *quadpos) -{ - uint chan; - /* do X */ - quadpos->xyzw[0].f[0] = x; - quadpos->xyzw[0].f[1] = x + 1; - quadpos->xyzw[0].f[2] = x; - quadpos->xyzw[0].f[3] = x + 1; - - /* do Y */ - quadpos->xyzw[1].f[0] = y; - quadpos->xyzw[1].f[1] = y; - quadpos->xyzw[1].f[2] = y + 1; - quadpos->xyzw[1].f[3] = y + 1; - - /* do Z and W for all fragments in the quad */ - for (chan = 2; chan < 4; chan++) { - const float dadx = coef->dadx[chan]; - const float dady = coef->dady[chan]; - const float a0 = coef->a0[chan] + dadx * x + dady * y; - quadpos->xyzw[chan].f[0] = a0; - quadpos->xyzw[chan].f[1] = a0 + dadx; - quadpos->xyzw[chan].f[2] = a0 + dady; - quadpos->xyzw[chan].f[3] = a0 + dadx + dady; - } -} - static void fs_sse_prepare( struct sp_fragment_shader *base, -- cgit v1.2.3 From d4d2e36a429fd015316c484fc40be7e6d2c69946 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 21 Feb 2008 08:37:49 -0700 Subject: gallium: comments, white-space clean-up --- src/gallium/include/pipe/p_state.h | 53 +++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 23 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 1082343e2f..47fa78c31d 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -66,7 +66,8 @@ struct pipe_winsys; * The driver will certainly subclass this to include actual memory * management information. */ -struct pipe_buffer { +struct pipe_buffer +{ unsigned alignment; unsigned usage; unsigned size; @@ -76,8 +77,6 @@ struct pipe_buffer { }; - - /** * Primitive (point/line/tri) rasterization info */ @@ -113,18 +112,21 @@ struct pipe_rasterizer_state }; -struct pipe_poly_stipple { +struct pipe_poly_stipple +{ unsigned stipple[32]; }; -struct pipe_viewport_state { +struct pipe_viewport_state +{ float scale[4]; float translate[4]; }; -struct pipe_scissor_state { +struct pipe_scissor_state +{ unsigned minx:16; unsigned miny:16; unsigned maxx:16; @@ -132,7 +134,8 @@ struct pipe_scissor_state { }; -struct pipe_clip_state { +struct pipe_clip_state +{ float ucp[PIPE_MAX_CLIP_PLANES][4]; unsigned nr; }; @@ -141,13 +144,15 @@ struct pipe_clip_state { /** * Constants for vertex/fragment shaders */ -struct pipe_constant_buffer { +struct pipe_constant_buffer +{ struct pipe_buffer *buffer; unsigned size; /** in bytes */ }; -struct pipe_shader_state { +struct pipe_shader_state +{ const struct tgsi_token *tokens; ubyte num_inputs; ubyte num_outputs; @@ -185,7 +190,8 @@ struct pipe_depth_stencil_alpha_state }; -struct pipe_blend_state { +struct pipe_blend_state +{ unsigned blend_enable:1; unsigned rgb_func:3; /**< PIPE_BLEND_x */ @@ -204,7 +210,8 @@ struct pipe_blend_state { }; -struct pipe_blend_color { +struct pipe_blend_color +{ float color[4]; }; @@ -224,19 +231,19 @@ struct pipe_framebuffer_state */ struct pipe_sampler_state { - unsigned wrap_s:3; /**< PIPE_TEX_WRAP_x */ - unsigned wrap_t:3; /**< PIPE_TEX_WRAP_x */ - unsigned wrap_r:3; /**< PIPE_TEX_WRAP_x */ + unsigned wrap_s:3; /**< PIPE_TEX_WRAP_x */ + unsigned wrap_t:3; /**< PIPE_TEX_WRAP_x */ + unsigned wrap_r:3; /**< PIPE_TEX_WRAP_x */ unsigned min_img_filter:2; /**< PIPE_TEX_FILTER_x */ unsigned min_mip_filter:2; /**< PIPE_TEX_MIPFILTER_x */ unsigned mag_img_filter:2; /**< PIPE_TEX_FILTER_x */ - unsigned compare:1; /**< shadow/depth compare enabled? */ - unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ - unsigned compare_func:3; /**< PIPE_FUNC_x */ - unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ - float shadow_ambient; /**< shadow test fail color/intensity */ - float lod_bias; /**< LOD/lambda bias */ - float min_lod, max_lod; /**< LOD clamp range, after bias */ + unsigned compare:1; /**< shadow/depth compare enabled? */ + unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ + unsigned compare_func:3; /**< PIPE_FUNC_x */ + unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ + float shadow_ambient; /**< shadow test fail color/intensity */ + float lod_bias; /**< LOD/lambda bias */ + float min_lod, max_lod; /**< LOD clamp range, after bias */ float border_color[4]; float max_anisotropy; }; @@ -248,10 +255,10 @@ struct pipe_sampler_state */ struct pipe_surface { - struct pipe_buffer *buffer; /**< driver private buffer handle */ + struct pipe_buffer *buffer; /**< surface's buffer/memory */ enum pipe_format format; /**< PIPE_FORMAT_x */ unsigned status; /**< PIPE_SURFACE_STATUS_x */ - unsigned clear_value; /**< may be temporary */ + unsigned clear_value; /**< XXX may be temporary */ unsigned cpp; /**< bytes per pixel */ unsigned width; unsigned height; -- cgit v1.2.3 From eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 21 Feb 2008 16:18:05 -0700 Subject: gallium: new AA point drawing stage AA points are drawn by converting the point to a quad, then modifying the user's fragment shader to compute a coverage value. The final fragment color's alpha is modulated by the coverage value. Fragments outside the point's radius are killed. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_aapoint.c | 875 +++++++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_context.c | 2 + src/gallium/auxiliary/draw/draw_context.h | 3 + src/gallium/auxiliary/draw/draw_private.h | 1 + src/gallium/auxiliary/draw/draw_validate.c | 5 + src/gallium/drivers/softpipe/sp_context.c | 6 +- 7 files changed, 892 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/draw/draw_aapoint.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 1ee9eca0ca..b7e71ed3ec 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -5,6 +5,7 @@ LIBNAME = draw C_SOURCES = \ draw_aaline.c \ + draw_aapoint.c \ draw_clip.c \ draw_vs_exec.c \ draw_vs_sse.c \ diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c new file mode 100644 index 0000000000..43119cc70b --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -0,0 +1,875 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * AA point stage: AA points are converted to quads and rendered with a + * special fragment shader. Another approach would be to use a texture + * map image of a point, but experiments indicate the quality isn't nearly + * as good as this approach. + * + * Note: this looks a lot like draw_aaline.c but there's actually little + * if any code that can be shared. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_private.h" + + +/* + * Enabling NORMALIZE might give _slightly_ better results. + * Basically, it controls whether we compute distance as d=sqrt(x*x+y*y) or + * d=x*x+y*y. Since we're working with a unit circle, the later seems + * close enough and saves some costly instructions. + */ +#define NORMALIZE 0 + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct aapoint_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; /**< the regular shader */ + void *aapoint_fs; /**< the aa point-augmented shader */ +}; + + +/** + * Subclass of draw_stage + */ +struct aapoint_stage +{ + struct draw_stage stage; + + int psize_slot; + float radius; + + /** this is the vertex attrib slot for the new texcoords */ + uint tex_slot; + + /* + * Currently bound state + */ + struct aapoint_fragment_shader *fs; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct aa_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int colorOutput; /**< which output is the primary color */ + int maxInput, maxGeneric; /**< max input index found */ + int tmp0, colorTemp; /**< temp registers */ + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for two free temp regs and available input reg for new texcoords. + */ +static void +aa_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_OUTPUT && + decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && + decl->Semantic.SemanticIndex == 0) { + aactx->colorOutput = decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) + aactx->maxInput = decl->u.DeclarationRange.Last; + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && + (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { + aactx->maxGeneric = decl->Semantic.SemanticIndex; + } + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + aactx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +aa_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + struct tgsi_full_instruction newInst; + + if (aactx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + const int texInput = aactx->maxInput + 1; + int tmp0; + uint i; + + /* find two free temp regs */ + for (i = 0; i < 32; i++) { + if ((aactx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (aactx->tmp0 < 0) + aactx->tmp0 = i; + else if (aactx->colorTemp < 0) + aactx->colorTemp = i; + else + break; + } + } + + assert(aactx->colorTemp != aactx->tmp0); + + tmp0 = aactx->tmp0; + + /* declare new generic input/texcoord */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; + decl.Declaration.Interpolate = 1; + /* XXX this could be linear... */ + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = texInput; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = tmp0; + ctx->emit_declaration(ctx, &decl); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->colorTemp; + ctx->emit_declaration(ctx, &decl); + + aactx->firstInstruction = FALSE; + + + /* + * Emit code to compute fragment coverage, kill if outside point radius + * + * Temp reg0 usage: + * t0.x = distance of fragment from center point + * t0.y = boolean, is t0.x > 1 ? + * t0.z = temporary for computing 1/(1-k) value + * t0.w = final coverage value + */ + + /* MUL t0.xy, tex, tex; # compute x^2, y^2 */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XY; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + ctx->emit_instruction(ctx, &newInst); + + /* ADD t0.x, t0.x, t0.y; # x^2 + y^2 */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_ADD; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + ctx->emit_instruction(ctx, &newInst); + +#if NORMALIZE /* OPTIONAL normalization of length */ + /* RSQ t0.x, t0.x; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RSQ; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + ctx->emit_instruction(ctx, &newInst); + + /* RCP t0.x, t0.x; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RCP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + ctx->emit_instruction(ctx, &newInst); +#endif + + /* SGT t0.y, t0.xxxx, t0.wwww; # bool b = d > 1 (NOTE t0.w == 1) */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SGT; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + ctx->emit_instruction(ctx, &newInst); + + /* KILP -t0.yyyy; # if b, KILL */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_KILP; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; + ctx->emit_instruction(ctx, &newInst); + + /* SGT t0.y, t0.x, tex.z; # bool b = distance > k */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SGT; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* IF t0.y # if b then */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_IF; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + ctx->emit_instruction(ctx, &newInst); + + { + /* compute coverage factor = (1-d)/(1-k) */ + + /* SUB t0.z, tex.w, tex.z; # m = 1 - k */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SUB; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* RCP t0.z, t0.z; # t0.z = 1 / m */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RCP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* SUB t0.x, 1, t0.x; # d = 1 - d */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SUB; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + ctx->emit_instruction(ctx, &newInst); + + /* MUL t0.w, t0.x, t0.z; # coverage = d * m */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + } + + /* ELSE */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_ELSE; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 0; + ctx->emit_instruction(ctx, &newInst); + + { + /* MOV t0.w, tex.w; # coverage = 1.0 */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MOV; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + ctx->emit_instruction(ctx, &newInst); + } + + /* ENDIF */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_ENDIF; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 0; + ctx->emit_instruction(ctx, &newInst); + } + + if (inst->Instruction.Opcode == TGSI_OPCODE_END) { + /* add alpha modulation code at tail of program */ + + /* MOV result.color.xyz, colorTemp; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MOV; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + ctx->emit_instruction(ctx, &newInst); + + /* MUL result.color.w, colorTemp, tmp0.w; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->tmp0; + ctx->emit_instruction(ctx, &newInst); + } + else { + /* Not an END instruction. + * Look for writes to result.color and replace with colorTemp reg. + */ + uint i; + + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + if (dst->DstRegister.File == TGSI_FILE_OUTPUT && + dst->DstRegister.Index == aactx->colorOutput) { + dst->DstRegister.File = TGSI_FILE_TEMPORARY; + dst->DstRegister.Index = aactx->colorTemp; + } + } + } + + ctx->emit_instruction(ctx, inst); +} + + +/** + * Generate the frag shader we'll use for drawing AA lines. + * This will be the user's shader plus some texture/modulate instructions. + */ +static void +generate_aapoint_fs(struct aapoint_stage *aapoint) +{ + const struct pipe_shader_state *orig_fs = &aapoint->fs->state; + struct draw_context *draw = aapoint->stage.draw; + struct pipe_shader_state aapoint_fs; + struct aa_transform_context transform; + +#define MAX 1000 + + aapoint_fs = *orig_fs; /* copy to init */ + aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.colorOutput = -1; + transform.maxInput = -1; + transform.maxGeneric = -1; + transform.colorTemp = -1; + transform.tmp0 = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = aa_transform_inst; + transform.base.transform_declaration = aa_transform_decl; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) aapoint_fs.tokens, + MAX, &transform.base); + +#if 0 /* DEBUG */ + tgsi_dump(orig_fs->tokens, 0); + tgsi_dump(aapoint_fs.tokens, 0); +#endif + + aapoint_fs.input_semantic_name[aapoint_fs.num_inputs] = TGSI_SEMANTIC_GENERIC; + aapoint_fs.input_semantic_index[aapoint_fs.num_inputs] = transform.maxGeneric + 1; + aapoint_fs.num_inputs++; + + aapoint->fs->aapoint_fs + = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs); + + /* advertise the extra post-transform vertex attributes which will have + * the texcoords. + */ + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; + draw->extra_vp_outputs.semantic_index = transform.maxGeneric + 1; +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_aapoint_fragment_shader(struct aapoint_stage *aapoint) +{ + if (!aapoint->fs->aapoint_fs) { + generate_aapoint_fs(aapoint); + } + aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs); +} + + + +static INLINE struct aapoint_stage * +aapoint_stage( struct draw_stage *stage ) +{ + return (struct aapoint_stage *) stage; +} + + +static void +passthrough_line(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->line(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw an AA point by drawing a quad. + */ +static void +aapoint_point(struct draw_stage *stage, struct prim_header *header) +{ + const struct aapoint_stage *aapoint = aapoint_stage(stage); + struct prim_header tri; + struct vertex_header *v[4]; + uint texPos = aapoint->tex_slot; + float radius, *pos, *tex; + uint i; + float k; + + if (aapoint->psize_slot >= 0) { + radius = 0.5f * header->v[0]->data[aapoint->psize_slot][0]; + } + else { + radius = aapoint->radius; + } + + /* + * Note: the texcoords (generic attrib, really) we use are special: + * The S and T components simply vary from -1 to +1. + * The R component is k, below. + * The Q component is 1.0 and will used as a handy constant in the + * fragment shader. + */ + + /* + * k is the threshold distance from the point's center at which + * we begin alpha attenuation (the coverage value). + * Operating within a unit circle, we'll compute the fragment's + * distance 'd' from the center point using the texcoords. + * IF d > 1.0 THEN + * KILL fragment + * ELSE IF d > k THEN + * compute coverage in [0,1] proportional to d in [k, 1]. + * ELSE + * coverage = 1.0; // full coverage + * ENDIF + */ + +#if !NORMALIZE + k = 1.0 / radius; + k = 1.0 - 2.0 * k + k * k; +#else + k = 1.0 - 1.0 / radius; +#endif + + /* allocate/dup new verts */ + for (i = 0; i < 4; i++) { + v[i] = dup_vert(stage, header->v[0], i); + } + + /* new verts */ + pos = v[0]->data[0]; + pos[0] -= radius; + pos[1] -= radius; + + pos = v[1]->data[0]; + pos[0] += radius; + pos[1] -= radius; + + pos = v[2]->data[0]; + pos[0] += radius; + pos[1] += radius; + + pos = v[3]->data[0]; + pos[0] -= radius; + pos[1] += radius; + + /* new texcoords */ + tex = v[0]->data[texPos]; + ASSIGN_4V(tex, -1, -1, k, 1); + + tex = v[1]->data[texPos]; + ASSIGN_4V(tex, 1, -1, k, 1); + + tex = v[2]->data[texPos]; + ASSIGN_4V(tex, 1, 1, k, 1); + + tex = v[3]->data[texPos]; + ASSIGN_4V(tex, -1, 1, k, 1); + + /* emit 2 tris for the quad strip */ + tri.v[0] = v[0]; + tri.v[1] = v[1]; + tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[0]; + tri.v[1] = v[2]; + tri.v[2] = v[3]; + stage->next->tri( stage->next, &tri ); +} + + +static void +aapoint_first_point(struct draw_stage *stage, struct prim_header *header) +{ + auto struct aapoint_stage *aapoint = aapoint_stage(stage); + struct draw_context *draw = stage->draw; + + assert(draw->rasterizer->point_smooth); + + if (draw->rasterizer->point_size <= 2.0) + aapoint->radius = 1.0; + else + aapoint->radius = 0.5f * draw->rasterizer->point_size; + + aapoint->tex_slot = draw->num_vs_outputs; + assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ + draw->extra_vp_outputs.slot = aapoint->tex_slot; + + /* + * Bind our fragprog. + */ + bind_aapoint_fragment_shader(aapoint); + + /* find psize slot in post-transform vertex */ + aapoint->psize_slot = -1; + if (draw->rasterizer->point_size_per_vertex) { + /* find PSIZ vertex output */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i; + for (i = 0; i < vs->state->num_outputs; i++) { + if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + aapoint->psize_slot = i; + break; + } + } + } + + /* now really draw first line */ + stage->point = aapoint_point; + stage->point(stage, header); +} + + +static void +aapoint_flush(struct draw_stage *stage, unsigned flags) +{ + struct draw_context *draw = stage->draw; + struct aapoint_stage *aapoint = aapoint_stage(stage); + struct pipe_context *pipe = aapoint->pipe; + + stage->point = aapoint_first_point; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs); + + draw->extra_vp_outputs.slot = 0; +} + + +static void +aapoint_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +aapoint_destroy(struct draw_stage *stage) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +static struct aapoint_stage * +draw_aapoint_stage(struct draw_context *draw) +{ + struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage); + + draw_alloc_temp_verts( &aapoint->stage, 4 ); + + aapoint->stage.draw = draw; + aapoint->stage.next = NULL; + aapoint->stage.point = aapoint_first_point; + aapoint->stage.line = passthrough_line; + aapoint->stage.tri = passthrough_tri; + aapoint->stage.flush = aapoint_flush; + aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter; + aapoint->stage.destroy = aapoint_destroy; + + return aapoint; +} + + +/* + * XXX temporary? solution to mapping a pipe_context to a aapoint_stage. + */ + +#define MAX_CONTEXTS 10 + +static struct pipe_context *Pipe[MAX_CONTEXTS]; +static struct aapoint_stage *Stage[MAX_CONTEXTS]; +static uint NumContexts; + +static void +add_aa_pipe_context(struct pipe_context *pipe, struct aapoint_stage *aa) +{ + assert(NumContexts < MAX_CONTEXTS); + Pipe[NumContexts] = pipe; + Stage[NumContexts] = aa; + NumContexts++; +} + +static struct aapoint_stage * +aapoint_stage_from_pipe(struct pipe_context *pipe) +{ + uint i; + for (i = 0; i < NumContexts; i++) { + if (Pipe[i] == pipe) + return Stage[i]; + } + assert(0); + return NULL; +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +aapoint_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs); + } + + return aafs; +} + + +static void +aapoint_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; + /* save current */ + aapoint->fs = aafs; + /* pass-through */ + aapoint->driver_bind_fs_state(aapoint->pipe, aafs->driver_fs); +} + + +static void +aapoint_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; + /* pass-through */ + aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs); + FREE(aafs); +} + + +/** + * Called by drivers that want to install this AA point prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA points. + */ +void +draw_install_aapoint_stage(struct draw_context *draw, + struct pipe_context *pipe) +{ + struct aapoint_stage *aapoint; + + /* + * Create / install AA point drawing / prim stage + */ + aapoint = draw_aapoint_stage( draw ); + assert(aapoint); + draw->pipeline.aapoint = &aapoint->stage; + + aapoint->pipe = pipe; + + /* save original driver functions */ + aapoint->driver_create_fs_state = pipe->create_fs_state; + aapoint->driver_bind_fs_state = pipe->bind_fs_state; + aapoint->driver_delete_fs_state = pipe->delete_fs_state; + + /* override the driver's functions */ + pipe->create_fs_state = aapoint_create_fs_state; + pipe->bind_fs_state = aapoint_bind_fs_state; + pipe->delete_fs_state = aapoint_delete_fs_state; + + add_aa_pipe_context(pipe, aapoint); +} diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index b90a9f474d..c28e78d33a 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -105,6 +105,8 @@ void draw_destroy( struct draw_context *draw ) draw->pipeline.validate->destroy( draw->pipeline.validate ); if (draw->pipeline.aaline) draw->pipeline.aaline->destroy( draw->pipeline.aaline ); + if (draw->pipeline.aapoint) + draw->pipeline.aapoint->destroy( draw->pipeline.aapoint ); if (draw->pipeline.rasterize) draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); tgsi_exec_machine_free_data(&draw->machine); diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 82035aa8ad..43b58bc056 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -99,6 +99,9 @@ boolean draw_use_sse(struct draw_context *draw); void draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); +void +draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe); + int draw_find_vs_output(struct draw_context *draw, diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 492c152ff9..8c469e74b7 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -180,6 +180,7 @@ struct draw_context struct draw_stage *offset; struct draw_stage *unfilled; struct draw_stage *stipple; + struct draw_stage *aapoint; struct draw_stage *aaline; struct draw_stage *wide; struct draw_stage *rasterize; diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index 97e40e372b..5167ef1e75 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -63,6 +63,11 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) next = draw->pipeline.aaline; } + if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) { + draw->pipeline.aapoint->next = next; + next = draw->pipeline.aapoint; + } + if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines && !draw->rasterizer->line_smooth) || (draw->rasterizer->point_size != 1.0 && draw->convert_wide_points) || diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 316020cba6..de4c6c18e7 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -328,8 +328,12 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, draw_set_rasterize_stage(softpipe->draw, softpipe->setup); } - /* enable aaline stage */ + /* plug in AA line/point stages */ draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); + draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); + + /* sp_prim_setup can do wide points (don't convert to quads) */ + draw_convert_wide_points(softpipe->draw, FALSE); sp_init_surface_functions(softpipe); -- cgit v1.2.3 From 446bfc32a83008e0865ec869bc80b920c907f10f Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 21 Feb 2008 16:56:32 -0700 Subject: gallium: new draw stage for polygon stipple. For hardware without native polygon stipple. Create a 32x32 alpha texture that encodes the stipple pattern. Modify the user's fragment program to sample the texture (with gl_FragCoord) and kill the fragment according to the texel value. Temporarily enabled in softpipe driver, replacing the sp_quad_stipple.c step. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_context.h | 3 + src/gallium/auxiliary/draw/draw_private.h | 1 + src/gallium/auxiliary/draw/draw_pstipple.c | 717 +++++++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_validate.c | 6 + src/gallium/drivers/softpipe/sp_context.c | 5 + src/gallium/drivers/softpipe/sp_context.h | 7 + src/gallium/drivers/softpipe/sp_quad.c | 2 + 8 files changed, 742 insertions(+) create mode 100644 src/gallium/auxiliary/draw/draw_pstipple.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index b7e71ed3ec..c9980f0b83 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -16,6 +16,7 @@ C_SOURCES = \ draw_flatshade.c \ draw_offset.c \ draw_prim.c \ + draw_pstipple.c \ draw_stipple.c \ draw_twoside.c \ draw_unfilled.c \ diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 43b58bc056..c25301f71d 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -102,6 +102,9 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); void draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe); +void +draw_install_pstipple_stage(struct draw_context *draw, struct pipe_context *pipe); + int draw_find_vs_output(struct draw_context *draw, diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 8c469e74b7..6abced139b 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -182,6 +182,7 @@ struct draw_context struct draw_stage *stipple; struct draw_stage *aapoint; struct draw_stage *aaline; + struct draw_stage *pstipple; struct draw_stage *wide; struct draw_stage *rasterize; } pipeline; diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c new file mode 100644 index 0000000000..4048abf856 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -0,0 +1,717 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Polygon stipple stage: implement polygon stipple with texture map and + * fragment program. The fragment program samples the texture and does + * a fragment kill for the stipple-failing fragments. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_private.h" + + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct pstip_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; + void *pstip_fs; +}; + + +/** + * Subclass of draw_stage + */ +struct pstip_stage +{ + struct draw_stage stage; + + void *sampler_cso; + struct pipe_texture *texture; + uint sampler_unit; + + /* + * Currently bound state + */ + struct pstip_fragment_shader *fs; + struct { + void *sampler[PIPE_MAX_SAMPLERS]; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + const struct pipe_poly_stipple *stipple; + } state; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *); + + void (*driver_set_sampler_texture)(struct pipe_context *, + unsigned sampler, + struct pipe_texture *); + + void (*driver_set_polygon_stipple)(struct pipe_context *, + const struct pipe_poly_stipple *); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct pstip_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int wincoordInput; + int maxInput; + int maxSampler; /**< max sampler index found */ + int texTemp; /**< temp registers */ + int numImmed; + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for a free sampler, a free input attrib, and two free temp regs. + */ +static void +pstip_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_SAMPLER) { + if ((int) decl->u.DeclarationRange.Last > pctx->maxSampler) + pctx->maxSampler = (int) decl->u.DeclarationRange.Last; + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + pctx->maxInput = MAX2(pctx->maxInput, decl->u.DeclarationRange.Last); + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) + pctx->wincoordInput = (int) decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + pctx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +static void +pstip_transform_immed(struct tgsi_transform_context *ctx, + struct tgsi_full_immediate *immed) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + pctx->numImmed++; +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +pstip_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + + if (pctx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction newInst; + uint i; + int wincoordInput; + const int sampler = pctx->maxSampler + 1; + + if (pctx->wincoordInput < 0) + wincoordInput = pctx->maxInput + 1; + else + wincoordInput = pctx->wincoordInput; + + /* find one free temp reg */ + for (i = 0; i < 32; i++) { + if ((pctx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (pctx->texTemp < 0) + pctx->texTemp = i; + else + break; + } + } + assert(pctx->texTemp >= 0); + + if (pctx->wincoordInput < 0) { + /* declare new position input reg */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; + decl.Semantic.SemanticIndex = 0; + decl.Declaration.Interpolate = 1; + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */ + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = wincoordInput; + ctx->emit_declaration(ctx, &decl); + } + + /* declare new sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = sampler; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = pctx->texTemp; + ctx->emit_declaration(ctx, &decl); + + /* emit immediate = {1/32, 1/32, 1, 1} + * The index/position of this immediate will be pctx->numImmed + */ + { + static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 }; + struct tgsi_full_immediate immed; + uint size = 4; + immed = tgsi_default_full_immediate(); + immed.Immediate.Size = 1 + size; /* one for the token itself */ + immed.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value; + ctx->emit_immediate(ctx, &immed); + } + + pctx->firstInstruction = FALSE; + + + /* + * Insert new MUL/TEX/KILP instructions at start of program + * Take gl_FragCoord, divide by 32 (stipple size), sample the + * texture and kill fragment if needed. + * + * We'd like to use non-normalized texcoords to index into a RECT + * texture, but we can only use GL_REPEAT wrap mode with normalized + * texcoords. Darn. + */ + + /* MUL texTemp, INPUT[wincoord], 1/32; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = wincoordInput; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_IMMEDIATE; + newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->numImmed; + ctx->emit_instruction(ctx, &newInst); + + /* TEX texTemp, texTemp, sampler; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_TEX; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + newInst.FullSrcRegisters[1].SrcRegister.Index = sampler; + ctx->emit_instruction(ctx, &newInst); + + /* KILP texTemp; # if texTemp < 0, KILL fragment */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_KILP; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; + newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; + ctx->emit_instruction(ctx, &newInst); + } + + /* emit this instruction */ + ctx->emit_instruction(ctx, inst); +} + + +/** + * Generate the frag shader we'll use for doing polygon stipple. + * This will be the user's shader prefixed with a TEX and KIL instruction. + */ +static void +generate_pstip_fs(struct pstip_stage *pstip) +{ + const struct pipe_shader_state *orig_fs = &pstip->fs->state; + /*struct draw_context *draw = pstip->stage.draw;*/ + struct pipe_shader_state pstip_fs; + struct pstip_transform_context transform; + +#define MAX 1000 + + pstip_fs = *orig_fs; /* copy to init */ + pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.wincoordInput = -1; + transform.maxInput = -1; + transform.maxSampler = -1; + transform.texTemp = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = pstip_transform_inst; + transform.base.transform_declaration = pstip_transform_decl; + transform.base.transform_immediate = pstip_transform_immed; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) pstip_fs.tokens, + MAX, &transform.base); + +#if 1 /* DEBUG */ + tgsi_dump(orig_fs->tokens, 0); + tgsi_dump(pstip_fs.tokens, 0); +#endif + + pstip->sampler_unit = transform.maxSampler + 1; + + if (transform.wincoordInput < 0) { + pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION; + pstip_fs.input_semantic_index[pstip_fs.num_inputs] = transform.maxInput; + pstip_fs.num_inputs++; + } + + pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); +} + + +/** + * Load texture image with current stipple pattern. + */ +static void +pstip_update_texture(struct pstip_stage *pstip) +{ + static const uint bit31 = 1 << 31; + struct pipe_context *pipe = pstip->pipe; + struct pipe_surface *surface; + const uint *stipple = pstip->state.stipple->stipple; + uint i, j; + ubyte *data; + + surface = pipe->get_tex_surface(pipe, pstip->texture, 0, 0, 0); + data = pipe_surface_map(surface); + + /* + * Load alpha texture. + * Note: 0 means keep the fragment, 255 means kill it. + * We'll negate the texel value and use KILP which kills if value + * is negative. + */ + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + if (stipple[i] & (bit31 >> j)) { + /* fragment "on" */ + data[i * surface->pitch + j] = 0; + } + else { + /* fragment "off" */ + data[i * surface->pitch + j] = 255; + } + } + } + + /* unmap */ + pipe_surface_unmap(surface); + pipe_surface_reference(&surface, NULL); + pipe->texture_update(pipe, pstip->texture); +} + + +/** + * Create the texture map we'll use for stippling. + */ +static void +pstip_create_texture(struct pstip_stage *pstip) +{ + struct pipe_context *pipe = pstip->pipe; + struct pipe_texture texTemp; + + memset(&texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ + texTemp.last_level = 0; + texTemp.width[0] = 32; + texTemp.height[0] = 32; + texTemp.depth[0] = 1; + texTemp.cpp = 1; + + pstip->texture = pipe->texture_create(pipe, &texTemp); + + //pstip_update_texture(pstip); +} + + +/** + * Create the sampler CSO that'll be used for antialiasing. + * By using a mipmapped texture, we don't have to generate a different + * texture image for each line size. + */ +static void +pstip_create_sampler(struct pstip_stage *pstip) +{ + struct pipe_sampler_state sampler; + struct pipe_context *pipe = pstip->pipe; + + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_REPEAT; + sampler.wrap_t = PIPE_TEX_WRAP_REPEAT; + sampler.wrap_r = PIPE_TEX_WRAP_REPEAT; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.normalized_coords = 1; + sampler.min_lod = 0.0f; + sampler.max_lod = 0.0f; + + pstip->sampler_cso = pipe->create_sampler_state(pipe, &sampler); +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_pstip_fragment_shader(struct pstip_stage *pstip) +{ + if (!pstip->fs->pstip_fs) { + generate_pstip_fs(pstip); + } + pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs); +} + + + +static INLINE struct pstip_stage * +pstip_stage( struct draw_stage *stage ) +{ + return (struct pstip_stage *) stage; +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point(stage->next, header); +} + + +static void +passthrough_line(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->line(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + + +static void +pstip_first_tri(struct draw_stage *stage, struct prim_header *header) +{ + struct pstip_stage *pstip = pstip_stage(stage); + struct draw_context *draw = stage->draw; + struct pipe_context *pipe = pstip->pipe; + + assert(draw->rasterizer->poly_stipple_enable); + + /* + * Bind our fragprog, sampler and texture + */ + bind_pstip_fragment_shader(pstip); + + pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit, pstip->sampler_cso); + pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit, pstip->texture); + + /* now really draw first line */ + stage->tri = passthrough_tri; + stage->tri(stage, header); +} + + +static void +pstip_flush(struct draw_stage *stage, unsigned flags) +{ + /*struct draw_context *draw = stage->draw;*/ + struct pstip_stage *pstip = pstip_stage(stage); + struct pipe_context *pipe = pstip->pipe; + + stage->tri = pstip_first_tri; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); + + /* XXX restore original texture, sampler state */ + pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit, + pstip->state.sampler[pstip->sampler_unit]); + pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit, + pstip->state.texture[pstip->sampler_unit]); +} + + +static void +pstip_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +pstip_destroy(struct draw_stage *stage) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +static struct pstip_stage * +draw_pstip_stage(struct draw_context *draw) +{ + struct pstip_stage *pstip = CALLOC_STRUCT(pstip_stage); + + draw_alloc_temp_verts( &pstip->stage, 8 ); + + pstip->stage.draw = draw; + pstip->stage.next = NULL; + pstip->stage.point = passthrough_point; + pstip->stage.line = passthrough_line; + pstip->stage.tri = pstip_first_tri; + pstip->stage.flush = pstip_flush; + pstip->stage.reset_stipple_counter = pstip_reset_stipple_counter; + pstip->stage.destroy = pstip_destroy; + + return pstip; +} + + +/* + * XXX temporary? solution to mapping a pipe_context to a pstip_stage. + */ + +#define MAX_CONTEXTS 10 + +static struct pipe_context *Pipe[MAX_CONTEXTS]; +static struct pstip_stage *Stage[MAX_CONTEXTS]; +static uint NumContexts; + +static void +add_pstip_pipe_context(struct pipe_context *pipe, struct pstip_stage *pstip) +{ + assert(NumContexts < MAX_CONTEXTS); + Pipe[NumContexts] = pipe; + Stage[NumContexts] = pstip; + NumContexts++; +} + +static struct pstip_stage * +pstip_stage_from_pipe(struct pipe_context *pipe) +{ + uint i; + for (i = 0; i < NumContexts; i++) { + if (Pipe[i] == pipe) + return Stage[i]; + } + assert(0); + return NULL; +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +pstip_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = CALLOC_STRUCT(pstip_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = pstip->driver_create_fs_state(pstip->pipe, fs); + } + + return aafs; +} + + +static void +pstip_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; + /* save current */ + pstip->fs = aafs; + /* pass-through */ + pstip->driver_bind_fs_state(pstip->pipe, aafs->driver_fs); +} + + +static void +pstip_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; + /* pass-through */ + pstip->driver_delete_fs_state(pstip->pipe, aafs->driver_fs); + FREE(aafs); +} + + +static void +pstip_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, void *sampler) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + /* save current */ + pstip->state.sampler[unit] = sampler; + /* pass-through */ + pstip->driver_bind_sampler_state(pstip->pipe, unit, sampler); +} + + +static void +pstip_set_sampler_texture(struct pipe_context *pipe, + unsigned sampler, struct pipe_texture *texture) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + /* save current */ + pstip->state.texture[sampler] = texture; + /* pass-through */ + pstip->driver_set_sampler_texture(pstip->pipe, sampler, texture); +} + + +static void +pstip_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + /* save current */ + pstip->state.stipple = stipple; + /* pass-through */ + pstip->driver_set_polygon_stipple(pstip->pipe, stipple); + + pstip_update_texture(pstip); +} + + + +/** + * Called by drivers that want to install this AA line prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA lines. + */ +void +draw_install_pstipple_stage(struct draw_context *draw, + struct pipe_context *pipe) +{ + struct pstip_stage *pstip; + + /* + * Create / install AA line drawing / prim stage + */ + pstip = draw_pstip_stage( draw ); + assert(pstip); + draw->pipeline.pstipple = &pstip->stage; + + pstip->pipe = pipe; + + /* create special texture, sampler state */ + pstip_create_texture(pstip); + pstip_create_sampler(pstip); + + /* save original driver functions */ + pstip->driver_create_fs_state = pipe->create_fs_state; + pstip->driver_bind_fs_state = pipe->bind_fs_state; + pstip->driver_delete_fs_state = pipe->delete_fs_state; + + pstip->driver_bind_sampler_state = pipe->bind_sampler_state; + pstip->driver_set_sampler_texture = pipe->set_sampler_texture; + pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; + + /* override the driver's functions */ + pipe->create_fs_state = pstip_create_fs_state; + pipe->bind_fs_state = pstip_bind_fs_state; + pipe->delete_fs_state = pstip_delete_fs_state; + + pipe->bind_sampler_state = pstip_bind_sampler_state; + pipe->set_sampler_texture = pstip_set_sampler_texture; + pipe->set_polygon_stipple = pstip_set_polygon_stipple; + + add_pstip_pipe_context(pipe, pstip); +} diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index 5167ef1e75..efd6793f2b 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -82,6 +82,12 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) precalc_flat = 1; /* only needed for lines really */ } + if (draw->rasterizer->poly_stipple_enable + && draw->pipeline.pstipple) { + draw->pipeline.pstipple->next = next; + next = draw->pipeline.pstipple; + } + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { draw->pipeline.unfilled->next = next; diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index de4c6c18e7..2cdf3c75bf 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -332,6 +332,11 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); +#if USE_DRAW_STAGE_PSTIPPLE + /* Do polygon stipple w/ texture map + frag prog? */ + draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); +#endif + /* sp_prim_setup can do wide points (don't convert to quads) */ draw_convert_wide_points(softpipe->draw, FALSE); diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index a50cee7648..feeafc7084 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -39,6 +39,13 @@ #include "sp_quad.h" +/** + * This is a temporary variable for testing draw-stage polygon stipple. + * If zero, do stipple in sp_quad_stipple.c + */ +#define USE_DRAW_STAGE_PSTIPPLE 1 + + struct softpipe_winsys; struct softpipe_vbuf_render; struct draw_context; diff --git a/src/gallium/drivers/softpipe/sp_quad.c b/src/gallium/drivers/softpipe/sp_quad.c index 6bd468a51c..15b5594547 100644 --- a/src/gallium/drivers/softpipe/sp_quad.c +++ b/src/gallium/drivers/softpipe/sp_quad.c @@ -112,7 +112,9 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp_push_quad_first( sp, sp->quad.earlyz ); } +#if !USE_DRAW_STAGE_PSTIPPLE if (sp->rasterizer->poly_stipple_enable) { sp_push_quad_first( sp, sp->quad.polygon_stipple ); } +#endif } -- cgit v1.2.3 From 26c57d163092d8069c69ff47929e73682b819ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 23 Feb 2008 00:46:40 +0900 Subject: Avoid building problematic module/drivers on windows. --- src/gallium/SConscript | 9 +++++++-- src/gallium/winsys/SConscript | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/SConscript b/src/gallium/SConscript index a08b4b830e..210fd7d309 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -23,7 +23,12 @@ if llvm: SConscript([ 'drivers/softpipe/SConscript', 'drivers/i915simple/SConscript', - 'drivers/i965simple/SConscript', 'drivers/failover/SConscript', - #'drivers/cell/SConscript', ]) + +if not msvc: + SConscript(['drivers/i965simple/SConscript']) + +#if cell: +# SConscript(['drivers/cell/SConscript']) + \ No newline at end of file diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index 32215d8d58..3f0596e19c 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -4,7 +4,8 @@ if dri: SConscript([ 'dri/SConscript', ]) -else: + +if env['x11'] and not dri and platform != 'winddk': SConscript([ 'xlib/SConscript', ]) -- cgit v1.2.3 From f44b30f1eb4896668c4fe91cd9b084ea63c9e915 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 20 Feb 2008 22:03:59 +0100 Subject: gallium: New file. --- src/gallium/include/pipe/p_pointer.h | 87 ++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/gallium/include/pipe/p_pointer.h (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_pointer.h b/src/gallium/include/pipe/p_pointer.h new file mode 100644 index 0000000000..e3927538e8 --- /dev/null +++ b/src/gallium/include/pipe/p_pointer.h @@ -0,0 +1,87 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef P_POINTER_H +#define P_POINTER_H + +#include "p_compiler.h" + +static INLINE intptr_t +pointer_to_intptr( const void *p ) +{ + union { + const void *p; + intptr_t i; + } pi; + pi.p = p; + return pi.i; +} + +static INLINE void * +intptr_to_pointer( intptr_t i ) +{ + union { + void *p; + intptr_t i; + } pi; + pi.i = i; + return pi.p; +} + +static INLINE uintptr_t +pointer_to_uintptr( const void *ptr ) +{ + union { + const void *p; + uintptr_t u; + } pu; + pu.p = ptr; + return pu.u; +} + +static INLINE void * +uintptr_to_pointer( uintptr_t u ) +{ + union { + void *p; + uintptr_t u; + } pu; + pu.u = u; + return pu.p; +} + +/** + * Return a pointer aligned to next multiple of N bytes. + */ +static INLINE void * +align_pointer( const void *unaligned, uintptr_t alignment ) +{ + uintptr_t aligned = (pointer_to_uintptr( unaligned ) + alignment - 1) & ~(alignment - 1); + return uintptr_to_pointer( aligned ); +} + +#endif /* P_POINTER_H */ -- cgit v1.2.3 From 8828dd1443c7d55697f78757b22be2733e059acf Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 20 Feb 2008 22:04:32 +0100 Subject: gallium: Move align_pointer() to p_pointer.h. --- src/gallium/include/pipe/p_util.h | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index d7da2801c9..6f0dbdacd9 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -30,6 +30,7 @@ #include "p_compiler.h" #include "p_debug.h" +#include "p_pointer.h" #include @@ -114,33 +115,6 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define CALLOC_STRUCT(T) (struct T *) CALLOC(1, sizeof(struct T)) -/** - * Return a pointer aligned to next multiple of N bytes. - */ -static INLINE void * -align_pointer( void *unaligned, uint alignment ) -{ - if (sizeof(void *) == 64) { - union { - void *p; - uint64 u; - } pu; - pu.p = unaligned; - pu.u = (pu.u + alignment - 1) & ~(uint64) (alignment - 1); - return pu.p; - } - else { - /* 32-bit pointers */ - union { - void *p; - uint u; - } pu; - pu.p = unaligned; - pu.u = (pu.u + alignment - 1) & ~(alignment - 1); - return pu.p; - } -} - /** * Return memory on given byte alignment */ -- cgit v1.2.3 From 6f238275c7c19f7e287b47276e6b4060c270599f Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 20 Feb 2008 22:05:06 +0100 Subject: gallium: Define intptr_t for Windows platform. --- src/gallium/include/pipe/p_compiler.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index 30cd729c56..ab527f2afe 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -61,8 +61,10 @@ typedef long long int64_t; typedef unsigned long long uint64_t; #if defined(_WIN64) +typedef __int64 intptr_t; typedef unsigned __int64 uintptr_t; #else +typedef int intptr_t; typedef unsigned int uintptr_t; #endif -- cgit v1.2.3 From 69a7c9739bc0f11e66e11ab410d813fa69fe5fc9 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 20 Feb 2008 22:05:52 +0100 Subject: gallium: Silence compiler warnings on Windows. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 43d5085895..0ced585c7f 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -343,7 +343,7 @@ nearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size) switch (wrapMode) { case PIPE_TEX_WRAP_CLAMP: i = ifloor(s); - return CLAMP(i, 0, size-1); + return CLAMP(i, 0, (int) size-1); case PIPE_TEX_WRAP_CLAMP_TO_EDGE: /* fall-through */ case PIPE_TEX_WRAP_CLAMP_TO_BORDER: @@ -366,7 +366,7 @@ linear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size, switch (wrapMode) { case PIPE_TEX_WRAP_CLAMP: /* Not exactly what the spec says, but it matches NVIDIA output */ - s = CLAMP(s - 0.5F, 0.0, (float) size - 1.0); + s = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f); *i0 = ifloor(s); *i1 = *i0 + 1; break; @@ -377,7 +377,7 @@ linear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size, s -= 0.5F; *i0 = ifloor(s); *i1 = *i0 + 1; - if (*i1 > size - 1) + if (*i1 > (int) size - 1) *i1 = size - 1; break; default: -- cgit v1.2.3 From 57060bc1fa82e4e93d2affafecd98219be2f991f Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 20 Feb 2008 22:10:27 +0100 Subject: gallium: Silence compiler warnings on Windows. --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index dcbf76f600..4d33950e99 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -25,6 +25,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_debug.h" +#include "pipe/p_pointer.h" #include "rtasm_execmem.h" #include "rtasm_x86sse.h" @@ -34,7 +35,7 @@ static unsigned char *cptr( void (*label)() ) { - return (unsigned char *)(unsigned long)label; + return (unsigned char *) label; } @@ -46,7 +47,7 @@ static void do_realloc( struct x86_function *p ) p->csr = p->store; } else { - unsigned used = p->csr - p->store; + uintptr_t used = pointer_to_uintptr( p->csr ) - pointer_to_uintptr( p->store ); unsigned char *tmp = p->store; p->size *= 2; p->store = rtasm_exec_malloc(p->size); @@ -60,7 +61,7 @@ static void do_realloc( struct x86_function *p ) */ static unsigned char *reserve( struct x86_function *p, int bytes ) { - if (p->csr + bytes - p->store > p->size) + if (p->csr + bytes - p->store > (int) p->size) do_realloc(p); { @@ -135,7 +136,7 @@ static void emit_modrm( struct x86_function *p, case mod_INDIRECT: break; case mod_DISP8: - emit_1b(p, regmem.disp); + emit_1b(p, (char) regmem.disp); break; case mod_DISP32: emit_1i(p, regmem.disp); @@ -251,14 +252,14 @@ void x86_jcc( struct x86_function *p, enum x86_cc cc, unsigned char *label ) { - int offset = label - (x86_get_label(p) + 2); + intptr_t offset = pointer_to_intptr( label ) - (pointer_to_intptr( x86_get_label(p) ) + 2); if (offset <= 127 && offset >= -128) { emit_1ub(p, 0x70 + cc); emit_1b(p, (char) offset); } else { - offset = label - (x86_get_label(p) + 6); + offset = pointer_to_intptr( label ) - (pointer_to_intptr( x86_get_label(p) ) + 6); emit_2ub(p, 0x0f, 0x80 + cc); emit_1i(p, offset); } @@ -293,13 +294,13 @@ unsigned char *x86_call_forward( struct x86_function *p) void x86_fixup_fwd_jump( struct x86_function *p, unsigned char *fixup ) { - *(int *)(fixup - 4) = x86_get_label(p) - fixup; + *(int *)(fixup - 4) = pointer_to_intptr( x86_get_label(p) ) - pointer_to_intptr( fixup ); } void x86_jmp( struct x86_function *p, unsigned char *label) { emit_1ub(p, 0xe9); - emit_1i(p, label - x86_get_label(p) - 4); + emit_1i(p, pointer_to_intptr( label ) - pointer_to_intptr( x86_get_label(p) ) - 4); } #if 0 @@ -1207,7 +1208,7 @@ void (*x86_get_func( struct x86_function *p ))(void) { if (DISASSEM && p->store) debug_printf("disassemble %p %p\n", p->store, p->csr); - return (void (*)(void)) (unsigned long) p->store; + return (void (*)(void)) p->store; } #else -- cgit v1.2.3 From e0de82fbcb181f5c3e372ed66b692970a9e80766 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 20 Feb 2008 22:25:18 +0100 Subject: gallium: Fix build on Windows. --- src/gallium/drivers/softpipe/sp_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 6ba0f09e0a..3d26e8ca66 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -139,7 +139,7 @@ softpipe_texture_update(struct pipe_context *pipe, struct softpipe_context *softpipe = softpipe_context(pipe); uint unit; for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { - if (softpipe->texture[unit] == texture) { + if (&softpipe->texture[unit]->base == texture) { sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); } } -- cgit v1.2.3 From 2cf860b866d80595b7287d6991dc96abc3ca8dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 22 Feb 2008 16:22:41 +0900 Subject: gallium: MSVC fixes. --- src/gallium/auxiliary/cso_cache/cso_hash.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index b40217c524..e65d331a0b 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -134,7 +134,7 @@ static void cso_data_rehash(struct cso_hash_data *hash, int hint) hint = countBits(-hint); if (hint < MinNumBits) hint = MinNumBits; - hash->userNumBits = hint; + hash->userNumBits = (short)hint; while (primeForNumBits(hint) < (hash->size >> 1)) ++hint; } else if (hint < MinNumBits) { @@ -147,7 +147,7 @@ static void cso_data_rehash(struct cso_hash_data *hash, int hint) int oldNumBuckets = hash->numBuckets; int i = 0; - hash->numBits = hint; + hash->numBits = (short)hint; hash->numBuckets = primeForNumBits(hint); hash->buckets = malloc(sizeof(struct cso_node*) * hash->numBuckets); for (i = 0; i < hash->numBuckets; ++i) @@ -241,7 +241,7 @@ struct cso_hash * cso_hash_create(void) hash->data.d->buckets = 0; hash->data.d->size = 0; hash->data.d->nodeSize = sizeof(struct cso_node); - hash->data.d->userNumBits = MinNumBits; + hash->data.d->userNumBits = (short)MinNumBits; hash->data.d->numBits = 0; hash->data.d->numBuckets = 0; -- cgit v1.2.3 From 6c597238b2e168b63738ac8cc9167c1d09185aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 22 Feb 2008 17:22:32 +0900 Subject: gallium: Add cso convenience routine (from Keith's patch). --- src/gallium/auxiliary/cso_cache/cso_cache.c | 20 ++++++++++++++++++++ src/gallium/auxiliary/cso_cache/cso_hash.h | 9 +++++++++ 2 files changed, 29 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index 9e77e0774d..776ce6bacf 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -132,6 +132,26 @@ cso_find_state(struct cso_cache *sc, return cso_hash_find(hash, hash_key); } + +void *cso_hash_find_data_from_template( struct cso_hash *hash, + unsigned hash_key, + void *templ, + int size ) +{ + struct cso_hash_iter iter = cso_hash_find(hash, hash_key); + while (!cso_hash_iter_is_null(iter)) { + void *iter_data = cso_hash_iter_data(iter); + if (!memcmp(iter_data, templ, size)) { + /* Return the payload: + */ + return (unsigned char *)iter_data + size; + } + iter = cso_hash_iter_next(iter); + } + return NULL; +} + + struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type, void *templ) diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h index b4aa111860..ffd99beba9 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.h +++ b/src/gallium/auxiliary/cso_cache/cso_hash.h @@ -59,4 +59,13 @@ void *cso_hash_iter_data(struct cso_hash_iter iter); struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter); struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter); + +/* KW: a convenience routine: + */ +void *cso_hash_find_data_from_template( struct cso_hash *hash, + unsigned hash_key, + void *templ, + int size ); + + #endif -- cgit v1.2.3 From 901b03e84dce21f4241375da179b2199a3162e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 22 Feb 2008 18:28:30 +0900 Subject: gallium: Wrap decls in extern "C". --- src/gallium/auxiliary/cso_cache/cso_cache.h | 12 ++++++++++++ src/gallium/auxiliary/cso_cache/cso_hash.h | 10 ++++++++++ 2 files changed, 22 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h index 116e2eaa2c..58664cdd94 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.h +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -37,8 +37,15 @@ #include "pipe/p_state.h" +#ifdef __cplusplus +extern "C" { +#endif + + struct cso_hash; +struct cso_hash_iter; + struct cso_cache { struct cso_hash *blend_hash; struct cso_hash *depth_stencil_hash; @@ -104,4 +111,9 @@ struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, void * cso_take_state(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h index ffd99beba9..2e8b69675c 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.h +++ b/src/gallium/auxiliary/cso_cache/cso_hash.h @@ -33,6 +33,12 @@ #ifndef CSO_HASH_H #define CSO_HASH_H + +#ifdef __cplusplus +extern "C" { +#endif + + struct cso_hash; struct cso_node; @@ -68,4 +74,8 @@ void *cso_hash_find_data_from_template( struct cso_hash *hash, int size ); +#ifdef __cplusplus +} +#endif + #endif -- cgit v1.2.3 From f1bef2cba2e6e4c0988b05306dd1435b8c0df3d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 22 Feb 2008 18:45:20 +0900 Subject: gallium: Countour MSVC's pickyness for structures returned by value. --- src/gallium/auxiliary/cso_cache/cso_cache.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h index 58664cdd94..b4f4f3ae41 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.h +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -36,16 +36,14 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" +#include "cso_hash.h" /* for cso_hash_iter, as MSVC requires structures returned by value to be fully defined */ + #ifdef __cplusplus extern "C" { #endif -struct cso_hash; - -struct cso_hash_iter; - struct cso_cache { struct cso_hash *blend_hash; struct cso_hash *depth_stencil_hash; -- cgit v1.2.3 From b4d050ffccf46e5e7b40d8a2f3868cc73fcf110e Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 22 Feb 2008 08:50:37 -0700 Subject: cell: fix build: s/dest/vertex/ --- src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index f7ef72e5a2..42cc47cbfe 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -123,7 +123,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) for (j = 0; j < n; j++) { vs->elts[j] = draw->vs.queue[i + j].elt; - vs->vOut[j] = (uintptr_t) draw->vs.queue[i + j].dest; + vs->vOut[j] = (uintptr_t) draw->vs.queue[i + j].vertex; } for (/* empty */; j < SPU_VERTS_PER_BATCH; j++) { -- cgit v1.2.3 From 0bb53709e837ac709f31ace8852599e885f4d090 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 22 Feb 2008 08:52:24 -0700 Subject: cell: added function prototypes to silence warnings --- src/gallium/drivers/cell/ppu/cell_context.h | 2 ++ src/gallium/drivers/cell/ppu/cell_flush.h | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 3b687bb868..1433a4925f 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -134,6 +134,8 @@ extern void cell_vertex_shader_queue_flush(struct draw_context *draw); +/* XXX find a better home for this */ +extern void cell_update_vertex_fetch(struct draw_context *draw); #endif /* CELL_CONTEXT_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_flush.h b/src/gallium/drivers/cell/ppu/cell_flush.h index eda351b1cb..7f940ae76b 100644 --- a/src/gallium/drivers/cell/ppu/cell_flush.h +++ b/src/gallium/drivers/cell/ppu/cell_flush.h @@ -35,4 +35,8 @@ cell_flush(struct pipe_context *pipe, unsigned flags); extern void cell_flush_int(struct pipe_context *pipe, unsigned flags); +extern void +cell_flush_buffer_range(struct cell_context *cell, void *ptr, + unsigned size); + #endif -- cgit v1.2.3 From 12c14c31b71d4bac494c4470a34e28ec66309254 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 22 Feb 2008 08:56:55 -0700 Subject: gallium: fix brokenb build --- src/gallium/drivers/softpipe/sp_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 3d26e8ca66..6ba0f09e0a 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -139,7 +139,7 @@ softpipe_texture_update(struct pipe_context *pipe, struct softpipe_context *softpipe = softpipe_context(pipe); uint unit; for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { - if (&softpipe->texture[unit]->base == texture) { + if (softpipe->texture[unit] == texture) { sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); } } -- cgit v1.2.3 From 24f3d7de29c5cd30ced7c3ce7293902460a82e0b Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 22 Feb 2008 14:07:12 -0700 Subject: i915: include p_debug.h (resolves undefined assert()) --- src/gallium/winsys/dri/intel/intel_batchbuffer.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h index 82feafa21f..caf6870a3c 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -28,6 +28,7 @@ #ifndef INTEL_BATCHBUFFER_H #define INTEL_BATCHBUFFER_H +#include "pipe/p_debug.h" #include "pipe/p_compiler.h" #include "dri_bufmgr.h" -- cgit v1.2.3 From 8cd7c1d03ce045bfa39471c3f77a31030195b899 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 22 Feb 2008 14:07:33 -0700 Subject: i915: include stdio.h --- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 49e04d81ec..5830b88b37 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -26,6 +26,7 @@ **************************************************************************/ #include +#include #include "intel_batchbuffer.h" #include "intel_context.h" #include "intel_screen.h" -- cgit v1.2.3 From c74900ee5d80c7c2b7cbe4ed87395526a742a13e Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 22 Feb 2008 16:48:05 -0700 Subject: gallium/i915: overhaul of fragment shader compilation, constant/immediate allocation Before, fragment shaders were translated to i915 hw code at bind time, rather than create time. Now there's an i915_fragment_shader struct with the expected contents that's created by i915_create_fs_state(). Translation to i915 code takes place there too. Immediates are handled correctly now. During program translation we keep track of which constant buffer slots are free (i.e. not referenced by the shader). Then the TGSI immediates and ancillary immediates (introduced for SIN/COS/etc) are put into those free slots. When it's time to upload the constant buffer, use the fp->constant_flags[] array to determine if we should grab an immediate from the shader, or a user-defined parameter from the gallium constant buffer. --- src/gallium/drivers/i915simple/i915_context.h | 42 ++++++- src/gallium/drivers/i915simple/i915_fpc.h | 23 ++-- src/gallium/drivers/i915simple/i915_fpc_emit.c | 101 +++++----------- .../drivers/i915simple/i915_fpc_translate.c | 132 +++++++++++++-------- src/gallium/drivers/i915simple/i915_state.c | 36 ++++-- .../drivers/i915simple/i915_state_derived.c | 3 +- src/gallium/drivers/i915simple/i915_state_emit.c | 39 ++++-- 7 files changed, 226 insertions(+), 150 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 2d876925b2..5cc38cdc85 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -79,6 +79,40 @@ #define I915_MAX_CONSTANT 32 +/** See constant_flags[] below */ +#define I915_CONSTFLAG_USER 0x1f + + +/** + * Subclass of pipe_shader_state + */ +struct i915_fragment_shader +{ + struct pipe_shader_state state; + uint *program; + uint program_len; + + /** + * constants introduced during translation. + * These are placed at the end of the constant buffer and grow toward + * the beginning (eg: slot 31, 30 29, ...) + * User-provided constants start at 0. + * This allows both types of constants to co-exist (until there's too many) + * and doesn't require regenerating/changing the fragment program to + * shuffle constants around. + */ + uint num_constants; + float constants[I915_MAX_CONSTANT][4]; + + /** + * Status of each constant + * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding + * slot of the user's constant buffer. (set by pipe->set_constant_buffer()) + * Else, the bitmask indicates which components are occupied by immediates. + */ + ubyte constant_flags[I915_MAX_CONSTANT]; +}; + struct i915_cache_context; @@ -93,11 +127,6 @@ struct i915_state float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4]; /** number of constants passed in through a constant buffer */ uint num_user_constants[PIPE_SHADER_TYPES]; - /** user constants, plus extra constants from shader translation */ - uint num_constants[PIPE_SHADER_TYPES]; - - uint *program; - uint program_len; /* texture sampler state */ unsigned sampler[I915_TEX_UNITS][3]; @@ -187,7 +216,8 @@ struct i915_context const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; const struct i915_depth_stencil_state *depth_stencil; const struct i915_rasterizer_state *rasterizer; - const struct pipe_shader_state *fs; + + struct i915_fragment_shader *fs; struct pipe_blend_color blend_color; struct pipe_clip_state clip; diff --git a/src/gallium/drivers/i915simple/i915_fpc.h b/src/gallium/drivers/i915simple/i915_fpc.h index 8c7b68aefb..250dfe6dbf 100644 --- a/src/gallium/drivers/i915simple/i915_fpc.h +++ b/src/gallium/drivers/i915simple/i915_fpc.h @@ -44,9 +44,16 @@ * Program translation state */ struct i915_fp_compile { - const struct pipe_shader_state *shader; + struct i915_fragment_shader *shader; /* the shader we're compiling */ - struct vertex_info *vertex_info; + boolean used_constants[I915_MAX_CONSTANT]; + + /** maps TGSI immediate index to constant slot */ + uint num_immediates; + uint immediates_map[I915_MAX_CONSTANT]; + float immediates[I915_MAX_CONSTANT][4]; + + boolean first_instruction; uint declarations[I915_PROGRAM_SIZE]; uint program[I915_PROGRAM_SIZE]; @@ -57,11 +64,6 @@ struct i915_fp_compile { uint output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; uint output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; - /** points into the i915->current.constants array: */ - float (*constants)[4]; - uint num_constants; - uint constant_flags[I915_MAX_CONSTANT]; /**< status of each constant */ - uint *csr; /**< Cursor, points into program. */ uint *decl; /**< Cursor, points into declarations. */ @@ -155,7 +157,9 @@ swizzle(int reg, uint x, uint y, uint z, uint w) /*********************************************************************** * Public interface for the compiler */ -extern void i915_translate_fragment_program( struct i915_context *i915 ); +extern void +i915_translate_fragment_program( struct i915_context *i915, + struct i915_fragment_shader *fs); @@ -206,8 +210,5 @@ extern void i915_disassemble_program(const uint * program, uint sz); extern void i915_program_error(struct i915_fp_compile *p, const char *msg, ...); -extern void -i915_translate_fragment_program(struct i915_context *i915); - #endif diff --git a/src/gallium/drivers/i915simple/i915_fpc_emit.c b/src/gallium/drivers/i915simple/i915_fpc_emit.c index 74924ff0a1..a59ee23403 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_emit.c +++ b/src/gallium/drivers/i915simple/i915_fpc_emit.c @@ -61,8 +61,6 @@ (REG_NR_MASK << UREG_NR_SHIFT)) -#define I915_CONSTFLAG_PARAM 0x1f - uint i915_get_temp(struct i915_fp_compile *p) { @@ -235,6 +233,7 @@ uint i915_emit_texld( struct i915_fp_compile *p, uint i915_emit_const1f(struct i915_fp_compile * p, float c0) { + struct i915_fragment_shader *ifs = p->shader; unsigned reg, idx; if (c0 == 0.0) @@ -243,15 +242,15 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0) return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE); for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + if (ifs->constant_flags[reg] == I915_CONSTFLAG_USER) continue; for (idx = 0; idx < 4; idx++) { - if (!(p->constant_flags[reg] & (1 << idx)) || - p->constants[reg][idx] == c0) { - p->constants[reg][idx] = c0; - p->constant_flags[reg] |= 1 << idx; - if (reg + 1 > p->num_constants) - p->num_constants = reg + 1; + if (!(ifs->constant_flags[reg] & (1 << idx)) || + ifs->constants[reg][idx] == c0) { + ifs->constants[reg][idx] = c0; + ifs->constant_flags[reg] |= 1 << idx; + if (reg + 1 > ifs->num_constants) + ifs->num_constants = reg + 1; return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); } } @@ -264,6 +263,7 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0) uint i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1) { + struct i915_fragment_shader *ifs = p->shader; unsigned reg, idx; if (c0 == 0.0) @@ -277,16 +277,16 @@ i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1) return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0xf || - p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + if (ifs->constant_flags[reg] == 0xf || + ifs->constant_flags[reg] == I915_CONSTFLAG_USER) continue; for (idx = 0; idx < 3; idx++) { - if (!(p->constant_flags[reg] & (3 << idx))) { - p->constants[reg][idx + 0] = c0; - p->constants[reg][idx + 1] = c1; - p->constant_flags[reg] |= 3 << idx; - if (reg + 1 > p->num_constants) - p->num_constants = reg + 1; + if (!(ifs->constant_flags[reg] & (3 << idx))) { + ifs->constants[reg][idx + 0] = c0; + ifs->constants[reg][idx + 1] = c1; + ifs->constant_flags[reg] |= 3 << idx; + if (reg + 1 > ifs->num_constants) + ifs->num_constants = reg + 1; return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE); } } @@ -302,25 +302,26 @@ uint i915_emit_const4f(struct i915_fp_compile * p, float c0, float c1, float c2, float c3) { + struct i915_fragment_shader *ifs = p->shader; unsigned reg; for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0xf && - p->constants[reg][0] == c0 && - p->constants[reg][1] == c1 && - p->constants[reg][2] == c2 && - p->constants[reg][3] == c3) { + if (ifs->constant_flags[reg] == 0xf && + ifs->constants[reg][0] == c0 && + ifs->constants[reg][1] == c1 && + ifs->constants[reg][2] == c2 && + ifs->constants[reg][3] == c3) { return UREG(REG_TYPE_CONST, reg); } - else if (p->constant_flags[reg] == 0) { - - p->constants[reg][0] = c0; - p->constants[reg][1] = c1; - p->constants[reg][2] = c2; - p->constants[reg][3] = c3; - p->constant_flags[reg] = 0xf; - if (reg + 1 > p->num_constants) - p->num_constants = reg + 1; + else if (ifs->constant_flags[reg] == 0) { + + ifs->constants[reg][0] = c0; + ifs->constants[reg][1] = c1; + ifs->constants[reg][2] = c2; + ifs->constants[reg][3] = c3; + ifs->constant_flags[reg] = 0xf; + if (reg + 1 > ifs->num_constants) + ifs->num_constants = reg + 1; return UREG(REG_TYPE_CONST, reg); } } @@ -335,41 +336,3 @@ i915_emit_const4fv(struct i915_fp_compile * p, const float * c) { return i915_emit_const4f(p, c[0], c[1], c[2], c[3]); } - - -#if 00000/*UNUSED*/ -/* Reserve a slot in the constant file for a Mesa state parameter. - * These will later need to be tracked on statechanges, but that is - * done elsewhere. - */ -uint -i915_emit_param4fv(struct i915_fp_compile * p, const float * values) -{ - struct i915_fragment_program *fp = p->fp; - int i; - - for (i = 0; i < fp->nr_params; i++) { - if (fp->param[i].values == values) - return UREG(REG_TYPE_CONST, fp->param[i].reg); - } - - if (p->constants->nr_constants == I915_MAX_CONSTANT || - fp->nr_params == I915_MAX_CONSTANT) { - i915_program_error(p, "i915_emit_param4fv: out of constants\n"); - return 0; - } - - { - int reg = p->constants->nr_constants++; - int i = fp->nr_params++; - - assert (p->constant_flags[reg] == 0); - p->constant_flags[reg] = I915_CONSTFLAG_PARAM; - - fp->param[i].values = values; - fp->param[i].reg = reg; - - return UREG(REG_TYPE_CONST, reg); - } -} -#endif diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 6c1524c768..afe7e25dce 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -34,6 +34,7 @@ #include "pipe/p_shader_tokens.h" #include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_dump.h" #include "draw/draw_vertex.h" @@ -97,19 +98,19 @@ negate(int reg, int x, int y, int z, int w) } +/** + * In the event of a translation failure, we'll generate a simple color + * pass-through program. + */ static void -i915_use_passthrough_shader(struct i915_context *i915) +i915_use_passthrough_shader(struct i915_fragment_shader *fs) { - debug_printf("**** Using i915 pass-through fragment shader\n"); - - i915->current.program = (uint *) MALLOC(sizeof(passthrough)); - if (i915->current.program) { - memcpy(i915->current.program, passthrough, sizeof(passthrough)); - i915->current.program_len = Elements(passthrough); + fs->program = (uint *) MALLOC(sizeof(passthrough)); + if (fs->program) { + memcpy(fs->program, passthrough, sizeof(passthrough)); + fs->program_len = Elements(passthrough); } - - i915->current.num_constants[PIPE_SHADER_FRAGMENT] = 0; - i915->current.num_user_constants[PIPE_SHADER_FRAGMENT] = 0; + fs->num_constants = 0; } @@ -161,9 +162,6 @@ src_vector(struct i915_fp_compile *p, * We also use a texture coordinate to pass wpos when possible. */ - /* use vertex format info to map a slot number to a VF attrib */ - assert(index < p->vertex_info->num_attribs); - sem_name = p->input_semantic_name[index]; sem_ind = p->input_semantic_index[index]; @@ -201,7 +199,8 @@ src_vector(struct i915_fp_compile *p, break; case TGSI_FILE_IMMEDIATE: - /* XXX unfinished - need to append immediates onto const buffer */ + assert(index < p->num_immediates); + index = p->immediates_map[index]; /* fall-through */ case TGSI_FILE_CONSTANT: src = UREG(REG_TYPE_CONST, index); @@ -896,6 +895,7 @@ static void i915_translate_instructions(struct i915_fp_compile *p, const struct tgsi_token *tokens) { + struct i915_fragment_shader *ifs = p->shader; struct tgsi_parse_context parse; tgsi_parse_init( &parse, tokens ); @@ -928,13 +928,54 @@ i915_translate_instructions(struct i915_fp_compile *p, p->output_semantic_name[ind] = sem; p->output_semantic_index[ind] = semi; } + else if (parse.FullToken.FullDeclaration.Declaration.File + == TGSI_FILE_CONSTANT) { + uint i; + for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First; + i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last; + i++) { + assert(ifs->constant_flags[i] == 0x0); + ifs->constant_flags[i] = I915_CONSTFLAG_USER; + ifs->num_constants = MAX2(ifs->num_constants, i + 1); + } + } break; case TGSI_TOKEN_TYPE_IMMEDIATE: - /* XXX append the immediate to the const buffer... */ + { + const struct tgsi_full_immediate *imm + = &parse.FullToken.FullImmediate; + const uint pos = p->num_immediates++; + uint j; + for (j = 0; j < imm->Immediate.Size; j++) { + p->immediates[pos][j] = imm->u.ImmediateFloat32[j].Float; + } + } break; case TGSI_TOKEN_TYPE_INSTRUCTION: + if (p->first_instruction) { + /* resolve location of immediates */ + uint i, j; + for (i = 0; i < p->num_immediates; i++) { + /* find constant slot for this immediate */ + for (j = 0; j < I915_MAX_CONSTANT; j++) { + if (ifs->constant_flags[j] == 0x0) { + memcpy(ifs->constants[j], + p->immediates[i], + 4 * sizeof(float)); + /*printf("immediate %d maps to const %d\n", i, j);*/ + ifs->constant_flags[j] = 0xf; /* all four comps used */ + p->immediates_map[i] = j; + ifs->num_constants = MAX2(ifs->num_constants, j + 1); + break; + } + } + } + + p->first_instruction = FALSE; + } + i915_translate_instruction(p, &parse.FullToken.FullInstruction); break; @@ -950,27 +991,28 @@ i915_translate_instructions(struct i915_fp_compile *p, static struct i915_fp_compile * i915_init_compile(struct i915_context *i915, - const struct pipe_shader_state *fs) + struct i915_fragment_shader *ifs) { struct i915_fp_compile *p = CALLOC_STRUCT(i915_fp_compile); - p->shader = i915->fs; + p->shader = ifs; - p->vertex_info = &i915->current.vertex_info; - - /* new constants found during translation get appended after the - * user-provided constants. + /* Put new constants at end of const buffer, growing downward. + * The problem is we don't know how many user-defined constants might + * be specified with pipe->set_constant_buffer(). + * Should pre-scan the user's program to determine the highest-numbered + * constant referenced. */ - p->constants = i915->current.constants[PIPE_SHADER_FRAGMENT]; - p->num_constants = i915->current.num_user_constants[PIPE_SHADER_FRAGMENT]; + ifs->num_constants = 0; + memset(ifs->constant_flags, 0, sizeof(ifs->constant_flags)); + + p->first_instruction = TRUE; p->nr_tex_indirect = 1; /* correct? */ p->nr_tex_insn = 0; p->nr_alu_insn = 0; p->nr_decl_insn = 0; - memset(p->constant_flags, 0, sizeof(p->constant_flags)); - p->csr = p->program; p->decl = p->declarations; p->decl_s = 0; @@ -993,6 +1035,7 @@ i915_init_compile(struct i915_context *i915, static void i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) { + struct i915_fragment_shader *ifs = p->shader; unsigned long program_size = (unsigned long) (p->csr - p->program); unsigned long decl_size = (unsigned long) (p->decl - p->declarations); @@ -1008,19 +1051,13 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) if (p->nr_decl_insn > I915_MAX_DECL_INSN) i915_program_error(p, "Exceeded max DECL instructions"); - /* free old program, if present */ - if (i915->current.program) { - FREE(i915->current.program); - i915->current.program_len = 0; - } - if (p->error) { p->NumNativeInstructions = 0; p->NumNativeAluInstructions = 0; p->NumNativeTexInstructions = 0; p->NumNativeTexIndirections = 0; - i915_use_passthrough_shader(i915); + i915_use_passthrough_shader(ifs); } else { p->NumNativeInstructions @@ -1034,24 +1071,20 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) /* Copy compilation results to fragment program struct: */ - i915->current.program + assert(!ifs->program); + ifs->program = (uint *) MALLOC((program_size + decl_size) * sizeof(uint)); - if (i915->current.program) { - i915->current.program_len = program_size + decl_size; + if (ifs->program) { + ifs->program_len = program_size + decl_size; - memcpy(i915->current.program, + memcpy(ifs->program, p->declarations, decl_size * sizeof(uint)); - memcpy(i915->current.program + decl_size, + memcpy(ifs->program + decl_size, p->program, program_size * sizeof(uint)); } - - /* update number of constants */ - i915->current.num_constants[PIPE_SHADER_FRAGMENT] = p->num_constants; - assert(i915->current.num_constants[PIPE_SHADER_FRAGMENT] - >= i915->current.num_user_constants[PIPE_SHADER_FRAGMENT]); } /* Release the compilation struct: @@ -1085,7 +1118,7 @@ i915_find_wpos_space(struct i915_fp_compile *p) i915_program_error(p, "No free texcoord for wpos value"); } #else - if (p->shader->input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { + if (p->shader->state.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { /* frag shader using the fragment position input */ #if 0 assert(0); @@ -1106,7 +1139,7 @@ static void i915_fixup_depth_write(struct i915_fp_compile *p) { /* XXX assuming pos/depth is always in output[0] */ - if (p->shader->output_semantic_name[0] == TGSI_SEMANTIC_POSITION) { + if (p->shader->state.output_semantic_name[0] == TGSI_SEMANTIC_POSITION) { const uint depth = UREG(REG_TYPE_OD, 0); i915_emit_arith(p, @@ -1121,13 +1154,18 @@ i915_fixup_depth_write(struct i915_fp_compile *p) void -i915_translate_fragment_program( struct i915_context *i915 ) +i915_translate_fragment_program( struct i915_context *i915, + struct i915_fragment_shader *fs) { - struct i915_fp_compile *p = i915_init_compile(i915, i915->fs); - const struct tgsi_token *tokens = i915->fs->tokens; + struct i915_fp_compile *p = i915_init_compile(i915, fs); + const struct tgsi_token *tokens = fs->state.tokens; i915_find_wpos_space(p); +#if 0 + tgsi_dump(tokens, 0); +#endif + i915_translate_instructions(p, tokens); i915_fixup_depth_write(p); diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index e055eed7e0..e4288d4e31 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -38,6 +38,7 @@ #include "i915_reg.h" #include "i915_state.h" #include "i915_state_inlines.h" +#include "i915_fpc.h" /* The i915 (and related graphics cores) do not support GL_CLAMP. The @@ -416,26 +417,47 @@ static void i915_set_polygon_stipple( struct pipe_context *pipe, } -static void * i915_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *templ) + +static void * +i915_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) { - return 0; + struct i915_context *i915 = i915_context(pipe); + struct i915_fragment_shader *ifs = CALLOC_STRUCT(i915_fragment_shader); + if (!ifs) + return NULL; + + ifs->state = *templ; + + /* The shader's compiled to i915 instructions here */ + i915_translate_fragment_program(i915, ifs); + + return ifs; } -static void i915_bind_fs_state(struct pipe_context *pipe, void *fs) +static void +i915_bind_fs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); - i915->fs = (struct pipe_shader_state *)fs; + i915->fs = (struct i915_fragment_shader*) shader; i915->dirty |= I915_NEW_FS; } -static void i915_delete_fs_state(struct pipe_context *pipe, void *shader) +static +void i915_delete_fs_state(struct pipe_context *pipe, void *shader) { - /*do nothing*/ + struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader; + + if (ifs->program) + FREE(ifs->program); + ifs->program_len = 0; + + FREE(ifs); } + static void * i915_create_vs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) diff --git a/src/gallium/drivers/i915simple/i915_state_derived.c b/src/gallium/drivers/i915simple/i915_state_derived.c index 4767584fc6..f654f543cc 100644 --- a/src/gallium/drivers/i915simple/i915_state_derived.c +++ b/src/gallium/drivers/i915simple/i915_state_derived.c @@ -43,7 +43,7 @@ */ static void calculate_vertex_layout( struct i915_context *i915 ) { - const struct pipe_shader_state *fs = i915->fs; + const struct pipe_shader_state *fs = &i915->fs->state; const enum interp_mode colorInterp = i915->rasterizer->color_interp; struct vertex_info vinfo; uint front0 = 0, back0 = 0, front1 = 0, back1 = 0; @@ -164,7 +164,6 @@ void i915_update_derived( struct i915_context *i915 ) i915_update_dynamic( i915 ); if (i915->dirty & I915_NEW_FS) { - i915_translate_fragment_program(i915); i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */ } diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 3339287f49..6bbaac4e34 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -99,7 +99,11 @@ i915_emit_hardware_state(struct i915_context *i915 ) 2 + I915_TEX_UNITS*3 + 2 + I915_TEX_UNITS*3 + 2 + I915_MAX_CONSTANT*4 + +#if 0 i915->current.program_len + +#else + i915->fs->program_len + +#endif 6 ) * 3/2; /* plus 50% margin */ const unsigned relocs = ( I915_TEX_UNITS + @@ -325,15 +329,34 @@ i915_emit_hardware_state(struct i915_context *i915 ) /* 2 + I915_MAX_CONSTANT*4 dwords, 0 relocs */ if (i915->hardware_dirty & I915_HW_PROGRAM) { - const uint nr = i915->current.num_constants[PIPE_SHADER_FRAGMENT]; - assert(nr <= I915_MAX_CONSTANT); - if (nr > 0) { - const uint *c - = (const uint *) i915->current.constants[PIPE_SHADER_FRAGMENT]; + /* Collate the user-defined constants with the fragment shader's + * immediates according to the constant_flags[] array. + */ + const uint nr = i915->fs->num_constants; + if (nr) { uint i; + OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) ); OUT_BATCH( (1 << (nr - 1)) | ((1 << (nr - 1)) - 1) ); + for (i = 0; i < nr; i++) { + const uint *c; + if (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER) { + /* grab user-defined constant */ + c = (uint *) i915->current.constants[PIPE_SHADER_FRAGMENT][i]; + } + else { + /* emit program constant */ + c = (uint *) i915->fs->constants[i]; + } +#if 0 /* debug */ + { + float *f = (float *) c; + printf("Const %2d: %f %f %f %f %s\n", i, f[0], f[1], f[2], f[3], + (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER + ? "user" : "immediate")); + } +#endif OUT_BATCH(*c++); OUT_BATCH(*c++); OUT_BATCH(*c++); @@ -348,9 +371,9 @@ i915_emit_hardware_state(struct i915_context *i915 ) { uint i; /* we should always have, at least, a pass-through program */ - assert(i915->current.program_len > 0); - for (i = 0; i < i915->current.program_len; i++) { - OUT_BATCH(i915->current.program[i]); + assert(i915->fs->program_len > 0); + for (i = 0; i < i915->fs->program_len; i++) { + OUT_BATCH(i915->fs->program[i]); } } -- cgit v1.2.3 From e9276efafe43219d7af548ce7f5d2440e19836b0 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 22 Feb 2008 17:22:10 -0700 Subject: gallium: fix bug in which wide point stage overrode the aapoint stage Also, simplify the logic a bit. --- src/gallium/auxiliary/draw/draw_validate.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index efd6793f2b..3a19dd4cd7 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -45,6 +45,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) struct draw_stage *next = draw->pipeline.rasterize; int need_det = 0; int precalc_flat = 0; + boolean wide_lines, wide_points; /* Set the validate's next stage to the rasterize stage, so that it * can be found later if needed for flushing. @@ -68,9 +69,18 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) next = draw->pipeline.aapoint; } - if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines - && !draw->rasterizer->line_smooth) || - (draw->rasterizer->point_size != 1.0 && draw->convert_wide_points) || + /* drawing wide lines? */ + wide_lines = (draw->rasterizer->line_width != 1.0 + && draw->convert_wide_lines + && !draw->rasterizer->line_smooth); + + /* drawing large points? */ + wide_points = (draw->rasterizer->point_size != 1.0 + && draw->convert_wide_points + && !draw->pipeline.aapoint); + + if (wide_lines || + wide_points || draw->rasterizer->point_sprite) { draw->pipeline.wide->next = next; next = draw->pipeline.wide; -- cgit v1.2.3 From aec315f05f860337bccfce827a7c1c80960dd476 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 22 Feb 2008 18:34:31 -0700 Subject: gallium: fix a state validation bug found w/ pointblast.c --- src/gallium/drivers/softpipe/sp_prim_setup.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 7b1e131ee1..b6a3fddb29 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -1165,6 +1165,10 @@ static void setup_begin( struct draw_stage *stage ) struct softpipe_context *sp = setup->softpipe; const struct pipe_shader_state *fs = &setup->softpipe->fs->shader; + if (sp->dirty) { + softpipe_update_derived(sp); + } + setup->quad.nr_attrs = fs->num_inputs; sp->quad.first->begin(sp->quad.first); -- cgit v1.2.3 From e8de5c70e3370e9112a5facc870075eea60c4c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 23 Feb 2008 14:14:54 +0900 Subject: Bring in several forgotten MSVC fixes. --- src/gallium/auxiliary/pipebuffer/pb_buffer.h | 1 + src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 4 ++-- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 2 +- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 4 +++- src/gallium/drivers/softpipe/sp_fs_exec.c | 4 ++-- src/gallium/drivers/softpipe/sp_fs_llvm.c | 2 +- src/gallium/include/pipe/p_compiler.h | 8 ++++++++ 7 files changed, 18 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index 97beb5f72a..f5b5f4052f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -166,6 +166,7 @@ static INLINE void pb_destroy(struct pb_buffer *buf) { assert(buf); + assert(buf->vtbl); buf->vtbl->destroy(buf); } diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index ff4fd123f3..66256f3fa7 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -192,8 +192,8 @@ mm_bufmgr_create_buffer(struct pb_manager *mgr, } /* Some sanity checks */ - assert(0 <= mm_buf->block->ofs && mm_buf->block->ofs < mm->size); - assert(size <= mm_buf->block->size && mm_buf->block->ofs + mm_buf->block->size <= mm->size); + assert(0 <= (unsigned)mm_buf->block->ofs && (unsigned)mm_buf->block->ofs < mm->size); + assert(size <= (unsigned)mm_buf->block->size && (unsigned)mm_buf->block->ofs + (unsigned)mm_buf->block->size <= mm->size); _glthread_UNLOCK_MUTEX(mm->mutex); return SUPER(mm_buf); diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index d7b18dc9c5..ac52441400 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -2455,7 +2455,7 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach ) /* execute instructions, until pc is set to -1 */ while (pc != -1) { - assert(pc < mach->NumInstructions); + assert(pc < (int) mach->NumInstructions); exec_instruction( mach, mach->Instructions + pc, &pc ); } diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index b5c54847e0..ff74e6117c 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -299,7 +299,8 @@ static const char *TGSI_SEMANTICS[] = "SEMANTIC_BCOLOR", "SEMANTIC_FOG", "SEMANTIC_PSIZE", - "SEMANTIC_GENERIC," + "SEMANTIC_GENERIC", + "SEMANTIC_NORMAL" }; static const char *TGSI_SEMANTICS_SHORT[] = @@ -310,6 +311,7 @@ static const char *TGSI_SEMANTICS_SHORT[] = "FOG", "PSIZE", "GENERIC", + "NORMAL" }; static const char *TGSI_IMMS[] = diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index 8cb0534342..d5bd7a702f 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -81,7 +81,7 @@ sp_setup_pos_vector(const struct tgsi_interp_coef *coef, static void -exec_prepare( struct sp_fragment_shader *base, +exec_prepare( const struct sp_fragment_shader *base, struct tgsi_exec_machine *machine, struct tgsi_sampler *samplers ) { @@ -98,7 +98,7 @@ exec_prepare( struct sp_fragment_shader *base, * interface: */ static unsigned -exec_run( struct sp_fragment_shader *base, +exec_run( const struct sp_fragment_shader *base, struct tgsi_exec_machine *machine, struct quad_header *quad ) { diff --git a/src/gallium/drivers/softpipe/sp_fs_llvm.c b/src/gallium/drivers/softpipe/sp_fs_llvm.c index 22da471453..34b2b7d4e2 100644 --- a/src/gallium/drivers/softpipe/sp_fs_llvm.c +++ b/src/gallium/drivers/softpipe/sp_fs_llvm.c @@ -146,7 +146,7 @@ shade_quad_llvm(struct quad_stage *qs, unsigned -run_llvm_fs( struct sp_fragment_shader *base, +run_llvm_fs( const struct sp_fragment_shader *base, struct foo *machine ) { } diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index ab527f2afe..91f3d2ac2d 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -42,6 +42,14 @@ #endif +#if defined(__MSC__) + +/* Avoid 'expression is always true' warning */ +#pragma warning(disable: 4296) + +#endif /* __MSC__ */ + + typedef unsigned int uint; typedef unsigned char ubyte; typedef unsigned char boolean; -- cgit v1.2.3 From 58a3d7dfd94453c25607106835fbbb3a54d42306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 23 Feb 2008 19:49:08 +0900 Subject: Revamp scons usage. --- src/gallium/SConscript | 16 ++++------------ src/gallium/winsys/SConscript | 2 +- 2 files changed, 5 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 210fd7d309..fa4833cbcf 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -1,3 +1,5 @@ +import os + Import('*') env = env.Clone() @@ -20,15 +22,5 @@ SConscript([ if llvm: SConscript(['auxiliary/gallivm/SConscript']) -SConscript([ - 'drivers/softpipe/SConscript', - 'drivers/i915simple/SConscript', - 'drivers/failover/SConscript', -]) - -if not msvc: - SConscript(['drivers/i965simple/SConscript']) - -#if cell: -# SConscript(['drivers/cell/SConscript']) - \ No newline at end of file +for driver in env['drivers']: + SConscript(os.path.join('drivers', driver, 'SConscript')) diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index 3f0596e19c..635a68eea2 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -5,7 +5,7 @@ if dri: 'dri/SConscript', ]) -if env['x11'] and not dri and platform != 'winddk': +if 'xlib' in env['drivers'] and not dri: SConscript([ 'xlib/SConscript', ]) -- cgit v1.2.3 From e9bb63c8e20361597463b2f7f88d84fe2770c8b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 24 Feb 2008 02:16:28 +0900 Subject: gallium: MSVC fixes. --- src/gallium/auxiliary/draw/draw_aapoint.c | 6 +++--- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 2 ++ src/gallium/drivers/softpipe/sp_state.h | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c index 43119cc70b..27a81f3e90 100644 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -616,10 +616,10 @@ aapoint_point(struct draw_stage *stage, struct prim_header *header) */ #if !NORMALIZE - k = 1.0 / radius; - k = 1.0 - 2.0 * k + k * k; + k = 1.0f / radius; + k = 1.0f - 2.0f * k + k * k; #else - k = 1.0 - 1.0 / radius; + k = 1.0f - 1.0f / radius; #endif /* allocate/dup new verts */ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index e2ee72ed1f..6e217eb2e0 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -285,7 +285,9 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list) /* Wait on outstanding fences */ while (fenced_list->numDelayed) { _glthread_UNLOCK_MUTEX(fenced_list->mutex); +#ifndef __MSC__ sched_yield(); +#endif _fenced_buffer_list_check_free(fenced_list, 1); _glthread_LOCK_MUTEX(fenced_list->mutex); } diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index ef8cf67d4c..6ff31e601f 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -63,14 +63,14 @@ struct tgsi_exec_machine; struct sp_fragment_shader { struct pipe_shader_state shader; - void (*prepare)( struct sp_fragment_shader *shader, + void (*prepare)( const struct sp_fragment_shader *shader, struct tgsi_exec_machine *machine, struct tgsi_sampler *samplers); /* Run the shader - this interface will get cleaned up in the * future: */ - unsigned (*run)( struct sp_fragment_shader *shader, + unsigned (*run)( const struct sp_fragment_shader *shader, struct tgsi_exec_machine *machine, struct quad_header *quad ); -- cgit v1.2.3 From 1d77d6caf647424f9c1c481145be0465e96c9e3e Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 23 Feb 2008 16:15:29 -0700 Subject: gallium: added new tgsi_scan.c / tgsi_scan_shader() function Used to get information about registers, instructions used in a shader. --- src/gallium/auxiliary/tgsi/Makefile | 1 + src/gallium/auxiliary/tgsi/util/tgsi_scan.c | 117 ++++++++++++++++++++++++++++ src/gallium/auxiliary/tgsi/util/tgsi_scan.h | 57 ++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_scan.c create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_scan.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index 71f64b747c..5555639b70 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -9,6 +9,7 @@ C_SOURCES = \ util/tgsi_build.c \ util/tgsi_dump.c \ util/tgsi_parse.c \ + util/tgsi_scan.c \ util/tgsi_transform.c \ util/tgsi_util.c diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c new file mode 100644 index 0000000000..4b99ac37cc --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c @@ -0,0 +1,117 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * TGSI program scan utility. + * Used to determine which registers and instructions are used by a shader. + * + * Authors: Brian Paul + */ + + +#include "tgsi_scan.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_build.h" + + + + +/** + */ +void +tgsi_scan_shader(const struct tgsi_token *tokens, + struct tgsi_shader_info *info) +{ + uint procType; + struct tgsi_parse_context parse; + + memset(info, 0, sizeof(*info)); + + /** + ** Setup to begin parsing input shader + **/ + if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) { + debug_printf("tgsi_parse_init() failed in tgsi_scan_shader()!\n"); + return; + } + procType = parse.FullHeader.Processor.Processor; + assert(procType == TGSI_PROCESSOR_FRAGMENT || + procType == TGSI_PROCESSOR_VERTEX || + procType == TGSI_PROCESSOR_GEOMETRY); + + + /** + ** Loop over incoming program tokens/instructions + */ + while( !tgsi_parse_end_of_tokens( &parse ) ) { + + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *fullinst + = &parse.FullToken.FullInstruction; + + assert(fullinst->Instruction.Opcode < TGSI_OPCODE_LAST); + info->opcode_count[fullinst->Instruction.Opcode]++; + } + break; + + case TGSI_TOKEN_TYPE_DECLARATION: + { + struct tgsi_full_declaration *fulldecl + = &parse.FullToken.FullDeclaration; + uint file = fulldecl->Declaration.File; + uint i; + for (i = fulldecl->u.DeclarationRange.First; + i <= fulldecl->u.DeclarationRange.Last; + i++) { + info->file_mask[file] |= (1 << i); + info->file_count[file]++; + + /* special case */ + if (procType == TGSI_PROCESSOR_FRAGMENT && + file == TGSI_FILE_OUTPUT && + fulldecl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { + info->writes_z = TRUE; + } + } + } + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + info->immediate_count++; + break; + + default: + assert( 0 ); + } + } + + tgsi_parse_free (&parse); +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h new file mode 100644 index 0000000000..757446437c --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h @@ -0,0 +1,57 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_SCAN_H +#define TGSI_SCAN_H + + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + + +/** + * Shader summary info + */ +struct tgsi_shader_info +{ + uint file_mask[TGSI_FILE_COUNT]; /**< bitmask of declared registers */ + uint file_count[TGSI_FILE_COUNT]; /**< number of declared registers */ + + uint immediate_count; /**< number of immediates declared */ + + uint opcode_count[TGSI_OPCODE_LAST]; /**< opcode histogram */ + + boolean writes_z; /**< does fragment shader write Z value? */ +}; + + +extern void +tgsi_scan_shader(const struct tgsi_token *tokens, + struct tgsi_shader_info *info); + + +#endif /* TGSI_SCAN_H */ -- cgit v1.2.3 From 35ca45daba3906ac94fb879d2374d476ba2dac47 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 23 Feb 2008 16:15:54 -0700 Subject: gallium: added TGSI_FILE_COUNT --- src/gallium/include/pipe/p_shader_tokens.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 10c47e0ef0..1806877f6c 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -50,6 +50,8 @@ struct tgsi_token #define TGSI_FILE_SAMPLER 5 #define TGSI_FILE_ADDRESS 6 #define TGSI_FILE_IMMEDIATE 7 +#define TGSI_FILE_COUNT 8 /**< how many TGSI_FILE_ types */ + #define TGSI_DECLARE_RANGE 0 #define TGSI_DECLARE_MASK 1 -- cgit v1.2.3 From 012391357fcbefd2b34e999eed91a129d5efd77c Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 23 Feb 2008 16:17:17 -0700 Subject: gallium: disable early Z test if fragment shader contains KIL instruction. Use tgsi_scan_shader() to determine if the fragment shader uses KIL or writes fragment.z --- src/gallium/drivers/softpipe/sp_quad.c | 5 +++-- src/gallium/drivers/softpipe/sp_state.h | 3 +++ src/gallium/drivers/softpipe/sp_state_fs.c | 22 +++++++++++++--------- 3 files changed, 19 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad.c b/src/gallium/drivers/softpipe/sp_quad.c index 15b5594547..142dbcc771 100644 --- a/src/gallium/drivers/softpipe/sp_quad.c +++ b/src/gallium/drivers/softpipe/sp_quad.c @@ -56,11 +56,12 @@ sp_build_depth_stencil( void sp_build_quad_pipeline(struct softpipe_context *sp) { - boolean early_depth_test = + boolean early_depth_test = sp->depth_stencil->depth.enabled && sp->framebuffer.zsbuf && !sp->depth_stencil->alpha.enabled && - sp->fs->shader.output_semantic_name[0] != TGSI_SEMANTIC_POSITION; + !sp->fs->uses_kill && + !sp->fs->writes_z; /* build up the pipeline in reverse order... */ diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 6ff31e601f..5aaa9e346b 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -63,6 +63,9 @@ struct tgsi_exec_machine; struct sp_fragment_shader { struct pipe_shader_state shader; + boolean uses_kill; + boolean writes_z; + void (*prepare)( const struct sp_fragment_shader *shader, struct tgsi_exec_machine *machine, struct tgsi_sampler *samplers); diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index b0238f8173..b184ac61bb 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -36,6 +36,7 @@ #include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" #include "tgsi/util/tgsi_dump.h" +#include "tgsi/util/tgsi_scan.h" void * @@ -44,21 +45,24 @@ softpipe_create_fs_state(struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state; + struct tgsi_shader_info info; + + tgsi_scan_shader(templ->tokens, &info); if (softpipe->dump_fs) tgsi_dump(templ->tokens, 0); state = softpipe_create_fs_llvm( softpipe, templ ); - if (state) - return state; - - state = softpipe_create_fs_sse( softpipe, templ ); - if (state) - return state; - - state = softpipe_create_fs_exec( softpipe, templ ); - + if (!state) { + state = softpipe_create_fs_sse( softpipe, templ ); + if (!state) { + state = softpipe_create_fs_exec( softpipe, templ ); + } + } assert(state); + state->uses_kill = (info.opcode_count[TGSI_OPCODE_KIL] || + info.opcode_count[TGSI_OPCODE_KILP]); + state->writes_z = info.writes_z; return state; } -- cgit v1.2.3 From 7aadb475e58b91f3c17c2a70f6700225e9ef25ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 24 Feb 2008 02:46:46 +0900 Subject: gallium: Fix MSVC warnings. --- src/gallium/auxiliary/draw/draw_pstipple.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index 4048abf856..1ab04cd959 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -133,7 +133,7 @@ pstip_transform_decl(struct tgsi_transform_context *ctx, pctx->maxSampler = (int) decl->u.DeclarationRange.Last; } else if (decl->Declaration.File == TGSI_FILE_INPUT) { - pctx->maxInput = MAX2(pctx->maxInput, decl->u.DeclarationRange.Last); + pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last); if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) pctx->wincoordInput = (int) decl->u.DeclarationRange.First; } @@ -332,7 +332,7 @@ generate_pstip_fs(struct pstip_stage *pstip) if (transform.wincoordInput < 0) { pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION; - pstip_fs.input_semantic_index[pstip_fs.num_inputs] = transform.maxInput; + pstip_fs.input_semantic_index[pstip_fs.num_inputs] = (ubyte)transform.maxInput; pstip_fs.num_inputs++; } -- cgit v1.2.3 From fdcb9260eea8f9b9deaeeade2a46cffbf3dcaa59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 24 Feb 2008 17:58:05 +0900 Subject: Add new files. --- src/gallium/auxiliary/draw/SConscript | 3 +++ src/gallium/auxiliary/tgsi/SConscript | 2 ++ src/gallium/drivers/softpipe/SConscript | 3 +++ 3 files changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 8e3a8caa74..3302dc44f7 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -3,6 +3,8 @@ Import('*') draw = env.ConvenienceLibrary( target = 'draw', source = [ + 'draw_aaline.c', + 'draw_aapoint.c', 'draw_clip.c', 'draw_vs_exec.c', 'draw_vs_sse.c', @@ -13,6 +15,7 @@ draw = env.ConvenienceLibrary( 'draw_flatshade.c', 'draw_offset.c', 'draw_prim.c', + 'draw_pstipple.c', 'draw_stipple.c', 'draw_twoside.c', 'draw_unfilled.c', diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript index 8464bfe944..4632dcc072 100644 --- a/src/gallium/auxiliary/tgsi/SConscript +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -8,6 +8,8 @@ tgsi = env.ConvenienceLibrary( 'util/tgsi_build.c', 'util/tgsi_dump.c', 'util/tgsi_parse.c', + 'util/tgsi_scan.c', + 'util/tgsi_transform.c', 'util/tgsi_util.c', ]) diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index d581ee8d3c..4c1a6d5df0 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -5,6 +5,9 @@ env = env.Clone() softpipe = env.ConvenienceLibrary( target = 'softpipe', source = [ + 'sp_fs_exec.c', + 'sp_fs_sse.c', + 'sp_fs_llvm.c', 'sp_clear.c', 'sp_context.c', 'sp_draw_arrays.c', -- cgit v1.2.3 From b75706764b4cf18f3b41bf4a97d82b3c528064d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 25 Feb 2008 15:18:33 +0900 Subject: Add Zack's comments about CSOs. --- src/gallium/auxiliary/cso_cache/cso_cache.h | 51 ++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h index b4f4f3ae41..3a005a376e 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.h +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -25,9 +25,48 @@ * **************************************************************************/ - /* - * Authors: - * Zack Rusin + /** + * @file + * Constant State Object (CSO) cache. + * + * The basic idea is that the states are created via the + * create_state/bind_state/delete_state semantics. The driver is expected to + * perform as much of the Gallium state translation to whatever its internal + * representation is during the create call. Gallium then has a caching + * mechanism where it stores the created states. When the pipeline needs an + * actual state change, a bind call is issued. In the bind call the driver + * gets its already translated representation. + * + * Those semantics mean that the driver doesn't do the repeated translations + * of states on every frame, but only once, when a new state is actually + * created. + * + * Even on hardware that doesn't do any kind of state cache, it makes the + * driver look a lot neater, plus it avoids all the redundant state + * translations on every frame. + * + * Currently our constant state objects are: + * - alpha test + * - blend + * - depth stencil + * - fragment shader + * - rasterizer (old setup) + * - sampler + * - vertex shader + * + * Things that are not constant state objects include: + * - blend_color + * - clip_state + * - clear_color_state + * - constant_buffer + * - feedback_state + * - framebuffer_state + * - polygon_stipple + * - scissor_state + * - texture_state + * - viewport_state + * + * @author Zack Rusin */ #ifndef CSO_CACHE_H @@ -36,7 +75,9 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "cso_hash.h" /* for cso_hash_iter, as MSVC requires structures returned by value to be fully defined */ +/* cso_hash.h is necessary for cso_hash_iter, as MSVC requires structures + * returned by value to be fully defined */ +#include "cso_hash.h" #ifdef __cplusplus -- cgit v1.2.3 From 2a0675eb75b8ca52efab739218bf93922bf884b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 25 Feb 2008 16:39:39 +0900 Subject: Replace standand library functions by portable ones. --- src/gallium/auxiliary/cso_cache/cso_cache.c | 6 +++-- src/gallium/auxiliary/cso_cache/cso_hash.c | 34 ++++++++++++++--------------- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index 776ce6bacf..9c32e94124 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -28,6 +28,8 @@ /* Authors: Zack Rusin */ +#include "pipe/p_util.h" + #include "cso_cache.h" #include "cso_hash.h" @@ -176,7 +178,7 @@ void * cso_take_state(struct cso_cache *sc, struct cso_cache *cso_cache_create(void) { - struct cso_cache *sc = malloc(sizeof(struct cso_cache)); + struct cso_cache *sc = MALLOC_STRUCT(cso_cache); sc->blend_hash = cso_hash_create(); sc->sampler_hash = cso_hash_create(); @@ -197,5 +199,5 @@ void cso_cache_delete(struct cso_cache *sc) cso_hash_delete(sc->rasterizer_hash); cso_hash_delete(sc->fs_hash); cso_hash_delete(sc->vs_hash); - free(sc); + FREE(sc); } diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index e65d331a0b..208fc58502 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -30,12 +30,10 @@ * Zack Rusin */ -#include "cso_hash.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" -#include -#include -#include -#include +#include "cso_hash.h" #define MAX(a, b) ((a > b) ? (a) : (b)) @@ -98,7 +96,7 @@ struct cso_hash { static void *cso_data_allocate_node(struct cso_hash_data *hash) { - return malloc(hash->nodeSize); + return MALLOC(hash->nodeSize); } static void cso_data_free_node(struct cso_node *node) @@ -107,10 +105,10 @@ static void cso_data_free_node(struct cso_node *node) * Need to cast value ptr to original cso type, then free the * driver-specific data hanging off of it. For example: struct cso_sampler *csamp = (struct cso_sampler *) node->value; - free(csamp->data); + FREE(csamp->data); */ - free(node->value); - free(node); + FREE(node->value); + FREE(node); } static struct cso_node * @@ -149,7 +147,7 @@ static void cso_data_rehash(struct cso_hash_data *hash, int hint) hash->numBits = (short)hint; hash->numBuckets = primeForNumBits(hint); - hash->buckets = malloc(sizeof(struct cso_node*) * hash->numBuckets); + hash->buckets = MALLOC(sizeof(struct cso_node*) * hash->numBuckets); for (i = 0; i < hash->numBuckets; ++i) hash->buckets[i] = e; @@ -173,7 +171,7 @@ static void cso_data_rehash(struct cso_hash_data *hash, int hint) firstNode = afterLastNode; } } - free(oldBuckets); + FREE(oldBuckets); } } @@ -235,8 +233,8 @@ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, struct cso_hash * cso_hash_create(void) { - struct cso_hash *hash = malloc(sizeof(struct cso_hash)); - hash->data.d = malloc(sizeof(struct cso_hash_data)); + struct cso_hash *hash = MALLOC_STRUCT(cso_hash); + hash->data.d = MALLOC_STRUCT(cso_hash_data); hash->data.d->fakeNext = 0; hash->data.d->buckets = 0; hash->data.d->size = 0; @@ -261,9 +259,9 @@ void cso_hash_delete(struct cso_hash *hash) cur = next; } } - free(hash->data.d->buckets); - free(hash->data.d); - free(hash); + FREE(hash->data.d->buckets); + FREE(hash->data.d); + FREE(hash); } struct cso_hash_iter cso_hash_find(struct cso_hash *hash, @@ -301,7 +299,7 @@ static struct cso_node *cso_hash_data_next(struct cso_node *node) a.next = node->next; if (!a.next) { - fprintf(stderr, "iterating beyond the last element\n"); + debug_printf("iterating beyond the last element\n"); return 0; } if (a.next->next) @@ -352,7 +350,7 @@ static struct cso_node *cso_hash_data_prev(struct cso_node *node) --bucket; --start; } - fprintf(stderr, "iterating backward beyond first element\n"); + debug_printf("iterating backward beyond first element\n"); return a.e; } -- cgit v1.2.3 From e4e30089231831339815cccebf3a3a0ea6dcd2a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 25 Feb 2008 20:05:41 +0900 Subject: Make the pipe headers C++ friendly. --- src/gallium/include/pipe/p_context.h | 10 ++++++++++ src/gallium/include/pipe/p_defines.h | 8 ++++++++ src/gallium/include/pipe/p_format.h | 8 ++++++++ src/gallium/include/pipe/p_inlines.h | 9 +++++++++ src/gallium/include/pipe/p_pointer.h | 8 ++++++++ src/gallium/include/pipe/p_state.h | 10 ++++++++++ src/gallium/include/pipe/p_util.h | 16 ++++++++-------- src/gallium/include/pipe/p_winsys.h | 20 ++++++++++++++------ 8 files changed, 75 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 036c4c8964..f69b52f5e3 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -31,6 +31,11 @@ #include "p_state.h" +#ifdef __cplusplus +extern "C" { +#endif + + struct pipe_state_cache; /* Opaque driver handles: @@ -226,4 +231,9 @@ struct pipe_context { unsigned flags ); }; + +#ifdef __cplusplus +} +#endif + #endif /* PIPE_CONTEXT_H */ diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 0bf53ecb79..d84ddbc27a 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -30,6 +30,10 @@ #include "p_format.h" +#ifdef __cplusplus +extern "C" { +#endif + #define PIPE_BLENDFACTOR_ONE 0x1 #define PIPE_BLENDFACTOR_SRC_COLOR 0x2 #define PIPE_BLENDFACTOR_SRC_ALPHA 0x3 @@ -267,4 +271,8 @@ enum pipe_texture_target { #define PIPE_CAP_MAX_TEXTURE_LOD_BIAS 19 #define PIPE_CAP_BITMAP_TEXCOORD_BIAS 20 +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index c9ad324315..561d2e5921 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -33,6 +33,10 @@ #include "p_compiler.h" #include "p_debug.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * The PIPE_FORMAT is a 32-bit wide bitfield that encodes all the information * needed to uniquely describe a pixel format. @@ -418,4 +422,8 @@ static INLINE uint pf_get_size( enum pipe_format format ) { return pf_get_bits(format) / 8; } +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index ebf6ed86bc..de3fa555c5 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -33,6 +33,11 @@ #include "p_winsys.h" +#ifdef __cplusplus +extern "C" { +#endif + + static INLINE void * pipe_surface_map(struct pipe_surface *surface) { @@ -109,4 +114,8 @@ pipe_texture_reference(struct pipe_context *pipe, struct pipe_texture **ptr, } +#ifdef __cplusplus +} +#endif + #endif /* P_INLINES_H */ diff --git a/src/gallium/include/pipe/p_pointer.h b/src/gallium/include/pipe/p_pointer.h index e3927538e8..3a1e6be88e 100644 --- a/src/gallium/include/pipe/p_pointer.h +++ b/src/gallium/include/pipe/p_pointer.h @@ -30,6 +30,10 @@ #include "p_compiler.h" +#ifdef __cplusplus +extern "C" { +#endif + static INLINE intptr_t pointer_to_intptr( const void *p ) { @@ -84,4 +88,8 @@ align_pointer( const void *unaligned, uintptr_t alignment ) return uintptr_to_pointer( aligned ); } +#ifdef __cplusplus +} +#endif + #endif /* P_POINTER_H */ diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 47fa78c31d..15c88881eb 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -42,6 +42,12 @@ #include "p_defines.h" #include "p_format.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /** * Implementation limits */ @@ -326,4 +332,8 @@ struct pipe_vertex_element }; +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 6f0dbdacd9..3b32ba1d24 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -34,13 +34,13 @@ #include -#ifdef WIN32 - #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif + +#ifdef WIN32 + void * __stdcall EngAllocMem( unsigned long Flags, @@ -51,10 +51,6 @@ void __stdcall EngFreeMem( void *Mem ); -#ifdef __cplusplus -} -#endif - static INLINE void * MALLOC( unsigned size ) { @@ -379,4 +375,8 @@ extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, int src_pitch, unsigned src_x, int src_y); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index 1e81eebd78..e784c92491 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -25,12 +25,6 @@ * **************************************************************************/ -#ifndef P_WINSYS_H -#define P_WINSYS_H - - -#include "p_format.h" - /** * \file * This is the interface that Gallium3D requires any window system @@ -38,6 +32,17 @@ * which is public. */ +#ifndef P_WINSYS_H +#define P_WINSYS_H + + +#include "p_format.h" + + +#ifdef __cplusplus +extern "C" { +#endif + /** Opaque type */ struct pipe_fence_handle; @@ -156,5 +161,8 @@ struct pipe_winsys }; +#ifdef __cplusplus +} +#endif #endif /* P_WINSYS_H */ -- cgit v1.2.3 From 20839b37ed61b044d6224c0e373ce10d74be4f3d Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 11:13:58 -0700 Subject: gallium/i915: added SGT/SLE opcodes --- .../drivers/i915simple/i915_fpc_translate.c | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index afe7e25dce..50c9e65409 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -385,6 +385,26 @@ emit_simple_arith(struct i915_fp_compile *p, arg3 ); } + +/** As above, but swap the first two src regs */ +static void +emit_simple_arith_swap2(struct i915_fp_compile *p, + const struct tgsi_full_instruction *inst, + uint opcode, uint numArgs) +{ + struct tgsi_full_instruction inst2; + + assert(numArgs == 2); + + /* transpose first two registers */ + inst2 = *inst; + inst2.FullSrcRegisters[0] = inst->FullSrcRegisters[1]; + inst2.FullSrcRegisters[1] = inst->FullSrcRegisters[0]; + + emit_simple_arith(p, &inst2, opcode, numArgs); +} + + #ifndef M_PI #define M_PI 3.14159265358979323846 #endif @@ -772,6 +792,11 @@ i915_translate_instruction(struct i915_fp_compile *p, emit_simple_arith(p, inst, A0_SGE, 2); break; + case TGSI_OPCODE_SLE: + /* like SGE, but swap reg0, reg1 */ + emit_simple_arith_swap2(p, inst, A0_SGE, 2); + break; + case TGSI_OPCODE_SIN: src0 = src_vector(p, &inst->FullSrcRegisters[0]); tmp = i915_get_utemp(p); @@ -826,6 +851,11 @@ i915_translate_instruction(struct i915_fp_compile *p, emit_simple_arith(p, inst, A0_SLT, 2); break; + case TGSI_OPCODE_SGT: + /* like SLT, but swap reg0, reg1 */ + emit_simple_arith_swap2(p, inst, A0_SLT, 2); + break; + case TGSI_OPCODE_SUB: src0 = src_vector(p, &inst->FullSrcRegisters[0]); src1 = src_vector(p, &inst->FullSrcRegisters[1]); @@ -879,6 +909,7 @@ i915_translate_instruction(struct i915_fp_compile *p, default: i915_program_error(p, "bad opcode %d", inst->Instruction.Opcode); + p->error = 1; return; } -- cgit v1.2.3 From ea02342c11eaeb700495b403caecc13a129333e8 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 11:21:03 -0700 Subject: gallium/i915: Use hardware rendering, unless INTEL_SP env var is set --- src/gallium/winsys/dri/intel/intel_context.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index c033f2a592..79b320c6bf 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -188,7 +188,8 @@ intelCreateContext(const __GLcontextModes * visual, /* * Pipe-related setup */ - if (!getenv("INTEL_HW")) { + if (getenv("INTEL_SP")) { + /* use softpipe driver instead of hw */ pipe = intel_create_softpipe( intel, intelScreen->winsys ); } else { -- cgit v1.2.3 From d6c7f7e314ee9f034402c919d142bf6ba9844ec9 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 14:46:42 -0700 Subject: gallium: modify draw_find_vs_output() to search vertex shader outputs This simplifies drivers using the draw module and removes the last dependency on vertex-shader "internals". Since the draw module is producing the post-transformed vertices, it makes sense to ask it where specific vertex attributes are located. This could also simplify some things in the state tracker code for selection, feedback, rasterpos... --- src/gallium/auxiliary/draw/draw_context.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index c28e78d33a..6e5e4d64d1 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -244,14 +244,32 @@ draw_convert_wide_lines(struct draw_context *draw, boolean enable) /** - * The draw module may sometimes generate vertices with extra attributes - * (such as texcoords for AA lines). The driver can call this function - * to find those attributes. + * Ask the draw module for the location/slot of the given vertex attribute in + * a post-transformed vertex. + * + * With this function, drivers that use the draw module should have no reason + * to track the current vertex shader. + * + * Note that the draw module may sometimes generate vertices with extra + * attributes (such as texcoords for AA lines). The driver can call this + * function to find those attributes. + * + * Zero is returned if the attribute is not found since this is + * a don't care / undefined situtation. Returning -1 would be a bit more + * work for the drivers. */ int draw_find_vs_output(struct draw_context *draw, uint semantic_name, uint semantic_index) { + const struct pipe_shader_state *vs = &draw->vertex_shader->state; + uint i; + for (i = 0; i < vs->num_outputs; i++) { + if (vs->output_semantic_name[i] == semantic_name && + vs->output_semantic_index[i] == semantic_index) + return i; + } + /* XXX there may be more than one extra vertex attrib. * For example, simulated gl_FragCoord and gl_PointCoord. */ -- cgit v1.2.3 From c037b4d45a551dc7b7dd33950c2e8df60449061c Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 14:47:13 -0700 Subject: softpipe: use draw_find_vs_output() directly --- src/gallium/drivers/softpipe/sp_state_derived.c | 39 +++++-------------------- 1 file changed, 7 insertions(+), 32 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index f9f2c5eaa8..4c6313001f 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -34,33 +34,6 @@ #include "sp_state.h" -/** - * Search vertex program's outputs to find a match for the given - * semantic name/index. Return the index of the output slot. - * - * Return 0 if not found. This will cause the fragment program to use - * vertex attrib 0 (position) in the cases where the fragment program - * attempts to use a missing vertex program output. This is an undefined - * condition that users shouldn't hit anyway. - */ -static int -find_vs_output(struct softpipe_context *sp, - const struct pipe_shader_state *vs, - uint semantic_name, - uint semantic_index) -{ - uint i; - for (i = 0; i < vs->num_outputs; i++) { - if (vs->output_semantic_name[i] == semantic_name && - vs->output_semantic_index[i] == semantic_index) - return i; - } - - /* See if the draw module is introducing a new attribute... */ - return draw_find_vs_output(sp->draw, semantic_name, semantic_index); -} - - /** * Mark the current vertex layout as "invalid". * We'll validate the vertex layout later, when we start to actually @@ -114,24 +87,25 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) int src; switch (fs->input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: - src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_POSITION, 0); + src = draw_find_vs_output(softpipe->draw, + TGSI_SEMANTIC_POSITION, 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src); break; case TGSI_SEMANTIC_COLOR: - src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_COLOR, + src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_COLOR, fs->input_semantic_index[i]); draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); break; case TGSI_SEMANTIC_FOG: - src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_FOG, 0); + src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_FOG, 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); break; case TGSI_SEMANTIC_GENERIC: /* this includes texcoords and varying vars */ - src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_GENERIC, + src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_GENERIC, fs->input_semantic_index[i]); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); break; @@ -141,7 +115,8 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) } } - softpipe->psize_slot = find_vs_output(softpipe, vs, TGSI_SEMANTIC_PSIZE, 0); + softpipe->psize_slot = draw_find_vs_output(softpipe->draw, + TGSI_SEMANTIC_PSIZE, 0); if (softpipe->psize_slot > 0) { draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, softpipe->psize_slot); -- cgit v1.2.3 From 846b7fbc6c9cbd57eed01bd04b1da73109935091 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 14:48:31 -0700 Subject: gallium/i915: use draw_find_vs_output() directly, fix broken fogcoords. We now produce the correct 915 vertex layout regardless of the order in which fragment shader inputs are declared. --- .../drivers/i915simple/i915_state_derived.c | 99 ++++++++++++---------- 1 file changed, 53 insertions(+), 46 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state_derived.c b/src/gallium/drivers/i915simple/i915_state_derived.c index f654f543cc..fe52fe6e6b 100644 --- a/src/gallium/drivers/i915simple/i915_state_derived.c +++ b/src/gallium/drivers/i915simple/i915_state_derived.c @@ -27,104 +27,111 @@ #include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" #include "draw/draw_vertex.h" #include "i915_context.h" #include "i915_state.h" #include "i915_reg.h" #include "i915_fpc.h" -#include "pipe/p_shader_tokens.h" + /** - * Determine which post-transform / pre-rasterization vertex attributes - * we need. - * Derived from: fs, setup states. + * Determine the hardware vertex layout. + * Depends on vertex/fragment shader state. */ static void calculate_vertex_layout( struct i915_context *i915 ) { const struct pipe_shader_state *fs = &i915->fs->state; const enum interp_mode colorInterp = i915->rasterizer->color_interp; struct vertex_info vinfo; - uint front0 = 0, back0 = 0, front1 = 0, back1 = 0; - boolean needW = 0; + boolean texCoords[8], colors[2], fog, needW; uint i; - boolean texCoords[8]; - uint src = 0; + int src; memset(texCoords, 0, sizeof(texCoords)); + colors[0] = colors[1] = fog = needW = FALSE; memset(&vinfo, 0, sizeof(vinfo)); - /* pos */ - draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src++); - /* Note: we'll set the S4_VFMT_XYZ[W] bits below */ - + /* Determine which fragment program inputs are needed. Setup HW vertex + * layout below, in the HW-specific attribute order. + */ for (i = 0; i < fs->num_inputs; i++) { switch (fs->input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: break; case TGSI_SEMANTIC_COLOR: - if (fs->input_semantic_index[i] == 0) { - front0 = draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src++); - vinfo.hwfmt[0] |= S4_VFMT_COLOR; - } - else { - assert(fs->input_semantic_index[i] == 1); - front1 = draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src++); - vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG; - } + assert(fs->input_semantic_index[i] < 2); + colors[fs->input_semantic_index[i]] = TRUE; break; case TGSI_SEMANTIC_GENERIC: /* usually a texcoord */ { const uint unit = fs->input_semantic_index[i]; - uint hwtc; + assert(unit < 8); texCoords[unit] = TRUE; - draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); - hwtc = TEXCOORDFMT_4D; needW = TRUE; - vinfo.hwfmt[1] |= hwtc << (unit * 4); } break; case TGSI_SEMANTIC_FOG: - debug_printf("i915 fogcoord not implemented yet\n"); - draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src++); + fog = TRUE; break; default: assert(0); } - } - /* finish up texcoord fields */ - for (i = 0; i < 8; i++) { - if (!texCoords[i]) { - const uint hwtc = TEXCOORDFMT_NOT_PRESENT; - vinfo.hwfmt[1] |= hwtc << (i* 4); - } - } - - /* go back and fill in the vertex position info now that we have needW */ + + /* pos */ + src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_POSITION, 0); if (needW) { + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src); vinfo.hwfmt[0] |= S4_VFMT_XYZW; vinfo.emit[0] = EMIT_4F; } else { + draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src); vinfo.hwfmt[0] |= S4_VFMT_XYZ; vinfo.emit[0] = EMIT_3F; } - /* Additional attributes required for setup: Just twosided - * lighting. Edgeflag is dealt with specially by setting bits in - * the vertex header. - */ - if (i915->rasterizer->light_twoside) { - if (front0) { - back0 = draw_emit_vertex_attr(&vinfo, EMIT_OMIT, colorInterp, src++); + /* hardware point size */ + /* XXX todo */ + + /* primary color */ + if (colors[0]) { + src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 0); + draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src); + vinfo.hwfmt[0] |= S4_VFMT_COLOR; + } + + /* secondary color */ + if (colors[1]) { + src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 1); + draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src); + vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG; + } + + /* fog coord, not fog blend factor */ + if (fog) { + src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_FOG, 0); + draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src); + vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM; + } + + /* texcoords */ + for (i = 0; i < 8; i++) { + uint hwtc; + if (texCoords[i]) { + hwtc = TEXCOORDFMT_4D; + src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_GENERIC, i); + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); } - if (back0) { - back1 = draw_emit_vertex_attr(&vinfo, EMIT_OMIT, colorInterp, src++); + else { + hwtc = TEXCOORDFMT_NOT_PRESENT; } + vinfo.hwfmt[1] |= hwtc << (i * 4); } draw_compute_vertex_size(&vinfo); -- cgit v1.2.3 From cc0cf1154b6288d49d7a9dfd18fb666331dd7334 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 15:34:46 -0700 Subject: gallium: fix bad ptr assignment --- src/gallium/auxiliary/draw/draw_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 6e5e4d64d1..7dd1c6f6fa 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -262,7 +262,7 @@ int draw_find_vs_output(struct draw_context *draw, uint semantic_name, uint semantic_index) { - const struct pipe_shader_state *vs = &draw->vertex_shader->state; + const struct pipe_shader_state *vs = draw->vertex_shader->state; uint i; for (i = 0; i < vs->num_outputs; i++) { if (vs->output_semantic_name[i] == semantic_name && -- cgit v1.2.3 From b53110c78941e7fcaa41921cce07ca00ec117a97 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 16:16:07 -0700 Subject: gallium/i915: call draw_flush() in i915_flush() --- src/gallium/drivers/i915simple/i915_flush.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c index 3c2069b827..96a54281f1 100644 --- a/src/gallium/drivers/i915simple/i915_flush.c +++ b/src/gallium/drivers/i915simple/i915_flush.c @@ -31,6 +31,7 @@ #include "pipe/p_defines.h" +#include "draw/draw_context.h" #include "i915_context.h" #include "i915_reg.h" #include "i915_batch.h" @@ -44,6 +45,8 @@ static void i915_flush( struct pipe_context *pipe, { struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); + /* Do we need to emit an MI_FLUSH command to flush the hardware * caches? */ -- cgit v1.2.3 From f41e95755757cb1452697fafa1dd5288390ed57e Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 16:20:04 -0700 Subject: gallium/i915: need to recompute vertex info if vertex shader changes --- src/gallium/drivers/i915simple/i915_context.h | 1 + src/gallium/drivers/i915simple/i915_state.c | 2 ++ src/gallium/drivers/i915simple/i915_state_derived.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 5cc38cdc85..d32dded6bd 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -263,6 +263,7 @@ struct i915_context #define I915_NEW_TEXTURE 0x800 #define I915_NEW_CONSTANTS 0x1000 #define I915_NEW_VBO 0x2000 +#define I915_NEW_VS 0x4000 /* Driver's internally generated state flags: diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index e4288d4e31..a35bdf941f 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -474,6 +474,8 @@ static void i915_bind_vs_state(struct pipe_context *pipe, void *shader) /* just pass-through to draw module */ draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader); + + i915->dirty |= I915_NEW_VS; } static void i915_delete_vs_state(struct pipe_context *pipe, void *shader) diff --git a/src/gallium/drivers/i915simple/i915_state_derived.c b/src/gallium/drivers/i915simple/i915_state_derived.c index fe52fe6e6b..5cf70acdf3 100644 --- a/src/gallium/drivers/i915simple/i915_state_derived.c +++ b/src/gallium/drivers/i915simple/i915_state_derived.c @@ -155,7 +155,7 @@ static void calculate_vertex_layout( struct i915_context *i915 ) */ void i915_update_derived( struct i915_context *i915 ) { - if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS)) + if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS)) calculate_vertex_layout( i915 ); if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_TEXTURE)) -- cgit v1.2.3 From 92650aeaddd1bd729f3a90383f05c8148f678066 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 16:22:58 -0700 Subject: gallium/i915: make sure state is up to date in i915_vbuf_render_get_vertex_info(), also disable bogus assertion --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index c5bf6174f6..9d5f609220 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -83,6 +83,12 @@ i915_vbuf_render_get_vertex_info( struct vbuf_render *render ) { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; + + if (i915->dirty) { + /* make sure we have up to date vertex layout */ + i915_update_derived( i915 ); + } + return &i915->current.vertex_info; } @@ -143,7 +149,8 @@ i915_vbuf_render_draw( struct vbuf_render *render, assert(nr_indices); - assert((i915->dirty & ~I915_NEW_VBO) == 0); + /* this seems to be bogus, since we validate state right after this */ + /*assert((i915->dirty & ~I915_NEW_VBO) == 0);*/ if (i915->dirty) i915_update_derived( i915 ); -- cgit v1.2.3 From 99047e0968882a4e3f9577fa2352d91733181339 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 16:24:47 -0700 Subject: gallium/i915: plug in aaline draw stage --- src/gallium/drivers/i915simple/i915_context.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index acfa349439..36f6429d46 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -298,10 +298,14 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, i915_init_string_functions(i915); i915_init_texture_functions(i915); + /* not working yet: + draw_install_aapoint_stage(i915->draw, &i915->pipe); + */ + draw_install_aaline_stage(i915->draw, &i915->pipe); + i915->pci_id = pci_id; i915->flags.is_i945 = is_i945; - i915->dirty = ~0; i915->hardware_dirty = ~0; -- cgit v1.2.3 From b02fc948348db5559d658251dd3a6d4f3390d686 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 17:01:20 -0700 Subject: gallium/i915: compute vertex size _after_ state validation in emit_prim(). Fixes crash when drawing aa lines. --- src/gallium/drivers/i915simple/i915_prim_emit.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c index 44c4325936..6da42b3846 100644 --- a/src/gallium/drivers/i915simple/i915_prim_emit.c +++ b/src/gallium/drivers/i915simple/i915_prim_emit.c @@ -72,6 +72,8 @@ emit_hw_vertex( struct i915_context *i915, uint i; uint count = 0; /* for debug/sanity */ + assert(!i915->dirty); + for (i = 0; i < vinfo->num_attribs; i++) { switch (vinfo->emit[i]) { case EMIT_OMIT: @@ -122,17 +124,19 @@ emit_prim( struct draw_stage *stage, unsigned nr ) { struct i915_context *i915 = setup_stage(stage)->i915; - unsigned vertex_size = i915->current.vertex_info.size * 4; /* in bytes */ + unsigned vertex_size; unsigned i; - assert(vertex_size >= 12); /* never smaller than 12 bytes */ - if (i915->dirty) i915_update_derived( i915 ); if (i915->hardware_dirty) i915_emit_hardware_state( i915 ); + /* need to do this after validation! */ + vertex_size = i915->current.vertex_info.size * 4; /* in bytes */ + assert(vertex_size >= 12); /* never smaller than 12 bytes */ + if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) { FLUSH_BATCH(); -- cgit v1.2.3 From 7976a084e792daf0b23c688bfa8f577de141ecca Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 21 Feb 2008 11:01:35 -0800 Subject: Cell: Use multiple DMA tags for the dcache. --- src/gallium/drivers/cell/spu/spu_dcache.c | 2 +- src/gallium/drivers/cell/spu/spu_main.h | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_dcache.c b/src/gallium/drivers/cell/spu/spu_dcache.c index 698a5790bb..3baeaea998 100644 --- a/src/gallium/drivers/cell/spu/spu_dcache.c +++ b/src/gallium/drivers/cell/spu/spu_dcache.c @@ -33,7 +33,7 @@ #define CACHE_NAME data #define CACHED_TYPE qword #define CACHE_TYPE CACHE_TYPE_RO -#define CACHE_SET_TAGID(set) TAG_VERTEX_BUFFER +#define CACHE_SET_TAGID(set) (((set) & 0x03) + TAG_DCACHE0) #define CACHE_LOG2NNWAY 2 #define CACHE_LOG2NSETS 6 #include diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index 5c95d112ac..d14f1abbe7 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -131,7 +131,10 @@ extern boolean Debug; #define TAG_BATCH_BUFFER 17 #define TAG_MISC 18 #define TAG_TEXTURE_TILE 19 -#define TAG_INSTRUCTION_FETCH 20 +#define TAG_DCACHE0 20 +#define TAG_DCACHE1 21 +#define TAG_DCACHE2 22 +#define TAG_DCACHE3 23 -- cgit v1.2.3 From fb68daceec312a90910dad3882e6ef57c370b7fd Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 21 Feb 2008 16:41:12 -0800 Subject: Cell: Remove unnecessary include files --- src/gallium/drivers/cell/spu/spu_exec.c | 2 -- src/gallium/drivers/cell/spu/spu_vertex_fetch.c | 2 -- 2 files changed, 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index cf81bee8fd..fff0114a23 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -50,8 +50,6 @@ * Brian Paul */ -#include -#include #include #include #include diff --git a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c index f7e4e653e3..219fd90cc0 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c @@ -32,8 +32,6 @@ * Ian Romanick */ -#include - #include "pipe/p_util.h" #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" -- cgit v1.2.3 From a63fd641a01a50e1be51664bf863e01ddaf61d3e Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 22 Feb 2008 16:27:39 -0800 Subject: cell: Trivial compiler warning clean-ups. --- src/gallium/drivers/cell/ppu/cell_draw_arrays.c | 1 + src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 1 - src/gallium/drivers/cell/spu/spu_exec.c | 6 ++++-- src/gallium/drivers/cell/spu/spu_main.c | 5 +++-- 4 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index cbd387f014..c839fb4d12 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -38,6 +38,7 @@ #include "cell_context.h" #include "cell_draw_arrays.h" #include "cell_state.h" +#include "cell_flush.h" #include "draw/draw_context.h" diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index 42cc47cbfe..17141924be 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -55,7 +55,6 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) struct cell_command_vs *const vs = &cell_global.command[0].vs; uint64_t *batch; struct cell_array_info *array_info; - struct cell_shader_info *shader_info; unsigned i, j; struct cell_attribute_fetch_code *cf; diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index fff0114a23..1560c0f157 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -149,6 +149,7 @@ spu_exec_machine_init(struct spu_exec_machine *mach, const qword zero = si_il(0); const qword not_zero = si_il(~0); + (void) numSamplers; mach->Samplers = samplers; mach->Processor = processor; mach->Addrs = &mach->Temps[TGSI_EXEC_NUM_TEMPS]; @@ -657,9 +658,10 @@ fetch_texel( struct spu_sampler *sampler, qword rgba[4]; qword out[4]; - sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, (float *) rgba); + sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, + (float (*)[4]) rgba); - _transpose_matrix4x4(out, rgba); + _transpose_matrix4x4((vec_float4 *) out, (vec_float4 *) rgba); r->q = out[0]; g->q = out[1]; b->q = out[2]; diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 1136dba62d..cc4bafdb3a 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -38,6 +38,7 @@ #include "spu_tile.h" //#include "spu_test.h" #include "spu_vertex_shader.h" +#include "spu_dcache.h" #include "cell/common.h" #include "pipe/p_defines.h" @@ -434,7 +435,7 @@ cmd_batch(uint opcode) pos += (1 + ROUNDUP8(sizeof(struct pipe_viewport_state)) / 8); break; case CELL_CMD_STATE_UNIFORMS: - draw.constants = (float (*)[4]) (uintptr_t) buffer[pos + 1]; + draw.constants = (const float (*)[4]) (uintptr_t) buffer[pos + 1]; pos += 2; break; case CELL_CMD_STATE_VS_ARRAY_INFO: @@ -583,7 +584,7 @@ main(main_param_t speid, main_param_t argp) one_time_init(); if (Debug) - printf("SPU: main() speid=%lu\n", speid); + printf("SPU: main() speid=%lu\n", (unsigned long) speid); mfc_get(&spu.init, /* dest */ (unsigned int) argp, /* src */ -- cgit v1.2.3 From 2efa7e9489541b6a86c3d46e3d58cbf5bf399189 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 22 Feb 2008 17:51:55 -0800 Subject: cell: Fix off-by-one error in spu_dcache_fetch_unaligned This time the off-by-one error caused an extra qword to be fetched under certain circumstances when the source ea was not qword aligned. --- src/gallium/drivers/cell/spu/spu_dcache.c | 50 ++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_dcache.c b/src/gallium/drivers/cell/spu/spu_dcache.c index 3baeaea998..a1701d80d1 100644 --- a/src/gallium/drivers/cell/spu/spu_dcache.c +++ b/src/gallium/drivers/cell/spu/spu_dcache.c @@ -49,43 +49,57 @@ /** * Fetch between arbitrary number of bytes from an unaligned address + * + * \param dst Destination data buffer + * \param ea Main memory effective address of source data + * \param size Number of bytes to read + * + * \warning + * As is hinted by the type of the \c dst pointer, this function writes + * multiples of 16-bytes. */ void spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size) { const int shift = ea & 0x0f; - const unsigned aligned_start_ea = ea & ~0x0f; - const unsigned aligned_end_ea = ROUNDUP16(ea + size); - const unsigned num_entries = (aligned_end_ea - aligned_start_ea) / 16; + const unsigned read_size = ROUNDUP16(size + shift); + const unsigned last_read = ROUNDUP16(ea + size); + const qword *const last_write = dst + (ROUNDUP16(size) / 16); unsigned i; if (shift == 0) { /* Data is already aligned. Fetch directly into the destination buffer. */ - for (i = 0; i < num_entries; i++) { - dst[i] = cache_rd(data, ea + (i * 16)); + for (i = 0; i < size; i += 16) { + *(dst++) = cache_rd(data, ea + i); } } else { - qword tmp[2] ALIGN16_ATTRIB; - + qword hi; - tmp[0] = cache_rd(data, (ea & ~0x0f)); - for (i = 0; i < (num_entries & ~1); i++) { - const unsigned curr = i & 1; - const unsigned next = curr ^ 1; - tmp[next] = cache_rd(data, (ea & ~0x0f) + (next * 16)); - - dst[i] = si_or((qword) spu_slqwbyte(tmp[curr], shift), - (qword) spu_rlmaskqwbyte(tmp[next], shift - 16)); + /* Please exercise extreme caution when modifying this code. This code + * must not read past the end of the page containing the source data, + * and it must not write more than ((size + 15) / 16) qwords to the + * destination buffer. + */ + ea &= ~0x0f; + hi = cache_rd(data, ea); + for (i = 16; i < read_size; i += 16) { + qword lo = cache_rd(data, ea + i); + + *(dst++) = si_or((qword) spu_slqwbyte(hi, shift), + (qword) spu_rlmaskqwbyte(lo, shift - 16)); + hi = lo; } - if (i < num_entries) { - dst[i] = si_or((qword) spu_slqwbyte(tmp[(i & 1)], shift), - si_il(0)); + if (dst != last_write) { + *(dst++) = si_or((qword) spu_slqwbyte(hi, shift), si_il(0)); } } + + ASSERT((ea + i) == last_read); + ASSERT(dst == last_write); } -- cgit v1.2.3 From 2fc9d0ffac4b44dad1f13443e5dedd545675a7ee Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 25 Feb 2008 16:15:59 -0800 Subject: cell: Additional changes to match changes in draw/draw_vertex_shader.c --- src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index 17141924be..f5c27852c1 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -127,7 +127,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) for (/* empty */; j < SPU_VERTS_PER_BATCH; j++) { vs->elts[j] = vs->elts[0]; - vs->vOut[j] = vs->vOut[0]; + vs->vOut[j] = (uintptr_t) draw->vs.queue[i + j].vertex; } vs->num_elts = n; @@ -136,5 +136,6 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) cell_flush_int(& cell->pipe, PIPE_FLUSH_WAIT); } + draw->vs.post_nr = draw->vs.queue_nr; draw->vs.queue_nr = 0; } -- cgit v1.2.3 From 0235b3252100eda553babea42c014445358a2985 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 17:59:51 -0700 Subject: gallium/i915: fix i915_emit_texld() to handle swizzled texcoords Allocate a temporary register, insert MOV instruction, etc. --- src/gallium/drivers/i915simple/i915_fpc_emit.c | 63 +++++++++++++++++----- .../drivers/i915simple/i915_fpc_translate.c | 20 +++++-- 2 files changed, 67 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_fpc_emit.c b/src/gallium/drivers/i915simple/i915_fpc_emit.c index a59ee23403..ad6dab6c11 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_emit.c +++ b/src/gallium/drivers/i915simple/i915_fpc_emit.c @@ -71,10 +71,21 @@ i915_get_temp(struct i915_fp_compile *p) } p->temp_flag |= 1 << (bit - 1); - return UREG(REG_TYPE_R, (bit - 1)); + return bit - 1; } +static void +i915_release_temp(struct i915_fp_compile *p, int reg) +{ + p->temp_flag &= ~(1 << reg); +} + + +/** + * Get unpreserved temporary, a temp whose value is not preserved between + * PS program phases. + */ uint i915_get_utemp(struct i915_fp_compile * p) { @@ -183,41 +194,63 @@ i915_emit_arith(struct i915_fp_compile * p, return dest; } + +/** + * Emit a texture load or texkill instruction. + * \param dest the dest i915 register + * \param destmask the dest register writemask + * \param sampler the i915 sampler register + * \param coord the i915 source texcoord operand + * \param opcode the instruction opcode + */ uint i915_emit_texld( struct i915_fp_compile *p, uint dest, uint destmask, uint sampler, uint coord, - uint op ) + uint opcode ) { - uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord)); + const uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord)); + int temp = -1; + if (coord != k) { - /* No real way to work around this in the general case - need to - * allocate and declare a new temporary register (a utemp won't - * do). Will fallback for now. + /* texcoord is swizzled or negated. Need to allocate a new temporary + * register (a utemp / unpreserved temp) won't do. */ - i915_program_error(p, "Can't (yet) swizzle TEX arguments"); - assert(0); - return 0; + uint tempReg; + + temp = i915_get_temp(p); /* get temp reg index */ + printf("***** ALLOC TEMP %d\n", temp); + tempReg = UREG(REG_TYPE_R, temp); /* make i915 register */ + + i915_emit_arith( p, A0_MOV, + tempReg, A0_DEST_CHANNEL_ALL, /* dest reg, writemask */ + 0, /* saturate */ + coord, 0, 0 ); /* src0, src1, src2 */ + + /* new src texcoord is tempReg */ + coord = tempReg; } /* Don't worry about saturate as we only support */ if (destmask != A0_DEST_CHANNEL_ALL) { + /* if not writing to XYZW... */ uint tmp = i915_get_utemp(p); - i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op ); + i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode ); i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 ); - return dest; + /* XXX release utemp here? */ } else { assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); + /* is the sampler coord a texcoord input reg? */ if (GET_UREG_TYPE(coord) != REG_TYPE_T) { p->nr_tex_indirect++; } - *(p->csr++) = (op | + *(p->csr++) = (opcode | T0_DEST( dest ) | T0_SAMPLER( sampler )); @@ -225,8 +258,12 @@ uint i915_emit_texld( struct i915_fp_compile *p, *(p->csr++) = T2_MBZ; p->nr_tex_insn++; - return dest; } + + if (temp >= 0) + i915_release_temp(p, temp); + + return dest; } diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 50c9e65409..76a2184e9a 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -575,8 +575,12 @@ i915_translate_instruction(struct i915_fp_compile *p, src0 = src_vector(p, &inst->FullSrcRegisters[0]); tmp = i915_get_utemp(p); - i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */ - 0, src0, T0_TEXKILL); + i915_emit_texld(p, + tmp, /* dest reg: a dummy reg */ + A0_DEST_CHANNEL_ALL, /* dest writemask */ + 0, /* sampler */ + src0, /* coord*/ + T0_TEXKILL); /* opcode */ break; case TGSI_OPCODE_LG2: @@ -970,6 +974,16 @@ i915_translate_instructions(struct i915_fp_compile *p, ifs->num_constants = MAX2(ifs->num_constants, i + 1); } } + else if (parse.FullToken.FullDeclaration.Declaration.File + == TGSI_FILE_TEMPORARY) { + uint i; + for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First; + i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last; + i++) { + assert(i < I915_MAX_TEMPORARY); + p->temp_flag |= (1 << i); /* mark temp as used */ + } + } break; case TGSI_TOKEN_TYPE_IMMEDIATE: @@ -1048,7 +1062,7 @@ i915_init_compile(struct i915_context *i915, p->decl = p->declarations; p->decl_s = 0; p->decl_t = 0; - p->temp_flag = 0xffff000; + p->temp_flag = ~0x0 << I915_MAX_TEMPORARY; p->utemp_flag = ~0x7; p->wpos_tex = -1; -- cgit v1.2.3 From 7ed9beef5f08554f126c64aa172cd03fd810f1db Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 18:00:14 -0700 Subject: gallium/i915: remove debug code --- src/gallium/drivers/i915simple/i915_fpc_emit.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_fpc_emit.c b/src/gallium/drivers/i915simple/i915_fpc_emit.c index ad6dab6c11..4bdeefb449 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_emit.c +++ b/src/gallium/drivers/i915simple/i915_fpc_emit.c @@ -220,7 +220,6 @@ uint i915_emit_texld( struct i915_fp_compile *p, uint tempReg; temp = i915_get_temp(p); /* get temp reg index */ - printf("***** ALLOC TEMP %d\n", temp); tempReg = UREG(REG_TYPE_R, temp); /* make i915 register */ i915_emit_arith( p, A0_MOV, -- cgit v1.2.3 From f43c44b5c9bbbd37e0d40488f911f81e5f3a0367 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 18:53:22 -0700 Subject: gallium/i915: Fix emit_hw_vertex(): need to use vinfo->src_index[] --- src/gallium/drivers/i915simple/i915_prim_emit.c | 30 +++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c index 6da42b3846..d8de5178f6 100644 --- a/src/gallium/drivers/i915simple/i915_prim_emit.c +++ b/src/gallium/drivers/i915simple/i915_prim_emit.c @@ -75,37 +75,39 @@ emit_hw_vertex( struct i915_context *i915, assert(!i915->dirty); for (i = 0; i < vinfo->num_attribs; i++) { + const uint j = vinfo->src_index[i]; + const float *attrib = vertex->data[j]; switch (vinfo->emit[i]) { case EMIT_OMIT: /* no-op */ break; case EMIT_1F: - OUT_BATCH( fui(vertex->data[i][0]) ); + OUT_BATCH( fui(attrib[0]) ); count++; break; case EMIT_2F: - OUT_BATCH( fui(vertex->data[i][0]) ); - OUT_BATCH( fui(vertex->data[i][1]) ); + OUT_BATCH( fui(attrib[0]) ); + OUT_BATCH( fui(attrib[1]) ); count += 2; break; case EMIT_3F: - OUT_BATCH( fui(vertex->data[i][0]) ); - OUT_BATCH( fui(vertex->data[i][1]) ); - OUT_BATCH( fui(vertex->data[i][2]) ); + OUT_BATCH( fui(attrib[0]) ); + OUT_BATCH( fui(attrib[1]) ); + OUT_BATCH( fui(attrib[2]) ); count += 3; break; case EMIT_4F: - OUT_BATCH( fui(vertex->data[i][0]) ); - OUT_BATCH( fui(vertex->data[i][1]) ); - OUT_BATCH( fui(vertex->data[i][2]) ); - OUT_BATCH( fui(vertex->data[i][3]) ); + OUT_BATCH( fui(attrib[0]) ); + OUT_BATCH( fui(attrib[1]) ); + OUT_BATCH( fui(attrib[2]) ); + OUT_BATCH( fui(attrib[3]) ); count += 4; break; case EMIT_4UB: - OUT_BATCH( pack_ub4(float_to_ubyte( vertex->data[i][2] ), - float_to_ubyte( vertex->data[i][1] ), - float_to_ubyte( vertex->data[i][0] ), - float_to_ubyte( vertex->data[i][3] )) ); + OUT_BATCH( pack_ub4(float_to_ubyte( attrib[2] ), + float_to_ubyte( attrib[1] ), + float_to_ubyte( attrib[0] ), + float_to_ubyte( attrib[3] )) ); count += 1; break; default: -- cgit v1.2.3 From ba376b33140f722b9f935960f450bbca8873439e Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 18:53:57 -0700 Subject: gallium/i915: plug in aapoint draw stage --- src/gallium/drivers/i915simple/i915_context.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 36f6429d46..c3955bbd2d 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -298,10 +298,8 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, i915_init_string_functions(i915); i915_init_texture_functions(i915); - /* not working yet: - draw_install_aapoint_stage(i915->draw, &i915->pipe); - */ draw_install_aaline_stage(i915->draw, &i915->pipe); + draw_install_aapoint_stage(i915->draw, &i915->pipe); i915->pci_id = pci_id; i915->flags.is_i945 = is_i945; -- cgit v1.2.3 From 08a5f49644c4bfc62291c49718f2d18e58527d1d Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Feb 2008 18:56:03 -0700 Subject: gallium: rewrite AA point fragment shader to use a CMP instruction instead of IF/ELSE/ENDIF Allows the shader to work on i915 hardware. --- src/gallium/auxiliary/draw/draw_aapoint.c | 196 +++++++++++++++--------------- 1 file changed, 96 insertions(+), 100 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c index 27a81f3e90..cae6fcd4d2 100644 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -222,7 +222,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx, * * Temp reg0 usage: * t0.x = distance of fragment from center point - * t0.y = boolean, is t0.x > 1 ? + * t0.y = boolean, is t0.x > 1.0, also misc temp usage * t0.z = temporary for computing 1/(1-k) value * t0.w = final coverage value */ @@ -313,9 +313,73 @@ aa_transform_inst(struct tgsi_transform_context *ctx, newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; ctx->emit_instruction(ctx, &newInst); - /* SGT t0.y, t0.x, tex.z; # bool b = distance > k */ + + /* compute coverage factor = (1-d)/(1-k) */ + + /* SUB t0.z, tex.w, tex.z; # m = 1 - k */ newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_SGT; + newInst.Instruction.Opcode = TGSI_OPCODE_SUB; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* RCP t0.z, t0.z; # t0.z = 1 / m */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RCP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* SUB t0.y, 1, t0.x; # d = 1 - d */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SUB; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + ctx->emit_instruction(ctx, &newInst); + + /* MUL t0.w, t0.y, t0.z; # coverage = d * m */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* SLE t0.y, t0.x, tex.z; # bool b = distance <= k */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SLE; newInst.Instruction.NumDstRegs = 1; newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; newInst.FullDstRegisters[0].DstRegister.Index = tmp0; @@ -329,111 +393,40 @@ aa_transform_inst(struct tgsi_transform_context *ctx, newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z; ctx->emit_instruction(ctx, &newInst); - /* IF t0.y # if b then */ + /* CMP t0.w, -t0.y, tex.w, t0.w; + * # if -t0.y < 0 then + * t0.w = 1 + * else + * t0.w = t0.w + */ newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_IF; - newInst.Instruction.NumDstRegs = 0; - newInst.Instruction.NumSrcRegs = 1; + newInst.Instruction.Opcode = TGSI_OPCODE_CMP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 3; newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[2].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; ctx->emit_instruction(ctx, &newInst); - { - /* compute coverage factor = (1-d)/(1-k) */ - - /* SUB t0.z, tex.w, tex.z; # m = 1 - k */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_SUB; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; - ctx->emit_instruction(ctx, &newInst); - - /* RCP t0.z, t0.z; # t0.z = 1 / m */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_RCP; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z; - ctx->emit_instruction(ctx, &newInst); - - /* SUB t0.x, 1, t0.x; # d = 1 - d */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_SUB; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - ctx->emit_instruction(ctx, &newInst); - - /* MUL t0.w, t0.x, t0.z; # coverage = d * m */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MUL; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z; - ctx->emit_instruction(ctx, &newInst); - } - - /* ELSE */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_ELSE; - newInst.Instruction.NumDstRegs = 0; - newInst.Instruction.NumSrcRegs = 0; - ctx->emit_instruction(ctx, &newInst); - - { - /* MOV t0.w, tex.w; # coverage = 1.0 */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MOV; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; - ctx->emit_instruction(ctx, &newInst); - } - - /* ENDIF */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_ENDIF; - newInst.Instruction.NumDstRegs = 0; - newInst.Instruction.NumSrcRegs = 0; - ctx->emit_instruction(ctx, &newInst); } if (inst->Instruction.Opcode == TGSI_OPCODE_END) { @@ -516,7 +509,7 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) (struct tgsi_token *) aapoint_fs.tokens, MAX, &transform.base); -#if 0 /* DEBUG */ +#if 1 /* DEBUG */ tgsi_dump(orig_fs->tokens, 0); tgsi_dump(aapoint_fs.tokens, 0); #endif @@ -613,6 +606,9 @@ aapoint_point(struct draw_stage *stage, struct prim_header *header) * ELSE * coverage = 1.0; // full coverage * ENDIF + * + * Note: the ELSEIF and ELSE clauses are actually implemented with CMP to + * avoid using IF/ELSE/ENDIF TGSI opcodes. */ #if !NORMALIZE -- cgit v1.2.3 From 6abb82da7e676384e7e2c9732307b23f8ed7157d Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 25 Feb 2008 22:03:58 -0500 Subject: implement deleting of driver side cached state in cso's --- src/gallium/auxiliary/cso_cache/cso_cache.c | 88 +++++++++++++++++++++++++++++ src/gallium/auxiliary/cso_cache/cso_cache.h | 14 +++++ src/gallium/auxiliary/cso_cache/cso_hash.h | 1 - 3 files changed, 102 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index 9c32e94124..9aa1a64272 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -190,9 +190,96 @@ struct cso_cache *cso_cache_create(void) return sc; } +void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type, + void (*func)(void *state, void *user_data), void *user_data) +{ + struct cso_hash *hash = 0; + struct cso_hash_iter iter; + + switch (type) { + case CSO_BLEND: + hash = sc->blend_hash; + break; + case CSO_SAMPLER: + hash = sc->sampler_hash; + break; + case CSO_DEPTH_STENCIL_ALPHA: + hash = sc->depth_stencil_hash; + break; + case CSO_RASTERIZER: + hash = sc->rasterizer_hash; + break; + case CSO_FRAGMENT_SHADER: + hash = sc->fs_hash; + break; + case CSO_VERTEX_SHADER: + hash = sc->vs_hash; + break; + } + + iter = cso_hash_first_node(hash); + while (!cso_hash_iter_is_null(iter)) { + void *state = cso_hash_iter_data(iter); + if (state) { + func(state, user_data); + } + iter = cso_hash_iter_next(iter); + } +} + +static void delete_blend_state(void *state, void *user_data) +{ + struct cso_blend *cso = (struct cso_blend *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + +static void delete_depth_stencil_state(void *state, void *pipe) +{ + struct cso_depth_stencil_alpha *cso = (struct cso_depth_stencil_alpha *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + +static void delete_sampler_state(void *state, void *pipe) +{ + struct cso_sampler *cso = (struct cso_sampler *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + +static void delete_rasterizer_state(void *state, void *pipe) +{ + struct cso_rasterizer *cso = (struct cso_rasterizer *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + +static void delete_fs_state(void *state, void *pipe) +{ + struct cso_fragment_shader *cso = (struct cso_fragment_shader *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + +static void delete_vs_state(void *state, void *pipe) +{ + struct cso_vertex_shader *cso = (struct cso_vertex_shader *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + void cso_cache_delete(struct cso_cache *sc) { assert(sc); + /* delete driver data */ + cso_for_each_state(sc, CSO_BLEND, delete_blend_state, 0); + cso_for_each_state(sc, CSO_DEPTH_STENCIL_ALPHA, delete_depth_stencil_state, 0); + cso_for_each_state(sc, CSO_FRAGMENT_SHADER, delete_fs_state, 0); + cso_for_each_state(sc, CSO_VERTEX_SHADER, delete_vs_state, 0); + cso_for_each_state(sc, CSO_RASTERIZER, delete_rasterizer_state, 0); + cso_for_each_state(sc, CSO_SAMPLER, delete_sampler_state, 0); + cso_hash_delete(sc->blend_hash); cso_hash_delete(sc->sampler_hash); cso_hash_delete(sc->depth_stencil_hash); @@ -201,3 +288,4 @@ void cso_cache_delete(struct cso_cache *sc) cso_hash_delete(sc->vs_hash); FREE(sc); } + diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h index 3a005a376e..f3bd4623c9 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.h +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -97,31 +97,43 @@ struct cso_cache { struct cso_blend { struct pipe_blend_state state; void *data; + void (*delete_state)(void *, void *); + void *context; }; struct cso_depth_stencil_alpha { struct pipe_depth_stencil_alpha_state state; void *data; + void (*delete_state)(void *, void *); + void *context; }; struct cso_rasterizer { struct pipe_rasterizer_state state; void *data; + void (*delete_state)(void *, void *); + void *context; }; struct cso_fragment_shader { struct pipe_shader_state state; void *data; + void (*delete_state)(void *, void *); + void *context; }; struct cso_vertex_shader { struct pipe_shader_state state; void *data; + void (*delete_state)(void *, void *); + void *context; }; struct cso_sampler { struct pipe_sampler_state state; void *data; + void (*delete_state)(void *, void *); + void *context; }; @@ -147,6 +159,8 @@ struct cso_hash_iter cso_find_state(struct cso_cache *sc, struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type, void *templ); +void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type, + void (*func)(void *state, void *user_data), void *user_data); void * cso_take_state(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type); diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h index 2e8b69675c..86c62c027a 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.h +++ b/src/gallium/auxiliary/cso_cache/cso_hash.h @@ -38,7 +38,6 @@ extern "C" { #endif - struct cso_hash; struct cso_node; -- cgit v1.2.3 From bf1c2f3602038440ffacf7ae494cb4e9bacc9bb9 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 26 Feb 2008 00:15:55 -0500 Subject: hide cso cache definition and add some initial code for size limiting the caches --- src/gallium/auxiliary/cso_cache/cso_cache.c | 22 ++++++++++++++++++++++ src/gallium/auxiliary/cso_cache/cso_cache.h | 28 +++++++++++----------------- 2 files changed, 33 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index 9aa1a64272..1b870c8e41 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -33,6 +33,17 @@ #include "cso_cache.h" #include "cso_hash.h" + +struct cso_cache { + struct cso_hash *blend_hash; + struct cso_hash *depth_stencil_hash; + struct cso_hash *fs_hash; + struct cso_hash *vs_hash; + struct cso_hash *rasterizer_hash; + struct cso_hash *sampler_hash; + int max_size; +}; + #if 1 static unsigned hash_key(const void *key, unsigned key_size) { @@ -180,6 +191,7 @@ struct cso_cache *cso_cache_create(void) { struct cso_cache *sc = MALLOC_STRUCT(cso_cache); + sc->max_size = 4096; sc->blend_hash = cso_hash_create(); sc->sampler_hash = cso_hash_create(); sc->depth_stencil_hash = cso_hash_create(); @@ -289,3 +301,13 @@ void cso_cache_delete(struct cso_cache *sc) FREE(sc); } +void cso_set_maximum_cache_size(struct cso_cache *sc, int number) +{ + sc->max_size = number; +} + +int cso_maximum_cache_size(const struct cso_cache *sc) +{ + return sc->max_size; +} + diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h index f3bd4623c9..72a6b9d488 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.h +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -28,7 +28,7 @@ /** * @file * Constant State Object (CSO) cache. - * + * * The basic idea is that the states are created via the * create_state/bind_state/delete_state semantics. The driver is expected to * perform as much of the Gallium state translation to whatever its internal @@ -36,15 +36,15 @@ * mechanism where it stores the created states. When the pipeline needs an * actual state change, a bind call is issued. In the bind call the driver * gets its already translated representation. - * + * * Those semantics mean that the driver doesn't do the repeated translations * of states on every frame, but only once, when a new state is actually * created. - * + * * Even on hardware that doesn't do any kind of state cache, it makes the * driver look a lot neater, plus it avoids all the redundant state * translations on every frame. - * + * * Currently our constant state objects are: * - alpha test * - blend @@ -53,7 +53,7 @@ * - rasterizer (old setup) * - sampler * - vertex shader - * + * * Things that are not constant state objects include: * - blend_color * - clip_state @@ -65,7 +65,7 @@ * - scissor_state * - texture_state * - viewport_state - * + * * @author Zack Rusin */ @@ -75,24 +75,16 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -/* cso_hash.h is necessary for cso_hash_iter, as MSVC requires structures +/* cso_hash.h is necessary for cso_hash_iter, as MSVC requires structures * returned by value to be fully defined */ -#include "cso_hash.h" +#include "cso_hash.h" #ifdef __cplusplus extern "C" { #endif - -struct cso_cache { - struct cso_hash *blend_hash; - struct cso_hash *depth_stencil_hash; - struct cso_hash *fs_hash; - struct cso_hash *vs_hash; - struct cso_hash *rasterizer_hash; - struct cso_hash *sampler_hash; -}; +struct cso_cache; struct cso_blend { struct pipe_blend_state state; @@ -164,6 +156,8 @@ void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type, void * cso_take_state(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type); +void cso_set_maximum_cache_size(struct cso_cache *sc, int number); +int cso_maximum_cache_size(const struct cso_cache *sc); #ifdef __cplusplus } -- cgit v1.2.3 From e7985105695a18c29c13deb2b8f40c15eef72ee6 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 26 Feb 2008 00:18:54 -0500 Subject: add an explicit callback decleration and use it to silence warnings --- src/gallium/auxiliary/cso_cache/cso_cache.c | 2 +- src/gallium/auxiliary/cso_cache/cso_cache.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index 1b870c8e41..f31042bce1 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -203,7 +203,7 @@ struct cso_cache *cso_cache_create(void) } void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type, - void (*func)(void *state, void *user_data), void *user_data) + cso_state_callback func, void *user_data) { struct cso_hash *hash = 0; struct cso_hash_iter iter; diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h index 72a6b9d488..3b0fe100b8 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.h +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -138,6 +138,8 @@ enum cso_cache_type { CSO_VERTEX_SHADER }; +typedef void (*cso_state_callback)(void *, void *); + unsigned cso_construct_key(void *item, int item_size); struct cso_cache *cso_cache_create(void); @@ -152,7 +154,7 @@ struct cso_hash_iter cso_find_state_template(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type, void *templ); void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type, - void (*func)(void *state, void *user_data), void *user_data); + cso_state_callback func, void *user_data); void * cso_take_state(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type); -- cgit v1.2.3 From 7838aaffdb9d34427ebcb73aac585c85d9622018 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 26 Feb 2008 01:48:01 -0500 Subject: implement cache limits for cso by default set to 4096, which might be on the large side --- src/gallium/auxiliary/cso_cache/cso_cache.c | 144 ++++++++++++++++++++-------- src/gallium/auxiliary/cso_cache/cso_hash.c | 5 + src/gallium/auxiliary/cso_cache/cso_hash.h | 4 +- 3 files changed, 110 insertions(+), 43 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index f31042bce1..a6e8469b44 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -127,12 +127,106 @@ static int _cso_size_for_type(enum cso_cache_type type) return 0; } + +static void delete_blend_state(void *state, void *data) +{ + struct cso_blend *cso = (struct cso_blend *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + +static void delete_depth_stencil_state(void *state, void *data) +{ + struct cso_depth_stencil_alpha *cso = (struct cso_depth_stencil_alpha *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + +static void delete_sampler_state(void *state, void *data) +{ + struct cso_sampler *cso = (struct cso_sampler *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + +static void delete_rasterizer_state(void *state, void *data) +{ + struct cso_rasterizer *cso = (struct cso_rasterizer *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + +static void delete_fs_state(void *state, void *data) +{ + struct cso_fragment_shader *cso = (struct cso_fragment_shader *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + +static void delete_vs_state(void *state, void *data) +{ + struct cso_vertex_shader *cso = (struct cso_vertex_shader *)state; + if (cso->delete_state && cso->data != &cso->state) + cso->delete_state(cso->context, cso->data); +} + + +static INLINE void delete_cso(void *state, enum cso_cache_type type) +{ + switch (type) { + case CSO_BLEND: { + delete_blend_state(state, 0); + } + break; + case CSO_SAMPLER: { + delete_sampler_state(state, 0); + } + break; + case CSO_DEPTH_STENCIL_ALPHA: { + delete_depth_stencil_state(state, 0); + } + break; + case CSO_RASTERIZER: { + delete_rasterizer_state(state, 0); + } + break; + case CSO_FRAGMENT_SHADER: { + delete_fs_state(state, 0); + } + break; + case CSO_VERTEX_SHADER: { + delete_vs_state(state, 0); + } + break; + } + free(state); +} + +static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type, + int max_size) +{ + /* if we're approach the maximum size, remove fourth of the entries + * otherwise every subsequent call will go through the same */ + int max_entries = (max_size > cso_hash_size(hash)) ? max_size : cso_hash_size(hash); + int to_remove = (max_size < max_entries) * max_entries/4; + while (to_remove) { + /*remove elements until we're good */ + /*fixme: currently we pick the nodes to remove at random*/ + struct cso_hash_iter iter = cso_hash_first_node(hash); + void *cso = cso_hash_take(hash, cso_hash_iter_key(iter)); + delete_cso(cso, type); + --to_remove; + } +} + struct cso_hash_iter cso_insert_state(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type, void *state) { struct cso_hash *hash = _cso_hash_for_type(sc, type); + sanitize_hash(hash, type, sc->max_size); + return cso_hash_insert(hash, hash_key, state); } @@ -239,48 +333,6 @@ void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type, } } -static void delete_blend_state(void *state, void *user_data) -{ - struct cso_blend *cso = (struct cso_blend *)state; - if (cso->delete_state && cso->data != &cso->state) - cso->delete_state(cso->context, cso->data); -} - -static void delete_depth_stencil_state(void *state, void *pipe) -{ - struct cso_depth_stencil_alpha *cso = (struct cso_depth_stencil_alpha *)state; - if (cso->delete_state && cso->data != &cso->state) - cso->delete_state(cso->context, cso->data); -} - -static void delete_sampler_state(void *state, void *pipe) -{ - struct cso_sampler *cso = (struct cso_sampler *)state; - if (cso->delete_state && cso->data != &cso->state) - cso->delete_state(cso->context, cso->data); -} - -static void delete_rasterizer_state(void *state, void *pipe) -{ - struct cso_rasterizer *cso = (struct cso_rasterizer *)state; - if (cso->delete_state && cso->data != &cso->state) - cso->delete_state(cso->context, cso->data); -} - -static void delete_fs_state(void *state, void *pipe) -{ - struct cso_fragment_shader *cso = (struct cso_fragment_shader *)state; - if (cso->delete_state && cso->data != &cso->state) - cso->delete_state(cso->context, cso->data); -} - -static void delete_vs_state(void *state, void *pipe) -{ - struct cso_vertex_shader *cso = (struct cso_vertex_shader *)state; - if (cso->delete_state && cso->data != &cso->state) - cso->delete_state(cso->context, cso->data); -} - void cso_cache_delete(struct cso_cache *sc) { assert(sc); @@ -304,6 +356,14 @@ void cso_cache_delete(struct cso_cache *sc) void cso_set_maximum_cache_size(struct cso_cache *sc, int number) { sc->max_size = number; + + sanitize_hash(sc->blend_hash, CSO_BLEND, sc->max_size); + sanitize_hash(sc->depth_stencil_hash, CSO_DEPTH_STENCIL_ALPHA, + sc->max_size); + sanitize_hash(sc->fs_hash, CSO_FRAGMENT_SHADER, sc->max_size); + sanitize_hash(sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size); + sanitize_hash(sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size); + sanitize_hash(sc->sampler_hash, CSO_SAMPLER, sc->max_size); } int cso_maximum_cache_size(const struct cso_cache *sc) diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index 208fc58502..b3b4d667d2 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -395,3 +395,8 @@ struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash) struct cso_hash_iter iter = {hash, cso_data_first_node(hash->data.d)}; return iter; } + +int cso_hash_size(struct cso_hash *hash) +{ + return hash->data.d->size; +} diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h index 86c62c027a..d5bca9d591 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.h +++ b/src/gallium/auxiliary/cso_cache/cso_hash.h @@ -47,7 +47,9 @@ struct cso_hash_iter { }; struct cso_hash *cso_hash_create(void); -void cso_hash_delete(struct cso_hash *hash); +void cso_hash_delete(struct cso_hash *hash); + +int cso_hash_size(struct cso_hash *hash); struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, unsigned key, void *data); -- cgit v1.2.3 From ad6bb870de6103ed240fa1f9f828bd13a4401a9a Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 26 Feb 2008 11:49:25 +0100 Subject: gallium: Fix build on Windows. --- src/gallium/auxiliary/cso_cache/cso_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index a6e8469b44..b427b509f8 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -199,7 +199,7 @@ static INLINE void delete_cso(void *state, enum cso_cache_type type) } break; } - free(state); + FREE(state); } static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type, -- cgit v1.2.3 From 232a41e19faa860f083e414cb1eb38c0617e9241 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 08:41:42 -0700 Subject: gallium: disable debug code --- src/gallium/auxiliary/draw/draw_aapoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c index cae6fcd4d2..d16adb2505 100644 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -509,7 +509,7 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) (struct tgsi_token *) aapoint_fs.tokens, MAX, &transform.base); -#if 1 /* DEBUG */ +#if 0 /* DEBUG */ tgsi_dump(orig_fs->tokens, 0); tgsi_dump(aapoint_fs.tokens, 0); #endif -- cgit v1.2.3 From ecd50ef58b034e604ff6b2fedbb0815953e510ea Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 08:43:07 -0700 Subject: gallium: remove input_map[] from pipe_shader_state --- src/gallium/include/pipe/p_state.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 15c88881eb..ddf3c1c79b 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -162,7 +162,6 @@ struct pipe_shader_state const struct tgsi_token *tokens; ubyte num_inputs; ubyte num_outputs; - ubyte input_map[PIPE_MAX_SHADER_INPUTS]; /* XXX this may be temporary */ ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */ ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */ -- cgit v1.2.3 From 1410b7bb509ef37c41043b173bc1047257483af0 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 10:12:17 -0700 Subject: gallium: collect more shader info in tgsi_scan_shader() Now getting input/output semantic info so we can eventually remove those fields from pipe_shader_state. --- src/gallium/auxiliary/tgsi/util/tgsi_scan.c | 20 ++++++++++++++++++++ src/gallium/auxiliary/tgsi/util/tgsi_scan.h | 11 +++++++++++ 2 files changed, 31 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c index 4b99ac37cc..a1cc681492 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c @@ -69,6 +69,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens, */ while( !tgsi_parse_end_of_tokens( &parse ) ) { + info->num_tokens++; + tgsi_parse_token( &parse ); switch( parse.FullToken.Token.Type ) { @@ -91,9 +93,27 @@ tgsi_scan_shader(const struct tgsi_token *tokens, for (i = fulldecl->u.DeclarationRange.First; i <= fulldecl->u.DeclarationRange.Last; i++) { + + /* only first 32 regs will appear in this bitfield */ info->file_mask[file] |= (1 << i); info->file_count[file]++; + if (file == TGSI_FILE_INPUT) { + info->input_semantic_name[info->num_inputs] + = fulldecl->Semantic.SemanticName; + info->input_semantic_index[info->num_inputs] + = fulldecl->Semantic.SemanticIndex; + info->num_inputs++; + } + + if (file == TGSI_FILE_OUTPUT) { + info->output_semantic_name[info->num_outputs] + = fulldecl->Semantic.SemanticName; + info->output_semantic_index[info->num_outputs] + = fulldecl->Semantic.SemanticIndex; + info->num_outputs++; + } + /* special case */ if (procType == TGSI_PROCESSOR_FRAGMENT && file == TGSI_FILE_OUTPUT && diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h index 757446437c..dc6dfd6d0b 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h @@ -30,6 +30,7 @@ #include "pipe/p_util.h" +#include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" @@ -38,6 +39,16 @@ */ struct tgsi_shader_info { + uint num_tokens; + + /* XXX eventually remove the corresponding fields from pipe_shader_state: */ + ubyte num_inputs; + ubyte num_outputs; + ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */ + ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; + ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */ + ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; + uint file_mask[TGSI_FILE_COUNT]; /**< bitmask of declared registers */ uint file_count[TGSI_FILE_COUNT]; /**< number of declared registers */ -- cgit v1.2.3 From f74279002a0ae0b106bd5410487ef9c0e9b1d8b6 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 10:13:39 -0700 Subject: gallium: added tgsi_shader_field to sp_fragment_shader Use the shader semantic info from there, instead of from pipe_shader_state. Carry this idea to draw module and other drivers... --- src/gallium/drivers/softpipe/sp_fs_llvm.c | 2 +- src/gallium/drivers/softpipe/sp_prim_setup.c | 18 +++++++++--------- src/gallium/drivers/softpipe/sp_quad.c | 2 +- src/gallium/drivers/softpipe/sp_quad_fs.c | 4 ++-- src/gallium/drivers/softpipe/sp_state.h | 6 ++++-- src/gallium/drivers/softpipe/sp_state_derived.c | 9 +++++---- src/gallium/drivers/softpipe/sp_state_fs.c | 16 ++++++++++------ 7 files changed, 32 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_fs_llvm.c b/src/gallium/drivers/softpipe/sp_fs_llvm.c index 34b2b7d4e2..07d058155f 100644 --- a/src/gallium/drivers/softpipe/sp_fs_llvm.c +++ b/src/gallium/drivers/softpipe/sp_fs_llvm.c @@ -96,7 +96,7 @@ shade_quad_llvm(struct quad_stage *qs, if (qss->colorOutSlot >= 0) { unsigned i; /* XXX need to handle multiple color outputs someday */ - allvmrt(qss->stage.softpipe->fs->shader.output_semantic_name[qss->colorOutSlot] + allvmrt(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] == TGSI_SEMANTIC_COLOR); for (i = 0; i < QUAD_SIZE; ++i) { quad->outputs.color[0][i] = dests[i][qss->colorOutSlot][0]; diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index b6a3fddb29..17284539b0 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -514,7 +514,7 @@ setup_fragcoord_coeff(struct setup_stage *setup, uint slot) static void setup_tri_coefficients( struct setup_stage *setup ) { struct softpipe_context *softpipe = setup->softpipe; - const struct pipe_shader_state *fs = &softpipe->fs->shader; + const struct sp_fragment_shader *spfs = softpipe->fs; const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; @@ -525,7 +525,7 @@ static void setup_tri_coefficients( struct setup_stage *setup ) /* setup interpolation for all the remaining attributes: */ - for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) { + for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { const uint vertSlot = vinfo->src_index[fragSlot]; uint j; @@ -549,7 +549,7 @@ static void setup_tri_coefficients( struct setup_stage *setup ) assert(0); } - if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { /* FOG.y = front/back facing XXX fix this */ setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; setup->coef[fragSlot].dadx[1] = 0.0; @@ -757,7 +757,7 @@ static INLINE void setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim) { struct softpipe_context *softpipe = setup->softpipe; - const struct pipe_shader_state *fs = &setup->softpipe->fs->shader; + const struct sp_fragment_shader *spfs = softpipe->fs; const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; @@ -779,7 +779,7 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim) /* setup interpolation for all the remaining attributes: */ - for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) { + for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { const uint vertSlot = vinfo->src_index[fragSlot]; uint j; @@ -803,7 +803,7 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim) assert(0); } - if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { /* FOG.y = front/back facing XXX fix this */ setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; setup->coef[fragSlot].dadx[1] = 0.0; @@ -967,7 +967,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim) { struct setup_stage *setup = setup_stage( stage ); struct softpipe_context *softpipe = setup->softpipe; - const struct pipe_shader_state *fs = &softpipe->fs->shader; + const struct sp_fragment_shader *spfs = softpipe->fs; const struct vertex_header *v0 = prim->v[0]; const int sizeAttr = setup->softpipe->psize_slot; const float size @@ -1002,7 +1002,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim) const_coeff(setup, &setup->posCoef, 0, 2); const_coeff(setup, &setup->posCoef, 0, 3); - for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) { + for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { const uint vertSlot = vinfo->src_index[fragSlot]; uint j; @@ -1025,7 +1025,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim) assert(0); } - if (fs->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { /* FOG.y = front/back facing XXX fix this */ setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; setup->coef[fragSlot].dadx[1] = 0.0; diff --git a/src/gallium/drivers/softpipe/sp_quad.c b/src/gallium/drivers/softpipe/sp_quad.c index 142dbcc771..0aaf94021f 100644 --- a/src/gallium/drivers/softpipe/sp_quad.c +++ b/src/gallium/drivers/softpipe/sp_quad.c @@ -61,7 +61,7 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp->framebuffer.zsbuf && !sp->depth_stencil->alpha.enabled && !sp->fs->uses_kill && - !sp->fs->writes_z; + !sp->fs->info.writes_z; /* build up the pipeline in reverse order... */ diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 2f40e09d5c..1794fb5a61 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -91,7 +91,7 @@ shade_quad( /* store result color */ if (qss->colorOutSlot >= 0) { /* XXX need to handle multiple color outputs someday */ - assert(qss->stage.softpipe->fs->shader.output_semantic_name[qss->colorOutSlot] + assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] == TGSI_SEMANTIC_COLOR); memcpy( quad->outputs.color, @@ -149,7 +149,7 @@ static void shade_begin(struct quad_stage *qs) qss->colorOutSlot = -1; qss->depthOutSlot = -1; for (i = 0; i < qss->stage.softpipe->fs->shader.num_outputs; i++) { - switch (qss->stage.softpipe->fs->shader.output_semantic_name[i]) { + switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: qss->depthOutSlot = i; break; diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 5aaa9e346b..b1070e185a 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -32,6 +32,7 @@ #define SP_STATE_H #include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" #define SP_NEW_VIEWPORT 0x1 @@ -61,10 +62,11 @@ struct tgsi_exec_machine; * This is starting to look an awful lot like a quad pipeline stage... */ struct sp_fragment_shader { - struct pipe_shader_state shader; + struct pipe_shader_state shader; + + struct tgsi_shader_info info; boolean uses_kill; - boolean writes_z; void (*prepare)( const struct sp_fragment_shader *shader, struct tgsi_exec_machine *machine, diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 4c6313001f..68702eafcf 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -62,6 +62,7 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) if (vinfo->num_attribs == 0) { /* compute vertex layout now */ const struct pipe_shader_state *vs = &softpipe->vs->shader; + const struct sp_fragment_shader *spfs = softpipe->fs; const struct pipe_shader_state *fs = &softpipe->fs->shader; const enum interp_mode colorInterp = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; @@ -83,9 +84,9 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) * from the vertex shader. */ vinfo->num_attribs = 0; - for (i = 0; i < fs->num_inputs; i++) { + for (i = 0; i < spfs->info.num_inputs; i++) { int src; - switch (fs->input_semantic_name[i]) { + switch (spfs->info.input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_POSITION, 0); @@ -94,7 +95,7 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) case TGSI_SEMANTIC_COLOR: src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_COLOR, - fs->input_semantic_index[i]); + spfs->info.input_semantic_index[i]); draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); break; @@ -106,7 +107,7 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) case TGSI_SEMANTIC_GENERIC: /* this includes texcoords and varying vars */ src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_GENERIC, - fs->input_semantic_index[i]); + spfs->info.input_semantic_index[i]); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); break; diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index b184ac61bb..2715dca0f0 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -45,13 +45,12 @@ softpipe_create_fs_state(struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state; - struct tgsi_shader_info info; - - tgsi_scan_shader(templ->tokens, &info); + /* debug */ if (softpipe->dump_fs) tgsi_dump(templ->tokens, 0); + /* codegen */ state = softpipe_create_fs_llvm( softpipe, templ ); if (!state) { state = softpipe_create_fs_sse( softpipe, templ ); @@ -59,10 +58,15 @@ softpipe_create_fs_state(struct pipe_context *pipe, state = softpipe_create_fs_exec( softpipe, templ ); } } + assert(state); - state->uses_kill = (info.opcode_count[TGSI_OPCODE_KIL] || - info.opcode_count[TGSI_OPCODE_KILP]); - state->writes_z = info.writes_z; + + /* get/save the summary info for this shader */ + tgsi_scan_shader(templ->tokens, &state->info); + + /* convenience field */ + state->uses_kill = (state->info.opcode_count[TGSI_OPCODE_KIL] || + state->info.opcode_count[TGSI_OPCODE_KILP]); return state; } -- cgit v1.2.3 From 33d213b6776701ec16b5c02b111ed31de5e93f43 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 10:44:44 -0700 Subject: gallium: remove unused var --- src/gallium/drivers/softpipe/sp_state_derived.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 68702eafcf..aa6e329116 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -63,7 +63,6 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) /* compute vertex layout now */ const struct pipe_shader_state *vs = &softpipe->vs->shader; const struct sp_fragment_shader *spfs = softpipe->fs; - const struct pipe_shader_state *fs = &softpipe->fs->shader; const enum interp_mode colorInterp = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; uint i; -- cgit v1.2.3 From 4901410293b35ac6bb4759142b50fcc0be8a1b25 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 10:47:42 -0700 Subject: gallium/i915: Use tgsi_scan_shader() to collect shader info No longer use semantic info in pipe_shader_state. Also, remove redundant semantic info from i915_fp_compile struct. --- src/gallium/drivers/i915simple/i915_context.h | 5 ++++ src/gallium/drivers/i915simple/i915_fpc.h | 6 ---- .../drivers/i915simple/i915_fpc_translate.c | 33 ++++------------------ src/gallium/drivers/i915simple/i915_state.c | 2 ++ .../drivers/i915simple/i915_state_derived.c | 12 ++++---- 5 files changed, 19 insertions(+), 39 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index d32dded6bd..20cf7d3c3b 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -35,6 +35,8 @@ #include "draw/draw_vertex.h" +#include "tgsi/util/tgsi_scan.h" + #define I915_TEX_UNITS 8 @@ -89,6 +91,9 @@ struct i915_fragment_shader { struct pipe_shader_state state; + + struct tgsi_shader_info info; + uint *program; uint program_len; diff --git a/src/gallium/drivers/i915simple/i915_fpc.h b/src/gallium/drivers/i915simple/i915_fpc.h index 250dfe6dbf..80a9576304 100644 --- a/src/gallium/drivers/i915simple/i915_fpc.h +++ b/src/gallium/drivers/i915simple/i915_fpc.h @@ -58,12 +58,6 @@ struct i915_fp_compile { uint declarations[I915_PROGRAM_SIZE]; uint program[I915_PROGRAM_SIZE]; - uint input_semantic_name[PIPE_MAX_SHADER_INPUTS]; - uint input_semantic_index[PIPE_MAX_SHADER_INPUTS]; - - uint output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; - uint output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; - uint *csr; /**< Cursor, points into program. */ uint *decl; /**< Cursor, points into declarations. */ diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 76a2184e9a..c2d9a93c6c 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -162,8 +162,8 @@ src_vector(struct i915_fp_compile *p, * We also use a texture coordinate to pass wpos when possible. */ - sem_name = p->input_semantic_name[index]; - sem_ind = p->input_semantic_index[index]; + sem_name = p->shader->info.input_semantic_name[index]; + sem_ind = p->shader->info.input_semantic_index[index]; switch (sem_name) { case TGSI_SEMANTIC_POSITION: @@ -265,7 +265,7 @@ get_result_vector(struct i915_fp_compile *p, switch (dest->DstRegister.File) { case TGSI_FILE_OUTPUT: { - uint sem_name = p->output_semantic_name[dest->DstRegister.Index]; + uint sem_name = p->shader->info.output_semantic_name[dest->DstRegister.Index]; switch (sem_name) { case TGSI_SEMANTIC_POSITION: return UREG(REG_TYPE_OD, 0); @@ -942,28 +942,6 @@ i915_translate_instructions(struct i915_fp_compile *p, switch( parse.FullToken.Token.Type ) { case TGSI_TOKEN_TYPE_DECLARATION: if (parse.FullToken.FullDeclaration.Declaration.File - == TGSI_FILE_INPUT) { - /* save input register info for use in src_vector() */ - uint ind, sem, semi; - ind = parse.FullToken.FullDeclaration.u.DeclarationRange.First; - sem = parse.FullToken.FullDeclaration.Semantic.SemanticName; - semi = parse.FullToken.FullDeclaration.Semantic.SemanticIndex; - /*debug_printf("FS Input DECL [%u] sem %u\n", ind, sem);*/ - p->input_semantic_name[ind] = sem; - p->input_semantic_index[ind] = semi; - } - else if (parse.FullToken.FullDeclaration.Declaration.File - == TGSI_FILE_OUTPUT) { - /* save output register info for use in get_result_vector() */ - uint ind, sem, semi; - ind = parse.FullToken.FullDeclaration.u.DeclarationRange.First; - sem = parse.FullToken.FullDeclaration.Semantic.SemanticName; - semi = parse.FullToken.FullDeclaration.Semantic.SemanticIndex; - /*debug_printf("FS Output DECL [%u] sem %u\n", ind, sem);*/ - p->output_semantic_name[ind] = sem; - p->output_semantic_index[ind] = semi; - } - else if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_CONSTANT) { uint i; for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First; @@ -981,6 +959,7 @@ i915_translate_instructions(struct i915_fp_compile *p, i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last; i++) { assert(i < I915_MAX_TEMPORARY); + /* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */ p->temp_flag |= (1 << i); /* mark temp as used */ } } @@ -1163,7 +1142,7 @@ i915_find_wpos_space(struct i915_fp_compile *p) i915_program_error(p, "No free texcoord for wpos value"); } #else - if (p->shader->state.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { + if (p->shader->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) { /* frag shader using the fragment position input */ #if 0 assert(0); @@ -1184,7 +1163,7 @@ static void i915_fixup_depth_write(struct i915_fp_compile *p) { /* XXX assuming pos/depth is always in output[0] */ - if (p->shader->state.output_semantic_name[0] == TGSI_SEMANTIC_POSITION) { + if (p->shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION) { const uint depth = UREG(REG_TYPE_OD, 0); i915_emit_arith(p, diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index a35bdf941f..9df0e12540 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -429,6 +429,8 @@ i915_create_fs_state(struct pipe_context *pipe, ifs->state = *templ; + tgsi_scan_shader(templ->tokens, &ifs->info); + /* The shader's compiled to i915 instructions here */ i915_translate_fragment_program(i915, ifs); diff --git a/src/gallium/drivers/i915simple/i915_state_derived.c b/src/gallium/drivers/i915simple/i915_state_derived.c index 5cf70acdf3..4daccec6e0 100644 --- a/src/gallium/drivers/i915simple/i915_state_derived.c +++ b/src/gallium/drivers/i915simple/i915_state_derived.c @@ -43,7 +43,7 @@ */ static void calculate_vertex_layout( struct i915_context *i915 ) { - const struct pipe_shader_state *fs = &i915->fs->state; + const struct i915_fragment_shader *fs = i915->fs; const enum interp_mode colorInterp = i915->rasterizer->color_interp; struct vertex_info vinfo; boolean texCoords[8], colors[2], fog, needW; @@ -57,18 +57,18 @@ static void calculate_vertex_layout( struct i915_context *i915 ) /* Determine which fragment program inputs are needed. Setup HW vertex * layout below, in the HW-specific attribute order. */ - for (i = 0; i < fs->num_inputs; i++) { - switch (fs->input_semantic_name[i]) { + for (i = 0; i < fs->info.num_inputs; i++) { + switch (fs->info.input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: break; case TGSI_SEMANTIC_COLOR: - assert(fs->input_semantic_index[i] < 2); - colors[fs->input_semantic_index[i]] = TRUE; + assert(fs->info.input_semantic_index[i] < 2); + colors[fs->info.input_semantic_index[i]] = TRUE; break; case TGSI_SEMANTIC_GENERIC: /* usually a texcoord */ { - const uint unit = fs->input_semantic_index[i]; + const uint unit = fs->info.input_semantic_index[i]; assert(unit < 8); texCoords[unit] = TRUE; needW = TRUE; -- cgit v1.2.3 From dbf12dcdb78aa251fe0d09b49aa661481727ecf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 26 Feb 2008 18:48:13 +0000 Subject: intel_winsys: Fix build failure due to DEBUG_IOCTL being undefined. Include pipe/p_debug.h to consistently enable or disable the debugging code. --- src/gallium/winsys/dri/intel/intel_context.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h index b01370c049..45430984d8 100644 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -30,6 +30,9 @@ #include "drm.h" + +#include "pipe/p_debug.h" + #include "intel_screen.h" #include "i915_drm.h" -- cgit v1.2.3 From 75dac3959f959f0227b4e172696ac43910f9257a Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 26 Feb 2008 11:18:51 -0800 Subject: cell: Multiple rendering contexts don't work yet Log a message and forcibly exit. This prevents silly fools from thinking there's a bug...instead of just an unimplemented feature. :) --- src/gallium/drivers/cell/ppu/cell_spu.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_spu.c b/src/gallium/drivers/cell/ppu/cell_spu.c index 419e74dc40..973c0b1aa1 100644 --- a/src/gallium/drivers/cell/ppu/cell_spu.c +++ b/src/gallium/drivers/cell/ppu/cell_spu.c @@ -97,8 +97,18 @@ static void *cell_thread_function(void *arg) void cell_start_spus(struct cell_context *cell) { + static boolean one_time_init = FALSE; uint i, j; + + if (one_time_init) { + fprintf(stderr, "PPU: Multiple rendering contexts not yet supported " + "on Cell.\n"); + abort(); + } + + one_time_init = TRUE; + assert(cell->num_spus <= MAX_SPUS); ASSERT_ALIGN16(&cell_global.command[0]); -- cgit v1.2.3 From 36aa9cf781440ce685930586cbf53248cf9c0dc2 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 26 Feb 2008 20:32:42 +0100 Subject: gallium: Print texture target for short dumps. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index ff74e6117c..59be14a748 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -664,6 +664,19 @@ static const char *TGSI_TEXTURES[] = "TEXTURE_SHADOWRECT" }; +static const char *TGSI_TEXTURES_SHORT[] = +{ + "UNKNOWN", + "1D", + "2D", + "3D", + "CUBE", + "RECT", + "SHADOW1D", + "SHADOW2D", + "SHADOWRECT" +}; + static const char *TGSI_SRC_REGISTER_EXTS[] = { "SRC_REGISTER_EXT_TYPE_SWZ", @@ -1037,6 +1050,11 @@ dump_instruction_short( first_reg = FALSE; } + if (inst->InstructionExtTexture.Texture != TGSI_TEXTURE_UNKNOWN) { + TXT( ", " ); + ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES_SHORT ); + } + switch( inst->Instruction.Opcode ) { case TGSI_OPCODE_IF: case TGSI_OPCODE_ELSE: -- cgit v1.2.3 From 5e29aab1752c3e07ae2ebde4cb00e6550dab0eb2 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 14:29:35 -0700 Subject: gallium: replace draw_convert_wide_points() with draw_wide_point_threshold() Specifying a threshold size is a bit more flexible, and allows the option of converting even 1-pixel points to triangles (set threshold=0). Also, remove 0.25 pixel bias in wide_point(). --- src/gallium/auxiliary/draw/draw_context.c | 10 +++++----- src/gallium/auxiliary/draw/draw_private.h | 2 +- src/gallium/auxiliary/draw/draw_validate.c | 23 +++++++++++++---------- src/gallium/auxiliary/draw/draw_wide_prims.c | 7 ++++--- src/gallium/drivers/softpipe/sp_context.c | 3 --- 5 files changed, 23 insertions(+), 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 7dd1c6f6fa..48f00946ea 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -80,7 +80,7 @@ struct draw_context *draw_create( void ) draw->shader_queue_flush = draw_vertex_shader_queue_flush; - draw->convert_wide_points = TRUE; + draw->wide_point_threshold = 1000000.0; /* infinity */ draw->convert_wide_lines = TRUE; draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ @@ -220,14 +220,14 @@ draw_set_mapped_constant_buffer(struct draw_context *draw, /** - * Tells the draw module whether to convert wide points (size != 1) - * into triangles. + * Tells the draw module to draw points with triangles if their size + * is greater than this threshold. */ void -draw_convert_wide_points(struct draw_context *draw, boolean enable) +draw_wide_point_threshold(struct draw_context *draw, float threshold) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->convert_wide_points = enable; + draw->wide_point_threshold = threshold; } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 6abced139b..03e3d3a66b 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -215,7 +215,7 @@ struct draw_context float plane[12][4]; unsigned nr_planes; - boolean convert_wide_points; /**< convert wide points to tris? */ + float wide_point_threshold; /**< convert pnts to tris if larger than this */ boolean convert_wide_lines; /**< convert wide lines to tris? */ boolean use_sse; diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index 3a19dd4cd7..ded7d10c08 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -52,6 +52,19 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) */ stage->next = next; + /* drawing wide lines? */ + wide_lines = (draw->rasterizer->line_width != 1.0 + && draw->convert_wide_lines + && !draw->rasterizer->line_smooth); + + /* drawing large points? */ + if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) + wide_points = FALSE; + else if (draw->rasterizer->point_size > draw->wide_point_threshold) + wide_points = TRUE; + else + wide_points = FALSE; + /* * NOTE: we build up the pipeline in end-to-start order. * @@ -69,16 +82,6 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) next = draw->pipeline.aapoint; } - /* drawing wide lines? */ - wide_lines = (draw->rasterizer->line_width != 1.0 - && draw->convert_wide_lines - && !draw->rasterizer->line_smooth); - - /* drawing large points? */ - wide_points = (draw->rasterizer->point_size != 1.0 - && draw->convert_wide_points - && !draw->pipeline.aapoint); - if (wide_lines || wide_points || draw->rasterizer->point_sprite) { diff --git a/src/gallium/auxiliary/draw/draw_wide_prims.c b/src/gallium/auxiliary/draw/draw_wide_prims.c index 1f8069bdca..d967810dd4 100644 --- a/src/gallium/auxiliary/draw/draw_wide_prims.c +++ b/src/gallium/auxiliary/draw/draw_wide_prims.c @@ -219,8 +219,8 @@ static void wide_point( struct draw_stage *stage, half_size = wide->half_point_size; } - left_adj = -half_size + 0.25f; - right_adj = half_size + 0.25f; + left_adj = -half_size; /* + 0.25f;*/ + right_adj = half_size; /* + 0.25f;*/ pos0[0] += left_adj; pos0[1] -= half_size; @@ -266,7 +266,8 @@ static void wide_first_point( struct draw_stage *stage, wide->half_point_size = 0.5f * draw->rasterizer->point_size; - if (draw->rasterizer->point_size != 1.0) { + /* XXX we won't know the real size if it's computed by the vertex shader! */ + if (draw->rasterizer->point_size > draw->wide_point_threshold) { stage->point = wide_point; } else { diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 2cdf3c75bf..6a884327e0 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -337,9 +337,6 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); #endif - /* sp_prim_setup can do wide points (don't convert to quads) */ - draw_convert_wide_points(softpipe->draw, FALSE); - sp_init_surface_functions(softpipe); return &softpipe->pipe; -- cgit v1.2.3 From d4a4bed6638e0156324ff9b270f2248c4b5275bb Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 14:30:41 -0700 Subject: gallium: updated prototype (missed in prev commit) --- src/gallium/auxiliary/draw/draw_context.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index c25301f71d..d6685f479b 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -90,6 +90,8 @@ void draw_set_rasterizer_state( struct draw_context *draw, void draw_set_rasterize_stage( struct draw_context *draw, struct draw_stage *stage ); +void draw_wide_point_threshold(struct draw_context *draw, float threshold); + void draw_convert_wide_points(struct draw_context *draw, boolean enable); void draw_convert_wide_lines(struct draw_context *draw, boolean enable); -- cgit v1.2.3 From 4da19dbcaa9f3e2d20fffd0145bf0bc756dd7542 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 19:31:22 -0700 Subject: gallium: remove pipe parameter from pipe_texture_reference() Added pipe field to pipe_texture (temporary, see comments). First step toward context-less texture creation... --- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 3 +-- src/gallium/drivers/i915simple/i915_state.c | 3 +-- src/gallium/drivers/i915simple/i915_texture.c | 1 + src/gallium/drivers/i965simple/brw_state.c | 3 +-- src/gallium/drivers/softpipe/sp_state_sampler.c | 2 +- src/gallium/drivers/softpipe/sp_texture.c | 1 + src/gallium/drivers/softpipe/sp_tile_cache.c | 2 +- src/gallium/include/pipe/p_inlines.h | 14 +++++++++++++- src/gallium/include/pipe/p_state.h | 5 +++++ 9 files changed, 25 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 95bfc29fbe..075e0a0c47 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -242,8 +242,7 @@ cell_set_sampler_texture(struct pipe_context *pipe, draw_flush(cell->draw); - pipe_texture_reference(pipe, - (struct pipe_texture **) &cell->texture[sampler], + pipe_texture_reference((struct pipe_texture **) &cell->texture[sampler], texture); cell_update_texture_mapping(cell); diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 9df0e12540..27af46bea0 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -532,8 +532,7 @@ static void i915_set_sampler_texture(struct pipe_context *pipe, { struct i915_context *i915 = i915_context(pipe); - pipe_texture_reference(pipe, - (struct pipe_texture **) &i915->texture[sampler], + pipe_texture_reference((struct pipe_texture **) &i915->texture[sampler], texture); i915->dirty |= I915_NEW_TEXTURE; diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 1b415a94d4..7fcf4332e1 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -489,6 +489,7 @@ i915_texture_create(struct pipe_context *pipe, tex->base = *templat; tex->base.refcount = 1; + tex->base.pipe = pipe; if (i915->flags.is_i945 ? i945_miptree_layout(pipe, tex) : i915_miptree_layout(pipe, tex)) diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index 2fc048bde0..7466fdc403 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -328,8 +328,7 @@ static void brw_set_sampler_texture(struct pipe_context *pipe, { struct brw_context *brw = brw_context(pipe); - pipe_texture_reference(pipe, - (struct pipe_texture **) &brw->attribs.Texture[unit], + pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[unit], texture); brw->state.dirty.brw |= BRW_NEW_TEXTURE; diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 18669a1c6e..1d6dd17d1d 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -83,7 +83,7 @@ softpipe_set_sampler_texture(struct pipe_context *pipe, draw_flush(softpipe->draw); assert(unit < PIPE_MAX_SAMPLERS); - pipe_texture_reference(pipe, &softpipe->texture[unit], texture); + pipe_texture_reference(&softpipe->texture[unit], texture); sp_tile_cache_set_texture(pipe, softpipe->tex_cache[unit], texture); diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 6ba0f09e0a..a96447fa7a 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -90,6 +90,7 @@ softpipe_texture_create(struct pipe_context *pipe, spt->base = *templat; spt->base.refcount = 1; + spt->base.pipe = pipe; softpipe_texture_layout(spt); diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index da30dd6c48..0ff93c5527 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -220,7 +220,7 @@ sp_tile_cache_set_texture(struct pipe_context *pipe, assert(!tc->surface); - pipe_texture_reference(pipe, &tc->texture, texture); + pipe_texture_reference(&tc->texture, texture); if (tc->tex_surf_map) { pipe_surface_unmap(tc->tex_surf); diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index de3fa555c5..21d4827e67 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -97,7 +97,7 @@ pipe_buffer_reference(struct pipe_winsys *winsys, * \sa pipe_surface_reference */ static INLINE void -pipe_texture_reference(struct pipe_context *pipe, struct pipe_texture **ptr, +pipe_texture_reference(struct pipe_texture **ptr, struct pipe_texture *pt) { assert(ptr); @@ -106,6 +106,7 @@ pipe_texture_reference(struct pipe_context *pipe, struct pipe_texture **ptr, pt->refcount++; if (*ptr) { + struct pipe_context *pipe = (*ptr)->pipe; pipe->texture_release(pipe, ptr); assert(!*ptr); } @@ -114,6 +115,17 @@ pipe_texture_reference(struct pipe_context *pipe, struct pipe_texture **ptr, } +static INLINE void +pipe_texture_release(struct pipe_texture **ptr) +{ + struct pipe_context *pipe; + assert(ptr); + pipe = (*ptr)->pipe; + pipe->texture_release(pipe, ptr); + *ptr = NULL; +} + + #ifdef __cplusplus } #endif diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index ddf3c1c79b..25a6fcc9e6 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -296,6 +296,11 @@ struct pipe_texture /* These are also refcounted: */ unsigned refcount; + + /**< pipe that created the texture + * XXX this'll change to a pipe_winsys (or pipe_screen)... + */ + struct pipe_context *pipe; }; -- cgit v1.2.3 From aa59a937ccf41609081d3f9a4973df5478979785 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 20:15:14 -0700 Subject: gallium: introduce 'pipe_screen' for context-independent functions This will allow creating textures before a rendering context exists, for example. Only implemented in i915 driver for now. i915pipe->texture_create() just dispatches through to the i915screen->texture_create() to avoid state tracker changes for now. --- src/gallium/drivers/i915simple/Makefile | 1 + src/gallium/drivers/i915simple/i915_context.c | 32 +----- src/gallium/drivers/i915simple/i915_context.h | 7 +- src/gallium/drivers/i915simple/i915_screen.c | 139 +++++++++++++++++++++++ src/gallium/drivers/i915simple/i915_screen.h | 60 ++++++++++ src/gallium/drivers/i915simple/i915_strings.c | 27 ++++- src/gallium/drivers/i915simple/i915_texture.c | 76 +++++++++---- src/gallium/drivers/i915simple/i915_texture.h | 7 +- src/gallium/drivers/i915simple/i915_winsys.h | 8 +- src/gallium/include/pipe/p_context.h | 3 + src/gallium/include/pipe/p_inlines.h | 11 +- src/gallium/include/pipe/p_screen.h | 98 ++++++++++++++++ src/gallium/include/pipe/p_state.h | 2 + src/gallium/winsys/dri/intel/intel_winsys_i915.c | 10 +- 14 files changed, 418 insertions(+), 63 deletions(-) create mode 100644 src/gallium/drivers/i915simple/i915_screen.c create mode 100644 src/gallium/drivers/i915simple/i915_screen.h create mode 100644 src/gallium/include/pipe/p_screen.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/Makefile b/src/gallium/drivers/i915simple/Makefile index 2a75f5d57c..3400747a73 100644 --- a/src/gallium/drivers/i915simple/Makefile +++ b/src/gallium/drivers/i915simple/Makefile @@ -17,6 +17,7 @@ C_SOURCES = \ i915_state_derived.c \ i915_state_emit.c \ i915_state_sampler.c \ + i915_screen.c \ i915_strings.c \ i915_prim_emit.c \ i915_prim_vbuf.c \ diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index c3955bbd2d..8478cd76a5 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -234,33 +234,11 @@ static boolean i915_draw_arrays( struct pipe_context *pipe, -struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, - struct i915_winsys *i915_winsys, - unsigned pci_id ) +struct pipe_context *i915_create_context( struct pipe_screen *screen, + struct pipe_winsys *pipe_winsys, + struct i915_winsys *i915_winsys ) { struct i915_context *i915; - unsigned is_i945 = 0; - - switch (pci_id) { - case PCI_CHIP_I915_G: - case PCI_CHIP_I915_GM: - break; - - case PCI_CHIP_I945_G: - case PCI_CHIP_I945_GM: - case PCI_CHIP_I945_GME: - case PCI_CHIP_G33_G: - case PCI_CHIP_Q33_G: - case PCI_CHIP_Q35_G: - is_i945 = 1; - break; - - default: - pipe_winsys->printf(pipe_winsys, - "%s: unknown pci id 0x%x, cannot create context\n", - __FUNCTION__, pci_id); - return NULL; - } i915 = CALLOC_STRUCT(i915_context); if (i915 == NULL) @@ -268,6 +246,7 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, i915->winsys = i915_winsys; i915->pipe.winsys = pipe_winsys; + i915->pipe.screen = screen; i915->pipe.destroy = i915_destroy; i915->pipe.is_format_supported = i915_is_format_supported; @@ -301,9 +280,6 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, draw_install_aaline_stage(i915->draw, &i915->pipe); draw_install_aapoint_stage(i915->draw, &i915->pipe); - i915->pci_id = pci_id; - i915->flags.is_i945 = is_i945; - i915->dirty = ~0; i915->hardware_dirty = ~0; diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 20cf7d3c3b..9fb85c122d 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -245,11 +245,6 @@ struct i915_context unsigned hardware_dirty; unsigned debug; - unsigned pci_id; - - struct { - unsigned is_i945:1; - } flags; }; /* A flag for each state_tracker state object: @@ -322,6 +317,8 @@ void i915_init_surface_functions( struct i915_context *i915 ); void i915_init_state_functions( struct i915_context *i915 ); void i915_init_flush_functions( struct i915_context *i915 ); void i915_init_string_functions( struct i915_context *i915 ); +void i915_init_screen_string_functions(struct pipe_screen *screen); + diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c new file mode 100644 index 0000000000..7e9d971d38 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -0,0 +1,139 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" + +#include "i915_reg.h" +#include "i915_screen.h" +#include "i915_texture.h" + + +static const char * +i915_get_vendor( struct pipe_screen *pscreen ) +{ + return "Tungsten Graphics, Inc."; +} + + +static const char * +i915_get_name( struct pipe_screen *pscreen ) +{ + static char buffer[128]; + const char *chipset; + + switch (i915_screen(pscreen)->pci_id) { + case PCI_CHIP_I915_G: + chipset = "915G"; + break; + case PCI_CHIP_I915_GM: + chipset = "915GM"; + break; + case PCI_CHIP_I945_G: + chipset = "945G"; + break; + case PCI_CHIP_I945_GM: + chipset = "945GM"; + break; + case PCI_CHIP_I945_GME: + chipset = "945GME"; + break; + case PCI_CHIP_G33_G: + chipset = "G33"; + break; + case PCI_CHIP_Q35_G: + chipset = "Q35"; + break; + case PCI_CHIP_Q33_G: + chipset = "Q33"; + break; + default: + chipset = "unknown"; + break; + } + + sprintf(buffer, "i915 (chipset: %s)", chipset); + return buffer; +} + + + +static void +i915_destroy_screen( struct pipe_screen *screen ) +{ + FREE(screen); +} + + +/** + * Create a new i915_screen object + */ +struct pipe_screen * +i915_create_screen(struct pipe_winsys *winsys, uint pci_id) +{ + struct i915_screen *i915screen = CALLOC_STRUCT(i915_screen); + + if (!i915screen) + return NULL; + + switch (pci_id) { + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + i915screen->is_i945 = FALSE; + break; + + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q33_G: + case PCI_CHIP_Q35_G: + i915screen->is_i945 = TRUE; + break; + + default: + winsys->printf(winsys, + "%s: unknown pci id 0x%x, cannot create screen\n", + __FUNCTION__, pci_id); + return NULL; + } + + i915screen->pci_id = pci_id; + + i915screen->screen.winsys = winsys; + + i915screen->screen.destroy = i915_destroy_screen; + + i915screen->screen.get_name = i915_get_name; + i915screen->screen.get_vendor = i915_get_vendor; + + i915_init_screen_string_functions(&i915screen->screen); + i915_init_screen_texture_functions(&i915screen->screen); + + return &i915screen->screen; +} diff --git a/src/gallium/drivers/i915simple/i915_screen.h b/src/gallium/drivers/i915simple/i915_screen.h new file mode 100644 index 0000000000..8394ddbe89 --- /dev/null +++ b/src/gallium/drivers/i915simple/i915_screen.h @@ -0,0 +1,60 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef I915_SCREEN_H +#define I915_SCREEN_H + + +#include "pipe/p_screen.h" + + +/** + * Subclass of pipe_screen + */ +struct i915_screen +{ + struct pipe_screen screen; + + boolean is_i945; + uint pci_id; +}; + + +/** cast wrapper */ +static INLINE struct i915_screen * +i915_screen(struct pipe_screen *pscreen) +{ + return (struct i915_screen *) pscreen; +} + + +extern struct pipe_screen * +i915_create_screen(struct pipe_winsys *winsys, uint pci_id); + + +#endif /* I915_SCREEN_H */ diff --git a/src/gallium/drivers/i915simple/i915_strings.c b/src/gallium/drivers/i915simple/i915_strings.c index 301fedea19..ee62bb2e5d 100644 --- a/src/gallium/drivers/i915simple/i915_strings.c +++ b/src/gallium/drivers/i915simple/i915_strings.c @@ -26,21 +26,31 @@ **************************************************************************/ #include "i915_context.h" +#include "i915_screen.h" #include "i915_reg.h" +/** XXX temporary screen/pipe duplication here */ + + +static const char *i915_get_vendor_screen( struct pipe_screen *screen ) +{ + return "Tungsten Graphics, Inc."; +} + static const char *i915_get_vendor( struct pipe_context *pipe ) { return "Tungsten Graphics, Inc."; } -static const char *i915_get_name( struct pipe_context *pipe ) +static const char *i915_get_name_screen( struct pipe_screen *screen ) { + struct i915_screen *i915screen = i915_screen(screen); static char buffer[128]; const char *chipset; - switch (i915_context(pipe)->pci_id) { + switch (i915screen->pci_id) { case PCI_CHIP_I915_G: chipset = "915G"; break; @@ -75,9 +85,22 @@ static const char *i915_get_name( struct pipe_context *pipe ) } +static const char *i915_get_name( struct pipe_context *pipe ) +{ + return pipe->screen->get_name(pipe->screen); +} + + void i915_init_string_functions(struct i915_context *i915) { i915->pipe.get_name = i915_get_name; i915->pipe.get_vendor = i915_get_vendor; } + +void +i915_init_screen_string_functions(struct pipe_screen *screen) +{ + screen->get_name = i915_get_name_screen; + screen->get_vendor = i915_get_vendor_screen; +} diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 7fcf4332e1..3c9509dee3 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -40,6 +40,7 @@ #include "i915_context.h" #include "i915_texture.h" #include "i915_debug.h" +#include "i915_screen.h" static unsigned minify( unsigned d ) @@ -187,7 +188,7 @@ static const int step_offsets[6][2] = { static boolean -i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) +i915_miptree_layout(struct i915_texture * tex) { struct pipe_texture *pt = &tex->base; unsigned level; @@ -311,7 +312,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) static boolean -i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) +i945_miptree_layout(struct i915_texture * tex) { struct pipe_texture *pt = &tex->base; unsigned level; @@ -479,24 +480,26 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) static struct pipe_texture * -i915_texture_create(struct pipe_context *pipe, - const struct pipe_texture *templat) +i915_texture_create_screen(struct pipe_screen *screen, + const struct pipe_texture *templat) { struct i915_texture *tex = CALLOC_STRUCT(i915_texture); if (tex) { - struct i915_context *i915 = i915_context(pipe); + struct i915_screen *i915screen = i915_screen(screen); + struct pipe_winsys *ws = screen->winsys; tex->base = *templat; tex->base.refcount = 1; - tex->base.pipe = pipe; + tex->base.pipe = NULL; + tex->base.screen = screen; - if (i915->flags.is_i945 ? i945_miptree_layout(pipe, tex) : - i915_miptree_layout(pipe, tex)) - tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64, - PIPE_BUFFER_USAGE_PIXEL, - tex->pitch * tex->base.cpp * - tex->total_height); + if (i915screen->is_i945 ? i945_miptree_layout(tex) : + i915_miptree_layout(tex)) + tex->buffer = ws->buffer_create(ws, 64, + PIPE_BUFFER_USAGE_PIXEL, + tex->pitch * tex->base.cpp * + tex->total_height); if (!tex->buffer) { FREE(tex); @@ -508,8 +511,17 @@ i915_texture_create(struct pipe_context *pipe, } +static struct pipe_texture * +i915_texture_create(struct pipe_context *pipe, + const struct pipe_texture *templat) +{ + return pipe->screen->texture_create(pipe->screen, templat); +} + + static void -i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +i915_texture_release_screen(struct pipe_screen *screen, + struct pipe_texture **pt) { if (!*pt) return; @@ -526,7 +538,7 @@ i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); */ - pipe_buffer_reference(pipe->winsys, &tex->buffer, NULL); + pipe_buffer_reference(screen->winsys, &tex->buffer, NULL); for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++) if (tex->image_offset[i]) @@ -538,6 +550,13 @@ i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } +static void +i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + i915_texture_release_screen(pipe->screen, pt); +} + + static void i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) { @@ -549,11 +568,12 @@ i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) * XXX note: same as code in sp_surface.c */ static struct pipe_surface * -i915_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) +i915_get_tex_surface_screen(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) { struct i915_texture *tex = (struct i915_texture *)pt; + struct pipe_winsys *ws = screen->winsys; struct pipe_surface *ps; unsigned offset; /* in bytes */ @@ -570,11 +590,11 @@ i915_get_tex_surface(struct pipe_context *pipe, assert(zslice == 0); } - ps = pipe->winsys->surface_alloc(pipe->winsys); + ps = ws->surface_alloc(ws); if (ps) { assert(ps->refcount); assert(ps->winsys); - pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); + pipe_buffer_reference(ws, &ps->buffer, tex->buffer); ps->format = pt->format; ps->cpp = pt->cpp; ps->width = pt->width[level]; @@ -586,6 +606,14 @@ i915_get_tex_surface(struct pipe_context *pipe, } +static struct pipe_surface * +i915_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + return i915_get_tex_surface_screen(pipe->screen, pt, face, level, zslice); +} + void i915_init_texture_functions(struct i915_context *i915) @@ -595,3 +623,13 @@ i915_init_texture_functions(struct i915_context *i915) i915->pipe.texture_update = i915_texture_update; i915->pipe.get_tex_surface = i915_get_tex_surface; } + + + +void +i915_init_screen_texture_functions(struct pipe_screen *screen) +{ + screen->texture_create = i915_texture_create_screen; + screen->texture_release = i915_texture_release_screen; + screen->get_tex_surface = i915_get_tex_surface_screen; +} diff --git a/src/gallium/drivers/i915simple/i915_texture.h b/src/gallium/drivers/i915simple/i915_texture.h index 6d8d41178f..7225016a9f 100644 --- a/src/gallium/drivers/i915simple/i915_texture.h +++ b/src/gallium/drivers/i915simple/i915_texture.h @@ -28,11 +28,16 @@ #ifndef I915_TEXTURE_H #define I915_TEXTURE_H -struct pipe_context; +struct i915_context; +struct pipe_screen; extern void i915_init_texture_functions(struct i915_context *i915); +extern void +i915_init_screen_texture_functions(struct pipe_screen *screen); + + #endif /* I915_TEXTURE_H */ diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h index fe49710852..e6b0ac9c52 100644 --- a/src/gallium/drivers/i915simple/i915_winsys.h +++ b/src/gallium/drivers/i915simple/i915_winsys.h @@ -52,6 +52,7 @@ struct pipe_buffer; struct pipe_winsys; +struct pipe_screen; /** @@ -107,9 +108,8 @@ struct i915_winsys { #define I915_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0) -struct pipe_context *i915_create( struct pipe_winsys *, - struct i915_winsys *, - unsigned pci_id ); - +struct pipe_context *i915_create_context( struct pipe_screen *, + struct pipe_winsys *, + struct i915_winsys * ); #endif diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index f69b52f5e3..93fcb1c3e9 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -36,6 +36,8 @@ extern "C" { #endif +struct pipe_screen; + struct pipe_state_cache; /* Opaque driver handles: @@ -51,6 +53,7 @@ struct pipe_query; */ struct pipe_context { struct pipe_winsys *winsys; + struct pipe_screen *screen; void *priv; /** context private data (for DRI for example) */ diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index 21d4827e67..a7e97fcd7d 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -30,6 +30,7 @@ #include "p_context.h" #include "p_defines.h" +#include "p_screen.h" #include "p_winsys.h" @@ -107,7 +108,15 @@ pipe_texture_reference(struct pipe_texture **ptr, if (*ptr) { struct pipe_context *pipe = (*ptr)->pipe; - pipe->texture_release(pipe, ptr); + /* XXX temporary mess here */ + if (pipe) { + pipe->texture_release(pipe, ptr); + } + else { + struct pipe_screen *screen = (*ptr)->screen; + screen->texture_release(screen, ptr); + } + assert(!*ptr); } diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h new file mode 100644 index 0000000000..6be9a82b68 --- /dev/null +++ b/src/gallium/include/pipe/p_screen.h @@ -0,0 +1,98 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Screen, Adapter or GPU + * + * These are driver functions/facilities that are context independent. + */ + + +#ifndef P_SCREEN_H +#define P_SCREEN_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +/** + * Gallium screen/adapter context. Basically everything + * hardware-specific that doesn't actually require a rendering + * context. + */ +struct pipe_screen { + struct pipe_winsys *winsys; + + void (*destroy)( struct pipe_screen * ); + + + /* + * Capability queries + */ + const char *(*get_name)( struct pipe_screen * ); + + const char *(*get_vendor)( struct pipe_screen * ); + + int (*get_param)( struct pipe_screen *, int param ); + + float (*get_paramf)( struct pipe_screen *, int param ); + + boolean (*is_format_supported)( struct pipe_screen *, + enum pipe_format format, + uint type ); + + + /* + * Texture functions + */ + struct pipe_texture * (*texture_create)(struct pipe_screen *, + const struct pipe_texture *templat); + + void (*texture_release)(struct pipe_screen *, + struct pipe_texture **pt); + + /** Get a surface which is a "view" into a texture */ + struct pipe_surface *(*get_tex_surface)(struct pipe_screen *, + struct pipe_texture *texture, + unsigned face, unsigned level, + unsigned zslice); +}; + + +#ifdef __cplusplus +} +#endif + +#endif /* P_SCREEN_H */ diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 25a6fcc9e6..bb4a6cb23e 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -63,6 +63,7 @@ extern "C" { /* fwd decls */ +struct pipe_screen; struct pipe_surface; struct pipe_winsys; @@ -301,6 +302,7 @@ struct pipe_texture * XXX this'll change to a pipe_winsys (or pipe_screen)... */ struct pipe_context *pipe; + struct pipe_screen *screen; }; diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index 0ed3890e93..2def1afc31 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -40,6 +40,7 @@ #include "pipe/p_util.h" #include "i915simple/i915_winsys.h" +#include "i915simple/i915_screen.h" struct intel_i915_winsys { @@ -135,6 +136,7 @@ intel_create_i915simple( struct intel_context *intel, struct pipe_winsys *winsys ) { struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys ); + struct pipe_screen *screen; /* Fill in this struct with callbacks that i915simple will need to * communicate with the window system, buffer manager, etc. @@ -146,9 +148,11 @@ intel_create_i915simple( struct intel_context *intel, iws->winsys.batch_finish = intel_i915_batch_finish; iws->intel = intel; + screen = i915_create_screen(winsys, intel->intelScreen->deviceID); + /* Create the i915simple context: */ - return i915_create( winsys, - &iws->winsys, - intel->intelScreen->deviceID ); + return i915_create_context( screen, + winsys, + &iws->winsys ); } -- cgit v1.2.3 From 94047122571ac78717874bfb42598ab210cd7f80 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 26 Feb 2008 20:12:29 -0700 Subject: cell: insert a (disabled) call to spe_cpu_info_get() Found on the Cell devel forum, but doesn't appear to be available in SDK 2.1. --- src/gallium/drivers/cell/ppu/cell_context.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index 98c314f45c..5cbc922cb9 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -228,6 +228,9 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) * SPU stuff */ cell->num_spus = 6; + /* XXX is this in SDK 3.0 only? + cell->num_spus = spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1); + */ cell_start_spus(cell); -- cgit v1.2.3 From 8902ce06e85f48a436ee3794c77f7abf59f56594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 27 Feb 2008 14:06:07 +0900 Subject: gallium: Use stricter types. VC++ won't silently convert a pointer to a function with typed pointer arguments to one with void pointer arguments. --- src/gallium/auxiliary/cso_cache/cso_cache.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h index 3b0fe100b8..44ee128a4a 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.h +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -88,44 +88,44 @@ struct cso_cache; struct cso_blend { struct pipe_blend_state state; - void *data; - void (*delete_state)(void *, void *); - void *context; + void *data; + void (*delete_state)(struct pipe_context *, void *); + struct pipe_context *context; }; struct cso_depth_stencil_alpha { struct pipe_depth_stencil_alpha_state state; void *data; - void (*delete_state)(void *, void *); - void *context; + void (*delete_state)(struct pipe_context *, void *); + struct pipe_context *context; }; struct cso_rasterizer { struct pipe_rasterizer_state state; void *data; - void (*delete_state)(void *, void *); - void *context; + void (*delete_state)(struct pipe_context *, void *); + struct pipe_context *context; }; struct cso_fragment_shader { struct pipe_shader_state state; void *data; - void (*delete_state)(void *, void *); - void *context; + void (*delete_state)(struct pipe_context *, void *); + struct pipe_context *context; }; struct cso_vertex_shader { struct pipe_shader_state state; void *data; - void (*delete_state)(void *, void *); - void *context; + void (*delete_state)(struct pipe_context *, void *); + struct pipe_context *context; }; struct cso_sampler { struct pipe_sampler_state state; void *data; - void (*delete_state)(void *, void *); - void *context; + void (*delete_state)(struct pipe_context *, void *); + struct pipe_context *context; }; -- cgit v1.2.3 From f81b7a6285455e838adb061dcca90036c9f99522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 27 Feb 2008 15:59:09 +0900 Subject: gallium: update for new i915_screen.c file; fix some warnings. --- src/gallium/drivers/i915simple/SConscript | 1 + src/gallium/drivers/i915simple/i915_screen.c | 1 + src/gallium/drivers/i915simple/i915_screen.h | 9 +++++++++ src/gallium/drivers/i915simple/i915_winsys.h | 9 +++++++++ 4 files changed, 20 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/SConscript b/src/gallium/drivers/i915simple/SConscript index f5fb96b995..3e1beaea6d 100644 --- a/src/gallium/drivers/i915simple/SConscript +++ b/src/gallium/drivers/i915simple/SConscript @@ -15,6 +15,7 @@ i915simple = env.ConvenienceLibrary( 'i915_fpc_translate.c', 'i915_prim_emit.c', 'i915_prim_vbuf.c', + 'i915_screen.c', 'i915_state.c', 'i915_state_derived.c', 'i915_state_dynamic.c', diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 7e9d971d38..5630440a5a 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -30,6 +30,7 @@ #include "pipe/p_winsys.h" #include "i915_reg.h" +#include "i915_context.h" #include "i915_screen.h" #include "i915_texture.h" diff --git a/src/gallium/drivers/i915simple/i915_screen.h b/src/gallium/drivers/i915simple/i915_screen.h index 8394ddbe89..73b0ff05ce 100644 --- a/src/gallium/drivers/i915simple/i915_screen.h +++ b/src/gallium/drivers/i915simple/i915_screen.h @@ -33,6 +33,11 @@ #include "pipe/p_screen.h" +#ifdef __cplusplus +extern "C" { +#endif + + /** * Subclass of pipe_screen */ @@ -57,4 +62,8 @@ extern struct pipe_screen * i915_create_screen(struct pipe_winsys *winsys, uint pci_id); +#ifdef __cplusplus +} +#endif + #endif /* I915_SCREEN_H */ diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h index e6b0ac9c52..aea3003281 100644 --- a/src/gallium/drivers/i915simple/i915_winsys.h +++ b/src/gallium/drivers/i915simple/i915_winsys.h @@ -40,6 +40,11 @@ #include "pipe/p_defines.h" +#ifdef __cplusplus +extern "C" { +#endif + + /* Pipe drivers are (meant to be!) independent of both GL and the * window system. The window system provides a buffer manager and a * set of additional hooks for things like command buffer submission, @@ -112,4 +117,8 @@ struct pipe_context *i915_create_context( struct pipe_screen *, struct pipe_winsys *, struct i915_winsys * ); +#ifdef __cplusplus +} +#endif + #endif -- cgit v1.2.3 From 94c73d1bb9037a1eead1d5174f218b15852b52d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 27 Feb 2008 16:23:50 +0900 Subject: gallium: Remove // comments. --- src/gallium/include/pipe/p_defines.h | 2 +- src/gallium/include/pipe/p_format.h | 2 +- src/gallium/include/pipe/p_shader_tokens.h | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index d84ddbc27a..0c662d6517 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -152,7 +152,7 @@ enum pipe_texture_target { */ #define PIPE_TEX_FILTER_NEAREST 0 #define PIPE_TEX_FILTER_LINEAR 1 -//#define PIPE_TEX_FILTER_ANISO 2 +/* #define PIPE_TEX_FILTER_ANISO 2 */ #define PIPE_TEX_COMPARE_NONE 0 diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 561d2e5921..f90087b3c9 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -28,7 +28,7 @@ #ifndef PIPE_FORMAT_H #define PIPE_FORMAT_H -#include // for sprintf +#include /* for sprintf */ #include "p_compiler.h" #include "p_debug.h" diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 1806877f6c..0a6145a6bf 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -1,9 +1,9 @@ #if !defined TGSI_TOKEN_H #define TGSI_TOKEN_H -#if defined __cplusplus +#ifdef __cplusplus extern "C" { -#endif // defined __cplusplus +#endif #include "p_compiler.h" @@ -802,9 +802,9 @@ struct tgsi_dst_register_ext_predicate }; -#if defined __cplusplus -} // extern "C" -#endif // defined __cplusplus +#ifdef __cplusplus +} +#endif -#endif // !defined TGSI_TOKEN_H +#endif /* TGSI_TOKEN_H */ -- cgit v1.2.3 From 9a8a5d7c2fe7f32c8d15bc0a77f86e1f2f995ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 27 Feb 2008 16:42:15 +0900 Subject: gallium: Replace // comments. --- src/gallium/auxiliary/gallivm/gallivm.h | 2 +- src/gallium/auxiliary/gallivm/gallivm_p.h | 6 +++--- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2 +- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h | 8 ++++---- src/gallium/auxiliary/tgsi/util/tgsi_build.h | 8 ++++---- src/gallium/auxiliary/tgsi/util/tgsi_dump.h | 8 ++++---- src/gallium/auxiliary/tgsi/util/tgsi_parse.h | 8 ++++---- src/gallium/auxiliary/tgsi/util/tgsi_util.h | 8 ++++---- 8 files changed, 25 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/gallivm.h b/src/gallium/auxiliary/gallivm/gallivm.h index 92da4bca7f..57912a952f 100644 --- a/src/gallium/auxiliary/gallivm/gallivm.h +++ b/src/gallium/auxiliary/gallivm/gallivm.h @@ -97,7 +97,7 @@ void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *ee); #endif /* MESA_LLVM */ #if defined __cplusplus -} // extern "C" +} #endif #endif diff --git a/src/gallium/auxiliary/gallivm/gallivm_p.h b/src/gallium/auxiliary/gallivm/gallivm_p.h index cfe7b1901b..ebf3e11cd5 100644 --- a/src/gallium/auxiliary/gallivm/gallivm_p.h +++ b/src/gallium/auxiliary/gallivm/gallivm_p.h @@ -32,7 +32,7 @@ struct gallivm_ir { int num_components; int num_consts; - //FIXME: this might not be enough for some shaders + /* FIXME: this might not be enough for some shaders */ struct gallivm_interpolate interpolators[32*4]; int num_interp; }; @@ -46,7 +46,7 @@ struct gallivm_prog { int num_consts; - //FIXME: this might not be enough for some shaders + /* FIXME: this might not be enough for some shaders */ struct gallivm_interpolate interpolators[32*4]; int num_interp; }; @@ -104,7 +104,7 @@ static INLINE int gallivm_w_swizzle(int swizzle) #endif /* MESA_LLVM */ #if defined __cplusplus -} // extern "C" +} #endif #endif diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 779b901f2b..57ccd86be4 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -1268,7 +1268,7 @@ emit_store( break; case TGSI_SAT_ZERO_ONE: -// assert( 0 ); + /* assert( 0 ); */ break; case TGSI_SAT_MINUS_PLUS_ONE: diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h index 9bee371766..63b8ef3911 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h @@ -3,7 +3,7 @@ #if defined __cplusplus extern "C" { -#endif // defined __cplusplus +#endif struct tgsi_token; struct x86_function; @@ -19,8 +19,8 @@ tgsi_emit_sse2_fs( struct x86_function *function ); #if defined __cplusplus -} // extern "C" -#endif // defined __cplusplus +} +#endif -#endif // !defined TGSI_SSE2_H +#endif /* TGSI_SSE2_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.h b/src/gallium/auxiliary/tgsi/util/tgsi_build.h index 116c78abf3..607860e7fc 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.h @@ -3,7 +3,7 @@ #if defined __cplusplus extern "C" { -#endif // defined __cplusplus +#endif /* * version @@ -313,8 +313,8 @@ tgsi_build_dst_register_ext_modulate( struct tgsi_header *header ); #if defined __cplusplus -} // extern "C" -#endif // defined __cplusplus +} +#endif -#endif // !defined TGSI_BUILD_H +#endif /* TGSI_BUILD_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h index 1adc9db251..b983b38226 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h @@ -3,7 +3,7 @@ #if defined __cplusplus extern "C" { -#endif // defined __cplusplus +#endif #define TGSI_DUMP_VERBOSE 1 #define TGSI_DUMP_NO_IGNORED 2 @@ -21,8 +21,8 @@ tgsi_dump_str( unsigned flags ); #if defined __cplusplus -} // extern "C" -#endif // defined __cplusplus +} +#endif -#endif // !defined TGSI_DUMP_H +#endif /* TGSI_DUMP_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h index 9372da8d5d..5ccb5bfcf6 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h @@ -3,7 +3,7 @@ #if defined __cplusplus extern "C" { -#endif // defined __cplusplus +#endif struct tgsi_full_version { @@ -114,8 +114,8 @@ tgsi_parse_token( struct tgsi_parse_context *ctx ); #if defined __cplusplus -} // extern "C" -#endif // defined __cplusplus +} +#endif -#endif // !defined TGSI_PARSE_H +#endif /* TGSI_PARSE_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.h b/src/gallium/auxiliary/tgsi/util/tgsi_util.h index ef14446f0e..45f5f0be0e 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_util.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_util.h @@ -3,7 +3,7 @@ #if defined __cplusplus extern "C" { -#endif // defined __cplusplus +#endif void * tgsi_align_128bit( @@ -63,8 +63,8 @@ tgsi_util_set_full_src_register_sign_mode( unsigned sign_mode ); #if defined __cplusplus -} // extern "C" -#endif // defined __cplusplus +} +#endif -#endif // !defined TGSI_UTIL_H +#endif /* TGSI_UTIL_H */ -- cgit v1.2.3 From d6229d7f1fda03d3c73998505b0facf6e3d5b882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 27 Feb 2008 18:39:57 +0900 Subject: gallium: Make headers C++ friendly. --- src/gallium/auxiliary/pipebuffer/pb_buffer.h | 11 ++++++++++- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h | 11 ++++++++++- src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 11 ++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index f5b5f4052f..4b09c80b2a 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -37,7 +37,7 @@ * There is no obligation of a winsys driver to use this library. And a pipe * driver should be completly agnostic about it. * - * \author José Fonseca + * \author Jos� Fonseca */ #ifndef PB_BUFFER_H_ @@ -50,6 +50,11 @@ #include "pipe/p_inlines.h" +#ifdef __cplusplus +extern "C" { +#endif + + struct pb_vtbl; /** @@ -200,4 +205,8 @@ void pb_init_winsys(struct pipe_winsys *winsys); +#ifdef __cplusplus +} +#endif + #endif /*PB_BUFFER_H_*/ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h index c40b9c75e1..50d5891bdb 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h @@ -44,7 +44,7 @@ * Between the handle's destruction, and the fence signalling, the buffer is * stored in a fenced buffer list. * - * \author José Fonseca + * \author José Fonseca */ #ifndef PB_BUFFER_FENCED_H_ @@ -54,6 +54,11 @@ #include "pipe/p_debug.h" +#ifdef __cplusplus +extern "C" { +#endif + + struct pipe_winsys; struct pipe_buffer; struct pipe_fence_handle; @@ -114,4 +119,8 @@ buffer_fence(struct pb_buffer *buf, struct pipe_fence_handle *fence); +#ifdef __cplusplus +} +#endif + #endif /*PB_BUFFER_FENCED_H_*/ diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 1ddf784c97..0cf8e92e37 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -43,7 +43,7 @@ * - the fenced buffer manager, which will delay buffer destruction until the * the moment the card finishing processing it. * - * \author José Fonseca + * \author José Fonseca */ #ifndef PB_BUFMGR_H_ @@ -53,6 +53,11 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + + struct pb_desc; struct pipe_buffer; struct pipe_winsys; @@ -123,4 +128,8 @@ fenced_bufmgr_create(struct pb_manager *provider, struct pipe_winsys *winsys); +#ifdef __cplusplus +} +#endif + #endif /*PB_BUFMGR_H_*/ -- cgit v1.2.3 From e8c0162fa0c4720aea612a617cbd02b83590763c Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 08:58:12 -0700 Subject: gallium: softpipe_init_texture_funcs(), make texture func static --- src/gallium/drivers/softpipe/sp_context.c | 7 +------ src/gallium/drivers/softpipe/sp_texture.c | 19 +++++++++++++++---- src/gallium/drivers/softpipe/sp_texture.h | 16 +--------------- 3 files changed, 17 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 6a884327e0..78acf51433 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -279,12 +279,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.flush = softpipe_flush; softpipe_init_query_funcs( softpipe ); - - /* textures */ - softpipe->pipe.texture_create = softpipe_texture_create; - softpipe->pipe.texture_release = softpipe_texture_release; - softpipe->pipe.texture_update = softpipe_texture_update; - softpipe->pipe.get_tex_surface = softpipe_get_tex_surface; + softpipe_init_texture_funcs( softpipe ); /* * Alloc caches for accessing drawing surfaces and textures. diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index a96447fa7a..1594521961 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -80,7 +80,7 @@ softpipe_texture_layout(struct softpipe_texture * spt) } -struct pipe_texture * +static struct pipe_texture * softpipe_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) { @@ -108,7 +108,7 @@ softpipe_texture_create(struct pipe_context *pipe, } -void +static void softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) { if (!*pt) @@ -133,7 +133,7 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } -void +static void softpipe_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) { @@ -150,7 +150,7 @@ softpipe_texture_update(struct pipe_context *pipe, /** * Called via pipe->get_tex_surface() */ -struct pipe_surface * +static struct pipe_surface * softpipe_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) @@ -183,3 +183,14 @@ softpipe_get_tex_surface(struct pipe_context *pipe, } return ps; } + + + +void +softpipe_init_texture_funcs( struct softpipe_context *softpipe ) +{ + softpipe->pipe.texture_create = softpipe_texture_create; + softpipe->pipe.texture_release = softpipe_texture_release; + softpipe->pipe.texture_update = softpipe_texture_update; + softpipe->pipe.get_tex_surface = softpipe_get_tex_surface; +} diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index 50fc100427..01b1e28ec5 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -54,22 +54,8 @@ softpipe_texture(struct pipe_texture *pt) } - -extern struct pipe_texture * -softpipe_texture_create(struct pipe_context *pipe, - const struct pipe_texture *templat); - extern void -softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); - -extern void -softpipe_texture_update(struct pipe_context *pipe, - struct pipe_texture *texture); - -extern struct pipe_surface * -softpipe_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice); +softpipe_init_texture_funcs( struct softpipe_context *softpipe ); #endif /* SP_TEXTURE */ -- cgit v1.2.3 From 31358282d4bd5a9708dba7be059dcff02233b4e1 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 09:15:15 -0700 Subject: gallium: better debug messages --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 57ccd86be4..0da3b0bdb7 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -2268,7 +2268,7 @@ tgsi_emit_sse2( &parse.FullToken.FullInstruction ); if (!ok) { - debug_printf("failed to translate tgsi opcode %d\n", + debug_printf("failed to translate tgsi opcode %d to SSE\n", parse.FullToken.FullInstruction.Instruction.Opcode ); } break; @@ -2276,7 +2276,7 @@ tgsi_emit_sse2( case TGSI_TOKEN_TYPE_IMMEDIATE: /* XXX implement this */ ok = 0; - debug_printf("failed to emit immediate value\n"); + debug_printf("failed to emit immediate value to SSE\n"); break; default: @@ -2358,7 +2358,7 @@ tgsi_emit_sse2_fs( &parse.FullToken.FullInstruction ); if (!ok) { - debug_printf("failed to translate tgsi opcode %d\n", + debug_printf("failed to translate tgsi opcode %d to SSE\n", parse.FullToken.FullInstruction.Instruction.Opcode ); } break; @@ -2366,7 +2366,7 @@ tgsi_emit_sse2_fs( case TGSI_TOKEN_TYPE_IMMEDIATE: /* XXX implement this */ ok = 0; - debug_printf("failed to emit immediate value\n"); + debug_printf("failed to emit immediate value to SSE\n"); break; default: -- cgit v1.2.3 From ef6c82b0c13573df1aab7acd6f4f9ef9076f421f Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 09:46:10 -0700 Subject: gallium/i915: remove some redundant code --- src/gallium/drivers/i915simple/i915_context.h | 1 - src/gallium/drivers/i915simple/i915_screen.c | 1 - src/gallium/drivers/i915simple/i915_strings.c | 55 +-------------------------- 3 files changed, 1 insertion(+), 56 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 9fb85c122d..6401112f83 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -317,7 +317,6 @@ void i915_init_surface_functions( struct i915_context *i915 ); void i915_init_state_functions( struct i915_context *i915 ); void i915_init_flush_functions( struct i915_context *i915 ); void i915_init_string_functions( struct i915_context *i915 ); -void i915_init_screen_string_functions(struct pipe_screen *screen); diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 5630440a5a..f44ff43c99 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -133,7 +133,6 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id) i915screen->screen.get_name = i915_get_name; i915screen->screen.get_vendor = i915_get_vendor; - i915_init_screen_string_functions(&i915screen->screen); i915_init_screen_texture_functions(&i915screen->screen); return &i915screen->screen; diff --git a/src/gallium/drivers/i915simple/i915_strings.c b/src/gallium/drivers/i915simple/i915_strings.c index ee62bb2e5d..14da3bcd72 100644 --- a/src/gallium/drivers/i915simple/i915_strings.c +++ b/src/gallium/drivers/i915simple/i915_strings.c @@ -33,55 +33,9 @@ /** XXX temporary screen/pipe duplication here */ -static const char *i915_get_vendor_screen( struct pipe_screen *screen ) -{ - return "Tungsten Graphics, Inc."; -} - static const char *i915_get_vendor( struct pipe_context *pipe ) { - return "Tungsten Graphics, Inc."; -} - - -static const char *i915_get_name_screen( struct pipe_screen *screen ) -{ - struct i915_screen *i915screen = i915_screen(screen); - static char buffer[128]; - const char *chipset; - - switch (i915screen->pci_id) { - case PCI_CHIP_I915_G: - chipset = "915G"; - break; - case PCI_CHIP_I915_GM: - chipset = "915GM"; - break; - case PCI_CHIP_I945_G: - chipset = "945G"; - break; - case PCI_CHIP_I945_GM: - chipset = "945GM"; - break; - case PCI_CHIP_I945_GME: - chipset = "945GME"; - break; - case PCI_CHIP_G33_G: - chipset = "G33"; - break; - case PCI_CHIP_Q35_G: - chipset = "Q35"; - break; - case PCI_CHIP_Q33_G: - chipset = "Q33"; - break; - default: - chipset = "unknown"; - break; - } - - sprintf(buffer, "i915 (chipset: %s)", chipset); - return buffer; + return pipe->screen->get_vendor(pipe->screen); } @@ -97,10 +51,3 @@ i915_init_string_functions(struct i915_context *i915) i915->pipe.get_name = i915_get_name; i915->pipe.get_vendor = i915_get_vendor; } - -void -i915_init_screen_string_functions(struct pipe_screen *screen) -{ - screen->get_name = i915_get_name_screen; - screen->get_vendor = i915_get_vendor_screen; -} -- cgit v1.2.3 From 4f36cf5858a7e53181c3578685675e15fbfcbb82 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 09:47:46 -0700 Subject: gallium: implement pipe_screen for softpipe driver --- src/gallium/drivers/softpipe/Makefile | 1 + src/gallium/drivers/softpipe/sp_context.c | 64 ++-------- src/gallium/drivers/softpipe/sp_screen.c | 141 +++++++++++++++++++++ src/gallium/drivers/softpipe/sp_texture.c | 57 +++++++-- src/gallium/drivers/softpipe/sp_texture.h | 10 +- src/gallium/drivers/softpipe/sp_winsys.h | 7 +- .../winsys/dri/intel/intel_winsys_softpipe.c | 3 +- src/gallium/winsys/xlib/xm_winsys.c | 3 +- 8 files changed, 220 insertions(+), 66 deletions(-) create mode 100644 src/gallium/drivers/softpipe/sp_screen.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index 539ffb77f5..f32db35d58 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -27,6 +27,7 @@ C_SOURCES = \ sp_quad_output.c \ sp_quad_stencil.c \ sp_quad_stipple.c \ + sp_screen.c \ sp_state_blend.c \ sp_state_clip.c \ sp_state_derived.c \ diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 78acf51433..4ac1719cbb 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -143,76 +143,31 @@ static void softpipe_destroy( struct pipe_context *pipe ) } +/* XXX these will go away shortly */ static const char *softpipe_get_name( struct pipe_context *pipe ) { - return "softpipe"; + return pipe->screen->get_name(pipe->screen); } static const char *softpipe_get_vendor( struct pipe_context *pipe ) { - return "Tungsten Graphics, Inc."; + return pipe->screen->get_vendor(pipe->screen); } static int softpipe_get_param(struct pipe_context *pipe, int param) { - switch (param) { - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 8; - case PIPE_CAP_NPOT_TEXTURES: - return 1; - case PIPE_CAP_TWO_SIDED_STENCIL: - return 1; - case PIPE_CAP_GLSL: - return 1; - case PIPE_CAP_S3TC: - return 0; - case PIPE_CAP_ANISOTROPIC_FILTER: - return 0; - case PIPE_CAP_POINT_SPRITE: - return 1; - case PIPE_CAP_MAX_RENDER_TARGETS: - return 1; - case PIPE_CAP_OCCLUSION_QUERY: - return 1; - case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 1; - case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - return 12; /* max 2Kx2K */ - case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - return 8; /* max 128x128x128 */ - case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - return 12; /* max 2Kx2K */ - default: - return 0; - } + return pipe->screen->get_param(pipe->screen, param); } static float softpipe_get_paramf(struct pipe_context *pipe, int param) { - switch (param) { - case PIPE_CAP_MAX_LINE_WIDTH: - /* fall-through */ - case PIPE_CAP_MAX_LINE_WIDTH_AA: - return 255.0; /* arbitrary */ - - case PIPE_CAP_MAX_POINT_WIDTH: - /* fall-through */ - case PIPE_CAP_MAX_POINT_WIDTH_AA: - return 255.0; /* arbitrary */ - - case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return 0.0; - - case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: - return 16.0; /* arbitrary */ - - default: - return 0; - } + return pipe->screen->get_paramf(pipe->screen, param); } -struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, - struct softpipe_winsys *softpipe_winsys ) +struct pipe_context * +softpipe_create( struct pipe_screen *screen, + struct pipe_winsys *pipe_winsys, + struct softpipe_winsys *softpipe_winsys ) { struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); uint i; @@ -226,6 +181,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL; softpipe->pipe.winsys = pipe_winsys; + softpipe->pipe.screen = screen; softpipe->pipe.destroy = softpipe_destroy; /* queries */ diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c new file mode 100644 index 0000000000..cc3b962580 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -0,0 +1,141 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_screen.h" + +#include "sp_texture.h" +#include "sp_winsys.h" + + +static const char * +softpipe_get_vendor(struct pipe_screen *screen) +{ + return "Tungsten Graphics, Inc."; +} + + +static const char * +softpipe_get_name(struct pipe_screen *screen) +{ + return "softpipe"; +} + + +static int +softpipe_get_param(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 8; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 1; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 1; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 1; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 12; /* max 2Kx2K */ + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 8; /* max 128x128x128 */ + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 12; /* max 2Kx2K */ + default: + return 0; + } +} + + +static float +softpipe_get_paramf(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 255.0; /* arbitrary */ + case PIPE_CAP_MAX_POINT_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 255.0; /* arbitrary */ + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 0.0; + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0; /* arbitrary */ + default: + return 0; + } +} + + +static void +softpipe_destroy_screen( struct pipe_screen *screen ) +{ + FREE(screen); +} + + +/** + * Create a new pipe_screen object + * Note: we're not presently subclassing pipe_screen (no softpipe_screen). + */ +struct pipe_screen * +softpipe_create_screen(struct pipe_winsys *winsys) +{ + struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen); + + if (!screen) + return NULL; + + screen->winsys = winsys; + + screen->destroy = softpipe_destroy_screen; + + screen->get_name = softpipe_get_name; + screen->get_vendor = softpipe_get_vendor; + screen->get_param = softpipe_get_param; + screen->get_paramf = softpipe_get_paramf; + + softpipe_init_screen_texture_funcs(screen); + + return screen; +} diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 1594521961..f0e8350a4a 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -80,23 +80,34 @@ softpipe_texture_layout(struct softpipe_texture * spt) } +/* XXX temporary */ static struct pipe_texture * softpipe_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) { + return pipe->screen->texture_create(pipe->screen, templat); +} + + +static struct pipe_texture * +softpipe_texture_create_screen(struct pipe_screen *screen, + const struct pipe_texture *templat) +{ + struct pipe_winsys *ws = screen->winsys; struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); if (!spt) return NULL; spt->base = *templat; spt->base.refcount = 1; - spt->base.pipe = pipe; + spt->base.pipe = NULL; + spt->base.screen = screen; softpipe_texture_layout(spt); - spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32, - PIPE_BUFFER_USAGE_PIXEL, - spt->buffer_size); + spt->buffer = ws->buffer_create(ws, 32, + PIPE_BUFFER_USAGE_PIXEL, + spt->buffer_size); if (!spt->buffer) { FREE(spt); return NULL; @@ -108,8 +119,17 @@ softpipe_texture_create(struct pipe_context *pipe, } +/* XXX temporary */ static void softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + return pipe->screen->texture_release(pipe->screen, pt); +} + + +static void +softpipe_texture_release_screen(struct pipe_screen *screen, + struct pipe_texture **pt) { if (!*pt) return; @@ -125,7 +145,7 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); */ - pipe_buffer_reference(pipe->winsys, &spt->buffer, NULL); + pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); FREE(spt); } @@ -150,21 +170,32 @@ softpipe_texture_update(struct pipe_context *pipe, /** * Called via pipe->get_tex_surface() */ +/* XXX temporary */ static struct pipe_surface * softpipe_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) { + return pipe->screen->get_tex_surface(pipe->screen, pt, face, level, zslice); +} + + +static struct pipe_surface * +softpipe_get_tex_surface_screen(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = screen->winsys; struct softpipe_texture *spt = softpipe_texture(pt); struct pipe_surface *ps; assert(level <= pt->last_level); - ps = pipe->winsys->surface_alloc(pipe->winsys); + ps = ws->surface_alloc(ws); if (ps) { assert(ps->refcount); assert(ps->winsys); - pipe_buffer_reference(pipe->winsys, &ps->buffer, spt->buffer); + pipe_buffer_reference(ws, &ps->buffer, spt->buffer); ps->format = pt->format; ps->cpp = pt->cpp; ps->width = pt->width[level]; @@ -176,7 +207,8 @@ softpipe_get_tex_surface(struct pipe_context *pipe, ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * (pt->compressed ? ps->height/4 : ps->height) * ps->width * ps->cpp; - } else { + } + else { assert(face == 0); assert(zslice == 0); } @@ -194,3 +226,12 @@ softpipe_init_texture_funcs( struct softpipe_context *softpipe ) softpipe->pipe.texture_update = softpipe_texture_update; softpipe->pipe.get_tex_surface = softpipe_get_tex_surface; } + + +void +softpipe_init_screen_texture_funcs(struct pipe_screen *screen) +{ + screen->texture_create = softpipe_texture_create_screen; + screen->texture_release = softpipe_texture_release_screen; + screen->get_tex_surface = softpipe_get_tex_surface_screen; +} diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index 01b1e28ec5..a7322144e6 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -29,8 +29,12 @@ #define SP_TEXTURE_H +#include "pipe/p_state.h" + + struct pipe_context; -struct pipe_texture; +struct pipe_screen; +struct softpipe_context; struct softpipe_texture @@ -58,4 +62,8 @@ extern void softpipe_init_texture_funcs( struct softpipe_context *softpipe ); +extern void +softpipe_init_screen_texture_funcs(struct pipe_screen *screen); + + #endif /* SP_TEXTURE */ diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h index d6b379f58c..80f5354808 100644 --- a/src/gallium/drivers/softpipe/sp_winsys.h +++ b/src/gallium/drivers/softpipe/sp_winsys.h @@ -50,8 +50,13 @@ struct pipe_winsys; struct pipe_context; -struct pipe_context *softpipe_create( struct pipe_winsys *, +struct pipe_context *softpipe_create( struct pipe_screen *, + struct pipe_winsys *, struct softpipe_winsys * ); +struct pipe_screen * +softpipe_create_screen(struct pipe_winsys *); + + #endif /* SP_WINSYS_H */ diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c index 9e483bdc9f..0bc2dc4002 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c @@ -68,6 +68,7 @@ intel_create_softpipe( struct intel_context *intel, struct pipe_winsys *winsys ) { struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); + struct pipe_screen *screen = softpipe_create_screen(winsys); /* Fill in this struct with callbacks that softpipe will need to * communicate with the window system, buffer manager, etc. @@ -77,5 +78,5 @@ intel_create_softpipe( struct intel_context *intel, /* Create the softpipe context: */ - return softpipe_create( winsys, &isws->sws ); + return softpipe_create( screen, winsys, &isws->sws ); } diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 8da596d419..adebe4020a 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -457,7 +457,8 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) #endif { struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat); - pipe = softpipe_create( pws, spws ); + struct pipe_screen *screen = softpipe_create_screen(pws); + pipe = softpipe_create( screen, pws, spws ); if (pipe) pipe->priv = xmesa; -- cgit v1.2.3 From f04736c8be5d30c510e1799ac0c8fa5173516513 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 09:55:17 -0700 Subject: Cell: implement pipe_screen for cell driver --- src/gallium/drivers/cell/ppu/Makefile | 1 + src/gallium/drivers/cell/ppu/cell_context.c | 68 +++---------- src/gallium/drivers/cell/ppu/cell_context.h | 2 +- src/gallium/drivers/cell/ppu/cell_screen.c | 147 ++++++++++++++++++++++++++++ src/gallium/drivers/cell/ppu/cell_screen.h | 41 ++++++++ src/gallium/drivers/cell/ppu/cell_texture.c | 49 ++++++++-- src/gallium/drivers/cell/ppu/cell_texture.h | 4 + src/gallium/winsys/xlib/xm_winsys.c | 6 +- 8 files changed, 254 insertions(+), 64 deletions(-) create mode 100644 src/gallium/drivers/cell/ppu/cell_screen.c create mode 100644 src/gallium/drivers/cell/ppu/cell_screen.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index 164dde762c..d38fa6ce07 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -29,6 +29,7 @@ SOURCES = \ cell_state_emit.c \ cell_state_shader.c \ cell_pipe_state.c \ + cell_screen.c \ cell_state_vertex.c \ cell_spu.c \ cell_surface.c \ diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index 5cbc922cb9..bb1838409f 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -37,9 +37,12 @@ #include "pipe/p_format.h" #include "pipe/p_util.h" #include "pipe/p_winsys.h" -#include "cell/common.h" +#include "pipe/p_screen.h" + #include "draw/draw_context.h" #include "draw/draw_private.h" + +#include "cell/common.h" #include "cell_clear.h" #include "cell_context.h" #include "cell_draw_arrays.h" @@ -76,73 +79,24 @@ cell_is_format_supported( struct pipe_context *pipe, static int cell_get_param(struct pipe_context *pipe, int param) { - switch (param) { - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 8; - case PIPE_CAP_NPOT_TEXTURES: - return 1; - case PIPE_CAP_TWO_SIDED_STENCIL: - return 1; - case PIPE_CAP_GLSL: - return 1; - case PIPE_CAP_S3TC: - return 0; - case PIPE_CAP_ANISOTROPIC_FILTER: - return 0; - case PIPE_CAP_POINT_SPRITE: - return 1; - case PIPE_CAP_MAX_RENDER_TARGETS: - return 1; - case PIPE_CAP_OCCLUSION_QUERY: - return 1; - case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 1; - case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - return 12; /* max 2Kx2K */ - case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - return 8; /* max 128x128x128 */ - case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - return 12; /* max 2Kx2K */ - default: - return 0; - } + return pipe->screen->get_param(pipe->screen, param); } static float cell_get_paramf(struct pipe_context *pipe, int param) { - switch (param) { - case PIPE_CAP_MAX_LINE_WIDTH: - /* fall-through */ - case PIPE_CAP_MAX_LINE_WIDTH_AA: - return 255.0; /* arbitrary */ - - case PIPE_CAP_MAX_POINT_WIDTH: - /* fall-through */ - case PIPE_CAP_MAX_POINT_WIDTH_AA: - return 255.0; /* arbitrary */ - - case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return 0.0; - - case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: - return 16.0; /* arbitrary */ - - default: - return 0; - } + return pipe->screen->get_paramf(pipe->screen, param); } - static const char * cell_get_name( struct pipe_context *pipe ) { - return "Cell"; + return pipe->screen->get_name(pipe->screen); } static const char * cell_get_vendor( struct pipe_context *pipe ) { - return "Tungsten Graphics, Inc."; + return pipe->screen->get_vendor(pipe->screen); } @@ -174,7 +128,8 @@ cell_draw_create(struct cell_context *cell) struct pipe_context * -cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) +cell_create_context(struct pipe_screen *screen, + struct cell_winsys *cws) { struct cell_context *cell; uint spu, buf; @@ -187,7 +142,8 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) memset(cell, 0, sizeof(*cell)); cell->winsys = cws; - cell->pipe.winsys = winsys; + cell->pipe.winsys = screen->winsys; + cell->pipe.screen = screen; cell->pipe.destroy = cell_destroy_context; /* queries */ diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 1433a4925f..bf27289f3f 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -128,7 +128,7 @@ cell_context(struct pipe_context *pipe) extern struct pipe_context * -cell_create_context(struct pipe_winsys *ws, struct cell_winsys *cws); +cell_create_context(struct pipe_screen *screen, struct cell_winsys *cws); extern void cell_vertex_shader_queue_flush(struct draw_context *draw); diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c new file mode 100644 index 0000000000..75255c0466 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -0,0 +1,147 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_screen.h" + +#include "cell_screen.h" +#include "cell_texture.h" +#include "cell_winsys.h" + + +static const char * +cell_get_vendor(struct pipe_screen *screen) +{ + return "Tungsten Graphics, Inc."; +} + + +static const char * +cell_get_name(struct pipe_screen *screen) +{ + return "Cell"; +} + + +static int +cell_get_param(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 8; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 1; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 1; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 1; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 12; /* max 2Kx2K */ + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 8; /* max 128x128x128 */ + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 12; /* max 2Kx2K */ + default: + return 0; + } +} + + +static float +cell_get_paramf(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 255.0; /* arbitrary */ + + case PIPE_CAP_MAX_POINT_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 255.0; /* arbitrary */ + + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 0.0; + + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0; /* arbitrary */ + + default: + return 0; + } +} + + +static void +cell_destroy_screen( struct pipe_screen *screen ) +{ + FREE(screen); +} + + +/** + * Create a new pipe_screen object + * Note: we're not presently subclassing pipe_screen (no cell_screen) but + * that would be the place to put SPU thread/context info... + */ +struct pipe_screen * +cell_create_screen(struct pipe_winsys *winsys) +{ + struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen); + + if (!screen) + return NULL; + + screen->winsys = winsys; + + screen->destroy = cell_destroy_screen; + + screen->get_name = cell_get_name; + screen->get_vendor = cell_get_vendor; + screen->get_param = cell_get_param; + screen->get_paramf = cell_get_paramf; + + cell_init_screen_texture_funcs(screen); + + return screen; +} diff --git a/src/gallium/drivers/cell/ppu/cell_screen.h b/src/gallium/drivers/cell/ppu/cell_screen.h new file mode 100644 index 0000000000..c7e15889d6 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_screen.h @@ -0,0 +1,41 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef CELL_SCREEN_H +#define CELL_SCREEN_H + + +struct pipe_screen; +struct pipe_winsys; + + +extern struct pipe_screen * +cell_create_screen(struct pipe_winsys *winsys); + + +#endif /* CELL_SCREEN_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index 0edefa5f05..e6398a85fa 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -83,18 +83,29 @@ static struct pipe_texture * cell_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) { + return pipe->screen->texture_create(pipe->screen, templat); + +} + +static struct pipe_texture * +cell_texture_create_screen(struct pipe_screen *screen, + const struct pipe_texture *templat) +{ + struct pipe_winsys *ws = screen->winsys; struct cell_texture *spt = CALLOC_STRUCT(cell_texture); if (!spt) return NULL; spt->base = *templat; spt->base.refcount = 1; + spt->base.pipe = NULL; + spt->base.screen = screen; cell_texture_layout(spt); - spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32, - PIPE_BUFFER_USAGE_PIXEL, - spt->buffer_size); + spt->buffer = ws->buffer_create(ws, 32, + PIPE_BUFFER_USAGE_PIXEL, + spt->buffer_size); if (!spt->buffer) { FREE(spt); @@ -107,6 +118,14 @@ cell_texture_create(struct pipe_context *pipe, static void cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + return pipe->screen->texture_release(pipe->screen, pt); +} + + +static void +cell_texture_release_screen(struct pipe_screen *screen, + struct pipe_texture **pt) { if (!*pt) return; @@ -122,7 +141,7 @@ cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); */ - pipe_buffer_reference(pipe->winsys, &spt->buffer, NULL); + pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); FREE(spt); } @@ -146,14 +165,24 @@ cell_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) { + return pipe->screen->get_tex_surface(pipe->screen, pt, face, level, zslice); +} + + +static struct pipe_surface * +cell_get_tex_surface_screen(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = screen->winsys; struct cell_texture *spt = cell_texture(pt); struct pipe_surface *ps; - ps = pipe->winsys->surface_alloc(pipe->winsys); + ps = ws->surface_alloc(ws); if (ps) { assert(ps->refcount); assert(ps->winsys); - pipe_buffer_reference(pipe->winsys, &ps->buffer, spt->buffer); + pipe_buffer_reference(ws, &ps->buffer, spt->buffer); ps->format = pt->format; ps->cpp = pt->cpp; ps->width = pt->width[level]; @@ -270,3 +299,11 @@ cell_init_texture_functions(struct cell_context *cell) cell->pipe.texture_update = cell_texture_update; cell->pipe.get_tex_surface = cell_get_tex_surface; } + +void +cell_init_screen_texture_funcs(struct pipe_screen *screen) +{ + screen->texture_create = cell_texture_create_screen; + screen->texture_release = cell_texture_release_screen; + screen->get_tex_surface = cell_get_tex_surface_screen; +} diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h index 824fb3e20f..fcee069d05 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.h +++ b/src/gallium/drivers/cell/ppu/cell_texture.h @@ -68,4 +68,8 @@ extern void cell_init_texture_functions(struct cell_context *cell); +extern void +cell_init_screen_texture_funcs(struct pipe_screen *screen); + + #endif /* CELL_TEXTURE_H */ diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index adebe4020a..018cf01cd6 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -36,6 +36,8 @@ #include "glxheader.h" #include "xmesaP.h" +#undef ASSERT + #include "pipe/p_winsys.h" #include "pipe/p_format.h" #include "pipe/p_context.h" @@ -45,6 +47,7 @@ #ifdef GALLIUM_CELL #include "cell/ppu/cell_context.h" +#include "cell/ppu/cell_screen.h" #include "cell/ppu/cell_winsys.h" #else #define TILE_SIZE 32 /* avoid compilation errors */ @@ -448,7 +451,8 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) #ifdef GALLIUM_CELL if (!getenv("GALLIUM_NOCELL")) { struct cell_winsys *cws = cell_get_winsys(pixelformat); - pipe = cell_create_context(pws, cws); + struct pipe_screen *screen = cell_create_screen(pws); + pipe = cell_create_context(screen, cws); if (pipe) pipe->priv = xmesa; return pipe; -- cgit v1.2.3 From 17188e4d5a3707c134fc97976863f0d8e2f1f5ab Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 10:15:37 -0700 Subject: gallium/i915: hook up screen->get_param() --- src/gallium/drivers/i915simple/i915_context.c | 55 +++-------------------- src/gallium/drivers/i915simple/i915_screen.c | 63 +++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 50 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 8478cd76a5..e89db8a130 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -36,6 +36,7 @@ #include "pipe/p_defines.h" #include "pipe/p_winsys.h" #include "pipe/p_util.h" +#include "pipe/p_screen.h" /** @@ -90,65 +91,19 @@ i915_is_format_supported( struct pipe_context *pipe, } +/* XXX temporary */ static int i915_get_param(struct pipe_context *pipe, int param) { - switch (param) { - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 8; - case PIPE_CAP_NPOT_TEXTURES: - return 1; - case PIPE_CAP_TWO_SIDED_STENCIL: - return 1; - case PIPE_CAP_GLSL: - return 0; - case PIPE_CAP_S3TC: - return 0; - case PIPE_CAP_ANISOTROPIC_FILTER: - return 0; - case PIPE_CAP_POINT_SPRITE: - return 0; - case PIPE_CAP_MAX_RENDER_TARGETS: - return 1; - case PIPE_CAP_OCCLUSION_QUERY: - return 0; - case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 1; - case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - return 11; /* max 1024x1024 */ - case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - return 8; /* max 128x128x128 */ - case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - return 11; /* max 1024x1024 */ - default: - return 0; - } + return pipe->screen->get_param(pipe->screen, param); } +/* XXX temporary */ static float i915_get_paramf(struct pipe_context *pipe, int param) { - switch (param) { - case PIPE_CAP_MAX_LINE_WIDTH: - /* fall-through */ - case PIPE_CAP_MAX_LINE_WIDTH_AA: - return 7.5; - - case PIPE_CAP_MAX_POINT_WIDTH: - /* fall-through */ - case PIPE_CAP_MAX_POINT_WIDTH_AA: - return 255.0; - - case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return 4.0; - - case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: - return 16.0; - - default: - return 0; - } + return pipe->screen->get_paramf(pipe->screen, param); } diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index f44ff43c99..b9b4d6b6fa 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -83,6 +83,67 @@ i915_get_name( struct pipe_screen *pscreen ) } +static int +i915_get_param(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 8; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 0; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 0; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 11; /* max 1024x1024 */ + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 8; /* max 128x128x128 */ + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 11; /* max 1024x1024 */ + default: + return 0; + } +} + + +static float +i915_get_paramf(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 7.5; + + case PIPE_CAP_MAX_POINT_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 255.0; + + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 4.0; + + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0; + + default: + return 0; + } +} + static void i915_destroy_screen( struct pipe_screen *screen ) @@ -132,6 +193,8 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id) i915screen->screen.get_name = i915_get_name; i915screen->screen.get_vendor = i915_get_vendor; + i915screen->screen.get_param = i915_get_param; + i915screen->screen.get_paramf = i915_get_paramf; i915_init_screen_texture_functions(&i915screen->screen); -- cgit v1.2.3 From 03b5267f52d440b1b357918ed7de2ca948f314e1 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 10:17:57 -0700 Subject: gallium/i965: implement pipe_screen for i965 driver (untested) --- src/gallium/drivers/i965simple/Makefile | 1 + src/gallium/drivers/i965simple/brw_context.c | 70 ++-------- src/gallium/drivers/i965simple/brw_screen.c | 168 ++++++++++++++++++++++++ src/gallium/drivers/i965simple/brw_screen.h | 68 ++++++++++ src/gallium/drivers/i965simple/brw_strings.c | 29 +--- src/gallium/drivers/i965simple/brw_tex_layout.c | 58 ++++++-- src/gallium/drivers/i965simple/brw_tex_layout.h | 32 +++++ src/gallium/drivers/i965simple/brw_winsys.h | 4 +- src/gallium/winsys/xlib/xm_winsys_aub.c | 4 +- 9 files changed, 338 insertions(+), 96 deletions(-) create mode 100644 src/gallium/drivers/i965simple/brw_screen.c create mode 100644 src/gallium/drivers/i965simple/brw_screen.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/Makefile b/src/gallium/drivers/i965simple/Makefile index cc8580836c..7b0df0f850 100644 --- a/src/gallium/drivers/i965simple/Makefile +++ b/src/gallium/drivers/i965simple/Makefile @@ -6,6 +6,7 @@ LIBNAME = i965simple C_SOURCES = \ brw_blit.c \ brw_flush.c \ + brw_screen.c \ brw_strings.c \ brw_surface.c \ brw_cc.c \ diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index 6fb840708e..d90b32d4b4 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -40,15 +40,14 @@ #include "pipe/p_winsys.h" #include "pipe/p_context.h" #include "pipe/p_util.h" +#include "pipe/p_screen.h" -/*************************************** - * Mesa's Driver Functions - ***************************************/ #ifndef BRW_DEBUG int BRW_DEBUG = (0); #endif + static void brw_destroy(struct pipe_context *pipe) { struct brw_context *brw = brw_context(pipe); @@ -56,6 +55,7 @@ static void brw_destroy(struct pipe_context *pipe) FREE(brw); } + static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps, unsigned clearValue) { @@ -74,64 +74,17 @@ static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps, static int brw_get_param(struct pipe_context *pipe, int param) { - switch (param) { - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 8; - case PIPE_CAP_NPOT_TEXTURES: - return 1; - case PIPE_CAP_TWO_SIDED_STENCIL: - return 1; - case PIPE_CAP_GLSL: - return 0; - case PIPE_CAP_S3TC: - return 0; - case PIPE_CAP_ANISOTROPIC_FILTER: - return 0; - case PIPE_CAP_POINT_SPRITE: - return 0; - case PIPE_CAP_MAX_RENDER_TARGETS: - return 1; - case PIPE_CAP_OCCLUSION_QUERY: - return 0; - case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 1; - case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - return 11; /* max 1024x1024 */ - case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - return 8; /* max 128x128x128 */ - case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - return 11; /* max 1024x1024 */ - default: - return 0; - } + return pipe->screen->get_param(pipe->screen, param); } static float brw_get_paramf(struct pipe_context *pipe, int param) { - switch (param) { - case PIPE_CAP_MAX_LINE_WIDTH: - /* fall-through */ - case PIPE_CAP_MAX_LINE_WIDTH_AA: - return 7.5; - - case PIPE_CAP_MAX_POINT_WIDTH: - /* fall-through */ - case PIPE_CAP_MAX_POINT_WIDTH_AA: - return 255.0; - - case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return 4.0; - - case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: - return 16.0; - - default: - return 0; - } + return pipe->screen->get_paramf(pipe->screen, param); } + static boolean brw_is_format_supported( struct pipe_context *pipe, enum pipe_format format, uint type ) @@ -200,22 +153,23 @@ brw_is_format_supported( struct pipe_context *pipe, -struct pipe_context *brw_create(struct pipe_winsys *pipe_winsys, +struct pipe_context *brw_create(struct pipe_screen *screen, struct brw_winsys *brw_winsys, unsigned pci_id) { struct brw_context *brw; - pipe_winsys->printf(pipe_winsys, - "%s: creating brw_context with pci id 0x%x\n", - __FUNCTION__, pci_id); + screen->winsys->printf(screen->winsys, + "%s: creating brw_context with pci id 0x%x\n", + __FUNCTION__, pci_id); brw = CALLOC_STRUCT(brw_context); if (brw == NULL) return NULL; brw->winsys = brw_winsys; - brw->pipe.winsys = pipe_winsys; + brw->pipe.winsys = screen->winsys; + brw->pipe.screen = screen; brw->pipe.destroy = brw_destroy; brw->pipe.is_format_supported = brw_is_format_supported; diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c new file mode 100644 index 0000000000..7afe070bd8 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_screen.c @@ -0,0 +1,168 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" + +#include "brw_context.h" +#include "brw_screen.h" +#include "brw_tex_layout.h" + + +static const char * +brw_get_vendor( struct pipe_screen *screen ) +{ + return "Tungsten Graphics, Inc."; +} + + +static const char * +brw_get_name( struct pipe_screen *screen ) +{ + static char buffer[128]; + const char *chipset; + + switch (brw_screen(screen)->pci_id) { + case PCI_CHIP_I965_Q: + chipset = "Intel(R) 965Q"; + break; + case PCI_CHIP_I965_G: + case PCI_CHIP_I965_G_1: + chipset = "Intel(R) 965G"; + break; + case PCI_CHIP_I965_GM: + chipset = "Intel(R) 965GM"; + break; + case PCI_CHIP_I965_GME: + chipset = "Intel(R) 965GME/GLE"; + break; + default: + chipset = "unknown"; + break; + } + + sprintf(buffer, "i965 (chipset: %s)", chipset); + return buffer; +} + + +static int +brw_get_param(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 8; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 0; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 0; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 11; /* max 1024x1024 */ + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 8; /* max 128x128x128 */ + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 11; /* max 1024x1024 */ + default: + return 0; + } +} + + +static float +brw_get_paramf(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 7.5; + + case PIPE_CAP_MAX_POINT_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 255.0; + + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 4.0; + + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0; + + default: + return 0; + } +} + + +static void +brw_destroy_screen( struct pipe_screen *screen ) +{ + FREE(screen); +} + + +/** + * Create a new brw_screen object + */ +struct pipe_screen * +brw_create_screen(struct pipe_winsys *winsys, uint pci_id) +{ + struct brw_screen *brwscreen = CALLOC_STRUCT(brw_screen); + + if (!brwscreen) + return NULL; + + brwscreen->pci_id = pci_id; + + brwscreen->screen.winsys = winsys; + + brwscreen->screen.destroy = brw_destroy_screen; + + brwscreen->screen.get_name = brw_get_name; + brwscreen->screen.get_vendor = brw_get_vendor; + brwscreen->screen.get_param = brw_get_param; + brwscreen->screen.get_paramf = brw_get_paramf; + + brw_init_screen_texture_funcs(&brwscreen->screen); + + return &brwscreen->screen; +} diff --git a/src/gallium/drivers/i965simple/brw_screen.h b/src/gallium/drivers/i965simple/brw_screen.h new file mode 100644 index 0000000000..d3c70387e6 --- /dev/null +++ b/src/gallium/drivers/i965simple/brw_screen.h @@ -0,0 +1,68 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef BRW_SCREEN_H +#define BRW_SCREEN_H + + +#include "pipe/p_screen.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Subclass of pipe_screen + */ +struct brw_screen +{ + struct pipe_screen screen; + + uint pci_id; +}; + + +/** cast wrapper */ +static INLINE struct brw_screen * +brw_screen(struct pipe_screen *pscreen) +{ + return (struct brw_screen *) pscreen; +} + + +extern struct pipe_screen * +brw_create_screen(struct pipe_winsys *winsys, uint pci_id); + + +#ifdef __cplusplus +} +#endif + +#endif /* BRW_SCREEN_H */ diff --git a/src/gallium/drivers/i965simple/brw_strings.c b/src/gallium/drivers/i965simple/brw_strings.c index 3d9c50961f..a8f2ce582a 100644 --- a/src/gallium/drivers/i965simple/brw_strings.c +++ b/src/gallium/drivers/i965simple/brw_strings.c @@ -28,39 +28,18 @@ #include "brw_context.h" #include "brw_reg.h" +#include "pipe/p_screen.h" + static const char *brw_get_vendor( struct pipe_context *pipe ) { - return "Tungsten Graphics, Inc."; + return pipe->screen->get_vendor(pipe->screen); } static const char *brw_get_name( struct pipe_context *pipe ) { - static char buffer[128]; - const char *chipset; - - switch (brw_context(pipe)->pci_id) { - case PCI_CHIP_I965_Q: - chipset = "Intel(R) 965Q"; - break; - case PCI_CHIP_I965_G: - case PCI_CHIP_I965_G_1: - chipset = "Intel(R) 965G"; - break; - case PCI_CHIP_I965_GM: - chipset = "Intel(R) 965GM"; - break; - case PCI_CHIP_I965_GME: - chipset = "Intel(R) 965GME/GLE"; - break; - default: - chipset = "unknown"; - break; - } - - sprintf(buffer, "i965 (chipset: %s)", chipset); - return buffer; + return pipe->screen->get_name(pipe->screen); } diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 86ce3d0cc3..9753c50143 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -71,8 +71,6 @@ static unsigned minify( unsigned d ) } -static boolean brw_miptree_layout(struct pipe_context *, struct brw_texture *); - static void intel_miptree_set_image_offset(struct brw_texture *tex, unsigned level, unsigned img, @@ -199,7 +197,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex) } } -static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture *tex) +static boolean brw_miptree_layout(struct brw_texture *tex) { struct pipe_texture *pt = &tex->base; /* XXX: these vary depending on image format: @@ -304,17 +302,26 @@ static struct pipe_texture * brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) { + return pipe->screen->texture_create(pipe->screen, templat); +} + + +static struct pipe_texture * +brw_texture_create_screen(struct pipe_screen *screen, + const struct pipe_texture *templat) +{ + struct pipe_winsys *ws = screen->winsys; struct brw_texture *tex = CALLOC_STRUCT(brw_texture); if (tex) { tex->base = *templat; tex->base.refcount = 1; - if (brw_miptree_layout(pipe, tex)) - tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64, - PIPE_BUFFER_USAGE_PIXEL, - tex->pitch * tex->base.cpp * - tex->total_height); + if (brw_miptree_layout(tex)) + tex->buffer = ws->buffer_create(ws, 64, + PIPE_BUFFER_USAGE_PIXEL, + tex->pitch * tex->base.cpp * + tex->total_height); if (!tex->buffer) { FREE(tex); @@ -328,6 +335,14 @@ brw_texture_create(struct pipe_context *pipe, static void brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + pipe->screen->texture_release(pipe->screen, pt); +} + + +static void +brw_texture_release_screen(struct pipe_screen *screen, + struct pipe_texture **pt) { if (!*pt) return; @@ -337,6 +352,7 @@ brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); */ if (--(*pt)->refcount <= 0) { + struct pipe_winsys *ws = screen->winsys; struct brw_texture *tex = (struct brw_texture *)*pt; uint i; @@ -344,7 +360,7 @@ brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); */ - pipe_buffer_reference(pipe->winsys, &tex->buffer, NULL); + pipe_buffer_reference(ws, &tex->buffer, NULL); for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++) if (tex->image_offset[i]) @@ -371,6 +387,16 @@ brw_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) { + return pipe->screen->get_tex_surface(pipe->screen, pt, face, level, zslice); +} + + +static struct pipe_surface * +brw_get_tex_surface_screen(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = screen->winsys; struct brw_texture *tex = (struct brw_texture *)pt; struct pipe_surface *ps; unsigned offset; /* in bytes */ @@ -388,11 +414,11 @@ brw_get_tex_surface(struct pipe_context *pipe, assert(zslice == 0); } - ps = pipe->winsys->surface_alloc(pipe->winsys); + ps = ws->surface_alloc(ws); if (ps) { assert(ps->format); assert(ps->refcount); - pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); + pipe_buffer_reference(ws, &ps->buffer, tex->buffer); ps->format = pt->format; ps->cpp = pt->cpp; ps->width = pt->width[level]; @@ -412,3 +438,13 @@ brw_init_texture_functions(struct brw_context *brw) brw->pipe.texture_update = brw_texture_update; brw->pipe.get_tex_surface = brw_get_tex_surface; } + + +void +brw_init_screen_texture_funcs(struct pipe_screen *screen) +{ + screen->texture_create = brw_texture_create_screen; + screen->texture_release = brw_texture_release_screen; + screen->get_tex_surface = brw_get_tex_surface_screen; +} + diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.h b/src/gallium/drivers/i965simple/brw_tex_layout.h index ed49baeef8..a6b6ba8146 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.h +++ b/src/gallium/drivers/i965simple/brw_tex_layout.h @@ -1,12 +1,44 @@ +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + + #ifndef BRW_TEX_LAYOUT_H #define BRW_TEX_LAYOUT_H struct brw_context; +struct pipe_screen; extern void brw_init_texture_functions(struct brw_context *brw); +extern void +brw_init_screen_texture_funcs(struct pipe_screen *screen); + #endif diff --git a/src/gallium/drivers/i965simple/brw_winsys.h b/src/gallium/drivers/i965simple/brw_winsys.h index 3523a58614..b67bd73750 100644 --- a/src/gallium/drivers/i965simple/brw_winsys.h +++ b/src/gallium/drivers/i965simple/brw_winsys.h @@ -53,6 +53,8 @@ struct pipe_buffer; struct pipe_fence_handle; struct pipe_winsys; +struct pipe_screen; + /* The pipe driver currently understands the following chipsets: */ @@ -181,7 +183,7 @@ struct brw_winsys { #define BRW_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0) -struct pipe_context *brw_create(struct pipe_winsys *, +struct pipe_context *brw_create(struct pipe_screen *, struct brw_winsys *, unsigned pci_id); diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index dbfd37bda2..d55d8c39eb 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -40,6 +40,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "i965simple/brw_winsys.h" +#include "i965simple/brw_screen.h" #include "brw_aub.h" #include "xm_winsys_aub.h" @@ -565,6 +566,7 @@ struct pipe_context * xmesa_create_i965simple( struct pipe_winsys *winsys ) { struct aub_brw_winsys *iws = CALLOC_STRUCT( aub_brw_winsys ); + struct pipe_screen *screen = brw_create_screen(winsys, 0/* XXX pci_id */); /* Fill in this struct with callbacks that i965simple will need to * communicate with the window system, buffer manager, etc. @@ -583,7 +585,7 @@ xmesa_create_i965simple( struct pipe_winsys *winsys ) /* Create the i965simple context: */ - return brw_create( winsys, + return brw_create( screen, &iws->winsys, 0 ); } -- cgit v1.2.3 From 8383f798b41df9a305e0a33afe8afa028d5d5dfb Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 11:24:35 -0700 Subject: gallium: start removing pipe_context->get_name/vendor/param/paramf These are now per-screen functions, not per-context. State tracker updated, code in drivers and p_context.h disabled. --- src/gallium/drivers/cell/ppu/cell_context.c | 29 --------------------------- src/gallium/drivers/failover/fo_context.c | 3 +++ src/gallium/drivers/i915simple/Makefile | 1 - src/gallium/drivers/i915simple/SConscript | 1 - src/gallium/drivers/i915simple/i915_context.c | 24 ---------------------- src/gallium/drivers/i965simple/Makefile | 1 - src/gallium/drivers/i965simple/SConscript | 1 - src/gallium/drivers/i965simple/brw_context.c | 17 ---------------- src/gallium/drivers/softpipe/sp_context.c | 25 ----------------------- src/gallium/include/pipe/p_context.h | 3 +++ 10 files changed, 6 insertions(+), 99 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index bb1838409f..351601473d 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -77,30 +77,6 @@ cell_is_format_supported( struct pipe_context *pipe, } -static int cell_get_param(struct pipe_context *pipe, int param) -{ - return pipe->screen->get_param(pipe->screen, param); -} - -static float cell_get_paramf(struct pipe_context *pipe, int param) -{ - return pipe->screen->get_paramf(pipe->screen, param); -} - -static const char * -cell_get_name( struct pipe_context *pipe ) -{ - return pipe->screen->get_name(pipe->screen); -} - -static const char * -cell_get_vendor( struct pipe_context *pipe ) -{ - return pipe->screen->get_vendor(pipe->screen); -} - - - static void cell_destroy_context( struct pipe_context *pipe ) { @@ -148,11 +124,6 @@ cell_create_context(struct pipe_screen *screen, /* queries */ cell->pipe.is_format_supported = cell_is_format_supported; - cell->pipe.get_name = cell_get_name; - cell->pipe.get_vendor = cell_get_vendor; - cell->pipe.get_param = cell_get_param; - cell->pipe.get_paramf = cell_get_paramf; - /* state setters */ cell->pipe.set_vertex_buffer = cell_set_vertex_buffer; diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index 156f7399b0..d5e54f5d61 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -117,12 +117,15 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover->hw = hw; failover->sw = sw; failover->pipe.winsys = hw->winsys; + failover->pipe.screen = hw->screen; failover->pipe.destroy = failover_destroy; failover->pipe.is_format_supported = hw->is_format_supported; +#if 0 failover->pipe.get_name = hw->get_name; failover->pipe.get_vendor = hw->get_vendor; failover->pipe.get_param = hw->get_param; failover->pipe.get_paramf = hw->get_paramf; +#endif failover->pipe.draw_arrays = failover_draw_arrays; failover->pipe.draw_elements = failover_draw_elements; diff --git a/src/gallium/drivers/i915simple/Makefile b/src/gallium/drivers/i915simple/Makefile index 3400747a73..41a61a0020 100644 --- a/src/gallium/drivers/i915simple/Makefile +++ b/src/gallium/drivers/i915simple/Makefile @@ -18,7 +18,6 @@ C_SOURCES = \ i915_state_emit.c \ i915_state_sampler.c \ i915_screen.c \ - i915_strings.c \ i915_prim_emit.c \ i915_prim_vbuf.c \ i915_texture.c \ diff --git a/src/gallium/drivers/i915simple/SConscript b/src/gallium/drivers/i915simple/SConscript index 3e1beaea6d..2366e1247f 100644 --- a/src/gallium/drivers/i915simple/SConscript +++ b/src/gallium/drivers/i915simple/SConscript @@ -22,7 +22,6 @@ i915simple = env.ConvenienceLibrary( 'i915_state_emit.c', 'i915_state_immediate.c', 'i915_state_sampler.c', - 'i915_strings.c', 'i915_surface.c', 'i915_texture.c', ]) diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index e89db8a130..42355552de 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -91,22 +91,6 @@ i915_is_format_supported( struct pipe_context *pipe, } -/* XXX temporary */ -static int -i915_get_param(struct pipe_context *pipe, int param) -{ - return pipe->screen->get_param(pipe->screen, param); -} - - -/* XXX temporary */ -static float -i915_get_paramf(struct pipe_context *pipe, int param) -{ - return pipe->screen->get_paramf(pipe->screen, param); -} - - static void i915_destroy( struct pipe_context *pipe ) { struct i915_context *i915 = i915_context( pipe ); @@ -205,8 +189,6 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen, i915->pipe.destroy = i915_destroy; i915->pipe.is_format_supported = i915_is_format_supported; - i915->pipe.get_param = i915_get_param; - i915->pipe.get_paramf = i915_get_paramf; i915->pipe.clear = i915_clear; @@ -229,7 +211,6 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen, i915_init_surface_functions(i915); i915_init_state_functions(i915); i915_init_flush_functions(i915); - i915_init_string_functions(i915); i915_init_texture_functions(i915); draw_install_aaline_stage(i915->draw, &i915->pipe); @@ -242,11 +223,6 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen, */ i915->batch_start = NULL; - /* - * XXX we could plug GL selection/feedback into the drawing pipeline - * by specifying a different setup/render stage. - */ - return &i915->pipe; } diff --git a/src/gallium/drivers/i965simple/Makefile b/src/gallium/drivers/i965simple/Makefile index 7b0df0f850..8589ebdf96 100644 --- a/src/gallium/drivers/i965simple/Makefile +++ b/src/gallium/drivers/i965simple/Makefile @@ -7,7 +7,6 @@ C_SOURCES = \ brw_blit.c \ brw_flush.c \ brw_screen.c \ - brw_strings.c \ brw_surface.c \ brw_cc.c \ brw_clip.c \ diff --git a/src/gallium/drivers/i965simple/SConscript b/src/gallium/drivers/i965simple/SConscript index 74621de84c..e0cc78826e 100644 --- a/src/gallium/drivers/i965simple/SConscript +++ b/src/gallium/drivers/i965simple/SConscript @@ -35,7 +35,6 @@ i965simple = env.ConvenienceLibrary( 'brw_state_cache.c', 'brw_state_pool.c', 'brw_state_upload.c', - 'brw_strings.c', 'brw_surface.c', 'brw_tex_layout.c', 'brw_urb.c', diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index d90b32d4b4..e0a4037286 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -71,20 +71,6 @@ static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps, } -static int -brw_get_param(struct pipe_context *pipe, int param) -{ - return pipe->screen->get_param(pipe->screen, param); -} - - -static float -brw_get_paramf(struct pipe_context *pipe, int param) -{ - return pipe->screen->get_paramf(pipe->screen, param); -} - - static boolean brw_is_format_supported( struct pipe_context *pipe, enum pipe_format format, uint type ) @@ -173,15 +159,12 @@ struct pipe_context *brw_create(struct pipe_screen *screen, brw->pipe.destroy = brw_destroy; brw->pipe.is_format_supported = brw_is_format_supported; - brw->pipe.get_param = brw_get_param; - brw->pipe.get_paramf = brw_get_paramf; brw->pipe.clear = brw_clear; brw_init_surface_functions(brw); brw_init_texture_functions(brw); brw_init_state_functions(brw); brw_init_flush_functions(brw); - brw_init_string_functions(brw); brw_init_draw_functions( brw ); diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 4ac1719cbb..6a88c277aa 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -143,27 +143,6 @@ static void softpipe_destroy( struct pipe_context *pipe ) } -/* XXX these will go away shortly */ -static const char *softpipe_get_name( struct pipe_context *pipe ) -{ - return pipe->screen->get_name(pipe->screen); -} - -static const char *softpipe_get_vendor( struct pipe_context *pipe ) -{ - return pipe->screen->get_vendor(pipe->screen); -} - -static int softpipe_get_param(struct pipe_context *pipe, int param) -{ - return pipe->screen->get_param(pipe->screen, param); -} - -static float softpipe_get_paramf(struct pipe_context *pipe, int param) -{ - return pipe->screen->get_paramf(pipe->screen, param); -} - struct pipe_context * softpipe_create( struct pipe_screen *screen, struct pipe_winsys *pipe_winsys, @@ -186,10 +165,6 @@ softpipe_create( struct pipe_screen *screen, /* queries */ softpipe->pipe.is_format_supported = softpipe_is_format_supported; - softpipe->pipe.get_name = softpipe_get_name; - softpipe->pipe.get_vendor = softpipe_get_vendor; - softpipe->pipe.get_param = softpipe_get_param; - softpipe->pipe.get_paramf = softpipe_get_paramf; /* state setters */ softpipe->pipe.create_blend_state = softpipe_create_blend_state; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 93fcb1c3e9..38ee95bdad 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -66,12 +66,15 @@ struct pipe_context { boolean (*is_format_supported)( struct pipe_context *pipe, enum pipe_format format, uint type ); +#if 0 + /* XXX obsolete, moved into pipe_screen */ const char *(*get_name)( struct pipe_context *pipe ); const char *(*get_vendor)( struct pipe_context *pipe ); int (*get_param)( struct pipe_context *pipe, int param ); float (*get_paramf)( struct pipe_context *pipe, int param ); +#endif /* -- cgit v1.2.3 From 364f8cad0f8f02fd39d9c51ea0774d349121b58d Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 13:58:06 -0700 Subject: gallium: move is_format_supported() to pipe_screen struct --- src/gallium/drivers/cell/ppu/cell_context.c | 23 --------- src/gallium/drivers/cell/ppu/cell_screen.c | 19 ++++++++ src/gallium/drivers/failover/fo_context.c | 2 +- src/gallium/drivers/i915simple/i915_context.c | 55 --------------------- src/gallium/drivers/i915simple/i915_screen.c | 48 +++++++++++++++++++ src/gallium/drivers/i965simple/brw_context.c | 69 --------------------------- src/gallium/drivers/i965simple/brw_screen.c | 67 ++++++++++++++++++++++++++ src/gallium/drivers/softpipe/sp_context.c | 26 ---------- src/gallium/drivers/softpipe/sp_screen.c | 24 ++++++++++ src/gallium/include/pipe/p_context.h | 19 +------- 10 files changed, 160 insertions(+), 192 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index 351601473d..2301df5ba5 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -57,26 +57,6 @@ -static boolean -cell_is_format_supported( struct pipe_context *pipe, - enum pipe_format format, uint type ) -{ - /*struct cell_context *cell = cell_context( pipe );*/ - - switch (type) { - case PIPE_TEXTURE: - /* cell supports all texture formats, XXX for now anyway */ - return TRUE; - case PIPE_SURFACE: - /* cell supports all (off-screen) surface formats, XXX for now */ - return TRUE; - default: - assert(0); - return FALSE; - } -} - - static void cell_destroy_context( struct pipe_context *pipe ) { @@ -122,9 +102,6 @@ cell_create_context(struct pipe_screen *screen, cell->pipe.screen = screen; cell->pipe.destroy = cell_destroy_context; - /* queries */ - cell->pipe.is_format_supported = cell_is_format_supported; - /* state setters */ cell->pipe.set_vertex_buffer = cell_set_vertex_buffer; cell->pipe.set_vertex_element = cell_set_vertex_element; diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 75255c0466..124670df25 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -112,6 +112,24 @@ cell_get_paramf(struct pipe_screen *screen, int param) } +static boolean +cell_is_format_supported( struct pipe_screen *screen, + enum pipe_format format, uint type ) +{ + switch (type) { + case PIPE_TEXTURE: + /* cell supports all texture formats, XXX for now anyway */ + return TRUE; + case PIPE_SURFACE: + /* cell supports all (off-screen) surface formats, XXX for now */ + return TRUE; + default: + assert(0); + return FALSE; + } +} + + static void cell_destroy_screen( struct pipe_screen *screen ) { @@ -140,6 +158,7 @@ cell_create_screen(struct pipe_winsys *winsys) screen->get_vendor = cell_get_vendor; screen->get_param = cell_get_param; screen->get_paramf = cell_get_paramf; + screen->is_format_supported = cell_is_format_supported; cell_init_screen_texture_funcs(screen); diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index d5e54f5d61..f559cc0d47 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -119,8 +119,8 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover->pipe.winsys = hw->winsys; failover->pipe.screen = hw->screen; failover->pipe.destroy = failover_destroy; - failover->pipe.is_format_supported = hw->is_format_supported; #if 0 + failover->pipe.is_format_supported = hw->is_format_supported; failover->pipe.get_name = hw->get_name; failover->pipe.get_vendor = hw->get_vendor; failover->pipe.get_param = hw->get_param; diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 42355552de..15ff2360b7 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -39,58 +39,6 @@ #include "pipe/p_screen.h" -/** - * Query format support for creating a texture, drawing surface, etc. - * \param format the format to test - * \param type one of PIPE_TEXTURE, PIPE_SURFACE - */ -static boolean -i915_is_format_supported( struct pipe_context *pipe, - enum pipe_format format, uint type ) -{ - static const enum pipe_format tex_supported[] = { - PIPE_FORMAT_R8G8B8A8_UNORM, - PIPE_FORMAT_A8R8G8B8_UNORM, - PIPE_FORMAT_R5G6B5_UNORM, - PIPE_FORMAT_U_L8, - PIPE_FORMAT_U_A8, - PIPE_FORMAT_U_I8, - PIPE_FORMAT_U_A8_L8, - PIPE_FORMAT_YCBCR, - PIPE_FORMAT_YCBCR_REV, - PIPE_FORMAT_S8Z24_UNORM, - PIPE_FORMAT_NONE /* list terminator */ - }; - static const enum pipe_format surface_supported[] = { - PIPE_FORMAT_A8R8G8B8_UNORM, - PIPE_FORMAT_R5G6B5_UNORM, - PIPE_FORMAT_S8Z24_UNORM, - /*PIPE_FORMAT_R16G16B16A16_SNORM,*/ - PIPE_FORMAT_NONE /* list terminator */ - }; - const enum pipe_format *list; - uint i; - - switch (type) { - case PIPE_TEXTURE: - list = tex_supported; - break; - case PIPE_SURFACE: - list = surface_supported; - break; - default: - assert(0); - } - - for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { - if (list[i] == format) - return TRUE; - } - - return FALSE; -} - - static void i915_destroy( struct pipe_context *pipe ) { struct i915_context *i915 = i915_context( pipe ); @@ -101,8 +49,6 @@ static void i915_destroy( struct pipe_context *pipe ) } - - static boolean i915_draw_elements( struct pipe_context *pipe, struct pipe_buffer *indexBuffer, @@ -188,7 +134,6 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen, i915->pipe.screen = screen; i915->pipe.destroy = i915_destroy; - i915->pipe.is_format_supported = i915_is_format_supported; i915->pipe.clear = i915_clear; diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index b9b4d6b6fa..8d7bf0b33e 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -145,6 +145,53 @@ i915_get_paramf(struct pipe_screen *screen, int param) } +static boolean +i915_is_format_supported( struct pipe_screen *screen, + enum pipe_format format, uint type ) +{ + static const enum pipe_format tex_supported[] = { + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_U_L8, + PIPE_FORMAT_U_A8, + PIPE_FORMAT_U_I8, + PIPE_FORMAT_U_A8_L8, + PIPE_FORMAT_YCBCR, + PIPE_FORMAT_YCBCR_REV, + PIPE_FORMAT_S8Z24_UNORM, + PIPE_FORMAT_NONE /* list terminator */ + }; + static const enum pipe_format surface_supported[] = { + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_S8Z24_UNORM, + /*PIPE_FORMAT_R16G16B16A16_SNORM,*/ + PIPE_FORMAT_NONE /* list terminator */ + }; + const enum pipe_format *list; + uint i; + + switch (type) { + case PIPE_TEXTURE: + list = tex_supported; + break; + case PIPE_SURFACE: + list = surface_supported; + break; + default: + assert(0); + } + + for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { + if (list[i] == format) + return TRUE; + } + + return FALSE; +} + + static void i915_destroy_screen( struct pipe_screen *screen ) { @@ -195,6 +242,7 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id) i915screen->screen.get_vendor = i915_get_vendor; i915screen->screen.get_param = i915_get_param; i915screen->screen.get_paramf = i915_get_paramf; + i915screen->screen.is_format_supported = i915_is_format_supported; i915_init_screen_texture_functions(&i915screen->screen); diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index e0a4037286..7c908da672 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -71,74 +71,6 @@ static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps, } -static boolean -brw_is_format_supported( struct pipe_context *pipe, - enum pipe_format format, uint type ) -{ -#if 0 - /* XXX: This is broken -- rewrite if still needed. */ - static const unsigned tex_supported[] = { - PIPE_FORMAT_U_R8_G8_B8_A8, - PIPE_FORMAT_U_A8_R8_G8_B8, - PIPE_FORMAT_U_R5_G6_B5, - PIPE_FORMAT_U_L8, - PIPE_FORMAT_U_A8, - PIPE_FORMAT_U_I8, - PIPE_FORMAT_U_L8_A8, - PIPE_FORMAT_YCBCR, - PIPE_FORMAT_YCBCR_REV, - PIPE_FORMAT_S8_Z24, - }; - - - /* Actually a lot more than this - add later: - */ - static const unsigned render_supported[] = { - PIPE_FORMAT_U_A8_R8_G8_B8, - PIPE_FORMAT_U_R5_G6_B5, - }; - - /* - */ - static const unsigned z_stencil_supported[] = { - PIPE_FORMAT_U_Z16, - PIPE_FORMAT_U_Z32, - PIPE_FORMAT_S8_Z24, - }; - - switch (type) { - case PIPE_RENDER_FORMAT: - *numFormats = Elements(render_supported); - return render_supported; - - case PIPE_TEX_FORMAT: - *numFormats = Elements(tex_supported); - return render_supported; - - case PIPE_Z_STENCIL_FORMAT: - *numFormats = Elements(render_supported); - return render_supported; - - default: - *numFormats = 0; - return NULL; - } -#else - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_S8Z24_UNORM: - return TRUE; - default: - return FALSE; - }; - return FALSE; -#endif -} - - - - struct pipe_context *brw_create(struct pipe_screen *screen, struct brw_winsys *brw_winsys, unsigned pci_id) @@ -158,7 +90,6 @@ struct pipe_context *brw_create(struct pipe_screen *screen, brw->pipe.screen = screen; brw->pipe.destroy = brw_destroy; - brw->pipe.is_format_supported = brw_is_format_supported; brw->pipe.clear = brw_clear; brw_init_surface_functions(brw); diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c index 7afe070bd8..5be369fe52 100644 --- a/src/gallium/drivers/i965simple/brw_screen.c +++ b/src/gallium/drivers/i965simple/brw_screen.c @@ -133,6 +133,72 @@ brw_get_paramf(struct pipe_screen *screen, int param) } +static boolean +brw_is_format_supported( struct pipe_screen *screen, + enum pipe_format format, uint type ) +{ +#if 0 + /* XXX: This is broken -- rewrite if still needed. */ + static const unsigned tex_supported[] = { + PIPE_FORMAT_U_R8_G8_B8_A8, + PIPE_FORMAT_U_A8_R8_G8_B8, + PIPE_FORMAT_U_R5_G6_B5, + PIPE_FORMAT_U_L8, + PIPE_FORMAT_U_A8, + PIPE_FORMAT_U_I8, + PIPE_FORMAT_U_L8_A8, + PIPE_FORMAT_YCBCR, + PIPE_FORMAT_YCBCR_REV, + PIPE_FORMAT_S8_Z24, + }; + + + /* Actually a lot more than this - add later: + */ + static const unsigned render_supported[] = { + PIPE_FORMAT_U_A8_R8_G8_B8, + PIPE_FORMAT_U_R5_G6_B5, + }; + + /* + */ + static const unsigned z_stencil_supported[] = { + PIPE_FORMAT_U_Z16, + PIPE_FORMAT_U_Z32, + PIPE_FORMAT_S8_Z24, + }; + + switch (type) { + case PIPE_RENDER_FORMAT: + *numFormats = Elements(render_supported); + return render_supported; + + case PIPE_TEX_FORMAT: + *numFormats = Elements(tex_supported); + return render_supported; + + case PIPE_Z_STENCIL_FORMAT: + *numFormats = Elements(render_supported); + return render_supported; + + default: + *numFormats = 0; + return NULL; + } +#else + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: + return TRUE; + default: + return FALSE; + }; + return FALSE; +#endif +} + + static void brw_destroy_screen( struct pipe_screen *screen ) { @@ -161,6 +227,7 @@ brw_create_screen(struct pipe_winsys *winsys, uint pci_id) brwscreen->screen.get_vendor = brw_get_vendor; brwscreen->screen.get_param = brw_get_param; brwscreen->screen.get_paramf = brw_get_paramf; + brwscreen->screen.is_format_supported = brw_is_format_supported; brw_init_screen_texture_funcs(&brwscreen->screen); diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 6a88c277aa..fa16ed94e8 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -47,29 +47,6 @@ -/** - * Query format support for creating a texture, drawing surface, etc. - * \param format the format to test - * \param type one of PIPE_TEXTURE, PIPE_SURFACE - */ -static boolean -softpipe_is_format_supported( struct pipe_context *pipe, - enum pipe_format format, uint type ) -{ - switch (type) { - case PIPE_TEXTURE: - /* softpipe supports all texture formats */ - return TRUE; - case PIPE_SURFACE: - /* softpipe supports all (off-screen) surface formats */ - return TRUE; - default: - assert(0); - return FALSE; - } -} - - /** * Map any drawing surfaces which aren't already mapped */ @@ -163,9 +140,6 @@ softpipe_create( struct pipe_screen *screen, softpipe->pipe.screen = screen; softpipe->pipe.destroy = softpipe_destroy; - /* queries */ - softpipe->pipe.is_format_supported = softpipe_is_format_supported; - /* state setters */ softpipe->pipe.create_blend_state = softpipe_create_blend_state; softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index cc3b962580..1850a1ced3 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -107,6 +107,29 @@ softpipe_get_paramf(struct pipe_screen *screen, int param) } +/** + * Query format support for creating a texture, drawing surface, etc. + * \param format the format to test + * \param type one of PIPE_TEXTURE, PIPE_SURFACE + */ +static boolean +softpipe_is_format_supported( struct pipe_screen *screen, + enum pipe_format format, uint type ) +{ + switch (type) { + case PIPE_TEXTURE: + /* softpipe supports all texture formats */ + return TRUE; + case PIPE_SURFACE: + /* softpipe supports all (off-screen) surface formats */ + return TRUE; + default: + assert(0); + return FALSE; + } +} + + static void softpipe_destroy_screen( struct pipe_screen *screen ) { @@ -134,6 +157,7 @@ softpipe_create_screen(struct pipe_winsys *winsys) screen->get_vendor = softpipe_get_vendor; screen->get_param = softpipe_get_param; screen->get_paramf = softpipe_get_paramf; + screen->is_format_supported = softpipe_is_format_supported; softpipe_init_screen_texture_funcs(screen); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 38ee95bdad..bb345df153 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -59,24 +59,6 @@ struct pipe_context { void (*destroy)( struct pipe_context * ); - /* - * Queries - */ - /** type is one of PIPE_SURFACE, PIPE_TEXTURE, etc. */ - boolean (*is_format_supported)( struct pipe_context *pipe, - enum pipe_format format, uint type ); - -#if 0 - /* XXX obsolete, moved into pipe_screen */ - const char *(*get_name)( struct pipe_context *pipe ); - - const char *(*get_vendor)( struct pipe_context *pipe ); - - int (*get_param)( struct pipe_context *pipe, int param ); - float (*get_paramf)( struct pipe_context *pipe, int param ); -#endif - - /* * Drawing. * Return false on fallbacks (temporary??) @@ -210,6 +192,7 @@ struct pipe_context { /* * Texture functions + * XXX these are moving to pipe_screen... */ struct pipe_texture * (*texture_create)(struct pipe_context *pipe, const struct pipe_texture *templat); -- cgit v1.2.3 From 6f715dcc219071e574e363a9db4365c9c31ebbd3 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 14:21:12 -0700 Subject: gallium: remove pipe_context->texture_create/release/get_tex_surface() These functions are now per-screen, not per-context. --- src/gallium/auxiliary/draw/draw_aaline.c | 5 ++- src/gallium/auxiliary/draw/draw_pstipple.c | 6 ++- src/gallium/drivers/cell/ppu/cell_texture.c | 30 ------------- src/gallium/drivers/failover/fo_context.c | 4 +- src/gallium/drivers/i915simple/i915_texture.c | 28 ------------ src/gallium/drivers/i965simple/brw_tex_layout.c | 30 ------------- src/gallium/drivers/softpipe/sp_texture.c | 60 ++++++------------------- src/gallium/drivers/softpipe/sp_tile_cache.c | 3 +- src/gallium/include/pipe/p_context.h | 18 +------- src/gallium/include/pipe/p_inlines.h | 18 +++----- 10 files changed, 33 insertions(+), 169 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index 73a02a32e4..be6cfd3b6a 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -362,6 +362,7 @@ static void aaline_create_texture(struct aaline_stage *aaline) { struct pipe_context *pipe = aaline->pipe; + struct pipe_screen *screen = pipe->screen; struct pipe_texture texTemp; uint level; @@ -374,7 +375,7 @@ aaline_create_texture(struct aaline_stage *aaline) texTemp.depth[0] = 1; texTemp.cpp = 1; - aaline->texture = pipe->texture_create(pipe, &texTemp); + aaline->texture = screen->texture_create(screen, &texTemp); /* Fill in mipmap images. * Basically each level is solid opaque, except for the outermost @@ -388,7 +389,7 @@ aaline_create_texture(struct aaline_stage *aaline) assert(aaline->texture->width[level] == aaline->texture->height[level]); - surface = pipe->get_tex_surface(pipe, aaline->texture, 0, level, 0); + surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0); data = pipe_surface_map(surface); for (i = 0; i < size; i++) { diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index 1ab04cd959..efc88bf038 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -348,12 +348,13 @@ pstip_update_texture(struct pstip_stage *pstip) { static const uint bit31 = 1 << 31; struct pipe_context *pipe = pstip->pipe; + struct pipe_screen *screen = pipe->screen; struct pipe_surface *surface; const uint *stipple = pstip->state.stipple->stipple; uint i, j; ubyte *data; - surface = pipe->get_tex_surface(pipe, pstip->texture, 0, 0, 0); + surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0); data = pipe_surface_map(surface); /* @@ -389,6 +390,7 @@ static void pstip_create_texture(struct pstip_stage *pstip) { struct pipe_context *pipe = pstip->pipe; + struct pipe_screen *screen = pipe->screen; struct pipe_texture texTemp; memset(&texTemp, 0, sizeof(texTemp)); @@ -400,7 +402,7 @@ pstip_create_texture(struct pstip_stage *pstip) texTemp.depth[0] = 1; texTemp.cpp = 1; - pstip->texture = pipe->texture_create(pipe, &texTemp); + pstip->texture = screen->texture_create(screen, &texTemp); //pstip_update_texture(pstip); } diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index e6398a85fa..28cadad6ed 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -79,14 +79,6 @@ cell_texture_layout(struct cell_texture * spt) } -static struct pipe_texture * -cell_texture_create(struct pipe_context *pipe, - const struct pipe_texture *templat) -{ - return pipe->screen->texture_create(pipe->screen, templat); - -} - static struct pipe_texture * cell_texture_create_screen(struct pipe_screen *screen, const struct pipe_texture *templat) @@ -116,13 +108,6 @@ cell_texture_create_screen(struct pipe_screen *screen, } -static void -cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) -{ - return pipe->screen->texture_release(pipe->screen, pt); -} - - static void cell_texture_release_screen(struct pipe_screen *screen, struct pipe_texture **pt) @@ -157,18 +142,6 @@ cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) } -/** - * Called via pipe->get_tex_surface() - */ -static struct pipe_surface * -cell_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - return pipe->screen->get_tex_surface(pipe->screen, pt, face, level, zslice); -} - - static struct pipe_surface * cell_get_tex_surface_screen(struct pipe_screen *screen, struct pipe_texture *pt, @@ -294,10 +267,7 @@ cell_update_texture_mapping(struct cell_context *cell) void cell_init_texture_functions(struct cell_context *cell) { - cell->pipe.texture_create = cell_texture_create; - cell->pipe.texture_release = cell_texture_release; cell->pipe.texture_update = cell_texture_update; - cell->pipe.get_tex_surface = cell_get_tex_surface; } void diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index f559cc0d47..afc0d7eb1e 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -143,10 +143,12 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover->pipe.surface_copy = hw->surface_copy; failover->pipe.surface_fill = hw->surface_fill; +#if 0 failover->pipe.texture_create = hw->texture_create; failover->pipe.texture_release = hw->texture_release; - failover->pipe.texture_update = hw->texture_update; failover->pipe.get_tex_surface = hw->get_tex_surface; +#endif + failover->pipe.texture_update = hw->texture_update; failover->pipe.flush = hw->flush; diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 3c9509dee3..9cdf3418a9 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -511,14 +511,6 @@ i915_texture_create_screen(struct pipe_screen *screen, } -static struct pipe_texture * -i915_texture_create(struct pipe_context *pipe, - const struct pipe_texture *templat) -{ - return pipe->screen->texture_create(pipe->screen, templat); -} - - static void i915_texture_release_screen(struct pipe_screen *screen, struct pipe_texture **pt) @@ -550,13 +542,6 @@ i915_texture_release_screen(struct pipe_screen *screen, } -static void -i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) -{ - i915_texture_release_screen(pipe->screen, pt); -} - - static void i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) { @@ -606,26 +591,13 @@ i915_get_tex_surface_screen(struct pipe_screen *screen, } -static struct pipe_surface * -i915_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - return i915_get_tex_surface_screen(pipe->screen, pt, face, level, zslice); -} - - void i915_init_texture_functions(struct i915_context *i915) { - i915->pipe.texture_create = i915_texture_create; - i915->pipe.texture_release = i915_texture_release; i915->pipe.texture_update = i915_texture_update; - i915->pipe.get_tex_surface = i915_get_tex_surface; } - void i915_init_screen_texture_functions(struct pipe_screen *screen) { diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 9753c50143..b24ac87c37 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -298,14 +298,6 @@ static boolean brw_miptree_layout(struct brw_texture *tex) } -static struct pipe_texture * -brw_texture_create(struct pipe_context *pipe, - const struct pipe_texture *templat) -{ - return pipe->screen->texture_create(pipe->screen, templat); -} - - static struct pipe_texture * brw_texture_create_screen(struct pipe_screen *screen, const struct pipe_texture *templat) @@ -333,13 +325,6 @@ brw_texture_create_screen(struct pipe_screen *screen, } -static void -brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) -{ - pipe->screen->texture_release(pipe->screen, pt); -} - - static void brw_texture_release_screen(struct pipe_screen *screen, struct pipe_texture **pt) @@ -379,18 +364,6 @@ brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) } -/* - * XXX note: same as code in sp_surface.c - */ -static struct pipe_surface * -brw_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - return pipe->screen->get_tex_surface(pipe->screen, pt, face, level, zslice); -} - - static struct pipe_surface * brw_get_tex_surface_screen(struct pipe_screen *screen, struct pipe_texture *pt, @@ -433,10 +406,7 @@ brw_get_tex_surface_screen(struct pipe_screen *screen, void brw_init_texture_functions(struct brw_context *brw) { - brw->pipe.texture_create = brw_texture_create; - brw->pipe.texture_release = brw_texture_release; brw->pipe.texture_update = brw_texture_update; - brw->pipe.get_tex_surface = brw_get_tex_surface; } diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index f0e8350a4a..7c02765313 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -80,15 +80,6 @@ softpipe_texture_layout(struct softpipe_texture * spt) } -/* XXX temporary */ -static struct pipe_texture * -softpipe_texture_create(struct pipe_context *pipe, - const struct pipe_texture *templat) -{ - return pipe->screen->texture_create(pipe->screen, templat); -} - - static struct pipe_texture * softpipe_texture_create_screen(struct pipe_screen *screen, const struct pipe_texture *templat) @@ -119,14 +110,6 @@ softpipe_texture_create_screen(struct pipe_screen *screen, } -/* XXX temporary */ -static void -softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) -{ - return pipe->screen->texture_release(pipe->screen, pt); -} - - static void softpipe_texture_release_screen(struct pipe_screen *screen, struct pipe_texture **pt) @@ -153,33 +136,6 @@ softpipe_texture_release_screen(struct pipe_screen *screen, } -static void -softpipe_texture_update(struct pipe_context *pipe, - struct pipe_texture *texture) -{ - struct softpipe_context *softpipe = softpipe_context(pipe); - uint unit; - for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { - if (softpipe->texture[unit] == texture) { - sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); - } - } -} - - -/** - * Called via pipe->get_tex_surface() - */ -/* XXX temporary */ -static struct pipe_surface * -softpipe_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - return pipe->screen->get_tex_surface(pipe->screen, pt, face, level, zslice); -} - - static struct pipe_surface * softpipe_get_tex_surface_screen(struct pipe_screen *screen, struct pipe_texture *pt, @@ -217,14 +173,24 @@ softpipe_get_tex_surface_screen(struct pipe_screen *screen, } +static void +softpipe_texture_update(struct pipe_context *pipe, + struct pipe_texture *texture) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint unit; + for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { + if (softpipe->texture[unit] == texture) { + sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); + } + } +} + void softpipe_init_texture_funcs( struct softpipe_context *softpipe ) { - softpipe->pipe.texture_create = softpipe_texture_create; - softpipe->pipe.texture_release = softpipe_texture_release; softpipe->pipe.texture_update = softpipe_texture_update; - softpipe->pipe.get_tex_surface = softpipe_get_tex_surface; } diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 0ff93c5527..4caf2dd3fc 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -489,6 +489,7 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, struct softpipe_tile_cache *tc, int x, int y, int z, int face, int level) { + struct pipe_screen *screen = pipe->screen; /* tile pos in framebuffer: */ const int tile_x = x & ~(TILE_SIZE - 1); const int tile_y = y & ~(TILE_SIZE - 1); @@ -514,7 +515,7 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, if (tc->tex_surf_map) pipe_surface_unmap(tc->tex_surf); - tc->tex_surf = pipe->get_tex_surface(pipe, tc->texture, face, level, z); + tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z); tc->tex_surf_map = pipe_surface_map(tc->tex_surf); tc->tex_face = face; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index bb345df153..d0f25d7d46 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -189,30 +189,16 @@ struct pipe_context { struct pipe_surface *ps, unsigned clearValue); - - /* - * Texture functions - * XXX these are moving to pipe_screen... - */ - struct pipe_texture * (*texture_create)(struct pipe_context *pipe, - const struct pipe_texture *templat); - - void (*texture_release)(struct pipe_context *pipe, - struct pipe_texture **pt); - /** * Called when texture data is changed. * Note: we could pass some hints about which mip levels or cube faces * have changed... + * XXX this may go away - could pass a 'write' flag to get_tex_surface() */ void (*texture_update)(struct pipe_context *pipe, struct pipe_texture *texture); - /** Get a surface which is a "view" into a texture */ - struct pipe_surface *(*get_tex_surface)(struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level, - unsigned zslice); + /* Flush rendering: */ diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index a7e97fcd7d..274f76a383 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -107,15 +107,9 @@ pipe_texture_reference(struct pipe_texture **ptr, pt->refcount++; if (*ptr) { - struct pipe_context *pipe = (*ptr)->pipe; - /* XXX temporary mess here */ - if (pipe) { - pipe->texture_release(pipe, ptr); - } - else { - struct pipe_screen *screen = (*ptr)->screen; - screen->texture_release(screen, ptr); - } + struct pipe_screen *screen = (*ptr)->screen; + assert(screen); + screen->texture_release(screen, ptr); assert(!*ptr); } @@ -127,10 +121,10 @@ pipe_texture_reference(struct pipe_texture **ptr, static INLINE void pipe_texture_release(struct pipe_texture **ptr) { - struct pipe_context *pipe; + struct pipe_screen *screen; assert(ptr); - pipe = (*ptr)->pipe; - pipe->texture_release(pipe, ptr); + screen = (*ptr)->screen; + screen->texture_release(screen, ptr); *ptr = NULL; } -- cgit v1.2.3 From cc5ffd762227345d0a5bf9e9356dd83a8b2a8b33 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 14:28:17 -0700 Subject: gallium: remove obsolete *_strings.c files --- src/gallium/drivers/i915simple/i915_strings.c | 53 --------------------------- src/gallium/drivers/i965simple/brw_strings.c | 51 -------------------------- 2 files changed, 104 deletions(-) delete mode 100644 src/gallium/drivers/i915simple/i915_strings.c delete mode 100644 src/gallium/drivers/i965simple/brw_strings.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_strings.c b/src/gallium/drivers/i915simple/i915_strings.c deleted file mode 100644 index 14da3bcd72..0000000000 --- a/src/gallium/drivers/i915simple/i915_strings.c +++ /dev/null @@ -1,53 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "i915_context.h" -#include "i915_screen.h" -#include "i915_reg.h" - - -/** XXX temporary screen/pipe duplication here */ - - -static const char *i915_get_vendor( struct pipe_context *pipe ) -{ - return pipe->screen->get_vendor(pipe->screen); -} - - -static const char *i915_get_name( struct pipe_context *pipe ) -{ - return pipe->screen->get_name(pipe->screen); -} - - -void -i915_init_string_functions(struct i915_context *i915) -{ - i915->pipe.get_name = i915_get_name; - i915->pipe.get_vendor = i915_get_vendor; -} diff --git a/src/gallium/drivers/i965simple/brw_strings.c b/src/gallium/drivers/i965simple/brw_strings.c deleted file mode 100644 index a8f2ce582a..0000000000 --- a/src/gallium/drivers/i965simple/brw_strings.c +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "brw_context.h" -#include "brw_reg.h" - -#include "pipe/p_screen.h" - - -static const char *brw_get_vendor( struct pipe_context *pipe ) -{ - return pipe->screen->get_vendor(pipe->screen); -} - - -static const char *brw_get_name( struct pipe_context *pipe ) -{ - return pipe->screen->get_name(pipe->screen); -} - - -void -brw_init_string_functions(struct brw_context *brw) -{ - brw->pipe.get_name = brw_get_name; - brw->pipe.get_vendor = brw_get_vendor; -} -- cgit v1.2.3 From 1c50ea2cd9ab8752793c99b4a7a2a6656bdde1ac Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 27 Feb 2008 13:40:23 -0800 Subject: cell: Use unified data cache for textures too --- src/gallium/drivers/cell/spu/spu_main.c | 2 + src/gallium/drivers/cell/spu/spu_main.h | 3 +- src/gallium/drivers/cell/spu/spu_texture.c | 184 +++++++++++------------------ 3 files changed, 72 insertions(+), 117 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index cc4bafdb3a..59300028d4 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -286,6 +286,8 @@ cmd_state_texture(const struct cell_command_texture *texture) { spu.texture.width, spu.texture.height, 0.0, 0.0}; spu.tex_size_mask = (vector unsigned int) { spu.texture.width - 1, spu.texture.height - 1, 0, 0 }; + spu.tex_size_x_mask = spu_splats(spu.texture.width - 1); + spu.tex_size_y_mask = spu_splats(spu.texture.height - 1); } diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index d14f1abbe7..a13edd1702 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -107,6 +107,8 @@ struct spu_global vector float tex_size; vector unsigned int tex_size_mask; /**< == int(size - 1) */ + vector unsigned int tex_size_x_mask; /**< == int(size - 1) */ + vector unsigned int tex_size_y_mask; /**< == int(size - 1) */ vector float (*sample_texture)(vector float texcoord); @@ -130,7 +132,6 @@ extern boolean Debug; #define TAG_INDEX_BUFFER 16 #define TAG_BATCH_BUFFER 17 #define TAG_MISC 18 -#define TAG_TEXTURE_TILE 19 #define TAG_DCACHE0 20 #define TAG_DCACHE1 21 #define TAG_DCACHE2 22 diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index 3962aaa4a9..67eb08196a 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -31,19 +31,7 @@ #include "spu_texture.h" #include "spu_tile.h" #include "spu_colorpack.h" - - -/** - * Number of texture tiles to cache. - * Note that this will probably be the largest consumer of SPU local store/ - * memory for this driver! - */ -#define CACHE_SIZE 16 - -static tile_t tex_tiles[CACHE_SIZE] ALIGN16_ATTRIB; - -static vector unsigned int tex_tile_xy[CACHE_SIZE]; - +#include "spu_dcache.h" /** @@ -52,78 +40,60 @@ static vector unsigned int tex_tile_xy[CACHE_SIZE]; void invalidate_tex_cache(void) { - /* XXX memset? */ - uint i; - for (i = 0; i < CACHE_SIZE; i++) { - tex_tile_xy[i] = ((vector unsigned int) { ~0U, ~0U, ~0U, ~0U }); - } + spu_dcache_mark_dirty((unsigned) spu.texture.start, + 4 * spu.texture.width * spu.texture.height); } -/** - * Return the cache pos/index which corresponds to tile (tx,ty) - */ -static INLINE uint -cache_pos(vector unsigned int txty) +static uint +get_texel(vec_uint4 coordinate) { - uint pos = (spu_extract(txty,0) + spu_extract(txty,1) * 4) % CACHE_SIZE; - return pos; + vec_uint4 tmp; + unsigned x = spu_extract(coordinate, 0); + unsigned y = spu_extract(coordinate, 1); + const unsigned tiles_per_row = spu.texture.width / TILE_SIZE; + unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row) + + (x / TILE_SIZE)); + unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE) + + (x % TILE_SIZE)); + + spu_dcache_fetch_unaligned((qword *) & tmp, + spu.texture.start + tile_offset + texel_offset, + 4); + return spu_extract(tmp, 0); } -/** - * Make sure the tile for texel (i,j) is present, return its position/index - * in the cache. - */ -static uint -get_tex_tile(vector unsigned int ij) +static void +get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels) { - /* tile address: tx,ty */ - const vector unsigned int txty = spu_rlmask(ij, -5); /* divide by 32 */ - const uint pos = cache_pos(txty); - - if ((spu_extract(tex_tile_xy[pos], 0) != spu_extract(txty, 0)) || - (spu_extract(tex_tile_xy[pos], 1) != spu_extract(txty, 1))) { - - /* texture cache miss, fetch tile from main memory */ - const uint tiles_per_row = spu.texture.width / TILE_SIZE; - const uint bytes_per_tile = sizeof(tile_t); - const void *src = (const ubyte *) spu.texture.start - + (spu_extract(txty,1) * tiles_per_row + spu_extract(txty,0)) * bytes_per_tile; - - printf("SPU %u: tex cache miss at %d, %d pos=%u old=%d,%d\n", - spu.init.id, - spu_extract(txty,0), - spu_extract(txty,1), - pos, - spu_extract(tex_tile_xy[pos],0), - spu_extract(tex_tile_xy[pos],1)); - - ASSERT_ALIGN16(tex_tiles[pos].ui); - ASSERT_ALIGN16(src); - - mfc_get(tex_tiles[pos].ui, /* dest */ - (unsigned int) src, - bytes_per_tile, /* size */ - TAG_TEXTURE_TILE, - 0, /* tid */ - 0 /* rid */); - - wait_on_mask(1 << TAG_TEXTURE_TILE); - - tex_tile_xy[pos] = txty; - } - else { -#if 0 - printf("SPU %u: tex cache HIT at %d, %d\n", - spu.init.id, tx, ty); -#endif - } - - return pos; + const unsigned texture_ea = (uintptr_t) spu.texture.start; + vec_uint4 tile_x = spu_rlmask(x, -5); + vec_uint4 tile_y = spu_rlmask(y, -5); + const qword offset_x = si_andi((qword) x, 0x1f); + const qword offset_y = si_andi((qword) y, 0x1f); + + const qword tiles_per_row = (qword) spu_splats(spu.texture.width / TILE_SIZE); + const qword tile_size = (qword) spu_splats(sizeof(tile_t)); + + qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x); + tile_offset = si_mpy((qword) tile_offset, tile_size); + + qword texel_offset = si_a(si_mpyui(offset_y, 32), offset_x); + texel_offset = si_mpyui(texel_offset, 4); + + vec_uint4 offset = (vec_uint4) si_a(tile_offset, texel_offset); + + spu_dcache_fetch_unaligned((qword *) & texels[0], + texture_ea + spu_extract(offset, 0), 4); + spu_dcache_fetch_unaligned((qword *) & texels[1], + texture_ea + spu_extract(offset, 1), 4); + spu_dcache_fetch_unaligned((qword *) & texels[2], + texture_ea + spu_extract(offset, 2), 4); + spu_dcache_fetch_unaligned((qword *) & texels[3], + texture_ea + spu_extract(offset, 3), 4); } - /** * Get texture sample at texcoord. * XXX this is extremely primitive for now. @@ -134,9 +104,7 @@ sample_texture_nearest(vector float texcoord) vector float tc = spu_mul(texcoord, spu.tex_size); vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */ itc = spu_and(itc, spu.tex_size_mask); /* mask (GL_REPEAT) */ - vector unsigned int ij = spu_and(itc, TILE_SIZE-1); /* intra tile addr */ - uint pos = get_tex_tile(itc); - uint texel = tex_tiles[pos].ui[spu_extract(ij, 1)][spu_extract(ij, 0)]; + uint texel = get_texel(itc); return spu_unpack_A8R8G8B8(texel); } @@ -144,49 +112,33 @@ sample_texture_nearest(vector float texcoord) vector float sample_texture_bilinear(vector float texcoord) { - static const vector unsigned int offset10 = {1, 0, 0, 0}; - static const vector unsigned int offset01 = {0, 1, 0, 0}; + static const vec_uint4 offset_x = {0, 0, 1, 1}; + static const vec_uint4 offset_y = {0, 1, 0, 1}; vector float tc = spu_mul(texcoord, spu.tex_size); tc = spu_add(tc, spu_splats(-0.5f)); /* half texel bias */ /* integer texcoords S,T: */ - vector unsigned int itc00 = spu_convtu(tc, 0); /* convert to int */ - vector unsigned int itc01 = spu_add(itc00, offset01); - vector unsigned int itc10 = spu_add(itc00, offset10); - vector unsigned int itc11 = spu_add(itc10, offset01); - - /* mask (GL_REPEAT) */ - itc00 = spu_and(itc00, spu.tex_size_mask); - itc01 = spu_and(itc01, spu.tex_size_mask); - itc10 = spu_and(itc10, spu.tex_size_mask); - itc11 = spu_and(itc11, spu.tex_size_mask); - - /* intra tile addr */ - vector unsigned int ij00 = spu_and(itc00, TILE_SIZE-1); - vector unsigned int ij01 = spu_and(itc01, TILE_SIZE-1); - vector unsigned int ij10 = spu_and(itc10, TILE_SIZE-1); - vector unsigned int ij11 = spu_and(itc11, TILE_SIZE-1); - - /* get tile cache positions */ - uint pos00 = get_tex_tile(itc00); - uint pos01, pos10, pos11; - if ((spu_extract(ij00, 0) < TILE_SIZE-1) && - (spu_extract(ij00, 1) < TILE_SIZE-1)) { - /* all texels are in the same tile */ - pos01 = pos10 = pos11 = pos00; - } - else { - pos01 = get_tex_tile(itc01); - pos10 = get_tex_tile(itc10); - pos11 = get_tex_tile(itc11); - } - - /* get texels from tiles and convert to float[4] */ - vector float texel00 = spu_unpack_A8R8G8B8(tex_tiles[pos00].ui[spu_extract(ij00, 1)][spu_extract(ij00, 0)]); - vector float texel01 = spu_unpack_A8R8G8B8(tex_tiles[pos01].ui[spu_extract(ij01, 1)][spu_extract(ij01, 0)]); - vector float texel10 = spu_unpack_A8R8G8B8(tex_tiles[pos10].ui[spu_extract(ij10, 1)][spu_extract(ij10, 0)]); - vector float texel11 = spu_unpack_A8R8G8B8(tex_tiles[pos11].ui[spu_extract(ij11, 1)][spu_extract(ij11, 0)]); + vec_uint4 itc = spu_convtu(tc, 0); /* convert to int */ + + vec_uint4 texels[4]; + + vec_uint4 x = spu_splats(spu_extract(itc, 0)); + vec_uint4 y = spu_splats(spu_extract(itc, 1)); + + x = spu_add(x, offset_x); + y = spu_add(y, offset_y); + + x = spu_and(x, spu.tex_size_x_mask); + y = spu_and(y, spu.tex_size_y_mask); + + get_four_texels(x, y, texels); + + vector float texel00 = spu_unpack_A8R8G8B8(spu_extract(texels[0], 0)); + vector float texel01 = spu_unpack_A8R8G8B8(spu_extract(texels[1], 0)); + vector float texel10 = spu_unpack_A8R8G8B8(spu_extract(texels[2], 0)); + vector float texel11 = spu_unpack_A8R8G8B8(spu_extract(texels[3], 0)); + /* Compute weighting factors in [0,1] * Multiply texcoord by 1024, AND with 1023, convert back to float. -- cgit v1.2.3 From fb40c5a9c7dc91c03f80780e0a09be0cade98705 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 15:06:04 -0700 Subject: gallium: added uses_kill field to tgsi_shader_info --- src/gallium/auxiliary/tgsi/util/tgsi_scan.c | 3 +++ src/gallium/auxiliary/tgsi/util/tgsi_scan.h | 1 + 2 files changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c index a1cc681492..a973aeb62f 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c @@ -133,5 +133,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens, } } + info->uses_kill = (info->opcode_count[TGSI_OPCODE_KIL] || + info->opcode_count[TGSI_OPCODE_KILP]); + tgsi_parse_free (&parse); } diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h index dc6dfd6d0b..d10d300c4d 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h @@ -57,6 +57,7 @@ struct tgsi_shader_info uint opcode_count[TGSI_OPCODE_LAST]; /**< opcode histogram */ boolean writes_z; /**< does fragment shader write Z value? */ + boolean uses_kill; /**< KIL or KILP instruction used? */ }; -- cgit v1.2.3 From c66ec5c7a2966df3e3456dfca3eb17c294b30dd5 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 15:06:55 -0700 Subject: gallium: remove uses_kill field from softpipe_shader --- src/gallium/drivers/softpipe/sp_quad.c | 2 +- src/gallium/drivers/softpipe/sp_state.h | 2 -- src/gallium/drivers/softpipe/sp_state_fs.c | 3 --- 3 files changed, 1 insertion(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad.c b/src/gallium/drivers/softpipe/sp_quad.c index 0aaf94021f..8603c1a367 100644 --- a/src/gallium/drivers/softpipe/sp_quad.c +++ b/src/gallium/drivers/softpipe/sp_quad.c @@ -60,7 +60,7 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp->depth_stencil->depth.enabled && sp->framebuffer.zsbuf && !sp->depth_stencil->alpha.enabled && - !sp->fs->uses_kill && + !sp->fs->info.uses_kill && !sp->fs->info.writes_z; /* build up the pipeline in reverse order... */ diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index b1070e185a..895976467c 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -66,8 +66,6 @@ struct sp_fragment_shader { struct tgsi_shader_info info; - boolean uses_kill; - void (*prepare)( const struct sp_fragment_shader *shader, struct tgsi_exec_machine *machine, struct tgsi_sampler *samplers); diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 2715dca0f0..eb641ed321 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -64,9 +64,6 @@ softpipe_create_fs_state(struct pipe_context *pipe, /* get/save the summary info for this shader */ tgsi_scan_shader(templ->tokens, &state->info); - /* convenience field */ - state->uses_kill = (state->info.opcode_count[TGSI_OPCODE_KIL] || - state->info.opcode_count[TGSI_OPCODE_KILP]); return state; } -- cgit v1.2.3 From 80a9b5e1d962c17530e3bcb34c0d1ac4aae8fa7f Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 15:11:12 -0700 Subject: gallium: remove unnecessary tgsi_interp_coef decl --- src/gallium/drivers/softpipe/sp_state.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 895976467c..3943d4ed2b 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -53,7 +53,6 @@ struct tgsi_sampler; -struct tgsi_interp_coef; struct tgsi_exec_machine; -- cgit v1.2.3 From 0e1e1f12f47d5b1d49f68930b05eadf1143e1396 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 15:45:41 -0700 Subject: gallium/i915: remove unneeded assignment --- src/gallium/drivers/i915simple/i915_texture.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 9cdf3418a9..ef5adff550 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -491,7 +491,6 @@ i915_texture_create_screen(struct pipe_screen *screen, tex->base = *templat; tex->base.refcount = 1; - tex->base.pipe = NULL; tex->base.screen = screen; if (i915screen->is_i945 ? i945_miptree_layout(tex) : -- cgit v1.2.3 From 3197ad5a56ee94773f974ac727b316c5adfe1b6f Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 15:47:24 -0700 Subject: gallium: added file_max[] array to tgsi_shader_info Records the highest index of a declared register. --- src/gallium/auxiliary/tgsi/util/tgsi_scan.c | 5 ++++- src/gallium/auxiliary/tgsi/util/tgsi_scan.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c index a973aeb62f..8c886edc65 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c @@ -46,10 +46,12 @@ void tgsi_scan_shader(const struct tgsi_token *tokens, struct tgsi_shader_info *info) { - uint procType; + uint procType, i; struct tgsi_parse_context parse; memset(info, 0, sizeof(*info)); + for (i = 0; i < TGSI_FILE_COUNT; i++) + info->file_max[i] = -1; /** ** Setup to begin parsing input shader @@ -97,6 +99,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens, /* only first 32 regs will appear in this bitfield */ info->file_mask[file] |= (1 << i); info->file_count[file]++; + info->file_max[file] = MAX2(info->file_max[file], i); if (file == TGSI_FILE_INPUT) { info->input_semantic_name[info->num_inputs] diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h index d10d300c4d..563ee900fa 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h @@ -51,6 +51,7 @@ struct tgsi_shader_info uint file_mask[TGSI_FILE_COUNT]; /**< bitmask of declared registers */ uint file_count[TGSI_FILE_COUNT]; /**< number of declared registers */ + int file_max[TGSI_FILE_COUNT]; /**< highest index of declared registers */ uint immediate_count; /**< number of immediates declared */ -- cgit v1.2.3 From 681b78fc60b2e60cf9f84802932bf9d2defd28c2 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 15:48:00 -0700 Subject: gallium: remove unnecessary assignment --- src/gallium/drivers/softpipe/sp_texture.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 7c02765313..c605ed925b 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -91,7 +91,6 @@ softpipe_texture_create_screen(struct pipe_screen *screen, spt->base = *templat; spt->base.refcount = 1; - spt->base.pipe = NULL; spt->base.screen = screen; softpipe_texture_layout(spt); -- cgit v1.2.3 From 679b6cf0a0e662513c8d7732049c44916e0e9e86 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 16:00:04 -0700 Subject: gallium: include p_compiler.h instead of p_util.h --- src/gallium/auxiliary/tgsi/util/tgsi_scan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h index 563ee900fa..0530bc6b51 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h @@ -29,7 +29,7 @@ #define TGSI_SCAN_H -#include "pipe/p_util.h" +#include "pipe/p_compiler.h" #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" -- cgit v1.2.3 From 7df26d76d2a37e9e828296bfbcf7cec04bfbe233 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 16:01:35 -0700 Subject: gallium: include p_util.h --- src/gallium/auxiliary/tgsi/util/tgsi_scan.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c index 8c886edc65..b7bbff1689 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c @@ -37,6 +37,7 @@ #include "tgsi/util/tgsi_parse.h" #include "tgsi/util/tgsi_build.h" +#include "pipe/p_util.h" -- cgit v1.2.3 From cddeca51adf0d2b736a223e47b60f6ef3be85bff Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 16:02:58 -0700 Subject: gallium: remove dependencies on pipe_shader_state's semantic info Use tgsi_scan_shader() to populate a tgsi_shader_info struct and use that instead. --- src/gallium/auxiliary/draw/draw_aaline.c | 2 ++ src/gallium/auxiliary/draw/draw_aapoint.c | 6 ++++-- src/gallium/auxiliary/draw/draw_clip.c | 8 ++++---- src/gallium/auxiliary/draw/draw_context.c | 8 ++++---- src/gallium/auxiliary/draw/draw_flatshade.c | 8 ++++---- src/gallium/auxiliary/draw/draw_private.h | 3 +++ src/gallium/auxiliary/draw/draw_pstipple.c | 2 ++ src/gallium/auxiliary/draw/draw_twoside.c | 12 ++++++------ src/gallium/auxiliary/draw/draw_vertex_fetch.c | 2 +- src/gallium/auxiliary/draw/draw_vertex_shader.c | 17 +++++++++-------- src/gallium/auxiliary/draw/draw_vs_exec.c | 2 +- src/gallium/auxiliary/draw/draw_vs_sse.c | 2 +- src/gallium/auxiliary/draw/draw_wide_prims.c | 8 ++++---- 13 files changed, 45 insertions(+), 35 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index be6cfd3b6a..51140388f0 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -340,9 +340,11 @@ generate_aaline_fs(struct aaline_stage *aaline) tgsi_dump(aaline_fs.tokens, 0); #endif +#if 1 /* XXX remove */ aaline_fs.input_semantic_name[aaline_fs.num_inputs] = TGSI_SEMANTIC_GENERIC; aaline_fs.input_semantic_index[aaline_fs.num_inputs] = transform.maxGeneric + 1; aaline_fs.num_inputs++; +#endif aaline->fs->aaline_fs = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c index d16adb2505..d48a416899 100644 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -514,9 +514,11 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) tgsi_dump(aapoint_fs.tokens, 0); #endif +#if 1 /* XXX remove */ aapoint_fs.input_semantic_name[aapoint_fs.num_inputs] = TGSI_SEMANTIC_GENERIC; aapoint_fs.input_semantic_index[aapoint_fs.num_inputs] = transform.maxGeneric + 1; aapoint_fs.num_inputs++; +#endif aapoint->fs->aapoint_fs = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs); @@ -694,8 +696,8 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header) /* find PSIZ vertex output */ const struct draw_vertex_shader *vs = draw->vertex_shader; uint i; - for (i = 0; i < vs->state->num_outputs; i++) { - if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { aapoint->psize_slot = i; break; } diff --git a/src/gallium/auxiliary/draw/draw_clip.c b/src/gallium/auxiliary/draw/draw_clip.c index e3051507ea..200152ecab 100644 --- a/src/gallium/auxiliary/draw/draw_clip.c +++ b/src/gallium/auxiliary/draw/draw_clip.c @@ -409,13 +409,13 @@ clip_init_state( struct draw_stage *stage ) clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE; if (clipper->flat) { - const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; uint i; clipper->num_color_attribs = 0; - for (i = 0; i < vs->num_outputs; i++) { - if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR || - vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || + vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { clipper->color_attribs[clipper->num_color_attribs++] = i; } } diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 48f00946ea..64ada8ce04 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -262,11 +262,11 @@ int draw_find_vs_output(struct draw_context *draw, uint semantic_name, uint semantic_index) { - const struct pipe_shader_state *vs = draw->vertex_shader->state; + const struct draw_vertex_shader *vs = draw->vertex_shader; uint i; - for (i = 0; i < vs->num_outputs; i++) { - if (vs->output_semantic_name[i] == semantic_name && - vs->output_semantic_index[i] == semantic_index) + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == semantic_name && + vs->info.output_semantic_index[i] == semantic_index) return i; } diff --git a/src/gallium/auxiliary/draw/draw_flatshade.c b/src/gallium/auxiliary/draw/draw_flatshade.c index 4398abbc60..ccad71d695 100644 --- a/src/gallium/auxiliary/draw/draw_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_flatshade.c @@ -128,14 +128,14 @@ static void flatshade_point( struct draw_stage *stage, static void flatshade_init_state( struct draw_stage *stage ) { struct flat_stage *flat = flat_stage(stage); - const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; uint i; /* Find which vertex shader outputs are colors, make a list */ flat->num_color_attribs = 0; - for (i = 0; i < vs->num_outputs; i++) { - if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR || - vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || + vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { flat->color_attribs[flat->num_color_attribs++] = i; } } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 03e3d3a66b..e988e71d23 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -46,6 +46,7 @@ #include "rtasm/rtasm_x86sse.h" #include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_scan.h" struct pipe_context; @@ -134,6 +135,8 @@ struct draw_vertex_shader { */ const struct pipe_shader_state *state; + struct tgsi_shader_info info; + void (*prepare)( struct draw_vertex_shader *shader, struct draw_context *draw ); diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index efc88bf038..f6200aa820 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -330,11 +330,13 @@ generate_pstip_fs(struct pstip_stage *pstip) pstip->sampler_unit = transform.maxSampler + 1; +#if 1 /* XXX remove */ if (transform.wincoordInput < 0) { pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION; pstip_fs.input_semantic_index[pstip_fs.num_inputs] = (ubyte)transform.maxInput; pstip_fs.num_inputs++; } +#endif pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); } diff --git a/src/gallium/auxiliary/draw/draw_twoside.c b/src/gallium/auxiliary/draw/draw_twoside.c index 1c38957987..3debaac282 100644 --- a/src/gallium/auxiliary/draw/draw_twoside.c +++ b/src/gallium/auxiliary/draw/draw_twoside.c @@ -119,7 +119,7 @@ static void twoside_first_tri( struct draw_stage *stage, struct prim_header *header ) { struct twoside_stage *twoside = twoside_stage(stage); - const struct pipe_shader_state *vs = stage->draw->vertex_shader->state; + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; uint i; twoside->attrib_front0 = 0; @@ -128,15 +128,15 @@ static void twoside_first_tri( struct draw_stage *stage, twoside->attrib_back1 = 0; /* Find which vertex shader outputs are front/back colors */ - for (i = 0; i < vs->num_outputs; i++) { - if (vs->output_semantic_name[i] == TGSI_SEMANTIC_COLOR) { - if (vs->output_semantic_index[i] == 0) + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR) { + if (vs->info.output_semantic_index[i] == 0) twoside->attrib_front0 = i; else twoside->attrib_front1 = i; } - if (vs->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { - if (vs->output_semantic_index[i] == 0) + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + if (vs->info.output_semantic_index[i] == 0) twoside->attrib_back0 = i; else twoside->attrib_back1 = i; diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c index e13df04605..cb8cdd04a3 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c +++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c @@ -473,7 +473,7 @@ void draw_update_vertex_fetch( struct draw_context *draw ) if (!draw->vertex_shader) return; - nr_attrs = draw->vertex_shader->state->num_inputs; + nr_attrs = draw->vertex_shader->info.num_inputs; for (i = 0; i < nr_attrs; i++) { unsigned buf = draw->vertex_element[i].vertex_buffer_index; diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index 5d2f5c9c43..1e95355555 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -91,15 +91,16 @@ draw_create_vertex_shader(struct draw_context *draw, struct draw_vertex_shader *vs; vs = draw_create_vs_llvm( draw, shader ); - if (vs) - return vs; + if (!vs) { + vs = draw_create_vs_sse( draw, shader ); + if (!vs) { + vs = draw_create_vs_exec( draw, shader ); + } + } + assert(vs); - vs = draw_create_vs_sse( draw, shader ); - if (vs) - return vs; + tgsi_scan_shader(shader->tokens, &vs->info); - vs = draw_create_vs_exec( draw, shader ); - assert(vs); return vs; } @@ -111,7 +112,7 @@ draw_bind_vertex_shader(struct draw_context *draw, draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); draw->vertex_shader = dvs; - draw->num_vs_outputs = dvs->state->num_outputs; + draw->num_vs_outputs = dvs->info.num_outputs; tgsi_exec_machine_init(&draw->machine); diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 8588879400..583812aadd 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -103,7 +103,7 @@ vs_exec_run( struct draw_vertex_shader *shader, const float *trans = draw->viewport.translate; assert(count <= 4); - assert(draw->vertex_shader->state->output_semantic_name[0] + assert(draw->vertex_shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); machine->Consts = (float (*)[4]) draw->user.constants; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 11ef0c503d..0b8bc2bf14 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -119,7 +119,7 @@ vs_sse_run( struct draw_vertex_shader *base, const float *trans = draw->viewport.translate; assert(count <= 4); - assert(draw->vertex_shader->state->output_semantic_name[0] + assert(draw->vertex_shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); /* Consts does not require 16 byte alignment. */ diff --git a/src/gallium/auxiliary/draw/draw_wide_prims.c b/src/gallium/auxiliary/draw/draw_wide_prims.c index d967810dd4..d6bff110b4 100644 --- a/src/gallium/auxiliary/draw/draw_wide_prims.c +++ b/src/gallium/auxiliary/draw/draw_wide_prims.c @@ -278,8 +278,8 @@ static void wide_first_point( struct draw_stage *stage, /* find vertex shader texcoord outputs */ const struct draw_vertex_shader *vs = draw->vertex_shader; uint i, j = 0; - for (i = 0; i < vs->state->num_outputs; i++) { - if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { wide->texcoord_slot[j] = i; wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; j++; @@ -294,8 +294,8 @@ static void wide_first_point( struct draw_stage *stage, /* find PSIZ vertex output */ const struct draw_vertex_shader *vs = draw->vertex_shader; uint i; - for (i = 0; i < vs->state->num_outputs; i++) { - if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { wide->psize_slot = i; break; } -- cgit v1.2.3 From 6b9a7eb460fe0a9c958b837f2ed49c2d4e303ebc Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 16:03:40 -0700 Subject: gallium: remove dependencies on pipe_shader_state's semantic info --- src/gallium/drivers/softpipe/sp_prim_setup.c | 4 ++-- src/gallium/drivers/softpipe/sp_quad_fs.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 17284539b0..5c8b0bf69c 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -1163,13 +1163,13 @@ static void setup_begin( struct draw_stage *stage ) { struct setup_stage *setup = setup_stage(stage); struct softpipe_context *sp = setup->softpipe; - const struct pipe_shader_state *fs = &setup->softpipe->fs->shader; + const struct sp_fragment_shader *fs = &setup->softpipe->fs; if (sp->dirty) { softpipe_update_derived(sp); } - setup->quad.nr_attrs = fs->num_inputs; + setup->quad.nr_attrs = fs->info.num_inputs; sp->quad.first->begin(sp->quad.first); diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 1794fb5a61..1fbb2e38c4 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -148,7 +148,7 @@ static void shade_begin(struct quad_stage *qs) /* find output slots for depth, color */ qss->colorOutSlot = -1; qss->depthOutSlot = -1; - for (i = 0; i < qss->stage.softpipe->fs->shader.num_outputs; i++) { + for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) { switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: qss->depthOutSlot = i; -- cgit v1.2.3 From ea7e86dd4d1e7dbef2642da73bb1980723ae49ef Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 16:05:16 -0700 Subject: gallium/i965: remove dependencies on pipe_shader_state's semantic info The brw_shader_info struct is rendundant and could be removed... --- src/gallium/drivers/i965simple/brw_context.h | 8 ++++++-- src/gallium/drivers/i965simple/brw_draw_upload.c | 2 +- src/gallium/drivers/i965simple/brw_sf.c | 2 +- src/gallium/drivers/i965simple/brw_shader_info.c | 5 +++-- src/gallium/drivers/i965simple/brw_state.c | 9 +++++++-- src/gallium/drivers/i965simple/brw_wm_decl.c | 8 ++++---- 6 files changed, 22 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index 65664d853d..fbc89c889b 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -38,6 +38,8 @@ #include "pipe/p_defines.h" #include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" + #include "brw_structs.h" #include "brw_winsys.h" @@ -203,7 +205,8 @@ struct brw_shader_info { struct brw_vertex_program { struct pipe_shader_state program; - struct brw_shader_info info; + struct tgsi_shader_info info; + struct brw_shader_info info2; /* XXX get rid of this */ int id; }; @@ -211,7 +214,8 @@ struct brw_vertex_program { struct brw_fragment_program { struct pipe_shader_state program; - struct brw_shader_info info; + struct tgsi_shader_info info; + struct brw_shader_info info2; /* XXX get rid of this */ boolean UsesDepth; boolean UsesKill; diff --git a/src/gallium/drivers/i965simple/brw_draw_upload.c b/src/gallium/drivers/i965simple/brw_draw_upload.c index aa85d93866..9c0c78c236 100644 --- a/src/gallium/drivers/i965simple/brw_draw_upload.c +++ b/src/gallium/drivers/i965simple/brw_draw_upload.c @@ -256,7 +256,7 @@ boolean brw_upload_vertex_elements( struct brw_context *brw ) struct brw_vertex_element_packet vep; unsigned i; - unsigned nr_enabled = brw->attribs.VertexProgram->program.num_inputs; + unsigned nr_enabled = brw->attribs.VertexProgram->info.num_inputs; memset(&vep, 0, sizeof(vep)); diff --git a/src/gallium/drivers/i965simple/brw_sf.c b/src/gallium/drivers/i965simple/brw_sf.c index 7c83b81c85..54ce5ed9f1 100644 --- a/src/gallium/drivers/i965simple/brw_sf.c +++ b/src/gallium/drivers/i965simple/brw_sf.c @@ -133,7 +133,7 @@ static void upload_sf_prog( struct brw_context *brw ) key.vp_output_count = brw->vs.prog_data->outputs_written; /* BRW_NEW_FS */ - key.fp_input_count = brw->attribs.FragmentProgram->info.nr_regs[TGSI_FILE_INPUT]; + key.fp_input_count = brw->attribs.FragmentProgram->info2.nr_regs[TGSI_FILE_INPUT]; /* BRW_NEW_REDUCED_PRIMITIVE */ diff --git a/src/gallium/drivers/i965simple/brw_shader_info.c b/src/gallium/drivers/i965simple/brw_shader_info.c index a762a870fe..e7e063dead 100644 --- a/src/gallium/drivers/i965simple/brw_shader_info.c +++ b/src/gallium/drivers/i965simple/brw_shader_info.c @@ -6,8 +6,9 @@ #include "tgsi/util/tgsi_parse.h" - - +/** + * XXX try to get rid of this. See tgsi_scan_shader() and tgsi_shader_info. + */ void brw_shader_info(const struct tgsi_token *tokens, struct brw_shader_info *info ) { diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index 7466fdc403..6e46465200 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -175,8 +175,10 @@ static void * brw_create_fs_state(struct pipe_context *pipe, brw_fp->program = *shader; brw_fp->id = brw_context(pipe)->program_id++; + tgsi_scan_shader(shader->tokens, &brw_fp->info); + brw_shader_info(shader->tokens, - &brw_fp->info); + &brw_fp->info2); tgsi_dump(shader->tokens, 0); @@ -211,8 +213,11 @@ static void *brw_create_vs_state(struct pipe_context *pipe, */ brw_vp->program = *shader; brw_vp->id = brw_context(pipe)->program_id++; + + tgsi_scan_shader(shader->tokens, &brw_vp->info); + brw_shader_info(shader->tokens, - &brw_vp->info); + &brw_vp->info2); tgsi_dump(shader->tokens, 0); diff --git a/src/gallium/drivers/i965simple/brw_wm_decl.c b/src/gallium/drivers/i965simple/brw_wm_decl.c index 97418a52e7..afea042bf0 100644 --- a/src/gallium/drivers/i965simple/brw_wm_decl.c +++ b/src/gallium/drivers/i965simple/brw_wm_decl.c @@ -259,7 +259,7 @@ static void prealloc_reg(struct brw_wm_compile *c) /* Then a copy of our part of the CURBE entry: */ { - int nr_constants = c->fp->info.nr_regs[TGSI_FILE_CONSTANT]; + int nr_constants = c->fp->info2.nr_regs[TGSI_FILE_CONSTANT]; int index = 0; c->prog_data.max_const = 4*nr_constants; @@ -282,7 +282,7 @@ static void prealloc_reg(struct brw_wm_compile *c) /* Next we receive the plane coefficients for parameter * interpolation: */ - for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_INPUT]; i++) { + for (i = 0; i < c->fp->info2.nr_regs[TGSI_FILE_INPUT]; i++) { c->payload_coef[i] = brw_vec8_grf(c->reg_index, 0); c->reg_index += 2; } @@ -302,11 +302,11 @@ static void prealloc_reg(struct brw_wm_compile *c) /* Now allocate room for the interpolated inputs and staging * registers for the outputs: */ - for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_INPUT]; i++) + for (i = 0; i < c->fp->info2.nr_regs[TGSI_FILE_INPUT]; i++) for (j = 0; j < 4; j++) c->wm_regs[TGSI_FILE_INPUT][i][j] = brw_vec8_grf( c->reg_index++, 0 ); - for (i = 0; i < c->fp->info.nr_regs[TGSI_FILE_OUTPUT]; i++) + for (i = 0; i < c->fp->info2.nr_regs[TGSI_FILE_OUTPUT]; i++) for (j = 0; j < 4; j++) c->wm_regs[TGSI_FILE_OUTPUT][i][j] = brw_vec8_grf( c->reg_index++, 0 ); -- cgit v1.2.3 From bad54d0b4dbe62aed6fad1d2725f7fe52a987440 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 16:09:17 -0700 Subject: gallium/i965: remove UsesDepth, UsesKill - use tgsi_shader_info instead --- src/gallium/drivers/i965simple/brw_context.h | 2 -- src/gallium/drivers/i965simple/brw_wm.c | 4 ++-- src/gallium/drivers/i965simple/brw_wm_state.c | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index fbc89c889b..170d50c5c3 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -218,8 +218,6 @@ struct brw_fragment_program { struct brw_shader_info info2; /* XXX get rid of this */ boolean UsesDepth; - boolean UsesKill; - boolean ComputesDepth; int id; }; diff --git a/src/gallium/drivers/i965simple/brw_wm.c b/src/gallium/drivers/i965simple/brw_wm.c index 539b170744..1c4b5b5ede 100644 --- a/src/gallium/drivers/i965simple/brw_wm.c +++ b/src/gallium/drivers/i965simple/brw_wm.c @@ -94,11 +94,11 @@ static void brw_wm_populate_key( struct brw_context *brw, /* Build the index for table lookup */ /* BRW_NEW_DEPTH_STENCIL */ - if (fp->UsesKill || + if (fp->info.uses_kill || brw->attribs.DepthStencil->alpha.enabled) lookup |= IZ_PS_KILL_ALPHATEST_BIT; - if (fp->ComputesDepth) + if (fp->info.writes_z) lookup |= IZ_PS_COMPUTES_DEPTH_BIT; if (brw->attribs.DepthStencil->depth.enabled) diff --git a/src/gallium/drivers/i965simple/brw_wm_state.c b/src/gallium/drivers/i965simple/brw_wm_state.c index 5ccd488842..f3aa36b07f 100644 --- a/src/gallium/drivers/i965simple/brw_wm_state.c +++ b/src/gallium/drivers/i965simple/brw_wm_state.c @@ -117,11 +117,11 @@ static void upload_wm_unit(struct brw_context *brw ) if (fp->UsesDepth) wm.wm5.program_uses_depth = 1; /* as far as we can tell */ - if (fp->ComputesDepth) + if (fp->info.writes_z) wm.wm5.program_computes_depth = 1; /* BRW_NEW_ALPHA_TEST */ - if (fp->UsesKill || + if (fp->info.uses_kill || brw->attribs.DepthStencil->alpha.enabled) wm.wm5.program_uses_killpixel = 1; -- cgit v1.2.3 From 7ba1afb03308685eb07d6b88184906ac42f60c2b Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 16:11:14 -0700 Subject: gallium/i965: added const to silence warnings --- src/gallium/drivers/i965simple/brw_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index 170d50c5c3..642db5b5a2 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -504,7 +504,7 @@ struct brw_context /* Arrays with buffer objects to copy non-bufferobj arrays into * for upload: */ - struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX]; + const struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX]; struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX]; -- cgit v1.2.3 From f504d87240542016213569b5da89e251adebc31d Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 16:11:26 -0700 Subject: gallium/i965: silence warnings --- src/gallium/drivers/i965simple/brw_surface.c | 1 + src/gallium/drivers/i965simple/brw_vs_emit.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index dc4846d39f..c99a91dcf7 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -164,6 +164,7 @@ brw_surface_fill(struct pipe_context *pipe, void brw_init_surface_functions(struct brw_context *brw) { + (void) brw_surface_data; /* silence warning */ brw->pipe.surface_copy = brw_surface_copy; brw->pipe.surface_fill = brw_surface_fill; } diff --git a/src/gallium/drivers/i965simple/brw_vs_emit.c b/src/gallium/drivers/i965simple/brw_vs_emit.c index 05df4860ed..33bbdc95c6 100644 --- a/src/gallium/drivers/i965simple/brw_vs_emit.c +++ b/src/gallium/drivers/i965simple/brw_vs_emit.c @@ -1051,7 +1051,7 @@ static void process_instruction(struct brw_vs_compile *c, { struct brw_reg args[3], dst; struct brw_compile *p = &c->func; - struct brw_indirect stack_index = brw_indirect(0, 0); + /*struct brw_indirect stack_index = brw_indirect(0, 0);*/ unsigned i; unsigned index; unsigned file; -- cgit v1.2.3 From dacf91fe587a777eed95b9767bc6b4ccdc7de71c Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 16:22:08 -0700 Subject: gallium/i965: remove brw_shader_info struct The info it contained is now found in tgsi_shader_info. Added a few assertions to catch potential misunderstandings about register counts vs. highest register index used. --- src/gallium/drivers/i965simple/Makefile | 1 - src/gallium/drivers/i965simple/SConscript | 1 - src/gallium/drivers/i965simple/brw_context.h | 13 +------------ src/gallium/drivers/i965simple/brw_sf.c | 2 +- src/gallium/drivers/i965simple/brw_shader_info.c | 2 +- src/gallium/drivers/i965simple/brw_state.c | 5 ++++- src/gallium/drivers/i965simple/brw_state.h | 7 ------- src/gallium/drivers/i965simple/brw_wm_decl.c | 18 ++++++++++++++---- 8 files changed, 21 insertions(+), 28 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/Makefile b/src/gallium/drivers/i965simple/Makefile index 8589ebdf96..e97146e57c 100644 --- a/src/gallium/drivers/i965simple/Makefile +++ b/src/gallium/drivers/i965simple/Makefile @@ -30,7 +30,6 @@ C_SOURCES = \ brw_sf.c \ brw_sf_emit.c \ brw_sf_state.c \ - brw_shader_info.c \ brw_state.c \ brw_state_batch.c \ brw_state_cache.c \ diff --git a/src/gallium/drivers/i965simple/SConscript b/src/gallium/drivers/i965simple/SConscript index e0cc78826e..c0825c4de3 100644 --- a/src/gallium/drivers/i965simple/SConscript +++ b/src/gallium/drivers/i965simple/SConscript @@ -29,7 +29,6 @@ i965simple = env.ConvenienceLibrary( 'brw_sf.c', 'brw_sf_emit.c', 'brw_sf_state.c', - 'brw_shader_info.c', 'brw_state.c', 'brw_state_batch.c', 'brw_state_cache.c', diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index 642db5b5a2..4da3a8cffc 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -197,33 +197,22 @@ struct brw_state_flags { }; -struct brw_shader_info { - int nr_regs[8]; /* TGSI_FILE_* */ -}; - - - struct brw_vertex_program { struct pipe_shader_state program; struct tgsi_shader_info info; - struct brw_shader_info info2; /* XXX get rid of this */ int id; }; - struct brw_fragment_program { struct pipe_shader_state program; struct tgsi_shader_info info; - struct brw_shader_info info2; /* XXX get rid of this */ - boolean UsesDepth; + boolean UsesDepth; /* XXX add this to tgsi_shader_info? */ int id; }; - - struct pipe_setup_linkage { struct { unsigned vp_output:5; diff --git a/src/gallium/drivers/i965simple/brw_sf.c b/src/gallium/drivers/i965simple/brw_sf.c index 54ce5ed9f1..c3b815a82b 100644 --- a/src/gallium/drivers/i965simple/brw_sf.c +++ b/src/gallium/drivers/i965simple/brw_sf.c @@ -133,7 +133,7 @@ static void upload_sf_prog( struct brw_context *brw ) key.vp_output_count = brw->vs.prog_data->outputs_written; /* BRW_NEW_FS */ - key.fp_input_count = brw->attribs.FragmentProgram->info2.nr_regs[TGSI_FILE_INPUT]; + key.fp_input_count = brw->attribs.FragmentProgram->info.file_max[TGSI_FILE_INPUT] + 1; /* BRW_NEW_REDUCED_PRIMITIVE */ diff --git a/src/gallium/drivers/i965simple/brw_shader_info.c b/src/gallium/drivers/i965simple/brw_shader_info.c index e7e063dead..f4694a4433 100644 --- a/src/gallium/drivers/i965simple/brw_shader_info.c +++ b/src/gallium/drivers/i965simple/brw_shader_info.c @@ -7,7 +7,7 @@ /** - * XXX try to get rid of this. See tgsi_scan_shader() and tgsi_shader_info. + * XXX this obsolete new and no longer compiled. */ void brw_shader_info(const struct tgsi_token *tokens, struct brw_shader_info *info ) diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index 6e46465200..6744a8aa4f 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -177,8 +177,10 @@ static void * brw_create_fs_state(struct pipe_context *pipe, tgsi_scan_shader(shader->tokens, &brw_fp->info); +#if 0 brw_shader_info(shader->tokens, &brw_fp->info2); +#endif tgsi_dump(shader->tokens, 0); @@ -216,9 +218,10 @@ static void *brw_create_vs_state(struct pipe_context *pipe, tgsi_scan_shader(shader->tokens, &brw_vp->info); +#if 0 brw_shader_info(shader->tokens, &brw_vp->info2); - +#endif tgsi_dump(shader->tokens, 0); return (void *)brw_vp; diff --git a/src/gallium/drivers/i965simple/brw_state.h b/src/gallium/drivers/i965simple/brw_state.h index 258e9a556e..de0a6371b8 100644 --- a/src/gallium/drivers/i965simple/brw_state.h +++ b/src/gallium/drivers/i965simple/brw_state.h @@ -148,11 +148,4 @@ void brw_invalidate_pools( struct brw_context *brw ); void brw_clear_batch_cache_flush( struct brw_context *brw ); -/* brw_shader_info.c - */ - -void brw_shader_info(const struct tgsi_token *tokens, - struct brw_shader_info *info ); - - #endif diff --git a/src/gallium/drivers/i965simple/brw_wm_decl.c b/src/gallium/drivers/i965simple/brw_wm_decl.c index afea042bf0..b50d768062 100644 --- a/src/gallium/drivers/i965simple/brw_wm_decl.c +++ b/src/gallium/drivers/i965simple/brw_wm_decl.c @@ -259,9 +259,12 @@ static void prealloc_reg(struct brw_wm_compile *c) /* Then a copy of our part of the CURBE entry: */ { - int nr_constants = c->fp->info2.nr_regs[TGSI_FILE_CONSTANT]; + int nr_constants = c->fp->info.file_max[TGSI_FILE_CONSTANT] + 1; int index = 0; + /* XXX number of constants, or highest numbered constant? */ + assert(nr_constants == c->fp->info.file_count[TGSI_FILE_CONSTANT]); + c->prog_data.max_const = 4*nr_constants; for (i = 0; i < nr_constants; i++) { for (j = 0; j < 4; j++, index++) @@ -282,7 +285,8 @@ static void prealloc_reg(struct brw_wm_compile *c) /* Next we receive the plane coefficients for parameter * interpolation: */ - for (i = 0; i < c->fp->info2.nr_regs[TGSI_FILE_INPUT]; i++) { + assert(c->fp->info.file_max[TGSI_FILE_INPUT] == c->fp->info.num_inputs); + for (i = 0; i < c->fp->info.file_max[TGSI_FILE_INPUT] + 1; i++) { c->payload_coef[i] = brw_vec8_grf(c->reg_index, 0); c->reg_index += 2; } @@ -302,11 +306,17 @@ static void prealloc_reg(struct brw_wm_compile *c) /* Now allocate room for the interpolated inputs and staging * registers for the outputs: */ - for (i = 0; i < c->fp->info2.nr_regs[TGSI_FILE_INPUT]; i++) + /* XXX do we want to loop over the _number_ of inputs/outputs or loop + * to the highest input/output index that's used? + * Probably the same, actually. + */ + assert(c->fp->info.file_max[TGSI_FILE_INPUT] + 1 == c->fp->info.num_inputs); + assert(c->fp->info.file_max[TGSI_FILE_OUTPUT] + 1 == c->fp->info.num_outputs); + for (i = 0; i < c->fp->info.file_max[TGSI_FILE_INPUT] + 1; i++) for (j = 0; j < 4; j++) c->wm_regs[TGSI_FILE_INPUT][i][j] = brw_vec8_grf( c->reg_index++, 0 ); - for (i = 0; i < c->fp->info2.nr_regs[TGSI_FILE_OUTPUT]; i++) + for (i = 0; i < c->fp->info.file_max[TGSI_FILE_OUTPUT] + 1; i++) for (j = 0; j < 4; j++) c->wm_regs[TGSI_FILE_OUTPUT][i][j] = brw_vec8_grf( c->reg_index++, 0 ); -- cgit v1.2.3 From d612b6fa9b5674e001755265e37924815646ad1a Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 16:17:15 -0700 Subject: cell: fix minor get_tex_surface() breakage --- src/gallium/drivers/cell/ppu/cell_texture.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index 28cadad6ed..bf6f6d3058 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -210,6 +210,7 @@ static void cell_tile_texture(struct cell_context *cell, struct cell_texture *texture) { + struct pipe_screen *screen = cell->pipe.screen; uint face = 0, level = 0, zslice = 0; struct pipe_surface *surf; const uint w = texture->base.width[0], h = texture->base.height[0]; @@ -221,7 +222,7 @@ cell_tile_texture(struct cell_context *cell, assert(w % TILE_SIZE == 0); assert(h % TILE_SIZE == 0); - surf = cell_get_tex_surface(&cell->pipe, &texture->base, face, level, zslice); + surf = screen->get_tex_surface(screen, &texture->base, face, level, zslice); ASSERT(surf); src = (const uint *) pipe_surface_map(surf); -- cgit v1.2.3 From 46da2f42a8e1bd88086cc17afc58738956d8b699 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 17:21:01 -0700 Subject: gallium/i965: added const to silence warning --- src/gallium/drivers/i965simple/brw_vs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_vs.h b/src/gallium/drivers/i965simple/brw_vs.h index 0e58f043b0..070f9dfcae 100644 --- a/src/gallium/drivers/i965simple/brw_vs.h +++ b/src/gallium/drivers/i965simple/brw_vs.h @@ -52,7 +52,7 @@ struct brw_vs_compile { struct brw_vs_prog_key key; struct brw_vs_prog_data prog_data; - struct brw_vertex_program *vp; + const struct brw_vertex_program *vp; unsigned nr_inputs; -- cgit v1.2.3 From 627efcaa8009bb7ed6a7f266f8122df800bb2706 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 17:21:29 -0700 Subject: gallium/i965: remove more dependencies on pipe_shader_state semantic info --- src/gallium/drivers/i965simple/brw_vs.c | 4 ++-- src/gallium/drivers/i965simple/brw_vs_emit.c | 4 ++-- src/gallium/drivers/i965simple/brw_wm_decl.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_vs.c b/src/gallium/drivers/i965simple/brw_vs.c index 738c6346d5..92327e896d 100644 --- a/src/gallium/drivers/i965simple/brw_vs.c +++ b/src/gallium/drivers/i965simple/brw_vs.c @@ -50,8 +50,8 @@ static void do_vs_prog( struct brw_context *brw, brw_init_compile(&c.func); c.vp = vp; - c.prog_data.outputs_written = vp->program.num_outputs; - c.prog_data.inputs_read = vp->program.num_inputs; + c.prog_data.outputs_written = vp->info.num_outputs; + c.prog_data.inputs_read = vp->info.num_inputs; #if 0 if (c.key.copy_edgeflag) { diff --git a/src/gallium/drivers/i965simple/brw_vs_emit.c b/src/gallium/drivers/i965simple/brw_vs_emit.c index 33bbdc95c6..9020fcc001 100644 --- a/src/gallium/drivers/i965simple/brw_vs_emit.c +++ b/src/gallium/drivers/i965simple/brw_vs_emit.c @@ -86,7 +86,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c, /* Allocate input regs: */ - c->nr_inputs = c->vp->program.num_inputs; + c->nr_inputs = c->vp->info.num_inputs; for (i = 0; i < c->nr_inputs; i++) { c->regs[TGSI_FILE_INPUT][i] = brw_vec8_grf(reg, 0); reg++; @@ -99,7 +99,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c, c->nr_outputs = 0; c->first_output = reg; mrf = 4; - for (i = 0; i < c->vp->program.num_outputs; i++) { + for (i = 0; i < c->vp->info.num_outputs; i++) { c->nr_outputs++; #if 0 if (i == VERT_RESULT_HPOS) { diff --git a/src/gallium/drivers/i965simple/brw_wm_decl.c b/src/gallium/drivers/i965simple/brw_wm_decl.c index b50d768062..74ccfd494a 100644 --- a/src/gallium/drivers/i965simple/brw_wm_decl.c +++ b/src/gallium/drivers/i965simple/brw_wm_decl.c @@ -292,7 +292,7 @@ static void prealloc_reg(struct brw_wm_compile *c) } c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2; - c->prog_data.urb_read_length = (c->fp->program.num_inputs + 1) * 2; + c->prog_data.urb_read_length = (c->fp->info.num_inputs + 1) * 2; c->prog_data.curb_read_length = nr_curbe_regs; /* That's the end of the payload, now we can start allocating registers. -- cgit v1.2.3 From 1774b177b858f9f87d00e54b0bf00e9634e375e9 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 18:46:54 -0700 Subject: gallium: added draw_num_vs_outputs() to query number of post-transform vertex attribs --- src/gallium/auxiliary/draw/draw_context.c | 13 +++++++++++++ src/gallium/auxiliary/draw/draw_context.h | 4 ++++ src/gallium/drivers/softpipe/sp_state_derived.c | 4 ++-- 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 64ada8ce04..3500c34811 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -281,6 +281,19 @@ draw_find_vs_output(struct draw_context *draw, } +/** + * Return number of vertex shader outputs. + */ +uint +draw_num_vs_outputs(struct draw_context *draw) +{ + uint count = draw->vertex_shader->info.num_outputs; + if (draw->extra_vp_outputs.slot >= 0) + count++; + return count; +} + + /** * Allocate space for temporary post-transform vertices, such as for clipping. */ diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index d6685f479b..99bfef55f4 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -112,6 +112,10 @@ int draw_find_vs_output(struct draw_context *draw, uint semantic_name, uint semantic_index); +uint +draw_num_vs_outputs(struct draw_context *draw); + + /* * Vertex shader functions diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index aa6e329116..eafbaed4b9 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -61,7 +61,6 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) if (vinfo->num_attribs == 0) { /* compute vertex layout now */ - const struct pipe_shader_state *vs = &softpipe->vs->shader; const struct sp_fragment_shader *spfs = softpipe->fs; const enum interp_mode colorInterp = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; @@ -74,7 +73,8 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; vinfo_vbuf->num_attribs = 0; draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0); - vinfo_vbuf->size = 4 * vs->num_outputs + /* size in dwords or floats */ + vinfo_vbuf->size = 4 * draw_num_vs_outputs(softpipe->draw) + sizeof(struct vertex_header) / 4; } -- cgit v1.2.3 From d8bf051c8b4a1ebe44895413a109d4ab898f7579 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 27 Feb 2008 18:49:35 -0700 Subject: gallium: remove unneeded pipe ptr from pipe_texture --- src/gallium/include/pipe/p_state.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index bb4a6cb23e..5fab41acbd 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -161,6 +161,7 @@ struct pipe_constant_buffer struct pipe_shader_state { const struct tgsi_token *tokens; + /* XXX these are going away */ ubyte num_inputs; ubyte num_outputs; ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */ @@ -276,8 +277,7 @@ struct pipe_surface /** - * Texture. Represents one or several texture images on one or several mipmap - * levels. + * Texture object. */ struct pipe_texture { @@ -298,11 +298,7 @@ struct pipe_texture */ unsigned refcount; - /**< pipe that created the texture - * XXX this'll change to a pipe_winsys (or pipe_screen)... - */ - struct pipe_context *pipe; - struct pipe_screen *screen; + struct pipe_screen *screen; /**< screen that this texture belongs to */ }; -- cgit v1.2.3 From 510bc3535c4af68db71e5ffd19f3e21e10ec6004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 28 Feb 2008 11:23:01 +0900 Subject: gallium: Fix sign/unsign comparison. --- src/gallium/auxiliary/tgsi/util/tgsi_scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c index b7bbff1689..cf6de1e82f 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c @@ -100,7 +100,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens, /* only first 32 regs will appear in this bitfield */ info->file_mask[file] |= (1 << i); info->file_count[file]++; - info->file_max[file] = MAX2(info->file_max[file], i); + info->file_max[file] = MAX2(info->file_max[file], (int)i); if (file == TGSI_FILE_INPUT) { info->input_semantic_name[info->num_inputs] -- cgit v1.2.3 From 5c0a089a5d13baa7a427b70852223990da5f175c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 28 Feb 2008 13:52:30 +0900 Subject: gallium: Remove extra level of indirecttion. --- src/gallium/drivers/softpipe/sp_prim_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 5c8b0bf69c..2feee5c485 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -1163,7 +1163,7 @@ static void setup_begin( struct draw_stage *stage ) { struct setup_stage *setup = setup_stage(stage); struct softpipe_context *sp = setup->softpipe; - const struct sp_fragment_shader *fs = &setup->softpipe->fs; + const struct sp_fragment_shader *fs = setup->softpipe->fs; if (sp->dirty) { softpipe_update_derived(sp); -- cgit v1.2.3 From 626b8d177b5fdacfac70c09216c02b1c833b91ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 28 Feb 2008 09:07:38 +0000 Subject: Make sure struct pipe_screen is declared. --- src/gallium/drivers/softpipe/sp_winsys.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h index 80f5354808..fc372dba27 100644 --- a/src/gallium/drivers/softpipe/sp_winsys.h +++ b/src/gallium/drivers/softpipe/sp_winsys.h @@ -46,6 +46,7 @@ struct softpipe_winsys { }; +struct pipe_screen; struct pipe_winsys; struct pipe_context; -- cgit v1.2.3 From e280bd50cc46ddbf5ac7fbaafc934d1048d77ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 28 Feb 2008 21:25:54 +0900 Subject: gallium: Fix MSVC warnings. --- src/gallium/auxiliary/tgsi/util/tgsi_scan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c index cf6de1e82f..ea4a72967d 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c @@ -104,17 +104,17 @@ tgsi_scan_shader(const struct tgsi_token *tokens, if (file == TGSI_FILE_INPUT) { info->input_semantic_name[info->num_inputs] - = fulldecl->Semantic.SemanticName; + = (ubyte)fulldecl->Semantic.SemanticName; info->input_semantic_index[info->num_inputs] - = fulldecl->Semantic.SemanticIndex; + = (ubyte)fulldecl->Semantic.SemanticIndex; info->num_inputs++; } if (file == TGSI_FILE_OUTPUT) { info->output_semantic_name[info->num_outputs] - = fulldecl->Semantic.SemanticName; + = (ubyte)fulldecl->Semantic.SemanticName; info->output_semantic_index[info->num_outputs] - = fulldecl->Semantic.SemanticIndex; + = (ubyte)fulldecl->Semantic.SemanticIndex; info->num_outputs++; } -- cgit v1.2.3 From a1a13954885cd469faab49633b5386e5c889e3df Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 28 Feb 2008 17:49:22 -0700 Subject: gallium: split draw_wide_prim stage into separate point/line stages. This fixes a validation/code-path problem. Enabling the stage for the sake of wide points also inadvertantly caused wide lines to be converted to tris when we actually want them passed through, such as for the AA line stage. This is just cleaner now. Also, replace draw_convert_wide_lines() with draw_wide_line_threshold() as was done for points. Allows for 1-pixel lines to be converted too if needed. --- src/gallium/auxiliary/draw/Makefile | 4 +++- src/gallium/auxiliary/draw/SConscript | 3 ++- src/gallium/auxiliary/draw/draw_context.c | 17 ++++++++++------- src/gallium/auxiliary/draw/draw_context.h | 4 +--- src/gallium/auxiliary/draw/draw_private.h | 8 +++++--- src/gallium/auxiliary/draw/draw_validate.c | 16 +++++++++------- 6 files changed, 30 insertions(+), 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index c9980f0b83..2daa1636f3 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -29,7 +29,9 @@ C_SOURCES = \ draw_vf.c \ draw_vf_generic.c \ draw_vf_sse.c \ - draw_wide_prims.c + draw_wide_line.c \ + draw_wide_point.c + include ../../Makefile.template diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 3302dc44f7..c18dcb2927 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -28,7 +28,8 @@ draw = env.ConvenienceLibrary( 'draw_vf.c', 'draw_vf_generic.c', 'draw_vf_sse.c', - 'draw_wide_prims.c', + 'draw_wide_point.c', + 'draw_wide_line.c' ]) auxiliaries.insert(0, draw) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 3500c34811..428b6209e0 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -48,7 +48,8 @@ struct draw_context *draw_create( void ) #endif /* create pipeline stages */ - draw->pipeline.wide = draw_wide_stage( draw ); + draw->pipeline.wide_line = draw_wide_line_stage( draw ); + draw->pipeline.wide_point = draw_wide_point_stage( draw ); draw->pipeline.stipple = draw_stipple_stage( draw ); draw->pipeline.unfilled = draw_unfilled_stage( draw ); draw->pipeline.twoside = draw_twoside_stage( draw ); @@ -80,8 +81,9 @@ struct draw_context *draw_create( void ) draw->shader_queue_flush = draw_vertex_shader_queue_flush; + /* these defaults are oriented toward the needs of softpipe */ draw->wide_point_threshold = 1000000.0; /* infinity */ - draw->convert_wide_lines = TRUE; + draw->wide_line_threshold = 1.0; draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ @@ -94,7 +96,8 @@ struct draw_context *draw_create( void ) void draw_destroy( struct draw_context *draw ) { - draw->pipeline.wide->destroy( draw->pipeline.wide ); + draw->pipeline.wide_line->destroy( draw->pipeline.wide_line ); + draw->pipeline.wide_point->destroy( draw->pipeline.wide_point ); draw->pipeline.stipple->destroy( draw->pipeline.stipple ); draw->pipeline.unfilled->destroy( draw->pipeline.unfilled ); draw->pipeline.twoside->destroy( draw->pipeline.twoside ); @@ -232,14 +235,14 @@ draw_wide_point_threshold(struct draw_context *draw, float threshold) /** - * Tells the draw module whether to convert wide lines (width != 1) - * into triangles. + * Tells the draw module to draw lines with triangles if their width + * is greater than this threshold. */ void -draw_convert_wide_lines(struct draw_context *draw, boolean enable) +draw_wide_line_threshold(struct draw_context *draw, float threshold) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->convert_wide_lines = enable; + draw->wide_line_threshold = threshold; } diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 99bfef55f4..ab87b4127c 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -92,9 +92,7 @@ void draw_set_rasterize_stage( struct draw_context *draw, void draw_wide_point_threshold(struct draw_context *draw, float threshold); -void draw_convert_wide_points(struct draw_context *draw, boolean enable); - -void draw_convert_wide_lines(struct draw_context *draw, boolean enable); +void draw_wide_line_threshold(struct draw_context *draw, float threshold); boolean draw_use_sse(struct draw_context *draw); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index e988e71d23..c732d723a7 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -186,7 +186,8 @@ struct draw_context struct draw_stage *aapoint; struct draw_stage *aaline; struct draw_stage *pstipple; - struct draw_stage *wide; + struct draw_stage *wide_line; + struct draw_stage *wide_point; struct draw_stage *rasterize; } pipeline; @@ -219,7 +220,7 @@ struct draw_context unsigned nr_planes; float wide_point_threshold; /**< convert pnts to tris if larger than this */ - boolean convert_wide_lines; /**< convert wide lines to tris? */ + float wide_line_threshold; /**< convert lines to tris if wider than this */ boolean use_sse; /* If a prim stage introduces new vertex attributes, they'll be stored here @@ -304,7 +305,8 @@ extern struct draw_stage *draw_clip_stage( struct draw_context *context ); extern struct draw_stage *draw_flatshade_stage( struct draw_context *context ); extern struct draw_stage *draw_cull_stage( struct draw_context *context ); extern struct draw_stage *draw_stipple_stage( struct draw_context *context ); -extern struct draw_stage *draw_wide_stage( struct draw_context *context ); +extern struct draw_stage *draw_wide_line_stage( struct draw_context *context ); +extern struct draw_stage *draw_wide_point_stage( struct draw_context *context ); extern struct draw_stage *draw_validate_stage( struct draw_context *context ); diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index ded7d10c08..084eee9b6e 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -53,8 +53,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) stage->next = next; /* drawing wide lines? */ - wide_lines = (draw->rasterizer->line_width != 1.0 - && draw->convert_wide_lines + wide_lines = (draw->rasterizer->line_width > draw->wide_line_threshold && !draw->rasterizer->line_smooth); /* drawing large points? */ @@ -82,11 +81,14 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) next = draw->pipeline.aapoint; } - if (wide_lines || - wide_points || - draw->rasterizer->point_sprite) { - draw->pipeline.wide->next = next; - next = draw->pipeline.wide; + if (wide_lines) { + draw->pipeline.wide_line->next = next; + next = draw->pipeline.wide_line; + } + + if (wide_points || draw->rasterizer->point_sprite) { + draw->pipeline.wide_point->next = next; + next = draw->pipeline.wide_point; } if (draw->rasterizer->line_stipple_enable) { -- cgit v1.2.3 From b233b1e2dc2fca2f45b3cb5df167e3675b8cc1fb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 28 Feb 2008 17:54:42 -0700 Subject: gallium: new wide point/line stages (missed in prev commit) --- src/gallium/auxiliary/draw/draw_wide_line.c | 187 +++++++++++++++++++ src/gallium/auxiliary/draw/draw_wide_point.c | 257 +++++++++++++++++++++++++++ 2 files changed, 444 insertions(+) create mode 100644 src/gallium/auxiliary/draw/draw_wide_line.c create mode 100644 src/gallium/auxiliary/draw/draw_wide_point.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_wide_line.c b/src/gallium/auxiliary/draw/draw_wide_line.c new file mode 100644 index 0000000000..946a983f00 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_wide_line.c @@ -0,0 +1,187 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +struct wideline_stage { + struct draw_stage stage; + + float half_line_width; +}; + + + +static INLINE struct wideline_stage *wideline_stage( struct draw_stage *stage ) +{ + return (struct wideline_stage *)stage; +} + + +static void wideline_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void wideline_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw a wide line by drawing a quad (two triangles). + * XXX need to disable polygon stipple. + */ +static void wideline_line( struct draw_stage *stage, + struct prim_header *header ) +{ + /*const struct wideline_stage *wide = wideline_stage(stage);*/ + const float half_width = 0.5f * stage->draw->rasterizer->line_width; + + struct prim_header tri; + + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + const float dx = FABSF(pos0[0] - pos2[0]); + const float dy = FABSF(pos0[1] - pos2[1]); + + /* + * Draw wide line as a quad (two tris) by "stretching" the line along + * X or Y. + * We need to tweak coords in several ways to be conformant here. + */ + + if (dx > dy) { + /* x-major line */ + pos0[1] = pos0[1] - half_width - 0.25f; + pos1[1] = pos1[1] + half_width - 0.25f; + pos2[1] = pos2[1] - half_width - 0.25f; + pos3[1] = pos3[1] + half_width - 0.25f; + if (pos0[0] < pos2[0]) { + /* left to right line */ + pos0[0] -= 0.5f; + pos1[0] -= 0.5f; + pos2[0] -= 0.5f; + pos3[0] -= 0.5f; + } + else { + /* right to left line */ + pos0[0] += 0.5f; + pos1[0] += 0.5f; + pos2[0] += 0.5f; + pos3[0] += 0.5f; + } + } + else { + /* y-major line */ + pos0[0] = pos0[0] - half_width + 0.25f; + pos1[0] = pos1[0] + half_width + 0.25f; + pos2[0] = pos2[0] - half_width + 0.25f; + pos3[0] = pos3[0] + half_width + 0.25f; + if (pos0[1] < pos2[1]) { + /* top to bottom line */ + pos0[1] -= 0.5f; + pos1[1] -= 0.5f; + pos2[1] -= 0.5f; + pos3[1] -= 0.5f; + } + else { + /* bottom to top line */ + pos0[1] += 0.5f; + pos1[1] += 0.5f; + pos2[1] += 0.5f; + pos3[1] += 0.5f; + } + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +static void wideline_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->next->flush( stage->next, flags ); +} + + +static void wideline_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void wideline_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +struct draw_stage *draw_wide_line_stage( struct draw_context *draw ) +{ + struct wideline_stage *wide = CALLOC_STRUCT(wideline_stage); + + draw_alloc_temp_verts( &wide->stage, 4 ); + + wide->stage.draw = draw; + wide->stage.next = NULL; + wide->stage.point = wideline_point; + wide->stage.line = wideline_line; + wide->stage.tri = wideline_tri; + wide->stage.flush = wideline_flush; + wide->stage.reset_stipple_counter = wideline_reset_stipple_counter; + wide->stage.destroy = wideline_destroy; + + return &wide->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c new file mode 100644 index 0000000000..8f877a102a --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_wide_point.c @@ -0,0 +1,257 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +struct widepoint_stage { + struct draw_stage stage; + + float half_point_size; + + uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; + uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; + uint num_texcoords; + + int psize_slot; +}; + + + +static INLINE struct widepoint_stage * +widepoint_stage( struct draw_stage *stage ) +{ + return (struct widepoint_stage *)stage; +} + + +static void passthrough_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + +static void widepoint_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line(stage->next, header); +} + +static void widepoint_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Set the vertex texcoords for sprite mode. + * Coords may be left untouched or set to a right-side-up or upside-down + * orientation. + */ +static void set_texcoords(const struct widepoint_stage *wide, + struct vertex_header *v, const float tc[4]) +{ + uint i; + for (i = 0; i < wide->num_texcoords; i++) { + if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { + uint j = wide->texcoord_slot[i]; + v->data[j][0] = tc[0]; + if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) + v->data[j][1] = 1.0f - tc[1]; + else + v->data[j][1] = tc[1]; + v->data[j][2] = tc[2]; + v->data[j][3] = tc[3]; + } + } +} + + +/* If there are lots of sprite points (and why wouldn't there be?) it + * would probably be more sensible to change hardware setup to + * optimize this rather than doing the whole thing in software like + * this. + */ +static void widepoint_point( struct draw_stage *stage, + struct prim_header *header ) +{ + const struct widepoint_stage *wide = widepoint_stage(stage); + const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; + float half_size; + float left_adj, right_adj; + + struct prim_header tri; + + /* four dups of original vertex */ + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + /* point size is either per-vertex or fixed size */ + if (wide->psize_slot >= 0) { + half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; + } + else { + half_size = wide->half_point_size; + } + + left_adj = -half_size; /* + 0.25f;*/ + right_adj = half_size; /* + 0.25f;*/ + + pos0[0] += left_adj; + pos0[1] -= half_size; + + pos1[0] += left_adj; + pos1[1] += half_size; + + pos2[0] += right_adj; + pos2[1] -= half_size; + + pos3[0] += right_adj; + pos3[1] += half_size; + + if (sprite) { + static const float tex00[4] = { 0, 0, 0, 1 }; + static const float tex01[4] = { 0, 1, 0, 1 }; + static const float tex11[4] = { 1, 1, 0, 1 }; + static const float tex10[4] = { 1, 0, 0, 1 }; + set_texcoords( wide, v0, tex00 ); + set_texcoords( wide, v1, tex01 ); + set_texcoords( wide, v2, tex10 ); + set_texcoords( wide, v3, tex11 ); + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +static void widepoint_first_point( struct draw_stage *stage, + struct prim_header *header ) +{ + struct widepoint_stage *wide = widepoint_stage(stage); + struct draw_context *draw = stage->draw; + + wide->half_point_size = 0.5f * draw->rasterizer->point_size; + + /* XXX we won't know the real size if it's computed by the vertex shader! */ + if (draw->rasterizer->point_size > draw->wide_point_threshold) { + stage->point = widepoint_point; + } + else { + stage->point = passthrough_point; + } + + if (draw->rasterizer->point_sprite) { + /* find vertex shader texcoord outputs */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i, j = 0; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { + wide->texcoord_slot[j] = i; + wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; + j++; + } + } + wide->num_texcoords = j; + } + + wide->psize_slot = -1; + if (draw->rasterizer->point_size_per_vertex) { + /* find PSIZ vertex output */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + wide->psize_slot = i; + break; + } + } + } + + stage->point( stage, header ); +} + + +static void widepoint_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->point = widepoint_first_point; + stage->next->flush( stage->next, flags ); +} + + +static void widepoint_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void widepoint_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +struct draw_stage *draw_wide_point_stage( struct draw_context *draw ) +{ + struct widepoint_stage *wide = CALLOC_STRUCT(widepoint_stage); + + draw_alloc_temp_verts( &wide->stage, 4 ); + + wide->stage.draw = draw; + wide->stage.next = NULL; + wide->stage.point = widepoint_first_point; + wide->stage.line = widepoint_line; + wide->stage.tri = widepoint_tri; + wide->stage.flush = widepoint_flush; + wide->stage.reset_stipple_counter = widepoint_reset_stipple_counter; + wide->stage.destroy = widepoint_destroy; + + return &wide->stage; +} -- cgit v1.2.3 From 6144c2bd65974f4e5b74936e26451a1ad75cb349 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 28 Feb 2008 17:57:54 -0700 Subject: cell: remove obsolete texture field --- src/gallium/drivers/cell/ppu/cell_texture.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index bf6f6d3058..e235421107 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -90,7 +90,6 @@ cell_texture_create_screen(struct pipe_screen *screen, spt->base = *templat; spt->base.refcount = 1; - spt->base.pipe = NULL; spt->base.screen = screen; cell_texture_layout(spt); -- cgit v1.2.3 From ebe3b34ad225e320a09bb4069ce4d24808386327 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 28 Feb 2008 18:02:05 -0700 Subject: cell: convert all points/lines to tris for the time being Allows more programs to look correct. We'll want native points/lines someday. --- src/gallium/drivers/cell/ppu/cell_context.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index 2301df5ba5..ccbbd1d331 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -128,6 +128,10 @@ cell_create_context(struct pipe_screen *screen, cell_init_vbuf(cell); draw_set_rasterize_stage(cell->draw, cell->vbuf); + /* convert all points/lines to tris for the time being */ + draw_wide_point_threshold(cell->draw, 0.0); + draw_wide_line_threshold(cell->draw, 0.0); + /* * SPU stuff */ -- cgit v1.2.3 From 78220aea864c36038f8425ad9d8467d2a2bdea58 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 29 Feb 2008 10:07:44 -0700 Subject: gallium: remove the ugly pipe->draw stage lookup code in aaline/point/pstipple stages Added a void *draw ptr to pipe_context. Probably look for a better solution someday. --- src/gallium/auxiliary/draw/draw_aaline.c | 32 ++++-------------------------- src/gallium/auxiliary/draw/draw_aapoint.c | 32 ++++-------------------------- src/gallium/auxiliary/draw/draw_pstipple.c | 32 ++++-------------------------- src/gallium/include/pipe/p_context.h | 1 + 4 files changed, 13 insertions(+), 84 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index 51140388f0..7660e56fe6 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -691,35 +691,11 @@ draw_aaline_stage(struct draw_context *draw) } -/* - * XXX temporary? solution to mapping a pipe_context to a aaline_stage. - */ - -#define MAX_CONTEXTS 10 - -static struct pipe_context *Pipe[MAX_CONTEXTS]; -static struct aaline_stage *Stage[MAX_CONTEXTS]; -static uint NumContexts; - -static void -add_aa_pipe_context(struct pipe_context *pipe, struct aaline_stage *aa) -{ - assert(NumContexts < MAX_CONTEXTS); - Pipe[NumContexts] = pipe; - Stage[NumContexts] = aa; - NumContexts++; -} - static struct aaline_stage * aaline_stage_from_pipe(struct pipe_context *pipe) { - uint i; - for (i = 0; i < NumContexts; i++) { - if (Pipe[i] == pipe) - return Stage[i]; - } - assert(0); - return NULL; + struct draw_context *draw = (struct draw_context *) pipe->draw; + return aaline_stage(draw->pipeline.aaline); } @@ -802,6 +778,8 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) { struct aaline_stage *aaline; + pipe->draw = (void *) draw; + /* * Create / install AA line drawing / prim stage */ @@ -830,6 +808,4 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) pipe->bind_sampler_state = aaline_bind_sampler_state; pipe->set_sampler_texture = aaline_set_sampler_texture; - - add_aa_pipe_context(pipe, aaline); } diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c index d48a416899..70f696475f 100644 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -762,35 +762,11 @@ draw_aapoint_stage(struct draw_context *draw) } -/* - * XXX temporary? solution to mapping a pipe_context to a aapoint_stage. - */ - -#define MAX_CONTEXTS 10 - -static struct pipe_context *Pipe[MAX_CONTEXTS]; -static struct aapoint_stage *Stage[MAX_CONTEXTS]; -static uint NumContexts; - -static void -add_aa_pipe_context(struct pipe_context *pipe, struct aapoint_stage *aa) -{ - assert(NumContexts < MAX_CONTEXTS); - Pipe[NumContexts] = pipe; - Stage[NumContexts] = aa; - NumContexts++; -} - static struct aapoint_stage * aapoint_stage_from_pipe(struct pipe_context *pipe) { - uint i; - for (i = 0; i < NumContexts; i++) { - if (Pipe[i] == pipe) - return Stage[i]; - } - assert(0); - return NULL; + struct draw_context *draw = (struct draw_context *) pipe->draw; + return aapoint_stage(draw->pipeline.aapoint); } @@ -850,6 +826,8 @@ draw_install_aapoint_stage(struct draw_context *draw, { struct aapoint_stage *aapoint; + pipe->draw = (void *) draw; + /* * Create / install AA point drawing / prim stage */ @@ -868,6 +846,4 @@ draw_install_aapoint_stage(struct draw_context *draw, pipe->create_fs_state = aapoint_create_fs_state; pipe->bind_fs_state = aapoint_bind_fs_state; pipe->delete_fs_state = aapoint_delete_fs_state; - - add_aa_pipe_context(pipe, aapoint); } diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index f6200aa820..2cfeb813b3 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -559,35 +559,11 @@ draw_pstip_stage(struct draw_context *draw) } -/* - * XXX temporary? solution to mapping a pipe_context to a pstip_stage. - */ - -#define MAX_CONTEXTS 10 - -static struct pipe_context *Pipe[MAX_CONTEXTS]; -static struct pstip_stage *Stage[MAX_CONTEXTS]; -static uint NumContexts; - -static void -add_pstip_pipe_context(struct pipe_context *pipe, struct pstip_stage *pstip) -{ - assert(NumContexts < MAX_CONTEXTS); - Pipe[NumContexts] = pipe; - Stage[NumContexts] = pstip; - NumContexts++; -} - static struct pstip_stage * pstip_stage_from_pipe(struct pipe_context *pipe) { - uint i; - for (i = 0; i < NumContexts; i++) { - if (Pipe[i] == pipe) - return Stage[i]; - } - assert(0); - return NULL; + struct draw_context *draw = (struct draw_context *) pipe->draw; + return pstip_stage(draw->pipeline.pstipple); } @@ -686,6 +662,8 @@ draw_install_pstipple_stage(struct draw_context *draw, { struct pstip_stage *pstip; + pipe->draw = (void *) draw; + /* * Create / install AA line drawing / prim stage */ @@ -716,6 +694,4 @@ draw_install_pstipple_stage(struct draw_context *draw, pipe->bind_sampler_state = pstip_bind_sampler_state; pipe->set_sampler_texture = pstip_set_sampler_texture; pipe->set_polygon_stipple = pstip_set_polygon_stipple; - - add_pstip_pipe_context(pipe, pstip); } diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index d0f25d7d46..1501b52f3e 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -56,6 +56,7 @@ struct pipe_context { struct pipe_screen *screen; void *priv; /** context private data (for DRI for example) */ + void *draw; /** private, for draw module (temporary? */ void (*destroy)( struct pipe_context * ); -- cgit v1.2.3 From a41b77f4fedc7d956d8cb44547d812b5449f8641 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 29 Feb 2008 11:09:02 -0700 Subject: gallium: added pipe_get/put_tile_z() functions --- src/gallium/auxiliary/util/p_tile.c | 124 ++++++++++++++++++++++++++++++++++++ src/gallium/auxiliary/util/p_tile.h | 14 ++++ 2 files changed, 138 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 3f795a3898..287d783981 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -697,3 +697,127 @@ pipe_put_tile_rgba(struct pipe_context *pipe, FREE(packed); } + + +/** + * Get a block of Z values, converted to 32-bit range. + */ +void +pipe_get_tile_z(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + uint *z) +{ + const uint dstStride = w; + uint *pDest = z; + uint i, j; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + switch (ps->format) { + case PIPE_FORMAT_Z32_UNORM: + { + const uint *pSrc + = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + for (i = 0; i < h; i++) { + memcpy(pDest, pSrc, 4 * w); + pDest += dstStride; + pSrc += ps->pitch; + } + } + break; + case PIPE_FORMAT_S8Z24_UNORM: + { + const uint *pSrc + = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + /* convert 24-bit Z to 32-bit Z */ + pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff); + } + pDest += dstStride; + pSrc += ps->pitch; + } + } + break; + case PIPE_FORMAT_Z16_UNORM: + { + const ushort *pSrc + = (const ushort *) pipe_surface_map(ps) + (y * ps->pitch + x); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + /* convert 16-bit Z to 32-bit Z */ + pDest[j] = (pSrc[j] << 16) | pSrc[j]; + } + pDest += dstStride; + pSrc += ps->pitch; + } + } + break; + default: + assert(0); + } + + pipe_surface_unmap(ps); +} + + +void +pipe_put_tile_z(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const uint *zSrc) +{ + const uint srcStride = w; + const uint *pSrc = zSrc; + uint i, j; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + switch (ps->format) { + case PIPE_FORMAT_Z32_UNORM: + { + uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + for (i = 0; i < h; i++) { + memcpy(pDest, pSrc, 4 * w); + pDest += ps->pitch; + pSrc += srcStride; + } + } + break; + case PIPE_FORMAT_S8Z24_UNORM: + { + uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + /* convert 32-bit Z to 24-bit Z (0 stencil) */ + pDest[j] = pSrc[j] >> 8; + } + pDest += ps->pitch; + pSrc += srcStride; + } + } + break; + case PIPE_FORMAT_Z16_UNORM: + { + ushort *pDest = (ushort *) pipe_surface_map(ps) + (y * ps->pitch + x); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + /* convert 32-bit Z to 16-bit Z */ + pDest[j] = pSrc[j] >> 16; + } + pDest += ps->pitch; + pSrc += srcStride; + } + } + break; + default: + assert(0); + } + + pipe_surface_unmap(ps); +} + + diff --git a/src/gallium/auxiliary/util/p_tile.h b/src/gallium/auxiliary/util/p_tile.h index cd8124bf11..318b6d11a6 100644 --- a/src/gallium/auxiliary/util/p_tile.h +++ b/src/gallium/auxiliary/util/p_tile.h @@ -78,4 +78,18 @@ pipe_put_tile_rgba(struct pipe_context *pipe, uint x, uint y, uint w, uint h, const float *p); + +extern void +pipe_get_tile_z(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + uint *z); + +extern void +pipe_put_tile_z(struct pipe_context *pipe, + struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const uint *z); + + #endif -- cgit v1.2.3 From 2a121e8e2289d2ca136f511c5a6ef049f9c99ec4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 29 Feb 2008 11:37:12 -0700 Subject: gallium: tweak coords for wide lines --- src/gallium/auxiliary/draw/draw_wide_line.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_wide_line.c b/src/gallium/auxiliary/draw/draw_wide_line.c index 946a983f00..9a168ce8bd 100644 --- a/src/gallium/auxiliary/draw/draw_wide_line.c +++ b/src/gallium/auxiliary/draw/draw_wide_line.c @@ -86,7 +86,10 @@ static void wideline_line( struct draw_stage *stage, const float dx = FABSF(pos0[0] - pos2[0]); const float dy = FABSF(pos0[1] - pos2[1]); - + + /* small tweak to meet GL specification */ + const float bias = 0.125f; + /* * Draw wide line as a quad (two tris) by "stretching" the line along * X or Y. @@ -95,10 +98,10 @@ static void wideline_line( struct draw_stage *stage, if (dx > dy) { /* x-major line */ - pos0[1] = pos0[1] - half_width - 0.25f; - pos1[1] = pos1[1] + half_width - 0.25f; - pos2[1] = pos2[1] - half_width - 0.25f; - pos3[1] = pos3[1] + half_width - 0.25f; + pos0[1] = pos0[1] - half_width - bias; + pos1[1] = pos1[1] + half_width - bias; + pos2[1] = pos2[1] - half_width - bias; + pos3[1] = pos3[1] + half_width - bias; if (pos0[0] < pos2[0]) { /* left to right line */ pos0[0] -= 0.5f; @@ -116,10 +119,10 @@ static void wideline_line( struct draw_stage *stage, } else { /* y-major line */ - pos0[0] = pos0[0] - half_width + 0.25f; - pos1[0] = pos1[0] + half_width + 0.25f; - pos2[0] = pos2[0] - half_width + 0.25f; - pos3[0] = pos3[0] + half_width + 0.25f; + pos0[0] = pos0[0] - half_width + bias; + pos1[0] = pos1[0] + half_width + bias; + pos2[0] = pos2[0] - half_width + bias; + pos3[0] = pos3[0] + half_width + bias; if (pos0[1] < pos2[1]) { /* top to bottom line */ pos0[1] -= 0.5f; -- cgit v1.2.3 From 4d22330837278574c7f06bdc9e12ffffb659f43d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 29 Feb 2008 10:32:25 +0100 Subject: scons: List sp_screen.c. --- src/gallium/drivers/softpipe/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index 4c1a6d5df0..88c21ee3b0 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -28,6 +28,7 @@ softpipe = env.ConvenienceLibrary( 'sp_quad_stencil.c', 'sp_quad_stipple.c', 'sp_query.c', + 'sp_screen.c', 'sp_state_blend.c', 'sp_state_clip.c', 'sp_state_derived.c', -- cgit v1.2.3 From b8ee90e05a98d5a167c1fdb5a8fc3bc0cb4a6a78 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 29 Feb 2008 12:21:42 -0700 Subject: gallium: need precalc_flat=1 for wide lines --- src/gallium/auxiliary/draw/draw_validate.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index 084eee9b6e..b43295b586 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -84,6 +84,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) if (wide_lines) { draw->pipeline.wide_line->next = next; next = draw->pipeline.wide_line; + precalc_flat = 1; } if (wide_points || draw->rasterizer->point_sprite) { -- cgit v1.2.3 From 6da943d204eeb488895933c45e174042cb69c92d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 29 Feb 2008 12:22:04 -0700 Subject: gallium: point rast coord tweak --- src/gallium/auxiliary/draw/draw_wide_point.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c index 8f877a102a..65bd50f2b8 100644 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_wide_point.c @@ -109,7 +109,7 @@ static void widepoint_point( struct draw_stage *stage, const struct widepoint_stage *wide = widepoint_stage(stage); const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; float half_size; - float left_adj, right_adj; + float left_adj, right_adj, bot_adj, top_adj; struct prim_header tri; @@ -124,6 +124,8 @@ static void widepoint_point( struct draw_stage *stage, float *pos2 = v2->data[0]; float *pos3 = v3->data[0]; + const float xbias = 0.0, ybias = -0.125; + /* point size is either per-vertex or fixed size */ if (wide->psize_slot >= 0) { half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; @@ -132,20 +134,22 @@ static void widepoint_point( struct draw_stage *stage, half_size = wide->half_point_size; } - left_adj = -half_size; /* + 0.25f;*/ - right_adj = half_size; /* + 0.25f;*/ + left_adj = -half_size + xbias; + right_adj = half_size + xbias; + bot_adj = half_size + ybias; + top_adj = -half_size + ybias; pos0[0] += left_adj; - pos0[1] -= half_size; + pos0[1] += top_adj; pos1[0] += left_adj; - pos1[1] += half_size; + pos1[1] += bot_adj; pos2[0] += right_adj; - pos2[1] -= half_size; + pos2[1] += top_adj; pos3[0] += right_adj; - pos3[1] += half_size; + pos3[1] += bot_adj; if (sprite) { static const float tex00[4] = { 0, 0, 0, 1 }; -- cgit v1.2.3 From 5240cebb23f4862f4f7458a1b397957e4460b527 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 29 Feb 2008 13:00:17 -0700 Subject: gallium: fix line emit order for unfilled tris A tri drawn with GL_LINE_LOOP and GL_POLYGON w/ fillmode=GL_LINE should produce the same results when line stipple is enabled. Results are correct now. --- src/gallium/auxiliary/draw/draw_unfilled.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_unfilled.c b/src/gallium/auxiliary/draw/draw_unfilled.c index 8777cfdfc8..4d718d514c 100644 --- a/src/gallium/auxiliary/draw/draw_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_unfilled.c @@ -101,9 +101,9 @@ static void lines( struct draw_stage *stage, assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag); #endif + if (header->edgeflags & 0x4) line( stage, v2, v0 ); if (header->edgeflags & 0x1) line( stage, v0, v1 ); if (header->edgeflags & 0x2) line( stage, v1, v2 ); - if (header->edgeflags & 0x4) line( stage, v2, v0 ); } -- cgit v1.2.3 From e884c7ed9a14aabaa86f6710c594d20812ed11d9 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 1 Mar 2008 08:04:21 -0500 Subject: start implementing start of bultins --- src/gallium/auxiliary/gallivm/Makefile | 7 +- src/gallium/auxiliary/gallivm/instructions.cpp | 10 ++ src/gallium/auxiliary/gallivm/instructionssoa.cpp | 116 ++++++++++++++++++++++ src/gallium/auxiliary/gallivm/instructionssoa.h | 14 ++- src/gallium/auxiliary/gallivm/soabuiltins.c | 58 +++++++++++ src/gallium/auxiliary/gallivm/storagesoa.cpp | 28 +++--- src/gallium/auxiliary/gallivm/storagesoa.h | 15 +-- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 38 ++----- src/gallium/include/pipe/p_shader_tokens.h | 20 ++-- 9 files changed, 239 insertions(+), 67 deletions(-) create mode 100644 src/gallium/auxiliary/gallivm/soabuiltins.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/Makefile b/src/gallium/auxiliary/gallivm/Makefile index 39fac6ea4a..c24e19e062 100644 --- a/src/gallium/auxiliary/gallivm/Makefile +++ b/src/gallium/auxiliary/gallivm/Makefile @@ -15,7 +15,7 @@ GALLIVM_SOURCES = \ storagesoa.cpp \ instructionssoa.cpp -INC_SOURCES = gallivm_builtins.cpp +INC_SOURCES = gallivm_builtins.cpp gallivmsoabuiltins.cpp CPP_SOURCES = \ $(GALLIVM_SOURCES) @@ -65,8 +65,10 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) gallivm_builtins.cpp: llvm_builtins.c - clang --emit-llvm $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins +gallivmsoabuiltins.cpp: soabuiltins.c + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-module -o=$@ -f -for=shader -funcname=createSoaBuiltins # Emacs tags tags: @@ -78,6 +80,7 @@ clean: -rm -f *.o */*.o *~ *.so *~ server/*.o -rm -f depend depend.bak -rm -f gallivm_builtins.cpp + -rm -f gallivmsoabuiltins.cpp symlinks: diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp index 55d39fa5f1..8919491792 100644 --- a/src/gallium/auxiliary/gallivm/instructions.cpp +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,15 @@ using namespace llvm; #include "gallivm_builtins.cpp" +#if 0 + +llvm::Value *arrayFromChannels(std::vector &vals) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + ArrayType *vectorArray = ArrayType::get(vectorType, 4); +} +#endif + static inline std::string createFuncName(int label) { std::ostringstream stream; diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index a4d5046637..5739cf0cde 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -2,9 +2,28 @@ #include "storagesoa.h" +#include "pipe/p_shader_tokens.h" + +#include #include +#include +#include +#include +#include +#include + +#include + +/* disable some warnings. this file is autogenerated */ +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif using namespace llvm; +#include "gallivmsoabuiltins.cpp" +#if defined(__GNUC__) +#pragma GCC diagnostic warning "-Wunused-variable" +#endif InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, StorageSoa *storage) @@ -12,6 +31,8 @@ InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, m_storage(storage), m_idx(0) { + createFunctionMap(); + createBuiltins(); } const char * InstructionsSoa::name(const char *prefix) const @@ -119,3 +140,98 @@ std::vector InstructionsSoa::extractVector(llvm::Value *vector) return res; } + +void InstructionsSoa::createFunctionMap() +{ + m_functionsMap[TGSI_OPCODE_DP3] = "dp3"; +} + +llvm::Function * InstructionsSoa::function(int op) +{ + if (m_functions.find(op) != m_functions.end()) + return m_functions[op]; + + std::string name = m_functionsMap[op]; + + llvm::Function *originalFunc = m_builtins->getFunction(name); + llvm::Function *func = CloneFunction(originalFunc); + currentModule()->getFunctionList().push_back(func); + std::cout << "Func parent is "<getParent() + <<", cur is "<setParent(currentModule()); + m_functions[op] = func; + return func; +} + +llvm::Module * InstructionsSoa::currentModule() const +{ + BasicBlock *block = m_builder.GetInsertBlock(); + if (!block || !block->getParent()) + return 0; + + return block->getParent()->getParent(); +} + +void InstructionsSoa::createBuiltins() +{ + m_builtins = createSoaBuiltins(); +} + +std::vector InstructionsSoa::dp3(const std::vector in1, + const std::vector in2) +{ + llvm::Function *func = function(TGSI_OPCODE_DP3); + std::vector params; + + llvm::Value *tmp = allocaTemp(); + params.push_back(tmp); + + params.push_back(in1[0]); + params.push_back(in1[1]); + params.push_back(in1[2]); + params.push_back(in1[3]); + params.push_back(in2[0]); + params.push_back(in2[1]); + params.push_back(in2[2]); + params.push_back(in2[3]); + CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), + name("dp3")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + + std::vector indices; + indices.push_back(m_storage->constantInt(0)); + indices.push_back(m_storage->constantInt(0)); + + GetElementPtrInst *getElem = new GetElementPtrInst(tmp, + indices.begin(), + indices.end(), + name("allocaPtr"), + m_builder.GetInsertBlock()); + indices = std::vector(); + indices.push_back(m_storage->constantInt(0)); + GetElementPtrInst *xElemPtr = new GetElementPtrInst(getElem, + m_storage->constantInt(0), + name("xPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *yElemPtr = new GetElementPtrInst(getElem, + m_storage->constantInt(1), + name("yPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *zElemPtr = new GetElementPtrInst(getElem, + m_storage->constantInt(2), + name("zPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *wElemPtr = new GetElementPtrInst(getElem, + m_storage->constantInt(3), + name("wPtr"), + m_builder.GetInsertBlock()); + + std::vector res(4); + res[0] = new LoadInst(xElemPtr); + res[1] = new LoadInst(yElemPtr); + res[2] = new LoadInst(zElemPtr); + res[3] = new LoadInst(wElemPtr); + + return res; +} diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h index 4169dcbb2e..5c26687150 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -30,6 +30,7 @@ #include +#include #include namespace llvm { @@ -47,9 +48,10 @@ public: llvm::BasicBlock *block, StorageSoa *storage); std::vector arl(const std::vector in); - std::vector add(const std::vector in1, const std::vector in2); + std::vector dp3(const std::vector in1, + const std::vector in2); std::vector madd(const std::vector in1, const std::vector in2, const std::vector in3); @@ -62,9 +64,19 @@ private: const char * name(const char *prefix) const; llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, llvm::Value *z, llvm::Value *w); + void createFunctionMap(); + void createBuiltins(); + llvm::Function *function(int); + llvm::Module *currentModule() const; + llvm::Value *allocaTemp(); private: llvm::LLVMFoldingBuilder m_builder; StorageSoa *m_storage; + + std::map m_functionsMap; + std::map m_functions; + llvm::Module *m_builtins; + private: mutable int m_idx; mutable char m_name[32]; diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c new file mode 100644 index 0000000000..0b428a750f --- /dev/null +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * This file is compiled with clang into the LLVM bitcode + * + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +typedef __attribute__(( ocu_vector_type(4) )) float float4; + +void dp3(float4 *res, + float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, + float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) +{ + float4 dot = (tmp0x * tmp1x) + (tmp0y * tmp1y) + + (tmp0z * tmp1z); + + res[0] = dot; + res[1] = dot; + res[2] = dot; + res[3] = dot; +} + +#if 0 +void yo(float4 *out, float4 *in) +{ + float4 res[4]; + + dp3(res, in[0], in[1], in[2], in[3], + in[4], in[5], in[6], in[7]); + out[1] = res[1]; +} +#endif diff --git a/src/gallium/auxiliary/gallivm/storagesoa.cpp b/src/gallium/auxiliary/gallivm/storagesoa.cpp index ed0674a96f..bb6fe3d7e1 100644 --- a/src/gallium/auxiliary/gallivm/storagesoa.cpp +++ b/src/gallium/auxiliary/gallivm/storagesoa.cpp @@ -277,7 +277,7 @@ llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &v return constVector; } -std::vector StorageSoa::load(Argument type, int idx, int swizzle, +std::vector StorageSoa::load(enum tgsi_file_type type, int idx, int swizzle, llvm::Value *indIdx) { std::vector val(4); @@ -292,25 +292,29 @@ std::vector StorageSoa::load(Argument type, int idx, int swizzle, debug_printf("XXXXXXXXX realIdx = %p, indIdx = %p\n", realIndex, indIdx); switch(type) { - case Input: + case TGSI_FILE_INPUT: val = inputElement(realIndex); break; - case Output: + case TGSI_FILE_OUTPUT: val = outputElement(realIndex); break; - case Temp: + case TGSI_FILE_TEMPORARY: val = tempElement(realIndex); break; - case Const: + case TGSI_FILE_CONSTANT: val = constElement(realIndex); break; - case Immediate: + case TGSI_FILE_IMMEDIATE: val = immediateElement(realIndex); break; - case Address: + case TGSI_FILE_ADDRESS: debug_printf("Address not handled in the load phase!\n"); assert(0); break; + default: + debug_printf("Unknown load!\n"); + assert(0); + break; } if (!gallivm_is_swizzle(swizzle)) return val; @@ -324,21 +328,21 @@ std::vector StorageSoa::load(Argument type, int idx, int swizzle, return res; } -void StorageSoa::store(Argument type, int idx, const std::vector &val, +void StorageSoa::store(enum tgsi_file_type type, int idx, const std::vector &val, int mask) { llvm::Value *out = 0; switch(type) { - case Output: + case TGSI_FILE_OUTPUT: out = m_output; break; - case Temp: + case TGSI_FILE_TEMPORARY: out = m_temps; break; - case Input: + case TGSI_FILE_INPUT: out = m_input; break; - case Address: { + case TGSI_FILE_ADDRESS: { llvm::Value *addr = m_addresses[idx]; if (!addr) { addAddress(idx); diff --git a/src/gallium/auxiliary/gallivm/storagesoa.h b/src/gallium/auxiliary/gallivm/storagesoa.h index 6443351f27..ae2fc7c6ae 100644 --- a/src/gallium/auxiliary/gallivm/storagesoa.h +++ b/src/gallium/auxiliary/gallivm/storagesoa.h @@ -28,6 +28,8 @@ #ifndef STORAGESOA_H #define STORAGESOA_H +#include + #include #include #include @@ -45,15 +47,6 @@ namespace llvm { class StorageSoa { -public: - enum Argument { - Input, - Output, - Temp, - Const, - Immediate, - Address - }; public: StorageSoa(llvm::BasicBlock *block, llvm::Value *input, @@ -62,9 +55,9 @@ public: llvm::Value *temps); - std::vector load(Argument type, int idx, int swizzle, + std::vector load(enum tgsi_file_type type, int idx, int swizzle, llvm::Value *indIdx =0); - void store(Argument type, int idx, const std::vector &val, + void store(enum tgsi_file_type type, int idx, const std::vector &val, int mask); void addImmediate(float *vec); diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 2cb4acce32..a52ee26434 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -708,25 +708,9 @@ translate_instructionir(llvm::Module *module, if (src->SrcRegister.Indirect) { indIdx = storage->addrElement(src->SrcRegisterInd.Index); } - if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { - val = storage->load(StorageSoa::Const, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { - val = storage->load(StorageSoa::Input, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { - val = storage->load(StorageSoa::Temp, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { - val = storage->load(StorageSoa::Output, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { - val = storage->load(StorageSoa::Immediate, - src->SrcRegister.Index, swizzle, indIdx); - } else { - fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); - return; - } + + val = storage->load((enum tgsi_file_type)src->SrcRegister.File, + src->SrcRegister.Index, swizzle, indIdx); inputs[i] = val; } @@ -763,6 +747,7 @@ translate_instructionir(llvm::Module *module, } break; case TGSI_OPCODE_DP3: { + out = instr->dp3(inputs[0], inputs[1]); } break; case TGSI_OPCODE_DP4: { @@ -1067,19 +1052,8 @@ translate_instructionir(llvm::Module *module, for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { - storage->store(StorageSoa::Output, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { - storage->store(StorageSoa::Temp, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { - storage->store(StorageSoa::Address, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else { - fprintf(stderr, "ERROR: unsupported LLVM destination!"); - assert(!"wrong destination"); - } + storage->store((enum tgsi_file_type)dst->DstRegister.File, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); } } diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 0a6145a6bf..b110f01291 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -42,15 +42,17 @@ struct tgsi_token unsigned Extended : 1; /* BOOL */ }; -#define TGSI_FILE_NULL 0 -#define TGSI_FILE_CONSTANT 1 -#define TGSI_FILE_INPUT 2 -#define TGSI_FILE_OUTPUT 3 -#define TGSI_FILE_TEMPORARY 4 -#define TGSI_FILE_SAMPLER 5 -#define TGSI_FILE_ADDRESS 6 -#define TGSI_FILE_IMMEDIATE 7 -#define TGSI_FILE_COUNT 8 /**< how many TGSI_FILE_ types */ +enum tgsi_file_type { + TGSI_FILE_NULL =0, + TGSI_FILE_CONSTANT =1, + TGSI_FILE_INPUT =2, + TGSI_FILE_OUTPUT =3, + TGSI_FILE_TEMPORARY =4, + TGSI_FILE_SAMPLER =5, + TGSI_FILE_ADDRESS =6, + TGSI_FILE_IMMEDIATE =7, + TGSI_FILE_COUNT /**< how many TGSI_FILE_ types */ +}; #define TGSI_DECLARE_RANGE 0 -- cgit v1.2.3 From 17f543fc4529ca4ce7f73a840ed0fb50d1fec925 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 1 Mar 2008 08:32:31 -0500 Subject: make the first builtin work (dp3) --- src/gallium/auxiliary/gallivm/gallivm.cpp | 10 +++++- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 41 +++++++++++++---------- 2 files changed, 33 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/gallivm.cpp b/src/gallium/auxiliary/gallivm/gallivm.cpp index d14bb3b99a..b6f641a3f8 100644 --- a/src/gallium/auxiliary/gallivm/gallivm.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm.cpp @@ -306,11 +306,19 @@ struct gallivm_prog * gallivm_ir_compile(struct gallivm_ir *ir) { struct gallivm_prog *prog = (struct gallivm_prog *)calloc(1, sizeof(struct gallivm_prog)); + + std::cout << "Before optimizations:"<module->dump(); + std::cout<<"-------------------------------"<module); llvm::Module *mod = llvm::CloneModule(ir->module); prog->num_consts = ir->num_consts; memcpy(prog->interpolators, ir->interpolators, sizeof(prog->interpolators)); prog->num_interp = ir->num_interp; - + /* Run optimization passes over it */ PassManager passes; passes.add(new TargetData(mod)); diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 5739cf0cde..3fcfce8ce0 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -158,6 +158,7 @@ llvm::Function * InstructionsSoa::function(int op) currentModule()->getFunctionList().push_back(func); std::cout << "Func parent is "<getParent() <<", cur is "<dump(); //func->setParent(currentModule()); m_functions[op] = func; return func; @@ -184,8 +185,15 @@ std::vector InstructionsSoa::dp3(const std::vector i std::vector params; llvm::Value *tmp = allocaTemp(); - params.push_back(tmp); - + std::vector indices; + indices.push_back(m_storage->constantInt(0)); + indices.push_back(m_storage->constantInt(0)); + GetElementPtrInst *getElem = new GetElementPtrInst(tmp, + indices.begin(), + indices.end(), + name("allocaPtr"), + m_builder.GetInsertBlock()); + params.push_back(getElem); params.push_back(in1[0]); params.push_back(in1[1]); params.push_back(in1[2]); @@ -194,20 +202,10 @@ std::vector InstructionsSoa::dp3(const std::vector i params.push_back(in2[1]); params.push_back(in2[2]); params.push_back(in2[3]); - CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), - name("dp3")); + CallInst *call = m_builder.CreateCall(func, params.begin(), params.end()); call->setCallingConv(CallingConv::C); call->setTailCall(false); - std::vector indices; - indices.push_back(m_storage->constantInt(0)); - indices.push_back(m_storage->constantInt(0)); - - GetElementPtrInst *getElem = new GetElementPtrInst(tmp, - indices.begin(), - indices.end(), - name("allocaPtr"), - m_builder.GetInsertBlock()); indices = std::vector(); indices.push_back(m_storage->constantInt(0)); GetElementPtrInst *xElemPtr = new GetElementPtrInst(getElem, @@ -228,10 +226,19 @@ std::vector InstructionsSoa::dp3(const std::vector i m_builder.GetInsertBlock()); std::vector res(4); - res[0] = new LoadInst(xElemPtr); - res[1] = new LoadInst(yElemPtr); - res[2] = new LoadInst(zElemPtr); - res[3] = new LoadInst(wElemPtr); + res[0] = new LoadInst(xElemPtr, name("xRes"), false, m_builder.GetInsertBlock()); + res[1] = new LoadInst(yElemPtr, name("yRes"), false, m_builder.GetInsertBlock()); + res[2] = new LoadInst(zElemPtr, name("zRes"), false, m_builder.GetInsertBlock()); + res[3] = new LoadInst(wElemPtr, name("wRes"), false, m_builder.GetInsertBlock()); return res; } + +llvm::Value * InstructionsSoa::allocaTemp() +{ + VectorType *vector = VectorType::get(Type::FloatTy, 4); + ArrayType *vecArray = ArrayType::get(vector, 4); + AllocaInst *alloca = new AllocaInst(vecArray, name("tmpRes"), + m_builder.GetInsertBlock()); + return alloca; +} -- cgit v1.2.3 From a9c40f833ead8459788b86603c7f2b94632b1109 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 1 Mar 2008 09:50:41 -0500 Subject: refactor code calling builtins and implement dp4 --- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 116 +++++++++++++++++----- src/gallium/auxiliary/gallivm/instructionssoa.h | 12 +++ src/gallium/auxiliary/gallivm/soabuiltins.c | 14 +++ src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 1 + 4 files changed, 116 insertions(+), 27 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 3fcfce8ce0..89d513afd0 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -144,6 +144,7 @@ std::vector InstructionsSoa::extractVector(llvm::Value *vector) void InstructionsSoa::createFunctionMap() { m_functionsMap[TGSI_OPCODE_DP3] = "dp3"; + m_functionsMap[TGSI_OPCODE_DP4] = "dp4"; } llvm::Function * InstructionsSoa::function(int op) @@ -182,45 +183,42 @@ std::vector InstructionsSoa::dp3(const std::vector i const std::vector in2) { llvm::Function *func = function(TGSI_OPCODE_DP3); - std::vector params; + return callBuiltin(func, in1, in2); +} + +llvm::Value * InstructionsSoa::allocaTemp() +{ + VectorType *vector = VectorType::get(Type::FloatTy, 4); + ArrayType *vecArray = ArrayType::get(vector, 4); + AllocaInst *alloca = new AllocaInst(vecArray, name("tmpRes"), + m_builder.GetInsertBlock()); - llvm::Value *tmp = allocaTemp(); std::vector indices; indices.push_back(m_storage->constantInt(0)); indices.push_back(m_storage->constantInt(0)); - GetElementPtrInst *getElem = new GetElementPtrInst(tmp, + GetElementPtrInst *getElem = new GetElementPtrInst(alloca, indices.begin(), indices.end(), name("allocaPtr"), m_builder.GetInsertBlock()); - params.push_back(getElem); - params.push_back(in1[0]); - params.push_back(in1[1]); - params.push_back(in1[2]); - params.push_back(in1[3]); - params.push_back(in2[0]); - params.push_back(in2[1]); - params.push_back(in2[2]); - params.push_back(in2[3]); - CallInst *call = m_builder.CreateCall(func, params.begin(), params.end()); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); + return getElem; +} - indices = std::vector(); - indices.push_back(m_storage->constantInt(0)); - GetElementPtrInst *xElemPtr = new GetElementPtrInst(getElem, +std::vector InstructionsSoa::allocaToResult(llvm::Value *allocaPtr) +{ + GetElementPtrInst *xElemPtr = new GetElementPtrInst(allocaPtr, m_storage->constantInt(0), name("xPtr"), m_builder.GetInsertBlock()); - GetElementPtrInst *yElemPtr = new GetElementPtrInst(getElem, + GetElementPtrInst *yElemPtr = new GetElementPtrInst(allocaPtr, m_storage->constantInt(1), name("yPtr"), m_builder.GetInsertBlock()); - GetElementPtrInst *zElemPtr = new GetElementPtrInst(getElem, + GetElementPtrInst *zElemPtr = new GetElementPtrInst(allocaPtr, m_storage->constantInt(2), name("zPtr"), m_builder.GetInsertBlock()); - GetElementPtrInst *wElemPtr = new GetElementPtrInst(getElem, + GetElementPtrInst *wElemPtr = new GetElementPtrInst(allocaPtr, m_storage->constantInt(3), name("wPtr"), m_builder.GetInsertBlock()); @@ -234,11 +232,75 @@ std::vector InstructionsSoa::dp3(const std::vector i return res; } -llvm::Value * InstructionsSoa::allocaTemp() +std::vector InstructionsSoa::dp4(const std::vector in1, + const std::vector in2) { - VectorType *vector = VectorType::get(Type::FloatTy, 4); - ArrayType *vecArray = ArrayType::get(vector, 4); - AllocaInst *alloca = new AllocaInst(vecArray, name("tmpRes"), - m_builder.GetInsertBlock()); - return alloca; + llvm::Function *func = function(TGSI_OPCODE_DP4); + return callBuiltin(func, in1, in2); +} + +std::vector InstructionsSoa::callBuiltin(llvm::Function *func, const std::vector in1) +{ + std::vector params; + + llvm::Value *allocaPtr = allocaTemp(); + params.push_back(allocaPtr); + params.push_back(in1[0]); + params.push_back(in1[1]); + params.push_back(in1[2]); + params.push_back(in1[3]); + CallInst *call = m_builder.CreateCall(func, params.begin(), params.end()); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + + return allocaToResult(allocaPtr); +} + +std::vector InstructionsSoa::callBuiltin(llvm::Function *func, const std::vector in1, + const std::vector in2) +{ + std::vector params; + + llvm::Value *allocaPtr = allocaTemp(); + params.push_back(allocaPtr); + params.push_back(in1[0]); + params.push_back(in1[1]); + params.push_back(in1[2]); + params.push_back(in1[3]); + params.push_back(in2[0]); + params.push_back(in2[1]); + params.push_back(in2[2]); + params.push_back(in2[3]); + CallInst *call = m_builder.CreateCall(func, params.begin(), params.end()); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + + return allocaToResult(allocaPtr); +} + +std::vector InstructionsSoa::callBuiltin(llvm::Function *func, const std::vector in1, + const std::vector in2, + const std::vector in3) +{ + std::vector params; + + llvm::Value *allocaPtr = allocaTemp(); + params.push_back(allocaPtr); + params.push_back(in1[0]); + params.push_back(in1[1]); + params.push_back(in1[2]); + params.push_back(in1[3]); + params.push_back(in2[0]); + params.push_back(in2[1]); + params.push_back(in2[2]); + params.push_back(in2[3]); + params.push_back(in3[0]); + params.push_back(in3[1]); + params.push_back(in3[2]); + params.push_back(in3[3]); + CallInst *call = m_builder.CreateCall(func, params.begin(), params.end()); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + + return allocaToResult(allocaPtr); } diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h index 5c26687150..3ef51dcaff 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -52,6 +52,8 @@ public: const std::vector in2); std::vector dp3(const std::vector in1, const std::vector in2); + std::vector dp4(const std::vector in1, + const std::vector in2); std::vector madd(const std::vector in1, const std::vector in2, const std::vector in3); @@ -69,6 +71,16 @@ private: llvm::Function *function(int); llvm::Module *currentModule() const; llvm::Value *allocaTemp(); + std::vector allocaToResult(llvm::Value *allocaPtr); + std::vector callBuiltin(llvm::Function *func, + const std::vector in1); + std::vector callBuiltin(llvm::Function *func, + const std::vector in1, + const std::vector in2); + std::vector callBuiltin(llvm::Function *func, + const std::vector in1, + const std::vector in2, + const std::vector in3); private: llvm::LLVMFoldingBuilder m_builder; StorageSoa *m_storage; diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c index 0b428a750f..24c14e1b69 100644 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -46,6 +46,20 @@ void dp3(float4 *res, res[3] = dot; } + +void dp4(float4 *res, + float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, + float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) +{ + float4 dot = (tmp0x * tmp1x) + (tmp0y * tmp1y) + + (tmp0z * tmp1z) + (tmp0w * tmp1w); + + res[0] = dot; + res[1] = dot; + res[2] = dot; + res[3] = dot; +} + #if 0 void yo(float4 *out, float4 *in) { diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index a52ee26434..3f65865a5a 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -751,6 +751,7 @@ translate_instructionir(llvm::Module *module, } break; case TGSI_OPCODE_DP4: { + out = instr->dp4(inputs[0], inputs[1]); } break; case TGSI_OPCODE_DST: { -- cgit v1.2.3 From f4e91c3432eaf653757193a8a1ac438372ea64a6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 27 Feb 2008 13:06:18 +0000 Subject: gallium: document user_buffer_create a little --- src/gallium/include/pipe/p_winsys.h | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index e784c92491..1383bd0544 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -104,13 +104,36 @@ struct pipe_winsys * usage is a bitmask of PIPE_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This * usage argument is only an optimization hint, not a guarantee, therefore * proper behavior must be observed in all circumstances. + * + * alignment indicates the client's alignment requirements, eg for + * SSE instructions. */ struct pipe_buffer *(*buffer_create)( struct pipe_winsys *sws, - unsigned alignment, - unsigned usage, - unsigned size ); + unsigned alignment, + unsigned usage, + unsigned size ); - /** Create a buffer that wraps user-space data */ + /** + * Create a buffer that wraps user-space data. + * + * Effectively this schedules a delayed call to buffer_create + * followed by an upload of the data at *some point in the future*, + * or perhaps never. Basically the allocate/upload is delayed + * until the buffer is actually passed to hardware. + * + * The intention is to provide a quick way to turn regular data + * into a buffer, and secondly to avoid a copy operation if that + * data subsequently turns out to be only accessed by the CPU. + * + * Common example is OpenGL vertex buffers that are subsequently + * processed either by software TNL in the driver or by passing to + * hardware. + * + * XXX: What happens if the delayed call to buffer_create() fails? + * + * Note that ptr may be accessed at any time upto the time when the + * buffer is destroyed, so the data must not be freed before then. + */ struct pipe_buffer *(*user_buffer_create)(struct pipe_winsys *sws, void *ptr, unsigned bytes); -- cgit v1.2.3 From 9506ac823593387aa2f3a19f48ea07a91d4b6bb9 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 28 Feb 2008 17:08:37 +0000 Subject: gallium: remove obsolete comment --- src/gallium/include/pipe/p_state.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 5fab41acbd..49a003b923 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -281,8 +281,6 @@ struct pipe_surface */ struct pipe_texture { - /* Effectively the key: - */ enum pipe_texture_target target; /**< PIPE_TEXTURE_x */ enum pipe_format format; /**< PIPE_FORMAT_x */ -- cgit v1.2.3 From 800d13df726b9f82f796c86fe7ae6d18231820ec Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 3 Mar 2008 17:44:04 +0100 Subject: draw: add fetch for bgra ubyte surfaces --- src/gallium/auxiliary/draw/draw_vertex_fetch.c | 44 +++++++++++++++++--------- 1 file changed, 29 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c index cb8cdd04a3..b56d85396d 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c +++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c @@ -54,7 +54,7 @@ fetch_##NAME(const void *ptr, float *attrib) \ int i; \ \ for (i = 0; i < SZ; i++) { \ - attrib[i] = CVT; \ + attrib[i] = CVT(i); \ } \ \ for (; i < 4; i++) { \ @@ -62,24 +62,24 @@ fetch_##NAME(const void *ptr, float *attrib) \ } \ } -#define CVT_64_FLOAT (float) ((double *) ptr)[i] -#define CVT_32_FLOAT ((float *) ptr)[i] +#define CVT_64_FLOAT(i) (float) ((double *) ptr)[i] +#define CVT_32_FLOAT(i) ((float *) ptr)[i] -#define CVT_8_USCALED (float) ((unsigned char *) ptr)[i] -#define CVT_16_USCALED (float) ((unsigned short *) ptr)[i] -#define CVT_32_USCALED (float) ((unsigned int *) ptr)[i] +#define CVT_8_USCALED(i) (float) ((unsigned char *) ptr)[i] +#define CVT_16_USCALED(i) (float) ((unsigned short *) ptr)[i] +#define CVT_32_USCALED(i) (float) ((unsigned int *) ptr)[i] -#define CVT_8_SSCALED (float) ((char *) ptr)[i] -#define CVT_16_SSCALED (float) ((short *) ptr)[i] -#define CVT_32_SSCALED (float) ((int *) ptr)[i] +#define CVT_8_SSCALED(i) (float) ((char *) ptr)[i] +#define CVT_16_SSCALED(i) (float) ((short *) ptr)[i] +#define CVT_32_SSCALED(i) (float) ((int *) ptr)[i] -#define CVT_8_UNORM (float) ((unsigned char *) ptr)[i] / 255.0f -#define CVT_16_UNORM (float) ((unsigned short *) ptr)[i] / 65535.0f -#define CVT_32_UNORM (float) ((unsigned int *) ptr)[i] / 4294967295.0f +#define CVT_8_UNORM(i) (float) ((unsigned char *) ptr)[i] / 255.0f +#define CVT_16_UNORM(i) (float) ((unsigned short *) ptr)[i] / 65535.0f +#define CVT_32_UNORM(i) (float) ((unsigned int *) ptr)[i] / 4294967295.0f -#define CVT_8_SNORM (float) ((char *) ptr)[i] / 127.0f -#define CVT_16_SNORM (float) ((short *) ptr)[i] / 32767.0f -#define CVT_32_SNORM (float) ((int *) ptr)[i] / 2147483647.0f +#define CVT_8_SNORM(i) (float) ((char *) ptr)[i] / 127.0f +#define CVT_16_SNORM(i) (float) ((short *) ptr)[i] / 32767.0f +#define CVT_32_SNORM(i) (float) ((int *) ptr)[i] / 2147483647.0f FETCH_ATTRIB( R64G64B64A64_FLOAT, 4, CVT_64_FLOAT ) FETCH_ATTRIB( R64G64B64_FLOAT, 3, CVT_64_FLOAT ) @@ -156,6 +156,16 @@ FETCH_ATTRIB( A8R8G8B8_UNORM, 4, CVT_8_UNORM ) +static void +fetch_B8G8R8A8_UNORM(const void *ptr, float *attrib) +{ + attrib[2] = CVT_8_UNORM(0); + attrib[1] = CVT_8_UNORM(1); + attrib[0] = CVT_8_UNORM(2); + attrib[3] = CVT_8_UNORM(3); +} + + static fetch_func get_fetch_func( enum pipe_format format ) { #if 0 @@ -296,6 +306,10 @@ static fetch_func get_fetch_func( enum pipe_format format ) case PIPE_FORMAT_A8R8G8B8_UNORM: return fetch_A8R8G8B8_UNORM; + + case PIPE_FORMAT_B8G8R8A8_UNORM: + return fetch_B8G8R8A8_UNORM; + case 0: return NULL; /* not sure why this is needed */ -- cgit v1.2.3 From 689e1c5d501eb2f557f85dd3279ac5d91e53b0ad Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 3 Mar 2008 17:49:38 +0100 Subject: win32: don't prepend all debug with gallium3d --- src/gallium/auxiliary/util/p_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index b9607a6ba7..0da3b66a4d 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -43,7 +43,7 @@ void debug_vprintf(const char *format, va_list ap) { #ifdef WIN32 - EngDebugPrint("Gallium3D: ", (PCHAR)format, ap); + EngDebugPrint("", (PCHAR)format, ap); #else vfprintf(stderr, format, ap); #endif -- cgit v1.2.3 From 1cd2623a53cb02b491c725f101ee70824ab26a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 4 Mar 2008 18:30:12 +0100 Subject: gallium: Make scons build gallivm before other auxiliary modules. This ensures that the gallivm symbols referenced by the draw module are resolved properly. --- src/gallium/SConscript | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/SConscript b/src/gallium/SConscript index fa4833cbcf..f09778ce99 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -9,6 +9,9 @@ auxiliaries = [] Export('auxiliaries') +if llvm: + SConscript(['auxiliary/gallivm/SConscript']) + SConscript([ # NOTE: order matters! 'auxiliary/util/SConscript', @@ -19,8 +22,5 @@ SConscript([ 'auxiliary/pipebuffer/SConscript', ]) -if llvm: - SConscript(['auxiliary/gallivm/SConscript']) - for driver in env['drivers']: SConscript(os.path.join('drivers', driver, 'SConscript')) -- cgit v1.2.3 From 5b9b5c850f3b34d8891890d808a520a64dd779bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 4 Mar 2008 18:32:16 +0100 Subject: gallium: Fix scons condition for building the xlib winsys. --- src/gallium/winsys/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index 635a68eea2..f18d3bd2f8 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -5,7 +5,7 @@ if dri: 'dri/SConscript', ]) -if 'xlib' in env['drivers'] and not dri: +if 'xlib' in env['winsys'] and not dri: SConscript([ 'xlib/SConscript', ]) -- cgit v1.2.3 From 19cc2e363185b50d19e4f257dd3558896b9b49d3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 4 Mar 2008 17:55:02 +0100 Subject: draw: dont' compute clipmask or apply viewport when not clipping (rename bypass_clipping to coords_in_window_space? --- src/gallium/auxiliary/draw/draw_vs_exec.c | 38 +++++++++++++++++++------------ 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 583812aadd..514303e0ea 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -132,20 +132,30 @@ vs_exec_run( struct draw_vertex_shader *shader, z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; - vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); - vOut[j]->edgeflag = 1; - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - - /* Viewport mapping */ - vOut[j]->data[0][0] = x * scale[0] + trans[0]; - vOut[j]->data[0][1] = y * scale[1] + trans[1]; - vOut[j]->data[0][2] = z * scale[2] + trans[2]; - vOut[j]->data[0][3] = w; + if (!draw->rasterizer->bypass_clipping) { + vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + vOut[j]->edgeflag = 1; + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; + + /* Viewport mapping */ + vOut[j]->data[0][0] = x * scale[0] + trans[0]; + vOut[j]->data[0][1] = y * scale[1] + trans[1]; + vOut[j]->data[0][2] = z * scale[2] + trans[2]; + vOut[j]->data[0][3] = w; + } + else { + vOut[j]->clipmask = 0; + vOut[j]->edgeflag = 1; + vOut[j]->data[0][0] = x; + vOut[j]->data[0][1] = y; + vOut[j]->data[0][2] = z; + vOut[j]->data[0][3] = w; + } /* Remaining attributes are packed into sequential post-transform * vertex attrib slots. -- cgit v1.2.3 From b1922de9f3478869c6788ef4e954c06c20e7aa9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 5 Mar 2008 11:38:21 +0100 Subject: gallium: Use custom vsnprintf in WINDDK. EngDebugPrint does not handle float point arguments, so we need to use our own vsnprintf implementation. --- src/gallium/auxiliary/util/SConscript | 1 + src/gallium/auxiliary/util/p_debug.c | 20 +- src/gallium/auxiliary/util/u_snprintf.c | 1482 +++++++++++++++++++++++++++++++ 3 files changed, 1502 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/util/u_snprintf.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 4717941434..642088b962 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -7,6 +7,7 @@ util = env.ConvenienceLibrary( 'p_tile.c', 'p_util.c', 'u_mm.c', + 'u_snprintf.c', ]) auxiliaries.insert(0, util) diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 0da3b66a4d..7b3c030956 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -40,10 +40,28 @@ #include "pipe/p_compiler.h" +#ifdef WIN32 +static INLINE void +rpl_EngDebugPrint(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + EngDebugPrint("", (PCHAR)format, ap); + va_end(ap); +} + +int rpl_vsnprintf(char *, size_t, const char *, va_list); +#endif + + void debug_vprintf(const char *format, va_list ap) { #ifdef WIN32 - EngDebugPrint("", (PCHAR)format, ap); + /* EngDebugPrint does not handle float point arguments, so we need to use + * our own vsnprintf implementation */ + char buf[512 + 1]; + rpl_vsnprintf(buf, sizeof(buf), format, ap); + rpl_EngDebugPrint("%s", buf); #else vfprintf(stderr, format, ap); #endif diff --git a/src/gallium/auxiliary/util/u_snprintf.c b/src/gallium/auxiliary/util/u_snprintf.c new file mode 100644 index 0000000000..5e19a2ddb2 --- /dev/null +++ b/src/gallium/auxiliary/util/u_snprintf.c @@ -0,0 +1,1482 @@ +/* + * Copyright (c) 1995 Patrick Powell. + * + * This code is based on code written by Patrick Powell . + * It may be used for any purpose as long as this notice remains intact on all + * source code distributions. + */ + +/* + * Copyright (c) 2008 Holger Weiss. + * + * This version of the code is maintained by Holger Weiss . + * My changes to the code may freely be used, modified and/or redistributed for + * any purpose. It would be nice if additions and fixes to this file (including + * trivial code cleanups) would be sent back in order to let me include them in + * the version available at . + * However, this is not a requirement for using or redistributing (possibly + * modified) versions of this file, nor is leaving this notice intact mandatory. + */ + +/* + * History + * + * 2008-01-20 Holger Weiss for C99-snprintf 1.1: + * + * Fixed the detection of infinite floating point values on IRIX (and + * possibly other systems) and applied another few minor cleanups. + * + * 2008-01-06 Holger Weiss for C99-snprintf 1.0: + * + * Added a lot of new features, fixed many bugs, and incorporated various + * improvements done by Andrew Tridgell , Russ Allbery + * , Hrvoje Niksic , Damien Miller + * , and others for the Samba, INN, Wget, and OpenSSH + * projects. The additions include: support the "e", "E", "g", "G", and + * "F" conversion specifiers (and use conversion style "f" or "F" for the + * still unsupported "a" and "A" specifiers); support the "hh", "ll", "j", + * "t", and "z" length modifiers; support the "#" flag and the (non-C99) + * "'" flag; use localeconv(3) (if available) to get both the current + * locale's decimal point character and the separator between groups of + * digits; fix the handling of various corner cases of field width and + * precision specifications; fix various floating point conversion bugs; + * handle infinite and NaN floating point values; don't attempt to write to + * the output buffer (which may be NULL) if a size of zero was specified; + * check for integer overflow of the field width, precision, and return + * values and during the floating point conversion; use the OUTCHAR() macro + * instead of a function for better performance; provide asprintf(3) and + * vasprintf(3) functions; add new test cases. The replacement functions + * have been renamed to use an "rpl_" prefix, the function calls in the + * main project (and in this file) must be redefined accordingly for each + * replacement function which is needed (by using Autoconf or other means). + * Various other minor improvements have been applied and the coding style + * was cleaned up for consistency. + * + * 2007-07-23 Holger Weiss for Mutt 1.5.13: + * + * C99 compliant snprintf(3) and vsnprintf(3) functions return the number + * of characters that would have been written to a sufficiently sized + * buffer (excluding the '\0'). The original code simply returned the + * length of the resulting output string, so that's been fixed. + * + * 1998-03-05 Michael Elkins for Mutt 0.90.8: + * + * The original code assumed that both snprintf(3) and vsnprintf(3) were + * missing. Some systems only have snprintf(3) but not vsnprintf(3), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + * 1998-01-27 Thomas Roessler for Mutt 0.89i: + * + * The PGP code was using unsigned hexadecimal formats. Unfortunately, + * unsigned formats simply didn't work. + * + * 1997-10-22 Brandon Long for Mutt 0.87.1: + * + * Ok, added some minimal floating point support, which means this probably + * requires libm on most operating systems. Don't yet support the exponent + * (e,E) and sigfig (g,G). Also, fmtint() was pretty badly broken, it just + * wasn't being exercised in ways which showed it, so that's been fixed. + * Also, formatted the code to Mutt conventions, and removed dead code left + * over from the original. Also, there is now a builtin-test, run with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm && ./snprintf + * + * 2996-09-15 Brandon Long for Mutt 0.43: + * + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything from the + * normal C string format, at least as far as I can tell from the Solaris + * 2.5 printf(3S) man page. + */ + +/* + * ToDo + * + * - Add wide character support. + * - Add support for "%a" and "%A" conversions. + * - Create test routines which predefine the expected results. Our test cases + * usually expose bugs in system implementations rather than in ours :-) + */ + +/* + * Usage + * + * 1) The following preprocessor macros should be defined to 1 if the feature or + * file in question is available on the target system (by using Autoconf or + * other means), though basic functionality should be available as long as + * HAVE_STDARG_H and HAVE_STDLIB_H are defined correctly: + * + * HAVE_VSNPRINTF + * HAVE_SNPRINTF + * HAVE_VASPRINTF + * HAVE_ASPRINTF + * HAVE_STDARG_H + * HAVE_STDDEF_H + * HAVE_STDINT_H + * HAVE_STDLIB_H + * HAVE_INTTYPES_H + * HAVE_LOCALE_H + * HAVE_LOCALECONV + * HAVE_LCONV_DECIMAL_POINT + * HAVE_LCONV_THOUSANDS_SEP + * HAVE_LONG_DOUBLE + * HAVE_LONG_LONG_INT + * HAVE_UNSIGNED_LONG_LONG_INT + * HAVE_INTMAX_T + * HAVE_UINTMAX_T + * HAVE_UINTPTR_T + * HAVE_PTRDIFF_T + * HAVE_VA_COPY + * HAVE___VA_COPY + * + * 2) The calls to the functions which should be replaced must be redefined + * throughout the project files (by using Autoconf or other means): + * + * #define vsnprintf rpl_vsnprintf + * #define snprintf rpl_snprintf + * #define vasprintf rpl_vasprintf + * #define asprintf rpl_asprintf + * + * 3) The required replacement functions should be declared in some header file + * included throughout the project files: + * + * #if HAVE_CONFIG_H + * #include + * #endif + * #if HAVE_STDARG_H + * #include + * #if !HAVE_VSNPRINTF + * int rpl_vsnprintf(char *, size_t, const char *, va_list); + * #endif + * #if !HAVE_SNPRINTF + * int rpl_snprintf(char *, size_t, const char *, ...); + * #endif + * #if !HAVE_VASPRINTF + * int rpl_vasprintf(char **, const char *, va_list); + * #endif + * #if !HAVE_ASPRINTF + * int rpl_asprintf(char **, const char *, ...); + * #endif + * #endif + * + * Autoconf macros for handling step 1 and step 2 are available at + * . + */ + +#if HAVE_CONFIG_H +#include +#else +#ifdef WIN32 +#define vsnprintf rpl_vsnprintf +#define snprintf rpl_snprintf +#define HAVE_VSNPRINTF 0 +#define HAVE_SNPRINTF 0 +#define HAVE_VASPRINTF 1 /* not needed */ +#define HAVE_ASPRINTF 1 /* not needed */ +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 0 +#define HAVE_STDLIB_H 1 +#define HAVE_INTTYPES_H 0 +#define HAVE_LOCALE_H 0 +#define HAVE_LOCALECONV 0 +#define HAVE_LCONV_DECIMAL_POINT 0 +#define HAVE_LCONV_THOUSANDS_SEP 0 +#define HAVE_LONG_DOUBLE 0 +#define HAVE_LONG_LONG_INT 1 +#define HAVE_UNSIGNED_LONG_LONG_INT 1 +#define HAVE_INTMAX_T 0 +#define HAVE_UINTMAX_T 0 +#define HAVE_UINTPTR_T 1 +#define HAVE_PTRDIFF_T 1 +#define HAVE_VA_COPY 0 +#define HAVE___VA_COPY 0 +#else +#define HAVE_VSNPRINTF 1 +#define HAVE_SNPRINTF 1 +#define HAVE_VASPRINTF 1 +#define HAVE_ASPRINTF 1 +#endif +#endif /* HAVE_CONFIG_H */ + +#if !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || !HAVE_VASPRINTF +#include /* For NULL, size_t, vsnprintf(3), and vasprintf(3). */ +#ifdef VA_START +#undef VA_START +#endif /* defined(VA_START) */ +#ifdef VA_SHIFT +#undef VA_SHIFT +#endif /* defined(VA_SHIFT) */ +#if HAVE_STDARG_H +#include +#define VA_START(ap, last) va_start(ap, last) +#define VA_SHIFT(ap, value, type) /* No-op for ANSI C. */ +#else /* Assume is available. */ +#include +#define VA_START(ap, last) va_start(ap) /* "last" is ignored. */ +#define VA_SHIFT(ap, value, type) value = va_arg(ap, type) +#endif /* HAVE_STDARG_H */ + +#if !HAVE_VASPRINTF +#if HAVE_STDLIB_H +#include /* For malloc(3). */ +#endif /* HAVE_STDLIB_H */ +#ifdef VA_COPY +#undef VA_COPY +#endif /* defined(VA_COPY) */ +#ifdef VA_END_COPY +#undef VA_END_COPY +#endif /* defined(VA_END_COPY) */ +#if HAVE_VA_COPY +#define VA_COPY(dest, src) va_copy(dest, src) +#define VA_END_COPY(ap) va_end(ap) +#elif HAVE___VA_COPY +#define VA_COPY(dest, src) __va_copy(dest, src) +#define VA_END_COPY(ap) va_end(ap) +#else +#define VA_COPY(dest, src) (void)mymemcpy(&dest, &src, sizeof(va_list)) +#define VA_END_COPY(ap) /* No-op. */ +#define NEED_MYMEMCPY 1 +static void *mymemcpy(void *, void *, size_t); +#endif /* HAVE_VA_COPY */ +#endif /* !HAVE_VASPRINTF */ + +#if !HAVE_VSNPRINTF +#include /* For ERANGE and errno. */ +#include /* For *_MAX. */ +#if HAVE_INTTYPES_H +#include /* For intmax_t (if not defined in ). */ +#endif /* HAVE_INTTYPES_H */ +#if HAVE_LOCALE_H +#include /* For localeconv(3). */ +#endif /* HAVE_LOCALE_H */ +#if HAVE_STDDEF_H +#include /* For ptrdiff_t. */ +#endif /* HAVE_STDDEF_H */ +#if HAVE_STDINT_H +#include /* For intmax_t. */ +#endif /* HAVE_STDINT_H */ + +/* Support for unsigned long long int. We may also need ULLONG_MAX. */ +#ifndef ULONG_MAX /* We may need ULONG_MAX as a fallback. */ +#ifdef UINT_MAX +#define ULONG_MAX UINT_MAX +#else +#define ULONG_MAX INT_MAX +#endif /* defined(UINT_MAX) */ +#endif /* !defined(ULONG_MAX) */ +#ifdef ULLONG +#undef ULLONG +#endif /* defined(ULLONG) */ +#if HAVE_UNSIGNED_LONG_LONG_INT +#define ULLONG unsigned long long int +#ifndef ULLONG_MAX +#define ULLONG_MAX ULONG_MAX +#endif /* !defined(ULLONG_MAX) */ +#else +#define ULLONG unsigned long int +#ifdef ULLONG_MAX +#undef ULLONG_MAX +#endif /* defined(ULLONG_MAX) */ +#define ULLONG_MAX ULONG_MAX +#endif /* HAVE_LONG_LONG_INT */ + +/* Support for uintmax_t. We also need UINTMAX_MAX. */ +#ifdef UINTMAX_T +#undef UINTMAX_T +#endif /* defined(UINTMAX_T) */ +#if HAVE_UINTMAX_T || defined(uintmax_t) +#define UINTMAX_T uintmax_t +#ifndef UINTMAX_MAX +#define UINTMAX_MAX ULLONG_MAX +#endif /* !defined(UINTMAX_MAX) */ +#else +#define UINTMAX_T ULLONG +#ifdef UINTMAX_MAX +#undef UINTMAX_MAX +#endif /* defined(UINTMAX_MAX) */ +#define UINTMAX_MAX ULLONG_MAX +#endif /* HAVE_UINTMAX_T || defined(uintmax_t) */ + +/* Support for long double. */ +#ifndef LDOUBLE +#if HAVE_LONG_DOUBLE +#define LDOUBLE long double +#else +#define LDOUBLE double +#endif /* HAVE_LONG_DOUBLE */ +#endif /* !defined(LDOUBLE) */ + +/* Support for long long int. */ +#ifndef LLONG +#if HAVE_LONG_LONG_INT +#define LLONG long long int +#else +#define LLONG long int +#endif /* HAVE_LONG_LONG_INT */ +#endif /* !defined(LLONG) */ + +/* Support for intmax_t. */ +#ifndef INTMAX_T +#if HAVE_INTMAX_T || defined(intmax_t) +#define INTMAX_T intmax_t +#else +#define INTMAX_T LLONG +#endif /* HAVE_INTMAX_T || defined(intmax_t) */ +#endif /* !defined(INTMAX_T) */ + +/* Support for uintptr_t. */ +#ifndef UINTPTR_T +#if HAVE_UINTPTR_T || defined(uintptr_t) +#define UINTPTR_T uintptr_t +#else +#define UINTPTR_T unsigned long int +#endif /* HAVE_UINTPTR_T || defined(uintptr_t) */ +#endif /* !defined(UINTPTR_T) */ + +/* Support for ptrdiff_t. */ +#ifndef PTRDIFF_T +#if HAVE_PTRDIFF_T || defined(ptrdiff_t) +#define PTRDIFF_T ptrdiff_t +#else +#define PTRDIFF_T long int +#endif /* HAVE_PTRDIFF_T || defined(ptrdiff_t) */ +#endif /* !defined(PTRDIFF_T) */ + +/* + * We need an unsigned integer type corresponding to ptrdiff_t (cf. C99: + * 7.19.6.1, 7). However, we'll simply use PTRDIFF_T and convert it to an + * unsigned type if necessary. This should work just fine in practice. + */ +#ifndef UPTRDIFF_T +#define UPTRDIFF_T PTRDIFF_T +#endif /* !defined(UPTRDIFF_T) */ + +/* + * We need a signed integer type corresponding to size_t (cf. C99: 7.19.6.1, 7). + * However, we'll simply use size_t and convert it to a signed type if + * necessary. This should work just fine in practice. + */ +#ifndef SSIZE_T +#define SSIZE_T size_t +#endif /* !defined(SSIZE_T) */ + +/* Either ERANGE or E2BIG should be available everywhere. */ +#ifndef ERANGE +#define ERANGE E2BIG +#endif /* !defined(ERANGE) */ +#ifndef EOVERFLOW +#define EOVERFLOW ERANGE +#endif /* !defined(EOVERFLOW) */ + +/* + * Buffer size to hold the octal string representation of UINT128_MAX without + * nul-termination ("3777777777777777777777777777777777777777777"). + */ +#ifdef MAX_CONVERT_LENGTH +#undef MAX_CONVERT_LENGTH +#endif /* defined(MAX_CONVERT_LENGTH) */ +#define MAX_CONVERT_LENGTH 43 + +/* Format read states. */ +#define PRINT_S_DEFAULT 0 +#define PRINT_S_FLAGS 1 +#define PRINT_S_WIDTH 2 +#define PRINT_S_DOT 3 +#define PRINT_S_PRECISION 4 +#define PRINT_S_MOD 5 +#define PRINT_S_CONV 6 + +/* Format flags. */ +#define PRINT_F_MINUS (1 << 0) +#define PRINT_F_PLUS (1 << 1) +#define PRINT_F_SPACE (1 << 2) +#define PRINT_F_NUM (1 << 3) +#define PRINT_F_ZERO (1 << 4) +#define PRINT_F_QUOTE (1 << 5) +#define PRINT_F_UP (1 << 6) +#define PRINT_F_UNSIGNED (1 << 7) +#define PRINT_F_TYPE_G (1 << 8) +#define PRINT_F_TYPE_E (1 << 9) + +/* Conversion flags. */ +#define PRINT_C_CHAR 1 +#define PRINT_C_SHORT 2 +#define PRINT_C_LONG 3 +#define PRINT_C_LLONG 4 +#define PRINT_C_LDOUBLE 5 +#define PRINT_C_SIZE 6 +#define PRINT_C_PTRDIFF 7 +#define PRINT_C_INTMAX 8 + +#ifndef MAX +#define MAX(x, y) ((x >= y) ? x : y) +#endif /* !defined(MAX) */ +#ifndef CHARTOINT +#define CHARTOINT(ch) (ch - '0') +#endif /* !defined(CHARTOINT) */ +#ifndef ISDIGIT +#define ISDIGIT(ch) ('0' <= (unsigned char)ch && (unsigned char)ch <= '9') +#endif /* !defined(ISDIGIT) */ +#ifndef ISNAN +#define ISNAN(x) (x != x) +#endif /* !defined(ISNAN) */ +#ifndef ISINF +#define ISINF(x) (x != 0.0 && x + x == x) +#endif /* !defined(ISINF) */ + +#ifdef OUTCHAR +#undef OUTCHAR +#endif /* defined(OUTCHAR) */ +#define OUTCHAR(str, len, size, ch) \ +do { \ + if (len + 1 < size) \ + str[len] = ch; \ + (len)++; \ +} while (/* CONSTCOND */ 0) + +static void fmtstr(char *, size_t *, size_t, const char *, int, int, int); +static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int); +static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *); +static void printsep(char *, size_t *, size_t); +static int getnumsep(int); +static int getexponent(LDOUBLE); +static int convert(UINTMAX_T, char *, size_t, int, int); +static UINTMAX_T cast(LDOUBLE); +static UINTMAX_T myround(LDOUBLE); +static LDOUBLE mypow10(int); + +extern int errno; + +int +rpl_vsnprintf(char *str, size_t size, const char *format, va_list args) +{ + LDOUBLE fvalue; + INTMAX_T value; + unsigned char cvalue; + const char *strvalue; + INTMAX_T *intmaxptr; + PTRDIFF_T *ptrdiffptr; + SSIZE_T *sizeptr; + LLONG *llongptr; + long int *longptr; + int *intptr; + short int *shortptr; + signed char *charptr; + size_t len = 0; + int overflow = 0; + int base = 0; + int cflags = 0; + int flags = 0; + int width = 0; + int precision = -1; + int state = PRINT_S_DEFAULT; + char ch = *format++; + + /* + * C99 says: "If `n' is zero, nothing is written, and `s' may be a null + * pointer." (7.19.6.5, 2) We're forgiving and allow a NULL pointer + * even if a size larger than zero was specified. At least NetBSD's + * snprintf(3) does the same, as well as other versions of this file. + * (Though some of these versions will write to a non-NULL buffer even + * if a size of zero was specified, which violates the standard.) + */ + if (str == NULL && size != 0) + size = 0; + + while (ch != '\0') + switch (state) { + case PRINT_S_DEFAULT: + if (ch == '%') + state = PRINT_S_FLAGS; + else + OUTCHAR(str, len, size, ch); + ch = *format++; + break; + case PRINT_S_FLAGS: + switch (ch) { + case '-': + flags |= PRINT_F_MINUS; + ch = *format++; + break; + case '+': + flags |= PRINT_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= PRINT_F_SPACE; + ch = *format++; + break; + case '#': + flags |= PRINT_F_NUM; + ch = *format++; + break; + case '0': + flags |= PRINT_F_ZERO; + ch = *format++; + break; + case '\'': /* SUSv2 flag (not in C99). */ + flags |= PRINT_F_QUOTE; + ch = *format++; + break; + default: + state = PRINT_S_WIDTH; + break; + } + break; + case PRINT_S_WIDTH: + if (ISDIGIT(ch)) { + ch = CHARTOINT(ch); + if (width > (INT_MAX - ch) / 10) { + overflow = 1; + goto out; + } + width = 10 * width + ch; + ch = *format++; + } else if (ch == '*') { + /* + * C99 says: "A negative field width argument is + * taken as a `-' flag followed by a positive + * field width." (7.19.6.1, 5) + */ + if ((width = va_arg(args, int)) < 0) { + flags |= PRINT_F_MINUS; + width = -width; + } + ch = *format++; + state = PRINT_S_DOT; + } else + state = PRINT_S_DOT; + break; + case PRINT_S_DOT: + if (ch == '.') { + state = PRINT_S_PRECISION; + ch = *format++; + } else + state = PRINT_S_MOD; + break; + case PRINT_S_PRECISION: + if (precision == -1) + precision = 0; + if (ISDIGIT(ch)) { + ch = CHARTOINT(ch); + if (precision > (INT_MAX - ch) / 10) { + overflow = 1; + goto out; + } + precision = 10 * precision + ch; + ch = *format++; + } else if (ch == '*') { + /* + * C99 says: "A negative precision argument is + * taken as if the precision were omitted." + * (7.19.6.1, 5) + */ + if ((precision = va_arg(args, int)) < 0) + precision = -1; + ch = *format++; + state = PRINT_S_MOD; + } else + state = PRINT_S_MOD; + break; + case PRINT_S_MOD: + switch (ch) { + case 'h': + ch = *format++; + if (ch == 'h') { /* It's a char. */ + ch = *format++; + cflags = PRINT_C_CHAR; + } else + cflags = PRINT_C_SHORT; + break; + case 'l': + ch = *format++; + if (ch == 'l') { /* It's a long long. */ + ch = *format++; + cflags = PRINT_C_LLONG; + } else + cflags = PRINT_C_LONG; + break; + case 'L': + cflags = PRINT_C_LDOUBLE; + ch = *format++; + break; + case 'j': + cflags = PRINT_C_INTMAX; + ch = *format++; + break; + case 't': + cflags = PRINT_C_PTRDIFF; + ch = *format++; + break; + case 'z': + cflags = PRINT_C_SIZE; + ch = *format++; + break; + } + state = PRINT_S_CONV; + break; + case PRINT_S_CONV: + switch (ch) { + case 'd': + /* FALLTHROUGH */ + case 'i': + switch (cflags) { + case PRINT_C_CHAR: + value = (signed char)va_arg(args, int); + break; + case PRINT_C_SHORT: + value = (short int)va_arg(args, int); + break; + case PRINT_C_LONG: + value = va_arg(args, long int); + break; + case PRINT_C_LLONG: + value = va_arg(args, LLONG); + break; + case PRINT_C_SIZE: + value = va_arg(args, SSIZE_T); + break; + case PRINT_C_INTMAX: + value = va_arg(args, INTMAX_T); + break; + case PRINT_C_PTRDIFF: + value = va_arg(args, PTRDIFF_T); + break; + default: + value = va_arg(args, int); + break; + } + fmtint(str, &len, size, value, 10, width, + precision, flags); + break; + case 'X': + flags |= PRINT_F_UP; + /* FALLTHROUGH */ + case 'x': + base = 16; + /* FALLTHROUGH */ + case 'o': + if (base == 0) + base = 8; + /* FALLTHROUGH */ + case 'u': + if (base == 0) + base = 10; + flags |= PRINT_F_UNSIGNED; + switch (cflags) { + case PRINT_C_CHAR: + value = (unsigned char)va_arg(args, + unsigned int); + break; + case PRINT_C_SHORT: + value = (unsigned short int)va_arg(args, + unsigned int); + break; + case PRINT_C_LONG: + value = va_arg(args, unsigned long int); + break; + case PRINT_C_LLONG: + value = va_arg(args, ULLONG); + break; + case PRINT_C_SIZE: + value = va_arg(args, size_t); + break; + case PRINT_C_INTMAX: + value = va_arg(args, UINTMAX_T); + break; + case PRINT_C_PTRDIFF: + value = va_arg(args, UPTRDIFF_T); + break; + default: + value = va_arg(args, unsigned int); + break; + } + fmtint(str, &len, size, value, base, width, + precision, flags); + break; + case 'A': + /* Not yet supported, we'll use "%F". */ + /* FALLTHROUGH */ + case 'F': + flags |= PRINT_F_UP; + case 'a': + /* Not yet supported, we'll use "%f". */ + /* FALLTHROUGH */ + case 'f': + if (cflags == PRINT_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + fmtflt(str, &len, size, fvalue, width, + precision, flags, &overflow); + if (overflow) + goto out; + break; + case 'E': + flags |= PRINT_F_UP; + /* FALLTHROUGH */ + case 'e': + flags |= PRINT_F_TYPE_E; + if (cflags == PRINT_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + fmtflt(str, &len, size, fvalue, width, + precision, flags, &overflow); + if (overflow) + goto out; + break; + case 'G': + flags |= PRINT_F_UP; + /* FALLTHROUGH */ + case 'g': + flags |= PRINT_F_TYPE_G; + if (cflags == PRINT_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + /* + * If the precision is zero, it is treated as + * one (cf. C99: 7.19.6.1, 8). + */ + if (precision == 0) + precision = 1; + fmtflt(str, &len, size, fvalue, width, + precision, flags, &overflow); + if (overflow) + goto out; + break; + case 'c': + cvalue = va_arg(args, int); + OUTCHAR(str, len, size, cvalue); + break; + case 's': + strvalue = va_arg(args, char *); + fmtstr(str, &len, size, strvalue, width, + precision, flags); + break; + case 'p': + /* + * C99 says: "The value of the pointer is + * converted to a sequence of printing + * characters, in an implementation-defined + * manner." (C99: 7.19.6.1, 8) + */ + if ((strvalue = va_arg(args, void *)) == NULL) + /* + * We use the glibc format. BSD prints + * "0x0", SysV "0". + */ + fmtstr(str, &len, size, "(nil)", width, + -1, flags); + else { + /* + * We use the BSD/glibc format. SysV + * omits the "0x" prefix (which we emit + * using the PRINT_F_NUM flag). + */ + flags |= PRINT_F_NUM; + flags |= PRINT_F_UNSIGNED; + fmtint(str, &len, size, + (UINTPTR_T)strvalue, 16, width, + precision, flags); + } + break; + case 'n': + switch (cflags) { + case PRINT_C_CHAR: + charptr = va_arg(args, signed char *); + *charptr = len; + break; + case PRINT_C_SHORT: + shortptr = va_arg(args, short int *); + *shortptr = len; + break; + case PRINT_C_LONG: + longptr = va_arg(args, long int *); + *longptr = len; + break; + case PRINT_C_LLONG: + llongptr = va_arg(args, LLONG *); + *llongptr = len; + break; + case PRINT_C_SIZE: + /* + * C99 says that with the "z" length + * modifier, "a following `n' conversion + * specifier applies to a pointer to a + * signed integer type corresponding to + * size_t argument." (7.19.6.1, 7) + */ + sizeptr = va_arg(args, SSIZE_T *); + *sizeptr = len; + break; + case PRINT_C_INTMAX: + intmaxptr = va_arg(args, INTMAX_T *); + *intmaxptr = len; + break; + case PRINT_C_PTRDIFF: + ptrdiffptr = va_arg(args, PTRDIFF_T *); + *ptrdiffptr = len; + break; + default: + intptr = va_arg(args, int *); + *intptr = len; + break; + } + break; + case '%': /* Print a "%" character verbatim. */ + OUTCHAR(str, len, size, ch); + break; + default: /* Skip other characters. */ + break; + } + ch = *format++; + state = PRINT_S_DEFAULT; + base = cflags = flags = width = 0; + precision = -1; + break; + } +out: + if (len < size) + str[len] = '\0'; + else if (size > 0) + str[size - 1] = '\0'; + + if (overflow || len >= INT_MAX) { + errno = overflow ? EOVERFLOW : ERANGE; + return -1; + } + return (int)len; +} + +static void +fmtstr(char *str, size_t *len, size_t size, const char *value, int width, + int precision, int flags) +{ + int padlen, strln; /* Amount to pad. */ + int noprecision = (precision == -1); + + if (value == NULL) /* We're forgiving. */ + value = "(null)"; + + /* If a precision was specified, don't read the string past it. */ + for (strln = 0; value[strln] != '\0' && + (noprecision || strln < precision); strln++) + continue; + + if ((padlen = width - strln) < 0) + padlen = 0; + if (flags & PRINT_F_MINUS) /* Left justify. */ + padlen = -padlen; + + while (padlen > 0) { /* Leading spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen--; + } + while (*value != '\0' && (noprecision || precision-- > 0)) { + OUTCHAR(str, *len, size, *value); + value++; + } + while (padlen < 0) { /* Trailing spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen++; + } +} + +static void +fmtint(char *str, size_t *len, size_t size, INTMAX_T value, int base, int width, + int precision, int flags) +{ + UINTMAX_T uvalue; + char iconvert[MAX_CONVERT_LENGTH]; + char sign = 0; + char hexprefix = 0; + int spadlen = 0; /* Amount to space pad. */ + int zpadlen = 0; /* Amount to zero pad. */ + int pos; + int separators = (flags & PRINT_F_QUOTE); + int noprecision = (precision == -1); + + if (flags & PRINT_F_UNSIGNED) + uvalue = value; + else { + uvalue = (value >= 0) ? value : -value; + if (value < 0) + sign = '-'; + else if (flags & PRINT_F_PLUS) /* Do a sign. */ + sign = '+'; + else if (flags & PRINT_F_SPACE) + sign = ' '; + } + + pos = convert(uvalue, iconvert, sizeof(iconvert), base, + flags & PRINT_F_UP); + + if (flags & PRINT_F_NUM && uvalue != 0) { + /* + * C99 says: "The result is converted to an `alternative form'. + * For `o' conversion, it increases the precision, if and only + * if necessary, to force the first digit of the result to be a + * zero (if the value and precision are both 0, a single 0 is + * printed). For `x' (or `X') conversion, a nonzero result has + * `0x' (or `0X') prefixed to it." (7.19.6.1, 6) + */ + switch (base) { + case 8: + if (precision <= pos) + precision = pos + 1; + break; + case 16: + hexprefix = (flags & PRINT_F_UP) ? 'X' : 'x'; + break; + } + } + + if (separators) /* Get the number of group separators we'll print. */ + separators = getnumsep(pos); + + zpadlen = precision - pos - separators; + spadlen = width /* Minimum field width. */ + - separators /* Number of separators. */ + - MAX(precision, pos) /* Number of integer digits. */ + - ((sign != 0) ? 1 : 0) /* Will we print a sign? */ + - ((hexprefix != 0) ? 2 : 0); /* Will we print a prefix? */ + + if (zpadlen < 0) + zpadlen = 0; + if (spadlen < 0) + spadlen = 0; + + /* + * C99 says: "If the `0' and `-' flags both appear, the `0' flag is + * ignored. For `d', `i', `o', `u', `x', and `X' conversions, if a + * precision is specified, the `0' flag is ignored." (7.19.6.1, 6) + */ + if (flags & PRINT_F_MINUS) /* Left justify. */ + spadlen = -spadlen; + else if (flags & PRINT_F_ZERO && noprecision) { + zpadlen += spadlen; + spadlen = 0; + } + while (spadlen > 0) { /* Leading spaces. */ + OUTCHAR(str, *len, size, ' '); + spadlen--; + } + if (sign != 0) /* Sign. */ + OUTCHAR(str, *len, size, sign); + if (hexprefix != 0) { /* A "0x" or "0X" prefix. */ + OUTCHAR(str, *len, size, '0'); + OUTCHAR(str, *len, size, hexprefix); + } + while (zpadlen > 0) { /* Leading zeros. */ + OUTCHAR(str, *len, size, '0'); + zpadlen--; + } + while (pos > 0) { /* The actual digits. */ + pos--; + OUTCHAR(str, *len, size, iconvert[pos]); + if (separators > 0 && pos > 0 && pos % 3 == 0) + printsep(str, len, size); + } + while (spadlen < 0) { /* Trailing spaces. */ + OUTCHAR(str, *len, size, ' '); + spadlen++; + } +} + +static void +fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width, + int precision, int flags, int *overflow) +{ + LDOUBLE ufvalue; + UINTMAX_T intpart; + UINTMAX_T fracpart; + UINTMAX_T mask; + const char *infnan = NULL; + char iconvert[MAX_CONVERT_LENGTH]; + char fconvert[MAX_CONVERT_LENGTH]; + char econvert[4]; /* "e-12" (without nul-termination). */ + char esign = 0; + char sign = 0; + int leadfraczeros = 0; + int exponent = 0; + int emitpoint = 0; + int omitzeros = 0; + int omitcount = 0; + int padlen = 0; + int epos = 0; + int fpos = 0; + int ipos = 0; + int separators = (flags & PRINT_F_QUOTE); + int estyle = (flags & PRINT_F_TYPE_E); +#if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT + struct lconv *lc = localeconv(); +#endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ + + /* + * AIX' man page says the default is 0, but C99 and at least Solaris' + * and NetBSD's man pages say the default is 6, and sprintf(3) on AIX + * defaults to 6. + */ + if (precision == -1) + precision = 6; + + if (fvalue < 0.0) + sign = '-'; + else if (flags & PRINT_F_PLUS) /* Do a sign. */ + sign = '+'; + else if (flags & PRINT_F_SPACE) + sign = ' '; + + if (ISNAN(fvalue)) + infnan = (flags & PRINT_F_UP) ? "NAN" : "nan"; + else if (ISINF(fvalue)) + infnan = (flags & PRINT_F_UP) ? "INF" : "inf"; + + if (infnan != NULL) { + if (sign != 0) + iconvert[ipos++] = sign; + while (*infnan != '\0') + iconvert[ipos++] = *infnan++; + fmtstr(str, len, size, iconvert, width, ipos, flags); + return; + } + + /* "%e" (or "%E") or "%g" (or "%G") conversion. */ + if (flags & PRINT_F_TYPE_E || flags & PRINT_F_TYPE_G) { + if (flags & PRINT_F_TYPE_G) { + /* + * For "%g" (and "%G") conversions, the precision + * specifies the number of significant digits, which + * includes the digits in the integer part. The + * conversion will or will not be using "e-style" (like + * "%e" or "%E" conversions) depending on the precision + * and on the exponent. However, the exponent can be + * affected by rounding the converted value, so we'll + * leave this decision for later. Until then, we'll + * assume that we're going to do an "e-style" conversion + * (in order to get the exponent calculated). For + * "e-style", the precision must be decremented by one. + */ + precision--; + /* + * For "%g" (and "%G") conversions, trailing zeros are + * removed from the fractional portion of the result + * unless the "#" flag was specified. + */ + if (!(flags & PRINT_F_NUM)) + omitzeros = 1; + } + exponent = getexponent(fvalue); + estyle = 1; + } + +again: + /* + * Sorry, we only support 9, 19, or 38 digits (that is, the number of + * digits of the 32-bit, the 64-bit, or the 128-bit UINTMAX_MAX value + * minus one) past the decimal point due to our conversion method. + */ + switch (sizeof(UINTMAX_T)) { + case 16: + if (precision > 38) + precision = 38; + break; + case 8: + if (precision > 19) + precision = 19; + break; + default: + if (precision > 9) + precision = 9; + break; + } + + ufvalue = (fvalue >= 0.0) ? fvalue : -fvalue; + if (estyle) /* We want exactly one integer digit. */ + ufvalue /= mypow10(exponent); + + if ((intpart = cast(ufvalue)) == UINTMAX_MAX) { + *overflow = 1; + return; + } + + /* + * Factor of ten with the number of digits needed for the fractional + * part. For example, if the precision is 3, the mask will be 1000. + */ + mask = mypow10(precision); + /* + * We "cheat" by converting the fractional part to integer by + * multiplying by a factor of ten. + */ + if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) { + /* + * For example, ufvalue = 2.99962, intpart = 2, and mask = 1000 + * (because precision = 3). Now, myround(1000 * 0.99962) will + * return 1000. So, the integer part must be incremented by one + * and the fractional part must be set to zero. + */ + intpart++; + fracpart = 0; + if (estyle && intpart == 10) { + /* + * The value was rounded up to ten, but we only want one + * integer digit if using "e-style". So, the integer + * part must be set to one and the exponent must be + * incremented by one. + */ + intpart = 1; + exponent++; + } + } + + /* + * Now that we know the real exponent, we can check whether or not to + * use "e-style" for "%g" (and "%G") conversions. If we don't need + * "e-style", the precision must be adjusted and the integer and + * fractional parts must be recalculated from the original value. + * + * C99 says: "Let P equal the precision if nonzero, 6 if the precision + * is omitted, or 1 if the precision is zero. Then, if a conversion + * with style `E' would have an exponent of X: + * + * - if P > X >= -4, the conversion is with style `f' (or `F') and + * precision P - (X + 1). + * + * - otherwise, the conversion is with style `e' (or `E') and precision + * P - 1." (7.19.6.1, 8) + * + * Note that we had decremented the precision by one. + */ + if (flags & PRINT_F_TYPE_G && estyle && + precision + 1 > exponent && exponent >= -4) { + precision -= exponent; + estyle = 0; + goto again; + } + + if (estyle) { + if (exponent < 0) { + exponent = -exponent; + esign = '-'; + } else + esign = '+'; + + /* + * Convert the exponent. The sizeof(econvert) is 4. So, the + * econvert buffer can hold e.g. "e+99" and "e-99". We don't + * support an exponent which contains more than two digits. + * Therefore, the following stores are safe. + */ + epos = convert(exponent, econvert, 2, 10, 0); + /* + * C99 says: "The exponent always contains at least two digits, + * and only as many more digits as necessary to represent the + * exponent." (7.19.6.1, 8) + */ + if (epos == 1) + econvert[epos++] = '0'; + econvert[epos++] = esign; + econvert[epos++] = (flags & PRINT_F_UP) ? 'E' : 'e'; + } + + /* Convert the integer part and the fractional part. */ + ipos = convert(intpart, iconvert, sizeof(iconvert), 10, 0); + if (fracpart != 0) /* convert() would return 1 if fracpart == 0. */ + fpos = convert(fracpart, fconvert, sizeof(fconvert), 10, 0); + + leadfraczeros = precision - fpos; + + if (omitzeros) { + if (fpos > 0) /* Omit trailing fractional part zeros. */ + while (omitcount < fpos && fconvert[omitcount] == '0') + omitcount++; + else { /* The fractional part is zero, omit it completely. */ + omitcount = precision; + leadfraczeros = 0; + } + precision -= omitcount; + } + + /* + * Print a decimal point if either the fractional part is non-zero + * and/or the "#" flag was specified. + */ + if (precision > 0 || flags & PRINT_F_NUM) + emitpoint = 1; + if (separators) /* Get the number of group separators we'll print. */ + separators = getnumsep(ipos); + + padlen = width /* Minimum field width. */ + - ipos /* Number of integer digits. */ + - epos /* Number of exponent characters. */ + - precision /* Number of fractional digits. */ + - separators /* Number of group separators. */ + - (emitpoint ? 1 : 0) /* Will we print a decimal point? */ + - ((sign != 0) ? 1 : 0); /* Will we print a sign character? */ + + if (padlen < 0) + padlen = 0; + + /* + * C99 says: "If the `0' and `-' flags both appear, the `0' flag is + * ignored." (7.19.6.1, 6) + */ + if (flags & PRINT_F_MINUS) /* Left justifty. */ + padlen = -padlen; + else if (flags & PRINT_F_ZERO && padlen > 0) { + if (sign != 0) { /* Sign. */ + OUTCHAR(str, *len, size, sign); + sign = 0; + } + while (padlen > 0) { /* Leading zeros. */ + OUTCHAR(str, *len, size, '0'); + padlen--; + } + } + while (padlen > 0) { /* Leading spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen--; + } + if (sign != 0) /* Sign. */ + OUTCHAR(str, *len, size, sign); + while (ipos > 0) { /* Integer part. */ + ipos--; + OUTCHAR(str, *len, size, iconvert[ipos]); + if (separators > 0 && ipos > 0 && ipos % 3 == 0) + printsep(str, len, size); + } + if (emitpoint) { /* Decimal point. */ +#if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT + if (lc->decimal_point != NULL && *lc->decimal_point != '\0') + OUTCHAR(str, *len, size, *lc->decimal_point); + else /* We'll always print some decimal point character. */ +#endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ + OUTCHAR(str, *len, size, '.'); + } + while (leadfraczeros > 0) { /* Leading fractional part zeros. */ + OUTCHAR(str, *len, size, '0'); + leadfraczeros--; + } + while (fpos > omitcount) { /* The remaining fractional part. */ + fpos--; + OUTCHAR(str, *len, size, fconvert[fpos]); + } + while (epos > 0) { /* Exponent. */ + epos--; + OUTCHAR(str, *len, size, econvert[epos]); + } + while (padlen < 0) { /* Trailing spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen++; + } +} + +static void +printsep(char *str, size_t *len, size_t size) +{ +#if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP + struct lconv *lc = localeconv(); + int i; + + if (lc->thousands_sep != NULL) + for (i = 0; lc->thousands_sep[i] != '\0'; i++) + OUTCHAR(str, *len, size, lc->thousands_sep[i]); + else +#endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ + OUTCHAR(str, *len, size, ','); +} + +static int +getnumsep(int digits) +{ + int separators = (digits - ((digits % 3 == 0) ? 1 : 0)) / 3; +#if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP + int strln; + struct lconv *lc = localeconv(); + + /* We support an arbitrary separator length (including zero). */ + if (lc->thousands_sep != NULL) { + for (strln = 0; lc->thousands_sep[strln] != '\0'; strln++) + continue; + separators *= strln; + } +#endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ + return separators; +} + +static int +getexponent(LDOUBLE value) +{ + LDOUBLE tmp = (value >= 0.0) ? value : -value; + int exponent = 0; + + /* + * We check for 99 > exponent > -99 in order to work around possible + * endless loops which could happen (at least) in the second loop (at + * least) if we're called with an infinite value. However, we checked + * for infinity before calling this function using our ISINF() macro, so + * this might be somewhat paranoid. + */ + while (tmp < 1.0 && tmp > 0.0 && --exponent > -99) + tmp *= 10; + while (tmp >= 10.0 && ++exponent < 99) + tmp /= 10; + + return exponent; +} + +static int +convert(UINTMAX_T value, char *buf, size_t size, int base, int caps) +{ + const char *digits = caps ? "0123456789ABCDEF" : "0123456789abcdef"; + size_t pos = 0; + + /* We return an unterminated buffer with the digits in reverse order. */ + do { + buf[pos++] = digits[value % base]; + value /= base; + } while (value != 0 && pos < size); + + return (int)pos; +} + +static UINTMAX_T +cast(LDOUBLE value) +{ + UINTMAX_T result; + + /* + * We check for ">=" and not for ">" because if UINTMAX_MAX cannot be + * represented exactly as an LDOUBLE value (but is less than LDBL_MAX), + * it may be increased to the nearest higher representable value for the + * comparison (cf. C99: 6.3.1.4, 2). It might then equal the LDOUBLE + * value although converting the latter to UINTMAX_T would overflow. + */ + if (value >= UINTMAX_MAX) + return UINTMAX_MAX; + + result = value; + /* + * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to + * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates + * the standard). Sigh. + */ + return (result <= value) ? result : result - 1; +} + +static UINTMAX_T +myround(LDOUBLE value) +{ + UINTMAX_T intpart = cast(value); + + return ((value -= intpart) < 0.5) ? intpart : intpart + 1; +} + +static LDOUBLE +mypow10(int exponent) +{ + LDOUBLE result = 1; + + while (exponent > 0) { + result *= 10; + exponent--; + } + while (exponent < 0) { + result /= 10; + exponent++; + } + return result; +} +#endif /* !HAVE_VSNPRINTF */ + +#if !HAVE_VASPRINTF +#if NEED_MYMEMCPY +void * +mymemcpy(void *dst, void *src, size_t len) +{ + const char *from = src; + char *to = dst; + + /* No need for optimization, we use this only to replace va_copy(3). */ + while (len-- > 0) + *to++ = *from++; + return dst; +} +#endif /* NEED_MYMEMCPY */ + +int +rpl_vasprintf(char **ret, const char *format, va_list ap) +{ + size_t size; + int len; + va_list aq; + + VA_COPY(aq, ap); + len = vsnprintf(NULL, 0, format, aq); + VA_END_COPY(aq); + if (len < 0 || (*ret = malloc(size = len + 1)) == NULL) + return -1; + return vsnprintf(*ret, size, format, ap); +} +#endif /* !HAVE_VASPRINTF */ + +#if !HAVE_SNPRINTF +#if HAVE_STDARG_H +int +rpl_snprintf(char *str, size_t size, const char *format, ...) +#else +int +rpl_snprintf(va_alist) va_dcl +#endif /* HAVE_STDARG_H */ +{ +#if !HAVE_STDARG_H + char *str; + size_t size; + char *format; +#endif /* HAVE_STDARG_H */ + va_list ap; + int len; + + VA_START(ap, format); + VA_SHIFT(ap, str, char *); + VA_SHIFT(ap, size, size_t); + VA_SHIFT(ap, format, const char *); + len = vsnprintf(str, size, format, ap); + va_end(ap); + return len; +} +#endif /* !HAVE_SNPRINTF */ + +#if !HAVE_ASPRINTF +#if HAVE_STDARG_H +int +rpl_asprintf(char **ret, const char *format, ...) +#else +int +rpl_asprintf(va_alist) va_dcl +#endif /* HAVE_STDARG_H */ +{ +#if !HAVE_STDARG_H + char **ret; + char *format; +#endif /* HAVE_STDARG_H */ + va_list ap; + int len; + + VA_START(ap, format); + VA_SHIFT(ap, ret, char **); + VA_SHIFT(ap, format, const char *); + len = vasprintf(ret, format, ap); + va_end(ap); + return len; +} +#endif /* !HAVE_ASPRINTF */ +#else /* Dummy declaration to avoid empty translation unit warnings. */ +int main(void); +#endif /* !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || [...] */ + + +/* vim: set joinspaces textwidth=80: */ -- cgit v1.2.3 From 4528287e040415c2071012d02f20979ff995c754 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 5 Mar 2008 10:50:14 +0100 Subject: gallium: michel's patch to rework texture/sampler binding interface Bind all the samplers/textures at once rather than piecemeal. This is easier for drivers to understand. --- src/gallium/auxiliary/draw/draw_aaline.c | 54 +- src/gallium/auxiliary/draw/draw_pstipple.c | 51 +- src/gallium/drivers/failover/fo_context.h | 7 +- src/gallium/drivers/failover/fo_state.c | 59 +- src/gallium/drivers/failover/fo_state_emit.c | 18 +- src/gallium/drivers/i915simple/i915_context.h | 675 +++++----- src/gallium/drivers/i915simple/i915_state.c | 46 +- src/gallium/drivers/i915simple/i915_state_emit.c | 6 - .../drivers/i915simple/i915_state_sampler.c | 6 +- src/gallium/drivers/i965simple/brw_context.h | 1365 ++++++++++---------- src/gallium/drivers/i965simple/brw_state.c | 896 ++++++------- .../drivers/i965simple/brw_wm_sampler_state.c | 3 +- .../drivers/i965simple/brw_wm_surface_state.c | 2 +- src/gallium/drivers/softpipe/sp_context.c | 486 +++---- src/gallium/drivers/softpipe/sp_context.h | 3 + src/gallium/drivers/softpipe/sp_quad_fs.c | 417 +++--- src/gallium/drivers/softpipe/sp_state.h | 390 +++--- src/gallium/drivers/softpipe/sp_state_sampler.c | 56 +- src/gallium/drivers/softpipe/sp_texture.c | 404 +++--- src/gallium/include/pipe/p_context.h | 8 +- 20 files changed, 2528 insertions(+), 2424 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index 7660e56fe6..3ec73b0800 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -78,7 +78,8 @@ struct aaline_stage void *sampler_cso; struct pipe_texture *texture; - uint sampler_unit; + uint num_samplers; + uint num_textures; /* @@ -98,11 +99,10 @@ struct aaline_stage void (*driver_bind_fs_state)(struct pipe_context *, void *); void (*driver_delete_fs_state)(struct pipe_context *, void *); - void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *); - - void (*driver_set_sampler_texture)(struct pipe_context *, - unsigned sampler, - struct pipe_texture *); + void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, + void **); + void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, + struct pipe_texture **); struct pipe_context *pipe; }; @@ -607,6 +607,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) auto struct aaline_stage *aaline = aaline_stage(stage); struct draw_context *draw = stage->draw; struct pipe_context *pipe = aaline->pipe; + uint num = MAX2(aaline->num_textures, aaline->num_samplers); assert(draw->rasterizer->line_smooth); @@ -624,8 +625,11 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) */ bind_aaline_fragment_shader(aaline); - aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit, aaline->sampler_cso); - aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit, aaline->texture); + aaline->state.sampler[num] = aaline->sampler_cso; + aaline->state.texture[num] = aaline->texture; + + aaline->driver_bind_sampler_states(pipe, num + 1, aaline->state.sampler); + aaline->driver_set_sampler_textures(pipe, num + 1, aaline->state.texture); /* now really draw first line */ stage->line = aaline_line; @@ -647,10 +651,10 @@ aaline_flush(struct draw_stage *stage, unsigned flags) aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); /* XXX restore original texture, sampler state */ - aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit, - aaline->state.sampler[aaline->sampler_unit]); - aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit, - aaline->state.texture[aaline->sampler_unit]); + aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, + aaline->state.sampler); + aaline->driver_set_sampler_textures(pipe, aaline->num_textures, + aaline->state.texture); draw->extra_vp_outputs.slot = 0; } @@ -745,26 +749,28 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs) static void -aaline_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) +aaline_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); /* save current */ - aaline->state.sampler[unit] = sampler; + memcpy(aaline->state.sampler, sampler, num * sizeof(void *)); + aaline->num_samplers = num; /* pass-through */ - aaline->driver_bind_sampler_state(aaline->pipe, unit, sampler); + aaline->driver_bind_sampler_states(aaline->pipe, num, sampler); } static void -aaline_set_sampler_texture(struct pipe_context *pipe, - unsigned sampler, struct pipe_texture *texture) +aaline_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); /* save current */ - aaline->state.texture[sampler] = texture; + memcpy(aaline->state.texture, texture, num * sizeof(struct pipe_texture *)); + aaline->num_textures = num; /* pass-through */ - aaline->driver_set_sampler_texture(aaline->pipe, sampler, texture); + aaline->driver_set_sampler_textures(aaline->pipe, num, texture); } @@ -798,14 +804,14 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) aaline->driver_bind_fs_state = pipe->bind_fs_state; aaline->driver_delete_fs_state = pipe->delete_fs_state; - aaline->driver_bind_sampler_state = pipe->bind_sampler_state; - aaline->driver_set_sampler_texture = pipe->set_sampler_texture; + aaline->driver_bind_sampler_states = pipe->bind_sampler_states; + aaline->driver_set_sampler_textures = pipe->set_sampler_textures; /* override the driver's functions */ pipe->create_fs_state = aaline_create_fs_state; pipe->bind_fs_state = aaline_bind_fs_state; pipe->delete_fs_state = aaline_delete_fs_state; - pipe->bind_sampler_state = aaline_bind_sampler_state; - pipe->set_sampler_texture = aaline_set_sampler_texture; + pipe->bind_sampler_states = aaline_bind_sampler_states; + pipe->set_sampler_textures = aaline_set_sampler_textures; } diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index 2cfeb813b3..894b136f2c 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -68,7 +68,8 @@ struct pstip_stage void *sampler_cso; struct pipe_texture *texture; - uint sampler_unit; + uint num_samplers; + uint num_textures; /* * Currently bound state @@ -88,11 +89,10 @@ struct pstip_stage void (*driver_bind_fs_state)(struct pipe_context *, void *); void (*driver_delete_fs_state)(struct pipe_context *, void *); - void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *); + void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **); - void (*driver_set_sampler_texture)(struct pipe_context *, - unsigned sampler, - struct pipe_texture *); + void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, + struct pipe_texture **); void (*driver_set_polygon_stipple)(struct pipe_context *, const struct pipe_poly_stipple *); @@ -328,8 +328,6 @@ generate_pstip_fs(struct pstip_stage *pstip) tgsi_dump(pstip_fs.tokens, 0); #endif - pstip->sampler_unit = transform.maxSampler + 1; - #if 1 /* XXX remove */ if (transform.wincoordInput < 0) { pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION; @@ -486,6 +484,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) struct pstip_stage *pstip = pstip_stage(stage); struct draw_context *draw = stage->draw; struct pipe_context *pipe = pstip->pipe; + uint num = MAX2(pstip->num_textures, pstip->num_samplers); assert(draw->rasterizer->poly_stipple_enable); @@ -494,8 +493,8 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) */ bind_pstip_fragment_shader(pstip); - pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit, pstip->sampler_cso); - pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit, pstip->texture); + pstip->driver_bind_sampler_states(pipe, num + 1, pstip->state.sampler); + pstip->driver_set_sampler_textures(pipe, num + 1, pstip->state.texture); /* now really draw first line */ stage->tri = passthrough_tri; @@ -517,10 +516,10 @@ pstip_flush(struct draw_stage *stage, unsigned flags) pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); /* XXX restore original texture, sampler state */ - pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit, - pstip->state.sampler[pstip->sampler_unit]); - pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit, - pstip->state.texture[pstip->sampler_unit]); + pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, + pstip->state.sampler); + pstip->driver_set_sampler_textures(pipe, pstip->num_textures, + pstip->state.texture); } @@ -613,26 +612,28 @@ pstip_delete_fs_state(struct pipe_context *pipe, void *fs) static void -pstip_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) +pstip_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); /* save current */ - pstip->state.sampler[unit] = sampler; + memcpy(pstip->state.sampler, sampler, num * sizeof(void *)); + pstip->num_samplers = num; /* pass-through */ - pstip->driver_bind_sampler_state(pstip->pipe, unit, sampler); + pstip->driver_bind_sampler_states(pstip->pipe, num, sampler); } static void -pstip_set_sampler_texture(struct pipe_context *pipe, - unsigned sampler, struct pipe_texture *texture) +pstip_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); /* save current */ - pstip->state.texture[sampler] = texture; + memcpy(pstip->state.texture, texture, num * sizeof(struct pipe_texture *)); + pstip->num_textures = num; /* pass-through */ - pstip->driver_set_sampler_texture(pstip->pipe, sampler, texture); + pstip->driver_set_sampler_textures(pstip->pipe, num, texture); } @@ -682,8 +683,8 @@ draw_install_pstipple_stage(struct draw_context *draw, pstip->driver_bind_fs_state = pipe->bind_fs_state; pstip->driver_delete_fs_state = pipe->delete_fs_state; - pstip->driver_bind_sampler_state = pipe->bind_sampler_state; - pstip->driver_set_sampler_texture = pipe->set_sampler_texture; + pstip->driver_bind_sampler_states = pipe->bind_sampler_states; + pstip->driver_set_sampler_textures = pipe->set_sampler_textures; pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; /* override the driver's functions */ @@ -691,7 +692,7 @@ draw_install_pstipple_stage(struct draw_context *draw, pipe->bind_fs_state = pstip_bind_fs_state; pipe->delete_fs_state = pstip_delete_fs_state; - pipe->bind_sampler_state = pstip_bind_sampler_state; - pipe->set_sampler_texture = pstip_set_sampler_texture; + pipe->bind_sampler_states = pstip_bind_sampler_states; + pipe->set_sampler_textures = pstip_set_sampler_textures; pipe->set_polygon_stipple = pstip_set_polygon_stipple; } diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 1dc87291c9..8f3ad3ee79 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -87,12 +87,15 @@ struct failover_context { struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + void *sw_sampler_state[PIPE_MAX_SAMPLERS]; + void *hw_sampler_state[PIPE_MAX_SAMPLERS]; + unsigned dirty; - unsigned dirty_sampler; - unsigned dirty_texture; unsigned dirty_vertex_buffer; unsigned dirty_vertex_element; + unsigned num_samplers; + unsigned num_textures; unsigned mode; struct pipe_context *hw; diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index 0fc5568da1..11eec2714e 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -28,6 +28,8 @@ /* Authors: Keith Whitwell */ +#include "pipe/p_inlines.h" + #include "fo_context.h" @@ -322,18 +324,27 @@ failover_create_sampler_state(struct pipe_context *pipe, } static void -failover_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) +failover_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) { struct failover_context *failover = failover_context(pipe); struct fo_state *state = (struct fo_state*)sampler; - failover->sampler[unit] = state; + uint i; + assert(num <= PIPE_MAX_SAMPLERS); + /* Check for no-op */ + if (num == failover->num_samplers && + !memcmp(failover->sampler, sampler, num * sizeof(void *))) + return; + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + failover->sw_sampler_state[i] = i < num ? state[i].sw_state : NULL; + failover->hw_sampler_state[i] = i < num ? state[i].hw_state : NULL; + } failover->dirty |= FO_NEW_SAMPLER; - failover->dirty_sampler |= (1<sw->bind_sampler_state(failover->sw, unit, - state->sw_state); - failover->hw->bind_sampler_state(failover->hw, unit, - state->hw_state); + failover->num_samplers = num; + failover->sw->bind_sampler_states(failover->sw, num, + failover->sw_sampler_state); + failover->hw->bind_sampler_states(failover->hw, num, + failover->hw_sampler_state); } static void @@ -351,17 +362,29 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler) static void -failover_set_sampler_texture(struct pipe_context *pipe, - unsigned unit, - struct pipe_texture *texture) +failover_set_sampler_textures(struct pipe_context *pipe, + unsigned num, + struct pipe_texture **texture) { struct failover_context *failover = failover_context(pipe); - - failover->texture[unit] = texture; + uint i; + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == failover->num_textures && + !memcmp(failover->texture, texture, num * sizeof(struct pipe_texture *))) + return; + for (i = 0; i < num; i++) + pipe_texture_reference((struct pipe_texture **) &failover->texture[i], + texture[i]); + for (i = num; i < failover->num_textures; i++) + pipe_texture_reference((struct pipe_texture **) &failover->texture[i], + NULL); failover->dirty |= FO_NEW_TEXTURE; - failover->dirty_texture |= (1<sw->set_sampler_texture( failover->sw, unit, texture ); - failover->hw->set_sampler_texture( failover->hw, unit, texture ); + failover->num_textures = num; + failover->sw->set_sampler_textures( failover->sw, num, texture ); + failover->hw->set_sampler_textures( failover->hw, num, texture ); } @@ -429,7 +452,7 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.bind_blend_state = failover_bind_blend_state; failover->pipe.delete_blend_state = failover_delete_blend_state; failover->pipe.create_sampler_state = failover_create_sampler_state; - failover->pipe.bind_sampler_state = failover_bind_sampler_state; + failover->pipe.bind_sampler_states = failover_bind_sampler_states; failover->pipe.delete_sampler_state = failover_delete_sampler_state; failover->pipe.create_depth_stencil_alpha_state = failover_create_depth_stencil_state; failover->pipe.bind_depth_stencil_alpha_state = failover_bind_depth_stencil_state; @@ -449,7 +472,7 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.set_framebuffer_state = failover_set_framebuffer_state; failover->pipe.set_polygon_stipple = failover_set_polygon_stipple; failover->pipe.set_scissor_state = failover_set_scissor_state; - failover->pipe.set_sampler_texture = failover_set_sampler_texture; + failover->pipe.set_sampler_textures = failover_set_sampler_textures; failover->pipe.set_viewport_state = failover_set_viewport_state; failover->pipe.set_vertex_buffer = failover_set_vertex_buffer; failover->pipe.set_vertex_element = failover_set_vertex_element; diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c index c663dd4947..3de931e04e 100644 --- a/src/gallium/drivers/failover/fo_state_emit.c +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -94,21 +94,13 @@ failover_state_emit( struct failover_context *failover ) failover->sw->set_viewport_state( failover->sw, &failover->viewport ); if (failover->dirty & FO_NEW_SAMPLER) { - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - if (failover->dirty_sampler & (1<sw->bind_sampler_state( failover->sw, i, - failover->sampler[i]->sw_state ); - } - } + failover->sw->bind_sampler_states( failover->sw, failover->num_samplers, + failover->sw_sampler_state ); } if (failover->dirty & FO_NEW_TEXTURE) { - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - if (failover->dirty_texture & (1<sw->set_sampler_texture( failover->sw, i, - failover->texture[i] ); - } - } + failover->sw->set_sampler_textures( failover->sw, failover->num_textures, + failover->texture ); } if (failover->dirty & FO_NEW_VERTEX_BUFFER) { @@ -132,6 +124,4 @@ failover_state_emit( struct failover_context *failover ) failover->dirty = 0; failover->dirty_vertex_element = 0; failover->dirty_vertex_buffer = 0; - failover->dirty_texture = 0; - failover->dirty_sampler = 0; } diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 6401112f83..746f18ba38 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -1,336 +1,339 @@ - /************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef I915_CONTEXT_H -#define I915_CONTEXT_H - - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "draw/draw_vertex.h" - -#include "tgsi/util/tgsi_scan.h" - - -#define I915_TEX_UNITS 8 - -#define I915_DYNAMIC_MODES4 0 -#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */ -#define I915_DYNAMIC_DEPTHSCALE_1 2 -#define I915_DYNAMIC_IAB 3 -#define I915_DYNAMIC_BC_0 4 /* just the header */ -#define I915_DYNAMIC_BC_1 5 -#define I915_DYNAMIC_BFO_0 6 -#define I915_DYNAMIC_BFO_1 7 -#define I915_DYNAMIC_STP_0 8 -#define I915_DYNAMIC_STP_1 9 -#define I915_DYNAMIC_SC_ENA_0 10 -#define I915_DYNAMIC_SC_RECT_0 11 -#define I915_DYNAMIC_SC_RECT_1 12 -#define I915_DYNAMIC_SC_RECT_2 13 -#define I915_MAX_DYNAMIC 14 - - -#define I915_IMMEDIATE_S0 0 -#define I915_IMMEDIATE_S1 1 -#define I915_IMMEDIATE_S2 2 -#define I915_IMMEDIATE_S3 3 -#define I915_IMMEDIATE_S4 4 -#define I915_IMMEDIATE_S5 5 -#define I915_IMMEDIATE_S6 6 -#define I915_IMMEDIATE_S7 7 -#define I915_MAX_IMMEDIATE 8 - -/* These must mach the order of LI0_STATE_* bits, as they will be used - * to generate hardware packets: - */ -#define I915_CACHE_STATIC 0 -#define I915_CACHE_DYNAMIC 1 /* handled specially */ -#define I915_CACHE_SAMPLER 2 -#define I915_CACHE_MAP 3 -#define I915_CACHE_PROGRAM 4 -#define I915_CACHE_CONSTANTS 5 -#define I915_MAX_CACHE 6 - -#define I915_MAX_CONSTANT 32 - - -/** See constant_flags[] below */ -#define I915_CONSTFLAG_USER 0x1f - - -/** - * Subclass of pipe_shader_state - */ -struct i915_fragment_shader -{ - struct pipe_shader_state state; - - struct tgsi_shader_info info; - - uint *program; - uint program_len; - - /** - * constants introduced during translation. - * These are placed at the end of the constant buffer and grow toward - * the beginning (eg: slot 31, 30 29, ...) - * User-provided constants start at 0. - * This allows both types of constants to co-exist (until there's too many) - * and doesn't require regenerating/changing the fragment program to - * shuffle constants around. - */ - uint num_constants; - float constants[I915_MAX_CONSTANT][4]; - - /** - * Status of each constant - * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding - * slot of the user's constant buffer. (set by pipe->set_constant_buffer()) - * Else, the bitmask indicates which components are occupied by immediates. - */ - ubyte constant_flags[I915_MAX_CONSTANT]; -}; - - -struct i915_cache_context; - -/* Use to calculate differences between state emitted to hardware and - * current driver-calculated state. - */ -struct i915_state -{ - unsigned immediate[I915_MAX_IMMEDIATE]; - unsigned dynamic[I915_MAX_DYNAMIC]; - - float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4]; - /** number of constants passed in through a constant buffer */ - uint num_user_constants[PIPE_SHADER_TYPES]; - - /* texture sampler state */ - unsigned sampler[I915_TEX_UNITS][3]; - unsigned sampler_enable_flags; - unsigned sampler_enable_nr; - - /* texture image buffers */ - unsigned texbuffer[I915_TEX_UNITS][2]; - - /** Describes the current hardware vertex layout */ - struct vertex_info vertex_info; - - unsigned id; /* track lost context events */ -}; - -struct i915_blend_state { - unsigned iab; - unsigned modes4; - unsigned LIS5; - unsigned LIS6; -}; - -struct i915_depth_stencil_state { - unsigned stencil_modes4; - unsigned bfo[2]; - unsigned stencil_LIS5; - unsigned depth_LIS6; -}; - -struct i915_rasterizer_state { - int light_twoside : 1; - unsigned st; - enum interp_mode color_interp; - - unsigned LIS4; - unsigned LIS7; - unsigned sc[1]; - - const struct pipe_rasterizer_state *templ; - - union { float f; unsigned u; } ds[2]; -}; - -struct i915_sampler_state { - unsigned state[3]; - const struct pipe_sampler_state *templ; -}; - - -struct i915_texture { - struct pipe_texture base; - - /* Derived from the above: - */ - unsigned pitch; - unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; - - unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; - - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats - * are going to be so diverse that there is no unified way to - * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - */ - unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ - - /* Includes image offset tables: - */ - unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; - - /* The data is held here: - */ - struct pipe_buffer *buffer; -}; - -struct i915_context -{ - struct pipe_context pipe; - struct i915_winsys *winsys; - struct draw_context *draw; - - /* The most recent drawing state as set by the driver: - */ - const struct i915_blend_state *blend; - const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; - const struct i915_depth_stencil_state *depth_stencil; - const struct i915_rasterizer_state *rasterizer; - - struct i915_fragment_shader *fs; - - struct pipe_blend_color blend_color; - struct pipe_clip_state clip; - struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; - struct pipe_framebuffer_state framebuffer; - struct pipe_poly_stipple poly_stipple; - struct pipe_scissor_state scissor; - struct i915_texture *texture[PIPE_MAX_SAMPLERS]; - struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; - - unsigned dirty; - - unsigned *batch_start; - - /** Vertex buffer */ - struct pipe_buffer *vbo; - - struct i915_state current; - unsigned hardware_dirty; - - unsigned debug; -}; - -/* A flag for each state_tracker state object: - */ -#define I915_NEW_VIEWPORT 0x1 -#define I915_NEW_RASTERIZER 0x2 -#define I915_NEW_FS 0x4 -#define I915_NEW_BLEND 0x8 -#define I915_NEW_CLIP 0x10 -#define I915_NEW_SCISSOR 0x20 -#define I915_NEW_STIPPLE 0x40 -#define I915_NEW_FRAMEBUFFER 0x80 -#define I915_NEW_ALPHA_TEST 0x100 -#define I915_NEW_DEPTH_STENCIL 0x200 -#define I915_NEW_SAMPLER 0x400 -#define I915_NEW_TEXTURE 0x800 -#define I915_NEW_CONSTANTS 0x1000 -#define I915_NEW_VBO 0x2000 -#define I915_NEW_VS 0x4000 - - -/* Driver's internally generated state flags: - */ -#define I915_NEW_VERTEX_FORMAT 0x10000 - - -/* Dirty flags for hardware emit - */ -#define I915_HW_STATIC (1<set_constant_buffer()) + * Else, the bitmask indicates which components are occupied by immediates. + */ + ubyte constant_flags[I915_MAX_CONSTANT]; +}; + + +struct i915_cache_context; + +/* Use to calculate differences between state emitted to hardware and + * current driver-calculated state. + */ +struct i915_state +{ + unsigned immediate[I915_MAX_IMMEDIATE]; + unsigned dynamic[I915_MAX_DYNAMIC]; + + float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4]; + /** number of constants passed in through a constant buffer */ + uint num_user_constants[PIPE_SHADER_TYPES]; + + /* texture sampler state */ + unsigned sampler[I915_TEX_UNITS][3]; + unsigned sampler_enable_flags; + unsigned sampler_enable_nr; + + /* texture image buffers */ + unsigned texbuffer[I915_TEX_UNITS][2]; + + /** Describes the current hardware vertex layout */ + struct vertex_info vertex_info; + + unsigned id; /* track lost context events */ +}; + +struct i915_blend_state { + unsigned iab; + unsigned modes4; + unsigned LIS5; + unsigned LIS6; +}; + +struct i915_depth_stencil_state { + unsigned stencil_modes4; + unsigned bfo[2]; + unsigned stencil_LIS5; + unsigned depth_LIS6; +}; + +struct i915_rasterizer_state { + int light_twoside : 1; + unsigned st; + enum interp_mode color_interp; + + unsigned LIS4; + unsigned LIS7; + unsigned sc[1]; + + const struct pipe_rasterizer_state *templ; + + union { float f; unsigned u; } ds[2]; +}; + +struct i915_sampler_state { + unsigned state[3]; + const struct pipe_sampler_state *templ; +}; + + +struct i915_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +struct i915_context +{ + struct pipe_context pipe; + struct i915_winsys *winsys; + struct draw_context *draw; + + /* The most recent drawing state as set by the driver: + */ + const struct i915_blend_state *blend; + const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct i915_depth_stencil_state *depth_stencil; + const struct i915_rasterizer_state *rasterizer; + + struct i915_fragment_shader *fs; + + struct pipe_blend_color blend_color; + struct pipe_clip_state clip; + struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; + struct pipe_framebuffer_state framebuffer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct i915_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; + + unsigned dirty; + + unsigned num_samplers; + unsigned num_textures; + + unsigned *batch_start; + + /** Vertex buffer */ + struct pipe_buffer *vbo; + + struct i915_state current; + unsigned hardware_dirty; + + unsigned debug; +}; + +/* A flag for each state_tracker state object: + */ +#define I915_NEW_VIEWPORT 0x1 +#define I915_NEW_RASTERIZER 0x2 +#define I915_NEW_FS 0x4 +#define I915_NEW_BLEND 0x8 +#define I915_NEW_CLIP 0x10 +#define I915_NEW_SCISSOR 0x20 +#define I915_NEW_STIPPLE 0x40 +#define I915_NEW_FRAMEBUFFER 0x80 +#define I915_NEW_ALPHA_TEST 0x100 +#define I915_NEW_DEPTH_STENCIL 0x200 +#define I915_NEW_SAMPLER 0x400 +#define I915_NEW_TEXTURE 0x800 +#define I915_NEW_CONSTANTS 0x1000 +#define I915_NEW_VBO 0x2000 +#define I915_NEW_VS 0x4000 + + +/* Driver's internally generated state flags: + */ +#define I915_NEW_VERTEX_FORMAT 0x10000 + + +/* Dirty flags for hardware emit + */ +#define I915_HW_STATIC (1<sampler[unit] = (const struct i915_sampler_state*)sampler; + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == i915->num_samplers && + !memcmp(i915->sampler, sampler, num * sizeof(void *))) + return; + + memcpy(i915->sampler, sampler, num * sizeof(void *)); + memset(&i915->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) * sizeof(void *)); + + i915->num_samplers = num; i915->dirty |= I915_NEW_SAMPLER; } @@ -526,14 +535,29 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, } -static void i915_set_sampler_texture(struct pipe_context *pipe, - unsigned sampler, - struct pipe_texture *texture) +static void i915_set_sampler_textures(struct pipe_context *pipe, + unsigned num, + struct pipe_texture **texture) { struct i915_context *i915 = i915_context(pipe); + uint i; + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == i915->num_textures && + !memcmp(i915->texture, texture, num * sizeof(struct pipe_texture *))) + return; + + for (i = 0; i < num; i++) + pipe_texture_reference((struct pipe_texture **) &i915->texture[i], + texture[i]); + + for (i = num; i < i915->num_textures; i++) + pipe_texture_reference((struct pipe_texture **) &i915->texture[i], + NULL); - pipe_texture_reference((struct pipe_texture **) &i915->texture[sampler], - texture); + i915->num_textures = num; i915->dirty |= I915_NEW_TEXTURE; } @@ -691,7 +715,7 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.delete_blend_state = i915_delete_blend_state; i915->pipe.create_sampler_state = i915_create_sampler_state; - i915->pipe.bind_sampler_state = i915_bind_sampler_state; + i915->pipe.bind_sampler_states = i915_bind_sampler_states; i915->pipe.delete_sampler_state = i915_delete_sampler_state; i915->pipe.create_depth_stencil_alpha_state = i915_create_depth_stencil_state; @@ -715,7 +739,7 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.set_polygon_stipple = i915_set_polygon_stipple; i915->pipe.set_scissor_state = i915_set_scissor_state; - i915->pipe.set_sampler_texture = i915_set_sampler_texture; + i915->pipe.set_sampler_textures = i915_set_sampler_textures; i915->pipe.set_viewport_state = i915_set_viewport_state; i915->pipe.set_vertex_buffer = i915_set_vertex_buffer; i915->pipe.set_vertex_element = i915_set_vertex_element; diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 6bbaac4e34..a7498d22b7 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -267,12 +267,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) /* 2 + I915_TEX_UNITS*3 dwords, I915_TEX_UNITS relocs */ if (i915->hardware_dirty & (I915_HW_MAP | I915_HW_SAMPLER)) { - /* XXX: we were refering to sampler state - * (current.sampler_enable_nr) below, but only checking - * I915_HW_MAP above. Should probably calculate the enabled - * flags separately - but there will be further rework of - * state so perhaps not necessary yet. - */ const uint nr = i915->current.sampler_enable_nr; if (nr) { const uint enabled = i915->current.sampler_enable_flags; diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c index 9c1a5bbbd6..9dbb1b1b23 100644 --- a/src/gallium/drivers/i915simple/i915_state_sampler.c +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -106,7 +106,8 @@ void i915_update_samplers( struct i915_context *i915 ) i915->current.sampler_enable_nr = 0; i915->current.sampler_enable_flags = 0x0; - for (unit = 0; unit < I915_TEX_UNITS; unit++) { + for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers; + unit++) { /* determine unit enable/disable by looking for a bound texture */ /* could also examine the fragment program? */ if (i915->texture[unit]) { @@ -219,7 +220,8 @@ i915_update_textures(struct i915_context *i915) { uint unit; - for (unit = 0; unit < I915_TEX_UNITS; unit++) { + for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers; + unit++) { /* determine unit enable/disable by looking for a bound texture */ /* could also examine the fragment program? */ if (i915->texture[unit]) { diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index 4da3a8cffc..b83a13c3b6 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -1,681 +1,684 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - - -#ifndef BRWCONTEXT_INC -#define BRWCONTEXT_INC - - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "tgsi/util/tgsi_scan.h" - -#include "brw_structs.h" -#include "brw_winsys.h" - - -/* Glossary: - * - * URB - uniform resource buffer. A mid-sized buffer which is - * partitioned between the fixed function units and used for passing - * values (vertices, primitives, constants) between them. - * - * CURBE - constant URB entry. An urb region (entry) used to hold - * constant values which the fixed function units can be instructed to - * preload into the GRF when spawining a thread. - * - * VUE - vertex URB entry. An urb entry holding a vertex and usually - * a vertex header. The header contains control information and - * things like primitive type, Begin/end flags and clip codes. - * - * PUE - primitive URB entry. An urb entry produced by the setup (SF) - * unit holding rasterization and interpolation parameters. - * - * GRF - general register file. One of several register files - * addressable by programmed threads. The inputs (r0, payload, curbe, - * urb) of the thread are preloaded to this area before the thread is - * spawned. The registers are individually 8 dwords wide and suitable - * for general usage. Registers holding thread input values are not - * special and may be overwritten. - * - * MRF - message register file. Threads communicate (and terminate) - * by sending messages. Message parameters are placed in contigous - * MRF registers. All program output is via these messages. URB - * entries are populated by sending a message to the shared URB - * function containing the new data, together with a control word, - * often an unmodified copy of R0. - * - * R0 - GRF register 0. Typically holds control information used when - * sending messages to other threads. - * - * EU or GEN4 EU: The name of the programmable subsystem of the - * i965 hardware. Threads are executed by the EU, the registers - * described above are part of the EU architecture. - * - * Fixed function units: - * - * CS - Command streamer. Notional first unit, little software - * interaction. Holds the URB entries used for constant data, ie the - * CURBEs. - * - * VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of - * this unit is responsible for pulling vertices out of vertex buffers - * in vram and injecting them into the processing pipe as VUEs. If - * enabled, it first passes them to a VS thread which is a good place - * for the driver to implement any active vertex shader. - * - * GS - Geometry Shader. This corresponds to a new DX10 concept. If - * enabled, incoming strips etc are passed to GS threads in individual - * line/triangle/point units. The GS thread may perform arbitary - * computation and emit whatever primtives with whatever vertices it - * chooses. This makes GS an excellent place to implement GL's - * unfilled polygon modes, though of course it is capable of much - * more. Additionally, GS is used to translate away primitives not - * handled by latter units, including Quads and Lineloops. - * - * CS - Clipper. Mesa's clipping algorithms are imported to run on - * this unit. The fixed function part performs cliptesting against - * the 6 fixed clipplanes and makes descisions on whether or not the - * incoming primitive needs to be passed to a thread for clipping. - * User clip planes are handled via cooperation with the VS thread. - * - * SF - Strips Fans or Setup: Triangles are prepared for - * rasterization. Interpolation coefficients are calculated. - * Flatshading and two-side lighting usually performed here. - * - * WM - Windower. Interpolation of vertex attributes performed here. - * Fragment shader implemented here. SIMD aspects of EU taken full - * advantage of, as pixels are processed in blocks of 16. - * - * CC - Color Calculator. No EU threads associated with this unit. - * Handles blending and (presumably) depth and stencil testing. - */ - -#define BRW_MAX_CURBE (32*16) - -struct brw_context; -struct brw_winsys; - - -/* Raised when we receive new state across the pipe interface: - */ -#define BRW_NEW_VIEWPORT 0x1 -#define BRW_NEW_RASTERIZER 0x2 -#define BRW_NEW_FS 0x4 -#define BRW_NEW_BLEND 0x8 -#define BRW_NEW_CLIP 0x10 -#define BRW_NEW_SCISSOR 0x20 -#define BRW_NEW_STIPPLE 0x40 -#define BRW_NEW_FRAMEBUFFER 0x80 -#define BRW_NEW_ALPHA_TEST 0x100 -#define BRW_NEW_DEPTH_STENCIL 0x200 -#define BRW_NEW_SAMPLER 0x400 -#define BRW_NEW_TEXTURE 0x800 -#define BRW_NEW_CONSTANTS 0x1000 -#define BRW_NEW_VBO 0x2000 -#define BRW_NEW_VS 0x4000 - -/* Raised for other internal events: - */ -#define BRW_NEW_URB_FENCE 0x10000 -#define BRW_NEW_PSP 0x20000 -#define BRW_NEW_CURBE_OFFSETS 0x40000 -#define BRW_NEW_REDUCED_PRIMITIVE 0x80000 -#define BRW_NEW_PRIMITIVE 0x100000 -#define BRW_NEW_SCENE 0x200000 -#define BRW_NEW_SF_LINKAGE 0x400000 - -extern int BRW_DEBUG; - -#define DEBUG_TEXTURE 0x1 -#define DEBUG_STATE 0x2 -#define DEBUG_IOCTL 0x4 -#define DEBUG_PRIMS 0x8 -#define DEBUG_VERTS 0x10 -#define DEBUG_FALLBACKS 0x20 -#define DEBUG_VERBOSE 0x40 -#define DEBUG_DRI 0x80 -#define DEBUG_DMA 0x100 -#define DEBUG_SANITY 0x200 -#define DEBUG_SYNC 0x400 -#define DEBUG_SLEEP 0x800 -#define DEBUG_PIXEL 0x1000 -#define DEBUG_STATS 0x2000 -#define DEBUG_TILE 0x4000 -#define DEBUG_SINGLE_THREAD 0x8000 -#define DEBUG_WM 0x10000 -#define DEBUG_URB 0x20000 -#define DEBUG_VS 0x40000 -#define DEBUG_BATCH 0x80000 -#define DEBUG_BUFMGR 0x100000 -#define DEBUG_BLIT 0x200000 -#define DEBUG_REGION 0x400000 -#define DEBUG_MIPTREE 0x800000 - -#define DBG(...) do { \ - if (BRW_DEBUG & FILE_DEBUG_FLAG) \ - brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ -} while(0) - -#define PRINT(...) do { \ - brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ -} while(0) - -struct brw_state_flags { - unsigned cache; - unsigned brw; -}; - - -struct brw_vertex_program { - struct pipe_shader_state program; - struct tgsi_shader_info info; - int id; -}; - - -struct brw_fragment_program { - struct pipe_shader_state program; - struct tgsi_shader_info info; - - boolean UsesDepth; /* XXX add this to tgsi_shader_info? */ - int id; -}; - - -struct pipe_setup_linkage { - struct { - unsigned vp_output:5; - unsigned interp_mode:4; - unsigned bf_vp_output:5; - } fp_input[PIPE_MAX_SHADER_INPUTS]; - - unsigned fp_input_count:5; - unsigned max_vp_output:5; -}; - - - -struct brw_texture { - struct pipe_texture base; - - /* Derived from the above: - */ - unsigned pitch; - unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; - - unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; - - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats - * are going to be so diverse that there is no unified way to - * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - */ - unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ - - /* Includes image offset tables: - */ - unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; - - /* The data is held here: - */ - struct pipe_buffer *buffer; -}; - -/* Data about a particular attempt to compile a program. Note that - * there can be many of these, each in a different GL state - * corresponding to a different brw_wm_prog_key struct, with different - * compiled programs: - */ -/* Data about a particular attempt to compile a program. Note that - * there can be many of these, each in a different GL state - * corresponding to a different brw_wm_prog_key struct, with different - * compiled programs: - */ - -struct brw_wm_prog_data { - unsigned curb_read_length; - unsigned urb_read_length; - - unsigned first_curbe_grf; - unsigned total_grf; - unsigned total_scratch; - - /* Internally generated constants for the CURBE. These are loaded - * ahead of the data from the constant buffer. - */ - const float internal_const[8]; - unsigned nr_internal_consts; - unsigned max_const; - - boolean error; -}; - -struct brw_sf_prog_data { - unsigned urb_read_length; - unsigned total_grf; - - /* Each vertex may have upto 12 attributes, 4 components each, - * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11 - * rows. - * - * Actually we use 4 for each, so call it 12 rows. - */ - unsigned urb_entry_size; -}; - -struct brw_clip_prog_data { - unsigned curb_read_length; /* user planes? */ - unsigned clip_mode; - unsigned urb_read_length; - unsigned total_grf; -}; - -struct brw_gs_prog_data { - unsigned urb_read_length; - unsigned total_grf; -}; - -struct brw_vs_prog_data { - unsigned curb_read_length; - unsigned urb_read_length; - unsigned total_grf; - unsigned outputs_written; - - unsigned inputs_read; - - unsigned max_const; - - float imm_buf[PIPE_MAX_CONSTANT][4]; - unsigned num_imm; - unsigned num_consts; - - /* Used for calculating urb partitions: - */ - unsigned urb_entry_size; -}; - - -#define BRW_MAX_TEX_UNIT 8 -#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 - -/* Create a fixed sized struct for caching binding tables: - */ -struct brw_surface_binding_table { - unsigned surf_ss_offset[BRW_WM_MAX_SURF]; -}; - - -struct brw_cache; - -struct brw_mem_pool { - struct pipe_buffer *buffer; - - unsigned size; - unsigned offset; /* offset of first free byte */ - - struct brw_context *brw; -}; - -struct brw_cache_item { - unsigned hash; - unsigned key_size; /* for variable-sized keys */ - const void *key; - - unsigned offset; /* offset within pool's buffer */ - unsigned data_size; - - struct brw_cache_item *next; -}; - - - -struct brw_cache { - unsigned id; - - const char *name; - - struct brw_context *brw; - struct brw_mem_pool *pool; - - struct brw_cache_item **items; - unsigned size, n_items; - - unsigned key_size; /* for fixed-size keys */ - unsigned aux_size; - - unsigned last_addr; /* offset of active item */ -}; - - - - -/* Considered adding a member to this struct to document which flags - * an update might raise so that ordering of the state atoms can be - * checked or derived at runtime. Dropped the idea in favor of having - * a debug mode where the state is monitored for flags which are - * raised that have already been tested against. - */ -struct brw_tracked_state { - struct brw_state_flags dirty; - void (*update)( struct brw_context *brw ); -}; - - -/* Flags for brw->state.cache. - */ -#define CACHE_NEW_CC_VP (1< 32. Wouldn't life - * be easier if C allowed arrays of packed elements? - */ -#define ATTRIB_BIT_DWORDS ((PIPE_ATTRIB_MAX+31)/32) - - - - -struct brw_vertex_info { - unsigned varying; /* varying:1[PIPE_ATTRIB_MAX] */ - unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_ATTRIB_MAX] */ -}; - - - - - -struct brw_context -{ - struct pipe_context pipe; - struct brw_winsys *winsys; - - unsigned primitive; - unsigned reduced_primitive; - - boolean emit_state_always; - - struct { - struct brw_state_flags dirty; - } state; - - - struct { - const struct pipe_blend_state *Blend; - const struct pipe_depth_stencil_alpha_state *DepthStencil; - const struct pipe_poly_stipple *PolygonStipple; - const struct pipe_rasterizer_state *Raster; - const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS]; - const struct brw_vertex_program *VertexProgram; - const struct brw_fragment_program *FragmentProgram; - - struct pipe_clip_state Clip; - struct pipe_blend_color BlendColor; - struct pipe_scissor_state Scissor; - struct pipe_viewport_state Viewport; - struct pipe_framebuffer_state FrameBuffer; - - const struct pipe_constant_buffer *Constants[2]; - const struct brw_texture *Texture[PIPE_MAX_SAMPLERS]; - } attribs; - - struct brw_mem_pool pool[BRW_MAX_POOL]; - struct brw_cache cache[BRW_MAX_CACHE]; - struct brw_cached_batch_item *cached_batch_items; - - struct { - - /* Arrays with buffer objects to copy non-bufferobj arrays into - * for upload: - */ - const struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX]; - - struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX]; - -#define BRW_NR_UPLOAD_BUFS 17 -#define BRW_UPLOAD_INIT_SIZE (128*1024) - - /* Summary of size and varying of active arrays, so we can check - * for changes to this state: - */ - struct brw_vertex_info info; - } vb; - - - unsigned hardware_dirty; - unsigned dirty; - unsigned pci_id; - /* BRW_NEW_URB_ALLOCATIONS: - */ - struct { - unsigned vsize; /* vertex size plus header in urb registers */ - unsigned csize; /* constant buffer size in urb registers */ - unsigned sfsize; /* setup data size in urb registers */ - - boolean constrained; - - unsigned nr_vs_entries; - unsigned nr_gs_entries; - unsigned nr_clip_entries; - unsigned nr_sf_entries; - unsigned nr_cs_entries; - -/* unsigned vs_size; */ -/* unsigned gs_size; */ -/* unsigned clip_size; */ -/* unsigned sf_size; */ -/* unsigned cs_size; */ - - unsigned vs_start; - unsigned gs_start; - unsigned clip_start; - unsigned sf_start; - unsigned cs_start; - } urb; - - - /* BRW_NEW_CURBE_OFFSETS: - */ - struct { - unsigned wm_start; - unsigned wm_size; - unsigned clip_start; - unsigned clip_size; - unsigned vs_start; - unsigned vs_size; - unsigned total_size; - - unsigned gs_offset; - - float *last_buf; - unsigned last_bufsz; - } curbe; - - struct { - struct brw_vs_prog_data *prog_data; - - unsigned prog_gs_offset; - unsigned state_gs_offset; - } vs; - - struct { - struct brw_gs_prog_data *prog_data; - - boolean prog_active; - unsigned prog_gs_offset; - unsigned state_gs_offset; - } gs; - - struct { - struct brw_clip_prog_data *prog_data; - - unsigned prog_gs_offset; - unsigned vp_gs_offset; - unsigned state_gs_offset; - } clip; - - - struct { - struct brw_sf_prog_data *prog_data; - - struct pipe_setup_linkage linkage; - - unsigned prog_gs_offset; - unsigned vp_gs_offset; - unsigned state_gs_offset; - } sf; - - struct { - struct brw_wm_prog_data *prog_data; - -// struct brw_wm_compiler *compile_data; - - - /** - * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER - * cache - */ - struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; - - unsigned render_surf; - unsigned nr_surfaces; - - unsigned max_threads; - struct pipe_buffer *scratch_buffer; - unsigned scratch_buffer_size; - - unsigned sampler_count; - unsigned sampler_gs_offset; - - struct brw_surface_binding_table bind; - unsigned bind_ss_offset; - - unsigned prog_gs_offset; - unsigned state_gs_offset; - } wm; - - - struct { - unsigned vp_gs_offset; - unsigned state_gs_offset; - } cc; - - - /* Used to give every program string a unique id - */ - unsigned program_id; -}; - - -#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a) - - -/*====================================================================== - * brw_vtbl.c - */ -void brw_do_flush( struct brw_context *brw, - unsigned flags ); - - -/*====================================================================== - * brw_state.c - */ -void brw_validate_state(struct brw_context *brw); -void brw_init_state(struct brw_context *brw); -void brw_destroy_state(struct brw_context *brw); - - -/*====================================================================== - * brw_tex.c - */ -void brwUpdateTextureState( struct brw_context *brw ); - - -/* brw_urb.c - */ -void brw_upload_urb_fence(struct brw_context *brw); - -void brw_upload_constant_buffer_state(struct brw_context *brw); - -void brw_init_surface_functions(struct brw_context *brw); -void brw_init_state_functions(struct brw_context *brw); -void brw_init_flush_functions(struct brw_context *brw); -void brw_init_string_functions(struct brw_context *brw); - -/*====================================================================== - * Inline conversion functions. These are better-typed than the - * macros used previously: - */ -static inline struct brw_context * -brw_context( struct pipe_context *ctx ) -{ - return (struct brw_context *)ctx; -} - -#endif - +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRWCONTEXT_INC +#define BRWCONTEXT_INC + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "tgsi/util/tgsi_scan.h" + +#include "brw_structs.h" +#include "brw_winsys.h" + + +/* Glossary: + * + * URB - uniform resource buffer. A mid-sized buffer which is + * partitioned between the fixed function units and used for passing + * values (vertices, primitives, constants) between them. + * + * CURBE - constant URB entry. An urb region (entry) used to hold + * constant values which the fixed function units can be instructed to + * preload into the GRF when spawining a thread. + * + * VUE - vertex URB entry. An urb entry holding a vertex and usually + * a vertex header. The header contains control information and + * things like primitive type, Begin/end flags and clip codes. + * + * PUE - primitive URB entry. An urb entry produced by the setup (SF) + * unit holding rasterization and interpolation parameters. + * + * GRF - general register file. One of several register files + * addressable by programmed threads. The inputs (r0, payload, curbe, + * urb) of the thread are preloaded to this area before the thread is + * spawned. The registers are individually 8 dwords wide and suitable + * for general usage. Registers holding thread input values are not + * special and may be overwritten. + * + * MRF - message register file. Threads communicate (and terminate) + * by sending messages. Message parameters are placed in contigous + * MRF registers. All program output is via these messages. URB + * entries are populated by sending a message to the shared URB + * function containing the new data, together with a control word, + * often an unmodified copy of R0. + * + * R0 - GRF register 0. Typically holds control information used when + * sending messages to other threads. + * + * EU or GEN4 EU: The name of the programmable subsystem of the + * i965 hardware. Threads are executed by the EU, the registers + * described above are part of the EU architecture. + * + * Fixed function units: + * + * CS - Command streamer. Notional first unit, little software + * interaction. Holds the URB entries used for constant data, ie the + * CURBEs. + * + * VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of + * this unit is responsible for pulling vertices out of vertex buffers + * in vram and injecting them into the processing pipe as VUEs. If + * enabled, it first passes them to a VS thread which is a good place + * for the driver to implement any active vertex shader. + * + * GS - Geometry Shader. This corresponds to a new DX10 concept. If + * enabled, incoming strips etc are passed to GS threads in individual + * line/triangle/point units. The GS thread may perform arbitary + * computation and emit whatever primtives with whatever vertices it + * chooses. This makes GS an excellent place to implement GL's + * unfilled polygon modes, though of course it is capable of much + * more. Additionally, GS is used to translate away primitives not + * handled by latter units, including Quads and Lineloops. + * + * CS - Clipper. Mesa's clipping algorithms are imported to run on + * this unit. The fixed function part performs cliptesting against + * the 6 fixed clipplanes and makes descisions on whether or not the + * incoming primitive needs to be passed to a thread for clipping. + * User clip planes are handled via cooperation with the VS thread. + * + * SF - Strips Fans or Setup: Triangles are prepared for + * rasterization. Interpolation coefficients are calculated. + * Flatshading and two-side lighting usually performed here. + * + * WM - Windower. Interpolation of vertex attributes performed here. + * Fragment shader implemented here. SIMD aspects of EU taken full + * advantage of, as pixels are processed in blocks of 16. + * + * CC - Color Calculator. No EU threads associated with this unit. + * Handles blending and (presumably) depth and stencil testing. + */ + +#define BRW_MAX_CURBE (32*16) + +struct brw_context; +struct brw_winsys; + + +/* Raised when we receive new state across the pipe interface: + */ +#define BRW_NEW_VIEWPORT 0x1 +#define BRW_NEW_RASTERIZER 0x2 +#define BRW_NEW_FS 0x4 +#define BRW_NEW_BLEND 0x8 +#define BRW_NEW_CLIP 0x10 +#define BRW_NEW_SCISSOR 0x20 +#define BRW_NEW_STIPPLE 0x40 +#define BRW_NEW_FRAMEBUFFER 0x80 +#define BRW_NEW_ALPHA_TEST 0x100 +#define BRW_NEW_DEPTH_STENCIL 0x200 +#define BRW_NEW_SAMPLER 0x400 +#define BRW_NEW_TEXTURE 0x800 +#define BRW_NEW_CONSTANTS 0x1000 +#define BRW_NEW_VBO 0x2000 +#define BRW_NEW_VS 0x4000 + +/* Raised for other internal events: + */ +#define BRW_NEW_URB_FENCE 0x10000 +#define BRW_NEW_PSP 0x20000 +#define BRW_NEW_CURBE_OFFSETS 0x40000 +#define BRW_NEW_REDUCED_PRIMITIVE 0x80000 +#define BRW_NEW_PRIMITIVE 0x100000 +#define BRW_NEW_SCENE 0x200000 +#define BRW_NEW_SF_LINKAGE 0x400000 + +extern int BRW_DEBUG; + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_PRIMS 0x8 +#define DEBUG_VERTS 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_DRI 0x80 +#define DEBUG_DMA 0x100 +#define DEBUG_SANITY 0x200 +#define DEBUG_SYNC 0x400 +#define DEBUG_SLEEP 0x800 +#define DEBUG_PIXEL 0x1000 +#define DEBUG_STATS 0x2000 +#define DEBUG_TILE 0x4000 +#define DEBUG_SINGLE_THREAD 0x8000 +#define DEBUG_WM 0x10000 +#define DEBUG_URB 0x20000 +#define DEBUG_VS 0x40000 +#define DEBUG_BATCH 0x80000 +#define DEBUG_BUFMGR 0x100000 +#define DEBUG_BLIT 0x200000 +#define DEBUG_REGION 0x400000 +#define DEBUG_MIPTREE 0x800000 + +#define DBG(...) do { \ + if (BRW_DEBUG & FILE_DEBUG_FLAG) \ + brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ +} while(0) + +#define PRINT(...) do { \ + brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ +} while(0) + +struct brw_state_flags { + unsigned cache; + unsigned brw; +}; + + +struct brw_vertex_program { + struct pipe_shader_state program; + struct tgsi_shader_info info; + int id; +}; + + +struct brw_fragment_program { + struct pipe_shader_state program; + struct tgsi_shader_info info; + + boolean UsesDepth; /* XXX add this to tgsi_shader_info? */ + int id; +}; + + +struct pipe_setup_linkage { + struct { + unsigned vp_output:5; + unsigned interp_mode:4; + unsigned bf_vp_output:5; + } fp_input[PIPE_MAX_SHADER_INPUTS]; + + unsigned fp_input_count:5; + unsigned max_vp_output:5; +}; + + + +struct brw_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ + +struct brw_wm_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + + unsigned first_curbe_grf; + unsigned total_grf; + unsigned total_scratch; + + /* Internally generated constants for the CURBE. These are loaded + * ahead of the data from the constant buffer. + */ + const float internal_const[8]; + unsigned nr_internal_consts; + unsigned max_const; + + boolean error; +}; + +struct brw_sf_prog_data { + unsigned urb_read_length; + unsigned total_grf; + + /* Each vertex may have upto 12 attributes, 4 components each, + * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11 + * rows. + * + * Actually we use 4 for each, so call it 12 rows. + */ + unsigned urb_entry_size; +}; + +struct brw_clip_prog_data { + unsigned curb_read_length; /* user planes? */ + unsigned clip_mode; + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_gs_prog_data { + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_vs_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + unsigned total_grf; + unsigned outputs_written; + + unsigned inputs_read; + + unsigned max_const; + + float imm_buf[PIPE_MAX_CONSTANT][4]; + unsigned num_imm; + unsigned num_consts; + + /* Used for calculating urb partitions: + */ + unsigned urb_entry_size; +}; + + +#define BRW_MAX_TEX_UNIT 8 +#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 + +/* Create a fixed sized struct for caching binding tables: + */ +struct brw_surface_binding_table { + unsigned surf_ss_offset[BRW_WM_MAX_SURF]; +}; + + +struct brw_cache; + +struct brw_mem_pool { + struct pipe_buffer *buffer; + + unsigned size; + unsigned offset; /* offset of first free byte */ + + struct brw_context *brw; +}; + +struct brw_cache_item { + unsigned hash; + unsigned key_size; /* for variable-sized keys */ + const void *key; + + unsigned offset; /* offset within pool's buffer */ + unsigned data_size; + + struct brw_cache_item *next; +}; + + + +struct brw_cache { + unsigned id; + + const char *name; + + struct brw_context *brw; + struct brw_mem_pool *pool; + + struct brw_cache_item **items; + unsigned size, n_items; + + unsigned key_size; /* for fixed-size keys */ + unsigned aux_size; + + unsigned last_addr; /* offset of active item */ +}; + + + + +/* Considered adding a member to this struct to document which flags + * an update might raise so that ordering of the state atoms can be + * checked or derived at runtime. Dropped the idea in favor of having + * a debug mode where the state is monitored for flags which are + * raised that have already been tested against. + */ +struct brw_tracked_state { + struct brw_state_flags dirty; + void (*update)( struct brw_context *brw ); +}; + + +/* Flags for brw->state.cache. + */ +#define CACHE_NEW_CC_VP (1< 32. Wouldn't life + * be easier if C allowed arrays of packed elements? + */ +#define ATTRIB_BIT_DWORDS ((PIPE_ATTRIB_MAX+31)/32) + + + + +struct brw_vertex_info { + unsigned varying; /* varying:1[PIPE_ATTRIB_MAX] */ + unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_ATTRIB_MAX] */ +}; + + + + + +struct brw_context +{ + struct pipe_context pipe; + struct brw_winsys *winsys; + + unsigned primitive; + unsigned reduced_primitive; + + boolean emit_state_always; + + struct { + struct brw_state_flags dirty; + } state; + + + struct { + const struct pipe_blend_state *Blend; + const struct pipe_depth_stencil_alpha_state *DepthStencil; + const struct pipe_poly_stipple *PolygonStipple; + const struct pipe_rasterizer_state *Raster; + const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS]; + const struct brw_vertex_program *VertexProgram; + const struct brw_fragment_program *FragmentProgram; + + struct pipe_clip_state Clip; + struct pipe_blend_color BlendColor; + struct pipe_scissor_state Scissor; + struct pipe_viewport_state Viewport; + struct pipe_framebuffer_state FrameBuffer; + + const struct pipe_constant_buffer *Constants[2]; + const struct brw_texture *Texture[PIPE_MAX_SAMPLERS]; + } attribs; + + unsigned num_samplers; + unsigned num_textures; + + struct brw_mem_pool pool[BRW_MAX_POOL]; + struct brw_cache cache[BRW_MAX_CACHE]; + struct brw_cached_batch_item *cached_batch_items; + + struct { + + /* Arrays with buffer objects to copy non-bufferobj arrays into + * for upload: + */ + const struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX]; + + struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX]; + +#define BRW_NR_UPLOAD_BUFS 17 +#define BRW_UPLOAD_INIT_SIZE (128*1024) + + /* Summary of size and varying of active arrays, so we can check + * for changes to this state: + */ + struct brw_vertex_info info; + } vb; + + + unsigned hardware_dirty; + unsigned dirty; + unsigned pci_id; + /* BRW_NEW_URB_ALLOCATIONS: + */ + struct { + unsigned vsize; /* vertex size plus header in urb registers */ + unsigned csize; /* constant buffer size in urb registers */ + unsigned sfsize; /* setup data size in urb registers */ + + boolean constrained; + + unsigned nr_vs_entries; + unsigned nr_gs_entries; + unsigned nr_clip_entries; + unsigned nr_sf_entries; + unsigned nr_cs_entries; + +/* unsigned vs_size; */ +/* unsigned gs_size; */ +/* unsigned clip_size; */ +/* unsigned sf_size; */ +/* unsigned cs_size; */ + + unsigned vs_start; + unsigned gs_start; + unsigned clip_start; + unsigned sf_start; + unsigned cs_start; + } urb; + + + /* BRW_NEW_CURBE_OFFSETS: + */ + struct { + unsigned wm_start; + unsigned wm_size; + unsigned clip_start; + unsigned clip_size; + unsigned vs_start; + unsigned vs_size; + unsigned total_size; + + unsigned gs_offset; + + float *last_buf; + unsigned last_bufsz; + } curbe; + + struct { + struct brw_vs_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } vs; + + struct { + struct brw_gs_prog_data *prog_data; + + boolean prog_active; + unsigned prog_gs_offset; + unsigned state_gs_offset; + } gs; + + struct { + struct brw_clip_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } clip; + + + struct { + struct brw_sf_prog_data *prog_data; + + struct pipe_setup_linkage linkage; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } sf; + + struct { + struct brw_wm_prog_data *prog_data; + +// struct brw_wm_compiler *compile_data; + + + /** + * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER + * cache + */ + struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; + + unsigned render_surf; + unsigned nr_surfaces; + + unsigned max_threads; + struct pipe_buffer *scratch_buffer; + unsigned scratch_buffer_size; + + unsigned sampler_count; + unsigned sampler_gs_offset; + + struct brw_surface_binding_table bind; + unsigned bind_ss_offset; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } wm; + + + struct { + unsigned vp_gs_offset; + unsigned state_gs_offset; + } cc; + + + /* Used to give every program string a unique id + */ + unsigned program_id; +}; + + +#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a) + + +/*====================================================================== + * brw_vtbl.c + */ +void brw_do_flush( struct brw_context *brw, + unsigned flags ); + + +/*====================================================================== + * brw_state.c + */ +void brw_validate_state(struct brw_context *brw); +void brw_init_state(struct brw_context *brw); +void brw_destroy_state(struct brw_context *brw); + + +/*====================================================================== + * brw_tex.c + */ +void brwUpdateTextureState( struct brw_context *brw ); + + +/* brw_urb.c + */ +void brw_upload_urb_fence(struct brw_context *brw); + +void brw_upload_constant_buffer_state(struct brw_context *brw); + +void brw_init_surface_functions(struct brw_context *brw); +void brw_init_state_functions(struct brw_context *brw); +void brw_init_flush_functions(struct brw_context *brw); +void brw_init_string_functions(struct brw_context *brw); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static inline struct brw_context * +brw_context( struct pipe_context *ctx ) +{ + return (struct brw_context *)ctx; +} + +#endif + diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index 6744a8aa4f..f5efe9fc06 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -1,434 +1,462 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Zack Rusin - * Keith Whitwell - */ - - -#include "pipe/p_winsys.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_dump.h" - -#include "brw_context.h" -#include "brw_defines.h" -#include "brw_state.h" -#include "brw_draw.h" - - -#define DUP( TYPE, VAL ) \ -do { \ - struct TYPE *x = malloc(sizeof(*x)); \ - memcpy(x, VAL, sizeof(*x) ); \ - return x; \ -} while (0) - -/************************************************************************ - * Blend - */ -static void * -brw_create_blend_state(struct pipe_context *pipe, - const struct pipe_blend_state *blend) -{ - DUP( pipe_blend_state, blend ); -} - -static void brw_bind_blend_state(struct pipe_context *pipe, - void *blend) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Blend = (struct pipe_blend_state*)blend; - brw->state.dirty.brw |= BRW_NEW_BLEND; -} - - -static void brw_delete_blend_state(struct pipe_context *pipe, void *blend) -{ - free(blend); -} - -static void brw_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.BlendColor = *blend_color; - - brw->state.dirty.brw |= BRW_NEW_BLEND; -} - -/************************************************************************ - * Sampler - */ - -static void * -brw_create_sampler_state(struct pipe_context *pipe, - const struct pipe_sampler_state *sampler) -{ - DUP( pipe_sampler_state, sampler ); -} - -static void brw_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Samplers[unit] = sampler; - brw->state.dirty.brw |= BRW_NEW_SAMPLER; -} - -static void brw_delete_sampler_state(struct pipe_context *pipe, - void *sampler) -{ - free(sampler); -} - - -/************************************************************************ - * Depth stencil - */ - -static void * -brw_create_depth_stencil_state(struct pipe_context *pipe, - const struct pipe_depth_stencil_alpha_state *depth_stencil) -{ - DUP( pipe_depth_stencil_alpha_state, depth_stencil ); -} - -static void brw_bind_depth_stencil_state(struct pipe_context *pipe, - void *depth_stencil) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; - - brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL; -} - -static void brw_delete_depth_stencil_state(struct pipe_context *pipe, - void *depth_stencil) -{ - free(depth_stencil); -} - -/************************************************************************ - * Scissor - */ -static void brw_set_scissor_state( struct pipe_context *pipe, - const struct pipe_scissor_state *scissor ) -{ - struct brw_context *brw = brw_context(pipe); - - memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) ); - brw->state.dirty.brw |= BRW_NEW_SCISSOR; -} - - -/************************************************************************ - * Stipple - */ - -static void brw_set_polygon_stipple( struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple ) -{ -} - - -/************************************************************************ - * Fragment shader - */ - -static void * brw_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *shader) -{ - struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program); - - /* XXX: Do I have to duplicate the tokens as well?? - */ - brw_fp->program = *shader; - brw_fp->id = brw_context(pipe)->program_id++; - - tgsi_scan_shader(shader->tokens, &brw_fp->info); - -#if 0 - brw_shader_info(shader->tokens, - &brw_fp->info2); -#endif - - tgsi_dump(shader->tokens, 0); - - - return (void *)brw_fp; -} - -static void brw_bind_fs_state(struct pipe_context *pipe, void *shader) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader; - brw->state.dirty.brw |= BRW_NEW_FS; -} - -static void brw_delete_fs_state(struct pipe_context *pipe, void *shader) -{ - FREE(shader); -} - - -/************************************************************************ - * Vertex shader and other TNL state - */ - -static void *brw_create_vs_state(struct pipe_context *pipe, - const struct pipe_shader_state *shader) -{ - struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program); - - /* XXX: Do I have to duplicate the tokens as well?? - */ - brw_vp->program = *shader; - brw_vp->id = brw_context(pipe)->program_id++; - - tgsi_scan_shader(shader->tokens, &brw_vp->info); - -#if 0 - brw_shader_info(shader->tokens, - &brw_vp->info2); -#endif - tgsi_dump(shader->tokens, 0); - - return (void *)brw_vp; -} - -static void brw_bind_vs_state(struct pipe_context *pipe, void *vs) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.VertexProgram = (struct brw_vertex_program *)vs; - brw->state.dirty.brw |= BRW_NEW_VS; - - debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n"); -} - -static void brw_delete_vs_state(struct pipe_context *pipe, void *shader) -{ - FREE(shader); -} - - -static void brw_set_clip_state( struct pipe_context *pipe, - const struct pipe_clip_state *clip ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Clip = *clip; -} - - -static void brw_set_viewport_state( struct pipe_context *pipe, - const struct pipe_viewport_state *viewport ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Viewport = *viewport; /* struct copy */ - brw->state.dirty.brw |= BRW_NEW_VIEWPORT; - - /* pass the viewport info to the draw module */ - //draw_set_viewport_state(brw->draw, viewport); -} - - -static void brw_set_vertex_buffer( struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_buffer *buffer ) -{ - struct brw_context *brw = brw_context(pipe); - brw->vb.vbo_array[index] = buffer; -} - -static void brw_set_vertex_element(struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_element *element) -{ - /* flush ? */ - struct brw_context *brw = brw_context(pipe); - - assert(index < PIPE_ATTRIB_MAX); - struct brw_vertex_element_state el; - memset(&el, 0, sizeof(el)); - - el.ve0.src_offset = element->src_offset; - el.ve0.src_format = brw_translate_surface_format(element->src_format); - el.ve0.valid = 1; - el.ve0.vertex_buffer_index = element->vertex_buffer_index; - - el.ve1.dst_offset = index * 4; - - el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; - - switch (element->nr_components) { - case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; - case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; - case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; - break; - } - - brw->vb.inputs[index] = el; -} - - - -/************************************************************************ - * Constant buffers - */ - -static void brw_set_constant_buffer(struct pipe_context *pipe, - uint shader, uint index, - const struct pipe_constant_buffer *buf) -{ - struct brw_context *brw = brw_context(pipe); - - assert(buf == 0 || index == 0); - - brw->attribs.Constants[shader] = buf; - brw->state.dirty.brw |= BRW_NEW_CONSTANTS; -} - - -/************************************************************************ - * Texture surfaces - */ - - -static void brw_set_sampler_texture(struct pipe_context *pipe, - unsigned unit, - struct pipe_texture *texture) -{ - struct brw_context *brw = brw_context(pipe); - - pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[unit], - texture); - - brw->state.dirty.brw |= BRW_NEW_TEXTURE; -} - - -/************************************************************************ - * Render targets, etc - */ - -static void brw_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.FrameBuffer = *fb; /* struct copy */ - - brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER; -} - - - -/************************************************************************ - * Rasterizer state - */ - -static void * -brw_create_rasterizer_state(struct pipe_context *pipe, - const struct pipe_rasterizer_state *rasterizer) -{ - DUP(pipe_rasterizer_state, rasterizer); -} - -static void brw_bind_rasterizer_state( struct pipe_context *pipe, - void *setup ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Raster = (struct pipe_rasterizer_state *)setup; - - /* Also pass-through to draw module: - */ - //draw_set_rasterizer_state(brw->draw, setup); - - brw->state.dirty.brw |= BRW_NEW_RASTERIZER; -} - -static void brw_delete_rasterizer_state(struct pipe_context *pipe, - void *setup) -{ - free(setup); -} - - - -void -brw_init_state_functions( struct brw_context *brw ) -{ - brw->pipe.create_blend_state = brw_create_blend_state; - brw->pipe.bind_blend_state = brw_bind_blend_state; - brw->pipe.delete_blend_state = brw_delete_blend_state; - - brw->pipe.create_sampler_state = brw_create_sampler_state; - brw->pipe.bind_sampler_state = brw_bind_sampler_state; - brw->pipe.delete_sampler_state = brw_delete_sampler_state; - - brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; - brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; - brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; - - brw->pipe.create_rasterizer_state = brw_create_rasterizer_state; - brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state; - brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state; - brw->pipe.create_fs_state = brw_create_fs_state; - brw->pipe.bind_fs_state = brw_bind_fs_state; - brw->pipe.delete_fs_state = brw_delete_fs_state; - brw->pipe.create_vs_state = brw_create_vs_state; - brw->pipe.bind_vs_state = brw_bind_vs_state; - brw->pipe.delete_vs_state = brw_delete_vs_state; - - brw->pipe.set_blend_color = brw_set_blend_color; - brw->pipe.set_clip_state = brw_set_clip_state; - brw->pipe.set_constant_buffer = brw_set_constant_buffer; - brw->pipe.set_framebuffer_state = brw_set_framebuffer_state; - -// brw->pipe.set_feedback_state = brw_set_feedback_state; -// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer; - - brw->pipe.set_polygon_stipple = brw_set_polygon_stipple; - brw->pipe.set_scissor_state = brw_set_scissor_state; - brw->pipe.set_sampler_texture = brw_set_sampler_texture; - brw->pipe.set_viewport_state = brw_set_viewport_state; - brw->pipe.set_vertex_buffer = brw_set_vertex_buffer; - brw->pipe.set_vertex_element = brw_set_vertex_element; -} +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Zack Rusin + * Keith Whitwell + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_dump.h" + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_state.h" +#include "brw_draw.h" + + +#define DUP( TYPE, VAL ) \ +do { \ + struct TYPE *x = malloc(sizeof(*x)); \ + memcpy(x, VAL, sizeof(*x) ); \ + return x; \ +} while (0) + +/************************************************************************ + * Blend + */ +static void * +brw_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + DUP( pipe_blend_state, blend ); +} + +static void brw_bind_blend_state(struct pipe_context *pipe, + void *blend) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Blend = (struct pipe_blend_state*)blend; + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + + +static void brw_delete_blend_state(struct pipe_context *pipe, void *blend) +{ + free(blend); +} + +static void brw_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.BlendColor = *blend_color; + + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + +/************************************************************************ + * Sampler + */ + +static void * +brw_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + DUP( pipe_sampler_state, sampler ); +} + +static void brw_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct brw_context *brw = brw_context(pipe); + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == brw->num_samplers && + !memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *))) + return; + + memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *)); + memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) * + sizeof(void *)); + + brw->num_samplers = num; + + brw->state.dirty.brw |= BRW_NEW_SAMPLER; +} + +static void brw_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + free(sampler); +} + + +/************************************************************************ + * Depth stencil + */ + +static void * +brw_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + DUP( pipe_depth_stencil_alpha_state, depth_stencil ); +} + +static void brw_bind_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; + + brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL; +} + +static void brw_delete_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + free(depth_stencil); +} + +/************************************************************************ + * Scissor + */ +static void brw_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct brw_context *brw = brw_context(pipe); + + memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) ); + brw->state.dirty.brw |= BRW_NEW_SCISSOR; +} + + +/************************************************************************ + * Stipple + */ + +static void brw_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ +} + + +/************************************************************************ + * Fragment shader + */ + +static void * brw_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program); + + /* XXX: Do I have to duplicate the tokens as well?? + */ + brw_fp->program = *shader; + brw_fp->id = brw_context(pipe)->program_id++; + + tgsi_scan_shader(shader->tokens, &brw_fp->info); + +#if 0 + brw_shader_info(shader->tokens, + &brw_fp->info2); +#endif + + tgsi_dump(shader->tokens, 0); + + + return (void *)brw_fp; +} + +static void brw_bind_fs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader; + brw->state.dirty.brw |= BRW_NEW_FS; +} + +static void brw_delete_fs_state(struct pipe_context *pipe, void *shader) +{ + FREE(shader); +} + + +/************************************************************************ + * Vertex shader and other TNL state + */ + +static void *brw_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program); + + /* XXX: Do I have to duplicate the tokens as well?? + */ + brw_vp->program = *shader; + brw_vp->id = brw_context(pipe)->program_id++; + + tgsi_scan_shader(shader->tokens, &brw_vp->info); + +#if 0 + brw_shader_info(shader->tokens, + &brw_vp->info2); +#endif + tgsi_dump(shader->tokens, 0); + + return (void *)brw_vp; +} + +static void brw_bind_vs_state(struct pipe_context *pipe, void *vs) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.VertexProgram = (struct brw_vertex_program *)vs; + brw->state.dirty.brw |= BRW_NEW_VS; + + debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n"); +} + +static void brw_delete_vs_state(struct pipe_context *pipe, void *shader) +{ + FREE(shader); +} + + +static void brw_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Clip = *clip; +} + + +static void brw_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Viewport = *viewport; /* struct copy */ + brw->state.dirty.brw |= BRW_NEW_VIEWPORT; + + /* pass the viewport info to the draw module */ + //draw_set_viewport_state(brw->draw, viewport); +} + + +static void brw_set_vertex_buffer( struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_buffer *buffer ) +{ + struct brw_context *brw = brw_context(pipe); + brw->vb.vbo_array[index] = buffer; +} + +static void brw_set_vertex_element(struct pipe_context *pipe, + unsigned index, + const struct pipe_vertex_element *element) +{ + /* flush ? */ + struct brw_context *brw = brw_context(pipe); + + assert(index < PIPE_ATTRIB_MAX); + struct brw_vertex_element_state el; + memset(&el, 0, sizeof(el)); + + el.ve0.src_offset = element->src_offset; + el.ve0.src_format = brw_translate_surface_format(element->src_format); + el.ve0.valid = 1; + el.ve0.vertex_buffer_index = element->vertex_buffer_index; + + el.ve1.dst_offset = index * 4; + + el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; + + switch (element->nr_components) { + case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; + case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; + case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; + break; + } + + brw->vb.inputs[index] = el; +} + + + +/************************************************************************ + * Constant buffers + */ + +static void brw_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct brw_context *brw = brw_context(pipe); + + assert(buf == 0 || index == 0); + + brw->attribs.Constants[shader] = buf; + brw->state.dirty.brw |= BRW_NEW_CONSTANTS; +} + + +/************************************************************************ + * Texture surfaces + */ + + +static void brw_set_sampler_textures(struct pipe_context *pipe, + unsigned num, + struct pipe_texture **texture) +{ + struct brw_context *brw = brw_context(pipe); + uint i; + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == brw->num_textures && + !memcmp(brw->attribs.Texture, texture, num * + sizeof(struct pipe_texture *))) + return; + + for (i = 0; i < num; i++) + pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], + texture[i]); + + for (i = num; i < brw->num_textures; i++) + pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], + NULL); + + brw->num_textures = num; + + brw->state.dirty.brw |= BRW_NEW_TEXTURE; +} + + +/************************************************************************ + * Render targets, etc + */ + +static void brw_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FrameBuffer = *fb; /* struct copy */ + + brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER; +} + + + +/************************************************************************ + * Rasterizer state + */ + +static void * +brw_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *rasterizer) +{ + DUP(pipe_rasterizer_state, rasterizer); +} + +static void brw_bind_rasterizer_state( struct pipe_context *pipe, + void *setup ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Raster = (struct pipe_rasterizer_state *)setup; + + /* Also pass-through to draw module: + */ + //draw_set_rasterizer_state(brw->draw, setup); + + brw->state.dirty.brw |= BRW_NEW_RASTERIZER; +} + +static void brw_delete_rasterizer_state(struct pipe_context *pipe, + void *setup) +{ + free(setup); +} + + + +void +brw_init_state_functions( struct brw_context *brw ) +{ + brw->pipe.create_blend_state = brw_create_blend_state; + brw->pipe.bind_blend_state = brw_bind_blend_state; + brw->pipe.delete_blend_state = brw_delete_blend_state; + + brw->pipe.create_sampler_state = brw_create_sampler_state; + brw->pipe.bind_sampler_states = brw_bind_sampler_states; + brw->pipe.delete_sampler_state = brw_delete_sampler_state; + + brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; + brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; + brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; + + brw->pipe.create_rasterizer_state = brw_create_rasterizer_state; + brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state; + brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state; + brw->pipe.create_fs_state = brw_create_fs_state; + brw->pipe.bind_fs_state = brw_bind_fs_state; + brw->pipe.delete_fs_state = brw_delete_fs_state; + brw->pipe.create_vs_state = brw_create_vs_state; + brw->pipe.bind_vs_state = brw_bind_vs_state; + brw->pipe.delete_vs_state = brw_delete_vs_state; + + brw->pipe.set_blend_color = brw_set_blend_color; + brw->pipe.set_clip_state = brw_set_clip_state; + brw->pipe.set_constant_buffer = brw_set_constant_buffer; + brw->pipe.set_framebuffer_state = brw_set_framebuffer_state; + +// brw->pipe.set_feedback_state = brw_set_feedback_state; +// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer; + + brw->pipe.set_polygon_stipple = brw_set_polygon_stipple; + brw->pipe.set_scissor_state = brw_set_scissor_state; + brw->pipe.set_sampler_textures = brw_set_sampler_textures; + brw->pipe.set_viewport_state = brw_set_viewport_state; + brw->pipe.set_vertex_buffer = brw_set_vertex_buffer; + brw->pipe.set_vertex_element = brw_set_vertex_element; +} diff --git a/src/gallium/drivers/i965simple/brw_wm_sampler_state.c b/src/gallium/drivers/i965simple/brw_wm_sampler_state.c index de42ffc5b1..ff5ba7e7c7 100644 --- a/src/gallium/drivers/i965simple/brw_wm_sampler_state.c +++ b/src/gallium/drivers/i965simple/brw_wm_sampler_state.c @@ -235,7 +235,8 @@ static void upload_wm_samplers(struct brw_context *brw) unsigned sampler_count = 0; /* BRW_NEW_SAMPLER */ - for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) { + for (unit = 0; unit < brw->num_textures && unit < brw->num_samplers; + unit++) { /* determine unit enable/disable by looking for a bound texture */ if (brw->attribs.Texture[unit]) { const struct pipe_sampler_state *sampler = brw->attribs.Samplers[unit]; diff --git a/src/gallium/drivers/i965simple/brw_wm_surface_state.c b/src/gallium/drivers/i965simple/brw_wm_surface_state.c index d16d919bce..853c743ccf 100644 --- a/src/gallium/drivers/i965simple/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965simple/brw_wm_surface_state.c @@ -237,7 +237,7 @@ static void upload_wm_surfaces(struct brw_context *brw ) /* BRW_NEW_TEXTURE */ - for (i = 0; i < BRW_MAX_TEX_UNIT; i++) { + for (i = 0; i < brw->num_textures && i < brw->num_samplers; i++) { const struct brw_texture *texUnit = brw->attribs.Texture[i]; if (texUnit && diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index fa16ed94e8..316ae552b8 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -1,243 +1,243 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Author: - * Keith Whitwell - */ - -#include "draw/draw_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/p_util.h" -#include "sp_clear.h" -#include "sp_context.h" -#include "sp_flush.h" -#include "sp_prim_setup.h" -#include "sp_prim_vbuf.h" -#include "sp_state.h" -#include "sp_surface.h" -#include "sp_tile_cache.h" -#include "sp_texture.h" -#include "sp_winsys.h" -#include "sp_query.h" - - - -/** - * Map any drawing surfaces which aren't already mapped - */ -void -softpipe_map_surfaces(struct softpipe_context *sp) -{ - unsigned i; - - for (i = 0; i < sp->framebuffer.num_cbufs; i++) { - sp_tile_cache_map_surfaces(sp->cbuf_cache[i]); - } - - sp_tile_cache_map_surfaces(sp->zsbuf_cache); -} - - -/** - * Unmap any mapped drawing surfaces - */ -void -softpipe_unmap_surfaces(struct softpipe_context *sp) -{ - uint i; - - for (i = 0; i < sp->framebuffer.num_cbufs; i++) - sp_flush_tile_cache(sp, sp->cbuf_cache[i]); - sp_flush_tile_cache(sp, sp->zsbuf_cache); - - for (i = 0; i < sp->framebuffer.num_cbufs; i++) { - sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]); - } - sp_tile_cache_unmap_surfaces(sp->zsbuf_cache); -} - - -static void softpipe_destroy( struct pipe_context *pipe ) -{ - struct softpipe_context *softpipe = softpipe_context( pipe ); - struct pipe_winsys *ws = pipe->winsys; - uint i; - - draw_destroy( softpipe->draw ); - - softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); - softpipe->quad.earlyz->destroy( softpipe->quad.earlyz ); - softpipe->quad.shade->destroy( softpipe->quad.shade ); - softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test ); - softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); - softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test ); - softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); - softpipe->quad.coverage->destroy( softpipe->quad.coverage ); - softpipe->quad.bufloop->destroy( softpipe->quad.bufloop ); - softpipe->quad.blend->destroy( softpipe->quad.blend ); - softpipe->quad.colormask->destroy( softpipe->quad.colormask ); - softpipe->quad.output->destroy( softpipe->quad.output ); - - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - sp_destroy_tile_cache(softpipe->cbuf_cache[i]); - sp_destroy_tile_cache(softpipe->zsbuf_cache); - - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - sp_destroy_tile_cache(softpipe->tex_cache[i]); - - for (i = 0; i < Elements(softpipe->constants); i++) { - if (softpipe->constants[i].buffer) { - pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL); - } - } - - FREE( softpipe ); -} - - -struct pipe_context * -softpipe_create( struct pipe_screen *screen, - struct pipe_winsys *pipe_winsys, - struct softpipe_winsys *softpipe_winsys ) -{ - struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); - uint i; - -#if defined(__i386__) || defined(__386__) - softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; -#else - softpipe->use_sse = FALSE; -#endif - - softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL; - - softpipe->pipe.winsys = pipe_winsys; - softpipe->pipe.screen = screen; - softpipe->pipe.destroy = softpipe_destroy; - - /* state setters */ - softpipe->pipe.create_blend_state = softpipe_create_blend_state; - softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; - softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; - - softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; - softpipe->pipe.bind_sampler_state = softpipe_bind_sampler_state; - softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; - - softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state; - softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state; - softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state; - - softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state; - softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state; - softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state; - - softpipe->pipe.create_fs_state = softpipe_create_fs_state; - softpipe->pipe.bind_fs_state = softpipe_bind_fs_state; - softpipe->pipe.delete_fs_state = softpipe_delete_fs_state; - - softpipe->pipe.create_vs_state = softpipe_create_vs_state; - softpipe->pipe.bind_vs_state = softpipe_bind_vs_state; - softpipe->pipe.delete_vs_state = softpipe_delete_vs_state; - - softpipe->pipe.set_blend_color = softpipe_set_blend_color; - softpipe->pipe.set_clip_state = softpipe_set_clip_state; - softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; - softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; - softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; - softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; - softpipe->pipe.set_sampler_texture = softpipe_set_sampler_texture; - softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; - - softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer; - softpipe->pipe.set_vertex_element = softpipe_set_vertex_element; - - softpipe->pipe.draw_arrays = softpipe_draw_arrays; - softpipe->pipe.draw_elements = softpipe_draw_elements; - - softpipe->pipe.clear = softpipe_clear; - softpipe->pipe.flush = softpipe_flush; - - softpipe_init_query_funcs( softpipe ); - softpipe_init_texture_funcs( softpipe ); - - /* - * Alloc caches for accessing drawing surfaces and textures. - * Must be before quad stage setup! - */ - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - softpipe->cbuf_cache[i] = sp_create_tile_cache(); - softpipe->zsbuf_cache = sp_create_tile_cache(); - - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - softpipe->tex_cache[i] = sp_create_tile_cache(); - - - /* setup quad rendering stages */ - softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); - softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe); - softpipe->quad.shade = sp_quad_shade_stage(softpipe); - softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe); - softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); - softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); - softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); - softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); - softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe); - softpipe->quad.blend = sp_quad_blend_stage(softpipe); - softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); - softpipe->quad.output = sp_quad_output_stage(softpipe); - - softpipe->winsys = softpipe_winsys; - - /* - * Create drawing context and plug our rendering stage into it. - */ - softpipe->draw = draw_create(); - assert(softpipe->draw); - softpipe->setup = sp_draw_render_stage(softpipe); - - if (GETENV( "SP_VBUF" ) != NULL) { - sp_init_vbuf(softpipe); - } - else { - draw_set_rasterize_stage(softpipe->draw, softpipe->setup); - } - - /* plug in AA line/point stages */ - draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); - draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); - -#if USE_DRAW_STAGE_PSTIPPLE - /* Do polygon stipple w/ texture map + frag prog? */ - draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); -#endif - - sp_init_surface_functions(softpipe); - - return &softpipe->pipe; -} +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "sp_clear.h" +#include "sp_context.h" +#include "sp_flush.h" +#include "sp_prim_setup.h" +#include "sp_prim_vbuf.h" +#include "sp_state.h" +#include "sp_surface.h" +#include "sp_tile_cache.h" +#include "sp_texture.h" +#include "sp_winsys.h" +#include "sp_query.h" + + + +/** + * Map any drawing surfaces which aren't already mapped + */ +void +softpipe_map_surfaces(struct softpipe_context *sp) +{ + unsigned i; + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) { + sp_tile_cache_map_surfaces(sp->cbuf_cache[i]); + } + + sp_tile_cache_map_surfaces(sp->zsbuf_cache); +} + + +/** + * Unmap any mapped drawing surfaces + */ +void +softpipe_unmap_surfaces(struct softpipe_context *sp) +{ + uint i; + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) + sp_flush_tile_cache(sp, sp->cbuf_cache[i]); + sp_flush_tile_cache(sp, sp->zsbuf_cache); + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) { + sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]); + } + sp_tile_cache_unmap_surfaces(sp->zsbuf_cache); +} + + +static void softpipe_destroy( struct pipe_context *pipe ) +{ + struct softpipe_context *softpipe = softpipe_context( pipe ); + struct pipe_winsys *ws = pipe->winsys; + uint i; + + draw_destroy( softpipe->draw ); + + softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); + softpipe->quad.earlyz->destroy( softpipe->quad.earlyz ); + softpipe->quad.shade->destroy( softpipe->quad.shade ); + softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test ); + softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); + softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test ); + softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); + softpipe->quad.coverage->destroy( softpipe->quad.coverage ); + softpipe->quad.bufloop->destroy( softpipe->quad.bufloop ); + softpipe->quad.blend->destroy( softpipe->quad.blend ); + softpipe->quad.colormask->destroy( softpipe->quad.colormask ); + softpipe->quad.output->destroy( softpipe->quad.output ); + + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + sp_destroy_tile_cache(softpipe->cbuf_cache[i]); + sp_destroy_tile_cache(softpipe->zsbuf_cache); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + sp_destroy_tile_cache(softpipe->tex_cache[i]); + + for (i = 0; i < Elements(softpipe->constants); i++) { + if (softpipe->constants[i].buffer) { + pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL); + } + } + + FREE( softpipe ); +} + + +struct pipe_context * +softpipe_create( struct pipe_screen *screen, + struct pipe_winsys *pipe_winsys, + struct softpipe_winsys *softpipe_winsys ) +{ + struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); + uint i; + +#if defined(__i386__) || defined(__386__) + softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; +#else + softpipe->use_sse = FALSE; +#endif + + softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL; + + softpipe->pipe.winsys = pipe_winsys; + softpipe->pipe.screen = screen; + softpipe->pipe.destroy = softpipe_destroy; + + /* state setters */ + softpipe->pipe.create_blend_state = softpipe_create_blend_state; + softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; + softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; + + softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; + softpipe->pipe.bind_sampler_states = softpipe_bind_sampler_states; + softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; + + softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state; + softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state; + softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state; + + softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state; + softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state; + softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state; + + softpipe->pipe.create_fs_state = softpipe_create_fs_state; + softpipe->pipe.bind_fs_state = softpipe_bind_fs_state; + softpipe->pipe.delete_fs_state = softpipe_delete_fs_state; + + softpipe->pipe.create_vs_state = softpipe_create_vs_state; + softpipe->pipe.bind_vs_state = softpipe_bind_vs_state; + softpipe->pipe.delete_vs_state = softpipe_delete_vs_state; + + softpipe->pipe.set_blend_color = softpipe_set_blend_color; + softpipe->pipe.set_clip_state = softpipe_set_clip_state; + softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; + softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; + softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; + softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; + softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures; + softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; + + softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer; + softpipe->pipe.set_vertex_element = softpipe_set_vertex_element; + + softpipe->pipe.draw_arrays = softpipe_draw_arrays; + softpipe->pipe.draw_elements = softpipe_draw_elements; + + softpipe->pipe.clear = softpipe_clear; + softpipe->pipe.flush = softpipe_flush; + + softpipe_init_query_funcs( softpipe ); + softpipe_init_texture_funcs( softpipe ); + + /* + * Alloc caches for accessing drawing surfaces and textures. + * Must be before quad stage setup! + */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + softpipe->cbuf_cache[i] = sp_create_tile_cache(); + softpipe->zsbuf_cache = sp_create_tile_cache(); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + softpipe->tex_cache[i] = sp_create_tile_cache(); + + + /* setup quad rendering stages */ + softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); + softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe); + softpipe->quad.shade = sp_quad_shade_stage(softpipe); + softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe); + softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); + softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); + softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); + softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); + softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe); + softpipe->quad.blend = sp_quad_blend_stage(softpipe); + softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); + softpipe->quad.output = sp_quad_output_stage(softpipe); + + softpipe->winsys = softpipe_winsys; + + /* + * Create drawing context and plug our rendering stage into it. + */ + softpipe->draw = draw_create(); + assert(softpipe->draw); + softpipe->setup = sp_draw_render_stage(softpipe); + + if (GETENV( "SP_VBUF" ) != NULL) { + sp_init_vbuf(softpipe); + } + else { + draw_set_rasterize_stage(softpipe->draw, softpipe->setup); + } + + /* plug in AA line/point stages */ + draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); + draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); + +#if USE_DRAW_STAGE_PSTIPPLE + /* Do polygon stipple w/ texture map + frag prog? */ + draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); +#endif + + sp_init_surface_functions(softpipe); + + return &softpipe->pipe; +} diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index feeafc7084..19e6cfaf02 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -81,6 +81,9 @@ struct softpipe_context { struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; unsigned dirty; + unsigned num_samplers; + unsigned num_textures; + /* Counter for occlusion queries. Note this supports overlapping * queries. */ diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 1fbb2e38c4..9198198db3 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -1,208 +1,209 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Vertices are just an array of floats, with all the attributes - * packed. We currently assume a layout like: - * - * attr[0][0..3] - window position - * attr[1..n][0..3] - remaining attributes. - * - * Attributes are assumed to be 4 floats wide but are packed so that - * all the enabled attributes run contiguously. - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" - -#include "sp_context.h" -#include "sp_state.h" -#include "sp_headers.h" -#include "sp_quad.h" -#include "sp_texture.h" -#include "sp_tex_sample.h" - - -struct quad_shade_stage -{ - struct quad_stage stage; - struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS]; - struct tgsi_exec_machine machine; - struct tgsi_exec_vector *inputs, *outputs; - int colorOutSlot, depthOutSlot; -}; - - -/** cast wrapper */ -static INLINE struct quad_shade_stage * -quad_shade_stage(struct quad_stage *qs) -{ - return (struct quad_shade_stage *) qs; -} - - - -/** - * Execute fragment shader for the four fragments in the quad. - */ -static void -shade_quad( - struct quad_stage *qs, - struct quad_header *quad ) -{ - struct quad_shade_stage *qss = quad_shade_stage( qs ); - struct softpipe_context *softpipe = qs->softpipe; - struct tgsi_exec_machine *machine = &qss->machine; - - /* Consts do not require 16 byte alignment. */ - machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; - - machine->InterpCoefs = quad->coef; - - /* run shader */ - quad->mask &= softpipe->fs->run( softpipe->fs, - &qss->machine, - quad ); - - /* store result color */ - if (qss->colorOutSlot >= 0) { - /* XXX need to handle multiple color outputs someday */ - assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] - == TGSI_SEMANTIC_COLOR); - memcpy( - quad->outputs.color, - &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0], - sizeof( quad->outputs.color ) ); - } - - /* - * XXX the following code for updating quad->outputs.depth - * isn't really needed if we did early z testing. - */ - - /* store result Z */ - if (qss->depthOutSlot >= 0) { - /* output[slot] is new Z */ - uint i; - for (i = 0; i < 4; i++) { - quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i]; - } - } - else { - /* copy input Z (which was interpolated by the executor) to output Z */ - uint i; - for (i = 0; i < 4; i++) { - quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i]; - /* XXX not sure the above line is always correct. The following - * might be better: - quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i]; - */ - } - } - - /* shader may cull fragments */ - if( quad->mask ) { - qs->next->run( qs->next, quad ); - } -} - -/** - * Per-primitive (or per-begin?) setup - */ -static void shade_begin(struct quad_stage *qs) -{ - struct quad_shade_stage *qss = quad_shade_stage(qs); - struct softpipe_context *softpipe = qs->softpipe; - unsigned i; - - /* set TGSI sampler state that varies */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - qss->samplers[i].state = softpipe->sampler[i]; - qss->samplers[i].texture = softpipe->texture[i]; - } - - /* find output slots for depth, color */ - qss->colorOutSlot = -1; - qss->depthOutSlot = -1; - for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) { - switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) { - case TGSI_SEMANTIC_POSITION: - qss->depthOutSlot = i; - break; - case TGSI_SEMANTIC_COLOR: - qss->colorOutSlot = i; - break; - } - } - - softpipe->fs->prepare( softpipe->fs, - &qss->machine, - qss->samplers ); - - qs->next->begin(qs->next); -} - - -static void shade_destroy(struct quad_stage *qs) -{ - struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; - - tgsi_exec_machine_free_data(&qss->machine); - FREE( qss->inputs ); - FREE( qss->outputs ); - FREE( qs ); -} - - -struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) -{ - struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); - uint i; - - /* allocate storage for program inputs/outputs, aligned to 16 bytes */ - qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16); - qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16); - qss->machine.Inputs = align16(qss->inputs); - qss->machine.Outputs = align16(qss->outputs); - - qss->stage.softpipe = softpipe; - qss->stage.begin = shade_begin; - qss->stage.run = shade_quad; - qss->stage.destroy = shade_destroy; - - /* set TGSI sampler state that's constant */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - assert(softpipe->tex_cache[i]); - qss->samplers[i].get_samples = sp_get_samples; - qss->samplers[i].pipe = &softpipe->pipe; - qss->samplers[i].cache = softpipe->tex_cache[i]; - } - - tgsi_exec_machine_init( &qss->machine ); - - return &qss->stage; -} +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Vertices are just an array of floats, with all the attributes + * packed. We currently assume a layout like: + * + * attr[0][0..3] - window position + * attr[1..n][0..3] - remaining attributes. + * + * Attributes are assumed to be 4 floats wide but are packed so that + * all the enabled attributes run contiguously. + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_headers.h" +#include "sp_quad.h" +#include "sp_texture.h" +#include "sp_tex_sample.h" + + +struct quad_shade_stage +{ + struct quad_stage stage; + struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS]; + struct tgsi_exec_machine machine; + struct tgsi_exec_vector *inputs, *outputs; + int colorOutSlot, depthOutSlot; +}; + + +/** cast wrapper */ +static INLINE struct quad_shade_stage * +quad_shade_stage(struct quad_stage *qs) +{ + return (struct quad_shade_stage *) qs; +} + + + +/** + * Execute fragment shader for the four fragments in the quad. + */ +static void +shade_quad( + struct quad_stage *qs, + struct quad_header *quad ) +{ + struct quad_shade_stage *qss = quad_shade_stage( qs ); + struct softpipe_context *softpipe = qs->softpipe; + struct tgsi_exec_machine *machine = &qss->machine; + + /* Consts do not require 16 byte alignment. */ + machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; + + machine->InterpCoefs = quad->coef; + + /* run shader */ + quad->mask &= softpipe->fs->run( softpipe->fs, + &qss->machine, + quad ); + + /* store result color */ + if (qss->colorOutSlot >= 0) { + /* XXX need to handle multiple color outputs someday */ + assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] + == TGSI_SEMANTIC_COLOR); + memcpy( + quad->outputs.color, + &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0], + sizeof( quad->outputs.color ) ); + } + + /* + * XXX the following code for updating quad->outputs.depth + * isn't really needed if we did early z testing. + */ + + /* store result Z */ + if (qss->depthOutSlot >= 0) { + /* output[slot] is new Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i]; + } + } + else { + /* copy input Z (which was interpolated by the executor) to output Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i]; + /* XXX not sure the above line is always correct. The following + * might be better: + quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i]; + */ + } + } + + /* shader may cull fragments */ + if( quad->mask ) { + qs->next->run( qs->next, quad ); + } +} + +/** + * Per-primitive (or per-begin?) setup + */ +static void shade_begin(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = quad_shade_stage(qs); + struct softpipe_context *softpipe = qs->softpipe; + unsigned i; + unsigned num = MAX2(softpipe->num_textures, softpipe->num_samplers); + + /* set TGSI sampler state that varies */ + for (i = 0; i < num; i++) { + qss->samplers[i].state = softpipe->sampler[i]; + qss->samplers[i].texture = softpipe->texture[i]; + } + + /* find output slots for depth, color */ + qss->colorOutSlot = -1; + qss->depthOutSlot = -1; + for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) { + switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + qss->depthOutSlot = i; + break; + case TGSI_SEMANTIC_COLOR: + qss->colorOutSlot = i; + break; + } + } + + softpipe->fs->prepare( softpipe->fs, + &qss->machine, + qss->samplers ); + + qs->next->begin(qs->next); +} + + +static void shade_destroy(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; + + tgsi_exec_machine_free_data(&qss->machine); + FREE( qss->inputs ); + FREE( qss->outputs ); + FREE( qs ); +} + + +struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) +{ + struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); + uint i; + + /* allocate storage for program inputs/outputs, aligned to 16 bytes */ + qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16); + qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16); + qss->machine.Inputs = align16(qss->inputs); + qss->machine.Outputs = align16(qss->outputs); + + qss->stage.softpipe = softpipe; + qss->stage.begin = shade_begin; + qss->stage.run = shade_quad; + qss->stage.destroy = shade_destroy; + + /* set TGSI sampler state that's constant */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + assert(softpipe->tex_cache[i]); + qss->samplers[i].get_samples = sp_get_samples; + qss->samplers[i].pipe = &softpipe->pipe; + qss->samplers[i].cache = softpipe->tex_cache[i]; + } + + tgsi_exec_machine_init( &qss->machine ); + + return &qss->stage; +} diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 3943d4ed2b..45d159143f 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -1,195 +1,195 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#ifndef SP_STATE_H -#define SP_STATE_H - -#include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" - - -#define SP_NEW_VIEWPORT 0x1 -#define SP_NEW_RASTERIZER 0x2 -#define SP_NEW_FS 0x4 -#define SP_NEW_BLEND 0x8 -#define SP_NEW_CLIP 0x10 -#define SP_NEW_SCISSOR 0x20 -#define SP_NEW_STIPPLE 0x40 -#define SP_NEW_FRAMEBUFFER 0x80 -#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100 -#define SP_NEW_CONSTANTS 0x200 -#define SP_NEW_SAMPLER 0x400 -#define SP_NEW_TEXTURE 0x800 -#define SP_NEW_VERTEX 0x1000 -#define SP_NEW_VS 0x2000 -#define SP_NEW_QUERY 0x4000 - - -struct tgsi_sampler; -struct tgsi_exec_machine; - - -/** Subclass of pipe_shader_state (though it doesn't really need to be). - * - * This is starting to look an awful lot like a quad pipeline stage... - */ -struct sp_fragment_shader { - struct pipe_shader_state shader; - - struct tgsi_shader_info info; - - void (*prepare)( const struct sp_fragment_shader *shader, - struct tgsi_exec_machine *machine, - struct tgsi_sampler *samplers); - - /* Run the shader - this interface will get cleaned up in the - * future: - */ - unsigned (*run)( const struct sp_fragment_shader *shader, - struct tgsi_exec_machine *machine, - struct quad_header *quad ); - - - void (*delete)( struct sp_fragment_shader * ); -}; - -struct vertex_info; - -/** Subclass of pipe_shader_state */ -struct sp_vertex_shader { - struct pipe_shader_state shader; - struct draw_vertex_shader *draw_data; -}; - - - -void * -softpipe_create_blend_state(struct pipe_context *, - const struct pipe_blend_state *); -void softpipe_bind_blend_state(struct pipe_context *, - void *); -void softpipe_delete_blend_state(struct pipe_context *, - void *); - -void * -softpipe_create_sampler_state(struct pipe_context *, - const struct pipe_sampler_state *); -void softpipe_bind_sampler_state(struct pipe_context *, unsigned, void *); -void softpipe_delete_sampler_state(struct pipe_context *, void *); - -void * -softpipe_create_depth_stencil_state(struct pipe_context *, - const struct pipe_depth_stencil_alpha_state *); -void softpipe_bind_depth_stencil_state(struct pipe_context *, void *); -void softpipe_delete_depth_stencil_state(struct pipe_context *, void *); - -void * -softpipe_create_rasterizer_state(struct pipe_context *, - const struct pipe_rasterizer_state *); -void softpipe_bind_rasterizer_state(struct pipe_context *, void *); -void softpipe_delete_rasterizer_state(struct pipe_context *, void *); - -void softpipe_set_framebuffer_state( struct pipe_context *, - const struct pipe_framebuffer_state * ); - -void softpipe_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ); - -void softpipe_set_clip_state( struct pipe_context *, - const struct pipe_clip_state * ); - -void softpipe_set_constant_buffer(struct pipe_context *, - uint shader, uint index, - const struct pipe_constant_buffer *buf); - -void *softpipe_create_fs_state(struct pipe_context *, - const struct pipe_shader_state *); -void softpipe_bind_fs_state(struct pipe_context *, void *); -void softpipe_delete_fs_state(struct pipe_context *, void *); -void *softpipe_create_vs_state(struct pipe_context *, - const struct pipe_shader_state *); -void softpipe_bind_vs_state(struct pipe_context *, void *); -void softpipe_delete_vs_state(struct pipe_context *, void *); - -void softpipe_set_polygon_stipple( struct pipe_context *, - const struct pipe_poly_stipple * ); - -void softpipe_set_scissor_state( struct pipe_context *, - const struct pipe_scissor_state * ); - -void softpipe_set_sampler_texture( struct pipe_context *, - unsigned unit, - struct pipe_texture * ); - -void softpipe_set_viewport_state( struct pipe_context *, - const struct pipe_viewport_state * ); - -void softpipe_set_vertex_element(struct pipe_context *, - unsigned index, - const struct pipe_vertex_element *); - -void softpipe_set_vertex_buffer(struct pipe_context *, - unsigned index, - const struct pipe_vertex_buffer *); - - -void softpipe_update_derived( struct softpipe_context *softpipe ); - - -boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count); - -boolean softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned mode, unsigned start, unsigned count); - - -void -softpipe_map_surfaces(struct softpipe_context *sp); - -void -softpipe_unmap_surfaces(struct softpipe_context *sp); - -void -softpipe_map_texture_surfaces(struct softpipe_context *sp); - -void -softpipe_unmap_texture_surfaces(struct softpipe_context *sp); - - -struct vertex_info * -softpipe_get_vertex_info(struct softpipe_context *softpipe); - -struct vertex_info * -softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe); - - -#endif +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_STATE_H +#define SP_STATE_H + +#include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" + + +#define SP_NEW_VIEWPORT 0x1 +#define SP_NEW_RASTERIZER 0x2 +#define SP_NEW_FS 0x4 +#define SP_NEW_BLEND 0x8 +#define SP_NEW_CLIP 0x10 +#define SP_NEW_SCISSOR 0x20 +#define SP_NEW_STIPPLE 0x40 +#define SP_NEW_FRAMEBUFFER 0x80 +#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100 +#define SP_NEW_CONSTANTS 0x200 +#define SP_NEW_SAMPLER 0x400 +#define SP_NEW_TEXTURE 0x800 +#define SP_NEW_VERTEX 0x1000 +#define SP_NEW_VS 0x2000 +#define SP_NEW_QUERY 0x4000 + + +struct tgsi_sampler; +struct tgsi_exec_machine; + + +/** Subclass of pipe_shader_state (though it doesn't really need to be). + * + * This is starting to look an awful lot like a quad pipeline stage... + */ +struct sp_fragment_shader { + struct pipe_shader_state shader; + + struct tgsi_shader_info info; + + void (*prepare)( const struct sp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct tgsi_sampler *samplers); + + /* Run the shader - this interface will get cleaned up in the + * future: + */ + unsigned (*run)( const struct sp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct quad_header *quad ); + + + void (*delete)( struct sp_fragment_shader * ); +}; + +struct vertex_info; + +/** Subclass of pipe_shader_state */ +struct sp_vertex_shader { + struct pipe_shader_state shader; + struct draw_vertex_shader *draw_data; +}; + + + +void * +softpipe_create_blend_state(struct pipe_context *, + const struct pipe_blend_state *); +void softpipe_bind_blend_state(struct pipe_context *, + void *); +void softpipe_delete_blend_state(struct pipe_context *, + void *); + +void * +softpipe_create_sampler_state(struct pipe_context *, + const struct pipe_sampler_state *); +void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **); +void softpipe_delete_sampler_state(struct pipe_context *, void *); + +void * +softpipe_create_depth_stencil_state(struct pipe_context *, + const struct pipe_depth_stencil_alpha_state *); +void softpipe_bind_depth_stencil_state(struct pipe_context *, void *); +void softpipe_delete_depth_stencil_state(struct pipe_context *, void *); + +void * +softpipe_create_rasterizer_state(struct pipe_context *, + const struct pipe_rasterizer_state *); +void softpipe_bind_rasterizer_state(struct pipe_context *, void *); +void softpipe_delete_rasterizer_state(struct pipe_context *, void *); + +void softpipe_set_framebuffer_state( struct pipe_context *, + const struct pipe_framebuffer_state * ); + +void softpipe_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ); + +void softpipe_set_clip_state( struct pipe_context *, + const struct pipe_clip_state * ); + +void softpipe_set_constant_buffer(struct pipe_context *, + uint shader, uint index, + const struct pipe_constant_buffer *buf); + +void *softpipe_create_fs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_fs_state(struct pipe_context *, void *); +void softpipe_delete_fs_state(struct pipe_context *, void *); +void *softpipe_create_vs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_vs_state(struct pipe_context *, void *); +void softpipe_delete_vs_state(struct pipe_context *, void *); + +void softpipe_set_polygon_stipple( struct pipe_context *, + const struct pipe_poly_stipple * ); + +void softpipe_set_scissor_state( struct pipe_context *, + const struct pipe_scissor_state * ); + +void softpipe_set_sampler_textures( struct pipe_context *, + unsigned num, + struct pipe_texture ** ); + +void softpipe_set_viewport_state( struct pipe_context *, + const struct pipe_viewport_state * ); + +void softpipe_set_vertex_element(struct pipe_context *, + unsigned index, + const struct pipe_vertex_element *); + +void softpipe_set_vertex_buffer(struct pipe_context *, + unsigned index, + const struct pipe_vertex_buffer *); + + +void softpipe_update_derived( struct softpipe_context *softpipe ); + + +boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count); + +boolean softpipe_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count); + + +void +softpipe_map_surfaces(struct softpipe_context *sp); + +void +softpipe_unmap_surfaces(struct softpipe_context *sp); + +void +softpipe_map_texture_surfaces(struct softpipe_context *sp); + +void +softpipe_unmap_texture_surfaces(struct softpipe_context *sp); + + +struct vertex_info * +softpipe_get_vertex_info(struct softpipe_context *softpipe); + +struct vertex_info * +softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe); + + +#endif diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 1d6dd17d1d..7cf85b9207 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -50,45 +50,67 @@ softpipe_create_sampler_state(struct pipe_context *pipe, return mem_dup(sampler, sizeof(*sampler)); } + void -softpipe_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) +softpipe_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) { struct softpipe_context *softpipe = softpipe_context(pipe); + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == softpipe->num_samplers && + !memcmp(softpipe->sampler, sampler, num * sizeof(void *))) + return; + draw_flush(softpipe->draw); - assert(unit < PIPE_MAX_SAMPLERS); - softpipe->sampler[unit] = (struct pipe_sampler_state *)sampler; + memcpy(softpipe->sampler, sampler, num * sizeof(void *)); + memset(&softpipe->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) * + sizeof(void *)); + + softpipe->num_samplers = num; softpipe->dirty |= SP_NEW_SAMPLER; } void -softpipe_delete_sampler_state(struct pipe_context *pipe, - void *sampler) +softpipe_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) { - FREE( sampler ); -} + struct softpipe_context *softpipe = softpipe_context(pipe); + uint i; + assert(num <= PIPE_MAX_SAMPLERS); -void -softpipe_set_sampler_texture(struct pipe_context *pipe, - unsigned unit, - struct pipe_texture *texture) -{ - struct softpipe_context *softpipe = softpipe_context(pipe); + /* Check for no-op */ + if (num == softpipe->num_textures && + !memcmp(softpipe->texture, texture, num * sizeof(struct pipe_texture *))) + return; draw_flush(softpipe->draw); - assert(unit < PIPE_MAX_SAMPLERS); - pipe_texture_reference(&softpipe->texture[unit], texture); + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + struct pipe_texture *tex = i < num ? texture[i] : NULL; + + pipe_texture_reference(&softpipe->texture[i], tex); + sp_tile_cache_set_texture(pipe, softpipe->tex_cache[i], tex); + } - sp_tile_cache_set_texture(pipe, softpipe->tex_cache[unit], texture); + softpipe->num_textures = num; softpipe->dirty |= SP_NEW_TEXTURE; } +void +softpipe_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + FREE( sampler ); +} + + diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index c605ed925b..bbf2d80308 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -1,202 +1,202 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - /* - * Authors: - * Keith Whitwell - * Michel Dänzer - */ - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/p_util.h" -#include "pipe/p_winsys.h" - -#include "sp_context.h" -#include "sp_state.h" -#include "sp_texture.h" -#include "sp_tile_cache.h" - - -/* Simple, maximally packed layout. - */ - -static unsigned minify( unsigned d ) -{ - return MAX2(1, d>>1); -} - - -static void -softpipe_texture_layout(struct softpipe_texture * spt) -{ - struct pipe_texture *pt = &spt->base; - unsigned level; - unsigned width = pt->width[0]; - unsigned height = pt->height[0]; - unsigned depth = pt->depth[0]; - - spt->buffer_size = 0; - - for (level = 0; level <= pt->last_level; level++) { - pt->width[level] = width; - pt->height[level] = height; - pt->depth[level] = depth; - - spt->level_offset[level] = spt->buffer_size; - - spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * - ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * - width * pt->cpp; - - width = minify(width); - height = minify(height); - depth = minify(depth); - } -} - - -static struct pipe_texture * -softpipe_texture_create_screen(struct pipe_screen *screen, - const struct pipe_texture *templat) -{ - struct pipe_winsys *ws = screen->winsys; - struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); - if (!spt) - return NULL; - - spt->base = *templat; - spt->base.refcount = 1; - spt->base.screen = screen; - - softpipe_texture_layout(spt); - - spt->buffer = ws->buffer_create(ws, 32, - PIPE_BUFFER_USAGE_PIXEL, - spt->buffer_size); - if (!spt->buffer) { - FREE(spt); - return NULL; - } - - assert(spt->base.refcount == 1); - - return &spt->base; -} - - -static void -softpipe_texture_release_screen(struct pipe_screen *screen, - struct pipe_texture **pt) -{ - if (!*pt) - return; - - /* - DBG("%s %p refcount will be %d\n", - __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); - */ - if (--(*pt)->refcount <= 0) { - struct softpipe_texture *spt = softpipe_texture(*pt); - - /* - DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); - */ - - pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); - - FREE(spt); - } - *pt = NULL; -} - - -static struct pipe_surface * -softpipe_get_tex_surface_screen(struct pipe_screen *screen, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct pipe_winsys *ws = screen->winsys; - struct softpipe_texture *spt = softpipe_texture(pt); - struct pipe_surface *ps; - - assert(level <= pt->last_level); - - ps = ws->surface_alloc(ws); - if (ps) { - assert(ps->refcount); - assert(ps->winsys); - pipe_buffer_reference(ws, &ps->buffer, spt->buffer); - ps->format = pt->format; - ps->cpp = pt->cpp; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - ps->pitch = ps->width; - ps->offset = spt->level_offset[level]; - - if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { - ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * - (pt->compressed ? ps->height/4 : ps->height) * - ps->width * ps->cpp; - } - else { - assert(face == 0); - assert(zslice == 0); - } - } - return ps; -} - - -static void -softpipe_texture_update(struct pipe_context *pipe, - struct pipe_texture *texture) -{ - struct softpipe_context *softpipe = softpipe_context(pipe); - uint unit; - for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { - if (softpipe->texture[unit] == texture) { - sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); - } - } -} - - -void -softpipe_init_texture_funcs( struct softpipe_context *softpipe ) -{ - softpipe->pipe.texture_update = softpipe_texture_update; -} - - -void -softpipe_init_screen_texture_funcs(struct pipe_screen *screen) -{ - screen->texture_create = softpipe_texture_create_screen; - screen->texture_release = softpipe_texture_release_screen; - screen->get_tex_surface = softpipe_get_tex_surface_screen; -} +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell + * Michel Dänzer + */ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_texture.h" +#include "sp_tile_cache.h" + + +/* Simple, maximally packed layout. + */ + +static unsigned minify( unsigned d ) +{ + return MAX2(1, d>>1); +} + + +static void +softpipe_texture_layout(struct softpipe_texture * spt) +{ + struct pipe_texture *pt = &spt->base; + unsigned level; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; + + spt->buffer_size = 0; + + for (level = 0; level <= pt->last_level; level++) { + pt->width[level] = width; + pt->height[level] = height; + pt->depth[level] = depth; + + spt->level_offset[level] = spt->buffer_size; + + spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * + ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * + width * pt->cpp; + + width = minify(width); + height = minify(height); + depth = minify(depth); + } +} + + +static struct pipe_texture * +softpipe_texture_create_screen(struct pipe_screen *screen, + const struct pipe_texture *templat) +{ + struct pipe_winsys *ws = screen->winsys; + struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); + if (!spt) + return NULL; + + spt->base = *templat; + spt->base.refcount = 1; + spt->base.screen = screen; + + softpipe_texture_layout(spt); + + spt->buffer = ws->buffer_create(ws, 32, + PIPE_BUFFER_USAGE_PIXEL, + spt->buffer_size); + if (!spt->buffer) { + FREE(spt); + return NULL; + } + + assert(spt->base.refcount == 1); + + return &spt->base; +} + + +static void +softpipe_texture_release_screen(struct pipe_screen *screen, + struct pipe_texture **pt) +{ + if (!*pt) + return; + + /* + DBG("%s %p refcount will be %d\n", + __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); + */ + if (--(*pt)->refcount <= 0) { + struct softpipe_texture *spt = softpipe_texture(*pt); + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); + */ + + pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); + + FREE(spt); + } + *pt = NULL; +} + + +static struct pipe_surface * +softpipe_get_tex_surface_screen(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = screen->winsys; + struct softpipe_texture *spt = softpipe_texture(pt); + struct pipe_surface *ps; + + assert(level <= pt->last_level); + + ps = ws->surface_alloc(ws); + if (ps) { + assert(ps->refcount); + assert(ps->winsys); + pipe_buffer_reference(ws, &ps->buffer, spt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = ps->width; + ps->offset = spt->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { + ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * + (pt->compressed ? ps->height/4 : ps->height) * + ps->width * ps->cpp; + } + else { + assert(face == 0); + assert(zslice == 0); + } + } + return ps; +} + + +static void +softpipe_texture_update(struct pipe_context *pipe, + struct pipe_texture *texture) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint unit; + for (unit = 0; unit < softpipe->num_textures; unit++) { + if (softpipe->texture[unit] == texture) { + sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); + } + } +} + + +void +softpipe_init_texture_funcs( struct softpipe_context *softpipe ) +{ + softpipe->pipe.texture_update = softpipe_texture_update; +} + + +void +softpipe_init_screen_texture_funcs(struct pipe_screen *screen) +{ + screen->texture_create = softpipe_texture_create_screen; + screen->texture_release = softpipe_texture_release_screen; + screen->get_tex_surface = softpipe_get_tex_surface_screen; +} diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 1501b52f3e..b64948f0f3 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -100,7 +100,7 @@ struct pipe_context { void * (*create_sampler_state)(struct pipe_context *, const struct pipe_sampler_state *); - void (*bind_sampler_state)(struct pipe_context *, unsigned unit, void *); + void (*bind_sampler_states)(struct pipe_context *, unsigned num, void **); void (*delete_sampler_state)(struct pipe_context *, void *); void * (*create_rasterizer_state)(struct pipe_context *, @@ -148,9 +148,9 @@ struct pipe_context { /* Currently a sampler is constrained to sample from a single texture: */ - void (*set_sampler_texture)( struct pipe_context *, - unsigned sampler, - struct pipe_texture * ); + void (*set_sampler_textures)( struct pipe_context *, + unsigned num, + struct pipe_texture ** ); void (*set_viewport_state)( struct pipe_context *, const struct pipe_viewport_state * ); -- cgit v1.2.3 From 8143adafddabb6ac3a21c18927ae41425f26bfff Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 6 Mar 2008 19:57:41 +0100 Subject: gallium: Surround externs with extern "C". --- src/gallium/auxiliary/util/p_tile.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.h b/src/gallium/auxiliary/util/p_tile.h index 318b6d11a6..fdc80a13b3 100644 --- a/src/gallium/auxiliary/util/p_tile.h +++ b/src/gallium/auxiliary/util/p_tile.h @@ -52,44 +52,50 @@ pipe_clip_tile(uint x, uint y, uint *w, uint *h, const struct pipe_surface *ps) return FALSE; } +#ifdef __cplusplus +extern "C" { +#endif -extern void +void pipe_get_tile_raw(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, void *p, int dst_stride); -extern void +void pipe_put_tile_raw(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, const void *p, int src_stride); -extern void +void pipe_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, float *p); -extern void +void pipe_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, const float *p); -extern void +void pipe_get_tile_z(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, uint *z); -extern void +void pipe_put_tile_z(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, const uint *z); +#ifdef __cplusplus +} +#endif #endif -- cgit v1.2.3 From fc96aec9b7aceb4a0e7471e797abe8a00fc40cf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 8 Mar 2008 16:29:12 +0000 Subject: gallium: Document debug_printf usage. --- src/gallium/auxiliary/util/Makefile | 3 ++- src/gallium/include/pipe/p_debug.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index 906a46d6b4..2a3a9380b3 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -7,7 +7,8 @@ C_SOURCES = \ p_debug.c \ p_tile.c \ p_util.c \ - u_mm.c + u_mm.c \ + u_snprintf.c include ../../Makefile.template diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 2a11627b36..a14a1fc5f6 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -58,8 +58,22 @@ extern "C" { #endif +/** + * Print debug messages. + * + * A debug message will be printed regardless of the DEBUG/NDEBUG macros. + * + * The actual channel used to output debug message is platform specific. To + * avoid misformating or truncation, follow these rules of thumb: + * - output whole lines + * - avoid outputing large strings (512 bytes is the current maximum length + * that is guaranteed to be printed in all platforms) + */ void debug_printf(const char *format, ...); +/** + * @sa debug_printf + */ void debug_vprintf(const char *format, va_list ap); void debug_assert_fail(const char *expr, const char *file, unsigned line); -- cgit v1.2.3 From 99691f38c278f1d4aeb0617b149109644e3571fb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 9 Mar 2008 15:07:09 +0100 Subject: gallium: add some commonly implemented bits of hw state --- src/gallium/include/pipe/p_state.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 49a003b923..e338a27383 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -108,6 +108,7 @@ struct pipe_rasterizer_state unsigned line_stipple_enable:1; unsigned line_stipple_factor:8; /**< [1..256] actually */ unsigned line_stipple_pattern:16; + unsigned line_last_pixel:1; unsigned bypass_clipping:1; unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ @@ -154,7 +155,7 @@ struct pipe_clip_state struct pipe_constant_buffer { struct pipe_buffer *buffer; - unsigned size; /** in bytes */ + unsigned size; /** in bytes (XXX: redundant!) */ }; @@ -248,6 +249,7 @@ struct pipe_sampler_state unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ unsigned compare_func:3; /**< PIPE_FUNC_x */ unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ + unsigned prefilter:4; /**< Wierd sampling state exposed by some api's */ float shadow_ambient; /**< shadow test fail color/intensity */ float lod_bias; /**< LOD/lambda bias */ float min_lod, max_lod; /**< LOD clamp range, after bias */ -- cgit v1.2.3 From 5d802d8c8460cecf306b130eb29ef05069173e30 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 9 Mar 2008 15:09:55 +0100 Subject: cso: add a higher-level interface which does all pipe interactions to set a given state --- src/gallium/auxiliary/cso_cache/Makefile | 1 + src/gallium/auxiliary/cso_cache/SConscript | 1 + src/gallium/auxiliary/cso_cache/cso_context.c | 340 ++++++++++++++++++++++++++ src/gallium/auxiliary/cso_cache/cso_context.h | 85 +++++++ 4 files changed, 427 insertions(+) create mode 100644 src/gallium/auxiliary/cso_cache/cso_context.c create mode 100644 src/gallium/auxiliary/cso_cache/cso_context.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/Makefile b/src/gallium/auxiliary/cso_cache/Makefile index 3e49266163..6bd6602088 100644 --- a/src/gallium/auxiliary/cso_cache/Makefile +++ b/src/gallium/auxiliary/cso_cache/Makefile @@ -4,6 +4,7 @@ include $(TOP)/configs/current LIBNAME = cso_cache C_SOURCES = \ + cso_context.c \ cso_cache.c \ cso_hash.c diff --git a/src/gallium/auxiliary/cso_cache/SConscript b/src/gallium/auxiliary/cso_cache/SConscript index 9751881613..651e68a191 100644 --- a/src/gallium/auxiliary/cso_cache/SConscript +++ b/src/gallium/auxiliary/cso_cache/SConscript @@ -3,6 +3,7 @@ Import('*') cso_cache = env.ConvenienceLibrary( target = 'cso_cache', source = [ + 'cso_context.c', 'cso_cache.c', 'cso_hash.c', ]) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c new file mode 100644 index 0000000000..77237464c5 --- /dev/null +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -0,0 +1,340 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* Wrap the cso cache & hash mechanisms in a simplified + * pipe-driver-specific interface. + * + * Authors: + * Zack Rusin + * Keith Whitwell + */ + +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "cso_cache/cso_context.h" +#include "cso_cache/cso_cache.h" +#include "cso_cache/cso_hash.h" + +struct cso_context { + struct pipe_context *pipe; + struct cso_cache *cache; + + struct { + void *samplers[PIPE_MAX_SAMPLERS]; + unsigned nr_samplers; + } hw; + + void *samplers[PIPE_MAX_SAMPLERS]; + unsigned nr_samplers; + + void *blend; + void *depth_stencil; + void *rasterizer; + void *fragment_shader; + void *vertex_shader; +}; + + +struct cso_context *cso_create_context( struct pipe_context *pipe ) +{ + struct cso_context *ctx = CALLOC_STRUCT(cso_context); + if (ctx == NULL) + goto out; + + ctx->cache = cso_cache_create(); + if (ctx->cache == NULL) + goto out; + + ctx->pipe = pipe; + + return ctx; + +out: + cso_destroy_context( ctx ); + return NULL; +} + + +void cso_destroy_context( struct cso_context *ctx ) +{ + if (ctx == NULL) + return; + +/* + if (ctx->pipe) + ctx->pipe->flush( ctx->pipe, PIPE_FLUSH_UNBIND_ALL ); +*/ + + if (ctx->cache) + cso_cache_delete( ctx->cache ); + + FREE( ctx ); +} + + +/* Those function will either find the state of the given template + * in the cache or they will create a new state from the given + * template, insert it in the cache and return it. + */ + +/* + * If the driver returns 0 from the create method then they will assign + * the data member of the cso to be the template itself. + */ + +void cso_set_blend(struct cso_context *ctx, + const struct pipe_blend_state *templ) +{ + unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, CSO_BLEND, + (void*)templ); + void *handle; + + if (cso_hash_iter_is_null(iter)) { + struct cso_blend *cso = malloc(sizeof(struct cso_blend)); + + cso->state = *templ; + cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state; + cso->context = ctx->pipe; + + iter = cso_insert_state(ctx->cache, hash_key, CSO_BLEND, cso); + handle = cso->data; + } + else { + handle = ((struct cso_blend *)cso_hash_iter_data(iter))->data; + } + + if (ctx->blend != handle) { + ctx->blend = handle; + ctx->pipe->bind_blend_state(ctx->pipe, handle); + } +} + +void cso_single_sampler(struct cso_context *ctx, + unsigned idx, + const struct pipe_sampler_state *templ) +{ + void *handle = NULL; + + if (templ != NULL) { + unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, CSO_SAMPLER, + (void*)templ); + + if (cso_hash_iter_is_null(iter)) { + struct cso_sampler *cso = malloc(sizeof(struct cso_sampler)); + + cso->state = *templ; + cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state; + cso->context = ctx->pipe; + + iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso); + handle = cso->data; + } + else { + handle = ((struct cso_sampler *)cso_hash_iter_data(iter))->data; + } + } + + ctx->samplers[idx] = handle; +} + +void cso_single_sampler_done( struct cso_context *ctx ) +{ + unsigned i; + + for (i = 0; i < 8; i++) + if (ctx->samplers[i] == NULL) + break; + + ctx->nr_samplers = i; + + if (ctx->hw.nr_samplers != ctx->nr_samplers || + memcmp(ctx->hw.samplers, + ctx->samplers, + ctx->nr_samplers * sizeof(void *)) != 0) + { + memcpy(ctx->hw.samplers, ctx->samplers, ctx->nr_samplers * sizeof(void *)); + ctx->hw.nr_samplers = ctx->nr_samplers; + + ctx->pipe->bind_sampler_states(ctx->pipe, ctx->nr_samplers, ctx->samplers); + } +} + +void cso_set_samplers( struct cso_context *ctx, + unsigned nr, + const struct pipe_sampler_state **templates ) +{ + unsigned i; + + /* TODO: fastpath + */ + + for (i = 0; i < nr; i++) + cso_single_sampler( ctx, i, templates[i] ); + + for ( ; i < ctx->nr_samplers; i++) + cso_single_sampler( ctx, i, NULL ); + + cso_single_sampler_done( ctx ); +} + +void cso_set_depth_stencil_alpha(struct cso_context *ctx, + const struct pipe_depth_stencil_alpha_state *templ) +{ + unsigned hash_key = cso_construct_key((void*)templ, + sizeof(struct pipe_depth_stencil_alpha_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, + CSO_DEPTH_STENCIL_ALPHA, + (void*)templ); + void *handle; + + if (cso_hash_iter_is_null(iter)) { + struct cso_depth_stencil_alpha *cso = malloc(sizeof(struct cso_depth_stencil_alpha)); + + cso->state = *templ; + cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state; + cso->context = ctx->pipe; + + cso_insert_state(ctx->cache, hash_key, CSO_DEPTH_STENCIL_ALPHA, cso); + handle = cso->data; + } + else { + handle = ((struct cso_depth_stencil_alpha *)cso_hash_iter_data(iter))->data; + } + + if (ctx->depth_stencil != handle) { + ctx->depth_stencil = handle; + ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, handle); + } +} + + + +void cso_set_rasterizer(struct cso_context *ctx, + const struct pipe_rasterizer_state *templ) +{ + unsigned hash_key = cso_construct_key((void*)templ, + sizeof(struct pipe_rasterizer_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, CSO_RASTERIZER, + (void*)templ); + void *handle = NULL; + + if (cso_hash_iter_is_null(iter)) { + struct cso_rasterizer *cso = malloc(sizeof(struct cso_rasterizer)); + + cso->state = *templ; + cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_rasterizer_state; + cso->context = ctx->pipe; + + cso_insert_state(ctx->cache, hash_key, CSO_RASTERIZER, cso); + handle = cso->data; + } + else { + handle = ((struct cso_rasterizer *)cso_hash_iter_data(iter))->data; + } + + if (ctx->rasterizer != handle) { + ctx->rasterizer = handle; + ctx->pipe->bind_rasterizer_state(ctx->pipe, handle); + } +} + + + + + +void cso_set_fragment_shader(struct cso_context *ctx, + const struct pipe_shader_state *templ) +{ + unsigned hash_key = cso_construct_key((void*)templ, + sizeof(struct pipe_shader_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, CSO_FRAGMENT_SHADER, + (void*)templ); + void *handle = NULL; + + if (cso_hash_iter_is_null(iter)) { + struct cso_fragment_shader *cso = malloc(sizeof(struct cso_fragment_shader)); + + cso->state = *templ; + cso->data = ctx->pipe->create_fs_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_fs_state; + cso->context = ctx->pipe; + + iter = cso_insert_state(ctx->cache, hash_key, CSO_FRAGMENT_SHADER, cso); + handle = cso->data; + } + else { + handle = ((struct cso_fragment_shader *)cso_hash_iter_data(iter))->data; + } + + if (ctx->fragment_shader != handle) { + ctx->fragment_shader = handle; + ctx->pipe->bind_fs_state(ctx->pipe, handle); + } +} + +void cso_set_vertex_shader(struct cso_context *ctx, + const struct pipe_shader_state *templ) +{ + unsigned hash_key = cso_construct_key((void*)templ, + sizeof(struct pipe_shader_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, CSO_VERTEX_SHADER, + (void*)templ); + void *handle = NULL; + + if (cso_hash_iter_is_null(iter)) { + struct cso_vertex_shader *cso = malloc(sizeof(struct cso_vertex_shader)); + + cso->state = *templ; + cso->data = ctx->pipe->create_vs_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_vs_state; + cso->context = ctx->pipe; + + iter = cso_insert_state(ctx->cache, hash_key, CSO_VERTEX_SHADER, cso); + handle = cso->data; + } + else { + handle = ((struct cso_vertex_shader *)cso_hash_iter_data(iter))->data; + } + + if (ctx->vertex_shader != handle) { + ctx->vertex_shader = handle; + ctx->pipe->bind_fs_state(ctx->pipe, handle); + } +} diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h new file mode 100644 index 0000000000..1f2a630804 --- /dev/null +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -0,0 +1,85 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef CSO_CONTEXT_H +#define CSO_CONTEXT_H + +#include "pipe/p_context.h" +#include "pipe/p_state.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +struct cso_context; + +struct cso_context *cso_create_context( struct pipe_context *pipe ); + +void cso_set_blend( struct cso_context *cso, + const struct pipe_blend_state *blend ); + +void cso_set_depth_stencil_alpha( struct cso_context *cso, + const struct pipe_depth_stencil_alpha_state *dsa ); + +void cso_set_rasterizer( struct cso_context *cso, + const struct pipe_rasterizer_state *rasterizer ); + +void cso_set_samplers( struct cso_context *cso, + unsigned count, + const struct pipe_sampler_state **states ); + +/* Alternate interface to support state trackers that like to modify + * samplers one at a time: + */ +void cso_single_sampler( struct cso_context *cso, + unsigned nr, + const struct pipe_sampler_state *states ); + +void cso_single_sampler_done( struct cso_context *cso ); + + +/* These aren't really sensible -- most of the time the api provides + * object semantics for shaders anyway, and the cases where it doesn't + * (eg mesa's internall-generated texenv programs), it will be up to + * the state tracker to implement their own specialized caching. + */ +void cso_set_fragment_shader( struct cso_context *cso, + const struct pipe_shader_state *shader ); + +void cso_set_vertex_shader( struct cso_context *cso, + const struct pipe_shader_state *shader ); + +void cso_destroy_context( struct cso_context *cso ); + + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3 From ac87bc18359825890a53d4dbfda5c6eecd916afd Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 9 Mar 2008 17:05:46 +0100 Subject: cso: Use MALLOC --- src/gallium/auxiliary/cso_cache/cso_context.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 77237464c5..051e7d96d3 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -117,7 +117,7 @@ void cso_set_blend(struct cso_context *ctx, void *handle; if (cso_hash_iter_is_null(iter)) { - struct cso_blend *cso = malloc(sizeof(struct cso_blend)); + struct cso_blend *cso = MALLOC(sizeof(struct cso_blend)); cso->state = *templ; cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state); @@ -150,7 +150,7 @@ void cso_single_sampler(struct cso_context *ctx, (void*)templ); if (cso_hash_iter_is_null(iter)) { - struct cso_sampler *cso = malloc(sizeof(struct cso_sampler)); + struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler)); cso->state = *templ; cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state); @@ -220,7 +220,7 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx, void *handle; if (cso_hash_iter_is_null(iter)) { - struct cso_depth_stencil_alpha *cso = malloc(sizeof(struct cso_depth_stencil_alpha)); + struct cso_depth_stencil_alpha *cso = MALLOC(sizeof(struct cso_depth_stencil_alpha)); cso->state = *templ; cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &cso->state); @@ -253,7 +253,7 @@ void cso_set_rasterizer(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { - struct cso_rasterizer *cso = malloc(sizeof(struct cso_rasterizer)); + struct cso_rasterizer *cso = MALLOC(sizeof(struct cso_rasterizer)); cso->state = *templ; cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state); @@ -288,7 +288,7 @@ void cso_set_fragment_shader(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { - struct cso_fragment_shader *cso = malloc(sizeof(struct cso_fragment_shader)); + struct cso_fragment_shader *cso = MALLOC(sizeof(struct cso_fragment_shader)); cso->state = *templ; cso->data = ctx->pipe->create_fs_state(ctx->pipe, &cso->state); @@ -319,7 +319,7 @@ void cso_set_vertex_shader(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { - struct cso_vertex_shader *cso = malloc(sizeof(struct cso_vertex_shader)); + struct cso_vertex_shader *cso = MALLOC(sizeof(struct cso_vertex_shader)); cso->state = *templ; cso->data = ctx->pipe->create_vs_state(ctx->pipe, &cso->state); -- cgit v1.2.3 From d8d6569e288fe3324473fb19ade798502dfbba8e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 9 Mar 2008 17:06:20 +0100 Subject: cso: fix line endings --- src/gallium/auxiliary/cso_cache/cso_context.c | 680 +++++++++++++------------- 1 file changed, 340 insertions(+), 340 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 051e7d96d3..596e5a9ad6 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -1,340 +1,340 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* Wrap the cso cache & hash mechanisms in a simplified - * pipe-driver-specific interface. - * - * Authors: - * Zack Rusin - * Keith Whitwell - */ - -#include "pipe/p_state.h" -#include "pipe/p_util.h" - -#include "cso_cache/cso_context.h" -#include "cso_cache/cso_cache.h" -#include "cso_cache/cso_hash.h" - -struct cso_context { - struct pipe_context *pipe; - struct cso_cache *cache; - - struct { - void *samplers[PIPE_MAX_SAMPLERS]; - unsigned nr_samplers; - } hw; - - void *samplers[PIPE_MAX_SAMPLERS]; - unsigned nr_samplers; - - void *blend; - void *depth_stencil; - void *rasterizer; - void *fragment_shader; - void *vertex_shader; -}; - - -struct cso_context *cso_create_context( struct pipe_context *pipe ) -{ - struct cso_context *ctx = CALLOC_STRUCT(cso_context); - if (ctx == NULL) - goto out; - - ctx->cache = cso_cache_create(); - if (ctx->cache == NULL) - goto out; - - ctx->pipe = pipe; - - return ctx; - -out: - cso_destroy_context( ctx ); - return NULL; -} - - -void cso_destroy_context( struct cso_context *ctx ) -{ - if (ctx == NULL) - return; - -/* - if (ctx->pipe) - ctx->pipe->flush( ctx->pipe, PIPE_FLUSH_UNBIND_ALL ); -*/ - - if (ctx->cache) - cso_cache_delete( ctx->cache ); - - FREE( ctx ); -} - - -/* Those function will either find the state of the given template - * in the cache or they will create a new state from the given - * template, insert it in the cache and return it. - */ - -/* - * If the driver returns 0 from the create method then they will assign - * the data member of the cso to be the template itself. - */ - -void cso_set_blend(struct cso_context *ctx, - const struct pipe_blend_state *templ) -{ - unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state)); - struct cso_hash_iter iter = cso_find_state_template(ctx->cache, - hash_key, CSO_BLEND, - (void*)templ); - void *handle; - - if (cso_hash_iter_is_null(iter)) { - struct cso_blend *cso = MALLOC(sizeof(struct cso_blend)); - - cso->state = *templ; - cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state); - cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state; - cso->context = ctx->pipe; - - iter = cso_insert_state(ctx->cache, hash_key, CSO_BLEND, cso); - handle = cso->data; - } - else { - handle = ((struct cso_blend *)cso_hash_iter_data(iter))->data; - } - - if (ctx->blend != handle) { - ctx->blend = handle; - ctx->pipe->bind_blend_state(ctx->pipe, handle); - } -} - -void cso_single_sampler(struct cso_context *ctx, - unsigned idx, - const struct pipe_sampler_state *templ) -{ - void *handle = NULL; - - if (templ != NULL) { - unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state)); - struct cso_hash_iter iter = cso_find_state_template(ctx->cache, - hash_key, CSO_SAMPLER, - (void*)templ); - - if (cso_hash_iter_is_null(iter)) { - struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler)); - - cso->state = *templ; - cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state); - cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state; - cso->context = ctx->pipe; - - iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso); - handle = cso->data; - } - else { - handle = ((struct cso_sampler *)cso_hash_iter_data(iter))->data; - } - } - - ctx->samplers[idx] = handle; -} - -void cso_single_sampler_done( struct cso_context *ctx ) -{ - unsigned i; - - for (i = 0; i < 8; i++) - if (ctx->samplers[i] == NULL) - break; - - ctx->nr_samplers = i; - - if (ctx->hw.nr_samplers != ctx->nr_samplers || - memcmp(ctx->hw.samplers, - ctx->samplers, - ctx->nr_samplers * sizeof(void *)) != 0) - { - memcpy(ctx->hw.samplers, ctx->samplers, ctx->nr_samplers * sizeof(void *)); - ctx->hw.nr_samplers = ctx->nr_samplers; - - ctx->pipe->bind_sampler_states(ctx->pipe, ctx->nr_samplers, ctx->samplers); - } -} - -void cso_set_samplers( struct cso_context *ctx, - unsigned nr, - const struct pipe_sampler_state **templates ) -{ - unsigned i; - - /* TODO: fastpath - */ - - for (i = 0; i < nr; i++) - cso_single_sampler( ctx, i, templates[i] ); - - for ( ; i < ctx->nr_samplers; i++) - cso_single_sampler( ctx, i, NULL ); - - cso_single_sampler_done( ctx ); -} - -void cso_set_depth_stencil_alpha(struct cso_context *ctx, - const struct pipe_depth_stencil_alpha_state *templ) -{ - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_depth_stencil_alpha_state)); - struct cso_hash_iter iter = cso_find_state_template(ctx->cache, - hash_key, - CSO_DEPTH_STENCIL_ALPHA, - (void*)templ); - void *handle; - - if (cso_hash_iter_is_null(iter)) { - struct cso_depth_stencil_alpha *cso = MALLOC(sizeof(struct cso_depth_stencil_alpha)); - - cso->state = *templ; - cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &cso->state); - cso->delete_state = (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state; - cso->context = ctx->pipe; - - cso_insert_state(ctx->cache, hash_key, CSO_DEPTH_STENCIL_ALPHA, cso); - handle = cso->data; - } - else { - handle = ((struct cso_depth_stencil_alpha *)cso_hash_iter_data(iter))->data; - } - - if (ctx->depth_stencil != handle) { - ctx->depth_stencil = handle; - ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, handle); - } -} - - - -void cso_set_rasterizer(struct cso_context *ctx, - const struct pipe_rasterizer_state *templ) -{ - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_rasterizer_state)); - struct cso_hash_iter iter = cso_find_state_template(ctx->cache, - hash_key, CSO_RASTERIZER, - (void*)templ); - void *handle = NULL; - - if (cso_hash_iter_is_null(iter)) { - struct cso_rasterizer *cso = MALLOC(sizeof(struct cso_rasterizer)); - - cso->state = *templ; - cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state); - cso->delete_state = (cso_state_callback)ctx->pipe->delete_rasterizer_state; - cso->context = ctx->pipe; - - cso_insert_state(ctx->cache, hash_key, CSO_RASTERIZER, cso); - handle = cso->data; - } - else { - handle = ((struct cso_rasterizer *)cso_hash_iter_data(iter))->data; - } - - if (ctx->rasterizer != handle) { - ctx->rasterizer = handle; - ctx->pipe->bind_rasterizer_state(ctx->pipe, handle); - } -} - - - - - -void cso_set_fragment_shader(struct cso_context *ctx, - const struct pipe_shader_state *templ) -{ - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_shader_state)); - struct cso_hash_iter iter = cso_find_state_template(ctx->cache, - hash_key, CSO_FRAGMENT_SHADER, - (void*)templ); - void *handle = NULL; - - if (cso_hash_iter_is_null(iter)) { - struct cso_fragment_shader *cso = MALLOC(sizeof(struct cso_fragment_shader)); - - cso->state = *templ; - cso->data = ctx->pipe->create_fs_state(ctx->pipe, &cso->state); - cso->delete_state = (cso_state_callback)ctx->pipe->delete_fs_state; - cso->context = ctx->pipe; - - iter = cso_insert_state(ctx->cache, hash_key, CSO_FRAGMENT_SHADER, cso); - handle = cso->data; - } - else { - handle = ((struct cso_fragment_shader *)cso_hash_iter_data(iter))->data; - } - - if (ctx->fragment_shader != handle) { - ctx->fragment_shader = handle; - ctx->pipe->bind_fs_state(ctx->pipe, handle); - } -} - -void cso_set_vertex_shader(struct cso_context *ctx, - const struct pipe_shader_state *templ) -{ - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_shader_state)); - struct cso_hash_iter iter = cso_find_state_template(ctx->cache, - hash_key, CSO_VERTEX_SHADER, - (void*)templ); - void *handle = NULL; - - if (cso_hash_iter_is_null(iter)) { - struct cso_vertex_shader *cso = MALLOC(sizeof(struct cso_vertex_shader)); - - cso->state = *templ; - cso->data = ctx->pipe->create_vs_state(ctx->pipe, &cso->state); - cso->delete_state = (cso_state_callback)ctx->pipe->delete_vs_state; - cso->context = ctx->pipe; - - iter = cso_insert_state(ctx->cache, hash_key, CSO_VERTEX_SHADER, cso); - handle = cso->data; - } - else { - handle = ((struct cso_vertex_shader *)cso_hash_iter_data(iter))->data; - } - - if (ctx->vertex_shader != handle) { - ctx->vertex_shader = handle; - ctx->pipe->bind_fs_state(ctx->pipe, handle); - } -} +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* Wrap the cso cache & hash mechanisms in a simplified + * pipe-driver-specific interface. + * + * Authors: + * Zack Rusin + * Keith Whitwell + */ + +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "cso_cache/cso_context.h" +#include "cso_cache/cso_cache.h" +#include "cso_cache/cso_hash.h" + +struct cso_context { + struct pipe_context *pipe; + struct cso_cache *cache; + + struct { + void *samplers[PIPE_MAX_SAMPLERS]; + unsigned nr_samplers; + } hw; + + void *samplers[PIPE_MAX_SAMPLERS]; + unsigned nr_samplers; + + void *blend; + void *depth_stencil; + void *rasterizer; + void *fragment_shader; + void *vertex_shader; +}; + + +struct cso_context *cso_create_context( struct pipe_context *pipe ) +{ + struct cso_context *ctx = CALLOC_STRUCT(cso_context); + if (ctx == NULL) + goto out; + + ctx->cache = cso_cache_create(); + if (ctx->cache == NULL) + goto out; + + ctx->pipe = pipe; + + return ctx; + +out: + cso_destroy_context( ctx ); + return NULL; +} + + +void cso_destroy_context( struct cso_context *ctx ) +{ + if (ctx == NULL) + return; + +/* + if (ctx->pipe) + ctx->pipe->flush( ctx->pipe, PIPE_FLUSH_UNBIND_ALL ); +*/ + + if (ctx->cache) + cso_cache_delete( ctx->cache ); + + FREE( ctx ); +} + + +/* Those function will either find the state of the given template + * in the cache or they will create a new state from the given + * template, insert it in the cache and return it. + */ + +/* + * If the driver returns 0 from the create method then they will assign + * the data member of the cso to be the template itself. + */ + +void cso_set_blend(struct cso_context *ctx, + const struct pipe_blend_state *templ) +{ + unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, CSO_BLEND, + (void*)templ); + void *handle; + + if (cso_hash_iter_is_null(iter)) { + struct cso_blend *cso = MALLOC(sizeof(struct cso_blend)); + + cso->state = *templ; + cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state; + cso->context = ctx->pipe; + + iter = cso_insert_state(ctx->cache, hash_key, CSO_BLEND, cso); + handle = cso->data; + } + else { + handle = ((struct cso_blend *)cso_hash_iter_data(iter))->data; + } + + if (ctx->blend != handle) { + ctx->blend = handle; + ctx->pipe->bind_blend_state(ctx->pipe, handle); + } +} + +void cso_single_sampler(struct cso_context *ctx, + unsigned idx, + const struct pipe_sampler_state *templ) +{ + void *handle = NULL; + + if (templ != NULL) { + unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, CSO_SAMPLER, + (void*)templ); + + if (cso_hash_iter_is_null(iter)) { + struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler)); + + cso->state = *templ; + cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state; + cso->context = ctx->pipe; + + iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso); + handle = cso->data; + } + else { + handle = ((struct cso_sampler *)cso_hash_iter_data(iter))->data; + } + } + + ctx->samplers[idx] = handle; +} + +void cso_single_sampler_done( struct cso_context *ctx ) +{ + unsigned i; + + for (i = 0; i < 8; i++) + if (ctx->samplers[i] == NULL) + break; + + ctx->nr_samplers = i; + + if (ctx->hw.nr_samplers != ctx->nr_samplers || + memcmp(ctx->hw.samplers, + ctx->samplers, + ctx->nr_samplers * sizeof(void *)) != 0) + { + memcpy(ctx->hw.samplers, ctx->samplers, ctx->nr_samplers * sizeof(void *)); + ctx->hw.nr_samplers = ctx->nr_samplers; + + ctx->pipe->bind_sampler_states(ctx->pipe, ctx->nr_samplers, ctx->samplers); + } +} + +void cso_set_samplers( struct cso_context *ctx, + unsigned nr, + const struct pipe_sampler_state **templates ) +{ + unsigned i; + + /* TODO: fastpath + */ + + for (i = 0; i < nr; i++) + cso_single_sampler( ctx, i, templates[i] ); + + for ( ; i < ctx->nr_samplers; i++) + cso_single_sampler( ctx, i, NULL ); + + cso_single_sampler_done( ctx ); +} + +void cso_set_depth_stencil_alpha(struct cso_context *ctx, + const struct pipe_depth_stencil_alpha_state *templ) +{ + unsigned hash_key = cso_construct_key((void*)templ, + sizeof(struct pipe_depth_stencil_alpha_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, + CSO_DEPTH_STENCIL_ALPHA, + (void*)templ); + void *handle; + + if (cso_hash_iter_is_null(iter)) { + struct cso_depth_stencil_alpha *cso = MALLOC(sizeof(struct cso_depth_stencil_alpha)); + + cso->state = *templ; + cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state; + cso->context = ctx->pipe; + + cso_insert_state(ctx->cache, hash_key, CSO_DEPTH_STENCIL_ALPHA, cso); + handle = cso->data; + } + else { + handle = ((struct cso_depth_stencil_alpha *)cso_hash_iter_data(iter))->data; + } + + if (ctx->depth_stencil != handle) { + ctx->depth_stencil = handle; + ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, handle); + } +} + + + +void cso_set_rasterizer(struct cso_context *ctx, + const struct pipe_rasterizer_state *templ) +{ + unsigned hash_key = cso_construct_key((void*)templ, + sizeof(struct pipe_rasterizer_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, CSO_RASTERIZER, + (void*)templ); + void *handle = NULL; + + if (cso_hash_iter_is_null(iter)) { + struct cso_rasterizer *cso = MALLOC(sizeof(struct cso_rasterizer)); + + cso->state = *templ; + cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_rasterizer_state; + cso->context = ctx->pipe; + + cso_insert_state(ctx->cache, hash_key, CSO_RASTERIZER, cso); + handle = cso->data; + } + else { + handle = ((struct cso_rasterizer *)cso_hash_iter_data(iter))->data; + } + + if (ctx->rasterizer != handle) { + ctx->rasterizer = handle; + ctx->pipe->bind_rasterizer_state(ctx->pipe, handle); + } +} + + + + + +void cso_set_fragment_shader(struct cso_context *ctx, + const struct pipe_shader_state *templ) +{ + unsigned hash_key = cso_construct_key((void*)templ, + sizeof(struct pipe_shader_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, CSO_FRAGMENT_SHADER, + (void*)templ); + void *handle = NULL; + + if (cso_hash_iter_is_null(iter)) { + struct cso_fragment_shader *cso = MALLOC(sizeof(struct cso_fragment_shader)); + + cso->state = *templ; + cso->data = ctx->pipe->create_fs_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_fs_state; + cso->context = ctx->pipe; + + iter = cso_insert_state(ctx->cache, hash_key, CSO_FRAGMENT_SHADER, cso); + handle = cso->data; + } + else { + handle = ((struct cso_fragment_shader *)cso_hash_iter_data(iter))->data; + } + + if (ctx->fragment_shader != handle) { + ctx->fragment_shader = handle; + ctx->pipe->bind_fs_state(ctx->pipe, handle); + } +} + +void cso_set_vertex_shader(struct cso_context *ctx, + const struct pipe_shader_state *templ) +{ + unsigned hash_key = cso_construct_key((void*)templ, + sizeof(struct pipe_shader_state)); + struct cso_hash_iter iter = cso_find_state_template(ctx->cache, + hash_key, CSO_VERTEX_SHADER, + (void*)templ); + void *handle = NULL; + + if (cso_hash_iter_is_null(iter)) { + struct cso_vertex_shader *cso = MALLOC(sizeof(struct cso_vertex_shader)); + + cso->state = *templ; + cso->data = ctx->pipe->create_vs_state(ctx->pipe, &cso->state); + cso->delete_state = (cso_state_callback)ctx->pipe->delete_vs_state; + cso->context = ctx->pipe; + + iter = cso_insert_state(ctx->cache, hash_key, CSO_VERTEX_SHADER, cso); + handle = cso->data; + } + else { + handle = ((struct cso_vertex_shader *)cso_hash_iter_data(iter))->data; + } + + if (ctx->vertex_shader != handle) { + ctx->vertex_shader = handle; + ctx->pipe->bind_fs_state(ctx->pipe, handle); + } +} -- cgit v1.2.3 From aff4cf19a753baf0428d2bf53614900e5afea8a3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 9 Mar 2008 20:17:02 +0000 Subject: draw: cope with binding NULL vertex shader (on context delete, for instance) --- src/gallium/auxiliary/draw/draw_vertex_shader.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index 1e95355555..133418baca 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -110,13 +110,20 @@ draw_bind_vertex_shader(struct draw_context *draw, struct draw_vertex_shader *dvs) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + if (dvs) + { + draw->vertex_shader = dvs; + draw->num_vs_outputs = dvs->info.num_outputs; - draw->vertex_shader = dvs; - draw->num_vs_outputs = dvs->info.num_outputs; + tgsi_exec_machine_init(&draw->machine); - tgsi_exec_machine_init(&draw->machine); - - dvs->prepare( dvs, draw ); + dvs->prepare( dvs, draw ); + } + else { + draw->vertex_shader = NULL; + draw->num_vs_outputs = 0; + } } -- cgit v1.2.3 From b041dbe9019ff8cb16ff15d0baaa803c7dc654db Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 9 Mar 2008 20:21:45 +0000 Subject: gallium: avoid deleting currently-bound CSO's on cache destruction --- src/gallium/auxiliary/cso_cache/cso_context.c | 34 +++++++++++++++++++-------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 596e5a9ad6..fbb26ca511 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -72,6 +72,9 @@ struct cso_context *cso_create_context( struct pipe_context *pipe ) ctx->pipe = pipe; + /* Enable for testing: */ + if (0) cso_set_maximum_cache_size( ctx->cache, 4 ); + return ctx; out: @@ -79,20 +82,31 @@ out: return NULL; } +static void cso_release_all( struct cso_context *ctx ) +{ + if (ctx->pipe) { + ctx->pipe->bind_blend_state( ctx->pipe, NULL ); + ctx->pipe->bind_rasterizer_state( ctx->pipe, NULL ); + ctx->pipe->bind_sampler_states( ctx->pipe, 0, NULL ); + ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL ); + ctx->pipe->bind_fs_state( ctx->pipe, NULL ); + ctx->pipe->bind_vs_state( ctx->pipe, NULL ); + } + + if (ctx->cache) { + cso_cache_delete( ctx->cache ); + ctx->cache = NULL; + } +} + void cso_destroy_context( struct cso_context *ctx ) { - if (ctx == NULL) - return; - -/* - if (ctx->pipe) - ctx->pipe->flush( ctx->pipe, PIPE_FLUSH_UNBIND_ALL ); -*/ + debug_printf("%s\n", __FUNCTION__); + + if (ctx) + cso_release_all( ctx ); - if (ctx->cache) - cso_cache_delete( ctx->cache ); - FREE( ctx ); } -- cgit v1.2.3 From b721bc8792f6add71dede11924d7060bbce72f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 10 Mar 2008 13:04:13 +0000 Subject: gallium: WinCE portability fixes. --- src/gallium/auxiliary/draw/draw_unfilled.c | 2 +- src/gallium/auxiliary/util/p_debug.c | 8 ++++++++ src/gallium/drivers/softpipe/sp_quad_alpha_test.c | 2 +- src/gallium/drivers/softpipe/sp_quad_blend.c | 6 +++--- src/gallium/drivers/softpipe/sp_quad_depth_test.c | 2 +- src/gallium/include/pipe/p_util.h | 10 ++++++++++ 6 files changed, 24 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_unfilled.c b/src/gallium/auxiliary/draw/draw_unfilled.c index 4d718d514c..b07860cd9e 100644 --- a/src/gallium/auxiliary/draw/draw_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_unfilled.c @@ -129,7 +129,7 @@ static void unfilled_tri( struct draw_stage *stage, points( stage, header ); break; default: - abort(); + assert(0); } } diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 7b3c030956..6255d716a6 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -57,11 +57,15 @@ int rpl_vsnprintf(char *, size_t, const char *, va_list); void debug_vprintf(const char *format, va_list ap) { #ifdef WIN32 +#ifndef WINCE /* EngDebugPrint does not handle float point arguments, so we need to use * our own vsnprintf implementation */ char buf[512 + 1]; rpl_vsnprintf(buf, sizeof(buf), format, ap); rpl_EngDebugPrint("%s", buf); +#else + /* TODO: Implement debug print for WINCE */ +#endif #else vfprintf(stderr, format, ap); #endif @@ -80,7 +84,11 @@ void debug_printf(const char *format, ...) static INLINE void debug_abort(void) { #ifdef WIN32 +#ifndef WINCE EngDebugBreak(); +#else + _asm {int 3}; +#endif #else abort(); #endif diff --git a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c index 4ffeac35e1..318916fe30 100644 --- a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c @@ -72,7 +72,7 @@ alpha_test_quad(struct quad_stage *qs, struct quad_header *quad) passMask = MASK_ALL; break; default: - abort(); + assert(0); } quad->mask &= passMask; diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index 17f3ecd0b8..0b79cfa1ed 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -392,7 +392,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) assert(0); /* to do */ break; default: - abort(); + assert(0); } /* @@ -464,7 +464,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) } break; default: - abort(); + assert(0); } @@ -716,7 +716,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */ break; default: - abort(); + assert(0); } /* pass blended quad to next stage */ diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index a9a0754f27..a1859f9883 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -185,7 +185,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) zmask = MASK_ALL; break; default: - abort(); + assert(0); } quad->mask &= zmask; diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 3b32ba1d24..ef36ce75f7 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -54,7 +54,12 @@ EngFreeMem( static INLINE void * MALLOC( unsigned size ) { +#ifdef WINCE + /* TODO: Need to abstract this */ + return malloc( size ); +#else return EngAllocMem( 0, size, 'D3AG' ); +#endif } static INLINE void * @@ -71,7 +76,12 @@ static INLINE void FREE( void *ptr ) { if( ptr ) { +#ifdef WINCE + /* TODO: Need to abstract this */ + free( ptr ); +#else EngFreeMem( ptr ); +#endif } } -- cgit v1.2.3 From 01bd21eef8f572944c09771f44e3006e2991280e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 10 Mar 2008 16:45:19 +0000 Subject: gallium: Import Dennis Smit cpu detection code. It still needs a slight code massasing to integrate with the rest of gallium (namely mapping the OS_* ARCH_* defines), but I'm commiting anyway so that it is available to be used when somebody needs it. --- src/gallium/auxiliary/util/u_cpu_detect.c | 506 ++++++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_cpu_detect.h | 78 +++++ 2 files changed, 584 insertions(+) create mode 100644 src/gallium/auxiliary/util/u_cpu_detect.c create mode 100644 src/gallium/auxiliary/util/u_cpu_detect.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_cpu_detect.c b/src/gallium/auxiliary/util/u_cpu_detect.c new file mode 100644 index 0000000000..d9f2f8fc28 --- /dev/null +++ b/src/gallium/auxiliary/util/u_cpu_detect.c @@ -0,0 +1,506 @@ +/************************************************************************** + * + * Copyright 2008 Dennis Smit + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* + * Based on the work of Eric Anholt + */ + +/* FIXME: clean this entire file up */ + +#include "u_cpu_detect.h" + +#ifdef __linux__ +#define OS_LINUX +#endif +#ifdef WIN32 +#define OS_WIN32 +#endif + +#if defined(ARCH_POWERPC) +#if defined(OS_DARWIN) +#include +#else +#include +#include +#endif +#endif + +#if defined(OS_NETBSD) || defined(OS_OPENBSD) +#include +#include +#include +#endif + +#if defined(OS_FREEBSD) +#include +#include +#endif + +#if defined(OS_LINUX) +#include +#endif + +#if defined(OS_WIN32) +#include +#endif + +#include +#include +#include +#include + + +static struct cpu_detect_caps __cpu_detect_caps; +static int __cpu_detect_initialized = 0; + +static int has_cpuid(void); +static int cpuid(unsigned int ax, unsigned int *p); + +/* The sigill handlers */ +#if defined(ARCH_X86) /* x86 (linux katmai handler check thing) */ +#if defined(OS_LINUX) && defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC) +static void sigill_handler_sse(int signal, struct sigcontext sc) +{ + /* Both the "xorps %%xmm0,%%xmm0" and "divps %xmm0,%%xmm1" + * instructions are 3 bytes long. We must increment the instruction + * pointer manually to avoid repeated execution of the offending + * instruction. + * + * If the SIGILL is caused by a divide-by-zero when unmasked + * exceptions aren't supported, the SIMD FPU status and control + * word will be restored at the end of the test, so we don't need + * to worry about doing it here. Besides, we may not be able to... + */ + sc.eip += 3; + + __cpu_detect_caps.hasSSE=0; +} + +static void sigfpe_handler_sse(int signal, struct sigcontext sc) +{ + if (sc.fpstate->magic != 0xffff) { + /* Our signal context has the extended FPU state, so reset the + * divide-by-zero exception mask and clear the divide-by-zero + * exception bit. + */ + sc.fpstate->mxcsr |= 0x00000200; + sc.fpstate->mxcsr &= 0xfffffffb; + } else { + /* If we ever get here, we're completely hosed. + */ + } +} +#endif +#endif /* OS_LINUX && _POSIX_SOURCE && X86_FXSR_MAGIC */ + +#if defined(OS_WIN32) +LONG CALLBACK win32_sig_handler_sse(EXCEPTION_POINTERS* ep) +{ + if(ep->ExceptionRecord->ExceptionCode==EXCEPTION_ILLEGAL_INSTRUCTION){ + ep->ContextRecord->Eip +=3; + __cpu_detect_caps.hasSSE=0; + return EXCEPTION_CONTINUE_EXECUTION; + } + return EXCEPTION_CONTINUE_SEARCH; +} +#endif /* OS_WIN32 */ + + +#if defined(ARCH_POWERPC) && !defined(OS_DARWIN) +static sigjmp_buf __lv_powerpc_jmpbuf; +static volatile sig_atomic_t __lv_powerpc_canjump = 0; + +static void sigill_handler (int sig); + +static void sigill_handler (int sig) +{ + if (!__lv_powerpc_canjump) { + signal (sig, SIG_DFL); + raise (sig); + } + + __lv_powerpc_canjump = 0; + siglongjmp(__lv_powerpc_jmpbuf, 1); +} + +static void check_os_altivec_support(void) +{ +#if defined(OS_DARWIN) + int sels[2] = {CTL_HW, HW_VECTORUNIT}; + int has_vu = 0; + int len = sizeof (has_vu); + int err; + + err = sysctl(sels, 2, &has_vu, &len, NULL, 0); + + if (err == 0) { + if (has_vu != 0) { + __cpu_detect_caps.hasAltiVec = 1; + } + } +#else /* !OS_DARWIN */ + /* no Darwin, do it the brute-force way */ + /* this is borrowed from the libmpeg2 library */ + signal(SIGILL, sigill_handler); + if (sigsetjmp(__lv_powerpc_jmpbuf, 1)) { + signal(SIGILL, SIG_DFL); + } else { + __lv_powerpc_canjump = 1; + + __asm __volatile + ("mtspr 256, %0\n\t" + "vand %%v0, %%v0, %%v0" + : + : "r" (-1)); + + signal(SIGILL, SIG_DFL); + __cpu_detect_caps.hasAltiVec = 1; + } +#endif +} +#endif + +/* If we're running on a processor that can do SSE, let's see if we + * are allowed to or not. This will catch 2.4.0 or later kernels that + * haven't been configured for a Pentium III but are running on one, + * and RedHat patched 2.2 kernels that have broken exception handling + * support for user space apps that do SSE. + */ +static void check_os_katmai_support(void) +{ +#if defined(ARCH_X86) +#if defined(OS_FREEBSD) + int has_sse=0, ret; + int len = sizeof (has_sse); + + ret = sysctlbyname("hw.instruction_sse", &has_sse, &len, NULL, 0); + if (ret || !has_sse) + __cpu_detect_caps.hasSSE=0; + +#elif defined(OS_NETBSD) || defined(OS_OPENBSD) + int has_sse, has_sse2, ret, mib[2]; + int varlen; + + mib[0] = CTL_MACHDEP; + mib[1] = CPU_SSE; + varlen = sizeof (has_sse); + + ret = sysctl(mib, 2, &has_sse, &varlen, NULL, 0); + if (ret < 0 || !has_sse) { + __cpu_detect_caps.hasSSE = 0; + } else { + __cpu_detect_caps.hasSSE = 1; + } + + mib[1] = CPU_SSE2; + varlen = sizeof (has_sse2); + ret = sysctl(mib, 2, &has_sse2, &varlen, NULL, 0); + if (ret < 0 || !has_sse2) { + __cpu_detect_caps.hasSSE2 = 0; + } else { + __cpu_detect_caps.hasSSE2 = 1; + } + __cpu_detect_caps.hasSSE = 0; /* FIXME ?!?!? */ + +#elif defined(OS_WIN32) + LPTOP_LEVEL_EXCEPTION_FILTER exc_fil; + if (__cpu_detect_caps.hasSSE) { + exc_fil = SetUnhandledExceptionFilter(win32_sig_handler_sse); + __asm __volatile ("xorps %xmm0, %xmm0"); + SetUnhandledExceptionFilter(exc_fil); + } +#elif defined(OS_LINUX) + struct sigaction saved_sigill; + struct sigaction saved_sigfpe; + + /* Save the original signal handlers. + */ + sigaction(SIGILL, NULL, &saved_sigill); + sigaction(SIGFPE, NULL, &saved_sigfpe); + + signal(SIGILL, (void (*)(int))sigill_handler_sse); + signal(SIGFPE, (void (*)(int))sigfpe_handler_sse); + + /* Emulate test for OSFXSR in CR4. The OS will set this bit if it + * supports the extended FPU save and restore required for SSE. If + * we execute an SSE instruction on a PIII and get a SIGILL, the OS + * doesn't support Streaming SIMD Exceptions, even if the processor + * does. + */ + if (__cpu_detect_caps.hasSSE) { + __asm __volatile ("xorps %xmm1, %xmm0"); + } + + /* Emulate test for OSXMMEXCPT in CR4. The OS will set this bit if + * it supports unmasked SIMD FPU exceptions. If we unmask the + * exceptions, do a SIMD divide-by-zero and get a SIGILL, the OS + * doesn't support unmasked SIMD FPU exceptions. If we get a SIGFPE + * as expected, we're okay but we need to clean up after it. + * + * Are we being too stringent in our requirement that the OS support + * unmasked exceptions? Certain RedHat 2.2 kernels enable SSE by + * setting CR4.OSFXSR but don't support unmasked exceptions. Win98 + * doesn't even support them. We at least know the user-space SSE + * support is good in kernels that do support unmasked exceptions, + * and therefore to be safe I'm going to leave this test in here. + */ + if (__cpu_detect_caps.hasSSE) { + // test_os_katmai_exception_support(); + } + + /* Restore the original signal handlers. + */ + sigaction(SIGILL, &saved_sigill, NULL); + sigaction(SIGFPE, &saved_sigfpe, NULL); + +#else + /* We can't use POSIX signal handling to test the availability of + * SSE, so we disable it by default. + */ + __cpu_detect_caps.hasSSE = 0; +#endif /* __linux__ */ +#endif +} + + +static int has_cpuid(void) +{ +#if defined(ARCH_X86) + int a, c; + + __asm __volatile + ("pushf\n" + "popl %0\n" + "movl %0, %1\n" + "xorl $0x200000, %0\n" + "push %0\n" + "popf\n" + "pushf\n" + "popl %0\n" + : "=a" (a), "=c" (c) + : + : "cc"); + + return a != c; +#else + return 0; +#endif +} + +static int cpuid(unsigned int ax, unsigned int *p) +{ +#if defined(ARCH_X86) + unsigned int flags; + + __asm __volatile + ("movl %%ebx, %%esi\n\t" + "cpuid\n\t" + "xchgl %%ebx, %%esi" + : "=a" (p[0]), "=S" (p[1]), + "=c" (p[2]), "=d" (p[3]) + : "0" (ax)); + + return 0; +#else + return -1; +#endif +} + +void cpu_detect_initialize() +{ + unsigned int regs[4]; + unsigned int regs2[4]; + + int mib[2], ncpu; + int len; + + memset(&__cpu_detect_caps, 0, sizeof (struct cpu_detect_caps)); + + /* Check for arch type */ +#if defined(ARCH_MIPS) + __cpu_detect_caps.type = CPU_DETECT_TYPE_MIPS; +#elif defined(ARCH_ALPHA) + __cpu_detect_caps.type = CPU_DETECT_TYPE_ALPHA; +#elif defined(ARCH_SPARC) + __cpu_detect_caps.type = CPU_DETECT_TYPE_SPARC; +#elif defined(ARCH_X86) + __cpu_detect_caps.type = CPU_DETECT_TYPE_X86; +#elif defined(ARCH_POWERPC) + __cpu_detect_caps.type = CPU_DETECT_TYPE_POWERPC; +#else + __cpu_detect_caps.type = CPU_DETECT_TYPE_OTHER; +#endif + + /* Count the number of CPUs in system */ +#if !defined(OS_WIN32) && !defined(OS_UNKNOWN) && defined(_SC_NPROCESSORS_ONLN) + __cpu_detect_caps.nrcpu = sysconf(_SC_NPROCESSORS_ONLN); + if (__cpu_detect_caps.nrcpu == -1) + __cpu_detect_caps.nrcpu = 1; + +#elif defined(OS_NETBSD) || defined(OS_FREEBSD) || defined(OS_OPENBSD) + + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + + len = sizeof (ncpu); + sysctl(mib, 2, &ncpu, &len, NULL, 0); + __cpu_detect_caps.nrcpu = ncpu; + +#else + __cpu_detect_caps.nrcpu = 1; +#endif + +#if defined(ARCH_X86) + /* No cpuid, old 486 or lower */ + if (has_cpuid() == 0) + return; + + __cpu_detect_caps.cacheline = 32; + + /* Get max cpuid level */ + cpuid(0x00000000, regs); + + if (regs[0] >= 0x00000001) { + unsigned int cacheline; + + cpuid (0x00000001, regs2); + + __cpu_detect_caps.x86cpuType = (regs2[0] >> 8) & 0xf; + if (__cpu_detect_caps.x86cpuType == 0xf) + __cpu_detect_caps.x86cpuType = 8 + ((regs2[0] >> 20) & 255); /* use extended family (P4, IA64) */ + + /* general feature flags */ + __cpu_detect_caps.hasTSC = (regs2[3] & (1 << 8 )) >> 8; /* 0x0000010 */ + __cpu_detect_caps.hasMMX = (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */ + __cpu_detect_caps.hasSSE = (regs2[3] & (1 << 25 )) >> 25; /* 0x2000000 */ + __cpu_detect_caps.hasSSE2 = (regs2[3] & (1 << 26 )) >> 26; /* 0x4000000 */ + __cpu_detect_caps.hasSSE3 = (regs2[2] & (1)); /* 0x0000001 */ + __cpu_detect_caps.hasSSSE3 = (regs2[2] & (1 << 9 )) >> 9; /* 0x0000020 */ + __cpu_detect_caps.hasMMX2 = __cpu_detect_caps.hasSSE; /* SSE cpus supports mmxext too */ + + cacheline = ((regs2[1] >> 8) & 0xFF) * 8; + if (cacheline > 0) + __cpu_detect_caps.cacheline = cacheline; + } + + cpuid(0x80000000, regs); + + if (regs[0] >= 0x80000001) { + + cpuid(0x80000001, regs2); + + __cpu_detect_caps.hasMMX |= (regs2[3] & (1 << 23 )) >> 23; /* 0x0800000 */ + __cpu_detect_caps.hasMMX2 |= (regs2[3] & (1 << 22 )) >> 22; /* 0x400000 */ + __cpu_detect_caps.has3DNow = (regs2[3] & (1 << 31 )) >> 31; /* 0x80000000 */ + __cpu_detect_caps.has3DNowExt = (regs2[3] & (1 << 30 )) >> 30; + } + + if (regs[0] >= 0x80000006) { + cpuid(0x80000006, regs2); + __cpu_detect_caps.cacheline = regs2[2] & 0xFF; + } + + +#if defined(OS_LINUX) || defined(OS_FREEBSD) || defined(OS_NETBSD) || defined(OS_CYGWIN) || defined(OS_OPENBSD) + if (__cpu_detect_caps.hasSSE) + check_os_katmai_support(); + + if (!__cpu_detect_caps.hasSSE) { + __cpu_detect_caps.hasSSE2 = 0; + __cpu_detect_caps.hasSSE3 = 0; + __cpu_detect_caps.hasSSSE3 = 0; + } +#else + __cpu_detect_caps.hasSSE = 0; + __cpu_detect_caps.hasSSE2 = 0; + __cpu_detect_caps.hasSSE3 = 0; + __cpu_detect_caps.hasSSSE3 = 0; +#endif +#endif /* ARCH_X86 */ + +#if defined(ARCH_POWERPC) + check_os_altivec_support(); +#endif /* ARCH_POWERPC */ + + __cpu_detect_initialized = 1; +} + +struct cpu_detect_caps *cpu_detect_get_caps() +{ + return &__cpu_detect_caps; +} + +/* The getters and setters for feature flags */ +int cpu_detect_get_tsc() +{ + return __cpu_detect_caps.hasTSC; +} + +int cpu_detect_get_mmx() +{ + return __cpu_detect_caps.hasMMX; +} + +int cpu_detect_get_mmx2() +{ + return __cpu_detect_caps.hasMMX2; +} + +int cpu_detect_get_sse() +{ + return __cpu_detect_caps.hasSSE; +} + +int cpu_detect_get_sse2() +{ + return __cpu_detect_caps.hasSSE2; +} + +int cpu_detect_get_sse3() +{ + return __cpu_detect_caps.hasSSE3; +} + +int cpu_detect_get_ssse3() +{ + return __cpu_detect_caps.hasSSSE3; +} + +int cpu_detect_get_3dnow() +{ + return __cpu_detect_caps.has3DNow; +} + +int cpu_detect_get_3dnow2() +{ + return __cpu_detect_caps.has3DNowExt; +} + +int cpu_detect_get_altivec() +{ + return __cpu_detect_caps.hasAltiVec; +} + diff --git a/src/gallium/auxiliary/util/u_cpu_detect.h b/src/gallium/auxiliary/util/u_cpu_detect.h new file mode 100644 index 0000000000..1612d49286 --- /dev/null +++ b/src/gallium/auxiliary/util/u_cpu_detect.h @@ -0,0 +1,78 @@ +/************************************************************************** + * + * Copyright 2008 Dennis Smit + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + ***************************************************************************/ + +/* + * Based on the work of Eric Anholt + */ + +#ifndef _CPU_DETECT_H +#define _CPU_DETECT_H + +typedef enum { + CPU_DETECT_TYPE_MIPS, + CPU_DETECT_TYPE_ALPHA, + CPU_DETECT_TYPE_SPARC, + CPU_DETECT_TYPE_X86, + CPU_DETECT_TYPE_POWERPC, + CPU_DETECT_TYPE_OTHER +} cpu_detect_type; + +struct cpu_detect_caps { + cpu_detect_type type; + int nrcpu; + + /* Feature flags */ + int x86cpuType; + int cacheline; + + int hasTSC; + int hasMMX; + int hasMMX2; + int hasSSE; + int hasSSE2; + int hasSSE3; + int hasSSSE3; + int has3DNow; + int has3DNowExt; + int hasAltiVec; +}; + +/* prototypes */ +void cpu_detect_initialize(void); +struct cpu_detect_caps *cpu_detect_get_caps(void); + +int cpu_detect_get_tsc(void); +int cpu_detect_get_mmx(void); +int cpu_detect_get_mmx2(void); +int cpu_detect_get_sse(void); +int cpu_detect_get_sse2(void); +int cpu_detect_get_sse3(void); +int cpu_detect_get_ssse3(void); +int cpu_detect_get_3dnow(void); +int cpu_detect_get_3dnow2(void); +int cpu_detect_get_altivec(void); + +#endif /* _CPU_DETECT_H */ -- cgit v1.2.3 From 34497eabc803fd979c58824d4737cabde1fb47e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 10 Mar 2008 21:15:31 +0000 Subject: Some notes about debugging --- src/gallium/README.portability | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/README.portability b/src/gallium/README.portability index c70ca774da..ab0c197847 100644 --- a/src/gallium/README.portability +++ b/src/gallium/README.portability @@ -39,5 +39,6 @@ portable way. == Debugging == -TODO +* Use the functions/macros in p_debug.h. +* Don't include assert.h, call abort, printf, etc. -- cgit v1.2.3 From 31022681543932ae4fce2bae5bc9d024c8178f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 10 Mar 2008 21:18:00 +0000 Subject: gallium: Use hardcoded breakpoints on x86 targets. --- src/gallium/auxiliary/util/p_debug.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 6255d716a6..93bfaea393 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -81,14 +81,17 @@ void debug_printf(const char *format, ...) } -static INLINE void debug_abort(void) +/* TODO: implement a debug_abort that calls EngBugCheckEx on WIN32 */ + + +static INLINE void debug_break(void) { -#ifdef WIN32 -#ifndef WINCE - EngDebugBreak(); -#else +#if (defined(__i386__) || defined(__386__)) && defined(__GNUC__) + __asm("int3"); +#elif (defined(__i386__) || defined(__386__)) && defined(__MSC__) _asm {int 3}; -#endif +#elif defined(WIN32) && !defined(WINCE) + EngDebugBreak(); #else abort(); #endif @@ -98,5 +101,5 @@ static INLINE void debug_abort(void) void debug_assert_fail(const char *expr, const char *file, unsigned line) { debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr); - debug_abort(); + debug_break(); } -- cgit v1.2.3 From 5b82d551b7a4954b24059585fea207f3a250ec0f Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 10 Mar 2008 16:43:36 -0600 Subject: cell: sync up with sampler/texture state-setting changes --- src/gallium/drivers/cell/ppu/cell_context.h | 2 ++ src/gallium/drivers/cell/ppu/cell_pipe_state.c | 32 ++++++++++++++++++-------- src/gallium/drivers/cell/ppu/cell_state_emit.c | 6 +++-- 3 files changed, 28 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index bf27289f3f..c568922cbd 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -63,6 +63,7 @@ struct cell_context const struct pipe_blend_state *blend; const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + uint num_samplers; const struct pipe_depth_stencil_alpha_state *depth_stencil; const struct pipe_rasterizer_state *rasterizer; const struct cell_vertex_shader_state *vs; @@ -75,6 +76,7 @@ struct cell_context struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct cell_texture *texture[PIPE_MAX_SAMPLERS]; + uint num_textures; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 075e0a0c47..025ed3bbbf 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -210,15 +210,19 @@ cell_create_sampler_state(struct pipe_context *pipe, static void -cell_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) +cell_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **samplers) { struct cell_context *cell = cell_context(pipe); draw_flush(cell->draw); assert(unit < PIPE_MAX_SAMPLERS); - cell->sampler[unit] = (struct pipe_sampler_state *)sampler; + + memcpy(cell->sampler, samplers, num * sizeof(void *)); + memset(&cell->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) * + sizeof(void *)); + cell->num_samplers = num; cell->dirty |= CELL_NEW_SAMPLER; } @@ -234,16 +238,24 @@ cell_delete_sampler_state(struct pipe_context *pipe, static void -cell_set_sampler_texture(struct pipe_context *pipe, - unsigned sampler, - struct pipe_texture *texture) +cell_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) { struct cell_context *cell = cell_context(pipe); + uint i; + + /* Check for no-op */ + if (num == cell->num_textures && + !memcmp(cell->texture, texture, num * sizeof(struct pipe_texture *))) + return; draw_flush(cell->draw); - pipe_texture_reference((struct pipe_texture **) &cell->texture[sampler], - texture); + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + struct pipe_texture *tex = i < num ? texture[i] : NULL; + + pipe_texture_reference((struct pipe_texture **) &cell->texture[i], tex); + } cell_update_texture_mapping(cell); @@ -300,10 +312,10 @@ cell_init_state_functions(struct cell_context *cell) cell->pipe.delete_blend_state = cell_delete_blend_state; cell->pipe.create_sampler_state = cell_create_sampler_state; - cell->pipe.bind_sampler_state = cell_bind_sampler_state; + cell->pipe.bind_sampler_states = cell_bind_sampler_states; cell->pipe.delete_sampler_state = cell_delete_sampler_state; - cell->pipe.set_sampler_texture = cell_set_sampler_texture; + cell->pipe.set_sampler_textures = cell_set_sampler_textures; cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state; cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state; diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 49c0d130c5..670eb26bdd 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -77,8 +77,10 @@ cell_emit_state(struct cell_context *cell) } if (cell->dirty & CELL_NEW_SAMPLER) { - emit_state_cmd(cell, CELL_CMD_STATE_SAMPLER, - cell->sampler[0], sizeof(struct pipe_sampler_state)); + if (cell->sampler[0]) { + emit_state_cmd(cell, CELL_CMD_STATE_SAMPLER, + cell->sampler[0], sizeof(struct pipe_sampler_state)); + } } if (cell->dirty & CELL_NEW_TEXTURE) { -- cgit v1.2.3 From d5692cb349fb74e8f9d3a18f5bbd788b09b93581 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 10 Mar 2008 17:21:43 -0600 Subject: gallium: new surface/context tracker (sct) module Will be used for tracking the surfaces and textures which are bound/used by contexts. --- src/gallium/auxiliary/sct/Makefile | 12 + src/gallium/auxiliary/sct/SConscript | 9 + src/gallium/auxiliary/sct/sct.c | 453 +++++++++++++++++++++++++++++++++++ src/gallium/auxiliary/sct/sct.h | 123 ++++++++++ src/gallium/auxiliary/sct/usage.c | 61 +++++ 5 files changed, 658 insertions(+) create mode 100644 src/gallium/auxiliary/sct/Makefile create mode 100644 src/gallium/auxiliary/sct/SConscript create mode 100644 src/gallium/auxiliary/sct/sct.c create mode 100644 src/gallium/auxiliary/sct/sct.h create mode 100644 src/gallium/auxiliary/sct/usage.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/sct/Makefile b/src/gallium/auxiliary/sct/Makefile new file mode 100644 index 0000000000..516d1756cf --- /dev/null +++ b/src/gallium/auxiliary/sct/Makefile @@ -0,0 +1,12 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = sct + +C_SOURCES = \ + sct.c + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/auxiliary/sct/SConscript b/src/gallium/auxiliary/sct/SConscript new file mode 100644 index 0000000000..76927d973f --- /dev/null +++ b/src/gallium/auxiliary/sct/SConscript @@ -0,0 +1,9 @@ +Import('*') + +sct = env.ConvenienceLibrary( + target = 'sct', + source = [ + 'sct.c' + ]) + +auxiliaries.insert(0, sct) diff --git a/src/gallium/auxiliary/sct/sct.c b/src/gallium/auxiliary/sct/sct.c new file mode 100644 index 0000000000..97ee5882a1 --- /dev/null +++ b/src/gallium/auxiliary/sct/sct.c @@ -0,0 +1,453 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_util.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" +#include "sct.h" + + +struct texture_list +{ + struct pipe_texture *texture; + struct texture_list *next; +}; + + + +#define MAX_SURFACES ((PIPE_MAX_COLOR_BUFS) + 1) + +struct sct_context +{ + const struct pipe_context *context; + + /** surfaces the context is drawing into */ + struct pipe_surface *surfaces[MAX_SURFACES]; + + /** currently bound textures */ + struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; + + /** previously bound textures, used but not flushed */ + struct texture_list *textures_used; + + boolean needs_flush; + + struct sct_context *next; +}; + + + +struct sct_surface +{ + const struct pipe_surface *surface; + + /** list of contexts drawing to this surface */ + struct sct_context_list *contexts; + + struct sct_surface *next; +}; + + + +/** + * Find the surface_info for the given pipe_surface + */ +static struct sct_surface * +find_surface_info(struct surface_context_tracker *sct, + const struct pipe_surface *surface) +{ + struct sct_surface *si; + for (si = sct->surfaces; si; si = si->next) + if (si->surface == surface) + return si; + return NULL; +} + + +/** + * As above, but create new surface_info if surface is new. + */ +static struct sct_surface * +find_create_surface_info(struct surface_context_tracker *sct, + const struct pipe_surface *surface) +{ + struct sct_surface *si = find_surface_info(sct, surface); + if (si) + return si; + + /* alloc new */ + si = CALLOC_STRUCT(sct_surface); + if (si) { + si->surface = surface; + + /* insert at head */ + si->next = sct->surfaces; + sct->surfaces = si; + } + + return si; +} + + +/** + * Find a context_info for the given context. + */ +static struct sct_context * +find_context_info(struct surface_context_tracker *sct, + const struct pipe_context *context) +{ + struct sct_context *ci; + for (ci = sct->contexts; ci; ci = ci->next) + if (ci->context == context) + return ci; + return NULL; +} + + +/** + * As above, but create new context_info if context is new. + */ +static struct sct_context * +find_create_context_info(struct surface_context_tracker *sct, + const struct pipe_context *context) +{ + struct sct_context *ci = find_context_info(sct, context); + if (ci) + return ci; + + /* alloc new */ + ci = CALLOC_STRUCT(sct_context); + if (ci) { + ci->context = context; + + /* insert at head */ + ci->next = sct->contexts; + sct->contexts = ci; + } + + return ci; +} + + +/** + * Is the context already bound to the surface? + */ +static boolean +find_surface_context(const struct sct_surface *si, + const struct pipe_context *context) +{ + const struct sct_context_list *cl; + for (cl = si->contexts; cl; cl = cl->next) { + if (cl->context == context) { + return TRUE; + } + } + return FALSE; +} + + +/** + * Add a context to the list of contexts associated with a surface. + */ +static void +add_context_to_surface(struct sct_surface *si, + const struct pipe_context *context) +{ + struct sct_context_list *cl = CALLOC_STRUCT(sct_context_list); + if (cl) { + cl->context = context; + /* insert at head of list of contexts */ + cl->next = si->contexts; + si->contexts = cl; + } +} + + +/** + * Remove a context from the list of contexts associated with a surface. + */ +static void +remove_context_from_surface(struct sct_surface *si, + const struct pipe_context *context) +{ + struct sct_context_list *prev = NULL, *curr, *next; + + for (curr = si->contexts; curr; curr = next) { + if (curr->context == context) { + /* remove */ + if (prev) + prev->next = curr->next; + else + si->contexts = curr->next; + next = curr->next; + FREE(curr); + } + else { + prev = curr; + } + } +} + + +/** + * Unbind context from surface. + */ +static void +unbind_context_surface(struct surface_context_tracker *sct, + struct pipe_context *context, + struct pipe_surface *surface) +{ + struct sct_surface *si = find_surface_info(sct, surface); + if (si) { + remove_context_from_surface(si, context); + } +} + + +/** + * Bind context to a set of surfaces (color + Z). + * Like MakeCurrent(). + */ +void +sct_bind_surfaces(struct surface_context_tracker *sct, + struct pipe_context *context, + uint num_surf, + struct pipe_surface **surfaces) +{ + struct sct_context *ci = find_create_context_info(sct, context); + uint i; + + if (!ci) { + return; /* out of memory */ + } + + /* unbind currently bound surfaces */ + for (i = 0; i < MAX_SURFACES; i++) { + if (ci->surfaces[i]) { + unbind_context_surface(sct, context, ci->surfaces[i]); + } + } + + /* bind new surfaces */ + for (i = 0; i < num_surf; i++) { + struct sct_surface *si = find_create_surface_info(sct, surfaces[i]); + if (!find_surface_context(si, context)) { + add_context_to_surface(si, context); + } + } +} + + +/** + * Return list of contexts bound to a surface. + */ +const struct sct_context_list * +sct_get_surface_contexts(struct surface_context_tracker *sct, + const struct pipe_surface *surface) +{ + const struct sct_surface *si = find_surface_info(sct, surface); + return si->contexts; +} + + + +static boolean +find_texture(const struct sct_context *ci, + const struct pipe_texture *texture) +{ + const struct texture_list *tl; + + for (tl = ci->textures_used; tl; tl = tl->next) { + if (tl->texture == texture) { + return TRUE; + } + } + return FALSE; +} + + +/** + * Add the given texture to the context's list of used textures. + */ +static void +add_texture_used(struct sct_context *ci, + struct pipe_texture *texture) +{ + if (!find_texture(ci, texture)) { + /* add to list */ + struct texture_list *tl = CALLOC_STRUCT(texture_list); + if (tl) { + pipe_texture_reference(&tl->texture, texture); + /* insert at head */ + tl->next = ci->textures_used; + ci->textures_used = tl; + } + } +} + + +/** + * Bind a texture to a rendering context. + */ +void +sct_bind_texture(struct surface_context_tracker *sct, + struct pipe_context *context, + uint unit, + struct pipe_texture *tex) +{ + struct sct_context *ci = find_context_info(sct, context); + + if (ci->textures[unit] != tex) { + /* put texture on the 'used' list */ + add_texture_used(ci, tex); + /* bind new */ + pipe_texture_reference(&ci->textures[unit], tex); + } +} + + +/** + * Check if the given texture has been used by the rendering context + * since the last call to sct_flush_textures(). + */ +boolean +sct_is_texture_used(struct surface_context_tracker *sct, + const struct pipe_context *context, + const struct pipe_texture *texture) +{ + const struct sct_context *ci = find_context_info(sct, context); + return find_texture(ci, texture); +} + + +/** + * To be called when the image contents of a texture are changed, such + * as for gl[Copy]TexSubImage(). + * XXX this may not be needed + */ +void +sct_update_texture(struct pipe_texture *tex) +{ + +} + + +/** + * When a scene is flushed/rendered we can release the list of + * used textures. + */ +void +sct_flush_textures(struct surface_context_tracker *sct, + struct pipe_context *context) +{ + struct sct_context *ci = find_context_info(sct, context); + struct texture_list *tl, *next; + uint i; + + for (tl = ci->textures_used; tl; tl = next) { + next = tl->next; + pipe_texture_release(&tl->texture); + FREE(tl); + } + ci->textures_used = NULL; + + /* put the currently bound textures on the 'used' list */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + add_texture_used(ci, ci->textures[i]); + } +} + + + +void +sct_destroy_context(struct surface_context_tracker *sct, + struct pipe_context *context) +{ + /* XXX should we require an unbinding first? */ + { + struct sct_surface *si; + for (si = sct->surfaces; si; si = si->next) { + remove_context_from_surface(si, context); + } + } + + /* remove context from context_info list */ + { + struct sct_context *ci, *next, *prev = NULL; + for (ci = sct->contexts; ci; ci = next) { + next = ci->next; + if (ci->context == context) { + if (prev) + prev->next = ci->next; + else + sct->contexts = ci->next; + FREE(ci); + } + else { + prev = ci; + } + } + } + +} + + +void +sct_destroy_surface(struct surface_context_tracker *sct, + struct pipe_surface *surface) +{ + if (1) { + /* debug/sanity: no context should be bound to surface */ + struct sct_context *ci; + uint i; + for (ci = sct->contexts; ci; ci = ci->next) { + for (i = 0; i < MAX_SURFACES; i++) { + assert(ci->surfaces[i] != surface); + } + } + } + + /* remove surface from sct_surface list */ + { + struct sct_surface *si, *next, *prev = NULL; + for (si = sct->surfaces; si; si = next) { + next = si->next; + if (si->surface == surface) { + /* unlink */ + if (prev) + prev->next = si->next; + else + sct->surfaces = si->next; + FREE(si); + } + else { + prev = si; + } + } + } +} diff --git a/src/gallium/auxiliary/sct/sct.h b/src/gallium/auxiliary/sct/sct.h new file mode 100644 index 0000000000..cf7c4d3bdf --- /dev/null +++ b/src/gallium/auxiliary/sct/sct.h @@ -0,0 +1,123 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Surface/Context Tracking + * + * For some drivers, we need to monitor the binding between contexts and + * surfaces/textures. + * This code may evolve quite a bit... + */ + + +#ifndef SCT_H +#define SCT_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct pipe_context; +struct pipe_surface; + +struct sct_context; +struct sct_surface; + + +/** + * Per-device info, basically + */ +struct surface_context_tracker +{ + struct sct_context *contexts; + struct sct_surface *surfaces; +}; + + + +/** + * Simple linked list of contexts + */ +struct sct_context_list +{ + const struct pipe_context *context; + struct sct_context_list *next; +}; + + + +extern void +sct_bind_surfaces(struct surface_context_tracker *sct, + struct pipe_context *context, + uint num_surf, + struct pipe_surface **surfaces); + + +extern void +sct_bind_texture(struct surface_context_tracker *sct, + struct pipe_context *context, + uint unit, + struct pipe_texture *texture); + + +extern void +sct_update_texture(struct pipe_texture *tex); + + +extern boolean +sct_is_texture_used(struct surface_context_tracker *sct, + const struct pipe_context *context, + const struct pipe_texture *texture); + +extern void +sct_flush_textures(struct surface_context_tracker *sct, + struct pipe_context *context); + + +extern const struct sct_context_list * +sct_get_surface_contexts(struct surface_context_tracker *sct, + const struct pipe_surface *surf); + + +extern void +sct_destroy_context(struct surface_context_tracker *sct, + struct pipe_context *context); + + +extern void +sct_destroy_surface(struct surface_context_tracker *sct, + struct pipe_surface *surface); + + + +#ifdef __cplusplus +} +#endif + +#endif /* SCT_H */ diff --git a/src/gallium/auxiliary/sct/usage.c b/src/gallium/auxiliary/sct/usage.c new file mode 100644 index 0000000000..6227f19962 --- /dev/null +++ b/src/gallium/auxiliary/sct/usage.c @@ -0,0 +1,61 @@ +/* surface / context tracking */ + + +/* + +context A: + render to texture T + +context B: + texture from T + +----------------------- + +flush surface: + which contexts are bound to the surface? + +----------------------- + +glTexSubImage(): + which contexts need to be flushed? + + */ + + +/* + +in MakeCurrent(): + + call sct_bind_surfaces(context, list of surfaces) to update the + dependencies between context and surfaces + + +in SurfaceFlush(), or whatever it is in D3D: + + call sct_get_surface_contexts(surface) to get a list of contexts + which are currently bound to the surface. + + + +in BindTexture(): + + call sct_bind_texture(context, texture) to indicate that the texture + is used in the scene. + + +in glTexSubImage() or RenderToTexture(): + + call sct_is_texture_used(context, texture) to determine if the texture + has been used in the scene, but the scene's not flushed. If TRUE is + returned it means the scene has to be rendered/flushed before the contents + of the texture can be changed. + + +in psb_scene_flush/terminate(): + + call sct_flush_textures(context) to tell the SCT that the textures which + were used in the scene can be released. + + + +*/ -- cgit v1.2.3 From 6d5ee6d9a4a705cce80117f90ee334986f5e5e26 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 10 Mar 2008 19:37:32 +0000 Subject: gallium: enable bug workaround in draw_vertex_cache_invalidate --- src/gallium/auxiliary/draw/draw_vertex_cache.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c index 53f8bbec44..161b247d4e 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_cache.c +++ b/src/gallium/auxiliary/draw/draw_vertex_cache.c @@ -41,7 +41,11 @@ void draw_vertex_cache_invalidate( struct draw_context *draw ) assert(draw->vs.queue_nr == 0); assert(draw->vcache.referenced == 0); -// memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx)); + /* There's an error somewhere in the vcache code that requires this + * memset. The bug is exposed in q3demo demo001, but probably + * elsewhere as well. Will track it down later. + */ + memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx)); } -- cgit v1.2.3 From 3f5b9f4ba49df57e7bbab04eab55a17a99bb5046 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 10 Mar 2008 19:41:12 +0000 Subject: gallium: use the same bypass_clipping logic on all vs paths --- src/gallium/auxiliary/draw/draw_vs_llvm.c | 48 +++++++++++++++++++------------ src/gallium/auxiliary/draw/draw_vs_sse.c | 38 +++++++++++++++--------- 2 files changed, 53 insertions(+), 33 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 0fd557d667..53c260be53 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -135,25 +135,35 @@ vs_llvm_run( struct draw_vertex_shader *base, unsigned slot; float x, y, z, w; - x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; - - vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); - vOut[j]->edgeflag = 1; - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - - /* Viewport mapping */ - vOut[j]->data[0][0] = x * scale[0] + trans[0]; - vOut[j]->data[0][1] = y * scale[1] + trans[1]; - vOut[j]->data[0][2] = z * scale[2] + trans[2]; - vOut[j]->data[0][3] = w; + if (!draw->rasterizer->bypass_clipping) { + x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + + vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + vOut[j]->edgeflag = 1; + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; + + /* Viewport mapping */ + vOut[j]->data[0][0] = x * scale[0] + trans[0]; + vOut[j]->data[0][1] = y * scale[1] + trans[1]; + vOut[j]->data[0][2] = z * scale[2] + trans[2]; + vOut[j]->data[0][3] = w; + } + else { + vOut[j]->clipmask = 0; + vOut[j]->edgeflag = 1; + vOut[j]->data[0][0] = x; + vOut[j]->data[0][1] = y; + vOut[j]->data[0][2] = z; + vOut[j]->data[0][3] = w; + } /* Remaining attributes are packed into sequential post-transform * vertex attrib slots. diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 0b8bc2bf14..e5c1a40cca 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -158,20 +158,30 @@ vs_sse_run( struct draw_vertex_shader *base, z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; - vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); - vOut[j]->edgeflag = 1; - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - - /* Viewport mapping */ - vOut[j]->data[0][0] = x * scale[0] + trans[0]; - vOut[j]->data[0][1] = y * scale[1] + trans[1]; - vOut[j]->data[0][2] = z * scale[2] + trans[2]; - vOut[j]->data[0][3] = w; + if (!draw->rasterizer->bypass_clipping) { + vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + vOut[j]->edgeflag = 1; + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; + + /* Viewport mapping */ + vOut[j]->data[0][0] = x * scale[0] + trans[0]; + vOut[j]->data[0][1] = y * scale[1] + trans[1]; + vOut[j]->data[0][2] = z * scale[2] + trans[2]; + vOut[j]->data[0][3] = w; + } + else { + vOut[j]->clipmask = 0; + vOut[j]->edgeflag = 1; + vOut[j]->data[0][0] = x; + vOut[j]->data[0][1] = y; + vOut[j]->data[0][2] = z; + vOut[j]->data[0][3] = w; + } /* Remaining attributes are packed into sequential post-transform * vertex attrib slots. -- cgit v1.2.3 From 7375369fb32e203023fbacf948169aad3f4c3a1d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 10 Mar 2008 19:41:51 +0000 Subject: gallium: fix compiler warning --- src/gallium/auxiliary/draw/draw_pstipple.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index 894b136f2c..b3e52dc1c7 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -482,11 +482,10 @@ static void pstip_first_tri(struct draw_stage *stage, struct prim_header *header) { struct pstip_stage *pstip = pstip_stage(stage); - struct draw_context *draw = stage->draw; struct pipe_context *pipe = pstip->pipe; uint num = MAX2(pstip->num_textures, pstip->num_samplers); - assert(draw->rasterizer->poly_stipple_enable); + assert(stage->draw->rasterizer->poly_stipple_enable); /* * Bind our fragprog, sampler and texture -- cgit v1.2.3 From 297b3be25a7f097fb9b1a79e332acddc12dcc3fe Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 10 Mar 2008 19:49:15 +0000 Subject: draw: placeholder/prototype code for a passthrough draw path --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/SConscript | 1 + src/gallium/auxiliary/draw/draw_context.c | 12 ++++++++++++ src/gallium/auxiliary/draw/draw_context.h | 5 +++++ src/gallium/auxiliary/draw/draw_private.h | 27 +++++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vbuf.h | 6 ++++++ 6 files changed, 52 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 2daa1636f3..ce6667d8ec 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -4,6 +4,7 @@ include $(TOP)/configs/current LIBNAME = draw C_SOURCES = \ + draw_passthrough.c \ draw_aaline.c \ draw_aapoint.c \ draw_clip.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index c18dcb2927..5cb7664c85 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -16,6 +16,7 @@ draw = env.ConvenienceLibrary( 'draw_offset.c', 'draw_prim.c', 'draw_pstipple.c', + 'draw_passthrough.c', 'draw_stipple.c', 'draw_twoside.c', 'draw_unfilled.c', diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 428b6209e0..bb64b50a17 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -34,6 +34,7 @@ #include "pipe/p_util.h" #include "draw_context.h" #include "draw_private.h" +#include "draw_vbuf.h" @@ -114,6 +115,10 @@ void draw_destroy( struct draw_context *draw ) draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); tgsi_exec_machine_free_data(&draw->machine); align_free( draw->vs.queue[0].vertex ); /* Frees all the vertices. */ + + if (draw->render) + draw->render->destroy( draw->render ); + FREE( draw ); } @@ -349,3 +354,10 @@ void draw_reset_vertex_ids(struct draw_context *draw) draw_vertex_cache_reset_vertex_ids(draw); } + + +void draw_set_render( struct draw_context *draw, + struct vbuf_render *render ) +{ + draw->render = render; +} diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index ab87b4127c..df63e91a22 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -168,4 +168,9 @@ unsigned draw_trim_prim( unsigned mode, unsigned count ); + +struct vbuf_render; +void draw_set_render( struct draw_context *draw, + struct vbuf_render *render ); + #endif /* DRAW_CONTEXT_H */ diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index c732d723a7..25fa8c09c2 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -162,8 +162,14 @@ typedef void (*full_fetch_func)( struct draw_context *draw, const unsigned *elts, unsigned count ); +typedef void (*pt_fetch_func)( struct draw_context *draw, + float *out, + unsigned start, + unsigned count ); +struct vbuf_render; + /** * Private context for the drawing module. */ @@ -191,6 +197,17 @@ struct draw_context struct draw_stage *rasterize; } pipeline; + + struct vbuf_render *render; + + /* Support prototype passthrough path: + */ + struct { + unsigned prim; + unsigned hw_vertex_size; + } pt; + + /* pipe state that we need: */ const struct pipe_rasterizer_state *rasterizer; struct pipe_viewport_state viewport; @@ -244,6 +261,7 @@ struct draw_context fetch_func fetch[PIPE_ATTRIB_MAX]; unsigned nr_attrs; full_fetch_func fetch_func; + pt_fetch_func pt_fetch; } vertex_fetch; /* Post-tnl vertex cache: @@ -331,6 +349,15 @@ struct tgsi_exec_machine; extern void draw_update_vertex_fetch( struct draw_context *draw ); +/* Prototype/hack + */ +boolean +draw_passthrough_arrays(struct draw_context *draw, + unsigned prim, + unsigned start, + unsigned count); + + #define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ #define DRAW_FLUSH_PRIM_QUEUE 0x2 #define DRAW_FLUSH_VERTEX_CACHE 0x4 diff --git a/src/gallium/auxiliary/draw/draw_vbuf.h b/src/gallium/auxiliary/draw/draw_vbuf.h index cfd2b9820c..5e7de905c1 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.h +++ b/src/gallium/auxiliary/draw/draw_vbuf.h @@ -85,6 +85,12 @@ struct vbuf_render { const ushort *indices, uint nr_indices ); + /* Draw Arrays path too. + */ + void (*draw_arrays)( struct vbuf_render *, + unsigned start, + uint nr ); + /** * Called when vbuf is done with this set of vertices: */ -- cgit v1.2.3 From b1525662b330ca8b4cdd930775f3642bfec3b58f Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 10 Mar 2008 16:28:54 -0700 Subject: Move SPE register allocator to rtasm code Move the register allocator to a common location. There is more code on the way that will make use of this interface. --- src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c | 47 +++++++++++ src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h | 16 ++++ src/gallium/drivers/cell/ppu/cell_vertex_fetch.c | 101 +++++++---------------- 3 files changed, 92 insertions(+), 72 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c index 95a2d6fcbb..a996218ce7 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c @@ -306,6 +306,11 @@ void spe_init_func(struct spe_function *p, unsigned code_size) { p->store = align_malloc(code_size, 16); p->csr = p->store; + + /* Conservatively treat R0 - R2 and R80 - R127 as non-volatile. + */ + p->regs[0] = ~7; + p->regs[1] = (1U << (80 - 64)) - 1; } @@ -317,6 +322,48 @@ void spe_release_func(struct spe_function *p) } +int spe_allocate_available_register(struct spe_function *p) +{ + unsigned i; + for (i = 0; i < 128; i++) { + const uint64_t mask = (1ULL << (i % 128)); + const unsigned idx = i / 128; + + if ((p->regs[idx] & mask) != 0) { + p->regs[idx] &= ~mask; + return i; + } + } + + return -1; +} + + +int spe_allocate_register(struct spe_function *p, int reg) +{ + const unsigned idx = reg / 128; + const unsigned bit = reg % 128; + + assert((p->regs[idx] & (1ULL << bit)) != 0); + + p->regs[idx] &= ~(1ULL << bit); + return reg; +} + + +void spe_release_register(struct spe_function *p, int reg) +{ + const unsigned idx = reg / 128; + const unsigned bit = reg % 128; + + assert((p->regs[idx] & (1ULL << bit)) == 0); + + p->regs[idx] |= (1ULL << bit); +} + + + + void spe_bi(struct spe_function *p, unsigned rA, int d, int e) { emit_RI7(p, 0x1a8, 0, rA, (d << 5) | (e << 4)); diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h index 10ce44b3a0..5a1eb1ed8d 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h @@ -39,11 +39,27 @@ struct spe_function { uint32_t *store; uint32_t *csr; const char *fn; + + /** + * Mask of used / unused registers + * + * Each set bit corresponds to an available register. Each cleared bit + * corresponds to an allocated register. + * + * \sa + * spe_allocate_register, spe_allocate_available_register, + * spe_release_register + */ + uint64_t regs[2]; }; extern void spe_init_func(struct spe_function *p, unsigned code_size); extern void spe_release_func(struct spe_function *p); +extern int spe_allocate_available_register(struct spe_function *p); +extern int spe_allocate_register(struct spe_function *p, int reg); +extern void spe_release_register(struct spe_function *p, int reg); + #endif /* RTASM_PPC_SPE_H */ #ifndef EMIT_ diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c index 9cf74bab47..4828a8023b 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c @@ -33,46 +33,11 @@ #include "cell_context.h" #include "rtasm/rtasm_ppc_spe.h" -typedef uint64_t register_mask; - -int allocate_available_register(register_mask *m) -{ - unsigned i; - for (i = 0; i < 64; i++) { - const uint64_t mask = (1ULL << i); - - if ((m[0] & mask) != 0) { - m[0] &= ~mask; - return i; - } - } - - return -1; -} - - -int allocate_register(register_mask *m, unsigned reg) -{ - assert((m[0] & (1ULL << reg)) != 0); - - m[0] &= ~(1ULL << reg); - return reg; -} - - -void release_register(register_mask *m, unsigned reg) -{ - assert((m[0] & (1ULL << reg)) == 0); - - m[0] |= (1ULL << reg); -} - /** * Emit a 4x4 matrix transpose operation * * \param p Function that the transpose operation is to be appended to - * \param m Live register mask * \param row0 Register containing row 0 of the source matrix * \param row1 Register containing row 1 of the source matrix * \param row2 Register containing row 2 of the source matrix @@ -91,15 +56,15 @@ void release_register(register_mask *m, unsigned reg) * This function requires that four temporary are available on entry. */ static void -emit_matrix_transpose(struct spe_function *p, register_mask *m, +emit_matrix_transpose(struct spe_function *p, unsigned row0, unsigned row1, unsigned row2, unsigned row3, unsigned dest_ptr, unsigned shuf_ptr, unsigned count) { - int shuf_hi = allocate_available_register(m); - int shuf_lo = allocate_available_register(m); - int t1 = allocate_available_register(m); - int t2 = allocate_available_register(m); + int shuf_hi = spe_allocate_available_register(p); + int shuf_lo = spe_allocate_available_register(p); + int t1 = spe_allocate_available_register(p); + int t2 = spe_allocate_available_register(p); int t3; int t4; int col0; @@ -169,19 +134,19 @@ emit_matrix_transpose(struct spe_function *p, register_mask *m, /* Release all of the temporary registers used. */ - release_register(m, col0); - release_register(m, col1); - release_register(m, col2); - release_register(m, col3); - release_register(m, shuf_hi); - release_register(m, shuf_lo); - release_register(m, t2); - release_register(m, t4); + spe_release_register(p, col0); + spe_release_register(p, col1); + spe_release_register(p, col2); + spe_release_register(p, col3); + spe_release_register(p, shuf_hi); + spe_release_register(p, shuf_lo); + spe_release_register(p, t2); + spe_release_register(p, t4); } static void -emit_fetch(struct spe_function *p, register_mask *m, +emit_fetch(struct spe_function *p, unsigned in_ptr, unsigned *offset, unsigned out_ptr, unsigned shuf_ptr, enum pipe_format format) @@ -191,11 +156,11 @@ emit_fetch(struct spe_function *p, register_mask *m, const unsigned type = pf_type(format); const unsigned bytes = pf_size_x(format); - int v0 = allocate_available_register(m); - int v1 = allocate_available_register(m); - int v2 = allocate_available_register(m); - int v3 = allocate_available_register(m); - int tmp = allocate_available_register(m); + int v0 = spe_allocate_available_register(p); + int v1 = spe_allocate_available_register(p); + int v2 = spe_allocate_available_register(p); + int v3 = spe_allocate_available_register(p); + int tmp = spe_allocate_available_register(p); int float_zero = -1; int float_one = -1; float scale_signed = 0.0; @@ -260,19 +225,19 @@ emit_fetch(struct spe_function *p, register_mask *m, if (count < 4) { - float_one = allocate_available_register(m); + float_one = spe_allocate_available_register(p); spe_il(p, float_one, 1); spe_cuflt(p, float_one, float_one, 0); if (count < 3) { - float_zero = allocate_available_register(m); + float_zero = spe_allocate_available_register(p); spe_il(p, float_zero, 0); } } - release_register(m, tmp); + spe_release_register(p, tmp); - emit_matrix_transpose(p, m, v0, v1, v2, v3, out_ptr, shuf_ptr, count); + emit_matrix_transpose(p, v0, v1, v2, v3, out_ptr, shuf_ptr, count); switch (count) { case 1: @@ -284,11 +249,11 @@ emit_fetch(struct spe_function *p, register_mask *m, } if (float_zero != -1) { - release_register(m, float_zero); + spe_release_register(p, float_zero); } if (float_one != -1) { - release_register(m, float_one); + spe_release_register(p, float_one); } } @@ -297,7 +262,6 @@ void cell_update_vertex_fetch(struct draw_context *draw) { struct cell_context *const cell = (struct cell_context *) draw->driver_private; - register_mask m = ~0; struct spe_function *p = &cell->attrib_fetch; unsigned function_index[PIPE_ATTRIB_MAX]; unsigned unique_attr_formats; @@ -338,18 +302,11 @@ void cell_update_vertex_fetch(struct draw_context *draw) spe_init_func(p, 136 * unique_attr_formats); - /* Registers 0, 1, and 2 are reserved by the ABI. - */ - allocate_register(&m, 0); - allocate_register(&m, 1); - allocate_register(&m, 2); - - /* Allocate registers for the function's input parameters. */ - out_ptr = allocate_register(&m, 3); - in_ptr = allocate_register(&m, 4); - shuf_ptr = allocate_register(&m, 5); + out_ptr = spe_allocate_register(p, 3); + in_ptr = spe_allocate_register(p, 4); + shuf_ptr = spe_allocate_register(p, 5); /* Generate code for the individual attribute fetch functions. @@ -362,7 +319,7 @@ void cell_update_vertex_fetch(struct draw_context *draw) - (void *) p->store); offset = 0; - emit_fetch(p, & m, in_ptr, &offset, out_ptr, shuf_ptr, + emit_fetch(p, in_ptr, &offset, out_ptr, shuf_ptr, draw->vertex_element[i].src_format); spe_bi(p, 0, 0, 0); -- cgit v1.2.3 From d9d2ca7a07469a7d5cdc183f2daa6cf9e30938fe Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 10 Mar 2008 22:10:07 -0400 Subject: fix compilation --- src/gallium/auxiliary/draw/Makefile | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index ce6667d8ec..2daa1636f3 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -4,7 +4,6 @@ include $(TOP)/configs/current LIBNAME = draw C_SOURCES = \ - draw_passthrough.c \ draw_aaline.c \ draw_aapoint.c \ draw_clip.c \ -- cgit v1.2.3 From be9a2457388d99a2185f258aeb5ef5183ccfbbb2 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 10 Mar 2008 22:10:18 -0400 Subject: fix double deletion plus, if the current hash is bigger than max size make sure we delete enough from it --- src/gallium/auxiliary/cso_cache/cso_cache.c | 5 ++++- src/gallium/auxiliary/cso_cache/cso_hash.c | 7 ------- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index b427b509f8..a2764b4265 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -207,8 +207,11 @@ static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type { /* if we're approach the maximum size, remove fourth of the entries * otherwise every subsequent call will go through the same */ - int max_entries = (max_size > cso_hash_size(hash)) ? max_size : cso_hash_size(hash); + int hash_size = cso_hash_size(hash); + int max_entries = (max_size > hash_size) ? max_size : hash_size; int to_remove = (max_size < max_entries) * max_entries/4; + if (hash_size > max_size) + to_remove += hash_size - max_size; while (to_remove) { /*remove elements until we're good */ /*fixme: currently we pick the nodes to remove at random*/ diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index b3b4d667d2..5cad5d3be7 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -101,13 +101,6 @@ static void *cso_data_allocate_node(struct cso_hash_data *hash) static void cso_data_free_node(struct cso_node *node) { - /* XXX still a leak here. - * Need to cast value ptr to original cso type, then free the - * driver-specific data hanging off of it. For example: - struct cso_sampler *csamp = (struct cso_sampler *) node->value; - FREE(csamp->data); - */ - FREE(node->value); FREE(node); } -- cgit v1.2.3 From ff3c7a3243e4f3fc60e6cfcfc6a2711e9ea5cf65 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 11 Mar 2008 08:42:49 +0000 Subject: gallium: missing file --- src/gallium/auxiliary/draw/draw_passthrough.c | 222 ++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 src/gallium/auxiliary/draw/draw_passthrough.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_passthrough.c b/src/gallium/auxiliary/draw/draw_passthrough.c new file mode 100644 index 0000000000..fc2dde38ba --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_passthrough.c @@ -0,0 +1,222 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + + +/* This code is a prototype of what a passhthrough vertex shader might + * look like. + * + * Probably the best approach for us is to do: + * - vertex fetch + * - vertex shader + * - cliptest / viewport transform + * + * in one step, then examine the clipOrMask & choose between two paths: + * + * Either: + * - build primitive headers + * - clip and the primitive path + * - build clipped vertex buffers, + * - vertex-emit to vbuf buffers + * + * Or, if no clipping: + * - vertex-emit directly to vbuf buffers + * + * But when bypass clipping is enabled, we just take the latter + * choice. If (some new) passthrough-vertex-shader flag is also set, + * the pipeline degenerates to: + * + * - vertex fetch + * - vertex emit to vbuf buffers + * + * Which is what is prototyped here. + */ +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" + + + +/* Example of a fetch/emit passthrough shader which could be + * generated when bypass_clipping is enabled on a passthrough vertex + * shader. + */ +static void fetch_xyz_rgb_st( struct draw_context *draw, + float *out, + unsigned start, + unsigned count ) +{ + const unsigned *pitch = draw->vertex_fetch.pitch; + const ubyte **src = draw->vertex_fetch.src_ptr; + int i; + + const ubyte *xyzw = src[0] + start * pitch[0]; + const ubyte *rgba = src[1] + start * pitch[1]; + const ubyte *st = src[2] + start * pitch[2]; + + /* loop over vertex attributes (vertex shader inputs) + */ + for (i = 0; i < count; i++) { + { + const float *in = (const float *)xyzw; xyzw += pitch[0]; + /* decode input, encode output. Assume both are float[4] */ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; + } + + { + const float *in = (const float *)rgba; rgba += pitch[1]; + /* decode input, encode output. Assume both are float[4] */ + out[4] = in[0]; + out[5] = in[1]; + out[6] = in[2]; + out[7] = in[3]; + } + + { + const float *in = (const float *)st; st += pitch[2]; + /* decode input, encode output. Assume both are float[2] */ + out[8] = in[0]; + out[9] = in[1]; + } + + out += 10; + } +} + + +static boolean update_shader( struct draw_context *draw ) +{ + const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); + + unsigned nr_attrs = vinfo->num_attribs; + unsigned i; + + for (i = 0; i < nr_attrs; i++) { + unsigned buf = draw->vertex_element[i].vertex_buffer_index; + + draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] + + draw->vertex_buffer[buf].buffer_offset + + draw->vertex_element[i].src_offset; + + draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch; + draw->vertex_fetch.fetch[i] = NULL; + } + + draw->vertex_fetch.nr_attrs = nr_attrs; + draw->vertex_fetch.fetch_func = NULL; + draw->vertex_fetch.pt_fetch = NULL; + + draw->pt.hw_vertex_size = vinfo->size * 4; + + /* Just trying to figure out how this would work: + */ + if (nr_attrs == 3 && + 0 /* some other tests */) + { + draw->vertex_fetch.pt_fetch = fetch_xyz_rgb_st; + assert(vinfo->size == 10); + return TRUE; + } + + return FALSE; +} + + + +static boolean set_prim( struct draw_context *draw, + unsigned prim ) +{ + assert(!draw->user.elts); + + draw->pt.prim = prim; + + switch (prim) { + case PIPE_PRIM_LINE_LOOP: + case PIPE_PRIM_QUADS: + case PIPE_PRIM_QUAD_STRIP: + return FALSE; + default: + draw->render->set_primitive( draw->render, prim ); + return TRUE; + } +} + + + +boolean +draw_passthrough_arrays(struct draw_context *draw, + unsigned prim, + unsigned start, + unsigned count) +{ + float *hw_verts; + + if (!set_prim(draw, prim)) + return FALSE; + + if (!update_shader( draw )) + return FALSE; + + hw_verts = draw->render->allocate_vertices( draw->render, + draw->pt.hw_vertex_size, + count ); + + if (!hw_verts) + return FALSE; + + /* Single routine to fetch vertices, run shader and emit HW verts. + * Clipping and viewport transformation are done on hardware. + */ + draw->vertex_fetch.pt_fetch( draw, + hw_verts, + start, count ); + + /* Draw arrays path to avoid re-emitting index list again and + * again. + */ + draw->render->draw_arrays( draw->render, + start, + count ); + + + draw->render->release_vertices( draw->render, + hw_verts, + draw->pt.hw_vertex_size, + count ); + + return TRUE; +} + -- cgit v1.2.3 From 5038c20795cb2e49d72c1f43a8b705056592356c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 11 Mar 2008 14:23:08 +0000 Subject: draw: don't free our copy of the render stage -- just borrowing it from vbuf stage --- src/gallium/auxiliary/draw/draw_context.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index bb64b50a17..fed2b6e759 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -116,8 +116,11 @@ void draw_destroy( struct draw_context *draw ) tgsi_exec_machine_free_data(&draw->machine); align_free( draw->vs.queue[0].vertex ); /* Frees all the vertices. */ + /* Not so fast -- we're just borrowing this at the moment. + * if (draw->render) draw->render->destroy( draw->render ); + */ FREE( draw ); } -- cgit v1.2.3 From 30fab81de8ea7bf81181db7bd605f376d4e4fca2 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 11 Mar 2008 14:31:17 -0600 Subject: gallium: fix fs/vs typo in cso_set_vertex_shader() --- src/gallium/auxiliary/cso_cache/cso_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index fbb26ca511..f7f4aebb16 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -349,6 +349,6 @@ void cso_set_vertex_shader(struct cso_context *ctx, if (ctx->vertex_shader != handle) { ctx->vertex_shader = handle; - ctx->pipe->bind_fs_state(ctx->pipe, handle); + ctx->pipe->bind_vs_state(ctx->pipe, handle); } } -- cgit v1.2.3 From 34a0ac7f2b93d6d0f3fc85106e7dacb38c4229b6 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 11 Mar 2008 15:01:52 -0600 Subject: gallium: fix some cso_state_callback cast warnings --- src/gallium/auxiliary/cso_cache/cso_cache.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h index 44ee128a4a..e5edbbb556 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.h +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -84,47 +84,49 @@ extern "C" { #endif +typedef void (*cso_state_callback)(void *ctx, void *obj); + struct cso_cache; struct cso_blend { struct pipe_blend_state state; void *data; - void (*delete_state)(struct pipe_context *, void *); + cso_state_callback delete_state; struct pipe_context *context; }; struct cso_depth_stencil_alpha { struct pipe_depth_stencil_alpha_state state; void *data; - void (*delete_state)(struct pipe_context *, void *); + cso_state_callback delete_state; struct pipe_context *context; }; struct cso_rasterizer { struct pipe_rasterizer_state state; void *data; - void (*delete_state)(struct pipe_context *, void *); + cso_state_callback delete_state; struct pipe_context *context; }; struct cso_fragment_shader { struct pipe_shader_state state; void *data; - void (*delete_state)(struct pipe_context *, void *); + cso_state_callback delete_state; struct pipe_context *context; }; struct cso_vertex_shader { struct pipe_shader_state state; void *data; - void (*delete_state)(struct pipe_context *, void *); + cso_state_callback delete_state; struct pipe_context *context; }; struct cso_sampler { struct pipe_sampler_state state; void *data; - void (*delete_state)(struct pipe_context *, void *); + cso_state_callback delete_state; struct pipe_context *context; }; @@ -138,8 +140,6 @@ enum cso_cache_type { CSO_VERTEX_SHADER }; -typedef void (*cso_state_callback)(void *, void *); - unsigned cso_construct_key(void *item, int item_size); struct cso_cache *cso_cache_create(void); -- cgit v1.2.3 From 130b3154544701be2a57ac1c57432f153e363572 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 11 Mar 2008 23:21:36 +0100 Subject: tgsi: Map OPCODE_TEXKILL to OPCODE_KILP. --- src/gallium/include/pipe/p_shader_tokens.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index b110f01291..e4d89971f9 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -341,7 +341,7 @@ struct tgsi_immediate_float32 * ps_1_1 */ #define TGSI_OPCODE_TEXCOORD TGSI_OPCODE_NOP -#define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KIL +#define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KILP #define TGSI_OPCODE_TEXBEM 107 #define TGSI_OPCODE_TEXBEML 108 #define TGSI_OPCODE_TEXREG2AR 109 -- cgit v1.2.3 From 45c59895113f997e5f2b7e346f95e46099fa3566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 11 Mar 2008 12:03:11 +0000 Subject: gallium: Conditional debugging output. Generalize the conditional debugging output code found trhought the gallium drivers. --- src/gallium/auxiliary/util/p_debug.c | 34 +++++++++++++++++++ src/gallium/include/pipe/p_debug.h | 64 ++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 93bfaea393..04e55dd91d 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -103,3 +103,37 @@ void debug_assert_fail(const char *expr, const char *file, unsigned line) debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr); debug_break(); } + + +#define DEBUG_MASK_TABLE_SIZE 256 + + +/** + * Mask hash table. + * + * For now we just take the lower bits of the key, and do no attempt to solve + * collisions. Use a proper hash table when we have dozens of drivers. + */ +static uint32_t debug_mask_table[DEBUG_MASK_TABLE_SIZE]; + + +void debug_mask_set(uint32_t uuid, uint32_t mask) +{ + unsigned hash = uuid & (DEBUG_MASK_TABLE_SIZE - 1); + debug_mask_table[hash] = mask; +} + + +uint32_t debug_mask_get(uint32_t uuid) +{ + unsigned hash = uuid & (DEBUG_MASK_TABLE_SIZE - 1); + return debug_mask_table[hash]; +} + + +void debug_mask_vprintf(uint32_t uuid, uint32_t what, const char *format, va_list ap) +{ + uint32_t mask = debug_mask_get(uuid); + if(mask & what) + debug_vprintf(format, ap); +} diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index a14a1fc5f6..f45363f355 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -41,6 +41,8 @@ #include +#include "p_compiler.h" + #ifdef __cplusplus extern "C" { @@ -93,6 +95,68 @@ void debug_assert_fail(const char *expr, const char *file, unsigned line); #define assert(expr) debug_assert(expr) +/** + * Set a channel's debug mask. + * + * uuid is just a random 32 bit integer that uniquely identifies the debugging + * channel. + * + * @note Due to current implementation issues, make sure the lower 8 bits of + * UUID are unique. + */ +void debug_mask_set(uint32_t uuid, uint32_t mask); + + +uint32_t debug_mask_get(uint32_t uuid); + + +/** + * Conditional debug output. + * + * This is just a generalization of the debug filtering mechanism used + * throughout Gallium. + * + * You use this function as: + * + * @code + * #define MYDRIVER_UUID 0x12345678 // random 32 bit identifier + * + * static inline mydriver_debug(uint32_t what, const char *format, ...) + * { + * #ifdef DEBUG + * va_list ap; + * va_start(ap, format); + * debug_mask_vprintf(MYDRIVER_UUID, what, format, ap); + * va_end(ap); + * #endif + * } + * + * ... + * + * debug_mask_set(MYDRIVER_UUID, + * MYDRIVER_DEBUG_THIS | + * MYDRIVER_DEBUG_THAT | + * ... ); + * + * ... + * + * mydriver_debug(MYDRIVER_DEBUG_THIS, + * "this and this happened\n"); + * + * mydriver_debug(MYDRIVER_DEBUG_THAT, + * "that = %f\n", that); + * ... + * @endcode + * + * You can also define several variants of mydriver_debug, with hardcoded what. + * Note that although macros with variable number of arguments would accomplish + * more in less code, they are not portable. + */ +void debug_mask_vprintf(uint32_t uuid, + uint32_t what, + const char *format, + va_list ap); + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 21ff00306131cd5598f95285badaaabc98021e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 11 Mar 2008 23:51:27 +0000 Subject: gallium: Silence MSVC warnings. --- src/gallium/auxiliary/util/u_snprintf.c | 10 +++------- src/gallium/drivers/i915simple/i915_state.c | 7 +++++-- src/gallium/drivers/softpipe/sp_state_sampler.c | 8 +++++--- 3 files changed, 13 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_snprintf.c b/src/gallium/auxiliary/util/u_snprintf.c index 5e19a2ddb2..61c20b48f7 100644 --- a/src/gallium/auxiliary/util/u_snprintf.c +++ b/src/gallium/auxiliary/util/u_snprintf.c @@ -241,7 +241,6 @@ static void *mymemcpy(void *, void *, size_t); #endif /* !HAVE_VASPRINTF */ #if !HAVE_VSNPRINTF -#include /* For ERANGE and errno. */ #include /* For *_MAX. */ #if HAVE_INTTYPES_H #include /* For intmax_t (if not defined in ). */ @@ -445,8 +444,6 @@ static UINTMAX_T cast(LDOUBLE); static UINTMAX_T myround(LDOUBLE); static LDOUBLE mypow10(int); -extern int errno; - int rpl_vsnprintf(char *str, size_t size, const char *format, va_list args) { @@ -747,7 +744,7 @@ rpl_vsnprintf(char *str, size_t size, const char *format, va_list args) goto out; break; case 'c': - cvalue = va_arg(args, int); + cvalue = (unsigned char)va_arg(args, int); OUTCHAR(str, len, size, cvalue); break; case 's': @@ -844,7 +841,6 @@ out: str[size - 1] = '\0'; if (overflow || len >= INT_MAX) { - errno = overflow ? EOVERFLOW : ERANGE; return -1; } return (int)len; @@ -1106,7 +1102,7 @@ again: * Factor of ten with the number of digits needed for the fractional * part. For example, if the precision is 3, the mask will be 1000. */ - mask = mypow10(precision); + mask = (UINTMAX_T)mypow10(precision); /* * We "cheat" by converting the fractional part to integer by * multiplying by a factor of ten. @@ -1358,7 +1354,7 @@ cast(LDOUBLE value) if (value >= UINTMAX_MAX) return UINTMAX_MAX; - result = value; + result = (UINTMAX_T)value; /* * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 24143243d3..d9ab483bfc 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -273,6 +273,7 @@ static void i915_bind_sampler_states(struct pipe_context *pipe, unsigned num, void **sampler) { struct i915_context *i915 = i915_context(pipe); + unsigned i; assert(num <= PIPE_MAX_SAMPLERS); @@ -281,8 +282,10 @@ static void i915_bind_sampler_states(struct pipe_context *pipe, !memcmp(i915->sampler, sampler, num * sizeof(void *))) return; - memcpy(i915->sampler, sampler, num * sizeof(void *)); - memset(&i915->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) * sizeof(void *)); + for (i = 0; i < num; ++i) + i915->sampler[i] = sampler[i]; + for (i = num; i < PIPE_MAX_SAMPLERS; ++i) + i915->sampler[i] = NULL; i915->num_samplers = num; diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 7cf85b9207..033288a0aa 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -56,6 +56,7 @@ softpipe_bind_sampler_states(struct pipe_context *pipe, unsigned num, void **sampler) { struct softpipe_context *softpipe = softpipe_context(pipe); + unsigned i; assert(num <= PIPE_MAX_SAMPLERS); @@ -66,9 +67,10 @@ softpipe_bind_sampler_states(struct pipe_context *pipe, draw_flush(softpipe->draw); - memcpy(softpipe->sampler, sampler, num * sizeof(void *)); - memset(&softpipe->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) * - sizeof(void *)); + for (i = 0; i < num; ++i) + softpipe->sampler[i] = sampler[i]; + for (i = num; i < PIPE_MAX_SAMPLERS; ++i) + softpipe->sampler[i] = NULL; softpipe->num_samplers = num; -- cgit v1.2.3 From 339e7ec6805e6de8794514c0a935081b5d36d38f Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 11 Mar 2008 18:54:31 -0600 Subject: gallium: rework CSO-related code in state tracker Use the code in cso_context.c rather than st_cache.c. Basically, binding of state objects now goes through the CSO module. But Vertex/fragment shaders go through pipe->bind_fs/vs_state() since they're not cached by the CSO module at this time. Also, update softpipe driver to handle NULL state objects in various places. This happens during context destruction. May need to update other drivers... --- src/gallium/auxiliary/draw/draw_aaline.c | 3 ++- src/gallium/auxiliary/draw/draw_aapoint.c | 3 ++- src/gallium/auxiliary/draw/draw_pstipple.c | 3 ++- src/gallium/drivers/softpipe/sp_state_fs.c | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index 3ec73b0800..6b1e640ae9 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -733,7 +733,8 @@ aaline_bind_fs_state(struct pipe_context *pipe, void *fs) /* save current */ aaline->fs = aafs; /* pass-through */ - aaline->driver_bind_fs_state(aaline->pipe, aafs->driver_fs); + aaline->driver_bind_fs_state(aaline->pipe, + (aafs ? aafs->driver_fs : NULL)); } diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c index 70f696475f..99e9e9fe34 100644 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -800,7 +800,8 @@ aapoint_bind_fs_state(struct pipe_context *pipe, void *fs) /* save current */ aapoint->fs = aafs; /* pass-through */ - aapoint->driver_bind_fs_state(aapoint->pipe, aafs->driver_fs); + aapoint->driver_bind_fs_state(aapoint->pipe, + (aafs ? aafs->driver_fs : NULL)); } diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index b3e52dc1c7..ed50d0805a 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -595,7 +595,8 @@ pstip_bind_fs_state(struct pipe_context *pipe, void *fs) /* save current */ pstip->fs = aafs; /* pass-through */ - pstip->driver_bind_fs_state(pstip->pipe, aafs->driver_fs); + pstip->driver_bind_fs_state(pstip->pipe, + (aafs ? aafs->driver_fs : NULL)); } diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index eb641ed321..4eefd1d61f 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -120,7 +120,8 @@ softpipe_bind_vs_state(struct pipe_context *pipe, void *vs) softpipe->vs = (const struct sp_vertex_shader *)vs; - draw_bind_vertex_shader(softpipe->draw, softpipe->vs->draw_data); + draw_bind_vertex_shader(softpipe->draw, + (softpipe->vs ? softpipe->vs->draw_data : NULL)); softpipe->dirty |= SP_NEW_VS; } -- cgit v1.2.3 From 7aa34eb40c05a9ccdbe5cef3fd426def0c295a60 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 11 Mar 2008 19:02:51 -0600 Subject: gallium: dummy install target --- src/gallium/Makefile | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/Makefile b/src/gallium/Makefile index 568747e157..aa77021daf 100644 --- a/src/gallium/Makefile +++ b/src/gallium/Makefile @@ -19,3 +19,7 @@ subdirs: clean: rm -f `find . -name \*.[oa]` rm -f `find . -name depend` + + +# Dummy install target +install: -- cgit v1.2.3 From 221adbd60116d6334996a6b71a8dd133e229a3e9 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 11 Mar 2008 20:03:37 -0600 Subject: cell: check for NULL shader pointer in cell_bind_vs_state() --- src/gallium/drivers/cell/ppu/cell_state_shader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c index 935501441b..269a5c15ba 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -131,7 +131,8 @@ cell_bind_vs_state(struct pipe_context *pipe, void *vs) cell->vs = (const struct cell_vertex_shader_state *) vs; - draw_bind_vertex_shader(cell->draw, cell->vs->draw_data); + draw_bind_vertex_shader(cell->draw, + (cell->vs ? cell->vs->draw_data : NULL)); cell->dirty |= CELL_NEW_VS; } -- cgit v1.2.3 From feb02084a88ca6e23c34fa06e963765c890f0b65 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 12 Mar 2008 11:37:02 +0100 Subject: tgsi: Dump source register divide component. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 59be14a748..a393c65da6 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -1047,6 +1047,11 @@ dump_instruction_short( CHR( ')' ); } + if (src->SrcRegisterExtSwz.ExtDivide != TGSI_EXTSWIZZLE_ONE) { + CHR( '/' ); + ENM( src->SrcRegisterExtSwz.ExtDivide, TGSI_EXTSWIZZLES_SHORT ); + } + first_reg = FALSE; } -- cgit v1.2.3 From 98ae83d5cc73b61826823c915b5c59746c2e85c7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 12 Mar 2008 10:39:25 +0000 Subject: gallium: Add TEX_FILTER_ANISO img filter Hardware almost universally expects us to set a special filtering mode when anisotropic filtering is enabled, as opposed to varying a max-aniso values. Do this once in the state tracker & simplify the driver code. --- src/gallium/drivers/i915simple/i915_state.c | 19 +++++------ .../drivers/i965simple/brw_wm_sampler_state.c | 38 +++++++++++----------- src/gallium/drivers/softpipe/sp_tex_sample.c | 3 ++ src/gallium/include/pipe/p_defines.h | 2 +- 4 files changed, 31 insertions(+), 31 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index d9ab483bfc..57b195ea8d 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -71,6 +71,8 @@ static unsigned translate_img_filter( unsigned filter ) return FILTER_NEAREST; case PIPE_TEX_FILTER_LINEAR: return FILTER_LINEAR; + case PIPE_TEX_FILTER_ANISO: + return FILTER_ANISOTROPIC; default: assert(0); return FILTER_NEAREST; @@ -84,7 +86,7 @@ static unsigned translate_mip_filter( unsigned filter ) return MIPFILTER_NONE; case PIPE_TEX_MIPFILTER_NEAREST: return MIPFILTER_NEAREST; - case PIPE_TEX_FILTER_LINEAR: + case PIPE_TEX_MIPFILTER_LINEAR: return MIPFILTER_LINEAR; default: assert(0); @@ -211,16 +213,11 @@ i915_create_sampler_state(struct pipe_context *pipe, cso->templ = sampler; mipFilt = translate_mip_filter(sampler->min_mip_filter); - if (sampler->max_anisotropy > 1.0) { - minFilt = FILTER_ANISOTROPIC; - magFilt = FILTER_ANISOTROPIC; - if (sampler->max_anisotropy > 2.0) { - cso->state[0] |= SS2_MAX_ANISO_4; - } - } - else { - minFilt = translate_img_filter( sampler->min_img_filter ); - magFilt = translate_img_filter( sampler->mag_img_filter ); + minFilt = translate_img_filter( sampler->min_img_filter ); + magFilt = translate_img_filter( sampler->mag_img_filter ); + + if (sampler->max_anisotropy > 2.0) { + cso->state[0] |= SS2_MAX_ANISO_4; } { diff --git a/src/gallium/drivers/i965simple/brw_wm_sampler_state.c b/src/gallium/drivers/i965simple/brw_wm_sampler_state.c index ff5ba7e7c7..b9eaee56ee 100644 --- a/src/gallium/drivers/i965simple/brw_wm_sampler_state.c +++ b/src/gallium/drivers/i965simple/brw_wm_sampler_state.c @@ -136,6 +136,9 @@ static void brw_update_sampler_state( const struct pipe_sampler_state *pipe_samp case PIPE_TEX_FILTER_LINEAR: sampler->ss0.min_filter = BRW_MAPFILTER_LINEAR; break; + case PIPE_TEX_FILTER_ANISO: + sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC; + break; default: break; } @@ -155,26 +158,23 @@ static void brw_update_sampler_state( const struct pipe_sampler_state *pipe_samp } /* Set Anisotropy: */ - if (pipe_sampler->max_anisotropy > 1.0) { - sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC; - sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC; - - if (pipe_sampler->max_anisotropy > 2.0) { - sampler->ss3.max_aniso = MAX2((pipe_sampler->max_anisotropy - 2) / 2, - BRW_ANISORATIO_16); - } + switch (pipe_sampler->mag_img_filter) { + case PIPE_TEX_FILTER_NEAREST: + sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST; + break; + case PIPE_TEX_FILTER_LINEAR: + sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR; + break; + case PIPE_TEX_FILTER_ANISO: + sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR; + break; + default: + break; } - else { - switch (pipe_sampler->mag_img_filter) { - case PIPE_TEX_FILTER_NEAREST: - sampler->ss0.mag_filter = BRW_MAPFILTER_NEAREST; - break; - case PIPE_TEX_FILTER_LINEAR: - sampler->ss0.mag_filter = BRW_MAPFILTER_LINEAR; - break; - default: - break; - } + + if (pipe_sampler->max_anisotropy > 2.0) { + sampler->ss3.max_aniso = MAX2((pipe_sampler->max_anisotropy - 2) / 2, + BRW_ANISORATIO_16); } sampler->ss1.s_wrap_mode = translate_wrap_mode(pipe_sampler->wrap_s); diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 0ced585c7f..34da6356d7 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -714,6 +714,7 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler, } break; case PIPE_TEX_FILTER_LINEAR: + case PIPE_TEX_FILTER_ANISO: for (j = 0; j < QUAD_SIZE; j++) { float tx[4][4], a, b; int x0, y0, x1, y1, c; @@ -846,6 +847,7 @@ sp_get_samples_3d(struct tgsi_sampler *sampler, } break; case PIPE_TEX_FILTER_LINEAR: + case PIPE_TEX_FILTER_ANISO: for (j = 0; j < QUAD_SIZE; j++) { float texel0[4][4], texel1[4][4]; float xw, yw, zw; /* interpolation weights */ @@ -972,6 +974,7 @@ sp_get_samples_rect(struct tgsi_sampler *sampler, } break; case PIPE_TEX_FILTER_LINEAR: + case PIPE_TEX_FILTER_ANISO: for (j = 0; j < QUAD_SIZE; j++) { float tx[4][4], a, b; int x0, y0, x1, y1, c; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 0c662d6517..bc938ba253 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -152,7 +152,7 @@ enum pipe_texture_target { */ #define PIPE_TEX_FILTER_NEAREST 0 #define PIPE_TEX_FILTER_LINEAR 1 -/* #define PIPE_TEX_FILTER_ANISO 2 */ +#define PIPE_TEX_FILTER_ANISO 2 #define PIPE_TEX_COMPARE_NONE 0 -- cgit v1.2.3 From 8fd633b5cfa36e0cf0acef096315c9250015aba7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 12 Mar 2008 10:43:53 +0000 Subject: gallium: reduce signed/unsigned warnings --- src/gallium/auxiliary/draw/draw_passthrough.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_passthrough.c b/src/gallium/auxiliary/draw/draw_passthrough.c index fc2dde38ba..a51fa0ab23 100644 --- a/src/gallium/auxiliary/draw/draw_passthrough.c +++ b/src/gallium/auxiliary/draw/draw_passthrough.c @@ -78,7 +78,7 @@ static void fetch_xyz_rgb_st( struct draw_context *draw, { const unsigned *pitch = draw->vertex_fetch.pitch; const ubyte **src = draw->vertex_fetch.src_ptr; - int i; + unsigned i; const ubyte *xyzw = src[0] + start * pitch[0]; const ubyte *rgba = src[1] + start * pitch[1]; -- cgit v1.2.3 From 70ae7f09c739465242b0c6255196dae1de9dd8d3 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 12 Mar 2008 14:54:43 +0100 Subject: tgsi: Introduce OPCODE_TXP. Depricate ExdDivide field. --- src/gallium/include/pipe/p_shader_tokens.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index e4d89971f9..f0bb43bc5b 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -227,6 +227,7 @@ struct tgsi_immediate_float32 #define TGSI_OPCODE_STR 51 #define TGSI_OPCODE_TEX 52 #define TGSI_OPCODE_TXD 53 +#define TGSI_OPCODE_TXP 134 #define TGSI_OPCODE_UP2H 54 #define TGSI_OPCODE_UP2US 55 #define TGSI_OPCODE_UP4B 56 @@ -421,7 +422,7 @@ struct tgsi_immediate_float32 #define TGSI_OPCODE_KIL 132 /* unpredicated kill */ #define TGSI_OPCODE_END 133 /* aka HALT */ -#define TGSI_OPCODE_LAST 134 +#define TGSI_OPCODE_LAST 135 #define TGSI_SAT_NONE 0 /* do not saturate */ #define TGSI_SAT_ZERO_ONE 1 /* clamp to [0,1] */ @@ -670,7 +671,14 @@ struct tgsi_src_register_ext_swz unsigned NegateY : 1; /* BOOL */ unsigned NegateZ : 1; /* BOOL */ unsigned NegateW : 1; /* BOOL */ + + /* + * XXX: Do not use. This field has been depricated. + * XXX: If using in conjunction with OPCODE_TEX, please use OPCODE_TXP + * XXX: and, if needed, perform a swizzle on the texture coordinate. + */ unsigned ExtDivide : 4; /* TGSI_EXTSWIZZLE_ */ + unsigned Padding : 3; unsigned Extended : 1; /* BOOL */ }; -- cgit v1.2.3 From a2ea51ed828d8b503492a7b42ac937d2642ac4f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 12 Mar 2008 15:01:18 +0000 Subject: gallium: Change assert behavior on runtime (Mark Mueller). --- src/gallium/auxiliary/util/p_debug.c | 38 ++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 04e55dd91d..09cabdae25 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -36,8 +36,9 @@ #include #endif -#include "pipe/p_debug.h" #include "pipe/p_compiler.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" #ifdef WIN32 @@ -97,11 +98,44 @@ static INLINE void debug_break(void) #endif } +#if defined(WIN32) +ULONG_PTR debug_config_file = 0; +void *mapped_config_file = 0; + +enum { + eAssertAbortEn = 0x1, +}; + +/* Check for aborts enabled. */ +static unsigned abort_en() +{ + if (!mapped_config_file) + { + /* Open an 8 byte file for configuration data. */ + mapped_config_file = EngMapFile(L"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file); + } + /* An value of "0" (ascii) in the configuration file will clear the first 8 bits in the test byte. */ + /* An value of "1" (ascii) in the configuration file will set the first bit in the test byte. */ + /* An value of "2" (ascii) in the configuration file will set the second bit in the test byte. */ + return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn; +} +#else /* WIN32 */ +static unsigned abort_en() +{ + return !GETENV("GALLIUM_ABORT_ON_ASSERT"); +} +#endif void debug_assert_fail(const char *expr, const char *file, unsigned line) { debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr); - debug_break(); + if (abort_en()) + { + debug_break(); + } else + { + debug_printf("continuing...\n"); + } } -- cgit v1.2.3 From 8901a46a742b0cfecde0b981fc65160bf3e8d019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 12 Mar 2008 15:02:11 +0000 Subject: gallium: Generic handle table. --- src/gallium/auxiliary/util/Makefile | 1 + src/gallium/auxiliary/util/SConscript | 1 + src/gallium/auxiliary/util/u_handle_table.c | 207 ++++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_handle_table.h | 96 +++++++++++++ 4 files changed, 305 insertions(+) create mode 100644 src/gallium/auxiliary/util/u_handle_table.c create mode 100644 src/gallium/auxiliary/util/u_handle_table.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index 2a3a9380b3..2abbe9500e 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -7,6 +7,7 @@ C_SOURCES = \ p_debug.c \ p_tile.c \ p_util.c \ + u_handle_table.c \ u_mm.c \ u_snprintf.c diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 642088b962..2030214aa7 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -6,6 +6,7 @@ util = env.ConvenienceLibrary( 'p_debug.c', 'p_tile.c', 'p_util.c', + 'u_handle_table.c', 'u_mm.c', 'u_snprintf.c', ]) diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c new file mode 100644 index 0000000000..8a298f7c41 --- /dev/null +++ b/src/gallium/auxiliary/util/u_handle_table.c @@ -0,0 +1,207 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Generic handle table implementation. + * + * @author José Fonseca + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" + +#include "u_handle_table.h" + + +#define HANDLE_TABLE_INITIAL_SIZE 16 + + +struct handle_table +{ + /** Object array. Empty handles have a null object */ + void **objects; + + /** Number of objects the handle can currently hold */ + unsigned size; + /** Number of consecutive objects allocated at the start of the table */ + unsigned filled; + + /** Optional object destructor */ + void (*destroy)(void *object); +}; + + +struct handle_table * +handle_table_create(void) +{ + struct handle_table *ht; + + ht = MALLOC_STRUCT(handle_table); + if(!ht) + return NULL; + + ht->objects = (void **)CALLOC(HANDLE_TABLE_INITIAL_SIZE, sizeof(void *)); + if(!ht->objects) { + FREE(ht); + return NULL; + } + + ht->size = HANDLE_TABLE_INITIAL_SIZE; + ht->filled = 0; + + ht->destroy = NULL; + + return ht; +} + + +void +handle_table_set_destroy(struct handle_table *ht, + void (*destroy)(void *object)) +{ + assert(ht); + ht->destroy = destroy; +} + + +unsigned +handle_table_add(struct handle_table *ht, + void *object) +{ + unsigned index; + unsigned handle; + + assert(ht); + assert(object); + if(!object) + return 0; + + /* linear search for an empty handle */ + while(ht->filled < ht->size) { + if(!ht->objects[ht->filled]) + break; + ++ht->filled; + } + + /* grow the table */ + if(ht->filled == ht->size) { + unsigned new_size; + void **new_objects; + + new_size = ht->size*2; + assert(new_size); + + new_objects = (void **)REALLOC((void *)ht->objects, + ht->size*sizeof(void *), + new_size*sizeof(void *)); + if(!new_objects) + return 0; + + memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *)); + + ht->size = new_size; + ht->objects = new_objects; + } + + index = ht->filled; + + handle = index + 1; + + /* check integer overflow */ + if(!handle) + return 0; + + assert(!ht->objects[index]); + ht->objects[index] = object; + ++ht->filled; + + return handle; +} + + +void * +handle_table_get(struct handle_table *ht, + unsigned handle) +{ + void *object; + + assert(ht); + assert(handle > 0); + assert(handle <= ht->size); + if(!handle || handle > ht->size) + return NULL; + + object = ht->objects[handle - 1]; + assert(object); + + return object; +} + + +void +handle_table_remove(struct handle_table *ht, + unsigned handle) +{ + void *object; + unsigned index; + + assert(ht); + assert(handle > 0); + assert(handle <= ht->size); + if(!handle || handle > ht->size) + return; + + index = handle - 1; + object = ht->objects[index]; + assert(object); + + if(object && ht->destroy) + ht->destroy(object); + + ht->objects[index] = NULL; + if(index < ht->filled) + ht->filled = index; +} + + +void +handle_table_destroy(struct handle_table *ht) +{ + unsigned index; + assert(ht); + + if(ht->destroy) + for(index = 0; index < ht->size; ++index) + if(ht->objects[index]) + ht->destroy(ht->objects[index]); + + FREE(ht->objects); + FREE(ht); +} + diff --git a/src/gallium/auxiliary/util/u_handle_table.h b/src/gallium/auxiliary/util/u_handle_table.h new file mode 100644 index 0000000000..51fc273865 --- /dev/null +++ b/src/gallium/auxiliary/util/u_handle_table.h @@ -0,0 +1,96 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Generic handle table. + * + * @author José Fonseca + */ + +#ifndef U_HANDLE_TABLE_H_ +#define U_HANDLE_TABLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Abstract data type to map integer handles to objects. + */ +struct handle_table; + + +struct handle_table * +handle_table_create(void); + + +/** + * Set an optional destructor callback. + * + * If set, it will be called during handle_table_remove and + * handle_table_destroy calls. + */ +void +handle_table_set_destroy(struct handle_table *ht, + void (*destroy)(void *object)); + + +/** + * Add a new object. + * + * Returns a zero handle on failure (out of memory). + */ +unsigned +handle_table_add(struct handle_table *ht, + void *object); + +/** + * Fetch an existing object. + * + * Returns NULL for an invalid handle. + */ +void * +handle_table_get(struct handle_table *ht, + unsigned handle); + + +void +handle_table_remove(struct handle_table *ht, + unsigned handle); + + +void +handle_table_destroy(struct handle_table *ht); + + +#ifdef __cplusplus +} +#endif + +#endif /* U_HANDLE_TABLE_H_ */ -- cgit v1.2.3 From e5b1a53c9f9ad247272415e0e21e83cfe00728a9 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 12 Mar 2008 15:29:39 +0100 Subject: tgsi: Dump TXP opcode. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index a393c65da6..1913d482f1 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -459,7 +459,8 @@ static const char *TGSI_OPCODES[] = "OPCODE_IFC", "OPCODE_BREAKC", "OPCODE_KIL", - "OPCODE_END" + "OPCODE_END", + "OPCODE_TXP" }; static const char *TGSI_OPCODES_SHORT[] = @@ -597,7 +598,8 @@ static const char *TGSI_OPCODES_SHORT[] = "IFC", "BREAKC", "KIL", - "END" + "END", + "TXP" }; static const char *TGSI_SATS[] = -- cgit v1.2.3 From ba75e82b6ebaf88dd2e4a8f764b2d296d715bf8a Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 12 Mar 2008 16:41:25 +0100 Subject: tgsi: Remove ExtDivide field from existence. Implement OPCODE_TXP. --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 46 +++++++--------------- src/gallium/auxiliary/tgsi/util/tgsi_build.c | 5 --- src/gallium/auxiliary/tgsi/util/tgsi_build.h | 1 - src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 9 ----- .../drivers/i915simple/i915_fpc_translate.c | 12 +++--- src/gallium/include/pipe/p_shader_tokens.h | 13 +----- 6 files changed, 21 insertions(+), 65 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index ac52441400..f2ed9e0353 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -1220,7 +1220,8 @@ fetch_texel( struct tgsi_sampler *sampler, static void exec_tex(struct tgsi_exec_machine *mach, const struct tgsi_full_instruction *inst, - boolean biasLod) + boolean biasLod, + boolean projected) { const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; union tgsi_exec_channel r[8]; @@ -1234,17 +1235,9 @@ exec_tex(struct tgsi_exec_machine *mach, FETCH(&r[0], 0, CHAN_X); - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: + if (projected) { FETCH(&r[1], 0, CHAN_W); micro_div( &r[0], &r[0], &r[1] ); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); } if (biasLod) { @@ -1266,19 +1259,11 @@ exec_tex(struct tgsi_exec_machine *mach, FETCH(&r[1], 0, CHAN_Y); FETCH(&r[2], 0, CHAN_Z); - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: + if (projected) { FETCH(&r[3], 0, CHAN_W); micro_div( &r[0], &r[0], &r[3] ); micro_div( &r[1], &r[1], &r[3] ); micro_div( &r[2], &r[2], &r[3] ); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); } if (biasLod) { @@ -1300,19 +1285,11 @@ exec_tex(struct tgsi_exec_machine *mach, FETCH(&r[1], 0, CHAN_Y); FETCH(&r[2], 0, CHAN_Z); - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: + if (projected) { FETCH(&r[3], 0, CHAN_W); micro_div( &r[0], &r[0], &r[3] ); micro_div( &r[1], &r[1], &r[3] ); micro_div( &r[2], &r[2], &r[3] ); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); } if (biasLod) { @@ -2007,14 +1984,14 @@ exec_instruction( /* simple texture lookup */ /* src[0] = texcoord */ /* src[1] = sampler unit */ - exec_tex(mach, inst, FALSE); + exec_tex(mach, inst, FALSE, FALSE); break; case TGSI_OPCODE_TXB: /* Texture lookup with lod bias */ /* src[0] = texcoord (src[0].w = LOD bias) */ /* src[1] = sampler unit */ - exec_tex(mach, inst, TRUE); + exec_tex(mach, inst, TRUE, FALSE); break; case TGSI_OPCODE_TXD: @@ -2030,7 +2007,14 @@ exec_instruction( /* Texture lookup with explit LOD */ /* src[0] = texcoord (src[0].w = LOD) */ /* src[1] = sampler unit */ - exec_tex(mach, inst, TRUE); + exec_tex(mach, inst, TRUE, FALSE); + break; + + case TGSI_OPCODE_TXP: + /* Texture lookup with projection */ + /* src[0] = texcoord (src[0].w = projection) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, FALSE, TRUE); break; case TGSI_OPCODE_UP2H: diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.c b/src/gallium/auxiliary/tgsi/util/tgsi_build.c index a00ff1c2a5..9c883ab704 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.c @@ -719,7 +719,6 @@ tgsi_build_full_instruction( reg->SrcRegisterExtSwz.NegateY, reg->SrcRegisterExtSwz.NegateZ, reg->SrcRegisterExtSwz.NegateW, - reg->SrcRegisterExtSwz.ExtDivide, prev_token, instruction, header ); @@ -1057,7 +1056,6 @@ tgsi_default_src_register_ext_swz( void ) src_register_ext_swz.NegateY = 0; src_register_ext_swz.NegateZ = 0; src_register_ext_swz.NegateW = 0; - src_register_ext_swz.ExtDivide = TGSI_EXTSWIZZLE_ONE; src_register_ext_swz.Padding = 0; src_register_ext_swz.Extended = 0; @@ -1084,7 +1082,6 @@ tgsi_build_src_register_ext_swz( unsigned negate_y, unsigned negate_z, unsigned negate_w, - unsigned ext_divide, struct tgsi_token *prev_token, struct tgsi_instruction *instruction, struct tgsi_header *header ) @@ -1099,7 +1096,6 @@ tgsi_build_src_register_ext_swz( assert( negate_y <= 1 ); assert( negate_z <= 1 ); assert( negate_w <= 1 ); - assert( ext_divide <= TGSI_EXTSWIZZLE_ONE ); src_register_ext_swz = tgsi_default_src_register_ext_swz(); src_register_ext_swz.ExtSwizzleX = ext_swizzle_x; @@ -1110,7 +1106,6 @@ tgsi_build_src_register_ext_swz( src_register_ext_swz.NegateY = negate_y; src_register_ext_swz.NegateZ = negate_z; src_register_ext_swz.NegateW = negate_w; - src_register_ext_swz.ExtDivide = ext_divide; prev_token->Extended = 1; instruction_grow( instruction, header ); diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.h b/src/gallium/auxiliary/tgsi/util/tgsi_build.h index 607860e7fc..80bffc4ae7 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.h @@ -229,7 +229,6 @@ tgsi_build_src_register_ext_swz( unsigned negate_y, unsigned negate_z, unsigned negate_w, - unsigned ext_divide, struct tgsi_token *prev_token, struct tgsi_instruction *instruction, struct tgsi_header *header ); diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 1913d482f1..ceb407b884 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -1049,11 +1049,6 @@ dump_instruction_short( CHR( ')' ); } - if (src->SrcRegisterExtSwz.ExtDivide != TGSI_EXTSWIZZLE_ONE) { - CHR( '/' ); - ENM( src->SrcRegisterExtSwz.ExtDivide, TGSI_EXTSWIZZLES_SHORT ); - } - first_reg = FALSE; } @@ -1368,10 +1363,6 @@ dump_instruction_verbose( TXT( "\nNegateW : " ); UID( src->SrcRegisterExtSwz.NegateW ); } - if( deflt || fs->SrcRegisterExtSwz.ExtDivide != src->SrcRegisterExtSwz.ExtDivide ) { - TXT( "\nExtDivide : " ); - ENM( src->SrcRegisterExtSwz.ExtDivide, TGSI_EXTSWIZZLES ); - } if( ignored ) { TXT( "\nPadding : " ); UIX( src->SrcRegisterExtSwz.Padding ); diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index c2d9a93c6c..7b4fca5db1 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -872,19 +872,17 @@ i915_translate_instruction(struct i915_fp_compile *p, break; case TGSI_OPCODE_TEX: - if (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide - == TGSI_EXTSWIZZLE_W) { - emit_tex(p, inst, T0_TEXLDP); - } - else { - emit_tex(p, inst, T0_TEXLD); - } + emit_tex(p, inst, T0_TEXLD); break; case TGSI_OPCODE_TXB: emit_tex(p, inst, T0_TEXLDB); break; + case TGSI_OPCODE_TXP: + emit_tex(p, inst, T0_TEXLDP); + break; + case TGSI_OPCODE_XPD: /* Cross product: * result.x = src0.y * src1.z - src0.z * src1.y; diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index f0bb43bc5b..210169f54f 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -655,9 +655,6 @@ struct tgsi_src_register_ext * * NegateX, NegateY, NegateZ and NegateW negate individual components of the * source register. - * - * ExtDivide specifies which component is used to divide all components of the - * source register. */ struct tgsi_src_register_ext_swz @@ -671,15 +668,7 @@ struct tgsi_src_register_ext_swz unsigned NegateY : 1; /* BOOL */ unsigned NegateZ : 1; /* BOOL */ unsigned NegateW : 1; /* BOOL */ - - /* - * XXX: Do not use. This field has been depricated. - * XXX: If using in conjunction with OPCODE_TEX, please use OPCODE_TXP - * XXX: and, if needed, perform a swizzle on the texture coordinate. - */ - unsigned ExtDivide : 4; /* TGSI_EXTSWIZZLE_ */ - - unsigned Padding : 3; + unsigned Padding : 7; unsigned Extended : 1; /* BOOL */ }; -- cgit v1.2.3 From 12ab5f97013e398b9f6485b97d6691c3c170447a Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 12 Mar 2008 13:20:29 -0600 Subject: gallium: change draw_vertex_shader->state from pointer to struct We were sometimes keeping a pointer to a stack-allocated object. Now make a copy of the pipe_shader_state object. This should fix some seemingly random memory errors/crashes. --- src/gallium/auxiliary/draw/draw_private.h | 2 +- src/gallium/auxiliary/draw/draw_vs_exec.c | 4 ++-- src/gallium/auxiliary/draw/draw_vs_sse.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 25fa8c09c2..4147472d45 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -133,7 +133,7 @@ struct draw_vertex_shader { /* This member will disappear shortly: */ - const struct pipe_shader_state *state; + struct pipe_shader_state state; struct tgsi_shader_info info; diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 514303e0ea..55bec14116 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -71,7 +71,7 @@ vs_exec_prepare( struct draw_vertex_shader *shader, { /* specify the vertex program to interpret/execute */ tgsi_exec_machine_bind_shader(&draw->machine, - shader->state->tokens, + shader->state.tokens, PIPE_MAX_SAMPLERS, NULL /*samplers*/ ); @@ -187,7 +187,7 @@ draw_create_vs_exec(struct draw_context *draw, if (vs == NULL) return NULL; - vs->state = state; + vs->state = *state; vs->prepare = vs_exec_prepare; vs->run = vs_exec_run; vs->delete = vs_exec_delete; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index e5c1a40cca..5ee2adb344 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -221,14 +221,14 @@ draw_create_vs_sse(struct draw_context *draw, if (vs == NULL) return NULL; - vs->base.state = templ; + vs->base.state = *templ; vs->base.prepare = vs_sse_prepare; vs->base.run = vs_sse_run; vs->base.delete = vs_sse_delete; x86_init_func( &vs->sse2_program ); - if (!tgsi_emit_sse2( (struct tgsi_token *) vs->base.state->tokens, + if (!tgsi_emit_sse2( (struct tgsi_token *) vs->base.state.tokens, &vs->sse2_program )) goto fail; -- cgit v1.2.3 From 51809bc1bc719c8d988cd6e06b6c96af43d12026 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 12 Mar 2008 13:22:58 -0600 Subject: remove reference to obsolete ExtDivide --- src/gallium/drivers/i965simple/brw_wm_glsl.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_wm_glsl.c b/src/gallium/drivers/i965simple/brw_wm_glsl.c index 44f946ea74..5c90583824 100644 --- a/src/gallium/drivers/i965simple/brw_wm_glsl.c +++ b/src/gallium/drivers/i965simple/brw_wm_glsl.c @@ -124,10 +124,6 @@ static struct brw_reg get_src_reg(struct brw_wm_compile *c, */ component = get_ext_swz(src->SrcRegisterExtSwz, component); - /* Can't handle this, don't know if we need to: - */ - assert(src->SrcRegisterExtSwz.ExtDivide == TGSI_EXTSWIZZLE_ONE); - /* Not handling indirect lookups yet: */ assert(src->SrcRegister.Indirect == 0); -- cgit v1.2.3 From 2109ba4c5d22e1f7effa33a6ff26ce587ce46fe3 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 12 Mar 2008 16:56:12 -0600 Subject: i915: handle NULL object in i915_bind_rasterizer_state() --- src/gallium/drivers/i915simple/i915_state.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 57b195ea8d..503c092400 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -668,22 +668,23 @@ i915_create_rasterizer_state(struct pipe_context *pipe, } static void i915_bind_rasterizer_state( struct pipe_context *pipe, - void *setup ) + void *raster ) { struct i915_context *i915 = i915_context(pipe); - i915->rasterizer = (struct i915_rasterizer_state *)setup; + i915->rasterizer = (struct i915_rasterizer_state *)raster; /* pass-through to draw module */ - draw_set_rasterizer_state(i915->draw, i915->rasterizer->templ); + draw_set_rasterizer_state(i915->draw, + (i915->rasterizer ? i915->rasterizer->templ : NULL)); i915->dirty |= I915_NEW_RASTERIZER; } static void i915_delete_rasterizer_state(struct pipe_context *pipe, - void *setup) + void *raster) { - FREE(setup); + FREE(raster); } static void i915_set_vertex_buffer( struct pipe_context *pipe, -- cgit v1.2.3 From 329c5431348117e5b99adf14936d2f57f2ef5f1f Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 12 Mar 2008 19:29:30 -0600 Subject: gallium: fix polygon stipple Was broken by commit 4528287e040415c2071012d02f20979ff995c754 (bind all samplers/texures at once). --- src/gallium/auxiliary/draw/draw_pstipple.c | 34 +++++++++++++++++++----------- 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index ed50d0805a..8b3e84a9a0 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -67,6 +67,7 @@ struct pstip_stage struct draw_stage stage; void *sampler_cso; + uint sampler_unit; struct pipe_texture *texture; uint num_samplers; uint num_textures; @@ -76,8 +77,8 @@ struct pstip_stage */ struct pstip_fragment_shader *fs; struct { - void *sampler[PIPE_MAX_SAMPLERS]; - struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + void *samplers[PIPE_MAX_SAMPLERS]; + struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; const struct pipe_poly_stipple *stipple; } state; @@ -328,6 +329,8 @@ generate_pstip_fs(struct pstip_stage *pstip) tgsi_dump(pstip_fs.tokens, 0); #endif + pstip->sampler_unit = transform.maxSampler + 1; + #if 1 /* XXX remove */ if (transform.wincoordInput < 0) { pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION; @@ -483,17 +486,24 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) { struct pstip_stage *pstip = pstip_stage(stage); struct pipe_context *pipe = pstip->pipe; - uint num = MAX2(pstip->num_textures, pstip->num_samplers); + uint num_samplers; + + /* how many samplers? */ + /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ + num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); + num_samplers = MAX2(num_samplers, pstip->sampler_unit + 1); assert(stage->draw->rasterizer->poly_stipple_enable); - /* - * Bind our fragprog, sampler and texture - */ + /* bind our fragprog */ bind_pstip_fragment_shader(pstip); - pstip->driver_bind_sampler_states(pipe, num + 1, pstip->state.sampler); - pstip->driver_set_sampler_textures(pipe, num + 1, pstip->state.texture); + /* plug in our sampler, texture */ + pstip->state.samplers[pstip->sampler_unit] = pstip->sampler_cso; + pstip->state.textures[pstip->sampler_unit] = pstip->texture; + + pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); + pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); /* now really draw first line */ stage->tri = passthrough_tri; @@ -516,9 +526,9 @@ pstip_flush(struct draw_stage *stage, unsigned flags) /* XXX restore original texture, sampler state */ pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, - pstip->state.sampler); + pstip->state.samplers); pstip->driver_set_sampler_textures(pipe, pstip->num_textures, - pstip->state.texture); + pstip->state.textures); } @@ -617,7 +627,7 @@ pstip_bind_sampler_states(struct pipe_context *pipe, { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); /* save current */ - memcpy(pstip->state.sampler, sampler, num * sizeof(void *)); + memcpy(pstip->state.samplers, sampler, num * sizeof(void *)); pstip->num_samplers = num; /* pass-through */ pstip->driver_bind_sampler_states(pstip->pipe, num, sampler); @@ -630,7 +640,7 @@ pstip_set_sampler_textures(struct pipe_context *pipe, { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); /* save current */ - memcpy(pstip->state.texture, texture, num * sizeof(struct pipe_texture *)); + memcpy(pstip->state.textures, texture, num * sizeof(struct pipe_texture *)); pstip->num_textures = num; /* pass-through */ pstip->driver_set_sampler_textures(pstip->pipe, num, texture); -- cgit v1.2.3 From a1d56728655a3fc87360b45ac8b348bcfdf6ac15 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 12 Mar 2008 21:42:33 -0400 Subject: document hash collision resolutions --- src/gallium/auxiliary/cso_cache/cso_hash.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h index d5bca9d591..84b45a5963 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.h +++ b/src/gallium/auxiliary/cso_cache/cso_hash.h @@ -25,6 +25,16 @@ * **************************************************************************/ +/** + This file provides a hash implementation that is capable of dealing + with collisions. It stores colliding entries in linked list. All + functions operating on the hash return an iterator. The iterator + itself points to the collision list. If there wasn't any collision + the list will have just one entry, otherwise client code should + iterate over the entries to find the exact entry among ones that + had the same key (e.g. memcmp could be used on the data to check + that) +*/ /* * Authors: * Zack Rusin -- cgit v1.2.3 From 2366bb1baf2e9ae5b6ecf19f66ae9e0a4b0d2f36 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 12 Mar 2008 22:06:51 -0400 Subject: Add some basic documentation for gallivm code --- src/gallium/auxiliary/gallivm/gallivm.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/gallivm.h b/src/gallium/auxiliary/gallivm/gallivm.h index 57912a952f..b4d6555d2f 100644 --- a/src/gallium/auxiliary/gallivm/gallivm.h +++ b/src/gallium/auxiliary/gallivm/gallivm.h @@ -33,6 +33,16 @@ #ifndef GALLIVM_H #define GALLIVM_H +/* + LLVM representation consists of two stages - layout independent + intermediate representation gallivm_ir and driver specific + gallivm_prog. TGSI is first being translated into gallivm_ir + after that driver can set number of options on gallivm_ir and + have it compiled into gallivm_prog. gallivm_prog can be either + executed (assuming there's LLVM JIT backend for the current + target) or machine code generation can be done (assuming there's + a LLVM code generator for thecurrent target) + */ #if defined __cplusplus extern "C" { #endif -- cgit v1.2.3 From cac037d36d451e8cafbb4a759d0edf9fa8b1ca81 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 12 Mar 2008 22:51:57 -0400 Subject: add code handling dependencies between generated code --- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 96 ++++++++++++++++++++--- src/gallium/auxiliary/gallivm/instructionssoa.h | 6 ++ src/gallium/auxiliary/gallivm/soabuiltins.c | 18 +++++ src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 1 + 4 files changed, 111 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 89d513afd0..6f83b56a72 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -143,8 +143,16 @@ std::vector InstructionsSoa::extractVector(llvm::Value *vector) void InstructionsSoa::createFunctionMap() { - m_functionsMap[TGSI_OPCODE_DP3] = "dp3"; - m_functionsMap[TGSI_OPCODE_DP4] = "dp4"; + m_functionsMap[TGSI_OPCODE_DP3] = "dp3"; + m_functionsMap[TGSI_OPCODE_DP4] = "dp4"; + m_functionsMap[TGSI_OPCODE_POWER] = "pow"; +} + +void InstructionsSoa::createDependencies() +{ + std::vector powDeps(1); + powDeps[0] = "powf"; + m_builtinDependencies["pow"] = powDeps; } llvm::Function * InstructionsSoa::function(int op) @@ -154,15 +162,14 @@ llvm::Function * InstructionsSoa::function(int op) std::string name = m_functionsMap[op]; + std::vector deps = m_builtinDependencies[name]; + for (unsigned int i = 0; i < deps.size(); ++i) { + injectFunction(m_builtins->getFunction(deps[i])); + } + llvm::Function *originalFunc = m_builtins->getFunction(name); - llvm::Function *func = CloneFunction(originalFunc); - currentModule()->getFunctionList().push_back(func); - std::cout << "Func parent is "<getParent() - <<", cur is "<dump(); - //func->setParent(currentModule()); - m_functions[op] = func; - return func; + injectFunction(originalFunc, op); + return m_functions[op]; } llvm::Module * InstructionsSoa::currentModule() const @@ -177,6 +184,7 @@ llvm::Module * InstructionsSoa::currentModule() const void InstructionsSoa::createBuiltins() { m_builtins = createSoaBuiltins(); + createDependencies(); } std::vector InstructionsSoa::dp3(const std::vector in1, @@ -304,3 +312,71 @@ std::vector InstructionsSoa::callBuiltin(llvm::Function *func, const std return allocaToResult(allocaPtr); } + +std::vector InstructionsSoa::pow(const std::vector in1, + const std::vector in2) +{ + llvm::Function *func = function(TGSI_OPCODE_POWER); + return callBuiltin(func, in1, in2); +} + +void checkFunction(Function *func) +{ + for (Function::const_iterator BI = func->begin(), BE = func->end(); + BI != BE; ++BI) { + const BasicBlock &BB = *BI; + for (BasicBlock::const_iterator II = BB.begin(), IE = BB.end(); + II != IE; ++II) { + const Instruction &I = *II; + std::cout<< "Instr = "<setOperand(op, V); + } + } + } +} + +void InstructionsSoa::injectFunction(llvm::Function *originalFunc, int op) +{ + assert(originalFunc); + std::cout << "injecting function originalFunc " <getName() <getFunction(originalFunc->getName()); + if (func) { + m_functions[op] = func; + return; + } + } + llvm::Function *func = 0; + if (originalFunc->isDeclaration()) { + std::cout << "function decleration" <getFunctionType(), GlobalValue::ExternalLinkage, + originalFunc->getName(), currentModule()); + func->setCallingConv(CallingConv::C); + const ParamAttrsList *pal = 0; + func->setParamAttrs(pal); + currentModule()->dump(); + } else { + DenseMap val; + val[m_builtins->getFunction("powf")] = currentModule()->getFunction("powf"); + std::cout <<" replacing "<getFunction("powf") + <<", with " <getFunction("powf")<getFunctionList().push_back(func); + std::cout << "Func parent is "<getParent() + <<", cur is "< #include #include @@ -59,6 +60,8 @@ public: const std::vector in3); std::vector mul(const std::vector in1, const std::vector in2); + std::vector pow(const std::vector in1, + const std::vector in2); void end(); std::vector extractVector(llvm::Value *vector); @@ -68,6 +71,7 @@ private: llvm::Value *z, llvm::Value *w); void createFunctionMap(); void createBuiltins(); + void createDependencies(); llvm::Function *function(int); llvm::Module *currentModule() const; llvm::Value *allocaTemp(); @@ -81,6 +85,7 @@ private: const std::vector in1, const std::vector in2, const std::vector in3); + void injectFunction(llvm::Function *originalFunc, int op = TGSI_OPCODE_LAST); private: llvm::LLVMFoldingBuilder m_builder; StorageSoa *m_storage; @@ -88,6 +93,7 @@ private: std::map m_functionsMap; std::map m_functions; llvm::Module *m_builtins; + std::map > m_builtinDependencies; private: mutable int m_idx; diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c index 24c14e1b69..4d658be520 100644 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -60,6 +60,24 @@ void dp4(float4 *res, res[3] = dot; } +extern float powf(float num, float p); + +void pow(float4 *res, + float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, + float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) +{ + float4 p; + p.x = powf(tmp0x.x, tmp1x.x); + p.y = powf(tmp0x.y, tmp1x.y); + p.z = powf(tmp0x.z, tmp1x.z); + p.w = powf(tmp0x.w, tmp1x.w); + + res[0] = p; + res[1] = p; + res[2] = p; + res[3] = p; +} + #if 0 void yo(float4 *out, float4 *in) { diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 3f65865a5a..d2b747ffd1 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -806,6 +806,7 @@ translate_instructionir(llvm::Module *module, } break; case TGSI_OPCODE_POWER: { + out = instr->pow(inputs[0], inputs[1]); } break; case TGSI_OPCODE_CROSSPRODUCT: { -- cgit v1.2.3 From 5ba2f0a507b8d413eea2eb7da09c304ab5a8d3f1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 13 Mar 2008 09:57:01 +0000 Subject: tgsi: bump MAX_SRC_REGS to 4, for TXD --- src/gallium/auxiliary/tgsi/util/tgsi_parse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h index 5ccb5bfcf6..40083728d6 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h @@ -56,7 +56,7 @@ struct tgsi_full_immediate }; #define TGSI_FULL_MAX_DST_REGISTERS 2 -#define TGSI_FULL_MAX_SRC_REGISTERS 3 +#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */ struct tgsi_full_instruction { -- cgit v1.2.3 From ddb4e5cbaced3e96117a97fe362ab890794f5ab7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 13 Mar 2008 10:01:38 +0000 Subject: tgsi: replace erroneous use of FETCH with emit_tempf --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 0da3b0bdb7..4e80597b3f 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -1821,7 +1821,11 @@ emit_instruction( STORE( func, *inst, 5, 0, CHAN_Z ); } IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { - FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C ); + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); STORE( func, *inst, 0, 0, CHAN_W ); } break; @@ -2021,11 +2025,19 @@ emit_instruction( STORE( func, *inst, 0, 0, CHAN_Y ); } IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { - FETCH( func, *inst, 0, TGSI_EXEC_TEMP_00000000_I, TGSI_EXEC_TEMP_00000000_C ); + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ); STORE( func, *inst, 0, 0, CHAN_Z ); } IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { - FETCH( func, *inst, 0, TGSI_EXEC_TEMP_ONE_I, TGSI_EXEC_TEMP_ONE_C ); + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); STORE( func, *inst, 0, 0, CHAN_W ); } break; -- cgit v1.2.3 From 192d1cbbdf9f8e2527ef38761195a87517c2d244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 12 Mar 2008 22:39:13 +0000 Subject: gallium: Add a new handle_table_set that accepts an arbitrary handle. --- src/gallium/auxiliary/util/u_handle_table.c | 85 ++++++++++++++++++++++------- src/gallium/auxiliary/util/u_handle_table.h | 11 ++++ 2 files changed, 75 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c index 8a298f7c41..ab427ee371 100644 --- a/src/gallium/auxiliary/util/u_handle_table.c +++ b/src/gallium/auxiliary/util/u_handle_table.c @@ -26,6 +26,7 @@ **************************************************************************/ /** + * @file * Generic handle table implementation. * * @author José Fonseca @@ -90,6 +91,39 @@ handle_table_set_destroy(struct handle_table *ht, } +/** + * Resize the table if necessary + */ +static INLINE int +handle_table_resize(struct handle_table *ht, + unsigned minimum_size) +{ + unsigned new_size; + void **new_objects; + + if(ht->size > minimum_size) + return ht->size; + + new_size = ht->size; + while(!(new_size > minimum_size)) + new_size *= 2; + assert(new_size); + + new_objects = (void **)REALLOC((void *)ht->objects, + ht->size*sizeof(void *), + new_size*sizeof(void *)); + if(!new_objects) + return 0; + + memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *)); + + ht->size = new_size; + ht->objects = new_objects; + + return ht->size; +} + + unsigned handle_table_add(struct handle_table *ht, void *object) @@ -109,34 +143,17 @@ handle_table_add(struct handle_table *ht, ++ht->filled; } - /* grow the table */ - if(ht->filled == ht->size) { - unsigned new_size; - void **new_objects; - - new_size = ht->size*2; - assert(new_size); - - new_objects = (void **)REALLOC((void *)ht->objects, - ht->size*sizeof(void *), - new_size*sizeof(void *)); - if(!new_objects) - return 0; - - memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *)); - - ht->size = new_size; - ht->objects = new_objects; - } - index = ht->filled; - handle = index + 1; /* check integer overflow */ if(!handle) return 0; + /* grow the table if necessary */ + if(!handle_table_resize(ht, index)) + return 0; + assert(!ht->objects[index]); ht->objects[index] = object; ++ht->filled; @@ -145,6 +162,32 @@ handle_table_add(struct handle_table *ht, } +unsigned +handle_table_set(struct handle_table *ht, + unsigned handle, + void *object) +{ + unsigned index; + + assert(ht); + assert(handle > 0); + assert(handle <= ht->size); + if(!handle || handle > ht->size) + return 0; + + index = handle - 1; + + /* grow the table if necessary */ + if(!handle_table_resize(ht, index)) + return 0; + + assert(!ht->objects[index]); + ht->objects[index] = object; + + return handle; +} + + void * handle_table_get(struct handle_table *ht, unsigned handle) diff --git a/src/gallium/auxiliary/util/u_handle_table.h b/src/gallium/auxiliary/util/u_handle_table.h index 51fc273865..a2f1f604ad 100644 --- a/src/gallium/auxiliary/util/u_handle_table.h +++ b/src/gallium/auxiliary/util/u_handle_table.h @@ -26,6 +26,7 @@ **************************************************************************/ /** + * @file * Generic handle table. * * @author José Fonseca @@ -42,6 +43,8 @@ extern "C" { /** * Abstract data type to map integer handles to objects. + * + * Also referred as "pointer array". */ struct handle_table; @@ -70,6 +73,14 @@ unsigned handle_table_add(struct handle_table *ht, void *object); +/** + * Returns zero on failure (out of memory). + */ +unsigned +handle_table_set(struct handle_table *ht, + unsigned handle, + void *object); + /** * Fetch an existing object. * -- cgit v1.2.3 From 8506e41dc080e20286709ab93b728aa5162f3c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 12 Mar 2008 22:39:44 +0000 Subject: gallium: Fix debug_mask_vprintf's example. --- src/gallium/include/pipe/p_debug.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index f45363f355..f971ad3adc 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -121,7 +121,8 @@ uint32_t debug_mask_get(uint32_t uuid); * @code * #define MYDRIVER_UUID 0x12345678 // random 32 bit identifier * - * static inline mydriver_debug(uint32_t what, const char *format, ...) + * static void inline + * mydriver_debug(uint32_t what, const char *format, ...) * { * #ifdef DEBUG * va_list ap; -- cgit v1.2.3 From e584eb888fac90783c5f62333a39e6735be3e488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 13 Mar 2008 09:58:29 +0000 Subject: gallium: Add a bit of documentation to cso_hash. --- src/gallium/auxiliary/cso_cache/cso_hash.h | 49 +++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h index 84b45a5963..a3a65b68c8 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.h +++ b/src/gallium/auxiliary/cso_cache/cso_hash.h @@ -26,19 +26,20 @@ **************************************************************************/ /** - This file provides a hash implementation that is capable of dealing - with collisions. It stores colliding entries in linked list. All - functions operating on the hash return an iterator. The iterator - itself points to the collision list. If there wasn't any collision - the list will have just one entry, otherwise client code should - iterate over the entries to find the exact entry among ones that - had the same key (e.g. memcmp could be used on the data to check - that) -*/ - /* - * Authors: - * Zack Rusin - */ + * @file + * Hash table implementation. + * + * This file provides a hash implementation that is capable of dealing + * with collisions. It stores colliding entries in linked list. All + * functions operating on the hash return an iterator. The iterator + * itself points to the collision list. If there wasn't any collision + * the list will have just one entry, otherwise client code should + * iterate over the entries to find the exact entry among ones that + * had the same key (e.g. memcmp could be used on the data to check + * that) + * + * @author Zack Rusin + */ #ifndef CSO_HASH_H #define CSO_HASH_H @@ -48,24 +49,38 @@ extern "C" { #endif + struct cso_hash; struct cso_node; + struct cso_hash_iter { struct cso_hash *hash; struct cso_node *node; }; + struct cso_hash *cso_hash_create(void); void cso_hash_delete(struct cso_hash *hash); + int cso_hash_size(struct cso_hash *hash); + +/** + * Create a list of objects and just add entry with the same key to the list. + */ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, unsigned key, void *data); + void *cso_hash_take(struct cso_hash *hash, unsigned key); + struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash); + +/** + * Return an iterator pointing to the first entry in the collision list. + */ struct cso_hash_iter cso_hash_find(struct cso_hash *hash, unsigned key); @@ -73,12 +88,16 @@ int cso_hash_iter_is_null(struct cso_hash_iter iter); unsigned cso_hash_iter_key(struct cso_hash_iter iter); void *cso_hash_iter_data(struct cso_hash_iter iter); + struct cso_hash_iter cso_hash_iter_next(struct cso_hash_iter iter); struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter); -/* KW: a convenience routine: - */ +/** + * Convenience routine to iterate over the collision list while doing a memory + * comparison to see which entry in the list is a direct copy of our template + * and returns that entry. + */ void *cso_hash_find_data_from_template( struct cso_hash *hash, unsigned hash_key, void *templ, -- cgit v1.2.3 From 734ccee565efd274e47f95ea314220726a38a512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 13 Mar 2008 09:59:29 +0000 Subject: gallium: Standardize most important error codes. --- src/gallium/include/pipe/p_error.h | 65 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/gallium/include/pipe/p_error.h (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_error.h b/src/gallium/include/pipe/p_error.h new file mode 100644 index 0000000000..b865b22635 --- /dev/null +++ b/src/gallium/include/pipe/p_error.h @@ -0,0 +1,65 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Gallium error codes. + * + * @author José Fonseca + */ + +#ifndef P_ERROR_H_ +#define P_ERROR_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Gallium error codes. + * + * - A zero value always means success. + * - A negative value always means failure. + * - The meaning of a positive value is function dependent. + */ +enum pipe_error { + PIPE_OK = 0, + PIPE_ERROR = -1, /**< Generic error */ + PIPE_ERROR_BAD_INPUT = -2, + PIPE_ERROR_OUT_OF_MEMORY = -3, + PIPE_ERROR_RETRY = -4 + /* TODO */ +}; + + +#ifdef __cplusplus +} +#endif + +#endif /* P_ERROR_H_ */ -- cgit v1.2.3 From 42f28684168ff88942f51fb01377702570d9d4d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 13 Mar 2008 10:19:23 +0000 Subject: gallium: General purpose hash table, which is actually just a convenient frontend to cso_hash. --- src/gallium/auxiliary/util/Makefile | 1 + src/gallium/auxiliary/util/SConscript | 1 + src/gallium/auxiliary/util/u_hash_table.c | 199 ++++++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_hash_table.h | 86 +++++++++++++ 4 files changed, 287 insertions(+) create mode 100644 src/gallium/auxiliary/util/u_hash_table.c create mode 100644 src/gallium/auxiliary/util/u_hash_table.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index 2abbe9500e..2016c6fb1f 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -8,6 +8,7 @@ C_SOURCES = \ p_tile.c \ p_util.c \ u_handle_table.c \ + u_hash_table.c \ u_mm.c \ u_snprintf.c diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 2030214aa7..154a3eca8c 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -7,6 +7,7 @@ util = env.ConvenienceLibrary( 'p_tile.c', 'p_util.c', 'u_handle_table.c', + 'u_hash_table.c', 'u_mm.c', 'u_snprintf.c', ]) diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c new file mode 100644 index 0000000000..ac2cb1b540 --- /dev/null +++ b/src/gallium/auxiliary/util/u_hash_table.c @@ -0,0 +1,199 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * General purpose hash table implementation. + * + * Just uses the cso_hash for now, but it might be better switch to a linear + * probing hash table implementation at some point -- as it is said they have + * better lookup and cache performance and it appears to be possible to write + * a lock-free implementation of such hash tables . + * + * @author José Fonseca + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" + +#include "cso_cache/cso_hash.h" +#include "u_hash_table.h" + + +struct hash_table +{ + struct cso_hash *cso; + + /** Hash function */ + unsigned (*hash)(void *key); + + /** Compare two keys */ + int (*compare)(void *key1, void *key2); + + /* TODO: key, value destructors? */ +}; + + +struct hash_table_item +{ + void *key; + void *value; +}; + + +struct hash_table * +hash_table_create(unsigned (*hash)(void *key), + int (*compare)(void *key1, void *key2)) +{ + struct hash_table *ht; + + ht = MALLOC_STRUCT(hash_table); + if(!ht) + return NULL; + + ht->cso = cso_hash_create(); + if(!ht->cso) { + FREE(ht); + return NULL; + } + + ht->hash = hash; + ht->compare = compare; + + return ht; +} + + +static struct hash_table_item * +hash_table_find_item(struct hash_table *ht, + void *key, + unsigned key_hash) +{ + struct cso_hash_iter iter; + struct hash_table_item *item; + + iter = cso_hash_find(ht->cso, key_hash); + while (!cso_hash_iter_is_null(iter)) { + item = (struct hash_table_item *)cso_hash_iter_data(iter); + if (!ht->compare(item->key, key)) + return item; + iter = cso_hash_iter_next(iter); + } + + return NULL; +} + + +enum pipe_error +hash_table_set(struct hash_table *ht, + void *key, + void *value) +{ + unsigned key_hash; + struct hash_table_item *item; + + assert(ht); + + key_hash = ht->hash(key); + + item = hash_table_find_item(ht, key, key_hash); + if(item) { + /* TODO: key/value destruction? */ + item->value = value; + return PIPE_OK; + } + + item = MALLOC_STRUCT(hash_table_item); + if(!item) + return PIPE_ERROR_OUT_OF_MEMORY; + + item->key = key; + item->value = value; + + cso_hash_insert(ht->cso, key_hash, item); + /* FIXME: there is no OOM propagation in cso_hash */ + if(0) { + FREE(item); + return PIPE_ERROR_OUT_OF_MEMORY; + } + + return PIPE_OK; +} + + +void * +hash_table_get(struct hash_table *ht, + void *key) +{ + unsigned key_hash; + struct hash_table_item *item; + + assert(ht); + + key_hash = ht->hash(key); + + item = hash_table_find_item(ht, key, key_hash); + if(!item) + return NULL; + + return item->value; +} + + +void +hash_table_remove(struct hash_table *ht, + void *key) +{ + unsigned key_hash; + struct hash_table_item *item; + + assert(ht); + + key_hash = ht->hash(key); + + item = hash_table_find_item(ht, key, key_hash); + if(!item) + return; + + /* FIXME: cso_hash_take takes the first element of the collision list + * indiscriminately, so we can not take the item down. */ + item->value = NULL; +} + + +void +hash_table_destroy(struct hash_table *ht) +{ + assert(ht); + + cso_hash_delete(ht->cso); + + FREE(ht); +} + diff --git a/src/gallium/auxiliary/util/u_hash_table.h b/src/gallium/auxiliary/util/u_hash_table.h new file mode 100644 index 0000000000..d941f2c6b1 --- /dev/null +++ b/src/gallium/auxiliary/util/u_hash_table.h @@ -0,0 +1,86 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * General purpose hash table. + * + * @author José Fonseca + */ + +#ifndef U_HASH_TABLE_H_ +#define U_HASH_TABLE_H_ + + +#include "pipe/p_error.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Generic purpose hash table. + */ +struct hash_table; + + +/** + * Create an hash table. + * + * @param hash hash function + * @param compare should return 0 for two equal keys. + */ +struct hash_table * +hash_table_create(unsigned (*hash)(void *key), + int (*compare)(void *key1, void *key2)); + + +enum pipe_error +hash_table_set(struct hash_table *ht, + void *key, + void *value); + +void * +hash_table_get(struct hash_table *ht, + void *key); + + +void +hash_table_remove(struct hash_table *ht, + void *key); + + +void +hash_table_destroy(struct hash_table *ht); + + +#ifdef __cplusplus +} +#endif + +#endif /* U_HASH_TABLE_H_ */ -- cgit v1.2.3 From 78ddfbd1306c113c3276c79712e5d0e2da82d136 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 13 Mar 2008 12:59:48 +0100 Subject: tgsi: Remove OPCODE_TEXCOORD, OPCODE_TEXCRD aliases. --- src/gallium/include/pipe/p_shader_tokens.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 210169f54f..e3947f663b 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -341,7 +341,6 @@ struct tgsi_immediate_float32 /* * ps_1_1 */ -#define TGSI_OPCODE_TEXCOORD TGSI_OPCODE_NOP #define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KILP #define TGSI_OPCODE_TEXBEM 107 #define TGSI_OPCODE_TEXBEML 108 @@ -372,7 +371,6 @@ struct tgsi_immediate_float32 /* * ps_1_4 */ -#define TGSI_OPCODE_TEXCRD TGSI_OPCODE_TEXCOORD #define TGSI_OPCODE_TEXLD TGSI_OPCODE_TEX #define TGSI_OPCODE_TEXDEPTH 122 #define TGSI_OPCODE_BEM 123 -- cgit v1.2.3 From bcb454e7a6e2f7efae114321c65bf98e91d5892f Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 13 Mar 2008 18:12:36 +0100 Subject: tgsi: Drop pre-ps_2_0 opcodes. --- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 68 ------------- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 46 ++------- src/gallium/include/pipe/p_shader_tokens.h | 147 ++++++++++++--------------- 3 files changed, 71 insertions(+), 190 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index d2b747ffd1..ab9e7a06fb 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -588,40 +588,6 @@ translate_instruction(llvm::Module *module, break; case TGSI_OPCODE_NOP: break; - case TGSI_OPCODE_TEXBEM: - break; - case TGSI_OPCODE_TEXBEML: - break; - case TGSI_OPCODE_TEXREG2AR: - break; - case TGSI_OPCODE_TEXM3X2PAD: - break; - case TGSI_OPCODE_TEXM3X2TEX: - break; - case TGSI_OPCODE_TEXM3X3PAD: - break; - case TGSI_OPCODE_TEXM3X3TEX: - break; - case TGSI_OPCODE_TEXM3X3SPEC: - break; - case TGSI_OPCODE_TEXM3X3VSPEC: - break; - case TGSI_OPCODE_TEXREG2GB: - break; - case TGSI_OPCODE_TEXREG2RGB: - break; - case TGSI_OPCODE_TEXDP3TEX: - break; - case TGSI_OPCODE_TEXDP3: - break; - case TGSI_OPCODE_TEXM3X3: - break; - case TGSI_OPCODE_TEXM3X2DEPTH: - break; - case TGSI_OPCODE_TEXDEPTH: - break; - case TGSI_OPCODE_BEM: - break; case TGSI_OPCODE_M4X3: break; case TGSI_OPCODE_M3X4: @@ -981,40 +947,6 @@ translate_instructionir(llvm::Module *module, break; case TGSI_OPCODE_NOP: break; - case TGSI_OPCODE_TEXBEM: - break; - case TGSI_OPCODE_TEXBEML: - break; - case TGSI_OPCODE_TEXREG2AR: - break; - case TGSI_OPCODE_TEXM3X2PAD: - break; - case TGSI_OPCODE_TEXM3X2TEX: - break; - case TGSI_OPCODE_TEXM3X3PAD: - break; - case TGSI_OPCODE_TEXM3X3TEX: - break; - case TGSI_OPCODE_TEXM3X3SPEC: - break; - case TGSI_OPCODE_TEXM3X3VSPEC: - break; - case TGSI_OPCODE_TEXREG2GB: - break; - case TGSI_OPCODE_TEXREG2RGB: - break; - case TGSI_OPCODE_TEXDP3TEX: - break; - case TGSI_OPCODE_TEXDP3: - break; - case TGSI_OPCODE_TEXM3X3: - break; - case TGSI_OPCODE_TEXM3X2DEPTH: - break; - case TGSI_OPCODE_TEXDEPTH: - break; - case TGSI_OPCODE_BEM: - break; case TGSI_OPCODE_M4X3: break; case TGSI_OPCODE_M3X4: diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index ceb407b884..aa78278700 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -324,7 +324,7 @@ static const char *TGSI_IMMS_SHORT[] = "FLT32" }; -static const char *TGSI_OPCODES[] = +static const char *TGSI_OPCODES[TGSI_OPCODE_LAST] = { "OPCODE_ARL", "OPCODE_MOV", @@ -380,6 +380,7 @@ static const char *TGSI_OPCODES[] = "OPCODE_STR", "OPCODE_TEX", "OPCODE_TXD", + "OPCODE_TXP", "OPCODE_UP2H", "OPCODE_UP2US", "OPCODE_UP4B", @@ -433,23 +434,6 @@ static const char *TGSI_OPCODES[] = "OPCODE_NOISE3", "OPCODE_NOISE4", "OPCODE_NOP", - "OPCODE_TEXBEM", - "OPCODE_TEXBEML", - "OPCODE_TEXREG2AR", - "OPCODE_TEXM3X2PAD", - "OPCODE_TEXM3X2TEX", - "OPCODE_TEXM3X3PAD", - "OPCODE_TEXM3X3TEX", - "OPCODE_TEXM3X3SPEC", - "OPCODE_TEXM3X3VSPEC", - "OPCODE_TEXREG2GB", - "OPCODE_TEXREG2RGB", - "OPCODE_TEXDP3TEX", - "OPCODE_TEXDP3", - "OPCODE_TEXM3X3", - "OPCODE_TEXM3X2DEPTH", - "OPCODE_TEXDEPTH", - "OPCODE_BEM", "OPCODE_M4X3", "OPCODE_M3X4", "OPCODE_M3X3", @@ -459,11 +443,10 @@ static const char *TGSI_OPCODES[] = "OPCODE_IFC", "OPCODE_BREAKC", "OPCODE_KIL", - "OPCODE_END", - "OPCODE_TXP" + "OPCODE_END" }; -static const char *TGSI_OPCODES_SHORT[] = +static const char *TGSI_OPCODES_SHORT[TGSI_OPCODE_LAST] = { "ARL", "MOV", @@ -519,6 +502,7 @@ static const char *TGSI_OPCODES_SHORT[] = "STR", "TEX", "TXD", + "TXP", "UP2H", "UP2US", "UP4B", @@ -572,23 +556,6 @@ static const char *TGSI_OPCODES_SHORT[] = "NOISE3", "NOISE4", "NOP", - "TEXBEM", - "TEXBEML", - "TEXREG2AR", - "TEXM3X2PAD", - "TEXM3X2TEX", - "TEXM3X3PAD", - "TEXM3X3TEX", - "TEXM3X3SPEC", - "TEXM3X3VSPEC", - "TEXREG2GB", - "TEXREG2RGB", - "TEXDP3TEX", - "TEXDP3", - "TEXM3X3", - "TEXM3X2DEPTH", - "TEXDEPTH", - "BEM", "M4X3", "M3X4", "M3X3", @@ -598,8 +565,7 @@ static const char *TGSI_OPCODES_SHORT[] = "IFC", "BREAKC", "KIL", - "END", - "TXP" + "END" }; static const char *TGSI_SATS[] = diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index e3947f663b..f05e1a34b3 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -227,22 +227,22 @@ struct tgsi_immediate_float32 #define TGSI_OPCODE_STR 51 #define TGSI_OPCODE_TEX 52 #define TGSI_OPCODE_TXD 53 -#define TGSI_OPCODE_TXP 134 -#define TGSI_OPCODE_UP2H 54 -#define TGSI_OPCODE_UP2US 55 -#define TGSI_OPCODE_UP4B 56 -#define TGSI_OPCODE_UP4UB 57 -#define TGSI_OPCODE_X2D 58 +#define TGSI_OPCODE_TXP 54 +#define TGSI_OPCODE_UP2H 55 +#define TGSI_OPCODE_UP2US 56 +#define TGSI_OPCODE_UP4B 57 +#define TGSI_OPCODE_UP4UB 58 +#define TGSI_OPCODE_X2D 59 /* * GL_NV_vertex_program2 */ -#define TGSI_OPCODE_ARA 59 -#define TGSI_OPCODE_ARR 60 -#define TGSI_OPCODE_BRA 61 -#define TGSI_OPCODE_CAL 62 -#define TGSI_OPCODE_RET 63 -#define TGSI_OPCODE_SSG 64 +#define TGSI_OPCODE_ARA 60 +#define TGSI_OPCODE_ARR 61 +#define TGSI_OPCODE_BRA 62 +#define TGSI_OPCODE_CAL 63 +#define TGSI_OPCODE_RET 64 +#define TGSI_OPCODE_SSG 65 /* * GL_ARB_vertex_program @@ -253,9 +253,9 @@ struct tgsi_immediate_float32 /* * GL_ARB_fragment_program */ -#define TGSI_OPCODE_CMP 65 -#define TGSI_OPCODE_SCS 66 -#define TGSI_OPCODE_TXB 67 +#define TGSI_OPCODE_CMP 66 +#define TGSI_OPCODE_SCS 67 +#define TGSI_OPCODE_TXB 68 /* * GL_NV_fragment_program_option @@ -265,19 +265,19 @@ struct tgsi_immediate_float32 /* * GL_NV_fragment_program2 */ -#define TGSI_OPCODE_NRM 68 -#define TGSI_OPCODE_DIV 69 -#define TGSI_OPCODE_DP2 70 +#define TGSI_OPCODE_NRM 69 +#define TGSI_OPCODE_DIV 70 +#define TGSI_OPCODE_DP2 71 #define TGSI_OPCODE_DP2A TGSI_OPCODE_DOT2ADD -#define TGSI_OPCODE_TXL 71 -#define TGSI_OPCODE_BRK 72 -#define TGSI_OPCODE_IF 73 -#define TGSI_OPCODE_LOOP 74 -#define TGSI_OPCODE_REP 75 -#define TGSI_OPCODE_ELSE 76 -#define TGSI_OPCODE_ENDIF 77 -#define TGSI_OPCODE_ENDLOOP 78 -#define TGSI_OPCODE_ENDREP 79 +#define TGSI_OPCODE_TXL 72 +#define TGSI_OPCODE_BRK 73 +#define TGSI_OPCODE_IF 74 +#define TGSI_OPCODE_LOOP 75 +#define TGSI_OPCODE_REP 76 +#define TGSI_OPCODE_ELSE 77 +#define TGSI_OPCODE_ENDIF 78 +#define TGSI_OPCODE_ENDLOOP 79 +#define TGSI_OPCODE_ENDREP 80 /* * GL_NV_vertex_program2_option @@ -286,26 +286,26 @@ struct tgsi_immediate_float32 /* * GL_NV_vertex_program3 */ -#define TGSI_OPCODE_PUSHA 80 -#define TGSI_OPCODE_POPA 81 +#define TGSI_OPCODE_PUSHA 81 +#define TGSI_OPCODE_POPA 82 /* * GL_NV_gpu_program4 */ -#define TGSI_OPCODE_CEIL 82 -#define TGSI_OPCODE_I2F 83 -#define TGSI_OPCODE_NOT 84 -#define TGSI_OPCODE_TRUNC 85 -#define TGSI_OPCODE_SHL 86 -#define TGSI_OPCODE_SHR 87 -#define TGSI_OPCODE_AND 88 -#define TGSI_OPCODE_OR 89 -#define TGSI_OPCODE_MOD 90 -#define TGSI_OPCODE_XOR 91 -#define TGSI_OPCODE_SAD 92 -#define TGSI_OPCODE_TXF 93 -#define TGSI_OPCODE_TXQ 94 -#define TGSI_OPCODE_CONT 95 +#define TGSI_OPCODE_CEIL 83 +#define TGSI_OPCODE_I2F 84 +#define TGSI_OPCODE_NOT 85 +#define TGSI_OPCODE_TRUNC 86 +#define TGSI_OPCODE_SHL 87 +#define TGSI_OPCODE_SHR 88 +#define TGSI_OPCODE_AND 89 +#define TGSI_OPCODE_OR 90 +#define TGSI_OPCODE_MOD 91 +#define TGSI_OPCODE_XOR 92 +#define TGSI_OPCODE_SAD 93 +#define TGSI_OPCODE_TXF 94 +#define TGSI_OPCODE_TXQ 95 +#define TGSI_OPCODE_CONT 96 /* * GL_NV_vertex_program4 @@ -321,70 +321,53 @@ struct tgsi_immediate_float32 * GL_NV_geometry_program4 */ /* Same as GL_NV_gpu_program4 */ -#define TGSI_OPCODE_EMIT 96 -#define TGSI_OPCODE_ENDPRIM 97 +#define TGSI_OPCODE_EMIT 97 +#define TGSI_OPCODE_ENDPRIM 98 /* * GLSL */ -#define TGSI_OPCODE_BGNLOOP2 98 -#define TGSI_OPCODE_BGNSUB 99 -#define TGSI_OPCODE_ENDLOOP2 100 -#define TGSI_OPCODE_ENDSUB 101 +#define TGSI_OPCODE_BGNLOOP2 99 +#define TGSI_OPCODE_BGNSUB 100 +#define TGSI_OPCODE_ENDLOOP2 101 +#define TGSI_OPCODE_ENDSUB 102 #define TGSI_OPCODE_INT TGSI_OPCODE_TRUNC -#define TGSI_OPCODE_NOISE1 102 -#define TGSI_OPCODE_NOISE2 103 -#define TGSI_OPCODE_NOISE3 104 -#define TGSI_OPCODE_NOISE4 105 -#define TGSI_OPCODE_NOP 106 +#define TGSI_OPCODE_NOISE1 103 +#define TGSI_OPCODE_NOISE2 104 +#define TGSI_OPCODE_NOISE3 105 +#define TGSI_OPCODE_NOISE4 106 +#define TGSI_OPCODE_NOP 107 /* * ps_1_1 */ #define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KILP -#define TGSI_OPCODE_TEXBEM 107 -#define TGSI_OPCODE_TEXBEML 108 -#define TGSI_OPCODE_TEXREG2AR 109 -#define TGSI_OPCODE_TEXM3X2PAD 110 -#define TGSI_OPCODE_TEXM3X2TEX 111 -#define TGSI_OPCODE_TEXM3X3PAD 112 -#define TGSI_OPCODE_TEXM3X3TEX 113 -#define TGSI_OPCODE_TEXM3X3SPEC 114 -#define TGSI_OPCODE_TEXM3X3VSPEC 115 /* * ps_1_2 */ -#define TGSI_OPCODE_TEXREG2GB 116 -#define TGSI_OPCODE_TEXREG2RGB 117 -#define TGSI_OPCODE_TEXDP3TEX 118 -#define TGSI_OPCODE_TEXDP3 119 -#define TGSI_OPCODE_TEXM3X3 120 /* CMP - use TGSI_OPCODE_CND0 */ /* * ps_1_3 */ -#define TGSI_OPCODE_TEXM3X2DEPTH 121 /* CMP - use TGSI_OPCODE_CND0 */ /* * ps_1_4 */ #define TGSI_OPCODE_TEXLD TGSI_OPCODE_TEX -#define TGSI_OPCODE_TEXDEPTH 122 -#define TGSI_OPCODE_BEM 123 /* * ps_2_0 */ #define TGSI_OPCODE_M4X4 TGSI_OPCODE_MULTIPLYMATRIX -#define TGSI_OPCODE_M4X3 124 -#define TGSI_OPCODE_M3X4 125 -#define TGSI_OPCODE_M3X3 126 -#define TGSI_OPCODE_M3X2 127 +#define TGSI_OPCODE_M4X3 108 +#define TGSI_OPCODE_M3X4 109 +#define TGSI_OPCODE_M3X3 110 +#define TGSI_OPCODE_M3X2 111 #define TGSI_OPCODE_CRS TGSI_OPCODE_XPD -#define TGSI_OPCODE_NRM4 128 +#define TGSI_OPCODE_NRM4 112 #define TGSI_OPCODE_SINCOS TGSI_OPCODE_SCS #define TGSI_OPCODE_TEXLDB TGSI_OPCODE_TXB #define TGSI_OPCODE_DP2ADD TGSI_OPCODE_DP2A @@ -393,10 +376,10 @@ struct tgsi_immediate_float32 * ps_2_x */ #define TGSI_OPCODE_CALL TGSI_OPCODE_CAL -#define TGSI_OPCODE_CALLNZ 129 -#define TGSI_OPCODE_IFC 130 +#define TGSI_OPCODE_CALLNZ 113 +#define TGSI_OPCODE_IFC 114 #define TGSI_OPCODE_BREAK TGSI_OPCODE_BRK -#define TGSI_OPCODE_BREAKC 131 +#define TGSI_OPCODE_BREAKC 115 #define TGSI_OPCODE_DSX TGSI_OPCODE_DDX #define TGSI_OPCODE_DSY TGSI_OPCODE_DDY #define TGSI_OPCODE_TEXLDD TGSI_OPCODE_TXD @@ -417,10 +400,10 @@ struct tgsi_immediate_float32 * vs_2_x */ -#define TGSI_OPCODE_KIL 132 /* unpredicated kill */ -#define TGSI_OPCODE_END 133 /* aka HALT */ +#define TGSI_OPCODE_KIL 116 /* unpredicated kill */ +#define TGSI_OPCODE_END 117 /* aka HALT */ -#define TGSI_OPCODE_LAST 135 +#define TGSI_OPCODE_LAST 118 #define TGSI_SAT_NONE 0 /* do not saturate */ #define TGSI_SAT_ZERO_ONE 1 /* clamp to [0,1] */ -- cgit v1.2.3 From b0d5519b449feda7b048bc59d4fede54e43f5ae1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 13 Mar 2008 15:23:04 +0000 Subject: gallium: make the windows config function more readable with 80-ish columns --- src/gallium/auxiliary/util/p_debug.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 09cabdae25..bb84e8096d 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -109,20 +109,30 @@ enum { /* Check for aborts enabled. */ static unsigned abort_en() { - if (!mapped_config_file) - { - /* Open an 8 byte file for configuration data. */ - mapped_config_file = EngMapFile(L"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file); - } - /* An value of "0" (ascii) in the configuration file will clear the first 8 bits in the test byte. */ - /* An value of "1" (ascii) in the configuration file will set the first bit in the test byte. */ - /* An value of "2" (ascii) in the configuration file will set the second bit in the test byte. */ - return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn; + if (!mapped_config_file) + { + /* Open an 8 byte file for configuration data. */ + mapped_config_file = EngMapFile(L"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file); + } + + /* A value of "0" (ascii) in the configuration file will clear the + * first 8 bits in the test byte. + * + * A value of "1" (ascii) in the configuration file will set the + * first bit in the test byte. + * + * A value of "2" (ascii) in the configuration file will set the + * second bit in the test byte. + * + * Currently the only interesting values are 0 and 1, which clear + * and set abort-on-assert behaviour respectively. + */ + return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn; } #else /* WIN32 */ static unsigned abort_en() { - return !GETENV("GALLIUM_ABORT_ON_ASSERT"); + return !GETENV("GALLIUM_ABORT_ON_ASSERT"); } #endif -- cgit v1.2.3 From fa9e7e9a8debb68611909ac2ffab527c6c39a3e5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 13 Mar 2008 18:08:18 +0000 Subject: gallium: remove semantic info from pipe_shader_state Brian's patch to clean up the shader interfaces. --- src/gallium/auxiliary/draw/draw_aaline.c | 2 +- src/gallium/auxiliary/draw/draw_aapoint.c | 2 +- src/gallium/auxiliary/draw/draw_pstipple.c | 2 +- src/gallium/include/pipe/p_state.h | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index 6b1e640ae9..bed709bad0 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -340,7 +340,7 @@ generate_aaline_fs(struct aaline_stage *aaline) tgsi_dump(aaline_fs.tokens, 0); #endif -#if 1 /* XXX remove */ +#if 0 /* XXX remove */ aaline_fs.input_semantic_name[aaline_fs.num_inputs] = TGSI_SEMANTIC_GENERIC; aaline_fs.input_semantic_index[aaline_fs.num_inputs] = transform.maxGeneric + 1; aaline_fs.num_inputs++; diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c index 99e9e9fe34..4bc2b5f3e2 100644 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -514,7 +514,7 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) tgsi_dump(aapoint_fs.tokens, 0); #endif -#if 1 /* XXX remove */ +#if 0 /* XXX remove */ aapoint_fs.input_semantic_name[aapoint_fs.num_inputs] = TGSI_SEMANTIC_GENERIC; aapoint_fs.input_semantic_index[aapoint_fs.num_inputs] = transform.maxGeneric + 1; aapoint_fs.num_inputs++; diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index 8b3e84a9a0..d7475b457c 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -331,7 +331,7 @@ generate_pstip_fs(struct pstip_stage *pstip) pstip->sampler_unit = transform.maxSampler + 1; -#if 1 /* XXX remove */ +#if 0 /* XXX remove */ if (transform.wincoordInput < 0) { pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION; pstip_fs.input_semantic_index[pstip_fs.num_inputs] = (ubyte)transform.maxInput; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index e338a27383..bb5fab5d5f 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -162,6 +162,7 @@ struct pipe_constant_buffer struct pipe_shader_state { const struct tgsi_token *tokens; +#if 0 /* XXX these are going away */ ubyte num_inputs; ubyte num_outputs; @@ -169,6 +170,7 @@ struct pipe_shader_state ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */ ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; +#endif }; -- cgit v1.2.3 From 647213804582a6b6cfd4fbfeb1c9874ef53307f3 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 13 Mar 2008 11:19:50 -0700 Subject: Replicate TXP changes in the SPU version of TGSI exec Replicate changes from commit ba75e82b6ebaf88dd2e4a8f764b2d296d715bf8a in spu_exec.c --- src/gallium/drivers/cell/spu/spu_exec.c | 45 ++++++++++----------------------- 1 file changed, 14 insertions(+), 31 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 1560c0f157..061fbebf61 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -672,7 +672,7 @@ fetch_texel( struct spu_sampler *sampler, static void exec_tex(struct spu_exec_machine *mach, const struct tgsi_full_instruction *inst, - boolean biasLod) + boolean biasLod, boolean projected) { const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; union spu_exec_channel r[8]; @@ -686,17 +686,9 @@ exec_tex(struct spu_exec_machine *mach, FETCH(&r[0], 0, CHAN_X); - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: + if (projected) { FETCH(&r[1], 0, CHAN_W); r[0].q = micro_div(r[0].q, r[1].q); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); } if (biasLod) { @@ -718,19 +710,11 @@ exec_tex(struct spu_exec_machine *mach, FETCH(&r[1], 0, CHAN_Y); FETCH(&r[2], 0, CHAN_Z); - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: + if (projected) { FETCH(&r[3], 0, CHAN_W); r[0].q = micro_div(r[0].q, r[3].q); r[1].q = micro_div(r[1].q, r[3].q); r[2].q = micro_div(r[2].q, r[3].q); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); } if (biasLod) { @@ -752,19 +736,11 @@ exec_tex(struct spu_exec_machine *mach, FETCH(&r[1], 0, CHAN_Y); FETCH(&r[2], 0, CHAN_Z); - switch (inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtDivide) { - case TGSI_EXTSWIZZLE_W: + if (projected) { FETCH(&r[3], 0, CHAN_W); r[0].q = micro_div(r[0].q, r[3].q); r[1].q = micro_div(r[1].q, r[3].q); r[2].q = micro_div(r[2].q, r[3].q); - break; - - case TGSI_EXTSWIZZLE_ONE: - break; - - default: - assert (0); } if (biasLod) { @@ -1450,14 +1426,14 @@ exec_instruction( /* simple texture lookup */ /* src[0] = texcoord */ /* src[1] = sampler unit */ - exec_tex(mach, inst, FALSE); + exec_tex(mach, inst, FALSE, FALSE); break; case TGSI_OPCODE_TXB: /* Texture lookup with lod bias */ /* src[0] = texcoord (src[0].w = load bias) */ /* src[1] = sampler unit */ - exec_tex(mach, inst, TRUE); + exec_tex(mach, inst, TRUE, FALSE); break; case TGSI_OPCODE_TXD: @@ -1473,7 +1449,14 @@ exec_instruction( /* Texture lookup with explit LOD */ /* src[0] = texcoord (src[0].w = load bias) */ /* src[1] = sampler unit */ - exec_tex(mach, inst, TRUE); + exec_tex(mach, inst, TRUE, FALSE); + break; + + case TGSI_OPCODE_TXP: + /* Texture lookup with projection + /* src[0] = texcoord (src[0].w = projection) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, TRUE, TRUE); break; case TGSI_OPCODE_UP2H: -- cgit v1.2.3 From cb294542bcaca7d9847067ce502a68fd8e92f42e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 12 Mar 2008 16:28:33 -0600 Subject: gallium: remove a debug printf --- src/gallium/auxiliary/cso_cache/cso_context.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index f7f4aebb16..fd86bfaca9 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -102,8 +102,6 @@ static void cso_release_all( struct cso_context *ctx ) void cso_destroy_context( struct cso_context *ctx ) { - debug_printf("%s\n", __FUNCTION__); - if (ctx) cso_release_all( ctx ); -- cgit v1.2.3 From 7ffbaebce1da7fec36a38f424f266806a3a0fc6a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 13 Mar 2008 13:22:24 -0600 Subject: gallium: fix bug in stip_first_tri() Need to compute num_samplers after binding/creating the fragment shader. --- src/gallium/auxiliary/draw/draw_pstipple.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index d7475b457c..08f06bf222 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -488,16 +488,16 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) struct pipe_context *pipe = pstip->pipe; uint num_samplers; - /* how many samplers? */ - /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ - num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); - num_samplers = MAX2(num_samplers, pstip->sampler_unit + 1); - assert(stage->draw->rasterizer->poly_stipple_enable); /* bind our fragprog */ bind_pstip_fragment_shader(pstip); + /* how many samplers? */ + /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ + num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); + num_samplers = MAX2(num_samplers, pstip->sampler_unit + 1); + /* plug in our sampler, texture */ pstip->state.samplers[pstip->sampler_unit] = pstip->sampler_cso; pstip->state.textures[pstip->sampler_unit] = pstip->texture; -- cgit v1.2.3 From b12a28db96d3bc7f01b6cdc9ee909f95a8c9ccc2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 13 Mar 2008 14:05:30 -0600 Subject: gallium: remove dead code related to shader semantic input/output info --- src/gallium/auxiliary/draw/draw_aaline.c | 6 ------ src/gallium/auxiliary/draw/draw_aapoint.c | 6 ------ src/gallium/auxiliary/draw/draw_pstipple.c | 10 +--------- src/gallium/include/pipe/p_state.h | 9 --------- 4 files changed, 1 insertion(+), 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index bed709bad0..f2b983374e 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -340,12 +340,6 @@ generate_aaline_fs(struct aaline_stage *aaline) tgsi_dump(aaline_fs.tokens, 0); #endif -#if 0 /* XXX remove */ - aaline_fs.input_semantic_name[aaline_fs.num_inputs] = TGSI_SEMANTIC_GENERIC; - aaline_fs.input_semantic_index[aaline_fs.num_inputs] = transform.maxGeneric + 1; - aaline_fs.num_inputs++; -#endif - aaline->fs->aaline_fs = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c index 4bc2b5f3e2..67a7a8ebab 100644 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -514,12 +514,6 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) tgsi_dump(aapoint_fs.tokens, 0); #endif -#if 0 /* XXX remove */ - aapoint_fs.input_semantic_name[aapoint_fs.num_inputs] = TGSI_SEMANTIC_GENERIC; - aapoint_fs.input_semantic_index[aapoint_fs.num_inputs] = transform.maxGeneric + 1; - aapoint_fs.num_inputs++; -#endif - aapoint->fs->aapoint_fs = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs); diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index 08f06bf222..09d542002f 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -324,21 +324,13 @@ generate_pstip_fs(struct pstip_stage *pstip) (struct tgsi_token *) pstip_fs.tokens, MAX, &transform.base); -#if 1 /* DEBUG */ +#if 0 /* DEBUG */ tgsi_dump(orig_fs->tokens, 0); tgsi_dump(pstip_fs.tokens, 0); #endif pstip->sampler_unit = transform.maxSampler + 1; -#if 0 /* XXX remove */ - if (transform.wincoordInput < 0) { - pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION; - pstip_fs.input_semantic_index[pstip_fs.num_inputs] = (ubyte)transform.maxInput; - pstip_fs.num_inputs++; - } -#endif - pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); } diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index bb5fab5d5f..02c354322d 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -162,15 +162,6 @@ struct pipe_constant_buffer struct pipe_shader_state { const struct tgsi_token *tokens; -#if 0 - /* XXX these are going away */ - ubyte num_inputs; - ubyte num_outputs; - ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */ - ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; - ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */ - ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; -#endif }; -- cgit v1.2.3 From 3115e8c968b51d22962b1b92b13946956dddd98e Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 13 Mar 2008 13:03:22 -0700 Subject: cell: Fix to work with commit fa9e7e9a8debb68611909ac2ffab527c6c39a3e5 --- src/gallium/drivers/cell/ppu/cell_context.h | 4 +++- src/gallium/drivers/cell/ppu/cell_state_derived.c | 20 ++++++++++---------- src/gallium/drivers/cell/ppu/cell_state_shader.c | 23 ++--------------------- 3 files changed, 15 insertions(+), 32 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index c568922cbd..b221424323 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -37,13 +37,14 @@ #include "cell_winsys.h" #include "cell/common.h" #include "rtasm/rtasm_ppc_spe.h" - +#include "tgsi/util/tgsi_scan.h" struct cell_vbuf_render; struct cell_vertex_shader_state { struct pipe_shader_state shader; + struct tgsi_shader_info info; void *draw_data; }; @@ -51,6 +52,7 @@ struct cell_vertex_shader_state struct cell_fragment_shader_state { struct pipe_shader_state shader; + struct tgsi_shader_info info; void *data; }; diff --git a/src/gallium/drivers/cell/ppu/cell_state_derived.c b/src/gallium/drivers/cell/ppu/cell_state_derived.c index 0c46829258..5c240a55c0 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_derived.c +++ b/src/gallium/drivers/cell/ppu/cell_state_derived.c @@ -36,14 +36,14 @@ static int -find_vs_output(const struct pipe_shader_state *vs, +find_vs_output(const struct cell_vertex_shader_state *vs, uint semantic_name, uint semantic_index) { uint i; - for (i = 0; i < vs->num_outputs; i++) { - if (vs->output_semantic_name[i] == semantic_name && - vs->output_semantic_index[i] == semantic_index) + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == semantic_name && + vs->info.output_semantic_index[i] == semantic_index) return i; } return -1; @@ -58,8 +58,8 @@ find_vs_output(const struct pipe_shader_state *vs, static void calculate_vertex_layout( struct cell_context *cell ) { - const struct pipe_shader_state *vs = &cell->vs->shader; - const struct pipe_shader_state *fs = &cell->fs->shader; + const struct cell_vertex_shader_state *vs = cell->vs; + const struct cell_fragment_shader_state *fs = cell->fs; const enum interp_mode colorInterp = cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; struct vertex_info *vinfo = &cell->vertex_info; @@ -91,15 +91,15 @@ calculate_vertex_layout( struct cell_context *cell ) * Loop over fragment shader inputs, searching for the matching output * from the vertex shader. */ - for (i = 0; i < fs->num_inputs; i++) { - switch (fs->input_semantic_name[i]) { + for (i = 0; i < fs->info.num_inputs; i++) { + switch (fs->info.input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: /* already done above */ break; case TGSI_SEMANTIC_COLOR: src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, - fs->input_semantic_index[i]); + fs->info.input_semantic_index[i]); assert(src >= 0); draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); break; @@ -117,7 +117,7 @@ calculate_vertex_layout( struct cell_context *cell ) case TGSI_SEMANTIC_GENERIC: /* this includes texcoords and varying vars */ src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC, - fs->input_semantic_index[i]); + fs->info.input_semantic_index[i]); assert(src >= 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); break; diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c index 269a5c15ba..fb2e940348 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -54,27 +54,7 @@ cell_create_fs_state(struct pipe_context *pipe, state->shader = *templ; -#if 0 - if (cell->dump_fs) { - tgsi_dump(state->shader.tokens, 0); - } - -#if defined(__i386__) || defined(__386__) - if (cell->use_sse) { - x86_init_func( &state->sse2_program ); - tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program ); - } -#endif - -#ifdef MESA_LLVM - state->llvm_prog = 0; - if (!gallivm_global_cpu_engine()) { - gallivm_cpu_engine_create(state->llvm_prog); - } - else - gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); -#endif -#endif + tgsi_scan_shader(templ->tokens, &state->info); return state; } @@ -113,6 +93,7 @@ cell_create_vs_state(struct pipe_context *pipe, return NULL; state->shader = *templ; + tgsi_scan_shader(templ->tokens, &state->info); state->draw_data = draw_create_vertex_shader(cell->draw, &state->shader); if (state->draw_data == NULL) { -- cgit v1.2.3 From b6ed165748c6585f1368be37c0d0289cead419c9 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 14:32:20 -0600 Subject: gallium: added bypass_vs flag to rasterizer state (may be temporary) --- src/gallium/include/pipe/p_state.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 02c354322d..5791a10119 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -110,6 +110,7 @@ struct pipe_rasterizer_state unsigned line_stipple_pattern:16; unsigned line_last_pixel:1; unsigned bypass_clipping:1; + unsigned bypass_vs:1; /**< vertices are already fully transformed */ unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ float line_width; -- cgit v1.2.3 From 8b8c9acdb747499149e633179a8ad10b0e4206b1 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 14:33:57 -0600 Subject: gallium: added draw_enable_line_stipple() function Allows drivers that implement line stipple to turn off this drawing stage. --- src/gallium/auxiliary/draw/draw_context.c | 12 ++++++++++++ src/gallium/auxiliary/draw/draw_context.h | 3 +++ src/gallium/auxiliary/draw/draw_private.h | 5 +++-- 3 files changed, 18 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index fed2b6e759..3d09d95851 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -85,6 +85,7 @@ struct draw_context *draw_create( void ) /* these defaults are oriented toward the needs of softpipe */ draw->wide_point_threshold = 1000000.0; /* infinity */ draw->wide_line_threshold = 1.0; + draw->line_stipple = TRUE; draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ @@ -254,6 +255,17 @@ draw_wide_line_threshold(struct draw_context *draw, float threshold) } +/** + * Tells the draw module whether or not to implement line stipple. + */ +void +draw_enable_line_stipple(struct draw_context *draw, boolean enable) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->line_stipple = enable; +} + + /** * Ask the draw module for the location/slot of the given vertex attribute in * a post-transformed vertex. diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index df63e91a22..e8e2b56bae 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -94,6 +94,9 @@ void draw_wide_point_threshold(struct draw_context *draw, float threshold); void draw_wide_line_threshold(struct draw_context *draw, float threshold); +void draw_enable_line_stipple(struct draw_context *draw, boolean enable); + + boolean draw_use_sse(struct draw_context *draw); void diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 4147472d45..379b6c3206 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -238,6 +238,7 @@ struct draw_context float wide_point_threshold; /**< convert pnts to tris if larger than this */ float wide_line_threshold; /**< convert lines to tris if wider than this */ + boolean line_stipple; /**< do line stipple? */ boolean use_sse; /* If a prim stage introduces new vertex attributes, they'll be stored here @@ -344,10 +345,10 @@ extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ); extern void draw_vertex_shader_queue_flush( struct draw_context *draw ); -struct tgsi_exec_machine; - extern void draw_update_vertex_fetch( struct draw_context *draw ); +extern boolean draw_need_pipeline(const struct draw_context *draw); + /* Prototype/hack */ -- cgit v1.2.3 From 3faf6230ff4b63833c072ac7afeb43c25d3cba22 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 14:34:35 -0600 Subject: gallium: added draw_need_pipeline() predicate function To test if we need any pipeline stage, or whether we can go into passthrough mode. --- src/gallium/auxiliary/draw/draw_validate.c | 55 +++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index b43295b586..602fa3429d 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -33,6 +33,59 @@ #include "draw_private.h" +/** + * Check if we need any special pipeline stages, or whether prims/verts + * can go through untouched. + */ +boolean +draw_need_pipeline(const struct draw_context *draw) +{ + /* clipping */ + if (!draw->rasterizer->bypass_clipping) + return TRUE; + + /* vertex shader */ + if (!draw->rasterizer->bypass_vs) + return TRUE; + + /* line stipple */ + if (draw->rasterizer->line_stipple_enable && draw->line_stipple) + return TRUE; + + /* wide lines */ + if (draw->rasterizer->line_width > draw->wide_line_threshold) + return TRUE; + + /* large points */ + if (draw->rasterizer->point_size > draw->wide_point_threshold) + return TRUE; + + /* AA lines */ + if (draw->rasterizer->line_smooth && draw->pipeline.aaline) + return TRUE; + + /* AA points */ + if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) + return TRUE; + + /* polygon stipple */ + if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple) + return TRUE; + + /* polygon offset */ + if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw) + return TRUE; + + /* two-side lighting */ + if (draw->rasterizer->light_twoside) + return TRUE; + + /* polygon cull */ + if (draw->rasterizer->cull_mode) + return TRUE; + + return FALSE; +} @@ -92,7 +145,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) next = draw->pipeline.wide_point; } - if (draw->rasterizer->line_stipple_enable) { + if (draw->rasterizer->line_stipple_enable && draw->line_stipple) { draw->pipeline.stipple->next = next; next = draw->pipeline.stipple; precalc_flat = 1; /* only needed for lines really */ -- cgit v1.2.3 From a889928d85ac8ba7e1a7fe15393858a9422cf750 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 13 Mar 2008 16:41:12 -0400 Subject: add a way of removing an exact iterator from the hash --- src/gallium/auxiliary/cso_cache/cso_hash.c | 25 ++++++++++++++++++++++--- src/gallium/auxiliary/cso_cache/cso_hash.h | 16 ++++++++++++++-- 2 files changed, 36 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index 5cad5d3be7..ddce3822f7 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -99,7 +99,7 @@ static void *cso_data_allocate_node(struct cso_hash_data *hash) return MALLOC(hash->nodeSize); } -static void cso_data_free_node(struct cso_node *node) +static void cso_free_node(struct cso_node *node) { FREE(node); } @@ -248,7 +248,7 @@ void cso_hash_delete(struct cso_hash *hash) struct cso_node *cur = *bucket++; while (cur != e_for_x) { struct cso_node *next = cur->next; - cso_data_free_node(cur); + cso_free_node(cur); cur = next; } } @@ -367,7 +367,7 @@ void * cso_hash_take(struct cso_hash *hash, if (*node != hash->data.e) { void *t = (*node)->value; struct cso_node *next = (*node)->next; - cso_data_free_node(*node); + cso_free_node(*node); *node = next; --hash->data.d->size; cso_data_has_shrunk(hash->data.d); @@ -393,3 +393,22 @@ int cso_hash_size(struct cso_hash *hash) { return hash->data.d->size; } + +struct cso_hash_iter cso_hash_erase(struct cso_hash *hash, struct cso_hash_iter iter) +{ + struct cso_hash_iter ret = iter; + struct cso_node *node = iter.node; + struct cso_node **node_ptr; + + if (node == hash->data.e) + return iter; + + ret = cso_hash_iter_next(ret); + node_ptr = (struct cso_node**)(&hash->data.d->buckets[node->key % hash->data.d->numBuckets]); + while (*node_ptr != node) + node_ptr = &(*node_ptr)->next; + *node_ptr = node->next; + cso_free_node(node); + --hash->data.d->size; + return ret; +} diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h index a3a65b68c8..73c4742006 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.h +++ b/src/gallium/auxiliary/cso_cache/cso_hash.h @@ -68,14 +68,26 @@ int cso_hash_size(struct cso_hash *hash); /** - * Create a list of objects and just add entry with the same key to the list. + * Adds a data with the given key to the hash. If entry with the given + * key is already in the hash, this current entry is instered before it + * in the collision list. + * Function returns iterator pointing to the inserted item in the hash. */ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, unsigned key, void *data); +/** + * Removes the item pointed to by the current iterator from the hash. + * Note that the data itself is not erased and if it was a malloc'ed pointer + * it will have to be freed after calling this function by the callee. + * Function returns iterator pointing to the item after the removed one in + * the hash. + */ +struct cso_hash_iter cso_hash_erase(struct cso_hash *hash, struct cso_hash_iter iter); void *cso_hash_take(struct cso_hash *hash, unsigned key); + struct cso_hash_iter cso_hash_first_node(struct cso_hash *hash); /** @@ -97,7 +109,7 @@ struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter); * Convenience routine to iterate over the collision list while doing a memory * comparison to see which entry in the list is a direct copy of our template * and returns that entry. - */ + */ void *cso_hash_find_data_from_template( struct cso_hash *hash, unsigned hash_key, void *templ, -- cgit v1.2.3 From 69c39b9ae28764194a6d310d58aa36b7ac596aa9 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 14:57:19 -0600 Subject: gallium: set surface status to CLEAR or DEFINED in clearing/drawing code. Otherwise, we were never setting these flags. This confused the state tracker. Fixes progs/demos/texenv.c, probably others. --- src/gallium/drivers/softpipe/sp_clear.c | 2 ++ src/gallium/drivers/softpipe/sp_prim_setup.c | 11 +++++++++++ 2 files changed, 13 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c index 8d295a30ca..39aed151c7 100644 --- a/src/gallium/drivers/softpipe/sp_clear.c +++ b/src/gallium/drivers/softpipe/sp_clear.c @@ -55,6 +55,7 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, if (ps == sp_tile_cache_get_surface(softpipe->zsbuf_cache)) { sp_tile_cache_clear(softpipe->zsbuf_cache, clearValue); + softpipe->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_CLEAR; #if TILE_CLEAR_OPTIMIZATION return; #endif @@ -63,6 +64,7 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) { if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) { sp_tile_cache_clear(softpipe->cbuf_cache[i], clearValue); + softpipe->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_CLEAR; } } diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 2feee5c485..7aa9cf8e85 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -1164,11 +1164,22 @@ static void setup_begin( struct draw_stage *stage ) struct setup_stage *setup = setup_stage(stage); struct softpipe_context *sp = setup->softpipe; const struct sp_fragment_shader *fs = setup->softpipe->fs; + uint i; if (sp->dirty) { softpipe_update_derived(sp); } + /* Mark surfaces as defined now */ + for (i = 0; i < sp->framebuffer.num_cbufs; i++){ + if (sp->framebuffer.cbufs[i]) { + sp->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; + } + } + if (sp->framebuffer.zsbuf) { + sp->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; + } + setup->quad.nr_attrs = fs->info.num_inputs; sp->quad.first->begin(sp->quad.first); -- cgit v1.2.3 From 7d5e38a55ae99a4c28873377572f77f383ce0c3e Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 16:53:44 -0600 Subject: gallium: plug in new sp_vbuf_draw_arrays() function Will be used for pass-through mode. Also, call draw_set_render() to register the vbuf stage. Should probably rename that function to something like draw_set_vbuf_stage(). --- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 57 +++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 69bea8a8f5..184aac16f4 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -183,6 +183,60 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) } +/** + * This function is hit when the draw module is working in pass-through mode. + * It's up to us to convert the vertex array into point/line/tri prims. + */ +static void +sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) +{ + struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + struct softpipe_context *softpipe = cvbr->softpipe; + struct draw_stage *setup = softpipe->setup; + struct prim_header prim; + const void *vertex_buffer = cvbr->vertex_buffer; + const unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float); + unsigned i, j; + + prim.det = 0; + prim.reset_line_stipple = 0; + prim.edgeflags = 0; + prim.pad = 0; + +#define VERTEX(I) \ + (struct vertex_header *) ((char *) vertex_buffer + (I) * vertex_size) + + switch (cvbr->prim) { + case PIPE_PRIM_TRIANGLES: + assert(nr % 3 == 0); + for (i = 0; i < nr; i += 3) { + prim.v[0] = VERTEX(i + 0); + prim.v[1] = VERTEX(i + 1); + prim.v[2] = VERTEX(i + 2); + calc_det(&prim); + setup->tri( setup, &prim ); + } + break; + case PIPE_PRIM_POLYGON: + /* draw as tri fan */ + for (i = 2; i < nr; i++) { + prim.v[0] = VERTEX(0); + prim.v[1] = VERTEX(i - 1); + prim.v[2] = VERTEX(i); + calc_det(&prim); + setup->tri( setup, &prim ); + } + break; + default: + /* XXX finish remaining prim types */ + assert(0); + } + +#undef VERTEX +} + + + static void sp_vbuf_destroy(struct vbuf_render *vbr) { @@ -210,6 +264,7 @@ sp_init_vbuf(struct softpipe_context *sp) sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices; sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive; sp->vbuf_render->base.draw = sp_vbuf_draw; + sp->vbuf_render->base.draw_arrays = sp_vbuf_draw_arrays; sp->vbuf_render->base.release_vertices = sp_vbuf_release_vertices; sp->vbuf_render->base.destroy = sp_vbuf_destroy; @@ -218,4 +273,6 @@ sp_init_vbuf(struct softpipe_context *sp) sp->vbuf = draw_vbuf_stage(sp->draw, &sp->vbuf_render->base); draw_set_rasterize_stage(sp->draw, sp->vbuf); + + draw_set_render(sp->draw, &sp->vbuf_render->base); } -- cgit v1.2.3 From b9518a4e39f739a31dd3f62d67563944f8c266a9 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 16:55:48 -0600 Subject: gallium: added new EMIT_HEADER token Used to emit the struct vertex_header info for softpipe. Before we were using the EMIT_ALL token but that's insufficient for the draw pass-through mode. EMIT_ALL might get removed soon... --- src/gallium/auxiliary/draw/draw_vertex.c | 3 +++ src/gallium/auxiliary/draw/draw_vertex.h | 1 + 2 files changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c index daf1ef4b80..970adc95e7 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.c +++ b/src/gallium/auxiliary/draw/draw_vertex.c @@ -52,6 +52,9 @@ draw_compute_vertex_size(struct vertex_info *vinfo) switch (vinfo->emit[i]) { case EMIT_OMIT: break; + case EMIT_HEADER: + vinfo->size += sizeof(struct vertex_header) / 4; + break; case EMIT_4UB: /* fall-through */ case EMIT_1F_PSIZE: diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index 267c74203b..abd2017ed3 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -48,6 +48,7 @@ enum attrib_emit { EMIT_OMIT, /**< don't emit the attribute */ EMIT_ALL, /**< emit whole post-xform vertex, w/ header */ + EMIT_HEADER, /**< emit vertex_header struct (XXX temp?) */ EMIT_1F, EMIT_1F_PSIZE, /**< insert constant point size */ EMIT_2F, -- cgit v1.2.3 From 13334c8dd2744402d43f8ea0a9d2c0e5e76ac28e Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 16:57:37 -0600 Subject: gallium: added EMIT_HEADER case in emit_vertex() --- src/gallium/auxiliary/draw/draw_vbuf.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c index 71ac73912b..f83b441e93 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_vbuf.c @@ -225,6 +225,11 @@ emit_vertex( struct vbuf_stage *vbuf, vbuf->vertex_ptr += vinfo->size; count += vinfo->size; break; + case EMIT_HEADER: + memcpy(vbuf->vertex_ptr, vertex, sizeof(*vertex)); + *vbuf->vertex_ptr += sizeof(*vertex) / 4; + count += sizeof(*vertex) / 4; + break; case EMIT_1F: *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); count++; -- cgit v1.2.3 From 269fbeb5459952532f5d188dd3653fa6b7425cfe Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 16:57:57 -0600 Subject: gallium: in softpipe_get_vertex_info() generate a vbuf vertex_info with real attribs Can't use the EMIT_ALL shortcut/optimization anymore because of passthrough mode. --- src/gallium/drivers/softpipe/sp_state_derived.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index eafbaed4b9..10483675ea 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -72,10 +72,22 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) */ struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; vinfo_vbuf->num_attribs = 0; +#if 0 + /* special-case to allow memcpy of whole vertex */ draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0); /* size in dwords or floats */ vinfo_vbuf->size = 4 * draw_num_vs_outputs(softpipe->draw) + sizeof(struct vertex_header) / 4; +#else + /* for pass-through mode, we need a more explicit list of attribs */ + const uint num = draw_num_vs_outputs(softpipe->draw); + uint i; + draw_emit_vertex_attr(vinfo_vbuf, EMIT_HEADER, INTERP_NONE, 0); + for (i = 0; i < num; i++) { + draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i); + } + draw_compute_vertex_size(vinfo_vbuf); +#endif } /* -- cgit v1.2.3 From cf106789abd4a84e8f07dc6ca12d2261e9bf92cd Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 17:04:04 -0600 Subject: gallium: added EMIT_HEADER case --- src/gallium/auxiliary/draw/draw_vf.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vf.c b/src/gallium/auxiliary/draw/draw_vf.c index 901ff20a7e..4b5b2a86f6 100644 --- a/src/gallium/auxiliary/draw/draw_vf.c +++ b/src/gallium/auxiliary/draw/draw_vf.c @@ -263,6 +263,10 @@ void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, } break; } + case EMIT_HEADER: + /* XXX emit new DRAW_EMIT_HEADER attribute??? */ + count += sizeof(struct vertex_header) / 4; + break; case EMIT_1F: attrs[nr_attrs].attrib = j; attrs[nr_attrs].format = DRAW_EMIT_1F; -- cgit v1.2.3 From ce49c4c24bf72ea642015d566ff687d512574fd5 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 17:04:56 -0600 Subject: gallium: fix bug in draw_num_vs_outputs() --- src/gallium/auxiliary/draw/draw_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 3d09d95851..e8473a4c57 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -311,7 +311,7 @@ uint draw_num_vs_outputs(struct draw_context *draw) { uint count = draw->vertex_shader->info.num_outputs; - if (draw->extra_vp_outputs.slot >= 0) + if (draw->extra_vp_outputs.slot > 0) count++; return count; } -- cgit v1.2.3 From d088d640fca415261a208d3cbede94a6522ebb6b Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 17:10:28 -0600 Subject: gallium: plug in vertex passthrough code Based on a patch from Zack. Basically, implement a new draw_arrays function that copies the incoming user-vertices to the hardware vertex buffer, doing format/type conversion as needed. The vertex fetch/store code is totally temporary for now. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/SConscript | 1 + src/gallium/auxiliary/draw/draw_passthrough.c | 106 ++++++++++++++++++++++++-- src/gallium/auxiliary/draw/draw_prim.c | 47 +++++++++++- 4 files changed, 147 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 2daa1636f3..21e9f737b7 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -15,6 +15,7 @@ C_SOURCES = \ draw_debug.c \ draw_flatshade.c \ draw_offset.c \ + draw_passthrough.c \ draw_prim.c \ draw_pstipple.c \ draw_stipple.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 5cb7664c85..64b444dbd5 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -15,6 +15,7 @@ draw = env.ConvenienceLibrary( 'draw_flatshade.c', 'draw_offset.c', 'draw_prim.c', + 'draw_passthrough.c', 'draw_pstipple.c', 'draw_passthrough.c', 'draw_stipple.c', diff --git a/src/gallium/auxiliary/draw/draw_passthrough.c b/src/gallium/auxiliary/draw/draw_passthrough.c index a51fa0ab23..d16f056191 100644 --- a/src/gallium/auxiliary/draw/draw_passthrough.c +++ b/src/gallium/auxiliary/draw/draw_passthrough.c @@ -66,6 +66,95 @@ #include "draw/draw_vertex.h" +/** + * General-purpose fetch from user's vertex arrays, emit to driver's + * vertex buffer. + * + * XXX this is totally temporary. + */ +static void +fetch_store_general( struct draw_context *draw, + float *out, + unsigned start, + unsigned count ) +{ + const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); + const unsigned nr_attrs = vinfo->num_attribs; + uint i, j; + + const unsigned *pitch = draw->vertex_fetch.pitch; + const ubyte **src = draw->vertex_fetch.src_ptr; + + for (i = start; i < count; i++) { + for (j = 0; j < nr_attrs; j++) { + const uint jj = vinfo->src_index[j]; + const enum pipe_format srcFormat = draw->vertex_element[jj].src_format; + const ubyte *from = src[jj] + i * pitch[jj]; + float attrib[4]; + + switch (srcFormat) { + case PIPE_FORMAT_R32G32B32A32_FLOAT: + { + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = f[1]; + attrib[2] = f[2]; + attrib[3] = f[3]; + } + break; + case PIPE_FORMAT_R32G32B32_FLOAT: + { + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = f[1]; + attrib[2] = f[2]; + attrib[3] = 1.0; + } + break; + case PIPE_FORMAT_R32G32_FLOAT: + { + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = f[1]; + attrib[2] = 0.0; + attrib[3] = 1.0; + } + break; + case PIPE_FORMAT_R32_FLOAT: + { + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = 0.0; + attrib[2] = 0.0; + attrib[3] = 1.0; + } + break; + default: + abort(); + } + + /* XXX this will probably only work for softpipe */ + switch (vinfo->emit[j]) { + case EMIT_HEADER: + memset(out, 0, sizeof(struct vertex_header)); + out += sizeof(struct vertex_header) / 4; + break; + case EMIT_4F: + out[0] = attrib[0]; + out[1] = attrib[1]; + out[2] = attrib[2]; + out[3] = attrib[3]; + out += 4; + break; + default: + abort(); + } + + } + } +} + + /* Example of a fetch/emit passthrough shader which could be * generated when bypass_clipping is enabled on a passthrough vertex @@ -116,7 +205,6 @@ static void fetch_xyz_rgb_st( struct draw_context *draw, } } - static boolean update_shader( struct draw_context *draw ) { const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); @@ -143,11 +231,15 @@ static boolean update_shader( struct draw_context *draw ) /* Just trying to figure out how this would work: */ - if (nr_attrs == 3 && - 0 /* some other tests */) + if (draw->rasterizer->bypass_vs || + (nr_attrs == 3 && 0 /* some other tests */)) { +#if 0 draw->vertex_fetch.pt_fetch = fetch_xyz_rgb_st; - assert(vinfo->size == 10); +#else + draw->vertex_fetch.pt_fetch = fetch_store_general; +#endif + /*assert(vinfo->size == 10);*/ return TRUE; } @@ -175,7 +267,6 @@ static boolean set_prim( struct draw_context *draw, } - boolean draw_passthrough_arrays(struct draw_context *draw, unsigned prim, @@ -184,10 +275,13 @@ draw_passthrough_arrays(struct draw_context *draw, { float *hw_verts; + if (draw_need_pipeline(draw)) + return FALSE; + if (!set_prim(draw, prim)) return FALSE; - if (!update_shader( draw )) + if (!update_shader(draw)) return FALSE; hw_verts = draw->render->allocate_vertices( draw->render, diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index 7d6cd43410..ff71ba9b73 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -31,6 +31,7 @@ */ #include "pipe/p_debug.h" +#include "pipe/p_util.h" #include "draw_private.h" #include "draw_context.h" @@ -118,7 +119,42 @@ static void draw_prim_queue_flush( struct draw_context *draw ) draw_vertex_cache_unreference( draw ); } +static INLINE void fetch_and_store(struct draw_context *draw) +{ + unsigned i; + + /* run vertex shader on vertex cache entries, four per invokation */ +#if 0 + { + const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); + memcpy(draw->vs.queue[0].vertex, draw->vs.queue[i + j].elt, + count * vinfo->size); + } +#elif 0 + draw_update_vertex_fetch(draw); + for (i = 0; i < draw->vs.queue_nr; i += 4) { + struct vertex_header *dests[4]; + unsigned elts[4]; + struct tgsi_exec_machine *machine = &draw->machine; + int j, n = MIN2(4, draw->vs.queue_nr - i); + + for (j = 0; j < n; j++) { + elts[j] = draw->vs.queue[i + j].elt; + dests[j] = draw->vs.queue[i + j].vertex; + } + for ( ; j < 4; j++) { + elts[j] = elts[0]; + dests[j] = draw->vs.queue[i + j].vertex; + } + //fetch directly into dests + draw->vertex_fetch.fetch_func(draw, machine, dests, count); + } +#endif + + draw->vs.post_nr = draw->vs.queue_nr; + draw->vs.queue_nr = 0; +} void draw_do_flush( struct draw_context *draw, unsigned flags ) { @@ -134,7 +170,10 @@ void draw_do_flush( struct draw_context *draw, unsigned flags ) if (flags >= DRAW_FLUSH_SHADER_QUEUE) { if (draw->vs.queue_nr) - (*draw->shader_queue_flush)(draw); + if (draw->rasterizer->bypass_vs) + fetch_and_store(draw); + else + (*draw->shader_queue_flush)(draw); if (flags >= DRAW_FLUSH_PRIM_QUEUE) { if (draw->pq.queue_nr) @@ -485,7 +524,11 @@ draw_arrays(struct draw_context *draw, unsigned prim, } /* drawing done here: */ - draw_prim(draw, prim, start, count); + if (!draw->rasterizer->bypass_vs || + !draw_passthrough_arrays(draw, prim, start, count)) { + /* we have to run the whole pipeline */ + draw_prim(draw, prim, start, count); + } } -- cgit v1.2.3 From 34be3969505d378c5a6734a134f03d094a865c56 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 17:39:30 -0600 Subject: gallium: fix EMIT_HEADER case in draw_vf_set_vertex_info() --- src/gallium/auxiliary/draw/draw_vf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vf.c b/src/gallium/auxiliary/draw/draw_vf.c index 4b5b2a86f6..f4e29a6293 100644 --- a/src/gallium/auxiliary/draw/draw_vf.c +++ b/src/gallium/auxiliary/draw/draw_vf.c @@ -265,7 +265,11 @@ void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, } case EMIT_HEADER: /* XXX emit new DRAW_EMIT_HEADER attribute??? */ - count += sizeof(struct vertex_header) / 4; + attrs[nr_attrs].attrib = 0; + attrs[nr_attrs].format = DRAW_EMIT_PAD; + attrs[nr_attrs].offset = offsetof(struct vertex_header, data); + count += offsetof(struct vertex_header, data)/4; + nr_attrs++; break; case EMIT_1F: attrs[nr_attrs].attrib = j; -- cgit v1.2.3 From 78302c7ca30d27ef3d087deb4d1a22e83858ce4b Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Mar 2008 18:19:47 -0600 Subject: gallium: need to all draw_flush() in softpipe_unmap_constant_buffers() Otherwise, we won't have our constants when we run the fragment shader. Fixes crash in glsl tests when SP_VBUF=1. --- src/gallium/drivers/softpipe/sp_draw_arrays.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 2049afda34..5b5a0fe573 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -62,6 +62,14 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp) { struct pipe_winsys *ws = sp->pipe.winsys; uint i; + + /* really need to flush all prims since the vert/frag shaders const buffers + * are going away now. + */ + draw_flush(sp->draw); + + draw_set_mapped_constant_buffer(sp->draw, NULL); + for (i = 0; i < 2; i++) { if (sp->constants[i].size) ws->buffer_unmap(ws, sp->constants[i].buffer); -- cgit v1.2.3 From d34bc880a4d17420ec20d422dcb461783457c473 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 14 Mar 2008 08:42:08 +0000 Subject: tgsi: add debug_printf version of tgsi_dump --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 22 ++++++++++++++++++++++ src/gallium/auxiliary/tgsi/util/tgsi_dump.h | 4 ++++ 2 files changed, 26 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index aa78278700..7d292778ad 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -1563,3 +1563,25 @@ tgsi_dump_str( *str = dump.text; } + + +void tgsi_debug_dump( struct tgsi_token *tokens ) +{ + char *str, *p; + + tgsi_dump_str( &str, tokens, 0 ); + + p = str; + while (p != NULL) + { + char *end = strchr( p, '\n' ); + if (end != NULL) + { + *end++ = '\0'; + } + debug_printf( "%s\n", p ); + p = end; + } + + FREE( str ); +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h index b983b38226..51d79a0362 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h @@ -20,6 +20,10 @@ tgsi_dump_str( const struct tgsi_token *tokens, unsigned flags ); +/* Dump to debug_printf() + */ +void tgsi_debug_dump( struct tgsi_token *tokens ); + #if defined __cplusplus } #endif -- cgit v1.2.3 From e4cdce43cebe6a2b38f7ea5145474ca2b12c57bb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 14 Mar 2008 08:42:45 +0000 Subject: gallium: fix some compiler warnings --- src/gallium/auxiliary/draw/draw_prim.c | 4 ++-- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 2 +- src/gallium/drivers/softpipe/sp_state_derived.c | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index ff71ba9b73..888fa536ea 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -121,8 +121,6 @@ static void draw_prim_queue_flush( struct draw_context *draw ) static INLINE void fetch_and_store(struct draw_context *draw) { - unsigned i; - /* run vertex shader on vertex cache entries, four per invokation */ #if 0 { @@ -131,6 +129,8 @@ static INLINE void fetch_and_store(struct draw_context *draw) count * vinfo->size); } #elif 0 + unsigned i; + draw_update_vertex_fetch(draw); for (i = 0; i < draw->vs.queue_nr; i += 4) { struct vertex_header *dests[4]; diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 184aac16f4..db0913cb2b 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -196,7 +196,7 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) struct prim_header prim; const void *vertex_buffer = cvbr->vertex_buffer; const unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float); - unsigned i, j; + unsigned i; prim.det = 0; prim.reset_line_stipple = 0; diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 10483675ea..82cb31ece7 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -71,8 +71,8 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) * simply emit the whole post-xform vertex as-is: */ struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; - vinfo_vbuf->num_attribs = 0; #if 0 + vinfo_vbuf->num_attribs = 0; /* special-case to allow memcpy of whole vertex */ draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0); /* size in dwords or floats */ @@ -82,6 +82,8 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) /* for pass-through mode, we need a more explicit list of attribs */ const uint num = draw_num_vs_outputs(softpipe->draw); uint i; + + vinfo_vbuf->num_attribs = 0; draw_emit_vertex_attr(vinfo_vbuf, EMIT_HEADER, INTERP_NONE, 0); for (i = 0; i < num; i++) { draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i); -- cgit v1.2.3 From a254d0c36870724e51e91de3a3da9220b67af850 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 14 Mar 2008 10:22:53 -0600 Subject: gallium: added dummy install target --- src/gallium/winsys/Makefile | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/Makefile b/src/gallium/winsys/Makefile index 3dc5ea5744..2360a6a94a 100644 --- a/src/gallium/winsys/Makefile +++ b/src/gallium/winsys/Makefile @@ -18,3 +18,7 @@ subdirs: clean: rm -f `find . -name \*.[oa]` + + +# Dummy install target +install: -- cgit v1.2.3 From 027433176cddec58821d625fb2df45cfd95f1e33 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 14 Mar 2008 10:23:11 -0600 Subject: i915: check for NULL const buffer ptr --- src/gallium/drivers/i915simple/i915_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 503c092400..1cec36e206 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -516,7 +516,7 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, * stays the same. In that case we should only be updating the first * N constants, leaving any extras from shader translation alone. */ - { + if (buf) { void *mapped; if (buf->size && (mapped = ws->buffer_map(ws, buf->buffer, -- cgit v1.2.3 From 3088eb59497ec8621e003ce3bc87025f257c0a92 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 14 Mar 2008 10:23:39 -0600 Subject: gallium: added some debug code (disabled) --- src/gallium/auxiliary/draw/draw_vs_exec.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 55bec14116..364693e0b4 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -166,6 +166,19 @@ vs_exec_run( struct draw_vertex_shader *shader, vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; } + +#if 0 /*DEBUG*/ + printf("Post xform vert:\n"); + for (slot = 0; slot < draw->num_vs_outputs; slot++) { + printf("%d: %f %f %f %f\n", slot, + vOut[j]->data[slot][0], + vOut[j]->data[slot][1], + vOut[j]->data[slot][2], + vOut[j]->data[slot][3]); + } +#endif + + } /* loop over vertices */ } -- cgit v1.2.3 From 9de9e1fe8c3f87fe672aed074348f07107fa3cec Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 14 Mar 2008 11:24:28 -0600 Subject: gallium: print warning rather than assert(0) for LOG/EXP opcodes Glean vertProg1 runs all the way through, rather than aborting. --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 34 +++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index f2ed9e0353..ad871d2bdf 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -1516,11 +1516,41 @@ exec_instruction( break; case TGSI_OPCODE_EXP: - assert (0); + printf("TGSI: EXP opcode not implemented\n"); + /* from ARB_v_p: + tmp = ScalarLoad(op0); + result.x = 2^floor(tmp); + result.y = tmp - floor(tmp); + result.z = RoughApprox2ToX(tmp); + result.w = 1.0; + */ +#if 0 + /* something like this: */ + FETCH( &r[0], 0, CHAN_X ); + micro_exp2( &r[0], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } +#endif break; case TGSI_OPCODE_LOG: - assert (0); + printf("TGSI: LOG opcode not implemented\n"); + /* from ARB_v_p: + tmp = fabs(ScalarLoad(op0)); + result.x = floor(log2(tmp)); + result.y = tmp / 2^(floor(log2(tmp))); + result.z = RoughApproxLog2(tmp); + result.w = 1.0; + */ +#if 0 + /* something like this: */ + FETCH( &r[0], 0, CHAN_X ); + micro_lg2( &r[0], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } +#endif break; case TGSI_OPCODE_MUL: -- cgit v1.2.3 From 2b8f31a6daf6a52086a3454a5dfd1f8bac046804 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 14 Mar 2008 21:40:02 +0100 Subject: scons: Remove second occurence of draw_passthrough.c. --- src/gallium/auxiliary/draw/SConscript | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 64b444dbd5..d7fb86d992 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -14,10 +14,9 @@ draw = env.ConvenienceLibrary( 'draw_debug.c', 'draw_flatshade.c', 'draw_offset.c', - 'draw_prim.c', 'draw_passthrough.c', + 'draw_prim.c', 'draw_pstipple.c', - 'draw_passthrough.c', 'draw_stipple.c', 'draw_twoside.c', 'draw_unfilled.c', -- cgit v1.2.3 From f23207ca57095b620febaf723815cc3eef3e87bd Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 14 Mar 2008 21:44:06 +0100 Subject: tgsi: Use debug_printf(). --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index ad871d2bdf..78e7dec569 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -1516,7 +1516,7 @@ exec_instruction( break; case TGSI_OPCODE_EXP: - printf("TGSI: EXP opcode not implemented\n"); + debug_printf("TGSI: EXP opcode not implemented\n"); /* from ARB_v_p: tmp = ScalarLoad(op0); result.x = 2^floor(tmp); @@ -1535,7 +1535,7 @@ exec_instruction( break; case TGSI_OPCODE_LOG: - printf("TGSI: LOG opcode not implemented\n"); + debug_printf("TGSI: LOG opcode not implemented\n"); /* from ARB_v_p: tmp = fabs(ScalarLoad(op0)); result.x = floor(log2(tmp)); -- cgit v1.2.3 From 08e341e5dc2e15d8a6c4ba870c9d293295df9467 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 14 Mar 2008 15:54:02 -0600 Subject: gallium: remove DOS carriage returns --- src/gallium/drivers/softpipe/sp_state.h | 390 ++++++++++++++++---------------- 1 file changed, 195 insertions(+), 195 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 45d159143f..0bb1095aec 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -1,195 +1,195 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#ifndef SP_STATE_H -#define SP_STATE_H - -#include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" - - -#define SP_NEW_VIEWPORT 0x1 -#define SP_NEW_RASTERIZER 0x2 -#define SP_NEW_FS 0x4 -#define SP_NEW_BLEND 0x8 -#define SP_NEW_CLIP 0x10 -#define SP_NEW_SCISSOR 0x20 -#define SP_NEW_STIPPLE 0x40 -#define SP_NEW_FRAMEBUFFER 0x80 -#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100 -#define SP_NEW_CONSTANTS 0x200 -#define SP_NEW_SAMPLER 0x400 -#define SP_NEW_TEXTURE 0x800 -#define SP_NEW_VERTEX 0x1000 -#define SP_NEW_VS 0x2000 -#define SP_NEW_QUERY 0x4000 - - -struct tgsi_sampler; -struct tgsi_exec_machine; - - -/** Subclass of pipe_shader_state (though it doesn't really need to be). - * - * This is starting to look an awful lot like a quad pipeline stage... - */ -struct sp_fragment_shader { - struct pipe_shader_state shader; - - struct tgsi_shader_info info; - - void (*prepare)( const struct sp_fragment_shader *shader, - struct tgsi_exec_machine *machine, - struct tgsi_sampler *samplers); - - /* Run the shader - this interface will get cleaned up in the - * future: - */ - unsigned (*run)( const struct sp_fragment_shader *shader, - struct tgsi_exec_machine *machine, - struct quad_header *quad ); - - - void (*delete)( struct sp_fragment_shader * ); -}; - -struct vertex_info; - -/** Subclass of pipe_shader_state */ -struct sp_vertex_shader { - struct pipe_shader_state shader; - struct draw_vertex_shader *draw_data; -}; - - - -void * -softpipe_create_blend_state(struct pipe_context *, - const struct pipe_blend_state *); -void softpipe_bind_blend_state(struct pipe_context *, - void *); -void softpipe_delete_blend_state(struct pipe_context *, - void *); - -void * -softpipe_create_sampler_state(struct pipe_context *, - const struct pipe_sampler_state *); -void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **); -void softpipe_delete_sampler_state(struct pipe_context *, void *); - -void * -softpipe_create_depth_stencil_state(struct pipe_context *, - const struct pipe_depth_stencil_alpha_state *); -void softpipe_bind_depth_stencil_state(struct pipe_context *, void *); -void softpipe_delete_depth_stencil_state(struct pipe_context *, void *); - -void * -softpipe_create_rasterizer_state(struct pipe_context *, - const struct pipe_rasterizer_state *); -void softpipe_bind_rasterizer_state(struct pipe_context *, void *); -void softpipe_delete_rasterizer_state(struct pipe_context *, void *); - -void softpipe_set_framebuffer_state( struct pipe_context *, - const struct pipe_framebuffer_state * ); - -void softpipe_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ); - -void softpipe_set_clip_state( struct pipe_context *, - const struct pipe_clip_state * ); - -void softpipe_set_constant_buffer(struct pipe_context *, - uint shader, uint index, - const struct pipe_constant_buffer *buf); - -void *softpipe_create_fs_state(struct pipe_context *, - const struct pipe_shader_state *); -void softpipe_bind_fs_state(struct pipe_context *, void *); -void softpipe_delete_fs_state(struct pipe_context *, void *); -void *softpipe_create_vs_state(struct pipe_context *, - const struct pipe_shader_state *); -void softpipe_bind_vs_state(struct pipe_context *, void *); -void softpipe_delete_vs_state(struct pipe_context *, void *); - -void softpipe_set_polygon_stipple( struct pipe_context *, - const struct pipe_poly_stipple * ); - -void softpipe_set_scissor_state( struct pipe_context *, - const struct pipe_scissor_state * ); - -void softpipe_set_sampler_textures( struct pipe_context *, - unsigned num, - struct pipe_texture ** ); - -void softpipe_set_viewport_state( struct pipe_context *, - const struct pipe_viewport_state * ); - -void softpipe_set_vertex_element(struct pipe_context *, - unsigned index, - const struct pipe_vertex_element *); - -void softpipe_set_vertex_buffer(struct pipe_context *, - unsigned index, - const struct pipe_vertex_buffer *); - - -void softpipe_update_derived( struct softpipe_context *softpipe ); - - -boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count); - -boolean softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned mode, unsigned start, unsigned count); - - -void -softpipe_map_surfaces(struct softpipe_context *sp); - -void -softpipe_unmap_surfaces(struct softpipe_context *sp); - -void -softpipe_map_texture_surfaces(struct softpipe_context *sp); - -void -softpipe_unmap_texture_surfaces(struct softpipe_context *sp); - - -struct vertex_info * -softpipe_get_vertex_info(struct softpipe_context *softpipe); - -struct vertex_info * -softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe); - - -#endif +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_STATE_H +#define SP_STATE_H + +#include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" + + +#define SP_NEW_VIEWPORT 0x1 +#define SP_NEW_RASTERIZER 0x2 +#define SP_NEW_FS 0x4 +#define SP_NEW_BLEND 0x8 +#define SP_NEW_CLIP 0x10 +#define SP_NEW_SCISSOR 0x20 +#define SP_NEW_STIPPLE 0x40 +#define SP_NEW_FRAMEBUFFER 0x80 +#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100 +#define SP_NEW_CONSTANTS 0x200 +#define SP_NEW_SAMPLER 0x400 +#define SP_NEW_TEXTURE 0x800 +#define SP_NEW_VERTEX 0x1000 +#define SP_NEW_VS 0x2000 +#define SP_NEW_QUERY 0x4000 + + +struct tgsi_sampler; +struct tgsi_exec_machine; + + +/** Subclass of pipe_shader_state (though it doesn't really need to be). + * + * This is starting to look an awful lot like a quad pipeline stage... + */ +struct sp_fragment_shader { + struct pipe_shader_state shader; + + struct tgsi_shader_info info; + + void (*prepare)( const struct sp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct tgsi_sampler *samplers); + + /* Run the shader - this interface will get cleaned up in the + * future: + */ + unsigned (*run)( const struct sp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct quad_header *quad ); + + + void (*delete)( struct sp_fragment_shader * ); +}; + +struct vertex_info; + +/** Subclass of pipe_shader_state */ +struct sp_vertex_shader { + struct pipe_shader_state shader; + struct draw_vertex_shader *draw_data; +}; + + + +void * +softpipe_create_blend_state(struct pipe_context *, + const struct pipe_blend_state *); +void softpipe_bind_blend_state(struct pipe_context *, + void *); +void softpipe_delete_blend_state(struct pipe_context *, + void *); + +void * +softpipe_create_sampler_state(struct pipe_context *, + const struct pipe_sampler_state *); +void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **); +void softpipe_delete_sampler_state(struct pipe_context *, void *); + +void * +softpipe_create_depth_stencil_state(struct pipe_context *, + const struct pipe_depth_stencil_alpha_state *); +void softpipe_bind_depth_stencil_state(struct pipe_context *, void *); +void softpipe_delete_depth_stencil_state(struct pipe_context *, void *); + +void * +softpipe_create_rasterizer_state(struct pipe_context *, + const struct pipe_rasterizer_state *); +void softpipe_bind_rasterizer_state(struct pipe_context *, void *); +void softpipe_delete_rasterizer_state(struct pipe_context *, void *); + +void softpipe_set_framebuffer_state( struct pipe_context *, + const struct pipe_framebuffer_state * ); + +void softpipe_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ); + +void softpipe_set_clip_state( struct pipe_context *, + const struct pipe_clip_state * ); + +void softpipe_set_constant_buffer(struct pipe_context *, + uint shader, uint index, + const struct pipe_constant_buffer *buf); + +void *softpipe_create_fs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_fs_state(struct pipe_context *, void *); +void softpipe_delete_fs_state(struct pipe_context *, void *); +void *softpipe_create_vs_state(struct pipe_context *, + const struct pipe_shader_state *); +void softpipe_bind_vs_state(struct pipe_context *, void *); +void softpipe_delete_vs_state(struct pipe_context *, void *); + +void softpipe_set_polygon_stipple( struct pipe_context *, + const struct pipe_poly_stipple * ); + +void softpipe_set_scissor_state( struct pipe_context *, + const struct pipe_scissor_state * ); + +void softpipe_set_sampler_textures( struct pipe_context *, + unsigned num, + struct pipe_texture ** ); + +void softpipe_set_viewport_state( struct pipe_context *, + const struct pipe_viewport_state * ); + +void softpipe_set_vertex_element(struct pipe_context *, + unsigned index, + const struct pipe_vertex_element *); + +void softpipe_set_vertex_buffer(struct pipe_context *, + unsigned index, + const struct pipe_vertex_buffer *); + + +void softpipe_update_derived( struct softpipe_context *softpipe ); + + +boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count); + +boolean softpipe_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count); + + +void +softpipe_map_surfaces(struct softpipe_context *sp); + +void +softpipe_unmap_surfaces(struct softpipe_context *sp); + +void +softpipe_map_texture_surfaces(struct softpipe_context *sp); + +void +softpipe_unmap_texture_surfaces(struct softpipe_context *sp); + + +struct vertex_info * +softpipe_get_vertex_info(struct softpipe_context *softpipe); + +struct vertex_info * +softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe); + + +#endif -- cgit v1.2.3 From 344356a0edee932604027386591c82f6666e607c Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 14 Mar 2008 16:00:15 -0600 Subject: gallium: remove DOS carriage returns --- src/gallium/drivers/softpipe/sp_context.c | 486 +++++++++++++++--------------- src/gallium/drivers/softpipe/sp_quad_fs.c | 418 ++++++++++++------------- src/gallium/drivers/softpipe/sp_texture.c | 404 ++++++++++++------------- 3 files changed, 654 insertions(+), 654 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 316ae552b8..16fb06f176 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -1,243 +1,243 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Author: - * Keith Whitwell - */ - -#include "draw/draw_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/p_util.h" -#include "sp_clear.h" -#include "sp_context.h" -#include "sp_flush.h" -#include "sp_prim_setup.h" -#include "sp_prim_vbuf.h" -#include "sp_state.h" -#include "sp_surface.h" -#include "sp_tile_cache.h" -#include "sp_texture.h" -#include "sp_winsys.h" -#include "sp_query.h" - - - -/** - * Map any drawing surfaces which aren't already mapped - */ -void -softpipe_map_surfaces(struct softpipe_context *sp) -{ - unsigned i; - - for (i = 0; i < sp->framebuffer.num_cbufs; i++) { - sp_tile_cache_map_surfaces(sp->cbuf_cache[i]); - } - - sp_tile_cache_map_surfaces(sp->zsbuf_cache); -} - - -/** - * Unmap any mapped drawing surfaces - */ -void -softpipe_unmap_surfaces(struct softpipe_context *sp) -{ - uint i; - - for (i = 0; i < sp->framebuffer.num_cbufs; i++) - sp_flush_tile_cache(sp, sp->cbuf_cache[i]); - sp_flush_tile_cache(sp, sp->zsbuf_cache); - - for (i = 0; i < sp->framebuffer.num_cbufs; i++) { - sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]); - } - sp_tile_cache_unmap_surfaces(sp->zsbuf_cache); -} - - -static void softpipe_destroy( struct pipe_context *pipe ) -{ - struct softpipe_context *softpipe = softpipe_context( pipe ); - struct pipe_winsys *ws = pipe->winsys; - uint i; - - draw_destroy( softpipe->draw ); - - softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); - softpipe->quad.earlyz->destroy( softpipe->quad.earlyz ); - softpipe->quad.shade->destroy( softpipe->quad.shade ); - softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test ); - softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); - softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test ); - softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); - softpipe->quad.coverage->destroy( softpipe->quad.coverage ); - softpipe->quad.bufloop->destroy( softpipe->quad.bufloop ); - softpipe->quad.blend->destroy( softpipe->quad.blend ); - softpipe->quad.colormask->destroy( softpipe->quad.colormask ); - softpipe->quad.output->destroy( softpipe->quad.output ); - - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - sp_destroy_tile_cache(softpipe->cbuf_cache[i]); - sp_destroy_tile_cache(softpipe->zsbuf_cache); - - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - sp_destroy_tile_cache(softpipe->tex_cache[i]); - - for (i = 0; i < Elements(softpipe->constants); i++) { - if (softpipe->constants[i].buffer) { - pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL); - } - } - - FREE( softpipe ); -} - - -struct pipe_context * -softpipe_create( struct pipe_screen *screen, - struct pipe_winsys *pipe_winsys, - struct softpipe_winsys *softpipe_winsys ) -{ - struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); - uint i; - -#if defined(__i386__) || defined(__386__) - softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; -#else - softpipe->use_sse = FALSE; -#endif - - softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL; - - softpipe->pipe.winsys = pipe_winsys; - softpipe->pipe.screen = screen; - softpipe->pipe.destroy = softpipe_destroy; - - /* state setters */ - softpipe->pipe.create_blend_state = softpipe_create_blend_state; - softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; - softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; - - softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; - softpipe->pipe.bind_sampler_states = softpipe_bind_sampler_states; - softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; - - softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state; - softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state; - softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state; - - softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state; - softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state; - softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state; - - softpipe->pipe.create_fs_state = softpipe_create_fs_state; - softpipe->pipe.bind_fs_state = softpipe_bind_fs_state; - softpipe->pipe.delete_fs_state = softpipe_delete_fs_state; - - softpipe->pipe.create_vs_state = softpipe_create_vs_state; - softpipe->pipe.bind_vs_state = softpipe_bind_vs_state; - softpipe->pipe.delete_vs_state = softpipe_delete_vs_state; - - softpipe->pipe.set_blend_color = softpipe_set_blend_color; - softpipe->pipe.set_clip_state = softpipe_set_clip_state; - softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; - softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; - softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; - softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; - softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures; - softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; - - softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer; - softpipe->pipe.set_vertex_element = softpipe_set_vertex_element; - - softpipe->pipe.draw_arrays = softpipe_draw_arrays; - softpipe->pipe.draw_elements = softpipe_draw_elements; - - softpipe->pipe.clear = softpipe_clear; - softpipe->pipe.flush = softpipe_flush; - - softpipe_init_query_funcs( softpipe ); - softpipe_init_texture_funcs( softpipe ); - - /* - * Alloc caches for accessing drawing surfaces and textures. - * Must be before quad stage setup! - */ - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - softpipe->cbuf_cache[i] = sp_create_tile_cache(); - softpipe->zsbuf_cache = sp_create_tile_cache(); - - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - softpipe->tex_cache[i] = sp_create_tile_cache(); - - - /* setup quad rendering stages */ - softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); - softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe); - softpipe->quad.shade = sp_quad_shade_stage(softpipe); - softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe); - softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); - softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); - softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); - softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); - softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe); - softpipe->quad.blend = sp_quad_blend_stage(softpipe); - softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); - softpipe->quad.output = sp_quad_output_stage(softpipe); - - softpipe->winsys = softpipe_winsys; - - /* - * Create drawing context and plug our rendering stage into it. - */ - softpipe->draw = draw_create(); - assert(softpipe->draw); - softpipe->setup = sp_draw_render_stage(softpipe); - - if (GETENV( "SP_VBUF" ) != NULL) { - sp_init_vbuf(softpipe); - } - else { - draw_set_rasterize_stage(softpipe->draw, softpipe->setup); - } - - /* plug in AA line/point stages */ - draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); - draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); - -#if USE_DRAW_STAGE_PSTIPPLE - /* Do polygon stipple w/ texture map + frag prog? */ - draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); -#endif - - sp_init_surface_functions(softpipe); - - return &softpipe->pipe; -} +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "sp_clear.h" +#include "sp_context.h" +#include "sp_flush.h" +#include "sp_prim_setup.h" +#include "sp_prim_vbuf.h" +#include "sp_state.h" +#include "sp_surface.h" +#include "sp_tile_cache.h" +#include "sp_texture.h" +#include "sp_winsys.h" +#include "sp_query.h" + + + +/** + * Map any drawing surfaces which aren't already mapped + */ +void +softpipe_map_surfaces(struct softpipe_context *sp) +{ + unsigned i; + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) { + sp_tile_cache_map_surfaces(sp->cbuf_cache[i]); + } + + sp_tile_cache_map_surfaces(sp->zsbuf_cache); +} + + +/** + * Unmap any mapped drawing surfaces + */ +void +softpipe_unmap_surfaces(struct softpipe_context *sp) +{ + uint i; + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) + sp_flush_tile_cache(sp, sp->cbuf_cache[i]); + sp_flush_tile_cache(sp, sp->zsbuf_cache); + + for (i = 0; i < sp->framebuffer.num_cbufs; i++) { + sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]); + } + sp_tile_cache_unmap_surfaces(sp->zsbuf_cache); +} + + +static void softpipe_destroy( struct pipe_context *pipe ) +{ + struct softpipe_context *softpipe = softpipe_context( pipe ); + struct pipe_winsys *ws = pipe->winsys; + uint i; + + draw_destroy( softpipe->draw ); + + softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); + softpipe->quad.earlyz->destroy( softpipe->quad.earlyz ); + softpipe->quad.shade->destroy( softpipe->quad.shade ); + softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test ); + softpipe->quad.depth_test->destroy( softpipe->quad.depth_test ); + softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test ); + softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); + softpipe->quad.coverage->destroy( softpipe->quad.coverage ); + softpipe->quad.bufloop->destroy( softpipe->quad.bufloop ); + softpipe->quad.blend->destroy( softpipe->quad.blend ); + softpipe->quad.colormask->destroy( softpipe->quad.colormask ); + softpipe->quad.output->destroy( softpipe->quad.output ); + + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + sp_destroy_tile_cache(softpipe->cbuf_cache[i]); + sp_destroy_tile_cache(softpipe->zsbuf_cache); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + sp_destroy_tile_cache(softpipe->tex_cache[i]); + + for (i = 0; i < Elements(softpipe->constants); i++) { + if (softpipe->constants[i].buffer) { + pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL); + } + } + + FREE( softpipe ); +} + + +struct pipe_context * +softpipe_create( struct pipe_screen *screen, + struct pipe_winsys *pipe_winsys, + struct softpipe_winsys *softpipe_winsys ) +{ + struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); + uint i; + +#if defined(__i386__) || defined(__386__) + softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; +#else + softpipe->use_sse = FALSE; +#endif + + softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL; + + softpipe->pipe.winsys = pipe_winsys; + softpipe->pipe.screen = screen; + softpipe->pipe.destroy = softpipe_destroy; + + /* state setters */ + softpipe->pipe.create_blend_state = softpipe_create_blend_state; + softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; + softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; + + softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; + softpipe->pipe.bind_sampler_states = softpipe_bind_sampler_states; + softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; + + softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state; + softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state; + softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state; + + softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state; + softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state; + softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state; + + softpipe->pipe.create_fs_state = softpipe_create_fs_state; + softpipe->pipe.bind_fs_state = softpipe_bind_fs_state; + softpipe->pipe.delete_fs_state = softpipe_delete_fs_state; + + softpipe->pipe.create_vs_state = softpipe_create_vs_state; + softpipe->pipe.bind_vs_state = softpipe_bind_vs_state; + softpipe->pipe.delete_vs_state = softpipe_delete_vs_state; + + softpipe->pipe.set_blend_color = softpipe_set_blend_color; + softpipe->pipe.set_clip_state = softpipe_set_clip_state; + softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; + softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; + softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; + softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; + softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures; + softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; + + softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer; + softpipe->pipe.set_vertex_element = softpipe_set_vertex_element; + + softpipe->pipe.draw_arrays = softpipe_draw_arrays; + softpipe->pipe.draw_elements = softpipe_draw_elements; + + softpipe->pipe.clear = softpipe_clear; + softpipe->pipe.flush = softpipe_flush; + + softpipe_init_query_funcs( softpipe ); + softpipe_init_texture_funcs( softpipe ); + + /* + * Alloc caches for accessing drawing surfaces and textures. + * Must be before quad stage setup! + */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + softpipe->cbuf_cache[i] = sp_create_tile_cache(); + softpipe->zsbuf_cache = sp_create_tile_cache(); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + softpipe->tex_cache[i] = sp_create_tile_cache(); + + + /* setup quad rendering stages */ + softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); + softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe); + softpipe->quad.shade = sp_quad_shade_stage(softpipe); + softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe); + softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); + softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); + softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); + softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); + softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe); + softpipe->quad.blend = sp_quad_blend_stage(softpipe); + softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); + softpipe->quad.output = sp_quad_output_stage(softpipe); + + softpipe->winsys = softpipe_winsys; + + /* + * Create drawing context and plug our rendering stage into it. + */ + softpipe->draw = draw_create(); + assert(softpipe->draw); + softpipe->setup = sp_draw_render_stage(softpipe); + + if (GETENV( "SP_VBUF" ) != NULL) { + sp_init_vbuf(softpipe); + } + else { + draw_set_rasterize_stage(softpipe->draw, softpipe->setup); + } + + /* plug in AA line/point stages */ + draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); + draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); + +#if USE_DRAW_STAGE_PSTIPPLE + /* Do polygon stipple w/ texture map + frag prog? */ + draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); +#endif + + sp_init_surface_functions(softpipe); + + return &softpipe->pipe; +} diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 9198198db3..861285101f 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -1,209 +1,209 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Vertices are just an array of floats, with all the attributes - * packed. We currently assume a layout like: - * - * attr[0][0..3] - window position - * attr[1..n][0..3] - remaining attributes. - * - * Attributes are assumed to be 4 floats wide but are packed so that - * all the enabled attributes run contiguously. - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" - -#include "sp_context.h" -#include "sp_state.h" -#include "sp_headers.h" -#include "sp_quad.h" -#include "sp_texture.h" -#include "sp_tex_sample.h" - - -struct quad_shade_stage -{ - struct quad_stage stage; - struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS]; - struct tgsi_exec_machine machine; - struct tgsi_exec_vector *inputs, *outputs; - int colorOutSlot, depthOutSlot; -}; - - -/** cast wrapper */ -static INLINE struct quad_shade_stage * -quad_shade_stage(struct quad_stage *qs) -{ - return (struct quad_shade_stage *) qs; -} - - - -/** - * Execute fragment shader for the four fragments in the quad. - */ -static void -shade_quad( - struct quad_stage *qs, - struct quad_header *quad ) -{ - struct quad_shade_stage *qss = quad_shade_stage( qs ); - struct softpipe_context *softpipe = qs->softpipe; - struct tgsi_exec_machine *machine = &qss->machine; - - /* Consts do not require 16 byte alignment. */ - machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; - - machine->InterpCoefs = quad->coef; - - /* run shader */ - quad->mask &= softpipe->fs->run( softpipe->fs, - &qss->machine, - quad ); - - /* store result color */ - if (qss->colorOutSlot >= 0) { - /* XXX need to handle multiple color outputs someday */ - assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] - == TGSI_SEMANTIC_COLOR); - memcpy( - quad->outputs.color, - &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0], - sizeof( quad->outputs.color ) ); - } - - /* - * XXX the following code for updating quad->outputs.depth - * isn't really needed if we did early z testing. - */ - - /* store result Z */ - if (qss->depthOutSlot >= 0) { - /* output[slot] is new Z */ - uint i; - for (i = 0; i < 4; i++) { - quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i]; - } - } - else { - /* copy input Z (which was interpolated by the executor) to output Z */ - uint i; - for (i = 0; i < 4; i++) { - quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i]; - /* XXX not sure the above line is always correct. The following - * might be better: - quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i]; - */ - } - } - - /* shader may cull fragments */ - if( quad->mask ) { - qs->next->run( qs->next, quad ); - } -} - -/** - * Per-primitive (or per-begin?) setup - */ -static void shade_begin(struct quad_stage *qs) -{ - struct quad_shade_stage *qss = quad_shade_stage(qs); - struct softpipe_context *softpipe = qs->softpipe; - unsigned i; - unsigned num = MAX2(softpipe->num_textures, softpipe->num_samplers); - - /* set TGSI sampler state that varies */ - for (i = 0; i < num; i++) { - qss->samplers[i].state = softpipe->sampler[i]; - qss->samplers[i].texture = softpipe->texture[i]; - } - - /* find output slots for depth, color */ - qss->colorOutSlot = -1; - qss->depthOutSlot = -1; - for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) { - switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) { - case TGSI_SEMANTIC_POSITION: - qss->depthOutSlot = i; - break; - case TGSI_SEMANTIC_COLOR: - qss->colorOutSlot = i; - break; - } - } - - softpipe->fs->prepare( softpipe->fs, - &qss->machine, - qss->samplers ); - - qs->next->begin(qs->next); -} - - -static void shade_destroy(struct quad_stage *qs) -{ - struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; - - tgsi_exec_machine_free_data(&qss->machine); - FREE( qss->inputs ); - FREE( qss->outputs ); - FREE( qs ); -} - - -struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) -{ - struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); - uint i; - - /* allocate storage for program inputs/outputs, aligned to 16 bytes */ - qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16); - qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16); - qss->machine.Inputs = align16(qss->inputs); - qss->machine.Outputs = align16(qss->outputs); - - qss->stage.softpipe = softpipe; - qss->stage.begin = shade_begin; - qss->stage.run = shade_quad; - qss->stage.destroy = shade_destroy; - - /* set TGSI sampler state that's constant */ - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - assert(softpipe->tex_cache[i]); - qss->samplers[i].get_samples = sp_get_samples; - qss->samplers[i].pipe = &softpipe->pipe; - qss->samplers[i].cache = softpipe->tex_cache[i]; - } - - tgsi_exec_machine_init( &qss->machine ); - - return &qss->stage; -} +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Vertices are just an array of floats, with all the attributes + * packed. We currently assume a layout like: + * + * attr[0][0..3] - window position + * attr[1..n][0..3] - remaining attributes. + * + * Attributes are assumed to be 4 floats wide but are packed so that + * all the enabled attributes run contiguously. + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_headers.h" +#include "sp_quad.h" +#include "sp_texture.h" +#include "sp_tex_sample.h" + + +struct quad_shade_stage +{ + struct quad_stage stage; + struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS]; + struct tgsi_exec_machine machine; + struct tgsi_exec_vector *inputs, *outputs; + int colorOutSlot, depthOutSlot; +}; + + +/** cast wrapper */ +static INLINE struct quad_shade_stage * +quad_shade_stage(struct quad_stage *qs) +{ + return (struct quad_shade_stage *) qs; +} + + + +/** + * Execute fragment shader for the four fragments in the quad. + */ +static void +shade_quad( + struct quad_stage *qs, + struct quad_header *quad ) +{ + struct quad_shade_stage *qss = quad_shade_stage( qs ); + struct softpipe_context *softpipe = qs->softpipe; + struct tgsi_exec_machine *machine = &qss->machine; + + /* Consts do not require 16 byte alignment. */ + machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; + + machine->InterpCoefs = quad->coef; + + /* run shader */ + quad->mask &= softpipe->fs->run( softpipe->fs, + &qss->machine, + quad ); + + /* store result color */ + if (qss->colorOutSlot >= 0) { + /* XXX need to handle multiple color outputs someday */ + assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] + == TGSI_SEMANTIC_COLOR); + memcpy( + quad->outputs.color, + &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0], + sizeof( quad->outputs.color ) ); + } + + /* + * XXX the following code for updating quad->outputs.depth + * isn't really needed if we did early z testing. + */ + + /* store result Z */ + if (qss->depthOutSlot >= 0) { + /* output[slot] is new Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i]; + } + } + else { + /* copy input Z (which was interpolated by the executor) to output Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i]; + /* XXX not sure the above line is always correct. The following + * might be better: + quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i]; + */ + } + } + + /* shader may cull fragments */ + if( quad->mask ) { + qs->next->run( qs->next, quad ); + } +} + +/** + * Per-primitive (or per-begin?) setup + */ +static void shade_begin(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = quad_shade_stage(qs); + struct softpipe_context *softpipe = qs->softpipe; + unsigned i; + unsigned num = MAX2(softpipe->num_textures, softpipe->num_samplers); + + /* set TGSI sampler state that varies */ + for (i = 0; i < num; i++) { + qss->samplers[i].state = softpipe->sampler[i]; + qss->samplers[i].texture = softpipe->texture[i]; + } + + /* find output slots for depth, color */ + qss->colorOutSlot = -1; + qss->depthOutSlot = -1; + for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) { + switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + qss->depthOutSlot = i; + break; + case TGSI_SEMANTIC_COLOR: + qss->colorOutSlot = i; + break; + } + } + + softpipe->fs->prepare( softpipe->fs, + &qss->machine, + qss->samplers ); + + qs->next->begin(qs->next); +} + + +static void shade_destroy(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; + + tgsi_exec_machine_free_data(&qss->machine); + FREE( qss->inputs ); + FREE( qss->outputs ); + FREE( qs ); +} + + +struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) +{ + struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); + uint i; + + /* allocate storage for program inputs/outputs, aligned to 16 bytes */ + qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16); + qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16); + qss->machine.Inputs = align16(qss->inputs); + qss->machine.Outputs = align16(qss->outputs); + + qss->stage.softpipe = softpipe; + qss->stage.begin = shade_begin; + qss->stage.run = shade_quad; + qss->stage.destroy = shade_destroy; + + /* set TGSI sampler state that's constant */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + assert(softpipe->tex_cache[i]); + qss->samplers[i].get_samples = sp_get_samples; + qss->samplers[i].pipe = &softpipe->pipe; + qss->samplers[i].cache = softpipe->tex_cache[i]; + } + + tgsi_exec_machine_init( &qss->machine ); + + return &qss->stage; +} diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index bbf2d80308..64bf353aa4 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -1,202 +1,202 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - /* - * Authors: - * Keith Whitwell - * Michel Dänzer - */ - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_inlines.h" -#include "pipe/p_util.h" -#include "pipe/p_winsys.h" - -#include "sp_context.h" -#include "sp_state.h" -#include "sp_texture.h" -#include "sp_tile_cache.h" - - -/* Simple, maximally packed layout. - */ - -static unsigned minify( unsigned d ) -{ - return MAX2(1, d>>1); -} - - -static void -softpipe_texture_layout(struct softpipe_texture * spt) -{ - struct pipe_texture *pt = &spt->base; - unsigned level; - unsigned width = pt->width[0]; - unsigned height = pt->height[0]; - unsigned depth = pt->depth[0]; - - spt->buffer_size = 0; - - for (level = 0; level <= pt->last_level; level++) { - pt->width[level] = width; - pt->height[level] = height; - pt->depth[level] = depth; - - spt->level_offset[level] = spt->buffer_size; - - spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * - ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * - width * pt->cpp; - - width = minify(width); - height = minify(height); - depth = minify(depth); - } -} - - -static struct pipe_texture * -softpipe_texture_create_screen(struct pipe_screen *screen, - const struct pipe_texture *templat) -{ - struct pipe_winsys *ws = screen->winsys; - struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); - if (!spt) - return NULL; - - spt->base = *templat; - spt->base.refcount = 1; - spt->base.screen = screen; - - softpipe_texture_layout(spt); - - spt->buffer = ws->buffer_create(ws, 32, - PIPE_BUFFER_USAGE_PIXEL, - spt->buffer_size); - if (!spt->buffer) { - FREE(spt); - return NULL; - } - - assert(spt->base.refcount == 1); - - return &spt->base; -} - - -static void -softpipe_texture_release_screen(struct pipe_screen *screen, - struct pipe_texture **pt) -{ - if (!*pt) - return; - - /* - DBG("%s %p refcount will be %d\n", - __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); - */ - if (--(*pt)->refcount <= 0) { - struct softpipe_texture *spt = softpipe_texture(*pt); - - /* - DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); - */ - - pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); - - FREE(spt); - } - *pt = NULL; -} - - -static struct pipe_surface * -softpipe_get_tex_surface_screen(struct pipe_screen *screen, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct pipe_winsys *ws = screen->winsys; - struct softpipe_texture *spt = softpipe_texture(pt); - struct pipe_surface *ps; - - assert(level <= pt->last_level); - - ps = ws->surface_alloc(ws); - if (ps) { - assert(ps->refcount); - assert(ps->winsys); - pipe_buffer_reference(ws, &ps->buffer, spt->buffer); - ps->format = pt->format; - ps->cpp = pt->cpp; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - ps->pitch = ps->width; - ps->offset = spt->level_offset[level]; - - if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { - ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * - (pt->compressed ? ps->height/4 : ps->height) * - ps->width * ps->cpp; - } - else { - assert(face == 0); - assert(zslice == 0); - } - } - return ps; -} - - -static void -softpipe_texture_update(struct pipe_context *pipe, - struct pipe_texture *texture) -{ - struct softpipe_context *softpipe = softpipe_context(pipe); - uint unit; - for (unit = 0; unit < softpipe->num_textures; unit++) { - if (softpipe->texture[unit] == texture) { - sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); - } - } -} - - -void -softpipe_init_texture_funcs( struct softpipe_context *softpipe ) -{ - softpipe->pipe.texture_update = softpipe_texture_update; -} - - -void -softpipe_init_screen_texture_funcs(struct pipe_screen *screen) -{ - screen->texture_create = softpipe_texture_create_screen; - screen->texture_release = softpipe_texture_release_screen; - screen->get_tex_surface = softpipe_get_tex_surface_screen; -} +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell + * Michel Dänzer + */ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_texture.h" +#include "sp_tile_cache.h" + + +/* Simple, maximally packed layout. + */ + +static unsigned minify( unsigned d ) +{ + return MAX2(1, d>>1); +} + + +static void +softpipe_texture_layout(struct softpipe_texture * spt) +{ + struct pipe_texture *pt = &spt->base; + unsigned level; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; + + spt->buffer_size = 0; + + for (level = 0; level <= pt->last_level; level++) { + pt->width[level] = width; + pt->height[level] = height; + pt->depth[level] = depth; + + spt->level_offset[level] = spt->buffer_size; + + spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * + ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * + width * pt->cpp; + + width = minify(width); + height = minify(height); + depth = minify(depth); + } +} + + +static struct pipe_texture * +softpipe_texture_create_screen(struct pipe_screen *screen, + const struct pipe_texture *templat) +{ + struct pipe_winsys *ws = screen->winsys; + struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); + if (!spt) + return NULL; + + spt->base = *templat; + spt->base.refcount = 1; + spt->base.screen = screen; + + softpipe_texture_layout(spt); + + spt->buffer = ws->buffer_create(ws, 32, + PIPE_BUFFER_USAGE_PIXEL, + spt->buffer_size); + if (!spt->buffer) { + FREE(spt); + return NULL; + } + + assert(spt->base.refcount == 1); + + return &spt->base; +} + + +static void +softpipe_texture_release_screen(struct pipe_screen *screen, + struct pipe_texture **pt) +{ + if (!*pt) + return; + + /* + DBG("%s %p refcount will be %d\n", + __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); + */ + if (--(*pt)->refcount <= 0) { + struct softpipe_texture *spt = softpipe_texture(*pt); + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); + */ + + pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); + + FREE(spt); + } + *pt = NULL; +} + + +static struct pipe_surface * +softpipe_get_tex_surface_screen(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = screen->winsys; + struct softpipe_texture *spt = softpipe_texture(pt); + struct pipe_surface *ps; + + assert(level <= pt->last_level); + + ps = ws->surface_alloc(ws); + if (ps) { + assert(ps->refcount); + assert(ps->winsys); + pipe_buffer_reference(ws, &ps->buffer, spt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = ps->width; + ps->offset = spt->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { + ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * + (pt->compressed ? ps->height/4 : ps->height) * + ps->width * ps->cpp; + } + else { + assert(face == 0); + assert(zslice == 0); + } + } + return ps; +} + + +static void +softpipe_texture_update(struct pipe_context *pipe, + struct pipe_texture *texture) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint unit; + for (unit = 0; unit < softpipe->num_textures; unit++) { + if (softpipe->texture[unit] == texture) { + sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); + } + } +} + + +void +softpipe_init_texture_funcs( struct softpipe_context *softpipe ) +{ + softpipe->pipe.texture_update = softpipe_texture_update; +} + + +void +softpipe_init_screen_texture_funcs(struct pipe_screen *screen) +{ + screen->texture_create = softpipe_texture_create_screen; + screen->texture_release = softpipe_texture_release_screen; + screen->get_tex_surface = softpipe_get_tex_surface_screen; +} -- cgit v1.2.3 From 5a09ad8248ce452136ed96a3d46532b03c877618 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 14 Mar 2008 16:13:35 -0600 Subject: gallium: add explicit control for point sprites (convert points to textured quads) New draw_enable_point_sprites() function. Fixes spriteblast.c demo --- src/gallium/auxiliary/draw/draw_context.c | 12 ++++++++++++ src/gallium/auxiliary/draw/draw_context.h | 2 ++ src/gallium/auxiliary/draw/draw_private.h | 1 + src/gallium/auxiliary/draw/draw_validate.c | 8 +++++++- src/gallium/auxiliary/draw/draw_wide_point.c | 3 ++- 5 files changed, 24 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index e8473a4c57..4cca965ac1 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -86,6 +86,7 @@ struct draw_context *draw_create( void ) draw->wide_point_threshold = 1000000.0; /* infinity */ draw->wide_line_threshold = 1.0; draw->line_stipple = TRUE; + draw->point_sprite = TRUE; draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ @@ -266,6 +267,17 @@ draw_enable_line_stipple(struct draw_context *draw, boolean enable) } +/** + * Tells draw module whether to convert points to quads for sprite mode. + */ +void +draw_enable_point_sprites(struct draw_context *draw, boolean enable) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->point_sprite = enable; +} + + /** * Ask the draw module for the location/slot of the given vertex attribute in * a post-transformed vertex. diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index e8e2b56bae..dae687e590 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -96,6 +96,8 @@ void draw_wide_line_threshold(struct draw_context *draw, float threshold); void draw_enable_line_stipple(struct draw_context *draw, boolean enable); +void draw_enable_point_sprites(struct draw_context *draw, boolean enable); + boolean draw_use_sse(struct draw_context *draw); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 379b6c3206..1c65c3d1b2 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -239,6 +239,7 @@ struct draw_context float wide_point_threshold; /**< convert pnts to tris if larger than this */ float wide_line_threshold; /**< convert lines to tris if wider than this */ boolean line_stipple; /**< do line stipple? */ + boolean point_sprite; /**< convert points to quads for sprites? */ boolean use_sse; /* If a prim stage introduces new vertex attributes, they'll be stored here diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index 602fa3429d..33e5559508 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -76,6 +76,10 @@ draw_need_pipeline(const struct draw_context *draw) if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw) return TRUE; + /* point sprites */ + if (draw->rasterizer->point_sprite && draw->point_sprite) + return TRUE; + /* two-side lighting */ if (draw->rasterizer->light_twoside) return TRUE; @@ -110,7 +114,9 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) && !draw->rasterizer->line_smooth); /* drawing large points? */ - if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) + if (draw->rasterizer->point_sprite && draw->point_sprite) + wide_points = TRUE; + else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) wide_points = FALSE; else if (draw->rasterizer->point_size > draw->wide_point_threshold) wide_points = TRUE; diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c index 65bd50f2b8..c53f7e6cb3 100644 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_wide_point.c @@ -184,7 +184,8 @@ static void widepoint_first_point( struct draw_stage *stage, wide->half_point_size = 0.5f * draw->rasterizer->point_size; /* XXX we won't know the real size if it's computed by the vertex shader! */ - if (draw->rasterizer->point_size > draw->wide_point_threshold) { + if ((draw->rasterizer->point_size > draw->wide_point_threshold) || + (draw->rasterizer->point_sprite && draw->point_sprite)) { stage->point = widepoint_point; } else { -- cgit v1.2.3 From cb98f71d42e4c714dfb0c3e29d28d8418a1ee86b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 15 Mar 2008 00:55:28 +0000 Subject: gallium: Ensure we don't add null objects to the table, as they mark empty handles. --- src/gallium/auxiliary/util/u_handle_table.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c index ab427ee371..d25872972a 100644 --- a/src/gallium/auxiliary/util/u_handle_table.c +++ b/src/gallium/auxiliary/util/u_handle_table.c @@ -175,6 +175,10 @@ handle_table_set(struct handle_table *ht, if(!handle || handle > ht->size) return 0; + assert(object); + if(!object) + return 0; + index = handle - 1; /* grow the table if necessary */ -- cgit v1.2.3 From 49a687882a659bd03fd09ca7a7d592818914597a Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 16 Mar 2008 10:33:59 -0600 Subject: gallium: finish remaining prim types for sp_vbuf_draw_arrays() Not totally tested, but easily fixed if glitches are found. --- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 73 +++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index db0913cb2b..e7d0cb2b87 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -207,6 +207,27 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) (struct vertex_header *) ((char *) vertex_buffer + (I) * vertex_size) switch (cvbr->prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < nr; i++) { + prim.v[0] = VERTEX(i); + setup->point( setup, &prim ); + } + break; + case PIPE_PRIM_LINES: + assert(nr % 2 == 0); + for (i = 0; i < nr; i += 2) { + prim.v[0] = VERTEX(i); + prim.v[1] = VERTEX(i + 1); + setup->line( setup, &prim ); + } + break; + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < nr; i++) { + prim.v[0] = VERTEX(i - 1); + prim.v[1] = VERTEX(i); + setup->line( setup, &prim ); + } + break; case PIPE_PRIM_TRIANGLES: assert(nr % 3 == 0); for (i = 0; i < nr; i += 3) { @@ -217,6 +238,58 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) setup->tri( setup, &prim ); } break; + case PIPE_PRIM_TRIANGLE_STRIP: + assert(nr >= 3); + for (i = 2; i < nr; i++) { + prim.v[0] = VERTEX(i - 2); + prim.v[1] = VERTEX(i - 1); + prim.v[2] = VERTEX(i); + calc_det(&prim); + setup->tri( setup, &prim ); + } + break; + case PIPE_PRIM_TRIANGLE_FAN: + assert(nr >= 3); + for (i = 2; i < nr; i++) { + prim.v[0] = VERTEX(0); + prim.v[1] = VERTEX(i - 1); + prim.v[2] = VERTEX(i); + calc_det(&prim); + setup->tri( setup, &prim ); + } + break; + case PIPE_PRIM_QUADS: + assert(nr % 4 == 0); + for (i = 0; i < nr; i += 4) { + prim.v[0] = VERTEX(i + 0); + prim.v[1] = VERTEX(i + 1); + prim.v[2] = VERTEX(i + 2); + calc_det(&prim); + setup->tri( setup, &prim ); + + prim.v[0] = VERTEX(i + 0); + prim.v[1] = VERTEX(i + 2); + prim.v[2] = VERTEX(i + 3); + calc_det(&prim); + setup->tri( setup, &prim ); + } + break; + case PIPE_PRIM_QUAD_STRIP: + assert(nr >= 4); + for (i = 2; i < nr; i += 2) { + prim.v[0] = VERTEX(i - 2); + prim.v[1] = VERTEX(i); + prim.v[2] = VERTEX(i + 1); + calc_det(&prim); + setup->tri( setup, &prim ); + + prim.v[0] = VERTEX(i - 2); + prim.v[1] = VERTEX(i + 1); + prim.v[2] = VERTEX(i - 1); + calc_det(&prim); + setup->tri( setup, &prim ); + } + break; case PIPE_PRIM_POLYGON: /* draw as tri fan */ for (i = 2; i < nr; i++) { -- cgit v1.2.3 From 9425a702bef7d3f601e9ddc2b801f00a3d52dbb8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 17 Mar 2008 10:10:45 +0000 Subject: gallium: improvements, or extensions at least, to the passthrough path Passthrough is actually more tricky than you'd think... --- src/gallium/auxiliary/draw/draw_passthrough.c | 349 +++++++++++++++++------- src/gallium/auxiliary/draw/draw_vbuf.h | 6 +- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 12 +- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 13 +- 4 files changed, 275 insertions(+), 105 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_passthrough.c b/src/gallium/auxiliary/draw/draw_passthrough.c index d16f056191..fdec6a591b 100644 --- a/src/gallium/auxiliary/draw/draw_passthrough.c +++ b/src/gallium/auxiliary/draw/draw_passthrough.c @@ -85,14 +85,52 @@ fetch_store_general( struct draw_context *draw, const unsigned *pitch = draw->vertex_fetch.pitch; const ubyte **src = draw->vertex_fetch.src_ptr; - for (i = start; i < count; i++) { + for (i = start; i < start + count; i++) { for (j = 0; j < nr_attrs; j++) { + /* vinfo->src_index is the output of the vertex shader + * matching this hw-vertex component. + * + * In passthrough, we require a 1:1 mapping between vertex + * shader outputs and inputs, which in turn correspond to + * vertex elements in the state. So, this is the vertex + * element we're interested in... + */ const uint jj = vinfo->src_index[j]; const enum pipe_format srcFormat = draw->vertex_element[jj].src_format; const ubyte *from = src[jj] + i * pitch[jj]; float attrib[4]; + /* Except... When we're not. Two cases EMIT_HEADER & + * EMIT_1F_PSIZE don't consume an input. Should have some + * method for indicating this, or change the logic here + * somewhat so it doesn't matter. + * + * Just hack this up now, do something better about it later. + */ + if (vinfo->emit[j] == EMIT_HEADER) { + memset(out, 0, sizeof(struct vertex_header)); + out += sizeof(struct vertex_header) / 4; + continue; + } + else if (vinfo->emit[j] == EMIT_1F_PSIZE) { + out[0] = 1.0; /* xxx */ + out += 1; + continue; + } + + + /* The normal fetch/emit code: + */ switch (srcFormat) { + case PIPE_FORMAT_B8G8R8A8_UNORM: + { + ubyte *ub = (ubyte *) from; + attrib[0] = UBYTE_TO_FLOAT(ub[0]); + attrib[1] = UBYTE_TO_FLOAT(ub[1]); + attrib[2] = UBYTE_TO_FLOAT(ub[2]); + attrib[3] = UBYTE_TO_FLOAT(ub[3]); + } + break; case PIPE_FORMAT_R32G32B32A32_FLOAT: { float *f = (float *) from; @@ -130,14 +168,21 @@ fetch_store_general( struct draw_context *draw, } break; default: - abort(); + assert(0); } - /* XXX this will probably only work for softpipe */ + debug_printf("attrib %d: %f %f %f %f\n", j, + attrib[0], attrib[1], attrib[2], attrib[3]); + switch (vinfo->emit[j]) { - case EMIT_HEADER: - memset(out, 0, sizeof(struct vertex_header)); - out += sizeof(struct vertex_header) / 4; + case EMIT_1F: + out[0] = attrib[0]; + out += 1; + break; + case EMIT_2F: + out[0] = attrib[0]; + out[1] = attrib[1]; + out += 2; break; case EMIT_4F: out[0] = attrib[0]; @@ -147,64 +192,15 @@ fetch_store_general( struct draw_context *draw, out += 4; break; default: - abort(); + assert(0); } - } + debug_printf("\n"); } } -/* Example of a fetch/emit passthrough shader which could be - * generated when bypass_clipping is enabled on a passthrough vertex - * shader. - */ -static void fetch_xyz_rgb_st( struct draw_context *draw, - float *out, - unsigned start, - unsigned count ) -{ - const unsigned *pitch = draw->vertex_fetch.pitch; - const ubyte **src = draw->vertex_fetch.src_ptr; - unsigned i; - - const ubyte *xyzw = src[0] + start * pitch[0]; - const ubyte *rgba = src[1] + start * pitch[1]; - const ubyte *st = src[2] + start * pitch[2]; - - /* loop over vertex attributes (vertex shader inputs) - */ - for (i = 0; i < count; i++) { - { - const float *in = (const float *)xyzw; xyzw += pitch[0]; - /* decode input, encode output. Assume both are float[4] */ - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; - } - - { - const float *in = (const float *)rgba; rgba += pitch[1]; - /* decode input, encode output. Assume both are float[4] */ - out[4] = in[0]; - out[5] = in[1]; - out[6] = in[2]; - out[7] = in[3]; - } - - { - const float *in = (const float *)st; st += pitch[2]; - /* decode input, encode output. Assume both are float[2] */ - out[8] = in[0]; - out[9] = in[1]; - } - - out += 10; - } -} - static boolean update_shader( struct draw_context *draw ) { const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); @@ -229,70 +225,166 @@ static boolean update_shader( struct draw_context *draw ) draw->pt.hw_vertex_size = vinfo->size * 4; - /* Just trying to figure out how this would work: - */ - if (draw->rasterizer->bypass_vs || - (nr_attrs == 3 && 0 /* some other tests */)) - { -#if 0 - draw->vertex_fetch.pt_fetch = fetch_xyz_rgb_st; -#else - draw->vertex_fetch.pt_fetch = fetch_store_general; -#endif - /*assert(vinfo->size == 10);*/ + draw->vertex_fetch.pt_fetch = fetch_store_general; + return TRUE; +} + + + + +static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr) +{ + switch (prim) { + case PIPE_PRIM_POINTS: + *first = 1; + *incr = 1; + return TRUE; + case PIPE_PRIM_LINES: + *first = 2; + *incr = 2; return TRUE; + case PIPE_PRIM_LINE_STRIP: + *first = 2; + *incr = 1; + return TRUE; + case PIPE_PRIM_TRIANGLES: + *first = 3; + *incr = 3; + return TRUE; + case PIPE_PRIM_TRIANGLE_STRIP: + *first = 3; + *incr = 1; + return TRUE; + case PIPE_PRIM_QUADS: + *first = 4; + *incr = 4; + return TRUE; + case PIPE_PRIM_QUAD_STRIP: + *first = 4; + *incr = 2; + return TRUE; + default: + *first = 0; + *incr = 1; /* set to one so that count % incr works */ + return FALSE; } - - return FALSE; } static boolean set_prim( struct draw_context *draw, - unsigned prim ) + unsigned prim, + unsigned count ) { assert(!draw->user.elts); - draw->pt.prim = prim; - switch (prim) { case PIPE_PRIM_LINE_LOOP: + if (count > 1024) + return FALSE; + return draw->render->set_primitive( draw->render, PIPE_PRIM_LINE_STRIP ); + + case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_POLYGON: + if (count > 1024) + return FALSE; + return draw->render->set_primitive( draw->render, prim ); + case PIPE_PRIM_QUADS: case PIPE_PRIM_QUAD_STRIP: - return FALSE; + return draw->render->set_primitive( draw->render, PIPE_PRIM_TRIANGLES ); + default: - draw->render->set_primitive( draw->render, prim ); - return TRUE; + return draw->render->set_primitive( draw->render, prim ); + break; } + + return TRUE; } -boolean -draw_passthrough_arrays(struct draw_context *draw, - unsigned prim, - unsigned start, - unsigned count) + +#define INDEX(i) (start + (i)) +static void pt_draw_arrays( struct draw_context *draw, + unsigned start, + unsigned length ) { - float *hw_verts; + ushort *tmp = NULL; + unsigned i, j; - if (draw_need_pipeline(draw)) - return FALSE; + switch (draw->pt.prim) { + case PIPE_PRIM_LINE_LOOP: + tmp = MALLOC( sizeof(ushort) * (length + 1) ); - if (!set_prim(draw, prim)) - return FALSE; + for (i = 0; i < length; i++) + tmp[i] = INDEX(i); + tmp[length] = 0; - if (!update_shader(draw)) - return FALSE; + draw->render->draw( draw->render, + tmp, + length+1 ); + break; - hw_verts = draw->render->allocate_vertices( draw->render, - draw->pt.hw_vertex_size, - count ); + + case PIPE_PRIM_QUAD_STRIP: + tmp = MALLOC( sizeof(ushort) * (length / 2 * 6) ); + + for (j = i = 0; i + 3 < length; i += 2, j += 6) { + tmp[j+0] = INDEX(i+0); + tmp[j+1] = INDEX(i+1); + tmp[j+2] = INDEX(i+3); + + tmp[j+3] = INDEX(i+2); + tmp[j+4] = INDEX(i+0); + tmp[j+5] = INDEX(i+3); + } + + if (j) + draw->render->draw( draw->render, tmp, j ); + break; + + case PIPE_PRIM_QUADS: + tmp = MALLOC( sizeof(int) * (length / 4 * 6) ); + + for (j = i = 0; i + 3 < length; i += 4, j += 6) { + tmp[j+0] = INDEX(i+0); + tmp[j+1] = INDEX(i+1); + tmp[j+2] = INDEX(i+3); + + tmp[j+3] = INDEX(i+1); + tmp[j+4] = INDEX(i+2); + tmp[j+5] = INDEX(i+3); + } + + if (j) + draw->render->draw( draw->render, tmp, j ); + break; + + default: + draw->render->draw_arrays( draw->render, + start, + length ); + break; + } + + if (tmp) + FREE(tmp); +} + + + +static boolean do_draw( struct draw_context *draw, + unsigned start, unsigned count ) +{ + float *hw_verts = + draw->render->allocate_vertices( draw->render, + (ushort)draw->pt.hw_vertex_size, + (ushort)count ); if (!hw_verts) return FALSE; - /* Single routine to fetch vertices, run shader and emit HW verts. - * Clipping and viewport transformation are done on hardware. + /* Single routine to fetch vertices and emit HW verts. */ draw->vertex_fetch.pt_fetch( draw, hw_verts, @@ -301,9 +393,9 @@ draw_passthrough_arrays(struct draw_context *draw, /* Draw arrays path to avoid re-emitting index list again and * again. */ - draw->render->draw_arrays( draw->render, - start, - count ); + pt_draw_arrays( draw, + 0, + count ); draw->render->release_vertices( draw->render, @@ -314,3 +406,68 @@ draw_passthrough_arrays(struct draw_context *draw, return TRUE; } + +boolean +draw_passthrough_arrays(struct draw_context *draw, + unsigned prim, + unsigned start, + unsigned count) +{ + unsigned i = 0; + unsigned first, incr; + + //debug_printf("%s prim %d start %d count %d\n", __FUNCTION__, prim, start, count); + + split_prim_inplace(prim, &first, &incr); + + count -= (count - first) % incr; + + debug_printf("%s %d %d %d\n", __FUNCTION__, prim, start, count); + + if (draw_need_pipeline(draw)) + return FALSE; + + debug_printf("%s AAA\n", __FUNCTION__); + + if (!set_prim(draw, prim, count)) + return FALSE; + + /* XXX: need a single value that reflects the most recent call to + * driver->set_primitive: + */ + draw->pt.prim = prim; + + debug_printf("%s BBB\n", __FUNCTION__); + + if (!update_shader(draw)) + return FALSE; + + debug_printf("%s CCC\n", __FUNCTION__); + + /* Chop this up into bite-sized pieces that a driver should be able + * to devour -- problem is we don't have a quick way to query the + * driver on the maximum size for this chunk in the current state. + */ + while (i + first <= count) { + int nr = MIN2( count - i, 1024 ); + + /* snap to prim boundary + */ + nr -= (nr - first) % incr; + + if (!do_draw( draw, start + i, nr )) { + assert(0); + return FALSE; + } + + /* increment allowing for repeated vertices + */ + i += nr - (first - incr); + } + + + debug_printf("%s DONE\n", __FUNCTION__); + return TRUE; +} + + diff --git a/src/gallium/auxiliary/draw/draw_vbuf.h b/src/gallium/auxiliary/draw/draw_vbuf.h index 5e7de905c1..e90f37872a 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.h +++ b/src/gallium/auxiliary/draw/draw_vbuf.h @@ -74,9 +74,11 @@ struct vbuf_render { /** * Notify the renderer of the current primitive when it changes. - * Prim is restricted to TRIANGLES, LINES and POINTS. + * Must succeed for TRIANGLES, LINES and POINTS. Other prims at + * the discretion of the driver, for the benefit of the passthrough + * path. */ - void (*set_primitive)( struct vbuf_render *, unsigned prim ); + boolean (*set_primitive)( struct vbuf_render *, unsigned prim ); /** * DrawElements, note indices are ushort: diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index 9d5f609220..eb64f51943 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -116,7 +116,7 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render, } -static void +static boolean i915_vbuf_render_set_primitive( struct vbuf_render *render, unsigned prim ) { @@ -125,15 +125,17 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render, switch(prim) { case PIPE_PRIM_POINTS: i915_render->hwprim = PRIM3D_POINTLIST; - break; + return TRUE; case PIPE_PRIM_LINES: i915_render->hwprim = PRIM3D_LINELIST; - break; + return TRUE; case PIPE_PRIM_TRIANGLES: i915_render->hwprim = PRIM3D_TRILIST; - break; + return TRUE; default: - assert(0); + /* Actually, can handle a lot more just fine... Fixme. + */ + return FALSE; } } diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index e7d0cb2b87..d940718ed2 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -101,11 +101,20 @@ sp_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices, } -static void +static boolean sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); - cvbr->prim = prim; + if (prim == PIPE_PRIM_TRIANGLES || + prim == PIPE_PRIM_LINES || + prim == PIPE_PRIM_POINTS) { + cvbr->prim = prim; + return TRUE; + } + else { + return FALSE; + } + } -- cgit v1.2.3 From e3a747f1fefc147e8dca5729bcc8d68f419c595a Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 17 Mar 2008 15:37:42 -0600 Subject: gallium: new util_draw_texquad() function. --- src/gallium/auxiliary/util/u_draw_quad.c | 112 +++++++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_draw_quad.h | 37 ++++++++++ 2 files changed, 149 insertions(+) create mode 100644 src/gallium/auxiliary/util/u_draw_quad.c create mode 100644 src/gallium/auxiliary/util/u_draw_quad.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c new file mode 100644 index 0000000000..79a69de633 --- /dev/null +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -0,0 +1,112 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" +#include "util/u_draw_quad.h" + + +/** + * Draw screen-aligned textured quad. + */ +void +util_draw_texquad(struct pipe_context *pipe, + float x0, float y0, float x1, float y1, float z) +{ + struct pipe_buffer *vbuf; + struct pipe_vertex_buffer vbuffer; + struct pipe_vertex_element velement; + uint numAttribs = 2, vertexBytes, i, j; + float *v; + + vertexBytes = 4 * (4 * numAttribs * sizeof(float)); + + /* XXX create one-time */ + vbuf = pipe->winsys->buffer_create(pipe->winsys, 32, + PIPE_BUFFER_USAGE_VERTEX, vertexBytes); + assert(vbuf); + + v = (float *) pipe->winsys->buffer_map(pipe->winsys, vbuf, + PIPE_BUFFER_USAGE_CPU_WRITE); + + /* + * Load vertex buffer + */ + for (i = j = 0; i < 4; i++) { + v[j + 2] = z; /* z */ + v[j + 3] = 1.0; /* w */ + v[j + 6] = 0.0; /* r */ + v[j + 7] = 1.0; /* q */ + j += 8; + } + + v[0] = x0; + v[1] = y0; + v[4] = 0.0; /*s*/ + v[5] = 0.0; /*t*/ + + v[8] = x1; + v[9] = y0; + v[12] = 1.0; + v[13] = 0.0; + + v[16] = x1; + v[17] = y1; + v[20] = 1.0; + v[21] = 1.0; + + v[24] = x0; + v[25] = y1; + v[28] = 0.0; + v[29] = 1.0; + + pipe->winsys->buffer_unmap(pipe->winsys, vbuf); + + /* tell pipe about the vertex buffer */ + vbuffer.buffer = vbuf; + vbuffer.pitch = numAttribs * 4 * sizeof(float); /* vertex size */ + vbuffer.buffer_offset = 0; + pipe->set_vertex_buffer(pipe, 0, &vbuffer); + + /* tell pipe about the vertex attributes */ + for (i = 0; i < numAttribs; i++) { + velement.src_offset = i * 4 * sizeof(float); + velement.vertex_buffer_index = 0; + velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + velement.nr_components = 4; + pipe->set_vertex_element(pipe, i, &velement); + } + + /* draw */ + pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4); + + /* XXX: do one-time */ + pipe_buffer_reference(pipe->winsys, &vbuf, NULL); +} diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h new file mode 100644 index 0000000000..a97f55d2ef --- /dev/null +++ b/src/gallium/auxiliary/util/u_draw_quad.h @@ -0,0 +1,37 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef U_DRAWQUAD_H +#define U_DRAWQUAD_H + + +extern void +util_draw_texquad(struct pipe_context *pipe, + float x0, float y0, float x1, float y1, float z); + + +#endif -- cgit v1.2.3 From f1b42595d02828bcc617bc88b4ce6cf38a69ddbf Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 17 Mar 2008 15:38:14 -0600 Subject: gallium: new mipmap generation code Based on code from Mesa's state tracker. Still need to implement fallbacks for those texture formats which can't generally be rendered to. --- src/gallium/auxiliary/util/u_gen_mipmap.c | 495 ++++++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_gen_mipmap.h | 63 ++++ 2 files changed, 558 insertions(+) create mode 100644 src/gallium/auxiliary/util/u_gen_mipmap.c create mode 100644 src/gallium/auxiliary/util/u_gen_mipmap.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c new file mode 100644 index 0000000000..f0b822929e --- /dev/null +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -0,0 +1,495 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Mipmap generation utility + * + * @author Brian Paul + */ + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_shader_tokens.h" + +#include "util/u_draw_quad.h" +#include "util/u_gen_mipmap.h" + +#include "tgsi/util/tgsi_build.h" +#include "tgsi/util/tgsi_dump.h" +#include "tgsi/util/tgsi_parse.h" + + +/** + * Make simple fragment shader: + * TEX OUT[0], IN[0], SAMP[0], 2D; + * END; + */ +static void +make_fragment_shader(struct gen_mipmap_state *ctx) +{ + struct pipe_context *pipe = ctx->pipe; + uint maxTokens = 100; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + const uint procType = TGSI_PROCESSOR_FRAGMENT; + uint ti = 0; + struct pipe_shader_state shader; + + tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0])); + + /* shader header + */ + *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + + header = (struct tgsi_header *) &tokens[1]; + *header = tgsi_build_header(); + + processor = (struct tgsi_processor *) &tokens[2]; + *processor = tgsi_build_processor( procType, header ); + + ti = 3; + + /* declare TEX[0] input */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = 0; + /* XXX this could be linear... */ + decl.Declaration.Interpolate = 1; + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + /* declare color[0] output */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + /* declare sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + /* TEX instruction */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_TEX; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + inst.FullSrcRegisters[1].SrcRegister.Index = 0; + ti += tgsi_build_full_instruction(&inst, + &tokens[ti], + header, + maxTokens - ti ); + + /* END instruction */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction(&inst, + &tokens[ti], + header, + maxTokens - ti ); + +#if 0 /*debug*/ + tgsi_dump(tokens, 0); +#endif + + shader.tokens = tokens; + ctx->fs = pipe->create_fs_state(pipe, &shader); +} + + +/** + * Make simple fragment shader: + * MOV OUT[0], IN[0]; + * MOV OUT[1], IN[1]; + * END; + * + * XXX eliminate this when vertex passthrough-mode is more solid. + */ +static void +make_vertex_shader(struct gen_mipmap_state *ctx) +{ + struct pipe_context *pipe = ctx->pipe; + uint maxTokens = 100; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + const uint procType = TGSI_PROCESSOR_VERTEX; + uint ti = 0; + struct pipe_shader_state shader; + + tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0])); + + /* shader header + */ + *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + + header = (struct tgsi_header *) &tokens[1]; + *header = tgsi_build_header(); + + processor = (struct tgsi_processor *) &tokens[2]; + *processor = tgsi_build_processor( procType, header ); + + ti = 3; + + /* declare POS input */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + /* + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; + decl.Semantic.SemanticIndex = 0; + */ + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + /* declare TEX[0] input */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + /* + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = 0; + */ + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 1; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + /* declare POS output */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + /* declare TEX[0] output */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 1; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + /* MOVE out[0], in[0]; # POS */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MOV; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + ti += tgsi_build_full_instruction(&inst, + &tokens[ti], + header, + maxTokens - ti ); + + /* MOVE out[1], in[1]; # TEX */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MOV; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 1; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 1; + ti += tgsi_build_full_instruction(&inst, + &tokens[ti], + header, + maxTokens - ti ); + + /* END instruction */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction(&inst, + &tokens[ti], + header, + maxTokens - ti ); + +#if 0 /*debug*/ + tgsi_dump(tokens, 0); +#endif + + shader.tokens = tokens; + ctx->vs = pipe->create_vs_state(pipe, &shader); +} + + +/** + * Create a mipmap generation context. + * The idea is to create one of these and re-use it each time we need to + * generate a mipmap. + */ +struct gen_mipmap_state * +util_create_gen_mipmap(struct pipe_context *pipe) +{ + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state depthstencil; + struct pipe_rasterizer_state rasterizer; + struct gen_mipmap_state *ctx; + + ctx = CALLOC_STRUCT(gen_mipmap_state); + if (!ctx) + return NULL; + + ctx->pipe = pipe; + + /* we don't use blending, but need to set valid values */ + memset(&blend, 0, sizeof(blend)); + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.colormask = PIPE_MASK_RGBA; + ctx->blend = pipe->create_blend_state(pipe, &blend); + + /* depth/stencil/alpha */ + memset(&depthstencil, 0, sizeof(depthstencil)); + ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil); + + /* rasterizer */ + memset(&rasterizer, 0, sizeof(rasterizer)); + rasterizer.front_winding = PIPE_WINDING_CW; + rasterizer.cull_mode = PIPE_WINDING_NONE; + rasterizer.bypass_clipping = 1; /* bypasses viewport too */ + //rasterizer.bypass_vs = 1; + ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer); + +#if 0 + /* viewport */ + ctx->viewport.scale[0] = 1.0; + ctx->viewport.scale[1] = 1.0; + ctx->viewport.scale[2] = 1.0; + ctx->viewport.scale[3] = 1.0; + ctx->viewport.translate[0] = 0.0; + ctx->viewport.translate[1] = 0.0; + ctx->viewport.translate[2] = 0.0; + ctx->viewport.translate[3] = 0.0; +#endif + + make_vertex_shader(ctx); + make_fragment_shader(ctx); + + return ctx; +} + + +/** + * Destroy a mipmap generation context + */ +void +util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) +{ + struct pipe_context *pipe = ctx->pipe; + + pipe->delete_blend_state(pipe, ctx->blend); + pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil); + pipe->delete_rasterizer_state(pipe, ctx->rasterizer); + pipe->delete_vs_state(pipe, ctx->vs); + pipe->delete_fs_state(pipe, ctx->fs); + + FREE(ctx); +} + + +#if 0 +static void +simple_viewport(struct pipe_context *pipe, uint width, uint height) +{ + struct pipe_viewport_state vp; + + vp.scale[0] = 0.5 * width; + vp.scale[1] = -0.5 * height; + vp.scale[2] = 1.0; + vp.scale[3] = 1.0; + vp.translate[0] = 0.5 * width; + vp.translate[1] = 0.5 * height; + vp.translate[2] = 0.0; + vp.translate[3] = 0.0; + + pipe->set_viewport_state(pipe, &vp); +} +#endif + + +/** + * Generate mipmap images. It's assumed all needed texture memory is + * already allocated. + * + * \param pt the texture to generate mipmap levels for + * \param face which cube face to generate mipmaps for (0 for non-cube maps) + * \param baseLevel the first mipmap level to use as a src + * \param lastLevel the last mipmap level to generate + */ +void +util_gen_mipmap(struct gen_mipmap_state *ctx, + struct pipe_texture *pt, + uint face, uint baseLevel, uint lastLevel) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_framebuffer_state fb; + struct pipe_sampler_state sampler; + void *sampler_cso; + uint dstLevel; + uint zslice = 0; + + /* check if we can render in the texture's format */ + if (!screen->is_format_supported(screen, pt->format, PIPE_SURFACE)) { +#if 0 + fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); +#endif + return; + } + + /* init framebuffer state */ + memset(&fb, 0, sizeof(fb)); + fb.num_cbufs = 1; + + /* sampler state */ + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; + sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.normalized_coords = 1; + + /* bind our state */ + pipe->bind_blend_state(pipe, ctx->blend); + pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil); + pipe->bind_rasterizer_state(pipe, ctx->rasterizer); + pipe->bind_vs_state(pipe, ctx->vs); + pipe->bind_fs_state(pipe, ctx->fs); +#if 0 + pipe->set_viewport_state(pipe, &ctx->viewport); +#endif + + /* + * XXX for small mipmap levels, it may be faster to use the software + * fallback path... + */ + for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { + const uint srcLevel = dstLevel - 1; + + /* + * Setup framebuffer / dest surface + */ + fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + pipe->set_framebuffer_state(pipe, &fb); + + /* + * Setup sampler state + * Note: we should only have to set the min/max LOD clamps to ensure + * we grab texels from the right mipmap level. But some hardware + * has trouble with min clamping so we also set the lod_bias to + * try to work around that. + */ + sampler.min_lod = sampler.max_lod = srcLevel; + sampler.lod_bias = srcLevel; + sampler_cso = pipe->create_sampler_state(pipe, &sampler); + pipe->bind_sampler_states(pipe, 1, &sampler_cso); + +#if 0 + simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]); +#endif + + pipe->set_sampler_textures(pipe, 1, &pt); + + /* quad coords in window coords (bypassing clipping, viewport mapping) */ + util_draw_texquad(pipe, + 0.0F, 0.0F, /* x0, y0 */ + (float) pt->width[dstLevel], /* x1 */ + (float) pt->height[dstLevel], /* y1 */ + 0.0F); /* z */ + + + pipe->flush(pipe, PIPE_FLUSH_WAIT); + + /*pipe->texture_update(pipe, pt); not really needed */ + + pipe->delete_sampler_state(pipe, sampler_cso); + } + + /* Note: caller must restore pipe/gallium state at this time */ +} diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h new file mode 100644 index 0000000000..6ee909f0a6 --- /dev/null +++ b/src/gallium/auxiliary/util/u_gen_mipmap.h @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef U_GENMIPMAP_H +#define U_GENMIPMAP_H + +#include "pipe/p_state.h" + + +struct gen_mipmap_state +{ + struct pipe_context *pipe; + + void *blend; + void *depthstencil; + void *rasterizer; + /*struct pipe_viewport_state viewport;*/ + struct pipe_sampler_state *vs; + struct pipe_sampler_state *fs; +}; + + + +extern struct gen_mipmap_state * +util_create_gen_mipmap(struct pipe_context *pipe); + + +extern void +util_destroy_gen_mipmap(struct gen_mipmap_state *ctx); + + + +extern void +util_gen_mipmap(struct gen_mipmap_state *ctx, + struct pipe_texture *pt, + uint face, uint baseLevel, uint lastLevel); + + +#endif -- cgit v1.2.3 From 11d723cda68d775fa20e43db16ac2ce7e00430b1 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 17 Mar 2008 15:39:19 -0600 Subject: gallium: added new u_draw_quad.c and u_gen_mipmap.c files. --- src/gallium/auxiliary/util/Makefile | 2 ++ src/gallium/auxiliary/util/SConscript | 2 ++ 2 files changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index 2016c6fb1f..d11fa6e803 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -7,6 +7,8 @@ C_SOURCES = \ p_debug.c \ p_tile.c \ p_util.c \ + u_draw_quad.c \ + u_gen_mipmap.c \ u_handle_table.c \ u_hash_table.c \ u_mm.c \ diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 154a3eca8c..6d4ba8643d 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -6,6 +6,8 @@ util = env.ConvenienceLibrary( 'p_debug.c', 'p_tile.c', 'p_util.c', + 'u_draw_quad.c', + 'u_gen_mipmap.c', 'u_handle_table.c', 'u_hash_table.c', 'u_mm.c', -- cgit v1.2.3 From 0c715de39fa8337a2753dacd77ed280000416c1a Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 17 Mar 2008 15:37:09 -0700 Subject: cell: Fix simple register allocator THere are 64-bits in a uint64_t, not 128. Duh. --- src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c index a996218ce7..842d713f84 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c @@ -326,8 +326,8 @@ int spe_allocate_available_register(struct spe_function *p) { unsigned i; for (i = 0; i < 128; i++) { - const uint64_t mask = (1ULL << (i % 128)); - const unsigned idx = i / 128; + const uint64_t mask = (1ULL << (i % 64)); + const unsigned idx = i / 64; if ((p->regs[idx] & mask) != 0) { p->regs[idx] &= ~mask; @@ -341,8 +341,8 @@ int spe_allocate_available_register(struct spe_function *p) int spe_allocate_register(struct spe_function *p, int reg) { - const unsigned idx = reg / 128; - const unsigned bit = reg % 128; + const unsigned idx = reg / 64; + const unsigned bit = reg % 64; assert((p->regs[idx] & (1ULL << bit)) != 0); @@ -353,8 +353,8 @@ int spe_allocate_register(struct spe_function *p, int reg) void spe_release_register(struct spe_function *p, int reg) { - const unsigned idx = reg / 128; - const unsigned bit = reg % 128; + const unsigned idx = reg / 64; + const unsigned bit = reg % 64; assert((p->regs[idx] & (1ULL << bit)) == 0); -- cgit v1.2.3 From 1936e4bdfd776f78f9fe44f77ce66066fd166360 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 17 Mar 2008 15:45:52 -0700 Subject: cell: Initial code-gen for alpha / stencil / depth testing Alpha test is currently broken because all per-fragment testing occurs before alpha is calculated. Stencil test is currently broken because the Z-clear code asserts if there is a stencil buffer. --- src/gallium/drivers/cell/common.h | 10 + src/gallium/drivers/cell/ppu/Makefile | 1 + src/gallium/drivers/cell/ppu/cell_context.h | 25 +- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 37 +- src/gallium/drivers/cell/ppu/cell_state_emit.c | 24 +- .../drivers/cell/ppu/cell_state_per_fragment.c | 1020 ++++++++++++++++++++ .../drivers/cell/ppu/cell_state_per_fragment.h | 35 + src/gallium/drivers/cell/spu/Makefile | 1 + src/gallium/drivers/cell/spu/spu_main.c | 25 +- src/gallium/drivers/cell/spu/spu_main.h | 16 +- src/gallium/drivers/cell/spu/spu_per_fragment_op.c | 191 ++++ src/gallium/drivers/cell/spu/spu_per_fragment_op.h | 32 + src/gallium/drivers/cell/spu/spu_render.c | 4 +- src/gallium/drivers/cell/spu/spu_tri.c | 23 +- src/gallium/drivers/cell/spu/spu_ztest.h | 135 --- 15 files changed, 1409 insertions(+), 170 deletions(-) create mode 100644 src/gallium/drivers/cell/ppu/cell_state_per_fragment.c create mode 100644 src/gallium/drivers/cell/ppu/cell_state_per_fragment.h create mode 100644 src/gallium/drivers/cell/spu/spu_per_fragment_op.c create mode 100644 src/gallium/drivers/cell/spu/spu_per_fragment_op.h delete mode 100644 src/gallium/drivers/cell/spu/spu_ztest.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index 9a4004535e..fe93fd8e1a 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -104,6 +104,16 @@ +/** + */ +struct cell_command_depth_stencil_alpha_test { + uint64_t base; /**< Effective address of code start. */ + unsigned size; /**< Size in bytes of test code. */ + unsigned read_depth; /**< Flag: should depth be read? */ + unsigned read_stencil; /**< Flag: should stencil be read? */ +}; + + /** * Tell SPUs about the framebuffer size, location */ diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index d38fa6ce07..0389a9554c 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -27,6 +27,7 @@ SOURCES = \ cell_flush.c \ cell_state_derived.c \ cell_state_emit.c \ + cell_state_per_fragment.c \ cell_state_shader.c \ cell_pipe_state.c \ cell_screen.c \ diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index b221424323..9e79db0ace 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -57,16 +57,37 @@ struct cell_fragment_shader_state }; +struct cell_blend_state { + struct pipe_blend_state base; + + /** + * Generated code to perform alpha blending + */ + struct spe_function code; +}; + + +struct cell_depth_stencil_alpha_state { + struct pipe_depth_stencil_alpha_state base; + + /** + * Generated code to perform alpha, stencil, and depth testing on the SPE + */ + struct spe_function code; + +}; + + struct cell_context { struct pipe_context pipe; struct cell_winsys *winsys; - const struct pipe_blend_state *blend; + const struct cell_blend_state *blend; const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; uint num_samplers; - const struct pipe_depth_stencil_alpha_state *depth_stencil; + const struct cell_depth_stencil_alpha_state *depth_stencil; const struct pipe_rasterizer_state *rasterizer; const struct cell_vertex_shader_state *vs; const struct cell_fragment_shader_state *fs; diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 025ed3bbbf..66ede99d13 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -36,6 +36,7 @@ #include "cell_context.h" #include "cell_state.h" #include "cell_texture.h" +#include "cell_state_per_fragment.h" @@ -43,7 +44,12 @@ static void * cell_create_blend_state(struct pipe_context *pipe, const struct pipe_blend_state *blend) { - return mem_dup(blend, sizeof(*blend)); + struct cell_blend_state *cb = MALLOC(sizeof(struct cell_blend_state)); + + (void) memcpy(cb, blend, sizeof(*blend)); + cb->code.store = NULL; + + return cb; } @@ -54,7 +60,7 @@ cell_bind_blend_state(struct pipe_context *pipe, void *blend) draw_flush(cell->draw); - cell->blend = (const struct pipe_blend_state *)blend; + cell->blend = (const struct cell_blend_state *)blend; cell->dirty |= CELL_NEW_BLEND; } @@ -63,7 +69,10 @@ cell_bind_blend_state(struct pipe_context *pipe, void *blend) static void cell_delete_blend_state(struct pipe_context *pipe, void *blend) { - FREE(blend); + struct cell_blend_state *cb = (struct cell_blend_state *) blend; + + spe_release_func(& cb->code); + FREE(cb); } @@ -87,7 +96,13 @@ static void * cell_create_depth_stencil_alpha_state(struct pipe_context *pipe, const struct pipe_depth_stencil_alpha_state *depth_stencil) { - return mem_dup(depth_stencil, sizeof(*depth_stencil)); + struct cell_depth_stencil_alpha_state *cdsa = + MALLOC(sizeof(struct cell_depth_stencil_alpha_state)); + + (void) memcpy(cdsa, depth_stencil, sizeof(*depth_stencil)); + cdsa->code.store = NULL; + + return cdsa; } @@ -96,12 +111,16 @@ cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth_stencil) { struct cell_context *cell = cell_context(pipe); + struct cell_depth_stencil_alpha_state *cdsa = + (struct cell_depth_stencil_alpha_state *) depth_stencil; draw_flush(cell->draw); - cell->depth_stencil - = (const struct pipe_depth_stencil_alpha_state *) depth_stencil; + if (cdsa->code.store == NULL) { + cell_generate_depth_stencil_test(cdsa); + } + cell->depth_stencil = cdsa; cell->dirty |= CELL_NEW_DEPTH_STENCIL; } @@ -109,7 +128,11 @@ cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe, static void cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth) { - FREE(depth); + struct cell_depth_stencil_alpha_state *cdsa = + (struct cell_depth_stencil_alpha_state *) depth; + + spe_release_func(& cdsa->code); + FREE(cdsa); } diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 670eb26bdd..c8d5fdf709 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -71,9 +71,27 @@ cell_emit_state(struct cell_context *cell) } if (cell->dirty & CELL_NEW_DEPTH_STENCIL) { - emit_state_cmd(cell, CELL_CMD_STATE_DEPTH_STENCIL, - cell->depth_stencil, - sizeof(struct pipe_depth_stencil_alpha_state)); + struct cell_command_depth_stencil_alpha_test dsat; + + + dsat.base = (intptr_t) cell->depth_stencil->code.store; + dsat.size = (char *) cell->depth_stencil->code.csr + - (char *) cell->depth_stencil->code.store; + dsat.read_depth = TRUE; + dsat.read_stencil = FALSE; + + { + uint32_t *p = cell->depth_stencil->code.store; + + printf("\t.text\n"); + for (/* empty */; p < cell->depth_stencil->code.csr; p++) { + printf("\t.long\t0x%04x\n", *p); + } + fflush(stdout); + } + + emit_state_cmd(cell, CELL_CMD_STATE_DEPTH_STENCIL, &dsat, + sizeof(dsat)); } if (cell->dirty & CELL_NEW_SAMPLER) { diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c new file mode 100644 index 0000000000..60b64438d8 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -0,0 +1,1020 @@ +/* + * (C) Copyright IBM Corporation 2008 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file + * Generate code to perform all per-fragment operations. + * + * Code generated by these functions perform both alpha, depth, and stencil + * testing as well as alpha blending. + * + * \note + * Occlusion query is not supported, but this is the right place to add that + * support. + * + * \author Ian Romanick + */ + +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "cell_context.h" + +#include "rtasm/rtasm_ppc_spe.h" + + +/** + * Generate code to perform alpha testing. + * + * The code generated by this function uses the register specificed by + * \c mask as both an input and an output. + * + * \param dsa Current alpha-test state + * \param f Function to which code should be appended + * \param mask Index of register containing active fragment mask + * \param alphas Index of register containing per-fragment alpha values + * + * \note Emits a maximum of 6 instructions. + */ +static void +emit_alpha_test(struct pipe_depth_stencil_alpha_state *dsa, + struct spe_function *f, int mask, int alphas) +{ + /* If the alpha function is either NEVER or ALWAYS, there is no need to + * load the reference value into a register. ALWAYS is a fairly common + * case, and this optimization saves 2 instructions. + */ + if (dsa->alpha.enabled + && (dsa->alpha.func != PIPE_FUNC_NEVER) + && (dsa->alpha.func != PIPE_FUNC_ALWAYS)) { + int ref = spe_allocate_available_register(f); + int tmp_a = spe_allocate_available_register(f); + int tmp_b = spe_allocate_available_register(f); + union { + float f; + unsigned u; + } ref_val; + boolean complement = FALSE; + + ref_val.f = dsa->alpha.ref; + + spe_il(f, ref, ref_val.u & 0x0000ffff); + spe_ilh(f, ref, ref_val.u >> 16); + + switch (dsa->alpha.func) { + case PIPE_FUNC_NOTEQUAL: + complement = TRUE; + /* FALLTHROUGH */ + + case PIPE_FUNC_EQUAL: + spe_fceq(f, tmp_a, ref, alphas); + break; + + case PIPE_FUNC_LEQUAL: + complement = TRUE; + /* FALLTHROUGH */ + + case PIPE_FUNC_GREATER: + spe_fcgt(f, tmp_a, ref, alphas); + break; + + case PIPE_FUNC_LESS: + complement = TRUE; + /* FALLTHROUGH */ + + case PIPE_FUNC_GEQUAL: + spe_fcgt(f, tmp_a, ref, alphas); + spe_fceq(f, tmp_b, ref, alphas); + spe_or(f, tmp_a, tmp_b, tmp_a); + break; + + case PIPE_FUNC_ALWAYS: + case PIPE_FUNC_NEVER: + default: + assert(0); + break; + } + + if (complement) { + spe_andc(f, mask, mask, tmp_a); + } else { + spe_and(f, mask, mask, tmp_a); + } + + spe_release_register(f, ref); + spe_release_register(f, tmp_a); + spe_release_register(f, tmp_b); + } else if (dsa->alpha.enabled && (dsa->alpha.func == PIPE_FUNC_NEVER)) { + spe_il(f, mask, 0); + } +} + + +/** + * \param dsa Current depth-test state + * \param f Function to which code should be appended + * \param m Mask of allocated / free SPE registers + * \param mask Index of register to contain depth-pass mask + * \param stored Index of register containing values from depth buffer + * \param calculated Index of register containing per-fragment depth values + * + * \return + * If the calculated depth comparison mask is the actual mask, \c FALSE is + * returned. If the calculated depth comparison mask is the compliment of + * the actual mask, \c TRUE is returned. + * + * \note Emits a maximum of 3 instructions. + */ +static boolean +emit_depth_test(struct pipe_depth_stencil_alpha_state *dsa, + struct spe_function *f, int mask, int stored, int calculated) +{ + unsigned func = (dsa->depth.enabled) + ? dsa->depth.func : PIPE_FUNC_ALWAYS; + int tmp = spe_allocate_available_register(f); + boolean compliment = FALSE; + + switch (func) { + case PIPE_FUNC_NEVER: + spe_il(f, mask, 0); + break; + + case PIPE_FUNC_NOTEQUAL: + compliment = TRUE; + /* FALLTHROUGH */ + case PIPE_FUNC_EQUAL: + spe_ceq(f, mask, calculated, stored); + break; + + case PIPE_FUNC_LEQUAL: + compliment = TRUE; + /* FALLTHROUGH */ + case PIPE_FUNC_GREATER: + spe_clgt(f, mask, calculated, stored); + break; + + case PIPE_FUNC_LESS: + compliment = TRUE; + /* FALLTHROUGH */ + case PIPE_FUNC_GEQUAL: + spe_clgt(f, mask, calculated, stored); + spe_ceq(f, tmp, calculated, stored); + spe_or(f, mask, mask, tmp); + break; + + case PIPE_FUNC_ALWAYS: + spe_il(f, mask, ~0); + break; + + default: + assert(0); + break; + } + + spe_release_register(f, tmp); + return compliment; +} + + +/** + * \note Emits a maximum of 5 instructions. + */ +static void +emit_stencil_op(struct spe_function *f, + int out, int in, int mask, unsigned op, unsigned ref) +{ + const int clamp = spe_allocate_available_register(f); + const int tmp = spe_allocate_available_register(f); + + switch(op) { + case PIPE_STENCIL_OP_KEEP: + assert(0); + case PIPE_STENCIL_OP_ZERO: + spe_il(f, out, 0); + break; + case PIPE_STENCIL_OP_REPLACE: + spe_il(f, out, ref); + break; + case PIPE_STENCIL_OP_INCR: + spe_il(f, clamp, 0x0ff); + spe_ai(f, out, in, 1); + spe_cgti(f, tmp, out, clamp); + spe_selb(f, out, out, clamp, tmp); + break; + case PIPE_STENCIL_OP_DECR: + spe_il(f, clamp, 0); + spe_ai(f, out, in, -1); + spe_cgti(f, tmp, out, clamp); + spe_selb(f, out, clamp, out, tmp); + break; + case PIPE_STENCIL_OP_INCR_WRAP: + spe_ai(f, out, in, 1); + break; + case PIPE_STENCIL_OP_DECR_WRAP: + spe_ai(f, out, in, -1); + break; + case PIPE_STENCIL_OP_INVERT: + spe_nor(f, out, in, in); + break; + default: + assert(0); + } + + spe_release_register(f, tmp); + spe_release_register(f, clamp); + + spe_selb(f, out, in, out, mask); +} + + +/** + * \param dsa Depth / stencil test state + * \param face 0 for front face, 1 for back face + * \param f Function to append instructions to + * \param reg_mask Mask of allocated registers + * \param mask Register containing mask of fragments passing the + * alpha test + * \param depth_mask Register containing mask of fragments passing the + * depth test + * \param depth_compliment Is \c depth_mask the compliment of the actual mask? + * \param stencil Register containing values from stencil buffer + * \param depth_pass Register to store mask of fragments passing stencil test + * and depth test + * + * \note + * Emits a maximum of 10 + (3 * 5) = 25 instructions. + */ +static int +emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, + unsigned face, + struct spe_function *f, + int mask, + int depth_mask, + boolean depth_complement, + int stencil, + int depth_pass) +{ + int stencil_fail = spe_allocate_available_register(f); + int depth_fail = spe_allocate_available_register(f); + int stencil_mask = spe_allocate_available_register(f); + int stencil_pass = spe_allocate_available_register(f); + int face_stencil = spe_allocate_available_register(f); + int stencil_src = stencil; + const unsigned ref = (dsa->stencil[face].ref_value + & dsa->stencil[face].value_mask); + boolean complement = FALSE; + int stored = spe_allocate_available_register(f); + int tmp = spe_allocate_available_register(f); + + + if ((dsa->stencil[face].func != PIPE_FUNC_NEVER) + && (dsa->stencil[face].func != PIPE_FUNC_ALWAYS) + && (dsa->stencil[face].value_mask != 0x0ff)) { + spe_andi(f, stored, stencil, dsa->stencil[face].value_mask); + } + + + switch (dsa->stencil[face].func) { + case PIPE_FUNC_NEVER: + spe_il(f, stencil_mask, 0); + break; + + case PIPE_FUNC_NOTEQUAL: + complement = TRUE; + /* FALLTHROUGH */ + case PIPE_FUNC_EQUAL: + spe_ceqi(f, stencil_mask, stored, ref); + break; + + case PIPE_FUNC_LEQUAL: + complement = TRUE; + /* FALLTHROUGH */ + case PIPE_FUNC_GREATER: + spe_clgti(f, stencil_mask, stored, ref); + break; + + case PIPE_FUNC_LESS: + complement = TRUE; + /* FALLTHROUGH */ + case PIPE_FUNC_GEQUAL: + spe_clgti(f, stencil_mask, stored, ref); + spe_ceqi(f, tmp, stored, ref); + spe_or(f, stencil_mask, stencil_mask, tmp); + break; + + case PIPE_FUNC_ALWAYS: + /* See comment below. */ + break; + + default: + assert(0); + break; + } + + spe_release_register(f, stored); + spe_release_register(f, tmp); + + + /* ALWAYS is a very common stencil-test, so some effort is applied to + * optimize that case. The stencil-pass mask is the same as the input + * fragment mask. This makes the stencil-test (above) a no-op, and the + * input fragment mask can be "renamed" the stencil-pass mask. + */ + if (dsa->stencil[face].func == PIPE_FUNC_ALWAYS) { + spe_release_register(f, stencil_pass); + stencil_pass = mask; + } else { + if (complement) { + spe_andc(f, stencil_pass, mask, stencil_mask); + } else { + spe_and(f, stencil_pass, mask, stencil_mask); + } + } + + if (depth_complement) { + spe_andc(f, depth_pass, stencil_pass, depth_mask); + } else { + spe_and(f, depth_pass, stencil_pass, depth_mask); + } + + + /* Conditionally emit code to update the stencil value under various + * condititons. Note that there is no need to generate code under the + * following circumstances: + * + * - Stencil write mask is zero. + * - For stencil-fail if the stencil test is ALWAYS + * - For depth-fail if the stencil test is NEVER + * - For depth-pass if the stencil test is NEVER + * - Any of the 3 conditions if the operation is KEEP + */ + if (dsa->stencil[face].write_mask != 0) { + if ((dsa->stencil[face].func != PIPE_FUNC_ALWAYS) + && (dsa->stencil[face].fail_op != PIPE_STENCIL_OP_KEEP)) { + if (complement) { + spe_and(f, stencil_fail, mask, stencil_mask); + } else { + spe_andc(f, stencil_fail, mask, stencil_mask); + } + + emit_stencil_op(f, face_stencil, stencil_src, stencil_fail, + dsa->stencil[face].fail_op, + dsa->stencil[face].ref_value); + + stencil_src = face_stencil; + } + + if ((dsa->stencil[face].func != PIPE_FUNC_NEVER) + && (dsa->stencil[face].zfail_op != PIPE_STENCIL_OP_KEEP)) { + if (depth_complement) { + spe_and(f, depth_fail, stencil_pass, depth_mask); + } else { + spe_andc(f, depth_fail, stencil_pass, depth_mask); + } + + emit_stencil_op(f, face_stencil, stencil_src, depth_fail, + dsa->stencil[face].zfail_op, + dsa->stencil[face].ref_value); + stencil_src = face_stencil; + } + + if ((dsa->stencil[face].func != PIPE_FUNC_NEVER) + && (dsa->stencil[face].zpass_op != PIPE_STENCIL_OP_KEEP)) { + emit_stencil_op(f, face_stencil, stencil_src, depth_pass, + dsa->stencil[face].zpass_op, + dsa->stencil[face].ref_value); + stencil_src = face_stencil; + } + } + + spe_release_register(f, stencil_fail); + spe_release_register(f, depth_fail); + spe_release_register(f, stencil_mask); + if (stencil_pass != mask) { + spe_release_register(f, stencil_pass); + } + + /* If all of the stencil operations were KEEP or the stencil write mask was + * zero, "stencil_src" will still be set to "stencil". In this case + * release the "face_stencil" register. Otherwise apply the stencil write + * mask to select bits from the calculated stencil value and the previous + * stencil value. + */ + if (stencil_src == stencil) { + spe_release_register(f, face_stencil); + } else if (dsa->stencil[face].write_mask != 0x0ff) { + int tmp = spe_allocate_available_register(f); + + spe_il(f, tmp, dsa->stencil[face].write_mask); + spe_selb(f, stencil_src, stencil, stencil_src, tmp); + + spe_release_register(f, tmp); + } + + return stencil_src; +} + + +void +cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) +{ + struct pipe_depth_stencil_alpha_state *const dsa = &cdsa->base; + struct spe_function *const f = &cdsa->code; + + /* This code generates a maximum of 6 (alpha test) + 3 (depth test) + * + 25 (front stencil) + 25 (back stencil) + 4 = 63 instructions. Round + * up to 64 to make it a happy power-of-two. + */ + spe_init_func(f, 4 * 64); + + + /* Allocate registers for the function's input parameters. Cleverly (and + * clever code is usually dangerous, but I couldn't resist) the generated + * function returns a structure. Returned structures start with register + * 3, and the structure fields are ordered to match up exactly with the + * input parameters. + */ + int mask = spe_allocate_register(f, 3); + int depth = spe_allocate_register(f, 4); + int stencil = spe_allocate_register(f, 5); + int zvals = spe_allocate_register(f, 6); + int frag_a = spe_allocate_register(f, 7); + int facing = spe_allocate_register(f, 8); + + int depth_mask = spe_allocate_available_register(f); + + boolean depth_complement; + + + emit_alpha_test(dsa, f, mask, frag_a); + + depth_complement = emit_depth_test(dsa, f, depth_mask, depth, zvals); + + if (dsa->stencil[0].enabled) { + const int front_depth_pass = spe_allocate_available_register(f); + int front_stencil = emit_stencil_test(dsa, 0, f, mask, + depth_mask, depth_complement, + stencil, front_depth_pass); + + if (dsa->stencil[1].enabled) { + const int back_depth_pass = spe_allocate_available_register(f); + int back_stencil = emit_stencil_test(dsa, 1, f, mask, + depth_mask, depth_complement, + stencil, back_depth_pass); + + /* If the front facing stencil value and the back facing stencil + * value are stored in the same register, there is no need to select + * a value based on the facing. This can happen if the stencil value + * was not modified due to the write masks being zero, the stencil + * operations being KEEP, etc. + */ + if (front_stencil != back_stencil) { + spe_selb(f, stencil, back_stencil, front_stencil, facing); + } + + if (back_stencil != stencil) { + spe_release_register(f, back_stencil); + } + + if (front_stencil != stencil) { + spe_release_register(f, front_stencil); + } + + spe_selb(f, mask, back_depth_pass, front_depth_pass, facing); + + spe_release_register(f, back_depth_pass); + } else { + if (front_stencil != stencil) { + spe_or(f, stencil, front_stencil, front_stencil); + spe_release_register(f, front_stencil); + } + } + + spe_release_register(f, front_depth_pass); + } else if (dsa->depth.enabled) { + if (depth_complement) { + spe_andc(f, mask, mask, depth_mask); + } else { + spe_and(f, mask, mask, depth_mask); + } + } + + if (dsa->depth.writemask) { + spe_selb(f, depth, depth, zvals, mask); + } + + spe_bi(f, 0, 0, 0); +} + + +/** + * \note Emits a maximum of 3 instructions + */ +static int +emit_alpha_factor_calculation(struct spe_function *f, + unsigned factor, float const_alpha, + int src_alpha, int dst_alpha) +{ + union { + float f; + unsigned u; + } alpha; + int factor_reg; + int tmp; + + + alpha.f = const_alpha; + + switch (factor) { + case PIPE_BLENDFACTOR_ONE: + factor_reg = -1; + break; + + case PIPE_BLENDFACTOR_SRC_ALPHA: + factor_reg = spe_allocate_available_register(f); + + spe_or(f, factor_reg, src_alpha, src_alpha); + break; + + case PIPE_BLENDFACTOR_DST_ALPHA: + factor_reg = dst_alpha; + break; + + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + factor_reg = -1; + break; + + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + const_alpha = 1.0 - const_alpha; + /* FALLTHROUGH */ + case PIPE_BLENDFACTOR_CONST_ALPHA: + factor_reg = spe_allocate_available_register(f); + + spe_il(f, factor_reg, alpha.u & 0x0ffff); + spe_ilh(f, factor_reg, alpha.u >> 16); + break; + + case PIPE_BLENDFACTOR_ZERO: + factor_reg = -1; + break; + + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + tmp = spe_allocate_available_register(f); + factor_reg = spe_allocate_available_register(f); + + spe_il(f, tmp, 1); + spe_cuflt(f, tmp, tmp, 0); + spe_fs(f, factor_reg, tmp, src_alpha); + + spe_release_register(f, tmp); + break; + + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + tmp = spe_allocate_available_register(f); + factor_reg = spe_allocate_available_register(f); + + spe_il(f, tmp, 1); + spe_cuflt(f, tmp, tmp, 0); + spe_fs(f, factor_reg, tmp, dst_alpha); + + spe_release_register(f, tmp); + break; + + case PIPE_BLENDFACTOR_SRC1_ALPHA: + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + default: + assert(0); + factor_reg = -1; + break; + } + + return factor_reg; +} + + +/** + * \note Emits a maximum of 5 instructions + */ +static void +emit_color_factor_calculation(struct spe_function *f, + unsigned sF, unsigned mask, + const struct pipe_blend_color *blend_color, + const int *src, + const int *dst, + int *factor) +{ + union { + float f[4]; + unsigned u[4]; + } color; + int tmp; + unsigned i; + + + color.f[0] = blend_color->color[0]; + color.f[1] = blend_color->color[1]; + color.f[2] = blend_color->color[2]; + color.f[3] = blend_color->color[3]; + + factor[0] = -1; + factor[1] = -1; + factor[2] = -1; + factor[3] = -1; + + switch (sF) { + case PIPE_BLENDFACTOR_ONE: + break; + + case PIPE_BLENDFACTOR_SRC_COLOR: + for (i = 0; i < 3; ++i) { + if ((mask & (1U << i)) != 0) { + factor[i] = spe_allocate_available_register(f); + spe_or(f, factor[i], src[i], src[i]); + } + } + break; + + case PIPE_BLENDFACTOR_SRC_ALPHA: + factor[0] = spe_allocate_available_register(f); + factor[1] = factor[0]; + factor[2] = factor[0]; + + spe_or(f, factor[0], src[3], src[3]); + break; + + case PIPE_BLENDFACTOR_DST_ALPHA: + factor[0] = dst[3]; + factor[1] = dst[3]; + factor[2] = dst[3]; + break; + + case PIPE_BLENDFACTOR_DST_COLOR: + factor[0] = dst[0]; + factor[1] = dst[1]; + factor[2] = dst[2]; + break; + + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + tmp = spe_allocate_available_register(f); + factor[0] = spe_allocate_available_register(f); + factor[1] = factor[0]; + factor[2] = factor[0]; + + /* Alpha saturate means min(As, 1-Ad). + */ + spe_il(f, tmp, 1); + spe_cuflt(f, tmp, tmp, 0); + spe_fs(f, tmp, tmp, dst[3]); + spe_fcgt(f, factor[0], tmp, src[3]); + spe_selb(f, factor[0], src[3], tmp, factor[0]); + + spe_release_register(f, tmp); + break; + + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + color.f[0] = 1.0 - color.f[0]; + color.f[1] = 1.0 - color.f[1]; + color.f[2] = 1.0 - color.f[2]; + /* FALLTHROUGH */ + case PIPE_BLENDFACTOR_CONST_COLOR: + for (i = 0; i < 3; i++) { + factor[i] = spe_allocate_available_register(f); + + spe_il(f, factor[i], color.u[i] & 0x0ffff); + spe_ilh(f, factor[i], color.u[i] >> 16); + } + break; + + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + color.f[3] = 1.0 - color.f[3]; + /* FALLTHROUGH */ + case PIPE_BLENDFACTOR_CONST_ALPHA: + factor[0] = spe_allocate_available_register(f); + factor[1] = factor[0]; + factor[2] = factor[0]; + + spe_il(f, factor[0], color.u[3] & 0x0ffff); + spe_ilh(f, factor[0], color.u[3] >> 16); + break; + + case PIPE_BLENDFACTOR_ZERO: + break; + + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + tmp = spe_allocate_available_register(f); + + spe_il(f, tmp, 1); + spe_cuflt(f, tmp, tmp, 0); + + for (i = 0; i < 3; ++i) { + if ((mask & (1U << i)) != 0) { + factor[i] = spe_allocate_available_register(f); + spe_fs(f, factor[i], tmp, src[i]); + } + } + + spe_release_register(f, tmp); + break; + + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + tmp = spe_allocate_available_register(f); + factor[0] = spe_allocate_available_register(f); + factor[1] = factor[0]; + factor[2] = factor[0]; + + spe_il(f, tmp, 1); + spe_cuflt(f, tmp, tmp, 0); + spe_fs(f, factor[0], tmp, src[3]); + + spe_release_register(f, tmp); + break; + + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + tmp = spe_allocate_available_register(f); + factor[0] = spe_allocate_available_register(f); + factor[1] = factor[0]; + factor[2] = factor[0]; + + spe_il(f, tmp, 1); + spe_cuflt(f, tmp, tmp, 0); + spe_fs(f, factor[0], tmp, dst[3]); + + spe_release_register(f, tmp); + break; + + case PIPE_BLENDFACTOR_INV_DST_COLOR: + tmp = spe_allocate_available_register(f); + + spe_il(f, tmp, 1); + spe_cuflt(f, tmp, tmp, 0); + + for (i = 0; i < 3; ++i) { + if ((mask & (1U << i)) != 0) { + factor[i] = spe_allocate_available_register(f); + spe_fs(f, factor[i], tmp, dst[i]); + } + } + + spe_release_register(f, tmp); + break; + + case PIPE_BLENDFACTOR_SRC1_COLOR: + case PIPE_BLENDFACTOR_SRC1_ALPHA: + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + default: + assert(0); + } +} + + +static void +emit_blend_calculation(struct spe_function *f, + unsigned func, unsigned sF, unsigned dF, + int src, int src_factor, int dst, int dst_factor) +{ + int tmp = spe_allocate_available_register(f); + + switch (func) { + case PIPE_BLEND_ADD: + if (sF == PIPE_BLENDFACTOR_ONE) { + if (dF == PIPE_BLENDFACTOR_ZERO) { + /* Do nothing. */ + } else if (dF == PIPE_BLENDFACTOR_ONE) { + spe_fa(f, src, src, dst); + } + } else if (sF == PIPE_BLENDFACTOR_ZERO) { + if (dF == PIPE_BLENDFACTOR_ZERO) { + spe_il(f, src, 0); + } else if (dF == PIPE_BLENDFACTOR_ONE) { + spe_or(f, src, dst, dst); + } + } else { + spe_fm(f, tmp, dst, dst_factor); + spe_fma(f, src, src, src_factor, tmp); + } + break; + + case PIPE_BLEND_SUBTRACT: + if (sF == PIPE_BLENDFACTOR_ONE) { + if (dF == PIPE_BLENDFACTOR_ZERO) { + /* Do nothing. */ + } else if (dF == PIPE_BLENDFACTOR_ONE) { + spe_fs(f, src, src, dst); + } + } else if (sF == PIPE_BLENDFACTOR_ZERO) { + if (dF == PIPE_BLENDFACTOR_ZERO) { + spe_il(f, src, 0); + } else if (dF == PIPE_BLENDFACTOR_ONE) { + spe_il(f, tmp, 0); + spe_fs(f, src, tmp, dst); + } + } else { + spe_fm(f, tmp, dst, dst_factor); + spe_fms(f, src, src, src_factor, tmp); + } + break; + + case PIPE_BLEND_REVERSE_SUBTRACT: + if (sF == PIPE_BLENDFACTOR_ONE) { + if (dF == PIPE_BLENDFACTOR_ZERO) { + spe_il(f, tmp, 0); + spe_fs(f, src, tmp, src); + } else if (dF == PIPE_BLENDFACTOR_ONE) { + spe_fs(f, src, dst, src); + } + } else if (sF == PIPE_BLENDFACTOR_ZERO) { + if (dF == PIPE_BLENDFACTOR_ZERO) { + spe_il(f, src, 0); + } else if (dF == PIPE_BLENDFACTOR_ONE) { + spe_or(f, src, dst, dst); + } + } else { + spe_fm(f, tmp, src, src_factor); + spe_fms(f, src, src, dst_factor, tmp); + } + break; + + case PIPE_BLEND_MIN: + spe_cgt(f, tmp, src, dst); + spe_selb(f, src, dst, src, tmp); + break; + + case PIPE_BLEND_MAX: + spe_cgt(f, tmp, src, dst); + spe_selb(f, src, src, dst, tmp); + break; + + default: + assert(0); + } + + spe_release_register(f, tmp); +} + + +/** + * Generate code to perform alpha blending on the SPE + */ +void +cell_generate_alpha_blend(struct cell_blend_state *cb, + const struct pipe_blend_color *blend_color) +{ + struct pipe_blend_state *const b = &cb->base; + struct spe_function *const f = &cb->code; + + /* This code generates a maximum of 3 (source alpha factor) + * + 3 (destination alpha factor) + (3 * 5) (source color factor) + * + (3 * 5) (destination color factor) + (4 * 2) (blend equation) + * + 4 (fragment mask) + 1 (return) = 49 instlructions. Round up to 64 to + * make it a happy power-of-two. + */ + spe_init_func(f, 4 * 64); + + + const int frag[4] = { + spe_allocate_register(f, 3), + spe_allocate_register(f, 4), + spe_allocate_register(f, 5), + spe_allocate_register(f, 6), + }; + const int pixel[4] = { + spe_allocate_register(f, 7), + spe_allocate_register(f, 8), + spe_allocate_register(f, 9), + spe_allocate_register(f, 10), + }; + const int mask = spe_allocate_register(f, 11); + unsigned func[4]; + unsigned sF[4]; + unsigned dF[4]; + unsigned i; + int src_factor[4]; + int dst_factor[4]; + + + /* Does the selected blend mode make use of the source / destination + * color (RGB) blend factors? + */ + boolean need_color_factor = b->blend_enable + && (b->rgb_func != PIPE_BLEND_MIN) + && (b->rgb_func != PIPE_BLEND_MAX); + + /* Does the selected blend mode make use of the source / destination + * alpha blend factors? + */ + boolean need_alpha_factor = b->blend_enable + && (b->alpha_func != PIPE_BLEND_MIN) + && (b->alpha_func != PIPE_BLEND_MAX); + + + sF[0] = b->rgb_src_factor; + sF[1] = sF[0]; + sF[2] = sF[0]; + sF[3] = (b->alpha_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE) + ? PIPE_BLENDFACTOR_ONE : b->alpha_src_factor; + + dF[0] = b->rgb_dst_factor; + dF[1] = dF[0]; + dF[2] = dF[0]; + dF[3] = b->rgb_dst_factor; + + + /* If alpha writing is enabled and the alpha blend mode requires use of + * the alpha factor, calculate the alpha factor. + */ + if (((b->colormask & 8) != 0) && need_alpha_factor) { + src_factor[3] = emit_alpha_factor_calculation(f, sF[3], + blend_color->color[3], + frag[3], pixel[3]); + + /* If the alpha destination blend factor is the same as the alpha source + * blend factor, re-use the previously calculated value. + */ + dst_factor[3] = (dF[3] == sF[3]) + ? src_factor[3] + : emit_alpha_factor_calculation(f, dF[3], + blend_color->color[3], + frag[3], pixel[3]); + } + + + if (sF[0] == sF[3]) { + src_factor[0] = src_factor[3]; + src_factor[1] = src_factor[3]; + src_factor[2] = src_factor[3]; + } else if (sF[0] == dF[3]) { + src_factor[0] = dst_factor[3]; + src_factor[1] = dst_factor[3]; + src_factor[2] = dst_factor[3]; + } else if (need_color_factor) { + emit_color_factor_calculation(f, + b->rgb_src_factor, + b->colormask, + blend_color, + frag, pixel, src_factor); + } + + + if (dF[0] == sF[3]) { + dst_factor[0] = src_factor[3]; + dst_factor[1] = src_factor[3]; + dst_factor[2] = src_factor[3]; + } else if (dF[0] == dF[3]) { + dst_factor[0] = dst_factor[3]; + dst_factor[1] = dst_factor[3]; + dst_factor[2] = dst_factor[3]; + } else if (dF[0] == sF[0]) { + dst_factor[0] = src_factor[0]; + dst_factor[1] = src_factor[1]; + dst_factor[2] = src_factor[2]; + } else if (need_color_factor) { + emit_color_factor_calculation(f, + b->rgb_dst_factor, + b->colormask, + blend_color, + frag, pixel, dst_factor); + } + + + + func[0] = b->rgb_func; + func[1] = func[0]; + func[2] = func[0]; + func[3] = b->alpha_func; + + for (i = 0; i < 4; ++i) { + if ((b->colormask & (1U << i)) != 0) { + emit_blend_calculation(f, + func[i], sF[i], dF[i], + frag[i], src_factor[i], + pixel[i], dst_factor[i]); + spe_selb(f, frag[i], pixel[i], frag[i], mask); + } else { + spe_or(f, frag[i], pixel[i], pixel[i]); + } + } + + spe_bi(f, 0, 0, 0); +} diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h new file mode 100644 index 0000000000..541c3b3be0 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright IBM Corporation 2008 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CELL_STATE_PER_FRAGMENT_H +#define CELL_STATE_PER_FRAGMENT_H + +extern void +cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa); + +extern void +cell_generate_alpha_blend(struct cell_blend_state *cb, + const struct pipe_blend_color *blend_color); + +#endif /* CELL_STATE_PER_FRAGMENT_H */ diff --git a/src/gallium/drivers/cell/spu/Makefile b/src/gallium/drivers/cell/spu/Makefile index c071de1900..115ca8cd90 100644 --- a/src/gallium/drivers/cell/spu/Makefile +++ b/src/gallium/drivers/cell/spu/Makefile @@ -19,6 +19,7 @@ SOURCES = \ spu_main.c \ spu_blend.c \ spu_dcache.c \ + spu_per_fragment_op.c \ spu_render.c \ spu_texture.c \ spu_tile.c \ diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 59300028d4..8e46f6e471 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -58,6 +58,9 @@ struct spu_vs_context draw; static unsigned char attribute_fetch_code_buffer[136 * PIPE_ATTRIB_MAX] ALIGN16_ATTRIB; +static unsigned char depth_stencil_code_buffer[4 * 64] + ALIGN16_ATTRIB; + /** * Tell the PPU that this SPU has finished copying a buffer to * local store and that it may be reused by the PPU. @@ -248,14 +251,26 @@ cmd_state_blend(const struct pipe_blend_state *state) static void -cmd_state_depth_stencil(const struct pipe_depth_stencil_alpha_state *state) +cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *state) { if (Debug) printf("SPU %u: DEPTH_STENCIL: ztest %d\n", spu.init.id, - state->depth.enabled); + state->read_depth); + + ASSERT_ALIGN16(state->base); + + mfc_get(depth_stencil_code_buffer, + (unsigned int) state->base, /* src */ + ROUNDUP16(state->size), + TAG_BATCH_BUFFER, + 0, /* tid */ + 0 /* rid */); + wait_on_mask(1 << TAG_BATCH_BUFFER); - memcpy(&spu.depth_stencil, state, sizeof(*state)); + spu.frag_test = (frag_test_func) depth_stencil_code_buffer; + spu.read_depth = state->read_depth; + spu.read_stencil = state->read_stencil; } @@ -415,9 +430,9 @@ cmd_batch(uint opcode) pos += (1 + ROUNDUP8(sizeof(struct pipe_blend_state)) / 8); break; case CELL_CMD_STATE_DEPTH_STENCIL: - cmd_state_depth_stencil((struct pipe_depth_stencil_alpha_state *) + cmd_state_depth_stencil((struct cell_command_depth_stencil_alpha_test *) &buffer[pos+1]); - pos += (1 + ROUNDUP8(sizeof(struct pipe_depth_stencil_alpha_state)) / 8); + pos += (1 + ROUNDUP8(sizeof(struct cell_command_depth_stencil_alpha_test)) / 8); break; case CELL_CMD_STATE_SAMPLER: cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]); diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index a13edd1702..444e218645 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -56,6 +56,17 @@ typedef union { #define TILE_STATUS_GETTING 5 /**< mfc_get() called but not yet arrived */ +struct spu_frag_test_results { + qword mask; + qword depth; + qword stencil; +}; + +typedef struct spu_frag_test_results (*frag_test_func)(qword frag_mask, + qword pixel_depth, qword pixel_stencil, qword frag_depth, + qword frag_alpha, qword facing); + + struct spu_framebuffer { void *color_start; /**< addr of color surface in main memory */ void *depth_start; /**< addr of depth surface in main memory */ @@ -79,8 +90,9 @@ struct spu_global struct cell_init_info init; struct spu_framebuffer fb; - struct pipe_blend_state blend_stencil; - struct pipe_depth_stencil_alpha_state depth_stencil; + boolean read_depth; + boolean read_stencil; + frag_test_func frag_test; struct pipe_blend_state blend; struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; struct cell_command_texture texture; diff --git a/src/gallium/drivers/cell/spu/spu_per_fragment_op.c b/src/gallium/drivers/cell/spu/spu_per_fragment_op.c new file mode 100644 index 0000000000..d42b522b41 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_per_fragment_op.c @@ -0,0 +1,191 @@ +/* + * (C) Copyright IBM Corporation 2008 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file spu_per_fragment_op.c + * SPU implementation various per-fragment operations. + * + * \author Ian Romanick + */ + +#include "pipe/p_format.h" +#include "spu_main.h" +#include "spu_per_fragment_op.h" + +#define ZERO 0x80 + +static void +read_ds_quad(tile_t *buffer, unsigned x, unsigned y, + enum pipe_format depth_format, qword *depth, + qword *stencil) +{ + const int ix = x / 2; + const int iy = y / 2; + + switch (depth_format) { + case PIPE_FORMAT_Z16_UNORM: { + qword *ptr = (qword *) &buffer->us8[iy][ix / 2]; + + const qword shuf_vec = (qword) { + ZERO, ZERO, 0, 1, ZERO, ZERO, 2, 3, + ZERO, ZERO, 4, 5, ZERO, ZERO, 6, 7 + }; + + + /* At even X values we want the first 4 shorts, and at odd X values we + * want the second 4 shorts. + */ + qword bias = (qword) spu_splats((unsigned char) ((ix & 0x01) << 3)); + qword bias_mask = si_fsmbi(0x3333); + qword sv = si_a(shuf_vec, si_and(bias_mask, bias)); + + *depth = si_shufb(*ptr, *ptr, sv); + *stencil = si_il(0); + break; + } + + + case PIPE_FORMAT_Z32_UNORM: { + qword *ptr = (qword *) &buffer->ui4[iy][ix]; + + *depth = *ptr; + *stencil = si_il(0); + break; + } + + + case PIPE_FORMAT_Z24S8_UNORM: { + qword *ptr = (qword *) &buffer->ui4[iy][ix]; + qword mask = si_fsmbi(0x7777); + + *depth = si_and(*ptr, mask); + *stencil = si_rotmai(si_andc(*ptr, mask), -24); + break; + } + + + default: + assert(0); + break; + } +} + + +static void +write_ds_quad(tile_t *buffer, unsigned x, unsigned y, + enum pipe_format depth_format, + qword depth, qword stencil) +{ + const int ix = x / 2; + const int iy = y / 2; + + (void) stencil; + + switch (depth_format) { + case PIPE_FORMAT_Z16_UNORM: { + qword *ptr = (qword *) &buffer->us8[iy][ix / 2]; + + qword sv = ((ix & 0x01) == 0) + ? (qword) { 2, 3, 6, 7, 10, 11, 14, 15, + 24, 25, 26, 27, 28, 29, 30, 31 } + : (qword) { 16, 17, 18, 19, 20 , 21, 22, 23, + 2, 3, 6, 7, 10, 11, 14, 15 }; + *ptr = si_shufb(depth, *ptr, sv); + break; + } + + + case PIPE_FORMAT_Z32_UNORM: { + qword *ptr = (qword *) &buffer->ui4[iy][ix]; + *ptr = depth; + break; + } + + + case PIPE_FORMAT_Z24S8_UNORM: { + qword *ptr = (qword *) &buffer->ui4[iy][ix]; + qword mask = si_fsmbi(0x7777); + + stencil = si_rotmai(stencil, 24); + *ptr = si_selb(stencil, depth, mask); + break; + } + + + default: + assert(0); + break; + } +} + + +qword +spu_do_depth_stencil(int x, int y, + qword frag_mask, qword frag_depth, qword frag_alpha, + qword facing) +{ + struct spu_frag_test_results result; + qword pixel_depth; + qword pixel_stencil; + + /* All of this preable code (everthing before the call to frag_test) should + * be generated on the PPU and upload to the SPU. + */ + if (spu.read_depth || spu.read_stencil) { + read_ds_quad(&spu.ztile, x, y, spu.fb.depth_format, + &pixel_depth, &pixel_stencil); + } + + switch (spu.fb.depth_format) { + case PIPE_FORMAT_Z16_UNORM: + frag_depth = si_fm(frag_depth, (qword)spu_splats((float)(0x0000ffffu))); + frag_depth = si_cfltu(frag_depth, 0); + break; + case PIPE_FORMAT_Z32_UNORM: + frag_depth = si_fm(frag_depth, (qword)spu_splats((float)(0xffffffffu))); + frag_depth = si_cfltu(frag_depth, 0); + break; + case PIPE_FORMAT_Z24S8_UNORM: + frag_depth = si_fm(frag_depth, (qword)spu_splats((float)(0x00ffffffu))); + frag_depth = si_cfltu(frag_depth, 0); + break; + default: + assert(0); + break; + } + + result = (*spu.frag_test)(frag_mask, pixel_depth, pixel_stencil, + frag_depth, frag_alpha, facing); + + + /* This code (everthing after the call to frag_test) should + * be generated on the PPU and upload to the SPU. + */ + if (spu.read_depth || spu.read_stencil) { + write_ds_quad(&spu.ztile, x, y, spu.fb.depth_format, + result.depth, result.stencil); + } + + return result.mask; +} diff --git a/src/gallium/drivers/cell/spu/spu_per_fragment_op.h b/src/gallium/drivers/cell/spu/spu_per_fragment_op.h new file mode 100644 index 0000000000..6571258699 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_per_fragment_op.h @@ -0,0 +1,32 @@ +/* + * (C) Copyright IBM Corporation 2008 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SPU_PER_FRAGMENT_OP +#define SPU_PER_FRAGMENT_OP + +extern qword +spu_do_depth_stencil(int x, int y, qword frag_mask, qword frag_depth, + qword frag_alpha, qword facing); + +#endif /* SPU_PER_FRAGMENT_OP */ diff --git a/src/gallium/drivers/cell/spu/spu_render.c b/src/gallium/drivers/cell/spu/spu_render.c index 20e77aa2e6..6df59abd36 100644 --- a/src/gallium/drivers/cell/spu/spu_render.c +++ b/src/gallium/drivers/cell/spu/spu_render.c @@ -98,7 +98,7 @@ my_tile(uint tx, uint ty) static INLINE void get_cz_tiles(uint tx, uint ty) { - if (spu.depth_stencil.depth.enabled) { + if (spu.read_depth) { if (spu.cur_ztile_status != TILE_STATUS_CLEAR) { //printf("SPU %u: getting Z tile %u, %u\n", spu.init.id, tx, ty); get_tile(tx, ty, &spu.ztile, TAG_READ_TILE_Z, 1); @@ -153,7 +153,7 @@ static INLINE void wait_put_cz_tiles(void) { wait_on_mask(1 << TAG_WRITE_TILE_COLOR); - if (spu.depth_stencil.depth.enabled) { + if (spu.read_depth) { wait_on_mask(1 << TAG_WRITE_TILE_Z); } } diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index be9624cf7d..81823f2463 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -38,8 +38,7 @@ #include "spu_texture.h" #include "spu_tile.h" #include "spu_tri.h" - -#include "spu_ztest.h" +#include "spu_per_fragment_op.h" /** Masks are uint[4] vectors with each element being 0 or 0xffffffff */ @@ -264,16 +263,12 @@ do_depth_test(int x, int y, mask_t quadmask) zvals.v = eval_z((float) x, (float) y); - if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) { - int ix = (x - setup.cliprect_minx) / 4; - int iy = (y - setup.cliprect_miny) / 2; - mask = spu_z16_test_less(zvals.v, &spu.ztile.us8[iy][ix], x>>1, quadmask); - } - else { - int ix = (x - setup.cliprect_minx) / 2; - int iy = (y - setup.cliprect_miny) / 2; - mask = spu_z32_test_less(zvals.v, &spu.ztile.ui4[iy][ix], quadmask); - } + mask = (mask_t) spu_do_depth_stencil(x - setup.cliprect_minx, + y - setup.cliprect_miny, + (qword) quadmask, + (qword) zvals.v, + (qword) spu_splats((unsigned char) 0x0ffu), + (qword) spu_splats((unsigned int) 0x01u)); if (spu_extract(spu_orx(mask), 0)) spu.cur_ztile_status = TILE_STATUS_DIRTY; @@ -299,7 +294,7 @@ emit_quad( int x, int y, mask_t mask ) sp->quad.first->run(sp->quad.first, &setup.quad); #else - if (spu.depth_stencil.depth.enabled) { + if (spu.read_depth) { mask = do_depth_test(x, y, mask); } @@ -434,7 +429,7 @@ static void flush_spans( void ) } ASSERT(spu.cur_ctile_status != TILE_STATUS_DEFINED); - if (spu.depth_stencil.depth.enabled) { + if (spu.read_depth) { if (spu.cur_ztile_status == TILE_STATUS_GETTING) { /* wait for mfc_get() to complete */ //printf("SPU: %u: waiting for ztile\n", spu.init.id); diff --git a/src/gallium/drivers/cell/spu/spu_ztest.h b/src/gallium/drivers/cell/spu/spu_ztest.h deleted file mode 100644 index ce8ad00339..0000000000 --- a/src/gallium/drivers/cell/spu/spu_ztest.h +++ /dev/null @@ -1,135 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Zbuffer/depth test code. - */ - - -#ifndef SPU_ZTEST_H -#define SPU_ZTEST_H - - -#ifdef __SPU__ -#include -#endif - - - -/** - * Perform Z testing for a 16-bit/value Z buffer. - * - * \param zvals vector of four fragment zvalues as floats - * \param zbuf ptr to vector of ushort[8] zbuffer values. Note that this - * contains the Z values for 2 quads, 8 pixels. - * \param x x coordinate of quad (only lsbit is significant) - * \param inMask indicates which fragments in the quad are alive - * \return new mask indicating which fragments are alive after ztest - */ -static INLINE vector unsigned int -spu_z16_test_less(vector float zvals, vector unsigned short *zbuf, - uint x, vector unsigned int inMask) -{ -#define ZERO 0x80 - vector unsigned int zvals_ui4, zbuf_ui4, mask; - - /* convert floats to uints in [0, 65535] */ - zvals_ui4 = spu_convtu(zvals, 32); /* convert to [0, 2^32] */ - zvals_ui4 = spu_rlmask(zvals_ui4, -16); /* right shift 16 */ - - /* XXX this conditional could be removed with a bit of work */ - if (x & 1) { - /* convert zbuffer values from ushorts to uints */ - /* gather lower four ushorts */ - zbuf_ui4 = spu_shuffle((vector unsigned int) *zbuf, - (vector unsigned int) *zbuf, - ((vector unsigned char) { - ZERO, ZERO, 8, 9, ZERO, ZERO, 10, 11, - ZERO, ZERO, 12, 13, ZERO, ZERO, 14, 15})); - /* mask = (zbuf_ui4 < zvals_ui4) ? ~0 : 0 */ - mask = spu_cmpgt(zbuf_ui4, zvals_ui4); - /* mask &= inMask */ - mask = spu_and(mask, inMask); - /* zbuf = mask ? zval : zbuf */ - zbuf_ui4 = spu_sel(zbuf_ui4, zvals_ui4, mask); - /* convert zbuffer values from uints back to ushorts, preserve lower 4 */ - *zbuf = (vector unsigned short) - spu_shuffle(zbuf_ui4, (vector unsigned int) *zbuf, - ((vector unsigned char) { - 16, 17, 18, 19, 20, 21, 22, 23, - 2, 3, 6, 7, 10, 11, 14, 15})); - } - else { - /* convert zbuffer values from ushorts to uints */ - /* gather upper four ushorts */ - zbuf_ui4 = spu_shuffle((vector unsigned int) *zbuf, - (vector unsigned int) *zbuf, - ((vector unsigned char) { - ZERO, ZERO, 0, 1, ZERO, ZERO, 2, 3, - ZERO, ZERO, 4, 5, ZERO, ZERO, 6, 7})); - /* mask = (zbuf_ui4 < zvals_ui4) ? ~0 : 0 */ - mask = spu_cmpgt(zbuf_ui4, zvals_ui4); - /* mask &= inMask */ - mask = spu_and(mask, inMask); - /* zbuf = mask ? zval : zbuf */ - zbuf_ui4 = spu_sel(zbuf_ui4, zvals_ui4, mask); - /* convert zbuffer values from uints back to ushorts, preserve upper 4 */ - *zbuf = (vector unsigned short) - spu_shuffle(zbuf_ui4, (vector unsigned int) *zbuf, - ((vector unsigned char) { - 2, 3, 6, 7, 10, 11, 14, 15, - 24, 25, 26, 27, 28, 29, 30, 31})); - } - return mask; -#undef ZERO -} - - -/** - * As above, but Zbuffer values as 32-bit uints - */ -static INLINE vector unsigned int -spu_z32_test_less(vector float zvals, vector unsigned int *zbuf_ptr, - vector unsigned int inMask) -{ - vector unsigned int zvals_ui4, mask, zbuf = *zbuf_ptr; - - /* convert floats to uints in [0, 0xffffffff] */ - zvals_ui4 = spu_convtu(zvals, 32); - /* mask = (zbuf < zvals_ui4) ? ~0 : 0 */ - mask = spu_cmpgt(zbuf, zvals_ui4); - /* mask &= inMask */ - mask = spu_and(mask, inMask); - /* zbuf = mask ? zval : zbuf */ - *zbuf_ptr = spu_sel(zbuf, zvals_ui4, mask); - - return mask; -} - - -#endif /* SPU_ZTEST_H */ -- cgit v1.2.3 From 9f106a8683ec89b873f0237fbb6930a63b89dfa0 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 17 Mar 2008 16:07:54 -0700 Subject: cell: Don't free NULL code pointers --- src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c index 842d713f84..24be65bff9 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c @@ -316,7 +316,9 @@ void spe_init_func(struct spe_function *p, unsigned code_size) void spe_release_func(struct spe_function *p) { - align_free(p->store); + if (p->store != NULL) { + align_free(p->store); + } p->store = NULL; p->csr = NULL; } -- cgit v1.2.3 From 9f93e6701902312edf48821bb4c0558c3d62aaa3 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 17 Mar 2008 16:09:28 -0700 Subject: cell: Don't segfault when unbinding alpha / stencil / depth test state --- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 2 +- src/gallium/drivers/cell/ppu/cell_state_emit.c | 17 ++++++++++++----- src/gallium/drivers/cell/spu/spu_main.c | 23 ++++++++++++++++------- 3 files changed, 29 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 66ede99d13..c880760e4b 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -116,7 +116,7 @@ cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe, draw_flush(cell->draw); - if (cdsa->code.store == NULL) { + if ((cdsa != NULL) && (cdsa->code.store == NULL)) { cell_generate_depth_stencil_test(cdsa); } diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index c8d5fdf709..e2cc9de48a 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -74,11 +74,18 @@ cell_emit_state(struct cell_context *cell) struct cell_command_depth_stencil_alpha_test dsat; - dsat.base = (intptr_t) cell->depth_stencil->code.store; - dsat.size = (char *) cell->depth_stencil->code.csr - - (char *) cell->depth_stencil->code.store; - dsat.read_depth = TRUE; - dsat.read_stencil = FALSE; + if (cell->depth_stencil != NULL) { + dsat.base = (intptr_t) cell->depth_stencil->code.store; + dsat.size = (char *) cell->depth_stencil->code.csr + - (char *) cell->depth_stencil->code.store; + dsat.read_depth = TRUE; + dsat.read_stencil = FALSE; + } else { + dsat.base = 0; + dsat.size = 0; + dsat.read_depth = FALSE; + dsat.read_stencil = FALSE; + } { uint32_t *p = cell->depth_stencil->code.store; diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 8e46f6e471..b8bb8e9449 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -260,13 +260,22 @@ cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *stat ASSERT_ALIGN16(state->base); - mfc_get(depth_stencil_code_buffer, - (unsigned int) state->base, /* src */ - ROUNDUP16(state->size), - TAG_BATCH_BUFFER, - 0, /* tid */ - 0 /* rid */); - wait_on_mask(1 << TAG_BATCH_BUFFER); + if (state->size != 0) { + mfc_get(depth_stencil_code_buffer, + (unsigned int) state->base, /* src */ + ROUNDUP16(state->size), + TAG_BATCH_BUFFER, + 0, /* tid */ + 0 /* rid */); + wait_on_mask(1 << TAG_BATCH_BUFFER); + } else { + /* If there is no code, emit a return instruction. + */ + depth_stencil_code_buffer[0] = 0x35; + depth_stencil_code_buffer[1] = 0x00; + depth_stencil_code_buffer[2] = 0x00; + depth_stencil_code_buffer[3] = 0x00; + } spu.frag_test = (frag_test_func) depth_stencil_code_buffer; spu.read_depth = state->read_depth; -- cgit v1.2.3 From de779c8d319b6269705cd7e6f2009243a771a2b9 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 17 Mar 2008 17:45:00 -0600 Subject: gallium: initial gen mipmap s/w fallback code --- src/gallium/auxiliary/util/u_gen_mipmap.c | 609 +++++++++++++++++++++++++++++- 1 file changed, 607 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index f0b822929e..8ca06281ab 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -34,6 +34,7 @@ #include "pipe/p_context.h" +#include "pipe/p_debug.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "pipe/p_util.h" @@ -48,6 +49,612 @@ #include "tgsi/util/tgsi_parse.h" + +enum dtype +{ + UBYTE, + UBYTE_3_3_2, + USHORT, + USHORT_4_4_4_4, + USHORT_5_6_5, + USHORT_1_5_5_5_REV, + UINT, + FLOAT, + HALF_FLOAT +}; + + +typedef ushort half_float; + + +#if 0 +extern half_float +float_to_half(float f); + +extern float +half_to_float(half_float h); +#endif + + +/** + * Average together two rows of a source image to produce a single new + * row in the dest image. It's legal for the two source rows to point + * to the same data. The source width must be equal to either the + * dest width or two times the dest width. + * \param datatype GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT, etc. + * \param comps number of components per pixel (1..4) + */ +static void +do_row(enum dtype datatype, uint comps, int srcWidth, + const void *srcRowA, const void *srcRowB, + int dstWidth, void *dstRow) +{ + const uint k0 = (srcWidth == dstWidth) ? 0 : 1; + const uint colStride = (srcWidth == dstWidth) ? 1 : 2; + + assert(comps >= 1); + assert(comps <= 4); + + /* This assertion is no longer valid with non-power-of-2 textures + assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth); + */ + + if (datatype == UBYTE && comps == 4) { + uint i, j, k; + const ubyte(*rowA)[4] = (const ubyte(*)[4]) srcRowA; + const ubyte(*rowB)[4] = (const ubyte(*)[4]) srcRowB; + ubyte(*dst)[4] = (ubyte(*)[4]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; + dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; + dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; + } + } + else if (datatype == UBYTE && comps == 3) { + uint i, j, k; + const ubyte(*rowA)[3] = (const ubyte(*)[3]) srcRowA; + const ubyte(*rowB)[3] = (const ubyte(*)[3]) srcRowB; + ubyte(*dst)[3] = (ubyte(*)[3]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; + dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; + } + } + else if (datatype == UBYTE && comps == 2) { + uint i, j, k; + const ubyte(*rowA)[2] = (const ubyte(*)[2]) srcRowA; + const ubyte(*rowB)[2] = (const ubyte(*)[2]) srcRowB; + ubyte(*dst)[2] = (ubyte(*)[2]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2; + } + } + else if (datatype == UBYTE && comps == 1) { + uint i, j, k; + const ubyte *rowA = (const ubyte *) srcRowA; + const ubyte *rowB = (const ubyte *) srcRowB; + ubyte *dst = (ubyte *) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2; + } + } + + else if (datatype == USHORT && comps == 4) { + uint i, j, k; + const ushort(*rowA)[4] = (const ushort(*)[4]) srcRowA; + const ushort(*rowB)[4] = (const ushort(*)[4]) srcRowB; + ushort(*dst)[4] = (ushort(*)[4]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; + dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; + dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; + } + } + else if (datatype == USHORT && comps == 3) { + uint i, j, k; + const ushort(*rowA)[3] = (const ushort(*)[3]) srcRowA; + const ushort(*rowB)[3] = (const ushort(*)[3]) srcRowB; + ushort(*dst)[3] = (ushort(*)[3]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; + dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; + } + } + else if (datatype == USHORT && comps == 2) { + uint i, j, k; + const ushort(*rowA)[2] = (const ushort(*)[2]) srcRowA; + const ushort(*rowB)[2] = (const ushort(*)[2]) srcRowB; + ushort(*dst)[2] = (ushort(*)[2]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; + } + } + else if (datatype == USHORT && comps == 1) { + uint i, j, k; + const ushort *rowA = (const ushort *) srcRowA; + const ushort *rowB = (const ushort *) srcRowB; + ushort *dst = (ushort *) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; + } + } + + else if (datatype == FLOAT && comps == 4) { + uint i, j, k; + const float(*rowA)[4] = (const float(*)[4]) srcRowA; + const float(*rowB)[4] = (const float(*)[4]) srcRowB; + float(*dst)[4] = (float(*)[4]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) * 0.25F; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) * 0.25F; + dst[i][2] = (rowA[j][2] + rowA[k][2] + + rowB[j][2] + rowB[k][2]) * 0.25F; + dst[i][3] = (rowA[j][3] + rowA[k][3] + + rowB[j][3] + rowB[k][3]) * 0.25F; + } + } + else if (datatype == FLOAT && comps == 3) { + uint i, j, k; + const float(*rowA)[3] = (const float(*)[3]) srcRowA; + const float(*rowB)[3] = (const float(*)[3]) srcRowB; + float(*dst)[3] = (float(*)[3]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) * 0.25F; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) * 0.25F; + dst[i][2] = (rowA[j][2] + rowA[k][2] + + rowB[j][2] + rowB[k][2]) * 0.25F; + } + } + else if (datatype == FLOAT && comps == 2) { + uint i, j, k; + const float(*rowA)[2] = (const float(*)[2]) srcRowA; + const float(*rowB)[2] = (const float(*)[2]) srcRowB; + float(*dst)[2] = (float(*)[2]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) * 0.25F; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) * 0.25F; + } + } + else if (datatype == FLOAT && comps == 1) { + uint i, j, k; + const float *rowA = (const float *) srcRowA; + const float *rowB = (const float *) srcRowB; + float *dst = (float *) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F; + } + } + +#if 0 + else if (datatype == HALF_FLOAT && comps == 4) { + uint i, j, k, comp; + const half_float(*rowA)[4] = (const half_float(*)[4]) srcRowA; + const half_float(*rowB)[4] = (const half_float(*)[4]) srcRowB; + half_float(*dst)[4] = (half_float(*)[4]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + for (comp = 0; comp < 4; comp++) { + float aj, ak, bj, bk; + aj = half_to_float(rowA[j][comp]); + ak = half_to_float(rowA[k][comp]); + bj = half_to_float(rowB[j][comp]); + bk = half_to_float(rowB[k][comp]); + dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F); + } + } + } + else if (datatype == HALF_FLOAT && comps == 3) { + uint i, j, k, comp; + const half_float(*rowA)[3] = (const half_float(*)[3]) srcRowA; + const half_float(*rowB)[3] = (const half_float(*)[3]) srcRowB; + half_float(*dst)[3] = (half_float(*)[3]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + for (comp = 0; comp < 3; comp++) { + float aj, ak, bj, bk; + aj = half_to_float(rowA[j][comp]); + ak = half_to_float(rowA[k][comp]); + bj = half_to_float(rowB[j][comp]); + bk = half_to_float(rowB[k][comp]); + dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F); + } + } + } + else if (datatype == HALF_FLOAT && comps == 2) { + uint i, j, k, comp; + const half_float(*rowA)[2] = (const half_float(*)[2]) srcRowA; + const half_float(*rowB)[2] = (const half_float(*)[2]) srcRowB; + half_float(*dst)[2] = (half_float(*)[2]) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + for (comp = 0; comp < 2; comp++) { + float aj, ak, bj, bk; + aj = half_to_float(rowA[j][comp]); + ak = half_to_float(rowA[k][comp]); + bj = half_to_float(rowB[j][comp]); + bk = half_to_float(rowB[k][comp]); + dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F); + } + } + } + else if (datatype == HALF_FLOAT && comps == 1) { + uint i, j, k; + const half_float *rowA = (const half_float *) srcRowA; + const half_float *rowB = (const half_float *) srcRowB; + half_float *dst = (half_float *) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + float aj, ak, bj, bk; + aj = half_to_float(rowA[j]); + ak = half_to_float(rowA[k]); + bj = half_to_float(rowB[j]); + bk = half_to_float(rowB[k]); + dst[i] = float_to_half((aj + ak + bj + bk) * 0.25F); + } + } +#endif + + else if (datatype == UINT && comps == 1) { + uint i, j, k; + const uint *rowA = (const uint *) srcRowA; + const uint *rowB = (const uint *) srcRowB; + float *dst = (float *) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4; + } + } + + else if (datatype == USHORT_5_6_5 && comps == 3) { + uint i, j, k; + const ushort *rowA = (const ushort *) srcRowA; + const ushort *rowB = (const ushort *) srcRowB; + ushort *dst = (ushort *) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + const int rowAr0 = rowA[j] & 0x1f; + const int rowAr1 = rowA[k] & 0x1f; + const int rowBr0 = rowB[j] & 0x1f; + const int rowBr1 = rowB[k] & 0x1f; + const int rowAg0 = (rowA[j] >> 5) & 0x3f; + const int rowAg1 = (rowA[k] >> 5) & 0x3f; + const int rowBg0 = (rowB[j] >> 5) & 0x3f; + const int rowBg1 = (rowB[k] >> 5) & 0x3f; + const int rowAb0 = (rowA[j] >> 11) & 0x1f; + const int rowAb1 = (rowA[k] >> 11) & 0x1f; + const int rowBb0 = (rowB[j] >> 11) & 0x1f; + const int rowBb1 = (rowB[k] >> 11) & 0x1f; + const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; + const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; + const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; + dst[i] = (blue << 11) | (green << 5) | red; + } + } + else if (datatype == USHORT_4_4_4_4 && comps == 4) { + uint i, j, k; + const ushort *rowA = (const ushort *) srcRowA; + const ushort *rowB = (const ushort *) srcRowB; + ushort *dst = (ushort *) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + const int rowAr0 = rowA[j] & 0xf; + const int rowAr1 = rowA[k] & 0xf; + const int rowBr0 = rowB[j] & 0xf; + const int rowBr1 = rowB[k] & 0xf; + const int rowAg0 = (rowA[j] >> 4) & 0xf; + const int rowAg1 = (rowA[k] >> 4) & 0xf; + const int rowBg0 = (rowB[j] >> 4) & 0xf; + const int rowBg1 = (rowB[k] >> 4) & 0xf; + const int rowAb0 = (rowA[j] >> 8) & 0xf; + const int rowAb1 = (rowA[k] >> 8) & 0xf; + const int rowBb0 = (rowB[j] >> 8) & 0xf; + const int rowBb1 = (rowB[k] >> 8) & 0xf; + const int rowAa0 = (rowA[j] >> 12) & 0xf; + const int rowAa1 = (rowA[k] >> 12) & 0xf; + const int rowBa0 = (rowB[j] >> 12) & 0xf; + const int rowBa1 = (rowB[k] >> 12) & 0xf; + const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; + const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; + const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; + const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; + dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red; + } + } + else if (datatype == USHORT_1_5_5_5_REV && comps == 4) { + uint i, j, k; + const ushort *rowA = (const ushort *) srcRowA; + const ushort *rowB = (const ushort *) srcRowB; + ushort *dst = (ushort *) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + const int rowAr0 = rowA[j] & 0x1f; + const int rowAr1 = rowA[k] & 0x1f; + const int rowBr0 = rowB[j] & 0x1f; + const int rowBr1 = rowB[k] & 0xf; + const int rowAg0 = (rowA[j] >> 5) & 0x1f; + const int rowAg1 = (rowA[k] >> 5) & 0x1f; + const int rowBg0 = (rowB[j] >> 5) & 0x1f; + const int rowBg1 = (rowB[k] >> 5) & 0x1f; + const int rowAb0 = (rowA[j] >> 10) & 0x1f; + const int rowAb1 = (rowA[k] >> 10) & 0x1f; + const int rowBb0 = (rowB[j] >> 10) & 0x1f; + const int rowBb1 = (rowB[k] >> 10) & 0x1f; + const int rowAa0 = (rowA[j] >> 15) & 0x1; + const int rowAa1 = (rowA[k] >> 15) & 0x1; + const int rowBa0 = (rowB[j] >> 15) & 0x1; + const int rowBa1 = (rowB[k] >> 15) & 0x1; + const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; + const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; + const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; + const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; + dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; + } + } + else if (datatype == UBYTE_3_3_2 && comps == 3) { + uint i, j, k; + const ubyte *rowA = (const ubyte *) srcRowA; + const ubyte *rowB = (const ubyte *) srcRowB; + ubyte *dst = (ubyte *) dstRow; + for (i = j = 0, k = k0; i < (uint) dstWidth; + i++, j += colStride, k += colStride) { + const int rowAr0 = rowA[j] & 0x3; + const int rowAr1 = rowA[k] & 0x3; + const int rowBr0 = rowB[j] & 0x3; + const int rowBr1 = rowB[k] & 0x3; + const int rowAg0 = (rowA[j] >> 2) & 0x7; + const int rowAg1 = (rowA[k] >> 2) & 0x7; + const int rowBg0 = (rowB[j] >> 2) & 0x7; + const int rowBg1 = (rowB[k] >> 2) & 0x7; + const int rowAb0 = (rowA[j] >> 5) & 0x7; + const int rowAb1 = (rowA[k] >> 5) & 0x7; + const int rowBb0 = (rowB[j] >> 5) & 0x7; + const int rowBb1 = (rowB[k] >> 5) & 0x7; + const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; + const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; + const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; + dst[i] = (blue << 5) | (green << 2) | red; + } + } + else { + debug_printf("bad format in do_row()"); + } +} + + +static void +format_to_type_comps(enum pipe_format pformat, + enum dtype *datatype, uint *comps) +{ + switch (pformat) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_B8G8R8A8_UNORM: + *datatype = UBYTE; + *comps = 4; + return; + case PIPE_FORMAT_A1R5G5B5_UNORM: + *datatype = USHORT_1_5_5_5_REV; + *comps = 4; + return; + case PIPE_FORMAT_A4R4G4B4_UNORM: + *datatype = USHORT_4_4_4_4; + *comps = 4; + return; + case PIPE_FORMAT_R5G6B5_UNORM: + *datatype = USHORT_5_6_5; + *comps = 3; + return; + case PIPE_FORMAT_U_L8: + case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_U_I8: + *datatype = UBYTE; + *comps = 1; + return; + case PIPE_FORMAT_U_A8_L8: + *datatype = UBYTE; + *comps = 2; + return; + default: + assert(0); + } +} + + +static void +reduce_1d(enum pipe_format pformat, + int srcWidth, const ubyte *srcPtr, + int dstWidth, ubyte *dstPtr) +{ + enum dtype datatype; + uint comps; + + format_to_type_comps(pformat, &datatype, &comps); + + /* we just duplicate the input row, kind of hack, saves code */ + do_row(datatype, comps, + srcWidth, srcPtr, srcPtr, + dstWidth, dstPtr); +} + + +/** + * Strides are in bytes. If zero, it'll be computed as width * bpp. + */ +static void +reduce_2d(enum pipe_format pformat, + int srcWidth, int srcHeight, + int srcRowStride, const ubyte *srcPtr, + int dstWidth, int dstHeight, + int dstRowStride, ubyte *dstPtr) +{ + enum dtype datatype; + uint comps; + const int bpt = pf_get_size(pformat); + const ubyte *srcA, *srcB; + ubyte *dst; + int row; + + format_to_type_comps(pformat, &datatype, &comps); + + if (!srcRowStride) + srcRowStride = bpt * srcWidth; + + if (!dstRowStride) + dstRowStride = bpt * dstWidth; + + /* Compute src and dst pointers */ + srcA = srcPtr; + if (srcHeight > 1) + srcB = srcA + srcRowStride; + else + srcB = srcA; + dst = dstPtr; + + for (row = 0; row < dstHeight; row++) { + do_row(datatype, comps, + srcWidth, srcA, srcB, + dstWidth, dst); + srcA += 2 * srcRowStride; + srcB += 2 * srcRowStride; + dst += dstRowStride; + } +} + + +static void +make_1d_mipmap(struct gen_mipmap_state *ctx, + struct pipe_texture *pt, + uint face, uint baseLevel, uint lastLevel) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_winsys *winsys = pipe->winsys; + const uint zslice = 0; + uint dstLevel; + + for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { + const uint srcLevel = dstLevel - 1; + struct pipe_surface *srcSurf, *dstSurf; + void *srcMap, *dstMap; + + srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice); + dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + + srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer, + PIPE_BUFFER_USAGE_CPU_READ) + + srcSurf->offset); + dstMap = ((ubyte *) winsys->buffer_map(winsys, dstSurf->buffer, + PIPE_BUFFER_USAGE_CPU_WRITE) + + dstSurf->offset); + + reduce_1d(pt->format, + srcSurf->width, srcMap, + dstSurf->width, dstMap); + + winsys->buffer_unmap(winsys, srcSurf->buffer); + winsys->buffer_unmap(winsys, dstSurf->buffer); + + pipe_surface_reference(&srcSurf, NULL); + pipe_surface_reference(&dstSurf, NULL); + } +} + + +static void +make_2d_mipmap(struct gen_mipmap_state *ctx, + struct pipe_texture *pt, + uint face, uint baseLevel, uint lastLevel) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_winsys *winsys = pipe->winsys; + const uint zslice = 0; + uint dstLevel; + const int bpt = pf_get_size(pt->format); + + for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { + const uint srcLevel = dstLevel - 1; + struct pipe_surface *srcSurf, *dstSurf; + ubyte *srcMap, *dstMap; + + srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice); + dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + + srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer, + PIPE_BUFFER_USAGE_CPU_READ) + + srcSurf->offset); + dstMap = ((ubyte *) winsys->buffer_map(winsys, dstSurf->buffer, + PIPE_BUFFER_USAGE_CPU_WRITE) + + dstSurf->offset); + + reduce_2d(pt->format, + srcSurf->width, srcSurf->height, + srcSurf->pitch * bpt, srcMap, + dstSurf->width, dstSurf->height, + dstSurf->pitch * bpt, dstMap); + + winsys->buffer_unmap(winsys, srcSurf->buffer); + winsys->buffer_unmap(winsys, dstSurf->buffer); + + pipe_surface_reference(&srcSurf, NULL); + pipe_surface_reference(&dstSurf, NULL); + } +} + + +static void +make_3d_mipmap(struct gen_mipmap_state *ctx, + struct pipe_texture *pt, + uint face, uint baseLevel, uint lastLevel) +{ +} + + +static void +fallback_gen_mipmap(struct gen_mipmap_state *ctx, + struct pipe_texture *pt, + uint face, uint baseLevel, uint lastLevel) +{ + switch (pt->target) { + case PIPE_TEXTURE_1D: + make_1d_mipmap(ctx, pt, face, baseLevel, lastLevel); + break; + case PIPE_TEXTURE_2D: + case PIPE_TEXTURE_CUBE: + make_2d_mipmap(ctx, pt, face, baseLevel, lastLevel); + break; + case PIPE_TEXTURE_3D: + make_3d_mipmap(ctx, pt, face, baseLevel, lastLevel); + break; + default: + assert(0); + } +} + + /** * Make simple fragment shader: * TEX OUT[0], IN[0], SAMP[0], 2D; @@ -415,9 +1022,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, /* check if we can render in the texture's format */ if (!screen->is_format_supported(screen, pt->format, PIPE_SURFACE)) { -#if 0 fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); -#endif return; } -- cgit v1.2.3 From b2b905b04c09dd5e701a43b0fecb73921b8f2866 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 18 Mar 2008 15:59:55 +0100 Subject: gallium: Silencium warnings on Windows. --- src/gallium/auxiliary/util/u_gen_mipmap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 8ca06281ab..d6d8c766ce 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -325,7 +325,7 @@ do_row(enum dtype datatype, uint comps, int srcWidth, float *dst = (float *) dstRow; for (i = j = 0, k = k0; i < (uint) dstWidth; i++, j += colStride, k += colStride) { - dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4; + dst[i] = (float) rowA[j] / 4 + (float) rowA[k] / 4 + (float) rowB[j] / 4 + (float) rowB[k] / 4; } } @@ -1070,8 +1070,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, * has trouble with min clamping so we also set the lod_bias to * try to work around that. */ - sampler.min_lod = sampler.max_lod = srcLevel; - sampler.lod_bias = srcLevel; + sampler.min_lod = sampler.max_lod = (float) srcLevel; + sampler.lod_bias = (float) srcLevel; sampler_cso = pipe->create_sampler_state(pipe, &sampler); pipe->bind_sampler_states(pipe, 1, &sampler_cso); -- cgit v1.2.3 From 544c27bcefd8a10318800c3cc2019514ee01a15b Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Mar 2008 09:22:41 -0600 Subject: gallium: utility for packing color, z values according to pipe_format --- src/gallium/auxiliary/util/u_pack_color.h | 125 ++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/gallium/auxiliary/util/u_pack_color.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h new file mode 100644 index 0000000000..93a18c1c7e --- /dev/null +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -0,0 +1,125 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Functions to produce packed colors/Z from floats. + */ + + +#include "pipe/p_compiler.h" + + +/** + * Note rgba outside [0,1] will be clamped for int pixel formats. + */ +static INLINE void +util_pack_color(const float rgba[4], enum pipe_format format, void *dest) +{ + ubyte r, g, b, a; + + if (pf_size_x(format) <= 8) { + /* format uses 8-bit components or less */ + UNCLAMPED_FLOAT_TO_UBYTE(r, rgba[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, rgba[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, rgba[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, rgba[3]); + } + + switch (format) { + case PIPE_FORMAT_R8G8B8A8_UNORM: + { + uint *d = (uint *) dest; + *d = (r << 24) | (g << 16) | (b << 8) | a; + } + return; + case PIPE_FORMAT_A8R8G8B8_UNORM: + { + uint *d = (uint *) dest; + *d = (a << 24) | (r << 16) | (g << 8) | b; + } + return; + case PIPE_FORMAT_B8G8R8A8_UNORM: + { + uint *d = (uint *) dest; + *d = (b << 24) | (g << 16) | (r << 8) | a; + } + return; + case PIPE_FORMAT_R5G6B5_UNORM: + { + ushort *d = (ushort *) dest; + *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); + } + return; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + { + float *d = (float *) dest; + d[0] = rgba[0]; + d[1] = rgba[1]; + d[2] = rgba[2]; + d[3] = rgba[3]; + } + return; + case PIPE_FORMAT_R32G32B32_FLOAT: + { + float *d = (float *) dest; + d[0] = rgba[0]; + d[1] = rgba[1]; + d[2] = rgba[2]; + } + return; + /* XXX lots more cases to add */ + default: + debug_printf("gallium: unhandled format in util_pack_color()"); + } +} + + +/** + * Note: it's assumed that z is in [0,1] + */ +static INLINE uint +util_pack_z(enum pipe_format format, double z) +{ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + return (uint) (z * 0xffff); + case PIPE_FORMAT_Z32_UNORM: + /* special-case to avoid overflow */ + if (z == 1.0) + return 0xffffffff; + else + return (uint) (z * 0xffffffff); + case PIPE_FORMAT_S8Z24_UNORM: + return (uint) (z * 0xffffff); + case PIPE_FORMAT_Z24S8_UNORM: + return ((uint) (z * 0xffffff)) << 8; + default: + debug_printf("gallium: unhandled fomrat in util_pack_z()"); + return 0; + } +} -- cgit v1.2.3 From e8f8b12bb940794cef8eff52ae8c908ad0604161 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Mar 2008 09:28:04 -0600 Subject: gallium: fix a mix-up in the uint[1] do_row() case --- src/gallium/auxiliary/util/u_gen_mipmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index d6d8c766ce..d47c677074 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -322,10 +322,10 @@ do_row(enum dtype datatype, uint comps, int srcWidth, uint i, j, k; const uint *rowA = (const uint *) srcRowA; const uint *rowB = (const uint *) srcRowB; - float *dst = (float *) dstRow; + uint *dst = (uint *) dstRow; for (i = j = 0, k = k0; i < (uint) dstWidth; i++, j += colStride, k += colStride) { - dst[i] = (float) rowA[j] / 4 + (float) rowA[k] / 4 + (float) rowB[j] / 4 + (float) rowB[k] / 4; + dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4; } } -- cgit v1.2.3 From d1ca951cc4f3392aeec2817e97fb9ade2c1b7881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 18 Mar 2008 11:49:02 +0000 Subject: gallium: Convenience debug_warning function. --- src/gallium/include/pipe/p_debug.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index f971ad3adc..f3dfa06216 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -158,6 +158,16 @@ void debug_mask_vprintf(uint32_t uuid, const char *format, va_list ap); + +#ifdef DEBUG +#define debug_warning(__msg) \ + debug_printf("%s:%i:warning: %s\n", __FILE__, __LINE__, (__msg)) +#else +#define debug_warning(__msg) \ + ((void)0) +#endif + + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 56ac9eb1f6e3826e4e8f7ab0f1fdbeed06c41c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 18 Mar 2008 11:49:29 +0000 Subject: gallium: Don't be pedantic about removing non exiting items from the table. --- src/gallium/auxiliary/util/u_handle_table.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c index d25872972a..fae4ac4039 100644 --- a/src/gallium/auxiliary/util/u_handle_table.c +++ b/src/gallium/auxiliary/util/u_handle_table.c @@ -226,9 +226,13 @@ handle_table_remove(struct handle_table *ht, index = handle - 1; object = ht->objects[index]; - assert(object); + if(!object) { + /* XXX: this warning may be noisy for legitimate use -- remove later */ + debug_warning("removing empty handle"); + return; + } - if(object && ht->destroy) + if(ht->destroy) ht->destroy(object); ht->objects[index] = NULL; -- cgit v1.2.3 From d26139d6a19aaf8b4dbbaa1ee937fed2283923e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 18 Mar 2008 12:01:14 +0000 Subject: d3d: Add function to walk through all items in the hash table. --- src/gallium/auxiliary/util/u_hash_table.c | 23 ++++++++++++++++++++++- src/gallium/auxiliary/util/u_hash_table.h | 5 +++++ 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c index ac2cb1b540..f3f16a8d94 100644 --- a/src/gallium/auxiliary/util/u_hash_table.c +++ b/src/gallium/auxiliary/util/u_hash_table.c @@ -187,6 +187,28 @@ hash_table_remove(struct hash_table *ht, } +enum pipe_error +hash_table_foreach(struct hash_table *ht, + enum pipe_error (*callback)(void *key, void *value, void *data), + void *data) +{ + struct cso_hash_iter iter; + struct hash_table_item *item; + enum pipe_error result; + + iter = cso_hash_first_node(ht->cso); + while (!cso_hash_iter_is_null(iter)) { + item = (struct hash_table_item *)cso_hash_iter_data(iter); + result = callback(item->key, item->value, data); + if(result != PIPE_OK) + return result; + iter = cso_hash_iter_next(iter); + } + + return PIPE_OK; +} + + void hash_table_destroy(struct hash_table *ht) { @@ -196,4 +218,3 @@ hash_table_destroy(struct hash_table *ht) FREE(ht); } - diff --git a/src/gallium/auxiliary/util/u_hash_table.h b/src/gallium/auxiliary/util/u_hash_table.h index d941f2c6b1..1583bd7548 100644 --- a/src/gallium/auxiliary/util/u_hash_table.h +++ b/src/gallium/auxiliary/util/u_hash_table.h @@ -75,6 +75,11 @@ hash_table_remove(struct hash_table *ht, void *key); +enum pipe_error +hash_table_foreach(struct hash_table *ht, + enum pipe_error (*callback)(void *key, void *value, void *data), + void *data); + void hash_table_destroy(struct hash_table *ht); -- cgit v1.2.3 From 527e30c53baadb396e5503e5188f0a9f1b2d2501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 18 Mar 2008 12:46:24 +0000 Subject: d3d: Allow to iterate over the handle table. --- src/gallium/auxiliary/util/u_handle_table.c | 22 ++++++++++++++++++++++ src/gallium/auxiliary/util/u_handle_table.h | 9 +++++++++ 2 files changed, 31 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c index fae4ac4039..0bfb9e1b4a 100644 --- a/src/gallium/auxiliary/util/u_handle_table.c +++ b/src/gallium/auxiliary/util/u_handle_table.c @@ -241,6 +241,28 @@ handle_table_remove(struct handle_table *ht, } +unsigned +handle_table_get_next_handle(struct handle_table *ht, + unsigned handle) +{ + unsigned index; + + for(index = handle; index < ht->size; ++index) { + if(!ht->objects[index]) + return index + 1; + } + + return 0; +} + + +unsigned +handle_table_get_first_handle(struct handle_table *ht) +{ + return handle_table_get_next_handle(ht, 0); +} + + void handle_table_destroy(struct handle_table *ht) { diff --git a/src/gallium/auxiliary/util/u_handle_table.h b/src/gallium/auxiliary/util/u_handle_table.h index a2f1f604ad..d080135c9f 100644 --- a/src/gallium/auxiliary/util/u_handle_table.h +++ b/src/gallium/auxiliary/util/u_handle_table.h @@ -100,6 +100,15 @@ void handle_table_destroy(struct handle_table *ht); +unsigned +handle_table_get_first_handle(struct handle_table *ht); + + +unsigned +handle_table_get_next_handle(struct handle_table *ht, + unsigned handle); + + #ifdef __cplusplus } #endif -- cgit v1.2.3 From f432ac5a1126997f10072760fe5afbf1b96f44f7 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 18 Mar 2008 10:23:39 -0700 Subject: cell: Move and (conditionally) silence debug code --- src/gallium/drivers/cell/ppu/cell_state_emit.c | 10 ------ .../drivers/cell/ppu/cell_state_per_fragment.c | 39 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index e2cc9de48a..4d589bcdbf 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -87,16 +87,6 @@ cell_emit_state(struct cell_context *cell) dsat.read_stencil = FALSE; } - { - uint32_t *p = cell->depth_stencil->code.store; - - printf("\t.text\n"); - for (/* empty */; p < cell->depth_stencil->code.csr; p++) { - printf("\t.long\t0x%04x\n", *p); - } - fflush(stdout); - } - emit_state_cmd(cell, CELL_CMD_STATE_DEPTH_STENCIL, &dsat, sizeof(dsat)); } diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index 60b64438d8..0ad9344cd4 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -525,6 +525,45 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) } spe_bi(f, 0, 0, 0); + + +#if 0 + { + const uint32_t *p = f->store; + unsigned i; + + printf("# alpha (%sabled)\n", + (dsa->alpha.enabled) ? "en" : "dis"); + printf("# func: %u\n", dsa->alpha.func); + printf("# ref: %.2f\n", dsa->alpha.ref); + + printf("# depth (%sabled)\n", + (dsa->depth.enabled) ? "en" : "dis"); + printf("# func: %u\n", dsa->depth.func); + + for (i = 0; i < 2; i++) { + printf("# %s stencil (%sabled)\n", + (i == 0) ? "front" : "back", + (dsa->stencil[i].enabled) ? "en" : "dis"); + + printf("# func: %u\n", dsa->stencil[i].func); + printf("# op (sf, zf, zp): %u %u %u\n", + dsa->stencil[i].fail_op, + dsa->stencil[i].zfail_op, + dsa->stencil[i].zpass_op); + printf("# ref value / value mask / write mask: %02x %02x %02x\n", + dsa->stencil[i].ref_value, + dsa->stencil[i].value_mask, + dsa->stencil[i].write_mask); + } + + printf("\t.text\n"); + for (/* empty */; p < f->csr; p++) { + printf("\t.long\t0x%04x\n", *p); + } + fflush(stdout); + } +#endif } -- cgit v1.2.3 From 5fdaebc51c5433ebc73f89690fd435dae2fcef60 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 18 Mar 2008 10:26:45 -0700 Subject: cell: Minor changes to make stencil not crash I'm not sure these are quite correct. The reflect demo doesn't assert anymore, but it doesn't produce correct results either. SPE-based vertex shader code needs to be disabled for relfect to run. --- src/gallium/drivers/cell/spu/spu_main.c | 12 +++++++++--- src/gallium/drivers/cell/spu/spu_tile.h | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index b8bb8e9449..122cf337a6 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -218,12 +218,18 @@ cmd_state_framebuffer(const struct cell_command_framebuffer *cmd) spu.fb.width_tiles = (spu.fb.width + TILE_SIZE - 1) / TILE_SIZE; spu.fb.height_tiles = (spu.fb.height + TILE_SIZE - 1) / TILE_SIZE; - if (spu.fb.depth_format == PIPE_FORMAT_Z32_UNORM) + switch (spu.fb.depth_format) { + case PIPE_FORMAT_Z32_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: spu.fb.zsize = 4; - else if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) + break; + case PIPE_FORMAT_Z16_UNORM: spu.fb.zsize = 2; - else + break; + default: spu.fb.zsize = 0; + break; + } if (spu.fb.color_format == PIPE_FORMAT_A8R8G8B8_UNORM) spu.color_shuffle = ((vector unsigned char) { diff --git a/src/gallium/drivers/cell/spu/spu_tile.h b/src/gallium/drivers/cell/spu/spu_tile.h index 3105b848fd..1b5491112d 100644 --- a/src/gallium/drivers/cell/spu/spu_tile.h +++ b/src/gallium/drivers/cell/spu/spu_tile.h @@ -56,13 +56,13 @@ clear_c_tile(tile_t *ctile) static INLINE void clear_z_tile(tile_t *ztile) { - if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) { + if (spu.fb.zsize == 2) { memset16((ushort*) ztile->us, spu.fb.depth_clear_value, TILE_SIZE * TILE_SIZE); } else { - ASSERT(spu.fb.depth_format == PIPE_FORMAT_Z32_UNORM); + ASSERT(spu.fb.zsize != 0); memset32((uint*) ztile->ui, spu.fb.depth_clear_value, TILE_SIZE * TILE_SIZE); -- cgit v1.2.3 From f3e686d24a54f65b98c9a61a952577faaf451148 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 18 Mar 2008 10:29:14 -0700 Subject: cell: Fix added whitespace errors. --- src/gallium/drivers/cell/ppu/cell_state_per_fragment.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index 0ad9344cd4..11c0aa5b23 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -532,12 +532,12 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) const uint32_t *p = f->store; unsigned i; - printf("# alpha (%sabled)\n", + printf("# alpha (%sabled)\n", (dsa->alpha.enabled) ? "en" : "dis"); printf("# func: %u\n", dsa->alpha.func); printf("# ref: %.2f\n", dsa->alpha.ref); - printf("# depth (%sabled)\n", + printf("# depth (%sabled)\n", (dsa->depth.enabled) ? "en" : "dis"); printf("# func: %u\n", dsa->depth.func); -- cgit v1.2.3 From 17b234ae3319d8a36afc44d0cceb30fea6b42d67 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 18 Mar 2008 11:47:37 -0700 Subject: cell: Fix depth read / write for s8z24. Stencil is still broken. --- src/gallium/drivers/cell/spu/spu_main.c | 1 + src/gallium/drivers/cell/spu/spu_per_fragment_op.c | 25 ++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 122cf337a6..937962285d 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -221,6 +221,7 @@ cmd_state_framebuffer(const struct cell_command_framebuffer *cmd) switch (spu.fb.depth_format) { case PIPE_FORMAT_Z32_UNORM: case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: spu.fb.zsize = 4; break; case PIPE_FORMAT_Z16_UNORM: diff --git a/src/gallium/drivers/cell/spu/spu_per_fragment_op.c b/src/gallium/drivers/cell/spu/spu_per_fragment_op.c index d42b522b41..06d68f5604 100644 --- a/src/gallium/drivers/cell/spu/spu_per_fragment_op.c +++ b/src/gallium/drivers/cell/spu/spu_per_fragment_op.c @@ -76,6 +76,16 @@ read_ds_quad(tile_t *buffer, unsigned x, unsigned y, case PIPE_FORMAT_Z24S8_UNORM: { + qword *ptr = (qword *) &buffer->ui4[iy][ix]; + qword mask = si_fsmbi(0xEEEE); + + *depth = si_rotmai(si_and(*ptr, mask), -8); + *stencil = si_andc(*ptr, mask); + break; + } + + + case PIPE_FORMAT_S8Z24_UNORM: { qword *ptr = (qword *) &buffer->ui4[iy][ix]; qword mask = si_fsmbi(0x7777); @@ -124,10 +134,20 @@ write_ds_quad(tile_t *buffer, unsigned x, unsigned y, case PIPE_FORMAT_Z24S8_UNORM: { + qword *ptr = (qword *) &buffer->ui4[iy][ix]; + qword mask = si_fsmbi(0xEEEE); + + depth = si_shli(depth, 8); + *ptr = si_selb(stencil, depth, mask); + break; + } + + + case PIPE_FORMAT_S8Z24_UNORM: { qword *ptr = (qword *) &buffer->ui4[iy][ix]; qword mask = si_fsmbi(0x7777); - stencil = si_rotmai(stencil, 24); + stencil = si_shli(stencil, 24); *ptr = si_selb(stencil, depth, mask); break; } @@ -167,11 +187,12 @@ spu_do_depth_stencil(int x, int y, frag_depth = si_cfltu(frag_depth, 0); break; case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: frag_depth = si_fm(frag_depth, (qword)spu_splats((float)(0x00ffffffu))); frag_depth = si_cfltu(frag_depth, 0); break; default: - assert(0); + ASSERT(0); break; } -- cgit v1.2.3 From 35a1ec53a7728311de22124c14b93dbbdee2ce90 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 18 Mar 2008 13:10:51 +0000 Subject: gallium: make REALLOC a bit more like realloc --- src/gallium/include/pipe/p_util.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index ef36ce75f7..c2e0f8c6a5 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -88,14 +88,16 @@ FREE( void *ptr ) static INLINE void * REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) { - void *new_ptr; - if( new_size <= old_size ) { - return old_ptr; - } - new_ptr = MALLOC( new_size ); - if( new_ptr ) { - memcpy( new_ptr, old_ptr, old_size ); + void *new_ptr = NULL; + + if (new_size != 0) { + new_ptr = MALLOC( new_size ); + + if( new_ptr && old_ptr ) { + memcpy( new_ptr, old_ptr, old_size ); + } } + FREE( old_ptr ); return new_ptr; } -- cgit v1.2.3 From fa69a6e1bb7a1fe96848456255e5370f1904706d Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 18 Mar 2008 15:59:06 -0700 Subject: cell: Correctly load stencil for PIPE_FORMAT_S8Z24_UNORM --- src/gallium/drivers/cell/spu/spu_per_fragment_op.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_per_fragment_op.c b/src/gallium/drivers/cell/spu/spu_per_fragment_op.c index 06d68f5604..b4cffeeb32 100644 --- a/src/gallium/drivers/cell/spu/spu_per_fragment_op.c +++ b/src/gallium/drivers/cell/spu/spu_per_fragment_op.c @@ -87,10 +87,9 @@ read_ds_quad(tile_t *buffer, unsigned x, unsigned y, case PIPE_FORMAT_S8Z24_UNORM: { qword *ptr = (qword *) &buffer->ui4[iy][ix]; - qword mask = si_fsmbi(0x7777); - *depth = si_and(*ptr, mask); - *stencil = si_rotmai(si_andc(*ptr, mask), -24); + *depth = si_and(*ptr, si_fsmbi(0x7777)); + *stencil = si_andi(si_roti(*ptr, 8), 0x0ff); break; } -- cgit v1.2.3 From fe40dae02d3f3a83ee5bb66819c1ed4a3f66da80 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 18 Mar 2008 15:59:33 -0700 Subject: cell: Fix various stencil test code-gen bugs --- .../drivers/cell/ppu/cell_state_per_fragment.c | 70 +++++++++++++--------- 1 file changed, 43 insertions(+), 27 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index 11c0aa5b23..9c47968459 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -199,52 +199,62 @@ emit_depth_test(struct pipe_depth_stencil_alpha_state *dsa, /** * \note Emits a maximum of 5 instructions. + * + * \warning + * Since \c out and \c in might be the same register, this routine cannot + * generate code that uses \c out as a temporary. */ static void emit_stencil_op(struct spe_function *f, int out, int in, int mask, unsigned op, unsigned ref) { const int clamp = spe_allocate_available_register(f); - const int tmp = spe_allocate_available_register(f); + const int clamp_mask = spe_allocate_available_register(f); + const int result = spe_allocate_available_register(f); switch(op) { case PIPE_STENCIL_OP_KEEP: assert(0); case PIPE_STENCIL_OP_ZERO: - spe_il(f, out, 0); + spe_il(f, result, 0); break; case PIPE_STENCIL_OP_REPLACE: - spe_il(f, out, ref); + spe_il(f, result, ref); break; case PIPE_STENCIL_OP_INCR: spe_il(f, clamp, 0x0ff); - spe_ai(f, out, in, 1); - spe_cgti(f, tmp, out, clamp); - spe_selb(f, out, out, clamp, tmp); + spe_ai(f, result, in, 1); + spe_clgti(f, clamp_mask, result, 0x0ff); + spe_selb(f, result, result, clamp, clamp_mask); break; case PIPE_STENCIL_OP_DECR: spe_il(f, clamp, 0); - spe_ai(f, out, in, -1); - spe_cgti(f, tmp, out, clamp); - spe_selb(f, out, clamp, out, tmp); + spe_ai(f, result, in, -1); + + /* If "(s-1) < 0" in signed arithemtic, then "(s-1) > MAX" in unsigned + * arithmetic. + */ + spe_clgti(f, clamp_mask, result, 0x0ff); + spe_selb(f, result, result, clamp, clamp_mask); break; case PIPE_STENCIL_OP_INCR_WRAP: - spe_ai(f, out, in, 1); + spe_ai(f, result, in, 1); break; case PIPE_STENCIL_OP_DECR_WRAP: - spe_ai(f, out, in, -1); + spe_ai(f, result, in, -1); break; case PIPE_STENCIL_OP_INVERT: - spe_nor(f, out, in, in); + spe_nor(f, result, in, in); break; default: assert(0); } - spe_release_register(f, tmp); - spe_release_register(f, clamp); + spe_selb(f, out, in, result, mask); - spe_selb(f, out, in, out, mask); + spe_release_register(f, result); + spe_release_register(f, clamp_mask); + spe_release_register(f, clamp); } @@ -261,13 +271,13 @@ emit_stencil_op(struct spe_function *f, * \param stencil Register containing values from stencil buffer * \param depth_pass Register to store mask of fragments passing stencil test * and depth test - * + * * \note * Emits a maximum of 10 + (3 * 5) = 25 instructions. */ static int emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, - unsigned face, + unsigned face, struct spe_function *f, int mask, int depth_mask, @@ -284,14 +294,17 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, const unsigned ref = (dsa->stencil[face].ref_value & dsa->stencil[face].value_mask); boolean complement = FALSE; - int stored = spe_allocate_available_register(f); + int stored; int tmp = spe_allocate_available_register(f); if ((dsa->stencil[face].func != PIPE_FUNC_NEVER) && (dsa->stencil[face].func != PIPE_FUNC_ALWAYS) && (dsa->stencil[face].value_mask != 0x0ff)) { + stored = spe_allocate_available_register(f); spe_andi(f, stored, stencil, dsa->stencil[face].value_mask); + } else { + stored = stencil; } @@ -332,7 +345,9 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, break; } - spe_release_register(f, stored); + if (stored != stencil) { + spe_release_register(f, stored); + } spe_release_register(f, tmp); @@ -362,7 +377,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, /* Conditionally emit code to update the stencil value under various * condititons. Note that there is no need to generate code under the * following circumstances: - * + * * - Stencil write mask is zero. * - For stencil-fail if the stencil test is ALWAYS * - For depth-fail if the stencil test is NEVER @@ -425,7 +440,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, spe_release_register(f, face_stencil); } else if (dsa->stencil[face].write_mask != 0x0ff) { int tmp = spe_allocate_available_register(f); - + spe_il(f, tmp, dsa->stencil[face].write_mask); spe_selb(f, stencil_src, stencil, stencil_src, tmp); @@ -492,12 +507,12 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) if (front_stencil != back_stencil) { spe_selb(f, stencil, back_stencil, front_stencil, facing); } - - if (back_stencil != stencil) { + + if (back_stencil != stencil) { spe_release_register(f, back_stencil); } - if (front_stencil != stencil) { + if (front_stencil != stencil) { spe_release_register(f, front_stencil); } @@ -505,10 +520,11 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) spe_release_register(f, back_depth_pass); } else { - if (front_stencil != stencil) { + if (front_stencil != stencil) { spe_or(f, stencil, front_stencil, front_stencil); spe_release_register(f, front_stencil); } + spe_or(f, mask, front_depth_pass, front_depth_pass); } spe_release_register(f, front_depth_pass); @@ -997,7 +1013,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, blend_color->color[3], frag[3], pixel[3]); } - + if (sF[0] == sF[3]) { src_factor[0] = src_factor[3]; @@ -1036,7 +1052,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, frag, pixel, dst_factor); } - + func[0] = b->rgb_func; func[1] = func[0]; -- cgit v1.2.3 From 31970c4633c5000916b0a36022ff761038f5cf5a Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Mar 2008 16:56:55 -0600 Subject: gallium: utilities for creating simple vertex/fragment shaders --- src/gallium/auxiliary/util/u_simple_shaders.c | 263 ++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_simple_shaders.h | 52 +++++ 2 files changed, 315 insertions(+) create mode 100644 src/gallium/auxiliary/util/u_simple_shaders.c create mode 100644 src/gallium/auxiliary/util/u_simple_shaders.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c new file mode 100644 index 0000000000..88e2ab05bd --- /dev/null +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -0,0 +1,263 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Simple vertex/fragment shader generators. + * + * @author Brian Paul + */ + + +#include "pipe/p_context.h" +#include "pipe/p_debug.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_shader_tokens.h" + +#include "util/u_simple_shaders.h" + +#include "tgsi/util/tgsi_build.h" +#include "tgsi/util/tgsi_dump.h" +#include "tgsi/util/tgsi_parse.h" + + + +/** + * Make simple vertex pass-through shader. + */ +void * +util_make_vertex_passthrough_shader(struct pipe_context *pipe, + uint num_attribs, + const uint *semantic_names, + const uint *semantic_indexes) +{ + uint maxTokens = 100; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + const uint procType = TGSI_PROCESSOR_VERTEX; + uint ti, i; + struct pipe_shader_state shader; + + tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0])); + + /* shader header + */ + *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + + header = (struct tgsi_header *) &tokens[1]; + *header = tgsi_build_header(); + + processor = (struct tgsi_processor *) &tokens[2]; + *processor = tgsi_build_processor( procType, header ); + + ti = 3; + + /* declare inputs */ + for (i = 0; i < num_attribs; i++) { + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + /* + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; + decl.Semantic.SemanticIndex = 0; + */ + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + } + + /* declare outputs */ + for (i = 0; i < num_attribs; i++) { + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = semantic_names[i]; + decl.Semantic.SemanticIndex = semantic_indexes[i]; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + } + + /* emit MOV instructions */ + for (i = 0; i < num_attribs; i++) { + /* MOVE out[i], in[i]; */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MOV; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = i; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = i; + ti += tgsi_build_full_instruction(&inst, + &tokens[ti], + header, + maxTokens - ti ); + } + + /* END instruction */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction(&inst, + &tokens[ti], + header, + maxTokens - ti ); + +#if 0 /*debug*/ + tgsi_dump(tokens, 0); +#endif + + shader.tokens = tokens; + return pipe->create_vs_state(pipe, &shader); +} + + + + +/** + * Make simple fragment texture shader: + * TEX OUT[0], IN[0], SAMP[0], 2D; + * END; + */ +void * +util_make_fragment_tex_shader(struct pipe_context *pipe) +{ + uint maxTokens = 100; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + const uint procType = TGSI_PROCESSOR_FRAGMENT; + uint ti; + struct pipe_shader_state shader; + + tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0])); + + /* shader header + */ + *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + + header = (struct tgsi_header *) &tokens[1]; + *header = tgsi_build_header(); + + processor = (struct tgsi_processor *) &tokens[2]; + *processor = tgsi_build_processor( procType, header ); + + ti = 3; + + /* declare TEX[0] input */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = 0; + /* XXX this could be linear... */ + decl.Declaration.Interpolate = 1; + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + /* declare color[0] output */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + /* declare sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + /* TEX instruction */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_TEX; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 2; + inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + inst.FullSrcRegisters[1].SrcRegister.Index = 0; + ti += tgsi_build_full_instruction(&inst, + &tokens[ti], + header, + maxTokens - ti ); + + /* END instruction */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction(&inst, + &tokens[ti], + header, + maxTokens - ti ); + +#if 0 /*debug*/ + tgsi_dump(tokens, 0); +#endif + + shader.tokens = tokens; + return pipe->create_fs_state(pipe, &shader); +} + diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h new file mode 100644 index 0000000000..3ef4f28801 --- /dev/null +++ b/src/gallium/auxiliary/util/u_simple_shaders.h @@ -0,0 +1,52 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef U_SIMPLE_SHADERS_H +#define U_SIMPLE_SHADERS_H + + +#include "pipe/p_compiler.h" + + +struct pipe_context; + + +extern void * +util_make_vertex_passthrough_shader(struct pipe_context *pipe, + uint num_attribs, + const uint *semantic_names, + const uint *semantic_indexes); + + +extern void * +util_make_fragment_tex_shader(struct pipe_context *pipe); + + +#endif + + -- cgit v1.2.3 From 4bd2b74441092154f0d0048822c6e36cfcc183af Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Mar 2008 16:57:23 -0600 Subject: gallium: use new simple shader utility routines --- src/gallium/auxiliary/util/u_gen_mipmap.c | 260 ++---------------------------- 1 file changed, 12 insertions(+), 248 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index d47c677074..e32ce768c4 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -43,6 +43,7 @@ #include "util/u_draw_quad.h" #include "util/u_gen_mipmap.h" +#include "util/u_simple_shaders.h" #include "tgsi/util/tgsi_build.h" #include "tgsi/util/tgsi_dump.h" @@ -655,252 +656,6 @@ fallback_gen_mipmap(struct gen_mipmap_state *ctx, } -/** - * Make simple fragment shader: - * TEX OUT[0], IN[0], SAMP[0], 2D; - * END; - */ -static void -make_fragment_shader(struct gen_mipmap_state *ctx) -{ - struct pipe_context *pipe = ctx->pipe; - uint maxTokens = 100; - struct tgsi_token *tokens; - struct tgsi_header *header; - struct tgsi_processor *processor; - struct tgsi_full_declaration decl; - struct tgsi_full_instruction inst; - const uint procType = TGSI_PROCESSOR_FRAGMENT; - uint ti = 0; - struct pipe_shader_state shader; - - tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0])); - - /* shader header - */ - *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); - - header = (struct tgsi_header *) &tokens[1]; - *header = tgsi_build_header(); - - processor = (struct tgsi_processor *) &tokens[2]; - *processor = tgsi_build_processor( procType, header ); - - ti = 3; - - /* declare TEX[0] input */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; - decl.Semantic.SemanticIndex = 0; - /* XXX this could be linear... */ - decl.Declaration.Interpolate = 1; - decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - maxTokens - ti); - - /* declare color[0] output */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_OUTPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; - decl.Semantic.SemanticIndex = 0; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - maxTokens - ti); - - /* declare sampler */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_SAMPLER; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - maxTokens - ti); - - /* TEX instruction */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_TEX; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - inst.FullDstRegisters[0].DstRegister.Index = 0; - inst.Instruction.NumSrcRegs = 2; - inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = 0; - inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - inst.FullSrcRegisters[1].SrcRegister.Index = 0; - ti += tgsi_build_full_instruction(&inst, - &tokens[ti], - header, - maxTokens - ti ); - - /* END instruction */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_END; - inst.Instruction.NumDstRegs = 0; - inst.Instruction.NumSrcRegs = 0; - ti += tgsi_build_full_instruction(&inst, - &tokens[ti], - header, - maxTokens - ti ); - -#if 0 /*debug*/ - tgsi_dump(tokens, 0); -#endif - - shader.tokens = tokens; - ctx->fs = pipe->create_fs_state(pipe, &shader); -} - - -/** - * Make simple fragment shader: - * MOV OUT[0], IN[0]; - * MOV OUT[1], IN[1]; - * END; - * - * XXX eliminate this when vertex passthrough-mode is more solid. - */ -static void -make_vertex_shader(struct gen_mipmap_state *ctx) -{ - struct pipe_context *pipe = ctx->pipe; - uint maxTokens = 100; - struct tgsi_token *tokens; - struct tgsi_header *header; - struct tgsi_processor *processor; - struct tgsi_full_declaration decl; - struct tgsi_full_instruction inst; - const uint procType = TGSI_PROCESSOR_VERTEX; - uint ti = 0; - struct pipe_shader_state shader; - - tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0])); - - /* shader header - */ - *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); - - header = (struct tgsi_header *) &tokens[1]; - *header = tgsi_build_header(); - - processor = (struct tgsi_processor *) &tokens[2]; - *processor = tgsi_build_processor( procType, header ); - - ti = 3; - - /* declare POS input */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - /* - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; - decl.Semantic.SemanticIndex = 0; - */ - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - maxTokens - ti); - /* declare TEX[0] input */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - /* - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; - decl.Semantic.SemanticIndex = 0; - */ - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 1; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - maxTokens - ti); - - /* declare POS output */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_OUTPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; - decl.Semantic.SemanticIndex = 0; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - maxTokens - ti); - - /* declare TEX[0] output */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_OUTPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; - decl.Semantic.SemanticIndex = 0; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 1; - ti += tgsi_build_full_declaration(&decl, - &tokens[ti], - header, - maxTokens - ti); - - /* MOVE out[0], in[0]; # POS */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_MOV; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - inst.FullDstRegisters[0].DstRegister.Index = 0; - inst.Instruction.NumSrcRegs = 1; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = 0; - ti += tgsi_build_full_instruction(&inst, - &tokens[ti], - header, - maxTokens - ti ); - - /* MOVE out[1], in[1]; # TEX */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_MOV; - inst.Instruction.NumDstRegs = 1; - inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - inst.FullDstRegisters[0].DstRegister.Index = 1; - inst.Instruction.NumSrcRegs = 1; - inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - inst.FullSrcRegisters[0].SrcRegister.Index = 1; - ti += tgsi_build_full_instruction(&inst, - &tokens[ti], - header, - maxTokens - ti ); - - /* END instruction */ - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = TGSI_OPCODE_END; - inst.Instruction.NumDstRegs = 0; - inst.Instruction.NumSrcRegs = 0; - ti += tgsi_build_full_instruction(&inst, - &tokens[ti], - header, - maxTokens - ti ); - -#if 0 /*debug*/ - tgsi_dump(tokens, 0); -#endif - - shader.tokens = tokens; - ctx->vs = pipe->create_vs_state(pipe, &shader); -} - - /** * Create a mipmap generation context. * The idea is to create one of these and re-use it each time we need to @@ -953,8 +708,17 @@ util_create_gen_mipmap(struct pipe_context *pipe) ctx->viewport.translate[3] = 0.0; #endif - make_vertex_shader(ctx); - make_fragment_shader(ctx); + /* vertex shader */ + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, + semantic_indexes); + } + + /* fragment shader */ + ctx->fs = util_make_fragment_tex_shader(pipe); return ctx; } -- cgit v1.2.3 From e5a20499d84ba8d270c3144f2c1c7615eeb077c7 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Mar 2008 16:58:15 -0600 Subject: gallium: make the gen_mipmap_state struct private --- src/gallium/auxiliary/util/u_gen_mipmap.c | 13 +++++++++++++ src/gallium/auxiliary/util/u_gen_mipmap.h | 13 +------------ 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index e32ce768c4..e18f8ab72a 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -50,6 +50,19 @@ #include "tgsi/util/tgsi_parse.h" +struct gen_mipmap_state +{ + struct pipe_context *pipe; + + void *blend; + void *depthstencil; + void *rasterizer; + /*struct pipe_viewport_state viewport;*/ + struct pipe_sampler_state *vs; + struct pipe_sampler_state *fs; +}; + + enum dtype { diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h index 6ee909f0a6..80496140a2 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.h +++ b/src/gallium/auxiliary/util/u_gen_mipmap.h @@ -31,18 +31,7 @@ #include "pipe/p_state.h" -struct gen_mipmap_state -{ - struct pipe_context *pipe; - - void *blend; - void *depthstencil; - void *rasterizer; - /*struct pipe_viewport_state viewport;*/ - struct pipe_sampler_state *vs; - struct pipe_sampler_state *fs; -}; - +struct gen_mipmap_state; extern struct gen_mipmap_state * -- cgit v1.2.3 From 8de9503d5d290c475a1940a71e58086ab3735f83 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Mar 2008 16:59:15 -0600 Subject: added u_simple_shaders.c --- src/gallium/auxiliary/util/Makefile | 1 + src/gallium/auxiliary/util/SConscript | 1 + 2 files changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index d11fa6e803..7af9b35d4b 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -12,6 +12,7 @@ C_SOURCES = \ u_handle_table.c \ u_hash_table.c \ u_mm.c \ + u_simple_shaders.c \ u_snprintf.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 6d4ba8643d..0eb1b8d9da 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -11,6 +11,7 @@ util = env.ConvenienceLibrary( 'u_handle_table.c', 'u_hash_table.c', 'u_mm.c', + 'u_simple_shaders.c', 'u_snprintf.c', ]) -- cgit v1.2.3 From 18f9fa9e71abdd999e49ef78729bfe3d92304312 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Mar 2008 16:59:46 -0600 Subject: gallium: protect against multi-#include --- src/gallium/auxiliary/util/u_pack_color.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 93a18c1c7e..cd13823985 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -31,7 +31,12 @@ */ +#ifndef U_PACK_COLOR_H +#define U_PACK_COLOR_H + + #include "pipe/p_compiler.h" +#include "pipe/p_format.h" /** @@ -123,3 +128,6 @@ util_pack_z(enum pipe_format format, double z) return 0; } } + + +#endif /* U_PACK_COLOR_H */ -- cgit v1.2.3 From 0abe462128a8a0725e006751e553f89fee2d7fa7 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Mar 2008 17:04:59 -0600 Subject: gallium: new pixel blit code Copy rectangular region from one surface to another w/ scaling. Disables most fragment operations. --- src/gallium/auxiliary/util/Makefile | 1 + src/gallium/auxiliary/util/SConscript | 1 + src/gallium/auxiliary/util/u_blit.c | 276 ++++++++++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_blit.h | 60 ++++++++ 4 files changed, 338 insertions(+) create mode 100644 src/gallium/auxiliary/util/u_blit.c create mode 100644 src/gallium/auxiliary/util/u_blit.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index 7af9b35d4b..9b6c2708b6 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -7,6 +7,7 @@ C_SOURCES = \ p_debug.c \ p_tile.c \ p_util.c \ + u_blit.c \ u_draw_quad.c \ u_gen_mipmap.c \ u_handle_table.c \ diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 0eb1b8d9da..b44f2d5e39 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -6,6 +6,7 @@ util = env.ConvenienceLibrary( 'p_debug.c', 'p_tile.c', 'p_util.c', + 'u_blit.c', 'u_draw_quad.c', 'u_gen_mipmap.c', 'u_handle_table.c', diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c new file mode 100644 index 0000000000..4b4ab8185f --- /dev/null +++ b/src/gallium/auxiliary/util/u_blit.c @@ -0,0 +1,276 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Copy/blit pixel rect between surfaces + * + * @author Brian Paul + */ + + +#include "pipe/p_context.h" +#include "pipe/p_debug.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_shader_tokens.h" + +#include "util/u_draw_quad.h" +#include "util/u_blit.h" +#include "util/u_simple_shaders.h" + + +struct blit_state +{ + struct pipe_context *pipe; + + void *blend; + void *depthstencil; + void *rasterizer; + void *samplers[2]; /* one for linear, one for nearest sampling */ + + /*struct pipe_viewport_state viewport;*/ + struct pipe_sampler_state *vs; + struct pipe_sampler_state *fs; +}; + + +/** + * Create state object for blit. + * Intended to be created once and re-used for many blit() calls. + */ +struct blit_state * +util_create_blit(struct pipe_context *pipe) +{ + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state depthstencil; + struct pipe_rasterizer_state rasterizer; + struct blit_state *ctx; + struct pipe_sampler_state sampler; + + ctx = CALLOC_STRUCT(blit_state); + if (!ctx) + return NULL; + + ctx->pipe = pipe; + + /* we don't use blending, but need to set valid values */ + memset(&blend, 0, sizeof(blend)); + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.colormask = PIPE_MASK_RGBA; + ctx->blend = pipe->create_blend_state(pipe, &blend); + + /* depth/stencil/alpha */ + memset(&depthstencil, 0, sizeof(depthstencil)); + ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil); + + /* rasterizer */ + memset(&rasterizer, 0, sizeof(rasterizer)); + rasterizer.front_winding = PIPE_WINDING_CW; + rasterizer.cull_mode = PIPE_WINDING_NONE; + rasterizer.bypass_clipping = 1; /* bypasses viewport too */ + /*rasterizer.bypass_vs = 1;*/ + ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer); + + /* samplers */ + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST; + sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; + sampler.normalized_coords = 1; + ctx->samplers[0] = pipe->create_sampler_state(pipe, &sampler); + + sampler.min_img_filter = PIPE_TEX_MIPFILTER_LINEAR; + sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR; + ctx->samplers[1] = pipe->create_sampler_state(pipe, &sampler); + + +#if 0 + /* viewport */ + ctx->viewport.scale[0] = 1.0; + ctx->viewport.scale[1] = 1.0; + ctx->viewport.scale[2] = 1.0; + ctx->viewport.scale[3] = 1.0; + ctx->viewport.translate[0] = 0.0; + ctx->viewport.translate[1] = 0.0; + ctx->viewport.translate[2] = 0.0; + ctx->viewport.translate[3] = 0.0; +#endif + + /* vertex shader */ + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, + semantic_indexes); + } + + /* fragment shader */ + ctx->fs = util_make_fragment_tex_shader(pipe); + + return ctx; +} + + +/** + * Destroy a blit context + */ +void +util_destroy_blit(struct blit_state *ctx) +{ + struct pipe_context *pipe = ctx->pipe; + + pipe->delete_blend_state(pipe, ctx->blend); + pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil); + pipe->delete_rasterizer_state(pipe, ctx->rasterizer); + pipe->delete_sampler_state(pipe, ctx->samplers[0]); + pipe->delete_sampler_state(pipe, ctx->samplers[1]); + + pipe->delete_vs_state(pipe, ctx->vs); + pipe->delete_fs_state(pipe, ctx->fs); + + FREE(ctx); +} + + +/** + * Copy pixel block from src surface to dst surface. + * Overlapping regions are acceptable. + * XXX need some control over blitting Z and/or stencil. + */ +void +util_blit_pixels(struct blit_state *ctx, + struct pipe_surface *src, + int srcX0, int srcY0, + int srcX1, int srcY1, + struct pipe_surface *dst, + int dstX0, int dstY0, + int dstX1, int dstY1, + float z, uint filter) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_texture texTemp, *tex; + struct pipe_surface *texSurf; + struct pipe_framebuffer_state fb; + const int srcW = abs(srcX1 - srcX0); + const int srcH = abs(srcY1 - srcY0); + const int srcLeft = MIN2(srcX0, srcX1); + const int srcTop = MIN2(srcY0, srcY1); + + assert(filter == PIPE_TEX_MIPFILTER_NEAREST || + filter == PIPE_TEX_MIPFILTER_LINEAR); + + if (srcLeft != srcX0) { + /* left-right flip */ + int tmp = dstX0; + dstX0 = dstX1; + dstX1 = tmp; + } + + if (srcTop != srcY0) { + /* up-down flip */ + int tmp = dstY0; + dstY0 = dstY1; + dstY1 = tmp; + } + + /* + * XXX for now we're always creating a temporary texture. + * Strictly speaking that's not always needed. + */ + + /* create temp texture */ + memset(&texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = src->format; + texTemp.last_level = 0; + texTemp.width[0] = srcW; + texTemp.height[0] = srcH; + texTemp.depth[0] = 1; + texTemp.compressed = 0; + texTemp.cpp = pf_get_bits(src->format) / 8; + + tex = screen->texture_create(screen, &texTemp); + if (!tex) + return; + + texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0); + + /* load temp texture */ + pipe->surface_copy(pipe, FALSE, + texSurf, 0, 0, /* dest */ + src, srcLeft, srcTop, /* src */ + srcW, srcH); /* size */ + + /* drawing dest */ + memset(&fb, 0, sizeof(fb)); + fb.num_cbufs = 1; + fb.cbufs[0] = dst; + pipe->set_framebuffer_state(pipe, &fb); + + /* sampler */ + if (filter == PIPE_TEX_MIPFILTER_NEAREST) + pipe->bind_sampler_states(pipe, 1, &ctx->samplers[0]); + else + pipe->bind_sampler_states(pipe, 1, &ctx->samplers[1]); + + /* texture */ + pipe->set_sampler_textures(pipe, 1, &tex); + + /* shaders */ + pipe->bind_fs_state(pipe, ctx->fs); + pipe->bind_vs_state(pipe, ctx->vs); + + /* misc state */ + pipe->bind_blend_state(pipe, ctx->blend); + pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil); + pipe->bind_rasterizer_state(pipe, ctx->rasterizer); + + /* draw quad */ + util_draw_texquad(pipe, dstX0, dstY0, dstX1, dstY1, z); + + /* unbind */ + pipe->set_sampler_textures(pipe, 0, NULL); + pipe->bind_sampler_states(pipe, 0, NULL); + + /* free stuff */ + pipe_surface_reference(&texSurf, NULL); + screen->texture_release(screen, &tex); + + /* Note: caller must restore pipe/gallium state at this time */ +} + diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h new file mode 100644 index 0000000000..0a8e05f88b --- /dev/null +++ b/src/gallium/auxiliary/util/u_blit.h @@ -0,0 +1,60 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef U_BLIT_H +#define U_BLIT_H + + +struct pipe_context; +struct pipe_surface; + + +struct copy_pixels_state; + + +extern struct blit_state * +util_create_blit(struct pipe_context *pipe); + + +extern void +util_destroy_blit(struct blit_state *ctx); + + + +extern void +util_blit_pixels(struct blit_state *ctx, + struct pipe_surface *src, + int srcX0, int srcY0, + int srcX1, int srcY1, + struct pipe_surface *dst, + int dstX0, int dstY0, + int dstX1, int dstY1, + float z, uint filter); + + +#endif -- cgit v1.2.3 From e5b19a0f833b5a3d5ffcf50d25a620d00bd8914b Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Mar 2008 17:14:05 -0600 Subject: gallium: added cso_unset_*() functions If we go behind the CSO context's back and set pipe state directly we need to invalidate the CSO's 'current' pointers. This will be revisited... --- src/gallium/auxiliary/cso_cache/cso_context.c | 36 ++++++++++++++++++++++++++- src/gallium/auxiliary/cso_cache/cso_context.h | 13 ++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index fd86bfaca9..294ac82281 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -149,6 +149,12 @@ void cso_set_blend(struct cso_context *ctx, } } +void cso_unset_blend(struct cso_context *ctx) +{ + ctx->blend = NULL; +} + + void cso_single_sampler(struct cso_context *ctx, unsigned idx, const struct pipe_sampler_state *templ) @@ -220,6 +226,15 @@ void cso_set_samplers( struct cso_context *ctx, cso_single_sampler_done( ctx ); } +void cso_unset_samplers( struct cso_context *ctx ) +{ + uint i; + for (i = 0; i < ctx->nr_samplers; i++) + ctx->samplers[i] = NULL; +} + + + void cso_set_depth_stencil_alpha(struct cso_context *ctx, const struct pipe_depth_stencil_alpha_state *templ) { @@ -252,6 +267,11 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx, } } +void cso_unset_depth_stencil_alpha(struct cso_context *ctx) +{ + ctx->depth_stencil = NULL; +} + void cso_set_rasterizer(struct cso_context *ctx, @@ -285,7 +305,10 @@ void cso_set_rasterizer(struct cso_context *ctx, } } - +void cso_unset_rasterizer(struct cso_context *ctx) +{ + ctx->rasterizer = NULL; +} @@ -320,6 +343,12 @@ void cso_set_fragment_shader(struct cso_context *ctx, } } +void cso_unset_fragment_shader(struct cso_context *ctx) +{ + ctx->fragment_shader = NULL; +} + + void cso_set_vertex_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) { @@ -350,3 +379,8 @@ void cso_set_vertex_shader(struct cso_context *ctx, ctx->pipe->bind_vs_state(ctx->pipe, handle); } } + +void cso_unset_vertex_shader(struct cso_context *ctx) +{ + ctx->vertex_shader = NULL; +} diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 1f2a630804..6aa619abf5 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -44,16 +44,25 @@ struct cso_context *cso_create_context( struct pipe_context *pipe ); void cso_set_blend( struct cso_context *cso, const struct pipe_blend_state *blend ); +void cso_unset_blend(struct cso_context *cso); + void cso_set_depth_stencil_alpha( struct cso_context *cso, const struct pipe_depth_stencil_alpha_state *dsa ); +void cso_unset_depth_stencil_alpha( struct cso_context *cso ); + void cso_set_rasterizer( struct cso_context *cso, const struct pipe_rasterizer_state *rasterizer ); +void cso_unset_rasterizer( struct cso_context *cso ); + void cso_set_samplers( struct cso_context *cso, unsigned count, const struct pipe_sampler_state **states ); +void cso_unset_samplers( struct cso_context *cso ); + + /* Alternate interface to support state trackers that like to modify * samplers one at a time: */ @@ -72,9 +81,13 @@ void cso_single_sampler_done( struct cso_context *cso ); void cso_set_fragment_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); +void cso_unset_fragment_shader( struct cso_context *cso ); + void cso_set_vertex_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); +void cso_unset_vertex_shader( struct cso_context *cso ); + void cso_destroy_context( struct cso_context *cso ); -- cgit v1.2.3 From d946b55543e483a15d8efbe4022d895c8444f6ac Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Mar 2008 17:15:25 -0600 Subject: gallium: s/copy_pixels_state/blit_state --- src/gallium/auxiliary/util/u_blit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h index 0a8e05f88b..a349be99ad 100644 --- a/src/gallium/auxiliary/util/u_blit.h +++ b/src/gallium/auxiliary/util/u_blit.h @@ -34,7 +34,7 @@ struct pipe_context; struct pipe_surface; -struct copy_pixels_state; +struct blit_state; extern struct blit_state * -- cgit v1.2.3 From 9f50a6a24c922926904c215249c3a0426dd433aa Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 18 Mar 2008 17:19:57 -0600 Subject: gallium: added braces to silence warning --- src/gallium/auxiliary/draw/draw_prim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index 888fa536ea..cb0277fb6c 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -169,11 +169,12 @@ void draw_do_flush( struct draw_context *draw, unsigned flags ) flushing = TRUE; if (flags >= DRAW_FLUSH_SHADER_QUEUE) { - if (draw->vs.queue_nr) + if (draw->vs.queue_nr) { if (draw->rasterizer->bypass_vs) fetch_and_store(draw); else (*draw->shader_queue_flush)(draw); + } if (flags >= DRAW_FLUSH_PRIM_QUEUE) { if (draw->pq.queue_nr) -- cgit v1.2.3 From e08501b45763cf177f03fb34b737050d23ba4bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 19 Mar 2008 16:41:07 +0000 Subject: gallium: Add generic enum and flags dumping utility functions. --- src/gallium/auxiliary/util/p_debug.c | 59 ++++++++++++++++++++++++++++++++++++ src/gallium/include/pipe/p_debug.h | 49 ++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index bb84e8096d..bd3a0221ea 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -52,6 +52,9 @@ rpl_EngDebugPrint(const char *format, ...) } int rpl_vsnprintf(char *, size_t, const char *, va_list); +int rpl_snprintf(char *str, size_t size, const char *format, ...); +#define vsnprintf rpl_vsnprintf +#define snprintf rpl_snprintf #endif @@ -181,3 +184,59 @@ void debug_mask_vprintf(uint32_t uuid, uint32_t what, const char *format, va_lis if(mask & what) debug_vprintf(format, ap); } + + +const char * +debug_dump_enum(const struct debug_named_value *names, + unsigned long value) +{ + static char rest[256]; + + while(names->name) { + if(names->value == value) + return names->name; + ++names; + } + + snprintf(rest, sizeof(rest), "0x%08x", value); + return rest; +} + + +const char * +debug_dump_flags(const struct debug_named_value *names, + unsigned long value) +{ + static char output[4096]; + static char rest[256]; + int first = 1; + + output[0] = '\0'; + + while(names->name) { + if((names->value & value) == names->value) { + if (!first) + strncat(output, "|", sizeof(output)); + else + first = 0; + strncat(output, names->name, sizeof(output)); + value &= ~names->value; + } + ++names; + } + + if (value) { + if (!first) + strncat(output, "|", sizeof(output)); + else + first = 0; + + snprintf(rest, sizeof(rest), "0x%08x", value); + strncat(output, rest, sizeof(output)); + } + + if(first) + return "0"; + + return output; +} diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index f3dfa06216..e924c1ef60 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -168,6 +168,55 @@ void debug_mask_vprintf(uint32_t uuid, #endif +/** + * Used by debug_dump_enum and debug_dump_flags to describe symbols. + */ +struct debug_named_value +{ + const char *name; + unsigned long value; +}; + + +/** + * Some C pre-processor magic to simplify creating named values. + * + * Example: + * @code + * static const debug_named_value my_names[] = { + * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_X), + * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Y), + * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Z), + * DEBUG_NAMED_VALUE_END + * }; + * + * ... + * debug_printf("%s = %s\n", + * name, + * debug_dump_enum(my_names, my_value)); + * ... + * @endcode + */ +#define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (unsigned long)__symbol} +#define DEBUG_NAMED_VALUE_END {NULL, 0} + + +/** + * Convert a enum value to a string. + */ +const char * +debug_dump_enum(const struct debug_named_value *names, + unsigned long value); + + +/** + * Convert binary flags value to a string. + */ +const char * +debug_dump_flags(const struct debug_named_value *names, + unsigned long value); + + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 4b39ba72166c6468525b19797c3d8a058814d789 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 19 Mar 2008 08:53:02 -0600 Subject: gallium: set tc->surface_map = NULL after unmapping --- src/gallium/drivers/softpipe/sp_tile_cache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 4caf2dd3fc..19f71887e7 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -156,6 +156,7 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, if (tc->surface_map) { /*assert(tc->surface != ps);*/ pipe_surface_unmap(tc->surface); + tc->surface_map = NULL; } pipe_surface_reference(&tc->surface, ps); -- cgit v1.2.3 From 7d95efde0a0e13e13c59444703bc47eb13926385 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 19 Mar 2008 11:12:48 -0600 Subject: gallium: implement CSO save/restore functions for use by meta operations (blit, gen-mipmaps, quad-clear, etc) Also, additional cso_set_*() functions for viewport, framebuffer, blend color, etc. state. --- src/gallium/auxiliary/cso_cache/cso_context.c | 202 +++++++++++++++++++++++--- src/gallium/auxiliary/cso_cache/cso_context.h | 53 +++++-- src/gallium/auxiliary/util/u_blit.c | 125 ++++++++-------- src/gallium/auxiliary/util/u_blit.h | 5 +- src/gallium/auxiliary/util/u_gen_mipmap.c | 116 ++++++++------- src/gallium/auxiliary/util/u_gen_mipmap.h | 6 +- 6 files changed, 357 insertions(+), 150 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 294ac82281..53d05ae6ce 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -52,11 +52,27 @@ struct cso_context { void *samplers[PIPE_MAX_SAMPLERS]; unsigned nr_samplers; - void *blend; - void *depth_stencil; - void *rasterizer; - void *fragment_shader; - void *vertex_shader; + void *samplers_saved[PIPE_MAX_SAMPLERS]; + unsigned nr_samplers_saved; + + struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; + uint nr_textures; + + struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS]; + uint nr_textures_saved; + + /** Current and saved state. + * The saved state is used as a 1-deep stack. + */ + void *blend, *blend_saved; + void *depth_stencil, *depth_stencil_saved; + void *rasterizer, *rasterizer_saved; + void *fragment_shader, *fragment_shader_saved; + void *vertex_shader, *vertex_shader_saved; + + struct pipe_framebuffer_state fb, fb_saved; + struct pipe_viewport_state vp, vp_saved; + struct pipe_blend_color blend_color; }; @@ -149,12 +165,23 @@ void cso_set_blend(struct cso_context *ctx, } } -void cso_unset_blend(struct cso_context *ctx) +void cso_save_blend(struct cso_context *ctx) +{ + assert(!ctx->blend_saved); + ctx->blend_saved = ctx->blend; +} + +void cso_restore_blend(struct cso_context *ctx) { - ctx->blend = NULL; + if (ctx->blend != ctx->blend_saved) { + ctx->blend = ctx->blend_saved; + ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend_saved); + } + ctx->blend_saved = NULL; } + void cso_single_sampler(struct cso_context *ctx, unsigned idx, const struct pipe_sampler_state *templ) @@ -226,13 +253,48 @@ void cso_set_samplers( struct cso_context *ctx, cso_single_sampler_done( ctx ); } -void cso_unset_samplers( struct cso_context *ctx ) +void cso_save_samplers(struct cso_context *ctx) +{ + ctx->nr_samplers_saved = ctx->nr_samplers; + memcpy(ctx->samplers_saved, ctx->samplers, sizeof(ctx->samplers)); +} + +void cso_restore_samplers(struct cso_context *ctx) +{ + cso_set_samplers(ctx, ctx->nr_samplers_saved, + (const struct pipe_sampler_state **) ctx->samplers_saved); +} + + +void cso_set_sampler_textures( struct cso_context *ctx, + uint count, + struct pipe_texture **textures ) { uint i; - for (i = 0; i < ctx->nr_samplers; i++) - ctx->samplers[i] = NULL; + + ctx->nr_textures = count; + + for (i = 0; i < count; i++) + ctx->textures[i] = textures[i]; + for ( ; i < PIPE_MAX_SAMPLERS; i++) + ctx->textures[i] = NULL; + + ctx->pipe->set_sampler_textures(ctx->pipe, count, textures); } +void cso_save_sampler_textures( struct cso_context *ctx ) +{ + ctx->nr_textures_saved = ctx->nr_textures; + memcpy(ctx->textures_saved, ctx->textures, sizeof(ctx->textures)); +} + +void cso_restore_sampler_textures( struct cso_context *ctx ) +{ + cso_set_sampler_textures(ctx, ctx->nr_textures_saved, ctx->textures_saved); + ctx->nr_textures_saved = 0; +} + + void cso_set_depth_stencil_alpha(struct cso_context *ctx, @@ -267,15 +329,25 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx, } } -void cso_unset_depth_stencil_alpha(struct cso_context *ctx) +void cso_save_depth_stencil_alpha(struct cso_context *ctx) { - ctx->depth_stencil = NULL; + assert(!ctx->depth_stencil_saved); + ctx->depth_stencil_saved = ctx->depth_stencil; +} + +void cso_restore_depth_stencil_alpha(struct cso_context *ctx) +{ + if (ctx->depth_stencil != ctx->depth_stencil_saved) { + ctx->depth_stencil = ctx->depth_stencil_saved; + ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->depth_stencil_saved); + } + ctx->depth_stencil_saved = NULL; } void cso_set_rasterizer(struct cso_context *ctx, - const struct pipe_rasterizer_state *templ) + const struct pipe_rasterizer_state *templ) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_rasterizer_state)); @@ -305,11 +377,20 @@ void cso_set_rasterizer(struct cso_context *ctx, } } -void cso_unset_rasterizer(struct cso_context *ctx) +void cso_save_rasterizer(struct cso_context *ctx) { - ctx->rasterizer = NULL; + assert(!ctx->rasterizer_saved); + ctx->rasterizer_saved = ctx->rasterizer; } +void cso_restore_rasterizer(struct cso_context *ctx) +{ + if (ctx->rasterizer != ctx->rasterizer_saved) { + ctx->rasterizer = ctx->rasterizer_saved; + ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rasterizer_saved); + } + ctx->rasterizer_saved = NULL; +} void cso_set_fragment_shader(struct cso_context *ctx, @@ -343,11 +424,23 @@ void cso_set_fragment_shader(struct cso_context *ctx, } } -void cso_unset_fragment_shader(struct cso_context *ctx) +void cso_save_fragment_shader(struct cso_context *ctx) { - ctx->fragment_shader = NULL; + assert(!ctx->fragment_shader_saved); + ctx->fragment_shader_saved = ctx->fragment_shader; } +void cso_restore_fragment_shader(struct cso_context *ctx) +{ + assert(ctx->fragment_shader_saved); + if (ctx->fragment_shader_saved != ctx->fragment_shader) { + ctx->pipe->bind_fs_state(ctx->pipe, ctx->fragment_shader_saved); + ctx->fragment_shader = ctx->fragment_shader_saved; + } + ctx->fragment_shader_saved = NULL; +} + + void cso_set_vertex_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) @@ -380,7 +473,78 @@ void cso_set_vertex_shader(struct cso_context *ctx, } } -void cso_unset_vertex_shader(struct cso_context *ctx) +void cso_save_vertex_shader(struct cso_context *ctx) { - ctx->vertex_shader = NULL; + assert(!ctx->vertex_shader_saved); + ctx->vertex_shader_saved = ctx->vertex_shader; +} + +void cso_restore_vertex_shader(struct cso_context *ctx) +{ + assert(ctx->vertex_shader_saved); + if (ctx->vertex_shader_saved != ctx->vertex_shader) { + ctx->pipe->bind_fs_state(ctx->pipe, ctx->vertex_shader_saved); + ctx->vertex_shader = ctx->vertex_shader_saved; + } + ctx->vertex_shader_saved = NULL; +} + + + +void cso_set_framebuffer(struct cso_context *ctx, + const struct pipe_framebuffer_state *fb) +{ + if (memcmp(&ctx->fb, fb, sizeof(*fb))) { + ctx->fb = *fb; + ctx->pipe->set_framebuffer_state(ctx->pipe, fb); + } +} + +void cso_save_framebuffer(struct cso_context *ctx) +{ + ctx->fb_saved = ctx->fb; +} + +void cso_restore_framebuffer(struct cso_context *ctx) +{ + if (memcmp(&ctx->fb, &ctx->fb_saved, sizeof(ctx->fb))) { + ctx->fb = ctx->fb_saved; + ctx->pipe->set_framebuffer_state(ctx->pipe, &ctx->fb); + } +} + + +void cso_set_viewport(struct cso_context *ctx, + const struct pipe_viewport_state *vp) +{ + if (memcmp(&ctx->vp, vp, sizeof(*vp))) { + ctx->vp = *vp; + ctx->pipe->set_viewport_state(ctx->pipe, vp); + } +} + +void cso_save_viewport(struct cso_context *ctx) +{ + ctx->vp_saved = ctx->vp; +} + + +void cso_restore_viewport(struct cso_context *ctx) +{ + if (memcmp(&ctx->vp, &ctx->vp_saved, sizeof(ctx->vp))) { + ctx->vp = ctx->vp_saved; + ctx->pipe->set_viewport_state(ctx->pipe, &ctx->vp); + } +} + + + + +void cso_set_blend_color(struct cso_context *ctx, + const struct pipe_blend_color *bc) +{ + if (memcmp(&ctx->blend_color, bc, sizeof(ctx->blend_color))) { + ctx->blend_color = *bc; + ctx->pipe->set_blend_color(ctx->pipe, bc); + } } diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 6aa619abf5..665e8d9911 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -41,27 +41,36 @@ struct cso_context; struct cso_context *cso_create_context( struct pipe_context *pipe ); +void cso_destroy_context( struct cso_context *cso ); + + + void cso_set_blend( struct cso_context *cso, const struct pipe_blend_state *blend ); +void cso_save_blend(struct cso_context *cso); +void cso_restore_blend(struct cso_context *cso); + -void cso_unset_blend(struct cso_context *cso); void cso_set_depth_stencil_alpha( struct cso_context *cso, const struct pipe_depth_stencil_alpha_state *dsa ); +void cso_save_depth_stencil_alpha(struct cso_context *cso); +void cso_restore_depth_stencil_alpha(struct cso_context *cso); + -void cso_unset_depth_stencil_alpha( struct cso_context *cso ); void cso_set_rasterizer( struct cso_context *cso, const struct pipe_rasterizer_state *rasterizer ); +void cso_save_rasterizer(struct cso_context *cso); +void cso_restore_rasterizer(struct cso_context *cso); + -void cso_unset_rasterizer( struct cso_context *cso ); void cso_set_samplers( struct cso_context *cso, unsigned count, const struct pipe_sampler_state **states ); - -void cso_unset_samplers( struct cso_context *cso ); - +void cso_save_samplers(struct cso_context *cso); +void cso_restore_samplers(struct cso_context *cso); /* Alternate interface to support state trackers that like to modify * samplers one at a time: @@ -73,6 +82,15 @@ void cso_single_sampler( struct cso_context *cso, void cso_single_sampler_done( struct cso_context *cso ); + +void cso_set_sampler_textures( struct cso_context *cso, + uint count, + struct pipe_texture **textures ); +void cso_save_sampler_textures( struct cso_context *cso ); +void cso_restore_sampler_textures( struct cso_context *cso ); + + + /* These aren't really sensible -- most of the time the api provides * object semantics for shaders anyway, and the cases where it doesn't * (eg mesa's internall-generated texenv programs), it will be up to @@ -80,15 +98,32 @@ void cso_single_sampler_done( struct cso_context *cso ); */ void cso_set_fragment_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); +void cso_save_fragment_shader(struct cso_context *cso); +void cso_restore_fragment_shader(struct cso_context *cso); + -void cso_unset_fragment_shader( struct cso_context *cso ); void cso_set_vertex_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); +void cso_save_vertex_shader(struct cso_context *cso); +void cso_restore_vertex_shader(struct cso_context *cso); -void cso_unset_vertex_shader( struct cso_context *cso ); -void cso_destroy_context( struct cso_context *cso ); + +void cso_set_framebuffer(struct cso_context *cso, + const struct pipe_framebuffer_state *fb); +void cso_save_framebuffer(struct cso_context *cso); +void cso_restore_framebuffer(struct cso_context *cso); + + +void cso_set_viewport(struct cso_context *cso, + const struct pipe_viewport_state *vp); +void cso_save_viewport(struct cso_context *cso); +void cso_restore_viewport(struct cso_context *cso); + + +void cso_set_blend_color(struct cso_context *cso, + const struct pipe_blend_color *bc); #ifdef __cplusplus diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 4b4ab8185f..123304fe68 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -45,15 +45,18 @@ #include "util/u_blit.h" #include "util/u_simple_shaders.h" +#include "cso_cache/cso_context.h" + struct blit_state { struct pipe_context *pipe; + struct cso_context *cso; - void *blend; - void *depthstencil; - void *rasterizer; - void *samplers[2]; /* one for linear, one for nearest sampling */ + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state depthstencil; + struct pipe_rasterizer_state rasterizer; + struct pipe_sampler_state sampler; /*struct pipe_viewport_state viewport;*/ struct pipe_sampler_state *vs; @@ -66,56 +69,44 @@ struct blit_state * Intended to be created once and re-used for many blit() calls. */ struct blit_state * -util_create_blit(struct pipe_context *pipe) +util_create_blit(struct pipe_context *pipe, struct cso_context *cso) { - struct pipe_blend_state blend; - struct pipe_depth_stencil_alpha_state depthstencil; - struct pipe_rasterizer_state rasterizer; struct blit_state *ctx; - struct pipe_sampler_state sampler; ctx = CALLOC_STRUCT(blit_state); if (!ctx) return NULL; ctx->pipe = pipe; + ctx->cso = cso; - /* we don't use blending, but need to set valid values */ - memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; - ctx->blend = pipe->create_blend_state(pipe, &blend); + /* disabled blending/masking */ + memset(&ctx->blend, 0, sizeof(ctx->blend)); + ctx->blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + ctx->blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + ctx->blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + ctx->blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + ctx->blend.colormask = PIPE_MASK_RGBA; - /* depth/stencil/alpha */ - memset(&depthstencil, 0, sizeof(depthstencil)); - ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil); + /* no-op depth/stencil/alpha */ + memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil)); /* rasterizer */ - memset(&rasterizer, 0, sizeof(rasterizer)); - rasterizer.front_winding = PIPE_WINDING_CW; - rasterizer.cull_mode = PIPE_WINDING_NONE; - rasterizer.bypass_clipping = 1; /* bypasses viewport too */ - /*rasterizer.bypass_vs = 1;*/ - ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer); + memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); + ctx->rasterizer.front_winding = PIPE_WINDING_CW; + ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; + ctx->rasterizer.bypass_clipping = 1; /* bypasses viewport too */ + /*ctx->rasterizer.bypass_vs = 1;*/ /* samplers */ - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; - sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST; - sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; - sampler.normalized_coords = 1; - ctx->samplers[0] = pipe->create_sampler_state(pipe, &sampler); - - sampler.min_img_filter = PIPE_TEX_MIPFILTER_LINEAR; - sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR; - ctx->samplers[1] = pipe->create_sampler_state(pipe, &sampler); - + memset(&ctx->sampler, 0, sizeof(ctx->sampler)); + ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + ctx->sampler.min_img_filter = 0; /* set later */ + ctx->sampler.mag_img_filter = 0; /* set later */ + ctx->sampler.normalized_coords = 1; #if 0 /* viewport */ @@ -153,12 +144,6 @@ util_destroy_blit(struct blit_state *ctx) { struct pipe_context *pipe = ctx->pipe; - pipe->delete_blend_state(pipe, ctx->blend); - pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil); - pipe->delete_rasterizer_state(pipe, ctx->rasterizer); - pipe->delete_sampler_state(pipe, ctx->samplers[0]); - pipe->delete_sampler_state(pipe, ctx->samplers[1]); - pipe->delete_vs_state(pipe, ctx->vs); pipe->delete_fs_state(pipe, ctx->fs); @@ -236,17 +221,24 @@ util_blit_pixels(struct blit_state *ctx, src, srcLeft, srcTop, /* src */ srcW, srcH); /* size */ - /* drawing dest */ - memset(&fb, 0, sizeof(fb)); - fb.num_cbufs = 1; - fb.cbufs[0] = dst; - pipe->set_framebuffer_state(pipe, &fb); + /* save state (restored below) */ + cso_save_blend(ctx->cso); + cso_save_depth_stencil_alpha(ctx->cso); + cso_save_rasterizer(ctx->cso); + cso_save_samplers(ctx->cso); + cso_save_sampler_textures(ctx->cso); + cso_save_framebuffer(ctx->cso); + + /* set misc state we care about */ + cso_set_blend(ctx->cso, &ctx->blend); + cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); + cso_set_rasterizer(ctx->cso, &ctx->rasterizer); /* sampler */ - if (filter == PIPE_TEX_MIPFILTER_NEAREST) - pipe->bind_sampler_states(pipe, 1, &ctx->samplers[0]); - else - pipe->bind_sampler_states(pipe, 1, &ctx->samplers[1]); + ctx->sampler.min_img_filter = filter; + ctx->sampler.mag_img_filter = filter; + cso_single_sampler(ctx->cso, 0, &ctx->sampler); + cso_single_sampler_done(ctx->cso); /* texture */ pipe->set_sampler_textures(pipe, 1, &tex); @@ -255,22 +247,25 @@ util_blit_pixels(struct blit_state *ctx, pipe->bind_fs_state(pipe, ctx->fs); pipe->bind_vs_state(pipe, ctx->vs); - /* misc state */ - pipe->bind_blend_state(pipe, ctx->blend); - pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil); - pipe->bind_rasterizer_state(pipe, ctx->rasterizer); + /* drawing dest */ + memset(&fb, 0, sizeof(fb)); + fb.num_cbufs = 1; + fb.cbufs[0] = dst; + cso_set_framebuffer(ctx->cso, &fb); /* draw quad */ util_draw_texquad(pipe, dstX0, dstY0, dstX1, dstY1, z); - /* unbind */ - pipe->set_sampler_textures(pipe, 0, NULL); - pipe->bind_sampler_states(pipe, 0, NULL); + /* restore state we changed */ + cso_restore_blend(ctx->cso); + cso_restore_depth_stencil_alpha(ctx->cso); + cso_restore_rasterizer(ctx->cso); + cso_restore_samplers(ctx->cso); + cso_restore_sampler_textures(ctx->cso); + cso_restore_framebuffer(ctx->cso); - /* free stuff */ + /* free the texture */ pipe_surface_reference(&texSurf, NULL); screen->texture_release(screen, &tex); - - /* Note: caller must restore pipe/gallium state at this time */ } diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h index a349be99ad..61f1d9bb32 100644 --- a/src/gallium/auxiliary/util/u_blit.h +++ b/src/gallium/auxiliary/util/u_blit.h @@ -30,15 +30,16 @@ #define U_BLIT_H + struct pipe_context; struct pipe_surface; +struct cso_context; struct blit_state; - extern struct blit_state * -util_create_blit(struct pipe_context *pipe); +util_create_blit(struct pipe_context *pipe, struct cso_context *cso); extern void diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index e18f8ab72a..27141c4d13 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -49,14 +49,18 @@ #include "tgsi/util/tgsi_dump.h" #include "tgsi/util/tgsi_parse.h" +#include "cso_cache/cso_context.h" + struct gen_mipmap_state { struct pipe_context *pipe; + struct cso_context *cso; - void *blend; - void *depthstencil; - void *rasterizer; + struct pipe_blend_state blend; + struct pipe_depth_stencil_alpha_state depthstencil; + struct pipe_rasterizer_state rasterizer; + struct pipe_sampler_state sampler; /*struct pipe_viewport_state viewport;*/ struct pipe_sampler_state *vs; struct pipe_sampler_state *fs; @@ -675,11 +679,9 @@ fallback_gen_mipmap(struct gen_mipmap_state *ctx, * generate a mipmap. */ struct gen_mipmap_state * -util_create_gen_mipmap(struct pipe_context *pipe) +util_create_gen_mipmap(struct pipe_context *pipe, + struct cso_context *cso) { - struct pipe_blend_state blend; - struct pipe_depth_stencil_alpha_state depthstencil; - struct pipe_rasterizer_state rasterizer; struct gen_mipmap_state *ctx; ctx = CALLOC_STRUCT(gen_mipmap_state); @@ -687,27 +689,36 @@ util_create_gen_mipmap(struct pipe_context *pipe) return NULL; ctx->pipe = pipe; + ctx->cso = cso; - /* we don't use blending, but need to set valid values */ - memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.colormask = PIPE_MASK_RGBA; - ctx->blend = pipe->create_blend_state(pipe, &blend); + /* disabled blending/masking */ + memset(&ctx->blend, 0, sizeof(ctx->blend)); + ctx->blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + ctx->blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + ctx->blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + ctx->blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + ctx->blend.colormask = PIPE_MASK_RGBA; - /* depth/stencil/alpha */ - memset(&depthstencil, 0, sizeof(depthstencil)); - ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil); + /* no-op depth/stencil/alpha */ + memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil)); /* rasterizer */ - memset(&rasterizer, 0, sizeof(rasterizer)); - rasterizer.front_winding = PIPE_WINDING_CW; - rasterizer.cull_mode = PIPE_WINDING_NONE; - rasterizer.bypass_clipping = 1; /* bypasses viewport too */ - //rasterizer.bypass_vs = 1; - ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer); + memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); + ctx->rasterizer.front_winding = PIPE_WINDING_CW; + ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; + ctx->rasterizer.bypass_clipping = 1; /* bypasses viewport too */ + /*ctx->rasterizer.bypass_vs = 1;*/ + + /* sampler state */ + memset(&ctx->sampler, 0, sizeof(ctx->sampler)); + ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; + ctx->sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + ctx->sampler.normalized_coords = 1; + #if 0 /* viewport */ @@ -745,9 +756,6 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) { struct pipe_context *pipe = ctx->pipe; - pipe->delete_blend_state(pipe, ctx->blend); - pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil); - pipe->delete_rasterizer_state(pipe, ctx->rasterizer); pipe->delete_vs_state(pipe, ctx->vs); pipe->delete_fs_state(pipe, ctx->fs); @@ -792,8 +800,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_framebuffer_state fb; - struct pipe_sampler_state sampler; - void *sampler_cso; uint dstLevel; uint zslice = 0; @@ -803,30 +809,29 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, return; } - /* init framebuffer state */ - memset(&fb, 0, sizeof(fb)); - fb.num_cbufs = 1; - - /* sampler state */ - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; - sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.normalized_coords = 1; + /* save state (restored below) */ + cso_save_blend(ctx->cso); + cso_save_depth_stencil_alpha(ctx->cso); + cso_save_rasterizer(ctx->cso); + cso_save_samplers(ctx->cso); + cso_save_sampler_textures(ctx->cso); + cso_save_framebuffer(ctx->cso); /* bind our state */ - pipe->bind_blend_state(pipe, ctx->blend); - pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil); - pipe->bind_rasterizer_state(pipe, ctx->rasterizer); + cso_set_blend(ctx->cso, &ctx->blend); + cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); + cso_set_rasterizer(ctx->cso, &ctx->rasterizer); + pipe->bind_vs_state(pipe, ctx->vs); pipe->bind_fs_state(pipe, ctx->fs); #if 0 pipe->set_viewport_state(pipe, &ctx->viewport); #endif + /* init framebuffer state */ + memset(&fb, 0, sizeof(fb)); + fb.num_cbufs = 1; + /* * XXX for small mipmap levels, it may be faster to use the software * fallback path... @@ -838,7 +843,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, * Setup framebuffer / dest surface */ fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); - pipe->set_framebuffer_state(pipe, &fb); + cso_set_framebuffer(ctx->cso, &fb); /* * Setup sampler state @@ -847,11 +852,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, * has trouble with min clamping so we also set the lod_bias to * try to work around that. */ - sampler.min_lod = sampler.max_lod = (float) srcLevel; - sampler.lod_bias = (float) srcLevel; - sampler_cso = pipe->create_sampler_state(pipe, &sampler); - pipe->bind_sampler_states(pipe, 1, &sampler_cso); - + ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel; + ctx->sampler.lod_bias = (float) srcLevel; + cso_single_sampler(ctx->cso, 0, &ctx->sampler); + cso_single_sampler_done(ctx->cso); #if 0 simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]); #endif @@ -869,9 +873,13 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, pipe->flush(pipe, PIPE_FLUSH_WAIT); /*pipe->texture_update(pipe, pt); not really needed */ - - pipe->delete_sampler_state(pipe, sampler_cso); } - /* Note: caller must restore pipe/gallium state at this time */ + /* restore state we changed */ + cso_restore_blend(ctx->cso); + cso_restore_depth_stencil_alpha(ctx->cso); + cso_restore_rasterizer(ctx->cso); + cso_restore_samplers(ctx->cso); + cso_restore_sampler_textures(ctx->cso); + cso_restore_framebuffer(ctx->cso); } diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h index 80496140a2..eeabf3bf07 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.h +++ b/src/gallium/auxiliary/util/u_gen_mipmap.h @@ -31,11 +31,15 @@ #include "pipe/p_state.h" +struct pipe_context; +struct pipe_texture; +struct cso_context; + struct gen_mipmap_state; extern struct gen_mipmap_state * -util_create_gen_mipmap(struct pipe_context *pipe); +util_create_gen_mipmap(struct pipe_context *pipe, struct cso_context *cso); extern void -- cgit v1.2.3 From b4f03d0c98674c83d06edfa767a7898eca5d4ef8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 19 Mar 2008 17:35:42 +0000 Subject: gallium: explict float casts --- src/gallium/auxiliary/util/u_blit.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 123304fe68..d05dae3af8 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -254,7 +254,11 @@ util_blit_pixels(struct blit_state *ctx, cso_set_framebuffer(ctx->cso, &fb); /* draw quad */ - util_draw_texquad(pipe, dstX0, dstY0, dstX1, dstY1, z); + util_draw_texquad(pipe, + (float)dstX0, + (float)dstY0, + (float)dstX1, + (float)dstY1, z); /* restore state we changed */ cso_restore_blend(ctx->cso); -- cgit v1.2.3 From df5ba799fa929d4c739be9d11d3f1000afc265b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 19 Mar 2008 20:46:08 +0000 Subject: gallium: Fix broken logic. --- src/gallium/auxiliary/util/u_handle_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c index 0bfb9e1b4a..8b0f7fca4b 100644 --- a/src/gallium/auxiliary/util/u_handle_table.c +++ b/src/gallium/auxiliary/util/u_handle_table.c @@ -248,7 +248,7 @@ handle_table_get_next_handle(struct handle_table *ht, unsigned index; for(index = handle; index < ht->size; ++index) { - if(!ht->objects[index]) + if(ht->objects[index]) return index + 1; } -- cgit v1.2.3 From b45669283fe4b9af9f2e78ac3c0c84207cf63775 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 19 Mar 2008 16:41:54 -0600 Subject: gallium: fix bug in cso_single_sampler_done() in computation of nr_samplers Need to find highest used sampler so search from end toward beginning. --- src/gallium/auxiliary/cso_cache/cso_context.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 53d05ae6ce..01fe216447 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -217,9 +217,11 @@ void cso_single_sampler_done( struct cso_context *ctx ) { unsigned i; - for (i = 0; i < 8; i++) - if (ctx->samplers[i] == NULL) + /* find highest non-null sampler */ + for (i = PIPE_MAX_SAMPLERS; i > 0; i--) { + if (ctx->samplers[i - 1] != NULL) break; + } ctx->nr_samplers = i; -- cgit v1.2.3 From 4984487bc3338fc351a0631eaa4515e4adbb86a9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 19 Mar 2008 17:08:16 -0600 Subject: gallium: add face, dirtyLevels params to pipe->texture_update() This provides better information about which images in texture object have changed. Also, call texture_update() from more places previously missed. --- src/gallium/auxiliary/draw/draw_aaline.c | 1 + src/gallium/auxiliary/draw/draw_pstipple.c | 2 +- src/gallium/auxiliary/util/u_gen_mipmap.c | 3 ++- src/gallium/drivers/cell/ppu/cell_texture.c | 3 ++- src/gallium/drivers/i915simple/i915_texture.c | 3 ++- src/gallium/drivers/i965simple/brw_tex_layout.c | 3 ++- src/gallium/drivers/softpipe/sp_texture.c | 3 ++- src/gallium/include/pipe/p_context.h | 6 ++---- 8 files changed, 14 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index f2b983374e..b4fa6bd967 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -410,6 +410,7 @@ aaline_create_texture(struct aaline_stage *aaline) /* unmap */ pipe_surface_unmap(surface); pipe_surface_reference(&surface, NULL); + pipe->texture_update(pipe, aaline->texture, 0, (1 << level)); } } diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index 09d542002f..9d154a6838 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -374,7 +374,7 @@ pstip_update_texture(struct pstip_stage *pstip) /* unmap */ pipe_surface_unmap(surface); pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, pstip->texture); + pipe->texture_update(pipe, pstip->texture, 0, 0x1); } diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 27141c4d13..028b180a77 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -872,7 +872,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, pipe->flush(pipe, PIPE_FLUSH_WAIT); - /*pipe->texture_update(pipe, pt); not really needed */ + /* need to signal that the texture has changed _after_ rendering to it */ + pipe->texture_update(pipe, pt, face, (1 << dstLevel)); } /* restore state we changed */ diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index e235421107..9c694e136d 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -134,7 +134,8 @@ cell_texture_release_screen(struct pipe_screen *screen, static void -cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, + uint face, uint levelsMask) { /* XXX TO DO: re-tile the texture data ... */ diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index ef5adff550..c39e747705 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -542,7 +542,8 @@ i915_texture_release_screen(struct pipe_screen *screen, static void -i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, + uint face, uint levelsMask) { /* no-op? */ } diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index b24ac87c37..b580f98204 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -358,7 +358,8 @@ brw_texture_release_screen(struct pipe_screen *screen, static void -brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, + uint face, uint levelsMask) { /* no-op? */ } diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 64bf353aa4..a98b3b1a4a 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -174,7 +174,8 @@ softpipe_get_tex_surface_screen(struct pipe_screen *screen, static void softpipe_texture_update(struct pipe_context *pipe, - struct pipe_texture *texture) + struct pipe_texture *texture, + uint face, uint levelsMask) { struct softpipe_context *softpipe = softpipe_context(pipe); uint unit; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index b64948f0f3..a3824601be 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -192,12 +192,10 @@ struct pipe_context { /** * Called when texture data is changed. - * Note: we could pass some hints about which mip levels or cube faces - * have changed... - * XXX this may go away - could pass a 'write' flag to get_tex_surface() */ void (*texture_update)(struct pipe_context *pipe, - struct pipe_texture *texture); + struct pipe_texture *texture, + uint face, uint dirtyLevelsMask); -- cgit v1.2.3 From 122ed506f4b808503b230bade421018614dbe696 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 19 Mar 2008 18:10:09 -0600 Subject: gallium: added fb_width/height fields to softpipe context These are convenience fields. Otherwise, we have to check cbuf[0] or zsbuf in various places. --- src/gallium/drivers/softpipe/sp_context.h | 2 ++ src/gallium/drivers/softpipe/sp_prim_setup.c | 2 +- src/gallium/drivers/softpipe/sp_quad_stipple.c | 2 +- src/gallium/drivers/softpipe/sp_state_derived.c | 13 ++----------- src/gallium/drivers/softpipe/sp_state_surface.c | 12 ++++++++++++ 5 files changed, 18 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 19e6cfaf02..31d7062dcc 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -84,6 +84,8 @@ struct softpipe_context { unsigned num_samplers; unsigned num_textures; + uint fb_width, fb_height; + /* Counter for occlusion queries. Note this supports overlapping * queries. */ diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 7aa9cf8e85..f2d6043e2e 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -485,7 +485,7 @@ setup_fragcoord_coeff(struct setup_stage *setup, uint slot) /*Y*/ if (setup->softpipe->rasterizer->origin_lower_left) { /* y=0=bottom */ - const int winHeight = setup->softpipe->framebuffer.cbufs[0]->height; + const int winHeight = setup->softpipe->fb_height; setup->coef[slot].a0[1] = (float) (winHeight - 1); setup->coef[slot].dady[1] = -1.0; } diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c index 8660432259..9a39249576 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stipple.c +++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c @@ -25,7 +25,7 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quad) int y0, y1; uint stipple0, stipple1; if (softpipe->rasterizer->origin_lower_left) { - y0 = softpipe->framebuffer.cbufs[0]->height - 1 - quad->y0; + y0 = softpipe->fb_height - 1 - quad->y0; y1 = y0 - 1; } else { diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 82cb31ece7..53b2056b8a 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -171,17 +171,8 @@ softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe) static void compute_cliprect(struct softpipe_context *sp) { - unsigned surfWidth, surfHeight; - - if (sp->framebuffer.num_cbufs > 0) { - surfWidth = sp->framebuffer.cbufs[0]->width; - surfHeight = sp->framebuffer.cbufs[0]->height; - } - else { - /* no surface? */ - surfWidth = sp->scissor.maxx; - surfHeight = sp->scissor.maxy; - } + uint surfWidth = sp->fb_width; + uint surfHeight = sp->fb_height; if (sp->rasterizer->scissor) { /* clip to scissor rect */ diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index 124b18b708..2f55684464 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -48,6 +48,9 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, struct softpipe_context *sp = softpipe_context(pipe); uint i; + /* updated below */ + sp->fb_width = sp->fb_height = 0; + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { /* check if changing cbuf */ if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) { @@ -60,6 +63,10 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, /* update cache */ sp_tile_cache_set_surface(sp->cbuf_cache[i], fb->cbufs[i]); } + if (fb->cbufs[i]) { + sp->fb_width = fb->cbufs[i]->width; + sp->fb_height = fb->cbufs[i]->height; + } } sp->framebuffer.num_cbufs = fb->num_cbufs; @@ -74,6 +81,11 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, /* update cache */ sp_tile_cache_set_surface(sp->zsbuf_cache, fb->zsbuf); + + if (!sp->fb_width && fb->zsbuf) { + sp->fb_width = fb->zsbuf->width; + sp->fb_height = fb->zsbuf->height; + } } #if 0 -- cgit v1.2.3 From a88202d3b02a24a3bfff95c5e375ead44dae4c5e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 20 Mar 2008 13:10:32 +0000 Subject: gallium: add debug facility to dump random blobs as hex --- src/gallium/auxiliary/util/p_debug.c | 18 ++++++++++++++++++ src/gallium/include/pipe/p_debug.h | 8 ++++++++ 2 files changed, 26 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index bd3a0221ea..c51e9e6a69 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -85,6 +85,22 @@ void debug_printf(const char *format, ...) } +void debug_print_blob( const char *name, + const void *blob, + unsigned size ) +{ + const unsigned *ublob = (const unsigned *)blob; + unsigned i; + + debug_printf("%s (%d dwords%s)\n", name, size/4, + size%4 ? "... plus a few bytes" : ""); + + for (i = 0; i < size/4; i++) { + debug_printf("%d:\t%08x\n", i, ublob[i]); + } +} + + /* TODO: implement a debug_abort that calls EngBugCheckEx on WIN32 */ @@ -240,3 +256,5 @@ debug_dump_flags(const struct debug_named_value *names, return output; } + + diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index e924c1ef60..14f8056924 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -73,6 +73,14 @@ extern "C" { */ void debug_printf(const char *format, ...); + +/* Dump a blob in hex to the same place that debug_printf sends its + * messages: + */ +void debug_print_blob( const char *name, + const void *blob, + unsigned size ); + /** * @sa debug_printf */ -- cgit v1.2.3 From 6a9a3afcf923ec5c67069cdb1656f52675cd8ede Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Mar 2008 09:11:27 -0600 Subject: gallium: added util_make_fragment_passthrough_shader() --- src/gallium/auxiliary/util/u_simple_shaders.c | 95 +++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_simple_shaders.h | 12 ++++ 2 files changed, 107 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index 88e2ab05bd..fca6f11119 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -261,3 +261,98 @@ util_make_fragment_tex_shader(struct pipe_context *pipe) return pipe->create_fs_state(pipe, &shader); } + + + + +/** + * Make simple fragment color pass-through shader. + */ +void * +util_make_fragment_passthrough_shader(struct pipe_context *pipe) +{ + uint maxTokens = 40; + struct tgsi_token *tokens; + struct tgsi_header *header; + struct tgsi_processor *processor; + struct tgsi_full_declaration decl; + struct tgsi_full_instruction inst; + const uint procType = TGSI_PROCESSOR_FRAGMENT; + uint ti, i; + struct pipe_shader_state shader; + + tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0])); + + /* shader header + */ + *(struct tgsi_version *) &tokens[0] = tgsi_build_version(); + + header = (struct tgsi_header *) &tokens[1]; + *header = tgsi_build_header(); + + processor = (struct tgsi_processor *) &tokens[2]; + *processor = tgsi_build_processor( procType, header ); + + ti = 3; + + /* declare input */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + /* declare output */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_OUTPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; + decl.Semantic.SemanticIndex = 0; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = 0; + ti += tgsi_build_full_declaration(&decl, + &tokens[ti], + header, + maxTokens - ti); + + + /* MOVE out[0], in[0]; */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_MOV; + inst.Instruction.NumDstRegs = 1; + inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + inst.FullDstRegisters[0].DstRegister.Index = 0; + inst.Instruction.NumSrcRegs = 1; + inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + inst.FullSrcRegisters[0].SrcRegister.Index = 0; + ti += tgsi_build_full_instruction(&inst, + &tokens[ti], + header, + maxTokens - ti ); + + /* END instruction */ + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = TGSI_OPCODE_END; + inst.Instruction.NumDstRegs = 0; + inst.Instruction.NumSrcRegs = 0; + ti += tgsi_build_full_instruction(&inst, + &tokens[ti], + header, + maxTokens - ti ); + + assert(ti < maxTokens); + +#if 0 /*debug*/ + tgsi_dump(tokens, 0); +#endif + + shader.tokens = tokens; + return pipe->create_fs_state(pipe, &shader); +} + diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h index 3ef4f28801..ca219a092c 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.h +++ b/src/gallium/auxiliary/util/u_simple_shaders.h @@ -36,6 +36,11 @@ struct pipe_context; +#ifdef __cplusplus +extern "C" { +#endif + + extern void * util_make_vertex_passthrough_shader(struct pipe_context *pipe, uint num_attribs, @@ -47,6 +52,13 @@ extern void * util_make_fragment_tex_shader(struct pipe_context *pipe); +extern void * +util_make_fragment_passthrough_shader(struct pipe_context *pipe); + + +#ifdef __cplusplus +} #endif +#endif -- cgit v1.2.3 From 8dd90ee19d97c4b032c2b057d96b3e674be3e1fd Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Mar 2008 09:15:24 -0600 Subject: gallium: temporarily disable the memcmp() in cso_set_framebuffer() The memcmp() fails to detect buffer size changes... --- src/gallium/auxiliary/cso_cache/cso_context.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 01fe216447..4a1a6cb79c 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -496,7 +496,8 @@ void cso_restore_vertex_shader(struct cso_context *ctx) void cso_set_framebuffer(struct cso_context *ctx, const struct pipe_framebuffer_state *fb) { - if (memcmp(&ctx->fb, fb, sizeof(*fb))) { + /* XXX this memcmp() fails to detect buffer size changes */ + if (1/*memcmp(&ctx->fb, fb, sizeof(*fb))*/) { ctx->fb = *fb; ctx->pipe->set_framebuffer_state(ctx->pipe, fb); } -- cgit v1.2.3 From 8c71406c74b80fa2d2b1a488938c3b9dfc156343 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Mar 2008 10:44:27 -0600 Subject: gallium: added util_draw_vertex_buffer() --- src/gallium/auxiliary/util/u_draw_quad.c | 59 +++++++++++++++++++++----------- src/gallium/auxiliary/util/u_draw_quad.h | 16 +++++++++ 2 files changed, 55 insertions(+), 20 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c index 79a69de633..37e8533609 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.c +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -33,16 +33,52 @@ #include "util/u_draw_quad.h" +/** + * Draw a simple vertex buffer / primitive. + * Limited to float[4] vertex attribs, tightly packed. + */ +void +util_draw_vertex_buffer(struct pipe_context *pipe, + struct pipe_buffer *vbuf, + uint prim_type, + uint num_verts, + uint num_attribs) +{ + struct pipe_vertex_buffer vbuffer; + struct pipe_vertex_element velement; + uint i; + + /* tell pipe about the vertex buffer */ + vbuffer.buffer = vbuf; + vbuffer.pitch = num_attribs * 4 * sizeof(float); /* vertex size */ + vbuffer.buffer_offset = 0; + pipe->set_vertex_buffer(pipe, 0, &vbuffer); + + /* tell pipe about the vertex attributes */ + for (i = 0; i < num_attribs; i++) { + velement.src_offset = i * 4 * sizeof(float); + velement.vertex_buffer_index = 0; + velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + velement.nr_components = 4; + pipe->set_vertex_element(pipe, i, &velement); + } + + /* draw */ + pipe->draw_arrays(pipe, prim_type, 0, num_verts); +} + + + /** * Draw screen-aligned textured quad. + * Note: this function allocs/destroys a vertex buffer and isn't especially + * efficient. */ void util_draw_texquad(struct pipe_context *pipe, float x0, float y0, float x1, float y1, float z) { struct pipe_buffer *vbuf; - struct pipe_vertex_buffer vbuffer; - struct pipe_vertex_element velement; uint numAttribs = 2, vertexBytes, i, j; float *v; @@ -89,24 +125,7 @@ util_draw_texquad(struct pipe_context *pipe, pipe->winsys->buffer_unmap(pipe->winsys, vbuf); - /* tell pipe about the vertex buffer */ - vbuffer.buffer = vbuf; - vbuffer.pitch = numAttribs * 4 * sizeof(float); /* vertex size */ - vbuffer.buffer_offset = 0; - pipe->set_vertex_buffer(pipe, 0, &vbuffer); - - /* tell pipe about the vertex attributes */ - for (i = 0; i < numAttribs; i++) { - velement.src_offset = i * 4 * sizeof(float); - velement.vertex_buffer_index = 0; - velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - velement.nr_components = 4; - pipe->set_vertex_element(pipe, i, &velement); - } - - /* draw */ - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4); + util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2); - /* XXX: do one-time */ pipe_buffer_reference(pipe->winsys, &vbuf, NULL); } diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h index a97f55d2ef..5b6539a99c 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.h +++ b/src/gallium/auxiliary/util/u_draw_quad.h @@ -29,9 +29,25 @@ #define U_DRAWQUAD_H +#ifdef __cplusplus +extern "C" { +#endif + + +extern void +util_draw_vertex_buffer(struct pipe_context *pipe, + struct pipe_buffer *vbuf, + uint num_attribs, uint num_verts, uint prim_type); + + extern void util_draw_texquad(struct pipe_context *pipe, float x0, float y0, float x1, float y1, float z); +#ifdef __cplusplus +} +#endif + + #endif -- cgit v1.2.3 From 309d6e52c5c1cdeca1434cbe29e869b9176e5fa5 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Mar 2008 10:44:51 -0600 Subject: gallium: create vertex buffer once and re-use. --- src/gallium/auxiliary/util/u_gen_mipmap.c | 71 ++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 028b180a77..5824843069 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -64,6 +64,9 @@ struct gen_mipmap_state /*struct pipe_viewport_state viewport;*/ struct pipe_sampler_state *vs; struct pipe_sampler_state *fs; + + struct pipe_buffer *vbuf; /**< quad vertices */ + float vertices[4][2][4]; /**< vertex/texcoords for quad */ }; @@ -683,6 +686,7 @@ util_create_gen_mipmap(struct pipe_context *pipe, struct cso_context *cso) { struct gen_mipmap_state *ctx; + uint i; ctx = CALLOC_STRUCT(gen_mipmap_state); if (!ctx) @@ -744,10 +748,62 @@ util_create_gen_mipmap(struct pipe_context *pipe, /* fragment shader */ ctx->fs = util_make_fragment_tex_shader(pipe); + ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys, + 32, + PIPE_BUFFER_USAGE_VERTEX, + 4 * 2 * 4 * sizeof(float)); + if (!ctx->vbuf) { + FREE(ctx); + return NULL; + } + + /* vertex data that doesn't change */ + for (i = 0; i < 4; i++) { + ctx->vertices[i][0][2] = 0.0f; /* z */ + ctx->vertices[i][0][3] = 1.0f; /* w */ + ctx->vertices[i][1][2] = 0.0f; /* r */ + ctx->vertices[i][1][3] = 1.0f; /* q */ + } + return ctx; } +static void +set_vertex_data(struct gen_mipmap_state *ctx, float width, float height) +{ + void *buf; + + ctx->vertices[0][0][0] = 0.0f; /*x*/ + ctx->vertices[0][0][1] = 0.0f; /*y*/ + ctx->vertices[0][1][0] = 0.0f; /*s*/ + ctx->vertices[0][1][1] = 0.0f; /*t*/ + + ctx->vertices[1][0][0] = width; /*x*/ + ctx->vertices[1][0][1] = 0.0f; /*y*/ + ctx->vertices[1][1][0] = 1.0f; /*s*/ + ctx->vertices[1][1][1] = 0.0f; /*t*/ + + ctx->vertices[2][0][0] = width; + ctx->vertices[2][0][1] = height; + ctx->vertices[2][1][0] = 1.0f; + ctx->vertices[2][1][1] = 1.0f; + + ctx->vertices[3][0][0] = 0.0f; + ctx->vertices[3][0][1] = height; + ctx->vertices[3][1][0] = 0.0f; + ctx->vertices[3][1][1] = 1.0f; + + buf = ctx->pipe->winsys->buffer_map(ctx->pipe->winsys, ctx->vbuf, + PIPE_BUFFER_USAGE_CPU_WRITE); + + memcpy(buf, ctx->vertices, sizeof(ctx->vertices)); + + ctx->pipe->winsys->buffer_unmap(ctx->pipe->winsys, ctx->vbuf); +} + + + /** * Destroy a mipmap generation context */ @@ -759,6 +815,8 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) pipe->delete_vs_state(pipe, ctx->vs); pipe->delete_fs_state(pipe, ctx->fs); + pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf); + FREE(ctx); } @@ -863,12 +921,13 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, pipe->set_sampler_textures(pipe, 1, &pt); /* quad coords in window coords (bypassing clipping, viewport mapping) */ - util_draw_texquad(pipe, - 0.0F, 0.0F, /* x0, y0 */ - (float) pt->width[dstLevel], /* x1 */ - (float) pt->height[dstLevel], /* y1 */ - 0.0F); /* z */ - + set_vertex_data(ctx, + (float) pt->width[dstLevel], + (float) pt->height[dstLevel]); + util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, + PIPE_PRIM_TRIANGLE_FAN, + 4, /* verts */ + 2); /* attribs/vert */ pipe->flush(pipe, PIPE_FLUSH_WAIT); -- cgit v1.2.3 From f259ea0347754e0e8c93fd16796fc1db72b03372 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 20 Mar 2008 19:25:44 +0000 Subject: gallium: remove unused local var --- src/gallium/auxiliary/util/u_simple_shaders.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index fca6f11119..442467ecad 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -278,7 +278,7 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe) struct tgsi_full_declaration decl; struct tgsi_full_instruction inst; const uint procType = TGSI_PROCESSOR_FRAGMENT; - uint ti, i; + uint ti; struct pipe_shader_state shader; tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0])); -- cgit v1.2.3 From 482f4995253a0c295dc02e34e58a138ac8822c54 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 20 Mar 2008 20:25:40 +0100 Subject: gallium: Fix build on Windows. --- src/gallium/auxiliary/util/u_simple_shaders.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index 442467ecad..a2c918b7fe 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -68,7 +68,7 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, uint ti, i; struct pipe_shader_state shader; - tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0])); + tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0])); /* shader header */ @@ -173,7 +173,7 @@ util_make_fragment_tex_shader(struct pipe_context *pipe) uint ti; struct pipe_shader_state shader; - tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0])); + tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0])); /* shader header */ -- cgit v1.2.3 From 400b12b4ceda32cc35b60d0484dfd333f1749b8e Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 20 Mar 2008 20:34:03 +0100 Subject: gallium: Fix build on Windows. --- src/gallium/auxiliary/util/u_simple_shaders.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index a2c918b7fe..8cb74e81d2 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -281,7 +281,7 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe) uint ti; struct pipe_shader_state shader; - tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0])); + tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0])); /* shader header */ -- cgit v1.2.3 From 9fa88fb3c57f6868dc169b692528cf23ceced76c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 20 Mar 2008 20:34:46 +0000 Subject: gallium: Give some chance for the table to actually grow. --- src/gallium/auxiliary/util/u_handle_table.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c index 8b0f7fca4b..5a731a6b96 100644 --- a/src/gallium/auxiliary/util/u_handle_table.c +++ b/src/gallium/auxiliary/util/u_handle_table.c @@ -171,8 +171,7 @@ handle_table_set(struct handle_table *ht, assert(ht); assert(handle > 0); - assert(handle <= ht->size); - if(!handle || handle > ht->size) + if(!handle) return 0; assert(object); -- cgit v1.2.3 From 18be9a588acb46dad52321c91eab9927bc332756 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Mar 2008 14:26:51 -0600 Subject: gallium: use sizeof(vertex buffer) --- src/gallium/auxiliary/util/u_gen_mipmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 5824843069..b84752e0b4 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -751,7 +751,7 @@ util_create_gen_mipmap(struct pipe_context *pipe, ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys, 32, PIPE_BUFFER_USAGE_VERTEX, - 4 * 2 * 4 * sizeof(float)); + sizeof(ctx->vertices)); if (!ctx->vbuf) { FREE(ctx); return NULL; -- cgit v1.2.3 From b028d32af4f5e7beeb4e659a4726e0d35d105ccc Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Mar 2008 14:27:14 -0600 Subject: gallium: create one vertex buffer and re-use --- src/gallium/auxiliary/util/u_blit.c | 80 ++++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index d05dae3af8..bb316554a4 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -61,6 +61,9 @@ struct blit_state /*struct pipe_viewport_state viewport;*/ struct pipe_sampler_state *vs; struct pipe_sampler_state *fs; + + struct pipe_buffer *vbuf; /**< quad vertices */ + float vertices[4][2][4]; /**< vertex/texcoords for quad */ }; @@ -72,6 +75,7 @@ struct blit_state * util_create_blit(struct pipe_context *pipe, struct cso_context *cso) { struct blit_state *ctx; + uint i; ctx = CALLOC_STRUCT(blit_state); if (!ctx) @@ -132,6 +136,24 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) /* fragment shader */ ctx->fs = util_make_fragment_tex_shader(pipe); + ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys, + 32, + PIPE_BUFFER_USAGE_VERTEX, + sizeof(ctx->vertices)); + if (!ctx->vbuf) { + FREE(ctx); + ctx->pipe->delete_fs_state(ctx->pipe, ctx->fs); + ctx->pipe->delete_vs_state(ctx->pipe, ctx->vs); + return NULL; + } + + /* init vertex data that doesn't change */ + for (i = 0; i < 4; i++) { + ctx->vertices[i][0][3] = 1.0f; /* w */ + ctx->vertices[i][1][2] = 0.0f; /* r */ + ctx->vertices[i][1][3] = 1.0f; /* q */ + } + return ctx; } @@ -147,10 +169,55 @@ util_destroy_blit(struct blit_state *ctx) pipe->delete_vs_state(pipe, ctx->vs); pipe->delete_fs_state(pipe, ctx->fs); + pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf); + FREE(ctx); } +/** + * Setup vertex data for the textured quad we'll draw. + * Note: y=0=top + */ +static void +setup_vertex_data(struct blit_state *ctx, + float x0, float y0, float x1, float y1, float z) +{ + void *buf; + + ctx->vertices[0][0][0] = x0; + ctx->vertices[0][0][1] = y0; + ctx->vertices[0][0][2] = z; + ctx->vertices[0][1][0] = 0.0f; /*s*/ + ctx->vertices[0][1][1] = 0.0f; /*t*/ + + ctx->vertices[1][0][0] = x1; + ctx->vertices[1][0][1] = y0; + ctx->vertices[1][0][2] = z; + ctx->vertices[1][1][0] = 1.0f; /*s*/ + ctx->vertices[1][1][1] = 0.0f; /*t*/ + + ctx->vertices[2][0][0] = x1; + ctx->vertices[2][0][1] = y1; + ctx->vertices[2][0][2] = z; + ctx->vertices[2][1][0] = 1.0f; + ctx->vertices[2][1][1] = 1.0f; + + ctx->vertices[3][0][0] = x0; + ctx->vertices[3][0][1] = y1; + ctx->vertices[3][0][2] = z; + ctx->vertices[3][1][0] = 0.0f; + ctx->vertices[3][1][1] = 1.0f; + + buf = ctx->pipe->winsys->buffer_map(ctx->pipe->winsys, ctx->vbuf, + PIPE_BUFFER_USAGE_CPU_WRITE); + + memcpy(buf, ctx->vertices, sizeof(ctx->vertices)); + + ctx->pipe->winsys->buffer_unmap(ctx->pipe->winsys, ctx->vbuf); +} + + /** * Copy pixel block from src surface to dst surface. * Overlapping regions are acceptable. @@ -254,11 +321,14 @@ util_blit_pixels(struct blit_state *ctx, cso_set_framebuffer(ctx->cso, &fb); /* draw quad */ - util_draw_texquad(pipe, - (float)dstX0, - (float)dstY0, - (float)dstX1, - (float)dstY1, z); + setup_vertex_data(ctx, + (float) dstX0, (float) dstY0, + (float) dstX1, (float) dstY1, z); + + util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, + PIPE_PRIM_TRIANGLE_FAN, + 4, /* verts */ + 2); /* attribs/vert */ /* restore state we changed */ cso_restore_blend(ctx->cso); -- cgit v1.2.3 From 80567f9c9f84d9df1cdb2d91a3c0814888cc5d08 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Mar 2008 15:01:44 -0600 Subject: gallium: added width, height to pipe_framebuffer_state --- src/gallium/include/pipe/p_state.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 5791a10119..3e531c4da4 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -220,6 +220,8 @@ struct pipe_blend_color struct pipe_framebuffer_state { + unsigned width, height; + /** multiple colorbuffers for multiple render targets */ unsigned num_cbufs; struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS]; -- cgit v1.2.3 From 2fb30b77ad09016efcf969456de9b0341bc53bac Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Mar 2008 15:02:59 -0600 Subject: cell: use pipe_framebuffer_state.width, height --- src/gallium/drivers/cell/ppu/cell_state_derived.c | 13 ++----------- src/gallium/drivers/cell/ppu/cell_state_emit.c | 4 ++-- 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_derived.c b/src/gallium/drivers/cell/ppu/cell_state_derived.c index 5c240a55c0..5480534ad9 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_derived.c +++ b/src/gallium/drivers/cell/ppu/cell_state_derived.c @@ -141,17 +141,8 @@ calculate_vertex_layout( struct cell_context *cell ) static void compute_cliprect(struct cell_context *sp) { - unsigned surfWidth, surfHeight; - - if (sp->framebuffer.num_cbufs > 0) { - surfWidth = sp->framebuffer.cbufs[0]->width; - surfHeight = sp->framebuffer.cbufs[0]->height; - } - else { - /* no surface? */ - surfWidth = sp->scissor.maxx; - surfHeight = sp->scissor.maxy; - } + uint surfWidth = sp->framebuffer.width; + uint surfHeight = sp->framebuffer.height; if (sp->rasterizer->scissor) { /* clip to scissor rect */ diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 4d589bcdbf..31cc938f07 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -60,8 +60,8 @@ cell_emit_state(struct cell_context *cell) fb->color_format = cbuf->format; fb->depth_start = cell->zsbuf_map; fb->depth_format = zbuf ? zbuf->format : PIPE_FORMAT_NONE; - fb->width = cell->framebuffer.cbufs[0]->width; - fb->height = cell->framebuffer.cbufs[0]->height; + fb->width = cell->framebuffer.width; + fb->height = cell->framebuffer.height; } if (cell->dirty & CELL_NEW_BLEND) { -- cgit v1.2.3 From 09f67990abd4bb9b79349be2fca9a6ae850b6f5f Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Mar 2008 15:03:43 -0600 Subject: gallium: use new framebuffer width, height fields --- src/gallium/drivers/softpipe/sp_context.h | 2 -- src/gallium/drivers/softpipe/sp_prim_setup.c | 2 +- src/gallium/drivers/softpipe/sp_quad_stipple.c | 2 +- src/gallium/drivers/softpipe/sp_state_derived.c | 4 ++-- src/gallium/drivers/softpipe/sp_state_surface.c | 19 +++---------------- 5 files changed, 7 insertions(+), 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 31d7062dcc..19e6cfaf02 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -84,8 +84,6 @@ struct softpipe_context { unsigned num_samplers; unsigned num_textures; - uint fb_width, fb_height; - /* Counter for occlusion queries. Note this supports overlapping * queries. */ diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index f2d6043e2e..6a81e4d8cc 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -485,7 +485,7 @@ setup_fragcoord_coeff(struct setup_stage *setup, uint slot) /*Y*/ if (setup->softpipe->rasterizer->origin_lower_left) { /* y=0=bottom */ - const int winHeight = setup->softpipe->fb_height; + const int winHeight = setup->softpipe->framebuffer.height; setup->coef[slot].a0[1] = (float) (winHeight - 1); setup->coef[slot].dady[1] = -1.0; } diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c index 9a39249576..f1e9b80e09 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stipple.c +++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c @@ -25,7 +25,7 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quad) int y0, y1; uint stipple0, stipple1; if (softpipe->rasterizer->origin_lower_left) { - y0 = softpipe->fb_height - 1 - quad->y0; + y0 = softpipe->framebuffer.height - 1 - quad->y0; y1 = y0 - 1; } else { diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 53b2056b8a..14abb20eeb 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -171,8 +171,8 @@ softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe) static void compute_cliprect(struct softpipe_context *sp) { - uint surfWidth = sp->fb_width; - uint surfHeight = sp->fb_height; + uint surfWidth = sp->framebuffer.width; + uint surfHeight = sp->framebuffer.height; if (sp->rasterizer->scissor) { /* clip to scissor rect */ diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index 2f55684464..ba8c9eece7 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -48,9 +48,6 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, struct softpipe_context *sp = softpipe_context(pipe); uint i; - /* updated below */ - sp->fb_width = sp->fb_height = 0; - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { /* check if changing cbuf */ if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) { @@ -63,10 +60,6 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, /* update cache */ sp_tile_cache_set_surface(sp->cbuf_cache[i], fb->cbufs[i]); } - if (fb->cbufs[i]) { - sp->fb_width = fb->cbufs[i]->width; - sp->fb_height = fb->cbufs[i]->height; - } } sp->framebuffer.num_cbufs = fb->num_cbufs; @@ -81,11 +74,6 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, /* update cache */ sp_tile_cache_set_surface(sp->zsbuf_cache, fb->zsbuf); - - if (!sp->fb_width && fb->zsbuf) { - sp->fb_width = fb->zsbuf->width; - sp->fb_height = fb->zsbuf->height; - } } #if 0 @@ -113,9 +101,8 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, } #endif + sp->framebuffer.width = fb->width; + sp->framebuffer.height = fb->height; + sp->dirty |= SP_NEW_FRAMEBUFFER; } - - - - -- cgit v1.2.3 From 00cf178d93e5bc36a88a9f8ff444f60c493be14d Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Mar 2008 15:21:55 -0600 Subject: gallium: enable vp input semantic info --- src/gallium/auxiliary/util/u_simple_shaders.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index 8cb74e81d2..d230ddfbeb 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -84,16 +84,15 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, /* declare inputs */ for (i = 0; i < num_attribs; i++) { - decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; - /* + decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; - decl.Semantic.SemanticIndex = 0; - */ + decl.Semantic.SemanticName = semantic_names[i]; + decl.Semantic.SemanticIndex = semantic_indexes[i]; + decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; + decl.u.DeclarationRange.Last = i; ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, @@ -102,19 +101,17 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, /* declare outputs */ for (i = 0; i < num_attribs; i++) { - decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_OUTPUT; decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = semantic_names[i]; decl.Semantic.SemanticIndex = semantic_indexes[i]; decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; + decl.u.DeclarationRange.Last = i; ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, maxTokens - ti); - } /* emit MOV instructions */ -- cgit v1.2.3 From 0565e6888a332956661f6bc8b5778b058168e5f9 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Mar 2008 15:22:20 -0600 Subject: gallium: set fb.width/height --- src/gallium/auxiliary/util/u_blit.c | 2 ++ src/gallium/auxiliary/util/u_gen_mipmap.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index bb316554a4..28a404fd01 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -316,6 +316,8 @@ util_blit_pixels(struct blit_state *ctx, /* drawing dest */ memset(&fb, 0, sizeof(fb)); + fb.width = dst->width; + fb.height = dst->height; fb.num_cbufs = 1; fb.cbufs[0] = dst; cso_set_framebuffer(ctx->cso, &fb); diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index b84752e0b4..cf02f00b1b 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -901,6 +901,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, * Setup framebuffer / dest surface */ fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + fb.width = pt->width[dstLevel]; + fb.height = pt->height[dstLevel]; cso_set_framebuffer(ctx->cso, &fb); /* -- cgit v1.2.3 From 2b21bde3b1fa6fe357a3a5adc6249e89d6915524 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 19 Mar 2008 17:29:39 -0700 Subject: cell: Use code-gen for alpha blend So far this is only tested when GL_BLEND is disabled. --- src/gallium/drivers/cell/common.h | 10 +++++ src/gallium/drivers/cell/ppu/cell_pipe_state.c | 11 +++-- src/gallium/drivers/cell/ppu/cell_state_emit.c | 17 +++++-- src/gallium/drivers/cell/spu/Makefile | 1 - src/gallium/drivers/cell/spu/spu_blend.c | 62 -------------------------- src/gallium/drivers/cell/spu/spu_blend.h | 37 --------------- src/gallium/drivers/cell/spu/spu_main.c | 50 ++++++++++++++++++--- src/gallium/drivers/cell/spu/spu_main.h | 17 ++++++- src/gallium/drivers/cell/spu/spu_tri.c | 56 +++++++++++++++-------- 9 files changed, 129 insertions(+), 132 deletions(-) delete mode 100644 src/gallium/drivers/cell/spu/spu_blend.c delete mode 100644 src/gallium/drivers/cell/spu/spu_blend.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index fe93fd8e1a..d59e4f7036 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -114,6 +114,16 @@ struct cell_command_depth_stencil_alpha_test { }; +/** + * Upload code to perform framebuffer blend operation + */ +struct cell_command_blend { + uint64_t base; /**< Effective address of code start. */ + unsigned size; /**< Size in bytes of test code. */ + unsigned read_fb; /**< Flag: should framebuffer be read? */ +}; + + /** * Tell SPUs about the framebuffer size, location */ diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index c880760e4b..4ca8c153b0 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -54,14 +54,19 @@ cell_create_blend_state(struct pipe_context *pipe, static void -cell_bind_blend_state(struct pipe_context *pipe, void *blend) +cell_bind_blend_state(struct pipe_context *pipe, void *state) { struct cell_context *cell = cell_context(pipe); + struct cell_blend_state *blend = (struct cell_blend_state *) state; + draw_flush(cell->draw); - cell->blend = (const struct cell_blend_state *)blend; + if ((blend != NULL) && (blend->code.store == NULL)) { + cell_generate_depth_stencil_test(blend); + } + cell->blend = blend; cell->dirty |= CELL_NEW_BLEND; } @@ -70,7 +75,7 @@ static void cell_delete_blend_state(struct pipe_context *pipe, void *blend) { struct cell_blend_state *cb = (struct cell_blend_state *) blend; - + spe_release_func(& cb->code); FREE(cb); } diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 31cc938f07..5709b48f12 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -65,9 +65,20 @@ cell_emit_state(struct cell_context *cell) } if (cell->dirty & CELL_NEW_BLEND) { - emit_state_cmd(cell, CELL_CMD_STATE_BLEND, - cell->blend, - sizeof(struct pipe_blend_state)); + struct cell_command_blend blend; + + if (cell->blend != NULL) { + blend.base = (intptr_t) cell->blend->code.store; + blend.size = (char *) cell->blend->code.csr + - (char *) cell->blend->code.store; + blend.read_fb = TRUE; + } else { + blend.base = 0; + blend.size = 0; + blend.read_fb = FALSE; + } + + emit_state_cmd(cell, CELL_CMD_STATE_BLEND, &blend, sizeof(blend)); } if (cell->dirty & CELL_NEW_DEPTH_STENCIL) { diff --git a/src/gallium/drivers/cell/spu/Makefile b/src/gallium/drivers/cell/spu/Makefile index 115ca8cd90..8e83610790 100644 --- a/src/gallium/drivers/cell/spu/Makefile +++ b/src/gallium/drivers/cell/spu/Makefile @@ -17,7 +17,6 @@ PROG_SPU_EMBED_O = $(PROG)_spu-embed.o SOURCES = \ spu_main.c \ - spu_blend.c \ spu_dcache.c \ spu_per_fragment_op.c \ spu_render.c \ diff --git a/src/gallium/drivers/cell/spu/spu_blend.c b/src/gallium/drivers/cell/spu/spu_blend.c deleted file mode 100644 index 23ec0eeb45..0000000000 --- a/src/gallium/drivers/cell/spu/spu_blend.c +++ /dev/null @@ -1,62 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "spu_main.h" -#include "spu_blend.h" -#include "spu_colorpack.h" - - -void -blend_quad(uint itx, uint ity, vector float colors[4]) -{ - /* simple SRC_ALPHA, ONE_MINUS_SRC_ALPHA blending */ - vector float fbc00 = spu_unpack_color(spu.ctile.ui[ity][itx]); - vector float fbc01 = spu_unpack_color(spu.ctile.ui[ity][itx+1]); - vector float fbc10 = spu_unpack_color(spu.ctile.ui[ity+1][itx]); - vector float fbc11 = spu_unpack_color(spu.ctile.ui[ity+1][itx+1]); - - vector float alpha00 = spu_splats(spu_extract(colors[0], 3)); - vector float alpha01 = spu_splats(spu_extract(colors[1], 3)); - vector float alpha10 = spu_splats(spu_extract(colors[2], 3)); - vector float alpha11 = spu_splats(spu_extract(colors[3], 3)); - - vector float one_minus_alpha00 = spu_sub(spu_splats(1.0f), alpha00); - vector float one_minus_alpha01 = spu_sub(spu_splats(1.0f), alpha01); - vector float one_minus_alpha10 = spu_sub(spu_splats(1.0f), alpha10); - vector float one_minus_alpha11 = spu_sub(spu_splats(1.0f), alpha11); - - colors[0] = spu_add(spu_mul(colors[0], alpha00), - spu_mul(fbc00, one_minus_alpha00)); - colors[1] = spu_add(spu_mul(colors[1], alpha01), - spu_mul(fbc01, one_minus_alpha01)); - colors[2] = spu_add(spu_mul(colors[2], alpha10), - spu_mul(fbc10, one_minus_alpha10)); - colors[3] = spu_add(spu_mul(colors[3], alpha11), - spu_mul(fbc11, one_minus_alpha11)); -} - diff --git a/src/gallium/drivers/cell/spu/spu_blend.h b/src/gallium/drivers/cell/spu/spu_blend.h deleted file mode 100644 index 2b594b578b..0000000000 --- a/src/gallium/drivers/cell/spu/spu_blend.h +++ /dev/null @@ -1,37 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef SPU_BLEND_H -#define SPU_BLEND_H - - -extern void -blend_quad(uint itx, uint ity, vector float colors[4]); - - -#endif /* SPU_BLEND_H */ diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 937962285d..41bebf5362 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -61,6 +61,25 @@ static unsigned char attribute_fetch_code_buffer[136 * PIPE_ATTRIB_MAX] static unsigned char depth_stencil_code_buffer[4 * 64] ALIGN16_ATTRIB; +static unsigned char fb_blend_code_buffer[4 * 64] + ALIGN16_ATTRIB; + +static struct spu_blend_results +default_blend(qword frag_r, qword frag_g, qword frag_b, qword frag_a, + qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a, + qword frag_mask) +{ + struct spu_blend_results result; + + result.r = si_selb(pixel_r, frag_r, frag_mask); + result.g = si_selb(pixel_g, frag_g, frag_mask); + result.b = si_selb(pixel_b, frag_b, frag_mask); + result.a = si_selb(pixel_a, frag_a, frag_mask); + + return result; +} + + /** * Tell the PPU that this SPU has finished copying a buffer to * local store and that it may be reused by the PPU. @@ -246,14 +265,31 @@ cmd_state_framebuffer(const struct cell_command_framebuffer *cmd) static void -cmd_state_blend(const struct pipe_blend_state *state) +cmd_state_blend(const struct cell_command_blend *state) { if (Debug) printf("SPU %u: BLEND: enabled %d\n", spu.init.id, - state->blend_enable); + (state->size != 0)); + + ASSERT_ALIGN16(state->base); - memcpy(&spu.blend, state, sizeof(*state)); + if (state->size != 0) { + mfc_get(fb_blend_code_buffer, + (unsigned int) state->base, /* src */ + ROUNDUP16(state->size), + TAG_BATCH_BUFFER, + 0, /* tid */ + 0 /* rid */); + wait_on_mask(1 << TAG_BATCH_BUFFER); + spu.blend = (blend_func) fb_blend_code_buffer; + spu.read_fb = state->read_fb; + } else { + /* If there is no code, use the default; + */ + spu.blend = default_blend; + spu.read_fb = FALSE; + } } @@ -441,9 +477,8 @@ cmd_batch(uint opcode) pos += 1; break; case CELL_CMD_STATE_BLEND: - cmd_state_blend((struct pipe_blend_state *) - &buffer[pos+1]); - pos += (1 + ROUNDUP8(sizeof(struct pipe_blend_state)) / 8); + cmd_state_blend((struct cell_command_blend *) &buffer[pos+1]); + pos += (1 + ROUNDUP8(sizeof(struct cell_command_blend)) / 8); break; case CELL_CMD_STATE_DEPTH_STENCIL: cmd_state_depth_stencil((struct cell_command_depth_stencil_alpha_test *) @@ -587,6 +622,9 @@ one_time_init(void) memset(spu.ctile_status, TILE_STATUS_DEFINED, sizeof(spu.ctile_status)); memset(spu.ztile_status, TILE_STATUS_DEFINED, sizeof(spu.ztile_status)); invalidate_tex_cache(); + + spu.blend = default_blend; + spu.read_fb = FALSE; } diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index 444e218645..56d0968676 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -67,6 +67,18 @@ typedef struct spu_frag_test_results (*frag_test_func)(qword frag_mask, qword frag_alpha, qword facing); +struct spu_blend_results { + qword r; + qword g; + qword b; + qword a; +}; + +typedef struct spu_blend_results (*blend_func)( + qword frag_r, qword frag_g, qword frag_b, qword frag_a, + qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a, + qword frag_mask); + struct spu_framebuffer { void *color_start; /**< addr of color surface in main memory */ void *depth_start; /**< addr of depth surface in main memory */ @@ -93,7 +105,10 @@ struct spu_global boolean read_depth; boolean read_stencil; frag_test_func frag_test; - struct pipe_blend_state blend; + + boolean read_fb; + blend_func blend; + struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; struct cell_command_texture texture; diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index 81823f2463..c9f8cadcda 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -29,10 +29,10 @@ * Triangle rendering within a tile. */ +#include #include "pipe/p_compiler.h" #include "pipe/p_format.h" #include "pipe/p_util.h" -#include "spu_blend.h" #include "spu_colorpack.h" #include "spu_main.h" #include "spu_texture.h" @@ -326,27 +326,45 @@ emit_quad( int x, int y, mask_t mask ) eval_coeff(1, (float) x, (float) y, colors); } -#if 1 - if (spu.blend.blend_enable) - blend_quad(ix % TILE_SIZE, iy % TILE_SIZE, colors); -#endif - if (spu_extract(mask, 0)) - spu.ctile.ui[iy][ix] = spu_pack_color_shuffle(colors[0], shuffle); - if (spu_extract(mask, 1)) - spu.ctile.ui[iy][ix+1] = spu_pack_color_shuffle(colors[1], shuffle); - if (spu_extract(mask, 2)) - spu.ctile.ui[iy+1][ix] = spu_pack_color_shuffle(colors[2], shuffle); - if (spu_extract(mask, 3)) - spu.ctile.ui[iy+1][ix+1] = spu_pack_color_shuffle(colors[3], shuffle); + /* Read the current framebuffer values. + * + * Ignore read_fb for now. In the future we can use this to avoid + * reading the framebuffer if read_fb is false and the fragment mask is + * all 0xffffffff. This is the common case, so it is probably worth + * the effort. We'll have to profile to determine whether or not the + * extra conditional branches hurt overall performance. + */ + vec_float4 aos_pix[4] = { + spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+0]), + spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+1]), + spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+0]), + spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+1]), + }; -#if 0 - /* SIMD_Z with swizzled color buffer (someday) */ - vector unsigned int uicolors = *((vector unsigned int *) &colors); - spu.ctile.ui4[iy/2][ix/2] = spu_sel(spu.ctile.ui4[iy/2][ix/2], uicolors, mask); -#endif - } + qword soa_pix[4]; + qword soa_frag[4]; + /* Convert pixel and fragment data from AoS to SoA format. + */ + _transpose_matrix4x4((vec_float4 *) soa_pix, aos_pix); + _transpose_matrix4x4((vec_float4 *) soa_frag, colors); + + const struct spu_blend_results result = + (*spu.blend)(soa_frag[0], soa_frag[1], soa_frag[2], soa_frag[3], + soa_pix[0], soa_pix[1], soa_pix[2], soa_pix[3], + (qword) mask); + + + /* Convert final pixel data from SoA to AoS format. + */ + _transpose_matrix4x4(aos_pix, (const vec_float4 *) &result); + + spu.ctile.ui[iy+0][ix+0] = spu_pack_color_shuffle(aos_pix[0], shuffle); + spu.ctile.ui[iy+0][ix+1] = spu_pack_color_shuffle(aos_pix[1], shuffle); + spu.ctile.ui[iy+1][ix+0] = spu_pack_color_shuffle(aos_pix[2], shuffle); + spu.ctile.ui[iy+1][ix+1] = spu_pack_color_shuffle(aos_pix[3], shuffle); + } #endif } -- cgit v1.2.3 From df1d6e2410dbc6af66ca416124587918b9764ee8 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 20 Mar 2008 17:36:05 -0700 Subject: cell: Fix bus error when there is no depth buffer --- src/gallium/drivers/cell/spu/spu_tri.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index c9f8cadcda..c4272d6e93 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -261,6 +261,9 @@ do_depth_test(int x, int y, mask_t quadmask) float4 zvals; mask_t mask; + if (spu.fb.depth_format == PIPE_FORMAT_NONE) + return quadmask; + zvals.v = eval_z((float) x, (float) y); mask = (mask_t) spu_do_depth_stencil(x - setup.cliprect_minx, -- cgit v1.2.3 From 4b9520fc05f169b74835c096c933d67c67c6d8cd Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 20 Mar 2008 17:36:31 -0700 Subject: cell: Call the correct function to generate blending code Cut-and-paste for the lose. :( --- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 4ca8c153b0..86fcdcff1f 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -63,7 +63,7 @@ cell_bind_blend_state(struct pipe_context *pipe, void *state) draw_flush(cell->draw); if ((blend != NULL) && (blend->code.store == NULL)) { - cell_generate_depth_stencil_test(blend); + cell_generate_alpha_blend(blend, &cell->blend_color); } cell->blend = blend; -- cgit v1.2.3 From cab68957c72d6f198546a250b6fe0a74732cb3ec Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 20 Mar 2008 18:17:48 -0700 Subject: cell: Fix several bugs in blend code-gen - Alpha factor set to a _COLOR mode was mishandled - Cases when either dst factor or src factor was ZERO were mishandled - MIN and MAX cases were backwards - Case when blend was disabled was mishandled - Incorrect comments about number of instructions generated The tests blendminmax and blendsquare run correctly. --- .../drivers/cell/ppu/cell_state_per_fragment.c | 112 +++++++++++++++++---- 1 file changed, 92 insertions(+), 20 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index 9c47968459..988c251e20 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -669,7 +669,7 @@ emit_alpha_factor_calculation(struct spe_function *f, /** - * \note Emits a maximum of 5 instructions + * \note Emits a maximum of 6 instructions */ static void emit_color_factor_calculation(struct spe_function *f, @@ -864,7 +864,11 @@ emit_blend_calculation(struct spe_function *f, spe_il(f, src, 0); } else if (dF == PIPE_BLENDFACTOR_ONE) { spe_or(f, src, dst, dst); + } else { + spe_fm(f, src, dst, dst_factor); } + } else if (dF == PIPE_BLENDFACTOR_ZERO) { + spe_fm(f, src, src, src_factor); } else { spe_fm(f, tmp, dst, dst_factor); spe_fma(f, src, src, src_factor, tmp); @@ -884,7 +888,11 @@ emit_blend_calculation(struct spe_function *f, } else if (dF == PIPE_BLENDFACTOR_ONE) { spe_il(f, tmp, 0); spe_fs(f, src, tmp, dst); + } else { + spe_fm(f, src, dst, dst_factor); } + } else if (dF == PIPE_BLENDFACTOR_ZERO) { + spe_fm(f, src, src, src_factor); } else { spe_fm(f, tmp, dst, dst_factor); spe_fms(f, src, src, src_factor, tmp); @@ -904,7 +912,11 @@ emit_blend_calculation(struct spe_function *f, spe_il(f, src, 0); } else if (dF == PIPE_BLENDFACTOR_ONE) { spe_or(f, src, dst, dst); + } else { + spe_fm(f, src, dst, dst_factor); } + } else if (dF == PIPE_BLENDFACTOR_ZERO) { + spe_fm(f, src, src, src_factor); } else { spe_fm(f, tmp, src, src_factor); spe_fms(f, src, src, dst_factor, tmp); @@ -913,12 +925,12 @@ emit_blend_calculation(struct spe_function *f, case PIPE_BLEND_MIN: spe_cgt(f, tmp, src, dst); - spe_selb(f, src, dst, src, tmp); + spe_selb(f, src, src, dst, tmp); break; case PIPE_BLEND_MAX: spe_cgt(f, tmp, src, dst); - spe_selb(f, src, src, dst, tmp); + spe_selb(f, src, dst, src, tmp); break; default: @@ -940,9 +952,9 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, struct spe_function *const f = &cb->code; /* This code generates a maximum of 3 (source alpha factor) - * + 3 (destination alpha factor) + (3 * 5) (source color factor) - * + (3 * 5) (destination color factor) + (4 * 2) (blend equation) - * + 4 (fragment mask) + 1 (return) = 49 instlructions. Round up to 64 to + * + 3 (destination alpha factor) + (3 * 6) (source color factor) + * + (3 * 6) (destination color factor) + (4 * 2) (blend equation) + * + 4 (fragment mask) + 1 (return) = 55 instlructions. Round up to 64 to * make it a happy power-of-two. */ spe_init_func(f, 4 * 64); @@ -984,16 +996,57 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, && (b->alpha_func != PIPE_BLEND_MAX); - sF[0] = b->rgb_src_factor; - sF[1] = sF[0]; - sF[2] = sF[0]; - sF[3] = (b->alpha_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE) - ? PIPE_BLENDFACTOR_ONE : b->alpha_src_factor; + if (b->blend_enable) { + sF[0] = b->rgb_src_factor; + sF[1] = sF[0]; + sF[2] = sF[0]; + switch (b->alpha_src_factor & 0x0f) { + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + sF[3] = PIPE_BLENDFACTOR_ONE; + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + case PIPE_BLENDFACTOR_DST_COLOR: + case PIPE_BLENDFACTOR_CONST_COLOR: + case PIPE_BLENDFACTOR_SRC1_COLOR: + sF[3] = b->alpha_src_factor + 1; + break; + default: + sF[3] = b->alpha_src_factor; + } - dF[0] = b->rgb_dst_factor; - dF[1] = dF[0]; - dF[2] = dF[0]; - dF[3] = b->rgb_dst_factor; + dF[0] = b->rgb_dst_factor; + dF[1] = dF[0]; + dF[2] = dF[0]; + switch (b->alpha_dst_factor & 0x0f) { + case PIPE_BLENDFACTOR_SRC_COLOR: + case PIPE_BLENDFACTOR_DST_COLOR: + case PIPE_BLENDFACTOR_CONST_COLOR: + case PIPE_BLENDFACTOR_SRC1_COLOR: + dF[3] = b->alpha_dst_factor + 1; + break; + default: + dF[3] = b->alpha_dst_factor; + } + + func[0] = b->rgb_func; + func[1] = func[0]; + func[2] = func[0]; + func[3] = b->alpha_func; + } else { + sF[0] = PIPE_BLENDFACTOR_ONE; + sF[1] = PIPE_BLENDFACTOR_ONE; + sF[2] = PIPE_BLENDFACTOR_ONE; + sF[3] = PIPE_BLENDFACTOR_ONE; + dF[0] = PIPE_BLENDFACTOR_ZERO; + dF[1] = PIPE_BLENDFACTOR_ZERO; + dF[2] = PIPE_BLENDFACTOR_ZERO; + dF[3] = PIPE_BLENDFACTOR_ZERO; + + func[0] = PIPE_BLEND_ADD; + func[1] = PIPE_BLEND_ADD; + func[2] = PIPE_BLEND_ADD; + func[3] = PIPE_BLEND_ADD; + } /* If alpha writing is enabled and the alpha blend mode requires use of @@ -1054,11 +1107,6 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, - func[0] = b->rgb_func; - func[1] = func[0]; - func[2] = func[0]; - func[3] = b->alpha_func; - for (i = 0; i < 4; ++i) { if ((b->colormask & (1U << i)) != 0) { emit_blend_calculation(f, @@ -1072,4 +1120,28 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, } spe_bi(f, 0, 0, 0); + +#if 0 + { + const uint32_t *p = f->store; + + printf("# %u instructions\n", f->csr - f->store); + printf("# blend (%sabled)\n", + (cb->base.blend_enable) ? "en" : "dis"); + printf("# RGB func / sf / df: %u %u %u\n", + cb->base.rgb_func, + cb->base.rgb_src_factor, + cb->base.rgb_dst_factor); + printf("# ALP func / sf / df: %u %u %u\n", + cb->base.alpha_func, + cb->base.alpha_src_factor, + cb->base.alpha_dst_factor); + + printf("\t.text\n"); + for (/* empty */; p < f->csr; p++) { + printf("\t.long\t0x%04x\n", *p); + } + fflush(stdout); + } +#endif } -- cgit v1.2.3 From 403c7ba91a72f4740ab64823172c8760d837770d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Mar 2008 10:38:56 -0600 Subject: gallium: additional comments, fix typos, etc --- src/gallium/include/pipe/p_format.h | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index f90087b3c9..d09b6dbefc 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -38,13 +38,14 @@ extern "C" { #endif /** - * The PIPE_FORMAT is a 32-bit wide bitfield that encodes all the information - * needed to uniquely describe a pixel format. + * The pipe_format enum is a 32-bit wide bitfield that encodes all the + * information needed to uniquely describe a pixel format. */ /** - * Possible format layouts -- occupy first 2 bits. The interpretation of - * the remaining 30 bits depends on a particual format layout. + * Possible format layouts are encoded in the first 2 bits. + * The interpretation of the remaining 30 bits depends on a particular + * format layout. */ #define PIPE_FORMAT_LAYOUT_RGBAZS 0 #define PIPE_FORMAT_LAYOUT_YCBCR 1 @@ -286,6 +287,7 @@ enum pipe_format { /** + * Unsigned 8-bit stencil format. * XXX should remove this, but S8_UNORM is a poor name */ #define PIPE_FORMAT_U_S8 PIPE_FORMAT_S8_UNORM @@ -294,11 +296,12 @@ enum pipe_format { /** * Builds pipe format name from format token. */ -static INLINE char *pf_sprint_name( char *str, uint format ) +static INLINE char *pf_sprint_name( char *str, enum pipe_format format ) { strcpy( str, "PIPE_FORMAT_" ); switch (pf_layout( format )) { - case PIPE_FORMAT_LAYOUT_RGBAZS: { + case PIPE_FORMAT_LAYOUT_RGBAZS: + { pipe_format_rgbazs_t rgbazs = (pipe_format_rgbazs_t) format; uint i; uint scale = 1 << (pf_exp8( rgbazs ) * 3); @@ -362,7 +365,8 @@ static INLINE char *pf_sprint_name( char *str, uint format ) } } break; - case PIPE_FORMAT_LAYOUT_YCBCR: { + case PIPE_FORMAT_LAYOUT_YCBCR: + { pipe_format_ycbcr_t ycbcr = (pipe_format_ycbcr_t) format; strcat( str, "YCBCR" ); @@ -375,6 +379,10 @@ static INLINE char *pf_sprint_name( char *str, uint format ) return str; } +/** + * Return bits for a particular component. + * \param comp component index, starting at 0 + */ static INLINE uint pf_get_component_bits( enum pipe_format format, uint comp ) { uint size; @@ -397,6 +405,9 @@ static INLINE uint pf_get_component_bits( enum pipe_format format, uint comp ) return size << (pf_exp8(format) * 3); } +/** + * Return total bits needed for the pixel format. + */ static INLINE uint pf_get_bits( enum pipe_format format ) { if (pf_layout(format) == PIPE_FORMAT_LAYOUT_RGBAZS) { @@ -417,7 +428,11 @@ static INLINE uint pf_get_bits( enum pipe_format format ) } } -static INLINE uint pf_get_size( enum pipe_format format ) { +/** + * Return bytes per pixel for the given format. + */ +static INLINE uint pf_get_size( enum pipe_format format ) +{ assert(pf_get_bits(format) % 8 == 0); return pf_get_bits(format) / 8; } -- cgit v1.2.3 From ad62644290cfb849db13fddab67bbf8515698d27 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Mar 2008 10:43:56 -0600 Subject: gallium: added sRGB formats --- src/gallium/include/pipe/p_format.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index d09b6dbefc..86e9704256 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -80,6 +80,8 @@ static INLINE uint pf_layout(uint f) /**< PIPE_FORMAT_LAYOUT_ */ #define PIPE_FORMAT_TYPE_SNORM 3 #define PIPE_FORMAT_TYPE_USCALED 4 #define PIPE_FORMAT_TYPE_SSCALED 5 +#define PIPE_FORMAT_TYPE_SRGB 6 + /** * Because the destination vector is assumed to be RGBA FLOAT, we @@ -282,7 +284,12 @@ enum pipe_format { PIPE_FORMAT_R8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R8G8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R8G8B8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SSCALED ), - PIPE_FORMAT_R8G8B8A8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ) + PIPE_FORMAT_R8G8B8A8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ), + /* sRGB formats */ + PIPE_FORMAT_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), + PIPE_FORMAT_A8_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), + PIPE_FORMAT_R8G8B8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB ), + PIPE_FORMAT_R8G8B8A8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ) }; -- cgit v1.2.3 From a472e3558e96dc4efcfee5db0e0cd21d9318dd30 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Mar 2008 10:45:33 -0600 Subject: gallium: PIPE_FORMAT_TYPE_ comments --- src/gallium/include/pipe/p_format.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 86e9704256..5f7b7c74b3 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -75,12 +75,12 @@ static INLINE uint pf_layout(uint f) /**< PIPE_FORMAT_LAYOUT_ */ * Format types for RGBAZS layout. */ #define PIPE_FORMAT_TYPE_UNKNOWN 0 -#define PIPE_FORMAT_TYPE_FLOAT 1 -#define PIPE_FORMAT_TYPE_UNORM 2 -#define PIPE_FORMAT_TYPE_SNORM 3 -#define PIPE_FORMAT_TYPE_USCALED 4 -#define PIPE_FORMAT_TYPE_SSCALED 5 -#define PIPE_FORMAT_TYPE_SRGB 6 +#define PIPE_FORMAT_TYPE_FLOAT 1 /**< 16/32/64-bit/channel formats */ +#define PIPE_FORMAT_TYPE_UNORM 2 /**< uints, normalized to [0,1] */ +#define PIPE_FORMAT_TYPE_SNORM 3 /**< ints, normalized to [-1,1] */ +#define PIPE_FORMAT_TYPE_USCALED 4 /**< uints, not normalized */ +#define PIPE_FORMAT_TYPE_SSCALED 5 /**< ints, not normalized */ +#define PIPE_FORMAT_TYPE_SRGB 6 /**< sRGB colorspace */ /** -- cgit v1.2.3 From 419248b5287e98494d4460ed418e572a8e556ac6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Mar 2008 10:50:26 -0600 Subject: gallium: document is_format_supported()'s type param --- src/gallium/include/pipe/p_screen.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 6be9a82b68..35bd46d691 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -69,6 +69,7 @@ struct pipe_screen { float (*get_paramf)( struct pipe_screen *, int param ); + /**< type is one of PIPE_TEXTURE, PIPE_SURFACE */ boolean (*is_format_supported)( struct pipe_screen *, enum pipe_format format, uint type ); -- cgit v1.2.3 From 4394736252fd79827a635a9746243689fef76b05 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 21 Mar 2008 11:03:53 -0600 Subject: gallium: added DXT formats (preliminary, will probably change) --- src/gallium/include/pipe/p_format.h | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 5f7b7c74b3..3238b152b6 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -49,6 +49,8 @@ extern "C" { */ #define PIPE_FORMAT_LAYOUT_RGBAZS 0 #define PIPE_FORMAT_LAYOUT_YCBCR 1 +#define PIPE_FORMAT_LAYOUT_DXT 2 /**< XXX temporary? */ + static INLINE uint pf_layout(uint f) /**< PIPE_FORMAT_LAYOUT_ */ { @@ -199,6 +201,20 @@ static INLINE uint pf_rev(pipe_format_ycbcr_t f) return (f >> 2) & 0x1; } + +/** + * Compresssed format layouts (this will probably change) + */ +#define _PIPE_FORMAT_DXT( LEVEL, RSIZE, GSIZE, BSIZE, ASIZE ) \ + ((PIPE_FORMAT_LAYOUT_DXT << 0) | \ + ((LEVEL) << 2) | \ + ((RSIZE) << 5) | \ + ((GSIZE) << 8) | \ + ((BSIZE) << 11) | \ + ((ASIZE) << 14) ) + + + /** * Texture/surface image formats (preliminary) */ @@ -289,7 +305,13 @@ enum pipe_format { PIPE_FORMAT_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), PIPE_FORMAT_A8_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), PIPE_FORMAT_R8G8B8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB ), - PIPE_FORMAT_R8G8B8A8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ) + PIPE_FORMAT_R8G8B8A8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), + + /* compressed formats */ + PIPE_FORMAT_DXT1_RGB = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 0 ), + PIPE_FORMAT_DXT1_RGBA = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 8 ), + PIPE_FORMAT_DXT3_RGBA = _PIPE_FORMAT_DXT( 3, 8, 8, 8, 8 ), + PIPE_FORMAT_DXT5_RGBA = _PIPE_FORMAT_DXT( 5, 8, 8, 8, 8 ) }; -- cgit v1.2.3 From b70a6babfbc035d64dbe35ac4bf9218e8232b435 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 21 Mar 2008 10:03:23 -0600 Subject: i915: added to-do note about setting the max_lod register to get proper min/mag filter selection --- src/gallium/drivers/i915simple/i915_state_sampler.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c index 9dbb1b1b23..84f6529a3a 100644 --- a/src/gallium/drivers/i915simple/i915_state_sampler.c +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -206,6 +206,12 @@ i915_update_texture(struct i915_context *i915, uint unit, | format | MS3_USE_FENCE_REGS); + /* + * XXX sampler->max_lod should be used to program the MAX_LOD field below. + * Also, when min_filter != mag_filter and there's just one mipmap level, + * set max_lod = 1 to make sure i915 chooses between min/mag filtering. + */ + /* MS4 state */ state[1] = ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) -- cgit v1.2.3 From 2902c164a22b6bcb6a42d7cd7fa82b608875093b Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 21 Mar 2008 10:23:52 -0700 Subject: cell: Remove unnecessary default_blend work-around I suspect that there was some other bug in the blend code-gen that made this work-around necessary. --- src/gallium/drivers/cell/spu/spu_main.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 41bebf5362..0a490ab277 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -64,21 +64,6 @@ static unsigned char depth_stencil_code_buffer[4 * 64] static unsigned char fb_blend_code_buffer[4 * 64] ALIGN16_ATTRIB; -static struct spu_blend_results -default_blend(qword frag_r, qword frag_g, qword frag_b, qword frag_a, - qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a, - qword frag_mask) -{ - struct spu_blend_results result; - - result.r = si_selb(pixel_r, frag_r, frag_mask); - result.g = si_selb(pixel_g, frag_g, frag_mask); - result.b = si_selb(pixel_b, frag_b, frag_mask); - result.a = si_selb(pixel_a, frag_a, frag_mask); - - return result; -} - /** * Tell the PPU that this SPU has finished copying a buffer to @@ -285,9 +270,6 @@ cmd_state_blend(const struct cell_command_blend *state) spu.blend = (blend_func) fb_blend_code_buffer; spu.read_fb = state->read_fb; } else { - /* If there is no code, use the default; - */ - spu.blend = default_blend; spu.read_fb = FALSE; } } @@ -622,9 +604,6 @@ one_time_init(void) memset(spu.ctile_status, TILE_STATUS_DEFINED, sizeof(spu.ctile_status)); memset(spu.ztile_status, TILE_STATUS_DEFINED, sizeof(spu.ztile_status)); invalidate_tex_cache(); - - spu.blend = default_blend; - spu.read_fb = FALSE; } -- cgit v1.2.3 From f140062b72ee2df05020d86abdc47336262494f9 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 21 Mar 2008 10:25:58 -0700 Subject: Tabs to spaces --- .../drivers/cell/ppu/cell_state_per_fragment.c | 54 +++++++++++----------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index 988c251e20..f353aeab0a 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -72,8 +72,8 @@ emit_alpha_test(struct pipe_depth_stencil_alpha_state *dsa, int tmp_a = spe_allocate_available_register(f); int tmp_b = spe_allocate_available_register(f); union { - float f; - unsigned u; + float f; + unsigned u; } ref_val; boolean complement = FALSE; @@ -84,42 +84,42 @@ emit_alpha_test(struct pipe_depth_stencil_alpha_state *dsa, switch (dsa->alpha.func) { case PIPE_FUNC_NOTEQUAL: - complement = TRUE; - /* FALLTHROUGH */ + complement = TRUE; + /* FALLTHROUGH */ case PIPE_FUNC_EQUAL: - spe_fceq(f, tmp_a, ref, alphas); - break; + spe_fceq(f, tmp_a, ref, alphas); + break; case PIPE_FUNC_LEQUAL: - complement = TRUE; - /* FALLTHROUGH */ + complement = TRUE; + /* FALLTHROUGH */ case PIPE_FUNC_GREATER: - spe_fcgt(f, tmp_a, ref, alphas); - break; + spe_fcgt(f, tmp_a, ref, alphas); + break; case PIPE_FUNC_LESS: - complement = TRUE; - /* FALLTHROUGH */ + complement = TRUE; + /* FALLTHROUGH */ case PIPE_FUNC_GEQUAL: - spe_fcgt(f, tmp_a, ref, alphas); - spe_fceq(f, tmp_b, ref, alphas); - spe_or(f, tmp_a, tmp_b, tmp_a); - break; + spe_fcgt(f, tmp_a, ref, alphas); + spe_fceq(f, tmp_b, ref, alphas); + spe_or(f, tmp_a, tmp_b, tmp_a); + break; case PIPE_FUNC_ALWAYS: case PIPE_FUNC_NEVER: default: - assert(0); - break; + assert(0); + break; } if (complement) { - spe_andc(f, mask, mask, tmp_a); + spe_andc(f, mask, mask, tmp_a); } else { - spe_and(f, mask, mask, tmp_a); + spe_and(f, mask, mask, tmp_a); } spe_release_register(f, ref); @@ -674,7 +674,7 @@ emit_alpha_factor_calculation(struct spe_function *f, static void emit_color_factor_calculation(struct spe_function *f, unsigned sF, unsigned mask, - const struct pipe_blend_color *blend_color, + const struct pipe_blend_color *blend_color, const int *src, const int *dst, int *factor) @@ -754,10 +754,10 @@ emit_color_factor_calculation(struct spe_function *f, /* FALLTHROUGH */ case PIPE_BLENDFACTOR_CONST_COLOR: for (i = 0; i < 3; i++) { - factor[i] = spe_allocate_available_register(f); + factor[i] = spe_allocate_available_register(f); - spe_il(f, factor[i], color.u[i] & 0x0ffff); - spe_ilh(f, factor[i], color.u[i] >> 16); + spe_il(f, factor[i], color.u[i] & 0x0ffff); + spe_ilh(f, factor[i], color.u[i] >> 16); } break; @@ -946,7 +946,7 @@ emit_blend_calculation(struct spe_function *f, */ void cell_generate_alpha_blend(struct cell_blend_state *cb, - const struct pipe_blend_color *blend_color) + const struct pipe_blend_color *blend_color) { struct pipe_blend_state *const b = &cb->base; struct spe_function *const f = &cb->code; @@ -1054,7 +1054,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, */ if (((b->colormask & 8) != 0) && need_alpha_factor) { src_factor[3] = emit_alpha_factor_calculation(f, sF[3], - blend_color->color[3], + blend_color->color[3], frag[3], pixel[3]); /* If the alpha destination blend factor is the same as the alpha source @@ -1063,7 +1063,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, dst_factor[3] = (dF[3] == sF[3]) ? src_factor[3] : emit_alpha_factor_calculation(f, dF[3], - blend_color->color[3], + blend_color->color[3], frag[3], pixel[3]); } -- cgit v1.2.3 From 600499cf888fee9a91ff3106beca939ea0c7b2bd Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 21 Mar 2008 11:15:49 -0700 Subject: cell: Change code-gen for CONST_COLOR blend factor Previously the constant color blend factor was compiled into the generated code. This meant that the code had to be regenerated each time the constant color was changed. This doesn't fit with the model used in Gallium. As-is, the code could be better. The constant color is loaded for every quad processed, even if it is not used. Also, if a lot of (1-x) blend factors are used, 1.0 will be loaded and reloaded into registers many times. --- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 2 +- .../drivers/cell/ppu/cell_state_per_fragment.c | 93 +++++++++++----------- .../drivers/cell/ppu/cell_state_per_fragment.h | 3 +- src/gallium/drivers/cell/spu/spu_main.h | 2 + src/gallium/drivers/cell/spu/spu_tri.c | 2 + 5 files changed, 53 insertions(+), 49 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 86fcdcff1f..d956d6fad4 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -63,7 +63,7 @@ cell_bind_blend_state(struct pipe_context *pipe, void *state) draw_flush(cell->draw); if ((blend != NULL) && (blend->code.store == NULL)) { - cell_generate_alpha_blend(blend, &cell->blend_color); + cell_generate_alpha_blend(blend); } cell->blend = blend; diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index f353aeab0a..c750b1d89d 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -588,19 +588,13 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) */ static int emit_alpha_factor_calculation(struct spe_function *f, - unsigned factor, float const_alpha, - int src_alpha, int dst_alpha) + unsigned factor, + int src_alpha, int dst_alpha, int const_alpha) { - union { - float f; - unsigned u; - } alpha; int factor_reg; int tmp; - alpha.f = const_alpha; - switch (factor) { case PIPE_BLENDFACTOR_ONE: factor_reg = -1; @@ -621,13 +615,17 @@ emit_alpha_factor_calculation(struct spe_function *f, break; case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - const_alpha = 1.0 - const_alpha; - /* FALLTHROUGH */ - case PIPE_BLENDFACTOR_CONST_ALPHA: factor_reg = spe_allocate_available_register(f); - spe_il(f, factor_reg, alpha.u & 0x0ffff); - spe_ilh(f, factor_reg, alpha.u >> 16); + tmp = spe_allocate_available_register(f); + spe_il(f, tmp, 1); + spe_cuflt(f, tmp, tmp, 0); + spe_fs(f, factor_reg, tmp, const_alpha); + spe_release_register(f, tmp); + break; + + case PIPE_BLENDFACTOR_CONST_ALPHA: + factor_reg = const_alpha; break; case PIPE_BLENDFACTOR_ZERO: @@ -674,24 +672,15 @@ emit_alpha_factor_calculation(struct spe_function *f, static void emit_color_factor_calculation(struct spe_function *f, unsigned sF, unsigned mask, - const struct pipe_blend_color *blend_color, const int *src, const int *dst, + const int *const_color, int *factor) { - union { - float f[4]; - unsigned u[4]; - } color; int tmp; unsigned i; - color.f[0] = blend_color->color[0]; - color.f[1] = blend_color->color[1]; - color.f[2] = blend_color->color[2]; - color.f[3] = blend_color->color[3]; - factor[0] = -1; factor[1] = -1; factor[2] = -1; @@ -748,29 +737,40 @@ emit_color_factor_calculation(struct spe_function *f, break; case PIPE_BLENDFACTOR_INV_CONST_COLOR: - color.f[0] = 1.0 - color.f[0]; - color.f[1] = 1.0 - color.f[1]; - color.f[2] = 1.0 - color.f[2]; - /* FALLTHROUGH */ - case PIPE_BLENDFACTOR_CONST_COLOR: + tmp = spe_allocate_available_register(f); + spe_il(f, tmp, 1); + spe_cuflt(f, tmp, tmp, 0); + for (i = 0; i < 3; i++) { factor[i] = spe_allocate_available_register(f); - spe_il(f, factor[i], color.u[i] & 0x0ffff); - spe_ilh(f, factor[i], color.u[i] >> 16); + spe_fs(f, factor[i], tmp, const_color[i]); + } + spe_release_register(f, tmp); + break; + + case PIPE_BLENDFACTOR_CONST_COLOR: + for (i = 0; i < 3; i++) { + factor[i] = const_color[i]; } break; case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - color.f[3] = 1.0 - color.f[3]; - /* FALLTHROUGH */ - case PIPE_BLENDFACTOR_CONST_ALPHA: factor[0] = spe_allocate_available_register(f); factor[1] = factor[0]; factor[2] = factor[0]; - spe_il(f, factor[0], color.u[3] & 0x0ffff); - spe_ilh(f, factor[0], color.u[3] >> 16); + tmp = spe_allocate_available_register(f); + spe_il(f, tmp, 1); + spe_cuflt(f, tmp, tmp, 0); + spe_fs(f, factor[0], tmp, const_color[3]); + spe_release_register(f, tmp); + break; + + case PIPE_BLENDFACTOR_CONST_ALPHA: + factor[0] = const_color[3]; + factor[1] = factor[0]; + factor[2] = factor[0]; break; case PIPE_BLENDFACTOR_ZERO: @@ -945,8 +945,7 @@ emit_blend_calculation(struct spe_function *f, * Generate code to perform alpha blending on the SPE */ void -cell_generate_alpha_blend(struct cell_blend_state *cb, - const struct pipe_blend_color *blend_color) +cell_generate_alpha_blend(struct cell_blend_state *cb) { struct pipe_blend_state *const b = &cb->base; struct spe_function *const f = &cb->code; @@ -972,7 +971,13 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, spe_allocate_register(f, 9), spe_allocate_register(f, 10), }; - const int mask = spe_allocate_register(f, 11); + const int const_color[4] = { + spe_allocate_register(f, 11), + spe_allocate_register(f, 12), + spe_allocate_register(f, 13), + spe_allocate_register(f, 14), + }; + const int mask = spe_allocate_register(f, 15); unsigned func[4]; unsigned sF[4]; unsigned dF[4]; @@ -1053,8 +1058,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, * the alpha factor, calculate the alpha factor. */ if (((b->colormask & 8) != 0) && need_alpha_factor) { - src_factor[3] = emit_alpha_factor_calculation(f, sF[3], - blend_color->color[3], + src_factor[3] = emit_alpha_factor_calculation(f, sF[3], const_color[3], frag[3], pixel[3]); /* If the alpha destination blend factor is the same as the alpha source @@ -1062,8 +1066,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, */ dst_factor[3] = (dF[3] == sF[3]) ? src_factor[3] - : emit_alpha_factor_calculation(f, dF[3], - blend_color->color[3], + : emit_alpha_factor_calculation(f, dF[3], const_color[3], frag[3], pixel[3]); } @@ -1080,8 +1083,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, emit_color_factor_calculation(f, b->rgb_src_factor, b->colormask, - blend_color, - frag, pixel, src_factor); + frag, pixel, const_color, src_factor); } @@ -1101,8 +1103,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb, emit_color_factor_calculation(f, b->rgb_dst_factor, b->colormask, - blend_color, - frag, pixel, dst_factor); + frag, pixel, const_color, dst_factor); } diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h index 541c3b3be0..f699247f9e 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h @@ -29,7 +29,6 @@ extern void cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa); extern void -cell_generate_alpha_blend(struct cell_blend_state *cb, - const struct pipe_blend_color *blend_color); +cell_generate_alpha_blend(struct cell_blend_state *cb); #endif /* CELL_STATE_PER_FRAGMENT_H */ diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index 56d0968676..49f5d99674 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -77,6 +77,7 @@ struct spu_blend_results { typedef struct spu_blend_results (*blend_func)( qword frag_r, qword frag_g, qword frag_b, qword frag_a, qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a, + qword const_r, qword const_g, qword const_b, qword const_a, qword frag_mask); struct spu_framebuffer { @@ -108,6 +109,7 @@ struct spu_global boolean read_fb; blend_func blend; + qword const_blend_color[4] ALIGN16_ATTRIB; struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; struct cell_command_texture texture; diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index c4272d6e93..e6a1ce01df 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -356,6 +356,8 @@ emit_quad( int x, int y, mask_t mask ) const struct spu_blend_results result = (*spu.blend)(soa_frag[0], soa_frag[1], soa_frag[2], soa_frag[3], soa_pix[0], soa_pix[1], soa_pix[2], soa_pix[3], + spu.const_blend_color[0], spu.const_blend_color[1], + spu.const_blend_color[2], spu.const_blend_color[3], (qword) mask); -- cgit v1.2.3 From 47531442e9c89c3ca764e9be225cfaec388609a1 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 21 Mar 2008 11:20:49 -0700 Subject: cell: Generate blend / depth test code when state atom is created Code generation should be performed when the device-specific state atom is created, not when it is bound. --- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 30 ++++++++------------------ 1 file changed, 9 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index d956d6fad4..00f4be7401 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -1,5 +1,5 @@ /************************************************************************** - * + * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ /* Authors: @@ -47,7 +47,7 @@ cell_create_blend_state(struct pipe_context *pipe, struct cell_blend_state *cb = MALLOC(sizeof(struct cell_blend_state)); (void) memcpy(cb, blend, sizeof(*blend)); - cb->code.store = NULL; + cell_generate_alpha_blend(cb); return cb; } @@ -57,16 +57,10 @@ static void cell_bind_blend_state(struct pipe_context *pipe, void *state) { struct cell_context *cell = cell_context(pipe); - struct cell_blend_state *blend = (struct cell_blend_state *) state; - draw_flush(cell->draw); - if ((blend != NULL) && (blend->code.store == NULL)) { - cell_generate_alpha_blend(blend); - } - - cell->blend = blend; + cell->blend = (struct cell_blend_state *) state; cell->dirty |= CELL_NEW_BLEND; } @@ -105,7 +99,7 @@ cell_create_depth_stencil_alpha_state(struct pipe_context *pipe, MALLOC(sizeof(struct cell_depth_stencil_alpha_state)); (void) memcpy(cdsa, depth_stencil, sizeof(*depth_stencil)); - cdsa->code.store = NULL; + cell_generate_depth_stencil_test(cdsa); return cdsa; } @@ -116,16 +110,11 @@ cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth_stencil) { struct cell_context *cell = cell_context(pipe); - struct cell_depth_stencil_alpha_state *cdsa = - (struct cell_depth_stencil_alpha_state *) depth_stencil; draw_flush(cell->draw); - if ((cdsa != NULL) && (cdsa->code.store == NULL)) { - cell_generate_depth_stencil_test(cdsa); - } - - cell->depth_stencil = cdsa; + cell->depth_stencil = + (struct cell_depth_stencil_alpha_state *) depth_stencil; cell->dirty |= CELL_NEW_DEPTH_STENCIL; } @@ -362,4 +351,3 @@ cell_init_state_functions(struct cell_context *cell) cell->pipe.set_scissor_state = cell_set_scissor_state; cell->pipe.set_viewport_state = cell_set_viewport_state; } - -- cgit v1.2.3 From 4e977fb35befa60b2f74a21c0c9818854e6a7c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 22 Mar 2008 10:05:55 +0000 Subject: gallium: Remove pedantic asserts. Move these to a higher level instead. --- src/gallium/auxiliary/util/u_handle_table.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c index 5a731a6b96..2176a00959 100644 --- a/src/gallium/auxiliary/util/u_handle_table.c +++ b/src/gallium/auxiliary/util/u_handle_table.c @@ -170,7 +170,7 @@ handle_table_set(struct handle_table *ht, unsigned index; assert(ht); - assert(handle > 0); + assert(handle); if(!handle) return 0; @@ -184,7 +184,9 @@ handle_table_set(struct handle_table *ht, if(!handle_table_resize(ht, index)) return 0; - assert(!ht->objects[index]); + if(ht->objects[index] && ht->destroy) + ht->destroy(ht->objects[index]); + ht->objects[index] = object; return handle; @@ -198,13 +200,11 @@ handle_table_get(struct handle_table *ht, void *object; assert(ht); - assert(handle > 0); - assert(handle <= ht->size); + assert(handle); if(!handle || handle > ht->size) return NULL; object = ht->objects[handle - 1]; - assert(object); return object; } @@ -218,18 +218,14 @@ handle_table_remove(struct handle_table *ht, unsigned index; assert(ht); - assert(handle > 0); - assert(handle <= ht->size); + assert(handle); if(!handle || handle > ht->size) return; index = handle - 1; object = ht->objects[index]; - if(!object) { - /* XXX: this warning may be noisy for legitimate use -- remove later */ - debug_warning("removing empty handle"); + if(!object) return; - } if(ht->destroy) ht->destroy(object); -- cgit v1.2.3 From 28b3b078959db8a1e60adfb66f35ceb04d4f414d Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 22 Mar 2008 09:12:27 -0600 Subject: gallium: fix mem leak (fee pstipple stage) --- src/gallium/auxiliary/draw/draw_context.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 4cca965ac1..41da93cdf8 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -113,6 +113,8 @@ void draw_destroy( struct draw_context *draw ) draw->pipeline.aaline->destroy( draw->pipeline.aaline ); if (draw->pipeline.aapoint) draw->pipeline.aapoint->destroy( draw->pipeline.aapoint ); + if (draw->pipeline.pstipple) + draw->pipeline.pstipple->destroy( draw->pipeline.pstipple ); if (draw->pipeline.rasterize) draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); tgsi_exec_machine_free_data(&draw->machine); -- cgit v1.2.3 From 2f8f6c2918e721f6525b2124cde053b84beecafe Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 22 Mar 2008 09:15:23 -0600 Subject: gallium: remove temporary _screen suffix from function names --- src/gallium/drivers/softpipe/sp_texture.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index a98b3b1a4a..256586ec88 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -81,8 +81,8 @@ softpipe_texture_layout(struct softpipe_texture * spt) static struct pipe_texture * -softpipe_texture_create_screen(struct pipe_screen *screen, - const struct pipe_texture *templat) +softpipe_texture_create(struct pipe_screen *screen, + const struct pipe_texture *templat) { struct pipe_winsys *ws = screen->winsys; struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); @@ -110,8 +110,8 @@ softpipe_texture_create_screen(struct pipe_screen *screen, static void -softpipe_texture_release_screen(struct pipe_screen *screen, - struct pipe_texture **pt) +softpipe_texture_release(struct pipe_screen *screen, + struct pipe_texture **pt) { if (!*pt) return; @@ -136,9 +136,9 @@ softpipe_texture_release_screen(struct pipe_screen *screen, static struct pipe_surface * -softpipe_get_tex_surface_screen(struct pipe_screen *screen, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) +softpipe_get_tex_surface(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) { struct pipe_winsys *ws = screen->winsys; struct softpipe_texture *spt = softpipe_texture(pt); @@ -197,7 +197,7 @@ softpipe_init_texture_funcs( struct softpipe_context *softpipe ) void softpipe_init_screen_texture_funcs(struct pipe_screen *screen) { - screen->texture_create = softpipe_texture_create_screen; - screen->texture_release = softpipe_texture_release_screen; - screen->get_tex_surface = softpipe_get_tex_surface_screen; + screen->texture_create = softpipe_texture_create; + screen->texture_release = softpipe_texture_release; + screen->get_tex_surface = softpipe_get_tex_surface; } -- cgit v1.2.3 From dae7993afc56be1e71e600af60e01e51eab17eda Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 22 Mar 2008 09:42:59 -0600 Subject: gallium: free samplers, textures in destroy() --- src/gallium/auxiliary/draw/draw_aaline.c | 7 +++++++ src/gallium/auxiliary/draw/draw_pstipple.c | 6 ++++++ 2 files changed, 13 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index b4fa6bd967..6742f7f4b9 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -665,7 +665,14 @@ aaline_reset_stipple_counter(struct draw_stage *stage) static void aaline_destroy(struct draw_stage *stage) { + struct aaline_stage *aaline = aaline_stage(stage); + + aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); + + pipe_texture_release(&aaline->texture); + draw_free_temp_verts( stage ); + FREE( stage ); } diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index 9d154a6838..bd8d3a76ae 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -534,6 +534,12 @@ pstip_reset_stipple_counter(struct draw_stage *stage) static void pstip_destroy(struct draw_stage *stage) { + struct pstip_stage *pstip = pstip_stage(stage); + + pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso); + + pipe_texture_release(&pstip->texture); + draw_free_temp_verts( stage ); FREE( stage ); } -- cgit v1.2.3 From f40357e25c0520ef1d64ffab03501da4c8b93529 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Mar 2008 16:44:59 +0000 Subject: gallium: beginnings of draw module vertex rework Trying to put a structure in place that we can actually optimize. Initially just implementing a passthrough mode, this will fairly soon replace all the vertex_cache/prim_queue/shader_queue stuff that's so hard to understand... Split the vertex processing into a couple of distinct stages: - Frontend - Prepares two lists of elements (fetch and draw) to be processed by the next stage. This stage doesn't fetch or draw vertices, but makes the decision which to draw. Multiple implementations of this will implement different strategies, currently just a vcache implementation. - MiddleEnd - Takes the list of fetch elements, fetches them, runs the vertex shader, cliptest, viewport transform on them to produce a linear array of vertex_header vertices. - Passes that list of vertices, plus the draw_elements (which index into that list) onto the backend - Backend - Either the existing primitive/clipping pipeline, or the vbuf_render hardware backend provided by the driver. Currently, the middle-end is the old passthrough code, and it build hardware vertices, not vertex_header vertices as above. It may be that passthrough is a special case in this respect. --- src/gallium/auxiliary/draw/Makefile | 4 + src/gallium/auxiliary/draw/SConscript | 6 +- src/gallium/auxiliary/draw/draw_context.c | 65 ++++- src/gallium/auxiliary/draw/draw_passthrough.c | 4 +- src/gallium/auxiliary/draw/draw_prim.c | 2 +- src/gallium/auxiliary/draw/draw_private.h | 33 ++- src/gallium/auxiliary/draw/draw_pt.c | 206 +++++++++++++++ src/gallium/auxiliary/draw/draw_pt.h | 116 ++++++++ src/gallium/auxiliary/draw/draw_pt_elts.c | 88 ++++++ src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 326 +++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pt_vcache.c | 338 ++++++++++++++++++++++++ 11 files changed, 1169 insertions(+), 19 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt.c create mode 100644 src/gallium/auxiliary/draw/draw_pt.h create mode 100644 src/gallium/auxiliary/draw/draw_pt_elts.c create mode 100644 src/gallium/auxiliary/draw/draw_pt_fetch_emit.c create mode 100644 src/gallium/auxiliary/draw/draw_pt_vcache.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 21e9f737b7..0c7ce5da5b 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -16,6 +16,10 @@ C_SOURCES = \ draw_flatshade.c \ draw_offset.c \ draw_passthrough.c \ + draw_pt.c \ + draw_pt_vcache.c \ + draw_pt_fetch_emit.c \ + draw_pt_elts.c \ draw_prim.c \ draw_pstipple.c \ draw_stipple.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index d7fb86d992..9b3e7247c5 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -14,7 +14,11 @@ draw = env.ConvenienceLibrary( 'draw_debug.c', 'draw_flatshade.c', 'draw_offset.c', - 'draw_passthrough.c', + 'draw_passthrough.c', # going away soon + 'draw_pt.c', + 'draw_pt_vcache.c', + 'draw_pt_fetch_emit.c', + 'draw_pt_elts.c', 'draw_prim.c', 'draw_pstipple.c', 'draw_stipple.c', diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 41da93cdf8..903cc26766 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -37,10 +37,11 @@ #include "draw_vbuf.h" - struct draw_context *draw_create( void ) { struct draw_context *draw = CALLOC_STRUCT( draw_context ); + if (draw == NULL) + goto fail; #if defined(__i386__) || defined(__386__) draw->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; @@ -61,6 +62,19 @@ struct draw_context *draw_create( void ) draw->pipeline.validate = draw_validate_stage( draw ); draw->pipeline.first = draw->pipeline.validate; + if (!draw->pipeline.wide_line || + !draw->pipeline.wide_point || + !draw->pipeline.stipple || + !draw->pipeline.unfilled || + !draw->pipeline.twoside || + !draw->pipeline.offset || + !draw->pipeline.clip || + !draw->pipeline.flatshade || + !draw->pipeline.cull || + !draw->pipeline.validate) + goto fail; + + 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 ); @@ -75,6 +89,8 @@ struct draw_context *draw_create( void ) uint i; const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; char *tmp = align_malloc(Elements(draw->vs.queue) * size, 16); + if (!tmp) + goto fail; for (i = 0; i < Elements(draw->vs.queue); i++) draw->vs.queue[i].vertex = (struct vertex_header *)(tmp + i * size); @@ -93,22 +109,42 @@ struct draw_context *draw_create( void ) draw_vertex_cache_invalidate( draw ); draw_set_mapped_element_buffer( draw, 0, NULL ); + if (!draw_pt_init( draw )) + goto fail; + return draw; + +fail: + draw_destroy( draw ); + return NULL; } void draw_destroy( struct draw_context *draw ) { - draw->pipeline.wide_line->destroy( draw->pipeline.wide_line ); - draw->pipeline.wide_point->destroy( draw->pipeline.wide_point ); - draw->pipeline.stipple->destroy( draw->pipeline.stipple ); - draw->pipeline.unfilled->destroy( draw->pipeline.unfilled ); - draw->pipeline.twoside->destroy( draw->pipeline.twoside ); - draw->pipeline.offset->destroy( draw->pipeline.offset ); - draw->pipeline.clip->destroy( draw->pipeline.clip ); - draw->pipeline.flatshade->destroy( draw->pipeline.flatshade ); - draw->pipeline.cull->destroy( draw->pipeline.cull ); - draw->pipeline.validate->destroy( draw->pipeline.validate ); + if (!draw) + return; + + if (draw->pipeline.wide_line) + draw->pipeline.wide_line->destroy( draw->pipeline.wide_line ); + if (draw->pipeline.wide_point) + draw->pipeline.wide_point->destroy( draw->pipeline.wide_point ); + if (draw->pipeline.stipple) + draw->pipeline.stipple->destroy( draw->pipeline.stipple ); + if (draw->pipeline.unfilled) + draw->pipeline.unfilled->destroy( draw->pipeline.unfilled ); + if (draw->pipeline.twoside) + draw->pipeline.twoside->destroy( draw->pipeline.twoside ); + if (draw->pipeline.offset) + draw->pipeline.offset->destroy( draw->pipeline.offset ); + if (draw->pipeline.clip) + draw->pipeline.clip->destroy( draw->pipeline.clip ); + if (draw->pipeline.flatshade) + draw->pipeline.flatshade->destroy( draw->pipeline.flatshade ); + if (draw->pipeline.cull) + draw->pipeline.cull->destroy( draw->pipeline.cull ); + if (draw->pipeline.validate) + draw->pipeline.validate->destroy( draw->pipeline.validate ); if (draw->pipeline.aaline) draw->pipeline.aaline->destroy( draw->pipeline.aaline ); if (draw->pipeline.aapoint) @@ -117,8 +153,11 @@ void draw_destroy( struct draw_context *draw ) draw->pipeline.pstipple->destroy( draw->pipeline.pstipple ); if (draw->pipeline.rasterize) draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); + tgsi_exec_machine_free_data(&draw->machine); - align_free( draw->vs.queue[0].vertex ); /* Frees all the vertices. */ + + if (draw->vs.queue[0].vertex) + align_free( draw->vs.queue[0].vertex ); /* Frees all the vertices. */ /* Not so fast -- we're just borrowing this at the moment. * @@ -126,6 +165,8 @@ void draw_destroy( struct draw_context *draw ) draw->render->destroy( draw->render ); */ + draw_pt_destroy( draw ); + FREE( draw ); } diff --git a/src/gallium/auxiliary/draw/draw_passthrough.c b/src/gallium/auxiliary/draw/draw_passthrough.c index fdec6a591b..dd00894c5b 100644 --- a/src/gallium/auxiliary/draw/draw_passthrough.c +++ b/src/gallium/auxiliary/draw/draw_passthrough.c @@ -125,9 +125,9 @@ fetch_store_general( struct draw_context *draw, case PIPE_FORMAT_B8G8R8A8_UNORM: { ubyte *ub = (ubyte *) from; - attrib[0] = UBYTE_TO_FLOAT(ub[0]); + attrib[2] = UBYTE_TO_FLOAT(ub[0]); attrib[1] = UBYTE_TO_FLOAT(ub[1]); - attrib[2] = UBYTE_TO_FLOAT(ub[2]); + attrib[0] = UBYTE_TO_FLOAT(ub[2]); attrib[3] = UBYTE_TO_FLOAT(ub[3]); } break; diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index cb0277fb6c..4fe0ddc02a 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -526,7 +526,7 @@ draw_arrays(struct draw_context *draw, unsigned prim, /* drawing done here: */ if (!draw->rasterizer->bypass_vs || - !draw_passthrough_arrays(draw, prim, start, count)) { + !draw_pt_arrays(draw, prim, start, count)) { /* we have to run the whole pipeline */ draw_prim(draw, prim, start, count); } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 1c65c3d1b2..0c5afcacfa 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -53,6 +53,9 @@ struct pipe_context; struct gallivm_prog; struct gallivm_cpu_engine; +struct draw_pt_middle_end; +struct draw_pt_front_end; + /** * Basic vertex info. * Carry some useful information around with the vertices in the prim pipe. @@ -203,8 +206,21 @@ struct draw_context /* Support prototype passthrough path: */ struct { - unsigned prim; - unsigned hw_vertex_size; + unsigned prim; /* XXX: to be removed */ + unsigned hw_vertex_size; /* XXX: to be removed */ + + struct { + struct draw_pt_middle_end *fetch_emit; + struct draw_pt_middle_end *fetch_shade_emit; + struct draw_pt_middle_end *fetch_shade_cliptest_pipeline_or_emit; + } middle; + + struct { + struct draw_pt_front_end *noop; + struct draw_pt_front_end *split_arrays; + struct draw_pt_front_end *vcache; + } front; + } pt; @@ -351,7 +367,18 @@ extern void draw_update_vertex_fetch( struct draw_context *draw ); extern boolean draw_need_pipeline(const struct draw_context *draw); -/* Prototype/hack +/* Passthrough mode (second attempt): + */ +boolean draw_pt_init( struct draw_context *draw ); +void draw_pt_destroy( struct draw_context *draw ); +boolean draw_pt_arrays( struct draw_context *draw, + unsigned prim, + unsigned start, + unsigned count ); + + + +/* Prototype/hack (DEPRECATED) */ boolean draw_passthrough_arrays(struct draw_context *draw, diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c new file mode 100644 index 0000000000..219b563422 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -0,0 +1,206 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_pt.h" + + +static boolean too_many_verts( struct draw_context *draw, + unsigned verts ) +{ + return verts < 1024; +} + +static boolean too_many_elts( struct draw_context *draw, + unsigned elts ) +{ + return elts < (16 * 1024); +} + + +boolean +draw_pt_arrays(struct draw_context *draw, + unsigned prim, + unsigned start, + unsigned count) +{ + const boolean pipeline = draw_need_pipeline(draw); + const boolean cliptest = !draw->rasterizer->bypass_clipping; + const boolean shading = !draw->rasterizer->bypass_vs; + struct draw_pt_front_end *frontend = NULL; + struct draw_pt_middle_end *middle = NULL; + + + /* Overall we do: + * - frontend -- prepare fetch_elts, draw_elts - eg vcache + * - middle -- fetch, shade, cliptest, viewport + * - pipeline -- the prim pipeline: clipping, wide lines, etc + * - backend -- the vbuf_render provided by the driver. + */ + + +#if 0 + if (!cliptest && !pipeline && !shading) { + /* This is the 'passthrough' path: + */ + /* Fetch user verts, emit hw verts: + */ + middle = draw->pt.middle.fetch_emit; + } + else if (!cliptest && !pipeline) { + /* Fetch user verts, run vertex shader, emit hw verts: + */ + middle = draw->pt.middle.fetch_shade_emit; + } + else if (!pipeline) { + /* Even though !pipeline, we have to run it to get clipping. We + * do know that the pipeline is just the clipping operation, but + * that probably doesn't help much. + * + * This is going to be the most important path for a lot of + * swtnl cards. + */ + /* Fetch user verts, + * run vertex shader, + * cliptest and viewport trasform + * if no clipped vertices, + * emit hw verts + * else + * run pipline + */ + middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit; + } + else if (!cliptest) { + /* Fetch user verts, run vertex shader, run pipeline: + */ + middle = draw->pt.middle.fetch_shade_pipeline; + } + else { + /* This is what we're currently always doing: + */ + /* Fetch user verts, run vertex shader, cliptest, run pipeline: + */ + middle = draw->pt.middle.fetch_shade_cliptest_pipeline; + } +#else + if (cliptest /*|| pipeline*/ || shading) + return FALSE; + + middle = draw->pt.middle.fetch_emit; +#endif + + + /* If !pipeline, need to make sure we respect the driver's limited + * capabilites to receive blocks of vertex data and elements. + */ +#if 0 + if (!pipeline) { + unsigned vertex_mode = passthrough; + unsigned nr_verts = count_vertices( draw, start, count ); + unsigned hw_prim = prim; + + if (is_elts(draw)) { + frontend = draw->pt.front.vcache; + hw_prim = reduced_prim(prim); + } + + if (too_many_verts(nr_verts)) { + /* if (is_verts(draw) && can_split(prim)) { + draw = draw_arrays_split; + } + else */ { + frontend = draw->pt.front.vcache; + hw_prim = reduced_prim(prim); + } + } + + if (too_many_elts(count)) { + + /* if (is_elts(draw) && can_split(prim)) { + draw = draw_elts_split; + } + else */ { + frontend = draw->pt.front.vcache; + hw_prim = reduced_prim(prim); + } + } + + if (!good_prim(hw_prim)) { + draw = draw->pt.front.vcache; + } + } +#else + frontend = draw->pt.front.vcache; +#endif + + frontend->prepare( frontend, middle ); + + frontend->run( frontend, + prim, + draw_pt_elt_func( draw ), + draw_pt_elt_ptr( draw, start ), + count ); + + frontend->finish( frontend ); + + return TRUE; +} + + +boolean draw_pt_init( struct draw_context *draw ) +{ + draw->pt.middle.fetch_emit = draw_pt_fetch_emit( draw ); + if (!draw->pt.middle.fetch_emit) + return FALSE; + + draw->pt.front.vcache = draw_pt_vcache(); + if (!draw->pt.front.vcache) + return FALSE; + + return TRUE; +} + + +void draw_pt_destroy( struct draw_context *draw ) +{ + if (draw->pt.middle.fetch_emit) { + draw->pt.middle.fetch_emit->destroy( draw->pt.middle.fetch_emit ); + draw->pt.middle.fetch_emit = NULL; + } + + if (draw->pt.front.vcache) { + draw->pt.front.vcache->destroy( draw->pt.front.vcache ); + draw->pt.front.vcache = NULL; + } +} diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h new file mode 100644 index 0000000000..1b81d196f6 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -0,0 +1,116 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#ifndef DRAW_PT_H +#define DRAW_PT_H + +#include "pipe/p_compiler.h" + +typedef ushort (*pt_elt_func)( const void *elts, ushort idx ); + + +/* The "front end" - prepare sets of fetch, draw elements for the + * middle end. + * + * Currenly one version of this: + * - vcache - catchall implementation, decomposes to TRI/LINE/POINT prims + * Later: + * - varray, varray_split + * - velement, velement_split + * + * Currenly only using the vcache version. + */ +struct draw_pt_front_end { + void (*prepare)( struct draw_pt_front_end *, + struct draw_pt_middle_end * ); + + void (*run)( struct draw_pt_front_end *, + unsigned prim, + pt_elt_func elt_func, + const void *elt_ptr, + unsigned count ); + + void (*finish)( struct draw_pt_front_end * ); + void (*destroy)( struct draw_pt_front_end * ); +}; + + +/* The "middle end" - prepares actual hardware vertices for the + * hardware backend. + * + * Currently two versions of this: + * - fetch, vertex shade, cliptest, prim-pipeline + * - fetch, emit (ie passthrough) + * Later: + * - fetch, vertex shade, cliptest, maybe-pipeline, maybe-emit + * - fetch, vertex shade, emit + * + * Currenly only using the passthrough version. + */ +struct draw_pt_middle_end { + void (*prepare)( struct draw_pt_middle_end * ); + + void (*run)( struct draw_pt_middle_end *, + unsigned prim, + const unsigned *fetch_elts, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ); + + void (*finish)( struct draw_pt_middle_end * ); + void (*destroy)( struct draw_pt_middle_end * ); +}; + + +/* The "back end" - supplied by the driver, defined in draw_vbuf.h. + * + * Not sure whether to wrap the prim pipeline up as an alternate + * backend. Would be a win for everything except pure passthrough + * mode... + */ +struct vbuf_render; + + +/* Helper functions. + */ +pt_elt_func draw_pt_elt_func( struct draw_context *draw ); +const void *draw_pt_elt_ptr( struct draw_context *draw, + unsigned start ); + +/* Implementations: + */ +struct draw_pt_front_end *draw_pt_vcache( void ); +struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ); + + + +#endif diff --git a/src/gallium/auxiliary/draw/draw_pt_elts.c b/src/gallium/auxiliary/draw/draw_pt_elts.c new file mode 100644 index 0000000000..585b83fa90 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_elts.c @@ -0,0 +1,88 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "draw/draw_pt.h" +#include "draw/draw_private.h" + +/* Neat get_elt func that also works for varrays drawing by encoding + * the start value into a pointer. + */ + +static ushort elt_uint( const void *elts, ushort idx ) +{ + return *(((const uint *)elts) + idx); +} + +static ushort elt_ushort( const void *elts, ushort idx ) +{ + return *(((const ushort *)elts) + idx); +} + +static ushort elt_ubyte( const void *elts, ushort idx ) +{ + return *(((const ubyte *)elts) + idx); +} + +static ushort elt_vert( const void *elts, ushort idx ) +{ + return (const ubyte *)elts - (const ubyte *)NULL + idx; +} + +pt_elt_func draw_pt_elt_func( struct draw_context *draw ) +{ + switch (draw->user.eltSize) { + case 0: return elt_vert; + case 1: return elt_ubyte; + case 2: return elt_ushort; + case 4: return elt_uint; + default: return NULL; + } +} + +const void *draw_pt_elt_ptr( struct draw_context *draw, + unsigned start ) +{ + const char *elts = draw->user.elts; + + switch (draw->user.eltSize) { + case 0: + return (const void *)(((const ubyte *)NULL) + start); + case 1: + return (const void *)(((const ubyte *)elts) + start); + case 2: + return (const void *)(((const ushort *)elts) + start); + case 4: + return (const void *)(((const uint *)elts) + start); + default: + return NULL; + } +} diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c new file mode 100644 index 0000000000..74a946545a --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -0,0 +1,326 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" + +/* The simplest 'middle end' in the new vertex code. + * + * The responsibilities of a middle end are to: + * - perform vertex fetch using + * - draw vertex element/buffer state + * - a list of fetch indices we received as an input + * - run the vertex shader + * - cliptest, + * - clip coord calculation + * - viewport transformation + * - if necessary, run the primitive pipeline, passing it: + * - a linear array of vertex_header vertices constructed here + * - a set of draw indices we received as an input + * - otherwise, drive the hw backend, + * - allocate space for hardware format vertices + * - translate the vertex-shader output vertices to hw format + * - calling the backend draw functions. + * + * For convenience, we provide a helper function to drive the hardware + * backend given similar inputs to those required to run the pipeline. + * + * In the case of passthrough mode, many of these actions are disabled + * or noops, so we end up doing: + * + * - perform vertex fetch + * - drive the hw backend + * + * IE, basically just vertex fetch to post-vs-format vertices, + * followed by a call to the backend helper function. + */ + + +struct fetch_emit_middle_end { + struct draw_pt_middle_end base; + struct draw_context *draw; + + struct { + const ubyte *ptr; + unsigned pitch; + enum pipe_format src_format; + unsigned dst_format; + } fetch[PIPE_ATTRIB_MAX]; + + unsigned nr_fetch; + unsigned hw_vertex_size; +}; + + +/** + * General-purpose fetch from user's vertex arrays, emit to driver's + * vertex buffer. + * + * XXX this is totally temporary. + */ +static void +fetch_store_general( struct fetch_emit_middle_end *feme, + void *out_ptr, + const unsigned *fetch_elts, + unsigned count ) +{ + float *out = (float *)out_ptr; + struct vbuf_render *render = feme->draw->render; + uint i, j; + + for (i = 0; i < count; i++) { + unsigned elt = fetch_elts[i]; + + for (j = 0; j < feme->nr_fetch; j++) { + float attrib[4]; + const ubyte *from = (feme->fetch[j].ptr + + feme->fetch[j].pitch * elt); + + /* The normal fetch/emit code: + */ + switch (feme->fetch[j].src_format) { + case PIPE_FORMAT_B8G8R8A8_UNORM: + { + ubyte *ub = (ubyte *) from; + attrib[2] = UBYTE_TO_FLOAT(ub[0]); + attrib[1] = UBYTE_TO_FLOAT(ub[1]); + attrib[0] = UBYTE_TO_FLOAT(ub[2]); + attrib[3] = UBYTE_TO_FLOAT(ub[3]); + } + break; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + { + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = f[1]; + attrib[2] = f[2]; + attrib[3] = f[3]; + } + break; + case PIPE_FORMAT_R32G32B32_FLOAT: + { + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = f[1]; + attrib[2] = f[2]; + attrib[3] = 1.0; + } + break; + case PIPE_FORMAT_R32G32_FLOAT: + { + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = f[1]; + attrib[2] = 0.0; + attrib[3] = 1.0; + } + break; + case PIPE_FORMAT_R32_FLOAT: + { + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = 0.0; + attrib[2] = 0.0; + attrib[3] = 1.0; + } + break; + default: + assert(0); + } + + if (0) debug_printf("attrib %d: %f %f %f %f\n", j, + attrib[0], attrib[1], attrib[2], attrib[3]); + + switch (feme->fetch[j].dst_format) { + case EMIT_1F: + out[0] = attrib[0]; + out += 1; + break; + case EMIT_2F: + out[0] = attrib[0]; + out[1] = attrib[1]; + out += 2; + break; + case EMIT_4F: + out[0] = attrib[0]; + out[1] = attrib[1]; + out[2] = attrib[2]; + out[3] = attrib[3]; + out += 4; + break; + default: + assert(0); + } + } + } +} + + + +static void fetch_emit_prepare( struct draw_pt_middle_end *middle ) +{ + struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; + struct draw_context *draw = feme->draw; + const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); + unsigned nr_attrs = vinfo->num_attribs; + unsigned i; + + for (i = 0; i < nr_attrs; i++) { + enum pipe_format src_format; + unsigned dst_format; + const void *src_ptr; + unsigned pitch; + + if (vinfo->emit[i] == EMIT_HEADER) { + static const unsigned zero = 0; + src_ptr = &zero; + src_format = PIPE_FORMAT_R32_FLOAT; + pitch = 0; + dst_format = EMIT_1F; + } + else if (vinfo->emit[i] == EMIT_1F_PSIZE) { + src_ptr = &feme->draw->rasterizer->point_size; + src_format = PIPE_FORMAT_R32_FLOAT; + pitch = 0; + dst_format = EMIT_1F; + } + else { + unsigned src_element = vinfo->src_index[i]; + unsigned src_buffer = draw->vertex_element[src_element].vertex_buffer_index; + + src_ptr = ((const ubyte *)draw->user.vbuffer[src_buffer] + + draw->vertex_buffer[src_buffer].buffer_offset + + draw->vertex_element[src_element].src_offset); + + src_format = draw->vertex_element[src_element].src_format; + pitch = draw->vertex_buffer[src_buffer].pitch; + dst_format = vinfo->emit[i]; + } + + feme->fetch[i].src_format = src_format; + feme->fetch[i].ptr = src_ptr; + feme->fetch[i].pitch = pitch; + feme->fetch[i].dst_format = dst_format; + } + + + feme->nr_fetch = nr_attrs; + feme->hw_vertex_size = vinfo->size * 4; +} + + + + + +static void fetch_emit_run( struct draw_pt_middle_end *middle, + unsigned prim, + const unsigned *fetch_elts, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; + struct draw_context *draw = feme->draw; + void *hw_verts; + boolean ok; + + ok = draw->render->set_primitive( draw->render, + prim ); + if (!ok) { + assert(0); + return; + } + + + hw_verts = draw->render->allocate_vertices( draw->render, + (ushort)feme->hw_vertex_size, + (ushort)fetch_count ); + if (!hw_verts) { + assert(0); + return; + } + + + /* Single routine to fetch vertices and emit HW verts. + */ + fetch_store_general( feme, + hw_verts, + fetch_elts, + fetch_count ); + + /* XXX: Draw arrays path to avoid re-emitting index list again and + * again. + */ + draw->render->draw( draw->render, + draw_elts, + draw_count ); + + /* Done -- that was easy, wasn't it: + */ + draw->render->release_vertices( draw->render, + hw_verts, + feme->hw_vertex_size, + fetch_count ); + +} + + + +static void fetch_emit_finish( struct draw_pt_middle_end *middle ) +{ + /* nothing to do */ +} + +static void fetch_emit_destroy( struct draw_pt_middle_end *middle ) +{ + FREE(middle); +} + + +struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ) +{ + struct fetch_emit_middle_end *fetch_emit = CALLOC_STRUCT( fetch_emit_middle_end ); + + fetch_emit->base.prepare = fetch_emit_prepare; + fetch_emit->base.run = fetch_emit_run; + fetch_emit->base.finish = fetch_emit_finish; + fetch_emit->base.destroy = fetch_emit_destroy; + + fetch_emit->draw = draw; + + return &fetch_emit->base; +} + diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c new file mode 100644 index 0000000000..07e9f0ae5f --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -0,0 +1,338 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +//#include "draw/draw_vbuf.h" +//#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" + + +#define CACHE_MAX 32 +#define FETCH_MAX 128 +#define DRAW_MAX (16*1024) + +struct vcache_frontend { + struct draw_pt_front_end base; + + ushort in[CACHE_MAX]; + ushort out[CACHE_MAX]; + + ushort draw_elts[DRAW_MAX]; + unsigned fetch_elts[FETCH_MAX]; + + unsigned draw_count; + unsigned fetch_count; + + pt_elt_func elt_func; + const void *elt_ptr; + + struct draw_pt_middle_end *middle; + unsigned output_prim; +}; + +static void vcache_flush( struct vcache_frontend *vcache ) +{ +#if 0 + /* Should always be true if output_prim == input_prim, otherwise + * not so much... + */ + unsigned i; + for (i = 0; i < vcache->draw_count; i++) { + assert( vcache->fetch_elts[vcache->draw_elts[i]] == + vcache->elt_func(vcache->elt_ptr, i) ); + } +#endif + + if (vcache->draw_count) + vcache->middle->run( vcache->middle, + vcache->output_prim, + vcache->fetch_elts, + vcache->fetch_count, + vcache->draw_elts, + vcache->draw_count ); + + memset(vcache->in, ~0, sizeof(vcache->in)); + vcache->fetch_count = 0; + vcache->draw_count = 0; +} + +static void vcache_check_flush( struct vcache_frontend *vcache ) +{ + if ( vcache->draw_count + 6 >= DRAW_MAX || + vcache->fetch_count + 4 >= FETCH_MAX ) + { + vcache_flush( vcache ); + } +} + + +static void vcache_elt( struct vcache_frontend *vcache, + unsigned felt ) +{ + // ushort felt = elt(draw, i); + + ushort idx = felt % CACHE_MAX; + + if (vcache->in[idx] != felt) { + assert(vcache->fetch_count < FETCH_MAX); + + vcache->in[idx] = felt; + vcache->out[idx] = vcache->fetch_count; + vcache->fetch_elts[vcache->fetch_count++] = felt; + } + + vcache->draw_elts[vcache->draw_count++] = vcache->out[idx]; +} + +static void vcache_triangle( struct vcache_frontend *vcache, + unsigned i0, + unsigned i1, + unsigned i2 ) +{ + /* TODO: encode edgeflags in draw_elts */ + vcache_elt(vcache, i0); + vcache_elt(vcache, i1); + vcache_elt(vcache, i2); + vcache_check_flush(vcache); +} + +static void vcache_line( struct vcache_frontend *vcache, + boolean reset, + unsigned i0, + unsigned i1 ) +{ + /* TODO: encode reset-line-stipple in draw_elts */ + (void) reset; + vcache_elt(vcache, i0); + vcache_elt(vcache, i1); + vcache_check_flush(vcache); +} + + +static void vcache_point( struct vcache_frontend *vcache, + unsigned i0 ) +{ + vcache_elt(vcache, i0); + vcache_check_flush(vcache); +} + +static void vcache_quad( struct vcache_frontend *vcache, + unsigned i0, + unsigned i1, + unsigned i2, + unsigned i3 ) +{ + vcache_triangle( vcache, i0, i1, i3 ); + vcache_triangle( vcache, i1, i2, i3 ); +} + + +static void vcache_prepare( struct draw_pt_front_end *frontend, + struct draw_pt_middle_end *middle ) +{ + struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; + vcache->middle = middle; + middle->prepare( middle ); +} + +static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { + PIPE_PRIM_POINTS, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES +}; + + +static void vcache_run( struct draw_pt_front_end *frontend, + unsigned prim, + pt_elt_func get_elt, + const void *elts, + unsigned count ) +{ + struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; + unsigned i; + + /* These are for validation only: + */ + vcache->elt_func = get_elt; + vcache->elt_ptr = elts; + vcache->output_prim = reduced_prim[prim]; + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i ++) { + vcache_point( vcache, + get_elt(elts, i) ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) { + vcache_line( vcache, + TRUE, + get_elt(elts, i + 0), + get_elt(elts, i + 1)); + } + break; + + case PIPE_PRIM_LINE_LOOP: + if (count >= 2) { + for (i = 1; i < count; i++) { + vcache_line( vcache, + i == 1, /* XXX: only if vb not split */ + get_elt(elts, i - 1), + get_elt(elts, i) ); + } + + vcache_line( vcache, + 0, + get_elt(elts, count - 1), + get_elt(elts, 0) ); + } + break; + + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < count; i++) { + vcache_line( vcache, + i == 1, + get_elt(elts, i - 1), + get_elt(elts, i) ); + } + break; + + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2) ); + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + for (i = 0; i+2 < count; i++) { + if (i & 1) { + vcache_triangle( vcache, + get_elt(elts, i + 1), + get_elt(elts, i + 0), + get_elt(elts, i + 2) ); + } + else { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + for (i = 0; i+2 < count; i++) { + vcache_triangle( vcache, + get_elt(elts, 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2) ); + } + break; + + + case PIPE_PRIM_QUADS: + for (i = 0; i+3 < count; i += 4) { + vcache_quad( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, i + 3)); + } + break; + + case PIPE_PRIM_QUAD_STRIP: + for (i = 0; i+3 < count; i += 2) { + vcache_quad( vcache, + get_elt(elts, i + 2), + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 3)); + } + break; + + case PIPE_PRIM_POLYGON: + for (i = 0; i+2 < count; i++) { + vcache_triangle( vcache, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0)); + } + break; + + default: + assert(0); + break; + } + + vcache_flush( vcache ); +} + +static void vcache_finish( struct draw_pt_front_end *frontend ) +{ + struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; + vcache->middle->finish( vcache->middle ); + vcache->middle = NULL; +} + +static void vcache_destroy( struct draw_pt_front_end *frontend ) +{ + FREE(frontend); +} + + +struct draw_pt_front_end *draw_pt_vcache( void ) +{ + struct vcache_frontend *vcache = CALLOC_STRUCT( vcache_frontend ); + + vcache->base.prepare = vcache_prepare; + vcache->base.run = vcache_run; + vcache->base.finish = vcache_finish; + vcache->base.destroy = vcache_destroy; + + memset(vcache->in, ~0, sizeof(vcache->in)); + + return &vcache->base; +} -- cgit v1.2.3 From 301b187ca9a811b608894d20bab934af0a10b8ab Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Mar 2008 18:21:00 +0000 Subject: draw: fix some unsigned vs ushort confusion Middle-end elements are ushort, but prior to that have to treat all elements as unsigned to avoid wrapping and/or overruns. --- src/gallium/auxiliary/draw/draw_pt.h | 2 +- src/gallium/auxiliary/draw/draw_pt_elts.c | 8 ++++---- src/gallium/auxiliary/draw/draw_pt_vcache.c | 9 ++++----- 3 files changed, 9 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 1b81d196f6..f56fa8d5cc 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -35,7 +35,7 @@ #include "pipe/p_compiler.h" -typedef ushort (*pt_elt_func)( const void *elts, ushort idx ); +typedef unsigned (*pt_elt_func)( const void *elts, unsigned idx ); /* The "front end" - prepare sets of fetch, draw elements for the diff --git a/src/gallium/auxiliary/draw/draw_pt_elts.c b/src/gallium/auxiliary/draw/draw_pt_elts.c index 585b83fa90..f337f71ea0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_elts.c +++ b/src/gallium/auxiliary/draw/draw_pt_elts.c @@ -37,22 +37,22 @@ * the start value into a pointer. */ -static ushort elt_uint( const void *elts, ushort idx ) +static unsigned elt_uint( const void *elts, unsigned idx ) { return *(((const uint *)elts) + idx); } -static ushort elt_ushort( const void *elts, ushort idx ) +static unsigned elt_ushort( const void *elts, unsigned idx ) { return *(((const ushort *)elts) + idx); } -static ushort elt_ubyte( const void *elts, ushort idx ) +static unsigned elt_ubyte( const void *elts, unsigned idx ) { return *(((const ubyte *)elts) + idx); } -static ushort elt_vert( const void *elts, ushort idx ) +static unsigned elt_vert( const void *elts, unsigned idx ) { return (const ubyte *)elts - (const ubyte *)NULL + idx; } diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 07e9f0ae5f..98c22eb4d4 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -45,7 +45,7 @@ struct vcache_frontend { struct draw_pt_front_end base; - ushort in[CACHE_MAX]; + unsigned in[CACHE_MAX]; ushort out[CACHE_MAX]; ushort draw_elts[DRAW_MAX]; @@ -74,13 +74,14 @@ static void vcache_flush( struct vcache_frontend *vcache ) } #endif - if (vcache->draw_count) + if (vcache->draw_count) { vcache->middle->run( vcache->middle, vcache->output_prim, vcache->fetch_elts, vcache->fetch_count, vcache->draw_elts, vcache->draw_count ); + } memset(vcache->in, ~0, sizeof(vcache->in)); vcache->fetch_count = 0; @@ -100,9 +101,7 @@ static void vcache_check_flush( struct vcache_frontend *vcache ) static void vcache_elt( struct vcache_frontend *vcache, unsigned felt ) { - // ushort felt = elt(draw, i); - - ushort idx = felt % CACHE_MAX; + unsigned idx = felt % CACHE_MAX; if (vcache->in[idx] != felt) { assert(vcache->fetch_count < FETCH_MAX); -- cgit v1.2.3 From 312cbc5a5c7416745976c2281a9bbce6e3332965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 23 Mar 2008 18:30:53 +0000 Subject: gallium: wrap decls in extern "C" --- src/gallium/drivers/softpipe/sp_winsys.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h index fc372dba27..291825dfe2 100644 --- a/src/gallium/drivers/softpipe/sp_winsys.h +++ b/src/gallium/drivers/softpipe/sp_winsys.h @@ -37,6 +37,12 @@ #include "pipe/p_compiler.h" /* for boolean */ + +#ifdef __cplusplus +extern "C" { +#endif + + enum pipe_format; struct softpipe_winsys { @@ -60,4 +66,8 @@ struct pipe_screen * softpipe_create_screen(struct pipe_winsys *); +#ifdef __cplusplus +} +#endif + #endif /* SP_WINSYS_H */ -- cgit v1.2.3 From 732422f6708199d6655185b1a5daec86efe2f1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 23 Mar 2008 18:38:10 +0000 Subject: gallium: Memory debugging utilities. There are no known tools for windows kernel memory debugging, so this is a simple set of malloc etc wrappers. Enabled by default on win32 debug builds --- src/gallium/auxiliary/util/SConscript | 1 + src/gallium/auxiliary/util/p_debug_mem.c | 172 +++++++++++++++++++++++++++++++ src/gallium/include/pipe/p_debug.h | 23 +++++ src/gallium/include/pipe/p_util.h | 21 +++- 4 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 src/gallium/auxiliary/util/p_debug_mem.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index b44f2d5e39..9b3929eb2d 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -4,6 +4,7 @@ util = env.ConvenienceLibrary( target = 'util', source = [ 'p_debug.c', + 'p_debug_mem.c', 'p_tile.c', 'p_util.c', 'u_blit.c', diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c new file mode 100644 index 0000000000..56599dafa6 --- /dev/null +++ b/src/gallium/auxiliary/util/p_debug_mem.c @@ -0,0 +1,172 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Memory debugging. + * + * @author José Fonseca + */ + +#ifdef WIN32 +#include +#include +#else +#include +#include +#endif + +#include "pipe/p_debug.h" +#include "util/u_double_list.h" + + +#define DEBUG_MEMORY_MAGIC 0x6e34090aU + + +#if defined(WIN32) && !defined(WINCE) +#define real_malloc(_size) EngAllocMem(0, _size, 'D3AG') +#define real_free(_ptr) EngFreeMem(_ptr) +#else +#define real_malloc(_size) malloc(_size) +#define real_free(_ptr) free(_ptr) +#endif + + +struct debug_memory_header +{ + struct list_head head; + + unsigned long no; + const char *file; + unsigned line; + const char *function; + size_t size; + unsigned magic; +}; + +static struct list_head list = { &list, &list }; + +static unsigned long start_no = 0; +static unsigned long end_no = 0; + + +void * +debug_malloc(const char *file, unsigned line, const char *function, + size_t size) +{ + struct debug_memory_header *hdr; + + hdr = real_malloc(sizeof(*hdr) + size); + if(!hdr) + return NULL; + + hdr->no = end_no++; + hdr->file = file; + hdr->line = line; + hdr->function = function; + hdr->size = size; + hdr->magic = DEBUG_MEMORY_MAGIC; + + LIST_ADDTAIL(&hdr->head, &list); + + return (void *)((char *)hdr + sizeof(*hdr)); +} + +void +debug_free(const char *file, unsigned line, const char *function, + void *ptr) +{ + struct debug_memory_header *hdr; + + if(!ptr) + return; + + hdr = (struct debug_memory_header *)((char *)ptr - sizeof(*hdr)); + if(hdr->magic != DEBUG_MEMORY_MAGIC) { + debug_printf("%s:%u:%s: freeing bad or corrupted memory %p\n", + file, line, function, + ptr); + debug_assert(0); + return; + } + + LIST_DEL(&hdr->head); + hdr->magic = 0; + + real_free(hdr); +} + +void * +debug_calloc(const char *file, unsigned line, const char *function, + size_t count, size_t size ) +{ + void *ptr = debug_malloc( file, line, function, count * size ); + if( ptr ) + memset( ptr, 0, count * size ); + return ptr; +} + +void * +debug_realloc(const char *file, unsigned line, const char *function, + void *old_ptr, size_t old_size, size_t new_size ) +{ + void *new_ptr = NULL; + + if (new_size != 0) { + new_ptr = debug_malloc( file, line, function, new_size ); + + if( new_ptr && old_ptr ) + memcpy( new_ptr, old_ptr, old_size ); + } + + debug_free( file, line, function, old_ptr ); + return new_ptr; +} + +void +debug_memory_reset(void) +{ + start_no = end_no; +} + +void +debug_memory_report(void) +{ + struct list_head *entry; + + entry = list.prev; + for (; entry != &list; entry = entry->prev) { + struct debug_memory_header *hdr; + void *ptr; + hdr = LIST_ENTRY(struct debug_memory_header, entry, head); + ptr = (void *)((char *)hdr + sizeof(*hdr)); + if(hdr->no >= start_no) + debug_printf("%s:%u:%s: %u byte st %p not freed\n", + hdr->file, hdr->line, hdr->function, + hdr->size, ptr); + } +} diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 14f8056924..c549513b6f 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -225,6 +225,29 @@ debug_dump_flags(const struct debug_named_value *names, unsigned long value); +void * +debug_malloc(const char *file, unsigned line, const char *function, + size_t size); + +void +debug_free(const char *file, unsigned line, const char *function, + void *ptr); + +void * +debug_calloc(const char *file, unsigned line, const char *function, + size_t count, size_t size ); + +void * +debug_realloc(const char *file, unsigned line, const char *function, + void *old_ptr, size_t old_size, size_t new_size ); + +void +debug_memory_reset(void); + +void +debug_memory_report(void); + + #ifdef __cplusplus } #endif diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index c2e0f8c6a5..d3b2fa2950 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -39,6 +39,22 @@ extern "C" { #endif +#if defined(WIN32) && defined(DEBUG) /* memory debugging */ + +#include "p_debug.h" + +#define MALLOC( _size ) \ + debug_malloc( __FILE__, __LINE__, __FUNCTION__, _size ) +#define CALLOC( _count, _size ) \ + debug_calloc(__FILE__, __LINE__, __FUNCTION__, _count, _size ) +#define FREE( _ptr ) \ + debug_free( __FILE__, __LINE__, __FUNCTION__, _ptr ) +#define REALLOC( _ptr, _old_size, _size ) \ + debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _size ) +#define GETENV( X ) NULL + +#else + #ifdef WIN32 void * __stdcall @@ -104,7 +120,7 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define GETENV( X ) NULL -#else /* WIN32 */ +#else /* !WIN32 */ #define MALLOC( SIZE ) malloc( SIZE ) @@ -116,7 +132,8 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define GETENV( X ) getenv( X ) -#endif /* WIN32 */ +#endif /* !WIN32 */ +#endif /* !DEBUG */ #define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T)) -- cgit v1.2.3 From d09b92d7e48ecee898ed158353021b7b3b6bae85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 23 Mar 2008 18:52:37 +0000 Subject: gallium: Fix typo. --- src/gallium/auxiliary/util/p_debug_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c index 56599dafa6..c160afe5b7 100644 --- a/src/gallium/auxiliary/util/p_debug_mem.c +++ b/src/gallium/auxiliary/util/p_debug_mem.c @@ -165,7 +165,7 @@ debug_memory_report(void) hdr = LIST_ENTRY(struct debug_memory_header, entry, head); ptr = (void *)((char *)hdr + sizeof(*hdr)); if(hdr->no >= start_no) - debug_printf("%s:%u:%s: %u byte st %p not freed\n", + debug_printf("%s:%u:%s: %u bytes at %p not freed\n", hdr->file, hdr->line, hdr->function, hdr->size, ptr); } -- cgit v1.2.3 From 48ef11d308c395837c1685df6ab701a69507e8b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 23 Mar 2008 18:57:35 +0000 Subject: gallium: Remove the debug_mask_* stuff. Overcomplex and not much different from using a global variable... --- src/gallium/auxiliary/util/p_debug.c | 34 ------------------- src/gallium/include/pipe/p_debug.h | 64 ------------------------------------ 2 files changed, 98 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index c51e9e6a69..19ad3f4663 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -168,40 +168,6 @@ void debug_assert_fail(const char *expr, const char *file, unsigned line) } -#define DEBUG_MASK_TABLE_SIZE 256 - - -/** - * Mask hash table. - * - * For now we just take the lower bits of the key, and do no attempt to solve - * collisions. Use a proper hash table when we have dozens of drivers. - */ -static uint32_t debug_mask_table[DEBUG_MASK_TABLE_SIZE]; - - -void debug_mask_set(uint32_t uuid, uint32_t mask) -{ - unsigned hash = uuid & (DEBUG_MASK_TABLE_SIZE - 1); - debug_mask_table[hash] = mask; -} - - -uint32_t debug_mask_get(uint32_t uuid) -{ - unsigned hash = uuid & (DEBUG_MASK_TABLE_SIZE - 1); - return debug_mask_table[hash]; -} - - -void debug_mask_vprintf(uint32_t uuid, uint32_t what, const char *format, va_list ap) -{ - uint32_t mask = debug_mask_get(uuid); - if(mask & what) - debug_vprintf(format, ap); -} - - const char * debug_dump_enum(const struct debug_named_value *names, unsigned long value) diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index c549513b6f..15fc2006d5 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -103,70 +103,6 @@ void debug_assert_fail(const char *expr, const char *file, unsigned line); #define assert(expr) debug_assert(expr) -/** - * Set a channel's debug mask. - * - * uuid is just a random 32 bit integer that uniquely identifies the debugging - * channel. - * - * @note Due to current implementation issues, make sure the lower 8 bits of - * UUID are unique. - */ -void debug_mask_set(uint32_t uuid, uint32_t mask); - - -uint32_t debug_mask_get(uint32_t uuid); - - -/** - * Conditional debug output. - * - * This is just a generalization of the debug filtering mechanism used - * throughout Gallium. - * - * You use this function as: - * - * @code - * #define MYDRIVER_UUID 0x12345678 // random 32 bit identifier - * - * static void inline - * mydriver_debug(uint32_t what, const char *format, ...) - * { - * #ifdef DEBUG - * va_list ap; - * va_start(ap, format); - * debug_mask_vprintf(MYDRIVER_UUID, what, format, ap); - * va_end(ap); - * #endif - * } - * - * ... - * - * debug_mask_set(MYDRIVER_UUID, - * MYDRIVER_DEBUG_THIS | - * MYDRIVER_DEBUG_THAT | - * ... ); - * - * ... - * - * mydriver_debug(MYDRIVER_DEBUG_THIS, - * "this and this happened\n"); - * - * mydriver_debug(MYDRIVER_DEBUG_THAT, - * "that = %f\n", that); - * ... - * @endcode - * - * You can also define several variants of mydriver_debug, with hardcoded what. - * Note that although macros with variable number of arguments would accomplish - * more in less code, they are not portable. - */ -void debug_mask_vprintf(uint32_t uuid, - uint32_t what, - const char *format, - va_list ap); - - #ifdef DEBUG #define debug_warning(__msg) \ debug_printf("%s:%i:warning: %s\n", __FILE__, __LINE__, (__msg)) -- cgit v1.2.3 From 38dc0f809d5f72b382676be6f72ea675a3929455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 23 Mar 2008 19:38:11 +0000 Subject: gallium: Fix memory leak. pipe cso's were being destroyed, but the hash elements themselves not. proper fix is IMHO add a destructor callback to cso_hash. --- src/gallium/auxiliary/cso_cache/cso_cache.c | 41 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index a2764b4265..18acab0967 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -29,6 +29,7 @@ */ #include "pipe/p_util.h" +#include "pipe/p_debug.h" #include "cso_cache.h" #include "cso_hash.h" @@ -131,75 +132,77 @@ static int _cso_size_for_type(enum cso_cache_type type) static void delete_blend_state(void *state, void *data) { struct cso_blend *cso = (struct cso_blend *)state; - if (cso->delete_state && cso->data != &cso->state) + if (cso->delete_state) cso->delete_state(cso->context, cso->data); + FREE(state); } static void delete_depth_stencil_state(void *state, void *data) { struct cso_depth_stencil_alpha *cso = (struct cso_depth_stencil_alpha *)state; - if (cso->delete_state && cso->data != &cso->state) + if (cso->delete_state) cso->delete_state(cso->context, cso->data); + FREE(state); } static void delete_sampler_state(void *state, void *data) { struct cso_sampler *cso = (struct cso_sampler *)state; - if (cso->delete_state && cso->data != &cso->state) + if (cso->delete_state) cso->delete_state(cso->context, cso->data); + FREE(state); } static void delete_rasterizer_state(void *state, void *data) { struct cso_rasterizer *cso = (struct cso_rasterizer *)state; - if (cso->delete_state && cso->data != &cso->state) + if (cso->delete_state) cso->delete_state(cso->context, cso->data); + FREE(state); } static void delete_fs_state(void *state, void *data) { struct cso_fragment_shader *cso = (struct cso_fragment_shader *)state; - if (cso->delete_state && cso->data != &cso->state) + if (cso->delete_state) cso->delete_state(cso->context, cso->data); + FREE(state); } static void delete_vs_state(void *state, void *data) { struct cso_vertex_shader *cso = (struct cso_vertex_shader *)state; - if (cso->delete_state && cso->data != &cso->state) + if (cso->delete_state) cso->delete_state(cso->context, cso->data); + FREE(state); } static INLINE void delete_cso(void *state, enum cso_cache_type type) { switch (type) { - case CSO_BLEND: { + case CSO_BLEND: delete_blend_state(state, 0); - } break; - case CSO_SAMPLER: { + case CSO_SAMPLER: delete_sampler_state(state, 0); - } break; - case CSO_DEPTH_STENCIL_ALPHA: { + case CSO_DEPTH_STENCIL_ALPHA: delete_depth_stencil_state(state, 0); - } break; - case CSO_RASTERIZER: { + case CSO_RASTERIZER: delete_rasterizer_state(state, 0); - } break; - case CSO_FRAGMENT_SHADER: { + case CSO_FRAGMENT_SHADER: delete_fs_state(state, 0); - } break; - case CSO_VERTEX_SHADER: { + case CSO_VERTEX_SHADER: delete_vs_state(state, 0); - } break; + default: + assert(0); + FREE(state); } - FREE(state); } static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type, -- cgit v1.2.3 From 6edaef531806f4ac6c92c4a2934da5a37262e2e3 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 23 Mar 2008 20:39:35 +0100 Subject: gallium: Add util_gen_mipmap_filter(). We need a way to specify the type of minification filter used to downsample mipmap levels. The old util_gen_mipmap() retains its behaviour and uses LINEAR filter. --- src/gallium/auxiliary/util/u_gen_mipmap.c | 27 +++++++++++++++++++++++---- src/gallium/auxiliary/util/u_gen_mipmap.h | 5 +++++ 2 files changed, 28 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index cf02f00b1b..9203a78191 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -719,7 +719,6 @@ util_create_gen_mipmap(struct pipe_context *pipe, ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; - ctx->sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; ctx->sampler.normalized_coords = 1; @@ -849,11 +848,12 @@ simple_viewport(struct pipe_context *pipe, uint width, uint height) * \param face which cube face to generate mipmaps for (0 for non-cube maps) * \param baseLevel the first mipmap level to use as a src * \param lastLevel the last mipmap level to generate + * \param filter the minification filter used to generate mipmap levels with */ void -util_gen_mipmap(struct gen_mipmap_state *ctx, - struct pipe_texture *pt, - uint face, uint baseLevel, uint lastLevel) +util_gen_mipmap_filter(struct gen_mipmap_state *ctx, + struct pipe_texture *pt, + uint face, uint baseLevel, uint lastLevel, uint filter) { struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; @@ -914,6 +914,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, */ ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel; ctx->sampler.lod_bias = (float) srcLevel; + ctx->sampler.min_img_filter = filter; cso_single_sampler(ctx->cso, 0, &ctx->sampler); cso_single_sampler_done(ctx->cso); #if 0 @@ -945,3 +946,21 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_sampler_textures(ctx->cso); cso_restore_framebuffer(ctx->cso); } + + +/** + * Generate mipmap images with a linear minification filter. + * See util_gen_mipmap_filter for more info. + * + * \param pt the texture to generate mipmap levels for + * \param face which cube face to generate mipmaps for (0 for non-cube maps) + * \param baseLevel the first mipmap level to use as a src + * \param lastLevel the last mipmap level to generate + */ +void +util_gen_mipmap(struct gen_mipmap_state *ctx, + struct pipe_texture *pt, + uint face, uint baseLevel, uint lastLevel) +{ + util_gen_mipmap_filter( ctx, pt, face, baseLevel, lastLevel, PIPE_TEX_FILTER_LINEAR ); +} diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h index eeabf3bf07..64abdeae98 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.h +++ b/src/gallium/auxiliary/util/u_gen_mipmap.h @@ -52,5 +52,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, struct pipe_texture *pt, uint face, uint baseLevel, uint lastLevel); +extern void +util_gen_mipmap_filter(struct gen_mipmap_state *ctx, + struct pipe_texture *pt, + uint face, uint baseLevel, uint lastLevel, uint filter); + #endif -- cgit v1.2.3 From 899fcde366646a3ab3e42ae819620e790161ac75 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Mar 2008 20:36:00 +0000 Subject: draw: restructure fetch/emit as a pair of function calls --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 261 ++++++++++++++---------- 1 file changed, 152 insertions(+), 109 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 74a946545a..f43483f883 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -76,8 +76,8 @@ struct fetch_emit_middle_end { struct { const ubyte *ptr; unsigned pitch; - enum pipe_format src_format; - unsigned dst_format; + void (*fetch)( const void *from, float *attrib); + void (*emit)( const float *attrib, float **out ); } fetch[PIPE_ATTRIB_MAX]; unsigned nr_fetch; @@ -85,6 +85,98 @@ struct fetch_emit_middle_end { }; +static void fetch_B8G8R8A8_UNORM( const void *from, + float *attrib ) +{ + ubyte *ub = (ubyte *) from; + attrib[2] = UBYTE_TO_FLOAT(ub[0]); + attrib[1] = UBYTE_TO_FLOAT(ub[1]); + attrib[0] = UBYTE_TO_FLOAT(ub[2]); + attrib[3] = UBYTE_TO_FLOAT(ub[3]); +} + +static void fetch_R32G32B32A32_FLOAT( const void *from, + float *attrib ) +{ + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = f[1]; + attrib[2] = f[2]; + attrib[3] = f[3]; +} + +static void fetch_R32G32B32_FLOAT( const void *from, + float *attrib ) +{ + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = f[1]; + attrib[2] = f[2]; + attrib[3] = 1.0; +} + +static void fetch_R32G32_FLOAT( const void *from, + float *attrib ) +{ + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = f[1]; + attrib[2] = 0.0; + attrib[3] = 1.0; +} + +static void fetch_R32_FLOAT( const void *from, + float *attrib ) +{ + float *f = (float *) from; + attrib[0] = f[0]; + attrib[1] = 0.0; + attrib[2] = 0.0; + attrib[3] = 1.0; +} + +static void fetch_HEADER( const void *from, + float *attrib ) +{ + attrib[0] = 0; +} + + +static void emit_1F( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out) += 1; +} + +static void emit_2F( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out) += 2; +} + +static void emit_3F( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out)[2] = attrib[2]; + (*out) += 3; +} + +static void emit_4F( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out)[2] = attrib[2]; + (*out)[3] = attrib[3]; + (*out) += 4; +} + + /** * General-purpose fetch from user's vertex arrays, emit to driver's * vertex buffer. @@ -109,81 +201,8 @@ fetch_store_general( struct fetch_emit_middle_end *feme, const ubyte *from = (feme->fetch[j].ptr + feme->fetch[j].pitch * elt); - /* The normal fetch/emit code: - */ - switch (feme->fetch[j].src_format) { - case PIPE_FORMAT_B8G8R8A8_UNORM: - { - ubyte *ub = (ubyte *) from; - attrib[2] = UBYTE_TO_FLOAT(ub[0]); - attrib[1] = UBYTE_TO_FLOAT(ub[1]); - attrib[0] = UBYTE_TO_FLOAT(ub[2]); - attrib[3] = UBYTE_TO_FLOAT(ub[3]); - } - break; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - { - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = f[2]; - attrib[3] = f[3]; - } - break; - case PIPE_FORMAT_R32G32B32_FLOAT: - { - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = f[2]; - attrib[3] = 1.0; - } - break; - case PIPE_FORMAT_R32G32_FLOAT: - { - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = 0.0; - attrib[3] = 1.0; - } - break; - case PIPE_FORMAT_R32_FLOAT: - { - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = 0.0; - attrib[2] = 0.0; - attrib[3] = 1.0; - } - break; - default: - assert(0); - } - - if (0) debug_printf("attrib %d: %f %f %f %f\n", j, - attrib[0], attrib[1], attrib[2], attrib[3]); - - switch (feme->fetch[j].dst_format) { - case EMIT_1F: - out[0] = attrib[0]; - out += 1; - break; - case EMIT_2F: - out[0] = attrib[0]; - out[1] = attrib[1]; - out += 2; - break; - case EMIT_4F: - out[0] = attrib[0]; - out[1] = attrib[1]; - out[2] = attrib[2]; - out[3] = attrib[3]; - out += 4; - break; - default: - assert(0); - } + feme->fetch[j].fetch( from, attrib ); + feme->fetch[j].emit( attrib, &out ); } } } @@ -199,44 +218,68 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle ) unsigned i; for (i = 0; i < nr_attrs; i++) { - enum pipe_format src_format; - unsigned dst_format; - const void *src_ptr; - unsigned pitch; + unsigned src_element = vinfo->src_index[i]; + unsigned src_buffer = draw->vertex_element[src_element].vertex_buffer_index; + + feme->fetch[i].ptr = ((const ubyte *)draw->user.vbuffer[src_buffer] + + draw->vertex_buffer[src_buffer].buffer_offset + + draw->vertex_element[src_element].src_offset); - if (vinfo->emit[i] == EMIT_HEADER) { - static const unsigned zero = 0; - src_ptr = &zero; - src_format = PIPE_FORMAT_R32_FLOAT; - pitch = 0; - dst_format = EMIT_1F; - } - else if (vinfo->emit[i] == EMIT_1F_PSIZE) { - src_ptr = &feme->draw->rasterizer->point_size; - src_format = PIPE_FORMAT_R32_FLOAT; - pitch = 0; - dst_format = EMIT_1F; + feme->fetch[i].pitch = draw->vertex_buffer[src_buffer].pitch; + + switch (draw->vertex_element[src_element].src_format) { + case PIPE_FORMAT_B8G8R8A8_UNORM: + feme->fetch[i].fetch = fetch_B8G8R8A8_UNORM; + break; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + feme->fetch[i].fetch = fetch_R32G32B32A32_FLOAT; + break; + case PIPE_FORMAT_R32G32B32_FLOAT: + feme->fetch[i].fetch = fetch_R32G32B32_FLOAT; + break; + case PIPE_FORMAT_R32G32_FLOAT: + feme->fetch[i].fetch = fetch_R32G32_FLOAT; + break; + case PIPE_FORMAT_R32_FLOAT: + feme->fetch[i].fetch = fetch_R32_FLOAT; + break; + default: + assert(0); + feme->fetch[i].fetch = NULL; + break; } - else { - unsigned src_element = vinfo->src_index[i]; - unsigned src_buffer = draw->vertex_element[src_element].vertex_buffer_index; - src_ptr = ((const ubyte *)draw->user.vbuffer[src_buffer] + - draw->vertex_buffer[src_buffer].buffer_offset + - draw->vertex_element[src_element].src_offset); - - src_format = draw->vertex_element[src_element].src_format; - pitch = draw->vertex_buffer[src_buffer].pitch; - dst_format = vinfo->emit[i]; + switch (vinfo->emit[i]) { + case EMIT_4F: + feme->fetch[i].emit = emit_4F; + break; + case EMIT_3F: + feme->fetch[i].emit = emit_3F; + break; + case EMIT_2F: + feme->fetch[i].emit = emit_2F; + break; + case EMIT_1F: + feme->fetch[i].emit = emit_1F; + break; + case EMIT_HEADER: + feme->fetch[i].ptr = NULL; + feme->fetch[i].pitch = 0; + feme->fetch[i].fetch = fetch_HEADER; + feme->fetch[i].emit = emit_1F; + break; + case EMIT_1F_PSIZE: + feme->fetch[i].ptr = (const ubyte *)&feme->draw->rasterizer->point_size; + feme->fetch[i].pitch = 0; + feme->fetch[i].fetch = fetch_R32_FLOAT; + feme->fetch[i].emit = emit_1F; + default: + assert(0); + feme->fetch[i].emit = NULL; + break; } - - feme->fetch[i].src_format = src_format; - feme->fetch[i].ptr = src_ptr; - feme->fetch[i].pitch = pitch; - feme->fetch[i].dst_format = dst_format; } - feme->nr_fetch = nr_attrs; feme->hw_vertex_size = vinfo->size * 4; } -- cgit v1.2.3 From 743e990831d74ff764f4677836b7bd9b044d39af Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Mar 2008 21:31:14 +0000 Subject: draw: rename emit functions to match pipe_format names --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 39 +++++++++++-------------- 1 file changed, 17 insertions(+), 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index f43483f883..64ef83d800 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -135,30 +135,24 @@ static void fetch_R32_FLOAT( const void *from, attrib[3] = 1.0; } -static void fetch_HEADER( const void *from, - float *attrib ) -{ - attrib[0] = 0; -} - -static void emit_1F( const float *attrib, - float **out ) +static void emit_R32_FLOAT( const float *attrib, + float **out ) { (*out)[0] = attrib[0]; (*out) += 1; } -static void emit_2F( const float *attrib, - float **out ) +static void emit_R32G32_FLOAT( const float *attrib, + float **out ) { (*out)[0] = attrib[0]; (*out)[1] = attrib[1]; (*out) += 2; } -static void emit_3F( const float *attrib, - float **out ) +static void emit_R32G32B32_FLOAT( const float *attrib, + float **out ) { (*out)[0] = attrib[0]; (*out)[1] = attrib[1]; @@ -166,8 +160,8 @@ static void emit_3F( const float *attrib, (*out) += 3; } -static void emit_4F( const float *attrib, - float **out ) +static void emit_R32G32B32A32_FLOAT( const float *attrib, + float **out ) { (*out)[0] = attrib[0]; (*out)[1] = attrib[1]; @@ -211,6 +205,7 @@ fetch_store_general( struct fetch_emit_middle_end *feme, static void fetch_emit_prepare( struct draw_pt_middle_end *middle ) { + static const float zero = 0; struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); @@ -251,28 +246,28 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle ) switch (vinfo->emit[i]) { case EMIT_4F: - feme->fetch[i].emit = emit_4F; + feme->fetch[i].emit = emit_R32G32B32A32_FLOAT; break; case EMIT_3F: - feme->fetch[i].emit = emit_3F; + feme->fetch[i].emit = emit_R32G32B32_FLOAT; break; case EMIT_2F: - feme->fetch[i].emit = emit_2F; + feme->fetch[i].emit = emit_R32G32_FLOAT; break; case EMIT_1F: - feme->fetch[i].emit = emit_1F; + feme->fetch[i].emit = emit_R32_FLOAT; break; case EMIT_HEADER: - feme->fetch[i].ptr = NULL; + feme->fetch[i].ptr = (const ubyte *)&zero; feme->fetch[i].pitch = 0; - feme->fetch[i].fetch = fetch_HEADER; - feme->fetch[i].emit = emit_1F; + feme->fetch[i].fetch = fetch_R32_FLOAT; + feme->fetch[i].emit = emit_R32_FLOAT; break; case EMIT_1F_PSIZE: feme->fetch[i].ptr = (const ubyte *)&feme->draw->rasterizer->point_size; feme->fetch[i].pitch = 0; feme->fetch[i].fetch = fetch_R32_FLOAT; - feme->fetch[i].emit = emit_1F; + feme->fetch[i].emit = emit_R32_FLOAT; default: assert(0); feme->fetch[i].emit = NULL; -- cgit v1.2.3 From e6ea786c003762143fdf4c63a6fc6a08f27e444e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Mar 2008 21:31:23 +0000 Subject: draw: fix crlf --- src/gallium/auxiliary/draw/draw_pt.h | 232 +++++++++++++++--------------- src/gallium/auxiliary/draw/draw_pt_elts.c | 176 +++++++++++------------ 2 files changed, 204 insertions(+), 204 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index f56fa8d5cc..dfc29b2e7d 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -1,116 +1,116 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#ifndef DRAW_PT_H -#define DRAW_PT_H - -#include "pipe/p_compiler.h" - -typedef unsigned (*pt_elt_func)( const void *elts, unsigned idx ); - - -/* The "front end" - prepare sets of fetch, draw elements for the - * middle end. - * - * Currenly one version of this: - * - vcache - catchall implementation, decomposes to TRI/LINE/POINT prims - * Later: - * - varray, varray_split - * - velement, velement_split - * - * Currenly only using the vcache version. - */ -struct draw_pt_front_end { - void (*prepare)( struct draw_pt_front_end *, - struct draw_pt_middle_end * ); - - void (*run)( struct draw_pt_front_end *, - unsigned prim, - pt_elt_func elt_func, - const void *elt_ptr, - unsigned count ); - - void (*finish)( struct draw_pt_front_end * ); - void (*destroy)( struct draw_pt_front_end * ); -}; - - -/* The "middle end" - prepares actual hardware vertices for the - * hardware backend. - * - * Currently two versions of this: - * - fetch, vertex shade, cliptest, prim-pipeline - * - fetch, emit (ie passthrough) - * Later: - * - fetch, vertex shade, cliptest, maybe-pipeline, maybe-emit - * - fetch, vertex shade, emit - * - * Currenly only using the passthrough version. - */ -struct draw_pt_middle_end { - void (*prepare)( struct draw_pt_middle_end * ); - - void (*run)( struct draw_pt_middle_end *, - unsigned prim, - const unsigned *fetch_elts, - unsigned fetch_count, - const ushort *draw_elts, - unsigned draw_count ); - - void (*finish)( struct draw_pt_middle_end * ); - void (*destroy)( struct draw_pt_middle_end * ); -}; - - -/* The "back end" - supplied by the driver, defined in draw_vbuf.h. - * - * Not sure whether to wrap the prim pipeline up as an alternate - * backend. Would be a win for everything except pure passthrough - * mode... - */ -struct vbuf_render; - - -/* Helper functions. - */ -pt_elt_func draw_pt_elt_func( struct draw_context *draw ); -const void *draw_pt_elt_ptr( struct draw_context *draw, - unsigned start ); - -/* Implementations: - */ -struct draw_pt_front_end *draw_pt_vcache( void ); -struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ); - - - -#endif +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#ifndef DRAW_PT_H +#define DRAW_PT_H + +#include "pipe/p_compiler.h" + +typedef unsigned (*pt_elt_func)( const void *elts, unsigned idx ); + + +/* The "front end" - prepare sets of fetch, draw elements for the + * middle end. + * + * Currenly one version of this: + * - vcache - catchall implementation, decomposes to TRI/LINE/POINT prims + * Later: + * - varray, varray_split + * - velement, velement_split + * + * Currenly only using the vcache version. + */ +struct draw_pt_front_end { + void (*prepare)( struct draw_pt_front_end *, + struct draw_pt_middle_end * ); + + void (*run)( struct draw_pt_front_end *, + unsigned prim, + pt_elt_func elt_func, + const void *elt_ptr, + unsigned count ); + + void (*finish)( struct draw_pt_front_end * ); + void (*destroy)( struct draw_pt_front_end * ); +}; + + +/* The "middle end" - prepares actual hardware vertices for the + * hardware backend. + * + * Currently two versions of this: + * - fetch, vertex shade, cliptest, prim-pipeline + * - fetch, emit (ie passthrough) + * Later: + * - fetch, vertex shade, cliptest, maybe-pipeline, maybe-emit + * - fetch, vertex shade, emit + * + * Currenly only using the passthrough version. + */ +struct draw_pt_middle_end { + void (*prepare)( struct draw_pt_middle_end * ); + + void (*run)( struct draw_pt_middle_end *, + unsigned prim, + const unsigned *fetch_elts, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ); + + void (*finish)( struct draw_pt_middle_end * ); + void (*destroy)( struct draw_pt_middle_end * ); +}; + + +/* The "back end" - supplied by the driver, defined in draw_vbuf.h. + * + * Not sure whether to wrap the prim pipeline up as an alternate + * backend. Would be a win for everything except pure passthrough + * mode... + */ +struct vbuf_render; + + +/* Helper functions. + */ +pt_elt_func draw_pt_elt_func( struct draw_context *draw ); +const void *draw_pt_elt_ptr( struct draw_context *draw, + unsigned start ); + +/* Implementations: + */ +struct draw_pt_front_end *draw_pt_vcache( void ); +struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ); + + + +#endif diff --git a/src/gallium/auxiliary/draw/draw_pt_elts.c b/src/gallium/auxiliary/draw/draw_pt_elts.c index f337f71ea0..d49770e7b2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_elts.c +++ b/src/gallium/auxiliary/draw/draw_pt_elts.c @@ -1,88 +1,88 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#include "draw/draw_pt.h" -#include "draw/draw_private.h" - -/* Neat get_elt func that also works for varrays drawing by encoding - * the start value into a pointer. - */ - -static unsigned elt_uint( const void *elts, unsigned idx ) -{ - return *(((const uint *)elts) + idx); -} - -static unsigned elt_ushort( const void *elts, unsigned idx ) -{ - return *(((const ushort *)elts) + idx); -} - -static unsigned elt_ubyte( const void *elts, unsigned idx ) -{ - return *(((const ubyte *)elts) + idx); -} - -static unsigned elt_vert( const void *elts, unsigned idx ) -{ - return (const ubyte *)elts - (const ubyte *)NULL + idx; -} - -pt_elt_func draw_pt_elt_func( struct draw_context *draw ) -{ - switch (draw->user.eltSize) { - case 0: return elt_vert; - case 1: return elt_ubyte; - case 2: return elt_ushort; - case 4: return elt_uint; - default: return NULL; - } -} - -const void *draw_pt_elt_ptr( struct draw_context *draw, - unsigned start ) -{ - const char *elts = draw->user.elts; - - switch (draw->user.eltSize) { - case 0: - return (const void *)(((const ubyte *)NULL) + start); - case 1: - return (const void *)(((const ubyte *)elts) + start); - case 2: - return (const void *)(((const ushort *)elts) + start); - case 4: - return (const void *)(((const uint *)elts) + start); - default: - return NULL; - } -} +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "draw/draw_pt.h" +#include "draw/draw_private.h" + +/* Neat get_elt func that also works for varrays drawing by encoding + * the start value into a pointer. + */ + +static unsigned elt_uint( const void *elts, unsigned idx ) +{ + return *(((const uint *)elts) + idx); +} + +static unsigned elt_ushort( const void *elts, unsigned idx ) +{ + return *(((const ushort *)elts) + idx); +} + +static unsigned elt_ubyte( const void *elts, unsigned idx ) +{ + return *(((const ubyte *)elts) + idx); +} + +static unsigned elt_vert( const void *elts, unsigned idx ) +{ + return (const ubyte *)elts - (const ubyte *)NULL + idx; +} + +pt_elt_func draw_pt_elt_func( struct draw_context *draw ) +{ + switch (draw->user.eltSize) { + case 0: return elt_vert; + case 1: return elt_ubyte; + case 2: return elt_ushort; + case 4: return elt_uint; + default: return NULL; + } +} + +const void *draw_pt_elt_ptr( struct draw_context *draw, + unsigned start ) +{ + const char *elts = draw->user.elts; + + switch (draw->user.eltSize) { + case 0: + return (const void *)(((const ubyte *)NULL) + start); + case 1: + return (const void *)(((const ubyte *)elts) + start); + case 2: + return (const void *)(((const ushort *)elts) + start); + case 4: + return (const void *)(((const uint *)elts) + start); + default: + return NULL; + } +} -- cgit v1.2.3 From 3e9b1bc1009ca1a2923f844d00bf478dc9d24644 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Mar 2008 21:54:44 +0000 Subject: draw: tweak the definition of draw_need_pipeline, fix minor bug --- src/gallium/auxiliary/draw/draw_validate.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index 33e5559508..70b477ba5c 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -34,20 +34,14 @@ /** - * Check if we need any special pipeline stages, or whether prims/verts - * can go through untouched. + * Check if we need any special pipeline stages, or whether + * prims/verts can go through untouched. Don't test for bypass + * clipping or vs modes, this function is just about the primitive + * pipeline stages. */ boolean draw_need_pipeline(const struct draw_context *draw) { - /* clipping */ - if (!draw->rasterizer->bypass_clipping) - return TRUE; - - /* vertex shader */ - if (!draw->rasterizer->bypass_vs) - return TRUE; - /* line stipple */ if (draw->rasterizer->line_stipple_enable && draw->line_stipple) return TRUE; @@ -72,6 +66,11 @@ draw_need_pipeline(const struct draw_context *draw) if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple) return TRUE; + /* unfilled polygons */ + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) + return TRUE; + /* polygon offset */ if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw) return TRUE; @@ -84,9 +83,14 @@ draw_need_pipeline(const struct draw_context *draw) if (draw->rasterizer->light_twoside) return TRUE; - /* polygon cull */ + /* polygon cull - this is difficult - hardware can cull just fine + * most of the time (though sometimes CULL_NEITHER is unsupported. + * + * Generally this isn't a reason to require the pipeline, though. + * if (draw->rasterizer->cull_mode) return TRUE; + */ return FALSE; } -- cgit v1.2.3 From 3b217c7fa77d397540e4b6299a35f586ad53a1a1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 23 Mar 2008 21:55:19 +0000 Subject: draw: check need_pipeline() in passthrough --- src/gallium/auxiliary/draw/draw_pt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 219b563422..d7169f78f4 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -114,7 +114,7 @@ draw_pt_arrays(struct draw_context *draw, middle = draw->pt.middle.fetch_shade_cliptest_pipeline; } #else - if (cliptest /*|| pipeline*/ || shading) + if (cliptest || pipeline || shading) return FALSE; middle = draw->pt.middle.fetch_emit; -- cgit v1.2.3 From a6d17bf671d6bfbb187a62ba14b9ad08fb5dafe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 24 Mar 2008 09:56:12 +0000 Subject: draw: Fix #include order to fix Linux build. --- src/gallium/auxiliary/draw/draw_pt_elts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_elts.c b/src/gallium/auxiliary/draw/draw_pt_elts.c index d49770e7b2..02fb6d9f41 100644 --- a/src/gallium/auxiliary/draw/draw_pt_elts.c +++ b/src/gallium/auxiliary/draw/draw_pt_elts.c @@ -30,8 +30,8 @@ * Keith Whitwell */ -#include "draw/draw_pt.h" #include "draw/draw_private.h" +#include "draw/draw_pt.h" /* Neat get_elt func that also works for varrays drawing by encoding * the start value into a pointer. -- cgit v1.2.3 From f4588c175280cd2b1f5341cd02bed7e9e7d1fd05 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 24 Mar 2008 10:52:20 +0000 Subject: Revert "draw: Fix #include order to fix Linux build." This reverts commit a6d17bf671d6bfbb187a62ba14b9ad08fb5dafe1. --- src/gallium/auxiliary/draw/draw_pt_elts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_elts.c b/src/gallium/auxiliary/draw/draw_pt_elts.c index 02fb6d9f41..d49770e7b2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_elts.c +++ b/src/gallium/auxiliary/draw/draw_pt_elts.c @@ -30,8 +30,8 @@ * Keith Whitwell */ -#include "draw/draw_private.h" #include "draw/draw_pt.h" +#include "draw/draw_private.h" /* Neat get_elt func that also works for varrays drawing by encoding * the start value into a pointer. -- cgit v1.2.3 From e0a9ce10f4c30b1aec08c46b6a33885782d40dd0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 24 Mar 2008 10:53:26 +0000 Subject: draw: pre-declare referenced structs --- src/gallium/auxiliary/draw/draw_pt.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index dfc29b2e7d..439fa4c881 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -37,6 +37,8 @@ typedef unsigned (*pt_elt_func)( const void *elts, unsigned idx ); +struct draw_pt_middle_end; +struct draw_context; /* The "front end" - prepare sets of fetch, draw elements for the * middle end. -- cgit v1.2.3 From c8c373514a18d31181cfaeefc23cd06eab3fddd0 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 24 Mar 2008 08:09:34 -0600 Subject: gallium: tweak coords in u_gen_mipmap code --- src/gallium/auxiliary/util/u_gen_mipmap.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 9203a78191..13e4531d4a 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -773,23 +773,23 @@ set_vertex_data(struct gen_mipmap_state *ctx, float width, float height) { void *buf; - ctx->vertices[0][0][0] = 0.0f; /*x*/ - ctx->vertices[0][0][1] = 0.0f; /*y*/ + ctx->vertices[0][0][0] = -0.5f; /*x*/ + ctx->vertices[0][0][1] = -0.5f; /*y*/ ctx->vertices[0][1][0] = 0.0f; /*s*/ ctx->vertices[0][1][1] = 0.0f; /*t*/ - ctx->vertices[1][0][0] = width; /*x*/ - ctx->vertices[1][0][1] = 0.0f; /*y*/ + ctx->vertices[1][0][0] = width - 0.5f; /*x*/ + ctx->vertices[1][0][1] = -0.5f; /*y*/ ctx->vertices[1][1][0] = 1.0f; /*s*/ ctx->vertices[1][1][1] = 0.0f; /*t*/ - ctx->vertices[2][0][0] = width; - ctx->vertices[2][0][1] = height; + ctx->vertices[2][0][0] = width - 0.5f; + ctx->vertices[2][0][1] = height - 0.5f; ctx->vertices[2][1][0] = 1.0f; ctx->vertices[2][1][1] = 1.0f; - ctx->vertices[3][0][0] = 0.0f; - ctx->vertices[3][0][1] = height; + ctx->vertices[3][0][0] = -0.5f; + ctx->vertices[3][0][1] = height - 0.5f; ctx->vertices[3][1][0] = 0.0f; ctx->vertices[3][1][1] = 1.0f; -- cgit v1.2.3 From 110b63d00fa0a555a00f5b1560452323517eafe1 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 24 Mar 2008 08:53:16 -0600 Subject: gallium: pass the filter mode to util_gen_mipmap(). Remove util_gen_mipmap_filter() when no longer used. --- src/gallium/auxiliary/util/u_gen_mipmap.c | 25 ++++++++++--------------- src/gallium/auxiliary/util/u_gen_mipmap.h | 2 +- 2 files changed, 11 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 13e4531d4a..26df5f29f8 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -719,7 +719,6 @@ util_create_gen_mipmap(struct pipe_context *pipe, ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; - ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; ctx->sampler.normalized_coords = 1; @@ -849,11 +848,12 @@ simple_viewport(struct pipe_context *pipe, uint width, uint height) * \param baseLevel the first mipmap level to use as a src * \param lastLevel the last mipmap level to generate * \param filter the minification filter used to generate mipmap levels with + * \param filter one of PIPE_TEX_FILTER_LINEAR, PIPE_TEX_FILTER_NEAREST */ void -util_gen_mipmap_filter(struct gen_mipmap_state *ctx, - struct pipe_texture *pt, - uint face, uint baseLevel, uint lastLevel, uint filter) +util_gen_mipmap(struct gen_mipmap_state *ctx, + struct pipe_texture *pt, + uint face, uint baseLevel, uint lastLevel, uint filter) { struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; @@ -914,6 +914,7 @@ util_gen_mipmap_filter(struct gen_mipmap_state *ctx, */ ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel; ctx->sampler.lod_bias = (float) srcLevel; + ctx->sampler.mag_img_filter = filter; ctx->sampler.min_img_filter = filter; cso_single_sampler(ctx->cso, 0, &ctx->sampler); cso_single_sampler_done(ctx->cso); @@ -949,18 +950,12 @@ util_gen_mipmap_filter(struct gen_mipmap_state *ctx, /** - * Generate mipmap images with a linear minification filter. - * See util_gen_mipmap_filter for more info. - * - * \param pt the texture to generate mipmap levels for - * \param face which cube face to generate mipmaps for (0 for non-cube maps) - * \param baseLevel the first mipmap level to use as a src - * \param lastLevel the last mipmap level to generate + * XXX remove this */ void -util_gen_mipmap(struct gen_mipmap_state *ctx, - struct pipe_texture *pt, - uint face, uint baseLevel, uint lastLevel) +util_gen_mipmap_filter(struct gen_mipmap_state *ctx, + struct pipe_texture *pt, + uint face, uint baseLevel, uint lastLevel, uint filter) { - util_gen_mipmap_filter( ctx, pt, face, baseLevel, lastLevel, PIPE_TEX_FILTER_LINEAR ); + util_gen_mipmap_filter( ctx, pt, face, baseLevel, lastLevel, filter ); } diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h index 64abdeae98..a5df8481bf 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.h +++ b/src/gallium/auxiliary/util/u_gen_mipmap.h @@ -50,7 +50,7 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx); extern void util_gen_mipmap(struct gen_mipmap_state *ctx, struct pipe_texture *pt, - uint face, uint baseLevel, uint lastLevel); + uint face, uint baseLevel, uint lastLevel, uint filter); extern void util_gen_mipmap_filter(struct gen_mipmap_state *ctx, -- cgit v1.2.3 From bf8de6d4dc1f956b7e70be285ff0d983b1a8eb5b Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 24 Mar 2008 16:50:39 +0100 Subject: gallium: Remove util_gen_mipmap_filter(). --- src/gallium/auxiliary/util/u_gen_mipmap.c | 12 ------------ src/gallium/auxiliary/util/u_gen_mipmap.h | 6 ------ 2 files changed, 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 26df5f29f8..427b217755 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -947,15 +947,3 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_sampler_textures(ctx->cso); cso_restore_framebuffer(ctx->cso); } - - -/** - * XXX remove this - */ -void -util_gen_mipmap_filter(struct gen_mipmap_state *ctx, - struct pipe_texture *pt, - uint face, uint baseLevel, uint lastLevel, uint filter) -{ - util_gen_mipmap_filter( ctx, pt, face, baseLevel, lastLevel, filter ); -} diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h index a5df8481bf..bd9af54fb7 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.h +++ b/src/gallium/auxiliary/util/u_gen_mipmap.h @@ -52,10 +52,4 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, struct pipe_texture *pt, uint face, uint baseLevel, uint lastLevel, uint filter); -extern void -util_gen_mipmap_filter(struct gen_mipmap_state *ctx, - struct pipe_texture *pt, - uint face, uint baseLevel, uint lastLevel, uint filter); - - #endif -- cgit v1.2.3 From 48726e129a3727ec01e130835e74d62007093051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 24 Mar 2008 18:25:31 +0000 Subject: gallium: Protect operator precedence in macro. --- src/gallium/include/pipe/p_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index d3b2fa2950..283f7fb8f5 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -201,7 +201,7 @@ mem_dup(const void *src, uint size) #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) #define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) -#define Elements(x) sizeof(x)/sizeof(*(x)) +#define Elements(x) (sizeof(x)/sizeof((x)[0])) #define Offset(TYPE, MEMBER) ((unsigned)&(((TYPE *)NULL)->MEMBER)) /** -- cgit v1.2.3 From 4e398df6825f4b6d568f055b689e7d7043e2785e Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 24 Mar 2008 12:50:28 -0600 Subject: gallium: fix REALLOC() to copy smaller of old/new sizes --- src/gallium/include/pipe/p_util.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 283f7fb8f5..505626c60b 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -107,10 +107,10 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) void *new_ptr = NULL; if (new_size != 0) { + unsigned copy_size = old_size < new_size ? old_size : new_size; new_ptr = MALLOC( new_size ); - - if( new_ptr && old_ptr ) { - memcpy( new_ptr, old_ptr, old_size ); + if (new_ptr && old_ptr && copy_size) { + memcpy( new_ptr, old_ptr, copy_size ); } } -- cgit v1.2.3 From d83e75c75958673e8019475f5ba5c2cff9b8415f Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 24 Mar 2008 12:51:50 -0600 Subject: gallium: move filter assignment out of loop --- src/gallium/auxiliary/util/u_gen_mipmap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 427b217755..e129c062be 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -890,6 +890,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, memset(&fb, 0, sizeof(fb)); fb.num_cbufs = 1; + /* set min/mag to same filter for faster sw speed */ + ctx->sampler.mag_img_filter = filter; + ctx->sampler.min_img_filter = filter; + /* * XXX for small mipmap levels, it may be faster to use the software * fallback path... @@ -914,8 +918,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, */ ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel; ctx->sampler.lod_bias = (float) srcLevel; - ctx->sampler.mag_img_filter = filter; - ctx->sampler.min_img_filter = filter; cso_single_sampler(ctx->cso, 0, &ctx->sampler); cso_single_sampler_done(ctx->cso); #if 0 -- cgit v1.2.3 From dd51365acdd515577ee76850ceda01347ceb27c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 24 Mar 2008 20:18:59 +0000 Subject: gallium: cleanup p_debug Now debug_printf is disabled on release builds. Use debug_error or _debug_printf to output messages on release versions. --- src/gallium/auxiliary/util/p_debug.c | 31 ++++------ src/gallium/include/pipe/p_debug.h | 117 +++++++++++++++++++++++++++++++---- 2 files changed, 118 insertions(+), 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 19ad3f4663..bd58e0e3a8 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -58,7 +58,7 @@ int rpl_snprintf(char *str, size_t size, const char *format, ...); #endif -void debug_vprintf(const char *format, va_list ap) +void _debug_vprintf(const char *format, va_list ap) { #ifdef WIN32 #ifndef WINCE @@ -76,15 +76,7 @@ void debug_vprintf(const char *format, va_list ap) } -void debug_printf(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - debug_vprintf(format, ap); - va_end(ap); -} - - +#ifdef DEBUG void debug_print_blob( const char *name, const void *blob, unsigned size ) @@ -99,12 +91,10 @@ void debug_print_blob( const char *name, debug_printf("%d:\t%08x\n", i, ublob[i]); } } +#endif -/* TODO: implement a debug_abort that calls EngBugCheckEx on WIN32 */ - - -static INLINE void debug_break(void) +void _debug_break(void) { #if (defined(__i386__) || defined(__386__)) && defined(__GNUC__) __asm("int3"); @@ -155,15 +145,18 @@ static unsigned abort_en() } #endif -void debug_assert_fail(const char *expr, const char *file, unsigned line) +void _debug_assert_fail(const char *expr, + const char *file, + unsigned line, + const char *function) { - debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr); + _debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file, line, function, expr); if (abort_en()) { debug_break(); } else { - debug_printf("continuing...\n"); + _debug_printf("continuing...\n"); } } @@ -180,7 +173,7 @@ debug_dump_enum(const struct debug_named_value *names, ++names; } - snprintf(rest, sizeof(rest), "0x%08x", value); + snprintf(rest, sizeof(rest), "0x%08lx", value); return rest; } @@ -213,7 +206,7 @@ debug_dump_flags(const struct debug_named_value *names, else first = 0; - snprintf(rest, sizeof(rest), "0x%08x", value); + snprintf(rest, sizeof(rest), "0x%08lx", value); strncat(output, rest, sizeof(output)); } diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 15fc2006d5..494cc3bb71 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -60,58 +60,153 @@ extern "C" { #endif +void _debug_vprintf(const char *format, va_list ap); + + +static void INLINE +_debug_printf(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + _debug_vprintf(format, ap); + va_end(ap); +} + + /** * Print debug messages. * - * A debug message will be printed regardless of the DEBUG/NDEBUG macros. - * * The actual channel used to output debug message is platform specific. To * avoid misformating or truncation, follow these rules of thumb: * - output whole lines * - avoid outputing large strings (512 bytes is the current maximum length * that is guaranteed to be printed in all platforms) */ -void debug_printf(const char *format, ...); +static void INLINE +debug_printf(const char *format, ...) +{ +#ifdef DEBUG + va_list ap; + va_start(ap, format); + _debug_vprintf(format, ap); + va_end(ap); +#endif +} + +#ifdef DEBUG +#define debug_vprintf(_format, _ap) _debug_vprintf(_format, _ap) +#else +#define debug_vprintf(_format, _ap) ((void)0) +#endif -/* Dump a blob in hex to the same place that debug_printf sends its - * messages: + +/** + * Dump a blob in hex to the same place that debug_printf sends its + * messages. */ +#ifdef DEBUG void debug_print_blob( const char *name, const void *blob, unsigned size ); +#else +#define debug_print_blob(_name, _blob, _size) ((void)0) +#endif + + +void _debug_break(void); + /** - * @sa debug_printf + * Hard-coded breakpoint. */ -void debug_vprintf(const char *format, va_list ap); +#ifdef DEBUG +#if (defined(__i386__) || defined(__386__)) && defined(__GNUC__) +#define debug_break() __asm("int3") +#elif (defined(__i386__) || defined(__386__)) && defined(__MSC__) +#define debug_break() _asm {int 3} +#else +#define debug_break() _debug_break() +#endif +#else /* !DEBUG */ +#define debug_break() ((void)0) +#endif /* !DEBUG */ + -void debug_assert_fail(const char *expr, const char *file, unsigned line); +void _debug_assert_fail(const char *expr, + const char *file, + unsigned line, + const char *function); -/** Assert macro */ +/** + * Assert macro + * + * Do not expect that the assert call terminates -- errors must be handled + * regardless of assert behavior. + */ #ifdef DEBUG -#define debug_assert(expr) ((expr) ? (void)0 : debug_assert_fail(#expr, __FILE__, __LINE__)) +#define debug_assert(expr) ((expr) ? (void)0 : _debug_assert_fail(#expr, __FILE__, __LINE__, __FUNCTION__)) #else #define debug_assert(expr) ((void)0) #endif +/** Override standard assert macro */ #ifdef assert #undef assert #endif #define assert(expr) debug_assert(expr) +/** + * Output the current function name. + */ +#ifdef DEBUG +#define debug_checkpoint() \ + _debug_printf("%s\n", __FUNCTION__) +#else +#define debug_checkpoint() \ + ((void)0) +#endif + + +/** + * Output the full source code position. + */ +#ifdef DEBUG +#define debug_checkpoint_full() \ + debug_printf("%s:%u:%s", __FILE__, __LINE__, __FUNCTION__) +#else +#define debug_checkpoint_full() \ + ((void)0) +#endif + + +/** + * Output a warning message. Muted on release version. + */ #ifdef DEBUG #define debug_warning(__msg) \ - debug_printf("%s:%i:warning: %s\n", __FILE__, __LINE__, (__msg)) + _debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __FUNCTION__, (__msg)) #else #define debug_warning(__msg) \ ((void)0) #endif +/** + * Output an error message. Not muted on release version. + */ +#ifdef DEBUG +#define debug_error(__msg) \ + _debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __FUNCTION__, (__msg)) +#else +#define debug_error(__msg) \ + _debug_printf("error: %s\n", __msg)) +#endif + + /** * Used by debug_dump_enum and debug_dump_flags to describe symbols. */ -- cgit v1.2.3 From e8c6ea4f608296ed976f1597ffd46ac0b42fc84a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 24 Mar 2008 22:30:33 +0000 Subject: gallium: Simple cross platform get-opt system. Uses getenv on Linux, and a memory mapped text file on Windows. It supports boolean options, flags, and plain strings. --- src/gallium/auxiliary/util/p_debug.c | 144 +++++++++++++++++++++++++++++++++++ src/gallium/include/pipe/p_debug.h | 27 +++++++ 2 files changed, 171 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index bd58e0e3a8..351de95c95 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -107,6 +107,150 @@ void _debug_break(void) #endif } + +#ifdef WIN32 +static const char * +find(const char *start, const char *end, char c) +{ + const char *p; + for(p = start; !end || p != end; ++p) { + if(*p == c) + return p; + if(*p < 32) + break; + } + return NULL; +} + +static int +compare(const char *start, const char *end, const char *s) +{ + const char *p, *q; + for(p = start, q = s; p != end && *q != '\0'; ++p, ++q) { + if(*p != *q) + return 0; + } + return p == end && *q == '\0'; +} + +static void +copy(char *dst, const char *start, const char *end, size_t n) +{ + const char *p; + char *q; + for(p = start, q = dst, n = n - 1; p != end && n; ++p, ++q, --n) + *q = *p; + *q = '\0'; +} +#endif + + +const char * +debug_get_option(const char *name, const char *dfault) +{ + const char *result; +#ifdef WIN32 + ULONG_PTR iFile = 0; + const void *pMap = NULL; + const char *sol, *eol, *sep; + static char output[1024]; + + pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile); + if(!pMap) + result = dfault; + else { + sol = (const char *)pMap; + while(1) { + /* TODO: handle LF line endings */ + eol = find(sol, NULL, '\r'); + if(!eol || eol == sol) + break; + sep = find(sol, eol, '='); + if(!sep) + break; + if(compare(sol, sep, name)) { + copy(output, sep + 1, eol, sizeof(output)); + result = output; + break; + } + sol = eol + 2; + } + EngUnmapFile(iFile); + } +#else + + result = getenv(name); + if(!result) + result = dfault; +#endif + + if(result) + debug_printf("%s: %s = %s\n", __FUNCTION__, name, result); + else + debug_printf("%s: %s = (null)\n", __FUNCTION__, name); + + return result; +} + +boolean +debug_get_bool_option(const char *name, boolean dfault) +{ + const char *str = debug_get_option(name, NULL); + boolean result; + + if(str == NULL) + result = dfault; + else if(!strcmp(str, "no")) + result = FALSE; + else if(!strcmp(str, "0")) + result = FALSE; + else if(!strcmp(str, "f")) + result = FALSE; + else if(!strcmp(str, "false")) + result = FALSE; + else + result = TRUE; + + debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? "TRUE" : "FALSE"); + + return result; +} + + +long +debug_get_num_option(const char *name, long dfault) +{ + /* FIXME */ + return dfault; +} + + +unsigned long +debug_get_flags_option(const char *name, + const struct debug_named_value *flags, + unsigned long dfault) +{ + unsigned long result; + const char *str; + + str = debug_get_option(name, NULL); + if(!str) + result = dfault; + else { + result = 0; + while( flags->name ) { + if (!strcmp(str, "all") || strstr(str, flags->name )) + result |= flags->value; + ++flags; + } + } + + debug_printf("%s: %s = 0x%lx\n", __FUNCTION__, name, result); + + return result; +} + + #if defined(WIN32) ULONG_PTR debug_config_file = 0; void *mapped_config_file = 0; diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 494cc3bb71..95bdf2d3b9 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -256,6 +256,33 @@ debug_dump_flags(const struct debug_named_value *names, unsigned long value); +/** + * Get option. + * + * It is an alias for getenv on Linux. + * + * On Windows it reads C:\gallium.cfg, which is a text file with CR+LF line + * endings with one option per line as + * + * NAME=value + * + * This file must be terminated with an extra empty line. + */ +const char * +debug_get_option(const char *name, const char *dfault); + +boolean +debug_get_bool_option(const char *name, boolean dfault); + +long +debug_get_unsigned_option(const char *name, long dfault); + +unsigned long +debug_get_flags_option(const char *name, + const struct debug_named_value *flags, + unsigned long dfault); + + void * debug_malloc(const char *file, unsigned line, const char *function, size_t size); -- cgit v1.2.3 From 648e26aa95b519f1f4abc429b5a23abaf4a5195b Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 24 Mar 2008 16:24:32 -0600 Subject: gallium: added tgsi_num_tokens() function to return number of tokens in token array. Maybe move to a different file someday. --- src/gallium/auxiliary/tgsi/util/tgsi_parse.c | 13 +++++++++++++ src/gallium/auxiliary/tgsi/util/tgsi_parse.h | 4 ++++ 2 files changed, 17 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c index bf6b89ce56..c3526cb71f 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c @@ -317,3 +317,16 @@ tgsi_parse_token( } } + +unsigned +tgsi_num_tokens(const struct tgsi_token *tokens) +{ + struct tgsi_parse_context ctx; + if (tgsi_parse_init(&ctx, tokens) == TGSI_PARSE_OK) { + unsigned len = (ctx.FullHeader.Header.HeaderSize + + ctx.FullHeader.Header.BodySize + + 1); + return len; + } + return 0; +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h index 40083728d6..a98e88e343 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h @@ -113,6 +113,10 @@ void tgsi_parse_token( struct tgsi_parse_context *ctx ); +unsigned +tgsi_num_tokens(const struct tgsi_token *tokens); + + #if defined __cplusplus } #endif -- cgit v1.2.3 From 7f430293772f201a59bcf62edd1ed4f942f8be29 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 24 Mar 2008 16:26:45 -0600 Subject: gallium: use pipe_texture_reference() in a few places (fixes refcounting bugs) --- src/gallium/auxiliary/draw/draw_aaline.c | 9 +++++++-- src/gallium/auxiliary/draw/draw_pstipple.c | 12 ++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index 6742f7f4b9..cc1873abad 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -621,7 +621,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) bind_aaline_fragment_shader(aaline); aaline->state.sampler[num] = aaline->sampler_cso; - aaline->state.texture[num] = aaline->texture; + pipe_texture_reference(&aaline->state.texture[num], aaline->texture); aaline->driver_bind_sampler_states(pipe, num + 1, aaline->state.sampler); aaline->driver_set_sampler_textures(pipe, num + 1, aaline->state.texture); @@ -769,9 +769,14 @@ aaline_set_sampler_textures(struct pipe_context *pipe, unsigned num, struct pipe_texture **texture) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + uint i; + /* save current */ - memcpy(aaline->state.texture, texture, num * sizeof(struct pipe_texture *)); + for (i = 0; i < num; i++) { + pipe_texture_reference(&aaline->state.texture[i], texture[i]); + } aaline->num_textures = num; + /* pass-through */ aaline->driver_set_sampler_textures(aaline->pipe, num, texture); } diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index bd8d3a76ae..f00b23959b 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -398,6 +398,7 @@ pstip_create_texture(struct pstip_stage *pstip) texTemp.cpp = 1; pstip->texture = screen->texture_create(screen, &texTemp); + assert(pstip->texture->refcount == 1); //pstip_update_texture(pstip); } @@ -492,7 +493,8 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) /* plug in our sampler, texture */ pstip->state.samplers[pstip->sampler_unit] = pstip->sampler_cso; - pstip->state.textures[pstip->sampler_unit] = pstip->texture; + pipe_texture_reference(&pstip->state.textures[pstip->sampler_unit], + pstip->texture); pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); @@ -624,6 +626,7 @@ pstip_bind_sampler_states(struct pipe_context *pipe, unsigned num, void **sampler) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + /* save current */ memcpy(pstip->state.samplers, sampler, num * sizeof(void *)); pstip->num_samplers = num; @@ -637,9 +640,14 @@ pstip_set_sampler_textures(struct pipe_context *pipe, unsigned num, struct pipe_texture **texture) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + uint i; + /* save current */ - memcpy(pstip->state.textures, texture, num * sizeof(struct pipe_texture *)); + for (i = 0; i < num; i++) { + pipe_texture_reference(&pstip->state.textures[i], texture[i]); + } pstip->num_textures = num; + /* pass-through */ pstip->driver_set_sampler_textures(pstip->pipe, num, texture); } -- cgit v1.2.3 From ae146e4bc86aeade59d018100e39e160f7553994 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 24 Mar 2008 16:31:15 -0600 Subject: gallium: make a copy of the vertex shader's token array. This solves problems when the state tracker frees the token array when the draw module still needs it. --- src/gallium/auxiliary/draw/draw_vs_exec.c | 7 ++++++- src/gallium/auxiliary/draw/draw_vs_llvm.c | 7 ++++++- src/gallium/auxiliary/draw/draw_vs_sse.c | 6 +++++- 3 files changed, 17 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 364693e0b4..4e2fa72707 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -38,6 +38,8 @@ #include "draw_context.h" #include "draw_vs.h" +#include "tgsi/util/tgsi_parse.h" + static INLINE unsigned compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) @@ -187,6 +189,7 @@ vs_exec_run( struct draw_vertex_shader *shader, static void vs_exec_delete( struct draw_vertex_shader *dvs ) { + FREE((void*) dvs->state.tokens); FREE( dvs ); } @@ -196,11 +199,13 @@ draw_create_vs_exec(struct draw_context *draw, const struct pipe_shader_state *state) { struct draw_vertex_shader *vs = CALLOC_STRUCT( draw_vertex_shader ); + uint nt = tgsi_num_tokens(state->tokens); if (vs == NULL) return NULL; - vs->state = *state; + /* we make a private copy of the tokens */ + vs->state.tokens = mem_dup(state->tokens, nt * sizeof(state->tokens[0])); vs->prepare = vs_exec_prepare; vs->run = vs_exec_run; vs->delete = vs_exec_delete; diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 53c260be53..bd983f2ddf 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -38,6 +38,8 @@ #include "draw_context.h" #include "draw_vs.h" +#include "tgsi/util/tgsi_parse.h" + #ifdef MESA_LLVM #include "gallivm/gallivm.h" @@ -186,6 +188,7 @@ vs_llvm_delete( struct draw_vertex_shader *base ) /* Do something to free compiled shader: */ + FREE( (void*) shader->base.state.tokens ); FREE( shader ); } @@ -197,12 +200,14 @@ draw_create_vs_llvm(struct draw_context *draw, const struct pipe_shader_state *templ) { struct draw_llvm_vertex_shader *vs; + uint nt = tgsi_num_tokens(templ->tokens); vs = CALLOC_STRUCT( draw_llvm_vertex_shader ); if (vs == NULL) return NULL; - vs->base.state = templ; + /* we make a private copy of the tokens */ + vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0])); vs->base.prepare = vs_llvm_prepare; vs->base.run = vs_llvm_run; vs->base.delete = vs_llvm_delete; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 5ee2adb344..a4503c143e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -43,6 +43,7 @@ #include "rtasm/rtasm_x86sse.h" #include "tgsi/exec/tgsi_sse2.h" +#include "tgsi/util/tgsi_parse.h" typedef void (XSTDCALL *codegen_function) ( @@ -204,6 +205,7 @@ vs_sse_delete( struct draw_vertex_shader *base ) x86_release_func( &shader->sse2_program ); + FREE( (void*) shader->base.state.tokens ); FREE( shader ); } @@ -213,6 +215,7 @@ draw_create_vs_sse(struct draw_context *draw, const struct pipe_shader_state *templ) { struct draw_sse_vertex_shader *vs; + uint nt = tgsi_num_tokens(templ->tokens); if (!draw->use_sse) return NULL; @@ -221,7 +224,8 @@ draw_create_vs_sse(struct draw_context *draw, if (vs == NULL) return NULL; - vs->base.state = *templ; + /* we make a private copy of the tokens */ + vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0])); vs->base.prepare = vs_sse_prepare; vs->base.run = vs_sse_run; vs->base.delete = vs_sse_delete; -- cgit v1.2.3 From d6af8fc51d0288f34b92b7249c565c382e83765a Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 24 Mar 2008 18:32:48 -0600 Subject: gallium: move sampler_unit field to pstip_fragment_shader since it's per-shader Also, fix another texture refcounting bug. --- src/gallium/auxiliary/draw/draw_pstipple.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index f00b23959b..9cec986640 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -56,6 +56,7 @@ struct pstip_fragment_shader struct pipe_shader_state state; void *driver_fs; void *pstip_fs; + uint sampler_unit; }; @@ -67,7 +68,6 @@ struct pstip_stage struct draw_stage stage; void *sampler_cso; - uint sampler_unit; struct pipe_texture *texture; uint num_samplers; uint num_textures; @@ -329,7 +329,7 @@ generate_pstip_fs(struct pstip_stage *pstip) tgsi_dump(pstip_fs.tokens, 0); #endif - pstip->sampler_unit = transform.maxSampler + 1; + pstip->fs->sampler_unit = transform.maxSampler + 1; pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); } @@ -489,13 +489,15 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) /* how many samplers? */ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); - num_samplers = MAX2(num_samplers, pstip->sampler_unit + 1); + num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1); /* plug in our sampler, texture */ - pstip->state.samplers[pstip->sampler_unit] = pstip->sampler_cso; - pipe_texture_reference(&pstip->state.textures[pstip->sampler_unit], + pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso; + pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit], pstip->texture); + assert(num_samplers <= PIPE_MAX_SAMPLERS); + pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); @@ -626,9 +628,14 @@ pstip_bind_sampler_states(struct pipe_context *pipe, unsigned num, void **sampler) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + uint i; /* save current */ memcpy(pstip->state.samplers, sampler, num * sizeof(void *)); + for (i = num; i < PIPE_MAX_SAMPLERS; i++) { + pstip->state.samplers[i] = NULL; + } + pstip->num_samplers = num; /* pass-through */ pstip->driver_bind_sampler_states(pstip->pipe, num, sampler); @@ -646,6 +653,10 @@ pstip_set_sampler_textures(struct pipe_context *pipe, for (i = 0; i < num; i++) { pipe_texture_reference(&pstip->state.textures[i], texture[i]); } + for (; i < PIPE_MAX_SAMPLERS; i++) { + pipe_texture_reference(&pstip->state.textures[i], NULL); + } + pstip->num_textures = num; /* pass-through */ -- cgit v1.2.3 From 4654803e2595ea041ea83baf5e13e6c68890e9a7 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 24 Mar 2008 18:49:56 -0600 Subject: gallium: fix a few bugs, warnings in the p_debug code added missing _ to a _debug_printf() call. --- src/gallium/auxiliary/util/p_debug.c | 4 ++-- src/gallium/include/pipe/p_debug.h | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 351de95c95..cc036dabf8 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -260,7 +260,7 @@ enum { }; /* Check for aborts enabled. */ -static unsigned abort_en() +static unsigned abort_en(void) { if (!mapped_config_file) { @@ -283,7 +283,7 @@ static unsigned abort_en() return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn; } #else /* WIN32 */ -static unsigned abort_en() +static unsigned abort_en(void) { return !GETENV("GALLIUM_ABORT_ON_ASSERT"); } diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 95bdf2d3b9..577cdaebcd 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -63,7 +63,7 @@ extern "C" { void _debug_vprintf(const char *format, va_list ap); -static void INLINE +static INLINE void _debug_printf(const char *format, ...) { va_list ap; @@ -82,7 +82,7 @@ _debug_printf(const char *format, ...) * - avoid outputing large strings (512 bytes is the current maximum length * that is guaranteed to be printed in all platforms) */ -static void INLINE +static INLINE void debug_printf(const char *format, ...) { #ifdef DEBUG @@ -133,6 +133,9 @@ void _debug_break(void); #endif /* !DEBUG */ +long +debug_get_num_option(const char *name, long dfault); + void _debug_assert_fail(const char *expr, const char *file, unsigned line, @@ -176,7 +179,7 @@ void _debug_assert_fail(const char *expr, */ #ifdef DEBUG #define debug_checkpoint_full() \ - debug_printf("%s:%u:%s", __FILE__, __LINE__, __FUNCTION__) + _debug_printf("%s:%u:%s", __FILE__, __LINE__, __FUNCTION__) #else #define debug_checkpoint_full() \ ((void)0) -- cgit v1.2.3 From 6579440ea98e61871fe781c1c9c681645ddcc075 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 24 Mar 2008 19:36:44 -0600 Subject: gallium: be smarter about picking the sampler unit for pstipple, aaalines Also, if the app really uses all available sampler/texture units, don't just die. Just use the last sampler for the pstipple or aaline texture. --- src/gallium/auxiliary/draw/draw_aaline.c | 54 ++++++++++++++++++++++++------ src/gallium/auxiliary/draw/draw_pstipple.c | 41 +++++++++++++++++------ 2 files changed, 74 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index cc1873abad..a999ef1227 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -61,6 +61,7 @@ struct aaline_fragment_shader void *aaline_fs; void *aapoint_fs; /* not yet */ void *sprite_fs; /* not yet */ + uint sampler_unit; }; @@ -117,7 +118,8 @@ struct aa_transform_context { struct tgsi_transform_context base; uint tempsUsed; /**< bitmask */ int colorOutput; /**< which output is the primary color */ - int maxSampler; /**< max sampler index found */ + uint samplersUsed; /**< bitfield of samplers used */ + int freeSampler; /** an available sampler for the pstipple */ int maxInput, maxGeneric; /**< max input index found */ int colorTemp, texTemp; /**< temp registers */ boolean firstInstruction; @@ -140,8 +142,11 @@ aa_transform_decl(struct tgsi_transform_context *ctx, aactx->colorOutput = decl->u.DeclarationRange.First; } else if (decl->Declaration.File == TGSI_FILE_SAMPLER) { - if ((int) decl->u.DeclarationRange.Last > aactx->maxSampler) - aactx->maxSampler = decl->u.DeclarationRange.Last + 1; + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + aactx->samplersUsed |= 1 << i; + } } else if (decl->Declaration.File == TGSI_FILE_INPUT) { if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) @@ -163,6 +168,21 @@ aa_transform_decl(struct tgsi_transform_context *ctx, } +/** + * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. + */ +static int +free_bit(uint bitfield) +{ + int i; + for (i = 0; i < 32; i++) { + if ((bitfield & (1 << i)) == 0) + return i; + } + return -1; +} + + /** * TGSI instruction transform callback. * Replace writes to result.color w/ a temp reg. @@ -180,6 +200,11 @@ aa_transform_inst(struct tgsi_transform_context *ctx, struct tgsi_full_declaration decl; uint i; + /* find free sampler */ + aactx->freeSampler = free_bit(aactx->samplersUsed); + if (aactx->freeSampler >= PIPE_MAX_SAMPLERS) + aactx->freeSampler = PIPE_MAX_SAMPLERS - 1; + /* find two free temp regs */ for (i = 0; i < 32; i++) { if ((aactx->tempsUsed & (1 << i)) == 0) { @@ -212,7 +237,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx, decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_SAMPLER; decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->maxSampler + 1; + decl.u.DeclarationRange.Last = aactx->freeSampler; ctx->emit_declaration(ctx, &decl); /* declare new temp regs */ @@ -246,7 +271,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx, newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1; newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->maxSampler + 1; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->freeSampler; ctx->emit_instruction(ctx, &newInst); @@ -322,7 +347,6 @@ generate_aaline_fs(struct aaline_stage *aaline) memset(&transform, 0, sizeof(transform)); transform.colorOutput = -1; - transform.maxSampler = -1; transform.maxInput = -1; transform.maxGeneric = -1; transform.colorTemp = -1; @@ -340,6 +364,8 @@ generate_aaline_fs(struct aaline_stage *aaline) tgsi_dump(aaline_fs.tokens, 0); #endif + aaline->fs->sampler_unit = transform.freeSampler; + aaline->fs->aaline_fs = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); @@ -602,7 +628,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) auto struct aaline_stage *aaline = aaline_stage(stage); struct draw_context *draw = stage->draw; struct pipe_context *pipe = aaline->pipe; - uint num = MAX2(aaline->num_textures, aaline->num_samplers); + uint num_samplers; assert(draw->rasterizer->line_smooth); @@ -620,11 +646,17 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) */ bind_aaline_fragment_shader(aaline); - aaline->state.sampler[num] = aaline->sampler_cso; - pipe_texture_reference(&aaline->state.texture[num], aaline->texture); + /* how many samplers? */ + /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ + num_samplers = MAX2(aaline->num_textures, aaline->num_samplers); + num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1); + + aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso; + pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit], + aaline->texture); - aaline->driver_bind_sampler_states(pipe, num + 1, aaline->state.sampler); - aaline->driver_set_sampler_textures(pipe, num + 1, aaline->state.texture); + aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler); + aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture); /* now really draw first line */ stage->line = aaline_line; diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c index 9cec986640..4dddb72906 100644 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -112,7 +112,8 @@ struct pstip_transform_context { uint tempsUsed; /**< bitmask */ int wincoordInput; int maxInput; - int maxSampler; /**< max sampler index found */ + uint samplersUsed; /**< bitfield of samplers used */ + int freeSampler; /** an available sampler for the pstipple */ int texTemp; /**< temp registers */ int numImmed; boolean firstInstruction; @@ -130,8 +131,11 @@ pstip_transform_decl(struct tgsi_transform_context *ctx, struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; if (decl->Declaration.File == TGSI_FILE_SAMPLER) { - if ((int) decl->u.DeclarationRange.Last > pctx->maxSampler) - pctx->maxSampler = (int) decl->u.DeclarationRange.Last; + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + pctx->samplersUsed |= 1 << i; + } } else if (decl->Declaration.File == TGSI_FILE_INPUT) { pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last); @@ -159,6 +163,21 @@ pstip_transform_immed(struct tgsi_transform_context *ctx, } +/** + * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. + */ +static int +free_bit(uint bitfield) +{ + int i; + for (i = 0; i < 32; i++) { + if ((bitfield & (1 << i)) == 0) + return i; + } + return -1; +} + + /** * TGSI instruction transform callback. * Replace writes to result.color w/ a temp reg. @@ -177,7 +196,11 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, struct tgsi_full_instruction newInst; uint i; int wincoordInput; - const int sampler = pctx->maxSampler + 1; + + /* find free sampler */ + pctx->freeSampler = free_bit(pctx->samplersUsed); + if (pctx->freeSampler >= PIPE_MAX_SAMPLERS) + pctx->freeSampler = PIPE_MAX_SAMPLERS - 1; if (pctx->wincoordInput < 0) wincoordInput = pctx->maxInput + 1; @@ -214,7 +237,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_SAMPLER; decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = sampler; + decl.u.DeclarationRange.Last = pctx->freeSampler; ctx->emit_declaration(ctx, &decl); /* declare new temp regs */ @@ -274,7 +297,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - newInst.FullSrcRegisters[1].SrcRegister.Index = sampler; + newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler; ctx->emit_instruction(ctx, &newInst); /* KILP texTemp; # if texTemp < 0, KILL fragment */ @@ -313,7 +336,6 @@ generate_pstip_fs(struct pstip_stage *pstip) memset(&transform, 0, sizeof(transform)); transform.wincoordInput = -1; transform.maxInput = -1; - transform.maxSampler = -1; transform.texTemp = -1; transform.firstInstruction = TRUE; transform.base.transform_instruction = pstip_transform_inst; @@ -329,7 +351,8 @@ generate_pstip_fs(struct pstip_stage *pstip) tgsi_dump(pstip_fs.tokens, 0); #endif - pstip->fs->sampler_unit = transform.maxSampler + 1; + pstip->fs->sampler_unit = transform.freeSampler; + assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS); pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); } @@ -399,8 +422,6 @@ pstip_create_texture(struct pstip_stage *pstip) pstip->texture = screen->texture_create(screen, &texTemp); assert(pstip->texture->refcount == 1); - - //pstip_update_texture(pstip); } -- cgit v1.2.3 From 6fa0bd067176d9159a741014301dfb5fbbd9c4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 25 Mar 2008 11:37:24 +0000 Subject: gallium: Fix default option on Windows. --- src/gallium/auxiliary/util/p_debug.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index cc036dabf8..5447bbb6f5 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -155,10 +155,12 @@ debug_get_option(const char *name, const char *dfault) const char *sol, *eol, *sep; static char output[1024]; + result = dfault; + /* XXX: this creates the file if it does not exists, so it must either be + * disabled on release versions, or put in a less conspicuous place. + */ pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile); - if(!pMap) - result = dfault; - else { + if(pMap) { sol = (const char *)pMap; while(1) { /* TODO: handle LF line endings */ @@ -184,10 +186,7 @@ debug_get_option(const char *name, const char *dfault) result = dfault; #endif - if(result) - debug_printf("%s: %s = %s\n", __FUNCTION__, name, result); - else - debug_printf("%s: %s = (null)\n", __FUNCTION__, name); + debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? result : "(null)"); return result; } -- cgit v1.2.3 From aacfc326cc94be180864201cd9377db08985698e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 25 Mar 2008 11:37:54 +0000 Subject: gallium: Use debug_get_option for GETENV --- src/gallium/include/pipe/p_util.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 505626c60b..1e7b8181f9 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -51,7 +51,6 @@ extern "C" { debug_free( __FILE__, __LINE__, __FUNCTION__, _ptr ) #define REALLOC( _ptr, _old_size, _size ) \ debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _size ) -#define GETENV( X ) NULL #else @@ -118,8 +117,6 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) return new_ptr; } -#define GETENV( X ) NULL - #else /* !WIN32 */ #define MALLOC( SIZE ) malloc( SIZE ) @@ -130,8 +127,6 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define REALLOC( OLDPTR, OLDSIZE, NEWSIZE ) realloc( OLDPTR, NEWSIZE ) -#define GETENV( X ) getenv( X ) - #endif /* !WIN32 */ #endif /* !DEBUG */ @@ -139,6 +134,8 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define CALLOC_STRUCT(T) (struct T *) CALLOC(1, sizeof(struct T)) +#define GETENV( X ) debug_get_option( X, NULL ) + /** * Return memory on given byte alignment -- cgit v1.2.3 From 4505acf3b28f0b88bf97838ed7898f10e9200b93 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 25 Mar 2008 15:17:53 +0000 Subject: draw: take primitive into account when deciding if the pipeline is active --- src/gallium/auxiliary/draw/draw_passthrough.c | 2 +- src/gallium/auxiliary/draw/draw_private.h | 3 +- src/gallium/auxiliary/draw/draw_pt.c | 2 +- src/gallium/auxiliary/draw/draw_validate.c | 99 ++++++++++++++++++--------- 4 files changed, 69 insertions(+), 37 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_passthrough.c b/src/gallium/auxiliary/draw/draw_passthrough.c index dd00894c5b..2198079a88 100644 --- a/src/gallium/auxiliary/draw/draw_passthrough.c +++ b/src/gallium/auxiliary/draw/draw_passthrough.c @@ -424,7 +424,7 @@ draw_passthrough_arrays(struct draw_context *draw, debug_printf("%s %d %d %d\n", __FUNCTION__, prim, start, count); - if (draw_need_pipeline(draw)) + if (draw_need_pipeline(draw, prim)) return FALSE; debug_printf("%s AAA\n", __FUNCTION__); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 0c5afcacfa..8a879809c3 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -364,7 +364,8 @@ extern void draw_vertex_shader_queue_flush( struct draw_context *draw ); extern void draw_update_vertex_fetch( struct draw_context *draw ); -extern boolean draw_need_pipeline(const struct draw_context *draw); +extern boolean draw_need_pipeline(const struct draw_context *draw, + unsigned prim ); /* Passthrough mode (second attempt): diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index d7169f78f4..3ec31ec25f 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -55,7 +55,7 @@ draw_pt_arrays(struct draw_context *draw, unsigned start, unsigned count) { - const boolean pipeline = draw_need_pipeline(draw); + const boolean pipeline = draw_need_pipeline(draw, prim); const boolean cliptest = !draw->rasterizer->bypass_clipping; const boolean shading = !draw->rasterizer->bypass_vs; struct draw_pt_front_end *frontend = NULL; diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index 70b477ba5c..e163e078f0 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -32,6 +32,22 @@ #include "pipe/p_defines.h" #include "draw_private.h" +static boolean points( unsigned prim ) +{ + return (prim == PIPE_PRIM_POINTS); +} + +static boolean lines( unsigned prim ) +{ + return (prim == PIPE_PRIM_LINES || + prim == PIPE_PRIM_LINE_STRIP || + prim == PIPE_PRIM_LINE_LOOP); +} + +static boolean triangles( unsigned prim ) +{ + return prim >= PIPE_PRIM_TRIANGLES; +} /** * Check if we need any special pipeline stages, or whether @@ -40,48 +56,63 @@ * pipeline stages. */ boolean -draw_need_pipeline(const struct draw_context *draw) +draw_need_pipeline(const struct draw_context *draw, + unsigned int prim ) { - /* line stipple */ - if (draw->rasterizer->line_stipple_enable && draw->line_stipple) - return TRUE; - - /* wide lines */ - if (draw->rasterizer->line_width > draw->wide_line_threshold) - return TRUE; + /* Don't have to worry about triangles turning into lines/points + * and triggering the pipeline, because we have to trigger the + * pipeline *anyway* if unfilled mode is active. + */ + if (lines(prim)) + { + /* line stipple */ + if (draw->rasterizer->line_stipple_enable && draw->line_stipple) + return TRUE; - /* large points */ - if (draw->rasterizer->point_size > draw->wide_point_threshold) - return TRUE; + /* wide lines */ + if (draw->rasterizer->line_width > draw->wide_line_threshold) + return TRUE; - /* AA lines */ - if (draw->rasterizer->line_smooth && draw->pipeline.aaline) - return TRUE; - - /* AA points */ - if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) - return TRUE; + /* AA lines */ + if (draw->rasterizer->line_smooth && draw->pipeline.aaline) + return TRUE; + } - /* polygon stipple */ - if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple) - return TRUE; + if (points(prim)) + { + /* large points */ + if (draw->rasterizer->point_size > draw->wide_point_threshold) + return TRUE; - /* unfilled polygons */ - if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) - return TRUE; + /* AA points */ + if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) + return TRUE; - /* polygon offset */ - if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw) - return TRUE; + /* point sprites */ + if (draw->rasterizer->point_sprite && draw->point_sprite) + return TRUE; + } - /* point sprites */ - if (draw->rasterizer->point_sprite && draw->point_sprite) - return TRUE; - /* two-side lighting */ - if (draw->rasterizer->light_twoside) - return TRUE; + if (triangles(prim)) + { + /* polygon stipple */ + if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple) + return TRUE; + + /* unfilled polygons */ + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) + return TRUE; + + /* polygon offset */ + if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw) + return TRUE; + + /* two-side lighting */ + if (draw->rasterizer->light_twoside) + return TRUE; + } /* polygon cull - this is difficult - hardware can cull just fine * most of the time (though sometimes CULL_NEITHER is unsupported. -- cgit v1.2.3 From 331a56136e96717704788b633c1b2e474b88d8ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 25 Mar 2008 17:47:39 +0000 Subject: Fix typo --- src/gallium/include/pipe/p_debug.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 577cdaebcd..097fc7c0b1 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -191,7 +191,7 @@ void _debug_assert_fail(const char *expr, */ #ifdef DEBUG #define debug_warning(__msg) \ - _debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __FUNCTION__, (__msg)) + _debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg) #else #define debug_warning(__msg) \ ((void)0) @@ -203,10 +203,10 @@ void _debug_assert_fail(const char *expr, */ #ifdef DEBUG #define debug_error(__msg) \ - _debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __FUNCTION__, (__msg)) + _debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg) #else #define debug_error(__msg) \ - _debug_printf("error: %s\n", __msg)) + _debug_printf("error: %s\n", __msg) #endif -- cgit v1.2.3 From cbec00849186db11d77fd00822145e11e69cb07f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 25 Mar 2008 18:09:25 +0000 Subject: draw: don't use fetch_and_store for bypass_vs mode, it's not quite right --- src/gallium/auxiliary/draw/draw_prim.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index 4fe0ddc02a..75b2f79bab 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -170,10 +170,7 @@ void draw_do_flush( struct draw_context *draw, unsigned flags ) if (flags >= DRAW_FLUSH_SHADER_QUEUE) { if (draw->vs.queue_nr) { - if (draw->rasterizer->bypass_vs) - fetch_and_store(draw); - else - (*draw->shader_queue_flush)(draw); + (*draw->shader_queue_flush)(draw); } if (flags >= DRAW_FLUSH_PRIM_QUEUE) { -- cgit v1.2.3 From 05a4ecdec2b5fc590eb09cc5a6b4208e0f739c5a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 25 Mar 2008 18:15:58 +0000 Subject: draw: vertex fetch can be validated too early leading to an assertion... disable --- src/gallium/auxiliary/draw/draw_vertex_fetch.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c index b56d85396d..11f99babf6 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c +++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c @@ -314,7 +314,11 @@ static fetch_func get_fetch_func( enum pipe_format format ) return NULL; /* not sure why this is needed */ default: - assert(0); + /* This can get hit because draw-state-validation is too eager, + and can jump in here validating stuff before the state tracker has set + up everything. + */ + /* assert(0); */ return NULL; } } -- cgit v1.2.3 From dc9757e1a8a0451a198d329880558b805adff42a Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 25 Mar 2008 23:48:30 +0100 Subject: gallium: Introduce flatshade_first field to rasterizer_state. This bit tells us which vertex of the primitive is used to propagate color for the remaining vertices if flatshade mode. --- src/gallium/include/pipe/p_state.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 3e531c4da4..a2bd8c6aaa 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -112,6 +112,7 @@ struct pipe_rasterizer_state unsigned bypass_clipping:1; unsigned bypass_vs:1; /**< vertices are already fully transformed */ unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ + unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */ float line_width; float point_size; /**< used when no per-vertex size */ -- cgit v1.2.3 From e1543fa55c7972e3634f3f7ba297c010337dfb0d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 25 Mar 2008 23:49:11 +0100 Subject: draw: Take flatshade_first rasterizer bit into account. --- src/gallium/auxiliary/draw/draw_prim.c | 162 ++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 45 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index 75b2f79bab..f589d0c017 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -330,6 +330,8 @@ draw_prim( struct draw_context *draw, unsigned i; boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL); + boolean flatfirst = + (draw->rasterizer->flatshade & draw->rasterizer->flatshade_first) ? TRUE : FALSE; // debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count ); @@ -342,11 +344,21 @@ draw_prim( struct draw_context *draw, break; case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - do_line( draw, - TRUE, - start + i + 0, - start + i + 1); + if (flatfirst) { + for (i = 0; i+1 < count; i += 2) { + do_line( draw, + TRUE, + start + i + 1, + start + i + 0); + } + } + else { + for (i = 0; i+1 < count; i += 2) { + do_line( draw, + TRUE, + start + i + 0, + start + i + 1); + } } break; @@ -367,60 +379,120 @@ draw_prim( struct draw_context *draw, break; case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < count; i++) { - do_line( draw, - i == 1, - start + i - 1, - start + i ); + if (flatfirst) { + for (i = 1; i < count; i++) { + do_line( draw, + i == 1, + start + i, + start + i - 1 ); + } + } + else { + for (i = 1; i < count; i++) { + do_line( draw, + i == 1, + start + i - 1, + start + i ); + } } break; case PIPE_PRIM_TRIANGLES: - if (unfilled) { - for (i = 0; i+2 < count; i += 3) { - do_ef_triangle( draw, - 1, - ~0, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } + if (flatfirst) { + if (unfilled) { + for (i = 0; i+2 < count; i += 3) { + do_ef_triangle( draw, + 1, + ~0, + start + i + 1, + start + i + 2, + start + i + 0 ); + } + } + else { + for (i = 0; i+2 < count; i += 3) { + do_triangle( draw, + start + i + 1, + start + i + 2, + start + i + 0 ); + } + } + } else { - for (i = 0; i+2 < count; i += 3) { - do_triangle( draw, - start + i + 0, - start + i + 1, - start + i + 2 ); - } + if (unfilled) { + for (i = 0; i+2 < count; i += 3) { + do_ef_triangle( draw, + 1, + ~0, + start + i + 0, + start + i + 1, + start + i + 2 ); + } + } + else { + for (i = 0; i+2 < count; i += 3) { + do_triangle( draw, + start + i + 0, + start + i + 1, + start + i + 2 ); + } + } } break; case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 0; i+2 < count; i++) { - if (i & 1) { - do_triangle( draw, - start + i + 1, - start + i + 0, - start + i + 2 ); - } - else { - do_triangle( draw, - start + i + 0, - start + i + 1, - start + i + 2 ); - } + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + if (i & 1) { + do_triangle( draw, + start + i + 2, + start + i + 1, + start + i + 0 ); + } + else { + do_triangle( draw, + start + i + 1, + start + i + 2, + start + i + 0 ); + } + } + } + else { + for (i = 0; i+2 < count; i++) { + if (i & 1) { + do_triangle( draw, + start + i + 1, + start + i + 0, + start + i + 2 ); + } + else { + do_triangle( draw, + start + i + 0, + start + i + 1, + start + i + 2 ); + } + } } break; case PIPE_PRIM_TRIANGLE_FAN: if (count >= 3) { - for (i = 0; i+2 < count; i++) { - do_triangle( draw, - start + 0, - start + i + 1, - start + i + 2 ); - } + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + do_triangle( draw, + start + i + 2, + start + 0, + start + i + 1 ); + } + } + else { + for (i = 0; i+2 < count; i++) { + do_triangle( draw, + start + 0, + start + i + 1, + start + i + 2 ); + } + } } break; -- cgit v1.2.3 From 84d8030735844785c3c97679db2bc1892a9c8c70 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 24 Mar 2008 12:15:59 -0700 Subject: cell: Float convert-to and convert-from instructions use different shift bias --- src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c | 4 ++-- src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c index 24be65bff9..7f6bf577b2 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c @@ -267,10 +267,10 @@ void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \ emit_RI7(p, _op, rT, rA, imm); \ } -#define EMIT_RI8(_name, _op) \ +#define EMIT_RI8(_name, _op, bias) \ void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \ { \ - emit_RI8(p, _op, rT, rA, 155 - imm); \ + emit_RI8(p, _op, rT, rA, bias - imm); \ } #define EMIT_RI10(_name, _op) \ diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h index 5a1eb1ed8d..1cacc717b1 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h @@ -76,7 +76,7 @@ extern void spe_release_register(struct spe_function *p, int reg); #define EMIT_RI7(_name, _op) \ extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ int imm) -#define EMIT_RI8(_name, _op) \ +#define EMIT_RI8(_name, _op, bias) \ extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ int imm) #define EMIT_RI10(_name, _op) \ @@ -289,10 +289,10 @@ EMIT_RR (spe_dfnma, 0x35f); EMIT_R (spe_frest, 0x1b8); EMIT_R (spe_frsqest, 0x1b9); EMIT_RR (spe_fi, 0x3d4); -EMIT_RI8 (spe_csflt, 0x1da); -EMIT_RI8 (spe_cflts, 0x1d8); -EMIT_RI8 (spe_cuflt, 0x1db); -EMIT_RI8 (spe_cfltu, 0x1d9); +EMIT_RI8 (spe_csflt, 0x1da, 155); +EMIT_RI8 (spe_cflts, 0x1d8, 173); +EMIT_RI8 (spe_cuflt, 0x1db, 155); +EMIT_RI8 (spe_cfltu, 0x1d9, 173); EMIT_R (spe_frds, 0x3b9); EMIT_R (spe_fesd, 0x3b8); EMIT_RR (spe_dfceq, 0x3c3); -- cgit v1.2.3 From b09de96a17028c3c936f6a196e048c4f224da89f Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 25 Mar 2008 18:07:56 -0700 Subject: xlib: Add support for MIT-SHM in xlib winsys driver Gives about a 3% performance increase in gears on x86-64 (non-tiled) and about 10% performance increase in gears on Cell (tiled). I actually expected more of a boost. :( --- src/gallium/winsys/xlib/xm_api.c | 16 +- src/gallium/winsys/xlib/xm_winsys.c | 301 ++++++++++++++++++++++++++------ src/gallium/winsys/xlib/xm_winsys_aub.h | 3 +- src/gallium/winsys/xlib/xmesaP.h | 3 + 4 files changed, 267 insertions(+), 56 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index e5fef1d7a8..6b46327e21 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -104,12 +104,16 @@ static int host_byte_order( void ) * 1 = shared XImage support available * 2 = shared Pixmap support available also */ -static int check_for_xshm( XMesaDisplay *display ) +int xmesa_check_for_xshm( XMesaDisplay *display ) { #if defined(USE_XSHM) && !defined(XFree86Server) int major, minor, ignore; Bool pixmaps; + if (getenv("MESA_NOSHM")) { + return 0; + } + if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { return (pixmaps==True) ? 2 : 1; @@ -528,7 +532,7 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, /* Setup for single/double buffering */ if (v->mesa_visual.doubleBufferMode) { /* Double buffered */ - b->shm = check_for_xshm( v->display ); + b->shm = xmesa_check_for_xshm( v->display ); } /* X11 graphics context */ @@ -770,13 +774,16 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) pf = choose_pixel_format(v); assert(pf); + c->xm_visual = v; + c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ + if (!getenv("XM_AUB")) { xmesa_mode = XMESA_SOFTPIPE; pipe = xmesa_create_pipe_context( c, pf ); } else { xmesa_mode = XMESA_AUB; - pipe = xmesa_create_i965simple( xmesa_get_pipe_winsys_aub() ); + pipe = xmesa_create_i965simple(xmesa_get_pipe_winsys_aub(v)); } c->st = st_create_context(pipe, &v->mesa_visual, @@ -800,9 +807,6 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) #endif /* finish up xmesa context initializations */ - c->xm_visual = v; - c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */ - c->st->haveFramebufferSurfaces = GL_TRUE; return c; diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 018cf01cd6..7baaae295c 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -65,8 +65,19 @@ struct xm_buffer boolean userBuffer; /** Is this a user-space buffer? */ void *data; void *mapped; + + XImage *tempImage; + int shm; +#if defined(USE_XSHM) && !defined(XFree86Server) + XShmSegmentInfo shminfo; +#endif }; +#if defined(USE_XSHM) && !defined(XFree86Server) +# define XSHM_ENABLED(b) ((b)->shm) +#else +# define XSHM_ENABLED(b) 0 +#endif struct xmesa_surface { @@ -88,6 +99,16 @@ struct xmesa_softpipe_winsys }; +struct xmesa_pipe_winsys +{ + struct pipe_winsys base; + struct xmesa_visual *xm_visual; + int shm; +}; + + +static void alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height); /** Cast wrapper */ static INLINE struct xmesa_surface * @@ -136,13 +157,27 @@ xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) static void xm_buffer_destroy(struct pipe_winsys *pws, - struct pipe_buffer *buf) + struct pipe_buffer *buf) { struct xm_buffer *oldBuf = xm_buffer(buf); if (oldBuf->data) { - if (!oldBuf->userBuffer) - align_free(oldBuf->data); +#if defined(USE_XSHM) && !defined(XFree86Server) + if (oldBuf->shminfo.shmid >= 0) { + shmdt(oldBuf->shminfo.shmaddr); + shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0); + + oldBuf->shminfo.shmid = -1; + oldBuf->shminfo.shmaddr = (char *) -1; + } + else +#endif + { + if (!oldBuf->userBuffer) { + align_free(oldBuf->data); + } + } + oldBuf->data = NULL; } @@ -157,7 +192,7 @@ xm_buffer_destroy(struct pipe_winsys *pws, static void xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) { - XImage *ximage = b->tempImage; + XImage *ximage; struct xm_buffer *xm_buf = xm_buffer(surf->buffer); const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE; uint x, y; @@ -166,10 +201,18 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) assert(ximage->format); assert(ximage->bitmap_unit); - /* update XImage's fields */ - ximage->width = TILE_SIZE; - ximage->height = TILE_SIZE; - ximage->bytes_per_line = TILE_SIZE * 4; + if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { + alloc_shm_ximage(xm_buf, b, TILE_SIZE, TILE_SIZE); + } + + ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; + + if (!XSHM_ENABLED(xm_buf)) { + /* update XImage's fields */ + ximage->width = TILE_SIZE; + ximage->height = TILE_SIZE; + ximage->bytes_per_line = TILE_SIZE * 4; + } for (y = 0; y < surf->height; y += TILE_SIZE) { for (x = 0; x < surf->width; x += TILE_SIZE) { @@ -183,8 +226,15 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) ximage->data = (char *) xm_buf->data + offset; - XPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, dx, dy, TILE_SIZE, TILE_SIZE); + if (XSHM_ENABLED(xm_buf)) { +#if defined(USE_XSHM) && !defined(XFree86Server) + XShmPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, x, y, TILE_SIZE, TILE_SIZE, False); +#endif + } else { + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, dx, dy, TILE_SIZE, TILE_SIZE); + } } } } @@ -197,7 +247,7 @@ xmesa_display_surface_tiled(XMesaBuffer b, const struct pipe_surface *surf) void xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) { - XImage *ximage = b->tempImage; + XImage *ximage; struct xm_buffer *xm_buf = xm_buffer(surf->buffer); const struct xmesa_surface *xm_surf = xmesa_surface((struct pipe_surface *) surf); @@ -207,19 +257,33 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) return; } - /* check that the XImage has been previously initialized */ - assert(ximage->format); - assert(ximage->bitmap_unit); - /* update XImage's fields */ - ximage->width = surf->width; - ximage->height = surf->height; - ximage->bytes_per_line = surf->pitch * (ximage->bits_per_pixel / 8); + if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { + alloc_shm_ximage(xm_buf, b, surf->pitch, surf->height); + } + + ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; ximage->data = xm_buf->data; /* display image in Window */ - XPutImage(b->xm_visual->display, b->drawable, b->gc, - ximage, 0, 0, 0, 0, surf->width, surf->height); + if (XSHM_ENABLED(xm_buf)) { +#if defined(USE_XSHM) && !defined(XFree86Server) + XShmPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, 0, 0, surf->width, surf->height, False); +#endif + } else { + /* check that the XImage has been previously initialized */ + assert(ximage->format); + assert(ximage->bitmap_unit); + + /* update XImage's fields */ + ximage->width = surf->width; + ximage->height = surf->height; + ximage->bytes_per_line = surf->pitch * surf->cpp; + + XPutImage(b->xm_visual->display, b->drawable, b->gc, + ximage, 0, 0, 0, 0, surf->width, surf->height); + } } @@ -256,6 +320,119 @@ xm_get_name(struct pipe_winsys *pws) } +#if defined(USE_XSHM) && !defined(XFree86Server) +static volatile int mesaXErrorFlag = 0; + +/** + * Catches potential Xlib errors. + */ +static int +mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event) +{ + (void) dpy; + (void) event; + mesaXErrorFlag = 1; + return 0; +} + + +static GLboolean alloc_shm(struct xm_buffer *buf, unsigned size) +{ + XShmSegmentInfo *const shminfo = & buf->shminfo; + + shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); + if (shminfo->shmid < 0) { + return GL_FALSE; + } + + shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); + if (shminfo->shmaddr == (char *) -1) { + shmctl(shminfo->shmid, IPC_RMID, 0); + return GL_FALSE; + } + + shminfo->readOnly = False; + return GL_TRUE; +} + + +/** + * Allocate a shared memory XImage back buffer for the given XMesaBuffer. + */ +static void +alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height) +{ + /* + * We have to do a _lot_ of error checking here to be sure we can + * really use the XSHM extension. It seems different servers trigger + * errors at different points if the extension won't work. Therefore + * we have to be very careful... + */ +#if 0 + GC gc; +#endif + int (*old_handler)(XMesaDisplay *, XErrorEvent *); + + b->tempImage = XShmCreateImage(xmb->xm_visual->display, + xmb->xm_visual->visinfo->visual, + xmb->xm_visual->visinfo->depth, + ZPixmap, + NULL, + &b->shminfo, + width, height); + if (b->tempImage == NULL) { + b->shm = 0; + return; + } + + + mesaXErrorFlag = 0; + old_handler = XSetErrorHandler(mesaHandleXError); + /* This may trigger the X protocol error we're ready to catch: */ + XShmAttach(xmb->xm_visual->display, &b->shminfo); + XSync(xmb->xm_visual->display, False); + + if (mesaXErrorFlag) { + /* we are on a remote display, this error is normal, don't print it */ + XFlush(xmb->xm_visual->display); + mesaXErrorFlag = 0; + XDestroyImage(b->tempImage); + b->tempImage = NULL; + b->shm = 0; + (void) XSetErrorHandler(old_handler); + return; + } + + + /* Finally, try an XShmPutImage to be really sure the extension works */ +#if 0 + gc = XCreateGC(xmb->xm_visual->display, xmb->drawable, 0, NULL); + XShmPutImage(xmb->xm_visual->display, xmb->drawable, gc, + b->tempImage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False); + XSync(xmb->xm_visual->display, False); + XFreeGC(xmb->xm_visual->display, gc); + (void) XSetErrorHandler(old_handler); + if (mesaXErrorFlag) { + XFlush(xmb->xm_visual->display); + mesaXErrorFlag = 0; + XDestroyImage(b->tempImage); + b->tempImage = NULL; + b->shm = 0; + return; + } +#endif +} +#else +static void +alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height) +{ + b->shm = 0; +} +#endif + + static struct pipe_buffer * xm_buffer_create(struct pipe_winsys *pws, unsigned alignment, @@ -263,13 +440,35 @@ xm_buffer_create(struct pipe_winsys *pws, unsigned size) { struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer); +#if defined(USE_XSHM) && !defined(XFree86Server) + struct xmesa_pipe_winsys *xpws = (struct xmesa_pipe_winsys *) pws; +#endif + buffer->base.refcount = 1; buffer->base.alignment = alignment; buffer->base.usage = usage; buffer->base.size = size; - /* align to 16-byte multiple for Cell */ - buffer->data = align_malloc(size, max(alignment, 16)); + +#if defined(USE_XSHM) && !defined(XFree86Server) + buffer->shminfo.shmid = -1; + buffer->shminfo.shmaddr = (char *) -1; + + if (xpws->shm && (usage & PIPE_BUFFER_USAGE_PIXEL) != 0) { + buffer->shm = xpws->shm; + + if (alloc_shm(buffer, size)) { + buffer->data = buffer->shminfo.shmaddr; + } + } +#endif + + if (buffer->data == NULL) { + buffer->shm = 0; + + /* align to 16-byte multiple for Cell */ + buffer->data = align_malloc(size, max(alignment, 16)); + } return &buffer->base; } @@ -286,6 +485,7 @@ xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) buffer->base.size = bytes; buffer->userBuffer = TRUE; buffer->data = ptr; + buffer->shm = 0; return &buffer->base; } @@ -377,35 +577,38 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) * Nothing special for the Xlib driver so no subclassing or anything. */ struct pipe_winsys * -xmesa_get_pipe_winsys_aub(void) +xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) { - static struct pipe_winsys *ws = NULL; + static struct xmesa_pipe_winsys *ws = NULL; if (!ws && getenv("XM_AUB")) { - ws = xmesa_create_pipe_winsys_aub(); + ws = (struct xmesa_pipe_winsys *) xmesa_create_pipe_winsys_aub(); } else if (!ws) { - ws = CALLOC_STRUCT(pipe_winsys); - + ws = CALLOC_STRUCT(xmesa_pipe_winsys); + + ws->xm_visual = xm_vis; + ws->shm = xmesa_check_for_xshm(xm_vis->display); + /* Fill in this struct with callbacks that pipe will need to * communicate with the window system, buffer manager, etc. */ - ws->buffer_create = xm_buffer_create; - ws->user_buffer_create = xm_user_buffer_create; - ws->buffer_map = xm_buffer_map; - ws->buffer_unmap = xm_buffer_unmap; - ws->buffer_destroy = xm_buffer_destroy; - - ws->surface_alloc = xm_surface_alloc; - ws->surface_alloc_storage = xm_surface_alloc_storage; - ws->surface_release = xm_surface_release; - - ws->flush_frontbuffer = xm_flush_frontbuffer; - ws->printf = xm_printf; - ws->get_name = xm_get_name; + ws->base.buffer_create = xm_buffer_create; + ws->base.user_buffer_create = xm_user_buffer_create; + ws->base.buffer_map = xm_buffer_map; + ws->base.buffer_unmap = xm_buffer_unmap; + ws->base.buffer_destroy = xm_buffer_destroy; + + ws->base.surface_alloc = xm_surface_alloc; + ws->base.surface_alloc_storage = xm_surface_alloc_storage; + ws->base.surface_release = xm_surface_release; + + ws->base.flush_frontbuffer = xm_flush_frontbuffer; + ws->base.printf = xm_printf; + ws->base.get_name = xm_get_name; } - return ws; + return &ws->base; } @@ -445,27 +648,27 @@ xmesa_get_softpipe_winsys(uint pixelformat) struct pipe_context * xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) { - struct pipe_winsys *pws = xmesa_get_pipe_winsys_aub(); + struct pipe_winsys *pws = xmesa_get_pipe_winsys_aub(xmesa->xm_visual); struct pipe_context *pipe; #ifdef GALLIUM_CELL if (!getenv("GALLIUM_NOCELL")) { struct cell_winsys *cws = cell_get_winsys(pixelformat); struct pipe_screen *screen = cell_create_screen(pws); + pipe = cell_create_context(screen, cws); - if (pipe) - pipe->priv = xmesa; - return pipe; } else #endif { struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat); struct pipe_screen *screen = softpipe_create_screen(pws); - pipe = softpipe_create( screen, pws, spws ); - if (pipe) - pipe->priv = xmesa; - return pipe; + pipe = softpipe_create(screen, pws, spws); } + + if (pipe) + pipe->priv = xmesa; + + return pipe; } diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.h b/src/gallium/winsys/xlib/xm_winsys_aub.h index 7bee199116..cc2a755277 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.h +++ b/src/gallium/winsys/xlib/xm_winsys_aub.h @@ -62,6 +62,7 @@ void xmesa_commands_aub(struct pipe_winsys *winsys, void xmesa_display_aub( /* struct pipe_winsys *winsys, */ struct pipe_surface *surface ); -struct pipe_winsys *xmesa_get_pipe_winsys_aub(void); +extern struct pipe_winsys * +xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis); #endif diff --git a/src/gallium/winsys/xlib/xmesaP.h b/src/gallium/winsys/xlib/xmesaP.h index fa8d1f14b9..9b15b2ddf9 100644 --- a/src/gallium/winsys/xlib/xmesaP.h +++ b/src/gallium/winsys/xlib/xmesaP.h @@ -173,4 +173,7 @@ xmesa_buffer_height(XMesaBuffer b) extern void xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf); +extern int +xmesa_check_for_xshm(XMesaDisplay *display); + #endif -- cgit v1.2.3 From 9f7cd571e01569abd0898fdee62d0e0f946bf3a8 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 25 Mar 2008 19:18:56 -0600 Subject: gallium: added fragment emit/write debug counters --- src/gallium/drivers/softpipe/sp_prim_setup.c | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 6a81e4d8cc..c7eb12b3bb 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -44,6 +44,7 @@ #include "pipe/p_shader_tokens.h" #define DEBUG_VERTS 0 +#define DEBUG_FRAGS 0 /** * Triangle edge info @@ -92,6 +93,11 @@ struct setup_stage { unsigned y_flags; unsigned mask; /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */ } span; + +#if DEBUG_FRAGS + uint numFragsEmitted; /**< per primitive */ + uint numFragsWritten; /**< per primitive */ +#endif }; @@ -160,7 +166,20 @@ emit_quad( struct setup_stage *setup, int x, int y, unsigned mask ) setup->quad.x0 = x; setup->quad.y0 = y; setup->quad.mask = mask; +#if DEBUG_FRAGS + if (mask & 1) setup->numFragsEmitted++; + if (mask & 2) setup->numFragsEmitted++; + if (mask & 4) setup->numFragsEmitted++; + if (mask & 8) setup->numFragsEmitted++; +#endif sp->quad.first->run(sp->quad.first, &setup->quad); +#if DEBUG_FRAGS + mask = setup->quad.mask; + if (mask & 1) setup->numFragsWritten++; + if (mask & 2) setup->numFragsWritten++; + if (mask & 4) setup->numFragsWritten++; + if (mask & 8) setup->numFragsWritten++; +#endif } @@ -674,6 +693,11 @@ static void setup_tri( struct draw_stage *stage, debug_printf("%s\n", __FUNCTION__ ); */ +#if DEBUG_FRAGS + setup->numFragsEmitted = 0; + setup->numFragsWritten = 0; +#endif + setup_sort_vertices( setup, prim ); setup_tri_coefficients( setup ); setup_tri_edges( setup ); @@ -702,6 +726,12 @@ static void setup_tri( struct draw_stage *stage, } flush_spans( setup ); + +#if DEBUG_FRAGS + printf("Tri: %u frags emitted, %u written\n", + setup->numFragsEmitted, + setup->numFragsWritten); +#endif } -- cgit v1.2.3 From e55dccd0bfc41dbcf306f864c01758f8e28fc660 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 25 Mar 2008 19:19:14 -0600 Subject: gallium: the generic attrib we use for computing coverage is per-shader Fixes a very tricky conformance failure. --- src/gallium/auxiliary/draw/draw_aapoint.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c index 67a7a8ebab..fcebe3e7a0 100644 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -68,6 +68,7 @@ struct aapoint_fragment_shader struct pipe_shader_state state; void *driver_fs; /**< the regular shader */ void *aapoint_fs; /**< the aa point-augmented shader */ + int generic_attrib; /**< The generic input attrib/texcoord we'll use */ }; @@ -486,7 +487,6 @@ static void generate_aapoint_fs(struct aapoint_stage *aapoint) { const struct pipe_shader_state *orig_fs = &aapoint->fs->state; - struct draw_context *draw = aapoint->stage.draw; struct pipe_shader_state aapoint_fs; struct aa_transform_context transform; @@ -510,18 +510,16 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) MAX, &transform.base); #if 0 /* DEBUG */ + printf("draw_aapoint, orig shader:\n"); tgsi_dump(orig_fs->tokens, 0); + printf("draw_aapoint, new shader:\n"); tgsi_dump(aapoint_fs.tokens, 0); #endif aapoint->fs->aapoint_fs = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs); - /* advertise the extra post-transform vertex attributes which will have - * the texcoords. - */ - draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; - draw->extra_vp_outputs.semantic_index = transform.maxGeneric + 1; + aapoint->fs->generic_attrib = transform.maxGeneric + 1; } @@ -675,15 +673,19 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header) else aapoint->radius = 0.5f * draw->rasterizer->point_size; - aapoint->tex_slot = draw->num_vs_outputs; - assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ - draw->extra_vp_outputs.slot = aapoint->tex_slot; - /* - * Bind our fragprog. + * Bind (generate) our fragprog. */ bind_aapoint_fragment_shader(aapoint); + /* update vertex attrib info */ + aapoint->tex_slot = draw->num_vs_outputs; + assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ + + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; + draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib; + draw->extra_vp_outputs.slot = aapoint->tex_slot; + /* find psize slot in post-transform vertex */ aapoint->psize_slot = -1; if (draw->rasterizer->point_size_per_vertex) { -- cgit v1.2.3 From 4abe1eb980ed76d2b2d3383eaab520d0aa2ae6f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 26 Mar 2008 09:36:40 +0000 Subject: gallium: Change pipe->flush() interface to optionally return a fence. The cell driver still uses an internal CELL_FLUSH_WAIT flag, in the long run proper fencing should be implemented for it. --- src/gallium/auxiliary/util/u_gen_mipmap.c | 2 +- src/gallium/drivers/cell/ppu/cell_flush.c | 15 ++++++++--- src/gallium/drivers/cell/ppu/cell_flush.h | 5 +++- src/gallium/drivers/cell/ppu/cell_vbuf.c | 2 +- src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 2 +- src/gallium/drivers/failover/fo_context.c | 4 +-- src/gallium/drivers/i915simple/i915_batch.h | 4 +-- src/gallium/drivers/i915simple/i915_blit.c | 4 +-- src/gallium/drivers/i915simple/i915_flush.c | 14 +++------- src/gallium/drivers/i915simple/i915_prim_emit.c | 2 +- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 2 +- src/gallium/drivers/i915simple/i915_state_emit.c | 2 +- src/gallium/drivers/i915simple/i915_winsys.h | 5 ++-- src/gallium/drivers/i965simple/brw_flush.c | 13 +++------- src/gallium/drivers/softpipe/sp_flush.c | 10 ++++---- src/gallium/drivers/softpipe/sp_flush.h | 4 ++- src/gallium/include/pipe/p_context.h | 5 ++-- src/gallium/include/pipe/p_defines.h | 3 +-- src/gallium/winsys/dri/intel/intel_context.c | 4 +-- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 25 ++++++++++-------- src/gallium/winsys/xlib/xm_winsys.c | 31 +++++++++++++++++++++++ 21 files changed, 97 insertions(+), 61 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index e129c062be..ed12768e7f 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -935,7 +935,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, 4, /* verts */ 2); /* attribs/vert */ - pipe->flush(pipe, PIPE_FLUSH_WAIT); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* need to signal that the texture has changed _after_ rendering to it */ pipe->texture_update(pipe, pt, face, (1 << dstLevel)); diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c index 66a5627d84..3aaf3de668 100644 --- a/src/gallium/drivers/cell/ppu/cell_flush.c +++ b/src/gallium/drivers/cell/ppu/cell_flush.c @@ -35,12 +35,19 @@ void -cell_flush(struct pipe_context *pipe, unsigned flags) +cell_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) { struct cell_context *cell = cell_context(pipe); + if (fence) { + *fence = NULL; + /* XXX: Implement real fencing */ + flags |= CELL_FLUSH_WAIT; + } + if (flags & PIPE_FLUSH_SWAPBUFFERS) - flags |= PIPE_FLUSH_WAIT; + flags |= CELL_FLUSH_WAIT; draw_flush( cell->draw ); cell_flush_int(pipe, flags); @@ -58,7 +65,7 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags) ASSERT(!flushing); flushing = TRUE; - if (flags & PIPE_FLUSH_WAIT) { + if (flags & CELL_FLUSH_WAIT) { uint64_t *cmd = (uint64_t *) cell_batch_alloc(cell, sizeof(uint64_t)); *cmd = CELL_CMD_FINISH; } @@ -72,7 +79,7 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags) } #endif - if (flags & PIPE_FLUSH_WAIT) { + if (flags & CELL_FLUSH_WAIT) { /* Wait for ack */ for (i = 0; i < cell->num_spus; i++) { uint k = wait_mbox_message(cell_global.spe_contexts[i]); diff --git a/src/gallium/drivers/cell/ppu/cell_flush.h b/src/gallium/drivers/cell/ppu/cell_flush.h index 7f940ae76b..8f0645c429 100644 --- a/src/gallium/drivers/cell/ppu/cell_flush.h +++ b/src/gallium/drivers/cell/ppu/cell_flush.h @@ -29,8 +29,11 @@ #ifndef CELL_FLUSH #define CELL_FLUSH +#define CELL_FLUSH_WAIT 0x80000000 + extern void -cell_flush(struct pipe_context *pipe, unsigned flags); +cell_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence); extern void cell_flush_int(struct pipe_context *pipe, unsigned flags); diff --git a/src/gallium/drivers/cell/ppu/cell_vbuf.c b/src/gallium/drivers/cell/ppu/cell_vbuf.c index cc727ff4ed..3a181b585c 100644 --- a/src/gallium/drivers/cell/ppu/cell_vbuf.c +++ b/src/gallium/drivers/cell/ppu/cell_vbuf.c @@ -243,7 +243,7 @@ cell_vbuf_draw(struct vbuf_render *vbr, #if 0 /* helpful for debug */ - cell_flush_int(&cell->pipe, PIPE_FLUSH_WAIT); + cell_flush_int(&cell->pipe, CELL_FLUSH_WAIT); #endif } diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index f5c27852c1..b418857ccd 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -133,7 +133,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) vs->num_elts = n; send_mbox_message(cell_global.spe_contexts[0], CELL_CMD_VS_EXECUTE); - cell_flush_int(& cell->pipe, PIPE_FLUSH_WAIT); + cell_flush_int(& cell->pipe, CELL_FLUSH_WAIT); } draw->vs.post_nr = draw->vs.queue_nr; diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index afc0d7eb1e..cb95ba516f 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -69,7 +69,7 @@ static boolean failover_draw_elements( struct pipe_context *pipe, start, count )) { - failover->hw->flush( failover->hw, ~0 ); + failover->hw->flush( failover->hw, ~0, NULL ); failover->mode = FO_SW; } } @@ -92,7 +92,7 @@ static boolean failover_draw_elements( struct pipe_context *pipe, * intervening flush. Unlikely to be much performance impact to * this: */ - failover->sw->flush( failover->sw, ~0 ); + failover->sw->flush( failover->sw, ~0, NULL ); } return TRUE; diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h index fb88cd6db0..4ea06ce02b 100644 --- a/src/gallium/drivers/i915simple/i915_batch.h +++ b/src/gallium/drivers/i915simple/i915_batch.h @@ -44,9 +44,9 @@ #define ADVANCE_BATCH() -#define FLUSH_BATCH() do { \ +#define FLUSH_BATCH(fence) do { \ if (0) i915_dump_batchbuffer( i915 ); \ - i915->winsys->batch_flush( i915->winsys ); \ + i915->winsys->batch_flush( i915->winsys, fence ); \ i915->batch_start = NULL; \ i915->hardware_dirty = ~0; \ } while (0) diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c index db4671ff55..24449e3fb3 100644 --- a/src/gallium/drivers/i915simple/i915_blit.c +++ b/src/gallium/drivers/i915simple/i915_blit.c @@ -70,7 +70,7 @@ i915_fill_blit(struct i915_context *i915, if (!BEGIN_BATCH(6, 1)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(6, 1)); } OUT_BATCH(CMD); @@ -145,7 +145,7 @@ i915_copy_blit( struct i915_context *i915, if (!BEGIN_BATCH(8, 2)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(8, 2)); } OUT_BATCH(CMD); diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c index 96a54281f1..7d23e6b6b9 100644 --- a/src/gallium/drivers/i915simple/i915_flush.c +++ b/src/gallium/drivers/i915simple/i915_flush.c @@ -37,11 +37,9 @@ #include "i915_batch.h" -/** - * In future we may want a fence-like interface instead of finish. - */ static void i915_flush( struct pipe_context *pipe, - unsigned flags ) + unsigned flags, + struct pipe_fence_handle **fence ) { struct i915_context *i915 = i915_context(pipe); @@ -60,7 +58,7 @@ static void i915_flush( struct pipe_context *pipe, flush |= FLUSH_MAP_CACHE; if (!BEGIN_BATCH(1, 0)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(1, 0)); } OUT_BATCH( flush ); @@ -69,11 +67,7 @@ static void i915_flush( struct pipe_context *pipe, /* If there are no flags, just flush pending commands to hardware: */ - FLUSH_BATCH(); - - if (flags & PIPE_FLUSH_WAIT) { - i915->winsys->batch_finish(i915->winsys); - } + FLUSH_BATCH(fence); } diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c index d8de5178f6..b6fb0a6d88 100644 --- a/src/gallium/drivers/i915simple/i915_prim_emit.c +++ b/src/gallium/drivers/i915simple/i915_prim_emit.c @@ -140,7 +140,7 @@ emit_prim( struct draw_stage *stage, assert(vertex_size >= 12); /* never smaller than 12 bytes */ if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); /* Make sure state is re-emitted after a flush: */ diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index eb64f51943..7fb2adbb53 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -161,7 +161,7 @@ i915_vbuf_render_draw( struct vbuf_render *render, i915_emit_hardware_state( i915 ); if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); /* Make sure state is re-emitted after a flush: */ diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index a7498d22b7..6f947d4346 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -115,7 +115,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) #endif if(!BEGIN_BATCH(dwords, relocs)) { - FLUSH_BATCH(); + FLUSH_BATCH(NULL); assert(BEGIN_BATCH(dwords, relocs)); } diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h index aea3003281..5e16543f4e 100644 --- a/src/gallium/drivers/i915simple/i915_winsys.h +++ b/src/gallium/drivers/i915simple/i915_winsys.h @@ -56,6 +56,7 @@ extern "C" { */ struct pipe_buffer; +struct pipe_fence_handle; struct pipe_winsys; struct pipe_screen; @@ -103,8 +104,8 @@ struct i915_winsys { unsigned access_flags, unsigned delta ); - void (*batch_flush)( struct i915_winsys *sws ); - void (*batch_finish)( struct i915_winsys *sws ); + void (*batch_flush)( struct i915_winsys *sws, + struct pipe_fence_handle **fence ); }; #define I915_BUFFER_ACCESS_WRITE 0x1 diff --git a/src/gallium/drivers/i965simple/brw_flush.c b/src/gallium/drivers/i965simple/brw_flush.c index 5216c680cf..e6001c30d9 100644 --- a/src/gallium/drivers/i965simple/brw_flush.c +++ b/src/gallium/drivers/i965simple/brw_flush.c @@ -36,14 +36,11 @@ #include "brw_batch.h" -/** - * In future we may want a fence-like interface instead of finish. - */ static void brw_flush( struct pipe_context *pipe, - unsigned flags ) + unsigned flags, + struct pipe_fence_handle **fence ) { struct brw_context *brw = brw_context(pipe); - struct pipe_fence_handle *fence; /* Do we need to emit an MI_FLUSH command to flush the hardware * caches? @@ -65,11 +62,7 @@ static void brw_flush( struct pipe_context *pipe, /* If there are no flags, just flush pending commands to hardware: */ - FLUSH_BATCH( &fence ); - - if (flags & PIPE_FLUSH_WAIT) { -// brw->winsys->wait_fence(brw->winsys, fence); - } + FLUSH_BATCH( fence ); } diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 2cbd0d7cab..0625b69099 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -40,13 +40,10 @@ #include "sp_winsys.h" -/* There will be actual work to do here. In future we may want a - * fence-like interface instead of finish, and perhaps flush will take - * flags to indicate what type of flush is required. - */ void softpipe_flush( struct pipe_context *pipe, - unsigned flags ) + unsigned flags, + struct pipe_fence_handle **fence ) { struct softpipe_context *softpipe = softpipe_context(pipe); uint i; @@ -72,5 +69,8 @@ softpipe_flush( struct pipe_context *pipe, * to unmap surfaces when flushing. */ softpipe_unmap_surfaces(softpipe); + + if (fence) + *fence = NULL; } diff --git a/src/gallium/drivers/softpipe/sp_flush.h b/src/gallium/drivers/softpipe/sp_flush.h index 34ec617866..68d9b5fa83 100644 --- a/src/gallium/drivers/softpipe/sp_flush.h +++ b/src/gallium/drivers/softpipe/sp_flush.h @@ -29,7 +29,9 @@ #define SP_FLUSH_H struct pipe_context; +struct pipe_fence_handle; -void softpipe_flush(struct pipe_context *pipe, unsigned flags ); +void softpipe_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence); #endif diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index a3824601be..b2e49bef4c 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -37,7 +37,7 @@ extern "C" { struct pipe_screen; - +struct pipe_fence_handle; struct pipe_state_cache; /* Opaque driver handles: @@ -202,7 +202,8 @@ struct pipe_context { /* Flush rendering: */ void (*flush)( struct pipe_context *pipe, - unsigned flags ); + unsigned flags, + struct pipe_fence_handle **fence ); }; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index bc938ba253..586951d956 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -201,8 +201,7 @@ enum pipe_texture_target { */ #define PIPE_FLUSH_RENDER_CACHE 0x1 #define PIPE_FLUSH_TEXTURE_CACHE 0x2 -#define PIPE_FLUSH_WAIT 0x4 -#define PIPE_FLUSH_SWAPBUFFERS 0x8 +#define PIPE_FLUSH_SWAPBUFFERS 0x4 /** diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 79b320c6bf..8eba33c313 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -228,7 +228,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) assert(intel); /* should never be null */ if (intel) { - st_flush(intel->st, PIPE_FLUSH_WAIT); + st_finish(intel->st); intel_batchbuffer_free(intel->batch); @@ -256,7 +256,7 @@ GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv) { struct intel_context *intel = intel_context(driContextPriv); - st_flush(intel->st, 0x0); + st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); /* XXX make_current(NULL)? */ return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index 2def1afc31..4d183db7c3 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -39,12 +39,14 @@ #include "intel_winsys.h" #include "pipe/p_util.h" +#include "pipe/p_winsys.h" #include "i915simple/i915_winsys.h" #include "i915simple/i915_screen.h" struct intel_i915_winsys { struct i915_winsys winsys; /**< batch buffer funcs */ + struct pipe_winsys *pws; struct intel_context *intel; }; @@ -112,19 +114,22 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws, -static void intel_i915_batch_flush( struct i915_winsys *sws ) +static void intel_i915_batch_flush( struct i915_winsys *sws, + struct pipe_fence_handle **fence ) { - struct intel_context *intel = intel_i915_winsys(sws)->intel; + struct intel_i915_winsys *iws = intel_i915_winsys(sws); + struct intel_context *intel = iws->intel; + union { + struct _DriFenceObject *dri; + struct pipe_fence_handle *pipe; + } fu; - intel_batchbuffer_flush( intel->batch ); -// if (0) intel_i915_batch_wait_idle( sws ); -} + fu.dri = intel_batchbuffer_flush( intel->batch ); + if (fu.dri) + iws->pws->fence_reference(iws->pws, fence, fu.pipe); -static void intel_i915_batch_finish( struct i915_winsys *sws ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - intel_batchbuffer_finish( intel->batch ); +// if (0) intel_i915_batch_wait_idle( sws ); } @@ -145,7 +150,7 @@ intel_create_i915simple( struct intel_context *intel, iws->winsys.batch_dword = intel_i915_batch_dword; iws->winsys.batch_reloc = intel_i915_batch_reloc; iws->winsys.batch_flush = intel_i915_batch_flush; - iws->winsys.batch_finish = intel_i915_batch_finish; + iws->pws = winsys; iws->intel = intel; screen = i915_create_screen(winsys, intel->intelScreen->deviceID); diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 7baaae295c..c930a1d196 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -570,6 +570,33 @@ xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) } +/* + * Fence functions - basically nothing to do, as we don't create any actual + * fence objects. + */ + +static void +xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + /** * Return pointer to a pipe_winsys object. @@ -603,6 +630,10 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) ws->base.surface_alloc_storage = xm_surface_alloc_storage; ws->base.surface_release = xm_surface_release; + ws->fence_reference = xm_fence_reference; + ws->fence_signalled = xm_fence_signalled; + ws->fence_finish = xm_fence_finish; + ws->base.flush_frontbuffer = xm_flush_frontbuffer; ws->base.printf = xm_printf; ws->base.get_name = xm_get_name; -- cgit v1.2.3 From 8cb85807d3bd42cb0e511970e4b409c542d2716b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 26 Mar 2008 08:21:17 -0600 Subject: gallium: as for aapoints, make the extra texcoord per-shader state --- src/gallium/auxiliary/draw/draw_aaline.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index a999ef1227..e8d2a45102 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -62,6 +62,7 @@ struct aaline_fragment_shader void *aapoint_fs; /* not yet */ void *sprite_fs; /* not yet */ uint sampler_unit; + int generic_attrib; /**< texcoord/generic used for texture */ }; @@ -336,7 +337,7 @@ static void generate_aaline_fs(struct aaline_stage *aaline) { const struct pipe_shader_state *orig_fs = &aaline->fs->state; - struct draw_context *draw = aaline->stage.draw; + //struct draw_context *draw = aaline->stage.draw; struct pipe_shader_state aaline_fs; struct aa_transform_context transform; @@ -369,11 +370,7 @@ generate_aaline_fs(struct aaline_stage *aaline) aaline->fs->aaline_fs = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); - /* advertise the extra post-transform vertex attributes which will have - * the texcoords. - */ - draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; - draw->extra_vp_outputs.semantic_index = transform.maxGeneric + 1; + aaline->fs->generic_attrib = transform.maxGeneric + 1; } @@ -637,15 +634,20 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) else aaline->half_line_width = 0.5f * draw->rasterizer->line_width; - aaline->tex_slot = draw->num_vs_outputs; - assert(aaline->tex_slot > 0); /* output[0] is vertex pos */ - draw->extra_vp_outputs.slot = aaline->tex_slot; - /* - * Bind our fragprog, sampler and texture + * Bind (generate) our fragprog, sampler and texture */ bind_aaline_fragment_shader(aaline); + /* update vertex attrib info */ + aaline->tex_slot = draw->num_vs_outputs; + assert(aaline->tex_slot > 0); /* output[0] is vertex pos */ + + /* advertise the extra post-transformed vertex attribute */ + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; + draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib; + draw->extra_vp_outputs.slot = aaline->tex_slot; + /* how many samplers? */ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ num_samplers = MAX2(aaline->num_textures, aaline->num_samplers); -- cgit v1.2.3 From 92126cea846959bb2152905a7712753d1114bd6b Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 26 Mar 2008 10:45:32 -0700 Subject: cell: Implement code-gen for logic op This also implements code-gen for the float-to-packed color conversion. It's currently hardcoded for A8R8G8B8, but that can easily be fixed as soon as other color depths are supported by the Cell driver. --- src/gallium/drivers/cell/common.h | 11 +- src/gallium/drivers/cell/ppu/cell_context.h | 2 + src/gallium/drivers/cell/ppu/cell_state_emit.c | 17 ++ .../drivers/cell/ppu/cell_state_per_fragment.c | 261 ++++++++++++++++++++- .../drivers/cell/ppu/cell_state_per_fragment.h | 4 + src/gallium/drivers/cell/spu/spu_main.c | 19 ++ src/gallium/drivers/cell/spu/spu_main.h | 9 +- src/gallium/drivers/cell/spu/spu_tri.c | 59 +++-- 8 files changed, 349 insertions(+), 33 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index d59e4f7036..b0928fefd2 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -92,8 +92,9 @@ #define CELL_CMD_STATE_BIND_VS 18 #define CELL_CMD_STATE_BLEND 19 #define CELL_CMD_STATE_ATTRIB_FETCH 20 -#define CELL_CMD_VS_EXECUTE 21 -#define CELL_CMD_FLUSH_BUFFER_RANGE 22 +#define CELL_CMD_STATE_LOGICOP 21 +#define CELL_CMD_VS_EXECUTE 22 +#define CELL_CMD_FLUSH_BUFFER_RANGE 23 #define CELL_NUM_BUFFERS 4 @@ -124,6 +125,12 @@ struct cell_command_blend { }; +struct cell_command_logicop { + uint64_t base; /**< Effective address of code start. */ + unsigned size; /**< Size in bytes of test code. */ +}; + + /** * Tell SPUs about the framebuffer size, location */ diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 9e79db0ace..0442abddc1 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -92,6 +92,8 @@ struct cell_context const struct cell_vertex_shader_state *vs; const struct cell_fragment_shader_state *fs; + struct spe_function logic_op; + struct pipe_blend_color blend_color; struct pipe_clip_state clip; struct pipe_constant_buffer constants[2]; diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 5709b48f12..5c1310d0b0 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -50,6 +50,23 @@ emit_state_cmd(struct cell_context *cell, uint cmd, void cell_emit_state(struct cell_context *cell) { + if (cell->dirty & (CELL_NEW_FRAMEBUFFER | CELL_NEW_BLEND)) { + struct cell_command_logicop logicop; + + if (cell->logic_op.store != NULL) { + spe_release_func(& cell->logic_op); + } + + cell_generate_logic_op(& cell->logic_op, + & cell->blend->base, + cell->framebuffer.cbufs[0]); + + logicop.base = (intptr_t) cell->logic_op.store; + logicop.size = 64 * 4; + emit_state_cmd(cell, CELL_CMD_STATE_LOGICOP, &logicop, + sizeof(logicop)); + } + if (cell->dirty & CELL_NEW_FRAMEBUFFER) { struct pipe_surface *cbuf = cell->framebuffer.cbufs[0]; struct pipe_surface *zbuf = cell->framebuffer.zsbuf; diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index c750b1d89d..f10025bd7c 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -977,7 +977,6 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) spe_allocate_register(f, 13), spe_allocate_register(f, 14), }; - const int mask = spe_allocate_register(f, 15); unsigned func[4]; unsigned sF[4]; unsigned dF[4]; @@ -1114,9 +1113,6 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) func[i], sF[i], dF[i], frag[i], src_factor[i], pixel[i], dst_factor[i]); - spe_selb(f, frag[i], pixel[i], frag[i], mask); - } else { - spe_or(f, frag[i], pixel[i], pixel[i]); } } @@ -1146,3 +1142,260 @@ cell_generate_alpha_blend(struct cell_blend_state *cb) } #endif } + + +int PC_OFFSET(const struct spe_function *f, const void *d) +{ + const intptr_t pc = (intptr_t) f->csr; + const intptr_t ea = ~0x0f & (intptr_t) d; + + return (ea - pc) >> 2; +} + + +/** + * Generate code to perform color conversion and logic op + * + * \bug + * The code generated by this function should also perform dithering. + * + * \bug + * The code generated by this function should also perform color-write + * masking. + * + * \bug + * This routine is hard-coded to only work with ARGB8 data. + */ +void +cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend, + struct pipe_surface *surf) +{ + const unsigned logic_op = (blend->logicop_enable) + ? blend->logicop_func : PIPE_LOGICOP_COPY; + + /* This code generates a maximum of 37 instructions. An additional 32 + * bytes (equiv. to 8 instructions) are needed for data storage. Round up + * to 64 to make it a happy power-of-two. + */ + spe_init_func(f, 4 * 64); + + + /* Pixel colors in framebuffer format in AoS layout. + */ + const int pixel[4] = { + spe_allocate_register(f, 3), + spe_allocate_register(f, 4), + spe_allocate_register(f, 5), + spe_allocate_register(f, 6), + }; + + /* Fragment colors stored as floats in SoA layout. + */ + const int frag[4] = { + spe_allocate_register(f, 7), + spe_allocate_register(f, 8), + spe_allocate_register(f, 9), + spe_allocate_register(f, 10), + }; + + const int mask = spe_allocate_register(f, 11); + + + /* Short-circuit the noop and invert cases. + */ + if ((logic_op == PIPE_LOGICOP_NOOP) || (blend->colormask == 0)) { + spe_bi(f, 0, 0, 0); + return; + } else if (logic_op == PIPE_LOGICOP_INVERT) { + spe_nor(f, pixel[0], pixel[0], pixel[0]); + spe_nor(f, pixel[1], pixel[1], pixel[1]); + spe_nor(f, pixel[2], pixel[2], pixel[2]); + spe_nor(f, pixel[3], pixel[3], pixel[3]); + spe_bi(f, 0, 0, 0); + return; + } + + + const int tmp[4] = { + spe_allocate_available_register(f), + spe_allocate_available_register(f), + spe_allocate_available_register(f), + spe_allocate_available_register(f), + }; + + const int shuf_xpose_hi = spe_allocate_available_register(f); + const int shuf_xpose_lo = spe_allocate_available_register(f); + const int shuf_color = spe_allocate_available_register(f); + + + /* Pointer to the begining of the function's private data area. + */ + uint32_t *const data = ((uint32_t *) f->store) + (64 - 8); + + + /* Convert fragment colors to framebuffer format in AoS layout. + */ + data[0] = 0x00010203; + data[1] = 0x10111213; + data[2] = 0x04050607; + data[3] = 0x14151617; + + data[4] = 0x0c000408; + data[5] = 0x80808080; + data[6] = 0x80808080; + data[7] = 0x80808080; + + spe_ilh(f, tmp[0], 0x0808); + spe_lqr(f, shuf_xpose_hi, PC_OFFSET(f, data+0)); + spe_lqr(f, shuf_color, PC_OFFSET(f, data+4)); + spe_a(f, shuf_xpose_lo, shuf_xpose_hi, tmp[0]); + + spe_shufb(f, tmp[0], frag[0], frag[2], shuf_xpose_hi); + spe_shufb(f, tmp[1], frag[0], frag[2], shuf_xpose_lo); + spe_shufb(f, tmp[2], frag[1], frag[3], shuf_xpose_hi); + spe_shufb(f, tmp[3], frag[1], frag[3], shuf_xpose_lo); + + spe_shufb(f, frag[0], tmp[0], tmp[2], shuf_xpose_hi); + spe_shufb(f, frag[1], tmp[0], tmp[2], shuf_xpose_lo); + spe_shufb(f, frag[2], tmp[1], tmp[3], shuf_xpose_hi); + spe_shufb(f, frag[3], tmp[1], tmp[3], shuf_xpose_lo); + + spe_cfltu(f, frag[0], frag[0], 32); + spe_cfltu(f, frag[1], frag[1], 32); + spe_cfltu(f, frag[2], frag[2], 32); + spe_cfltu(f, frag[3], frag[3], 32); + + spe_shufb(f, frag[0], frag[0], pixel[0], shuf_color); + spe_shufb(f, frag[1], frag[1], pixel[1], shuf_color); + spe_shufb(f, frag[2], frag[2], pixel[2], shuf_color); + spe_shufb(f, frag[3], frag[3], pixel[3], shuf_color); + + + /* If logic op is enabled, perform the requested logical operation on the + * converted fragment colors and the pixel colors. + */ + switch (logic_op) { + case PIPE_LOGICOP_CLEAR: + spe_il(f, frag[0], 0); + spe_il(f, frag[1], 0); + spe_il(f, frag[2], 0); + spe_il(f, frag[3], 0); + break; + case PIPE_LOGICOP_NOR: + spe_nor(f, frag[0], frag[0], pixel[0]); + spe_nor(f, frag[1], frag[1], pixel[1]); + spe_nor(f, frag[2], frag[2], pixel[2]); + spe_nor(f, frag[3], frag[3], pixel[3]); + break; + case PIPE_LOGICOP_AND_INVERTED: + spe_andc(f, frag[0], pixel[0], frag[0]); + spe_andc(f, frag[1], pixel[1], frag[1]); + spe_andc(f, frag[2], pixel[2], frag[2]); + spe_andc(f, frag[3], pixel[3], frag[3]); + break; + case PIPE_LOGICOP_COPY_INVERTED: + spe_nor(f, frag[0], frag[0], frag[0]); + spe_nor(f, frag[1], frag[1], frag[1]); + spe_nor(f, frag[2], frag[2], frag[2]); + spe_nor(f, frag[3], frag[3], frag[3]); + break; + case PIPE_LOGICOP_AND_REVERSE: + spe_andc(f, frag[0], frag[0], pixel[0]); + spe_andc(f, frag[1], frag[1], pixel[1]); + spe_andc(f, frag[2], frag[2], pixel[2]); + spe_andc(f, frag[3], frag[3], pixel[3]); + break; + case PIPE_LOGICOP_XOR: + spe_xor(f, frag[0], frag[0], pixel[0]); + spe_xor(f, frag[1], frag[1], pixel[1]); + spe_xor(f, frag[2], frag[2], pixel[2]); + spe_xor(f, frag[3], frag[3], pixel[3]); + break; + case PIPE_LOGICOP_NAND: + spe_nand(f, frag[0], frag[0], pixel[0]); + spe_nand(f, frag[1], frag[1], pixel[1]); + spe_nand(f, frag[2], frag[2], pixel[2]); + spe_nand(f, frag[3], frag[3], pixel[3]); + break; + case PIPE_LOGICOP_AND: + spe_and(f, frag[0], frag[0], pixel[0]); + spe_and(f, frag[1], frag[1], pixel[1]); + spe_and(f, frag[2], frag[2], pixel[2]); + spe_and(f, frag[3], frag[3], pixel[3]); + break; + case PIPE_LOGICOP_EQUIV: + spe_eqv(f, frag[0], frag[0], pixel[0]); + spe_eqv(f, frag[1], frag[1], pixel[1]); + spe_eqv(f, frag[2], frag[2], pixel[2]); + spe_eqv(f, frag[3], frag[3], pixel[3]); + break; + case PIPE_LOGICOP_OR_INVERTED: + spe_orc(f, frag[0], pixel[0], frag[0]); + spe_orc(f, frag[1], pixel[1], frag[1]); + spe_orc(f, frag[2], pixel[2], frag[2]); + spe_orc(f, frag[3], pixel[3], frag[3]); + break; + case PIPE_LOGICOP_COPY: + break; + case PIPE_LOGICOP_OR_REVERSE: + spe_orc(f, frag[0], frag[0], pixel[0]); + spe_orc(f, frag[1], frag[1], pixel[1]); + spe_orc(f, frag[2], frag[2], pixel[2]); + spe_orc(f, frag[3], frag[3], pixel[3]); + break; + case PIPE_LOGICOP_OR: + spe_or(f, frag[0], frag[0], pixel[0]); + spe_or(f, frag[1], frag[1], pixel[1]); + spe_or(f, frag[2], frag[2], pixel[2]); + spe_or(f, frag[3], frag[3], pixel[3]); + break; + case PIPE_LOGICOP_SET: + spe_il(f, frag[0], ~0); + spe_il(f, frag[1], ~0); + spe_il(f, frag[2], ~0); + spe_il(f, frag[3], ~0); + break; + + /* These two cases are short-circuited above. + */ + case PIPE_LOGICOP_INVERT: + case PIPE_LOGICOP_NOOP: + default: + assert(0); + } + + + /* Apply fragment mask. + */ + spe_ilh(f, tmp[0], 0x0000); + spe_ilh(f, tmp[1], 0x0404); + spe_ilh(f, tmp[2], 0x0808); + spe_ilh(f, tmp[3], 0x0c0c); + + spe_shufb(f, tmp[0], mask, mask, tmp[0]); + spe_shufb(f, tmp[1], mask, mask, tmp[1]); + spe_shufb(f, tmp[2], mask, mask, tmp[2]); + spe_shufb(f, tmp[3], mask, mask, tmp[3]); + + spe_selb(f, pixel[0], pixel[0], frag[0], tmp[0]); + spe_selb(f, pixel[1], pixel[1], frag[1], tmp[1]); + spe_selb(f, pixel[2], pixel[2], frag[2], tmp[2]); + spe_selb(f, pixel[3], pixel[3], frag[3], tmp[3]); + + spe_bi(f, 0, 0, 0); + +#if 0 + { + const uint32_t *p = f->store; + unsigned i; + + printf("# %u instructions\n", f->csr - f->store); + + printf("\t.text\n"); + for (i = 0; i < 64; i++) { + printf("\t.long\t0x%04x\n", p[i]); + } + fflush(stdout); + } +#endif +} diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h index f699247f9e..ab4de96c69 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h @@ -31,4 +31,8 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa); extern void cell_generate_alpha_blend(struct cell_blend_state *cb); +extern void +cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend, + struct pipe_surface *surf); + #endif /* CELL_STATE_PER_FRAGMENT_H */ diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 0a490ab277..fccff01e10 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -64,6 +64,9 @@ static unsigned char depth_stencil_code_buffer[4 * 64] static unsigned char fb_blend_code_buffer[4 * 64] ALIGN16_ATTRIB; +static unsigned char logicop_code_buffer[4 * 64] + ALIGN16_ATTRIB; + /** * Tell the PPU that this SPU has finished copying a buffer to @@ -513,6 +516,22 @@ cmd_batch(uint opcode) pos += (1 + ROUNDUP8(sizeof(struct cell_attribute_fetch_code)) / 8); break; } + case CELL_CMD_STATE_LOGICOP: { + struct cell_command_logicop *code = + (struct cell_command_logicop *) &buffer[pos+1]; + + mfc_get(logicop_code_buffer, + (unsigned int) code->base, /* src */ + code->size, + TAG_BATCH_BUFFER, + 0, /* tid */ + 0 /* rid */); + wait_on_mask(1 << TAG_BATCH_BUFFER); + + spu.logicop = (logicop_func) logicop_code_buffer; + pos += (1 + ROUNDUP8(sizeof(struct cell_command_logicop)) / 8); + break; + } case CELL_CMD_FLUSH_BUFFER_RANGE: { struct cell_buffer_range *br = (struct cell_buffer_range *) &buffer[pos+1]; diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index 49f5d99674..c20452931a 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -77,9 +77,14 @@ struct spu_blend_results { typedef struct spu_blend_results (*blend_func)( qword frag_r, qword frag_g, qword frag_b, qword frag_a, qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a, - qword const_r, qword const_g, qword const_b, qword const_a, + qword const_r, qword const_g, qword const_b, qword const_a); + +typedef struct spu_blend_results (*logicop_func)( + qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a, + qword frag_r, qword frag_g, qword frag_b, qword frag_a, qword frag_mask); + struct spu_framebuffer { void *color_start; /**< addr of color surface in main memory */ void *depth_start; /**< addr of depth surface in main memory */ @@ -111,6 +116,8 @@ struct spu_global blend_func blend; qword const_blend_color[4] ALIGN16_ATTRIB; + logicop_func logicop; + struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; struct cell_command_texture texture; diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index e6a1ce01df..95c629a8aa 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -305,7 +305,6 @@ emit_quad( int x, int y, mask_t mask ) if (spu_extract(spu_orx(mask), 0)) { const int ix = x - setup.cliprect_minx; const int iy = y - setup.cliprect_miny; - const vector unsigned char shuffle = spu.color_shuffle; vector float colors[4]; spu.cur_ctile_status = TILE_STATUS_DIRTY; @@ -330,45 +329,53 @@ emit_quad( int x, int y, mask_t mask ) } + /* Convert fragment data from AoS to SoA format. + */ + qword soa_frag[4]; + _transpose_matrix4x4((vec_float4 *) soa_frag, colors); + /* Read the current framebuffer values. - * - * Ignore read_fb for now. In the future we can use this to avoid - * reading the framebuffer if read_fb is false and the fragment mask is - * all 0xffffffff. This is the common case, so it is probably worth - * the effort. We'll have to profile to determine whether or not the - * extra conditional branches hurt overall performance. */ - vec_float4 aos_pix[4] = { - spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+0]), - spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+1]), - spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+0]), - spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+1]), + const qword pix[4] = { + (qword) spu_splats(spu.ctile.ui[iy+0][ix+0]), + (qword) spu_splats(spu.ctile.ui[iy+0][ix+1]), + (qword) spu_splats(spu.ctile.ui[iy+1][ix+0]), + (qword) spu_splats(spu.ctile.ui[iy+1][ix+1]), }; qword soa_pix[4]; - qword soa_frag[4]; - /* Convert pixel and fragment data from AoS to SoA format. - */ - _transpose_matrix4x4((vec_float4 *) soa_pix, aos_pix); - _transpose_matrix4x4((vec_float4 *) soa_frag, colors); + if (spu.read_fb) { + /* Convert pixel data from AoS to SoA format. + */ + vec_float4 aos_pix[4] = { + spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+0]), + spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+1]), + spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+0]), + spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+1]), + }; + + _transpose_matrix4x4((vec_float4 *) soa_pix, aos_pix); + } - const struct spu_blend_results result = + + struct spu_blend_results result = (*spu.blend)(soa_frag[0], soa_frag[1], soa_frag[2], soa_frag[3], soa_pix[0], soa_pix[1], soa_pix[2], soa_pix[3], spu.const_blend_color[0], spu.const_blend_color[1], - spu.const_blend_color[2], spu.const_blend_color[3], - (qword) mask); + spu.const_blend_color[2], spu.const_blend_color[3]); /* Convert final pixel data from SoA to AoS format. */ - _transpose_matrix4x4(aos_pix, (const vec_float4 *) &result); - - spu.ctile.ui[iy+0][ix+0] = spu_pack_color_shuffle(aos_pix[0], shuffle); - spu.ctile.ui[iy+0][ix+1] = spu_pack_color_shuffle(aos_pix[1], shuffle); - spu.ctile.ui[iy+1][ix+0] = spu_pack_color_shuffle(aos_pix[2], shuffle); - spu.ctile.ui[iy+1][ix+1] = spu_pack_color_shuffle(aos_pix[3], shuffle); + result = (*spu.logicop)(pix[0], pix[1], pix[2], pix[3], + result.r, result.g, result.b, result.a, + (qword) mask); + + spu.ctile.ui[iy+0][ix+0] = spu_extract((vec_uint4) result.r, 0); + spu.ctile.ui[iy+0][ix+1] = spu_extract((vec_uint4) result.g, 0); + spu.ctile.ui[iy+1][ix+0] = spu_extract((vec_uint4) result.b, 0); + spu.ctile.ui[iy+1][ix+1] = spu_extract((vec_uint4) result.a, 0); } #endif } -- cgit v1.2.3 From 70659e8ec8ba0c599daa36d9ed81e86efd99eb52 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 26 Mar 2008 10:52:08 -0700 Subject: xlib: Fix build error from recent fence changes --- src/gallium/winsys/xlib/xm_winsys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index c930a1d196..7459756279 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -630,9 +630,9 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) ws->base.surface_alloc_storage = xm_surface_alloc_storage; ws->base.surface_release = xm_surface_release; - ws->fence_reference = xm_fence_reference; - ws->fence_signalled = xm_fence_signalled; - ws->fence_finish = xm_fence_finish; + ws->base.fence_reference = xm_fence_reference; + ws->base.fence_signalled = xm_fence_signalled; + ws->base.fence_finish = xm_fence_finish; ws->base.flush_frontbuffer = xm_flush_frontbuffer; ws->base.printf = xm_printf; -- cgit v1.2.3 From 979358c47115d8ea50001832372f8043a60a5b80 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Mar 2008 15:26:22 -0600 Subject: cell: fix unclosed comment --- src/gallium/drivers/cell/spu/spu_exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 061fbebf61..48edc62f49 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -1453,7 +1453,7 @@ exec_instruction( break; case TGSI_OPCODE_TXP: - /* Texture lookup with projection + /* Texture lookup with projection */ /* src[0] = texcoord (src[0].w = projection) */ /* src[1] = sampler unit */ exec_tex(mach, inst, TRUE, TRUE); -- cgit v1.2.3 From 8b8a947111ad911a986e48a66c9fe31f120de9a2 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Mar 2008 15:26:54 -0600 Subject: cell: added (uint64_t) cast to silence warning --- src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index b418857ccd..f753960a0f 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -69,7 +69,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) batch = cell_batch_alloc(cell, sizeof(batch[0]) + sizeof(*cf)); batch[0] = CELL_CMD_STATE_ATTRIB_FETCH; cf = (struct cell_attribute_fetch_code *) (&batch[1]); - cf->base = cell->attrib_fetch.store; + cf->base = (uint64_t) cell->attrib_fetch.store; cf->size = ROUNDUP16((unsigned)((void *) cell->attrib_fetch.csr - (void *) cell->attrib_fetch.store)); -- cgit v1.2.3 From 132df5ebce8529f7b0999cdd574d70ec0f12a4fd Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Mar 2008 15:27:14 -0600 Subject: cell: include cell_state_per_fragment.h to silence warning --- src/gallium/drivers/cell/ppu/cell_state_emit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 5c1310d0b0..4c75caa025 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -29,6 +29,7 @@ #include "cell_context.h" #include "cell_state.h" #include "cell_state_emit.h" +#include "cell_state_per_fragment.h" #include "cell_batch.h" #include "cell_texture.h" #include "draw/draw_context.h" -- cgit v1.2.3 From d355eee5cacac30e2b4c8ac2f10964e2861a539e Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Mar 2008 15:27:31 -0600 Subject: gallium: silence unused var warning --- src/gallium/include/pipe/p_debug.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 097fc7c0b1..9e52ad9a37 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -90,6 +90,8 @@ debug_printf(const char *format, ...) va_start(ap, format); _debug_vprintf(format, ap); va_end(ap); +#else + (void) format; /* silence warning */ #endif } -- cgit v1.2.3 From df1744c0433f3f73ebf4b06567fefa946a29c3d8 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Mar 2008 15:33:47 -0600 Subject: gallium: remove temporary static var --- src/gallium/auxiliary/draw/draw_prim.c | 11 +++++------ src/gallium/auxiliary/draw/draw_private.h | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index f589d0c017..ddcde01d9a 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -158,15 +158,15 @@ static INLINE void fetch_and_store(struct draw_context *draw) void draw_do_flush( struct draw_context *draw, unsigned flags ) { - static boolean flushing = FALSE; - if (0) debug_printf("Flushing with %d verts, %d prims\n", draw->vs.queue_nr, draw->pq.queue_nr ); - if (!flushing) { - flushing = TRUE; + if (draw->flushing) + return; + + draw->flushing = TRUE; if (flags >= DRAW_FLUSH_SHADER_QUEUE) { if (draw->vs.queue_nr) { @@ -189,8 +189,7 @@ void draw_do_flush( struct draw_context *draw, unsigned flags ) } } - flushing = FALSE; - } + draw->flushing = FALSE; } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 8a879809c3..7007ee22c4 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -223,6 +223,7 @@ struct draw_context } pt; + boolean flushing; /* pipe state that we need: */ const struct pipe_rasterizer_state *rasterizer; -- cgit v1.2.3 From ba49fa39f3028d1ee44a999d84b29a0cfbfab0bd Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Mar 2008 15:35:25 -0600 Subject: gallium: fix incorrect types for shaders --- src/gallium/auxiliary/util/u_blit.c | 5 ++--- src/gallium/auxiliary/util/u_gen_mipmap.c | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 28a404fd01..9986dc3570 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -58,9 +58,8 @@ struct blit_state struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; - /*struct pipe_viewport_state viewport;*/ - struct pipe_sampler_state *vs; - struct pipe_sampler_state *fs; + void *vs; + void *fs; struct pipe_buffer *vbuf; /**< quad vertices */ float vertices[4][2][4]; /**< vertex/texcoords for quad */ diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index ed12768e7f..5549652abb 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -61,9 +61,9 @@ struct gen_mipmap_state struct pipe_depth_stencil_alpha_state depthstencil; struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; - /*struct pipe_viewport_state viewport;*/ - struct pipe_sampler_state *vs; - struct pipe_sampler_state *fs; + + void *vs; + void *fs; struct pipe_buffer *vbuf; /**< quad vertices */ float vertices[4][2][4]; /**< vertex/texcoords for quad */ -- cgit v1.2.3 From dccbfd8bf0624250a435948029916073d3390191 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Mar 2008 15:42:09 -0600 Subject: gallium: return pipe_shader_state from the simple shader functions Allows us to fix a mem leak (tokens array). --- src/gallium/auxiliary/util/u_blit.c | 10 +++++++-- src/gallium/auxiliary/util/u_gen_mipmap.c | 10 +++++++-- src/gallium/auxiliary/util/u_simple_shaders.c | 31 ++++++++++++++++----------- src/gallium/auxiliary/util/u_simple_shaders.h | 10 ++++++--- 4 files changed, 42 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 9986dc3570..eec5e600c9 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -58,6 +58,8 @@ struct blit_state struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; + struct pipe_shader_state vert_shader; + struct pipe_shader_state frag_shader; void *vs; void *fs; @@ -129,11 +131,12 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) TGSI_SEMANTIC_GENERIC }; const uint semantic_indexes[] = { 0, 0 }; ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, - semantic_indexes); + semantic_indexes, + &ctx->vert_shader); } /* fragment shader */ - ctx->fs = util_make_fragment_tex_shader(pipe); + ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader); ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys, 32, @@ -168,6 +171,9 @@ util_destroy_blit(struct blit_state *ctx) pipe->delete_vs_state(pipe, ctx->vs); pipe->delete_fs_state(pipe, ctx->fs); + FREE((void*) ctx->vert_shader.tokens); + FREE((void*) ctx->frag_shader.tokens); + pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf); FREE(ctx); diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 5549652abb..2fd214d22e 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -62,6 +62,8 @@ struct gen_mipmap_state struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; + struct pipe_shader_state vert_shader; + struct pipe_shader_state frag_shader; void *vs; void *fs; @@ -740,11 +742,12 @@ util_create_gen_mipmap(struct pipe_context *pipe, TGSI_SEMANTIC_GENERIC }; const uint semantic_indexes[] = { 0, 0 }; ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, - semantic_indexes); + semantic_indexes, + &ctx->vert_shader); } /* fragment shader */ - ctx->fs = util_make_fragment_tex_shader(pipe); + ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader); ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys, 32, @@ -813,6 +816,9 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) pipe->delete_vs_state(pipe, ctx->vs); pipe->delete_fs_state(pipe, ctx->fs); + FREE((void*) ctx->vert_shader.tokens); + FREE((void*) ctx->frag_shader.tokens); + pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf); FREE(ctx); diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index d230ddfbeb..5f8d12191d 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -56,7 +56,9 @@ void * util_make_vertex_passthrough_shader(struct pipe_context *pipe, uint num_attribs, const uint *semantic_names, - const uint *semantic_indexes) + const uint *semantic_indexes, + struct pipe_shader_state *shader) + { uint maxTokens = 100; struct tgsi_token *tokens; @@ -66,7 +68,6 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, struct tgsi_full_instruction inst; const uint procType = TGSI_PROCESSOR_VERTEX; uint ti, i; - struct pipe_shader_state shader; tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0])); @@ -145,8 +146,10 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, tgsi_dump(tokens, 0); #endif - shader.tokens = tokens; - return pipe->create_vs_state(pipe, &shader); + shader->tokens = tokens; + /*shader->num_tokens = ti;*/ + + return pipe->create_vs_state(pipe, shader); } @@ -158,7 +161,8 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, * END; */ void * -util_make_fragment_tex_shader(struct pipe_context *pipe) +util_make_fragment_tex_shader(struct pipe_context *pipe, + struct pipe_shader_state *shader) { uint maxTokens = 100; struct tgsi_token *tokens; @@ -168,7 +172,6 @@ util_make_fragment_tex_shader(struct pipe_context *pipe) struct tgsi_full_instruction inst; const uint procType = TGSI_PROCESSOR_FRAGMENT; uint ti; - struct pipe_shader_state shader; tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0])); @@ -254,8 +257,10 @@ util_make_fragment_tex_shader(struct pipe_context *pipe) tgsi_dump(tokens, 0); #endif - shader.tokens = tokens; - return pipe->create_fs_state(pipe, &shader); + shader->tokens = tokens; + /*shader->num_tokens = ti;*/ + + return pipe->create_fs_state(pipe, shader); } @@ -266,7 +271,8 @@ util_make_fragment_tex_shader(struct pipe_context *pipe) * Make simple fragment color pass-through shader. */ void * -util_make_fragment_passthrough_shader(struct pipe_context *pipe) +util_make_fragment_passthrough_shader(struct pipe_context *pipe, + struct pipe_shader_state *shader) { uint maxTokens = 40; struct tgsi_token *tokens; @@ -276,7 +282,6 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe) struct tgsi_full_instruction inst; const uint procType = TGSI_PROCESSOR_FRAGMENT; uint ti; - struct pipe_shader_state shader; tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0])); @@ -349,7 +354,9 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe) tgsi_dump(tokens, 0); #endif - shader.tokens = tokens; - return pipe->create_fs_state(pipe, &shader); + shader->tokens = tokens; + /*shader->num_tokens = ti;*/ + + return pipe->create_fs_state(pipe, shader); } diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h index ca219a092c..8ca4977d71 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.h +++ b/src/gallium/auxiliary/util/u_simple_shaders.h @@ -34,6 +34,7 @@ struct pipe_context; +struct pipe_shader_state; #ifdef __cplusplus @@ -45,15 +46,18 @@ extern void * util_make_vertex_passthrough_shader(struct pipe_context *pipe, uint num_attribs, const uint *semantic_names, - const uint *semantic_indexes); + const uint *semantic_indexes, + struct pipe_shader_state *shader); extern void * -util_make_fragment_tex_shader(struct pipe_context *pipe); +util_make_fragment_tex_shader(struct pipe_context *pipe, + struct pipe_shader_state *shader); extern void * -util_make_fragment_passthrough_shader(struct pipe_context *pipe); +util_make_fragment_passthrough_shader(struct pipe_context *pipe, + struct pipe_shader_state *shader); #ifdef __cplusplus -- cgit v1.2.3 From 37da2d685102ab5a706e0634fc55c60229598faa Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 27 Mar 2008 17:18:25 -0600 Subject: gallium: updated/improved comments, minor re-formatting --- src/gallium/include/pipe/p_context.h | 58 +++++++++++++++++------------------- 1 file changed, 27 insertions(+), 31 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index b2e49bef4c..2d063e3f9e 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -39,31 +39,28 @@ extern "C" { struct pipe_screen; struct pipe_fence_handle; struct pipe_state_cache; - -/* Opaque driver handles: - */ struct pipe_query; + /** * Gallium rendering context. Basically: * - state setting functions * - VBO drawing functions * - surface functions - * - device queries */ struct pipe_context { struct pipe_winsys *winsys; struct pipe_screen *screen; - void *priv; /** context private data (for DRI for example) */ - void *draw; /** private, for draw module (temporary? */ + void *priv; /**< context private data (for DRI for example) */ + void *draw; /**< private, for draw module (temporary?) */ void (*destroy)( struct pipe_context * ); - /* - * Drawing. - * Return false on fallbacks (temporary??) + /** + * VBO drawing (return false on fallbacks (temporary??)) */ + /*@{*/ boolean (*draw_arrays)( struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count); @@ -71,11 +68,13 @@ struct pipe_context { struct pipe_buffer *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); + /*@}*/ /** * Query objects */ + /*@{*/ struct pipe_query *(*create_query)( struct pipe_context *pipe, unsigned query_type ); @@ -89,10 +88,12 @@ struct pipe_context { struct pipe_query *q, boolean wait, uint64 *result); + /*@}*/ - /* - * State functions + /** + * State functions (create/bind/destroy state objects) */ + /*@{*/ void * (*create_blend_state)(struct pipe_context *, const struct pipe_blend_state *); void (*bind_blend_state)(struct pipe_context *, void *); @@ -122,10 +123,12 @@ struct pipe_context { const struct pipe_shader_state *); void (*bind_vs_state)(struct pipe_context *, void *); void (*delete_vs_state)(struct pipe_context *, void *); + /*@}*/ - /* The following look more properties than states. - * maybe combine a few of them into states or pass them - * in the bind calls to the state */ + /** + * Parameter-like state (or properties) + */ + /*@{*/ void (*set_blend_color)( struct pipe_context *, const struct pipe_blend_color * ); @@ -145,19 +148,13 @@ struct pipe_context { void (*set_scissor_state)( struct pipe_context *, const struct pipe_scissor_state * ); + void (*set_viewport_state)( struct pipe_context *, + const struct pipe_viewport_state * ); - /* Currently a sampler is constrained to sample from a single texture: - */ void (*set_sampler_textures)( struct pipe_context *, - unsigned num, + unsigned num_textures, struct pipe_texture ** ); - void (*set_viewport_state)( struct pipe_context *, - const struct pipe_viewport_state * ); - - /* - * Vertex arrays - */ void (*set_vertex_buffer)( struct pipe_context *, unsigned index, const struct pipe_vertex_buffer * ); @@ -165,12 +162,13 @@ struct pipe_context { void (*set_vertex_element)( struct pipe_context *, unsigned index, const struct pipe_vertex_element * ); + /*@}*/ - /* + /** * Surface functions */ - + /*@{*/ void (*surface_copy)(struct pipe_context *pipe, unsigned do_flip, /*<< flip surface contents vertically */ struct pipe_surface *dest, @@ -189,18 +187,16 @@ struct pipe_context { void (*clear)(struct pipe_context *pipe, struct pipe_surface *ps, unsigned clearValue); + /*@}*/ - /** - * Called when texture data is changed. - */ + + /** Called when texture data is changed */ void (*texture_update)(struct pipe_context *pipe, struct pipe_texture *texture, uint face, uint dirtyLevelsMask); - - /* Flush rendering: - */ + /** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */ void (*flush)( struct pipe_context *pipe, unsigned flags, struct pipe_fence_handle **fence ); -- cgit v1.2.3 From 39038c11699bbc9baab744542e96d54e91cb452a Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Mar 2008 17:41:55 -0600 Subject: gallium: replace PIPE_ATTRIB_MAX with PIPE_MAX_ATTRIBS The later follows the naming scheme of other limits. Keep the old definition until all possible usage is updated. --- src/gallium/auxiliary/draw/draw_context.c | 4 ++-- src/gallium/auxiliary/draw/draw_private.h | 12 ++++++------ src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 2 +- src/gallium/auxiliary/draw/draw_vf.c | 4 ++-- src/gallium/auxiliary/draw/draw_vf.h | 2 +- src/gallium/auxiliary/draw/draw_vs_exec.c | 4 ++-- src/gallium/auxiliary/draw/draw_vs_llvm.c | 4 ++-- src/gallium/auxiliary/draw/draw_vs_sse.c | 4 ++-- src/gallium/drivers/cell/ppu/cell_context.h | 6 +++--- src/gallium/drivers/cell/ppu/cell_draw_arrays.c | 4 ++-- src/gallium/drivers/cell/ppu/cell_state_vertex.c | 4 ++-- src/gallium/drivers/cell/ppu/cell_vertex_fetch.c | 2 +- src/gallium/drivers/cell/spu/spu_main.c | 4 ++-- src/gallium/drivers/cell/spu/spu_vertex_shader.c | 4 ++-- src/gallium/drivers/cell/spu/spu_vertex_shader.h | 8 ++++---- src/gallium/drivers/failover/fo_context.h | 4 ++-- src/gallium/drivers/failover/fo_state_emit.c | 4 ++-- src/gallium/drivers/i915simple/i915_context.c | 4 ++-- src/gallium/drivers/i915simple/i915_context.h | 2 +- src/gallium/drivers/i965simple/brw_clip.h | 2 +- src/gallium/drivers/i965simple/brw_context.h | 12 ++++++------ src/gallium/drivers/i965simple/brw_state.c | 2 +- src/gallium/drivers/i965simple/brw_wm.h | 4 ++-- src/gallium/drivers/softpipe/sp_context.h | 6 +++--- src/gallium/drivers/softpipe/sp_draw_arrays.c | 4 ++-- src/gallium/drivers/softpipe/sp_quad_fs.c | 4 ++-- src/gallium/drivers/softpipe/sp_state_vertex.c | 4 ++-- src/gallium/include/pipe/p_state.h | 3 ++- 28 files changed, 62 insertions(+), 61 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 903cc26766..81858e01ca 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -238,7 +238,7 @@ draw_set_vertex_buffer(struct draw_context *draw, const struct pipe_vertex_buffer *buffer) { draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - assert(attr < PIPE_ATTRIB_MAX); + assert(attr < PIPE_MAX_ATTRIBS); draw->vertex_buffer[attr] = *buffer; } @@ -249,7 +249,7 @@ draw_set_vertex_element(struct draw_context *draw, const struct pipe_vertex_element *element) { draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - assert(attr < PIPE_ATTRIB_MAX); + assert(attr < PIPE_MAX_ATTRIBS); draw->vertex_element[attr] = *element; } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 7007ee22c4..8eb2f515cb 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -228,8 +228,8 @@ struct draw_context /* pipe state that we need: */ const struct pipe_rasterizer_state *rasterizer; struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; - struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; struct draw_vertex_shader *vertex_shader; uint num_vs_outputs; /**< convenience, from vertex_shader */ @@ -242,7 +242,7 @@ struct draw_context unsigned eltSize; /** vertex arrays */ - const void *vbuffer[PIPE_ATTRIB_MAX]; + const void *vbuffer[PIPE_MAX_ATTRIBS]; /** constant buffer (for vertex shader) */ const void *constants; @@ -275,9 +275,9 @@ struct draw_context /* Vertex fetch internal state */ struct { - const ubyte *src_ptr[PIPE_ATTRIB_MAX]; - unsigned pitch[PIPE_ATTRIB_MAX]; - fetch_func fetch[PIPE_ATTRIB_MAX]; + const ubyte *src_ptr[PIPE_MAX_ATTRIBS]; + unsigned pitch[PIPE_MAX_ATTRIBS]; + fetch_func fetch[PIPE_MAX_ATTRIBS]; unsigned nr_attrs; full_fetch_func fetch_func; pt_fetch_func pt_fetch; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 64ef83d800..9b098bc173 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -78,7 +78,7 @@ struct fetch_emit_middle_end { unsigned pitch; void (*fetch)( const void *from, float *attrib); void (*emit)( const float *attrib, float **out ); - } fetch[PIPE_ATTRIB_MAX]; + } fetch[PIPE_MAX_ATTRIBS]; unsigned nr_fetch; unsigned hw_vertex_size; diff --git a/src/gallium/auxiliary/draw/draw_vf.c b/src/gallium/auxiliary/draw/draw_vf.c index f4e29a6293..7bb34ace7a 100644 --- a/src/gallium/auxiliary/draw/draw_vf.c +++ b/src/gallium/auxiliary/draw/draw_vf.c @@ -158,7 +158,7 @@ draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, unsigned offset = 0; unsigned i, j; - assert(nr < PIPE_ATTRIB_MAX); + assert(nr < PIPE_MAX_ATTRIBS); for (j = 0, i = 0; i < nr; i++) { const unsigned format = map[i].format; @@ -390,7 +390,7 @@ struct draw_vertex_fetch *draw_vf_create( void ) struct draw_vertex_fetch *vf = CALLOC_STRUCT(draw_vertex_fetch); unsigned i; - for (i = 0; i < PIPE_ATTRIB_MAX; i++) + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) vf->attr[i].vf = vf; vf->identity[0] = 0.0; diff --git a/src/gallium/auxiliary/draw/draw_vf.h b/src/gallium/auxiliary/draw/draw_vf.h index 011c8f0ff1..7555d1bd58 100644 --- a/src/gallium/auxiliary/draw/draw_vf.h +++ b/src/gallium/auxiliary/draw/draw_vf.h @@ -169,7 +169,7 @@ struct draw_vf_attr struct draw_vertex_fetch { - struct draw_vf_attr attr[PIPE_ATTRIB_MAX]; + struct draw_vf_attr attr[PIPE_MAX_ATTRIBS]; unsigned attr_count; unsigned vertex_stride; diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 4e2fa72707..487d0ea7f4 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -99,8 +99,8 @@ vs_exec_run( struct draw_vertex_shader *shader, struct tgsi_exec_machine *machine = &draw->machine; unsigned int j; - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); + ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); + ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index bd983f2ddf..d29cb18efe 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -107,8 +107,8 @@ vs_llvm_run( struct draw_vertex_shader *base, struct tgsi_exec_machine *machine = &draw->machine; unsigned int j; - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); + ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); + ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index a4503c143e..bc910dc2d0 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -114,8 +114,8 @@ vs_sse_run( struct draw_vertex_shader *base, struct tgsi_exec_machine *machine = &draw->machine; unsigned int j; - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); + ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); + ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 0442abddc1..7f656a9744 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -103,8 +103,8 @@ struct cell_context struct cell_texture *texture[PIPE_MAX_SAMPLERS]; uint num_textures; struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; - struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS]; ubyte *zsbuf_map; @@ -141,7 +141,7 @@ struct cell_context struct spe_function attrib_fetch; - unsigned attrib_fetch_offsets[PIPE_ATTRIB_MAX]; + unsigned attrib_fetch_offsets[PIPE_MAX_ATTRIBS]; }; diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index c839fb4d12..b896252f81 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -123,7 +123,7 @@ cell_draw_elements(struct pipe_context *pipe, /* * Map vertex buffers */ - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { if (sp->vertex_buffer[i].buffer) { void *buf = pipe->winsys->buffer_map(pipe->winsys, sp->vertex_buffer[i].buffer, @@ -151,7 +151,7 @@ cell_draw_elements(struct pipe_context *pipe, /* * unmap vertex/index buffers - will cause draw module to flush */ - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { if (sp->vertex_buffer[i].buffer) { draw_set_mapped_vertex_buffer(draw, i, NULL); pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer); diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c index 563831b62d..37d25fb357 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c +++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c @@ -41,7 +41,7 @@ cell_set_vertex_element(struct pipe_context *pipe, const struct pipe_vertex_element *attrib) { struct cell_context *cell = cell_context(pipe); - assert(index < PIPE_ATTRIB_MAX); + assert(index < PIPE_MAX_ATTRIBS); cell->vertex_element[index] = *attrib; /* struct copy */ cell->dirty |= CELL_NEW_VERTEX; @@ -55,7 +55,7 @@ cell_set_vertex_buffer(struct pipe_context *pipe, const struct pipe_vertex_buffer *buffer) { struct cell_context *cell = cell_context(pipe); - assert(index < PIPE_ATTRIB_MAX); + assert(index < PIPE_MAX_ATTRIBS); cell->vertex_buffer[index] = *buffer; /* struct copy */ cell->dirty |= CELL_NEW_VERTEX; diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c index 4828a8023b..49d5443cde 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c @@ -263,7 +263,7 @@ void cell_update_vertex_fetch(struct draw_context *draw) struct cell_context *const cell = (struct cell_context *) draw->driver_private; struct spe_function *p = &cell->attrib_fetch; - unsigned function_index[PIPE_ATTRIB_MAX]; + unsigned function_index[PIPE_MAX_ATTRIBS]; unsigned unique_attr_formats; int out_ptr; int in_ptr; diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index fccff01e10..d7f46f8024 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -55,7 +55,7 @@ struct spu_global spu; struct spu_vs_context draw; -static unsigned char attribute_fetch_code_buffer[136 * PIPE_ATTRIB_MAX] +static unsigned char attribute_fetch_code_buffer[136 * PIPE_MAX_ATTRIBS] ALIGN16_ATTRIB; static unsigned char depth_stencil_code_buffer[4 * 64] @@ -361,7 +361,7 @@ cmd_state_vs_array_info(const struct cell_array_info *vs_info) { const unsigned attr = vs_info->attr; - ASSERT(attr < PIPE_ATTRIB_MAX); + ASSERT(attr < PIPE_MAX_ATTRIBS); draw.vertex_fetch.src_ptr[attr] = vs_info->base; draw.vertex_fetch.pitch[attr] = vs_info->pitch; draw.vertex_fetch.size[attr] = vs_info->size; diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c index 8363efeeb6..3119a78c06 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c @@ -86,8 +86,8 @@ run_vertex_program(struct spu_vs_context *draw, struct spu_exec_machine *machine = &draw->machine; unsigned int j; - ALIGN16_DECL(struct spu_exec_vector, inputs, PIPE_ATTRIB_MAX); - ALIGN16_DECL(struct spu_exec_vector, outputs, PIPE_ATTRIB_MAX); + ALIGN16_DECL(struct spu_exec_vector, inputs, PIPE_MAX_ATTRIBS); + ALIGN16_DECL(struct spu_exec_vector, outputs, PIPE_MAX_ATTRIBS); const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.h b/src/gallium/drivers/cell/spu/spu_vertex_shader.h index 54a4b8d9b9..4c74f5e74d 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.h +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.h @@ -16,10 +16,10 @@ struct spu_vs_context { struct pipe_viewport_state viewport; struct { - uint64_t src_ptr[PIPE_ATTRIB_MAX]; - unsigned pitch[PIPE_ATTRIB_MAX]; - unsigned size[PIPE_ATTRIB_MAX]; - unsigned code_offset[PIPE_ATTRIB_MAX]; + uint64_t src_ptr[PIPE_MAX_ATTRIBS]; + unsigned pitch[PIPE_MAX_ATTRIBS]; + unsigned size[PIPE_MAX_ATTRIBS]; + unsigned code_offset[PIPE_MAX_ATTRIBS]; unsigned nr_attrs; boolean dirty; diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 8f3ad3ee79..4afe10c4b8 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -84,8 +84,8 @@ struct failover_context { struct pipe_scissor_state scissor; struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; - struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; void *sw_sampler_state[PIPE_MAX_SAMPLERS]; void *hw_sampler_state[PIPE_MAX_SAMPLERS]; diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c index 3de931e04e..bb89f925e9 100644 --- a/src/gallium/drivers/failover/fo_state_emit.c +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -104,7 +104,7 @@ failover_state_emit( struct failover_context *failover ) } if (failover->dirty & FO_NEW_VERTEX_BUFFER) { - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { if (failover->dirty_vertex_buffer & (1<sw->set_vertex_buffer( failover->sw, i, &failover->vertex_buffer[i] ); @@ -113,7 +113,7 @@ failover_state_emit( struct failover_context *failover ) } if (failover->dirty & FO_NEW_VERTEX_ELEMENT) { - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { if (failover->dirty_vertex_element & (1<sw->set_vertex_element( failover->sw, i, &failover->vertex_element[i] ); diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 15ff2360b7..fee33d82de 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -65,7 +65,7 @@ i915_draw_elements( struct pipe_context *pipe, /* * Map vertex buffers */ - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { if (i915->vertex_buffer[i].buffer) { void *buf = pipe->winsys->buffer_map(pipe->winsys, @@ -96,7 +96,7 @@ i915_draw_elements( struct pipe_context *pipe, /* * unmap vertex/index buffers */ - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { if (i915->vertex_buffer[i].buffer) { pipe->winsys->buffer_unmap(pipe->winsys, i915->vertex_buffer[i].buffer); draw_set_mapped_vertex_buffer(draw, i, NULL); diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 746f18ba38..8e707ea574 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -232,7 +232,7 @@ struct i915_context struct pipe_scissor_state scissor; struct i915_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; unsigned dirty; diff --git a/src/gallium/drivers/i965simple/brw_clip.h b/src/gallium/drivers/i965simple/brw_clip.h index a89d08b791..d70fc094ff 100644 --- a/src/gallium/drivers/i965simple/brw_clip.h +++ b/src/gallium/drivers/i965simple/brw_clip.h @@ -116,7 +116,7 @@ struct brw_clip_compile { unsigned last_mrf; unsigned header_position_offset; - unsigned offset[PIPE_ATTRIB_MAX]; + unsigned offset[PIPE_MAX_ATTRIBS]; }; #define ATTR_SIZE (4*4) diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index b83a13c3b6..0c96ba1732 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -433,17 +433,17 @@ struct brw_cached_batch_item { -/* Protect against a future where PIPE_ATTRIB_MAX > 32. Wouldn't life +/* Protect against a future where PIPE_MAX_ATTRIBS > 32. Wouldn't life * be easier if C allowed arrays of packed elements? */ -#define ATTRIB_BIT_DWORDS ((PIPE_ATTRIB_MAX+31)/32) +#define ATTRIB_BIT_DWORDS ((PIPE_MAX_ATTRIBS+31)/32) struct brw_vertex_info { - unsigned varying; /* varying:1[PIPE_ATTRIB_MAX] */ - unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_ATTRIB_MAX] */ + unsigned varying; /* varying:1[PIPE_MAX_ATTRIBS] */ + unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_MAX_ATTRIBS] */ }; @@ -496,9 +496,9 @@ struct brw_context /* Arrays with buffer objects to copy non-bufferobj arrays into * for upload: */ - const struct pipe_vertex_buffer *vbo_array[PIPE_ATTRIB_MAX]; + const struct pipe_vertex_buffer *vbo_array[PIPE_MAX_ATTRIBS]; - struct brw_vertex_element_state inputs[PIPE_ATTRIB_MAX]; + struct brw_vertex_element_state inputs[PIPE_MAX_ATTRIBS]; #define BRW_NR_UPLOAD_BUFS 17 #define BRW_UPLOAD_INIT_SIZE (128*1024) diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index f5efe9fc06..0d04a8a594 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -292,7 +292,7 @@ static void brw_set_vertex_element(struct pipe_context *pipe, /* flush ? */ struct brw_context *brw = brw_context(pipe); - assert(index < PIPE_ATTRIB_MAX); + assert(index < PIPE_MAX_ATTRIBS); struct brw_vertex_element_state el; memset(&el, 0, sizeof(el)); diff --git a/src/gallium/drivers/i965simple/brw_wm.h b/src/gallium/drivers/i965simple/brw_wm.h index a1ac0f504a..b29c4393f0 100644 --- a/src/gallium/drivers/i965simple/brw_wm.h +++ b/src/gallium/drivers/i965simple/brw_wm.h @@ -76,7 +76,7 @@ struct brw_wm_prog_key { #define PROGRAM_INTERNAL_PARAM #define MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS 1024 /* 72 for GL_ARB_f_p */ -#define BRW_WM_MAX_INSN (MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS*3 + PIPE_ATTRIB_MAX + 3) +#define BRW_WM_MAX_INSN (MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS*3 + PIPE_MAX_ATTRIBS + 3) #define BRW_WM_MAX_GRF 128 /* hardware limit */ #define BRW_WM_MAX_VREG (BRW_WM_MAX_INSN * 4) #define BRW_WM_MAX_REF (BRW_WM_MAX_INSN * 12) @@ -84,7 +84,7 @@ struct brw_wm_prog_key { #define BRW_WM_MAX_CONST 256 #define BRW_WM_MAX_KILLS MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS -#define PAYLOAD_DEPTH (PIPE_ATTRIB_MAX) +#define PAYLOAD_DEPTH (PIPE_MAX_ATTRIBS) #define MAX_IFSN 32 #define MAX_LOOP_DEPTH 32 diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 19e6cfaf02..dc9d0e6d5d 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -77,8 +77,8 @@ struct softpipe_context { struct pipe_scissor_state scissor; struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; - struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; unsigned dirty; unsigned num_samplers; @@ -92,7 +92,7 @@ struct softpipe_context { /* * Mapped vertex buffers */ - ubyte *mapped_vbuffer[PIPE_ATTRIB_MAX]; + ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS]; /** Mapped constant buffers */ void *mapped_constants[PIPE_SHADER_TYPES]; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 5b5a0fe573..ab54050d3f 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -125,7 +125,7 @@ softpipe_draw_elements(struct pipe_context *pipe, /* * Map vertex buffers */ - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { if (sp->vertex_buffer[i].buffer) { void *buf = pipe->winsys->buffer_map(pipe->winsys, @@ -153,7 +153,7 @@ softpipe_draw_elements(struct pipe_context *pipe, /* * unmap vertex/index buffers - will cause draw module to flush */ - for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { if (sp->vertex_buffer[i].buffer) { draw_set_mapped_vertex_buffer(draw, i, NULL); pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer); diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 861285101f..c10ad80e01 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -185,8 +185,8 @@ struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) uint i; /* allocate storage for program inputs/outputs, aligned to 16 bytes */ - qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16); - qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16); + qss->inputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->inputs) + 16); + qss->outputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->outputs) + 16); qss->machine.Inputs = align16(qss->inputs); qss->machine.Outputs = align16(qss->outputs); diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index f01a10de3b..c054e76d9b 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -42,7 +42,7 @@ softpipe_set_vertex_element(struct pipe_context *pipe, const struct pipe_vertex_element *attrib) { struct softpipe_context *softpipe = softpipe_context(pipe); - assert(index < PIPE_ATTRIB_MAX); + assert(index < PIPE_MAX_ATTRIBS); softpipe->vertex_element[index] = *attrib; /* struct copy */ softpipe->dirty |= SP_NEW_VERTEX; @@ -56,7 +56,7 @@ softpipe_set_vertex_buffer(struct pipe_context *pipe, const struct pipe_vertex_buffer *buffer) { struct softpipe_context *softpipe = softpipe_context(pipe); - assert(index < PIPE_ATTRIB_MAX); + assert(index < PIPE_MAX_ATTRIBS); softpipe->vertex_buffer[index] = *buffer; /* struct copy */ softpipe->dirty |= SP_NEW_VERTEX; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index a2bd8c6aaa..2490412126 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -54,7 +54,8 @@ extern "C" { #define PIPE_MAX_SAMPLERS 8 #define PIPE_MAX_CLIP_PLANES 6 #define PIPE_MAX_CONSTANT 32 -#define PIPE_ATTRIB_MAX 32 +#define PIPE_MAX_ATTRIBS 32 +#define PIPE_ATTRIB_MAX 32 /* XXX obsolete - remove */ #define PIPE_MAX_COLOR_BUFS 8 #define PIPE_MAX_TEXTURE_LEVELS 16 #define PIPE_MAX_FEEDBACK_ATTRIBS 16 -- cgit v1.2.3 From 5935b16ff5d8cbe07c97f2990e281a9c5986d0a1 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Mar 2008 21:11:45 -0600 Subject: If visual is 32bpp, set visual->alphaBits = 8. This works since we always use XImages for color buffers. It wouldn't always work for Windows/Pixmaps. --- src/gallium/winsys/xlib/xm_api.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 6b46327e21..a82d3c990e 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -511,6 +511,14 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, return GL_FALSE; } v->mesa_visual.indexBits = 0; + + if (v->BitsPerPixel == 32) { + /* We use XImages for all front/back buffers. If an X Window or + * X Pixmap is 32bpp, there's no guarantee that the alpha channel + * will be preserved. For XImages we're in luck. + */ + v->mesa_visual.alphaBits = 8; + } } /* -- cgit v1.2.3 From 4e7bcaa4c20cc358206cf4668316f998d79c85b0 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 28 Mar 2008 12:31:35 +0100 Subject: gallium: Bump PIPE_MAX_SAMPLERS to 16. We need it to fulfil D3D minimum requirements. --- src/gallium/include/pipe/p_state.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 2490412126..b47595deca 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -51,7 +51,7 @@ extern "C" { /** * Implementation limits */ -#define PIPE_MAX_SAMPLERS 8 +#define PIPE_MAX_SAMPLERS 16 #define PIPE_MAX_CLIP_PLANES 6 #define PIPE_MAX_CONSTANT 32 #define PIPE_MAX_ATTRIBS 32 -- cgit v1.2.3 From 5615ab78b03cf1cb5fb19fc04fef52818f91b0be Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 28 Mar 2008 15:43:00 +0100 Subject: gallium: remove redundant compare bit in sampler state --- src/gallium/drivers/i965simple/brw_wm.c | 3 +-- src/gallium/include/pipe/p_state.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_wm.c b/src/gallium/drivers/i965simple/brw_wm.c index 1c4b5b5ede..7fc5f59a98 100644 --- a/src/gallium/drivers/i965simple/brw_wm.c +++ b/src/gallium/drivers/i965simple/brw_wm.c @@ -161,8 +161,7 @@ static void brw_wm_populate_key( struct brw_context *brw, if (unit) { - if (unit->compare && - unit->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + if (unit->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { key->shadowtex_mask |= 1<Image[0][t->BaseLevel]->InternalFormat == GL_YCBCR_MESA) diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index b47595deca..0eeee47a9a 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -243,7 +243,6 @@ struct pipe_sampler_state unsigned min_img_filter:2; /**< PIPE_TEX_FILTER_x */ unsigned min_mip_filter:2; /**< PIPE_TEX_MIPFILTER_x */ unsigned mag_img_filter:2; /**< PIPE_TEX_FILTER_x */ - unsigned compare:1; /**< shadow/depth compare enabled? */ unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ unsigned compare_func:3; /**< PIPE_FUNC_x */ unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ -- cgit v1.2.3 From cbfe6ee5d58e7342012392a8ead7ae373625c00a Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 28 Mar 2008 15:22:34 -0600 Subject: gallium: Fix computation of Z values when not using early Z. This fixes the missing bitmaps in the engine and fogcoord demos. --- src/gallium/drivers/softpipe/sp_quad_fs.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index c10ad80e01..a73df31383 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -113,15 +113,18 @@ shade_quad( } } else { - /* copy input Z (which was interpolated by the executor) to output Z */ - uint i; - for (i = 0; i < 4; i++) { - quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i]; - /* XXX not sure the above line is always correct. The following - * might be better: - quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i]; - */ - } + /* compute Z values now, as in the quad earlyz stage */ + /* XXX we should really only do this if the earlyz stage is not used */ + const float fx = (float) quad->x0; + const float fy = (float) quad->y0; + const float dzdx = quad->posCoef->dadx[2]; + const float dzdy = quad->posCoef->dady[2]; + const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy; + + quad->outputs.depth[0] = z0; + quad->outputs.depth[1] = z0 + dzdx; + quad->outputs.depth[2] = z0 + dzdy; + quad->outputs.depth[3] = z0 + dzdx + dzdy; } /* shader may cull fragments */ -- cgit v1.2.3 From f10016b9a0639d7bc814c7b92a30d5b5b2cba5ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 25 Mar 2008 17:30:34 +0000 Subject: gallium: Fix some MSVC warnings. --- src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 +- src/gallium/auxiliary/util/u_snprintf.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 98c22eb4d4..da9a3a52ae 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -107,7 +107,7 @@ static void vcache_elt( struct vcache_frontend *vcache, assert(vcache->fetch_count < FETCH_MAX); vcache->in[idx] = felt; - vcache->out[idx] = vcache->fetch_count; + vcache->out[idx] = (ushort)vcache->fetch_count; vcache->fetch_elts[vcache->fetch_count++] = felt; } diff --git a/src/gallium/auxiliary/util/u_snprintf.c b/src/gallium/auxiliary/util/u_snprintf.c index 61c20b48f7..48426abcb7 100644 --- a/src/gallium/auxiliary/util/u_snprintf.c +++ b/src/gallium/auxiliary/util/u_snprintf.c @@ -783,19 +783,19 @@ rpl_vsnprintf(char *str, size_t size, const char *format, va_list args) switch (cflags) { case PRINT_C_CHAR: charptr = va_arg(args, signed char *); - *charptr = len; + *charptr = (signed char)len; break; case PRINT_C_SHORT: shortptr = va_arg(args, short int *); - *shortptr = len; + *shortptr = (short int)len; break; case PRINT_C_LONG: longptr = va_arg(args, long int *); - *longptr = len; + *longptr = (long int)len; break; case PRINT_C_LLONG: llongptr = va_arg(args, LLONG *); - *llongptr = len; + *llongptr = (LLONG)len; break; case PRINT_C_SIZE: /* -- cgit v1.2.3 From a52c0416d1f2105960b4646e2e268aed26814689 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 29 Mar 2008 14:41:03 +0100 Subject: gallium: Set vertex state/buffers en-mass. --- src/gallium/auxiliary/draw/draw_context.c | 24 ++++++---- src/gallium/auxiliary/draw/draw_context.h | 12 ++--- src/gallium/auxiliary/util/u_draw_quad.c | 16 ++++--- src/gallium/drivers/cell/ppu/cell_context.c | 4 +- src/gallium/drivers/cell/ppu/cell_state.h | 12 ++--- src/gallium/drivers/cell/ppu/cell_state_vertex.c | 30 +++++++----- src/gallium/drivers/failover/fo_context.h | 9 ++-- src/gallium/drivers/failover/fo_state.c | 35 +++++++------- src/gallium/drivers/failover/fo_state_emit.c | 22 +++------ src/gallium/drivers/i915simple/i915_state.c | 23 ++++----- src/gallium/drivers/i965simple/brw_state.c | 60 +++++++++++++----------- src/gallium/drivers/softpipe/sp_context.c | 4 +- src/gallium/drivers/softpipe/sp_state.h | 12 ++--- src/gallium/drivers/softpipe/sp_state_vertex.c | 31 +++++++----- src/gallium/include/pipe/p_context.h | 12 ++--- 15 files changed, 162 insertions(+), 144 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 81858e01ca..10bf9f54c1 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -233,24 +233,28 @@ void draw_set_viewport_state( struct draw_context *draw, void -draw_set_vertex_buffer(struct draw_context *draw, - unsigned attr, - const struct pipe_vertex_buffer *buffer) +draw_set_vertex_buffers(struct draw_context *draw, + unsigned count, + const struct pipe_vertex_buffer *buffers) { + assert(count <= PIPE_MAX_ATTRIBS); + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - assert(attr < PIPE_MAX_ATTRIBS); - draw->vertex_buffer[attr] = *buffer; + + memcpy(draw->vertex_buffer, buffers, count * sizeof(buffers[0])); } void -draw_set_vertex_element(struct draw_context *draw, - unsigned attr, - const struct pipe_vertex_element *element) +draw_set_vertex_elements(struct draw_context *draw, + unsigned count, + const struct pipe_vertex_element *elements) { + assert(count <= PIPE_MAX_ATTRIBS); + draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - assert(attr < PIPE_MAX_ATTRIBS); - draw->vertex_element[attr] = *element; + + memcpy(draw->vertex_element, elements, count * sizeof(elements[0])); } diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index dae687e590..84bae3bd78 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -138,13 +138,13 @@ void draw_delete_vertex_shader(struct draw_context *draw, * Vertex data functions */ -void draw_set_vertex_buffer(struct draw_context *draw, - unsigned attr, - const struct pipe_vertex_buffer *buffer); +void draw_set_vertex_buffers(struct draw_context *draw, + unsigned count, + const struct pipe_vertex_buffer *buffers); -void draw_set_vertex_element(struct draw_context *draw, - unsigned attr, - const struct pipe_vertex_element *element); +void draw_set_vertex_elements(struct draw_context *draw, + unsigned count, + const struct pipe_vertex_element *elements); void draw_set_mapped_element_buffer( struct draw_context *draw, unsigned eltSize, void *elements ); diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c index 37e8533609..e659edb088 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.c +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -45,23 +45,25 @@ util_draw_vertex_buffer(struct pipe_context *pipe, uint num_attribs) { struct pipe_vertex_buffer vbuffer; - struct pipe_vertex_element velement; + struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; uint i; + assert(num_attribs <= PIPE_MAX_ATTRIBS); + /* tell pipe about the vertex buffer */ vbuffer.buffer = vbuf; vbuffer.pitch = num_attribs * 4 * sizeof(float); /* vertex size */ vbuffer.buffer_offset = 0; - pipe->set_vertex_buffer(pipe, 0, &vbuffer); + pipe->set_vertex_buffers(pipe, 1, &vbuffer); /* tell pipe about the vertex attributes */ for (i = 0; i < num_attribs; i++) { - velement.src_offset = i * 4 * sizeof(float); - velement.vertex_buffer_index = 0; - velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - velement.nr_components = 4; - pipe->set_vertex_element(pipe, i, &velement); + velements[i].src_offset = i * 4 * sizeof(float); + velements[i].vertex_buffer_index = 0; + velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + velements[i].nr_components = 4; } + pipe->set_vertex_elements(pipe, num_attribs, velements); /* draw */ pipe->draw_arrays(pipe, prim_type, 0, num_verts); diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index ccbbd1d331..12eb5aa254 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -103,8 +103,8 @@ cell_create_context(struct pipe_screen *screen, cell->pipe.destroy = cell_destroy_context; /* state setters */ - cell->pipe.set_vertex_buffer = cell_set_vertex_buffer; - cell->pipe.set_vertex_element = cell_set_vertex_element; + cell->pipe.set_vertex_buffers = cell_set_vertex_buffers; + cell->pipe.set_vertex_elements = cell_set_vertex_elements; cell->pipe.draw_arrays = cell_draw_arrays; cell->pipe.draw_elements = cell_draw_elements; diff --git a/src/gallium/drivers/cell/ppu/cell_state.h b/src/gallium/drivers/cell/ppu/cell_state.h index 31ce505e21..82580ea35a 100644 --- a/src/gallium/drivers/cell/ppu/cell_state.h +++ b/src/gallium/drivers/cell/ppu/cell_state.h @@ -48,13 +48,13 @@ #define CELL_NEW_VERTEX_INFO 0x8000 -void cell_set_vertex_element(struct pipe_context *, - unsigned index, - const struct pipe_vertex_element *); +void cell_set_vertex_elements(struct pipe_context *, + unsigned count, + const struct pipe_vertex_element *); -void cell_set_vertex_buffer(struct pipe_context *, - unsigned index, - const struct pipe_vertex_buffer *); +void cell_set_vertex_buffers(struct pipe_context *, + unsigned count, + const struct pipe_vertex_buffer *); void cell_update_derived( struct cell_context *softpipe ); diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c index 37d25fb357..6c83b8dc72 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c +++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c @@ -36,28 +36,34 @@ void -cell_set_vertex_element(struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_element *attrib) +cell_set_vertex_elements(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_element *elements) { struct cell_context *cell = cell_context(pipe); - assert(index < PIPE_MAX_ATTRIBS); - cell->vertex_element[index] = *attrib; /* struct copy */ + + assert(count <= PIPE_MAX_ATTRIBS); + + memcpy(cell->vertex_element, elements, count * sizeof(elements[0])); + cell->dirty |= CELL_NEW_VERTEX; - draw_set_vertex_element(cell->draw, index, attrib); + draw_set_vertex_elements(cell->draw, count, elements); } void -cell_set_vertex_buffer(struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_buffer *buffer) +cell_set_vertex_buffers(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_buffer *buffers) { struct cell_context *cell = cell_context(pipe); - assert(index < PIPE_MAX_ATTRIBS); - cell->vertex_buffer[index] = *buffer; /* struct copy */ + + assert(count <= PIPE_MAX_ATTRIBS); + + memcpy(cell->vertex_buffer, buffers, count * sizeof(buffers[0])); + cell->dirty |= CELL_NEW_VERTEX; - draw_set_vertex_buffer(cell->draw, index, buffer); + draw_set_vertex_buffers(cell->draw, count, buffers); } diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 4afe10c4b8..c6409fe1e1 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -84,15 +84,16 @@ struct failover_context { struct pipe_scissor_state scissor; struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS]; + + uint num_vertex_buffers; + uint num_vertex_elements; void *sw_sampler_state[PIPE_MAX_SAMPLERS]; void *hw_sampler_state[PIPE_MAX_SAMPLERS]; unsigned dirty; - unsigned dirty_vertex_buffer; - unsigned dirty_vertex_element; unsigned num_samplers; unsigned num_textures; diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index 11eec2714e..6a79706632 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -402,32 +402,35 @@ failover_set_viewport_state( struct pipe_context *pipe, static void -failover_set_vertex_buffer(struct pipe_context *pipe, - unsigned unit, - const struct pipe_vertex_buffer *vertex_buffer) +failover_set_vertex_buffers(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_buffer *vertex_buffers) { struct failover_context *failover = failover_context(pipe); - failover->vertex_buffer[unit] = *vertex_buffer; + memcpy(failover->vertex_buffers, vertex_buffers, + count * sizeof(vertex_buffers[0])); failover->dirty |= FO_NEW_VERTEX_BUFFER; - failover->dirty_vertex_buffer |= (1<sw->set_vertex_buffer( failover->sw, unit, vertex_buffer ); - failover->hw->set_vertex_buffer( failover->hw, unit, vertex_buffer ); + failover->num_vertex_buffers = count; + failover->sw->set_vertex_buffers( failover->sw, count, vertex_buffers ); + failover->hw->set_vertex_buffers( failover->hw, count, vertex_buffers ); } static void -failover_set_vertex_element(struct pipe_context *pipe, - unsigned unit, - const struct pipe_vertex_element *vertex_element) +failover_set_vertex_elements(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_element *vertex_elements) { struct failover_context *failover = failover_context(pipe); - failover->vertex_element[unit] = *vertex_element; + memcpy(failover->vertex_elements, vertex_elements, + count * sizeof(vertex_elements[0])); + failover->dirty |= FO_NEW_VERTEX_ELEMENT; - failover->dirty_vertex_element |= (1<sw->set_vertex_element( failover->sw, unit, vertex_element ); - failover->hw->set_vertex_element( failover->hw, unit, vertex_element ); + failover->num_vertex_elements = count; + failover->sw->set_vertex_elements( failover->sw, count, vertex_elements ); + failover->hw->set_vertex_elements( failover->hw, count, vertex_elements ); } void @@ -474,7 +477,7 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.set_scissor_state = failover_set_scissor_state; failover->pipe.set_sampler_textures = failover_set_sampler_textures; failover->pipe.set_viewport_state = failover_set_viewport_state; - failover->pipe.set_vertex_buffer = failover_set_vertex_buffer; - failover->pipe.set_vertex_element = failover_set_vertex_element; + failover->pipe.set_vertex_buffers = failover_set_vertex_buffers; + failover->pipe.set_vertex_elements = failover_set_vertex_elements; failover->pipe.set_constant_buffer = failover_set_constant_buffer; } diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c index bb89f925e9..bd4fce9d20 100644 --- a/src/gallium/drivers/failover/fo_state_emit.c +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -53,8 +53,6 @@ void failover_state_emit( struct failover_context *failover ) { - unsigned i; - if (failover->dirty & FO_NEW_BLEND) failover->sw->bind_blend_state( failover->sw, failover->blend->sw_state ); @@ -104,24 +102,16 @@ failover_state_emit( struct failover_context *failover ) } if (failover->dirty & FO_NEW_VERTEX_BUFFER) { - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (failover->dirty_vertex_buffer & (1<sw->set_vertex_buffer( failover->sw, i, - &failover->vertex_buffer[i] ); - } - } + failover->sw->set_vertex_buffers( failover->sw, + failover->num_vertex_buffers, + failover->vertex_buffers ); } if (failover->dirty & FO_NEW_VERTEX_ELEMENT) { - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (failover->dirty_vertex_element & (1<sw->set_vertex_element( failover->sw, i, - &failover->vertex_element[i] ); - } - } + failover->sw->set_vertex_elements( failover->sw, + failover->num_vertex_elements, + failover->vertex_elements ); } failover->dirty = 0; - failover->dirty_vertex_element = 0; - failover->dirty_vertex_buffer = 0; } diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 1cec36e206..4404bc4590 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -687,23 +687,24 @@ static void i915_delete_rasterizer_state(struct pipe_context *pipe, FREE(raster); } -static void i915_set_vertex_buffer( struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_buffer *buffer ) +static void i915_set_vertex_buffers(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_buffer *buffers) { struct i915_context *i915 = i915_context(pipe); - i915->vertex_buffer[index] = *buffer; + + memcpy(i915->vertex_buffer, buffers, count * sizeof(buffers[0])); /* pass-through to draw module */ - draw_set_vertex_buffer(i915->draw, index, buffer); + draw_set_vertex_buffers(i915->draw, count, buffers); } -static void i915_set_vertex_element( struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_element *element) +static void i915_set_vertex_elements(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_element *elements) { struct i915_context *i915 = i915_context(pipe); /* pass-through to draw module */ - draw_set_vertex_element(i915->draw, index, element); + draw_set_vertex_elements(i915->draw, count, elements); } @@ -742,6 +743,6 @@ i915_init_state_functions( struct i915_context *i915 ) i915->pipe.set_scissor_state = i915_set_scissor_state; i915->pipe.set_sampler_textures = i915_set_sampler_textures; i915->pipe.set_viewport_state = i915_set_viewport_state; - i915->pipe.set_vertex_buffer = i915_set_vertex_buffer; - i915->pipe.set_vertex_element = i915_set_vertex_element; + i915->pipe.set_vertex_buffers = i915_set_vertex_buffers; + i915->pipe.set_vertex_elements = i915_set_vertex_elements; } diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index 0d04a8a594..376f1487b2 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -277,45 +277,49 @@ static void brw_set_viewport_state( struct pipe_context *pipe, } -static void brw_set_vertex_buffer( struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_buffer *buffer ) +static void brw_set_vertex_buffers(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_buffer *buffers) { struct brw_context *brw = brw_context(pipe); - brw->vb.vbo_array[index] = buffer; + memcpy(brw->vb.vbo_array, buffers, count * sizeof(buffers[0])); } -static void brw_set_vertex_element(struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_element *element) +static void brw_set_vertex_elements(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_element *elements) { /* flush ? */ struct brw_context *brw = brw_context(pipe); + uint i; - assert(index < PIPE_MAX_ATTRIBS); - struct brw_vertex_element_state el; - memset(&el, 0, sizeof(el)); + assert(count <= PIPE_MAX_ATTRIBS); - el.ve0.src_offset = element->src_offset; - el.ve0.src_format = brw_translate_surface_format(element->src_format); - el.ve0.valid = 1; - el.ve0.vertex_buffer_index = element->vertex_buffer_index; + for (i = 0; i < count; i++) { + struct brw_vertex_element_state el; + memset(&el, 0, sizeof(el)); - el.ve1.dst_offset = index * 4; + el.ve0.src_offset = elements[i].src_offset; + el.ve0.src_format = brw_translate_surface_format(elements[i].src_format); + el.ve0.valid = 1; + el.ve0.vertex_buffer_index = elements[i].vertex_buffer_index; - el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.dst_offset = i * 4; - switch (element->nr_components) { - case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; - case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; - case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; - break; - } + el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; - brw->vb.inputs[index] = el; + switch (elements[i].nr_components) { + case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; + case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; + case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; + break; + } + + brw->vb.inputs[i] = el; + } } @@ -457,6 +461,6 @@ brw_init_state_functions( struct brw_context *brw ) brw->pipe.set_scissor_state = brw_set_scissor_state; brw->pipe.set_sampler_textures = brw_set_sampler_textures; brw->pipe.set_viewport_state = brw_set_viewport_state; - brw->pipe.set_vertex_buffer = brw_set_vertex_buffer; - brw->pipe.set_vertex_element = brw_set_vertex_element; + brw->pipe.set_vertex_buffers = brw_set_vertex_buffers; + brw->pipe.set_vertex_elements = brw_set_vertex_elements; } diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 16fb06f176..e298ed37c3 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -174,8 +174,8 @@ softpipe_create( struct pipe_screen *screen, softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures; softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; - softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer; - softpipe->pipe.set_vertex_element = softpipe_set_vertex_element; + softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers; + softpipe->pipe.set_vertex_elements = softpipe_set_vertex_elements; softpipe->pipe.draw_arrays = softpipe_draw_arrays; softpipe->pipe.draw_elements = softpipe_draw_elements; diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 0bb1095aec..6e6501f5bc 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -151,13 +151,13 @@ void softpipe_set_sampler_textures( struct pipe_context *, void softpipe_set_viewport_state( struct pipe_context *, const struct pipe_viewport_state * ); -void softpipe_set_vertex_element(struct pipe_context *, - unsigned index, - const struct pipe_vertex_element *); +void softpipe_set_vertex_elements(struct pipe_context *, + unsigned count, + const struct pipe_vertex_element *); -void softpipe_set_vertex_buffer(struct pipe_context *, - unsigned index, - const struct pipe_vertex_buffer *); +void softpipe_set_vertex_buffers(struct pipe_context *, + unsigned count, + const struct pipe_vertex_buffer *); void softpipe_update_derived( struct softpipe_context *softpipe ); diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index c054e76d9b..e0230e16a4 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -37,28 +37,35 @@ void -softpipe_set_vertex_element(struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_element *attrib) +softpipe_set_vertex_elements(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_element *attribs) { struct softpipe_context *softpipe = softpipe_context(pipe); - assert(index < PIPE_MAX_ATTRIBS); - softpipe->vertex_element[index] = *attrib; /* struct copy */ + + assert(count <= PIPE_MAX_ATTRIBS); + + memcpy(softpipe->vertex_element, attribs, + count * sizeof(struct pipe_vertex_element)); + softpipe->dirty |= SP_NEW_VERTEX; - draw_set_vertex_element(softpipe->draw, index, attrib); + draw_set_vertex_elements(softpipe->draw, count, attribs); } void -softpipe_set_vertex_buffer(struct pipe_context *pipe, - unsigned index, - const struct pipe_vertex_buffer *buffer) +softpipe_set_vertex_buffers(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_buffer *buffers) { struct softpipe_context *softpipe = softpipe_context(pipe); - assert(index < PIPE_MAX_ATTRIBS); - softpipe->vertex_buffer[index] = *buffer; /* struct copy */ + + assert(count <= PIPE_MAX_ATTRIBS); + + memcpy(softpipe->vertex_buffer, buffers, count * sizeof(buffers[0])); + softpipe->dirty |= SP_NEW_VERTEX; - draw_set_vertex_buffer(softpipe->draw, index, buffer); + draw_set_vertex_buffers(softpipe->draw, count, buffers); } diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 2d063e3f9e..324f70185a 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -155,13 +155,13 @@ struct pipe_context { unsigned num_textures, struct pipe_texture ** ); - void (*set_vertex_buffer)( struct pipe_context *, - unsigned index, - const struct pipe_vertex_buffer * ); + void (*set_vertex_buffers)( struct pipe_context *, + unsigned num_buffers, + const struct pipe_vertex_buffer * ); - void (*set_vertex_element)( struct pipe_context *, - unsigned index, - const struct pipe_vertex_element * ); + void (*set_vertex_elements)( struct pipe_context *, + unsigned num_elements, + const struct pipe_vertex_element * ); /*@}*/ -- cgit v1.2.3 From fc9888014470286d8d651c569aaadf9cd69d8282 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 30 Mar 2008 22:48:49 +0200 Subject: draw: Fix bypass_vs semantic misuse. --- src/gallium/auxiliary/draw/draw_prim.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index ddcde01d9a..404c28d76a 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -594,6 +594,7 @@ draw_arrays(struct draw_context *draw, unsigned prim, /* drawing done here: */ if (!draw->rasterizer->bypass_vs || + (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first) || !draw_pt_arrays(draw, prim, start, count)) { /* we have to run the whole pipeline */ draw_prim(draw, prim, start, count); -- cgit v1.2.3 From 63950b11b6060e4e0d06e0d14548ff132a295067 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 30 Mar 2008 23:21:20 +0200 Subject: draw: Do not run full pipeline when flatshade_first for point primitives. --- src/gallium/auxiliary/draw/draw_prim.c | 1 - src/gallium/auxiliary/draw/draw_pt.c | 3 +++ src/gallium/auxiliary/draw/draw_validate.c | 8 ++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index 404c28d76a..ddcde01d9a 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -594,7 +594,6 @@ draw_arrays(struct draw_context *draw, unsigned prim, /* drawing done here: */ if (!draw->rasterizer->bypass_vs || - (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first) || !draw_pt_arrays(draw, prim, start, count)) { /* we have to run the whole pipeline */ draw_prim(draw, prim, start, count); diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 3ec31ec25f..fc9304197a 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -36,6 +36,9 @@ #include "draw/draw_pt.h" +/* XXX: Shouldn't those two functions below use the '>' operator??? + */ + static boolean too_many_verts( struct draw_context *draw, unsigned verts ) { diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index e163e078f0..ad43f06f73 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -76,6 +76,10 @@ draw_need_pipeline(const struct draw_context *draw, /* AA lines */ if (draw->rasterizer->line_smooth && draw->pipeline.aaline) return TRUE; + + /* first-vertex driven flatshading */ + if (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first) + return TRUE; } if (points(prim)) @@ -112,6 +116,10 @@ draw_need_pipeline(const struct draw_context *draw, /* two-side lighting */ if (draw->rasterizer->light_twoside) return TRUE; + + /* first-vertex driven flatshading */ + if (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first) + return TRUE; } /* polygon cull - this is difficult - hardware can cull just fine -- cgit v1.2.3 From baab98a637d526871fb77ec6f313012f49c0e998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 31 Mar 2008 09:02:08 +0900 Subject: gallium: Eliminate p_winsys::printf Not convenient and almost not used at all. Better replacements in p_debug.h --- src/gallium/drivers/i915simple/i915_debug.c | 19 +++++++------------ src/gallium/drivers/i915simple/i915_debug.h | 4 +--- src/gallium/drivers/i915simple/i915_debug_fp.c | 4 +--- src/gallium/drivers/i915simple/i915_screen.c | 5 ++--- src/gallium/drivers/i965simple/brw_context.c | 5 ++--- src/gallium/drivers/i965simple/brw_context.h | 6 +++--- src/gallium/include/pipe/p_winsys.h | 4 ---- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 10 ---------- src/gallium/winsys/xlib/xm_winsys.c | 11 ----------- src/gallium/winsys/xlib/xm_winsys_aub.c | 10 ---------- 10 files changed, 16 insertions(+), 62 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_debug.c b/src/gallium/drivers/i915simple/i915_debug.c index 78102dbac2..9b9111167f 100644 --- a/src/gallium/drivers/i915simple/i915_debug.c +++ b/src/gallium/drivers/i915simple/i915_debug.c @@ -30,6 +30,7 @@ #include "i915_winsys.h" #include "i915_debug.h" #include "pipe/p_winsys.h" +#include "pipe/p_debug.h" static void @@ -39,11 +40,9 @@ PRINTF( ... ) { va_list args; - char buffer[256]; va_start( args, fmt ); - vsprintf( buffer, fmt, args ); - stream->winsys->printf( stream->winsys, buffer ); + debug_vprintf( fmt, args ); va_end( args ); } @@ -200,14 +199,12 @@ BITS( ... ) { va_list args; - char buffer[256]; unsigned himask = ~0UL >> (31 - (hi)); PRINTF(stream, "\t\t "); va_start( args, fmt ); - vsprintf( buffer, fmt, args ); - stream->winsys->printf( stream->winsys, buffer ); + debug_vprintf( fmt, args ); va_end( args ); PRINTF(stream, ": 0x%x\n", ((dw) & himask) >> (lo)); @@ -231,13 +228,11 @@ FLAG( { if (((dw) >> (bit)) & 1) { va_list args; - char buffer[256]; PRINTF(stream, "\t\t "); va_start( args, fmt ); - vsprintf( buffer, fmt, args ); - stream->winsys->printf( stream->winsys, buffer ); + debug_vprintf( fmt, args ); va_end( args ); PRINTF(stream, "\n"); @@ -877,11 +872,11 @@ i915_dump_batchbuffer( struct i915_context *i915 ) stream.winsys = i915->pipe.winsys; if (!start || !end) { - stream.winsys->printf( stream.winsys, "\n\nBATCH: ???\n"); + debug_printf( "\n\nBATCH: ???\n"); return; } - stream.winsys->printf( stream.winsys, "\n\nBATCH: (%d)\n", bytes / 4); + debug_printf( "\n\nBATCH: (%d)\n", bytes / 4); while (!done && stream.offset < bytes) @@ -893,7 +888,7 @@ i915_dump_batchbuffer( struct i915_context *i915 ) stream.offset >= 0); } - stream.winsys->printf( stream.winsys, "END-BATCH\n\n\n"); + debug_printf( "END-BATCH\n\n\n"); } diff --git a/src/gallium/drivers/i915simple/i915_debug.h b/src/gallium/drivers/i915simple/i915_debug.h index 0bcd094233..afb63edabf 100644 --- a/src/gallium/drivers/i915simple/i915_debug.h +++ b/src/gallium/drivers/i915simple/i915_debug.h @@ -83,11 +83,9 @@ I915_DBG( { if ((i915)->debug & FILE_DEBUG_FLAG) { va_list args; - char buffer[256]; va_start( args, fmt ); - vsprintf( buffer, fmt, args ); - i915->pipe.winsys->printf( i915->pipe.winsys, buffer ); + debug_vprintf( fmt, args ); va_end( args ); } } diff --git a/src/gallium/drivers/i915simple/i915_debug_fp.c b/src/gallium/drivers/i915simple/i915_debug_fp.c index ebfdb3d93c..37a3508fe1 100644 --- a/src/gallium/drivers/i915simple/i915_debug_fp.c +++ b/src/gallium/drivers/i915simple/i915_debug_fp.c @@ -39,11 +39,9 @@ PRINTF( ... ) { va_list args; - char buffer[256]; va_start( args, fmt ); - vsprintf( buffer, fmt, args ); - stream->winsys->printf( stream->winsys, buffer ); + debug_vprintf( fmt, args ); va_end( args ); } diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 8d7bf0b33e..839b98c0ce 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -226,9 +226,8 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id) break; default: - winsys->printf(winsys, - "%s: unknown pci id 0x%x, cannot create screen\n", - __FUNCTION__, pci_id); + debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", + __FUNCTION__, pci_id); return NULL; } diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index 7c908da672..a276cc0535 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -77,9 +77,8 @@ struct pipe_context *brw_create(struct pipe_screen *screen, { struct brw_context *brw; - screen->winsys->printf(screen->winsys, - "%s: creating brw_context with pci id 0x%x\n", - __FUNCTION__, pci_id); + debug_printf("%s: creating brw_context with pci id 0x%x\n", + __FUNCTION__, pci_id); brw = CALLOC_STRUCT(brw_context); if (brw == NULL) diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index 0c96ba1732..eeccf36785 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -183,12 +183,12 @@ extern int BRW_DEBUG; #define DEBUG_MIPTREE 0x800000 #define DBG(...) do { \ - if (BRW_DEBUG & FILE_DEBUG_FLAG) \ - brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ + if (BRW_DEBUG & FILE_DEBUG_FLAG) \ + debug_printf(__VA_ARGS__); \ } while(0) #define PRINT(...) do { \ - brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \ + debug_printf(brw->pipe.winsys, __VA_ARGS__); \ } while(0) struct brw_state_flags { diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index 1383bd0544..8569cdcf12 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -73,10 +73,6 @@ struct pipe_winsys struct pipe_surface *surf, void *context_private ); - /** Debug output */ - void (*printf)( struct pipe_winsys *sws, - const char *, ... ); - /** allocate a new surface (no context dependency) */ struct pipe_surface *(*surface_alloc)(struct pipe_winsys *ws); diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 789a386500..77dec9488d 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -243,15 +243,6 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -static void -intel_printf( struct pipe_winsys *winsys, const char *fmtString, ... ) -{ - va_list args; - va_start( args, fmtString ); - vfprintf(stderr, fmtString, args); - va_end( args ); -} - static const char * intel_get_name( struct pipe_winsys *winsys ) { @@ -277,7 +268,6 @@ intel_create_pipe_winsys( int fd ) iws->winsys.buffer_unmap = intel_buffer_unmap; iws->winsys.buffer_destroy = intel_buffer_destroy; iws->winsys.flush_frontbuffer = intel_flush_frontbuffer; - iws->winsys.printf = intel_printf; iws->winsys.get_name = intel_get_name; iws->winsys.surface_alloc = intel_i915_surface_alloc; iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 7459756279..9a20bdfb69 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -303,16 +303,6 @@ xm_flush_frontbuffer(struct pipe_winsys *pws, -static void -xm_printf(struct pipe_winsys *pws, const char *fmtString, ...) -{ - va_list args; - va_start( args, fmtString ); - vfprintf(stderr, fmtString, args); - va_end( args ); -} - - static const char * xm_get_name(struct pipe_winsys *pws) { @@ -635,7 +625,6 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) ws->base.fence_finish = xm_fence_finish; ws->base.flush_frontbuffer = xm_flush_frontbuffer; - ws->base.printf = xm_printf; ws->base.get_name = xm_get_name; } diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index d55d8c39eb..f42f7fcc5f 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -311,15 +311,6 @@ aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -static void -aub_printf( struct pipe_winsys *winsys, const char *fmtString, ... ) -{ - va_list args; - va_start( args, fmtString ); - vfprintf(stderr, fmtString, args); - va_end( args ); -} - static const char * aub_get_name( struct pipe_winsys *winsys ) { @@ -344,7 +335,6 @@ xmesa_create_pipe_winsys_aub( void ) iws->winsys.buffer_unmap = aub_buffer_unmap; iws->winsys.buffer_destroy = aub_buffer_destroy; iws->winsys.flush_frontbuffer = aub_flush_frontbuffer; - iws->winsys.printf = aub_printf; iws->winsys.get_name = aub_get_name; iws->winsys.surface_alloc = aub_i915_surface_alloc; -- cgit v1.2.3 From 499d8aaa476fb67b7355122dc6fbc641e1b44ed0 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 14:06:42 -0600 Subject: gallium: draw_passthrough.c is not used anymore --- src/gallium/auxiliary/draw/Makefile | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 0c7ce5da5b..a0db2e4555 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -15,7 +15,6 @@ C_SOURCES = \ draw_debug.c \ draw_flatshade.c \ draw_offset.c \ - draw_passthrough.c \ draw_pt.c \ draw_pt_vcache.c \ draw_pt_fetch_emit.c \ -- cgit v1.2.3 From 9cbd8400433fb27da03f300b36495baef464cc6b Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 14:13:09 -0600 Subject: gallium: draw_passthrough.c is not used anymore --- src/gallium/auxiliary/draw/SConscript | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 9b3e7247c5..981225a8c2 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -14,7 +14,6 @@ draw = env.ConvenienceLibrary( 'draw_debug.c', 'draw_flatshade.c', 'draw_offset.c', - 'draw_passthrough.c', # going away soon 'draw_pt.c', 'draw_pt_vcache.c', 'draw_pt_fetch_emit.c', -- cgit v1.2.3 From 594dab4769533afaeb30a588e1731a6753a93f0d Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 14:14:30 -0600 Subject: gallium: move the test for bypass_vs into the vs_XXX_run() functions Also: 1. Added an identity_viewport flag to skip viewport transformation when it has no effect. Might also add an explicit bypass_viewport flag someday. 2. Separate the code for computing clip codes and doing the viewport transform. Predicate them separately. Note: even if bypass_vs is set, we still look at the shader to determine the number of inputs and outputs. --- src/gallium/auxiliary/draw/draw_context.c | 8 ++++++ src/gallium/auxiliary/draw/draw_prim.c | 3 +-- src/gallium/auxiliary/draw/draw_private.h | 2 ++ src/gallium/auxiliary/draw/draw_vs_exec.c | 24 ++++++++++++------ src/gallium/auxiliary/draw/draw_vs_llvm.c | 42 ++++++++++++++++++++----------- src/gallium/auxiliary/draw/draw_vs_sse.c | 32 +++++++++++++++-------- 6 files changed, 76 insertions(+), 35 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 10bf9f54c1..d0d5f66b37 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -228,6 +228,14 @@ void draw_set_viewport_state( struct draw_context *draw, { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); draw->viewport = *viewport; /* struct copy */ + draw->identity_viewport = (viewport->scale[0] == 1.0f && + viewport->scale[1] == 1.0f && + viewport->scale[2] == 1.0f && + viewport->scale[3] == 1.0f && + viewport->translate[0] == 0.0f && + viewport->translate[1] == 0.0f && + viewport->translate[2] == 0.0f && + viewport->translate[3] == 0.0f); } diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index ddcde01d9a..9779aa8440 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -593,8 +593,7 @@ draw_arrays(struct draw_context *draw, unsigned prim, } /* drawing done here: */ - if (!draw->rasterizer->bypass_vs || - !draw_pt_arrays(draw, prim, start, count)) { + if (!draw_pt_arrays(draw, prim, start, count)) { /* we have to run the whole pipeline */ draw_prim(draw, prim, start, count); } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 8eb2f515cb..9a9b25297f 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -232,6 +232,8 @@ struct draw_context struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; struct draw_vertex_shader *vertex_shader; + boolean identity_viewport; + uint num_vs_outputs; /**< convenience, from vertex_shader */ /* user-space vertex data, buffers */ diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 487d0ea7f4..c8ed17c00a 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -110,13 +110,20 @@ vs_exec_run( struct draw_vertex_shader *shader, machine->Consts = (float (*)[4]) draw->user.constants; machine->Inputs = ALIGN16_ASSIGN(inputs); - machine->Outputs = ALIGN16_ASSIGN(outputs); + if (draw->rasterizer->bypass_vs) { + /* outputs are just the inputs */ + machine->Outputs = machine->Inputs; + } + else { + machine->Outputs = ALIGN16_ASSIGN(outputs); + } draw->vertex_fetch.fetch_func( draw, machine, elts, count ); - /* run interpreter */ - tgsi_exec_machine_run( machine ); - + if (!draw->rasterizer->bypass_vs) { + /* run interpreter */ + tgsi_exec_machine_run( machine ); + } /* store machine results */ for (j = 0; j < count; j++) { @@ -136,8 +143,13 @@ vs_exec_run( struct draw_vertex_shader *shader, if (!draw->rasterizer->bypass_clipping) { vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); - vOut[j]->edgeflag = 1; + } + else { + vOut[j]->clipmask = 0; + } + vOut[j]->edgeflag = 1; + if (!draw->identity_viewport) { /* divide by w */ w = 1.0f / w; x *= w; @@ -151,8 +163,6 @@ vs_exec_run( struct draw_vertex_shader *shader, vOut[j]->data[0][3] = w; } else { - vOut[j]->clipmask = 0; - vOut[j]->edgeflag = 1; vOut[j]->data[0][0] = x; vOut[j]->data[0][1] = y; vOut[j]->data[0][2] = z; diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index d29cb18efe..8aa8a617bb 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -121,31 +121,45 @@ vs_llvm_run( struct draw_vertex_shader *base, machine->Consts = (float (*)[4]) draw->user.constants; machine->Inputs = ALIGN16_ASSIGN(inputs); - machine->Outputs = ALIGN16_ASSIGN(outputs); + if (draw->rasterizer->bypass_vs) { + /* outputs are just the inputs */ + machine->Outputs = machine->Inputs; + } + else { + machine->Outputs = ALIGN16_ASSIGN(outputs); + } + draw->vertex_fetch.fetch_func( draw, machine, elts, count ); - /* run shader */ - gallivm_cpu_vs_exec(shader->llvm_prog, - machine->Inputs, - machine->Outputs, - machine->Consts, - machine->Temps); + if (!draw->rasterizer->bypass_vs) { + /* run shader */ + gallivm_cpu_vs_exec(shader->llvm_prog, + machine->Inputs, + machine->Outputs, + machine->Consts, + machine->Temps); + } /* store machine results */ for (j = 0; j < count; j++) { unsigned slot; float x, y, z, w; - if (!draw->rasterizer->bypass_clipping) { - x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + if (!draw->rasterizer->bypass_clipping) { vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); - vOut[j]->edgeflag = 1; + } + else { + vOut[j]->clipmask = 0; + } + vOut[j]->edgeflag = 1; + if (!draw->identity_viewport) { /* divide by w */ w = 1.0f / w; x *= w; @@ -159,8 +173,6 @@ vs_llvm_run( struct draw_vertex_shader *base, vOut[j]->data[0][3] = w; } else { - vOut[j]->clipmask = 0; - vOut[j]->edgeflag = 1; vOut[j]->data[0][0] = x; vOut[j]->data[0][1] = y; vOut[j]->data[0][2] = z; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index bc910dc2d0..701137f908 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -126,7 +126,13 @@ vs_sse_run( struct draw_vertex_shader *base, /* Consts does not require 16 byte alignment. */ machine->Consts = (float (*)[4]) draw->user.constants; machine->Inputs = ALIGN16_ASSIGN(inputs); - machine->Outputs = ALIGN16_ASSIGN(outputs); + if (draw->rasterizer->bypass_vs) { + /* outputs are just the inputs */ + machine->Outputs = machine->Inputs; + } + else { + machine->Outputs = ALIGN16_ASSIGN(outputs); + } /* Fetch vertices. This may at some point be integrated into the @@ -137,13 +143,14 @@ vs_sse_run( struct draw_vertex_shader *base, draw->vertex_fetch.fetch_func( draw, machine, elts, count ); - /* run compiled shader - */ - shader->func( - machine->Inputs, - machine->Outputs, - machine->Consts, - machine->Temps ); + if (!draw->rasterizer->bypass_vs) { + /* run compiled shader + */ + shader->func(machine->Inputs, + machine->Outputs, + machine->Consts, + machine->Temps ); + } /* XXX: Computing the clipmask and emitting results should be done @@ -161,8 +168,13 @@ vs_sse_run( struct draw_vertex_shader *base, if (!draw->rasterizer->bypass_clipping) { vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); - vOut[j]->edgeflag = 1; + } + else { + vOut[j]->clipmask = 0; + } + vOut[j]->edgeflag = 1; + if (!draw->identity_viewport) { /* divide by w */ w = 1.0f / w; x *= w; @@ -176,8 +188,6 @@ vs_sse_run( struct draw_vertex_shader *base, vOut[j]->data[0][3] = w; } else { - vOut[j]->clipmask = 0; - vOut[j]->edgeflag = 1; vOut[j]->data[0][0] = x; vOut[j]->data[0][1] = y; vOut[j]->data[0][2] = z; -- cgit v1.2.3 From 7139b8ef78adb8d08c13e439fc8add31a2d79f36 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 14:20:16 -0600 Subject: gallium: draw_passthrough.c is obsolete - removed --- src/gallium/auxiliary/draw/draw_passthrough.c | 473 -------------------------- 1 file changed, 473 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_passthrough.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_passthrough.c b/src/gallium/auxiliary/draw/draw_passthrough.c deleted file mode 100644 index 2198079a88..0000000000 --- a/src/gallium/auxiliary/draw/draw_passthrough.c +++ /dev/null @@ -1,473 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - - -/* This code is a prototype of what a passhthrough vertex shader might - * look like. - * - * Probably the best approach for us is to do: - * - vertex fetch - * - vertex shader - * - cliptest / viewport transform - * - * in one step, then examine the clipOrMask & choose between two paths: - * - * Either: - * - build primitive headers - * - clip and the primitive path - * - build clipped vertex buffers, - * - vertex-emit to vbuf buffers - * - * Or, if no clipping: - * - vertex-emit directly to vbuf buffers - * - * But when bypass clipping is enabled, we just take the latter - * choice. If (some new) passthrough-vertex-shader flag is also set, - * the pipeline degenerates to: - * - * - vertex fetch - * - vertex emit to vbuf buffers - * - * Which is what is prototyped here. - */ -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "draw/draw_private.h" -#include "draw/draw_vbuf.h" -#include "draw/draw_vertex.h" - - -/** - * General-purpose fetch from user's vertex arrays, emit to driver's - * vertex buffer. - * - * XXX this is totally temporary. - */ -static void -fetch_store_general( struct draw_context *draw, - float *out, - unsigned start, - unsigned count ) -{ - const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); - const unsigned nr_attrs = vinfo->num_attribs; - uint i, j; - - const unsigned *pitch = draw->vertex_fetch.pitch; - const ubyte **src = draw->vertex_fetch.src_ptr; - - for (i = start; i < start + count; i++) { - for (j = 0; j < nr_attrs; j++) { - /* vinfo->src_index is the output of the vertex shader - * matching this hw-vertex component. - * - * In passthrough, we require a 1:1 mapping between vertex - * shader outputs and inputs, which in turn correspond to - * vertex elements in the state. So, this is the vertex - * element we're interested in... - */ - const uint jj = vinfo->src_index[j]; - const enum pipe_format srcFormat = draw->vertex_element[jj].src_format; - const ubyte *from = src[jj] + i * pitch[jj]; - float attrib[4]; - - /* Except... When we're not. Two cases EMIT_HEADER & - * EMIT_1F_PSIZE don't consume an input. Should have some - * method for indicating this, or change the logic here - * somewhat so it doesn't matter. - * - * Just hack this up now, do something better about it later. - */ - if (vinfo->emit[j] == EMIT_HEADER) { - memset(out, 0, sizeof(struct vertex_header)); - out += sizeof(struct vertex_header) / 4; - continue; - } - else if (vinfo->emit[j] == EMIT_1F_PSIZE) { - out[0] = 1.0; /* xxx */ - out += 1; - continue; - } - - - /* The normal fetch/emit code: - */ - switch (srcFormat) { - case PIPE_FORMAT_B8G8R8A8_UNORM: - { - ubyte *ub = (ubyte *) from; - attrib[2] = UBYTE_TO_FLOAT(ub[0]); - attrib[1] = UBYTE_TO_FLOAT(ub[1]); - attrib[0] = UBYTE_TO_FLOAT(ub[2]); - attrib[3] = UBYTE_TO_FLOAT(ub[3]); - } - break; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - { - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = f[2]; - attrib[3] = f[3]; - } - break; - case PIPE_FORMAT_R32G32B32_FLOAT: - { - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = f[2]; - attrib[3] = 1.0; - } - break; - case PIPE_FORMAT_R32G32_FLOAT: - { - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = 0.0; - attrib[3] = 1.0; - } - break; - case PIPE_FORMAT_R32_FLOAT: - { - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = 0.0; - attrib[2] = 0.0; - attrib[3] = 1.0; - } - break; - default: - assert(0); - } - - debug_printf("attrib %d: %f %f %f %f\n", j, - attrib[0], attrib[1], attrib[2], attrib[3]); - - switch (vinfo->emit[j]) { - case EMIT_1F: - out[0] = attrib[0]; - out += 1; - break; - case EMIT_2F: - out[0] = attrib[0]; - out[1] = attrib[1]; - out += 2; - break; - case EMIT_4F: - out[0] = attrib[0]; - out[1] = attrib[1]; - out[2] = attrib[2]; - out[3] = attrib[3]; - out += 4; - break; - default: - assert(0); - } - } - debug_printf("\n"); - } -} - - - -static boolean update_shader( struct draw_context *draw ) -{ - const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); - - unsigned nr_attrs = vinfo->num_attribs; - unsigned i; - - for (i = 0; i < nr_attrs; i++) { - unsigned buf = draw->vertex_element[i].vertex_buffer_index; - - draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] + - draw->vertex_buffer[buf].buffer_offset + - draw->vertex_element[i].src_offset; - - draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch; - draw->vertex_fetch.fetch[i] = NULL; - } - - draw->vertex_fetch.nr_attrs = nr_attrs; - draw->vertex_fetch.fetch_func = NULL; - draw->vertex_fetch.pt_fetch = NULL; - - draw->pt.hw_vertex_size = vinfo->size * 4; - - draw->vertex_fetch.pt_fetch = fetch_store_general; - return TRUE; -} - - - - -static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr) -{ - switch (prim) { - case PIPE_PRIM_POINTS: - *first = 1; - *incr = 1; - return TRUE; - case PIPE_PRIM_LINES: - *first = 2; - *incr = 2; - return TRUE; - case PIPE_PRIM_LINE_STRIP: - *first = 2; - *incr = 1; - return TRUE; - case PIPE_PRIM_TRIANGLES: - *first = 3; - *incr = 3; - return TRUE; - case PIPE_PRIM_TRIANGLE_STRIP: - *first = 3; - *incr = 1; - return TRUE; - case PIPE_PRIM_QUADS: - *first = 4; - *incr = 4; - return TRUE; - case PIPE_PRIM_QUAD_STRIP: - *first = 4; - *incr = 2; - return TRUE; - default: - *first = 0; - *incr = 1; /* set to one so that count % incr works */ - return FALSE; - } -} - - - -static boolean set_prim( struct draw_context *draw, - unsigned prim, - unsigned count ) -{ - assert(!draw->user.elts); - - switch (prim) { - case PIPE_PRIM_LINE_LOOP: - if (count > 1024) - return FALSE; - return draw->render->set_primitive( draw->render, PIPE_PRIM_LINE_STRIP ); - - case PIPE_PRIM_TRIANGLE_FAN: - case PIPE_PRIM_POLYGON: - if (count > 1024) - return FALSE; - return draw->render->set_primitive( draw->render, prim ); - - case PIPE_PRIM_QUADS: - case PIPE_PRIM_QUAD_STRIP: - return draw->render->set_primitive( draw->render, PIPE_PRIM_TRIANGLES ); - - default: - return draw->render->set_primitive( draw->render, prim ); - break; - } - - return TRUE; -} - - - -#define INDEX(i) (start + (i)) -static void pt_draw_arrays( struct draw_context *draw, - unsigned start, - unsigned length ) -{ - ushort *tmp = NULL; - unsigned i, j; - - switch (draw->pt.prim) { - case PIPE_PRIM_LINE_LOOP: - tmp = MALLOC( sizeof(ushort) * (length + 1) ); - - for (i = 0; i < length; i++) - tmp[i] = INDEX(i); - tmp[length] = 0; - - draw->render->draw( draw->render, - tmp, - length+1 ); - break; - - - case PIPE_PRIM_QUAD_STRIP: - tmp = MALLOC( sizeof(ushort) * (length / 2 * 6) ); - - for (j = i = 0; i + 3 < length; i += 2, j += 6) { - tmp[j+0] = INDEX(i+0); - tmp[j+1] = INDEX(i+1); - tmp[j+2] = INDEX(i+3); - - tmp[j+3] = INDEX(i+2); - tmp[j+4] = INDEX(i+0); - tmp[j+5] = INDEX(i+3); - } - - if (j) - draw->render->draw( draw->render, tmp, j ); - break; - - case PIPE_PRIM_QUADS: - tmp = MALLOC( sizeof(int) * (length / 4 * 6) ); - - for (j = i = 0; i + 3 < length; i += 4, j += 6) { - tmp[j+0] = INDEX(i+0); - tmp[j+1] = INDEX(i+1); - tmp[j+2] = INDEX(i+3); - - tmp[j+3] = INDEX(i+1); - tmp[j+4] = INDEX(i+2); - tmp[j+5] = INDEX(i+3); - } - - if (j) - draw->render->draw( draw->render, tmp, j ); - break; - - default: - draw->render->draw_arrays( draw->render, - start, - length ); - break; - } - - if (tmp) - FREE(tmp); -} - - - -static boolean do_draw( struct draw_context *draw, - unsigned start, unsigned count ) -{ - float *hw_verts = - draw->render->allocate_vertices( draw->render, - (ushort)draw->pt.hw_vertex_size, - (ushort)count ); - - if (!hw_verts) - return FALSE; - - /* Single routine to fetch vertices and emit HW verts. - */ - draw->vertex_fetch.pt_fetch( draw, - hw_verts, - start, count ); - - /* Draw arrays path to avoid re-emitting index list again and - * again. - */ - pt_draw_arrays( draw, - 0, - count ); - - - draw->render->release_vertices( draw->render, - hw_verts, - draw->pt.hw_vertex_size, - count ); - - return TRUE; -} - - -boolean -draw_passthrough_arrays(struct draw_context *draw, - unsigned prim, - unsigned start, - unsigned count) -{ - unsigned i = 0; - unsigned first, incr; - - //debug_printf("%s prim %d start %d count %d\n", __FUNCTION__, prim, start, count); - - split_prim_inplace(prim, &first, &incr); - - count -= (count - first) % incr; - - debug_printf("%s %d %d %d\n", __FUNCTION__, prim, start, count); - - if (draw_need_pipeline(draw, prim)) - return FALSE; - - debug_printf("%s AAA\n", __FUNCTION__); - - if (!set_prim(draw, prim, count)) - return FALSE; - - /* XXX: need a single value that reflects the most recent call to - * driver->set_primitive: - */ - draw->pt.prim = prim; - - debug_printf("%s BBB\n", __FUNCTION__); - - if (!update_shader(draw)) - return FALSE; - - debug_printf("%s CCC\n", __FUNCTION__); - - /* Chop this up into bite-sized pieces that a driver should be able - * to devour -- problem is we don't have a quick way to query the - * driver on the maximum size for this chunk in the current state. - */ - while (i + first <= count) { - int nr = MIN2( count - i, 1024 ); - - /* snap to prim boundary - */ - nr -= (nr - first) % incr; - - if (!do_draw( draw, start + i, nr )) { - assert(0); - return FALSE; - } - - /* increment allowing for repeated vertices - */ - i += nr - (first - incr); - } - - - debug_printf("%s DONE\n", __FUNCTION__); - return TRUE; -} - - -- cgit v1.2.3 From 23b03c536daa47b53e585fa98476bad96eb73529 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 15:12:01 -0600 Subject: gallium: updated comment for bypass_vs --- src/gallium/include/pipe/p_state.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 0eeee47a9a..a73028814e 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -111,7 +111,8 @@ struct pipe_rasterizer_state unsigned line_stipple_pattern:16; unsigned line_last_pixel:1; unsigned bypass_clipping:1; - unsigned bypass_vs:1; /**< vertices are already fully transformed */ + unsigned bypass_vs:1; /**< Skip the vertex shader. Note that the shader is + still needed though, to indicate inputs/outputs */ unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */ -- cgit v1.2.3 From 8a81429fa866cc1e2a14dec7e888fd2c888dc40a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 1 Apr 2008 07:22:10 +0900 Subject: gallium: Compute YCBCR bit depth. --- src/gallium/include/pipe/p_format.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 3238b152b6..9e0f91f202 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -439,7 +439,8 @@ static INLINE uint pf_get_component_bits( enum pipe_format format, uint comp ) */ static INLINE uint pf_get_bits( enum pipe_format format ) { - if (pf_layout(format) == PIPE_FORMAT_LAYOUT_RGBAZS) { + switch (pf_layout(format)) { + case PIPE_FORMAT_LAYOUT_RGBAZS: return pf_get_component_bits( format, PIPE_FORMAT_COMP_R ) + pf_get_component_bits( format, PIPE_FORMAT_COMP_G ) + @@ -447,11 +448,11 @@ static INLINE uint pf_get_bits( enum pipe_format format ) pf_get_component_bits( format, PIPE_FORMAT_COMP_A ) + pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) + pf_get_component_bits( format, PIPE_FORMAT_COMP_S ); - } - else { - assert( pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR ); - - /* TODO */ + case PIPE_FORMAT_LAYOUT_YCBCR: + assert( format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV ); + /* return effective bits per pixel */ + return 16; + default: assert( 0 ); return 0; } -- cgit v1.2.3 From ab8bcc4ec626be2d09bcdbaba2d1030b8dac7e25 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 16:35:13 -0600 Subject: cell: implement logicop/output for PIPE_FORMAT_B8G8R8A8_UNORM Remote display to my usual terminal shows the right colors again. Not 100% sure about the shuffle control words, but they seem to work. --- .../drivers/cell/ppu/cell_state_per_fragment.c | 36 ++++++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index f10025bd7c..0a79cccc83 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -1164,7 +1164,7 @@ int PC_OFFSET(const struct spe_function *f, const void *d) * masking. * * \bug - * This routine is hard-coded to only work with ARGB8 data. + * Only two framebuffer formats are supported at this time. */ void cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend, @@ -1235,15 +1235,31 @@ cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend, /* Convert fragment colors to framebuffer format in AoS layout. */ - data[0] = 0x00010203; - data[1] = 0x10111213; - data[2] = 0x04050607; - data[3] = 0x14151617; - - data[4] = 0x0c000408; - data[5] = 0x80808080; - data[6] = 0x80808080; - data[7] = 0x80808080; + switch (surf->format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + data[0] = 0x00010203; + data[1] = 0x10111213; + data[2] = 0x04050607; + data[3] = 0x14151617; + data[4] = 0x0c000408; + data[5] = 0x80808080; + data[6] = 0x80808080; + data[7] = 0x80808080; + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + data[0] = 0x03020100; + data[1] = 0x13121110; + data[2] = 0x07060504; + data[3] = 0x17161514; + data[4] = 0x0804000c; + data[5] = 0x80808080; + data[6] = 0x80808080; + data[7] = 0x80808080; + break; + default: + fprintf(stderr, "CELL: Bad pixel format in cell_generate_logic_op()"); + ASSERT(0); + } spe_ilh(f, tmp[0], 0x0808); spe_lqr(f, shuf_xpose_hi, PC_OFFSET(f, data+0)); -- cgit v1.2.3 From 58b6690cf84147f88ea2ba95d2a929089e93b57f Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 16:44:56 -0600 Subject: cell: updated comments: s/test/SPE/ --- src/gallium/drivers/cell/common.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index b0928fefd2..c9e873b35c 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -109,7 +109,7 @@ */ struct cell_command_depth_stencil_alpha_test { uint64_t base; /**< Effective address of code start. */ - unsigned size; /**< Size in bytes of test code. */ + unsigned size; /**< Size in bytes of SPE code. */ unsigned read_depth; /**< Flag: should depth be read? */ unsigned read_stencil; /**< Flag: should stencil be read? */ }; @@ -120,14 +120,14 @@ struct cell_command_depth_stencil_alpha_test { */ struct cell_command_blend { uint64_t base; /**< Effective address of code start. */ - unsigned size; /**< Size in bytes of test code. */ + unsigned size; /**< Size in bytes of SPE code. */ unsigned read_fb; /**< Flag: should framebuffer be read? */ }; struct cell_command_logicop { uint64_t base; /**< Effective address of code start. */ - unsigned size; /**< Size in bytes of test code. */ + unsigned size; /**< Size in bytes of SPE code. */ }; -- cgit v1.2.3 From 84c2821d2a3b0252d6ccdfc88c6acd8f72134ebf Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 16:54:31 -0600 Subject: cell: added const qualifier --- src/gallium/drivers/cell/ppu/cell_state_per_fragment.c | 3 ++- src/gallium/drivers/cell/ppu/cell_state_per_fragment.h | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index 0a79cccc83..53ae3aa50e 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -1167,7 +1167,8 @@ int PC_OFFSET(const struct spe_function *f, const void *d) * Only two framebuffer formats are supported at this time. */ void -cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend, +cell_generate_logic_op(struct spe_function *f, + const struct pipe_blend_state *blend, struct pipe_surface *surf) { const unsigned logic_op = (blend->logicop_enable) diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h index ab4de96c69..a8267a5133 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h @@ -32,7 +32,8 @@ extern void cell_generate_alpha_blend(struct cell_blend_state *cb); extern void -cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend, - struct pipe_surface *surf); +cell_generate_logic_op(struct spe_function *f, + const struct pipe_blend_state *blend, + struct pipe_surface *surf); #endif /* CELL_STATE_PER_FRAGMENT_H */ -- cgit v1.2.3 From 14452aee73e16f2ede075cf894e69d62cc539f5e Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 17:38:21 -0600 Subject: cell: initial work to support multi-texture --- src/gallium/drivers/cell/common.h | 8 +++++-- src/gallium/drivers/cell/ppu/cell_state_emit.c | 18 +++++++--------- src/gallium/drivers/cell/spu/spu_main.c | 27 ++++++++++++++++-------- src/gallium/drivers/cell/spu/spu_main.h | 8 +++---- src/gallium/drivers/cell/spu/spu_texture.c | 29 ++++++++++++++++---------- src/gallium/drivers/cell/spu/spu_tri.c | 2 +- 6 files changed, 55 insertions(+), 37 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index c9e873b35c..298812fc20 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -66,6 +66,8 @@ #define CELL_MAX_SPUS 6 +#define CELL_MAX_SAMPLERS 4 + #define TILE_SIZE 32 @@ -228,8 +230,10 @@ struct cell_command_release_verts struct cell_command_texture { - void *start; /**< Address in main memory */ - uint width, height; + struct { + void *start; /**< Address in main memory */ + ushort width, height; + } texture[CELL_MAX_SAMPLERS]; }; diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 4c75caa025..4fbe1a21b8 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -129,17 +129,15 @@ cell_emit_state(struct cell_context *cell) if (cell->dirty & CELL_NEW_TEXTURE) { struct cell_command_texture texture; - if (cell->texture[0]) { - texture.start = cell->texture[0]->tiled_data; - texture.width = cell->texture[0]->base.width[0]; - texture.height = cell->texture[0]->base.height[0]; + uint i; + memset(&texture, 0, sizeof(texture)); + for (i = 0;i < CELL_MAX_SAMPLERS; i++) { + if (cell->texture[i]) { + texture.texture[i].start = cell->texture[i]->tiled_data; + texture.texture[i].width = cell->texture[i]->base.width[0]; + texture.texture[i].height = cell->texture[i]->base.height[0]; + } } - else { - texture.start = NULL; - texture.width = 0; - texture.height = 0; - } - emit_state_cmd(cell, CELL_CMD_STATE_TEXTURE, &texture, sizeof(struct cell_command_texture)); } diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index d7f46f8024..80fa5f7859 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -329,17 +329,26 @@ cmd_state_sampler(const struct pipe_sampler_state *state) static void cmd_state_texture(const struct cell_command_texture *texture) { - if (Debug) - printf("SPU %u: TEXTURE at %p size %u x %u\n", - spu.init.id, texture->start, texture->width, texture->height); + uint i; + + if (1||Debug) { + printf("SPU %u: TEXTURE\n", spu.init.id); + for (i = 0; i < CELL_MAX_SAMPLERS; i++) { + printf(" %d: at %p size %u x %u\n", i, texture->texture[i].start, + texture->texture[i].width, texture->texture[i].height); + } + } memcpy(&spu.texture, texture, sizeof(*texture)); - spu.tex_size = (vector float) - { spu.texture.width, spu.texture.height, 0.0, 0.0}; - spu.tex_size_mask = (vector unsigned int) - { spu.texture.width - 1, spu.texture.height - 1, 0, 0 }; - spu.tex_size_x_mask = spu_splats(spu.texture.width - 1); - spu.tex_size_y_mask = spu_splats(spu.texture.height - 1); + for (i = 0; i < CELL_MAX_SAMPLERS; i++) { + const uint width = texture->texture[i].width; + const uint height = texture->texture[i].height; + spu.tex_size[i] = (vector float) { width, height, 0.0, 0.0}; + spu.tex_size_mask[i] = (vector unsigned int) + { width - 1, height - 1, 0, 0 }; + spu.tex_size_x_mask[i] = spu_splats(width - 1); + spu.tex_size_y_mask[i] = spu_splats(height - 1); + } } diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index c20452931a..8a87787537 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -141,10 +141,10 @@ struct spu_global /** for converting RGBA to PIPE_FORMAT_x colors */ vector unsigned char color_shuffle; - vector float tex_size; - vector unsigned int tex_size_mask; /**< == int(size - 1) */ - vector unsigned int tex_size_x_mask; /**< == int(size - 1) */ - vector unsigned int tex_size_y_mask; /**< == int(size - 1) */ + vector float tex_size[CELL_MAX_SAMPLERS]; + vector unsigned int tex_size_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */ + vector unsigned int tex_size_x_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */ + vector unsigned int tex_size_y_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */ vector float (*sample_texture)(vector float texcoord); diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index 67eb08196a..91a6aec5ec 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -40,25 +40,29 @@ void invalidate_tex_cache(void) { - spu_dcache_mark_dirty((unsigned) spu.texture.start, - 4 * spu.texture.width * spu.texture.height); + uint unit = 0; + uint bytes = 4 * spu.texture.texture[unit].width + * spu.texture.texture[unit].height; + + spu_dcache_mark_dirty((unsigned) spu.texture.texture[unit].start, bytes); } static uint get_texel(vec_uint4 coordinate) { + const uint unit = 0; vec_uint4 tmp; unsigned x = spu_extract(coordinate, 0); unsigned y = spu_extract(coordinate, 1); - const unsigned tiles_per_row = spu.texture.width / TILE_SIZE; + const unsigned tiles_per_row = spu.texture.texture[unit].width / TILE_SIZE; unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row) + (x / TILE_SIZE)); unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE) + (x % TILE_SIZE)); spu_dcache_fetch_unaligned((qword *) & tmp, - spu.texture.start + tile_offset + texel_offset, + spu.texture.texture[unit].start + tile_offset + texel_offset, 4); return spu_extract(tmp, 0); } @@ -67,13 +71,14 @@ get_texel(vec_uint4 coordinate) static void get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels) { - const unsigned texture_ea = (uintptr_t) spu.texture.start; + const uint unit = 0; + const unsigned texture_ea = (uintptr_t) spu.texture.texture[unit].start; vec_uint4 tile_x = spu_rlmask(x, -5); vec_uint4 tile_y = spu_rlmask(y, -5); const qword offset_x = si_andi((qword) x, 0x1f); const qword offset_y = si_andi((qword) y, 0x1f); - const qword tiles_per_row = (qword) spu_splats(spu.texture.width / TILE_SIZE); + const qword tiles_per_row = (qword) spu_splats(spu.texture.texture[unit].width / TILE_SIZE); const qword tile_size = (qword) spu_splats(sizeof(tile_t)); qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x); @@ -101,9 +106,10 @@ get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels) vector float sample_texture_nearest(vector float texcoord) { - vector float tc = spu_mul(texcoord, spu.tex_size); + const uint unit = 0; + vector float tc = spu_mul(texcoord, spu.tex_size[unit]); vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */ - itc = spu_and(itc, spu.tex_size_mask); /* mask (GL_REPEAT) */ + itc = spu_and(itc, spu.tex_size_mask[unit]); /* mask (GL_REPEAT) */ uint texel = get_texel(itc); return spu_unpack_A8R8G8B8(texel); } @@ -112,10 +118,11 @@ sample_texture_nearest(vector float texcoord) vector float sample_texture_bilinear(vector float texcoord) { + const uint unit = 0; static const vec_uint4 offset_x = {0, 0, 1, 1}; static const vec_uint4 offset_y = {0, 1, 0, 1}; - vector float tc = spu_mul(texcoord, spu.tex_size); + vector float tc = spu_mul(texcoord, spu.tex_size[unit]); tc = spu_add(tc, spu_splats(-0.5f)); /* half texel bias */ /* integer texcoords S,T: */ @@ -129,8 +136,8 @@ sample_texture_bilinear(vector float texcoord) x = spu_add(x, offset_x); y = spu_add(y, offset_y); - x = spu_and(x, spu.tex_size_x_mask); - y = spu_and(y, spu.tex_size_y_mask); + x = spu_and(x, spu.tex_size_x_mask[unit]); + y = spu_and(y, spu.tex_size_y_mask[unit]); get_four_texels(x, y, texels); diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index 95c629a8aa..9f63317b1f 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -309,7 +309,7 @@ emit_quad( int x, int y, mask_t mask ) spu.cur_ctile_status = TILE_STATUS_DIRTY; - if (spu.texture.start) { + if (spu.texture.texture[0].start) { /* texture mapping */ vector float texcoords[4]; eval_coeff(2, (float) x, (float) y, texcoords); -- cgit v1.2.3 From 686a6c746851b4bc2572aaa1153d570717bdd77f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 1 Apr 2008 10:41:43 +0900 Subject: gallium: Do not assume that buffers are freed in the same order they are fenced. Also free buffers as soon as possible. This short term fix corrects the fenced list behavior but it will impact on performance. The long term fix is probably replace the linked list (legacy from the bufpool code) by a binary tree. --- .../auxiliary/pipebuffer/pb_buffer_fenced.c | 39 ++++++++++++---------- 1 file changed, 21 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 6e217eb2e0..55f32e6816 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -29,8 +29,8 @@ * \file * Implementation of fenced buffers. * - * \author José Fonseca - * \author Thomas Hellström + * \author José Fonseca + * \author Thomas Hellström */ @@ -44,7 +44,7 @@ #include "pb_buffer.h" #include "pb_buffer_fenced.h" -#ifndef __MSC__ +#ifndef WIN32 #include #endif @@ -93,8 +93,6 @@ fenced_buffer(struct pb_buffer *buf) } - - static void _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, int wait) @@ -105,15 +103,6 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, int signaled = -1; list = fenced_list->delayed.next; - - if (fenced_list->numDelayed > 3) { - unsigned i; - - for (i = 0; i < fenced_list->numDelayed; i += 3) { - list = list->next; - } - } - prev = list->prev; for (; list != &fenced_list->delayed; list = prev, prev = list->prev) { @@ -128,11 +117,17 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, } } - if (signaled != 0) + if (signaled != 0) { +#if 0 /* XXX: we are assuming that buffers are freed in the same order they * are fenced which may not always be true... */ break; +#else + signaled = -1; + continue; +#endif + } winsys->fence_reference(winsys, &fenced_buf->fence, NULL); @@ -154,8 +149,16 @@ fenced_buffer_destroy(struct pb_buffer *buf) struct fenced_buffer_list *fenced_list = fenced_buf->list; if (fenced_buf->fence) { - LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); - fenced_list->numDelayed++; + struct pipe_winsys *winsys = fenced_list->winsys; + if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) { + LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); + fenced_list->numDelayed++; + } + else { + winsys->fence_reference(winsys, &fenced_buf->fence, NULL); + pb_reference(&fenced_buf->buffer, NULL); + FREE(fenced_buf); + } } else { pb_reference(&fenced_buf->buffer, NULL); @@ -285,7 +288,7 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list) /* Wait on outstanding fences */ while (fenced_list->numDelayed) { _glthread_UNLOCK_MUTEX(fenced_list->mutex); -#ifndef __MSC__ +#ifndef WIN32 sched_yield(); #endif _fenced_buffer_list_check_free(fenced_list, 1); -- cgit v1.2.3 From 5553a3b6757f0baaabbd67dd2f86d834d2f291ca Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 20:36:53 -0600 Subject: cell: set cell->num_textures in cell_set_sampler_textures() --- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 00f4be7401..52c3126050 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -273,6 +273,7 @@ cell_set_sampler_textures(struct pipe_context *pipe, pipe_texture_reference((struct pipe_texture **) &cell->texture[i], tex); } + cell->num_textures = num; cell_update_texture_mapping(cell); -- cgit v1.2.3 From e6c981f22c0b6469ef44e9d7a34113db34647fef Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 21:09:02 -0600 Subject: cell: more work for multi-texture support --- src/gallium/drivers/cell/common.h | 17 ++++++-- src/gallium/drivers/cell/ppu/cell_state_emit.c | 31 ++++++++++----- src/gallium/drivers/cell/spu/spu_main.c | 55 +++++++++++++++----------- src/gallium/drivers/cell/spu/spu_main.h | 18 ++++++--- src/gallium/drivers/cell/spu/spu_texture.c | 24 +++++------ src/gallium/drivers/cell/spu/spu_tri.c | 2 +- 6 files changed, 90 insertions(+), 57 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index 298812fc20..f430e88b9c 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -36,6 +36,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_util.h" #include "pipe/p_format.h" +#include "pipe/p_state.h" /** The standard assert macro doesn't seem to work reliably */ @@ -228,12 +229,20 @@ struct cell_command_release_verts }; +struct cell_command_sampler +{ + uint64_t opcode; /**< CELL_CMD_STATE_SAMPLER */ + uint unit; + struct pipe_sampler_state state; +}; + + struct cell_command_texture { - struct { - void *start; /**< Address in main memory */ - ushort width, height; - } texture[CELL_MAX_SAMPLERS]; + uint64_t opcode; /**< CELL_CMD_STATE_TEXTURE */ + uint unit; + void *start; /**< Address in main memory */ + ushort width, height; }; diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 4fbe1a21b8..9cae67f091 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -121,25 +121,36 @@ cell_emit_state(struct cell_context *cell) } if (cell->dirty & CELL_NEW_SAMPLER) { - if (cell->sampler[0]) { - emit_state_cmd(cell, CELL_CMD_STATE_SAMPLER, - cell->sampler[0], sizeof(struct pipe_sampler_state)); + uint i; + for (i = 0; i < CELL_MAX_SAMPLERS; i++) { + if (cell->sampler[i]) { + struct cell_command_sampler *sampler + = cell_batch_alloc(cell, sizeof(*sampler)); + sampler->opcode = CELL_CMD_STATE_SAMPLER; + sampler->unit = i; + sampler->state = *cell->sampler[i]; + } } } if (cell->dirty & CELL_NEW_TEXTURE) { - struct cell_command_texture texture; uint i; - memset(&texture, 0, sizeof(texture)); for (i = 0;i < CELL_MAX_SAMPLERS; i++) { + struct cell_command_texture *texture + = cell_batch_alloc(cell, sizeof(*texture)); + texture->opcode = CELL_CMD_STATE_TEXTURE; + texture->unit = i; if (cell->texture[i]) { - texture.texture[i].start = cell->texture[i]->tiled_data; - texture.texture[i].width = cell->texture[i]->base.width[0]; - texture.texture[i].height = cell->texture[i]->base.height[0]; + texture->start = cell->texture[i]->tiled_data; + texture->width = cell->texture[i]->base.width[0]; + texture->height = cell->texture[i]->base.height[0]; + } + else { + texture->start = NULL; + texture->width = 1; + texture->height = 1; } } - emit_state_cmd(cell, CELL_CMD_STATE_TEXTURE, - &texture, sizeof(struct cell_command_texture)); } if (cell->dirty & CELL_NEW_VERTEX_INFO) { diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 80fa5f7859..7f0473d198 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -312,13 +312,13 @@ cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *stat static void -cmd_state_sampler(const struct pipe_sampler_state *state) +cmd_state_sampler(const struct cell_command_sampler *sampler) { if (Debug) - printf("SPU %u: SAMPLER\n", - spu.init.id); + printf("SPU %u: SAMPLER [%u]\n", + spu.init.id, sampler->unit); - memcpy(&spu.sampler[0], state, sizeof(*state)); + spu.sampler[sampler->unit] = sampler->state; if (spu.sampler[0].min_img_filter == PIPE_TEX_FILTER_LINEAR) spu.sample_texture = sample_texture_bilinear; else @@ -329,26 +329,25 @@ cmd_state_sampler(const struct pipe_sampler_state *state) static void cmd_state_texture(const struct cell_command_texture *texture) { - uint i; + const uint unit = texture->unit; + const uint width = texture->width; + const uint height = texture->height; - if (1||Debug) { - printf("SPU %u: TEXTURE\n", spu.init.id); - for (i = 0; i < CELL_MAX_SAMPLERS; i++) { - printf(" %d: at %p size %u x %u\n", i, texture->texture[i].start, - texture->texture[i].width, texture->texture[i].height); - } + if (Debug) { + printf("SPU %u: TEXTURE [%u] at %p size %u x %u\n", spu.init.id, + texture->unit, texture->start, + texture->width, texture->height); } - memcpy(&spu.texture, texture, sizeof(*texture)); - for (i = 0; i < CELL_MAX_SAMPLERS; i++) { - const uint width = texture->texture[i].width; - const uint height = texture->texture[i].height; - spu.tex_size[i] = (vector float) { width, height, 0.0, 0.0}; - spu.tex_size_mask[i] = (vector unsigned int) + spu.texture[unit].start = texture->start; + spu.texture[unit].width = width; + spu.texture[unit].height = height; + + spu.texture[unit].tex_size = (vector float) { width, height, 0.0, 0.0}; + spu.texture[unit].tex_size_mask = (vector unsigned int) { width - 1, height - 1, 0, 0 }; - spu.tex_size_x_mask[i] = spu_splats(width - 1); - spu.tex_size_y_mask[i] = spu_splats(height - 1); - } + spu.texture[unit].tex_size_x_mask = spu_splats(width - 1); + spu.texture[unit].tex_size_y_mask = spu_splats(height - 1); } @@ -480,12 +479,20 @@ cmd_batch(uint opcode) pos += (1 + ROUNDUP8(sizeof(struct cell_command_depth_stencil_alpha_test)) / 8); break; case CELL_CMD_STATE_SAMPLER: - cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]); - pos += (1 + ROUNDUP8(sizeof(struct pipe_sampler_state)) / 8); + { + struct cell_command_sampler *sampler + = (struct cell_command_sampler *) &buffer[pos]; + cmd_state_sampler(sampler); + pos += sizeof(*sampler) / 8; + } break; case CELL_CMD_STATE_TEXTURE: - cmd_state_texture((struct cell_command_texture *) &buffer[pos+1]); - pos += (1 + ROUNDUP8(sizeof(struct cell_command_texture)) / 8); + { + struct cell_command_texture *texture + = (struct cell_command_texture *) &buffer[pos]; + cmd_state_texture(texture); + pos += sizeof(*texture) / 8; + } break; case CELL_CMD_STATE_VERTEX_INFO: cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]); diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index 8a87787537..2bfad3535a 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -100,6 +100,17 @@ struct spu_framebuffer { } ALIGN16_ATTRIB; +struct spu_texture +{ + void *start; + uint width, height; + vector float tex_size; + vector unsigned int tex_size_mask; /**< == int(size - 1) */ + vector unsigned int tex_size_x_mask; /**< == int(size - 1) */ + vector unsigned int tex_size_y_mask; /**< == int(size - 1) */ +} ALIGN16_ATTRIB; + + /** * All SPU global/context state will be in singleton object of this type: */ @@ -119,7 +130,7 @@ struct spu_global logicop_func logicop; struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; - struct cell_command_texture texture; + struct spu_texture texture[PIPE_MAX_SAMPLERS]; struct vertex_info vertex_info; @@ -141,11 +152,6 @@ struct spu_global /** for converting RGBA to PIPE_FORMAT_x colors */ vector unsigned char color_shuffle; - vector float tex_size[CELL_MAX_SAMPLERS]; - vector unsigned int tex_size_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */ - vector unsigned int tex_size_x_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */ - vector unsigned int tex_size_y_mask[CELL_MAX_SAMPLERS]; /**< == int(size - 1) */ - vector float (*sample_texture)(vector float texcoord); } ALIGN16_ATTRIB; diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index 91a6aec5ec..4612501eb3 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -41,10 +41,10 @@ void invalidate_tex_cache(void) { uint unit = 0; - uint bytes = 4 * spu.texture.texture[unit].width - * spu.texture.texture[unit].height; + uint bytes = 4 * spu.texture[unit].width + * spu.texture[unit].height; - spu_dcache_mark_dirty((unsigned) spu.texture.texture[unit].start, bytes); + spu_dcache_mark_dirty((unsigned) spu.texture[unit].start, bytes); } @@ -55,14 +55,14 @@ get_texel(vec_uint4 coordinate) vec_uint4 tmp; unsigned x = spu_extract(coordinate, 0); unsigned y = spu_extract(coordinate, 1); - const unsigned tiles_per_row = spu.texture.texture[unit].width / TILE_SIZE; + const unsigned tiles_per_row = spu.texture[unit].width / TILE_SIZE; unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row) + (x / TILE_SIZE)); unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE) + (x % TILE_SIZE)); spu_dcache_fetch_unaligned((qword *) & tmp, - spu.texture.texture[unit].start + tile_offset + texel_offset, + spu.texture[unit].start + tile_offset + texel_offset, 4); return spu_extract(tmp, 0); } @@ -72,13 +72,13 @@ static void get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels) { const uint unit = 0; - const unsigned texture_ea = (uintptr_t) spu.texture.texture[unit].start; + const unsigned texture_ea = (uintptr_t) spu.texture[unit].start; vec_uint4 tile_x = spu_rlmask(x, -5); vec_uint4 tile_y = spu_rlmask(y, -5); const qword offset_x = si_andi((qword) x, 0x1f); const qword offset_y = si_andi((qword) y, 0x1f); - const qword tiles_per_row = (qword) spu_splats(spu.texture.texture[unit].width / TILE_SIZE); + const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].width / TILE_SIZE); const qword tile_size = (qword) spu_splats(sizeof(tile_t)); qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x); @@ -107,9 +107,9 @@ vector float sample_texture_nearest(vector float texcoord) { const uint unit = 0; - vector float tc = spu_mul(texcoord, spu.tex_size[unit]); + vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size); vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */ - itc = spu_and(itc, spu.tex_size_mask[unit]); /* mask (GL_REPEAT) */ + itc = spu_and(itc, spu.texture[unit].tex_size_mask); /* mask (GL_REPEAT) */ uint texel = get_texel(itc); return spu_unpack_A8R8G8B8(texel); } @@ -122,7 +122,7 @@ sample_texture_bilinear(vector float texcoord) static const vec_uint4 offset_x = {0, 0, 1, 1}; static const vec_uint4 offset_y = {0, 1, 0, 1}; - vector float tc = spu_mul(texcoord, spu.tex_size[unit]); + vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size); tc = spu_add(tc, spu_splats(-0.5f)); /* half texel bias */ /* integer texcoords S,T: */ @@ -136,8 +136,8 @@ sample_texture_bilinear(vector float texcoord) x = spu_add(x, offset_x); y = spu_add(y, offset_y); - x = spu_and(x, spu.tex_size_x_mask[unit]); - y = spu_and(y, spu.tex_size_y_mask[unit]); + x = spu_and(x, spu.texture[unit].tex_size_x_mask); + y = spu_and(y, spu.texture[unit].tex_size_y_mask); get_four_texels(x, y, texels); diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index 9f63317b1f..17e337bbdf 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -309,7 +309,7 @@ emit_quad( int x, int y, mask_t mask ) spu.cur_ctile_status = TILE_STATUS_DIRTY; - if (spu.texture.texture[0].start) { + if (spu.texture[0].start) { /* texture mapping */ vector float texcoords[4]; eval_coeff(2, (float) x, (float) y, texcoords); -- cgit v1.2.3 From d83e0c45bec8d08c249088f9e8575505355fe595 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 31 Mar 2008 21:15:57 -0600 Subject: cell: update some of the CAP, texformat queries --- src/gallium/drivers/cell/ppu/cell_screen.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 124670df25..84b48bf4f1 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -55,11 +55,11 @@ cell_get_param(struct pipe_screen *screen, int param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 8; + return PIPE_MAX_SAMPLERS; case PIPE_CAP_NPOT_TEXTURES: - return 1; + return 0; case PIPE_CAP_TWO_SIDED_STENCIL: - return 1; + return 0; case PIPE_CAP_GLSL: return 1; case PIPE_CAP_S3TC: @@ -67,13 +67,13 @@ cell_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_ANISOTROPIC_FILTER: return 0; case PIPE_CAP_POINT_SPRITE: - return 1; + return 0; case PIPE_CAP_MAX_RENDER_TARGETS: return 1; case PIPE_CAP_OCCLUSION_QUERY: - return 1; + return 0; case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 1; + return 0; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: return 12; /* max 2Kx2K */ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: @@ -118,8 +118,12 @@ cell_is_format_supported( struct pipe_screen *screen, { switch (type) { case PIPE_TEXTURE: - /* cell supports all texture formats, XXX for now anyway */ - return TRUE; + /* cell supports most texture formats, XXX for now anyway */ + if (format == PIPE_FORMAT_DXT5_RGBA || + format == PIPE_FORMAT_R8G8B8A8_SRGB) + return FALSE; + else + return TRUE; case PIPE_SURFACE: /* cell supports all (off-screen) surface formats, XXX for now */ return TRUE; -- cgit v1.2.3 From 2df9941368c807fb677d3d95a5c1dfffe719c26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 1 Apr 2008 13:00:51 +0100 Subject: scons: Fix test for building dri/intel winsys. --- src/gallium/winsys/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index f18d3bd2f8..e8a581adb2 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -1,6 +1,6 @@ Import('*') -if dri: +if 'intel' in env['winsys'] and dri: SConscript([ 'dri/SConscript', ]) -- cgit v1.2.3 From 4b1377b2403bcb34081f91991f1ffde06df17af1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 1 Apr 2008 14:14:06 +0100 Subject: draw: flush between pt/non-pt modes --- src/gallium/auxiliary/draw/draw_pt.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index fc9304197a..df306a5fa4 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -167,6 +167,10 @@ draw_pt_arrays(struct draw_context *draw, frontend = draw->pt.front.vcache; #endif + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + frontend->prepare( frontend, middle ); frontend->run( frontend, -- cgit v1.2.3 From 52f40dcc468039fc9cca45a4de20a5aa11228b67 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 1 Apr 2008 14:14:46 +0100 Subject: draw: associate rhw divide with clipping not viewport flag --- src/gallium/auxiliary/draw/draw_vs_exec.c | 12 ++++++------ src/gallium/auxiliary/draw/draw_vs_llvm.c | 12 ++++++------ src/gallium/auxiliary/draw/draw_vs_sse.c | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index c8ed17c00a..c6e503686a 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -143,6 +143,12 @@ vs_exec_run( struct draw_vertex_shader *shader, if (!draw->rasterizer->bypass_clipping) { vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; } else { vOut[j]->clipmask = 0; @@ -150,12 +156,6 @@ vs_exec_run( struct draw_vertex_shader *shader, vOut[j]->edgeflag = 1; if (!draw->identity_viewport) { - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - /* Viewport mapping */ vOut[j]->data[0][0] = x * scale[0] + trans[0]; vOut[j]->data[0][1] = y * scale[1] + trans[1]; diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 8aa8a617bb..c8268317ef 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -153,6 +153,12 @@ vs_llvm_run( struct draw_vertex_shader *base, if (!draw->rasterizer->bypass_clipping) { vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; } else { vOut[j]->clipmask = 0; @@ -160,12 +166,6 @@ vs_llvm_run( struct draw_vertex_shader *base, vOut[j]->edgeflag = 1; if (!draw->identity_viewport) { - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - /* Viewport mapping */ vOut[j]->data[0][0] = x * scale[0] + trans[0]; vOut[j]->data[0][1] = y * scale[1] + trans[1]; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 701137f908..f40d65df08 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -168,6 +168,12 @@ vs_sse_run( struct draw_vertex_shader *base, if (!draw->rasterizer->bypass_clipping) { vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; } else { vOut[j]->clipmask = 0; @@ -175,12 +181,6 @@ vs_sse_run( struct draw_vertex_shader *base, vOut[j]->edgeflag = 1; if (!draw->identity_viewport) { - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - /* Viewport mapping */ vOut[j]->data[0][0] = x * scale[0] + trans[0]; vOut[j]->data[0][1] = y * scale[1] + trans[1]; -- cgit v1.2.3 From caa44763f7f7aa26ed0b0d1e5af0c410fba6bfe6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 1 Apr 2008 14:48:59 +0100 Subject: draw: respect flatshade_first in flatshade stage --- src/gallium/auxiliary/draw/draw_flatshade.c | 55 +++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_flatshade.c b/src/gallium/auxiliary/draw/draw_flatshade.c index ccad71d695..af2cb05c98 100644 --- a/src/gallium/auxiliary/draw/draw_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_flatshade.c @@ -84,8 +84,25 @@ static INLINE void copy_colors2( struct draw_stage *stage, * Flatshade tri. Required for clipping and when unfilled tris are * active, otherwise handled by hardware. */ -static void flatshade_tri( struct draw_stage *stage, - struct prim_header *header ) +static void flatshade_tri_0( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + tmp.v[0] = header->v[0]; + tmp.v[1] = dup_vert(stage, header->v[1], 0); + tmp.v[2] = dup_vert(stage, header->v[2], 1); + + copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]); + + stage->next->tri( stage->next, &tmp ); +} + + +static void flatshade_tri_2( struct draw_stage *stage, + struct prim_header *header ) { struct prim_header tmp; @@ -101,11 +118,27 @@ static void flatshade_tri( struct draw_stage *stage, } + + + /** * Flatshade line. Required for clipping. */ -static void flatshade_line( struct draw_stage *stage, - struct prim_header *header ) +static void flatshade_line_0( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.v[0] = header->v[0]; + tmp.v[1] = dup_vert(stage, header->v[1], 0); + + copy_colors(stage, tmp.v[1], tmp.v[0]); + + stage->next->line( stage->next, &tmp ); +} + +static void flatshade_line_1( struct draw_stage *stage, + struct prim_header *header ) { struct prim_header tmp; @@ -118,6 +151,8 @@ static void flatshade_line( struct draw_stage *stage, } +/* Flatshade point -- passthrough. + */ static void flatshade_point( struct draw_stage *stage, struct prim_header *header ) { @@ -140,8 +175,16 @@ static void flatshade_init_state( struct draw_stage *stage ) } } - stage->line = flatshade_line; - stage->tri = flatshade_tri; + /* Choose flatshade routine according to provoking vertex: + */ + if (stage->draw->rasterizer->flatshade_first) { + stage->line = flatshade_line_0; + stage->tri = flatshade_tri_0; + } + else { + stage->line = flatshade_line_1; + stage->tri = flatshade_tri_2; + } } static void flatshade_first_tri( struct draw_stage *stage, -- cgit v1.2.3 From edfa8201a50c47376b7aa0c05d7851e3e1353bde Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 1 Apr 2008 14:49:56 +0100 Subject: draw: more flatshade_first changes - Reduce the number of changes to the normal vertex ordering - Assume that the hardware knows how to do this in the standard case. - Add support to the passthrough vcache path. --- src/gallium/auxiliary/draw/draw_prim.c | 102 +++++++--------------- src/gallium/auxiliary/draw/draw_pt.c | 2 +- src/gallium/auxiliary/draw/draw_pt.h | 2 +- src/gallium/auxiliary/draw/draw_pt_vcache.c | 127 ++++++++++++++++++++++++---- src/gallium/auxiliary/draw/draw_validate.c | 8 -- 5 files changed, 144 insertions(+), 97 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index 9779aa8440..4452376a70 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -343,21 +343,11 @@ draw_prim( struct draw_context *draw, break; case PIPE_PRIM_LINES: - if (flatfirst) { - for (i = 0; i+1 < count; i += 2) { - do_line( draw, - TRUE, - start + i + 1, - start + i + 0); - } - } - else { - for (i = 0; i+1 < count; i += 2) { - do_line( draw, - TRUE, - start + i + 0, - start + i + 1); - } + for (i = 0; i+1 < count; i += 2) { + do_line( draw, + TRUE, + start + i + 0, + start + i + 1); } break; @@ -378,63 +368,31 @@ draw_prim( struct draw_context *draw, break; case PIPE_PRIM_LINE_STRIP: - if (flatfirst) { - for (i = 1; i < count; i++) { - do_line( draw, - i == 1, - start + i, - start + i - 1 ); - } - } - else { - for (i = 1; i < count; i++) { - do_line( draw, - i == 1, - start + i - 1, - start + i ); - } + for (i = 1; i < count; i++) { + do_line( draw, + i == 1, + start + i - 1, + start + i ); } break; case PIPE_PRIM_TRIANGLES: - if (flatfirst) { - if (unfilled) { - for (i = 0; i+2 < count; i += 3) { - do_ef_triangle( draw, - 1, - ~0, - start + i + 1, - start + i + 2, - start + i + 0 ); - } - } - else { - for (i = 0; i+2 < count; i += 3) { - do_triangle( draw, - start + i + 1, - start + i + 2, - start + i + 0 ); - } + if (unfilled) { + for (i = 0; i+2 < count; i += 3) { + do_ef_triangle( draw, + 1, + ~0, + start + i + 0, + start + i + 1, + start + i + 2 ); } - } + } else { - if (unfilled) { - for (i = 0; i+2 < count; i += 3) { - do_ef_triangle( draw, - 1, - ~0, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - else { - for (i = 0; i+2 < count; i += 3) { - do_triangle( draw, - start + i + 0, - start + i + 1, - start + i + 2 ); - } + for (i = 0; i+2 < count; i += 3) { + do_triangle( draw, + start + i + 0, + start + i + 1, + start + i + 2 ); } } break; @@ -444,15 +402,15 @@ draw_prim( struct draw_context *draw, for (i = 0; i+2 < count; i++) { if (i & 1) { do_triangle( draw, + start + i + 0, start + i + 2, - start + i + 1, - start + i + 0 ); + start + i + 1 ); } else { do_triangle( draw, + start + i + 0, start + i + 1, - start + i + 2, - start + i + 0 ); + start + i + 2 ); } } } @@ -479,9 +437,9 @@ draw_prim( struct draw_context *draw, if (flatfirst) { for (i = 0; i+2 < count; i++) { do_triangle( draw, + start + i + 1, start + i + 2, - start + 0, - start + i + 1 ); + start + 0 ); } } else { diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index df306a5fa4..2ea96c686d 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -191,7 +191,7 @@ boolean draw_pt_init( struct draw_context *draw ) if (!draw->pt.middle.fetch_emit) return FALSE; - draw->pt.front.vcache = draw_pt_vcache(); + draw->pt.front.vcache = draw_pt_vcache( draw ); if (!draw->pt.front.vcache) return FALSE; diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 439fa4c881..f878616079 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -110,7 +110,7 @@ const void *draw_pt_elt_ptr( struct draw_context *draw, /* Implementations: */ -struct draw_pt_front_end *draw_pt_vcache( void ); +struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ); diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index da9a3a52ae..16ffedf580 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -44,6 +44,7 @@ struct vcache_frontend { struct draw_pt_front_end base; + struct draw_context *draw; unsigned in[CACHE_MAX]; ushort out[CACHE_MAX]; @@ -157,14 +158,6 @@ static void vcache_quad( struct vcache_frontend *vcache, } -static void vcache_prepare( struct draw_pt_front_end *frontend, - struct draw_pt_middle_end *middle ) -{ - struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; - vcache->middle = middle; - middle->prepare( middle ); -} - static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { PIPE_PRIM_POINTS, PIPE_PRIM_LINES, @@ -179,11 +172,11 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { }; -static void vcache_run( struct draw_pt_front_end *frontend, - unsigned prim, - pt_elt_func get_elt, - const void *elts, - unsigned count ) +static void vcache_run_pv2( struct draw_pt_front_end *frontend, + unsigned prim, + pt_elt_func get_elt, + const void *elts, + unsigned count ) { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; unsigned i; @@ -309,6 +302,109 @@ static void vcache_run( struct draw_pt_front_end *frontend, vcache_flush( vcache ); } + +static void vcache_run_pv0( struct draw_pt_front_end *frontend, + unsigned prim, + pt_elt_func get_elt, + const void *elts, + unsigned count ) +{ + struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; + unsigned i; + + /* These are for validation only: + */ + vcache->elt_func = get_elt; + vcache->elt_ptr = elts; + vcache->output_prim = reduced_prim[prim]; + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i ++) { + vcache_point( vcache, + get_elt(elts, i) ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) { + vcache_line( vcache, + TRUE, + get_elt(elts, i + 0), + get_elt(elts, i + 1)); + } + break; + + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < count; i++) { + vcache_line( vcache, + i == 1, + get_elt(elts, i - 1), + get_elt(elts, i) ); + } + break; + + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2) ); + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + for (i = 0; i+2 < count; i++) { + if (i & 1) { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 2), + get_elt(elts, i + 1) ); + } + else { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + for (i = 0; i+2 < count; i++) { + vcache_triangle( vcache, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0) ); + } + break; + + + default: + assert(0); + break; + } + + vcache_flush( vcache ); +} + +static void vcache_prepare( struct draw_pt_front_end *frontend, + struct draw_pt_middle_end *middle ) +{ + struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; + + if (vcache->draw->rasterizer->flatshade_first) + vcache->base.run = vcache_run_pv0; + else + vcache->base.run = vcache_run_pv2; + + vcache->middle = middle; + middle->prepare( middle ); +} + + + + static void vcache_finish( struct draw_pt_front_end *frontend ) { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; @@ -322,14 +418,15 @@ static void vcache_destroy( struct draw_pt_front_end *frontend ) } -struct draw_pt_front_end *draw_pt_vcache( void ) +struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ) { struct vcache_frontend *vcache = CALLOC_STRUCT( vcache_frontend ); vcache->base.prepare = vcache_prepare; - vcache->base.run = vcache_run; + vcache->base.run = NULL; vcache->base.finish = vcache_finish; vcache->base.destroy = vcache_destroy; + vcache->draw = draw; memset(vcache->in, ~0, sizeof(vcache->in)); diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index ad43f06f73..e163e078f0 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -76,10 +76,6 @@ draw_need_pipeline(const struct draw_context *draw, /* AA lines */ if (draw->rasterizer->line_smooth && draw->pipeline.aaline) return TRUE; - - /* first-vertex driven flatshading */ - if (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first) - return TRUE; } if (points(prim)) @@ -116,10 +112,6 @@ draw_need_pipeline(const struct draw_context *draw, /* two-side lighting */ if (draw->rasterizer->light_twoside) return TRUE; - - /* first-vertex driven flatshading */ - if (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first) - return TRUE; } /* polygon cull - this is difficult - hardware can cull just fine -- cgit v1.2.3 From 8f8b95ae58c6e51f3bf0bc6ed2fa5ac8b9e82f1e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 1 Apr 2008 15:19:30 +0100 Subject: draw: remove dead code --- src/gallium/auxiliary/draw/draw_prim.c | 37 ---------------------------------- 1 file changed, 37 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index 4452376a70..51b6950334 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -119,43 +119,6 @@ static void draw_prim_queue_flush( struct draw_context *draw ) draw_vertex_cache_unreference( draw ); } -static INLINE void fetch_and_store(struct draw_context *draw) -{ - /* run vertex shader on vertex cache entries, four per invokation */ -#if 0 - { - const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); - memcpy(draw->vs.queue[0].vertex, draw->vs.queue[i + j].elt, - count * vinfo->size); - } -#elif 0 - unsigned i; - - draw_update_vertex_fetch(draw); - for (i = 0; i < draw->vs.queue_nr; i += 4) { - struct vertex_header *dests[4]; - unsigned elts[4]; - struct tgsi_exec_machine *machine = &draw->machine; - int j, n = MIN2(4, draw->vs.queue_nr - i); - - for (j = 0; j < n; j++) { - elts[j] = draw->vs.queue[i + j].elt; - dests[j] = draw->vs.queue[i + j].vertex; - } - - for ( ; j < 4; j++) { - elts[j] = elts[0]; - dests[j] = draw->vs.queue[i + j].vertex; - } - //fetch directly into dests - draw->vertex_fetch.fetch_func(draw, machine, dests, count); - } -#endif - - draw->vs.post_nr = draw->vs.queue_nr; - draw->vs.queue_nr = 0; -} - void draw_do_flush( struct draw_context *draw, unsigned flags ) { if (0) -- cgit v1.2.3 From f8c09464f801e97b24ccdb1ba70444c60d4235bd Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 1 Apr 2008 11:05:32 -0600 Subject: cell: enable #define CACHE_STATS to print a cache report upon exit --- src/gallium/drivers/cell/spu/spu_dcache.c | 18 ++++++++++++++++++ src/gallium/drivers/cell/spu/spu_dcache.h | 3 +++ src/gallium/drivers/cell/spu/spu_main.c | 2 ++ 3 files changed, 23 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_dcache.c b/src/gallium/drivers/cell/spu/spu_dcache.c index a1701d80d1..167404cdc5 100644 --- a/src/gallium/drivers/cell/spu/spu_dcache.c +++ b/src/gallium/drivers/cell/spu/spu_dcache.c @@ -36,6 +36,7 @@ #define CACHE_SET_TAGID(set) (((set) & 0x03) + TAG_DCACHE0) #define CACHE_LOG2NNWAY 2 #define CACHE_LOG2NSETS 6 +/*#define CACHE_STATS 1*/ #include /* Yes folks, this is ugly. @@ -123,3 +124,20 @@ spu_dcache_mark_dirty(unsigned ea, unsigned size) ? (entry & ~CACHELINE_VALID) : entry; } } + + +/** + * Print cache utilization report + */ +void +spu_dcache_report(void) +{ +#ifdef CACHE_STATS + if (spu.init.id == 0) { + printf("SPU 0: Texture cache report:\n"); + cache_pr_stats(data); + } +#endif +} + + diff --git a/src/gallium/drivers/cell/spu/spu_dcache.h b/src/gallium/drivers/cell/spu/spu_dcache.h index 7a06b8c25a..39a19eb31b 100644 --- a/src/gallium/drivers/cell/spu/spu_dcache.h +++ b/src/gallium/drivers/cell/spu/spu_dcache.h @@ -31,4 +31,7 @@ spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size); extern void spu_dcache_mark_dirty(unsigned ea, unsigned size); +extern void +spu_dcache_report(void); + #endif /* SPU_DCACHE_H */ diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 7f0473d198..5b5a570a3c 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -629,6 +629,8 @@ main_loop(void) if (Debug) printf("SPU %u: Exit main loop\n", spu.init.id); + + spu_dcache_report(); } -- cgit v1.2.3 From 6ddd2df1aec329be494d342dbd88a9f5af5e7b2c Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 1 Apr 2008 11:28:27 -0600 Subject: cell: return CELL_MAX_SAMPLERS to indicate number of texture units --- src/gallium/drivers/cell/ppu/cell_screen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 84b48bf4f1..5198b51441 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -31,6 +31,7 @@ #include "pipe/p_defines.h" #include "pipe/p_screen.h" +#include "cell/common.h" #include "cell_screen.h" #include "cell_texture.h" #include "cell_winsys.h" @@ -55,7 +56,7 @@ cell_get_param(struct pipe_screen *screen, int param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return PIPE_MAX_SAMPLERS; + return CELL_MAX_SAMPLERS; case PIPE_CAP_NPOT_TEXTURES: return 0; case PIPE_CAP_TWO_SIDED_STENCIL: -- cgit v1.2.3 From c14da8f52407529f20f819e31a01356535de0117 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 1 Apr 2008 11:30:17 -0600 Subject: cell: assert num samplers/textures <= CELL_MAX_SAMPLERS --- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 52c3126050..67b87f16d7 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -232,12 +232,12 @@ cell_bind_sampler_states(struct pipe_context *pipe, { struct cell_context *cell = cell_context(pipe); - draw_flush(cell->draw); + assert(num <= CELL_MAX_SAMPLERS); - assert(unit < PIPE_MAX_SAMPLERS); + draw_flush(cell->draw); memcpy(cell->sampler, samplers, num * sizeof(void *)); - memset(&cell->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) * + memset(&cell->sampler[num], 0, (CELL_MAX_SAMPLERS - num) * sizeof(void *)); cell->num_samplers = num; @@ -261,6 +261,8 @@ cell_set_sampler_textures(struct pipe_context *pipe, struct cell_context *cell = cell_context(pipe); uint i; + assert(num <= CELL_MAX_SAMPLERS); + /* Check for no-op */ if (num == cell->num_textures && !memcmp(cell->texture, texture, num * sizeof(struct pipe_texture *))) @@ -268,7 +270,7 @@ cell_set_sampler_textures(struct pipe_context *pipe, draw_flush(cell->draw); - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + for (i = 0; i < CELL_MAX_SAMPLERS; i++) { struct pipe_texture *tex = i < num ? texture[i] : NULL; pipe_texture_reference((struct pipe_texture **) &cell->texture[i], tex); -- cgit v1.2.3 From e7b23d36df1ab3ac5b54ef8e4e56c4fd46db8257 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 1 Apr 2008 11:35:53 -0600 Subject: cell: checkpoint: more multi-texture work --- src/gallium/drivers/cell/ppu/cell_texture.c | 8 +++++-- src/gallium/drivers/cell/spu/spu_main.c | 2 +- src/gallium/drivers/cell/spu/spu_main.h | 2 +- src/gallium/drivers/cell/spu/spu_texture.c | 6 ++--- src/gallium/drivers/cell/spu/spu_texture.h | 4 ++-- src/gallium/drivers/cell/spu/spu_tri.c | 34 +++++++++++++++++++++++++---- 6 files changed, 42 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index 9c694e136d..c59d1f7f23 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -245,9 +245,13 @@ void cell_update_texture_mapping(struct cell_context *cell) { uint face = 0, level = 0, zslice = 0; + uint i; + + for (i = 0; i < CELL_MAX_SAMPLERS; i++) { + if (cell->texture[i]) + cell_tile_texture(cell, cell->texture[i]); + } - if (cell->texture[0]) - cell_tile_texture(cell, cell->texture[0]); #if 0 if (cell->tex_surf && cell->tex_map) { pipe_surface_unmap(cell->tex_surf); diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 5b5a570a3c..a840d01596 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -333,7 +333,7 @@ cmd_state_texture(const struct cell_command_texture *texture) const uint width = texture->width; const uint height = texture->height; - if (Debug) { + if (1||Debug) { printf("SPU %u: TEXTURE [%u] at %p size %u x %u\n", spu.init.id, texture->unit, texture->start, texture->width, texture->height); diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index 2bfad3535a..26e050cfc3 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -152,7 +152,7 @@ struct spu_global /** for converting RGBA to PIPE_FORMAT_x colors */ vector unsigned char color_shuffle; - vector float (*sample_texture)(vector float texcoord); + vector float (*sample_texture)(uint unit, vector float texcoord); } ALIGN16_ATTRIB; diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index 4612501eb3..58a426cc40 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -104,9 +104,8 @@ get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels) * XXX this is extremely primitive for now. */ vector float -sample_texture_nearest(vector float texcoord) +sample_texture_nearest(uint unit, vector float texcoord) { - const uint unit = 0; vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size); vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */ itc = spu_and(itc, spu.texture[unit].tex_size_mask); /* mask (GL_REPEAT) */ @@ -116,9 +115,8 @@ sample_texture_nearest(vector float texcoord) vector float -sample_texture_bilinear(vector float texcoord) +sample_texture_bilinear(uint unit, vector float texcoord) { - const uint unit = 0; static const vec_uint4 offset_x = {0, 0, 1, 1}; static const vec_uint4 offset_y = {0, 1, 0, 1}; diff --git a/src/gallium/drivers/cell/spu/spu_texture.h b/src/gallium/drivers/cell/spu/spu_texture.h index 95eb87080f..f7c9738be8 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.h +++ b/src/gallium/drivers/cell/spu/spu_texture.h @@ -37,11 +37,11 @@ invalidate_tex_cache(void); extern vector float -sample_texture_nearest(vector float texcoord); +sample_texture_nearest(uint unit, vector float texcoord); extern vector float -sample_texture_bilinear(vector float texcoord); +sample_texture_bilinear(uint unit, vector float texcoord); #endif /* SPU_TEXTURE_H */ diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index 17e337bbdf..51abcb1757 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -311,17 +311,43 @@ emit_quad( int x, int y, mask_t mask ) if (spu.texture[0].start) { /* texture mapping */ + const uint unit = 0; vector float texcoords[4]; eval_coeff(2, (float) x, (float) y, texcoords); if (spu_extract(mask, 0)) - colors[0] = spu.sample_texture(texcoords[0]); + colors[0] = spu.sample_texture(unit, texcoords[0]); if (spu_extract(mask, 1)) - colors[1] = spu.sample_texture(texcoords[1]); + colors[1] = spu.sample_texture(unit, texcoords[1]); if (spu_extract(mask, 2)) - colors[2] = spu.sample_texture(texcoords[2]); + colors[2] = spu.sample_texture(unit, texcoords[2]); if (spu_extract(mask, 3)) - colors[3] = spu.sample_texture(texcoords[3]); + colors[3] = spu.sample_texture(unit, texcoords[3]); + + + if (spu.texture[1].start) { + /* multi-texture mapping */ + const uint unit = 1; + vector float colors1[4]; + + eval_coeff(3, (float) x, (float) y, texcoords); + + if (spu_extract(mask, 0)) + colors1[0] = spu.sample_texture(unit, texcoords[0]); + if (spu_extract(mask, 1)) + colors1[1] = spu.sample_texture(unit, texcoords[1]); + if (spu_extract(mask, 2)) + colors1[2] = spu.sample_texture(unit, texcoords[2]); + if (spu_extract(mask, 3)) + colors1[3] = spu.sample_texture(unit, texcoords[3]); + + /* hack: modulate first texture by second */ + colors[0] = spu_mul(colors[0], colors1[0]); + colors[1] = spu_mul(colors[1], colors1[1]); + colors[2] = spu_mul(colors[2], colors1[2]); + colors[3] = spu_mul(colors[3], colors1[3]); + } + } else { /* simple shading */ -- cgit v1.2.3 From 2d02ee85093d8068f11ecb286c5f02f52786cd95 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 1 Apr 2008 14:52:04 -0600 Subject: cell: fix bug in texture tiling function (non-square textures work now) --- src/gallium/drivers/cell/ppu/cell_texture.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index c59d1f7f23..07717da8f6 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -186,15 +186,17 @@ tile_copy_data(uint w, uint h, uint tile_size, uint *dst, const uint *src) uint it, jt; /* tile counters */ uint i, j; /* intra-tile counters */ + /* loop over dest tiles */ for (it = 0; it < h_t; it++) { for (jt = 0; jt < w_t; jt++) { - /* fill in tile (i, j) */ + /* start of dest tile: */ uint *tdst = dst + (it * w_t + jt) * tile_size2; + /* loop over texels in the tile */ for (i = 0; i < tile_size; i++) { for (j = 0; j < tile_size; j++) { const uint srci = it * tile_size + i; const uint srcj = jt * tile_size + j; - *tdst++ = src[srci * h + srcj]; + *tdst++ = src[srci * w + srcj]; } } } -- cgit v1.2.3 From 9e7b730eb25f08065d718dee4a67c67d1d133b6e Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 1 Apr 2008 14:52:25 -0600 Subject: cell: pass tex unit to get_texel() --- src/gallium/drivers/cell/spu/spu_texture.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index 58a426cc40..ba0d57b959 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -49,9 +49,8 @@ invalidate_tex_cache(void) static uint -get_texel(vec_uint4 coordinate) +get_texel(uint unit, vec_uint4 coordinate) { - const uint unit = 0; vec_uint4 tmp; unsigned x = spu_extract(coordinate, 0); unsigned y = spu_extract(coordinate, 1); @@ -109,7 +108,7 @@ sample_texture_nearest(uint unit, vector float texcoord) vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size); vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */ itc = spu_and(itc, spu.texture[unit].tex_size_mask); /* mask (GL_REPEAT) */ - uint texel = get_texel(itc); + uint texel = get_texel(unit, itc); return spu_unpack_A8R8G8B8(texel); } -- cgit v1.2.3 From 9d1444092fbfd9f975cfb996695f0533a78410f7 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 1 Apr 2008 14:55:31 -0600 Subject: cell: turn off some debug output --- src/gallium/drivers/cell/spu/spu_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index a840d01596..5b5a570a3c 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -333,7 +333,7 @@ cmd_state_texture(const struct cell_command_texture *texture) const uint width = texture->width; const uint height = texture->height; - if (1||Debug) { + if (Debug) { printf("SPU %u: TEXTURE [%u] at %p size %u x %u\n", spu.init.id, texture->unit, texture->start, texture->width, texture->height); -- cgit v1.2.3 From bccd3f138ccc717fad9073110d15e3321b590476 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 1 Apr 2008 15:42:42 -0600 Subject: cell: more multi-texture fixes (mostly working now) --- src/gallium/drivers/cell/spu/spu_main.c | 6 +++--- src/gallium/drivers/cell/spu/spu_main.h | 4 +++- src/gallium/drivers/cell/spu/spu_texture.c | 5 ++--- src/gallium/drivers/cell/spu/spu_tri.c | 18 +++++++++--------- 4 files changed, 17 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 5b5a570a3c..1ab1c40379 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -319,10 +319,10 @@ cmd_state_sampler(const struct cell_command_sampler *sampler) spu.init.id, sampler->unit); spu.sampler[sampler->unit] = sampler->state; - if (spu.sampler[0].min_img_filter == PIPE_TEX_FILTER_LINEAR) - spu.sample_texture = sample_texture_bilinear; + if (spu.sampler[sampler->unit].min_img_filter == PIPE_TEX_FILTER_LINEAR) + spu.sample_texture[sampler->unit] = sample_texture_bilinear; else - spu.sample_texture = sample_texture_nearest; + spu.sample_texture[sampler->unit] = sample_texture_nearest; } diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index 26e050cfc3..e9e39cbeab 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -85,6 +85,8 @@ typedef struct spu_blend_results (*logicop_func)( qword frag_mask); +typedef vector float (*sample_texture_func)(uint unit, vector float texcoord); + struct spu_framebuffer { void *color_start; /**< addr of color surface in main memory */ void *depth_start; /**< addr of depth surface in main memory */ @@ -152,7 +154,7 @@ struct spu_global /** for converting RGBA to PIPE_FORMAT_x colors */ vector unsigned char color_shuffle; - vector float (*sample_texture)(uint unit, vector float texcoord); + sample_texture_func sample_texture[CELL_MAX_SAMPLERS]; } ALIGN16_ATTRIB; diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index ba0d57b959..ceab246980 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -68,9 +68,8 @@ get_texel(uint unit, vec_uint4 coordinate) static void -get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels) +get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) { - const uint unit = 0; const unsigned texture_ea = (uintptr_t) spu.texture[unit].start; vec_uint4 tile_x = spu_rlmask(x, -5); vec_uint4 tile_y = spu_rlmask(y, -5); @@ -136,7 +135,7 @@ sample_texture_bilinear(uint unit, vector float texcoord) x = spu_and(x, spu.texture[unit].tex_size_x_mask); y = spu_and(y, spu.texture[unit].tex_size_y_mask); - get_four_texels(x, y, texels); + get_four_texels(unit, x, y, texels); vector float texel00 = spu_unpack_A8R8G8B8(spu_extract(texels[0], 0)); vector float texel01 = spu_unpack_A8R8G8B8(spu_extract(texels[1], 0)); diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index 51abcb1757..ab4ff8160a 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -316,13 +316,13 @@ emit_quad( int x, int y, mask_t mask ) eval_coeff(2, (float) x, (float) y, texcoords); if (spu_extract(mask, 0)) - colors[0] = spu.sample_texture(unit, texcoords[0]); + colors[0] = spu.sample_texture[unit](unit, texcoords[0]); if (spu_extract(mask, 1)) - colors[1] = spu.sample_texture(unit, texcoords[1]); + colors[1] = spu.sample_texture[unit](unit, texcoords[1]); if (spu_extract(mask, 2)) - colors[2] = spu.sample_texture(unit, texcoords[2]); + colors[2] = spu.sample_texture[unit](unit, texcoords[2]); if (spu_extract(mask, 3)) - colors[3] = spu.sample_texture(unit, texcoords[3]); + colors[3] = spu.sample_texture[unit](unit, texcoords[3]); if (spu.texture[1].start) { @@ -330,16 +330,16 @@ emit_quad( int x, int y, mask_t mask ) const uint unit = 1; vector float colors1[4]; - eval_coeff(3, (float) x, (float) y, texcoords); + eval_coeff(2, (float) x, (float) y, texcoords); if (spu_extract(mask, 0)) - colors1[0] = spu.sample_texture(unit, texcoords[0]); + colors1[0] = spu.sample_texture[unit](unit, texcoords[0]); if (spu_extract(mask, 1)) - colors1[1] = spu.sample_texture(unit, texcoords[1]); + colors1[1] = spu.sample_texture[unit](unit, texcoords[1]); if (spu_extract(mask, 2)) - colors1[2] = spu.sample_texture(unit, texcoords[2]); + colors1[2] = spu.sample_texture[unit](unit, texcoords[2]); if (spu_extract(mask, 3)) - colors1[3] = spu.sample_texture(unit, texcoords[3]); + colors1[3] = spu.sample_texture[unit](unit, texcoords[3]); /* hack: modulate first texture by second */ colors[0] = spu_mul(colors[0], colors1[0]); -- cgit v1.2.3 From bc739440c29c551fcc44e9e12d0d9c170d8d24fb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 2 Apr 2008 10:43:37 +0100 Subject: gallium: add temporary facility for rasterization-time clamping of point sizes --- src/gallium/auxiliary/draw/draw_wide_point.c | 14 +++++++++++++- src/gallium/include/pipe/p_state.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c index c53f7e6cb3..86281ca3d8 100644 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_wide_point.c @@ -38,6 +38,8 @@ struct widepoint_stage { struct draw_stage stage; float half_point_size; + float point_size_min; + float point_size_max; uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; @@ -128,7 +130,15 @@ static void widepoint_point( struct draw_stage *stage, /* point size is either per-vertex or fixed size */ if (wide->psize_slot >= 0) { - half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; + half_size = header->v[0]->data[wide->psize_slot][0]; + + /* XXX: temporary -- do this in the vertex shader?? + */ + half_size = CLAMP(half_size, + wide->point_size_min, + wide->point_size_max); + + half_size *= 0.5f; } else { half_size = wide->half_point_size; @@ -182,6 +192,8 @@ static void widepoint_first_point( struct draw_stage *stage, struct draw_context *draw = stage->draw; wide->half_point_size = 0.5f * draw->rasterizer->point_size; + wide->point_size_min = draw->rasterizer->point_size_min; + wide->point_size_max = draw->rasterizer->point_size_max; /* XXX we won't know the real size if it's computed by the vertex shader! */ if ((draw->rasterizer->point_size > draw->wide_point_threshold) || diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index a73028814e..e407e3bc72 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -118,6 +118,8 @@ struct pipe_rasterizer_state float line_width; float point_size; /**< used when no per-vertex size */ + float point_size_min; /* XXX - temporary, will go away */ + float point_size_max; /* XXX - temporary, will go away */ float offset_units; float offset_scale; ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */ -- cgit v1.2.3 From 8e33194837dd206d920889851d9cf22190100c99 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 2 Apr 2008 11:38:33 +0100 Subject: gallium: add a flag to turn on gl rasterization rules Use this to set up hardware rasterization (if your hardware can do it) or otherwise turn on various tweaks in the draw module. Currently only hooked up to point biasing code. --- src/gallium/auxiliary/draw/draw_wide_point.c | 19 +++++++++++++------ src/gallium/include/pipe/p_state.h | 1 + 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c index 86281ca3d8..6fc7c9fcd7 100644 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_wide_point.c @@ -41,6 +41,9 @@ struct widepoint_stage { float point_size_min; float point_size_max; + float xbias; + float ybias; + uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; uint num_texcoords; @@ -126,8 +129,6 @@ static void widepoint_point( struct draw_stage *stage, float *pos2 = v2->data[0]; float *pos3 = v3->data[0]; - const float xbias = 0.0, ybias = -0.125; - /* point size is either per-vertex or fixed size */ if (wide->psize_slot >= 0) { half_size = header->v[0]->data[wide->psize_slot][0]; @@ -144,10 +145,10 @@ static void widepoint_point( struct draw_stage *stage, half_size = wide->half_point_size; } - left_adj = -half_size + xbias; - right_adj = half_size + xbias; - bot_adj = half_size + ybias; - top_adj = -half_size + ybias; + left_adj = -half_size + wide->xbias; + right_adj = half_size + wide->xbias; + bot_adj = half_size + wide->ybias; + top_adj = -half_size + wide->ybias; pos0[0] += left_adj; pos0[1] += top_adj; @@ -194,6 +195,12 @@ static void widepoint_first_point( struct draw_stage *stage, wide->half_point_size = 0.5f * draw->rasterizer->point_size; wide->point_size_min = draw->rasterizer->point_size_min; wide->point_size_max = draw->rasterizer->point_size_max; + wide->xbias = 0.0; + wide->ybias = 0.0; + + if (draw->rasterizer->gl_rasterization_rules) { + wide->ybias = -0.125; + } /* XXX we won't know the real size if it's computed by the vertex shader! */ if ((draw->rasterizer->point_size > draw->wide_point_threshold) || diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index e407e3bc72..3593446e1c 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -115,6 +115,7 @@ struct pipe_rasterizer_state still needed though, to indicate inputs/outputs */ unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */ + unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization? */ float line_width; float point_size; /**< used when no per-vertex size */ -- cgit v1.2.3 From ae3c91e98ce3355bca22738440f8ba313b3b8b23 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 2 Apr 2008 11:55:03 +0100 Subject: draw: Set the backend prim in the pt 'prepare' operation Leaving it until 'run' is bad as the primitive is pretty much state for some drivers and so needs to get set early. In some drivers this is used to determine things like vertex format, etc -- by the time we get to 'run', it's too late to change this. --- src/gallium/auxiliary/draw/draw_pt.c | 3 +-- src/gallium/auxiliary/draw/draw_pt.h | 6 ++--- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 33 ++++++++++++++----------- src/gallium/auxiliary/draw/draw_pt_vcache.c | 17 +++++++------ 4 files changed, 31 insertions(+), 28 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 2ea96c686d..c3baf5b7da 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -171,10 +171,9 @@ draw_pt_arrays(struct draw_context *draw, */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); - frontend->prepare( frontend, middle ); + frontend->prepare( frontend, prim, middle ); frontend->run( frontend, - prim, draw_pt_elt_func( draw ), draw_pt_elt_ptr( draw, start ), count ); diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index f878616079..428b1e0e6b 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -53,10 +53,10 @@ struct draw_context; */ struct draw_pt_front_end { void (*prepare)( struct draw_pt_front_end *, + unsigned prim, struct draw_pt_middle_end * ); void (*run)( struct draw_pt_front_end *, - unsigned prim, pt_elt_func elt_func, const void *elt_ptr, unsigned count ); @@ -79,10 +79,10 @@ struct draw_pt_front_end { * Currenly only using the passthrough version. */ struct draw_pt_middle_end { - void (*prepare)( struct draw_pt_middle_end * ); + void (*prepare)( struct draw_pt_middle_end *, + unsigned prim ); void (*run)( struct draw_pt_middle_end *, - unsigned prim, const unsigned *fetch_elts, unsigned fetch_count, const ushort *draw_elts, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 9b098bc173..9339cf1f88 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -203,16 +203,29 @@ fetch_store_general( struct fetch_emit_middle_end *feme, -static void fetch_emit_prepare( struct draw_pt_middle_end *middle ) +static void fetch_emit_prepare( struct draw_pt_middle_end *middle, + unsigned prim ) { static const float zero = 0; struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; - const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); - unsigned nr_attrs = vinfo->num_attribs; + const struct vertex_info *vinfo; unsigned i; + boolean ok; + + + ok = draw->render->set_primitive( draw->render, + prim ); + if (!ok) { + assert(0); + return; + } + + /* Must do this after set_primitive() above: + */ + vinfo = draw->render->get_vertex_info(draw->render); - for (i = 0; i < nr_attrs; i++) { + for (i = 0; i < vinfo->num_attribs; i++) { unsigned src_element = vinfo->src_index[i]; unsigned src_buffer = draw->vertex_element[src_element].vertex_buffer_index; @@ -275,7 +288,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle ) } } - feme->nr_fetch = nr_attrs; + feme->nr_fetch = vinfo->num_attribs; feme->hw_vertex_size = vinfo->size * 4; } @@ -284,7 +297,6 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle ) static void fetch_emit_run( struct draw_pt_middle_end *middle, - unsigned prim, const unsigned *fetch_elts, unsigned fetch_count, const ushort *draw_elts, @@ -293,16 +305,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; void *hw_verts; - boolean ok; - - ok = draw->render->set_primitive( draw->render, - prim ); - if (!ok) { - assert(0); - return; - } - hw_verts = draw->render->allocate_vertices( draw->render, (ushort)feme->hw_vertex_size, (ushort)fetch_count ); diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 16ffedf580..5a068761df 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -59,6 +59,8 @@ struct vcache_frontend { const void *elt_ptr; struct draw_pt_middle_end *middle; + + unsigned input_prim; unsigned output_prim; }; @@ -77,7 +79,6 @@ static void vcache_flush( struct vcache_frontend *vcache ) if (vcache->draw_count) { vcache->middle->run( vcache->middle, - vcache->output_prim, vcache->fetch_elts, vcache->fetch_count, vcache->draw_elts, @@ -173,7 +174,6 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { static void vcache_run_pv2( struct draw_pt_front_end *frontend, - unsigned prim, pt_elt_func get_elt, const void *elts, unsigned count ) @@ -185,9 +185,8 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend, */ vcache->elt_func = get_elt; vcache->elt_ptr = elts; - vcache->output_prim = reduced_prim[prim]; - switch (prim) { + switch (vcache->input_prim) { case PIPE_PRIM_POINTS: for (i = 0; i < count; i ++) { vcache_point( vcache, @@ -304,7 +303,6 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend, static void vcache_run_pv0( struct draw_pt_front_end *frontend, - unsigned prim, pt_elt_func get_elt, const void *elts, unsigned count ) @@ -316,9 +314,8 @@ static void vcache_run_pv0( struct draw_pt_front_end *frontend, */ vcache->elt_func = get_elt; vcache->elt_ptr = elts; - vcache->output_prim = reduced_prim[prim]; - switch (prim) { + switch (vcache->input_prim) { case PIPE_PRIM_POINTS: for (i = 0; i < count; i ++) { vcache_point( vcache, @@ -389,6 +386,7 @@ static void vcache_run_pv0( struct draw_pt_front_end *frontend, } static void vcache_prepare( struct draw_pt_front_end *frontend, + unsigned prim, struct draw_pt_middle_end *middle ) { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; @@ -398,8 +396,11 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, else vcache->base.run = vcache_run_pv2; + vcache->input_prim = prim; + vcache->output_prim = reduced_prim[prim]; + vcache->middle = middle; - middle->prepare( middle ); + middle->prepare( middle, vcache->output_prim ); } -- cgit v1.2.3 From add46fbc8cc04d3bce303815541a7bc5d0b33953 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 2 Apr 2008 12:05:55 +0100 Subject: draw: add missing break statement --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 9339cf1f88..f863a46d9c 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -281,6 +281,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, feme->fetch[i].pitch = 0; feme->fetch[i].fetch = fetch_R32_FLOAT; feme->fetch[i].emit = emit_R32_FLOAT; + break; default: assert(0); feme->fetch[i].emit = NULL; -- cgit v1.2.3 From d2cb4ba0bb2388c784f145c59f3798f914dc7f39 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 3 Apr 2008 12:21:30 +0100 Subject: draw: add passthrough path to the pipeline This handles the case where bypass_vs is set, but vertices need to go through the pipeline for some reason - eg unfilled polygon mode. Demonstrates how to drive the pipeline from inside one of these things. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/SConscript | 1 + src/gallium/auxiliary/draw/draw_private.h | 6 + src/gallium/auxiliary/draw/draw_pt.c | 23 +- src/gallium/auxiliary/draw/draw_pt.h | 1 + src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 64 +--- .../auxiliary/draw/draw_pt_fetch_pipeline.c | 391 +++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vertex_fetch.c | 4 +- 8 files changed, 424 insertions(+), 67 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index a0db2e4555..b28e516396 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -18,6 +18,7 @@ C_SOURCES = \ draw_pt.c \ draw_pt_vcache.c \ draw_pt_fetch_emit.c \ + draw_pt_fetch_pipeline.c \ draw_pt_elts.c \ draw_prim.c \ draw_pstipple.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 981225a8c2..9ca4197441 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -17,6 +17,7 @@ draw = env.ConvenienceLibrary( 'draw_pt.c', 'draw_pt_vcache.c', 'draw_pt_fetch_emit.c', + 'draw_pt_fetch_pipeline.c', 'draw_pt_elts.c', 'draw_prim.c', 'draw_pstipple.c', diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 9a9b25297f..0c9f9c2e03 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -160,6 +160,11 @@ struct draw_vertex_shader { /* Internal function for vertex fetch. */ typedef void (*fetch_func)(const void *ptr, float *attrib); + +fetch_func draw_get_fetch_func( enum pipe_format format ); + + + typedef void (*full_fetch_func)( struct draw_context *draw, struct tgsi_exec_machine *machine, const unsigned *elts, @@ -211,6 +216,7 @@ struct draw_context struct { struct draw_pt_middle_end *fetch_emit; + struct draw_pt_middle_end *fetch_pipeline; struct draw_pt_middle_end *fetch_shade_emit; struct draw_pt_middle_end *fetch_shade_cliptest_pipeline_or_emit; } middle; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index c3baf5b7da..f59fb86f78 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -73,7 +73,6 @@ draw_pt_arrays(struct draw_context *draw, */ -#if 0 if (!cliptest && !pipeline && !shading) { /* This is the 'passthrough' path: */ @@ -81,6 +80,14 @@ draw_pt_arrays(struct draw_context *draw, */ middle = draw->pt.middle.fetch_emit; } + else if (!cliptest && !shading) { + /* This is the 'passthrough' path targetting the pipeline backend. + */ + /* Fetch user verts, emit pipeline verts, run pipeline: + */ + middle = draw->pt.middle.fetch_pipeline; + } +#if 0 else if (!cliptest && !pipeline) { /* Fetch user verts, run vertex shader, emit hw verts: */ @@ -117,10 +124,9 @@ draw_pt_arrays(struct draw_context *draw, middle = draw->pt.middle.fetch_shade_cliptest_pipeline; } #else - if (cliptest || pipeline || shading) + else { return FALSE; - - middle = draw->pt.middle.fetch_emit; + } #endif @@ -190,6 +196,10 @@ boolean draw_pt_init( struct draw_context *draw ) if (!draw->pt.middle.fetch_emit) return FALSE; + draw->pt.middle.fetch_pipeline = draw_pt_fetch_pipeline( draw ); + if (!draw->pt.middle.fetch_pipeline) + return FALSE; + draw->pt.front.vcache = draw_pt_vcache( draw ); if (!draw->pt.front.vcache) return FALSE; @@ -205,6 +215,11 @@ void draw_pt_destroy( struct draw_context *draw ) draw->pt.middle.fetch_emit = NULL; } + if (draw->pt.middle.fetch_pipeline) { + draw->pt.middle.fetch_pipeline->destroy( draw->pt.middle.fetch_pipeline ); + draw->pt.middle.fetch_pipeline = NULL; + } + if (draw->pt.front.vcache) { draw->pt.front.vcache->destroy( draw->pt.front.vcache ); draw->pt.front.vcache = NULL; diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 428b1e0e6b..800072c511 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -112,6 +112,7 @@ const void *draw_pt_elt_ptr( struct draw_context *draw, */ struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ); +struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index f863a46d9c..39f0b40838 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -85,45 +85,6 @@ struct fetch_emit_middle_end { }; -static void fetch_B8G8R8A8_UNORM( const void *from, - float *attrib ) -{ - ubyte *ub = (ubyte *) from; - attrib[2] = UBYTE_TO_FLOAT(ub[0]); - attrib[1] = UBYTE_TO_FLOAT(ub[1]); - attrib[0] = UBYTE_TO_FLOAT(ub[2]); - attrib[3] = UBYTE_TO_FLOAT(ub[3]); -} - -static void fetch_R32G32B32A32_FLOAT( const void *from, - float *attrib ) -{ - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = f[2]; - attrib[3] = f[3]; -} - -static void fetch_R32G32B32_FLOAT( const void *from, - float *attrib ) -{ - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = f[2]; - attrib[3] = 1.0; -} - -static void fetch_R32G32_FLOAT( const void *from, - float *attrib ) -{ - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = 0.0; - attrib[3] = 1.0; -} static void fetch_R32_FLOAT( const void *from, float *attrib ) @@ -235,28 +196,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, feme->fetch[i].pitch = draw->vertex_buffer[src_buffer].pitch; - switch (draw->vertex_element[src_element].src_format) { - case PIPE_FORMAT_B8G8R8A8_UNORM: - feme->fetch[i].fetch = fetch_B8G8R8A8_UNORM; - break; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - feme->fetch[i].fetch = fetch_R32G32B32A32_FLOAT; - break; - case PIPE_FORMAT_R32G32B32_FLOAT: - feme->fetch[i].fetch = fetch_R32G32B32_FLOAT; - break; - case PIPE_FORMAT_R32G32_FLOAT: - feme->fetch[i].fetch = fetch_R32G32_FLOAT; - break; - case PIPE_FORMAT_R32_FLOAT: - feme->fetch[i].fetch = fetch_R32_FLOAT; - break; - default: - assert(0); - feme->fetch[i].fetch = NULL; - break; - } - + feme->fetch[i].fetch = draw_get_fetch_func(draw->vertex_element[src_element].src_format); + + switch (vinfo->emit[i]) { case EMIT_4F: feme->fetch[i].emit = emit_R32G32B32A32_FLOAT; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c new file mode 100644 index 0000000000..94e7d01be4 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -0,0 +1,391 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" + +/* The simplest 'middle end' in the new vertex code. + * + * The responsibilities of a middle end are to: + * - perform vertex fetch using + * - draw vertex element/buffer state + * - a list of fetch indices we received as an input + * - run the vertex shader + * - cliptest, + * - clip coord calculation + * - viewport transformation + * - if necessary, run the primitive pipeline, passing it: + * - a linear array of vertex_header vertices constructed here + * - a set of draw indices we received as an input + * - otherwise, drive the hw backend, + * - allocate space for hardware format vertices + * - translate the vertex-shader output vertices to hw format + * - calling the backend draw functions. + * + * For convenience, we provide a helper function to drive the hardware + * backend given similar inputs to those required to run the pipeline. + * + * In the case of passthrough mode, many of these actions are disabled + * or noops, so we end up doing: + * + * - perform vertex fetch + * - drive the hw backend + * + * IE, basically just vertex fetch to post-vs-format vertices, + * followed by a call to the backend helper function. + */ + + +struct fetch_pipeline_middle_end { + struct draw_pt_middle_end base; + struct draw_context *draw; + + struct { + const ubyte *ptr; + unsigned pitch; + void (*fetch)( const void *from, float *attrib); + void (*emit)( const float *attrib, float **out ); + } fetch[PIPE_MAX_ATTRIBS]; + + unsigned nr_fetch; + unsigned pipeline_vertex_size; + unsigned prim; +}; + + +static void fetch_NULL( const void *from, + float *attrib ) +{ +} + + + +static void emit_R32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out) += 1; +} + +static void emit_R32G32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out) += 2; +} + +static void emit_R32G32B32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out)[2] = attrib[2]; + (*out) += 3; +} + +static void emit_R32G32B32A32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out)[2] = attrib[2]; + (*out)[3] = attrib[3]; + (*out) += 4; +} + +static void emit_header( const float *attrib, + float **out ) +{ + (*out)[0] = 0; + (*out)[1] = 0; + (*out)[2] = 0; + (*out)[3] = 0; + (*out)[3] = 1; + (*out) += 5; +} + +/** + * General-purpose fetch from user's vertex arrays, emit to driver's + * vertex buffer. + * + * XXX this is totally temporary. + */ +static void +fetch_store_general( struct fetch_pipeline_middle_end *fpme, + void *out_ptr, + const unsigned *fetch_elts, + unsigned count ) +{ + float *out = (float *)out_ptr; + uint i, j; + + for (i = 0; i < count; i++) { + unsigned elt = fetch_elts[i]; + + for (j = 0; j < fpme->nr_fetch; j++) { + float attrib[4]; + const ubyte *from = (fpme->fetch[j].ptr + + fpme->fetch[j].pitch * elt); + + fpme->fetch[j].fetch( from, attrib ); + fpme->fetch[j].emit( attrib, &out ); + } + } +} + + +/* We aren't running a vertex shader, but are running the pipeline. + * That means the vertices we need to build look like: + * + * dw0: vertex header (zero?) + * dw1: clip coord 0 + * dw2: clip coord 1 + * dw3: clip coord 2 + * dw4: clip coord 4 + * dw5: screen coord 0 + * dw6: screen coord 0 + * dw7: screen coord 0 + * dw8: screen coord 0 + * dw9: other attribs... + * + */ +static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, + unsigned prim ) +{ + static const float zero = 0; + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + struct draw_context *draw = fpme->draw; + unsigned i, nr = 0; + + fpme->prim = prim; + + /* Emit the vertex header and empty clipspace coord field: + */ + { + fpme->fetch[nr].ptr = NULL; + fpme->fetch[nr].pitch = 0; + fpme->fetch[nr].fetch = fetch_NULL; + fpme->fetch[nr].emit = emit_header; + nr++; + } + + + /* Need to look at vertex shader inputs (we know it is a + * passthrough shader, so these define the outputs too). If we + * were running a shader, we'd still be looking at the inputs at + * this point. + */ + for (i = 0; i < draw->vertex_shader->info.num_inputs; i++) { + unsigned buf = draw->vertex_element[i].vertex_buffer_index; + enum pipe_format format = draw->vertex_element[i].src_format; + + fpme->fetch[nr].ptr = ((const ubyte *) draw->user.vbuffer[buf] + + draw->vertex_buffer[buf].buffer_offset + + draw->vertex_element[i].src_offset); + + fpme->fetch[nr].pitch = draw->vertex_buffer[buf].pitch; + fpme->fetch[nr].fetch = draw_get_fetch_func( format ); + + /* Always do this -- somewhat redundant... + */ + fpme->fetch[nr].emit = emit_R32G32B32A32_FLOAT; + nr++; + } + + fpme->nr_fetch = nr; + fpme->pipeline_vertex_size = (5 + (nr-1) * 4) * sizeof(float); +} + + + +/** + * Add a point to the primitive queue. + * \param i0 index into user's vertex arrays + */ +static void do_point( struct draw_context *draw, + const char *v0 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 0; + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + + draw->pipeline.first->point( draw->pipeline.first, &prim ); +} + + +/** + * Add a line to the primitive queue. + * \param i0 index into user's vertex arrays + * \param i1 index into user's vertex arrays + */ +static void do_line( struct draw_context *draw, + const char *v0, + const char *v1 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 1; /* fixme */ + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + + draw->pipeline.first->line( draw->pipeline.first, &prim ); +} + +/** + * Add a triangle to the primitive queue. + */ +static void do_triangle( struct draw_context *draw, + char *v0, + char *v1, + char *v2 ) +{ + struct prim_header prim; + +// _mesa_printf("tri %d %d %d\n", i0, i1, i2); + prim.reset_line_stipple = 1; + prim.edgeflags = ~0; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + prim.v[2] = (struct vertex_header *)v2; + + draw->pipeline.first->tri( draw->pipeline.first, &prim ); +} + + +static void run_pipeline( struct fetch_pipeline_middle_end *fpme, + char *verts, + const ushort *elts, + unsigned count ) +{ + struct draw_context *draw = fpme->draw; + unsigned stride = fpme->pipeline_vertex_size; + unsigned i; + + switch (fpme->prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i++) + do_point( draw, + verts + stride * elts[i] ); + break; + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) + do_line( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1]); + break; + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) + do_triangle( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1], + verts + stride * elts[i+2]); + break; + } +} + + + + +static void fetch_pipeline_run( struct draw_pt_middle_end *middle, + const unsigned *fetch_elts, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + struct draw_context *draw = fpme->draw; + char *pipeline_verts; + + pipeline_verts = MALLOC( fpme->pipeline_vertex_size * + fetch_count ); + if (!pipeline_verts) { + assert(0); + return; + } + + + /* Single routine to fetch vertices and emit pipeline verts. + */ + fetch_store_general( fpme, + pipeline_verts, + fetch_elts, + fetch_count ); + + + run_pipeline( fpme, + pipeline_verts, + draw_elts, + draw_count ); + + + /* Done -- that was easy, wasn't it: + */ + FREE( pipeline_verts ); +} + + + +static void fetch_pipeline_finish( struct draw_pt_middle_end *middle ) +{ + /* nothing to do */ +} + +static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) +{ + FREE(middle); +} + + +struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ) +{ + struct fetch_pipeline_middle_end *fetch_pipeline = CALLOC_STRUCT( fetch_pipeline_middle_end ); + + fetch_pipeline->base.prepare = fetch_pipeline_prepare; + fetch_pipeline->base.run = fetch_pipeline_run; + fetch_pipeline->base.finish = fetch_pipeline_finish; + fetch_pipeline->base.destroy = fetch_pipeline_destroy; + + fetch_pipeline->draw = draw; + + return &fetch_pipeline->base; +} + diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c index 11f99babf6..9041041006 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c +++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c @@ -166,7 +166,7 @@ fetch_B8G8R8A8_UNORM(const void *ptr, float *attrib) } -static fetch_func get_fetch_func( enum pipe_format format ) +fetch_func draw_get_fetch_func( enum pipe_format format ) { #if 0 { @@ -502,7 +502,7 @@ void draw_update_vertex_fetch( struct draw_context *draw ) draw->vertex_element[i].src_offset; draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch; - draw->vertex_fetch.fetch[i] = get_fetch_func( format ); + draw->vertex_fetch.fetch[i] = draw_get_fetch_func( format ); } draw->vertex_fetch.nr_attrs = nr_attrs; -- cgit v1.2.3 From 333df9656a257507d5eb5a6a8e8f2d9fc7577f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 3 Apr 2008 13:19:38 +0100 Subject: gallium: Only build softpipe driver by default for xlib winsys with scons. --- src/gallium/winsys/xlib/SConscript | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index c38b5be52c..218b89285f 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -22,8 +22,6 @@ sources = [ drivers = [ softpipe, - i915simple, - i965simple, ] # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -- cgit v1.2.3 From 766f3a545ebb317d2115b9053a8fc13b49ceec12 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 3 Apr 2008 16:36:07 -0600 Subject: gallium: implement ycbcr->rgba tile conversion --- src/gallium/auxiliary/util/p_tile.c | 71 +++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 287d783981..c9a9c8f4f7 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -560,6 +560,69 @@ z24s8_get_tile_rgba(unsigned *src, } +/*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/ + +/** + * Convert YCbCr (or YCrCb) to RGBA. + */ +static void +ycbcr_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride, + boolean rev) +{ + const float scale = 1.0f / 255.0f; + unsigned i, j; + + /* we're assuming we're being asked for an even number of texels */ + assert((w & 1) == 0); + + for (i = 0; i < h; i++) { + float *pRow = p; + /* do two texels at a time */ + for (j = 0; j < w; j += 2, src += 2) { + const ushort t0 = src[0]; + const ushort t1 = src[1]; + const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ + const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */ + ubyte cb, cr; + if (rev) { + cb = t1 & 0xff; /* chroma U */ + cr = t0 & 0xff; /* chroma V */ + } + else { + cb = t0 & 0xff; /* chroma U */ + cr = t1 & 0xff; /* chroma V */ + } + float r, g, b; + + /* even pixel: y0,cr,cb */ + r = 1.164 * (y0-16) + 1.596 * (cr-128); + g = 1.164 * (y0-16) - 0.813 * (cr-128) - 0.391 * (cb-128); + b = 1.164 * (y0-16) + 2.018 * (cb-128); + pRow[0] = r * scale; + pRow[1] = g * scale; + pRow[2] = b * scale; + pRow[3] = 1.0f; + pRow += 4; + + /* odd pixel: use y1,cr,cb */ + r = 1.164 * (y1-16) + 1.596 * (cr-128); + g = 1.164 * (y1-16) - 0.813 * (cr-128) - 0.391 * (cb-128); + b = 1.164 * (y1-16) + 2.018 * (cb-128); + pRow[0] = r * scale; + pRow[1] = g * scale; + pRow[2] = b * scale; + pRow[3] = 1.0f; + pRow += 4; + + } + p += dst_stride; + } +} + + void pipe_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, @@ -622,6 +685,14 @@ pipe_get_tile_rgba(struct pipe_context *pipe, case PIPE_FORMAT_Z24S8_UNORM: z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); break; + case PIPE_FORMAT_YCBCR: + assert((x & 1) == 0); + ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, FALSE); + break; + case PIPE_FORMAT_YCBCR_REV: + assert((x & 1) == 0); + ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, TRUE); + break; default: assert(0); } -- cgit v1.2.3 From 217d37940771dd02ff1aa365105eca2c7a09d623 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 2 Apr 2008 14:01:42 -0600 Subject: cell: minor texture improvements Precompute tiles_per_row. Use ushort multiplies in a few places. New comments. --- src/gallium/drivers/cell/spu/spu_main.c | 2 ++ src/gallium/drivers/cell/spu/spu_main.h | 3 ++- src/gallium/drivers/cell/spu/spu_texture.c | 32 ++++++++++++++++++++---------- 3 files changed, 26 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 1ab1c40379..e04ffeb9b1 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -343,6 +343,8 @@ cmd_state_texture(const struct cell_command_texture *texture) spu.texture[unit].width = width; spu.texture[unit].height = height; + spu.texture[unit].tiles_per_row = width / TILE_SIZE; + spu.texture[unit].tex_size = (vector float) { width, height, 0.0, 0.0}; spu.texture[unit].tex_size_mask = (vector unsigned int) { width - 1, height - 1, 0, 0 }; diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index e9e39cbeab..e962e1426c 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -105,7 +105,8 @@ struct spu_framebuffer { struct spu_texture { void *start; - uint width, height; + ushort width, height; + ushort tiles_per_row; vector float tex_size; vector unsigned int tex_size_mask; /**< == int(size - 1) */ vector unsigned int tex_size_x_mask; /**< == int(size - 1) */ diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index ceab246980..e9a2754e57 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -51,22 +51,25 @@ invalidate_tex_cache(void) static uint get_texel(uint unit, vec_uint4 coordinate) { + const unsigned texture_ea = (uintptr_t) spu.texture[unit].start; + ushort x = spu_extract(coordinate, 0); + ushort y = spu_extract(coordinate, 1); + unsigned tile_offset = sizeof(tile_t) + * ((y / TILE_SIZE * spu.texture[unit].tiles_per_row) + (x / TILE_SIZE)); + ushort texel_offset = (ushort) 4 + * (ushort) (((ushort) (y % TILE_SIZE) * (ushort) TILE_SIZE) + (x % TILE_SIZE)); vec_uint4 tmp; - unsigned x = spu_extract(coordinate, 0); - unsigned y = spu_extract(coordinate, 1); - const unsigned tiles_per_row = spu.texture[unit].width / TILE_SIZE; - unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row) - + (x / TILE_SIZE)); - unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE) - + (x % TILE_SIZE)); spu_dcache_fetch_unaligned((qword *) & tmp, - spu.texture[unit].start + tile_offset + texel_offset, + texture_ea + tile_offset + texel_offset, 4); return spu_extract(tmp, 0); } +/** + * Get four texels from locations (x[0], y[0]), (x[1], y[1]) ... + */ static void get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) { @@ -76,7 +79,7 @@ get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) const qword offset_x = si_andi((qword) x, 0x1f); const qword offset_y = si_andi((qword) y, 0x1f); - const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].width / TILE_SIZE); + const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].tiles_per_row); const qword tile_size = (qword) spu_splats(sizeof(tile_t)); qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x); @@ -97,6 +100,7 @@ get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) texture_ea + spu_extract(offset, 3), 4); } + /** * Get texture sample at texcoord. * XXX this is extremely primitive for now. @@ -126,17 +130,25 @@ sample_texture_bilinear(uint unit, vector float texcoord) vec_uint4 texels[4]; + /* setup texcoords for quad: + * +-----+-----+ + * |x0,y0|x1,y1| + * +-----+-----+ + * |x2,y2|x3,y3| + * +-----+-----+ + */ vec_uint4 x = spu_splats(spu_extract(itc, 0)); vec_uint4 y = spu_splats(spu_extract(itc, 1)); - x = spu_add(x, offset_x); y = spu_add(y, offset_y); + /* GL_REPEAT wrap mode: */ x = spu_and(x, spu.texture[unit].tex_size_x_mask); y = spu_and(y, spu.texture[unit].tex_size_y_mask); get_four_texels(unit, x, y, texels); + /* integer A8R8G8B8 to float texel conversion */ vector float texel00 = spu_unpack_A8R8G8B8(spu_extract(texels[0], 0)); vector float texel01 = spu_unpack_A8R8G8B8(spu_extract(texels[1], 0)); vector float texel10 = spu_unpack_A8R8G8B8(spu_extract(texels[2], 0)); -- cgit v1.2.3 From a7504ad587ee8cbfa9958ad23321a691ce0823d3 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 2 Apr 2008 14:30:28 -0600 Subject: cell: added some comments/ideas about better texture sampling --- src/gallium/drivers/cell/spu/spu_texture.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index e9a2754e57..5051774f00 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -48,9 +48,16 @@ invalidate_tex_cache(void) } +/** + * XXX look into getting texels for all four pixels in a quad at once. + */ static uint get_texel(uint unit, vec_uint4 coordinate) { + /* + * XXX we could do the "/ TILE_SIZE" and "% TILE_SIZE" operations as + * SIMD since X and Y are already in a SIMD register. + */ const unsigned texture_ea = (uintptr_t) spu.texture[unit].start; ushort x = spu_extract(coordinate, 0); ushort y = spu_extract(coordinate, 1); @@ -69,6 +76,16 @@ get_texel(uint unit, vec_uint4 coordinate) /** * Get four texels from locations (x[0], y[0]), (x[1], y[1]) ... + * + * NOTE: in the typical case of bilinear filtering, the four texels + * are in a 2x2 group so we could get by with just two dcache fetches + * (two side-by-side texels per fetch). But when bilinear filtering + * wraps around a texture edge, we'll probably need code like we have + * now. + * FURTHERMORE: since we're rasterizing a quad of 2x2 pixels at a time, + * it's quite likely that the four pixels in a quad will need some of the + * same texels. So look into doing texture fetches for four pixels at + * a time. */ static void get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) @@ -103,7 +120,6 @@ get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) /** * Get texture sample at texcoord. - * XXX this is extremely primitive for now. */ vector float sample_texture_nearest(uint unit, vector float texcoord) -- cgit v1.2.3 From 7a7bce7b24ea4f63faa1d5bfe3f71d09b412c838 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 4 Apr 2008 11:13:10 +0100 Subject: gallium: make msvc less unhappy --- src/gallium/auxiliary/util/p_tile.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index c9a9c8f4f7..520da5cecd 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -587,6 +587,8 @@ ycbcr_get_tile_rgba(ushort *src, const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */ ubyte cb, cr; + float r, g, b; + if (rev) { cb = t1 & 0xff; /* chroma U */ cr = t0 & 0xff; /* chroma V */ @@ -595,12 +597,11 @@ ycbcr_get_tile_rgba(ushort *src, cb = t0 & 0xff; /* chroma U */ cr = t1 & 0xff; /* chroma V */ } - float r, g, b; /* even pixel: y0,cr,cb */ - r = 1.164 * (y0-16) + 1.596 * (cr-128); - g = 1.164 * (y0-16) - 0.813 * (cr-128) - 0.391 * (cb-128); - b = 1.164 * (y0-16) + 2.018 * (cb-128); + r = 1.164f * (y0-16) + 1.596f * (cr-128); + g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128); + b = 1.164f * (y0-16) + 2.018f * (cb-128); pRow[0] = r * scale; pRow[1] = g * scale; pRow[2] = b * scale; @@ -608,9 +609,9 @@ ycbcr_get_tile_rgba(ushort *src, pRow += 4; /* odd pixel: use y1,cr,cb */ - r = 1.164 * (y1-16) + 1.596 * (cr-128); - g = 1.164 * (y1-16) - 0.813 * (cr-128) - 0.391 * (cb-128); - b = 1.164 * (y1-16) + 2.018 * (cb-128); + r = 1.164f * (y1-16) + 1.596f * (cr-128); + g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128); + b = 1.164f * (y1-16) + 2.018f * (cb-128); pRow[0] = r * scale; pRow[1] = g * scale; pRow[2] = b * scale; -- cgit v1.2.3 From cf9b07ea3474cd33e797eeb10b3fd73ad54ae8d5 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 4 Apr 2008 01:59:38 +0200 Subject: gallium: fix two-side stencil handling Previously all drivers were in twosided mode since they checked for stencil.enable[1] flag which was a copy of stencil.enable[0]. Note that drivers should not reference stencil[1] state (other than the enable) if twosided stenciling is disabled (for now the stencil state is still copied but for instance clear_with_quads won't provide useful values in there). Also, use _TestTwoSide instead of TestTwoSide since results would be bogus otherwise if using APIs with implicit two side stencil enable (i.e. core ogl 2.0). --- src/gallium/include/pipe/p_state.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 3593446e1c..2dc9a92186 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -181,7 +181,7 @@ struct pipe_depth_stencil_alpha_state unsigned occlusion_count:1; /**< do occlusion counting? */ } depth; struct { - unsigned enabled:1; + unsigned enabled:1; /**< stencil[0]: stencil enabled, stencil[1]: two-side enabled */ unsigned func:3; /**< PIPE_FUNC_x */ unsigned fail_op:3; /**< PIPE_STENCIL_OP_x */ unsigned zpass_op:3; /**< PIPE_STENCIL_OP_x */ -- cgit v1.2.3 From 0b20d1b9b5e0514a68ab460d748753d29df2e70b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 4 Apr 2008 13:18:09 +0100 Subject: draw: move code to run pipeline from pt to new file Add facility for draw_vbuf.c to reset these vertex ids on flushes. Pre-initialize vertex ids correctly. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/SConscript | 1 + src/gallium/auxiliary/draw/draw_context.c | 3 +- src/gallium/auxiliary/draw/draw_private.h | 14 ++ .../auxiliary/draw/draw_pt_fetch_pipeline.c | 114 ++------------- src/gallium/auxiliary/draw/draw_pt_pipeline.c | 162 +++++++++++++++++++++ 6 files changed, 196 insertions(+), 99 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_pipeline.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index b28e516396..28262a92c6 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -19,6 +19,7 @@ C_SOURCES = \ draw_pt_vcache.c \ draw_pt_fetch_emit.c \ draw_pt_fetch_pipeline.c \ + draw_pt_pipeline.c \ draw_pt_elts.c \ draw_prim.c \ draw_pstipple.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 9ca4197441..52107912f5 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -18,6 +18,7 @@ draw = env.ConvenienceLibrary( 'draw_pt_vcache.c', 'draw_pt_fetch_emit.c', 'draw_pt_fetch_pipeline.c', + 'draw_pt_pipeline.c', 'draw_pt_elts.c', 'draw_prim.c', 'draw_pstipple.c', diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index d0d5f66b37..470c1c571b 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -434,7 +434,8 @@ void draw_reset_vertex_ids(struct draw_context *draw) stage = stage->next; } - draw_vertex_cache_reset_vertex_ids(draw); + draw_vertex_cache_reset_vertex_ids(draw); /* going away soon */ + draw_pt_reset_vertex_ids(draw); } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 0c9f9c2e03..48545af9e2 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -227,6 +227,12 @@ struct draw_context struct draw_pt_front_end *vcache; } front; + struct { + char *verts; + unsigned vertex_stride; + unsigned vertex_count; + } pipeline; + } pt; boolean flushing; @@ -386,6 +392,14 @@ boolean draw_pt_arrays( struct draw_context *draw, unsigned start, unsigned count ); +void draw_pt_reset_vertex_ids( struct draw_context *draw ); +void draw_pt_run_pipeline( struct draw_context *draw, + unsigned prim, + char *verts, + unsigned vertex_stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ); /* Prototype/hack (DEPRECATED) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index 94e7d01be4..0ddb400f7e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -129,7 +129,13 @@ static void emit_R32G32B32A32_FLOAT( const float *attrib, static void emit_header( const float *attrib, float **out ) { - (*out)[0] = 0; + struct vertex_header *header = (struct vertex_header *) (*out); + + header->clipmask = 0; + header->edgeflag = 1; + header->pad = 0; + header->vertex_id = UNDEFINED_VERTEX_ID; + (*out)[1] = 0; (*out)[2] = 0; (*out)[3] = 0; @@ -231,99 +237,6 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, -/** - * Add a point to the primitive queue. - * \param i0 index into user's vertex arrays - */ -static void do_point( struct draw_context *draw, - const char *v0 ) -{ - struct prim_header prim; - - prim.reset_line_stipple = 0; - prim.edgeflags = 1; - prim.pad = 0; - prim.v[0] = (struct vertex_header *)v0; - - draw->pipeline.first->point( draw->pipeline.first, &prim ); -} - - -/** - * Add a line to the primitive queue. - * \param i0 index into user's vertex arrays - * \param i1 index into user's vertex arrays - */ -static void do_line( struct draw_context *draw, - const char *v0, - const char *v1 ) -{ - struct prim_header prim; - - prim.reset_line_stipple = 1; /* fixme */ - prim.edgeflags = 1; - prim.pad = 0; - prim.v[0] = (struct vertex_header *)v0; - prim.v[1] = (struct vertex_header *)v1; - - draw->pipeline.first->line( draw->pipeline.first, &prim ); -} - -/** - * Add a triangle to the primitive queue. - */ -static void do_triangle( struct draw_context *draw, - char *v0, - char *v1, - char *v2 ) -{ - struct prim_header prim; - -// _mesa_printf("tri %d %d %d\n", i0, i1, i2); - prim.reset_line_stipple = 1; - prim.edgeflags = ~0; - prim.pad = 0; - prim.v[0] = (struct vertex_header *)v0; - prim.v[1] = (struct vertex_header *)v1; - prim.v[2] = (struct vertex_header *)v2; - - draw->pipeline.first->tri( draw->pipeline.first, &prim ); -} - - -static void run_pipeline( struct fetch_pipeline_middle_end *fpme, - char *verts, - const ushort *elts, - unsigned count ) -{ - struct draw_context *draw = fpme->draw; - unsigned stride = fpme->pipeline_vertex_size; - unsigned i; - - switch (fpme->prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i++) - do_point( draw, - verts + stride * elts[i] ); - break; - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) - do_line( draw, - verts + stride * elts[i+0], - verts + stride * elts[i+1]); - break; - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) - do_triangle( draw, - verts + stride * elts[i+0], - verts + stride * elts[i+1], - verts + stride * elts[i+2]); - break; - } -} - - - static void fetch_pipeline_run( struct draw_pt_middle_end *middle, const unsigned *fetch_elts, @@ -351,10 +264,15 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, fetch_count ); - run_pipeline( fpme, - pipeline_verts, - draw_elts, - draw_count ); + /* Run the pipeline + */ + draw_pt_run_pipeline( fpme->draw, + fpme->prim, + pipeline_verts, + fpme->pipeline_vertex_size, + fetch_count, + draw_elts, + draw_count ); /* Done -- that was easy, wasn't it: diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c new file mode 100644 index 0000000000..6e46d3925f --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c @@ -0,0 +1,162 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" + + +/** + * Add a point to the primitive queue. + * \param i0 index into user's vertex arrays + */ +static void do_point( struct draw_context *draw, + const char *v0 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 0; + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + + draw->pipeline.first->point( draw->pipeline.first, &prim ); +} + + +/** + * Add a line to the primitive queue. + * \param i0 index into user's vertex arrays + * \param i1 index into user's vertex arrays + */ +static void do_line( struct draw_context *draw, + const char *v0, + const char *v1 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 1; /* fixme */ + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + + draw->pipeline.first->line( draw->pipeline.first, &prim ); +} + +/** + * Add a triangle to the primitive queue. + */ +static void do_triangle( struct draw_context *draw, + char *v0, + char *v1, + char *v2 ) +{ + struct prim_header prim; + +// _mesa_printf("tri %d %d %d\n", i0, i1, i2); + prim.reset_line_stipple = 1; + prim.edgeflags = ~0; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + prim.v[2] = (struct vertex_header *)v2; + + draw->pipeline.first->tri( draw->pipeline.first, &prim ); +} + + + +void draw_pt_reset_vertex_ids( struct draw_context *draw ) +{ + unsigned i; + char *verts = draw->pt.pipeline.verts; + unsigned stride = draw->pt.pipeline.vertex_stride; + + for (i = 0; i < draw->pt.pipeline.vertex_count; i++) { + ((struct vertex_header *)verts)->vertex_id = UNDEFINED_VERTEX_ID; + verts += stride; + } +} + + +/* Code to run the pipeline on a fairly arbitary collection of vertices. + * + * Vertex headers must be pre-initialized with the + * UNDEFINED_VERTEX_ID, this code will cause that id to become + * overwritten, so it may have to be reset if there is the intention + * to reuse the vertices. + * + * This code provides a callback to reset the vertex id's which the + * draw_vbuf.c code uses when it has to perform a flush. + */ +void draw_pt_run_pipeline( struct draw_context *draw, + unsigned prim, + char *verts, + unsigned stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ) +{ + unsigned i; + + draw->pt.pipeline.verts = verts; + draw->pt.pipeline.vertex_stride = stride; + draw->pt.pipeline.vertex_count = vertex_count; + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i++) + do_point( draw, + verts + stride * elts[i] ); + break; + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) + do_line( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1]); + break; + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) + do_triangle( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1], + verts + stride * elts[i+2]); + break; + } + + draw->pt.pipeline.verts = NULL; + draw->pt.pipeline.vertex_count = 0; +} + -- cgit v1.2.3 From 84501e68f6294370d6f2f6aec4e7eab57bcc0e72 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 4 Apr 2008 17:02:20 +0100 Subject: gallium: Handle client-supplied edgeflags. Also, implement support in the draw module. We were hardwiring these to one for quite a long time... Currently using a draw_set_edgeflags() function, may be better to push the argument into the draw_arrays() function. TBD. --- src/gallium/auxiliary/draw/draw_context.c | 16 +++++++ src/gallium/auxiliary/draw/draw_context.h | 3 ++ src/gallium/auxiliary/draw/draw_private.h | 13 ++---- .../auxiliary/draw/draw_pt_fetch_pipeline.c | 49 +++++++++++++++------- src/gallium/auxiliary/draw/draw_pt_pipeline.c | 8 ++-- src/gallium/auxiliary/draw/draw_vertex_cache.c | 2 +- src/gallium/include/pipe/p_context.h | 8 ++++ 7 files changed, 71 insertions(+), 28 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 470c1c571b..b3c65c90d6 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -444,3 +444,19 @@ void draw_set_render( struct draw_context *draw, { draw->render = render; } + +void draw_set_edgeflags( struct draw_context *draw, + const unsigned *edgeflag ) +{ + draw->user.edgeflag = edgeflag; +} + + +boolean draw_get_edgeflag( struct draw_context *draw, + unsigned idx ) +{ + if (draw->user.edgeflag) + return (draw->user.edgeflag[idx/32] & (1 << (idx%32))) != 0; + else + return 1; +} diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 84bae3bd78..c7ac32b452 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -155,6 +155,9 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw, void draw_set_mapped_constant_buffer(struct draw_context *draw, const void *buffer); +void draw_set_edgeflags( struct draw_context *draw, + const unsigned *edgeflag ); + /*********************************************************************** * draw_prim.c diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 48545af9e2..4d056f6dba 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -250,6 +250,8 @@ struct draw_context /* user-space vertex data, buffers */ struct { + const unsigned *edgeflag; + /** vertex element/index buffer (ex: glDrawElements) */ const void *elts; /** bytes per index (0, 1, 2 or 4) */ @@ -402,15 +404,6 @@ void draw_pt_run_pipeline( struct draw_context *draw, unsigned count ); -/* Prototype/hack (DEPRECATED) - */ -boolean -draw_passthrough_arrays(struct draw_context *draw, - unsigned prim, - unsigned start, - unsigned count); - - #define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ #define DRAW_FLUSH_PRIM_QUEUE 0x2 #define DRAW_FLUSH_VERTEX_CACHE 0x4 @@ -420,6 +413,8 @@ draw_passthrough_arrays(struct draw_context *draw, void draw_do_flush( struct draw_context *draw, unsigned flags ); +boolean draw_get_edgeflag( struct draw_context *draw, + unsigned idx ); /** diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index 0ddb400f7e..ba95420b72 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -72,6 +72,8 @@ struct fetch_pipeline_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; + void (*header)( const unsigned *edgeflag, unsigned count, float **out); + struct { const ubyte *ptr; unsigned pitch; @@ -85,12 +87,6 @@ struct fetch_pipeline_middle_end { }; -static void fetch_NULL( const void *from, - float *attrib ) -{ -} - - static void emit_R32_FLOAT( const float *attrib, float **out ) @@ -126,8 +122,9 @@ static void emit_R32G32B32A32_FLOAT( const float *attrib, (*out) += 4; } -static void emit_header( const float *attrib, - float **out ) +static void header( const unsigned *edgeflag, + unsigned idx, + float **out ) { struct vertex_header *header = (struct vertex_header *) (*out); @@ -143,6 +140,26 @@ static void emit_header( const float *attrib, (*out) += 5; } + +static void header_ef( const unsigned *edgeflag, + unsigned idx, + float **out ) +{ + struct vertex_header *header = (struct vertex_header *) (*out); + + header->clipmask = 0; + header->edgeflag = (edgeflag[idx/32] & (1 << (idx%32))) != 0; + header->pad = 0; + header->vertex_id = UNDEFINED_VERTEX_ID; + + (*out)[1] = 0; + (*out)[2] = 0; + (*out)[3] = 0; + (*out)[3] = 1; + (*out) += 5; +} + + /** * General-purpose fetch from user's vertex arrays, emit to driver's * vertex buffer. @@ -155,12 +172,15 @@ fetch_store_general( struct fetch_pipeline_middle_end *fpme, const unsigned *fetch_elts, unsigned count ) { + const unsigned *edgeflag = fpme->draw->user.edgeflag; float *out = (float *)out_ptr; uint i, j; for (i = 0; i < count; i++) { unsigned elt = fetch_elts[i]; + fpme->header( edgeflag, i, &out ); + for (j = 0; j < fpme->nr_fetch; j++) { float attrib[4]; const ubyte *from = (fpme->fetch[j].ptr + @@ -200,12 +220,11 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, /* Emit the vertex header and empty clipspace coord field: */ - { - fpme->fetch[nr].ptr = NULL; - fpme->fetch[nr].pitch = 0; - fpme->fetch[nr].fetch = fetch_NULL; - fpme->fetch[nr].emit = emit_header; - nr++; + if (draw->user.edgeflag) { + fpme->header = header_ef; + } + else { + fpme->header = header; } @@ -232,7 +251,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, } fpme->nr_fetch = nr; - fpme->pipeline_vertex_size = (5 + (nr-1) * 4) * sizeof(float); + fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); } diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c index 6e46d3925f..942df518eb 100644 --- a/src/gallium/auxiliary/draw/draw_pt_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c @@ -86,12 +86,14 @@ static void do_triangle( struct draw_context *draw, struct prim_header prim; // _mesa_printf("tri %d %d %d\n", i0, i1, i2); - prim.reset_line_stipple = 1; - prim.edgeflags = ~0; - prim.pad = 0; prim.v[0] = (struct vertex_header *)v0; prim.v[1] = (struct vertex_header *)v1; prim.v[2] = (struct vertex_header *)v2; + prim.reset_line_stipple = 1; + prim.edgeflags = ((prim.v[0]->edgeflag) | + (prim.v[1]->edgeflag << 1) | + (prim.v[2]->edgeflag << 2)); + prim.pad = 0; draw->pipeline.first->tri( draw->pipeline.first, &prim ); } diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c index 161b247d4e..c0248979e2 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_cache.c +++ b/src/gallium/auxiliary/draw/draw_vertex_cache.c @@ -101,7 +101,7 @@ static struct vertex_header *get_vertex( struct draw_context *draw, draw->vs.queue[out].elt = i; draw->vs.queue[out].vertex->clipmask = 0; - draw->vs.queue[out].vertex->edgeflag = 1; /*XXX use user's edge flag! */ + draw->vs.queue[out].vertex->edgeflag = draw_get_edgeflag(draw, i); draw->vs.queue[out].vertex->pad = 0; draw->vs.queue[out].vertex->vertex_id = UNDEFINED_VERTEX_ID; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 324f70185a..f3a9c2cd8b 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -57,6 +57,14 @@ struct pipe_context { void (*destroy)( struct pipe_context * ); + + /* Possible interface for setting edgeflags. These aren't really + * vertex elements, so don't fit there. + */ + void (*set_edgeflags)( struct pipe_context *, + const unsigned *bitfield ); + + /** * VBO drawing (return false on fallbacks (temporary??)) */ -- cgit v1.2.3 From 5ffc5cce1507fd407399911abefeea988a69394e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Apr 2008 12:24:01 -0600 Subject: gallium: new debug code, disabled --- src/gallium/auxiliary/draw/draw_clip.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_clip.c b/src/gallium/auxiliary/draw/draw_clip.c index 200152ecab..fd1c71152e 100644 --- a/src/gallium/auxiliary/draw/draw_clip.c +++ b/src/gallium/auxiliary/draw/draw_clip.c @@ -181,6 +181,21 @@ static void emit_poly( struct draw_stage *stage, (header.v[1]->edgeflag << 1) | (header.v[2]->edgeflag << 2)); + if (0) { + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + uint j, k; + printf("Clipped tri:\n"); + for (j = 0; j < 3; j++) { + for (k = 0; k < vs->info.num_outputs; k++) { + printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, + header.v[j]->data[k][0], + header.v[j]->data[k][1], + header.v[j]->data[k][2], + header.v[j]->data[k][3]); + } + } + } + stage->next->tri( stage->next, &header ); header.v[1]->edgeflag = tmp1; -- cgit v1.2.3 From c1d26d3dccafed808349c47dc12b94081f956560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 2 Apr 2008 10:21:24 +0900 Subject: gallium: Use the custom snprintf implementation everywhere (for Win32). Because winddk's implemenation does not handle floats. --- src/gallium/auxiliary/util/p_debug.c | 11 +++-------- src/gallium/include/pipe/p_util.h | 9 +++++++++ 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 5447bbb6f5..090e3b7794 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -43,18 +43,13 @@ #ifdef WIN32 static INLINE void -rpl_EngDebugPrint(const char *format, ...) +_EngDebugPrint(const char *format, ...) { va_list ap; va_start(ap, format); EngDebugPrint("", (PCHAR)format, ap); va_end(ap); } - -int rpl_vsnprintf(char *, size_t, const char *, va_list); -int rpl_snprintf(char *str, size_t size, const char *format, ...); -#define vsnprintf rpl_vsnprintf -#define snprintf rpl_snprintf #endif @@ -65,8 +60,8 @@ void _debug_vprintf(const char *format, va_list ap) /* EngDebugPrint does not handle float point arguments, so we need to use * our own vsnprintf implementation */ char buf[512 + 1]; - rpl_vsnprintf(buf, sizeof(buf), format, ap); - rpl_EngDebugPrint("%s", buf); + vsnprintf(buf, sizeof(buf), format, ap); + _EngDebugPrint("%s", buf); #else /* TODO: Implement debug print for WINCE */ #endif diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 1e7b8181f9..8e3aaee496 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -32,6 +32,7 @@ #include "p_debug.h" #include "p_pointer.h" #include +#include #ifdef __cplusplus @@ -137,6 +138,14 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define GETENV( X ) debug_get_option( X, NULL ) +#ifdef WIN32 +int rpl_vsnprintf(char *, size_t, const char *, va_list); +int rpl_snprintf(char *str, size_t size, const char *format, ...); +#define vsnprintf rpl_vsnprintf +#define snprintf rpl_snprintf +#endif + + /** * Return memory on given byte alignment */ -- cgit v1.2.3 From f1efef809caddff442ed45a59645b3f39498f521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 5 Apr 2008 09:49:50 +0900 Subject: gallium: Fix typo. --- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 55f32e6816..1ecc7d42ee 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -150,7 +150,7 @@ fenced_buffer_destroy(struct pb_buffer *buf) if (fenced_buf->fence) { struct pipe_winsys *winsys = fenced_list->winsys; - if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) { + if(winsys->fence_signalled(winsys, fenced_buf->fence, 0) != 0) { LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); fenced_list->numDelayed++; } -- cgit v1.2.3 From fdff063343ddfbfb1b2fa921e2efcc2fae35d0ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 5 Apr 2008 11:29:26 +0900 Subject: gallium: Keep fenced buffers list ordered. This allows to keep the list small without the overhead of full walks. --- .../auxiliary/pipebuffer/pb_buffer_fenced.c | 152 ++++++++++++++------- 1 file changed, 99 insertions(+), 53 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 1ecc7d42ee..24ba61a0b7 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -62,7 +62,6 @@ struct fenced_buffer_list struct pipe_winsys *winsys; size_t numDelayed; - size_t checkDelayed; struct list_head delayed; }; @@ -93,51 +92,93 @@ fenced_buffer(struct pb_buffer *buf) } +static INLINE void +_fenced_buffer_add(struct fenced_buffer *fenced_buf) +{ + struct fenced_buffer_list *fenced_list = fenced_buf->list; + + assert(fenced_buf->fence); + assert(!fenced_buf->head.prev); + assert(!fenced_buf->head.next); + LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); + ++fenced_list->numDelayed; +} + + +/** + * Actually destroy the buffer. + */ +static INLINE void +_fenced_buffer_destroy(struct fenced_buffer *fenced_buf) +{ + struct fenced_buffer_list *fenced_list = fenced_buf->list; + + assert(!fenced_buf->base.base.refcount); + assert(!fenced_buf->fence); + pb_reference(&fenced_buf->buffer, NULL); + FREE(fenced_buf); +} + + +static INLINE void +_fenced_buffer_remove(struct fenced_buffer *fenced_buf) +{ + struct fenced_buffer_list *fenced_list = fenced_buf->list; + struct pipe_winsys *winsys = fenced_list->winsys; + + assert(fenced_buf->fence); + + assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0); + winsys->fence_reference(winsys, &fenced_buf->fence, NULL); + + assert(fenced_buf->head.prev); + assert(fenced_buf->head.next); + LIST_DEL(&fenced_buf->head); +#ifdef DEBUG + fenced_buf->head.prev = NULL; + fenced_buf->head.next = NULL; +#endif + + assert(fenced_list->numDelayed); + --fenced_list->numDelayed; + + if(!fenced_buf->base.base.refcount) + _fenced_buffer_destroy(fenced_buf); +} + + +/** + * Free as many fenced buffers from the list head as possible. + */ static void _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, int wait) { struct pipe_winsys *winsys = fenced_list->winsys; - struct fenced_buffer *fenced_buf; - struct list_head *list, *prev; - int signaled = -1; - - list = fenced_list->delayed.next; - prev = list->prev; - for (; list != &fenced_list->delayed; list = prev, prev = list->prev) { - - fenced_buf = LIST_ENTRY(struct fenced_buffer, list, head); - - if (signaled != 0) { - if (wait) { - signaled = winsys->fence_finish(winsys, fenced_buf->fence, 0); - } - else { - signaled = winsys->fence_signalled(winsys, fenced_buf->fence, 0); - } + struct list_head *curr, *next; + struct fenced_buffer *fenced_buf; + struct pipe_fence_handle *prev_fence = NULL; + + curr = fenced_list->delayed.next; + next = curr->next; + while(curr != &fenced_list->delayed) { + fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); + + if(fenced_buf->fence != prev_fence) { + int signaled; + if (wait) + signaled = winsys->fence_finish(winsys, fenced_buf->fence, 0); + else + signaled = winsys->fence_signalled(winsys, fenced_buf->fence, 0); + if (signaled != 0) + break; + prev_fence = fenced_buf->fence; } - if (signaled != 0) { -#if 0 - /* XXX: we are assuming that buffers are freed in the same order they - * are fenced which may not always be true... - */ - break; -#else - signaled = -1; - continue; -#endif - } + _fenced_buffer_remove(fenced_buf); - winsys->fence_reference(winsys, &fenced_buf->fence, NULL); - - LIST_DEL(list); - fenced_list->numDelayed--; - - /* Do the delayed destroy: - */ - pb_reference(&fenced_buf->buffer, NULL); - FREE(fenced_buf); + curr = next; + next = curr->next; } } @@ -148,25 +189,29 @@ fenced_buffer_destroy(struct pb_buffer *buf) struct fenced_buffer *fenced_buf = fenced_buffer(buf); struct fenced_buffer_list *fenced_list = fenced_buf->list; + _glthread_LOCK_MUTEX(fenced_list->mutex); + assert(fenced_buf->base.base.refcount == 0); if (fenced_buf->fence) { struct pipe_winsys *winsys = fenced_list->winsys; - if(winsys->fence_signalled(winsys, fenced_buf->fence, 0) != 0) { - LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); - fenced_list->numDelayed++; - } + if(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0) { + struct list_head *curr, *prev; + curr = &fenced_buf->head; + prev = curr->prev; + do { + fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); + _fenced_buffer_remove(fenced_buf); + curr = prev; + prev = curr->prev; + } while (curr != &fenced_list->delayed); + } else { - winsys->fence_reference(winsys, &fenced_buf->fence, NULL); - pb_reference(&fenced_buf->buffer, NULL); - FREE(fenced_buf); + /* delay destruction */ } } else { - pb_reference(&fenced_buf->buffer, NULL); - FREE(fenced_buf); + _fenced_buffer_destroy(fenced_buf); } - - if ((fenced_list->numDelayed % fenced_list->checkDelayed) == 0) - _fenced_buffer_list_check_free(fenced_list, 0); + _glthread_UNLOCK_MUTEX(fenced_list->mutex); } @@ -241,7 +286,11 @@ buffer_fence(struct pb_buffer *buf, struct pipe_winsys *winsys = fenced_list->winsys; _glthread_LOCK_MUTEX(fenced_list->mutex); + if (fenced_buf->fence) + _fenced_buffer_remove(fenced_buf); winsys->fence_reference(winsys, &fenced_buf->fence, fence); + if (fenced_buf->fence) + _fenced_buffer_add(fenced_buf); _glthread_UNLOCK_MUTEX(fenced_list->mutex); } @@ -261,9 +310,6 @@ fenced_buffer_list_create(struct pipe_winsys *winsys) fenced_list->numDelayed = 0; - /* TODO: don't hard code this */ - fenced_list->checkDelayed = 5; - _glthread_INIT_MUTEX(fenced_list->mutex); return fenced_list; -- cgit v1.2.3 From a8ca54955322b34c77a7459246e5639d3f8610cd Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 5 Apr 2008 10:22:47 +0200 Subject: draw: Use debug_printf(). --- src/gallium/auxiliary/draw/draw_clip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_clip.c b/src/gallium/auxiliary/draw/draw_clip.c index fd1c71152e..e24c5d8032 100644 --- a/src/gallium/auxiliary/draw/draw_clip.c +++ b/src/gallium/auxiliary/draw/draw_clip.c @@ -184,10 +184,10 @@ static void emit_poly( struct draw_stage *stage, if (0) { const struct draw_vertex_shader *vs = stage->draw->vertex_shader; uint j, k; - printf("Clipped tri:\n"); + debug_printf("Clipped tri:\n"); for (j = 0; j < 3; j++) { for (k = 0; k < vs->info.num_outputs; k++) { - printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, + debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, header.v[j]->data[k][0], header.v[j]->data[k][1], header.v[j]->data[k][2], -- cgit v1.2.3 From 5c19e47362c2d193850e98bd43a2bc2b783b0b5c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 6 Apr 2008 14:29:30 +0100 Subject: draw: fix edgeflag handling on the pt paths Encode edgeflags (and reset_stipple info) into the top two bits of the fetch elements. This info could be moved elsewhere, but for now we can live with a 1<<30 maximum element size... Also use the primitive decomposition code from draw_prim.c verbatim, as it includes all this stuff and is known to work. --- src/gallium/auxiliary/draw/draw_pt.h | 10 + .../auxiliary/draw/draw_pt_fetch_pipeline.c | 16 +- src/gallium/auxiliary/draw/draw_pt_pipeline.c | 6 +- src/gallium/auxiliary/draw/draw_pt_vcache.c | 396 ++++++++++++--------- 4 files changed, 253 insertions(+), 175 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 800072c511..590823fd33 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -40,6 +40,16 @@ typedef unsigned (*pt_elt_func)( const void *elts, unsigned idx ); struct draw_pt_middle_end; struct draw_context; +/* We use the top couple of bits in the vertex fetch index to convey a + * little API information. This limits the number of vertices we can + * address to only 1 billion -- if that becomes a problem, these could + * be moved out & passed separately. + */ +#define DRAW_PT_EDGEFLAG (1<<30) +#define DRAW_PT_RESET_STIPPLE (1<<31) +#define DRAW_PT_FLAG_MASK (3<<30) + + /* The "front end" - prepare sets of fetch, draw elements for the * middle end. * diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index ba95420b72..4c2a281b29 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -72,7 +72,7 @@ struct fetch_pipeline_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; - void (*header)( const unsigned *edgeflag, unsigned count, float **out); + void (*header)( unsigned idx, float **out); struct { const ubyte *ptr; @@ -122,8 +122,7 @@ static void emit_R32G32B32A32_FLOAT( const float *attrib, (*out) += 4; } -static void header( const unsigned *edgeflag, - unsigned idx, +static void header( unsigned idx, float **out ) { struct vertex_header *header = (struct vertex_header *) (*out); @@ -141,14 +140,15 @@ static void header( const unsigned *edgeflag, } -static void header_ef( const unsigned *edgeflag, - unsigned idx, +static void header_ef( unsigned idx, float **out ) { struct vertex_header *header = (struct vertex_header *) (*out); + /* XXX: need a reset_stipple flag in the vertex header too? + */ header->clipmask = 0; - header->edgeflag = (edgeflag[idx/32] & (1 << (idx%32))) != 0; + header->edgeflag = (idx & DRAW_PT_EDGEFLAG) != 0; header->pad = 0; header->vertex_id = UNDEFINED_VERTEX_ID; @@ -172,14 +172,14 @@ fetch_store_general( struct fetch_pipeline_middle_end *fpme, const unsigned *fetch_elts, unsigned count ) { - const unsigned *edgeflag = fpme->draw->user.edgeflag; float *out = (float *)out_ptr; uint i, j; for (i = 0; i < count; i++) { unsigned elt = fetch_elts[i]; - fpme->header( edgeflag, i, &out ); + fpme->header( elt, &out ); + elt &= ~DRAW_PT_FLAG_MASK; for (j = 0; j < fpme->nr_fetch; j++) { float attrib[4]; diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c index 942df518eb..e70e63d08f 100644 --- a/src/gallium/auxiliary/draw/draw_pt_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c @@ -85,7 +85,6 @@ static void do_triangle( struct draw_context *draw, { struct prim_header prim; -// _mesa_printf("tri %d %d %d\n", i0, i1, i2); prim.v[0] = (struct vertex_header *)v0; prim.v[1] = (struct vertex_header *)v1; prim.v[2] = (struct vertex_header *)v2; @@ -95,6 +94,11 @@ static void do_triangle( struct draw_context *draw, (prim.v[2]->edgeflag << 2)); prim.pad = 0; + if (0) debug_printf("tri ef: %d %d %d\n", + prim.v[0]->edgeflag, + prim.v[1]->edgeflag, + prim.v[2]->edgeflag); + draw->pipeline.first->tri( draw->pipeline.first, &prim ); } diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 5a068761df..107dcfc269 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -55,9 +55,6 @@ struct vcache_frontend { unsigned draw_count; unsigned fetch_count; - pt_elt_func elt_func; - const void *elt_ptr; - struct draw_pt_middle_end *middle; unsigned input_prim; @@ -66,17 +63,6 @@ struct vcache_frontend { static void vcache_flush( struct vcache_frontend *vcache ) { -#if 0 - /* Should always be true if output_prim == input_prim, otherwise - * not so much... - */ - unsigned i; - for (i = 0; i < vcache->draw_count; i++) { - assert( vcache->fetch_elts[vcache->draw_elts[i]] == - vcache->elt_func(vcache->elt_ptr, i) ); - } -#endif - if (vcache->draw_count) { vcache->middle->run( vcache->middle, vcache->fetch_elts, @@ -115,26 +101,73 @@ static void vcache_elt( struct vcache_frontend *vcache, vcache->draw_elts[vcache->draw_count++] = vcache->out[idx]; } + +static unsigned add_edgeflag( struct vcache_frontend *vcache, + unsigned idx, + unsigned mask ) +{ + if (mask && draw_get_edgeflag(vcache->draw, idx)) + return idx | DRAW_PT_EDGEFLAG; + else + return idx; +} + + +static unsigned add_reset_stipple( unsigned idx, + unsigned reset ) +{ + if (reset) + return idx | DRAW_PT_RESET_STIPPLE; + else + return idx; +} + static void vcache_triangle( struct vcache_frontend *vcache, unsigned i0, unsigned i1, unsigned i2 ) { - /* TODO: encode edgeflags in draw_elts */ + vcache_elt(vcache, i0 | DRAW_PT_EDGEFLAG | DRAW_PT_RESET_STIPPLE); + vcache_elt(vcache, i1 | DRAW_PT_EDGEFLAG); + vcache_elt(vcache, i2 | DRAW_PT_EDGEFLAG); + vcache_check_flush(vcache); +} + + +static void vcache_ef_triangle( struct vcache_frontend *vcache, + boolean reset_stipple, + unsigned ef_mask, + unsigned i0, + unsigned i1, + unsigned i2 ) +{ + i0 = add_edgeflag( vcache, i0, (ef_mask >> 0) & 1 ); + i1 = add_edgeflag( vcache, i1, (ef_mask >> 1) & 1 ); + i2 = add_edgeflag( vcache, i2, (ef_mask >> 2) & 1 ); + + i0 = add_reset_stipple( i0, reset_stipple ); + vcache_elt(vcache, i0); vcache_elt(vcache, i1); vcache_elt(vcache, i2); vcache_check_flush(vcache); + + if (0) debug_printf("emit tri ef: %d %d %d\n", + !!(i0 & DRAW_PT_EDGEFLAG), + !!(i1 & DRAW_PT_EDGEFLAG), + !!(i2 & DRAW_PT_EDGEFLAG)); + } + static void vcache_line( struct vcache_frontend *vcache, - boolean reset, + boolean reset_stipple, unsigned i0, unsigned i1 ) { - /* TODO: encode reset-line-stipple in draw_elts */ - (void) reset; + i0 = add_reset_stipple( i0, reset_stipple ); + vcache_elt(vcache, i0); vcache_elt(vcache, i1); vcache_check_flush(vcache); @@ -158,39 +191,43 @@ static void vcache_quad( struct vcache_frontend *vcache, vcache_triangle( vcache, i1, i2, i3 ); } +static void vcache_ef_quad( struct vcache_frontend *vcache, + unsigned i0, + unsigned i1, + unsigned i2, + unsigned i3 ) +{ + const unsigned omitEdge2 = ~(1 << 1); + const unsigned omitEdge3 = ~(1 << 2); + vcache_ef_triangle( vcache, 1, omitEdge2, i0, i1, i3 ); + vcache_ef_triangle( vcache, 0, omitEdge3, i1, i2, i3 ); +} + -static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { - PIPE_PRIM_POINTS, - PIPE_PRIM_LINES, - PIPE_PRIM_LINES, - PIPE_PRIM_LINES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES -}; -static void vcache_run_pv2( struct draw_pt_front_end *frontend, - pt_elt_func get_elt, - const void *elts, - unsigned count ) +static void vcache_run( struct draw_pt_front_end *frontend, + pt_elt_func get_elt, + const void *elts, + unsigned count ) { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; + struct draw_context *draw = vcache->draw; + + boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL); + + boolean flatfirst = (draw->rasterizer->flatshade && + draw->rasterizer->flatshade_first); unsigned i; - - /* These are for validation only: - */ - vcache->elt_func = get_elt; - vcache->elt_ptr = elts; + +// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count ); switch (vcache->input_prim) { case PIPE_PRIM_POINTS: for (i = 0; i < count; i ++) { - vcache_point( vcache, - get_elt(elts, i) ); + vcache_point( vcache, + get_elt(elts, i + 0) ); } break; @@ -205,17 +242,17 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend, case PIPE_PRIM_LINE_LOOP: if (count >= 2) { - for (i = 1; i < count; i++) { - vcache_line( vcache, + for (i = 1; i < count; i++) { + vcache_line( vcache, i == 1, /* XXX: only if vb not split */ get_elt(elts, i - 1), - get_elt(elts, i) ); - } + get_elt(elts, i )); + } - vcache_line( vcache, + vcache_line( vcache, 0, get_elt(elts, count - 1), - get_elt(elts, 0) ); + get_elt(elts, 0 )); } break; @@ -224,72 +261,163 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend, vcache_line( vcache, i == 1, get_elt(elts, i - 1), - get_elt(elts, i) ); + get_elt(elts, i )); } break; case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2) ); + if (unfilled) { + for (i = 0; i+2 < count; i += 3) { + vcache_ef_triangle( vcache, + 1, + ~0, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } + } + else { + for (i = 0; i+2 < count; i += 3) { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } } break; case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 0; i+2 < count; i++) { - if (i & 1) { - vcache_triangle( vcache, - get_elt(elts, i + 1), - get_elt(elts, i + 0), - get_elt(elts, i + 2) ); + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + if (i & 1) { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 2), + get_elt(elts, i + 1 )); + } + else { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } } - else { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2) ); + } + else { + for (i = 0; i+2 < count; i++) { + if (i & 1) { + vcache_triangle( vcache, + get_elt(elts, i + 1), + get_elt(elts, i + 0), + get_elt(elts, i + 2 )); + } + else { + vcache_triangle( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } } } break; case PIPE_PRIM_TRIANGLE_FAN: - for (i = 0; i+2 < count; i++) { - vcache_triangle( vcache, - get_elt(elts, 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2) ); + if (count >= 3) { + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + vcache_triangle( vcache, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0 )); + } + } + else { + for (i = 0; i+2 < count; i++) { + vcache_triangle( vcache, + get_elt(elts, 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } + } } break; case PIPE_PRIM_QUADS: - for (i = 0; i+3 < count; i += 4) { - vcache_quad( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, i + 3)); + if (unfilled) { + for (i = 0; i+3 < count; i += 4) { + vcache_ef_quad( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, i + 3)); + } + } + else { + for (i = 0; i+3 < count; i += 4) { + vcache_quad( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, i + 3)); + } } break; case PIPE_PRIM_QUAD_STRIP: - for (i = 0; i+3 < count; i += 2) { - vcache_quad( vcache, - get_elt(elts, i + 2), - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 3)); + if (unfilled) { + for (i = 0; i+3 < count; i += 2) { + vcache_ef_quad( vcache, + get_elt(elts, i + 2), + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 3)); + } + } + else { + for (i = 0; i+3 < count; i += 2) { + vcache_quad( vcache, + get_elt(elts, i + 2), + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 3)); + } } break; case PIPE_PRIM_POLYGON: - for (i = 0; i+2 < count; i++) { - vcache_triangle( vcache, - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, 0)); + if (unfilled) { + /* These bitflags look a little odd because we submit the + * vertices as (1,2,0) to satisfy flatshade requirements. + */ + const unsigned edge_first = (1<<2); + const unsigned edge_middle = (1<<0); + const unsigned edge_last = (1<<1); + + for (i = 0; i+2 < count; i++) { + unsigned ef_mask = edge_middle; + + if (i == 0) + ef_mask |= edge_first; + + if (i + 3 == count) + ef_mask |= edge_last; + + vcache_ef_triangle( vcache, + i == 0, + ef_mask, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0)); + } + } + else { + for (i = 0; i+2 < count; i++) { + vcache_triangle( vcache, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0)); + } } break; @@ -302,88 +430,21 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend, } -static void vcache_run_pv0( struct draw_pt_front_end *frontend, - pt_elt_func get_elt, - const void *elts, - unsigned count ) -{ - struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; - unsigned i; - - /* These are for validation only: - */ - vcache->elt_func = get_elt; - vcache->elt_ptr = elts; - - switch (vcache->input_prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i ++) { - vcache_point( vcache, - get_elt(elts, i) ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - vcache_line( vcache, - TRUE, - get_elt(elts, i + 0), - get_elt(elts, i + 1)); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < count; i++) { - vcache_line( vcache, - i == 1, - get_elt(elts, i - 1), - get_elt(elts, i) ); - } - break; - - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2) ); - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 0; i+2 < count; i++) { - if (i & 1) { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 2), - get_elt(elts, i + 1) ); - } - else { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2) ); - } - } - break; - case PIPE_PRIM_TRIANGLE_FAN: - for (i = 0; i+2 < count; i++) { - vcache_triangle( vcache, - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, 0) ); - } - break; +static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { + PIPE_PRIM_POINTS, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES +}; - default: - assert(0); - break; - } - - vcache_flush( vcache ); -} static void vcache_prepare( struct draw_pt_front_end *frontend, unsigned prim, @@ -391,11 +452,14 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; +/* if (vcache->draw->rasterizer->flatshade_first) vcache->base.run = vcache_run_pv0; else vcache->base.run = vcache_run_pv2; - +*/ + + vcache->base.run = vcache_run; vcache->input_prim = prim; vcache->output_prim = reduced_prim[prim]; -- cgit v1.2.3 From a8a5376406cabf5aa6a44f7d37f5f8abbb4adf56 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 7 Apr 2008 12:28:31 +0100 Subject: draw: strip edgeflags out of fetch-emit path --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 39f0b40838..0806076956 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -149,7 +149,7 @@ fetch_store_general( struct fetch_emit_middle_end *feme, uint i, j; for (i = 0; i < count; i++) { - unsigned elt = fetch_elts[i]; + unsigned elt = fetch_elts[i] & ~DRAW_PT_FLAG_MASK; for (j = 0; j < feme->nr_fetch; j++) { float attrib[4]; -- cgit v1.2.3 From 24fc93ebdc119ee01d6ce47ea4fe33a2a8067bd2 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Apr 2008 19:39:28 +0200 Subject: gallium: Stop warnings --- src/gallium/include/pipe/p_util.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 8e3aaee496..1bc00ac7a0 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -207,7 +207,10 @@ mem_dup(const void *src, uint size) #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) #define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) +/* JB stop warnings */ +#ifndef Elements #define Elements(x) (sizeof(x)/sizeof((x)[0])) +#endif #define Offset(TYPE, MEMBER) ((unsigned)&(((TYPE *)NULL)->MEMBER)) /** -- cgit v1.2.3 From d5d93a31580cf58744b4d186a4ab8fac09743a33 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Apr 2008 19:40:43 +0200 Subject: i915: Pulled in changes from i915tex --- src/gallium/winsys/dri/intel/Makefile | 7 +- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 488 ++++++----- src/gallium/winsys/dri/intel/intel_batchbuffer.h | 108 ++- src/gallium/winsys/dri/intel/intel_batchpool.c | 427 ---------- src/gallium/winsys/dri/intel/intel_batchpool.h | 37 - src/gallium/winsys/dri/intel/intel_context.c | 5 +- src/gallium/winsys/dri/intel/intel_context.h | 2 +- src/gallium/winsys/dri/intel/intel_ioctl.c | 138 ++++ src/gallium/winsys/dri/intel/intel_ioctl.h | 40 + src/gallium/winsys/dri/intel/intel_screen.c | 53 +- src/gallium/winsys/dri/intel/intel_screen.h | 9 +- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 4 +- src/gallium/winsys/dri/intel/intel_winsys.h | 2 +- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 30 +- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 55 +- src/gallium/winsys/dri/intel/server/i830_common.h | 46 +- src/gallium/winsys/dri/intel/ws_dri_bufmgr.c | 945 ++++++++++++++++++++++ src/gallium/winsys/dri/intel/ws_dri_bufmgr.h | 138 ++++ src/gallium/winsys/dri/intel/ws_dri_bufpool.h | 102 +++ src/gallium/winsys/dri/intel/ws_dri_drmpool.c | 268 ++++++ src/gallium/winsys/dri/intel/ws_dri_fencemgr.c | 372 +++++++++ src/gallium/winsys/dri/intel/ws_dri_fencemgr.h | 115 +++ src/gallium/winsys/dri/intel/ws_dri_mallocpool.c | 162 ++++ src/gallium/winsys/dri/intel/ws_dri_slabpool.c | 945 ++++++++++++++++++++++ 24 files changed, 3742 insertions(+), 756 deletions(-) delete mode 100644 src/gallium/winsys/dri/intel/intel_batchpool.c delete mode 100644 src/gallium/winsys/dri/intel/intel_batchpool.h create mode 100644 src/gallium/winsys/dri/intel/intel_ioctl.c create mode 100644 src/gallium/winsys/dri/intel/intel_ioctl.h create mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufmgr.c create mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufmgr.h create mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufpool.h create mode 100644 src/gallium/winsys/dri/intel/ws_dri_drmpool.c create mode 100644 src/gallium/winsys/dri/intel/ws_dri_fencemgr.c create mode 100644 src/gallium/winsys/dri/intel/ws_dri_fencemgr.h create mode 100644 src/gallium/winsys/dri/intel/ws_dri_mallocpool.c create mode 100644 src/gallium/winsys/dri/intel/ws_dri_slabpool.c (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index 40654bb2ac..f140939248 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -19,11 +19,14 @@ DRIVER_SOURCES = \ intel_context.c \ intel_lock.c \ intel_screen.c \ - intel_batchpool.c + ws_dri_bufmgr.c \ + ws_dri_drmpool.c \ + ws_dri_fencemgr.c \ + ws_dri_mallocpool.c \ + ws_dri_slabpool.c C_SOURCES = \ $(COMMON_GALLIUM_SOURCES) \ - $(COMMON_BM_SOURCES) \ $(DRIVER_SOURCES) ASM_SOURCES = diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 5830b88b37..05223bf700 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -25,108 +25,95 @@ * **************************************************************************/ -#include -#include #include "intel_batchbuffer.h" -#include "intel_context.h" -#include "intel_screen.h" -#include "intel_reg.h" -#include "drm.h" - -/* Relocations in kernel space: - * - pass dma buffer seperately - * - memory manager knows how to patch - * - pass list of dependent buffers - * - pass relocation list - * - * Either: - * - get back an offset for buffer to fire - * - memory manager knows how to fire buffer - * - * Really want the buffer to be AGP and pinned. - * - */ - -/* Cliprect fence: The highest fence protecting a dma buffer - * containing explicit cliprect information. Like the old drawable - * lock but irq-driven. X server must wait for this fence to expire - * before changing cliprects [and then doing sw rendering?]. For - * other dma buffers, the scheduler will grab current cliprect info - * and mix into buffer. X server must hold the lock while changing - * cliprects??? Make per-drawable. Need cliprects in shared memory - * -- beats storing them with every cmd buffer in the queue. - * - * ==> X server must wait for this fence to expire before touching the - * framebuffer with new cliprects. - * - * ==> Cliprect-dependent buffers associated with a - * cliprect-timestamp. All of the buffers associated with a timestamp - * must go to hardware before any buffer with a newer timestamp. - * - * ==> Dma should be queued per-drawable for correct X/GL - * synchronization. Or can fences be used for this? - * - * Applies to: Blit operations, metaops, X server operations -- X - * server automatically waits on its own dma to complete before - * modifying cliprects ??? - */ +#include "intel_ioctl.h" +#include +#if 0 static void -intel_dump_batchbuffer(uint offset, uint * ptr, uint count) +intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) { int i; - printf("\n\n\nSTART BATCH (%d dwords):\n", count / 4); - for (i = 0; i < count / 4; i += 1) - printf("\t0x%08x\n", ptr[i]); - printf("END BATCH\n\n\n"); + fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); + for (i = 0; i < count / 4; i += 4) + fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", + offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); + fprintf(stderr, "END BATCH\n\n\n"); +} +#endif + +static void +intel_realloc_relocs(struct intel_batchbuffer *batch, int num_relocs) +{ + unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; + + size *= sizeof(uint32_t); + batch->reloc = realloc(batch->reloc, size); + batch->reloc_size = num_relocs; } void intel_batchbuffer_reset(struct intel_batchbuffer *batch) { - int i; - - if (batch->map) { - driBOUnmap(batch->buffer); - batch->map = NULL; - } - /* * Get a new, free batchbuffer. */ - batch->size = BATCH_SZ; - driBOData(batch->buffer, batch->size, NULL, 0); + drmBO *bo; + struct drm_bo_info_req *req; + + driBOUnrefUserList(batch->list); + driBOResetList(batch->list); - driBOResetList(&batch->list); + batch->size = 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; + driBOData(batch->buffer, batch->size, NULL, NULL, 0); /* - * Unreference buffers previously on the relocation list. + * Add the batchbuffer to the validate list. */ - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - driBOUnReference(r->buf); - } - batch->list_count = 0; - batch->nr_relocs = 0; - batch->flags = 0; + driBOAddListItem(batch->list, batch->buffer, + DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, + &batch->dest_location, &batch->node); + + req = &batch->node->bo_arg.d.req.bo_req; /* - * We don't refcount the batchbuffer itself since we can't destroy it - * while it's on the list. + * Set up information needed for us to make relocations + * relative to the underlying drm buffer objects. */ - driBOAddListItem(&batch->list, batch->buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE); + driReadLockKernelBO(); + bo = driBOKernel(batch->buffer); + req->presumed_offset = (uint64_t) bo->offset; + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + batch->drmBOVirtual = (uint8_t *) bo->virtual; + driReadUnlockKernelBO(); + /* + * Adjust the relocation buffer size. + */ + + if (batch->reloc_size > INTEL_MAX_RELOCS || + batch->reloc == NULL) + intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); + + assert(batch->reloc != NULL); + batch->reloc[0] = 0; /* No relocs yet. */ + batch->reloc[1] = 1; /* Reloc type 1 */ + batch->reloc[2] = 0; /* Only a single relocation list. */ + batch->reloc[3] = 0; /* Only a single relocation list. */ batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->poolOffset = driBOPoolOffset(batch->buffer); batch->ptr = batch->map; + batch->dirty_state = ~0; + batch->nr_relocs = 0; + batch->flags = 0; + batch->id = 0;//batch->intel->intelScreen->batch_id++; } - /*====================================================================== * Public functions */ @@ -141,121 +128,253 @@ intel_batchbuffer_alloc(struct intel_context *intel) &batch->buffer, 4096, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); batch->last_fence = NULL; - driBOCreateList(20, &batch->list); + batch->list = driBOCreateList(20); + batch->reloc = NULL; intel_batchbuffer_reset(batch); return batch; } - void intel_batchbuffer_free(struct intel_batchbuffer *batch) { if (batch->last_fence) { driFenceFinish(batch->last_fence, - DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, - GL_FALSE); - driFenceUnReference(batch->last_fence); - batch->last_fence = NULL; + DRM_FENCE_TYPE_EXE, GL_FALSE); + driFenceUnReference(&batch->last_fence); } if (batch->map) { driBOUnmap(batch->buffer); batch->map = NULL; } driBOUnReference(batch->buffer); + driBOFreeList(batch->list); + if (batch->reloc) + free(batch->reloc); batch->buffer = NULL; free(batch); } +void +intel_offset_relocation(struct intel_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask) +{ + int itemLoc; + struct _drmBONode *node; + uint32_t *reloc; + struct drm_bo_info_req *req; + + driBOAddListItem(batch->list, driBO, val_flags, val_mask, + &itemLoc, &node); + req = &node->bo_arg.d.req.bo_req; + + if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { + + /* + * Stop other threads from tampering with the underlying + * drmBO while we're reading its offset. + */ + + driReadLockKernelBO(); + req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; + driReadUnlockKernelBO(); + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + } + + pre_add += driBOPoolOffset(driBO); + + if (batch->nr_relocs == batch->reloc_size) + intel_realloc_relocs(batch, batch->reloc_size * 2); + + reloc = batch->reloc + + (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); + + reloc[0] = ((uint8_t *)batch->ptr - batch->drmBOVirtual); + intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add); + reloc[1] = pre_add; + reloc[2] = itemLoc; + reloc[3] = batch->dest_location; + batch->nr_relocs++; +} static void -intel_batch_ioctl(struct intel_context *intel, - uint start_offset, uint used, boolean allow_unlock) +i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) { - drmI830BatchBuffer batch; - - batch.start = start_offset; - batch.used = used; - batch.cliprects = NULL; /* unused */ - batch.num_cliprects = 0; - batch.DR1 = 0; - batch.DR4 = 0; /* still need this ? */ - - DBG(IOCTL, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n", - __FUNCTION__, - batch.start, - batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); - - if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, - sizeof(batch))) { - printf("DRM_I830_BATCHBUFFER: %d\n", -errno); - UNLOCK_HARDWARE(intel); - exit(1); - } + buf->handle = rep->handle; + buf->flags = rep->flags; + buf->size = rep->size; + buf->offset = rep->offset; + buf->mapHandle = rep->arg_handle; + buf->proposedFlags = rep->proposed_flags; + buf->start = rep->buffer_start; + buf->fenceFlags = rep->fence_flags; + buf->replyFlags = rep->rep_flags; + buf->pageAlignment = rep->page_alignment; } +static int +i915_execbuf(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, + drmBOList *list, + struct drm_i915_execbuffer *ea) +{ + struct intel_context *intel = batch->intel; + drmBONode *node; + drmMMListHead *l; + struct drm_i915_op_arg *arg, *first; + struct drm_bo_op_req *req; + struct drm_bo_info_rep *rep; + uint64_t *prevNext = NULL; + drmBO *buf; + int ret = 0; + uint32_t count = 0; + + first = NULL; + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + + arg = &node->bo_arg; + req = &arg->d.req; + + if (!first) + first = arg; + + if (prevNext) + *prevNext = (unsigned long)arg; + + prevNext = &arg->next; + req->bo_req.handle = node->buf->handle; + req->op = drm_bo_validate; + req->bo_req.flags = node->arg0; + req->bo_req.mask = node->arg1; + req->bo_req.hint |= 0; + count++; + } + + memset(ea, 0, sizeof(*ea)); + ea->num_buffers = count; + ea->batch.start = batch->poolOffset; + ea->batch.used = used; +#if 0 /* ZZZ JB: no cliprects used */ + ea->batch.cliprects = intel->pClipRects; + ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); +#else + ea->batch.cliprects = NULL; + ea->batch.num_cliprects = 0; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0; +#endif + ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; + ea->ops_list = (unsigned long) first; + first->reloc_ptr = (unsigned long) batch->reloc; + batch->reloc[0] = batch->nr_relocs; + + //return -EFAULT; + do { + ret = drmCommandWriteRead(intel->driFd, DRM_I915_EXECBUFFER, ea, + sizeof(*ea)); + } while (ret == -EAGAIN); + + if (ret != 0) + return ret; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + arg = &node->bo_arg; + rep = &arg->d.rep.bo_info; + + if (!arg->handled) { + return -EFAULT; + } + if (arg->d.rep.ret) + return arg->d.rep.ret; + + buf = node->buf; + i915_drm_copy_reply(rep, buf); + } + return 0; +} /* TODO: Push this whole function into bufmgr. */ -static void +static struct _DriFenceObject * do_flush_locked(struct intel_batchbuffer *batch, - uint used, boolean allow_unlock) + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) { - uint *ptr; - uint i, fenceFlags; + struct intel_context *intel = batch->intel; struct _DriFenceObject *fo; + drmFence fence; + drmBOList *boList; + struct drm_i915_execbuffer ea; + int ret = 0; + + driBOValidateUserList(batch->list); + boList = driGetdrmBOList(batch->list); + +#if 0 /* ZZZ JB Allways run */ + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { +#else + if (1) { +#endif + ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); + } else { + driPutdrmBOList(batch->list); + fo = NULL; + goto out; + } + driPutdrmBOList(batch->list); + if (ret) + abort(); - driBOValidateList(batch->intel->driFd, &batch->list); - - /* Apply the relocations. This nasty map indicates to me that the - * whole task should be done internally by the memory manager, and - * that dma buffers probably need to be pinned within agp space. - */ - ptr = (uint *) driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_ALLOW_UNFENCED_MAP); + if (ea.fence_arg.error != 0) { - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; + /* + * The hardware has been idled by the kernel. + * Don't fence the driBOs. + */ - ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta; + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); +#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ + _mesa_printf("fence error\n"); +#endif + batch->last_fence = NULL; + fo = NULL; + goto out; } - if (0) - intel_dump_batchbuffer(0, ptr, used); + fence.handle = ea.fence_arg.handle; + fence.fence_class = ea.fence_arg.fence_class; + fence.type = ea.fence_arg.type; + fence.flags = ea.fence_arg.flags; + fence.signaled = ea.fence_arg.signaled; - driBOUnmap(batch->buffer); - batch->map = NULL; - - intel_batch_ioctl(batch->intel, - driBOOffset(batch->buffer), - used, allow_unlock); - - /* - * Kernel fencing. The flags tells the kernel that we've - * programmed an MI_FLUSH. - */ - fenceFlags = DRM_I915_FENCE_FLAG_FLUSHED; - fo = driFenceBuffers(batch->intel->driFd, "Batch fence", fenceFlags); + fo = driBOFenceUserList(batch->intel->intelScreen->mgr, batch->list, + "SuperFence", &fence); + if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); /* - * User space fencing. - */ - driBOFence(batch->buffer, fo); - - if (driFenceType(fo) == DRM_FENCE_TYPE_EXE) { - /* - * Oops. We only validated a batch buffer. This means we - * didn't do any proper rendering. Discard this fence object. - */ - driFenceUnReference(fo); - } - else { - driFenceUnReference(batch->last_fence); - batch->last_fence = fo; - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - driBOFence(r->buf, fo); - } - } + * FIXME: Context last fence?? + */ + batch->last_fence = fo; + driFenceReference(fo); + } + out: +#if 0 /* ZZZ JB: fix this */ + intel->vtbl.lost_hardware(intel); +#else + (void)intel; +#endif + return fo; } @@ -263,29 +382,41 @@ struct _DriFenceObject * intel_batchbuffer_flush(struct intel_batchbuffer *batch) { struct intel_context *intel = batch->intel; - uint used = batch->ptr - batch->map; - const boolean was_locked = intel->locked; + GLuint used = batch->ptr - batch->map; + GLboolean was_locked = intel->locked; + struct _DriFenceObject *fence; if (used == 0) return batch->last_fence; -#define MI_FLUSH ((0 << 29) | (4 << 23)) - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a * performance drain that we would like to avoid. */ +#if 0 /* ZZZ JB: what should we do here? */ if (used & 4) { - ((int *) batch->ptr)[0] = MI_FLUSH; + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); ((int *) batch->ptr)[1] = 0; ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; used += 12; } else { - ((int *) batch->ptr)[0] = MI_FLUSH; + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; used += 8; } - +#else + if (used & 4) { + ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 8; + } +#endif driBOUnmap(batch->buffer); batch->ptr = NULL; batch->map = NULL; @@ -296,7 +427,8 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) if (!was_locked) LOCK_HARDWARE(intel); - do_flush_locked(batch, used, GL_FALSE); + fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + GL_FALSE); if (!was_locked) UNLOCK_HARDWARE(intel); @@ -304,52 +436,20 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) /* Reset the buffer: */ intel_batchbuffer_reset(batch); - return batch->last_fence; + return fence; } - void intel_batchbuffer_finish(struct intel_batchbuffer *batch) { struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); - if (fence) { - driFenceReference(fence); - driFenceFinish(fence, - DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, - GL_FALSE); - driFenceUnReference(fence); - } + driFenceFinish(fence, driFenceType(fence), GL_FALSE); + driFenceUnReference(&fence); } - -/* This is the only way buffers get added to the validate list. - */ -boolean -intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - struct _DriBufferObject *buffer, - uint flags, uint mask, uint delta) -{ - assert(batch->nr_relocs < MAX_RELOCS); - - driBOAddListItem(&batch->list, buffer, flags, mask); - - { - struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; - driBOReference(buffer); - r->buf = buffer; - r->offset = batch->ptr - batch->map; - r->delta = delta; - *(uint *) batch->ptr = 0x12345678; - } - - batch->ptr += 4; - return GL_TRUE; -} - - void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, uint bytes, uint flags) + const void *data, GLuint bytes, GLuint flags) { assert((bytes & 3) == 0); intel_batchbuffer_require_space(batch, bytes, flags); diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h index caf6870a3c..9e4b8043bf 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -1,54 +1,20 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - #ifndef INTEL_BATCHBUFFER_H #define INTEL_BATCHBUFFER_H -#include "pipe/p_debug.h" -#include "pipe/p_compiler.h" -#include "dri_bufmgr.h" +#include "mtypes.h" +#include "ws_dri_bufmgr.h" struct intel_context; #define BATCH_SZ 16384 #define BATCH_RESERVED 16 -#define MAX_RELOCS 4096 +#define INTEL_DEFAULT_RELOCS 100 +#define INTEL_MAX_RELOCS 400 #define INTEL_BATCH_NO_CLIPRECTS 0x1 #define INTEL_BATCH_CLIPRECTS 0x2 -struct buffer_reloc -{ - struct _DriBufferObject *buf; - uint offset; - uint delta; /* not needed? */ -}; - struct intel_batchbuffer { struct bufmgr *bm; @@ -56,19 +22,30 @@ struct intel_batchbuffer struct _DriBufferObject *buffer; struct _DriFenceObject *last_fence; - uint flags; + GLuint flags; - drmBOList list; - uint list_count; - ubyte *map; - ubyte *ptr; + struct _DriBufferList *list; + GLuint list_count; + GLubyte *map; + GLubyte *ptr; - struct buffer_reloc reloc[MAX_RELOCS]; - uint nr_relocs; - uint size; + uint32_t *reloc; + GLuint reloc_size; + GLuint nr_relocs; + + GLuint size; + + GLuint dirty_state; + GLuint id; + + uint32_t poolOffset; + uint8_t *drmBOVirtual; + struct _drmBONode *node; /* Validation list node for this buffer */ + int dest_location; /* Validation list sequence for this buffer */ }; -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context *intel); +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context + *intel); void intel_batchbuffer_free(struct intel_batchbuffer *batch); @@ -82,26 +59,28 @@ void intel_batchbuffer_reset(struct intel_batchbuffer *batch); /* Unlike bmBufferData, this currently requires the buffer be mapped. - * Consider it a convenience function wrapping multiple + * Consider it a convenience function wrapping multple * intel_buffer_dword() calls. */ void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, uint bytes, uint flags); + const void *data, GLuint bytes, GLuint flags); void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - uint bytes); + GLuint bytes); -boolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - struct _DriBufferObject *buffer, - uint flags, - uint mask, uint offset); +void +intel_offset_relocation(struct intel_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask); /* Inline functions - might actually be better off with these * non-inlined. Certainly better off switching all command packets to * be passed as structs rather than dwords, but that's a little bit of * work... */ -static INLINE uint +static INLINE GLuint intel_batchbuffer_space(struct intel_batchbuffer *batch) { return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); @@ -109,22 +88,26 @@ intel_batchbuffer_space(struct intel_batchbuffer *batch) static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, uint dword) +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) { assert(batch->map); assert(intel_batchbuffer_space(batch) >= 4); - *(uint *) (batch->ptr) = dword; + *(GLuint *) (batch->ptr) = dword; batch->ptr += 4; } static INLINE void intel_batchbuffer_require_space(struct intel_batchbuffer *batch, - uint sz, uint flags) + GLuint sz, GLuint flags) { + struct _DriFenceObject *fence; + assert(sz < batch->size - 8); if (intel_batchbuffer_space(batch) < sz || - (batch->flags != 0 && flags != 0 && batch->flags != flags)) - intel_batchbuffer_flush(batch); + (batch->flags != 0 && flags != 0 && batch->flags != flags)) { + fence = intel_batchbuffer_flush(batch); + driFenceUnReference(&fence); + } batch->flags |= flags; } @@ -134,14 +117,15 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch, #define BATCH_LOCALS #define BEGIN_BATCH(n, flags) do { \ + assert(!intel->prim.flush); \ intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ } while (0) #define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) #define OUT_RELOC(buf,flags,mask,delta) do { \ - assert((delta) >= 0); \ - intel_batchbuffer_emit_reloc(intel->batch, buf, flags, mask, delta); \ + assert((delta) >= 0); \ + intel_offset_relocation(intel->batch, delta, buf, flags, mask); \ } while (0) #define ADVANCE_BATCH() do { } while(0) diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.c b/src/gallium/winsys/dri/intel/intel_batchpool.c deleted file mode 100644 index ce154c7b88..0000000000 --- a/src/gallium/winsys/dri/intel/intel_batchpool.c +++ /dev/null @@ -1,427 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -/** - * XXX NOTE: there are no intel dependencies in this file. - * Rename to dri_batchpool.c? - */ - -#include -#include -#include -#include - -#include "pipe/p_compiler.h" -#include "pipe/p_thread.h" - -#include "dri_bufpool.h" -#include "dri_bufmgr.h" -#include "intel_batchpool.h" - - -typedef struct -{ - drmMMListHead head; - struct _BPool *parent; - struct _DriFenceObject *fence; - unsigned long start; - int unfenced; - int mapped; -} BBuf; - -typedef struct _BPool -{ - _glthread_Mutex mutex; - unsigned long bufSize; - unsigned poolSize; - unsigned numFree; - unsigned numTot; - unsigned numDelayed; - unsigned checkDelayed; - drmMMListHead free; - drmMMListHead delayed; - drmMMListHead head; - drmBO kernelBO; - void *virtual; - BBuf *bufs; -} BPool; - - -static BPool * -createBPool(int fd, unsigned long bufSize, unsigned numBufs, unsigned flags, - unsigned checkDelayed) -{ - BPool *p = (BPool *) malloc(sizeof(*p)); - BBuf *buf; - int i; - - if (!p) - return NULL; - - p->bufs = (BBuf *) malloc(numBufs * sizeof(*p->bufs)); - if (!p->bufs) { - free(p); - return NULL; - } - - DRMINITLISTHEAD(&p->free); - DRMINITLISTHEAD(&p->head); - DRMINITLISTHEAD(&p->delayed); - - p->numTot = numBufs; - p->numFree = numBufs; - p->bufSize = bufSize; - p->numDelayed = 0; - p->checkDelayed = checkDelayed; - - _glthread_INIT_MUTEX(p->mutex); - - if (drmBOCreate(fd, 0, numBufs * bufSize, 0, NULL, drm_bo_type_dc, - flags, DRM_BO_HINT_DONT_FENCE, &p->kernelBO)) { - free(p->bufs); - free(p); - return NULL; - } - if (drmBOMap(fd, &p->kernelBO, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, - &p->virtual)) { - drmBODestroy(fd, &p->kernelBO); - free(p->bufs); - free(p); - return NULL; - } - - /* - * We unmap the buffer so that we can validate it later. Note that this is - * just a synchronizing operation. The buffer will have a virtual mapping - * until it is destroyed. - */ - - drmBOUnmap(fd, &p->kernelBO); - - buf = p->bufs; - for (i = 0; i < numBufs; ++i) { - buf->parent = p; - buf->fence = NULL; - buf->start = i * bufSize; - buf->mapped = 0; - buf->unfenced = 0; - DRMLISTADDTAIL(&buf->head, &p->free); - buf++; - } - - return p; -} - - -static void -pool_checkFree(BPool * p, int wait) -{ - drmMMListHead *list, *prev; - BBuf *buf; - int signaled = 0; - int i; - - list = p->delayed.next; - - if (p->numDelayed > 3) { - for (i = 0; i < p->numDelayed; i += 3) { - list = list->next; - } - } - - prev = list->prev; - for (; list != &p->delayed; list = prev, prev = list->prev) { - - buf = DRMLISTENTRY(BBuf, list, head); - - if (!signaled) { - if (wait) { - driFenceFinish(buf->fence, DRM_FENCE_TYPE_EXE, 1); - signaled = 1; - } - else { - signaled = driFenceSignaled(buf->fence, DRM_FENCE_TYPE_EXE); - } - } - - if (!signaled) - break; - - driFenceUnReference(buf->fence); - buf->fence = NULL; - DRMLISTDEL(list); - p->numDelayed--; - DRMLISTADD(list, &p->free); - p->numFree++; - } -} - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, unsigned flags, unsigned hint, - unsigned alignment) -{ - BPool *p = (BPool *) pool->data; - - drmMMListHead *item; - - if (alignment && (alignment != 4096)) - return NULL; - - _glthread_LOCK_MUTEX(p->mutex); - - if (p->numFree == 0) - pool_checkFree(p, TRUE); - - if (p->numFree == 0) { - fprintf(stderr, "Out of fixed size buffer objects\n"); - BM_CKFATAL(-ENOMEM); - } - - item = p->free.next; - - if (item == &p->free) { - fprintf(stderr, "Fixed size buffer pool corruption\n"); - } - - DRMLISTDEL(item); - --p->numFree; - - _glthread_UNLOCK_MUTEX(p->mutex); - return (void *) DRMLISTENTRY(BBuf, item, head); -} - - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - - if (buf->fence) { - DRMLISTADDTAIL(&buf->head, &p->delayed); - p->numDelayed++; - } - else { - buf->unfenced = 0; - DRMLISTADD(&buf->head, &p->free); - p->numFree++; - } - - if ((p->numDelayed % p->checkDelayed) == 0) - pool_checkFree(p, 0); - - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, void **virtual) -{ - - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - - /* - * Currently Mesa doesn't have any condition variables to resolve this - * cleanly in a multithreading environment. - * We bail out instead. - */ - - if (buf->mapped) { - fprintf(stderr, "Trying to map already mapped buffer object\n"); - BM_CKFATAL(-EINVAL); - } - -#if 0 - if (buf->unfenced && !(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) { - fprintf(stderr, "Trying to map an unfenced buffer object 0x%08x" - " 0x%08x %d\n", hint, flags, buf->start); - BM_CKFATAL(-EINVAL); - } - -#endif - - if (buf->fence) { - _glthread_UNLOCK_MUTEX(p->mutex); - return -EBUSY; - } - - buf->mapped = TRUE; - *virtual = (unsigned char *) p->virtual + buf->start; - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) -{ - BBuf *buf = (BBuf *) private; - driFenceFinish(buf->fence, 0x0, lazy); - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - - buf->mapped = 0; - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - return p->kernelBO.offset + buf->start; -} - -static unsigned -pool_flags(struct _DriBufferPool *pool, void *private) -{ - BPool *p = (BPool *) pool->data; - - return p->kernelBO.flags; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - BPool *p = (BPool *) pool->data; - - return p->bufSize; -} - - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - if (buf->fence) { - driFenceUnReference(buf->fence); - } - buf->fence = fence; - buf->unfenced = 0; - driFenceReference(buf->fence); - _glthread_UNLOCK_MUTEX(p->mutex); - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - return &p->kernelBO; -} - -static int -pool_validate(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - _glthread_LOCK_MUTEX(p->mutex); - buf->unfenced = TRUE; - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - BPool *p = (BPool *) pool->data; - - /* - * Wait on outstanding fences. - */ - - _glthread_LOCK_MUTEX(p->mutex); - while ((p->numFree < p->numTot) && p->numDelayed) { - _glthread_UNLOCK_MUTEX(p->mutex); - sched_yield(); - pool_checkFree(p, TRUE); - _glthread_LOCK_MUTEX(p->mutex); - } - - drmBODestroy(pool->fd, &p->kernelBO); - free(p->bufs); - _glthread_UNLOCK_MUTEX(p->mutex); - free(p); - free(pool); -} - - -struct _DriBufferPool * -driBatchPoolInit(int fd, unsigned flags, - unsigned long bufSize, - unsigned numBufs, unsigned checkDelayed) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - if (!pool) - return NULL; - - pool->data = createBPool(fd, bufSize, numBufs, flags, checkDelayed); - if (!pool->data) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = &pool_validate; - pool->waitIdle = &pool_waitIdle; - pool->setstatic = NULL; - pool->takeDown = &pool_takedown; - return pool; -} diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.h b/src/gallium/winsys/dri/intel/intel_batchpool.h deleted file mode 100644 index f6a95723bc..0000000000 --- a/src/gallium/winsys/dri/intel/intel_batchpool.h +++ /dev/null @@ -1,37 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_BATCHPOOL_H -#define INTEL_BATCHPOOL_H - -extern struct _DriBufferPool *driBatchPoolInit(int fd, unsigned flags, - unsigned long bufSize, - unsigned numBufs, - unsigned checkDelayed); - - -#endif /* INTEL_BATCHPOOL_H */ diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 8eba33c313..cc2fc11c5e 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -162,6 +162,7 @@ intelCreateContext(const __GLcontextModes * visual, * memory pools */ DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + // ZZZ JB should be per screen and not be done per context havePools = intelCreatePools(sPriv); DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); if (!havePools) @@ -234,12 +235,12 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) if (intel->last_swap_fence) { driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(intel->last_swap_fence); + driFenceUnReference(&intel->last_swap_fence); intel->last_swap_fence = NULL; } if (intel->first_swap_fence) { driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(intel->first_swap_fence); + driFenceUnReference(&intel->first_swap_fence); intel->first_swap_fence = NULL; } diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h index 45430984d8..597dc13830 100644 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -28,7 +28,7 @@ #ifndef INTEL_CONTEXT_H #define INTEL_CONTEXT_H - +#include #include "drm.h" #include "pipe/p_debug.h" diff --git a/src/gallium/winsys/dri/intel/intel_ioctl.c b/src/gallium/winsys/dri/intel/intel_ioctl.c new file mode 100644 index 0000000000..3250c6b3a9 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_ioctl.c @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include +#include +#include +#include + +#include "mtypes.h" +#include "context.h" +#include "swrast/swrast.h" + +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "drm.h" + +#define FILE_DEBUG_FLAG DEBUG_IOCTL + +int +intelEmitIrqLocked(struct intel_context *intel) +{ + drmI830IrqEmit ie; + int ret, seq; + + assert(((*(int *) intel->driHwLock) & ~DRM_LOCK_CONT) == + (DRM_LOCK_HELD | intel->hHWContext)); + + ie.irq_seq = &seq; + + ret = drmCommandWriteRead(intel->driFd, DRM_I830_IRQ_EMIT, + &ie, sizeof(ie)); + if (ret) { + fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); + exit(1); + } + + DBG("%s --> %d\n", __FUNCTION__, seq); + + return seq; +} + +void +intelWaitIrq(struct intel_context *intel, int seq) +{ + int ret; + + DBG("%s %d\n", __FUNCTION__, seq); + + intel->iw.irq_seq = seq; + + do { + ret = + drmCommandWrite(intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, + sizeof(intel->iw)); + } while (ret == -EAGAIN || ret == -EINTR); + + if (ret) { + fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret); + exit(1); + } +} + + +void +intel_batch_ioctl(struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + drmI830BatchBuffer batch; + + assert(intel->locked); + assert(used); + + DBG("%s used %d offset %x..%x ignore_cliprects %d\n", + __FUNCTION__, + used, start_offset, start_offset + used, ignore_cliprects); + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + + + batch.start = start_offset; + batch.used = used; + batch.cliprects = intel->pClipRects; + batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + batch.DR1 = 0; + batch.DR4 = ((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); + + DBG("%s: 0x%x..0x%x DR4: %x cliprects: %d\n", + __FUNCTION__, + batch.start, + batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); + + if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, + sizeof(batch))) { + fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); + UNLOCK_HARDWARE(intel); + exit(1); + } + + /* FIXME: use hardware contexts to avoid 'losing' hardware after + * each buffer flush. + */ + intel->vtbl.lost_hardware(intel); +} diff --git a/src/gallium/winsys/dri/intel/intel_ioctl.h b/src/gallium/winsys/dri/intel/intel_ioctl.h new file mode 100644 index 0000000000..e8d07de893 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_ioctl.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_IOCTL_H +#define INTEL_IOCTL_H + +#include "intel_context.h" + +void intelWaitIrq(struct intel_context *intel, int seq); +int intelEmitIrqLocked(struct intel_context *intel); + +void intel_batch_ioctl(struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock); +#endif diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 9e31c013a9..a3fc6d7344 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -32,12 +32,12 @@ #include "intel_context.h" #include "intel_screen.h" #include "intel_batchbuffer.h" -#include "intel_batchpool.h" +//#include "intel_batchpool.h" #include "intel_swapbuffers.h" #include "intel_winsys.h" #include "i830_dri.h" -#include "dri_bufpool.h" +#include "ws_dri_bufpool.h" #include "pipe/p_context.h" #include "state_tracker/st_public.h" @@ -132,6 +132,7 @@ intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) assert( sarea->front_size >= intelScreen->front.pitch * intelScreen->front.height ); +#if 0 /* JB not important */ if (!sarea->front_handle) return; @@ -142,30 +143,41 @@ intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) fprintf(stderr, "drmMap(frontbuffer) failed!\n"); return; } +#endif +#if 0 /* JB */ if (intelScreen->staticPool) { driGenBuffers(intelScreen->staticPool, "static region", 1, &intelScreen->front.buffer, 64, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - + driBOSetStatic(intelScreen->front.buffer, intelScreen->front.offset, intelScreen->front.pitch * intelScreen->front.height, intelScreen->front.map, 0); } +#else + if (intelScreen->staticPool) { + if (intelScreen->front.buffer) + driBOUnReference(intelScreen->front.buffer); + driGenBuffers(intelScreen->staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle); + } +#endif } boolean intelCreatePools(__DRIscreenPrivate * sPriv) { - unsigned batchPoolSize = 1024*1024; + //unsigned batchPoolSize = 1024*1024; struct intel_screen *intelScreen = intel_screen(sPriv); if (intelScreen->havePools) return GL_TRUE; +#if 0 /* ZZZ JB fix this */ intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); if (!intelScreen->staticPool) return GL_FALSE; @@ -181,7 +193,17 @@ intelCreatePools(__DRIscreenPrivate * sPriv) fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); return GL_FALSE; } - +#else + intelScreen->staticPool = driDRMPoolInit(sPriv->fd); + intelScreen->batchPool = driSlabPoolInit(sPriv->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + 4096, //intelScreen->maxBatchSize, + 1, 40, 16*16384, 0, + intelScreen->fMan); +#endif intelScreen->havePools = GL_TRUE; intelUpdateScreenRotation(sPriv, intelScreen->sarea); @@ -240,7 +262,26 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd); + + +#if 1 // ZZZ JB + intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd); + if (!intelScreen->mgr) { + fprintf(stderr, "Failed to create fence manager.\n"); + return GL_FALSE; + } + + intelScreen->fMan = driInitFreeSlabManager(10, 10); + if (!intelScreen->fMan) { + fprintf(stderr, "Failed to create free slab manager.\n"); + return GL_FALSE; + } + + if (!intelCreatePools(sPriv)) + return GL_FALSE; +#endif + + intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd, intelScreen->fMan); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index 3396f9e564..c17f0202e4 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -31,7 +31,7 @@ #include "dri_util.h" #include "i830_common.h" #include "xmlconfig.h" -#include "dri_bufpool.h" +#include "ws_dri_bufpool.h" #include "pipe/p_compiler.h" @@ -74,6 +74,13 @@ struct intel_screen */ struct intel_context *dummyContext; + /* + * New stuff form the i915tex integration + */ + struct _DriFenceMgr *mgr; + struct _DriFreeSlabManager *fMan; + unsigned batch_id; + struct pipe_winsys *winsys; }; diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 56b86d6a63..1a42389169 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -63,7 +63,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, if (intel->last_swap_fence) { driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); - driFenceUnReference(intel->last_swap_fence); + driFenceUnReference(&intel->last_swap_fence); intel->last_swap_fence = NULL; } intel->last_swap_fence = intel->first_swap_fence; @@ -178,7 +178,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, } if (intel->first_swap_fence) - driFenceUnReference(intel->first_swap_fence); + driFenceUnReference(&intel->first_swap_fence); intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); driFenceReference(intel->first_swap_fence); } diff --git a/src/gallium/winsys/dri/intel/intel_winsys.h b/src/gallium/winsys/dri/intel/intel_winsys.h index ffc40782be..d0a319f9a4 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys.h +++ b/src/gallium/winsys/dri/intel/intel_winsys.h @@ -37,7 +37,7 @@ struct pipe_buffer; struct _DriBufferObject; struct pipe_winsys * -intel_create_pipe_winsys( int fd ); +intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ); void intel_destroy_pipe_winsys( struct pipe_winsys *winsys ); diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index 4d183db7c3..ae3e9654d3 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -31,8 +31,8 @@ #include #include -#include "dri_bufpool.h" -#include "dri_bufmgr.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" #include "intel_context.h" #include "intel_batchbuffer.h" @@ -106,10 +106,18 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws, mask |= DRM_BO_FLAG_READ; } - intel_batchbuffer_emit_reloc( intel->batch, +#if 0 /* JB old */ + intel_batchbuffer_emit_reloc( intel->batch, dri_bo( buf ), - flags, mask, + flags, mask, delta ); +#else /* new */ + intel_offset_relocation( intel->batch, + delta, + dri_bo( buf ), + flags, + mask ); +#endif } @@ -126,8 +134,18 @@ static void intel_i915_batch_flush( struct i915_winsys *sws, fu.dri = intel_batchbuffer_flush( intel->batch ); - if (fu.dri) - iws->pws->fence_reference(iws->pws, fence, fu.pipe); + if (!fu.dri && fence) { + *fence = NULL; + return; + } + + if (fu.dri) { + if (fence) + *fence = fu.pipe; + else + iws->pws->fence_reference(iws->pws, &fu.dri, NULL); + } + // if (0) intel_i915_batch_wait_idle( sws ); } diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 77dec9488d..59729a0245 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -31,8 +31,8 @@ #include #include -#include "dri_bufpool.h" -#include "dri_bufmgr.h" +//#include "dri_bufpool.h" +//#include "dri_bufmgr.h" #include "intel_context.h" #include "intel_winsys.h" @@ -50,6 +50,7 @@ struct intel_pipe_winsys { struct pipe_winsys winsys; struct _DriBufferPool *regionPool; + struct _DriFreeSlabManager *fMan; }; @@ -142,7 +143,7 @@ intel_buffer_create(struct pipe_winsys *winsys, driGenBuffers( iws->regionPool, "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); - driBOData( buffer->driBO, size, NULL, 0 ); + driBOData( buffer->driBO, size, NULL, iws->regionPool, 0 ); return &buffer->base; } @@ -155,7 +156,7 @@ intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); driGenUserBuffer( iws->regionPool, - "pipe user buffer", &buffer->driBO, ptr, bytes); + "pipe user buffer", &buffer->driBO, ptr, bytes ); return &buffer->base; } @@ -209,7 +210,7 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned flags) { const unsigned alignment = 64; - int ret; + //int ret; surf->width = width; surf->height = height; @@ -249,9 +250,37 @@ intel_get_name( struct pipe_winsys *winsys ) return "Intel/DRI/ttm"; } +static void +intel_fence_reference( struct pipe_winsys *sws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence ) +{ + if (*ptr) + driFenceUnReference((struct _DriFenceObject **)ptr); + + if (fence) + *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); +} + +static int +intel_fence_signalled( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceSignaled((struct _DriFenceObject *)fence, flag); +} + +static int +intel_fence_finish( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + /* JB: Lets allways lazy wait */ + return driFenceFinish((struct _DriFenceObject *)fence, flag, 1); +} struct pipe_winsys * -intel_create_pipe_winsys( int fd ) +intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) { struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys ); @@ -273,8 +302,20 @@ intel_create_pipe_winsys( int fd ) iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; iws->winsys.surface_release = intel_i915_surface_release; + iws->winsys.fence_reference = intel_fence_reference; + iws->winsys.fence_signalled = intel_fence_signalled; + iws->winsys.fence_finish = intel_fence_finish; + if (fd) - iws->regionPool = driDRMPoolInit(fd); + iws->regionPool = driSlabPoolInit(fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + 64, 6, 16, 4096, 0, + fMan); return &iws->winsys; } diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h index d4d58886ce..f1fd3939ab 100644 --- a/src/gallium/winsys/dri/intel/server/i830_common.h +++ b/src/gallium/winsys/dri/intel/server/i830_common.h @@ -54,6 +54,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRM_I830_DESTROY_HEAP 0x0c #define DRM_I830_SET_VBLANK_PIPE 0x0d #define DRM_I830_GET_VBLANK_PIPE 0x0e +#define DRM_I830_MMIO 0x10 typedef struct { enum { @@ -85,6 +86,7 @@ typedef struct { int last_enqueue; /* last time a buffer was enqueued */ int last_dispatch; /* age of the most recently dispatched buffer */ int ctxOwner; /* last context to upload state */ + /** Last context that used the buffer manager. */ int texAge; int pf_enabled; /* is pageflipping allowed? */ int pf_active; @@ -121,20 +123,29 @@ typedef struct { unsigned int rotated_tiled; unsigned int rotated2_tiled; - int pipeA_x; - int pipeA_y; - int pipeA_w; - int pipeA_h; - int pipeB_x; - int pipeB_y; - int pipeB_w; - int pipeB_h; + int planeA_x; + int planeA_y; + int planeA_w; + int planeA_h; + int planeB_x; + int planeB_y; + int planeB_w; + int planeB_h; /* Triple buffering */ drm_handle_t third_handle; int third_offset; int third_size; unsigned int third_tiled; + + /* buffer object handles for the static buffers. May change + * over the lifetime of the client, though it doesn't in our current + * implementation. + */ + unsigned int front_bo_handle; + unsigned int back_bo_handle; + unsigned int third_bo_handle; + unsigned int depth_bo_handle; } drmI830Sarea; /* Flags for perf_boxes @@ -223,4 +234,23 @@ typedef struct { int pipe; } drmI830VBlankPipe; +#define MMIO_READ 0 +#define MMIO_WRITE 1 + +#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 +#define MMIO_REGS_IA_VERTICES_COUNT 1 +#define MMIO_REGS_VS_INVOCATION_COUNT 2 +#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 +#define MMIO_REGS_GS_INVOCATION_COUNT 4 +#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 +#define MMIO_REGS_CL_INVOCATION_COUNT 6 +#define MMIO_REGS_PS_INVOCATION_COUNT 7 +#define MMIO_REGS_PS_DEPTH_COUNT 8 + +typedef struct { + unsigned int read_write:1; + unsigned int reg:31; + void __user *data; +} drmI830MMIO; + #endif /* _I830_DRM_H_ */ diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c new file mode 100644 index 0000000000..eb5216cb37 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c @@ -0,0 +1,945 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#include +#include +#include "glthread.h" +#include "errno.h" +#include "ws_dri_bufmgr.h" +#include "string.h" +#include "imports.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + +/* + * This lock is here to protect drmBO structs changing underneath us during a + * validate list call, since validatelist cannot take individiual locks for + * each drmBO. Validatelist takes this lock in write mode. Any access to an + * individual drmBO should take this lock in read mode, since in that case, the + * driBufferObject mutex will protect the access. Locking order is + * driBufferObject mutex - > this rw lock. + */ + +_glthread_DECLARE_STATIC_MUTEX(bmMutex); +_glthread_DECLARE_STATIC_COND(bmCond); + +static int kernelReaders = 0; + +static drmBO *drmBOListBuf(void *iterator) +{ + drmBONode *node; + drmMMListHead *l = (drmMMListHead *) iterator; + node = DRMLISTENTRY(drmBONode, l, head); + return node->buf; +} + +static void *drmBOListIterator(drmBOList *list) +{ + void *ret = list->list.next; + + if (ret == &list->list) + return NULL; + return ret; +} + +static void *drmBOListNext(drmBOList *list, void *iterator) +{ + void *ret; + + drmMMListHead *l = (drmMMListHead *) iterator; + ret = l->next; + if (ret == &list->list) + return NULL; + return ret; +} + +static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, + uint64_t arg0, + uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } + else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADD(&node->head, &list->list); + list->numOnList++; + return node; +} + +static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, + uint64_t mask, int *newItem) +{ + drmBONode *node, *cur; + drmMMListHead *l; + + *newItem = 0; + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + } + if (!cur) { + cur = drmAddListItem(list, buf, flags, mask); + if (!cur) { + return -ENOMEM; + } + *newItem = 1; + cur->arg0 = flags; + cur->arg1 = mask; + } + else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + return 0; +} + +static void drmBOFreeList(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->list.next; + while(l != &list->list) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->list.next; + list->numCurrent--; + list->numOnList--; + } + + l = list->free.next; + while(l != &list->free) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + } +} + +static int drmAdjustListNodes(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + int ret = 0; + + while(list->numCurrent < list->numTarget) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + ret = -ENOMEM; + break; + } + list->numCurrent++; + DRMLISTADD(&node->head, &list->free); + } + + while(list->numCurrent > list->numTarget) { + l = list->free.next; + if (l == &list->free) + break; + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + list->numCurrent--; + } + return ret; +} + +static int drmBOCreateList(int numTarget, drmBOList *list) +{ + DRMINITLISTHEAD(&list->list); + DRMINITLISTHEAD(&list->free); + list->numTarget = numTarget; + list->numCurrent = 0; + list->numOnList = 0; + return drmAdjustListNodes(list); +} + +static int drmBOResetList(drmBOList *list) +{ + drmMMListHead *l; + int ret; + + ret = drmAdjustListNodes(list); + if (ret) + return ret; + + l = list->list.next; + while (l != &list->list) { + DRMLISTDEL(l); + DRMLISTADD(l, &list->free); + list->numOnList--; + l = list->list.next; + } + return drmAdjustListNodes(list); +} + +void driWriteLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + while(kernelReaders != 0) + _glthread_COND_WAIT(bmCond, bmMutex); +} + +void driWriteUnlockKernelBO(void) +{ + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + kernelReaders++; + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadUnlockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + if (--kernelReaders == 0) + _glthread_COND_BROADCAST(bmCond); + _glthread_UNLOCK_MUTEX(bmMutex); +} + + + + +/* + * TODO: Introduce fence pools in the same way as + * buffer object pools. + */ + +typedef struct _DriBufferObject +{ + DriBufferPool *pool; + _glthread_Mutex mutex; + int refCount; + const char *name; + uint64_t flags; + unsigned hint; + unsigned alignment; + unsigned createdByReference; + void *private; + /* user-space buffer: */ + unsigned userBuffer; + void *userData; + unsigned userSize; +} DriBufferObject; + +typedef struct _DriBufferList { + drmBOList drmBuffers; /* List of kernel buffers needing validation */ + drmBOList driBuffers; /* List of user-space buffers needing validation */ +} DriBufferList; + + +void +bmError(int val, const char *file, const char *function, int line) +{ + _mesa_printf("Fatal video memory manager error \"%s\".\n" + "Check kernel logs or set the LIBGL_DEBUG\n" + "environment variable to \"verbose\" for more info.\n" + "Detected in file %s, line %d, function %s.\n", + strerror(-val), file, line, function); +#ifndef NDEBUG + abort(); +#else + abort(); +#endif +} + +extern drmBO * +driBOKernel(struct _DriBufferObject *buf) +{ + drmBO *ret; + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + ret = buf->pool->kernel(buf->pool, buf->private); + if (!ret) + BM_CKFATAL(-EINVAL); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + + return ret; +} + +void +driBOWaitIdle(struct _DriBufferObject *buf, int lazy) +{ + + /* + * This function may block. Is it sane to keep the mutex held during + * that time?? + */ + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void * +driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) +{ + void *virtual; + int retval; + + if (buf->userBuffer) { + return buf->userData; + } + + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + retval = buf->pool->map(buf->pool, buf->private, flags, hint, + &buf->mutex, &virtual); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval == 0 ? virtual : NULL; +} + +void +driBOUnmap(struct _DriBufferObject *buf) +{ + if (buf->userBuffer) + return; + + assert(buf->private != NULL); + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +unsigned long +driBOOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->offset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +unsigned long +driBOPoolOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->poolOffset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +uint64_t +driBOFlags(struct _DriBufferObject *buf) +{ + uint64_t ret; + + assert(buf->private != NULL); + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->flags(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + return ret; +} + +struct _DriBufferObject * +driBOReference(struct _DriBufferObject *buf) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (++buf->refCount == 1) { + _glthread_UNLOCK_MUTEX(buf->mutex); + BM_CKFATAL(-EINVAL); + } + _glthread_UNLOCK_MUTEX(buf->mutex); + return buf; +} + +void +driBOUnReference(struct _DriBufferObject *buf) +{ + int tmp; + + if (!buf) + return; + + + _glthread_LOCK_MUTEX(buf->mutex); + tmp = --buf->refCount; + if (!tmp) { + _glthread_UNLOCK_MUTEX(buf->mutex); + if (buf->private) { + if (buf->createdByReference) + buf->pool->unreference(buf->pool, buf->private); + else + buf->pool->destroy(buf->pool, buf->private); + } + free(buf); + } else + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + + +int +driBOData(struct _DriBufferObject *buf, + unsigned size, const void *data, + DriBufferPool *newPool, + uint64_t flags) +{ + void *virtual = NULL; + int newBuffer; + int retval = 0; + struct _DriBufferPool *pool; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + pool = buf->pool; + + if (pool == NULL && newPool != NULL) { + buf->pool = newPool; + pool = newPool; + } + if (newPool == NULL) + newPool = pool; + + if (!pool->create) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "driBOData called on invalid buffer\n"); + BM_CKFATAL(-EINVAL); + } + + newBuffer = (!buf->private || pool != newPool || + pool->size(pool, buf->private) < size); + + if (!flags) + flags = buf->flags; + + if (newBuffer) { + + if (buf->createdByReference) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "driBOData requiring resizing called on " + "shared buffer.\n"); + BM_CKFATAL(-EINVAL); + } + + if (buf->private) + buf->pool->destroy(buf->pool, buf->private); + + pool = newPool; + buf->pool = newPool; + buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (!buf->private) + retval = -ENOMEM; + + if (retval == 0) + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); + } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { + /* + * Buffer is busy. need to create a new one. + */ + + void *newBuf; + + newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (newBuf) { + buf->pool->destroy(buf->pool, buf->private); + buf->private = newBuf; + } + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } else { + uint64_t flag_diff = flags ^ buf->flags; + + /* + * We might need to change buffer flags. + */ + + if (flag_diff){ + assert(pool->setStatus != NULL); + BM_CKFATAL(pool->unmap(pool, buf->private)); + BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, + buf->flags)); + if (!data) + goto out; + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } + } + + if (retval == 0) { + if (data) + memcpy(virtual, data, size); + + BM_CKFATAL(pool->unmap(pool, buf->private)); + } + + out: + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval; +} + +void +driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, const void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, + &virtual)); + memcpy((unsigned char *) virtual + offset, data, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); + memcpy(data, (unsigned char *) virtual + offset, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->private != NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer for setReferenced\n"); + BM_CKFATAL(-EINVAL); + + } + if (buf->pool->reference == NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer pool for setReferenced\n"); + BM_CKFATAL(-EINVAL); + } + buf->private = buf->pool->reference(buf->pool, handle); + if (!buf->private) { + _mesa_error(NULL, GL_OUT_OF_MEMORY, + "Invalid buffer pool for setStatic\n"); + BM_CKFATAL(-ENOMEM); + } + buf->createdByReference = GL_TRUE; + buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +int +driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint) +{ + struct _DriBufferObject *buf; + int i; + + flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + + assert(pool); + + for (i = 0; i < n; ++i) { + buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); + if (!buf) + return -ENOMEM; + + _glthread_INIT_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(buf->mutex); + buf->refCount = 1; + buf->flags = flags; + buf->hint = hint; + buf->name = name; + buf->alignment = alignment; + buf->pool = pool; + buf->createdByReference = 0; + _glthread_UNLOCK_MUTEX(buf->mutex); + buffers[i] = buf; + } + return 0; +} + +void +driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject **buffers, + void *ptr, unsigned bytes) +{ + const unsigned alignment = 1, flags = 0, hint = 0; + + driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); + + (*buffers)->userBuffer = 1; + (*buffers)->userData = ptr; + (*buffers)->userSize = bytes; +} + +void +driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) +{ + int i; + + for (i = 0; i < n; ++i) { + driBOUnReference(buffers[i]); + } +} + + +void +driInitBufMgr(int fd) +{ + ; +} + +/* + * Note that lists are per-context and don't need mutex protection. + */ + +struct _DriBufferList * +driBOCreateList(int target) +{ + struct _DriBufferList *list = calloc(sizeof(*list), 1); + + BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); + BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); + return list; +} + +int +driBOResetList(struct _DriBufferList * list) +{ + int ret; + ret = drmBOResetList(&list->drmBuffers); + if (ret) + return ret; + ret = drmBOResetList(&list->driBuffers); + return ret; +} + +void +driBOFreeList(struct _DriBufferList * list) +{ + drmBOFreeList(&list->drmBuffers); + drmBOFreeList(&list->driBuffers); + free(list); +} + + +/* + * Copied from libdrm, because it is needed by driAddValidateItem. + */ + +static drmBONode * +driAddListItem(drmBOList * list, drmBO * item, + uint64_t arg0, uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + memset(&node->bo_arg, 0, sizeof(node->bo_arg)); + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADDTAIL(&node->head, &list->list); + list->numOnList++; + return node; +} + +/* + * Slightly modified version compared to the libdrm version. + * This one returns the list index of the buffer put on the list. + */ + +static int +driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, + uint64_t mask, int *itemLoc, + struct _drmBONode **pnode) +{ + drmBONode *node, *cur; + drmMMListHead *l; + int count = 0; + + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + count++; + } + if (!cur) { + cur = driAddListItem(list, buf, flags, mask); + if (!cur) + return -ENOMEM; + + cur->arg0 = flags; + cur->arg1 = mask; + } else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + *itemLoc = count; + *pnode = cur; + return 0; +} + + +void +driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node) +{ + int newItem; + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(driAddValidateItem(&list->drmBuffers, + buf->pool->kernel(buf->pool, buf->private), + flags, mask, itemLoc, node)); + BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, + flags, mask, &newItem)); + if (newItem) + buf->refCount++; + + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +drmBOList *driGetdrmBOList(struct _DriBufferList *list) +{ + driWriteLockKernelBO(); + return &list->drmBuffers; +} + +void driPutdrmBOList(struct _DriBufferList *list) +{ + driWriteUnlockKernelBO(); +} + + +void +driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->fence) + BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + +void +driBOUnrefUserList(struct _DriBufferList *list) +{ + struct _DriBufferObject *buf; + void *curBuf; + + curBuf = drmBOListIterator(&list->driBuffers); + while (curBuf) { + buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + +struct _DriFenceObject * +driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, const char *name, + drmFence *kFence) +{ + struct _DriFenceObject *fence; + struct _DriBufferObject *buf; + void *curBuf; + + fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, + kFence, sizeof(*kFence)); + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space fencing callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + driBOFence(buf, fence); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } + + driBOResetList(list); + return fence; +} + +void +driBOValidateUserList(struct _DriBufferList * list) +{ + void *curBuf; + struct _DriBufferObject *buf; + + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space validation callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->validate) + BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); + _glthread_UNLOCK_MUTEX(buf->mutex); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + + +void +driPoolTakeDown(struct _DriBufferPool *pool) +{ + pool->takeDown(pool); + +} + +unsigned long +driBOSize(struct _DriBufferObject *buf) +{ + unsigned long size; + + _glthread_LOCK_MUTEX(buf->mutex); + size = buf->pool->size(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return size; + +} + +drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) +{ + return &list->drmBuffers; +} + +drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) +{ + return &list->driBuffers; +} + diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h new file mode 100644 index 0000000000..fdaf5ee93a --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#ifndef _PSB_BUFMGR_H_ +#define _PSB_BUFMGR_H_ +#include +#include "i915_drm.h" +#include "ws_dri_fencemgr.h" + +typedef struct _drmBONode +{ + drmMMListHead head; + drmBO *buf; + struct drm_i915_op_arg bo_arg; + uint64_t arg0; + uint64_t arg1; +} drmBONode; + +typedef struct _drmBOList { + unsigned numTarget; + unsigned numCurrent; + unsigned numOnList; + drmMMListHead list; + drmMMListHead free; +} drmBOList; + + +struct _DriFenceObject; +struct _DriBufferObject; +struct _DriBufferPool; +struct _DriBufferList; + +/* + * Return a pointer to the libdrm buffer object this DriBufferObject + * uses. + */ + +extern drmBO *driBOKernel(struct _DriBufferObject *buf); +extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, + unsigned hint); +extern void driBOUnmap(struct _DriBufferObject *buf); +extern unsigned long driBOOffset(struct _DriBufferObject *buf); +extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); + +extern uint64_t driBOFlags(struct _DriBufferObject *buf); +extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); +extern void driBOUnReference(struct _DriBufferObject *buf); + +extern int driBOData(struct _DriBufferObject *r_buf, + unsigned size, const void *data, + struct _DriBufferPool *pool, uint64_t flags); + +extern void driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + const void *data); +extern void driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + void *data); +extern int driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint); +extern void driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject *buffers[], + void *ptr, unsigned bytes); +extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); +extern void driInitBufMgr(int fd); +extern struct _DriBufferList *driBOCreateList(int target); +extern int driBOResetList(struct _DriBufferList * list); +extern void driBOAddListItem(struct _DriBufferList * list, + struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node); + +extern void driBOValidateList(int fd, struct _DriBufferList * list); +extern void driBOFreeList(struct _DriBufferList * list); +extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, + const char *name, + drmFence *kFence); +extern void driBOUnrefUserList(struct _DriBufferList *list); +extern void driBOValidateUserList(struct _DriBufferList * list); +extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); +extern void driPutdrmBOList(struct _DriBufferList *list); + +extern void driBOFence(struct _DriBufferObject *buf, + struct _DriFenceObject *fence); + +extern void driPoolTakeDown(struct _DriBufferPool *pool); +extern void driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle); +unsigned long driBOSize(struct _DriBufferObject *buf); +extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); +extern void driPoolTakeDown(struct _DriBufferPool *pool); + +extern void driReadLockKernelBO(void); +extern void driReadUnlockKernelBO(void); +extern void driWriteLockKernelBO(void); +extern void driWriteUnlockKernelBO(void); + +/* + * For debugging purposes. + */ + +extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); +extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); +#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufpool.h b/src/gallium/winsys/dri/intel/ws_dri_bufpool.h new file mode 100644 index 0000000000..3a302e13d3 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_bufpool.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#ifndef _PSB_BUFPOOL_H_ +#define _PSB_BUFPOOL_H_ + +#include +#include +struct _DriFenceObject; + +typedef struct _DriBufferPool +{ + int fd; + int (*map) (struct _DriBufferPool * pool, void *private, + unsigned flags, int hint, _glthread_Mutex *mutex, + void **virtual); + int (*unmap) (struct _DriBufferPool * pool, void *private); + int (*destroy) (struct _DriBufferPool * pool, void *private); + unsigned long (*offset) (struct _DriBufferPool * pool, void *private); + unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); + uint64_t (*flags) (struct _DriBufferPool * pool, void *private); + unsigned long (*size) (struct _DriBufferPool * pool, void *private); + void *(*create) (struct _DriBufferPool * pool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment); + void *(*reference) (struct _DriBufferPool * pool, unsigned handle); + int (*unreference) (struct _DriBufferPool * pool, void *private); + int (*fence) (struct _DriBufferPool * pool, void *private, + struct _DriFenceObject * fence); + drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); + int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy); + int (*setStatus) (struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags); + void (*takeDown) (struct _DriBufferPool * pool); + void *data; +} DriBufferPool; + +extern void bmError(int val, const char *file, const char *function, + int line); +#define BM_CKFATAL(val) \ + do{ \ + int tstVal = (val); \ + if (tstVal) \ + bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ + } while(0); + + +/* + * Builtin pools. + */ + +/* + * Kernel buffer objects. Size in multiples of page size. Page size aligned. + */ + +extern struct _DriBufferPool *driDRMPoolInit(int fd); +extern struct _DriBufferPool *driMallocPoolInit(void); + +struct _DriFreeSlabManager; +extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan); +extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); +extern struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); + + +#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_drmpool.c b/src/gallium/winsys/dri/intel/ws_dri_drmpool.c new file mode 100644 index 0000000000..7c55dbc674 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_drmpool.c @@ -0,0 +1,268 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "assert.h" + +/* + * Buffer pool implementation using DRM buffer objects as DRI buffer objects. + */ + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + unsigned pageSize = getpagesize(); + + if (!buf) + return NULL; + + if ((alignment > pageSize) && (alignment % pageSize)) { + free(buf); + return NULL; + } + + ret = drmBOCreate(pool->fd, size, alignment / pageSize, + NULL, + flags, hint, buf); + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static void * +pool_reference(struct _DriBufferPool *pool, unsigned handle) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + + if (!buf) + return NULL; + + ret = drmBOReference(pool->fd, handle, buf); + + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unreference(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOMap(pool->fd, buf, flags, hint, virtual); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOUnmap(pool->fd, buf); + driReadUnlockKernelBO(); + + return ret; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long offset; + + driReadLockKernelBO(); + assert(buf->flags & DRM_BO_FLAG_NO_MOVE); + offset = buf->offset; + driReadUnlockKernelBO(); + + return buf->offset; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + uint64_t flags; + + driReadLockKernelBO(); + flags = buf->flags; + driReadUnlockKernelBO(); + + return flags; +} + + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long size; + + driReadLockKernelBO(); + size = buf->size; + driReadUnlockKernelBO(); + + return buf->size; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + /* + * Noop. The kernel handles all fencing. + */ + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + return (drmBO *) private; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); + driReadUnlockKernelBO(); + + return ret; +} + + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + +/*static int +pool_setStatus(struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags) +{ + drmBO *buf = (drmBO *) private; + uint64_t new_flags = old_flags ^ flag_diff; + int ret; + + driReadLockKernelBO(); + ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, + 0, 0, 0); + driReadUnlockKernelBO(); + return ret; +}*/ + +struct _DriBufferPool * +driDRMPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->reference = &pool_reference; + pool->unreference = &pool_unreference; + pool->data = NULL; + return pool; +} diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c new file mode 100644 index 0000000000..8aaef1c620 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c @@ -0,0 +1,372 @@ +#include "ws_dri_fencemgr.h" +#include "glthread.h" +#include +#include +#include + +/* + * Note: Locking order is + * _DriFenceObject::mutex + * _DriFenceMgr::mutex + */ + +struct _DriFenceMgr { + /* + * Constant members. Need no mutex protection. + */ + struct _DriFenceMgrCreateInfo info; + void *private; + + /* + * These members are protected by this->mutex + */ + _glthread_Mutex mutex; + int refCount; + drmMMListHead *heads; +}; + +struct _DriFenceObject { + + /* + * These members are constant and need no mutex protection. + */ + struct _DriFenceMgr *mgr; + uint32_t fence_class; + uint32_t fence_type; + + /* + * These members are protected by mgr->mutex. + */ + drmMMListHead head; + int refCount; + + /* + * These members are protected by this->mutex. + */ + _glthread_Mutex mutex; + uint32_t signaled_type; + void *private; +}; + +uint32_t +driFenceType(struct _DriFenceObject *fence) +{ + return fence->fence_type; +} + +struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) +{ + struct _DriFenceMgr *tmp; + uint32_t i; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->refCount = 1; + tmp->info = *info; + tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); + if (!tmp->heads) + goto out_err; + + for (i=0; iinfo.num_classes; ++i) { + DRMINITLISTHEAD(&tmp->heads[i]); + } + _glthread_UNLOCK_MUTEX(tmp->mutex); + return tmp; + + out_err: + if (tmp) + free(tmp); + return NULL; +} + +static void +driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) +{ + struct _DriFenceMgr *mgr = *pMgr; + + *pMgr = NULL; + if (--mgr->refCount == 0) + free(mgr); + else + _glthread_UNLOCK_MUTEX(mgr->mutex); +} + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr) +{ + _glthread_LOCK_MUTEX((*pMgr)->mutex); + driFenceMgrUnrefUnlock(pMgr); +} + +static void +driFenceUnReferenceLocked(struct _DriFenceObject **pFence) +{ + struct _DriFenceObject *fence = *pFence; + struct _DriFenceMgr *mgr = fence->mgr; + + *pFence = NULL; + if (--fence->refCount == 0) { + DRMLISTDELINIT(&fence->head); + if (fence->private) + mgr->info.unreference(mgr, &fence->private); + fence->mgr = NULL; + --mgr->refCount; + free(fence); + } +} + + +static void +driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, + drmMMListHead *list, + uint32_t fence_class, + uint32_t fence_type) +{ + struct _DriFenceObject *entry; + drmMMListHead *prev; + + while(list != &mgr->heads[fence_class]) { + entry = DRMLISTENTRY(struct _DriFenceObject, list, head); + + /* + * Up refcount so that entry doesn't disappear from under us + * when we unlock-relock mgr to get the correct locking order. + */ + + ++entry->refCount; + _glthread_UNLOCK_MUTEX(mgr->mutex); + _glthread_LOCK_MUTEX(entry->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + + prev = list->prev; + + + + if (list->prev == list) { + + /* + * Somebody else removed the entry from the list. + */ + + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + return; + } + + entry->signaled_type |= (fence_type & entry->fence_type); + if (entry->signaled_type == entry->fence_type) { + DRMLISTDELINIT(list); + mgr->info.unreference(mgr, &entry->private); + } + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + list = prev; + } +} + + +int +driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint) +{ + struct _DriFenceMgr *mgr = fence->mgr; + int ret = 0; + + _glthread_LOCK_MUTEX(fence->mutex); + + if ((fence->signaled_type & fence_type) == fence_type) + goto out0; + + ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); + if (ret) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + fence_type); + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) +{ + uint32_t ret; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = fence->signaled_type; + _glthread_UNLOCK_MUTEX(fence->mutex); + + return ret; +} + +int +driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, + uint32_t *signaled) +{ + int ret = 0; + struct _DriFenceMgr *mgr; + + _glthread_LOCK_MUTEX(fence->mutex); + mgr = fence->mgr; + *signaled = fence->signaled_type; + if ((fence->signaled_type & flush_type) == flush_type) + goto out0; + + ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); + if (ret) { + *signaled = fence->signaled_type; + goto out0; + } + + if ((fence->signaled_type | *signaled) == fence->signaled_type) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + *signaled); + + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +struct _DriFenceObject * +driFenceReference(struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(fence->mgr->mutex); + ++fence->refCount; + _glthread_UNLOCK_MUTEX(fence->mgr->mutex); + return fence; +} + +void +driFenceUnReference(struct _DriFenceObject **pFence) +{ + struct _DriFenceMgr *mgr; + + if (*pFence == NULL) + return; + + mgr = (*pFence)->mgr; + _glthread_LOCK_MUTEX(mgr->mutex); + ++mgr->refCount; + driFenceUnReferenceLocked(pFence); + driFenceMgrUnrefUnlock(&mgr); +} + +struct _DriFenceObject +*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, + uint32_t fence_type, void *private, size_t private_size) +{ + struct _DriFenceObject *fence; + size_t fence_size = sizeof(*fence); + + if (private_size) + fence_size = ((fence_size + 15) & ~15); + + fence = calloc(1, fence_size + private_size); + + if (!fence) { + int ret = mgr->info.finish(mgr, private, fence_type, 0); + + if (ret) + usleep(10000000); + + return NULL; + } + + _glthread_INIT_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + fence->refCount = 1; + DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); + fence->mgr = mgr; + ++mgr->refCount; + _glthread_UNLOCK_MUTEX(mgr->mutex); + fence->fence_class = fence_class; + fence->fence_type = fence_type; + fence->signaled_type = 0; + fence->private = private; + if (private_size) { + fence->private = (void *)(((uint8_t *) fence) + fence_size); + memcpy(fence->private, private, private_size); + } + + _glthread_UNLOCK_MUTEX(fence->mutex); + return fence; +} + + +static int +tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type) +{ + long fd = (long) mgr->private; + int dummy; + drmFence *fence = (drmFence *) private; + int ret; + + *signaled_type = 0; + ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); + if (ret) + return ret; + + *signaled_type = fence->signaled; + + return 0; +} + +static int +tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, + int lazy_hint) +{ + long fd = (long) mgr->private; + unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; + + return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); +} + +static int +tUnref(struct _DriFenceMgr *mgr, void **private) +{ + long fd = (long) mgr->private; + drmFence *fence = (drmFence *) *private; + *private = NULL; + + return drmFenceUnreference(fd, fence); +} + +struct _DriFenceMgr *driFenceMgrTTMInit(int fd) +{ + struct _DriFenceMgrCreateInfo info; + struct _DriFenceMgr *mgr; + + info.flags = DRI_FENCE_CLASS_ORDERED; + info.num_classes = 4; + info.signaled = tSignaled; + info.finish = tFinish; + info.unreference = tUnref; + + mgr = driFenceMgrCreate(&info); + if (mgr == NULL) + return NULL; + + mgr->private = (void *) (long) fd; + return mgr; +} + diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h new file mode 100644 index 0000000000..4ea58dfe18 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h @@ -0,0 +1,115 @@ +#ifndef DRI_FENCEMGR_H +#define DRI_FENCEMGR_H + +#include +#include + +struct _DriFenceObject; +struct _DriFenceMgr; + +/* + * Do a quick check to see if the fence manager has registered the fence + * object as signaled. Note that this function may return a false negative + * answer. + */ +extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); + +/* + * Check if the fence object is signaled. This function can be substantially + * more expensive to call than the above function, but will not return a false + * negative answer. The argument "flush_type" sets the types that the + * underlying mechanism must make sure will eventually signal. + */ +extern int driFenceSignaledType(struct _DriFenceObject *fence, + uint32_t flush_type, uint32_t *signaled); + +/* + * Convenience functions. + */ + +static inline int driFenceSignaled(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types; + int ret = driFenceSignaledType(fence, flush_type, &signaled_types); + if (ret) + return 0; + return ((signaled_types & flush_type) == flush_type); +} + +static inline int driFenceSignaledCached(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types = + driFenceSignaledTypeCached(fence); + + return ((signaled_types & flush_type) == flush_type); +} + +/* + * Reference a fence object. + */ +extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); + +/* + * Unreference a fence object. The fence object pointer will be reset to NULL. + */ + +extern void driFenceUnReference(struct _DriFenceObject **pFence); + + +/* + * Wait for a fence to signal the indicated fence_type. + * If "lazy_hint" is true, it indicates that the wait may sleep to avoid + * busy-wait polling. + */ +extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint); + +/* + * Create a DriFenceObject for manager "mgr". + * + * "private" is a pointer that should be used for the callbacks in + * struct _DriFenceMgrCreateInfo. + * + * if private_size is nonzero, then the info stored at *private, with size + * private size will be copied and the fence manager will instead use a + * pointer to the copied data for the callbacks in + * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by + * "private" may be destroyed after the call to driFenceCreate. + */ +extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, + uint32_t fence_class, + uint32_t fence_type, + void *private, + size_t private_size); + +extern uint32_t driFenceType(struct _DriFenceObject *fence); + +/* + * Fence creations are ordered. If a fence signals a fence_type, + * it is safe to assume that all fences of the same class that was + * created before that fence has signaled the same type. + */ + +#define DRI_FENCE_CLASS_ORDERED (1 << 0) + +struct _DriFenceMgrCreateInfo { + uint32_t flags; + uint32_t num_classes; + int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type); + int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); + int (*unreference) (struct _DriFenceMgr *mgr, void **private); +}; + +extern struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr); + +extern struct _DriFenceMgr * +driFenceMgrTTMInit(int fd); + +#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c b/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c new file mode 100644 index 0000000000..bf97d7e440 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c @@ -0,0 +1,162 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "imports.h" +#include "glthread.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "intel_screen.h" + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + unsigned long *private = malloc(size + 2*sizeof(unsigned long)); + if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) + abort(); + + *private = size; + return (void *)private; +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + free(private); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + *virtual = (void *)((unsigned long *)private + 2); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); + return 0UL; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + return *(unsigned long *) private; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + abort(); + return 0UL; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + abort(); + return NULL; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + + +struct _DriBufferPool * +driMallocPoolInit(void) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = NULL; + pool->fd = -1; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/gallium/winsys/dri/intel/ws_dri_slabpool.c b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c new file mode 100644 index 0000000000..235f0ac972 --- /dev/null +++ b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c @@ -0,0 +1,945 @@ +/************************************************************************** + * + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include +#include +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" +#include "ws_dri_bufmgr.h" +#include "glthread.h" + +#define DRI_SLABPOOL_ALLOC_RETRIES 100 + +struct _DriSlab; + +struct _DriSlabBuffer { + int isSlabBuffer; + drmBO *bo; + struct _DriFenceObject *fence; + struct _DriSlab *parent; + drmMMListHead head; + uint32_t mapCount; + uint32_t start; + uint32_t fenceType; + int unFenced; + _glthread_Cond event; +}; + +struct _DriKernelBO { + int fd; + drmBO bo; + drmMMListHead timeoutHead; + drmMMListHead head; + struct timeval timeFreed; + uint32_t pageAlignment; + void *virtual; +}; + +struct _DriSlab{ + drmMMListHead head; + drmMMListHead freeBuffers; + uint32_t numBuffers; + uint32_t numFree; + struct _DriSlabBuffer *buffers; + struct _DriSlabSizeHeader *header; + struct _DriKernelBO *kbo; +}; + + +struct _DriSlabSizeHeader { + drmMMListHead slabs; + drmMMListHead freeSlabs; + drmMMListHead delayedBuffers; + uint32_t numDelayed; + struct _DriSlabPool *slabPool; + uint32_t bufSize; + _glthread_Mutex mutex; +}; + +struct _DriFreeSlabManager { + struct timeval slabTimeout; + struct timeval checkInterval; + struct timeval nextCheck; + drmMMListHead timeoutList; + drmMMListHead unCached; + drmMMListHead cached; + _glthread_Mutex mutex; +}; + + +struct _DriSlabPool { + + /* + * The data of this structure remains constant after + * initialization and thus needs no mutex protection. + */ + + struct _DriFreeSlabManager *fMan; + uint64_t proposedFlags; + uint64_t validMask; + uint32_t *bucketSizes; + uint32_t numBuckets; + uint32_t pageSize; + int fd; + int pageAlignment; + int maxSlabSize; + int desiredNumBuffers; + struct _DriSlabSizeHeader *headers; +}; + +/* + * FIXME: Perhaps arrange timeout slabs in size buckets for fast + * retreival?? + */ + + +static inline int +driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) +{ + return ((arg1->tv_sec > arg2->tv_sec) || + ((arg1->tv_sec == arg2->tv_sec) && + (arg1->tv_usec > arg2->tv_usec))); +} + +static inline void +driTimeAdd(struct timeval *arg, struct timeval *add) +{ + unsigned int sec; + + arg->tv_sec += add->tv_sec; + arg->tv_usec += add->tv_usec; + sec = arg->tv_usec / 1000000; + arg->tv_sec += sec; + arg->tv_usec -= sec*1000000; +} + +static void +driFreeKernelBO(struct _DriKernelBO *kbo) +{ + if (!kbo) + return; + + (void) drmBOUnreference(kbo->fd, &kbo->bo); + free(kbo); +} + + +static void +driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, + struct timeval *time) +{ + drmMMListHead *list, *next; + struct _DriKernelBO *kbo; + + if (!driTimeAfterEq(time, &fMan->nextCheck)) + return; + + for (list = fMan->timeoutList.next, next = list->next; + list != &fMan->timeoutList; + list = next, next = list->next) { + + kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); + + if (!driTimeAfterEq(time, &kbo->timeFreed)) + break; + + DRMLISTDELINIT(&kbo->timeoutHead); + DRMLISTDELINIT(&kbo->head); + driFreeKernelBO(kbo); + } + + fMan->nextCheck = *time; + driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); +} + + +/* + * Add a _DriKernelBO to the free slab manager. + * This means that it is available for reuse, but if it's not + * reused in a while, it will be freed. + */ + +static void +driSetKernelBOFree(struct _DriFreeSlabManager *fMan, + struct _DriKernelBO *kbo) +{ + struct timeval time; + + _glthread_LOCK_MUTEX(fMan->mutex); + gettimeofday(&time, NULL); + driTimeAdd(&time, &fMan->slabTimeout); + + kbo->timeFreed = time; + + if (kbo->bo.flags & DRM_BO_FLAG_CACHED) + DRMLISTADD(&kbo->head, &fMan->cached); + else + DRMLISTADD(&kbo->head, &fMan->unCached); + + DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); + driFreeTimeoutKBOsLocked(fMan, &time); + + _glthread_UNLOCK_MUTEX(fMan->mutex); +} + +/* + * Get a _DriKernelBO for us to use as storage for a slab. + * + */ + +static struct _DriKernelBO * +driAllocKernelBO(struct _DriSlabSizeHeader *header) + +{ + struct _DriSlabPool *slabPool = header->slabPool; + struct _DriFreeSlabManager *fMan = slabPool->fMan; + drmMMListHead *list, *next, *head; + uint32_t size = header->bufSize * slabPool->desiredNumBuffers; + struct _DriKernelBO *kbo; + int ret; + + /* + * FIXME: We should perhaps allow some variation in slabsize in order + * to efficiently reuse slabs. + */ + + size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; + size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); + _glthread_LOCK_MUTEX(fMan->mutex); + + kbo = NULL; + + retry: + head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? + &fMan->cached : &fMan->unCached; + + for (list = head->next, next = list->next; + list != head; + list = next, next = list->next) { + + kbo = DRMLISTENTRY(struct _DriKernelBO, list, head); + + if ((kbo->bo.size == size) && + (slabPool->pageAlignment == 0 || + (kbo->pageAlignment % slabPool->pageAlignment) == 0)) { + + DRMLISTDELINIT(&kbo->head); + DRMLISTDELINIT(&kbo->timeoutHead); + break; + } + + kbo = NULL; + } + + _glthread_UNLOCK_MUTEX(fMan->mutex); + + if (kbo) { + ret = 0; + ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, + (slabPool->proposedFlags ^ kbo->bo.flags), + DRM_BO_HINT_DONT_FENCE, 0, 0); + if (ret == 0) + return kbo; + + driFreeKernelBO(kbo); + kbo = NULL; + goto retry; + } + + kbo = calloc(1, sizeof(struct _DriKernelBO)); + if (!kbo) + return NULL; + + kbo->fd = slabPool->fd; + DRMINITLISTHEAD(&kbo->head); + DRMINITLISTHEAD(&kbo->timeoutHead); + + ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, + slabPool->proposedFlags, + DRM_BO_HINT_DONT_FENCE, &kbo->bo); + if (ret) + goto out_err0; + + ret = drmBOMap(kbo->fd, &kbo->bo, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &kbo->virtual); + + if (ret) + goto out_err1; + + ret = drmBOUnmap(kbo->fd, &kbo->bo); + if (ret) + goto out_err1; + + return kbo; + + out_err1: + drmBOUnreference(kbo->fd, &kbo->bo); + out_err0: + free(kbo); + return NULL; +} + + +static int +driAllocSlab(struct _DriSlabSizeHeader *header) +{ + struct _DriSlab *slab; + struct _DriSlabBuffer *buf; + uint32_t numBuffers; + int ret; + int i; + + slab = calloc(1, sizeof(*slab)); + if (!slab) + return -ENOMEM; + + slab->kbo = driAllocKernelBO(header); + if (!slab->kbo) { + ret = -ENOMEM; + goto out_err0; + } + + numBuffers = slab->kbo->bo.size / header->bufSize; + + slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); + if (!slab->buffers) { + ret = -ENOMEM; + goto out_err1; + } + + DRMINITLISTHEAD(&slab->head); + DRMINITLISTHEAD(&slab->freeBuffers); + slab->numBuffers = numBuffers; + slab->numFree = 0; + slab->header = header; + + buf = slab->buffers; + for (i=0; i < numBuffers; ++i) { + buf->parent = slab; + buf->start = i* header->bufSize; + buf->mapCount = 0; + buf->isSlabBuffer = 1; + _glthread_INIT_COND(buf->event); + DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); + slab->numFree++; + buf++; + } + + DRMLISTADDTAIL(&slab->head, &header->slabs); + + return 0; + + out_err1: + driSetKernelBOFree(header->slabPool->fMan, slab->kbo); + free(slab->buffers); + out_err0: + free(slab); + return ret; +} + +/* + * Delete a buffer from the slab header delayed list and put + * it on the slab free list. + */ + +static void +driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) +{ + struct _DriSlab *slab = buf->parent; + struct _DriSlabSizeHeader *header = slab->header; + drmMMListHead *list = &buf->head; + + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &slab->freeBuffers); + slab->numFree++; + + if (slab->head.next == &slab->head) + DRMLISTADDTAIL(&slab->head, &header->slabs); + + if (slab->numFree == slab->numBuffers) { + list = &slab->head; + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &header->freeSlabs); + } + + if (header->slabs.next == &header->slabs || + slab->numFree != slab->numBuffers) { + + drmMMListHead *next; + struct _DriFreeSlabManager *fMan = header->slabPool->fMan; + + for (list = header->freeSlabs.next, next = list->next; + list != &header->freeSlabs; + list = next, next = list->next) { + + slab = DRMLISTENTRY(struct _DriSlab, list, head); + + DRMLISTDELINIT(list); + driSetKernelBOFree(fMan, slab->kbo); + free(slab->buffers); + free(slab); + } + } +} + +static void +driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) +{ + drmMMListHead *list, *prev; + struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + + int signaled = 0; + int i; + int ret; + + list = header->delayedBuffers.next; + + /* Only examine the oldest 1/3 of delayed buffers: + */ + if (header->numDelayed > 3) { + for (i = 0; i < header->numDelayed; i += 3) { + list = list->next; + } + } + + prev = list->prev; + for (; list != &header->delayedBuffers; list = prev, prev = list->prev) { + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + slab = buf->parent; + + if (!signaled) { + if (wait) { + ret = driFenceFinish(buf->fence, buf->fenceType, 0); + if (ret) + break; + signaled = 1; + } else { + signaled = driFenceSignaled(buf->fence, buf->fenceType); + } + if (signaled) { + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } +} + + +static struct _DriSlabBuffer * +driSlabAllocBuffer(struct _DriSlabSizeHeader *header) +{ + static struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + drmMMListHead *list; + int count = DRI_SLABPOOL_ALLOC_RETRIES; + + _glthread_LOCK_MUTEX(header->mutex); + while(header->slabs.next == &header->slabs && count > 0) { + driSlabCheckFreeLocked(header, 0); + if (header->slabs.next != &header->slabs) + break; + + _glthread_UNLOCK_MUTEX(header->mutex); + if (count != DRI_SLABPOOL_ALLOC_RETRIES) + usleep(1); + (void) driAllocSlab(header); + _glthread_LOCK_MUTEX(header->mutex); + count--; + } + + list = header->slabs.next; + if (list == &header->slabs) { + _glthread_UNLOCK_MUTEX(header->mutex); + //assert(0, "no buffers in slab"); + return NULL; + } + slab = DRMLISTENTRY(struct _DriSlab, list, head); + if (--slab->numFree == 0) + DRMLISTDELINIT(list); + + list = slab->freeBuffers.next; + DRMLISTDELINIT(list); + + _glthread_UNLOCK_MUTEX(header->mutex); + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + return buf; +} + +static void * +pool_create(struct _DriBufferPool *driPool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment) +{ + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + struct _DriSlabSizeHeader *header; + struct _DriSlabBuffer *buf; + void *dummy; + int i; + int ret; + + + /* + * FIXME: Check for compatibility. + */ + + header = pool->headers; + for (i=0; inumBuckets; ++i) { + if (header->bufSize >= size) + break; + header++; + } + + if (i < pool->numBuckets) + return driSlabAllocBuffer(header); + + + /* + * Fall back to allocate a buffer object directly from DRM. + * and wrap it in a driBO structure. + */ + + + buf = calloc(1, sizeof(*buf)); + + if (!buf) + return NULL; + + buf->bo = calloc(1, sizeof(*buf->bo)); + if (!buf->bo) + goto out_err0; + + if (alignment) { + if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) + goto out_err1; + if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) + goto out_err1; + } + + ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, + flags, hint, buf->bo); + if (ret) + goto out_err1; + + ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &dummy); + if (ret) + goto out_err2; + + ret = drmBOUnmap(pool->fd, buf->bo); + if (ret) + goto out_err2; + + return buf; + out_err2: + drmBOUnreference(pool->fd, buf->bo); + out_err1: + free(buf->bo); + out_err0: + free(buf); + return NULL; +} + +static int +pool_destroy(struct _DriBufferPool *driPool, void *private) +{ + struct _DriSlabBuffer *buf = + (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + int ret; + + ret = drmBOUnreference(pool->fd, buf->bo); + free(buf->bo); + free(buf); + return ret; + } + + slab = buf->parent; + header = slab->header; + + _glthread_LOCK_MUTEX(header->mutex); + buf->unFenced = 0; + buf->mapCount = 0; + + if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { + DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); + header->numDelayed++; + } else { + driSlabFreeBufferLocked(buf); + } + + _glthread_UNLOCK_MUTEX(header->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *driPool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + while(buf->unFenced) + _glthread_COND_WAIT(buf->event, *mutex); + + if (!buf->fence) + return 0; + + driFenceFinish(buf->fence, buf->fenceType, lazy); + driFenceUnReference(&buf->fence); + + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + int busy; + + if (buf->isSlabBuffer) + busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); + else + busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); + + + if (busy) { + if (hint & DRM_BO_HINT_DONT_BLOCK) + return -EBUSY; + else { + (void) pool_waitIdle(pool, private, mutex, 0); + } + } + + ++buf->mapCount; + *virtual = (buf->isSlabBuffer) ? + (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : + (void *) buf->bo->virtual; + + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + --buf->mapCount; + if (buf->mapCount == 0 && buf->isSlabBuffer) + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return buf->bo->offset; + } + + slab = buf->parent; + header = slab->header; + + (void) header; + assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return slab->kbo->bo.offset + buf->start; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return buf->start; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return buf->bo->flags; + + return buf->parent->kbo->bo.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + if (!buf->isSlabBuffer) + return buf->bo->size; + + return buf->parent->header->bufSize; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + drmBO *bo; + + if (buf->fence) + driFenceUnReference(&buf->fence); + + buf->fence = driFenceReference(fence); + bo = (buf->isSlabBuffer) ? + &buf->parent->kbo->bo: + buf->bo; + buf->fenceType = bo->fenceFlags; + + buf->unFenced = 0; + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return 0; + + while(buf->mapCount != 0) + _glthread_COND_WAIT(buf->event, *mutex); + + buf->unFenced = 1; + return 0; +} + + +struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) +{ + struct _DriFreeSlabManager *tmp; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; + tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; + tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; + + tmp->checkInterval.tv_usec = checkIntervalMsec*1000; + tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; + tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; + + gettimeofday(&tmp->nextCheck, NULL); + driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); + DRMINITLISTHEAD(&tmp->timeoutList); + DRMINITLISTHEAD(&tmp->unCached); + DRMINITLISTHEAD(&tmp->cached); + _glthread_UNLOCK_MUTEX(tmp->mutex); + + return tmp; +} + +void +driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) +{ + struct timeval time; + + time = fMan->nextCheck; + driTimeAdd(&time, &fMan->checkInterval); + + _glthread_LOCK_MUTEX(fMan->mutex); + driFreeTimeoutKBOsLocked(fMan, &time); + _glthread_UNLOCK_MUTEX(fMan->mutex); + + assert(fMan->timeoutList.next == &fMan->timeoutList); + assert(fMan->unCached.next == &fMan->unCached); + assert(fMan->cached.next == &fMan->cached); + + free(fMan); +} + +static void +driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, + struct _DriSlabSizeHeader *header) +{ + _glthread_INIT_MUTEX(header->mutex); + _glthread_LOCK_MUTEX(header->mutex); + + DRMINITLISTHEAD(&header->slabs); + DRMINITLISTHEAD(&header->freeSlabs); + DRMINITLISTHEAD(&header->delayedBuffers); + + header->numDelayed = 0; + header->slabPool = pool; + header->bufSize = size; + + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +driFinishSizeHeader(struct _DriSlabSizeHeader *header) +{ + drmMMListHead *list, *next; + struct _DriSlabBuffer *buf; + + _glthread_LOCK_MUTEX(header->mutex); + for (list = header->delayedBuffers.next, next = list->next; + list != &header->delayedBuffers; + list = next, next = list->next) { + + buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); + if (buf->fence) { + (void) driFenceFinish(buf->fence, buf->fenceType, 0); + driFenceUnReference(&buf->fence); + } + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +pool_takedown(struct _DriBufferPool *driPool) +{ + struct _DriSlabPool *pool = driPool->data; + int i; + + for (i=0; inumBuckets; ++i) { + driFinishSizeHeader(&pool->headers[i]); + } + + free(pool->headers); + free(pool->bucketSizes); + free(pool); + free(driPool); +} + +struct _DriBufferPool * +driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan) +{ + struct _DriBufferPool *driPool; + struct _DriSlabPool *pool; + uint32_t i; + + driPool = calloc(1, sizeof(*driPool)); + if (!driPool) + return NULL; + + pool = calloc(1, sizeof(*pool)); + if (!pool) + goto out_err0; + + pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); + if (!pool->bucketSizes) + goto out_err1; + + pool->headers = calloc(numSizes, sizeof(*pool->headers)); + if (!pool->headers) + goto out_err2; + + pool->fMan = fMan; + pool->proposedFlags = flags; + pool->validMask = validMask; + pool->numBuckets = numSizes; + pool->pageSize = getpagesize(); + pool->fd = fd; + pool->pageAlignment = pageAlignment; + pool->maxSlabSize = maxSlabSize; + pool->desiredNumBuffers = desiredNumBuffers; + + for (i=0; inumBuckets; ++i) { + pool->bucketSizes[i] = (smallestSize << i); + driInitSizeHeader(pool, pool->bucketSizes[i], + &pool->headers[i]); + } + + driPool->data = (void *) pool; + driPool->map = &pool_map; + driPool->unmap = &pool_unmap; + driPool->destroy = &pool_destroy; + driPool->offset = &pool_offset; + driPool->poolOffset = &pool_poolOffset; + driPool->flags = &pool_flags; + driPool->size = &pool_size; + driPool->create = &pool_create; + driPool->fence = &pool_fence; + driPool->kernel = &pool_kernel; + driPool->validate = &pool_validate; + driPool->waitIdle = &pool_waitIdle; + driPool->takeDown = &pool_takedown; + + return driPool; + + out_err2: + free(pool->bucketSizes); + out_err1: + free(pool); + out_err0: + free(driPool); + + return NULL; +} -- cgit v1.2.3 From 4e2127b0e5cb6411123e16dd562626cd70814a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 8 Apr 2008 11:30:36 +0900 Subject: gallium: Allow to debug memory leaks in nested scopes. --- src/gallium/auxiliary/util/p_debug_mem.c | 16 ++++++++-------- src/gallium/include/pipe/p_debug.h | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c index c160afe5b7..97ec9c5b39 100644 --- a/src/gallium/auxiliary/util/p_debug_mem.c +++ b/src/gallium/auxiliary/util/p_debug_mem.c @@ -70,8 +70,7 @@ struct debug_memory_header static struct list_head list = { &list, &list }; -static unsigned long start_no = 0; -static unsigned long end_no = 0; +static unsigned long last_no = 0; void * @@ -84,7 +83,7 @@ debug_malloc(const char *file, unsigned line, const char *function, if(!hdr) return NULL; - hdr->no = end_no++; + hdr->no = last_no++; hdr->file = file; hdr->line = line; hdr->function = function; @@ -147,14 +146,14 @@ debug_realloc(const char *file, unsigned line, const char *function, return new_ptr; } -void -debug_memory_reset(void) +unsigned long +debug_memory_begin(void) { - start_no = end_no; + return last_no; } void -debug_memory_report(void) +debug_memory_end(unsigned long start_no) { struct list_head *entry; @@ -164,7 +163,8 @@ debug_memory_report(void) void *ptr; hdr = LIST_ENTRY(struct debug_memory_header, entry, head); ptr = (void *)((char *)hdr + sizeof(*hdr)); - if(hdr->no >= start_no) + if(start_no <= hdr->no && hdr->no < last_no || + last_no < start_no && (hdr->no < last_no || start_no <= hdr->no)) debug_printf("%s:%u:%s: %u bytes at %p not freed\n", hdr->file, hdr->line, hdr->function, hdr->size, ptr); diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 9e52ad9a37..235c47abac 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -304,11 +304,11 @@ void * debug_realloc(const char *file, unsigned line, const char *function, void *old_ptr, size_t old_size, size_t new_size ); -void -debug_memory_reset(void); +unsigned long +debug_memory_begin(void); void -debug_memory_report(void); +debug_memory_end(unsigned long beginning); #ifdef __cplusplus -- cgit v1.2.3 From c7daa68ca312cc98abe351be2fef8d8246929627 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 7 Apr 2008 21:59:12 -0600 Subject: gallium: begin reworking quad stages for multiple color outputs --- src/gallium/drivers/softpipe/sp_context.h | 2 - src/gallium/drivers/softpipe/sp_fs_llvm.c | 16 +- src/gallium/drivers/softpipe/sp_headers.h | 4 +- src/gallium/drivers/softpipe/sp_quad.c | 9 - src/gallium/drivers/softpipe/sp_quad_alpha_test.c | 5 +- src/gallium/drivers/softpipe/sp_quad_blend.c | 1192 +++++++++++---------- src/gallium/drivers/softpipe/sp_quad_bufloop.c | 4 +- src/gallium/drivers/softpipe/sp_quad_colormask.c | 59 +- src/gallium/drivers/softpipe/sp_quad_coverage.c | 15 +- src/gallium/drivers/softpipe/sp_quad_fs.c | 60 +- src/gallium/drivers/softpipe/sp_quad_output.c | 39 +- 11 files changed, 734 insertions(+), 671 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index dc9d0e6d5d..9724d185d1 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -138,8 +138,6 @@ struct softpipe_context { struct draw_stage *vbuf; struct softpipe_vbuf_render *vbuf_render; - uint current_cbuf; /**< current color buffer being written to */ - struct softpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS]; struct softpipe_tile_cache *zsbuf_cache; diff --git a/src/gallium/drivers/softpipe/sp_fs_llvm.c b/src/gallium/drivers/softpipe/sp_fs_llvm.c index 07d058155f..6e1d9280bb 100644 --- a/src/gallium/drivers/softpipe/sp_fs_llvm.c +++ b/src/gallium/drivers/softpipe/sp_fs_llvm.c @@ -99,19 +99,19 @@ shade_quad_llvm(struct quad_stage *qs, allvmrt(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] == TGSI_SEMANTIC_COLOR); for (i = 0; i < QUAD_SIZE; ++i) { - quad->outputs.color[0][i] = dests[i][qss->colorOutSlot][0]; - quad->outputs.color[1][i] = dests[i][qss->colorOutSlot][1]; - quad->outputs.color[2][i] = dests[i][qss->colorOutSlot][2]; - quad->outputs.color[3][i] = dests[i][qss->colorOutSlot][3]; + quad->outputs.color[0][0][i] = dests[i][qss->colorOutSlot][0]; + quad->outputs.color[0][1][i] = dests[i][qss->colorOutSlot][1]; + quad->outputs.color[0][2][i] = dests[i][qss->colorOutSlot][2]; + quad->outputs.color[0][3][i] = dests[i][qss->colorOutSlot][3]; } } #if DLLVM for (int i = 0; i < QUAD_SIZE; ++i) { debug_printf("QLLVM%d(%d) [%f, %f, %f, %f]\n", i, qss->colorOutSlot, - quad->outputs.color[0][i], - quad->outputs.color[1][i], - quad->outputs.color[2][i], - quad->outputs.color[3][i]); + quad->outputs.color[0][0][i], + quad->outputs.color[0][1][i], + quad->outputs.color[0][2][i], + quad->outputs.color[0][3][i]); } #endif diff --git a/src/gallium/drivers/softpipe/sp_headers.h b/src/gallium/drivers/softpipe/sp_headers.h index 9cf8222133..3d9ede69bb 100644 --- a/src/gallium/drivers/softpipe/sp_headers.h +++ b/src/gallium/drivers/softpipe/sp_headers.h @@ -31,6 +31,7 @@ #ifndef SP_HEADERS_H #define SP_HEADERS_H +#include "pipe/p_state.h" #include "tgsi/exec/tgsi_exec.h" #define PRIM_POINT 1 @@ -66,7 +67,8 @@ struct quad_header { unsigned prim:2; /**< PRIM_POINT, LINE, TRI */ struct { - float color[NUM_CHANNELS][QUAD_SIZE]; /* rrrr, gggg, bbbb, aaaa */ + /** colors in SOA format (rrrr, gggg, bbbb, aaaa) */ + float color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][QUAD_SIZE]; float depth[QUAD_SIZE]; } outputs; diff --git a/src/gallium/drivers/softpipe/sp_quad.c b/src/gallium/drivers/softpipe/sp_quad.c index 8603c1a367..bc83d78ea1 100644 --- a/src/gallium/drivers/softpipe/sp_quad.c +++ b/src/gallium/drivers/softpipe/sp_quad.c @@ -76,15 +76,6 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp_push_quad_first( sp, sp->quad.blend ); } - if (sp->framebuffer.num_cbufs == 1) { - /* the usual case: write to exactly one colorbuf */ - sp->current_cbuf = 0; - } - else { - /* insert bufloop stage */ - sp_push_quad_first( sp, sp->quad.bufloop ); - } - if (sp->depth_stencil->depth.occlusion_count) { sp_push_quad_first( sp, sp->quad.occlusion ); } diff --git a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c index 318916fe30..7a42b08ef5 100644 --- a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c @@ -16,7 +16,8 @@ alpha_test_quad(struct quad_stage *qs, struct quad_header *quad) struct softpipe_context *softpipe = qs->softpipe; const float ref = softpipe->depth_stencil->alpha.ref; unsigned passMask = 0x0, j; - const float *aaaa = quad->outputs.color[3]; + const uint cbuf = 0; /* only output[0].alpha is tested */ + const float *aaaa = quad->outputs.color[cbuf][3]; switch (softpipe->depth_stencil->alpha.func) { case PIPE_FUNC_NEVER: @@ -25,7 +26,7 @@ alpha_test_quad(struct quad_stage *qs, struct quad_header *quad) case PIPE_FUNC_LESS: /* * If mask were an array [4] we could do this SIMD-style: - * passMask = (quad->outputs.color[3] <= vec4(ref)); + * passMask = (quad->outputs.color[0][3] <= vec4(ref)); */ for (j = 0; j < QUAD_SIZE; j++) { if (aaaa[j] < ref) { diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index 0b79cfa1ed..8be8025f40 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -101,114 +101,119 @@ static void logicop_quad(struct quad_stage *qs, struct quad_header *quad) { struct softpipe_context *softpipe = qs->softpipe; - float dest[4][QUAD_SIZE]; - ubyte src[4][4], dst[4][4], res[4][4]; - uint *src4 = (uint *) src; - uint *dst4 = (uint *) dst; - uint *res4 = (uint *) res; - struct softpipe_cached_tile * - tile = sp_get_cached_tile(softpipe, - softpipe->cbuf_cache[softpipe->current_cbuf], - quad->x0, quad->y0); - float (*quadColor)[4] = quad->outputs.color; - uint i, j; - - /* get/swizzle dest colors */ - for (j = 0; j < QUAD_SIZE; j++) { - int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); - int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1); - for (i = 0; i < 4; i++) { - dest[i][j] = tile->data.color[y][x][i]; + uint cbuf; + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) { + float dest[4][QUAD_SIZE]; + ubyte src[4][4], dst[4][4], res[4][4]; + uint *src4 = (uint *) src; + uint *dst4 = (uint *) dst; + uint *res4 = (uint *) res; + struct softpipe_cached_tile * + tile = sp_get_cached_tile(softpipe, + softpipe->cbuf_cache[cbuf], + quad->x0, quad->y0); + float (*quadColor)[4] = quad->outputs.color[cbuf]; + uint i, j; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } } - } - /* convert to ubyte */ - for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */ - UNCLAMPED_FLOAT_TO_UBYTE(dst[j][0], dest[j][0]); /* P0 */ - UNCLAMPED_FLOAT_TO_UBYTE(dst[j][1], dest[j][1]); /* P1 */ - UNCLAMPED_FLOAT_TO_UBYTE(dst[j][2], dest[j][2]); /* P2 */ - UNCLAMPED_FLOAT_TO_UBYTE(dst[j][3], dest[j][3]); /* P3 */ - - UNCLAMPED_FLOAT_TO_UBYTE(src[j][0], quadColor[j][0]); /* P0 */ - UNCLAMPED_FLOAT_TO_UBYTE(src[j][1], quadColor[j][1]); /* P1 */ - UNCLAMPED_FLOAT_TO_UBYTE(src[j][2], quadColor[j][2]); /* P2 */ - UNCLAMPED_FLOAT_TO_UBYTE(src[j][3], quadColor[j][3]); /* P3 */ - } + /* convert to ubyte */ + for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */ + UNCLAMPED_FLOAT_TO_UBYTE(dst[j][0], dest[j][0]); /* P0 */ + UNCLAMPED_FLOAT_TO_UBYTE(dst[j][1], dest[j][1]); /* P1 */ + UNCLAMPED_FLOAT_TO_UBYTE(dst[j][2], dest[j][2]); /* P2 */ + UNCLAMPED_FLOAT_TO_UBYTE(dst[j][3], dest[j][3]); /* P3 */ + + UNCLAMPED_FLOAT_TO_UBYTE(src[j][0], quadColor[j][0]); /* P0 */ + UNCLAMPED_FLOAT_TO_UBYTE(src[j][1], quadColor[j][1]); /* P1 */ + UNCLAMPED_FLOAT_TO_UBYTE(src[j][2], quadColor[j][2]); /* P2 */ + UNCLAMPED_FLOAT_TO_UBYTE(src[j][3], quadColor[j][3]); /* P3 */ + } - switch (softpipe->blend->logicop_func) { - case PIPE_LOGICOP_CLEAR: - for (j = 0; j < 4; j++) - res4[j] = 0; - break; - case PIPE_LOGICOP_NOR: - for (j = 0; j < 4; j++) - res4[j] = ~(src4[j] | dst4[j]); - break; - case PIPE_LOGICOP_AND_INVERTED: - for (j = 0; j < 4; j++) - res4[j] = ~src4[j] & dst4[j]; - break; - case PIPE_LOGICOP_COPY_INVERTED: - for (j = 0; j < 4; j++) - res4[j] = ~src4[j]; - break; - case PIPE_LOGICOP_AND_REVERSE: - for (j = 0; j < 4; j++) - res4[j] = src4[j] & ~dst4[j]; - break; - case PIPE_LOGICOP_INVERT: - for (j = 0; j < 4; j++) - res4[j] = ~dst4[j]; - break; - case PIPE_LOGICOP_XOR: - for (j = 0; j < 4; j++) - res4[j] = dst4[j] ^ src4[j]; - break; - case PIPE_LOGICOP_NAND: - for (j = 0; j < 4; j++) - res4[j] = ~(src4[j] & dst4[j]); - break; - case PIPE_LOGICOP_AND: - for (j = 0; j < 4; j++) - res4[j] = src4[j] & dst4[j]; - break; - case PIPE_LOGICOP_EQUIV: - for (j = 0; j < 4; j++) - res4[j] = ~(src4[j] ^ dst4[j]); - break; - case PIPE_LOGICOP_NOOP: - for (j = 0; j < 4; j++) - res4[j] = dst4[j]; - break; - case PIPE_LOGICOP_OR_INVERTED: - for (j = 0; j < 4; j++) - res4[j] = ~src4[j] | dst4[j]; - break; - case PIPE_LOGICOP_COPY: - for (j = 0; j < 4; j++) - res4[j] = src4[j]; - break; - case PIPE_LOGICOP_OR_REVERSE: - for (j = 0; j < 4; j++) - res4[j] = src4[j] | ~dst4[j]; - break; - case PIPE_LOGICOP_OR: - for (j = 0; j < 4; j++) - res4[j] = src4[j] | dst4[j]; - break; - case PIPE_LOGICOP_SET: - for (j = 0; j < 4; j++) - res4[j] = ~0; - break; - default: - assert(0); - } + switch (softpipe->blend->logicop_func) { + case PIPE_LOGICOP_CLEAR: + for (j = 0; j < 4; j++) + res4[j] = 0; + break; + case PIPE_LOGICOP_NOR: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] | dst4[j]); + break; + case PIPE_LOGICOP_AND_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j] & dst4[j]; + break; + case PIPE_LOGICOP_COPY_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j]; + break; + case PIPE_LOGICOP_AND_REVERSE: + for (j = 0; j < 4; j++) + res4[j] = src4[j] & ~dst4[j]; + break; + case PIPE_LOGICOP_INVERT: + for (j = 0; j < 4; j++) + res4[j] = ~dst4[j]; + break; + case PIPE_LOGICOP_XOR: + for (j = 0; j < 4; j++) + res4[j] = dst4[j] ^ src4[j]; + break; + case PIPE_LOGICOP_NAND: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] & dst4[j]); + break; + case PIPE_LOGICOP_AND: + for (j = 0; j < 4; j++) + res4[j] = src4[j] & dst4[j]; + break; + case PIPE_LOGICOP_EQUIV: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] ^ dst4[j]); + break; + case PIPE_LOGICOP_NOOP: + for (j = 0; j < 4; j++) + res4[j] = dst4[j]; + break; + case PIPE_LOGICOP_OR_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j] | dst4[j]; + break; + case PIPE_LOGICOP_COPY: + for (j = 0; j < 4; j++) + res4[j] = src4[j]; + break; + case PIPE_LOGICOP_OR_REVERSE: + for (j = 0; j < 4; j++) + res4[j] = src4[j] | ~dst4[j]; + break; + case PIPE_LOGICOP_OR: + for (j = 0; j < 4; j++) + res4[j] = src4[j] | dst4[j]; + break; + case PIPE_LOGICOP_SET: + for (j = 0; j < 4; j++) + res4[j] = ~0; + break; + default: + assert(0); + } - for (j = 0; j < 4; j++) { - quadColor[j][0] = UBYTE_TO_FLOAT(res[j][0]); - quadColor[j][1] = UBYTE_TO_FLOAT(res[j][1]); - quadColor[j][2] = UBYTE_TO_FLOAT(res[j][2]); - quadColor[j][3] = UBYTE_TO_FLOAT(res[j][3]); + for (j = 0; j < 4; j++) { + quadColor[j][0] = UBYTE_TO_FLOAT(res[j][0]); + quadColor[j][1] = UBYTE_TO_FLOAT(res[j][1]); + quadColor[j][2] = UBYTE_TO_FLOAT(res[j][2]); + quadColor[j][3] = UBYTE_TO_FLOAT(res[j][3]); + } } /* pass quad to next stage */ @@ -221,504 +226,511 @@ logicop_quad(struct quad_stage *qs, struct quad_header *quad) static void blend_quad(struct quad_stage *qs, struct quad_header *quad) { - struct softpipe_context *softpipe = qs->softpipe; static const float zero[4] = { 0, 0, 0, 0 }; static const float one[4] = { 1, 1, 1, 1 }; - float source[4][QUAD_SIZE], dest[4][QUAD_SIZE]; - struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe, - softpipe->cbuf_cache[softpipe->current_cbuf], - quad->x0, quad->y0); - float (*quadColor)[4] = quad->outputs.color; - uint i, j; - - if (softpipe->blend->logicop_enable) { - logicop_quad(qs, quad); - return; - } - /* get/swizzle dest colors */ - for (j = 0; j < QUAD_SIZE; j++) { - int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); - int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1); - for (i = 0; i < 4; i++) { - dest[i][j] = tile->data.color[y][x][i]; + struct softpipe_context *softpipe = qs->softpipe; + uint cbuf; + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) { + float source[4][QUAD_SIZE], dest[4][QUAD_SIZE]; + struct softpipe_cached_tile *tile + = sp_get_cached_tile(softpipe, + softpipe->cbuf_cache[cbuf], + quad->x0, quad->y0); + float (*quadColor)[4] = quad->outputs.color[cbuf]; + uint i, j; + + if (softpipe->blend->logicop_enable) { + logicop_quad(qs, quad); + return; } - } - /* - * Compute src/first term RGB - */ - switch (softpipe->blend->rgb_src_factor) { - case PIPE_BLENDFACTOR_ONE: - VEC4_COPY(source[0], quadColor[0]); /* R */ - VEC4_COPY(source[1], quadColor[1]); /* G */ - VEC4_COPY(source[2], quadColor[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */ - VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */ - VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA: - { - const float *alpha = quadColor[3]; - VEC4_MUL(source[0], quadColor[0], alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_DST_COLOR: - VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */ - VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */ - VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */ - break; - case PIPE_BLENDFACTOR_DST_ALPHA: - { - const float *alpha = dest[3]; - VEC4_MUL(source[0], quadColor[0], alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - { - const float *alpha = quadColor[3]; - float diff[4]; - VEC4_SUB(diff, one, dest[3]); - VEC4_MIN(source[0], alpha, diff); /* R */ - VEC4_MIN(source[1], alpha, diff); /* G */ - VEC4_MIN(source[2], alpha, diff); /* B */ - } - break; - case PIPE_BLENDFACTOR_CONST_COLOR: - { - float comp[4]; - VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ - VEC4_MUL(source[0], quadColor[0], comp); /* R */ - VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ - VEC4_MUL(source[1], quadColor[1], comp); /* G */ - VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ - VEC4_MUL(source[2], quadColor[2], comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_CONST_ALPHA: - { - float alpha[4]; - VEC4_SCALAR(alpha, softpipe->blend_color.color[3]); - VEC4_MUL(source[0], quadColor[0], alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_SRC1_COLOR: - assert(0); /* to do */ - break; - case PIPE_BLENDFACTOR_SRC1_ALPHA: - assert(0); /* to do */ - break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(source[0], zero); /* R */ - VEC4_COPY(source[1], zero); /* G */ - VEC4_COPY(source[2], zero); /* B */ - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ - VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ - VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ - VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ - VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ - VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, quadColor[3]); - VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, dest[3]); - VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, dest[0]); /* R */ - VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ - VEC4_SUB(inv_comp, one, dest[1]); /* G */ - VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ - VEC4_SUB(inv_comp, one, dest[2]); /* B */ - VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - { - float inv_comp[4]; - /* R */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); - VEC4_MUL(source[0], quadColor[0], inv_comp); - /* G */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); - VEC4_MUL(source[1], quadColor[1], inv_comp); - /* B */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); - VEC4_MUL(source[2], quadColor[2], inv_comp); - } - break; - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - { - float inv_alpha[4]; - VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]); - VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ - VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ - VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_SRC1_COLOR: - assert(0); /* to do */ - break; - case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: - assert(0); /* to do */ - break; - default: - assert(0); - } - - /* - * Compute src/first term A - */ - switch (softpipe->blend->alpha_src_factor) { - case PIPE_BLENDFACTOR_ONE: - VEC4_COPY(source[3], quadColor[3]); /* A */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_SRC_ALPHA: - { - const float *alpha = quadColor[3]; - VEC4_MUL(source[3], quadColor[3], alpha); /* A */ - } - break; - case PIPE_BLENDFACTOR_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - { - const float *alpha = quadColor[3]; - float diff[4]; - VEC4_SUB(diff, one, dest[3]); - VEC4_MIN(source[3], alpha, diff); /* A */ - } - break; - case PIPE_BLENDFACTOR_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_CONST_ALPHA: - { - float comp[4]; - VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ - VEC4_MUL(source[3], quadColor[3], comp); /* A */ + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } } - break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(source[3], zero); /* A */ - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, quadColor[3]); - VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ - } - break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_alpha[4]; - VEC4_SUB(inv_alpha, one, dest[3]); - VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ - } - break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - { - float inv_comp[4]; - /* A */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); - VEC4_MUL(source[3], quadColor[3], inv_comp); - } - break; - default: - assert(0); - } - - - /* - * Compute dest/second term RGB - */ - switch (softpipe->blend->rgb_dst_factor) { - case PIPE_BLENDFACTOR_ONE: - /* dest = dest * 1 NO-OP, leave dest as-is */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */ - VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */ - VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA: - VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */ - VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */ - VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */ - break; - case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ - VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ - VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ - break; - case PIPE_BLENDFACTOR_DST_COLOR: - VEC4_MUL(dest[0], dest[0], dest[0]); /* R */ - VEC4_MUL(dest[1], dest[1], dest[1]); /* G */ - VEC4_MUL(dest[2], dest[2], dest[2]); /* B */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - assert(0); /* illegal */ - break; - case PIPE_BLENDFACTOR_CONST_COLOR: - { - float comp[4]; - VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ - VEC4_MUL(dest[0], dest[0], comp); /* R */ - VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ - VEC4_MUL(dest[1], dest[1], comp); /* G */ - VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ - VEC4_MUL(dest[2], dest[2], comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_CONST_ALPHA: - { - float comp[4]; - VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ - VEC4_MUL(dest[0], dest[0], comp); /* R */ - VEC4_MUL(dest[1], dest[1], comp); /* G */ - VEC4_MUL(dest[2], dest[2], comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(dest[0], zero); /* R */ - VEC4_COPY(dest[1], zero); /* G */ - VEC4_COPY(dest[2], zero); /* B */ - break; - case PIPE_BLENDFACTOR_SRC1_COLOR: - case PIPE_BLENDFACTOR_SRC1_ALPHA: - /* XXX what are these? */ - assert(0); - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ - VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ - VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ - VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ - VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ - VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: - { - float one_minus_alpha[QUAD_SIZE]; - VEC4_SUB(one_minus_alpha, one, quadColor[3]); - VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */ - VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */ - VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, quadColor[3]); /* A */ - VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ - VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ - VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, dest[0]); /* R */ - VEC4_MUL(dest[0], dest[0], inv_comp); /* R */ - VEC4_SUB(inv_comp, one, dest[1]); /* G */ - VEC4_MUL(dest[1], dest[1], inv_comp); /* G */ - VEC4_SUB(inv_comp, one, dest[2]); /* B */ - VEC4_MUL(dest[2], dest[2], inv_comp); /* B */ - } - break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - { - float inv_comp[4]; - /* R */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); - VEC4_MUL(dest[0], dest[0], inv_comp); - /* G */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); - VEC4_MUL(dest[1], dest[1], inv_comp); - /* B */ - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); - VEC4_MUL(dest[2], dest[2], inv_comp); + + /* + * Compute src/first term RGB + */ + switch (softpipe->blend->rgb_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[0], quadColor[0]); /* R */ + VEC4_COPY(source[1], quadColor[1]); /* G */ + VEC4_COPY(source[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */ + VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */ + VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: + { + const float *alpha = quadColor[3]; + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_DST_COLOR: + VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */ + VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */ + VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */ + break; + case PIPE_BLENDFACTOR_DST_ALPHA: + { + const float *alpha = dest[3]; + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + { + const float *alpha = quadColor[3]; + float diff[4]; + VEC4_SUB(diff, one, dest[3]); + VEC4_MIN(source[0], alpha, diff); /* R */ + VEC4_MIN(source[1], alpha, diff); /* G */ + VEC4_MIN(source[2], alpha, diff); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], comp); /* R */ + VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], comp); /* G */ + VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float alpha[4]; + VEC4_SCALAR(alpha, softpipe->blend_color.color[3]); + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_SRC1_ALPHA: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[0], zero); /* R */ + VEC4_COPY(source[1], zero); /* G */ + VEC4_COPY(source[2], zero); /* B */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, quadColor[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, dest[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, dest[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + { + float inv_comp[4]; + /* R */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); + VEC4_MUL(source[0], quadColor[0], inv_comp); + /* G */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); + VEC4_MUL(source[1], quadColor[1], inv_comp); + /* B */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); + VEC4_MUL(source[2], quadColor[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_alpha[4]; + VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + assert(0); /* to do */ + break; + default: + assert(0); } - break; - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - { - float inv_comp[4]; - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); - VEC4_MUL(dest[0], dest[0], inv_comp); - VEC4_MUL(dest[1], dest[1], inv_comp); - VEC4_MUL(dest[2], dest[2], inv_comp); + + /* + * Compute src/first term A + */ + switch (softpipe->blend->alpha_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[3], quadColor[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC_ALPHA: + { + const float *alpha = quadColor[3]; + VEC4_MUL(source[3], quadColor[3], alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + { + const float *alpha = quadColor[3]; + float diff[4]; + VEC4_SUB(diff, one, dest[3]); + VEC4_MIN(source[3], alpha, diff); /* A */ + } + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ + VEC4_MUL(source[3], quadColor[3], comp); /* A */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[3], zero); /* A */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, quadColor[3]); + VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + /* A */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(source[3], quadColor[3], inv_comp); + } + break; + default: + assert(0); } - break; - case PIPE_BLENDFACTOR_INV_SRC1_COLOR: - case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: - /* XXX what are these? */ - assert(0); - break; - default: - assert(0); - } - - /* - * Compute dest/second term A - */ - switch (softpipe->blend->alpha_dst_factor) { - case PIPE_BLENDFACTOR_ONE: - /* dest = dest * 1 NO-OP, leave dest as-is */ - break; - case PIPE_BLENDFACTOR_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_SRC_ALPHA: - VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */ - break; - case PIPE_BLENDFACTOR_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_DST_ALPHA: - VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ - break; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - assert(0); /* illegal */ - break; - case PIPE_BLENDFACTOR_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_CONST_ALPHA: - { - float comp[4]; - VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ - VEC4_MUL(dest[3], dest[3], comp); /* A */ + + + /* + * Compute dest/second term RGB + */ + switch (softpipe->blend->rgb_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */ + VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */ + VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: + VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */ + break; + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ + break; + case PIPE_BLENDFACTOR_DST_COLOR: + VEC4_MUL(dest[0], dest[0], dest[0]); /* R */ + VEC4_MUL(dest[1], dest[1], dest[1]); /* G */ + VEC4_MUL(dest[2], dest[2], dest[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + assert(0); /* illegal */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ + VEC4_MUL(dest[0], dest[0], comp); /* R */ + VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ + VEC4_MUL(dest[1], dest[1], comp); /* G */ + VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ + VEC4_MUL(dest[2], dest[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ + VEC4_MUL(dest[0], dest[0], comp); /* R */ + VEC4_MUL(dest[1], dest[1], comp); /* G */ + VEC4_MUL(dest[2], dest[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[0], zero); /* R */ + VEC4_COPY(dest[1], zero); /* G */ + VEC4_COPY(dest[2], zero); /* B */ + break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + case PIPE_BLENDFACTOR_SRC1_ALPHA: + /* XXX what are these? */ + assert(0); + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ + VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ + VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ + VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ + VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ + VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float one_minus_alpha[QUAD_SIZE]; + VEC4_SUB(one_minus_alpha, one, quadColor[3]); + VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */ + VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */ + VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, quadColor[3]); /* A */ + VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ + VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ + VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[0]); /* R */ + VEC4_MUL(dest[0], dest[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, dest[1]); /* G */ + VEC4_MUL(dest[1], dest[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, dest[2]); /* B */ + VEC4_MUL(dest[2], dest[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + { + float inv_comp[4]; + /* R */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]); + VEC4_MUL(dest[0], dest[0], inv_comp); + /* G */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]); + VEC4_MUL(dest[1], dest[1], inv_comp); + /* B */ + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]); + VEC4_MUL(dest[2], dest[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(dest[0], dest[0], inv_comp); + VEC4_MUL(dest[1], dest[1], inv_comp); + VEC4_MUL(dest[2], dest[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + /* XXX what are these? */ + assert(0); + break; + default: + assert(0); } - break; - case PIPE_BLENDFACTOR_ZERO: - VEC4_COPY(dest[3], zero); /* A */ - break; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: - { - float one_minus_alpha[QUAD_SIZE]; - VEC4_SUB(one_minus_alpha, one, quadColor[3]); - VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */ + + /* + * Compute dest/second term A + */ + switch (softpipe->blend->alpha_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC_ALPHA: + VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */ + break; + case PIPE_BLENDFACTOR_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + assert(0); /* illegal */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */ + VEC4_MUL(dest[3], dest[3], comp); /* A */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[3], zero); /* A */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float one_minus_alpha[QUAD_SIZE]; + VEC4_SUB(one_minus_alpha, one, quadColor[3]); + VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[3]); /* A */ + VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); + VEC4_MUL(dest[3], dest[3], inv_comp); + } + break; + default: + assert(0); } - break; - case PIPE_BLENDFACTOR_INV_DST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_DST_ALPHA: - { - float inv_comp[4]; - VEC4_SUB(inv_comp, one, dest[3]); /* A */ - VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ + + /* + * Combine RGB terms + */ + switch (softpipe->blend->rgb_func) { + case PIPE_BLEND_ADD: + VEC4_ADD(quadColor[0], source[0], dest[0]); /* R */ + VEC4_ADD(quadColor[1], source[1], dest[1]); /* G */ + VEC4_ADD(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB(quadColor[0], source[0], dest[0]); /* R */ + VEC4_SUB(quadColor[1], source[1], dest[1]); /* G */ + VEC4_SUB(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB(quadColor[0], dest[0], source[0]); /* R */ + VEC4_SUB(quadColor[1], dest[1], source[1]); /* G */ + VEC4_SUB(quadColor[2], dest[2], source[2]); /* B */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */ + VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */ + VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */ + VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */ + VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */ + break; + default: + assert(0); } - break; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - /* fall-through */ - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - { - float inv_comp[4]; - VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]); - VEC4_MUL(dest[3], dest[3], inv_comp); + + /* + * Combine A terms + */ + switch (softpipe->blend->alpha_func) { + case PIPE_BLEND_ADD: + VEC4_ADD(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB(quadColor[3], dest[3], source[3]); /* A */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */ + break; + default: + assert(0); } - break; - default: - assert(0); - } - - /* - * Combine RGB terms - */ - switch (softpipe->blend->rgb_func) { - case PIPE_BLEND_ADD: - VEC4_ADD(quadColor[0], source[0], dest[0]); /* R */ - VEC4_ADD(quadColor[1], source[1], dest[1]); /* G */ - VEC4_ADD(quadColor[2], source[2], dest[2]); /* B */ - break; - case PIPE_BLEND_SUBTRACT: - VEC4_SUB(quadColor[0], source[0], dest[0]); /* R */ - VEC4_SUB(quadColor[1], source[1], dest[1]); /* G */ - VEC4_SUB(quadColor[2], source[2], dest[2]); /* B */ - break; - case PIPE_BLEND_REVERSE_SUBTRACT: - VEC4_SUB(quadColor[0], dest[0], source[0]); /* R */ - VEC4_SUB(quadColor[1], dest[1], source[1]); /* G */ - VEC4_SUB(quadColor[2], dest[2], source[2]); /* B */ - break; - case PIPE_BLEND_MIN: - VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */ - VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */ - VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */ - break; - case PIPE_BLEND_MAX: - VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */ - VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */ - VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */ - break; - default: - assert(0); - } - - /* - * Combine A terms - */ - switch (softpipe->blend->alpha_func) { - case PIPE_BLEND_ADD: - VEC4_ADD(quadColor[3], source[3], dest[3]); /* A */ - break; - case PIPE_BLEND_SUBTRACT: - VEC4_SUB(quadColor[3], source[3], dest[3]); /* A */ - break; - case PIPE_BLEND_REVERSE_SUBTRACT: - VEC4_SUB(quadColor[3], dest[3], source[3]); /* A */ - break; - case PIPE_BLEND_MIN: - VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */ - break; - case PIPE_BLEND_MAX: - VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */ - break; - default: - assert(0); - } - + + } /* cbuf loop */ + /* pass blended quad to next stage */ qs->next->run(qs->next, quad); } diff --git a/src/gallium/drivers/softpipe/sp_quad_bufloop.c b/src/gallium/drivers/softpipe/sp_quad_bufloop.c index 2ae4e22a7d..b3db428ef1 100644 --- a/src/gallium/drivers/softpipe/sp_quad_bufloop.c +++ b/src/gallium/drivers/softpipe/sp_quad_bufloop.c @@ -13,7 +13,7 @@ static void cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad) { struct softpipe_context *softpipe = qs->softpipe; - float tmp[4][QUAD_SIZE]; + float tmp[PIPE_MAX_COLOR_BUFS][4][QUAD_SIZE]; unsigned i; assert(sizeof(quad->outputs.color) == sizeof(tmp)); @@ -30,7 +30,9 @@ cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad) for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) { /* set current cbuffer */ +#if 0 /* obsolete & going away */ softpipe->current_cbuf = i; +#endif /* pass blended quad to next stage */ qs->next->run(qs->next, quad); diff --git a/src/gallium/drivers/softpipe/sp_quad_colormask.c b/src/gallium/drivers/softpipe/sp_quad_colormask.c index 1f09d900ca..7fe080990b 100644 --- a/src/gallium/drivers/softpipe/sp_quad_colormask.c +++ b/src/gallium/drivers/softpipe/sp_quad_colormask.c @@ -47,38 +47,43 @@ static void colormask_quad(struct quad_stage *qs, struct quad_header *quad) { struct softpipe_context *softpipe = qs->softpipe; - float dest[4][QUAD_SIZE]; - struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe, - softpipe->cbuf_cache[softpipe->current_cbuf], - quad->x0, quad->y0); - float (*quadColor)[4] = quad->outputs.color; - uint i, j; - - /* get/swizzle dest colors */ - for (j = 0; j < QUAD_SIZE; j++) { - int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); - int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1); - for (i = 0; i < 4; i++) { - dest[i][j] = tile->data.color[y][x][i]; + uint cbuf; + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) { + float dest[4][QUAD_SIZE]; + struct softpipe_cached_tile *tile + = sp_get_cached_tile(softpipe, + softpipe->cbuf_cache[cbuf], + quad->x0, quad->y0); + float (*quadColor)[4] = quad->outputs.color[cbuf]; + uint i, j; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } } - } - /* R */ - if (!(softpipe->blend->colormask & PIPE_MASK_R)) - COPY_4V(quadColor[0], dest[0]); + /* R */ + if (!(softpipe->blend->colormask & PIPE_MASK_R)) + COPY_4V(quadColor[0], dest[0]); - /* G */ - if (!(softpipe->blend->colormask & PIPE_MASK_G)) - COPY_4V(quadColor[1], dest[1]); + /* G */ + if (!(softpipe->blend->colormask & PIPE_MASK_G)) + COPY_4V(quadColor[1], dest[1]); - /* B */ - if (!(softpipe->blend->colormask & PIPE_MASK_B)) - COPY_4V(quadColor[2], dest[2]); + /* B */ + if (!(softpipe->blend->colormask & PIPE_MASK_B)) + COPY_4V(quadColor[2], dest[2]); - /* A */ - if (!(softpipe->blend->colormask & PIPE_MASK_A)) - COPY_4V(quadColor[3], dest[3]); + /* A */ + if (!(softpipe->blend->colormask & PIPE_MASK_A)) + COPY_4V(quadColor[3], dest[3]); + } /* pass quad to next stage */ qs->next->run(qs->next, quad); diff --git a/src/gallium/drivers/softpipe/sp_quad_coverage.c b/src/gallium/drivers/softpipe/sp_quad_coverage.c index b3d3fae22f..dd5ebb2296 100644 --- a/src/gallium/drivers/softpipe/sp_quad_coverage.c +++ b/src/gallium/drivers/softpipe/sp_quad_coverage.c @@ -50,12 +50,17 @@ coverage_quad(struct quad_stage *qs, struct quad_header *quad) if ((softpipe->rasterizer->poly_smooth && quad->prim == PRIM_TRI) || (softpipe->rasterizer->line_smooth && quad->prim == PRIM_LINE) || (softpipe->rasterizer->point_smooth && quad->prim == PRIM_POINT)) { - float (*quadColor)[4] = quad->outputs.color; - unsigned j; - for (j = 0; j < QUAD_SIZE; j++) { - assert(quad->coverage[j] >= 0.0); - assert(quad->coverage[j] <= 1.0); + uint cbuf; + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) { + float (*quadColor)[4] = quad->outputs.color[cbuf]; + unsigned j; + for (j = 0; j < QUAD_SIZE; j++) { + assert(quad->coverage[j] >= 0.0); + assert(quad->coverage[j] <= 1.0); quadColor[3][j] *= quad->coverage[j]; + } } } diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index a73df31383..9a20c056a2 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -88,22 +88,64 @@ shade_quad( &qss->machine, quad ); - /* store result color */ +#if 0 /* XXX multi color outputs - untested */ + /* store outputs */ + boolean z_written = FALSE; + { + const ubyte *sem_name = softpipe->fs->info.output_semantic_name; + const ubyte *sem_index = softpipe->fs->info.output_semantic_index; + const uint n = qss->stage.softpipe->fs->info.num_outputs; + uint i; + for (i = 0; i < n; i++) { + switch (sem_name[i]) { + case TGSI_SEMANTIC_COLOR: + { + uint cbuf = sem_index[i]; + memcpy(quad->outputs.color[cbuf], + &machine->Outputs[i].xyzw[0].f[0], + sizeof(quad->outputs.color[0]) ); + } + break; + case TGSI_SEMANTIC_POSITION: + { + uint j; + for (j = 0; j < 4; j++) { + quad->outputs.depth[j] = machine->Outputs[0].xyzw[2].f[j]; + } + z_written = TRUE; + } + break; + } + } + } + + if (!z_written) { + /* compute Z values now, as in the quad earlyz stage */ + /* XXX we should really only do this if the earlyz stage is not used */ + const float fx = (float) quad->x0; + const float fy = (float) quad->y0; + const float dzdx = quad->posCoef->dadx[2]; + const float dzdy = quad->posCoef->dady[2]; + const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy; + + quad->outputs.depth[0] = z0; + quad->outputs.depth[1] = z0 + dzdx; + quad->outputs.depth[2] = z0 + dzdy; + quad->outputs.depth[3] = z0 + dzdx + dzdy; + } +#endif + + /* store result color(s) */ if (qss->colorOutSlot >= 0) { /* XXX need to handle multiple color outputs someday */ - assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot] + assert(softpipe->fs->info.output_semantic_name[qss->colorOutSlot] == TGSI_SEMANTIC_COLOR); memcpy( - quad->outputs.color, + quad->outputs.color[0], &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0], - sizeof( quad->outputs.color ) ); + sizeof( quad->outputs.color[0] ) ); } - /* - * XXX the following code for updating quad->outputs.depth - * isn't really needed if we did early z testing. - */ - /* store result Z */ if (qss->depthOutSlot >= 0) { /* output[slot] is new Z */ diff --git a/src/gallium/drivers/softpipe/sp_quad_output.c b/src/gallium/drivers/softpipe/sp_quad_output.c index cfe8f11808..40083138a4 100644 --- a/src/gallium/drivers/softpipe/sp_quad_output.c +++ b/src/gallium/drivers/softpipe/sp_quad_output.c @@ -34,31 +34,36 @@ /** - * Write quad to framebuffer, taking mask into account. - * - * Note that surfaces support only full quad reads and writes. + * Last step of quad processing: write quad colors to the framebuffer, + * taking mask into account. */ static void output_quad(struct quad_stage *qs, struct quad_header *quad) { - struct softpipe_context *softpipe = qs->softpipe; - struct softpipe_cached_tile *tile - = sp_get_cached_tile(softpipe, - softpipe->cbuf_cache[softpipe->current_cbuf], - quad->x0, quad->y0); /* in-tile pos: */ const int itx = quad->x0 % TILE_SIZE; const int ity = quad->y0 % TILE_SIZE; - float (*quadColor)[4] = quad->outputs.color; - int i, j; - /* get/swizzle dest colors */ - for (j = 0; j < QUAD_SIZE; j++) { - if (quad->mask & (1 << j)) { - int x = itx + (j & 1); - int y = ity + (j >> 1); - for (i = 0; i < 4; i++) { /* loop over color chans */ - tile->data.color[y][x][i] = quadColor[i][j]; + struct softpipe_context *softpipe = qs->softpipe; + uint cbuf; + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) { + struct softpipe_cached_tile *tile + = sp_get_cached_tile(softpipe, + softpipe->cbuf_cache[cbuf], + quad->x0, quad->y0); + float (*quadColor)[4] = quad->outputs.color[cbuf]; + int i, j; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->mask & (1 << j)) { + int x = itx + (j & 1); + int y = ity + (j >> 1); + for (i = 0; i < 4; i++) { /* loop over color chans */ + tile->data.color[y][x][i] = quadColor[i][j]; + } } } } -- cgit v1.2.3 From 17f640990350823f530257ee1b1fa7fa1f83493f Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 7 Apr 2008 22:00:41 -0600 Subject: gallium: get rid of bufloop quad stage --- src/gallium/drivers/softpipe/Makefile | 1 - src/gallium/drivers/softpipe/SConscript | 1 - src/gallium/drivers/softpipe/sp_context.c | 2 -- src/gallium/drivers/softpipe/sp_context.h | 1 - src/gallium/drivers/softpipe/sp_quad.h | 1 - 5 files changed, 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index f32db35d58..19dfd8c1a7 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -17,7 +17,6 @@ C_SOURCES = \ sp_quad.c \ sp_quad_alpha_test.c \ sp_quad_blend.c \ - sp_quad_bufloop.c \ sp_quad_colormask.c \ sp_quad_coverage.c \ sp_quad_depth_test.c \ diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index 88c21ee3b0..06931fa8d8 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -16,7 +16,6 @@ softpipe = env.ConvenienceLibrary( 'sp_prim_vbuf.c', 'sp_quad_alpha_test.c', 'sp_quad_blend.c', - 'sp_quad_bufloop.c', 'sp_quad.c', 'sp_quad_colormask.c', 'sp_quad_coverage.c', diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index e298ed37c3..8c84ddbe19 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -98,7 +98,6 @@ static void softpipe_destroy( struct pipe_context *pipe ) softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test ); softpipe->quad.occlusion->destroy( softpipe->quad.occlusion ); softpipe->quad.coverage->destroy( softpipe->quad.coverage ); - softpipe->quad.bufloop->destroy( softpipe->quad.bufloop ); softpipe->quad.blend->destroy( softpipe->quad.blend ); softpipe->quad.colormask->destroy( softpipe->quad.colormask ); softpipe->quad.output->destroy( softpipe->quad.output ); @@ -207,7 +206,6 @@ softpipe_create( struct pipe_screen *screen, softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); - softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe); softpipe->quad.blend = sp_quad_blend_stage(softpipe); softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); softpipe->quad.output = sp_quad_output_stage(softpipe); diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 9724d185d1..6f0b234d89 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -124,7 +124,6 @@ struct softpipe_context { struct quad_stage *depth_test; struct quad_stage *occlusion; struct quad_stage *coverage; - struct quad_stage *bufloop; struct quad_stage *blend; struct quad_stage *colormask; struct quad_stage *output; diff --git a/src/gallium/drivers/softpipe/sp_quad.h b/src/gallium/drivers/softpipe/sp_quad.h index f1e0281764..08513cb95f 100644 --- a/src/gallium/drivers/softpipe/sp_quad.h +++ b/src/gallium/drivers/softpipe/sp_quad.h @@ -58,7 +58,6 @@ struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe ); struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe ); struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe ); -struct quad_stage *sp_quad_bufloop_stage( struct softpipe_context *softpipe ); struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe ); struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe ); struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe ); -- cgit v1.2.3 From 4c0f72432393e324d608474d24d20ebb465cb2ca Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Apr 2008 11:26:52 +0200 Subject: Fixed user_buffer memory leak --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 4 +++- src/gallium/winsys/dri/intel/ws_dri_bufmgr.c | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 59729a0245..40902197e1 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -156,7 +156,9 @@ intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); driGenUserBuffer( iws->regionPool, - "pipe user buffer", &buffer->driBO, ptr, bytes ); + "pipe user buffer", &buffer->driBO, ptr, bytes ); + + buffer->base.refcount = 1; return &buffer->base; } diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c index eb5216cb37..bf387f672b 100644 --- a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c +++ b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c @@ -431,7 +431,6 @@ driBOUnReference(struct _DriBufferObject *buf) if (!buf) return; - _glthread_LOCK_MUTEX(buf->mutex); tmp = --buf->refCount; if (!tmp) { -- cgit v1.2.3 From caa5b1736dd4c4ba85966fa7710c52da406b1dce Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Apr 2008 11:48:44 +0200 Subject: Added fence counter to fence manager --- src/gallium/winsys/dri/intel/ws_dri_fencemgr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c index 8aaef1c620..1f893b47ce 100644 --- a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c +++ b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c @@ -23,6 +23,7 @@ struct _DriFenceMgr { _glthread_Mutex mutex; int refCount; drmMMListHead *heads; + int num_fences; }; struct _DriFenceObject { @@ -68,6 +69,7 @@ driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) _glthread_LOCK_MUTEX(tmp->mutex); tmp->refCount = 1; tmp->info = *info; + tmp->num_fences = 0; tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); if (!tmp->heads) goto out_err; @@ -114,9 +116,11 @@ driFenceUnReferenceLocked(struct _DriFenceObject **pFence) DRMLISTDELINIT(&fence->head); if (fence->private) mgr->info.unreference(mgr, &fence->private); + --mgr->num_fences; fence->mgr = NULL; --mgr->refCount; free(fence); + } } @@ -297,6 +301,7 @@ struct _DriFenceObject DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); fence->mgr = mgr; ++mgr->refCount; + ++mgr->num_fences; _glthread_UNLOCK_MUTEX(mgr->mutex); fence->fence_class = fence_class; fence->fence_type = fence_type; -- cgit v1.2.3 From 4382b0c9cba3efa8a60252f6ddf2f0653352f7d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 8 Apr 2008 20:42:06 +0900 Subject: gallium: Fix overzealous assert. --- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 24ba61a0b7..b1f7d93057 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -97,6 +97,7 @@ _fenced_buffer_add(struct fenced_buffer *fenced_buf) { struct fenced_buffer_list *fenced_list = fenced_buf->list; + assert(fenced_buf->base.base.refcount); assert(fenced_buf->fence); assert(!fenced_buf->head.prev); assert(!fenced_buf->head.next); @@ -128,7 +129,6 @@ _fenced_buffer_remove(struct fenced_buffer *fenced_buf) assert(fenced_buf->fence); - assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0); winsys->fence_reference(winsys, &fenced_buf->fence, NULL); assert(fenced_buf->head.prev); @@ -174,6 +174,9 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, break; prev_fence = fenced_buf->fence; } + else { + assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0); + } _fenced_buffer_remove(fenced_buf); @@ -199,6 +202,7 @@ fenced_buffer_destroy(struct pb_buffer *buf) prev = curr->prev; do { fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); + assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0); _fenced_buffer_remove(fenced_buf); curr = prev; prev = curr->prev; -- cgit v1.2.3 From 2dd6022e65972b0706011734b68da4e9177b05c3 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Apr 2008 15:01:16 +0200 Subject: i915: Fixed fence leak in intel_swapbuffers.c --- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 1a42389169..923b542771 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -180,7 +180,6 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, if (intel->first_swap_fence) driFenceUnReference(&intel->first_swap_fence); intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); - driFenceReference(intel->first_swap_fence); } UNLOCK_HARDWARE(intel); -- cgit v1.2.3 From 1d43a8b25513866d67b5b16ae1945d6e9d95743d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Apr 2008 17:24:33 +0200 Subject: i915: Fixed fence related problems --- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 4 +++- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 05223bf700..3a8ff5a4eb 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -386,8 +386,10 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) GLboolean was_locked = intel->locked; struct _DriFenceObject *fence; - if (used == 0) + if (used == 0) { + driFenceReference(batch->last_fence); return batch->last_fence; + } /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a * performance drain that we would like to avoid. diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index ae3e9654d3..a35825d36a 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -113,10 +113,10 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws, delta ); #else /* new */ intel_offset_relocation( intel->batch, - delta, - dri_bo( buf ), - flags, - mask ); + delta, + dri_bo( buf ), + flags, + mask ); #endif } @@ -132,9 +132,13 @@ static void intel_i915_batch_flush( struct i915_winsys *sws, struct pipe_fence_handle *pipe; } fu; + if (fence) + assert(!*fence); + fu.dri = intel_batchbuffer_flush( intel->batch ); - if (!fu.dri && fence) { + if (!fu.dri) { + assert(0); *fence = NULL; return; } @@ -143,11 +147,9 @@ static void intel_i915_batch_flush( struct i915_winsys *sws, if (fence) *fence = fu.pipe; else - iws->pws->fence_reference(iws->pws, &fu.dri, NULL); + driFenceUnReference(&fu.dri); } - -// if (0) intel_i915_batch_wait_idle( sws ); } -- cgit v1.2.3 From bd56b21adf5eafebe6df90eac12f0f9eaa9e225f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Apr 2008 18:40:36 +0200 Subject: i915: Added debug counter to bufmgr --- src/gallium/winsys/dri/intel/ws_dri_bufmgr.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c index bf387f672b..1bc1089352 100644 --- a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c +++ b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c @@ -53,6 +53,8 @@ _glthread_DECLARE_STATIC_MUTEX(bmMutex); _glthread_DECLARE_STATIC_COND(bmCond); static int kernelReaders = 0; +static int num_buffers = 0; +static int num_user_buffers = 0; static drmBO *drmBOListBuf(void *iterator) { @@ -441,6 +443,10 @@ driBOUnReference(struct _DriBufferObject *buf) else buf->pool->destroy(buf->pool, buf->private); } + if (buf->userBuffer) + num_user_buffers--; + else + num_buffers--; free(buf); } else _glthread_UNLOCK_MUTEX(buf->mutex); @@ -633,6 +639,7 @@ driGenBuffers(struct _DriBufferPool *pool, flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + ++num_buffers; assert(pool); @@ -664,7 +671,9 @@ driGenUserBuffer(struct _DriBufferPool *pool, { const unsigned alignment = 1, flags = 0, hint = 0; + --num_buffers; /* JB: is inced in GenBuffes */ driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); + ++num_user_buffers; (*buffers)->userBuffer = 1; (*buffers)->userData = ptr; -- cgit v1.2.3 From 28cf8c8fdcbd2817b93f27cad2bba3b4fb8aecf5 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 8 Apr 2008 21:07:14 -0600 Subject: gallium: keep track of num_vertex_attribs/buffers for shorter loops --- src/gallium/drivers/softpipe/sp_context.h | 2 ++ src/gallium/drivers/softpipe/sp_draw_arrays.c | 22 +++++++++------------- src/gallium/drivers/softpipe/sp_state_vertex.c | 2 ++ 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 6f0b234d89..2442bd1eb0 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -83,6 +83,8 @@ struct softpipe_context { unsigned num_samplers; unsigned num_textures; + unsigned num_vertex_elements; + unsigned num_vertex_buffers; /* Counter for occlusion queries. Note this supports overlapping * queries. diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index ab54050d3f..61bcf51899 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -125,14 +125,12 @@ softpipe_draw_elements(struct pipe_context *pipe, /* * Map vertex buffers */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (sp->vertex_buffer[i].buffer) { - void *buf - = pipe->winsys->buffer_map(pipe->winsys, - sp->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_vertex_buffer(draw, i, buf); - } + for (i = 0; i < sp->num_vertex_buffers; i++) { + void *buf + = pipe->winsys->buffer_map(pipe->winsys, + sp->vertex_buffer[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { @@ -153,11 +151,9 @@ softpipe_draw_elements(struct pipe_context *pipe, /* * unmap vertex/index buffers - will cause draw module to flush */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (sp->vertex_buffer[i].buffer) { - draw_set_mapped_vertex_buffer(draw, i, NULL); - pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer); - } + for (i = 0; i < sp->num_vertex_buffers; i++) { + draw_set_mapped_vertex_buffer(draw, i, NULL); + pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer); } if (indexBuffer) { draw_set_mapped_element_buffer(draw, 0, NULL); diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index e0230e16a4..46b6991195 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -47,6 +47,7 @@ softpipe_set_vertex_elements(struct pipe_context *pipe, memcpy(softpipe->vertex_element, attribs, count * sizeof(struct pipe_vertex_element)); + softpipe->num_vertex_elements = count; softpipe->dirty |= SP_NEW_VERTEX; @@ -64,6 +65,7 @@ softpipe_set_vertex_buffers(struct pipe_context *pipe, assert(count <= PIPE_MAX_ATTRIBS); memcpy(softpipe->vertex_buffer, buffers, count * sizeof(buffers[0])); + softpipe->num_vertex_buffers = count; softpipe->dirty |= SP_NEW_VERTEX; -- cgit v1.2.3 From 1f888abf16ce4de00231505b8d1bc68426b04e8f Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 8 Apr 2008 21:14:58 -0600 Subject: i915: keep track of num_vertex_attribs/buffers for shorter loops --- src/gallium/drivers/i915simple/i915_context.c | 22 +++++++++------------- src/gallium/drivers/i915simple/i915_context.h | 2 ++ src/gallium/drivers/i915simple/i915_state.c | 3 +++ 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index fee33d82de..58a5854f0d 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -65,14 +65,12 @@ i915_draw_elements( struct pipe_context *pipe, /* * Map vertex buffers */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (i915->vertex_buffer[i].buffer) { - void *buf - = pipe->winsys->buffer_map(pipe->winsys, - i915->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_vertex_buffer(draw, i, buf); - } + for (i = 0; i < i915->num_vertex_buffers; i++) { + void *buf + = pipe->winsys->buffer_map(pipe->winsys, + i915->vertex_buffer[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { @@ -96,11 +94,9 @@ i915_draw_elements( struct pipe_context *pipe, /* * unmap vertex/index buffers */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (i915->vertex_buffer[i].buffer) { - pipe->winsys->buffer_unmap(pipe->winsys, i915->vertex_buffer[i].buffer); - draw_set_mapped_vertex_buffer(draw, i, NULL); - } + for (i = 0; i < i915->num_vertex_buffers; i++) { + pipe->winsys->buffer_unmap(pipe->winsys, i915->vertex_buffer[i].buffer); + draw_set_mapped_vertex_buffer(draw, i, NULL); } if (indexBuffer) { pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 8e707ea574..38e6a34884 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -238,6 +238,8 @@ struct i915_context unsigned num_samplers; unsigned num_textures; + unsigned num_vertex_elements; + unsigned num_vertex_buffers; unsigned *batch_start; diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 4404bc4590..24d31ad740 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -694,6 +694,8 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe, struct i915_context *i915 = i915_context(pipe); memcpy(i915->vertex_buffer, buffers, count * sizeof(buffers[0])); + i915->num_vertex_buffers = count; + /* pass-through to draw module */ draw_set_vertex_buffers(i915->draw, count, buffers); } @@ -703,6 +705,7 @@ static void i915_set_vertex_elements(struct pipe_context *pipe, const struct pipe_vertex_element *elements) { struct i915_context *i915 = i915_context(pipe); + i915->num_vertex_elements = count; /* pass-through to draw module */ draw_set_vertex_elements(i915->draw, count, elements); } -- cgit v1.2.3 From 7e57a9e8bba322b2ba8a02eec4b79c90e7052738 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 8 Apr 2008 21:18:21 -0600 Subject: cell: keep track of num_vertex_attribs/buffers for shorter loops --- src/gallium/drivers/cell/ppu/cell_context.h | 2 ++ src/gallium/drivers/cell/ppu/cell_draw_arrays.c | 22 +++++++++------------- src/gallium/drivers/cell/ppu/cell_state_vertex.c | 2 ++ 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 7f656a9744..8df41c1d4c 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -104,7 +104,9 @@ struct cell_context uint num_textures; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + uint num_vertex_buffers; struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; + uint num_vertex_elements; ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS]; ubyte *zsbuf_map; diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index b896252f81..36af5be5f0 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -123,14 +123,12 @@ cell_draw_elements(struct pipe_context *pipe, /* * Map vertex buffers */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (sp->vertex_buffer[i].buffer) { - void *buf = pipe->winsys->buffer_map(pipe->winsys, - sp->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); - cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size); - draw_set_mapped_vertex_buffer(draw, i, buf); - } + for (i = 0; i < sp->num_vertex_buffers; i++) { + void *buf = pipe->winsys->buffer_map(pipe->winsys, + sp->vertex_buffer[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size); + draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { @@ -151,11 +149,9 @@ cell_draw_elements(struct pipe_context *pipe, /* * unmap vertex/index buffers - will cause draw module to flush */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (sp->vertex_buffer[i].buffer) { - draw_set_mapped_vertex_buffer(draw, i, NULL); - pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer); - } + for (i = 0; i < sp->num_vertex_buffers; i++) { + draw_set_mapped_vertex_buffer(draw, i, NULL); + pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer); } if (indexBuffer) { draw_set_mapped_element_buffer(draw, 0, NULL); diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c index 6c83b8dc72..114684c2a3 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c +++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c @@ -45,6 +45,7 @@ cell_set_vertex_elements(struct pipe_context *pipe, assert(count <= PIPE_MAX_ATTRIBS); memcpy(cell->vertex_element, elements, count * sizeof(elements[0])); + cell->num_vertex_elements = count; cell->dirty |= CELL_NEW_VERTEX; @@ -62,6 +63,7 @@ cell_set_vertex_buffers(struct pipe_context *pipe, assert(count <= PIPE_MAX_ATTRIBS); memcpy(cell->vertex_buffer, buffers, count * sizeof(buffers[0])); + cell->num_vertex_buffers = count; cell->dirty |= CELL_NEW_VERTEX; -- cgit v1.2.3 From be37e8350f9b95fb50fbce3a2bd84098ad27e462 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 8 Apr 2008 21:38:44 -0600 Subject: gallium: remove obsolete/unused PIPE_ATTRIB_MAX --- src/gallium/include/pipe/p_state.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 2dc9a92186..79efc4f53d 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -55,7 +55,6 @@ extern "C" { #define PIPE_MAX_CLIP_PLANES 6 #define PIPE_MAX_CONSTANT 32 #define PIPE_MAX_ATTRIBS 32 -#define PIPE_ATTRIB_MAX 32 /* XXX obsolete - remove */ #define PIPE_MAX_COLOR_BUFS 8 #define PIPE_MAX_TEXTURE_LEVELS 16 #define PIPE_MAX_FEEDBACK_ATTRIBS 16 -- cgit v1.2.3 From da8934034b33adef5dc41395cfde4bdd26ba207c Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 8 Apr 2008 21:43:36 -0600 Subject: gallium: re-order, clean-up PIPE_MAX_* definitions --- src/gallium/include/pipe/p_state.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 79efc4f53d..912d84e7b9 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -51,15 +51,14 @@ extern "C" { /** * Implementation limits */ -#define PIPE_MAX_SAMPLERS 16 -#define PIPE_MAX_CLIP_PLANES 6 -#define PIPE_MAX_CONSTANT 32 -#define PIPE_MAX_ATTRIBS 32 -#define PIPE_MAX_COLOR_BUFS 8 -#define PIPE_MAX_TEXTURE_LEVELS 16 -#define PIPE_MAX_FEEDBACK_ATTRIBS 16 -#define PIPE_MAX_SHADER_INPUTS 16 -#define PIPE_MAX_SHADER_OUTPUTS 16 +#define PIPE_MAX_ATTRIBS 32 +#define PIPE_MAX_CLIP_PLANES 6 +#define PIPE_MAX_COLOR_BUFS 8 +#define PIPE_MAX_CONSTANT 32 +#define PIPE_MAX_SAMPLERS 16 +#define PIPE_MAX_SHADER_INPUTS 16 +#define PIPE_MAX_SHADER_OUTPUTS 16 +#define PIPE_MAX_TEXTURE_LEVELS 16 /* fwd decls */ -- cgit v1.2.3 From f7e475280a0b98484a8c1a98f18b2733532486b4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 9 Apr 2008 14:17:48 -0600 Subject: gallium: fix bug in PIPE_BLENDFACTOR_INV_DST_ALPHA case --- src/gallium/drivers/softpipe/sp_quad_blend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index 8be8025f40..802472df45 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -561,7 +561,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) case PIPE_BLENDFACTOR_INV_DST_ALPHA: { float inv_comp[4]; - VEC4_SUB(inv_comp, one, quadColor[3]); /* A */ + VEC4_SUB(inv_comp, one, dest[3]); /* A */ VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ -- cgit v1.2.3 From a52faa9325db178601811f4bdad6d9747de5f238 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 9 Apr 2008 16:09:46 -0600 Subject: gallium: remove unneeded st->haveFramebufferSurfaces field. --- src/gallium/winsys/xlib/xm_api.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index a82d3c990e..0c248344b1 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -814,9 +814,6 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) mesaCtx->Const.CheckArrayBounds = GL_TRUE; #endif - /* finish up xmesa context initializations */ - c->st->haveFramebufferSurfaces = GL_TRUE; - return c; } -- cgit v1.2.3 From c95dcc49629b72b95826e87e067d7a48753605fb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 8 Apr 2008 17:59:28 +0100 Subject: remove usage of vertex_header --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 6 - src/gallium/auxiliary/draw/draw_vbuf.c | 20 - src/gallium/auxiliary/draw/draw_vertex.c | 5 - src/gallium/auxiliary/draw/draw_vertex.h | 2 - src/gallium/auxiliary/draw/draw_vf.c | 56 +- src/gallium/drivers/softpipe/Makefile | 1 + src/gallium/drivers/softpipe/SConscript | 1 + src/gallium/drivers/softpipe/sp_prim_setup.c | 1189 +-------------------- src/gallium/drivers/softpipe/sp_prim_setup.h | 6 + src/gallium/drivers/softpipe/sp_prim_vbuf.c | 223 ++-- src/gallium/drivers/softpipe/sp_setup.c | 1249 +++++++++++++++++++++++ src/gallium/drivers/softpipe/sp_setup.h | 53 + src/gallium/drivers/softpipe/sp_state_derived.c | 13 +- 13 files changed, 1480 insertions(+), 1344 deletions(-) create mode 100644 src/gallium/drivers/softpipe/sp_setup.c create mode 100644 src/gallium/drivers/softpipe/sp_setup.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 0806076956..e4e144ef19 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -212,12 +212,6 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, case EMIT_1F: feme->fetch[i].emit = emit_R32_FLOAT; break; - case EMIT_HEADER: - feme->fetch[i].ptr = (const ubyte *)&zero; - feme->fetch[i].pitch = 0; - feme->fetch[i].fetch = fetch_R32_FLOAT; - feme->fetch[i].emit = emit_R32_FLOAT; - break; case EMIT_1F_PSIZE: feme->fetch[i].ptr = (const ubyte *)&feme->draw->rasterizer->point_size; feme->fetch[i].pitch = 0; diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c index f83b441e93..e3216ff711 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_vbuf.c @@ -126,13 +126,6 @@ dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) case EMIT_OMIT: debug_printf("EMIT_OMIT:"); break; - case EMIT_ALL: - assert(i == 0); - assert(j == 0); - debug_printf("EMIT_ALL:\t"); - for(k = 0; k < vinfo->size*4; ++k) - debug_printf("%02x ", *data++); - break; case EMIT_1F: debug_printf("EMIT_1F:\t"); debug_printf("%f ", *(float *)data); data += sizeof(float); @@ -217,19 +210,6 @@ emit_vertex( struct vbuf_stage *vbuf, case EMIT_OMIT: /* no-op */ break; - case EMIT_ALL: - /* just copy the whole vertex as-is to the vbuf */ - assert(i == 0); - assert(j == 0); - memcpy(vbuf->vertex_ptr, vertex, vinfo->size * 4); - vbuf->vertex_ptr += vinfo->size; - count += vinfo->size; - break; - case EMIT_HEADER: - memcpy(vbuf->vertex_ptr, vertex, sizeof(*vertex)); - *vbuf->vertex_ptr += sizeof(*vertex) / 4; - count += sizeof(*vertex) / 4; - break; case EMIT_1F: *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); count++; diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c index 970adc95e7..168036eee8 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.c +++ b/src/gallium/auxiliary/draw/draw_vertex.c @@ -52,9 +52,6 @@ draw_compute_vertex_size(struct vertex_info *vinfo) switch (vinfo->emit[i]) { case EMIT_OMIT: break; - case EMIT_HEADER: - vinfo->size += sizeof(struct vertex_header) / 4; - break; case EMIT_4UB: /* fall-through */ case EMIT_1F_PSIZE: @@ -71,8 +68,6 @@ draw_compute_vertex_size(struct vertex_info *vinfo) case EMIT_4F: vinfo->size += 4; break; - case EMIT_ALL: - /* fall-through */ default: assert(0); } diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index abd2017ed3..65818463ca 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -47,8 +47,6 @@ */ enum attrib_emit { EMIT_OMIT, /**< don't emit the attribute */ - EMIT_ALL, /**< emit whole post-xform vertex, w/ header */ - EMIT_HEADER, /**< emit vertex_header struct (XXX temp?) */ EMIT_1F, EMIT_1F_PSIZE, /**< insert constant point size */ EMIT_2F, diff --git a/src/gallium/auxiliary/draw/draw_vf.c b/src/gallium/auxiliary/draw/draw_vf.c index 7bb34ace7a..9d0154c50d 100644 --- a/src/gallium/auxiliary/draw/draw_vf.c +++ b/src/gallium/auxiliary/draw/draw_vf.c @@ -205,7 +205,7 @@ void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, const struct vertex_info *vinfo, float point_size ) { - unsigned i, j, k; + unsigned i, j; struct draw_vf_attr *a = vf->attr; struct draw_vf_attr_map attrs[PIPE_MAX_SHADER_INPUTS]; unsigned count = 0; /* for debug/sanity */ @@ -217,60 +217,6 @@ void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, case EMIT_OMIT: /* no-op */ break; - case EMIT_ALL: { - /* just copy the whole vertex as-is to the vbuf */ - unsigned s = vinfo->size; - assert(i == 0); - assert(j == 0); - /* copy the vertex header */ - /* XXX: we actually don't copy the header, just pad it */ - attrs[nr_attrs].attrib = 0; - attrs[nr_attrs].format = DRAW_EMIT_PAD; - attrs[nr_attrs].offset = offsetof(struct vertex_header, data); - s -= offsetof(struct vertex_header, data)/4; - count += offsetof(struct vertex_header, data)/4; - nr_attrs++; - /* copy the vertex data */ - for(k = 0; k < (s & ~0x3); k += 4) { - attrs[nr_attrs].attrib = k/4; - attrs[nr_attrs].format = DRAW_EMIT_4F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 4; - } - /* tail */ - /* XXX: actually, this shouldn't be needed */ - attrs[nr_attrs].attrib = k/4; - attrs[nr_attrs].offset = 0; - switch(s & 0x3) { - case 0: - break; - case 1: - attrs[nr_attrs].format = DRAW_EMIT_1F; - nr_attrs++; - count += 1; - break; - case 2: - attrs[nr_attrs].format = DRAW_EMIT_2F; - nr_attrs++; - count += 2; - break; - case 3: - attrs[nr_attrs].format = DRAW_EMIT_3F; - nr_attrs++; - count += 3; - break; - } - break; - } - case EMIT_HEADER: - /* XXX emit new DRAW_EMIT_HEADER attribute??? */ - attrs[nr_attrs].attrib = 0; - attrs[nr_attrs].format = DRAW_EMIT_PAD; - attrs[nr_attrs].offset = offsetof(struct vertex_header, data); - count += offsetof(struct vertex_header, data)/4; - nr_attrs++; - break; case EMIT_1F: attrs[nr_attrs].attrib = j; attrs[nr_attrs].format = DRAW_EMIT_1F; diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index 19dfd8c1a7..120bdfd9dd 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -27,6 +27,7 @@ C_SOURCES = \ sp_quad_stencil.c \ sp_quad_stipple.c \ sp_screen.c \ + sp_setup.c \ sp_state_blend.c \ sp_state_clip.c \ sp_state_derived.c \ diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index 06931fa8d8..c1f7daa8ab 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -14,6 +14,7 @@ softpipe = env.ConvenienceLibrary( 'sp_flush.c', 'sp_prim_setup.c', 'sp_prim_vbuf.c', + 'sp_setup.c', 'sp_quad_alpha_test.c', 'sp_quad_blend.c', 'sp_quad.c', diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index c7eb12b3bb..6fe463b74c 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -26,7 +26,9 @@ **************************************************************************/ /** - * \brief Primitive rasterization/rendering (points, lines, triangles) + * \brief A draw stage that drives our triangle setup routines from + * within the draw pipeline. One of two ways to drive setup, the + * other being in sp_prim_vbuf.c. * * \author Keith Whitwell * \author Brian Paul @@ -34,29 +36,12 @@ #include "sp_context.h" -#include "sp_headers.h" -#include "sp_quad.h" +#include "sp_setup.h" #include "sp_state.h" #include "sp_prim_setup.h" #include "draw/draw_private.h" #include "draw/draw_vertex.h" #include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" - -#define DEBUG_VERTS 0 -#define DEBUG_FRAGS 0 - -/** - * Triangle edge info - */ -struct edge { - float dx; /**< X(v1) - X(v0), used only during setup */ - float dy; /**< Y(v1) - Y(v0), used only during setup */ - float dxdy; /**< dx/dy */ - float sx, sy; /**< first sample point coord */ - int lines; /**< number of lines on this edge */ -}; - /** * Triangle setup info (derived from draw_stage). @@ -65,39 +50,7 @@ struct edge { struct setup_stage { struct draw_stage stage; /**< This must be first (base class) */ - struct softpipe_context *softpipe; - - /* Vertices are just an array of floats making up each attribute in - * turn. Currently fixed at 4 floats, but should change in time. - * Codegen will help cope with this. - */ - const struct vertex_header *vmax; - const struct vertex_header *vmid; - const struct vertex_header *vmin; - const struct vertex_header *vprovoke; - - struct edge ebot; - struct edge etop; - struct edge emaj; - - float oneoverarea; - - struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS]; - struct tgsi_interp_coef posCoef; /* For Z, W */ - struct quad_header quad; - - struct { - int left[2]; /**< [0] = row0, [1] = row1 */ - int right[2]; - int y; - unsigned y_flags; - unsigned mask; /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */ - } span; - -#if DEBUG_FRAGS - uint numFragsEmitted; /**< per primitive */ - uint numFragsWritten; /**< per primitive */ -#endif + struct setup_context *setup; }; @@ -111,1112 +64,50 @@ static INLINE struct setup_stage *setup_stage( struct draw_stage *stage ) } -/** - * Clip setup->quad against the scissor/surface bounds. - */ -static INLINE void -quad_clip(struct setup_stage *setup) -{ - const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect; - const int minx = (int) cliprect->minx; - const int maxx = (int) cliprect->maxx; - const int miny = (int) cliprect->miny; - const int maxy = (int) cliprect->maxy; - - if (setup->quad.x0 >= maxx || - setup->quad.y0 >= maxy || - setup->quad.x0 + 1 < minx || - setup->quad.y0 + 1 < miny) { - /* totally clipped */ - setup->quad.mask = 0x0; - return; - } - if (setup->quad.x0 < minx) - setup->quad.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); - if (setup->quad.y0 < miny) - setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); - if (setup->quad.x0 == maxx - 1) - setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); - if (setup->quad.y0 == maxy - 1) - setup->quad.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); -} - - -/** - * Emit a quad (pass to next stage) with clipping. - */ -static INLINE void -clip_emit_quad(struct setup_stage *setup) -{ - quad_clip(setup); - if (setup->quad.mask) { - struct softpipe_context *sp = setup->softpipe; - sp->quad.first->run(sp->quad.first, &setup->quad); - } -} - - -/** - * Emit a quad (pass to next stage). No clipping is done. - */ -static INLINE void -emit_quad( struct setup_stage *setup, int x, int y, unsigned mask ) -{ - struct softpipe_context *sp = setup->softpipe; - setup->quad.x0 = x; - setup->quad.y0 = y; - setup->quad.mask = mask; -#if DEBUG_FRAGS - if (mask & 1) setup->numFragsEmitted++; - if (mask & 2) setup->numFragsEmitted++; - if (mask & 4) setup->numFragsEmitted++; - if (mask & 8) setup->numFragsEmitted++; -#endif - sp->quad.first->run(sp->quad.first, &setup->quad); -#if DEBUG_FRAGS - mask = setup->quad.mask; - if (mask & 1) setup->numFragsWritten++; - if (mask & 2) setup->numFragsWritten++; - if (mask & 4) setup->numFragsWritten++; - if (mask & 8) setup->numFragsWritten++; -#endif -} - - -/** - * Given an X or Y coordinate, return the block/quad coordinate that it - * belongs to. - */ -static INLINE int block( int x ) -{ - return x & ~1; -} - - -/** - * Compute mask which indicates which pixels in the 2x2 quad are actually inside - * the triangle's bounds. - * - * this is pretty nasty... may need to rework flush_spans again to - * fix it, if possible. - */ -static unsigned calculate_mask( struct setup_stage *setup, int x ) -{ - unsigned mask = 0x0; - - if (x >= setup->span.left[0] && x < setup->span.right[0]) - mask |= MASK_TOP_LEFT; - - if (x >= setup->span.left[1] && x < setup->span.right[1]) - mask |= MASK_BOTTOM_LEFT; - - if (x+1 >= setup->span.left[0] && x+1 < setup->span.right[0]) - mask |= MASK_TOP_RIGHT; - - if (x+1 >= setup->span.left[1] && x+1 < setup->span.right[1]) - mask |= MASK_BOTTOM_RIGHT; - - return mask; -} - - -/** - * Render a horizontal span of quads - */ -static void flush_spans( struct setup_stage *setup ) -{ - int minleft, maxright; - int x; - - switch (setup->span.y_flags) { - case 0x3: - /* both odd and even lines written (both quad rows) */ - minleft = MIN2(setup->span.left[0], setup->span.left[1]); - maxright = MAX2(setup->span.right[0], setup->span.right[1]); - break; - - case 0x1: - /* only even line written (quad top row) */ - minleft = setup->span.left[0]; - maxright = setup->span.right[0]; - break; - - case 0x2: - /* only odd line written (quad bottom row) */ - minleft = setup->span.left[1]; - maxright = setup->span.right[1]; - break; - - default: - return; - } - - /* XXX this loop could be moved into the above switch cases and - * calculate_mask() could be simplified a bit... - */ - for (x = block(minleft); x <= block(maxright); x += 2) { - emit_quad( setup, x, setup->span.y, - calculate_mask( setup, x ) ); - } - - setup->span.y = 0; - setup->span.y_flags = 0; - setup->span.right[0] = 0; - setup->span.right[1] = 0; -} - -#if DEBUG_VERTS -static void print_vertex(const struct setup_stage *setup, - const struct vertex_header *v) -{ - int i; - debug_printf("Vertex: (%p)\n", v); - for (i = 0; i < setup->quad.nr_attrs; i++) { - debug_printf(" %d: %f %f %f %f\n", i, - v->data[i][0], v->data[i][1], v->data[i][2], v->data[i][3]); - } -} -#endif - -static boolean setup_sort_vertices( struct setup_stage *setup, - const struct prim_header *prim ) -{ - const struct vertex_header *v0 = prim->v[0]; - const struct vertex_header *v1 = prim->v[1]; - const struct vertex_header *v2 = prim->v[2]; - -#if DEBUG_VERTS - debug_printf("Triangle:\n"); - print_vertex(setup, v0); - print_vertex(setup, v1); - print_vertex(setup, v2); -#endif - - setup->vprovoke = v2; - - /* determine bottom to top order of vertices */ - { - float y0 = v0->data[0][1]; - float y1 = v1->data[0][1]; - float y2 = v2->data[0][1]; - if (y0 <= y1) { - if (y1 <= y2) { - /* y0<=y1<=y2 */ - setup->vmin = v0; - setup->vmid = v1; - setup->vmax = v2; - } - else if (y2 <= y0) { - /* y2<=y0<=y1 */ - setup->vmin = v2; - setup->vmid = v0; - setup->vmax = v1; - } - else { - /* y0<=y2<=y1 */ - setup->vmin = v0; - setup->vmid = v2; - setup->vmax = v1; - } - } - else { - if (y0 <= y2) { - /* y1<=y0<=y2 */ - setup->vmin = v1; - setup->vmid = v0; - setup->vmax = v2; - } - else if (y2 <= y1) { - /* y2<=y1<=y0 */ - setup->vmin = v2; - setup->vmid = v1; - setup->vmax = v0; - } - else { - /* y1<=y2<=y0 */ - setup->vmin = v1; - setup->vmid = v2; - setup->vmax = v0; - } - } - } - - setup->ebot.dx = setup->vmid->data[0][0] - setup->vmin->data[0][0]; - setup->ebot.dy = setup->vmid->data[0][1] - setup->vmin->data[0][1]; - setup->emaj.dx = setup->vmax->data[0][0] - setup->vmin->data[0][0]; - setup->emaj.dy = setup->vmax->data[0][1] - setup->vmin->data[0][1]; - setup->etop.dx = setup->vmax->data[0][0] - setup->vmid->data[0][0]; - setup->etop.dy = setup->vmax->data[0][1] - setup->vmid->data[0][1]; - - /* - * Compute triangle's area. Use 1/area to compute partial - * derivatives of attributes later. - * - * The area will be the same as prim->det, but the sign may be - * different depending on how the vertices get sorted above. - * - * To determine whether the primitive is front or back facing we - * use the prim->det value because its sign is correct. - */ - { - const float area = (setup->emaj.dx * setup->ebot.dy - - setup->ebot.dx * setup->emaj.dy); - - setup->oneoverarea = 1.0f / area; - /* - debug_printf("%s one-over-area %f area %f det %f\n", - __FUNCTION__, setup->oneoverarea, area, prim->det ); - */ - } - - /* We need to know if this is a front or back-facing triangle for: - * - the GLSL gl_FrontFacing fragment attribute (bool) - * - two-sided stencil test - */ - setup->quad.facing = (prim->det > 0.0) ^ (setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW); - - return TRUE; -} - - -/** - * Compute a0 for a constant-valued coefficient (GL_FLAT shading). - * The value value comes from vertex->data[slot][i]. - * The result will be put into setup->coef[slot].a0[i]. - * \param slot which attribute slot - * \param i which component of the slot (0..3) - */ -static void const_coeff( struct setup_stage *setup, - struct tgsi_interp_coef *coef, - uint vertSlot, uint i) -{ - assert(i <= 3); - - coef->dadx[i] = 0; - coef->dady[i] = 0; - /* need provoking vertex info! - */ - coef->a0[i] = setup->vprovoke->data[vertSlot][i]; -} - - -/** - * Compute a0, dadx and dady for a linearly interpolated coefficient, - * for a triangle. - */ -static void tri_linear_coeff( struct setup_stage *setup, - struct tgsi_interp_coef *coef, - uint vertSlot, uint i) -{ - float botda = setup->vmid->data[vertSlot][i] - setup->vmin->data[vertSlot][i]; - float majda = setup->vmax->data[vertSlot][i] - setup->vmin->data[vertSlot][i]; - float a = setup->ebot.dy * majda - botda * setup->emaj.dy; - float b = setup->emaj.dx * botda - majda * setup->ebot.dx; - float dadx = a * setup->oneoverarea; - float dady = b * setup->oneoverarea; - - assert(i <= 3); - - coef->dadx[i] = dadx; - coef->dady[i] = dady; - - /* calculate a0 as the value which would be sampled for the - * fragment at (0,0), taking into account that we want to sample at - * pixel centers, in other words (0.5, 0.5). - * - * this is neat but unfortunately not a good way to do things for - * triangles with very large values of dadx or dady as it will - * result in the subtraction and re-addition from a0 of a very - * large number, which means we'll end up loosing a lot of the - * fractional bits and precision from a0. the way to fix this is - * to define a0 as the sample at a pixel center somewhere near vmin - * instead - i'll switch to this later. - */ - coef->a0[i] = (setup->vmin->data[vertSlot][i] - - (dadx * (setup->vmin->data[0][0] - 0.5f) + - dady * (setup->vmin->data[0][1] - 0.5f))); - - /* - debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", - slot, "xyzw"[i], - setup->coef[slot].a0[i], - setup->coef[slot].dadx[i], - setup->coef[slot].dady[i]); - */ -} - - -/** - * Compute a0, dadx and dady for a perspective-corrected interpolant, - * for a triangle. - * We basically multiply the vertex value by 1/w before computing - * the plane coefficients (a0, dadx, dady). - * Later, when we compute the value at a particular fragment position we'll - * divide the interpolated value by the interpolated W at that fragment. - */ -static void tri_persp_coeff( struct setup_stage *setup, - struct tgsi_interp_coef *coef, - uint vertSlot, uint i) -{ - /* premultiply by 1/w (v->data[0][3] is always W): - */ - float mina = setup->vmin->data[vertSlot][i] * setup->vmin->data[0][3]; - float mida = setup->vmid->data[vertSlot][i] * setup->vmid->data[0][3]; - float maxa = setup->vmax->data[vertSlot][i] * setup->vmax->data[0][3]; - float botda = mida - mina; - float majda = maxa - mina; - float a = setup->ebot.dy * majda - botda * setup->emaj.dy; - float b = setup->emaj.dx * botda - majda * setup->ebot.dx; - float dadx = a * setup->oneoverarea; - float dady = b * setup->oneoverarea; - - /* - debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i, - setup->vmin->data[vertSlot][i], - setup->vmid->data[vertSlot][i], - setup->vmax->data[vertSlot][i] - ); - */ - assert(i <= 3); - - coef->dadx[i] = dadx; - coef->dady[i] = dady; - coef->a0[i] = (mina - - (dadx * (setup->vmin->data[0][0] - 0.5f) + - dady * (setup->vmin->data[0][1] - 0.5f))); -} - - -/** - * Special coefficient setup for gl_FragCoord. - * X and Y are trivial, though Y has to be inverted for OpenGL. - * Z and W are copied from posCoef which should have already been computed. - * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. - */ static void -setup_fragcoord_coeff(struct setup_stage *setup, uint slot) -{ - /*X*/ - setup->coef[slot].a0[0] = 0; - setup->coef[slot].dadx[0] = 1.0; - setup->coef[slot].dady[0] = 0.0; - /*Y*/ - if (setup->softpipe->rasterizer->origin_lower_left) { - /* y=0=bottom */ - const int winHeight = setup->softpipe->framebuffer.height; - setup->coef[slot].a0[1] = (float) (winHeight - 1); - setup->coef[slot].dady[1] = -1.0; - } - else { - /* y=0=top */ - setup->coef[slot].a0[1] = 0.0; - setup->coef[slot].dady[1] = 1.0; - } - setup->coef[slot].dadx[1] = 0.0; - /*Z*/ - setup->coef[slot].a0[2] = setup->posCoef.a0[2]; - setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; - setup->coef[slot].dady[2] = setup->posCoef.dady[2]; - /*W*/ - setup->coef[slot].a0[3] = setup->posCoef.a0[3]; - setup->coef[slot].dadx[3] = setup->posCoef.dadx[3]; - setup->coef[slot].dady[3] = setup->posCoef.dady[3]; -} - - - -/** - * Compute the setup->coef[] array dadx, dady, a0 values. - * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized. - */ -static void setup_tri_coefficients( struct setup_stage *setup ) -{ - struct softpipe_context *softpipe = setup->softpipe; - const struct sp_fragment_shader *spfs = softpipe->fs; - const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); - uint fragSlot; - - /* z and w are done by linear interpolation: - */ - tri_linear_coeff(setup, &setup->posCoef, 0, 2); - tri_linear_coeff(setup, &setup->posCoef, 0, 3); - - /* setup interpolation for all the remaining attributes: - */ - for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { - const uint vertSlot = vinfo->src_index[fragSlot]; - uint j; - - switch (vinfo->interp_mode[fragSlot]) { - case INTERP_CONSTANT: - for (j = 0; j < NUM_CHANNELS; j++) - const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_LINEAR: - for (j = 0; j < NUM_CHANNELS; j++) - tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_PERSPECTIVE: - for (j = 0; j < NUM_CHANNELS; j++) - tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_POS: - setup_fragcoord_coeff(setup, fragSlot); - break; - default: - assert(0); - } - - if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { - /* FOG.y = front/back facing XXX fix this */ - setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; - setup->coef[fragSlot].dadx[1] = 0.0; - setup->coef[fragSlot].dady[1] = 0.0; - } - } -} - - - -static void setup_tri_edges( struct setup_stage *setup ) -{ - float vmin_x = setup->vmin->data[0][0] + 0.5f; - float vmid_x = setup->vmid->data[0][0] + 0.5f; - - float vmin_y = setup->vmin->data[0][1] - 0.5f; - float vmid_y = setup->vmid->data[0][1] - 0.5f; - float vmax_y = setup->vmax->data[0][1] - 0.5f; - - setup->emaj.sy = CEILF(vmin_y); - setup->emaj.lines = (int) CEILF(vmax_y - setup->emaj.sy); - setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy; - setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; - - setup->etop.sy = CEILF(vmid_y); - setup->etop.lines = (int) CEILF(vmax_y - setup->etop.sy); - setup->etop.dxdy = setup->etop.dx / setup->etop.dy; - setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; - - setup->ebot.sy = CEILF(vmin_y); - setup->ebot.lines = (int) CEILF(vmid_y - setup->ebot.sy); - setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy; - setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; -} - - -/** - * Render the upper or lower half of a triangle. - * Scissoring/cliprect is applied here too. - */ -static void subtriangle( struct setup_stage *setup, - struct edge *eleft, - struct edge *eright, - unsigned lines ) -{ - const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect; - const int minx = (int) cliprect->minx; - const int maxx = (int) cliprect->maxx; - const int miny = (int) cliprect->miny; - const int maxy = (int) cliprect->maxy; - int y, start_y, finish_y; - int sy = (int)eleft->sy; - - assert((int)eleft->sy == (int) eright->sy); - - /* clip top/bottom */ - start_y = sy; - finish_y = sy + lines; - - if (start_y < miny) - start_y = miny; - - if (finish_y > maxy) - finish_y = maxy; - - start_y -= sy; - finish_y -= sy; - - /* - debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); - */ - - for (y = start_y; y < finish_y; y++) { - - /* avoid accumulating adds as floats don't have the precision to - * accurately iterate large triangle edges that way. luckily we - * can just multiply these days. - * - * this is all drowned out by the attribute interpolation anyway. - */ - int left = (int)(eleft->sx + y * eleft->dxdy); - int right = (int)(eright->sx + y * eright->dxdy); - - /* clip left/right */ - if (left < minx) - left = minx; - if (right > maxx) - right = maxx; - - if (left < right) { - int _y = sy + y; - if (block(_y) != setup->span.y) { - flush_spans(setup); - setup->span.y = block(_y); - } - - setup->span.left[_y&1] = left; - setup->span.right[_y&1] = right; - setup->span.y_flags |= 1<<(_y&1); - } - } - - - /* save the values so that emaj can be restarted: - */ - eleft->sx += lines * eleft->dxdy; - eright->sx += lines * eright->dxdy; - eleft->sy += lines; - eright->sy += lines; -} - - -/** - * Do setup for triangle rasterization, then render the triangle. - */ -static void setup_tri( struct draw_stage *stage, - struct prim_header *prim ) +do_tri(struct draw_stage *stage, struct prim_header *prim) { struct setup_stage *setup = setup_stage( stage ); - /* - debug_printf("%s\n", __FUNCTION__ ); - */ - -#if DEBUG_FRAGS - setup->numFragsEmitted = 0; - setup->numFragsWritten = 0; -#endif - - setup_sort_vertices( setup, prim ); - setup_tri_coefficients( setup ); - setup_tri_edges( setup ); - - setup->quad.prim = PRIM_TRI; - - setup->span.y = 0; - setup->span.y_flags = 0; - setup->span.right[0] = 0; - setup->span.right[1] = 0; - /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ - - /* init_constant_attribs( setup ); */ - - if (setup->oneoverarea < 0.0) { - /* emaj on left: - */ - subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); - subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); - } - else { - /* emaj on right: - */ - subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); - subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); - } - - flush_spans( setup ); - -#if DEBUG_FRAGS - printf("Tri: %u frags emitted, %u written\n", - setup->numFragsEmitted, - setup->numFragsWritten); -#endif -} - - - -/** - * Compute a0, dadx and dady for a linearly interpolated coefficient, - * for a line. - */ -static void -line_linear_coeff(struct setup_stage *setup, - struct tgsi_interp_coef *coef, - uint vertSlot, uint i) -{ - const float da = setup->vmax->data[vertSlot][i] - setup->vmin->data[vertSlot][i]; - const float dadx = da * setup->emaj.dx * setup->oneoverarea; - const float dady = da * setup->emaj.dy * setup->oneoverarea; - coef->dadx[i] = dadx; - coef->dady[i] = dady; - coef->a0[i] = (setup->vmin->data[vertSlot][i] - - (dadx * (setup->vmin->data[0][0] - 0.5f) + - dady * (setup->vmin->data[0][1] - 0.5f))); -} - - -/** - * Compute a0, dadx and dady for a perspective-corrected interpolant, - * for a line. - */ -static void -line_persp_coeff(struct setup_stage *setup, - struct tgsi_interp_coef *coef, - uint vertSlot, uint i) -{ - /* XXX double-check/verify this arithmetic */ - const float a0 = setup->vmin->data[vertSlot][i] * setup->vmin->data[0][3]; - const float a1 = setup->vmax->data[vertSlot][i] * setup->vmax->data[0][3]; - const float da = a1 - a0; - const float dadx = da * setup->emaj.dx * setup->oneoverarea; - const float dady = da * setup->emaj.dy * setup->oneoverarea; - coef->dadx[i] = dadx; - coef->dady[i] = dady; - coef->a0[i] = (setup->vmin->data[vertSlot][i] - - (dadx * (setup->vmin->data[0][0] - 0.5f) + - dady * (setup->vmin->data[0][1] - 0.5f))); -} - - -/** - * Compute the setup->coef[] array dadx, dady, a0 values. - * Must be called after setup->vmin,vmax are initialized. - */ -static INLINE void -setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim) -{ - struct softpipe_context *softpipe = setup->softpipe; - const struct sp_fragment_shader *spfs = softpipe->fs; - const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); - uint fragSlot; - - /* use setup->vmin, vmax to point to vertices */ - setup->vprovoke = prim->v[1]; - setup->vmin = prim->v[0]; - setup->vmax = prim->v[1]; - - setup->emaj.dx = setup->vmax->data[0][0] - setup->vmin->data[0][0]; - setup->emaj.dy = setup->vmax->data[0][1] - setup->vmin->data[0][1]; - /* NOTE: this is not really 1/area */ - setup->oneoverarea = 1.0f / (setup->emaj.dx * setup->emaj.dx + - setup->emaj.dy * setup->emaj.dy); - - /* z and w are done by linear interpolation: - */ - line_linear_coeff(setup, &setup->posCoef, 0, 2); - line_linear_coeff(setup, &setup->posCoef, 0, 3); - - /* setup interpolation for all the remaining attributes: - */ - for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { - const uint vertSlot = vinfo->src_index[fragSlot]; - uint j; - - switch (vinfo->interp_mode[fragSlot]) { - case INTERP_CONSTANT: - for (j = 0; j < NUM_CHANNELS; j++) - const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_LINEAR: - for (j = 0; j < NUM_CHANNELS; j++) - line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_PERSPECTIVE: - for (j = 0; j < NUM_CHANNELS; j++) - line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_POS: - setup_fragcoord_coeff(setup, fragSlot); - break; - default: - assert(0); - } - - if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { - /* FOG.y = front/back facing XXX fix this */ - setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; - setup->coef[fragSlot].dadx[1] = 0.0; - setup->coef[fragSlot].dady[1] = 0.0; - } - } + setup_tri( setup->setup, + prim->det, + prim->v[0]->data, + prim->v[1]->data, + prim->v[2]->data ); } - -/** - * Plot a pixel in a line segment. - */ -static INLINE void -plot(struct setup_stage *setup, int x, int y) -{ - const int iy = y & 1; - const int ix = x & 1; - const int quadX = x - ix; - const int quadY = y - iy; - const int mask = (1 << ix) << (2 * iy); - - if (quadX != setup->quad.x0 || - quadY != setup->quad.y0) - { - /* flush prev quad, start new quad */ - - if (setup->quad.x0 != -1) - clip_emit_quad(setup); - - setup->quad.x0 = quadX; - setup->quad.y0 = quadY; - setup->quad.mask = 0x0; - } - - setup->quad.mask |= mask; -} - - -/** - * Do setup for line rasterization, then render the line. - * Single-pixel width, no stipple, etc. We rely on the 'draw' module - * to handle stippling and wide lines. - */ static void -setup_line(struct draw_stage *stage, struct prim_header *prim) +do_line(struct draw_stage *stage, struct prim_header *prim) { - const struct vertex_header *v0 = prim->v[0]; - const struct vertex_header *v1 = prim->v[1]; struct setup_stage *setup = setup_stage( stage ); - int x0 = (int) v0->data[0][0]; - int x1 = (int) v1->data[0][0]; - int y0 = (int) v0->data[0][1]; - int y1 = (int) v1->data[0][1]; - int dx = x1 - x0; - int dy = y1 - y0; - int xstep, ystep; - if (dx == 0 && dy == 0) - return; - - setup_line_coefficients(setup, prim); - - if (dx < 0) { - dx = -dx; /* make positive */ - xstep = -1; - } - else { - xstep = 1; - } - - if (dy < 0) { - dy = -dy; /* make positive */ - ystep = -1; - } - else { - ystep = 1; - } - - assert(dx >= 0); - assert(dy >= 0); - - setup->quad.x0 = setup->quad.y0 = -1; - setup->quad.mask = 0x0; - setup->quad.prim = PRIM_LINE; - /* XXX temporary: set coverage to 1.0 so the line appears - * if AA mode happens to be enabled. - */ - setup->quad.coverage[0] = - setup->quad.coverage[1] = - setup->quad.coverage[2] = - setup->quad.coverage[3] = 1.0; - - if (dx > dy) { - /*** X-major line ***/ - int i; - const int errorInc = dy + dy; - int error = errorInc - dx; - const int errorDec = error - dx; - - for (i = 0; i < dx; i++) { - plot(setup, x0, y0); - - x0 += xstep; - if (error < 0) { - error += errorInc; - } - else { - error += errorDec; - y0 += ystep; - } - } - } - else { - /*** Y-major line ***/ - int i; - const int errorInc = dx + dx; - int error = errorInc - dy; - const int errorDec = error - dy; - - for (i = 0; i < dy; i++) { - plot(setup, x0, y0); - - y0 += ystep; - if (error < 0) { - error += errorInc; - } - else { - error += errorDec; - x0 += xstep; - } - } - } - - /* draw final quad */ - if (setup->quad.mask) { - clip_emit_quad(setup); - } + setup_line( setup->setup, + prim->v[0]->data, + prim->v[1]->data ); } - static void -point_persp_coeff(struct setup_stage *setup, - const struct vertex_header *vert, - struct tgsi_interp_coef *coef, - uint vertSlot, uint i) -{ - assert(i <= 3); - coef->dadx[i] = 0.0F; - coef->dady[i] = 0.0F; - coef->a0[i] = vert->data[vertSlot][i] * vert->data[0][3]; -} - - -/** - * Do setup for point rasterization, then render the point. - * Round or square points... - * XXX could optimize a lot for 1-pixel points. - */ -static void -setup_point(struct draw_stage *stage, struct prim_header *prim) +do_point(struct draw_stage *stage, struct prim_header *prim) { struct setup_stage *setup = setup_stage( stage ); - struct softpipe_context *softpipe = setup->softpipe; - const struct sp_fragment_shader *spfs = softpipe->fs; - const struct vertex_header *v0 = prim->v[0]; - const int sizeAttr = setup->softpipe->psize_slot; - const float size - = sizeAttr > 0 ? v0->data[sizeAttr][0] - : setup->softpipe->rasterizer->point_size; - const float halfSize = 0.5F * size; - const boolean round = (boolean) setup->softpipe->rasterizer->point_smooth; - const float x = v0->data[0][0]; /* Note: data[0] is always position */ - const float y = v0->data[0][1]; - const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); - uint fragSlot; - - /* For points, all interpolants are constant-valued. - * However, for point sprites, we'll need to setup texcoords appropriately. - * XXX: which coefficients are the texcoords??? - * We may do point sprites as textured quads... - * - * KW: We don't know which coefficients are texcoords - ultimately - * the choice of what interpolation mode to use for each attribute - * should be determined by the fragment program, using - * per-attribute declaration statements that include interpolation - * mode as a parameter. So either the fragment program will have - * to be adjusted for pointsprite vs normal point behaviour, or - * otherwise a special interpolation mode will have to be defined - * which matches the required behaviour for point sprites. But - - * the latter is not a feature of normal hardware, and as such - * probably should be ruled out on that basis. - */ - setup->vprovoke = prim->v[0]; - - /* setup Z, W */ - const_coeff(setup, &setup->posCoef, 0, 2); - const_coeff(setup, &setup->posCoef, 0, 3); - - for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { - const uint vertSlot = vinfo->src_index[fragSlot]; - uint j; - - switch (vinfo->interp_mode[fragSlot]) { - case INTERP_CONSTANT: - /* fall-through */ - case INTERP_LINEAR: - for (j = 0; j < NUM_CHANNELS; j++) - const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_PERSPECTIVE: - for (j = 0; j < NUM_CHANNELS; j++) - point_persp_coeff(setup, setup->vprovoke, - &setup->coef[fragSlot], vertSlot, j); - break; - case INTERP_POS: - setup_fragcoord_coeff(setup, fragSlot); - break; - default: - assert(0); - } - - if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { - /* FOG.y = front/back facing XXX fix this */ - setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; - setup->coef[fragSlot].dadx[1] = 0.0; - setup->coef[fragSlot].dady[1] = 0.0; - } - } - - setup->quad.prim = PRIM_POINT; - - if (halfSize <= 0.5 && !round) { - /* special case for 1-pixel points */ - const int ix = ((int) x) & 1; - const int iy = ((int) y) & 1; - setup->quad.x0 = (int) x - ix; - setup->quad.y0 = (int) y - iy; - setup->quad.mask = (1 << ix) << (2 * iy); - clip_emit_quad(setup); - } - else { - if (round) { - /* rounded points */ - const int ixmin = block((int) (x - halfSize)); - const int ixmax = block((int) (x + halfSize)); - const int iymin = block((int) (y - halfSize)); - const int iymax = block((int) (y + halfSize)); - const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ - const float rmax = halfSize + 0.7071F; - const float rmin2 = MAX2(0.0F, rmin * rmin); - const float rmax2 = rmax * rmax; - const float cscale = 1.0F / (rmax2 - rmin2); - int ix, iy; - - for (iy = iymin; iy <= iymax; iy += 2) { - for (ix = ixmin; ix <= ixmax; ix += 2) { - float dx, dy, dist2, cover; - - setup->quad.mask = 0x0; - - dx = (ix + 0.5f) - x; - dy = (iy + 0.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); - setup->quad.mask |= MASK_TOP_LEFT; - } - - dx = (ix + 1.5f) - x; - dy = (iy + 0.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); - setup->quad.mask |= MASK_TOP_RIGHT; - } - dx = (ix + 0.5f) - x; - dy = (iy + 1.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); - setup->quad.mask |= MASK_BOTTOM_LEFT; - } - - dx = (ix + 1.5f) - x; - dy = (iy + 1.5f) - y; - dist2 = dx * dx + dy * dy; - if (dist2 <= rmax2) { - cover = 1.0F - (dist2 - rmin2) * cscale; - setup->quad.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); - setup->quad.mask |= MASK_BOTTOM_RIGHT; - } - - if (setup->quad.mask) { - setup->quad.x0 = ix; - setup->quad.y0 = iy; - clip_emit_quad(setup); - } - } - } - } - else { - /* square points */ - const int xmin = (int) (x + 0.75 - halfSize); - const int ymin = (int) (y + 0.25 - halfSize); - const int xmax = xmin + (int) size; - const int ymax = ymin + (int) size; - /* XXX could apply scissor to xmin,ymin,xmax,ymax now */ - const int ixmin = block(xmin); - const int ixmax = block(xmax - 1); - const int iymin = block(ymin); - const int iymax = block(ymax - 1); - int ix, iy; - - /* - debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax); - */ - for (iy = iymin; iy <= iymax; iy += 2) { - uint rowMask = 0xf; - if (iy < ymin) { - /* above the top edge */ - rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); - } - if (iy + 1 >= ymax) { - /* below the bottom edge */ - rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); - } - - for (ix = ixmin; ix <= ixmax; ix += 2) { - uint mask = rowMask; - - if (ix < xmin) { - /* fragment is past left edge of point, turn off left bits */ - mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); - } - if (ix + 1 >= xmax) { - /* past the right edge */ - mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); - } - - setup->quad.mask = mask; - setup->quad.x0 = ix; - setup->quad.y0 = iy; - clip_emit_quad(setup); - } - } - } - } + setup_point( setup->setup, + prim->v[0]->data ); } + static void setup_begin( struct draw_stage *stage ) { struct setup_stage *setup = setup_stage(stage); - struct softpipe_context *sp = setup->softpipe; - const struct sp_fragment_shader *fs = setup->softpipe->fs; - uint i; - - if (sp->dirty) { - softpipe_update_derived(sp); - } - /* Mark surfaces as defined now */ - for (i = 0; i < sp->framebuffer.num_cbufs; i++){ - if (sp->framebuffer.cbufs[i]) { - sp->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; - } - } - if (sp->framebuffer.zsbuf) { - sp->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; - } + setup_prepare( setup->setup ); - setup->quad.nr_attrs = fs->info.num_inputs; - - sp->quad.first->begin(sp->quad.first); - - stage->point = setup_point; - stage->line = setup_line; - stage->tri = setup_tri; + stage->point = do_point; + stage->line = do_line; + stage->tri = do_tri; } @@ -1269,19 +160,29 @@ static void render_destroy( struct draw_stage *stage ) */ struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe ) { - struct setup_stage *setup = CALLOC_STRUCT(setup_stage); + struct setup_stage *sstage = CALLOC_STRUCT(setup_stage); - setup->softpipe = softpipe; - setup->stage.draw = softpipe->draw; - setup->stage.point = setup_first_point; - setup->stage.line = setup_first_line; - setup->stage.tri = setup_first_tri; - setup->stage.flush = setup_flush; - setup->stage.reset_stipple_counter = reset_stipple_counter; - setup->stage.destroy = render_destroy; + sstage->setup = setup_create_context(softpipe); + sstage->stage.draw = softpipe->draw; + sstage->stage.point = setup_first_point; + sstage->stage.line = setup_first_line; + sstage->stage.tri = setup_first_tri; + sstage->stage.flush = setup_flush; + sstage->stage.reset_stipple_counter = reset_stipple_counter; + sstage->stage.destroy = render_destroy; - setup->quad.coef = setup->coef; - setup->quad.posCoef = &setup->posCoef; + return (struct draw_stage *)sstage; +} - return &setup->stage; +struct setup_context * +sp_draw_setup_context( struct draw_stage *stage ) +{ + struct setup_stage *ssetup = setup_stage(stage); + return ssetup->setup; +} + +void +sp_draw_flush( struct draw_stage *stage ) +{ + stage->flush( stage, 0 ); } diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.h b/src/gallium/drivers/softpipe/sp_prim_setup.h index f3e8a79dd9..49bdd98ed8 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.h +++ b/src/gallium/drivers/softpipe/sp_prim_setup.h @@ -69,6 +69,12 @@ typedef void (*vbuf_draw_func)( struct pipe_context *pipe, extern struct draw_stage * sp_draw_render_stage( struct softpipe_context *softpipe ); +extern struct setup_context * +sp_draw_setup_context( struct draw_stage * ); + +extern void +sp_draw_flush( struct draw_stage * ); + extern struct draw_stage * sp_draw_vbuf_stage( struct draw_context *draw_context, diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index d940718ed2..025a0113bf 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ /** @@ -30,7 +30,7 @@ * softpipe rendering pipeline. * Probably not desired in general, but useful for testing/debuggin. * Enabled/Disabled with SP_VBUF env var. - * + * * Authors * Brian Paul */ @@ -39,14 +39,16 @@ #include "sp_context.h" #include "sp_state.h" #include "sp_prim_vbuf.h" +#include "sp_prim_setup.h" +#include "sp_setup.h" #include "draw/draw_context.h" -#include "draw/draw_private.h" #include "draw/draw_vbuf.h" #define SP_MAX_VBUF_INDEXES 1024 #define SP_MAX_VBUF_SIZE 4096 +typedef const float (*cptrf4)[4]; /** * Subclass of vbuf_render. @@ -69,7 +71,6 @@ softpipe_vbuf_render(struct vbuf_render *vbr) } - static const struct vertex_info * sp_vbuf_get_vertex_info(struct vbuf_render *vbr) { @@ -91,7 +92,7 @@ sp_vbuf_allocate_vertices(struct vbuf_render *vbr, static void -sp_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices, +sp_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices, unsigned vertex_size, unsigned vertices_used) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); @@ -114,7 +115,7 @@ sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) else { return FALSE; } - + } @@ -122,22 +123,19 @@ sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) * Recalculate prim's determinant. * XXX is this needed? */ -static void -calc_det(struct prim_header *header) +static float +calc_det( const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) { - /* Window coords: */ - const float *v0 = header->v[0]->data[0]; - const float *v1 = header->v[1]->data[0]; - const float *v2 = header->v[2]->data[0]; - /* edge vectors e = v0 - v2, f = v1 - v2 */ - const float ex = v0[0] - v2[0]; - const float ey = v0[1] - v2[1]; - const float fx = v1[0] - v2[0]; - const float fy = v1[1] - v2[1]; - + const float ex = v0[0][0] - v2[0][0]; + const float ey = v0[0][1] - v2[0][1]; + const float fx = v1[0][0] - v2[0][0]; + const float fy = v1[0][1] - v2[0][1]; + /* det = cross(e,f).z */ - header->det = ex * fy - ey * fx; + return ex * fy - ey * fx; } @@ -147,48 +145,51 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); struct softpipe_context *softpipe = cvbr->softpipe; struct draw_stage *setup = softpipe->setup; - struct prim_header prim; unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float); unsigned i, j; void *vertex_buffer = cvbr->vertex_buffer; - - prim.det = 0; - prim.reset_line_stipple = 0; - prim.edgeflags = 0; - prim.pad = 0; + cptrf4 v[3]; + struct setup_context *setup_ctx = sp_draw_setup_context(setup); switch (cvbr->prim) { case PIPE_PRIM_TRIANGLES: for (i = 0; i < nr_indices; i += 3) { - for (j = 0; j < 3; j++) - prim.v[j] = (struct vertex_header *)((char *)vertex_buffer + - indices[i+j] * vertex_size); - - calc_det(&prim); - setup->tri( setup, &prim ); + for (j = 0; j < 3; j++) + v[j] = (cptrf4)((char *)vertex_buffer + + indices[i+j] * vertex_size); + + setup_tri( setup_ctx, + calc_det(v[0], v[1], v[2]), + v[0], + v[1], + v[2]); } break; case PIPE_PRIM_LINES: for (i = 0; i < nr_indices; i += 2) { - for (j = 0; j < 2; j++) - prim.v[j] = (struct vertex_header *)((char *)vertex_buffer + - indices[i+j] * vertex_size); - - setup->line( setup, &prim ); + for (j = 0; j < 2; j++) + v[j] = (cptrf4)((char *)vertex_buffer + + indices[i+j] * vertex_size); + + setup_line( setup_ctx, + v[0], + v[1] ); } break; case PIPE_PRIM_POINTS: for (i = 0; i < nr_indices; i++) { - prim.v[0] = (struct vertex_header *)((char *)vertex_buffer + - indices[i] * vertex_size); - setup->point( setup, &prim ); + v[0] = (cptrf4)((char *)vertex_buffer + + indices[i] * vertex_size); + + setup_point( setup_ctx, + v[0] ); } break; } - setup->flush( setup, 0 ); + sp_draw_flush( setup ); } @@ -202,111 +203,131 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); struct softpipe_context *softpipe = cvbr->softpipe; struct draw_stage *setup = softpipe->setup; - struct prim_header prim; const void *vertex_buffer = cvbr->vertex_buffer; const unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float); unsigned i; - - prim.det = 0; - prim.reset_line_stipple = 0; - prim.edgeflags = 0; - prim.pad = 0; + struct setup_context *setup_ctx = sp_draw_setup_context(setup); + cptrf4 v[3]; #define VERTEX(I) \ - (struct vertex_header *) ((char *) vertex_buffer + (I) * vertex_size) + (cptrf4) ((char *) vertex_buffer + (I) * vertex_size) switch (cvbr->prim) { case PIPE_PRIM_POINTS: for (i = 0; i < nr; i++) { - prim.v[0] = VERTEX(i); - setup->point( setup, &prim ); + v[0] = VERTEX(i); + setup_point( setup_ctx, v[0] ); } break; case PIPE_PRIM_LINES: assert(nr % 2 == 0); for (i = 0; i < nr; i += 2) { - prim.v[0] = VERTEX(i); - prim.v[1] = VERTEX(i + 1); - setup->line( setup, &prim ); + v[0] = VERTEX(i); + v[1] = VERTEX(i + 1); + setup_line( setup_ctx, v[0], v[1] ); } break; case PIPE_PRIM_LINE_STRIP: for (i = 1; i < nr; i++) { - prim.v[0] = VERTEX(i - 1); - prim.v[1] = VERTEX(i); - setup->line( setup, &prim ); + v[0] = VERTEX(i - 1); + v[1] = VERTEX(i); + setup_line( setup_ctx, v[0], v[1] ); } break; case PIPE_PRIM_TRIANGLES: assert(nr % 3 == 0); for (i = 0; i < nr; i += 3) { - prim.v[0] = VERTEX(i + 0); - prim.v[1] = VERTEX(i + 1); - prim.v[2] = VERTEX(i + 2); - calc_det(&prim); - setup->tri( setup, &prim ); + v[0] = VERTEX(i + 0); + v[1] = VERTEX(i + 1); + v[2] = VERTEX(i + 2); + setup_tri( setup_ctx, + calc_det(v[0], v[1], v[2]), + v[0], + v[1], + v[2] ); } break; case PIPE_PRIM_TRIANGLE_STRIP: assert(nr >= 3); for (i = 2; i < nr; i++) { - prim.v[0] = VERTEX(i - 2); - prim.v[1] = VERTEX(i - 1); - prim.v[2] = VERTEX(i); - calc_det(&prim); - setup->tri( setup, &prim ); + v[0] = VERTEX(i - 2); + v[1] = VERTEX(i - 1); + v[2] = VERTEX(i); + setup_tri( setup_ctx, + calc_det(v[0], v[1], v[2]), + v[0], + v[1], + v[2] ); } break; case PIPE_PRIM_TRIANGLE_FAN: assert(nr >= 3); for (i = 2; i < nr; i++) { - prim.v[0] = VERTEX(0); - prim.v[1] = VERTEX(i - 1); - prim.v[2] = VERTEX(i); - calc_det(&prim); - setup->tri( setup, &prim ); + v[0] = VERTEX(0); + v[1] = VERTEX(i - 1); + v[2] = VERTEX(i); + setup_tri( setup_ctx, + calc_det(v[0], v[1], v[2]), + v[0], + v[1], + v[2] ); } break; case PIPE_PRIM_QUADS: assert(nr % 4 == 0); for (i = 0; i < nr; i += 4) { - prim.v[0] = VERTEX(i + 0); - prim.v[1] = VERTEX(i + 1); - prim.v[2] = VERTEX(i + 2); - calc_det(&prim); - setup->tri( setup, &prim ); - - prim.v[0] = VERTEX(i + 0); - prim.v[1] = VERTEX(i + 2); - prim.v[2] = VERTEX(i + 3); - calc_det(&prim); - setup->tri( setup, &prim ); + v[0] = VERTEX(i + 0); + v[1] = VERTEX(i + 1); + v[2] = VERTEX(i + 2); + setup_tri( setup_ctx, + calc_det(v[0], v[1], v[2]), + v[0], + v[1], + v[2] ); + + v[0] = VERTEX(i + 0); + v[1] = VERTEX(i + 2); + v[2] = VERTEX(i + 3); + setup_tri( setup_ctx, + calc_det(v[0], v[1], v[2]), + v[0], + v[1], + v[2] ); } break; case PIPE_PRIM_QUAD_STRIP: assert(nr >= 4); for (i = 2; i < nr; i += 2) { - prim.v[0] = VERTEX(i - 2); - prim.v[1] = VERTEX(i); - prim.v[2] = VERTEX(i + 1); - calc_det(&prim); - setup->tri( setup, &prim ); - - prim.v[0] = VERTEX(i - 2); - prim.v[1] = VERTEX(i + 1); - prim.v[2] = VERTEX(i - 1); - calc_det(&prim); - setup->tri( setup, &prim ); + v[0] = VERTEX(i - 2); + v[1] = VERTEX(i); + v[2] = VERTEX(i + 1); + setup_tri( setup_ctx, + calc_det(v[0], v[1], v[2]), + v[0], + v[1], + v[2] ); + + v[0] = VERTEX(i - 2); + v[1] = VERTEX(i + 1); + v[2] = VERTEX(i - 1); + setup_tri( setup_ctx, + calc_det(v[0], v[1], v[2]), + v[0], + v[1], + v[2] ); } break; case PIPE_PRIM_POLYGON: /* draw as tri fan */ for (i = 2; i < nr; i++) { - prim.v[0] = VERTEX(0); - prim.v[1] = VERTEX(i - 1); - prim.v[2] = VERTEX(i); - calc_det(&prim); - setup->tri( setup, &prim ); + v[0] = VERTEX(0); + v[1] = VERTEX(i - 1); + v[2] = VERTEX(i); + setup_tri( setup_ctx, + calc_det(v[0], v[1], v[2]), + v[0], + v[1], + v[2] ); } break; default: diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c new file mode 100644 index 0000000000..48617a66ed --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -0,0 +1,1249 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Primitive rasterization/rendering (points, lines, triangles) + * + * \author Keith Whitwell + * \author Brian Paul + */ + +#include "sp_setup.h" + +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_quad.h" +#include "sp_state.h" +#include "sp_prim_setup.h" +#include "draw/draw_private.h" +#include "draw/draw_vertex.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#define DEBUG_VERTS 0 +#define DEBUG_FRAGS 0 + +/** + * Triangle edge info + */ +struct edge { + float dx; /**< X(v1) - X(v0), used only during setup */ + float dy; /**< Y(v1) - Y(v0), used only during setup */ + float dxdy; /**< dx/dy */ + float sx, sy; /**< first sample point coord */ + int lines; /**< number of lines on this edge */ +}; + + +/** + * Triangle setup info (derived from draw_stage). + * Also used for line drawing (taking some liberties). + */ +struct setup_context { + struct softpipe_context *softpipe; + + /* Vertices are just an array of floats making up each attribute in + * turn. Currently fixed at 4 floats, but should change in time. + * Codegen will help cope with this. + */ + const float (*vmax)[4]; + const float (*vmid)[4]; + const float (*vmin)[4]; + const float (*vprovoke)[4]; + + struct edge ebot; + struct edge etop; + struct edge emaj; + + float oneoverarea; + + struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS]; + struct tgsi_interp_coef posCoef; /* For Z, W */ + struct quad_header quad; + + struct { + int left[2]; /**< [0] = row0, [1] = row1 */ + int right[2]; + int y; + unsigned y_flags; + unsigned mask; /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */ + } span; + +#if DEBUG_FRAGS + uint numFragsEmitted; /**< per primitive */ + uint numFragsWritten; /**< per primitive */ +#endif +}; + + + + + +/** + * Recalculate prim's determinant. + * XXX is this needed? + */ +static INLINE float +calc_det( const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) +{ + /* edge vectors e = v0 - v2, f = v1 - v2 */ + const float ex = v0[0][0] - v2[0][0]; + const float ey = v0[0][1] - v2[0][1]; + const float fx = v1[0][0] - v2[0][0]; + const float fy = v1[0][1] - v2[0][1]; + + /* det = cross(e,f).z */ + return ex * fy - ey * fx; +} + +/** + * Clip setup->quad against the scissor/surface bounds. + */ +static INLINE void +quad_clip(struct setup_context *setup) +{ + const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect; + const int minx = (int) cliprect->minx; + const int maxx = (int) cliprect->maxx; + const int miny = (int) cliprect->miny; + const int maxy = (int) cliprect->maxy; + + if (setup->quad.x0 >= maxx || + setup->quad.y0 >= maxy || + setup->quad.x0 + 1 < minx || + setup->quad.y0 + 1 < miny) { + /* totally clipped */ + setup->quad.mask = 0x0; + return; + } + if (setup->quad.x0 < minx) + setup->quad.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); + if (setup->quad.y0 < miny) + setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); + if (setup->quad.x0 == maxx - 1) + setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); + if (setup->quad.y0 == maxy - 1) + setup->quad.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); +} + + +/** + * Emit a quad (pass to next stage) with clipping. + */ +static INLINE void +clip_emit_quad(struct setup_context *setup) +{ + quad_clip(setup); + if (setup->quad.mask) { + struct softpipe_context *sp = setup->softpipe; + sp->quad.first->run(sp->quad.first, &setup->quad); + } +} + + +/** + * Emit a quad (pass to next stage). No clipping is done. + */ +static INLINE void +emit_quad( struct setup_context *setup, int x, int y, unsigned mask ) +{ + struct softpipe_context *sp = setup->softpipe; + setup->quad.x0 = x; + setup->quad.y0 = y; + setup->quad.mask = mask; +#if DEBUG_FRAGS + if (mask & 1) setup->numFragsEmitted++; + if (mask & 2) setup->numFragsEmitted++; + if (mask & 4) setup->numFragsEmitted++; + if (mask & 8) setup->numFragsEmitted++; +#endif + sp->quad.first->run(sp->quad.first, &setup->quad); +#if DEBUG_FRAGS + mask = setup->quad.mask; + if (mask & 1) setup->numFragsWritten++; + if (mask & 2) setup->numFragsWritten++; + if (mask & 4) setup->numFragsWritten++; + if (mask & 8) setup->numFragsWritten++; +#endif +} + + +/** + * Given an X or Y coordinate, return the block/quad coordinate that it + * belongs to. + */ +static INLINE int block( int x ) +{ + return x & ~1; +} + + +/** + * Compute mask which indicates which pixels in the 2x2 quad are actually inside + * the triangle's bounds. + * + * this is pretty nasty... may need to rework flush_spans again to + * fix it, if possible. + */ +static unsigned calculate_mask( struct setup_context *setup, int x ) +{ + unsigned mask = 0x0; + + if (x >= setup->span.left[0] && x < setup->span.right[0]) + mask |= MASK_TOP_LEFT; + + if (x >= setup->span.left[1] && x < setup->span.right[1]) + mask |= MASK_BOTTOM_LEFT; + + if (x+1 >= setup->span.left[0] && x+1 < setup->span.right[0]) + mask |= MASK_TOP_RIGHT; + + if (x+1 >= setup->span.left[1] && x+1 < setup->span.right[1]) + mask |= MASK_BOTTOM_RIGHT; + + return mask; +} + + +/** + * Render a horizontal span of quads + */ +static void flush_spans( struct setup_context *setup ) +{ + int minleft, maxright; + int x; + + switch (setup->span.y_flags) { + case 0x3: + /* both odd and even lines written (both quad rows) */ + minleft = MIN2(setup->span.left[0], setup->span.left[1]); + maxright = MAX2(setup->span.right[0], setup->span.right[1]); + break; + + case 0x1: + /* only even line written (quad top row) */ + minleft = setup->span.left[0]; + maxright = setup->span.right[0]; + break; + + case 0x2: + /* only odd line written (quad bottom row) */ + minleft = setup->span.left[1]; + maxright = setup->span.right[1]; + break; + + default: + return; + } + + /* XXX this loop could be moved into the above switch cases and + * calculate_mask() could be simplified a bit... + */ + for (x = block(minleft); x <= block(maxright); x += 2) { + emit_quad( setup, x, setup->span.y, + calculate_mask( setup, x ) ); + } + + setup->span.y = 0; + setup->span.y_flags = 0; + setup->span.right[0] = 0; + setup->span.right[1] = 0; +} + +#if DEBUG_VERTS +static void print_vertex(const struct setup_context *setup, + const float (*v)[4]) +{ + int i; + debug_printf("Vertex: (%p)\n", v); + for (i = 0; i < setup->quad.nr_attrs; i++) { + debug_printf(" %d: %f %f %f %f\n", i, + v[i][0], v[i][1], v[i][2], v[i][3]); + } +} +#endif + +static boolean setup_sort_vertices( struct setup_context *setup, + float det, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) +{ +#if DEBUG_VERTS + debug_printf("Triangle:\n"); + print_vertex(setup, v0); + print_vertex(setup, v1); + print_vertex(setup, v2); +#endif + + setup->vprovoke = v2; + + /* determine bottom to top order of vertices */ + { + float y0 = v0[0][1]; + float y1 = v1[0][1]; + float y2 = v2[0][1]; + if (y0 <= y1) { + if (y1 <= y2) { + /* y0<=y1<=y2 */ + setup->vmin = v0; + setup->vmid = v1; + setup->vmax = v2; + } + else if (y2 <= y0) { + /* y2<=y0<=y1 */ + setup->vmin = v2; + setup->vmid = v0; + setup->vmax = v1; + } + else { + /* y0<=y2<=y1 */ + setup->vmin = v0; + setup->vmid = v2; + setup->vmax = v1; + } + } + else { + if (y0 <= y2) { + /* y1<=y0<=y2 */ + setup->vmin = v1; + setup->vmid = v0; + setup->vmax = v2; + } + else if (y2 <= y1) { + /* y2<=y1<=y0 */ + setup->vmin = v2; + setup->vmid = v1; + setup->vmax = v0; + } + else { + /* y1<=y2<=y0 */ + setup->vmin = v1; + setup->vmid = v2; + setup->vmax = v0; + } + } + } + + setup->ebot.dx = setup->vmid[0][0] - setup->vmin[0][0]; + setup->ebot.dy = setup->vmid[0][1] - setup->vmin[0][1]; + setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; + setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; + setup->etop.dx = setup->vmax[0][0] - setup->vmid[0][0]; + setup->etop.dy = setup->vmax[0][1] - setup->vmid[0][1]; + + /* + * Compute triangle's area. Use 1/area to compute partial + * derivatives of attributes later. + * + * The area will be the same as prim->det, but the sign may be + * different depending on how the vertices get sorted above. + * + * To determine whether the primitive is front or back facing we + * use the prim->det value because its sign is correct. + */ + { + const float area = (setup->emaj.dx * setup->ebot.dy - + setup->ebot.dx * setup->emaj.dy); + + setup->oneoverarea = 1.0f / area; + /* + debug_printf("%s one-over-area %f area %f det %f\n", + __FUNCTION__, setup->oneoverarea, area, det ); + */ + } + + /* We need to know if this is a front or back-facing triangle for: + * - the GLSL gl_FrontFacing fragment attribute (bool) + * - two-sided stencil test + */ + setup->quad.facing = (det > 0.0) ^ (setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW); + + return TRUE; +} + + +/** + * Compute a0 for a constant-valued coefficient (GL_FLAT shading). + * The value value comes from vertex[slot][i]. + * The result will be put into setup->coef[slot].a0[i]. + * \param slot which attribute slot + * \param i which component of the slot (0..3) + */ +static void const_coeff( struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + assert(i <= 3); + + coef->dadx[i] = 0; + coef->dady[i] = 0; + + /* need provoking vertex info! + */ + coef->a0[i] = setup->vprovoke[vertSlot][i]; +} + + +/** + * Compute a0, dadx and dady for a linearly interpolated coefficient, + * for a triangle. + */ +static void tri_linear_coeff( struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i]; + float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; + float a = setup->ebot.dy * majda - botda * setup->emaj.dy; + float b = setup->emaj.dx * botda - majda * setup->ebot.dx; + float dadx = a * setup->oneoverarea; + float dady = b * setup->oneoverarea; + + assert(i <= 3); + + coef->dadx[i] = dadx; + coef->dady[i] = dady; + + /* calculate a0 as the value which would be sampled for the + * fragment at (0,0), taking into account that we want to sample at + * pixel centers, in other words (0.5, 0.5). + * + * this is neat but unfortunately not a good way to do things for + * triangles with very large values of dadx or dady as it will + * result in the subtraction and re-addition from a0 of a very + * large number, which means we'll end up loosing a lot of the + * fractional bits and precision from a0. the way to fix this is + * to define a0 as the sample at a pixel center somewhere near vmin + * instead - i'll switch to this later. + */ + coef->a0[i] = (setup->vmin[vertSlot][i] - + (dadx * (setup->vmin[0][0] - 0.5f) + + dady * (setup->vmin[0][1] - 0.5f))); + + /* + debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", + slot, "xyzw"[i], + setup->coef[slot].a0[i], + setup->coef[slot].dadx[i], + setup->coef[slot].dady[i]); + */ +} + + +/** + * Compute a0, dadx and dady for a perspective-corrected interpolant, + * for a triangle. + * We basically multiply the vertex value by 1/w before computing + * the plane coefficients (a0, dadx, dady). + * Later, when we compute the value at a particular fragment position we'll + * divide the interpolated value by the interpolated W at that fragment. + */ +static void tri_persp_coeff( struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + /* premultiply by 1/w (v[0][3] is always W): + */ + float mina = setup->vmin[vertSlot][i] * setup->vmin[0][3]; + float mida = setup->vmid[vertSlot][i] * setup->vmid[0][3]; + float maxa = setup->vmax[vertSlot][i] * setup->vmax[0][3]; + float botda = mida - mina; + float majda = maxa - mina; + float a = setup->ebot.dy * majda - botda * setup->emaj.dy; + float b = setup->emaj.dx * botda - majda * setup->ebot.dx; + float dadx = a * setup->oneoverarea; + float dady = b * setup->oneoverarea; + + /* + debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i, + setup->vmin[vertSlot][i], + setup->vmid[vertSlot][i], + setup->vmax[vertSlot][i] + ); + */ + assert(i <= 3); + + coef->dadx[i] = dadx; + coef->dady[i] = dady; + coef->a0[i] = (mina - + (dadx * (setup->vmin[0][0] - 0.5f) + + dady * (setup->vmin[0][1] - 0.5f))); +} + + +/** + * Special coefficient setup for gl_FragCoord. + * X and Y are trivial, though Y has to be inverted for OpenGL. + * Z and W are copied from posCoef which should have already been computed. + * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. + */ +static void +setup_fragcoord_coeff(struct setup_context *setup, uint slot) +{ + /*X*/ + setup->coef[slot].a0[0] = 0; + setup->coef[slot].dadx[0] = 1.0; + setup->coef[slot].dady[0] = 0.0; + /*Y*/ + if (setup->softpipe->rasterizer->origin_lower_left) { + /* y=0=bottom */ + const int winHeight = setup->softpipe->framebuffer.height; + setup->coef[slot].a0[1] = (float) (winHeight - 1); + setup->coef[slot].dady[1] = -1.0; + } + else { + /* y=0=top */ + setup->coef[slot].a0[1] = 0.0; + setup->coef[slot].dady[1] = 1.0; + } + setup->coef[slot].dadx[1] = 0.0; + /*Z*/ + setup->coef[slot].a0[2] = setup->posCoef.a0[2]; + setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; + setup->coef[slot].dady[2] = setup->posCoef.dady[2]; + /*W*/ + setup->coef[slot].a0[3] = setup->posCoef.a0[3]; + setup->coef[slot].dadx[3] = setup->posCoef.dadx[3]; + setup->coef[slot].dady[3] = setup->posCoef.dady[3]; +} + + + +/** + * Compute the setup->coef[] array dadx, dady, a0 values. + * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized. + */ +static void setup_tri_coefficients( struct setup_context *setup ) +{ + struct softpipe_context *softpipe = setup->softpipe; + const struct sp_fragment_shader *spfs = softpipe->fs; + const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); + uint fragSlot; + + /* z and w are done by linear interpolation: + */ + tri_linear_coeff(setup, &setup->posCoef, 0, 2); + tri_linear_coeff(setup, &setup->posCoef, 0, 3); + + /* setup interpolation for all the remaining attributes: + */ + for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { + const uint vertSlot = vinfo->src_index[fragSlot]; + uint j; + + switch (vinfo->interp_mode[fragSlot]) { + case INTERP_CONSTANT: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + setup_fragcoord_coeff(setup, fragSlot); + break; + default: + assert(0); + } + + if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + /* FOG.y = front/back facing XXX fix this */ + setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; + setup->coef[fragSlot].dadx[1] = 0.0; + setup->coef[fragSlot].dady[1] = 0.0; + } + } +} + + + +static void setup_tri_edges( struct setup_context *setup ) +{ + float vmin_x = setup->vmin[0][0] + 0.5f; + float vmid_x = setup->vmid[0][0] + 0.5f; + + float vmin_y = setup->vmin[0][1] - 0.5f; + float vmid_y = setup->vmid[0][1] - 0.5f; + float vmax_y = setup->vmax[0][1] - 0.5f; + + setup->emaj.sy = CEILF(vmin_y); + setup->emaj.lines = (int) CEILF(vmax_y - setup->emaj.sy); + setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy; + setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; + + setup->etop.sy = CEILF(vmid_y); + setup->etop.lines = (int) CEILF(vmax_y - setup->etop.sy); + setup->etop.dxdy = setup->etop.dx / setup->etop.dy; + setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; + + setup->ebot.sy = CEILF(vmin_y); + setup->ebot.lines = (int) CEILF(vmid_y - setup->ebot.sy); + setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy; + setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; +} + + +/** + * Render the upper or lower half of a triangle. + * Scissoring/cliprect is applied here too. + */ +static void subtriangle( struct setup_context *setup, + struct edge *eleft, + struct edge *eright, + unsigned lines ) +{ + const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect; + const int minx = (int) cliprect->minx; + const int maxx = (int) cliprect->maxx; + const int miny = (int) cliprect->miny; + const int maxy = (int) cliprect->maxy; + int y, start_y, finish_y; + int sy = (int)eleft->sy; + + assert((int)eleft->sy == (int) eright->sy); + + /* clip top/bottom */ + start_y = sy; + finish_y = sy + lines; + + if (start_y < miny) + start_y = miny; + + if (finish_y > maxy) + finish_y = maxy; + + start_y -= sy; + finish_y -= sy; + + /* + debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); + */ + + for (y = start_y; y < finish_y; y++) { + + /* avoid accumulating adds as floats don't have the precision to + * accurately iterate large triangle edges that way. luckily we + * can just multiply these days. + * + * this is all drowned out by the attribute interpolation anyway. + */ + int left = (int)(eleft->sx + y * eleft->dxdy); + int right = (int)(eright->sx + y * eright->dxdy); + + /* clip left/right */ + if (left < minx) + left = minx; + if (right > maxx) + right = maxx; + + if (left < right) { + int _y = sy + y; + if (block(_y) != setup->span.y) { + flush_spans(setup); + setup->span.y = block(_y); + } + + setup->span.left[_y&1] = left; + setup->span.right[_y&1] = right; + setup->span.y_flags |= 1<<(_y&1); + } + } + + + /* save the values so that emaj can be restarted: + */ + eleft->sx += lines * eleft->dxdy; + eright->sx += lines * eright->dxdy; + eleft->sy += lines; + eright->sy += lines; +} + + +/** + * Do setup for triangle rasterization, then render the triangle. + */ +void setup_tri( struct setup_context *setup, + float det, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) +{ + /* + debug_printf("%s\n", __FUNCTION__ ); + */ + +#if DEBUG_FRAGS + setup->numFragsEmitted = 0; + setup->numFragsWritten = 0; +#endif + + setup_sort_vertices( setup, calc_det(v0, v1, v2), + v0, v1, v2 ); + setup_tri_coefficients( setup ); + setup_tri_edges( setup ); + + setup->quad.prim = PRIM_TRI; + + setup->span.y = 0; + setup->span.y_flags = 0; + setup->span.right[0] = 0; + setup->span.right[1] = 0; + /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ + + /* init_constant_attribs( setup ); */ + + if (setup->oneoverarea < 0.0) { + /* emaj on left: + */ + subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); + subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); + } + else { + /* emaj on right: + */ + subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); + subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); + } + + flush_spans( setup ); + +#if DEBUG_FRAGS + printf("Tri: %u frags emitted, %u written\n", + setup->numFragsEmitted, + setup->numFragsWritten); +#endif +} + + + +/** + * Compute a0, dadx and dady for a linearly interpolated coefficient, + * for a line. + */ +static void +line_linear_coeff(struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; + const float dadx = da * setup->emaj.dx * setup->oneoverarea; + const float dady = da * setup->emaj.dy * setup->oneoverarea; + coef->dadx[i] = dadx; + coef->dady[i] = dady; + coef->a0[i] = (setup->vmin[vertSlot][i] - + (dadx * (setup->vmin[0][0] - 0.5f) + + dady * (setup->vmin[0][1] - 0.5f))); +} + + +/** + * Compute a0, dadx and dady for a perspective-corrected interpolant, + * for a line. + */ +static void +line_persp_coeff(struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + /* XXX double-check/verify this arithmetic */ + const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3]; + const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3]; + const float da = a1 - a0; + const float dadx = da * setup->emaj.dx * setup->oneoverarea; + const float dady = da * setup->emaj.dy * setup->oneoverarea; + coef->dadx[i] = dadx; + coef->dady[i] = dady; + coef->a0[i] = (setup->vmin[vertSlot][i] - + (dadx * (setup->vmin[0][0] - 0.5f) + + dady * (setup->vmin[0][1] - 0.5f))); +} + + +/** + * Compute the setup->coef[] array dadx, dady, a0 values. + * Must be called after setup->vmin,vmax are initialized. + */ +static INLINE void +setup_line_coefficients(struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4]) +{ + struct softpipe_context *softpipe = setup->softpipe; + const struct sp_fragment_shader *spfs = softpipe->fs; + const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); + uint fragSlot; + + /* use setup->vmin, vmax to point to vertices */ + setup->vprovoke = v1; + setup->vmin = v0; + setup->vmax = v1; + + setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; + setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; + /* NOTE: this is not really 1/area */ + setup->oneoverarea = 1.0f / (setup->emaj.dx * setup->emaj.dx + + setup->emaj.dy * setup->emaj.dy); + + /* z and w are done by linear interpolation: + */ + line_linear_coeff(setup, &setup->posCoef, 0, 2); + line_linear_coeff(setup, &setup->posCoef, 0, 3); + + /* setup interpolation for all the remaining attributes: + */ + for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { + const uint vertSlot = vinfo->src_index[fragSlot]; + uint j; + + switch (vinfo->interp_mode[fragSlot]) { + case INTERP_CONSTANT: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + setup_fragcoord_coeff(setup, fragSlot); + break; + default: + assert(0); + } + + if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + /* FOG.y = front/back facing XXX fix this */ + setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; + setup->coef[fragSlot].dadx[1] = 0.0; + setup->coef[fragSlot].dady[1] = 0.0; + } + } +} + + +/** + * Plot a pixel in a line segment. + */ +static INLINE void +plot(struct setup_context *setup, int x, int y) +{ + const int iy = y & 1; + const int ix = x & 1; + const int quadX = x - ix; + const int quadY = y - iy; + const int mask = (1 << ix) << (2 * iy); + + if (quadX != setup->quad.x0 || + quadY != setup->quad.y0) + { + /* flush prev quad, start new quad */ + + if (setup->quad.x0 != -1) + clip_emit_quad(setup); + + setup->quad.x0 = quadX; + setup->quad.y0 = quadY; + setup->quad.mask = 0x0; + } + + setup->quad.mask |= mask; +} + + +/** + * Do setup for line rasterization, then render the line. + * Single-pixel width, no stipple, etc. We rely on the 'draw' module + * to handle stippling and wide lines. + */ +void +setup_line(struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4]) +{ + int x0 = (int) v0[0][0]; + int x1 = (int) v1[0][0]; + int y0 = (int) v0[0][1]; + int y1 = (int) v1[0][1]; + int dx = x1 - x0; + int dy = y1 - y0; + int xstep, ystep; + + if (dx == 0 && dy == 0) + return; + + setup_line_coefficients(setup, v0, v1); + + if (dx < 0) { + dx = -dx; /* make positive */ + xstep = -1; + } + else { + xstep = 1; + } + + if (dy < 0) { + dy = -dy; /* make positive */ + ystep = -1; + } + else { + ystep = 1; + } + + assert(dx >= 0); + assert(dy >= 0); + + setup->quad.x0 = setup->quad.y0 = -1; + setup->quad.mask = 0x0; + setup->quad.prim = PRIM_LINE; + /* XXX temporary: set coverage to 1.0 so the line appears + * if AA mode happens to be enabled. + */ + setup->quad.coverage[0] = + setup->quad.coverage[1] = + setup->quad.coverage[2] = + setup->quad.coverage[3] = 1.0; + + if (dx > dy) { + /*** X-major line ***/ + int i; + const int errorInc = dy + dy; + int error = errorInc - dx; + const int errorDec = error - dx; + + for (i = 0; i < dx; i++) { + plot(setup, x0, y0); + + x0 += xstep; + if (error < 0) { + error += errorInc; + } + else { + error += errorDec; + y0 += ystep; + } + } + } + else { + /*** Y-major line ***/ + int i; + const int errorInc = dx + dx; + int error = errorInc - dy; + const int errorDec = error - dy; + + for (i = 0; i < dy; i++) { + plot(setup, x0, y0); + + y0 += ystep; + if (error < 0) { + error += errorInc; + } + else { + error += errorDec; + x0 += xstep; + } + } + } + + /* draw final quad */ + if (setup->quad.mask) { + clip_emit_quad(setup); + } +} + + +static void +point_persp_coeff(struct setup_context *setup, + const float (*vert)[4], + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + assert(i <= 3); + coef->dadx[i] = 0.0F; + coef->dady[i] = 0.0F; + coef->a0[i] = vert[vertSlot][i] * vert[0][3]; +} + + +/** + * Do setup for point rasterization, then render the point. + * Round or square points... + * XXX could optimize a lot for 1-pixel points. + */ +void +setup_point( struct setup_context *setup, + const float (*v0)[4] ) +{ + struct softpipe_context *softpipe = setup->softpipe; + const struct sp_fragment_shader *spfs = softpipe->fs; + const int sizeAttr = setup->softpipe->psize_slot; + const float size + = sizeAttr > 0 ? v0[sizeAttr][0] + : setup->softpipe->rasterizer->point_size; + const float halfSize = 0.5F * size; + const boolean round = (boolean) setup->softpipe->rasterizer->point_smooth; + const float x = v0[0][0]; /* Note: data[0] is always position */ + const float y = v0[0][1]; + const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); + uint fragSlot; + + /* For points, all interpolants are constant-valued. + * However, for point sprites, we'll need to setup texcoords appropriately. + * XXX: which coefficients are the texcoords??? + * We may do point sprites as textured quads... + * + * KW: We don't know which coefficients are texcoords - ultimately + * the choice of what interpolation mode to use for each attribute + * should be determined by the fragment program, using + * per-attribute declaration statements that include interpolation + * mode as a parameter. So either the fragment program will have + * to be adjusted for pointsprite vs normal point behaviour, or + * otherwise a special interpolation mode will have to be defined + * which matches the required behaviour for point sprites. But - + * the latter is not a feature of normal hardware, and as such + * probably should be ruled out on that basis. + */ + setup->vprovoke = v0; + + /* setup Z, W */ + const_coeff(setup, &setup->posCoef, 0, 2); + const_coeff(setup, &setup->posCoef, 0, 3); + + for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { + const uint vertSlot = vinfo->src_index[fragSlot]; + uint j; + + switch (vinfo->interp_mode[fragSlot]) { + case INTERP_CONSTANT: + /* fall-through */ + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + point_persp_coeff(setup, setup->vprovoke, + &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + setup_fragcoord_coeff(setup, fragSlot); + break; + default: + assert(0); + } + + if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FOG) { + /* FOG.y = front/back facing XXX fix this */ + setup->coef[fragSlot].a0[1] = 1.0f - setup->quad.facing; + setup->coef[fragSlot].dadx[1] = 0.0; + setup->coef[fragSlot].dady[1] = 0.0; + } + } + + setup->quad.prim = PRIM_POINT; + + if (halfSize <= 0.5 && !round) { + /* special case for 1-pixel points */ + const int ix = ((int) x) & 1; + const int iy = ((int) y) & 1; + setup->quad.x0 = (int) x - ix; + setup->quad.y0 = (int) y - iy; + setup->quad.mask = (1 << ix) << (2 * iy); + clip_emit_quad(setup); + } + else { + if (round) { + /* rounded points */ + const int ixmin = block((int) (x - halfSize)); + const int ixmax = block((int) (x + halfSize)); + const int iymin = block((int) (y - halfSize)); + const int iymax = block((int) (y + halfSize)); + const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ + const float rmax = halfSize + 0.7071F; + const float rmin2 = MAX2(0.0F, rmin * rmin); + const float rmax2 = rmax * rmax; + const float cscale = 1.0F / (rmax2 - rmin2); + int ix, iy; + + for (iy = iymin; iy <= iymax; iy += 2) { + for (ix = ixmin; ix <= ixmax; ix += 2) { + float dx, dy, dist2, cover; + + setup->quad.mask = 0x0; + + dx = (ix + 0.5f) - x; + dy = (iy + 0.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); + setup->quad.mask |= MASK_TOP_LEFT; + } + + dx = (ix + 1.5f) - x; + dy = (iy + 0.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); + setup->quad.mask |= MASK_TOP_RIGHT; + } + + dx = (ix + 0.5f) - x; + dy = (iy + 1.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); + setup->quad.mask |= MASK_BOTTOM_LEFT; + } + + dx = (ix + 1.5f) - x; + dy = (iy + 1.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); + setup->quad.mask |= MASK_BOTTOM_RIGHT; + } + + if (setup->quad.mask) { + setup->quad.x0 = ix; + setup->quad.y0 = iy; + clip_emit_quad(setup); + } + } + } + } + else { + /* square points */ + const int xmin = (int) (x + 0.75 - halfSize); + const int ymin = (int) (y + 0.25 - halfSize); + const int xmax = xmin + (int) size; + const int ymax = ymin + (int) size; + /* XXX could apply scissor to xmin,ymin,xmax,ymax now */ + const int ixmin = block(xmin); + const int ixmax = block(xmax - 1); + const int iymin = block(ymin); + const int iymax = block(ymax - 1); + int ix, iy; + + /* + debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax); + */ + for (iy = iymin; iy <= iymax; iy += 2) { + uint rowMask = 0xf; + if (iy < ymin) { + /* above the top edge */ + rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); + } + if (iy + 1 >= ymax) { + /* below the bottom edge */ + rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); + } + + for (ix = ixmin; ix <= ixmax; ix += 2) { + uint mask = rowMask; + + if (ix < xmin) { + /* fragment is past left edge of point, turn off left bits */ + mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); + } + if (ix + 1 >= xmax) { + /* past the right edge */ + mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); + } + + setup->quad.mask = mask; + setup->quad.x0 = ix; + setup->quad.y0 = iy; + clip_emit_quad(setup); + } + } + } + } +} + +void setup_prepare( struct setup_context *setup ) +{ + struct softpipe_context *sp = setup->softpipe; + unsigned i; + + if (sp->dirty) { + softpipe_update_derived(sp); + } + + /* Mark surfaces as defined now */ + for (i = 0; i < sp->framebuffer.num_cbufs; i++){ + if (sp->framebuffer.cbufs[i]) { + sp->framebuffer.cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED; + } + } + if (sp->framebuffer.zsbuf) { + sp->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; + } + + { + const struct sp_fragment_shader *fs = setup->softpipe->fs; + setup->quad.nr_attrs = fs->info.num_inputs; + sp->quad.first->begin(sp->quad.first); + } +} + + + +void setup_destroy_context( struct setup_context *setup ) +{ + FREE( setup ); +} + + +/** + * Create a new primitive setup/render stage. + */ +struct setup_context *setup_create_context( struct softpipe_context *softpipe ) +{ + struct setup_context *setup = CALLOC_STRUCT(setup_context); + + setup->softpipe = softpipe; + + setup->quad.coef = setup->coef; + setup->quad.posCoef = &setup->posCoef; + + return setup; +} diff --git a/src/gallium/drivers/softpipe/sp_setup.h b/src/gallium/drivers/softpipe/sp_setup.h new file mode 100644 index 0000000000..3133fc2a3d --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_setup.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +#ifndef SP_SETUP_H +#define SP_SETUP_H + +struct setup_context; +struct softpipe_context; + +void setup_tri( struct setup_context *setup, + float det, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ); + +void +setup_line(struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4]); + +void +setup_point( struct setup_context *setup, + const float (*v0)[4] ); + + +struct setup_context *setup_create_context( struct softpipe_context *softpipe ); +void setup_prepare( struct setup_context *setup ); +void setup_destroy_context( struct setup_context *setup ); + +#endif diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 14abb20eeb..f10a1fa471 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -71,25 +71,16 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) * simply emit the whole post-xform vertex as-is: */ struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf; -#if 0 - vinfo_vbuf->num_attribs = 0; - /* special-case to allow memcpy of whole vertex */ - draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0); - /* size in dwords or floats */ - vinfo_vbuf->size = 4 * draw_num_vs_outputs(softpipe->draw) - + sizeof(struct vertex_header) / 4; -#else - /* for pass-through mode, we need a more explicit list of attribs */ const uint num = draw_num_vs_outputs(softpipe->draw); uint i; + /* No longer any need to try and emit draw vertex_header info. + */ vinfo_vbuf->num_attribs = 0; - draw_emit_vertex_attr(vinfo_vbuf, EMIT_HEADER, INTERP_NONE, 0); for (i = 0; i < num; i++) { draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i); } draw_compute_vertex_size(vinfo_vbuf); -#endif } /* -- cgit v1.2.3 From bc56e87ce180ddca63bcb9774366fc380214a2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 10 Apr 2008 22:57:21 +0900 Subject: gallium: Attribute realloc leaks to the first malloc call. --- src/gallium/auxiliary/util/p_debug_mem.c | 71 +++++++++++++++++++++++++----- src/gallium/auxiliary/util/u_double_list.h | 8 ++++ 2 files changed, 68 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c index 97ec9c5b39..aba69c0294 100644 --- a/src/gallium/auxiliary/util/p_debug_mem.c +++ b/src/gallium/auxiliary/util/p_debug_mem.c @@ -73,6 +73,25 @@ static struct list_head list = { &list, &list }; static unsigned long last_no = 0; +static INLINE struct debug_memory_header * +header_from_data(void *data) +{ + if(data) + return (struct debug_memory_header *)((char *)data - sizeof(struct debug_memory_header)); + else + return NULL; +} + +static INLINE void * +data_from_header(struct debug_memory_header *hdr) +{ + if(hdr) + return (void *)((char *)hdr + sizeof(struct debug_memory_header)); + else + return NULL; +} + + void * debug_malloc(const char *file, unsigned line, const char *function, size_t size) @@ -92,7 +111,7 @@ debug_malloc(const char *file, unsigned line, const char *function, LIST_ADDTAIL(&hdr->head, &list); - return (void *)((char *)hdr + sizeof(*hdr)); + return data_from_header(hdr); } void @@ -104,7 +123,7 @@ debug_free(const char *file, unsigned line, const char *function, if(!ptr) return; - hdr = (struct debug_memory_header *)((char *)ptr - sizeof(*hdr)); + hdr = header_from_data(ptr); if(hdr->magic != DEBUG_MEMORY_MAGIC) { debug_printf("%s:%u:%s: freeing bad or corrupted memory %p\n", file, line, function, @@ -133,16 +152,46 @@ void * debug_realloc(const char *file, unsigned line, const char *function, void *old_ptr, size_t old_size, size_t new_size ) { - void *new_ptr = NULL; - - if (new_size != 0) { - new_ptr = debug_malloc( file, line, function, new_size ); - - if( new_ptr && old_ptr ) - memcpy( new_ptr, old_ptr, old_size ); + struct debug_memory_header *old_hdr, *new_hdr; + void *new_ptr; + + if(!old_ptr) + return debug_malloc( file, line, function, new_size ); + + if(!new_size) { + debug_free( file, line, function, old_ptr ); + return NULL; } + + old_hdr = header_from_data(old_ptr); + if(old_hdr->magic != DEBUG_MEMORY_MAGIC) { + debug_printf("%s:%u:%s: reallocating bad or corrupted memory %p\n", + file, line, function, + old_ptr); + debug_assert(0); + return NULL; + } + + /* alloc new */ + new_hdr = real_malloc(sizeof(*new_hdr) + new_size); + if(!new_hdr) + return NULL; + new_hdr->no = old_hdr->no; + new_hdr->file = old_hdr->file; + new_hdr->line = old_hdr->line; + new_hdr->function = old_hdr->function; + new_hdr->size = new_size; + new_hdr->magic = DEBUG_MEMORY_MAGIC; + LIST_REPLACE(&old_hdr->head, &new_hdr->head); + + /* copy data */ + new_ptr = data_from_header(new_hdr); + memcpy( new_ptr, old_ptr, old_size < new_size ? old_size : new_size ); + + /* free old */ + old_hdr->magic = 0; + real_free(old_hdr); - debug_free( file, line, function, old_ptr ); return new_ptr; } @@ -162,7 +211,7 @@ debug_memory_end(unsigned long start_no) struct debug_memory_header *hdr; void *ptr; hdr = LIST_ENTRY(struct debug_memory_header, entry, head); - ptr = (void *)((char *)hdr + sizeof(*hdr)); + ptr = data_from_header(hdr); if(start_no <= hdr->no && hdr->no < last_no || last_no < start_no && (hdr->no < last_no || start_no <= hdr->no)) debug_printf("%s:%u:%s: %u bytes at %p not freed\n", diff --git a/src/gallium/auxiliary/util/u_double_list.h b/src/gallium/auxiliary/util/u_double_list.h index 8cb10c9820..d108d92e52 100644 --- a/src/gallium/auxiliary/util/u_double_list.h +++ b/src/gallium/auxiliary/util/u_double_list.h @@ -70,6 +70,14 @@ struct list_head (__list)->prev = (__item); \ } while(0) +#define LIST_REPLACE(__from, __to) \ + do { \ + (__to)->prev = (__from)->prev; \ + (__to)->next = (__from)->next; \ + (__from)->next->prev = (__to); \ + (__from)->prev->next = (__to); \ + } while (0) + #define LIST_DEL(__item) \ do { \ (__item)->prev->next = (__item)->next; \ -- cgit v1.2.3 From 87b0b8e7bc3b4ce4be90a271b9fced1c97df6c95 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 7 Apr 2008 16:53:41 -0600 Subject: gallium: flags param to surface_alloc_storage() is unused and deprecated --- src/gallium/include/pipe/p_winsys.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index 8569cdcf12..bf5aad7351 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -80,6 +80,7 @@ struct pipe_winsys /** * Allocate storage for a pipe_surface. * Returns 0 if succeeds. + * XXX: flags is unused and will be removed someday. */ int (*surface_alloc_storage)(struct pipe_winsys *ws, struct pipe_surface *surf, -- cgit v1.2.3 From 03a3373bdf929b6b7c43600c9eebb0c4ee3ff38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 11 Apr 2008 12:11:14 +0900 Subject: gallium: Thread condition variables. --- src/gallium/include/pipe/p_thread.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/include/pipe/p_thread.h index 4325abc951..af9150aafb 100644 --- a/src/gallium/include/pipe/p_thread.h +++ b/src/gallium/include/pipe/p_thread.h @@ -114,6 +114,26 @@ typedef pthread_mutex_t _glthread_Mutex; #define _glthread_UNLOCK_MUTEX(name) \ (void) pthread_mutex_unlock(&(name)) +typedef pthread_cond_t _glthread_Cond; + +#define _glthread_DECLARE_STATIC_COND(name) \ + static _glthread_Cond name = PTHREAD_COND_INITIALIZER + +#define _glthread_INIT_COND(cond) \ + pthread_cond_init(&(cond), NULL) + +#define _glthread_DESTROY_COND(name) \ + pthread_cond_destroy(&(name)) + +#define _glthread_COND_WAIT(cond, mutex) \ + pthread_cond_wait(&(cond), &(mutex)) + +#define _glthread_COND_SIGNAL(cond) \ + pthread_cond_signal(&(cond)) + +#define _glthread_COND_BROADCAST(cond) \ + pthread_cond_broadcast(&(cond)) + #endif /* PTHREADS */ @@ -273,6 +293,20 @@ typedef unsigned _glthread_Mutex; #define _glthread_UNLOCK_MUTEX(name) (void) name +typedef unsigned _glthread_Cond; + +#define _glthread_DECLARE_STATIC_COND(name) static _glthread_Cond name = 0 + +#define _glthread_INIT_COND(name) (void) name + +#define _glthread_DESTROY_COND(name) (void) name + +#define _glthread_COND_WAIT(name, mutex) (void) name + +#define _glthread_COND_SIGNAL(name) (void) name + +#define _glthread_COND_BROADCAST(name) (void) name + #endif /* THREADS */ -- cgit v1.2.3 From 2483062f10e93fbbc5e3f629627b9e8addcc3f84 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 7 Apr 2008 11:44:34 +0200 Subject: tgsi: Dump semantics before interpolator. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 7d292778ad..ad9770e474 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -746,17 +746,19 @@ dump_declaration_short( } } - if( decl->Declaration.Interpolate ) { + if (decl->Declaration.Semantic) { TXT( ", " ); - ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES_SHORT ); + ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT ); + if (decl->Semantic.SemanticIndex != 0) { + CHR( '[' ); + UID( decl->Semantic.SemanticIndex ); + CHR( ']' ); + } } - if( decl->Declaration.Semantic ) { + if (decl->Declaration.Interpolate) { TXT( ", " ); - ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT ); - CHR( '[' ); - UID( decl->Semantic.SemanticIndex ); - CHR( ']' ); + ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES_SHORT ); } } -- cgit v1.2.3 From f41cc50ef063e9a56dc2d0fc6564a0c0f4344b83 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 7 Apr 2008 11:46:57 +0200 Subject: tgsi: Dump processor type and version as a single token. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index ad9770e474..1d6e8b155d 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -1402,7 +1402,6 @@ dump_gen( CHR( '\n' ); ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES_SHORT ); - CHR( ' ' ); UID( parse.FullVersion.Version.MajorVersion ); CHR( '.' ); UID( parse.FullVersion.Version.MinorVersion ); -- cgit v1.2.3 From 4d184cc33131b440f9aafbcdd2d657050411db49 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 11 Apr 2008 13:20:52 -0600 Subject: gallium: fix broken x86_call() --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 4d33950e99..aea8b28e58 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -317,7 +317,7 @@ void x86_call( struct x86_function *p, void (*label)()) void x86_call( struct x86_function *p, struct x86_reg reg) { emit_1ub(p, 0xff); - emit_modrm(p, reg, reg); + emit_modrm_noreg(p, 2, reg); } #endif -- cgit v1.2.3 From 9e8a85ef670dfb7d356d6066bad4710683a07fd9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Apr 2008 13:21:39 -0600 Subject: gallium: fix SCS codegen (sin scalar src comes from X, not Y) --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 4e80597b3f..35c63feccc 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -2020,7 +2020,7 @@ emit_instruction( STORE( func, *inst, 0, 0, CHAN_X ); } IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { - FETCH( func, *inst, 0, 0, CHAN_Y ); + FETCH( func, *inst, 0, 0, CHAN_X ); emit_sin( func, 0 ); STORE( func, *inst, 0, 0, CHAN_Y ); } -- cgit v1.2.3 From 097301395d33d57d19bc942f236b4a8c912cc0cc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Apr 2008 13:44:47 -0600 Subject: gallium: comments --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 35c63feccc..93813f36cb 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -548,6 +548,12 @@ emit_xorps( * Data fetch helpers. */ +/** + * Copy a shader constant to xmm register + * \param xmm the destination xmm register + * \param vec the src const buffer index + * \param chan src channel to fetch (X, Y, Z or W) + */ static void emit_const( struct x86_function *func, @@ -566,6 +572,12 @@ emit_const( SHUF( 0, 0, 0, 0 ) ); } +/** + * Copy a shader input to xmm register + * \param xmm the destination xmm register + * \param vec the src input attrib + * \param chan src channel to fetch (X, Y, Z or W) + */ static void emit_inputf( struct x86_function *func, @@ -579,6 +591,12 @@ emit_inputf( get_input( vec, chan ) ); } +/** + * Store an xmm register to a shader output + * \param xmm the source xmm register + * \param vec the dest output attrib + * \param chan src dest channel to store (X, Y, Z or W) + */ static void emit_output( struct x86_function *func, @@ -592,6 +610,12 @@ emit_output( make_xmm( xmm ) ); } +/** + * Copy a shader temporary to xmm register + * \param xmm the destination xmm register + * \param vec the src temp register + * \param chan src channel to fetch (X, Y, Z or W) + */ static void emit_tempf( struct x86_function *func, @@ -605,6 +629,13 @@ emit_tempf( get_temp( vec, chan ) ); } +/** + * Load an xmm register with an input attrib coefficient (a0, dadx or dady) + * \param xmm the destination xmm register + * \param vec the src input/attribute coefficient index + * \param chan src channel to fetch (X, Y, Z or W) + * \param member 0=a0, 1=dadx, 2=dady + */ static void emit_coef( struct x86_function *func, -- cgit v1.2.3 From e3cf0cd6a9f3f072594e5712763b98ce7e579bcf Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Apr 2008 14:18:07 -0600 Subject: gallium: implement immediates (aka literals) for SSE fragment shaders --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 82 +++++++++++++++++++++++++++-- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h | 4 +- src/gallium/drivers/softpipe/sp_fs_sse.c | 10 ++-- 3 files changed, 88 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 93813f36cb..748c53dbfc 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -225,6 +225,15 @@ get_coef_base( void ) return get_output_base(); } +static struct x86_reg +get_immediate_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_DI ); +} + + /** * Data access helpers. */ @@ -238,6 +247,16 @@ get_argument( (index + 1) * 4 ); } +static struct x86_reg +get_immediate( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_immediate_base(), + (vec * 4 + chan) * 4 ); +} + static struct x86_reg get_const( unsigned vec, @@ -572,6 +591,25 @@ emit_const( SHUF( 0, 0, 0, 0 ) ); } +static void +emit_immediate( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movss( + func, + make_xmm( xmm ), + get_immediate( vec, chan ) ); + emit_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); +} + + /** * Copy a shader input to xmm register * \param xmm the destination xmm register @@ -1191,6 +1229,14 @@ emit_fetch( swizzle ); break; + case TGSI_FILE_IMMEDIATE: + emit_immediate( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + case TGSI_FILE_INPUT: emit_inputf( func, @@ -2343,15 +2389,21 @@ tgsi_emit_sse2( * DECLARATION and INSTRUCTION phase. * GP register holding the output argument is aliased with the coeff argument, * as outputs are not needed in the DECLARATION phase. + * + * \param tokens the TGSI input shader + * \param func the output SSE code/function + * \param immediates buffer to place immediates, later passed to SSE func */ unsigned tgsi_emit_sse2_fs( struct tgsi_token *tokens, - struct x86_function *func ) + struct x86_function *func, + float (*immediates)[4]) { struct tgsi_parse_context parse; boolean instruction_phase = FALSE; unsigned ok = 1; + uint num_immediates = 0; DUMP_START(); @@ -2362,6 +2414,7 @@ tgsi_emit_sse2_fs( func, get_input_base(), get_argument( 0 ) ); + /* skipping outputs argument here */ emit_mov( func, get_const_base(), @@ -2374,6 +2427,10 @@ tgsi_emit_sse2_fs( func, get_coef_base(), get_argument( 4 ) ); + emit_mov( + func, + get_immediate_base(), + get_argument( 5 ) ); tgsi_parse_init( &parse, tokens ); @@ -2407,9 +2464,26 @@ tgsi_emit_sse2_fs( break; case TGSI_TOKEN_TYPE_IMMEDIATE: - /* XXX implement this */ - ok = 0; - debug_printf("failed to emit immediate value to SSE\n"); + /* simply copy the immediate values into the next immediates[] slot */ + { + const uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; + uint i; + assert(size <= 4); + assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES); + for( i = 0; i < size; i++ ) { + immediates[num_immediates][i] = + parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; + } +#if 0 + debug_printf("SSE FS immediate[%d] = %f %f %f %f\n", + num_immediates, + immediates[num_immediates][0], + immediates[num_immediates][1], + immediates[num_immediates][2], + immediates[num_immediates][3]); +#endif + num_immediates++; + } break; default: diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h index 63b8ef3911..fde06047fe 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h @@ -16,7 +16,9 @@ tgsi_emit_sse2( unsigned tgsi_emit_sse2_fs( struct tgsi_token *tokens, - struct x86_function *function ); + struct x86_function *function, + float (*immediates)[4] + ); #if defined __cplusplus } diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 8095d662ee..9c7948264f 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -51,7 +51,8 @@ typedef void (XSTDCALL *codegen_function)( struct tgsi_exec_vector *output, float (*constant)[4], struct tgsi_exec_vector *temporary, - const struct tgsi_interp_coef *coef + const struct tgsi_interp_coef *coef, + float (*immediates)[4] //, const struct tgsi_exec_vector *quadPos ); @@ -60,6 +61,7 @@ struct sp_sse_fragment_shader { struct sp_fragment_shader base; struct x86_function sse2_program; codegen_function func; + float immediates[TGSI_EXEC_NUM_IMMEDIATES][4]; }; @@ -96,7 +98,8 @@ fs_sse_run( struct sp_fragment_shader *base, machine->Outputs, machine->Consts, machine->Temps, - machine->InterpCoefs + machine->InterpCoefs, + shader->immediates // , &machine->QuadPos ); @@ -129,7 +132,8 @@ softpipe_create_fs_sse(struct softpipe_context *softpipe, x86_init_func( &shader->sse2_program ); - if (!tgsi_emit_sse2_fs( templ->tokens, &shader->sse2_program )) { + if (!tgsi_emit_sse2_fs( templ->tokens, &shader->sse2_program, + shader->immediates)) { FREE(shader); return NULL; } -- cgit v1.2.3 From 7c2416f06e518bc1491fe13e145dcc9487d75449 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Apr 2008 15:02:21 -0600 Subject: gallium: handle TGSI immediates in SSE code for vertex shaders --- src/gallium/auxiliary/draw/draw_vs_sse.c | 9 ++++++--- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 23 +++++++++++++++++++---- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h | 4 +++- 3 files changed, 28 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index f40d65df08..13394129bc 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -50,13 +50,15 @@ typedef void (XSTDCALL *codegen_function) ( const struct tgsi_exec_vector *input, struct tgsi_exec_vector *output, float (*constant)[4], - struct tgsi_exec_vector *temporary ); + struct tgsi_exec_vector *temporary, + float (*immediates)[4] ); struct draw_sse_vertex_shader { struct draw_vertex_shader base; struct x86_function sse2_program; codegen_function func; + float immediates[TGSI_EXEC_NUM_IMMEDIATES][4]; }; @@ -149,7 +151,8 @@ vs_sse_run( struct draw_vertex_shader *base, shader->func(machine->Inputs, machine->Outputs, machine->Consts, - machine->Temps ); + machine->Temps, + shader->immediates); } @@ -243,7 +246,7 @@ draw_create_vs_sse(struct draw_context *draw, x86_init_func( &vs->sse2_program ); if (!tgsi_emit_sse2( (struct tgsi_token *) vs->base.state.tokens, - &vs->sse2_program )) + &vs->sse2_program, vs->immediates )) goto fail; vs->func = (codegen_function) x86_get_func( &vs->sse2_program ); diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 748c53dbfc..e55fae6047 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -2316,10 +2316,12 @@ emit_declaration( unsigned tgsi_emit_sse2( struct tgsi_token *tokens, - struct x86_function *func ) + struct x86_function *func, + float (*immediates)[4] ) { struct tgsi_parse_context parse; unsigned ok = 1; + uint num_immediates = 0; DUMP_START(); @@ -2341,6 +2343,10 @@ tgsi_emit_sse2( func, get_temp_base(), get_argument( 3 ) ); + emit_mov( + func, + get_immediate_base(), + get_argument( 4 ) ); tgsi_parse_init( &parse, tokens ); @@ -2363,9 +2369,18 @@ tgsi_emit_sse2( break; case TGSI_TOKEN_TYPE_IMMEDIATE: - /* XXX implement this */ - ok = 0; - debug_printf("failed to emit immediate value to SSE\n"); + /* simply copy the immediate values into the next immediates[] slot */ + { + const uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; + uint i; + assert(size <= 4); + assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES); + for( i = 0; i < size; i++ ) { + immediates[num_immediates][i] = + parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; + } + num_immediates++; + } break; default: diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h index fde06047fe..d1190727d0 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h @@ -11,7 +11,9 @@ struct x86_function; unsigned tgsi_emit_sse2( struct tgsi_token *tokens, - struct x86_function *function ); + struct x86_function *function, + float (*immediates)[4] + ); unsigned tgsi_emit_sse2_fs( -- cgit v1.2.3 From 593cf5a6b55eb9b490a2aee2c3850d2d493fc4df Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Apr 2008 15:27:00 -0600 Subject: gallium: merge the tgsi_emit_sse2() and tgsi_emit_sse2_fs() functions. The two functions were mostly the same. We can look at the shader header info to determine if it's a vertex or fragment shader. --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 201 +++++++++++----------------- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h | 7 - src/gallium/drivers/softpipe/sp_fs_sse.c | 4 +- 3 files changed, 80 insertions(+), 132 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index e55fae6047..c37e201b2b 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -2313,104 +2313,25 @@ emit_declaration( } } -unsigned -tgsi_emit_sse2( - struct tgsi_token *tokens, - struct x86_function *func, - float (*immediates)[4] ) -{ - struct tgsi_parse_context parse; - unsigned ok = 1; - uint num_immediates = 0; - - DUMP_START(); - - func->csr = func->store; - - emit_mov( - func, - get_input_base(), - get_argument( 0 ) ); - emit_mov( - func, - get_output_base(), - get_argument( 1 ) ); - emit_mov( - func, - get_const_base(), - get_argument( 2 ) ); - emit_mov( - func, - get_temp_base(), - get_argument( 3 ) ); - emit_mov( - func, - get_immediate_base(), - get_argument( 4 ) ); - - tgsi_parse_init( &parse, tokens ); - - while( !tgsi_parse_end_of_tokens( &parse ) && ok ) { - tgsi_parse_token( &parse ); - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - ok = emit_instruction( - func, - &parse.FullToken.FullInstruction ); - - if (!ok) { - debug_printf("failed to translate tgsi opcode %d to SSE\n", - parse.FullToken.FullInstruction.Instruction.Opcode ); - } - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - /* simply copy the immediate values into the next immediates[] slot */ - { - const uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; - uint i; - assert(size <= 4); - assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES); - for( i = 0; i < size; i++ ) { - immediates[num_immediates][i] = - parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; - } - num_immediates++; - } - break; - - default: - assert( 0 ); - ok = 0; - break; - } - } - - tgsi_parse_free( &parse ); - - DUMP_END(); - - return ok; -} /** - * Fragment shaders are responsible for interpolating shader inputs. Because on - * x86 we have only 4 GP registers, and here we have 5 shader arguments (input, - * output, const, temp and coef), the code is split into two phases -- - * DECLARATION and INSTRUCTION phase. - * GP register holding the output argument is aliased with the coeff argument, - * as outputs are not needed in the DECLARATION phase. + * Translate a TGSI vertex/fragment shader to SSE2 code. + * Slightly different things are done for vertex vs. fragment shaders. + * + * Note that fragment shaders are responsible for interpolating shader + * inputs. Because on x86 we have only 4 GP registers, and here we + * have 5 shader arguments (input, output, const, temp and coef), the + * code is split into two phases -- DECLARATION and INSTRUCTION phase. + * GP register holding the output argument is aliased with the coeff + * argument, as outputs are not needed in the DECLARATION phase. * * \param tokens the TGSI input shader * \param func the output SSE code/function * \param immediates buffer to place immediates, later passed to SSE func + * \param return 1 for success, 0 if translation failed */ unsigned -tgsi_emit_sse2_fs( +tgsi_emit_sse2( struct tgsi_token *tokens, struct x86_function *func, float (*immediates)[4]) @@ -2424,50 +2345,84 @@ tgsi_emit_sse2_fs( func->csr = func->store; - /* DECLARATION phase, do not load output argument. */ - emit_mov( - func, - get_input_base(), - get_argument( 0 ) ); - /* skipping outputs argument here */ - emit_mov( - func, - get_const_base(), - get_argument( 2 ) ); - emit_mov( - func, - get_temp_base(), - get_argument( 3 ) ); - emit_mov( - func, - get_coef_base(), - get_argument( 4 ) ); - emit_mov( - func, - get_immediate_base(), - get_argument( 5 ) ); - tgsi_parse_init( &parse, tokens ); + /* + * Different function args for vertex/fragment shaders: + */ + if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { + /* DECLARATION phase, do not load output argument. */ + emit_mov( + func, + get_input_base(), + get_argument( 0 ) ); + /* skipping outputs argument here */ + emit_mov( + func, + get_const_base(), + get_argument( 2 ) ); + emit_mov( + func, + get_temp_base(), + get_argument( 3 ) ); + emit_mov( + func, + get_coef_base(), + get_argument( 4 ) ); + emit_mov( + func, + get_immediate_base(), + get_argument( 5 ) ); + } + else { + assert(parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX); + + emit_mov( + func, + get_input_base(), + get_argument( 0 ) ); + emit_mov( + func, + get_output_base(), + get_argument( 1 ) ); + emit_mov( + func, + get_const_base(), + get_argument( 2 ) ); + emit_mov( + func, + get_temp_base(), + get_argument( 3 ) ); + emit_mov( + func, + get_immediate_base(), + get_argument( 4 ) ); + } + while( !tgsi_parse_end_of_tokens( &parse ) && ok ) { tgsi_parse_token( &parse ); switch( parse.FullToken.Token.Type ) { case TGSI_TOKEN_TYPE_DECLARATION: - emit_declaration( - func, - &parse.FullToken.FullDeclaration ); + if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { + emit_declaration( + func, + &parse.FullToken.FullDeclaration ); + } break; case TGSI_TOKEN_TYPE_INSTRUCTION: - if( !instruction_phase ) { - /* INSTRUCTION phase, overwrite coeff with output. */ - instruction_phase = TRUE; - emit_mov( - func, - get_output_base(), - get_argument( 1 ) ); + if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { + if( !instruction_phase ) { + /* INSTRUCTION phase, overwrite coeff with output. */ + instruction_phase = TRUE; + emit_mov( + func, + get_output_base(), + get_argument( 1 ) ); + } } + ok = emit_instruction( func, &parse.FullToken.FullInstruction ); diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h index d1190727d0..d56bf7f98a 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h @@ -15,13 +15,6 @@ tgsi_emit_sse2( float (*immediates)[4] ); -unsigned -tgsi_emit_sse2_fs( - struct tgsi_token *tokens, - struct x86_function *function, - float (*immediates)[4] - ); - #if defined __cplusplus } #endif diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 9c7948264f..5ef02a7142 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -132,8 +132,8 @@ softpipe_create_fs_sse(struct softpipe_context *softpipe, x86_init_func( &shader->sse2_program ); - if (!tgsi_emit_sse2_fs( templ->tokens, &shader->sse2_program, - shader->immediates)) { + if (!tgsi_emit_sse2( templ->tokens, &shader->sse2_program, + shader->immediates)) { FREE(shader); return NULL; } -- cgit v1.2.3 From 5dcfc1f1b637aefbed631cc1265ce3808f2ff249 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sat, 12 Apr 2008 14:34:59 +0200 Subject: Fixed memory leak --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 40902197e1..44baa6d9fa 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -93,6 +93,7 @@ intel_buffer_destroy(struct pipe_winsys *winsys, struct pipe_buffer *buf) { driBOUnReference( dri_bo(buf) ); + FREE(buf); } -- cgit v1.2.3 From 2ebc99fcbc0c8fc6f6ce50e2ee674312e214ea2f Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 12 Apr 2008 11:03:56 -0600 Subject: gallium: move duplicated compute_clipmask() code to draw_vs.h --- src/gallium/auxiliary/draw/draw_vs.h | 33 +++++++++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_exec.c | 26 ------------------------ src/gallium/auxiliary/draw/draw_vs_llvm.c | 27 ------------------------- src/gallium/auxiliary/draw/draw_vs_sse.c | 28 -------------------------- 4 files changed, 33 insertions(+), 81 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 4ee7e705e9..33ce1e335e 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -31,6 +31,10 @@ #ifndef DRAW_VS_H #define DRAW_VS_H +#include "draw_context.h" +#include "draw_private.h" + + struct draw_vertex_shader; struct draw_context; struct pipe_shader_state; @@ -47,4 +51,33 @@ struct draw_vertex_shader * draw_create_vs_llvm(struct draw_context *draw, const struct pipe_shader_state *templ); + +/* Should be part of the generated shader: + */ +static INLINE unsigned +compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) +{ + unsigned mask = 0x0; + unsigned i; + + /* Do the hardwired planes first: + */ + if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; + if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; + if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; + if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; + if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; + if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; + + /* Followed by any remaining ones: + */ + for (i = 6; i < nr; i++) { + if (dot4(clip, plane[i]) < 0) + mask |= (1< Date: Sat, 12 Apr 2008 22:59:17 +0200 Subject: tgsi: Fix source register short dump code. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 62 +++++++++++++++-------------- 1 file changed, 32 insertions(+), 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 1d6e8b155d..cb3573ceb6 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -968,18 +968,18 @@ dump_instruction_short( } CHR( ' ' ); - if( src->SrcRegisterExtMod.Complement ) { - TXT( "(1 - " ); - } - if( src->SrcRegisterExtMod.Negate ) { - CHR( '-' ); - } - if( src->SrcRegisterExtMod.Absolute ) { + if (src->SrcRegisterExtMod.Negate) + TXT( "-(" ); + if (src->SrcRegisterExtMod.Absolute) CHR( '|' ); - } - if( src->SrcRegister.Negate ) { + if (src->SrcRegisterExtMod.Scale2X) + TXT( "2*(" ); + if (src->SrcRegisterExtMod.Bias) + CHR( '(' ); + if (src->SrcRegisterExtMod.Complement) + TXT( "1-(" ); + if (src->SrcRegister.Negate) CHR( '-' ); - } ENM( src->SrcRegister.File, TGSI_FILES_SHORT ); @@ -987,35 +987,37 @@ dump_instruction_short( SID( src->SrcRegister.Index ); CHR( ']' ); - if (src->SrcRegister.Extended) { - if (src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || - src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || - src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || - src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) { - CHR( '.' ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES_SHORT ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES_SHORT ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES_SHORT ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES_SHORT ); - } - } - else if( src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || - src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || - src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || - src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W ) { + if (src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || + src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || + src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || + src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W) { CHR( '.' ); ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES_SHORT ); ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES_SHORT ); ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES_SHORT ); ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES_SHORT ); } + if (src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || + src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || + src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || + src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) { + CHR( '.' ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES_SHORT ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES_SHORT ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES_SHORT ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES_SHORT ); + } - if( src->SrcRegisterExtMod.Absolute ) { + if (src->SrcRegisterExtMod.Complement) + CHR( ')' ); + if (src->SrcRegisterExtMod.Bias) + TXT( ")-.5" ); + if (src->SrcRegisterExtMod.Scale2X) + CHR( ')' ); + if (src->SrcRegisterExtMod.Absolute) CHR( '|' ); - } - if( src->SrcRegisterExtMod.Complement ) { + if (src->SrcRegisterExtMod.Negate) CHR( ')' ); - } first_reg = FALSE; } -- cgit v1.2.3 From cd5931240688cb8bd12834e3ba23f858f26dbf8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 13 Apr 2008 12:23:26 +0900 Subject: gallium: OS independent time-manipulation functions. --- src/gallium/auxiliary/util/Makefile | 3 +- src/gallium/auxiliary/util/SConscript | 1 + src/gallium/auxiliary/util/u_time.c | 152 ++++++++++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_time.h | 99 ++++++++++++++++++++++ 4 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/util/u_time.c create mode 100644 src/gallium/auxiliary/util/u_time.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index 9b6c2708b6..fe82fa6378 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -14,7 +14,8 @@ C_SOURCES = \ u_hash_table.c \ u_mm.c \ u_simple_shaders.c \ - u_snprintf.c + u_snprintf.c \ + u_mm.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 9b3929eb2d..d55d2c7081 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -15,6 +15,7 @@ util = env.ConvenienceLibrary( 'u_mm.c', 'u_simple_shaders.c', 'u_snprintf.c', + 'u_time.c', ]) auxiliaries.insert(0, util) diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c new file mode 100644 index 0000000000..e6c0b19ff6 --- /dev/null +++ b/src/gallium/auxiliary/util/u_time.c @@ -0,0 +1,152 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * OS independent time-manipulation functions. + * + * @author Jose Fonseca + */ + + +#ifndef WIN32 +#include +#else +#include +#include +#endif + +#include "util/u_time.h" + + +#ifdef WIN32 +static LONGLONG frequency = 0; +#endif + + +void +util_time_get(struct util_time *t) +{ +#ifndef WIN32 + gettimeofday(&t->tv, NULL); +#else + EngQueryPerformanceCounter(&t->counter); +#endif +} + + +void +util_time_add(const struct util_time *t1, + int64_t usecs, + struct util_time *t2) +{ +#ifndef WIN32 + t2->tv.tv_sec = t1->tv.tv_sec + usecs / 1000000; + t2->tv.tv_usec = t1->tv.tv_usec + usecs % 1000000; +#else + if(!frequency) + EngQueryPerformanceFrequency(&frequency); + t2->counter = t1->counter + (usecs * frequency + 999999LL)/1000000LL; +#endif +} + + +int64_t +util_time_diff(const struct util_time *t1, + const struct util_time *t2) +{ +#ifndef WIN32 + return (t2->tv.tv_usec - t1->tv.tv_usec) + + (t2->tv.tv_sec - t1->tv.tv_sec)*1000000; +#else + return (t2->counter - t1->counter)*1000000LL/frequency; +#endif +} + + +/** + * Compare two time values. + * + * Not publicly available because it does not take in account wrap-arounds. + * Use util_time_timeout instead. + */ +static INLINE int +util_time_compare(const struct util_time *t1, + const struct util_time *t2) +{ +#ifndef WIN32 + if (t1->tv.tv_sec < t2->tv.tv_sec) + return -1; + else if(t1->tv.tv_sec > t2->tv.tv_sec) + return 1; + else if (t1->tv.tv_usec < t2->tv.tv_usec) + return -1; + else if(t1->tv.tv_usec > t2->tv.tv_usec) + return 1; + else + return 0; +#else + if (t1->counter < t2->counter) + return -1; + else if(t1->counter > t2->counter) + return 1; + else + return 0; +#endif +} + + +int +util_time_timeout(const struct util_time *start, + const struct util_time *end, + const struct util_time *curr) +{ + if(util_time_compare(start, end) <= 0) + return util_time_compare(start, curr) <= 0 && util_time_compare(curr, end) < 0; + else + return util_time_compare(start, curr) <= 0 || util_time_compare(curr, end) < 0; +} + + +#ifdef WIN32 +void util_time_usleep(unsigned usecs) +{ + LONGLONG start, curr, end; + + EngQueryPerformanceCounter(&start); + + if(!frequency) + EngQueryPerformanceFrequency(&frequency); + + end = start + (usecs * frequency + 999999LL)/1000000LL; + + do { + EngQueryPerformanceCounter(&curr); + } while(start <= curr && curr < end || + end < start && (curr < end || start <= curr)); +} +#endif diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h new file mode 100644 index 0000000000..32035cceb5 --- /dev/null +++ b/src/gallium/auxiliary/util/u_time.h @@ -0,0 +1,99 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * OS independent time-manipulation functions. + * + * @author Jose Fonseca + */ + +#ifndef U_TIME_H_ +#define U_TIME_H_ + + +#ifndef WIN32 +#include /* timeval */ +#include /* usleep */ +#endif + +#include "pipe/p_compiler.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Time abstraction. + * + * Do not access this structure directly. Use the provided function instead. + */ +struct util_time +{ +#ifndef WIN32 + struct timeval tv; +#else + long long counter; +#endif +}; + + +void +util_time_get(struct util_time *t); + +void +util_time_add(const struct util_time *t1, + int64_t usecs, + struct util_time *t2); + +int64_t +util_time_diff(const struct util_time *t1, + const struct util_time *t2); + +/** + * Returns zero when the timeout expires, non zero otherwise. + */ +int +util_time_timeout(const struct util_time *start, + const struct util_time *end, + const struct util_time *curr); + +#ifndef WIN32 +#define util_time_sleep usleep +#else +int +util_time_sleep(unsigned usecs); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* U_TIME_H_ */ -- cgit v1.2.3 From 21c302b0ec39480a7eaab7827cce5b609d196606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 13 Apr 2008 14:10:46 +0900 Subject: gallium: Initial port of Thomas slab suballocator to pipebuffer. Not tested yet -- just compiles. This includes only the slab algorithm. Fencing is already implemented in pb_bufmgr_fence and time-based caching will be commited in a separate module shortly. --- src/gallium/auxiliary/pipebuffer/Makefile | 1 + src/gallium/auxiliary/pipebuffer/SConscript | 1 + src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 9 + src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 429 ++++++++++++++++++++++ 4 files changed, 440 insertions(+) create mode 100644 src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile index a9fa518c67..0770cad45a 100644 --- a/src/gallium/auxiliary/pipebuffer/Makefile +++ b/src/gallium/auxiliary/pipebuffer/Makefile @@ -9,6 +9,7 @@ C_SOURCES = \ pb_bufmgr_fenced.c \ pb_bufmgr_mm.c \ pb_bufmgr_pool.c \ + pb_bufmgr_slab.c \ pb_winsys.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript index 3d41fd84a6..14c3c77e37 100644 --- a/src/gallium/auxiliary/pipebuffer/SConscript +++ b/src/gallium/auxiliary/pipebuffer/SConscript @@ -8,6 +8,7 @@ pipebuffer = env.ConvenienceLibrary( 'pb_bufmgr_fenced.c', 'pb_bufmgr_mm.c', 'pb_bufmgr_pool.c', + 'pb_bufmgr_slab.c', 'pb_winsys.c', ]) diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 0cf8e92e37..a2377f70e2 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -114,6 +114,15 @@ mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, size_t size, size_t align2); +struct pb_manager * +pb_slab_manager_create(struct pb_manager *provider, + const struct pb_desc *desc, + size_t smallestSize, + size_t numSizes, + size_t desiredNumBuffers, + size_t maxSlabSize, + size_t pageAlignment); + /** * Fenced buffer manager. * diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c new file mode 100644 index 0000000000..676e8e29b9 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -0,0 +1,429 @@ +/************************************************************************** + * + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * Permission is hereby granted, FREE of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * @file + * S-lab pool implementation. + * + * @author Thomas Hellstrom + * @author Jose Fonseca + */ + +#include "pipe/p_compiler.h" +#include "pipe/p_error.h" +#include "pipe/p_debug.h" +#include "pipe/p_thread.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "util/u_double_list.h" +#include "util/u_time.h" + +#include "pb_buffer.h" +#include "pb_bufmgr.h" + + +#define DRI_SLABPOOL_ALLOC_RETRIES 100 + + +struct pb_slab; + +struct pb_slab_buffer +{ + struct pb_buffer base; + + struct pb_slab *slab; + struct list_head head; + unsigned mapCount; + size_t start; + _glthread_Cond event; +}; + +struct pb_slab +{ + struct list_head head; + struct list_head freeBuffers; + size_t numBuffers; + size_t numFree; + struct pb_slab_buffer *buffers; + struct pb_slab_size_header *header; + + struct pb_buffer *bo; + size_t pageAlignment; + void *virtual; +}; + +struct pb_slab_size_header +{ + struct list_head slabs; + struct list_head freeSlabs; + struct pb_slab_manager *pool; + size_t bufSize; + _glthread_Mutex mutex; +}; + +/** + * The data of this structure remains constant after + * initialization and thus needs no mutex protection. + */ +struct pb_slab_manager +{ + struct pb_manager base; + + struct pb_desc desc; + size_t *bucketSizes; + size_t numBuckets; + size_t pageSize; + struct pb_manager *provider; + unsigned pageAlignment; + unsigned maxSlabSize; + unsigned desiredNumBuffers; + struct pb_slab_size_header *headers; +}; + + +static INLINE struct pb_slab_buffer * +pb_slab_buffer(struct pb_buffer *buf) +{ + assert(buf); + return (struct pb_slab_buffer *)buf; +} + + +static INLINE struct pb_slab_manager * +pb_slab_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct pb_slab_manager *)mgr; +} + + +/** + * Delete a buffer from the slab header delayed list and put + * it on the slab FREE list. + */ +static void +pb_slab_buffer_destroy(struct pb_buffer *_buf) +{ + struct pb_slab_buffer *buf = pb_slab_buffer(_buf); + struct pb_slab *slab = buf->slab; + struct pb_slab_size_header *header = slab->header; + struct list_head *list = &buf->head; + + _glthread_LOCK_MUTEX(header->mutex); + + assert(buf->base.base.refcount == 0); + + buf->mapCount = 0; + + LIST_DEL(list); + LIST_ADDTAIL(list, &slab->freeBuffers); + slab->numFree++; + + if (slab->head.next == &slab->head) + LIST_ADDTAIL(&slab->head, &header->slabs); + + if (slab->numFree == slab->numBuffers) { + list = &slab->head; + LIST_DEL(list); + LIST_ADDTAIL(list, &header->freeSlabs); + } + + if (header->slabs.next == &header->slabs || slab->numFree + != slab->numBuffers) { + + struct list_head *next; + + for (list = header->freeSlabs.next, next = list->next; list + != &header->freeSlabs; list = next, next = list->next) { + + slab = LIST_ENTRY(struct pb_slab, list, head); + + LIST_DELINIT(list); + pb_reference(&slab->bo, NULL); + FREE(slab->buffers); + FREE(slab); + } + } + + _glthread_UNLOCK_MUTEX(header->mutex); +} + + +static void * +pb_slab_buffer_map(struct pb_buffer *_buf, + unsigned flags) +{ + struct pb_slab_buffer *buf = pb_slab_buffer(_buf); + + ++buf->mapCount; + return (void *) ((uint8_t *) buf->slab->virtual + buf->start); +} + + +static void +pb_slab_buffer_unmap(struct pb_buffer *_buf) +{ + struct pb_slab_buffer *buf = pb_slab_buffer(_buf); + + --buf->mapCount; + if (buf->mapCount == 0) + _glthread_COND_BROADCAST(buf->event); +} + + +static void +pb_slab_buffer_get_base_buffer(struct pb_buffer *_buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + struct pb_slab_buffer *buf = pb_slab_buffer(_buf); + pb_get_base_buffer(buf->slab->bo, base_buf, offset); + *offset += buf->start; +} + + +static const struct pb_vtbl +pb_slab_buffer_vtbl = { + pb_slab_buffer_destroy, + pb_slab_buffer_map, + pb_slab_buffer_unmap, + pb_slab_buffer_get_base_buffer +}; + + +static enum pipe_error +pb_slab_create(struct pb_slab_size_header *header) +{ + struct pb_slab_manager *pool = header->pool; + size_t size = header->bufSize * pool->desiredNumBuffers; + struct pb_slab *slab; + struct pb_slab_buffer *buf; + size_t numBuffers; + int ret; + unsigned i; + + slab = CALLOC_STRUCT(pb_slab); + if (!slab) + return PIPE_ERROR_OUT_OF_MEMORY; + + /* + * FIXME: We should perhaps allow some variation in slabsize in order + * to efficiently reuse slabs. + */ + + size = (size <= pool->maxSlabSize) ? size : pool->maxSlabSize; + size = (size + pool->pageSize - 1) & ~(pool->pageSize - 1); + + slab->bo = pool->provider->create_buffer(pool->provider, size, &pool->desc); + if(!slab->bo) + goto out_err0; + + slab->virtual = pb_map(slab->bo, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + if(!slab->virtual) + goto out_err1; + + pb_unmap(slab->bo); + + numBuffers = slab->bo->base.size / header->bufSize; + + slab->buffers = CALLOC(numBuffers, sizeof(*slab->buffers)); + if (!slab->buffers) { + ret = PIPE_ERROR_OUT_OF_MEMORY; + goto out_err1; + } + + LIST_INITHEAD(&slab->head); + LIST_INITHEAD(&slab->freeBuffers); + slab->numBuffers = numBuffers; + slab->numFree = 0; + slab->header = header; + + buf = slab->buffers; + for (i=0; i < numBuffers; ++i) { + buf->base.base.refcount = 0; + buf->base.base.size = header->bufSize; + buf->base.base.alignment = 0; + buf->base.base.usage = 0; + buf->base.vtbl = &pb_slab_buffer_vtbl; + buf->slab = slab; + buf->start = i* header->bufSize; + buf->mapCount = 0; + _glthread_INIT_COND(buf->event); + LIST_ADDTAIL(&buf->head, &slab->freeBuffers); + slab->numFree++; + buf++; + } + + LIST_ADDTAIL(&slab->head, &header->slabs); + + return PIPE_OK; + +out_err1: + pb_reference(&slab->bo, NULL); +out_err0: + FREE(slab); + return ret; +} + + +static struct pb_buffer * +pb_slab_manager_create_buffer(struct pb_manager *_pool, + size_t size, + const struct pb_desc *desc) +{ + struct pb_slab_manager *pool = pb_slab_manager(_pool); + struct pb_slab_size_header *header; + unsigned i; + static struct pb_slab_buffer *buf; + struct pb_slab *slab; + struct list_head *list; + int count = DRI_SLABPOOL_ALLOC_RETRIES; + + /* + * FIXME: Check for compatibility. + */ + + header = pool->headers; + for (i=0; inumBuckets; ++i) { + if (header->bufSize >= size) + break; + header++; + } + + if (i >= pool->numBuckets) + /* Fall back to allocate a buffer object directly from the provider. */ + return pool->provider->create_buffer(pool->provider, size, desc); + + + _glthread_LOCK_MUTEX(header->mutex); + while (header->slabs.next == &header->slabs && count > 0) { + if (header->slabs.next != &header->slabs) + break; + + _glthread_UNLOCK_MUTEX(header->mutex); + if (count != DRI_SLABPOOL_ALLOC_RETRIES) + util_time_sleep(1); + _glthread_LOCK_MUTEX(header->mutex); + (void) pb_slab_create(header); + count--; + } + + list = header->slabs.next; + if (list == &header->slabs) { + _glthread_UNLOCK_MUTEX(header->mutex); + return NULL; + } + slab = LIST_ENTRY(struct pb_slab, list, head); + if (--slab->numFree == 0) + LIST_DELINIT(list); + + list = slab->freeBuffers.next; + LIST_DELINIT(list); + + _glthread_UNLOCK_MUTEX(header->mutex); + buf = LIST_ENTRY(struct pb_slab_buffer, list, head); + ++buf->base.base.refcount; + return &buf->base; +} + + +static void +pb_slab_manager_destroy(struct pb_manager *_pool) +{ + struct pb_slab_manager *pool = pb_slab_manager(_pool); + + FREE(pool->headers); + FREE(pool->bucketSizes); + FREE(pool); +} + + +struct pb_manager * +pb_slab_manager_create(struct pb_manager *provider, + const struct pb_desc *desc, + size_t smallestSize, + size_t numSizes, + size_t desiredNumBuffers, + size_t maxSlabSize, + size_t pageAlignment) +{ + struct pb_slab_manager *pool; + size_t i; + + pool = CALLOC_STRUCT(pb_slab_manager); + if (!pool) + goto out_err0; + + pool->bucketSizes = CALLOC(numSizes, sizeof(*pool->bucketSizes)); + if (!pool->bucketSizes) + goto out_err1; + + pool->headers = CALLOC(numSizes, sizeof(*pool->headers)); + if (!pool->headers) + goto out_err2; + + pool->desc = *desc; + pool->numBuckets = numSizes; +#ifdef WIN32 + pool->pageSize = 4096; +#else + pool->pageSize = getpagesize(); +#endif + pool->provider = provider; + pool->pageAlignment = pageAlignment; + pool->maxSlabSize = maxSlabSize; + pool->desiredNumBuffers = desiredNumBuffers; + + for (i=0; inumBuckets; ++i) { + struct pb_slab_size_header *header = &pool->headers[i]; + + pool->bucketSizes[i] = (smallestSize << i); + + _glthread_INIT_MUTEX(header->mutex); + + LIST_INITHEAD(&header->slabs); + LIST_INITHEAD(&header->freeSlabs); + + header->pool = pool; + header->bufSize = (smallestSize << i); + } + + pool->base.destroy = pb_slab_manager_destroy; + pool->base.create_buffer = pb_slab_manager_create_buffer; + + return &pool->base; + +out_err2: + FREE(pool->bucketSizes); +out_err1: + FREE(pool); +out_err0: + return NULL; +} -- cgit v1.2.3 From fb2b5f7a4ac411a5bb5cde12ba15265b30c032e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 13 Apr 2008 15:10:01 +0900 Subject: gallium: Buffer cache. --- src/gallium/auxiliary/pipebuffer/Makefile | 1 + src/gallium/auxiliary/pipebuffer/SConscript | 1 + src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 20 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 299 +++++++++++++++++++++ 4 files changed, 318 insertions(+), 3 deletions(-) create mode 100644 src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile index 0770cad45a..d654dbcc91 100644 --- a/src/gallium/auxiliary/pipebuffer/Makefile +++ b/src/gallium/auxiliary/pipebuffer/Makefile @@ -6,6 +6,7 @@ LIBNAME = pipebuffer C_SOURCES = \ pb_buffer_fenced.c \ pb_buffer_malloc.c \ + pb_bufmgr_cache.c \ pb_bufmgr_fenced.c \ pb_bufmgr_mm.c \ pb_bufmgr_pool.c \ diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript index 14c3c77e37..604a217982 100644 --- a/src/gallium/auxiliary/pipebuffer/SConscript +++ b/src/gallium/auxiliary/pipebuffer/SConscript @@ -5,6 +5,7 @@ pipebuffer = env.ConvenienceLibrary( source = [ 'pb_buffer_fenced.c', 'pb_buffer_malloc.c', + 'pb_bufmgr_cache.c', 'pb_bufmgr_fenced.c', 'pb_bufmgr_mm.c', 'pb_bufmgr_pool.c', diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index a2377f70e2..b2d2520b67 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -80,7 +80,7 @@ struct pb_manager /** - * Static buffer pool manager. + * Static buffer pool sub-allocator. * * Manages the allocation of equally sized buffers. It does so by allocating * a single big buffer and divide it equally sized buffers. @@ -94,7 +94,7 @@ pool_bufmgr_create(struct pb_manager *provider, /** - * Wraper around the old memory manager. + * Static sub-allocator based the old memory manager. * * It managers buffers of different sizes. It does so by allocating a buffer * with the size of the heap, and then using the old mm memory manager to manage @@ -114,6 +114,9 @@ mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, size_t size, size_t align2); +/** + * Slab sub-allocator. + */ struct pb_manager * pb_slab_manager_create(struct pb_manager *provider, const struct pb_desc *desc, @@ -122,7 +125,18 @@ pb_slab_manager_create(struct pb_manager *provider, size_t desiredNumBuffers, size_t maxSlabSize, size_t pageAlignment); - + + +/** + * Time-based buffer cache. + * + * This manager keeps a cache of destroyed buffers during a time interval. + */ +struct pb_manager * +pb_cache_manager_create(struct pb_manager *provider, + unsigned usecs); + + /** * Fenced buffer manager. * diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c new file mode 100644 index 0000000000..06de0bb6c3 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -0,0 +1,299 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Buffer cache. + * + * \author José Fonseca + * \author Thomas Hellström + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_winsys.h" +#include "pipe/p_thread.h" +#include "pipe/p_util.h" +#include "util/u_double_list.h" +#include "util/u_time.h" + +#include "pb_buffer.h" +#include "pb_bufmgr.h" + + +/** + * Convenience macro (type safe). + */ +#define SUPER(__derived) (&(__derived)->base) + + +struct pb_cache_manager; + + +/** + * Wrapper around a pipe buffer which adds delayed destruction. + */ +struct pb_cache_buffer +{ + struct pb_buffer base; + + struct pb_buffer *buffer; + struct pb_cache_manager *mgr; + + /** Caching time interval */ + struct util_time start, end; + + struct list_head head; +}; + + +struct pb_cache_manager +{ + struct pb_manager base; + + struct pb_manager *provider; + unsigned usecs; + + _glthread_Mutex mutex; + + struct list_head delayed; + size_t numDelayed; +}; + + +static INLINE struct pb_cache_buffer * +pb_cache_buffer(struct pb_buffer *buf) +{ + assert(buf); + return (struct pb_cache_buffer *)buf; +} + + +static INLINE struct pb_cache_manager * +pb_cache_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct pb_cache_manager *)mgr; +} + + +/** + * Actually destroy the buffer. + */ +static INLINE void +_pb_cache_buffer_destroy(struct pb_cache_buffer *buf) +{ + struct pb_cache_manager *mgr = buf->mgr; + + LIST_DEL(&buf->head); + assert(mgr->numDelayed); + --mgr->numDelayed; + assert(!buf->base.base.refcount); + pb_reference(&buf->buffer, NULL); + FREE(buf); +} + + +/** + * Free as many cache buffers from the list head as possible. + */ +static void +_pb_cache_buffer_list_check_free(struct pb_cache_manager *mgr) +{ + struct list_head *curr, *next; + struct pb_cache_buffer *buf; + struct util_time now; + + util_time_get(&now); + + curr = mgr->delayed.next; + next = curr->next; + while(curr != &mgr->delayed) { + buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); + + if(util_time_timeout(&buf->start, &buf->end, &now) != 0) + break; + + _pb_cache_buffer_destroy(buf); + + curr = next; + next = curr->next; + } +} + + +static void +pb_cache_buffer_destroy(struct pb_buffer *_buf) +{ + struct pb_cache_buffer *buf = pb_cache_buffer(_buf); + struct pb_cache_manager *mgr = buf->mgr; + + _glthread_LOCK_MUTEX(mgr->mutex); + assert(buf->base.base.refcount == 0); + + _pb_cache_buffer_list_check_free(mgr); + + util_time_get(&buf->start); + util_time_add(&buf->start, mgr->usecs, &buf->end); + LIST_ADDTAIL(&buf->head, &mgr->delayed); + ++mgr->numDelayed; + _glthread_UNLOCK_MUTEX(mgr->mutex); +} + + +static void * +pb_cache_buffer_map(struct pb_buffer *_buf, + unsigned flags) +{ + struct pb_cache_buffer *buf = pb_cache_buffer(_buf); + return pb_map(buf->buffer, flags); +} + + +static void +pb_cache_buffer_unmap(struct pb_buffer *_buf) +{ + struct pb_cache_buffer *buf = pb_cache_buffer(_buf); + pb_unmap(buf->buffer); +} + + +static void +pb_cache_buffer_get_base_buffer(struct pb_buffer *_buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + struct pb_cache_buffer *buf = pb_cache_buffer(_buf); + pb_get_base_buffer(buf->buffer, base_buf, offset); +} + + +const struct pb_vtbl +pb_cache_buffer_vtbl = { + pb_cache_buffer_destroy, + pb_cache_buffer_map, + pb_cache_buffer_unmap, + pb_cache_buffer_get_base_buffer +}; + + +static struct pb_buffer * +pb_cache_manager_create_buffer(struct pb_manager *_mgr, + size_t size, + const struct pb_desc *desc) +{ + struct pb_cache_manager *mgr = pb_cache_manager(_mgr); + struct pb_cache_buffer *buf; + struct list_head *curr, *next; + struct util_time now; + + util_time_get(&now); + curr = mgr->delayed.next; + next = curr->next; + while(curr != &mgr->delayed) { + buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); + + if(buf->base.base.size == size && + buf->base.base.alignment >= desc->alignment && + (buf->base.base.alignment % desc->alignment) == 0 && + /* buf->base.base.usage == usage */ 1) { + ++buf->base.base.refcount; + return &buf->base; + } + + if(util_time_timeout(&buf->start, &buf->end, &now) != 0) + _pb_cache_buffer_destroy(buf); + + curr = next; + next = curr->next; + } + + buf = CALLOC_STRUCT(pb_cache_buffer); + if(!buf) + return NULL; + + buf->buffer = mgr->provider->create_buffer(mgr->provider, size, desc); + if(!buf->buffer) { + FREE(buf); + return NULL; + } + + buf->base.base.refcount = 1; + buf->base.base.alignment = buf->buffer->base.alignment; + buf->base.base.usage = buf->buffer->base.usage; + buf->base.base.size = buf->buffer->base.size; + + buf->base.vtbl = &pb_cache_buffer_vtbl; + buf->mgr = mgr; + + return &buf->base; +} + + +static void +pb_cache_manager_destroy(struct pb_manager *_mgr) +{ + struct pb_cache_manager *mgr = pb_cache_manager(_mgr); + struct list_head *curr, *next; + struct pb_cache_buffer *buf; + + _glthread_LOCK_MUTEX(mgr->mutex); + curr = mgr->delayed.next; + next = curr->next; + while(curr != &mgr->delayed) { + buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); + _pb_cache_buffer_destroy(buf); + curr = next; + next = curr->next; + } + _glthread_UNLOCK_MUTEX(mgr->mutex); + + FREE(mgr); +} + + +struct pb_manager * +pb_cache_manager_create(struct pb_manager *provider, + unsigned usecs) +{ + struct pb_cache_manager *mgr; + + mgr = (struct pb_cache_manager *)CALLOC(1, sizeof(*mgr)); + if (!mgr) + return NULL; + + mgr->base.destroy = pb_cache_manager_destroy; + mgr->base.create_buffer = pb_cache_manager_create_buffer; + mgr->provider = provider; + mgr->usecs = usecs; + LIST_INITHEAD(&mgr->delayed); + mgr->numDelayed = 0; + _glthread_INIT_MUTEX(mgr->mutex); + + return &mgr->base; +} -- cgit v1.2.3 From 84994693f53668d5ca72d57765a0729fe343593b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 13 Apr 2008 18:52:54 +0900 Subject: gallium: Add u_time.c --- src/gallium/auxiliary/util/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index fe82fa6378..05bc43131a 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -15,6 +15,7 @@ C_SOURCES = \ u_mm.c \ u_simple_shaders.c \ u_snprintf.c \ + u_time.c \ u_mm.c include ../../Makefile.template -- cgit v1.2.3 From 4f550ab821f9aef9f19d9f1e10785f8c1f511ad4 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 7 Apr 2008 20:38:39 -0400 Subject: introduce a define to maxout the processed vertices --- src/gallium/auxiliary/draw/draw_vertex_shader.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index 133418baca..d5f37bca21 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -37,7 +37,7 @@ #include "draw_context.h" #include "draw_vs.h" - +#define MAX_SHADER_VERTICES 4 /** * Run the vertex shader on all vertices in the vertex queue. @@ -58,23 +58,23 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) // fprintf(stderr, "%s %d\n", __FUNCTION__, draw->vs.queue_nr ); /* run vertex shader on vertex cache entries, four per invokation */ - for (i = 0; i < draw->vs.queue_nr; i += 4) { - struct vertex_header *dests[4]; - unsigned elts[4]; - int j, n = MIN2(4, draw->vs.queue_nr - i); + for (i = 0; i < draw->vs.queue_nr; i += MAX_SHADER_VERTICES) { + struct vertex_header *dests[MAX_SHADER_VERTICES]; + unsigned elts[MAX_SHADER_VERTICES]; + int j, n = MIN2(MAX_SHADER_VERTICES, - i); for (j = 0; j < n; j++) { elts[j] = draw->vs.queue[i + j].elt; dests[j] = draw->vs.queue[i + j].vertex; } - for ( ; j < 4; j++) { + for ( ; j < MAX_SHADER_VERTICES; j++) { elts[j] = elts[0]; dests[j] = draw->vs.queue[i + j].vertex; } assert(n > 0); - assert(n <= 4); + assert(n <= MAX_SHADER_VERTICES); shader->run(shader, draw, elts, n, dests); } -- cgit v1.2.3 From aadbb1d7fbbaada6e378cb60194e5861cadf98d1 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 12 Apr 2008 15:45:28 -0400 Subject: pass arbitrary number of vertices to the shader execution cycle --- src/gallium/auxiliary/draw/draw_private.h | 2 + src/gallium/auxiliary/draw/draw_vertex_shader.c | 4 +- src/gallium/auxiliary/draw/draw_vs_exec.c | 144 ++++++++++++------------ src/gallium/auxiliary/draw/draw_vs_sse.c | 139 +++++++++++------------ 4 files changed, 146 insertions(+), 143 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 4d056f6dba..f9aea9f355 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -56,6 +56,8 @@ struct gallivm_cpu_engine; struct draw_pt_middle_end; struct draw_pt_front_end; +#define MAX_SHADER_VERTICES 128 + /** * Basic vertex info. * Carry some useful information around with the vertices in the prim pipe. diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index d5f37bca21..726921d77b 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -37,8 +37,6 @@ #include "draw_context.h" #include "draw_vs.h" -#define MAX_SHADER_VERTICES 4 - /** * Run the vertex shader on all vertices in the vertex queue. * Called by the draw module when the vertx cache needs to be flushed. @@ -61,7 +59,7 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) for (i = 0; i < draw->vs.queue_nr; i += MAX_SHADER_VERTICES) { struct vertex_header *dests[MAX_SHADER_VERTICES]; unsigned elts[MAX_SHADER_VERTICES]; - int j, n = MIN2(MAX_SHADER_VERTICES, - i); + int j, n = MIN2(MAX_SHADER_VERTICES, draw->vs.queue_nr - i); for (j = 0; j < n; j++) { elts[j] = draw->vs.queue[i + j].elt; diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 9629410abb..df0051d693 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -40,6 +40,7 @@ #include "tgsi/util/tgsi_parse.h" +#define MAX_TGSI_VERTICES 4 static void vs_exec_prepare( struct draw_vertex_shader *shader, @@ -71,14 +72,13 @@ vs_exec_run( struct draw_vertex_shader *shader, struct vertex_header *vOut[] ) { struct tgsi_exec_machine *machine = &draw->machine; - unsigned int j; + unsigned int i, j; ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; - assert(count <= 4); assert(draw->vertex_shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); @@ -92,80 +92,82 @@ vs_exec_run( struct draw_vertex_shader *shader, machine->Outputs = ALIGN16_ASSIGN(outputs); } - draw->vertex_fetch.fetch_func( draw, machine, elts, count ); + for (i = 0; i < count; i += MAX_TGSI_VERTICES) { + unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); + draw->vertex_fetch.fetch_func( draw, machine, &elts[i], max_vertices ); - if (!draw->rasterizer->bypass_vs) { - /* run interpreter */ - tgsi_exec_machine_run( machine ); - } - - /* store machine results */ - for (j = 0; j < count; j++) { - unsigned slot; - float x, y, z, w; - - /* Handle attr[0] (position) specially: - * - * XXX: Computing the clipmask should be done in the vertex - * program as a set of DP4 instructions appended to the - * user-provided code. - */ - x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; - - if (!draw->rasterizer->bypass_clipping) { - vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - } - else { - vOut[j]->clipmask = 0; - } - vOut[j]->edgeflag = 1; - - if (!draw->identity_viewport) { - /* Viewport mapping */ - vOut[j]->data[0][0] = x * scale[0] + trans[0]; - vOut[j]->data[0][1] = y * scale[1] + trans[1]; - vOut[j]->data[0][2] = z * scale[2] + trans[2]; - vOut[j]->data[0][3] = w; - } - else { - vOut[j]->data[0][0] = x; - vOut[j]->data[0][1] = y; - vOut[j]->data[0][2] = z; - vOut[j]->data[0][3] = w; + if (!draw->rasterizer->bypass_vs) { + /* run interpreter */ + tgsi_exec_machine_run( machine ); } - /* Remaining attributes are packed into sequential post-transform - * vertex attrib slots. - */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; - } + /* store machine results */ + for (j = 0; j < max_vertices; j++) { + unsigned slot; + float x, y, z, w; + + /* Handle attr[0] (position) specially: + * + * XXX: Computing the clipmask should be done in the vertex + * program as a set of DP4 instructions appended to the + * user-provided code. + */ + x = vOut[i + j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = vOut[i + j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = vOut[i + j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = vOut[i + j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + + if (!draw->rasterizer->bypass_clipping) { + vOut[i + j]->clipmask = compute_clipmask(vOut[i + j]->clip, draw->plane, + draw->nr_planes); + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; + } + else { + vOut[i + j]->clipmask = 0; + } + vOut[i + j]->edgeflag = 1; + + if (!draw->identity_viewport) { + /* Viewport mapping */ + vOut[i + j]->data[0][0] = x * scale[0] + trans[0]; + vOut[i + j]->data[0][1] = y * scale[1] + trans[1]; + vOut[i + j]->data[0][2] = z * scale[2] + trans[2]; + vOut[i + j]->data[0][3] = w; + } + else { + vOut[i + j]->data[0][0] = x; + vOut[i + j]->data[0][1] = y; + vOut[i + j]->data[0][2] = z; + vOut[i + j]->data[0][3] = w; + } + + /* Remaining attributes are packed into sequential post-transform + * vertex attrib slots. + */ + for (slot = 1; slot < draw->num_vs_outputs; slot++) { + vOut[i + j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + vOut[i + j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + vOut[i + j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + vOut[i + j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } #if 0 /*DEBUG*/ - printf("Post xform vert:\n"); - for (slot = 0; slot < draw->num_vs_outputs; slot++) { - printf("%d: %f %f %f %f\n", slot, - vOut[j]->data[slot][0], - vOut[j]->data[slot][1], - vOut[j]->data[slot][2], - vOut[j]->data[slot][3]); - } -#endif - - - } /* loop over vertices */ + printf("%d) Post xform vert:\n", i + j); + for (slot = 0; slot < draw->num_vs_outputs; slot++) { + printf("\t%d: %f %f %f %f\n", slot, + vOut[i + j]->data[slot][0], + vOut[i + j]->data[slot][1], + vOut[i + j]->data[slot][2], + vOut[i + j]->data[slot][3]); + } +#endif + } /* loop over vertices */ + } } diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 0ee991d764..bfec89254e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -45,6 +45,7 @@ #include "tgsi/exec/tgsi_sse2.h" #include "tgsi/util/tgsi_parse.h" +#define SSE_MAX_VERTICES 4 typedef void (XSTDCALL *codegen_function) ( const struct tgsi_exec_vector *input, @@ -86,14 +87,13 @@ vs_sse_run( struct draw_vertex_shader *base, { struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; struct tgsi_exec_machine *machine = &draw->machine; - unsigned int j; + unsigned int i, j; ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; - assert(count <= 4); assert(draw->vertex_shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); @@ -108,77 +108,78 @@ vs_sse_run( struct draw_vertex_shader *base, machine->Outputs = ALIGN16_ASSIGN(outputs); } - - /* Fetch vertices. This may at some point be integrated into the - * compiled shader -- that would require a reorganization where - * multiple versions of the compiled shader might exist, - * specialized for each fetch state. - */ - draw->vertex_fetch.fetch_func( draw, machine, elts, count ); - - - if (!draw->rasterizer->bypass_vs) { - /* run compiled shader - */ - shader->func(machine->Inputs, - machine->Outputs, - machine->Consts, - machine->Temps, - shader->immediates); - } - - - /* XXX: Computing the clipmask and emitting results should be done - * in the vertex program as a set of instructions appended to - * the user-provided code. - */ - for (j = 0; j < count; j++) { - unsigned slot; - float x, y, z, w; - - x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; - - if (!draw->rasterizer->bypass_clipping) { - vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - } - else { - vOut[j]->clipmask = 0; - } - vOut[j]->edgeflag = 1; - - if (!draw->identity_viewport) { - /* Viewport mapping */ - vOut[j]->data[0][0] = x * scale[0] + trans[0]; - vOut[j]->data[0][1] = y * scale[1] + trans[1]; - vOut[j]->data[0][2] = z * scale[2] + trans[2]; - vOut[j]->data[0][3] = w; - } - else { - vOut[j]->data[0][0] = x; - vOut[j]->data[0][1] = y; - vOut[j]->data[0][2] = z; - vOut[j]->data[0][3] = w; + for (i = 0; i < count; i += SSE_MAX_VERTICES) { + unsigned int max_vertices = MIN2(SSE_MAX_VERTICES, count - i); + /* Fetch vertices. This may at some point be integrated into the + * compiled shader -- that would require a reorganization where + * multiple versions of the compiled shader might exist, + * specialized for each fetch state. + */ + draw->vertex_fetch.fetch_func(draw, machine, &elts[i], max_vertices); + + if (!draw->rasterizer->bypass_vs) { + /* run compiled shader + */ + shader->func(machine->Inputs, + machine->Outputs, + machine->Consts, + machine->Temps, + shader->immediates); } - /* Remaining attributes are packed into sequential post-transform - * vertex attrib slots. + /* XXX: Computing the clipmask and emitting results should be done + * in the vertex program as a set of instructions appended to + * the user-provided code. */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + for (j = 0; j < max_vertices; j++) { + unsigned slot; + float x, y, z, w; + + x = vOut[i + j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = vOut[i + j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = vOut[i + j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = vOut[i + j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + + if (!draw->rasterizer->bypass_clipping) { + vOut[i + j]->clipmask = compute_clipmask(vOut[i + j]->clip, draw->plane, + draw->nr_planes); + + /* divide by w */ + w = 1.0f / w; + x *= w; + y *= w; + z *= w; + } + else { + vOut[i + j]->clipmask = 0; + } + vOut[j]->edgeflag = 1; + + if (!draw->identity_viewport) { + /* Viewport mapping */ + vOut[i + j]->data[0][0] = x * scale[0] + trans[0]; + vOut[i + j]->data[0][1] = y * scale[1] + trans[1]; + vOut[i + j]->data[0][2] = z * scale[2] + trans[2]; + vOut[i + j]->data[0][3] = w; + } + else { + vOut[i + j]->data[0][0] = x; + vOut[i + j]->data[0][1] = y; + vOut[i + j]->data[0][2] = z; + vOut[i + j]->data[0][3] = w; + } + + /* Remaining attributes are packed into sequential post-transform + * vertex attrib slots. + */ + for (slot = 1; slot < draw->num_vs_outputs; slot++) { + vOut[i + j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + vOut[i + j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + vOut[i + j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + vOut[i + j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } } - } + } } -- cgit v1.2.3 From 808f968f3ad0cb32e86f517753d5715d00e9ec2c Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 11 Apr 2008 19:58:22 -0400 Subject: return true if one of the vertices has been clipped --- src/gallium/auxiliary/draw/draw_private.h | 12 ++++++------ src/gallium/auxiliary/draw/draw_vs_exec.c | 5 ++++- src/gallium/auxiliary/draw/draw_vs_llvm.c | 18 +++++++++++------- src/gallium/auxiliary/draw/draw_vs_sse.c | 5 ++++- 4 files changed, 25 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index f9aea9f355..5c710667fc 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -148,12 +148,12 @@ struct draw_vertex_shader { /* Run the shader - this interface will get cleaned up in the * future: */ - void (*run)( struct draw_vertex_shader *shader, - struct draw_context *draw, - const unsigned *elts, - unsigned count, - struct vertex_header *vOut[] ); - + boolean (*run)( struct draw_vertex_shader *shader, + struct draw_context *draw, + const unsigned *elts, + unsigned count, + struct vertex_header *vOut[] ); + void (*delete)( struct draw_vertex_shader * ); }; diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index df0051d693..09e0d0eaab 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -64,7 +64,7 @@ vs_exec_prepare( struct draw_vertex_shader *shader, * \param count number of vertices to shade [1..4] * \param vOut array of pointers to four output vertices */ -static void +static boolean vs_exec_run( struct draw_vertex_shader *shader, struct draw_context *draw, const unsigned *elts, @@ -73,6 +73,7 @@ vs_exec_run( struct draw_vertex_shader *shader, { struct tgsi_exec_machine *machine = &draw->machine; unsigned int i, j; + unsigned int clipped = 0; ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); @@ -120,6 +121,7 @@ vs_exec_run( struct draw_vertex_shader *shader, if (!draw->rasterizer->bypass_clipping) { vOut[i + j]->clipmask = compute_clipmask(vOut[i + j]->clip, draw->plane, draw->nr_planes); + clipped += vOut[i + j]->clipmask; /* divide by w */ w = 1.0f / w; @@ -168,6 +170,7 @@ vs_exec_run( struct draw_vertex_shader *shader, #endif } /* loop over vertices */ } + return clipped != 0; } diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 7e48428cdd..6db1e65a2d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -67,18 +67,19 @@ vs_llvm_prepare( struct draw_vertex_shader *base, * \param count number of vertices to shade [1..4] * \param vOut array of pointers to four output vertices */ -static void +static boolean vs_llvm_run( struct draw_vertex_shader *base, - struct draw_context *draw, - const unsigned *elts, + struct draw_context *draw, + const unsigned *elts, unsigned count, struct vertex_header *vOut[] ) { - struct draw_llvm_vertex_shader *shader = + struct draw_llvm_vertex_shader *shader = (struct draw_llvm_vertex_shader *)base; struct tgsi_exec_machine *machine = &draw->machine; unsigned int j; + unsigned int clipped = 0; ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); @@ -125,19 +126,21 @@ vs_llvm_run( struct draw_vertex_shader *base, w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; if (!draw->rasterizer->bypass_clipping) { - vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes); + vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, + draw->nr_planes); + clipped += vOut[j]->clipmask; /* divide by w */ w = 1.0f / w; x *= w; y *= w; - z *= w; + z *= w; } else { vOut[j]->clipmask = 0; } vOut[j]->edgeflag = 1; - + if (!draw->identity_viewport) { /* Viewport mapping */ vOut[j]->data[0][0] = x * scale[0] + trans[0]; @@ -162,6 +165,7 @@ vs_llvm_run( struct draw_vertex_shader *base, vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; } } /* loop over vertices */ + return clipped != 0; } static void diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index bfec89254e..6e8d2021f5 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -78,7 +78,7 @@ vs_sse_prepare( struct draw_vertex_shader *base, * \param count number of vertices to shade [1..4] * \param vOut array of pointers to four output vertices */ -static void +static boolean vs_sse_run( struct draw_vertex_shader *base, struct draw_context *draw, const unsigned *elts, @@ -88,6 +88,7 @@ vs_sse_run( struct draw_vertex_shader *base, struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; struct tgsi_exec_machine *machine = &draw->machine; unsigned int i, j; + unsigned int clipped = 0; ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); @@ -143,6 +144,7 @@ vs_sse_run( struct draw_vertex_shader *base, if (!draw->rasterizer->bypass_clipping) { vOut[i + j]->clipmask = compute_clipmask(vOut[i + j]->clip, draw->plane, draw->nr_planes); + clipped += vOut[i + j]->clipmask; /* divide by w */ w = 1.0f / w; @@ -180,6 +182,7 @@ vs_sse_run( struct draw_vertex_shader *base, } } } + return clipped != 0; } -- cgit v1.2.3 From 3f7a3dd58c0ce2719af83ff1d89a26185d08c04c Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 12 Apr 2008 21:52:46 -0400 Subject: Make shaders operate on a block of memory instead of arrays of vertex_header's --- src/gallium/auxiliary/draw/draw_context.c | 10 ++--- src/gallium/auxiliary/draw/draw_private.h | 15 ++++--- src/gallium/auxiliary/draw/draw_vertex_cache.c | 33 +++++++++------ src/gallium/auxiliary/draw/draw_vertex_shader.c | 7 ++-- src/gallium/auxiliary/draw/draw_vs_exec.c | 54 ++++++++++++------------ src/gallium/auxiliary/draw/draw_vs_llvm.c | 2 +- src/gallium/auxiliary/draw/draw_vs_sse.c | 56 +++++++++++++++---------- 7 files changed, 100 insertions(+), 77 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index b3c65c90d6..cdca556fbd 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -86,14 +86,12 @@ struct draw_context *draw_create( void ) /* Statically allocate maximum sized vertices for the cache - could be cleverer... */ { - uint i; const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; - char *tmp = align_malloc(Elements(draw->vs.queue) * size, 16); + char *tmp = align_malloc(VS_QUEUE_LENGTH * size, 16); if (!tmp) goto fail; - for (i = 0; i < Elements(draw->vs.queue); i++) - draw->vs.queue[i].vertex = (struct vertex_header *)(tmp + i * size); + draw->vs.vertex_cache = tmp; } draw->shader_queue_flush = draw_vertex_shader_queue_flush; @@ -156,8 +154,8 @@ void draw_destroy( struct draw_context *draw ) tgsi_exec_machine_free_data(&draw->machine); - if (draw->vs.queue[0].vertex) - align_free( draw->vs.queue[0].vertex ); /* Frees all the vertices. */ + if (draw->vs.vertex_cache) + align_free( draw->vs.vertex_cache ); /* Frees all the vertices. */ /* Not so fast -- we're just borrowing this at the moment. * diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 5c710667fc..1115166192 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -152,7 +152,7 @@ struct draw_vertex_shader { struct draw_context *draw, const unsigned *elts, unsigned count, - struct vertex_header *vOut[] ); + void *out ); void (*delete)( struct draw_vertex_shader * ); @@ -321,10 +321,8 @@ struct draw_context /* Vertex shader queue: */ struct { - struct { - unsigned elt; /**< index into the user's vertex arrays */ - struct vertex_header *vertex; - } queue[VS_QUEUE_LENGTH]; + unsigned elts[VS_QUEUE_LENGTH]; /**< index into the user's vertex arrays */ + char *vertex_cache; unsigned queue_nr; unsigned post_nr; } vs; @@ -450,4 +448,11 @@ dot4(const float *a, const float *b) return result; } +static INLINE struct vertex_header * +draw_header_from_block(char *block, int num) +{ + static const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; + return (struct vertex_header*)(block + num * size); +} + #endif /* DRAW_PRIVATE_H */ diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c index c0248979e2..9256dec4ea 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_cache.c +++ b/src/gallium/auxiliary/draw/draw_vertex_cache.c @@ -71,25 +71,27 @@ static struct vertex_header *get_vertex( struct draw_context *draw, /* Cache hit? */ if (draw->vcache.idx[slot].in == i) { -// _mesa_printf("HIT %d %d\n", slot, i); + /*debug_printf("HIT %d %d\n", slot, i);*/ assert(draw->vcache.idx[slot].out < draw->vs.queue_nr); - return draw->vs.queue[draw->vcache.idx[slot].out].vertex; + return draw_header_from_block(draw->vs.vertex_cache, + draw->vcache.idx[slot].out); } /* Otherwise a collision */ slot = VCACHE_SIZE + draw->vcache.overflow++; -// _mesa_printf("XXX %d --> %d\n", i, slot); + /*debug_printf("XXX %d --> %d\n", i, slot);*/ } /* Deal with the cache miss: */ { unsigned out; - + struct vertex_header *header; + assert(slot < Elements(draw->vcache.idx)); -// _mesa_printf("NEW %d %d\n", slot, i); + /*debug_printf("NEW %d %d\n", slot, i);*/ draw->vcache.idx[slot].in = i; draw->vcache.idx[slot].out = out = draw->vs.queue_nr++; draw->vcache.referenced |= (1 << slot); @@ -99,17 +101,19 @@ static struct vertex_header *get_vertex( struct draw_context *draw, */ assert(draw->vs.queue_nr < VS_QUEUE_LENGTH); - draw->vs.queue[out].elt = i; - draw->vs.queue[out].vertex->clipmask = 0; - draw->vs.queue[out].vertex->edgeflag = draw_get_edgeflag(draw, i); - draw->vs.queue[out].vertex->pad = 0; - draw->vs.queue[out].vertex->vertex_id = UNDEFINED_VERTEX_ID; + header = draw_header_from_block(draw->vs.vertex_cache, out); + draw->vs.elts[out] = i; + header->clipmask = 0; + header->edgeflag = draw_get_edgeflag(draw, i); + header->pad = 0; + header->vertex_id = UNDEFINED_VERTEX_ID; /* Need to set the vertex's edge flag here. If we're being called * by do_ef_triangle(), that function needs edge flag info! */ - return draw->vs.queue[draw->vcache.idx[slot].out].vertex; + return draw_header_from_block(draw->vs.vertex_cache, + draw->vcache.idx[slot].out); } } @@ -142,8 +146,11 @@ void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ) { unsigned i; - for (i = 0; i < draw->vs.post_nr; i++) - draw->vs.queue[i].vertex->vertex_id = UNDEFINED_VERTEX_ID; + for (i = 0; i < draw->vs.post_nr; i++) { + struct vertex_header * header = + draw_header_from_block(draw->vs.vertex_cache, i); + header->vertex_id = UNDEFINED_VERTEX_ID; + } } diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index 726921d77b..452d0175c3 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -57,18 +57,17 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) /* run vertex shader on vertex cache entries, four per invokation */ for (i = 0; i < draw->vs.queue_nr; i += MAX_SHADER_VERTICES) { - struct vertex_header *dests[MAX_SHADER_VERTICES]; unsigned elts[MAX_SHADER_VERTICES]; int j, n = MIN2(MAX_SHADER_VERTICES, draw->vs.queue_nr - i); + struct vertex_header *dests = + draw_header_from_block(draw->vs.vertex_cache, i); for (j = 0; j < n; j++) { - elts[j] = draw->vs.queue[i + j].elt; - dests[j] = draw->vs.queue[i + j].vertex; + elts[j] = draw->vs.elts[i + j]; } for ( ; j < MAX_SHADER_VERTICES; j++) { elts[j] = elts[0]; - dests[j] = draw->vs.queue[i + j].vertex; } assert(n > 0); diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 09e0d0eaab..6fe4e554d5 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -69,7 +69,7 @@ vs_exec_run( struct draw_vertex_shader *shader, struct draw_context *draw, const unsigned *elts, unsigned count, - struct vertex_header *vOut[] ) + void *vOut ) { struct tgsi_exec_machine *machine = &draw->machine; unsigned int i, j; @@ -106,6 +106,8 @@ vs_exec_run( struct draw_vertex_shader *shader, for (j = 0; j < max_vertices; j++) { unsigned slot; float x, y, z, w; + struct vertex_header *out = + draw_header_from_block(vOut, i + j); /* Handle attr[0] (position) specially: * @@ -113,15 +115,15 @@ vs_exec_run( struct draw_vertex_shader *shader, * program as a set of DP4 instructions appended to the * user-provided code. */ - x = vOut[i + j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[i + j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[i + j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[i + j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + x = out->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = out->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = out->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = out->clip[3] = machine->Outputs[0].xyzw[3].f[j]; if (!draw->rasterizer->bypass_clipping) { - vOut[i + j]->clipmask = compute_clipmask(vOut[i + j]->clip, draw->plane, - draw->nr_planes); - clipped += vOut[i + j]->clipmask; + out->clipmask = compute_clipmask(out->clip, draw->plane, + draw->nr_planes); + clipped += out->clipmask; /* divide by w */ w = 1.0f / w; @@ -130,42 +132,42 @@ vs_exec_run( struct draw_vertex_shader *shader, z *= w; } else { - vOut[i + j]->clipmask = 0; + out->clipmask = 0; } - vOut[i + j]->edgeflag = 1; + out->edgeflag = 1; if (!draw->identity_viewport) { /* Viewport mapping */ - vOut[i + j]->data[0][0] = x * scale[0] + trans[0]; - vOut[i + j]->data[0][1] = y * scale[1] + trans[1]; - vOut[i + j]->data[0][2] = z * scale[2] + trans[2]; - vOut[i + j]->data[0][3] = w; + out->data[0][0] = x * scale[0] + trans[0]; + out->data[0][1] = y * scale[1] + trans[1]; + out->data[0][2] = z * scale[2] + trans[2]; + out->data[0][3] = w; } else { - vOut[i + j]->data[0][0] = x; - vOut[i + j]->data[0][1] = y; - vOut[i + j]->data[0][2] = z; - vOut[i + j]->data[0][3] = w; + out->data[0][0] = x; + out->data[0][1] = y; + out->data[0][2] = z; + out->data[0][3] = w; } /* Remaining attributes are packed into sequential post-transform * vertex attrib slots. */ for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[i + j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - vOut[i + j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - vOut[i + j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - vOut[i + j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + out->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + out->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + out->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + out->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; } #if 0 /*DEBUG*/ printf("%d) Post xform vert:\n", i + j); for (slot = 0; slot < draw->num_vs_outputs; slot++) { printf("\t%d: %f %f %f %f\n", slot, - vOut[i + j]->data[slot][0], - vOut[i + j]->data[slot][1], - vOut[i + j]->data[slot][2], - vOut[i + j]->data[slot][3]); + out->data[slot][0], + out->data[slot][1], + out->data[slot][2], + out->data[slot][3]); } #endif } /* loop over vertices */ diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 6db1e65a2d..72317c67ae 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -72,7 +72,7 @@ vs_llvm_run( struct draw_vertex_shader *base, struct draw_context *draw, const unsigned *elts, unsigned count, - struct vertex_header *vOut[] ) + void *vOut ) { struct draw_llvm_vertex_shader *shader = (struct draw_llvm_vertex_shader *)base; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 6e8d2021f5..c877f5ee3a 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -83,7 +83,7 @@ vs_sse_run( struct draw_vertex_shader *base, struct draw_context *draw, const unsigned *elts, unsigned count, - struct vertex_header *vOut[] ) + void *vOut ) { struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; struct tgsi_exec_machine *machine = &draw->machine; @@ -135,16 +135,18 @@ vs_sse_run( struct draw_vertex_shader *base, for (j = 0; j < max_vertices; j++) { unsigned slot; float x, y, z, w; + struct vertex_header *out = + draw_header_from_block(vOut, i + j); - x = vOut[i + j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[i + j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[i + j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[i + j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + x = out->clip[0] = machine->Outputs[0].xyzw[0].f[j]; + y = out->clip[1] = machine->Outputs[0].xyzw[1].f[j]; + z = out->clip[2] = machine->Outputs[0].xyzw[2].f[j]; + w = out->clip[3] = machine->Outputs[0].xyzw[3].f[j]; if (!draw->rasterizer->bypass_clipping) { - vOut[i + j]->clipmask = compute_clipmask(vOut[i + j]->clip, draw->plane, - draw->nr_planes); - clipped += vOut[i + j]->clipmask; + out->clipmask = compute_clipmask(out->clip, draw->plane, + draw->nr_planes); + clipped += out->clipmask; /* divide by w */ w = 1.0f / w; @@ -153,33 +155,43 @@ vs_sse_run( struct draw_vertex_shader *base, z *= w; } else { - vOut[i + j]->clipmask = 0; + out->clipmask = 0; } - vOut[j]->edgeflag = 1; + out->edgeflag = 1; if (!draw->identity_viewport) { /* Viewport mapping */ - vOut[i + j]->data[0][0] = x * scale[0] + trans[0]; - vOut[i + j]->data[0][1] = y * scale[1] + trans[1]; - vOut[i + j]->data[0][2] = z * scale[2] + trans[2]; - vOut[i + j]->data[0][3] = w; + out->data[0][0] = x * scale[0] + trans[0]; + out->data[0][1] = y * scale[1] + trans[1]; + out->data[0][2] = z * scale[2] + trans[2]; + out->data[0][3] = w; } else { - vOut[i + j]->data[0][0] = x; - vOut[i + j]->data[0][1] = y; - vOut[i + j]->data[0][2] = z; - vOut[i + j]->data[0][3] = w; + out->data[0][0] = x; + out->data[0][1] = y; + out->data[0][2] = z; + out->data[0][3] = w; } /* Remaining attributes are packed into sequential post-transform * vertex attrib slots. */ for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[i + j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - vOut[i + j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - vOut[i + j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - vOut[i + j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + out->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + out->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + out->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + out->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; } +#if 0 /*DEBUG*/ + printf("%d) Post xform vert:\n", i + j); + for (slot = 0; slot < draw->num_vs_outputs; slot++) { + printf("\t%d: %f %f %f %f\n", slot, + out->data[slot][0], + out->data[slot][1], + out->data[slot][2], + out->data[slot][3]); + } +#endif } } return clipped != 0; -- cgit v1.2.3 From 0c1cb54923f3ab31caa2821e095685277174dd2f Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sun, 13 Apr 2008 01:47:07 -0400 Subject: Implement fetch/shade/pipeline or emit vertex passthrough. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_pt.c | 54 +++-- src/gallium/auxiliary/draw/draw_pt.h | 2 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 253 +++++++++++++++++++++ 4 files changed, 287 insertions(+), 23 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 28262a92c6..5ab3cfe5ce 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -19,6 +19,7 @@ C_SOURCES = \ draw_pt_vcache.c \ draw_pt_fetch_emit.c \ draw_pt_fetch_pipeline.c \ + draw_pt_fetch_shade_pipeline.c \ draw_pt_pipeline.c \ draw_pt_elts.c \ draw_prim.c \ diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index f59fb86f78..c8663c0e84 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -38,19 +38,23 @@ /* XXX: Shouldn't those two functions below use the '>' operator??? */ - -static boolean too_many_verts( struct draw_context *draw, - unsigned verts ) +static boolean too_many_elts( struct draw_context *draw, + unsigned elts ) { - return verts < 1024; + return elts > (8 * 1024); } -static boolean too_many_elts( struct draw_context *draw, - unsigned elts ) +static INLINE unsigned reduced_prim(unsigned prim) { - return elts < (16 * 1024); + /*FIXME*/ + return prim; } +static INLINE boolean good_prim(unsigned prim) +{ + /*FIXME*/ + return FALSE; +} boolean draw_pt_arrays(struct draw_context *draw, @@ -64,6 +68,9 @@ draw_pt_arrays(struct draw_context *draw, struct draw_pt_front_end *frontend = NULL; struct draw_pt_middle_end *middle = NULL; + if (!draw->render) + return FALSE; + /*debug_printf("XXXXXXXXXX needs_pipeline = %d\n", pipeline);*/ /* Overall we do: * - frontend -- prepare fetch_elts, draw_elts - eg vcache @@ -87,7 +94,6 @@ draw_pt_arrays(struct draw_context *draw, */ middle = draw->pt.middle.fetch_pipeline; } -#if 0 else if (!cliptest && !pipeline) { /* Fetch user verts, run vertex shader, emit hw verts: */ @@ -111,23 +117,15 @@ draw_pt_arrays(struct draw_context *draw, */ middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit; } - else if (!cliptest) { - /* Fetch user verts, run vertex shader, run pipeline: - */ - middle = draw->pt.middle.fetch_shade_pipeline; - } else { /* This is what we're currently always doing: */ - /* Fetch user verts, run vertex shader, cliptest, run pipeline: + /* Fetch user verts, run vertex shader, cliptest, run pipeline + * or + * Fetch user verts, run vertex shader, run pipeline */ - middle = draw->pt.middle.fetch_shade_cliptest_pipeline; - } -#else - else { - return FALSE; + middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit; } -#endif /* If !pipeline, need to make sure we respect the driver's limited @@ -143,7 +141,7 @@ draw_pt_arrays(struct draw_context *draw, frontend = draw->pt.front.vcache; hw_prim = reduced_prim(prim); } - +#if 0 if (too_many_verts(nr_verts)) { /* if (is_verts(draw) && can_split(prim)) { draw = draw_arrays_split; @@ -153,6 +151,7 @@ draw_pt_arrays(struct draw_context *draw, hw_prim = reduced_prim(prim); } } +#endif if (too_many_elts(count)) { @@ -166,7 +165,7 @@ draw_pt_arrays(struct draw_context *draw, } if (!good_prim(hw_prim)) { - draw = draw->pt.front.vcache; + frontend = draw->pt.front.vcache; } } #else @@ -200,6 +199,11 @@ boolean draw_pt_init( struct draw_context *draw ) if (!draw->pt.middle.fetch_pipeline) return FALSE; + draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit = + draw_pt_fetch_pipeline_or_emit( draw ); + if (!draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit) + return FALSE; + draw->pt.front.vcache = draw_pt_vcache( draw ); if (!draw->pt.front.vcache) return FALSE; @@ -220,6 +224,12 @@ void draw_pt_destroy( struct draw_context *draw ) draw->pt.middle.fetch_pipeline = NULL; } + if (draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit) { + draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit->destroy( + draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit ); + draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit = NULL; + } + if (draw->pt.front.vcache) { draw->pt.front.vcache->destroy( draw->pt.front.vcache ); draw->pt.front.vcache = NULL; diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 590823fd33..48413b648a 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -123,7 +123,7 @@ const void *draw_pt_elt_ptr( struct draw_context *draw, struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ); - +struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw); #endif diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c new file mode 100644 index 0000000000..e7550fe328 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -0,0 +1,253 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" + +struct fetch_pipeline_middle_end { + struct draw_pt_middle_end base; + struct draw_context *draw; + + struct { + const ubyte *ptr; + unsigned pitch; + void (*fetch)( const void *from, float *attrib); + void (*emit)( const float *attrib, float **out ); + } fetch[PIPE_MAX_ATTRIBS]; + + unsigned nr_fetch; + unsigned pipeline_vertex_size; + unsigned hw_vertex_size; + unsigned prim; +}; + +static void emit_R32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out) += 1; +} + +static void emit_R32G32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out) += 2; +} + +static void emit_R32G32B32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out)[2] = attrib[2]; + (*out) += 3; +} + +static void emit_R32G32B32A32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out)[2] = attrib[2]; + (*out)[3] = attrib[3]; + (*out) += 4; +} + +static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, + unsigned prim ) +{ + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + struct draw_context *draw = fpme->draw; + unsigned i, nr = 0; + boolean ok; + const struct vertex_info *vinfo; + + fpme->prim = prim; + + ok = draw->render->set_primitive(draw->render, prim); + if (!ok) { + assert(0); + return; + } + /* Must do this after set_primitive() above: + */ + vinfo = draw->render->get_vertex_info(draw->render); + + /* Need to look at vertex shader inputs (we know it is a + * passthrough shader, so these define the outputs too). If we + * were running a shader, we'd still be looking at the inputs at + * this point. + */ + for (i = 0; i < draw->vertex_shader->info.num_inputs; i++) { + unsigned buf = draw->vertex_element[i].vertex_buffer_index; + enum pipe_format format = draw->vertex_element[i].src_format; + + fpme->fetch[nr].ptr = ((const ubyte *) draw->user.vbuffer[buf] + + draw->vertex_buffer[buf].buffer_offset + + draw->vertex_element[i].src_offset); + + fpme->fetch[nr].pitch = draw->vertex_buffer[buf].pitch; + fpme->fetch[nr].fetch = draw_get_fetch_func( format ); + + /* Always do this -- somewhat redundant... + */ + fpme->fetch[nr].emit = emit_R32G32B32A32_FLOAT; + nr++; + } + + fpme->nr_fetch = nr; + //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); + fpme->pipeline_vertex_size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; + fpme->hw_vertex_size = vinfo->size * 4; +} + + + + +static void fetch_pipeline_run( struct draw_pt_middle_end *middle, + const unsigned *fetch_elts, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + struct draw_context *draw = fpme->draw; + struct draw_vertex_shader *shader = draw->vertex_shader; + char *pipeline_verts; + unsigned i; + + //debug_printf("fc = %d, VS = %d\n", fetch_count, VS_QUEUE_LENGTH); + if (fetch_count < VS_QUEUE_LENGTH) { + pipeline_verts = draw->vs.vertex_cache; + } else { + pipeline_verts = MALLOC(fpme->pipeline_vertex_size * + fetch_count); + } + + if (!pipeline_verts) { + assert(0); + return; + } + + /*FIXME: this init phase should go away */ + for (i = 0; i < fetch_count; ++i) { + struct vertex_header *header = + (struct vertex_header*)(pipeline_verts + (fpme->pipeline_vertex_size * i)); + header->clipmask = 0; + header->edgeflag = draw_get_edgeflag(draw, i); + header->pad = 0; + header->vertex_id = UNDEFINED_VERTEX_ID; + } + + /* Shade + */ + shader->prepare(shader, draw); + if (shader->run(shader, draw, fetch_elts, fetch_count, pipeline_verts)) { + /* Run the pipeline */ + draw_pt_run_pipeline( fpme->draw, + fpme->prim, + pipeline_verts, + fpme->pipeline_vertex_size, + fetch_count, + draw_elts, + draw_count ); + } else { + unsigned i, j; + void *hw_verts; + float *out; + + hw_verts = draw->render->allocate_vertices(draw->render, + (ushort)fpme->hw_vertex_size, + (ushort)fetch_count); + if (!hw_verts) { + assert(0); + return; + } + + out = (float *)hw_verts; + for (i = 0; i < fetch_count; i++) { + struct vertex_header *header = + (struct vertex_header*)(pipeline_verts + (fpme->pipeline_vertex_size * i)); + + for (j = 0; j < fpme->nr_fetch; j++) { + float *attrib = header->data[j]; + /*debug_printf("emiting [%f, %f, %f, %f]\n", + attrib[0], attrib[1], + attrib[2], attrib[3]);*/ + fpme->fetch[j].emit(attrib, &out); + } + } + /* XXX: Draw arrays path to avoid re-emitting index list again and + * again. + */ + draw->render->draw(draw->render, + draw_elts, + draw_count); + + draw->render->release_vertices(draw->render, + hw_verts, + fpme->hw_vertex_size, + fetch_count); + } + + + if (pipeline_verts != draw->vs.vertex_cache) + FREE(pipeline_verts); +} + + + +static void fetch_pipeline_finish( struct draw_pt_middle_end *middle ) +{ + /* nothing to do */ +} + +static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) +{ + FREE(middle); +} + + +struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context *draw ) +{ + struct fetch_pipeline_middle_end *fetch_pipeline = CALLOC_STRUCT( fetch_pipeline_middle_end ); + + fetch_pipeline->base.prepare = fetch_pipeline_prepare; + fetch_pipeline->base.run = fetch_pipeline_run; + fetch_pipeline->base.finish = fetch_pipeline_finish; + fetch_pipeline->base.destroy = fetch_pipeline_destroy; + + fetch_pipeline->draw = draw; + + return &fetch_pipeline->base; +} -- cgit v1.2.3 From 8e7326832a7420154fc0d526ac682494db1be160 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 14 Apr 2008 11:32:50 +0100 Subject: softpipe: do our own culling, don't rely on the draw module. May not always happen due to passthrough modes, etc. --- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 21 +++++++++++--- src/gallium/drivers/softpipe/sp_setup.c | 44 +++++++++++++++++------------ 2 files changed, 43 insertions(+), 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 025a0113bf..74cd675908 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -120,8 +120,9 @@ sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) /** - * Recalculate prim's determinant. - * XXX is this needed? + * Recalculate prim's determinant. This is needed as we don't have + * get this information through the vbuf_render interface & we must + * calculate it here. */ static float calc_det( const float (*v0)[4], @@ -144,12 +145,21 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); struct softpipe_context *softpipe = cvbr->softpipe; - struct draw_stage *setup = softpipe->setup; unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float); unsigned i, j; void *vertex_buffer = cvbr->vertex_buffer; cptrf4 v[3]; - struct setup_context *setup_ctx = sp_draw_setup_context(setup); + + /* XXX: break this dependency - make setup_context live under + * softpipe, rename the old "setup" draw stage to something else. + */ + struct draw_stage *setup = softpipe->setup; + struct setup_context *setup_ctx = sp_draw_setup_context(softpipe->setup); + + /* XXX: call this from allocate_vertices: + */ + setup_prepare( setup_ctx ); + switch (cvbr->prim) { case PIPE_PRIM_TRIANGLES: @@ -189,6 +199,9 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) break; } + /* XXX: why are we calling this??? If we had to call something, it + * would be a function in sp_setup.c: + */ sp_draw_flush( setup ); } diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 48617a66ed..5a30788850 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -97,31 +97,35 @@ struct setup_context { uint numFragsEmitted; /**< per primitive */ uint numFragsWritten; /**< per primitive */ #endif + + unsigned winding; /* which winding to cull */ }; -/** - * Recalculate prim's determinant. - * XXX is this needed? - */ -static INLINE float -calc_det( const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4] ) +static boolean cull_tri( struct setup_context *setup, + float det ) { - /* edge vectors e = v0 - v2, f = v1 - v2 */ - const float ex = v0[0][0] - v2[0][0]; - const float ey = v0[0][1] - v2[0][1]; - const float fx = v1[0][0] - v2[0][0]; - const float fy = v1[0][1] - v2[0][1]; - - /* det = cross(e,f).z */ - return ex * fy - ey * fx; + if (det != 0) + { + /* if (det < 0 then Z points toward camera and triangle is + * counter-clockwise winding. + */ + unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; + + if ((winding & setup->winding) == 0) + return FALSE; + } + + /* Culled: + */ + return TRUE; } + + /** * Clip setup->quad against the scissor/surface bounds. */ @@ -709,8 +713,10 @@ void setup_tri( struct setup_context *setup, setup->numFragsWritten = 0; #endif - setup_sort_vertices( setup, calc_det(v0, v1, v2), - v0, v1, v2 ); + if (cull_tri( setup, det )) + return; + + setup_sort_vertices( setup, det, v0, v1, v2 ); setup_tri_coefficients( setup ); setup_tri_edges( setup ); @@ -1223,6 +1229,8 @@ void setup_prepare( struct setup_context *setup ) setup->quad.nr_attrs = fs->info.num_inputs; sp->quad.first->begin(sp->quad.first); } + + setup->winding = sp->rasterizer->cull_mode; } -- cgit v1.2.3 From caf293343fd236e97ce399533ac0ada3c7afee7a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 14 Apr 2008 12:08:46 +0100 Subject: draw: hide passthrough shading paths behind an environment variable --- src/gallium/auxiliary/draw/draw_context.c | 2 ++ src/gallium/auxiliary/draw/draw_private.h | 1 + src/gallium/auxiliary/draw/draw_pt.c | 3 +++ 3 files changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index cdca556fbd..1e70a77523 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -49,6 +49,8 @@ struct draw_context *draw_create( void ) draw->use_sse = FALSE; #endif + draw->use_pt_shaders = GETENV( "GALLIUM_PT_SHADERS" ) != NULL; + /* create pipeline stages */ draw->pipeline.wide_line = draw_wide_line_stage( draw ); draw->pipeline.wide_point = draw_wide_point_stage( draw ); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 1115166192..3042d26847 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -276,6 +276,7 @@ struct draw_context boolean line_stipple; /**< do line stipple? */ boolean point_sprite; /**< convert points to quads for sprites? */ boolean use_sse; + boolean use_pt_shaders; /* temporary flag to switch on pt shader paths */ /* If a prim stage introduces new vertex attributes, they'll be stored here */ diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index c8663c0e84..c67a217982 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -79,6 +79,9 @@ draw_pt_arrays(struct draw_context *draw, * - backend -- the vbuf_render provided by the driver. */ + if (shading && !draw->use_pt_shaders) + return FALSE; + if (!cliptest && !pipeline && !shading) { /* This is the 'passthrough' path: -- cgit v1.2.3 From e106b2d3d65585b0aaa0e60afd541da020d9e220 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 14 Apr 2008 12:27:25 +0100 Subject: draw: move vertex header init out of fetch_shade_pipeline.c --- src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c | 2 -- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 9 --------- src/gallium/auxiliary/draw/draw_vs_exec.c | 1 + src/gallium/auxiliary/draw/draw_vs_llvm.c | 1 + src/gallium/auxiliary/draw/draw_vs_sse.c | 1 + 5 files changed, 3 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index 4c2a281b29..0914a90440 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -211,7 +211,6 @@ fetch_store_general( struct fetch_pipeline_middle_end *fpme, static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned prim ) { - static const float zero = 0; struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; unsigned i, nr = 0; @@ -264,7 +263,6 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, unsigned draw_count ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; - struct draw_context *draw = fpme->draw; char *pipeline_verts; pipeline_verts = MALLOC( fpme->pipeline_vertex_size * diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index e7550fe328..fb9b2da5c0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -159,15 +159,6 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, return; } - /*FIXME: this init phase should go away */ - for (i = 0; i < fetch_count; ++i) { - struct vertex_header *header = - (struct vertex_header*)(pipeline_verts + (fpme->pipeline_vertex_size * i)); - header->clipmask = 0; - header->edgeflag = draw_get_edgeflag(draw, i); - header->pad = 0; - header->vertex_id = UNDEFINED_VERTEX_ID; - } /* Shade */ diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 6fe4e554d5..27cf060cc9 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -135,6 +135,7 @@ vs_exec_run( struct draw_vertex_shader *shader, out->clipmask = 0; } out->edgeflag = 1; + out->vertex_id = UNDEFINED_VERTEX_ID; if (!draw->identity_viewport) { /* Viewport mapping */ diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 72317c67ae..73076d2467 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -140,6 +140,7 @@ vs_llvm_run( struct draw_vertex_shader *base, vOut[j]->clipmask = 0; } vOut[j]->edgeflag = 1; + vOut[j]->vertex_id = UNDEFINED_VERTEX_ID; if (!draw->identity_viewport) { /* Viewport mapping */ diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index c877f5ee3a..92b9947e9f 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -158,6 +158,7 @@ vs_sse_run( struct draw_vertex_shader *base, out->clipmask = 0; } out->edgeflag = 1; + out->vertex_id = UNDEFINED_VERTEX_ID; if (!draw->identity_viewport) { /* Viewport mapping */ -- cgit v1.2.3 From a82e4996a13ef3cae1497fef95c2fca7631cd889 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 14 Apr 2008 12:32:53 +0100 Subject: draw: flush pipeline before trying to allocate more hw vertices --- src/gallium/auxiliary/draw/draw_pt.c | 4 ---- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 4 ++++ src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index c67a217982..5c16165c15 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -175,10 +175,6 @@ draw_pt_arrays(struct draw_context *draw, frontend = draw->pt.front.vcache; #endif - /* XXX: need to flush to get prim_vbuf.c to release its allocation?? - */ - draw_do_flush( draw, DRAW_FLUSH_BACKEND ); - frontend->prepare( frontend, prim, middle ); frontend->run( frontend, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index e4e144ef19..2f8b08db79 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -243,6 +243,10 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, struct draw_context *draw = feme->draw; void *hw_verts; + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + hw_verts = draw->render->allocate_vertices( draw->render, (ushort)feme->hw_vertex_size, (ushort)fetch_count ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index fb9b2da5c0..b5d2f81a14 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -177,6 +177,10 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, void *hw_verts; float *out; + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + hw_verts = draw->render->allocate_vertices(draw->render, (ushort)fpme->hw_vertex_size, (ushort)fetch_count); -- cgit v1.2.3 From 36bacf97a6b10f7274f0d3fcf37bf7ebf9388161 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 14 Apr 2008 12:46:47 +0100 Subject: draw: always malloc verts for fetch_shade_pipeline --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index b5d2f81a14..427128f335 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -144,15 +144,9 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, struct draw_context *draw = fpme->draw; struct draw_vertex_shader *shader = draw->vertex_shader; char *pipeline_verts; - unsigned i; - //debug_printf("fc = %d, VS = %d\n", fetch_count, VS_QUEUE_LENGTH); - if (fetch_count < VS_QUEUE_LENGTH) { - pipeline_verts = draw->vs.vertex_cache; - } else { - pipeline_verts = MALLOC(fpme->pipeline_vertex_size * - fetch_count); - } + pipeline_verts = MALLOC(fpme->pipeline_vertex_size * + fetch_count); if (!pipeline_verts) { assert(0); @@ -216,8 +210,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, } - if (pipeline_verts != draw->vs.vertex_cache) - FREE(pipeline_verts); + FREE(pipeline_verts); } -- cgit v1.2.3 From ca750dd045893ca5a9e1c33bd31528ade7bb1009 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 14 Apr 2008 17:02:02 +0200 Subject: Removed intel_ioctl it wasn't needed --- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 2 +- src/gallium/winsys/dri/intel/intel_ioctl.c | 138 ----------------------- src/gallium/winsys/dri/intel/intel_ioctl.h | 40 ------- 3 files changed, 1 insertion(+), 179 deletions(-) delete mode 100644 src/gallium/winsys/dri/intel/intel_ioctl.c delete mode 100644 src/gallium/winsys/dri/intel/intel_ioctl.h (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 3a8ff5a4eb..3a8591b580 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -26,7 +26,7 @@ **************************************************************************/ #include "intel_batchbuffer.h" -#include "intel_ioctl.h" +#include "intel_context.h" #include #if 0 diff --git a/src/gallium/winsys/dri/intel/intel_ioctl.c b/src/gallium/winsys/dri/intel/intel_ioctl.c deleted file mode 100644 index 3250c6b3a9..0000000000 --- a/src/gallium/winsys/dri/intel/intel_ioctl.c +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include -#include -#include -#include - -#include "mtypes.h" -#include "context.h" -#include "swrast/swrast.h" - -#include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_regions.h" -#include "drm.h" - -#define FILE_DEBUG_FLAG DEBUG_IOCTL - -int -intelEmitIrqLocked(struct intel_context *intel) -{ - drmI830IrqEmit ie; - int ret, seq; - - assert(((*(int *) intel->driHwLock) & ~DRM_LOCK_CONT) == - (DRM_LOCK_HELD | intel->hHWContext)); - - ie.irq_seq = &seq; - - ret = drmCommandWriteRead(intel->driFd, DRM_I830_IRQ_EMIT, - &ie, sizeof(ie)); - if (ret) { - fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); - exit(1); - } - - DBG("%s --> %d\n", __FUNCTION__, seq); - - return seq; -} - -void -intelWaitIrq(struct intel_context *intel, int seq) -{ - int ret; - - DBG("%s %d\n", __FUNCTION__, seq); - - intel->iw.irq_seq = seq; - - do { - ret = - drmCommandWrite(intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, - sizeof(intel->iw)); - } while (ret == -EAGAIN || ret == -EINTR); - - if (ret) { - fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret); - exit(1); - } -} - - -void -intel_batch_ioctl(struct intel_context *intel, - GLuint start_offset, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - drmI830BatchBuffer batch; - - assert(intel->locked); - assert(used); - - DBG("%s used %d offset %x..%x ignore_cliprects %d\n", - __FUNCTION__, - used, start_offset, start_offset + used, ignore_cliprects); - - /* Throw away non-effective packets. Won't work once we have - * hardware contexts which would preserve statechanges beyond a - * single buffer. - */ - - - - batch.start = start_offset; - batch.used = used; - batch.cliprects = intel->pClipRects; - batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; - batch.DR1 = 0; - batch.DR4 = ((((GLuint) intel->drawX) & 0xffff) | - (((GLuint) intel->drawY) << 16)); - - DBG("%s: 0x%x..0x%x DR4: %x cliprects: %d\n", - __FUNCTION__, - batch.start, - batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); - - if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, - sizeof(batch))) { - fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); - UNLOCK_HARDWARE(intel); - exit(1); - } - - /* FIXME: use hardware contexts to avoid 'losing' hardware after - * each buffer flush. - */ - intel->vtbl.lost_hardware(intel); -} diff --git a/src/gallium/winsys/dri/intel/intel_ioctl.h b/src/gallium/winsys/dri/intel/intel_ioctl.h deleted file mode 100644 index e8d07de893..0000000000 --- a/src/gallium/winsys/dri/intel/intel_ioctl.h +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_IOCTL_H -#define INTEL_IOCTL_H - -#include "intel_context.h" - -void intelWaitIrq(struct intel_context *intel, int seq); -int intelEmitIrqLocked(struct intel_context *intel); - -void intel_batch_ioctl(struct intel_context *intel, - GLuint start_offset, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock); -#endif -- cgit v1.2.3 From 8cbda9f1088718e5dbb97b9a6ddcc43737f94351 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 14 Apr 2008 16:15:39 +0100 Subject: draw: remove dead code --- src/gallium/auxiliary/draw/draw_vf.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vf.h b/src/gallium/auxiliary/draw/draw_vf.h index 7555d1bd58..0ef98d6257 100644 --- a/src/gallium/auxiliary/draw/draw_vf.h +++ b/src/gallium/auxiliary/draw/draw_vf.h @@ -128,9 +128,6 @@ draw_vf_destroy( struct draw_vertex_fetch *vf ); struct draw_vf_attr; -typedef void (*draw_vf_extract_func)( const struct draw_vf_attr *a, - float *out, - const uint8_t *v ); typedef void (*draw_vf_insert_func)( const struct draw_vf_attr *a, uint8_t *v, @@ -164,7 +161,6 @@ struct draw_vf_attr uint8_t *inputptr; const draw_vf_insert_func *insert; draw_vf_insert_func do_insert; - draw_vf_extract_func extract; }; struct draw_vertex_fetch -- cgit v1.2.3 From 871d39ec8c168fa58d8758013e99da63fa58111d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 14 Apr 2008 16:18:00 +0100 Subject: softpipe: calculate determinant for all triangles, don't rely on draw module to do it --- src/gallium/drivers/softpipe/sp_prim_setup.c | 1 - src/gallium/drivers/softpipe/sp_prim_vbuf.c | 28 ---------------------------- src/gallium/drivers/softpipe/sp_setup.c | 26 +++++++++++++++++++++++++- src/gallium/drivers/softpipe/sp_setup.h | 10 +++++----- 4 files changed, 30 insertions(+), 35 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 6fe463b74c..0ddb06764a 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -71,7 +71,6 @@ do_tri(struct draw_stage *stage, struct prim_header *prim) struct setup_stage *setup = setup_stage( stage ); setup_tri( setup->setup, - prim->det, prim->v[0]->data, prim->v[1]->data, prim->v[2]->data ); diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 74cd675908..4fed19ecb6 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -119,25 +119,6 @@ sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) } -/** - * Recalculate prim's determinant. This is needed as we don't have - * get this information through the vbuf_render interface & we must - * calculate it here. - */ -static float -calc_det( const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4] ) -{ - /* edge vectors e = v0 - v2, f = v1 - v2 */ - const float ex = v0[0][0] - v2[0][0]; - const float ey = v0[0][1] - v2[0][1]; - const float fx = v1[0][0] - v2[0][0]; - const float fy = v1[0][1] - v2[0][1]; - - /* det = cross(e,f).z */ - return ex * fy - ey * fx; -} static void @@ -169,7 +150,6 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) indices[i+j] * vertex_size); setup_tri( setup_ctx, - calc_det(v[0], v[1], v[2]), v[0], v[1], v[2]); @@ -254,7 +234,6 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) v[1] = VERTEX(i + 1); v[2] = VERTEX(i + 2); setup_tri( setup_ctx, - calc_det(v[0], v[1], v[2]), v[0], v[1], v[2] ); @@ -267,7 +246,6 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) v[1] = VERTEX(i - 1); v[2] = VERTEX(i); setup_tri( setup_ctx, - calc_det(v[0], v[1], v[2]), v[0], v[1], v[2] ); @@ -280,7 +258,6 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) v[1] = VERTEX(i - 1); v[2] = VERTEX(i); setup_tri( setup_ctx, - calc_det(v[0], v[1], v[2]), v[0], v[1], v[2] ); @@ -293,7 +270,6 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) v[1] = VERTEX(i + 1); v[2] = VERTEX(i + 2); setup_tri( setup_ctx, - calc_det(v[0], v[1], v[2]), v[0], v[1], v[2] ); @@ -302,7 +278,6 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) v[1] = VERTEX(i + 2); v[2] = VERTEX(i + 3); setup_tri( setup_ctx, - calc_det(v[0], v[1], v[2]), v[0], v[1], v[2] ); @@ -315,7 +290,6 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) v[1] = VERTEX(i); v[2] = VERTEX(i + 1); setup_tri( setup_ctx, - calc_det(v[0], v[1], v[2]), v[0], v[1], v[2] ); @@ -324,7 +298,6 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) v[1] = VERTEX(i + 1); v[2] = VERTEX(i - 1); setup_tri( setup_ctx, - calc_det(v[0], v[1], v[2]), v[0], v[1], v[2] ); @@ -337,7 +310,6 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) v[1] = VERTEX(i - 1); v[2] = VERTEX(i); setup_tri( setup_ctx, - calc_det(v[0], v[1], v[2]), v[0], v[1], v[2] ); diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 5a30788850..0164d0588d 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -695,15 +695,37 @@ static void subtriangle( struct setup_context *setup, } +/** + * Recalculate prim's determinant. This is needed as we don't have + * get this information through the vbuf_render interface & we must + * calculate it here. + */ +static float +calc_det( const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) +{ + /* edge vectors e = v0 - v2, f = v1 - v2 */ + const float ex = v0[0][0] - v2[0][0]; + const float ey = v0[0][1] - v2[0][1]; + const float fx = v1[0][0] - v2[0][0]; + const float fy = v1[0][1] - v2[0][1]; + + /* det = cross(e,f).z */ + return ex * fy - ey * fx; +} + + /** * Do setup for triangle rasterization, then render the triangle. */ void setup_tri( struct setup_context *setup, - float det, const float (*v0)[4], const float (*v1)[4], const float (*v2)[4] ) { + float det = calc_det(v0, v1, v2); + /* debug_printf("%s\n", __FUNCTION__ ); */ @@ -713,6 +735,8 @@ void setup_tri( struct setup_context *setup, setup->numFragsWritten = 0; #endif + + if (cull_tri( setup, det )) return; diff --git a/src/gallium/drivers/softpipe/sp_setup.h b/src/gallium/drivers/softpipe/sp_setup.h index 3133fc2a3d..d54f334428 100644 --- a/src/gallium/drivers/softpipe/sp_setup.h +++ b/src/gallium/drivers/softpipe/sp_setup.h @@ -30,11 +30,11 @@ struct setup_context; struct softpipe_context; -void setup_tri( struct setup_context *setup, - float det, - const float (*v0)[4], - const float (*v1)[4], - const float (*v2)[4] ); +void +setup_tri( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ); void setup_line(struct setup_context *setup, -- cgit v1.2.3 From e3309197855b5caf7c4c167d1e7beedf33ed2fdd Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 14 Apr 2008 12:27:24 -0400 Subject: pass vertex size to shaders so that callee can decide on the size of the vertices and not always have to use the maximum vertex allocation size for them --- src/gallium/auxiliary/draw/draw_private.h | 7 ++++--- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 3 ++- src/gallium/auxiliary/draw/draw_vertex_cache.c | 8 ++++++-- src/gallium/auxiliary/draw/draw_vertex_shader.c | 5 +++-- src/gallium/auxiliary/draw/draw_vs_exec.c | 5 +++-- src/gallium/auxiliary/draw/draw_vs_sse.c | 5 +++-- 6 files changed, 21 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 3042d26847..c8cb96c8ba 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -78,6 +78,7 @@ struct vertex_header { /* XXX This is too large */ #define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) +#define MAX_VERTEX_ALLOCATION ((MAX_VERTEX_SIZE + 0x0f) & ~0x0f) @@ -152,7 +153,8 @@ struct draw_vertex_shader { struct draw_context *draw, const unsigned *elts, unsigned count, - void *out ); + void *out, + unsigned vertex_size); void (*delete)( struct draw_vertex_shader * ); @@ -450,9 +452,8 @@ dot4(const float *a, const float *b) } static INLINE struct vertex_header * -draw_header_from_block(char *block, int num) +draw_header_from_block(char *block, int size, int num) { - static const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; return (struct vertex_header*)(block + num * size); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 427128f335..3fa6dcc5e7 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -157,7 +157,8 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, /* Shade */ shader->prepare(shader, draw); - if (shader->run(shader, draw, fetch_elts, fetch_count, pipeline_verts)) { + if (shader->run(shader, draw, fetch_elts, fetch_count, pipeline_verts, + fpme->pipeline_vertex_size)) { /* Run the pipeline */ draw_pt_run_pipeline( fpme->draw, fpme->prim, diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c index 9256dec4ea..730c18bcb3 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_cache.c +++ b/src/gallium/auxiliary/draw/draw_vertex_cache.c @@ -74,6 +74,7 @@ static struct vertex_header *get_vertex( struct draw_context *draw, /*debug_printf("HIT %d %d\n", slot, i);*/ assert(draw->vcache.idx[slot].out < draw->vs.queue_nr); return draw_header_from_block(draw->vs.vertex_cache, + MAX_VERTEX_ALLOCATION, draw->vcache.idx[slot].out); } @@ -101,7 +102,8 @@ static struct vertex_header *get_vertex( struct draw_context *draw, */ assert(draw->vs.queue_nr < VS_QUEUE_LENGTH); - header = draw_header_from_block(draw->vs.vertex_cache, out); + header = draw_header_from_block(draw->vs.vertex_cache, MAX_VERTEX_ALLOCATION, + out); draw->vs.elts[out] = i; header->clipmask = 0; header->edgeflag = draw_get_edgeflag(draw, i); @@ -113,6 +115,7 @@ static struct vertex_header *get_vertex( struct draw_context *draw, */ return draw_header_from_block(draw->vs.vertex_cache, + MAX_VERTEX_ALLOCATION, draw->vcache.idx[slot].out); } } @@ -148,7 +151,8 @@ void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ) for (i = 0; i < draw->vs.post_nr; i++) { struct vertex_header * header = - draw_header_from_block(draw->vs.vertex_cache, i); + draw_header_from_block(draw->vs.vertex_cache, + MAX_VERTEX_ALLOCATION, i); header->vertex_id = UNDEFINED_VERTEX_ID; } } diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index 452d0175c3..8572a6d40c 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -60,7 +60,8 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) unsigned elts[MAX_SHADER_VERTICES]; int j, n = MIN2(MAX_SHADER_VERTICES, draw->vs.queue_nr - i); struct vertex_header *dests = - draw_header_from_block(draw->vs.vertex_cache, i); + draw_header_from_block(draw->vs.vertex_cache, + MAX_VERTEX_ALLOCATION, i); for (j = 0; j < n; j++) { elts[j] = draw->vs.elts[i + j]; @@ -73,7 +74,7 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) assert(n > 0); assert(n <= MAX_SHADER_VERTICES); - shader->run(shader, draw, elts, n, dests); + shader->run(shader, draw, elts, n, dests, MAX_VERTEX_ALLOCATION); } draw->vs.post_nr = draw->vs.queue_nr; diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 27cf060cc9..5c88c2e24e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -69,7 +69,8 @@ vs_exec_run( struct draw_vertex_shader *shader, struct draw_context *draw, const unsigned *elts, unsigned count, - void *vOut ) + void *vOut, + unsigned vertex_size) { struct tgsi_exec_machine *machine = &draw->machine; unsigned int i, j; @@ -107,7 +108,7 @@ vs_exec_run( struct draw_vertex_shader *shader, unsigned slot; float x, y, z, w; struct vertex_header *out = - draw_header_from_block(vOut, i + j); + draw_header_from_block(vOut, vertex_size, i + j); /* Handle attr[0] (position) specially: * diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 92b9947e9f..ee0a3105b9 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -83,7 +83,8 @@ vs_sse_run( struct draw_vertex_shader *base, struct draw_context *draw, const unsigned *elts, unsigned count, - void *vOut ) + void *vOut, + unsigned vertex_size ) { struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; struct tgsi_exec_machine *machine = &draw->machine; @@ -136,7 +137,7 @@ vs_sse_run( struct draw_vertex_shader *base, unsigned slot; float x, y, z, w; struct vertex_header *out = - draw_header_from_block(vOut, i + j); + draw_header_from_block(vOut, vertex_size, i + j); x = out->clip[0] = machine->Outputs[0].xyzw[0].f[j]; y = out->clip[1] = machine->Outputs[0].xyzw[1].f[j]; -- cgit v1.2.3 From 2ba6e1fa71be07a2d75abe2d085d485046c0932b Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 14 Apr 2008 12:29:23 -0400 Subject: silence some warnings --- src/gallium/auxiliary/draw/draw_pt.c | 4 ++-- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 2 -- src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c | 4 ++-- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 3 ++- 4 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 5c16165c15..3d2e7bf7b8 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -36,13 +36,13 @@ #include "draw/draw_pt.h" -/* XXX: Shouldn't those two functions below use the '>' operator??? - */ +#if 0 static boolean too_many_elts( struct draw_context *draw, unsigned elts ) { return elts > (8 * 1024); } +#endif static INLINE unsigned reduced_prim(unsigned prim) { diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 2f8b08db79..3a26a5d712 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -145,7 +145,6 @@ fetch_store_general( struct fetch_emit_middle_end *feme, unsigned count ) { float *out = (float *)out_ptr; - struct vbuf_render *render = feme->draw->render; uint i, j; for (i = 0; i < count; i++) { @@ -167,7 +166,6 @@ fetch_store_general( struct fetch_emit_middle_end *feme, static void fetch_emit_prepare( struct draw_pt_middle_end *middle, unsigned prim ) { - static const float zero = 0; struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; const struct vertex_info *vinfo; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index 0914a90440..a70d129c93 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -87,7 +87,7 @@ struct fetch_pipeline_middle_end { }; - +#if 0 static void emit_R32_FLOAT( const float *attrib, float **out ) { @@ -111,7 +111,7 @@ static void emit_R32G32B32_FLOAT( const float *attrib, (*out)[2] = attrib[2]; (*out) += 3; } - +#endif static void emit_R32G32B32A32_FLOAT( const float *attrib, float **out ) { diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 3fa6dcc5e7..b49c9efa65 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -49,6 +49,7 @@ struct fetch_pipeline_middle_end { unsigned prim; }; +#if 0 static void emit_R32_FLOAT( const float *attrib, float **out ) { @@ -72,7 +73,7 @@ static void emit_R32G32B32_FLOAT( const float *attrib, (*out)[2] = attrib[2]; (*out) += 3; } - +#endif static void emit_R32G32B32A32_FLOAT( const float *attrib, float **out ) { -- cgit v1.2.3 From 983b6a73e1842b436d158dc1d018bd483a1c9929 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 14 Apr 2008 12:32:25 -0400 Subject: use the new macro --- src/gallium/auxiliary/draw/draw_context.c | 3 +-- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 1e70a77523..0c314f6e1d 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -88,8 +88,7 @@ struct draw_context *draw_create( void ) /* Statically allocate maximum sized vertices for the cache - could be cleverer... */ { - const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; - char *tmp = align_malloc(VS_QUEUE_LENGTH * size, 16); + char *tmp = align_malloc(VS_QUEUE_LENGTH * MAX_VERTEX_ALLOCATION, 16); if (!tmp) goto fail; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index b49c9efa65..04b3d2c4cf 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -128,7 +128,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, fpme->nr_fetch = nr; //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); - fpme->pipeline_vertex_size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; + fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; fpme->hw_vertex_size = vinfo->size * 4; } -- cgit v1.2.3 From f58ab8e75c082a0aea36ed63fe7e21fb5fac14b6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 14 Apr 2008 10:56:56 -0600 Subject: gallium: take reduced prim, fill modes into account when culling --- src/gallium/drivers/softpipe/sp_context.h | 2 ++ src/gallium/drivers/softpipe/sp_draw_arrays.c | 15 +++++++++++++++ src/gallium/drivers/softpipe/sp_setup.c | 11 ++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 2442bd1eb0..0e1d5e561d 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -105,6 +105,8 @@ struct softpipe_context { int psize_slot; + unsigned reduced_api_prim; /**< PIPE_PRIM_POINTS, _LINES or _TRIANGLES */ + #if 0 /* Stipple derived state: */ diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 61bcf51899..421509495a 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -78,6 +78,20 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp) } +static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { + PIPE_PRIM_POINTS, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES +}; + + boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) @@ -115,6 +129,7 @@ softpipe_draw_elements(struct pipe_context *pipe, assert(0); #endif + sp->reduced_api_prim = reduced_prim[mode]; if (sp->dirty) softpipe_update_derived( sp ); diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 0164d0588d..813d703108 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -1254,7 +1254,16 @@ void setup_prepare( struct setup_context *setup ) sp->quad.first->begin(sp->quad.first); } - setup->winding = sp->rasterizer->cull_mode; + if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES && + sp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && + sp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { + /* we'll do culling */ + setup->winding = sp->rasterizer->cull_mode; + } + else { + /* 'draw' will do culling */ + setup->winding = PIPE_WINDING_NONE; + } } -- cgit v1.2.3 From 21ae3d2721326d56c76370fd8bfcc1536203925d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 14 Apr 2008 22:39:33 +0900 Subject: gallium: Serialize buffers writes. Allow concurrent reads from buffers by the CPU/GPU, but serialize all writes. --- .../auxiliary/pipebuffer/pb_buffer_fenced.c | 81 ++++++++++++++++++++-- 1 file changed, 76 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index b1f7d93057..65b6584003 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -35,6 +35,7 @@ #include "pipe/p_compiler.h" +#include "pipe/p_error.h" #include "pipe/p_debug.h" #include "pipe/p_winsys.h" #include "pipe/p_thread.h" @@ -54,6 +55,13 @@ */ #define SUPER(__derived) (&(__derived)->base) +#define PIPE_BUFFER_USAGE_CPU_READ_WRITE \ + ( PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE ) +#define PIPE_BUFFER_USAGE_GPU_READ_WRITE \ + ( PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE ) +#define PIPE_BUFFER_USAGE_WRITE \ + ( PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_GPU_WRITE ) + struct fenced_buffer_list { @@ -76,6 +84,15 @@ struct fenced_buffer struct pb_buffer *buffer; + /* FIXME: protect access with mutex */ + + /** + * A bitmask of PIPE_BUFFER_USAGE_CPU/GPU_READ/WRITE describing the current + * buffer usage. + */ + unsigned flags; + + unsigned mapcount; struct pipe_fence_handle *fence; struct list_head head; @@ -98,7 +115,9 @@ _fenced_buffer_add(struct fenced_buffer *fenced_buf) struct fenced_buffer_list *fenced_list = fenced_buf->list; assert(fenced_buf->base.base.refcount); + assert(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE); assert(fenced_buf->fence); + assert(!fenced_buf->head.prev); assert(!fenced_buf->head.next); LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); @@ -130,6 +149,7 @@ _fenced_buffer_remove(struct fenced_buffer *fenced_buf) assert(fenced_buf->fence); winsys->fence_reference(winsys, &fenced_buf->fence, NULL); + fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE; assert(fenced_buf->head.prev); assert(fenced_buf->head.next); @@ -186,6 +206,34 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, } +/** + * Serialize writes, but allow concurrent reads. + */ +static INLINE enum pipe_error +fenced_buffer_serialize(struct fenced_buffer *fenced_buf, unsigned flags) +{ + struct fenced_buffer_list *fenced_list = fenced_buf->list; + struct pipe_winsys *winsys = fenced_list->winsys; + + if(((fenced_buf->flags | flags) & PIPE_BUFFER_USAGE_WRITE) == 0) + return PIPE_OK; + + if(fenced_buf->mapcount) { + /* FIXME */ + debug_warning("attemp to write concurrently to buffer"); + return PIPE_ERROR_RETRY; + } + + if(fenced_buf->fence) { + if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) + return PIPE_ERROR_RETRY; + _fenced_buffer_remove(fenced_buf); + } + + return PIPE_OK; +} + + static void fenced_buffer_destroy(struct pb_buffer *buf) { @@ -223,16 +271,30 @@ static void * fenced_buffer_map(struct pb_buffer *buf, unsigned flags) { - struct fenced_buffer *fenced_buf = fenced_buffer(buf); - return pb_map(fenced_buf->buffer, flags); + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + void *map; + assert((flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE) == 0); + + if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK) + return NULL; + + map = pb_map(fenced_buf->buffer, flags); + if(map) + ++fenced_buf->mapcount; + fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE; + return map; } static void fenced_buffer_unmap(struct pb_buffer *buf) { - struct fenced_buffer *fenced_buf = fenced_buffer(buf); + struct fenced_buffer *fenced_buf = fenced_buffer(buf); + assert(fenced_buf->mapcount); pb_unmap(fenced_buf->buffer); + --fenced_buf->mapcount; + if(!fenced_buf->mapcount) + fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE; } @@ -288,13 +350,22 @@ buffer_fence(struct pb_buffer *buf, struct fenced_buffer *fenced_buf = fenced_buffer(buf); struct fenced_buffer_list *fenced_list = fenced_buf->list; struct pipe_winsys *winsys = fenced_list->winsys; + /* FIXME: receive this as a parameter */ + unsigned flags = fence ? PIPE_BUFFER_USAGE_GPU_READ_WRITE : 0; + + if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK) { + /* FIXME: propagate error */ + (void)0; + } _glthread_LOCK_MUTEX(fenced_list->mutex); if (fenced_buf->fence) _fenced_buffer_remove(fenced_buf); - winsys->fence_reference(winsys, &fenced_buf->fence, fence); - if (fenced_buf->fence) + if (fence) { + winsys->fence_reference(winsys, &fenced_buf->fence, fence); + fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE; _fenced_buffer_add(fenced_buf); + } _glthread_UNLOCK_MUTEX(fenced_list->mutex); } -- cgit v1.2.3 From 5b8fa518476868530d748ce6d03674e9cca3d89f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 14 Apr 2008 23:55:36 +0900 Subject: gallium: Don't assume snprintf are always available. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 9 ++-- src/gallium/auxiliary/util/p_debug.c | 7 +-- src/gallium/auxiliary/util/u_snprintf.c | 16 +++--- src/gallium/auxiliary/util/u_string.h | 63 ++++++++++++++++++++++ .../drivers/i915simple/i915_fpc_translate.c | 3 +- src/gallium/drivers/i915simple/i915_screen.c | 3 +- src/gallium/drivers/i965simple/brw_screen.c | 3 +- src/gallium/include/pipe/p_format.h | 4 +- src/gallium/include/pipe/p_util.h | 8 --- 9 files changed, 88 insertions(+), 28 deletions(-) create mode 100644 src/gallium/auxiliary/util/u_string.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index cb3573ceb6..ff6a2c4194 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -30,6 +30,7 @@ #include "pipe/p_debug.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" +#include "util/u_string.h" #include "tgsi_dump.h" #include "tgsi_parse.h" #include "tgsi_build.h" @@ -147,7 +148,7 @@ gen_dump_uix( { char str[36]; - sprintf( str, "0x%x", ui ); + util_snprintf( str, sizeof(str), "0x%x", ui ); gen_dump_str( dump, str ); } @@ -158,7 +159,7 @@ gen_dump_uid( { char str[16]; - sprintf( str, "%u", ui ); + util_snprintf( str, sizeof(str), "%u", ui ); gen_dump_str( dump, str ); } @@ -169,7 +170,7 @@ gen_dump_sid( { char str[16]; - sprintf( str, "%d", si ); + util_snprintf( str, sizeof(str), "%d", si ); gen_dump_str( dump, str ); } @@ -180,7 +181,7 @@ gen_dump_flt( { char str[48]; - sprintf( str, "%10.4f", flt ); + util_snprintf( str, sizeof(str), "%10.4f", flt ); gen_dump_str( dump, str ); } diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 090e3b7794..f9366467cd 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -39,6 +39,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_util.h" #include "pipe/p_debug.h" +#include "util/u_string.h" #ifdef WIN32 @@ -60,7 +61,7 @@ void _debug_vprintf(const char *format, va_list ap) /* EngDebugPrint does not handle float point arguments, so we need to use * our own vsnprintf implementation */ char buf[512 + 1]; - vsnprintf(buf, sizeof(buf), format, ap); + util_vsnprintf(buf, sizeof(buf), format, ap); _EngDebugPrint("%s", buf); #else /* TODO: Implement debug print for WINCE */ @@ -311,7 +312,7 @@ debug_dump_enum(const struct debug_named_value *names, ++names; } - snprintf(rest, sizeof(rest), "0x%08lx", value); + util_snprintf(rest, sizeof(rest), "0x%08lx", value); return rest; } @@ -344,7 +345,7 @@ debug_dump_flags(const struct debug_named_value *names, else first = 0; - snprintf(rest, sizeof(rest), "0x%08lx", value); + util_snprintf(rest, sizeof(rest), "0x%08lx", value); strncat(output, rest, sizeof(output)); } diff --git a/src/gallium/auxiliary/util/u_snprintf.c b/src/gallium/auxiliary/util/u_snprintf.c index 48426abcb7..c4f4bbd30c 100644 --- a/src/gallium/auxiliary/util/u_snprintf.c +++ b/src/gallium/auxiliary/util/u_snprintf.c @@ -166,8 +166,8 @@ #include #else #ifdef WIN32 -#define vsnprintf rpl_vsnprintf -#define snprintf rpl_snprintf +#define vsnprintf util_vsnprintf +#define snprintf util_snprintf #define HAVE_VSNPRINTF 0 #define HAVE_SNPRINTF 0 #define HAVE_VASPRINTF 1 /* not needed */ @@ -445,7 +445,7 @@ static UINTMAX_T myround(LDOUBLE); static LDOUBLE mypow10(int); int -rpl_vsnprintf(char *str, size_t size, const char *format, va_list args) +util_vsnprintf(char *str, size_t size, const char *format, va_list args) { LDOUBLE fvalue; INTMAX_T value; @@ -1404,7 +1404,7 @@ mymemcpy(void *dst, void *src, size_t len) #endif /* NEED_MYMEMCPY */ int -rpl_vasprintf(char **ret, const char *format, va_list ap) +util_vasprintf(char **ret, const char *format, va_list ap) { size_t size; int len; @@ -1422,10 +1422,10 @@ rpl_vasprintf(char **ret, const char *format, va_list ap) #if !HAVE_SNPRINTF #if HAVE_STDARG_H int -rpl_snprintf(char *str, size_t size, const char *format, ...) +util_snprintf(char *str, size_t size, const char *format, ...) #else int -rpl_snprintf(va_alist) va_dcl +util_snprintf(va_alist) va_dcl #endif /* HAVE_STDARG_H */ { #if !HAVE_STDARG_H @@ -1449,10 +1449,10 @@ rpl_snprintf(va_alist) va_dcl #if !HAVE_ASPRINTF #if HAVE_STDARG_H int -rpl_asprintf(char **ret, const char *format, ...) +util_asprintf(char **ret, const char *format, ...) #else int -rpl_asprintf(va_alist) va_dcl +util_asprintf(va_alist) va_dcl #endif /* HAVE_STDARG_H */ { #if !HAVE_STDARG_H diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h new file mode 100644 index 0000000000..b99d4e8021 --- /dev/null +++ b/src/gallium/auxiliary/util/u_string.h @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Platform independent functions for string manipulation. + * + * @author Jose Fonseca + */ + +#ifndef U_STRING_H_ +#define U_STRING_H_ + +#ifndef WIN32 +#include +#endif +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef WIN32 +int util_vsnprintf(char *, size_t, const char *, va_list); +int util_snprintf(char *str, size_t size, const char *format, ...); +#else +#define util_vsnprintf vsnprintf +#define util_snprintf snprintf +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* U_STRING_H_ */ diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 7b4fca5db1..3ccf74c72c 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -33,6 +33,7 @@ #include "i915_fpc.h" #include "pipe/p_shader_tokens.h" +#include "util/u_string.h" #include "tgsi/util/tgsi_parse.h" #include "tgsi/util/tgsi_dump.h" @@ -122,7 +123,7 @@ i915_program_error(struct i915_fp_compile *p, const char *msg, ...) debug_printf("i915_program_error: "); va_start( args, msg ); - vsprintf( buffer, msg, args ); + util_vsnprintf( buffer, sizeof(buffer), msg, args ); va_end( args ); debug_printf(buffer); debug_printf("\n"); diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 839b98c0ce..9ae594ce54 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -28,6 +28,7 @@ #include "pipe/p_util.h" #include "pipe/p_winsys.h" +#include "util/u_string.h" #include "i915_reg.h" #include "i915_context.h" @@ -78,7 +79,7 @@ i915_get_name( struct pipe_screen *pscreen ) break; } - sprintf(buffer, "i915 (chipset: %s)", chipset); + util_snprintf(buffer, sizeof(buffer), "i915 (chipset: %s)", chipset); return buffer; } diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c index 5be369fe52..6845c7abde 100644 --- a/src/gallium/drivers/i965simple/brw_screen.c +++ b/src/gallium/drivers/i965simple/brw_screen.c @@ -28,6 +28,7 @@ #include "pipe/p_util.h" #include "pipe/p_winsys.h" +#include "util/u_string.h" #include "brw_context.h" #include "brw_screen.h" @@ -66,7 +67,7 @@ brw_get_name( struct pipe_screen *screen ) break; } - sprintf(buffer, "i965 (chipset: %s)", chipset); + util_snprintf(buffer, sizeof(buffer), "i965 (chipset: %s)", chipset); return buffer; } diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 9e0f91f202..ef9e3a3d6c 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -28,7 +28,7 @@ #ifndef PIPE_FORMAT_H #define PIPE_FORMAT_H -#include /* for sprintf */ +#include "util/u_string.h" #include "p_compiler.h" #include "p_debug.h" @@ -367,7 +367,7 @@ static INLINE char *pf_sprint_name( char *str, enum pipe_format format ) strcat( str, "S" ); break; } - sprintf( &str[strlen( str )], "%u", size * scale ); + util_snprintf( &str[strlen( str )], 32, "%u", size * scale ); } if (i != 0) { strcat( str, "_" ); diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 8e3aaee496..dbca080a4b 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -138,14 +138,6 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define GETENV( X ) debug_get_option( X, NULL ) -#ifdef WIN32 -int rpl_vsnprintf(char *, size_t, const char *, va_list); -int rpl_snprintf(char *str, size_t size, const char *format, ...); -#define vsnprintf rpl_vsnprintf -#define snprintf rpl_snprintf -#endif - - /** * Return memory on given byte alignment */ -- cgit v1.2.3 From 01c7dd2629d161bf87af679a3045e1e2d54259fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Apr 2008 10:38:05 +0900 Subject: gallium: Add draw_pt_fetch_shade_pipeline.c to scons build. --- src/gallium/auxiliary/draw/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 52107912f5..a7fb5dbd61 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -18,6 +18,7 @@ draw = env.ConvenienceLibrary( 'draw_pt_vcache.c', 'draw_pt_fetch_emit.c', 'draw_pt_fetch_pipeline.c', + 'draw_pt_fetch_shade_pipeline.c', 'draw_pt_pipeline.c', 'draw_pt_elts.c', 'draw_prim.c', -- cgit v1.2.3 From fdd794dcfa33482bdabe7c04ec9df655e0c69bfc Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 14 Apr 2008 20:55:14 -0600 Subject: gallium: fix PIPE_CAP_MAX_RENDER_TARGETS query --- src/gallium/drivers/softpipe/sp_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 1850a1ced3..7dacb1c461 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -68,7 +68,7 @@ softpipe_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_POINT_SPRITE: return 1; case PIPE_CAP_MAX_RENDER_TARGETS: - return 1; + return PIPE_MAX_COLOR_BUFS; case PIPE_CAP_OCCLUSION_QUERY: return 1; case PIPE_CAP_TEXTURE_SHADOW_MAP: -- cgit v1.2.3 From d3878b070b7b5084526b65499737cc686a6039b6 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 14 Apr 2008 21:01:40 -0600 Subject: gallium: enable new quad output code, remove old code --- src/gallium/drivers/softpipe/sp_quad_fs.c | 36 ------------------------------- 1 file changed, 36 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 9a20c056a2..8dbdbe5764 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -88,7 +88,6 @@ shade_quad( &qss->machine, quad ); -#if 0 /* XXX multi color outputs - untested */ /* store outputs */ boolean z_written = FALSE; { @@ -133,41 +132,6 @@ shade_quad( quad->outputs.depth[2] = z0 + dzdy; quad->outputs.depth[3] = z0 + dzdx + dzdy; } -#endif - - /* store result color(s) */ - if (qss->colorOutSlot >= 0) { - /* XXX need to handle multiple color outputs someday */ - assert(softpipe->fs->info.output_semantic_name[qss->colorOutSlot] - == TGSI_SEMANTIC_COLOR); - memcpy( - quad->outputs.color[0], - &machine->Outputs[qss->colorOutSlot].xyzw[0].f[0], - sizeof( quad->outputs.color[0] ) ); - } - - /* store result Z */ - if (qss->depthOutSlot >= 0) { - /* output[slot] is new Z */ - uint i; - for (i = 0; i < 4; i++) { - quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i]; - } - } - else { - /* compute Z values now, as in the quad earlyz stage */ - /* XXX we should really only do this if the earlyz stage is not used */ - const float fx = (float) quad->x0; - const float fy = (float) quad->y0; - const float dzdx = quad->posCoef->dadx[2]; - const float dzdy = quad->posCoef->dady[2]; - const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy; - - quad->outputs.depth[0] = z0; - quad->outputs.depth[1] = z0 + dzdx; - quad->outputs.depth[2] = z0 + dzdy; - quad->outputs.depth[3] = z0 + dzdx + dzdy; - } /* shader may cull fragments */ if( quad->mask ) { -- cgit v1.2.3 From a175e15f20b2a231cc9d09099e7b6d8aea6c624e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Apr 2008 12:34:33 +0900 Subject: gallium: Allow to use a single slab. We often want to use a pool of equally sized buffers, so this makes the slab suballocator a drop-in replacement. --- src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 22 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 315 +++++++++++++--------- 2 files changed, 209 insertions(+), 128 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index b2d2520b67..96f9af3825 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -118,13 +118,21 @@ mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, * Slab sub-allocator. */ struct pb_manager * -pb_slab_manager_create(struct pb_manager *provider, - const struct pb_desc *desc, - size_t smallestSize, - size_t numSizes, - size_t desiredNumBuffers, - size_t maxSlabSize, - size_t pageAlignment); +pb_slab_manager_create(struct pb_manager *provider, + size_t bufSize, + size_t slabSize, + const struct pb_desc *desc); + +/** + * Allow a range of buffer size, by aggregating multiple slabs sub-allocators + * with different bucket sizes. + */ +struct pb_manager * +pb_slab_range_manager_create(struct pb_manager *provider, + size_t minBufSize, + size_t maxBufSize, + size_t slabSize, + const struct pb_desc *desc); /** diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index 676e8e29b9..9506ac9ae1 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -70,19 +70,24 @@ struct pb_slab size_t numBuffers; size_t numFree; struct pb_slab_buffer *buffers; - struct pb_slab_size_header *header; + struct pb_slab_manager *mgr; struct pb_buffer *bo; - size_t pageAlignment; void *virtual; }; -struct pb_slab_size_header +struct pb_slab_manager { + struct pb_manager base; + + struct pb_manager *provider; + size_t bufSize; + size_t slabSize; + struct pb_desc desc; + struct list_head slabs; struct list_head freeSlabs; - struct pb_slab_manager *pool; - size_t bufSize; + _glthread_Mutex mutex; }; @@ -90,19 +95,18 @@ struct pb_slab_size_header * The data of this structure remains constant after * initialization and thus needs no mutex protection. */ -struct pb_slab_manager +struct pb_slab_range_manager { struct pb_manager base; + struct pb_manager *provider; + size_t minBufSize; + size_t maxBufSize; struct pb_desc desc; + + unsigned numBuckets; size_t *bucketSizes; - size_t numBuckets; - size_t pageSize; - struct pb_manager *provider; - unsigned pageAlignment; - unsigned maxSlabSize; - unsigned desiredNumBuffers; - struct pb_slab_size_header *headers; + struct pb_manager **buckets; }; @@ -122,8 +126,16 @@ pb_slab_manager(struct pb_manager *mgr) } +static INLINE struct pb_slab_range_manager * +pb_slab_range_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct pb_slab_range_manager *)mgr; +} + + /** - * Delete a buffer from the slab header delayed list and put + * Delete a buffer from the slab delayed list and put * it on the slab FREE list. */ static void @@ -131,10 +143,10 @@ pb_slab_buffer_destroy(struct pb_buffer *_buf) { struct pb_slab_buffer *buf = pb_slab_buffer(_buf); struct pb_slab *slab = buf->slab; - struct pb_slab_size_header *header = slab->header; + struct pb_slab_manager *mgr = slab->mgr; struct list_head *list = &buf->head; - _glthread_LOCK_MUTEX(header->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); assert(buf->base.base.refcount == 0); @@ -145,21 +157,21 @@ pb_slab_buffer_destroy(struct pb_buffer *_buf) slab->numFree++; if (slab->head.next == &slab->head) - LIST_ADDTAIL(&slab->head, &header->slabs); + LIST_ADDTAIL(&slab->head, &mgr->slabs); if (slab->numFree == slab->numBuffers) { list = &slab->head; LIST_DEL(list); - LIST_ADDTAIL(list, &header->freeSlabs); + LIST_ADDTAIL(list, &mgr->freeSlabs); } - if (header->slabs.next == &header->slabs || slab->numFree + if (mgr->slabs.next == &mgr->slabs || slab->numFree != slab->numBuffers) { struct list_head *next; - for (list = header->freeSlabs.next, next = list->next; list - != &header->freeSlabs; list = next, next = list->next) { + for (list = mgr->freeSlabs.next, next = list->next; list + != &mgr->freeSlabs; list = next, next = list->next) { slab = LIST_ENTRY(struct pb_slab, list, head); @@ -170,7 +182,7 @@ pb_slab_buffer_destroy(struct pb_buffer *_buf) } } - _glthread_UNLOCK_MUTEX(header->mutex); + _glthread_UNLOCK_MUTEX(mgr->mutex); } @@ -217,15 +229,13 @@ pb_slab_buffer_vtbl = { static enum pipe_error -pb_slab_create(struct pb_slab_size_header *header) +pb_slab_create(struct pb_slab_manager *mgr) { - struct pb_slab_manager *pool = header->pool; - size_t size = header->bufSize * pool->desiredNumBuffers; struct pb_slab *slab; struct pb_slab_buffer *buf; - size_t numBuffers; - int ret; + unsigned numBuffers; unsigned i; + enum pipe_error ret; slab = CALLOC_STRUCT(pb_slab); if (!slab) @@ -236,22 +246,23 @@ pb_slab_create(struct pb_slab_size_header *header) * to efficiently reuse slabs. */ - size = (size <= pool->maxSlabSize) ? size : pool->maxSlabSize; - size = (size + pool->pageSize - 1) & ~(pool->pageSize - 1); - - slab->bo = pool->provider->create_buffer(pool->provider, size, &pool->desc); - if(!slab->bo) + slab->bo = mgr->provider->create_buffer(mgr->provider, mgr->slabSize, &mgr->desc); + if(!slab->bo) { + ret = PIPE_ERROR_OUT_OF_MEMORY; goto out_err0; + } slab->virtual = pb_map(slab->bo, - PIPE_BUFFER_USAGE_CPU_READ | - PIPE_BUFFER_USAGE_CPU_WRITE); - if(!slab->virtual) + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + if(!slab->virtual) { + ret = PIPE_ERROR_OUT_OF_MEMORY; goto out_err1; + } pb_unmap(slab->bo); - numBuffers = slab->bo->base.size / header->bufSize; + numBuffers = slab->bo->base.size / mgr->bufSize; slab->buffers = CALLOC(numBuffers, sizeof(*slab->buffers)); if (!slab->buffers) { @@ -263,17 +274,17 @@ pb_slab_create(struct pb_slab_size_header *header) LIST_INITHEAD(&slab->freeBuffers); slab->numBuffers = numBuffers; slab->numFree = 0; - slab->header = header; + slab->mgr = mgr; buf = slab->buffers; for (i=0; i < numBuffers; ++i) { buf->base.base.refcount = 0; - buf->base.base.size = header->bufSize; + buf->base.base.size = mgr->bufSize; buf->base.base.alignment = 0; buf->base.base.usage = 0; buf->base.vtbl = &pb_slab_buffer_vtbl; buf->slab = slab; - buf->start = i* header->bufSize; + buf->start = i* mgr->bufSize; buf->mapCount = 0; _glthread_INIT_COND(buf->event); LIST_ADDTAIL(&buf->head, &slab->freeBuffers); @@ -281,7 +292,7 @@ pb_slab_create(struct pb_slab_size_header *header) buf++; } - LIST_ADDTAIL(&slab->head, &header->slabs); + LIST_ADDTAIL(&slab->head, &mgr->slabs); return PIPE_OK; @@ -293,51 +304,55 @@ out_err0: } +static int +check_alignment(size_t requested, size_t provided) +{ + return requested <= provided && (provided % requested) == 0; +} + + static struct pb_buffer * -pb_slab_manager_create_buffer(struct pb_manager *_pool, +pb_slab_manager_create_buffer(struct pb_manager *_mgr, size_t size, const struct pb_desc *desc) { - struct pb_slab_manager *pool = pb_slab_manager(_pool); - struct pb_slab_size_header *header; - unsigned i; + struct pb_slab_manager *mgr = pb_slab_manager(_mgr); static struct pb_slab_buffer *buf; struct pb_slab *slab; struct list_head *list; int count = DRI_SLABPOOL_ALLOC_RETRIES; - /* - * FIXME: Check for compatibility. - */ - - header = pool->headers; - for (i=0; inumBuckets; ++i) { - if (header->bufSize >= size) - break; - header++; - } - - if (i >= pool->numBuckets) - /* Fall back to allocate a buffer object directly from the provider. */ - return pool->provider->create_buffer(pool->provider, size, desc); - + /* check size */ + assert(size == mgr->bufSize); + if(size != mgr->bufSize) + return NULL; + + /* check if we can provide the requested alignment */ + assert(check_alignment(desc->alignment, mgr->desc.alignment)); + if(!check_alignment(desc->alignment, mgr->desc.alignment)) + return NULL; + assert(check_alignment(desc->alignment, mgr->bufSize)); + if(!check_alignment(desc->alignment, mgr->bufSize)) + return NULL; - _glthread_LOCK_MUTEX(header->mutex); - while (header->slabs.next == &header->slabs && count > 0) { - if (header->slabs.next != &header->slabs) + /* XXX: check for compatible buffer usage too? */ + + _glthread_LOCK_MUTEX(mgr->mutex); + while (mgr->slabs.next == &mgr->slabs && count > 0) { + if (mgr->slabs.next != &mgr->slabs) break; - _glthread_UNLOCK_MUTEX(header->mutex); + _glthread_UNLOCK_MUTEX(mgr->mutex); if (count != DRI_SLABPOOL_ALLOC_RETRIES) util_time_sleep(1); - _glthread_LOCK_MUTEX(header->mutex); - (void) pb_slab_create(header); + _glthread_LOCK_MUTEX(mgr->mutex); + (void) pb_slab_create(mgr); count--; } - list = header->slabs.next; - if (list == &header->slabs) { - _glthread_UNLOCK_MUTEX(header->mutex); + list = mgr->slabs.next; + if (list == &mgr->slabs) { + _glthread_UNLOCK_MUTEX(mgr->mutex); return NULL; } slab = LIST_ENTRY(struct pb_slab, list, head); @@ -347,83 +362,141 @@ pb_slab_manager_create_buffer(struct pb_manager *_pool, list = slab->freeBuffers.next; LIST_DELINIT(list); - _glthread_UNLOCK_MUTEX(header->mutex); + _glthread_UNLOCK_MUTEX(mgr->mutex); buf = LIST_ENTRY(struct pb_slab_buffer, list, head); + ++buf->base.base.refcount; + buf->base.base.alignment = desc->alignment; + buf->base.base.usage = desc->usage; + return &buf->base; } static void -pb_slab_manager_destroy(struct pb_manager *_pool) +pb_slab_manager_destroy(struct pb_manager *_mgr) { - struct pb_slab_manager *pool = pb_slab_manager(_pool); + struct pb_slab_manager *mgr = pb_slab_manager(_mgr); - FREE(pool->headers); - FREE(pool->bucketSizes); - FREE(pool); + /* TODO: cleanup all allocated buffers */ + FREE(mgr); } struct pb_manager * -pb_slab_manager_create(struct pb_manager *provider, - const struct pb_desc *desc, - size_t smallestSize, - size_t numSizes, - size_t desiredNumBuffers, - size_t maxSlabSize, - size_t pageAlignment) +pb_slab_manager_create(struct pb_manager *provider, + size_t bufSize, + size_t slabSize, + const struct pb_desc *desc) +{ + struct pb_slab_manager *mgr; + + mgr = CALLOC_STRUCT(pb_slab_manager); + if (!mgr) + return NULL; + + mgr->base.destroy = pb_slab_manager_destroy; + mgr->base.create_buffer = pb_slab_manager_create_buffer; + + mgr->provider = provider; + mgr->bufSize = bufSize; + mgr->slabSize = slabSize; + mgr->desc = *desc; + + LIST_INITHEAD(&mgr->slabs); + LIST_INITHEAD(&mgr->freeSlabs); + + _glthread_INIT_MUTEX(mgr->mutex); + + return &mgr->base; +} + + +static struct pb_buffer * +pb_slab_range_manager_create_buffer(struct pb_manager *_mgr, + size_t size, + const struct pb_desc *desc) { - struct pb_slab_manager *pool; - size_t i; + struct pb_slab_range_manager *mgr = pb_slab_range_manager(_mgr); + size_t bufSize; + unsigned i; - pool = CALLOC_STRUCT(pb_slab_manager); - if (!pool) + bufSize = mgr->minBufSize; + for (i = 0; i < mgr->numBuckets; ++i) { + if(bufSize >= size) + return mgr->buckets[i]->create_buffer(mgr->buckets[i], size, desc); + bufSize *= 2; + } + + /* Fall back to allocate a buffer object directly from the provider. */ + return mgr->provider->create_buffer(mgr->provider, size, desc); +} + + +static void +pb_slab_range_manager_destroy(struct pb_manager *_mgr) +{ + struct pb_slab_range_manager *mgr = pb_slab_range_manager(_mgr); + unsigned i; + + for (i = 0; i < mgr->numBuckets; ++i) + mgr->buckets[i]->destroy(mgr->buckets[i]); + FREE(mgr->buckets); + FREE(mgr->bucketSizes); + FREE(mgr); +} + + +struct pb_manager * +pb_slab_range_manager_create(struct pb_manager *provider, + size_t minBufSize, + size_t maxBufSize, + size_t slabSize, + const struct pb_desc *desc) +{ + struct pb_slab_range_manager *mgr; + size_t bufSize; + unsigned i; + + mgr = CALLOC_STRUCT(pb_slab_range_manager); + if (!mgr) goto out_err0; - pool->bucketSizes = CALLOC(numSizes, sizeof(*pool->bucketSizes)); - if (!pool->bucketSizes) - goto out_err1; + mgr->base.destroy = pb_slab_range_manager_destroy; + mgr->base.create_buffer = pb_slab_range_manager_create_buffer; - pool->headers = CALLOC(numSizes, sizeof(*pool->headers)); - if (!pool->headers) - goto out_err2; - - pool->desc = *desc; - pool->numBuckets = numSizes; -#ifdef WIN32 - pool->pageSize = 4096; -#else - pool->pageSize = getpagesize(); -#endif - pool->provider = provider; - pool->pageAlignment = pageAlignment; - pool->maxSlabSize = maxSlabSize; - pool->desiredNumBuffers = desiredNumBuffers; - - for (i=0; inumBuckets; ++i) { - struct pb_slab_size_header *header = &pool->headers[i]; - - pool->bucketSizes[i] = (smallestSize << i); - - _glthread_INIT_MUTEX(header->mutex); - - LIST_INITHEAD(&header->slabs); - LIST_INITHEAD(&header->freeSlabs); - - header->pool = pool; - header->bufSize = (smallestSize << i); + mgr->provider = provider; + mgr->minBufSize = minBufSize; + mgr->maxBufSize = maxBufSize; + + mgr->numBuckets = 1; + bufSize = minBufSize; + while(bufSize < maxBufSize) { + bufSize *= 2; + ++mgr->numBuckets; } + + mgr->buckets = CALLOC(mgr->numBuckets, sizeof(*mgr->buckets)); + if (!mgr->buckets) + goto out_err1; - pool->base.destroy = pb_slab_manager_destroy; - pool->base.create_buffer = pb_slab_manager_create_buffer; + bufSize = minBufSize; + for (i = 0; i < mgr->numBuckets; ++i) { + mgr->buckets[i] = pb_slab_manager_create(provider, bufSize, slabSize, desc); + if(!mgr->buckets[i]) + goto out_err2; + bufSize *= 2; + } - return &pool->base; + return &mgr->base; out_err2: - FREE(pool->bucketSizes); + for (i = 0; i < mgr->numBuckets; ++i) + if(mgr->buckets[i]) + mgr->buckets[i]->destroy(mgr->buckets[i]); + FREE(mgr->buckets); out_err1: - FREE(pool); + FREE(mgr); out_err0: return NULL; } -- cgit v1.2.3 From 0b995b44e5a02dd4a3abdb6b2a0821a32e597e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Apr 2008 12:35:00 +0900 Subject: gallium: Fix mismatching prototypes. --- src/gallium/auxiliary/util/u_time.c | 2 +- src/gallium/auxiliary/util/u_time.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c index e6c0b19ff6..04f85c42ef 100644 --- a/src/gallium/auxiliary/util/u_time.c +++ b/src/gallium/auxiliary/util/u_time.c @@ -133,7 +133,7 @@ util_time_timeout(const struct util_time *start, #ifdef WIN32 -void util_time_usleep(unsigned usecs) +void util_time_sleep(unsigned usecs) { LONGLONG start, curr, end; diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h index 32035cceb5..2133958446 100644 --- a/src/gallium/auxiliary/util/u_time.h +++ b/src/gallium/auxiliary/util/u_time.h @@ -87,7 +87,7 @@ util_time_timeout(const struct util_time *start, #ifndef WIN32 #define util_time_sleep usleep #else -int +void util_time_sleep(unsigned usecs); #endif -- cgit v1.2.3 From 50bbbbe581edd6b8d4fe9f8ba7f134e17dc80a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Apr 2008 14:58:32 +0900 Subject: gallium: Remove middle of scope declarations. --- src/gallium/drivers/softpipe/sp_quad_fs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 8dbdbe5764..625d0f9b48 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -77,7 +77,8 @@ shade_quad( struct quad_shade_stage *qss = quad_shade_stage( qs ); struct softpipe_context *softpipe = qs->softpipe; struct tgsi_exec_machine *machine = &qss->machine; - + boolean z_written; + /* Consts do not require 16 byte alignment. */ machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; @@ -89,7 +90,7 @@ shade_quad( quad ); /* store outputs */ - boolean z_written = FALSE; + z_written = FALSE; { const ubyte *sem_name = softpipe->fs->info.output_semantic_name; const ubyte *sem_index = softpipe->fs->info.output_semantic_index; -- cgit v1.2.3 From d005befcb9e191ae90619fbdd3c37e262ae3b03e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Apr 2008 15:40:35 +0900 Subject: gallium: Less confusing interface for timeouts. --- src/gallium/auxiliary/util/u_time.c | 6 +++--- src/gallium/auxiliary/util/u_time.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c index 04f85c42ef..01112ebe5a 100644 --- a/src/gallium/auxiliary/util/u_time.c +++ b/src/gallium/auxiliary/util/u_time.c @@ -120,15 +120,15 @@ util_time_compare(const struct util_time *t1, } -int +boolean util_time_timeout(const struct util_time *start, const struct util_time *end, const struct util_time *curr) { if(util_time_compare(start, end) <= 0) - return util_time_compare(start, curr) <= 0 && util_time_compare(curr, end) < 0; + return !(util_time_compare(start, curr) <= 0 && util_time_compare(curr, end) < 0); else - return util_time_compare(start, curr) <= 0 || util_time_compare(curr, end) < 0; + return !(util_time_compare(start, curr) <= 0 || util_time_compare(curr, end) < 0); } diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h index 2133958446..c8836c137f 100644 --- a/src/gallium/auxiliary/util/u_time.h +++ b/src/gallium/auxiliary/util/u_time.h @@ -77,9 +77,9 @@ util_time_diff(const struct util_time *t1, const struct util_time *t2); /** - * Returns zero when the timeout expires, non zero otherwise. + * Returns non-zero when the timeout expires. */ -int +boolean util_time_timeout(const struct util_time *start, const struct util_time *end, const struct util_time *curr); -- cgit v1.2.3 From 95aeeb6d746e57473116ef4d72c05330902f68a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Apr 2008 15:41:08 +0900 Subject: gallium: Several fixes to buffer caching. --- src/gallium/auxiliary/pipebuffer/pb_buffer.h | 11 ++++ src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 67 +++++++++++++++++----- src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 15 ++--- 3 files changed, 68 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index 4b09c80b2a..49705cb862 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -192,6 +192,17 @@ pb_reference(struct pb_buffer **dst, } +/** + * Utility function to check whether a requested alignment is consistent with + * the provided alignment or not. + */ +static INLINE int +pb_check_alignment(size_t requested, size_t provided) +{ + return requested <= provided && (provided % requested) == 0; +} + + /** * Malloc-based buffer to store data that can't be used by the graphics * hardware. diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 06de0bb6c3..543fd51253 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -136,7 +136,7 @@ _pb_cache_buffer_list_check_free(struct pb_cache_manager *mgr) while(curr != &mgr->delayed) { buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); - if(util_time_timeout(&buf->start, &buf->end, &now) != 0) + if(!util_time_timeout(&buf->start, &buf->end, &now)) break; _pb_cache_buffer_destroy(buf); @@ -202,6 +202,24 @@ pb_cache_buffer_vtbl = { }; +static INLINE boolean +pb_cache_is_buffer_compat(struct pb_cache_buffer *buf, + size_t size, + const struct pb_desc *desc) +{ + /* TODO: be more lenient with size */ + if(buf->base.base.size != size) + return FALSE; + + if(!pb_check_alignment(desc->alignment, buf->base.base.alignment)) + return FALSE; + + /* XXX: check usage too? */ + + return TRUE; +} + + static struct pb_buffer * pb_cache_manager_create_buffer(struct pb_manager *_mgr, size_t size, @@ -209,29 +227,45 @@ pb_cache_manager_create_buffer(struct pb_manager *_mgr, { struct pb_cache_manager *mgr = pb_cache_manager(_mgr); struct pb_cache_buffer *buf; + struct pb_cache_buffer *curr_buf; struct list_head *curr, *next; struct util_time now; - util_time_get(&now); + _glthread_LOCK_MUTEX(mgr->mutex); + + buf = NULL; curr = mgr->delayed.next; next = curr->next; + + /* search in the expired buffers, freeing them in the process */ + util_time_get(&now); while(curr != &mgr->delayed) { - buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); - - if(buf->base.base.size == size && - buf->base.base.alignment >= desc->alignment && - (buf->base.base.alignment % desc->alignment) == 0 && - /* buf->base.base.usage == usage */ 1) { - ++buf->base.base.refcount; - return &buf->base; - } - - if(util_time_timeout(&buf->start, &buf->end, &now) != 0) - _pb_cache_buffer_destroy(buf); + curr_buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); + if(!buf && pb_cache_is_buffer_compat(curr_buf, size, desc)) + buf = curr_buf; + else if(util_time_timeout(&curr_buf->start, &curr_buf->end, &now)) + _pb_cache_buffer_destroy(curr_buf); + curr = next; + next = curr->next; + } + /* keep searching in the hot buffers */ + while(!buf && curr != &mgr->delayed) { + curr_buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); + if(pb_cache_is_buffer_compat(curr_buf, size, desc)) + buf = curr_buf; curr = next; next = curr->next; } + + if(buf) { + LIST_DEL(&buf->head); + _glthread_UNLOCK_MUTEX(mgr->mutex); + ++buf->base.base.refcount; + return &buf->base; + } + + _glthread_UNLOCK_MUTEX(mgr->mutex); buf = CALLOC_STRUCT(pb_cache_buffer); if(!buf) @@ -243,6 +277,11 @@ pb_cache_manager_create_buffer(struct pb_manager *_mgr, return NULL; } + assert(buf->buffer->base.refcount >= 1); + assert(pb_check_alignment(desc->alignment, buf->buffer->base.alignment)); + assert((buf->buffer->base.usage & desc->usage) == desc->usage); + assert(buf->buffer->base.size >= size); + buf->base.base.refcount = 1; buf->base.base.alignment = buf->buffer->base.alignment; buf->base.base.usage = buf->buffer->base.usage; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index 9506ac9ae1..b931455056 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -304,13 +304,6 @@ out_err0: } -static int -check_alignment(size_t requested, size_t provided) -{ - return requested <= provided && (provided % requested) == 0; -} - - static struct pb_buffer * pb_slab_manager_create_buffer(struct pb_manager *_mgr, size_t size, @@ -328,11 +321,11 @@ pb_slab_manager_create_buffer(struct pb_manager *_mgr, return NULL; /* check if we can provide the requested alignment */ - assert(check_alignment(desc->alignment, mgr->desc.alignment)); - if(!check_alignment(desc->alignment, mgr->desc.alignment)) + assert(pb_check_alignment(desc->alignment, mgr->desc.alignment)); + if(!pb_check_alignment(desc->alignment, mgr->desc.alignment)) return NULL; - assert(check_alignment(desc->alignment, mgr->bufSize)); - if(!check_alignment(desc->alignment, mgr->bufSize)) + assert(pb_check_alignment(desc->alignment, mgr->bufSize)); + if(!pb_check_alignment(desc->alignment, mgr->bufSize)) return NULL; /* XXX: check for compatible buffer usage too? */ -- cgit v1.2.3 From 7619240cc0c24d3ad4d2424e65110c0326a12dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Apr 2008 15:58:14 +0900 Subject: gallium: Fix seg fault (James Vogt). --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c index bffca5b244..9d809e2f9b 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c @@ -30,7 +30,7 @@ * \file * A buffer manager that wraps buffers in fenced buffers. * - * \author José Fonseca + * \author José Fonseca */ @@ -101,7 +101,8 @@ fenced_bufmgr_destroy(struct pb_manager *mgr) fenced_buffer_list_destroy(fenced_mgr->fenced_list); - fenced_mgr->provider->destroy(fenced_mgr->provider); + if(fenced_mgr->provider) + fenced_mgr->provider->destroy(fenced_mgr->provider); FREE(fenced_mgr); } @@ -113,6 +114,9 @@ fenced_bufmgr_create(struct pb_manager *provider, { struct fenced_pb_manager *fenced_mgr; + if(!provider) + return NULL; + fenced_mgr = (struct fenced_pb_manager *)CALLOC(1, sizeof(*fenced_mgr)); if (!fenced_mgr) return NULL; -- cgit v1.2.3 From 3c4f1ba5a2edefd69b2c47abaf534fb3af3f259d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Apr 2008 17:08:10 +0900 Subject: gallium: Eliminate stdio file usage. Remove unused stuff. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 334 +++------------------------- src/gallium/auxiliary/tgsi/util/tgsi_dump.h | 10 - 2 files changed, 34 insertions(+), 310 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index ff6a2c4194..26bfc2051f 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -25,8 +25,6 @@ * **************************************************************************/ -#include - #include "pipe/p_debug.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" @@ -35,196 +33,28 @@ #include "tgsi_parse.h" #include "tgsi_build.h" -struct gen_dump -{ - unsigned tabs; - void (* write)( - struct gen_dump *dump, - const void *data, - unsigned size ); -}; - -struct text_dump -{ - struct gen_dump base; - char *text; - unsigned length; - unsigned capacity; -}; - -static void -_text_dump_write( - struct gen_dump *dump, - const void *data, - unsigned size ) -{ - struct text_dump *td = (struct text_dump *) dump; - unsigned new_length = td->length + size; - - if( new_length >= td->capacity ) { - unsigned new_capacity = td->capacity; - - do { - if( new_capacity == 0 ) { - new_capacity = 256; - } - else { - new_capacity *= 2; - } - } while( new_length >= new_capacity ); - td->text = (char *) REALLOC( - td->text, - td->capacity, - new_capacity ); - td->capacity = new_capacity; - } - memcpy( - &td->text[td->length], - data, - size ); - td->length = new_length; - td->text[td->length] = '\0'; -} - -struct file_dump -{ - struct gen_dump base; - FILE *file; -}; - -static void -_file_dump_write( - struct gen_dump *dump, - const void *data, - unsigned size ) -{ - struct file_dump *fd = (struct file_dump *) dump; - -#if 0 - fwrite( data, 1, size, fd->file ); -#else - { - unsigned i; - - for (i = 0; i < size; i++ ) { - fprintf( fd->file, "%c", ((const char *) data)[i] ); - } - } -#endif -} - -static void -gen_dump_str( - struct gen_dump *dump, - const char *str ) -{ - unsigned i; - size_t len = strlen( str ); - - for (i = 0; i < len; i++) { - dump->write( dump, &str[i], 1 ); - if (str[i] == '\n') { - unsigned i; - - for (i = 0; i < dump->tabs; i++) { - dump->write( dump, " ", 4 ); - } - } - } -} - -static void -gen_dump_chr( - struct gen_dump *dump, - const char chr ) -{ - dump->write( dump, &chr, 1 ); -} - -static void -gen_dump_uix( - struct gen_dump *dump, - const unsigned ui ) -{ - char str[36]; - - util_snprintf( str, sizeof(str), "0x%x", ui ); - gen_dump_str( dump, str ); -} - -static void -gen_dump_uid( - struct gen_dump *dump, - const unsigned ui ) -{ - char str[16]; - - util_snprintf( str, sizeof(str), "%u", ui ); - gen_dump_str( dump, str ); -} - -static void -gen_dump_sid( - struct gen_dump *dump, - const int si ) -{ - char str[16]; - - util_snprintf( str, sizeof(str), "%d", si ); - gen_dump_str( dump, str ); -} - static void -gen_dump_flt( - struct gen_dump *dump, - const float flt ) -{ - char str[48]; - - util_snprintf( str, sizeof(str), "%10.4f", flt ); - gen_dump_str( dump, str ); -} - -static void -gen_dump_enum( - struct gen_dump *dump, +dump_enum( const unsigned e, const char **enums, const unsigned enums_count ) { if (e >= enums_count) { - gen_dump_uid( dump, e ); + debug_printf( "%u", e ); } else { - gen_dump_str( dump, enums[e] ); + debug_printf( "%s", enums[e] ); } } -static void -gen_dump_tab( - struct gen_dump *dump ) -{ - ++dump->tabs; -} - -static void -gen_dump_untab( - struct gen_dump *dump ) -{ - assert( dump->tabs > 0 ); - - --dump->tabs; -} - -#define TXT(S) gen_dump_str( dump, S ) -#define CHR(C) gen_dump_chr( dump, C ) -#define UIX(I) gen_dump_uix( dump, I ) -#define UID(I) gen_dump_uid( dump, I ) -#define SID(I) gen_dump_sid( dump, I ) -#define FLT(F) gen_dump_flt( dump, F ) -#define TAB() gen_dump_tab( dump ) -#define UNT() gen_dump_untab( dump ) -#define ENM(E,ENUMS) gen_dump_enum( dump, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) +#define EOL() debug_printf( "\n" ) +#define TXT(S) debug_printf( "%s", S ) +#define CHR(C) debug_printf( "%c", C ) +#define UIX(I) debug_printf( "0x%x", I ) +#define UID(I) debug_printf( "%u", I ) +#define SID(I) debug_printf( "%d", I ) +#define FLT(F) debug_printf( "%10.4f", F ) +#define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) static const char *TGSI_PROCESSOR_TYPES[] = { @@ -711,7 +541,6 @@ static const char *TGSI_MODULATES[] = static void dump_declaration_short( - struct gen_dump *dump, struct tgsi_full_declaration *decl ) { TXT( "\nDCL " ); @@ -765,7 +594,6 @@ dump_declaration_short( static void dump_declaration_verbose( - struct gen_dump *dump, struct tgsi_full_declaration *decl, unsigned ignored, unsigned deflt, @@ -803,7 +631,7 @@ dump_declaration_verbose( UIX( decl->Declaration.Padding ); } - CHR( '\n' ); + EOL(); switch( decl->Declaration.Declare ) { case TGSI_DECLARE_RANGE: TXT( "\nFirst: " ); @@ -822,7 +650,7 @@ dump_declaration_verbose( } if( decl->Declaration.Interpolate ) { - CHR( '\n' ); + EOL(); TXT( "\nInterpolate: " ); ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES ); if( ignored ) { @@ -832,7 +660,7 @@ dump_declaration_verbose( } if( decl->Declaration.Semantic ) { - CHR( '\n' ); + EOL(); TXT( "\nSemanticName : " ); ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS ); TXT( "\nSemanticIndex: " ); @@ -846,7 +674,6 @@ dump_declaration_verbose( static void dump_immediate_short( - struct gen_dump *dump, struct tgsi_full_immediate *imm ) { unsigned i; @@ -874,7 +701,6 @@ dump_immediate_short( static void dump_immediate_verbose( - struct gen_dump *dump, struct tgsi_full_immediate *imm, unsigned ignored ) { @@ -888,7 +714,7 @@ dump_immediate_verbose( } for( i = 0; i < imm->Immediate.Size - 1; i++ ) { - CHR( '\n' ); + EOL(); switch( imm->Immediate.DataType ) { case TGSI_IMM_FLOAT32: TXT( "\nFloat: " ); @@ -903,14 +729,13 @@ dump_immediate_verbose( static void dump_instruction_short( - struct gen_dump *dump, struct tgsi_full_instruction *inst, unsigned instno ) { unsigned i; boolean first_reg = TRUE; - CHR( '\n' ); + EOL(); UID( instno ); CHR( ':' ); ENM( inst->Instruction.Opcode, TGSI_OPCODES_SHORT ); @@ -1042,7 +867,6 @@ dump_instruction_short( static void dump_instruction_verbose( - struct gen_dump *dump, struct tgsi_full_instruction *inst, unsigned ignored, unsigned deflt, @@ -1070,7 +894,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi->InstructionExtNv ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS ); if( deflt || fi->InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) { @@ -1124,7 +948,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS ); if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) { @@ -1142,7 +966,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS ); if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) { @@ -1163,7 +987,7 @@ dump_instruction_verbose( struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i]; - CHR( '\n' ); + EOL(); TXT( "\nFile : " ); ENM( dst->DstRegister.File, TGSI_FILES ); if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) { @@ -1194,7 +1018,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS ); if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) { @@ -1232,7 +1056,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS ); if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) { @@ -1254,7 +1078,7 @@ dump_instruction_verbose( struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i]; - CHR( '\n' ); + EOL(); TXT( "\nFile : "); ENM( src->SrcRegister.File, TGSI_FILES ); if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) { @@ -1299,7 +1123,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS ); if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) { @@ -1345,7 +1169,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS ); if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) { @@ -1380,9 +1204,8 @@ dump_instruction_verbose( } } -static void -dump_gen( - struct gen_dump *dump, +void +tgsi_dump( const struct tgsi_token *tokens, unsigned flags ) { @@ -1394,16 +1217,16 @@ dump_gen( unsigned deflt = !(flags & TGSI_DUMP_NO_DEFAULT); unsigned instno = 0; - dump->tabs = 0; - - /* sanity check */ + /* sanity checks */ assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); + assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "END") == 0); tgsi_parse_init( &parse, tokens ); TXT( "tgsi-dump begin -----------------" ); - CHR( '\n' ); + EOL(); ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES_SHORT ); UID( parse.FullVersion.Version.MajorVersion ); CHR( '.' ); @@ -1414,7 +1237,7 @@ dump_gen( UID( parse.FullVersion.Version.MajorVersion ); TXT( "\nMinorVersion: " ); UID( parse.FullVersion.Version.MinorVersion ); - CHR( '\n' ); + EOL(); TXT( "\nHeaderSize: " ); UID( parse.FullHeader.Header.HeaderSize ); @@ -1422,7 +1245,7 @@ dump_gen( UID( parse.FullHeader.Header.BodySize ); TXT( "\nProcessor : " ); ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); - CHR( '\n' ); + EOL(); } fi = tgsi_default_full_instruction(); @@ -1434,19 +1257,16 @@ dump_gen( switch( parse.FullToken.Token.Type ) { case TGSI_TOKEN_TYPE_DECLARATION: dump_declaration_short( - dump, &parse.FullToken.FullDeclaration ); break; case TGSI_TOKEN_TYPE_IMMEDIATE: dump_immediate_short( - dump, &parse.FullToken.FullImmediate ); break; case TGSI_TOKEN_TYPE_INSTRUCTION: dump_instruction_short( - dump, &parse.FullToken.FullInstruction, instno ); instno++; @@ -1471,7 +1291,6 @@ dump_gen( switch( parse.FullToken.Token.Type ) { case TGSI_TOKEN_TYPE_DECLARATION: dump_declaration_verbose( - dump, &parse.FullToken.FullDeclaration, ignored, deflt, @@ -1480,14 +1299,12 @@ dump_gen( case TGSI_TOKEN_TYPE_IMMEDIATE: dump_immediate_verbose( - dump, &parse.FullToken.FullImmediate, ignored ); break; case TGSI_TOKEN_TYPE_INSTRUCTION: dump_instruction_verbose( - dump, &parse.FullToken.FullInstruction, ignored, deflt, @@ -1498,7 +1315,7 @@ dump_gen( assert( 0 ); } - CHR( '\n' ); + EOL(); } } @@ -1506,86 +1323,3 @@ dump_gen( tgsi_parse_free( &parse ); } - - -static void -sanity_checks(void) -{ - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); - assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "END") == 0); -} - - -void -tgsi_dump( - const struct tgsi_token *tokens, - unsigned flags ) -{ - struct file_dump dump; - - sanity_checks(); - - dump.base.write = _file_dump_write; -#if 0 - { - static unsigned counter = 0; - char buffer[64]; - sprintf( buffer, "tgsi-dump-%.4u.txt", counter++ ); - dump.file = fopen( buffer, "wt" ); - } -#else - dump.file = stderr; -#endif - - dump_gen( - &dump.base, - tokens, - flags ); - -#if 0 - fclose( dump.file ); -#endif -} - -void -tgsi_dump_str( - char **str, - const struct tgsi_token *tokens, - unsigned flags ) -{ - struct text_dump dump; - - dump.base.write = _text_dump_write; - dump.text = NULL; - dump.length = 0; - dump.capacity = 0; - - dump_gen( - &dump.base, - tokens, - flags ); - - *str = dump.text; -} - - -void tgsi_debug_dump( struct tgsi_token *tokens ) -{ - char *str, *p; - - tgsi_dump_str( &str, tokens, 0 ); - - p = str; - while (p != NULL) - { - char *end = strchr( p, '\n' ); - if (end != NULL) - { - *end++ = '\0'; - } - debug_printf( "%s\n", p ); - p = end; - } - - FREE( str ); -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h index 51d79a0362..beb0155d56 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h @@ -14,16 +14,6 @@ tgsi_dump( const struct tgsi_token *tokens, unsigned flags ); -void -tgsi_dump_str( - char **str, - const struct tgsi_token *tokens, - unsigned flags ); - -/* Dump to debug_printf() - */ -void tgsi_debug_dump( struct tgsi_token *tokens ); - #if defined __cplusplus } #endif -- cgit v1.2.3 From a68f664124592829a3b715388e6cfa43f82900c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Apr 2008 18:11:47 +0900 Subject: gallium: Cache one line worth of debug output on windows. The windbg connection seems synchronous, so this speeds up when printing little text at a time (e.g., tgsi output). --- src/gallium/auxiliary/util/p_debug.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index f9366467cd..c195f61820 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -59,10 +59,15 @@ void _debug_vprintf(const char *format, va_list ap) #ifdef WIN32 #ifndef WINCE /* EngDebugPrint does not handle float point arguments, so we need to use - * our own vsnprintf implementation */ - char buf[512 + 1]; - util_vsnprintf(buf, sizeof(buf), format, ap); - _EngDebugPrint("%s", buf); + * our own vsnprintf implementation. It is also very slow, so buffer until + * we find a newline. */ + static char buf[512 + 1] = {'\0'}; + size_t len = strlen(buf); + int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap); + if(ret > (int)(sizeof(buf) - len - 1) || strchr(buf + len, '\n')) { + _EngDebugPrint("%s", buf); + buf[0] = '\0'; + } #else /* TODO: Implement debug print for WINCE */ #endif -- cgit v1.2.3 From f2ee51e7d9a9bde8fd7de29b382d11fe0d58226d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 15 Apr 2008 12:08:36 +0200 Subject: i915: Changed name to i915_dri.so --- src/gallium/winsys/dri/intel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index f140939248..c0ce2f927b 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -2,7 +2,7 @@ TOP = ../../../../.. include $(TOP)/configs/current -LIBNAME = i915tex_dri.so +LIBNAME = i915_dri.so MINIGLX_SOURCES = server/intel_dri.c -- cgit v1.2.3 From 6a26a9c58cc38ff636ee88ce01fed40eea500fc0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 14:28:41 +0100 Subject: draw: fetch_shade_pipeline needs to translate to hw vertex format (from get_vertex_info) --- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 158 +++++++++++++-------- 1 file changed, 102 insertions(+), 56 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 04b3d2c4cf..557cd43f5b 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -36,52 +36,60 @@ struct fetch_pipeline_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; + const ubyte *input_buf[2]; + struct { - const ubyte *ptr; - unsigned pitch; - void (*fetch)( const void *from, float *attrib); - void (*emit)( const float *attrib, float **out ); - } fetch[PIPE_MAX_ATTRIBS]; + const ubyte **input_buf; + unsigned input_offset; + unsigned output_offset; + + void (*emit)( const float *attrib, void *ptr ); + } translate[PIPE_MAX_ATTRIBS]; + unsigned nr_translate; - unsigned nr_fetch; unsigned pipeline_vertex_size; unsigned hw_vertex_size; unsigned prim; }; -#if 0 + +static void emit_NULL( const float *attrib, + void *ptr ) +{ +} + static void emit_R32_FLOAT( const float *attrib, - float **out ) + void *ptr ) { - (*out)[0] = attrib[0]; - (*out) += 1; + float *out = (float *)ptr; + out[0] = attrib[0]; } static void emit_R32G32_FLOAT( const float *attrib, - float **out ) + void *ptr ) { - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out) += 2; + float *out = (float *)ptr; + out[0] = attrib[0]; + out[1] = attrib[1]; } static void emit_R32G32B32_FLOAT( const float *attrib, - float **out ) + void *ptr ) { - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out) += 3; + float *out = (float *)ptr; + out[0] = attrib[0]; + out[1] = attrib[1]; + out[2] = attrib[2]; } -#endif + static void emit_R32G32B32A32_FLOAT( const float *attrib, - float **out ) + void *ptr ) { - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out)[3] = attrib[3]; - (*out) += 4; + float *out = (float *)ptr; + out[0] = attrib[0]; + out[1] = attrib[1]; + out[2] = attrib[2]; + out[3] = attrib[3]; } static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, @@ -89,9 +97,10 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; - unsigned i, nr = 0; + unsigned i; boolean ok; const struct vertex_info *vinfo; + unsigned dst_offset; fpme->prim = prim; @@ -100,33 +109,63 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, assert(0); return; } + /* Must do this after set_primitive() above: */ vinfo = draw->render->get_vertex_info(draw->render); - /* Need to look at vertex shader inputs (we know it is a - * passthrough shader, so these define the outputs too). If we - * were running a shader, we'd still be looking at the inputs at - * this point. - */ - for (i = 0; i < draw->vertex_shader->info.num_inputs; i++) { - unsigned buf = draw->vertex_element[i].vertex_buffer_index; - enum pipe_format format = draw->vertex_element[i].src_format; - - fpme->fetch[nr].ptr = ((const ubyte *) draw->user.vbuffer[buf] + - draw->vertex_buffer[buf].buffer_offset + - draw->vertex_element[i].src_offset); - fpme->fetch[nr].pitch = draw->vertex_buffer[buf].pitch; - fpme->fetch[nr].fetch = draw_get_fetch_func( format ); + /* In passthrough mode, need to translate from vertex shader + * outputs to hw vertices. + */ + dst_offset = 0; + for (i = 0; i < vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned src_buffer = 0; + unsigned src_offset = (sizeof(struct vertex_header) + + vinfo->src_index[i] * 4 * sizeof(float) ); + + + + switch (vinfo->emit[i]) { + case EMIT_4F: + fpme->translate[i].emit = emit_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + fpme->translate[i].emit = emit_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + fpme->translate[i].emit = emit_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + fpme->translate[i].emit = emit_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + fpme->translate[i].emit = emit_R32_FLOAT; + emit_sz = 1 * sizeof(float); + src_buffer = 1; + src_offset = 0; + break; + default: + assert(0); + fpme->translate[i].emit = emit_NULL; + emit_sz = 0; + break; + } - /* Always do this -- somewhat redundant... - */ - fpme->fetch[nr].emit = emit_R32G32B32A32_FLOAT; - nr++; + fpme->translate[i].input_buf = &fpme->input_buf[src_buffer]; + fpme->translate[i].input_offset = src_offset; + fpme->translate[i].output_offset = dst_offset; + dst_offset += emit_sz; } - fpme->nr_fetch = nr; + fpme->nr_translate = vinfo->num_attribs; + fpme->hw_vertex_size = vinfo->size * 4; + //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; fpme->hw_vertex_size = vinfo->size * 4; @@ -171,7 +210,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, } else { unsigned i, j; void *hw_verts; - float *out; + char *out_buf; /* XXX: need to flush to get prim_vbuf.c to release its allocation?? */ @@ -185,22 +224,29 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, return; } - out = (float *)hw_verts; + out_buf = (char *)hw_verts; + fpme->input_buf[0] = (const ubyte *)pipeline_verts; + fpme->input_buf[1] = (const ubyte *)&fpme->draw->rasterizer->point_size; + for (i = 0; i < fetch_count; i++) { - struct vertex_header *header = - (struct vertex_header*)(pipeline_verts + (fpme->pipeline_vertex_size * i)); - for (j = 0; j < fpme->nr_fetch; j++) { - float *attrib = header->data[j]; + for (j = 0; j < fpme->nr_translate; j++) { + + const float *attrib = (const float *)( (*fpme->translate[i].input_buf) + + fpme->translate[i].input_offset ); + + char *dest = out_buf + fpme->translate[i].output_offset; + /*debug_printf("emiting [%f, %f, %f, %f]\n", attrib[0], attrib[1], attrib[2], attrib[3]);*/ - fpme->fetch[j].emit(attrib, &out); + + fpme->translate[j].emit(attrib, dest); } + + fpme->input_buf[0] += fpme->pipeline_vertex_size; } - /* XXX: Draw arrays path to avoid re-emitting index list again and - * again. - */ + draw->render->draw(draw->render, draw_elts, draw_count); -- cgit v1.2.3 From c81bbab6f6c0413996799800cac6fb49a698e765 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 14:35:29 +0100 Subject: gallium: add a generic vertex (or other) buffer translation module --- src/gallium/auxiliary/translate/Makefile | 12 + src/gallium/auxiliary/translate/SConscript | 9 + src/gallium/auxiliary/translate/translate.h | 82 +++ .../auxiliary/translate/translate_generic.c | 630 +++++++++++++++++++++ 4 files changed, 733 insertions(+) create mode 100644 src/gallium/auxiliary/translate/Makefile create mode 100644 src/gallium/auxiliary/translate/SConscript create mode 100644 src/gallium/auxiliary/translate/translate.h create mode 100644 src/gallium/auxiliary/translate/translate_generic.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/Makefile b/src/gallium/auxiliary/translate/Makefile new file mode 100644 index 0000000000..051987bb7e --- /dev/null +++ b/src/gallium/auxiliary/translate/Makefile @@ -0,0 +1,12 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = translate + +C_SOURCES = \ + translate_generic.c + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/auxiliary/translate/SConscript b/src/gallium/auxiliary/translate/SConscript new file mode 100644 index 0000000000..947b9438cb --- /dev/null +++ b/src/gallium/auxiliary/translate/SConscript @@ -0,0 +1,9 @@ +Import('*') + +cso_cache = env.ConvenienceLibrary( + target = 'translate', + source = [ + 'translate_generic.c', + ]) + +auxiliaries.insert(0, translate) diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h new file mode 100644 index 0000000000..ac6bc7088b --- /dev/null +++ b/src/gallium/auxiliary/translate/translate.h @@ -0,0 +1,82 @@ +/* + * Copyright 2008 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/** + * Vertex fetch/store/convert code. This functionality is used in two places: + * 1. Vertex fetch/convert - to grab vertex data from incoming vertex + * arrays and convert to format needed by vertex shaders. + * 2. Vertex store/emit - to convert simple float[][4] vertex attributes + * (which is the organization used throughout the draw/prim pipeline) to + * hardware-specific formats and emit into hardware vertex buffers. + * + * + * Authors: + * Keith Whitwell + */ + +#ifndef _TRANSLATE_H +#define _TRANSLATE_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" + +struct translate_element +{ + enum pipe_format input_format; + unsigned input_buffer; + unsigned input_offset; + + enum pipe_format output_format; + unsigned output_offset; +}; + + +struct translate { + void (*destroy)( struct translate * ); + + void (*set_buffer)( struct translate *, + unsigned i, + const void *ptr, + unsigned stride ); + + void (*run_elts)( struct translate *, + const unsigned *elts, + unsigned count, + void *output_buffer); +}; + + + +struct translate *translate_sse2_create( unsigned output_stride, + const struct translate_element *elements, + unsigned nr_elements ); + +struct translate *translate_generic_create( unsigned output_stride, + const struct translate_element *elements, + unsigned nr_elements ); + + +#endif diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c new file mode 100644 index 0000000000..643f6430c5 --- /dev/null +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -0,0 +1,630 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_state.h" +#include "translate.h" + + +#define DRAW_DBG 0 + +typedef void (*fetch_func)(const void *ptr, float *attrib); +typedef void (*emit_func)(const float *attrib, void *ptr); + + + +struct translate_generic { + struct translate translate; + + struct { + fetch_func fetch; + unsigned buffer; + unsigned input_offset; + + emit_func emit; + unsigned output_offset; + + char *input_ptr; + unsigned input_stride; + + } attrib[PIPE_MAX_ATTRIBS]; + + unsigned nr_attrib; + unsigned output_stride; +}; + + +static struct translate_generic *translate_generic( struct translate *translate ) +{ + return (struct translate_generic *)translate; +} + +/** + * Fetch a float[4] vertex attribute from memory, doing format/type + * conversion as needed. + * + * This is probably needed/dupliocated elsewhere, eg format + * conversion, texture sampling etc. + */ +#define ATTRIB( NAME, SZ, TYPE, FROM, TO ) \ +static void \ +fetch_##NAME(const void *ptr, float *attrib) \ +{ \ + const float defaults[4] = { 0,0,0,1 }; \ + int i; \ + \ + for (i = 0; i < SZ; i++) { \ + attrib[i] = FROM(i); \ + } \ + \ + for (; i < 4; i++) { \ + attrib[i] = defaults[i]; \ + } \ +} \ + \ +static void \ +emit_##NAME(const float *attrib, void *ptr) \ +{ \ + unsigned i; \ + TYPE *out = (TYPE *)ptr; \ + \ + for (i = 0; i < SZ; i++) { \ + out[i] = TO(attrib[i]); \ + } \ +} + + +#define FROM_64_FLOAT(i) ((float) ((double *) ptr)[i]) +#define FROM_32_FLOAT(i) (((float *) ptr)[i]) + +#define FROM_8_USCALED(i) ((float) ((unsigned char *) ptr)[i]) +#define FROM_16_USCALED(i) ((float) ((unsigned short *) ptr)[i]) +#define FROM_32_USCALED(i) ((float) ((unsigned int *) ptr)[i]) + +#define FROM_8_SSCALED(i) ((float) ((char *) ptr)[i]) +#define FROM_16_SSCALED(i) ((float) ((short *) ptr)[i]) +#define FROM_32_SSCALED(i) ((float) ((int *) ptr)[i]) + +#define FROM_8_UNORM(i) ((float) ((unsigned char *) ptr)[i] / 255.0f) +#define FROM_16_UNORM(i) ((float) ((unsigned short *) ptr)[i] / 65535.0f) +#define FROM_32_UNORM(i) ((float) ((unsigned int *) ptr)[i] / 4294967295.0f) + +#define FROM_8_SNORM(i) ((float) ((char *) ptr)[i] / 127.0f) +#define FROM_16_SNORM(i) ((float) ((short *) ptr)[i] / 32767.0f) +#define FROM_32_SNORM(i) ((float) ((int *) ptr)[i] / 2147483647.0f) + +#define TO_64_FLOAT(f) ((double) f) +#define TO_32_FLOAT(f) (f) + +#define TO_8_USCALED(f) ((unsigned char) f) +#define TO_16_USCALED(f) ((unsigned short) f) +#define TO_32_USCALED(f) ((unsigned int) f) + +#define TO_8_SSCALED(f) ((char) f) +#define TO_16_SSCALED(f) ((short) f) +#define TO_32_SSCALED(f) ((int) f) + +#define TO_8_UNORM(f) ((unsigned char) (f * 255.0f)) +#define TO_16_UNORM(f) ((unsigned short) (f * 65535.0f)) +#define TO_32_UNORM(f) ((unsigned int) (f * 4294967295.0f)) + +#define TO_8_SNORM(f) ((char) (f * 127.0f)) +#define TO_16_SNORM(f) ((short) (f * 32767.0f)) +#define TO_32_SNORM(f) ((int) (f * 2147483647.0f)) + + + +ATTRIB( R64G64B64A64_FLOAT, 4, double, FROM_64_FLOAT, TO_64_FLOAT ) +ATTRIB( R64G64B64_FLOAT, 3, double, FROM_64_FLOAT, TO_64_FLOAT ) +ATTRIB( R64G64_FLOAT, 2, double, FROM_64_FLOAT, TO_64_FLOAT ) +ATTRIB( R64_FLOAT, 1, double, FROM_64_FLOAT, TO_64_FLOAT ) + +ATTRIB( R32G32B32A32_FLOAT, 4, float, FROM_32_FLOAT, TO_32_FLOAT ) +ATTRIB( R32G32B32_FLOAT, 3, float, FROM_32_FLOAT, TO_32_FLOAT ) +ATTRIB( R32G32_FLOAT, 2, float, FROM_32_FLOAT, TO_32_FLOAT ) +ATTRIB( R32_FLOAT, 1, float, FROM_32_FLOAT, TO_32_FLOAT ) + +ATTRIB( R32G32B32A32_USCALED, 4, unsigned, FROM_32_USCALED, TO_32_USCALED ) +ATTRIB( R32G32B32_USCALED, 3, unsigned, FROM_32_USCALED, TO_32_USCALED ) +ATTRIB( R32G32_USCALED, 2, unsigned, FROM_32_USCALED, TO_32_USCALED ) +ATTRIB( R32_USCALED, 1, unsigned, FROM_32_USCALED, TO_32_USCALED ) + +ATTRIB( R32G32B32A32_SSCALED, 4, int, FROM_32_SSCALED, TO_32_SSCALED ) +ATTRIB( R32G32B32_SSCALED, 3, int, FROM_32_SSCALED, TO_32_SSCALED ) +ATTRIB( R32G32_SSCALED, 2, int, FROM_32_SSCALED, TO_32_SSCALED ) +ATTRIB( R32_SSCALED, 1, int, FROM_32_SSCALED, TO_32_SSCALED ) + +ATTRIB( R32G32B32A32_UNORM, 4, unsigned, FROM_32_UNORM, TO_32_UNORM ) +ATTRIB( R32G32B32_UNORM, 3, unsigned, FROM_32_UNORM, TO_32_UNORM ) +ATTRIB( R32G32_UNORM, 2, unsigned, FROM_32_UNORM, TO_32_UNORM ) +ATTRIB( R32_UNORM, 1, unsigned, FROM_32_UNORM, TO_32_UNORM ) + +ATTRIB( R32G32B32A32_SNORM, 4, int, FROM_32_SNORM, TO_32_SNORM ) +ATTRIB( R32G32B32_SNORM, 3, int, FROM_32_SNORM, TO_32_SNORM ) +ATTRIB( R32G32_SNORM, 2, int, FROM_32_SNORM, TO_32_SNORM ) +ATTRIB( R32_SNORM, 1, int, FROM_32_SNORM, TO_32_SNORM ) + +ATTRIB( R16G16B16A16_USCALED, 4, ushort, FROM_16_USCALED, TO_16_USCALED ) +ATTRIB( R16G16B16_USCALED, 3, ushort, FROM_16_USCALED, TO_16_USCALED ) +ATTRIB( R16G16_USCALED, 2, ushort, FROM_16_USCALED, TO_16_USCALED ) +ATTRIB( R16_USCALED, 1, ushort, FROM_16_USCALED, TO_16_USCALED ) + +ATTRIB( R16G16B16A16_SSCALED, 4, short, FROM_16_SSCALED, TO_16_SSCALED ) +ATTRIB( R16G16B16_SSCALED, 3, short, FROM_16_SSCALED, TO_16_SSCALED ) +ATTRIB( R16G16_SSCALED, 2, short, FROM_16_SSCALED, TO_16_SSCALED ) +ATTRIB( R16_SSCALED, 1, short, FROM_16_SSCALED, TO_16_SSCALED ) + +ATTRIB( R16G16B16A16_UNORM, 4, ushort, FROM_16_UNORM, TO_16_UNORM ) +ATTRIB( R16G16B16_UNORM, 3, ushort, FROM_16_UNORM, TO_16_UNORM ) +ATTRIB( R16G16_UNORM, 2, ushort, FROM_16_UNORM, TO_16_UNORM ) +ATTRIB( R16_UNORM, 1, ushort, FROM_16_UNORM, TO_16_UNORM ) + +ATTRIB( R16G16B16A16_SNORM, 4, short, FROM_16_SNORM, TO_16_SNORM ) +ATTRIB( R16G16B16_SNORM, 3, short, FROM_16_SNORM, TO_16_SNORM ) +ATTRIB( R16G16_SNORM, 2, short, FROM_16_SNORM, TO_16_SNORM ) +ATTRIB( R16_SNORM, 1, short, FROM_16_SNORM, TO_16_SNORM ) + +ATTRIB( R8G8B8A8_USCALED, 4, ubyte, FROM_8_USCALED, TO_8_USCALED ) +ATTRIB( R8G8B8_USCALED, 3, ubyte, FROM_8_USCALED, TO_8_USCALED ) +ATTRIB( R8G8_USCALED, 2, ubyte, FROM_8_USCALED, TO_8_USCALED ) +ATTRIB( R8_USCALED, 1, ubyte, FROM_8_USCALED, TO_8_USCALED ) + +ATTRIB( R8G8B8A8_SSCALED, 4, char, FROM_8_SSCALED, TO_8_SSCALED ) +ATTRIB( R8G8B8_SSCALED, 3, char, FROM_8_SSCALED, TO_8_SSCALED ) +ATTRIB( R8G8_SSCALED, 2, char, FROM_8_SSCALED, TO_8_SSCALED ) +ATTRIB( R8_SSCALED, 1, char, FROM_8_SSCALED, TO_8_SSCALED ) + +ATTRIB( R8G8B8A8_UNORM, 4, ubyte, FROM_8_UNORM, TO_8_UNORM ) +ATTRIB( R8G8B8_UNORM, 3, ubyte, FROM_8_UNORM, TO_8_UNORM ) +ATTRIB( R8G8_UNORM, 2, ubyte, FROM_8_UNORM, TO_8_UNORM ) +ATTRIB( R8_UNORM, 1, ubyte, FROM_8_UNORM, TO_8_UNORM ) + +ATTRIB( R8G8B8A8_SNORM, 4, char, FROM_8_SNORM, TO_8_SNORM ) +ATTRIB( R8G8B8_SNORM, 3, char, FROM_8_SNORM, TO_8_SNORM ) +ATTRIB( R8G8_SNORM, 2, char, FROM_8_SNORM, TO_8_SNORM ) +ATTRIB( R8_SNORM, 1, char, FROM_8_SNORM, TO_8_SNORM ) + +ATTRIB( A8R8G8B8_UNORM, 4, ubyte, FROM_8_UNORM, TO_8_UNORM ) +//ATTRIB( R8G8B8A8_UNORM, 4, ubyte, FROM_8_UNORM, TO_8_UNORM ) + + + +static void +fetch_B8G8R8A8_UNORM(const void *ptr, float *attrib) +{ + attrib[2] = FROM_8_UNORM(0); + attrib[1] = FROM_8_UNORM(1); + attrib[0] = FROM_8_UNORM(2); + attrib[3] = FROM_8_UNORM(3); +} + +static void +emit_B8G8R8A8_UNORM( const float *attrib, void *ptr) +{ + ubyte *out = (ubyte *)ptr; + out[2] = TO_8_UNORM(out[0]); + out[1] = TO_8_UNORM(out[1]); + out[0] = TO_8_UNORM(out[2]); + out[3] = TO_8_UNORM(out[3]); +} + +static void +fetch_NULL( const void *ptr, float *attrib ) +{ + attrib[0] = 0; + attrib[1] = 0; + attrib[2] = 0; + attrib[3] = 1; +} + +static void +emit_NULL( const float *attrib, void *ptr ) +{ + /* do nothing is the only sensible option */ +} + +static fetch_func get_fetch_func( enum pipe_format format ) +{ + switch (format) { + case PIPE_FORMAT_R64_FLOAT: + return fetch_R64_FLOAT; + case PIPE_FORMAT_R64G64_FLOAT: + return fetch_R64G64_FLOAT; + case PIPE_FORMAT_R64G64B64_FLOAT: + return fetch_R64G64B64_FLOAT; + case PIPE_FORMAT_R64G64B64A64_FLOAT: + return fetch_R64G64B64A64_FLOAT; + + case PIPE_FORMAT_R32_FLOAT: + return fetch_R32_FLOAT; + case PIPE_FORMAT_R32G32_FLOAT: + return fetch_R32G32_FLOAT; + case PIPE_FORMAT_R32G32B32_FLOAT: + return fetch_R32G32B32_FLOAT; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return fetch_R32G32B32A32_FLOAT; + + case PIPE_FORMAT_R32_UNORM: + return fetch_R32_UNORM; + case PIPE_FORMAT_R32G32_UNORM: + return fetch_R32G32_UNORM; + case PIPE_FORMAT_R32G32B32_UNORM: + return fetch_R32G32B32_UNORM; + case PIPE_FORMAT_R32G32B32A32_UNORM: + return fetch_R32G32B32A32_UNORM; + + case PIPE_FORMAT_R32_USCALED: + return fetch_R32_USCALED; + case PIPE_FORMAT_R32G32_USCALED: + return fetch_R32G32_USCALED; + case PIPE_FORMAT_R32G32B32_USCALED: + return fetch_R32G32B32_USCALED; + case PIPE_FORMAT_R32G32B32A32_USCALED: + return fetch_R32G32B32A32_USCALED; + + case PIPE_FORMAT_R32_SNORM: + return fetch_R32_SNORM; + case PIPE_FORMAT_R32G32_SNORM: + return fetch_R32G32_SNORM; + case PIPE_FORMAT_R32G32B32_SNORM: + return fetch_R32G32B32_SNORM; + case PIPE_FORMAT_R32G32B32A32_SNORM: + return fetch_R32G32B32A32_SNORM; + + case PIPE_FORMAT_R32_SSCALED: + return fetch_R32_SSCALED; + case PIPE_FORMAT_R32G32_SSCALED: + return fetch_R32G32_SSCALED; + case PIPE_FORMAT_R32G32B32_SSCALED: + return fetch_R32G32B32_SSCALED; + case PIPE_FORMAT_R32G32B32A32_SSCALED: + return fetch_R32G32B32A32_SSCALED; + + case PIPE_FORMAT_R16_UNORM: + return fetch_R16_UNORM; + case PIPE_FORMAT_R16G16_UNORM: + return fetch_R16G16_UNORM; + case PIPE_FORMAT_R16G16B16_UNORM: + return fetch_R16G16B16_UNORM; + case PIPE_FORMAT_R16G16B16A16_UNORM: + return fetch_R16G16B16A16_UNORM; + + case PIPE_FORMAT_R16_USCALED: + return fetch_R16_USCALED; + case PIPE_FORMAT_R16G16_USCALED: + return fetch_R16G16_USCALED; + case PIPE_FORMAT_R16G16B16_USCALED: + return fetch_R16G16B16_USCALED; + case PIPE_FORMAT_R16G16B16A16_USCALED: + return fetch_R16G16B16A16_USCALED; + + case PIPE_FORMAT_R16_SNORM: + return fetch_R16_SNORM; + case PIPE_FORMAT_R16G16_SNORM: + return fetch_R16G16_SNORM; + case PIPE_FORMAT_R16G16B16_SNORM: + return fetch_R16G16B16_SNORM; + case PIPE_FORMAT_R16G16B16A16_SNORM: + return fetch_R16G16B16A16_SNORM; + + case PIPE_FORMAT_R16_SSCALED: + return fetch_R16_SSCALED; + case PIPE_FORMAT_R16G16_SSCALED: + return fetch_R16G16_SSCALED; + case PIPE_FORMAT_R16G16B16_SSCALED: + return fetch_R16G16B16_SSCALED; + case PIPE_FORMAT_R16G16B16A16_SSCALED: + return fetch_R16G16B16A16_SSCALED; + + case PIPE_FORMAT_R8_UNORM: + return fetch_R8_UNORM; + case PIPE_FORMAT_R8G8_UNORM: + return fetch_R8G8_UNORM; + case PIPE_FORMAT_R8G8B8_UNORM: + return fetch_R8G8B8_UNORM; + case PIPE_FORMAT_R8G8B8A8_UNORM: + return fetch_R8G8B8A8_UNORM; + + case PIPE_FORMAT_R8_USCALED: + return fetch_R8_USCALED; + case PIPE_FORMAT_R8G8_USCALED: + return fetch_R8G8_USCALED; + case PIPE_FORMAT_R8G8B8_USCALED: + return fetch_R8G8B8_USCALED; + case PIPE_FORMAT_R8G8B8A8_USCALED: + return fetch_R8G8B8A8_USCALED; + + case PIPE_FORMAT_R8_SNORM: + return fetch_R8_SNORM; + case PIPE_FORMAT_R8G8_SNORM: + return fetch_R8G8_SNORM; + case PIPE_FORMAT_R8G8B8_SNORM: + return fetch_R8G8B8_SNORM; + case PIPE_FORMAT_R8G8B8A8_SNORM: + return fetch_R8G8B8A8_SNORM; + + case PIPE_FORMAT_R8_SSCALED: + return fetch_R8_SSCALED; + case PIPE_FORMAT_R8G8_SSCALED: + return fetch_R8G8_SSCALED; + case PIPE_FORMAT_R8G8B8_SSCALED: + return fetch_R8G8B8_SSCALED; + case PIPE_FORMAT_R8G8B8A8_SSCALED: + return fetch_R8G8B8A8_SSCALED; + + case PIPE_FORMAT_A8R8G8B8_UNORM: + return fetch_A8R8G8B8_UNORM; + + case PIPE_FORMAT_B8G8R8A8_UNORM: + return fetch_B8G8R8A8_UNORM; + + default: + assert(0); + return fetch_NULL; + } +} + + + + +static emit_func get_emit_func( enum pipe_format format ) +{ + switch (format) { + case PIPE_FORMAT_R64_FLOAT: + return emit_R64_FLOAT; + case PIPE_FORMAT_R64G64_FLOAT: + return emit_R64G64_FLOAT; + case PIPE_FORMAT_R64G64B64_FLOAT: + return emit_R64G64B64_FLOAT; + case PIPE_FORMAT_R64G64B64A64_FLOAT: + return emit_R64G64B64A64_FLOAT; + + case PIPE_FORMAT_R32_FLOAT: + return emit_R32_FLOAT; + case PIPE_FORMAT_R32G32_FLOAT: + return emit_R32G32_FLOAT; + case PIPE_FORMAT_R32G32B32_FLOAT: + return emit_R32G32B32_FLOAT; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return emit_R32G32B32A32_FLOAT; + + case PIPE_FORMAT_R32_UNORM: + return emit_R32_UNORM; + case PIPE_FORMAT_R32G32_UNORM: + return emit_R32G32_UNORM; + case PIPE_FORMAT_R32G32B32_UNORM: + return emit_R32G32B32_UNORM; + case PIPE_FORMAT_R32G32B32A32_UNORM: + return emit_R32G32B32A32_UNORM; + + case PIPE_FORMAT_R32_USCALED: + return emit_R32_USCALED; + case PIPE_FORMAT_R32G32_USCALED: + return emit_R32G32_USCALED; + case PIPE_FORMAT_R32G32B32_USCALED: + return emit_R32G32B32_USCALED; + case PIPE_FORMAT_R32G32B32A32_USCALED: + return emit_R32G32B32A32_USCALED; + + case PIPE_FORMAT_R32_SNORM: + return emit_R32_SNORM; + case PIPE_FORMAT_R32G32_SNORM: + return emit_R32G32_SNORM; + case PIPE_FORMAT_R32G32B32_SNORM: + return emit_R32G32B32_SNORM; + case PIPE_FORMAT_R32G32B32A32_SNORM: + return emit_R32G32B32A32_SNORM; + + case PIPE_FORMAT_R32_SSCALED: + return emit_R32_SSCALED; + case PIPE_FORMAT_R32G32_SSCALED: + return emit_R32G32_SSCALED; + case PIPE_FORMAT_R32G32B32_SSCALED: + return emit_R32G32B32_SSCALED; + case PIPE_FORMAT_R32G32B32A32_SSCALED: + return emit_R32G32B32A32_SSCALED; + + case PIPE_FORMAT_R16_UNORM: + return emit_R16_UNORM; + case PIPE_FORMAT_R16G16_UNORM: + return emit_R16G16_UNORM; + case PIPE_FORMAT_R16G16B16_UNORM: + return emit_R16G16B16_UNORM; + case PIPE_FORMAT_R16G16B16A16_UNORM: + return emit_R16G16B16A16_UNORM; + + case PIPE_FORMAT_R16_USCALED: + return emit_R16_USCALED; + case PIPE_FORMAT_R16G16_USCALED: + return emit_R16G16_USCALED; + case PIPE_FORMAT_R16G16B16_USCALED: + return emit_R16G16B16_USCALED; + case PIPE_FORMAT_R16G16B16A16_USCALED: + return emit_R16G16B16A16_USCALED; + + case PIPE_FORMAT_R16_SNORM: + return emit_R16_SNORM; + case PIPE_FORMAT_R16G16_SNORM: + return emit_R16G16_SNORM; + case PIPE_FORMAT_R16G16B16_SNORM: + return emit_R16G16B16_SNORM; + case PIPE_FORMAT_R16G16B16A16_SNORM: + return emit_R16G16B16A16_SNORM; + + case PIPE_FORMAT_R16_SSCALED: + return emit_R16_SSCALED; + case PIPE_FORMAT_R16G16_SSCALED: + return emit_R16G16_SSCALED; + case PIPE_FORMAT_R16G16B16_SSCALED: + return emit_R16G16B16_SSCALED; + case PIPE_FORMAT_R16G16B16A16_SSCALED: + return emit_R16G16B16A16_SSCALED; + + case PIPE_FORMAT_R8_UNORM: + return emit_R8_UNORM; + case PIPE_FORMAT_R8G8_UNORM: + return emit_R8G8_UNORM; + case PIPE_FORMAT_R8G8B8_UNORM: + return emit_R8G8B8_UNORM; + case PIPE_FORMAT_R8G8B8A8_UNORM: + return emit_R8G8B8A8_UNORM; + + case PIPE_FORMAT_R8_USCALED: + return emit_R8_USCALED; + case PIPE_FORMAT_R8G8_USCALED: + return emit_R8G8_USCALED; + case PIPE_FORMAT_R8G8B8_USCALED: + return emit_R8G8B8_USCALED; + case PIPE_FORMAT_R8G8B8A8_USCALED: + return emit_R8G8B8A8_USCALED; + + case PIPE_FORMAT_R8_SNORM: + return emit_R8_SNORM; + case PIPE_FORMAT_R8G8_SNORM: + return emit_R8G8_SNORM; + case PIPE_FORMAT_R8G8B8_SNORM: + return emit_R8G8B8_SNORM; + case PIPE_FORMAT_R8G8B8A8_SNORM: + return emit_R8G8B8A8_SNORM; + + case PIPE_FORMAT_R8_SSCALED: + return emit_R8_SSCALED; + case PIPE_FORMAT_R8G8_SSCALED: + return emit_R8G8_SSCALED; + case PIPE_FORMAT_R8G8B8_SSCALED: + return emit_R8G8B8_SSCALED; + case PIPE_FORMAT_R8G8B8A8_SSCALED: + return emit_R8G8B8A8_SSCALED; + + case PIPE_FORMAT_A8R8G8B8_UNORM: + return emit_A8R8G8B8_UNORM; + + case PIPE_FORMAT_B8G8R8A8_UNORM: + return emit_B8G8R8A8_UNORM; + + default: + assert(0); + return emit_NULL; + } +} + + + +/** + * Fetch vertex attributes for 'count' vertices. + */ +static void generic_run_elts( struct translate *translate, + const unsigned *elts, + unsigned count, + void *output_buffer ) +{ + struct translate_generic *tg = translate_generic(translate); + char *vert = output_buffer; + unsigned nr_attrs = tg->nr_attrib; + unsigned attr; + unsigned i; + + /* loop over vertex attributes (vertex shader inputs) + */ + for (i = 0; i < count; i++) { + unsigned elt = *elts++; + + for (attr = 0; attr < nr_attrs; attr++) { + float data[4]; + + const char *src = (tg->attrib[attr].input_ptr + + tg->attrib[attr].input_stride * elt); + + char *dst = (vert + + tg->attrib[attr].output_offset); + + tg->attrib[attr].fetch( src, data ); + tg->attrib[attr].emit( data, dst ); + } + + vert += tg->output_stride; + } +} + + + +static void generic_set_buffer( struct translate *translate, + unsigned buf, + const void *ptr, + unsigned stride ) +{ + struct translate_generic *tg = translate_generic(translate); + unsigned i; + + for (i = 0; i < tg->nr_attrib; i++) { + if (tg->attrib[i].buffer == buf) { + tg->attrib[i].input_ptr = ((char *)ptr + + tg->attrib[i].input_offset); + tg->attrib[i].input_stride = stride; + } + } +} + + +static void generic_destroy( struct translate *translate ) +{ + FREE(translate); +} + +struct translate *translate_generic_create( unsigned output_stride, + const struct translate_element *elements, + unsigned nr_elements ) +{ + struct translate_generic *tg = CALLOC_STRUCT(translate_generic); + unsigned i; + + if (tg == NULL) + return NULL; + + tg->translate.destroy = generic_destroy; + tg->translate.set_buffer = generic_set_buffer; + tg->translate.run_elts = generic_run_elts; + + for (i = 0; i < nr_elements; i++) { + tg->attrib[i].fetch = get_fetch_func(elements[i].input_format); + tg->attrib[i].buffer = elements[i].input_buffer; + tg->attrib[i].input_offset = elements[i].input_offset; + + tg->attrib[i].emit = get_emit_func(elements[i].output_format); + tg->attrib[i].output_offset = elements[i].output_offset; + } + + tg->nr_attrib = nr_elements; + + + return &tg->translate; +} -- cgit v1.2.3 From 59f68f36c4ad37496e3ed5d7d3142e3ae35dd351 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 14:40:16 +0100 Subject: translate: typo in emit_B8G8R8A8_UNORM --- src/gallium/auxiliary/translate/translate_generic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 643f6430c5..7e75ba8365 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -231,10 +231,10 @@ static void emit_B8G8R8A8_UNORM( const float *attrib, void *ptr) { ubyte *out = (ubyte *)ptr; - out[2] = TO_8_UNORM(out[0]); - out[1] = TO_8_UNORM(out[1]); - out[0] = TO_8_UNORM(out[2]); - out[3] = TO_8_UNORM(out[3]); + out[2] = TO_8_UNORM(attrib[0]); + out[1] = TO_8_UNORM(attrib[1]); + out[0] = TO_8_UNORM(attrib[2]); + out[3] = TO_8_UNORM(attrib[3]); } static void -- cgit v1.2.3 From 7eb6f130a1dfb8179ff371eb4e75b47d6ee45d2a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 14:44:39 +0100 Subject: draw: fix first glitch in vertex emit --- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 557cd43f5b..889cab700c 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -92,6 +92,16 @@ static void emit_R32G32B32A32_FLOAT( const float *attrib, out[3] = attrib[3]; } +static void +emit_B8G8R8A8_UNORM( const float *attrib, void *ptr) +{ + ubyte *out = (ubyte *)ptr; + out[2] = float_to_ubyte(attrib[0]); + out[1] = float_to_ubyte(attrib[1]); + out[0] = float_to_ubyte(attrib[2]); + out[3] = float_to_ubyte(attrib[3]); +} + static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned prim ) { @@ -150,6 +160,9 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, src_buffer = 1; src_offset = 0; break; + case EMIT_4UB: + fpme->translate[i].emit = emit_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); default: assert(0); fpme->translate[i].emit = emit_NULL; @@ -232,10 +245,10 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, for (j = 0; j < fpme->nr_translate; j++) { - const float *attrib = (const float *)( (*fpme->translate[i].input_buf) + - fpme->translate[i].input_offset ); + const float *attrib = (const float *)( (*fpme->translate[j].input_buf) + + fpme->translate[j].input_offset ); - char *dest = out_buf + fpme->translate[i].output_offset; + char *dest = out_buf + fpme->translate[j].output_offset; /*debug_printf("emiting [%f, %f, %f, %f]\n", attrib[0], attrib[1], -- cgit v1.2.3 From 8cac6f3fcf9d6c08959efc20f8fce9eddbdcd0ef Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 14:52:56 +0100 Subject: draw: increment output vertex properly --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 889cab700c..75bbcc8d41 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -250,14 +250,16 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, char *dest = out_buf + fpme->translate[j].output_offset; - /*debug_printf("emiting [%f, %f, %f, %f]\n", - attrib[0], attrib[1], - attrib[2], attrib[3]);*/ + if (0) + debug_printf("emiting [%f, %f, %f, %f]\n", + attrib[0], attrib[1], + attrib[2], attrib[3]); fpme->translate[j].emit(attrib, dest); } fpme->input_buf[0] += fpme->pipeline_vertex_size; + out_buf += fpme->hw_vertex_size; } draw->render->draw(draw->render, -- cgit v1.2.3 From a5a7dc24ba2dcf9bbdd73709c4c182e324bdc3a5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 19:14:31 +0100 Subject: gallium: Switch one vertex path over to new translate module Will eventually do this for all instances where we are converting vertices from one format to another. --- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 146 +++++++-------------- src/gallium/auxiliary/translate/translate.h | 36 ++++- .../auxiliary/translate/translate_generic.c | 66 ++++++++-- 3 files changed, 128 insertions(+), 120 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 75bbcc8d41..2d83e11940 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -31,77 +31,20 @@ #include "draw/draw_vbuf.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" +#include "translate/translate.h" + struct fetch_pipeline_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; - const ubyte *input_buf[2]; - - struct { - const ubyte **input_buf; - unsigned input_offset; - unsigned output_offset; - - void (*emit)( const float *attrib, void *ptr ); - } translate[PIPE_MAX_ATTRIBS]; - unsigned nr_translate; + struct translate *translate; unsigned pipeline_vertex_size; - unsigned hw_vertex_size; unsigned prim; }; -static void emit_NULL( const float *attrib, - void *ptr ) -{ -} - -static void emit_R32_FLOAT( const float *attrib, - void *ptr ) -{ - float *out = (float *)ptr; - out[0] = attrib[0]; -} - -static void emit_R32G32_FLOAT( const float *attrib, - void *ptr ) -{ - float *out = (float *)ptr; - out[0] = attrib[0]; - out[1] = attrib[1]; -} - -static void emit_R32G32B32_FLOAT( const float *attrib, - void *ptr ) -{ - float *out = (float *)ptr; - out[0] = attrib[0]; - out[1] = attrib[1]; - out[2] = attrib[2]; -} - -static void emit_R32G32B32A32_FLOAT( const float *attrib, - void *ptr ) -{ - float *out = (float *)ptr; - out[0] = attrib[0]; - out[1] = attrib[1]; - out[2] = attrib[2]; - out[3] = attrib[3]; -} - -static void -emit_B8G8R8A8_UNORM( const float *attrib, void *ptr) -{ - ubyte *out = (ubyte *)ptr; - out[2] = float_to_ubyte(attrib[0]); - out[1] = float_to_ubyte(attrib[1]); - out[0] = float_to_ubyte(attrib[2]); - out[3] = float_to_ubyte(attrib[3]); -} - static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned prim ) { @@ -111,6 +54,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, boolean ok; const struct vertex_info *vinfo; unsigned dst_offset; + struct translate_key hw_key; fpme->prim = prim; @@ -132,6 +76,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, for (i = 0; i < vinfo->num_attribs; i++) { unsigned emit_sz = 0; unsigned src_buffer = 0; + unsigned output_format; unsigned src_offset = (sizeof(struct vertex_header) + vinfo->src_index[i] * 4 * sizeof(float) ); @@ -139,49 +84,64 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, switch (vinfo->emit[i]) { case EMIT_4F: - fpme->translate[i].emit = emit_R32G32B32A32_FLOAT; + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; emit_sz = 4 * sizeof(float); break; case EMIT_3F: - fpme->translate[i].emit = emit_R32G32B32_FLOAT; + output_format = PIPE_FORMAT_R32G32B32_FLOAT; emit_sz = 3 * sizeof(float); break; case EMIT_2F: - fpme->translate[i].emit = emit_R32G32_FLOAT; + output_format = PIPE_FORMAT_R32G32_FLOAT; emit_sz = 2 * sizeof(float); break; case EMIT_1F: - fpme->translate[i].emit = emit_R32_FLOAT; + output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); break; case EMIT_1F_PSIZE: - fpme->translate[i].emit = emit_R32_FLOAT; + output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); src_buffer = 1; src_offset = 0; break; case EMIT_4UB: - fpme->translate[i].emit = emit_B8G8R8A8_UNORM; + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; emit_sz = 4 * sizeof(ubyte); default: assert(0); - fpme->translate[i].emit = emit_NULL; + output_format = PIPE_FORMAT_NONE; emit_sz = 0; break; } + + hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + hw_key.element[i].input_buffer = src_buffer; + hw_key.element[i].input_offset = src_offset; + hw_key.element[i].output_format = output_format; + hw_key.element[i].output_offset = dst_offset; - fpme->translate[i].input_buf = &fpme->input_buf[src_buffer]; - fpme->translate[i].input_offset = src_offset; - fpme->translate[i].output_offset = dst_offset; dst_offset += emit_sz; } - fpme->nr_translate = vinfo->num_attribs; - fpme->hw_vertex_size = vinfo->size * 4; + hw_key.nr_elements = vinfo->num_attribs; + hw_key.output_stride = vinfo->size * 4; + + /* Don't bother with caching at this stage: + */ + if (!fpme->translate || + memcmp(&fpme->translate->key, &hw_key, sizeof(hw_key)) != 0) + { + if (fpme->translate) + fpme->translate->release(fpme->translate); + + fpme->translate = translate_generic_create( &hw_key ); + } + + //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; - fpme->hw_vertex_size = vinfo->size * 4; } @@ -221,46 +181,34 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, draw_elts, draw_count ); } else { - unsigned i, j; + struct translate *translate = fpme->translate; void *hw_verts; - char *out_buf; /* XXX: need to flush to get prim_vbuf.c to release its allocation?? */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); hw_verts = draw->render->allocate_vertices(draw->render, - (ushort)fpme->hw_vertex_size, + (ushort)fpme->translate->key.output_stride, (ushort)fetch_count); if (!hw_verts) { assert(0); return; } - out_buf = (char *)hw_verts; - fpme->input_buf[0] = (const ubyte *)pipeline_verts; - fpme->input_buf[1] = (const ubyte *)&fpme->draw->rasterizer->point_size; - - for (i = 0; i < fetch_count; i++) { - - for (j = 0; j < fpme->nr_translate; j++) { + translate->set_buffer(translate, + 0, + pipeline_verts, + fpme->pipeline_vertex_size ); - const float *attrib = (const float *)( (*fpme->translate[j].input_buf) + - fpme->translate[j].input_offset ); + translate->set_buffer(translate, + 1, + &fpme->draw->rasterizer->point_size, + 0); - char *dest = out_buf + fpme->translate[j].output_offset; - - if (0) - debug_printf("emiting [%f, %f, %f, %f]\n", - attrib[0], attrib[1], - attrib[2], attrib[3]); - - fpme->translate[j].emit(attrib, dest); - } - - fpme->input_buf[0] += fpme->pipeline_vertex_size; - out_buf += fpme->hw_vertex_size; - } + translate->run( translate, + 0, fetch_count, + hw_verts ); draw->render->draw(draw->render, draw_elts, @@ -268,7 +216,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, draw->render->release_vertices(draw->render, hw_verts, - fpme->hw_vertex_size, + fpme->translate->key.output_stride, fetch_count); } diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index ac6bc7088b..4f9f40e51a 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -54,8 +54,17 @@ struct translate_element }; +struct translate_key { + unsigned output_stride; + unsigned nr_elements; + struct translate_element element[PIPE_MAX_ATTRIBS]; +}; + + struct translate { - void (*destroy)( struct translate * ); + struct translate_key key; + + void (*release)( struct translate * ); void (*set_buffer)( struct translate *, unsigned i, @@ -66,17 +75,30 @@ struct translate { const unsigned *elts, unsigned count, void *output_buffer); + + void (*run)( struct translate *, + unsigned start, + unsigned count, + void *output_buffer); }; -struct translate *translate_sse2_create( unsigned output_stride, - const struct translate_element *elements, - unsigned nr_elements ); +#if 0 +struct translate_context *translate_context_create( void ); +void translate_context_destroy( struct translate_context * ); + +struct translate *translate_lookup_or_create( struct translate_context *tctx, + const struct translate_key *key ); +#endif + + +/******************************************************************************* + * Private: + */ +struct translate *translate_sse2_create( const struct translate_key *key ); -struct translate *translate_generic_create( unsigned output_stride, - const struct translate_element *elements, - unsigned nr_elements ); +struct translate *translate_generic_create( const struct translate_key *key ); #endif diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 7e75ba8365..fc9060900b 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -59,7 +59,6 @@ struct translate_generic { } attrib[PIPE_MAX_ATTRIBS]; unsigned nr_attrib; - unsigned output_stride; }; @@ -571,7 +570,42 @@ static void generic_run_elts( struct translate *translate, tg->attrib[attr].emit( data, dst ); } - vert += tg->output_stride; + vert += tg->translate.key.output_stride; + } +} + + + +static void generic_run( struct translate *translate, + unsigned start, + unsigned count, + void *output_buffer ) +{ + struct translate_generic *tg = translate_generic(translate); + char *vert = output_buffer; + unsigned nr_attrs = tg->nr_attrib; + unsigned attr; + unsigned i; + + /* loop over vertex attributes (vertex shader inputs) + */ + for (i = 0; i < count; i++) { + unsigned elt = start + i; + + for (attr = 0; attr < nr_attrs; attr++) { + float data[4]; + + const char *src = (tg->attrib[attr].input_ptr + + tg->attrib[attr].input_stride * elt); + + char *dst = (vert + + tg->attrib[attr].output_offset); + + tg->attrib[attr].fetch( src, data ); + tg->attrib[attr].emit( data, dst ); + } + + vert += tg->translate.key.output_stride; } } @@ -595,14 +629,14 @@ static void generic_set_buffer( struct translate *translate, } -static void generic_destroy( struct translate *translate ) +static void generic_release( struct translate *translate ) { + /* Refcount? + */ FREE(translate); } -struct translate *translate_generic_create( unsigned output_stride, - const struct translate_element *elements, - unsigned nr_elements ) +struct translate *translate_generic_create( const struct translate_key *key ) { struct translate_generic *tg = CALLOC_STRUCT(translate_generic); unsigned i; @@ -610,20 +644,24 @@ struct translate *translate_generic_create( unsigned output_stride, if (tg == NULL) return NULL; - tg->translate.destroy = generic_destroy; + tg->translate.key = *key; + tg->translate.release = generic_release; tg->translate.set_buffer = generic_set_buffer; tg->translate.run_elts = generic_run_elts; + tg->translate.run = generic_run; + + for (i = 0; i < key->nr_elements; i++) { + + tg->attrib[i].fetch = get_fetch_func(key->element[i].input_format); + tg->attrib[i].buffer = key->element[i].input_buffer; + tg->attrib[i].input_offset = key->element[i].input_offset; - for (i = 0; i < nr_elements; i++) { - tg->attrib[i].fetch = get_fetch_func(elements[i].input_format); - tg->attrib[i].buffer = elements[i].input_buffer; - tg->attrib[i].input_offset = elements[i].input_offset; + tg->attrib[i].emit = get_emit_func(key->element[i].output_format); + tg->attrib[i].output_offset = key->element[i].output_offset; - tg->attrib[i].emit = get_emit_func(elements[i].output_format); - tg->attrib[i].output_offset = elements[i].output_offset; } - tg->nr_attrib = nr_elements; + tg->nr_attrib = key->nr_elements; return &tg->translate; -- cgit v1.2.3 From e2269e94c0ecaa97c7153815489e59c9ca64c243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 16 Apr 2008 11:39:22 +0900 Subject: gallium: Build and link the translate module. --- src/gallium/SConscript | 1 + src/gallium/auxiliary/translate/SConscript | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/SConscript b/src/gallium/SConscript index f09778ce99..2653f91bd2 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -18,6 +18,7 @@ SConscript([ 'auxiliary/rtasm/SConscript', 'auxiliary/tgsi/SConscript', 'auxiliary/cso_cache/SConscript', + 'auxiliary/translate/SConscript', 'auxiliary/draw/SConscript', 'auxiliary/pipebuffer/SConscript', ]) diff --git a/src/gallium/auxiliary/translate/SConscript b/src/gallium/auxiliary/translate/SConscript index 947b9438cb..42513ba3b0 100644 --- a/src/gallium/auxiliary/translate/SConscript +++ b/src/gallium/auxiliary/translate/SConscript @@ -1,6 +1,6 @@ Import('*') -cso_cache = env.ConvenienceLibrary( +translate = env.ConvenienceLibrary( target = 'translate', source = [ 'translate_generic.c', -- cgit v1.2.3 From fd6acabd2f62fe006b078ae7640a944c7f65903c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 16 Apr 2008 11:42:08 +0900 Subject: gallium: Get the translate module to build on msvc. Appearently MSVC c-preprocessor parses "255.0f" as two tokens: "255.0" and "f", and performs variable substitution on "f". --- .../auxiliary/translate/translate_generic.c | 32 +++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index fc9060900b..e7fb1dcb2d 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -78,8 +78,8 @@ static struct translate_generic *translate_generic( struct translate *translate static void \ fetch_##NAME(const void *ptr, float *attrib) \ { \ - const float defaults[4] = { 0,0,0,1 }; \ - int i; \ + const float defaults[4] = { 0.0f,0.0f,0.0f,1.0f }; \ + unsigned i; \ \ for (i = 0; i < SZ; i++) { \ attrib[i] = FROM(i); \ @@ -121,24 +121,24 @@ emit_##NAME(const float *attrib, void *ptr) \ #define FROM_16_SNORM(i) ((float) ((short *) ptr)[i] / 32767.0f) #define FROM_32_SNORM(i) ((float) ((int *) ptr)[i] / 2147483647.0f) -#define TO_64_FLOAT(f) ((double) f) -#define TO_32_FLOAT(f) (f) +#define TO_64_FLOAT(x) ((double) x) +#define TO_32_FLOAT(x) (x) -#define TO_8_USCALED(f) ((unsigned char) f) -#define TO_16_USCALED(f) ((unsigned short) f) -#define TO_32_USCALED(f) ((unsigned int) f) +#define TO_8_USCALED(x) ((unsigned char) x) +#define TO_16_USCALED(x) ((unsigned short) x) +#define TO_32_USCALED(x) ((unsigned int) x) -#define TO_8_SSCALED(f) ((char) f) -#define TO_16_SSCALED(f) ((short) f) -#define TO_32_SSCALED(f) ((int) f) +#define TO_8_SSCALED(x) ((char) x) +#define TO_16_SSCALED(x) ((short) x) +#define TO_32_SSCALED(x) ((int) x) -#define TO_8_UNORM(f) ((unsigned char) (f * 255.0f)) -#define TO_16_UNORM(f) ((unsigned short) (f * 65535.0f)) -#define TO_32_UNORM(f) ((unsigned int) (f * 4294967295.0f)) +#define TO_8_UNORM(x) ((unsigned char) (x * 255.0f)) +#define TO_16_UNORM(x) ((unsigned short) (x * 65535.0f)) +#define TO_32_UNORM(x) ((unsigned int) (x * 4294967295.0f)) -#define TO_8_SNORM(f) ((char) (f * 127.0f)) -#define TO_16_SNORM(f) ((short) (f * 32767.0f)) -#define TO_32_SNORM(f) ((int) (f * 2147483647.0f)) +#define TO_8_SNORM(x) ((char) (x * 127.0f)) +#define TO_16_SNORM(x) ((short) (x * 32767.0f)) +#define TO_32_SNORM(x) ((int) (x * 2147483647.0f)) -- cgit v1.2.3 From a8582efaca35d09c8ca18918a243a9284583356d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 16 Apr 2008 10:03:18 +0100 Subject: draw: make pt run pipeline when need_pipeline is true, not just when clipped --- src/gallium/auxiliary/draw/draw_private.h | 13 +- src/gallium/auxiliary/draw/draw_pt.c | 182 +++++---------------- src/gallium/auxiliary/draw/draw_pt.h | 6 +- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 3 +- .../auxiliary/draw/draw_pt_fetch_pipeline.c | 3 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 18 +- src/gallium/auxiliary/draw/draw_pt_vcache.c | 5 +- 7 files changed, 75 insertions(+), 155 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index c8cb96c8ba..8ac061cc9f 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -182,6 +182,12 @@ typedef void (*pt_fetch_func)( struct draw_context *draw, struct vbuf_render; + +#define PT_SHADE 0x1 +#define PT_CLIPTEST 0x2 +#define PT_PIPELINE 0x4 +#define PT_MAX_MIDDLE 0x8 + /** * Private context for the drawing module. */ @@ -219,15 +225,10 @@ struct draw_context unsigned hw_vertex_size; /* XXX: to be removed */ struct { - struct draw_pt_middle_end *fetch_emit; - struct draw_pt_middle_end *fetch_pipeline; - struct draw_pt_middle_end *fetch_shade_emit; - struct draw_pt_middle_end *fetch_shade_cliptest_pipeline_or_emit; + struct draw_pt_middle_end *opt[PT_MAX_MIDDLE]; } middle; struct { - struct draw_pt_front_end *noop; - struct draw_pt_front_end *split_arrays; struct draw_pt_front_end *vcache; } front; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 3d2e7bf7b8..895224c952 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -36,146 +36,58 @@ #include "draw/draw_pt.h" -#if 0 -static boolean too_many_elts( struct draw_context *draw, - unsigned elts ) -{ - return elts > (8 * 1024); -} -#endif - -static INLINE unsigned reduced_prim(unsigned prim) -{ - /*FIXME*/ - return prim; -} -static INLINE boolean good_prim(unsigned prim) -{ - /*FIXME*/ - return FALSE; -} +/* Overall we split things into: + * - frontend -- prepare fetch_elts, draw_elts - eg vcache + * - middle -- fetch, shade, cliptest, viewport + * - pipeline -- the prim pipeline: clipping, wide lines, etc + * - backend -- the vbuf_render provided by the driver. + */ boolean draw_pt_arrays(struct draw_context *draw, unsigned prim, unsigned start, unsigned count) { - const boolean pipeline = draw_need_pipeline(draw, prim); - const boolean cliptest = !draw->rasterizer->bypass_clipping; - const boolean shading = !draw->rasterizer->bypass_vs; struct draw_pt_front_end *frontend = NULL; struct draw_pt_middle_end *middle = NULL; + unsigned opt = 0; if (!draw->render) return FALSE; /*debug_printf("XXXXXXXXXX needs_pipeline = %d\n", pipeline);*/ - /* Overall we do: - * - frontend -- prepare fetch_elts, draw_elts - eg vcache - * - middle -- fetch, shade, cliptest, viewport - * - pipeline -- the prim pipeline: clipping, wide lines, etc - * - backend -- the vbuf_render provided by the driver. - */ - - if (shading && !draw->use_pt_shaders) - return FALSE; - - if (!cliptest && !pipeline && !shading) { - /* This is the 'passthrough' path: - */ - /* Fetch user verts, emit hw verts: - */ - middle = draw->pt.middle.fetch_emit; - } - else if (!cliptest && !shading) { - /* This is the 'passthrough' path targetting the pipeline backend. - */ - /* Fetch user verts, emit pipeline verts, run pipeline: - */ - middle = draw->pt.middle.fetch_pipeline; - } - else if (!cliptest && !pipeline) { - /* Fetch user verts, run vertex shader, emit hw verts: - */ - middle = draw->pt.middle.fetch_shade_emit; - } - else if (!pipeline) { - /* Even though !pipeline, we have to run it to get clipping. We - * do know that the pipeline is just the clipping operation, but - * that probably doesn't help much. - * - * This is going to be the most important path for a lot of - * swtnl cards. - */ - /* Fetch user verts, - * run vertex shader, - * cliptest and viewport trasform - * if no clipped vertices, - * emit hw verts - * else - * run pipline - */ - middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit; - } - else { - /* This is what we're currently always doing: - */ - /* Fetch user verts, run vertex shader, cliptest, run pipeline - * or - * Fetch user verts, run vertex shader, run pipeline - */ - middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit; + if (draw_need_pipeline(draw, prim)) { + opt |= PT_PIPELINE; } + if (!draw->rasterizer->bypass_clipping) { + opt |= PT_CLIPTEST; + } - /* If !pipeline, need to make sure we respect the driver's limited - * capabilites to receive blocks of vertex data and elements. - */ -#if 0 - if (!pipeline) { - unsigned vertex_mode = passthrough; - unsigned nr_verts = count_vertices( draw, start, count ); - unsigned hw_prim = prim; - - if (is_elts(draw)) { - frontend = draw->pt.front.vcache; - hw_prim = reduced_prim(prim); - } -#if 0 - if (too_many_verts(nr_verts)) { - /* if (is_verts(draw) && can_split(prim)) { - draw = draw_arrays_split; - } - else */ { - frontend = draw->pt.front.vcache; - hw_prim = reduced_prim(prim); - } - } -#endif + if (!draw->rasterizer->bypass_vs) { + opt |= PT_SHADE; - if (too_many_elts(count)) { + if (!draw->use_pt_shaders) + return FALSE; + } - /* if (is_elts(draw) && can_split(prim)) { - draw = draw_elts_split; - } - else */ { - frontend = draw->pt.front.vcache; - hw_prim = reduced_prim(prim); - } - } - if (!good_prim(hw_prim)) { - frontend = draw->pt.front.vcache; - } + if (draw->pt.middle.opt[opt] == NULL) { + opt = PT_PIPELINE | PT_CLIPTEST | PT_SHADE; } -#else + + middle = draw->pt.middle.opt[opt]; + assert(middle); + + /* May create a short-circuited version of this for small primitives: + */ frontend = draw->pt.front.vcache; -#endif - frontend->prepare( frontend, prim, middle ); + + frontend->prepare( frontend, prim, middle, opt ); frontend->run( frontend, draw_pt_elt_func( draw ), @@ -190,21 +102,19 @@ draw_pt_arrays(struct draw_context *draw, boolean draw_pt_init( struct draw_context *draw ) { - draw->pt.middle.fetch_emit = draw_pt_fetch_emit( draw ); - if (!draw->pt.middle.fetch_emit) - return FALSE; - - draw->pt.middle.fetch_pipeline = draw_pt_fetch_pipeline( draw ); - if (!draw->pt.middle.fetch_pipeline) + draw->pt.front.vcache = draw_pt_vcache( draw ); + if (!draw->pt.front.vcache) return FALSE; - draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit = + draw->pt.middle.opt[0] = draw_pt_fetch_emit( draw ); + draw->pt.middle.opt[PT_PIPELINE] = draw_pt_fetch_pipeline( draw ); +// draw->pt.middle.opt[PT_SHADE] = draw_pt_shade_emit( draw ); +// draw->pt.middle.opt[PT_SHADE | PT_PIPELINE] = draw_pt_shade_pipeline( draw ); +// draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST] = draw_pt_shade_clip_either( draw ); + draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE] = draw_pt_fetch_pipeline_or_emit( draw ); - if (!draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit) - return FALSE; - draw->pt.front.vcache = draw_pt_vcache( draw ); - if (!draw->pt.front.vcache) + if (!draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE]) return FALSE; return TRUE; @@ -213,21 +123,13 @@ boolean draw_pt_init( struct draw_context *draw ) void draw_pt_destroy( struct draw_context *draw ) { - if (draw->pt.middle.fetch_emit) { - draw->pt.middle.fetch_emit->destroy( draw->pt.middle.fetch_emit ); - draw->pt.middle.fetch_emit = NULL; - } + int i; - if (draw->pt.middle.fetch_pipeline) { - draw->pt.middle.fetch_pipeline->destroy( draw->pt.middle.fetch_pipeline ); - draw->pt.middle.fetch_pipeline = NULL; - } - - if (draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit) { - draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit->destroy( - draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit ); - draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit = NULL; - } + for (i = 0; i < PT_MAX_MIDDLE; i++) + if (draw->pt.middle.opt[i]) { + draw->pt.middle.opt[i]->destroy( draw->pt.middle.opt[i] ); + draw->pt.middle.opt[i] = NULL; + } if (draw->pt.front.vcache) { draw->pt.front.vcache->destroy( draw->pt.front.vcache ); diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 48413b648a..08afb60645 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -64,7 +64,8 @@ struct draw_context; struct draw_pt_front_end { void (*prepare)( struct draw_pt_front_end *, unsigned prim, - struct draw_pt_middle_end * ); + struct draw_pt_middle_end *, + unsigned opt ); void (*run)( struct draw_pt_front_end *, pt_elt_func elt_func, @@ -90,7 +91,8 @@ struct draw_pt_front_end { */ struct draw_pt_middle_end { void (*prepare)( struct draw_pt_middle_end *, - unsigned prim ); + unsigned prim, + unsigned opt ); void (*run)( struct draw_pt_middle_end *, const unsigned *fetch_elts, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 3a26a5d712..1a9d331a06 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -164,7 +164,8 @@ fetch_store_general( struct fetch_emit_middle_end *feme, static void fetch_emit_prepare( struct draw_pt_middle_end *middle, - unsigned prim ) + unsigned prim, + unsigned opt ) { struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index a70d129c93..db6d6c76ea 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -209,7 +209,8 @@ fetch_store_general( struct fetch_pipeline_middle_end *fpme, * */ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, - unsigned prim ) + unsigned prim, + unsigned opt ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 2d83e11940..52be4a64aa 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -42,11 +42,13 @@ struct fetch_pipeline_middle_end { unsigned pipeline_vertex_size; unsigned prim; + unsigned opt; }; static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, - unsigned prim ) + unsigned prim, + unsigned opt ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; @@ -57,6 +59,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, struct translate_key hw_key; fpme->prim = prim; + fpme->opt = opt; ok = draw->render->set_primitive(draw->render, prim); if (!ok) { @@ -157,6 +160,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, struct draw_context *draw = fpme->draw; struct draw_vertex_shader *shader = draw->vertex_shader; char *pipeline_verts; + unsigned pipeline = PT_PIPELINE; pipeline_verts = MALLOC(fpme->pipeline_vertex_size * fetch_count); @@ -170,9 +174,17 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, /* Shade */ shader->prepare(shader, draw); + if (shader->run(shader, draw, fetch_elts, fetch_count, pipeline_verts, - fpme->pipeline_vertex_size)) { - /* Run the pipeline */ + fpme->pipeline_vertex_size)) + { + pipeline |= PT_CLIPTEST; + } + + + /* Do we need to run the pipeline? + */ + if (fpme->opt & pipeline) { draw_pt_run_pipeline( fpme->draw, fpme->prim, pipeline_verts, diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 107dcfc269..5561f2b6fb 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -448,7 +448,8 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { static void vcache_prepare( struct draw_pt_front_end *frontend, unsigned prim, - struct draw_pt_middle_end *middle ) + struct draw_pt_middle_end *middle, + unsigned opt ) { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; @@ -464,7 +465,7 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, vcache->output_prim = reduced_prim[prim]; vcache->middle = middle; - middle->prepare( middle, vcache->output_prim ); + middle->prepare( middle, vcache->output_prim, opt ); } -- cgit v1.2.3 From 909e8ce543a6c1e97d55791d2069cbdc56ea9db6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 16 Apr 2008 10:12:12 +0100 Subject: draw: update debug code --- src/gallium/auxiliary/draw/draw_vbuf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c index e3216ff711..eeb194afaa 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_vbuf.c @@ -113,12 +113,12 @@ check_space( struct vbuf_stage *vbuf, unsigned nr ) } -#if 0 +#if 1 static INLINE void dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) { - assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); - unsigned i, j, k; +// assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); + unsigned i, j; for (i = 0; i < vinfo->num_attribs; i++) { j = vinfo->src_index[i]; @@ -264,6 +264,8 @@ emit_vertex( struct vbuf_stage *vbuf, } else { draw_vf_emit_vertex(vbuf->vf, vertex, vbuf->vertex_ptr); + + if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); vbuf->vertex_ptr += vbuf->vertex_size/4; } -- cgit v1.2.3 From 8b607f42d094e61432c5718b8baa0a68268ec150 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 16 Apr 2008 12:20:39 +0100 Subject: softpipe: call setup_prepare earlier so that vertex info is correct when queried --- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 4fed19ecb6..e063fe82ef 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -106,6 +106,16 @@ static boolean sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + + /* XXX: break this dependency - make setup_context live under + * softpipe, rename the old "setup" draw stage to something else. + */ + struct setup_context *setup_ctx = sp_draw_setup_context(cvbr->softpipe->setup); + + setup_prepare( setup_ctx ); + + + if (prim == PIPE_PRIM_TRIANGLES || prim == PIPE_PRIM_LINES || prim == PIPE_PRIM_POINTS) { @@ -136,10 +146,6 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) */ struct draw_stage *setup = softpipe->setup; struct setup_context *setup_ctx = sp_draw_setup_context(softpipe->setup); - - /* XXX: call this from allocate_vertices: - */ - setup_prepare( setup_ctx ); switch (cvbr->prim) { -- cgit v1.2.3 From d8c389171872b69af3c94ebab02ad5f4bcd2d4df Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 16 Apr 2008 12:31:19 +0100 Subject: draw: remove vbuf non-vf debug path, fix some failure modes in draw_vbuf_create() --- src/gallium/auxiliary/draw/draw_vbuf.c | 106 ++++++--------------------------- 1 file changed, 19 insertions(+), 87 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c index eeb194afaa..59b63f5bfa 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_vbuf.c @@ -113,7 +113,6 @@ check_space( struct vbuf_stage *vbuf, unsigned nr ) } -#if 1 static INLINE void dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) { @@ -167,7 +166,6 @@ dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) } debug_printf("\n"); } -#endif /** @@ -181,94 +179,22 @@ static INLINE void emit_vertex( struct vbuf_stage *vbuf, struct vertex_header *vertex ) { -#if 0 - debug_printf("emit vertex %d to %p\n", - vbuf->nr_vertices, vbuf->vertex_ptr); -#endif - if(vertex->vertex_id != UNDEFINED_VERTEX_ID) { if(vertex->vertex_id < vbuf->nr_vertices) return; else debug_printf("Bad vertex id 0x%04x (>= 0x%04x)\n", - vertex->vertex_id, vbuf->nr_vertices); + vertex->vertex_id, vbuf->nr_vertices); return; } vertex->vertex_id = vbuf->nr_vertices++; - if(!vbuf->vf) { - const struct vertex_info *vinfo = vbuf->vinfo; - uint i; - uint count = 0; /* for debug/sanity */ - - assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); - - for (i = 0; i < vinfo->num_attribs; i++) { - uint j = vinfo->src_index[i]; - switch (vinfo->emit[i]) { - case EMIT_OMIT: - /* no-op */ - break; - case EMIT_1F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - count++; - break; - case EMIT_1F_PSIZE: - *vbuf->vertex_ptr++ = fui(vbuf->stage.draw->rasterizer->point_size); - count++; - break; - case EMIT_2F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); - count += 2; - break; - case EMIT_3F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); - count += 3; - break; - case EMIT_4F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][3]); - count += 4; - break; - case EMIT_4UB: - *vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[j][2] ), - float_to_ubyte( vertex->data[j][1] ), - float_to_ubyte( vertex->data[j][0] ), - float_to_ubyte( vertex->data[j][3] )); - count += 1; - break; - default: - assert(0); - } - } - assert(count == vinfo->size); -#if 0 - { - static float data[256]; - draw_vf_emit_vertex(vbuf->vf, vertex, data); - if(memcmp((uint8_t *)vbuf->vertex_ptr - vbuf->vertex_size, data, vbuf->vertex_size)) { - debug_printf("With VF:\n"); - dump_emitted_vertex(vbuf->vinfo, (uint8_t *)data); - debug_printf("Without VF:\n"); - dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr - vbuf->vertex_size); - assert(0); - } - } -#endif - } - else { - draw_vf_emit_vertex(vbuf->vf, vertex, vbuf->vertex_ptr); + draw_vf_emit_vertex(vbuf->vf, vertex, vbuf->vertex_ptr); - if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); + if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); - vbuf->vertex_ptr += vbuf->vertex_size/4; - } + vbuf->vertex_ptr += vbuf->vertex_size/4; } @@ -526,7 +452,7 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); if(!vbuf) - return NULL; + goto fail; vbuf->stage.draw = draw; vbuf->stage.point = vbuf_first_point; @@ -537,21 +463,27 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, vbuf->stage.destroy = vbuf_destroy; vbuf->render = render; + vbuf->max_indices = MAX2(render->max_indices, UNDEFINED_VERTEX_ID-1); - assert(render->max_indices < UNDEFINED_VERTEX_ID); - vbuf->max_indices = render->max_indices; - vbuf->indices = (ushort *) - align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 ); + vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * + sizeof(vbuf->indices[0]), + 16 ); if(!vbuf->indices) - vbuf_destroy(&vbuf->stage); + goto fail; vbuf->vertices = NULL; vbuf->vertex_ptr = vbuf->vertices; vbuf->prim = ~0; - - if(!GETENV("GALLIUM_NOVF")) - vbuf->vf = draw_vf_create(); + vbuf->vf = draw_vf_create(); + if (!vbuf->vf) + goto fail; return &vbuf->stage; + + fail: + if (vbuf) + vbuf_destroy(&vbuf->stage); + + return NULL; } -- cgit v1.2.3 From 3be453bf7fcffd945ee0238e66ff4247a4491f1c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 16 Apr 2008 12:55:47 +0100 Subject: draw: allow pt paths to run without a vbuf render stage --- src/gallium/auxiliary/draw/draw_pt.c | 7 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 137 +++++++++++---------- 2 files changed, 72 insertions(+), 72 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 895224c952..c0125c906f 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -54,10 +54,9 @@ draw_pt_arrays(struct draw_context *draw, struct draw_pt_middle_end *middle = NULL; unsigned opt = 0; - if (!draw->render) - return FALSE; - /*debug_printf("XXXXXXXXXX needs_pipeline = %d\n", pipeline);*/ - + if (!draw->render) { + opt |= PT_PIPELINE; + } if (draw_need_pipeline(draw, prim)) { opt |= PT_PIPELINE; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 52be4a64aa..a66e8b0ba2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -61,88 +61,89 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, fpme->prim = prim; fpme->opt = opt; - ok = draw->render->set_primitive(draw->render, prim); - if (!ok) { - assert(0); - return; - } + if (!(opt & PT_PIPELINE)) { + ok = draw->render->set_primitive(draw->render, prim); + if (!ok) { + assert(0); + return; + } - /* Must do this after set_primitive() above: - */ - vinfo = draw->render->get_vertex_info(draw->render); + /* Must do this after set_primitive() above: + */ + vinfo = draw->render->get_vertex_info(draw->render); - /* In passthrough mode, need to translate from vertex shader - * outputs to hw vertices. - */ - dst_offset = 0; - for (i = 0; i < vinfo->num_attribs; i++) { - unsigned emit_sz = 0; - unsigned src_buffer = 0; - unsigned output_format; - unsigned src_offset = (sizeof(struct vertex_header) + - vinfo->src_index[i] * 4 * sizeof(float) ); + /* In passthrough mode, need to translate from vertex shader + * outputs to hw vertices. + */ + dst_offset = 0; + for (i = 0; i < vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned src_buffer = 0; + unsigned output_format; + unsigned src_offset = (sizeof(struct vertex_header) + + vinfo->src_index[i] * 4 * sizeof(float) ); - switch (vinfo->emit[i]) { - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - src_buffer = 1; - src_offset = 0; - break; - case EMIT_4UB: - output_format = PIPE_FORMAT_B8G8R8A8_UNORM; - emit_sz = 4 * sizeof(ubyte); - default: - assert(0); - output_format = PIPE_FORMAT_NONE; - emit_sz = 0; - break; - } + switch (vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + src_buffer = 1; + src_offset = 0; + break; + case EMIT_4UB: + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); + default: + assert(0); + output_format = PIPE_FORMAT_NONE; + emit_sz = 0; + break; + } - hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - hw_key.element[i].input_buffer = src_buffer; - hw_key.element[i].input_offset = src_offset; - hw_key.element[i].output_format = output_format; - hw_key.element[i].output_offset = dst_offset; + hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + hw_key.element[i].input_buffer = src_buffer; + hw_key.element[i].input_offset = src_offset; + hw_key.element[i].output_format = output_format; + hw_key.element[i].output_offset = dst_offset; - dst_offset += emit_sz; - } + dst_offset += emit_sz; + } - hw_key.nr_elements = vinfo->num_attribs; - hw_key.output_stride = vinfo->size * 4; + hw_key.nr_elements = vinfo->num_attribs; + hw_key.output_stride = vinfo->size * 4; - /* Don't bother with caching at this stage: - */ - if (!fpme->translate || - memcmp(&fpme->translate->key, &hw_key, sizeof(hw_key)) != 0) - { - if (fpme->translate) - fpme->translate->release(fpme->translate); + /* Don't bother with caching at this stage: + */ + if (!fpme->translate || + memcmp(&fpme->translate->key, &hw_key, sizeof(hw_key)) != 0) + { + if (fpme->translate) + fpme->translate->release(fpme->translate); - fpme->translate = translate_generic_create( &hw_key ); + fpme->translate = translate_generic_create( &hw_key ); + } } - //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; } -- cgit v1.2.3 From 3a765bbe00940c4dffce72b659f625d97ea17971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 16 Apr 2008 22:32:10 +0900 Subject: gallium: Use debug_get_bool_option for controlling assert failure behaviour. Add GALLIUM_ABORT_ON_ASSERT=no to C:\gallium.cfg instead. --- src/gallium/auxiliary/util/p_debug.c | 47 +++--------------------------------- 1 file changed, 4 insertions(+), 43 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index c195f61820..25b132b40c 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -200,6 +200,8 @@ debug_get_bool_option(const char *name, boolean dfault) if(str == NULL) result = dfault; + else if(!strcmp(str, "n")) + result = FALSE; else if(!strcmp(str, "no")) result = FALSE; else if(!strcmp(str, "0")) @@ -251,57 +253,16 @@ debug_get_flags_option(const char *name, } -#if defined(WIN32) -ULONG_PTR debug_config_file = 0; -void *mapped_config_file = 0; - -enum { - eAssertAbortEn = 0x1, -}; - -/* Check for aborts enabled. */ -static unsigned abort_en(void) -{ - if (!mapped_config_file) - { - /* Open an 8 byte file for configuration data. */ - mapped_config_file = EngMapFile(L"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file); - } - - /* A value of "0" (ascii) in the configuration file will clear the - * first 8 bits in the test byte. - * - * A value of "1" (ascii) in the configuration file will set the - * first bit in the test byte. - * - * A value of "2" (ascii) in the configuration file will set the - * second bit in the test byte. - * - * Currently the only interesting values are 0 and 1, which clear - * and set abort-on-assert behaviour respectively. - */ - return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn; -} -#else /* WIN32 */ -static unsigned abort_en(void) -{ - return !GETENV("GALLIUM_ABORT_ON_ASSERT"); -} -#endif - void _debug_assert_fail(const char *expr, const char *file, unsigned line, const char *function) { _debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file, line, function, expr); - if (abort_en()) - { + if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", TRUE)) debug_break(); - } else - { + else _debug_printf("continuing...\n"); - } } -- cgit v1.2.3 From 52544aa23bebe68d6fc9b13dc55f6bb8c03430ff Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Apr 2008 09:46:38 -0600 Subject: gallium: added util_pack_color_ub() --- src/gallium/auxiliary/util/u_pack_color.h | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index cd13823985..1f6604c554 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -39,6 +39,45 @@ #include "pipe/p_format.h" +/** + * Pack ubyte R,G,B,A into dest pixel. + */ +static INLINE void +util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, + enum pipe_format format, void *dest) +{ + switch (format) { + case PIPE_FORMAT_R8G8B8A8_UNORM: + { + uint *d = (uint *) dest; + *d = (r << 24) | (g << 16) | (b << 8) | a; + } + return; + case PIPE_FORMAT_A8R8G8B8_UNORM: + { + uint *d = (uint *) dest; + *d = (a << 24) | (r << 16) | (g << 8) | b; + } + return; + case PIPE_FORMAT_B8G8R8A8_UNORM: + { + uint *d = (uint *) dest; + *d = (b << 24) | (g << 16) | (r << 8) | a; + } + return; + case PIPE_FORMAT_R5G6B5_UNORM: + { + ushort *d = (ushort *) dest; + *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); + } + return; + /* XXX lots more cases to add */ + default: + debug_printf("gallium: unhandled format in util_pack_color_ub()"); + } +} + + /** * Note rgba outside [0,1] will be clamped for int pixel formats. */ -- cgit v1.2.3 From 8abfcea690c66f75d61905f0ec5497b8fd7950d4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 10:37:53 +0100 Subject: draw: remove misleading comments --- src/gallium/auxiliary/draw/draw_pt_pipeline.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c index e70e63d08f..17ce6febec 100644 --- a/src/gallium/auxiliary/draw/draw_pt_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c @@ -36,11 +36,6 @@ #include "draw/draw_vertex.h" #include "draw/draw_pt.h" - -/** - * Add a point to the primitive queue. - * \param i0 index into user's vertex arrays - */ static void do_point( struct draw_context *draw, const char *v0 ) { @@ -55,11 +50,6 @@ static void do_point( struct draw_context *draw, } -/** - * Add a line to the primitive queue. - * \param i0 index into user's vertex arrays - * \param i1 index into user's vertex arrays - */ static void do_line( struct draw_context *draw, const char *v0, const char *v1 ) @@ -75,9 +65,7 @@ static void do_line( struct draw_context *draw, draw->pipeline.first->line( draw->pipeline.first, &prim ); } -/** - * Add a triangle to the primitive queue. - */ + static void do_triangle( struct draw_context *draw, char *v0, char *v1, -- cgit v1.2.3 From c96d565643de271c6bda066e892b25d0a97ea4d0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 13:14:22 +0100 Subject: draw: keep record of number of active vertex buffers --- src/gallium/auxiliary/draw/draw_context.c | 1 + src/gallium/auxiliary/draw/draw_private.h | 3 +++ 2 files changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 0c314f6e1d..cdcbfdc323 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -249,6 +249,7 @@ draw_set_vertex_buffers(struct draw_context *draw, draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); memcpy(draw->vertex_buffer, buffers, count * sizeof(buffers[0])); + draw->nr_vertex_buffers = count; } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 8ac061cc9f..359a8b8a3d 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -245,7 +245,10 @@ struct draw_context /* pipe state that we need: */ const struct pipe_rasterizer_state *rasterizer; struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + unsigned nr_vertex_buffers; + struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; struct draw_vertex_shader *vertex_shader; -- cgit v1.2.3 From 49becd2d7c751e563ce6be9051dd8e6dad88d1f7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 13:14:55 +0100 Subject: draw: add comment --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 1a9d331a06..d696afa1aa 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -185,6 +185,11 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, */ vinfo = draw->render->get_vertex_info(draw->render); + + /* This is unique as it transforms straight from API vertex + * information to HW vertices. All other cases go through our + * intermediate float[4] format. + */ for (i = 0; i < vinfo->num_attribs; i++) { unsigned src_element = vinfo->src_index[i]; unsigned src_buffer = draw->vertex_element[src_element].vertex_buffer_index; -- cgit v1.2.3 From 938ec19210c5b4e19dcb2b606c9ade415f2c1f84 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 14:19:03 +0100 Subject: tsgi: make Consts const --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h index 45c49dd007..92e2e5e985 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h @@ -166,7 +166,7 @@ struct tgsi_exec_machine float Imms[TGSI_EXEC_NUM_IMMEDIATES][4]; unsigned ImmLimit; - float (*Consts)[4]; + const float (*Consts)[4]; struct tgsi_exec_vector *Inputs; struct tgsi_exec_vector *Outputs; const struct tgsi_token *Tokens; -- cgit v1.2.3 From 280bcff1fa200b790d8712946a4ffbaa47a67433 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 14:20:00 +0100 Subject: draw: add vertex shader run_linear function --- src/gallium/auxiliary/draw/draw_aapoint.c | 2 +- src/gallium/auxiliary/draw/draw_clip.c | 2 +- src/gallium/auxiliary/draw/draw_context.c | 17 +++- src/gallium/auxiliary/draw/draw_flatshade.c | 2 +- src/gallium/auxiliary/draw/draw_private.h | 28 +------ .../auxiliary/draw/draw_pt_fetch_pipeline.c | 2 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 2 +- src/gallium/auxiliary/draw/draw_twoside.c | 2 +- src/gallium/auxiliary/draw/draw_vertex_fetch.c | 2 +- src/gallium/auxiliary/draw/draw_vertex_shader.c | 7 +- src/gallium/auxiliary/draw/draw_vs.h | 40 ++++++++- src/gallium/auxiliary/draw/draw_vs_exec.c | 95 +++++++++++++++++++--- src/gallium/auxiliary/draw/draw_vs_llvm.c | 66 ++++++++++++++- src/gallium/auxiliary/draw/draw_vs_sse.c | 76 ++++++++++++++++- src/gallium/auxiliary/draw/draw_wide_point.c | 2 +- 15 files changed, 286 insertions(+), 59 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c index fcebe3e7a0..e84d380e50 100644 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -48,7 +48,7 @@ #include "tgsi/util/tgsi_dump.h" #include "draw_context.h" -#include "draw_private.h" +#include "draw_vs.h" /* diff --git a/src/gallium/auxiliary/draw/draw_clip.c b/src/gallium/auxiliary/draw/draw_clip.c index e24c5d8032..0ac3a240e5 100644 --- a/src/gallium/auxiliary/draw/draw_clip.c +++ b/src/gallium/auxiliary/draw/draw_clip.c @@ -36,7 +36,7 @@ #include "pipe/p_shader_tokens.h" #include "draw_context.h" -#include "draw_private.h" +#include "draw_vs.h" #ifndef IS_NEGATIVE diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index cdcbfdc323..9b2dcc0b57 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -33,8 +33,8 @@ #include "pipe/p_util.h" #include "draw_context.h" -#include "draw_private.h" #include "draw_vbuf.h" +#include "draw_vs.h" struct draw_context *draw_create( void ) @@ -108,6 +108,8 @@ struct draw_context *draw_create( void ) draw_vertex_cache_invalidate( draw ); draw_set_mapped_element_buffer( draw, 0, NULL ); + tgsi_exec_machine_init(&draw->machine); + if (!draw_pt_init( draw )) goto fail; @@ -460,3 +462,16 @@ boolean draw_get_edgeflag( struct draw_context *draw, else return 1; } + + +#if 0 +/* Crufty init function. Fix me. + */ +boolean draw_init_machine( struct draw_context *draw ) +{ + ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); + ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); + machine->Inputs = ALIGN16_ASSIGN(inputs); + machine->Outputs = ALIGN16_ASSIGN(outputs); +} +#endif diff --git a/src/gallium/auxiliary/draw/draw_flatshade.c b/src/gallium/auxiliary/draw/draw_flatshade.c index af2cb05c98..54baa1fbc9 100644 --- a/src/gallium/auxiliary/draw/draw_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_flatshade.c @@ -30,7 +30,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "draw_private.h" +#include "draw_vs.h" /** subclass of draw_stage */ diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 359a8b8a3d..7953dbb7d9 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -55,6 +55,7 @@ struct gallivm_cpu_engine; struct draw_pt_middle_end; struct draw_pt_front_end; +struct draw_vertex_shader; #define MAX_SHADER_VERTICES 128 @@ -132,33 +133,6 @@ struct draw_stage #define VCACHE_OVERFLOW 4 #define VS_QUEUE_LENGTH (VCACHE_SIZE + VCACHE_OVERFLOW + 1) /* can never fill up */ -/** - * Private version of the compiled vertex_shader - */ -struct draw_vertex_shader { - - /* This member will disappear shortly: - */ - struct pipe_shader_state state; - - struct tgsi_shader_info info; - - void (*prepare)( struct draw_vertex_shader *shader, - struct draw_context *draw ); - - /* Run the shader - this interface will get cleaned up in the - * future: - */ - boolean (*run)( struct draw_vertex_shader *shader, - struct draw_context *draw, - const unsigned *elts, - unsigned count, - void *out, - unsigned vertex_size); - - - void (*delete)( struct draw_vertex_shader * ); -}; /* Internal function for vertex fetch. diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index db6d6c76ea..79548d4156 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -32,9 +32,9 @@ #include "pipe/p_util.h" #include "draw/draw_context.h" -#include "draw/draw_private.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" +#include "draw/draw_vs.h" /* The simplest 'middle end' in the new vertex code. * diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index a66e8b0ba2..cf37493eb6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -27,10 +27,10 @@ #include "pipe/p_util.h" #include "draw/draw_context.h" -#include "draw/draw_private.h" #include "draw/draw_vbuf.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" +#include "draw/draw_vs.h" #include "translate/translate.h" diff --git a/src/gallium/auxiliary/draw/draw_twoside.c b/src/gallium/auxiliary/draw/draw_twoside.c index 3debaac282..01d905c153 100644 --- a/src/gallium/auxiliary/draw/draw_twoside.c +++ b/src/gallium/auxiliary/draw/draw_twoside.c @@ -31,7 +31,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "draw_private.h" +#include "draw_vs.h" struct twoside_stage { diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c index 9041041006..0bc2fcb424 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c +++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c @@ -32,7 +32,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "draw_private.h" +#include "draw_vs.h" #include "draw_context.h" diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index 8572a6d40c..c0c17c116e 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -95,10 +95,8 @@ draw_create_vertex_shader(struct draw_context *draw, vs = draw_create_vs_exec( draw, shader ); } } - assert(vs); - - tgsi_scan_shader(shader->tokens, &vs->info); + assert(vs); return vs; } @@ -113,9 +111,6 @@ draw_bind_vertex_shader(struct draw_context *draw, { draw->vertex_shader = dvs; draw->num_vs_outputs = dvs->info.num_outputs; - - tgsi_exec_machine_init(&draw->machine); - dvs->prepare( dvs, draw ); } else { diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 33ce1e335e..e88d00e247 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -35,10 +35,46 @@ #include "draw_private.h" -struct draw_vertex_shader; struct draw_context; struct pipe_shader_state; +/** + * Private version of the compiled vertex_shader + */ +struct draw_vertex_shader { + + /* This member will disappear shortly: + */ + struct pipe_shader_state state; + + struct tgsi_shader_info info; + + void (*prepare)( struct draw_vertex_shader *shader, + struct draw_context *draw ); + + /* Run the shader - this interface will get cleaned up in the + * future: + */ + boolean (*run)( struct draw_vertex_shader *shader, + struct draw_context *draw, + const unsigned *elts, + unsigned count, + void *out, + unsigned vertex_size); + + void (*run_linear)( struct draw_vertex_shader *shader, + const float (*input)[4], + float (*output)[4], + const float (*constants)[4], + unsigned count, + unsigned input_stride, + unsigned output_stride ); + + + void (*delete)( struct draw_vertex_shader * ); +}; + + struct draw_vertex_shader * draw_create_vs_exec(struct draw_context *draw, const struct pipe_shader_state *templ); @@ -79,5 +115,7 @@ compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) return mask; } +#define MAX_TGSI_VERTICES 4 + #endif diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 5c88c2e24e..0e05b79715 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -40,8 +40,20 @@ #include "tgsi/util/tgsi_parse.h" -#define MAX_TGSI_VERTICES 4 +struct exec_vertex_shader { + struct draw_vertex_shader base; + struct tgsi_exec_machine *machine; +}; + +static struct exec_vertex_shader *exec_vertex_shader( struct draw_vertex_shader *vs ) +{ + return (struct exec_vertex_shader *)vs; +} + + +/* Not required for run_linear. + */ static void vs_exec_prepare( struct draw_vertex_shader *shader, struct draw_context *draw ) @@ -81,10 +93,9 @@ vs_exec_run( struct draw_vertex_shader *shader, const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; - assert(draw->vertex_shader->info.output_semantic_name[0] - == TGSI_SEMANTIC_POSITION); + assert(shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); - machine->Consts = (float (*)[4]) draw->user.constants; + machine->Consts = (const float (*)[4]) draw->user.constants; machine->Inputs = ALIGN16_ASSIGN(inputs); if (draw->rasterizer->bypass_vs) { /* outputs are just the inputs */ @@ -179,6 +190,64 @@ vs_exec_run( struct draw_vertex_shader *shader, +/* Simplified vertex shader interface for the pt paths. Given the + * complexity of code-generating all the above operations together, + * it's time to try doing all the other stuff separately. + */ +static void +vs_exec_run_linear( struct draw_vertex_shader *shader, + const float (*input)[4], + float (*output)[4], + const float (*constants)[4], + unsigned count, + unsigned input_stride, + unsigned output_stride ) +{ + struct exec_vertex_shader *evs = exec_vertex_shader(shader); + struct tgsi_exec_machine *machine = evs->machine; + unsigned int i, j; + unsigned slot; + + machine->Consts = constants; + + for (i = 0; i < count; i += MAX_TGSI_VERTICES) { + unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); + + /* Swizzle inputs. + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < shader->info.num_inputs; slot++) { + machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; + machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; + machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; + machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; + } + } + + /* run interpreter */ + tgsi_exec_machine_run( machine ); + + /* Unswizzle all output results. + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < shader->info.num_outputs; slot++) { + output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + } + + /* Advance input, output pointers: + */ + input = (const float (*)[4])((const char *)input + input_stride); + output = (float (*)[4])((char *)output + output_stride); + } +} + + + + static void vs_exec_delete( struct draw_vertex_shader *dvs ) { @@ -191,17 +260,23 @@ struct draw_vertex_shader * draw_create_vs_exec(struct draw_context *draw, const struct pipe_shader_state *state) { - struct draw_vertex_shader *vs = CALLOC_STRUCT( draw_vertex_shader ); + struct exec_vertex_shader *vs = CALLOC_STRUCT( exec_vertex_shader ); uint nt = tgsi_num_tokens(state->tokens); if (vs == NULL) return NULL; /* we make a private copy of the tokens */ - vs->state.tokens = mem_dup(state->tokens, nt * sizeof(state->tokens[0])); - vs->prepare = vs_exec_prepare; - vs->run = vs_exec_run; - vs->delete = vs_exec_delete; + vs->base.state.tokens = mem_dup(state->tokens, nt * sizeof(state->tokens[0])); + tgsi_scan_shader(state->tokens, &vs->base.info); + + + vs->base.prepare = vs_exec_prepare; + vs->base.run = vs_exec_run; + vs->base.run_linear = vs_exec_run_linear; + vs->base.delete = vs_exec_delete; + vs->machine = &draw->machine; + - return vs; + return &vs->base; } diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 73076d2467..d0baca715e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -88,8 +88,7 @@ vs_llvm_run( struct draw_vertex_shader *base, assert(count <= 4); - assert(draw->vertex_shader->state->output_semantic_name[0] - == TGSI_SEMANTIC_POSITION); + assert(base->state->output_semantic_name[0] == TGSI_SEMANTIC_POSITION); /* Consts does not require 16 byte alignment. */ machine->Consts = (float (*)[4]) draw->user.constants; @@ -169,6 +168,65 @@ vs_llvm_run( struct draw_vertex_shader *base, return clipped != 0; } + + + +static void +vs_llvm_run_linear( struct draw_vertex_shader *base, + const float (*input)[4], + float (*output)[4], + const float (*constants)[4], + unsigned count, + unsigned input_stride, + unsigned output_stride ) +{ + struct draw_llvm_vertex_shader *shader = + (struct draw_llvm_vertex_shader *)base; + + struct tgsi_exec_machine *machine = &draw->machine; + unsigned int j; + + + for (i = 0; i < count; i += MAX_TGSI_VERTICES) { + unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); + + /* Swizzle inputs. + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < draw->num_vs_inputs; slot++) { + machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; + machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; + machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; + machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; + } + } + + /* run shader */ + gallivm_cpu_vs_exec(shader->llvm_prog, + machine->Inputs, + machine->Outputs, + (float (*)[4]) constants, + machine->Temps); + + + /* Unswizzle all output results + */ + for (slot = 1; slot < draw->num_vs_outputs; slot++) { + output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + + /* Advance input, output pointers: + */ + input = (const float (*)[4])((const char *)input + input_stride); + output = (float (*)[4])((char *)output + output_stride); + } +} + + + static void vs_llvm_delete( struct draw_vertex_shader *base ) { @@ -198,8 +256,12 @@ draw_create_vs_llvm(struct draw_context *draw, /* we make a private copy of the tokens */ vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0])); + + tgsi_scan_shader(shader->tokens, &vs->base.info); + vs->base.prepare = vs_llvm_prepare; vs->base.run = vs_llvm_run; + vs->base.run_linear = vs_llvm_run_linear; vs->base.delete = vs_llvm_delete; { diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index ee0a3105b9..873ecfdc5d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -58,7 +58,11 @@ typedef void (XSTDCALL *codegen_function) ( struct draw_sse_vertex_shader { struct draw_vertex_shader base; struct x86_function sse2_program; + codegen_function func; + + struct tgsi_exec_machine *machine; + float immediates[TGSI_EXEC_NUM_IMMEDIATES][4]; }; @@ -96,11 +100,10 @@ vs_sse_run( struct draw_vertex_shader *base, const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; - assert(draw->vertex_shader->info.output_semantic_name[0] - == TGSI_SEMANTIC_POSITION); + assert(base->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); /* Consts does not require 16 byte alignment. */ - machine->Consts = (float (*)[4]) draw->user.constants; + machine->Consts = (const float (*)[4]) draw->user.constants; machine->Inputs = ALIGN16_ASSIGN(inputs); if (draw->rasterizer->bypass_vs) { /* outputs are just the inputs */ @@ -124,7 +127,7 @@ vs_sse_run( struct draw_vertex_shader *base, */ shader->func(machine->Inputs, machine->Outputs, - machine->Consts, + (float (*)[4])machine->Consts, machine->Temps, shader->immediates); } @@ -200,6 +203,67 @@ vs_sse_run( struct draw_vertex_shader *base, } +/* Simplified vertex shader interface for the pt paths. Given the + * complexity of code-generating all the above operations together, + * it's time to try doing all the other stuff separately. + */ +static void +vs_sse_run_linear( struct draw_vertex_shader *base, + const float (*input)[4], + float (*output)[4], + const float (*constants)[4], + unsigned count, + unsigned input_stride, + unsigned output_stride ) +{ + struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; + struct tgsi_exec_machine *machine = shader->machine; + unsigned int i, j; + unsigned slot; + + for (i = 0; i < count; i += MAX_TGSI_VERTICES) { + unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); + + /* Swizzle inputs. + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < base->info.num_inputs; slot++) { + machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; + machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; + machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; + machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; + } + } + + /* run compiled shader + */ + shader->func(machine->Inputs, + machine->Outputs, + (float (*)[4])constants, + machine->Temps, + shader->immediates); + + + /* Unswizzle all output results. + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < base->info.num_outputs; slot++) { + output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + } + + /* Advance input, output pointers: + */ + input = (const float (*)[4])((const char *)input + input_stride); + output = (float (*)[4])((char *)output + output_stride); + } +} + + + static void vs_sse_delete( struct draw_vertex_shader *base ) @@ -229,8 +293,12 @@ draw_create_vs_sse(struct draw_context *draw, /* we make a private copy of the tokens */ vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0])); + + tgsi_scan_shader(templ->tokens, &vs->base.info); + vs->base.prepare = vs_sse_prepare; vs->base.run = vs_sse_run; + vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; x86_init_func( &vs->sse2_program ); diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c index 6fc7c9fcd7..0fa7c9313c 100644 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_wide_point.c @@ -31,7 +31,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "draw_private.h" +#include "draw_vs.h" struct widepoint_stage { -- cgit v1.2.3 From fe8af141246bdfc0e98beec0089acdb92407bcfa Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 14:42:05 +0100 Subject: draw: don't always run pipeline if clipping --- src/gallium/auxiliary/draw/draw_pt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index c0125c906f..60a47f3911 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -74,11 +74,11 @@ draw_pt_arrays(struct draw_context *draw, } - if (draw->pt.middle.opt[opt] == NULL) { - opt = PT_PIPELINE | PT_CLIPTEST | PT_SHADE; + middle = draw->pt.middle.opt[opt]; + if (middle == NULL) { + middle = draw->pt.middle.opt[PT_PIPELINE | PT_CLIPTEST | PT_SHADE]; } - middle = draw->pt.middle.opt[opt]; assert(middle); /* May create a short-circuited version of this for small primitives: -- cgit v1.2.3 From c503e55d74cf84f87f82b3dab3cb4d38b201d47a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 14:43:40 +0100 Subject: draw: move hw vertex emit to a new module --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_private.h | 8 - src/gallium/auxiliary/draw/draw_pt.h | 33 ++++ src/gallium/auxiliary/draw/draw_pt_emit.c | 208 +++++++++++++++++++++ .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 161 +++------------- 5 files changed, 270 insertions(+), 141 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_emit.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 5ab3cfe5ce..836e98f086 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -21,6 +21,7 @@ C_SOURCES = \ draw_pt_fetch_pipeline.c \ draw_pt_fetch_shade_pipeline.c \ draw_pt_pipeline.c \ + draw_pt_emit.c \ draw_pt_elts.c \ draw_prim.c \ draw_pstipple.c \ diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 7953dbb7d9..9407217fd3 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -376,14 +376,6 @@ boolean draw_pt_arrays( struct draw_context *draw, unsigned count ); void draw_pt_reset_vertex_ids( struct draw_context *draw ); -void draw_pt_run_pipeline( struct draw_context *draw, - unsigned prim, - char *verts, - unsigned vertex_stride, - unsigned vertex_count, - const ushort *elts, - unsigned count ); - #define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ #define DRAW_FLUSH_PRIM_QUEUE 0x2 diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 08afb60645..31d18ec62b 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -128,4 +128,37 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw); +/* More helpers: + */ +void draw_pt_run_pipeline( struct draw_context *draw, + unsigned prim, + char *verts, + unsigned vertex_stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ); + + +/* HW vertex emit: + */ +struct pt_emit; + +void draw_pt_emit_prepare( struct pt_emit *emit, + unsigned prim, + unsigned opt ); + +void draw_pt_emit( struct pt_emit *emit, + char *verts, + unsigned stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ); + +void draw_pt_emit_destroy( struct pt_emit *emit ); + +struct pt_emit *draw_pt_emit_create( struct draw_context *draw ); + + + + #endif diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c new file mode 100644 index 0000000000..e9ed29450a --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -0,0 +1,208 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" +#include "translate/translate.h" + + +struct pt_emit { + struct draw_context *draw; + + struct translate *translate; + + unsigned pipeline_vertex_size; + unsigned prim; + unsigned opt; +}; + + +void draw_pt_emit_prepare( struct pt_emit *emit, + unsigned prim, + unsigned opt ) +{ + struct draw_context *draw = emit->draw; + const struct vertex_info *vinfo; + unsigned dst_offset; + struct translate_key hw_key; + unsigned i; + boolean ok; + + ok = draw->render->set_primitive(draw->render, prim); + if (!ok) { + assert(0); + return; + } + + /* Must do this after set_primitive() above: + */ + vinfo = draw->render->get_vertex_info(draw->render); + + + /* In passthrough mode, need to translate from vertex shader + * outputs to hw vertices. + */ + dst_offset = 0; + for (i = 0; i < vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned src_buffer = 0; + unsigned output_format; + unsigned src_offset = (sizeof(struct vertex_header) + + vinfo->src_index[i] * 4 * sizeof(float) ); + + + + switch (vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + src_buffer = 1; + src_offset = 0; + break; + case EMIT_4UB: + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); + default: + assert(0); + output_format = PIPE_FORMAT_NONE; + emit_sz = 0; + break; + } + + hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + hw_key.element[i].input_buffer = src_buffer; + hw_key.element[i].input_offset = src_offset; + hw_key.element[i].output_format = output_format; + hw_key.element[i].output_offset = dst_offset; + + dst_offset += emit_sz; + } + + hw_key.nr_elements = vinfo->num_attribs; + hw_key.output_stride = vinfo->size * 4; + + /* Don't bother with caching at this stage: + */ + if (!emit->translate || + memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0) + { + if (emit->translate) + emit->translate->release(emit->translate); + + emit->translate = translate_generic_create( &hw_key ); + } +} + + +void draw_pt_emit( struct pt_emit *emit, + char *verts, + unsigned stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ) +{ + struct draw_context *draw = emit->draw; + struct translate *translate = emit->translate; + struct vbuf_render *render = draw->render; + void *hw_verts; + + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + + hw_verts = render->allocate_vertices(render, + (ushort)translate->key.output_stride, + (ushort)count); + if (!hw_verts) { + assert(0); + return; + } + + translate->set_buffer(translate, + 0, + verts, + stride ); + + translate->set_buffer(translate, + 1, + &draw->rasterizer->point_size, + 0); + + translate->run( translate, + 0, + vertex_count, + hw_verts ); + + render->draw(render, + elts, + count); + + render->release_vertices(render, + hw_verts, + translate->key.output_stride, + vertex_count); +} + + +struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) +{ + struct pt_emit *emit = CALLOC_STRUCT(pt_emit); + if (!emit) + return NULL; + + emit->draw = draw; + + return emit; +} + +void draw_pt_emit_destroy( struct pt_emit *emit ) +{ + if (emit->translate) + emit->translate->release( emit->translate ); + + FREE(emit); +} diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index cf37493eb6..8db9e31e2d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -38,7 +38,7 @@ struct fetch_pipeline_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; - struct translate *translate; + struct pt_emit *emit; unsigned pipeline_vertex_size; unsigned prim; @@ -51,98 +51,12 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned opt ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; - struct draw_context *draw = fpme->draw; - unsigned i; - boolean ok; - const struct vertex_info *vinfo; - unsigned dst_offset; - struct translate_key hw_key; fpme->prim = prim; fpme->opt = opt; - if (!(opt & PT_PIPELINE)) { - ok = draw->render->set_primitive(draw->render, prim); - if (!ok) { - assert(0); - return; - } - - /* Must do this after set_primitive() above: - */ - vinfo = draw->render->get_vertex_info(draw->render); - - - /* In passthrough mode, need to translate from vertex shader - * outputs to hw vertices. - */ - dst_offset = 0; - for (i = 0; i < vinfo->num_attribs; i++) { - unsigned emit_sz = 0; - unsigned src_buffer = 0; - unsigned output_format; - unsigned src_offset = (sizeof(struct vertex_header) + - vinfo->src_index[i] * 4 * sizeof(float) ); - - - - switch (vinfo->emit[i]) { - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - src_buffer = 1; - src_offset = 0; - break; - case EMIT_4UB: - output_format = PIPE_FORMAT_B8G8R8A8_UNORM; - emit_sz = 4 * sizeof(ubyte); - default: - assert(0); - output_format = PIPE_FORMAT_NONE; - emit_sz = 0; - break; - } - - hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - hw_key.element[i].input_buffer = src_buffer; - hw_key.element[i].input_offset = src_offset; - hw_key.element[i].output_format = output_format; - hw_key.element[i].output_offset = dst_offset; - - dst_offset += emit_sz; - } - - hw_key.nr_elements = vinfo->num_attribs; - hw_key.output_stride = vinfo->size * 4; - - /* Don't bother with caching at this stage: - */ - if (!fpme->translate || - memcmp(&fpme->translate->key, &hw_key, sizeof(hw_key)) != 0) - { - if (fpme->translate) - fpme->translate->release(fpme->translate); - - fpme->translate = translate_generic_create( &hw_key ); - } - } - + if (!(opt & PT_PIPELINE)) + draw_pt_emit_prepare( fpme->emit, prim, opt ); //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; @@ -194,43 +108,12 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, draw_elts, draw_count ); } else { - struct translate *translate = fpme->translate; - void *hw_verts; - - /* XXX: need to flush to get prim_vbuf.c to release its allocation?? - */ - draw_do_flush( draw, DRAW_FLUSH_BACKEND ); - - hw_verts = draw->render->allocate_vertices(draw->render, - (ushort)fpme->translate->key.output_stride, - (ushort)fetch_count); - if (!hw_verts) { - assert(0); - return; - } - - translate->set_buffer(translate, - 0, - pipeline_verts, - fpme->pipeline_vertex_size ); - - translate->set_buffer(translate, - 1, - &fpme->draw->rasterizer->point_size, - 0); - - translate->run( translate, - 0, fetch_count, - hw_verts ); - - draw->render->draw(draw->render, - draw_elts, - draw_count); - - draw->render->release_vertices(draw->render, - hw_verts, - fpme->translate->key.output_stride, - fetch_count); + draw_pt_emit( fpme->emit, + pipeline_verts, + fpme->pipeline_vertex_size, + fetch_count, + draw_elts, + draw_count ); } @@ -252,14 +135,26 @@ static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context *draw ) { - struct fetch_pipeline_middle_end *fetch_pipeline = CALLOC_STRUCT( fetch_pipeline_middle_end ); + struct fetch_pipeline_middle_end *fpme = CALLOC_STRUCT( fetch_pipeline_middle_end ); + if (!fpme) + goto fail; + + fpme->base.prepare = fetch_pipeline_prepare; + fpme->base.run = fetch_pipeline_run; + fpme->base.finish = fetch_pipeline_finish; + fpme->base.destroy = fetch_pipeline_destroy; + + fpme->draw = draw; + + fpme->emit = draw_pt_emit_create( draw ); + if (!fpme->emit) + goto fail; - fetch_pipeline->base.prepare = fetch_pipeline_prepare; - fetch_pipeline->base.run = fetch_pipeline_run; - fetch_pipeline->base.finish = fetch_pipeline_finish; - fetch_pipeline->base.destroy = fetch_pipeline_destroy; + return &fpme->base; - fetch_pipeline->draw = draw; + fail: + if (fpme) + fetch_pipeline_destroy( &fpme->base ); - return &fetch_pipeline->base; + return NULL; } -- cgit v1.2.3 From 4dcb09d48981f07a82d7f609fe492453c8fdbcf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 17 Apr 2008 17:53:33 +0100 Subject: gallium: Add new file to scons build. --- src/gallium/auxiliary/draw/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index a7fb5dbd61..62e0cd9e50 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -16,6 +16,7 @@ draw = env.ConvenienceLibrary( 'draw_offset.c', 'draw_pt.c', 'draw_pt_vcache.c', + 'draw_pt_emit.c', 'draw_pt_fetch_emit.c', 'draw_pt_fetch_pipeline.c', 'draw_pt_fetch_shade_pipeline.c', -- cgit v1.2.3 From ce454d2192918ae4b2535d0e76c68ebde3c4653f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 17 Apr 2008 11:13:05 -0600 Subject: gallium: assert that we're not deleting the currently bound shader --- src/gallium/drivers/softpipe/sp_state_fs.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 4eefd1d61f..2921066ce3 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -82,7 +82,10 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) void softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { + struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state = fs; + + assert(fs != softpipe->fs); state->delete( state ); } -- cgit v1.2.3 From 01b6354e72a84f8c3c22be1f77eab8d9c05920a3 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 17 Apr 2008 15:26:37 -0600 Subject: gallium: tweak x/ybias values --- src/gallium/auxiliary/draw/draw_wide_point.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c index 0fa7c9313c..3d0add0c1a 100644 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_wide_point.c @@ -199,7 +199,7 @@ static void widepoint_first_point( struct draw_stage *stage, wide->ybias = 0.0; if (draw->rasterizer->gl_rasterization_rules) { - wide->ybias = -0.125; + wide->xbias = 0.125; } /* XXX we won't know the real size if it's computed by the vertex shader! */ -- cgit v1.2.3 From a773f06e969a3992451dd7fe6fd55ea96b2774fa Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 23:44:32 +0100 Subject: draw: split off all the extra functionality in the vertex shader This will at least allow us to make the initial gains to get decent vertex performance much more quickly & with higher confidence of getting it right. At some later point can look again at code-generating all the fetch/cliptest/viewport extras in the same block as the vertex shader. For now, just need to get some decent baseline performance. --- src/gallium/auxiliary/draw/Makefile | 4 +- src/gallium/auxiliary/draw/draw_context.c | 26 +-- src/gallium/auxiliary/draw/draw_private.h | 2 + src/gallium/auxiliary/draw/draw_pt.h | 51 +++++- src/gallium/auxiliary/draw/draw_pt_emit.c | 16 +- src/gallium/auxiliary/draw/draw_pt_fetch.c | 175 ++++++++++++++++++ .../auxiliary/draw/draw_pt_fetch_pipeline.c | 4 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 109 +++++++++-- src/gallium/auxiliary/draw/draw_pt_pipeline.c | 5 +- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 202 +++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_exec.c | 82 ++++++--- src/gallium/auxiliary/draw/draw_vs_llvm.c | 39 ++-- src/gallium/auxiliary/draw/draw_vs_sse.c | 38 ++-- 13 files changed, 635 insertions(+), 118 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_fetch.c create mode 100644 src/gallium/auxiliary/draw/draw_pt_post_vs.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 836e98f086..154c8a99b5 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -20,8 +20,10 @@ C_SOURCES = \ draw_pt_fetch_emit.c \ draw_pt_fetch_pipeline.c \ draw_pt_fetch_shade_pipeline.c \ - draw_pt_pipeline.c \ + draw_pt_fetch.c \ + draw_pt_post_vs.c \ draw_pt_emit.c \ + draw_pt_pipeline.c \ draw_pt_elts.c \ draw_prim.c \ draw_pstipple.c \ diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 9b2dcc0b57..4838b68ed1 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -110,6 +110,12 @@ struct draw_context *draw_create( void ) tgsi_exec_machine_init(&draw->machine); + /* FIXME: give this machine thing a proper constructor: + */ + draw->machine.Inputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); + draw->machine.Outputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); + + if (!draw_pt_init( draw )) goto fail; @@ -155,8 +161,13 @@ void draw_destroy( struct draw_context *draw ) if (draw->pipeline.rasterize) draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); + if (draw->machine.Inputs) + align_free(draw->machine.Inputs); + if (draw->machine.Outputs) + align_free(draw->machine.Outputs); tgsi_exec_machine_free_data(&draw->machine); - + + if (draw->vs.vertex_cache) align_free( draw->vs.vertex_cache ); /* Frees all the vertices. */ @@ -265,6 +276,7 @@ draw_set_vertex_elements(struct draw_context *draw, draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); memcpy(draw->vertex_element, elements, count * sizeof(elements[0])); + draw->nr_vertex_elements = count; } @@ -463,15 +475,3 @@ boolean draw_get_edgeflag( struct draw_context *draw, return 1; } - -#if 0 -/* Crufty init function. Fix me. - */ -boolean draw_init_machine( struct draw_context *draw ) -{ - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); - machine->Inputs = ALIGN16_ASSIGN(inputs); - machine->Outputs = ALIGN16_ASSIGN(outputs); -} -#endif diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 9407217fd3..da94e69781 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -224,6 +224,8 @@ struct draw_context unsigned nr_vertex_buffers; struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; + unsigned nr_vertex_elements; + struct draw_vertex_shader *vertex_shader; boolean identity_viewport; diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 31d18ec62b..316289969b 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -112,6 +112,7 @@ struct draw_pt_middle_end { * mode... */ struct vbuf_render; +struct vertex_header; /* Helper functions. @@ -132,25 +133,25 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *d */ void draw_pt_run_pipeline( struct draw_context *draw, unsigned prim, - char *verts, - unsigned vertex_stride, + struct vertex_header *verts, unsigned vertex_count, + unsigned vertex_stride, const ushort *elts, unsigned count ); -/* HW vertex emit: +/******************************************************************************* + * HW vertex emit: */ struct pt_emit; void draw_pt_emit_prepare( struct pt_emit *emit, - unsigned prim, - unsigned opt ); + unsigned prim ); void draw_pt_emit( struct pt_emit *emit, - char *verts, - unsigned stride, + const float (*vertex_data)[4], unsigned vertex_count, + unsigned stride, const ushort *elts, unsigned count ); @@ -159,6 +160,42 @@ void draw_pt_emit_destroy( struct pt_emit *emit ); struct pt_emit *draw_pt_emit_create( struct draw_context *draw ); +/******************************************************************************* + * API vertex fetch: + */ + +struct pt_fetch; +void draw_pt_fetch_prepare( struct pt_fetch *fetch, + boolean emit_header, + unsigned vertex_size ); + +void draw_pt_fetch_run( struct pt_fetch *fetch, + const unsigned *elts, + unsigned count, + char *verts ); + +void draw_pt_fetch_destroy( struct pt_fetch *fetch ); + +struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ); + +/******************************************************************************* + * Post-VS: cliptest, rhw, viewport + */ +struct pt_post_vs; + +boolean draw_pt_post_vs_run( struct pt_post_vs *pvs, + struct vertex_header *pipeline_verts, + unsigned stride, + unsigned count ); + +void draw_pt_post_vs_prepare( struct pt_post_vs *pvs, + boolean bypass_clipping, + boolean identity_viewport, + boolean opengl ); + +struct pt_post_vs *draw_pt_post_vs_create( struct draw_context *draw ); + +void draw_pt_post_vs_destroy( struct pt_post_vs *pvs ); #endif diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index e9ed29450a..ef9db70a02 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -38,16 +38,11 @@ struct pt_emit { struct draw_context *draw; struct translate *translate; - - unsigned pipeline_vertex_size; - unsigned prim; - unsigned opt; }; void draw_pt_emit_prepare( struct pt_emit *emit, - unsigned prim, - unsigned opt ) + unsigned prim ) { struct draw_context *draw = emit->draw; const struct vertex_info *vinfo; @@ -75,8 +70,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, unsigned emit_sz = 0; unsigned src_buffer = 0; unsigned output_format; - unsigned src_offset = (sizeof(struct vertex_header) + - vinfo->src_index[i] * 4 * sizeof(float) ); + unsigned src_offset = (vinfo->src_index[i] * 4 * sizeof(float) ); @@ -139,9 +133,9 @@ void draw_pt_emit_prepare( struct pt_emit *emit, void draw_pt_emit( struct pt_emit *emit, - char *verts, - unsigned stride, + const float (*vertex_data)[4], unsigned vertex_count, + unsigned stride, const ushort *elts, unsigned count ) { @@ -164,7 +158,7 @@ void draw_pt_emit( struct pt_emit *emit, translate->set_buffer(translate, 0, - verts, + vertex_data, stride ); translate->set_buffer(translate, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c new file mode 100644 index 0000000000..a7553023b8 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -0,0 +1,175 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" +#include "translate/translate.h" + + +struct pt_fetch { + struct draw_context *draw; + + struct translate *translate; + + unsigned vertex_size; +}; + + + +/* Perform the fetch from API vertex elements & vertex buffers, to a + * contiguous set of float[4] attributes as required for the + * vertex_shader->run_linear() method. + * + * This is used in all cases except pure passthrough + * (draw_pt_fetch_emit.c) which has its own version to translate + * directly to hw vertices. + * + */ +void draw_pt_fetch_prepare( struct pt_fetch *fetch, + boolean emit_header, + unsigned vertex_size ) +{ + struct draw_context *draw = fetch->draw; + unsigned i, nr = 0; + unsigned dst_offset = 0; + struct translate_key key; + + fetch->vertex_size = vertex_size; + + memset(&key, 0, sizeof(key)); + + /* If PT_SHADE is not set, then we are creating post-shader + * vertices, meaning that we need to emit/leave space for a vertex + * header. + * + * It's worth considering whether the vertex headers should contain + * a pointer to the 'data', rather than having it inline. + * Something to look at after we've fully switched over to the pt + * paths. + */ + if (emit_header) + { + /* Need to set header->vertex_id = 0xffff somehow. + */ + key.element[nr].input_format = PIPE_FORMAT_R32_FLOAT; + key.element[nr].input_buffer = draw->nr_vertex_buffers; + key.element[nr].input_offset = 0; + key.element[nr].output_format = PIPE_FORMAT_R32_FLOAT; + key.element[nr].output_offset = dst_offset; + dst_offset += 1 * sizeof(float); + nr++; + + + /* Just leave the clip[] array untouched. + */ + dst_offset += 4 * sizeof(float); + } + + + for (i = 0; i < draw->nr_vertex_elements; i++) { + key.element[nr].input_format = draw->vertex_element[i].src_format; + key.element[nr].input_buffer = draw->vertex_element[i].vertex_buffer_index; + key.element[nr].input_offset = draw->vertex_element[i].src_offset; + key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + key.element[nr].output_offset = dst_offset; + + dst_offset += 4 * sizeof(float); + nr++; + } + + assert(dst_offset <= vertex_size); + + key.nr_elements = nr; + key.output_stride = vertex_size; + + + /* Don't bother with caching at this stage: + */ + if (!fetch->translate || + memcmp(&fetch->translate->key, &key, sizeof(key)) != 0) + { + if (fetch->translate) + fetch->translate->release(fetch->translate); + + fetch->translate = translate_generic_create( &key ); + + if (emit_header) { + static struct vertex_header vh = { 0, 0, 0, 0xffff }; + fetch->translate->set_buffer(fetch->translate, + draw->nr_vertex_buffers, + &vh, + 0); + } + } +} + + + + +void draw_pt_fetch_run( struct pt_fetch *fetch, + const unsigned *elts, + unsigned count, + char *verts ) +{ + struct draw_context *draw = fetch->draw; + struct translate *translate = fetch->translate; + unsigned i; + + for (i = 0; i < draw->nr_vertex_buffers; i++) { + translate->set_buffer(translate, + i, + ((char *)draw->user.vbuffer[i] + + draw->vertex_buffer[i].buffer_offset), + draw->vertex_buffer[i].pitch ); + } + + translate->run_elts( translate, + elts, + count, + verts ); +} + + +struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) +{ + struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch); + if (!fetch) + return NULL; + + fetch->draw = draw; + return fetch; +} + +void draw_pt_fetch_destroy( struct pt_fetch *fetch ) +{ + FREE(fetch); +} + diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index 79548d4156..26d0b37286 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -286,9 +286,9 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, */ draw_pt_run_pipeline( fpme->draw, fpme->prim, - pipeline_verts, - fpme->pipeline_vertex_size, + (struct vertex_header *)pipeline_verts, fetch_count, + fpme->pipeline_vertex_size, draw_elts, draw_count ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 8db9e31e2d..0b9e8d15ba 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -39,8 +39,11 @@ struct fetch_pipeline_middle_end { struct draw_context *draw; struct pt_emit *emit; + struct pt_fetch *fetch; + struct pt_post_vs *post_vs; - unsigned pipeline_vertex_size; + unsigned vertex_data_offset; + unsigned vertex_size; unsigned prim; unsigned opt; }; @@ -51,15 +54,43 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned opt ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + struct draw_context *draw = fpme->draw; + struct draw_vertex_shader *vs = draw->vertex_shader; + unsigned nr = MAX2( vs->info.num_inputs, + vs->info.num_outputs ); fpme->prim = prim; fpme->opt = opt; + /* Always leave room for the vertex header whether we need it or + * not. It's hard to get rid of it in particular because of the + * viewport code in draw_pt_post_vs.c. + */ + fpme->vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); + + + + draw_pt_fetch_prepare( fpme->fetch, + (opt & (PT_CLIPTEST | PT_PIPELINE)) != 0, + fpme->vertex_size ); + + /* XXX: it's not really gl rasterization rules we care about here, + * but gl vs dx9 clip spaces. + */ + draw_pt_post_vs_prepare( fpme->post_vs, + draw->rasterizer->bypass_clipping, + draw->identity_viewport, + draw->rasterizer->gl_rasterization_rules ); + + if (!(opt & PT_PIPELINE)) - draw_pt_emit_prepare( fpme->emit, prim, opt ); + draw_pt_emit_prepare( fpme->emit, + prim ); + + /* No need to prepare the shader. + */ + vs->prepare(vs, draw); - //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); - fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; } @@ -74,44 +105,63 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; struct draw_vertex_shader *shader = draw->vertex_shader; - char *pipeline_verts; - unsigned pipeline = PT_PIPELINE; + unsigned opt = fpme->opt; - pipeline_verts = MALLOC(fpme->pipeline_vertex_size * - fetch_count); + struct vertex_header *pipeline_verts = + (struct vertex_header *)MALLOC(fpme->vertex_size * fetch_count); if (!pipeline_verts) { assert(0); return; } - - /* Shade + /* Fetch into our vertex buffer */ - shader->prepare(shader, draw); - - if (shader->run(shader, draw, fetch_elts, fetch_count, pipeline_verts, - fpme->pipeline_vertex_size)) + draw_pt_fetch_run( fpme->fetch, + fetch_elts, + fetch_count, + (char *)pipeline_verts ); + + /* Run the shader, note that this overwrites the data[] parts of + * the pipeline verts. If there is no shader, ie a bypass shader, + * then the inputs == outputs, and are already in the correct + * place. + */ + if (opt & PT_SHADE) { - pipeline |= PT_CLIPTEST; + shader->run_linear(shader, + (const float (*)[4])pipeline_verts->data, + ( float (*)[4])pipeline_verts->data, + (const float (*)[4])draw->user.constants, + fetch_count, + fpme->vertex_size, + fpme->vertex_size); } + if (draw_pt_post_vs_run( fpme->post_vs, + pipeline_verts, + fetch_count, + fpme->vertex_size )) + { + opt |= PT_PIPELINE; + } /* Do we need to run the pipeline? */ - if (fpme->opt & pipeline) { + if (opt & PT_PIPELINE) { draw_pt_run_pipeline( fpme->draw, fpme->prim, pipeline_verts, - fpme->pipeline_vertex_size, fetch_count, + fpme->vertex_size, draw_elts, draw_count ); - } else { + } + else { draw_pt_emit( fpme->emit, - pipeline_verts, - fpme->pipeline_vertex_size, + (const float (*)[4])pipeline_verts->data, fetch_count, + fpme->vertex_size, draw_elts, draw_count ); } @@ -129,6 +179,17 @@ static void fetch_pipeline_finish( struct draw_pt_middle_end *middle ) static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) { + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + + if (fpme->fetch) + draw_pt_fetch_destroy( fpme->fetch ); + + if (fpme->emit) + draw_pt_emit_destroy( fpme->emit ); + + if (fpme->post_vs) + draw_pt_post_vs_destroy( fpme->post_vs ); + FREE(middle); } @@ -146,6 +207,14 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context * fpme->draw = draw; + fpme->fetch = draw_pt_fetch_create( draw ); + if (!fpme->fetch) + goto fail; + + fpme->post_vs = draw_pt_post_vs_create( draw ); + if (!fpme->post_vs) + goto fail; + fpme->emit = draw_pt_emit_create( draw ); if (!fpme->emit) goto fail; diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c index 17ce6febec..1a9a3adb03 100644 --- a/src/gallium/auxiliary/draw/draw_pt_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c @@ -117,12 +117,13 @@ void draw_pt_reset_vertex_ids( struct draw_context *draw ) */ void draw_pt_run_pipeline( struct draw_context *draw, unsigned prim, - char *verts, - unsigned stride, + struct vertex_header *pipeline_verts, unsigned vertex_count, + unsigned stride, const ushort *elts, unsigned count ) { + char *verts = (char *)pipeline_verts; unsigned i; draw->pt.pipeline.verts = verts; diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c new file mode 100644 index 0000000000..315b02f4ee --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -0,0 +1,202 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "pipe/p_context.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" + +struct pt_post_vs { + struct draw_context *draw; + + boolean (*run)( struct pt_post_vs *pvs, + struct vertex_header *vertices, + unsigned count, + unsigned stride ); +}; + + + +static INLINE unsigned +compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr) +{ + unsigned mask = 0x0; + unsigned i; + + /* Do the hardwired planes first: + */ + if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; + if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; + if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; + if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; + if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; + if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; + + /* Followed by any remaining ones: + */ + for (i = 6; i < nr; i++) { + if (dot4(clip, plane[i]) < 0) + mask |= (1<draw->viewport.scale; + const float *trans = pvs->draw->viewport.translate; + unsigned j; + unsigned clipped = 0; + + for (j = 0; j < count; j++) { + out->clip[0] = out->data[0][0]; + out->clip[1] = out->data[0][1]; + out->clip[2] = out->data[0][2]; + out->clip[3] = out->data[0][3]; + + out->vertex_id = 0xffff; + out->edgeflag = 1; + out->clipmask = compute_clipmask_gl(out->clip, + pvs->draw->plane, + pvs->draw->nr_planes); + clipped += out->clipmask; + + if (out->clipmask == 0) + { + /* divide by w */ + float w = 1.0f / out->data[0][3]; + + /* Viewport mapping */ + out->data[0][0] = out->data[0][0] * w * scale[0] + trans[0]; + out->data[0][1] = out->data[0][1] * w * scale[1] + trans[1]; + out->data[0][2] = out->data[0][2] * w * scale[2] + trans[2]; + out->data[0][3] = w; + } + + out = (struct vertex_header *)( (char *)out + stride ); + } + + return clipped != 0; +} + + + +/* If bypass_clipping is set, skip cliptest and rhw divide. + */ +static boolean post_vs_viewport( struct pt_post_vs *pvs, + struct vertex_header *vertices, + unsigned count, + unsigned stride ) +{ + struct vertex_header *out = vertices; + const float *scale = pvs->draw->viewport.scale; + const float *trans = pvs->draw->viewport.translate; + unsigned j; + + debug_printf("%s\n", __FUNCTION__); + for (j = 0; j < count; j++) { + /* Viewport mapping only, no cliptest/rhw divide + */ + out->data[0][0] = out->data[0][0] * scale[0] + trans[0]; + out->data[0][1] = out->data[0][1] * scale[1] + trans[1]; + out->data[0][2] = out->data[0][2] * scale[2] + trans[2]; + + out = (struct vertex_header *)((char *)out + stride); + } + + return FALSE; +} + + +/* If bypass_clipping is set and we have an identity viewport, nothing + * to do. + */ +static boolean post_vs_none( struct pt_post_vs *pvs, + struct vertex_header *vertices, + unsigned count, + unsigned stride ) +{ + debug_printf("%s\n", __FUNCTION__); + return FALSE; +} + +boolean draw_pt_post_vs_run( struct pt_post_vs *pvs, + struct vertex_header *pipeline_verts, + unsigned count, + unsigned stride ) +{ + return pvs->run( pvs, pipeline_verts, count, stride ); +} + + +void draw_pt_post_vs_prepare( struct pt_post_vs *pvs, + boolean bypass_clipping, + boolean identity_viewport, + boolean opengl ) +{ + if (bypass_clipping) { + if (identity_viewport) + pvs->run = post_vs_none; + else + pvs->run = post_vs_viewport; + } + else { + //if (opengl) + pvs->run = post_vs_cliptest_viewport_gl; + } +} + + +struct pt_post_vs *draw_pt_post_vs_create( struct draw_context *draw ) +{ + struct pt_post_vs *pvs = CALLOC_STRUCT( pt_post_vs ); + if (!pvs) + return NULL; + + pvs->draw = draw; + + return pvs; +} + +void draw_pt_post_vs_destroy( struct pt_post_vs *pvs ) +{ + FREE(pvs); +} diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 0e05b79715..184151b9b1 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -58,8 +58,10 @@ static void vs_exec_prepare( struct draw_vertex_shader *shader, struct draw_context *draw ) { + struct exec_vertex_shader *evs = exec_vertex_shader(shader); + /* specify the vertex program to interpret/execute */ - tgsi_exec_machine_bind_shader(&draw->machine, + tgsi_exec_machine_bind_shader(evs->machine, shader->state.tokens, PIPE_MAX_SAMPLERS, NULL /*samplers*/ ); @@ -84,31 +86,45 @@ vs_exec_run( struct draw_vertex_shader *shader, void *vOut, unsigned vertex_size) { - struct tgsi_exec_machine *machine = &draw->machine; + struct exec_vertex_shader *evs = exec_vertex_shader(shader); + struct tgsi_exec_machine *machine = evs->machine; unsigned int i, j; unsigned int clipped = 0; - - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); + struct tgsi_exec_vector *outputs = 0; const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; assert(shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); machine->Consts = (const float (*)[4]) draw->user.constants; - machine->Inputs = ALIGN16_ASSIGN(inputs); + if (draw->rasterizer->bypass_vs) { /* outputs are just the inputs */ - machine->Outputs = machine->Inputs; + outputs = machine->Inputs; } else { - machine->Outputs = ALIGN16_ASSIGN(outputs); + outputs = machine->Outputs; } for (i = 0; i < count; i += MAX_TGSI_VERTICES) { unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); draw->vertex_fetch.fetch_func( draw, machine, &elts[i], max_vertices ); +#if 0 + for (j = 0; j < max_vertices; j++) { + unsigned slot; + debug_printf("%d) Input vert:\n", i + j); + for (slot = 0; slot < shader->info.num_inputs; slot++) { + debug_printf("\t%d: %f %f %f %f\n", slot, + machine->Inputs[slot].xyzw[0].f[j], + machine->Inputs[slot].xyzw[1].f[j], + machine->Inputs[slot].xyzw[2].f[j], + machine->Inputs[slot].xyzw[3].f[j]); + } + } +#endif + + if (!draw->rasterizer->bypass_vs) { /* run interpreter */ tgsi_exec_machine_run( machine ); @@ -127,10 +143,10 @@ vs_exec_run( struct draw_vertex_shader *shader, * program as a set of DP4 instructions appended to the * user-provided code. */ - x = out->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = out->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = out->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = out->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + x = out->clip[0] = outputs[0].xyzw[0].f[j]; + y = out->clip[1] = outputs[0].xyzw[1].f[j]; + z = out->clip[2] = outputs[0].xyzw[2].f[j]; + w = out->clip[3] = outputs[0].xyzw[3].f[j]; if (!draw->rasterizer->bypass_clipping) { out->clipmask = compute_clipmask(out->clip, draw->plane, @@ -156,7 +172,8 @@ vs_exec_run( struct draw_vertex_shader *shader, out->data[0][2] = z * scale[2] + trans[2]; out->data[0][3] = w; } - else { + else + { out->data[0][0] = x; out->data[0][1] = y; out->data[0][2] = z; @@ -167,10 +184,10 @@ vs_exec_run( struct draw_vertex_shader *shader, * vertex attrib slots. */ for (slot = 1; slot < draw->num_vs_outputs; slot++) { - out->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - out->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - out->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - out->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + out->data[slot][0] = outputs[slot].xyzw[0].f[j]; + out->data[slot][1] = outputs[slot].xyzw[1].f[j]; + out->data[slot][2] = outputs[slot].xyzw[2].f[j]; + out->data[slot][3] = outputs[slot].xyzw[3].f[j]; } #if 0 /*DEBUG*/ @@ -216,12 +233,25 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, /* Swizzle inputs. */ for (j = 0; j < max_vertices; j++) { +#if 0 + debug_printf("%d) Input vert:\n", i + j); + for (slot = 0; slot < shader->info.num_inputs; slot++) { + debug_printf("\t%d: %f %f %f %f\n", slot, + input[slot][0], + input[slot][1], + input[slot][2], + input[slot][3]); + } +#endif + for (slot = 0; slot < shader->info.num_inputs; slot++) { machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; } + + input = (const float (*)[4])((const char *)input + input_stride); } /* run interpreter */ @@ -235,13 +265,23 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + +#if 0 + debug_printf("%d) Post xform vert:\n", i + j); + for (slot = 0; slot < shader->info.num_outputs; slot++) { + debug_printf("\t%d: %f %f %f %f\n", slot, + output[slot][0], + output[slot][1], + output[slot][2], + output[slot][3]); + } +#endif + + output = (float (*)[4])((char *)output + output_stride); } - /* Advance input, output pointers: - */ - input = (const float (*)[4])((const char *)input + input_stride); - output = (float (*)[4])((char *)output + output_stride); } } diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index d0baca715e..4dbfa955a4 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -47,6 +47,7 @@ struct draw_llvm_vertex_shader { struct draw_vertex_shader base; struct gallivm_prog *llvm_prog; + struct tgsi_exec_machine *machine; }; @@ -77,12 +78,9 @@ vs_llvm_run( struct draw_vertex_shader *base, struct draw_llvm_vertex_shader *shader = (struct draw_llvm_vertex_shader *)base; - struct tgsi_exec_machine *machine = &draw->machine; + struct tgsi_exec_machine *machine = shader->machine; unsigned int j; unsigned int clipped = 0; - - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; @@ -93,13 +91,12 @@ vs_llvm_run( struct draw_vertex_shader *base, /* Consts does not require 16 byte alignment. */ machine->Consts = (float (*)[4]) draw->user.constants; - machine->Inputs = ALIGN16_ASSIGN(inputs); if (draw->rasterizer->bypass_vs) { /* outputs are just the inputs */ - machine->Outputs = machine->Inputs; + outputs = machine->Inputs; } else { - machine->Outputs = ALIGN16_ASSIGN(outputs); + outputs = machine->Outputs; } @@ -119,10 +116,10 @@ vs_llvm_run( struct draw_vertex_shader *base, unsigned slot; float x, y, z, w; - x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + x = vOut[j]->clip[0] = outputs[0].xyzw[0].f[j]; + y = vOut[j]->clip[1] = outputs[0].xyzw[1].f[j]; + z = vOut[j]->clip[2] = outputs[0].xyzw[2].f[j]; + w = vOut[j]->clip[3] = outputs[0].xyzw[3].f[j]; if (!draw->rasterizer->bypass_clipping) { vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, @@ -159,10 +156,10 @@ vs_llvm_run( struct draw_vertex_shader *base, * vertex attrib slots. */ for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + vOut[j]->data[slot][0] = outputs[slot].xyzw[0].f[j]; + vOut[j]->data[slot][1] = outputs[slot].xyzw[1].f[j]; + vOut[j]->data[slot][2] = outputs[slot].xyzw[2].f[j]; + vOut[j]->data[slot][3] = outputs[slot].xyzw[3].f[j]; } } /* loop over vertices */ return clipped != 0; @@ -183,7 +180,7 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, struct draw_llvm_vertex_shader *shader = (struct draw_llvm_vertex_shader *)base; - struct tgsi_exec_machine *machine = &draw->machine; + struct tgsi_exec_machine *machine = shader->machine; unsigned int j; @@ -199,6 +196,8 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; } + + input = (const float (*)[4])((const char *)input + input_stride); } /* run shader */ @@ -216,12 +215,9 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; - } - /* Advance input, output pointers: - */ - input = (const float (*)[4])((const char *)input + input_stride); - output = (float (*)[4])((char *)output + output_stride); + output = (float (*)[4])((char *)output + output_stride); + } } } @@ -263,6 +259,7 @@ draw_create_vs_llvm(struct draw_context *draw, vs->base.run = vs_llvm_run; vs->base.run_linear = vs_llvm_run_linear; vs->base.delete = vs_llvm_delete; + vs->machine = &draw->machine; { struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 873ecfdc5d..a763f3845c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -91,12 +91,10 @@ vs_sse_run( struct draw_vertex_shader *base, unsigned vertex_size ) { struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; - struct tgsi_exec_machine *machine = &draw->machine; + struct tgsi_exec_machine *machine = shader->machine; unsigned int i, j; unsigned int clipped = 0; - - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); + struct tgsi_exec_vector *outputs = 0; const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; @@ -104,13 +102,13 @@ vs_sse_run( struct draw_vertex_shader *base, /* Consts does not require 16 byte alignment. */ machine->Consts = (const float (*)[4]) draw->user.constants; - machine->Inputs = ALIGN16_ASSIGN(inputs); + if (draw->rasterizer->bypass_vs) { /* outputs are just the inputs */ - machine->Outputs = machine->Inputs; + outputs = machine->Inputs; } else { - machine->Outputs = ALIGN16_ASSIGN(outputs); + outputs = machine->Outputs; } for (i = 0; i < count; i += SSE_MAX_VERTICES) { @@ -142,10 +140,10 @@ vs_sse_run( struct draw_vertex_shader *base, struct vertex_header *out = draw_header_from_block(vOut, vertex_size, i + j); - x = out->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = out->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = out->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = out->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + x = out->clip[0] = outputs[0].xyzw[0].f[j]; + y = out->clip[1] = outputs[0].xyzw[1].f[j]; + z = out->clip[2] = outputs[0].xyzw[2].f[j]; + w = out->clip[3] = outputs[0].xyzw[3].f[j]; if (!draw->rasterizer->bypass_clipping) { out->clipmask = compute_clipmask(out->clip, draw->plane, @@ -182,10 +180,10 @@ vs_sse_run( struct draw_vertex_shader *base, * vertex attrib slots. */ for (slot = 1; slot < draw->num_vs_outputs; slot++) { - out->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - out->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - out->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - out->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + out->data[slot][0] = outputs[slot].xyzw[0].f[j]; + out->data[slot][1] = outputs[slot].xyzw[1].f[j]; + out->data[slot][2] = outputs[slot].xyzw[2].f[j]; + out->data[slot][3] = outputs[slot].xyzw[3].f[j]; } #if 0 /*DEBUG*/ printf("%d) Post xform vert:\n", i + j); @@ -233,6 +231,8 @@ vs_sse_run_linear( struct draw_vertex_shader *base, machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; } + + input = (const float (*)[4])((const char *)input + input_stride); } /* run compiled shader @@ -253,12 +253,9 @@ vs_sse_run_linear( struct draw_vertex_shader *base, output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; } - } - /* Advance input, output pointers: - */ - input = (const float (*)[4])((const char *)input + input_stride); - output = (float (*)[4])((char *)output + output_stride); + output = (float (*)[4])((char *)output + output_stride); + } } } @@ -300,6 +297,7 @@ draw_create_vs_sse(struct draw_context *draw, vs->base.run = vs_sse_run; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; + vs->machine = &draw->machine; x86_init_func( &vs->sse2_program ); -- cgit v1.2.3 From da9079b936684f88da79425a810d7902e4d6e7ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 18 Apr 2008 20:59:28 +0900 Subject: gallium: Add missing files to scons. --- src/gallium/auxiliary/draw/SConscript | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 62e0cd9e50..0274d48e7f 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -6,24 +6,23 @@ draw = env.ConvenienceLibrary( 'draw_aaline.c', 'draw_aapoint.c', 'draw_clip.c', - 'draw_vs_exec.c', - 'draw_vs_sse.c', - 'draw_vs_llvm.c', 'draw_context.c', 'draw_cull.c', 'draw_debug.c', 'draw_flatshade.c', 'draw_offset.c', + 'draw_prim.c', + 'draw_pstipple.c', 'draw_pt.c', - 'draw_pt_vcache.c', + 'draw_pt_elts.c', 'draw_pt_emit.c', + 'draw_pt_fetch.c', 'draw_pt_fetch_emit.c', 'draw_pt_fetch_pipeline.c', 'draw_pt_fetch_shade_pipeline.c', 'draw_pt_pipeline.c', - 'draw_pt_elts.c', - 'draw_prim.c', - 'draw_pstipple.c', + 'draw_pt_post_vs.c', + 'draw_pt_vcache.c', 'draw_stipple.c', 'draw_twoside.c', 'draw_unfilled.c', @@ -36,8 +35,11 @@ draw = env.ConvenienceLibrary( 'draw_vf.c', 'draw_vf_generic.c', 'draw_vf_sse.c', + 'draw_vs_exec.c', + 'draw_vs_llvm.c', + 'draw_vs_sse.c', + 'draw_wide_line.c', 'draw_wide_point.c', - 'draw_wide_line.c' ]) auxiliaries.insert(0, draw) -- cgit v1.2.3 From 5b97c762ed9882dd922f48c2fbf13b14ad86a96e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 17:32:39 +0100 Subject: rtasm: add a couple more insns, clean up x86_mul --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 34 ++++++++++++++++++++++++------ src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 2 ++ 2 files changed, 29 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index aea8b28e58..5c25fa155d 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -33,11 +33,6 @@ #define DISASSEM 0 #define X86_TWOB 0x0f -static unsigned char *cptr( void (*label)() ) -{ - return (unsigned char *) label; -} - static void do_realloc( struct x86_function *p ) { @@ -304,6 +299,11 @@ void x86_jmp( struct x86_function *p, unsigned char *label) } #if 0 +static unsigned char *cptr( void (*label)() ) +{ + return (unsigned char *) label; +} + /* This doesn't work once we start reallocating & copying the * generated code on buffer fills, because the call is relative to the * current pc. @@ -417,11 +417,14 @@ void x86_add( struct x86_function *p, emit_op_modrm(p, 0x03, 0x01, dst, src ); } +/* Calculate EAX * src, results in EDX:EAX. + */ void x86_mul( struct x86_function *p, struct x86_reg src ) { - assert (src.file == file_REG32 && src.mod == mod_REG); - emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src ); +// assert (src.file == file_REG32 && src.mod == mod_REG); + emit_1ub(p, 0xf7); + emit_modrm_noreg(p, 4, src ); } void x86_sub( struct x86_function *p, @@ -646,6 +649,14 @@ void sse_cvtps2pi( struct x86_function *p, emit_modrm( p, dst, src ); } +void sse2_cvtdq2ps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5b); + emit_modrm( p, dst, src ); +} + /* Shufps can also be used to implement a reduced swizzle when dest == * arg0. @@ -735,6 +746,15 @@ void sse2_packuswb( struct x86_function *p, emit_modrm( p, dst, src ); } +void sse2_punpcklbw( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x60); + emit_modrm( p, dst, src ); +} + + void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index 606b41eb35..dfde661f46 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -165,6 +165,7 @@ void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg sr void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_cvtdq2ps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); @@ -202,6 +203,7 @@ void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, unsigned char shuf ); void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src ); +void sse2_punpcklbw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -- cgit v1.2.3 From f631bebe1a05c8af863e514546763433343b7c53 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 17:34:55 +0100 Subject: softpipe: fix const-related compiler warnings --- src/gallium/drivers/softpipe/sp_fs_sse.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 5ef02a7142..f857d26143 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -49,7 +49,7 @@ typedef void (XSTDCALL *codegen_function)( const struct tgsi_exec_vector *input, struct tgsi_exec_vector *output, - float (*constant)[4], + const float (*constant)[4], struct tgsi_exec_vector *temporary, const struct tgsi_interp_coef *coef, float (*immediates)[4] @@ -67,9 +67,9 @@ struct sp_sse_fragment_shader { static void -fs_sse_prepare( struct sp_fragment_shader *base, - struct tgsi_exec_machine *machine, - struct tgsi_sampler *samplers ) +fs_sse_prepare( const struct sp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct tgsi_sampler *samplers ) { } @@ -80,9 +80,9 @@ fs_sse_prepare( struct sp_fragment_shader *base, * TODO: process >1 quad at a time */ static unsigned -fs_sse_run( struct sp_fragment_shader *base, - struct tgsi_exec_machine *machine, - struct quad_header *quad ) +fs_sse_run( const struct sp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct quad_header *quad ) { struct sp_sse_fragment_shader *shader = (struct sp_sse_fragment_shader *) base; -- cgit v1.2.3 From c5f0158a9179463593d63b33cf3b5490167faac9 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 17:35:32 +0100 Subject: tgsi: add const qualifier to tokens on sse emit --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2 +- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index c37e201b2b..0a3a7559ca 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -2332,7 +2332,7 @@ emit_declaration( */ unsigned tgsi_emit_sse2( - struct tgsi_token *tokens, + const struct tgsi_token *tokens, struct x86_function *func, float (*immediates)[4]) { diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h index d56bf7f98a..063287dc5e 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h @@ -10,7 +10,7 @@ struct x86_function; unsigned tgsi_emit_sse2( - struct tgsi_token *tokens, + const struct tgsi_token *tokens, struct x86_function *function, float (*immediates)[4] ); -- cgit v1.2.3 From 363f7abf2000c1cf5993ae8f83ba81b2054bf6e0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 18:30:41 +0100 Subject: rtasm: add x86_imul --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 11 ++++++++++- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 5c25fa155d..7f8cc23d15 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -422,11 +422,20 @@ void x86_add( struct x86_function *p, void x86_mul( struct x86_function *p, struct x86_reg src ) { -// assert (src.file == file_REG32 && src.mod == mod_REG); emit_1ub(p, 0xf7); emit_modrm_noreg(p, 4, src ); } + +void x86_imul( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0xAF); + emit_modrm(p, dst, src); +} + + void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index dfde661f46..5e99ceea70 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -213,6 +213,7 @@ void x86_inc( struct x86_function *p, struct x86_reg reg ); void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_mul( struct x86_function *p, struct x86_reg src ); +void x86_imul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_pop( struct x86_function *p, struct x86_reg reg ); void x86_push( struct x86_function *p, struct x86_reg reg ); -- cgit v1.2.3 From 7400bc4b6fb0c20a935cd108afa92814eeafec6d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 18:31:45 +0100 Subject: translate: add sse version based on old draw_vf_sse.c --- src/gallium/auxiliary/draw/draw_pt_emit.c | 2 +- src/gallium/auxiliary/draw/draw_pt_fetch.c | 2 +- src/gallium/auxiliary/translate/Makefile | 4 +- src/gallium/auxiliary/translate/SConscript | 2 + src/gallium/auxiliary/translate/translate.h | 4 + src/gallium/auxiliary/translate/translate_sse.c | 615 ++++++++++++++++++++++++ 6 files changed, 626 insertions(+), 3 deletions(-) create mode 100644 src/gallium/auxiliary/translate/translate_sse.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index ef9db70a02..a6a3ff6cac 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -127,7 +127,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, if (emit->translate) emit->translate->release(emit->translate); - emit->translate = translate_generic_create( &hw_key ); + emit->translate = translate_create( &hw_key ); } } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index a7553023b8..1aed251c85 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -119,7 +119,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, if (fetch->translate) fetch->translate->release(fetch->translate); - fetch->translate = translate_generic_create( &key ); + fetch->translate = translate_create( &key ); if (emit_header) { static struct vertex_header vh = { 0, 0, 0, 0xffff }; diff --git a/src/gallium/auxiliary/translate/Makefile b/src/gallium/auxiliary/translate/Makefile index 051987bb7e..39dfb0de30 100644 --- a/src/gallium/auxiliary/translate/Makefile +++ b/src/gallium/auxiliary/translate/Makefile @@ -4,7 +4,9 @@ include $(TOP)/configs/current LIBNAME = translate C_SOURCES = \ - translate_generic.c + translate_generic.c \ + translate_sse.c \ + translate.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/translate/SConscript b/src/gallium/auxiliary/translate/SConscript index 42513ba3b0..7608908915 100644 --- a/src/gallium/auxiliary/translate/SConscript +++ b/src/gallium/auxiliary/translate/SConscript @@ -4,6 +4,8 @@ translate = env.ConvenienceLibrary( target = 'translate', source = [ 'translate_generic.c', + 'translate_sse.c', + 'translate.c', ]) auxiliaries.insert(0, translate) diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index 4f9f40e51a..d95d1ac4f3 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -42,6 +42,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" +#include "pipe/p_state.h" struct translate_element { @@ -93,6 +94,9 @@ struct translate *translate_lookup_or_create( struct translate_context *tctx, #endif +struct translate *translate_create( const struct translate_key *key ); + + /******************************************************************************* * Private: */ diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c new file mode 100644 index 0000000000..cb8815c173 --- /dev/null +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -0,0 +1,615 @@ +/* + * Copyright 2003 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_util.h" +#include "util/u_simple_list.h" + +#include "translate.h" + + +#if defined(__i386__) || defined(__386__) || defined(i386) + +#include "rtasm/rtasm_cpu.h" +#include "rtasm/rtasm_x86sse.h" + + +#define X 0 +#define Y 1 +#define Z 2 +#define W 3 + + +typedef void (*run_func)( struct translate *translate, + unsigned start, + unsigned count, + void *output_buffer ); + +typedef void (*run_elts_func)( struct translate *translate, + const unsigned *elts, + unsigned count, + void *output_buffer ); + + + +struct translate_sse { + struct translate translate; + + struct x86_function linear_func; + struct x86_function elt_func; + struct x86_function *func; + + boolean loaded_identity; + boolean loaded_255; + boolean loaded_inv_255; + + float identity[4]; + float float_255[4]; + float inv_255[4]; + + struct { + char *input_ptr; + unsigned input_stride; + } attrib[PIPE_MAX_ATTRIBS]; + + run_func gen_run; + run_elts_func gen_run_elts; + +}; + +static int get_offset( const void *a, const void *b ) +{ + return (const char *)b - (const char *)a; +} + + + +static struct x86_reg get_identity( struct translate_sse *p ) +{ + struct x86_reg reg = x86_make_reg(file_XMM, 6); + + if (!p->loaded_identity) { + /* Nasty: + */ + struct x86_reg translateESI = x86_make_reg(file_REG32, reg_SI); + + p->loaded_identity = TRUE; + p->identity[0] = 0; + p->identity[1] = 0; + p->identity[2] = 0; + p->identity[3] = 1; + + sse_movups(p->func, reg, + x86_make_disp(translateESI, + get_offset(p, &p->identity[0]))); + } + + return reg; +} + +static struct x86_reg get_255( struct translate_sse *p ) +{ + struct x86_reg reg = x86_make_reg(file_XMM, 6); + + if (!p->loaded_255) { + struct x86_reg translateESI = x86_make_reg(file_REG32, reg_SI); + + p->loaded_255 = TRUE; + p->float_255[0] = + p->float_255[1] = + p->float_255[2] = + p->float_255[3] = 255.0f; + + sse_movups(p->func, reg, + x86_make_disp(translateESI, + get_offset(p, &p->float_255[0]))); + } + + return reg; + return x86_make_reg(file_XMM, 7); +} + +static struct x86_reg get_inv_255( struct translate_sse *p ) +{ + struct x86_reg reg = x86_make_reg(file_XMM, 5); + + if (!p->loaded_inv_255) { + struct x86_reg translateESI = x86_make_reg(file_REG32, reg_SI); + + p->loaded_inv_255 = TRUE; + p->inv_255[0] = + p->inv_255[1] = + p->inv_255[2] = + p->inv_255[3] = 1.0 / 255.0f; + + sse_movups(p->func, reg, + x86_make_disp(translateESI, + get_offset(p, &p->inv_255[0]))); + } + + return reg; +} + + +static void emit_load_R32G32B32A32( struct translate_sse *p, + struct x86_reg data, + struct x86_reg arg0 ) +{ + sse_movups(p->func, data, arg0); +} + +static void emit_load_R32G32B32( struct translate_sse *p, + struct x86_reg data, + struct x86_reg arg0 ) +{ + /* Have to jump through some hoops: + * + * c 0 0 0 + * c 0 0 1 + * 0 0 c 1 + * a b c 1 + */ + sse_movss(p->func, data, x86_make_disp(arg0, 8)); + sse_shufps(p->func, data, get_identity(p), SHUF(X,Y,Z,W) ); + sse_shufps(p->func, data, data, SHUF(Y,Z,X,W) ); + sse_movlps(p->func, data, arg0); +} + +static void emit_load_R32G32( struct translate_sse *p, + struct x86_reg data, + struct x86_reg arg0 ) +{ + /* 0 0 0 1 + * a b 0 1 + */ + sse_movups(p->func, data, get_identity(p) ); + sse_movlps(p->func, data, arg0); +} + + +static void emit_load_R32( struct translate_sse *p, + struct x86_reg data, + struct x86_reg arg0 ) +{ + /* a 0 0 0 + * a 0 0 1 + */ + sse_movss(p->func, data, arg0); + sse_orps(p->func, data, get_identity(p) ); +} + + +static void emit_load_R8G8B8A8_UNORM( struct translate_sse *p, + struct x86_reg data, + struct x86_reg src ) +{ + + /* Load and unpack twice: + */ + sse_movss(p->func, data, src); + sse2_punpcklbw(p->func, src, get_identity(p)); + sse2_punpcklbw(p->func, src, get_identity(p)); + + /* Convert to float: + */ + sse2_cvtdq2ps(p->func, src, src); + + + /* Scale by 1/255.0 + */ + sse_mulps(p->func, src, get_inv_255(p)); +} + + + + +static void emit_store_R32G32B32A32( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg dataXMM ) +{ + sse_movups(p->func, dest, dataXMM); +} + +static void emit_store_R32G32B32( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg dataXMM ) +{ + /* Emit two, shuffle, emit one. + */ + sse_movlps(p->func, dest, dataXMM); + sse_shufps(p->func, dataXMM, dataXMM, SHUF(Z,Z,Z,Z) ); /* NOTE! destructive */ + sse_movss(p->func, x86_make_disp(dest,8), dataXMM); +} + +static void emit_store_R32G32( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg dataXMM ) +{ + sse_movlps(p->func, dest, dataXMM); +} + +static void emit_store_R32( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg dataXMM ) +{ + sse_movss(p->func, dest, dataXMM); +} + + + +static void emit_store_R8G8B8A8_UNORM( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg dataXMM ) +{ + /* Scale by 255.0 + */ + sse_mulps(p->func, dataXMM, get_255(p)); + + /* Pack and emit: + */ + sse2_cvtps2dq(p->func, dataXMM, dataXMM); + sse2_packssdw(p->func, dataXMM, dataXMM); + sse2_packuswb(p->func, dataXMM, dataXMM); + sse_movss(p->func, dest, dataXMM); +} + + + + + +static void get_src_ptr( struct translate_sse *p, + struct x86_reg srcEAX, + struct x86_reg translateREG, + struct x86_reg eltREG, + unsigned a ) +{ + struct x86_reg input_ptr = + x86_make_disp(translateREG, + get_offset(p, &p->attrib[a].input_ptr)); + + struct x86_reg input_stride = + x86_make_disp(translateREG, + get_offset(p, &p->attrib[a].input_stride)); + + /* Calculate pointer to current attrib: + */ + x86_mov(p->func, srcEAX, input_stride); + x86_imul(p->func, srcEAX, eltREG); + x86_add(p->func, srcEAX, input_ptr); +} + + +/* Extended swizzles? Maybe later. + */ +static void emit_swizzle( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg src, + unsigned shuffle ) +{ + sse_shufps(p->func, dest, src, shuffle); +} + + +static boolean translate_attr( struct translate_sse *p, + const struct translate_element *a, + struct x86_reg srcECX, + struct x86_reg dstEAX) +{ + struct x86_reg dataXMM = x86_make_reg(file_XMM, 0); + + switch (a->input_format) { + case PIPE_FORMAT_R32_FLOAT: + emit_load_R32(p, dataXMM, srcECX); + break; + case PIPE_FORMAT_R32G32_FLOAT: + emit_load_R32G32(p, dataXMM, srcECX); + break; + case PIPE_FORMAT_R32G32B32_FLOAT: + emit_load_R32G32B32(p, dataXMM, srcECX); + break; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + emit_load_R32G32B32A32(p, dataXMM, srcECX); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + emit_load_R8G8B8A8_UNORM(p, dataXMM, srcECX); + emit_swizzle(p, dataXMM, dataXMM, SHUF(Z,Y,X,W)); + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + emit_load_R8G8B8A8_UNORM(p, dataXMM, srcECX); + break; + default: + return FALSE; + } + + switch (a->output_format) { + case PIPE_FORMAT_R32_FLOAT: + emit_store_R32(p, dstEAX, dataXMM); + break; + case PIPE_FORMAT_R32G32_FLOAT: + emit_store_R32G32(p, dstEAX, dataXMM); + break; + case PIPE_FORMAT_R32G32B32_FLOAT: + emit_store_R32G32B32(p, dstEAX, dataXMM); + break; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + emit_store_R32G32B32A32(p, dstEAX, dataXMM); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + emit_swizzle(p, dataXMM, dataXMM, SHUF(Z,Y,X,W)); + emit_store_R8G8B8A8_UNORM(p, dstEAX, dataXMM); + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + emit_store_R8G8B8A8_UNORM(p, dstEAX, dataXMM); + break; + default: + return FALSE; + } + + return TRUE; +} + +/* Build run( struct translate *translate, + * unsigned start, + * unsigned count, + * void *output_buffer ) + * or + * run_elts( struct translate *translate, + * unsigned *elts, + * unsigned count, + * void *output_buffer ) + * + * Lots of hardcoding + * + * EAX -- pointer to current output vertex + * ECX -- pointer to current attribute + * + */ +static boolean build_vertex_emit( struct translate_sse *p, + struct x86_function *func, + boolean linear ) +{ + struct x86_reg vertexECX = x86_make_reg(file_REG32, reg_AX); + struct x86_reg idxEBX = x86_make_reg(file_REG32, reg_BX); + struct x86_reg srcEAX = x86_make_reg(file_REG32, reg_CX); + struct x86_reg countEBP = x86_make_reg(file_REG32, reg_BP); + struct x86_reg translateESI = x86_make_reg(file_REG32, reg_SI); + uint8_t *fixup, *label; + unsigned j; + + p->func = func; + p->loaded_inv_255 = FALSE; + p->loaded_255 = FALSE; + p->loaded_identity = FALSE; + + x86_init_func(p->func); + + /* Push a few regs? + */ + x86_push(p->func, countEBP); + x86_push(p->func, translateESI); + x86_push(p->func, idxEBX); + + /* Get vertex count, compare to zero + */ + x86_xor(p->func, idxEBX, idxEBX); + x86_mov(p->func, countEBP, x86_fn_arg(p->func, 3)); + x86_cmp(p->func, countEBP, idxEBX); + fixup = x86_jcc_forward(p->func, cc_E); + + /* If linear, idx is the current element, otherwise it is a pointer + * to the current element. + */ + x86_mov(p->func, idxEBX, x86_fn_arg(p->func, 2)); + + /* Initialize destination register. + */ + x86_mov(p->func, vertexECX, x86_fn_arg(p->func, 4)); + + /* Move argument 1 (translate_sse pointer) into a reg: + */ + x86_mov(p->func, translateESI, x86_fn_arg(p->func, 1)); + + + /* always load, needed or not: + */ + + /* Note address for loop jump */ + label = x86_get_label(p->func); + + + for (j = 0; j < p->translate.key.nr_elements; j++) { + const struct translate_element *a = &p->translate.key.element[j]; + + struct x86_reg destEAX = x86_make_disp(vertexECX, + a->output_offset); + + /* Figure out source pointer address: + */ + if (linear) { + get_src_ptr(p, srcEAX, translateESI, idxEBX, j); + } + else { + get_src_ptr(p, srcEAX, translateESI, x86_deref(idxEBX), j); + } + + if (!translate_attr( p, a, x86_deref(srcEAX), destEAX )) + return FALSE; + } + + /* Next vertex: + */ + x86_lea(p->func, vertexECX, x86_make_disp(vertexECX, p->translate.key.output_stride)); + + /* Incr index + */ /* Emit code for each of the attributes. Currently routes + * everything through SSE registers, even when it might be more + * efficient to stick with regular old x86. No optimization or + * other tricks - enough new ground to cover here just getting + * things working. + */ + + if (linear) { + x86_inc(p->func, idxEBX); + } + else { + x86_lea(p->func, idxEBX, x86_make_disp(idxEBX, 4)); + } + + /* decr count, loop if not zero + */ + x86_dec(p->func, countEBP); + x86_test(p->func, countEBP, countEBP); + x86_jcc(p->func, cc_NZ, label); + + /* Exit mmx state? + */ + if (p->func->need_emms) + mmx_emms(p->func); + + /* Land forward jump here: + */ + x86_fixup_fwd_jump(p->func, fixup); + + /* Pop regs and return + */ + + x86_pop(p->func, idxEBX); + x86_pop(p->func, translateESI); + x86_pop(p->func, countEBP); + x86_ret(p->func); + + return TRUE; +} + + + + + + + +static void translate_sse_set_buffer( struct translate *translate, + unsigned buf, + const void *ptr, + unsigned stride ) +{ + struct translate_sse *p = (struct translate_sse *)translate; + unsigned i; + + for (i = 0; i < p->translate.key.nr_elements; i++) { + if (p->translate.key.element[i].input_buffer == buf) { + p->attrib[i].input_ptr = ((char *)ptr + + p->translate.key.element[i].input_offset); + p->attrib[i].input_stride = stride; + } + } +} + + +static void translate_sse_release( struct translate *translate ) +{ + struct translate_sse *p = (struct translate_sse *)translate; + + x86_release_func( &p->linear_func ); + x86_release_func( &p->elt_func ); + + FREE(p); +} + +static void translate_sse_run_elts( struct translate *translate, + const unsigned *elts, + unsigned count, + void *output_buffer ) +{ + struct translate_sse *p = (struct translate_sse *)translate; + + p->gen_run_elts( translate, + elts, + count, + output_buffer ); + +} + +static void translate_sse_run( struct translate *translate, + unsigned start, + unsigned count, + void *output_buffer ) +{ + struct translate_sse *p = (struct translate_sse *)translate; + + p->gen_run( translate, + start, + count, + output_buffer ); +} + + +struct translate *translate_sse2_create( const struct translate_key *key ) +{ + struct translate_sse *p = CALLOC_STRUCT( translate_sse ); + + if (p == NULL) + goto fail; + + if (!rtasm_cpu_has_sse() || !rtasm_cpu_has_sse2()) + goto fail; + + + p->translate.key = *key; + p->translate.release = translate_sse_release; + p->translate.set_buffer = translate_sse_set_buffer; + p->translate.run_elts = translate_sse_run_elts; + p->translate.run = translate_sse_run; + + if (!build_vertex_emit(p, &p->linear_func, TRUE)) + goto fail; + + if (!build_vertex_emit(p, &p->elt_func, FALSE)) + goto fail; + + p->gen_run = (run_func)x86_get_func(&p->linear_func); + p->gen_run_elts = (run_elts_func)x86_get_func(&p->elt_func); + + return &p->translate; + + fail: + if (p) + p->translate.release( &p->translate ); + + return NULL; +} + + + +#else + +void translate_create_sse( const struct translate_key *key ) +{ + return NULL; +} + +#endif -- cgit v1.2.3 From 26c27f6636069ca849a740c3969c577d841484e2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 18:42:41 +0100 Subject: draw: remove fetch_pipeline middle end -- just use the general path --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/SConscript | 1 - src/gallium/auxiliary/draw/draw_pt.c | 4 - src/gallium/auxiliary/draw/draw_pt.h | 26 +- .../auxiliary/draw/draw_pt_fetch_pipeline.c | 327 --------------------- 5 files changed, 15 insertions(+), 344 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 154c8a99b5..916e134719 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -18,7 +18,6 @@ C_SOURCES = \ draw_pt.c \ draw_pt_vcache.c \ draw_pt_fetch_emit.c \ - draw_pt_fetch_pipeline.c \ draw_pt_fetch_shade_pipeline.c \ draw_pt_fetch.c \ draw_pt_post_vs.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 0274d48e7f..6dc0195d93 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -18,7 +18,6 @@ draw = env.ConvenienceLibrary( 'draw_pt_emit.c', 'draw_pt_fetch.c', 'draw_pt_fetch_emit.c', - 'draw_pt_fetch_pipeline.c', 'draw_pt_fetch_shade_pipeline.c', 'draw_pt_pipeline.c', 'draw_pt_post_vs.c', diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 60a47f3911..b48d0cae9f 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -106,10 +106,6 @@ boolean draw_pt_init( struct draw_context *draw ) return FALSE; draw->pt.middle.opt[0] = draw_pt_fetch_emit( draw ); - draw->pt.middle.opt[PT_PIPELINE] = draw_pt_fetch_pipeline( draw ); -// draw->pt.middle.opt[PT_SHADE] = draw_pt_shade_emit( draw ); -// draw->pt.middle.opt[PT_SHADE | PT_PIPELINE] = draw_pt_shade_pipeline( draw ); -// draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST] = draw_pt_shade_clip_either( draw ); draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE] = draw_pt_fetch_pipeline_or_emit( draw ); diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 316289969b..eb23ee1c1e 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -83,11 +83,6 @@ struct draw_pt_front_end { * Currently two versions of this: * - fetch, vertex shade, cliptest, prim-pipeline * - fetch, emit (ie passthrough) - * Later: - * - fetch, vertex shade, cliptest, maybe-pipeline, maybe-emit - * - fetch, vertex shade, emit - * - * Currenly only using the passthrough version. */ struct draw_pt_middle_end { void (*prepare)( struct draw_pt_middle_end *, @@ -106,10 +101,6 @@ struct draw_pt_middle_end { /* The "back end" - supplied by the driver, defined in draw_vbuf.h. - * - * Not sure whether to wrap the prim pipeline up as an alternate - * backend. Would be a win for everything except pure passthrough - * mode... */ struct vbuf_render; struct vertex_header; @@ -121,11 +112,24 @@ pt_elt_func draw_pt_elt_func( struct draw_context *draw ); const void *draw_pt_elt_ptr( struct draw_context *draw, unsigned start ); -/* Implementations: +/* Frontends: + * + * Currently only the general-purpose vcache implementation, could add + * a special case for tiny vertex buffers. */ struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ); + +/* Middle-ends: + * + * Currently one general-purpose case which can do all possibilities, + * at the slight expense of creating a vertex_header in some cases + * unecessarily. + * + * The special case fetch_emit code avoids pipeline vertices + * altogether and builds hardware vertices directly from API + * vertex_elements. + */ struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ); -struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c deleted file mode 100644 index 26d0b37286..0000000000 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ /dev/null @@ -1,327 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "draw/draw_vertex.h" -#include "draw/draw_pt.h" -#include "draw/draw_vs.h" - -/* The simplest 'middle end' in the new vertex code. - * - * The responsibilities of a middle end are to: - * - perform vertex fetch using - * - draw vertex element/buffer state - * - a list of fetch indices we received as an input - * - run the vertex shader - * - cliptest, - * - clip coord calculation - * - viewport transformation - * - if necessary, run the primitive pipeline, passing it: - * - a linear array of vertex_header vertices constructed here - * - a set of draw indices we received as an input - * - otherwise, drive the hw backend, - * - allocate space for hardware format vertices - * - translate the vertex-shader output vertices to hw format - * - calling the backend draw functions. - * - * For convenience, we provide a helper function to drive the hardware - * backend given similar inputs to those required to run the pipeline. - * - * In the case of passthrough mode, many of these actions are disabled - * or noops, so we end up doing: - * - * - perform vertex fetch - * - drive the hw backend - * - * IE, basically just vertex fetch to post-vs-format vertices, - * followed by a call to the backend helper function. - */ - - -struct fetch_pipeline_middle_end { - struct draw_pt_middle_end base; - struct draw_context *draw; - - void (*header)( unsigned idx, float **out); - - struct { - const ubyte *ptr; - unsigned pitch; - void (*fetch)( const void *from, float *attrib); - void (*emit)( const float *attrib, float **out ); - } fetch[PIPE_MAX_ATTRIBS]; - - unsigned nr_fetch; - unsigned pipeline_vertex_size; - unsigned prim; -}; - - -#if 0 -static void emit_R32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out) += 1; -} - -static void emit_R32G32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out) += 2; -} - -static void emit_R32G32B32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out) += 3; -} -#endif -static void emit_R32G32B32A32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out)[3] = attrib[3]; - (*out) += 4; -} - -static void header( unsigned idx, - float **out ) -{ - struct vertex_header *header = (struct vertex_header *) (*out); - - header->clipmask = 0; - header->edgeflag = 1; - header->pad = 0; - header->vertex_id = UNDEFINED_VERTEX_ID; - - (*out)[1] = 0; - (*out)[2] = 0; - (*out)[3] = 0; - (*out)[3] = 1; - (*out) += 5; -} - - -static void header_ef( unsigned idx, - float **out ) -{ - struct vertex_header *header = (struct vertex_header *) (*out); - - /* XXX: need a reset_stipple flag in the vertex header too? - */ - header->clipmask = 0; - header->edgeflag = (idx & DRAW_PT_EDGEFLAG) != 0; - header->pad = 0; - header->vertex_id = UNDEFINED_VERTEX_ID; - - (*out)[1] = 0; - (*out)[2] = 0; - (*out)[3] = 0; - (*out)[3] = 1; - (*out) += 5; -} - - -/** - * General-purpose fetch from user's vertex arrays, emit to driver's - * vertex buffer. - * - * XXX this is totally temporary. - */ -static void -fetch_store_general( struct fetch_pipeline_middle_end *fpme, - void *out_ptr, - const unsigned *fetch_elts, - unsigned count ) -{ - float *out = (float *)out_ptr; - uint i, j; - - for (i = 0; i < count; i++) { - unsigned elt = fetch_elts[i]; - - fpme->header( elt, &out ); - elt &= ~DRAW_PT_FLAG_MASK; - - for (j = 0; j < fpme->nr_fetch; j++) { - float attrib[4]; - const ubyte *from = (fpme->fetch[j].ptr + - fpme->fetch[j].pitch * elt); - - fpme->fetch[j].fetch( from, attrib ); - fpme->fetch[j].emit( attrib, &out ); - } - } -} - - -/* We aren't running a vertex shader, but are running the pipeline. - * That means the vertices we need to build look like: - * - * dw0: vertex header (zero?) - * dw1: clip coord 0 - * dw2: clip coord 1 - * dw3: clip coord 2 - * dw4: clip coord 4 - * dw5: screen coord 0 - * dw6: screen coord 0 - * dw7: screen coord 0 - * dw8: screen coord 0 - * dw9: other attribs... - * - */ -static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, - unsigned prim, - unsigned opt ) -{ - struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; - struct draw_context *draw = fpme->draw; - unsigned i, nr = 0; - - fpme->prim = prim; - - /* Emit the vertex header and empty clipspace coord field: - */ - if (draw->user.edgeflag) { - fpme->header = header_ef; - } - else { - fpme->header = header; - } - - - /* Need to look at vertex shader inputs (we know it is a - * passthrough shader, so these define the outputs too). If we - * were running a shader, we'd still be looking at the inputs at - * this point. - */ - for (i = 0; i < draw->vertex_shader->info.num_inputs; i++) { - unsigned buf = draw->vertex_element[i].vertex_buffer_index; - enum pipe_format format = draw->vertex_element[i].src_format; - - fpme->fetch[nr].ptr = ((const ubyte *) draw->user.vbuffer[buf] + - draw->vertex_buffer[buf].buffer_offset + - draw->vertex_element[i].src_offset); - - fpme->fetch[nr].pitch = draw->vertex_buffer[buf].pitch; - fpme->fetch[nr].fetch = draw_get_fetch_func( format ); - - /* Always do this -- somewhat redundant... - */ - fpme->fetch[nr].emit = emit_R32G32B32A32_FLOAT; - nr++; - } - - fpme->nr_fetch = nr; - fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); -} - - - - -static void fetch_pipeline_run( struct draw_pt_middle_end *middle, - const unsigned *fetch_elts, - unsigned fetch_count, - const ushort *draw_elts, - unsigned draw_count ) -{ - struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; - char *pipeline_verts; - - pipeline_verts = MALLOC( fpme->pipeline_vertex_size * - fetch_count ); - if (!pipeline_verts) { - assert(0); - return; - } - - - /* Single routine to fetch vertices and emit pipeline verts. - */ - fetch_store_general( fpme, - pipeline_verts, - fetch_elts, - fetch_count ); - - - /* Run the pipeline - */ - draw_pt_run_pipeline( fpme->draw, - fpme->prim, - (struct vertex_header *)pipeline_verts, - fetch_count, - fpme->pipeline_vertex_size, - draw_elts, - draw_count ); - - - /* Done -- that was easy, wasn't it: - */ - FREE( pipeline_verts ); -} - - - -static void fetch_pipeline_finish( struct draw_pt_middle_end *middle ) -{ - /* nothing to do */ -} - -static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) -{ - FREE(middle); -} - - -struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ) -{ - struct fetch_pipeline_middle_end *fetch_pipeline = CALLOC_STRUCT( fetch_pipeline_middle_end ); - - fetch_pipeline->base.prepare = fetch_pipeline_prepare; - fetch_pipeline->base.run = fetch_pipeline_run; - fetch_pipeline->base.finish = fetch_pipeline_finish; - fetch_pipeline->base.destroy = fetch_pipeline_destroy; - - fetch_pipeline->draw = draw; - - return &fetch_pipeline->base; -} - -- cgit v1.2.3 From 19218e2195f3dffc9403f16a742ba8c63edbf8b4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 18 Apr 2008 11:15:18 -0600 Subject: gallium: implement recip sqrt() with C code for now. Some conformance lighting tests fail with the SSE rsqrt instruction. --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 0a3a7559ca..6f785be3f5 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -36,6 +36,8 @@ #if defined(__i386__) || defined(__386__) +#define HIGH_PRECISION 1 /* for 1/sqrt() */ + #define DUMP_SSE 0 #if DUMP_SSE @@ -1137,16 +1139,44 @@ emit_rcp ( make_xmm( xmm_src ) ); } +#if HIGH_PRECISION +static void XSTDCALL +rsqrt4f( + float *store ) +{ +#ifdef WIN32 + store[0] = 1.0F / (float) sqrt( (double) store[0] ); + store[1] = 1.0F / (float) sqrt( (double) store[1] ); + store[2] = 1.0F / (float) sqrt( (double) store[2] ); + store[3] = 1.0F / (float) sqrt( (double) store[3] ); +#else + const unsigned X = TEMP_R0 * 16; + store[X + 0] = 1.0F / sqrt( store[X + 0] ); + store[X + 1] = 1.0F / sqrt( store[X + 1] ); + store[X + 2] = 1.0F / sqrt( store[X + 2] ); + store[X + 3] = 1.0F / sqrt( store[X + 3] ); +#endif +} +#endif + static void emit_rsqrt( struct x86_function *func, unsigned xmm_dst, unsigned xmm_src ) { +#if HIGH_PRECISION + emit_func_call_dst_src( + func, + xmm_dst, + xmm_src, + rsqrt4f ); +#else emit_rsqrtps( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); +#endif } static void -- cgit v1.2.3 From e430d885e0d819172068805b1492cb6f10eb5d7f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 18 Apr 2008 11:15:53 -0600 Subject: gallium: a few comments --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 6f785be3f5..d47935e982 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -1598,20 +1598,25 @@ emit_instruction( STORE( func, *inst, 0, 0, CHAN_Y ); } if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + /* XMM[1] = SrcReg[0].yyyy */ FETCH( func, *inst, 1, 0, CHAN_Y ); + /* XMM[1] = max(XMM[1], 0) */ emit_maxps( func, make_xmm( 1 ), get_temp( TGSI_EXEC_TEMP_00000000_I, TGSI_EXEC_TEMP_00000000_C ) ); + /* XMM[2] = SrcReg[0].wwww */ FETCH( func, *inst, 2, 0, CHAN_W ); + /* XMM[2] = min(XMM[2], 128.0) */ emit_minps( func, make_xmm( 2 ), get_temp( TGSI_EXEC_TEMP_128_I, TGSI_EXEC_TEMP_128_C ) ); + /* XMM[2] = max(XMM[2], -128.0) */ emit_maxps( func, make_xmm( 2 ), -- cgit v1.2.3 From 7b34a43d1ab74974bd157a2339d7a491aed9c9b4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 18:51:43 +0100 Subject: translate: missing file --- src/gallium/auxiliary/translate/translate.c | 46 +++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/gallium/auxiliary/translate/translate.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate.c b/src/gallium/auxiliary/translate/translate.c new file mode 100644 index 0000000000..86ebeae2a7 --- /dev/null +++ b/src/gallium/auxiliary/translate/translate.c @@ -0,0 +1,46 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_state.h" +#include "translate.h" + +struct translate *translate_create( const struct translate_key *key ) +{ + struct translate *translate = NULL; + + translate = translate_sse2_create( key ); + if (translate) + return translate; + + return translate_generic_create( key ); +} -- cgit v1.2.3 From cb9f0a589623397c3437911aeef39f189213527a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:05:36 +0100 Subject: draw: remove draw_vf code, use translate instead --- src/gallium/auxiliary/draw/Makefile | 3 - src/gallium/auxiliary/draw/SConscript | 3 - src/gallium/auxiliary/draw/draw_pt_emit.c | 3 +- src/gallium/auxiliary/draw/draw_vbuf.c | 188 ++++---- src/gallium/auxiliary/draw/draw_vf.c | 378 ----------------- src/gallium/auxiliary/draw/draw_vf.h | 232 ---------- src/gallium/auxiliary/draw/draw_vf_generic.c | 585 ------------------------- src/gallium/auxiliary/draw/draw_vf_sse.c | 613 --------------------------- 8 files changed, 115 insertions(+), 1890 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_vf.c delete mode 100644 src/gallium/auxiliary/draw/draw_vf.h delete mode 100644 src/gallium/auxiliary/draw/draw_vf_generic.c delete mode 100644 src/gallium/auxiliary/draw/draw_vf_sse.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 916e134719..27464e5c86 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -35,9 +35,6 @@ C_SOURCES = \ draw_vertex_cache.c \ draw_vertex_fetch.c \ draw_vertex_shader.c \ - draw_vf.c \ - draw_vf_generic.c \ - draw_vf_sse.c \ draw_wide_line.c \ draw_wide_point.c diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 6dc0195d93..7af65c3c05 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -31,9 +31,6 @@ draw = env.ConvenienceLibrary( 'draw_vertex_cache.c', 'draw_vertex_fetch.c', 'draw_vertex_shader.c', - 'draw_vf.c', - 'draw_vf_generic.c', - 'draw_vf_sse.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', 'draw_vs_sse.c', diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index a6a3ff6cac..490da4cca3 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -62,8 +62,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, vinfo = draw->render->get_vertex_info(draw->render); - /* In passthrough mode, need to translate from vertex shader - * outputs to hw vertices. + /* Translate from pipeline vertices to hw vertices. */ dst_offset = 0; for (i = 0; i < vinfo->num_attribs; i++) { diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c index 59b63f5bfa..dbbcf05c3c 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_vbuf.c @@ -40,7 +40,7 @@ #include "draw_vbuf.h" #include "draw_private.h" #include "draw_vertex.h" -#include "draw_vf.h" +#include "translate/translate.h" /** @@ -56,7 +56,7 @@ struct vbuf_stage { /** Vertex size in bytes */ unsigned vertex_size; - struct draw_vertex_fetch *vf; + struct translate *translate; /* FIXME: we have no guarantee that 'unsigned' is 32bit */ @@ -71,8 +71,9 @@ struct vbuf_stage { unsigned max_indices; unsigned nr_indices; - /** Pipe primitive */ - unsigned prim; + /* Cache point size somewhere it's address won't change: + */ + float point_size; }; @@ -175,26 +176,25 @@ dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) * have a couple of slots at the beginning (1-dword header, 4-dword * clip pos) that we ignore here. We only use the vertex->data[] fields. */ -static INLINE void +static INLINE ushort emit_vertex( struct vbuf_stage *vbuf, struct vertex_header *vertex ) { - if(vertex->vertex_id != UNDEFINED_VERTEX_ID) { - if(vertex->vertex_id < vbuf->nr_vertices) - return; - else - debug_printf("Bad vertex id 0x%04x (>= 0x%04x)\n", - vertex->vertex_id, vbuf->nr_vertices); - return; - } + if(vertex->vertex_id == UNDEFINED_VERTEX_ID) { + /* Hmm - vertices are emitted one at a time - better make sure + * set_buffer is efficient. Consider a special one-shot mode for + * translate. + */ + vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); + vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); + + if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); - vertex->vertex_id = vbuf->nr_vertices++; - - draw_vf_emit_vertex(vbuf->vf, vertex, vbuf->vertex_ptr); + vbuf->vertex_ptr += vbuf->vertex_size/4; + vertex->vertex_id = vbuf->nr_vertices++; + } - if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); - - vbuf->vertex_ptr += vbuf->vertex_size/4; + return vertex->vertex_id; } @@ -208,9 +208,7 @@ vbuf_tri( struct draw_stage *stage, check_space( vbuf, 3 ); for (i = 0; i < 3; i++) { - emit_vertex( vbuf, prim->v[i] ); - - vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[i]->vertex_id; + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); } } @@ -225,9 +223,7 @@ vbuf_line( struct draw_stage *stage, check_space( vbuf, 2 ); for (i = 0; i < 2; i++) { - emit_vertex( vbuf, prim->v[i] ); - - vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[i]->vertex_id; + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); } } @@ -240,43 +236,112 @@ vbuf_point( struct draw_stage *stage, check_space( vbuf, 1 ); - emit_vertex( vbuf, prim->v[0] ); - - vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[0]->vertex_id; + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] ); } + + /** * Set the prim type for subsequent vertices. * This may result in a new vertex size. The existing vbuffer (if any) * will be flushed if needed and a new one allocated. */ static void -vbuf_set_prim( struct vbuf_stage *vbuf, uint newprim ) +vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) { - const struct vertex_info *vinfo; - unsigned vertex_size; - - assert(newprim == PIPE_PRIM_POINTS || - newprim == PIPE_PRIM_LINES || - newprim == PIPE_PRIM_TRIANGLES); + struct translate_key hw_key; + unsigned dst_offset; + unsigned i; - vbuf->prim = newprim; - vbuf->render->set_primitive(vbuf->render, newprim); + vbuf->render->set_primitive(vbuf->render, prim); - vinfo = vbuf->render->get_vertex_info(vbuf->render); - vertex_size = vinfo->size * sizeof(float); + /* Must do this after set_primitive() above: + * + * XXX: need some state managment to track when this needs to be + * recalculated. The driver should tell us whether there was a + * state change. + */ + vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render); - if (vertex_size != vbuf->vertex_size) + if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) { vbuf_flush_vertices(vbuf); + vbuf->vertex_size = vbuf->vinfo->size * sizeof(float); + } - vbuf->vinfo = vinfo; - vbuf->vertex_size = vertex_size; - if(vbuf->vf) - draw_vf_set_vertex_info(vbuf->vf, - vbuf->vinfo, - vbuf->stage.draw->rasterizer->point_size); - + /* Translate from pipeline vertices to hw vertices. + */ + dst_offset = 0; + memset(&hw_key, 0, sizeof(hw_key)); + + for (i = 0; i < vbuf->vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned src_buffer = 0; + unsigned output_format; + unsigned src_offset = (vbuf->vinfo->src_index[i] * 4 * sizeof(float) ); + + switch (vbuf->vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + src_buffer = 1; + src_offset = 0; + break; + case EMIT_4UB: + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); + default: + assert(0); + output_format = PIPE_FORMAT_NONE; + emit_sz = 0; + break; + } + + hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + hw_key.element[i].input_buffer = src_buffer; + hw_key.element[i].input_offset = src_offset; + hw_key.element[i].output_format = output_format; + hw_key.element[i].output_offset = dst_offset; + + dst_offset += emit_sz; + } + + hw_key.nr_elements = vbuf->vinfo->num_attribs; + hw_key.output_stride = vbuf->vinfo->size * 4; + + /* Don't bother with caching at this stage: + */ + if (!vbuf->translate || + memcmp(&vbuf->translate->key, &hw_key, sizeof(hw_key)) != 0) + { + if (vbuf->translate) + vbuf->translate->release(vbuf->translate); + + vbuf->translate = translate_create( &hw_key ); + + vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0); + } + + vbuf->point_size = vbuf->stage.draw->rasterizer->point_size; + + /* Allocate new buffer? + */ if (!vbuf->vertices) vbuf_alloc_vertices(vbuf); } @@ -330,29 +395,9 @@ vbuf_flush_indices( struct vbuf_stage *vbuf ) assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned)); - switch(vbuf->prim) { - case PIPE_PRIM_POINTS: - break; - case PIPE_PRIM_LINES: - assert(vbuf->nr_indices % 2 == 0); - break; - case PIPE_PRIM_TRIANGLES: - assert(vbuf->nr_indices % 3 == 0); - break; - default: - assert(0); - } - vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices); vbuf->nr_indices = 0; - - /* don't need to reset point/line/tri functions */ -#if 0 - stage->point = vbuf_first_point; - stage->line = vbuf_first_line; - stage->tri = vbuf_first_tri; -#endif } @@ -433,8 +478,8 @@ static void vbuf_destroy( struct draw_stage *stage ) if(vbuf->indices) align_free( vbuf->indices ); - if(vbuf->vf) - draw_vf_destroy( vbuf->vf ); + if(vbuf->translate) + vbuf->translate->release( vbuf->translate ); if (vbuf->render) vbuf->render->destroy( vbuf->render ); @@ -473,11 +518,6 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, vbuf->vertices = NULL; vbuf->vertex_ptr = vbuf->vertices; - - vbuf->prim = ~0; - vbuf->vf = draw_vf_create(); - if (!vbuf->vf) - goto fail; return &vbuf->stage; diff --git a/src/gallium/auxiliary/draw/draw_vf.c b/src/gallium/auxiliary/draw/draw_vf.c deleted file mode 100644 index 9d0154c50d..0000000000 --- a/src/gallium/auxiliary/draw/draw_vf.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright 2003 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - */ - - -#include - -#include "pipe/p_compiler.h" -#include "pipe/p_util.h" -#include "rtasm/rtasm_execmem.h" - -#include "draw_vf.h" - - -#define DRAW_VF_DBG 0 - - -static boolean match_fastpath( struct draw_vertex_fetch *vf, - const struct draw_vf_fastpath *fp) -{ - unsigned j; - - if (vf->attr_count != fp->attr_count) - return FALSE; - - for (j = 0; j < vf->attr_count; j++) - if (vf->attr[j].format != fp->attr[j].format || - vf->attr[j].inputsize != fp->attr[j].size || - vf->attr[j].vertoffset != fp->attr[j].offset) - return FALSE; - - if (fp->match_strides) { - if (vf->vertex_stride != fp->vertex_stride) - return FALSE; - - for (j = 0; j < vf->attr_count; j++) - if (vf->attr[j].inputstride != fp->attr[j].stride) - return FALSE; - } - - return TRUE; -} - -static boolean search_fastpath_emit( struct draw_vertex_fetch *vf ) -{ - struct draw_vf_fastpath *fp = vf->fastpath; - - for ( ; fp ; fp = fp->next) { - if (match_fastpath(vf, fp)) { - vf->emit = fp->func; - return TRUE; - } - } - - return FALSE; -} - -void draw_vf_register_fastpath( struct draw_vertex_fetch *vf, - boolean match_strides ) -{ - struct draw_vf_fastpath *fastpath = CALLOC_STRUCT(draw_vf_fastpath); - unsigned i; - - fastpath->vertex_stride = vf->vertex_stride; - fastpath->attr_count = vf->attr_count; - fastpath->match_strides = match_strides; - fastpath->func = vf->emit; - fastpath->attr = (struct draw_vf_attr_type *) - MALLOC(vf->attr_count * sizeof(fastpath->attr[0])); - - for (i = 0; i < vf->attr_count; i++) { - fastpath->attr[i].format = vf->attr[i].format; - fastpath->attr[i].stride = vf->attr[i].inputstride; - fastpath->attr[i].size = vf->attr[i].inputsize; - fastpath->attr[i].offset = vf->attr[i].vertoffset; - } - - fastpath->next = vf->fastpath; - vf->fastpath = fastpath; -} - - - - -/*********************************************************************** - * Build codegen functions or return generic ones: - */ -static void choose_emit_func( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *dest) -{ - vf->emit = NULL; - - /* Does this match an existing (hardwired, codegen or known-bad) - * fastpath? - */ - if (search_fastpath_emit(vf)) { - /* Use this result. If it is null, then it is already known - * that the current state will fail for codegen and there is no - * point trying again. - */ - } - else if (vf->codegen_emit) { - vf->codegen_emit( vf ); - } - - if (!vf->emit) { - draw_vf_generate_hardwired_emit(vf); - } - - /* Otherwise use the generic version: - */ - if (!vf->emit) - vf->emit = draw_vf_generic_emit; - - vf->emit( vf, count, dest ); -} - - - - - -/*********************************************************************** - * Public entrypoints, mostly dispatch to the above: - */ - - - -static unsigned -draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, - const struct draw_vf_attr_map *map, - unsigned nr, - unsigned vertex_stride ) -{ - unsigned offset = 0; - unsigned i, j; - - assert(nr < PIPE_MAX_ATTRIBS); - - for (j = 0, i = 0; i < nr; i++) { - const unsigned format = map[i].format; - if (format == DRAW_EMIT_PAD) { -#if (DRAW_VF_DBG) - debug_printf("%d: pad %d, offset %d\n", i, - map[i].offset, offset); -#endif - - offset += map[i].offset; - - } - else { - vf->attr[j].attrib = map[i].attrib; - vf->attr[j].format = format; - vf->attr[j].insert = draw_vf_format_info[format].insert; - vf->attr[j].vertattrsize = draw_vf_format_info[format].attrsize; - vf->attr[j].vertoffset = offset; - vf->attr[j].isconst = draw_vf_format_info[format].isconst; - if(vf->attr[j].isconst) - memcpy(vf->attr[j].data, &map[i].data, vf->attr[j].vertattrsize); - -#if (DRAW_VF_DBG) - debug_printf("%d: %s, offset %d\n", i, - draw_vf_format_info[format].name, - vf->attr[j].vertoffset); -#endif - - offset += draw_vf_format_info[format].attrsize; - j++; - } - } - - vf->attr_count = j; - vf->vertex_stride = vertex_stride ? vertex_stride : offset; - vf->emit = choose_emit_func; - - assert(vf->vertex_stride >= offset); - return vf->vertex_stride; -} - - -void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, - const struct vertex_info *vinfo, - float point_size ) -{ - unsigned i, j; - struct draw_vf_attr *a = vf->attr; - struct draw_vf_attr_map attrs[PIPE_MAX_SHADER_INPUTS]; - unsigned count = 0; /* for debug/sanity */ - unsigned nr_attrs = 0; - - for (i = 0; i < vinfo->num_attribs; i++) { - j = vinfo->src_index[i]; - switch (vinfo->emit[i]) { - case EMIT_OMIT: - /* no-op */ - break; - case EMIT_1F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_1F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count++; - break; - case EMIT_1F_PSIZE: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_1F_CONST; - attrs[nr_attrs].offset = 0; - attrs[nr_attrs].data.f[0] = point_size; - nr_attrs++; - count++; - break; - case EMIT_2F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_2F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 2; - break; - case EMIT_3F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_3F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 3; - break; - case EMIT_4F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_4F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 4; - break; - case EMIT_4UB: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_4UB_4F_BGRA; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 1; - break; - default: - assert(0); - } - } - - assert(count == vinfo->size); - - draw_vf_set_vertex_attributes(vf, - attrs, - nr_attrs, - vinfo->size * sizeof(float) ); - - for (j = 0; j < vf->attr_count; j++) { - a[j].inputsize = 4; - a[j].do_insert = a[j].insert[4 - 1]; - if(a[j].isconst) { - a[j].inputptr = a[j].data; - a[j].inputstride = 0; - } - } -} - - -#if 0 -/* Set attribute pointers, adjusted for start position: - */ -void draw_vf_set_sources( struct draw_vertex_fetch *vf, - GLvector4f * const sources[], - unsigned start ) -{ - struct draw_vf_attr *a = vf->attr; - unsigned j; - - for (j = 0; j < vf->attr_count; j++) { - const GLvector4f *vptr = sources[a[j].attrib]; - - if ((a[j].inputstride != vptr->stride) || - (a[j].inputsize != vptr->size)) - vf->emit = choose_emit_func; - - a[j].inputstride = vptr->stride; - a[j].inputsize = vptr->size; - a[j].do_insert = a[j].insert[vptr->size - 1]; - a[j].inputptr = ((uint8_t *)vptr->data) + start * vptr->stride; - } -} -#endif - - -/** - * Emit a vertex to dest. - */ -void draw_vf_emit_vertex( struct draw_vertex_fetch *vf, - struct vertex_header *vertex, - void *dest ) -{ - struct draw_vf_attr *a = vf->attr; - unsigned j; - - for (j = 0; j < vf->attr_count; j++) { - if (!a[j].isconst) { - a[j].inputptr = (uint8_t *)&vertex->data[a[j].attrib][0]; - a[j].inputstride = 0; /* XXX: one-vertex-max ATM */ - } - } - - vf->emit( vf, 1, (uint8_t*) dest ); -} - - - -struct draw_vertex_fetch *draw_vf_create( void ) -{ - struct draw_vertex_fetch *vf = CALLOC_STRUCT(draw_vertex_fetch); - unsigned i; - - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) - vf->attr[i].vf = vf; - - vf->identity[0] = 0.0; - vf->identity[1] = 0.0; - vf->identity[2] = 0.0; - vf->identity[3] = 1.0; - - vf->codegen_emit = NULL; - -#ifdef USE_SSE_ASM - if (!GETENV("GALLIUM_NO_CODEGEN")) - vf->codegen_emit = draw_vf_generate_sse_emit; -#endif - - return vf; -} - - -void draw_vf_destroy( struct draw_vertex_fetch *vf ) -{ - struct draw_vf_fastpath *fp, *tmp; - - for (fp = vf->fastpath ; fp ; fp = tmp) { - tmp = fp->next; - FREE(fp->attr); - - /* KW: At the moment, fp->func is constrained to be allocated by - * rtasm_exec_alloc(), as the hardwired fastpaths in - * t_vertex_generic.c are handled specially. It would be nice - * to unify them, but this probably won't change until this - * module gets another overhaul. - */ - //rtasm_exec_free((void *) fp->func); - FREE(fp); - } - - vf->fastpath = NULL; - FREE(vf); -} diff --git a/src/gallium/auxiliary/draw/draw_vf.h b/src/gallium/auxiliary/draw/draw_vf.h deleted file mode 100644 index 0ef98d6257..0000000000 --- a/src/gallium/auxiliary/draw/draw_vf.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright 2008 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * Vertex fetch/store/convert code. This functionality is used in two places: - * 1. Vertex fetch/convert - to grab vertex data from incoming vertex - * arrays and convert to format needed by vertex shaders. - * 2. Vertex store/emit - to convert simple float[][4] vertex attributes - * (which is the organization used throughout the draw/prim pipeline) to - * hardware-specific formats and emit into hardware vertex buffers. - * - * - * Authors: - * Keith Whitwell - */ - -#ifndef DRAW_VF_H -#define DRAW_VF_H - - -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" - -#include "draw_vertex.h" -#include "draw_private.h" /* for vertex_header */ - - -enum draw_vf_attr_format { - DRAW_EMIT_1F, - DRAW_EMIT_2F, - DRAW_EMIT_3F, - DRAW_EMIT_4F, - DRAW_EMIT_3F_XYW, /**< for projective texture */ - DRAW_EMIT_1UB_1F, /**< for fog coordinate */ - DRAW_EMIT_3UB_3F_RGB, /**< for specular color */ - DRAW_EMIT_3UB_3F_BGR, /**< for specular color */ - DRAW_EMIT_4UB_4F_RGBA, /**< for color */ - DRAW_EMIT_4UB_4F_BGRA, /**< for color */ - DRAW_EMIT_4UB_4F_ARGB, /**< for color */ - DRAW_EMIT_4UB_4F_ABGR, /**< for color */ - DRAW_EMIT_1F_CONST, - DRAW_EMIT_2F_CONST, - DRAW_EMIT_3F_CONST, - DRAW_EMIT_4F_CONST, - DRAW_EMIT_PAD, /**< leave a hole of 'offset' bytes */ - DRAW_EMIT_MAX -}; - -struct draw_vf_attr_map -{ - /** Input attribute number */ - unsigned attrib; - - enum draw_vf_attr_format format; - - unsigned offset; - - /** - * Constant data for DRAW_EMIT_*_CONST - */ - union { - uint8_t ub[4]; - float f[4]; - } data; -}; - -struct draw_vertex_fetch; - - - -#if 0 -unsigned -draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, - const struct draw_vf_attr_map *map, - unsigned nr, - unsigned vertex_stride ); -#endif - -void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, - const struct vertex_info *vinfo, - float point_size ); - -#if 0 -void -draw_vf_set_sources( struct draw_vertex_fetch *vf, - GLvector4f * const attrib[], - unsigned start ); -#endif - -void -draw_vf_emit_vertex( struct draw_vertex_fetch *vf, - struct vertex_header *vertex, - void *dest ); - -struct draw_vertex_fetch * -draw_vf_create( void ); - -void -draw_vf_destroy( struct draw_vertex_fetch *vf ); - - - -/*********************************************************************** - * Internal functions and structs: - */ - -struct draw_vf_attr; - - -typedef void (*draw_vf_insert_func)( const struct draw_vf_attr *a, - uint8_t *v, - const float *in ); - -typedef void (*draw_vf_emit_func)( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *dest ); - - - -/** - * Describes how to convert/move a vertex attribute from a vertex - * array to a vertex structure. - */ -struct draw_vf_attr -{ - struct draw_vertex_fetch *vf; - - unsigned format; - unsigned inputsize; - unsigned inputstride; - unsigned vertoffset; /**< position of the attrib in the vertex struct */ - - boolean isconst; /**< read from const data below */ - uint8_t data[16]; - - unsigned attrib; /**< which vertex attrib (0=position, etc) */ - unsigned vertattrsize; /**< size of the attribute in bytes */ - - uint8_t *inputptr; - const draw_vf_insert_func *insert; - draw_vf_insert_func do_insert; -}; - -struct draw_vertex_fetch -{ - struct draw_vf_attr attr[PIPE_MAX_ATTRIBS]; - unsigned attr_count; - unsigned vertex_stride; - - draw_vf_emit_func emit; - - /* Parameters and constants for codegen: - */ - float identity[4]; - - struct draw_vf_fastpath *fastpath; - - void (*codegen_emit)( struct draw_vertex_fetch *vf ); -}; - - -struct draw_vf_attr_type { - unsigned format; - unsigned size; - unsigned stride; - unsigned offset; -}; - -/** XXX this could be moved into draw_vf.c */ -struct draw_vf_fastpath { - unsigned vertex_stride; - unsigned attr_count; - boolean match_strides; - - struct draw_vf_attr_type *attr; - - draw_vf_emit_func func; - struct draw_vf_fastpath *next; -}; - - -void -draw_vf_register_fastpath( struct draw_vertex_fetch *vtx, - boolean match_strides ); - -void -draw_vf_generic_emit( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *v ); - -void -draw_vf_generate_hardwired_emit( struct draw_vertex_fetch *vf ); - -void -draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ); - - -/** XXX this type and function could probably be moved into draw_vf.c */ -struct draw_vf_format_info { - const char *name; - draw_vf_insert_func insert[4]; - const unsigned attrsize; - const boolean isconst; -}; - -extern const struct draw_vf_format_info -draw_vf_format_info[DRAW_EMIT_MAX]; - - -#endif diff --git a/src/gallium/auxiliary/draw/draw_vf_generic.c b/src/gallium/auxiliary/draw/draw_vf_generic.c deleted file mode 100644 index 7a60a9db9c..0000000000 --- a/src/gallium/auxiliary/draw/draw_vf_generic.c +++ /dev/null @@ -1,585 +0,0 @@ - -/* - * Copyright 2003 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - */ - - -#include "pipe/p_compiler.h" -#include "pipe/p_debug.h" -#include "pipe/p_util.h" - -#include "draw_vf.h" - - - -static INLINE void insert_4f_4( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; -} - -static INLINE void insert_4f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = 1; -} - -static INLINE void insert_4f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = 0; - out[3] = 1; -} - -static INLINE void insert_4f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = 0; - out[2] = 0; - out[3] = 1; -} - -static INLINE void insert_3f_xyw_4( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[3]; -} - -static INLINE void insert_3f_xyw_err( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - (void) a; (void) v; (void) in; - assert(0); -} - -static INLINE void insert_3f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; -} - -static INLINE void insert_3f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = 0; -} - -static INLINE void insert_3f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = 0; - out[2] = 0; -} - - -static INLINE void insert_2f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; -} - -static INLINE void insert_2f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = 0; -} - -static INLINE void insert_1f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; -} - -static INLINE void insert_null( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - (void) a; (void) v; (void) in; -} - -static INLINE void insert_4ub_4f_rgba_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); -} - -static INLINE void insert_4ub_4f_rgba_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_rgba_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[2] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_rgba_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - v[1] = 0; - v[2] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_bgra_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); -} - -static INLINE void insert_4ub_4f_bgra_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_bgra_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[0] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_bgra_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - v[1] = 0; - v[0] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_argb_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); -} - -static INLINE void insert_4ub_4f_argb_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_argb_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - v[3] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_argb_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - v[2] = 0x00; - v[3] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_abgr_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); -} - -static INLINE void insert_4ub_4f_abgr_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_abgr_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - v[1] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_abgr_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - v[2] = 0x00; - v[1] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_3ub_3f_rgb_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); -} - -static INLINE void insert_3ub_3f_rgb_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[2] = 0; -} - -static INLINE void insert_3ub_3f_rgb_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - v[1] = 0; - v[2] = 0; -} - -static INLINE void insert_3ub_3f_bgr_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); -} - -static INLINE void insert_3ub_3f_bgr_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[0] = 0; -} - -static INLINE void insert_3ub_3f_bgr_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - v[1] = 0; - v[0] = 0; -} - - -static INLINE void insert_1ub_1f_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); -} - - -const struct draw_vf_format_info draw_vf_format_info[DRAW_EMIT_MAX] = -{ - { "1f", - { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, - sizeof(float), FALSE }, - - { "2f", - { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, - 2 * sizeof(float), FALSE }, - - { "3f", - { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, - 3 * sizeof(float), FALSE }, - - { "4f", - { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, - 4 * sizeof(float), FALSE }, - - { "3f_xyw", - { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err, - insert_3f_xyw_4 }, - 3 * sizeof(float), FALSE }, - - { "1ub_1f", - { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 }, - sizeof(uint8_t), FALSE }, - - { "3ub_3f_rgb", - { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3, - insert_3ub_3f_rgb_3 }, - 3 * sizeof(uint8_t), FALSE }, - - { "3ub_3f_bgr", - { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3, - insert_3ub_3f_bgr_3 }, - 3 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_rgba", - { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3, - insert_4ub_4f_rgba_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_bgra", - { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3, - insert_4ub_4f_bgra_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_argb", - { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3, - insert_4ub_4f_argb_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_abgr", - { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3, - insert_4ub_4f_abgr_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "1f_const", - { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, - sizeof(float), TRUE }, - - { "2f_const", - { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, - 2 * sizeof(float), TRUE }, - - { "3f_const", - { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, - 3 * sizeof(float), TRUE }, - - { "4f_const", - { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, - 4 * sizeof(float), TRUE }, - - { "pad", - { NULL, NULL, NULL, NULL }, - 0, FALSE }, - -}; - - - - -/*********************************************************************** - * Hardwired fastpaths for emitting whole vertices or groups of - * vertices - */ -#define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \ -static void NAME( struct draw_vertex_fetch *vf, \ - unsigned count, \ - uint8_t *v ) \ -{ \ - struct draw_vf_attr *a = vf->attr; \ - unsigned i; \ - \ - for (i = 0 ; i < count ; i++, v += vf->vertex_stride) { \ - if (NR > 0) { \ - F0( &a[0], v + a[0].vertoffset, (float *)a[0].inputptr ); \ - a[0].inputptr += a[0].inputstride; \ - } \ - \ - if (NR > 1) { \ - F1( &a[1], v + a[1].vertoffset, (float *)a[1].inputptr ); \ - a[1].inputptr += a[1].inputstride; \ - } \ - \ - if (NR > 2) { \ - F2( &a[2], v + a[2].vertoffset, (float *)a[2].inputptr ); \ - a[2].inputptr += a[2].inputstride; \ - } \ - \ - if (NR > 3) { \ - F3( &a[3], v + a[3].vertoffset, (float *)a[3].inputptr ); \ - a[3].inputptr += a[3].inputstride; \ - } \ - \ - if (NR > 4) { \ - F4( &a[4], v + a[4].vertoffset, (float *)a[4].inputptr ); \ - a[4].inputptr += a[4].inputstride; \ - } \ - } \ -} - - -#define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \ - insert_null, insert_null, NAME) - -#define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \ - insert_null, NAME) - -#define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \ - insert_null, NAME) - - -EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4) - -EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2) - -EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2) - - -/* Use the codegen paths to select one of a number of hardwired - * fastpaths. - */ -void draw_vf_generate_hardwired_emit( struct draw_vertex_fetch *vf ) -{ - draw_vf_emit_func func = NULL; - - /* Does it fit a hardwired fastpath? Help! this is growing out of - * control! - */ - switch (vf->attr_count) { - case 2: - if (vf->attr[0].do_insert == insert_3f_3 && - vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { - func = emit_xyz3_rgba4; - } - break; - case 3: - if (vf->attr[2].do_insert == insert_2f_2) { - if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { - if (vf->attr[0].do_insert == insert_4f_4) - func = emit_xyzw4_rgba4_st2; - } - } - break; - case 4: - if (vf->attr[2].do_insert == insert_2f_2 && - vf->attr[3].do_insert == insert_2f_2) { - if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { - if (vf->attr[0].do_insert == insert_4f_4) - func = emit_xyzw4_rgba4_st2_st2; - } - } - break; - } - - vf->emit = func; -} - -/*********************************************************************** - * Generic (non-codegen) functions for whole vertices or groups of - * vertices - */ - -void draw_vf_generic_emit( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *v ) -{ - struct draw_vf_attr *a = vf->attr; - const unsigned attr_count = vf->attr_count; - const unsigned stride = vf->vertex_stride; - unsigned i, j; - - for (i = 0 ; i < count ; i++, v += stride) { - for (j = 0; j < attr_count; j++) { - float *in = (float *)a[j].inputptr; - a[j].inputptr += a[j].inputstride; - a[j].do_insert( &a[j], v + a[j].vertoffset, in ); - } - } -} - - diff --git a/src/gallium/auxiliary/draw/draw_vf_sse.c b/src/gallium/auxiliary/draw/draw_vf_sse.c deleted file mode 100644 index aff4ffd985..0000000000 --- a/src/gallium/auxiliary/draw/draw_vf_sse.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Copyright 2003 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell - */ - - -#include "pipe/p_compiler.h" -#include "util/u_simple_list.h" - -#include "draw_vf.h" - - -#if defined(USE_SSE_ASM) - -#include "rtasm/rtasm_cpu.h" -#include "rtasm/rtasm_x86sse.h" - - -#define X 0 -#define Y 1 -#define Z 2 -#define W 3 - - -struct x86_program { - struct x86_function func; - - struct draw_vertex_fetch *vf; - boolean inputs_safe; - boolean outputs_safe; - boolean have_sse2; - - struct x86_reg identity; - struct x86_reg chan0; -}; - - -static struct x86_reg get_identity( struct x86_program *p ) -{ - return p->identity; -} - -static void emit_load4f_4( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movups(&p->func, dest, arg0); -} - -static void emit_load4f_3( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Have to jump through some hoops: - * - * c 0 0 0 - * c 0 0 1 - * 0 0 c 1 - * a b c 1 - */ - sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); - sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); - sse_shufps(&p->func, dest, dest, SHUF(Y,Z,X,W) ); - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load4f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Initialize from identity, then pull in low two words: - */ - sse_movups(&p->func, dest, get_identity(p)); - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load4f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Pull in low word, then swizzle in identity */ - sse_movss(&p->func, dest, arg0); - sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); -} - - - -static void emit_load3f_3( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Over-reads by 1 dword - potential SEGV if input is a vertex - * array. - */ - if (p->inputs_safe) { - sse_movups(&p->func, dest, arg0); - } - else { - /* c 0 0 0 - * c c c c - * a b c c - */ - sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); - sse_shufps(&p->func, dest, dest, SHUF(X,X,X,X)); - sse_movlps(&p->func, dest, arg0); - } -} - -static void emit_load3f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - emit_load4f_2(p, dest, arg0); -} - -static void emit_load3f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - emit_load4f_1(p, dest, arg0); -} - -static void emit_load2f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load2f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - emit_load4f_1(p, dest, arg0); -} - -static void emit_load1f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movss(&p->func, dest, arg0); -} - -static void (*load[4][4])( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) = { - { emit_load1f_1, - emit_load1f_1, - emit_load1f_1, - emit_load1f_1 }, - - { emit_load2f_1, - emit_load2f_2, - emit_load2f_2, - emit_load2f_2 }, - - { emit_load3f_1, - emit_load3f_2, - emit_load3f_3, - emit_load3f_3 }, - - { emit_load4f_1, - emit_load4f_2, - emit_load4f_3, - emit_load4f_4 } -}; - -static void emit_load( struct x86_program *p, - struct x86_reg dest, - unsigned sz, - struct x86_reg src, - unsigned src_sz) -{ - load[sz-1][src_sz-1](p, dest, src); -} - -static void emit_store4f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movups(&p->func, dest, arg0); -} - -static void emit_store3f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - if (p->outputs_safe) { - /* Emit the extra dword anyway. This may hurt writecombining, - * may cause other problems. - */ - sse_movups(&p->func, dest, arg0); - } - else { - /* Alternate strategy - emit two, shuffle, emit one. - */ - sse_movlps(&p->func, dest, arg0); - sse_shufps(&p->func, arg0, arg0, SHUF(Z,Z,Z,Z) ); /* NOTE! destructive */ - sse_movss(&p->func, x86_make_disp(dest,8), arg0); - } -} - -static void emit_store2f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movlps(&p->func, dest, arg0); -} - -static void emit_store1f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movss(&p->func, dest, arg0); -} - - -static void (*store[4])( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) = -{ - emit_store1f, - emit_store2f, - emit_store3f, - emit_store4f -}; - -static void emit_store( struct x86_program *p, - struct x86_reg dest, - unsigned sz, - struct x86_reg temp ) - -{ - store[sz-1](p, dest, temp); -} - -static void emit_pack_store_4ub( struct x86_program *p, - struct x86_reg dest, - struct x86_reg temp ) -{ - /* Scale by 255.0 - */ - sse_mulps(&p->func, temp, p->chan0); - - if (p->have_sse2) { - sse2_cvtps2dq(&p->func, temp, temp); - sse2_packssdw(&p->func, temp, temp); - sse2_packuswb(&p->func, temp, temp); - sse_movss(&p->func, dest, temp); - } - else { - struct x86_reg mmx0 = x86_make_reg(file_MMX, 0); - struct x86_reg mmx1 = x86_make_reg(file_MMX, 1); - sse_cvtps2pi(&p->func, mmx0, temp); - sse_movhlps(&p->func, temp, temp); - sse_cvtps2pi(&p->func, mmx1, temp); - mmx_packssdw(&p->func, mmx0, mmx1); - mmx_packuswb(&p->func, mmx0, mmx0); - mmx_movd(&p->func, dest, mmx0); - } -} - -static int get_offset( const void *a, const void *b ) -{ - return (const char *)b - (const char *)a; -} - -/* Not much happens here. Eventually use this function to try and - * avoid saving/reloading the source pointers each vertex (if some of - * them can fit in registers). - */ -static void get_src_ptr( struct x86_program *p, - struct x86_reg srcREG, - struct x86_reg vfREG, - struct draw_vf_attr *a ) -{ - struct draw_vertex_fetch *vf = p->vf; - struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr)); - - /* Load current a[j].inputptr - */ - x86_mov(&p->func, srcREG, ptr_to_src); -} - -static void update_src_ptr( struct x86_program *p, - struct x86_reg srcREG, - struct x86_reg vfREG, - struct draw_vf_attr *a ) -{ - if (a->inputstride) { - struct draw_vertex_fetch *vf = p->vf; - struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr)); - - /* add a[j].inputstride (hardcoded value - could just as easily - * pull the stride value from memory each time). - */ - x86_lea(&p->func, srcREG, x86_make_disp(srcREG, a->inputstride)); - - /* save new value of a[j].inputptr - */ - x86_mov(&p->func, ptr_to_src, srcREG); - } -} - - -/* Lots of hardcoding - * - * EAX -- pointer to current output vertex - * ECX -- pointer to current attribute - * - */ -static boolean build_vertex_emit( struct x86_program *p ) -{ - struct draw_vertex_fetch *vf = p->vf; - unsigned j = 0; - - struct x86_reg vertexEAX = x86_make_reg(file_REG32, reg_AX); - struct x86_reg srcECX = x86_make_reg(file_REG32, reg_CX); - struct x86_reg countEBP = x86_make_reg(file_REG32, reg_BP); - struct x86_reg vfESI = x86_make_reg(file_REG32, reg_SI); - struct x86_reg temp = x86_make_reg(file_XMM, 0); - uint8_t *fixup, *label; - - /* Push a few regs? - */ - x86_push(&p->func, countEBP); - x86_push(&p->func, vfESI); - - - /* Get vertex count, compare to zero - */ - x86_xor(&p->func, srcECX, srcECX); - x86_mov(&p->func, countEBP, x86_fn_arg(&p->func, 2)); - x86_cmp(&p->func, countEBP, srcECX); - fixup = x86_jcc_forward(&p->func, cc_E); - - /* Initialize destination register. - */ - x86_mov(&p->func, vertexEAX, x86_fn_arg(&p->func, 3)); - - /* Move argument 1 (vf) into a reg: - */ - x86_mov(&p->func, vfESI, x86_fn_arg(&p->func, 1)); - - - /* always load, needed or not: - */ - sse_movups(&p->func, p->identity, x86_make_disp(vfESI, get_offset(vf, &vf->identity[0]))); - - /* Note address for loop jump */ - label = x86_get_label(&p->func); - - /* Emit code for each of the attributes. Currently routes - * everything through SSE registers, even when it might be more - * efficient to stick with regular old x86. No optimization or - * other tricks - enough new ground to cover here just getting - * things working. - */ - while (j < vf->attr_count) { - struct draw_vf_attr *a = &vf->attr[j]; - struct x86_reg dest = x86_make_disp(vertexEAX, a->vertoffset); - - /* Now, load an XMM reg from src, perhaps transform, then save. - * Could be shortcircuited in specific cases: - */ - switch (a->format) { - case DRAW_EMIT_1F: - case DRAW_EMIT_1F_CONST: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 1, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_2F: - case DRAW_EMIT_2F_CONST: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 2, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_3F: - case DRAW_EMIT_3F_CONST: - /* Potentially the worst case - hardcode 2+1 copying: - */ - if (0) { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 3, temp); - update_src_ptr(p, srcECX, vfESI, a); - } - else { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 2, temp); - if (a->inputsize > 2) { - emit_load(p, temp, 1, x86_make_disp(srcECX, 8), 1); - emit_store(p, x86_make_disp(dest,8), 1, temp); - } - else { - sse_movss(&p->func, x86_make_disp(dest,8), get_identity(p)); - } - update_src_ptr(p, srcECX, vfESI, a); - } - break; - case DRAW_EMIT_4F: - case DRAW_EMIT_4F_CONST: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 4, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_3F_XYW: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(X,Y,W,Z)); - emit_store(p, dest, 3, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - - case DRAW_EMIT_1UB_1F: - /* Test for PAD3 + 1UB: - */ - if (j > 0 && - a[-1].vertoffset + a[-1].vertattrsize <= a->vertoffset - 3) - { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(X,X,X,X)); - emit_pack_store_4ub(p, x86_make_disp(dest, -3), temp); /* overkill! */ - update_src_ptr(p, srcECX, vfESI, a); - } - else { - debug_printf("Can't emit 1ub %x %x %d\n", - a->vertoffset, a[-1].vertoffset, a[-1].vertattrsize ); - return FALSE; - } - break; - case DRAW_EMIT_3UB_3F_RGB: - case DRAW_EMIT_3UB_3F_BGR: - /* Test for 3UB + PAD1: - */ - if (j == vf->attr_count - 1 || - a[1].vertoffset >= a->vertoffset + 4) { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - if (a->format == DRAW_EMIT_3UB_3F_BGR) - sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - } - /* Test for 3UB + 1UB: - */ - else if (j < vf->attr_count - 1 && - a[1].format == DRAW_EMIT_1UB_1F && - a[1].vertoffset == a->vertoffset + 3) { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - update_src_ptr(p, srcECX, vfESI, a); - - /* Make room for incoming value: - */ - sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); - - get_src_ptr(p, srcECX, vfESI, &a[1]); - emit_load(p, temp, 1, x86_deref(srcECX), a[1].inputsize); - update_src_ptr(p, srcECX, vfESI, &a[1]); - - /* Rearrange and possibly do BGR conversion: - */ - if (a->format == DRAW_EMIT_3UB_3F_BGR) - sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); - else - sse_shufps(&p->func, temp, temp, SHUF(Y,Z,W,X)); - - emit_pack_store_4ub(p, dest, temp); - j++; /* NOTE: two attrs consumed */ - } - else { - debug_printf("Can't emit 3ub\n"); - } - return FALSE; /* add this later */ - break; - - case DRAW_EMIT_4UB_4F_RGBA: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_4UB_4F_BGRA: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_4UB_4F_ARGB: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_4UB_4F_ABGR: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - default: - debug_printf("unknown a[%d].format %d\n", j, a->format); - return FALSE; /* catch any new opcodes */ - } - - /* Increment j by at least 1 - may have been incremented above also: - */ - j++; - } - - /* Next vertex: - */ - x86_lea(&p->func, vertexEAX, x86_make_disp(vertexEAX, vf->vertex_stride)); - - /* decr count, loop if not zero - */ - x86_dec(&p->func, countEBP); - x86_test(&p->func, countEBP, countEBP); - x86_jcc(&p->func, cc_NZ, label); - - /* Exit mmx state? - */ - if (p->func.need_emms) - mmx_emms(&p->func); - - /* Land forward jump here: - */ - x86_fixup_fwd_jump(&p->func, fixup); - - /* Pop regs and return - */ - x86_pop(&p->func, x86_get_base_reg(vfESI)); - x86_pop(&p->func, countEBP); - x86_ret(&p->func); - - vf->emit = (draw_vf_emit_func)x86_get_func(&p->func); - return TRUE; -} - - - -void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) -{ - struct x86_program p; - - if (!rtasm_cpu_has_sse()) { - vf->codegen_emit = NULL; - return; - } - - memset(&p, 0, sizeof(p)); - - p.vf = vf; - p.inputs_safe = 0; /* for now */ - p.outputs_safe = 1; /* for now */ - p.have_sse2 = rtasm_cpu_has_sse2(); - p.identity = x86_make_reg(file_XMM, 6); - p.chan0 = x86_make_reg(file_XMM, 7); - - x86_init_func(&p.func); - - if (build_vertex_emit(&p)) { - draw_vf_register_fastpath( vf, TRUE ); - } - else { - /* Note the failure so that we don't keep trying to codegen an - * impossible state: - */ - draw_vf_register_fastpath( vf, FALSE ); - x86_release_func(&p.func); - } -} - -#else - -void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) -{ - /* Dummy version for when USE_SSE_ASM not defined */ -} - -#endif -- cgit v1.2.3 From a41c05b20a36d2160aa232d08ed57d3095438025 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:11:16 +0100 Subject: draw: switch over to draw_pt paths, will remove old code shortly --- src/gallium/auxiliary/draw/draw_context.c | 2 -- src/gallium/auxiliary/draw/draw_private.h | 1 - src/gallium/auxiliary/draw/draw_pt.c | 3 --- 3 files changed, 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 4838b68ed1..5dc3358bd1 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -49,8 +49,6 @@ struct draw_context *draw_create( void ) draw->use_sse = FALSE; #endif - draw->use_pt_shaders = GETENV( "GALLIUM_PT_SHADERS" ) != NULL; - /* create pipeline stages */ draw->pipeline.wide_line = draw_wide_line_stage( draw ); draw->pipeline.wide_point = draw_wide_point_stage( draw ); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index da94e69781..18ce6c0ec5 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -258,7 +258,6 @@ struct draw_context boolean line_stipple; /**< do line stipple? */ boolean point_sprite; /**< convert points to quads for sprites? */ boolean use_sse; - boolean use_pt_shaders; /* temporary flag to switch on pt shader paths */ /* If a prim stage introduces new vertex attributes, they'll be stored here */ diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index b48d0cae9f..941f6efbe4 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -68,9 +68,6 @@ draw_pt_arrays(struct draw_context *draw, if (!draw->rasterizer->bypass_vs) { opt |= PT_SHADE; - - if (!draw->use_pt_shaders) - return FALSE; } -- cgit v1.2.3 From b11d89dc6d230f7f945f9eb420d39921c648ec20 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:36:38 +0100 Subject: draw: remove draw_prim.c --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/SConscript | 1 - src/gallium/auxiliary/draw/draw_prim.c | 23 -------------- src/gallium/auxiliary/draw/draw_pt.c | 55 ++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 27464e5c86..080311a667 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -24,7 +24,6 @@ C_SOURCES = \ draw_pt_emit.c \ draw_pt_pipeline.c \ draw_pt_elts.c \ - draw_prim.c \ draw_pstipple.c \ draw_stipple.c \ draw_twoside.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 7af65c3c05..238e3f7d28 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -11,7 +11,6 @@ draw = env.ConvenienceLibrary( 'draw_debug.c', 'draw_flatshade.c', 'draw_offset.c', - 'draw_prim.c', 'draw_pstipple.c', 'draw_pt.c', 'draw_pt_elts.c', diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index 51b6950334..d61cd25243 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -497,27 +497,4 @@ draw_prim( struct draw_context *draw, -/** - * Draw vertex arrays - * This is the main entrypoint into the drawing module. - * \param prim one of PIPE_PRIM_x - * \param start index of first vertex to draw - * \param count number of vertices to draw - */ -void -draw_arrays(struct draw_context *draw, unsigned prim, - unsigned start, unsigned count) -{ - if (reduced_prim[prim] != draw->reduced_prim) { - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->reduced_prim = reduced_prim[prim]; - } - - /* drawing done here: */ - if (!draw_pt_arrays(draw, prim, start, count)) { - /* we have to run the whole pipeline */ - draw_prim(draw, prim, start, count); - } -} - diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 941f6efbe4..ecaed84070 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -128,3 +128,58 @@ void draw_pt_destroy( struct draw_context *draw ) draw->pt.front.vcache = NULL; } } + + + +static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { + PIPE_PRIM_POINTS, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES +}; + + +/** + * Draw vertex arrays + * This is the main entrypoint into the drawing module. + * \param prim one of PIPE_PRIM_x + * \param start index of first vertex to draw + * \param count number of vertices to draw + */ +void +draw_arrays(struct draw_context *draw, unsigned prim, + unsigned start, unsigned count) +{ + if (reduced_prim[prim] != draw->reduced_prim) { + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->reduced_prim = reduced_prim[prim]; + } + + /* drawing done here: */ + draw_pt_arrays(draw, prim, start, count); +} + + +/* Revamp me please: + */ +void draw_do_flush( struct draw_context *draw, unsigned flags ) +{ + if (!draw->flushing) + { + draw->flushing = TRUE; + + if (flags >= DRAW_FLUSH_STATE_CHANGE) { + draw->pipeline.first->flush( draw->pipeline.first, flags ); + draw->pipeline.first = draw->pipeline.validate; + draw->reduced_prim = ~0; + } + + draw->flushing = FALSE; + } +} -- cgit v1.2.3 From 66891826421d5b774e081f7a2a85580cd0523fab Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:39:13 +0100 Subject: draw: remove draw_vertex_cache.c --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/draw_context.c | 20 +- src/gallium/auxiliary/draw/draw_prim.c | 500 ------------------------- src/gallium/auxiliary/draw/draw_vertex_cache.c | 219 ----------- 4 files changed, 18 insertions(+), 722 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_prim.c delete mode 100644 src/gallium/auxiliary/draw/draw_vertex_cache.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 080311a667..03210f6a4a 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -31,7 +31,6 @@ C_SOURCES = \ draw_validate.c \ draw_vbuf.c \ draw_vertex.c \ - draw_vertex_cache.c \ draw_vertex_fetch.c \ draw_vertex_shader.c \ draw_wide_line.c \ diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 5dc3358bd1..c611300841 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -103,7 +103,6 @@ struct draw_context *draw_create( void ) draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ - draw_vertex_cache_invalidate( draw ); draw_set_mapped_element_buffer( draw, 0, NULL ); tgsi_exec_machine_init(&draw->machine); @@ -446,7 +445,6 @@ void draw_reset_vertex_ids(struct draw_context *draw) stage = stage->next; } - draw_vertex_cache_reset_vertex_ids(draw); /* going away soon */ draw_pt_reset_vertex_ids(draw); } @@ -473,3 +471,21 @@ boolean draw_get_edgeflag( struct draw_context *draw, return 1; } + +/** + * Tell the drawing context about the index/element buffer to use + * (ala glDrawElements) + * If no element buffer is to be used (i.e. glDrawArrays) then this + * should be called with eltSize=0 and elements=NULL. + * + * \param draw the drawing context + * \param eltSize size of each element (1, 2 or 4 bytes) + * \param elements the element buffer ptr + */ +void +draw_set_mapped_element_buffer( struct draw_context *draw, + unsigned eltSize, void *elements ) +{ + draw->user.elts = elements; + draw->user.eltSize = eltSize; +} diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c deleted file mode 100644 index d61cd25243..0000000000 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ /dev/null @@ -1,500 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" - -#include "draw_private.h" -#include "draw_context.h" - - - -#define RP_NONE 0 -#define RP_POINT 1 -#define RP_LINE 2 -#define RP_TRI 3 - - -static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { - RP_POINT, - RP_LINE, - RP_LINE, - RP_LINE, - RP_TRI, - RP_TRI, - RP_TRI, - RP_TRI, - RP_TRI, - RP_TRI -}; - - -static void draw_prim_queue_flush( struct draw_context *draw ) -{ - unsigned i; - - if (0) - debug_printf("Flushing with %d prims, %d verts\n", - draw->pq.queue_nr, draw->vs.queue_nr); - - assert (draw->pq.queue_nr != 0); - - /* NOTE: we cannot save draw->pipeline->first in a local var because - * draw->pipeline->first is often changed by the first call to tri(), - * line(), etc. - */ - if (draw->rasterizer->line_stipple_enable) { - switch (draw->reduced_prim) { - case RP_TRI: - for (i = 0; i < draw->pq.queue_nr; i++) { - if (draw->pq.queue[i].reset_line_stipple) - draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); - - draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] ); - } - break; - case RP_LINE: - for (i = 0; i < draw->pq.queue_nr; i++) { - if (draw->pq.queue[i].reset_line_stipple) - draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); - - draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] ); - } - break; - case RP_POINT: - draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] ); - break; - } - } - else { - switch (draw->reduced_prim) { - case RP_TRI: - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] ); - break; - case RP_LINE: - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] ); - break; - case RP_POINT: - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] ); - break; - } - } - - draw->pq.queue_nr = 0; - draw->vs.post_nr = 0; - draw_vertex_cache_unreference( draw ); -} - -void draw_do_flush( struct draw_context *draw, unsigned flags ) -{ - if (0) - debug_printf("Flushing with %d verts, %d prims\n", - draw->vs.queue_nr, - draw->pq.queue_nr ); - - if (draw->flushing) - return; - - draw->flushing = TRUE; - - if (flags >= DRAW_FLUSH_SHADER_QUEUE) { - if (draw->vs.queue_nr) { - (*draw->shader_queue_flush)(draw); - } - - if (flags >= DRAW_FLUSH_PRIM_QUEUE) { - if (draw->pq.queue_nr) - draw_prim_queue_flush(draw); - - if (flags >= DRAW_FLUSH_VERTEX_CACHE) { - draw_vertex_cache_invalidate(draw); - - if (flags >= DRAW_FLUSH_STATE_CHANGE) { - draw->pipeline.first->flush( draw->pipeline.first, flags ); - draw->pipeline.first = draw->pipeline.validate; - draw->reduced_prim = ~0; - } - } - } - } - - draw->flushing = FALSE; -} - - - -/* Return a pointer to a freshly queued primitive header. Ensure that - * there is room in the vertex cache for a maximum of "nr_verts" new - * vertices. Flush primitive and/or vertex queues if necessary to - * make space. - */ -static struct prim_header *get_queued_prim( struct draw_context *draw, - unsigned nr_verts ) -{ - if (!draw_vertex_cache_check_space( draw, nr_verts )) { -// debug_printf("v"); - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE ); - } - else if (draw->pq.queue_nr == PRIM_QUEUE_LENGTH) { -// debug_printf("p"); - draw_do_flush( draw, DRAW_FLUSH_PRIM_QUEUE ); - } - - assert(draw->pq.queue_nr < PRIM_QUEUE_LENGTH); - - return &draw->pq.queue[draw->pq.queue_nr++]; -} - - - -/** - * Add a point to the primitive queue. - * \param i0 index into user's vertex arrays - */ -static void do_point( struct draw_context *draw, - unsigned i0 ) -{ - struct prim_header *prim = get_queued_prim( draw, 1 ); - - prim->reset_line_stipple = 0; - prim->edgeflags = 1; - prim->pad = 0; - prim->v[0] = draw->vcache.get_vertex( draw, i0 ); -} - - -/** - * Add a line to the primitive queue. - * \param i0 index into user's vertex arrays - * \param i1 index into user's vertex arrays - */ -static void do_line( struct draw_context *draw, - boolean reset_stipple, - unsigned i0, - unsigned i1 ) -{ - struct prim_header *prim = get_queued_prim( draw, 2 ); - - prim->reset_line_stipple = reset_stipple; - prim->edgeflags = 1; - prim->pad = 0; - prim->v[0] = draw->vcache.get_vertex( draw, i0 ); - prim->v[1] = draw->vcache.get_vertex( draw, i1 ); -} - -/** - * Add a triangle to the primitive queue. - */ -static void do_triangle( struct draw_context *draw, - unsigned i0, - unsigned i1, - unsigned i2 ) -{ - struct prim_header *prim = get_queued_prim( draw, 3 ); - -// _mesa_printf("tri %d %d %d\n", i0, i1, i2); - prim->reset_line_stipple = 1; - prim->edgeflags = ~0; - prim->pad = 0; - prim->v[0] = draw->vcache.get_vertex( draw, i0 ); - prim->v[1] = draw->vcache.get_vertex( draw, i1 ); - prim->v[2] = draw->vcache.get_vertex( draw, i2 ); -} - -static void do_ef_triangle( struct draw_context *draw, - boolean reset_stipple, - unsigned ef_mask, - unsigned i0, - unsigned i1, - unsigned i2 ) -{ - struct prim_header *prim = get_queued_prim( draw, 3 ); - struct vertex_header *v0 = draw->vcache.get_vertex( draw, i0 ); - struct vertex_header *v1 = draw->vcache.get_vertex( draw, i1 ); - struct vertex_header *v2 = draw->vcache.get_vertex( draw, i2 ); - - prim->reset_line_stipple = reset_stipple; - - prim->edgeflags = ef_mask & ((v0->edgeflag << 0) | - (v1->edgeflag << 1) | - (v2->edgeflag << 2)); - prim->pad = 0; - prim->v[0] = v0; - prim->v[1] = v1; - prim->v[2] = v2; -} - - -static void do_ef_quad( struct draw_context *draw, - unsigned v0, - unsigned v1, - unsigned v2, - unsigned v3 ) -{ - const unsigned omitEdge2 = ~(1 << 1); - const unsigned omitEdge3 = ~(1 << 2); - do_ef_triangle( draw, 1, omitEdge2, v0, v1, v3 ); - do_ef_triangle( draw, 0, omitEdge3, v1, v2, v3 ); -} - -static void do_quad( struct draw_context *draw, - unsigned v0, - unsigned v1, - unsigned v2, - unsigned v3 ) -{ - do_triangle( draw, v0, v1, v3 ); - do_triangle( draw, v1, v2, v3 ); -} - - -/** - * Main entrypoint to draw some number of points/lines/triangles - */ -static void -draw_prim( struct draw_context *draw, - unsigned prim, unsigned start, unsigned count ) -{ - unsigned i; - boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL); - boolean flatfirst = - (draw->rasterizer->flatshade & draw->rasterizer->flatshade_first) ? TRUE : FALSE; - -// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count ); - - switch (prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i ++) { - do_point( draw, - start + i ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - do_line( draw, - TRUE, - start + i + 0, - start + i + 1); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - for (i = 1; i < count; i++) { - do_line( draw, - i == 1, /* XXX: only if vb not split */ - start + i - 1, - start + i ); - } - - do_line( draw, - 0, - start + count - 1, - start + 0 ); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < count; i++) { - do_line( draw, - i == 1, - start + i - 1, - start + i ); - } - break; - - case PIPE_PRIM_TRIANGLES: - if (unfilled) { - for (i = 0; i+2 < count; i += 3) { - do_ef_triangle( draw, - 1, - ~0, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - else { - for (i = 0; i+2 < count; i += 3) { - do_triangle( draw, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - if (i & 1) { - do_triangle( draw, - start + i + 0, - start + i + 2, - start + i + 1 ); - } - else { - do_triangle( draw, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - } - else { - for (i = 0; i+2 < count; i++) { - if (i & 1) { - do_triangle( draw, - start + i + 1, - start + i + 0, - start + i + 2 ); - } - else { - do_triangle( draw, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - do_triangle( draw, - start + i + 1, - start + i + 2, - start + 0 ); - } - } - else { - for (i = 0; i+2 < count; i++) { - do_triangle( draw, - start + 0, - start + i + 1, - start + i + 2 ); - } - } - } - break; - - - case PIPE_PRIM_QUADS: - if (unfilled) { - for (i = 0; i+3 < count; i += 4) { - do_ef_quad( draw, - start + i + 0, - start + i + 1, - start + i + 2, - start + i + 3); - } - } - else { - for (i = 0; i+3 < count; i += 4) { - do_quad( draw, - start + i + 0, - start + i + 1, - start + i + 2, - start + i + 3); - } - } - break; - - case PIPE_PRIM_QUAD_STRIP: - if (unfilled) { - for (i = 0; i+3 < count; i += 2) { - do_ef_quad( draw, - start + i + 2, - start + i + 0, - start + i + 1, - start + i + 3); - } - } - else { - for (i = 0; i+3 < count; i += 2) { - do_quad( draw, - start + i + 2, - start + i + 0, - start + i + 1, - start + i + 3); - } - } - break; - - case PIPE_PRIM_POLYGON: - if (unfilled) { - unsigned ef_mask = (1<<2) | (1<<0); - - for (i = 0; i+2 < count; i++) { - - if (i + 3 >= count) - ef_mask |= (1<<1); - - do_ef_triangle( draw, - i == 0, - ef_mask, - start + i + 1, - start + i + 2, - start + 0); - - ef_mask &= ~(1<<2); - } - } - else { - for (i = 0; i+2 < count; i++) { - do_triangle( draw, - start + i + 1, - start + i + 2, - start + 0); - } - } - break; - - default: - assert(0); - break; - } -} - - - - - diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c deleted file mode 100644 index 730c18bcb3..0000000000 --- a/src/gallium/auxiliary/draw/draw_vertex_cache.c +++ /dev/null @@ -1,219 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "draw_private.h" -#include "draw_context.h" - - -void draw_vertex_cache_invalidate( struct draw_context *draw ) -{ - assert(draw->pq.queue_nr == 0); - assert(draw->vs.queue_nr == 0); - assert(draw->vcache.referenced == 0); - - /* There's an error somewhere in the vcache code that requires this - * memset. The bug is exposed in q3demo demo001, but probably - * elsewhere as well. Will track it down later. - */ - memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx)); -} - - -/** - * Check if vertex is in cache, otherwise add it. It won't go through - * VS yet, not until there is a flush operation or the VS queue fills up. - * - * Note that cache entries are basically just two pointers: the first - * an index into the user's vertex arrays, the second a location in - * the vertex shader cache for the post-transformed vertex. - * - * \return pointer to location of (post-transformed) vertex header in the cache - */ -static struct vertex_header *get_vertex( struct draw_context *draw, - unsigned i ) -{ - unsigned slot = (i + (i>>5)) % VCACHE_SIZE; - - assert(slot < 32); /* so we don't exceed the bitfield size below */ - - if (draw->vcache.referenced & (1<vcache.idx[slot].in == i) { - /*debug_printf("HIT %d %d\n", slot, i);*/ - assert(draw->vcache.idx[slot].out < draw->vs.queue_nr); - return draw_header_from_block(draw->vs.vertex_cache, - MAX_VERTEX_ALLOCATION, - draw->vcache.idx[slot].out); - } - - /* Otherwise a collision - */ - slot = VCACHE_SIZE + draw->vcache.overflow++; - /*debug_printf("XXX %d --> %d\n", i, slot);*/ - } - - /* Deal with the cache miss: - */ - { - unsigned out; - struct vertex_header *header; - - assert(slot < Elements(draw->vcache.idx)); - - /*debug_printf("NEW %d %d\n", slot, i);*/ - draw->vcache.idx[slot].in = i; - draw->vcache.idx[slot].out = out = draw->vs.queue_nr++; - draw->vcache.referenced |= (1 << slot); - - - /* Add to vertex shader queue: - */ - assert(draw->vs.queue_nr < VS_QUEUE_LENGTH); - - header = draw_header_from_block(draw->vs.vertex_cache, MAX_VERTEX_ALLOCATION, - out); - draw->vs.elts[out] = i; - header->clipmask = 0; - header->edgeflag = draw_get_edgeflag(draw, i); - header->pad = 0; - header->vertex_id = UNDEFINED_VERTEX_ID; - - /* Need to set the vertex's edge flag here. If we're being called - * by do_ef_triangle(), that function needs edge flag info! - */ - - return draw_header_from_block(draw->vs.vertex_cache, - MAX_VERTEX_ALLOCATION, - draw->vcache.idx[slot].out); - } -} - - -static struct vertex_header *get_uint_elt_vertex( struct draw_context *draw, - unsigned i ) -{ - const unsigned *elts = (const unsigned *) draw->user.elts; - return get_vertex( draw, elts[i] ); -} - - -static struct vertex_header *get_ushort_elt_vertex( struct draw_context *draw, - unsigned i ) -{ - const ushort *elts = (const ushort *) draw->user.elts; - return get_vertex( draw, elts[i] ); -} - - -static struct vertex_header *get_ubyte_elt_vertex( struct draw_context *draw, - unsigned i ) -{ - const ubyte *elts = (const ubyte *) draw->user.elts; - return get_vertex( draw, elts[i] ); -} - - -void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ) -{ - unsigned i; - - for (i = 0; i < draw->vs.post_nr; i++) { - struct vertex_header * header = - draw_header_from_block(draw->vs.vertex_cache, - MAX_VERTEX_ALLOCATION, i); - header->vertex_id = UNDEFINED_VERTEX_ID; - } -} - - -void draw_vertex_cache_unreference( struct draw_context *draw ) -{ - draw->vcache.referenced = 0; - draw->vcache.overflow = 0; -} - - -int draw_vertex_cache_check_space( struct draw_context *draw, - unsigned nr_verts ) -{ - if (draw->vcache.overflow + nr_verts < VCACHE_OVERFLOW) { - /* The vs queue is sized so that this can never happen: - */ - assert(draw->vs.queue_nr + nr_verts < VS_QUEUE_LENGTH); - return TRUE; - } - else - return FALSE; -} - - - -/** - * Tell the drawing context about the index/element buffer to use - * (ala glDrawElements) - * If no element buffer is to be used (i.e. glDrawArrays) then this - * should be called with eltSize=0 and elements=NULL. - * - * \param draw the drawing context - * \param eltSize size of each element (1, 2 or 4 bytes) - * \param elements the element buffer ptr - */ -void -draw_set_mapped_element_buffer( struct draw_context *draw, - unsigned eltSize, void *elements ) -{ -// draw_statechange( draw ); - - /* choose the get_vertex() function to use */ - switch (eltSize) { - case 0: - draw->vcache.get_vertex = get_vertex; - break; - case 1: - draw->vcache.get_vertex = get_ubyte_elt_vertex; - break; - case 2: - draw->vcache.get_vertex = get_ushort_elt_vertex; - break; - case 4: - draw->vcache.get_vertex = get_uint_elt_vertex; - break; - default: - assert(0); - } - draw->user.elts = elements; - draw->user.eltSize = eltSize; -} - -- cgit v1.2.3 From dd903d83b3ff8dd19f75ac7542b96bc8f1387fe6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:41:39 +0100 Subject: draw: remove old vertex_shader->run() functions --- src/gallium/auxiliary/draw/draw_vertex_shader.c | 2 +- src/gallium/auxiliary/draw/draw_vs.h | 7 -- src/gallium/auxiliary/draw/draw_vs_exec.c | 137 ------------------------ src/gallium/auxiliary/draw/draw_vs_llvm.c | 108 ------------------- src/gallium/auxiliary/draw/draw_vs_sse.c | 126 ---------------------- 5 files changed, 1 insertion(+), 379 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index c0c17c116e..118664d619 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -74,7 +74,7 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) assert(n > 0); assert(n <= MAX_SHADER_VERTICES); - shader->run(shader, draw, elts, n, dests, MAX_VERTEX_ALLOCATION); +// shader->run(shader, draw, elts, n, dests, MAX_VERTEX_ALLOCATION); } draw->vs.post_nr = draw->vs.queue_nr; diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index e88d00e247..b6f3bbdaea 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -55,13 +55,6 @@ struct draw_vertex_shader { /* Run the shader - this interface will get cleaned up in the * future: */ - boolean (*run)( struct draw_vertex_shader *shader, - struct draw_context *draw, - const unsigned *elts, - unsigned count, - void *out, - unsigned vertex_size); - void (*run_linear)( struct draw_vertex_shader *shader, const float (*input)[4], float (*output)[4], diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 184151b9b1..54a2b2ab04 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -66,145 +66,9 @@ vs_exec_prepare( struct draw_vertex_shader *shader, PIPE_MAX_SAMPLERS, NULL /*samplers*/ ); - draw_update_vertex_fetch( draw ); } -/** - * Transform vertices with the current vertex program/shader - * Up to four vertices can be shaded at a time. - * \param vbuffer the input vertex data - * \param elts indexes of four input vertices - * \param count number of vertices to shade [1..4] - * \param vOut array of pointers to four output vertices - */ -static boolean -vs_exec_run( struct draw_vertex_shader *shader, - struct draw_context *draw, - const unsigned *elts, - unsigned count, - void *vOut, - unsigned vertex_size) -{ - struct exec_vertex_shader *evs = exec_vertex_shader(shader); - struct tgsi_exec_machine *machine = evs->machine; - unsigned int i, j; - unsigned int clipped = 0; - struct tgsi_exec_vector *outputs = 0; - const float *scale = draw->viewport.scale; - const float *trans = draw->viewport.translate; - - assert(shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); - - machine->Consts = (const float (*)[4]) draw->user.constants; - - if (draw->rasterizer->bypass_vs) { - /* outputs are just the inputs */ - outputs = machine->Inputs; - } - else { - outputs = machine->Outputs; - } - - for (i = 0; i < count; i += MAX_TGSI_VERTICES) { - unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); - draw->vertex_fetch.fetch_func( draw, machine, &elts[i], max_vertices ); - -#if 0 - for (j = 0; j < max_vertices; j++) { - unsigned slot; - debug_printf("%d) Input vert:\n", i + j); - for (slot = 0; slot < shader->info.num_inputs; slot++) { - debug_printf("\t%d: %f %f %f %f\n", slot, - machine->Inputs[slot].xyzw[0].f[j], - machine->Inputs[slot].xyzw[1].f[j], - machine->Inputs[slot].xyzw[2].f[j], - machine->Inputs[slot].xyzw[3].f[j]); - } - } -#endif - - - if (!draw->rasterizer->bypass_vs) { - /* run interpreter */ - tgsi_exec_machine_run( machine ); - } - - /* store machine results */ - for (j = 0; j < max_vertices; j++) { - unsigned slot; - float x, y, z, w; - struct vertex_header *out = - draw_header_from_block(vOut, vertex_size, i + j); - - /* Handle attr[0] (position) specially: - * - * XXX: Computing the clipmask should be done in the vertex - * program as a set of DP4 instructions appended to the - * user-provided code. - */ - x = out->clip[0] = outputs[0].xyzw[0].f[j]; - y = out->clip[1] = outputs[0].xyzw[1].f[j]; - z = out->clip[2] = outputs[0].xyzw[2].f[j]; - w = out->clip[3] = outputs[0].xyzw[3].f[j]; - - if (!draw->rasterizer->bypass_clipping) { - out->clipmask = compute_clipmask(out->clip, draw->plane, - draw->nr_planes); - clipped += out->clipmask; - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - } - else { - out->clipmask = 0; - } - out->edgeflag = 1; - out->vertex_id = UNDEFINED_VERTEX_ID; - - if (!draw->identity_viewport) { - /* Viewport mapping */ - out->data[0][0] = x * scale[0] + trans[0]; - out->data[0][1] = y * scale[1] + trans[1]; - out->data[0][2] = z * scale[2] + trans[2]; - out->data[0][3] = w; - } - else - { - out->data[0][0] = x; - out->data[0][1] = y; - out->data[0][2] = z; - out->data[0][3] = w; - } - - /* Remaining attributes are packed into sequential post-transform - * vertex attrib slots. - */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { - out->data[slot][0] = outputs[slot].xyzw[0].f[j]; - out->data[slot][1] = outputs[slot].xyzw[1].f[j]; - out->data[slot][2] = outputs[slot].xyzw[2].f[j]; - out->data[slot][3] = outputs[slot].xyzw[3].f[j]; - } - -#if 0 /*DEBUG*/ - printf("%d) Post xform vert:\n", i + j); - for (slot = 0; slot < draw->num_vs_outputs; slot++) { - printf("\t%d: %f %f %f %f\n", slot, - out->data[slot][0], - out->data[slot][1], - out->data[slot][2], - out->data[slot][3]); - } -#endif - } /* loop over vertices */ - } - return clipped != 0; -} - /* Simplified vertex shader interface for the pt paths. Given the @@ -312,7 +176,6 @@ draw_create_vs_exec(struct draw_context *draw, vs->base.prepare = vs_exec_prepare; - vs->base.run = vs_exec_run; vs->base.run_linear = vs_exec_run_linear; vs->base.delete = vs_exec_delete; vs->machine = &draw->machine; diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 4dbfa955a4..5e27bc9ff0 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -60,113 +60,6 @@ vs_llvm_prepare( struct draw_vertex_shader *base, -/** - * Transform vertices with the current vertex program/shader - * Up to four vertices can be shaded at a time. - * \param vbuffer the input vertex data - * \param elts indexes of four input vertices - * \param count number of vertices to shade [1..4] - * \param vOut array of pointers to four output vertices - */ -static boolean -vs_llvm_run( struct draw_vertex_shader *base, - struct draw_context *draw, - const unsigned *elts, - unsigned count, - void *vOut ) -{ - struct draw_llvm_vertex_shader *shader = - (struct draw_llvm_vertex_shader *)base; - - struct tgsi_exec_machine *machine = shader->machine; - unsigned int j; - unsigned int clipped = 0; - const float *scale = draw->viewport.scale; - const float *trans = draw->viewport.translate; - - - assert(count <= 4); - assert(base->state->output_semantic_name[0] == TGSI_SEMANTIC_POSITION); - - /* Consts does not require 16 byte alignment. */ - machine->Consts = (float (*)[4]) draw->user.constants; - - if (draw->rasterizer->bypass_vs) { - /* outputs are just the inputs */ - outputs = machine->Inputs; - } - else { - outputs = machine->Outputs; - } - - - draw->vertex_fetch.fetch_func( draw, machine, elts, count ); - - if (!draw->rasterizer->bypass_vs) { - /* run shader */ - gallivm_cpu_vs_exec(shader->llvm_prog, - machine->Inputs, - machine->Outputs, - machine->Consts, - machine->Temps); - } - - /* store machine results */ - for (j = 0; j < count; j++) { - unsigned slot; - float x, y, z, w; - - x = vOut[j]->clip[0] = outputs[0].xyzw[0].f[j]; - y = vOut[j]->clip[1] = outputs[0].xyzw[1].f[j]; - z = vOut[j]->clip[2] = outputs[0].xyzw[2].f[j]; - w = vOut[j]->clip[3] = outputs[0].xyzw[3].f[j]; - - if (!draw->rasterizer->bypass_clipping) { - vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, - draw->nr_planes); - clipped += vOut[j]->clipmask; - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - } - else { - vOut[j]->clipmask = 0; - } - vOut[j]->edgeflag = 1; - vOut[j]->vertex_id = UNDEFINED_VERTEX_ID; - - if (!draw->identity_viewport) { - /* Viewport mapping */ - vOut[j]->data[0][0] = x * scale[0] + trans[0]; - vOut[j]->data[0][1] = y * scale[1] + trans[1]; - vOut[j]->data[0][2] = z * scale[2] + trans[2]; - vOut[j]->data[0][3] = w; - } - else { - vOut[j]->data[0][0] = x; - vOut[j]->data[0][1] = y; - vOut[j]->data[0][2] = z; - vOut[j]->data[0][3] = w; - } - - /* Remaining attributes are packed into sequential post-transform - * vertex attrib slots. - */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[j]->data[slot][0] = outputs[slot].xyzw[0].f[j]; - vOut[j]->data[slot][1] = outputs[slot].xyzw[1].f[j]; - vOut[j]->data[slot][2] = outputs[slot].xyzw[2].f[j]; - vOut[j]->data[slot][3] = outputs[slot].xyzw[3].f[j]; - } - } /* loop over vertices */ - return clipped != 0; -} - - - static void vs_llvm_run_linear( struct draw_vertex_shader *base, @@ -256,7 +149,6 @@ draw_create_vs_llvm(struct draw_context *draw, tgsi_scan_shader(shader->tokens, &vs->base.info); vs->base.prepare = vs_llvm_prepare; - vs->base.run = vs_llvm_run; vs->base.run_linear = vs_llvm_run_linear; vs->base.delete = vs_llvm_delete; vs->machine = &draw->machine; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index a763f3845c..60f60a5b53 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -74,131 +74,6 @@ vs_sse_prepare( struct draw_vertex_shader *base, draw_update_vertex_fetch( draw ); } -/** - * Transform vertices with the current vertex program/shader - * Up to four vertices can be shaded at a time. - * \param vbuffer the input vertex data - * \param elts indexes of four input vertices - * \param count number of vertices to shade [1..4] - * \param vOut array of pointers to four output vertices - */ -static boolean -vs_sse_run( struct draw_vertex_shader *base, - struct draw_context *draw, - const unsigned *elts, - unsigned count, - void *vOut, - unsigned vertex_size ) -{ - struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; - struct tgsi_exec_machine *machine = shader->machine; - unsigned int i, j; - unsigned int clipped = 0; - struct tgsi_exec_vector *outputs = 0; - const float *scale = draw->viewport.scale; - const float *trans = draw->viewport.translate; - - assert(base->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); - - /* Consts does not require 16 byte alignment. */ - machine->Consts = (const float (*)[4]) draw->user.constants; - - if (draw->rasterizer->bypass_vs) { - /* outputs are just the inputs */ - outputs = machine->Inputs; - } - else { - outputs = machine->Outputs; - } - - for (i = 0; i < count; i += SSE_MAX_VERTICES) { - unsigned int max_vertices = MIN2(SSE_MAX_VERTICES, count - i); - /* Fetch vertices. This may at some point be integrated into the - * compiled shader -- that would require a reorganization where - * multiple versions of the compiled shader might exist, - * specialized for each fetch state. - */ - draw->vertex_fetch.fetch_func(draw, machine, &elts[i], max_vertices); - - if (!draw->rasterizer->bypass_vs) { - /* run compiled shader - */ - shader->func(machine->Inputs, - machine->Outputs, - (float (*)[4])machine->Consts, - machine->Temps, - shader->immediates); - } - - /* XXX: Computing the clipmask and emitting results should be done - * in the vertex program as a set of instructions appended to - * the user-provided code. - */ - for (j = 0; j < max_vertices; j++) { - unsigned slot; - float x, y, z, w; - struct vertex_header *out = - draw_header_from_block(vOut, vertex_size, i + j); - - x = out->clip[0] = outputs[0].xyzw[0].f[j]; - y = out->clip[1] = outputs[0].xyzw[1].f[j]; - z = out->clip[2] = outputs[0].xyzw[2].f[j]; - w = out->clip[3] = outputs[0].xyzw[3].f[j]; - - if (!draw->rasterizer->bypass_clipping) { - out->clipmask = compute_clipmask(out->clip, draw->plane, - draw->nr_planes); - clipped += out->clipmask; - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - } - else { - out->clipmask = 0; - } - out->edgeflag = 1; - out->vertex_id = UNDEFINED_VERTEX_ID; - - if (!draw->identity_viewport) { - /* Viewport mapping */ - out->data[0][0] = x * scale[0] + trans[0]; - out->data[0][1] = y * scale[1] + trans[1]; - out->data[0][2] = z * scale[2] + trans[2]; - out->data[0][3] = w; - } - else { - out->data[0][0] = x; - out->data[0][1] = y; - out->data[0][2] = z; - out->data[0][3] = w; - } - - /* Remaining attributes are packed into sequential post-transform - * vertex attrib slots. - */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { - out->data[slot][0] = outputs[slot].xyzw[0].f[j]; - out->data[slot][1] = outputs[slot].xyzw[1].f[j]; - out->data[slot][2] = outputs[slot].xyzw[2].f[j]; - out->data[slot][3] = outputs[slot].xyzw[3].f[j]; - } -#if 0 /*DEBUG*/ - printf("%d) Post xform vert:\n", i + j); - for (slot = 0; slot < draw->num_vs_outputs; slot++) { - printf("\t%d: %f %f %f %f\n", slot, - out->data[slot][0], - out->data[slot][1], - out->data[slot][2], - out->data[slot][3]); - } -#endif - } - } - return clipped != 0; -} /* Simplified vertex shader interface for the pt paths. Given the @@ -294,7 +169,6 @@ draw_create_vs_sse(struct draw_context *draw, tgsi_scan_shader(templ->tokens, &vs->base.info); vs->base.prepare = vs_sse_prepare; - vs->base.run = vs_sse_run; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; vs->machine = &draw->machine; -- cgit v1.2.3 From 709e33cf0bfd552220e46f44e8cfa2063c3cef69 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:44:13 +0100 Subject: draw: remove old draw_vertex_shader_queue_flush function --- src/gallium/auxiliary/draw/draw_context.c | 2 -- src/gallium/auxiliary/draw/draw_private.h | 6 ---- src/gallium/auxiliary/draw/draw_vertex_shader.c | 43 ------------------------- 3 files changed, 51 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index c611300841..9c3ae9bc0d 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -93,8 +93,6 @@ struct draw_context *draw_create( void ) draw->vs.vertex_cache = tmp; } - draw->shader_queue_flush = draw_vertex_shader_queue_flush; - /* these defaults are oriented toward the needs of softpipe */ draw->wide_point_threshold = 1000000.0; /* infinity */ draw->wide_line_threshold = 1.0; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 18ce6c0ec5..93add257a3 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -309,11 +309,6 @@ struct draw_context unsigned post_nr; } vs; - /** - * Run the vertex shader on all vertices in the vertex queue. - */ - void (*shader_queue_flush)(struct draw_context *draw); - /* Prim pipeline queue: */ struct { @@ -359,7 +354,6 @@ extern void draw_vertex_cache_invalidate( struct draw_context *draw ); extern void draw_vertex_cache_unreference( struct draw_context *draw ); extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ); -extern void draw_vertex_shader_queue_flush( struct draw_context *draw ); extern void draw_update_vertex_fetch( struct draw_context *draw ); diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index 118664d619..03fe00a951 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -37,49 +37,6 @@ #include "draw_context.h" #include "draw_vs.h" -/** - * Run the vertex shader on all vertices in the vertex queue. - * Called by the draw module when the vertx cache needs to be flushed. - */ -void -draw_vertex_shader_queue_flush(struct draw_context *draw) -{ - struct draw_vertex_shader *shader = draw->vertex_shader; - unsigned i; - - assert(draw->vs.queue_nr != 0); - - /* XXX: do this on statechange: - */ - shader->prepare( shader, draw ); - -// fprintf(stderr, "%s %d\n", __FUNCTION__, draw->vs.queue_nr ); - - /* run vertex shader on vertex cache entries, four per invokation */ - for (i = 0; i < draw->vs.queue_nr; i += MAX_SHADER_VERTICES) { - unsigned elts[MAX_SHADER_VERTICES]; - int j, n = MIN2(MAX_SHADER_VERTICES, draw->vs.queue_nr - i); - struct vertex_header *dests = - draw_header_from_block(draw->vs.vertex_cache, - MAX_VERTEX_ALLOCATION, i); - - for (j = 0; j < n; j++) { - elts[j] = draw->vs.elts[i + j]; - } - - for ( ; j < MAX_SHADER_VERTICES; j++) { - elts[j] = elts[0]; - } - - assert(n > 0); - assert(n <= MAX_SHADER_VERTICES); - -// shader->run(shader, draw, elts, n, dests, MAX_VERTEX_ALLOCATION); - } - - draw->vs.post_nr = draw->vs.queue_nr; - draw->vs.queue_nr = 0; -} struct draw_vertex_shader * -- cgit v1.2.3 From 415e8e039ba38716336e8de3d7b3cdc23b9a9d8e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:46:06 +0100 Subject: draw: remove draw_vertex_fetch.c --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/SConscript | 2 - src/gallium/auxiliary/draw/draw_vertex_fetch.c | 528 ------------------------- src/gallium/auxiliary/draw/draw_vs_llvm.c | 1 - src/gallium/auxiliary/draw/draw_vs_sse.c | 1 - 5 files changed, 533 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_vertex_fetch.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 03210f6a4a..60bb9dfe88 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -31,7 +31,6 @@ C_SOURCES = \ draw_validate.c \ draw_vbuf.c \ draw_vertex.c \ - draw_vertex_fetch.c \ draw_vertex_shader.c \ draw_wide_line.c \ draw_wide_point.c diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 238e3f7d28..246083a962 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -27,8 +27,6 @@ draw = env.ConvenienceLibrary( 'draw_validate.c', 'draw_vbuf.c', 'draw_vertex.c', - 'draw_vertex_cache.c', - 'draw_vertex_fetch.c', 'draw_vertex_shader.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c deleted file mode 100644 index 0bc2fcb424..0000000000 --- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c +++ /dev/null @@ -1,528 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "draw_vs.h" -#include "draw_context.h" - - -#define DRAW_DBG 0 - - -/** - * Fetch a float[4] vertex attribute from memory, doing format/type - * conversion as needed. - * - * This is probably needed/dupliocated elsewhere, eg format - * conversion, texture sampling etc. - */ -#define FETCH_ATTRIB( NAME, SZ, CVT ) \ -static void \ -fetch_##NAME(const void *ptr, float *attrib) \ -{ \ - static const float defaults[4] = { 0,0,0,1 }; \ - int i; \ - \ - for (i = 0; i < SZ; i++) { \ - attrib[i] = CVT(i); \ - } \ - \ - for (; i < 4; i++) { \ - attrib[i] = defaults[i]; \ - } \ -} - -#define CVT_64_FLOAT(i) (float) ((double *) ptr)[i] -#define CVT_32_FLOAT(i) ((float *) ptr)[i] - -#define CVT_8_USCALED(i) (float) ((unsigned char *) ptr)[i] -#define CVT_16_USCALED(i) (float) ((unsigned short *) ptr)[i] -#define CVT_32_USCALED(i) (float) ((unsigned int *) ptr)[i] - -#define CVT_8_SSCALED(i) (float) ((char *) ptr)[i] -#define CVT_16_SSCALED(i) (float) ((short *) ptr)[i] -#define CVT_32_SSCALED(i) (float) ((int *) ptr)[i] - -#define CVT_8_UNORM(i) (float) ((unsigned char *) ptr)[i] / 255.0f -#define CVT_16_UNORM(i) (float) ((unsigned short *) ptr)[i] / 65535.0f -#define CVT_32_UNORM(i) (float) ((unsigned int *) ptr)[i] / 4294967295.0f - -#define CVT_8_SNORM(i) (float) ((char *) ptr)[i] / 127.0f -#define CVT_16_SNORM(i) (float) ((short *) ptr)[i] / 32767.0f -#define CVT_32_SNORM(i) (float) ((int *) ptr)[i] / 2147483647.0f - -FETCH_ATTRIB( R64G64B64A64_FLOAT, 4, CVT_64_FLOAT ) -FETCH_ATTRIB( R64G64B64_FLOAT, 3, CVT_64_FLOAT ) -FETCH_ATTRIB( R64G64_FLOAT, 2, CVT_64_FLOAT ) -FETCH_ATTRIB( R64_FLOAT, 1, CVT_64_FLOAT ) - -FETCH_ATTRIB( R32G32B32A32_FLOAT, 4, CVT_32_FLOAT ) -FETCH_ATTRIB( R32G32B32_FLOAT, 3, CVT_32_FLOAT ) -FETCH_ATTRIB( R32G32_FLOAT, 2, CVT_32_FLOAT ) -FETCH_ATTRIB( R32_FLOAT, 1, CVT_32_FLOAT ) - -FETCH_ATTRIB( R32G32B32A32_USCALED, 4, CVT_32_USCALED ) -FETCH_ATTRIB( R32G32B32_USCALED, 3, CVT_32_USCALED ) -FETCH_ATTRIB( R32G32_USCALED, 2, CVT_32_USCALED ) -FETCH_ATTRIB( R32_USCALED, 1, CVT_32_USCALED ) - -FETCH_ATTRIB( R32G32B32A32_SSCALED, 4, CVT_32_SSCALED ) -FETCH_ATTRIB( R32G32B32_SSCALED, 3, CVT_32_SSCALED ) -FETCH_ATTRIB( R32G32_SSCALED, 2, CVT_32_SSCALED ) -FETCH_ATTRIB( R32_SSCALED, 1, CVT_32_SSCALED ) - -FETCH_ATTRIB( R32G32B32A32_UNORM, 4, CVT_32_UNORM ) -FETCH_ATTRIB( R32G32B32_UNORM, 3, CVT_32_UNORM ) -FETCH_ATTRIB( R32G32_UNORM, 2, CVT_32_UNORM ) -FETCH_ATTRIB( R32_UNORM, 1, CVT_32_UNORM ) - -FETCH_ATTRIB( R32G32B32A32_SNORM, 4, CVT_32_SNORM ) -FETCH_ATTRIB( R32G32B32_SNORM, 3, CVT_32_SNORM ) -FETCH_ATTRIB( R32G32_SNORM, 2, CVT_32_SNORM ) -FETCH_ATTRIB( R32_SNORM, 1, CVT_32_SNORM ) - -FETCH_ATTRIB( R16G16B16A16_USCALED, 4, CVT_16_USCALED ) -FETCH_ATTRIB( R16G16B16_USCALED, 3, CVT_16_USCALED ) -FETCH_ATTRIB( R16G16_USCALED, 2, CVT_16_USCALED ) -FETCH_ATTRIB( R16_USCALED, 1, CVT_16_USCALED ) - -FETCH_ATTRIB( R16G16B16A16_SSCALED, 4, CVT_16_SSCALED ) -FETCH_ATTRIB( R16G16B16_SSCALED, 3, CVT_16_SSCALED ) -FETCH_ATTRIB( R16G16_SSCALED, 2, CVT_16_SSCALED ) -FETCH_ATTRIB( R16_SSCALED, 1, CVT_16_SSCALED ) - -FETCH_ATTRIB( R16G16B16A16_UNORM, 4, CVT_16_UNORM ) -FETCH_ATTRIB( R16G16B16_UNORM, 3, CVT_16_UNORM ) -FETCH_ATTRIB( R16G16_UNORM, 2, CVT_16_UNORM ) -FETCH_ATTRIB( R16_UNORM, 1, CVT_16_UNORM ) - -FETCH_ATTRIB( R16G16B16A16_SNORM, 4, CVT_16_SNORM ) -FETCH_ATTRIB( R16G16B16_SNORM, 3, CVT_16_SNORM ) -FETCH_ATTRIB( R16G16_SNORM, 2, CVT_16_SNORM ) -FETCH_ATTRIB( R16_SNORM, 1, CVT_16_SNORM ) - -FETCH_ATTRIB( R8G8B8A8_USCALED, 4, CVT_8_USCALED ) -FETCH_ATTRIB( R8G8B8_USCALED, 3, CVT_8_USCALED ) -FETCH_ATTRIB( R8G8_USCALED, 2, CVT_8_USCALED ) -FETCH_ATTRIB( R8_USCALED, 1, CVT_8_USCALED ) - -FETCH_ATTRIB( R8G8B8A8_SSCALED, 4, CVT_8_SSCALED ) -FETCH_ATTRIB( R8G8B8_SSCALED, 3, CVT_8_SSCALED ) -FETCH_ATTRIB( R8G8_SSCALED, 2, CVT_8_SSCALED ) -FETCH_ATTRIB( R8_SSCALED, 1, CVT_8_SSCALED ) - -FETCH_ATTRIB( R8G8B8A8_UNORM, 4, CVT_8_UNORM ) -FETCH_ATTRIB( R8G8B8_UNORM, 3, CVT_8_UNORM ) -FETCH_ATTRIB( R8G8_UNORM, 2, CVT_8_UNORM ) -FETCH_ATTRIB( R8_UNORM, 1, CVT_8_UNORM ) - -FETCH_ATTRIB( R8G8B8A8_SNORM, 4, CVT_8_SNORM ) -FETCH_ATTRIB( R8G8B8_SNORM, 3, CVT_8_SNORM ) -FETCH_ATTRIB( R8G8_SNORM, 2, CVT_8_SNORM ) -FETCH_ATTRIB( R8_SNORM, 1, CVT_8_SNORM ) - -FETCH_ATTRIB( A8R8G8B8_UNORM, 4, CVT_8_UNORM ) -//FETCH_ATTRIB( R8G8B8A8_UNORM, 4, CVT_8_UNORM ) - - - -static void -fetch_B8G8R8A8_UNORM(const void *ptr, float *attrib) -{ - attrib[2] = CVT_8_UNORM(0); - attrib[1] = CVT_8_UNORM(1); - attrib[0] = CVT_8_UNORM(2); - attrib[3] = CVT_8_UNORM(3); -} - - -fetch_func draw_get_fetch_func( enum pipe_format format ) -{ -#if 0 - { - char tmp[80]; - pf_sprint_name(tmp, format); - debug_printf("%s: %s\n", __FUNCTION__, tmp); - } -#endif - - switch (format) { - case PIPE_FORMAT_R64_FLOAT: - return fetch_R64_FLOAT; - case PIPE_FORMAT_R64G64_FLOAT: - return fetch_R64G64_FLOAT; - case PIPE_FORMAT_R64G64B64_FLOAT: - return fetch_R64G64B64_FLOAT; - case PIPE_FORMAT_R64G64B64A64_FLOAT: - return fetch_R64G64B64A64_FLOAT; - - case PIPE_FORMAT_R32_FLOAT: - return fetch_R32_FLOAT; - case PIPE_FORMAT_R32G32_FLOAT: - return fetch_R32G32_FLOAT; - case PIPE_FORMAT_R32G32B32_FLOAT: - return fetch_R32G32B32_FLOAT; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - return fetch_R32G32B32A32_FLOAT; - - case PIPE_FORMAT_R32_UNORM: - return fetch_R32_UNORM; - case PIPE_FORMAT_R32G32_UNORM: - return fetch_R32G32_UNORM; - case PIPE_FORMAT_R32G32B32_UNORM: - return fetch_R32G32B32_UNORM; - case PIPE_FORMAT_R32G32B32A32_UNORM: - return fetch_R32G32B32A32_UNORM; - - case PIPE_FORMAT_R32_USCALED: - return fetch_R32_USCALED; - case PIPE_FORMAT_R32G32_USCALED: - return fetch_R32G32_USCALED; - case PIPE_FORMAT_R32G32B32_USCALED: - return fetch_R32G32B32_USCALED; - case PIPE_FORMAT_R32G32B32A32_USCALED: - return fetch_R32G32B32A32_USCALED; - - case PIPE_FORMAT_R32_SNORM: - return fetch_R32_SNORM; - case PIPE_FORMAT_R32G32_SNORM: - return fetch_R32G32_SNORM; - case PIPE_FORMAT_R32G32B32_SNORM: - return fetch_R32G32B32_SNORM; - case PIPE_FORMAT_R32G32B32A32_SNORM: - return fetch_R32G32B32A32_SNORM; - - case PIPE_FORMAT_R32_SSCALED: - return fetch_R32_SSCALED; - case PIPE_FORMAT_R32G32_SSCALED: - return fetch_R32G32_SSCALED; - case PIPE_FORMAT_R32G32B32_SSCALED: - return fetch_R32G32B32_SSCALED; - case PIPE_FORMAT_R32G32B32A32_SSCALED: - return fetch_R32G32B32A32_SSCALED; - - case PIPE_FORMAT_R16_UNORM: - return fetch_R16_UNORM; - case PIPE_FORMAT_R16G16_UNORM: - return fetch_R16G16_UNORM; - case PIPE_FORMAT_R16G16B16_UNORM: - return fetch_R16G16B16_UNORM; - case PIPE_FORMAT_R16G16B16A16_UNORM: - return fetch_R16G16B16A16_UNORM; - - case PIPE_FORMAT_R16_USCALED: - return fetch_R16_USCALED; - case PIPE_FORMAT_R16G16_USCALED: - return fetch_R16G16_USCALED; - case PIPE_FORMAT_R16G16B16_USCALED: - return fetch_R16G16B16_USCALED; - case PIPE_FORMAT_R16G16B16A16_USCALED: - return fetch_R16G16B16A16_USCALED; - - case PIPE_FORMAT_R16_SNORM: - return fetch_R16_SNORM; - case PIPE_FORMAT_R16G16_SNORM: - return fetch_R16G16_SNORM; - case PIPE_FORMAT_R16G16B16_SNORM: - return fetch_R16G16B16_SNORM; - case PIPE_FORMAT_R16G16B16A16_SNORM: - return fetch_R16G16B16A16_SNORM; - - case PIPE_FORMAT_R16_SSCALED: - return fetch_R16_SSCALED; - case PIPE_FORMAT_R16G16_SSCALED: - return fetch_R16G16_SSCALED; - case PIPE_FORMAT_R16G16B16_SSCALED: - return fetch_R16G16B16_SSCALED; - case PIPE_FORMAT_R16G16B16A16_SSCALED: - return fetch_R16G16B16A16_SSCALED; - - case PIPE_FORMAT_R8_UNORM: - return fetch_R8_UNORM; - case PIPE_FORMAT_R8G8_UNORM: - return fetch_R8G8_UNORM; - case PIPE_FORMAT_R8G8B8_UNORM: - return fetch_R8G8B8_UNORM; - case PIPE_FORMAT_R8G8B8A8_UNORM: - return fetch_R8G8B8A8_UNORM; - - case PIPE_FORMAT_R8_USCALED: - return fetch_R8_USCALED; - case PIPE_FORMAT_R8G8_USCALED: - return fetch_R8G8_USCALED; - case PIPE_FORMAT_R8G8B8_USCALED: - return fetch_R8G8B8_USCALED; - case PIPE_FORMAT_R8G8B8A8_USCALED: - return fetch_R8G8B8A8_USCALED; - - case PIPE_FORMAT_R8_SNORM: - return fetch_R8_SNORM; - case PIPE_FORMAT_R8G8_SNORM: - return fetch_R8G8_SNORM; - case PIPE_FORMAT_R8G8B8_SNORM: - return fetch_R8G8B8_SNORM; - case PIPE_FORMAT_R8G8B8A8_SNORM: - return fetch_R8G8B8A8_SNORM; - - case PIPE_FORMAT_R8_SSCALED: - return fetch_R8_SSCALED; - case PIPE_FORMAT_R8G8_SSCALED: - return fetch_R8G8_SSCALED; - case PIPE_FORMAT_R8G8B8_SSCALED: - return fetch_R8G8B8_SSCALED; - case PIPE_FORMAT_R8G8B8A8_SSCALED: - return fetch_R8G8B8A8_SSCALED; - - case PIPE_FORMAT_A8R8G8B8_UNORM: - return fetch_A8R8G8B8_UNORM; - - - case PIPE_FORMAT_B8G8R8A8_UNORM: - return fetch_B8G8R8A8_UNORM; - - case 0: - return NULL; /* not sure why this is needed */ - - default: - /* This can get hit because draw-state-validation is too eager, - and can jump in here validating stuff before the state tracker has set - up everything. - */ - /* assert(0); */ - return NULL; - } -} - - -static void -transpose_4x4( float *out, const float *in ) -{ - /* This can be achieved in 12 sse instructions, plus the final - * stores I guess. This is probably a bit more than that - maybe - * 32 or so? - */ - out[0] = in[0]; out[1] = in[4]; out[2] = in[8]; out[3] = in[12]; - out[4] = in[1]; out[5] = in[5]; out[6] = in[9]; out[7] = in[13]; - out[8] = in[2]; out[9] = in[6]; out[10] = in[10]; out[11] = in[14]; - out[12] = in[3]; out[13] = in[7]; out[14] = in[11]; out[15] = in[15]; -} - - - -static void fetch_xyz_rgb( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ) -{ - const unsigned *pitch = draw->vertex_fetch.pitch; - const ubyte **src = draw->vertex_fetch.src_ptr; - int i; - - assert(count <= 4); - -// debug_printf("%s\n", __FUNCTION__); - - /* loop over vertex attributes (vertex shader inputs) - */ - - for (i = 0; i < 4; i++) { - { - const float *in = (const float *)(src[0] + elts[i] * pitch[0]); - float *out = &machine->Inputs[0].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - - { - const float *in = (const float *)(src[1] + elts[i] * pitch[1]); - float *out = &machine->Inputs[1].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - } -} - - - - -static void fetch_xyz_rgb_st( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ) -{ - const unsigned *pitch = draw->vertex_fetch.pitch; - const ubyte **src = draw->vertex_fetch.src_ptr; - int i; - - assert(count <= 4); - - /* loop over vertex attributes (vertex shader inputs) - */ - - for (i = 0; i < 4; i++) { - { - const float *in = (const float *)(src[0] + elts[i] * pitch[0]); - float *out = &machine->Inputs[0].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - - { - const float *in = (const float *)(src[1] + elts[i] * pitch[1]); - float *out = &machine->Inputs[1].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - - { - const float *in = (const float *)(src[2] + elts[i] * pitch[2]); - float *out = &machine->Inputs[2].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = 0.0f; - out[12] = 1.0f; - } - } -} - - - - -/** - * Fetch vertex attributes for 'count' vertices. - */ -static void generic_vertex_fetch( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ) -{ - unsigned nr_attrs = draw->vertex_fetch.nr_attrs; - unsigned attr; - - assert(count <= 4); - -// debug_printf("%s %d\n", __FUNCTION__, count); - - /* loop over vertex attributes (vertex shader inputs) - */ - for (attr = 0; attr < nr_attrs; attr++) { - - const unsigned pitch = draw->vertex_fetch.pitch[attr]; - const ubyte *src = draw->vertex_fetch.src_ptr[attr]; - const fetch_func fetch = draw->vertex_fetch.fetch[attr]; - unsigned i; - float p[4][4]; - - - /* Fetch four attributes for four vertices. - * - * Could fetch directly into AOS format, but this is meant to be - * a prototype for an sse implementation, which would have - * difficulties doing that. - */ - for (i = 0; i < count; i++) - fetch( src + elts[i] * pitch, p[i] ); - - /* Be nice and zero out any missing vertices: - */ - for ( ; i < 4; i++) - p[i][0] = p[i][1] = p[i][2] = p[i][3] = 0; - - /* Transpose/swizzle into sse-friendly format. Currently - * assuming that all vertex shader inputs are float[4], but this - * isn't true -- if the vertex shader only wants tex0.xy, we - * could optimize for that. - * - * To do so fully without codegen would probably require an - * excessive number of fetch functions, but we could at least - * minimize the transpose step: - */ - transpose_4x4( (float *)&machine->Inputs[attr].xyzw[0].f[0], (float *)p ); - } -} - - - -void draw_update_vertex_fetch( struct draw_context *draw ) -{ - unsigned nr_attrs, i; - -// debug_printf("%s\n", __FUNCTION__); - - /* this may happend during context init */ - if (!draw->vertex_shader) - return; - - nr_attrs = draw->vertex_shader->info.num_inputs; - - for (i = 0; i < nr_attrs; i++) { - unsigned buf = draw->vertex_element[i].vertex_buffer_index; - enum pipe_format format = draw->vertex_element[i].src_format; - - draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] + - draw->vertex_buffer[buf].buffer_offset + - draw->vertex_element[i].src_offset; - - draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch; - draw->vertex_fetch.fetch[i] = draw_get_fetch_func( format ); - } - - draw->vertex_fetch.nr_attrs = nr_attrs; - - draw->vertex_fetch.fetch_func = generic_vertex_fetch; - - switch (nr_attrs) { - case 2: - if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT && - draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT) - draw->vertex_fetch.fetch_func = fetch_xyz_rgb; - break; - case 3: - if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT && - draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT && - draw->vertex_element[2].src_format == PIPE_FORMAT_R32G32_FLOAT) - draw->vertex_fetch.fetch_func = fetch_xyz_rgb_st; - break; - default: - break; - } - -} diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 5e27bc9ff0..c219a91156 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -55,7 +55,6 @@ static void vs_llvm_prepare( struct draw_vertex_shader *base, struct draw_context *draw ) { - draw_update_vertex_fetch( draw ); } diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 60f60a5b53..8e2d381f14 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -71,7 +71,6 @@ static void vs_sse_prepare( struct draw_vertex_shader *base, struct draw_context *draw ) { - draw_update_vertex_fetch( draw ); } -- cgit v1.2.3 From 6094e79f4e3350d123c7532b1c73faa60834a62d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:27:12 +0100 Subject: draw: remove dead data structures --- src/gallium/auxiliary/draw/draw_context.c | 20 ----------- src/gallium/auxiliary/draw/draw_private.h | 59 ------------------------------- 2 files changed, 79 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 9c3ae9bc0d..6012bc155e 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -83,16 +83,6 @@ struct draw_context *draw_create( void ) ASSIGN_4V( draw->plane[5], 0, 0, -1, 1 ); /* mesa's a bit wonky */ draw->nr_planes = 6; - /* Statically allocate maximum sized vertices for the cache - could be cleverer... - */ - { - char *tmp = align_malloc(VS_QUEUE_LENGTH * MAX_VERTEX_ALLOCATION, 16); - if (!tmp) - goto fail; - - draw->vs.vertex_cache = tmp; - } - /* these defaults are oriented toward the needs of softpipe */ draw->wide_point_threshold = 1000000.0; /* infinity */ draw->wide_line_threshold = 1.0; @@ -162,10 +152,6 @@ void draw_destroy( struct draw_context *draw ) align_free(draw->machine.Outputs); tgsi_exec_machine_free_data(&draw->machine); - - if (draw->vs.vertex_cache) - align_free( draw->vs.vertex_cache ); /* Frees all the vertices. */ - /* Not so fast -- we're just borrowing this at the moment. * if (draw->render) @@ -254,8 +240,6 @@ draw_set_vertex_buffers(struct draw_context *draw, { assert(count <= PIPE_MAX_ATTRIBS); - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - memcpy(draw->vertex_buffer, buffers, count * sizeof(buffers[0])); draw->nr_vertex_buffers = count; } @@ -268,8 +252,6 @@ draw_set_vertex_elements(struct draw_context *draw, { assert(count <= PIPE_MAX_ATTRIBS); - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - memcpy(draw->vertex_element, elements, count * sizeof(elements[0])); draw->nr_vertex_elements = count; } @@ -282,7 +264,6 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw, unsigned attr, const void *buffer) { - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); draw->user.vbuffer[attr] = buffer; } @@ -291,7 +272,6 @@ void draw_set_mapped_constant_buffer(struct draw_context *draw, const void *buffer) { - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); draw->user.constants = buffer; } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 93add257a3..78265c64a6 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -195,9 +195,6 @@ struct draw_context /* Support prototype passthrough path: */ struct { - unsigned prim; /* XXX: to be removed */ - unsigned hw_vertex_size; /* XXX: to be removed */ - struct { struct draw_pt_middle_end *opt[PT_MAX_MIDDLE]; } middle; @@ -272,54 +269,6 @@ struct draw_context /** TGSI program interpreter runtime state */ struct tgsi_exec_machine machine; - /* Vertex fetch internal state - */ - struct { - const ubyte *src_ptr[PIPE_MAX_ATTRIBS]; - unsigned pitch[PIPE_MAX_ATTRIBS]; - fetch_func fetch[PIPE_MAX_ATTRIBS]; - unsigned nr_attrs; - full_fetch_func fetch_func; - pt_fetch_func pt_fetch; - } vertex_fetch; - - /* Post-tnl vertex cache: - */ - struct { - unsigned referenced; /**< bitfield */ - - struct { - unsigned in; /* client array element */ - unsigned out; /* index in vs queue/array */ - } idx[VCACHE_SIZE + VCACHE_OVERFLOW]; - - unsigned overflow; - - /** To find space in the vertex cache: */ - struct vertex_header *(*get_vertex)( struct draw_context *draw, - unsigned i ); - } vcache; - - /* Vertex shader queue: - */ - struct { - unsigned elts[VS_QUEUE_LENGTH]; /**< index into the user's vertex arrays */ - char *vertex_cache; - unsigned queue_nr; - unsigned post_nr; - } vs; - - /* Prim pipeline queue: - */ - struct { - /* Need to queue up primitives until their vertices have been - * transformed by a vs queue flush. - */ - struct prim_header queue[PRIM_QUEUE_LENGTH]; - unsigned queue_nr; - } pq; - - /* This (and the tgsi_exec_machine struct) probably need to be moved somewhere private. */ struct gallivm_cpu_engine *engine; @@ -372,9 +321,6 @@ boolean draw_pt_arrays( struct draw_context *draw, void draw_pt_reset_vertex_ids( struct draw_context *draw ); -#define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ -#define DRAW_FLUSH_PRIM_QUEUE 0x2 -#define DRAW_FLUSH_VERTEX_CACHE 0x4 #define DRAW_FLUSH_STATE_CHANGE 0x8 #define DRAW_FLUSH_BACKEND 0x10 @@ -416,10 +362,5 @@ dot4(const float *a, const float *b) return result; } -static INLINE struct vertex_header * -draw_header_from_block(char *block, int size, int num) -{ - return (struct vertex_header*)(block + num * size); -} #endif /* DRAW_PRIVATE_H */ -- cgit v1.2.3 From 251ebcc175d479dda8d0d5b64fc42f44e747197e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:29:25 +0100 Subject: draw: remove more dead data structures --- src/gallium/auxiliary/draw/draw_private.h | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 78265c64a6..476b1184d4 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -128,31 +128,6 @@ struct draw_stage }; -#define PRIM_QUEUE_LENGTH 32 -#define VCACHE_SIZE 32 -#define VCACHE_OVERFLOW 4 -#define VS_QUEUE_LENGTH (VCACHE_SIZE + VCACHE_OVERFLOW + 1) /* can never fill up */ - - - -/* Internal function for vertex fetch. - */ -typedef void (*fetch_func)(const void *ptr, float *attrib); - -fetch_func draw_get_fetch_func( enum pipe_format format ); - - - -typedef void (*full_fetch_func)( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ); - -typedef void (*pt_fetch_func)( struct draw_context *draw, - float *out, - unsigned start, - unsigned count ); - struct vbuf_render; -- cgit v1.2.3 From 6d9132de04fc190fea56978849dfc427e5359912 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:31:06 +0100 Subject: draw: make draw_pt_fetch_emit use translate facility --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 186 +++++++++--------------- src/gallium/auxiliary/draw/draw_vbuf.c | 4 +- 2 files changed, 72 insertions(+), 118 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index d696afa1aa..6e4fea460b 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -36,6 +36,7 @@ #include "draw/draw_vbuf.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" +#include "translate/translate.h" /* The simplest 'middle end' in the new vertex code. * @@ -72,94 +73,15 @@ struct fetch_emit_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; - - struct { - const ubyte *ptr; - unsigned pitch; - void (*fetch)( const void *from, float *attrib); - void (*emit)( const float *attrib, float **out ); - } fetch[PIPE_MAX_ATTRIBS]; - unsigned nr_fetch; - unsigned hw_vertex_size; -}; - - - -static void fetch_R32_FLOAT( const void *from, - float *attrib ) -{ - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = 0.0; - attrib[2] = 0.0; - attrib[3] = 1.0; -} - - -static void emit_R32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out) += 1; -} - -static void emit_R32G32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out) += 2; -} - -static void emit_R32G32B32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out) += 3; -} - -static void emit_R32G32B32A32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out)[3] = attrib[3]; - (*out) += 4; -} + struct translate *translate; + /* Cache point size somewhere it's address won't change: + */ + float point_size; -/** - * General-purpose fetch from user's vertex arrays, emit to driver's - * vertex buffer. - * - * XXX this is totally temporary. - */ -static void -fetch_store_general( struct fetch_emit_middle_end *feme, - void *out_ptr, - const unsigned *fetch_elts, - unsigned count ) -{ - float *out = (float *)out_ptr; - uint i, j; +}; - for (i = 0; i < count; i++) { - unsigned elt = fetch_elts[i] & ~DRAW_PT_FLAG_MASK; - - for (j = 0; j < feme->nr_fetch; j++) { - float attrib[4]; - const ubyte *from = (feme->fetch[j].ptr + - feme->fetch[j].pitch * elt); - - feme->fetch[j].fetch( from, attrib ); - feme->fetch[j].emit( attrib, &out ); - } - } -} @@ -170,8 +92,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; const struct vertex_info *vinfo; - unsigned i; + unsigned i, dst_offset; boolean ok; + struct translate_key key; ok = draw->render->set_primitive( draw->render, @@ -186,51 +109,82 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, vinfo = draw->render->get_vertex_info(draw->render); - /* This is unique as it transforms straight from API vertex - * information to HW vertices. All other cases go through our - * intermediate float[4] format. + + /* Transform from API vertices to HW vertices, skipping the + * pipeline_vertex intermediate step. */ - for (i = 0; i < vinfo->num_attribs; i++) { - unsigned src_element = vinfo->src_index[i]; - unsigned src_buffer = draw->vertex_element[src_element].vertex_buffer_index; - - feme->fetch[i].ptr = ((const ubyte *)draw->user.vbuffer[src_buffer] + - draw->vertex_buffer[src_buffer].buffer_offset + - draw->vertex_element[src_element].src_offset); + dst_offset = 0; + memset(&key, 0, sizeof(key)); - feme->fetch[i].pitch = draw->vertex_buffer[src_buffer].pitch; - - feme->fetch[i].fetch = draw_get_fetch_func(draw->vertex_element[src_element].src_format); + for (i = 0; i < vinfo->num_attribs; i++) { + const struct pipe_vertex_element *src = &draw->vertex_element[vinfo->src_index[i]]; + unsigned emit_sz = 0; + unsigned input_format = src->src_format; + unsigned input_buffer = src->vertex_buffer_index; + unsigned input_offset = src->src_offset; + unsigned output_format; switch (vinfo->emit[i]) { case EMIT_4F: - feme->fetch[i].emit = emit_R32G32B32A32_FLOAT; + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); break; case EMIT_3F: - feme->fetch[i].emit = emit_R32G32B32_FLOAT; + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); break; case EMIT_2F: - feme->fetch[i].emit = emit_R32G32_FLOAT; + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); break; case EMIT_1F: - feme->fetch[i].emit = emit_R32_FLOAT; + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); break; case EMIT_1F_PSIZE: - feme->fetch[i].ptr = (const ubyte *)&feme->draw->rasterizer->point_size; - feme->fetch[i].pitch = 0; - feme->fetch[i].fetch = fetch_R32_FLOAT; - feme->fetch[i].emit = emit_R32_FLOAT; + input_format = PIPE_FORMAT_R32_FLOAT; + input_buffer = draw->nr_vertex_buffers; + input_offset = 0; + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); break; default: assert(0); - feme->fetch[i].emit = NULL; - break; + output_format = PIPE_FORMAT_NONE; + emit_sz = 0; + continue; } + + key.element[i].input_format = input_format; + key.element[i].input_buffer = input_buffer; + key.element[i].input_offset = input_offset; + key.element[i].output_format = output_format; + key.element[i].output_offset = dst_offset; + + dst_offset += emit_sz; } - feme->nr_fetch = vinfo->num_attribs; - feme->hw_vertex_size = vinfo->size * 4; + key.nr_elements = vinfo->num_attribs; + key.output_stride = vinfo->size * 4; + + /* Don't bother with caching at this stage: + */ + if (!feme->translate || + memcmp(&feme->translate->key, &key, sizeof(key)) != 0) + { + if (feme->translate) + feme->translate->release(feme->translate); + + feme->translate = translate_create( &key ); + + feme->translate->set_buffer(feme->translate, + draw->nr_vertex_buffers, + &feme->point_size, + 0); + } + + feme->point_size = draw->rasterizer->point_size; } @@ -252,7 +206,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, draw_do_flush( draw, DRAW_FLUSH_BACKEND ); hw_verts = draw->render->allocate_vertices( draw->render, - (ushort)feme->hw_vertex_size, + (ushort)feme->translate->key.output_stride, (ushort)fetch_count ); if (!hw_verts) { assert(0); @@ -262,10 +216,10 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, /* Single routine to fetch vertices and emit HW verts. */ - fetch_store_general( feme, - hw_verts, - fetch_elts, - fetch_count ); + feme->translate->run_elts( feme->translate, + fetch_elts, + fetch_count, + hw_verts ); /* XXX: Draw arrays path to avoid re-emitting index list again and * again. @@ -278,7 +232,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, */ draw->render->release_vertices( draw->render, hw_verts, - feme->hw_vertex_size, + feme->translate->key.output_stride, fetch_count ); } diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c index dbbcf05c3c..30dceeb43d 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_vbuf.c @@ -439,8 +439,8 @@ vbuf_alloc_vertices( struct vbuf_stage *vbuf ) /* Allocate a new vertex buffer */ vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, - (ushort) vbuf->vertex_size, - (ushort) vbuf->max_vertices); + (ushort) vbuf->vertex_size, + (ushort) vbuf->max_vertices); vbuf->vertex_ptr = vbuf->vertices; } -- cgit v1.2.3 From 6494946db66b62d280e34a0486b83cca15f5b457 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:36:35 +0100 Subject: draw: remove draw_debug.c --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/SConscript | 1 - src/gallium/auxiliary/draw/draw_debug.c | 113 -------------------------------- 3 files changed, 115 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_debug.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 60bb9dfe88..45def9153c 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -12,7 +12,6 @@ C_SOURCES = \ draw_vs_llvm.c \ draw_context.c\ draw_cull.c \ - draw_debug.c \ draw_flatshade.c \ draw_offset.c \ draw_pt.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 246083a962..bff32d2c8b 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -8,7 +8,6 @@ draw = env.ConvenienceLibrary( 'draw_clip.c', 'draw_context.c', 'draw_cull.c', - 'draw_debug.c', 'draw_flatshade.c', 'draw_offset.c', 'draw_pstipple.c', diff --git a/src/gallium/auxiliary/draw/draw_debug.c b/src/gallium/auxiliary/draw/draw_debug.c deleted file mode 100644 index d6220b5f62..0000000000 --- a/src/gallium/auxiliary/draw/draw_debug.c +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#include "draw_private.h" -#include "draw_context.h" - - - -static void -draw_prim_info(unsigned prim, unsigned *first, unsigned *incr) -{ - assert(prim >= PIPE_PRIM_POINTS); - assert(prim <= PIPE_PRIM_POLYGON); - - switch (prim) { - case PIPE_PRIM_POINTS: - *first = 1; - *incr = 1; - break; - case PIPE_PRIM_LINES: - *first = 2; - *incr = 2; - break; - case PIPE_PRIM_LINE_STRIP: - *first = 2; - *incr = 1; - break; - case PIPE_PRIM_LINE_LOOP: - *first = 2; - *incr = 1; - break; - case PIPE_PRIM_TRIANGLES: - *first = 3; - *incr = 3; - break; - case PIPE_PRIM_TRIANGLE_STRIP: - *first = 3; - *incr = 1; - break; - case PIPE_PRIM_TRIANGLE_FAN: - case PIPE_PRIM_POLYGON: - *first = 3; - *incr = 1; - break; - case PIPE_PRIM_QUADS: - *first = 4; - *incr = 4; - break; - case PIPE_PRIM_QUAD_STRIP: - *first = 4; - *incr = 2; - break; - default: - assert(0); - *first = 1; - *incr = 1; - break; - } -} - - -unsigned -draw_trim_prim( unsigned mode, unsigned count ) -{ - unsigned length, first, incr; - - draw_prim_info( mode, &first, &incr ); - - if (count < first) - length = 0; - else - length = count - (count - first) % incr; - - return length; -} - - -boolean -draw_validate_prim( unsigned mode, unsigned count ) -{ - return (count > 0 && - count == draw_trim_prim( mode, count )); -} - -- cgit v1.2.3 From 6c38c600ff1212699e2e8e0f2928cd9e69559ac5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:37:51 +0100 Subject: draw: rename draw_vertex_shader.c -> draw_vs.c --- src/gallium/auxiliary/draw/Makefile | 2 +- src/gallium/auxiliary/draw/SConscript | 2 +- src/gallium/auxiliary/draw/draw_vertex_shader.c | 85 ------------------------- src/gallium/auxiliary/draw/draw_vs.c | 85 +++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 87 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_vertex_shader.c create mode 100644 src/gallium/auxiliary/draw/draw_vs.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 45def9153c..9c41649883 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -7,6 +7,7 @@ C_SOURCES = \ draw_aaline.c \ draw_aapoint.c \ draw_clip.c \ + draw_vs.c \ draw_vs_exec.c \ draw_vs_sse.c \ draw_vs_llvm.c \ @@ -30,7 +31,6 @@ C_SOURCES = \ draw_validate.c \ draw_vbuf.c \ draw_vertex.c \ - draw_vertex_shader.c \ draw_wide_line.c \ draw_wide_point.c diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index bff32d2c8b..388d7879dd 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -26,7 +26,7 @@ draw = env.ConvenienceLibrary( 'draw_validate.c', 'draw_vbuf.c', 'draw_vertex.c', - 'draw_vertex_shader.c', + 'draw_vs.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', 'draw_vs_sse.c', diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c deleted file mode 100644 index 03fe00a951..0000000000 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - * Brian Paul - */ - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" -#include "draw_context.h" -#include "draw_vs.h" - - - -struct draw_vertex_shader * -draw_create_vertex_shader(struct draw_context *draw, - const struct pipe_shader_state *shader) -{ - struct draw_vertex_shader *vs; - - vs = draw_create_vs_llvm( draw, shader ); - if (!vs) { - vs = draw_create_vs_sse( draw, shader ); - if (!vs) { - vs = draw_create_vs_exec( draw, shader ); - } - } - - assert(vs); - return vs; -} - - -void -draw_bind_vertex_shader(struct draw_context *draw, - struct draw_vertex_shader *dvs) -{ - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - - if (dvs) - { - draw->vertex_shader = dvs; - draw->num_vs_outputs = dvs->info.num_outputs; - dvs->prepare( dvs, draw ); - } - else { - draw->vertex_shader = NULL; - draw->num_vs_outputs = 0; - } -} - - -void -draw_delete_vertex_shader(struct draw_context *draw, - struct draw_vertex_shader *dvs) -{ - dvs->delete( dvs ); -} diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c new file mode 100644 index 0000000000..03fe00a951 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -0,0 +1,85 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + * Brian Paul + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" +#include "draw_context.h" +#include "draw_vs.h" + + + +struct draw_vertex_shader * +draw_create_vertex_shader(struct draw_context *draw, + const struct pipe_shader_state *shader) +{ + struct draw_vertex_shader *vs; + + vs = draw_create_vs_llvm( draw, shader ); + if (!vs) { + vs = draw_create_vs_sse( draw, shader ); + if (!vs) { + vs = draw_create_vs_exec( draw, shader ); + } + } + + assert(vs); + return vs; +} + + +void +draw_bind_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + if (dvs) + { + draw->vertex_shader = dvs; + draw->num_vs_outputs = dvs->info.num_outputs; + dvs->prepare( dvs, draw ); + } + else { + draw->vertex_shader = NULL; + draw->num_vs_outputs = 0; + } +} + + +void +draw_delete_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs) +{ + dvs->delete( dvs ); +} -- cgit v1.2.3 From 1b411f894369f6a55c6f11cf650511eaa18a8510 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:39:38 +0100 Subject: draw: sort makefile sources --- src/gallium/auxiliary/draw/Makefile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 9c41649883..0b0578a179 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -7,30 +7,30 @@ C_SOURCES = \ draw_aaline.c \ draw_aapoint.c \ draw_clip.c \ - draw_vs.c \ - draw_vs_exec.c \ - draw_vs_sse.c \ - draw_vs_llvm.c \ draw_context.c\ draw_cull.c \ draw_flatshade.c \ draw_offset.c \ + draw_pstipple.c \ draw_pt.c \ - draw_pt_vcache.c \ + draw_pt_elts.c \ + draw_pt_emit.c \ + draw_pt_fetch.c \ draw_pt_fetch_emit.c \ draw_pt_fetch_shade_pipeline.c \ - draw_pt_fetch.c \ - draw_pt_post_vs.c \ - draw_pt_emit.c \ draw_pt_pipeline.c \ - draw_pt_elts.c \ - draw_pstipple.c \ + draw_pt_post_vs.c \ + draw_pt_vcache.c \ draw_stipple.c \ draw_twoside.c \ draw_unfilled.c \ draw_validate.c \ draw_vbuf.c \ draw_vertex.c \ + draw_vs.c \ + draw_vs_exec.c \ + draw_vs_llvm.c \ + draw_vs_sse.c \ draw_wide_line.c \ draw_wide_point.c -- cgit v1.2.3 From c717f1fbe25f16ce6e607b0f7319ce74f9ae99b4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:43:58 +0100 Subject: softpipe: don't need to trim prims --- src/gallium/drivers/softpipe/sp_draw_arrays.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 421509495a..778291dded 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -118,17 +118,6 @@ softpipe_draw_elements(struct pipe_context *pipe, struct draw_context *draw = sp->draw; unsigned i; - /* first, check that the primitive is not malformed. It is the - * state tracker's responsibility to do send only correctly formed - * primitives down. It currently isn't doing that though... - */ -#if 1 - count = draw_trim_prim( mode, count ); -#else - if (!draw_validate_prim( mode, count )) - assert(0); -#endif - sp->reduced_api_prim = reduced_prim[mode]; if (sp->dirty) -- cgit v1.2.3 From 43452886e2e33e33bdc57abe7e0b4af0abbbd2b1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:44:09 +0100 Subject: cell: don't need to trim prims --- src/gallium/drivers/cell/ppu/cell_draw_arrays.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index 36af5be5f0..6e08cf6fe8 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -101,17 +101,6 @@ cell_draw_elements(struct pipe_context *pipe, struct draw_context *draw = sp->draw; unsigned i; - /* first, check that the primitive is not malformed. It is the - * state tracker's responsibility to do send only correctly formed - * primitives down. It currently isn't doing that though... - */ -#if 1 - count = draw_trim_prim( mode, count ); -#else - if (!draw_validate_prim( mode, count )) - assert(0); -#endif - if (sp->dirty) cell_update_derived( sp ); -- cgit v1.2.3 From 26831bdac594a11e51b6c4b09df78bb11444f5dd Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:45:05 +0100 Subject: draw: rename pipeline files to draw_pipe_* --- src/gallium/auxiliary/draw/Makefile | 32 +- src/gallium/auxiliary/draw/SConscript | 30 +- src/gallium/auxiliary/draw/draw_aaline.c | 859 ---------------------- src/gallium/auxiliary/draw/draw_aapoint.c | 846 --------------------- src/gallium/auxiliary/draw/draw_clip.c | 503 ------------- src/gallium/auxiliary/draw/draw_cull.c | 150 ---- src/gallium/auxiliary/draw/draw_flatshade.c | 248 ------- src/gallium/auxiliary/draw/draw_offset.c | 186 ----- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 859 ++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 846 +++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pipe_clip.c | 503 +++++++++++++ src/gallium/auxiliary/draw/draw_pipe_cull.c | 150 ++++ src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 248 +++++++ src/gallium/auxiliary/draw/draw_pipe_offset.c | 186 +++++ src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 746 +++++++++++++++++++ src/gallium/auxiliary/draw/draw_pipe_stipple.c | 239 ++++++ src/gallium/auxiliary/draw/draw_pipe_twoside.c | 203 +++++ src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 206 ++++++ src/gallium/auxiliary/draw/draw_pipe_validate.c | 312 ++++++++ src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 529 +++++++++++++ src/gallium/auxiliary/draw/draw_pipe_wide_line.c | 190 +++++ src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 281 +++++++ src/gallium/auxiliary/draw/draw_pipe_wide_prims.c | 366 +++++++++ src/gallium/auxiliary/draw/draw_pstipple.c | 746 ------------------- src/gallium/auxiliary/draw/draw_stipple.c | 239 ------ src/gallium/auxiliary/draw/draw_twoside.c | 203 ----- src/gallium/auxiliary/draw/draw_unfilled.c | 206 ------ src/gallium/auxiliary/draw/draw_validate.c | 312 -------- src/gallium/auxiliary/draw/draw_vbuf.c | 529 ------------- src/gallium/auxiliary/draw/draw_wide_line.c | 190 ----- src/gallium/auxiliary/draw/draw_wide_point.c | 281 ------- src/gallium/auxiliary/draw/draw_wide_prims.c | 366 --------- 32 files changed, 5895 insertions(+), 5895 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_aaline.c delete mode 100644 src/gallium/auxiliary/draw/draw_aapoint.c delete mode 100644 src/gallium/auxiliary/draw/draw_clip.c delete mode 100644 src/gallium/auxiliary/draw/draw_cull.c delete mode 100644 src/gallium/auxiliary/draw/draw_flatshade.c delete mode 100644 src/gallium/auxiliary/draw/draw_offset.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_aaline.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_aapoint.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_clip.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_cull.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_flatshade.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_offset.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_pstipple.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_stipple.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_twoside.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_unfilled.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_validate.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_vbuf.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_wide_line.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_wide_point.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_wide_prims.c delete mode 100644 src/gallium/auxiliary/draw/draw_pstipple.c delete mode 100644 src/gallium/auxiliary/draw/draw_stipple.c delete mode 100644 src/gallium/auxiliary/draw/draw_twoside.c delete mode 100644 src/gallium/auxiliary/draw/draw_unfilled.c delete mode 100644 src/gallium/auxiliary/draw/draw_validate.c delete mode 100644 src/gallium/auxiliary/draw/draw_vbuf.c delete mode 100644 src/gallium/auxiliary/draw/draw_wide_line.c delete mode 100644 src/gallium/auxiliary/draw/draw_wide_point.c delete mode 100644 src/gallium/auxiliary/draw/draw_wide_prims.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 0b0578a179..62f46c6db1 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -4,14 +4,21 @@ include $(TOP)/configs/current LIBNAME = draw C_SOURCES = \ - draw_aaline.c \ - draw_aapoint.c \ - draw_clip.c \ - draw_context.c\ - draw_cull.c \ - draw_flatshade.c \ - draw_offset.c \ - draw_pstipple.c \ + draw_context.c \ + draw_pipe_aaline.c \ + draw_pipe_aapoint.c \ + draw_pipe_clip.c \ + draw_pipe_cull.c \ + draw_pipe_flatshade.c \ + draw_pipe_offset.c \ + draw_pipe_pstipple.c \ + draw_pipe_stipple.c \ + draw_pipe_twoside.c \ + draw_pipe_unfilled.c \ + draw_pipe_validate.c \ + draw_pipe_vbuf.c \ + draw_pipe_wide_line.c \ + draw_pipe_wide_point.c \ draw_pt.c \ draw_pt_elts.c \ draw_pt_emit.c \ @@ -21,18 +28,11 @@ C_SOURCES = \ draw_pt_pipeline.c \ draw_pt_post_vs.c \ draw_pt_vcache.c \ - draw_stipple.c \ - draw_twoside.c \ - draw_unfilled.c \ - draw_validate.c \ - draw_vbuf.c \ draw_vertex.c \ draw_vs.c \ draw_vs_exec.c \ draw_vs_llvm.c \ - draw_vs_sse.c \ - draw_wide_line.c \ - draw_wide_point.c + draw_vs_sse.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 388d7879dd..5fa35d3005 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -3,14 +3,22 @@ Import('*') draw = env.ConvenienceLibrary( target = 'draw', source = [ - 'draw_aaline.c', - 'draw_aapoint.c', - 'draw_clip.c', 'draw_context.c', - 'draw_cull.c', - 'draw_flatshade.c', - 'draw_offset.c', - 'draw_pstipple.c', + 'draw_pipe_aaline.c', + 'draw_pipe_aapoint.c', + 'draw_pipe_clip.c', + 'draw_pipe_cull.c', + 'draw_pipe_flatshade.c', + 'draw_pipe_offset.c', + 'draw_pipe_pstipple.c', + 'draw_pipe_stipple.c', + 'draw_pipe_twoside.c', + 'draw_pipe_unfilled.c', + 'draw_pipe_validate.c', + 'draw_pipe_vbuf.c', + 'draw_pipe_vertex.c', + 'draw_pipe_wide_line.c', + 'draw_pipe_wide_point.c', 'draw_pt.c', 'draw_pt_elts.c', 'draw_pt_emit.c', @@ -20,18 +28,10 @@ draw = env.ConvenienceLibrary( 'draw_pt_pipeline.c', 'draw_pt_post_vs.c', 'draw_pt_vcache.c', - 'draw_stipple.c', - 'draw_twoside.c', - 'draw_unfilled.c', - 'draw_validate.c', - 'draw_vbuf.c', - 'draw_vertex.c', 'draw_vs.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', 'draw_vs_sse.c', - 'draw_wide_line.c', - 'draw_wide_point.c', ]) auxiliaries.insert(0, draw) diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c deleted file mode 100644 index e8d2a45102..0000000000 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ /dev/null @@ -1,859 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * AA line stage: AA lines are converted to texture mapped triangles. - * - * Authors: Brian Paul - */ - - -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/util/tgsi_transform.h" -#include "tgsi/util/tgsi_dump.h" - -#include "draw_context.h" -#include "draw_private.h" - - -/** - * Max texture level for the alpha texture used for antialiasing - */ -#define MAX_TEXTURE_LEVEL 5 /* 32 x 32 */ - - -/** - * Subclass of pipe_shader_state to carry extra fragment shader info. - */ -struct aaline_fragment_shader -{ - struct pipe_shader_state state; - void *driver_fs; - void *aaline_fs; - void *aapoint_fs; /* not yet */ - void *sprite_fs; /* not yet */ - uint sampler_unit; - int generic_attrib; /**< texcoord/generic used for texture */ -}; - - -/** - * Subclass of draw_stage - */ -struct aaline_stage -{ - struct draw_stage stage; - - float half_line_width; - - /** For AA lines, this is the vertex attrib slot for the new texcoords */ - uint tex_slot; - - void *sampler_cso; - struct pipe_texture *texture; - uint num_samplers; - uint num_textures; - - - /* - * Currently bound state - */ - struct aaline_fragment_shader *fs; - struct { - void *sampler[PIPE_MAX_SAMPLERS]; - struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; - } state; - - /* - * Driver interface/override functions - */ - void * (*driver_create_fs_state)(struct pipe_context *, - const struct pipe_shader_state *); - void (*driver_bind_fs_state)(struct pipe_context *, void *); - void (*driver_delete_fs_state)(struct pipe_context *, void *); - - void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, - void **); - void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, - struct pipe_texture **); - - struct pipe_context *pipe; -}; - - - -/** - * Subclass of tgsi_transform_context, used for transforming the - * user's fragment shader to add the special AA instructions. - */ -struct aa_transform_context { - struct tgsi_transform_context base; - uint tempsUsed; /**< bitmask */ - int colorOutput; /**< which output is the primary color */ - uint samplersUsed; /**< bitfield of samplers used */ - int freeSampler; /** an available sampler for the pstipple */ - int maxInput, maxGeneric; /**< max input index found */ - int colorTemp, texTemp; /**< temp registers */ - boolean firstInstruction; -}; - - -/** - * TGSI declaration transform callback. - * Look for a free sampler, a free input attrib, and two free temp regs. - */ -static void -aa_transform_decl(struct tgsi_transform_context *ctx, - struct tgsi_full_declaration *decl) -{ - struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; - - if (decl->Declaration.File == TGSI_FILE_OUTPUT && - decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && - decl->Semantic.SemanticIndex == 0) { - aactx->colorOutput = decl->u.DeclarationRange.First; - } - else if (decl->Declaration.File == TGSI_FILE_SAMPLER) { - uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { - aactx->samplersUsed |= 1 << i; - } - } - else if (decl->Declaration.File == TGSI_FILE_INPUT) { - if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) - aactx->maxInput = decl->u.DeclarationRange.Last; - if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && - (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { - aactx->maxGeneric = decl->Semantic.SemanticIndex; - } - } - else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { - uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { - aactx->tempsUsed |= (1 << i); - } - } - - ctx->emit_declaration(ctx, decl); -} - - -/** - * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. - */ -static int -free_bit(uint bitfield) -{ - int i; - for (i = 0; i < 32; i++) { - if ((bitfield & (1 << i)) == 0) - return i; - } - return -1; -} - - -/** - * TGSI instruction transform callback. - * Replace writes to result.color w/ a temp reg. - * Upon END instruction, insert texture sampling code for antialiasing. - */ -static void -aa_transform_inst(struct tgsi_transform_context *ctx, - struct tgsi_full_instruction *inst) -{ - struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; - - if (aactx->firstInstruction) { - /* emit our new declarations before the first instruction */ - - struct tgsi_full_declaration decl; - uint i; - - /* find free sampler */ - aactx->freeSampler = free_bit(aactx->samplersUsed); - if (aactx->freeSampler >= PIPE_MAX_SAMPLERS) - aactx->freeSampler = PIPE_MAX_SAMPLERS - 1; - - /* find two free temp regs */ - for (i = 0; i < 32; i++) { - if ((aactx->tempsUsed & (1 << i)) == 0) { - /* found a free temp */ - if (aactx->colorTemp < 0) - aactx->colorTemp = i; - else if (aactx->texTemp < 0) - aactx->texTemp = i; - else - break; - } - } - assert(aactx->colorTemp >= 0); - assert(aactx->texTemp >= 0); - - /* declare new generic input/texcoord */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; - decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; - decl.Declaration.Interpolate = 1; - /* XXX this could be linear... */ - decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->maxInput + 1; - ctx->emit_declaration(ctx, &decl); - - /* declare new sampler */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_SAMPLER; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->freeSampler; - ctx->emit_declaration(ctx, &decl); - - /* declare new temp regs */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->texTemp; - ctx->emit_declaration(ctx, &decl); - - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->colorTemp; - ctx->emit_declaration(ctx, &decl); - - aactx->firstInstruction = FALSE; - } - - if (inst->Instruction.Opcode == TGSI_OPCODE_END && - aactx->colorOutput != -1) { - struct tgsi_full_instruction newInst; - - /* TEX */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_TEX; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = aactx->texTemp; - newInst.Instruction.NumSrcRegs = 2; - newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->freeSampler; - - ctx->emit_instruction(ctx, &newInst); - - /* MOV rgb */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MOV; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; - ctx->emit_instruction(ctx, &newInst); - - /* MUL alpha */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MUL; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->texTemp; - ctx->emit_instruction(ctx, &newInst); - - /* END */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_END; - newInst.Instruction.NumDstRegs = 0; - newInst.Instruction.NumSrcRegs = 0; - ctx->emit_instruction(ctx, &newInst); - } - else { - /* Not an END instruction. - * Look for writes to result.color and replace with colorTemp reg. - */ - uint i; - - for (i = 0; i < inst->Instruction.NumDstRegs; i++) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - if (dst->DstRegister.File == TGSI_FILE_OUTPUT && - dst->DstRegister.Index == aactx->colorOutput) { - dst->DstRegister.File = TGSI_FILE_TEMPORARY; - dst->DstRegister.Index = aactx->colorTemp; - } - } - - ctx->emit_instruction(ctx, inst); - } -} - - -/** - * Generate the frag shader we'll use for drawing AA lines. - * This will be the user's shader plus some texture/modulate instructions. - */ -static void -generate_aaline_fs(struct aaline_stage *aaline) -{ - const struct pipe_shader_state *orig_fs = &aaline->fs->state; - //struct draw_context *draw = aaline->stage.draw; - struct pipe_shader_state aaline_fs; - struct aa_transform_context transform; - -#define MAX 1000 - - aaline_fs = *orig_fs; /* copy to init */ - aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); - - memset(&transform, 0, sizeof(transform)); - transform.colorOutput = -1; - transform.maxInput = -1; - transform.maxGeneric = -1; - transform.colorTemp = -1; - transform.texTemp = -1; - transform.firstInstruction = TRUE; - transform.base.transform_instruction = aa_transform_inst; - transform.base.transform_declaration = aa_transform_decl; - - tgsi_transform_shader(orig_fs->tokens, - (struct tgsi_token *) aaline_fs.tokens, - MAX, &transform.base); - -#if 0 /* DEBUG */ - tgsi_dump(orig_fs->tokens, 0); - tgsi_dump(aaline_fs.tokens, 0); -#endif - - aaline->fs->sampler_unit = transform.freeSampler; - - aaline->fs->aaline_fs - = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); - - aaline->fs->generic_attrib = transform.maxGeneric + 1; -} - - -/** - * Create the texture map we'll use for antialiasing the lines. - */ -static void -aaline_create_texture(struct aaline_stage *aaline) -{ - struct pipe_context *pipe = aaline->pipe; - struct pipe_screen *screen = pipe->screen; - struct pipe_texture texTemp; - uint level; - - memset(&texTemp, 0, sizeof(texTemp)); - texTemp.target = PIPE_TEXTURE_2D; - texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ - texTemp.last_level = MAX_TEXTURE_LEVEL; - texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL; - texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL; - texTemp.depth[0] = 1; - texTemp.cpp = 1; - - aaline->texture = screen->texture_create(screen, &texTemp); - - /* Fill in mipmap images. - * Basically each level is solid opaque, except for the outermost - * texels which are zero. Special case the 1x1 and 2x2 levels. - */ - for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) { - struct pipe_surface *surface; - const uint size = aaline->texture->width[level]; - ubyte *data; - uint i, j; - - assert(aaline->texture->width[level] == aaline->texture->height[level]); - - surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0); - data = pipe_surface_map(surface); - - for (i = 0; i < size; i++) { - for (j = 0; j < size; j++) { - ubyte d; - if (size == 1) { - d = 255; - } - else if (size == 2) { - d = 200; /* tuneable */ - } - else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) { - d = 0; - } - else { - d = 255; - } - data[i * surface->pitch + j] = d; - } - } - - /* unmap */ - pipe_surface_unmap(surface); - pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, aaline->texture, 0, (1 << level)); - } -} - - -/** - * Create the sampler CSO that'll be used for antialiasing. - * By using a mipmapped texture, we don't have to generate a different - * texture image for each line size. - */ -static void -aaline_create_sampler(struct aaline_stage *aaline) -{ - struct pipe_sampler_state sampler; - struct pipe_context *pipe = aaline->pipe; - - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR; - sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.normalized_coords = 1; - sampler.min_lod = 0.0f; - sampler.max_lod = MAX_TEXTURE_LEVEL; - - aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler); -} - - -/** - * When we're about to draw our first AA line in a batch, this function is - * called to tell the driver to bind our modified fragment shader. - */ -static void -bind_aaline_fragment_shader(struct aaline_stage *aaline) -{ - if (!aaline->fs->aaline_fs) { - generate_aaline_fs(aaline); - } - aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs); -} - - - -static INLINE struct aaline_stage * -aaline_stage( struct draw_stage *stage ) -{ - return (struct aaline_stage *) stage; -} - - -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Draw a wide line by drawing a quad, using geometry which will - * fullfill GL's antialiased line requirements. - */ -static void -aaline_line(struct draw_stage *stage, struct prim_header *header) -{ - const struct aaline_stage *aaline = aaline_stage(stage); - const float half_width = aaline->half_line_width; - struct prim_header tri; - struct vertex_header *v[8]; - uint texPos = aaline->tex_slot; - float *pos, *tex; - float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; - float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; - double a = atan2(dy, dx); - float c_a = (float) cos(a), s_a = (float) sin(a); - uint i; - - /* XXX the ends of lines aren't quite perfect yet, but probably passable */ - dx = 0.5F * half_width; - dy = half_width; - - /* allocate/dup new verts */ - for (i = 0; i < 8; i++) { - v[i] = dup_vert(stage, header->v[i/4], i); - } - - /* - * Quad strip for line from v0 to v1 (*=endpoints): - * - * 1 3 5 7 - * +---+---------------------+---+ - * | | - * | *v0 v1* | - * | | - * +---+---------------------+---+ - * 0 2 4 6 - */ - - /* new verts */ - pos = v[0]->data[0]; - pos[0] += (-dx * c_a - dy * s_a); - pos[1] += (-dx * s_a + dy * c_a); - - pos = v[1]->data[0]; - pos[0] += (-dx * c_a - -dy * s_a); - pos[1] += (-dx * s_a + -dy * c_a); - - pos = v[2]->data[0]; - pos[0] += ( dx * c_a - dy * s_a); - pos[1] += ( dx * s_a + dy * c_a); - - pos = v[3]->data[0]; - pos[0] += ( dx * c_a - -dy * s_a); - pos[1] += ( dx * s_a + -dy * c_a); - - pos = v[4]->data[0]; - pos[0] += (-dx * c_a - dy * s_a); - pos[1] += (-dx * s_a + dy * c_a); - - pos = v[5]->data[0]; - pos[0] += (-dx * c_a - -dy * s_a); - pos[1] += (-dx * s_a + -dy * c_a); - - pos = v[6]->data[0]; - pos[0] += ( dx * c_a - dy * s_a); - pos[1] += ( dx * s_a + dy * c_a); - - pos = v[7]->data[0]; - pos[0] += ( dx * c_a - -dy * s_a); - pos[1] += ( dx * s_a + -dy * c_a); - - /* new texcoords */ - tex = v[0]->data[texPos]; - ASSIGN_4V(tex, 0, 0, 0, 1); - - tex = v[1]->data[texPos]; - ASSIGN_4V(tex, 0, 1, 0, 1); - - tex = v[2]->data[texPos]; - ASSIGN_4V(tex, .5, 0, 0, 1); - - tex = v[3]->data[texPos]; - ASSIGN_4V(tex, .5, 1, 0, 1); - - tex = v[4]->data[texPos]; - ASSIGN_4V(tex, .5, 0, 0, 1); - - tex = v[5]->data[texPos]; - ASSIGN_4V(tex, .5, 1, 0, 1); - - tex = v[6]->data[texPos]; - ASSIGN_4V(tex, 1, 0, 0, 1); - - tex = v[7]->data[texPos]; - ASSIGN_4V(tex, 1, 1, 0, 1); - - /* emit 6 tris for the quad strip */ - tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[4]; tri.v[1] = v[3]; tri.v[2] = v[2]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[5]; tri.v[1] = v[3]; tri.v[2] = v[4]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[6]; tri.v[1] = v[5]; tri.v[2] = v[4]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[7]; tri.v[1] = v[5]; tri.v[2] = v[6]; - stage->next->tri( stage->next, &tri ); -} - - -static void -aaline_first_line(struct draw_stage *stage, struct prim_header *header) -{ - auto struct aaline_stage *aaline = aaline_stage(stage); - struct draw_context *draw = stage->draw; - struct pipe_context *pipe = aaline->pipe; - uint num_samplers; - - assert(draw->rasterizer->line_smooth); - - if (draw->rasterizer->line_width <= 3.0) - aaline->half_line_width = 1.5f; - else - aaline->half_line_width = 0.5f * draw->rasterizer->line_width; - - /* - * Bind (generate) our fragprog, sampler and texture - */ - bind_aaline_fragment_shader(aaline); - - /* update vertex attrib info */ - aaline->tex_slot = draw->num_vs_outputs; - assert(aaline->tex_slot > 0); /* output[0] is vertex pos */ - - /* advertise the extra post-transformed vertex attribute */ - draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; - draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib; - draw->extra_vp_outputs.slot = aaline->tex_slot; - - /* how many samplers? */ - /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ - num_samplers = MAX2(aaline->num_textures, aaline->num_samplers); - num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1); - - aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso; - pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit], - aaline->texture); - - aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler); - aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture); - - /* now really draw first line */ - stage->line = aaline_line; - stage->line(stage, header); -} - - -static void -aaline_flush(struct draw_stage *stage, unsigned flags) -{ - struct draw_context *draw = stage->draw; - struct aaline_stage *aaline = aaline_stage(stage); - struct pipe_context *pipe = aaline->pipe; - - stage->line = aaline_first_line; - stage->next->flush( stage->next, flags ); - - /* restore original frag shader */ - aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); - - /* XXX restore original texture, sampler state */ - aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, - aaline->state.sampler); - aaline->driver_set_sampler_textures(pipe, aaline->num_textures, - aaline->state.texture); - - draw->extra_vp_outputs.slot = 0; -} - - -static void -aaline_reset_stipple_counter(struct draw_stage *stage) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void -aaline_destroy(struct draw_stage *stage) -{ - struct aaline_stage *aaline = aaline_stage(stage); - - aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); - - pipe_texture_release(&aaline->texture); - - draw_free_temp_verts( stage ); - - FREE( stage ); -} - - -static struct aaline_stage * -draw_aaline_stage(struct draw_context *draw) -{ - struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage); - - draw_alloc_temp_verts( &aaline->stage, 8 ); - - aaline->stage.draw = draw; - aaline->stage.next = NULL; - aaline->stage.point = passthrough_point; - aaline->stage.line = aaline_first_line; - aaline->stage.tri = passthrough_tri; - aaline->stage.flush = aaline_flush; - aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter; - aaline->stage.destroy = aaline_destroy; - - return aaline; -} - - -static struct aaline_stage * -aaline_stage_from_pipe(struct pipe_context *pipe) -{ - struct draw_context *draw = (struct draw_context *) pipe->draw; - return aaline_stage(draw->pipeline.aaline); -} - - -/** - * This function overrides the driver's create_fs_state() function and - * will typically be called by the state tracker. - */ -static void * -aaline_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *fs) -{ - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader); - - if (aafs) { - aafs->state = *fs; - - /* pass-through */ - aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs); - } - - return aafs; -} - - -static void -aaline_bind_fs_state(struct pipe_context *pipe, void *fs) -{ - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; - /* save current */ - aaline->fs = aafs; - /* pass-through */ - aaline->driver_bind_fs_state(aaline->pipe, - (aafs ? aafs->driver_fs : NULL)); -} - - -static void -aaline_delete_fs_state(struct pipe_context *pipe, void *fs) -{ - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; - /* pass-through */ - aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs); - FREE(aafs); -} - - -static void -aaline_bind_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) -{ - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - /* save current */ - memcpy(aaline->state.sampler, sampler, num * sizeof(void *)); - aaline->num_samplers = num; - /* pass-through */ - aaline->driver_bind_sampler_states(aaline->pipe, num, sampler); -} - - -static void -aaline_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) -{ - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - uint i; - - /* save current */ - for (i = 0; i < num; i++) { - pipe_texture_reference(&aaline->state.texture[i], texture[i]); - } - aaline->num_textures = num; - - /* pass-through */ - aaline->driver_set_sampler_textures(aaline->pipe, num, texture); -} - - -/** - * Called by drivers that want to install this AA line prim stage - * into the draw module's pipeline. This will not be used if the - * hardware has native support for AA lines. - */ -void -draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) -{ - struct aaline_stage *aaline; - - pipe->draw = (void *) draw; - - /* - * Create / install AA line drawing / prim stage - */ - aaline = draw_aaline_stage( draw ); - assert(aaline); - draw->pipeline.aaline = &aaline->stage; - - aaline->pipe = pipe; - - /* create special texture, sampler state */ - aaline_create_texture(aaline); - aaline_create_sampler(aaline); - - /* save original driver functions */ - aaline->driver_create_fs_state = pipe->create_fs_state; - aaline->driver_bind_fs_state = pipe->bind_fs_state; - aaline->driver_delete_fs_state = pipe->delete_fs_state; - - aaline->driver_bind_sampler_states = pipe->bind_sampler_states; - aaline->driver_set_sampler_textures = pipe->set_sampler_textures; - - /* override the driver's functions */ - pipe->create_fs_state = aaline_create_fs_state; - pipe->bind_fs_state = aaline_bind_fs_state; - pipe->delete_fs_state = aaline_delete_fs_state; - - pipe->bind_sampler_states = aaline_bind_sampler_states; - pipe->set_sampler_textures = aaline_set_sampler_textures; -} diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c deleted file mode 100644 index e84d380e50..0000000000 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ /dev/null @@ -1,846 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * AA point stage: AA points are converted to quads and rendered with a - * special fragment shader. Another approach would be to use a texture - * map image of a point, but experiments indicate the quality isn't nearly - * as good as this approach. - * - * Note: this looks a lot like draw_aaline.c but there's actually little - * if any code that can be shared. - * - * Authors: Brian Paul - */ - - -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/util/tgsi_transform.h" -#include "tgsi/util/tgsi_dump.h" - -#include "draw_context.h" -#include "draw_vs.h" - - -/* - * Enabling NORMALIZE might give _slightly_ better results. - * Basically, it controls whether we compute distance as d=sqrt(x*x+y*y) or - * d=x*x+y*y. Since we're working with a unit circle, the later seems - * close enough and saves some costly instructions. - */ -#define NORMALIZE 0 - - -/** - * Subclass of pipe_shader_state to carry extra fragment shader info. - */ -struct aapoint_fragment_shader -{ - struct pipe_shader_state state; - void *driver_fs; /**< the regular shader */ - void *aapoint_fs; /**< the aa point-augmented shader */ - int generic_attrib; /**< The generic input attrib/texcoord we'll use */ -}; - - -/** - * Subclass of draw_stage - */ -struct aapoint_stage -{ - struct draw_stage stage; - - int psize_slot; - float radius; - - /** this is the vertex attrib slot for the new texcoords */ - uint tex_slot; - - /* - * Currently bound state - */ - struct aapoint_fragment_shader *fs; - - /* - * Driver interface/override functions - */ - void * (*driver_create_fs_state)(struct pipe_context *, - const struct pipe_shader_state *); - void (*driver_bind_fs_state)(struct pipe_context *, void *); - void (*driver_delete_fs_state)(struct pipe_context *, void *); - - struct pipe_context *pipe; -}; - - - -/** - * Subclass of tgsi_transform_context, used for transforming the - * user's fragment shader to add the special AA instructions. - */ -struct aa_transform_context { - struct tgsi_transform_context base; - uint tempsUsed; /**< bitmask */ - int colorOutput; /**< which output is the primary color */ - int maxInput, maxGeneric; /**< max input index found */ - int tmp0, colorTemp; /**< temp registers */ - boolean firstInstruction; -}; - - -/** - * TGSI declaration transform callback. - * Look for two free temp regs and available input reg for new texcoords. - */ -static void -aa_transform_decl(struct tgsi_transform_context *ctx, - struct tgsi_full_declaration *decl) -{ - struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; - - if (decl->Declaration.File == TGSI_FILE_OUTPUT && - decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && - decl->Semantic.SemanticIndex == 0) { - aactx->colorOutput = decl->u.DeclarationRange.First; - } - else if (decl->Declaration.File == TGSI_FILE_INPUT) { - if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) - aactx->maxInput = decl->u.DeclarationRange.Last; - if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && - (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { - aactx->maxGeneric = decl->Semantic.SemanticIndex; - } - } - else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { - uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { - aactx->tempsUsed |= (1 << i); - } - } - - ctx->emit_declaration(ctx, decl); -} - - -/** - * TGSI instruction transform callback. - * Replace writes to result.color w/ a temp reg. - * Upon END instruction, insert texture sampling code for antialiasing. - */ -static void -aa_transform_inst(struct tgsi_transform_context *ctx, - struct tgsi_full_instruction *inst) -{ - struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; - struct tgsi_full_instruction newInst; - - if (aactx->firstInstruction) { - /* emit our new declarations before the first instruction */ - - struct tgsi_full_declaration decl; - const int texInput = aactx->maxInput + 1; - int tmp0; - uint i; - - /* find two free temp regs */ - for (i = 0; i < 32; i++) { - if ((aactx->tempsUsed & (1 << i)) == 0) { - /* found a free temp */ - if (aactx->tmp0 < 0) - aactx->tmp0 = i; - else if (aactx->colorTemp < 0) - aactx->colorTemp = i; - else - break; - } - } - - assert(aactx->colorTemp != aactx->tmp0); - - tmp0 = aactx->tmp0; - - /* declare new generic input/texcoord */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; - decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; - decl.Declaration.Interpolate = 1; - /* XXX this could be linear... */ - decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = texInput; - ctx->emit_declaration(ctx, &decl); - - /* declare new temp regs */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = tmp0; - ctx->emit_declaration(ctx, &decl); - - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->colorTemp; - ctx->emit_declaration(ctx, &decl); - - aactx->firstInstruction = FALSE; - - - /* - * Emit code to compute fragment coverage, kill if outside point radius - * - * Temp reg0 usage: - * t0.x = distance of fragment from center point - * t0.y = boolean, is t0.x > 1.0, also misc temp usage - * t0.z = temporary for computing 1/(1-k) value - * t0.w = final coverage value - */ - - /* MUL t0.xy, tex, tex; # compute x^2, y^2 */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MUL; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XY; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; - ctx->emit_instruction(ctx, &newInst); - - /* ADD t0.x, t0.x, t0.y; # x^2 + y^2 */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_ADD; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; - ctx->emit_instruction(ctx, &newInst); - -#if NORMALIZE /* OPTIONAL normalization of length */ - /* RSQ t0.x, t0.x; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_RSQ; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - ctx->emit_instruction(ctx, &newInst); - - /* RCP t0.x, t0.x; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_RCP; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - ctx->emit_instruction(ctx, &newInst); -#endif - - /* SGT t0.y, t0.xxxx, t0.wwww; # bool b = d > 1 (NOTE t0.w == 1) */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_SGT; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; - ctx->emit_instruction(ctx, &newInst); - - /* KILP -t0.yyyy; # if b, KILL */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_KILP; - newInst.Instruction.NumDstRegs = 0; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; - ctx->emit_instruction(ctx, &newInst); - - - /* compute coverage factor = (1-d)/(1-k) */ - - /* SUB t0.z, tex.w, tex.z; # m = 1 - k */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_SUB; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; - ctx->emit_instruction(ctx, &newInst); - - /* RCP t0.z, t0.z; # t0.z = 1 / m */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_RCP; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z; - ctx->emit_instruction(ctx, &newInst); - - /* SUB t0.y, 1, t0.x; # d = 1 - d */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_SUB; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - ctx->emit_instruction(ctx, &newInst); - - /* MUL t0.w, t0.y, t0.z; # coverage = d * m */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MUL; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z; - ctx->emit_instruction(ctx, &newInst); - - /* SLE t0.y, t0.x, tex.z; # bool b = distance <= k */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_SLE; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z; - ctx->emit_instruction(ctx, &newInst); - - /* CMP t0.w, -t0.y, tex.w, t0.w; - * # if -t0.y < 0 then - * t0.w = 1 - * else - * t0.w = t0.w - */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_CMP; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; - newInst.Instruction.NumSrcRegs = 3; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[2].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; - ctx->emit_instruction(ctx, &newInst); - - } - - if (inst->Instruction.Opcode == TGSI_OPCODE_END) { - /* add alpha modulation code at tail of program */ - - /* MOV result.color.xyz, colorTemp; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MOV; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; - ctx->emit_instruction(ctx, &newInst); - - /* MUL result.color.w, colorTemp, tmp0.w; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MUL; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->tmp0; - ctx->emit_instruction(ctx, &newInst); - } - else { - /* Not an END instruction. - * Look for writes to result.color and replace with colorTemp reg. - */ - uint i; - - for (i = 0; i < inst->Instruction.NumDstRegs; i++) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - if (dst->DstRegister.File == TGSI_FILE_OUTPUT && - dst->DstRegister.Index == aactx->colorOutput) { - dst->DstRegister.File = TGSI_FILE_TEMPORARY; - dst->DstRegister.Index = aactx->colorTemp; - } - } - } - - ctx->emit_instruction(ctx, inst); -} - - -/** - * Generate the frag shader we'll use for drawing AA lines. - * This will be the user's shader plus some texture/modulate instructions. - */ -static void -generate_aapoint_fs(struct aapoint_stage *aapoint) -{ - const struct pipe_shader_state *orig_fs = &aapoint->fs->state; - struct pipe_shader_state aapoint_fs; - struct aa_transform_context transform; - -#define MAX 1000 - - aapoint_fs = *orig_fs; /* copy to init */ - aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); - - memset(&transform, 0, sizeof(transform)); - transform.colorOutput = -1; - transform.maxInput = -1; - transform.maxGeneric = -1; - transform.colorTemp = -1; - transform.tmp0 = -1; - transform.firstInstruction = TRUE; - transform.base.transform_instruction = aa_transform_inst; - transform.base.transform_declaration = aa_transform_decl; - - tgsi_transform_shader(orig_fs->tokens, - (struct tgsi_token *) aapoint_fs.tokens, - MAX, &transform.base); - -#if 0 /* DEBUG */ - printf("draw_aapoint, orig shader:\n"); - tgsi_dump(orig_fs->tokens, 0); - printf("draw_aapoint, new shader:\n"); - tgsi_dump(aapoint_fs.tokens, 0); -#endif - - aapoint->fs->aapoint_fs - = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs); - - aapoint->fs->generic_attrib = transform.maxGeneric + 1; -} - - -/** - * When we're about to draw our first AA line in a batch, this function is - * called to tell the driver to bind our modified fragment shader. - */ -static void -bind_aapoint_fragment_shader(struct aapoint_stage *aapoint) -{ - if (!aapoint->fs->aapoint_fs) { - generate_aapoint_fs(aapoint); - } - aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs); -} - - - -static INLINE struct aapoint_stage * -aapoint_stage( struct draw_stage *stage ) -{ - return (struct aapoint_stage *) stage; -} - - -static void -passthrough_line(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->line(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Draw an AA point by drawing a quad. - */ -static void -aapoint_point(struct draw_stage *stage, struct prim_header *header) -{ - const struct aapoint_stage *aapoint = aapoint_stage(stage); - struct prim_header tri; - struct vertex_header *v[4]; - uint texPos = aapoint->tex_slot; - float radius, *pos, *tex; - uint i; - float k; - - if (aapoint->psize_slot >= 0) { - radius = 0.5f * header->v[0]->data[aapoint->psize_slot][0]; - } - else { - radius = aapoint->radius; - } - - /* - * Note: the texcoords (generic attrib, really) we use are special: - * The S and T components simply vary from -1 to +1. - * The R component is k, below. - * The Q component is 1.0 and will used as a handy constant in the - * fragment shader. - */ - - /* - * k is the threshold distance from the point's center at which - * we begin alpha attenuation (the coverage value). - * Operating within a unit circle, we'll compute the fragment's - * distance 'd' from the center point using the texcoords. - * IF d > 1.0 THEN - * KILL fragment - * ELSE IF d > k THEN - * compute coverage in [0,1] proportional to d in [k, 1]. - * ELSE - * coverage = 1.0; // full coverage - * ENDIF - * - * Note: the ELSEIF and ELSE clauses are actually implemented with CMP to - * avoid using IF/ELSE/ENDIF TGSI opcodes. - */ - -#if !NORMALIZE - k = 1.0f / radius; - k = 1.0f - 2.0f * k + k * k; -#else - k = 1.0f - 1.0f / radius; -#endif - - /* allocate/dup new verts */ - for (i = 0; i < 4; i++) { - v[i] = dup_vert(stage, header->v[0], i); - } - - /* new verts */ - pos = v[0]->data[0]; - pos[0] -= radius; - pos[1] -= radius; - - pos = v[1]->data[0]; - pos[0] += radius; - pos[1] -= radius; - - pos = v[2]->data[0]; - pos[0] += radius; - pos[1] += radius; - - pos = v[3]->data[0]; - pos[0] -= radius; - pos[1] += radius; - - /* new texcoords */ - tex = v[0]->data[texPos]; - ASSIGN_4V(tex, -1, -1, k, 1); - - tex = v[1]->data[texPos]; - ASSIGN_4V(tex, 1, -1, k, 1); - - tex = v[2]->data[texPos]; - ASSIGN_4V(tex, 1, 1, k, 1); - - tex = v[3]->data[texPos]; - ASSIGN_4V(tex, -1, 1, k, 1); - - /* emit 2 tris for the quad strip */ - tri.v[0] = v[0]; - tri.v[1] = v[1]; - tri.v[2] = v[2]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[0]; - tri.v[1] = v[2]; - tri.v[2] = v[3]; - stage->next->tri( stage->next, &tri ); -} - - -static void -aapoint_first_point(struct draw_stage *stage, struct prim_header *header) -{ - auto struct aapoint_stage *aapoint = aapoint_stage(stage); - struct draw_context *draw = stage->draw; - - assert(draw->rasterizer->point_smooth); - - if (draw->rasterizer->point_size <= 2.0) - aapoint->radius = 1.0; - else - aapoint->radius = 0.5f * draw->rasterizer->point_size; - - /* - * Bind (generate) our fragprog. - */ - bind_aapoint_fragment_shader(aapoint); - - /* update vertex attrib info */ - aapoint->tex_slot = draw->num_vs_outputs; - assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ - - draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; - draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib; - draw->extra_vp_outputs.slot = aapoint->tex_slot; - - /* find psize slot in post-transform vertex */ - aapoint->psize_slot = -1; - if (draw->rasterizer->point_size_per_vertex) { - /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { - aapoint->psize_slot = i; - break; - } - } - } - - /* now really draw first line */ - stage->point = aapoint_point; - stage->point(stage, header); -} - - -static void -aapoint_flush(struct draw_stage *stage, unsigned flags) -{ - struct draw_context *draw = stage->draw; - struct aapoint_stage *aapoint = aapoint_stage(stage); - struct pipe_context *pipe = aapoint->pipe; - - stage->point = aapoint_first_point; - stage->next->flush( stage->next, flags ); - - /* restore original frag shader */ - aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs); - - draw->extra_vp_outputs.slot = 0; -} - - -static void -aapoint_reset_stipple_counter(struct draw_stage *stage) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void -aapoint_destroy(struct draw_stage *stage) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -static struct aapoint_stage * -draw_aapoint_stage(struct draw_context *draw) -{ - struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage); - - draw_alloc_temp_verts( &aapoint->stage, 4 ); - - aapoint->stage.draw = draw; - aapoint->stage.next = NULL; - aapoint->stage.point = aapoint_first_point; - aapoint->stage.line = passthrough_line; - aapoint->stage.tri = passthrough_tri; - aapoint->stage.flush = aapoint_flush; - aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter; - aapoint->stage.destroy = aapoint_destroy; - - return aapoint; -} - - -static struct aapoint_stage * -aapoint_stage_from_pipe(struct pipe_context *pipe) -{ - struct draw_context *draw = (struct draw_context *) pipe->draw; - return aapoint_stage(draw->pipeline.aapoint); -} - - -/** - * This function overrides the driver's create_fs_state() function and - * will typically be called by the state tracker. - */ -static void * -aapoint_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *fs) -{ - struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); - struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader); - - if (aafs) { - aafs->state = *fs; - - /* pass-through */ - aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs); - } - - return aafs; -} - - -static void -aapoint_bind_fs_state(struct pipe_context *pipe, void *fs) -{ - struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); - struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; - /* save current */ - aapoint->fs = aafs; - /* pass-through */ - aapoint->driver_bind_fs_state(aapoint->pipe, - (aafs ? aafs->driver_fs : NULL)); -} - - -static void -aapoint_delete_fs_state(struct pipe_context *pipe, void *fs) -{ - struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); - struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; - /* pass-through */ - aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs); - FREE(aafs); -} - - -/** - * Called by drivers that want to install this AA point prim stage - * into the draw module's pipeline. This will not be used if the - * hardware has native support for AA points. - */ -void -draw_install_aapoint_stage(struct draw_context *draw, - struct pipe_context *pipe) -{ - struct aapoint_stage *aapoint; - - pipe->draw = (void *) draw; - - /* - * Create / install AA point drawing / prim stage - */ - aapoint = draw_aapoint_stage( draw ); - assert(aapoint); - draw->pipeline.aapoint = &aapoint->stage; - - aapoint->pipe = pipe; - - /* save original driver functions */ - aapoint->driver_create_fs_state = pipe->create_fs_state; - aapoint->driver_bind_fs_state = pipe->bind_fs_state; - aapoint->driver_delete_fs_state = pipe->delete_fs_state; - - /* override the driver's functions */ - pipe->create_fs_state = aapoint_create_fs_state; - pipe->bind_fs_state = aapoint_bind_fs_state; - pipe->delete_fs_state = aapoint_delete_fs_state; -} diff --git a/src/gallium/auxiliary/draw/draw_clip.c b/src/gallium/auxiliary/draw/draw_clip.c deleted file mode 100644 index 0ac3a240e5..0000000000 --- a/src/gallium/auxiliary/draw/draw_clip.c +++ /dev/null @@ -1,503 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief Clipping stage - * - * \author Keith Whitwell - */ - - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" - -#include "draw_context.h" -#include "draw_vs.h" - - -#ifndef IS_NEGATIVE -#define IS_NEGATIVE(X) ((X) < 0.0) -#endif - -#ifndef DIFFERENT_SIGNS -#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F) -#endif - -#ifndef MAX_CLIPPED_VERTICES -#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1) -#endif - - - -struct clipper { - struct draw_stage stage; /**< base class */ - - /* Basically duplicate some of the flatshading logic here: - */ - boolean flat; - uint num_color_attribs; - uint color_attribs[4]; /* front/back primary/secondary colors */ - - float (*plane)[4]; -}; - - -/* This is a bit confusing: - */ -static INLINE struct clipper *clipper_stage( struct draw_stage *stage ) -{ - return (struct clipper *)stage; -} - - -#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT))) - - -/* All attributes are float[4], so this is easy: - */ -static void interp_attr( float *fdst, - float t, - const float *fin, - const float *fout ) -{ - fdst[0] = LINTERP( t, fout[0], fin[0] ); - fdst[1] = LINTERP( t, fout[1], fin[1] ); - fdst[2] = LINTERP( t, fout[2], fin[2] ); - fdst[3] = LINTERP( t, fout[3], fin[3] ); -} - -static void copy_colors( struct draw_stage *stage, - struct vertex_header *dst, - const struct vertex_header *src ) -{ - const struct clipper *clipper = clipper_stage(stage); - uint i; - for (i = 0; i < clipper->num_color_attribs; i++) { - const uint attr = clipper->color_attribs[i]; - COPY_4FV(dst->data[attr], src->data[attr]); - } -} - - - -/* Interpolate between two vertices to produce a third. - */ -static void interp( const struct clipper *clip, - struct vertex_header *dst, - float t, - const struct vertex_header *out, - const struct vertex_header *in ) -{ - const unsigned nr_attrs = clip->stage.draw->num_vs_outputs; - unsigned j; - - /* Vertex header. - */ - { - dst->clipmask = 0; - dst->edgeflag = 0; - dst->pad = 0; - dst->vertex_id = UNDEFINED_VERTEX_ID; - } - - /* Clip coordinates: interpolate normally - */ - { - interp_attr(dst->clip, t, in->clip, out->clip); - } - - /* Do the projective divide and insert window coordinates: - */ - { - const float *pos = dst->clip; - const float *scale = clip->stage.draw->viewport.scale; - const float *trans = clip->stage.draw->viewport.translate; - const float oow = 1.0f / pos[3]; - - dst->data[0][0] = pos[0] * oow * scale[0] + trans[0]; - dst->data[0][1] = pos[1] * oow * scale[1] + trans[1]; - dst->data[0][2] = pos[2] * oow * scale[2] + trans[2]; - dst->data[0][3] = oow; - } - - /* Other attributes - * Note: start at 1 to skip winpos (data[0]) since we just computed - * it above. - */ - for (j = 1; j < nr_attrs; j++) { - interp_attr(dst->data[j], t, in->data[j], out->data[j]); - } -} - - -static void emit_poly( struct draw_stage *stage, - struct vertex_header **inlist, - unsigned n, - const struct prim_header *origPrim) -{ - struct prim_header header; - unsigned i; - - /* later stages may need the determinant, but only the sign matters */ - header.det = origPrim->det; - - for (i = 2; i < n; i++) { - header.v[0] = inlist[i-1]; - header.v[1] = inlist[i]; - header.v[2] = inlist[0]; /* keep in v[2] for flatshading */ - - { - unsigned tmp1 = header.v[1]->edgeflag; - unsigned tmp2 = header.v[2]->edgeflag; - - if (i != n-1) header.v[1]->edgeflag = 0; - if (i != 2) header.v[2]->edgeflag = 0; - - header.edgeflags = ((header.v[0]->edgeflag << 0) | - (header.v[1]->edgeflag << 1) | - (header.v[2]->edgeflag << 2)); - - if (0) { - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; - uint j, k; - debug_printf("Clipped tri:\n"); - for (j = 0; j < 3; j++) { - for (k = 0; k < vs->info.num_outputs; k++) { - debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, - header.v[j]->data[k][0], - header.v[j]->data[k][1], - header.v[j]->data[k][2], - header.v[j]->data[k][3]); - } - } - } - - stage->next->tri( stage->next, &header ); - - header.v[1]->edgeflag = tmp1; - header.v[2]->edgeflag = tmp2; - } - } -} - - - - -/* Clip a triangle against the viewport and user clip planes. - */ -static void -do_clip_tri( struct draw_stage *stage, - struct prim_header *header, - unsigned clipmask ) -{ - struct clipper *clipper = clipper_stage( stage ); - struct vertex_header *a[MAX_CLIPPED_VERTICES]; - struct vertex_header *b[MAX_CLIPPED_VERTICES]; - struct vertex_header **inlist = a; - struct vertex_header **outlist = b; - unsigned tmpnr = 0; - unsigned n = 3; - unsigned i; - - inlist[0] = header->v[0]; - inlist[1] = header->v[1]; - inlist[2] = header->v[2]; - - while (clipmask && n >= 3) { - const unsigned plane_idx = ffs(clipmask)-1; - const float *plane = clipper->plane[plane_idx]; - struct vertex_header *vert_prev = inlist[0]; - float dp_prev = dot4( vert_prev->clip, plane ); - unsigned outcount = 0; - - clipmask &= ~(1<clip, plane ); - - if (!IS_NEGATIVE(dp_prev)) { - outlist[outcount++] = vert_prev; - } - - if (DIFFERENT_SIGNS(dp, dp_prev)) { - struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++]; - outlist[outcount++] = new_vert; - - if (IS_NEGATIVE(dp)) { - /* Going out of bounds. Avoid division by zero as we - * know dp != dp_prev from DIFFERENT_SIGNS, above. - */ - float t = dp / (dp - dp_prev); - interp( clipper, new_vert, t, vert, vert_prev ); - - /* Force edgeflag true in this case: - */ - new_vert->edgeflag = 1; - } else { - /* Coming back in. - */ - float t = dp_prev / (dp_prev - dp); - interp( clipper, new_vert, t, vert_prev, vert ); - - /* Copy starting vert's edgeflag: - */ - new_vert->edgeflag = vert_prev->edgeflag; - } - } - - vert_prev = vert; - dp_prev = dp; - } - - { - struct vertex_header **tmp = inlist; - inlist = outlist; - outlist = tmp; - n = outcount; - } - } - - /* If flat-shading, copy color to new provoking vertex. - */ - if (clipper->flat && inlist[0] != header->v[2]) { - if (1) { - inlist[0] = dup_vert(stage, inlist[0], tmpnr++); - } - - copy_colors(stage, inlist[0], header->v[2]); - } - - - - /* Emit the polygon as triangles to the setup stage: - */ - if (n >= 3) - emit_poly( stage, inlist, n, header ); -} - - -/* Clip a line against the viewport and user clip planes. - */ -static void -do_clip_line( struct draw_stage *stage, - struct prim_header *header, - unsigned clipmask ) -{ - const struct clipper *clipper = clipper_stage( stage ); - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - const float *pos0 = v0->clip; - const float *pos1 = v1->clip; - float t0 = 0.0F; - float t1 = 0.0F; - struct prim_header newprim; - - while (clipmask) { - const unsigned plane_idx = ffs(clipmask)-1; - const float *plane = clipper->plane[plane_idx]; - const float dp0 = dot4( pos0, plane ); - const float dp1 = dot4( pos1, plane ); - - if (dp1 < 0.0F) { - float t = dp1 / (dp1 - dp0); - t1 = MAX2(t1, t); - } - - if (dp0 < 0.0F) { - float t = dp0 / (dp0 - dp1); - t0 = MAX2(t0, t); - } - - if (t0 + t1 >= 1.0F) - return; /* discard */ - - clipmask &= ~(1 << plane_idx); /* turn off this plane's bit */ - } - - if (v0->clipmask) { - interp( clipper, stage->tmp[0], t0, v0, v1 ); - - if (clipper->flat) - copy_colors(stage, stage->tmp[0], v0); - - newprim.v[0] = stage->tmp[0]; - } - else { - newprim.v[0] = v0; - } - - if (v1->clipmask) { - interp( clipper, stage->tmp[1], t1, v1, v0 ); - newprim.v[1] = stage->tmp[1]; - } - else { - newprim.v[1] = v1; - } - - stage->next->line( stage->next, &newprim ); -} - - -static void -clip_point( struct draw_stage *stage, - struct prim_header *header ) -{ - if (header->v[0]->clipmask == 0) - stage->next->point( stage->next, header ); -} - - -static void -clip_line( struct draw_stage *stage, - struct prim_header *header ) -{ - unsigned clipmask = (header->v[0]->clipmask | - header->v[1]->clipmask); - - if (clipmask == 0) { - /* no clipping needed */ - stage->next->line( stage->next, header ); - } - else if ((header->v[0]->clipmask & - header->v[1]->clipmask) == 0) { - do_clip_line(stage, header, clipmask); - } - /* else, totally clipped */ -} - - -static void -clip_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - unsigned clipmask = (header->v[0]->clipmask | - header->v[1]->clipmask | - header->v[2]->clipmask); - - if (clipmask == 0) { - /* no clipping needed */ - stage->next->tri( stage->next, header ); - } - else if ((header->v[0]->clipmask & - header->v[1]->clipmask & - header->v[2]->clipmask) == 0) { - do_clip_tri(stage, header, clipmask); - } -} - -/* Update state. Could further delay this until we hit the first - * primitive that really requires clipping. - */ -static void -clip_init_state( struct draw_stage *stage ) -{ - struct clipper *clipper = clipper_stage( stage ); - - clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE; - - if (clipper->flat) { - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; - uint i; - - clipper->num_color_attribs = 0; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || - vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { - clipper->color_attribs[clipper->num_color_attribs++] = i; - } - } - } - - stage->tri = clip_tri; - stage->line = clip_line; -} - - - -static void clip_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - clip_init_state( stage ); - stage->tri( stage, header ); -} - -static void clip_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - clip_init_state( stage ); - stage->line( stage, header ); -} - - -static void clip_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->tri = clip_first_tri; - stage->line = clip_first_line; - stage->next->flush( stage->next, flags ); -} - - -static void clip_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void clip_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Allocate a new clipper stage. - * \return pointer to new stage object - */ -struct draw_stage *draw_clip_stage( struct draw_context *draw ) -{ - struct clipper *clipper = CALLOC_STRUCT(clipper); - - draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ); - - clipper->stage.draw = draw; - clipper->stage.point = clip_point; - clipper->stage.line = clip_first_line; - clipper->stage.tri = clip_first_tri; - clipper->stage.flush = clip_flush; - clipper->stage.reset_stipple_counter = clip_reset_stipple_counter; - clipper->stage.destroy = clip_destroy; - - clipper->plane = draw->plane; - - return &clipper->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_cull.c b/src/gallium/auxiliary/draw/draw_cull.c deleted file mode 100644 index 8177b0ac86..0000000000 --- a/src/gallium/auxiliary/draw/draw_cull.c +++ /dev/null @@ -1,150 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief Drawing stage for polygon culling - */ - -/* Authors: Keith Whitwell - */ - - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "draw_private.h" - - -struct cull_stage { - struct draw_stage stage; - unsigned winding; /**< which winding(s) to cull (one of PIPE_WINDING_x) */ -}; - - -static INLINE struct cull_stage *cull_stage( struct draw_stage *stage ) -{ - return (struct cull_stage *)stage; -} - - - - -static void cull_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - /* Window coords: */ - const float *v0 = header->v[0]->data[0]; - const float *v1 = header->v[1]->data[0]; - const float *v2 = header->v[2]->data[0]; - - /* edge vectors e = v0 - v2, f = v1 - v2 */ - const float ex = v0[0] - v2[0]; - const float ey = v0[1] - v2[1]; - const float fx = v1[0] - v2[0]; - const float fy = v1[1] - v2[1]; - - /* det = cross(e,f).z */ - header->det = ex * fy - ey * fx; - - if (header->det != 0) { - /* if (det < 0 then Z points toward camera and triangle is - * counter-clockwise winding. - */ - unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; - - if ((winding & cull_stage(stage)->winding) == 0) { - /* triangle is not culled, pass to next stage */ - stage->next->tri( stage->next, header ); - } - } -} - -static void cull_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct cull_stage *cull = cull_stage(stage); - - cull->winding = stage->draw->rasterizer->cull_mode; - - stage->tri = cull_tri; - stage->tri( stage, header ); -} - - - -static void cull_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void cull_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void cull_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->tri = cull_first_tri; - stage->next->flush( stage->next, flags ); -} - -static void cull_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void cull_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create a new polygon culling stage. - */ -struct draw_stage *draw_cull_stage( struct draw_context *draw ) -{ - struct cull_stage *cull = CALLOC_STRUCT(cull_stage); - - draw_alloc_temp_verts( &cull->stage, 0 ); - - cull->stage.draw = draw; - cull->stage.next = NULL; - cull->stage.point = cull_point; - cull->stage.line = cull_line; - cull->stage.tri = cull_first_tri; - cull->stage.flush = cull_flush; - cull->stage.reset_stipple_counter = cull_reset_stipple_counter; - cull->stage.destroy = cull_destroy; - - return &cull->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_flatshade.c b/src/gallium/auxiliary/draw/draw_flatshade.c deleted file mode 100644 index 54baa1fbc9..0000000000 --- a/src/gallium/auxiliary/draw/draw_flatshade.c +++ /dev/null @@ -1,248 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "draw_vs.h" - - -/** subclass of draw_stage */ -struct flat_stage -{ - struct draw_stage stage; - - uint num_color_attribs; - uint color_attribs[4]; /* front/back primary/secondary colors */ -}; - - -static INLINE struct flat_stage * -flat_stage(struct draw_stage *stage) -{ - return (struct flat_stage *) stage; -} - - -/** Copy all the color attributes from 'src' vertex to 'dst' vertex */ -static INLINE void copy_colors( struct draw_stage *stage, - struct vertex_header *dst, - const struct vertex_header *src ) -{ - const struct flat_stage *flat = flat_stage(stage); - uint i; - for (i = 0; i < flat->num_color_attribs; i++) { - const uint attr = flat->color_attribs[i]; - COPY_4FV(dst->data[attr], src->data[attr]); - } -} - - -/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */ -static INLINE void copy_colors2( struct draw_stage *stage, - struct vertex_header *dst0, - struct vertex_header *dst1, - const struct vertex_header *src ) -{ - const struct flat_stage *flat = flat_stage(stage); - uint i; - for (i = 0; i < flat->num_color_attribs; i++) { - const uint attr = flat->color_attribs[i]; - COPY_4FV(dst0->data[attr], src->data[attr]); - COPY_4FV(dst1->data[attr], src->data[attr]); - } -} - - -/** - * Flatshade tri. Required for clipping and when unfilled tris are - * active, otherwise handled by hardware. - */ -static void flatshade_tri_0( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.det = header->det; - tmp.edgeflags = header->edgeflags; - tmp.v[0] = header->v[0]; - tmp.v[1] = dup_vert(stage, header->v[1], 0); - tmp.v[2] = dup_vert(stage, header->v[2], 1); - - copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]); - - stage->next->tri( stage->next, &tmp ); -} - - -static void flatshade_tri_2( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.det = header->det; - tmp.edgeflags = header->edgeflags; - tmp.v[0] = dup_vert(stage, header->v[0], 0); - tmp.v[1] = dup_vert(stage, header->v[1], 1); - tmp.v[2] = header->v[2]; - - copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]); - - stage->next->tri( stage->next, &tmp ); -} - - - - - -/** - * Flatshade line. Required for clipping. - */ -static void flatshade_line_0( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.v[0] = header->v[0]; - tmp.v[1] = dup_vert(stage, header->v[1], 0); - - copy_colors(stage, tmp.v[1], tmp.v[0]); - - stage->next->line( stage->next, &tmp ); -} - -static void flatshade_line_1( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.v[0] = dup_vert(stage, header->v[0], 0); - tmp.v[1] = header->v[1]; - - copy_colors(stage, tmp.v[0], tmp.v[1]); - - stage->next->line( stage->next, &tmp ); -} - - -/* Flatshade point -- passthrough. - */ -static void flatshade_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void flatshade_init_state( struct draw_stage *stage ) -{ - struct flat_stage *flat = flat_stage(stage); - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; - uint i; - - /* Find which vertex shader outputs are colors, make a list */ - flat->num_color_attribs = 0; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || - vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { - flat->color_attribs[flat->num_color_attribs++] = i; - } - } - - /* Choose flatshade routine according to provoking vertex: - */ - if (stage->draw->rasterizer->flatshade_first) { - stage->line = flatshade_line_0; - stage->tri = flatshade_tri_0; - } - else { - stage->line = flatshade_line_1; - stage->tri = flatshade_tri_2; - } -} - -static void flatshade_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - flatshade_init_state( stage ); - stage->tri( stage, header ); -} - -static void flatshade_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - flatshade_init_state( stage ); - stage->line( stage, header ); -} - - -static void flatshade_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->tri = flatshade_first_tri; - stage->line = flatshade_first_line; - stage->next->flush( stage->next, flags ); -} - - -static void flatshade_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void flatshade_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create flatshading drawing stage. - */ -struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) -{ - struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage); - - draw_alloc_temp_verts( &flatshade->stage, 2 ); - - flatshade->stage.draw = draw; - flatshade->stage.next = NULL; - flatshade->stage.point = flatshade_point; - flatshade->stage.line = flatshade_first_line; - flatshade->stage.tri = flatshade_first_tri; - flatshade->stage.flush = flatshade_flush; - flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter; - flatshade->stage.destroy = flatshade_destroy; - - return &flatshade->stage; -} - - diff --git a/src/gallium/auxiliary/draw/draw_offset.c b/src/gallium/auxiliary/draw/draw_offset.c deleted file mode 100644 index dbc676deae..0000000000 --- a/src/gallium/auxiliary/draw/draw_offset.c +++ /dev/null @@ -1,186 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief polygon offset state - * - * \author Keith Whitwell - * \author Brian Paul - */ - -#include "pipe/p_util.h" -#include "draw_private.h" - - - -struct offset_stage { - struct draw_stage stage; - - float scale; - float units; -}; - - - -static INLINE struct offset_stage *offset_stage( struct draw_stage *stage ) -{ - return (struct offset_stage *) stage; -} - - - - - -/** - * Offset tri Z. Some hardware can handle this, but not usually when - * doing unfilled rendering. - */ -static void do_offset_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct offset_stage *offset = offset_stage(stage); - float inv_det = 1.0f / header->det; - - /* Window coords: - */ - float *v0 = header->v[0]->data[0]; - float *v1 = header->v[1]->data[0]; - float *v2 = header->v[2]->data[0]; - - /* edge vectors e = v0 - v2, f = v1 - v2 */ - float ex = v0[0] - v2[0]; - float ey = v0[1] - v2[1]; - float ez = v0[2] - v2[2]; - float fx = v1[0] - v2[0]; - float fy = v1[1] - v2[1]; - float fz = v1[2] - v2[2]; - - /* (a,b) = cross(e,f).xy */ - float a = ey*fz - ez*fy; - float b = ez*fx - ex*fz; - - float dzdx = FABSF(a * inv_det); - float dzdy = FABSF(b * inv_det); - - float zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale; - - /* - * Note: we're applying the offset and clamping per-vertex. - * Ideally, the offset is applied per-fragment prior to fragment shading. - */ - v0[2] = CLAMP(v0[2] + zoffset, 0.0f, 1.0f); - v1[2] = CLAMP(v1[2] + zoffset, 0.0f, 1.0f); - v2[2] = CLAMP(v2[2] + zoffset, 0.0f, 1.0f); - - stage->next->tri( stage->next, header ); -} - - -static void offset_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.det = header->det; - tmp.edgeflags = header->edgeflags; - tmp.v[0] = dup_vert(stage, header->v[0], 0); - tmp.v[1] = dup_vert(stage, header->v[1], 1); - tmp.v[2] = dup_vert(stage, header->v[2], 2); - - do_offset_tri( stage, &tmp ); -} - - -static void offset_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct offset_stage *offset = offset_stage(stage); - float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */ - - offset->units = stage->draw->rasterizer->offset_units * mrd; - offset->scale = stage->draw->rasterizer->offset_scale; - - stage->tri = offset_tri; - stage->tri( stage, header ); -} - - -static void offset_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void offset_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void offset_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->tri = offset_first_tri; - stage->next->flush( stage->next, flags ); -} - - -static void offset_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void offset_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create polygon offset drawing stage. - */ -struct draw_stage *draw_offset_stage( struct draw_context *draw ) -{ - struct offset_stage *offset = CALLOC_STRUCT(offset_stage); - - draw_alloc_temp_verts( &offset->stage, 3 ); - - offset->stage.draw = draw; - offset->stage.next = NULL; - offset->stage.point = offset_point; - offset->stage.line = offset_line; - offset->stage.tri = offset_first_tri; - offset->stage.flush = offset_flush; - offset->stage.reset_stipple_counter = offset_reset_stipple_counter; - offset->stage.destroy = offset_destroy; - - return &offset->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c new file mode 100644 index 0000000000..e8d2a45102 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -0,0 +1,859 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * AA line stage: AA lines are converted to texture mapped triangles. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_private.h" + + +/** + * Max texture level for the alpha texture used for antialiasing + */ +#define MAX_TEXTURE_LEVEL 5 /* 32 x 32 */ + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct aaline_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; + void *aaline_fs; + void *aapoint_fs; /* not yet */ + void *sprite_fs; /* not yet */ + uint sampler_unit; + int generic_attrib; /**< texcoord/generic used for texture */ +}; + + +/** + * Subclass of draw_stage + */ +struct aaline_stage +{ + struct draw_stage stage; + + float half_line_width; + + /** For AA lines, this is the vertex attrib slot for the new texcoords */ + uint tex_slot; + + void *sampler_cso; + struct pipe_texture *texture; + uint num_samplers; + uint num_textures; + + + /* + * Currently bound state + */ + struct aaline_fragment_shader *fs; + struct { + void *sampler[PIPE_MAX_SAMPLERS]; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + } state; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, + void **); + void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, + struct pipe_texture **); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct aa_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int colorOutput; /**< which output is the primary color */ + uint samplersUsed; /**< bitfield of samplers used */ + int freeSampler; /** an available sampler for the pstipple */ + int maxInput, maxGeneric; /**< max input index found */ + int colorTemp, texTemp; /**< temp registers */ + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for a free sampler, a free input attrib, and two free temp regs. + */ +static void +aa_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_OUTPUT && + decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && + decl->Semantic.SemanticIndex == 0) { + aactx->colorOutput = decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_SAMPLER) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + aactx->samplersUsed |= 1 << i; + } + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) + aactx->maxInput = decl->u.DeclarationRange.Last; + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && + (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { + aactx->maxGeneric = decl->Semantic.SemanticIndex; + } + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + aactx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +/** + * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. + */ +static int +free_bit(uint bitfield) +{ + int i; + for (i = 0; i < 32; i++) { + if ((bitfield & (1 << i)) == 0) + return i; + } + return -1; +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +aa_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (aactx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + uint i; + + /* find free sampler */ + aactx->freeSampler = free_bit(aactx->samplersUsed); + if (aactx->freeSampler >= PIPE_MAX_SAMPLERS) + aactx->freeSampler = PIPE_MAX_SAMPLERS - 1; + + /* find two free temp regs */ + for (i = 0; i < 32; i++) { + if ((aactx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (aactx->colorTemp < 0) + aactx->colorTemp = i; + else if (aactx->texTemp < 0) + aactx->texTemp = i; + else + break; + } + } + assert(aactx->colorTemp >= 0); + assert(aactx->texTemp >= 0); + + /* declare new generic input/texcoord */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; + decl.Declaration.Interpolate = 1; + /* XXX this could be linear... */ + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->maxInput + 1; + ctx->emit_declaration(ctx, &decl); + + /* declare new sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->freeSampler; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->texTemp; + ctx->emit_declaration(ctx, &decl); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->colorTemp; + ctx->emit_declaration(ctx, &decl); + + aactx->firstInstruction = FALSE; + } + + if (inst->Instruction.Opcode == TGSI_OPCODE_END && + aactx->colorOutput != -1) { + struct tgsi_full_instruction newInst; + + /* TEX */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_TEX; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->freeSampler; + + ctx->emit_instruction(ctx, &newInst); + + /* MOV rgb */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MOV; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + ctx->emit_instruction(ctx, &newInst); + + /* MUL alpha */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->texTemp; + ctx->emit_instruction(ctx, &newInst); + + /* END */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_END; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 0; + ctx->emit_instruction(ctx, &newInst); + } + else { + /* Not an END instruction. + * Look for writes to result.color and replace with colorTemp reg. + */ + uint i; + + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + if (dst->DstRegister.File == TGSI_FILE_OUTPUT && + dst->DstRegister.Index == aactx->colorOutput) { + dst->DstRegister.File = TGSI_FILE_TEMPORARY; + dst->DstRegister.Index = aactx->colorTemp; + } + } + + ctx->emit_instruction(ctx, inst); + } +} + + +/** + * Generate the frag shader we'll use for drawing AA lines. + * This will be the user's shader plus some texture/modulate instructions. + */ +static void +generate_aaline_fs(struct aaline_stage *aaline) +{ + const struct pipe_shader_state *orig_fs = &aaline->fs->state; + //struct draw_context *draw = aaline->stage.draw; + struct pipe_shader_state aaline_fs; + struct aa_transform_context transform; + +#define MAX 1000 + + aaline_fs = *orig_fs; /* copy to init */ + aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.colorOutput = -1; + transform.maxInput = -1; + transform.maxGeneric = -1; + transform.colorTemp = -1; + transform.texTemp = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = aa_transform_inst; + transform.base.transform_declaration = aa_transform_decl; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) aaline_fs.tokens, + MAX, &transform.base); + +#if 0 /* DEBUG */ + tgsi_dump(orig_fs->tokens, 0); + tgsi_dump(aaline_fs.tokens, 0); +#endif + + aaline->fs->sampler_unit = transform.freeSampler; + + aaline->fs->aaline_fs + = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); + + aaline->fs->generic_attrib = transform.maxGeneric + 1; +} + + +/** + * Create the texture map we'll use for antialiasing the lines. + */ +static void +aaline_create_texture(struct aaline_stage *aaline) +{ + struct pipe_context *pipe = aaline->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_texture texTemp; + uint level; + + memset(&texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ + texTemp.last_level = MAX_TEXTURE_LEVEL; + texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL; + texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL; + texTemp.depth[0] = 1; + texTemp.cpp = 1; + + aaline->texture = screen->texture_create(screen, &texTemp); + + /* Fill in mipmap images. + * Basically each level is solid opaque, except for the outermost + * texels which are zero. Special case the 1x1 and 2x2 levels. + */ + for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) { + struct pipe_surface *surface; + const uint size = aaline->texture->width[level]; + ubyte *data; + uint i, j; + + assert(aaline->texture->width[level] == aaline->texture->height[level]); + + surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0); + data = pipe_surface_map(surface); + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + ubyte d; + if (size == 1) { + d = 255; + } + else if (size == 2) { + d = 200; /* tuneable */ + } + else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) { + d = 0; + } + else { + d = 255; + } + data[i * surface->pitch + j] = d; + } + } + + /* unmap */ + pipe_surface_unmap(surface); + pipe_surface_reference(&surface, NULL); + pipe->texture_update(pipe, aaline->texture, 0, (1 << level)); + } +} + + +/** + * Create the sampler CSO that'll be used for antialiasing. + * By using a mipmapped texture, we don't have to generate a different + * texture image for each line size. + */ +static void +aaline_create_sampler(struct aaline_stage *aaline) +{ + struct pipe_sampler_state sampler; + struct pipe_context *pipe = aaline->pipe; + + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR; + sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.normalized_coords = 1; + sampler.min_lod = 0.0f; + sampler.max_lod = MAX_TEXTURE_LEVEL; + + aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler); +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_aaline_fragment_shader(struct aaline_stage *aaline) +{ + if (!aaline->fs->aaline_fs) { + generate_aaline_fs(aaline); + } + aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs); +} + + + +static INLINE struct aaline_stage * +aaline_stage( struct draw_stage *stage ) +{ + return (struct aaline_stage *) stage; +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw a wide line by drawing a quad, using geometry which will + * fullfill GL's antialiased line requirements. + */ +static void +aaline_line(struct draw_stage *stage, struct prim_header *header) +{ + const struct aaline_stage *aaline = aaline_stage(stage); + const float half_width = aaline->half_line_width; + struct prim_header tri; + struct vertex_header *v[8]; + uint texPos = aaline->tex_slot; + float *pos, *tex; + float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; + float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; + double a = atan2(dy, dx); + float c_a = (float) cos(a), s_a = (float) sin(a); + uint i; + + /* XXX the ends of lines aren't quite perfect yet, but probably passable */ + dx = 0.5F * half_width; + dy = half_width; + + /* allocate/dup new verts */ + for (i = 0; i < 8; i++) { + v[i] = dup_vert(stage, header->v[i/4], i); + } + + /* + * Quad strip for line from v0 to v1 (*=endpoints): + * + * 1 3 5 7 + * +---+---------------------+---+ + * | | + * | *v0 v1* | + * | | + * +---+---------------------+---+ + * 0 2 4 6 + */ + + /* new verts */ + pos = v[0]->data[0]; + pos[0] += (-dx * c_a - dy * s_a); + pos[1] += (-dx * s_a + dy * c_a); + + pos = v[1]->data[0]; + pos[0] += (-dx * c_a - -dy * s_a); + pos[1] += (-dx * s_a + -dy * c_a); + + pos = v[2]->data[0]; + pos[0] += ( dx * c_a - dy * s_a); + pos[1] += ( dx * s_a + dy * c_a); + + pos = v[3]->data[0]; + pos[0] += ( dx * c_a - -dy * s_a); + pos[1] += ( dx * s_a + -dy * c_a); + + pos = v[4]->data[0]; + pos[0] += (-dx * c_a - dy * s_a); + pos[1] += (-dx * s_a + dy * c_a); + + pos = v[5]->data[0]; + pos[0] += (-dx * c_a - -dy * s_a); + pos[1] += (-dx * s_a + -dy * c_a); + + pos = v[6]->data[0]; + pos[0] += ( dx * c_a - dy * s_a); + pos[1] += ( dx * s_a + dy * c_a); + + pos = v[7]->data[0]; + pos[0] += ( dx * c_a - -dy * s_a); + pos[1] += ( dx * s_a + -dy * c_a); + + /* new texcoords */ + tex = v[0]->data[texPos]; + ASSIGN_4V(tex, 0, 0, 0, 1); + + tex = v[1]->data[texPos]; + ASSIGN_4V(tex, 0, 1, 0, 1); + + tex = v[2]->data[texPos]; + ASSIGN_4V(tex, .5, 0, 0, 1); + + tex = v[3]->data[texPos]; + ASSIGN_4V(tex, .5, 1, 0, 1); + + tex = v[4]->data[texPos]; + ASSIGN_4V(tex, .5, 0, 0, 1); + + tex = v[5]->data[texPos]; + ASSIGN_4V(tex, .5, 1, 0, 1); + + tex = v[6]->data[texPos]; + ASSIGN_4V(tex, 1, 0, 0, 1); + + tex = v[7]->data[texPos]; + ASSIGN_4V(tex, 1, 1, 0, 1); + + /* emit 6 tris for the quad strip */ + tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[4]; tri.v[1] = v[3]; tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[5]; tri.v[1] = v[3]; tri.v[2] = v[4]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[6]; tri.v[1] = v[5]; tri.v[2] = v[4]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[7]; tri.v[1] = v[5]; tri.v[2] = v[6]; + stage->next->tri( stage->next, &tri ); +} + + +static void +aaline_first_line(struct draw_stage *stage, struct prim_header *header) +{ + auto struct aaline_stage *aaline = aaline_stage(stage); + struct draw_context *draw = stage->draw; + struct pipe_context *pipe = aaline->pipe; + uint num_samplers; + + assert(draw->rasterizer->line_smooth); + + if (draw->rasterizer->line_width <= 3.0) + aaline->half_line_width = 1.5f; + else + aaline->half_line_width = 0.5f * draw->rasterizer->line_width; + + /* + * Bind (generate) our fragprog, sampler and texture + */ + bind_aaline_fragment_shader(aaline); + + /* update vertex attrib info */ + aaline->tex_slot = draw->num_vs_outputs; + assert(aaline->tex_slot > 0); /* output[0] is vertex pos */ + + /* advertise the extra post-transformed vertex attribute */ + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; + draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib; + draw->extra_vp_outputs.slot = aaline->tex_slot; + + /* how many samplers? */ + /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ + num_samplers = MAX2(aaline->num_textures, aaline->num_samplers); + num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1); + + aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso; + pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit], + aaline->texture); + + aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler); + aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture); + + /* now really draw first line */ + stage->line = aaline_line; + stage->line(stage, header); +} + + +static void +aaline_flush(struct draw_stage *stage, unsigned flags) +{ + struct draw_context *draw = stage->draw; + struct aaline_stage *aaline = aaline_stage(stage); + struct pipe_context *pipe = aaline->pipe; + + stage->line = aaline_first_line; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); + + /* XXX restore original texture, sampler state */ + aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, + aaline->state.sampler); + aaline->driver_set_sampler_textures(pipe, aaline->num_textures, + aaline->state.texture); + + draw->extra_vp_outputs.slot = 0; +} + + +static void +aaline_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +aaline_destroy(struct draw_stage *stage) +{ + struct aaline_stage *aaline = aaline_stage(stage); + + aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); + + pipe_texture_release(&aaline->texture); + + draw_free_temp_verts( stage ); + + FREE( stage ); +} + + +static struct aaline_stage * +draw_aaline_stage(struct draw_context *draw) +{ + struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage); + + draw_alloc_temp_verts( &aaline->stage, 8 ); + + aaline->stage.draw = draw; + aaline->stage.next = NULL; + aaline->stage.point = passthrough_point; + aaline->stage.line = aaline_first_line; + aaline->stage.tri = passthrough_tri; + aaline->stage.flush = aaline_flush; + aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter; + aaline->stage.destroy = aaline_destroy; + + return aaline; +} + + +static struct aaline_stage * +aaline_stage_from_pipe(struct pipe_context *pipe) +{ + struct draw_context *draw = (struct draw_context *) pipe->draw; + return aaline_stage(draw->pipeline.aaline); +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +aaline_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs); + } + + return aafs; +} + + +static void +aaline_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; + /* save current */ + aaline->fs = aafs; + /* pass-through */ + aaline->driver_bind_fs_state(aaline->pipe, + (aafs ? aafs->driver_fs : NULL)); +} + + +static void +aaline_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; + /* pass-through */ + aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs); + FREE(aafs); +} + + +static void +aaline_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + /* save current */ + memcpy(aaline->state.sampler, sampler, num * sizeof(void *)); + aaline->num_samplers = num; + /* pass-through */ + aaline->driver_bind_sampler_states(aaline->pipe, num, sampler); +} + + +static void +aaline_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + uint i; + + /* save current */ + for (i = 0; i < num; i++) { + pipe_texture_reference(&aaline->state.texture[i], texture[i]); + } + aaline->num_textures = num; + + /* pass-through */ + aaline->driver_set_sampler_textures(aaline->pipe, num, texture); +} + + +/** + * Called by drivers that want to install this AA line prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA lines. + */ +void +draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) +{ + struct aaline_stage *aaline; + + pipe->draw = (void *) draw; + + /* + * Create / install AA line drawing / prim stage + */ + aaline = draw_aaline_stage( draw ); + assert(aaline); + draw->pipeline.aaline = &aaline->stage; + + aaline->pipe = pipe; + + /* create special texture, sampler state */ + aaline_create_texture(aaline); + aaline_create_sampler(aaline); + + /* save original driver functions */ + aaline->driver_create_fs_state = pipe->create_fs_state; + aaline->driver_bind_fs_state = pipe->bind_fs_state; + aaline->driver_delete_fs_state = pipe->delete_fs_state; + + aaline->driver_bind_sampler_states = pipe->bind_sampler_states; + aaline->driver_set_sampler_textures = pipe->set_sampler_textures; + + /* override the driver's functions */ + pipe->create_fs_state = aaline_create_fs_state; + pipe->bind_fs_state = aaline_bind_fs_state; + pipe->delete_fs_state = aaline_delete_fs_state; + + pipe->bind_sampler_states = aaline_bind_sampler_states; + pipe->set_sampler_textures = aaline_set_sampler_textures; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c new file mode 100644 index 0000000000..e84d380e50 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -0,0 +1,846 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * AA point stage: AA points are converted to quads and rendered with a + * special fragment shader. Another approach would be to use a texture + * map image of a point, but experiments indicate the quality isn't nearly + * as good as this approach. + * + * Note: this looks a lot like draw_aaline.c but there's actually little + * if any code that can be shared. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_vs.h" + + +/* + * Enabling NORMALIZE might give _slightly_ better results. + * Basically, it controls whether we compute distance as d=sqrt(x*x+y*y) or + * d=x*x+y*y. Since we're working with a unit circle, the later seems + * close enough and saves some costly instructions. + */ +#define NORMALIZE 0 + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct aapoint_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; /**< the regular shader */ + void *aapoint_fs; /**< the aa point-augmented shader */ + int generic_attrib; /**< The generic input attrib/texcoord we'll use */ +}; + + +/** + * Subclass of draw_stage + */ +struct aapoint_stage +{ + struct draw_stage stage; + + int psize_slot; + float radius; + + /** this is the vertex attrib slot for the new texcoords */ + uint tex_slot; + + /* + * Currently bound state + */ + struct aapoint_fragment_shader *fs; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct aa_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int colorOutput; /**< which output is the primary color */ + int maxInput, maxGeneric; /**< max input index found */ + int tmp0, colorTemp; /**< temp registers */ + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for two free temp regs and available input reg for new texcoords. + */ +static void +aa_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_OUTPUT && + decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && + decl->Semantic.SemanticIndex == 0) { + aactx->colorOutput = decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) + aactx->maxInput = decl->u.DeclarationRange.Last; + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && + (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { + aactx->maxGeneric = decl->Semantic.SemanticIndex; + } + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + aactx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +aa_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + struct tgsi_full_instruction newInst; + + if (aactx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + const int texInput = aactx->maxInput + 1; + int tmp0; + uint i; + + /* find two free temp regs */ + for (i = 0; i < 32; i++) { + if ((aactx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (aactx->tmp0 < 0) + aactx->tmp0 = i; + else if (aactx->colorTemp < 0) + aactx->colorTemp = i; + else + break; + } + } + + assert(aactx->colorTemp != aactx->tmp0); + + tmp0 = aactx->tmp0; + + /* declare new generic input/texcoord */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; + decl.Declaration.Interpolate = 1; + /* XXX this could be linear... */ + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = texInput; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = tmp0; + ctx->emit_declaration(ctx, &decl); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->colorTemp; + ctx->emit_declaration(ctx, &decl); + + aactx->firstInstruction = FALSE; + + + /* + * Emit code to compute fragment coverage, kill if outside point radius + * + * Temp reg0 usage: + * t0.x = distance of fragment from center point + * t0.y = boolean, is t0.x > 1.0, also misc temp usage + * t0.z = temporary for computing 1/(1-k) value + * t0.w = final coverage value + */ + + /* MUL t0.xy, tex, tex; # compute x^2, y^2 */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XY; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + ctx->emit_instruction(ctx, &newInst); + + /* ADD t0.x, t0.x, t0.y; # x^2 + y^2 */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_ADD; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + ctx->emit_instruction(ctx, &newInst); + +#if NORMALIZE /* OPTIONAL normalization of length */ + /* RSQ t0.x, t0.x; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RSQ; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + ctx->emit_instruction(ctx, &newInst); + + /* RCP t0.x, t0.x; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RCP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + ctx->emit_instruction(ctx, &newInst); +#endif + + /* SGT t0.y, t0.xxxx, t0.wwww; # bool b = d > 1 (NOTE t0.w == 1) */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SGT; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + ctx->emit_instruction(ctx, &newInst); + + /* KILP -t0.yyyy; # if b, KILL */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_KILP; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; + ctx->emit_instruction(ctx, &newInst); + + + /* compute coverage factor = (1-d)/(1-k) */ + + /* SUB t0.z, tex.w, tex.z; # m = 1 - k */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SUB; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* RCP t0.z, t0.z; # t0.z = 1 / m */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RCP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* SUB t0.y, 1, t0.x; # d = 1 - d */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SUB; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + ctx->emit_instruction(ctx, &newInst); + + /* MUL t0.w, t0.y, t0.z; # coverage = d * m */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* SLE t0.y, t0.x, tex.z; # bool b = distance <= k */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SLE; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* CMP t0.w, -t0.y, tex.w, t0.w; + * # if -t0.y < 0 then + * t0.w = 1 + * else + * t0.w = t0.w + */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_CMP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 3; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[2].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; + ctx->emit_instruction(ctx, &newInst); + + } + + if (inst->Instruction.Opcode == TGSI_OPCODE_END) { + /* add alpha modulation code at tail of program */ + + /* MOV result.color.xyz, colorTemp; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MOV; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + ctx->emit_instruction(ctx, &newInst); + + /* MUL result.color.w, colorTemp, tmp0.w; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->tmp0; + ctx->emit_instruction(ctx, &newInst); + } + else { + /* Not an END instruction. + * Look for writes to result.color and replace with colorTemp reg. + */ + uint i; + + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + if (dst->DstRegister.File == TGSI_FILE_OUTPUT && + dst->DstRegister.Index == aactx->colorOutput) { + dst->DstRegister.File = TGSI_FILE_TEMPORARY; + dst->DstRegister.Index = aactx->colorTemp; + } + } + } + + ctx->emit_instruction(ctx, inst); +} + + +/** + * Generate the frag shader we'll use for drawing AA lines. + * This will be the user's shader plus some texture/modulate instructions. + */ +static void +generate_aapoint_fs(struct aapoint_stage *aapoint) +{ + const struct pipe_shader_state *orig_fs = &aapoint->fs->state; + struct pipe_shader_state aapoint_fs; + struct aa_transform_context transform; + +#define MAX 1000 + + aapoint_fs = *orig_fs; /* copy to init */ + aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.colorOutput = -1; + transform.maxInput = -1; + transform.maxGeneric = -1; + transform.colorTemp = -1; + transform.tmp0 = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = aa_transform_inst; + transform.base.transform_declaration = aa_transform_decl; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) aapoint_fs.tokens, + MAX, &transform.base); + +#if 0 /* DEBUG */ + printf("draw_aapoint, orig shader:\n"); + tgsi_dump(orig_fs->tokens, 0); + printf("draw_aapoint, new shader:\n"); + tgsi_dump(aapoint_fs.tokens, 0); +#endif + + aapoint->fs->aapoint_fs + = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs); + + aapoint->fs->generic_attrib = transform.maxGeneric + 1; +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_aapoint_fragment_shader(struct aapoint_stage *aapoint) +{ + if (!aapoint->fs->aapoint_fs) { + generate_aapoint_fs(aapoint); + } + aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs); +} + + + +static INLINE struct aapoint_stage * +aapoint_stage( struct draw_stage *stage ) +{ + return (struct aapoint_stage *) stage; +} + + +static void +passthrough_line(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->line(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw an AA point by drawing a quad. + */ +static void +aapoint_point(struct draw_stage *stage, struct prim_header *header) +{ + const struct aapoint_stage *aapoint = aapoint_stage(stage); + struct prim_header tri; + struct vertex_header *v[4]; + uint texPos = aapoint->tex_slot; + float radius, *pos, *tex; + uint i; + float k; + + if (aapoint->psize_slot >= 0) { + radius = 0.5f * header->v[0]->data[aapoint->psize_slot][0]; + } + else { + radius = aapoint->radius; + } + + /* + * Note: the texcoords (generic attrib, really) we use are special: + * The S and T components simply vary from -1 to +1. + * The R component is k, below. + * The Q component is 1.0 and will used as a handy constant in the + * fragment shader. + */ + + /* + * k is the threshold distance from the point's center at which + * we begin alpha attenuation (the coverage value). + * Operating within a unit circle, we'll compute the fragment's + * distance 'd' from the center point using the texcoords. + * IF d > 1.0 THEN + * KILL fragment + * ELSE IF d > k THEN + * compute coverage in [0,1] proportional to d in [k, 1]. + * ELSE + * coverage = 1.0; // full coverage + * ENDIF + * + * Note: the ELSEIF and ELSE clauses are actually implemented with CMP to + * avoid using IF/ELSE/ENDIF TGSI opcodes. + */ + +#if !NORMALIZE + k = 1.0f / radius; + k = 1.0f - 2.0f * k + k * k; +#else + k = 1.0f - 1.0f / radius; +#endif + + /* allocate/dup new verts */ + for (i = 0; i < 4; i++) { + v[i] = dup_vert(stage, header->v[0], i); + } + + /* new verts */ + pos = v[0]->data[0]; + pos[0] -= radius; + pos[1] -= radius; + + pos = v[1]->data[0]; + pos[0] += radius; + pos[1] -= radius; + + pos = v[2]->data[0]; + pos[0] += radius; + pos[1] += radius; + + pos = v[3]->data[0]; + pos[0] -= radius; + pos[1] += radius; + + /* new texcoords */ + tex = v[0]->data[texPos]; + ASSIGN_4V(tex, -1, -1, k, 1); + + tex = v[1]->data[texPos]; + ASSIGN_4V(tex, 1, -1, k, 1); + + tex = v[2]->data[texPos]; + ASSIGN_4V(tex, 1, 1, k, 1); + + tex = v[3]->data[texPos]; + ASSIGN_4V(tex, -1, 1, k, 1); + + /* emit 2 tris for the quad strip */ + tri.v[0] = v[0]; + tri.v[1] = v[1]; + tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[0]; + tri.v[1] = v[2]; + tri.v[2] = v[3]; + stage->next->tri( stage->next, &tri ); +} + + +static void +aapoint_first_point(struct draw_stage *stage, struct prim_header *header) +{ + auto struct aapoint_stage *aapoint = aapoint_stage(stage); + struct draw_context *draw = stage->draw; + + assert(draw->rasterizer->point_smooth); + + if (draw->rasterizer->point_size <= 2.0) + aapoint->radius = 1.0; + else + aapoint->radius = 0.5f * draw->rasterizer->point_size; + + /* + * Bind (generate) our fragprog. + */ + bind_aapoint_fragment_shader(aapoint); + + /* update vertex attrib info */ + aapoint->tex_slot = draw->num_vs_outputs; + assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ + + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; + draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib; + draw->extra_vp_outputs.slot = aapoint->tex_slot; + + /* find psize slot in post-transform vertex */ + aapoint->psize_slot = -1; + if (draw->rasterizer->point_size_per_vertex) { + /* find PSIZ vertex output */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + aapoint->psize_slot = i; + break; + } + } + } + + /* now really draw first line */ + stage->point = aapoint_point; + stage->point(stage, header); +} + + +static void +aapoint_flush(struct draw_stage *stage, unsigned flags) +{ + struct draw_context *draw = stage->draw; + struct aapoint_stage *aapoint = aapoint_stage(stage); + struct pipe_context *pipe = aapoint->pipe; + + stage->point = aapoint_first_point; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs); + + draw->extra_vp_outputs.slot = 0; +} + + +static void +aapoint_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +aapoint_destroy(struct draw_stage *stage) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +static struct aapoint_stage * +draw_aapoint_stage(struct draw_context *draw) +{ + struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage); + + draw_alloc_temp_verts( &aapoint->stage, 4 ); + + aapoint->stage.draw = draw; + aapoint->stage.next = NULL; + aapoint->stage.point = aapoint_first_point; + aapoint->stage.line = passthrough_line; + aapoint->stage.tri = passthrough_tri; + aapoint->stage.flush = aapoint_flush; + aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter; + aapoint->stage.destroy = aapoint_destroy; + + return aapoint; +} + + +static struct aapoint_stage * +aapoint_stage_from_pipe(struct pipe_context *pipe) +{ + struct draw_context *draw = (struct draw_context *) pipe->draw; + return aapoint_stage(draw->pipeline.aapoint); +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +aapoint_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs); + } + + return aafs; +} + + +static void +aapoint_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; + /* save current */ + aapoint->fs = aafs; + /* pass-through */ + aapoint->driver_bind_fs_state(aapoint->pipe, + (aafs ? aafs->driver_fs : NULL)); +} + + +static void +aapoint_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; + /* pass-through */ + aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs); + FREE(aafs); +} + + +/** + * Called by drivers that want to install this AA point prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA points. + */ +void +draw_install_aapoint_stage(struct draw_context *draw, + struct pipe_context *pipe) +{ + struct aapoint_stage *aapoint; + + pipe->draw = (void *) draw; + + /* + * Create / install AA point drawing / prim stage + */ + aapoint = draw_aapoint_stage( draw ); + assert(aapoint); + draw->pipeline.aapoint = &aapoint->stage; + + aapoint->pipe = pipe; + + /* save original driver functions */ + aapoint->driver_create_fs_state = pipe->create_fs_state; + aapoint->driver_bind_fs_state = pipe->bind_fs_state; + aapoint->driver_delete_fs_state = pipe->delete_fs_state; + + /* override the driver's functions */ + pipe->create_fs_state = aapoint_create_fs_state; + pipe->bind_fs_state = aapoint_bind_fs_state; + pipe->delete_fs_state = aapoint_delete_fs_state; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c new file mode 100644 index 0000000000..0ac3a240e5 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -0,0 +1,503 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Clipping stage + * + * \author Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#include "draw_context.h" +#include "draw_vs.h" + + +#ifndef IS_NEGATIVE +#define IS_NEGATIVE(X) ((X) < 0.0) +#endif + +#ifndef DIFFERENT_SIGNS +#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F) +#endif + +#ifndef MAX_CLIPPED_VERTICES +#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1) +#endif + + + +struct clipper { + struct draw_stage stage; /**< base class */ + + /* Basically duplicate some of the flatshading logic here: + */ + boolean flat; + uint num_color_attribs; + uint color_attribs[4]; /* front/back primary/secondary colors */ + + float (*plane)[4]; +}; + + +/* This is a bit confusing: + */ +static INLINE struct clipper *clipper_stage( struct draw_stage *stage ) +{ + return (struct clipper *)stage; +} + + +#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT))) + + +/* All attributes are float[4], so this is easy: + */ +static void interp_attr( float *fdst, + float t, + const float *fin, + const float *fout ) +{ + fdst[0] = LINTERP( t, fout[0], fin[0] ); + fdst[1] = LINTERP( t, fout[1], fin[1] ); + fdst[2] = LINTERP( t, fout[2], fin[2] ); + fdst[3] = LINTERP( t, fout[3], fin[3] ); +} + +static void copy_colors( struct draw_stage *stage, + struct vertex_header *dst, + const struct vertex_header *src ) +{ + const struct clipper *clipper = clipper_stage(stage); + uint i; + for (i = 0; i < clipper->num_color_attribs; i++) { + const uint attr = clipper->color_attribs[i]; + COPY_4FV(dst->data[attr], src->data[attr]); + } +} + + + +/* Interpolate between two vertices to produce a third. + */ +static void interp( const struct clipper *clip, + struct vertex_header *dst, + float t, + const struct vertex_header *out, + const struct vertex_header *in ) +{ + const unsigned nr_attrs = clip->stage.draw->num_vs_outputs; + unsigned j; + + /* Vertex header. + */ + { + dst->clipmask = 0; + dst->edgeflag = 0; + dst->pad = 0; + dst->vertex_id = UNDEFINED_VERTEX_ID; + } + + /* Clip coordinates: interpolate normally + */ + { + interp_attr(dst->clip, t, in->clip, out->clip); + } + + /* Do the projective divide and insert window coordinates: + */ + { + const float *pos = dst->clip; + const float *scale = clip->stage.draw->viewport.scale; + const float *trans = clip->stage.draw->viewport.translate; + const float oow = 1.0f / pos[3]; + + dst->data[0][0] = pos[0] * oow * scale[0] + trans[0]; + dst->data[0][1] = pos[1] * oow * scale[1] + trans[1]; + dst->data[0][2] = pos[2] * oow * scale[2] + trans[2]; + dst->data[0][3] = oow; + } + + /* Other attributes + * Note: start at 1 to skip winpos (data[0]) since we just computed + * it above. + */ + for (j = 1; j < nr_attrs; j++) { + interp_attr(dst->data[j], t, in->data[j], out->data[j]); + } +} + + +static void emit_poly( struct draw_stage *stage, + struct vertex_header **inlist, + unsigned n, + const struct prim_header *origPrim) +{ + struct prim_header header; + unsigned i; + + /* later stages may need the determinant, but only the sign matters */ + header.det = origPrim->det; + + for (i = 2; i < n; i++) { + header.v[0] = inlist[i-1]; + header.v[1] = inlist[i]; + header.v[2] = inlist[0]; /* keep in v[2] for flatshading */ + + { + unsigned tmp1 = header.v[1]->edgeflag; + unsigned tmp2 = header.v[2]->edgeflag; + + if (i != n-1) header.v[1]->edgeflag = 0; + if (i != 2) header.v[2]->edgeflag = 0; + + header.edgeflags = ((header.v[0]->edgeflag << 0) | + (header.v[1]->edgeflag << 1) | + (header.v[2]->edgeflag << 2)); + + if (0) { + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + uint j, k; + debug_printf("Clipped tri:\n"); + for (j = 0; j < 3; j++) { + for (k = 0; k < vs->info.num_outputs; k++) { + debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, + header.v[j]->data[k][0], + header.v[j]->data[k][1], + header.v[j]->data[k][2], + header.v[j]->data[k][3]); + } + } + } + + stage->next->tri( stage->next, &header ); + + header.v[1]->edgeflag = tmp1; + header.v[2]->edgeflag = tmp2; + } + } +} + + + + +/* Clip a triangle against the viewport and user clip planes. + */ +static void +do_clip_tri( struct draw_stage *stage, + struct prim_header *header, + unsigned clipmask ) +{ + struct clipper *clipper = clipper_stage( stage ); + struct vertex_header *a[MAX_CLIPPED_VERTICES]; + struct vertex_header *b[MAX_CLIPPED_VERTICES]; + struct vertex_header **inlist = a; + struct vertex_header **outlist = b; + unsigned tmpnr = 0; + unsigned n = 3; + unsigned i; + + inlist[0] = header->v[0]; + inlist[1] = header->v[1]; + inlist[2] = header->v[2]; + + while (clipmask && n >= 3) { + const unsigned plane_idx = ffs(clipmask)-1; + const float *plane = clipper->plane[plane_idx]; + struct vertex_header *vert_prev = inlist[0]; + float dp_prev = dot4( vert_prev->clip, plane ); + unsigned outcount = 0; + + clipmask &= ~(1<clip, plane ); + + if (!IS_NEGATIVE(dp_prev)) { + outlist[outcount++] = vert_prev; + } + + if (DIFFERENT_SIGNS(dp, dp_prev)) { + struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++]; + outlist[outcount++] = new_vert; + + if (IS_NEGATIVE(dp)) { + /* Going out of bounds. Avoid division by zero as we + * know dp != dp_prev from DIFFERENT_SIGNS, above. + */ + float t = dp / (dp - dp_prev); + interp( clipper, new_vert, t, vert, vert_prev ); + + /* Force edgeflag true in this case: + */ + new_vert->edgeflag = 1; + } else { + /* Coming back in. + */ + float t = dp_prev / (dp_prev - dp); + interp( clipper, new_vert, t, vert_prev, vert ); + + /* Copy starting vert's edgeflag: + */ + new_vert->edgeflag = vert_prev->edgeflag; + } + } + + vert_prev = vert; + dp_prev = dp; + } + + { + struct vertex_header **tmp = inlist; + inlist = outlist; + outlist = tmp; + n = outcount; + } + } + + /* If flat-shading, copy color to new provoking vertex. + */ + if (clipper->flat && inlist[0] != header->v[2]) { + if (1) { + inlist[0] = dup_vert(stage, inlist[0], tmpnr++); + } + + copy_colors(stage, inlist[0], header->v[2]); + } + + + + /* Emit the polygon as triangles to the setup stage: + */ + if (n >= 3) + emit_poly( stage, inlist, n, header ); +} + + +/* Clip a line against the viewport and user clip planes. + */ +static void +do_clip_line( struct draw_stage *stage, + struct prim_header *header, + unsigned clipmask ) +{ + const struct clipper *clipper = clipper_stage( stage ); + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + const float *pos0 = v0->clip; + const float *pos1 = v1->clip; + float t0 = 0.0F; + float t1 = 0.0F; + struct prim_header newprim; + + while (clipmask) { + const unsigned plane_idx = ffs(clipmask)-1; + const float *plane = clipper->plane[plane_idx]; + const float dp0 = dot4( pos0, plane ); + const float dp1 = dot4( pos1, plane ); + + if (dp1 < 0.0F) { + float t = dp1 / (dp1 - dp0); + t1 = MAX2(t1, t); + } + + if (dp0 < 0.0F) { + float t = dp0 / (dp0 - dp1); + t0 = MAX2(t0, t); + } + + if (t0 + t1 >= 1.0F) + return; /* discard */ + + clipmask &= ~(1 << plane_idx); /* turn off this plane's bit */ + } + + if (v0->clipmask) { + interp( clipper, stage->tmp[0], t0, v0, v1 ); + + if (clipper->flat) + copy_colors(stage, stage->tmp[0], v0); + + newprim.v[0] = stage->tmp[0]; + } + else { + newprim.v[0] = v0; + } + + if (v1->clipmask) { + interp( clipper, stage->tmp[1], t1, v1, v0 ); + newprim.v[1] = stage->tmp[1]; + } + else { + newprim.v[1] = v1; + } + + stage->next->line( stage->next, &newprim ); +} + + +static void +clip_point( struct draw_stage *stage, + struct prim_header *header ) +{ + if (header->v[0]->clipmask == 0) + stage->next->point( stage->next, header ); +} + + +static void +clip_line( struct draw_stage *stage, + struct prim_header *header ) +{ + unsigned clipmask = (header->v[0]->clipmask | + header->v[1]->clipmask); + + if (clipmask == 0) { + /* no clipping needed */ + stage->next->line( stage->next, header ); + } + else if ((header->v[0]->clipmask & + header->v[1]->clipmask) == 0) { + do_clip_line(stage, header, clipmask); + } + /* else, totally clipped */ +} + + +static void +clip_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + unsigned clipmask = (header->v[0]->clipmask | + header->v[1]->clipmask | + header->v[2]->clipmask); + + if (clipmask == 0) { + /* no clipping needed */ + stage->next->tri( stage->next, header ); + } + else if ((header->v[0]->clipmask & + header->v[1]->clipmask & + header->v[2]->clipmask) == 0) { + do_clip_tri(stage, header, clipmask); + } +} + +/* Update state. Could further delay this until we hit the first + * primitive that really requires clipping. + */ +static void +clip_init_state( struct draw_stage *stage ) +{ + struct clipper *clipper = clipper_stage( stage ); + + clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE; + + if (clipper->flat) { + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + uint i; + + clipper->num_color_attribs = 0; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || + vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + clipper->color_attribs[clipper->num_color_attribs++] = i; + } + } + } + + stage->tri = clip_tri; + stage->line = clip_line; +} + + + +static void clip_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + clip_init_state( stage ); + stage->tri( stage, header ); +} + +static void clip_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + clip_init_state( stage ); + stage->line( stage, header ); +} + + +static void clip_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = clip_first_tri; + stage->line = clip_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void clip_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void clip_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Allocate a new clipper stage. + * \return pointer to new stage object + */ +struct draw_stage *draw_clip_stage( struct draw_context *draw ) +{ + struct clipper *clipper = CALLOC_STRUCT(clipper); + + draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ); + + clipper->stage.draw = draw; + clipper->stage.point = clip_point; + clipper->stage.line = clip_first_line; + clipper->stage.tri = clip_first_tri; + clipper->stage.flush = clip_flush; + clipper->stage.reset_stipple_counter = clip_reset_stipple_counter; + clipper->stage.destroy = clip_destroy; + + clipper->plane = draw->plane; + + return &clipper->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c new file mode 100644 index 0000000000..8177b0ac86 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -0,0 +1,150 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Drawing stage for polygon culling + */ + +/* Authors: Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + + +struct cull_stage { + struct draw_stage stage; + unsigned winding; /**< which winding(s) to cull (one of PIPE_WINDING_x) */ +}; + + +static INLINE struct cull_stage *cull_stage( struct draw_stage *stage ) +{ + return (struct cull_stage *)stage; +} + + + + +static void cull_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + /* Window coords: */ + const float *v0 = header->v[0]->data[0]; + const float *v1 = header->v[1]->data[0]; + const float *v2 = header->v[2]->data[0]; + + /* edge vectors e = v0 - v2, f = v1 - v2 */ + const float ex = v0[0] - v2[0]; + const float ey = v0[1] - v2[1]; + const float fx = v1[0] - v2[0]; + const float fy = v1[1] - v2[1]; + + /* det = cross(e,f).z */ + header->det = ex * fy - ey * fx; + + if (header->det != 0) { + /* if (det < 0 then Z points toward camera and triangle is + * counter-clockwise winding. + */ + unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; + + if ((winding & cull_stage(stage)->winding) == 0) { + /* triangle is not culled, pass to next stage */ + stage->next->tri( stage->next, header ); + } + } +} + +static void cull_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct cull_stage *cull = cull_stage(stage); + + cull->winding = stage->draw->rasterizer->cull_mode; + + stage->tri = cull_tri; + stage->tri( stage, header ); +} + + + +static void cull_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void cull_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void cull_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->tri = cull_first_tri; + stage->next->flush( stage->next, flags ); +} + +static void cull_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void cull_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create a new polygon culling stage. + */ +struct draw_stage *draw_cull_stage( struct draw_context *draw ) +{ + struct cull_stage *cull = CALLOC_STRUCT(cull_stage); + + draw_alloc_temp_verts( &cull->stage, 0 ); + + cull->stage.draw = draw; + cull->stage.next = NULL; + cull->stage.point = cull_point; + cull->stage.line = cull_line; + cull->stage.tri = cull_first_tri; + cull->stage.flush = cull_flush; + cull->stage.reset_stipple_counter = cull_reset_stipple_counter; + cull->stage.destroy = cull_destroy; + + return &cull->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c new file mode 100644 index 0000000000..54baa1fbc9 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -0,0 +1,248 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "draw_vs.h" + + +/** subclass of draw_stage */ +struct flat_stage +{ + struct draw_stage stage; + + uint num_color_attribs; + uint color_attribs[4]; /* front/back primary/secondary colors */ +}; + + +static INLINE struct flat_stage * +flat_stage(struct draw_stage *stage) +{ + return (struct flat_stage *) stage; +} + + +/** Copy all the color attributes from 'src' vertex to 'dst' vertex */ +static INLINE void copy_colors( struct draw_stage *stage, + struct vertex_header *dst, + const struct vertex_header *src ) +{ + const struct flat_stage *flat = flat_stage(stage); + uint i; + for (i = 0; i < flat->num_color_attribs; i++) { + const uint attr = flat->color_attribs[i]; + COPY_4FV(dst->data[attr], src->data[attr]); + } +} + + +/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */ +static INLINE void copy_colors2( struct draw_stage *stage, + struct vertex_header *dst0, + struct vertex_header *dst1, + const struct vertex_header *src ) +{ + const struct flat_stage *flat = flat_stage(stage); + uint i; + for (i = 0; i < flat->num_color_attribs; i++) { + const uint attr = flat->color_attribs[i]; + COPY_4FV(dst0->data[attr], src->data[attr]); + COPY_4FV(dst1->data[attr], src->data[attr]); + } +} + + +/** + * Flatshade tri. Required for clipping and when unfilled tris are + * active, otherwise handled by hardware. + */ +static void flatshade_tri_0( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + tmp.v[0] = header->v[0]; + tmp.v[1] = dup_vert(stage, header->v[1], 0); + tmp.v[2] = dup_vert(stage, header->v[2], 1); + + copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]); + + stage->next->tri( stage->next, &tmp ); +} + + +static void flatshade_tri_2( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = dup_vert(stage, header->v[1], 1); + tmp.v[2] = header->v[2]; + + copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]); + + stage->next->tri( stage->next, &tmp ); +} + + + + + +/** + * Flatshade line. Required for clipping. + */ +static void flatshade_line_0( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.v[0] = header->v[0]; + tmp.v[1] = dup_vert(stage, header->v[1], 0); + + copy_colors(stage, tmp.v[1], tmp.v[0]); + + stage->next->line( stage->next, &tmp ); +} + +static void flatshade_line_1( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = header->v[1]; + + copy_colors(stage, tmp.v[0], tmp.v[1]); + + stage->next->line( stage->next, &tmp ); +} + + +/* Flatshade point -- passthrough. + */ +static void flatshade_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void flatshade_init_state( struct draw_stage *stage ) +{ + struct flat_stage *flat = flat_stage(stage); + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + uint i; + + /* Find which vertex shader outputs are colors, make a list */ + flat->num_color_attribs = 0; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || + vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + flat->color_attribs[flat->num_color_attribs++] = i; + } + } + + /* Choose flatshade routine according to provoking vertex: + */ + if (stage->draw->rasterizer->flatshade_first) { + stage->line = flatshade_line_0; + stage->tri = flatshade_tri_0; + } + else { + stage->line = flatshade_line_1; + stage->tri = flatshade_tri_2; + } +} + +static void flatshade_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + flatshade_init_state( stage ); + stage->tri( stage, header ); +} + +static void flatshade_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + flatshade_init_state( stage ); + stage->line( stage, header ); +} + + +static void flatshade_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = flatshade_first_tri; + stage->line = flatshade_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void flatshade_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void flatshade_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create flatshading drawing stage. + */ +struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) +{ + struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage); + + draw_alloc_temp_verts( &flatshade->stage, 2 ); + + flatshade->stage.draw = draw; + flatshade->stage.next = NULL; + flatshade->stage.point = flatshade_point; + flatshade->stage.line = flatshade_first_line; + flatshade->stage.tri = flatshade_first_tri; + flatshade->stage.flush = flatshade_flush; + flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter; + flatshade->stage.destroy = flatshade_destroy; + + return &flatshade->stage; +} + + diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c new file mode 100644 index 0000000000..dbc676deae --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -0,0 +1,186 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief polygon offset state + * + * \author Keith Whitwell + * \author Brian Paul + */ + +#include "pipe/p_util.h" +#include "draw_private.h" + + + +struct offset_stage { + struct draw_stage stage; + + float scale; + float units; +}; + + + +static INLINE struct offset_stage *offset_stage( struct draw_stage *stage ) +{ + return (struct offset_stage *) stage; +} + + + + + +/** + * Offset tri Z. Some hardware can handle this, but not usually when + * doing unfilled rendering. + */ +static void do_offset_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct offset_stage *offset = offset_stage(stage); + float inv_det = 1.0f / header->det; + + /* Window coords: + */ + float *v0 = header->v[0]->data[0]; + float *v1 = header->v[1]->data[0]; + float *v2 = header->v[2]->data[0]; + + /* edge vectors e = v0 - v2, f = v1 - v2 */ + float ex = v0[0] - v2[0]; + float ey = v0[1] - v2[1]; + float ez = v0[2] - v2[2]; + float fx = v1[0] - v2[0]; + float fy = v1[1] - v2[1]; + float fz = v1[2] - v2[2]; + + /* (a,b) = cross(e,f).xy */ + float a = ey*fz - ez*fy; + float b = ez*fx - ex*fz; + + float dzdx = FABSF(a * inv_det); + float dzdy = FABSF(b * inv_det); + + float zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale; + + /* + * Note: we're applying the offset and clamping per-vertex. + * Ideally, the offset is applied per-fragment prior to fragment shading. + */ + v0[2] = CLAMP(v0[2] + zoffset, 0.0f, 1.0f); + v1[2] = CLAMP(v1[2] + zoffset, 0.0f, 1.0f); + v2[2] = CLAMP(v2[2] + zoffset, 0.0f, 1.0f); + + stage->next->tri( stage->next, header ); +} + + +static void offset_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = dup_vert(stage, header->v[1], 1); + tmp.v[2] = dup_vert(stage, header->v[2], 2); + + do_offset_tri( stage, &tmp ); +} + + +static void offset_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct offset_stage *offset = offset_stage(stage); + float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */ + + offset->units = stage->draw->rasterizer->offset_units * mrd; + offset->scale = stage->draw->rasterizer->offset_scale; + + stage->tri = offset_tri; + stage->tri( stage, header ); +} + + +static void offset_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void offset_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void offset_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = offset_first_tri; + stage->next->flush( stage->next, flags ); +} + + +static void offset_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void offset_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create polygon offset drawing stage. + */ +struct draw_stage *draw_offset_stage( struct draw_context *draw ) +{ + struct offset_stage *offset = CALLOC_STRUCT(offset_stage); + + draw_alloc_temp_verts( &offset->stage, 3 ); + + offset->stage.draw = draw; + offset->stage.next = NULL; + offset->stage.point = offset_point; + offset->stage.line = offset_line; + offset->stage.tri = offset_first_tri; + offset->stage.flush = offset_flush; + offset->stage.reset_stipple_counter = offset_reset_stipple_counter; + offset->stage.destroy = offset_destroy; + + return &offset->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c new file mode 100644 index 0000000000..4dddb72906 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -0,0 +1,746 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Polygon stipple stage: implement polygon stipple with texture map and + * fragment program. The fragment program samples the texture and does + * a fragment kill for the stipple-failing fragments. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_private.h" + + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct pstip_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; + void *pstip_fs; + uint sampler_unit; +}; + + +/** + * Subclass of draw_stage + */ +struct pstip_stage +{ + struct draw_stage stage; + + void *sampler_cso; + struct pipe_texture *texture; + uint num_samplers; + uint num_textures; + + /* + * Currently bound state + */ + struct pstip_fragment_shader *fs; + struct { + void *samplers[PIPE_MAX_SAMPLERS]; + struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; + const struct pipe_poly_stipple *stipple; + } state; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + 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_polygon_stipple)(struct pipe_context *, + const struct pipe_poly_stipple *); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct pstip_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int wincoordInput; + int maxInput; + uint samplersUsed; /**< bitfield of samplers used */ + int freeSampler; /** an available sampler for the pstipple */ + int texTemp; /**< temp registers */ + int numImmed; + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for a free sampler, a free input attrib, and two free temp regs. + */ +static void +pstip_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_SAMPLER) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + pctx->samplersUsed |= 1 << i; + } + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last); + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) + pctx->wincoordInput = (int) decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + pctx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +static void +pstip_transform_immed(struct tgsi_transform_context *ctx, + struct tgsi_full_immediate *immed) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + pctx->numImmed++; +} + + +/** + * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. + */ +static int +free_bit(uint bitfield) +{ + int i; + for (i = 0; i < 32; i++) { + if ((bitfield & (1 << i)) == 0) + return i; + } + return -1; +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +pstip_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + + if (pctx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction newInst; + uint i; + int wincoordInput; + + /* find free sampler */ + pctx->freeSampler = free_bit(pctx->samplersUsed); + if (pctx->freeSampler >= PIPE_MAX_SAMPLERS) + pctx->freeSampler = PIPE_MAX_SAMPLERS - 1; + + if (pctx->wincoordInput < 0) + wincoordInput = pctx->maxInput + 1; + else + wincoordInput = pctx->wincoordInput; + + /* find one free temp reg */ + for (i = 0; i < 32; i++) { + if ((pctx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (pctx->texTemp < 0) + pctx->texTemp = i; + else + break; + } + } + assert(pctx->texTemp >= 0); + + if (pctx->wincoordInput < 0) { + /* declare new position input reg */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; + decl.Semantic.SemanticIndex = 0; + decl.Declaration.Interpolate = 1; + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */ + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = wincoordInput; + ctx->emit_declaration(ctx, &decl); + } + + /* declare new sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = pctx->freeSampler; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = pctx->texTemp; + ctx->emit_declaration(ctx, &decl); + + /* emit immediate = {1/32, 1/32, 1, 1} + * The index/position of this immediate will be pctx->numImmed + */ + { + static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 }; + struct tgsi_full_immediate immed; + uint size = 4; + immed = tgsi_default_full_immediate(); + immed.Immediate.Size = 1 + size; /* one for the token itself */ + immed.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value; + ctx->emit_immediate(ctx, &immed); + } + + pctx->firstInstruction = FALSE; + + + /* + * Insert new MUL/TEX/KILP instructions at start of program + * Take gl_FragCoord, divide by 32 (stipple size), sample the + * texture and kill fragment if needed. + * + * We'd like to use non-normalized texcoords to index into a RECT + * texture, but we can only use GL_REPEAT wrap mode with normalized + * texcoords. Darn. + */ + + /* MUL texTemp, INPUT[wincoord], 1/32; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = wincoordInput; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_IMMEDIATE; + newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->numImmed; + ctx->emit_instruction(ctx, &newInst); + + /* TEX texTemp, texTemp, sampler; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_TEX; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler; + ctx->emit_instruction(ctx, &newInst); + + /* KILP texTemp; # if texTemp < 0, KILL fragment */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_KILP; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; + newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; + ctx->emit_instruction(ctx, &newInst); + } + + /* emit this instruction */ + ctx->emit_instruction(ctx, inst); +} + + +/** + * Generate the frag shader we'll use for doing polygon stipple. + * This will be the user's shader prefixed with a TEX and KIL instruction. + */ +static void +generate_pstip_fs(struct pstip_stage *pstip) +{ + const struct pipe_shader_state *orig_fs = &pstip->fs->state; + /*struct draw_context *draw = pstip->stage.draw;*/ + struct pipe_shader_state pstip_fs; + struct pstip_transform_context transform; + +#define MAX 1000 + + pstip_fs = *orig_fs; /* copy to init */ + pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.wincoordInput = -1; + transform.maxInput = -1; + transform.texTemp = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = pstip_transform_inst; + transform.base.transform_declaration = pstip_transform_decl; + transform.base.transform_immediate = pstip_transform_immed; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) pstip_fs.tokens, + MAX, &transform.base); + +#if 0 /* DEBUG */ + tgsi_dump(orig_fs->tokens, 0); + tgsi_dump(pstip_fs.tokens, 0); +#endif + + pstip->fs->sampler_unit = transform.freeSampler; + assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS); + + pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); +} + + +/** + * Load texture image with current stipple pattern. + */ +static void +pstip_update_texture(struct pstip_stage *pstip) +{ + static const uint bit31 = 1 << 31; + struct pipe_context *pipe = pstip->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_surface *surface; + const uint *stipple = pstip->state.stipple->stipple; + uint i, j; + ubyte *data; + + surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0); + data = pipe_surface_map(surface); + + /* + * Load alpha texture. + * Note: 0 means keep the fragment, 255 means kill it. + * We'll negate the texel value and use KILP which kills if value + * is negative. + */ + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + if (stipple[i] & (bit31 >> j)) { + /* fragment "on" */ + data[i * surface->pitch + j] = 0; + } + else { + /* fragment "off" */ + data[i * surface->pitch + j] = 255; + } + } + } + + /* unmap */ + pipe_surface_unmap(surface); + pipe_surface_reference(&surface, NULL); + pipe->texture_update(pipe, pstip->texture, 0, 0x1); +} + + +/** + * Create the texture map we'll use for stippling. + */ +static void +pstip_create_texture(struct pstip_stage *pstip) +{ + struct pipe_context *pipe = pstip->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_texture texTemp; + + memset(&texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ + texTemp.last_level = 0; + texTemp.width[0] = 32; + texTemp.height[0] = 32; + texTemp.depth[0] = 1; + texTemp.cpp = 1; + + pstip->texture = screen->texture_create(screen, &texTemp); + assert(pstip->texture->refcount == 1); +} + + +/** + * Create the sampler CSO that'll be used for antialiasing. + * By using a mipmapped texture, we don't have to generate a different + * texture image for each line size. + */ +static void +pstip_create_sampler(struct pstip_stage *pstip) +{ + struct pipe_sampler_state sampler; + struct pipe_context *pipe = pstip->pipe; + + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_REPEAT; + sampler.wrap_t = PIPE_TEX_WRAP_REPEAT; + sampler.wrap_r = PIPE_TEX_WRAP_REPEAT; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.normalized_coords = 1; + sampler.min_lod = 0.0f; + sampler.max_lod = 0.0f; + + pstip->sampler_cso = pipe->create_sampler_state(pipe, &sampler); +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_pstip_fragment_shader(struct pstip_stage *pstip) +{ + if (!pstip->fs->pstip_fs) { + generate_pstip_fs(pstip); + } + pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs); +} + + + +static INLINE struct pstip_stage * +pstip_stage( struct draw_stage *stage ) +{ + return (struct pstip_stage *) stage; +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point(stage->next, header); +} + + +static void +passthrough_line(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->line(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + + +static void +pstip_first_tri(struct draw_stage *stage, struct prim_header *header) +{ + struct pstip_stage *pstip = pstip_stage(stage); + struct pipe_context *pipe = pstip->pipe; + uint num_samplers; + + assert(stage->draw->rasterizer->poly_stipple_enable); + + /* bind our fragprog */ + bind_pstip_fragment_shader(pstip); + + /* how many samplers? */ + /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ + num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); + num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1); + + /* plug in our sampler, texture */ + pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso; + pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit], + pstip->texture); + + assert(num_samplers <= PIPE_MAX_SAMPLERS); + + pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); + pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); + + /* now really draw first line */ + stage->tri = passthrough_tri; + stage->tri(stage, header); +} + + +static void +pstip_flush(struct draw_stage *stage, unsigned flags) +{ + /*struct draw_context *draw = stage->draw;*/ + struct pstip_stage *pstip = pstip_stage(stage); + struct pipe_context *pipe = pstip->pipe; + + stage->tri = pstip_first_tri; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); + + /* XXX restore original texture, sampler state */ + pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, + pstip->state.samplers); + pstip->driver_set_sampler_textures(pipe, pstip->num_textures, + pstip->state.textures); +} + + +static void +pstip_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +pstip_destroy(struct draw_stage *stage) +{ + struct pstip_stage *pstip = pstip_stage(stage); + + pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso); + + pipe_texture_release(&pstip->texture); + + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +static struct pstip_stage * +draw_pstip_stage(struct draw_context *draw) +{ + struct pstip_stage *pstip = CALLOC_STRUCT(pstip_stage); + + draw_alloc_temp_verts( &pstip->stage, 8 ); + + pstip->stage.draw = draw; + pstip->stage.next = NULL; + pstip->stage.point = passthrough_point; + pstip->stage.line = passthrough_line; + pstip->stage.tri = pstip_first_tri; + pstip->stage.flush = pstip_flush; + pstip->stage.reset_stipple_counter = pstip_reset_stipple_counter; + pstip->stage.destroy = pstip_destroy; + + return pstip; +} + + +static struct pstip_stage * +pstip_stage_from_pipe(struct pipe_context *pipe) +{ + struct draw_context *draw = (struct draw_context *) pipe->draw; + return pstip_stage(draw->pipeline.pstipple); +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +pstip_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = CALLOC_STRUCT(pstip_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = pstip->driver_create_fs_state(pstip->pipe, fs); + } + + return aafs; +} + + +static void +pstip_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; + /* save current */ + pstip->fs = aafs; + /* pass-through */ + pstip->driver_bind_fs_state(pstip->pipe, + (aafs ? aafs->driver_fs : NULL)); +} + + +static void +pstip_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; + /* pass-through */ + pstip->driver_delete_fs_state(pstip->pipe, aafs->driver_fs); + FREE(aafs); +} + + +static void +pstip_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + uint i; + + /* save current */ + memcpy(pstip->state.samplers, sampler, num * sizeof(void *)); + for (i = num; i < PIPE_MAX_SAMPLERS; i++) { + pstip->state.samplers[i] = NULL; + } + + pstip->num_samplers = num; + /* pass-through */ + pstip->driver_bind_sampler_states(pstip->pipe, num, sampler); +} + + +static void +pstip_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + uint i; + + /* save current */ + for (i = 0; i < num; i++) { + pipe_texture_reference(&pstip->state.textures[i], texture[i]); + } + for (; i < PIPE_MAX_SAMPLERS; i++) { + pipe_texture_reference(&pstip->state.textures[i], NULL); + } + + pstip->num_textures = num; + + /* pass-through */ + pstip->driver_set_sampler_textures(pstip->pipe, num, texture); +} + + +static void +pstip_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + /* save current */ + pstip->state.stipple = stipple; + /* pass-through */ + pstip->driver_set_polygon_stipple(pstip->pipe, stipple); + + pstip_update_texture(pstip); +} + + + +/** + * Called by drivers that want to install this AA line prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA lines. + */ +void +draw_install_pstipple_stage(struct draw_context *draw, + struct pipe_context *pipe) +{ + struct pstip_stage *pstip; + + pipe->draw = (void *) draw; + + /* + * Create / install AA line drawing / prim stage + */ + pstip = draw_pstip_stage( draw ); + assert(pstip); + draw->pipeline.pstipple = &pstip->stage; + + pstip->pipe = pipe; + + /* create special texture, sampler state */ + pstip_create_texture(pstip); + pstip_create_sampler(pstip); + + /* save original driver functions */ + pstip->driver_create_fs_state = pipe->create_fs_state; + pstip->driver_bind_fs_state = pipe->bind_fs_state; + pstip->driver_delete_fs_state = pipe->delete_fs_state; + + pstip->driver_bind_sampler_states = pipe->bind_sampler_states; + pstip->driver_set_sampler_textures = pipe->set_sampler_textures; + pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; + + /* override the driver's functions */ + pipe->create_fs_state = pstip_create_fs_state; + pipe->bind_fs_state = pstip_bind_fs_state; + pipe->delete_fs_state = pstip_delete_fs_state; + + pipe->bind_sampler_states = pstip_bind_sampler_states; + pipe->set_sampler_textures = pstip_set_sampler_textures; + pipe->set_polygon_stipple = pstip_set_polygon_stipple; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c new file mode 100644 index 0000000000..506f33512c --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c @@ -0,0 +1,239 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +/* Implement line stipple by cutting lines up into smaller lines. + * There are hundreds of ways to implement line stipple, this is one + * choice that should work in all situations, requires no state + * manipulations, but with a penalty in terms of large amounts of + * generated geometry. + */ + + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +/** Subclass of draw_stage */ +struct stipple_stage { + struct draw_stage stage; + float counter; + uint pattern; + uint factor; +}; + + +static INLINE struct stipple_stage * +stipple_stage(struct draw_stage *stage) +{ + return (struct stipple_stage *) stage; +} + + +/** + * Compute interpolated vertex attributes for 'dst' at position 't' + * between 'v0' and 'v1'. + * XXX using linear interpolation for all attribs at this time. + */ +static void +screen_interp( struct draw_context *draw, + struct vertex_header *dst, + float t, + const struct vertex_header *v0, + const struct vertex_header *v1 ) +{ + uint attr; + for (attr = 0; attr < draw->num_vs_outputs; attr++) { + const float *val0 = v0->data[attr]; + const float *val1 = v1->data[attr]; + float *newv = dst->data[attr]; + uint i; + for (i = 0; i < 4; i++) { + newv[i] = val0[i] + t * (val1[i] - val0[i]); + } + } +} + + +static void +emit_segment(struct draw_stage *stage, struct prim_header *header, + float t0, float t1) +{ + struct vertex_header *v0new = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1new = dup_vert(stage, header->v[1], 1); + struct prim_header newprim = *header; + + if (t0 > 0.0) { + screen_interp( stage->draw, v0new, t0, header->v[0], header->v[1] ); + newprim.v[0] = v0new; + } + + if (t1 < 1.0) { + screen_interp( stage->draw, v1new, t1, header->v[0], header->v[1] ); + newprim.v[1] = v1new; + } + + stage->next->line( stage->next, &newprim ); +} + + +static INLINE unsigned +stipple_test(int counter, ushort pattern, int factor) +{ + int b = (counter / factor) & 0xf; + return (1 << b) & pattern; +} + + +static void +stipple_line(struct draw_stage *stage, struct prim_header *header) +{ + struct stipple_stage *stipple = stipple_stage(stage); + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + const float *pos0 = v0->data[0]; + const float *pos1 = v1->data[0]; + float start = 0; + int state = 0; + + float x0 = pos0[0]; + float x1 = pos1[0]; + float y0 = pos0[1]; + float y1 = pos1[1]; + + float dx = x0 > x1 ? x0 - x1 : x1 - x0; + float dy = y0 > y1 ? y0 - y1 : y1 - y0; + + float length = MAX2(dx, dy); + int i; + + /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table. + */ + for (i = 0; i < length; i++) { + int result = stipple_test( (int) stipple->counter+i, + (ushort) stipple->pattern, stipple->factor ); + if (result != state) { + /* changing from "off" to "on" or vice versa */ + if (state) { + if (start != i) { + /* finishing an "on" segment */ + emit_segment( stage, header, start / length, i / length ); + } + } + else { + /* starting an "on" segment */ + start = (float) i; + } + state = result; + } + } + + if (state && start < length) + emit_segment( stage, header, start / length, 1.0 ); + + stipple->counter += length; +} + + +static void +reset_stipple_counter(struct draw_stage *stage) +{ + struct stipple_stage *stipple = stipple_stage(stage); + stipple->counter = 0; + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +stipple_first_line(struct draw_stage *stage, + struct prim_header *header) +{ + struct stipple_stage *stipple = stipple_stage(stage); + struct draw_context *draw = stage->draw; + + stipple->pattern = draw->rasterizer->line_stipple_pattern; + stipple->factor = draw->rasterizer->line_stipple_factor + 1; + + stage->line = stipple_line; + stage->line( stage, header ); +} + + +static void +stipple_flush(struct draw_stage *stage, unsigned flags) +{ + stage->line = stipple_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point( stage->next, header ); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +static void +stipple_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create line stippler stage + */ +struct draw_stage *draw_stipple_stage( struct draw_context *draw ) +{ + struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage); + + draw_alloc_temp_verts( &stipple->stage, 2 ); + + stipple->stage.draw = draw; + stipple->stage.next = NULL; + stipple->stage.point = passthrough_point; + stipple->stage.line = stipple_first_line; + stipple->stage.tri = passthrough_tri; + stipple->stage.reset_stipple_counter = reset_stipple_counter; + stipple->stage.flush = stipple_flush; + stipple->stage.destroy = stipple_destroy; + + return &stipple->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c new file mode 100644 index 0000000000..01d905c153 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -0,0 +1,203 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_vs.h" + + +struct twoside_stage { + struct draw_stage stage; + float sign; /**< +1 or -1 */ + uint attrib_front0, attrib_back0; + uint attrib_front1, attrib_back1; +}; + + +static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage ) +{ + return (struct twoside_stage *)stage; +} + + + + +/** + * Copy back color(s) to front color(s). + */ +static INLINE struct vertex_header * +copy_bfc( struct twoside_stage *twoside, + const struct vertex_header *v, + unsigned idx ) +{ + struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx ); + + if (twoside->attrib_back0) { + COPY_4FV(tmp->data[twoside->attrib_front0], + tmp->data[twoside->attrib_back0]); + } + if (twoside->attrib_back1) { + COPY_4FV(tmp->data[twoside->attrib_front1], + tmp->data[twoside->attrib_back1]); + } + + return tmp; +} + + +/* Twoside tri: + */ +static void twoside_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct twoside_stage *twoside = twoside_stage(stage); + + if (header->det * twoside->sign < 0.0) { + /* this is a back-facing triangle */ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + /* copy back attribs to front attribs */ + tmp.v[0] = copy_bfc(twoside, header->v[0], 0); + tmp.v[1] = copy_bfc(twoside, header->v[1], 1); + tmp.v[2] = copy_bfc(twoside, header->v[2], 2); + + stage->next->tri( stage->next, &tmp ); + } + else { + stage->next->tri( stage->next, header ); + } +} + + +static void twoside_line( struct draw_stage *stage, + struct prim_header *header ) +{ + /* pass-through */ + stage->next->line( stage->next, header ); +} + + +static void twoside_point( struct draw_stage *stage, + struct prim_header *header ) +{ + /* pass-through */ + stage->next->point( stage->next, header ); +} + + +static void twoside_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct twoside_stage *twoside = twoside_stage(stage); + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + uint i; + + twoside->attrib_front0 = 0; + twoside->attrib_front1 = 0; + twoside->attrib_back0 = 0; + twoside->attrib_back1 = 0; + + /* Find which vertex shader outputs are front/back colors */ + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR) { + if (vs->info.output_semantic_index[i] == 0) + twoside->attrib_front0 = i; + else + twoside->attrib_front1 = i; + } + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + if (vs->info.output_semantic_index[i] == 0) + twoside->attrib_back0 = i; + else + twoside->attrib_back1 = i; + } + } + + if (!twoside->attrib_back0) + twoside->attrib_front0 = 0; + + if (!twoside->attrib_back1) + twoside->attrib_front1 = 0; + + /* + * We'll multiply the primitive's determinant by this sign to determine + * if the triangle is back-facing (negative). + * sign = -1 for CCW, +1 for CW + */ + twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f; + + stage->tri = twoside_tri; + stage->tri( stage, header ); +} + + +static void twoside_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->tri = twoside_first_tri; + stage->next->flush( stage->next, flags ); +} + + +static void twoside_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void twoside_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create twoside pipeline stage. + */ +struct draw_stage *draw_twoside_stage( struct draw_context *draw ) +{ + struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage); + + draw_alloc_temp_verts( &twoside->stage, 3 ); + + twoside->stage.draw = draw; + twoside->stage.next = NULL; + twoside->stage.point = twoside_point; + twoside->stage.line = twoside_line; + twoside->stage.tri = twoside_first_tri; + twoside->stage.flush = twoside_flush; + twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter; + twoside->stage.destroy = twoside_destroy; + + return &twoside->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c new file mode 100644 index 0000000000..b07860cd9e --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -0,0 +1,206 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Drawing stage for handling glPolygonMode(line/point). + * Convert triangles to points or lines as needed. + */ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + + +struct unfilled_stage { + struct draw_stage stage; + + /** [0] = front face, [1] = back face. + * legal values: PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE, + * and PIPE_POLYGON_MODE_POINT, + */ + unsigned mode[2]; +}; + + +static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage ) +{ + return (struct unfilled_stage *)stage; +} + + + +static void point( struct draw_stage *stage, + struct vertex_header *v0 ) +{ + struct prim_header tmp; + tmp.v[0] = v0; + stage->next->point( stage->next, &tmp ); +} + +static void line( struct draw_stage *stage, + struct vertex_header *v0, + struct vertex_header *v1 ) +{ + struct prim_header tmp; + tmp.v[0] = v0; + tmp.v[1] = v1; + stage->next->line( stage->next, &tmp ); +} + + +static void points( struct draw_stage *stage, + struct prim_header *header ) +{ + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + struct vertex_header *v2 = header->v[2]; + + if (header->edgeflags & 0x1) point( stage, v0 ); + if (header->edgeflags & 0x2) point( stage, v1 ); + if (header->edgeflags & 0x4) point( stage, v2 ); +} + + +static void lines( struct draw_stage *stage, + struct prim_header *header ) +{ + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + struct vertex_header *v2 = header->v[2]; + +#if 0 + assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag); + assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag); + assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag); +#endif + + if (header->edgeflags & 0x4) line( stage, v2, v0 ); + if (header->edgeflags & 0x1) line( stage, v0, v1 ); + if (header->edgeflags & 0x2) line( stage, v1, v2 ); +} + + +/* Unfilled tri: + * + * Note edgeflags in the vertex struct is not sufficient as we will + * need to manipulate them when decomposing primitives??? + */ +static void unfilled_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct unfilled_stage *unfilled = unfilled_stage(stage); + unsigned mode = unfilled->mode[header->det >= 0.0]; + + switch (mode) { + case PIPE_POLYGON_MODE_FILL: + stage->next->tri( stage->next, header ); + break; + case PIPE_POLYGON_MODE_LINE: + lines( stage, header ); + break; + case PIPE_POLYGON_MODE_POINT: + points( stage, header ); + break; + default: + assert(0); + } +} + + +static void unfilled_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct unfilled_stage *unfilled = unfilled_stage(stage); + + unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */ + unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */ + + stage->tri = unfilled_tri; + stage->tri( stage, header ); +} + + +static void unfilled_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void unfilled_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void unfilled_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->next->flush( stage->next, flags ); + + stage->tri = unfilled_first_tri; +} + + +static void unfilled_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void unfilled_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create unfilled triangle stage. + */ +struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) +{ + struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage); + + draw_alloc_temp_verts( &unfilled->stage, 0 ); + + unfilled->stage.draw = draw; + unfilled->stage.next = NULL; + unfilled->stage.tmp = NULL; + unfilled->stage.point = unfilled_point; + unfilled->stage.line = unfilled_line; + unfilled->stage.tri = unfilled_first_tri; + unfilled->stage.flush = unfilled_flush; + unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter; + unfilled->stage.destroy = unfilled_destroy; + + return &unfilled->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c new file mode 100644 index 0000000000..e163e078f0 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -0,0 +1,312 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + +static boolean points( unsigned prim ) +{ + return (prim == PIPE_PRIM_POINTS); +} + +static boolean lines( unsigned prim ) +{ + return (prim == PIPE_PRIM_LINES || + prim == PIPE_PRIM_LINE_STRIP || + prim == PIPE_PRIM_LINE_LOOP); +} + +static boolean triangles( unsigned prim ) +{ + return prim >= PIPE_PRIM_TRIANGLES; +} + +/** + * Check if we need any special pipeline stages, or whether + * prims/verts can go through untouched. Don't test for bypass + * clipping or vs modes, this function is just about the primitive + * pipeline stages. + */ +boolean +draw_need_pipeline(const struct draw_context *draw, + unsigned int prim ) +{ + /* Don't have to worry about triangles turning into lines/points + * and triggering the pipeline, because we have to trigger the + * pipeline *anyway* if unfilled mode is active. + */ + if (lines(prim)) + { + /* line stipple */ + if (draw->rasterizer->line_stipple_enable && draw->line_stipple) + return TRUE; + + /* wide lines */ + if (draw->rasterizer->line_width > draw->wide_line_threshold) + return TRUE; + + /* AA lines */ + if (draw->rasterizer->line_smooth && draw->pipeline.aaline) + return TRUE; + } + + if (points(prim)) + { + /* large points */ + if (draw->rasterizer->point_size > draw->wide_point_threshold) + return TRUE; + + /* AA points */ + if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) + return TRUE; + + /* point sprites */ + if (draw->rasterizer->point_sprite && draw->point_sprite) + return TRUE; + } + + + if (triangles(prim)) + { + /* polygon stipple */ + if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple) + return TRUE; + + /* unfilled polygons */ + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) + return TRUE; + + /* polygon offset */ + if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw) + return TRUE; + + /* two-side lighting */ + if (draw->rasterizer->light_twoside) + return TRUE; + } + + /* polygon cull - this is difficult - hardware can cull just fine + * most of the time (though sometimes CULL_NEITHER is unsupported. + * + * Generally this isn't a reason to require the pipeline, though. + * + if (draw->rasterizer->cull_mode) + return TRUE; + */ + + return FALSE; +} + + + +/** + * Rebuild the rendering pipeline. + */ +static struct draw_stage *validate_pipeline( struct draw_stage *stage ) +{ + struct draw_context *draw = stage->draw; + struct draw_stage *next = draw->pipeline.rasterize; + int need_det = 0; + int precalc_flat = 0; + boolean wide_lines, wide_points; + + /* Set the validate's next stage to the rasterize stage, so that it + * can be found later if needed for flushing. + */ + stage->next = next; + + /* drawing wide lines? */ + wide_lines = (draw->rasterizer->line_width > draw->wide_line_threshold + && !draw->rasterizer->line_smooth); + + /* drawing large points? */ + if (draw->rasterizer->point_sprite && draw->point_sprite) + wide_points = TRUE; + else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) + wide_points = FALSE; + else if (draw->rasterizer->point_size > draw->wide_point_threshold) + wide_points = TRUE; + else + wide_points = FALSE; + + /* + * NOTE: we build up the pipeline in end-to-start order. + * + * TODO: make the current primitive part of the state and build + * shorter pipelines for lines & points. + */ + + if (draw->rasterizer->line_smooth && draw->pipeline.aaline) { + draw->pipeline.aaline->next = next; + next = draw->pipeline.aaline; + } + + if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) { + draw->pipeline.aapoint->next = next; + next = draw->pipeline.aapoint; + } + + if (wide_lines) { + draw->pipeline.wide_line->next = next; + next = draw->pipeline.wide_line; + precalc_flat = 1; + } + + if (wide_points || draw->rasterizer->point_sprite) { + draw->pipeline.wide_point->next = next; + next = draw->pipeline.wide_point; + } + + if (draw->rasterizer->line_stipple_enable && draw->line_stipple) { + draw->pipeline.stipple->next = next; + next = draw->pipeline.stipple; + precalc_flat = 1; /* only needed for lines really */ + } + + if (draw->rasterizer->poly_stipple_enable + && draw->pipeline.pstipple) { + draw->pipeline.pstipple->next = next; + next = draw->pipeline.pstipple; + } + + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { + draw->pipeline.unfilled->next = next; + next = draw->pipeline.unfilled; + precalc_flat = 1; /* only needed for triangles really */ + need_det = 1; + } + + if (draw->rasterizer->flatshade && precalc_flat) { + draw->pipeline.flatshade->next = next; + next = draw->pipeline.flatshade; + } + + if (draw->rasterizer->offset_cw || + draw->rasterizer->offset_ccw) { + draw->pipeline.offset->next = next; + next = draw->pipeline.offset; + need_det = 1; + } + + if (draw->rasterizer->light_twoside) { + draw->pipeline.twoside->next = next; + next = draw->pipeline.twoside; + need_det = 1; + } + + /* Always run the cull stage as we calculate determinant there + * also. + * + * This can actually be a win as culling out the triangles can lead + * to less work emitting vertices, smaller vertex buffers, etc. + * It's difficult to say whether this will be true in general. + */ + if (need_det || draw->rasterizer->cull_mode) { + draw->pipeline.cull->next = next; + next = draw->pipeline.cull; + } + + /* Clip stage + */ + if (!draw->rasterizer->bypass_clipping) + { + draw->pipeline.clip->next = next; + next = draw->pipeline.clip; + } + + + draw->pipeline.first = next; + return next; +} + +static void validate_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->tri( pipeline, header ); +} + +static void validate_line( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->line( pipeline, header ); +} + +static void validate_point( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->point( pipeline, header ); +} + +static void validate_reset_stipple_counter( struct draw_stage *stage ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->reset_stipple_counter( pipeline ); +} + +static void validate_flush( struct draw_stage *stage, + unsigned flags ) +{ + /* May need to pass a backend flush on to the rasterize stage. + */ + if (stage->next) + stage->next->flush( stage->next, flags ); +} + + +static void validate_destroy( struct draw_stage *stage ) +{ + FREE( stage ); +} + + +/** + * Create validate pipeline stage. + */ +struct draw_stage *draw_validate_stage( struct draw_context *draw ) +{ + struct draw_stage *stage = CALLOC_STRUCT(draw_stage); + + stage->draw = draw; + stage->next = NULL; + stage->point = validate_point; + stage->line = validate_line; + stage->tri = validate_tri; + stage->flush = validate_flush; + stage->reset_stipple_counter = validate_reset_stipple_counter; + stage->destroy = validate_destroy; + + return stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c new file mode 100644 index 0000000000..30dceeb43d --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -0,0 +1,529 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Vertex buffer drawing stage. + * + * \author José Fonseca + * \author Keith Whitwell + */ + + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" + +#include "draw_vbuf.h" +#include "draw_private.h" +#include "draw_vertex.h" +#include "translate/translate.h" + + +/** + * Vertex buffer emit stage. + */ +struct vbuf_stage { + struct draw_stage stage; /**< This must be first (base class) */ + + struct vbuf_render *render; + + const struct vertex_info *vinfo; + + /** Vertex size in bytes */ + unsigned vertex_size; + + struct translate *translate; + + /* FIXME: we have no guarantee that 'unsigned' is 32bit */ + + /** Vertices in hardware format */ + unsigned *vertices; + unsigned *vertex_ptr; + unsigned max_vertices; + unsigned nr_vertices; + + /** Indices */ + ushort *indices; + unsigned max_indices; + unsigned nr_indices; + + /* Cache point size somewhere it's address won't change: + */ + float point_size; +}; + + +/** + * Basically a cast wrapper. + */ +static INLINE struct vbuf_stage * +vbuf_stage( struct draw_stage *stage ) +{ + assert(stage); + return (struct vbuf_stage *)stage; +} + + +static void vbuf_flush_indices( struct vbuf_stage *vbuf ); +static void vbuf_flush_vertices( struct vbuf_stage *vbuf ); +static void vbuf_alloc_vertices( struct vbuf_stage *vbuf ); + + +static INLINE boolean +overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz ) +{ + unsigned long used = (unsigned long) ((char *)ptr - (char *)map); + return (used + bytes) > bufsz; +} + + +static INLINE void +check_space( struct vbuf_stage *vbuf, unsigned nr ) +{ + if (vbuf->nr_vertices + nr > vbuf->max_vertices ) { + vbuf_flush_vertices(vbuf); + vbuf_alloc_vertices(vbuf); + } + + if (vbuf->nr_indices + nr > vbuf->max_indices ) + vbuf_flush_indices(vbuf); +} + + +static INLINE void +dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) +{ +// assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); + unsigned i, j; + + for (i = 0; i < vinfo->num_attribs; i++) { + j = vinfo->src_index[i]; + switch (vinfo->emit[i]) { + case EMIT_OMIT: + debug_printf("EMIT_OMIT:"); + break; + case EMIT_1F: + debug_printf("EMIT_1F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_1F_PSIZE: + debug_printf("EMIT_1F_PSIZE:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_2F: + debug_printf("EMIT_2F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_3F: + debug_printf("EMIT_3F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + data += sizeof(float); + break; + case EMIT_4F: + debug_printf("EMIT_4F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_4UB: + debug_printf("EMIT_4UB:\t"); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + break; + default: + assert(0); + } + debug_printf("\n"); + } + debug_printf("\n"); +} + + +/** + * Extract the needed fields from post-transformed vertex and emit + * a hardware(driver) vertex. + * Recall that the vertices are constructed by the 'draw' module and + * have a couple of slots at the beginning (1-dword header, 4-dword + * clip pos) that we ignore here. We only use the vertex->data[] fields. + */ +static INLINE ushort +emit_vertex( struct vbuf_stage *vbuf, + struct vertex_header *vertex ) +{ + if(vertex->vertex_id == UNDEFINED_VERTEX_ID) { + /* Hmm - vertices are emitted one at a time - better make sure + * set_buffer is efficient. Consider a special one-shot mode for + * translate. + */ + vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); + vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); + + if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); + + vbuf->vertex_ptr += vbuf->vertex_size/4; + vertex->vertex_id = vbuf->nr_vertices++; + } + + return vertex->vertex_id; +} + + +static void +vbuf_tri( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + unsigned i; + + check_space( vbuf, 3 ); + + for (i = 0; i < 3; i++) { + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); + } +} + + +static void +vbuf_line( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + unsigned i; + + check_space( vbuf, 2 ); + + for (i = 0; i < 2; i++) { + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); + } +} + + +static void +vbuf_point( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + check_space( vbuf, 1 ); + + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] ); +} + + + + +/** + * Set the prim type for subsequent vertices. + * This may result in a new vertex size. The existing vbuffer (if any) + * will be flushed if needed and a new one allocated. + */ +static void +vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) +{ + struct translate_key hw_key; + unsigned dst_offset; + unsigned i; + + vbuf->render->set_primitive(vbuf->render, prim); + + /* Must do this after set_primitive() above: + * + * XXX: need some state managment to track when this needs to be + * recalculated. The driver should tell us whether there was a + * state change. + */ + vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render); + + if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) { + vbuf_flush_vertices(vbuf); + vbuf->vertex_size = vbuf->vinfo->size * sizeof(float); + } + + /* Translate from pipeline vertices to hw vertices. + */ + dst_offset = 0; + memset(&hw_key, 0, sizeof(hw_key)); + + for (i = 0; i < vbuf->vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned src_buffer = 0; + unsigned output_format; + unsigned src_offset = (vbuf->vinfo->src_index[i] * 4 * sizeof(float) ); + + switch (vbuf->vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + src_buffer = 1; + src_offset = 0; + break; + case EMIT_4UB: + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); + default: + assert(0); + output_format = PIPE_FORMAT_NONE; + emit_sz = 0; + break; + } + + hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + hw_key.element[i].input_buffer = src_buffer; + hw_key.element[i].input_offset = src_offset; + hw_key.element[i].output_format = output_format; + hw_key.element[i].output_offset = dst_offset; + + dst_offset += emit_sz; + } + + hw_key.nr_elements = vbuf->vinfo->num_attribs; + hw_key.output_stride = vbuf->vinfo->size * 4; + + /* Don't bother with caching at this stage: + */ + if (!vbuf->translate || + memcmp(&vbuf->translate->key, &hw_key, sizeof(hw_key)) != 0) + { + if (vbuf->translate) + vbuf->translate->release(vbuf->translate); + + vbuf->translate = translate_create( &hw_key ); + + vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0); + } + + vbuf->point_size = vbuf->stage.draw->rasterizer->point_size; + + /* Allocate new buffer? + */ + if (!vbuf->vertices) + vbuf_alloc_vertices(vbuf); +} + + +static void +vbuf_first_tri( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->tri = vbuf_tri; + vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES); + stage->tri( stage, prim ); +} + + +static void +vbuf_first_line( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->line = vbuf_line; + vbuf_set_prim(vbuf, PIPE_PRIM_LINES); + stage->line( stage, prim ); +} + + +static void +vbuf_first_point( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->point = vbuf_point; + vbuf_set_prim(vbuf, PIPE_PRIM_POINTS); + stage->point( stage, prim ); +} + + +static void +vbuf_flush_indices( struct vbuf_stage *vbuf ) +{ + if(!vbuf->nr_indices) + return; + + assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == + vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned)); + + vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices); + + vbuf->nr_indices = 0; +} + + +/** + * Flush existing vertex buffer and allocate a new one. + * + * XXX: We separate flush-on-index-full and flush-on-vb-full, but may + * raise issues uploading vertices if the hardware wants to flush when + * we flush. + */ +static void +vbuf_flush_vertices( struct vbuf_stage *vbuf ) +{ + if(vbuf->vertices) { + vbuf_flush_indices(vbuf); + + /* Reset temporary vertices ids */ + if(vbuf->nr_vertices) + draw_reset_vertex_ids( vbuf->stage.draw ); + + /* Free the vertex buffer */ + vbuf->render->release_vertices(vbuf->render, + vbuf->vertices, + vbuf->vertex_size, + vbuf->nr_vertices); + vbuf->max_vertices = vbuf->nr_vertices = 0; + vbuf->vertex_ptr = vbuf->vertices = NULL; + + } +} + + +static void +vbuf_alloc_vertices( struct vbuf_stage *vbuf ) +{ + assert(!vbuf->nr_indices); + assert(!vbuf->vertices); + + /* Allocate a new vertex buffer */ + vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; + vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, + (ushort) vbuf->vertex_size, + (ushort) vbuf->max_vertices); + vbuf->vertex_ptr = vbuf->vertices; +} + + + +static void +vbuf_flush( struct draw_stage *stage, unsigned flags ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + + stage->point = vbuf_first_point; + stage->line = vbuf_first_line; + stage->tri = vbuf_first_tri; + + if (flags & DRAW_FLUSH_BACKEND) + vbuf_flush_vertices( vbuf ); +} + + +static void +vbuf_reset_stipple_counter( struct draw_stage *stage ) +{ + /* XXX: Need to do something here for hardware with linestipple. + */ + (void) stage; +} + + +static void vbuf_destroy( struct draw_stage *stage ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + if(vbuf->indices) + align_free( vbuf->indices ); + + if(vbuf->translate) + vbuf->translate->release( vbuf->translate ); + + if (vbuf->render) + vbuf->render->destroy( vbuf->render ); + + FREE( stage ); +} + + +/** + * Create a new primitive vbuf/render stage. + */ +struct draw_stage *draw_vbuf_stage( struct draw_context *draw, + struct vbuf_render *render ) +{ + struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); + + if(!vbuf) + goto fail; + + vbuf->stage.draw = draw; + vbuf->stage.point = vbuf_first_point; + vbuf->stage.line = vbuf_first_line; + vbuf->stage.tri = vbuf_first_tri; + vbuf->stage.flush = vbuf_flush; + vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter; + vbuf->stage.destroy = vbuf_destroy; + + vbuf->render = render; + vbuf->max_indices = MAX2(render->max_indices, UNDEFINED_VERTEX_ID-1); + + vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * + sizeof(vbuf->indices[0]), + 16 ); + if(!vbuf->indices) + goto fail; + + vbuf->vertices = NULL; + vbuf->vertex_ptr = vbuf->vertices; + + return &vbuf->stage; + + fail: + if (vbuf) + vbuf_destroy(&vbuf->stage); + + return NULL; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c new file mode 100644 index 0000000000..9a168ce8bd --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -0,0 +1,190 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +struct wideline_stage { + struct draw_stage stage; + + float half_line_width; +}; + + + +static INLINE struct wideline_stage *wideline_stage( struct draw_stage *stage ) +{ + return (struct wideline_stage *)stage; +} + + +static void wideline_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void wideline_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw a wide line by drawing a quad (two triangles). + * XXX need to disable polygon stipple. + */ +static void wideline_line( struct draw_stage *stage, + struct prim_header *header ) +{ + /*const struct wideline_stage *wide = wideline_stage(stage);*/ + const float half_width = 0.5f * stage->draw->rasterizer->line_width; + + struct prim_header tri; + + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + const float dx = FABSF(pos0[0] - pos2[0]); + const float dy = FABSF(pos0[1] - pos2[1]); + + /* small tweak to meet GL specification */ + const float bias = 0.125f; + + /* + * Draw wide line as a quad (two tris) by "stretching" the line along + * X or Y. + * We need to tweak coords in several ways to be conformant here. + */ + + if (dx > dy) { + /* x-major line */ + pos0[1] = pos0[1] - half_width - bias; + pos1[1] = pos1[1] + half_width - bias; + pos2[1] = pos2[1] - half_width - bias; + pos3[1] = pos3[1] + half_width - bias; + if (pos0[0] < pos2[0]) { + /* left to right line */ + pos0[0] -= 0.5f; + pos1[0] -= 0.5f; + pos2[0] -= 0.5f; + pos3[0] -= 0.5f; + } + else { + /* right to left line */ + pos0[0] += 0.5f; + pos1[0] += 0.5f; + pos2[0] += 0.5f; + pos3[0] += 0.5f; + } + } + else { + /* y-major line */ + pos0[0] = pos0[0] - half_width + bias; + pos1[0] = pos1[0] + half_width + bias; + pos2[0] = pos2[0] - half_width + bias; + pos3[0] = pos3[0] + half_width + bias; + if (pos0[1] < pos2[1]) { + /* top to bottom line */ + pos0[1] -= 0.5f; + pos1[1] -= 0.5f; + pos2[1] -= 0.5f; + pos3[1] -= 0.5f; + } + else { + /* bottom to top line */ + pos0[1] += 0.5f; + pos1[1] += 0.5f; + pos2[1] += 0.5f; + pos3[1] += 0.5f; + } + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +static void wideline_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->next->flush( stage->next, flags ); +} + + +static void wideline_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void wideline_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +struct draw_stage *draw_wide_line_stage( struct draw_context *draw ) +{ + struct wideline_stage *wide = CALLOC_STRUCT(wideline_stage); + + draw_alloc_temp_verts( &wide->stage, 4 ); + + wide->stage.draw = draw; + wide->stage.next = NULL; + wide->stage.point = wideline_point; + wide->stage.line = wideline_line; + wide->stage.tri = wideline_tri; + wide->stage.flush = wideline_flush; + wide->stage.reset_stipple_counter = wideline_reset_stipple_counter; + wide->stage.destroy = wideline_destroy; + + return &wide->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c new file mode 100644 index 0000000000..3d0add0c1a --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -0,0 +1,281 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_vs.h" + + +struct widepoint_stage { + struct draw_stage stage; + + float half_point_size; + float point_size_min; + float point_size_max; + + float xbias; + float ybias; + + uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; + uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; + uint num_texcoords; + + int psize_slot; +}; + + + +static INLINE struct widepoint_stage * +widepoint_stage( struct draw_stage *stage ) +{ + return (struct widepoint_stage *)stage; +} + + +static void passthrough_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + +static void widepoint_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line(stage->next, header); +} + +static void widepoint_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Set the vertex texcoords for sprite mode. + * Coords may be left untouched or set to a right-side-up or upside-down + * orientation. + */ +static void set_texcoords(const struct widepoint_stage *wide, + struct vertex_header *v, const float tc[4]) +{ + uint i; + for (i = 0; i < wide->num_texcoords; i++) { + if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { + uint j = wide->texcoord_slot[i]; + v->data[j][0] = tc[0]; + if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) + v->data[j][1] = 1.0f - tc[1]; + else + v->data[j][1] = tc[1]; + v->data[j][2] = tc[2]; + v->data[j][3] = tc[3]; + } + } +} + + +/* If there are lots of sprite points (and why wouldn't there be?) it + * would probably be more sensible to change hardware setup to + * optimize this rather than doing the whole thing in software like + * this. + */ +static void widepoint_point( struct draw_stage *stage, + struct prim_header *header ) +{ + const struct widepoint_stage *wide = widepoint_stage(stage); + const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; + float half_size; + float left_adj, right_adj, bot_adj, top_adj; + + struct prim_header tri; + + /* four dups of original vertex */ + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + /* point size is either per-vertex or fixed size */ + if (wide->psize_slot >= 0) { + half_size = header->v[0]->data[wide->psize_slot][0]; + + /* XXX: temporary -- do this in the vertex shader?? + */ + half_size = CLAMP(half_size, + wide->point_size_min, + wide->point_size_max); + + half_size *= 0.5f; + } + else { + half_size = wide->half_point_size; + } + + left_adj = -half_size + wide->xbias; + right_adj = half_size + wide->xbias; + bot_adj = half_size + wide->ybias; + top_adj = -half_size + wide->ybias; + + pos0[0] += left_adj; + pos0[1] += top_adj; + + pos1[0] += left_adj; + pos1[1] += bot_adj; + + pos2[0] += right_adj; + pos2[1] += top_adj; + + pos3[0] += right_adj; + pos3[1] += bot_adj; + + if (sprite) { + static const float tex00[4] = { 0, 0, 0, 1 }; + static const float tex01[4] = { 0, 1, 0, 1 }; + static const float tex11[4] = { 1, 1, 0, 1 }; + static const float tex10[4] = { 1, 0, 0, 1 }; + set_texcoords( wide, v0, tex00 ); + set_texcoords( wide, v1, tex01 ); + set_texcoords( wide, v2, tex10 ); + set_texcoords( wide, v3, tex11 ); + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +static void widepoint_first_point( struct draw_stage *stage, + struct prim_header *header ) +{ + struct widepoint_stage *wide = widepoint_stage(stage); + struct draw_context *draw = stage->draw; + + wide->half_point_size = 0.5f * draw->rasterizer->point_size; + wide->point_size_min = draw->rasterizer->point_size_min; + wide->point_size_max = draw->rasterizer->point_size_max; + wide->xbias = 0.0; + wide->ybias = 0.0; + + if (draw->rasterizer->gl_rasterization_rules) { + wide->xbias = 0.125; + } + + /* XXX we won't know the real size if it's computed by the vertex shader! */ + if ((draw->rasterizer->point_size > draw->wide_point_threshold) || + (draw->rasterizer->point_sprite && draw->point_sprite)) { + stage->point = widepoint_point; + } + else { + stage->point = passthrough_point; + } + + if (draw->rasterizer->point_sprite) { + /* find vertex shader texcoord outputs */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i, j = 0; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { + wide->texcoord_slot[j] = i; + wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; + j++; + } + } + wide->num_texcoords = j; + } + + wide->psize_slot = -1; + if (draw->rasterizer->point_size_per_vertex) { + /* find PSIZ vertex output */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + wide->psize_slot = i; + break; + } + } + } + + stage->point( stage, header ); +} + + +static void widepoint_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->point = widepoint_first_point; + stage->next->flush( stage->next, flags ); +} + + +static void widepoint_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void widepoint_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +struct draw_stage *draw_wide_point_stage( struct draw_context *draw ) +{ + struct widepoint_stage *wide = CALLOC_STRUCT(widepoint_stage); + + draw_alloc_temp_verts( &wide->stage, 4 ); + + wide->stage.draw = draw; + wide->stage.next = NULL; + wide->stage.point = widepoint_first_point; + wide->stage.line = widepoint_line; + wide->stage.tri = widepoint_tri; + wide->stage.flush = widepoint_flush; + wide->stage.reset_stipple_counter = widepoint_reset_stipple_counter; + wide->stage.destroy = widepoint_destroy; + + return &wide->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c b/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c new file mode 100644 index 0000000000..d6bff110b4 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c @@ -0,0 +1,366 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +struct wide_stage { + struct draw_stage stage; + + float half_line_width; + float half_point_size; + + uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; + uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; + uint num_texcoords; + + int psize_slot; +}; + + + +static INLINE struct wide_stage *wide_stage( struct draw_stage *stage ) +{ + return (struct wide_stage *)stage; +} + + +static void passthrough_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + +static void passthrough_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line(stage->next, header); +} + +static void passthrough_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw a wide line by drawing a quad (two triangles). + * XXX need to disable polygon stipple. + */ +static void wide_line( struct draw_stage *stage, + struct prim_header *header ) +{ + const struct wide_stage *wide = wide_stage(stage); + const float half_width = wide->half_line_width; + + struct prim_header tri; + + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + const float dx = FABSF(pos0[0] - pos2[0]); + const float dy = FABSF(pos0[1] - pos2[1]); + + /* + * Draw wide line as a quad (two tris) by "stretching" the line along + * X or Y. + * We need to tweak coords in several ways to be conformant here. + */ + + if (dx > dy) { + /* x-major line */ + pos0[1] = pos0[1] - half_width - 0.25f; + pos1[1] = pos1[1] + half_width - 0.25f; + pos2[1] = pos2[1] - half_width - 0.25f; + pos3[1] = pos3[1] + half_width - 0.25f; + if (pos0[0] < pos2[0]) { + /* left to right line */ + pos0[0] -= 0.5f; + pos1[0] -= 0.5f; + pos2[0] -= 0.5f; + pos3[0] -= 0.5f; + } + else { + /* right to left line */ + pos0[0] += 0.5f; + pos1[0] += 0.5f; + pos2[0] += 0.5f; + pos3[0] += 0.5f; + } + } + else { + /* y-major line */ + pos0[0] = pos0[0] - half_width + 0.25f; + pos1[0] = pos1[0] + half_width + 0.25f; + pos2[0] = pos2[0] - half_width + 0.25f; + pos3[0] = pos3[0] + half_width + 0.25f; + if (pos0[1] < pos2[1]) { + /* top to bottom line */ + pos0[1] -= 0.5f; + pos1[1] -= 0.5f; + pos2[1] -= 0.5f; + pos3[1] -= 0.5f; + } + else { + /* bottom to top line */ + pos0[1] += 0.5f; + pos1[1] += 0.5f; + pos2[1] += 0.5f; + pos3[1] += 0.5f; + } + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +/** + * Set the vertex texcoords for sprite mode. + * Coords may be left untouched or set to a right-side-up or upside-down + * orientation. + */ +static void set_texcoords(const struct wide_stage *wide, + struct vertex_header *v, const float tc[4]) +{ + uint i; + for (i = 0; i < wide->num_texcoords; i++) { + if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { + uint j = wide->texcoord_slot[i]; + v->data[j][0] = tc[0]; + if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) + v->data[j][1] = 1.0f - tc[1]; + else + v->data[j][1] = tc[1]; + v->data[j][2] = tc[2]; + v->data[j][3] = tc[3]; + } + } +} + + +/* If there are lots of sprite points (and why wouldn't there be?) it + * would probably be more sensible to change hardware setup to + * optimize this rather than doing the whole thing in software like + * this. + */ +static void wide_point( struct draw_stage *stage, + struct prim_header *header ) +{ + const struct wide_stage *wide = wide_stage(stage); + const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; + float half_size; + float left_adj, right_adj; + + struct prim_header tri; + + /* four dups of original vertex */ + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + /* point size is either per-vertex or fixed size */ + if (wide->psize_slot >= 0) { + half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; + } + else { + half_size = wide->half_point_size; + } + + left_adj = -half_size; /* + 0.25f;*/ + right_adj = half_size; /* + 0.25f;*/ + + pos0[0] += left_adj; + pos0[1] -= half_size; + + pos1[0] += left_adj; + pos1[1] += half_size; + + pos2[0] += right_adj; + pos2[1] -= half_size; + + pos3[0] += right_adj; + pos3[1] += half_size; + + if (sprite) { + static const float tex00[4] = { 0, 0, 0, 1 }; + static const float tex01[4] = { 0, 1, 0, 1 }; + static const float tex11[4] = { 1, 1, 0, 1 }; + static const float tex10[4] = { 1, 0, 0, 1 }; + set_texcoords( wide, v0, tex00 ); + set_texcoords( wide, v1, tex01 ); + set_texcoords( wide, v2, tex10 ); + set_texcoords( wide, v3, tex11 ); + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +static void wide_first_point( struct draw_stage *stage, + struct prim_header *header ) +{ + struct wide_stage *wide = wide_stage(stage); + struct draw_context *draw = stage->draw; + + wide->half_point_size = 0.5f * draw->rasterizer->point_size; + + /* XXX we won't know the real size if it's computed by the vertex shader! */ + if (draw->rasterizer->point_size > draw->wide_point_threshold) { + stage->point = wide_point; + } + else { + stage->point = passthrough_point; + } + + if (draw->rasterizer->point_sprite) { + /* find vertex shader texcoord outputs */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i, j = 0; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { + wide->texcoord_slot[j] = i; + wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; + j++; + } + } + wide->num_texcoords = j; + } + + wide->psize_slot = -1; + + if (draw->rasterizer->point_size_per_vertex) { + /* find PSIZ vertex output */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + wide->psize_slot = i; + break; + } + } + } + + stage->point( stage, header ); +} + + + +static void wide_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + struct wide_stage *wide = wide_stage(stage); + struct draw_context *draw = stage->draw; + + wide->half_line_width = 0.5f * draw->rasterizer->line_width; + + if (draw->rasterizer->line_width != 1.0) { + wide->stage.line = wide_line; + } + else { + wide->stage.line = passthrough_line; + } + + stage->line( stage, header ); +} + + +static void wide_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->line = wide_first_line; + stage->point = wide_first_point; + stage->next->flush( stage->next, flags ); +} + + +static void wide_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void wide_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +struct draw_stage *draw_wide_stage( struct draw_context *draw ) +{ + struct wide_stage *wide = CALLOC_STRUCT(wide_stage); + + draw_alloc_temp_verts( &wide->stage, 4 ); + + wide->stage.draw = draw; + wide->stage.next = NULL; + wide->stage.point = wide_first_point; + wide->stage.line = wide_first_line; + wide->stage.tri = passthrough_tri; + wide->stage.flush = wide_flush; + wide->stage.reset_stipple_counter = wide_reset_stipple_counter; + wide->stage.destroy = wide_destroy; + + return &wide->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c deleted file mode 100644 index 4dddb72906..0000000000 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ /dev/null @@ -1,746 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * Polygon stipple stage: implement polygon stipple with texture map and - * fragment program. The fragment program samples the texture and does - * a fragment kill for the stipple-failing fragments. - * - * Authors: Brian Paul - */ - - -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/util/tgsi_transform.h" -#include "tgsi/util/tgsi_dump.h" - -#include "draw_context.h" -#include "draw_private.h" - - - -/** - * Subclass of pipe_shader_state to carry extra fragment shader info. - */ -struct pstip_fragment_shader -{ - struct pipe_shader_state state; - void *driver_fs; - void *pstip_fs; - uint sampler_unit; -}; - - -/** - * Subclass of draw_stage - */ -struct pstip_stage -{ - struct draw_stage stage; - - void *sampler_cso; - struct pipe_texture *texture; - uint num_samplers; - uint num_textures; - - /* - * Currently bound state - */ - struct pstip_fragment_shader *fs; - struct { - void *samplers[PIPE_MAX_SAMPLERS]; - struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; - const struct pipe_poly_stipple *stipple; - } state; - - /* - * Driver interface/override functions - */ - void * (*driver_create_fs_state)(struct pipe_context *, - const struct pipe_shader_state *); - void (*driver_bind_fs_state)(struct pipe_context *, void *); - void (*driver_delete_fs_state)(struct pipe_context *, void *); - - 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_polygon_stipple)(struct pipe_context *, - const struct pipe_poly_stipple *); - - struct pipe_context *pipe; -}; - - - -/** - * Subclass of tgsi_transform_context, used for transforming the - * user's fragment shader to add the special AA instructions. - */ -struct pstip_transform_context { - struct tgsi_transform_context base; - uint tempsUsed; /**< bitmask */ - int wincoordInput; - int maxInput; - uint samplersUsed; /**< bitfield of samplers used */ - int freeSampler; /** an available sampler for the pstipple */ - int texTemp; /**< temp registers */ - int numImmed; - boolean firstInstruction; -}; - - -/** - * TGSI declaration transform callback. - * Look for a free sampler, a free input attrib, and two free temp regs. - */ -static void -pstip_transform_decl(struct tgsi_transform_context *ctx, - struct tgsi_full_declaration *decl) -{ - struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; - - if (decl->Declaration.File == TGSI_FILE_SAMPLER) { - uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { - pctx->samplersUsed |= 1 << i; - } - } - else if (decl->Declaration.File == TGSI_FILE_INPUT) { - pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last); - if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) - pctx->wincoordInput = (int) decl->u.DeclarationRange.First; - } - else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { - uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { - pctx->tempsUsed |= (1 << i); - } - } - - ctx->emit_declaration(ctx, decl); -} - - -static void -pstip_transform_immed(struct tgsi_transform_context *ctx, - struct tgsi_full_immediate *immed) -{ - struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; - pctx->numImmed++; -} - - -/** - * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. - */ -static int -free_bit(uint bitfield) -{ - int i; - for (i = 0; i < 32; i++) { - if ((bitfield & (1 << i)) == 0) - return i; - } - return -1; -} - - -/** - * TGSI instruction transform callback. - * Replace writes to result.color w/ a temp reg. - * Upon END instruction, insert texture sampling code for antialiasing. - */ -static void -pstip_transform_inst(struct tgsi_transform_context *ctx, - struct tgsi_full_instruction *inst) -{ - struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; - - if (pctx->firstInstruction) { - /* emit our new declarations before the first instruction */ - - struct tgsi_full_declaration decl; - struct tgsi_full_instruction newInst; - uint i; - int wincoordInput; - - /* find free sampler */ - pctx->freeSampler = free_bit(pctx->samplersUsed); - if (pctx->freeSampler >= PIPE_MAX_SAMPLERS) - pctx->freeSampler = PIPE_MAX_SAMPLERS - 1; - - if (pctx->wincoordInput < 0) - wincoordInput = pctx->maxInput + 1; - else - wincoordInput = pctx->wincoordInput; - - /* find one free temp reg */ - for (i = 0; i < 32; i++) { - if ((pctx->tempsUsed & (1 << i)) == 0) { - /* found a free temp */ - if (pctx->texTemp < 0) - pctx->texTemp = i; - else - break; - } - } - assert(pctx->texTemp >= 0); - - if (pctx->wincoordInput < 0) { - /* declare new position input reg */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; - decl.Semantic.SemanticIndex = 0; - decl.Declaration.Interpolate = 1; - decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */ - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = wincoordInput; - ctx->emit_declaration(ctx, &decl); - } - - /* declare new sampler */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_SAMPLER; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = pctx->freeSampler; - ctx->emit_declaration(ctx, &decl); - - /* declare new temp regs */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = pctx->texTemp; - ctx->emit_declaration(ctx, &decl); - - /* emit immediate = {1/32, 1/32, 1, 1} - * The index/position of this immediate will be pctx->numImmed - */ - { - static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 }; - struct tgsi_full_immediate immed; - uint size = 4; - immed = tgsi_default_full_immediate(); - immed.Immediate.Size = 1 + size; /* one for the token itself */ - immed.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value; - ctx->emit_immediate(ctx, &immed); - } - - pctx->firstInstruction = FALSE; - - - /* - * Insert new MUL/TEX/KILP instructions at start of program - * Take gl_FragCoord, divide by 32 (stipple size), sample the - * texture and kill fragment if needed. - * - * We'd like to use non-normalized texcoords to index into a RECT - * texture, but we can only use GL_REPEAT wrap mode with normalized - * texcoords. Darn. - */ - - /* MUL texTemp, INPUT[wincoord], 1/32; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MUL; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = wincoordInput; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_IMMEDIATE; - newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->numImmed; - ctx->emit_instruction(ctx, &newInst); - - /* TEX texTemp, texTemp, sampler; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_TEX; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; - newInst.Instruction.NumSrcRegs = 2; - newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler; - ctx->emit_instruction(ctx, &newInst); - - /* KILP texTemp; # if texTemp < 0, KILL fragment */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_KILP; - newInst.Instruction.NumDstRegs = 0; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; - newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; - ctx->emit_instruction(ctx, &newInst); - } - - /* emit this instruction */ - ctx->emit_instruction(ctx, inst); -} - - -/** - * Generate the frag shader we'll use for doing polygon stipple. - * This will be the user's shader prefixed with a TEX and KIL instruction. - */ -static void -generate_pstip_fs(struct pstip_stage *pstip) -{ - const struct pipe_shader_state *orig_fs = &pstip->fs->state; - /*struct draw_context *draw = pstip->stage.draw;*/ - struct pipe_shader_state pstip_fs; - struct pstip_transform_context transform; - -#define MAX 1000 - - pstip_fs = *orig_fs; /* copy to init */ - pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); - - memset(&transform, 0, sizeof(transform)); - transform.wincoordInput = -1; - transform.maxInput = -1; - transform.texTemp = -1; - transform.firstInstruction = TRUE; - transform.base.transform_instruction = pstip_transform_inst; - transform.base.transform_declaration = pstip_transform_decl; - transform.base.transform_immediate = pstip_transform_immed; - - tgsi_transform_shader(orig_fs->tokens, - (struct tgsi_token *) pstip_fs.tokens, - MAX, &transform.base); - -#if 0 /* DEBUG */ - tgsi_dump(orig_fs->tokens, 0); - tgsi_dump(pstip_fs.tokens, 0); -#endif - - pstip->fs->sampler_unit = transform.freeSampler; - assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS); - - pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); -} - - -/** - * Load texture image with current stipple pattern. - */ -static void -pstip_update_texture(struct pstip_stage *pstip) -{ - static const uint bit31 = 1 << 31; - struct pipe_context *pipe = pstip->pipe; - struct pipe_screen *screen = pipe->screen; - struct pipe_surface *surface; - const uint *stipple = pstip->state.stipple->stipple; - uint i, j; - ubyte *data; - - surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0); - data = pipe_surface_map(surface); - - /* - * Load alpha texture. - * Note: 0 means keep the fragment, 255 means kill it. - * We'll negate the texel value and use KILP which kills if value - * is negative. - */ - for (i = 0; i < 32; i++) { - for (j = 0; j < 32; j++) { - if (stipple[i] & (bit31 >> j)) { - /* fragment "on" */ - data[i * surface->pitch + j] = 0; - } - else { - /* fragment "off" */ - data[i * surface->pitch + j] = 255; - } - } - } - - /* unmap */ - pipe_surface_unmap(surface); - pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, pstip->texture, 0, 0x1); -} - - -/** - * Create the texture map we'll use for stippling. - */ -static void -pstip_create_texture(struct pstip_stage *pstip) -{ - struct pipe_context *pipe = pstip->pipe; - struct pipe_screen *screen = pipe->screen; - struct pipe_texture texTemp; - - memset(&texTemp, 0, sizeof(texTemp)); - texTemp.target = PIPE_TEXTURE_2D; - texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ - texTemp.last_level = 0; - texTemp.width[0] = 32; - texTemp.height[0] = 32; - texTemp.depth[0] = 1; - texTemp.cpp = 1; - - pstip->texture = screen->texture_create(screen, &texTemp); - assert(pstip->texture->refcount == 1); -} - - -/** - * Create the sampler CSO that'll be used for antialiasing. - * By using a mipmapped texture, we don't have to generate a different - * texture image for each line size. - */ -static void -pstip_create_sampler(struct pstip_stage *pstip) -{ - struct pipe_sampler_state sampler; - struct pipe_context *pipe = pstip->pipe; - - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_REPEAT; - sampler.wrap_t = PIPE_TEX_WRAP_REPEAT; - sampler.wrap_r = PIPE_TEX_WRAP_REPEAT; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; - sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; - sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; - sampler.normalized_coords = 1; - sampler.min_lod = 0.0f; - sampler.max_lod = 0.0f; - - pstip->sampler_cso = pipe->create_sampler_state(pipe, &sampler); -} - - -/** - * When we're about to draw our first AA line in a batch, this function is - * called to tell the driver to bind our modified fragment shader. - */ -static void -bind_pstip_fragment_shader(struct pstip_stage *pstip) -{ - if (!pstip->fs->pstip_fs) { - generate_pstip_fs(pstip); - } - pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs); -} - - - -static INLINE struct pstip_stage * -pstip_stage( struct draw_stage *stage ) -{ - return (struct pstip_stage *) stage; -} - - -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point(stage->next, header); -} - - -static void -passthrough_line(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->line(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} - - - -static void -pstip_first_tri(struct draw_stage *stage, struct prim_header *header) -{ - struct pstip_stage *pstip = pstip_stage(stage); - struct pipe_context *pipe = pstip->pipe; - uint num_samplers; - - assert(stage->draw->rasterizer->poly_stipple_enable); - - /* bind our fragprog */ - bind_pstip_fragment_shader(pstip); - - /* how many samplers? */ - /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ - num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); - num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1); - - /* plug in our sampler, texture */ - pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso; - pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit], - pstip->texture); - - assert(num_samplers <= PIPE_MAX_SAMPLERS); - - pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); - pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); - - /* now really draw first line */ - stage->tri = passthrough_tri; - stage->tri(stage, header); -} - - -static void -pstip_flush(struct draw_stage *stage, unsigned flags) -{ - /*struct draw_context *draw = stage->draw;*/ - struct pstip_stage *pstip = pstip_stage(stage); - struct pipe_context *pipe = pstip->pipe; - - stage->tri = pstip_first_tri; - stage->next->flush( stage->next, flags ); - - /* restore original frag shader */ - pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); - - /* XXX restore original texture, sampler state */ - pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, - pstip->state.samplers); - pstip->driver_set_sampler_textures(pipe, pstip->num_textures, - pstip->state.textures); -} - - -static void -pstip_reset_stipple_counter(struct draw_stage *stage) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void -pstip_destroy(struct draw_stage *stage) -{ - struct pstip_stage *pstip = pstip_stage(stage); - - pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso); - - pipe_texture_release(&pstip->texture); - - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -static struct pstip_stage * -draw_pstip_stage(struct draw_context *draw) -{ - struct pstip_stage *pstip = CALLOC_STRUCT(pstip_stage); - - draw_alloc_temp_verts( &pstip->stage, 8 ); - - pstip->stage.draw = draw; - pstip->stage.next = NULL; - pstip->stage.point = passthrough_point; - pstip->stage.line = passthrough_line; - pstip->stage.tri = pstip_first_tri; - pstip->stage.flush = pstip_flush; - pstip->stage.reset_stipple_counter = pstip_reset_stipple_counter; - pstip->stage.destroy = pstip_destroy; - - return pstip; -} - - -static struct pstip_stage * -pstip_stage_from_pipe(struct pipe_context *pipe) -{ - struct draw_context *draw = (struct draw_context *) pipe->draw; - return pstip_stage(draw->pipeline.pstipple); -} - - -/** - * This function overrides the driver's create_fs_state() function and - * will typically be called by the state tracker. - */ -static void * -pstip_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *fs) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - struct pstip_fragment_shader *aafs = CALLOC_STRUCT(pstip_fragment_shader); - - if (aafs) { - aafs->state = *fs; - - /* pass-through */ - aafs->driver_fs = pstip->driver_create_fs_state(pstip->pipe, fs); - } - - return aafs; -} - - -static void -pstip_bind_fs_state(struct pipe_context *pipe, void *fs) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; - /* save current */ - pstip->fs = aafs; - /* pass-through */ - pstip->driver_bind_fs_state(pstip->pipe, - (aafs ? aafs->driver_fs : NULL)); -} - - -static void -pstip_delete_fs_state(struct pipe_context *pipe, void *fs) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; - /* pass-through */ - pstip->driver_delete_fs_state(pstip->pipe, aafs->driver_fs); - FREE(aafs); -} - - -static void -pstip_bind_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - uint i; - - /* save current */ - memcpy(pstip->state.samplers, sampler, num * sizeof(void *)); - for (i = num; i < PIPE_MAX_SAMPLERS; i++) { - pstip->state.samplers[i] = NULL; - } - - pstip->num_samplers = num; - /* pass-through */ - pstip->driver_bind_sampler_states(pstip->pipe, num, sampler); -} - - -static void -pstip_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - uint i; - - /* save current */ - for (i = 0; i < num; i++) { - pipe_texture_reference(&pstip->state.textures[i], texture[i]); - } - for (; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&pstip->state.textures[i], NULL); - } - - pstip->num_textures = num; - - /* pass-through */ - pstip->driver_set_sampler_textures(pstip->pipe, num, texture); -} - - -static void -pstip_set_polygon_stipple(struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - /* save current */ - pstip->state.stipple = stipple; - /* pass-through */ - pstip->driver_set_polygon_stipple(pstip->pipe, stipple); - - pstip_update_texture(pstip); -} - - - -/** - * Called by drivers that want to install this AA line prim stage - * into the draw module's pipeline. This will not be used if the - * hardware has native support for AA lines. - */ -void -draw_install_pstipple_stage(struct draw_context *draw, - struct pipe_context *pipe) -{ - struct pstip_stage *pstip; - - pipe->draw = (void *) draw; - - /* - * Create / install AA line drawing / prim stage - */ - pstip = draw_pstip_stage( draw ); - assert(pstip); - draw->pipeline.pstipple = &pstip->stage; - - pstip->pipe = pipe; - - /* create special texture, sampler state */ - pstip_create_texture(pstip); - pstip_create_sampler(pstip); - - /* save original driver functions */ - pstip->driver_create_fs_state = pipe->create_fs_state; - pstip->driver_bind_fs_state = pipe->bind_fs_state; - pstip->driver_delete_fs_state = pipe->delete_fs_state; - - pstip->driver_bind_sampler_states = pipe->bind_sampler_states; - pstip->driver_set_sampler_textures = pipe->set_sampler_textures; - pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; - - /* override the driver's functions */ - pipe->create_fs_state = pstip_create_fs_state; - pipe->bind_fs_state = pstip_bind_fs_state; - pipe->delete_fs_state = pstip_delete_fs_state; - - pipe->bind_sampler_states = pstip_bind_sampler_states; - pipe->set_sampler_textures = pstip_set_sampler_textures; - pipe->set_polygon_stipple = pstip_set_polygon_stipple; -} diff --git a/src/gallium/auxiliary/draw/draw_stipple.c b/src/gallium/auxiliary/draw/draw_stipple.c deleted file mode 100644 index 506f33512c..0000000000 --- a/src/gallium/auxiliary/draw/draw_stipple.c +++ /dev/null @@ -1,239 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -/* Implement line stipple by cutting lines up into smaller lines. - * There are hundreds of ways to implement line stipple, this is one - * choice that should work in all situations, requires no state - * manipulations, but with a penalty in terms of large amounts of - * generated geometry. - */ - - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -/** Subclass of draw_stage */ -struct stipple_stage { - struct draw_stage stage; - float counter; - uint pattern; - uint factor; -}; - - -static INLINE struct stipple_stage * -stipple_stage(struct draw_stage *stage) -{ - return (struct stipple_stage *) stage; -} - - -/** - * Compute interpolated vertex attributes for 'dst' at position 't' - * between 'v0' and 'v1'. - * XXX using linear interpolation for all attribs at this time. - */ -static void -screen_interp( struct draw_context *draw, - struct vertex_header *dst, - float t, - const struct vertex_header *v0, - const struct vertex_header *v1 ) -{ - uint attr; - for (attr = 0; attr < draw->num_vs_outputs; attr++) { - const float *val0 = v0->data[attr]; - const float *val1 = v1->data[attr]; - float *newv = dst->data[attr]; - uint i; - for (i = 0; i < 4; i++) { - newv[i] = val0[i] + t * (val1[i] - val0[i]); - } - } -} - - -static void -emit_segment(struct draw_stage *stage, struct prim_header *header, - float t0, float t1) -{ - struct vertex_header *v0new = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1new = dup_vert(stage, header->v[1], 1); - struct prim_header newprim = *header; - - if (t0 > 0.0) { - screen_interp( stage->draw, v0new, t0, header->v[0], header->v[1] ); - newprim.v[0] = v0new; - } - - if (t1 < 1.0) { - screen_interp( stage->draw, v1new, t1, header->v[0], header->v[1] ); - newprim.v[1] = v1new; - } - - stage->next->line( stage->next, &newprim ); -} - - -static INLINE unsigned -stipple_test(int counter, ushort pattern, int factor) -{ - int b = (counter / factor) & 0xf; - return (1 << b) & pattern; -} - - -static void -stipple_line(struct draw_stage *stage, struct prim_header *header) -{ - struct stipple_stage *stipple = stipple_stage(stage); - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - const float *pos0 = v0->data[0]; - const float *pos1 = v1->data[0]; - float start = 0; - int state = 0; - - float x0 = pos0[0]; - float x1 = pos1[0]; - float y0 = pos0[1]; - float y1 = pos1[1]; - - float dx = x0 > x1 ? x0 - x1 : x1 - x0; - float dy = y0 > y1 ? y0 - y1 : y1 - y0; - - float length = MAX2(dx, dy); - int i; - - /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table. - */ - for (i = 0; i < length; i++) { - int result = stipple_test( (int) stipple->counter+i, - (ushort) stipple->pattern, stipple->factor ); - if (result != state) { - /* changing from "off" to "on" or vice versa */ - if (state) { - if (start != i) { - /* finishing an "on" segment */ - emit_segment( stage, header, start / length, i / length ); - } - } - else { - /* starting an "on" segment */ - start = (float) i; - } - state = result; - } - } - - if (state && start < length) - emit_segment( stage, header, start / length, 1.0 ); - - stipple->counter += length; -} - - -static void -reset_stipple_counter(struct draw_stage *stage) -{ - struct stipple_stage *stipple = stipple_stage(stage); - stipple->counter = 0; - stage->next->reset_stipple_counter( stage->next ); -} - - -static void -stipple_first_line(struct draw_stage *stage, - struct prim_header *header) -{ - struct stipple_stage *stipple = stipple_stage(stage); - struct draw_context *draw = stage->draw; - - stipple->pattern = draw->rasterizer->line_stipple_pattern; - stipple->factor = draw->rasterizer->line_stipple_factor + 1; - - stage->line = stipple_line; - stage->line( stage, header ); -} - - -static void -stipple_flush(struct draw_stage *stage, unsigned flags) -{ - stage->line = stipple_first_line; - stage->next->flush( stage->next, flags ); -} - - -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point( stage->next, header ); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} - - -static void -stipple_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create line stippler stage - */ -struct draw_stage *draw_stipple_stage( struct draw_context *draw ) -{ - struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage); - - draw_alloc_temp_verts( &stipple->stage, 2 ); - - stipple->stage.draw = draw; - stipple->stage.next = NULL; - stipple->stage.point = passthrough_point; - stipple->stage.line = stipple_first_line; - stipple->stage.tri = passthrough_tri; - stipple->stage.reset_stipple_counter = reset_stipple_counter; - stipple->stage.flush = stipple_flush; - stipple->stage.destroy = stipple_destroy; - - return &stipple->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_twoside.c b/src/gallium/auxiliary/draw/draw_twoside.c deleted file mode 100644 index 01d905c153..0000000000 --- a/src/gallium/auxiliary/draw/draw_twoside.c +++ /dev/null @@ -1,203 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_vs.h" - - -struct twoside_stage { - struct draw_stage stage; - float sign; /**< +1 or -1 */ - uint attrib_front0, attrib_back0; - uint attrib_front1, attrib_back1; -}; - - -static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage ) -{ - return (struct twoside_stage *)stage; -} - - - - -/** - * Copy back color(s) to front color(s). - */ -static INLINE struct vertex_header * -copy_bfc( struct twoside_stage *twoside, - const struct vertex_header *v, - unsigned idx ) -{ - struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx ); - - if (twoside->attrib_back0) { - COPY_4FV(tmp->data[twoside->attrib_front0], - tmp->data[twoside->attrib_back0]); - } - if (twoside->attrib_back1) { - COPY_4FV(tmp->data[twoside->attrib_front1], - tmp->data[twoside->attrib_back1]); - } - - return tmp; -} - - -/* Twoside tri: - */ -static void twoside_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct twoside_stage *twoside = twoside_stage(stage); - - if (header->det * twoside->sign < 0.0) { - /* this is a back-facing triangle */ - struct prim_header tmp; - - tmp.det = header->det; - tmp.edgeflags = header->edgeflags; - /* copy back attribs to front attribs */ - tmp.v[0] = copy_bfc(twoside, header->v[0], 0); - tmp.v[1] = copy_bfc(twoside, header->v[1], 1); - tmp.v[2] = copy_bfc(twoside, header->v[2], 2); - - stage->next->tri( stage->next, &tmp ); - } - else { - stage->next->tri( stage->next, header ); - } -} - - -static void twoside_line( struct draw_stage *stage, - struct prim_header *header ) -{ - /* pass-through */ - stage->next->line( stage->next, header ); -} - - -static void twoside_point( struct draw_stage *stage, - struct prim_header *header ) -{ - /* pass-through */ - stage->next->point( stage->next, header ); -} - - -static void twoside_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct twoside_stage *twoside = twoside_stage(stage); - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; - uint i; - - twoside->attrib_front0 = 0; - twoside->attrib_front1 = 0; - twoside->attrib_back0 = 0; - twoside->attrib_back1 = 0; - - /* Find which vertex shader outputs are front/back colors */ - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR) { - if (vs->info.output_semantic_index[i] == 0) - twoside->attrib_front0 = i; - else - twoside->attrib_front1 = i; - } - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { - if (vs->info.output_semantic_index[i] == 0) - twoside->attrib_back0 = i; - else - twoside->attrib_back1 = i; - } - } - - if (!twoside->attrib_back0) - twoside->attrib_front0 = 0; - - if (!twoside->attrib_back1) - twoside->attrib_front1 = 0; - - /* - * We'll multiply the primitive's determinant by this sign to determine - * if the triangle is back-facing (negative). - * sign = -1 for CCW, +1 for CW - */ - twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f; - - stage->tri = twoside_tri; - stage->tri( stage, header ); -} - - -static void twoside_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->tri = twoside_first_tri; - stage->next->flush( stage->next, flags ); -} - - -static void twoside_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void twoside_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create twoside pipeline stage. - */ -struct draw_stage *draw_twoside_stage( struct draw_context *draw ) -{ - struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage); - - draw_alloc_temp_verts( &twoside->stage, 3 ); - - twoside->stage.draw = draw; - twoside->stage.next = NULL; - twoside->stage.point = twoside_point; - twoside->stage.line = twoside_line; - twoside->stage.tri = twoside_first_tri; - twoside->stage.flush = twoside_flush; - twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter; - twoside->stage.destroy = twoside_destroy; - - return &twoside->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_unfilled.c b/src/gallium/auxiliary/draw/draw_unfilled.c deleted file mode 100644 index b07860cd9e..0000000000 --- a/src/gallium/auxiliary/draw/draw_unfilled.c +++ /dev/null @@ -1,206 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \brief Drawing stage for handling glPolygonMode(line/point). - * Convert triangles to points or lines as needed. - */ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "draw_private.h" - - -struct unfilled_stage { - struct draw_stage stage; - - /** [0] = front face, [1] = back face. - * legal values: PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE, - * and PIPE_POLYGON_MODE_POINT, - */ - unsigned mode[2]; -}; - - -static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage ) -{ - return (struct unfilled_stage *)stage; -} - - - -static void point( struct draw_stage *stage, - struct vertex_header *v0 ) -{ - struct prim_header tmp; - tmp.v[0] = v0; - stage->next->point( stage->next, &tmp ); -} - -static void line( struct draw_stage *stage, - struct vertex_header *v0, - struct vertex_header *v1 ) -{ - struct prim_header tmp; - tmp.v[0] = v0; - tmp.v[1] = v1; - stage->next->line( stage->next, &tmp ); -} - - -static void points( struct draw_stage *stage, - struct prim_header *header ) -{ - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - struct vertex_header *v2 = header->v[2]; - - if (header->edgeflags & 0x1) point( stage, v0 ); - if (header->edgeflags & 0x2) point( stage, v1 ); - if (header->edgeflags & 0x4) point( stage, v2 ); -} - - -static void lines( struct draw_stage *stage, - struct prim_header *header ) -{ - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - struct vertex_header *v2 = header->v[2]; - -#if 0 - assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag); - assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag); - assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag); -#endif - - if (header->edgeflags & 0x4) line( stage, v2, v0 ); - if (header->edgeflags & 0x1) line( stage, v0, v1 ); - if (header->edgeflags & 0x2) line( stage, v1, v2 ); -} - - -/* Unfilled tri: - * - * Note edgeflags in the vertex struct is not sufficient as we will - * need to manipulate them when decomposing primitives??? - */ -static void unfilled_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct unfilled_stage *unfilled = unfilled_stage(stage); - unsigned mode = unfilled->mode[header->det >= 0.0]; - - switch (mode) { - case PIPE_POLYGON_MODE_FILL: - stage->next->tri( stage->next, header ); - break; - case PIPE_POLYGON_MODE_LINE: - lines( stage, header ); - break; - case PIPE_POLYGON_MODE_POINT: - points( stage, header ); - break; - default: - assert(0); - } -} - - -static void unfilled_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct unfilled_stage *unfilled = unfilled_stage(stage); - - unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */ - unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */ - - stage->tri = unfilled_tri; - stage->tri( stage, header ); -} - - -static void unfilled_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void unfilled_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void unfilled_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->next->flush( stage->next, flags ); - - stage->tri = unfilled_first_tri; -} - - -static void unfilled_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void unfilled_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create unfilled triangle stage. - */ -struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) -{ - struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage); - - draw_alloc_temp_verts( &unfilled->stage, 0 ); - - unfilled->stage.draw = draw; - unfilled->stage.next = NULL; - unfilled->stage.tmp = NULL; - unfilled->stage.point = unfilled_point; - unfilled->stage.line = unfilled_line; - unfilled->stage.tri = unfilled_first_tri; - unfilled->stage.flush = unfilled_flush; - unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter; - unfilled->stage.destroy = unfilled_destroy; - - return &unfilled->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c deleted file mode 100644 index e163e078f0..0000000000 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ /dev/null @@ -1,312 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "draw_private.h" - -static boolean points( unsigned prim ) -{ - return (prim == PIPE_PRIM_POINTS); -} - -static boolean lines( unsigned prim ) -{ - return (prim == PIPE_PRIM_LINES || - prim == PIPE_PRIM_LINE_STRIP || - prim == PIPE_PRIM_LINE_LOOP); -} - -static boolean triangles( unsigned prim ) -{ - return prim >= PIPE_PRIM_TRIANGLES; -} - -/** - * Check if we need any special pipeline stages, or whether - * prims/verts can go through untouched. Don't test for bypass - * clipping or vs modes, this function is just about the primitive - * pipeline stages. - */ -boolean -draw_need_pipeline(const struct draw_context *draw, - unsigned int prim ) -{ - /* Don't have to worry about triangles turning into lines/points - * and triggering the pipeline, because we have to trigger the - * pipeline *anyway* if unfilled mode is active. - */ - if (lines(prim)) - { - /* line stipple */ - if (draw->rasterizer->line_stipple_enable && draw->line_stipple) - return TRUE; - - /* wide lines */ - if (draw->rasterizer->line_width > draw->wide_line_threshold) - return TRUE; - - /* AA lines */ - if (draw->rasterizer->line_smooth && draw->pipeline.aaline) - return TRUE; - } - - if (points(prim)) - { - /* large points */ - if (draw->rasterizer->point_size > draw->wide_point_threshold) - return TRUE; - - /* AA points */ - if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) - return TRUE; - - /* point sprites */ - if (draw->rasterizer->point_sprite && draw->point_sprite) - return TRUE; - } - - - if (triangles(prim)) - { - /* polygon stipple */ - if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple) - return TRUE; - - /* unfilled polygons */ - if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) - return TRUE; - - /* polygon offset */ - if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw) - return TRUE; - - /* two-side lighting */ - if (draw->rasterizer->light_twoside) - return TRUE; - } - - /* polygon cull - this is difficult - hardware can cull just fine - * most of the time (though sometimes CULL_NEITHER is unsupported. - * - * Generally this isn't a reason to require the pipeline, though. - * - if (draw->rasterizer->cull_mode) - return TRUE; - */ - - return FALSE; -} - - - -/** - * Rebuild the rendering pipeline. - */ -static struct draw_stage *validate_pipeline( struct draw_stage *stage ) -{ - struct draw_context *draw = stage->draw; - struct draw_stage *next = draw->pipeline.rasterize; - int need_det = 0; - int precalc_flat = 0; - boolean wide_lines, wide_points; - - /* Set the validate's next stage to the rasterize stage, so that it - * can be found later if needed for flushing. - */ - stage->next = next; - - /* drawing wide lines? */ - wide_lines = (draw->rasterizer->line_width > draw->wide_line_threshold - && !draw->rasterizer->line_smooth); - - /* drawing large points? */ - if (draw->rasterizer->point_sprite && draw->point_sprite) - wide_points = TRUE; - else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) - wide_points = FALSE; - else if (draw->rasterizer->point_size > draw->wide_point_threshold) - wide_points = TRUE; - else - wide_points = FALSE; - - /* - * NOTE: we build up the pipeline in end-to-start order. - * - * TODO: make the current primitive part of the state and build - * shorter pipelines for lines & points. - */ - - if (draw->rasterizer->line_smooth && draw->pipeline.aaline) { - draw->pipeline.aaline->next = next; - next = draw->pipeline.aaline; - } - - if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) { - draw->pipeline.aapoint->next = next; - next = draw->pipeline.aapoint; - } - - if (wide_lines) { - draw->pipeline.wide_line->next = next; - next = draw->pipeline.wide_line; - precalc_flat = 1; - } - - if (wide_points || draw->rasterizer->point_sprite) { - draw->pipeline.wide_point->next = next; - next = draw->pipeline.wide_point; - } - - if (draw->rasterizer->line_stipple_enable && draw->line_stipple) { - draw->pipeline.stipple->next = next; - next = draw->pipeline.stipple; - precalc_flat = 1; /* only needed for lines really */ - } - - if (draw->rasterizer->poly_stipple_enable - && draw->pipeline.pstipple) { - draw->pipeline.pstipple->next = next; - next = draw->pipeline.pstipple; - } - - if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { - draw->pipeline.unfilled->next = next; - next = draw->pipeline.unfilled; - precalc_flat = 1; /* only needed for triangles really */ - need_det = 1; - } - - if (draw->rasterizer->flatshade && precalc_flat) { - draw->pipeline.flatshade->next = next; - next = draw->pipeline.flatshade; - } - - if (draw->rasterizer->offset_cw || - draw->rasterizer->offset_ccw) { - draw->pipeline.offset->next = next; - next = draw->pipeline.offset; - need_det = 1; - } - - if (draw->rasterizer->light_twoside) { - draw->pipeline.twoside->next = next; - next = draw->pipeline.twoside; - need_det = 1; - } - - /* Always run the cull stage as we calculate determinant there - * also. - * - * This can actually be a win as culling out the triangles can lead - * to less work emitting vertices, smaller vertex buffers, etc. - * It's difficult to say whether this will be true in general. - */ - if (need_det || draw->rasterizer->cull_mode) { - draw->pipeline.cull->next = next; - next = draw->pipeline.cull; - } - - /* Clip stage - */ - if (!draw->rasterizer->bypass_clipping) - { - draw->pipeline.clip->next = next; - next = draw->pipeline.clip; - } - - - draw->pipeline.first = next; - return next; -} - -static void validate_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->tri( pipeline, header ); -} - -static void validate_line( struct draw_stage *stage, - struct prim_header *header ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->line( pipeline, header ); -} - -static void validate_point( struct draw_stage *stage, - struct prim_header *header ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->point( pipeline, header ); -} - -static void validate_reset_stipple_counter( struct draw_stage *stage ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->reset_stipple_counter( pipeline ); -} - -static void validate_flush( struct draw_stage *stage, - unsigned flags ) -{ - /* May need to pass a backend flush on to the rasterize stage. - */ - if (stage->next) - stage->next->flush( stage->next, flags ); -} - - -static void validate_destroy( struct draw_stage *stage ) -{ - FREE( stage ); -} - - -/** - * Create validate pipeline stage. - */ -struct draw_stage *draw_validate_stage( struct draw_context *draw ) -{ - struct draw_stage *stage = CALLOC_STRUCT(draw_stage); - - stage->draw = draw; - stage->next = NULL; - stage->point = validate_point; - stage->line = validate_line; - stage->tri = validate_tri; - stage->flush = validate_flush; - stage->reset_stipple_counter = validate_reset_stipple_counter; - stage->destroy = validate_destroy; - - return stage; -} diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c deleted file mode 100644 index 30dceeb43d..0000000000 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ /dev/null @@ -1,529 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file - * Vertex buffer drawing stage. - * - * \author José Fonseca - * \author Keith Whitwell - */ - - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" - -#include "draw_vbuf.h" -#include "draw_private.h" -#include "draw_vertex.h" -#include "translate/translate.h" - - -/** - * Vertex buffer emit stage. - */ -struct vbuf_stage { - struct draw_stage stage; /**< This must be first (base class) */ - - struct vbuf_render *render; - - const struct vertex_info *vinfo; - - /** Vertex size in bytes */ - unsigned vertex_size; - - struct translate *translate; - - /* FIXME: we have no guarantee that 'unsigned' is 32bit */ - - /** Vertices in hardware format */ - unsigned *vertices; - unsigned *vertex_ptr; - unsigned max_vertices; - unsigned nr_vertices; - - /** Indices */ - ushort *indices; - unsigned max_indices; - unsigned nr_indices; - - /* Cache point size somewhere it's address won't change: - */ - float point_size; -}; - - -/** - * Basically a cast wrapper. - */ -static INLINE struct vbuf_stage * -vbuf_stage( struct draw_stage *stage ) -{ - assert(stage); - return (struct vbuf_stage *)stage; -} - - -static void vbuf_flush_indices( struct vbuf_stage *vbuf ); -static void vbuf_flush_vertices( struct vbuf_stage *vbuf ); -static void vbuf_alloc_vertices( struct vbuf_stage *vbuf ); - - -static INLINE boolean -overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz ) -{ - unsigned long used = (unsigned long) ((char *)ptr - (char *)map); - return (used + bytes) > bufsz; -} - - -static INLINE void -check_space( struct vbuf_stage *vbuf, unsigned nr ) -{ - if (vbuf->nr_vertices + nr > vbuf->max_vertices ) { - vbuf_flush_vertices(vbuf); - vbuf_alloc_vertices(vbuf); - } - - if (vbuf->nr_indices + nr > vbuf->max_indices ) - vbuf_flush_indices(vbuf); -} - - -static INLINE void -dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) -{ -// assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); - unsigned i, j; - - for (i = 0; i < vinfo->num_attribs; i++) { - j = vinfo->src_index[i]; - switch (vinfo->emit[i]) { - case EMIT_OMIT: - debug_printf("EMIT_OMIT:"); - break; - case EMIT_1F: - debug_printf("EMIT_1F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_1F_PSIZE: - debug_printf("EMIT_1F_PSIZE:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_2F: - debug_printf("EMIT_2F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_3F: - debug_printf("EMIT_3F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - data += sizeof(float); - break; - case EMIT_4F: - debug_printf("EMIT_4F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_4UB: - debug_printf("EMIT_4UB:\t"); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - break; - default: - assert(0); - } - debug_printf("\n"); - } - debug_printf("\n"); -} - - -/** - * Extract the needed fields from post-transformed vertex and emit - * a hardware(driver) vertex. - * Recall that the vertices are constructed by the 'draw' module and - * have a couple of slots at the beginning (1-dword header, 4-dword - * clip pos) that we ignore here. We only use the vertex->data[] fields. - */ -static INLINE ushort -emit_vertex( struct vbuf_stage *vbuf, - struct vertex_header *vertex ) -{ - if(vertex->vertex_id == UNDEFINED_VERTEX_ID) { - /* Hmm - vertices are emitted one at a time - better make sure - * set_buffer is efficient. Consider a special one-shot mode for - * translate. - */ - vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); - vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); - - if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); - - vbuf->vertex_ptr += vbuf->vertex_size/4; - vertex->vertex_id = vbuf->nr_vertices++; - } - - return vertex->vertex_id; -} - - -static void -vbuf_tri( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - unsigned i; - - check_space( vbuf, 3 ); - - for (i = 0; i < 3; i++) { - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); - } -} - - -static void -vbuf_line( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - unsigned i; - - check_space( vbuf, 2 ); - - for (i = 0; i < 2; i++) { - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); - } -} - - -static void -vbuf_point( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - check_space( vbuf, 1 ); - - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] ); -} - - - - -/** - * Set the prim type for subsequent vertices. - * This may result in a new vertex size. The existing vbuffer (if any) - * will be flushed if needed and a new one allocated. - */ -static void -vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) -{ - struct translate_key hw_key; - unsigned dst_offset; - unsigned i; - - vbuf->render->set_primitive(vbuf->render, prim); - - /* Must do this after set_primitive() above: - * - * XXX: need some state managment to track when this needs to be - * recalculated. The driver should tell us whether there was a - * state change. - */ - vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render); - - if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) { - vbuf_flush_vertices(vbuf); - vbuf->vertex_size = vbuf->vinfo->size * sizeof(float); - } - - /* Translate from pipeline vertices to hw vertices. - */ - dst_offset = 0; - memset(&hw_key, 0, sizeof(hw_key)); - - for (i = 0; i < vbuf->vinfo->num_attribs; i++) { - unsigned emit_sz = 0; - unsigned src_buffer = 0; - unsigned output_format; - unsigned src_offset = (vbuf->vinfo->src_index[i] * 4 * sizeof(float) ); - - switch (vbuf->vinfo->emit[i]) { - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - src_buffer = 1; - src_offset = 0; - break; - case EMIT_4UB: - output_format = PIPE_FORMAT_B8G8R8A8_UNORM; - emit_sz = 4 * sizeof(ubyte); - default: - assert(0); - output_format = PIPE_FORMAT_NONE; - emit_sz = 0; - break; - } - - hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - hw_key.element[i].input_buffer = src_buffer; - hw_key.element[i].input_offset = src_offset; - hw_key.element[i].output_format = output_format; - hw_key.element[i].output_offset = dst_offset; - - dst_offset += emit_sz; - } - - hw_key.nr_elements = vbuf->vinfo->num_attribs; - hw_key.output_stride = vbuf->vinfo->size * 4; - - /* Don't bother with caching at this stage: - */ - if (!vbuf->translate || - memcmp(&vbuf->translate->key, &hw_key, sizeof(hw_key)) != 0) - { - if (vbuf->translate) - vbuf->translate->release(vbuf->translate); - - vbuf->translate = translate_create( &hw_key ); - - vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0); - } - - vbuf->point_size = vbuf->stage.draw->rasterizer->point_size; - - /* Allocate new buffer? - */ - if (!vbuf->vertices) - vbuf_alloc_vertices(vbuf); -} - - -static void -vbuf_first_tri( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - stage->tri = vbuf_tri; - vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES); - stage->tri( stage, prim ); -} - - -static void -vbuf_first_line( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - stage->line = vbuf_line; - vbuf_set_prim(vbuf, PIPE_PRIM_LINES); - stage->line( stage, prim ); -} - - -static void -vbuf_first_point( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - stage->point = vbuf_point; - vbuf_set_prim(vbuf, PIPE_PRIM_POINTS); - stage->point( stage, prim ); -} - - -static void -vbuf_flush_indices( struct vbuf_stage *vbuf ) -{ - if(!vbuf->nr_indices) - return; - - assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == - vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned)); - - vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices); - - vbuf->nr_indices = 0; -} - - -/** - * Flush existing vertex buffer and allocate a new one. - * - * XXX: We separate flush-on-index-full and flush-on-vb-full, but may - * raise issues uploading vertices if the hardware wants to flush when - * we flush. - */ -static void -vbuf_flush_vertices( struct vbuf_stage *vbuf ) -{ - if(vbuf->vertices) { - vbuf_flush_indices(vbuf); - - /* Reset temporary vertices ids */ - if(vbuf->nr_vertices) - draw_reset_vertex_ids( vbuf->stage.draw ); - - /* Free the vertex buffer */ - vbuf->render->release_vertices(vbuf->render, - vbuf->vertices, - vbuf->vertex_size, - vbuf->nr_vertices); - vbuf->max_vertices = vbuf->nr_vertices = 0; - vbuf->vertex_ptr = vbuf->vertices = NULL; - - } -} - - -static void -vbuf_alloc_vertices( struct vbuf_stage *vbuf ) -{ - assert(!vbuf->nr_indices); - assert(!vbuf->vertices); - - /* Allocate a new vertex buffer */ - vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; - vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, - (ushort) vbuf->vertex_size, - (ushort) vbuf->max_vertices); - vbuf->vertex_ptr = vbuf->vertices; -} - - - -static void -vbuf_flush( struct draw_stage *stage, unsigned flags ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - - stage->point = vbuf_first_point; - stage->line = vbuf_first_line; - stage->tri = vbuf_first_tri; - - if (flags & DRAW_FLUSH_BACKEND) - vbuf_flush_vertices( vbuf ); -} - - -static void -vbuf_reset_stipple_counter( struct draw_stage *stage ) -{ - /* XXX: Need to do something here for hardware with linestipple. - */ - (void) stage; -} - - -static void vbuf_destroy( struct draw_stage *stage ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - if(vbuf->indices) - align_free( vbuf->indices ); - - if(vbuf->translate) - vbuf->translate->release( vbuf->translate ); - - if (vbuf->render) - vbuf->render->destroy( vbuf->render ); - - FREE( stage ); -} - - -/** - * Create a new primitive vbuf/render stage. - */ -struct draw_stage *draw_vbuf_stage( struct draw_context *draw, - struct vbuf_render *render ) -{ - struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); - - if(!vbuf) - goto fail; - - vbuf->stage.draw = draw; - vbuf->stage.point = vbuf_first_point; - vbuf->stage.line = vbuf_first_line; - vbuf->stage.tri = vbuf_first_tri; - vbuf->stage.flush = vbuf_flush; - vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter; - vbuf->stage.destroy = vbuf_destroy; - - vbuf->render = render; - vbuf->max_indices = MAX2(render->max_indices, UNDEFINED_VERTEX_ID-1); - - vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * - sizeof(vbuf->indices[0]), - 16 ); - if(!vbuf->indices) - goto fail; - - vbuf->vertices = NULL; - vbuf->vertex_ptr = vbuf->vertices; - - return &vbuf->stage; - - fail: - if (vbuf) - vbuf_destroy(&vbuf->stage); - - return NULL; -} diff --git a/src/gallium/auxiliary/draw/draw_wide_line.c b/src/gallium/auxiliary/draw/draw_wide_line.c deleted file mode 100644 index 9a168ce8bd..0000000000 --- a/src/gallium/auxiliary/draw/draw_wide_line.c +++ /dev/null @@ -1,190 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -struct wideline_stage { - struct draw_stage stage; - - float half_line_width; -}; - - - -static INLINE struct wideline_stage *wideline_stage( struct draw_stage *stage ) -{ - return (struct wideline_stage *)stage; -} - - -static void wideline_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void wideline_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Draw a wide line by drawing a quad (two triangles). - * XXX need to disable polygon stipple. - */ -static void wideline_line( struct draw_stage *stage, - struct prim_header *header ) -{ - /*const struct wideline_stage *wide = wideline_stage(stage);*/ - const float half_width = 0.5f * stage->draw->rasterizer->line_width; - - struct prim_header tri; - - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - const float dx = FABSF(pos0[0] - pos2[0]); - const float dy = FABSF(pos0[1] - pos2[1]); - - /* small tweak to meet GL specification */ - const float bias = 0.125f; - - /* - * Draw wide line as a quad (two tris) by "stretching" the line along - * X or Y. - * We need to tweak coords in several ways to be conformant here. - */ - - if (dx > dy) { - /* x-major line */ - pos0[1] = pos0[1] - half_width - bias; - pos1[1] = pos1[1] + half_width - bias; - pos2[1] = pos2[1] - half_width - bias; - pos3[1] = pos3[1] + half_width - bias; - if (pos0[0] < pos2[0]) { - /* left to right line */ - pos0[0] -= 0.5f; - pos1[0] -= 0.5f; - pos2[0] -= 0.5f; - pos3[0] -= 0.5f; - } - else { - /* right to left line */ - pos0[0] += 0.5f; - pos1[0] += 0.5f; - pos2[0] += 0.5f; - pos3[0] += 0.5f; - } - } - else { - /* y-major line */ - pos0[0] = pos0[0] - half_width + bias; - pos1[0] = pos1[0] + half_width + bias; - pos2[0] = pos2[0] - half_width + bias; - pos3[0] = pos3[0] + half_width + bias; - if (pos0[1] < pos2[1]) { - /* top to bottom line */ - pos0[1] -= 0.5f; - pos1[1] -= 0.5f; - pos2[1] -= 0.5f; - pos3[1] -= 0.5f; - } - else { - /* bottom to top line */ - pos0[1] += 0.5f; - pos1[1] += 0.5f; - pos2[1] += 0.5f; - pos3[1] += 0.5f; - } - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -static void wideline_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->next->flush( stage->next, flags ); -} - - -static void wideline_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void wideline_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -struct draw_stage *draw_wide_line_stage( struct draw_context *draw ) -{ - struct wideline_stage *wide = CALLOC_STRUCT(wideline_stage); - - draw_alloc_temp_verts( &wide->stage, 4 ); - - wide->stage.draw = draw; - wide->stage.next = NULL; - wide->stage.point = wideline_point; - wide->stage.line = wideline_line; - wide->stage.tri = wideline_tri; - wide->stage.flush = wideline_flush; - wide->stage.reset_stipple_counter = wideline_reset_stipple_counter; - wide->stage.destroy = wideline_destroy; - - return &wide->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c deleted file mode 100644 index 3d0add0c1a..0000000000 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ /dev/null @@ -1,281 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_vs.h" - - -struct widepoint_stage { - struct draw_stage stage; - - float half_point_size; - float point_size_min; - float point_size_max; - - float xbias; - float ybias; - - uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; - uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; - uint num_texcoords; - - int psize_slot; -}; - - - -static INLINE struct widepoint_stage * -widepoint_stage( struct draw_stage *stage ) -{ - return (struct widepoint_stage *)stage; -} - - -static void passthrough_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - -static void widepoint_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line(stage->next, header); -} - -static void widepoint_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Set the vertex texcoords for sprite mode. - * Coords may be left untouched or set to a right-side-up or upside-down - * orientation. - */ -static void set_texcoords(const struct widepoint_stage *wide, - struct vertex_header *v, const float tc[4]) -{ - uint i; - for (i = 0; i < wide->num_texcoords; i++) { - if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { - uint j = wide->texcoord_slot[i]; - v->data[j][0] = tc[0]; - if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) - v->data[j][1] = 1.0f - tc[1]; - else - v->data[j][1] = tc[1]; - v->data[j][2] = tc[2]; - v->data[j][3] = tc[3]; - } - } -} - - -/* If there are lots of sprite points (and why wouldn't there be?) it - * would probably be more sensible to change hardware setup to - * optimize this rather than doing the whole thing in software like - * this. - */ -static void widepoint_point( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct widepoint_stage *wide = widepoint_stage(stage); - const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; - float half_size; - float left_adj, right_adj, bot_adj, top_adj; - - struct prim_header tri; - - /* four dups of original vertex */ - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - /* point size is either per-vertex or fixed size */ - if (wide->psize_slot >= 0) { - half_size = header->v[0]->data[wide->psize_slot][0]; - - /* XXX: temporary -- do this in the vertex shader?? - */ - half_size = CLAMP(half_size, - wide->point_size_min, - wide->point_size_max); - - half_size *= 0.5f; - } - else { - half_size = wide->half_point_size; - } - - left_adj = -half_size + wide->xbias; - right_adj = half_size + wide->xbias; - bot_adj = half_size + wide->ybias; - top_adj = -half_size + wide->ybias; - - pos0[0] += left_adj; - pos0[1] += top_adj; - - pos1[0] += left_adj; - pos1[1] += bot_adj; - - pos2[0] += right_adj; - pos2[1] += top_adj; - - pos3[0] += right_adj; - pos3[1] += bot_adj; - - if (sprite) { - static const float tex00[4] = { 0, 0, 0, 1 }; - static const float tex01[4] = { 0, 1, 0, 1 }; - static const float tex11[4] = { 1, 1, 0, 1 }; - static const float tex10[4] = { 1, 0, 0, 1 }; - set_texcoords( wide, v0, tex00 ); - set_texcoords( wide, v1, tex01 ); - set_texcoords( wide, v2, tex10 ); - set_texcoords( wide, v3, tex11 ); - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -static void widepoint_first_point( struct draw_stage *stage, - struct prim_header *header ) -{ - struct widepoint_stage *wide = widepoint_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_point_size = 0.5f * draw->rasterizer->point_size; - wide->point_size_min = draw->rasterizer->point_size_min; - wide->point_size_max = draw->rasterizer->point_size_max; - wide->xbias = 0.0; - wide->ybias = 0.0; - - if (draw->rasterizer->gl_rasterization_rules) { - wide->xbias = 0.125; - } - - /* XXX we won't know the real size if it's computed by the vertex shader! */ - if ((draw->rasterizer->point_size > draw->wide_point_threshold) || - (draw->rasterizer->point_sprite && draw->point_sprite)) { - stage->point = widepoint_point; - } - else { - stage->point = passthrough_point; - } - - if (draw->rasterizer->point_sprite) { - /* find vertex shader texcoord outputs */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i, j = 0; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { - wide->texcoord_slot[j] = i; - wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; - j++; - } - } - wide->num_texcoords = j; - } - - wide->psize_slot = -1; - if (draw->rasterizer->point_size_per_vertex) { - /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { - wide->psize_slot = i; - break; - } - } - } - - stage->point( stage, header ); -} - - -static void widepoint_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->point = widepoint_first_point; - stage->next->flush( stage->next, flags ); -} - - -static void widepoint_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void widepoint_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -struct draw_stage *draw_wide_point_stage( struct draw_context *draw ) -{ - struct widepoint_stage *wide = CALLOC_STRUCT(widepoint_stage); - - draw_alloc_temp_verts( &wide->stage, 4 ); - - wide->stage.draw = draw; - wide->stage.next = NULL; - wide->stage.point = widepoint_first_point; - wide->stage.line = widepoint_line; - wide->stage.tri = widepoint_tri; - wide->stage.flush = widepoint_flush; - wide->stage.reset_stipple_counter = widepoint_reset_stipple_counter; - wide->stage.destroy = widepoint_destroy; - - return &wide->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_wide_prims.c b/src/gallium/auxiliary/draw/draw_wide_prims.c deleted file mode 100644 index d6bff110b4..0000000000 --- a/src/gallium/auxiliary/draw/draw_wide_prims.c +++ /dev/null @@ -1,366 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -struct wide_stage { - struct draw_stage stage; - - float half_line_width; - float half_point_size; - - uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; - uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; - uint num_texcoords; - - int psize_slot; -}; - - - -static INLINE struct wide_stage *wide_stage( struct draw_stage *stage ) -{ - return (struct wide_stage *)stage; -} - - -static void passthrough_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - -static void passthrough_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line(stage->next, header); -} - -static void passthrough_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Draw a wide line by drawing a quad (two triangles). - * XXX need to disable polygon stipple. - */ -static void wide_line( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct wide_stage *wide = wide_stage(stage); - const float half_width = wide->half_line_width; - - struct prim_header tri; - - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - const float dx = FABSF(pos0[0] - pos2[0]); - const float dy = FABSF(pos0[1] - pos2[1]); - - /* - * Draw wide line as a quad (two tris) by "stretching" the line along - * X or Y. - * We need to tweak coords in several ways to be conformant here. - */ - - if (dx > dy) { - /* x-major line */ - pos0[1] = pos0[1] - half_width - 0.25f; - pos1[1] = pos1[1] + half_width - 0.25f; - pos2[1] = pos2[1] - half_width - 0.25f; - pos3[1] = pos3[1] + half_width - 0.25f; - if (pos0[0] < pos2[0]) { - /* left to right line */ - pos0[0] -= 0.5f; - pos1[0] -= 0.5f; - pos2[0] -= 0.5f; - pos3[0] -= 0.5f; - } - else { - /* right to left line */ - pos0[0] += 0.5f; - pos1[0] += 0.5f; - pos2[0] += 0.5f; - pos3[0] += 0.5f; - } - } - else { - /* y-major line */ - pos0[0] = pos0[0] - half_width + 0.25f; - pos1[0] = pos1[0] + half_width + 0.25f; - pos2[0] = pos2[0] - half_width + 0.25f; - pos3[0] = pos3[0] + half_width + 0.25f; - if (pos0[1] < pos2[1]) { - /* top to bottom line */ - pos0[1] -= 0.5f; - pos1[1] -= 0.5f; - pos2[1] -= 0.5f; - pos3[1] -= 0.5f; - } - else { - /* bottom to top line */ - pos0[1] += 0.5f; - pos1[1] += 0.5f; - pos2[1] += 0.5f; - pos3[1] += 0.5f; - } - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -/** - * Set the vertex texcoords for sprite mode. - * Coords may be left untouched or set to a right-side-up or upside-down - * orientation. - */ -static void set_texcoords(const struct wide_stage *wide, - struct vertex_header *v, const float tc[4]) -{ - uint i; - for (i = 0; i < wide->num_texcoords; i++) { - if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { - uint j = wide->texcoord_slot[i]; - v->data[j][0] = tc[0]; - if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) - v->data[j][1] = 1.0f - tc[1]; - else - v->data[j][1] = tc[1]; - v->data[j][2] = tc[2]; - v->data[j][3] = tc[3]; - } - } -} - - -/* If there are lots of sprite points (and why wouldn't there be?) it - * would probably be more sensible to change hardware setup to - * optimize this rather than doing the whole thing in software like - * this. - */ -static void wide_point( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct wide_stage *wide = wide_stage(stage); - const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; - float half_size; - float left_adj, right_adj; - - struct prim_header tri; - - /* four dups of original vertex */ - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - /* point size is either per-vertex or fixed size */ - if (wide->psize_slot >= 0) { - half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; - } - else { - half_size = wide->half_point_size; - } - - left_adj = -half_size; /* + 0.25f;*/ - right_adj = half_size; /* + 0.25f;*/ - - pos0[0] += left_adj; - pos0[1] -= half_size; - - pos1[0] += left_adj; - pos1[1] += half_size; - - pos2[0] += right_adj; - pos2[1] -= half_size; - - pos3[0] += right_adj; - pos3[1] += half_size; - - if (sprite) { - static const float tex00[4] = { 0, 0, 0, 1 }; - static const float tex01[4] = { 0, 1, 0, 1 }; - static const float tex11[4] = { 1, 1, 0, 1 }; - static const float tex10[4] = { 1, 0, 0, 1 }; - set_texcoords( wide, v0, tex00 ); - set_texcoords( wide, v1, tex01 ); - set_texcoords( wide, v2, tex10 ); - set_texcoords( wide, v3, tex11 ); - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -static void wide_first_point( struct draw_stage *stage, - struct prim_header *header ) -{ - struct wide_stage *wide = wide_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_point_size = 0.5f * draw->rasterizer->point_size; - - /* XXX we won't know the real size if it's computed by the vertex shader! */ - if (draw->rasterizer->point_size > draw->wide_point_threshold) { - stage->point = wide_point; - } - else { - stage->point = passthrough_point; - } - - if (draw->rasterizer->point_sprite) { - /* find vertex shader texcoord outputs */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i, j = 0; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { - wide->texcoord_slot[j] = i; - wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; - j++; - } - } - wide->num_texcoords = j; - } - - wide->psize_slot = -1; - - if (draw->rasterizer->point_size_per_vertex) { - /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { - wide->psize_slot = i; - break; - } - } - } - - stage->point( stage, header ); -} - - - -static void wide_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - struct wide_stage *wide = wide_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_line_width = 0.5f * draw->rasterizer->line_width; - - if (draw->rasterizer->line_width != 1.0) { - wide->stage.line = wide_line; - } - else { - wide->stage.line = passthrough_line; - } - - stage->line( stage, header ); -} - - -static void wide_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->line = wide_first_line; - stage->point = wide_first_point; - stage->next->flush( stage->next, flags ); -} - - -static void wide_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void wide_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -struct draw_stage *draw_wide_stage( struct draw_context *draw ) -{ - struct wide_stage *wide = CALLOC_STRUCT(wide_stage); - - draw_alloc_temp_verts( &wide->stage, 4 ); - - wide->stage.draw = draw; - wide->stage.next = NULL; - wide->stage.point = wide_first_point; - wide->stage.line = wide_first_line; - wide->stage.tri = passthrough_tri; - wide->stage.flush = wide_flush; - wide->stage.reset_stipple_counter = wide_reset_stipple_counter; - wide->stage.destroy = wide_destroy; - - return &wide->stage; -} -- cgit v1.2.3 From 882e5d84dcb19c24b7b56cfe6049810023f3a17e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 13:12:07 +0100 Subject: draw: remove dead code --- src/gallium/auxiliary/draw/draw_vs.h | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index b6f3bbdaea..f9772b83b8 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -81,33 +81,6 @@ draw_create_vs_llvm(struct draw_context *draw, const struct pipe_shader_state *templ); -/* Should be part of the generated shader: - */ -static INLINE unsigned -compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) -{ - unsigned mask = 0x0; - unsigned i; - - /* Do the hardwired planes first: - */ - if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; - if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; - if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; - if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; - if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; - if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; - - /* Followed by any remaining ones: - */ - for (i = 6; i < nr; i++) { - if (dot4(clip, plane[i]) < 0) - mask |= (1< Date: Sat, 19 Apr 2008 13:20:26 +0100 Subject: draw: remove named clipmask flags, tidy up pt middle ends --- src/gallium/auxiliary/draw/draw_context.h | 37 +++------------------------- src/gallium/auxiliary/draw/draw_private.h | 9 ++----- src/gallium/auxiliary/draw/draw_pt.c | 36 +++++++++++++-------------- src/gallium/auxiliary/draw/draw_pt.h | 6 +++++ src/gallium/auxiliary/draw/draw_pt_post_vs.c | 12 ++++----- 5 files changed, 35 insertions(+), 65 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index c7ac32b452..a0ac980c89 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -42,37 +42,11 @@ struct pipe_context; -struct vertex_buffer; -struct vertex_info; struct draw_context; struct draw_stage; struct draw_vertex_shader; -/** - * Clipmask flags - */ -/*@{*/ -#define CLIP_RIGHT_BIT 0x01 -#define CLIP_LEFT_BIT 0x02 -#define CLIP_TOP_BIT 0x04 -#define CLIP_BOTTOM_BIT 0x08 -#define CLIP_NEAR_BIT 0x10 -#define CLIP_FAR_BIT 0x20 -/*@}*/ - -/** - * Bitshift for each clip flag - */ -/*@{*/ -#define CLIP_RIGHT_SHIFT 0 -#define CLIP_LEFT_SHIFT 1 -#define CLIP_TOP_SHIFT 2 -#define CLIP_BOTTOM_SHIFT 3 -#define CLIP_NEAR_SHIFT 4 -#define CLIP_FAR_SHIFT 5 -/*@}*/ - struct draw_context *draw_create( void ); @@ -168,15 +142,10 @@ void draw_arrays(struct draw_context *draw, unsigned prim, void draw_flush(struct draw_context *draw); -/*********************************************************************** - * draw_debug.c - */ -boolean draw_validate_prim( unsigned prim, unsigned length ); -unsigned draw_trim_prim( unsigned mode, unsigned count ); - - - +/******************************************************************************* + * Driver backend interface + */ struct vbuf_render; void draw_set_render( struct draw_context *draw, struct vbuf_render *render ); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 476b1184d4..37ffdbf902 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -44,7 +44,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "rtasm/rtasm_x86sse.h" #include "tgsi/exec/tgsi_exec.h" #include "tgsi/util/tgsi_scan.h" @@ -171,7 +170,8 @@ struct draw_context */ struct { struct { - struct draw_pt_middle_end *opt[PT_MAX_MIDDLE]; + struct draw_pt_middle_end *fetch_emit; + struct draw_pt_middle_end *general; } middle; struct { @@ -289,11 +289,6 @@ extern boolean draw_need_pipeline(const struct draw_context *draw, */ boolean draw_pt_init( struct draw_context *draw ); void draw_pt_destroy( struct draw_context *draw ); -boolean draw_pt_arrays( struct draw_context *draw, - unsigned prim, - unsigned start, - unsigned count ); - void draw_pt_reset_vertex_ids( struct draw_context *draw ); #define DRAW_FLUSH_STATE_CHANGE 0x8 diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index ecaed84070..f153a3ee2c 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -44,7 +44,7 @@ * - pipeline -- the prim pipeline: clipping, wide lines, etc * - backend -- the vbuf_render provided by the driver. */ -boolean +static boolean draw_pt_arrays(struct draw_context *draw, unsigned prim, unsigned start, @@ -70,19 +70,16 @@ draw_pt_arrays(struct draw_context *draw, opt |= PT_SHADE; } + if (opt) + middle = draw->pt.middle.general; + else + middle = draw->pt.middle.fetch_emit; - middle = draw->pt.middle.opt[opt]; - if (middle == NULL) { - middle = draw->pt.middle.opt[PT_PIPELINE | PT_CLIPTEST | PT_SHADE]; - } - - assert(middle); /* May create a short-circuited version of this for small primitives: */ frontend = draw->pt.front.vcache; - frontend->prepare( frontend, prim, middle, opt ); frontend->run( frontend, @@ -102,11 +99,12 @@ boolean draw_pt_init( struct draw_context *draw ) if (!draw->pt.front.vcache) return FALSE; - draw->pt.middle.opt[0] = draw_pt_fetch_emit( draw ); - draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE] = - draw_pt_fetch_pipeline_or_emit( draw ); + draw->pt.middle.fetch_emit = draw_pt_fetch_emit( draw ); + if (!draw->pt.middle.fetch_emit) + return FALSE; - if (!draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE]) + draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit( draw ); + if (!draw->pt.middle.general) return FALSE; return TRUE; @@ -115,13 +113,15 @@ boolean draw_pt_init( struct draw_context *draw ) void draw_pt_destroy( struct draw_context *draw ) { - int i; + if (draw->pt.middle.general) { + draw->pt.middle.general->destroy( draw->pt.middle.general ); + draw->pt.middle.general = NULL; + } - for (i = 0; i < PT_MAX_MIDDLE; i++) - if (draw->pt.middle.opt[i]) { - draw->pt.middle.opt[i]->destroy( draw->pt.middle.opt[i] ); - draw->pt.middle.opt[i] = NULL; - } + if (draw->pt.middle.fetch_emit) { + draw->pt.middle.fetch_emit->destroy( draw->pt.middle.fetch_emit ); + draw->pt.middle.fetch_emit = NULL; + } if (draw->pt.front.vcache) { draw->pt.front.vcache->destroy( draw->pt.front.vcache ); diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index eb23ee1c1e..1119e9c6b8 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -50,6 +50,12 @@ struct draw_context; #define DRAW_PT_FLAG_MASK (3<<30) +#define PT_SHADE 0x1 +#define PT_CLIPTEST 0x2 +#define PT_PIPELINE 0x4 +#define PT_MAX_MIDDLE 0x8 + + /* The "front end" - prepare sets of fetch, draw elements for the * middle end. * diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index 315b02f4ee..b3ecec6ece 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -52,12 +52,12 @@ compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr) /* Do the hardwired planes first: */ - if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; - if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; - if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; - if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; - if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; - if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; + if (-clip[0] + clip[3] < 0) mask |= (1<<0); + if ( clip[0] + clip[3] < 0) mask |= (1<<1); + if (-clip[1] + clip[3] < 0) mask |= (1<<2); + if ( clip[1] + clip[3] < 0) mask |= (1<<3); + if ( clip[2] + clip[3] < 0) mask |= (1<<4); /* match mesa clipplane numbering - for now */ + if (-clip[2] + clip[3] < 0) mask |= (1<<5); /* match mesa clipplane numbering - for now */ /* Followed by any remaining ones: */ -- cgit v1.2.3 From 0959f909ba585968f0408e78961e1c0ffc69a9f8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 13:30:19 +0100 Subject: draw: remove dead file pipe_wide_prims.c --- src/gallium/auxiliary/draw/draw_pipe_wide_prims.c | 366 ---------------------- 1 file changed, 366 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_pipe_wide_prims.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c b/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c deleted file mode 100644 index d6bff110b4..0000000000 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c +++ /dev/null @@ -1,366 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -struct wide_stage { - struct draw_stage stage; - - float half_line_width; - float half_point_size; - - uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; - uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; - uint num_texcoords; - - int psize_slot; -}; - - - -static INLINE struct wide_stage *wide_stage( struct draw_stage *stage ) -{ - return (struct wide_stage *)stage; -} - - -static void passthrough_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - -static void passthrough_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line(stage->next, header); -} - -static void passthrough_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Draw a wide line by drawing a quad (two triangles). - * XXX need to disable polygon stipple. - */ -static void wide_line( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct wide_stage *wide = wide_stage(stage); - const float half_width = wide->half_line_width; - - struct prim_header tri; - - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - const float dx = FABSF(pos0[0] - pos2[0]); - const float dy = FABSF(pos0[1] - pos2[1]); - - /* - * Draw wide line as a quad (two tris) by "stretching" the line along - * X or Y. - * We need to tweak coords in several ways to be conformant here. - */ - - if (dx > dy) { - /* x-major line */ - pos0[1] = pos0[1] - half_width - 0.25f; - pos1[1] = pos1[1] + half_width - 0.25f; - pos2[1] = pos2[1] - half_width - 0.25f; - pos3[1] = pos3[1] + half_width - 0.25f; - if (pos0[0] < pos2[0]) { - /* left to right line */ - pos0[0] -= 0.5f; - pos1[0] -= 0.5f; - pos2[0] -= 0.5f; - pos3[0] -= 0.5f; - } - else { - /* right to left line */ - pos0[0] += 0.5f; - pos1[0] += 0.5f; - pos2[0] += 0.5f; - pos3[0] += 0.5f; - } - } - else { - /* y-major line */ - pos0[0] = pos0[0] - half_width + 0.25f; - pos1[0] = pos1[0] + half_width + 0.25f; - pos2[0] = pos2[0] - half_width + 0.25f; - pos3[0] = pos3[0] + half_width + 0.25f; - if (pos0[1] < pos2[1]) { - /* top to bottom line */ - pos0[1] -= 0.5f; - pos1[1] -= 0.5f; - pos2[1] -= 0.5f; - pos3[1] -= 0.5f; - } - else { - /* bottom to top line */ - pos0[1] += 0.5f; - pos1[1] += 0.5f; - pos2[1] += 0.5f; - pos3[1] += 0.5f; - } - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -/** - * Set the vertex texcoords for sprite mode. - * Coords may be left untouched or set to a right-side-up or upside-down - * orientation. - */ -static void set_texcoords(const struct wide_stage *wide, - struct vertex_header *v, const float tc[4]) -{ - uint i; - for (i = 0; i < wide->num_texcoords; i++) { - if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { - uint j = wide->texcoord_slot[i]; - v->data[j][0] = tc[0]; - if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) - v->data[j][1] = 1.0f - tc[1]; - else - v->data[j][1] = tc[1]; - v->data[j][2] = tc[2]; - v->data[j][3] = tc[3]; - } - } -} - - -/* If there are lots of sprite points (and why wouldn't there be?) it - * would probably be more sensible to change hardware setup to - * optimize this rather than doing the whole thing in software like - * this. - */ -static void wide_point( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct wide_stage *wide = wide_stage(stage); - const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; - float half_size; - float left_adj, right_adj; - - struct prim_header tri; - - /* four dups of original vertex */ - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - /* point size is either per-vertex or fixed size */ - if (wide->psize_slot >= 0) { - half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; - } - else { - half_size = wide->half_point_size; - } - - left_adj = -half_size; /* + 0.25f;*/ - right_adj = half_size; /* + 0.25f;*/ - - pos0[0] += left_adj; - pos0[1] -= half_size; - - pos1[0] += left_adj; - pos1[1] += half_size; - - pos2[0] += right_adj; - pos2[1] -= half_size; - - pos3[0] += right_adj; - pos3[1] += half_size; - - if (sprite) { - static const float tex00[4] = { 0, 0, 0, 1 }; - static const float tex01[4] = { 0, 1, 0, 1 }; - static const float tex11[4] = { 1, 1, 0, 1 }; - static const float tex10[4] = { 1, 0, 0, 1 }; - set_texcoords( wide, v0, tex00 ); - set_texcoords( wide, v1, tex01 ); - set_texcoords( wide, v2, tex10 ); - set_texcoords( wide, v3, tex11 ); - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -static void wide_first_point( struct draw_stage *stage, - struct prim_header *header ) -{ - struct wide_stage *wide = wide_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_point_size = 0.5f * draw->rasterizer->point_size; - - /* XXX we won't know the real size if it's computed by the vertex shader! */ - if (draw->rasterizer->point_size > draw->wide_point_threshold) { - stage->point = wide_point; - } - else { - stage->point = passthrough_point; - } - - if (draw->rasterizer->point_sprite) { - /* find vertex shader texcoord outputs */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i, j = 0; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { - wide->texcoord_slot[j] = i; - wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; - j++; - } - } - wide->num_texcoords = j; - } - - wide->psize_slot = -1; - - if (draw->rasterizer->point_size_per_vertex) { - /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { - wide->psize_slot = i; - break; - } - } - } - - stage->point( stage, header ); -} - - - -static void wide_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - struct wide_stage *wide = wide_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_line_width = 0.5f * draw->rasterizer->line_width; - - if (draw->rasterizer->line_width != 1.0) { - wide->stage.line = wide_line; - } - else { - wide->stage.line = passthrough_line; - } - - stage->line( stage, header ); -} - - -static void wide_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->line = wide_first_line; - stage->point = wide_first_point; - stage->next->flush( stage->next, flags ); -} - - -static void wide_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void wide_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -struct draw_stage *draw_wide_stage( struct draw_context *draw ) -{ - struct wide_stage *wide = CALLOC_STRUCT(wide_stage); - - draw_alloc_temp_verts( &wide->stage, 4 ); - - wide->stage.draw = draw; - wide->stage.next = NULL; - wide->stage.point = wide_first_point; - wide->stage.line = wide_first_line; - wide->stage.tri = passthrough_tri; - wide->stage.flush = wide_flush; - wide->stage.reset_stipple_counter = wide_reset_stipple_counter; - wide->stage.destroy = wide_destroy; - - return &wide->stage; -} -- cgit v1.2.3 From 507fbe2d327efb8d608ce8e07436b97321560808 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 15:29:27 +0100 Subject: draw: move some pipeline-specific code & state to draw_pipe.[ch] --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_context.c | 141 +++++-------------- src/gallium/auxiliary/draw/draw_pipe.c | 161 ++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pipe.h | 110 +++++++++++++++ src/gallium/auxiliary/draw/draw_pipe_aaline.c | 1 + src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 1 + src/gallium/auxiliary/draw/draw_pipe_clip.c | 11 +- src/gallium/auxiliary/draw/draw_pipe_cull.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 1 + src/gallium/auxiliary/draw/draw_pipe_offset.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_stipple.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_twoside.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 1 + src/gallium/auxiliary/draw/draw_pipe_validate.c | 17 +-- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 1 + src/gallium/auxiliary/draw/draw_pipe_wide_line.c | 1 + src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 5 +- src/gallium/auxiliary/draw/draw_private.h | 132 ++++-------------- src/gallium/auxiliary/draw/draw_pt.c | 18 --- src/gallium/auxiliary/draw/draw_pt_pipeline.c | 1 + src/gallium/auxiliary/draw/draw_pt_post_vs.c | 11 ++ src/gallium/auxiliary/draw/draw_vertex.c | 2 - src/gallium/drivers/i915simple/i915_context.c | 2 +- src/gallium/drivers/i915simple/i915_prim_emit.c | 5 +- src/gallium/drivers/softpipe/sp_prim_setup.c | 2 +- 26 files changed, 375 insertions(+), 260 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pipe.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 62f46c6db1..4fffd11b77 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -5,6 +5,7 @@ LIBNAME = draw C_SOURCES = \ draw_context.c \ + draw_pipe.c \ draw_pipe_aaline.c \ draw_pipe_aapoint.c \ draw_pipe_clip.c \ diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 6012bc155e..fa6791fa0b 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -35,6 +35,8 @@ #include "draw_context.h" #include "draw_vbuf.h" #include "draw_vs.h" +#include "draw_pt.h" +#include "draw_pipe.h" struct draw_context *draw_create( void ) @@ -49,32 +51,6 @@ struct draw_context *draw_create( void ) draw->use_sse = FALSE; #endif - /* create pipeline stages */ - draw->pipeline.wide_line = draw_wide_line_stage( draw ); - draw->pipeline.wide_point = draw_wide_point_stage( draw ); - draw->pipeline.stipple = draw_stipple_stage( draw ); - draw->pipeline.unfilled = draw_unfilled_stage( draw ); - draw->pipeline.twoside = draw_twoside_stage( draw ); - draw->pipeline.offset = draw_offset_stage( draw ); - draw->pipeline.clip = draw_clip_stage( draw ); - draw->pipeline.flatshade = draw_flatshade_stage( draw ); - draw->pipeline.cull = draw_cull_stage( draw ); - draw->pipeline.validate = draw_validate_stage( draw ); - draw->pipeline.first = draw->pipeline.validate; - - if (!draw->pipeline.wide_line || - !draw->pipeline.wide_point || - !draw->pipeline.stipple || - !draw->pipeline.unfilled || - !draw->pipeline.twoside || - !draw->pipeline.offset || - !draw->pipeline.clip || - !draw->pipeline.flatshade || - !draw->pipeline.cull || - !draw->pipeline.validate) - goto fail; - - 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 ); @@ -83,11 +59,6 @@ struct draw_context *draw_create( void ) ASSIGN_4V( draw->plane[5], 0, 0, -1, 1 ); /* mesa's a bit wonky */ draw->nr_planes = 6; - /* these defaults are oriented toward the needs of softpipe */ - draw->wide_point_threshold = 1000000.0; /* infinity */ - draw->wide_line_threshold = 1.0; - draw->line_stipple = TRUE; - draw->point_sprite = TRUE; draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ @@ -100,6 +71,8 @@ struct draw_context *draw_create( void ) draw->machine.Inputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); draw->machine.Outputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); + if (!draw_pipeline_init( draw )) + goto fail; if (!draw_pt_init( draw )) goto fail; @@ -117,39 +90,13 @@ void draw_destroy( struct draw_context *draw ) if (!draw) return; - if (draw->pipeline.wide_line) - draw->pipeline.wide_line->destroy( draw->pipeline.wide_line ); - if (draw->pipeline.wide_point) - draw->pipeline.wide_point->destroy( draw->pipeline.wide_point ); - if (draw->pipeline.stipple) - draw->pipeline.stipple->destroy( draw->pipeline.stipple ); - if (draw->pipeline.unfilled) - draw->pipeline.unfilled->destroy( draw->pipeline.unfilled ); - if (draw->pipeline.twoside) - draw->pipeline.twoside->destroy( draw->pipeline.twoside ); - if (draw->pipeline.offset) - draw->pipeline.offset->destroy( draw->pipeline.offset ); - if (draw->pipeline.clip) - draw->pipeline.clip->destroy( draw->pipeline.clip ); - if (draw->pipeline.flatshade) - draw->pipeline.flatshade->destroy( draw->pipeline.flatshade ); - if (draw->pipeline.cull) - draw->pipeline.cull->destroy( draw->pipeline.cull ); - if (draw->pipeline.validate) - draw->pipeline.validate->destroy( draw->pipeline.validate ); - if (draw->pipeline.aaline) - draw->pipeline.aaline->destroy( draw->pipeline.aaline ); - if (draw->pipeline.aapoint) - draw->pipeline.aapoint->destroy( draw->pipeline.aapoint ); - if (draw->pipeline.pstipple) - draw->pipeline.pstipple->destroy( draw->pipeline.pstipple ); - if (draw->pipeline.rasterize) - draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); if (draw->machine.Inputs) align_free(draw->machine.Inputs); + if (draw->machine.Outputs) align_free(draw->machine.Outputs); + tgsi_exec_machine_free_data(&draw->machine); /* Not so fast -- we're just borrowing this at the moment. @@ -158,6 +105,7 @@ void draw_destroy( struct draw_context *draw ) draw->render->destroy( draw->render ); */ + draw_pipeline_destroy( draw ); draw_pt_destroy( draw ); FREE( draw ); @@ -284,7 +232,7 @@ void draw_wide_point_threshold(struct draw_context *draw, float threshold) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->wide_point_threshold = threshold; + draw->pipeline.wide_point_threshold = threshold; } @@ -296,7 +244,7 @@ void draw_wide_line_threshold(struct draw_context *draw, float threshold) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->wide_line_threshold = threshold; + draw->pipeline.wide_line_threshold = threshold; } @@ -307,7 +255,7 @@ void draw_enable_line_stipple(struct draw_context *draw, boolean enable) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->line_stipple = enable; + draw->pipeline.line_stipple = enable; } @@ -318,7 +266,7 @@ void draw_enable_point_sprites(struct draw_context *draw, boolean enable) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->point_sprite = enable; + draw->pipeline.point_sprite = enable; } @@ -373,36 +321,6 @@ draw_num_vs_outputs(struct draw_context *draw) } -/** - * Allocate space for temporary post-transform vertices, such as for clipping. - */ -void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) -{ - assert(!stage->tmp); - - stage->nr_tmps = nr; - - if (nr) { - ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); - unsigned i; - - stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); - - for (i = 0; i < nr; i++) - stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); - } -} - - -void draw_free_temp_verts( struct draw_stage *stage ) -{ - if (stage->tmp) { - FREE( stage->tmp[0] ); - FREE( stage->tmp ); - stage->tmp = NULL; - } -} - boolean draw_use_sse(struct draw_context *draw) { @@ -410,23 +328,6 @@ boolean draw_use_sse(struct draw_context *draw) } -void draw_reset_vertex_ids(struct draw_context *draw) -{ - struct draw_stage *stage = draw->pipeline.first; - - while (stage) { - unsigned i; - - for (i = 0; i < stage->nr_tmps; i++) - stage->tmp[i]->vertex_id = UNDEFINED_VERTEX_ID; - - stage = stage->next; - } - - draw_pt_reset_vertex_ids(draw); -} - - void draw_set_render( struct draw_context *draw, struct vbuf_render *render ) { @@ -467,3 +368,23 @@ draw_set_mapped_element_buffer( struct draw_context *draw, draw->user.elts = elements; draw->user.eltSize = eltSize; } + + + +/* Revamp me please: + */ +void draw_do_flush( struct draw_context *draw, unsigned flags ) +{ + if (!draw->flushing) + { + draw->flushing = TRUE; + + if (flags >= DRAW_FLUSH_STATE_CHANGE) { + draw->pipeline.first->flush( draw->pipeline.first, flags ); + draw->pipeline.first = draw->pipeline.validate; + draw->reduced_prim = ~0; /* is reduced_prim needed any more? */ + } + + draw->flushing = FALSE; + } +} diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c new file mode 100644 index 0000000000..9d62cb2c65 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -0,0 +1,161 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw/draw_private.h" +#include "draw/draw_pipe.h" + + +boolean draw_pipeline_init( struct draw_context *draw ) +{ + /* create pipeline stages */ + draw->pipeline.wide_line = draw_wide_line_stage( draw ); + draw->pipeline.wide_point = draw_wide_point_stage( draw ); + draw->pipeline.stipple = draw_stipple_stage( draw ); + draw->pipeline.unfilled = draw_unfilled_stage( draw ); + draw->pipeline.twoside = draw_twoside_stage( draw ); + draw->pipeline.offset = draw_offset_stage( draw ); + draw->pipeline.clip = draw_clip_stage( draw ); + draw->pipeline.flatshade = draw_flatshade_stage( draw ); + draw->pipeline.cull = draw_cull_stage( draw ); + draw->pipeline.validate = draw_validate_stage( draw ); + draw->pipeline.first = draw->pipeline.validate; + + if (!draw->pipeline.wide_line || + !draw->pipeline.wide_point || + !draw->pipeline.stipple || + !draw->pipeline.unfilled || + !draw->pipeline.twoside || + !draw->pipeline.offset || + !draw->pipeline.clip || + !draw->pipeline.flatshade || + !draw->pipeline.cull || + !draw->pipeline.validate) + return FALSE; + + /* these defaults are oriented toward the needs of softpipe */ + draw->pipeline.wide_point_threshold = 1000000.0; /* infinity */ + draw->pipeline.wide_line_threshold = 1.0; + draw->pipeline.line_stipple = TRUE; + draw->pipeline.point_sprite = TRUE; + + return TRUE; +} + + +void draw_pipeline_destroy( struct draw_context *draw ) +{ + if (draw->pipeline.wide_line) + draw->pipeline.wide_line->destroy( draw->pipeline.wide_line ); + if (draw->pipeline.wide_point) + draw->pipeline.wide_point->destroy( draw->pipeline.wide_point ); + if (draw->pipeline.stipple) + draw->pipeline.stipple->destroy( draw->pipeline.stipple ); + if (draw->pipeline.unfilled) + draw->pipeline.unfilled->destroy( draw->pipeline.unfilled ); + if (draw->pipeline.twoside) + draw->pipeline.twoside->destroy( draw->pipeline.twoside ); + if (draw->pipeline.offset) + draw->pipeline.offset->destroy( draw->pipeline.offset ); + if (draw->pipeline.clip) + draw->pipeline.clip->destroy( draw->pipeline.clip ); + if (draw->pipeline.flatshade) + draw->pipeline.flatshade->destroy( draw->pipeline.flatshade ); + if (draw->pipeline.cull) + draw->pipeline.cull->destroy( draw->pipeline.cull ); + if (draw->pipeline.validate) + draw->pipeline.validate->destroy( draw->pipeline.validate ); + if (draw->pipeline.aaline) + draw->pipeline.aaline->destroy( draw->pipeline.aaline ); + if (draw->pipeline.aapoint) + draw->pipeline.aapoint->destroy( draw->pipeline.aapoint ); + if (draw->pipeline.pstipple) + draw->pipeline.pstipple->destroy( draw->pipeline.pstipple ); + if (draw->pipeline.rasterize) + draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); +} + + + + +/* This is only used for temporary verts. + */ +#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) + + +/** + * Allocate space for temporary post-transform vertices, such as for clipping. + */ +void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) +{ + assert(!stage->tmp); + + stage->nr_tmps = nr; + + if (nr) { + ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); + unsigned i; + + stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); + + for (i = 0; i < nr; i++) + stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + } +} + + +void draw_free_temp_verts( struct draw_stage *stage ) +{ + if (stage->tmp) { + FREE( stage->tmp[0] ); + FREE( stage->tmp ); + stage->tmp = NULL; + } +} + +void draw_reset_vertex_ids(struct draw_context *draw) +{ + struct draw_stage *stage = draw->pipeline.first; + + while (stage) { + unsigned i; + + for (i = 0; i < stage->nr_tmps; i++) + stage->tmp[i]->vertex_id = UNDEFINED_VERTEX_ID; + + stage = stage->next; + } + + draw_pt_reset_vertex_ids(draw); +} + + diff --git a/src/gallium/auxiliary/draw/draw_pipe.h b/src/gallium/auxiliary/draw/draw_pipe.h new file mode 100644 index 0000000000..5b97ca5c8c --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe.h @@ -0,0 +1,110 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#ifndef DRAW_PIPE_H +#define DRAW_PIPE_H + +#include "pipe/p_compiler.h" +#include "draw_private.h" /* for sizeof(vertex_header) */ + + + +/** + * Base class for all primitive drawing stages. + */ +struct draw_stage +{ + struct draw_context *draw; /**< parent context */ + + struct draw_stage *next; /**< next stage in pipeline */ + + struct vertex_header **tmp; /**< temp vert storage, such as for clipping */ + unsigned nr_tmps; + + void (*point)( struct draw_stage *, + struct prim_header * ); + + void (*line)( struct draw_stage *, + struct prim_header * ); + + void (*tri)( struct draw_stage *, + struct prim_header * ); + + void (*flush)( struct draw_stage *, + unsigned flags ); + + void (*reset_stipple_counter)( struct draw_stage * ); + + void (*destroy)( struct draw_stage * ); +}; + + +extern struct draw_stage *draw_unfilled_stage( struct draw_context *context ); +extern struct draw_stage *draw_twoside_stage( struct draw_context *context ); +extern struct draw_stage *draw_offset_stage( struct draw_context *context ); +extern struct draw_stage *draw_clip_stage( struct draw_context *context ); +extern struct draw_stage *draw_flatshade_stage( struct draw_context *context ); +extern struct draw_stage *draw_cull_stage( struct draw_context *context ); +extern struct draw_stage *draw_stipple_stage( struct draw_context *context ); +extern struct draw_stage *draw_wide_line_stage( struct draw_context *context ); +extern struct draw_stage *draw_wide_point_stage( struct draw_context *context ); +extern struct draw_stage *draw_validate_stage( struct draw_context *context ); + + +extern void draw_free_temp_verts( struct draw_stage *stage ); + +extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); + + + + +/** + * Get a writeable copy of a vertex. + * \param stage drawing stage info + * \param vert the vertex to copy (source) + * \param idx index into stage's tmp[] array to put the copy (dest) + * \return pointer to the copied vertex + */ +static INLINE struct vertex_header * +dup_vert( struct draw_stage *stage, + const struct vertex_header *vert, + unsigned idx ) +{ + struct vertex_header *tmp = stage->tmp[idx]; + const uint vsize = sizeof(struct vertex_header) + + stage->draw->num_vs_outputs * 4 * sizeof(float); + memcpy(tmp, vert, vsize); + tmp->vertex_id = UNDEFINED_VERTEX_ID; + return tmp; +} + +#endif diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index e8d2a45102..24bc87d4f8 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -43,6 +43,7 @@ #include "draw_context.h" #include "draw_private.h" +#include "draw_pipe.h" /** diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index e84d380e50..9f878f6c02 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -49,6 +49,7 @@ #include "draw_context.h" #include "draw_vs.h" +#include "draw_pipe.h" /* diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 0ac3a240e5..6780f275d9 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -35,8 +35,8 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "draw_context.h" #include "draw_vs.h" +#include "draw_pipe.h" #ifndef IS_NEGATIVE @@ -204,7 +204,14 @@ static void emit_poly( struct draw_stage *stage, } } - +static INLINE float +dot4(const float *a, const float *b) +{ + return (a[0]*b[0] + + a[1]*b[1] + + a[2]*b[2] + + a[3]*b[3]); +} /* Clip a triangle against the viewport and user clip planes. diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c index 8177b0ac86..c406f89d05 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_cull.c +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -35,7 +35,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" -#include "draw_private.h" +#include "draw_pipe.h" struct cull_stage { diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c index 54baa1fbc9..bdb8b49dc4 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -31,6 +31,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "draw_vs.h" +#include "draw_pipe.h" /** subclass of draw_stage */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index dbc676deae..dbdece45bb 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -33,7 +33,7 @@ */ #include "pipe/p_util.h" -#include "draw_private.h" +#include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 4dddb72906..4903ba2133 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -44,7 +44,7 @@ #include "tgsi/util/tgsi_dump.h" #include "draw_context.h" -#include "draw_private.h" +#include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c index 506f33512c..49429ee9e1 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c @@ -39,7 +39,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "draw_private.h" +#include "draw_pipe.h" /** Subclass of draw_stage */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c index 01d905c153..09a9d23d57 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -32,7 +32,7 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" #include "draw_vs.h" - +#include "draw_pipe.h" struct twoside_stage { struct draw_stage stage; diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c index b07860cd9e..31e24f6a14 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -36,6 +36,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" #include "draw_private.h" +#include "draw_pipe.h" struct unfilled_stage { diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c index e163e078f0..ffddc2f62c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_validate.c +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -31,6 +31,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" #include "draw_private.h" +#include "draw_pipe.h" static boolean points( unsigned prim ) { @@ -66,11 +67,11 @@ draw_need_pipeline(const struct draw_context *draw, if (lines(prim)) { /* line stipple */ - if (draw->rasterizer->line_stipple_enable && draw->line_stipple) + if (draw->rasterizer->line_stipple_enable && draw->pipeline.line_stipple) return TRUE; /* wide lines */ - if (draw->rasterizer->line_width > draw->wide_line_threshold) + if (draw->rasterizer->line_width > draw->pipeline.wide_line_threshold) return TRUE; /* AA lines */ @@ -81,7 +82,7 @@ draw_need_pipeline(const struct draw_context *draw, if (points(prim)) { /* large points */ - if (draw->rasterizer->point_size > draw->wide_point_threshold) + if (draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) return TRUE; /* AA points */ @@ -89,7 +90,7 @@ draw_need_pipeline(const struct draw_context *draw, return TRUE; /* point sprites */ - if (draw->rasterizer->point_sprite && draw->point_sprite) + if (draw->rasterizer->point_sprite && draw->pipeline.point_sprite) return TRUE; } @@ -145,15 +146,15 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) stage->next = next; /* drawing wide lines? */ - wide_lines = (draw->rasterizer->line_width > draw->wide_line_threshold + wide_lines = (draw->rasterizer->line_width > draw->pipeline.wide_line_threshold && !draw->rasterizer->line_smooth); /* drawing large points? */ - if (draw->rasterizer->point_sprite && draw->point_sprite) + if (draw->rasterizer->point_sprite && draw->pipeline.point_sprite) wide_points = TRUE; else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) wide_points = FALSE; - else if (draw->rasterizer->point_size > draw->wide_point_threshold) + else if (draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) wide_points = TRUE; else wide_points = FALSE; @@ -186,7 +187,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) next = draw->pipeline.wide_point; } - if (draw->rasterizer->line_stipple_enable && draw->line_stipple) { + if (draw->rasterizer->line_stipple_enable && draw->pipeline.line_stipple) { draw->pipeline.stipple->next = next; next = draw->pipeline.stipple; precalc_flat = 1; /* only needed for lines really */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 30dceeb43d..c835727e32 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -40,6 +40,7 @@ #include "draw_vbuf.h" #include "draw_private.h" #include "draw_vertex.h" +#include "draw_pipe.h" #include "translate/translate.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c index 9a168ce8bd..329b5d0fb0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -32,6 +32,7 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" #include "draw_private.h" +#include "draw_pipe.h" struct wideline_stage { diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index 3d0add0c1a..7a439178a0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -32,6 +32,7 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" #include "draw_vs.h" +#include "draw_pipe.h" struct widepoint_stage { @@ -203,8 +204,8 @@ static void widepoint_first_point( struct draw_stage *stage, } /* XXX we won't know the real size if it's computed by the vertex shader! */ - if ((draw->rasterizer->point_size > draw->wide_point_threshold) || - (draw->rasterizer->point_sprite && draw->point_sprite)) { + if ((draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) || + (draw->rasterizer->point_sprite && draw->pipeline.point_sprite)) { stage->point = widepoint_point; } else { diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 37ffdbf902..b2b2f82b8f 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -51,12 +51,11 @@ struct pipe_context; struct gallivm_prog; struct gallivm_cpu_engine; - -struct draw_pt_middle_end; -struct draw_pt_front_end; struct draw_vertex_shader; +struct draw_context; +struct draw_stage; +struct vbuf_render; -#define MAX_SHADER_VERTICES 128 /** * Basic vertex info. @@ -70,17 +69,14 @@ struct vertex_header { float clip[4]; - float data[][4]; /* Note variable size */ + /* This will probably become float (*data)[4] soon: + */ + float data[][4]; }; /* NOTE: It should match vertex_id size above */ #define UNDEFINED_VERTEX_ID 0xffff -/* XXX This is too large */ -#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) -#define MAX_VERTEX_ALLOCATION ((MAX_VERTEX_SIZE + 0x0f) & ~0x0f) - - /** * Basic info for a point/line/triangle primitive. @@ -95,41 +91,6 @@ struct prim_header { -struct draw_context; - -/** - * Base class for all primitive drawing stages. - */ -struct draw_stage -{ - struct draw_context *draw; /**< parent context */ - - struct draw_stage *next; /**< next stage in pipeline */ - - struct vertex_header **tmp; /**< temp vert storage, such as for clipping */ - unsigned nr_tmps; - - void (*point)( struct draw_stage *, - struct prim_header * ); - - void (*line)( struct draw_stage *, - struct prim_header * ); - - void (*tri)( struct draw_stage *, - struct prim_header * ); - - void (*flush)( struct draw_stage *, - unsigned flags ); - - void (*reset_stipple_counter)( struct draw_stage * ); - - void (*destroy)( struct draw_stage * ); -}; - - - -struct vbuf_render; - #define PT_SHADE 0x1 #define PT_CLIPTEST 0x2 @@ -161,6 +122,12 @@ struct draw_context struct draw_stage *wide_line; struct draw_stage *wide_point; struct draw_stage *rasterize; + + float wide_point_threshold; /**< convert pnts to tris if larger than this */ + float wide_line_threshold; /**< convert lines to tris if wider than this */ + boolean line_stipple; /**< do line stipple? */ + boolean point_sprite; /**< convert points to quads for sprites? */ + } pipeline; @@ -225,10 +192,6 @@ struct draw_context float plane[12][4]; unsigned nr_planes; - float wide_point_threshold; /**< convert pnts to tris if larger than this */ - float wide_line_threshold; /**< convert lines to tris if wider than this */ - boolean line_stipple; /**< do line stipple? */ - boolean point_sprite; /**< convert points to quads for sprites? */ boolean use_sse; /* If a prim stage introduces new vertex attributes, they'll be stored here @@ -252,44 +215,29 @@ struct draw_context -extern struct draw_stage *draw_unfilled_stage( struct draw_context *context ); -extern struct draw_stage *draw_twoside_stage( struct draw_context *context ); -extern struct draw_stage *draw_offset_stage( struct draw_context *context ); -extern struct draw_stage *draw_clip_stage( struct draw_context *context ); -extern struct draw_stage *draw_flatshade_stage( struct draw_context *context ); -extern struct draw_stage *draw_cull_stage( struct draw_context *context ); -extern struct draw_stage *draw_stipple_stage( struct draw_context *context ); -extern struct draw_stage *draw_wide_line_stage( struct draw_context *context ); -extern struct draw_stage *draw_wide_point_stage( struct draw_context *context ); -extern struct draw_stage *draw_validate_stage( struct draw_context *context ); - - -extern void draw_free_temp_verts( struct draw_stage *stage ); - -extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); extern void draw_reset_vertex_ids( struct draw_context *draw ); -extern int draw_vertex_cache_check_space( struct draw_context *draw, - unsigned nr_verts ); -extern void draw_vertex_cache_invalidate( struct draw_context *draw ); -extern void draw_vertex_cache_unreference( struct draw_context *draw ); -extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ); +/******************************************************************************* + * Vertex processing (was passthrough) code: + */ +boolean draw_pt_init( struct draw_context *draw ); +void draw_pt_destroy( struct draw_context *draw ); +void draw_pt_reset_vertex_ids( struct draw_context *draw ); -extern void draw_update_vertex_fetch( struct draw_context *draw ); +/******************************************************************************* + * Primitive processing (pipelnie) code: + */ -extern boolean draw_need_pipeline(const struct draw_context *draw, - unsigned prim ); +boolean draw_pipeline_init( struct draw_context *draw ); +void draw_pipeline_destroy( struct draw_context *draw ); +boolean draw_need_pipeline(const struct draw_context *draw, + unsigned prim ); -/* Passthrough mode (second attempt): - */ -boolean draw_pt_init( struct draw_context *draw ); -void draw_pt_destroy( struct draw_context *draw ); -void draw_pt_reset_vertex_ids( struct draw_context *draw ); #define DRAW_FLUSH_STATE_CHANGE 0x8 #define DRAW_FLUSH_BACKEND 0x10 @@ -301,36 +249,6 @@ boolean draw_get_edgeflag( struct draw_context *draw, unsigned idx ); -/** - * Get a writeable copy of a vertex. - * \param stage drawing stage info - * \param vert the vertex to copy (source) - * \param idx index into stage's tmp[] array to put the copy (dest) - * \return pointer to the copied vertex - */ -static INLINE struct vertex_header * -dup_vert( struct draw_stage *stage, - const struct vertex_header *vert, - unsigned idx ) -{ - struct vertex_header *tmp = stage->tmp[idx]; - const uint vsize = sizeof(struct vertex_header) - + stage->draw->num_vs_outputs * 4 * sizeof(float); - memcpy(tmp, vert, vsize); - tmp->vertex_id = UNDEFINED_VERTEX_ID; - return tmp; -} - -static INLINE float -dot4(const float *a, const float *b) -{ - float result = (a[0]*b[0] + - a[1]*b[1] + - a[2]*b[2] + - a[3]*b[3]); - - return result; -} #endif /* DRAW_PRIVATE_H */ diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index f153a3ee2c..965269251f 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -165,21 +165,3 @@ draw_arrays(struct draw_context *draw, unsigned prim, draw_pt_arrays(draw, prim, start, count); } - -/* Revamp me please: - */ -void draw_do_flush( struct draw_context *draw, unsigned flags ) -{ - if (!draw->flushing) - { - draw->flushing = TRUE; - - if (flags >= DRAW_FLUSH_STATE_CHANGE) { - draw->pipeline.first->flush( draw->pipeline.first, flags ); - draw->pipeline.first = draw->pipeline.validate; - draw->reduced_prim = ~0; - } - - draw->flushing = FALSE; - } -} diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c index 1a9a3adb03..922344e448 100644 --- a/src/gallium/auxiliary/draw/draw_pt_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c @@ -35,6 +35,7 @@ #include "draw/draw_private.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" +#include "draw/draw_pipe.h" static void do_point( struct draw_context *draw, const char *v0 ) diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index b3ecec6ece..581f044dae 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -44,6 +44,17 @@ struct pt_post_vs { +static INLINE float +dot4(const float *a, const float *b) +{ + return (a[0]*b[0] + + a[1]*b[1] + + a[2]*b[2] + + a[3]*b[3]); +} + + + static INLINE unsigned compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr) { diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c index 168036eee8..a42adaafb1 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.c +++ b/src/gallium/auxiliary/draw/draw_vertex.c @@ -72,6 +72,4 @@ draw_compute_vertex_size(struct vertex_info *vinfo) assert(0); } } - - assert(vinfo->size * 4 <= MAX_VERTEX_SIZE); } diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 58a5854f0d..4bef21619c 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -142,7 +142,7 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen, */ i915->draw = draw_create(); assert(i915->draw); - if (GETENV("I915_VBUF")) { + if (!GETENV("I915_NO_VBUF")) { draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915)); } else { diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c index b6fb0a6d88..9ffa460138 100644 --- a/src/gallium/drivers/i915simple/i915_prim_emit.c +++ b/src/gallium/drivers/i915simple/i915_prim_emit.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "draw/draw_private.h" +#include "draw/draw_pipe.h" #include "pipe/p_util.h" #include "i915_context.h" @@ -78,9 +78,6 @@ emit_hw_vertex( struct i915_context *i915, const uint j = vinfo->src_index[i]; const float *attrib = vertex->data[j]; switch (vinfo->emit[i]) { - case EMIT_OMIT: - /* no-op */ - break; case EMIT_1F: OUT_BATCH( fui(attrib[0]) ); count++; diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 0ddb06764a..feb35d492a 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -39,7 +39,7 @@ #include "sp_setup.h" #include "sp_state.h" #include "sp_prim_setup.h" -#include "draw/draw_private.h" +#include "draw/draw_pipe.h" #include "draw/draw_vertex.h" #include "pipe/p_util.h" -- cgit v1.2.3 From c898eae27221bd23b11327553c215a94369eeb99 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 15:35:22 +0100 Subject: draw: always emit header in draw_pt_fetch.c --- src/gallium/auxiliary/draw/draw_pt.h | 1 - src/gallium/auxiliary/draw/draw_pt_fetch.c | 8 ++------ src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 1 - 3 files changed, 2 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 1119e9c6b8..eaf8e0374a 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -176,7 +176,6 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw ); struct pt_fetch; void draw_pt_fetch_prepare( struct pt_fetch *fetch, - boolean emit_header, unsigned vertex_size ); void draw_pt_fetch_run( struct pt_fetch *fetch, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 1aed251c85..037e3765da 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -54,7 +54,6 @@ struct pt_fetch { * */ void draw_pt_fetch_prepare( struct pt_fetch *fetch, - boolean emit_header, unsigned vertex_size ) { struct draw_context *draw = fetch->draw; @@ -66,16 +65,13 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, memset(&key, 0, sizeof(key)); - /* If PT_SHADE is not set, then we are creating post-shader - * vertices, meaning that we need to emit/leave space for a vertex - * header. + /* Always emit/leave space for a vertex header. * * It's worth considering whether the vertex headers should contain * a pointer to the 'data', rather than having it inline. * Something to look at after we've fully switched over to the pt * paths. */ - if (emit_header) { /* Need to set header->vertex_id = 0xffff somehow. */ @@ -121,7 +117,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, fetch->translate = translate_create( &key ); - if (emit_header) { + { static struct vertex_header vh = { 0, 0, 0, 0xffff }; fetch->translate->set_buffer(fetch->translate, draw->nr_vertex_buffers, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 0b9e8d15ba..560f1bcd92 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -71,7 +71,6 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, draw_pt_fetch_prepare( fpme->fetch, - (opt & (PT_CLIPTEST | PT_PIPELINE)) != 0, fpme->vertex_size ); /* XXX: it's not really gl rasterization rules we care about here, -- cgit v1.2.3 From bee1d31641674c67676de86fbb4b35ca5bf7f33f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 16:39:24 +0100 Subject: draw: move pt_pipeline code to draw_pipe.c This is now the drawing interface to the pipeline. No more calling into pipeline.first->tri(), etc. --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/SConscript | 1 - src/gallium/auxiliary/draw/draw_pipe.c | 117 ++++++++++++++- src/gallium/auxiliary/draw/draw_private.h | 24 +++- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 14 +- src/gallium/auxiliary/draw/draw_pt_pipeline.c | 158 --------------------- 6 files changed, 140 insertions(+), 175 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_pt_pipeline.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 4fffd11b77..5289f2660a 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -26,7 +26,6 @@ C_SOURCES = \ draw_pt_fetch.c \ draw_pt_fetch_emit.c \ draw_pt_fetch_shade_pipeline.c \ - draw_pt_pipeline.c \ draw_pt_post_vs.c \ draw_pt_vcache.c \ draw_vertex.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 5fa35d3005..6f3ca4fa49 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -25,7 +25,6 @@ draw = env.ConvenienceLibrary( 'draw_pt_fetch.c', 'draw_pt_fetch_emit.c', 'draw_pt_fetch_shade_pipeline.c', - 'draw_pt_pipeline.c', 'draw_pt_post_vs.c', 'draw_pt_vcache.c', 'draw_vs.c', diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 9d62cb2c65..b18b747d9c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -35,6 +35,7 @@ #include "draw/draw_pipe.h" + boolean draw_pipeline_init( struct draw_context *draw ) { /* create pipeline stages */ @@ -142,6 +143,60 @@ void draw_free_temp_verts( struct draw_stage *stage ) } } + + +static void do_point( struct draw_context *draw, + const char *v0 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 0; + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + + draw->pipeline.first->point( draw->pipeline.first, &prim ); +} + + +static void do_line( struct draw_context *draw, + const char *v0, + const char *v1 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 1; /* fixme */ + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + + draw->pipeline.first->line( draw->pipeline.first, &prim ); +} + + +static void do_triangle( struct draw_context *draw, + char *v0, + char *v1, + char *v2 ) +{ + struct prim_header prim; + + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + prim.v[2] = (struct vertex_header *)v2; + prim.reset_line_stipple = 1; + prim.edgeflags = ((prim.v[0]->edgeflag) | + (prim.v[1]->edgeflag << 1) | + (prim.v[2]->edgeflag << 2)); + prim.pad = 0; + + draw->pipeline.first->tri( draw->pipeline.first, &prim ); +} + + +/* Reset vertex ids. This is basically a type of flush. + */ void draw_reset_vertex_ids(struct draw_context *draw) { struct draw_stage *stage = draw->pipeline.first; @@ -155,7 +210,67 @@ void draw_reset_vertex_ids(struct draw_context *draw) stage = stage->next; } - draw_pt_reset_vertex_ids(draw); + if (draw->pipeline.verts) + { + unsigned i; + char *verts = draw->pipeline.verts; + unsigned stride = draw->pipeline.vertex_stride; + + for (i = 0; i < draw->pipeline.vertex_count; i++) { + ((struct vertex_header *)verts)->vertex_id = UNDEFINED_VERTEX_ID; + verts += stride; + } + } } +/* Code to run the pipeline on a fairly arbitary collection of vertices. + * + * Vertex headers must be pre-initialized with the + * UNDEFINED_VERTEX_ID, this code will cause that id to become + * overwritten, so it may have to be reset if there is the intention + * to reuse the vertices. + * + * This code provides a callback to reset the vertex id's which the + * draw_vbuf.c code uses when it has to perform a flush. + */ +void draw_pipeline_run( struct draw_context *draw, + unsigned prim, + struct vertex_header *vertices, + unsigned vertex_count, + unsigned stride, + const ushort *elts, + unsigned count ) +{ + char *verts = (char *)vertices; + unsigned i; + + draw->pipeline.verts = verts; + draw->pipeline.vertex_stride = stride; + draw->pipeline.vertex_count = vertex_count; + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i++) + do_point( draw, + verts + stride * elts[i] ); + break; + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) + do_line( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1]); + break; + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) + do_triangle( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1], + verts + stride * elts[i+2]); + break; + } + + draw->pipeline.verts = NULL; + draw->pipeline.vertex_count = 0; +} + diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index b2b2f82b8f..4d123cf8d9 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -128,6 +128,11 @@ struct draw_context boolean line_stipple; /**< do line stipple? */ boolean point_sprite; /**< convert points to quads for sprites? */ + /* Temporary storage while the pipeline is being run: + */ + char *verts; + unsigned vertex_stride; + unsigned vertex_count; } pipeline; @@ -144,13 +149,6 @@ struct draw_context struct { struct draw_pt_front_end *vcache; } front; - - struct { - char *verts; - unsigned vertex_stride; - unsigned vertex_count; - } pipeline; - } pt; boolean flushing; @@ -235,10 +233,22 @@ void draw_pt_reset_vertex_ids( struct draw_context *draw ); boolean draw_pipeline_init( struct draw_context *draw ); void draw_pipeline_destroy( struct draw_context *draw ); +void draw_pipeline_run( struct draw_context *draw, + unsigned prim, + struct vertex_header *vertices, + unsigned vertex_count, + unsigned stride, + const ushort *elts, + unsigned count ); + boolean draw_need_pipeline(const struct draw_context *draw, unsigned prim ); +/******************************************************************************* + * Flushing + */ + #define DRAW_FLUSH_STATE_CHANGE 0x8 #define DRAW_FLUSH_BACKEND 0x10 diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 560f1bcd92..a47693ba20 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -148,13 +148,13 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, /* Do we need to run the pipeline? */ if (opt & PT_PIPELINE) { - draw_pt_run_pipeline( fpme->draw, - fpme->prim, - pipeline_verts, - fetch_count, - fpme->vertex_size, - draw_elts, - draw_count ); + draw_pipeline_run( fpme->draw, + fpme->prim, + pipeline_verts, + fetch_count, + fpme->vertex_size, + draw_elts, + draw_count ); } else { draw_pt_emit( fpme->emit, diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c deleted file mode 100644 index 922344e448..0000000000 --- a/src/gallium/auxiliary/draw/draw_pt_pipeline.c +++ /dev/null @@ -1,158 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "draw/draw_private.h" -#include "draw/draw_vertex.h" -#include "draw/draw_pt.h" -#include "draw/draw_pipe.h" - -static void do_point( struct draw_context *draw, - const char *v0 ) -{ - struct prim_header prim; - - prim.reset_line_stipple = 0; - prim.edgeflags = 1; - prim.pad = 0; - prim.v[0] = (struct vertex_header *)v0; - - draw->pipeline.first->point( draw->pipeline.first, &prim ); -} - - -static void do_line( struct draw_context *draw, - const char *v0, - const char *v1 ) -{ - struct prim_header prim; - - prim.reset_line_stipple = 1; /* fixme */ - prim.edgeflags = 1; - prim.pad = 0; - prim.v[0] = (struct vertex_header *)v0; - prim.v[1] = (struct vertex_header *)v1; - - draw->pipeline.first->line( draw->pipeline.first, &prim ); -} - - -static void do_triangle( struct draw_context *draw, - char *v0, - char *v1, - char *v2 ) -{ - struct prim_header prim; - - prim.v[0] = (struct vertex_header *)v0; - prim.v[1] = (struct vertex_header *)v1; - prim.v[2] = (struct vertex_header *)v2; - prim.reset_line_stipple = 1; - prim.edgeflags = ((prim.v[0]->edgeflag) | - (prim.v[1]->edgeflag << 1) | - (prim.v[2]->edgeflag << 2)); - prim.pad = 0; - - if (0) debug_printf("tri ef: %d %d %d\n", - prim.v[0]->edgeflag, - prim.v[1]->edgeflag, - prim.v[2]->edgeflag); - - draw->pipeline.first->tri( draw->pipeline.first, &prim ); -} - - - -void draw_pt_reset_vertex_ids( struct draw_context *draw ) -{ - unsigned i; - char *verts = draw->pt.pipeline.verts; - unsigned stride = draw->pt.pipeline.vertex_stride; - - for (i = 0; i < draw->pt.pipeline.vertex_count; i++) { - ((struct vertex_header *)verts)->vertex_id = UNDEFINED_VERTEX_ID; - verts += stride; - } -} - - -/* Code to run the pipeline on a fairly arbitary collection of vertices. - * - * Vertex headers must be pre-initialized with the - * UNDEFINED_VERTEX_ID, this code will cause that id to become - * overwritten, so it may have to be reset if there is the intention - * to reuse the vertices. - * - * This code provides a callback to reset the vertex id's which the - * draw_vbuf.c code uses when it has to perform a flush. - */ -void draw_pt_run_pipeline( struct draw_context *draw, - unsigned prim, - struct vertex_header *pipeline_verts, - unsigned vertex_count, - unsigned stride, - const ushort *elts, - unsigned count ) -{ - char *verts = (char *)pipeline_verts; - unsigned i; - - draw->pt.pipeline.verts = verts; - draw->pt.pipeline.vertex_stride = stride; - draw->pt.pipeline.vertex_count = vertex_count; - - switch (prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i++) - do_point( draw, - verts + stride * elts[i] ); - break; - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) - do_line( draw, - verts + stride * elts[i+0], - verts + stride * elts[i+1]); - break; - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) - do_triangle( draw, - verts + stride * elts[i+0], - verts + stride * elts[i+1], - verts + stride * elts[i+2]); - break; - } - - draw->pt.pipeline.verts = NULL; - draw->pt.pipeline.vertex_count = 0; -} - -- cgit v1.2.3 From e7bac4276634ea1ee81ac71f6f6869f87e689872 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 16:43:15 +0100 Subject: draw: put pipeline flushing behind a new interface --- src/gallium/auxiliary/draw/draw_context.c | 8 +++----- src/gallium/auxiliary/draw/draw_pipe.c | 8 ++++++++ src/gallium/auxiliary/draw/draw_private.h | 5 ++++- 3 files changed, 15 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index fa6791fa0b..3e69867d11 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -379,11 +379,9 @@ void draw_do_flush( struct draw_context *draw, unsigned flags ) { draw->flushing = TRUE; - if (flags >= DRAW_FLUSH_STATE_CHANGE) { - draw->pipeline.first->flush( draw->pipeline.first, flags ); - draw->pipeline.first = draw->pipeline.validate; - draw->reduced_prim = ~0; /* is reduced_prim needed any more? */ - } + draw_pipeline_flush( draw, flags ); + + draw->reduced_prim = ~0; /* is reduced_prim needed any more? */ draw->flushing = FALSE; } diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index b18b747d9c..3fae908514 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -274,3 +274,11 @@ void draw_pipeline_run( struct draw_context *draw, draw->pipeline.vertex_count = 0; } + + +void draw_pipeline_flush( struct draw_context *draw, + unsigned flags ) +{ + draw->pipeline.first->flush( draw->pipeline.first, flags ); + draw->pipeline.first = draw->pipeline.validate; +} diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 4d123cf8d9..59635d643b 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -227,7 +227,7 @@ void draw_pt_reset_vertex_ids( struct draw_context *draw ); /******************************************************************************* - * Primitive processing (pipelnie) code: + * Primitive processing (pipeline) code: */ boolean draw_pipeline_init( struct draw_context *draw ); @@ -241,6 +241,9 @@ void draw_pipeline_run( struct draw_context *draw, const ushort *elts, unsigned count ); +void draw_pipeline_flush( struct draw_context *draw, + unsigned flags ); + boolean draw_need_pipeline(const struct draw_context *draw, unsigned prim ); -- cgit v1.2.3 From 2dae208fb19e79c7446a29ee5dee53e50283b57c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 17:16:23 +0100 Subject: draw: make room for extra_vs_outputs --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index a47693ba20..e1df594035 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -56,8 +56,12 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; struct draw_vertex_shader *vs = draw->vertex_shader; + + /* Add one to num_outputs because the pipeline occasionally tags on + * an additional texcoord, eg for AA lines. + */ unsigned nr = MAX2( vs->info.num_inputs, - vs->info.num_outputs ); + vs->info.num_outputs + 1 ); fpme->prim = prim; fpme->opt = opt; -- cgit v1.2.3 From dcf6f776ce32b89b7ff784bb38030bd29698e005 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 17:16:41 +0100 Subject: draw: make draw_reset_vertex_ids private to the draw_pipe_* code --- src/gallium/auxiliary/draw/draw_pipe.c | 2 ++ src/gallium/auxiliary/draw/draw_pipe.h | 2 +- src/gallium/auxiliary/draw/draw_private.h | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 3fae908514..0c0840af0c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -196,6 +196,8 @@ static void do_triangle( struct draw_context *draw, /* Reset vertex ids. This is basically a type of flush. + * + * Called only from draw_pipe_vbuf.c */ void draw_reset_vertex_ids(struct draw_context *draw) { diff --git a/src/gallium/auxiliary/draw/draw_pipe.h b/src/gallium/auxiliary/draw/draw_pipe.h index 5b97ca5c8c..f2749b34bb 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.h +++ b/src/gallium/auxiliary/draw/draw_pipe.h @@ -81,9 +81,9 @@ extern struct draw_stage *draw_validate_stage( struct draw_context *context ); extern void draw_free_temp_verts( struct draw_stage *stage ); - extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); +extern void draw_reset_vertex_ids( struct draw_context *draw ); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 59635d643b..6cf3e54e28 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -214,7 +214,6 @@ struct draw_context -extern void draw_reset_vertex_ids( struct draw_context *draw ); -- cgit v1.2.3 From 7d72607e142c0412b88183b849fd701e698b8f79 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 17:27:52 +0100 Subject: draw: move incoming vertex state into draw->pt This state is effectively private to the vertex processing part of the draw module. --- src/gallium/auxiliary/draw/draw_context.c | 28 +++++-------- src/gallium/auxiliary/draw/draw_private.h | 47 +++++++++++----------- src/gallium/auxiliary/draw/draw_pt.c | 8 ++++ src/gallium/auxiliary/draw/draw_pt.h | 9 +---- src/gallium/auxiliary/draw/draw_pt_elts.c | 6 +-- src/gallium/auxiliary/draw/draw_pt_fetch.c | 20 ++++----- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 6 +-- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 2 +- src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 +- 9 files changed, 60 insertions(+), 68 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 3e69867d11..4988d67faa 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -62,8 +62,6 @@ struct draw_context *draw_create( void ) draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ - draw_set_mapped_element_buffer( draw, 0, NULL ); - tgsi_exec_machine_init(&draw->machine); /* FIXME: give this machine thing a proper constructor: @@ -188,8 +186,8 @@ draw_set_vertex_buffers(struct draw_context *draw, { assert(count <= PIPE_MAX_ATTRIBS); - memcpy(draw->vertex_buffer, buffers, count * sizeof(buffers[0])); - draw->nr_vertex_buffers = count; + memcpy(draw->pt.vertex_buffer, buffers, count * sizeof(buffers[0])); + draw->pt.nr_vertex_buffers = count; } @@ -200,8 +198,8 @@ draw_set_vertex_elements(struct draw_context *draw, { assert(count <= PIPE_MAX_ATTRIBS); - memcpy(draw->vertex_element, elements, count * sizeof(elements[0])); - draw->nr_vertex_elements = count; + memcpy(draw->pt.vertex_element, elements, count * sizeof(elements[0])); + draw->pt.nr_vertex_elements = count; } @@ -212,7 +210,7 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw, unsigned attr, const void *buffer) { - draw->user.vbuffer[attr] = buffer; + draw->pt.user.vbuffer[attr] = buffer; } @@ -220,7 +218,7 @@ void draw_set_mapped_constant_buffer(struct draw_context *draw, const void *buffer) { - draw->user.constants = buffer; + draw->pt.user.constants = buffer; } @@ -337,18 +335,10 @@ void draw_set_render( struct draw_context *draw, void draw_set_edgeflags( struct draw_context *draw, const unsigned *edgeflag ) { - draw->user.edgeflag = edgeflag; + draw->pt.user.edgeflag = edgeflag; } -boolean draw_get_edgeflag( struct draw_context *draw, - unsigned idx ) -{ - if (draw->user.edgeflag) - return (draw->user.edgeflag[idx/32] & (1 << (idx%32))) != 0; - else - return 1; -} /** @@ -365,8 +355,8 @@ void draw_set_mapped_element_buffer( struct draw_context *draw, unsigned eltSize, void *elements ) { - draw->user.elts = elements; - draw->user.eltSize = eltSize; + draw->pt.user.elts = elements; + draw->pt.user.eltSize = eltSize; } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 6cf3e54e28..27f61c2f40 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -149,6 +149,29 @@ struct draw_context struct { struct draw_pt_front_end *vcache; } front; + + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + unsigned nr_vertex_buffers; + + struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; + unsigned nr_vertex_elements; + + /* user-space vertex data, buffers */ + struct { + const unsigned *edgeflag; + + /** vertex element/index buffer (ex: glDrawElements) */ + const void *elts; + /** bytes per index (0, 1, 2 or 4) */ + unsigned eltSize; + + /** vertex arrays */ + const void *vbuffer[PIPE_MAX_ATTRIBS]; + + /** constant buffer (for vertex shader) */ + const void *constants; + } user; + } pt; boolean flushing; @@ -157,33 +180,12 @@ struct draw_context const struct pipe_rasterizer_state *rasterizer; struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - unsigned nr_vertex_buffers; - - struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; - unsigned nr_vertex_elements; - struct draw_vertex_shader *vertex_shader; boolean identity_viewport; uint num_vs_outputs; /**< convenience, from vertex_shader */ - /* user-space vertex data, buffers */ - struct { - const unsigned *edgeflag; - - /** vertex element/index buffer (ex: glDrawElements) */ - const void *elts; - /** bytes per index (0, 1, 2 or 4) */ - unsigned eltSize; - - /** vertex arrays */ - const void *vbuffer[PIPE_MAX_ATTRIBS]; - - /** constant buffer (for vertex shader) */ - const void *constants; - } user; /* Clip derived state: */ @@ -257,9 +259,6 @@ boolean draw_need_pipeline(const struct draw_context *draw, void draw_do_flush( struct draw_context *draw, unsigned flags ); -boolean draw_get_edgeflag( struct draw_context *draw, - unsigned idx ); - diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 965269251f..9f8e8d3d62 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -165,3 +165,11 @@ draw_arrays(struct draw_context *draw, unsigned prim, draw_pt_arrays(draw, prim, start, count); } +boolean draw_pt_get_edgeflag( struct draw_context *draw, + unsigned idx ) +{ + if (draw->pt.user.edgeflag) + return (draw->pt.user.edgeflag[idx/32] & (1 << (idx%32))) != 0; + else + return 1; +} diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index eaf8e0374a..fd0d158fcf 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -141,13 +141,8 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *d /* More helpers: */ -void draw_pt_run_pipeline( struct draw_context *draw, - unsigned prim, - struct vertex_header *verts, - unsigned vertex_count, - unsigned vertex_stride, - const ushort *elts, - unsigned count ); +boolean draw_pt_get_edgeflag( struct draw_context *draw, + unsigned idx ); /******************************************************************************* diff --git a/src/gallium/auxiliary/draw/draw_pt_elts.c b/src/gallium/auxiliary/draw/draw_pt_elts.c index d49770e7b2..2094c081ed 100644 --- a/src/gallium/auxiliary/draw/draw_pt_elts.c +++ b/src/gallium/auxiliary/draw/draw_pt_elts.c @@ -59,7 +59,7 @@ static unsigned elt_vert( const void *elts, unsigned idx ) pt_elt_func draw_pt_elt_func( struct draw_context *draw ) { - switch (draw->user.eltSize) { + switch (draw->pt.user.eltSize) { case 0: return elt_vert; case 1: return elt_ubyte; case 2: return elt_ushort; @@ -71,9 +71,9 @@ pt_elt_func draw_pt_elt_func( struct draw_context *draw ) const void *draw_pt_elt_ptr( struct draw_context *draw, unsigned start ) { - const char *elts = draw->user.elts; + const char *elts = draw->pt.user.elts; - switch (draw->user.eltSize) { + switch (draw->pt.user.eltSize) { case 0: return (const void *)(((const ubyte *)NULL) + start); case 1: diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 037e3765da..c588710b75 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -76,7 +76,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, /* Need to set header->vertex_id = 0xffff somehow. */ key.element[nr].input_format = PIPE_FORMAT_R32_FLOAT; - key.element[nr].input_buffer = draw->nr_vertex_buffers; + key.element[nr].input_buffer = draw->pt.nr_vertex_buffers; key.element[nr].input_offset = 0; key.element[nr].output_format = PIPE_FORMAT_R32_FLOAT; key.element[nr].output_offset = dst_offset; @@ -90,10 +90,10 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, } - for (i = 0; i < draw->nr_vertex_elements; i++) { - key.element[nr].input_format = draw->vertex_element[i].src_format; - key.element[nr].input_buffer = draw->vertex_element[i].vertex_buffer_index; - key.element[nr].input_offset = draw->vertex_element[i].src_offset; + for (i = 0; i < draw->pt.nr_vertex_elements; i++) { + key.element[nr].input_format = draw->pt.vertex_element[i].src_format; + key.element[nr].input_buffer = draw->pt.vertex_element[i].vertex_buffer_index; + key.element[nr].input_offset = draw->pt.vertex_element[i].src_offset; key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; key.element[nr].output_offset = dst_offset; @@ -120,7 +120,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, { static struct vertex_header vh = { 0, 0, 0, 0xffff }; fetch->translate->set_buffer(fetch->translate, - draw->nr_vertex_buffers, + draw->pt.nr_vertex_buffers, &vh, 0); } @@ -139,12 +139,12 @@ void draw_pt_fetch_run( struct pt_fetch *fetch, struct translate *translate = fetch->translate; unsigned i; - for (i = 0; i < draw->nr_vertex_buffers; i++) { + for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { translate->set_buffer(translate, i, - ((char *)draw->user.vbuffer[i] + - draw->vertex_buffer[i].buffer_offset), - draw->vertex_buffer[i].pitch ); + ((char *)draw->pt.user.vbuffer[i] + + draw->pt.vertex_buffer[i].buffer_offset), + draw->pt.vertex_buffer[i].pitch ); } translate->run_elts( translate, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 6e4fea460b..1b9b3bfaa6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -117,7 +117,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, memset(&key, 0, sizeof(key)); for (i = 0; i < vinfo->num_attribs; i++) { - const struct pipe_vertex_element *src = &draw->vertex_element[vinfo->src_index[i]]; + const struct pipe_vertex_element *src = &draw->pt.vertex_element[vinfo->src_index[i]]; unsigned emit_sz = 0; unsigned input_format = src->src_format; @@ -144,7 +144,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, break; case EMIT_1F_PSIZE: input_format = PIPE_FORMAT_R32_FLOAT; - input_buffer = draw->nr_vertex_buffers; + input_buffer = draw->pt.nr_vertex_buffers; input_offset = 0; output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); @@ -179,7 +179,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, feme->translate = translate_create( &key ); feme->translate->set_buffer(feme->translate, - draw->nr_vertex_buffers, + draw->pt.nr_vertex_buffers, &feme->point_size, 0); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index e1df594035..881e47d59d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -135,7 +135,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, shader->run_linear(shader, (const float (*)[4])pipeline_verts->data, ( float (*)[4])pipeline_verts->data, - (const float (*)[4])draw->user.constants, + (const float (*)[4])draw->pt.user.constants, fetch_count, fpme->vertex_size, fpme->vertex_size); diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 5561f2b6fb..b61bb50664 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -106,7 +106,7 @@ static unsigned add_edgeflag( struct vcache_frontend *vcache, unsigned idx, unsigned mask ) { - if (mask && draw_get_edgeflag(vcache->draw, idx)) + if (mask && draw_pt_get_edgeflag(vcache->draw, idx)) return idx | DRAW_PT_EDGEFLAG; else return idx; -- cgit v1.2.3 From d3cb62b8b3ea03bfb9800bf4b738d9814ef3c516 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 18:02:42 +0100 Subject: draw: fix scons build --- src/gallium/auxiliary/draw/SConscript | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 6f3ca4fa49..91e6a35c5e 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -4,6 +4,7 @@ draw = env.ConvenienceLibrary( target = 'draw', source = [ 'draw_context.c', + 'draw_pipe.c', 'draw_pipe_aaline.c', 'draw_pipe_aapoint.c', 'draw_pipe_clip.c', @@ -16,7 +17,6 @@ draw = env.ConvenienceLibrary( 'draw_pipe_unfilled.c', 'draw_pipe_validate.c', 'draw_pipe_vbuf.c', - 'draw_pipe_vertex.c', 'draw_pipe_wide_line.c', 'draw_pipe_wide_point.c', 'draw_pt.c', @@ -27,6 +27,7 @@ draw = env.ConvenienceLibrary( 'draw_pt_fetch_shade_pipeline.c', 'draw_pt_post_vs.c', 'draw_pt_vcache.c', + 'draw_vertex.c', 'draw_vs.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', -- cgit v1.2.3 From af523a5bd7828fd554669cf83f18992af967a075 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 18:25:33 +0100 Subject: rtasm: include yet another i386 define varient --- src/gallium/auxiliary/rtasm/rtasm_cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c index eb3359750b..d577ff5b42 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_cpu.c +++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c @@ -32,7 +32,7 @@ int rtasm_cpu_has_sse(void) { /* FIXME: actually detect this at run-time */ -#if defined(__i386__) || defined(__386__) +#if defined(__i386__) || defined(__386__) || defined(i386) return 1; #else return 0; @@ -42,7 +42,7 @@ int rtasm_cpu_has_sse(void) int rtasm_cpu_has_sse2(void) { /* FIXME: actually detect this at run-time */ -#if defined(__i386__) || defined(__386__) +#if defined(__i386__) || defined(__386__) || defined(i386) return 1; #else return 0; -- cgit v1.2.3 From b1158a5e0031aa33a71baa7bc14ca2c0fe0dabc4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 18:26:39 +0100 Subject: translate: don't crash on failure to create sse version --- src/gallium/auxiliary/translate/translate_generic.c | 11 +++++++++++ src/gallium/auxiliary/translate/translate_sse.c | 13 ++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index e7fb1dcb2d..9de007c767 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -567,8 +567,14 @@ static void generic_run_elts( struct translate *translate, tg->attrib[attr].output_offset); tg->attrib[attr].fetch( src, data ); + + debug_printf("vert %d/%d attr %d: %f %f %f %f\n", + i, elt, attr, data[0], data[1], data[2], data[3]); + + tg->attrib[attr].emit( data, dst ); } + debug_printf("\n"); vert += tg->translate.key.output_stride; } @@ -602,8 +608,13 @@ static void generic_run( struct translate *translate, tg->attrib[attr].output_offset); tg->attrib[attr].fetch( src, data ); + + debug_printf("vert %d attr %d: %f %f %f %f\n", + i, attr, data[0], data[1], data[2], data[3]); + tg->attrib[attr].emit( data, dst ); } + debug_printf("\n"); vert += tg->translate.key.output_stride; } diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index cb8815c173..575852d222 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -145,7 +145,7 @@ static struct x86_reg get_inv_255( struct translate_sse *p ) p->inv_255[0] = p->inv_255[1] = p->inv_255[2] = - p->inv_255[3] = 1.0 / 255.0f; + p->inv_255[3] = 1.0f / 255.0f; sse_movups(p->func, reg, x86_make_disp(translateESI, @@ -575,22 +575,21 @@ struct translate *translate_sse2_create( const struct translate_key *key ) if (p == NULL) goto fail; - if (!rtasm_cpu_has_sse() || !rtasm_cpu_has_sse2()) - goto fail; - - - p->translate.key = *key; p->translate.release = translate_sse_release; p->translate.set_buffer = translate_sse_set_buffer; p->translate.run_elts = translate_sse_run_elts; p->translate.run = translate_sse_run; + if (!rtasm_cpu_has_sse() || !rtasm_cpu_has_sse2()) + goto fail; + if (!build_vertex_emit(p, &p->linear_func, TRUE)) goto fail; if (!build_vertex_emit(p, &p->elt_func, FALSE)) goto fail; + p->translate.key = *key; p->gen_run = (run_func)x86_get_func(&p->linear_func); p->gen_run_elts = (run_elts_func)x86_get_func(&p->elt_func); @@ -598,7 +597,7 @@ struct translate *translate_sse2_create( const struct translate_key *key ) fail: if (p) - p->translate.release( &p->translate ); + translate_sse_release( &p->translate ); return NULL; } -- cgit v1.2.3 From bfd179776f5ded75c2134a54f0a57a1579118cd0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 18:41:53 +0100 Subject: draw: add missing translate->set_buffer for fetch emit path --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 1b9b3bfaa6..70d136dce6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -185,6 +185,14 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, } feme->point_size = draw->rasterizer->point_size; + + for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { + feme->translate->set_buffer(feme->translate, + i, + ((char *)draw->pt.user.vbuffer[i] + + draw->pt.vertex_buffer[i].buffer_offset), + draw->pt.vertex_buffer[i].pitch ); + } } -- cgit v1.2.3 From d0a4bf08b1a80d62f81301c5b37723dfca436b62 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 20:18:40 +0100 Subject: translate: fix several bugs - specify cdecl calling convention on WIN32 - fix load bgra8 function - fix previous don't crash fix. --- .../auxiliary/translate/translate_generic.c | 11 +++--- src/gallium/auxiliary/translate/translate_sse.c | 42 ++++++++++++---------- 2 files changed, 28 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 9de007c767..402780ee53 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -568,13 +568,11 @@ static void generic_run_elts( struct translate *translate, tg->attrib[attr].fetch( src, data ); - debug_printf("vert %d/%d attr %d: %f %f %f %f\n", - i, elt, attr, data[0], data[1], data[2], data[3]); - + if (0) debug_printf("vert %d/%d attr %d: %f %f %f %f\n", + i, elt, attr, data[0], data[1], data[2], data[3]); tg->attrib[attr].emit( data, dst ); } - debug_printf("\n"); vert += tg->translate.key.output_stride; } @@ -609,12 +607,11 @@ static void generic_run( struct translate *translate, tg->attrib[attr].fetch( src, data ); - debug_printf("vert %d attr %d: %f %f %f %f\n", - i, attr, data[0], data[1], data[2], data[3]); + if (0) debug_printf("vert %d attr %d: %f %f %f %f\n", + i, attr, data[0], data[1], data[2], data[3]); tg->attrib[attr].emit( data, dst ); } - debug_printf("\n"); vert += tg->translate.key.output_stride; } diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index 575852d222..e587e5afec 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -45,15 +45,21 @@ #define W 3 -typedef void (*run_func)( struct translate *translate, - unsigned start, - unsigned count, - void *output_buffer ); +#ifdef WIN32 +#define RTASM __cdecl +#else +#define RTASM +#endif + +typedef void (RTASM *run_func)( struct translate *translate, + unsigned start, + unsigned count, + void *output_buffer ); -typedef void (*run_elts_func)( struct translate *translate, - const unsigned *elts, - unsigned count, - void *output_buffer ); +typedef void (RTASM *run_elts_func)( struct translate *translate, + const unsigned *elts, + unsigned count, + void *output_buffer ); @@ -212,17 +218,17 @@ static void emit_load_R8G8B8A8_UNORM( struct translate_sse *p, /* Load and unpack twice: */ sse_movss(p->func, data, src); - sse2_punpcklbw(p->func, src, get_identity(p)); - sse2_punpcklbw(p->func, src, get_identity(p)); + sse2_punpcklbw(p->func, data, get_identity(p)); + sse2_punpcklbw(p->func, data, get_identity(p)); /* Convert to float: */ - sse2_cvtdq2ps(p->func, src, src); + sse2_cvtdq2ps(p->func, data, data); /* Scale by 1/255.0 */ - sse_mulps(p->func, src, get_inv_255(p)); + sse_mulps(p->func, data, get_inv_255(p)); } @@ -551,7 +557,6 @@ static void translate_sse_run_elts( struct translate *translate, elts, count, output_buffer ); - } static void translate_sse_run( struct translate *translate, @@ -570,26 +575,27 @@ static void translate_sse_run( struct translate *translate, struct translate *translate_sse2_create( const struct translate_key *key ) { - struct translate_sse *p = CALLOC_STRUCT( translate_sse ); + struct translate_sse *p = NULL; + + if (!rtasm_cpu_has_sse() || !rtasm_cpu_has_sse2()) + goto fail; + p = CALLOC_STRUCT( translate_sse ); if (p == NULL) goto fail; + p->translate.key = *key; p->translate.release = translate_sse_release; p->translate.set_buffer = translate_sse_set_buffer; p->translate.run_elts = translate_sse_run_elts; p->translate.run = translate_sse_run; - if (!rtasm_cpu_has_sse() || !rtasm_cpu_has_sse2()) - goto fail; - if (!build_vertex_emit(p, &p->linear_func, TRUE)) goto fail; if (!build_vertex_emit(p, &p->elt_func, FALSE)) goto fail; - p->translate.key = *key; p->gen_run = (run_func)x86_get_func(&p->linear_func); p->gen_run_elts = (run_elts_func)x86_get_func(&p->elt_func); -- cgit v1.2.3 From 68a7cb21fa14eac9e38bf398623739a892cc0d52 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 20:20:40 +0100 Subject: draw: rearrange debug code --- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 55 +------------------------ src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 16 +++++-- src/gallium/auxiliary/draw/draw_vertex.c | 54 ++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vertex.h | 2 + 4 files changed, 70 insertions(+), 57 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index c835727e32..c5810febe0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -115,59 +115,6 @@ check_space( struct vbuf_stage *vbuf, unsigned nr ) } -static INLINE void -dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) -{ -// assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); - unsigned i, j; - - for (i = 0; i < vinfo->num_attribs; i++) { - j = vinfo->src_index[i]; - switch (vinfo->emit[i]) { - case EMIT_OMIT: - debug_printf("EMIT_OMIT:"); - break; - case EMIT_1F: - debug_printf("EMIT_1F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_1F_PSIZE: - debug_printf("EMIT_1F_PSIZE:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_2F: - debug_printf("EMIT_2F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_3F: - debug_printf("EMIT_3F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - data += sizeof(float); - break; - case EMIT_4F: - debug_printf("EMIT_4F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_4UB: - debug_printf("EMIT_4UB:\t"); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - break; - default: - assert(0); - } - debug_printf("\n"); - } - debug_printf("\n"); -} /** @@ -189,7 +136,7 @@ emit_vertex( struct vbuf_stage *vbuf, vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); - if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); + if (0) draw_dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); vbuf->vertex_ptr += vbuf->vertex_size/4; vertex->vertex_id = vbuf->nr_vertices++; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 70d136dce6..002ced2186 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -75,6 +75,7 @@ struct fetch_emit_middle_end { struct draw_context *draw; struct translate *translate; + const struct vertex_info *vinfo; /* Cache point size somewhere it's address won't change: */ @@ -106,9 +107,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, /* Must do this after set_primitive() above: */ - vinfo = draw->render->get_vertex_info(draw->render); - - + vinfo = feme->vinfo = draw->render->get_vertex_info(draw->render); + + /* Transform from API vertices to HW vertices, skipping the * pipeline_vertex intermediate step. @@ -229,6 +230,15 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, fetch_count, hw_verts ); + if (0) { + unsigned i; + for (i = 0; i < fetch_count; i++) { + debug_printf("\n\nvertex %d:\n", i); + draw_dump_emitted_vertex( feme->vinfo, + (const uint8_t *)hw_verts + feme->vinfo->size * 4 * i ); + } + } + /* XXX: Draw arrays path to avoid re-emitting index list again and * again. */ diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c index a42adaafb1..1446f785c5 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.c +++ b/src/gallium/auxiliary/draw/draw_vertex.c @@ -73,3 +73,57 @@ draw_compute_vertex_size(struct vertex_info *vinfo) } } } + + +void +draw_dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) +{ + unsigned i, j; + + for (i = 0; i < vinfo->num_attribs; i++) { + j = vinfo->src_index[i]; + switch (vinfo->emit[i]) { + case EMIT_OMIT: + debug_printf("EMIT_OMIT:"); + break; + case EMIT_1F: + debug_printf("EMIT_1F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_1F_PSIZE: + debug_printf("EMIT_1F_PSIZE:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_2F: + debug_printf("EMIT_2F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_3F: + debug_printf("EMIT_3F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + data += sizeof(float); + break; + case EMIT_4F: + debug_printf("EMIT_4F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_4UB: + debug_printf("EMIT_4UB:\t"); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + break; + default: + assert(0); + } + debug_printf("\n"); + } + debug_printf("\n"); +} diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index 65818463ca..6d8bac5138 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -106,5 +106,7 @@ draw_emit_vertex_attr(struct vertex_info *vinfo, extern void draw_compute_vertex_size(struct vertex_info *vinfo); +void draw_dump_emitted_vertex(const struct vertex_info *vinfo, + const uint8_t *data); #endif /* DRAW_VERTEX_H */ -- cgit v1.2.3 From 29858e1b553cee1fd7e3380ea62c69d2a6b91b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 20 Apr 2008 14:41:02 +0900 Subject: gallium: Refcount textures. Pipe driver does refcount textures. If cso_context does not, dangling pointers appear. --- src/gallium/auxiliary/cso_cache/cso_context.c | 37 ++++++++++++++++++++------- 1 file changed, 28 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 4a1a6cb79c..746b176185 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -25,16 +25,19 @@ * **************************************************************************/ - /* Wrap the cso cache & hash mechanisms in a simplified + /** + * @file + * + * Wrap the cso cache & hash mechanisms in a simplified * pipe-driver-specific interface. * - * Authors: - * Zack Rusin - * Keith Whitwell + * @author Zack Rusin + * @author Keith Whitwell */ #include "pipe/p_state.h" #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "cso_cache/cso_context.h" #include "cso_cache/cso_cache.h" @@ -277,23 +280,39 @@ void cso_set_sampler_textures( struct cso_context *ctx, ctx->nr_textures = count; for (i = 0; i < count; i++) - ctx->textures[i] = textures[i]; + pipe_texture_reference(&ctx->textures[i], textures[i]); for ( ; i < PIPE_MAX_SAMPLERS; i++) - ctx->textures[i] = NULL; + pipe_texture_reference(&ctx->textures[i], NULL); ctx->pipe->set_sampler_textures(ctx->pipe, count, textures); } void cso_save_sampler_textures( struct cso_context *ctx ) { + uint i; + ctx->nr_textures_saved = ctx->nr_textures; - memcpy(ctx->textures_saved, ctx->textures, sizeof(ctx->textures)); + for (i = 0; i < ctx->nr_textures; i++) { + assert(!ctx->textures_saved[i]); + pipe_texture_reference(&ctx->textures_saved[i], ctx->textures[i]); + } } void cso_restore_sampler_textures( struct cso_context *ctx ) { - cso_set_sampler_textures(ctx, ctx->nr_textures_saved, ctx->textures_saved); - ctx->nr_textures_saved = 0; + uint i; + + ctx->nr_textures = ctx->nr_textures_saved; + + for (i = 0; i < ctx->nr_textures; i++) { + pipe_texture_reference(&ctx->textures[i], NULL); + ctx->textures[i] = ctx->textures_saved[i]; + ctx->textures_saved[i] = NULL; + } + for ( ; i < PIPE_MAX_SAMPLERS; i++) + pipe_texture_reference(&ctx->textures[i], NULL); + + ctx->pipe->set_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures); } -- cgit v1.2.3 From 40e0439db448a7d93ddb18faac7f14b47b1343c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 21 Apr 2008 13:02:59 +0900 Subject: gallium: Centralize SSE usage logic. --- src/gallium/auxiliary/draw/draw_context.c | 12 ------------ src/gallium/auxiliary/draw/draw_context.h | 2 -- src/gallium/auxiliary/draw/draw_private.h | 2 -- src/gallium/auxiliary/draw/draw_vs_sse.c | 3 ++- src/gallium/auxiliary/rtasm/rtasm_cpu.c | 10 ++++++++-- 5 files changed, 10 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 4988d67faa..b4dbdccd61 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -45,12 +45,6 @@ struct draw_context *draw_create( void ) if (draw == NULL) goto fail; -#if defined(__i386__) || defined(__386__) - draw->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; -#else - draw->use_sse = FALSE; -#endif - 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 ); @@ -320,12 +314,6 @@ draw_num_vs_outputs(struct draw_context *draw) -boolean draw_use_sse(struct draw_context *draw) -{ - return (boolean) draw->use_sse; -} - - void draw_set_render( struct draw_context *draw, struct vbuf_render *render ) { diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index a0ac980c89..68e2efb865 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -73,8 +73,6 @@ void draw_enable_line_stipple(struct draw_context *draw, boolean enable); void draw_enable_point_sprites(struct draw_context *draw, boolean enable); -boolean draw_use_sse(struct draw_context *draw); - void draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 27f61c2f40..da973e868b 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -192,8 +192,6 @@ struct draw_context float plane[12][4]; unsigned nr_planes; - boolean use_sse; - /* If a prim stage introduces new vertex attributes, they'll be stored here */ struct { diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 8e2d381f14..b1e9f67114 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -41,6 +41,7 @@ #include "draw_private.h" #include "draw_context.h" +#include "rtasm/rtasm_cpu.h" #include "rtasm/rtasm_x86sse.h" #include "tgsi/exec/tgsi_sse2.h" #include "tgsi/util/tgsi_parse.h" @@ -155,7 +156,7 @@ draw_create_vs_sse(struct draw_context *draw, struct draw_sse_vertex_shader *vs; uint nt = tgsi_num_tokens(templ->tokens); - if (!draw->use_sse) + if (!rtasm_cpu_has_sse2()) return NULL; vs = CALLOC_STRUCT( draw_sse_vertex_shader ); diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c index d577ff5b42..175245a9f6 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_cpu.c +++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c @@ -26,14 +26,20 @@ **************************************************************************/ +#include "pipe/p_debug.h" #include "rtasm_cpu.h" +static boolean rtasm_sse_enabled(void) +{ + return !debug_get_bool_option("GALLIUM_NOSSE", FALSE); +} + int rtasm_cpu_has_sse(void) { /* FIXME: actually detect this at run-time */ #if defined(__i386__) || defined(__386__) || defined(i386) - return 1; + return rtasm_sse_enabled(); #else return 0; #endif @@ -43,7 +49,7 @@ int rtasm_cpu_has_sse2(void) { /* FIXME: actually detect this at run-time */ #if defined(__i386__) || defined(__386__) || defined(i386) - return 1; + return rtasm_sse_enabled(); #else return 0; #endif -- cgit v1.2.3 From 201ac414d4df00745e487a6ffbc9979a2e70f0c6 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 00:10:39 -0400 Subject: make llvm draw paths compile with the latest changes switch the method of distribution of builtins (to get rid of the llvm2cpp dependency) --- src/gallium/auxiliary/draw/draw_vs_llvm.c | 13 +- src/gallium/auxiliary/gallivm/Makefile | 8 +- src/gallium/auxiliary/gallivm/gallivm_builtins.cpp | 708 ++++----------------- src/gallium/auxiliary/gallivm/instructions.cpp | 11 +- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 37 +- src/gallium/auxiliary/gallivm/llvm_builtins.c | 2 +- src/gallium/auxiliary/gallivm/soabuiltins.c | 2 +- 7 files changed, 199 insertions(+), 582 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index c219a91156..2ebf05526a 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -73,16 +73,17 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, (struct draw_llvm_vertex_shader *)base; struct tgsi_exec_machine *machine = shader->machine; - unsigned int j; + unsigned int i, j; + unsigned slot; for (i = 0; i < count; i += MAX_TGSI_VERTICES) { unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); - /* Swizzle inputs. + /* Swizzle inputs. */ for (j = 0; j < max_vertices; j++) { - for (slot = 0; slot < draw->num_vs_inputs; slot++) { + for (slot = 0; slot < base->info.num_inputs; slot++) { machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; @@ -102,7 +103,7 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, /* Unswizzle all output results */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { + for (slot = 1; slot < base->info.num_inputs; slot++) { output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; @@ -145,7 +146,7 @@ draw_create_vs_llvm(struct draw_context *draw, /* we make a private copy of the tokens */ vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0])); - tgsi_scan_shader(shader->tokens, &vs->base.info); + tgsi_scan_shader(vs->base.state.tokens, &vs->base.info); vs->base.prepare = vs_llvm_prepare; vs->base.run_linear = vs_llvm_run_linear; @@ -156,7 +157,7 @@ draw_create_vs_llvm(struct draw_context *draw, struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); gallivm_ir_set_layout(ir, GALLIVM_SOA); gallivm_ir_set_components(ir, 4); - gallivm_ir_fill_from_tgsi(ir, vs->base.state->tokens); + gallivm_ir_fill_from_tgsi(ir, vs->base.state.tokens); vs->llvm_prog = gallivm_ir_compile(ir); gallivm_ir_delete(ir); } diff --git a/src/gallium/auxiliary/gallivm/Makefile b/src/gallium/auxiliary/gallivm/Makefile index c24e19e062..6bfd187fb3 100644 --- a/src/gallium/auxiliary/gallivm/Makefile +++ b/src/gallium/auxiliary/gallivm/Makefile @@ -65,10 +65,14 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) gallivm_builtins.cpp: llvm_builtins.c - clang --emit-llvm < $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp.bin + (echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ + rm temp.bin gallivmsoabuiltins.cpp: soabuiltins.c - clang --emit-llvm < $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-module -o=$@ -f -for=shader -funcname=createSoaBuiltins + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp.bin + (echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ + rm temp.bin # Emacs tags tags: diff --git a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp index 1796f0a177..a6f8cd043b 100644 --- a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp @@ -1,567 +1,141 @@ -// Generated by llvm2cpp - DO NOT MODIFY! - - -Module* createGallivmBuiltins(Module *mod) { - -mod->setModuleIdentifier("shader"); - -// Type Definitions -ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(8), 25); - -PointerType* PointerTy_1 = PointerType::get(ArrayTy_0, 0); - -std::vectorFuncTy_2_args; -FuncTy_2_args.push_back(Type::FloatTy); -FuncTy_2_args.push_back(Type::FloatTy); -FunctionType* FuncTy_2 = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/FuncTy_2_args, - /*isVarArg=*/false); - -PointerType* PointerTy_3 = PointerType::get(FuncTy_2, 0); - -VectorType* VectorTy_4 = VectorType::get(Type::FloatTy, 4); - -std::vectorFuncTy_5_args; -FuncTy_5_args.push_back(VectorTy_4); -FunctionType* FuncTy_5 = FunctionType::get( - /*Result=*/VectorTy_4, - /*Params=*/FuncTy_5_args, - /*isVarArg=*/false); - -std::vectorFuncTy_6_args; -FuncTy_6_args.push_back(VectorTy_4); -FuncTy_6_args.push_back(VectorTy_4); -FuncTy_6_args.push_back(VectorTy_4); -FunctionType* FuncTy_6 = FunctionType::get( - /*Result=*/VectorTy_4, - /*Params=*/FuncTy_6_args, - /*isVarArg=*/false); - -VectorType* VectorTy_7 = VectorType::get(IntegerType::get(32), 4); - -std::vectorFuncTy_9_args; -FunctionType* FuncTy_9 = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/FuncTy_9_args, - /*isVarArg=*/true); - -PointerType* PointerTy_8 = PointerType::get(FuncTy_9, 0); - -PointerType* PointerTy_10 = PointerType::get(IntegerType::get(8), 0); - -std::vectorFuncTy_12_args; -FuncTy_12_args.push_back(Type::FloatTy); -FunctionType* FuncTy_12 = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/FuncTy_12_args, - /*isVarArg=*/false); - -PointerType* PointerTy_11 = PointerType::get(FuncTy_12, 0); - -std::vectorFuncTy_13_args; -FuncTy_13_args.push_back(VectorTy_4); -FunctionType* FuncTy_13 = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/FuncTy_13_args, - /*isVarArg=*/false); - - -// Function Declarations - -Function* func_approx = new Function( - /*Type=*/FuncTy_2, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"approx", mod); -func_approx->setCallingConv(CallingConv::C); -const ParamAttrsList *func_approx_PAL = 0; -func_approx->setParamAttrs(func_approx_PAL); - -Function* func_powf = new Function( - /*Type=*/FuncTy_2, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"powf", mod); // (external, no body) -func_powf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_powf_PAL = 0; -func_powf->setParamAttrs(func_powf_PAL); - -Function* func_lit = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"lit", mod); -func_lit->setCallingConv(CallingConv::C); -const ParamAttrsList *func_lit_PAL = 0; -func_lit->setParamAttrs(func_lit_PAL); - -Function* func_cmp = new Function( - /*Type=*/FuncTy_6, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"cmp", mod); -func_cmp->setCallingConv(CallingConv::C); -const ParamAttrsList *func_cmp_PAL = 0; -{ - ParamAttrsVector Attrs; - ParamAttrsWithIndex PAWI; - PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; - Attrs.push_back(PAWI); - func_cmp_PAL = ParamAttrsList::get(Attrs); - -} -func_cmp->setParamAttrs(func_cmp_PAL); - -Function* func_vcos = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"vcos", mod); -func_vcos->setCallingConv(CallingConv::C); -const ParamAttrsList *func_vcos_PAL = 0; -func_vcos->setParamAttrs(func_vcos_PAL); - -Function* func_printf = new Function( - /*Type=*/FuncTy_9, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"printf", mod); // (external, no body) -func_printf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_printf_PAL = 0; -func_printf->setParamAttrs(func_printf_PAL); - -Function* func_cosf = new Function( - /*Type=*/FuncTy_12, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"cosf", mod); // (external, no body) -func_cosf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_cosf_PAL = 0; -func_cosf->setParamAttrs(func_cosf_PAL); - -Function* func_scs = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"scs", mod); -func_scs->setCallingConv(CallingConv::C); -const ParamAttrsList *func_scs_PAL = 0; -func_scs->setParamAttrs(func_scs_PAL); - -Function* func_sinf = new Function( - /*Type=*/FuncTy_12, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"sinf", mod); // (external, no body) -func_sinf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_sinf_PAL = 0; -func_sinf->setParamAttrs(func_sinf_PAL); - -Function* func_vsin = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"vsin", mod); -func_vsin->setCallingConv(CallingConv::C); -const ParamAttrsList *func_vsin_PAL = 0; -func_vsin->setParamAttrs(func_vsin_PAL); - -Function* func_kilp = new Function( - /*Type=*/FuncTy_13, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"kilp", mod); -func_kilp->setCallingConv(CallingConv::C); -const ParamAttrsList *func_kilp_PAL = 0; -{ - ParamAttrsVector Attrs; - ParamAttrsWithIndex PAWI; - PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; - Attrs.push_back(PAWI); - func_kilp_PAL = ParamAttrsList::get(Attrs); - -} -func_kilp->setParamAttrs(func_kilp_PAL); - -// Global Variable Declarations - - -GlobalVariable* gvar_array__str = new GlobalVariable( -/*Type=*/ArrayTy_0, -/*isConstant=*/true, -/*Linkage=*/GlobalValue::InternalLinkage, -/*Initializer=*/0, // has initializer, specified below -/*Name=*/".str", -mod); - -GlobalVariable* gvar_array__str1 = new GlobalVariable( -/*Type=*/ArrayTy_0, -/*isConstant=*/true, -/*Linkage=*/GlobalValue::InternalLinkage, -/*Initializer=*/0, // has initializer, specified below -/*Name=*/".str1", -mod); - -// Constant Definitions -Constant* const_array_14 = ConstantArray::get("VEC IN is %f %f %f %f\x0A", true); -Constant* const_array_15 = ConstantArray::get("VEC OUT is %f %f %f %f\x0A", true); -ConstantFP* const_float_16 = ConstantFP::get(Type::FloatTy, APFloat(-1.280000e+02f)); -ConstantFP* const_float_17 = ConstantFP::get(Type::FloatTy, APFloat(1.280000e+02f)); -Constant* const_float_18 = Constant::getNullValue(Type::FloatTy); -Constant* const_int32_19 = Constant::getNullValue(IntegerType::get(32)); -std::vector const_packed_20_elems; -ConstantFP* const_float_21 = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); -const_packed_20_elems.push_back(const_float_21); -UndefValue* const_float_22 = UndefValue::get(Type::FloatTy); -const_packed_20_elems.push_back(const_float_22); -const_packed_20_elems.push_back(const_float_22); -const_packed_20_elems.push_back(const_float_21); -Constant* const_packed_20 = ConstantVector::get(VectorTy_4, const_packed_20_elems); -ConstantInt* const_int32_23 = ConstantInt::get(APInt(32, "1", 10)); -ConstantInt* const_int32_24 = ConstantInt::get(APInt(32, "3", 10)); -ConstantInt* const_int32_25 = ConstantInt::get(APInt(32, "2", 10)); -std::vector const_packed_26_elems; -const_packed_26_elems.push_back(const_float_21); -const_packed_26_elems.push_back(const_float_18); -const_packed_26_elems.push_back(const_float_18); -const_packed_26_elems.push_back(const_float_21); -Constant* const_packed_26 = ConstantVector::get(VectorTy_4, const_packed_26_elems); -Constant* const_double_27 = Constant::getNullValue(Type::DoubleTy); -std::vector const_packed_28_elems; -const_packed_28_elems.push_back(const_int32_19); -ConstantInt* const_int32_29 = ConstantInt::get(APInt(32, "5", 10)); -const_packed_28_elems.push_back(const_int32_29); -const_packed_28_elems.push_back(const_int32_25); -const_packed_28_elems.push_back(const_int32_24); -Constant* const_packed_28 = ConstantVector::get(VectorTy_7, const_packed_28_elems); -std::vector const_packed_30_elems; -const_packed_30_elems.push_back(const_int32_19); -const_packed_30_elems.push_back(const_int32_23); -ConstantInt* const_int32_31 = ConstantInt::get(APInt(32, "6", 10)); -const_packed_30_elems.push_back(const_int32_31); -const_packed_30_elems.push_back(const_int32_24); -Constant* const_packed_30 = ConstantVector::get(VectorTy_7, const_packed_30_elems); -std::vector const_packed_32_elems; -const_packed_32_elems.push_back(const_int32_19); -const_packed_32_elems.push_back(const_int32_23); -const_packed_32_elems.push_back(const_int32_25); -ConstantInt* const_int32_33 = ConstantInt::get(APInt(32, "7", 10)); -const_packed_32_elems.push_back(const_int32_33); -Constant* const_packed_32 = ConstantVector::get(VectorTy_7, const_packed_32_elems); -std::vector const_ptr_34_indices; -const_ptr_34_indices.push_back(const_int32_19); -const_ptr_34_indices.push_back(const_int32_19); -Constant* const_ptr_34 = ConstantExpr::getGetElementPtr(gvar_array__str, &const_ptr_34_indices[0], const_ptr_34_indices.size() ); -UndefValue* const_packed_35 = UndefValue::get(VectorTy_4); -std::vector const_ptr_36_indices; -const_ptr_36_indices.push_back(const_int32_19); -const_ptr_36_indices.push_back(const_int32_19); -Constant* const_ptr_36 = ConstantExpr::getGetElementPtr(gvar_array__str1, &const_ptr_36_indices[0], const_ptr_36_indices.size() ); - -// Global Variable Definitions -gvar_array__str->setInitializer(const_array_14); -gvar_array__str1->setInitializer(const_array_15); - -// Function Definitions - -// Function: approx (func_approx) -{ - Function::arg_iterator args = func_approx->arg_begin(); - Value* float_a = args++; - float_a->setName("a"); - Value* float_b = args++; - float_b->setName("b"); - - BasicBlock* label_entry = new BasicBlock("entry",func_approx,0); - - // Block entry (label_entry) - FCmpInst* int1_cmp = new FCmpInst(FCmpInst::FCMP_OLT, float_b, const_float_16, "cmp", label_entry); - SelectInst* float_b_addr_0 = new SelectInst(int1_cmp, const_float_16, float_b, "b.addr.0", label_entry); - FCmpInst* int1_cmp3 = new FCmpInst(FCmpInst::FCMP_OGT, float_b_addr_0, const_float_17, "cmp3", label_entry); - SelectInst* float_b_addr_1 = new SelectInst(int1_cmp3, const_float_17, float_b_addr_0, "b.addr.1", label_entry); - FCmpInst* int1_cmp7 = new FCmpInst(FCmpInst::FCMP_OLT, float_a, const_float_18, "cmp7", label_entry); - SelectInst* float_a_addr_0 = new SelectInst(int1_cmp7, const_float_18, float_a, "a.addr.0", label_entry); - std::vector float_call_params; - float_call_params.push_back(float_a_addr_0); - float_call_params.push_back(float_b_addr_1); - CallInst* float_call = new CallInst(func_powf, float_call_params.begin(), float_call_params.end(), "call", label_entry); - float_call->setCallingConv(CallingConv::C); - float_call->setTailCall(true);const ParamAttrsList *float_call_PAL = 0; - float_call->setParamAttrs(float_call_PAL); - - new ReturnInst(float_call, label_entry); - -} - -// Function: lit (func_lit) -{ - Function::arg_iterator args = func_lit->arg_begin(); - Value* packed_tmp = args++; - packed_tmp->setName("tmp"); - - BasicBlock* label_entry_38 = new BasicBlock("entry",func_lit,0); - BasicBlock* label_ifthen = new BasicBlock("ifthen",func_lit,0); - BasicBlock* label_UnifiedReturnBlock = new BasicBlock("UnifiedReturnBlock",func_lit,0); - - // Block entry (label_entry_38) - ExtractElementInst* float_tmp6 = new ExtractElementInst(packed_tmp, const_int32_19, "tmp6", label_entry_38); - FCmpInst* int1_cmp_39 = new FCmpInst(FCmpInst::FCMP_OGT, float_tmp6, const_float_18, "cmp", label_entry_38); - new BranchInst(label_ifthen, label_UnifiedReturnBlock, int1_cmp_39, label_entry_38); - - // Block ifthen (label_ifthen) - InsertElementInst* packed_tmp10 = new InsertElementInst(const_packed_20, float_tmp6, const_int32_23, "tmp10", label_ifthen); - ExtractElementInst* float_tmp12 = new ExtractElementInst(packed_tmp, const_int32_23, "tmp12", label_ifthen); - ExtractElementInst* float_tmp14 = new ExtractElementInst(packed_tmp, const_int32_24, "tmp14", label_ifthen); - std::vector float_call_41_params; - float_call_41_params.push_back(float_tmp12); - float_call_41_params.push_back(float_tmp14); - CallInst* float_call_41 = new CallInst(func_approx, float_call_41_params.begin(), float_call_41_params.end(), "call", label_ifthen); - float_call_41->setCallingConv(CallingConv::C); - float_call_41->setTailCall(true);const ParamAttrsList *float_call_41_PAL = 0; - float_call_41->setParamAttrs(float_call_41_PAL); - - InsertElementInst* packed_tmp16 = new InsertElementInst(packed_tmp10, float_call_41, const_int32_25, "tmp16", label_ifthen); - new ReturnInst(packed_tmp16, label_ifthen); - - // Block UnifiedReturnBlock (label_UnifiedReturnBlock) - new ReturnInst(const_packed_26, label_UnifiedReturnBlock); - -} - -// Function: cmp (func_cmp) -{ - Function::arg_iterator args = func_cmp->arg_begin(); - Value* packed_tmp0 = args++; - packed_tmp0->setName("tmp0"); - Value* packed_tmp1 = args++; - packed_tmp1->setName("tmp1"); - Value* packed_tmp2 = args++; - packed_tmp2->setName("tmp2"); - - BasicBlock* label_entry_44 = new BasicBlock("entry",func_cmp,0); - BasicBlock* label_cond__14 = new BasicBlock("cond.?14",func_cmp,0); - BasicBlock* label_cond_cont20 = new BasicBlock("cond.cont20",func_cmp,0); - BasicBlock* label_cond__28 = new BasicBlock("cond.?28",func_cmp,0); - BasicBlock* label_cond_cont34 = new BasicBlock("cond.cont34",func_cmp,0); - BasicBlock* label_cond__42 = new BasicBlock("cond.?42",func_cmp,0); - BasicBlock* label_cond_cont48 = new BasicBlock("cond.cont48",func_cmp,0); - - // Block entry (label_entry_44) - ExtractElementInst* float_tmp3 = new ExtractElementInst(packed_tmp0, const_int32_19, "tmp3", label_entry_44); - CastInst* double_conv = new FPExtInst(float_tmp3, Type::DoubleTy, "conv", label_entry_44); - FCmpInst* int1_cmp_45 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv, const_double_27, "cmp", label_entry_44); - ExtractElementInst* float_tmp11 = new ExtractElementInst(packed_tmp0, const_int32_23, "tmp11", label_entry_44); - CastInst* double_conv12 = new FPExtInst(float_tmp11, Type::DoubleTy, "conv12", label_entry_44); - FCmpInst* int1_cmp13 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv12, const_double_27, "cmp13", label_entry_44); - SelectInst* packed_tmp1_tmp2 = new SelectInst(int1_cmp_45, packed_tmp1, packed_tmp2, "tmp1.tmp2", label_entry_44); - new BranchInst(label_cond__14, label_cond_cont20, int1_cmp13, label_entry_44); - - // Block cond.?14 (label_cond__14) - ShuffleVectorInst* packed_tmp233 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp1, const_packed_28, "tmp233", label_cond__14); - ExtractElementInst* float_tmp254 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp254", label_cond__14); - CastInst* double_conv265 = new FPExtInst(float_tmp254, Type::DoubleTy, "conv265", label_cond__14); - FCmpInst* int1_cmp276 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv265, const_double_27, "cmp276", label_cond__14); - new BranchInst(label_cond__28, label_cond_cont34, int1_cmp276, label_cond__14); - - // Block cond.cont20 (label_cond_cont20) - ShuffleVectorInst* packed_tmp23 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp2, const_packed_28, "tmp23", label_cond_cont20); - ExtractElementInst* float_tmp25 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp25", label_cond_cont20); - CastInst* double_conv26 = new FPExtInst(float_tmp25, Type::DoubleTy, "conv26", label_cond_cont20); - FCmpInst* int1_cmp27 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv26, const_double_27, "cmp27", label_cond_cont20); - new BranchInst(label_cond__28, label_cond_cont34, int1_cmp27, label_cond_cont20); - - // Block cond.?28 (label_cond__28) - PHINode* packed_tmp23_reg2mem_0 = new PHINode(VectorTy_4, "tmp23.reg2mem.0", label_cond__28); - packed_tmp23_reg2mem_0->reserveOperandSpace(2); - packed_tmp23_reg2mem_0->addIncoming(packed_tmp233, label_cond__14); - packed_tmp23_reg2mem_0->addIncoming(packed_tmp23, label_cond_cont20); - - ShuffleVectorInst* packed_tmp378 = new ShuffleVectorInst(packed_tmp23_reg2mem_0, packed_tmp1, const_packed_30, "tmp378", label_cond__28); - ExtractElementInst* float_tmp399 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp399", label_cond__28); - CastInst* double_conv4010 = new FPExtInst(float_tmp399, Type::DoubleTy, "conv4010", label_cond__28); - FCmpInst* int1_cmp4111 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv4010, const_double_27, "cmp4111", label_cond__28); - new BranchInst(label_cond__42, label_cond_cont48, int1_cmp4111, label_cond__28); - - // Block cond.cont34 (label_cond_cont34) - PHINode* packed_tmp23_reg2mem_1 = new PHINode(VectorTy_4, "tmp23.reg2mem.1", label_cond_cont34); - packed_tmp23_reg2mem_1->reserveOperandSpace(2); - packed_tmp23_reg2mem_1->addIncoming(packed_tmp233, label_cond__14); - packed_tmp23_reg2mem_1->addIncoming(packed_tmp23, label_cond_cont20); - - ShuffleVectorInst* packed_tmp37 = new ShuffleVectorInst(packed_tmp23_reg2mem_1, packed_tmp2, const_packed_30, "tmp37", label_cond_cont34); - ExtractElementInst* float_tmp39 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp39", label_cond_cont34); - CastInst* double_conv40 = new FPExtInst(float_tmp39, Type::DoubleTy, "conv40", label_cond_cont34); - FCmpInst* int1_cmp41 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv40, const_double_27, "cmp41", label_cond_cont34); - new BranchInst(label_cond__42, label_cond_cont48, int1_cmp41, label_cond_cont34); - - // Block cond.?42 (label_cond__42) - PHINode* packed_tmp37_reg2mem_0 = new PHINode(VectorTy_4, "tmp37.reg2mem.0", label_cond__42); - packed_tmp37_reg2mem_0->reserveOperandSpace(2); - packed_tmp37_reg2mem_0->addIncoming(packed_tmp378, label_cond__28); - packed_tmp37_reg2mem_0->addIncoming(packed_tmp37, label_cond_cont34); - - ShuffleVectorInst* packed_tmp5113 = new ShuffleVectorInst(packed_tmp37_reg2mem_0, packed_tmp1, const_packed_32, "tmp5113", label_cond__42); - new ReturnInst(packed_tmp5113, label_cond__42); - - // Block cond.cont48 (label_cond_cont48) - PHINode* packed_tmp37_reg2mem_1 = new PHINode(VectorTy_4, "tmp37.reg2mem.1", label_cond_cont48); - packed_tmp37_reg2mem_1->reserveOperandSpace(2); - packed_tmp37_reg2mem_1->addIncoming(packed_tmp378, label_cond__28); - packed_tmp37_reg2mem_1->addIncoming(packed_tmp37, label_cond_cont34); - - ShuffleVectorInst* packed_tmp51 = new ShuffleVectorInst(packed_tmp37_reg2mem_1, packed_tmp2, const_packed_32, "tmp51", label_cond_cont48); - new ReturnInst(packed_tmp51, label_cond_cont48); - -} - -// Function: vcos (func_vcos) -{ - Function::arg_iterator args = func_vcos->arg_begin(); - Value* packed_val = args++; - packed_val->setName("val"); - - BasicBlock* label_entry_53 = new BasicBlock("entry",func_vcos,0); - - // Block entry (label_entry_53) - ExtractElementInst* float_tmp1 = new ExtractElementInst(packed_val, const_int32_19, "tmp1", label_entry_53); - CastInst* double_conv_54 = new FPExtInst(float_tmp1, Type::DoubleTy, "conv", label_entry_53); - ExtractElementInst* float_tmp3_55 = new ExtractElementInst(packed_val, const_int32_23, "tmp3", label_entry_53); - CastInst* double_conv4 = new FPExtInst(float_tmp3_55, Type::DoubleTy, "conv4", label_entry_53); - ExtractElementInst* float_tmp6_56 = new ExtractElementInst(packed_val, const_int32_25, "tmp6", label_entry_53); - CastInst* double_conv7 = new FPExtInst(float_tmp6_56, Type::DoubleTy, "conv7", label_entry_53); - ExtractElementInst* float_tmp9 = new ExtractElementInst(packed_val, const_int32_24, "tmp9", label_entry_53); - CastInst* double_conv10 = new FPExtInst(float_tmp9, Type::DoubleTy, "conv10", label_entry_53); - std::vector int32_call_params; - int32_call_params.push_back(const_ptr_34); - int32_call_params.push_back(double_conv_54); - int32_call_params.push_back(double_conv4); - int32_call_params.push_back(double_conv7); - int32_call_params.push_back(double_conv10); - CallInst* int32_call = new CallInst(func_printf, int32_call_params.begin(), int32_call_params.end(), "call", label_entry_53); - int32_call->setCallingConv(CallingConv::C); - int32_call->setTailCall(true);const ParamAttrsList *int32_call_PAL = 0; - int32_call->setParamAttrs(int32_call_PAL); - - CallInst* float_call13 = new CallInst(func_cosf, float_tmp1, "call13", label_entry_53); - float_call13->setCallingConv(CallingConv::C); - float_call13->setTailCall(true);const ParamAttrsList *float_call13_PAL = 0; - float_call13->setParamAttrs(float_call13_PAL); - - InsertElementInst* packed_tmp15 = new InsertElementInst(const_packed_35, float_call13, const_int32_19, "tmp15", label_entry_53); - CallInst* float_call18 = new CallInst(func_cosf, float_tmp1, "call18", label_entry_53); - float_call18->setCallingConv(CallingConv::C); - float_call18->setTailCall(true);const ParamAttrsList *float_call18_PAL = 0; - float_call18->setParamAttrs(float_call18_PAL); - - InsertElementInst* packed_tmp20 = new InsertElementInst(packed_tmp15, float_call18, const_int32_23, "tmp20", label_entry_53); - CallInst* float_call23 = new CallInst(func_cosf, float_tmp1, "call23", label_entry_53); - float_call23->setCallingConv(CallingConv::C); - float_call23->setTailCall(true);const ParamAttrsList *float_call23_PAL = 0; - float_call23->setParamAttrs(float_call23_PAL); - - InsertElementInst* packed_tmp25 = new InsertElementInst(packed_tmp20, float_call23, const_int32_25, "tmp25", label_entry_53); - CallInst* float_call28 = new CallInst(func_cosf, float_tmp1, "call28", label_entry_53); - float_call28->setCallingConv(CallingConv::C); - float_call28->setTailCall(true);const ParamAttrsList *float_call28_PAL = 0; - float_call28->setParamAttrs(float_call28_PAL); - - InsertElementInst* packed_tmp30 = new InsertElementInst(packed_tmp25, float_call28, const_int32_24, "tmp30", label_entry_53); - CastInst* double_conv33 = new FPExtInst(float_call13, Type::DoubleTy, "conv33", label_entry_53); - CastInst* double_conv36 = new FPExtInst(float_call18, Type::DoubleTy, "conv36", label_entry_53); - CastInst* double_conv39 = new FPExtInst(float_call23, Type::DoubleTy, "conv39", label_entry_53); - CastInst* double_conv42 = new FPExtInst(float_call28, Type::DoubleTy, "conv42", label_entry_53); - std::vector int32_call43_params; - int32_call43_params.push_back(const_ptr_36); - int32_call43_params.push_back(double_conv33); - int32_call43_params.push_back(double_conv36); - int32_call43_params.push_back(double_conv39); - int32_call43_params.push_back(double_conv42); - CallInst* int32_call43 = new CallInst(func_printf, int32_call43_params.begin(), int32_call43_params.end(), "call43", label_entry_53); - int32_call43->setCallingConv(CallingConv::C); - int32_call43->setTailCall(true);const ParamAttrsList *int32_call43_PAL = 0; - int32_call43->setParamAttrs(int32_call43_PAL); - - new ReturnInst(packed_tmp30, label_entry_53); - -} - -// Function: scs (func_scs) -{ - Function::arg_iterator args = func_scs->arg_begin(); - Value* packed_val_58 = args++; - packed_val_58->setName("val"); - - BasicBlock* label_entry_59 = new BasicBlock("entry",func_scs,0); - - // Block entry (label_entry_59) - ExtractElementInst* float_tmp2 = new ExtractElementInst(packed_val_58, const_int32_19, "tmp2", label_entry_59); - CallInst* float_call_60 = new CallInst(func_cosf, float_tmp2, "call", label_entry_59); - float_call_60->setCallingConv(CallingConv::C); - float_call_60->setTailCall(true);const ParamAttrsList *float_call_60_PAL = 0; - float_call_60->setParamAttrs(float_call_60_PAL); - - InsertElementInst* packed_tmp5 = new InsertElementInst(const_packed_35, float_call_60, const_int32_19, "tmp5", label_entry_59); - CallInst* float_call7 = new CallInst(func_sinf, float_tmp2, "call7", label_entry_59); - float_call7->setCallingConv(CallingConv::C); - float_call7->setTailCall(true);const ParamAttrsList *float_call7_PAL = 0; - float_call7->setParamAttrs(float_call7_PAL); - - InsertElementInst* packed_tmp9 = new InsertElementInst(packed_tmp5, float_call7, const_int32_23, "tmp9", label_entry_59); - new ReturnInst(packed_tmp9, label_entry_59); - -} - -// Function: vsin (func_vsin) -{ - Function::arg_iterator args = func_vsin->arg_begin(); - Value* packed_val_62 = args++; - packed_val_62->setName("val"); - - BasicBlock* label_entry_63 = new BasicBlock("entry",func_vsin,0); - - // Block entry (label_entry_63) - ExtractElementInst* float_tmp2_64 = new ExtractElementInst(packed_val_62, const_int32_19, "tmp2", label_entry_63); - CallInst* float_call_65 = new CallInst(func_sinf, float_tmp2_64, "call", label_entry_63); - float_call_65->setCallingConv(CallingConv::C); - float_call_65->setTailCall(true);const ParamAttrsList *float_call_65_PAL = 0; - float_call_65->setParamAttrs(float_call_65_PAL); - - InsertElementInst* packed_tmp6 = new InsertElementInst(const_packed_35, float_call_65, const_int32_19, "tmp6", label_entry_63); - InsertElementInst* packed_tmp9_66 = new InsertElementInst(packed_tmp6, float_call_65, const_int32_23, "tmp9", label_entry_63); - InsertElementInst* packed_tmp12 = new InsertElementInst(packed_tmp9_66, float_call_65, const_int32_25, "tmp12", label_entry_63); - InsertElementInst* packed_tmp15_67 = new InsertElementInst(packed_tmp12, float_call_65, const_int32_24, "tmp15", label_entry_63); - new ReturnInst(packed_tmp15_67, label_entry_63); - -} - -// Function: kilp (func_kilp) -{ - Function::arg_iterator args = func_kilp->arg_begin(); - Value* packed_val_69 = args++; - packed_val_69->setName("val"); - - BasicBlock* label_entry_70 = new BasicBlock("entry",func_kilp,0); - BasicBlock* label_lor_rhs = new BasicBlock("lor_rhs",func_kilp,0); - BasicBlock* label_lor_rhs5 = new BasicBlock("lor_rhs5",func_kilp,0); - BasicBlock* label_lor_rhs11 = new BasicBlock("lor_rhs11",func_kilp,0); - BasicBlock* label_UnifiedReturnBlock_71 = new BasicBlock("UnifiedReturnBlock",func_kilp,0); - - // Block entry (label_entry_70) - ExtractElementInst* float_tmp1_72 = new ExtractElementInst(packed_val_69, const_int32_19, "tmp1", label_entry_70); - FCmpInst* int1_cmp_73 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp1_72, const_float_18, "cmp", label_entry_70); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs, int1_cmp_73, label_entry_70); - - // Block lor_rhs (label_lor_rhs) - ExtractElementInst* float_tmp3_75 = new ExtractElementInst(packed_val_69, const_int32_23, "tmp3", label_lor_rhs); - FCmpInst* int1_cmp4 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp3_75, const_float_18, "cmp4", label_lor_rhs); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs5, int1_cmp4, label_lor_rhs); - - // Block lor_rhs5 (label_lor_rhs5) - ExtractElementInst* float_tmp7 = new ExtractElementInst(packed_val_69, const_int32_25, "tmp7", label_lor_rhs5); - FCmpInst* int1_cmp8 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp7, const_float_18, "cmp8", label_lor_rhs5); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs11, int1_cmp8, label_lor_rhs5); - - // Block lor_rhs11 (label_lor_rhs11) - ExtractElementInst* float_tmp13 = new ExtractElementInst(packed_val_69, const_int32_24, "tmp13", label_lor_rhs11); - FCmpInst* int1_cmp14 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp13, const_float_18, "cmp14", label_lor_rhs11); - CastInst* int32_retval = new ZExtInst(int1_cmp14, IntegerType::get(32), "retval", label_lor_rhs11); - new ReturnInst(int32_retval, label_lor_rhs11); - - // Block UnifiedReturnBlock (label_UnifiedReturnBlock_71) - new ReturnInst(const_int32_23, label_UnifiedReturnBlock_71); - -} - -return mod; - -} +static const unsigned char llvm_builtins_data[] = { +0x42,0x43,0xc0,0xde,0x21,0x0c,0x00,0x00,0x2b,0x02,0x00,0x00,0x01,0x10,0x00,0x00, +0x10,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,0x06,0x10,0x32,0x39, +0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,0x80,0x14,0x45,0x02, +0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,0x0a,0x32,0x44,0x24, +0x48,0x0a,0x90,0x21,0x23,0x44,0x72,0x80,0x8c,0x14,0x21,0x86,0x0a,0x8a,0x0a,0x64, +0x0c,0x1f,0x00,0x00,0x49,0x18,0x00,0x00,0x02,0x00,0x00,0x00,0x0b,0x04,0x00,0x0c, +0x00,0x00,0x00,0x00,0x51,0x20,0x00,0x00,0x13,0x00,0x00,0x00,0x32,0x22,0x48,0x09, +0x20,0x65,0x82,0x84,0x00,0x26,0x45,0x48,0x05,0x09,0x26,0x45,0xc6,0x05,0x42,0x52, +0x26,0x08,0xb0,0x19,0x80,0x61,0x04,0x02,0x98,0x23,0x00,0x83,0x21,0x80,0x39,0x82, +0x60,0x0a,0x80,0x2e,0xd5,0x61,0x04,0x42,0x20,0x49,0x90,0x22,0x4d,0xa2,0x73,0x04, +0x08,0xb9,0x32,0x00,0x00,0x8a,0x10,0xc2,0x65,0xb8,0x42,0x84,0x10,0x42,0x0d,0x44, +0x11,0x00,0x18,0x01,0x28,0x82,0x08,0x00,0x13,0xa2,0x74,0xb0,0x03,0x3c,0xb0,0x83, +0x36,0x80,0x87,0x71,0x68,0x03,0x76,0x48,0x07,0x77,0xa8,0x07,0x7c,0x68,0x83,0x73, +0x70,0x87,0x7a,0xd8,0x70,0x0f,0xe5,0xd0,0x06,0xf0,0xa0,0x07,0x73,0x20,0x07,0x7a, +0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x90,0x0e,0x71,0xa0,0x07,0x78,0xa0, +0x07,0x78,0xd0,0x06,0xe9,0x80,0x07,0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e, +0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x6d,0x90,0x0e,0x73, +0x20,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x90,0x0e,0x76,0x40, +0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0e,0x73,0x20,0x07, +0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,0x0e,0x76,0x40,0x07,0x7a, +0x30,0x07,0x72,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x76,0x40,0x07,0x7a,0x60, +0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x71,0x20,0x07,0x78,0xa0,0x07, +0x71,0x20,0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xd0,0x06,0xe1,0x00,0x07,0x7a, +0x00,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xe6,0x80,0x07,0x70,0xa0,0x07,0x71,0x20, +0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xa0,0xf3,0x40,0x88,0x04,0x32,0x32,0x02, +0x04,0x60,0x76,0xc6,0xfc,0x6c,0x48,0xa2,0x00,0x40,0x00,0x00,0x00,0x00,0x0c,0x49, +0x14,0x20,0x00,0x00,0x00,0x00,0x80,0x21,0xc9,0x02,0x00,0x01,0x00,0x00,0x00,0x30, +0x24,0x61,0x00,0x20,0x08,0x00,0x00,0x00,0x86,0x24,0x0b,0x00,0x04,0x00,0x00,0x00, +0xc0,0x90,0xa4,0x01,0x02,0x00,0x00,0x00,0x00,0x18,0x92,0x1c,0x40,0x00,0x00,0x00, +0x00,0x00,0x43,0x92,0x05,0x00,0x02,0x00,0x00,0x00,0x60,0x48,0x72,0x00,0x01,0x00, +0x00,0x00,0x00,0x0c,0x49,0x16,0x00,0x08,0x00,0x00,0x00,0x80,0x21,0x89,0x01,0x00, +0x41,0x00,0x00,0x00,0x90,0x05,0x02,0x00,0x10,0x00,0x00,0x00,0x32,0x1e,0x98,0x10, +0x19,0x11,0x4c,0x90,0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x92,0x8a,0x59,0x8b,0x43, +0x50,0xd2,0x09,0x02,0x81,0xd2,0x73,0x50,0xc9,0x0c,0x2a,0x99,0x41,0x25,0x33,0xa8, +0x64,0x56,0x28,0x66,0x2d,0x0e,0x41,0xcf,0x2a,0x15,0x04,0x4a,0xcf,0x41,0x25,0x33, +0xa8,0x64,0x06,0x95,0xcc,0xa0,0x92,0x59,0x01,0x00,0x00,0x00,0x53,0x82,0x26,0x0c, +0x04,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00, +0x05,0x00,0x00,0x00,0x04,0xc6,0x08,0x40,0x10,0x04,0xe1,0x70,0x18,0x23,0x00,0x41, +0x10,0x84,0xc3,0x60,0x04,0x00,0x00,0x00,0x93,0x0c,0xce,0x43,0x4c,0x31,0x3c,0x8e, +0x34,0xc9,0x30,0x41,0xc2,0x14,0x03,0x34,0x51,0x93,0x0c,0x4d,0x44,0x4c,0x31,0x44, +0x8d,0x35,0x56,0x01,0x04,0xc3,0x55,0x21,0x16,0x0e,0x04,0x00,0x0f,0x00,0x00,0x00, +0x46,0x41,0x08,0xcc,0x73,0x9b,0x05,0x21,0x30,0xcf,0x6e,0x18,0x84,0x00,0x2c,0x8b, +0x35,0x04,0x80,0x39,0x04,0x81,0x5d,0x20,0x80,0x0f,0x0c,0x43,0xe4,0xd3,0x36,0x81, +0x04,0x3e,0x30,0x0c,0x91,0x4f,0x5b,0x05,0x12,0xf8,0xc0,0x30,0x44,0x7e,0x7d,0x00, +0x05,0xd1,0x4c,0x11,0x66,0x12,0x83,0xc0,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x61,0x20,0x00,0x00,0x2a,0x00,0x00,0x00,0x13,0x04,0x43,0x2c,0x10,0x00,0x00,0x00, +0x08,0x00,0x00,0x00,0x24,0x8a,0xa0,0x0c,0x46,0x00,0x4a,0x80,0xc2,0x1c,0x84,0x55, +0x55,0xd6,0x1c,0x84,0x45,0x51,0x16,0x81,0x19,0x80,0x11,0x80,0x31,0x02,0x10,0x04, +0x41,0xfc,0x03,0x00,0x63,0x08,0x0d,0x34,0xc9,0x70,0x55,0xc2,0x2c,0x43,0x20,0x60, +0x73,0x0c,0xd3,0x15,0x8d,0x21,0x34,0xd1,0x18,0x42,0xf3,0x8c,0x55,0x00,0x81,0xa0, +0x6d,0x73,0x0c,0x19,0xe7,0x60,0x87,0x52,0x38,0x10,0x00,0x00,0x13,0x00,0x00,0x00, +0x17,0x60,0x20,0xc5,0x74,0x10,0x8d,0x65,0x14,0x13,0xf3,0xd4,0xb4,0x6d,0x14,0x13, +0xf3,0xd4,0xb8,0x69,0x14,0x13,0xf3,0xd4,0xb6,0x75,0x14,0x13,0xf3,0xd4,0xba,0x35, +0x0c,0x13,0xf3,0x9c,0x80,0xe4,0x36,0x48,0x81,0x10,0xc3,0x4a,0x4c,0x54,0xd4,0x6c, +0x8b,0x23,0x28,0x76,0x41,0x4c,0xcc,0xa3,0x1b,0x07,0x21,0x00,0xcb,0x72,0x00,0x05, +0xd1,0x4c,0x11,0x66,0x18,0x83,0xc0,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x61,0x20,0x00,0x00,0x82,0x00,0x00,0x00,0x13,0x04,0x47,0x2c,0x10,0x00,0x00,0x00, +0x08,0x00,0x00,0x00,0x24,0x46,0x00,0x8a,0xa0,0x0c,0x4a,0xa0,0x14,0x8a,0xa1,0x1c, +0x68,0x8c,0x00,0x10,0x9a,0x83,0x80,0xa8,0x48,0x9a,0x83,0x80,0xa6,0x4a,0x9a,0x83, +0x80,0xa6,0xc8,0x02,0x63,0x08,0x0d,0x64,0xdb,0xc0,0x49,0x06,0xee,0x22,0xc6,0x10, +0x9a,0xc9,0xbc,0x81,0x93,0x0c,0xdf,0x45,0x4c,0x31,0x38,0x4f,0x37,0xcb,0x10,0x08, +0x60,0x30,0xc8,0x10,0x06,0x0e,0x36,0x86,0xd0,0x44,0x36,0x06,0x03,0x27,0x19,0xc8, +0xe0,0x22,0x66,0x19,0x06,0xa2,0x0c,0x06,0x19,0xc2,0xe0,0xc1,0xc6,0x10,0x9a,0xc8, +0xce,0x60,0xe0,0x24,0x03,0x1a,0x5c,0xc4,0x2c,0xc3,0x40,0xa4,0xc1,0x40,0x45,0x20, +0x06,0x81,0x19,0x08,0x83,0x0c,0x6a,0xe0,0x64,0x63,0x08,0x8d,0x64,0x6c,0x30,0x70, +0x92,0xa1,0x0d,0x2e,0x62,0x96,0xa1,0x30,0xdc,0x60,0xa0,0x22,0x10,0x83,0xc0,0x0c, +0x84,0x41,0x86,0x37,0x78,0xb2,0x31,0x84,0x46,0xb2,0x38,0x18,0x38,0xc9,0x20,0x07, +0x17,0x31,0xcb,0x50,0x18,0x73,0x30,0x50,0x11,0xac,0xc1,0x00,0x07,0xc4,0x20,0x03, +0x1d,0x38,0x1a,0xd6,0xc1,0x40,0x45,0xb0,0x06,0x03,0x1c,0x10,0x83,0x0c,0x76,0xf0, +0x68,0x78,0x07,0xe1,0x40,0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x56,0x62,0x08,0xcc, +0x63,0xef,0x3a,0xa9,0x00,0x19,0x7b,0x73,0x23,0x73,0xf9,0xa1,0x91,0x31,0x98,0x62, +0x62,0x9e,0x7b,0xb7,0x06,0x62,0x62,0x1e,0xda,0x1c,0x88,0x89,0x79,0x6a,0x7b,0x20, +0x26,0xe6,0xb1,0x6d,0x83,0x98,0x98,0xe7,0x36,0x92,0x43,0x70,0x9a,0xca,0xd6,0x73, +0xa3,0x79,0x26,0xe6,0xb9,0x77,0x3f,0x22,0x0c,0x9b,0x21,0x18,0x9f,0xb6,0x90,0x64, +0x62,0x9e,0xda,0x9f,0x98,0xc7,0x36,0x9b,0x67,0x62,0x9e,0x7b,0xf7,0x23,0xc2,0xb0, +0x19,0x82,0xf1,0x6b,0x53,0x79,0x26,0xe6,0xb1,0x6f,0x3f,0x22,0x0c,0x9b,0x21,0x18, +0x9f,0xb6,0x98,0x62,0x62,0x9e,0xbb,0xb7,0x97,0x67,0x62,0x1e,0xfb,0xf6,0x23,0xc2, +0xb0,0x19,0x82,0xf1,0x6b,0x43,0x31,0x04,0xa7,0xa9,0x6c,0xdd,0x66,0x0a,0x81,0x79, +0xf0,0xfa,0x08,0x16,0xc1,0x69,0x06,0x5f,0x70,0x9a,0xe9,0xc6,0x49,0x01,0xc8,0xd8, +0x9b,0x1b,0x99,0xcb,0x4f,0x0c,0x8d,0xad,0x18,0x13,0xf3,0xdc,0x3b,0x6f,0x35,0xc7, +0xc4,0x3c,0x79,0x5d,0xdf,0x06,0x52,0x08,0xcc,0x53,0xdf,0x26,0x62,0x4c,0xcc,0x63, +0xdf,0xb7,0xb9,0x1c,0x02,0xf3,0xe0,0x75,0x5d,0x5b,0xc7,0x20,0x30,0x8f,0x79,0x14, +0x13,0xf3,0xd4,0xf5,0x19,0x2c,0x82,0xd3,0x0c,0xbe,0xe0,0x34,0x13,0xce,0x5b,0x0b, +0x22,0x38,0x4d,0x85,0xd3,0x35,0x6d,0x37,0xc5,0xc4,0x3c,0x79,0x4d,0x1a,0x40,0xc6, +0xde,0xdc,0xc8,0x5c,0x7e,0x64,0x70,0x8c,0x83,0x10,0x9c,0xa6,0xb2,0x94,0x42,0x60, +0x1e,0x7b,0x37,0x19,0x43,0x70,0x9a,0x0a,0xa7,0xcd,0xa4,0x98,0x98,0xc7,0xbe,0x8d, +0xc5,0x98,0x98,0xe7,0xee,0x7b,0x3b,0x29,0x26,0xe6,0xb1,0xf3,0x13,0x58,0x04,0xa7, +0x19,0x7c,0xc1,0x69,0x26,0x9b,0xb6,0x0f,0x43,0x70,0x9a,0xaa,0xb6,0x6d,0xc4,0x98, +0x98,0xc7,0xce,0xf1,0x03,0x28,0x88,0x66,0x8a,0x30,0x00,0x00,0x00,0x00,0x00,0x00, +0x61,0x20,0x00,0x00,0x4a,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00, +0x07,0x00,0x00,0x00,0x24,0xca,0x60,0x04,0xa0,0x04,0x8a,0x80,0xc2,0x0c,0x00,0xbd, +0x61,0x8c,0x04,0x10,0x1e,0xe1,0x19,0xc6,0x48,0x02,0xe1,0x11,0x1e,0x00,0x00,0x00, +0x63,0x08,0xcd,0x63,0xd5,0xc0,0x31,0x84,0x06,0xb2,0x6b,0xe0,0x18,0x42,0x13,0x59, +0x36,0x70,0x0c,0xa1,0x71,0x6c,0x1b,0x38,0x16,0x02,0x04,0xc7,0x64,0x61,0x1a,0x37, +0x16,0x01,0x04,0x48,0x35,0xc7,0x20,0x79,0xcf,0x58,0x04,0x10,0x20,0xd5,0x1c,0xc3, +0x07,0x06,0xd0,0x58,0x04,0x10,0x20,0xd5,0x1c,0x43,0x18,0x88,0x41,0x34,0x16,0x01, +0x04,0x48,0x35,0xc7,0x30,0x06,0x64,0xe0,0x98,0x37,0xd0,0xc0,0x60,0xa0,0x89,0xc1, +0x40,0x23,0x83,0x81,0x63,0x21,0x40,0x70,0x50,0x66,0x70,0x06,0x68,0x90,0x06,0x58, +0x06,0xe1,0x40,0x00,0x25,0x00,0x00,0x00,0x56,0x52,0x4c,0xcc,0x73,0xd3,0x56,0x41, +0x4c,0xcc,0x53,0xdb,0x05,0x31,0x31,0xcf,0x6d,0x19,0xc4,0xc4,0x3c,0xba,0x6d,0x10, +0x13,0xf3,0xf4,0xd6,0x41,0x08,0xc0,0xb2,0x18,0x46,0x21,0x38,0x4d,0x85,0x9b,0x46, +0x21,0x38,0x4d,0xb5,0x9b,0x8a,0x21,0x00,0xcb,0x82,0xdf,0x66,0x62,0x08,0x4e,0x53, +0xdd,0xb7,0x9d,0x18,0x82,0xd3,0x54,0xb7,0x6e,0x28,0x86,0xe0,0x34,0xd5,0xdd,0xdb, +0x47,0x31,0x31,0x4f,0x9d,0x9b,0x87,0x21,0x00,0xcb,0x52,0xdf,0x06,0x62,0x08,0xc0, +0xb2,0xd4,0xbc,0x59,0x10,0x82,0xd3,0x54,0x96,0x62,0x08,0x4e,0x53,0xe1,0xb6,0x85, +0x14,0x13,0xf3,0xd8,0xb4,0x8d,0x14,0x13,0xf3,0xd8,0xb9,0x89,0x18,0x02,0xb0,0x2c, +0xf6,0x6d,0x24,0x86,0x00,0x2c,0x8b,0xcd,0x1b,0x87,0x21,0x38,0x4d,0x55,0xd3,0xd6, +0x30,0x54,0xc0,0x72,0x00,0x05,0xd1,0x4c,0x11,0x06,0x00,0x00,0x00,0x00,0x00,0x00, +0x61,0x20,0x00,0x00,0x19,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00, +0x03,0x00,0x00,0x00,0x24,0x4a,0x60,0x04,0x80,0xc2,0x0c,0x00,0x00,0x00,0x00,0x00, +0x63,0x08,0xcd,0x33,0x16,0x01,0x04,0x48,0x34,0xc7,0x00,0x49,0xcf,0x58,0x04,0x10, +0x28,0xd1,0x1c,0xc3,0x44,0x39,0x58,0x85,0x03,0x01,0x00,0x00,0x0a,0x00,0x00,0x00, +0x16,0x41,0x4c,0xcc,0x63,0xdb,0x04,0x31,0x31,0x4f,0x6e,0x0d,0x43,0x05,0x2c,0x07, +0x50,0x10,0xcd,0x14,0x61,0x56,0x41,0x4c,0xcc,0xd3,0x1b,0x45,0x21,0x00,0xcb,0xb2, +0x9b,0x04,0x21,0x00,0xcb,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00, +0x1b,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x03,0x00,0x00,0x00, +0x24,0xca,0x60,0x04,0xa0,0x04,0x8a,0x80,0xc2,0x0c,0x00,0x00,0x63,0x08,0xcd,0x33, +0x16,0x01,0x04,0xca,0x34,0xc7,0x20,0x51,0xcf,0x1c,0x43,0x45,0x41,0x73,0x0c,0x16, +0x15,0xcd,0x31,0x5c,0x94,0x83,0x58,0x38,0x10,0x00,0x00,0x00,0x0b,0x00,0x00,0x00, +0x86,0x51,0x4c,0xcc,0x53,0xe7,0x76,0x51,0x4c,0xcc,0x53,0xdb,0x36,0x41,0x4c,0xcc, +0x63,0x5b,0x05,0x31,0x31,0x8f,0x6e,0x0d,0x43,0x05,0x2c,0x66,0x41,0x4c,0xcc,0xd3, +0x1f,0x40,0x41,0x34,0x53,0x84,0x19,0x05,0x21,0x00,0xcb,0x02,0x00,0x00,0x00,0x00, +0x61,0x20,0x00,0x00,0x2f,0x00,0x00,0x00,0x13,0x04,0x45,0x2c,0x10,0x00,0x00,0x00, +0x03,0x00,0x00,0x00,0x24,0xca,0xa0,0x04,0x46,0x00,0x8a,0x80,0xc0,0x08,0x00,0x00, +0x63,0x08,0x0d,0x34,0xc9,0x30,0x49,0xc4,0x2c,0x03,0x11,0x50,0x63,0x08,0xcd,0x33, +0xc9,0x50,0x49,0xc4,0x2c,0x03,0x21,0x58,0x63,0x08,0x4d,0x34,0xc9,0x70,0x49,0xc4, +0x2c,0x03,0x31,0x60,0x63,0x08,0x8d,0x33,0xc9,0x90,0x49,0x84,0x69,0x22,0x70,0xc3, +0x27,0x1c,0x08,0x00,0x1a,0x00,0x00,0x00,0x96,0x51,0x4c,0xcc,0x53,0xdf,0x66,0x41, +0x08,0xcc,0x83,0xdb,0x04,0x31,0x31,0x4f,0x6d,0x15,0xc4,0xc4,0x3c,0xb7,0x61,0x10, +0x02,0xf3,0xf0,0x47,0x20,0xb9,0x0d,0x52,0x20,0xc4,0xb0,0x12,0x13,0x15,0x35,0xdb, +0xe2,0x08,0x8a,0x5d,0x10,0x13,0xf3,0xec,0x37,0x90,0x2c,0x4e,0xf4,0x47,0x87,0x54, +0xd7,0x17,0x70,0x2c,0x4e,0xf4,0x47,0x87,0x74,0x02,0xc8,0xe2,0x44,0x7f,0x74,0x48, +0xb9,0x69,0x14,0x02,0xf3,0xd4,0xb8,0x6d,0x18,0x11,0x31,0x55,0xc0,0x62,0x0d,0x43, +0x05,0x2c,0x07,0x50,0x10,0xcd,0x14,0x61,0x46,0x31,0x08,0xcc,0x03,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x71,0x20,0x00,0x00,0x12,0x00,0x00,0x00,0x66,0x40,0x54,0x82, +0x23,0x59,0xc2,0x20,0x09,0x92,0x1d,0x18,0x4f,0x84,0x34,0x53,0x61,0x03,0xc4,0xe3, +0x58,0x85,0x05,0x14,0xbe,0x34,0x45,0xb5,0x21,0x10,0x82,0x23,0x15,0x46,0x30,0x2c, +0xc8,0x64,0x02,0x06,0xf0,0x3c,0x91,0x73,0x19,0x00,0xe1,0x4b,0x53,0x64,0x0a,0x84, +0x84,0x34,0x85,0x31,0x10,0x0a,0xb2,0x3c,0x56,0x30,0x08,0xcc,0x63,0x0b,0x44,0x25, +0x21,0x0d,0x00,0x00,0x00,0x00,0x00,0x00}; diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp index 8919491792..b35d6790f7 100644 --- a/src/gallium/auxiliary/gallivm/instructions.cpp +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -35,6 +35,8 @@ #include "storage.h" +#include "pipe/p_util.h" + #include #include #include @@ -42,7 +44,8 @@ #include #include #include -#include +#include +#include #include #include @@ -53,7 +56,6 @@ using namespace llvm; #include "gallivm_builtins.cpp" #if 0 - llvm::Value *arrayFromChannels(std::vector &vals) { VectorType *vectorType = VectorType::get(Type::FloatTy, 4); @@ -84,7 +86,10 @@ Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicB m_llvmLit = 0; m_fmtPtr = 0; - createGallivmBuiltins(m_mod); + MemoryBuffer *buffer = MemoryBuffer::getMemBuffer( + (const char*)&llvm_builtins_data[0], + (const char*)&llvm_builtins_data[Elements(llvm_builtins_data)-1]); + m_mod = ParseBitcodeFile(buffer); } llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2) diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 6f83b56a72..3c16a3692d 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -1,8 +1,35 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ #include "instructionssoa.h" #include "storagesoa.h" #include "pipe/p_shader_tokens.h" +#include "pipe/p_util.h" #include #include @@ -10,7 +37,10 @@ #include #include #include -#include +#include +#include +#include + #include @@ -183,7 +213,10 @@ llvm::Module * InstructionsSoa::currentModule() const void InstructionsSoa::createBuiltins() { - m_builtins = createSoaBuiltins(); + MemoryBuffer *buffer = MemoryBuffer::getMemBuffer( + (const char*)&soabuiltins_data[0], + (const char*)&soabuiltins_data[Elements(soabuiltins_data)-1]); + m_builtins = ParseBitcodeFile(buffer); createDependencies(); } diff --git a/src/gallium/auxiliary/gallivm/llvm_builtins.c b/src/gallium/auxiliary/gallivm/llvm_builtins.c index 4f98d754ba..64b5d499a8 100644 --- a/src/gallium/auxiliary/gallivm/llvm_builtins.c +++ b/src/gallium/auxiliary/gallivm/llvm_builtins.c @@ -30,7 +30,7 @@ * Authors: * Zack Rusin zack@tungstengraphics.com */ -typedef __attribute__(( ocu_vector_type(4) )) float float4; +typedef __attribute__(( ext_vector_type(4) )) float float4; extern float powf(float a, float b); diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c index 4d658be520..40addebd8c 100644 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -31,7 +31,7 @@ * Authors: * Zack Rusin zack@tungstengraphics.com */ -typedef __attribute__(( ocu_vector_type(4) )) float float4; +typedef __attribute__(( ext_vector_type(4) )) float float4; void dp3(float4 *res, float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, -- cgit v1.2.3 From b6c9d2ef2cfadbbe3e7aa94f21fd0da36d089952 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 12:37:41 +0100 Subject: rtasm: add dump facility for x86 (from tgsi_sse2.c) --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 267 ++++++++++++++++++++++++++--- 1 file changed, 243 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 7f8cc23d15..f2c08c96a6 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -34,6 +34,116 @@ #define X86_TWOB 0x0f +#define DUMP_SSE 0 + +#if DUMP_SSE + +static void +_print_reg( + struct x86_reg reg ) +{ + if (reg.mod != mod_REG) + debug_printf( "[" ); + + switch( reg.file ) { + case file_REG32: + switch( reg.idx ) { + case reg_AX: debug_printf( "EAX" ); break; + case reg_CX: debug_printf( "ECX" ); break; + case reg_DX: debug_printf( "EDX" ); break; + case reg_BX: debug_printf( "EBX" ); break; + case reg_SP: debug_printf( "ESP" ); break; + case reg_BP: debug_printf( "EBP" ); break; + case reg_SI: debug_printf( "ESI" ); break; + case reg_DI: debug_printf( "EDI" ); break; + } + break; + case file_MMX: + debug_printf( "MMX%u", reg.idx ); + break; + case file_XMM: + debug_printf( "XMM%u", reg.idx ); + break; + case file_x87: + debug_printf( "fp%u", reg.idx ); + break; + } + + if (reg.mod == mod_DISP8 || + reg.mod == mod_DISP32) + debug_printf("+%d", reg.disp); + + if (reg.mod != mod_REG) + debug_printf( "]" ); +} + +static void +_fill( + const char *op ) +{ + unsigned count = 10 - strlen( op ); + + while( count-- ) { + debug_printf( " " ); + } +} + +#define DUMP_START() debug_printf( "\nsse-dump start ----------------" ) +#define DUMP_END() debug_printf( "\nsse-dump end ----------------\n" ) +#define DUMP( OP ) debug_printf( "\n%s", OP ) + +#define DUMP_I( OP, I ) do { \ + debug_printf( "\n%s", OP ); \ + _fill( OP ); \ + debug_printf( "%u", I ); \ +} while( 0 ) + +#define DUMP_R( OP, R0 ) do { \ + debug_printf( "\n%s", OP ); \ + _fill( OP ); \ + _print_reg( R0 ); \ +} while( 0 ) + +#define DUMP_RR( OP, R0, R1 ) do { \ + debug_printf( "\n%s", OP ); \ + _fill( OP ); \ + _print_reg( R0 ); \ + debug_printf( ", " ); \ + _print_reg( R1 ); \ +} while( 0 ) + +#define DUMP_RI( OP, R0, I ) do { \ + debug_printf( "\n%s", OP ); \ + _fill( OP ); \ + _print_reg( R0 ); \ + debug_printf( ", " ); \ + debug_printf( "%u", I ); \ +} while( 0 ) + +#define DUMP_RRI( OP, R0, R1, I ) do { \ + debug_printf( "\n%s", OP ); \ + _fill( OP ); \ + _print_reg( R0 ); \ + debug_printf( ", " ); \ + _print_reg( R1 ); \ + debug_printf( ", " ); \ + debug_printf( "%u", I ); \ +} while( 0 ) + +#else + +#define DUMP_START() +#define DUMP_END() +#define DUMP( OP ) +#define DUMP_I( OP, I ) +#define DUMP_R( OP, R0 ) +#define DUMP_RR( OP, R0, R1 ) +#define DUMP_RI( OP, R0, I ) +#define DUMP_RRI( OP, R0, R1, I ) + +#endif + + static void do_realloc( struct x86_function *p ) { if (p->size == 0) { @@ -272,6 +382,7 @@ unsigned char *x86_jcc_forward( struct x86_function *p, unsigned char *x86_jmp_forward( struct x86_function *p) { + DUMP( __FUNCTION__ ); emit_1ub(p, 0xe9); emit_1i(p, 0); return x86_get_label(p); @@ -279,6 +390,8 @@ unsigned char *x86_jmp_forward( struct x86_function *p) unsigned char *x86_call_forward( struct x86_function *p) { + DUMP( __FUNCTION__ ); + emit_1ub(p, 0xe8); emit_1i(p, 0); return x86_get_label(p); @@ -294,6 +407,7 @@ void x86_fixup_fwd_jump( struct x86_function *p, void x86_jmp( struct x86_function *p, unsigned char *label) { + DUMP_I( __FUNCTION__, label ); emit_1ub(p, 0xe9); emit_1i(p, pointer_to_intptr( label ) - pointer_to_intptr( x86_get_label(p) ) - 4); } @@ -310,12 +424,14 @@ static unsigned char *cptr( void (*label)() ) */ void x86_call( struct x86_function *p, void (*label)()) { + DUMP_I( __FUNCTION__, label ); emit_1ub(p, 0xe8); emit_1i(p, cptr(label) - x86_get_label(p) - 4); } #else void x86_call( struct x86_function *p, struct x86_reg reg) { + DUMP_R( __FUNCTION__, reg ); emit_1ub(p, 0xff); emit_modrm_noreg(p, 2, reg); } @@ -328,6 +444,7 @@ void x86_call( struct x86_function *p, struct x86_reg reg) */ void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) { + DUMP_RI( __FUNCTION__, dst, imm ); assert(dst.mod == mod_REG); emit_1ub(p, 0xb8 + dst.idx); emit_1i(p, imm); @@ -336,6 +453,7 @@ void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) void x86_push( struct x86_function *p, struct x86_reg reg ) { + DUMP_R( __FUNCTION__, reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x50 + reg.idx); p->stack_offset += 4; @@ -344,6 +462,7 @@ void x86_push( struct x86_function *p, void x86_pop( struct x86_function *p, struct x86_reg reg ) { + DUMP_R( __FUNCTION__, reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x58 + reg.idx); p->stack_offset -= 4; @@ -352,6 +471,7 @@ void x86_pop( struct x86_function *p, void x86_inc( struct x86_function *p, struct x86_reg reg ) { + DUMP_R( __FUNCTION__, reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x40 + reg.idx); } @@ -359,17 +479,20 @@ void x86_inc( struct x86_function *p, void x86_dec( struct x86_function *p, struct x86_reg reg ) { + DUMP_R( __FUNCTION__, reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x48 + reg.idx); } void x86_ret( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_1ub(p, 0xc3); } void x86_sahf( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_1ub(p, 0x9e); } @@ -377,6 +500,7 @@ void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm( p, 0x8b, 0x89, dst, src ); } @@ -384,6 +508,7 @@ void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm( p, 0x33, 0x31, dst, src ); } @@ -391,6 +516,7 @@ void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm( p, 0x3b, 0x39, dst, src ); } @@ -398,6 +524,7 @@ void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_1ub(p, 0x8d); emit_modrm( p, dst, src ); } @@ -406,6 +533,7 @@ void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_1ub(p, 0x85); emit_modrm( p, dst, src ); } @@ -414,6 +542,7 @@ void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm(p, 0x03, 0x01, dst, src ); } @@ -422,6 +551,7 @@ void x86_add( struct x86_function *p, void x86_mul( struct x86_function *p, struct x86_reg src ) { + DUMP_R( __FUNCTION__, src ); emit_1ub(p, 0xf7); emit_modrm_noreg(p, 4, src ); } @@ -431,6 +561,7 @@ void x86_imul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0xAF); emit_modrm(p, dst, src); } @@ -440,6 +571,7 @@ void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm(p, 0x2b, 0x29, dst, src ); } @@ -447,6 +579,7 @@ void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm( p, 0x0b, 0x09, dst, src ); } @@ -454,6 +587,7 @@ void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm( p, 0x23, 0x21, dst, src ); } @@ -468,6 +602,7 @@ void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, 0xF3, X86_TWOB); emit_op_modrm( p, 0x10, 0x11, dst, src ); } @@ -476,6 +611,7 @@ void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x28, 0x29, dst, src ); } @@ -484,6 +620,7 @@ void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x10, 0x11, dst, src ); } @@ -492,6 +629,7 @@ void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.mod != mod_REG || src.mod != mod_REG); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ @@ -501,6 +639,7 @@ void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.mod != mod_REG || src.mod != mod_REG); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ @@ -510,6 +649,7 @@ void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x5F); emit_modrm( p, dst, src ); } @@ -518,6 +658,7 @@ void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x5F); emit_modrm( p, dst, src ); } @@ -526,6 +667,7 @@ void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x5E); emit_modrm( p, dst, src ); } @@ -534,6 +676,7 @@ void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x5D); emit_modrm( p, dst, src ); } @@ -542,6 +685,7 @@ void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x5C); emit_modrm( p, dst, src ); } @@ -550,6 +694,7 @@ void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x59); emit_modrm( p, dst, src ); } @@ -558,6 +703,7 @@ void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x59); emit_modrm( p, dst, src ); } @@ -566,6 +712,7 @@ void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x58); emit_modrm( p, dst, src ); } @@ -574,6 +721,7 @@ void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x58); emit_modrm( p, dst, src ); } @@ -582,6 +730,7 @@ void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x55); emit_modrm( p, dst, src ); } @@ -590,6 +739,7 @@ void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x54); emit_modrm( p, dst, src ); } @@ -598,6 +748,7 @@ void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x52); emit_modrm( p, dst, src ); } @@ -606,6 +757,7 @@ void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x52); emit_modrm( p, dst, src ); @@ -615,6 +767,7 @@ void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.mod == mod_REG && src.mod == mod_REG); emit_2ub(p, X86_TWOB, 0x12); emit_modrm( p, dst, src ); @@ -624,6 +777,7 @@ void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.mod == mod_REG && src.mod == mod_REG); emit_2ub(p, X86_TWOB, 0x16); emit_modrm( p, dst, src ); @@ -633,6 +787,7 @@ void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x56); emit_modrm( p, dst, src ); } @@ -641,6 +796,7 @@ void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x57); emit_modrm( p, dst, src ); } @@ -649,6 +805,7 @@ void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.file == file_MMX && (src.file == file_XMM || src.mod != mod_REG)); @@ -662,6 +819,7 @@ void sse2_cvtdq2ps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x5b); emit_modrm( p, dst, src ); } @@ -671,31 +829,34 @@ void sse2_cvtdq2ps( struct x86_function *p, * arg0. */ void sse_shufps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, + struct x86_reg dst, + struct x86_reg src, unsigned char shuf) { + DUMP_RRI( __FUNCTION__, dst, src, shuf ); emit_2ub(p, X86_TWOB, 0xC6); - emit_modrm(p, dest, arg0); + emit_modrm(p, dst, src); emit_1ub(p, shuf); } void sse_cmpps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, + struct x86_reg dst, + struct x86_reg src, unsigned char cc) { + DUMP_RRI( "CMPPS", dst, src, cc ); emit_2ub(p, X86_TWOB, 0xC2); - emit_modrm(p, dest, arg0); + emit_modrm(p, dst, src); emit_1ub(p, cc); } void sse_pmovmskb( struct x86_function *p, - struct x86_reg dest, + struct x86_reg dst, struct x86_reg src) { - emit_3ub(p, 0x66, X86_TWOB, 0xD7); - emit_modrm(p, dest, src); + DUMP_RR( __FUNCTION__, dst, src ); + emit_3ub(p, 0x66, X86_TWOB, 0xD7); + emit_modrm(p, dst, src); } /*********************************************************************** @@ -706,12 +867,13 @@ void sse_pmovmskb( struct x86_function *p, * Perform a reduced swizzle: */ void sse2_pshufd( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, + struct x86_reg dst, + struct x86_reg src, unsigned char shuf) { + DUMP_RRI( __FUNCTION__, dst, src, shuf ); emit_3ub(p, 0x66, X86_TWOB, 0x70); - emit_modrm(p, dest, arg0); + emit_modrm(p, dst, src); emit_1ub(p, shuf); } @@ -719,6 +881,7 @@ void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); emit_modrm( p, dst, src ); } @@ -727,6 +890,7 @@ void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x5B); emit_modrm( p, dst, src ); } @@ -735,6 +899,7 @@ void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x6B); emit_modrm( p, dst, src ); } @@ -743,6 +908,7 @@ void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x63); emit_modrm( p, dst, src ); } @@ -751,6 +917,7 @@ void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x67); emit_modrm( p, dst, src ); } @@ -759,6 +926,7 @@ void sse2_punpcklbw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x60); emit_modrm( p, dst, src ); } @@ -768,6 +936,7 @@ void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x53); emit_modrm( p, dst, src ); } @@ -776,6 +945,7 @@ void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x53); emit_modrm( p, dst, src ); } @@ -784,6 +954,7 @@ void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, 0x66, X86_TWOB); emit_op_modrm( p, 0x6e, 0x7e, dst, src ); } @@ -796,30 +967,35 @@ void sse2_movd( struct x86_function *p, */ void x87_fist( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); emit_1ub(p, 0xdb); emit_modrm_noreg(p, 2, dst); } void x87_fistp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); emit_1ub(p, 0xdb); emit_modrm_noreg(p, 3, dst); } void x87_fild( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); emit_1ub(p, 0xdf); emit_modrm_noreg(p, 0, arg); } void x87_fldz( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xee); } void x87_fldcw( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); assert(arg.file == file_REG32); assert(arg.mod != mod_REG); emit_1ub(p, 0xd9); @@ -828,26 +1004,31 @@ void x87_fldcw( struct x86_function *p, struct x86_reg arg ) void x87_fld1( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xe8); } void x87_fldl2e( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xea); } void x87_fldln2( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xed); } void x87_fwait( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_1ub(p, 0x9b); } void x87_fnclex( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xdb, 0xe2); } @@ -884,49 +1065,55 @@ static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86 assert(0); } -void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xc8, 0xdc, 0xc8, 4); } -void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xe0, 0xdc, 0xe8, 4); } -void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xe8, 0xdc, 0xe0, 5); } -void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xc0, 0xdc, 0xc0, 0); } -void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xf0, 0xdc, 0xf8, 6); } -void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xf8, 0xdc, 0xf0, 7); @@ -934,6 +1121,7 @@ void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) void x87_fmulp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xc8+dst.idx); @@ -941,6 +1129,7 @@ void x87_fmulp( struct x86_function *p, struct x86_reg dst ) void x87_fsubp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xe8+dst.idx); @@ -948,6 +1137,7 @@ void x87_fsubp( struct x86_function *p, struct x86_reg dst ) void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xe0+dst.idx); @@ -955,6 +1145,7 @@ void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) void x87_faddp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xc0+dst.idx); @@ -962,6 +1153,7 @@ void x87_faddp( struct x86_function *p, struct x86_reg dst ) void x87_fdivp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xf8+dst.idx); @@ -969,6 +1161,7 @@ void x87_fdivp( struct x86_function *p, struct x86_reg dst ) void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xf0+dst.idx); @@ -976,70 +1169,83 @@ void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) void x87_fucom( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); assert(arg.file == file_x87); emit_2ub(p, 0xdd, 0xe0+arg.idx); } void x87_fucomp( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); assert(arg.file == file_x87); emit_2ub(p, 0xdd, 0xe8+arg.idx); } void x87_fucompp( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xda, 0xe9); } void x87_fxch( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); assert(arg.file == file_x87); emit_2ub(p, 0xd9, 0xc8+arg.idx); } void x87_fabs( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xe1); } void x87_fchs( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xe0); } void x87_fcos( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xff); } void x87_fprndint( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xfc); } void x87_fscale( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xfd); } void x87_fsin( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xfe); } void x87_fsincos( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xfb); } void x87_fsqrt( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xfa); } void x87_fxtract( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xf4); } @@ -1049,6 +1255,7 @@ void x87_fxtract( struct x86_function *p ) */ void x87_f2xm1( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xf0); } @@ -1057,6 +1264,7 @@ void x87_f2xm1( struct x86_function *p ) */ void x87_fyl2x( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xf1); } @@ -1067,12 +1275,14 @@ void x87_fyl2x( struct x86_function *p ) */ void x87_fyl2xp1( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xf9); } void x87_fld( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); if (arg.file == file_x87) emit_2ub(p, 0xd9, 0xc0 + arg.idx); else { @@ -1083,6 +1293,7 @@ void x87_fld( struct x86_function *p, struct x86_reg arg ) void x87_fst( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); if (dst.file == file_x87) emit_2ub(p, 0xdd, 0xd0 + dst.idx); else { @@ -1093,6 +1304,7 @@ void x87_fst( struct x86_function *p, struct x86_reg dst ) void x87_fstp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); if (dst.file == file_x87) emit_2ub(p, 0xdd, 0xd8 + dst.idx); else { @@ -1103,6 +1315,7 @@ void x87_fstp( struct x86_function *p, struct x86_reg dst ) void x87_fcom( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); if (dst.file == file_x87) emit_2ub(p, 0xd8, 0xd0 + dst.idx); else { @@ -1113,6 +1326,7 @@ void x87_fcom( struct x86_function *p, struct x86_reg dst ) void x87_fcomp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); if (dst.file == file_x87) emit_2ub(p, 0xd8, 0xd8 + dst.idx); else { @@ -1124,6 +1338,7 @@ void x87_fcomp( struct x86_function *p, struct x86_reg dst ) void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_REG32); if (dst.idx == reg_AX && @@ -1153,6 +1368,7 @@ void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.file == file_MMX && (src.file == file_MMX || src.mod != mod_REG)); @@ -1166,6 +1382,7 @@ void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.file == file_MMX && (src.file == file_MMX || src.mod != mod_REG)); @@ -1179,6 +1396,7 @@ void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); p->need_emms = 1; emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x6e, 0x7e, dst, src ); @@ -1188,6 +1406,7 @@ void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); p->need_emms = 1; emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x6f, 0x7f, dst, src ); -- cgit v1.2.3 From f30f3206121c56e5c50ccafb1467a8301044d411 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 12:38:14 +0100 Subject: util: add wrappers for float math functions on windows --- src/gallium/include/pipe/p_util.h | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index dbca080a4b..77783b11a8 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -402,6 +402,52 @@ extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, int src_pitch, unsigned src_x, int src_y); + +#ifdef WIN32 + +static INLINE float cosf( float f ) +{ + return (float) cos( (double) f ); +} + +static INLINE float sinf( float f ) +{ + return (float) sin( (double) f ); +} + +static INLINE float ceilf( float f ) +{ + return (float) ceil( (double) f ); +} + +static INLINE float floorf( float f ) +{ + return (float) floor( (double) f ); +} + +static INLINE float powf( float f, float g ) +{ + return (float) pow( (double) f, (double) g ); +} + +static INLINE float sqrtf( float f ) +{ + return (float) sqrt( (double) f ); +} + +static INLINE float fabsf( float f ) +{ + return (float) fabs( (double) f ); +} + +static INLINE float logf( float f ) +{ + return (float) cos( (double) f ); +} + +#endif + + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 615cdd3a535bb71754baa8b37e79b85af01854dd Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 12:39:59 +0100 Subject: tgsi: use new float math funcs, drop local disassembly code --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 88 ++--- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 591 +++++++--------------------- 2 files changed, 178 insertions(+), 501 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index 78e7dec569..29e104bbd1 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -287,10 +287,10 @@ micro_abs( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) fabs( (double) src->f[0] ); - dst->f[1] = (float) fabs( (double) src->f[1] ); - dst->f[2] = (float) fabs( (double) src->f[2] ); - dst->f[3] = (float) fabs( (double) src->f[3] ); + dst->f[0] = fabsf( src->f[0] ); + dst->f[1] = fabsf( src->f[1] ); + dst->f[2] = fabsf( src->f[2] ); + dst->f[3] = fabsf( src->f[3] ); } static void @@ -334,10 +334,10 @@ micro_ceil( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) ceil( (double) src->f[0] ); - dst->f[1] = (float) ceil( (double) src->f[1] ); - dst->f[2] = (float) ceil( (double) src->f[2] ); - dst->f[3] = (float) ceil( (double) src->f[3] ); + dst->f[0] = ceilf( src->f[0] ); + dst->f[1] = ceilf( src->f[1] ); + dst->f[2] = ceilf( src->f[2] ); + dst->f[3] = ceilf( src->f[3] ); } static void @@ -345,10 +345,10 @@ micro_cos( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) cos( (double) src->f[0] ); - dst->f[1] = (float) cos( (double) src->f[1] ); - dst->f[2] = (float) cos( (double) src->f[2] ); - dst->f[3] = (float) cos( (double) src->f[3] ); + dst->f[0] = cosf( src->f[0] ); + dst->f[1] = cosf( src->f[1] ); + dst->f[2] = cosf( src->f[2] ); + dst->f[3] = cosf( src->f[3] ); } static void @@ -430,10 +430,10 @@ micro_exp2( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src) { - dst->f[0] = (float) pow( 2.0, (double) src->f[0] ); - dst->f[1] = (float) pow( 2.0, (double) src->f[1] ); - dst->f[2] = (float) pow( 2.0, (double) src->f[2] ); - dst->f[3] = (float) pow( 2.0, (double) src->f[3] ); + dst->f[0] = powf( 2.0f, src->f[0] ); + dst->f[1] = powf( 2.0f, src->f[1] ); + dst->f[2] = powf( 2.0f, src->f[2] ); + dst->f[3] = powf( 2.0f, src->f[3] ); } static void @@ -463,10 +463,10 @@ micro_flr( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) floor( (double) src->f[0] ); - dst->f[1] = (float) floor( (double) src->f[1] ); - dst->f[2] = (float) floor( (double) src->f[2] ); - dst->f[3] = (float) floor( (double) src->f[3] ); + dst->f[0] = floorf( src->f[0] ); + dst->f[1] = floorf( src->f[1] ); + dst->f[2] = floorf( src->f[2] ); + dst->f[3] = floorf( src->f[3] ); } static void @@ -474,10 +474,10 @@ micro_frc( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = src->f[0] - (float) floor( (double) src->f[0] ); - dst->f[1] = src->f[1] - (float) floor( (double) src->f[1] ); - dst->f[2] = src->f[2] - (float) floor( (double) src->f[2] ); - dst->f[3] = src->f[3] - (float) floor( (double) src->f[3] ); + dst->f[0] = src->f[0] - floorf( src->f[0] ); + dst->f[1] = src->f[1] - floorf( src->f[1] ); + dst->f[2] = src->f[2] - floorf( src->f[2] ); + dst->f[3] = src->f[3] - floorf( src->f[3] ); } static void @@ -510,10 +510,10 @@ micro_lg2( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) log( (double) src->f[0] ) * 1.442695f; - dst->f[1] = (float) log( (double) src->f[1] ) * 1.442695f; - dst->f[2] = (float) log( (double) src->f[2] ) * 1.442695f; - dst->f[3] = (float) log( (double) src->f[3] ) * 1.442695f; + dst->f[0] = logf( src->f[0] ) * 1.442695f; + dst->f[1] = logf( src->f[1] ) * 1.442695f; + dst->f[2] = logf( src->f[2] ) * 1.442695f; + dst->f[3] = logf( src->f[3] ) * 1.442695f; } static void @@ -764,10 +764,10 @@ micro_pow( const union tgsi_exec_channel *src0, const union tgsi_exec_channel *src1 ) { - dst->f[0] = (float) pow( (double) src0->f[0], (double) src1->f[0] ); - dst->f[1] = (float) pow( (double) src0->f[1], (double) src1->f[1] ); - dst->f[2] = (float) pow( (double) src0->f[2], (double) src1->f[2] ); - dst->f[3] = (float) pow( (double) src0->f[3], (double) src1->f[3] ); + dst->f[0] = powf( src0->f[0], src1->f[0] ); + dst->f[1] = powf( src0->f[1], src1->f[1] ); + dst->f[2] = powf( src0->f[2], src1->f[2] ); + dst->f[3] = powf( src0->f[3], src1->f[3] ); } static void @@ -775,10 +775,10 @@ micro_rnd( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) floor( (double) (src->f[0] + 0.5f) ); - dst->f[1] = (float) floor( (double) (src->f[1] + 0.5f) ); - dst->f[2] = (float) floor( (double) (src->f[2] + 0.5f) ); - dst->f[3] = (float) floor( (double) (src->f[3] + 0.5f) ); + dst->f[0] = floorf( src->f[0] + 0.5f ); + dst->f[1] = floorf( src->f[1] + 0.5f ); + dst->f[2] = floorf( src->f[2] + 0.5f ); + dst->f[3] = floorf( src->f[3] + 0.5f ); } static void @@ -833,20 +833,20 @@ micro_sin( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) sin( (double) src->f[0] ); - dst->f[1] = (float) sin( (double) src->f[1] ); - dst->f[2] = (float) sin( (double) src->f[2] ); - dst->f[3] = (float) sin( (double) src->f[3] ); + dst->f[0] = sinf( src->f[0] ); + dst->f[1] = sinf( src->f[1] ); + dst->f[2] = sinf( src->f[2] ); + dst->f[3] = sinf( src->f[3] ); } static void micro_sqrt( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) sqrt( (double) src->f[0] ); - dst->f[1] = (float) sqrt( (double) src->f[1] ); - dst->f[2] = (float) sqrt( (double) src->f[2] ); - dst->f[3] = (float) sqrt( (double) src->f[3] ); + dst->f[0] = sqrtf( src->f[0] ); + dst->f[1] = sqrtf( src->f[1] ); + dst->f[2] = sqrtf( src->f[2] ); + dst->f[3] = sqrtf( src->f[3] ); } static void diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index d47935e982..c3295a27ff 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -38,113 +38,6 @@ #define HIGH_PRECISION 1 /* for 1/sqrt() */ -#define DUMP_SSE 0 - -#if DUMP_SSE - -static void -_print_reg( - struct x86_reg reg ) -{ - if (reg.mod != mod_REG) - debug_printf( "[" ); - - switch( reg.file ) { - case file_REG32: - switch( reg.idx ) { - case reg_AX: - debug_printf( "EAX" ); - break; - case reg_CX: - debug_printf( "ECX" ); - break; - case reg_DX: - debug_printf( "EDX" ); - break; - case reg_BX: - debug_printf( "EBX" ); - break; - case reg_SP: - debug_printf( "ESP" ); - break; - case reg_BP: - debug_printf( "EBP" ); - break; - case reg_SI: - debug_printf( "ESI" ); - break; - case reg_DI: - debug_printf( "EDI" ); - break; - } - break; - case file_MMX: - assert( 0 ); - break; - case file_XMM: - debug_printf( "XMM%u", reg.idx ); - break; - case file_x87: - assert( 0 ); - break; - } - - if (reg.mod == mod_DISP8 || - reg.mod == mod_DISP32) - debug_printf("+%d", reg.disp); - - if (reg.mod != mod_REG) - debug_printf( "]" ); -} - -static void -_fill( - const char *op ) -{ - unsigned count = 10 - strlen( op ); - - while( count-- ) { - debug_printf( " " ); - } -} - -#define DUMP_START() debug_printf( "\nsse-dump start ----------------" ) -#define DUMP_END() debug_printf( "\nsse-dump end ----------------\n" ) -#define DUMP( OP ) debug_printf( "\n%s", OP ) -#define DUMP_I( OP, I ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - debug_printf( "%u", I ); } while( 0 ) -#define DUMP_R( OP, R0 ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - _print_reg( R0 ); } while( 0 ) -#define DUMP_RR( OP, R0, R1 ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - _print_reg( R0 );\ - debug_printf( ", " );\ - _print_reg( R1 ); } while( 0 ) -#define DUMP_RRI( OP, R0, R1, I ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - _print_reg( R0 );\ - debug_printf( ", " );\ - _print_reg( R1 );\ - debug_printf( ", " );\ - debug_printf( "%u", I ); } while( 0 ) - -#else - -#define DUMP_START() -#define DUMP_END() -#define DUMP( OP ) -#define DUMP_I( OP, I ) -#define DUMP_R( OP, R0 ) -#define DUMP_RR( OP, R0, R1 ) -#define DUMP_RRI( OP, R0, R1, I ) - -#endif #define FOR_EACH_CHANNEL( CHAN )\ for( CHAN = 0; CHAN < 4; CHAN++ ) @@ -310,200 +203,6 @@ get_coef( ((vec * 3 + member) * 4 + chan) * 4 ); } -/** - * X86 rtasm wrappers. - */ - -static void -emit_addps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ADDPS", dst, src ); - sse_addps( func, dst, src ); -} - -static void -emit_andnps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ANDNPS", dst, src ); - sse_andnps( func, dst, src ); -} - -static void -emit_andps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ANDPS", dst, src ); - sse_andps( func, dst, src ); -} - -static void -emit_call( - struct x86_function *func, - void (* addr)() ) -{ - struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); - - DUMP_I( "CALL", addr ); - x86_mov_reg_imm( func, ecx, (unsigned long) addr ); - x86_call( func, ecx ); -} - -static void -emit_cmpps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src, - enum sse_cc cc ) -{ - DUMP_RRI( "CMPPS", dst, src, cc ); - sse_cmpps( func, dst, src, cc ); -} - -static void -emit_cvttps2dq( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "CVTTPS2DQ", dst, src ); - sse2_cvttps2dq( func, dst, src ); -} - -static void -emit_maxps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MAXPS", dst, src ); - sse_maxps( func, dst, src ); -} - -static void -emit_minps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MINPS", dst, src ); - sse_minps( func, dst, src ); -} - -static void -emit_mov( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOV", dst, src ); - x86_mov( func, dst, src ); -} - -static void -emit_movaps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOVAPS", dst, src ); - sse_movaps( func, dst, src ); -} - -static void -emit_movss( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOVSS", dst, src ); - sse_movss( func, dst, src ); -} - -static void -emit_movups( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOVUPS", dst, src ); - sse_movups( func, dst, src ); -} - -static void -emit_mulps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MULPS", dst, src ); - sse_mulps( func, dst, src ); -} - -static void -emit_or( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "OR", dst, src ); - x86_or( func, dst, src ); -} - -static void -emit_orps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ORPS", dst, src ); - sse_orps( func, dst, src ); -} - -static void -emit_pmovmskb( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "PMOVMSKB", dst, src ); - sse_pmovmskb( func, dst, src ); -} - -static void -emit_pop( - struct x86_function *func, - struct x86_reg dst ) -{ - DUMP_R( "POP", dst ); - x86_pop( func, dst ); -} - -static void -emit_push( - struct x86_function *func, - struct x86_reg dst ) -{ - DUMP_R( "PUSH", dst ); - x86_push( func, dst ); -} - -static void -emit_rcpps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "RCPPS", dst, src ); - sse2_rcpps( func, dst, src ); -} #ifdef WIN32 static void @@ -511,7 +210,6 @@ emit_retw( struct x86_function *func, unsigned size ) { - DUMP_I( "RET", size ); x86_retw( func, size ); } #else @@ -519,51 +217,10 @@ static void emit_ret( struct x86_function *func ) { - DUMP( "RET" ); x86_ret( func ); } #endif -static void -emit_rsqrtps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "RSQRTPS", dst, src ); - sse_rsqrtps( func, dst, src ); -} - -static void -emit_shufps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src, - unsigned char shuf ) -{ - DUMP_RRI( "SHUFPS", dst, src, shuf ); - sse_shufps( func, dst, src, shuf ); -} - -static void -emit_subps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "SUBPS", dst, src ); - sse_subps( func, dst, src ); -} - -static void -emit_xorps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "XORPS", dst, src ); - sse_xorps( func, dst, src ); -} /** * Data fetch helpers. @@ -582,11 +239,11 @@ emit_const( unsigned vec, unsigned chan ) { - emit_movss( + sse_movss( func, make_xmm( xmm ), get_const( vec, chan ) ); - emit_shufps( + sse_shufps( func, make_xmm( xmm ), make_xmm( xmm ), @@ -600,11 +257,11 @@ emit_immediate( unsigned vec, unsigned chan ) { - emit_movss( + sse_movss( func, make_xmm( xmm ), get_immediate( vec, chan ) ); - emit_shufps( + sse_shufps( func, make_xmm( xmm ), make_xmm( xmm ), @@ -625,7 +282,7 @@ emit_inputf( unsigned vec, unsigned chan ) { - emit_movups( + sse_movups( func, make_xmm( xmm ), get_input( vec, chan ) ); @@ -644,7 +301,7 @@ emit_output( unsigned vec, unsigned chan ) { - emit_movups( + sse_movups( func, get_output( vec, chan ), make_xmm( xmm ) ); @@ -663,7 +320,7 @@ emit_tempf( unsigned vec, unsigned chan ) { - emit_movaps( + sse_movaps( func, make_xmm( xmm ), get_temp( vec, chan ) ); @@ -684,11 +341,11 @@ emit_coef( unsigned chan, unsigned member ) { - emit_movss( + sse_movss( func, make_xmm( xmm ), get_coef( vec, chan, member ) ); - emit_shufps( + sse_shufps( func, make_xmm( xmm ), make_xmm( xmm ), @@ -706,7 +363,7 @@ emit_inputs( unsigned vec, unsigned chan ) { - emit_movups( + sse_movups( func, get_input( vec, chan ), make_xmm( xmm ) ); @@ -719,7 +376,7 @@ emit_temps( unsigned vec, unsigned chan ) { - emit_movaps( + sse_movaps( func, get_temp( vec, chan ), make_xmm( xmm ) ); @@ -796,39 +453,39 @@ static void emit_push_gp( struct x86_function *func ) { - emit_push( + x86_push( func, get_const_base() ); - emit_push( + x86_push( func, get_input_base() ); - emit_push( + x86_push( func, get_output_base() ); /* It is important on non-win32 platforms that temp base is pushed last. */ - emit_push( + x86_push( func, get_temp_base() ); } static void -emit_pop_gp( +x86_pop_gp( struct x86_function *func ) { /* Restore GP registers in a reverse order. */ - emit_pop( + x86_pop( func, get_temp_base() ); - emit_pop( + x86_pop( func, get_output_base() ); - emit_pop( + x86_pop( func, get_input_base() ); - emit_pop( + x86_pop( func, get_const_base() ); } @@ -839,7 +496,7 @@ emit_func_call_dst( unsigned xmm_dst, void (*code)() ) { - emit_movaps( + sse_movaps( func, get_temp( TEMP_R0, 0 ), make_xmm( xmm_dst ) ); @@ -848,19 +505,22 @@ emit_func_call_dst( func ); #ifdef WIN32 - emit_push( + x86_push( func, get_temp( TEMP_R0, 0 ) ); #endif - emit_call( - func, - code ); + { + struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); + + x86_mov_reg_imm( func, ecx, (unsigned long) code ); + x86_call( func, ecx ); + } - emit_pop_gp( + x86_pop_gp( func ); - emit_movaps( + sse_movaps( func, make_xmm( xmm_dst ), get_temp( TEMP_R0, 0 ) ); @@ -873,7 +533,7 @@ emit_func_call_dst_src( unsigned xmm_src, void (*code)() ) { - emit_movaps( + sse_movaps( func, get_temp( TEMP_R0, 1 ), make_xmm( xmm_src ) ); @@ -893,7 +553,7 @@ emit_abs( struct x86_function *func, unsigned xmm ) { - emit_andps( + sse_andps( func, make_xmm( xmm ), get_temp( @@ -907,7 +567,7 @@ emit_add( unsigned xmm_dst, unsigned xmm_src ) { - emit_addps( + sse_addps( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); @@ -918,17 +578,15 @@ cos4f( float *store ) { #ifdef WIN32 - store[0] = (float) cos( (double) store[0] ); - store[1] = (float) cos( (double) store[1] ); - store[2] = (float) cos( (double) store[2] ); - store[3] = (float) cos( (double) store[3] ); + const unsigned X = 0; #else const unsigned X = TEMP_R0 * 16; +#endif + store[X + 0] = cosf( store[X + 0] ); store[X + 1] = cosf( store[X + 1] ); store[X + 2] = cosf( store[X + 2] ); store[X + 3] = cosf( store[X + 3] ); -#endif } static void @@ -947,17 +605,14 @@ ex24f( float *store ) { #ifdef WIN32 - store[0] = (float) pow( 2.0, (double) store[0] ); - store[1] = (float) pow( 2.0, (double) store[1] ); - store[2] = (float) pow( 2.0, (double) store[2] ); - store[3] = (float) pow( 2.0, (double) store[3] ); + const unsigned X = 0; #else const unsigned X = TEMP_R0 * 16; +#endif store[X + 0] = powf( 2.0f, store[X + 0] ); store[X + 1] = powf( 2.0f, store[X + 1] ); store[X + 2] = powf( 2.0f, store[X + 2] ); store[X + 3] = powf( 2.0f, store[X + 3] ); -#endif } static void @@ -976,7 +631,7 @@ emit_f2it( struct x86_function *func, unsigned xmm ) { - emit_cvttps2dq( + sse2_cvttps2dq( func, make_xmm( xmm ), make_xmm( xmm ) ); @@ -991,10 +646,10 @@ flr4f( #else const unsigned X = TEMP_R0 * 16; #endif - store[X + 0] = (float) floor( (double) store[X + 0] ); - store[X + 1] = (float) floor( (double) store[X + 1] ); - store[X + 2] = (float) floor( (double) store[X + 2] ); - store[X + 3] = (float) floor( (double) store[X + 3] ); + store[X + 0] = floorf( store[X + 0] ); + store[X + 1] = floorf( store[X + 1] ); + store[X + 2] = floorf( store[X + 2] ); + store[X + 3] = floorf( store[X + 3] ); } static void @@ -1017,10 +672,10 @@ frc4f( #else const unsigned X = TEMP_R0 * 16; #endif - store[X + 0] -= (float) floor( (double) store[X + 0] ); - store[X + 1] -= (float) floor( (double) store[X + 1] ); - store[X + 2] -= (float) floor( (double) store[X + 2] ); - store[X + 3] -= (float) floor( (double) store[X + 3] ); + store[X + 0] -= floorf( store[X + 0] ); + store[X + 1] -= floorf( store[X + 1] ); + store[X + 2] -= floorf( store[X + 2] ); + store[X + 3] -= floorf( store[X + 3] ); } static void @@ -1066,7 +721,7 @@ emit_MOV( unsigned xmm_dst, unsigned xmm_src ) { - emit_movups( + sse_movups( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); @@ -1077,7 +732,7 @@ emit_mul (struct x86_function *func, unsigned xmm_dst, unsigned xmm_src) { - emit_mulps( + sse_mulps( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); @@ -1088,7 +743,7 @@ emit_neg( struct x86_function *func, unsigned xmm ) { - emit_xorps( + sse_xorps( func, make_xmm( xmm ), get_temp( @@ -1101,17 +756,14 @@ pow4f( float *store ) { #ifdef WIN32 - store[0] = (float) pow( (double) store[0], (double) store[4] ); - store[1] = (float) pow( (double) store[1], (double) store[5] ); - store[2] = (float) pow( (double) store[2], (double) store[6] ); - store[3] = (float) pow( (double) store[3], (double) store[7] ); + const unsigned X = 0; #else const unsigned X = TEMP_R0 * 16; +#endif store[X + 0] = powf( store[X + 0], store[X + 4] ); store[X + 1] = powf( store[X + 1], store[X + 5] ); store[X + 2] = powf( store[X + 2], store[X + 6] ); store[X + 3] = powf( store[X + 3], store[X + 7] ); -#endif } static void @@ -1133,7 +785,11 @@ emit_rcp ( unsigned xmm_dst, unsigned xmm_src ) { - emit_rcpps( + /* On Intel CPUs at least, this is only accurate to 12 bits -- not + * good enough. Need to either emit a proper divide or use the + * iterative technique described below in emit_rsqrt(). + */ + sse2_rcpps( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); @@ -1145,17 +801,14 @@ rsqrt4f( float *store ) { #ifdef WIN32 - store[0] = 1.0F / (float) sqrt( (double) store[0] ); - store[1] = 1.0F / (float) sqrt( (double) store[1] ); - store[2] = 1.0F / (float) sqrt( (double) store[2] ); - store[3] = 1.0F / (float) sqrt( (double) store[3] ); + const unsigned X = 0; #else const unsigned X = TEMP_R0 * 16; - store[X + 0] = 1.0F / sqrt( store[X + 0] ); - store[X + 1] = 1.0F / sqrt( store[X + 1] ); - store[X + 2] = 1.0F / sqrt( store[X + 2] ); - store[X + 3] = 1.0F / sqrt( store[X + 3] ); #endif + store[X + 0] = 1.0F / sqrtf( store[X + 0] ); + store[X + 1] = 1.0F / sqrtf( store[X + 1] ); + store[X + 2] = 1.0F / sqrtf( store[X + 2] ); + store[X + 3] = 1.0F / sqrtf( store[X + 3] ); } #endif @@ -1166,12 +819,41 @@ emit_rsqrt( unsigned xmm_src ) { #if HIGH_PRECISION +#if 1 emit_func_call_dst_src( func, xmm_dst, xmm_src, rsqrt4f ); #else + /* Although rsqrtps() and rcpps() are low precision on some/all SSE + * implementations, it is possible to improve its precision at + * fairly low cost, using a newton/raphson step, as below: + * + * x1 = 2 * rcpps(a) - a * rcpps(a) * rcpps(a) + * x1 = 0.5 * rsqrtps(a) * [3.0 - (a * rsqrtps(a))* rsqrtps(a)] + * + * See: http://softwarecommunity.intel.com/articles/eng/1818.htm + */ + /* This is some code that woudl do the above for a scalar 'a'. We + * obviously are interested in a vector version: + * + * movss xmm3, a; + * movss xmm1, half; + * movss xmm2, three; + * rsqrtss xmm0, xmm3; + * mulss xmm3, xmm0; + * mulss xmm1, xmm0; + * mulss xmm3, xmm0; + * subss xmm2, xmm3; + * mulss xmm1, xmm2; + * movss x, xmm1; + */ +#endif +#else + /* On Intel CPUs at least, this is only accurate to 12 bits -- not + * good enough. + */ emit_rsqrtps( func, make_xmm( xmm_dst ), @@ -1184,7 +866,7 @@ emit_setsign( struct x86_function *func, unsigned xmm ) { - emit_orps( + sse_orps( func, make_xmm( xmm ), get_temp( @@ -1197,17 +879,14 @@ sin4f( float *store ) { #ifdef WIN32 - store[0] = (float) sin( (double) store[0] ); - store[1] = (float) sin( (double) store[1] ); - store[2] = (float) sin( (double) store[2] ); - store[3] = (float) sin( (double) store[3] ); + const unsigned X = 0; #else const unsigned X = TEMP_R0 * 16; +#endif store[X + 0] = sinf( store[X + 0] ); store[X + 1] = sinf( store[X + 1] ); store[X + 2] = sinf( store[X + 2] ); store[X + 3] = sinf( store[X + 3] ); -#endif } static void @@ -1226,7 +905,7 @@ emit_sub( unsigned xmm_dst, unsigned xmm_src ) { - emit_subps( + sse_subps( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); @@ -1435,16 +1114,16 @@ emit_kil( } } - emit_push( + x86_push( func, x86_make_reg( file_REG32, reg_AX ) ); - emit_push( + x86_push( func, x86_make_reg( file_REG32, reg_DX ) ); FOR_EACH_CHANNEL( chan_index ) { if( uniquemask & (1 << chan_index) ) { - emit_cmpps( + sse_cmpps( func, make_xmm( registers[chan_index] ), get_temp( @@ -1453,17 +1132,17 @@ emit_kil( cc_LessThan ); if( chan_index == firstchan ) { - emit_pmovmskb( + sse_pmovmskb( func, x86_make_reg( file_REG32, reg_AX ), make_xmm( registers[chan_index] ) ); } else { - emit_pmovmskb( + sse_pmovmskb( func, x86_make_reg( file_REG32, reg_DX ), make_xmm( registers[chan_index] ) ); - emit_or( + x86_or( func, x86_make_reg( file_REG32, reg_AX ), x86_make_reg( file_REG32, reg_DX ) ); @@ -1471,17 +1150,17 @@ emit_kil( } } - emit_or( + x86_or( func, get_temp( TGSI_EXEC_TEMP_KILMASK_I, TGSI_EXEC_TEMP_KILMASK_C ), x86_make_reg( file_REG32, reg_AX ) ); - emit_pop( + x86_pop( func, x86_make_reg( file_REG32, reg_DX ) ); - emit_pop( + x86_pop( func, x86_make_reg( file_REG32, reg_AX ) ); } @@ -1497,12 +1176,12 @@ emit_setcc( FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); FETCH( func, *inst, 1, 1, chan_index ); - emit_cmpps( + sse_cmpps( func, make_xmm( 0 ), make_xmm( 1 ), cc ); - emit_andps( + sse_andps( func, make_xmm( 0 ), get_temp( @@ -1523,22 +1202,22 @@ emit_cmp( FETCH( func, *inst, 0, 0, chan_index ); FETCH( func, *inst, 1, 1, chan_index ); FETCH( func, *inst, 2, 2, chan_index ); - emit_cmpps( + sse_cmpps( func, make_xmm( 0 ), get_temp( TGSI_EXEC_TEMP_00000000_I, TGSI_EXEC_TEMP_00000000_C ), cc_LessThan ); - emit_andps( + sse_andps( func, make_xmm( 1 ), make_xmm( 0 ) ); - emit_andnps( + sse_andnps( func, make_xmm( 0 ), make_xmm( 2 ) ); - emit_orps( + sse_orps( func, make_xmm( 0 ), make_xmm( 1 ) ); @@ -1589,7 +1268,7 @@ emit_instruction( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { FETCH( func, *inst, 0, 0, CHAN_X ); - emit_maxps( + sse_maxps( func, make_xmm( 0 ), get_temp( @@ -1601,7 +1280,7 @@ emit_instruction( /* XMM[1] = SrcReg[0].yyyy */ FETCH( func, *inst, 1, 0, CHAN_Y ); /* XMM[1] = max(XMM[1], 0) */ - emit_maxps( + sse_maxps( func, make_xmm( 1 ), get_temp( @@ -1610,14 +1289,14 @@ emit_instruction( /* XMM[2] = SrcReg[0].wwww */ FETCH( func, *inst, 2, 0, CHAN_W ); /* XMM[2] = min(XMM[2], 128.0) */ - emit_minps( + sse_minps( func, make_xmm( 2 ), get_temp( TGSI_EXEC_TEMP_128_I, TGSI_EXEC_TEMP_128_C ) ); /* XMM[2] = max(XMM[2], -128.0) */ - emit_maxps( + sse_maxps( func, make_xmm( 2 ), get_temp( @@ -1625,16 +1304,16 @@ emit_instruction( TGSI_EXEC_TEMP_MINUS_128_C ) ); emit_pow( func, 1, 2 ); FETCH( func, *inst, 0, 0, CHAN_X ); - emit_xorps( + sse_xorps( func, make_xmm( 2 ), make_xmm( 2 ) ); - emit_cmpps( + sse_cmpps( func, make_xmm( 2 ), make_xmm( 0 ), cc_LessThanEqual ); - emit_andps( + sse_andps( func, make_xmm( 2 ), make_xmm( 1 ) ); @@ -1756,7 +1435,7 @@ emit_instruction( FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); FETCH( func, *inst, 1, 1, chan_index ); - emit_minps( + sse_minps( func, make_xmm( 0 ), make_xmm( 1 ) ); @@ -1768,7 +1447,7 @@ emit_instruction( FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); FETCH( func, *inst, 1, 1, chan_index ); - emit_maxps( + sse_maxps( func, make_xmm( 0 ), make_xmm( 1 ) ); @@ -2376,8 +2055,6 @@ tgsi_emit_sse2( unsigned ok = 1; uint num_immediates = 0; - DUMP_START(); - func->csr = func->store; tgsi_parse_init( &parse, tokens ); @@ -2387,24 +2064,24 @@ tgsi_emit_sse2( */ if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { /* DECLARATION phase, do not load output argument. */ - emit_mov( + x86_mov( func, get_input_base(), get_argument( 0 ) ); /* skipping outputs argument here */ - emit_mov( + x86_mov( func, get_const_base(), get_argument( 2 ) ); - emit_mov( + x86_mov( func, get_temp_base(), get_argument( 3 ) ); - emit_mov( + x86_mov( func, get_coef_base(), get_argument( 4 ) ); - emit_mov( + x86_mov( func, get_immediate_base(), get_argument( 5 ) ); @@ -2412,23 +2089,23 @@ tgsi_emit_sse2( else { assert(parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX); - emit_mov( + x86_mov( func, get_input_base(), get_argument( 0 ) ); - emit_mov( + x86_mov( func, get_output_base(), get_argument( 1 ) ); - emit_mov( + x86_mov( func, get_const_base(), get_argument( 2 ) ); - emit_mov( + x86_mov( func, get_temp_base(), get_argument( 3 ) ); - emit_mov( + x86_mov( func, get_immediate_base(), get_argument( 4 ) ); @@ -2451,7 +2128,7 @@ tgsi_emit_sse2( if( !instruction_phase ) { /* INSTRUCTION phase, overwrite coeff with output. */ instruction_phase = TRUE; - emit_mov( + x86_mov( func, get_output_base(), get_argument( 1 ) ); @@ -2463,8 +2140,10 @@ tgsi_emit_sse2( &parse.FullToken.FullInstruction ); if (!ok) { - debug_printf("failed to translate tgsi opcode %d to SSE\n", - parse.FullToken.FullInstruction.Instruction.Opcode ); + debug_printf("failed to translate tgsi opcode %d to SSE (%s)\n", + parse.FullToken.FullInstruction.Instruction.Opcode, + parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ? + "vertex shader" : "fragment shader"); } break; @@ -2499,8 +2178,6 @@ tgsi_emit_sse2( tgsi_parse_free( &parse ); - DUMP_END(); - return ok; } -- cgit v1.2.3 From 76a3590046d74c923d9837f82ece1587224b9a41 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 14:19:15 +0100 Subject: util: work around freaky win32 math.h --- src/gallium/include/pipe/p_util.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 77783b11a8..43d94ec4ba 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -405,6 +405,8 @@ extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, #ifdef WIN32 +#if !defined(_INC_MATH) || !defined(__cplusplus) + static INLINE float cosf( float f ) { return (float) cos( (double) f ); @@ -444,7 +446,7 @@ static INLINE float logf( float f ) { return (float) cos( (double) f ); } - +#endif /* _INC_MATH */ #endif -- cgit v1.2.3 From 08717d94619802f7816420be155c0c92fa727109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 21 Apr 2008 20:44:45 +0900 Subject: gallium: Do not mistake pipe state objects for state tracker state objects. --- src/gallium/auxiliary/cso_cache/cso_context.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 746b176185..4541be8a5c 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -266,8 +266,9 @@ void cso_save_samplers(struct cso_context *ctx) void cso_restore_samplers(struct cso_context *ctx) { - cso_set_samplers(ctx, ctx->nr_samplers_saved, - (const struct pipe_sampler_state **) ctx->samplers_saved); + ctx->nr_samplers = ctx->nr_samplers_saved; + memcpy(ctx->samplers, ctx->samplers_saved, sizeof(ctx->samplers)); + cso_single_sampler_done( ctx ); } @@ -313,6 +314,8 @@ void cso_restore_sampler_textures( struct cso_context *ctx ) pipe_texture_reference(&ctx->textures[i], NULL); ctx->pipe->set_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures); + + ctx->nr_textures_saved = 0; } -- cgit v1.2.3 From 13d8b1b211a803f44ffe325e7eed887cce4abaca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 21 Apr 2008 22:26:33 +0900 Subject: gallium: Set all state via cso_context in blit/gen_mipmap utils. cso_restore_* functions are implemented on top of cso_set_*, therefore they require full knowledge of the current pipe state to work correctly. Directly calling pipe's set_*_state functions will lead to undefined state. Also save and restore shaders. --- src/gallium/auxiliary/util/u_blit.c | 10 +++++++--- src/gallium/auxiliary/util/u_gen_mipmap.c | 12 ++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index eec5e600c9..be5e83e834 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -300,6 +300,8 @@ util_blit_pixels(struct blit_state *ctx, cso_save_samplers(ctx->cso); cso_save_sampler_textures(ctx->cso); cso_save_framebuffer(ctx->cso); + cso_save_fragment_shader(ctx->cso); + cso_save_vertex_shader(ctx->cso); /* set misc state we care about */ cso_set_blend(ctx->cso, &ctx->blend); @@ -313,11 +315,11 @@ util_blit_pixels(struct blit_state *ctx, cso_single_sampler_done(ctx->cso); /* texture */ - pipe->set_sampler_textures(pipe, 1, &tex); + cso_set_sampler_textures(ctx->cso, 1, &tex); /* shaders */ - pipe->bind_fs_state(pipe, ctx->fs); - pipe->bind_vs_state(pipe, ctx->vs); + cso_set_fragment_shader(ctx->cso, ctx->fs); + cso_set_vertex_shader(ctx->cso, ctx->vs); /* drawing dest */ memset(&fb, 0, sizeof(fb)); @@ -344,6 +346,8 @@ util_blit_pixels(struct blit_state *ctx, cso_restore_samplers(ctx->cso); cso_restore_sampler_textures(ctx->cso); cso_restore_framebuffer(ctx->cso); + cso_restore_fragment_shader(ctx->cso); + cso_restore_vertex_shader(ctx->cso); /* free the texture */ pipe_surface_reference(&texSurf, NULL); diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 2fd214d22e..f0c4063b28 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -880,16 +880,18 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_save_samplers(ctx->cso); cso_save_sampler_textures(ctx->cso); cso_save_framebuffer(ctx->cso); + cso_save_fragment_shader(ctx->cso); + cso_save_vertex_shader(ctx->cso); /* bind our state */ cso_set_blend(ctx->cso, &ctx->blend); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); - pipe->bind_vs_state(pipe, ctx->vs); - pipe->bind_fs_state(pipe, ctx->fs); + cso_set_fragment_shader(ctx->cso, ctx->fs); + cso_set_vertex_shader(ctx->cso, ctx->vs); #if 0 - pipe->set_viewport_state(pipe, &ctx->viewport); + cso_set_viewport(ctx->cso, &ctx->viewport); #endif /* init framebuffer state */ @@ -930,7 +932,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]); #endif - pipe->set_sampler_textures(pipe, 1, &pt); + cso_set_sampler_textures(ctx->cso, 1, &pt); /* quad coords in window coords (bypassing clipping, viewport mapping) */ set_vertex_data(ctx, @@ -954,4 +956,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_samplers(ctx->cso); cso_restore_sampler_textures(ctx->cso); cso_restore_framebuffer(ctx->cso); + cso_restore_fragment_shader(ctx->cso); + cso_restore_vertex_shader(ctx->cso); } -- cgit v1.2.3 From e29583afcb238cf7a70089cfdf50a69ca277c53a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 22 Apr 2008 00:14:08 +0900 Subject: gallium: Include dependent header. --- src/gallium/auxiliary/tgsi/util/tgsi_parse.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h index a98e88e343..da0121c482 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h @@ -1,6 +1,8 @@ #if !defined TGSI_PARSE_H #define TGSI_PARSE_H +#include "pipe/p_shader_tokens.h" + #if defined __cplusplus extern "C" { #endif -- cgit v1.2.3 From d3045ebb0642b09b4d353be6d4a258e6766061e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 22 Apr 2008 00:16:04 +0900 Subject: gallium: Hash the fragment shader tokens, instead of pipe_shader_state. PS: pipe_shader_state should probably go away now that it is reduced to a single pointer. --- src/gallium/auxiliary/cso_cache/cso_context.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 4541be8a5c..87995c80c3 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -38,6 +38,7 @@ #include "pipe/p_state.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "tgsi/util/tgsi_parse.h" #include "cso_cache/cso_context.h" #include "cso_cache/cso_cache.h" @@ -148,6 +149,7 @@ void cso_set_blend(struct cso_context *ctx, void *handle; if (cso_hash_iter_is_null(iter)) { + /* FIXME: handle OOM */ struct cso_blend *cso = MALLOC(sizeof(struct cso_blend)); cso->state = *templ; @@ -198,6 +200,7 @@ void cso_single_sampler(struct cso_context *ctx, (void*)templ); if (cso_hash_iter_is_null(iter)) { + /* FIXME: handle OOM */ struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler)); cso->state = *templ; @@ -333,6 +336,7 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx, void *handle; if (cso_hash_iter_is_null(iter)) { + /* FIXME: handle OOM */ struct cso_depth_stencil_alpha *cso = MALLOC(sizeof(struct cso_depth_stencil_alpha)); cso->state = *templ; @@ -381,6 +385,7 @@ void cso_set_rasterizer(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { + /* FIXME: handle OOM */ struct cso_rasterizer *cso = MALLOC(sizeof(struct cso_rasterizer)); cso->state = *templ; @@ -420,17 +425,23 @@ void cso_restore_rasterizer(struct cso_context *ctx) void cso_set_fragment_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) { - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_shader_state)); + const struct tgsi_token *tokens = templ->tokens; + unsigned num_tokens = tgsi_num_tokens(tokens); + size_t tokens_size = num_tokens*sizeof(struct tgsi_token); + unsigned hash_key = cso_construct_key((void*)tokens, tokens_size); struct cso_hash_iter iter = cso_find_state_template(ctx->cache, - hash_key, CSO_FRAGMENT_SHADER, - (void*)templ); + hash_key, + CSO_FRAGMENT_SHADER, + (void*)tokens); void *handle = NULL; if (cso_hash_iter_is_null(iter)) { - struct cso_fragment_shader *cso = MALLOC(sizeof(struct cso_fragment_shader)); + /* FIXME: handle OOM */ + struct cso_fragment_shader *cso = MALLOC(sizeof(struct cso_fragment_shader) + tokens_size); + struct tgsi_token *cso_tokens = (struct tgsi_token *)((char *)cso + sizeof(*cso)); - cso->state = *templ; + memcpy(cso_tokens, tokens, tokens_size); + cso->state.tokens = cso_tokens; cso->data = ctx->pipe->create_fs_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_fs_state; cso->context = ctx->pipe; @@ -477,6 +488,7 @@ void cso_set_vertex_shader(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { + /* FIXME: handle OOM */ struct cso_vertex_shader *cso = MALLOC(sizeof(struct cso_vertex_shader)); cso->state = *templ; -- cgit v1.2.3 From a918a9c744f656c8bf2e3fd2841732e01a5ccefc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 16:10:13 +0100 Subject: draw: consolidate all the passthrough line/tri/point funcs --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/SConscript | 1 + src/gallium/auxiliary/draw/draw_pipe.c | 63 ---------- src/gallium/auxiliary/draw/draw_pipe.h | 6 +- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 38 +++---- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 16 +-- src/gallium/auxiliary/draw/draw_pipe_cull.c | 18 +-- src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 9 +- src/gallium/auxiliary/draw/draw_pipe_offset.c | 16 +-- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 25 +--- src/gallium/auxiliary/draw/draw_pipe_stipple.c | 16 +-- src/gallium/auxiliary/draw/draw_pipe_twoside.c | 19 +--- src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 17 +-- src/gallium/auxiliary/draw/draw_pipe_util.c | 133 ++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pipe_wide_line.c | 17 +-- src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 23 +--- 16 files changed, 177 insertions(+), 241 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pipe_util.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 5289f2660a..bc6acfe458 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -16,6 +16,7 @@ C_SOURCES = \ draw_pipe_stipple.c \ draw_pipe_twoside.c \ draw_pipe_unfilled.c \ + draw_pipe_util.c \ draw_pipe_validate.c \ draw_pipe_vbuf.c \ draw_pipe_wide_line.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 91e6a35c5e..0b9852f633 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -15,6 +15,7 @@ draw = env.ConvenienceLibrary( 'draw_pipe_stipple.c', 'draw_pipe_twoside.c', 'draw_pipe_unfilled.c', + 'draw_pipe_util.c', 'draw_pipe_validate.c', 'draw_pipe_vbuf.c', 'draw_pipe_wide_line.c', diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 0c0840af0c..d0890203a5 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -108,40 +108,6 @@ void draw_pipeline_destroy( struct draw_context *draw ) -/* This is only used for temporary verts. - */ -#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) - - -/** - * Allocate space for temporary post-transform vertices, such as for clipping. - */ -void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) -{ - assert(!stage->tmp); - - stage->nr_tmps = nr; - - if (nr) { - ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); - unsigned i; - - stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); - - for (i = 0; i < nr; i++) - stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); - } -} - - -void draw_free_temp_verts( struct draw_stage *stage ) -{ - if (stage->tmp) { - FREE( stage->tmp[0] ); - FREE( stage->tmp ); - stage->tmp = NULL; - } -} @@ -195,35 +161,6 @@ static void do_triangle( struct draw_context *draw, } -/* Reset vertex ids. This is basically a type of flush. - * - * Called only from draw_pipe_vbuf.c - */ -void draw_reset_vertex_ids(struct draw_context *draw) -{ - struct draw_stage *stage = draw->pipeline.first; - - while (stage) { - unsigned i; - - for (i = 0; i < stage->nr_tmps; i++) - stage->tmp[i]->vertex_id = UNDEFINED_VERTEX_ID; - - stage = stage->next; - } - - if (draw->pipeline.verts) - { - unsigned i; - char *verts = draw->pipeline.verts; - unsigned stride = draw->pipeline.vertex_stride; - - for (i = 0; i < draw->pipeline.vertex_count; i++) { - ((struct vertex_header *)verts)->vertex_id = UNDEFINED_VERTEX_ID; - verts += stride; - } - } -} /* Code to run the pipeline on a fairly arbitary collection of vertices. diff --git a/src/gallium/auxiliary/draw/draw_pipe.h b/src/gallium/auxiliary/draw/draw_pipe.h index f2749b34bb..2476abb2b2 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.h +++ b/src/gallium/auxiliary/draw/draw_pipe.h @@ -81,10 +81,14 @@ extern struct draw_stage *draw_validate_stage( struct draw_context *context ); extern void draw_free_temp_verts( struct draw_stage *stage ); -extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); +extern boolean draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); extern void draw_reset_vertex_ids( struct draw_context *draw ); +void draw_pipe_passthrough_tri(struct draw_stage *stage, struct prim_header *header); +void draw_pipe_passthrough_line(struct draw_stage *stage, struct prim_header *header); +void draw_pipe_passthrough_point(struct draw_stage *stage, struct prim_header *header); + /** diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 24bc87d4f8..b27360170a 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -334,7 +334,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx, * Generate the frag shader we'll use for drawing AA lines. * This will be the user's shader plus some texture/modulate instructions. */ -static void +static boolean generate_aaline_fs(struct aaline_stage *aaline) { const struct pipe_shader_state *orig_fs = &aaline->fs->state; @@ -346,6 +346,8 @@ generate_aaline_fs(struct aaline_stage *aaline) aaline_fs = *orig_fs; /* copy to init */ aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + if (aaline_fs.tokens == NULL) + return FALSE; memset(&transform, 0, sizeof(transform)); transform.colorOutput = -1; @@ -372,6 +374,7 @@ generate_aaline_fs(struct aaline_stage *aaline) = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); aaline->fs->generic_attrib = transform.maxGeneric + 1; + return TRUE; } @@ -469,13 +472,15 @@ aaline_create_sampler(struct aaline_stage *aaline) * When we're about to draw our first AA line in a batch, this function is * called to tell the driver to bind our modified fragment shader. */ -static void +static boolean bind_aaline_fragment_shader(struct aaline_stage *aaline) { - if (!aaline->fs->aaline_fs) { - generate_aaline_fs(aaline); - } + if (!aaline->fs->aaline_fs && + !generate_aaline_fs(aaline)) + return FALSE; + aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs); + return TRUE; } @@ -487,20 +492,6 @@ aaline_stage( struct draw_stage *stage ) } -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} - - /** * Draw a wide line by drawing a quad, using geometry which will * fullfill GL's antialiased line requirements. @@ -638,7 +629,10 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) /* * Bind (generate) our fragprog, sampler and texture */ - bind_aaline_fragment_shader(aaline); + if (!bind_aaline_fragment_shader(aaline)) { + stage->line = draw_pipe_passthrough_line; + return; + } /* update vertex attrib info */ aaline->tex_slot = draw->num_vs_outputs; @@ -721,9 +715,9 @@ draw_aaline_stage(struct draw_context *draw) aaline->stage.draw = draw; aaline->stage.next = NULL; - aaline->stage.point = passthrough_point; + aaline->stage.point = draw_pipe_passthrough_point; aaline->stage.line = aaline_first_line; - aaline->stage.tri = passthrough_tri; + aaline->stage.tri = draw_pipe_passthrough_tri; aaline->stage.flush = aaline_flush; aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter; aaline->stage.destroy = aaline_destroy; diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 9f878f6c02..6d22d7ac48 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -546,18 +546,6 @@ aapoint_stage( struct draw_stage *stage ) } -static void -passthrough_line(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->line(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} /** @@ -749,8 +737,8 @@ draw_aapoint_stage(struct draw_context *draw) aapoint->stage.draw = draw; aapoint->stage.next = NULL; aapoint->stage.point = aapoint_first_point; - aapoint->stage.line = passthrough_line; - aapoint->stage.tri = passthrough_tri; + aapoint->stage.line = draw_pipe_passthrough_line; + aapoint->stage.tri = draw_pipe_passthrough_tri; aapoint->stage.flush = aapoint_flush; aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter; aapoint->stage.destroy = aapoint_destroy; diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c index c406f89d05..8c13f40b55 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_cull.c +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -95,20 +95,6 @@ static void cull_first_tri( struct draw_stage *stage, -static void cull_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void cull_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - static void cull_flush( struct draw_stage *stage, unsigned flags ) { stage->tri = cull_first_tri; @@ -139,8 +125,8 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw ) cull->stage.draw = draw; cull->stage.next = NULL; - cull->stage.point = cull_point; - cull->stage.line = cull_line; + cull->stage.point = draw_pipe_passthrough_point; + cull->stage.line = draw_pipe_passthrough_line; cull->stage.tri = cull_first_tri; cull->stage.flush = cull_flush; cull->stage.reset_stipple_counter = cull_reset_stipple_counter; diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c index bdb8b49dc4..2aeb309554 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -152,13 +152,6 @@ static void flatshade_line_1( struct draw_stage *stage, } -/* Flatshade point -- passthrough. - */ -static void flatshade_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} static void flatshade_init_state( struct draw_stage *stage ) @@ -236,7 +229,7 @@ struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) flatshade->stage.draw = draw; flatshade->stage.next = NULL; - flatshade->stage.point = flatshade_point; + flatshade->stage.point = draw_pipe_passthrough_point; flatshade->stage.line = flatshade_first_line; flatshade->stage.tri = flatshade_first_tri; flatshade->stage.flush = flatshade_flush; diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index dbdece45bb..c1dc21cd32 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -129,18 +129,6 @@ static void offset_first_tri( struct draw_stage *stage, } -static void offset_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void offset_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} static void offset_flush( struct draw_stage *stage, @@ -175,8 +163,8 @@ struct draw_stage *draw_offset_stage( struct draw_context *draw ) offset->stage.draw = draw; offset->stage.next = NULL; - offset->stage.point = offset_point; - offset->stage.line = offset_line; + offset->stage.point = draw_pipe_passthrough_point; + offset->stage.line = draw_pipe_passthrough_line; offset->stage.tri = offset_first_tri; offset->stage.flush = offset_flush; offset->stage.reset_stipple_counter = offset_reset_stipple_counter; diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 4903ba2133..5686729cd3 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -473,25 +473,6 @@ pstip_stage( struct draw_stage *stage ) } -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point(stage->next, header); -} - - -static void -passthrough_line(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->line(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} @@ -523,7 +504,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); /* now really draw first line */ - stage->tri = passthrough_tri; + stage->tri = draw_pipe_passthrough_tri; stage->tri(stage, header); } @@ -579,8 +560,8 @@ draw_pstip_stage(struct draw_context *draw) pstip->stage.draw = draw; pstip->stage.next = NULL; - pstip->stage.point = passthrough_point; - pstip->stage.line = passthrough_line; + pstip->stage.point = draw_pipe_passthrough_point; + pstip->stage.line = draw_pipe_passthrough_line; pstip->stage.tri = pstip_first_tri; pstip->stage.flush = pstip_flush; pstip->stage.reset_stipple_counter = pstip_reset_stipple_counter; diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c index 49429ee9e1..9cf5840cce 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c @@ -195,18 +195,6 @@ stipple_flush(struct draw_stage *stage, unsigned flags) } -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point( stage->next, header ); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} static void @@ -228,9 +216,9 @@ struct draw_stage *draw_stipple_stage( struct draw_context *draw ) stipple->stage.draw = draw; stipple->stage.next = NULL; - stipple->stage.point = passthrough_point; + stipple->stage.point = draw_pipe_passthrough_point; stipple->stage.line = stipple_first_line; - stipple->stage.tri = passthrough_tri; + stipple->stage.tri = draw_pipe_passthrough_tri; stipple->stage.reset_stipple_counter = reset_stipple_counter; stipple->stage.flush = stipple_flush; stipple->stage.destroy = stipple_destroy; diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c index 09a9d23d57..453fd3ac71 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -99,21 +99,6 @@ static void twoside_tri( struct draw_stage *stage, } -static void twoside_line( struct draw_stage *stage, - struct prim_header *header ) -{ - /* pass-through */ - stage->next->line( stage->next, header ); -} - - -static void twoside_point( struct draw_stage *stage, - struct prim_header *header ) -{ - /* pass-through */ - stage->next->point( stage->next, header ); -} - static void twoside_first_tri( struct draw_stage *stage, struct prim_header *header ) @@ -192,8 +177,8 @@ struct draw_stage *draw_twoside_stage( struct draw_context *draw ) twoside->stage.draw = draw; twoside->stage.next = NULL; - twoside->stage.point = twoside_point; - twoside->stage.line = twoside_line; + twoside->stage.point = draw_pipe_passthrough_point; + twoside->stage.line = draw_pipe_passthrough_line; twoside->stage.tri = twoside_first_tri; twoside->stage.flush = twoside_flush; twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter; diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c index 31e24f6a14..d4ddfec1b3 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -148,19 +148,6 @@ static void unfilled_first_tri( struct draw_stage *stage, } -static void unfilled_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void unfilled_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - static void unfilled_flush( struct draw_stage *stage, unsigned flags ) @@ -196,8 +183,8 @@ struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) unfilled->stage.draw = draw; unfilled->stage.next = NULL; unfilled->stage.tmp = NULL; - unfilled->stage.point = unfilled_point; - unfilled->stage.line = unfilled_line; + unfilled->stage.point = draw_pipe_passthrough_point; + unfilled->stage.line = draw_pipe_passthrough_line; unfilled->stage.tri = unfilled_first_tri; unfilled->stage.flush = unfilled_flush; unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter; diff --git a/src/gallium/auxiliary/draw/draw_pipe_util.c b/src/gallium/auxiliary/draw/draw_pipe_util.c new file mode 100644 index 0000000000..e9821de976 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_util.c @@ -0,0 +1,133 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw/draw_private.h" +#include "draw/draw_pipe.h" + + + +void +draw_pipe_passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point(stage->next, header); +} + +void +draw_pipe_passthrough_line(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->line(stage->next, header); +} + +void +draw_pipe_passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + + + + +/* This is only used for temporary verts. + */ +#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) + + +/** + * Allocate space for temporary post-transform vertices, such as for clipping. + */ +boolean draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) +{ + unsigned i; + ubyte *store; + + assert(!stage->tmp); + + stage->tmp = NULL; + stage->nr_tmps = nr; + if (nr == 0) + return FALSE; + + store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); + if (store == NULL) + return FALSE; + + stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); + + for (i = 0; i < nr; i++) + stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + + return TRUE; +} + + +void draw_free_temp_verts( struct draw_stage *stage ) +{ + if (stage->tmp) { + FREE( stage->tmp[0] ); + FREE( stage->tmp ); + stage->tmp = NULL; + } +} + + +/* Reset vertex ids. This is basically a type of flush. + * + * Called only from draw_pipe_vbuf.c + */ +void draw_reset_vertex_ids(struct draw_context *draw) +{ + struct draw_stage *stage = draw->pipeline.first; + + while (stage) { + unsigned i; + + for (i = 0; i < stage->nr_tmps; i++) + stage->tmp[i]->vertex_id = UNDEFINED_VERTEX_ID; + + stage = stage->next; + } + + if (draw->pipeline.verts) + { + unsigned i; + char *verts = draw->pipeline.verts; + unsigned stride = draw->pipeline.vertex_stride; + + for (i = 0; i < draw->pipeline.vertex_count; i++) { + ((struct vertex_header *)verts)->vertex_id = UNDEFINED_VERTEX_ID; + verts += stride; + } + } +} + diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c index 329b5d0fb0..452732e662 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -49,19 +49,6 @@ static INLINE struct wideline_stage *wideline_stage( struct draw_stage *stage ) } -static void wideline_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void wideline_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} - /** * Draw a wide line by drawing a quad (two triangles). @@ -180,9 +167,9 @@ struct draw_stage *draw_wide_line_stage( struct draw_context *draw ) wide->stage.draw = draw; wide->stage.next = NULL; - wide->stage.point = wideline_point; + wide->stage.point = draw_pipe_passthrough_point; wide->stage.line = wideline_line; - wide->stage.tri = wideline_tri; + wide->stage.tri = draw_pipe_passthrough_point; wide->stage.flush = wideline_flush; wide->stage.reset_stipple_counter = wideline_reset_stipple_counter; wide->stage.destroy = wideline_destroy; diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index 7a439178a0..8101340680 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -61,23 +61,6 @@ widepoint_stage( struct draw_stage *stage ) } -static void passthrough_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - -static void widepoint_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line(stage->next, header); -} - -static void widepoint_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} /** @@ -209,7 +192,7 @@ static void widepoint_first_point( struct draw_stage *stage, stage->point = widepoint_point; } else { - stage->point = passthrough_point; + stage->point = draw_pipe_passthrough_point; } if (draw->rasterizer->point_sprite) { @@ -272,8 +255,8 @@ struct draw_stage *draw_wide_point_stage( struct draw_context *draw ) wide->stage.draw = draw; wide->stage.next = NULL; wide->stage.point = widepoint_first_point; - wide->stage.line = widepoint_line; - wide->stage.tri = widepoint_tri; + wide->stage.line = draw_pipe_passthrough_line; + wide->stage.tri = draw_pipe_passthrough_tri; wide->stage.flush = widepoint_flush; wide->stage.reset_stipple_counter = widepoint_reset_stipple_counter; wide->stage.destroy = widepoint_destroy; -- cgit v1.2.3 From 69ecc2a577dc45451d56cee3e41cb6e7e542b097 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 16:38:09 +0100 Subject: draw: propogate errors out of aaline stage --- src/gallium/auxiliary/draw/draw_context.h | 2 +- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 58 ++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 68e2efb865..6171c75cb4 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -73,7 +73,7 @@ void draw_enable_line_stipple(struct draw_context *draw, boolean enable); void draw_enable_point_sprites(struct draw_context *draw, boolean enable); -void +boolean draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); void diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index b27360170a..ae1abf91c2 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -338,7 +338,6 @@ static boolean generate_aaline_fs(struct aaline_stage *aaline) { const struct pipe_shader_state *orig_fs = &aaline->fs->state; - //struct draw_context *draw = aaline->stage.draw; struct pipe_shader_state aaline_fs; struct aa_transform_context transform; @@ -372,6 +371,8 @@ generate_aaline_fs(struct aaline_stage *aaline) aaline->fs->aaline_fs = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); + if (aaline->fs->aaline_fs == NULL) + return FALSE; aaline->fs->generic_attrib = transform.maxGeneric + 1; return TRUE; @@ -381,7 +382,7 @@ generate_aaline_fs(struct aaline_stage *aaline) /** * Create the texture map we'll use for antialiasing the lines. */ -static void +static boolean aaline_create_texture(struct aaline_stage *aaline) { struct pipe_context *pipe = aaline->pipe; @@ -399,6 +400,8 @@ aaline_create_texture(struct aaline_stage *aaline) texTemp.cpp = 1; aaline->texture = screen->texture_create(screen, &texTemp); + if (!aaline->texture) + return FALSE; /* Fill in mipmap images. * Basically each level is solid opaque, except for the outermost @@ -414,6 +417,8 @@ aaline_create_texture(struct aaline_stage *aaline) surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0); data = pipe_surface_map(surface); + if (data == NULL) + return FALSE; for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { @@ -439,6 +444,7 @@ aaline_create_texture(struct aaline_stage *aaline) pipe_surface_reference(&surface, NULL); pipe->texture_update(pipe, aaline->texture, 0, (1 << level)); } + return TRUE; } @@ -447,7 +453,7 @@ aaline_create_texture(struct aaline_stage *aaline) * By using a mipmapped texture, we don't have to generate a different * texture image for each line size. */ -static void +static boolean aaline_create_sampler(struct aaline_stage *aaline) { struct pipe_sampler_state sampler; @@ -465,6 +471,10 @@ aaline_create_sampler(struct aaline_stage *aaline) sampler.max_lod = MAX_TEXTURE_LEVEL; aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler); + if (aaline->sampler_cso == NULL) + return FALSE; + + return TRUE; } @@ -696,9 +706,11 @@ aaline_destroy(struct draw_stage *stage) { struct aaline_stage *aaline = aaline_stage(stage); - aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); + if (aaline->sampler_cso) + aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); - pipe_texture_release(&aaline->texture); + if (aaline->texture) + pipe_texture_release(&aaline->texture); draw_free_temp_verts( stage ); @@ -710,8 +722,11 @@ static struct aaline_stage * draw_aaline_stage(struct draw_context *draw) { struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage); + if (aaline == NULL) + return NULL; - draw_alloc_temp_verts( &aaline->stage, 8 ); + if (draw_alloc_temp_verts( &aaline->stage, 8 )) + goto fail; aaline->stage.draw = draw; aaline->stage.next = NULL; @@ -723,6 +738,12 @@ draw_aaline_stage(struct draw_context *draw) aaline->stage.destroy = aaline_destroy; return aaline; + + fail: + if (aaline) + aaline_destroy(&aaline->stage); + + return NULL; } @@ -816,7 +837,7 @@ aaline_set_sampler_textures(struct pipe_context *pipe, * into the draw module's pipeline. This will not be used if the * hardware has native support for AA lines. */ -void +boolean draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) { struct aaline_stage *aaline; @@ -827,14 +848,17 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) * Create / install AA line drawing / prim stage */ aaline = draw_aaline_stage( draw ); - assert(aaline); - draw->pipeline.aaline = &aaline->stage; + if (!aaline) + goto fail; aaline->pipe = pipe; /* create special texture, sampler state */ - aaline_create_texture(aaline); - aaline_create_sampler(aaline); + if (!aaline_create_texture(aaline)) + goto fail; + + if (!aaline_create_sampler(aaline)) + goto fail; /* save original driver functions */ aaline->driver_create_fs_state = pipe->create_fs_state; @@ -851,4 +875,16 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) pipe->bind_sampler_states = aaline_bind_sampler_states; pipe->set_sampler_textures = aaline_set_sampler_textures; + + /* Install once everything is known to be OK: + */ + draw->pipeline.aaline = &aaline->stage; + + return TRUE; + + fail: + if (aaline) + aaline->stage.destroy( &aaline->stage ); + + return FALSE; } -- cgit v1.2.3 From 0cd90a917d289363a3edb5cfa40c391eb07aa97c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 16:45:41 +0100 Subject: draw: propogate errors out of aapoint stage --- src/gallium/auxiliary/draw/draw_context.h | 2 +- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 46 ++++++++++++++++++++------ 3 files changed, 38 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 6171c75cb4..197235b2d8 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -76,7 +76,7 @@ void draw_enable_point_sprites(struct draw_context *draw, boolean enable); boolean draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); -void +boolean draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe); void diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index ae1abf91c2..bc514d40f0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -725,7 +725,7 @@ draw_aaline_stage(struct draw_context *draw) if (aaline == NULL) return NULL; - if (draw_alloc_temp_verts( &aaline->stage, 8 )) + if (!draw_alloc_temp_verts( &aaline->stage, 8 )) goto fail; aaline->stage.draw = draw; diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 6d22d7ac48..6d689c36de 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -484,7 +484,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx, * Generate the frag shader we'll use for drawing AA lines. * This will be the user's shader plus some texture/modulate instructions. */ -static void +static boolean generate_aapoint_fs(struct aapoint_stage *aapoint) { const struct pipe_shader_state *orig_fs = &aapoint->fs->state; @@ -495,6 +495,8 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) aapoint_fs = *orig_fs; /* copy to init */ aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + if (aapoint_fs.tokens == NULL) + return FALSE; memset(&transform, 0, sizeof(transform)); transform.colorOutput = -1; @@ -519,8 +521,12 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) aapoint->fs->aapoint_fs = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs); + if (aapoint->fs->aapoint_fs == NULL) + return FALSE; aapoint->fs->generic_attrib = transform.maxGeneric + 1; + + return TRUE; } @@ -528,13 +534,15 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) * When we're about to draw our first AA line in a batch, this function is * called to tell the driver to bind our modified fragment shader. */ -static void +static boolean bind_aapoint_fragment_shader(struct aapoint_stage *aapoint) { - if (!aapoint->fs->aapoint_fs) { - generate_aapoint_fs(aapoint); - } + if (!aapoint->fs->aapoint_fs && + !generate_aapoint_fs(aapoint)) + return FALSE; + aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs); + return TRUE; } @@ -731,8 +739,11 @@ static struct aapoint_stage * draw_aapoint_stage(struct draw_context *draw) { struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage); + if (aapoint == NULL) + goto fail; - draw_alloc_temp_verts( &aapoint->stage, 4 ); + if (!draw_alloc_temp_verts( &aapoint->stage, 4 )) + goto fail; aapoint->stage.draw = draw; aapoint->stage.next = NULL; @@ -744,6 +755,13 @@ draw_aapoint_stage(struct draw_context *draw) aapoint->stage.destroy = aapoint_destroy; return aapoint; + + fail: + if (aapoint) + aapoint_destroy(&aapoint->stage); + + return NULL; + } @@ -806,20 +824,19 @@ aapoint_delete_fs_state(struct pipe_context *pipe, void *fs) * into the draw module's pipeline. This will not be used if the * hardware has native support for AA points. */ -void +boolean draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe) { struct aapoint_stage *aapoint; - pipe->draw = (void *) draw; /* * Create / install AA point drawing / prim stage */ aapoint = draw_aapoint_stage( draw ); - assert(aapoint); - draw->pipeline.aapoint = &aapoint->stage; + if (aapoint == NULL) + goto fail; aapoint->pipe = pipe; @@ -832,4 +849,13 @@ draw_install_aapoint_stage(struct draw_context *draw, pipe->create_fs_state = aapoint_create_fs_state; pipe->bind_fs_state = aapoint_bind_fs_state; pipe->delete_fs_state = aapoint_delete_fs_state; + + pipe->draw = (void *) draw; + draw->pipeline.aapoint = &aapoint->stage; + + fail: + if (aapoint) + aapoint->stage.destroy( &aapoint->stage ); + + return FALSE; } -- cgit v1.2.3 From 0d4ece4c5a243dc4b684331bad49f220311e5520 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 17:03:37 +0100 Subject: draw: propogate lots of errors --- src/gallium/auxiliary/draw/draw_context.h | 2 +- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 10 ++++---- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 14 ++++++----- src/gallium/auxiliary/draw/draw_pipe_clip.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pipe_cull.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pipe_offset.c | 8 +++++++ src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 14 +++++++++-- src/gallium/auxiliary/draw/draw_pipe_twoside.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pipe_util.c | 28 ++++++++++++---------- src/gallium/auxiliary/draw/draw_pipe_validate.c | 2 ++ src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 5 ++-- src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 2 ++ .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 2 ++ src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 ++ 17 files changed, 120 insertions(+), 35 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 197235b2d8..2742001698 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -79,7 +79,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); boolean draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe); -void +boolean draw_install_pstipple_stage(struct draw_context *draw, struct pipe_context *pipe); diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index bc514d40f0..fbb5b45b40 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -765,13 +765,13 @@ aaline_create_fs_state(struct pipe_context *pipe, { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader); + if (aafs == NULL) + return NULL; - if (aafs) { - aafs->state = *fs; + aafs->state = *fs; - /* pass-through */ - aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs); - } + /* pass-through */ + aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs); return aafs; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 6d689c36de..ac0aa4cd7c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -783,13 +783,13 @@ aapoint_create_fs_state(struct pipe_context *pipe, { struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader); + if (aafs == NULL) + return NULL; - if (aafs) { - aafs->state = *fs; + aafs->state = *fs; - /* pass-through */ - aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs); - } + /* pass-through */ + aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs); return aafs; } @@ -830,6 +830,7 @@ draw_install_aapoint_stage(struct draw_context *draw, { struct aapoint_stage *aapoint; + pipe->draw = (void *) draw; /* * Create / install AA point drawing / prim stage @@ -850,9 +851,10 @@ draw_install_aapoint_stage(struct draw_context *draw, pipe->bind_fs_state = aapoint_bind_fs_state; pipe->delete_fs_state = aapoint_delete_fs_state; - pipe->draw = (void *) draw; draw->pipeline.aapoint = &aapoint->stage; + return TRUE; + fail: if (aapoint) aapoint->stage.destroy( &aapoint->stage ); diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 6780f275d9..21216addea 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -493,8 +493,11 @@ static void clip_destroy( struct draw_stage *stage ) struct draw_stage *draw_clip_stage( struct draw_context *draw ) { struct clipper *clipper = CALLOC_STRUCT(clipper); + if (clipper == NULL) + goto fail; - draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ); + if (!draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 )) + goto fail; clipper->stage.draw = draw; clipper->stage.point = clip_point; @@ -507,4 +510,10 @@ struct draw_stage *draw_clip_stage( struct draw_context *draw ) clipper->plane = draw->plane; return &clipper->stage; + + fail: + if (clipper) + clipper->stage.destroy( &clipper->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c index 8c13f40b55..87aaf1f85b 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_cull.c +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -120,8 +120,11 @@ static void cull_destroy( struct draw_stage *stage ) struct draw_stage *draw_cull_stage( struct draw_context *draw ) { struct cull_stage *cull = CALLOC_STRUCT(cull_stage); + if (cull == NULL) + goto fail; - draw_alloc_temp_verts( &cull->stage, 0 ); + if (!draw_alloc_temp_verts( &cull->stage, 0 )) + goto fail; cull->stage.draw = draw; cull->stage.next = NULL; @@ -133,4 +136,10 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw ) cull->stage.destroy = cull_destroy; return &cull->stage; + + fail: + if (cull) + cull->stage.destroy( &cull->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c index 2aeb309554..205000cbea 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -224,8 +224,11 @@ static void flatshade_destroy( struct draw_stage *stage ) struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) { struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage); + if (flatshade == NULL) + goto fail; - draw_alloc_temp_verts( &flatshade->stage, 2 ); + if (!draw_alloc_temp_verts( &flatshade->stage, 2 )) + goto fail; flatshade->stage.draw = draw; flatshade->stage.next = NULL; @@ -237,6 +240,12 @@ struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) flatshade->stage.destroy = flatshade_destroy; return &flatshade->stage; + + fail: + if (flatshade) + flatshade->stage.destroy( &flatshade->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index c1dc21cd32..ffec85ccdd 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -158,6 +158,8 @@ static void offset_destroy( struct draw_stage *stage ) struct draw_stage *draw_offset_stage( struct draw_context *draw ) { struct offset_stage *offset = CALLOC_STRUCT(offset_stage); + if (offset == NULL) + goto fail; draw_alloc_temp_verts( &offset->stage, 3 ); @@ -171,4 +173,10 @@ struct draw_stage *draw_offset_stage( struct draw_context *draw ) offset->stage.destroy = offset_destroy; return &offset->stage; + + fail: + if (offset) + offset->stage.destroy( &offset->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 5686729cd3..ac08aa10ce 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -686,7 +686,7 @@ pstip_set_polygon_stipple(struct pipe_context *pipe, * into the draw module's pipeline. This will not be used if the * hardware has native support for AA lines. */ -void +boolean draw_install_pstipple_stage(struct draw_context *draw, struct pipe_context *pipe) { @@ -698,7 +698,9 @@ draw_install_pstipple_stage(struct draw_context *draw, * Create / install AA line drawing / prim stage */ pstip = draw_pstip_stage( draw ); - assert(pstip); + if (pstip == NULL) + goto fail; + draw->pipeline.pstipple = &pstip->stage; pstip->pipe = pipe; @@ -724,4 +726,12 @@ draw_install_pstipple_stage(struct draw_context *draw, pipe->bind_sampler_states = pstip_bind_sampler_states; pipe->set_sampler_textures = pstip_set_sampler_textures; pipe->set_polygon_stipple = pstip_set_polygon_stipple; + + return TRUE; + + fail: + if (pstip) + pstip->stage.destroy( &pstip->stage ); + + return FALSE; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c index 453fd3ac71..5910dccc43 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -172,8 +172,11 @@ static void twoside_destroy( struct draw_stage *stage ) struct draw_stage *draw_twoside_stage( struct draw_context *draw ) { struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage); + if (twoside == NULL) + goto fail; - draw_alloc_temp_verts( &twoside->stage, 3 ); + if (!draw_alloc_temp_verts( &twoside->stage, 3 )) + goto fail; twoside->stage.draw = draw; twoside->stage.next = NULL; @@ -185,4 +188,10 @@ struct draw_stage *draw_twoside_stage( struct draw_context *draw ) twoside->stage.destroy = twoside_destroy; return &twoside->stage; + + fail: + if (twoside) + twoside->stage.destroy( &twoside->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c index d4ddfec1b3..eeb2bc43f9 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -177,8 +177,11 @@ static void unfilled_destroy( struct draw_stage *stage ) struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) { struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage); + if (unfilled == NULL) + goto fail; - draw_alloc_temp_verts( &unfilled->stage, 0 ); + if (!draw_alloc_temp_verts( &unfilled->stage, 0 )) + goto fail; unfilled->stage.draw = draw; unfilled->stage.next = NULL; @@ -191,4 +194,10 @@ struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) unfilled->stage.destroy = unfilled_destroy; return &unfilled->stage; + + fail: + if (unfilled) + unfilled->stage.destroy( &unfilled->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_util.c b/src/gallium/auxiliary/draw/draw_pipe_util.c index e9821de976..04438f4dd0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_util.c +++ b/src/gallium/auxiliary/draw/draw_pipe_util.c @@ -68,24 +68,28 @@ draw_pipe_passthrough_tri(struct draw_stage *stage, struct prim_header *header) */ boolean draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) { - unsigned i; - ubyte *store; - assert(!stage->tmp); stage->tmp = NULL; stage->nr_tmps = nr; - if (nr == 0) - return FALSE; - store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); - if (store == NULL) - return FALSE; + if (nr != 0) + { + unsigned i; + ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); + + if (store == NULL) + return FALSE; - stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); - - for (i = 0; i < nr; i++) - stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); + if (stage->tmp == NULL) { + FREE(store); + return FALSE; + } + + for (i = 0; i < nr; i++) + stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + } return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c index ffddc2f62c..a2e0812c89 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_validate.c +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -299,6 +299,8 @@ static void validate_destroy( struct draw_stage *stage ) struct draw_stage *draw_validate_stage( struct draw_context *draw ) { struct draw_stage *stage = CALLOC_STRUCT(draw_stage); + if (stage == NULL) + return NULL; stage->draw = draw; stage->next = NULL; diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index c5810febe0..afd5f5544d 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -443,8 +443,7 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, struct vbuf_render *render ) { struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); - - if(!vbuf) + if (vbuf == NULL) goto fail; vbuf->stage.draw = draw; @@ -461,7 +460,7 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 ); - if(!vbuf->indices) + if (!vbuf->indices) goto fail; vbuf->vertices = NULL; diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index 8101340680..ed08573382 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -249,8 +249,11 @@ static void widepoint_destroy( struct draw_stage *stage ) struct draw_stage *draw_wide_point_stage( struct draw_context *draw ) { struct widepoint_stage *wide = CALLOC_STRUCT(widepoint_stage); + if (wide == NULL) + goto fail; - draw_alloc_temp_verts( &wide->stage, 4 ); + if (!draw_alloc_temp_verts( &wide->stage, 4 )) + goto fail; wide->stage.draw = draw; wide->stage.next = NULL; @@ -262,4 +265,10 @@ struct draw_stage *draw_wide_point_stage( struct draw_context *draw ) wide->stage.destroy = widepoint_destroy; return &wide->stage; + + fail: + if (wide) + wide->stage.destroy( &wide->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 002ced2186..7735173042 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -271,6 +271,8 @@ static void fetch_emit_destroy( struct draw_pt_middle_end *middle ) struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ) { struct fetch_emit_middle_end *fetch_emit = CALLOC_STRUCT( fetch_emit_middle_end ); + if (fetch_emit == NULL) + return NULL; fetch_emit->base.prepare = fetch_emit_prepare; fetch_emit->base.run = fetch_emit_run; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 881e47d59d..98a2cb45e4 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -114,6 +114,8 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, (struct vertex_header *)MALLOC(fpme->vertex_size * fetch_count); if (!pipeline_verts) { + /* Not much we can do here - just skip the rendering. + */ assert(0); return; } diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index b61bb50664..3cc2941f96 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -487,6 +487,8 @@ static void vcache_destroy( struct draw_pt_front_end *frontend ) struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ) { struct vcache_frontend *vcache = CALLOC_STRUCT( vcache_frontend ); + if (vcache == NULL) + return NULL; vcache->base.prepare = vcache_prepare; vcache->base.run = NULL; -- cgit v1.2.3 From 30b4dc29091347252bc61d3be9370db0a45c16c3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 17:17:27 +0100 Subject: draw: more propogation -- pstipple stage. --- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 1 + src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 43 ++++++++++++++++++------- 2 files changed, 33 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index fbb5b45b40..7e5f8bd281 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -641,6 +641,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) */ if (!bind_aaline_fragment_shader(aaline)) { stage->line = draw_pipe_passthrough_line; + stage->line(stage, header); return; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index ac08aa10ce..61bdd29aa0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -320,7 +320,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, * Generate the frag shader we'll use for doing polygon stipple. * This will be the user's shader prefixed with a TEX and KIL instruction. */ -static void +static boolean generate_pstip_fs(struct pstip_stage *pstip) { const struct pipe_shader_state *orig_fs = &pstip->fs->state; @@ -332,6 +332,8 @@ generate_pstip_fs(struct pstip_stage *pstip) pstip_fs = *orig_fs; /* copy to init */ pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + if (pstip_fs.tokens == NULL) + return FALSE; memset(&transform, 0, sizeof(transform)); transform.wincoordInput = -1; @@ -355,6 +357,8 @@ generate_pstip_fs(struct pstip_stage *pstip) assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS); pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); + + return TRUE; } @@ -404,7 +408,7 @@ pstip_update_texture(struct pstip_stage *pstip) /** * Create the texture map we'll use for stippling. */ -static void +static boolean pstip_create_texture(struct pstip_stage *pstip) { struct pipe_context *pipe = pstip->pipe; @@ -421,7 +425,10 @@ pstip_create_texture(struct pstip_stage *pstip) texTemp.cpp = 1; pstip->texture = screen->texture_create(screen, &texTemp); - assert(pstip->texture->refcount == 1); + if (pstip->texture == NULL) + return FALSE; + + return TRUE; } @@ -430,7 +437,7 @@ pstip_create_texture(struct pstip_stage *pstip) * By using a mipmapped texture, we don't have to generate a different * texture image for each line size. */ -static void +static boolean pstip_create_sampler(struct pstip_stage *pstip) { struct pipe_sampler_state sampler; @@ -448,6 +455,10 @@ pstip_create_sampler(struct pstip_stage *pstip) sampler.max_lod = 0.0f; pstip->sampler_cso = pipe->create_sampler_state(pipe, &sampler); + if (pstip->sampler_cso == NULL) + return FALSE; + + return TRUE; } @@ -455,13 +466,15 @@ pstip_create_sampler(struct pstip_stage *pstip) * When we're about to draw our first AA line in a batch, this function is * called to tell the driver to bind our modified fragment shader. */ -static void +static boolean bind_pstip_fragment_shader(struct pstip_stage *pstip) { - if (!pstip->fs->pstip_fs) { - generate_pstip_fs(pstip); - } + if (!pstip->fs->pstip_fs || + !generate_pstip_fs(pstip)) + return FALSE; + pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs); + return TRUE; } @@ -486,7 +499,12 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) assert(stage->draw->rasterizer->poly_stipple_enable); /* bind our fragprog */ - bind_pstip_fragment_shader(pstip); + if (!bind_pstip_fragment_shader(pstip)) { + stage->tri = draw_pipe_passthrough_tri; + stage->tri(stage, header); + return; + } + /* how many samplers? */ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ @@ -706,8 +724,11 @@ draw_install_pstipple_stage(struct draw_context *draw, pstip->pipe = pipe; /* create special texture, sampler state */ - pstip_create_texture(pstip); - pstip_create_sampler(pstip); + if (!pstip_create_texture(pstip)) + goto fail; + + if (!pstip_create_sampler(pstip)) + goto fail; /* save original driver functions */ pstip->driver_create_fs_state = pipe->create_fs_state; -- cgit v1.2.3 From 0824fb1d6afc651c0ab814e96f08326c706de216 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 12:42:37 -0400 Subject: actually write the results --- src/gallium/auxiliary/draw/draw_vs_llvm.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 2ebf05526a..dcada66514 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -103,15 +103,16 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, /* Unswizzle all output results */ - for (slot = 1; slot < base->info.num_inputs; slot++) { - output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; - - output = (float (*)[4])((char *)output + output_stride); + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < base->info.num_outputs; slot++) { + output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + output = (float (*)[4])((char *)output + output_stride); } - } + } } -- cgit v1.2.3 From b17e123a8f20239e8e1fc6816ccf115d9ec57471 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:09:38 +0100 Subject: rtasm: propogate errors in x86 emit --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 34 +++++++++++++++++++++++++----- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 1 + 2 files changed, 30 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index f2c08c96a6..c2fe0e40f5 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -146,7 +146,10 @@ _fill( static void do_realloc( struct x86_function *p ) { - if (p->size == 0) { + if (p->store == p->error_overflow) { + p->csr = p->store; + } + else if (p->size == 0) { p->size = 1024; p->store = rtasm_exec_malloc(p->size); p->csr = p->store; @@ -156,10 +159,22 @@ static void do_realloc( struct x86_function *p ) unsigned char *tmp = p->store; p->size *= 2; p->store = rtasm_exec_malloc(p->size); - memcpy(p->store, tmp, used); - p->csr = p->store + used; + + if (p->store) { + memcpy(p->store, tmp, used); + p->csr = p->store + used; + } + else { + p->csr = p->store; + } + rtasm_exec_free(tmp); } + + if (p->store == NULL) { + p->store = p->csr = p->error_overflow; + p->size = 4; + } } /* Emit bytes to the instruction stream: @@ -1440,12 +1455,17 @@ void x86_init_func_size( struct x86_function *p, unsigned code_size ) { p->size = code_size; p->store = rtasm_exec_malloc(code_size); + if (p->store == NULL) { + p->store = p->error_overflow; + } p->csr = p->store; } void x86_release_func( struct x86_function *p ) { - rtasm_exec_free(p->store); + if (p->store && p->store != p->error_overflow) + rtasm_exec_free(p->store); + p->store = NULL; p->csr = NULL; p->size = 0; @@ -1456,7 +1476,11 @@ void (*x86_get_func( struct x86_function *p ))(void) { if (DISASSEM && p->store) debug_printf("disassemble %p %p\n", p->store, p->csr); - return (void (*)(void)) p->store; + + if (p->store == p->error_overflow) + return (void (*)(void)) NULL; + else + return (void (*)(void)) p->store; } #else diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index 5e99ceea70..695a1cef4e 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -43,6 +43,7 @@ struct x86_function { unsigned char *csr; unsigned stack_offset; int need_emms; + unsigned char error_overflow[4]; const char *fn; }; -- cgit v1.2.3 From d3db46eb8257c1b0cf823f1805ca00457be9aff3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:09:54 +0100 Subject: translate: fail on x86 rtasm fail --- src/gallium/auxiliary/translate/translate_sse.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index e587e5afec..f590d48b78 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -597,7 +597,12 @@ struct translate *translate_sse2_create( const struct translate_key *key ) goto fail; p->gen_run = (run_func)x86_get_func(&p->linear_func); + if (p->gen_run == NULL) + goto fail; + p->gen_run_elts = (run_elts_func)x86_get_func(&p->elt_func); + if (p->gen_run_elts == NULL) + goto fail; return &p->translate; -- cgit v1.2.3 From 785831fc6fc56815d9637c7dd2acbcee6dfbbb0a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:11:58 +0100 Subject: cso: propogate one easy error - many more --- src/gallium/auxiliary/cso_cache/cso_cache.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index 18acab0967..f607528fdc 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -290,6 +290,8 @@ void * cso_take_state(struct cso_cache *sc, struct cso_cache *cso_cache_create(void) { struct cso_cache *sc = MALLOC_STRUCT(cso_cache); + if (sc == NULL) + return NULL; sc->max_size = 4096; sc->blend_hash = cso_hash_create(); -- cgit v1.2.3 From 73c2711bb186692b866720058a09f5eb05950213 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:43:53 +0100 Subject: rtasm: clean up debug dumping a little --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 286 ++++++++++++++--------------- 1 file changed, 140 insertions(+), 146 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index c2fe0e40f5..10796c540d 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -77,69 +77,60 @@ _print_reg( debug_printf( "]" ); } -static void -_fill( - const char *op ) -{ - unsigned count = 10 - strlen( op ); - while( count-- ) { - debug_printf( " " ); - } -} +#define DUMP_START() debug_printf( "\n" ) +#define DUMP_END() debug_printf( "\n" ) -#define DUMP_START() debug_printf( "\nsse-dump start ----------------" ) -#define DUMP_END() debug_printf( "\nsse-dump end ----------------\n" ) -#define DUMP( OP ) debug_printf( "\n%s", OP ) +#define DUMP() do { \ + const char *foo = __FUNCTION__; \ + while (*foo && *foo != '_') \ + foo++; \ + if (*foo) \ + foo++; \ + debug_printf( "\n% 15s ", foo ); \ +} while (0) -#define DUMP_I( OP, I ) do { \ - debug_printf( "\n%s", OP ); \ - _fill( OP ); \ +#define DUMP_I( I ) do { \ + DUMP(); \ debug_printf( "%u", I ); \ } while( 0 ) -#define DUMP_R( OP, R0 ) do { \ - debug_printf( "\n%s", OP ); \ - _fill( OP ); \ +#define DUMP_R( R0 ) do { \ + DUMP(); \ _print_reg( R0 ); \ } while( 0 ) -#define DUMP_RR( OP, R0, R1 ) do { \ - debug_printf( "\n%s", OP ); \ - _fill( OP ); \ +#define DUMP_RR( R0, R1 ) do { \ + DUMP(); \ _print_reg( R0 ); \ debug_printf( ", " ); \ _print_reg( R1 ); \ } while( 0 ) -#define DUMP_RI( OP, R0, I ) do { \ - debug_printf( "\n%s", OP ); \ - _fill( OP ); \ +#define DUMP_RI( R0, I ) do { \ + DUMP(); \ _print_reg( R0 ); \ - debug_printf( ", " ); \ - debug_printf( "%u", I ); \ + debug_printf( ", %u", I ); \ } while( 0 ) -#define DUMP_RRI( OP, R0, R1, I ) do { \ - debug_printf( "\n%s", OP ); \ - _fill( OP ); \ +#define DUMP_RRI( R0, R1, I ) do { \ + DUMP(); \ _print_reg( R0 ); \ debug_printf( ", " ); \ _print_reg( R1 ); \ - debug_printf( ", " ); \ - debug_printf( "%u", I ); \ + debug_printf( ", %u", I ); \ } while( 0 ) #else #define DUMP_START() #define DUMP_END() -#define DUMP( OP ) -#define DUMP_I( OP, I ) -#define DUMP_R( OP, R0 ) -#define DUMP_RR( OP, R0, R1 ) -#define DUMP_RI( OP, R0, I ) -#define DUMP_RRI( OP, R0, R1, I ) +#define DUMP( ) +#define DUMP_I( I ) +#define DUMP_R( R0 ) +#define DUMP_RR( R0, R1 ) +#define DUMP_RI( R0, I ) +#define DUMP_RRI( R0, R1, I ) #endif @@ -173,7 +164,7 @@ static void do_realloc( struct x86_function *p ) if (p->store == NULL) { p->store = p->csr = p->error_overflow; - p->size = 4; + p->size = sizeof(p->error_overflow); } } @@ -397,7 +388,7 @@ unsigned char *x86_jcc_forward( struct x86_function *p, unsigned char *x86_jmp_forward( struct x86_function *p) { - DUMP( __FUNCTION__ ); + DUMP(); emit_1ub(p, 0xe9); emit_1i(p, 0); return x86_get_label(p); @@ -405,7 +396,7 @@ unsigned char *x86_jmp_forward( struct x86_function *p) unsigned char *x86_call_forward( struct x86_function *p) { - DUMP( __FUNCTION__ ); + DUMP(); emit_1ub(p, 0xe8); emit_1i(p, 0); @@ -422,7 +413,7 @@ void x86_fixup_fwd_jump( struct x86_function *p, void x86_jmp( struct x86_function *p, unsigned char *label) { - DUMP_I( __FUNCTION__, label ); + DUMP_I( label ); emit_1ub(p, 0xe9); emit_1i(p, pointer_to_intptr( label ) - pointer_to_intptr( x86_get_label(p) ) - 4); } @@ -439,14 +430,14 @@ static unsigned char *cptr( void (*label)() ) */ void x86_call( struct x86_function *p, void (*label)()) { - DUMP_I( __FUNCTION__, label ); + DUMP_I( label ); emit_1ub(p, 0xe8); emit_1i(p, cptr(label) - x86_get_label(p) - 4); } #else void x86_call( struct x86_function *p, struct x86_reg reg) { - DUMP_R( __FUNCTION__, reg ); + DUMP_R( reg ); emit_1ub(p, 0xff); emit_modrm_noreg(p, 2, reg); } @@ -459,7 +450,7 @@ void x86_call( struct x86_function *p, struct x86_reg reg) */ void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) { - DUMP_RI( __FUNCTION__, dst, imm ); + DUMP_RI( dst, imm ); assert(dst.mod == mod_REG); emit_1ub(p, 0xb8 + dst.idx); emit_1i(p, imm); @@ -468,7 +459,7 @@ void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) void x86_push( struct x86_function *p, struct x86_reg reg ) { - DUMP_R( __FUNCTION__, reg ); + DUMP_R( reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x50 + reg.idx); p->stack_offset += 4; @@ -477,7 +468,7 @@ void x86_push( struct x86_function *p, void x86_pop( struct x86_function *p, struct x86_reg reg ) { - DUMP_R( __FUNCTION__, reg ); + DUMP_R( reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x58 + reg.idx); p->stack_offset -= 4; @@ -486,7 +477,7 @@ void x86_pop( struct x86_function *p, void x86_inc( struct x86_function *p, struct x86_reg reg ) { - DUMP_R( __FUNCTION__, reg ); + DUMP_R( reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x40 + reg.idx); } @@ -494,20 +485,20 @@ void x86_inc( struct x86_function *p, void x86_dec( struct x86_function *p, struct x86_reg reg ) { - DUMP_R( __FUNCTION__, reg ); + DUMP_R( reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x48 + reg.idx); } void x86_ret( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_1ub(p, 0xc3); } void x86_sahf( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_1ub(p, 0x9e); } @@ -515,7 +506,7 @@ void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm( p, 0x8b, 0x89, dst, src ); } @@ -523,7 +514,7 @@ void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm( p, 0x33, 0x31, dst, src ); } @@ -531,7 +522,7 @@ void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm( p, 0x3b, 0x39, dst, src ); } @@ -539,7 +530,7 @@ void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_1ub(p, 0x8d); emit_modrm( p, dst, src ); } @@ -548,7 +539,7 @@ void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_1ub(p, 0x85); emit_modrm( p, dst, src ); } @@ -557,7 +548,7 @@ void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm(p, 0x03, 0x01, dst, src ); } @@ -566,7 +557,7 @@ void x86_add( struct x86_function *p, void x86_mul( struct x86_function *p, struct x86_reg src ) { - DUMP_R( __FUNCTION__, src ); + DUMP_R( src ); emit_1ub(p, 0xf7); emit_modrm_noreg(p, 4, src ); } @@ -576,7 +567,7 @@ void x86_imul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0xAF); emit_modrm(p, dst, src); } @@ -586,7 +577,7 @@ void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm(p, 0x2b, 0x29, dst, src ); } @@ -594,7 +585,7 @@ void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm( p, 0x0b, 0x09, dst, src ); } @@ -602,7 +593,7 @@ void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm( p, 0x23, 0x21, dst, src ); } @@ -617,7 +608,7 @@ void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, 0xF3, X86_TWOB); emit_op_modrm( p, 0x10, 0x11, dst, src ); } @@ -626,7 +617,7 @@ void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x28, 0x29, dst, src ); } @@ -635,7 +626,7 @@ void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x10, 0x11, dst, src ); } @@ -644,7 +635,7 @@ void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.mod != mod_REG || src.mod != mod_REG); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ @@ -654,7 +645,7 @@ void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.mod != mod_REG || src.mod != mod_REG); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ @@ -664,7 +655,7 @@ void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x5F); emit_modrm( p, dst, src ); } @@ -673,7 +664,7 @@ void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x5F); emit_modrm( p, dst, src ); } @@ -682,7 +673,7 @@ void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x5E); emit_modrm( p, dst, src ); } @@ -691,7 +682,7 @@ void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x5D); emit_modrm( p, dst, src ); } @@ -700,7 +691,7 @@ void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x5C); emit_modrm( p, dst, src ); } @@ -709,7 +700,7 @@ void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x59); emit_modrm( p, dst, src ); } @@ -718,7 +709,7 @@ void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x59); emit_modrm( p, dst, src ); } @@ -727,7 +718,7 @@ void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x58); emit_modrm( p, dst, src ); } @@ -736,7 +727,7 @@ void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x58); emit_modrm( p, dst, src ); } @@ -745,7 +736,7 @@ void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x55); emit_modrm( p, dst, src ); } @@ -754,7 +745,7 @@ void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x54); emit_modrm( p, dst, src ); } @@ -763,7 +754,7 @@ void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x52); emit_modrm( p, dst, src ); } @@ -772,7 +763,7 @@ void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x52); emit_modrm( p, dst, src ); @@ -782,7 +773,7 @@ void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.mod == mod_REG && src.mod == mod_REG); emit_2ub(p, X86_TWOB, 0x12); emit_modrm( p, dst, src ); @@ -792,7 +783,7 @@ void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.mod == mod_REG && src.mod == mod_REG); emit_2ub(p, X86_TWOB, 0x16); emit_modrm( p, dst, src ); @@ -802,7 +793,7 @@ void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x56); emit_modrm( p, dst, src ); } @@ -811,7 +802,7 @@ void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x57); emit_modrm( p, dst, src ); } @@ -820,7 +811,7 @@ void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.file == file_MMX && (src.file == file_XMM || src.mod != mod_REG)); @@ -834,7 +825,7 @@ void sse2_cvtdq2ps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x5b); emit_modrm( p, dst, src ); } @@ -848,7 +839,7 @@ void sse_shufps( struct x86_function *p, struct x86_reg src, unsigned char shuf) { - DUMP_RRI( __FUNCTION__, dst, src, shuf ); + DUMP_RRI( dst, src, shuf ); emit_2ub(p, X86_TWOB, 0xC6); emit_modrm(p, dst, src); emit_1ub(p, shuf); @@ -859,7 +850,7 @@ void sse_cmpps( struct x86_function *p, struct x86_reg src, unsigned char cc) { - DUMP_RRI( "CMPPS", dst, src, cc ); + DUMP_RRI( dst, src, cc ); emit_2ub(p, X86_TWOB, 0xC2); emit_modrm(p, dst, src); emit_1ub(p, cc); @@ -869,7 +860,7 @@ void sse_pmovmskb( struct x86_function *p, struct x86_reg dst, struct x86_reg src) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0xD7); emit_modrm(p, dst, src); } @@ -886,7 +877,7 @@ void sse2_pshufd( struct x86_function *p, struct x86_reg src, unsigned char shuf) { - DUMP_RRI( __FUNCTION__, dst, src, shuf ); + DUMP_RRI( dst, src, shuf ); emit_3ub(p, 0x66, X86_TWOB, 0x70); emit_modrm(p, dst, src); emit_1ub(p, shuf); @@ -896,7 +887,7 @@ void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); emit_modrm( p, dst, src ); } @@ -905,7 +896,7 @@ void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x5B); emit_modrm( p, dst, src ); } @@ -914,7 +905,7 @@ void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x6B); emit_modrm( p, dst, src ); } @@ -923,7 +914,7 @@ void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x63); emit_modrm( p, dst, src ); } @@ -932,7 +923,7 @@ void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x67); emit_modrm( p, dst, src ); } @@ -941,7 +932,7 @@ void sse2_punpcklbw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x60); emit_modrm( p, dst, src ); } @@ -951,7 +942,7 @@ void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x53); emit_modrm( p, dst, src ); } @@ -960,7 +951,7 @@ void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x53); emit_modrm( p, dst, src ); } @@ -969,7 +960,7 @@ void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, 0x66, X86_TWOB); emit_op_modrm( p, 0x6e, 0x7e, dst, src ); } @@ -982,35 +973,35 @@ void sse2_movd( struct x86_function *p, */ void x87_fist( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); emit_1ub(p, 0xdb); emit_modrm_noreg(p, 2, dst); } void x87_fistp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); emit_1ub(p, 0xdb); emit_modrm_noreg(p, 3, dst); } void x87_fild( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); emit_1ub(p, 0xdf); emit_modrm_noreg(p, 0, arg); } void x87_fldz( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xee); } void x87_fldcw( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); assert(arg.file == file_REG32); assert(arg.mod != mod_REG); emit_1ub(p, 0xd9); @@ -1019,31 +1010,31 @@ void x87_fldcw( struct x86_function *p, struct x86_reg arg ) void x87_fld1( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xe8); } void x87_fldl2e( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xea); } void x87_fldln2( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xed); } void x87_fwait( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_1ub(p, 0x9b); } void x87_fnclex( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xdb, 0xe2); } @@ -1082,7 +1073,7 @@ static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86 void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xc8, 0xdc, 0xc8, @@ -1091,7 +1082,7 @@ void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xe0, 0xdc, 0xe8, @@ -1100,7 +1091,7 @@ void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xe8, 0xdc, 0xe0, @@ -1109,7 +1100,7 @@ void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xc0, 0xdc, 0xc0, @@ -1118,7 +1109,7 @@ void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xf0, 0xdc, 0xf8, @@ -1127,7 +1118,7 @@ void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xf8, 0xdc, 0xf0, @@ -1136,7 +1127,7 @@ void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fmulp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xc8+dst.idx); @@ -1144,7 +1135,7 @@ void x87_fmulp( struct x86_function *p, struct x86_reg dst ) void x87_fsubp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xe8+dst.idx); @@ -1152,7 +1143,7 @@ void x87_fsubp( struct x86_function *p, struct x86_reg dst ) void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xe0+dst.idx); @@ -1160,7 +1151,7 @@ void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) void x87_faddp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xc0+dst.idx); @@ -1168,7 +1159,7 @@ void x87_faddp( struct x86_function *p, struct x86_reg dst ) void x87_fdivp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xf8+dst.idx); @@ -1176,7 +1167,7 @@ void x87_fdivp( struct x86_function *p, struct x86_reg dst ) void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xf0+dst.idx); @@ -1184,83 +1175,83 @@ void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) void x87_fucom( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); assert(arg.file == file_x87); emit_2ub(p, 0xdd, 0xe0+arg.idx); } void x87_fucomp( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); assert(arg.file == file_x87); emit_2ub(p, 0xdd, 0xe8+arg.idx); } void x87_fucompp( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xda, 0xe9); } void x87_fxch( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); assert(arg.file == file_x87); emit_2ub(p, 0xd9, 0xc8+arg.idx); } void x87_fabs( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xe1); } void x87_fchs( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xe0); } void x87_fcos( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xff); } void x87_fprndint( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xfc); } void x87_fscale( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xfd); } void x87_fsin( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xfe); } void x87_fsincos( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xfb); } void x87_fsqrt( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xfa); } void x87_fxtract( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xf4); } @@ -1270,7 +1261,7 @@ void x87_fxtract( struct x86_function *p ) */ void x87_f2xm1( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xf0); } @@ -1279,7 +1270,7 @@ void x87_f2xm1( struct x86_function *p ) */ void x87_fyl2x( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xf1); } @@ -1290,14 +1281,14 @@ void x87_fyl2x( struct x86_function *p ) */ void x87_fyl2xp1( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xf9); } void x87_fld( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); if (arg.file == file_x87) emit_2ub(p, 0xd9, 0xc0 + arg.idx); else { @@ -1308,7 +1299,7 @@ void x87_fld( struct x86_function *p, struct x86_reg arg ) void x87_fst( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); if (dst.file == file_x87) emit_2ub(p, 0xdd, 0xd0 + dst.idx); else { @@ -1319,7 +1310,7 @@ void x87_fst( struct x86_function *p, struct x86_reg dst ) void x87_fstp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); if (dst.file == file_x87) emit_2ub(p, 0xdd, 0xd8 + dst.idx); else { @@ -1330,7 +1321,7 @@ void x87_fstp( struct x86_function *p, struct x86_reg dst ) void x87_fcom( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); if (dst.file == file_x87) emit_2ub(p, 0xd8, 0xd0 + dst.idx); else { @@ -1341,7 +1332,7 @@ void x87_fcom( struct x86_function *p, struct x86_reg dst ) void x87_fcomp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); if (dst.file == file_x87) emit_2ub(p, 0xd8, 0xd8 + dst.idx); else { @@ -1353,7 +1344,7 @@ void x87_fcomp( struct x86_function *p, struct x86_reg dst ) void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_REG32); if (dst.idx == reg_AX && @@ -1383,7 +1374,7 @@ void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.file == file_MMX && (src.file == file_MMX || src.mod != mod_REG)); @@ -1397,7 +1388,7 @@ void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.file == file_MMX && (src.file == file_MMX || src.mod != mod_REG)); @@ -1411,7 +1402,7 @@ void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); p->need_emms = 1; emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x6e, 0x7e, dst, src ); @@ -1421,7 +1412,7 @@ void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); p->need_emms = 1; emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x6f, 0x7f, dst, src ); @@ -1449,6 +1440,7 @@ void x86_init_func( struct x86_function *p ) p->size = 0; p->store = NULL; p->csr = p->store; + DUMP_START(); } void x86_init_func_size( struct x86_function *p, unsigned code_size ) @@ -1459,6 +1451,7 @@ void x86_init_func_size( struct x86_function *p, unsigned code_size ) p->store = p->error_overflow; } p->csr = p->store; + DUMP_START(); } void x86_release_func( struct x86_function *p ) @@ -1474,6 +1467,7 @@ void x86_release_func( struct x86_function *p ) void (*x86_get_func( struct x86_function *p ))(void) { + DUMP_END(); if (DISASSEM && p->store) debug_printf("disassemble %p %p\n", p->store, p->csr); -- cgit v1.2.3 From 73706deef59c35472d2410411403f30c9603f22f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:48:08 +0100 Subject: rtasm: quieten sse_enabled debug --- src/gallium/auxiliary/rtasm/rtasm_cpu.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c index 175245a9f6..f01e12faa0 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_cpu.c +++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c @@ -32,7 +32,16 @@ static boolean rtasm_sse_enabled(void) { - return !debug_get_bool_option("GALLIUM_NOSSE", FALSE); + static boolean firsttime = 1; + static boolean enabled; + + /* This gets called quite often at the moment: + */ + if (firsttime) { + enabled = !debug_get_bool_option("GALLIUM_NOSSE", FALSE); + firsttime = FALSE; + } + return enabled; } int rtasm_cpu_has_sse(void) -- cgit v1.2.3 From a945420ae6f96f0d7024f97e37ffd31329865a84 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:48:21 +0100 Subject: rtasm: debug some missing funcs --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 10796c540d..3cd45d7dd9 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -364,6 +364,7 @@ void x86_jcc( struct x86_function *p, unsigned char *label ) { intptr_t offset = pointer_to_intptr( label ) - (pointer_to_intptr( x86_get_label(p) ) + 2); + DUMP_I(cc); if (offset <= 127 && offset >= -128) { emit_1ub(p, 0x70 + cc); @@ -381,6 +382,7 @@ void x86_jcc( struct x86_function *p, unsigned char *x86_jcc_forward( struct x86_function *p, enum x86_cc cc ) { + DUMP_I(cc); emit_2ub(p, 0x0f, 0x80 + cc); emit_1i(p, 0); return x86_get_label(p); @@ -1365,6 +1367,7 @@ void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) void mmx_emms( struct x86_function *p ) { + DUMP(); assert(p->need_emms); emit_2ub(p, 0x0f, 0x77); p->need_emms = 0; -- cgit v1.2.3 From fb1c09305ea8cb727514c53a0346d90e78eeb05f Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 15:15:31 -0400 Subject: Use llvm 2.3 (2.2 won't work because of a lot of problems, e.g. lack of constant vectors handling in execution engine) --- src/gallium/auxiliary/gallivm/Makefile | 12 +++--- src/gallium/auxiliary/gallivm/instructions.cpp | 42 +++++++++---------- src/gallium/auxiliary/gallivm/instructions.h | 4 +- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 49 ++++++++++++----------- src/gallium/auxiliary/gallivm/instructionssoa.h | 4 +- src/gallium/auxiliary/gallivm/storage.cpp | 32 +++++++-------- src/gallium/auxiliary/gallivm/storagesoa.cpp | 10 ++--- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 4 +- 8 files changed, 79 insertions(+), 78 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/Makefile b/src/gallium/auxiliary/gallivm/Makefile index 6bfd187fb3..c3f7bfba93 100644 --- a/src/gallium/auxiliary/gallivm/Makefile +++ b/src/gallium/auxiliary/gallivm/Makefile @@ -65,14 +65,14 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) gallivm_builtins.cpp: llvm_builtins.c - clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp.bin - (echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ - rm temp.bin + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp1.bin + (echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp1.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ + rm temp1.bin gallivmsoabuiltins.cpp: soabuiltins.c - clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp.bin - (echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ - rm temp.bin + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp2.bin + (echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp2.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ + rm temp2.bin # Emacs tags tags: diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp index b35d6790f7..95a670edaf 100644 --- a/src/gallium/auxiliary/gallivm/instructions.cpp +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -139,12 +139,12 @@ llvm::Value *Instructions::callFSqrt(llvm::Value *val) // predeclare the intrinsic std::vector fsqrtArgs; fsqrtArgs.push_back(Type::FloatTy); - ParamAttrsList *fsqrtPal = 0; + PAListPtr fsqrtPal; FunctionType* fsqrtType = FunctionType::get( /*Result=*/Type::FloatTy, /*Params=*/fsqrtArgs, /*isVarArg=*/false); - m_llvmFSqrt = new Function( + m_llvmFSqrt = Function::Create( /*Type=*/fsqrtType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"llvm.sqrt.f32", m_mod); @@ -196,12 +196,12 @@ llvm::Value *Instructions::callFAbs(llvm::Value *val) // predeclare the intrinsic std::vector fabsArgs; fabsArgs.push_back(Type::FloatTy); - ParamAttrsList *fabsPal = 0; + PAListPtr fabsPal; FunctionType* fabsType = FunctionType::get( /*Result=*/Type::FloatTy, /*Params=*/fabsArgs, /*isVarArg=*/false); - m_llvmFAbs = new Function( + m_llvmFAbs = Function::Create( /*Type=*/fabsType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"fabs", m_mod); @@ -239,12 +239,12 @@ llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2) std::vector powArgs; powArgs.push_back(Type::FloatTy); powArgs.push_back(Type::FloatTy); - ParamAttrsList *powPal = 0; + PAListPtr powPal; FunctionType* powType = FunctionType::get( /*Result=*/Type::FloatTy, /*Params=*/powArgs, /*isVarArg=*/false); - m_llvmPow = new Function( + m_llvmPow = Function::Create( /*Type=*/powType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"llvm.pow.f32", m_mod); @@ -338,12 +338,12 @@ llvm::Value * Instructions::callFloor(llvm::Value *val) // predeclare the intrinsic std::vector floorArgs; floorArgs.push_back(Type::FloatTy); - ParamAttrsList *floorPal = 0; + PAListPtr floorPal; FunctionType* floorType = FunctionType::get( /*Result=*/Type::FloatTy, /*Params=*/floorArgs, /*isVarArg=*/false); - m_llvmFloor = new Function( + m_llvmFloor = Function::Create( /*Type=*/floorType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"floorf", m_mod); @@ -381,12 +381,12 @@ llvm::Value * Instructions::callFLog(llvm::Value *val) // predeclare the intrinsic std::vector flogArgs; flogArgs.push_back(Type::FloatTy); - ParamAttrsList *flogPal = 0; + PAListPtr flogPal; FunctionType* flogType = FunctionType::get( /*Result=*/Type::FloatTy, /*Params=*/flogArgs, /*isVarArg=*/false); - m_llvmFlog = new Function( + m_llvmFlog = Function::Create( /*Type=*/flogType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"logf", m_mod); @@ -509,12 +509,12 @@ void Instructions::printVector(llvm::Value *val) llvm::Function * Instructions::declarePrintf() { std::vector args; - ParamAttrsList *params = 0; + PAListPtr params; FunctionType* funcTy = FunctionType::get( /*Result=*/IntegerType::get(32), /*Params=*/args, /*isVarArg=*/true); - Function* func_printf = new Function( + Function* func_printf = Function::Create( /*Type=*/funcTy, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"printf", m_mod); @@ -638,8 +638,8 @@ llvm::Value * Instructions::abs(llvm::Value *in) void Instructions::ifop(llvm::Value *in) { - BasicBlock *ifthen = new BasicBlock(name("ifthen"), m_func,0); - BasicBlock *ifend = new BasicBlock(name("ifthenend"), m_func,0); + BasicBlock *ifthen = BasicBlock::Create(name("ifthen"), m_func,0); + BasicBlock *ifend = BasicBlock::Create(name("ifthenend"), m_func,0); //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0); //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0); @@ -665,7 +665,7 @@ llvm::BasicBlock * Instructions::currentBlock() const void Instructions::elseop() { assert(!m_ifStack.empty()); - BasicBlock *ifend = new BasicBlock(name("ifend"), m_func,0); + BasicBlock *ifend = BasicBlock::Create(name("ifend"), m_func,0); m_builder.CreateBr(ifend); m_builder.SetInsertPoint(m_ifStack.top()); currentBlock()->setName(name("ifelse")); @@ -692,8 +692,8 @@ llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2, void Instructions::beginLoop() { - BasicBlock *begin = new BasicBlock(name("loop"), m_func,0); - BasicBlock *end = new BasicBlock(name("endloop"), m_func,0); + BasicBlock *begin = BasicBlock::Create(name("loop"), m_func,0); + BasicBlock *end = BasicBlock::Create(name("endloop"), m_func,0); m_builder.CreateBr(begin); Loop loop; @@ -716,7 +716,7 @@ void Instructions::endLoop() void Instructions::brk() { assert(!m_loopStack.empty()); - BasicBlock *unr = new BasicBlock(name("unreachable"), m_func,0); + BasicBlock *unr = BasicBlock::Create(name("unreachable"), m_func,0); m_builder.CreateBr(m_loopStack.top().end); m_builder.SetInsertPoint(unr); } @@ -765,13 +765,13 @@ llvm::Function * Instructions::declareFunc(int label) args.push_back(vecPtr); args.push_back(vecPtr); args.push_back(vecPtr); - ParamAttrsList *params = 0; + PAListPtr params; FunctionType *funcType = FunctionType::get( /*Result=*/Type::VoidTy, /*Params=*/args, /*isVarArg=*/false); std::string name = createFuncName(label); - Function *func = new Function( + Function *func = Function::Create( /*Type=*/funcType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/name.c_str(), m_mod); @@ -789,7 +789,7 @@ void Instructions::bgnSub(unsigned label) ptr_INPUT->setName("INPUT"); m_storage->pushArguments(ptr_INPUT); - llvm::BasicBlock *entry = new BasicBlock("entry", func, 0); + llvm::BasicBlock *entry = BasicBlock::Create("entry", func, 0); m_func = func; m_builder.SetInsertPoint(entry); diff --git a/src/gallium/auxiliary/gallivm/instructions.h b/src/gallium/auxiliary/gallivm/instructions.h index 9ebc17dd8e..19ca84ddc6 100644 --- a/src/gallium/auxiliary/gallivm/instructions.h +++ b/src/gallium/auxiliary/gallivm/instructions.h @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -125,7 +125,7 @@ private: llvm::Module *m_mod; llvm::Function *m_func; char m_name[32]; - llvm::LLVMFoldingBuilder m_builder; + llvm::IRBuilder m_builder; int m_idx; llvm::VectorType *m_floatVecType; diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 3c16a3692d..f0122802db 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -38,6 +38,7 @@ #include #include #include +//#include #include #include @@ -237,32 +238,32 @@ llvm::Value * InstructionsSoa::allocaTemp() std::vector indices; indices.push_back(m_storage->constantInt(0)); indices.push_back(m_storage->constantInt(0)); - GetElementPtrInst *getElem = new GetElementPtrInst(alloca, - indices.begin(), - indices.end(), - name("allocaPtr"), - m_builder.GetInsertBlock()); + GetElementPtrInst *getElem = GetElementPtrInst::Create(alloca, + indices.begin(), + indices.end(), + name("allocaPtr"), + m_builder.GetInsertBlock()); return getElem; } std::vector InstructionsSoa::allocaToResult(llvm::Value *allocaPtr) { - GetElementPtrInst *xElemPtr = new GetElementPtrInst(allocaPtr, - m_storage->constantInt(0), - name("xPtr"), - m_builder.GetInsertBlock()); - GetElementPtrInst *yElemPtr = new GetElementPtrInst(allocaPtr, - m_storage->constantInt(1), - name("yPtr"), - m_builder.GetInsertBlock()); - GetElementPtrInst *zElemPtr = new GetElementPtrInst(allocaPtr, - m_storage->constantInt(2), - name("zPtr"), - m_builder.GetInsertBlock()); - GetElementPtrInst *wElemPtr = new GetElementPtrInst(allocaPtr, - m_storage->constantInt(3), - name("wPtr"), - m_builder.GetInsertBlock()); + GetElementPtrInst *xElemPtr = GetElementPtrInst::Create(allocaPtr, + m_storage->constantInt(0), + name("xPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *yElemPtr = GetElementPtrInst::Create(allocaPtr, + m_storage->constantInt(1), + name("yPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *zElemPtr = GetElementPtrInst::Create(allocaPtr, + m_storage->constantInt(2), + name("zPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *wElemPtr = GetElementPtrInst::Create(allocaPtr, + m_storage->constantInt(3), + name("wPtr"), + m_builder.GetInsertBlock()); std::vector res(4); res[0] = new LoadInst(xElemPtr, name("xRes"), false, m_builder.GetInsertBlock()); @@ -388,10 +389,10 @@ void InstructionsSoa::injectFunction(llvm::Function *originalFunc, int op) llvm::Function *func = 0; if (originalFunc->isDeclaration()) { std::cout << "function decleration" <getFunctionType(), GlobalValue::ExternalLinkage, - originalFunc->getName(), currentModule()); + func = Function::Create(originalFunc->getFunctionType(), GlobalValue::ExternalLinkage, + originalFunc->getName(), currentModule()); func->setCallingConv(CallingConv::C); - const ParamAttrsList *pal = 0; + const PAListPtr pal; func->setParamAttrs(pal); currentModule()->dump(); } else { diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h index b9104ea286..060ee72f2e 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -29,7 +29,7 @@ #define INSTRUCTIONSSOA_H #include -#include +#include #include #include @@ -87,7 +87,7 @@ private: const std::vector in3); void injectFunction(llvm::Function *originalFunc, int op = TGSI_OPCODE_LAST); private: - llvm::LLVMFoldingBuilder m_builder; + llvm::IRBuilder m_builder; StorageSoa *m_storage; std::map m_functionsMap; diff --git a/src/gallium/auxiliary/gallivm/storage.cpp b/src/gallium/auxiliary/gallivm/storage.cpp index c4326de8c5..9d9fd12360 100644 --- a/src/gallium/auxiliary/gallivm/storage.cpp +++ b/src/gallium/auxiliary/gallivm/storage.cpp @@ -186,26 +186,26 @@ llvm::Value *Storage::maskWrite(llvm::Value *src, int mask, llvm::Value *templ) if ((mask & TGSI_WRITEMASK_X)) { llvm::Value *x = new ExtractElementInst(src, unsigned(0), name("x"), m_block); - dst = new InsertElementInst(dst, x, unsigned(0), - name("dstx"), m_block); + dst = InsertElementInst::Create(dst, x, unsigned(0), + name("dstx"), m_block); } if ((mask & TGSI_WRITEMASK_Y)) { llvm::Value *y = new ExtractElementInst(src, unsigned(1), name("y"), m_block); - dst = new InsertElementInst(dst, y, unsigned(1), - name("dsty"), m_block); + dst = InsertElementInst::Create(dst, y, unsigned(1), + name("dsty"), m_block); } if ((mask & TGSI_WRITEMASK_Z)) { llvm::Value *z = new ExtractElementInst(src, unsigned(2), name("z"), m_block); - dst = new InsertElementInst(dst, z, unsigned(2), - name("dstz"), m_block); + dst = InsertElementInst::Create(dst, z, unsigned(2), + name("dstz"), m_block); } if ((mask & TGSI_WRITEMASK_W)) { llvm::Value *w = new ExtractElementInst(src, unsigned(3), name("w"), m_block); - dst = new InsertElementInst(dst, w, unsigned(3), - name("dstw"), m_block); + dst = InsertElementInst::Create(dst, w, unsigned(3), + name("dstw"), m_block); } return dst; } @@ -308,11 +308,11 @@ llvm::Value * Storage::elemPtr(Args arg) std::vector indices; indices.push_back(constantInt(0)); indices.push_back(constantInt(static_cast(arg))); - GetElementPtrInst *getElem = new GetElementPtrInst(m_INPUT, - indices.begin(), - indices.end(), - name("input_ptr"), - m_block); + GetElementPtrInst *getElem = GetElementPtrInst::Create(m_INPUT, + indices.begin(), + indices.end(), + name("input_ptr"), + m_block); return new LoadInst(getElem, name("input_field"), false, m_block); } @@ -322,7 +322,7 @@ llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, GetElementPtrInst *getElem = 0; if (indIdx) { - getElem = new GetElementPtrInst(ptr, + getElem = GetElementPtrInst::Create(ptr, BinaryOperator::create(Instruction::Add, indIdx, constantInt(idx), @@ -331,7 +331,7 @@ llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, name("field"), m_block); } else { - getElem = new GetElementPtrInst(ptr, + getElem = GetElementPtrInst::Create(ptr, constantInt(idx), name("field"), m_block); @@ -350,7 +350,7 @@ void Storage::setKilElement(llvm::Value *val) std::vector indices; indices.push_back(constantInt(0)); indices.push_back(constantInt(static_cast(KilArg))); - GetElementPtrInst *elem = new GetElementPtrInst(m_INPUT, + GetElementPtrInst *elem = GetElementPtrInst::Create(m_INPUT, indices.begin(), indices.end(), name("kil_ptr"), diff --git a/src/gallium/auxiliary/gallivm/storagesoa.cpp b/src/gallium/auxiliary/gallivm/storagesoa.cpp index bb6fe3d7e1..0e6e68c9d7 100644 --- a/src/gallium/auxiliary/gallivm/storagesoa.cpp +++ b/src/gallium/auxiliary/gallivm/storagesoa.cpp @@ -207,11 +207,11 @@ llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, llvm::Value *index, indices.push_back(index); indices.push_back(constantInt(channel)); - GetElementPtrInst *getElem = new GetElementPtrInst(ptr, - indices.begin(), - indices.end(), - name("ptr"), - m_block); + GetElementPtrInst *getElem = GetElementPtrInst::Create(ptr, + indices.begin(), + indices.end(), + name("ptr"), + m_block); return getElem; } diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index ab9e7a06fb..ab8c851f14 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -1014,7 +1014,7 @@ tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens) Value *ptr_INPUT = args++; ptr_INPUT->setName("input"); - BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0); tgsi_parse_init(&parse, tokens); @@ -1085,7 +1085,7 @@ llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, Value *temps = args++; temps->setName("temps"); - BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0); tgsi_parse_init(&parse, tokens); -- cgit v1.2.3 From 1dc5e56f3e48b629daa18c2d8631c96bda638eb6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 20:25:47 +0100 Subject: cso: provide functions to bind fs/vs handles directly --- src/gallium/auxiliary/cso_cache/cso_context.c | 32 ++++++++++++++++++++------- src/gallium/auxiliary/cso_cache/cso_context.h | 4 ++++ 2 files changed, 28 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 87995c80c3..e6366e7b14 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -422,6 +422,16 @@ void cso_restore_rasterizer(struct cso_context *ctx) } +void cso_set_fragment_shader_handle(struct cso_context *ctx, + void *handle ) +{ + if (ctx->fragment_shader != handle) { + ctx->fragment_shader = handle; + ctx->pipe->bind_fs_state(ctx->pipe, handle); + } +} + + void cso_set_fragment_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) { @@ -453,10 +463,7 @@ void cso_set_fragment_shader(struct cso_context *ctx, handle = ((struct cso_fragment_shader *)cso_hash_iter_data(iter))->data; } - if (ctx->fragment_shader != handle) { - ctx->fragment_shader = handle; - ctx->pipe->bind_fs_state(ctx->pipe, handle); - } + cso_set_fragment_shader_handle( ctx, handle ); } void cso_save_fragment_shader(struct cso_context *ctx) @@ -476,6 +483,16 @@ void cso_restore_fragment_shader(struct cso_context *ctx) } +void cso_set_vertex_shader_handle(struct cso_context *ctx, + void *handle ) +{ + if (ctx->vertex_shader != handle) { + ctx->vertex_shader = handle; + ctx->pipe->bind_vs_state(ctx->pipe, handle); + } +} + + void cso_set_vertex_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) @@ -503,12 +520,11 @@ void cso_set_vertex_shader(struct cso_context *ctx, handle = ((struct cso_vertex_shader *)cso_hash_iter_data(iter))->data; } - if (ctx->vertex_shader != handle) { - ctx->vertex_shader = handle; - ctx->pipe->bind_vs_state(ctx->pipe, handle); - } + cso_set_vertex_shader_handle( ctx, handle ); } + + void cso_save_vertex_shader(struct cso_context *ctx) { assert(!ctx->vertex_shader_saved); diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 665e8d9911..945f4881a8 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -96,6 +96,8 @@ void cso_restore_sampler_textures( struct cso_context *cso ); * (eg mesa's internall-generated texenv programs), it will be up to * the state tracker to implement their own specialized caching. */ +void cso_set_fragment_shader_handle(struct cso_context *ctx, + void *handle ); void cso_set_fragment_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); void cso_save_fragment_shader(struct cso_context *cso); @@ -103,6 +105,8 @@ void cso_restore_fragment_shader(struct cso_context *cso); +void cso_set_vertex_shader_handle(struct cso_context *ctx, + void *handle ); void cso_set_vertex_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); void cso_save_vertex_shader(struct cso_context *cso); -- cgit v1.2.3 From 01dfa6cde157321f565bab949f23f367ed20fa0e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 20:26:19 +0100 Subject: use cso fs/vs handle functions --- src/gallium/auxiliary/util/u_blit.c | 4 ++-- src/gallium/auxiliary/util/u_gen_mipmap.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index be5e83e834..0938b03820 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -318,8 +318,8 @@ util_blit_pixels(struct blit_state *ctx, cso_set_sampler_textures(ctx->cso, 1, &tex); /* shaders */ - cso_set_fragment_shader(ctx->cso, ctx->fs); - cso_set_vertex_shader(ctx->cso, ctx->vs); + cso_set_fragment_shader_handle(ctx->cso, ctx->fs); + cso_set_vertex_shader_handle(ctx->cso, ctx->vs); /* drawing dest */ memset(&fb, 0, sizeof(fb)); diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index f0c4063b28..9822a25ca6 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -888,8 +888,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); - cso_set_fragment_shader(ctx->cso, ctx->fs); - cso_set_vertex_shader(ctx->cso, ctx->vs); + cso_set_fragment_shader_handle(ctx->cso, ctx->fs); + cso_set_vertex_shader_handle(ctx->cso, ctx->vs); #if 0 cso_set_viewport(ctx->cso, &ctx->viewport); #endif -- cgit v1.2.3 From e406ad5912985920a0d796f1ada58b40316590ed Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 21:01:38 +0100 Subject: draw: squash a couple of memory leaks --- src/gallium/auxiliary/draw/draw_pt_fetch.c | 3 +++ src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 5 +++++ 2 files changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index c588710b75..f98bce6eac 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -166,6 +166,9 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) void draw_pt_fetch_destroy( struct pt_fetch *fetch ) { + if (fetch->translate) + fetch->translate->release( fetch->translate ); + FREE(fetch); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 7735173042..68b2c5b1e3 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -264,6 +264,11 @@ static void fetch_emit_finish( struct draw_pt_middle_end *middle ) static void fetch_emit_destroy( struct draw_pt_middle_end *middle ) { + struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; + + if (feme->translate) + feme->translate->release( feme->translate ); + FREE(middle); } -- cgit v1.2.3 From 9a0e6860d3b4602515f39593ed9af00cee7bb106 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 21:05:11 +0100 Subject: cso: disable not-really-working cso_set_*_shader() funcs --- src/gallium/auxiliary/cso_cache/cso_context.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index e6366e7b14..3840dd2239 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -432,6 +432,9 @@ void cso_set_fragment_shader_handle(struct cso_context *ctx, } +/* Not really working: + */ +#if 0 void cso_set_fragment_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) { @@ -465,6 +468,7 @@ void cso_set_fragment_shader(struct cso_context *ctx, cso_set_fragment_shader_handle( ctx, handle ); } +#endif void cso_save_fragment_shader(struct cso_context *ctx) { @@ -493,7 +497,9 @@ void cso_set_vertex_shader_handle(struct cso_context *ctx, } - +/* Not really working: + */ +#if 0 void cso_set_vertex_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) { @@ -522,6 +528,7 @@ void cso_set_vertex_shader(struct cso_context *ctx, cso_set_vertex_shader_handle( ctx, handle ); } +#endif -- cgit v1.2.3 From 9fe63929011cd9c4d86ab6525555a3e53423c854 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 15:44:51 -0400 Subject: initial stab at error handling in cso --- src/gallium/auxiliary/cso_cache/cso_context.c | 98 +++++++++++++++++---------- src/gallium/auxiliary/cso_cache/cso_context.h | 34 +++++----- 2 files changed, 80 insertions(+), 52 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 3840dd2239..6040522a46 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -139,8 +139,8 @@ void cso_destroy_context( struct cso_context *ctx ) * the data member of the cso to be the template itself. */ -void cso_set_blend(struct cso_context *ctx, - const struct pipe_blend_state *templ) +enum pipe_error cso_set_blend(struct cso_context *ctx, + const struct pipe_blend_state *templ) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state)); struct cso_hash_iter iter = cso_find_state_template(ctx->cache, @@ -149,8 +149,9 @@ void cso_set_blend(struct cso_context *ctx, void *handle; if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_blend *cso = MALLOC(sizeof(struct cso_blend)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; cso->state = *templ; cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state); @@ -168,6 +169,7 @@ void cso_set_blend(struct cso_context *ctx, ctx->blend = handle; ctx->pipe->bind_blend_state(ctx->pipe, handle); } + return PIPE_OK; } void cso_save_blend(struct cso_context *ctx) @@ -187,12 +189,12 @@ void cso_restore_blend(struct cso_context *ctx) -void cso_single_sampler(struct cso_context *ctx, - unsigned idx, - const struct pipe_sampler_state *templ) +enum pipe_error cso_single_sampler(struct cso_context *ctx, + unsigned idx, + const struct pipe_sampler_state *templ) { void *handle = NULL; - + if (templ != NULL) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state)); struct cso_hash_iter iter = cso_find_state_template(ctx->cache, @@ -200,9 +202,10 @@ void cso_single_sampler(struct cso_context *ctx, (void*)templ); if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler)); - + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; + cso->state = *templ; cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state; @@ -217,11 +220,12 @@ void cso_single_sampler(struct cso_context *ctx, } ctx->samplers[idx] = handle; + return PIPE_OK; } void cso_single_sampler_done( struct cso_context *ctx ) { - unsigned i; + unsigned i; /* find highest non-null sampler */ for (i = PIPE_MAX_SAMPLERS; i > 0; i--) { @@ -232,8 +236,8 @@ void cso_single_sampler_done( struct cso_context *ctx ) ctx->nr_samplers = i; if (ctx->hw.nr_samplers != ctx->nr_samplers || - memcmp(ctx->hw.samplers, - ctx->samplers, + memcmp(ctx->hw.samplers, + ctx->samplers, ctx->nr_samplers * sizeof(void *)) != 0) { memcpy(ctx->hw.samplers, ctx->samplers, ctx->nr_samplers * sizeof(void *)); @@ -243,22 +247,36 @@ void cso_single_sampler_done( struct cso_context *ctx ) } } -void cso_set_samplers( struct cso_context *ctx, - unsigned nr, - const struct pipe_sampler_state **templates ) +/* + * If the function encouters any errors it will return the + * last one. Done to always try to set as many samplers + * as possible. + */ +enum pipe_error cso_set_samplers( struct cso_context *ctx, + unsigned nr, + const struct pipe_sampler_state **templates ) { unsigned i; - + enum pipe_error temp, error = PIPE_OK; + /* TODO: fastpath */ - for (i = 0; i < nr; i++) - cso_single_sampler( ctx, i, templates[i] ); + for (i = 0; i < nr; i++) { + temp = cso_single_sampler( ctx, i, templates[i] ); + if (temp != PIPE_OK) + error = temp; + } + + for ( ; i < ctx->nr_samplers; i++) { + temp = cso_single_sampler( ctx, i, NULL ); + if (temp != PIPE_OK) + error = temp; + } - for ( ; i < ctx->nr_samplers; i++) - cso_single_sampler( ctx, i, NULL ); - cso_single_sampler_done( ctx ); + + return error; } void cso_save_samplers(struct cso_context *ctx) @@ -294,7 +312,7 @@ void cso_set_sampler_textures( struct cso_context *ctx, void cso_save_sampler_textures( struct cso_context *ctx ) { uint i; - + ctx->nr_textures_saved = ctx->nr_textures; for (i = 0; i < ctx->nr_textures; i++) { assert(!ctx->textures_saved[i]); @@ -323,9 +341,8 @@ void cso_restore_sampler_textures( struct cso_context *ctx ) - -void cso_set_depth_stencil_alpha(struct cso_context *ctx, - const struct pipe_depth_stencil_alpha_state *templ) +enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx, + const struct pipe_depth_stencil_alpha_state *templ) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_depth_stencil_alpha_state)); @@ -336,8 +353,9 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx, void *handle; if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_depth_stencil_alpha *cso = MALLOC(sizeof(struct cso_depth_stencil_alpha)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; cso->state = *templ; cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &cso->state); @@ -355,6 +373,7 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx, ctx->depth_stencil = handle; ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, handle); } + return PIPE_OK; } void cso_save_depth_stencil_alpha(struct cso_context *ctx) @@ -374,8 +393,8 @@ void cso_restore_depth_stencil_alpha(struct cso_context *ctx) -void cso_set_rasterizer(struct cso_context *ctx, - const struct pipe_rasterizer_state *templ) +enum pipe_error cso_set_rasterizer(struct cso_context *ctx, + const struct pipe_rasterizer_state *templ) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_rasterizer_state)); @@ -385,8 +404,9 @@ void cso_set_rasterizer(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_rasterizer *cso = MALLOC(sizeof(struct cso_rasterizer)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; cso->state = *templ; cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state); @@ -404,6 +424,7 @@ void cso_set_rasterizer(struct cso_context *ctx, ctx->rasterizer = handle; ctx->pipe->bind_rasterizer_state(ctx->pipe, handle); } + return PIPE_OK; } void cso_save_rasterizer(struct cso_context *ctx) @@ -422,6 +443,7 @@ void cso_restore_rasterizer(struct cso_context *ctx) } +<<<<<<< HEAD:src/gallium/auxiliary/cso_cache/cso_context.c void cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle ) { @@ -435,8 +457,8 @@ void cso_set_fragment_shader_handle(struct cso_context *ctx, /* Not really working: */ #if 0 -void cso_set_fragment_shader(struct cso_context *ctx, - const struct pipe_shader_state *templ) +enum pipe_error cso_set_fragment_shader(struct cso_context *ctx, + const struct pipe_shader_state *templ) { const struct tgsi_token *tokens = templ->tokens; unsigned num_tokens = tgsi_num_tokens(tokens); @@ -449,10 +471,12 @@ void cso_set_fragment_shader(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_fragment_shader *cso = MALLOC(sizeof(struct cso_fragment_shader) + tokens_size); struct tgsi_token *cso_tokens = (struct tgsi_token *)((char *)cso + sizeof(*cso)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; + memcpy(cso_tokens, tokens, tokens_size); cso->state.tokens = cso_tokens; cso->data = ctx->pipe->create_fs_state(ctx->pipe, &cso->state); @@ -467,6 +491,7 @@ void cso_set_fragment_shader(struct cso_context *ctx, } cso_set_fragment_shader_handle( ctx, handle ); + return PIPE_OK; } #endif @@ -500,8 +525,8 @@ void cso_set_vertex_shader_handle(struct cso_context *ctx, /* Not really working: */ #if 0 -void cso_set_vertex_shader(struct cso_context *ctx, - const struct pipe_shader_state *templ) +enum pipe_error cso_set_vertex_shader(struct cso_context *ctx, + const struct pipe_shader_state *templ) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_shader_state)); @@ -511,9 +536,11 @@ void cso_set_vertex_shader(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_vertex_shader *cso = MALLOC(sizeof(struct cso_vertex_shader)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; + cso->state = *templ; cso->data = ctx->pipe->create_vs_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_vs_state; @@ -527,6 +554,7 @@ void cso_set_vertex_shader(struct cso_context *ctx, } cso_set_vertex_shader_handle( ctx, handle ); + return PIPE_OK; } #endif diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 945f4881a8..ab46b93d5a 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -31,6 +31,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" +#include "pipe/p_error.h" #ifdef __cplusplus @@ -45,39 +46,39 @@ void cso_destroy_context( struct cso_context *cso ); -void cso_set_blend( struct cso_context *cso, - const struct pipe_blend_state *blend ); +enum pipe_error cso_set_blend( struct cso_context *cso, + const struct pipe_blend_state *blend ); void cso_save_blend(struct cso_context *cso); void cso_restore_blend(struct cso_context *cso); -void cso_set_depth_stencil_alpha( struct cso_context *cso, - const struct pipe_depth_stencil_alpha_state *dsa ); +enum pipe_error cso_set_depth_stencil_alpha( struct cso_context *cso, + const struct pipe_depth_stencil_alpha_state *dsa ); void cso_save_depth_stencil_alpha(struct cso_context *cso); void cso_restore_depth_stencil_alpha(struct cso_context *cso); -void cso_set_rasterizer( struct cso_context *cso, - const struct pipe_rasterizer_state *rasterizer ); +enum pipe_error cso_set_rasterizer( struct cso_context *cso, + const struct pipe_rasterizer_state *rasterizer ); void cso_save_rasterizer(struct cso_context *cso); void cso_restore_rasterizer(struct cso_context *cso); -void cso_set_samplers( struct cso_context *cso, - unsigned count, - const struct pipe_sampler_state **states ); +enum pipe_error cso_set_samplers( struct cso_context *cso, + unsigned count, + const struct pipe_sampler_state **states ); void cso_save_samplers(struct cso_context *cso); void cso_restore_samplers(struct cso_context *cso); /* Alternate interface to support state trackers that like to modify * samplers one at a time: */ -void cso_single_sampler( struct cso_context *cso, - unsigned nr, - const struct pipe_sampler_state *states ); +enum pipe_error cso_single_sampler( struct cso_context *cso, + unsigned nr, + const struct pipe_sampler_state *states ); void cso_single_sampler_done( struct cso_context *cso ); @@ -98,17 +99,16 @@ void cso_restore_sampler_textures( struct cso_context *cso ); */ void cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle ); -void cso_set_fragment_shader( struct cso_context *cso, - const struct pipe_shader_state *shader ); +enum pipe_error cso_set_fragment_shader( struct cso_context *cso, + const struct pipe_shader_state *shader ); void cso_save_fragment_shader(struct cso_context *cso); void cso_restore_fragment_shader(struct cso_context *cso); - void cso_set_vertex_shader_handle(struct cso_context *ctx, void *handle ); -void cso_set_vertex_shader( struct cso_context *cso, - const struct pipe_shader_state *shader ); +enum pipe_error cso_set_vertex_shader( struct cso_context *cso, + const struct pipe_shader_state *shader ); void cso_save_vertex_shader(struct cso_context *cso); void cso_restore_vertex_shader(struct cso_context *cso); -- cgit v1.2.3 From 0879237725eca893318137b795d4234300a37e9a Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 16:04:27 -0400 Subject: handle some of the possible allocation failures within the hash itself --- src/gallium/auxiliary/cso_cache/cso_context.c | 36 ++++++++++++++++++++++++--- src/gallium/auxiliary/cso_cache/cso_hash.c | 17 +++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 6040522a46..364a413580 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -159,6 +159,11 @@ enum pipe_error cso_set_blend(struct cso_context *ctx, cso->context = ctx->pipe; iter = cso_insert_state(ctx->cache, hash_key, CSO_BLEND, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { @@ -212,6 +217,11 @@ enum pipe_error cso_single_sampler(struct cso_context *ctx, cso->context = ctx->pipe; iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { @@ -362,7 +372,12 @@ enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx, cso->delete_state = (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state; cso->context = ctx->pipe; - cso_insert_state(ctx->cache, hash_key, CSO_DEPTH_STENCIL_ALPHA, cso); + iter = cso_insert_state(ctx->cache, hash_key, CSO_DEPTH_STENCIL_ALPHA, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { @@ -413,7 +428,12 @@ enum pipe_error cso_set_rasterizer(struct cso_context *ctx, cso->delete_state = (cso_state_callback)ctx->pipe->delete_rasterizer_state; cso->context = ctx->pipe; - cso_insert_state(ctx->cache, hash_key, CSO_RASTERIZER, cso); + iter = cso_insert_state(ctx->cache, hash_key, CSO_RASTERIZER, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { @@ -442,8 +462,6 @@ void cso_restore_rasterizer(struct cso_context *ctx) ctx->rasterizer_saved = NULL; } - -<<<<<<< HEAD:src/gallium/auxiliary/cso_cache/cso_context.c void cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle ) { @@ -484,6 +502,11 @@ enum pipe_error cso_set_fragment_shader(struct cso_context *ctx, cso->context = ctx->pipe; iter = cso_insert_state(ctx->cache, hash_key, CSO_FRAGMENT_SHADER, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { @@ -547,6 +570,11 @@ enum pipe_error cso_set_vertex_shader(struct cso_context *ctx, cso->context = ctx->pipe; iter = cso_insert_state(ctx->cache, hash_key, CSO_VERTEX_SHADER, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index ddce3822f7..8d867f86d2 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -110,6 +110,10 @@ cso_hash_create_node(struct cso_hash *hash, struct cso_node **anextNode) { struct cso_node *node = cso_data_allocate_node(hash->data.d); + + if (!node) + return NULL; + node->key = akey; node->value = avalue; @@ -219,6 +223,11 @@ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, { struct cso_node **nextNode = cso_hash_find_node(hash, key); struct cso_node *node = cso_hash_create_node(hash, key, data, nextNode); + if (!node) { + struct cso_hash_iter null_iter = {hash, 0}; + return null_iter; + } + struct cso_hash_iter iter = {hash, node}; return iter; } @@ -227,7 +236,15 @@ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, struct cso_hash * cso_hash_create(void) { struct cso_hash *hash = MALLOC_STRUCT(cso_hash); + if (!hash) + return NULL; + hash->data.d = MALLOC_STRUCT(cso_hash_data); + if (!hash->data.d) { + FREE(hash); + return NULL; + } + hash->data.d->fakeNext = 0; hash->data.d->buckets = 0; hash->data.d->size = 0; -- cgit v1.2.3 From ed187d39a6e0fd921b2a45a143d88ac4b66eee91 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 16:40:27 -0400 Subject: make the api consistent (all set functions return pipe_error status) --- src/gallium/auxiliary/cso_cache/cso_context.c | 39 +++++++++++++++------------ src/gallium/auxiliary/cso_cache/cso_context.h | 26 +++++++++--------- 2 files changed, 35 insertions(+), 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 364a413580..2d98a34edf 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -303,9 +303,9 @@ void cso_restore_samplers(struct cso_context *ctx) } -void cso_set_sampler_textures( struct cso_context *ctx, - uint count, - struct pipe_texture **textures ) +enum pipe_error cso_set_sampler_textures( struct cso_context *ctx, + uint count, + struct pipe_texture **textures ) { uint i; @@ -317,6 +317,8 @@ void cso_set_sampler_textures( struct cso_context *ctx, pipe_texture_reference(&ctx->textures[i], NULL); ctx->pipe->set_sampler_textures(ctx->pipe, count, textures); + + return PIPE_OK; } void cso_save_sampler_textures( struct cso_context *ctx ) @@ -462,13 +464,14 @@ void cso_restore_rasterizer(struct cso_context *ctx) ctx->rasterizer_saved = NULL; } -void cso_set_fragment_shader_handle(struct cso_context *ctx, - void *handle ) +enum pipe_error cso_set_fragment_shader_handle(struct cso_context *ctx, + void *handle ) { if (ctx->fragment_shader != handle) { ctx->fragment_shader = handle; ctx->pipe->bind_fs_state(ctx->pipe, handle); } + return PIPE_OK; } @@ -513,8 +516,7 @@ enum pipe_error cso_set_fragment_shader(struct cso_context *ctx, handle = ((struct cso_fragment_shader *)cso_hash_iter_data(iter))->data; } - cso_set_fragment_shader_handle( ctx, handle ); - return PIPE_OK; + return cso_set_fragment_shader_handle( ctx, handle ); } #endif @@ -535,13 +537,14 @@ void cso_restore_fragment_shader(struct cso_context *ctx) } -void cso_set_vertex_shader_handle(struct cso_context *ctx, - void *handle ) +enum pipe_error cso_set_vertex_shader_handle(struct cso_context *ctx, + void *handle ) { if (ctx->vertex_shader != handle) { ctx->vertex_shader = handle; ctx->pipe->bind_vs_state(ctx->pipe, handle); } + return PIPE_OK; } @@ -581,8 +584,7 @@ enum pipe_error cso_set_vertex_shader(struct cso_context *ctx, handle = ((struct cso_vertex_shader *)cso_hash_iter_data(iter))->data; } - cso_set_vertex_shader_handle( ctx, handle ); - return PIPE_OK; + return cso_set_vertex_shader_handle( ctx, handle ); } #endif @@ -606,14 +608,15 @@ void cso_restore_vertex_shader(struct cso_context *ctx) -void cso_set_framebuffer(struct cso_context *ctx, - const struct pipe_framebuffer_state *fb) +enum pipe_error cso_set_framebuffer(struct cso_context *ctx, + const struct pipe_framebuffer_state *fb) { /* XXX this memcmp() fails to detect buffer size changes */ if (1/*memcmp(&ctx->fb, fb, sizeof(*fb))*/) { ctx->fb = *fb; ctx->pipe->set_framebuffer_state(ctx->pipe, fb); } + return PIPE_OK; } void cso_save_framebuffer(struct cso_context *ctx) @@ -630,13 +633,14 @@ void cso_restore_framebuffer(struct cso_context *ctx) } -void cso_set_viewport(struct cso_context *ctx, - const struct pipe_viewport_state *vp) +enum pipe_error cso_set_viewport(struct cso_context *ctx, + const struct pipe_viewport_state *vp) { if (memcmp(&ctx->vp, vp, sizeof(*vp))) { ctx->vp = *vp; ctx->pipe->set_viewport_state(ctx->pipe, vp); } + return PIPE_OK; } void cso_save_viewport(struct cso_context *ctx) @@ -656,11 +660,12 @@ void cso_restore_viewport(struct cso_context *ctx) -void cso_set_blend_color(struct cso_context *ctx, - const struct pipe_blend_color *bc) +enum pipe_error cso_set_blend_color(struct cso_context *ctx, + const struct pipe_blend_color *bc) { if (memcmp(&ctx->blend_color, bc, sizeof(ctx->blend_color))) { ctx->blend_color = *bc; ctx->pipe->set_blend_color(ctx->pipe, bc); } + return PIPE_OK; } diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index ab46b93d5a..0405944132 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -84,9 +84,9 @@ void cso_single_sampler_done( struct cso_context *cso ); -void cso_set_sampler_textures( struct cso_context *cso, - uint count, - struct pipe_texture **textures ); +enum pipe_error cso_set_sampler_textures( struct cso_context *cso, + uint count, + struct pipe_texture **textures ); void cso_save_sampler_textures( struct cso_context *cso ); void cso_restore_sampler_textures( struct cso_context *cso ); @@ -97,16 +97,16 @@ void cso_restore_sampler_textures( struct cso_context *cso ); * (eg mesa's internall-generated texenv programs), it will be up to * the state tracker to implement their own specialized caching. */ -void cso_set_fragment_shader_handle(struct cso_context *ctx, - void *handle ); +enum pipe_error cso_set_fragment_shader_handle(struct cso_context *ctx, + void *handle ); enum pipe_error cso_set_fragment_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); void cso_save_fragment_shader(struct cso_context *cso); void cso_restore_fragment_shader(struct cso_context *cso); -void cso_set_vertex_shader_handle(struct cso_context *ctx, - void *handle ); +enum pipe_error cso_set_vertex_shader_handle(struct cso_context *ctx, + void *handle ); enum pipe_error cso_set_vertex_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); void cso_save_vertex_shader(struct cso_context *cso); @@ -114,20 +114,20 @@ void cso_restore_vertex_shader(struct cso_context *cso); -void cso_set_framebuffer(struct cso_context *cso, - const struct pipe_framebuffer_state *fb); +enum pipe_error cso_set_framebuffer(struct cso_context *cso, + const struct pipe_framebuffer_state *fb); void cso_save_framebuffer(struct cso_context *cso); void cso_restore_framebuffer(struct cso_context *cso); -void cso_set_viewport(struct cso_context *cso, - const struct pipe_viewport_state *vp); +enum pipe_error cso_set_viewport(struct cso_context *cso, + const struct pipe_viewport_state *vp); void cso_save_viewport(struct cso_context *cso); void cso_restore_viewport(struct cso_context *cso); -void cso_set_blend_color(struct cso_context *cso, - const struct pipe_blend_color *bc); +enum pipe_error cso_set_blend_color(struct cso_context *cso, + const struct pipe_blend_color *bc); #ifdef __cplusplus -- cgit v1.2.3 From 83fec372b45eb0af9e2d83549b3d92afb17c38af Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 22 Apr 2008 11:26:26 +0200 Subject: cso: Fix build on Win32. --- src/gallium/auxiliary/cso_cache/cso_hash.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index 8d867f86d2..0646efd952 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -228,8 +228,10 @@ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, return null_iter; } - struct cso_hash_iter iter = {hash, node}; - return iter; + { + struct cso_hash_iter iter = {hash, node}; + return iter; + } } } -- cgit v1.2.3 From 09b668615852eb28cb6289baf84faaf3b6ccc3c2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 10:57:06 +0100 Subject: softpipe: make NUM_ENTRIES 32 so that div/mods are easier --- src/gallium/drivers/softpipe/sp_tile_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 19f71887e7..edafd93d8b 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -39,7 +39,7 @@ #include "sp_surface.h" #include "sp_tile_cache.h" -#define NUM_ENTRIES 30 +#define NUM_ENTRIES 32 /** XXX move these */ -- cgit v1.2.3 From a5b87f249ef79b1a8d8b9dbe72879b7ac9eb133c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 11:01:41 +0100 Subject: softpipe: implement SP_NO_RAST env var --- src/gallium/drivers/softpipe/sp_clear.c | 3 +++ src/gallium/drivers/softpipe/sp_context.c | 3 +++ src/gallium/drivers/softpipe/sp_context.h | 2 ++ src/gallium/drivers/softpipe/sp_setup.c | 10 ++++++++++ 4 files changed, 18 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c index 39aed151c7..1236706891 100644 --- a/src/gallium/drivers/softpipe/sp_clear.c +++ b/src/gallium/drivers/softpipe/sp_clear.c @@ -49,6 +49,9 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, struct softpipe_context *softpipe = softpipe_context(pipe); uint i; + if (softpipe->no_rast) + return; + #if 0 softpipe_update_derived(softpipe); /* not needed?? */ #endif diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 8c84ddbe19..200fb415ac 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -219,6 +219,9 @@ softpipe_create( struct pipe_screen *screen, assert(softpipe->draw); softpipe->setup = sp_draw_render_stage(softpipe); + if (GETENV( "SP_NO_RAST" ) != NULL) + softpipe->no_rast = TRUE; + if (GETENV( "SP_VBUF" ) != NULL) { sp_init_vbuf(softpipe); } diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 0e1d5e561d..b3e2b2e435 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -86,6 +86,8 @@ struct softpipe_context { unsigned num_vertex_elements; unsigned num_vertex_buffers; + boolean no_rast; + /* Counter for occlusion queries. Note this supports overlapping * queries. */ diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 813d703108..0bf2b2dc3e 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -726,6 +726,9 @@ void setup_tri( struct setup_context *setup, { float det = calc_det(v0, v1, v2); + if (setup->softpipe->no_rast) + return; + /* debug_printf("%s\n", __FUNCTION__ ); */ @@ -934,6 +937,9 @@ setup_line(struct setup_context *setup, int dy = y1 - y0; int xstep, ystep; + if (setup->softpipe->no_rast) + return; + if (dx == 0 && dy == 0) return; @@ -1052,6 +1058,10 @@ setup_point( struct setup_context *setup, const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; + + if (softpipe->no_rast) + return; + /* For points, all interpolants are constant-valued. * However, for point sprites, we'll need to setup texcoords appropriately. * XXX: which coefficients are the texcoords??? -- cgit v1.2.3 From d07ed9216cc7033fecb5bce661bbaf79189bb391 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 11:01:56 +0100 Subject: xlib: implement SP_NO_RAST env var --- src/gallium/winsys/xlib/xm_winsys.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 9a20bdfb69..5a424d0ac7 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -84,6 +84,7 @@ struct xmesa_surface struct pipe_surface surface; int tileSize; + boolean no_swap; }; @@ -252,6 +253,9 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) const struct xmesa_surface *xm_surf = xmesa_surface((struct pipe_surface *) surf); + if (xm_surf->no_swap) + return; + if (xm_surf->tileSize) { xmesa_display_surface_tiled(b, surf); return; @@ -529,6 +533,13 @@ static struct pipe_surface * xm_surface_alloc(struct pipe_winsys *ws) { struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface); + static boolean no_swap = 0; + static boolean firsttime = 1; + + if (firsttime) { + no_swap = getenv("SP_NO_RAST") != NULL; + firsttime = 0; + } assert(ws); @@ -540,7 +551,9 @@ xm_surface_alloc(struct pipe_winsys *ws) xms->tileSize = 32; /** probably temporary */ } #endif - + + xms->no_swap = no_swap; + return &xms->surface; } -- cgit v1.2.3 From 6a9f6625b38c3669769568d122958993f4a8d5b3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 11:15:51 +0100 Subject: xlib: shortcircuit no-op makecurrent --- src/gallium/winsys/xlib/fakeglx.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c index 902a755075..6e04cb4117 100644 --- a/src/gallium/winsys/xlib/fakeglx.c +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -1504,6 +1504,13 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, #endif } + if (MakeCurrent_PrevContext == ctx && + MakeCurrent_PrevDrawable == draw && + MakeCurrent_PrevReadable == read && + MakeCurrent_PrevDrawBuffer == drawBuffer && + MakeCurrent_PrevReadBuffer == readBuffer) + return True; + MakeCurrent_PrevContext = ctx; MakeCurrent_PrevDrawable = draw; MakeCurrent_PrevReadable = read; -- cgit v1.2.3 From 57987ea67320e79e4c2d7e66388806148ece09b5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 11:26:07 +0100 Subject: draw: disable broken edgeflag code - didn't work & was killing performance --- src/gallium/auxiliary/draw/draw_pt_vcache.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 3cc2941f96..153055417d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -106,7 +106,7 @@ static unsigned add_edgeflag( struct vcache_frontend *vcache, unsigned idx, unsigned mask ) { - if (mask && draw_pt_get_edgeflag(vcache->draw, idx)) + if (0 && mask && draw_pt_get_edgeflag(vcache->draw, idx)) return idx | DRAW_PT_EDGEFLAG; else return idx; @@ -116,7 +116,7 @@ static unsigned add_edgeflag( struct vcache_frontend *vcache, static unsigned add_reset_stipple( unsigned idx, unsigned reset ) { - if (reset) + if (0 && reset) return idx | DRAW_PT_RESET_STIPPLE; else return idx; @@ -128,9 +128,9 @@ static void vcache_triangle( struct vcache_frontend *vcache, unsigned i1, unsigned i2 ) { - vcache_elt(vcache, i0 | DRAW_PT_EDGEFLAG | DRAW_PT_RESET_STIPPLE); - vcache_elt(vcache, i1 | DRAW_PT_EDGEFLAG); - vcache_elt(vcache, i2 | DRAW_PT_EDGEFLAG); + vcache_elt(vcache, i0 /* | DRAW_PT_EDGEFLAG | DRAW_PT_RESET_STIPPLE */ ); + vcache_elt(vcache, i1 /* | DRAW_PT_EDGEFLAG */); + vcache_elt(vcache, i2 /* | DRAW_PT_EDGEFLAG */); vcache_check_flush(vcache); } @@ -142,11 +142,12 @@ static void vcache_ef_triangle( struct vcache_frontend *vcache, unsigned i1, unsigned i2 ) { +/* i0 = add_edgeflag( vcache, i0, (ef_mask >> 0) & 1 ); i1 = add_edgeflag( vcache, i1, (ef_mask >> 1) & 1 ); i2 = add_edgeflag( vcache, i2, (ef_mask >> 2) & 1 ); - i0 = add_reset_stipple( i0, reset_stipple ); +*/ vcache_elt(vcache, i0); vcache_elt(vcache, i1); -- cgit v1.2.3 From b4b3a73bdf68adc1d9fbadac913aa6cf60d648d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 22 Apr 2008 19:47:02 +0900 Subject: pipebuffer: Temporarily allow simultaneous CPU writes. Also, fast path for re-fencing the same buffer multiple times with the same fence. --- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 65b6584003..27032b0c4c 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -215,15 +215,21 @@ fenced_buffer_serialize(struct fenced_buffer *fenced_buf, unsigned flags) struct fenced_buffer_list *fenced_list = fenced_buf->list; struct pipe_winsys *winsys = fenced_list->winsys; + /* Allow concurrent reads */ if(((fenced_buf->flags | flags) & PIPE_BUFFER_USAGE_WRITE) == 0) return PIPE_OK; + /* Wait for the CPU to finish */ if(fenced_buf->mapcount) { - /* FIXME */ + /* FIXME: Use thread conditions variables to signal when mapcount + * reaches zero */ debug_warning("attemp to write concurrently to buffer"); + /* XXX: we must not fail here in order to support texture mipmap generation return PIPE_ERROR_RETRY; + */ } + /* Wait for the GPU to finish */ if(fenced_buf->fence) { if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) return PIPE_ERROR_RETRY; @@ -353,6 +359,16 @@ buffer_fence(struct pb_buffer *buf, /* FIXME: receive this as a parameter */ unsigned flags = fence ? PIPE_BUFFER_USAGE_GPU_READ_WRITE : 0; + if(fence == fenced_buf->fence) { + /* Handle the same fence case specially, not only because it is a fast + * path, but mostly to avoid serializing two writes with the same fence, + * as that would bring the hardware down to synchronous operation without + * any benefit. + */ + fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE; + return; + } + if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK) { /* FIXME: propagate error */ (void)0; -- cgit v1.2.3 From f9b1d47d652778012fd35552ffc51717ac0b6f79 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 15:15:21 +0100 Subject: softpipe: do something sensible on an error path, squash warning --- src/gallium/drivers/softpipe/sp_tex_sample.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 34da6356d7..5b63f97997 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -651,7 +651,9 @@ shadow_compare(uint compare_func, k = 0; break; default: + k = 0; assert(0); + break; } rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; -- cgit v1.2.3 From 88f8eed3c4430505b1436b6c5b0114d34c33f822 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 15:26:38 +0100 Subject: cso: fix vs/fs confusion --- src/gallium/auxiliary/cso_cache/cso_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 2d98a34edf..23b1f5a032 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -600,7 +600,7 @@ void cso_restore_vertex_shader(struct cso_context *ctx) { assert(ctx->vertex_shader_saved); if (ctx->vertex_shader_saved != ctx->vertex_shader) { - ctx->pipe->bind_fs_state(ctx->pipe, ctx->vertex_shader_saved); + ctx->pipe->bind_vs_state(ctx->pipe, ctx->vertex_shader_saved); ctx->vertex_shader = ctx->vertex_shader_saved; } ctx->vertex_shader_saved = NULL; -- cgit v1.2.3 From 1f0f029ba6f22ef4ada01fcdc153da91571a7963 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 20:32:22 +0100 Subject: softpipe: squash warning --- src/gallium/drivers/softpipe/sp_state_fs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 2921066ce3..525cea9eed 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -82,7 +82,6 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) void softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { - struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state = fs; assert(fs != softpipe->fs); -- cgit v1.2.3 From 0588858702d1a5c9c08573ea6817e2e149473cf6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 20:50:20 +0100 Subject: draw: allow drivers to query pipeline state more easily Also, provide a separate flag to say whether the driver can handle clipping/rhw tasks, in addition to the API flag which indicates they have already been done. --- src/gallium/auxiliary/draw/draw_context.c | 13 ++++++++++ src/gallium/auxiliary/draw/draw_context.h | 12 +++++++++ src/gallium/auxiliary/draw/draw_pipe_validate.c | 30 ++++++++++++---------- src/gallium/auxiliary/draw/draw_private.h | 7 +++-- src/gallium/auxiliary/draw/draw_pt.c | 6 +++-- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 2 +- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 11 +++++--- 7 files changed, 58 insertions(+), 23 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index b4dbdccd61..b916b27877 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -122,6 +122,19 @@ void draw_set_rasterizer_state( struct draw_context *draw, draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); draw->rasterizer = raster; + draw->bypass_clipping = (draw->rasterizer->bypass_clipping || + draw->driver.bypass_clipping); +} + + +void draw_set_driver_clipping( struct draw_context *draw, + boolean bypass_clipping ) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + draw->driver.bypass_clipping = bypass_clipping; + draw->bypass_clipping = (draw->rasterizer->bypass_clipping || + draw->driver.bypass_clipping); } diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 2742001698..c5c3d3b09e 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -148,4 +148,16 @@ struct vbuf_render; void draw_set_render( struct draw_context *draw, struct vbuf_render *render ); +void draw_set_driver_clipping( struct draw_context *draw, + boolean bypass_clipping ); + +/******************************************************************************* + * Draw pipeline + */ +boolean draw_need_pipeline(const struct draw_context *draw, + const struct pipe_rasterizer_state *rasterizer, + unsigned prim ); + + + #endif /* DRAW_CONTEXT_H */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c index a2e0812c89..6be1d369c3 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_validate.c +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -32,6 +32,7 @@ #include "pipe/p_defines.h" #include "draw_private.h" #include "draw_pipe.h" +#include "draw_context.h" static boolean points( unsigned prim ) { @@ -57,7 +58,8 @@ static boolean triangles( unsigned prim ) * pipeline stages. */ boolean -draw_need_pipeline(const struct draw_context *draw, +draw_need_pipeline(const struct draw_context *draw, + const struct pipe_rasterizer_state *rasterizer, unsigned int prim ) { /* Don't have to worry about triangles turning into lines/points @@ -67,30 +69,30 @@ draw_need_pipeline(const struct draw_context *draw, if (lines(prim)) { /* line stipple */ - if (draw->rasterizer->line_stipple_enable && draw->pipeline.line_stipple) + if (rasterizer->line_stipple_enable && draw->pipeline.line_stipple) return TRUE; /* wide lines */ - if (draw->rasterizer->line_width > draw->pipeline.wide_line_threshold) + if (rasterizer->line_width > draw->pipeline.wide_line_threshold) return TRUE; /* AA lines */ - if (draw->rasterizer->line_smooth && draw->pipeline.aaline) + if (rasterizer->line_smooth && draw->pipeline.aaline) return TRUE; } if (points(prim)) { /* large points */ - if (draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) + if (rasterizer->point_size > draw->pipeline.wide_point_threshold) return TRUE; /* AA points */ - if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) + if (rasterizer->point_smooth && draw->pipeline.aapoint) return TRUE; /* point sprites */ - if (draw->rasterizer->point_sprite && draw->pipeline.point_sprite) + if (rasterizer->point_sprite && draw->pipeline.point_sprite) return TRUE; } @@ -98,20 +100,20 @@ draw_need_pipeline(const struct draw_context *draw, if (triangles(prim)) { /* polygon stipple */ - if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple) + if (rasterizer->poly_stipple_enable && draw->pipeline.pstipple) return TRUE; /* unfilled polygons */ - if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) + if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) return TRUE; /* polygon offset */ - if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw) + if (rasterizer->offset_cw || rasterizer->offset_ccw) return TRUE; /* two-side lighting */ - if (draw->rasterizer->light_twoside) + if (rasterizer->light_twoside) return TRUE; } @@ -120,7 +122,7 @@ draw_need_pipeline(const struct draw_context *draw, * * Generally this isn't a reason to require the pipeline, though. * - if (draw->rasterizer->cull_mode) + if (rasterizer->cull_mode) return TRUE; */ @@ -239,7 +241,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) /* Clip stage */ - if (!draw->rasterizer->bypass_clipping) + if (!draw->bypass_clipping) { draw->pipeline.clip->next = next; next = draw->pipeline.clip; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index da973e868b..83b81f66a0 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -174,7 +174,12 @@ struct draw_context } pt; + struct { + boolean bypass_clipping; + } driver; + boolean flushing; + boolean bypass_clipping; /* set if either api or driver bypass_clipping true */ /* pipe state that we need: */ const struct pipe_rasterizer_state *rasterizer; @@ -243,8 +248,6 @@ void draw_pipeline_run( struct draw_context *draw, void draw_pipeline_flush( struct draw_context *draw, unsigned flags ); -boolean draw_need_pipeline(const struct draw_context *draw, - unsigned prim ); /******************************************************************************* diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 9f8e8d3d62..f5a3bf390e 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -58,11 +58,13 @@ draw_pt_arrays(struct draw_context *draw, opt |= PT_PIPELINE; } - if (draw_need_pipeline(draw, prim)) { + if (draw_need_pipeline(draw, + draw->rasterizer, + prim)) { opt |= PT_PIPELINE; } - if (!draw->rasterizer->bypass_clipping) { + if (!draw->bypass_clipping) { opt |= PT_CLIPTEST; } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 98a2cb45e4..f0763dad8d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -81,7 +81,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, * but gl vs dx9 clip spaces. */ draw_pt_post_vs_prepare( fpme->post_vs, - draw->rasterizer->bypass_clipping, + draw->bypass_clipping, draw->identity_viewport, draw->rasterizer->gl_rasterization_rules ); diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index 581f044dae..e5e38fa264 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -94,8 +94,10 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, struct vertex_header *out = vertices; const float *scale = pvs->draw->viewport.scale; const float *trans = pvs->draw->viewport.translate; + boolean clipped = FALSE; unsigned j; - unsigned clipped = 0; + + if (0) debug_printf("%s\n"); for (j = 0; j < count; j++) { out->clip[0] = out->data[0][0]; @@ -108,10 +110,11 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, out->clipmask = compute_clipmask_gl(out->clip, pvs->draw->plane, pvs->draw->nr_planes); - clipped += out->clipmask; if (out->clipmask == 0) { + clipped = TRUE; + /* divide by w */ float w = 1.0f / out->data[0][3]; @@ -142,7 +145,7 @@ static boolean post_vs_viewport( struct pt_post_vs *pvs, const float *trans = pvs->draw->viewport.translate; unsigned j; - debug_printf("%s\n", __FUNCTION__); + if (0) debug_printf("%s\n", __FUNCTION__); for (j = 0; j < count; j++) { /* Viewport mapping only, no cliptest/rhw divide */ @@ -165,7 +168,7 @@ static boolean post_vs_none( struct pt_post_vs *pvs, unsigned count, unsigned stride ) { - debug_printf("%s\n", __FUNCTION__); + if (0) debug_printf("%s\n", __FUNCTION__); return FALSE; } -- cgit v1.2.3 From 4ebede8c7f43a83adfc73dcca783de2e9efcd9ba Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 21:17:21 +0100 Subject: Revert "softpipe: squash warning" This reverts commit 1f0f029ba6f22ef4ada01fcdc153da91571a7963. Which broke the debug build. --- src/gallium/drivers/softpipe/sp_state_fs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 525cea9eed..2921066ce3 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -82,6 +82,7 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) void softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { + struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state = fs; assert(fs != softpipe->fs); -- cgit v1.2.3 From 6b4798b9068b58a3c4581a268727ce01680d08cd Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 22 Apr 2008 22:23:22 +0200 Subject: i915: Fixed weird fence leak when I915_VBUF=true --- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 923b542771..f029dd6a90 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -62,7 +62,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, } if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceFinish(intel->last_swap_fence, driFenceType(intel->last_swap_fence), GL_FALSE); driFenceUnReference(&intel->last_swap_fence); intel->last_swap_fence = NULL; } -- cgit v1.2.3 From 8f4f89c04383b2100f6d856270cad62dfe8a6354 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 14:42:36 -0600 Subject: gallium: remove assertions It's possible the current vs/fs is null when cso_save_vertex/fragment_shader() is called. --- src/gallium/auxiliary/cso_cache/cso_context.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 23b1f5a032..0523cb1949 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -528,7 +528,6 @@ void cso_save_fragment_shader(struct cso_context *ctx) void cso_restore_fragment_shader(struct cso_context *ctx) { - assert(ctx->fragment_shader_saved); if (ctx->fragment_shader_saved != ctx->fragment_shader) { ctx->pipe->bind_fs_state(ctx->pipe, ctx->fragment_shader_saved); ctx->fragment_shader = ctx->fragment_shader_saved; @@ -598,7 +597,6 @@ void cso_save_vertex_shader(struct cso_context *ctx) void cso_restore_vertex_shader(struct cso_context *ctx) { - assert(ctx->vertex_shader_saved); if (ctx->vertex_shader_saved != ctx->vertex_shader) { ctx->pipe->bind_vs_state(ctx->pipe, ctx->vertex_shader_saved); ctx->vertex_shader = ctx->vertex_shader_saved; -- cgit v1.2.3 From 465bc9473a0122d8f66ac1b4a69459e9bd889799 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 16:15:49 -0600 Subject: gallium: move the vertex print/debug code --- src/gallium/drivers/softpipe/sp_setup.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 0bf2b2dc3e..7df8fc5f67 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -299,13 +299,6 @@ static boolean setup_sort_vertices( struct setup_context *setup, const float (*v1)[4], const float (*v2)[4] ) { -#if DEBUG_VERTS - debug_printf("Triangle:\n"); - print_vertex(setup, v0); - print_vertex(setup, v1); - print_vertex(setup, v2); -#endif - setup->vprovoke = v2; /* determine bottom to top order of vertices */ @@ -738,7 +731,12 @@ void setup_tri( struct setup_context *setup, setup->numFragsWritten = 0; #endif - +#if DEBUG_VERTS + debug_printf("Triangle:\n"); + print_vertex(setup, v0); + print_vertex(setup, v1); + print_vertex(setup, v2); +#endif if (cull_tri( setup, det )) return; -- cgit v1.2.3 From aaa43218f34fc9897b280d6cf9bc1a31bbb7dafc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 16:22:21 -0600 Subject: gallium: setup an identity viewport --- src/gallium/auxiliary/util/u_gen_mipmap.c | 35 +++++-------------------------- 1 file changed, 5 insertions(+), 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 9822a25ca6..ff5881b979 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -61,6 +61,7 @@ struct gen_mipmap_state struct pipe_depth_stencil_alpha_state depthstencil; struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; + struct pipe_viewport_state viewport; struct pipe_shader_state vert_shader; struct pipe_shader_state frag_shader; @@ -723,9 +724,7 @@ util_create_gen_mipmap(struct pipe_context *pipe, ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; ctx->sampler.normalized_coords = 1; - -#if 0 - /* viewport */ + /* viewport state (identity, verts are in wincoords) */ ctx->viewport.scale[0] = 1.0; ctx->viewport.scale[1] = 1.0; ctx->viewport.scale[2] = 1.0; @@ -734,7 +733,6 @@ util_create_gen_mipmap(struct pipe_context *pipe, ctx->viewport.translate[1] = 0.0; ctx->viewport.translate[2] = 0.0; ctx->viewport.translate[3] = 0.0; -#endif /* vertex shader */ { @@ -825,26 +823,6 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) } -#if 0 -static void -simple_viewport(struct pipe_context *pipe, uint width, uint height) -{ - struct pipe_viewport_state vp; - - vp.scale[0] = 0.5 * width; - vp.scale[1] = -0.5 * height; - vp.scale[2] = 1.0; - vp.scale[3] = 1.0; - vp.translate[0] = 0.5 * width; - vp.translate[1] = 0.5 * height; - vp.translate[2] = 0.0; - vp.translate[3] = 0.0; - - pipe->set_viewport_state(pipe, &vp); -} -#endif - - /** * Generate mipmap images. It's assumed all needed texture memory is * already allocated. @@ -882,17 +860,16 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); + cso_save_viewport(ctx->cso); /* bind our state */ cso_set_blend(ctx->cso, &ctx->blend); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); + cso_set_viewport(ctx->cso, &ctx->viewport); cso_set_fragment_shader_handle(ctx->cso, ctx->fs); cso_set_vertex_shader_handle(ctx->cso, ctx->vs); -#if 0 - cso_set_viewport(ctx->cso, &ctx->viewport); -#endif /* init framebuffer state */ memset(&fb, 0, sizeof(fb)); @@ -928,9 +905,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, ctx->sampler.lod_bias = (float) srcLevel; cso_single_sampler(ctx->cso, 0, &ctx->sampler); cso_single_sampler_done(ctx->cso); -#if 0 - simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]); -#endif cso_set_sampler_textures(ctx->cso, 1, &pt); @@ -958,4 +932,5 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); + cso_restore_viewport(ctx->cso); } -- cgit v1.2.3 From 0939a986a8a7dbb8d30c505fcaad8d2718a6527d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 16:25:55 -0600 Subject: gallium: update comment about bypass clipping/viewport --- src/gallium/auxiliary/util/u_gen_mipmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index ff5881b979..dfdb5f16fe 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -713,7 +713,7 @@ util_create_gen_mipmap(struct pipe_context *pipe, memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); ctx->rasterizer.front_winding = PIPE_WINDING_CW; ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; - ctx->rasterizer.bypass_clipping = 1; /* bypasses viewport too */ + ctx->rasterizer.bypass_clipping = 1; /*ctx->rasterizer.bypass_vs = 1;*/ /* sampler state */ -- cgit v1.2.3 From 22cbf6a70437dfa12c10600e5a496ea5771cfc56 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 16:29:48 -0600 Subject: gallium: setup an identity viewport This fixes broken blits. --- src/gallium/auxiliary/util/u_blit.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 0938b03820..1105066cb8 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -57,6 +57,7 @@ struct blit_state struct pipe_depth_stencil_alpha_state depthstencil; struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; + struct pipe_viewport_state viewport; struct pipe_shader_state vert_shader; struct pipe_shader_state frag_shader; @@ -100,7 +101,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); ctx->rasterizer.front_winding = PIPE_WINDING_CW; ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; - ctx->rasterizer.bypass_clipping = 1; /* bypasses viewport too */ + ctx->rasterizer.bypass_clipping = 1; /*ctx->rasterizer.bypass_vs = 1;*/ /* samplers */ @@ -113,8 +114,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) ctx->sampler.mag_img_filter = 0; /* set later */ ctx->sampler.normalized_coords = 1; -#if 0 - /* viewport */ + /* viewport (identity, we setup vertices in wincoords) */ ctx->viewport.scale[0] = 1.0; ctx->viewport.scale[1] = 1.0; ctx->viewport.scale[2] = 1.0; @@ -123,7 +123,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) ctx->viewport.translate[1] = 0.0; ctx->viewport.translate[2] = 0.0; ctx->viewport.translate[3] = 0.0; -#endif /* vertex shader */ { @@ -302,11 +301,13 @@ util_blit_pixels(struct blit_state *ctx, cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); + cso_save_viewport(ctx->cso); /* set misc state we care about */ cso_set_blend(ctx->cso, &ctx->blend); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); + cso_set_viewport(ctx->cso, &ctx->viewport); /* sampler */ ctx->sampler.min_img_filter = filter; @@ -348,6 +349,7 @@ util_blit_pixels(struct blit_state *ctx, cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); + cso_restore_viewport(ctx->cso); /* free the texture */ pipe_surface_reference(&texSurf, NULL); -- cgit v1.2.3 From 500c41b8ba3ad025c69e63a2c74da90674a8037d Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 22 Apr 2008 18:11:58 -0400 Subject: Fix reporting of clipped vertices. --- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index e5e38fa264..f98e130ed6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -94,7 +94,7 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, struct vertex_header *out = vertices; const float *scale = pvs->draw->viewport.scale; const float *trans = pvs->draw->viewport.translate; - boolean clipped = FALSE; + unsigned clipped = 0; unsigned j; if (0) debug_printf("%s\n"); @@ -110,11 +110,10 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, out->clipmask = compute_clipmask_gl(out->clip, pvs->draw->plane, pvs->draw->nr_planes); + clipped += out->clipmask; if (out->clipmask == 0) { - clipped = TRUE; - /* divide by w */ float w = 1.0f / out->data[0][3]; -- cgit v1.2.3 From f088b53769aacbee20135d912c33d688b6002011 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 22 Apr 2008 18:20:34 -0400 Subject: Cache translate's structs for emits and fetches. Results in a fair speed improvement. --- src/gallium/auxiliary/draw/draw_pt_emit.c | 63 ++++++++++++++++++++++++++--- src/gallium/auxiliary/draw/draw_pt_fetch.c | 65 ++++++++++++++++++++++++++---- 2 files changed, 114 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 490da4cca3..d35329aba0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -33,13 +33,66 @@ #include "draw/draw_pt.h" #include "translate/translate.h" +#include "cso_cache/cso_cache.h" +#include "cso_cache/cso_hash.h" struct pt_emit { struct draw_context *draw; struct translate *translate; + + struct cso_hash *hash; }; +static INLINE unsigned translate_hash_key_size(struct translate_key *key) +{ + unsigned size = sizeof(struct translate_key) - + sizeof(struct translate_element) * (PIPE_MAX_ATTRIBS - key->nr_elements); + return size; +} + +static INLINE unsigned create_key(struct translate_key *key) +{ + unsigned hash_key; + unsigned size = translate_hash_key_size(key); + /*debug_printf("key size = %d, (els = %d)\n", + size, key->nr_elements);*/ + hash_key = cso_construct_key(key, size); + return hash_key; +} + +static struct translate *cached_translate(struct pt_emit *emit, + struct translate_key *key) +{ + unsigned hash_key = create_key(key); + struct cso_hash_iter iter = cso_hash_find(emit->hash, hash_key); + struct translate *translate = 0; + + if (cso_hash_iter_is_null(iter)) { + translate = translate_create(key); + cso_hash_insert(emit->hash, hash_key, translate); + /*debug_printf("\tCREATED with %d\n", hash_key);*/ + } else { + translate = cso_hash_iter_data(iter); + /*debug_printf("\tOK with %d\n", hash_key);*/ + } + + return translate; +} + + +static INLINE void delete_translates(struct pt_emit *emit) +{ + struct cso_hash *hash = emit->hash; + struct cso_hash_iter iter = cso_hash_first_node(hash); + while (!cso_hash_iter_is_null(iter)) { + struct translate *state = (struct translate*)cso_hash_iter_data(iter); + iter = cso_hash_iter_next(iter); + if (state) { + state->release(state); + } + } +} void draw_pt_emit_prepare( struct pt_emit *emit, unsigned prim ) @@ -123,10 +176,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, if (!emit->translate || memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0) { - if (emit->translate) - emit->translate->release(emit->translate); - - emit->translate = translate_create( &hw_key ); + emit->translate = cached_translate(emit, &hw_key); } } @@ -188,14 +238,15 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) return NULL; emit->draw = draw; + emit->hash = cso_hash_create(); return emit; } void draw_pt_emit_destroy( struct pt_emit *emit ) { - if (emit->translate) - emit->translate->release( emit->translate ); + delete_translates(emit); + cso_hash_delete(emit->hash); FREE(emit); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index f98bce6eac..93da811ed8 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -33,16 +33,67 @@ #include "draw/draw_pt.h" #include "translate/translate.h" +#include "cso_cache/cso_cache.h" +#include "cso_cache/cso_hash.h" struct pt_fetch { struct draw_context *draw; struct translate *translate; - + unsigned vertex_size; + + struct cso_hash *hash; }; +static INLINE unsigned translate_hash_key_size(struct translate_key *key) +{ + unsigned size = sizeof(struct translate_key) - + sizeof(struct translate_element) * (PIPE_MAX_ATTRIBS - key->nr_elements); + return size; +} + +static INLINE unsigned create_key(struct translate_key *key) +{ + unsigned hash_key; + unsigned size = translate_hash_key_size(key); + /*debug_printf("key size = %d, (els = %d)\n", + size, key->nr_elements);*/ + hash_key = cso_construct_key(key, size); + return hash_key; +} + +static struct translate *cached_translate(struct pt_fetch *fetch, + struct translate_key *key) +{ + unsigned hash_key = create_key(key); + struct cso_hash_iter iter = cso_hash_find(fetch->hash, hash_key); + struct translate *translate = 0; + + if (cso_hash_iter_is_null(iter)) { + translate = translate_create(key); + cso_hash_insert(fetch->hash, hash_key, translate); + /*debug_printf("\tCREATED with %d\n", hash_key);*/ + } else { + translate = cso_hash_iter_data(iter); + /*debug_printf("\tOK with %d\n", hash_key);*/ + } + + return translate; +} +static INLINE void delete_translates(struct pt_fetch *fetch) +{ + struct cso_hash *hash = fetch->hash; + struct cso_hash_iter iter = cso_hash_first_node(hash); + while (!cso_hash_iter_is_null(iter)) { + struct translate *state = (struct translate*)cso_hash_iter_data(iter); + iter = cso_hash_iter_next(iter); + if (state) { + state->release(state); + } + } +} /* Perform the fetch from API vertex elements & vertex buffers, to a * contiguous set of float[4] attributes as required for the @@ -112,10 +163,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, if (!fetch->translate || memcmp(&fetch->translate->key, &key, sizeof(key)) != 0) { - if (fetch->translate) - fetch->translate->release(fetch->translate); - - fetch->translate = translate_create( &key ); + fetch->translate = cached_translate(fetch, &key); { static struct vertex_header vh = { 0, 0, 0, 0xffff }; @@ -159,15 +207,16 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch); if (!fetch) return NULL; - + fetch->draw = draw; + fetch->hash = cso_hash_create(); return fetch; } void draw_pt_fetch_destroy( struct pt_fetch *fetch ) { - if (fetch->translate) - fetch->translate->release( fetch->translate ); + delete_translates(fetch); + cso_hash_delete(fetch->hash); FREE(fetch); } -- cgit v1.2.3 From d8f2e400cfe6e32e82d1656d3483905343124b97 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 22 Apr 2008 18:30:31 -0400 Subject: Fix a crash. Rasterizer can be null --- src/gallium/auxiliary/draw/draw_context.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index b916b27877..db92a53ed2 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -122,8 +122,9 @@ void draw_set_rasterizer_state( struct draw_context *draw, draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); draw->rasterizer = raster; - draw->bypass_clipping = (draw->rasterizer->bypass_clipping || - draw->driver.bypass_clipping); + draw->bypass_clipping = + ((draw->rasterizer && draw->rasterizer->bypass_clipping) || + draw->driver.bypass_clipping); } -- cgit v1.2.3 From 36feb5eacf16467d06d5cd9f63d19f17f933f1ef Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 22 Apr 2008 18:32:29 -0400 Subject: In case the 'func' is deleting the state move the iterator before calling it. --- src/gallium/auxiliary/cso_cache/cso_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index f607528fdc..63464e0705 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -334,10 +334,10 @@ void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type, iter = cso_hash_first_node(hash); while (!cso_hash_iter_is_null(iter)) { void *state = cso_hash_iter_data(iter); + iter = cso_hash_iter_next(iter); if (state) { func(state, user_data); } - iter = cso_hash_iter_next(iter); } } -- cgit v1.2.3 From 91e37b71404a83b5e4258e129a2753f7c8fd0706 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 19:10:52 -0600 Subject: gallium: fix bad logic in bind_pstip_fragment_shader(): use &&, not || --- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 61bdd29aa0..aec485a6e7 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -469,7 +469,7 @@ pstip_create_sampler(struct pstip_stage *pstip) static boolean bind_pstip_fragment_shader(struct pstip_stage *pstip) { - if (!pstip->fs->pstip_fs || + if (!pstip->fs->pstip_fs && !generate_pstip_fs(pstip)) return FALSE; -- cgit v1.2.3 From 72fd5b9c5a78792ad8c1fe7c8713a3583008c50a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 19:11:59 -0600 Subject: gallium: added a flushing_vcache flag, test in draw_do_flush() Fixes broken polygon stipple, aaline, aapoint stages --- src/gallium/auxiliary/draw/draw_context.c | 2 +- src/gallium/auxiliary/draw/draw_private.h | 1 + src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index db92a53ed2..f90187816b 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -367,7 +367,7 @@ draw_set_mapped_element_buffer( struct draw_context *draw, */ void draw_do_flush( struct draw_context *draw, unsigned flags ) { - if (!draw->flushing) + if (!draw->flushing && !draw->vcache_flushing) { draw->flushing = TRUE; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 83b81f66a0..39aa81b43c 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -179,6 +179,7 @@ struct draw_context } driver; boolean flushing; + boolean vcache_flushing; boolean bypass_clipping; /* set if either api or driver bypass_clipping true */ /* pipe state that we need: */ diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 153055417d..afcff41043 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -63,6 +63,7 @@ struct vcache_frontend { static void vcache_flush( struct vcache_frontend *vcache ) { + vcache->draw->vcache_flushing = TRUE; if (vcache->draw_count) { vcache->middle->run( vcache->middle, vcache->fetch_elts, @@ -74,6 +75,7 @@ static void vcache_flush( struct vcache_frontend *vcache ) memset(vcache->in, ~0, sizeof(vcache->in)); vcache->fetch_count = 0; vcache->draw_count = 0; + vcache->draw->vcache_flushing = FALSE; } static void vcache_check_flush( struct vcache_frontend *vcache ) -- cgit v1.2.3 From 6fc530ccda2971a5d99a955ad90ae9762238040f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 23 Apr 2008 12:38:37 +1000 Subject: fix non-i386 builds --- src/gallium/auxiliary/translate/translate.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate.c b/src/gallium/auxiliary/translate/translate.c index 86ebeae2a7..b04bc6eefd 100644 --- a/src/gallium/auxiliary/translate/translate.c +++ b/src/gallium/auxiliary/translate/translate.c @@ -38,9 +38,11 @@ struct translate *translate_create( const struct translate_key *key ) { struct translate *translate = NULL; +#if defined(__i386__) || defined(__386__) || defined(i386) translate = translate_sse2_create( key ); if (translate) return translate; +#endif return translate_generic_create( key ); } -- cgit v1.2.3 From b0a58d526624485b98665b103fb5b507253b851b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 23 Apr 2008 11:56:35 +0200 Subject: i915: Real fix for weird fence leak. Thanks Thomas --- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 2 +- src/gallium/winsys/dri/intel/ws_dri_slabpool.c | 109 ++++++++++++++--------- 2 files changed, 67 insertions(+), 44 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index f029dd6a90..923b542771 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -62,7 +62,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, } if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, driFenceType(intel->last_swap_fence), GL_FALSE); + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); driFenceUnReference(&intel->last_swap_fence); intel->last_swap_fence = NULL; } diff --git a/src/gallium/winsys/dri/intel/ws_dri_slabpool.c b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c index 235f0ac972..62d82bbd94 100644 --- a/src/gallium/winsys/dri/intel/ws_dri_slabpool.c +++ b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c @@ -227,6 +227,7 @@ driAllocKernelBO(struct _DriSlabSizeHeader *header) drmMMListHead *list, *next, *head; uint32_t size = header->bufSize * slabPool->desiredNumBuffers; struct _DriKernelBO *kbo; + struct _DriKernelBO *kboTmp; int ret; /* @@ -248,27 +249,36 @@ driAllocKernelBO(struct _DriSlabSizeHeader *header) list != head; list = next, next = list->next) { - kbo = DRMLISTENTRY(struct _DriKernelBO, list, head); + kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); - if ((kbo->bo.size == size) && + if ((kboTmp->bo.size == size) && (slabPool->pageAlignment == 0 || - (kbo->pageAlignment % slabPool->pageAlignment) == 0)) { + (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { + + if (!kbo) + kbo = kboTmp; + + if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) + break; - DRMLISTDELINIT(&kbo->head); - DRMLISTDELINIT(&kbo->timeoutHead); - break; } + } - kbo = NULL; + if (kbo) { + DRMLISTDELINIT(&kbo->head); + DRMLISTDELINIT(&kbo->timeoutHead); } _glthread_UNLOCK_MUTEX(fMan->mutex); if (kbo) { + uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; + ret = 0; - ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, - (slabPool->proposedFlags ^ kbo->bo.flags), - DRM_BO_HINT_DONT_FENCE, 0, 0); + if (new_mask) { + ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, + new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); + } if (ret == 0) return kbo; @@ -284,7 +294,6 @@ driAllocKernelBO(struct _DriSlabSizeHeader *header) kbo->fd = slabPool->fd; DRMINITLISTHEAD(&kbo->head); DRMINITLISTHEAD(&kbo->timeoutHead); - ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, slabPool->proposedFlags, DRM_BO_HINT_DONT_FENCE, &kbo->bo); @@ -417,47 +426,61 @@ driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) static void driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) { - drmMMListHead *list, *prev; + drmMMListHead *list, *prev, *first; struct _DriSlabBuffer *buf; struct _DriSlab *slab; - - int signaled = 0; + int firstWasSignaled = 1; + int signaled; int i; int ret; - list = header->delayedBuffers.next; - - /* Only examine the oldest 1/3 of delayed buffers: + /* + * Rerun the freeing test if the youngest tested buffer + * was signaled, since there might be more idle buffers + * in the delay list. */ - if (header->numDelayed > 3) { - for (i = 0; i < header->numDelayed; i += 3) { - list = list->next; - } - } - prev = list->prev; - for (; list != &header->delayedBuffers; list = prev, prev = list->prev) { - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - slab = buf->parent; - - if (!signaled) { - if (wait) { - ret = driFenceFinish(buf->fence, buf->fenceType, 0); - if (ret) - break; - signaled = 1; - } else { - signaled = driFenceSignaled(buf->fence, buf->fenceType); + while (firstWasSignaled) { + firstWasSignaled = 0; + signaled = 0; + first = header->delayedBuffers.next; + + /* Only examine the oldest 1/3 of delayed buffers: + */ + if (header->numDelayed > 3) { + for (i = 0; i < header->numDelayed; i += 3) { + first = first->next; } - if (signaled) { + } + + for (list = first, prev = list->prev; + list != &header->delayedBuffers; + list = prev, prev = list->prev) { + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + slab = buf->parent; + + if (!signaled) { + if (wait) { + ret = driFenceFinish(buf->fence, buf->fenceType, 0); + if (ret) + break; + signaled = 1; + wait = 0; + } else { + signaled = driFenceSignaled(buf->fence, buf->fenceType); + } + if (signaled) { + if (list == first) + firstWasSignaled = 1; + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { driFenceUnReference(&buf->fence); header->numDelayed--; driSlabFreeBufferLocked(buf); } - } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); } } } @@ -480,15 +503,14 @@ driSlabAllocBuffer(struct _DriSlabSizeHeader *header) _glthread_UNLOCK_MUTEX(header->mutex); if (count != DRI_SLABPOOL_ALLOC_RETRIES) usleep(1); - (void) driAllocSlab(header); _glthread_LOCK_MUTEX(header->mutex); + (void) driAllocSlab(header); count--; } list = header->slabs.next; if (list == &header->slabs) { _glthread_UNLOCK_MUTEX(header->mutex); - //assert(0, "no buffers in slab"); return NULL; } slab = DRMLISTENTRY(struct _DriSlab, list, head); @@ -514,7 +536,6 @@ pool_create(struct _DriBufferPool *driPool, unsigned long size, int i; int ret; - /* * FIXME: Check for compatibility. */ @@ -605,6 +626,8 @@ pool_destroy(struct _DriBufferPool *driPool, void *private) DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); header->numDelayed++; } else { + if (buf->fence) + driFenceUnReference(&buf->fence); driSlabFreeBufferLocked(buf); } -- cgit v1.2.3 From d6a965972b48fec95a2bcb778cf05d0468ba2573 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 23 Apr 2008 13:51:50 +0100 Subject: draw: add missing break (Jakob) --- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index afd5f5544d..1eb7c4bc38 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -136,7 +136,7 @@ emit_vertex( struct vbuf_stage *vbuf, vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); - if (0) draw_dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); + if (1) draw_dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); vbuf->vertex_ptr += vbuf->vertex_size/4; vertex->vertex_id = vbuf->nr_vertices++; @@ -254,6 +254,7 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) case EMIT_4UB: output_format = PIPE_FORMAT_B8G8R8A8_UNORM; emit_sz = 4 * sizeof(ubyte); + break; default: assert(0); output_format = PIPE_FORMAT_NONE; -- cgit v1.2.3 From 43be7a4819ad342e1cb3f8e3fb966a8a78dc2c1b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 23 Apr 2008 13:56:05 +0100 Subject: draw: remove stupid debug (Keith) --- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 1eb7c4bc38..2a19e6916a 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -136,7 +136,7 @@ emit_vertex( struct vbuf_stage *vbuf, vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); - if (1) draw_dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); + if (0) draw_dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); vbuf->vertex_ptr += vbuf->vertex_size/4; vertex->vertex_id = vbuf->nr_vertices++; -- cgit v1.2.3 From 333976c90aafa602816defef3e4cc4a418601a51 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Apr 2008 10:29:52 -0600 Subject: gallium: fix broken hashing for vertex translation It seems we get hash collisions fairly easily and the code as it was didn't deal with that properly. I think we need a simpler hashing interface... --- src/gallium/auxiliary/draw/draw_pt_fetch.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 93da811ed8..a8d4be5b64 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -70,13 +70,21 @@ static struct translate *cached_translate(struct pt_fetch *fetch, struct cso_hash_iter iter = cso_hash_find(fetch->hash, hash_key); struct translate *translate = 0; - if (cso_hash_iter_is_null(iter)) { + while (!cso_hash_iter_is_null(iter)) { + void *iter_data = cso_hash_iter_data(iter); + if (memcmp(iter_data, key, sizeof(*key)) == 0) { + /* found */ + translate = cso_hash_iter_data(iter); + break; + } + iter = cso_hash_iter_next(iter); + /*debug_printf("\tOK with %d\n", hash_key);*/ + } + + if (!translate) { + /* create/insert */ translate = translate_create(key); cso_hash_insert(fetch->hash, hash_key, translate); - /*debug_printf("\tCREATED with %d\n", hash_key);*/ - } else { - translate = cso_hash_iter_data(iter); - /*debug_printf("\tOK with %d\n", hash_key);*/ } return translate; -- cgit v1.2.3 From 53cf833af9776d47bd4c14906784aa8f2027dc4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 24 Apr 2008 00:10:51 +0900 Subject: gallium: Add extern "C" to the headers. --- src/gallium/auxiliary/util/u_blit.h | 8 ++++++++ src/gallium/auxiliary/util/u_gen_mipmap.h | 10 ++++++++++ 2 files changed, 18 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h index 61f1d9bb32..0ce9732e62 100644 --- a/src/gallium/auxiliary/util/u_blit.h +++ b/src/gallium/auxiliary/util/u_blit.h @@ -30,7 +30,11 @@ #define U_BLIT_H +#ifdef __cplusplus +extern "C" { +#endif + struct pipe_context; struct pipe_surface; struct cso_context; @@ -58,4 +62,8 @@ util_blit_pixels(struct blit_state *ctx, float z, uint filter); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h index bd9af54fb7..3277024f07 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.h +++ b/src/gallium/auxiliary/util/u_gen_mipmap.h @@ -31,6 +31,11 @@ #include "pipe/p_state.h" +#ifdef __cplusplus +extern "C" { +#endif + + struct pipe_context; struct pipe_texture; struct cso_context; @@ -52,4 +57,9 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, struct pipe_texture *pt, uint face, uint baseLevel, uint lastLevel, uint filter); + +#ifdef __cplusplus +} +#endif + #endif -- cgit v1.2.3 From a75a3df851339c782e045e01c2b21ffadb1e09f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 24 Apr 2008 01:59:57 +0900 Subject: pipebuffer: New function to flush the buffer cache. --- src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 3 +++ src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 12 +++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 96f9af3825..8de286e3f9 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -144,6 +144,9 @@ struct pb_manager * pb_cache_manager_create(struct pb_manager *provider, unsigned usecs); +void +pb_cache_flush(struct pb_manager *mgr); + /** * Fenced buffer manager. diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 543fd51253..4bd3f94a6c 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -294,8 +294,8 @@ pb_cache_manager_create_buffer(struct pb_manager *_mgr, } -static void -pb_cache_manager_destroy(struct pb_manager *_mgr) +void +pb_cache_flush(struct pb_manager *_mgr) { struct pb_cache_manager *mgr = pb_cache_manager(_mgr); struct list_head *curr, *next; @@ -311,7 +311,13 @@ pb_cache_manager_destroy(struct pb_manager *_mgr) next = curr->next; } _glthread_UNLOCK_MUTEX(mgr->mutex); - +} + + +static void +pb_cache_manager_destroy(struct pb_manager *mgr) +{ + pb_cache_flush(mgr); FREE(mgr); } -- cgit v1.2.3 From 4f93a3a680560940630c44be0066b72a86ff008a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 24 Apr 2008 02:13:31 +0900 Subject: gallium: Fix texture refcount leak. --- src/gallium/auxiliary/cso_cache/cso_context.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 0523cb1949..d246dff433 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -104,6 +104,8 @@ out: static void cso_release_all( struct cso_context *ctx ) { + unsigned i; + if (ctx->pipe) { ctx->pipe->bind_blend_state( ctx->pipe, NULL ); ctx->pipe->bind_rasterizer_state( ctx->pipe, NULL ); @@ -113,6 +115,11 @@ static void cso_release_all( struct cso_context *ctx ) ctx->pipe->bind_vs_state( ctx->pipe, NULL ); } + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + pipe_texture_reference(&ctx->textures[i], NULL); + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + pipe_texture_reference(&ctx->textures_saved[i], NULL); + if (ctx->cache) { cso_cache_delete( ctx->cache ); ctx->cache = NULL; -- cgit v1.2.3 From e1180c2d694851ed12e86027aa406ee20546e6d3 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 23 Apr 2008 13:32:41 -0400 Subject: fix the simple hash finding function and use it --- src/gallium/auxiliary/cso_cache/cso_cache.c | 4 ++-- src/gallium/auxiliary/draw/draw_pt_emit.c | 14 ++++++-------- src/gallium/auxiliary/draw/draw_pt_fetch.c | 17 ++++------------- 3 files changed, 12 insertions(+), 23 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index 63464e0705..096875807b 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -255,9 +255,9 @@ void *cso_hash_find_data_from_template( struct cso_hash *hash, while (!cso_hash_iter_is_null(iter)) { void *iter_data = cso_hash_iter_data(iter); if (!memcmp(iter_data, templ, size)) { - /* Return the payload: + /* We found a match */ - return (unsigned char *)iter_data + size; + return iter_data; } iter = cso_hash_iter_next(iter); } diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index d35329aba0..92ad8f7049 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -65,16 +65,14 @@ static struct translate *cached_translate(struct pt_emit *emit, struct translate_key *key) { unsigned hash_key = create_key(key); - struct cso_hash_iter iter = cso_hash_find(emit->hash, hash_key); - struct translate *translate = 0; - - if (cso_hash_iter_is_null(iter)) { + struct translate *translate = (struct translate*) + cso_hash_find_data_from_template(emit->hash, + hash_key, + key, sizeof(*key)); + if (!translate) { + /* create/insert */ translate = translate_create(key); cso_hash_insert(emit->hash, hash_key, translate); - /*debug_printf("\tCREATED with %d\n", hash_key);*/ - } else { - translate = cso_hash_iter_data(iter); - /*debug_printf("\tOK with %d\n", hash_key);*/ } return translate; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index a8d4be5b64..013d16e1bc 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -67,19 +67,10 @@ static struct translate *cached_translate(struct pt_fetch *fetch, struct translate_key *key) { unsigned hash_key = create_key(key); - struct cso_hash_iter iter = cso_hash_find(fetch->hash, hash_key); - struct translate *translate = 0; - - while (!cso_hash_iter_is_null(iter)) { - void *iter_data = cso_hash_iter_data(iter); - if (memcmp(iter_data, key, sizeof(*key)) == 0) { - /* found */ - translate = cso_hash_iter_data(iter); - break; - } - iter = cso_hash_iter_next(iter); - /*debug_printf("\tOK with %d\n", hash_key);*/ - } + struct translate *translate = (struct translate*) + cso_hash_find_data_from_template(fetch->hash, + hash_key, + key, sizeof(*key)); if (!translate) { /* create/insert */ -- cgit v1.2.3 From 76d39f0c19ee0673b65d6ad09ab338c8b750251a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Apr 2008 11:22:18 -0600 Subject: gallium: more vertex debug code --- src/gallium/drivers/softpipe/sp_setup.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 7df8fc5f67..df7be01fcd 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -719,6 +719,13 @@ void setup_tri( struct setup_context *setup, { float det = calc_det(v0, v1, v2); +#if DEBUG_VERTS + debug_printf("Setup triangle:\n"); + print_vertex(setup, v0); + print_vertex(setup, v1); + print_vertex(setup, v2); +#endif + if (setup->softpipe->no_rast) return; @@ -731,13 +738,6 @@ void setup_tri( struct setup_context *setup, setup->numFragsWritten = 0; #endif -#if DEBUG_VERTS - debug_printf("Triangle:\n"); - print_vertex(setup, v0); - print_vertex(setup, v1); - print_vertex(setup, v2); -#endif - if (cull_tri( setup, det )) return; @@ -935,6 +935,12 @@ setup_line(struct setup_context *setup, int dy = y1 - y0; int xstep, ystep; +#if DEBUG_VERTS + debug_printf("Setup line:\n"); + print_vertex(setup, v0); + print_vertex(setup, v1); +#endif + if (setup->softpipe->no_rast) return; @@ -1056,6 +1062,10 @@ setup_point( struct setup_context *setup, const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; +#if DEBUG_VERTS + debug_printf("Setup point:\n"); + print_vertex(setup, v0); +#endif if (softpipe->no_rast) return; -- cgit v1.2.3 From 2221cb9f74ceee826efb09840188711f408e5428 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Apr 2008 11:23:12 -0600 Subject: gallium: fix broken PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE --- src/gallium/drivers/softpipe/sp_quad_blend.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index 802472df45..ca266ec8e6 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -294,11 +294,12 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: { const float *alpha = quadColor[3]; - float diff[4]; + float diff[4], temp[4]; VEC4_SUB(diff, one, dest[3]); - VEC4_MIN(source[0], alpha, diff); /* R */ - VEC4_MIN(source[1], alpha, diff); /* G */ - VEC4_MIN(source[2], alpha, diff); /* B */ + VEC4_MIN(temp, alpha, diff); + VEC4_MUL(source[0], quadColor[0], temp); /* R */ + VEC4_MUL(source[1], quadColor[1], temp); /* G */ + VEC4_MUL(source[2], quadColor[2], temp); /* B */ } break; case PIPE_BLENDFACTOR_CONST_COLOR: @@ -426,12 +427,8 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ break; case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: - { - const float *alpha = quadColor[3]; - float diff[4]; - VEC4_SUB(diff, one, dest[3]); - VEC4_MIN(source[3], alpha, diff); /* A */ - } + /* multiply alpha by 1.0 */ + VEC4_COPY(source[3], quadColor[3]); /* A */ break; case PIPE_BLENDFACTOR_CONST_COLOR: /* fall-through */ -- cgit v1.2.3 From 809bc8f9ad3667c297afa2652c6688f98d6451b0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Apr 2008 11:24:42 -0600 Subject: gallium: move logicop test outside of loop --- src/gallium/drivers/softpipe/sp_quad_blend.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index ca266ec8e6..74c6bff84a 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -232,6 +232,11 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) struct softpipe_context *softpipe = qs->softpipe; uint cbuf; + if (softpipe->blend->logicop_enable) { + logicop_quad(qs, quad); + return; + } + /* loop over colorbuffer outputs */ for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) { float source[4][QUAD_SIZE], dest[4][QUAD_SIZE]; @@ -242,11 +247,6 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad) float (*quadColor)[4] = quad->outputs.color[cbuf]; uint i, j; - if (softpipe->blend->logicop_enable) { - logicop_quad(qs, quad); - return; - } - /* get/swizzle dest colors */ for (j = 0; j < QUAD_SIZE; j++) { int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1); -- cgit v1.2.3 From 5d873c87186fd3a59b46b4e1e0c987120aa961a7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Apr 2008 11:36:47 -0600 Subject: gallium: additional debug code --- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index f98e130ed6..65cb8ba701 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -61,6 +61,12 @@ compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr) unsigned mask = 0x0; unsigned i; +#if 0 + debug_printf("compute clipmask %f %f %f %f\n", + clip[0], clip[1], clip[2], clip[3]); + assert(clip[3] != 0.0); +#endif + /* Do the hardwired planes first: */ if (-clip[0] + clip[3] < 0) mask |= (1<<0); @@ -122,6 +128,13 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, out->data[0][1] = out->data[0][1] * w * scale[1] + trans[1]; out->data[0][2] = out->data[0][2] * w * scale[2] + trans[2]; out->data[0][3] = w; +#if 0 + debug_printf("post viewport: %f %f %f %f\n", + out->data[0][0], + out->data[0][1], + out->data[0][2], + out->data[0][3]); +#endif } out = (struct vertex_header *)( (char *)out + stride ); -- cgit v1.2.3 From 5fcd84ab39318a371253b1a7285bc657fb82efed Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 23 Apr 2008 14:00:13 -0400 Subject: Create a sharable translate_cache and use it. --- src/gallium/auxiliary/cso_cache/cso_hash.h | 4 +- src/gallium/auxiliary/draw/draw_pt_emit.c | 65 ++------------ src/gallium/auxiliary/draw/draw_pt_fetch.c | 68 ++------------- src/gallium/auxiliary/translate/Makefile | 3 +- src/gallium/auxiliary/translate/SConscript | 1 + src/gallium/auxiliary/translate/translate.h | 1 - src/gallium/auxiliary/translate/translate_cache.c | 100 ++++++++++++++++++++++ src/gallium/auxiliary/translate/translate_cache.h | 54 ++++++++++++ 8 files changed, 173 insertions(+), 123 deletions(-) create mode 100644 src/gallium/auxiliary/translate/translate_cache.c create mode 100644 src/gallium/auxiliary/translate/translate_cache.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.h b/src/gallium/auxiliary/cso_cache/cso_hash.h index 73c4742006..85f3e276c6 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.h +++ b/src/gallium/auxiliary/cso_cache/cso_hash.h @@ -106,12 +106,12 @@ struct cso_hash_iter cso_hash_iter_prev(struct cso_hash_iter iter); /** - * Convenience routine to iterate over the collision list while doing a memory + * Convenience routine to iterate over the collision list while doing a memory * comparison to see which entry in the list is a direct copy of our template * and returns that entry. */ void *cso_hash_find_data_from_template( struct cso_hash *hash, - unsigned hash_key, + unsigned hash_key, void *templ, int size ); diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 92ad8f7049..c6d9537530 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -32,66 +32,16 @@ #include "draw/draw_vertex.h" #include "draw/draw_pt.h" #include "translate/translate.h" - -#include "cso_cache/cso_cache.h" -#include "cso_cache/cso_hash.h" +#include "translate/translate_cache.h" struct pt_emit { struct draw_context *draw; struct translate *translate; - struct cso_hash *hash; + struct translate_cache *cache; }; -static INLINE unsigned translate_hash_key_size(struct translate_key *key) -{ - unsigned size = sizeof(struct translate_key) - - sizeof(struct translate_element) * (PIPE_MAX_ATTRIBS - key->nr_elements); - return size; -} - -static INLINE unsigned create_key(struct translate_key *key) -{ - unsigned hash_key; - unsigned size = translate_hash_key_size(key); - /*debug_printf("key size = %d, (els = %d)\n", - size, key->nr_elements);*/ - hash_key = cso_construct_key(key, size); - return hash_key; -} - -static struct translate *cached_translate(struct pt_emit *emit, - struct translate_key *key) -{ - unsigned hash_key = create_key(key); - struct translate *translate = (struct translate*) - cso_hash_find_data_from_template(emit->hash, - hash_key, - key, sizeof(*key)); - if (!translate) { - /* create/insert */ - translate = translate_create(key); - cso_hash_insert(emit->hash, hash_key, translate); - } - - return translate; -} - - -static INLINE void delete_translates(struct pt_emit *emit) -{ - struct cso_hash *hash = emit->hash; - struct cso_hash_iter iter = cso_hash_first_node(hash); - while (!cso_hash_iter_is_null(iter)) { - struct translate *state = (struct translate*)cso_hash_iter_data(iter); - iter = cso_hash_iter_next(iter); - if (state) { - state->release(state); - } - } -} - void draw_pt_emit_prepare( struct pt_emit *emit, unsigned prim ) { @@ -169,12 +119,10 @@ void draw_pt_emit_prepare( struct pt_emit *emit, hw_key.nr_elements = vinfo->num_attribs; hw_key.output_stride = vinfo->size * 4; - /* Don't bother with caching at this stage: - */ if (!emit->translate || - memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0) + memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0) { - emit->translate = cached_translate(emit, &hw_key); + emit->translate = translate_cache_find(emit->cache, &hw_key); } } @@ -236,15 +184,14 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) return NULL; emit->draw = draw; - emit->hash = cso_hash_create(); + emit->cache = translate_cache_create(); return emit; } void draw_pt_emit_destroy( struct pt_emit *emit ) { - delete_translates(emit); - cso_hash_delete(emit->hash); + translate_cache_destroy(emit->cache); FREE(emit); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 013d16e1bc..8183c51676 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -32,9 +32,8 @@ #include "draw/draw_vertex.h" #include "draw/draw_pt.h" #include "translate/translate.h" +#include "translate/translate_cache.h" -#include "cso_cache/cso_cache.h" -#include "cso_cache/cso_hash.h" struct pt_fetch { struct draw_context *draw; @@ -43,57 +42,9 @@ struct pt_fetch { unsigned vertex_size; - struct cso_hash *hash; + struct translate_cache *cache; }; -static INLINE unsigned translate_hash_key_size(struct translate_key *key) -{ - unsigned size = sizeof(struct translate_key) - - sizeof(struct translate_element) * (PIPE_MAX_ATTRIBS - key->nr_elements); - return size; -} - -static INLINE unsigned create_key(struct translate_key *key) -{ - unsigned hash_key; - unsigned size = translate_hash_key_size(key); - /*debug_printf("key size = %d, (els = %d)\n", - size, key->nr_elements);*/ - hash_key = cso_construct_key(key, size); - return hash_key; -} - -static struct translate *cached_translate(struct pt_fetch *fetch, - struct translate_key *key) -{ - unsigned hash_key = create_key(key); - struct translate *translate = (struct translate*) - cso_hash_find_data_from_template(fetch->hash, - hash_key, - key, sizeof(*key)); - - if (!translate) { - /* create/insert */ - translate = translate_create(key); - cso_hash_insert(fetch->hash, hash_key, translate); - } - - return translate; -} - -static INLINE void delete_translates(struct pt_fetch *fetch) -{ - struct cso_hash *hash = fetch->hash; - struct cso_hash_iter iter = cso_hash_first_node(hash); - while (!cso_hash_iter_is_null(iter)) { - struct translate *state = (struct translate*)cso_hash_iter_data(iter); - iter = cso_hash_iter_next(iter); - if (state) { - state->release(state); - } - } -} - /* Perform the fetch from API vertex elements & vertex buffers, to a * contiguous set of float[4] attributes as required for the * vertex_shader->run_linear() method. @@ -157,17 +108,15 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, key.output_stride = vertex_size; - /* Don't bother with caching at this stage: - */ if (!fetch->translate || - memcmp(&fetch->translate->key, &key, sizeof(key)) != 0) + memcmp(&fetch->translate->key, &key, sizeof(key)) != 0) { - fetch->translate = cached_translate(fetch, &key); + fetch->translate = translate_cache_find(fetch->cache, &key); { static struct vertex_header vh = { 0, 0, 0, 0xffff }; - fetch->translate->set_buffer(fetch->translate, - draw->pt.nr_vertex_buffers, + fetch->translate->set_buffer(fetch->translate, + draw->pt.nr_vertex_buffers, &vh, 0); } @@ -208,14 +157,13 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) return NULL; fetch->draw = draw; - fetch->hash = cso_hash_create(); + fetch->cache = translate_cache_create(); return fetch; } void draw_pt_fetch_destroy( struct pt_fetch *fetch ) { - delete_translates(fetch); - cso_hash_delete(fetch->hash); + translate_cache_destroy(fetch->cache); FREE(fetch); } diff --git a/src/gallium/auxiliary/translate/Makefile b/src/gallium/auxiliary/translate/Makefile index 39dfb0de30..ad2a5b705e 100644 --- a/src/gallium/auxiliary/translate/Makefile +++ b/src/gallium/auxiliary/translate/Makefile @@ -6,7 +6,8 @@ LIBNAME = translate C_SOURCES = \ translate_generic.c \ translate_sse.c \ - translate.c + translate.c \ + translate_cache.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/translate/SConscript b/src/gallium/auxiliary/translate/SConscript index 7608908915..9553a67537 100644 --- a/src/gallium/auxiliary/translate/SConscript +++ b/src/gallium/auxiliary/translate/SConscript @@ -6,6 +6,7 @@ translate = env.ConvenienceLibrary( 'translate_generic.c', 'translate_sse.c', 'translate.c', + 'translate_cache.c', ]) auxiliaries.insert(0, translate) diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index d95d1ac4f3..6c15d7e4dc 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -96,7 +96,6 @@ struct translate *translate_lookup_or_create( struct translate_context *tctx, struct translate *translate_create( const struct translate_key *key ); - /******************************************************************************* * Private: */ diff --git a/src/gallium/auxiliary/translate/translate_cache.c b/src/gallium/auxiliary/translate/translate_cache.c new file mode 100644 index 0000000000..c14f37c42f --- /dev/null +++ b/src/gallium/auxiliary/translate/translate_cache.c @@ -0,0 +1,100 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "pipe/p_state.h" +#include "translate.h" + +#include "cso_cache/cso_cache.h" +#include "cso_cache/cso_hash.h" + +struct translate_cache { + struct cso_hash *hash; +}; + +struct translate_cache * translate_cache_create() +{ + struct translate_cache *cache = MALLOC_STRUCT(translate_cache); + cache->hash = cso_hash_create(); +} + + +static INLINE void delete_translates(struct translate_cache *cache) +{ + struct cso_hash *hash = cache->hash; + struct cso_hash_iter iter = cso_hash_first_node(hash); + while (!cso_hash_iter_is_null(iter)) { + struct translate *state = (struct translate*)cso_hash_iter_data(iter); + iter = cso_hash_iter_next(iter); + if (state) { + state->release(state); + } + } +} + +void translate_cache_destroy(struct translate_cache *cache) +{ + delete_translates(cache); + cso_hash_delete(cache->hash); + FREE(cache); +} + + +static INLINE unsigned translate_hash_key_size(struct translate_key *key) +{ + unsigned size = sizeof(struct translate_key) - + sizeof(struct translate_element) * (PIPE_MAX_ATTRIBS - key->nr_elements); + return size; +} + +static INLINE unsigned create_key(struct translate_key *key) +{ + unsigned hash_key; + unsigned size = translate_hash_key_size(key); + /*debug_printf("key size = %d, (els = %d)\n", + size, key->nr_elements);*/ + hash_key = cso_construct_key(key, size); + return hash_key; +} + +struct translate * translate_cache_find(struct translate_cache *cache, + struct translate_key *key) +{ + unsigned hash_key = create_key(key); + struct translate *translate = (struct translate*) + cso_hash_find_data_from_template(cache->hash, + hash_key, + key, sizeof(*key)); + + if (!translate) { + /* create/insert */ + translate = translate_create(key); + cso_hash_insert(cache->hash, hash_key, translate); + } + + return translate; +} diff --git a/src/gallium/auxiliary/translate/translate_cache.h b/src/gallium/auxiliary/translate/translate_cache.h new file mode 100644 index 0000000000..63fc57b7ea --- /dev/null +++ b/src/gallium/auxiliary/translate/translate_cache.h @@ -0,0 +1,54 @@ +/* + * Copyright 2008 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef _TRANSLATE_CACHE_H +#define _TRANSLATE_CACHE_H + + +/******************************************************************************* + * Translate cache. + * Simply used to cache created translates. Avoids unecessary creation of + * translate's if one suitable for a given translate_key has already been + * created. + * + * Note: this functionality depends and requires the CSO module. + */ +struct translate_cache; + +struct translate_key; +struct translate; + +struct translate_cache *translate_cache_create(); +void translate_cache_destroy(struct translate_cache *cache); + +/** + * Will try to find a translate structure matched by the given key. + * If such a structure doesn't exist in the cache the function + * will automatically create it, insert it in the cache and + * return the created version. + * + */ +struct translate *translate_cache_find(struct translate_cache *cache, + struct translate_key *key); + +#endif -- cgit v1.2.3 From 95f8f8863a80ce1e584160d4d085213a9bbaef12 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 23 Apr 2008 14:07:53 -0400 Subject: Add translate cache to fetch_emit stage and add out of memory checks to code creating the cache. --- src/gallium/auxiliary/draw/draw_pt_emit.c | 4 ++++ src/gallium/auxiliary/draw/draw_pt_fetch.c | 5 +++++ src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 20 +++++++++++++------- 3 files changed, 22 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index c6d9537530..35707af8a8 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -185,6 +185,10 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) emit->draw = draw; emit->cache = translate_cache_create(); + if (!emit->cache) { + FREE(emit); + return NULL; + } return emit; } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 8183c51676..cc61b113fd 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -158,6 +158,11 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) fetch->draw = draw; fetch->cache = translate_cache_create(); + if (!fetch->cache) { + FREE(fetch); + return NULL; + } + return fetch; } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 68b2c5b1e3..a4de341df8 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -37,6 +37,7 @@ #include "draw/draw_vertex.h" #include "draw/draw_pt.h" #include "translate/translate.h" +#include "translate/translate_cache.h" /* The simplest 'middle end' in the new vertex code. * @@ -81,6 +82,7 @@ struct fetch_emit_middle_end { */ float point_size; + struct translate_cache *cache; }; @@ -174,10 +176,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, if (!feme->translate || memcmp(&feme->translate->key, &key, sizeof(key)) != 0) { - if (feme->translate) - feme->translate->release(feme->translate); + feme->translate = translate_cache_find(feme->cache, + &key); - feme->translate = translate_create( &key ); feme->translate->set_buffer(feme->translate, draw->pt.nr_vertex_buffers, @@ -266,9 +267,8 @@ static void fetch_emit_destroy( struct draw_pt_middle_end *middle ) { struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; - if (feme->translate) - feme->translate->release( feme->translate ); - + translate_cache_destroy(feme->cache); + FREE(middle); } @@ -278,7 +278,13 @@ struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ) struct fetch_emit_middle_end *fetch_emit = CALLOC_STRUCT( fetch_emit_middle_end ); if (fetch_emit == NULL) return NULL; - + + fetch_emit->cache = translate_cache_create(); + if (!fetch_emit->cache) { + FREE(fetch_emit); + return NULL; + } + fetch_emit->base.prepare = fetch_emit_prepare; fetch_emit->base.run = fetch_emit_run; fetch_emit->base.finish = fetch_emit_finish; -- cgit v1.2.3 From 3f6242d3e4d3ee61884a91a3eef4be8dfaadee3c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Apr 2008 12:11:00 -0600 Subject: gallium: passthrough tri, not point --- src/gallium/auxiliary/draw/draw_pipe_wide_line.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c index 452732e662..878c9c7169 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -169,7 +169,7 @@ struct draw_stage *draw_wide_line_stage( struct draw_context *draw ) wide->stage.next = NULL; wide->stage.point = draw_pipe_passthrough_point; wide->stage.line = wideline_line; - wide->stage.tri = draw_pipe_passthrough_point; + wide->stage.tri = draw_pipe_passthrough_tri; wide->stage.flush = wideline_flush; wide->stage.reset_stipple_counter = wideline_reset_stipple_counter; wide->stage.destroy = wideline_destroy; -- cgit v1.2.3 From bff371c431b962c62d74800c543e09d258e67551 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Apr 2008 17:40:39 -0600 Subject: gallium: fix comments, whitespace changes --- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index aec485a6e7..848d3be55d 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -433,9 +433,7 @@ pstip_create_texture(struct pstip_stage *pstip) /** - * Create the sampler CSO that'll be used for antialiasing. - * By using a mipmapped texture, we don't have to generate a different - * texture image for each line size. + * Create the sampler CSO that'll be used for stippling. */ static boolean pstip_create_sampler(struct pstip_stage *pstip) @@ -463,8 +461,8 @@ pstip_create_sampler(struct pstip_stage *pstip) /** - * When we're about to draw our first AA line in a batch, this function is - * called to tell the driver to bind our modified fragment shader. + * When we're about to draw our first stipple polygon in a batch, this function + * is called to tell the driver to bind our modified fragment shader. */ static boolean bind_pstip_fragment_shader(struct pstip_stage *pstip) @@ -478,7 +476,6 @@ bind_pstip_fragment_shader(struct pstip_stage *pstip) } - static INLINE struct pstip_stage * pstip_stage( struct draw_stage *stage ) { @@ -486,9 +483,6 @@ pstip_stage( struct draw_stage *stage ) } - - - static void pstip_first_tri(struct draw_stage *stage, struct prim_header *header) { @@ -521,7 +515,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); - /* now really draw first line */ + /* now really draw first triangle */ stage->tri = draw_pipe_passthrough_tri; stage->tri(stage, header); } @@ -698,11 +692,10 @@ pstip_set_polygon_stipple(struct pipe_context *pipe, } - /** - * Called by drivers that want to install this AA line prim stage + * Called by drivers that want to install this polygon stipple stage * into the draw module's pipeline. This will not be used if the - * hardware has native support for AA lines. + * hardware has native support for polygon stipple. */ boolean draw_install_pstipple_stage(struct draw_context *draw, @@ -713,7 +706,7 @@ draw_install_pstipple_stage(struct draw_context *draw, pipe->draw = (void *) draw; /* - * Create / install AA line drawing / prim stage + * Create / install pgon stipple drawing / prim stage */ pstip = draw_pstip_stage( draw ); if (pstip == NULL) -- cgit v1.2.3 From 8437f5c763c1a1ac364d71426109c2b095bbcc72 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Apr 2008 17:41:30 -0600 Subject: gallium: fix comments --- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index ac0aa4cd7c..8c38c15d86 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -481,7 +481,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx, /** - * Generate the frag shader we'll use for drawing AA lines. + * Generate the frag shader we'll use for drawing AA points. * This will be the user's shader plus some texture/modulate instructions. */ static boolean @@ -531,7 +531,7 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) /** - * When we're about to draw our first AA line in a batch, this function is + * When we're about to draw our first AA point in a batch, this function is * called to tell the driver to bind our modified fragment shader. */ static boolean @@ -697,7 +697,7 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header) } } - /* now really draw first line */ + /* now really draw first point */ stage->point = aapoint_point; stage->point(stage, header); } -- cgit v1.2.3 From 14d1ca8d867d6e44c756cb759f92421107118b2e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Apr 2008 18:08:20 -0600 Subject: gallium: fix issues in recursive flushing When flushing/rendering, some stages (like AA line/point) need to set pipe/driver state. Those driver functions often call draw_flush(). That leads to recursion. Use new draw->suspend_flush flag to explicitly prevent that in the key places. Remove the draw->vcache_flushing field. Reuse draw->flushing as a debug/assertion var. --- src/gallium/auxiliary/draw/draw_context.c | 4 +++- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 18 +++++++++++++++--- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 7 +++++++ src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 16 ++++++++++++++-- src/gallium/auxiliary/draw/draw_private.h | 6 +++--- src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 -- 6 files changed, 42 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index f90187816b..98e23fa830 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -367,8 +367,10 @@ draw_set_mapped_element_buffer( struct draw_context *draw, */ void draw_do_flush( struct draw_context *draw, unsigned flags ) { - if (!draw->flushing && !draw->vcache_flushing) + if (!draw->suspend_flushing) { + assert(!draw->flushing); /* catch inadvertant recursion */ + draw->flushing = TRUE; draw_pipeline_flush( draw, flags ); diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 7e5f8bd281..0545dbc171 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -485,11 +485,16 @@ aaline_create_sampler(struct aaline_stage *aaline) static boolean bind_aaline_fragment_shader(struct aaline_stage *aaline) { + struct draw_context *draw = aaline->stage.draw; + if (!aaline->fs->aaline_fs && !generate_aaline_fs(aaline)) return FALSE; + draw->suspend_flushing = TRUE; aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs); + draw->suspend_flushing = FALSE; + return TRUE; } @@ -663,8 +668,10 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit], aaline->texture); + 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); + draw->suspend_flushing = FALSE; /* now really draw first line */ stage->line = aaline_line; @@ -682,14 +689,14 @@ aaline_flush(struct draw_stage *stage, unsigned flags) stage->line = aaline_first_line; stage->next->flush( stage->next, flags ); - /* restore original frag shader */ + /* restore original frag shader, texture, sampler state */ + draw->suspend_flushing = TRUE; aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); - - /* XXX restore original texture, sampler state */ aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, aaline->state.sampler); aaline->driver_set_sampler_textures(pipe, aaline->num_textures, aaline->state.texture); + draw->suspend_flushing = FALSE; draw->extra_vp_outputs.slot = 0; } @@ -783,6 +790,7 @@ aaline_bind_fs_state(struct pipe_context *pipe, void *fs) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; + /* save current */ aaline->fs = aafs; /* pass-through */ @@ -807,9 +815,12 @@ aaline_bind_sampler_states(struct pipe_context *pipe, unsigned num, void **sampler) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct draw_context *draw = aaline->stage.draw; + /* save current */ memcpy(aaline->state.sampler, sampler, num * sizeof(void *)); aaline->num_samplers = num; + /* pass-through */ aaline->driver_bind_sampler_states(aaline->pipe, num, sampler); } @@ -820,6 +831,7 @@ aaline_set_sampler_textures(struct pipe_context *pipe, unsigned num, struct pipe_texture **texture) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct draw_context *draw = aaline->stage.draw; uint i; /* save current */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 8c38c15d86..122a48660a 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -537,11 +537,16 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) static boolean bind_aapoint_fragment_shader(struct aapoint_stage *aapoint) { + struct draw_context *draw = aapoint->stage.draw; + if (!aapoint->fs->aapoint_fs && !generate_aapoint_fs(aapoint)) return FALSE; + draw->suspend_flushing = TRUE; aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs); + draw->suspend_flushing = FALSE; + return TRUE; } @@ -714,7 +719,9 @@ aapoint_flush(struct draw_stage *stage, unsigned flags) stage->next->flush( stage->next, flags ); /* restore original frag shader */ + draw->suspend_flushing = TRUE; aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs); + draw->suspend_flushing = FALSE; draw->extra_vp_outputs.slot = 0; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 848d3be55d..f8156fe731 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -467,11 +467,14 @@ pstip_create_sampler(struct pstip_stage *pstip) static boolean bind_pstip_fragment_shader(struct pstip_stage *pstip) { + struct draw_context *draw = pstip->stage.draw; if (!pstip->fs->pstip_fs && !generate_pstip_fs(pstip)) return FALSE; + draw->suspend_flushing = TRUE; pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs); + draw->suspend_flushing = FALSE; return TRUE; } @@ -488,6 +491,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) { struct pstip_stage *pstip = pstip_stage(stage); struct pipe_context *pipe = pstip->pipe; + struct draw_context *draw = stage->draw; uint num_samplers; assert(stage->draw->rasterizer->poly_stipple_enable); @@ -512,8 +516,10 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) assert(num_samplers <= PIPE_MAX_SAMPLERS); + draw->suspend_flushing = TRUE; pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); + draw->suspend_flushing = FALSE; /* now really draw first triangle */ stage->tri = draw_pipe_passthrough_tri; @@ -524,7 +530,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) static void pstip_flush(struct draw_stage *stage, unsigned flags) { - /*struct draw_context *draw = stage->draw;*/ + struct draw_context *draw = stage->draw; struct pstip_stage *pstip = pstip_stage(stage); struct pipe_context *pipe = pstip->pipe; @@ -534,11 +540,13 @@ pstip_flush(struct draw_stage *stage, unsigned flags) /* restore original frag shader */ pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); - /* XXX restore original texture, sampler state */ + /* restore original texture, sampler state */ + draw->suspend_flushing = TRUE; pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, pstip->state.samplers); pstip->driver_set_sampler_textures(pipe, pstip->num_textures, pstip->state.textures); + draw->suspend_flushing = FALSE; } @@ -661,6 +669,7 @@ pstip_set_sampler_textures(struct pipe_context *pipe, unsigned num, struct pipe_texture **texture) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct draw_context *draw = pstip->stage.draw; uint i; /* save current */ @@ -683,8 +692,11 @@ pstip_set_polygon_stipple(struct pipe_context *pipe, const struct pipe_poly_stipple *stipple) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct draw_context *draw = (struct draw_context *) pipe->draw; + /* save current */ pstip->state.stipple = stipple; + /* pass-through */ pstip->driver_set_polygon_stipple(pstip->pipe, stipple); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 39aa81b43c..ca5021c5c6 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -178,9 +178,9 @@ struct draw_context boolean bypass_clipping; } driver; - boolean flushing; - boolean vcache_flushing; - boolean bypass_clipping; /* set if either api or driver bypass_clipping true */ + boolean flushing; /**< debugging/sanity */ + boolean suspend_flushing; /**< internally set */ + boolean bypass_clipping; /**< set if either api or driver bypass_clipping true */ /* pipe state that we need: */ const struct pipe_rasterizer_state *rasterizer; diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index afcff41043..153055417d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -63,7 +63,6 @@ struct vcache_frontend { static void vcache_flush( struct vcache_frontend *vcache ) { - vcache->draw->vcache_flushing = TRUE; if (vcache->draw_count) { vcache->middle->run( vcache->middle, vcache->fetch_elts, @@ -75,7 +74,6 @@ static void vcache_flush( struct vcache_frontend *vcache ) memset(vcache->in, ~0, sizeof(vcache->in)); vcache->fetch_count = 0; vcache->draw_count = 0; - vcache->draw->vcache_flushing = FALSE; } static void vcache_check_flush( struct vcache_frontend *vcache ) -- cgit v1.2.3 From bb4f8ae1f93d17c57fd8f62bea24b48131e02037 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Apr 2008 18:09:20 -0600 Subject: gallium: reorder code to fix a recursive flush --- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index f8156fe731..da303a13ad 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -537,11 +537,9 @@ pstip_flush(struct draw_stage *stage, unsigned flags) stage->tri = pstip_first_tri; stage->next->flush( stage->next, flags ); - /* restore original frag shader */ - pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); - - /* restore original texture, sampler state */ + /* restore original frag shader, texture, sampler state */ draw->suspend_flushing = TRUE; + pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, pstip->state.samplers); pstip->driver_set_sampler_textures(pipe, pstip->num_textures, -- cgit v1.2.3 From 7333578d2a5fa18f7f0101fc3fd3b03cf2f356bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 24 Apr 2008 10:12:07 +0100 Subject: gallium: Initial support for pixel formats with unused storage components. Also clarify that RGB formats with no (used) alpha component are treated as having alpha = 1.0. --- src/gallium/auxiliary/util/p_tile.c | 52 ++++++++++++++ src/gallium/auxiliary/util/u_gen_mipmap.c | 2 + src/gallium/auxiliary/util/u_pack_color.h | 38 +++++++++++ src/gallium/include/pipe/p_format.h | 108 +++++++++++++++++------------- 4 files changed, 153 insertions(+), 47 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 520da5cecd..91283a9ab0 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -169,6 +169,52 @@ a8r8g8b8_put_tile_rgba(unsigned *dst, } +/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ + +static void +x8r8g8b8_get_tile_rgba(unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const unsigned pixel = *src++; + pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); + pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); + pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); + pRow[3] = UBYTE_TO_FLOAT(0xff); + } + p += dst_stride; + } +} + + +static void +x8r8g8b8_put_tile_rgba(unsigned *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); + *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b; + } + p += src_stride; + } +} + + /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/ static void @@ -647,6 +693,9 @@ pipe_get_tile_rgba(struct pipe_context *pipe, case PIPE_FORMAT_A8R8G8B8_UNORM: a8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); break; + case PIPE_FORMAT_X8R8G8B8_UNORM: + x8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + break; case PIPE_FORMAT_B8G8R8A8_UNORM: b8g8r8a8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); break; @@ -723,6 +772,9 @@ pipe_put_tile_rgba(struct pipe_context *pipe, case PIPE_FORMAT_A8R8G8B8_UNORM: a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); break; + case PIPE_FORMAT_X8R8G8B8_UNORM: + x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); + break; case PIPE_FORMAT_B8G8R8A8_UNORM: b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); break; diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index dfdb5f16fe..b8dc6c66c0 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -475,7 +475,9 @@ format_to_type_comps(enum pipe_format pformat, { switch (pformat) { case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_UNORM: case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8X8_UNORM: *datatype = UBYTE; *comps = 4; return; diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 1f6604c554..50ef44992b 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -53,18 +53,36 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, *d = (r << 24) | (g << 16) | (b << 8) | a; } return; + case PIPE_FORMAT_R8G8B8X8_UNORM: + { + uint *d = (uint *) dest; + *d = (r << 24) | (g << 16) | (b << 8) | 0xff; + } + return; case PIPE_FORMAT_A8R8G8B8_UNORM: { uint *d = (uint *) dest; *d = (a << 24) | (r << 16) | (g << 8) | b; } return; + case PIPE_FORMAT_X8R8G8B8_UNORM: + { + uint *d = (uint *) dest; + *d = (0xff << 24) | (r << 16) | (g << 8) | b; + } + return; case PIPE_FORMAT_B8G8R8A8_UNORM: { uint *d = (uint *) dest; *d = (b << 24) | (g << 16) | (r << 8) | a; } return; + case PIPE_FORMAT_B8G8R8X8_UNORM: + { + uint *d = (uint *) dest; + *d = (b << 24) | (g << 16) | (r << 8) | 0xff; + } + return; case PIPE_FORMAT_R5G6B5_UNORM: { ushort *d = (ushort *) dest; @@ -101,18 +119,36 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest) *d = (r << 24) | (g << 16) | (b << 8) | a; } return; + case PIPE_FORMAT_R8G8B8X8_UNORM: + { + uint *d = (uint *) dest; + *d = (r << 24) | (g << 16) | (b << 8) | 0xff; + } + return; case PIPE_FORMAT_A8R8G8B8_UNORM: { uint *d = (uint *) dest; *d = (a << 24) | (r << 16) | (g << 8) | b; } return; + case PIPE_FORMAT_X8R8G8B8_UNORM: + { + uint *d = (uint *) dest; + *d = (0xff << 24) | (r << 16) | (g << 8) | b; + } + return; case PIPE_FORMAT_B8G8R8A8_UNORM: { uint *d = (uint *) dest; *d = (b << 24) | (g << 16) | (r << 8) | a; } return; + case PIPE_FORMAT_B8G8R8X8_UNORM: + { + uint *d = (uint *) dest; + *d = (b << 24) | (g << 16) | (r << 8) | 0xff; + } + return; case PIPE_FORMAT_R5G6B5_UNORM: { ushort *d = (ushort *) dest; @@ -159,8 +195,10 @@ util_pack_z(enum pipe_format format, double z) else return (uint) (z * 0xffffffff); case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: return (uint) (z * 0xffffff); case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z24X8_UNORM: return ((uint) (z * 0xffffff)) << 8; default: debug_printf("gallium: unhandled fomrat in util_pack_z()"); diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index ef9e3a3d6c..2ee6f100bf 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -163,18 +163,21 @@ static INLINE uint pf_get(pipe_format_rgbazs_t f, uint shift, uint mask) /** * Shorthand macro for common format swizzles. */ -#define _PIPE_FORMAT_R000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) -#define _PIPE_FORMAT_RG00 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) -#define _PIPE_FORMAT_RGB0 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_0 ) +#define _PIPE_FORMAT_R001 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_1 ) +#define _PIPE_FORMAT_RG01 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_1 ) +#define _PIPE_FORMAT_RGB1 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_1 ) #define _PIPE_FORMAT_RGBA _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_A ) #define _PIPE_FORMAT_ARGB _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_A, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B ) #define _PIPE_FORMAT_BGRA _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_A ) +#define _PIPE_FORMAT_1RGB _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_1, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B ) +#define _PIPE_FORMAT_BGR1 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_1 ) #define _PIPE_FORMAT_0000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) #define _PIPE_FORMAT_000R _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_R ) #define _PIPE_FORMAT_RRR1 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_1 ) #define _PIPE_FORMAT_RRRR _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R ) #define _PIPE_FORMAT_RRRG _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G ) #define _PIPE_FORMAT_Z000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) +#define _PIPE_FORMAT_0Z00 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) #define _PIPE_FORMAT_SZ00 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) #define _PIPE_FORMAT_ZS00 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_Z, PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) #define _PIPE_FORMAT_S000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_S, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) @@ -229,10 +232,12 @@ static INLINE uint pf_rev(pipe_format_ycbcr_t f) enum pipe_format { PIPE_FORMAT_NONE = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_0000, 0, 0, 0, 0, PIPE_FORMAT_TYPE_UNKNOWN ), PIPE_FORMAT_A8R8G8B8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_ARGB, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_X8R8G8B8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_1RGB, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_B8G8R8A8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGRA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_B8G8R8X8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_A1R5G5B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 1, 5, 5, 5, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_A4R4G4B4_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_R5G6B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_RGB0, 5, 6, 5, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R5G6B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_RGB1, 5, 6, 5, 0, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_U_L8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte luminance */ PIPE_FORMAT_U_A8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_000R, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha */ PIPE_FORMAT_U_I8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRR, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte intensity */ @@ -244,68 +249,75 @@ enum pipe_format { PIPE_FORMAT_Z32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), PIPE_FORMAT_S8Z24_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_SZ00, 1, 3, 0, 0, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_Z24S8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_ZS00, 3, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_X8Z24_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_0Z00, 1, 3, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_Z24X8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 3, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_S8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_S000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte stencil */ - PIPE_FORMAT_R64_FLOAT = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), - PIPE_FORMAT_R64G64_FLOAT = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), - PIPE_FORMAT_R64G64B64_FLOAT = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R64_FLOAT = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R64G64_FLOAT = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R64G64B64_FLOAT = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_FLOAT ), PIPE_FORMAT_R64G64B64A64_FLOAT = _PIPE_FORMAT_RGBAZS_64( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_FLOAT ), - PIPE_FORMAT_R32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), - PIPE_FORMAT_R32G32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 4, 4, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), - PIPE_FORMAT_R32G32B32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 4, 4, 4, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R32G32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_FLOAT ), + PIPE_FORMAT_R32G32B32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_FLOAT ), PIPE_FORMAT_R32G32B32A32_FLOAT = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_FLOAT ), - PIPE_FORMAT_R32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_R32G32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 4, 4, 0, 0, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_R32G32B32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 4, 4, 4, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R32G32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R32G32B32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_R32G32B32A32_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_R32_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ), - PIPE_FORMAT_R32G32_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 4, 4, 0, 0, PIPE_FORMAT_TYPE_USCALED ), - PIPE_FORMAT_R32G32B32_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 4, 4, 4, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R32_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R32G32_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R32G32B32_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_USCALED ), PIPE_FORMAT_R32G32B32A32_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_USCALED ), - PIPE_FORMAT_R32_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ), - PIPE_FORMAT_R32G32_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 4, 4, 0, 0, PIPE_FORMAT_TYPE_SNORM ), - PIPE_FORMAT_R32G32B32_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 4, 4, 4, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R32_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R32G32_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R32G32B32_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_SNORM ), PIPE_FORMAT_R32G32B32A32_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_SNORM ), - PIPE_FORMAT_R32_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 4, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), - PIPE_FORMAT_R32G32_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 4, 4, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), - PIPE_FORMAT_R32G32B32_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 4, 4, 4, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R32_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R32G32_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R32G32B32_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R32G32B32A32_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_SSCALED ), - PIPE_FORMAT_R16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_R16G16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 2, 2, 0, 0, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_R16G16B16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 2, 2, 2, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R16G16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R16G16B16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_R16G16B16A16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_R16_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ), - PIPE_FORMAT_R16G16_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 2, 2, 0, 0, PIPE_FORMAT_TYPE_USCALED ), - PIPE_FORMAT_R16G16B16_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 2, 2, 2, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R16_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R16G16_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R16G16B16_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_USCALED ), PIPE_FORMAT_R16G16B16A16_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_USCALED ), - PIPE_FORMAT_R16_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ), - PIPE_FORMAT_R16G16_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 2, 2, 0, 0, PIPE_FORMAT_TYPE_SNORM ), - PIPE_FORMAT_R16G16B16_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 2, 2, 2, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R16_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R16G16_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R16G16B16_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_SNORM ), PIPE_FORMAT_R16G16B16A16_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_SNORM ), - PIPE_FORMAT_R16_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), - PIPE_FORMAT_R16G16_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 2, 2, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), - PIPE_FORMAT_R16G16B16_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 2, 2, 2, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R16_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 2, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R16G16_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 2, 2, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R16G16B16_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R16G16B16A16_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 2, 2, 2, 2, PIPE_FORMAT_TYPE_SSCALED ), - PIPE_FORMAT_R8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_R8G8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_R8G8B8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R8G8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R8G8B8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_R8G8B8A8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_R8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ), - PIPE_FORMAT_R8G8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_USCALED ), - PIPE_FORMAT_R8G8B8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R8G8B8X8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_R8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R8G8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R8G8B8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_USCALED ), PIPE_FORMAT_R8G8B8A8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_USCALED ), - PIPE_FORMAT_R8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ), - PIPE_FORMAT_R8G8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SNORM ), - PIPE_FORMAT_R8G8B8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R8G8B8X8_USCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_USCALED ), + PIPE_FORMAT_R8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R8G8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R8G8B8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SNORM ), PIPE_FORMAT_R8G8B8A8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ), - PIPE_FORMAT_R8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), - PIPE_FORMAT_R8G8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), - PIPE_FORMAT_R8G8B8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R8G8B8X8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_R8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R8G8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R8G8B8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R8G8B8A8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R8G8B8X8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ), /* sRGB formats */ PIPE_FORMAT_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), PIPE_FORMAT_A8_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), - PIPE_FORMAT_R8G8B8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB ), + PIPE_FORMAT_R8G8B8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB ), PIPE_FORMAT_R8G8B8A8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), + PIPE_FORMAT_R8G8B8X8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), /* compressed formats */ PIPE_FORMAT_DXT1_RGB = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 0 ), @@ -442,6 +454,8 @@ static INLINE uint pf_get_bits( enum pipe_format format ) switch (pf_layout(format)) { case PIPE_FORMAT_LAYOUT_RGBAZS: return + pf_get_component_bits( format, PIPE_FORMAT_COMP_0 ) + + pf_get_component_bits( format, PIPE_FORMAT_COMP_1 ) + pf_get_component_bits( format, PIPE_FORMAT_COMP_R ) + pf_get_component_bits( format, PIPE_FORMAT_COMP_G ) + pf_get_component_bits( format, PIPE_FORMAT_COMP_B ) + -- cgit v1.2.3 From dddedd915afb58ab6b87492e850baeadc007fe47 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 24 Apr 2008 12:36:04 +0100 Subject: xlib: only shortcircuit makecurrent if NO_RAST set, otherwise window size updates fail --- src/gallium/winsys/xlib/fakeglx.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c index 6e04cb4117..ec77e81fed 100644 --- a/src/gallium/winsys/xlib/fakeglx.c +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -1459,6 +1459,13 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx ) { struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; + static boolean firsttime = 1, no_rast = 0; + + if (firsttime) { + no_rast = getenv("SP_NO_RAST") != NULL; + firsttime = 0; + } + if (ctx && draw && read) { XMesaBuffer drawBuffer, readBuffer; @@ -1504,7 +1511,8 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, #endif } - if (MakeCurrent_PrevContext == ctx && + if (no_rast && + MakeCurrent_PrevContext == ctx && MakeCurrent_PrevDrawable == draw && MakeCurrent_PrevReadable == read && MakeCurrent_PrevDrawBuffer == drawBuffer && -- cgit v1.2.3 From f93332da5655a31b6c44a1079629a15360ff999b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 24 Apr 2008 12:38:15 +0100 Subject: draw: handle edgeflags and reset-line-stipple again --- src/gallium/auxiliary/draw/draw_pipe.c | 19 +- src/gallium/auxiliary/draw/draw_pipe.h | 11 + src/gallium/auxiliary/draw/draw_pipe_clip.c | 56 ++-- src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 6 +- src/gallium/auxiliary/draw/draw_pipe_offset.c | 3 +- src/gallium/auxiliary/draw/draw_pipe_stipple.c | 4 + src/gallium/auxiliary/draw/draw_pipe_twoside.c | 3 +- src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 24 +- src/gallium/auxiliary/draw/draw_private.h | 40 +-- src/gallium/auxiliary/draw/draw_pt.h | 9 - src/gallium/auxiliary/draw/draw_pt_fetch.c | 17 ++ src/gallium/auxiliary/draw/draw_pt_vcache.c | 356 +++++------------------ src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h | 174 +++++++++++ 13 files changed, 348 insertions(+), 374 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index d0890203a5..1c9d8650e2 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -116,8 +116,7 @@ static void do_point( struct draw_context *draw, { struct prim_header prim; - prim.reset_line_stipple = 0; - prim.edgeflags = 1; + prim.flags = 0; prim.pad = 0; prim.v[0] = (struct vertex_header *)v0; @@ -126,13 +125,13 @@ static void do_point( struct draw_context *draw, static void do_line( struct draw_context *draw, + ushort flags, const char *v0, const char *v1 ) { struct prim_header prim; - prim.reset_line_stipple = 1; /* fixme */ - prim.edgeflags = 1; + prim.flags = flags; prim.pad = 0; prim.v[0] = (struct vertex_header *)v0; prim.v[1] = (struct vertex_header *)v1; @@ -142,6 +141,7 @@ static void do_line( struct draw_context *draw, static void do_triangle( struct draw_context *draw, + ushort flags, char *v0, char *v1, char *v2 ) @@ -151,10 +151,7 @@ static void do_triangle( struct draw_context *draw, prim.v[0] = (struct vertex_header *)v0; prim.v[1] = (struct vertex_header *)v1; prim.v[2] = (struct vertex_header *)v2; - prim.reset_line_stipple = 1; - prim.edgeflags = ((prim.v[0]->edgeflag) | - (prim.v[1]->edgeflag << 1) | - (prim.v[2]->edgeflag << 2)); + prim.flags = flags; prim.pad = 0; draw->pipeline.first->tri( draw->pipeline.first, &prim ); @@ -197,13 +194,15 @@ void draw_pipeline_run( struct draw_context *draw, case PIPE_PRIM_LINES: for (i = 0; i+1 < count; i += 2) do_line( draw, - verts + stride * elts[i+0], + elts[i+0], + verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK), verts + stride * elts[i+1]); break; case PIPE_PRIM_TRIANGLES: for (i = 0; i+2 < count; i += 3) do_triangle( draw, - verts + stride * elts[i+0], + elts[i+0], + verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK), verts + stride * elts[i+1], verts + stride * elts[i+2]); break; diff --git a/src/gallium/auxiliary/draw/draw_pipe.h b/src/gallium/auxiliary/draw/draw_pipe.h index 2476abb2b2..f1cb0891ca 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.h +++ b/src/gallium/auxiliary/draw/draw_pipe.h @@ -37,6 +37,17 @@ #include "draw_private.h" /* for sizeof(vertex_header) */ +/** + * Basic info for a point/line/triangle primitive. + */ +struct prim_header { + float det; /**< front/back face determinant */ + ushort flags; + ushort pad; + struct vertex_header *v[3]; /**< 1 to 3 vertex pointers */ +}; + + /** * Base class for all primitive drawing stages. diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 21216addea..ce80c94163 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -119,7 +119,7 @@ static void interp( const struct clipper *clip, */ { dst->clipmask = 0; - dst->edgeflag = 0; + dst->edgeflag = 0; /* will get overwritten later */ dst->pad = 0; dst->vertex_id = UNDEFINED_VERTEX_ID; } @@ -162,45 +162,39 @@ static void emit_poly( struct draw_stage *stage, struct prim_header header; unsigned i; + const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; + const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; + const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; + /* later stages may need the determinant, but only the sign matters */ header.det = origPrim->det; + header.flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; + header.pad = 0; - for (i = 2; i < n; i++) { + for (i = 2; i < n; i++, header.flags = 0) { header.v[0] = inlist[i-1]; header.v[1] = inlist[i]; header.v[2] = inlist[0]; /* keep in v[2] for flatshading */ - - { - unsigned tmp1 = header.v[1]->edgeflag; - unsigned tmp2 = header.v[2]->edgeflag; - - if (i != n-1) header.v[1]->edgeflag = 0; - if (i != 2) header.v[2]->edgeflag = 0; - - header.edgeflags = ((header.v[0]->edgeflag << 0) | - (header.v[1]->edgeflag << 1) | - (header.v[2]->edgeflag << 2)); - - if (0) { - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; - uint j, k; - debug_printf("Clipped tri:\n"); - for (j = 0; j < 3; j++) { - for (k = 0; k < vs->info.num_outputs; k++) { - debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, - header.v[j]->data[k][0], - header.v[j]->data[k][1], - header.v[j]->data[k][2], - header.v[j]->data[k][3]); - } + + if (i == n-1) + header.flags |= edge_last; + + if (0) { + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + uint j, k; + debug_printf("Clipped tri:\n"); + for (j = 0; j < 3; j++) { + for (k = 0; k < vs->info.num_outputs; k++) { + debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, + header.v[j]->data[k][0], + header.v[j]->data[k][1], + header.v[j]->data[k][2], + header.v[j]->data[k][3]); } } - - stage->next->tri( stage->next, &header ); - - header.v[1]->edgeflag = tmp1; - header.v[2]->edgeflag = tmp2; } + + stage->next->tri( stage->next, &header ); } } diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c index 205000cbea..09b68c4559 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -91,7 +91,8 @@ static void flatshade_tri_0( struct draw_stage *stage, struct prim_header tmp; tmp.det = header->det; - tmp.edgeflags = header->edgeflags; + tmp.flags = header->flags; + tmp.pad = header->pad; tmp.v[0] = header->v[0]; tmp.v[1] = dup_vert(stage, header->v[1], 0); tmp.v[2] = dup_vert(stage, header->v[2], 1); @@ -108,7 +109,8 @@ static void flatshade_tri_2( struct draw_stage *stage, struct prim_header tmp; tmp.det = header->det; - tmp.edgeflags = header->edgeflags; + tmp.flags = header->flags; + tmp.pad = header->pad; tmp.v[0] = dup_vert(stage, header->v[0], 0); tmp.v[1] = dup_vert(stage, header->v[1], 1); tmp.v[2] = header->v[2]; diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index ffec85ccdd..ea6de8c571 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -106,7 +106,8 @@ static void offset_tri( struct draw_stage *stage, struct prim_header tmp; tmp.det = header->det; - tmp.edgeflags = header->edgeflags; + tmp.flags = header->flags; + tmp.pad = header->pad; tmp.v[0] = dup_vert(stage, header->v[0], 0); tmp.v[1] = dup_vert(stage, header->v[1], 1); tmp.v[2] = dup_vert(stage, header->v[2], 2); diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c index 9cf5840cce..3cbced362e 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c @@ -135,6 +135,10 @@ stipple_line(struct draw_stage *stage, struct prim_header *header) float length = MAX2(dx, dy); int i; + if (header->flags & DRAW_PIPE_RESET_STIPPLE) + stipple->counter = 0; + + /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table. */ for (i = 0; i < length; i++) { diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c index 5910dccc43..50872fdbe9 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -85,7 +85,8 @@ static void twoside_tri( struct draw_stage *stage, struct prim_header tmp; tmp.det = header->det; - tmp.edgeflags = header->edgeflags; + tmp.flags = header->flags; + tmp.pad = header->pad; /* copy back attribs to front attribs */ tmp.v[0] = copy_bfc(twoside, header->v[0], 0); tmp.v[1] = copy_bfc(twoside, header->v[1], 1); diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c index eeb2bc43f9..8f97fdedaa 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -83,9 +83,9 @@ static void points( struct draw_stage *stage, struct vertex_header *v1 = header->v[1]; struct vertex_header *v2 = header->v[2]; - if (header->edgeflags & 0x1) point( stage, v0 ); - if (header->edgeflags & 0x2) point( stage, v1 ); - if (header->edgeflags & 0x4) point( stage, v2 ); + if ((header->flags & DRAW_PIPE_EDGE_FLAG_0) && v0->edgeflag) point( stage, v0 ); + if ((header->flags & DRAW_PIPE_EDGE_FLAG_1) && v1->edgeflag) point( stage, v1 ); + if ((header->flags & DRAW_PIPE_EDGE_FLAG_2) && v2->edgeflag) point( stage, v2 ); } @@ -96,22 +96,22 @@ static void lines( struct draw_stage *stage, struct vertex_header *v1 = header->v[1]; struct vertex_header *v2 = header->v[2]; -#if 0 - assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag); - assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag); - assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag); -#endif + if (header->flags & DRAW_PIPE_RESET_STIPPLE) + stage->next->reset_stipple_counter( stage->next ); - if (header->edgeflags & 0x4) line( stage, v2, v0 ); - if (header->edgeflags & 0x1) line( stage, v0, v1 ); - if (header->edgeflags & 0x2) line( stage, v1, v2 ); + if ((header->flags & DRAW_PIPE_EDGE_FLAG_2) && v2->edgeflag) line( stage, v2, v0 ); + if ((header->flags & DRAW_PIPE_EDGE_FLAG_0) && v0->edgeflag) line( stage, v0, v1 ); + if ((header->flags & DRAW_PIPE_EDGE_FLAG_1) && v1->edgeflag) line( stage, v1, v2 ); } /* Unfilled tri: * * Note edgeflags in the vertex struct is not sufficient as we will - * need to manipulate them when decomposing primitives??? + * need to manipulate them when decomposing primitives. + * + * We currently keep the vertex edgeflag and primitive edgeflag mask + * separate until the last possible moment. */ static void unfilled_tri( struct draw_stage *stage, struct prim_header *header ) diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index ca5021c5c6..49593c8fad 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -78,25 +78,6 @@ struct vertex_header { #define UNDEFINED_VERTEX_ID 0xffff -/** - * Basic info for a point/line/triangle primitive. - */ -struct prim_header { - float det; /**< front/back face determinant */ - unsigned reset_line_stipple:1; - unsigned edgeflags:3; - unsigned pad:28; - struct vertex_header *v[3]; /**< 1 to 3 vertex pointers */ -}; - - - - -#define PT_SHADE 0x1 -#define PT_CLIPTEST 0x2 -#define PT_PIPELINE 0x4 -#define PT_MAX_MIDDLE 0x8 - /** * Private context for the drawing module. */ @@ -238,6 +219,25 @@ void draw_pt_reset_vertex_ids( struct draw_context *draw ); boolean draw_pipeline_init( struct draw_context *draw ); void draw_pipeline_destroy( struct draw_context *draw ); + + + + +/* We use the top few bits in the elts[] parameter to convey a little + * API information. This limits the number of vertices we can address + * to only 4096 -- if that becomes a problem, we can switch to 32-bit + * draw indices. + * + * These flags expected at first vertex of lines & triangles when + * unfilled and/or line stipple modes are operational. + */ +#define DRAW_PIPE_EDGE_FLAG_0 (0x1<<12) +#define DRAW_PIPE_EDGE_FLAG_1 (0x2<<12) +#define DRAW_PIPE_EDGE_FLAG_2 (0x4<<12) +#define DRAW_PIPE_EDGE_FLAG_ALL (0x7<<12) +#define DRAW_PIPE_RESET_STIPPLE (0x8<<12) +#define DRAW_PIPE_FLAG_MASK (0xf<<12) + void draw_pipeline_run( struct draw_context *draw, unsigned prim, struct vertex_header *vertices, @@ -246,6 +246,8 @@ void draw_pipeline_run( struct draw_context *draw, const ushort *elts, unsigned count ); + + void draw_pipeline_flush( struct draw_context *draw, unsigned flags ); diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index fd0d158fcf..df5c29fc36 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -40,15 +40,6 @@ typedef unsigned (*pt_elt_func)( const void *elts, unsigned idx ); struct draw_pt_middle_end; struct draw_context; -/* We use the top couple of bits in the vertex fetch index to convey a - * little API information. This limits the number of vertices we can - * address to only 1 billion -- if that becomes a problem, these could - * be moved out & passed separately. - */ -#define DRAW_PT_EDGEFLAG (1<<30) -#define DRAW_PT_RESET_STIPPLE (1<<31) -#define DRAW_PT_FLAG_MASK (3<<30) - #define PT_SHADE 0x1 #define PT_CLIPTEST 0x2 diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index cc61b113fd..9f74806e11 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -41,6 +41,7 @@ struct pt_fetch { struct translate *translate; unsigned vertex_size; + boolean need_edgeflags; struct translate_cache *cache; }; @@ -121,6 +122,10 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, 0); } } + + fetch->need_edgeflags = ((draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) && + draw->pt.user.edgeflag); } @@ -147,6 +152,18 @@ void draw_pt_fetch_run( struct pt_fetch *fetch, elts, count, verts ); + + /* Edgeflags are hard to fit into a translate program, populate + * them separately if required. In the setup above they are + * defaulted to one, so only need this if there is reason to change + * that default: + */ + if (fetch->need_edgeflags) { + for (i = 0; i < count; i++) { + struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size); + vh->edgeflag = draw_pt_get_edgeflag( draw, elts[i] ); + } + } } diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 153055417d..b3133359e0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -33,8 +33,6 @@ #include "pipe/p_util.h" #include "draw/draw_context.h" #include "draw/draw_private.h" -//#include "draw/draw_vbuf.h" -//#include "draw/draw_vertex.h" #include "draw/draw_pt.h" @@ -86,8 +84,9 @@ static void vcache_check_flush( struct vcache_frontend *vcache ) } -static void vcache_elt( struct vcache_frontend *vcache, - unsigned felt ) +static INLINE void vcache_elt( struct vcache_frontend *vcache, + unsigned felt, + ushort flags ) { unsigned idx = felt % CACHE_MAX; @@ -99,28 +98,9 @@ static void vcache_elt( struct vcache_frontend *vcache, vcache->fetch_elts[vcache->fetch_count++] = felt; } - vcache->draw_elts[vcache->draw_count++] = vcache->out[idx]; + vcache->draw_elts[vcache->draw_count++] = vcache->out[idx] | flags; } -static unsigned add_edgeflag( struct vcache_frontend *vcache, - unsigned idx, - unsigned mask ) -{ - if (0 && mask && draw_pt_get_edgeflag(vcache->draw, idx)) - return idx | DRAW_PT_EDGEFLAG; - else - return idx; -} - - -static unsigned add_reset_stipple( unsigned idx, - unsigned reset ) -{ - if (0 && reset) - return idx | DRAW_PT_RESET_STIPPLE; - else - return idx; -} static void vcache_triangle( struct vcache_frontend *vcache, @@ -128,49 +108,42 @@ static void vcache_triangle( struct vcache_frontend *vcache, unsigned i1, unsigned i2 ) { - vcache_elt(vcache, i0 /* | DRAW_PT_EDGEFLAG | DRAW_PT_RESET_STIPPLE */ ); - vcache_elt(vcache, i1 /* | DRAW_PT_EDGEFLAG */); - vcache_elt(vcache, i2 /* | DRAW_PT_EDGEFLAG */); + vcache_elt(vcache, i0, 0); + vcache_elt(vcache, i1, 0); + vcache_elt(vcache, i2, 0); vcache_check_flush(vcache); } -static void vcache_ef_triangle( struct vcache_frontend *vcache, - boolean reset_stipple, - unsigned ef_mask, - unsigned i0, - unsigned i1, - unsigned i2 ) +static void vcache_triangle_flags( struct vcache_frontend *vcache, + ushort flags, + unsigned i0, + unsigned i1, + unsigned i2 ) { -/* - i0 = add_edgeflag( vcache, i0, (ef_mask >> 0) & 1 ); - i1 = add_edgeflag( vcache, i1, (ef_mask >> 1) & 1 ); - i2 = add_edgeflag( vcache, i2, (ef_mask >> 2) & 1 ); - i0 = add_reset_stipple( i0, reset_stipple ); -*/ - - vcache_elt(vcache, i0); - vcache_elt(vcache, i1); - vcache_elt(vcache, i2); + vcache_elt(vcache, i0, flags); + vcache_elt(vcache, i1, 0); + vcache_elt(vcache, i2, 0); vcache_check_flush(vcache); - - if (0) debug_printf("emit tri ef: %d %d %d\n", - !!(i0 & DRAW_PT_EDGEFLAG), - !!(i1 & DRAW_PT_EDGEFLAG), - !!(i2 & DRAW_PT_EDGEFLAG)); - } - static void vcache_line( struct vcache_frontend *vcache, - boolean reset_stipple, unsigned i0, unsigned i1 ) { - i0 = add_reset_stipple( i0, reset_stipple ); + vcache_elt(vcache, i0, 0); + vcache_elt(vcache, i1, 0); + vcache_check_flush(vcache); +} + - vcache_elt(vcache, i0); - vcache_elt(vcache, i1); +static void vcache_line_flags( struct vcache_frontend *vcache, + ushort flags, + unsigned i0, + unsigned i1 ) +{ + vcache_elt(vcache, i0, flags); + vcache_elt(vcache, i1, 0); vcache_check_flush(vcache); } @@ -178,7 +151,7 @@ static void vcache_line( struct vcache_frontend *vcache, static void vcache_point( struct vcache_frontend *vcache, unsigned i0 ) { - vcache_elt(vcache, i0); + vcache_elt(vcache, i0, 0); vcache_check_flush(vcache); } @@ -198,237 +171,36 @@ static void vcache_ef_quad( struct vcache_frontend *vcache, unsigned i2, unsigned i3 ) { - const unsigned omitEdge2 = ~(1 << 1); - const unsigned omitEdge3 = ~(1 << 2); - vcache_ef_triangle( vcache, 1, omitEdge2, i0, i1, i3 ); - vcache_ef_triangle( vcache, 0, omitEdge3, i1, i2, i3 ); -} + const unsigned omitEdge1 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_2; + const unsigned omitEdge2 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_1; + vcache_triangle_flags( vcache, + DRAW_PIPE_RESET_STIPPLE | omitEdge1, + i0, i1, i3 ); + vcache_triangle_flags( vcache, + omitEdge2, + i1, i2, i3 ); +} +/* At least for now, we're back to using a template include file for + * this. The two paths aren't too different though - it may be + * possible to reunify them. + */ +#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle_flags(vc,flags,i0,i1,i2) +#define QUAD(vc,i0,i1,i2,i3) vcache_ef_quad(vc,i0,i1,i2,i3) +#define LINE(vc,flags,i0,i1) vcache_line_flags(vc,flags,i0,i1) +#define POINT(vc,i0) vcache_point(vc,i0) +#define FUNC vcache_run_extras +#include "draw_pt_vcache_tmp.h" + +#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle(vc,i0,i1,i2) +#define QUAD(vc,i0,i1,i2,i3) vcache_quad(vc,i0,i1,i2,i3) +#define LINE(vc,flags,i0,i1) vcache_line(vc,i0,i1) +#define POINT(vc,i0) vcache_point(vc,i0) +#define FUNC vcache_run +#include "draw_pt_vcache_tmp.h" -static void vcache_run( struct draw_pt_front_end *frontend, - pt_elt_func get_elt, - const void *elts, - unsigned count ) -{ - struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; - struct draw_context *draw = vcache->draw; - - boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL); - - boolean flatfirst = (draw->rasterizer->flatshade && - draw->rasterizer->flatshade_first); - unsigned i; - -// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count ); - - switch (vcache->input_prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i ++) { - vcache_point( vcache, - get_elt(elts, i + 0) ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - vcache_line( vcache, - TRUE, - get_elt(elts, i + 0), - get_elt(elts, i + 1)); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - for (i = 1; i < count; i++) { - vcache_line( vcache, - i == 1, /* XXX: only if vb not split */ - get_elt(elts, i - 1), - get_elt(elts, i )); - } - - vcache_line( vcache, - 0, - get_elt(elts, count - 1), - get_elt(elts, 0 )); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < count; i++) { - vcache_line( vcache, - i == 1, - get_elt(elts, i - 1), - get_elt(elts, i )); - } - break; - - case PIPE_PRIM_TRIANGLES: - if (unfilled) { - for (i = 0; i+2 < count; i += 3) { - vcache_ef_triangle( vcache, - 1, - ~0, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2 )); - } - } - else { - for (i = 0; i+2 < count; i += 3) { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2 )); - } - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - if (i & 1) { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 2), - get_elt(elts, i + 1 )); - } - else { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2 )); - } - } - } - else { - for (i = 0; i+2 < count; i++) { - if (i & 1) { - vcache_triangle( vcache, - get_elt(elts, i + 1), - get_elt(elts, i + 0), - get_elt(elts, i + 2 )); - } - else { - vcache_triangle( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2 )); - } - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - vcache_triangle( vcache, - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, 0 )); - } - } - else { - for (i = 0; i+2 < count; i++) { - vcache_triangle( vcache, - get_elt(elts, 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2 )); - } - } - } - break; - - - case PIPE_PRIM_QUADS: - if (unfilled) { - for (i = 0; i+3 < count; i += 4) { - vcache_ef_quad( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, i + 3)); - } - } - else { - for (i = 0; i+3 < count; i += 4) { - vcache_quad( vcache, - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, i + 3)); - } - } - break; - - case PIPE_PRIM_QUAD_STRIP: - if (unfilled) { - for (i = 0; i+3 < count; i += 2) { - vcache_ef_quad( vcache, - get_elt(elts, i + 2), - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 3)); - } - } - else { - for (i = 0; i+3 < count; i += 2) { - vcache_quad( vcache, - get_elt(elts, i + 2), - get_elt(elts, i + 0), - get_elt(elts, i + 1), - get_elt(elts, i + 3)); - } - } - break; - - case PIPE_PRIM_POLYGON: - if (unfilled) { - /* These bitflags look a little odd because we submit the - * vertices as (1,2,0) to satisfy flatshade requirements. - */ - const unsigned edge_first = (1<<2); - const unsigned edge_middle = (1<<0); - const unsigned edge_last = (1<<1); - - for (i = 0; i+2 < count; i++) { - unsigned ef_mask = edge_middle; - - if (i == 0) - ef_mask |= edge_first; - - if (i + 3 == count) - ef_mask |= edge_last; - - vcache_ef_triangle( vcache, - i == 0, - ef_mask, - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, 0)); - } - } - else { - for (i = 0; i+2 < count; i++) { - vcache_triangle( vcache, - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, 0)); - } - } - break; - - default: - assert(0); - break; - } - - vcache_flush( vcache ); -} @@ -453,15 +225,21 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, unsigned opt ) { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; + const struct pipe_rasterizer_state *rasterizer = vcache->draw->rasterizer; + -/* - if (vcache->draw->rasterizer->flatshade_first) - vcache->base.run = vcache_run_pv0; - else - vcache->base.run = vcache_run_pv2; -*/ + if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL || + rasterizer->line_stipple_enable) + { + assert(opt & PT_PIPELINE); + vcache->base.run = vcache_run_extras; + } + else + { + vcache->base.run = vcache_run; + } - vcache->base.run = vcache_run; vcache->input_prim = prim; vcache->output_prim = reduced_prim[prim]; diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h new file mode 100644 index 0000000000..cf9f394aa3 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h @@ -0,0 +1,174 @@ + + +static void FUNC( struct draw_pt_front_end *frontend, + pt_elt_func get_elt, + const void *elts, + unsigned count ) +{ + struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; + struct draw_context *draw = vcache->draw; + + boolean flatfirst = (draw->rasterizer->flatshade && + draw->rasterizer->flatshade_first); + unsigned i, flags; + + + switch (vcache->input_prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i ++) { + POINT( vcache, + get_elt(elts, i + 0) ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) { + LINE( vcache, + DRAW_PIPE_RESET_STIPPLE, + get_elt(elts, i + 0), + get_elt(elts, i + 1)); + } + break; + + case PIPE_PRIM_LINE_LOOP: + if (count >= 2) { + flags = DRAW_PIPE_RESET_STIPPLE; + + for (i = 1; i < count; i++, flags = 0) { + LINE( vcache, + flags, + get_elt(elts, i - 1), + get_elt(elts, i )); + } + + LINE( vcache, + flags, + get_elt(elts, i - 1), + get_elt(elts, 0 )); + } + break; + + case PIPE_PRIM_LINE_STRIP: + flags = DRAW_PIPE_RESET_STIPPLE; + for (i = 1; i < count; i++, flags = 0) { + LINE( vcache, + flags, + get_elt(elts, i - 1), + get_elt(elts, i )); + } + break; + + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) { + TRIANGLE( vcache, + DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + TRIANGLE( vcache, + DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + get_elt(elts, i + 0), + get_elt(elts, i + 1 + (i&1)), + get_elt(elts, i + 2 - (i&1))); + } + } + else { + for (i = 0; i+2 < count; i++) { + TRIANGLE( vcache, + DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + get_elt(elts, i + 0 + (i&1)), + get_elt(elts, i + 1 - (i&1)), + get_elt(elts, i + 2 )); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (count >= 3) { + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + TRIANGLE( vcache, + DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0 )); + } + } + else { + for (i = 0; i+2 < count; i++) { + TRIANGLE( vcache, + DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + get_elt(elts, 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } + } + } + break; + + + case PIPE_PRIM_QUADS: + for (i = 0; i+3 < count; i += 4) { + QUAD( vcache, + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, i + 3)); + } + break; + + case PIPE_PRIM_QUAD_STRIP: + for (i = 0; i+3 < count; i += 2) { + QUAD( vcache, + get_elt(elts, i + 2), + get_elt(elts, i + 0), + get_elt(elts, i + 1), + get_elt(elts, i + 3)); + } + break; + + case PIPE_PRIM_POLYGON: + { + /* These bitflags look a little odd because we submit the + * vertices as (1,2,0) to satisfy flatshade requirements. + */ + const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2; + const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0; + const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1; + + flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; + + for (i = 0; i+2 < count; i++, flags = edge_middle) { + + if (i + 3 == count) + flags |= edge_last; + + TRIANGLE( vcache, + flags, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0)); + } + } + break; + + default: + assert(0); + break; + } + + vcache_flush( vcache ); +} + + +#undef TRIANGLE +#undef QUAD +#undef POINT +#undef LINE +#undef FUNC -- cgit v1.2.3 From d712eea074303812b1be0e79b302d7b9f49a09a8 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 24 Apr 2008 14:05:39 +0200 Subject: translate: Actually return a value from translate_cache_create(). --- src/gallium/auxiliary/translate/translate_cache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate_cache.c b/src/gallium/auxiliary/translate/translate_cache.c index c14f37c42f..e91d648eba 100644 --- a/src/gallium/auxiliary/translate/translate_cache.c +++ b/src/gallium/auxiliary/translate/translate_cache.c @@ -40,6 +40,7 @@ struct translate_cache * translate_cache_create() { struct translate_cache *cache = MALLOC_STRUCT(translate_cache); cache->hash = cso_hash_create(); + return cache; } -- cgit v1.2.3 From cefa367b5d909f26d943101efb042562de778c5f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 24 Apr 2008 17:07:45 +0200 Subject: i915: Fix for wrong texture in texobj with VBUF --- src/gallium/drivers/i915simple/i915_state.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 24d31ad740..3d94b52366 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -549,6 +549,9 @@ static void i915_set_sampler_textures(struct pipe_context *pipe, !memcmp(i915->texture, texture, num * sizeof(struct pipe_texture *))) return; + /* Fixes wrong texture in texobj with VBUF */ + draw_flush(i915->draw); + for (i = 0; i < num; i++) pipe_texture_reference((struct pipe_texture **) &i915->texture[i], texture[i]); -- cgit v1.2.3 From 35dc003c6a0845a96934f9c222bd57bb62e0a62f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 24 Apr 2008 18:39:25 +0100 Subject: gallium: Make sure the size of non-existent storage components is set to 0. Before adding support for formats with unused storage components, the size of components swizzled to 0 or 1 was ignored, so this didn't matter. --- src/gallium/include/pipe/p_format.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 2ee6f100bf..94c2eeb62b 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -238,8 +238,8 @@ enum pipe_format { PIPE_FORMAT_A1R5G5B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 1, 5, 5, 5, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_A4R4G4B4_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_R5G6B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_RGB1, 5, 6, 5, 0, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_U_L8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte luminance */ - PIPE_FORMAT_U_A8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_000R, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha */ + PIPE_FORMAT_U_L8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte luminance */ + PIPE_FORMAT_U_A8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_000R, 0, 0, 0, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha */ PIPE_FORMAT_U_I8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRR, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte intensity */ PIPE_FORMAT_U_A8_L8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha, luminance */ PIPE_FORMAT_YCBCR = _PIPE_FORMAT_YCBCR( 0 ), @@ -313,7 +313,7 @@ enum pipe_format { PIPE_FORMAT_R8G8B8A8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R8G8B8X8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ), /* sRGB formats */ - PIPE_FORMAT_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), + PIPE_FORMAT_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB ), PIPE_FORMAT_A8_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), PIPE_FORMAT_R8G8B8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB ), PIPE_FORMAT_R8G8B8A8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), -- cgit v1.2.3 From f2c31257167f85df276322be1b8523064e8b66a9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Apr 2008 11:52:37 -0600 Subject: gallium: added cso_delete_vertex_fragment_shader() functions The state tracker now uses these functions to free shaders, rather than the pipe->delete_vs/fs-state() functions. Before, we could get in a situation where we free() a shader and happen to alloc() a new one at the same address. The cso_set_vertex/fragment_shader() function would no-op the state change since the pointers were the same. This led to problems elsewhere, of course. The new delete functions null-out the CSO's current shader pointers. --- src/gallium/auxiliary/cso_cache/cso_context.c | 17 +++++++++++++++++ src/gallium/auxiliary/cso_cache/cso_context.h | 6 ++++++ 2 files changed, 23 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index d246dff433..cfb91d31de 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -471,6 +471,8 @@ void cso_restore_rasterizer(struct cso_context *ctx) ctx->rasterizer_saved = NULL; } + + enum pipe_error cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle ) { @@ -481,6 +483,13 @@ enum pipe_error cso_set_fragment_shader_handle(struct cso_context *ctx, return PIPE_OK; } +void cso_delete_fragment_shader(struct cso_context *ctx, void *handle ) +{ + if (handle == ctx->fragment_shader) + ctx->pipe->bind_fs_state(ctx->pipe, NULL); + ctx->pipe->delete_fs_state(ctx->pipe, handle); + ctx->fragment_shader = NULL; +} /* Not really working: */ @@ -553,6 +562,14 @@ enum pipe_error cso_set_vertex_shader_handle(struct cso_context *ctx, return PIPE_OK; } +void cso_delete_vertex_shader(struct cso_context *ctx, void *handle ) +{ + if (handle == ctx->vertex_shader) + ctx->pipe->bind_vs_state(ctx->pipe, NULL); + ctx->pipe->delete_vs_state(ctx->pipe, handle); + ctx->vertex_shader = NULL; +} + /* Not really working: */ diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 0405944132..cb46f71d51 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -99,16 +99,22 @@ void cso_restore_sampler_textures( struct cso_context *cso ); */ enum pipe_error cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle ); +void cso_delete_fragment_shader(struct cso_context *ctx, void *handle ); +/* enum pipe_error cso_set_fragment_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); +*/ void cso_save_fragment_shader(struct cso_context *cso); void cso_restore_fragment_shader(struct cso_context *cso); enum pipe_error cso_set_vertex_shader_handle(struct cso_context *ctx, void *handle ); +void cso_delete_vertex_shader(struct cso_context *ctx, void *handle ); +/* enum pipe_error cso_set_vertex_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); +*/ void cso_save_vertex_shader(struct cso_context *cso); void cso_restore_vertex_shader(struct cso_context *cso); -- cgit v1.2.3 From ac79532a15a7109bf0fbd0e40a1ba8e65ed8c435 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Apr 2008 11:56:06 -0600 Subject: gallium: tweak the new shader delete funcs --- src/gallium/auxiliary/cso_cache/cso_context.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index cfb91d31de..febecbbbde 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -485,10 +485,12 @@ enum pipe_error cso_set_fragment_shader_handle(struct cso_context *ctx, void cso_delete_fragment_shader(struct cso_context *ctx, void *handle ) { - if (handle == ctx->fragment_shader) + if (handle == ctx->fragment_shader) { + /* unbind before deleting */ ctx->pipe->bind_fs_state(ctx->pipe, NULL); + ctx->fragment_shader = NULL; + } ctx->pipe->delete_fs_state(ctx->pipe, handle); - ctx->fragment_shader = NULL; } /* Not really working: @@ -564,10 +566,12 @@ enum pipe_error cso_set_vertex_shader_handle(struct cso_context *ctx, void cso_delete_vertex_shader(struct cso_context *ctx, void *handle ) { - if (handle == ctx->vertex_shader) + if (handle == ctx->vertex_shader) { + /* unbind before deleting */ ctx->pipe->bind_vs_state(ctx->pipe, NULL); + ctx->vertex_shader = NULL; + } ctx->pipe->delete_vs_state(ctx->pipe, handle); - ctx->vertex_shader = NULL; } -- cgit v1.2.3 From a41804909d5799cddfbf48a46524f78c736408d4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Apr 2008 11:59:22 -0600 Subject: gallium: minor clean-ups, comments --- src/gallium/auxiliary/cso_cache/cso_context.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index febecbbbde..8cf2313b7f 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -102,6 +102,10 @@ out: return NULL; } + +/** + * Prior to context destruction, this function unbinds all state objects. + */ static void cso_release_all( struct cso_context *ctx ) { unsigned i; @@ -115,10 +119,10 @@ static void cso_release_all( struct cso_context *ctx ) ctx->pipe->bind_vs_state( ctx->pipe, NULL ); } - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { pipe_texture_reference(&ctx->textures[i], NULL); - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) pipe_texture_reference(&ctx->textures_saved[i], NULL); + } if (ctx->cache) { cso_cache_delete( ctx->cache ); @@ -129,10 +133,10 @@ static void cso_release_all( struct cso_context *ctx ) void cso_destroy_context( struct cso_context *ctx ) { - if (ctx) + if (ctx) { cso_release_all( ctx ); - - FREE( ctx ); + FREE( ctx ); + } } -- cgit v1.2.3 From 386102c62a3315182ffbc6319351cb883234511a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Apr 2008 12:10:14 -0600 Subject: gallium: make cso_release_all() public --- src/gallium/auxiliary/cso_cache/cso_context.c | 4 ++-- src/gallium/auxiliary/cso_cache/cso_context.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 8cf2313b7f..b4609e999b 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -106,7 +106,7 @@ out: /** * Prior to context destruction, this function unbinds all state objects. */ -static void cso_release_all( struct cso_context *ctx ) +void cso_release_all( struct cso_context *ctx ) { unsigned i; @@ -134,7 +134,7 @@ static void cso_release_all( struct cso_context *ctx ) void cso_destroy_context( struct cso_context *ctx ) { if (ctx) { - cso_release_all( ctx ); + //cso_release_all( ctx ); FREE( ctx ); } } diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index cb46f71d51..b04e98bfa1 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -42,6 +42,8 @@ struct cso_context; struct cso_context *cso_create_context( struct pipe_context *pipe ); +void cso_release_all( struct cso_context *ctx ); + void cso_destroy_context( struct cso_context *cso ); -- cgit v1.2.3 From da8312a1cf73d0777d51c63148ee090a9acace8b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 24 Apr 2008 21:13:56 +0100 Subject: draw: default edgeflag should be one --- src/gallium/auxiliary/draw/draw_pt_fetch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 9f74806e11..1f765b73ad 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -115,7 +115,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, fetch->translate = translate_cache_find(fetch->cache, &key); { - static struct vertex_header vh = { 0, 0, 0, 0xffff }; + static struct vertex_header vh = { 0, 1, 0, 0xffff }; fetch->translate->set_buffer(fetch->translate, draw->pt.nr_vertex_buffers, &vh, -- cgit v1.2.3 From 909894e34ca5e575ce21005e38dc0b5e98e4bcd6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Apr 2008 15:58:46 -0600 Subject: gallium: comments --- src/gallium/auxiliary/draw/draw_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 1c9d8650e2..46afb0f41f 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -194,14 +194,14 @@ void draw_pipeline_run( struct draw_context *draw, case PIPE_PRIM_LINES: for (i = 0; i+1 < count; i += 2) do_line( draw, - elts[i+0], + elts[i+0], /* flags */ verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK), verts + stride * elts[i+1]); break; case PIPE_PRIM_TRIANGLES: for (i = 0; i+2 < count; i += 3) do_triangle( draw, - elts[i+0], + elts[i+0], /* flags */ verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK), verts + stride * elts[i+1], verts + stride * elts[i+2]); -- cgit v1.2.3 From 98165318621cd3e01919b2b9ff140ce7a4e12beb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Apr 2008 15:59:08 -0600 Subject: gallium: plug in softpipe_set_edgeflags() function --- src/gallium/drivers/softpipe/sp_context.c | 2 ++ src/gallium/drivers/softpipe/sp_draw_arrays.c | 9 +++++++++ src/gallium/drivers/softpipe/sp_state.h | 3 +++ 3 files changed, 14 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 200fb415ac..f2ce0fdc6e 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -178,6 +178,8 @@ softpipe_create( struct pipe_screen *screen, softpipe->pipe.draw_arrays = softpipe_draw_arrays; softpipe->pipe.draw_elements = softpipe_draw_elements; + softpipe->pipe.set_edgeflags = softpipe_set_edgeflags; + softpipe->pipe.clear = softpipe_clear; softpipe->pipe.flush = softpipe_flush; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 778291dded..6c58f9909d 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -170,3 +170,12 @@ softpipe_draw_elements(struct pipe_context *pipe, return TRUE; } + + +void +softpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags) +{ + struct softpipe_context *sp = softpipe_context(pipe); + draw_set_edgeflags(sp->draw, edgeflags); +} + diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 6e6501f5bc..45056502b8 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -171,6 +171,9 @@ boolean softpipe_draw_elements(struct pipe_context *pipe, unsigned indexSize, unsigned mode, unsigned start, unsigned count); +void +softpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags); + void softpipe_map_surfaces(struct softpipe_context *sp); -- cgit v1.2.3 From 2926e59e4ad604dedcb639b2961937841afcf005 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 24 Apr 2008 23:31:35 +0100 Subject: draw: remove old assignment of edgeflag value --- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index 65cb8ba701..c4a67c8289 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -112,7 +112,6 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, out->clip[3] = out->data[0][3]; out->vertex_id = 0xffff; - out->edgeflag = 1; out->clipmask = compute_clipmask_gl(out->clip, pvs->draw->plane, pvs->draw->nr_planes); -- cgit v1.2.3 From dacfef158943665fc0d11035867d14ff1f5db332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 25 Apr 2008 18:18:48 +0900 Subject: gallium: New configuration header. To abstract all those weird #ifdef (__???__) checks. It should typically be the first included header. --- src/gallium/include/pipe/p_compiler.h | 2 + src/gallium/include/pipe/p_config.h | 112 ++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 src/gallium/include/pipe/p_config.h (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index 91f3d2ac2d..a4b772bc4f 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -29,6 +29,8 @@ #define P_COMPILER_H +#include "p_config.h" + #include #include diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h new file mode 100644 index 0000000000..e44fafeae9 --- /dev/null +++ b/src/gallium/include/pipe/p_config.h @@ -0,0 +1,112 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Gallium configuration defines. + * + * This header file sets several defines based on the compiler, processor + * architecture, and operating system being used. These defines should be used + * throughout the code to facilitate porting to new platforms. It is likely that + * this file is auto-generated by an autoconf-like tool at some point, as some + * things cannot be determined by existing defines alone. + * + * @author José Fonseca + */ + +#ifndef P_CONFIG_H_ +#define P_CONFIG_H_ + + +/* + * Compiler + */ + +#if defined(__GNUC__) +#define PIPE_CC_GCC +#endif + +#if defined(_MSC_VER) || defined(__MSC__) +#define PIPE_CC_MSVC +#endif + +#if defined(__ICL) +#define PIPE_CC_ICL +#endif + + +/* + * Processor architecture + */ + +#if defined(_X86_) || defined(__i386__) || defined(__386__) || defined(i386) +#define PIPE_ARCH_X86 +#endif + +#if 0 /* FIXME */ +#define PIPE_ARCH_X86_64 +#endif + +#if 0 /* FIXME */ +#define PIPE_ARCH_PPC +#endif + + +/* + * Operating system + */ + +#if defined(__linux__) +#define PIPE_OS_LINUX +#endif + +#if defined(_WIN32) || defined(WIN32) +#define PIPE_OS_WINDOWS +#endif + + +/* + * Subsystem + * + * XXX: There is no way to autodetect this. + */ + +#if defined(PIPE_OS_LINUX) +#define PIPE_SUBSYSTEM_DRI +#endif + +#if defined(PIPE_OS_WINDOWS) +#if !defined(PIPE_SUBSYSTEM_USER) && !defined(PIPE_SUBSYSTEM_KERNEL) +#error Neither PIPE_SUBSYSTEM_USER or PIPE_SUBSYSTEM_KERNEL defined. +#endif +#if defined(PIPE_SUBSYSTEM_KERNEL) +#define PIPE_SUBSYSTEM_WINDOWS_DISPLAY +#endif +#endif + + +#endif /* P_CONFIG_H_ */ -- cgit v1.2.3 From b06cd4debfc4fb4162b4b45e61ea91948de0a279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 25 Apr 2008 18:19:51 +0900 Subject: gallium: Windows user mode portability fixes. --- .../auxiliary/pipebuffer/pb_buffer_fenced.c | 11 ++++--- src/gallium/auxiliary/util/p_debug.c | 14 ++++---- src/gallium/auxiliary/util/p_debug_mem.c | 6 ++-- src/gallium/auxiliary/util/u_time.c | 38 ++++++++++++++-------- src/gallium/auxiliary/util/u_time.h | 8 +++-- src/gallium/include/pipe/p_util.h | 9 ++--- 6 files changed, 53 insertions(+), 33 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 27032b0c4c..d3c1ec4fbe 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -34,6 +34,12 @@ */ +#include "pipe/p_config.h" + +#if defined(PIPE_OS_LINUX) +#include +#endif + #include "pipe/p_compiler.h" #include "pipe/p_error.h" #include "pipe/p_debug.h" @@ -45,9 +51,6 @@ #include "pb_buffer.h" #include "pb_buffer_fenced.h" -#ifndef WIN32 -#include -#endif /** @@ -425,7 +428,7 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list) /* Wait on outstanding fences */ while (fenced_list->numDelayed) { _glthread_UNLOCK_MUTEX(fenced_list->mutex); -#ifndef WIN32 +#if defined(PIPE_OS_LINUX) sched_yield(); #endif _fenced_buffer_list_check_free(fenced_list, 1); diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 25b132b40c..cd612e23b3 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -26,9 +26,11 @@ **************************************************************************/ +#include "pipe/p_config.h" + #include -#ifdef WIN32 +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY #include #include #else @@ -42,7 +44,7 @@ #include "util/u_string.h" -#ifdef WIN32 +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY static INLINE void _EngDebugPrint(const char *format, ...) { @@ -56,7 +58,7 @@ _EngDebugPrint(const char *format, ...) void _debug_vprintf(const char *format, va_list ap) { -#ifdef WIN32 +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY #ifndef WINCE /* EngDebugPrint does not handle float point arguments, so we need to use * our own vsnprintf implementation. It is also very slow, so buffer until @@ -101,7 +103,7 @@ void _debug_break(void) __asm("int3"); #elif (defined(__i386__) || defined(__386__)) && defined(__MSC__) _asm {int 3}; -#elif defined(WIN32) && !defined(WINCE) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && !defined(WINCE) EngDebugBreak(); #else abort(); @@ -109,7 +111,7 @@ void _debug_break(void) } -#ifdef WIN32 +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY static const char * find(const char *start, const char *end, char c) { @@ -150,7 +152,7 @@ const char * debug_get_option(const char *name, const char *dfault) { const char *result; -#ifdef WIN32 +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY ULONG_PTR iFile = 0; const void *pMap = NULL; const char *sol, *eol, *sep; diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c index aba69c0294..9321cf71bb 100644 --- a/src/gallium/auxiliary/util/p_debug_mem.c +++ b/src/gallium/auxiliary/util/p_debug_mem.c @@ -32,7 +32,9 @@ * @author José Fonseca */ -#ifdef WIN32 +#include "pipe/p_config.h" + +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY #include #include #else @@ -47,7 +49,7 @@ #define DEBUG_MEMORY_MAGIC 0x6e34090aU -#if defined(WIN32) && !defined(WINCE) +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && !defined(WINCE) #define real_malloc(_size) EngAllocMem(0, _size, 'D3AG') #define real_free(_ptr) EngFreeMem(_ptr) #else diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c index 01112ebe5a..dd28ff4134 100644 --- a/src/gallium/auxiliary/util/u_time.c +++ b/src/gallium/auxiliary/util/u_time.c @@ -33,27 +33,35 @@ */ -#ifndef WIN32 +#include "util/u_time.h" + +#if defined(PIPE_OS_LINUX) #include -#else +#elif defined(PIPE_OS_WINDOWS) #include +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) #include #endif - -#include "util/u_time.h" +#else +#error Unsupported OS +#endif -#ifdef WIN32 +#if defined(PIPE_OS_WINDOWS) static LONGLONG frequency = 0; +#if !defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) +#define EngQueryPerformanceFrequency(p) QueryPerformanceFrequency((LARGE_INTEGER*)(p)) +#define EngQueryPerformanceCounter(p) QueryPerformanceCounter((LARGE_INTEGER*)(p)) +#endif #endif void util_time_get(struct util_time *t) { -#ifndef WIN32 +#if defined(PIPE_OS_LINUX) gettimeofday(&t->tv, NULL); -#else +#elif defined(PIPE_OS_WINDOWS) EngQueryPerformanceCounter(&t->counter); #endif } @@ -64,10 +72,10 @@ util_time_add(const struct util_time *t1, int64_t usecs, struct util_time *t2) { -#ifndef WIN32 +#if defined(PIPE_OS_LINUX) t2->tv.tv_sec = t1->tv.tv_sec + usecs / 1000000; t2->tv.tv_usec = t1->tv.tv_usec + usecs % 1000000; -#else +#elif defined(PIPE_OS_WINDOWS) if(!frequency) EngQueryPerformanceFrequency(&frequency); t2->counter = t1->counter + (usecs * frequency + 999999LL)/1000000LL; @@ -79,10 +87,12 @@ int64_t util_time_diff(const struct util_time *t1, const struct util_time *t2) { -#ifndef WIN32 +#if defined(PIPE_OS_LINUX) return (t2->tv.tv_usec - t1->tv.tv_usec) + (t2->tv.tv_sec - t1->tv.tv_sec)*1000000; -#else +#elif defined(PIPE_OS_WINDOWS) + if(!frequency) + EngQueryPerformanceFrequency(&frequency); return (t2->counter - t1->counter)*1000000LL/frequency; #endif } @@ -98,7 +108,7 @@ static INLINE int util_time_compare(const struct util_time *t1, const struct util_time *t2) { -#ifndef WIN32 +#if defined(PIPE_OS_LINUX) if (t1->tv.tv_sec < t2->tv.tv_sec) return -1; else if(t1->tv.tv_sec > t2->tv.tv_sec) @@ -109,7 +119,7 @@ util_time_compare(const struct util_time *t1, return 1; else return 0; -#else +#elif defined(PIPE_OS_WINDOWS) if (t1->counter < t2->counter) return -1; else if(t1->counter > t2->counter) @@ -132,7 +142,7 @@ util_time_timeout(const struct util_time *start, } -#ifdef WIN32 +#if defined(PIPE_OS_WINDOWS) void util_time_sleep(unsigned usecs) { LONGLONG start, curr, end; diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h index c8836c137f..48ec7a4a96 100644 --- a/src/gallium/auxiliary/util/u_time.h +++ b/src/gallium/auxiliary/util/u_time.h @@ -36,7 +36,9 @@ #define U_TIME_H_ -#ifndef WIN32 +#include "pipe/p_config.h" + +#if defined(PIPE_OS_LINUX) #include /* timeval */ #include /* usleep */ #endif @@ -56,7 +58,7 @@ extern "C" { */ struct util_time { -#ifndef WIN32 +#if defined(PIPE_OS_LINUX) struct timeval tv; #else long long counter; @@ -84,7 +86,7 @@ util_time_timeout(const struct util_time *start, const struct util_time *end, const struct util_time *curr); -#ifndef WIN32 +#if defined(PIPE_OS_LINUX) #define util_time_sleep usleep #else void diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 43d94ec4ba..63301ae3aa 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -28,6 +28,7 @@ #ifndef P_UTIL_H #define P_UTIL_H +#include "p_config.h" #include "p_compiler.h" #include "p_debug.h" #include "p_pointer.h" @@ -40,7 +41,7 @@ extern "C" { #endif -#if defined(WIN32) && defined(DEBUG) /* memory debugging */ +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && defined(DEBUG) /* memory debugging */ #include "p_debug.h" @@ -55,7 +56,7 @@ extern "C" { #else -#ifdef WIN32 +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) void * __stdcall EngAllocMem( @@ -118,7 +119,7 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) return new_ptr; } -#else /* !WIN32 */ +#else /* !PIPE_SUBSYSTEM_WINDOWS_DISPLAY */ #define MALLOC( SIZE ) malloc( SIZE ) @@ -128,7 +129,7 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define REALLOC( OLDPTR, OLDSIZE, NEWSIZE ) realloc( OLDPTR, NEWSIZE ) -#endif /* !WIN32 */ +#endif /* !PIPE_SUBSYSTEM_WINDOWS_DISPLAY */ #endif /* !DEBUG */ #define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T)) -- cgit v1.2.3 From 992d0b997f8f7e965e56852b81e01c290f8c13de Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 24 Apr 2008 16:22:47 -0400 Subject: frontend for rendering without elts --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_private.h | 1 + src/gallium/auxiliary/draw/draw_pt.c | 30 ++- src/gallium/auxiliary/draw/draw_pt.h | 1 + src/gallium/auxiliary/draw/draw_pt_varray.c | 251 ++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 144 ++++++++++++++ 6 files changed, 421 insertions(+), 7 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_varray.c create mode 100644 src/gallium/auxiliary/draw/draw_pt_varray_tmp.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index bc6acfe458..da7eded21f 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -28,6 +28,7 @@ C_SOURCES = \ draw_pt_fetch_emit.c \ draw_pt_fetch_shade_pipeline.c \ draw_pt_post_vs.c \ + draw_pt_varray.c \ draw_pt_vcache.c \ draw_vertex.c \ draw_vs.c \ diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 49593c8fad..cee58bbf73 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -129,6 +129,7 @@ struct draw_context struct { struct draw_pt_front_end *vcache; + struct draw_pt_front_end *varray; } front; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index f5a3bf390e..d6585bbfd0 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -53,12 +53,14 @@ draw_pt_arrays(struct draw_context *draw, struct draw_pt_front_end *frontend = NULL; struct draw_pt_middle_end *middle = NULL; unsigned opt = 0; + pt_elt_func get_elt = 0; + void *elts = 0; if (!draw->render) { opt |= PT_PIPELINE; } - if (draw_need_pipeline(draw, + if (draw_need_pipeline(draw, draw->rasterizer, prim)) { opt |= PT_PIPELINE; @@ -78,16 +80,21 @@ draw_pt_arrays(struct draw_context *draw, middle = draw->pt.middle.fetch_emit; - /* May create a short-circuited version of this for small primitives: + /* Pick the right frontend */ - frontend = draw->pt.front.vcache; + if (draw->pt.user.elts || + count >= 256) { + frontend = draw->pt.front.vcache; + get_elt = draw_pt_elt_func(draw); + elts = draw_pt_elt_ptr(draw, start); + } else { + frontend = draw->pt.front.varray; + elts = start; + } frontend->prepare( frontend, prim, middle, opt ); - frontend->run( frontend, - draw_pt_elt_func( draw ), - draw_pt_elt_ptr( draw, start ), - count ); + frontend->run(frontend, get_elt, elts, count); frontend->finish( frontend ); @@ -101,6 +108,10 @@ boolean draw_pt_init( struct draw_context *draw ) if (!draw->pt.front.vcache) return FALSE; + draw->pt.front.varray = draw_pt_varray(draw); + if (!draw->pt.front.varray) + return FALSE; + draw->pt.middle.fetch_emit = draw_pt_fetch_emit( draw ); if (!draw->pt.middle.fetch_emit) return FALSE; @@ -129,6 +140,11 @@ void draw_pt_destroy( struct draw_context *draw ) draw->pt.front.vcache->destroy( draw->pt.front.vcache ); draw->pt.front.vcache = NULL; } + + if (draw->pt.front.varray) { + draw->pt.front.varray->destroy( draw->pt.front.varray ); + draw->pt.front.varray = NULL; + } } diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index df5c29fc36..2dec376cee 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -115,6 +115,7 @@ const void *draw_pt_elt_ptr( struct draw_context *draw, * a special case for tiny vertex buffers. */ struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ); +struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw); /* Middle-ends: * diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c new file mode 100644 index 0000000000..022098a314 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -0,0 +1,251 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_pt.h" + +#define FETCH_MAX 256 +#define DRAW_MAX (16*FETCH_MAX) + +struct varray_frontend { + struct draw_pt_front_end base; + struct draw_context *draw; + + ushort draw_elts[DRAW_MAX]; + unsigned fetch_elts[FETCH_MAX]; + + unsigned draw_count; + unsigned fetch_count; + + struct draw_pt_middle_end *middle; + + unsigned input_prim; + unsigned output_prim; +}; + +static void varray_flush(struct varray_frontend *varray) +{ + if (varray->draw_count) { +#if 0 + debug_printf("FLUSH fc = %d, dc = %d\n", + varray->fetch_count, + varray->draw_count); +#endif + varray->middle->run(varray->middle, + varray->fetch_elts, + varray->fetch_count, + varray->draw_elts, + varray->draw_count); + } + + varray->fetch_count = 0; + varray->draw_count = 0; +} + +#if 0 +static void varray_check_flush(struct varray_frontend *varray) +{ + if (varray->draw_count + 6 >= DRAW_MAX/* || + varray->fetch_count + 4 >= FETCH_MAX*/) { + varray_flush(varray); + } +} +#endif + +static INLINE void add_draw_el(struct varray_frontend *varray, + int idx, ushort flags) +{ + varray->draw_elts[varray->draw_count++] = idx | flags; +} + + +static INLINE void varray_triangle( struct varray_frontend *varray, + unsigned i0, + unsigned i1, + unsigned i2 ) +{ + add_draw_el(varray, i0, 0); + add_draw_el(varray, i1, 0); + add_draw_el(varray, i2, 0); +} + +static INLINE void varray_triangle_flags( struct varray_frontend *varray, + ushort flags, + unsigned i0, + unsigned i1, + unsigned i2 ) +{ + add_draw_el(varray, i0, flags); + add_draw_el(varray, i1, 0); + add_draw_el(varray, i2, 0); +} + +static INLINE void varray_line( struct varray_frontend *varray, + unsigned i0, + unsigned i1 ) +{ + add_draw_el(varray, i0, 0); + add_draw_el(varray, i1, 0); +} + + +static INLINE void varray_line_flags( struct varray_frontend *varray, + ushort flags, + unsigned i0, + unsigned i1 ) +{ + add_draw_el(varray, i0, flags); + add_draw_el(varray, i1, 0); +} + + +static INLINE void varray_point( struct varray_frontend *varray, + unsigned i0 ) +{ + add_draw_el(varray, i0, 0); +} + +static INLINE void varray_quad( struct varray_frontend *varray, + unsigned i0, + unsigned i1, + unsigned i2, + unsigned i3 ) +{ + varray_triangle( varray, i0, i1, i3 ); + varray_triangle( varray, i1, i2, i3 ); +} + +static INLINE void varray_ef_quad( struct varray_frontend *varray, + unsigned i0, + unsigned i1, + unsigned i2, + unsigned i3 ) +{ + const unsigned omitEdge1 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_2; + const unsigned omitEdge2 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_1; + + varray_triangle_flags( varray, + DRAW_PIPE_RESET_STIPPLE | omitEdge1, + i0, i1, i3 ); + + varray_triangle_flags( varray, + omitEdge2, + i1, i2, i3 ); +} + +/* At least for now, we're back to using a template include file for + * this. The two paths aren't too different though - it may be + * possible to reunify them. + */ +#define TRIANGLE(vc,flags,i0,i1,i2) varray_triangle_flags(vc,flags,i0,i1,i2) +#define QUAD(vc,i0,i1,i2,i3) varray_ef_quad(vc,i0,i1,i2,i3) +#define LINE(vc,flags,i0,i1) varray_line_flags(vc,flags,i0,i1) +#define POINT(vc,i0) varray_point(vc,i0) +#define FUNC varray_run_extras +#include "draw_pt_varray_tmp.h" + +#define TRIANGLE(vc,flags,i0,i1,i2) varray_triangle(vc,i0,i1,i2) +#define QUAD(vc,i0,i1,i2,i3) varray_quad(vc,i0,i1,i2,i3) +#define LINE(vc,flags,i0,i1) varray_line(vc,i0,i1) +#define POINT(vc,i0) varray_point(vc,i0) +#define FUNC varray_run +#include "draw_pt_varray_tmp.h" + + + +static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { + PIPE_PRIM_POINTS, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES +}; + + + +static void varray_prepare(struct draw_pt_front_end *frontend, + unsigned prim, + struct draw_pt_middle_end *middle, + unsigned opt) +{ + struct varray_frontend *varray = (struct varray_frontend *)frontend; + const struct pipe_rasterizer_state *rasterizer = varray->draw->rasterizer; + + if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL || + rasterizer->line_stipple_enable) + { + assert(opt & PT_PIPELINE); + varray->base.run = varray_run_extras; + } else { + varray->base.run = varray_run; + } + + varray->input_prim = prim; + varray->output_prim = reduced_prim[prim]; + + varray->middle = middle; + middle->prepare(middle, varray->output_prim, opt); +} + + + + +static void varray_finish(struct draw_pt_front_end *frontend) +{ + struct varray_frontend *varray = (struct varray_frontend *)frontend; + varray->middle->finish(varray->middle); + varray->middle = NULL; +} + +static void varray_destroy(struct draw_pt_front_end *frontend) +{ + FREE(frontend); +} + + +struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw) +{ + struct varray_frontend *varray = CALLOC_STRUCT(varray_frontend); + if (varray == NULL) + return NULL; + + varray->base.prepare = varray_prepare; + varray->base.run = NULL; + varray->base.finish = varray_finish; + varray->base.destroy = varray_destroy; + varray->draw = draw; + + return &varray->base; +} diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h new file mode 100644 index 0000000000..b9a319b253 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -0,0 +1,144 @@ + +static void FUNC(struct draw_pt_front_end *frontend, + pt_elt_func get_elt, + const void *elts, + unsigned count) +{ + struct varray_frontend *varray = (struct varray_frontend *)frontend; + struct draw_context *draw = varray->draw; + unsigned start = (unsigned)elts; + + boolean flatfirst = (draw->rasterizer->flatshade && + draw->rasterizer->flatshade_first); + unsigned i, flags; + +#if 0 + debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count); +#endif +#if 0 + debug_printf("INPUT PRIM = %d (start = %d, count = %d)\n", varray->input_prim, + start, count); +#endif + + for (i = 0; i < count; ++i) { + varray->fetch_elts[i] = start + i; + } + varray->fetch_count = count; + + switch (varray->input_prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i ++) { + POINT(varray, i + 0); + } + break; + + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) { + LINE(varray, DRAW_PIPE_RESET_STIPPLE, + i + 0, i + 1); + } + break; + + case PIPE_PRIM_LINE_LOOP: + if (count >= 2) { + flags = DRAW_PIPE_RESET_STIPPLE; + + for (i = 1; i < count; i++, flags = 0) { + LINE(varray, flags, i - 1, i); + } + LINE(varray, flags, i - 1, 0); + } + break; + + case PIPE_PRIM_LINE_STRIP: + flags = DRAW_PIPE_RESET_STIPPLE; + for (i = 1; i < count; i++, flags = 0) { + LINE(varray, flags, i - 1, i); + } + break; + + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) { + TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + i + 0, i + 1, i + 2); + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + i + 0, i + 1 + (i&1), i + 2 - (i&1)); + } + } + else { + for (i = 0; i+2 < count; i++) { + TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + i + 0 + (i&1), i + 1 - (i&1), i + 2); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (count >= 3) { + if (flatfirst) { + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + for (i = 0; i+2 < count; i++) { + TRIANGLE(varray, flags, i + 1, i + 2, 0); + } + } + else { + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + for (i = 0; i+2 < count; i++) { + TRIANGLE(varray, flags, 0, i + 1, i + 2); + } + } + } + break; + + case PIPE_PRIM_QUADS: + for (i = 0; i+3 < count; i += 4) { + QUAD(varray, i + 0, i + 1, i + 2, i + 3); + } + break; + + case PIPE_PRIM_QUAD_STRIP: + for (i = 0; i+3 < count; i += 2) { + QUAD(varray, i + 2, i + 0, i + 1, i + 3); + } + break; + + case PIPE_PRIM_POLYGON: + { + /* These bitflags look a little odd because we submit the + * vertices as (1,2,0) to satisfy flatshade requirements. + */ + const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2; + const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0; + const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1; + + flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; + + for (i = 0; i+2 < count; i++, flags = edge_middle) { + + if (i + 3 == count) + flags |= edge_last; + + TRIANGLE(varray, flags, i + 1, i + 2, 0); + } + } + break; + + default: + assert(0); + break; + } + + varray_flush(varray); +} + +#undef TRIANGLE +#undef QUAD +#undef POINT +#undef LINE +#undef FUNC -- cgit v1.2.3 From 4e46e6f52b88ca7df40a52cf994e6fe1e4b9870e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 25 Apr 2008 14:10:02 +0100 Subject: draw: remove unused vars --- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 2 -- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 2 -- 2 files changed, 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 0545dbc171..f05641dee6 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -815,7 +815,6 @@ aaline_bind_sampler_states(struct pipe_context *pipe, unsigned num, void **sampler) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - struct draw_context *draw = aaline->stage.draw; /* save current */ memcpy(aaline->state.sampler, sampler, num * sizeof(void *)); @@ -831,7 +830,6 @@ aaline_set_sampler_textures(struct pipe_context *pipe, unsigned num, struct pipe_texture **texture) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - struct draw_context *draw = aaline->stage.draw; uint i; /* save current */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index da303a13ad..d1d63d73be 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -667,7 +667,6 @@ pstip_set_sampler_textures(struct pipe_context *pipe, unsigned num, struct pipe_texture **texture) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - struct draw_context *draw = pstip->stage.draw; uint i; /* save current */ @@ -690,7 +689,6 @@ pstip_set_polygon_stipple(struct pipe_context *pipe, const struct pipe_poly_stipple *stipple) { struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - struct draw_context *draw = (struct draw_context *) pipe->draw; /* save current */ pstip->state.stipple = stipple; -- cgit v1.2.3 From 14cfcb18204233d3d4848ea8e579465983df3d75 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 25 Apr 2008 14:10:32 +0100 Subject: draw: no need to special-case elts/get_elts for varray frontend --- src/gallium/auxiliary/draw/draw_pt.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index d6585bbfd0..c9c5d18313 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -53,8 +53,6 @@ draw_pt_arrays(struct draw_context *draw, struct draw_pt_front_end *frontend = NULL; struct draw_pt_middle_end *middle = NULL; unsigned opt = 0; - pt_elt_func get_elt = 0; - void *elts = 0; if (!draw->render) { opt |= PT_PIPELINE; @@ -83,18 +81,18 @@ draw_pt_arrays(struct draw_context *draw, /* Pick the right frontend */ if (draw->pt.user.elts || - count >= 256) { + count >= 256) { frontend = draw->pt.front.vcache; - get_elt = draw_pt_elt_func(draw); - elts = draw_pt_elt_ptr(draw, start); } else { frontend = draw->pt.front.varray; - elts = start; } frontend->prepare( frontend, prim, middle, opt ); - frontend->run(frontend, get_elt, elts, count); + frontend->run(frontend, + draw_pt_elt_func(draw), + draw_pt_elt_ptr(draw, start), + count); frontend->finish( frontend ); -- cgit v1.2.3 From 2325d1959783aaf57178a86d8a0b28f168761e13 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 25 Apr 2008 14:20:02 +0100 Subject: tgsi: fix compile when HIGH_PRECISION not defined --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index c3295a27ff..559370e613 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -854,7 +854,7 @@ emit_rsqrt( /* On Intel CPUs at least, this is only accurate to 12 bits -- not * good enough. */ - emit_rsqrtps( + sse_rsqrtps( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); -- cgit v1.2.3 From 96cfd804f6dcc0ec9f5e887ff1b402a55886fb0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 25 Apr 2008 14:57:50 +0100 Subject: gallium: Add draw_pt_varray.c to scons build. --- src/gallium/auxiliary/draw/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 0b9852f633..3b5d5ed492 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -27,6 +27,7 @@ draw = env.ConvenienceLibrary( 'draw_pt_fetch_emit.c', 'draw_pt_fetch_shade_pipeline.c', 'draw_pt_post_vs.c', + 'draw_pt_varray.c', 'draw_pt_vcache.c', 'draw_vertex.c', 'draw_vs.c', -- cgit v1.2.3 From 1aedbf9efe4d1cf45be3c27fc3a0eb4a69a1b1b9 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 25 Apr 2008 16:16:06 +0100 Subject: draw: emit extra flags whenever pipeline is active The assert was in fact over-sensitive, but emitting the extra flags is pretty trivial & we may as well just do it whenever we know the pipeline is running. --- src/gallium/auxiliary/draw/draw_pt_varray.c | 9 ++++----- src/gallium/auxiliary/draw/draw_pt_vcache.c | 6 +----- 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index 022098a314..c85d8ded50 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -202,13 +202,12 @@ static void varray_prepare(struct draw_pt_front_end *frontend, struct varray_frontend *varray = (struct varray_frontend *)frontend; const struct pipe_rasterizer_state *rasterizer = varray->draw->rasterizer; - if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL || - rasterizer->line_stipple_enable) + if (opt & PT_PIPELINE) { - assert(opt & PT_PIPELINE); varray->base.run = varray_run_extras; - } else { + } + else + { varray->base.run = varray_run; } diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index b3133359e0..2f9775814f 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -227,12 +227,8 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; const struct pipe_rasterizer_state *rasterizer = vcache->draw->rasterizer; - - if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL || - rasterizer->line_stipple_enable) + if (opt & PT_PIPELINE) { - assert(opt & PT_PIPELINE); vcache->base.run = vcache_run_extras; } else -- cgit v1.2.3 From 5e3b0d227c1b009c88a1b79df4a9e8c632e356f9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 25 Apr 2008 15:55:47 -0600 Subject: gallium: tweak comments, minor var renaming --- src/gallium/include/pipe/p_winsys.h | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index bf5aad7351..3005ec2d94 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -63,13 +63,13 @@ struct pipe_surface; struct pipe_winsys { /** Returns name of this winsys interface */ - const char *(*get_name)( struct pipe_winsys *sws ); + const char *(*get_name)( struct pipe_winsys *ws ); /** * Do any special operations to ensure frontbuffer contents are * displayed, eg copy fake frontbuffer. */ - void (*flush_frontbuffer)( struct pipe_winsys *sws, + void (*flush_frontbuffer)( struct pipe_winsys *ws, struct pipe_surface *surf, void *context_private ); @@ -79,8 +79,8 @@ struct pipe_winsys /** * Allocate storage for a pipe_surface. - * Returns 0 if succeeds. - * XXX: flags is unused and will be removed someday. + * \param flags XXX unused, remove someday + * \return 0 if succeeds. */ int (*surface_alloc_storage)(struct pipe_winsys *ws, struct pipe_surface *surf, @@ -105,7 +105,7 @@ struct pipe_winsys * alignment indicates the client's alignment requirements, eg for * SSE instructions. */ - struct pipe_buffer *(*buffer_create)( struct pipe_winsys *sws, + struct pipe_buffer *(*buffer_create)( struct pipe_winsys *ws, unsigned alignment, unsigned usage, unsigned size ); @@ -131,7 +131,7 @@ struct pipe_winsys * Note that ptr may be accessed at any time upto the time when the * buffer is destroyed, so the data must not be freed before then. */ - struct pipe_buffer *(*user_buffer_create)(struct pipe_winsys *sws, + struct pipe_buffer *(*user_buffer_create)(struct pipe_winsys *ws, void *ptr, unsigned bytes); @@ -139,45 +139,40 @@ struct pipe_winsys * Map the entire data store of a buffer object into the client's address. * flags is bitmask of PIPE_BUFFER_USAGE_CPU_READ/WRITE flags. */ - void *(*buffer_map)( struct pipe_winsys *sws, + void *(*buffer_map)( struct pipe_winsys *ws, struct pipe_buffer *buf, unsigned usage ); - void (*buffer_unmap)( struct pipe_winsys *sws, + void (*buffer_unmap)( struct pipe_winsys *ws, struct pipe_buffer *buf ); - void (*buffer_destroy)( struct pipe_winsys *sws, + void (*buffer_destroy)( struct pipe_winsys *ws, struct pipe_buffer *buf ); /** Set ptr = fence, with reference counting */ - void (*fence_reference)( struct pipe_winsys *sws, + void (*fence_reference)( struct pipe_winsys *ws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence ); /** * Checks whether the fence has been signalled. - * - * The meaning of flag is pipe-driver specific. - * - * Returns zero if it has. + * \param flags driver-specific meaning + * \return zero on success. */ - int (*fence_signalled)( struct pipe_winsys *sws, + int (*fence_signalled)( struct pipe_winsys *ws, struct pipe_fence_handle *fence, unsigned flag ); /** * Wait for the fence to finish. - * - * The meaning of flag is pipe-driver specific. - * - * Returns zero on success. + * \param flags driver-specific meaning + * \return zero on success. */ - int (*fence_finish)( struct pipe_winsys *sws, + int (*fence_finish)( struct pipe_winsys *ws, struct pipe_fence_handle *fence, unsigned flag ); - }; -- cgit v1.2.3 From aad9dd14d8ef44e55f70b639765dae89e9976345 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 25 Apr 2008 15:59:55 -0600 Subject: gallium: tweak comments, minor var renaming --- src/gallium/include/pipe/p_screen.h | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 35bd46d691..26ac99d287 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -58,25 +58,33 @@ struct pipe_screen { void (*destroy)( struct pipe_screen * ); - /* - * Capability queries - */ const char *(*get_name)( struct pipe_screen * ); const char *(*get_vendor)( struct pipe_screen * ); + /** + * Query an integer-valued capability/parameter/limit + * \param param one of PIPE_CAP_x + */ int (*get_param)( struct pipe_screen *, int param ); + /** + * Query a float-valued capability/parameter/limit + * \param param one of PIPE_CAP_x + */ float (*get_paramf)( struct pipe_screen *, int param ); - /**< type is one of PIPE_TEXTURE, PIPE_SURFACE */ + /** + * Check if the given pipe_format is supported as a texture or + * drawing surface. + * \param type one of PIPE_TEXTURE, PIPE_SURFACE + */ boolean (*is_format_supported)( struct pipe_screen *, enum pipe_format format, uint type ); - - /* - * Texture functions + /** + * Create a new texture object, using the given template info. */ struct pipe_texture * (*texture_create)(struct pipe_screen *, const struct pipe_texture *templat); -- cgit v1.2.3 From a94aad297d9804688f888a5112326104a5d00e07 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 25 Apr 2008 18:46:29 -0600 Subject: use PIPE_ARCH_X86 --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 559370e613..9061e00b63 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -34,7 +34,7 @@ #include "rtasm/rtasm_x86sse.h" -#if defined(__i386__) || defined(__386__) +#ifdef PIPE_ARCH_X86 #define HIGH_PRECISION 1 /* for 1/sqrt() */ @@ -2181,4 +2181,4 @@ tgsi_emit_sse2( return ok; } -#endif /* i386 */ +#endif /* PIPE_ARCH_X86 */ -- cgit v1.2.3 From a8e39b6f5a1fedf2f8719e1adb8802ebbfc09688 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 25 Apr 2008 19:25:26 -0600 Subject: gallium: fix broken SGT, SLE --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index 29e104bbd1..d55f907c0d 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -516,6 +516,20 @@ micro_lg2( dst->f[3] = logf( src->f[3] ) * 1.442695f; } +static void +micro_le( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] <= src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] <= src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] <= src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] <= src1->f[3] ? src2->f[3] : src3->f[3]; +} + static void micro_lt( union tgsi_exec_channel *dst, @@ -1975,7 +1989,7 @@ exec_instruction( FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( &r[0], 0, chan_index ); FETCH( &r[1], 1, chan_index ); - micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + micro_le( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); STORE( &r[0], 0, chan_index ); } break; @@ -1992,7 +2006,7 @@ exec_instruction( FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( &r[0], 0, chan_index ); FETCH( &r[1], 1, chan_index ); - micro_ge( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + micro_le( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); STORE( &r[0], 0, chan_index ); } break; -- cgit v1.2.3 From e3c415995706d2dda7c34a227e2e24d0745763ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 27 Apr 2008 21:09:45 +0900 Subject: rtasm: Implement x86_retw. --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 6 ++++++ src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 1 + 2 files changed, 7 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 3cd45d7dd9..e6cbe9967f 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -498,6 +498,12 @@ void x86_ret( struct x86_function *p ) emit_1ub(p, 0xc3); } +void x86_retw( struct x86_function *p, unsigned short imm ) +{ + DUMP(); + emit_3ub(p, 0xc2, imm & 0xff, (imm >> 8) & 0xff); +} + void x86_sahf( struct x86_function *p ) { DUMP(); diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index 695a1cef4e..1962b07bc5 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -219,6 +219,7 @@ void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_pop( struct x86_function *p, struct x86_reg reg ); void x86_push( struct x86_function *p, struct x86_reg reg ); void x86_ret( struct x86_function *p ); +void x86_retw( struct x86_function *p, unsigned short imm ); void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -- cgit v1.2.3 From 083008d808c02226a3dfead6000a84efd5e6a9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 27 Apr 2008 21:19:34 +0900 Subject: pipebuffer: Be extra cautious with the incoming buffers. A common mistake is trying to fence user or malloc buffers. So don't let the crash happen inside pipebuffer lib. --- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index d3c1ec4fbe..a92daf91dd 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -356,11 +356,25 @@ void buffer_fence(struct pb_buffer *buf, struct pipe_fence_handle *fence) { - struct fenced_buffer *fenced_buf = fenced_buffer(buf); - struct fenced_buffer_list *fenced_list = fenced_buf->list; - struct pipe_winsys *winsys = fenced_list->winsys; + struct fenced_buffer *fenced_buf; + struct fenced_buffer_list *fenced_list; + struct pipe_winsys *winsys; /* FIXME: receive this as a parameter */ unsigned flags = fence ? PIPE_BUFFER_USAGE_GPU_READ_WRITE : 0; + + /* This is a public function, so be extra cautious with the buffer passed, + * as happens frequently to receive null buffers, or pointer to buffers + * other than fenced buffers. */ + assert(buf); + if(!buf) + return; + assert(buf->vtbl == &fenced_buffer_vtbl); + if(buf->vtbl != &fenced_buffer_vtbl) + return; + + fenced_buf = fenced_buffer(buf); + fenced_list = fenced_buf->list; + winsys = fenced_list->winsys; if(fence == fenced_buf->fence) { /* Handle the same fence case specially, not only because it is a fast -- cgit v1.2.3 From 0d179ffe9774487f37838aa634c59ff8ebc1111d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 28 Apr 2008 09:33:20 -0600 Subject: gallium: add cases for PIPE_FORMAT_X8Z24_UNORM --- src/gallium/auxiliary/util/p_tile.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 91283a9ab0..13175ca46e 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -730,6 +730,7 @@ pipe_get_tile_rgba(struct pipe_context *pipe, z32_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); break; case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: s8z24_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); break; case PIPE_FORMAT_Z24S8_UNORM: @@ -808,6 +809,7 @@ pipe_put_tile_rgba(struct pipe_context *pipe, /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ break; case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ break; case PIPE_FORMAT_Z24S8_UNORM: @@ -852,6 +854,7 @@ pipe_get_tile_z(struct pipe_context *pipe, } break; case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: { const uint *pSrc = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x); @@ -912,6 +915,7 @@ pipe_put_tile_z(struct pipe_context *pipe, } break; case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: { uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x); for (i = 0; i < h; i++) { -- cgit v1.2.3 From 58d3dff0d3115ddd5397b7f77b5bcf4f9ca616b6 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 28 Apr 2008 18:50:27 +0200 Subject: gallium: Generate SSE code to swizzle and unswizzle vs inputs and outputs. Change SSE_SWIZZLES #define to 0 to disable it. --- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 3 +- src/gallium/auxiliary/draw/draw_vs_sse.c | 52 ++++++-- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 14 ++ src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 2 + src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 142 ++++++++++++++++++++- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h | 4 +- src/gallium/drivers/softpipe/sp_fs_sse.c | 2 +- 7 files changed, 204 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index f0763dad8d..4ec20493c4 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -109,9 +109,10 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, struct draw_context *draw = fpme->draw; struct draw_vertex_shader *shader = draw->vertex_shader; unsigned opt = fpme->opt; + unsigned alloc_count = align_int( fetch_count, 4 ); struct vertex_header *pipeline_verts = - (struct vertex_header *)MALLOC(fpme->vertex_size * fetch_count); + (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); if (!pipeline_verts) { /* Not much we can do here - just skip the rendering. diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index b1e9f67114..07f85bc448 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -47,14 +47,29 @@ #include "tgsi/util/tgsi_parse.h" #define SSE_MAX_VERTICES 4 +#define SSE_SWIZZLES 1 +#if SSE_SWIZZLES +typedef void (XSTDCALL *codegen_function) ( + const struct tgsi_exec_vector *input, + struct tgsi_exec_vector *output, + float (*constant)[4], + struct tgsi_exec_vector *temporary, + float (*immediates)[4], + const float (*aos_input)[4], + uint num_inputs, + uint input_stride, + float (*aos_output)[4], + uint num_outputs, + uint output_stride ); +#else typedef void (XSTDCALL *codegen_function) ( const struct tgsi_exec_vector *input, struct tgsi_exec_vector *output, float (*constant)[4], struct tgsi_exec_vector *temporary, float (*immediates)[4] ); - +#endif struct draw_sse_vertex_shader { struct draw_vertex_shader base; @@ -91,12 +106,31 @@ vs_sse_run_linear( struct draw_vertex_shader *base, { struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; struct tgsi_exec_machine *machine = shader->machine; - unsigned int i, j; - unsigned slot; + unsigned int i; for (i = 0; i < count; i += MAX_TGSI_VERTICES) { unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); +#if SSE_SWIZZLES + /* run compiled shader + */ + shader->func(machine->Inputs, + machine->Outputs, + (float (*)[4])constants, + machine->Temps, + shader->immediates, + input, + base->info.num_inputs, + input_stride, + output, + base->info.num_outputs, + output_stride ); + + input = (const float (*)[4])((const char *)input + input_stride * max_vertices); + output = (float (*)[4])((char *)output + output_stride * max_vertices); +#else + unsigned int j, slot; + /* Swizzle inputs. */ for (j = 0; j < max_vertices; j++) { @@ -105,10 +139,10 @@ vs_sse_run_linear( struct draw_vertex_shader *base, machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; - } + } input = (const float (*)[4])((const char *)input + input_stride); - } + } /* run compiled shader */ @@ -118,7 +152,6 @@ vs_sse_run_linear( struct draw_vertex_shader *base, machine->Temps, shader->immediates); - /* Unswizzle all output results. */ for (j = 0; j < max_vertices; j++) { @@ -127,10 +160,11 @@ vs_sse_run_linear( struct draw_vertex_shader *base, output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; - } + } output = (float (*)[4])((char *)output + output_stride); - } + } +#endif } } @@ -176,7 +210,7 @@ draw_create_vs_sse(struct draw_context *draw, x86_init_func( &vs->sse2_program ); if (!tgsi_emit_sse2( (struct tgsi_token *) vs->base.state.tokens, - &vs->sse2_program, vs->immediates )) + &vs->sse2_program, vs->immediates, SSE_SWIZZLES )) goto fail; vs->func = (codegen_function) x86_get_func( &vs->sse2_program ); diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index e6cbe9967f..d7e2230557 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -853,6 +853,20 @@ void sse_shufps( struct x86_function *p, emit_1ub(p, shuf); } +void sse_unpckhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) +{ + DUMP_RR( dst, src ); + emit_2ub( p, X86_TWOB, 0x15 ); + emit_modrm( p, dst, src ); +} + +void sse_unpcklps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) +{ + DUMP_RR( dst, src ); + emit_2ub( p, X86_TWOB, 0x14 ); + emit_modrm( p, dst, src ); +} + void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index 1962b07bc5..ad79b1facf 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -203,6 +203,8 @@ void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, unsigned char shuf ); +void sse_unpckhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_unpcklps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src ); void sse2_punpcklbw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 9061e00b63..86ca16c246 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -1788,7 +1788,6 @@ emit_instruction( break; case TGSI_OPCODE_RET: - case TGSI_OPCODE_END: #ifdef WIN32 emit_retw( func, 16 ); #else @@ -1796,6 +1795,9 @@ emit_instruction( #endif break; + case TGSI_OPCODE_END: + break; + case TGSI_OPCODE_SSG: return 0; break; @@ -2027,6 +2029,127 @@ emit_declaration( } } +static void aos_to_soa( struct x86_function *func, uint aos, uint soa, uint num, uint stride ) +{ + struct x86_reg soa_input; + struct x86_reg aos_input; + struct x86_reg num_inputs; + struct x86_reg temp; + unsigned char *inner_loop; + + soa_input = x86_make_reg( file_REG32, reg_AX ); + aos_input = x86_make_reg( file_REG32, reg_BX ); + num_inputs = x86_make_reg( file_REG32, reg_CX ); + temp = x86_make_reg( file_REG32, reg_DX ); + + /* Save EBX */ + x86_push( func, x86_make_reg( file_REG32, reg_BX ) ); + + x86_mov( func, soa_input, get_argument( soa + 1 ) ); + x86_mov( func, aos_input, get_argument( aos + 1 ) ); + x86_mov( func, num_inputs, get_argument( num + 1 ) ); + + inner_loop = x86_get_label( func ); + + x86_mov( func, temp, get_argument( stride + 1 ) ); + x86_push( func, aos_input ); + sse_movlps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); + sse_movlps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); + x86_add( func, aos_input, temp ); + sse_movhps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); + sse_movhps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); + x86_add( func, aos_input, temp ); + sse_movlps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); + sse_movlps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); + x86_add( func, aos_input, temp ); + sse_movhps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); + sse_movhps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); + x86_pop( func, aos_input ); + + sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) ); + sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) ); + sse_shufps( func, make_xmm( 0 ), make_xmm( 1 ), 0x88 ); + sse_shufps( func, make_xmm( 2 ), make_xmm( 1 ), 0xdd ); + sse_shufps( func, make_xmm( 3 ), make_xmm( 4 ), 0x88 ); + sse_shufps( func, make_xmm( 5 ), make_xmm( 4 ), 0xdd ); + + sse_movups( func, x86_make_disp( soa_input, 0 ), make_xmm( 0 ) ); + sse_movups( func, x86_make_disp( soa_input, 16 ), make_xmm( 2 ) ); + sse_movups( func, x86_make_disp( soa_input, 32 ), make_xmm( 3 ) ); + sse_movups( func, x86_make_disp( soa_input, 48 ), make_xmm( 5 ) ); + + /* Advance to next input */ + x86_mov_reg_imm( func, temp, 16 ); + x86_add( func, aos_input, temp ); + x86_mov_reg_imm( func, temp, 64 ); + x86_add( func, soa_input, temp ); + x86_dec( func, num_inputs ); + x86_jcc( func, cc_NE, inner_loop ); + + /* Restore EBX */ + x86_pop( func, x86_make_reg( file_REG32, reg_BX ) ); +} + +static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, uint stride ) +{ + struct x86_reg soa_output; + struct x86_reg aos_output; + struct x86_reg num_outputs; + struct x86_reg temp; + unsigned char *inner_loop; + + soa_output = x86_make_reg( file_REG32, reg_AX ); + aos_output = x86_make_reg( file_REG32, reg_BX ); + num_outputs = x86_make_reg( file_REG32, reg_CX ); + temp = x86_make_reg( file_REG32, reg_DX ); + + /* Save EBX */ + x86_push( func, x86_make_reg( file_REG32, reg_BX ) ); + + x86_mov( func, soa_output, get_argument( soa + 1 ) ); + x86_mov( func, aos_output, get_argument( aos + 1 ) ); + x86_mov( func, num_outputs, get_argument( num + 1 ) ); + + inner_loop = x86_get_label( func ); + + sse_movups( func, make_xmm( 0 ), x86_make_disp( soa_output, 0 ) ); + sse_movups( func, make_xmm( 1 ), x86_make_disp( soa_output, 16 ) ); + sse_movups( func, make_xmm( 3 ), x86_make_disp( soa_output, 32 ) ); + sse_movups( func, make_xmm( 4 ), x86_make_disp( soa_output, 48 ) ); + + sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) ); + sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) ); + sse_unpcklps( func, make_xmm( 0 ), make_xmm( 1 ) ); + sse_unpckhps( func, make_xmm( 2 ), make_xmm( 1 ) ); + sse_unpcklps( func, make_xmm( 3 ), make_xmm( 4 ) ); + sse_unpckhps( func, make_xmm( 5 ), make_xmm( 4 ) ); + + x86_mov( func, temp, get_argument( stride + 1 ) ); + x86_push( func, aos_output ); + sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) ); + sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) ); + x86_add( func, aos_output, temp ); + sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) ); + sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) ); + x86_add( func, aos_output, temp ); + sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) ); + sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) ); + x86_add( func, aos_output, temp ); + sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) ); + sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) ); + x86_pop( func, aos_output ); + + /* Advance to next output */ + x86_mov_reg_imm( func, temp, 16 ); + x86_add( func, aos_output, temp ); + x86_mov_reg_imm( func, temp, 64 ); + x86_add( func, soa_output, temp ); + x86_dec( func, num_outputs ); + x86_jcc( func, cc_NE, inner_loop ); + + /* Restore EBX */ + x86_pop( func, x86_make_reg( file_REG32, reg_BX ) ); +} /** * Translate a TGSI vertex/fragment shader to SSE2 code. @@ -2048,7 +2171,8 @@ unsigned tgsi_emit_sse2( const struct tgsi_token *tokens, struct x86_function *func, - float (*immediates)[4]) + float (*immediates)[4], + boolean do_swizzles ) { struct tgsi_parse_context parse; boolean instruction_phase = FALSE; @@ -2089,6 +2213,9 @@ tgsi_emit_sse2( else { assert(parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX); + if (do_swizzles) + aos_to_soa( func, 5, 0, 6, 7 ); + x86_mov( func, get_input_base(), @@ -2176,6 +2303,17 @@ tgsi_emit_sse2( } } + if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) { + if (do_swizzles) + soa_to_aos( func, 8, 1, 9, 10 ); + } + +#ifdef WIN32 + emit_retw( func, 16 ); +#else + emit_ret( func ); +#endif + tgsi_parse_free( &parse ); return ok; diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h index 063287dc5e..e66d115283 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h @@ -12,8 +12,8 @@ unsigned tgsi_emit_sse2( const struct tgsi_token *tokens, struct x86_function *function, - float (*immediates)[4] - ); + float (*immediates)[4], + boolean do_swizzles ); #if defined __cplusplus } diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index f857d26143..4d569e1e22 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -133,7 +133,7 @@ softpipe_create_fs_sse(struct softpipe_context *softpipe, x86_init_func( &shader->sse2_program ); if (!tgsi_emit_sse2( templ->tokens, &shader->sse2_program, - shader->immediates)) { + shader->immediates, FALSE )) { FREE(shader); return NULL; } -- cgit v1.2.3 From b6d9666a420bd7c31a6696f94ba1025e5204d458 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 28 Apr 2008 19:03:20 +0200 Subject: gallium: Set SSE_SWIZZLES to 0 by default. --- src/gallium/auxiliary/draw/draw_vs_sse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 07f85bc448..90926aec85 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -47,7 +47,7 @@ #include "tgsi/util/tgsi_parse.h" #define SSE_MAX_VERTICES 4 -#define SSE_SWIZZLES 1 +#define SSE_SWIZZLES 0 #if SSE_SWIZZLES typedef void (XSTDCALL *codegen_function) ( -- cgit v1.2.3 From a41b78d107264227f3338446e04dcfda32634f52 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 25 Apr 2008 15:27:33 +0100 Subject: pb: remove unused variable, squash warning --- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index a92daf91dd..2fa0842971 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -134,8 +134,6 @@ _fenced_buffer_add(struct fenced_buffer *fenced_buf) static INLINE void _fenced_buffer_destroy(struct fenced_buffer *fenced_buf) { - struct fenced_buffer_list *fenced_list = fenced_buf->list; - assert(!fenced_buf->base.base.refcount); assert(!fenced_buf->fence); pb_reference(&fenced_buf->buffer, NULL); -- cgit v1.2.3 From 546ab045d8a18758ffc44da9dc76ad1335553cf6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 25 Apr 2008 15:28:54 +0100 Subject: translate: squash warnings --- src/gallium/auxiliary/translate/translate_cache.c | 3 ++- src/gallium/auxiliary/translate/translate_cache.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate_cache.c b/src/gallium/auxiliary/translate/translate_cache.c index e91d648eba..115dc9287e 100644 --- a/src/gallium/auxiliary/translate/translate_cache.c +++ b/src/gallium/auxiliary/translate/translate_cache.c @@ -28,6 +28,7 @@ #include "pipe/p_util.h" #include "pipe/p_state.h" #include "translate.h" +#include "translate_cache.h" #include "cso_cache/cso_cache.h" #include "cso_cache/cso_hash.h" @@ -36,7 +37,7 @@ struct translate_cache { struct cso_hash *hash; }; -struct translate_cache * translate_cache_create() +struct translate_cache * translate_cache_create( void ) { struct translate_cache *cache = MALLOC_STRUCT(translate_cache); cache->hash = cso_hash_create(); diff --git a/src/gallium/auxiliary/translate/translate_cache.h b/src/gallium/auxiliary/translate/translate_cache.h index 63fc57b7ea..7dba871e57 100644 --- a/src/gallium/auxiliary/translate/translate_cache.h +++ b/src/gallium/auxiliary/translate/translate_cache.h @@ -38,7 +38,7 @@ struct translate_cache; struct translate_key; struct translate; -struct translate_cache *translate_cache_create(); +struct translate_cache *translate_cache_create( void ); void translate_cache_destroy(struct translate_cache *cache); /** -- cgit v1.2.3 From 9fb444f191015b44498a5c83d762519ccc98ed55 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 28 Apr 2008 18:43:27 +0100 Subject: tsgi: add a makefile --- src/gallium/auxiliary/tgsi/exec/Makefile | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/gallium/auxiliary/tgsi/exec/Makefile (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/Makefile b/src/gallium/auxiliary/tgsi/exec/Makefile new file mode 100644 index 0000000000..451911a354 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/exec/Makefile @@ -0,0 +1,2 @@ +default: + cd .. ; make -- cgit v1.2.3 From c4917c62311522df902003d77b146fc677c09a4e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 28 Apr 2008 18:50:31 +0100 Subject: tgsi: make loop structure clearer, use x86_lea for increments --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 134 ++++++++++++++-------------- 1 file changed, 68 insertions(+), 66 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 86ca16c246..1138f59997 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -2049,40 +2049,41 @@ static void aos_to_soa( struct x86_function *func, uint aos, uint soa, uint num, x86_mov( func, aos_input, get_argument( aos + 1 ) ); x86_mov( func, num_inputs, get_argument( num + 1 ) ); + /* do */ inner_loop = x86_get_label( func ); - - x86_mov( func, temp, get_argument( stride + 1 ) ); - x86_push( func, aos_input ); - sse_movlps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); - sse_movlps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); - x86_add( func, aos_input, temp ); - sse_movhps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); - sse_movhps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); - x86_add( func, aos_input, temp ); - sse_movlps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); - sse_movlps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); - x86_add( func, aos_input, temp ); - sse_movhps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); - sse_movhps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); - x86_pop( func, aos_input ); - - sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) ); - sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) ); - sse_shufps( func, make_xmm( 0 ), make_xmm( 1 ), 0x88 ); - sse_shufps( func, make_xmm( 2 ), make_xmm( 1 ), 0xdd ); - sse_shufps( func, make_xmm( 3 ), make_xmm( 4 ), 0x88 ); - sse_shufps( func, make_xmm( 5 ), make_xmm( 4 ), 0xdd ); - - sse_movups( func, x86_make_disp( soa_input, 0 ), make_xmm( 0 ) ); - sse_movups( func, x86_make_disp( soa_input, 16 ), make_xmm( 2 ) ); - sse_movups( func, x86_make_disp( soa_input, 32 ), make_xmm( 3 ) ); - sse_movups( func, x86_make_disp( soa_input, 48 ), make_xmm( 5 ) ); - - /* Advance to next input */ - x86_mov_reg_imm( func, temp, 16 ); - x86_add( func, aos_input, temp ); - x86_mov_reg_imm( func, temp, 64 ); - x86_add( func, soa_input, temp ); + { + x86_mov( func, temp, get_argument( stride + 1 ) ); + x86_push( func, aos_input ); + sse_movlps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); + sse_movlps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); + x86_add( func, aos_input, temp ); + sse_movhps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); + sse_movhps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); + x86_add( func, aos_input, temp ); + sse_movlps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); + sse_movlps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); + x86_add( func, aos_input, temp ); + sse_movhps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); + sse_movhps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); + x86_pop( func, aos_input ); + + sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) ); + sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) ); + sse_shufps( func, make_xmm( 0 ), make_xmm( 1 ), 0x88 ); + sse_shufps( func, make_xmm( 2 ), make_xmm( 1 ), 0xdd ); + sse_shufps( func, make_xmm( 3 ), make_xmm( 4 ), 0x88 ); + sse_shufps( func, make_xmm( 5 ), make_xmm( 4 ), 0xdd ); + + sse_movups( func, x86_make_disp( soa_input, 0 ), make_xmm( 0 ) ); + sse_movups( func, x86_make_disp( soa_input, 16 ), make_xmm( 2 ) ); + sse_movups( func, x86_make_disp( soa_input, 32 ), make_xmm( 3 ) ); + sse_movups( func, x86_make_disp( soa_input, 48 ), make_xmm( 5 ) ); + + /* Advance to next input */ + x86_lea( func, aos_input, x86_make_disp(aos_input, 16) ); + x86_lea( func, soa_input, x86_make_disp(soa_input, 64) ); + } + /* while --num_inputs */ x86_dec( func, num_inputs ); x86_jcc( func, cc_NE, inner_loop ); @@ -2110,40 +2111,41 @@ static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, x86_mov( func, aos_output, get_argument( aos + 1 ) ); x86_mov( func, num_outputs, get_argument( num + 1 ) ); + /* do */ inner_loop = x86_get_label( func ); - - sse_movups( func, make_xmm( 0 ), x86_make_disp( soa_output, 0 ) ); - sse_movups( func, make_xmm( 1 ), x86_make_disp( soa_output, 16 ) ); - sse_movups( func, make_xmm( 3 ), x86_make_disp( soa_output, 32 ) ); - sse_movups( func, make_xmm( 4 ), x86_make_disp( soa_output, 48 ) ); - - sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) ); - sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) ); - sse_unpcklps( func, make_xmm( 0 ), make_xmm( 1 ) ); - sse_unpckhps( func, make_xmm( 2 ), make_xmm( 1 ) ); - sse_unpcklps( func, make_xmm( 3 ), make_xmm( 4 ) ); - sse_unpckhps( func, make_xmm( 5 ), make_xmm( 4 ) ); - - x86_mov( func, temp, get_argument( stride + 1 ) ); - x86_push( func, aos_output ); - sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) ); - sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) ); - x86_add( func, aos_output, temp ); - sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) ); - sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) ); - x86_add( func, aos_output, temp ); - sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) ); - sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) ); - x86_add( func, aos_output, temp ); - sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) ); - sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) ); - x86_pop( func, aos_output ); - - /* Advance to next output */ - x86_mov_reg_imm( func, temp, 16 ); - x86_add( func, aos_output, temp ); - x86_mov_reg_imm( func, temp, 64 ); - x86_add( func, soa_output, temp ); + { + sse_movups( func, make_xmm( 0 ), x86_make_disp( soa_output, 0 ) ); + sse_movups( func, make_xmm( 1 ), x86_make_disp( soa_output, 16 ) ); + sse_movups( func, make_xmm( 3 ), x86_make_disp( soa_output, 32 ) ); + sse_movups( func, make_xmm( 4 ), x86_make_disp( soa_output, 48 ) ); + + sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) ); + sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) ); + sse_unpcklps( func, make_xmm( 0 ), make_xmm( 1 ) ); + sse_unpckhps( func, make_xmm( 2 ), make_xmm( 1 ) ); + sse_unpcklps( func, make_xmm( 3 ), make_xmm( 4 ) ); + sse_unpckhps( func, make_xmm( 5 ), make_xmm( 4 ) ); + + x86_mov( func, temp, get_argument( stride + 1 ) ); + x86_push( func, aos_output ); + sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) ); + sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) ); + x86_add( func, aos_output, temp ); + sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) ); + sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) ); + x86_add( func, aos_output, temp ); + sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) ); + sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) ); + x86_add( func, aos_output, temp ); + sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) ); + sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) ); + x86_pop( func, aos_output ); + + /* Advance to next output */ + x86_lea( func, aos_output, x86_make_disp(aos_output, 16) ); + x86_lea( func, soa_output, x86_make_disp(soa_output, 64) ); + } + /* while --num_outputs */ x86_dec( func, num_outputs ); x86_jcc( func, cc_NE, inner_loop ); -- cgit v1.2.3 From 5e8d7899a8114918054f07c807aef07cbbfcb6b4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 28 Apr 2008 16:32:42 -0600 Subject: gallium: fix error msg typo --- src/gallium/auxiliary/util/u_pack_color.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 50ef44992b..89e3b5dc45 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -201,7 +201,7 @@ util_pack_z(enum pipe_format format, double z) case PIPE_FORMAT_Z24X8_UNORM: return ((uint) (z * 0xffffff)) << 8; default: - debug_printf("gallium: unhandled fomrat in util_pack_z()"); + debug_printf("gallium: unhandled format in util_pack_z()\n"); return 0; } } -- cgit v1.2.3 From 1cff4992b389ad884a663c93bdd7b7c6be6c79d2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 28 Apr 2008 16:33:15 -0600 Subject: gallium: add \n to error strings --- src/gallium/auxiliary/util/u_pack_color.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 89e3b5dc45..8296f1291c 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -91,7 +91,7 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, return; /* XXX lots more cases to add */ default: - debug_printf("gallium: unhandled format in util_pack_color_ub()"); + debug_printf("gallium: unhandled format in util_pack_color_ub()\n"); } } @@ -174,7 +174,7 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest) return; /* XXX lots more cases to add */ default: - debug_printf("gallium: unhandled format in util_pack_color()"); + debug_printf("gallium: unhandled format in util_pack_color()\n"); } } -- cgit v1.2.3 From 733bc4df1a53bb1899933685e06c52109d096bee Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 29 Apr 2008 12:55:41 -0600 Subject: gallium: added some assertions to be sure the blit's surface formats are suitable --- src/gallium/auxiliary/util/u_blit.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 1105066cb8..9e9912c6e4 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -264,6 +264,9 @@ util_blit_pixels(struct blit_state *ctx, dstY1 = tmp; } + assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE)); + assert(screen->is_format_supported(screen, dst->format, PIPE_SURFACE)); + /* * XXX for now we're always creating a temporary texture. * Strictly speaking that's not always needed. -- cgit v1.2.3 From 9bfe1a3d505733489f7583fe603b7d192f38fa8c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 29 Apr 2008 20:33:37 +0100 Subject: gallium: add debug_print_format() make it easier to print format error messages --- src/gallium/auxiliary/util/p_debug.c | 97 +++++++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_pack_color.h | 9 ++- src/gallium/include/pipe/p_debug.h | 11 ++-- src/gallium/include/pipe/p_format.h | 83 +------------------------- 4 files changed, 111 insertions(+), 89 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index cd612e23b3..eaf2c9bd98 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -41,6 +41,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_util.h" #include "pipe/p_debug.h" +#include "pipe/p_format.h" #include "util/u_string.h" @@ -324,3 +325,99 @@ debug_dump_flags(const struct debug_named_value *names, } + + + + +char *pf_sprint_name( char *str, enum pipe_format format ) +{ + strcpy( str, "PIPE_FORMAT_" ); + switch (pf_layout( format )) { + case PIPE_FORMAT_LAYOUT_RGBAZS: + { + pipe_format_rgbazs_t rgbazs = (pipe_format_rgbazs_t) format; + uint i; + uint scale = 1 << (pf_exp8( rgbazs ) * 3); + + for (i = 0; i < 4; i++) { + uint size = pf_size_xyzw( rgbazs, i ); + + if (size == 0) { + break; + } + switch (pf_swizzle_xyzw( rgbazs, i )) { + case PIPE_FORMAT_COMP_R: + strcat( str, "R" ); + break; + case PIPE_FORMAT_COMP_G: + strcat( str, "G" ); + break; + case PIPE_FORMAT_COMP_B: + strcat( str, "B" ); + break; + case PIPE_FORMAT_COMP_A: + strcat( str, "A" ); + break; + case PIPE_FORMAT_COMP_0: + strcat( str, "0" ); + break; + case PIPE_FORMAT_COMP_1: + strcat( str, "1" ); + break; + case PIPE_FORMAT_COMP_Z: + strcat( str, "Z" ); + break; + case PIPE_FORMAT_COMP_S: + strcat( str, "S" ); + break; + } + util_snprintf( &str[strlen( str )], 32, "%u", size * scale ); + } + if (i != 0) { + strcat( str, "_" ); + } + switch (pf_type( rgbazs )) { + case PIPE_FORMAT_TYPE_UNKNOWN: + strcat( str, "NONE" ); + break; + case PIPE_FORMAT_TYPE_FLOAT: + strcat( str, "FLOAT" ); + break; + case PIPE_FORMAT_TYPE_UNORM: + strcat( str, "UNORM" ); + break; + case PIPE_FORMAT_TYPE_SNORM: + strcat( str, "SNORM" ); + break; + case PIPE_FORMAT_TYPE_USCALED: + strcat( str, "USCALED" ); + break; + case PIPE_FORMAT_TYPE_SSCALED: + strcat( str, "SSCALED" ); + break; + } + } + break; + case PIPE_FORMAT_LAYOUT_YCBCR: + { + pipe_format_ycbcr_t ycbcr = (pipe_format_ycbcr_t) format; + + strcat( str, "YCBCR" ); + if (pf_rev( ycbcr )) { + strcat( str, "_REV" ); + } + } + break; + } + return str; +} + + +void debug_print_format(const char *msg, enum pipe_format fmt ) +{ + char fmtstr[80]; + + pf_sprint_name(fmtstr, fmt); + + debug_printf("%s: %s\n", msg, fmtstr); +} diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 8296f1291c..7e26b1642a 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -91,7 +91,8 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, return; /* XXX lots more cases to add */ default: - debug_printf("gallium: unhandled format in util_pack_color_ub()\n"); + debug_print_format("gallium: unhandled format in util_pack_color_ub()", format); + assert(0); } } @@ -174,7 +175,8 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest) return; /* XXX lots more cases to add */ default: - debug_printf("gallium: unhandled format in util_pack_color()\n"); + debug_print_format("gallium: unhandled format in util_pack_color()", format); + assert(0); } } @@ -201,7 +203,8 @@ util_pack_z(enum pipe_format format, double z) case PIPE_FORMAT_Z24X8_UNORM: return ((uint) (z * 0xffffff)) << 8; default: - debug_printf("gallium: unhandled format in util_pack_z()\n"); + debug_print_format("gallium: unhandled format in util_pack_z()", format); + assert(0); return 0; } } diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 235c47abac..f87247994b 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -103,16 +103,19 @@ debug_printf(const char *format, ...) #endif +#ifdef DEBUG /** * Dump a blob in hex to the same place that debug_printf sends its * messages. */ -#ifdef DEBUG -void debug_print_blob( const char *name, - const void *blob, - unsigned size ); +void debug_print_blob( const char *name, const void *blob, unsigned size ); + +/* Print a message along with a prettified format string + */ +void debug_print_format(const char *msg, enum pipe_format fmt ); #else #define debug_print_blob(_name, _blob, _size) ((void)0) +#define debug_print_format(_msg, _fmt) ((void)0) #endif diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 94c2eeb62b..bc23fe142e 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -337,88 +337,7 @@ enum pipe_format { /** * Builds pipe format name from format token. */ -static INLINE char *pf_sprint_name( char *str, enum pipe_format format ) -{ - strcpy( str, "PIPE_FORMAT_" ); - switch (pf_layout( format )) { - case PIPE_FORMAT_LAYOUT_RGBAZS: - { - pipe_format_rgbazs_t rgbazs = (pipe_format_rgbazs_t) format; - uint i; - uint scale = 1 << (pf_exp8( rgbazs ) * 3); - - for (i = 0; i < 4; i++) { - uint size = pf_size_xyzw( rgbazs, i ); - - if (size == 0) { - break; - } - switch (pf_swizzle_xyzw( rgbazs, i )) { - case PIPE_FORMAT_COMP_R: - strcat( str, "R" ); - break; - case PIPE_FORMAT_COMP_G: - strcat( str, "G" ); - break; - case PIPE_FORMAT_COMP_B: - strcat( str, "B" ); - break; - case PIPE_FORMAT_COMP_A: - strcat( str, "A" ); - break; - case PIPE_FORMAT_COMP_0: - strcat( str, "0" ); - break; - case PIPE_FORMAT_COMP_1: - strcat( str, "1" ); - break; - case PIPE_FORMAT_COMP_Z: - strcat( str, "Z" ); - break; - case PIPE_FORMAT_COMP_S: - strcat( str, "S" ); - break; - } - util_snprintf( &str[strlen( str )], 32, "%u", size * scale ); - } - if (i != 0) { - strcat( str, "_" ); - } - switch (pf_type( rgbazs )) { - case PIPE_FORMAT_TYPE_UNKNOWN: - strcat( str, "NONE" ); - break; - case PIPE_FORMAT_TYPE_FLOAT: - strcat( str, "FLOAT" ); - break; - case PIPE_FORMAT_TYPE_UNORM: - strcat( str, "UNORM" ); - break; - case PIPE_FORMAT_TYPE_SNORM: - strcat( str, "SNORM" ); - break; - case PIPE_FORMAT_TYPE_USCALED: - strcat( str, "USCALED" ); - break; - case PIPE_FORMAT_TYPE_SSCALED: - strcat( str, "SSCALED" ); - break; - } - } - break; - case PIPE_FORMAT_LAYOUT_YCBCR: - { - pipe_format_ycbcr_t ycbcr = (pipe_format_ycbcr_t) format; - - strcat( str, "YCBCR" ); - if (pf_rev( ycbcr )) { - strcat( str, "_REV" ); - } - } - break; - } - return str; -} +extern char *pf_sprint_name( char *str, enum pipe_format format ); /** * Return bits for a particular component. -- cgit v1.2.3 From 7441f2e3ea77404064d65b604e1e525cacc453e9 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 29 Apr 2008 20:42:35 +0100 Subject: gallium: add pack for A1R5B5G5 --- src/gallium/auxiliary/util/u_pack_color.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 7e26b1642a..7d4024e82c 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -89,6 +89,12 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); } return; + case PIPE_FORMAT_A1R5G5B5_UNORM: + { + ushort *d = (ushort *) dest; + *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 3) | (b >> 3); + } + return; /* XXX lots more cases to add */ default: debug_print_format("gallium: unhandled format in util_pack_color_ub()", format); @@ -156,6 +162,12 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest) *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); } return; + case PIPE_FORMAT_A1R5G5B5_UNORM: + { + ushort *d = (ushort *) dest; + *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 3) | (b >> 3); + } + return; case PIPE_FORMAT_R32G32B32A32_FLOAT: { float *d = (float *) dest; -- cgit v1.2.3 From fbddc8097ce3a9d38a061105542875dbb9f909f7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 29 Apr 2008 21:05:48 +0100 Subject: gallium: add pack for A4R4G4B4 --- src/gallium/auxiliary/util/u_pack_color.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 7d4024e82c..f641329d18 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -95,6 +95,12 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 3) | (b >> 3); } return; + case PIPE_FORMAT_A4R4G4B4_UNORM: + { + ushort *d = (ushort *) dest; + *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); + } + return; /* XXX lots more cases to add */ default: debug_print_format("gallium: unhandled format in util_pack_color_ub()", format); @@ -168,6 +174,12 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest) *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 3) | (b >> 3); } return; + case PIPE_FORMAT_A4R4G4B4_UNORM: + { + ushort *d = (ushort *) dest; + *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); + } + return; case PIPE_FORMAT_R32G32B32A32_FLOAT: { float *d = (float *) dest; -- cgit v1.2.3 From bbafa8aa2fc8009fb8e32f996d4972c56e6b46e6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 29 Apr 2008 21:30:04 +0100 Subject: gallium: fix pack for A1R5B5G5 --- src/gallium/auxiliary/util/u_pack_color.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index f641329d18..bb2c34e5f6 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -92,7 +92,7 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, case PIPE_FORMAT_A1R5G5B5_UNORM: { ushort *d = (ushort *) dest; - *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 3) | (b >> 3); + *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); } return; case PIPE_FORMAT_A4R4G4B4_UNORM: @@ -171,7 +171,7 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest) case PIPE_FORMAT_A1R5G5B5_UNORM: { ushort *d = (ushort *) dest; - *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 3) | (b >> 3); + *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); } return; case PIPE_FORMAT_A4R4G4B4_UNORM: -- cgit v1.2.3 From 1e97ab685689ef06181a5f22fae9a3a82c83142c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 29 Apr 2008 21:30:31 +0100 Subject: gallium: add pack for _FLOAT formats to pack_ub --- src/gallium/auxiliary/util/u_pack_color.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index bb2c34e5f6..0b917c005f 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -101,6 +101,24 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); } return; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + { + float *d = (float *) dest; + d[0] = (float)r / 255.0f; + d[1] = (float)g / 255.0f; + d[2] = (float)b / 255.0f; + d[3] = (float)a / 255.0f; + } + return; + case PIPE_FORMAT_R32G32B32_FLOAT: + { + float *d = (float *) dest; + d[0] = (float)r / 255.0f; + d[1] = (float)g / 255.0f; + d[2] = (float)b / 255.0f; + } + return; + /* XXX lots more cases to add */ default: debug_print_format("gallium: unhandled format in util_pack_color_ub()", format); -- cgit v1.2.3 From fce5951b56a84304d0cb0dce4785237d90a71eb2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 29 Apr 2008 14:39:42 -0600 Subject: gallium: declare pipe_format enum to silence warnings --- src/gallium/include/pipe/p_debug.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index f87247994b..ed47c0e14c 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -60,6 +60,8 @@ extern "C" { #endif +enum pipe_format; + void _debug_vprintf(const char *format, va_list ap); -- cgit v1.2.3 From 0d80f407f128f1a324e9dc0db2d0910bf32ba736 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 29 Apr 2008 17:21:10 -0400 Subject: =?UTF-8?q?silence=20p=5Fdebug.h:63:=20warning:=20ISO=20C=20forbid?= =?UTF-8?q?s=20forward=20references=20to=20=E2=80=98enum=E2=80=99=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gallium/auxiliary/util/p_debug.c | 4 ++-- src/gallium/include/pipe/p_debug.h | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index eaf2c9bd98..8ef2880191 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -413,11 +413,11 @@ char *pf_sprint_name( char *str, enum pipe_format format ) } -void debug_print_format(const char *msg, enum pipe_format fmt ) +void debug_print_format(const char *msg, unsigned fmt ) { char fmtstr[80]; - pf_sprint_name(fmtstr, fmt); + pf_sprint_name(fmtstr, (enum pipe_format)fmt); debug_printf("%s: %s\n", msg, fmtstr); } diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index ed47c0e14c..7a7312ea12 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -59,9 +59,6 @@ extern "C" { #endif #endif - -enum pipe_format; - void _debug_vprintf(const char *format, va_list ap); @@ -114,7 +111,7 @@ void debug_print_blob( const char *name, const void *blob, unsigned size ); /* Print a message along with a prettified format string */ -void debug_print_format(const char *msg, enum pipe_format fmt ); +void debug_print_format(const char *msg, unsigned fmt ); #else #define debug_print_blob(_name, _blob, _size) ((void)0) #define debug_print_format(_msg, _fmt) ((void)0) -- cgit v1.2.3 From 62a29412b90008a247fd3b61f1b882df2e5e81c1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 25 Apr 2008 16:50:56 -0600 Subject: gallium: test for new PIPE_ARCH_X86 --- src/gallium/drivers/softpipe/sp_context.c | 2 +- src/gallium/drivers/softpipe/sp_fs_sse.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index f2ce0fdc6e..edf91ecafa 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -127,7 +127,7 @@ softpipe_create( struct pipe_screen *screen, struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); uint i; -#if defined(__i386__) || defined(__386__) +#ifdef PIPE_ARCH_X86 softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; #else softpipe->use_sse = FALSE; diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 4d569e1e22..25fdfea491 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -40,7 +40,7 @@ #include "tgsi/exec/tgsi_sse2.h" -#if defined(__i386__) || defined(__386__) +#ifdef PIPE_ARCH_X86 #include "rtasm/rtasm_x86sse.h" -- cgit v1.2.3 From d0b2561c57763db196b45ab052a01a12fc37b06f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 25 Apr 2008 17:50:48 -0600 Subject: gallium: updated comment in xm_flush_frontbuffer() --- src/gallium/winsys/xlib/xm_winsys.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 5a424d0ac7..8a89278cde 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -296,10 +296,9 @@ xm_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf, void *context_private) { - /* The Xlib driver's front color surfaces are actually X Windows so - * this flush is a no-op. - * If we instead did front buffer rendering to a temporary XImage, - * this would be the place to copy the Ximage to the on-screen Window. + /* + * The front color buffer is actually just another XImage buffer. + * This function copies that XImage to the actual X Window. */ XMesaContext xmctx = (XMesaContext) context_private; xmesa_display_surface(xmctx->xm_buffer, surf); -- cgit v1.2.3 From 42fb48492e71016c5a2888cd3d2507a89dbd91f3 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 29 Apr 2008 18:34:14 -0600 Subject: gallium: init hw_key with memset() to silence valgrind warnings We shouldn't be hashing with keys that have uninitialized memory. --- src/gallium/auxiliary/draw/draw_pt_emit.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 35707af8a8..f9ac16786e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -58,6 +58,8 @@ void draw_pt_emit_prepare( struct pt_emit *emit, return; } + memset(&hw_key, 0, sizeof(hw_key)); + /* Must do this after set_primitive() above: */ vinfo = draw->render->get_vertex_info(draw->render); -- cgit v1.2.3 From 15318c8d8eb97cec8c8528cc91aaeab8858f33c6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 30 Apr 2008 10:43:09 -0600 Subject: gallium: new pipe_buffer alloc/map/unmap/ref wrappers --- src/gallium/include/pipe/p_inlines.h | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index 274f76a383..8eb604e73f 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -129,6 +129,56 @@ pipe_texture_release(struct pipe_texture **ptr) } +/** + * Convenience wrappers for winsys buffer functions. + */ + +static INLINE struct pipe_buffer * +pipe_buffer_create( struct pipe_context *pipe, + unsigned alignment, unsigned usage, unsigned size ) +{ + return pipe->winsys->buffer_create(pipe->winsys, alignment, usage, size); +} + +static INLINE struct pipe_buffer * +pipe_user_buffer_create( struct pipe_context *pipe, void *ptr, unsigned size ) +{ + return pipe->winsys->user_buffer_create(pipe->winsys, ptr, size); +} + +static INLINE void +pipe_buffer_destroy( struct pipe_context *pipe, struct pipe_buffer *buf ) +{ + pipe->winsys->buffer_destroy(pipe->winsys, buf); +} + +static INLINE void * +pipe_buffer_map(struct pipe_context *pipe, + struct pipe_buffer *buf, + unsigned usage) +{ + return pipe->winsys->buffer_map(pipe->winsys, buf, usage); +} + +static INLINE void +pipe_buffer_unmap(struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + pipe->winsys->buffer_unmap(pipe->winsys, buf); +} + +/* XXX when we're using this everywhere, get rid of + * pipe_buffer_reference() above. + */ +static INLINE void +pipe_reference_buffer(struct pipe_context *pipe, + struct pipe_buffer **ptr, + struct pipe_buffer *buf) +{ + pipe_buffer_reference(pipe->winsys, ptr, buf); +} + + #ifdef __cplusplus } #endif -- cgit v1.2.3 From cafb545721e6c9479c07d3a7a891236e006d3376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 1 May 2008 00:59:12 +0900 Subject: d3d: Windows miniport driver portability fixes. --- src/gallium/auxiliary/util/p_debug.c | 2 +- src/gallium/auxiliary/util/p_debug_mem.c | 7 +++- src/gallium/auxiliary/util/u_time.c | 6 +-- src/gallium/include/pipe/p_config.h | 9 +++++ src/gallium/include/pipe/p_util.h | 64 +++++++++++++++++--------------- 5 files changed, 53 insertions(+), 35 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 8ef2880191..56eecaab62 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -104,7 +104,7 @@ void _debug_break(void) __asm("int3"); #elif (defined(__i386__) || defined(__386__)) && defined(__MSC__) _asm {int 3}; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && !defined(WINCE) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) EngDebugBreak(); #else abort(); diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c index 9321cf71bb..3b5e4fbaee 100644 --- a/src/gallium/auxiliary/util/p_debug_mem.c +++ b/src/gallium/auxiliary/util/p_debug_mem.c @@ -34,9 +34,11 @@ #include "pipe/p_config.h" -#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) #include #include +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) +#include #else #include #include @@ -52,6 +54,9 @@ #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && !defined(WINCE) #define real_malloc(_size) EngAllocMem(0, _size, 'D3AG') #define real_free(_ptr) EngFreeMem(_ptr) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) +#define real_malloc(_size) ExAllocatePool(0, _size) +#define real_free(_ptr) ExFreePool(_ptr) #else #define real_malloc(_size) malloc(_size) #define real_free(_ptr) free(_ptr) diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c index dd28ff4134..9b97050d51 100644 --- a/src/gallium/auxiliary/util/u_time.c +++ b/src/gallium/auxiliary/util/u_time.c @@ -37,11 +37,11 @@ #if defined(PIPE_OS_LINUX) #include -#elif defined(PIPE_OS_WINDOWS) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) #include -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) #include -#endif +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) +#include #else #error Unsupported OS #endif diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index e44fafeae9..5c030bdfff 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -106,7 +106,16 @@ #if defined(PIPE_SUBSYSTEM_KERNEL) #define PIPE_SUBSYSTEM_WINDOWS_DISPLAY #endif +#if 0 /* FIXME */ +#define PIPE_SUBSYSTEM_WINDOWS_MINIPORT +#endif +#if 0 /* FIXME */ +#define PIPE_SUBSYSTEM_WINDOWS_CE +#endif +#if defined(PIPE_SUBSYSTEM_USER) +#define PIPE_SUBSYSTEM_WINDOWS_USER #endif +#endif /* PIPE_OS_WINDOWS */ #endif /* P_CONFIG_H_ */ diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 63301ae3aa..0e7e246666 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -41,7 +41,9 @@ extern "C" { #endif -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && defined(DEBUG) /* memory debugging */ +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && defined(DEBUG) + +/* memory debugging */ #include "p_debug.h" @@ -54,9 +56,7 @@ extern "C" { #define REALLOC( _ptr, _old_size, _size ) \ debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _size ) -#else - -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) void * __stdcall EngAllocMem( @@ -68,17 +68,33 @@ void __stdcall EngFreeMem( void *Mem ); -static INLINE void * -MALLOC( unsigned size ) -{ -#ifdef WINCE - /* TODO: Need to abstract this */ - return malloc( size ); +#define MALLOC( _size ) EngAllocMem( 0, _size, 'D3AG' ) +#define _FREE( _ptr ) EngFreeMem( _ptr ) + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + +void * +ExAllocatePool( + unsigned long PoolType, + size_t NumberOfBytes); + +void +ExFreePool(void *P); + +#define MALLOC(_size) ExAllocatePool(0, _size) +#define _FREE(_ptr) ExFreePool(_ptr) + #else - return EngAllocMem( 0, size, 'D3AG' ); + +#define MALLOC( SIZE ) malloc( SIZE ) +#define CALLOC( COUNT, SIZE ) calloc( COUNT, SIZE ) +#define FREE( PTR ) free( PTR ) +#define REALLOC( OLDPTR, OLDSIZE, NEWSIZE ) realloc( OLDPTR, NEWSIZE ) + #endif -} + +#ifndef CALLOC static INLINE void * CALLOC( unsigned count, unsigned size ) { @@ -88,20 +104,19 @@ CALLOC( unsigned count, unsigned size ) } return ptr; } +#endif /* !CALLOC */ +#ifndef FREE static INLINE void FREE( void *ptr ) { if( ptr ) { -#ifdef WINCE - /* TODO: Need to abstract this */ - free( ptr ); -#else - EngFreeMem( ptr ); -#endif + _FREE( ptr ); } } +#endif /* !FREE */ +#ifndef REALLOC static INLINE void * REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) { @@ -118,19 +133,8 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) FREE( old_ptr ); return new_ptr; } +#endif /* !REALLOC */ -#else /* !PIPE_SUBSYSTEM_WINDOWS_DISPLAY */ - -#define MALLOC( SIZE ) malloc( SIZE ) - -#define CALLOC( COUNT, SIZE ) calloc( COUNT, SIZE ) - -#define FREE( PTR ) free( PTR ) - -#define REALLOC( OLDPTR, OLDSIZE, NEWSIZE ) realloc( OLDPTR, NEWSIZE ) - -#endif /* !PIPE_SUBSYSTEM_WINDOWS_DISPLAY */ -#endif /* !DEBUG */ #define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T)) -- cgit v1.2.3 From dadb11f5d96354975f1c9f7c8134bb4727129249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 1 May 2008 03:43:19 +0900 Subject: gallium: Fix release build. --- src/gallium/auxiliary/util/p_debug.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 56eecaab62..f1fb07bf5b 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -413,6 +413,7 @@ char *pf_sprint_name( char *str, enum pipe_format format ) } +#ifdef DEBUG void debug_print_format(const char *msg, unsigned fmt ) { char fmtstr[80]; @@ -421,3 +422,4 @@ void debug_print_format(const char *msg, unsigned fmt ) debug_printf("%s: %s\n", msg, fmtstr); } +#endif \ No newline at end of file -- cgit v1.2.3 From 026e31a068981724fb0c98f6d1fc87d086fd2da6 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 30 Apr 2008 02:04:28 -0400 Subject: try to fix the deleting of the bound cso during cleanup of the hash --- src/gallium/auxiliary/cso_cache/cso_cache.c | 40 ++++++-- src/gallium/auxiliary/cso_cache/cso_cache.h | 28 ++++-- src/gallium/auxiliary/cso_cache/cso_context.c | 128 ++++++++++++++++++++++++++ 3 files changed, 178 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index 096875807b..36dc46ff80 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -43,6 +43,9 @@ struct cso_cache { struct cso_hash *rasterizer_hash; struct cso_hash *sampler_hash; int max_size; + + cso_sanitize_callback sanitize_cb; + void *sanitize_data; }; #if 1 @@ -205,8 +208,19 @@ static INLINE void delete_cso(void *state, enum cso_cache_type type) } } -static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type, + +static INLINE void sanitize_hash(struct cso_cache *sc, + struct cso_hash *hash, + enum cso_cache_type type, int max_size) +{ + if (sc->sanitize_cb) + sc->sanitize_cb(hash, type, max_size, sc->sanitize_data); +} + + +static INLINE void sanitize_cb(struct cso_hash *hash, enum cso_cache_type type, + int max_size, void *user_data) { /* if we're approach the maximum size, remove fourth of the entries * otherwise every subsequent call will go through the same */ @@ -231,7 +245,7 @@ cso_insert_state(struct cso_cache *sc, void *state) { struct cso_hash *hash = _cso_hash_for_type(sc, type); - sanitize_hash(hash, type, sc->max_size); + sanitize_hash(sc, hash, type, sc->max_size); return cso_hash_insert(hash, hash_key, state); } @@ -300,6 +314,8 @@ struct cso_cache *cso_cache_create(void) sc->rasterizer_hash = cso_hash_create(); sc->fs_hash = cso_hash_create(); sc->vs_hash = cso_hash_create(); + sc->sanitize_cb = sanitize_cb; + sc->sanitize_data = 0; return sc; } @@ -365,13 +381,13 @@ void cso_set_maximum_cache_size(struct cso_cache *sc, int number) { sc->max_size = number; - sanitize_hash(sc->blend_hash, CSO_BLEND, sc->max_size); - sanitize_hash(sc->depth_stencil_hash, CSO_DEPTH_STENCIL_ALPHA, + sanitize_hash(sc, sc->blend_hash, CSO_BLEND, sc->max_size); + sanitize_hash(sc, sc->depth_stencil_hash, CSO_DEPTH_STENCIL_ALPHA, sc->max_size); - sanitize_hash(sc->fs_hash, CSO_FRAGMENT_SHADER, sc->max_size); - sanitize_hash(sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size); - sanitize_hash(sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size); - sanitize_hash(sc->sampler_hash, CSO_SAMPLER, sc->max_size); + sanitize_hash(sc, sc->fs_hash, CSO_FRAGMENT_SHADER, sc->max_size); + sanitize_hash(sc, sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size); + sanitize_hash(sc, sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size); + sanitize_hash(sc, sc->sampler_hash, CSO_SAMPLER, sc->max_size); } int cso_maximum_cache_size(const struct cso_cache *sc) @@ -379,3 +395,11 @@ int cso_maximum_cache_size(const struct cso_cache *sc) return sc->max_size; } +void cso_cache_set_sanitize_callback(struct cso_cache *sc, + cso_sanitize_callback cb, + void *user_data) +{ + sc->sanitize_cb = cb; + sc->sanitize_data = user_data; +} + diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h index e5edbbb556..6b5c230e8f 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.h +++ b/src/gallium/auxiliary/cso_cache/cso_cache.h @@ -84,8 +84,22 @@ extern "C" { #endif +enum cso_cache_type { + CSO_BLEND, + CSO_SAMPLER, + CSO_DEPTH_STENCIL_ALPHA, + CSO_RASTERIZER, + CSO_FRAGMENT_SHADER, + CSO_VERTEX_SHADER +}; + typedef void (*cso_state_callback)(void *ctx, void *obj); +typedef void (*cso_sanitize_callback)(struct cso_hash *hash, + enum cso_cache_type type, + int max_size, + void *user_data); + struct cso_cache; struct cso_blend { @@ -130,21 +144,15 @@ struct cso_sampler { struct pipe_context *context; }; - -enum cso_cache_type { - CSO_BLEND, - CSO_SAMPLER, - CSO_DEPTH_STENCIL_ALPHA, - CSO_RASTERIZER, - CSO_FRAGMENT_SHADER, - CSO_VERTEX_SHADER -}; - unsigned cso_construct_key(void *item, int item_size); struct cso_cache *cso_cache_create(void); void cso_cache_delete(struct cso_cache *sc); +void cso_cache_set_sanitize_callback(struct cso_cache *sc, + cso_sanitize_callback cb, + void *user_data); + struct cso_hash_iter cso_insert_state(struct cso_cache *sc, unsigned hash_key, enum cso_cache_type type, void *state); diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index b4609e999b..eef898f486 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -80,6 +80,131 @@ struct cso_context { }; +static boolean delete_blend_state(struct cso_context *ctx, void *state) +{ + struct cso_blend *cso = (struct cso_blend *)state; + + if (ctx->blend == state) + return FALSE; + + if (cso->delete_state) + cso->delete_state(cso->context, cso->data); + FREE(state); + return TRUE; +} + +static boolean delete_depth_stencil_state(struct cso_context *ctx, void *state) +{ + struct cso_depth_stencil_alpha *cso = (struct cso_depth_stencil_alpha *)state; + + if (ctx->depth_stencil == cso->data) + return FALSE; + + if (cso->delete_state) + cso->delete_state(cso->context, cso->data); + FREE(state); + + return TRUE; +} + +static boolean delete_sampler_state(struct cso_context *ctx, void *state) +{ + struct cso_sampler *cso = (struct cso_sampler *)state; + if (cso->delete_state) + cso->delete_state(cso->context, cso->data); + FREE(state); + return TRUE; +} + +static boolean delete_rasterizer_state(struct cso_context *ctx, void *state) +{ + struct cso_rasterizer *cso = (struct cso_rasterizer *)state; + + if (ctx->rasterizer == cso->data) + return FALSE; + if (cso->delete_state) + cso->delete_state(cso->context, cso->data); + FREE(state); + return TRUE; +} + +static boolean delete_fs_state(struct cso_context *ctx, void *state) +{ + struct cso_fragment_shader *cso = (struct cso_fragment_shader *)state; + if (ctx->fragment_shader == cso->data) + return FALSE; + if (cso->delete_state) + cso->delete_state(cso->context, cso->data); + FREE(state); + return TRUE; +} + +static boolean delete_vs_state(struct cso_context *ctx, void *state) +{ + struct cso_vertex_shader *cso = (struct cso_vertex_shader *)state; + if (ctx->vertex_shader == cso->data) + return TRUE; + if (cso->delete_state) + cso->delete_state(cso->context, cso->data); + FREE(state); + return FALSE; +} + + +static INLINE boolean delete_cso(struct cso_context *ctx, + void *state, enum cso_cache_type type) +{ + switch (type) { + case CSO_BLEND: + return delete_blend_state(ctx, state); + break; + case CSO_SAMPLER: + return delete_sampler_state(ctx, state); + break; + case CSO_DEPTH_STENCIL_ALPHA: + return delete_depth_stencil_state(ctx, state); + break; + case CSO_RASTERIZER: + return delete_rasterizer_state(ctx, state); + break; + case CSO_FRAGMENT_SHADER: + return delete_fs_state(ctx, state); + break; + case CSO_VERTEX_SHADER: + return delete_vs_state(ctx, state); + break; + default: + assert(0); + FREE(state); + } + return FALSE; +} + +static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type, + int max_size, void *user_data) +{ + struct cso_context *ctx = (struct cso_context *)user_data; + /* if we're approach the maximum size, remove fourth of the entries + * otherwise every subsequent call will go through the same */ + int hash_size = cso_hash_size(hash); + int max_entries = (max_size > hash_size) ? max_size : hash_size; + int to_remove = (max_size < max_entries) * max_entries/4; + struct cso_hash_iter iter = cso_hash_first_node(hash); + if (hash_size > max_size) + to_remove += hash_size - max_size; + while (to_remove) { + /*remove elements until we're good */ + /*fixme: currently we pick the nodes to remove at random*/ + void *cso = cso_hash_iter_data(iter); + if (delete_cso(ctx, cso, type)) { + iter = cso_hash_erase(hash, iter); + --to_remove; + } else + iter = cso_hash_iter_next(iter); + } +} + + struct cso_context *cso_create_context( struct pipe_context *pipe ) { struct cso_context *ctx = CALLOC_STRUCT(cso_context); @@ -89,6 +214,9 @@ struct cso_context *cso_create_context( struct pipe_context *pipe ) ctx->cache = cso_cache_create(); if (ctx->cache == NULL) goto out; + cso_cache_set_sanitize_callback(ctx->cache, + sanitize_hash, + ctx); ctx->pipe = pipe; -- cgit v1.2.3 From 653da2d0698d18a8d3dcad1b1590437dee7bb403 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 30 Apr 2008 14:05:49 -0400 Subject: plug a memleak, destroy setup context --- src/gallium/drivers/softpipe/sp_prim_setup.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index feb35d492a..1cf9ffa632 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -150,6 +150,8 @@ static void reset_stipple_counter( struct draw_stage *stage ) static void render_destroy( struct draw_stage *stage ) { + struct setup_stage *ssetup = setup_stage(stage); + setup_destroy_context(ssetup->setup); FREE( stage ); } -- cgit v1.2.3 From bd5b99d3890f162ec0928a589b6afbc8e67580b7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 30 Apr 2008 13:24:35 -0600 Subject: gallium: fix typo: s/custam/custom/ --- src/gallium/include/pipe/p_defines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 586951d956..d5d341d689 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -192,7 +192,7 @@ enum pipe_texture_target { #define PIPE_BUFFER_USAGE_VERTEX (1 << 5) #define PIPE_BUFFER_USAGE_INDEX (1 << 6) #define PIPE_BUFFER_USAGE_CONSTANT (1 << 7) -/** Pipe driver custam usage flags should be greater or equal to this value */ +/** Pipe driver custom usage flags should be greater or equal to this value */ #define PIPE_BUFFER_USAGE_CUSTOM (1 << 16) -- cgit v1.2.3 From 18f4d962653cdbb76f08e8498fbbec6e1759f21e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 30 Apr 2008 16:41:53 -0600 Subject: gallium: replace old PIPE_FORMAT_U_S8 with PIPE_FORMAT_S8_UNORM --- src/gallium/drivers/softpipe/sp_quad_stencil.c | 4 ++-- src/gallium/drivers/softpipe/sp_tile_cache.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad_stencil.c b/src/gallium/drivers/softpipe/sp_quad_stencil.c index 92a0da0083..b4c7e942fa 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stencil.c +++ b/src/gallium/drivers/softpipe/sp_quad_stencil.c @@ -243,7 +243,7 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) stencilVals[j] = tile->data.depth32[y][x] & 0xff; } break; - case PIPE_FORMAT_U_S8: + case PIPE_FORMAT_S8_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); int y = quad->y0 % TILE_SIZE + (j >> 1); @@ -311,7 +311,7 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) tile->data.depth32[y][x] = z24s8; } break; - case PIPE_FORMAT_U_S8: + case PIPE_FORMAT_S8_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); int y = quad->y0 % TILE_SIZE + (j >> 1); diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index edafd93d8b..a88aad5d09 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -168,7 +168,7 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || ps->format == PIPE_FORMAT_Z16_UNORM || ps->format == PIPE_FORMAT_Z32_UNORM || - ps->format == PIPE_FORMAT_U_S8); + ps->format == PIPE_FORMAT_S8_UNORM); } } -- cgit v1.2.3 From 8d45576ec5110d39fe48c2f65b04db16ce845968 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 30 Apr 2008 16:49:38 -0600 Subject: gallium: rename old PIPE_FORMAT_U_I8 with PIPE_FORMAT_I8_UNORM, etc. Now all the packed color types are consistantly named. Added temporary #defines for the old names until all drivers are updated. --- src/gallium/include/pipe/p_format.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index bc23fe142e..e32212d36c 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -238,10 +238,10 @@ enum pipe_format { PIPE_FORMAT_A1R5G5B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 1, 5, 5, 5, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_A4R4G4B4_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_R5G6B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_RGB1, 5, 6, 5, 0, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_U_L8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte luminance */ - PIPE_FORMAT_U_A8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_000R, 0, 0, 0, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha */ - PIPE_FORMAT_U_I8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRR, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte intensity */ - PIPE_FORMAT_U_A8_L8 = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha, luminance */ + PIPE_FORMAT_L8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte luminance */ + PIPE_FORMAT_A8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_000R, 0, 0, 0, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha */ + PIPE_FORMAT_I8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRR, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte intensity */ + PIPE_FORMAT_A8L8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha, luminance */ PIPE_FORMAT_YCBCR = _PIPE_FORMAT_YCBCR( 0 ), PIPE_FORMAT_YCBCR_REV = _PIPE_FORMAT_YCBCR( 1 ), PIPE_FORMAT_Z16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), @@ -327,11 +327,12 @@ enum pipe_format { }; -/** - * Unsigned 8-bit stencil format. - * XXX should remove this, but S8_UNORM is a poor name - */ -#define PIPE_FORMAT_U_S8 PIPE_FORMAT_S8_UNORM +/** XXX remove these deprecated names */ +#define PIPE_FORMAT_U_L8 PIPE_FORMAT_L8_UNORM +#define PIPE_FORMAT_U_A8 PIPE_FORMAT_A8_UNORM +#define PIPE_FORMAT_U_I8 PIPE_FORMAT_I8_UNORM +#define PIPE_FORMAT_U_A8_L8 PIPE_FORMAT_A8L8_UNORM +#define PIPE_FORMAT_U_S8 PIPE_FORMAT_S8_UNORM /** -- cgit v1.2.3 From 54f94a790e4488445347abcff9a636a9c440d7f9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 30 Apr 2008 16:50:17 -0600 Subject: gallium: use the newer PIPE_FORMAT_x_UNORM format names --- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 2 +- src/gallium/auxiliary/util/p_tile.c | 24 +++++++++++----------- src/gallium/auxiliary/util/u_gen_mipmap.c | 8 ++++---- src/gallium/drivers/i915simple/i915_screen.c | 8 ++++---- .../drivers/i915simple/i915_state_sampler.c | 8 ++++---- src/gallium/drivers/i965simple/brw_screen.c | 24 +++++++++++----------- .../drivers/i965simple/brw_wm_surface_state.c | 8 ++++---- 8 files changed, 42 insertions(+), 42 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index f05641dee6..f501b2aed4 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -392,7 +392,7 @@ aaline_create_texture(struct aaline_stage *aaline) memset(&texTemp, 0, sizeof(texTemp)); texTemp.target = PIPE_TEXTURE_2D; - texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ + texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */ texTemp.last_level = MAX_TEXTURE_LEVEL; texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL; texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL; diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index d1d63d73be..c4de9d2698 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -417,7 +417,7 @@ pstip_create_texture(struct pstip_stage *pstip) memset(&texTemp, 0, sizeof(texTemp)); texTemp.target = PIPE_TEXTURE_2D; - texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ + texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */ texTemp.last_level = 0; texTemp.width[0] = 32; texTemp.height[0] = 32; diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 13175ca46e..63e1cc6013 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -385,7 +385,7 @@ z16_get_tile_rgba(ushort *src, -/*** PIPE_FORMAT_U_L8 ***/ +/*** PIPE_FORMAT_L8_UNORM ***/ static void l8_get_tile_rgba(ubyte *src, @@ -408,7 +408,7 @@ l8_get_tile_rgba(ubyte *src, } -/*** PIPE_FORMAT_U_A8 ***/ +/*** PIPE_FORMAT_A8_UNORM ***/ static void a8_get_tile_rgba(ubyte *src, @@ -476,7 +476,7 @@ r16g16b16a16_put_tile_rgba(short *dst, -/*** PIPE_FORMAT_U_I8 ***/ +/*** PIPE_FORMAT_I8_UNORM ***/ static void i8_get_tile_rgba(ubyte *src, @@ -499,7 +499,7 @@ i8_get_tile_rgba(ubyte *src, } -/*** PIPE_FORMAT_U_A8_L8 ***/ +/*** PIPE_FORMAT_A8L8_UNORM ***/ static void a8_l8_get_tile_rgba(ushort *src, @@ -708,16 +708,16 @@ pipe_get_tile_rgba(struct pipe_context *pipe, case PIPE_FORMAT_R5G6B5_UNORM: r5g6b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); break; - case PIPE_FORMAT_U_L8: + case PIPE_FORMAT_L8_UNORM: l8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); break; - case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_A8_UNORM: a8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); break; - case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_I8_UNORM: i8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); break; - case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_A8L8_UNORM: a8_l8_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); break; case PIPE_FORMAT_R16G16B16A16_SNORM: @@ -787,16 +787,16 @@ pipe_put_tile_rgba(struct pipe_context *pipe, break; case PIPE_FORMAT_R8G8B8A8_UNORM: break; - case PIPE_FORMAT_U_L8: + case PIPE_FORMAT_L8_UNORM: /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ break; - case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_A8_UNORM: /*a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ break; - case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_I8_UNORM: /*i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ break; - case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_A8L8_UNORM: /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ break; case PIPE_FORMAT_R16G16B16A16_SNORM: diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index b8dc6c66c0..0348629ab8 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -493,13 +493,13 @@ format_to_type_comps(enum pipe_format pformat, *datatype = USHORT_5_6_5; *comps = 3; return; - case PIPE_FORMAT_U_L8: - case PIPE_FORMAT_U_A8: - case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: *datatype = UBYTE; *comps = 1; return; - case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_A8L8_UNORM: *datatype = UBYTE; *comps = 2; return; diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 9ae594ce54..631642e1b6 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -154,10 +154,10 @@ i915_is_format_supported( struct pipe_screen *screen, PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_R5G6B5_UNORM, - PIPE_FORMAT_U_L8, - PIPE_FORMAT_U_A8, - PIPE_FORMAT_U_I8, - PIPE_FORMAT_U_A8_L8, + PIPE_FORMAT_L8_UNORM, + PIPE_FORMAT_A8_UNORM, + PIPE_FORMAT_I8_UNORM, + PIPE_FORMAT_A8L8_UNORM, PIPE_FORMAT_YCBCR, PIPE_FORMAT_YCBCR_REV, PIPE_FORMAT_S8Z24_UNORM, diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c index 84f6529a3a..982eec4a1b 100644 --- a/src/gallium/drivers/i915simple/i915_state_sampler.c +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -131,13 +131,13 @@ static uint translate_texture_format(enum pipe_format pipeFormat) { switch (pipeFormat) { - case PIPE_FORMAT_U_L8: + case PIPE_FORMAT_L8_UNORM: return MAPSURF_8BIT | MT_8BIT_L8; - case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_I8_UNORM: return MAPSURF_8BIT | MT_8BIT_I8; - case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_A8_UNORM: return MAPSURF_8BIT | MT_8BIT_A8; - case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_A8L8_UNORM: return MAPSURF_16BIT | MT_16BIT_AY88; case PIPE_FORMAT_R5G6B5_UNORM: return MAPSURF_16BIT | MT_16BIT_RGB565; diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c index 6845c7abde..b700f7e4f5 100644 --- a/src/gallium/drivers/i965simple/brw_screen.c +++ b/src/gallium/drivers/i965simple/brw_screen.c @@ -141,13 +141,13 @@ brw_is_format_supported( struct pipe_screen *screen, #if 0 /* XXX: This is broken -- rewrite if still needed. */ static const unsigned tex_supported[] = { - PIPE_FORMAT_U_R8_G8_B8_A8, - PIPE_FORMAT_U_A8_R8_G8_B8, - PIPE_FORMAT_U_R5_G6_B5, - PIPE_FORMAT_U_L8, - PIPE_FORMAT_U_A8, - PIPE_FORMAT_U_I8, - PIPE_FORMAT_U_L8_A8, + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_L8_UNORM, + PIPE_FORMAT_A8_UNORM, + PIPE_FORMAT_I8_UNORM, + PIPE_FORMAT_L8A8_UNORM, PIPE_FORMAT_YCBCR, PIPE_FORMAT_YCBCR_REV, PIPE_FORMAT_S8_Z24, @@ -157,16 +157,16 @@ brw_is_format_supported( struct pipe_screen *screen, /* Actually a lot more than this - add later: */ static const unsigned render_supported[] = { - PIPE_FORMAT_U_A8_R8_G8_B8, - PIPE_FORMAT_U_R5_G6_B5, + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_R5G6B5_UNORM, }; /* */ static const unsigned z_stencil_supported[] = { - PIPE_FORMAT_U_Z16, - PIPE_FORMAT_U_Z32, - PIPE_FORMAT_S8_Z24, + PIPE_FORMAT_Z16_UNORM, + PIPE_FORMAT_Z32_UNORM, + PIPE_FORMAT_S8Z24_UNORM, }; switch (type) { diff --git a/src/gallium/drivers/i965simple/brw_wm_surface_state.c b/src/gallium/drivers/i965simple/brw_wm_surface_state.c index 853c743ccf..69e56dc8bd 100644 --- a/src/gallium/drivers/i965simple/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965simple/brw_wm_surface_state.c @@ -57,16 +57,16 @@ static unsigned translate_tex_target( enum pipe_texture_target target ) static unsigned translate_tex_format( enum pipe_format pipe_format ) { switch( pipe_format ) { - case PIPE_FORMAT_U_L8: + case PIPE_FORMAT_L8_UNORM: return BRW_SURFACEFORMAT_L8_UNORM; - case PIPE_FORMAT_U_I8: + case PIPE_FORMAT_I8_UNORM: return BRW_SURFACEFORMAT_I8_UNORM; - case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_A8_UNORM: return BRW_SURFACEFORMAT_A8_UNORM; - case PIPE_FORMAT_U_A8_L8: + case PIPE_FORMAT_A8L8_UNORM: return BRW_SURFACEFORMAT_L8A8_UNORM; case PIPE_FORMAT_R8G8B8_UNORM: -- cgit v1.2.3 From c9ed86a96483063f3d6789ed16645a3dca77d726 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 11:07:21 +0100 Subject: gallium: tex surface checkpoint --- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 12 ++-- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 15 +++-- src/gallium/auxiliary/util/p_tile.c | 50 ++++++++++---- src/gallium/auxiliary/util/u_blit.c | 3 +- src/gallium/auxiliary/util/u_gen_mipmap.c | 21 ++++-- src/gallium/drivers/failover/fo_context.c | 2 +- src/gallium/drivers/i915simple/i915_screen.c | 31 +++++++++ src/gallium/drivers/i915simple/i915_surface.c | 23 +++++-- src/gallium/drivers/i915simple/i915_texture.c | 13 ++-- src/gallium/drivers/i965simple/brw_surface.c | 51 ++++++--------- src/gallium/drivers/i965simple/brw_tex_layout.c | 2 +- src/gallium/drivers/softpipe/sp_context.c | 6 +- src/gallium/drivers/softpipe/sp_draw_arrays.c | 6 +- src/gallium/drivers/softpipe/sp_flush.c | 35 +++++----- src/gallium/drivers/softpipe/sp_screen.c | 22 ++++--- src/gallium/drivers/softpipe/sp_surface.c | 23 +++++-- src/gallium/drivers/softpipe/sp_texture.c | 87 ++++++++++++++++++------- src/gallium/drivers/softpipe/sp_texture.h | 1 - src/gallium/drivers/softpipe/sp_tile_cache.c | 36 ++++++---- src/gallium/drivers/softpipe/sp_tile_cache.h | 2 +- src/gallium/include/pipe/p_context.h | 6 -- src/gallium/include/pipe/p_inlines.h | 31 ++++----- src/gallium/include/pipe/p_screen.h | 17 ++++- src/gallium/include/pipe/p_state.h | 4 ++ src/gallium/include/pipe/p_util.h | 3 + src/gallium/include/pipe/p_winsys.h | 2 +- src/gallium/winsys/xlib/xm_winsys.c | 2 + 27 files changed, 328 insertions(+), 178 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index f501b2aed4..6dc20f2c90 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -415,8 +415,11 @@ aaline_create_texture(struct aaline_stage *aaline) assert(aaline->texture->width[level] == aaline->texture->height[level]); - surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0); - data = pipe_surface_map(surface); + /* This texture is new, no need to flush. + */ + surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + data = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE); if (data == NULL) return FALSE; @@ -440,9 +443,8 @@ aaline_create_texture(struct aaline_stage *aaline) } /* unmap */ - pipe_surface_unmap(surface); - pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, aaline->texture, 0, (1 << level)); + screen->surface_unmap(screen, surface); + screen->tex_surface_release(screen, &surface); } return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index c4de9d2698..3aa326acc7 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -376,8 +376,14 @@ pstip_update_texture(struct pstip_stage *pstip) uint i, j; ubyte *data; - surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0); - data = pipe_surface_map(surface); + /* XXX: want to avoid flushing just because we use stipple: + */ + pipe->flush( pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL ); + + surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + data = screen->surface_map(screen, surface, + PIPE_BUFFER_USAGE_CPU_WRITE); /* * Load alpha texture. @@ -399,9 +405,8 @@ pstip_update_texture(struct pstip_stage *pstip) } /* unmap */ - pipe_surface_unmap(surface); - pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, pstip->texture, 0, 0x1); + screen->surface_unmap(screen, surface); + screen->tex_surface_release(screen, &surface); } diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 63e1cc6013..5728757d2f 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -50,6 +50,7 @@ pipe_get_tile_raw(struct pipe_context *pipe, uint x, uint y, uint w, uint h, void *p, int dst_stride) { + struct pipe_screen *screen = pipe->screen; const uint cpp = ps->cpp; const ubyte *pSrc; const uint src_stride = ps->pitch * cpp; @@ -63,7 +64,11 @@ pipe_get_tile_raw(struct pipe_context *pipe, if (pipe_clip_tile(x, y, &w, &h, ps)) return; - pSrc = (const ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; + pSrc = (const ubyte *) screen->surface_map(screen, ps, + PIPE_BUFFER_USAGE_CPU_READ); + assert(pSrc); /* XXX: proper error handling! */ + + pSrc += (y * ps->pitch + x) * cpp; pDest = (ubyte *) p; for (i = 0; i < h; i++) { @@ -72,7 +77,7 @@ pipe_get_tile_raw(struct pipe_context *pipe, pSrc += src_stride; } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } @@ -86,6 +91,7 @@ pipe_put_tile_raw(struct pipe_context *pipe, uint x, uint y, uint w, uint h, const void *p, int src_stride) { + struct pipe_screen *screen = pipe->screen; const uint cpp = ps->cpp; const ubyte *pSrc; const uint dst_stride = ps->pitch * cpp; @@ -100,7 +106,11 @@ pipe_put_tile_raw(struct pipe_context *pipe, return; pSrc = (const ubyte *) p; - pDest = (ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; + + pDest = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + assert(pDest); /* XXX: proper error handling */ + + pDest += (y * ps->pitch + x) * cpp; for (i = 0; i < h; i++) { memcpy(pDest, pSrc, w * cpp); @@ -108,7 +118,7 @@ pipe_put_tile_raw(struct pipe_context *pipe, pSrc += src_stride; } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } @@ -834,18 +844,26 @@ pipe_get_tile_z(struct pipe_context *pipe, uint x, uint y, uint w, uint h, uint *z) { + struct pipe_screen *screen = pipe->screen; const uint dstStride = w; + void *map; uint *pDest = z; uint i, j; if (pipe_clip_tile(x, y, &w, &h, ps)) return; + map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + if (!map) { + assert(0); + return; + } + switch (ps->format) { case PIPE_FORMAT_Z32_UNORM: { const uint *pSrc - = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + = (const uint *)map + (y * ps->pitch + x); for (i = 0; i < h; i++) { memcpy(pDest, pSrc, 4 * w); pDest += dstStride; @@ -857,7 +875,7 @@ pipe_get_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_X8Z24_UNORM: { const uint *pSrc - = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + = (const uint *)map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 24-bit Z to 32-bit Z */ @@ -871,7 +889,7 @@ pipe_get_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_Z16_UNORM: { const ushort *pSrc - = (const ushort *) pipe_surface_map(ps) + (y * ps->pitch + x); + = (const ushort *)map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 16-bit Z to 32-bit Z */ @@ -886,7 +904,7 @@ pipe_get_tile_z(struct pipe_context *pipe, assert(0); } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } @@ -896,17 +914,25 @@ pipe_put_tile_z(struct pipe_context *pipe, uint x, uint y, uint w, uint h, const uint *zSrc) { + struct pipe_screen *screen = pipe->screen; const uint srcStride = w; const uint *pSrc = zSrc; + void *map; uint i, j; if (pipe_clip_tile(x, y, &w, &h, ps)) return; + map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + if (!map) { + assert(0); + return; + } + switch (ps->format) { case PIPE_FORMAT_Z32_UNORM: { - uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + uint *pDest = (uint *) map + (y * ps->pitch + x); for (i = 0; i < h; i++) { memcpy(pDest, pSrc, 4 * w); pDest += ps->pitch; @@ -917,7 +943,7 @@ pipe_put_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: { - uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + uint *pDest = (uint *) map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 24-bit Z (0 stencil) */ @@ -930,7 +956,7 @@ pipe_put_tile_z(struct pipe_context *pipe, break; case PIPE_FORMAT_Z16_UNORM: { - ushort *pDest = (ushort *) pipe_surface_map(ps) + (y * ps->pitch + x); + ushort *pDest = (ushort *) map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 16-bit Z */ @@ -945,7 +971,7 @@ pipe_put_tile_z(struct pipe_context *pipe, assert(0); } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 9e9912c6e4..257473ab26 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -287,7 +287,8 @@ util_blit_pixels(struct blit_state *ctx, if (!tex) return; - texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0); + texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); /* load temp texture */ pipe->surface_copy(pipe, FALSE, diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 0348629ab8..6ed5503c9a 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -586,8 +586,11 @@ make_1d_mipmap(struct gen_mipmap_state *ctx, struct pipe_surface *srcSurf, *dstSurf; void *srcMap, *dstMap; - srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice); - dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice, + PIPE_BUFFER_USAGE_CPU_READ); + + dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice, + PIPE_BUFFER_USAGE_CPU_WRITE); srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer, PIPE_BUFFER_USAGE_CPU_READ) @@ -626,8 +629,10 @@ make_2d_mipmap(struct gen_mipmap_state *ctx, struct pipe_surface *srcSurf, *dstSurf; ubyte *srcMap, *dstMap; - srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice); - dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice, + PIPE_BUFFER_USAGE_CPU_READ); + dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice, + PIPE_BUFFER_USAGE_CPU_WRITE); srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer, PIPE_BUFFER_USAGE_CPU_READ) @@ -888,10 +893,14 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { const uint srcLevel = dstLevel - 1; + struct pipe_surface *surf = + screen->get_tex_surface(screen, pt, face, dstLevel, zslice, + PIPE_BUFFER_USAGE_GPU_WRITE); + /* * Setup framebuffer / dest surface */ - fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + fb.cbufs[0] = surf; fb.width = pt->width[dstLevel]; fb.height = pt->height[dstLevel]; cso_set_framebuffer(ctx->cso, &fb); @@ -922,7 +931,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* need to signal that the texture has changed _after_ rendering to it */ - pipe->texture_update(pipe, pt, face, (1 << dstLevel)); + pipe_surface_reference( &surf, NULL ); } /* restore state we changed */ diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index cb95ba516f..014a3e31d5 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -147,8 +147,8 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover->pipe.texture_create = hw->texture_create; failover->pipe.texture_release = hw->texture_release; failover->pipe.get_tex_surface = hw->get_tex_surface; -#endif failover->pipe.texture_update = hw->texture_update; +#endif failover->pipe.flush = hw->flush; diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 631642e1b6..dcd349e478 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -200,6 +200,35 @@ i915_destroy_screen( struct pipe_screen *screen ) } +static void * +i915_surface_map( struct pipe_screen *screen, + struct pipe_surface *surface, + unsigned flags ) +{ + char *map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags ); + if (map == NULL) + return NULL; + + if (surface->texture && + (flags & PIPE_BUFFER_USAGE_CPU_WRITE)) + { + /* Do something to notify contexts of a texture change. + */ + /* i915_screen(screen)->timestamp++; */ + } + + return map + surface->offset; +} + +static void +i915_surface_unmap(struct pipe_screen *screen, + struct pipe_surface *surface) +{ + screen->winsys->buffer_unmap( screen->winsys, surface->buffer ); +} + + + /** * Create a new i915_screen object */ @@ -243,6 +272,8 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id) i915screen->screen.get_param = i915_get_param; i915screen->screen.get_paramf = i915_get_paramf; i915screen->screen.is_format_supported = i915_is_format_supported; + i915screen->screen.surface_map = i915_surface_map; + i915screen->screen.surface_unmap = i915_surface_unmap; i915_init_screen_texture_functions(&i915screen->screen); diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index f4fbedbe9b..98367ac073 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -51,17 +51,25 @@ i915_surface_copy(struct pipe_context *pipe, assert( dst->cpp == src->cpp ); if (0) { - pipe_copy_rect(pipe_surface_map(dst), + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + + const void *src_map = pipe->screen->surface_map( pipe->screen, + src, + PIPE_BUFFER_USAGE_CPU_READ ); + + pipe_copy_rect(dst_map, dst->cpp, dst->pitch, dstx, dsty, width, height, - pipe_surface_map(src), + src_map, do_flip ? -(int) src->pitch : src->pitch, srcx, do_flip ? 1 - srcy - height : srcy); - pipe_surface_unmap(src); - pipe_surface_unmap(dst); + pipe->screen->surface_unmap(pipe->screen, src); + pipe->screen->surface_unmap(pipe->screen, dst); } else { i915_copy_blit( i915_context(pipe), @@ -92,7 +100,10 @@ i915_surface_fill(struct pipe_context *pipe, { if (0) { unsigned i, j; - void *dst_map = pipe_surface_map(dst); + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + switch (dst->cpp) { case 1: { @@ -126,7 +137,7 @@ i915_surface_fill(struct pipe_context *pipe, break; } - pipe_surface_unmap( dst ); + pipe->screen->surface_unmap(pipe->screen, dst); } else { i915_fill_blit( i915_context(pipe), diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index c39e747705..7b9359a0fe 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -541,13 +541,6 @@ i915_texture_release_screen(struct pipe_screen *screen, } -static void -i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, - uint face, uint levelsMask) -{ - /* no-op? */ -} - /* * XXX note: same as code in sp_surface.c @@ -555,7 +548,8 @@ i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, static struct pipe_surface * i915_get_tex_surface_screen(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) + unsigned face, unsigned level, unsigned zslice, + unsigned flags) { struct i915_texture *tex = (struct i915_texture *)pt; struct pipe_winsys *ws = screen->winsys; @@ -586,6 +580,7 @@ i915_get_tex_surface_screen(struct pipe_screen *screen, ps->height = pt->height[level]; ps->pitch = tex->pitch; ps->offset = offset; + ps->usage = flags; } return ps; } @@ -594,7 +589,7 @@ i915_get_tex_surface_screen(struct pipe_screen *screen, void i915_init_texture_functions(struct i915_context *i915) { - i915->pipe.texture_update = i915_texture_update; +// i915->pipe.texture_update = i915_texture_update; } diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index c99a91dcf7..3e3736b280 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -35,27 +35,6 @@ #include "util/p_tile.h" -/* Upload data to a rectangular sub-region. Lots of choices how to do this: - * - * - memcpy by span to current destination - * - upload data as new buffer and blit - * - * Currently always memcpy. - */ -static void -brw_surface_data(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - const void *src, unsigned src_pitch, - unsigned srcx, unsigned srcy, unsigned width, unsigned height) -{ - pipe_copy_rect(pipe_surface_map(dst) + dst->offset, - dst->cpp, dst->pitch, - dstx, dsty, width, height, src, src_pitch, srcx, srcy); - - pipe_surface_unmap(dst); -} - /* Assumes all values are within bounds -- no checking at this level - * do it higher up if required. @@ -72,17 +51,25 @@ brw_surface_copy(struct pipe_context *pipe, assert(dst->cpp == src->cpp); if (0) { - pipe_copy_rect(pipe_surface_map(dst) + dst->offset, + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + + const void *src_map = pipe->screen->surface_map( pipe->screen, + src, + PIPE_BUFFER_USAGE_CPU_READ ); + + pipe_copy_rect(dst_map, dst->cpp, dst->pitch, - dstx, dsty, - width, height, - pipe_surface_map(src) + src->offset, - do_flip ? -src->pitch : src->pitch, + dstx, dsty, + width, height, + src_map, + do_flip ? -(int) src->pitch : src->pitch, srcx, do_flip ? 1 - srcy - height : srcy); - pipe_surface_unmap(src); - pipe_surface_unmap(dst); + pipe->screen->surface_unmap(pipe->screen, src); + pipe->screen->surface_unmap(pipe->screen, dst); } else { brw_copy_blit(brw_context(pipe), @@ -113,7 +100,10 @@ brw_surface_fill(struct pipe_context *pipe, { if (0) { unsigned i, j; - void *dst_map = pipe_surface_map(dst); + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + switch (dst->cpp) { case 1: { @@ -147,7 +137,7 @@ brw_surface_fill(struct pipe_context *pipe, break; } - pipe_surface_unmap( dst ); + pipe->screen->surface_unmap(pipe->screen, dst); } else { brw_fill_blit(brw_context(pipe), @@ -164,7 +154,6 @@ brw_surface_fill(struct pipe_context *pipe, void brw_init_surface_functions(struct brw_context *brw) { - (void) brw_surface_data; /* silence warning */ brw->pipe.surface_copy = brw_surface_copy; brw->pipe.surface_fill = brw_surface_fill; } diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index b580f98204..ba4c4a7bcf 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -407,7 +407,7 @@ brw_get_tex_surface_screen(struct pipe_screen *screen, void brw_init_texture_functions(struct brw_context *brw) { - brw->pipe.texture_update = brw_texture_update; +// brw->pipe.texture_update = brw_texture_update; } diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index edf91ecafa..ee74826763 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -192,11 +192,11 @@ softpipe_create( struct pipe_screen *screen, * Must be before quad stage setup! */ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - softpipe->cbuf_cache[i] = sp_create_tile_cache(); - softpipe->zsbuf_cache = sp_create_tile_cache(); + softpipe->cbuf_cache[i] = sp_create_tile_cache( screen ); + softpipe->zsbuf_cache = sp_create_tile_cache( screen ); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - softpipe->tex_cache[i] = sp_create_tile_cache(); + softpipe->tex_cache[i] = sp_create_tile_cache( screen ); /* setup quad rendering stages */ diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 6c58f9909d..355c120d18 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -50,7 +50,7 @@ softpipe_map_constant_buffers(struct softpipe_context *sp) for (i = 0; i < 2; i++) { if (sp->constants[i].size) sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_BUFFER_USAGE_GPU_READ); } draw_set_mapped_constant_buffer(sp->draw, @@ -133,14 +133,14 @@ softpipe_draw_elements(struct pipe_context *pipe, void *buf = pipe->winsys->buffer_map(pipe->winsys, sp->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_BUFFER_USAGE_GPU_READ); draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { void *mapped_indexes = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_BUFFER_USAGE_GPU_READ); draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); } else { diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 0625b69099..e03994b63b 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -50,25 +50,28 @@ softpipe_flush( struct pipe_context *pipe, draw_flush(softpipe->draw); - /* - flush the quad pipeline - * - flush the texture cache - * - flush the render cache - */ + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + for (i = 0; i < softpipe->num_textures; i++) { + sp_flush_tile_cache(softpipe, softpipe->tex_cache[i]); + } + } - for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) - if (softpipe->cbuf_cache[i]) - sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]); + if (flags & PIPE_FLUSH_RENDER_CACHE) { + for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) + if (softpipe->cbuf_cache[i]) + sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]); - if (softpipe->zsbuf_cache) - sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache); + if (softpipe->zsbuf_cache) + sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache); - /* Need this call for hardware buffers before swapbuffers. - * - * there should probably be another/different flush-type function - * that's called before swapbuffers because we don't always want - * to unmap surfaces when flushing. - */ - softpipe_unmap_surfaces(softpipe); + /* Need this call for hardware buffers before swapbuffers. + * + * there should probably be another/different flush-type function + * that's called before swapbuffers because we don't always want + * to unmap surfaces when flushing. + */ + softpipe_unmap_surfaces(softpipe); + } if (fence) *fence = NULL; diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 7dacb1c461..e9926bf41f 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -33,6 +33,7 @@ #include "sp_texture.h" #include "sp_winsys.h" +#include "sp_screen.h" static const char * @@ -137,6 +138,7 @@ softpipe_destroy_screen( struct pipe_screen *screen ) } + /** * Create a new pipe_screen object * Note: we're not presently subclassing pipe_screen (no softpipe_screen). @@ -144,22 +146,22 @@ softpipe_destroy_screen( struct pipe_screen *screen ) struct pipe_screen * softpipe_create_screen(struct pipe_winsys *winsys) { - struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen); + struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen); if (!screen) return NULL; - screen->winsys = winsys; + screen->base.winsys = winsys; - screen->destroy = softpipe_destroy_screen; + screen->base.destroy = softpipe_destroy_screen; - screen->get_name = softpipe_get_name; - screen->get_vendor = softpipe_get_vendor; - screen->get_param = softpipe_get_param; - screen->get_paramf = softpipe_get_paramf; - screen->is_format_supported = softpipe_is_format_supported; + screen->base.get_name = softpipe_get_name; + screen->base.get_vendor = softpipe_get_vendor; + screen->base.get_param = softpipe_get_param; + screen->base.get_paramf = softpipe_get_paramf; + screen->base.is_format_supported = softpipe_is_format_supported; - softpipe_init_screen_texture_funcs(screen); + softpipe_init_screen_texture_funcs(&screen->base); - return screen; + return &screen->base; } diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index 653449c4f1..b5cc053548 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -47,18 +47,27 @@ sp_surface_copy(struct pipe_context *pipe, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { assert( dst->cpp == src->cpp ); + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_GPU_WRITE ); - pipe_copy_rect(pipe_surface_map(dst), + const void *src_map = pipe->screen->surface_map( pipe->screen, + src, + PIPE_BUFFER_USAGE_GPU_READ ); + + assert(src_map && dst_map); + + pipe_copy_rect(dst_map, dst->cpp, dst->pitch, dstx, dsty, width, height, - pipe_surface_map(src), + src_map, do_flip ? -(int) src->pitch : src->pitch, srcx, do_flip ? 1 - srcy - height : srcy); - pipe_surface_unmap(src); - pipe_surface_unmap(dst); + pipe->screen->surface_unmap(pipe->screen, src); + pipe->screen->surface_unmap(pipe->screen, dst); } @@ -83,7 +92,9 @@ sp_surface_fill(struct pipe_context *pipe, unsigned width, unsigned height, unsigned value) { unsigned i, j; - void *dst_map = pipe_surface_map(dst); + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_GPU_WRITE ); assert(dst->pitch > 0); assert(width <= dst->pitch); @@ -147,7 +158,7 @@ sp_surface_fill(struct pipe_context *pipe, break; } - pipe_surface_unmap( dst ); + pipe->screen->surface_unmap(pipe->screen, dst); } diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 256586ec88..ee3fa994f9 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -40,6 +40,7 @@ #include "sp_state.h" #include "sp_texture.h" #include "sp_tile_cache.h" +#include "sp_screen.h" /* Simple, maximally packed layout. @@ -116,19 +117,10 @@ softpipe_texture_release(struct pipe_screen *screen, if (!*pt) return; - /* - DBG("%s %p refcount will be %d\n", - __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); - */ if (--(*pt)->refcount <= 0) { struct softpipe_texture *spt = softpipe_texture(*pt); - /* - DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); - */ - pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); - FREE(spt); } *pt = NULL; @@ -138,7 +130,8 @@ softpipe_texture_release(struct pipe_screen *screen, static struct pipe_surface * softpipe_get_tex_surface(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) + unsigned face, unsigned level, unsigned zslice, + unsigned usage) { struct pipe_winsys *ws = screen->winsys; struct softpipe_texture *spt = softpipe_texture(pt); @@ -157,6 +150,7 @@ softpipe_get_tex_surface(struct pipe_screen *screen, ps->height = pt->height[level]; ps->pitch = ps->width; ps->offset = spt->level_offset[level]; + ps->usage = usage; if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * @@ -167,30 +161,74 @@ softpipe_get_tex_surface(struct pipe_screen *screen, assert(face == 0); assert(zslice == 0); } + + if (usage & (PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_WRITE)) { + /* XXX if writing to the texture, invalidate the texcache entries!!! */ + assert(0); + } } return ps; } -static void -softpipe_texture_update(struct pipe_context *pipe, - struct pipe_texture *texture, - uint face, uint levelsMask) +static void +softpipe_tex_surface_release(struct pipe_screen *screen, + struct pipe_surface **s) { - struct softpipe_context *softpipe = softpipe_context(pipe); - uint unit; - for (unit = 0; unit < softpipe->num_textures; unit++) { - if (softpipe->texture[unit] == texture) { - sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); - } + /* Effectively do the texture_update work here - if texture images + * needed post-processing to put them into hardware layout, this is + * where it would happen. For softpipe, nothing to do. + */ + assert ((*s)->texture); + + screen->winsys->surface_release(screen->winsys, s); +} + + +static void * +softpipe_surface_map( struct pipe_screen *screen, + struct pipe_surface *surface, + unsigned flags ) +{ + ubyte *map; + + if (flags & ~surface->usage) { + assert(0); + return NULL; + } + + map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags ); + if (map == NULL) + return NULL; + + /* May want to different things here depending on read/write nature + * of the map: + */ + if (surface->texture && + (flags & PIPE_BUFFER_USAGE_GPU_WRITE)) + { + /* Do something to notify sharing contexts of a texture change. + * In softpipe, that would mean flushing the texture cache. + */ + softpipe_screen(screen)->timestamp++; } + + return map + surface->offset; +} + + +static void +softpipe_surface_unmap(struct pipe_screen *screen, + struct pipe_surface *surface) +{ + screen->winsys->buffer_unmap( screen->winsys, surface->buffer ); } void -softpipe_init_texture_funcs( struct softpipe_context *softpipe ) +softpipe_init_texture_funcs(struct softpipe_context *sp) { - softpipe->pipe.texture_update = softpipe_texture_update; } @@ -199,5 +237,10 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = softpipe_texture_create; screen->texture_release = softpipe_texture_release; + screen->get_tex_surface = softpipe_get_tex_surface; + screen->tex_surface_release = softpipe_tex_surface_release; + + screen->surface_map = softpipe_surface_map; + screen->surface_unmap = softpipe_surface_unmap; } diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index a7322144e6..2ba093320d 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -61,7 +61,6 @@ softpipe_texture(struct pipe_texture *pt) extern void softpipe_init_texture_funcs( struct softpipe_context *softpipe ); - extern void softpipe_init_screen_texture_funcs(struct pipe_screen *screen); diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index a88aad5d09..a3fd375a2d 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -49,6 +49,7 @@ struct softpipe_tile_cache { + struct pipe_screen *screen; struct pipe_surface *surface; /**< the surface we're caching */ void *surface_map; struct pipe_texture *texture; /**< if caching a texture */ @@ -109,13 +110,14 @@ clear_clear_flag(uint *bitvec, int x, int y) struct softpipe_tile_cache * -sp_create_tile_cache(void) +sp_create_tile_cache( struct pipe_screen *screen ) { struct softpipe_tile_cache *tc; uint pos; tc = CALLOC_STRUCT( softpipe_tile_cache ); if (tc) { + tc->screen = screen; for (pos = 0; pos < NUM_ENTRIES; pos++) { tc->entries[pos].x = tc->entries[pos].y = -1; @@ -154,16 +156,17 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, assert(!tc->texture); if (tc->surface_map) { - /*assert(tc->surface != ps);*/ - pipe_surface_unmap(tc->surface); + tc->screen->surface_unmap(tc->screen, tc->surface); tc->surface_map = NULL; } pipe_surface_reference(&tc->surface, ps); - if (ps) { - if (tc->surface_map) - tc->surface_map = pipe_surface_map(ps); + if (tc->surface) { + if (tc->surface_map) /* XXX: this is always NULL!? */ + tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || ps->format == PIPE_FORMAT_Z16_UNORM || @@ -187,10 +190,13 @@ void sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc) { if (tc->surface && !tc->surface_map) - tc->surface_map = pipe_surface_map(tc->surface); + tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface, + PIPE_BUFFER_USAGE_GPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ); if (tc->tex_surf && !tc->tex_surf_map) - tc->tex_surf_map = pipe_surface_map(tc->tex_surf); + tc->tex_surf_map = tc->screen->surface_map(tc->screen, tc->tex_surf, + PIPE_BUFFER_USAGE_GPU_READ); } @@ -198,12 +204,12 @@ void sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc) { if (tc->surface_map) { - pipe_surface_unmap(tc->surface); + tc->screen->surface_unmap(tc->screen, tc->surface); tc->surface_map = NULL; } if (tc->tex_surf_map) { - pipe_surface_unmap(tc->tex_surf); + tc->screen->surface_unmap(tc->screen, tc->tex_surf); tc->tex_surf_map = NULL; } } @@ -224,7 +230,7 @@ sp_tile_cache_set_texture(struct pipe_context *pipe, pipe_texture_reference(&tc->texture, texture); if (tc->tex_surf_map) { - pipe_surface_unmap(tc->tex_surf); + tc->screen->surface_unmap(tc->screen, tc->tex_surf); tc->tex_surf_map = NULL; } pipe_surface_reference(&tc->tex_surf, NULL); @@ -514,10 +520,12 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, /* get new surface (view into texture) */ if (tc->tex_surf_map) - pipe_surface_unmap(tc->tex_surf); + tc->screen->surface_unmap(tc->screen, tc->tex_surf); - tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z); - tc->tex_surf_map = pipe_surface_map(tc->tex_surf); + tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z, + PIPE_BUFFER_USAGE_GPU_READ); + tc->tex_surf_map = screen->surface_map(screen, tc->tex_surf, + PIPE_BUFFER_USAGE_GPU_READ); tc->tex_face = face; tc->tex_level = level; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 2631e29a3a..bc96c941f6 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -61,7 +61,7 @@ struct softpipe_cached_tile extern struct softpipe_tile_cache * -sp_create_tile_cache(void); +sp_create_tile_cache( struct pipe_screen *screen ); extern void sp_destroy_tile_cache(struct softpipe_tile_cache *tc); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index f3a9c2cd8b..0f68f592f7 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -198,12 +198,6 @@ struct pipe_context { /*@}*/ - /** Called when texture data is changed */ - void (*texture_update)(struct pipe_context *pipe, - struct pipe_texture *texture, - uint face, uint dirtyLevelsMask); - - /** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */ void (*flush)( struct pipe_context *pipe, unsigned flags, diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index 8eb604e73f..592c3c87c2 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -39,20 +39,6 @@ extern "C" { #endif -static INLINE void * -pipe_surface_map(struct pipe_surface *surface) -{ - return (char *)surface->winsys->buffer_map( surface->winsys, surface->buffer, - PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_CPU_READ ) - + surface->offset; -} - -static INLINE void -pipe_surface_unmap(struct pipe_surface *surface) -{ - surface->winsys->buffer_unmap( surface->winsys, surface->buffer ); -} /** * Set 'ptr' to point to 'surf' and update reference counting. @@ -66,9 +52,20 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) if (surf) surf->refcount++; - if (*ptr /* && --(*ptr)->refcount == 0 */) { - struct pipe_winsys *winsys = (*ptr)->winsys; - winsys->surface_release(winsys, ptr); + if (*ptr) { + + /* There are currently two sorts of surfaces... This needs to be + * fixed so that all surfaces are views into a texture. + */ + if ((*ptr)->texture) { + struct pipe_screen *screen = (*ptr)->texture->screen; + screen->tex_surface_release( screen, ptr ); + } + else { + struct pipe_winsys *winsys = (*ptr)->winsys; + winsys->surface_release(winsys, ptr); + } + assert(!*ptr); } diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 26ac99d287..c080579c26 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -96,7 +96,22 @@ struct pipe_screen { struct pipe_surface *(*get_tex_surface)(struct pipe_screen *, struct pipe_texture *texture, unsigned face, unsigned level, - unsigned zslice); + unsigned zslice, + unsigned usage ); + + /* Surfaces allocated by the above must be released here: + */ + void (*tex_surface_release)( struct pipe_screen *, + struct pipe_surface ** ); + + + void *(*surface_map)( struct pipe_screen *, + struct pipe_surface *surface, + unsigned flags ); + + void (*surface_unmap)( struct pipe_screen *, + struct pipe_surface *surface ); + }; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 912d84e7b9..62b05a403b 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -273,7 +273,11 @@ struct pipe_surface unsigned pitch; /**< in pixels */ unsigned offset; /**< offset from start of buffer, in bytes */ unsigned refcount; + unsigned usage; /**< PIPE_BUFFER_USAGE_* */ + struct pipe_winsys *winsys; /**< winsys which owns/created the surface */ + + struct pipe_texture *texture; /**< optional texture into which this is a view */ }; diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 0e7e246666..0d8ed167b2 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -204,7 +204,10 @@ mem_dup(const void *src, uint size) #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) #define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) +#ifndef Elements #define Elements(x) (sizeof(x)/sizeof((x)[0])) +#endif + #define Offset(TYPE, MEMBER) ((unsigned)&(((TYPE *)NULL)->MEMBER)) /** diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index 3005ec2d94..87a66b66d7 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -90,7 +90,7 @@ struct pipe_winsys void (*surface_release)(struct pipe_winsys *ws, struct pipe_surface **s); - + /** * Buffer management. Buffer attributes are mostly fixed over its lifetime. * diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 8a89278cde..fd2f56eff2 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -508,6 +508,7 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, surf->format = format; surf->cpp = pf_get_size(format); surf->pitch = round_up(width, alignment / surf->cpp); + surf->usage = flags; #ifdef GALLIUM_CELL /* XXX a bit of a hack */ height = round_up(height, TILE_SIZE); @@ -562,6 +563,7 @@ static void xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) { struct pipe_surface *surf = *s; + assert(!surf->texture); surf->refcount--; if (surf->refcount == 0) { if (surf->buffer) -- cgit v1.2.3 From 27e46611f04108765fa99890822a474820d5c563 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 11:28:47 +0100 Subject: softpipe: use CPU flags for mapping But when creating surfaces, adjust incoming flags from GPU->CPU usage. --- src/gallium/drivers/softpipe/sp_draw_arrays.c | 6 ++--- src/gallium/drivers/softpipe/sp_surface.c | 6 ++--- src/gallium/drivers/softpipe/sp_texture.c | 34 ++++++++++++++++++++++++--- src/gallium/drivers/softpipe/sp_tile_cache.c | 14 +++++------ 4 files changed, 44 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 355c120d18..6c58f9909d 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -50,7 +50,7 @@ softpipe_map_constant_buffers(struct softpipe_context *sp) for (i = 0; i < 2; i++) { if (sp->constants[i].size) sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, - PIPE_BUFFER_USAGE_GPU_READ); + PIPE_BUFFER_USAGE_CPU_READ); } draw_set_mapped_constant_buffer(sp->draw, @@ -133,14 +133,14 @@ softpipe_draw_elements(struct pipe_context *pipe, void *buf = pipe->winsys->buffer_map(pipe->winsys, sp->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_GPU_READ); + PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { void *mapped_indexes = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, - PIPE_BUFFER_USAGE_GPU_READ); + PIPE_BUFFER_USAGE_CPU_READ); draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); } else { diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index b5cc053548..b82b1a8f37 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -49,11 +49,11 @@ sp_surface_copy(struct pipe_context *pipe, assert( dst->cpp == src->cpp ); void *dst_map = pipe->screen->surface_map( pipe->screen, dst, - PIPE_BUFFER_USAGE_GPU_WRITE ); + PIPE_BUFFER_USAGE_CPU_WRITE ); const void *src_map = pipe->screen->surface_map( pipe->screen, src, - PIPE_BUFFER_USAGE_GPU_READ ); + PIPE_BUFFER_USAGE_CPU_READ ); assert(src_map && dst_map); @@ -94,7 +94,7 @@ sp_surface_fill(struct pipe_context *pipe, unsigned i, j; void *dst_map = pipe->screen->surface_map( pipe->screen, dst, - PIPE_BUFFER_USAGE_GPU_WRITE ); + PIPE_BUFFER_USAGE_CPU_WRITE ); assert(dst->pitch > 0); assert(width <= dst->pitch); diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index ee3fa994f9..2b31cd4f25 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -151,6 +151,23 @@ softpipe_get_tex_surface(struct pipe_screen *screen, ps->pitch = ps->width; ps->offset = spt->level_offset[level]; ps->usage = usage; + + /* Because we are softpipe, anything that the state tracker + * thought was going to be done with the GPU will actually get + * done with the CPU. Let's adjust the flags to take that into + * account. + */ + if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) + ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE; + + if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) + ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; + + + pipe_texture_reference(&ps->texture, pt); + ps->face = face; + ps->level = level; + ps->zslice = zslice; if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * @@ -164,8 +181,18 @@ softpipe_get_tex_surface(struct pipe_screen *screen, if (usage & (PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_GPU_WRITE)) { - /* XXX if writing to the texture, invalidate the texcache entries!!! */ - assert(0); + /* XXX if writing to the texture, invalidate the texcache entries!!! + * + * Actually, no. Flushing dependent contexts is still done + * explicitly and separately. Hardware drivers won't insert + * FLUSH commands into a command stream at this point, + * neither should softpipe try to flush caches. + * + * Those contexts could be living in separate threads & doing + * all sorts of unrelated stuff... Context<->texture + * dependency tracking needs to happen elsewhere. + */ + /* assert(0); */ } } return ps; @@ -181,6 +208,7 @@ softpipe_tex_surface_release(struct pipe_screen *screen, * where it would happen. For softpipe, nothing to do. */ assert ((*s)->texture); + pipe_texture_reference(&(*s)->texture, NULL); screen->winsys->surface_release(screen->winsys, s); } @@ -206,7 +234,7 @@ softpipe_surface_map( struct pipe_screen *screen, * of the map: */ if (surface->texture && - (flags & PIPE_BUFFER_USAGE_GPU_WRITE)) + (flags & PIPE_BUFFER_USAGE_CPU_WRITE)) { /* Do something to notify sharing contexts of a texture change. * In softpipe, that would mean flushing the texture cache. diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index a3fd375a2d..142faf5074 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -165,8 +165,8 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, if (tc->surface) { if (tc->surface_map) /* XXX: this is always NULL!? */ tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface, - PIPE_BUFFER_USAGE_GPU_READ | - PIPE_BUFFER_USAGE_GPU_WRITE); + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || ps->format == PIPE_FORMAT_Z16_UNORM || @@ -191,12 +191,12 @@ sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc) { if (tc->surface && !tc->surface_map) tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface, - PIPE_BUFFER_USAGE_GPU_WRITE | - PIPE_BUFFER_USAGE_GPU_READ); + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_CPU_READ); if (tc->tex_surf && !tc->tex_surf_map) tc->tex_surf_map = tc->screen->surface_map(tc->screen, tc->tex_surf, - PIPE_BUFFER_USAGE_GPU_READ); + PIPE_BUFFER_USAGE_CPU_READ); } @@ -523,9 +523,9 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, tc->screen->surface_unmap(tc->screen, tc->tex_surf); tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z, - PIPE_BUFFER_USAGE_GPU_READ); + PIPE_BUFFER_USAGE_CPU_READ); tc->tex_surf_map = screen->surface_map(screen, tc->tex_surf, - PIPE_BUFFER_USAGE_GPU_READ); + PIPE_BUFFER_USAGE_CPU_READ); tc->tex_face = face; tc->tex_level = level; -- cgit v1.2.3 From 228aaa6cab9ebb32eb23b85fc8a5f05c1dbe975a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 12:21:48 +0100 Subject: softpipe: missing file --- src/gallium/drivers/softpipe/sp_screen.h | 58 ++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/gallium/drivers/softpipe/sp_screen.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_screen.h b/src/gallium/drivers/softpipe/sp_screen.h new file mode 100644 index 0000000000..3d4bfd3e84 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_screen.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_SCREEN_H +#define SP_SCREEN_H + +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" + + + +struct softpipe_screen { + struct pipe_screen base; + + /* Increments whenever textures are modified. Contexts can track + * this. + */ + unsigned timestamp; +}; + + + + +static INLINE struct softpipe_screen * +softpipe_screen( struct pipe_screen *pipe ) +{ + return (struct softpipe_screen *)pipe; +} + + +#endif /* SP_SCREEN_H */ -- cgit v1.2.3 From b59f9c95c1f7aca60c5d6889d4dc388d19fbc3e1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 12:28:50 +0100 Subject: gallium: add information to surface to identify which texture image it is pointing at --- src/gallium/include/pipe/p_state.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 62b05a403b..47e57e2957 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -278,6 +278,9 @@ struct pipe_surface struct pipe_winsys *winsys; /**< winsys which owns/created the surface */ struct pipe_texture *texture; /**< optional texture into which this is a view */ + unsigned face; + unsigned level; + unsigned zslice; }; -- cgit v1.2.3 From 4584c0efbd547559d30ba9a5e76549fc1b679619 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 13:47:09 +0100 Subject: draw: turn on SSE swizzle code --- src/gallium/auxiliary/draw/draw_vs_sse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 90926aec85..07f85bc448 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -47,7 +47,7 @@ #include "tgsi/util/tgsi_parse.h" #define SSE_MAX_VERTICES 4 -#define SSE_SWIZZLES 0 +#define SSE_SWIZZLES 1 #if SSE_SWIZZLES typedef void (XSTDCALL *codegen_function) ( -- cgit v1.2.3 From be7e1297f4d5a2c2949968bea428b4c0e7c75d63 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 13:47:27 +0100 Subject: draw: squash warnings --- src/gallium/auxiliary/draw/draw_pt_varray.c | 1 - src/gallium/auxiliary/draw/draw_pt_vcache.c | 1 - 2 files changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index c85d8ded50..355093f945 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -200,7 +200,6 @@ static void varray_prepare(struct draw_pt_front_end *frontend, unsigned opt) { struct varray_frontend *varray = (struct varray_frontend *)frontend; - const struct pipe_rasterizer_state *rasterizer = varray->draw->rasterizer; if (opt & PT_PIPELINE) { diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 2f9775814f..6b3fb1406b 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -225,7 +225,6 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, unsigned opt ) { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; - const struct pipe_rasterizer_state *rasterizer = vcache->draw->rasterizer; if (opt & PT_PIPELINE) { -- cgit v1.2.3 From c6fadd9fade40e3397f56fdbfa2325861799e49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 1 May 2008 10:20:31 +0900 Subject: gallium: Add newline to eof. --- src/gallium/auxiliary/util/p_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index f1fb07bf5b..4ec1746662 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -422,4 +422,4 @@ void debug_print_format(const char *msg, unsigned fmt ) debug_printf("%s: %s\n", msg, fmtstr); } -#endif \ No newline at end of file +#endif -- cgit v1.2.3 From 073bb94a4150d7b3c78ea5420383cb7ed8f97566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 1 May 2008 21:52:05 +0900 Subject: Add Brian's explanation for inheritance in C. --- src/gallium/README.portability | 65 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/README.portability b/src/gallium/README.portability index ab0c197847..18a97f449b 100644 --- a/src/gallium/README.portability +++ b/src/gallium/README.portability @@ -24,6 +24,7 @@ headers in general, should stricly follow these guidelines to ensure * Don't use variable number of macro arguments. Use static inline functions instead. +* Don't use C99 features. = Standard Library = @@ -42,3 +43,67 @@ portable way. * Use the functions/macros in p_debug.h. * Don't include assert.h, call abort, printf, etc. + + += Code Style = + +== Inherantice in C == + +The main thing we do is mimic inheritance by structure containment. + +Here's a silly made-up example: + +/* base class */ +struct buffer +{ + int size; + void (*validate)(struct buffer *buf); +}; + +/* sub-class of bufffer */ +struct texture_buffer +{ + struct buffer base; /* the base class, MUST COME FIRST! */ + int format; + int width, height; +}; + + +Then, we'll typically have cast-wrapper functions to convert base-class +pointers to sub-class pointers where needed: + +static inline struct vertex_buffer *vertex_buffer(struct buffer *buf) +{ + return (struct vertex_buffer *) buf; +} + + +To create/init a sub-classed object: + +struct buffer *create_texture_buffer(int w, int h, int format) +{ + struct texture_buffer *t = malloc(sizeof(*t)); + t->format = format; + t->width = w; + t->height = h; + t->base.size = w * h; + t->base.validate = tex_validate; + return &t->base; +} + +Example sub-class method: + +void tex_validate(struct buffer *buf) +{ + struct texture_buffer *tb = texture_buffer(buf); + assert(tb->format); + assert(tb->width); + assert(tb->height); +} + + +Note that we typically do not use typedefs to make "class names"; we use +'struct whatever' everywhere. + +Gallium's pipe_context and the subclassed psb_context, etc are prime examples +of this. There's also many examples in Mesa and the Mesa state tracker. -- cgit v1.2.3 From 35b0efb8c6afd319ae36e99aa578ac6c75faf2f5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 14:19:25 +0100 Subject: gallium: do something sensible on the error path to try to avoid crashing in release builds --- src/gallium/auxiliary/util/u_gen_mipmap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 0348629ab8..2e8417ee13 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -505,6 +505,9 @@ format_to_type_comps(enum pipe_format pformat, return; default: assert(0); + *datatype = UBYTE; + *comps = 0; + break; } } -- cgit v1.2.3 From 1e4217e1b857c6a3c5da7d1eceb74683bf0b9a00 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 14:51:18 +0100 Subject: tgsi: use ESI instead of EBX on non-win32 platforms --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 1138f59997..4587b0930a 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -36,7 +36,7 @@ #ifdef PIPE_ARCH_X86 -#define HIGH_PRECISION 1 /* for 1/sqrt() */ +#define HIGH_PRECISION 0 /* for 1/sqrt() */ #define FOR_EACH_CHANNEL( CHAN )\ @@ -2038,12 +2038,12 @@ static void aos_to_soa( struct x86_function *func, uint aos, uint soa, uint num, unsigned char *inner_loop; soa_input = x86_make_reg( file_REG32, reg_AX ); - aos_input = x86_make_reg( file_REG32, reg_BX ); + aos_input = get_temp_base(); /* BX or SI */ num_inputs = x86_make_reg( file_REG32, reg_CX ); temp = x86_make_reg( file_REG32, reg_DX ); /* Save EBX */ - x86_push( func, x86_make_reg( file_REG32, reg_BX ) ); + x86_push( func, aos_input ); x86_mov( func, soa_input, get_argument( soa + 1 ) ); x86_mov( func, aos_input, get_argument( aos + 1 ) ); @@ -2088,7 +2088,7 @@ static void aos_to_soa( struct x86_function *func, uint aos, uint soa, uint num, x86_jcc( func, cc_NE, inner_loop ); /* Restore EBX */ - x86_pop( func, x86_make_reg( file_REG32, reg_BX ) ); + x86_pop( func, aos_input ); } static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, uint stride ) @@ -2100,12 +2100,12 @@ static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, unsigned char *inner_loop; soa_output = x86_make_reg( file_REG32, reg_AX ); - aos_output = x86_make_reg( file_REG32, reg_BX ); + aos_output = get_temp_base(); /* BX or SI */ num_outputs = x86_make_reg( file_REG32, reg_CX ); temp = x86_make_reg( file_REG32, reg_DX ); /* Save EBX */ - x86_push( func, x86_make_reg( file_REG32, reg_BX ) ); + x86_push( func, aos_output ); x86_mov( func, soa_output, get_argument( soa + 1 ) ); x86_mov( func, aos_output, get_argument( aos + 1 ) ); @@ -2150,7 +2150,7 @@ static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, x86_jcc( func, cc_NE, inner_loop ); /* Restore EBX */ - x86_pop( func, x86_make_reg( file_REG32, reg_BX ) ); + x86_pop( func, aos_output ); } /** -- cgit v1.2.3 From 7810e7f623a47978cdd1a167cc9e6b743d56d949 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 15:13:46 +0100 Subject: tgsi: use x86_fn_arg instead of get_argument() -- it knows about push/pops to the stack --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 63 ++++++++++++++++------------- 1 file changed, 34 insertions(+), 29 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 4587b0930a..5e133a9663 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -133,14 +133,6 @@ get_immediate_base( void ) * Data access helpers. */ -static struct x86_reg -get_argument( - unsigned index ) -{ - return x86_make_disp( - x86_make_reg( file_REG32, reg_SP ), - (index + 1) * 4 ); -} static struct x86_reg get_immediate( @@ -2045,14 +2037,14 @@ static void aos_to_soa( struct x86_function *func, uint aos, uint soa, uint num, /* Save EBX */ x86_push( func, aos_input ); - x86_mov( func, soa_input, get_argument( soa + 1 ) ); - x86_mov( func, aos_input, get_argument( aos + 1 ) ); - x86_mov( func, num_inputs, get_argument( num + 1 ) ); + x86_mov( func, soa_input, x86_fn_arg( func, soa ) ); + x86_mov( func, aos_input, x86_fn_arg( func, aos ) ); + x86_mov( func, num_inputs, x86_fn_arg( func, num ) ); /* do */ inner_loop = x86_get_label( func ); { - x86_mov( func, temp, get_argument( stride + 1 ) ); + x86_mov( func, temp, x86_fn_arg( func, stride ) ); x86_push( func, aos_input ); sse_movlps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); sse_movlps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); @@ -2107,9 +2099,9 @@ static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, /* Save EBX */ x86_push( func, aos_output ); - x86_mov( func, soa_output, get_argument( soa + 1 ) ); - x86_mov( func, aos_output, get_argument( aos + 1 ) ); - x86_mov( func, num_outputs, get_argument( num + 1 ) ); + x86_mov( func, soa_output, x86_fn_arg( func, soa ) ); + x86_mov( func, aos_output, x86_fn_arg( func, aos ) ); + x86_mov( func, num_outputs, x86_fn_arg( func, num ) ); /* do */ inner_loop = x86_get_label( func ); @@ -2126,7 +2118,7 @@ static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, sse_unpcklps( func, make_xmm( 3 ), make_xmm( 4 ) ); sse_unpckhps( func, make_xmm( 5 ), make_xmm( 4 ) ); - x86_mov( func, temp, get_argument( stride + 1 ) ); + x86_mov( func, temp, x86_fn_arg( func, stride ) ); x86_push( func, aos_output ); sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) ); sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) ); @@ -2185,6 +2177,13 @@ tgsi_emit_sse2( tgsi_parse_init( &parse, tokens ); + /* Can't just use EDI without save/restoring it: + */ + x86_push( + func, + get_immediate_base() ); + + /* * Different function args for vertex/fragment shaders: */ @@ -2193,51 +2192,51 @@ tgsi_emit_sse2( x86_mov( func, get_input_base(), - get_argument( 0 ) ); + x86_fn_arg( func, 1 ) ); /* skipping outputs argument here */ x86_mov( func, get_const_base(), - get_argument( 2 ) ); + x86_fn_arg( func, 3 ) ); x86_mov( func, get_temp_base(), - get_argument( 3 ) ); + x86_fn_arg( func, 4 ) ); x86_mov( func, get_coef_base(), - get_argument( 4 ) ); + x86_fn_arg( func, 5 ) ); x86_mov( func, get_immediate_base(), - get_argument( 5 ) ); + x86_fn_arg( func, 6 ) ); } else { assert(parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX); if (do_swizzles) - aos_to_soa( func, 5, 0, 6, 7 ); + aos_to_soa( func, 6, 1, 7, 8 ); x86_mov( func, get_input_base(), - get_argument( 0 ) ); + x86_fn_arg( func, 1 ) ); x86_mov( func, get_output_base(), - get_argument( 1 ) ); + x86_fn_arg( func, 2 ) ); x86_mov( func, get_const_base(), - get_argument( 2 ) ); + x86_fn_arg( func, 3 ) ); x86_mov( func, get_temp_base(), - get_argument( 3 ) ); + x86_fn_arg( func, 4 ) ); x86_mov( func, get_immediate_base(), - get_argument( 4 ) ); + x86_fn_arg( func, 5 ) ); } while( !tgsi_parse_end_of_tokens( &parse ) && ok ) { @@ -2260,7 +2259,7 @@ tgsi_emit_sse2( x86_mov( func, get_output_base(), - get_argument( 1 ) ); + x86_fn_arg( func, 2 ) ); } } @@ -2307,9 +2306,15 @@ tgsi_emit_sse2( if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) { if (do_swizzles) - soa_to_aos( func, 8, 1, 9, 10 ); + soa_to_aos( func, 9, 2, 10, 11 ); } + /* Can't just use EDI without save/restoring it: + */ + x86_pop( + func, + get_immediate_base() ); + #ifdef WIN32 emit_retw( func, 16 ); #else -- cgit v1.2.3 From 47aa416821b69d3afa33c79ec8cb8499688a0e8e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 15:27:53 +0100 Subject: tgsi: use EBX everywhere, be sure to push/pop it --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 5e133a9663..06df3dbb05 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -103,15 +103,9 @@ get_output_base( void ) static struct x86_reg get_temp_base( void ) { -#ifdef WIN32 return x86_make_reg( file_REG32, reg_BX ); -#else - return x86_make_reg( - file_REG32, - reg_SI ); -#endif } static struct x86_reg @@ -2177,12 +2171,16 @@ tgsi_emit_sse2( tgsi_parse_init( &parse, tokens ); - /* Can't just use EDI without save/restoring it: + /* Can't just use EDI, EBX without save/restoring them: */ x86_push( func, get_immediate_base() ); + x86_push( + func, + get_temp_base() ); + /* * Different function args for vertex/fragment shaders: @@ -2309,8 +2307,12 @@ tgsi_emit_sse2( soa_to_aos( func, 9, 2, 10, 11 ); } - /* Can't just use EDI without save/restoring it: + /* Can't just use EBX, EDI without save/restoring them: */ + x86_pop( + func, + get_temp_base() ); + x86_pop( func, get_immediate_base() ); -- cgit v1.2.3 From 6980823da9120d8d8533f7a78eac2d63dece430f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 15:30:50 +0100 Subject: draw: avoid aliasing warning --- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index c4de9d2698..54fdcc1a3b 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -256,7 +256,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, uint size = 4; immed = tgsi_default_full_immediate(); immed.Immediate.Size = 1 + size; /* one for the token itself */ - immed.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value; + immed.u.Pointer = value; ctx->emit_immediate(ctx, &immed); } -- cgit v1.2.3 From 727257f32002544658219d2e0163993c1cbc5644 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 15:31:17 +0100 Subject: rtasm: assert stack is fully popped in return --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index d7e2230557..40f6f973d6 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -495,6 +495,7 @@ void x86_dec( struct x86_function *p, void x86_ret( struct x86_function *p ) { DUMP(); + assert(p->stack_offset == 0); emit_1ub(p, 0xc3); } -- cgit v1.2.3 From afe67db8038855d9f7b4ce46b610701c55736c1f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 15:36:14 +0100 Subject: tgsi: add some const qualifiers to immediate pointers --- src/gallium/auxiliary/tgsi/util/tgsi_parse.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h index da0121c482..15e76feb7c 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h @@ -52,8 +52,8 @@ struct tgsi_full_immediate struct tgsi_immediate Immediate; union { - void *Pointer; - struct tgsi_immediate_float32 *ImmediateFloat32; + const void *Pointer; + const struct tgsi_immediate_float32 *ImmediateFloat32; } u; }; -- cgit v1.2.3 From 419f3c447520d1dc95c529afa693ffe3fffe5560 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 15:45:51 +0100 Subject: tgsi: restore HIGH_PRECISION setting --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 06df3dbb05..45453c34ce 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -36,7 +36,7 @@ #ifdef PIPE_ARCH_X86 -#define HIGH_PRECISION 0 /* for 1/sqrt() */ +#define HIGH_PRECISION 1 /* for 1/sqrt() */ #define FOR_EACH_CHANNEL( CHAN )\ -- cgit v1.2.3 From f1f52a8be98efa26c7c9bc480a2483fc2106d654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 1 May 2008 17:30:17 +0100 Subject: gallium: Notify driver of texture updates in util_blit_pixels(). --- src/gallium/auxiliary/util/u_blit.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 9e9912c6e4..568d62ced1 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -295,6 +295,8 @@ util_blit_pixels(struct blit_state *ctx, src, srcLeft, srcTop, /* src */ srcW, srcH); /* size */ + pipe->texture_update(pipe, tex, 0, 1 << 0); + /* save state (restored below) */ cso_save_blend(ctx->cso); cso_save_depth_stencil_alpha(ctx->cso); -- cgit v1.2.3 From 0000792a2006a2c8fde1b54d070490a625fb8435 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 18:48:28 +0100 Subject: sct: fix bug in remove_context_from_surface --- src/gallium/auxiliary/sct/sct.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/sct/sct.c b/src/gallium/auxiliary/sct/sct.c index 97ee5882a1..5e4126e014 100644 --- a/src/gallium/auxiliary/sct/sct.c +++ b/src/gallium/auxiliary/sct/sct.c @@ -209,6 +209,7 @@ remove_context_from_surface(struct sct_surface *si, } else { prev = curr; + next = curr->next; } } } -- cgit v1.2.3 From f30285e99c1e158971855b12331df3da38555004 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 18:49:07 +0100 Subject: softpipe: fix warning --- src/gallium/drivers/softpipe/sp_state_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 2921066ce3..9e77b7e91b 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -82,10 +82,9 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) void softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { - struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state = fs; - assert(fs != softpipe->fs); + assert(fs != softpipe_context(pipe)->fs); state->delete( state ); } -- cgit v1.2.3 From 26bcef898af4e6dfd578783ed33818a2bd38b06d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 18:49:52 +0100 Subject: i915: fix warning --- src/gallium/drivers/i915simple/i915_debug_fp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_debug_fp.c b/src/gallium/drivers/i915simple/i915_debug_fp.c index 37a3508fe1..c024a051a5 100644 --- a/src/gallium/drivers/i915simple/i915_debug_fp.c +++ b/src/gallium/drivers/i915simple/i915_debug_fp.c @@ -333,12 +333,11 @@ void i915_disassemble_program(struct debug_stream *stream, const unsigned * program, unsigned sz) { - unsigned size = program[0] & 0x1ff; unsigned i; PRINTF(stream, "\t\tBEGIN\n"); - assert(size + 2 == sz); + assert((program[0] & 0x1ff) + 2 == sz); program++; for (i = 1; i < sz; i += 3, program += 3) { -- cgit v1.2.3 From b8936ca1c22de7b0cb695ee3b392e4473fd17aa0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 18:50:33 +0100 Subject: i915: avoid crashing on bad parameter --- src/gallium/drivers/i915simple/i915_screen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 631642e1b6..646cfd921d 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -182,6 +182,7 @@ i915_is_format_supported( struct pipe_screen *screen, break; default: assert(0); + return FALSE; } for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { -- cgit v1.2.3 From fb3623b235f5caa9d76e656b1e5eda797c7c73eb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 20:41:03 +0100 Subject: rtasm: fix labels after (not so) recent change to allow dynamic fn growth Using char * for labels doesn't work if you realloc the function during assembly and free the old storage... --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 49 +++++++++---------------- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 14 +++---- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 4 +- src/gallium/auxiliary/translate/translate_sse.c | 2 +- 4 files changed, 28 insertions(+), 41 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 40f6f973d6..e69251f072 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -347,9 +347,9 @@ struct x86_reg x86_get_base_reg( struct x86_reg reg ) return x86_make_reg( reg.file, reg.idx ); } -unsigned char *x86_get_label( struct x86_function *p ) +int x86_get_label( struct x86_function *p ) { - return p->csr; + return p->csr - p->store; } @@ -361,17 +361,22 @@ unsigned char *x86_get_label( struct x86_function *p ) void x86_jcc( struct x86_function *p, enum x86_cc cc, - unsigned char *label ) + int label ) { - intptr_t offset = pointer_to_intptr( label ) - (pointer_to_intptr( x86_get_label(p) ) + 2); + int offset = label - (x86_get_label(p) + 2); DUMP_I(cc); + if (offset < 0) { + int amt = p->csr - p->store; + assert(amt > -offset); + } + if (offset <= 127 && offset >= -128) { emit_1ub(p, 0x70 + cc); emit_1b(p, (char) offset); } else { - offset = pointer_to_intptr( label ) - (pointer_to_intptr( x86_get_label(p) ) + 6); + offset = label - (x86_get_label(p) + 6); emit_2ub(p, 0x0f, 0x80 + cc); emit_1i(p, offset); } @@ -379,8 +384,8 @@ void x86_jcc( struct x86_function *p, /* Always use a 32bit offset for forward jumps: */ -unsigned char *x86_jcc_forward( struct x86_function *p, - enum x86_cc cc ) +int x86_jcc_forward( struct x86_function *p, + enum x86_cc cc ) { DUMP_I(cc); emit_2ub(p, 0x0f, 0x80 + cc); @@ -388,7 +393,7 @@ unsigned char *x86_jcc_forward( struct x86_function *p, return x86_get_label(p); } -unsigned char *x86_jmp_forward( struct x86_function *p) +int x86_jmp_forward( struct x86_function *p) { DUMP(); emit_1ub(p, 0xe9); @@ -396,7 +401,7 @@ unsigned char *x86_jmp_forward( struct x86_function *p) return x86_get_label(p); } -unsigned char *x86_call_forward( struct x86_function *p) +int x86_call_forward( struct x86_function *p) { DUMP(); @@ -408,42 +413,24 @@ unsigned char *x86_call_forward( struct x86_function *p) /* Fixup offset from forward jump: */ void x86_fixup_fwd_jump( struct x86_function *p, - unsigned char *fixup ) + int fixup ) { - *(int *)(fixup - 4) = pointer_to_intptr( x86_get_label(p) ) - pointer_to_intptr( fixup ); + *(int *)(p->store + fixup - 4) = x86_get_label(p) - fixup; } -void x86_jmp( struct x86_function *p, unsigned char *label) +void x86_jmp( struct x86_function *p, int label) { DUMP_I( label ); emit_1ub(p, 0xe9); - emit_1i(p, pointer_to_intptr( label ) - pointer_to_intptr( x86_get_label(p) ) - 4); -} - -#if 0 -static unsigned char *cptr( void (*label)() ) -{ - return (unsigned char *) label; + emit_1i(p, label - x86_get_label(p) - 4); } -/* This doesn't work once we start reallocating & copying the - * generated code on buffer fills, because the call is relative to the - * current pc. - */ -void x86_call( struct x86_function *p, void (*label)()) -{ - DUMP_I( label ); - emit_1ub(p, 0xe8); - emit_1i(p, cptr(label) - x86_get_label(p) - 4); -} -#else void x86_call( struct x86_function *p, struct x86_reg reg) { DUMP_R( reg ); emit_1ub(p, 0xff); emit_modrm_noreg(p, 2, reg); } -#endif /* michal: diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index ad79b1facf..eacaeeaf6f 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -124,23 +124,23 @@ struct x86_reg x86_get_base_reg( struct x86_reg reg ); /* Labels, jumps and fixup: */ -unsigned char *x86_get_label( struct x86_function *p ); +int x86_get_label( struct x86_function *p ); void x86_jcc( struct x86_function *p, enum x86_cc cc, - unsigned char *label ); + int label ); -unsigned char *x86_jcc_forward( struct x86_function *p, +int x86_jcc_forward( struct x86_function *p, enum x86_cc cc ); -unsigned char *x86_jmp_forward( struct x86_function *p); +int x86_jmp_forward( struct x86_function *p); -unsigned char *x86_call_forward( struct x86_function *p); +int x86_call_forward( struct x86_function *p); void x86_fixup_fwd_jump( struct x86_function *p, - unsigned char *fixup ); + int fixup ); -void x86_jmp( struct x86_function *p, unsigned char *label ); +void x86_jmp( struct x86_function *p, int label ); /* void x86_call( struct x86_function *p, void (*label)() ); */ void x86_call( struct x86_function *p, struct x86_reg reg); diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 45453c34ce..07db3292b4 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -2021,7 +2021,7 @@ static void aos_to_soa( struct x86_function *func, uint aos, uint soa, uint num, struct x86_reg aos_input; struct x86_reg num_inputs; struct x86_reg temp; - unsigned char *inner_loop; + int inner_loop; soa_input = x86_make_reg( file_REG32, reg_AX ); aos_input = get_temp_base(); /* BX or SI */ @@ -2083,7 +2083,7 @@ static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, struct x86_reg aos_output; struct x86_reg num_outputs; struct x86_reg temp; - unsigned char *inner_loop; + int inner_loop; soa_output = x86_make_reg( file_REG32, reg_AX ); aos_output = get_temp_base(); /* BX or SI */ diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index f590d48b78..a54ac5a82f 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -404,7 +404,7 @@ static boolean build_vertex_emit( struct translate_sse *p, struct x86_reg srcEAX = x86_make_reg(file_REG32, reg_CX); struct x86_reg countEBP = x86_make_reg(file_REG32, reg_BP); struct x86_reg translateESI = x86_make_reg(file_REG32, reg_SI); - uint8_t *fixup, *label; + int fixup, label; unsigned j; p->func = func; -- cgit v1.2.3 From 2004b8a769110456e66d040398eacf25c8592710 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 20:42:44 +0100 Subject: draw: label fn args -- shouldn't this be defined where the fn is created? --- src/gallium/auxiliary/draw/draw_vs_sse.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 07f85bc448..a57c938fbf 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -51,17 +51,17 @@ #if SSE_SWIZZLES typedef void (XSTDCALL *codegen_function) ( - const struct tgsi_exec_vector *input, - struct tgsi_exec_vector *output, - float (*constant)[4], - struct tgsi_exec_vector *temporary, - float (*immediates)[4], - const float (*aos_input)[4], - uint num_inputs, - uint input_stride, - float (*aos_output)[4], - uint num_outputs, - uint output_stride ); + const struct tgsi_exec_vector *input, /* 1 */ + struct tgsi_exec_vector *output, /* 2 */ + float (*constant)[4], /* 3 */ + struct tgsi_exec_vector *temporary, /* 4 */ + float (*immediates)[4], /* 5 */ + const float (*aos_input)[4], /* 6 */ + uint num_inputs, /* 7 */ + uint input_stride, /* 8 */ + float (*aos_output)[4], /* 9 */ + uint num_outputs, /* 10 */ + uint output_stride ); /* 11 */ #else typedef void (XSTDCALL *codegen_function) ( const struct tgsi_exec_vector *input, -- cgit v1.2.3 From 2c89b75e36fd35d5a003107d1d2f97b537321f95 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 20:44:41 +0100 Subject: rtasm: learn another version of push --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index e69251f072..4e036d9032 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -449,8 +449,15 @@ void x86_push( struct x86_function *p, struct x86_reg reg ) { DUMP_R( reg ); - assert(reg.mod == mod_REG); - emit_1ub(p, 0x50 + reg.idx); + if (reg.mod == mod_REG) + emit_1ub(p, 0x50 + reg.idx); + else + { + emit_1ub(p, 0xff); + emit_modrm_noreg(p, 6, reg); + } + + p->stack_offset += 4; } -- cgit v1.2.3 From f067c6c452bdd5f5cc6b0f6b2f79fb3fc1162822 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 20:45:15 +0100 Subject: tgsi: remove some bogus win vs. linux crud Pass arguments properly in linux now. Still need to change this to use a single calling convention on both platforms. --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 118 +++++++++++----------------- 1 file changed, 46 insertions(+), 72 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 07db3292b4..a67bc8567b 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -441,19 +441,13 @@ emit_push_gp( { x86_push( func, - get_const_base() ); + x86_make_reg( file_REG32, reg_AX) ); x86_push( func, - get_input_base() ); + x86_make_reg( file_REG32, reg_CX) ); x86_push( func, - get_output_base() ); - - /* It is important on non-win32 platforms that temp base is pushed last. - */ - x86_push( - func, - get_temp_base() ); + x86_make_reg( file_REG32, reg_DX) ); } static void @@ -464,16 +458,13 @@ x86_pop_gp( */ x86_pop( func, - get_temp_base() ); + x86_make_reg( file_REG32, reg_DX) ); x86_pop( func, - get_output_base() ); + x86_make_reg( file_REG32, reg_CX) ); x86_pop( func, - get_input_base() ); - x86_pop( - func, - get_const_base() ); + x86_make_reg( file_REG32, reg_AX) ); } static void @@ -490,19 +481,23 @@ emit_func_call_dst( emit_push_gp( func ); -#ifdef WIN32 - x86_push( - func, - get_temp( TEMP_R0, 0 ) ); -#endif - { struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); + x86_lea( + func, + ecx, + get_temp( TEMP_R0, 0 ) ); + + x86_push( func, ecx ); x86_mov_reg_imm( func, ecx, (unsigned long) code ); x86_call( func, ecx ); +#ifndef WIN32 + x86_pop(func, ecx ); +#endif } + x86_pop_gp( func ); @@ -563,11 +558,7 @@ static void XSTDCALL cos4f( float *store ) { -#ifdef WIN32 const unsigned X = 0; -#else - const unsigned X = TEMP_R0 * 16; -#endif store[X + 0] = cosf( store[X + 0] ); store[X + 1] = cosf( store[X + 1] ); @@ -590,11 +581,8 @@ static void XSTDCALL ex24f( float *store ) { -#ifdef WIN32 const unsigned X = 0; -#else - const unsigned X = TEMP_R0 * 16; -#endif + store[X + 0] = powf( 2.0f, store[X + 0] ); store[X + 1] = powf( 2.0f, store[X + 1] ); store[X + 2] = powf( 2.0f, store[X + 2] ); @@ -627,11 +615,8 @@ static void XSTDCALL flr4f( float *store ) { -#ifdef WIN32 const unsigned X = 0; -#else - const unsigned X = TEMP_R0 * 16; -#endif + store[X + 0] = floorf( store[X + 0] ); store[X + 1] = floorf( store[X + 1] ); store[X + 2] = floorf( store[X + 2] ); @@ -653,11 +638,8 @@ static void XSTDCALL frc4f( float *store ) { -#ifdef WIN32 const unsigned X = 0; -#else - const unsigned X = TEMP_R0 * 16; -#endif + store[X + 0] -= floorf( store[X + 0] ); store[X + 1] -= floorf( store[X + 1] ); store[X + 2] -= floorf( store[X + 2] ); @@ -679,11 +661,8 @@ static void XSTDCALL lg24f( float *store ) { -#ifdef WIN32 const unsigned X = 0; -#else - const unsigned X = TEMP_R0 * 16; -#endif + store[X + 0] = LOG2( store[X + 0] ); store[X + 1] = LOG2( store[X + 1] ); store[X + 2] = LOG2( store[X + 2] ); @@ -741,11 +720,8 @@ static void XSTDCALL pow4f( float *store ) { -#ifdef WIN32 const unsigned X = 0; -#else - const unsigned X = TEMP_R0 * 16; -#endif + store[X + 0] = powf( store[X + 0], store[X + 4] ); store[X + 1] = powf( store[X + 1], store[X + 5] ); store[X + 2] = powf( store[X + 2], store[X + 6] ); @@ -786,11 +762,8 @@ static void XSTDCALL rsqrt4f( float *store ) { -#ifdef WIN32 const unsigned X = 0; -#else - const unsigned X = TEMP_R0 * 16; -#endif + store[X + 0] = 1.0F / sqrtf( store[X + 0] ); store[X + 1] = 1.0F / sqrtf( store[X + 1] ); store[X + 2] = 1.0F / sqrtf( store[X + 2] ); @@ -864,11 +837,8 @@ static void XSTDCALL sin4f( float *store ) { -#ifdef WIN32 const unsigned X = 0; -#else - const unsigned X = TEMP_R0 * 16; -#endif + store[X + 0] = sinf( store[X + 0] ); store[X + 1] = sinf( store[X + 1] ); store[X + 2] = sinf( store[X + 2] ); @@ -2015,40 +1985,40 @@ emit_declaration( } } -static void aos_to_soa( struct x86_function *func, uint aos, uint soa, uint num, uint stride ) +static void aos_to_soa( struct x86_function *func, + uint arg_aos, + uint arg_soa, + uint arg_num, + uint arg_stride ) { - struct x86_reg soa_input; - struct x86_reg aos_input; - struct x86_reg num_inputs; - struct x86_reg temp; + struct x86_reg soa_input = x86_make_reg( file_REG32, reg_AX ); + struct x86_reg aos_input = x86_make_reg( file_REG32, reg_BX ); + struct x86_reg num_inputs = x86_make_reg( file_REG32, reg_CX ); + struct x86_reg stride = x86_make_reg( file_REG32, reg_DX ); int inner_loop; - soa_input = x86_make_reg( file_REG32, reg_AX ); - aos_input = get_temp_base(); /* BX or SI */ - num_inputs = x86_make_reg( file_REG32, reg_CX ); - temp = x86_make_reg( file_REG32, reg_DX ); /* Save EBX */ - x86_push( func, aos_input ); + x86_push( func, x86_make_reg( file_REG32, reg_BX ) ); - x86_mov( func, soa_input, x86_fn_arg( func, soa ) ); - x86_mov( func, aos_input, x86_fn_arg( func, aos ) ); - x86_mov( func, num_inputs, x86_fn_arg( func, num ) ); + x86_mov( func, aos_input, x86_fn_arg( func, arg_aos ) ); + x86_mov( func, soa_input, x86_fn_arg( func, arg_soa ) ); + x86_mov( func, num_inputs, x86_fn_arg( func, arg_num ) ); + x86_mov( func, stride, x86_fn_arg( func, arg_stride ) ); /* do */ inner_loop = x86_get_label( func ); { - x86_mov( func, temp, x86_fn_arg( func, stride ) ); x86_push( func, aos_input ); sse_movlps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); sse_movlps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); - x86_add( func, aos_input, temp ); + x86_add( func, aos_input, stride ); sse_movhps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); sse_movhps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); - x86_add( func, aos_input, temp ); + x86_add( func, aos_input, stride ); sse_movlps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); sse_movlps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); - x86_add( func, aos_input, temp ); + x86_add( func, aos_input, stride ); sse_movhps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); sse_movhps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); x86_pop( func, aos_input ); @@ -2086,7 +2056,7 @@ static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, int inner_loop; soa_output = x86_make_reg( file_REG32, reg_AX ); - aos_output = get_temp_base(); /* BX or SI */ + aos_output = x86_make_reg( file_REG32, reg_BX ); num_outputs = x86_make_reg( file_REG32, reg_CX ); temp = x86_make_reg( file_REG32, reg_DX ); @@ -2213,7 +2183,11 @@ tgsi_emit_sse2( assert(parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX); if (do_swizzles) - aos_to_soa( func, 6, 1, 7, 8 ); + aos_to_soa( func, + 6, /* aos_input */ + 1, /* machine->input */ + 7, /* num_inputs */ + 8 ); /* input_stride */ x86_mov( func, -- cgit v1.2.3 From c1abd758c51247ebaf3d4808a77513d7814205cd Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 1 May 2008 15:19:00 -0600 Subject: gallium: remove the unused softpipe_winsys code The struct is still there though until all winsys layers are updated --- src/gallium/drivers/softpipe/sp_context.c | 4 +- src/gallium/drivers/softpipe/sp_context.h | 2 - src/gallium/drivers/softpipe/sp_winsys.h | 2 +- src/gallium/winsys/xlib/xm_winsys.c | 81 +++++++++---------------------- 4 files changed, 25 insertions(+), 64 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index edf91ecafa..fe9cd8375e 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -122,7 +122,7 @@ static void softpipe_destroy( struct pipe_context *pipe ) struct pipe_context * softpipe_create( struct pipe_screen *screen, struct pipe_winsys *pipe_winsys, - struct softpipe_winsys *softpipe_winsys ) + void *unused ) { struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); uint i; @@ -212,8 +212,6 @@ softpipe_create( struct pipe_screen *screen, softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); softpipe->quad.output = sp_quad_output_stage(softpipe); - softpipe->winsys = softpipe_winsys; - /* * Create drawing context and plug our rendering stage into it. */ diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index b3e2b2e435..62eabfb30e 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -57,8 +57,6 @@ struct sp_vertex_shader; struct softpipe_context { struct pipe_context pipe; /**< base class */ - struct softpipe_winsys *winsys; /**< window system interface */ - /* The most recent drawing state as set by the driver: */ diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h index 291825dfe2..4ab666486c 100644 --- a/src/gallium/drivers/softpipe/sp_winsys.h +++ b/src/gallium/drivers/softpipe/sp_winsys.h @@ -59,7 +59,7 @@ struct pipe_context; struct pipe_context *softpipe_create( struct pipe_screen *, struct pipe_winsys *, - struct softpipe_winsys * ); + void *unused ); struct pipe_screen * diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 8a89278cde..71ba076bff 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -37,6 +37,7 @@ #include "xmesaP.h" #undef ASSERT +#undef Elements #include "pipe/p_winsys.h" #include "pipe/p_format.h" @@ -88,18 +89,6 @@ struct xmesa_surface }; -/** - * Derived from softpipe_winsys. - * We just need one extra field which indicates the pixel format to use for - * drawing surfaces so that we're compatible with the XVisual/window format. - */ -struct xmesa_softpipe_winsys -{ - struct softpipe_winsys spws; - enum pipe_format pixelformat; -}; - - struct xmesa_pipe_winsys { struct pipe_winsys base; @@ -119,12 +108,7 @@ xmesa_surface(struct pipe_surface *ps) return (struct xmesa_surface *) ps; } -/** cast wrapper */ -static INLINE struct xmesa_softpipe_winsys * -xmesa_softpipe_winsys(struct softpipe_winsys *spws) -{ - return (struct xmesa_softpipe_winsys *) spws; -} + /** * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque @@ -525,8 +509,7 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, /** - * Called via pipe->surface_alloc() to create new surfaces (textures, - * renderbuffers, etc. + * Called via winsys->surface_alloc() to create new surfaces. */ static struct pipe_surface * xm_surface_alloc(struct pipe_winsys *ws) @@ -610,10 +593,19 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) { static struct xmesa_pipe_winsys *ws = NULL; - if (!ws && getenv("XM_AUB")) { + if (!ws) { ws = (struct xmesa_pipe_winsys *) xmesa_create_pipe_winsys_aub(); } - else if (!ws) { + return &ws->base; +} + + +struct pipe_winsys * +xmesa_get_pipe_winsys(struct xmesa_visual *xm_vis) +{ + static struct xmesa_pipe_winsys *ws = NULL; + + if (!ws) { ws = CALLOC_STRUCT(xmesa_pipe_winsys); ws->xm_visual = xm_vis; @@ -644,45 +636,19 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) } -/** - * Called via softpipe_winsys->is_format_supported(). - * This function is only called to test formats for front/back color surfaces. - * The winsys being queried will have been created at glXCreateContext - * time, with a pixel format corresponding to the context's visual. - */ -static boolean -xmesa_is_format_supported(struct softpipe_winsys *sws, - enum pipe_format format) -{ - struct xmesa_softpipe_winsys *xmws = xmesa_softpipe_winsys(sws); - return (format == xmws->pixelformat); -} - - -/** - * Return pointer to a softpipe_winsys object. - */ -static struct softpipe_winsys * -xmesa_get_softpipe_winsys(uint pixelformat) -{ - struct xmesa_softpipe_winsys *xmws - = CALLOC_STRUCT(xmesa_softpipe_winsys); - if (!xmws) - return NULL; - - xmws->spws.is_format_supported = xmesa_is_format_supported; - xmws->pixelformat = pixelformat; - - return &xmws->spws; -} - - struct pipe_context * xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) { - struct pipe_winsys *pws = xmesa_get_pipe_winsys_aub(xmesa->xm_visual); + struct pipe_winsys *pws; struct pipe_context *pipe; + if (getenv("XM_AUB")) { + pws = xmesa_get_pipe_winsys_aub(xmesa->xm_visual); + } + else { + pws = xmesa_get_pipe_winsys(xmesa->xm_visual); + } + #ifdef GALLIUM_CELL if (!getenv("GALLIUM_NOCELL")) { struct cell_winsys *cws = cell_get_winsys(pixelformat); @@ -693,10 +659,9 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) else #endif { - struct softpipe_winsys *spws = xmesa_get_softpipe_winsys(pixelformat); struct pipe_screen *screen = softpipe_create_screen(pws); - pipe = softpipe_create(screen, pws, spws); + pipe = softpipe_create(screen, pws, NULL); } if (pipe) -- cgit v1.2.3 From bc4952987419d77fabbf4fa43913f6e488bdb211 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 1 May 2008 15:21:40 -0600 Subject: added cast for MSVC --- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 54fdcc1a3b..73ee419858 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -256,7 +256,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, uint size = 4; immed = tgsi_default_full_immediate(); immed.Immediate.Size = 1 + size; /* one for the token itself */ - immed.u.Pointer = value; + immed.u.Pointer = (void *) value; ctx->emit_immediate(ctx, &immed); } -- cgit v1.2.3 From 7a4313b63bcd06318437d384875472e7139070a1 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 1 May 2008 18:42:01 -0600 Subject: gallium: implement TGSI_OPCODE_LOG --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 30 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index d55f907c0d..4b33d7e8bd 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -1549,22 +1549,24 @@ exec_instruction( break; case TGSI_OPCODE_LOG: - debug_printf("TGSI: LOG opcode not implemented\n"); - /* from ARB_v_p: - tmp = fabs(ScalarLoad(op0)); - result.x = floor(log2(tmp)); - result.y = tmp / 2^(floor(log2(tmp))); - result.z = RoughApproxLog2(tmp); - result.w = 1.0; - */ -#if 0 - /* something like this: */ FETCH( &r[0], 0, CHAN_X ); - micro_lg2( &r[0], &r[0] ); - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); + micro_abs( &r[2], &r[0] ); /* r2 = abs(r0) */ + micro_lg2( &r[1], &r[2] ); /* r1 = lg2(r2) */ + micro_flr( &r[0], &r[1] ); /* r0 = floor(r1) */ + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &r[0], 0, CHAN_X ); + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + micro_exp2( &r[0], &r[0] ); /* r0 = 2 ^ r0 */ + micro_div( &r[0], &r[2], &r[0] ); /* r0 = r2 / r0 */ + STORE( &r[0], 0, CHAN_Y ); + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + STORE( &r[1], 0, CHAN_Z ); + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); } -#endif break; case TGSI_OPCODE_MUL: -- cgit v1.2.3 From 3b63bc8ac6db7af4077f12cfd44876a9d43cc6ec Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 1 May 2008 18:49:20 -0600 Subject: gallium: implement TGSI_OPCODE_EXP --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index 4b33d7e8bd..5d5125f7cb 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -1530,22 +1530,23 @@ exec_instruction( break; case TGSI_OPCODE_EXP: - debug_printf("TGSI: EXP opcode not implemented\n"); - /* from ARB_v_p: - tmp = ScalarLoad(op0); - result.x = 2^floor(tmp); - result.y = tmp - floor(tmp); - result.z = RoughApprox2ToX(tmp); - result.w = 1.0; - */ -#if 0 - /* something like this: */ FETCH( &r[0], 0, CHAN_X ); - micro_exp2( &r[0], &r[0] ); - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); + micro_flr( &r[1], &r[0] ); /* r1 = floor(r0) */ + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + micro_exp2( &r[2], &r[1] ); /* r2 = 2 ^ r1 */ + STORE( &r[2], 0, CHAN_X ); /* store r2 */ + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + micro_sub( &r[2], &r[0], &r[1] ); /* r2 = r0 - r1 */ + STORE( &r[2], 0, CHAN_Y ); /* store r2 */ + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + micro_exp2( &r[2], &r[0] ); /* r2 = 2 ^ r0 */ + STORE( &r[2], 0, CHAN_Z ); /* store r2 */ + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); } -#endif break; case TGSI_OPCODE_LOG: -- cgit v1.2.3 From 869b0836c1c4339de91c9918ae07926c846a004c Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 1 May 2008 18:56:20 -0600 Subject: gallium: temporarily disable broken SSE2 code for ARL opcode --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index a67bc8567b..2fd76a3072 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -1190,11 +1190,16 @@ emit_instruction( switch( inst->Instruction.Opcode ) { case TGSI_OPCODE_ARL: +#if 0 + /* XXX this isn't working properly (see glean vertProg1 test) */ FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); emit_f2it( func, 0 ); STORE( func, *inst, 0, 0, chan_index ); } +#else + return 0; +#endif break; case TGSI_OPCODE_MOV: -- cgit v1.2.3 From 9d151a2517de3f83d676624a21b4f73d5accecbe Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 1 May 2008 16:39:54 +0200 Subject: tgsi: Dump destination register modulate modifier. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 26bfc2051f..4c65ffd780 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -767,6 +767,31 @@ dump_instruction_short( SID( dst->DstRegister.Index ); CHR( ']' ); + switch (dst->DstRegisterExtModulate.Modulate) { + case TGSI_MODULATE_1X: + break; + case TGSI_MODULATE_2X: + TXT( "_2X" ); + break; + case TGSI_MODULATE_4X: + TXT( "_4X" ); + break; + case TGSI_MODULATE_8X: + TXT( "_8X" ); + break; + case TGSI_MODULATE_HALF: + TXT( "_D2" ); + break; + case TGSI_MODULATE_QUARTER: + TXT( "_D4" ); + break; + case TGSI_MODULATE_EIGHTH: + TXT( "_D8" ); + break; + default: + assert( 0 ); + } + if( dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW ) { CHR( '.' ); if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_X ) { -- cgit v1.2.3 From 36f93c5e5159ebd99a5a4504efccdf6c5bf40716 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 2 May 2008 10:20:53 +0200 Subject: tgsi: Fix build on Win32. --- src/gallium/auxiliary/tgsi/util/tgsi_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c index c3526cb71f..5bea773840 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c @@ -43,7 +43,7 @@ tgsi_full_token_free( union tgsi_full_token *full_token ) { if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE ) { - FREE( full_token->FullImmediate.u.Pointer ); + FREE( (void *) full_token->FullImmediate.u.Pointer ); } } @@ -156,7 +156,7 @@ tgsi_parse_token( imm->u.Pointer = MALLOC( sizeof( struct tgsi_immediate_float32 ) * (imm->Immediate.Size - 1) ); for( i = 0; i < imm->Immediate.Size - 1; i++ ) { - next_token( ctx, &imm->u.ImmediateFloat32[i] ); + next_token( ctx, (struct tgsi_immediate_float32 *) &imm->u.ImmediateFloat32[i] ); } break; -- cgit v1.2.3 From a1cb0c2b915532e934b5d37bd0c550b1bfcc77ba Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 2 May 2008 11:13:58 +0200 Subject: tgsi: Do not assume IN and OUT registers are declared sequentially. --- src/gallium/auxiliary/tgsi/util/tgsi_scan.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c index ea4a72967d..65650ed22a 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c @@ -103,18 +103,14 @@ tgsi_scan_shader(const struct tgsi_token *tokens, info->file_max[file] = MAX2(info->file_max[file], (int)i); if (file == TGSI_FILE_INPUT) { - info->input_semantic_name[info->num_inputs] - = (ubyte)fulldecl->Semantic.SemanticName; - info->input_semantic_index[info->num_inputs] - = (ubyte)fulldecl->Semantic.SemanticIndex; + info->input_semantic_name[i] = (ubyte)fulldecl->Semantic.SemanticName; + info->input_semantic_index[i] = (ubyte)fulldecl->Semantic.SemanticIndex; info->num_inputs++; } if (file == TGSI_FILE_OUTPUT) { - info->output_semantic_name[info->num_outputs] - = (ubyte)fulldecl->Semantic.SemanticName; - info->output_semantic_index[info->num_outputs] - = (ubyte)fulldecl->Semantic.SemanticIndex; + info->output_semantic_name[i] = (ubyte)fulldecl->Semantic.SemanticName; + info->output_semantic_index[i] = (ubyte)fulldecl->Semantic.SemanticIndex; info->num_outputs++; } @@ -137,6 +133,9 @@ tgsi_scan_shader(const struct tgsi_token *tokens, } } + assert( info->file_max[TGSI_FILE_INPUT] + 1 == info->num_inputs ); + assert( info->file_max[TGSI_FILE_OUTPUT] + 1 == info->num_outputs ); + info->uses_kill = (info->opcode_count[TGSI_OPCODE_KIL] || info->opcode_count[TGSI_OPCODE_KILP]); -- cgit v1.2.3 From 251db95945c6b484a093336e7bf12aed6091de54 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 17:55:52 +0100 Subject: cso: can memcmp-compare pipe_framebuffer_state now it includes fb dimensions --- src/gallium/auxiliary/cso_cache/cso_context.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index eef898f486..5d626b7cdc 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -769,8 +769,7 @@ void cso_restore_vertex_shader(struct cso_context *ctx) enum pipe_error cso_set_framebuffer(struct cso_context *ctx, const struct pipe_framebuffer_state *fb) { - /* XXX this memcmp() fails to detect buffer size changes */ - if (1/*memcmp(&ctx->fb, fb, sizeof(*fb))*/) { + if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) { ctx->fb = *fb; ctx->pipe->set_framebuffer_state(ctx->pipe, fb); } -- cgit v1.2.3 From 731e7b961cd081ac6a64b636937716ce3a623c2c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 May 2008 18:13:46 +0100 Subject: re-add pipe_surface map/unmap inlines --- src/gallium/auxiliary/draw/draw_vs_sse.c | 2 +- src/gallium/drivers/softpipe/sp_surface.c | 2 +- src/gallium/include/pipe/p_inlines.h | 33 +++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 90926aec85..07f85bc448 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -47,7 +47,7 @@ #include "tgsi/util/tgsi_parse.h" #define SSE_MAX_VERTICES 4 -#define SSE_SWIZZLES 0 +#define SSE_SWIZZLES 1 #if SSE_SWIZZLES typedef void (XSTDCALL *codegen_function) ( diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index b82b1a8f37..29a1e92416 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -46,7 +46,6 @@ sp_surface_copy(struct pipe_context *pipe, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { - assert( dst->cpp == src->cpp ); void *dst_map = pipe->screen->surface_map( pipe->screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE ); @@ -55,6 +54,7 @@ sp_surface_copy(struct pipe_context *pipe, src, PIPE_BUFFER_USAGE_CPU_READ ); + assert( dst->cpp == src->cpp ); assert(src_map && dst_map); pipe_copy_rect(dst_map, diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index 592c3c87c2..1e4b98edb4 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -39,6 +39,39 @@ extern "C" { #endif +/* XXX: these are a kludge. will fix when all surfaces are views into + * textures, and free-floating winsys surfaces go away. + */ +static INLINE void * +pipe_surface_map( struct pipe_surface *surf, unsigned flags ) +{ + if (surf->texture) { + struct pipe_screen *screen = surf->texture->screen; + return surf->texture->screen->surface_map( screen, surf, flags ); + } + else { + struct pipe_winsys *winsys = surf->winsys; + char *map = (char *)winsys->buffer_map( winsys, surf->buffer, flags ); + if (map == NULL) + return NULL; + return (void *)(map + surf->offset); + } +} + +static INLINE void +pipe_surface_unmap( struct pipe_surface *surf ) +{ + if (surf->texture) { + struct pipe_screen *screen = surf->texture->screen; + surf->texture->screen->surface_unmap( screen, surf ); + } + else { + struct pipe_winsys *winsys = surf->winsys; + winsys->buffer_unmap( winsys, surf->buffer ); + } +} + + /** * Set 'ptr' to point to 'surf' and update reference counting. -- cgit v1.2.3 From 25d60838b5dfdbde54f19f26b41977fc25011474 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 2 May 2008 12:17:11 +0100 Subject: gallium: fix build after merge --- src/gallium/auxiliary/util/u_blit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index b70bcbfa66..999a3e5099 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -296,7 +296,9 @@ util_blit_pixels(struct blit_state *ctx, src, srcLeft, srcTop, /* src */ srcW, srcH); /* size */ - pipe->texture_update(pipe, tex, 0, 1 << 0); + /* free the surface, update the texture if necessary. + */ + screen->tex_surface_release(screen, &texSurf); /* save state (restored below) */ cso_save_blend(ctx->cso); @@ -357,8 +359,6 @@ util_blit_pixels(struct blit_state *ctx, cso_restore_vertex_shader(ctx->cso); cso_restore_viewport(ctx->cso); - /* free the texture */ - pipe_surface_reference(&texSurf, NULL); screen->texture_release(screen, &tex); } -- cgit v1.2.3 From 4a159132082429d5492f5298c2ccb0df551c9f65 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 2 May 2008 14:27:10 +0100 Subject: gallium: remove usage of winsys->surface_alloc_storage from state tracker Allocate a texture containing storage instead. Also clean up ACCUM buffer allocation slightly -- drivers will need some changes to texture allocation logic to accomodate the concept of a texture that will only as image storage by the CPU, but it's cleaner than it was. --- src/gallium/include/pipe/p_state.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 47e57e2957..277ee4b319 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -299,6 +299,8 @@ struct pipe_texture unsigned cpp:8; unsigned last_level:8; /**< Index of last mipmap level present/defined */ unsigned compressed:1; + + unsigned usage; /* These are also refcounted: */ -- cgit v1.2.3 From 17058e07469f2dc5b47b4f820bd5a31b7ed9177c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 2 May 2008 16:02:18 +0200 Subject: tgsi: Implement fast rsqrtf. Not tested, inactive. --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 6 ++++ src/gallium/auxiliary/tgsi/exec/tgsi_exec.h | 10 +++++-- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 43 +++++++++++++++++------------ 3 files changed, 40 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index 5d5125f7cb..826b432f09 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -88,6 +88,10 @@ #define TEMP_OUTPUT_C TGSI_EXEC_TEMP_OUTPUT_C #define TEMP_PRIMITIVE_I TGSI_EXEC_TEMP_PRIMITIVE_I #define TEMP_PRIMITIVE_C TGSI_EXEC_TEMP_PRIMITIVE_C +#define TEMP_3_I TGSI_EXEC_TEMP_THREE_I +#define TEMP_3_C TGSI_EXEC_TEMP_THREE_C +#define TEMP_HALF_I TGSI_EXEC_TEMP_HALF_I +#define TEMP_HALF_C TGSI_EXEC_TEMP_HALF_C #define TEMP_R0 TGSI_EXEC_TEMP_R0 #define FOR_EACH_CHANNEL(CHAN)\ @@ -262,6 +266,8 @@ tgsi_exec_machine_init( mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].f[i] = 2.0f; mach->Temps[TEMP_128_I].xyzw[TEMP_128_C].f[i] = 128.0f; mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C].f[i] = -128.0f; + mach->Temps[TEMP_3_I].xyzw[TEMP_3_C].f[i] = 3.0f; + mach->Temps[TEMP_HALF_I].xyzw[TEMP_HALF_C].f[i] = 0.5f; } } diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h index 92e2e5e985..19bd78df3d 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h @@ -133,9 +133,15 @@ struct tgsi_exec_labels #define TGSI_EXEC_TEMP_PRIMITIVE_I 34 #define TGSI_EXEC_TEMP_PRIMITIVE_C 2 -#define TGSI_EXEC_TEMP_R0 35 +#define TGSI_EXEC_TEMP_THREE_I 34 +#define TGSI_EXEC_TEMP_THREE_C 3 -#define TGSI_EXEC_NUM_TEMPS (32 + 4) +#define TGSI_EXEC_TEMP_HALF_I 35 +#define TGSI_EXEC_TEMP_HALF_C 0 + +#define TGSI_EXEC_TEMP_R0 36 + +#define TGSI_EXEC_NUM_TEMPS (32 + 5) #define TGSI_EXEC_NUM_ADDRS 1 #define TGSI_EXEC_NUM_IMMEDIATES 256 diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 2fd76a3072..dbf002130b 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -36,7 +36,11 @@ #ifdef PIPE_ARCH_X86 -#define HIGH_PRECISION 1 /* for 1/sqrt() */ +/* for 1/sqrt() + * + * This costs about 100fps (close to 10%) in gears: + */ +#define HIGH_PRECISION 1 #define FOR_EACH_CHANNEL( CHAN )\ @@ -794,20 +798,25 @@ emit_rsqrt( * * See: http://softwarecommunity.intel.com/articles/eng/1818.htm */ - /* This is some code that woudl do the above for a scalar 'a'. We - * obviously are interested in a vector version: - * - * movss xmm3, a; - * movss xmm1, half; - * movss xmm2, three; - * rsqrtss xmm0, xmm3; - * mulss xmm3, xmm0; - * mulss xmm1, xmm0; - * mulss xmm3, xmm0; - * subss xmm2, xmm3; - * mulss xmm1, xmm2; - * movss x, xmm1; - */ + { + struct x86_reg dst = make_xmm( xmm_dst ); + struct x86_reg src = make_xmm( xmm_src ); + struct x86_reg tmp0 = make_xmm( 2 ); + struct x86_reg tmp1 = make_xmm( 3 ); + + assert( xmm_dst != xmm_src ); + assert( xmm_dst != 2 && xmm_dst != 3 ); + assert( xmm_src != 2 && xmm_src != 3 ); + + sse_movaps( func, dst, get_temp( TGSI_EXEC_TEMP_HALF_I, TGSI_EXEC_TEMP_HALF_C ) ); + sse_movaps( func, tmp0, get_temp( TGSI_EXEC_TEMP_THREE_I, TGSI_EXEC_TEMP_THREE_C ) ); + sse_rsqrtps( func, tmp1, src ); + sse_mulps( func, src, tmp1 ); + sse_mulps( func, dst, tmp1 ); + sse_mulps( func, src, tmp1 ); + sse_subps( func, tmp0, src ); + sse_mulps( func, dst, tmp0 ); + } #endif #else /* On Intel CPUs at least, this is only accurate to 12 bits -- not @@ -1295,9 +1304,9 @@ emit_instruction( case TGSI_OPCODE_RSQ: /* TGSI_OPCODE_RECIPSQRT */ FETCH( func, *inst, 0, 0, CHAN_X ); - emit_rsqrt( func, 0, 0 ); + emit_rsqrt( func, 1, 0 ); FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); + STORE( func, *inst, 1, 0, chan_index ); } break; -- cgit v1.2.3 From 6c15a70b75b1625b69790f98f2f44e9ae4435f6a Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 2 May 2008 16:12:55 +0200 Subject: tgsi: Enable fast high precision rsqrt. --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index dbf002130b..b6b05944be 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -761,20 +761,6 @@ emit_rcp ( make_xmm( xmm_src ) ); } -#if HIGH_PRECISION -static void XSTDCALL -rsqrt4f( - float *store ) -{ - const unsigned X = 0; - - store[X + 0] = 1.0F / sqrtf( store[X + 0] ); - store[X + 1] = 1.0F / sqrtf( store[X + 1] ); - store[X + 2] = 1.0F / sqrtf( store[X + 2] ); - store[X + 3] = 1.0F / sqrtf( store[X + 3] ); -} -#endif - static void emit_rsqrt( struct x86_function *func, @@ -782,13 +768,6 @@ emit_rsqrt( unsigned xmm_src ) { #if HIGH_PRECISION -#if 1 - emit_func_call_dst_src( - func, - xmm_dst, - xmm_src, - rsqrt4f ); -#else /* Although rsqrtps() and rcpps() are low precision on some/all SSE * implementations, it is possible to improve its precision at * fairly low cost, using a newton/raphson step, as below: @@ -817,7 +796,6 @@ emit_rsqrt( sse_subps( func, tmp0, src ); sse_mulps( func, dst, tmp0 ); } -#endif #else /* On Intel CPUs at least, this is only accurate to 12 bits -- not * good enough. -- cgit v1.2.3 From 8a5bf456dcb84b315152b87e33c8736248ad0a46 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 1 May 2008 15:29:25 -0600 Subject: gallium: comments, clean-ups --- src/gallium/winsys/xlib/xm_winsys.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 71ba076bff..51b247ffc3 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -58,6 +58,7 @@ /** + * Subclass of pipe_buffer for Xlib winsys. * Low-level OS/window system memory buffer */ struct xm_buffer @@ -80,6 +81,10 @@ struct xm_buffer # define XSHM_ENABLED(b) 0 #endif + +/** + * Subclass of pipe_surface for Xlib winsys + */ struct xmesa_surface { struct pipe_surface surface; @@ -89,6 +94,9 @@ struct xmesa_surface }; +/** + * Subclass of pipe_winsys for Xlib winsys + */ struct xmesa_pipe_winsys { struct pipe_winsys base; @@ -100,11 +108,11 @@ struct xmesa_pipe_winsys static void alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, unsigned width, unsigned height); + /** Cast wrapper */ static INLINE struct xmesa_surface * xmesa_surface(struct pipe_surface *ps) { -// assert(0); return (struct xmesa_surface *) ps; } -- cgit v1.2.3 From e9513bd403c0ba0b004d2414fda6736b38cecfd5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 2 May 2008 07:54:11 -0600 Subject: gallium: code movement (XSHM code) --- src/gallium/winsys/xlib/xm_winsys.c | 252 ++++++++++++++++++------------------ 1 file changed, 125 insertions(+), 127 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 51b247ffc3..641ec11652 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -75,12 +75,6 @@ struct xm_buffer #endif }; -#if defined(USE_XSHM) && !defined(XFree86Server) -# define XSHM_ENABLED(b) ((b)->shm) -#else -# define XSHM_ENABLED(b) 0 -#endif - /** * Subclass of pipe_surface for Xlib winsys @@ -105,9 +99,6 @@ struct xmesa_pipe_winsys }; -static void alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, - unsigned width, unsigned height); - /** Cast wrapper */ static INLINE struct xmesa_surface * @@ -117,11 +108,7 @@ xmesa_surface(struct pipe_surface *ps) } - -/** - * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque - * buffer pointer... - */ +/** Cast wrapper */ static INLINE struct xm_buffer * xm_buffer( struct pipe_buffer *buf ) { @@ -129,6 +116,130 @@ xm_buffer( struct pipe_buffer *buf ) } +/** + * X Shared Memory Image extension code + */ +#if defined(USE_XSHM) && !defined(XFree86Server) + +#define XSHM_ENABLED(b) ((b)->shm) + +static volatile int mesaXErrorFlag = 0; + +/** + * Catches potential Xlib errors. + */ +static int +mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event) +{ + (void) dpy; + (void) event; + mesaXErrorFlag = 1; + return 0; +} + + +static GLboolean alloc_shm(struct xm_buffer *buf, unsigned size) +{ + XShmSegmentInfo *const shminfo = & buf->shminfo; + + shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); + if (shminfo->shmid < 0) { + return GL_FALSE; + } + + shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); + if (shminfo->shmaddr == (char *) -1) { + shmctl(shminfo->shmid, IPC_RMID, 0); + return GL_FALSE; + } + + shminfo->readOnly = False; + return GL_TRUE; +} + + +/** + * Allocate a shared memory XImage back buffer for the given XMesaBuffer. + */ +static void +alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height) +{ + /* + * We have to do a _lot_ of error checking here to be sure we can + * really use the XSHM extension. It seems different servers trigger + * errors at different points if the extension won't work. Therefore + * we have to be very careful... + */ +#if 0 + GC gc; +#endif + int (*old_handler)(XMesaDisplay *, XErrorEvent *); + + b->tempImage = XShmCreateImage(xmb->xm_visual->display, + xmb->xm_visual->visinfo->visual, + xmb->xm_visual->visinfo->depth, + ZPixmap, + NULL, + &b->shminfo, + width, height); + if (b->tempImage == NULL) { + b->shm = 0; + return; + } + + + mesaXErrorFlag = 0; + old_handler = XSetErrorHandler(mesaHandleXError); + /* This may trigger the X protocol error we're ready to catch: */ + XShmAttach(xmb->xm_visual->display, &b->shminfo); + XSync(xmb->xm_visual->display, False); + + if (mesaXErrorFlag) { + /* we are on a remote display, this error is normal, don't print it */ + XFlush(xmb->xm_visual->display); + mesaXErrorFlag = 0; + XDestroyImage(b->tempImage); + b->tempImage = NULL; + b->shm = 0; + (void) XSetErrorHandler(old_handler); + return; + } + + + /* Finally, try an XShmPutImage to be really sure the extension works */ +#if 0 + gc = XCreateGC(xmb->xm_visual->display, xmb->drawable, 0, NULL); + XShmPutImage(xmb->xm_visual->display, xmb->drawable, gc, + b->tempImage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False); + XSync(xmb->xm_visual->display, False); + XFreeGC(xmb->xm_visual->display, gc); + (void) XSetErrorHandler(old_handler); + if (mesaXErrorFlag) { + XFlush(xmb->xm_visual->display); + mesaXErrorFlag = 0; + XDestroyImage(b->tempImage); + b->tempImage = NULL; + b->shm = 0; + return; + } +#endif +} + +#else + +#define XSHM_ENABLED(b) 0 + +static void +alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, + unsigned width, unsigned height) +{ + b->shm = 0; +} +#endif /* USE_XSHM */ + + + /* Most callbacks map direcly onto dri_bufmgr operations: */ @@ -305,119 +416,6 @@ xm_get_name(struct pipe_winsys *pws) } -#if defined(USE_XSHM) && !defined(XFree86Server) -static volatile int mesaXErrorFlag = 0; - -/** - * Catches potential Xlib errors. - */ -static int -mesaHandleXError(XMesaDisplay *dpy, XErrorEvent *event) -{ - (void) dpy; - (void) event; - mesaXErrorFlag = 1; - return 0; -} - - -static GLboolean alloc_shm(struct xm_buffer *buf, unsigned size) -{ - XShmSegmentInfo *const shminfo = & buf->shminfo; - - shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777); - if (shminfo->shmid < 0) { - return GL_FALSE; - } - - shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); - if (shminfo->shmaddr == (char *) -1) { - shmctl(shminfo->shmid, IPC_RMID, 0); - return GL_FALSE; - } - - shminfo->readOnly = False; - return GL_TRUE; -} - - -/** - * Allocate a shared memory XImage back buffer for the given XMesaBuffer. - */ -static void -alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, - unsigned width, unsigned height) -{ - /* - * We have to do a _lot_ of error checking here to be sure we can - * really use the XSHM extension. It seems different servers trigger - * errors at different points if the extension won't work. Therefore - * we have to be very careful... - */ -#if 0 - GC gc; -#endif - int (*old_handler)(XMesaDisplay *, XErrorEvent *); - - b->tempImage = XShmCreateImage(xmb->xm_visual->display, - xmb->xm_visual->visinfo->visual, - xmb->xm_visual->visinfo->depth, - ZPixmap, - NULL, - &b->shminfo, - width, height); - if (b->tempImage == NULL) { - b->shm = 0; - return; - } - - - mesaXErrorFlag = 0; - old_handler = XSetErrorHandler(mesaHandleXError); - /* This may trigger the X protocol error we're ready to catch: */ - XShmAttach(xmb->xm_visual->display, &b->shminfo); - XSync(xmb->xm_visual->display, False); - - if (mesaXErrorFlag) { - /* we are on a remote display, this error is normal, don't print it */ - XFlush(xmb->xm_visual->display); - mesaXErrorFlag = 0; - XDestroyImage(b->tempImage); - b->tempImage = NULL; - b->shm = 0; - (void) XSetErrorHandler(old_handler); - return; - } - - - /* Finally, try an XShmPutImage to be really sure the extension works */ -#if 0 - gc = XCreateGC(xmb->xm_visual->display, xmb->drawable, 0, NULL); - XShmPutImage(xmb->xm_visual->display, xmb->drawable, gc, - b->tempImage, 0, 0, 0, 0, 1, 1 /*one pixel*/, False); - XSync(xmb->xm_visual->display, False); - XFreeGC(xmb->xm_visual->display, gc); - (void) XSetErrorHandler(old_handler); - if (mesaXErrorFlag) { - XFlush(xmb->xm_visual->display); - mesaXErrorFlag = 0; - XDestroyImage(b->tempImage); - b->tempImage = NULL; - b->shm = 0; - return; - } -#endif -} -#else -static void -alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, - unsigned width, unsigned height) -{ - b->shm = 0; -} -#endif - - static struct pipe_buffer * xm_buffer_create(struct pipe_winsys *pws, unsigned alignment, -- cgit v1.2.3 From cff8d3bdcbf78b57b52a2f60c54e5a3cae286137 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 2 May 2008 08:22:25 -0600 Subject: gallium: remove ^M (CR) chars --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 46 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index b6b05944be..8018bd7fa4 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -36,11 +36,11 @@ #ifdef PIPE_ARCH_X86 -/* for 1/sqrt() - * - * This costs about 100fps (close to 10%) in gears: - */ -#define HIGH_PRECISION 1 +/* for 1/sqrt() + * + * This costs about 100fps (close to 10%) in gears: + */ +#define HIGH_PRECISION 1 #define FOR_EACH_CHANNEL( CHAN )\ @@ -777,24 +777,24 @@ emit_rsqrt( * * See: http://softwarecommunity.intel.com/articles/eng/1818.htm */ - { - struct x86_reg dst = make_xmm( xmm_dst ); - struct x86_reg src = make_xmm( xmm_src ); - struct x86_reg tmp0 = make_xmm( 2 ); - struct x86_reg tmp1 = make_xmm( 3 ); - - assert( xmm_dst != xmm_src ); - assert( xmm_dst != 2 && xmm_dst != 3 ); - assert( xmm_src != 2 && xmm_src != 3 ); - - sse_movaps( func, dst, get_temp( TGSI_EXEC_TEMP_HALF_I, TGSI_EXEC_TEMP_HALF_C ) ); - sse_movaps( func, tmp0, get_temp( TGSI_EXEC_TEMP_THREE_I, TGSI_EXEC_TEMP_THREE_C ) ); - sse_rsqrtps( func, tmp1, src ); - sse_mulps( func, src, tmp1 ); - sse_mulps( func, dst, tmp1 ); - sse_mulps( func, src, tmp1 ); - sse_subps( func, tmp0, src ); - sse_mulps( func, dst, tmp0 ); + { + struct x86_reg dst = make_xmm( xmm_dst ); + struct x86_reg src = make_xmm( xmm_src ); + struct x86_reg tmp0 = make_xmm( 2 ); + struct x86_reg tmp1 = make_xmm( 3 ); + + assert( xmm_dst != xmm_src ); + assert( xmm_dst != 2 && xmm_dst != 3 ); + assert( xmm_src != 2 && xmm_src != 3 ); + + sse_movaps( func, dst, get_temp( TGSI_EXEC_TEMP_HALF_I, TGSI_EXEC_TEMP_HALF_C ) ); + sse_movaps( func, tmp0, get_temp( TGSI_EXEC_TEMP_THREE_I, TGSI_EXEC_TEMP_THREE_C ) ); + sse_rsqrtps( func, tmp1, src ); + sse_mulps( func, src, tmp1 ); + sse_mulps( func, dst, tmp1 ); + sse_mulps( func, src, tmp1 ); + sse_subps( func, tmp0, src ); + sse_mulps( func, dst, tmp0 ); } #else /* On Intel CPUs at least, this is only accurate to 12 bits -- not -- cgit v1.2.3 From cc2af38f2afa0e6003c8338d51c4f5fbabde40e1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 2 May 2008 09:26:17 -0600 Subject: gallium: fix typos, comments, whitespace --- src/gallium/drivers/softpipe/sp_tile_cache.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index a88aad5d09..1117c0ad4c 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -131,7 +131,7 @@ sp_destroy_tile_cache(struct softpipe_tile_cache *tc) uint pos; for (pos = 0; pos < NUM_ENTRIES; pos++) { - //assert(tc->entries[pos].x < 0); + /*assert(tc->entries[pos].x < 0);*/ } if (tc->surface) { pipe_surface_reference(&tc->surface, NULL); @@ -332,8 +332,8 @@ sp_tile_cache_flush_clear(struct pipe_context *pipe, for (x = 0; x < w; x += TILE_SIZE) { if (is_clear_flag_set(tc->clear_flags, x, y)) { pipe_put_tile_raw(pipe, ps, - x, y, TILE_SIZE, TILE_SIZE, - tc->tile.data.color32, 0/*STRIDE*/); + x, y, TILE_SIZE, TILE_SIZE, + tc->tile.data.color32, 0/*STRIDE*/); /* do this? */ clear_clear_flag(tc->clear_flags, x, y); @@ -367,8 +367,8 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, if (tile->x >= 0) { if (tc->depth_stencil) { pipe_put_tile_raw(pipe, ps, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, - tile->data.depth32, 0/*STRIDE*/); + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->data.depth32, 0/*STRIDE*/); } else { pipe_put_tile_rgba(pipe, ps, @@ -385,7 +385,7 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, #endif } else if (tc->texture) { - /* caching a texture, mark all entries as embpy */ + /* caching a texture, mark all entries as empty */ for (pos = 0; pos < NUM_ENTRIES; pos++) { tc->entries[pos].x = -1; } -- cgit v1.2.3 From a73ae3d5eb8419feab5aea26573aa41b72f941eb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 2 May 2008 16:46:31 +0100 Subject: gallium: Add texture usage flags, special-case allocation of display targets For many envirionments it's necessary to allocate display targets in a window-system friendly manner. Add facilities so that a driver can tell if a texture is likely to be used to generate a display surface and if use special allocation paths if necessary. Hook up softpipe to call into the winsys->surface_alloc_storage() routine in this case, though we probably want to change that interface slightly also. --- src/gallium/drivers/softpipe/sp_texture.c | 101 ++++++++++++++++++++---------- src/gallium/drivers/softpipe/sp_texture.h | 2 +- src/gallium/include/pipe/p_state.h | 6 +- 3 files changed, 73 insertions(+), 36 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 2b31cd4f25..599ff2ac45 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -52,40 +52,87 @@ static unsigned minify( unsigned d ) } -static void -softpipe_texture_layout(struct softpipe_texture * spt) +/* Conventional allocation path for non-display textures: + */ +static boolean +softpipe_texture_layout(struct pipe_screen *screen, + struct softpipe_texture * spt) { + struct pipe_winsys *ws = screen->winsys; struct pipe_texture *pt = &spt->base; unsigned level; unsigned width = pt->width[0]; unsigned height = pt->height[0]; unsigned depth = pt->depth[0]; - spt->buffer_size = 0; + unsigned buffer_size = 0; for (level = 0; level <= pt->last_level; level++) { pt->width[level] = width; pt->height[level] = height; pt->depth[level] = depth; + spt->pitch[level] = width; - spt->level_offset[level] = spt->buffer_size; + spt->level_offset[level] = buffer_size; - spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * - ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * - width * pt->cpp; + buffer_size += (((pt->compressed) ? MAX2(1, height/4) : height) * + ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * + width * pt->cpp); width = minify(width); height = minify(height); depth = minify(depth); } + + spt->buffer = ws->buffer_create(ws, 32, + PIPE_BUFFER_USAGE_PIXEL, + buffer_size); + + return spt->buffer != NULL; } + +/* Hack it up to use the old winsys->surface_alloc_storage() + * method for now: + */ +static boolean +softpipe_displaytarget_layout(struct pipe_screen *screen, + struct softpipe_texture * spt) +{ + struct pipe_winsys *ws = screen->winsys; + struct pipe_surface surf; + unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + + + memset(&surf, 0, sizeof(surf)); + + ws->surface_alloc_storage( ws, + &surf, + spt->base.width[0], + spt->base.height[0], + spt->base.format, + flags); + + /* Now extract the goodies: + */ + spt->buffer = surf.buffer; + spt->pitch[0] = surf.pitch; + + return spt->buffer != NULL; +} + + + + + static struct pipe_texture * softpipe_texture_create(struct pipe_screen *screen, const struct pipe_texture *templat) { - struct pipe_winsys *ws = screen->winsys; struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); if (!spt) return NULL; @@ -94,19 +141,21 @@ softpipe_texture_create(struct pipe_screen *screen, spt->base.refcount = 1; spt->base.screen = screen; - softpipe_texture_layout(spt); - - spt->buffer = ws->buffer_create(ws, 32, - PIPE_BUFFER_USAGE_PIXEL, - spt->buffer_size); - if (!spt->buffer) { - FREE(spt); - return NULL; + if (spt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if (!softpipe_displaytarget_layout(screen, spt)) + goto fail; } - + else { + if (!softpipe_texture_layout(screen, spt)) + goto fail; + } + assert(spt->base.refcount == 1); - return &spt->base; + + fail: + FREE(spt); + return NULL; } @@ -178,22 +227,6 @@ softpipe_get_tex_surface(struct pipe_screen *screen, assert(face == 0); assert(zslice == 0); } - - if (usage & (PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_WRITE)) { - /* XXX if writing to the texture, invalidate the texcache entries!!! - * - * Actually, no. Flushing dependent contexts is still done - * explicitly and separately. Hardware drivers won't insert - * FLUSH commands into a command stream at this point, - * neither should softpipe try to flush caches. - * - * Those contexts could be living in separate threads & doing - * all sorts of unrelated stuff... Context<->texture - * dependency tracking needs to happen elsewhere. - */ - /* assert(0); */ - } } return ps; } diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index 2ba093320d..779a9d8fc9 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -42,11 +42,11 @@ struct softpipe_texture struct pipe_texture base; unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS]; /* The data is held here: */ struct pipe_buffer *buffer; - unsigned long buffer_size; }; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 277ee4b319..d7565dff96 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -284,6 +284,10 @@ struct pipe_surface }; +#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1 +#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */ +#define PIPE_TEXTURE_USAGE_SAMPLER 0x4 + /** * Texture object. */ @@ -300,7 +304,7 @@ struct pipe_texture unsigned last_level:8; /**< Index of last mipmap level present/defined */ unsigned compressed:1; - unsigned usage; + unsigned tex_usage; /* PIPE_TEXTURE_USAGE_* */ /* These are also refcounted: */ -- cgit v1.2.3 From 5cb29dae06a4d97dc40ac7573e7ae7211e329b3c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 2 May 2008 16:56:06 +0100 Subject: i915: update to new display target allocation --- src/gallium/drivers/i915simple/i915_texture.c | 91 ++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 7b9359a0fe..f668e2e7d7 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -105,6 +105,50 @@ i915_miptree_set_image_offset(struct i915_texture *tex, } +/* Hack it up to use the old winsys->surface_alloc_storage() + * method for now: + */ +static boolean +i915_displaytarget_layout(struct pipe_screen *screen, + struct i915_texture *tex) +{ + struct pipe_winsys *ws = screen->winsys; + struct pipe_surface surf; + unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + + + memset(&surf, 0, sizeof(surf)); + + ws->surface_alloc_storage( ws, + &surf, + tex->base.width[0], + tex->base.height[0], + tex->base.format, + flags); + + /* Now extract the goodies: + */ + i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); + i915_miptree_set_level_info( tex, 0, 0, 0, 0, + tex->base.width[0], + tex->base.height[0], + 1 ); + + tex->buffer = surf.buffer; + tex->pitch = surf.pitch; + tex->total_height = 0; + + + return tex->buffer != NULL; +} + + + + + static void i945_miptree_layout_2d( struct i915_texture *tex ) { @@ -483,30 +527,45 @@ static struct pipe_texture * i915_texture_create_screen(struct pipe_screen *screen, const struct pipe_texture *templat) { + struct i915_screen *i915screen = i915_screen(screen); + struct pipe_winsys *ws = screen->winsys; struct i915_texture *tex = CALLOC_STRUCT(i915_texture); - if (tex) { - struct i915_screen *i915screen = i915_screen(screen); - struct pipe_winsys *ws = screen->winsys; - - tex->base = *templat; - tex->base.refcount = 1; - tex->base.screen = screen; + if (!tex) + return NULL; - if (i915screen->is_i945 ? i945_miptree_layout(tex) : - i915_miptree_layout(tex)) - tex->buffer = ws->buffer_create(ws, 64, - PIPE_BUFFER_USAGE_PIXEL, - tex->pitch * tex->base.cpp * - tex->total_height); + tex->base = *templat; + tex->base.refcount = 1; + tex->base.screen = screen; - if (!tex->buffer) { - FREE(tex); - return NULL; + if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if (!i915_displaytarget_layout(screen, tex)) + goto fail; + } + else { + if (i915screen->is_i945) { + if (!i945_miptree_layout(tex)) + goto fail; } + else { + if (!i915_miptree_layout(tex)) + goto fail; + } + + tex->buffer = ws->buffer_create(ws, 64, + PIPE_BUFFER_USAGE_PIXEL, + tex->pitch * tex->base.cpp * + tex->total_height); + + if (!tex->buffer) + goto fail; } return &tex->base; + + fail: + FREE(tex); + return NULL; } -- cgit v1.2.3 From 3d53d38d5e35386de4793162b9dd32e171927059 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 2 May 2008 10:37:20 -0600 Subject: gallium: new debug code (disabled) --- src/gallium/drivers/softpipe/sp_tex_sample.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 5b63f97997..be0b57d9fa 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -1051,5 +1051,19 @@ sp_get_samples(struct tgsi_sampler *sampler, default: assert(0); } + +#if 0 /* DEBUG */ + { + int i; + printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]); + for (i = 0; i < 4; i++) { + printf("Frag %d: %f %f %f %f\n", i, + rgba[0][i], + rgba[1][i], + rgba[2][i], + rgba[3][i]); + } + } +#endif } -- cgit v1.2.3 From 7849ccb2a7dba3b9d751acaac9dd9aec3abe3b59 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 2 May 2008 17:55:22 +0100 Subject: brw: remove dead code --- src/gallium/drivers/i965simple/brw_tex_layout.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index ba4c4a7bcf..78ae0b1223 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -357,14 +357,6 @@ brw_texture_release_screen(struct pipe_screen *screen, } -static void -brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, - uint face, uint levelsMask) -{ - /* no-op? */ -} - - static struct pipe_surface * brw_get_tex_surface_screen(struct pipe_screen *screen, struct pipe_texture *pt, -- cgit v1.2.3 From b2021e7c06a9ec13b82eeeb352ad2408fe060518 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 2 May 2008 17:56:01 +0100 Subject: gallium: identify depth-stencil textures And don't use the display-target path to allocate them. --- src/gallium/include/pipe/p_state.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index d7565dff96..4936b7f507 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -286,7 +286,8 @@ struct pipe_surface #define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1 #define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */ -#define PIPE_TEXTURE_USAGE_SAMPLER 0x4 +#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x4 +#define PIPE_TEXTURE_USAGE_SAMPLER 0x8 /** * Texture object. -- cgit v1.2.3 From 07aaf3a7a730d65052ec34a82cce9b373673b556 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 2 May 2008 14:00:08 -0600 Subject: gallium: remove obsolete PIPE_CAP_BITMAP_TEXCOORD_BIAS --- src/gallium/include/pipe/p_defines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index d5d341d689..46a355daa2 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -268,7 +268,7 @@ enum pipe_texture_target { #define PIPE_CAP_MAX_POINT_WIDTH_AA 17 #define PIPE_CAP_MAX_TEXTURE_ANISOTROPY 18 #define PIPE_CAP_MAX_TEXTURE_LOD_BIAS 19 -#define PIPE_CAP_BITMAP_TEXCOORD_BIAS 20 + #ifdef __cplusplus } -- cgit v1.2.3 From 6e004e973bcc5b789ee3f70b70f5d728c8b8ea71 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 2 May 2008 14:00:35 -0600 Subject: gallium: remove 0.5 vertex biases in set_vertex_data() These should not be needed and were causing garbage to appear along the edges of the mipmap images. --- src/gallium/auxiliary/util/u_gen_mipmap.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 2e8417ee13..c53c512268 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -778,23 +778,23 @@ set_vertex_data(struct gen_mipmap_state *ctx, float width, float height) { void *buf; - ctx->vertices[0][0][0] = -0.5f; /*x*/ - ctx->vertices[0][0][1] = -0.5f; /*y*/ + ctx->vertices[0][0][0] = 0.0f; /*x*/ + ctx->vertices[0][0][1] = 0.0f; /*y*/ ctx->vertices[0][1][0] = 0.0f; /*s*/ ctx->vertices[0][1][1] = 0.0f; /*t*/ - ctx->vertices[1][0][0] = width - 0.5f; /*x*/ - ctx->vertices[1][0][1] = -0.5f; /*y*/ - ctx->vertices[1][1][0] = 1.0f; /*s*/ - ctx->vertices[1][1][1] = 0.0f; /*t*/ + ctx->vertices[1][0][0] = width; + ctx->vertices[1][0][1] = 0.0f; + ctx->vertices[1][1][0] = 1.0f; + ctx->vertices[1][1][1] = 0.0f; - ctx->vertices[2][0][0] = width - 0.5f; - ctx->vertices[2][0][1] = height - 0.5f; + ctx->vertices[2][0][0] = width; + ctx->vertices[2][0][1] = height; ctx->vertices[2][1][0] = 1.0f; ctx->vertices[2][1][1] = 1.0f; - ctx->vertices[3][0][0] = -0.5f; - ctx->vertices[3][0][1] = height - 0.5f; + ctx->vertices[3][0][0] = 0.0f; + ctx->vertices[3][0][1] = height; ctx->vertices[3][1][0] = 0.0f; ctx->vertices[3][1][1] = 1.0f; -- cgit v1.2.3 From 8e6a3807981bb96bb6747683dbc9f92ae7117dd2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 3 May 2008 15:41:05 +0100 Subject: gallium: add pipe surface layout value (Roland Scheidegger) --- src/gallium/include/pipe/p_defines.h | 6 ++++++ src/gallium/include/pipe/p_state.h | 1 + 2 files changed, 7 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index d5d341d689..2e77fb42a8 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -173,6 +173,12 @@ enum pipe_texture_target { #define PIPE_SURFACE 2 /**< user-created surfaces */ +/** + * Surface layout + */ +#define PIPE_SURFACE_LAYOUT_LINEAR 0 + + /** * Surface status */ diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 4936b7f507..571ea8c6e1 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -271,6 +271,7 @@ struct pipe_surface unsigned width; unsigned height; unsigned pitch; /**< in pixels */ + unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ unsigned offset; /**< offset from start of buffer, in bytes */ unsigned refcount; unsigned usage; /**< PIPE_BUFFER_USAGE_* */ -- cgit v1.2.3 From 736f535b4f1c5e6912b5b2fe9415a3b44a678844 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 3 May 2008 09:26:25 -0600 Subject: gallium: fix warnings --- src/gallium/winsys/xlib/xm_winsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 641ec11652..14c3892559 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -606,7 +606,7 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) } -struct pipe_winsys * +static struct pipe_winsys * xmesa_get_pipe_winsys(struct xmesa_visual *xm_vis) { static struct xmesa_pipe_winsys *ws = NULL; -- cgit v1.2.3 From 131a1fbc91725c11e4822b82e58b94ec3a711476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 5 May 2008 23:58:37 +0900 Subject: util: Alternative implementation for standard c library string functions. --- src/gallium/auxiliary/util/u_string.h | 112 ++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h index b99d4e8021..2fede229d9 100644 --- a/src/gallium/auxiliary/util/u_string.h +++ b/src/gallium/auxiliary/util/u_string.h @@ -41,6 +41,8 @@ #include #include +#include "pipe/p_compiler.h" + #ifdef __cplusplus extern "C" { @@ -48,11 +50,121 @@ extern "C" { #ifdef WIN32 + int util_vsnprintf(char *, size_t, const char *, va_list); int util_snprintf(char *str, size_t size, const char *format, ...); + +static INLINE void +util_sprintf(char *str, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + util_vsnprintf(str, (size_t)-1, format, ap); + va_end(ap); +} + +static INLINE char * +util_strchr(const char *s, char c) +{ + while(*s) { + if(*s == c) + return (char *)s; + ++s; + } + return NULL; +} + +static INLINE char* +util_strncat(char *dst, const char *src, size_t n) +{ + char *p = dst + strlen(dst); + const char *q = src; + size_t i; + + for (i = 0; i < n && *q != '\0'; ++i) + *p++ = *q++; + *p = '\0'; + + return dst; +} + +static INLINE int +util_strcmp(const char *s1, const char *s2) +{ + unsigned char u1, u2; + + while (1) { + u1 = (unsigned char) *s1++; + u2 = (unsigned char) *s2++; + if (u1 != u2) + return u1 - u2; + if (u1 == '\0') + return 0; + } + return 0; +} + +static INLINE int +util_strncmp(const char *s1, const char *s2, size_t n) +{ + unsigned char u1, u2; + + while (n-- > 0) { + u1 = (unsigned char) *s1++; + u2 = (unsigned char) *s2++; + if (u1 != u2) + return u1 - u2; + if (u1 == '\0') + return 0; + } + return 0; +} + +static INLINE char * +util_strstr(const char *haystack, const char *needle) +{ + const char *p = haystack; + int len = strlen(needle); + + for (; (p = util_strchr(p, *needle)) != 0; p++) { + if (util_strncmp(p, needle, len) == 0) { + return (char *)p; + } + } + return NULL; +} + +static INLINE void * +util_memmove(void *dest, const void *src, size_t n) +{ + char *p = (char *)dest; + const char *q = (const char *)src; + if (dest < src) { + while (n--) + *p++ = *q++; + } + else + { + p += n; + q += n; + while (n--) + *--p = *--q; + } + return dest; +} + + #else + #define util_vsnprintf vsnprintf #define util_snprintf snprintf +#define util_strchr strchr +#define util_strcmp strcmp +#define util_strncmp strncmp +#define util_strncat strncat +#define util_strstr strstr +#define util_memmove memmove + #endif -- cgit v1.2.3 From 6361d6f48d13ce481253faf106fba5c6a41488ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 6 May 2008 14:57:18 +0900 Subject: gallium: New pipe_screen interface to overlay a texture on existing memory. --- src/gallium/include/pipe/p_screen.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index c080579c26..cc8430dae1 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -89,6 +89,18 @@ struct pipe_screen { struct pipe_texture * (*texture_create)(struct pipe_screen *, const struct pipe_texture *templat); + /** + * Create a new texture object, using the given template info, but on top of + * existing memory. + * + * It is assumed that the buffer data is layed out according to the expected + * by the hardware. NULL will be returned if any inconsistency is found. + */ + struct pipe_texture * (*texture_blanket)(struct pipe_screen *, + const struct pipe_texture *templat, + const unsigned *pitch, + struct pipe_buffer *buffer); + void (*texture_release)(struct pipe_screen *, struct pipe_texture **pt); -- cgit v1.2.3 From 4c6c073f993e13da0b68f897a4221e6bb7875fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 6 May 2008 09:07:11 +0100 Subject: gallium: Define util_sprintf for non-WIN32. --- src/gallium/auxiliary/util/u_string.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h index 2fede229d9..d7d925ee9b 100644 --- a/src/gallium/auxiliary/util/u_string.h +++ b/src/gallium/auxiliary/util/u_string.h @@ -158,6 +158,7 @@ util_memmove(void *dest, const void *src, size_t n) #define util_vsnprintf vsnprintf #define util_snprintf snprintf +#define util_sprintf sprintf #define util_strchr strchr #define util_strcmp strcmp #define util_strncmp strncmp -- cgit v1.2.3 From a6ad4927740e5699f1a047f4c78f069f6a91c6ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 7 May 2008 02:51:49 +0900 Subject: gallium: Simple facility to dump and view images for debugging. --- src/gallium/auxiliary/util/p_debug.c | 47 ++++++++++++++++++++++++++++++++++++ src/gallium/include/pipe/p_debug.h | 11 +++++++++ 2 files changed, 58 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 4ec1746662..f971ee03ba 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -423,3 +423,50 @@ void debug_print_format(const char *msg, unsigned fmt ) debug_printf("%s: %s\n", msg, fmtstr); } #endif + + +#ifdef DEBUG +void debug_dump_image(const char *prefix, + unsigned format, unsigned cpp, + unsigned width, unsigned height, + unsigned pitch, + const void *data) +{ +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY + static unsigned no = 0; + char filename[256]; + WCHAR wfilename[sizeof(filename)]; + ULONG_PTR iFile = 0; + struct { + unsigned format; + unsigned cpp; + unsigned width; + unsigned height; + } header; + unsigned char *pMap = NULL; + unsigned i; + + util_snprintf(filename, sizeof(filename), "\\??\\c:\\%03u%s.raw", ++no, prefix); + for(i = 0; i < sizeof(filename); ++i) + wfilename[i] = (WCHAR)filename[i]; + + pMap = (unsigned char *)EngMapFile(wfilename, sizeof(header) + cpp*width*height, &iFile); + if(!pMap) + return; + + header.format = format; + header.cpp = cpp; + header.width = width; + header.height = height; + memcpy(pMap, &header, sizeof(header)); + pMap += sizeof(header); + + for(i = 0; i < height; ++i) { + memcpy(pMap, (unsigned char *)data + cpp*pitch*i, cpp*width); + pMap += cpp*width; + } + + EngUnmapFile(iFile); +#endif +} +#endif \ No newline at end of file diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 7a7312ea12..1263d0da61 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -313,6 +313,17 @@ void debug_memory_end(unsigned long beginning); +#ifdef DEBUG +void debug_dump_image(const char *prefix, + unsigned format, unsigned cpp, + unsigned width, unsigned height, + unsigned pitch, + const void *data); +#else +#define debug_dump_image(prefix, format, cpp, width, height, pitch, data) ((void)0) +#endif + + #ifdef __cplusplus } #endif -- cgit v1.2.3 From fe06a47361b2db3dfde537aeb0c193495a16905e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 7 May 2008 14:14:48 +0900 Subject: gallium: New PIPE_TEXTURE_USAGE_PRIMARY flag for primary surfaces. --- src/gallium/include/pipe/p_state.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 571ea8c6e1..e7ee8c97ed 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -287,8 +287,9 @@ struct pipe_surface #define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1 #define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */ -#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x4 -#define PIPE_TEXTURE_USAGE_SAMPLER 0x8 +#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */ +#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8 +#define PIPE_TEXTURE_USAGE_SAMPLER 0x10 /** * Texture object. -- cgit v1.2.3 From c7ad942c54c3892a98d248a15af817f256260e75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 7 May 2008 14:17:59 +0900 Subject: gallium: Propagate tex_usage flags down to winsys. --- src/gallium/drivers/i915simple/i915_texture.c | 3 ++- src/gallium/drivers/softpipe/sp_texture.c | 3 ++- src/gallium/include/pipe/p_winsys.h | 3 ++- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 3 ++- src/gallium/winsys/xlib/xm_winsys.c | 3 ++- src/gallium/winsys/xlib/xm_winsys_aub.c | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index f668e2e7d7..3e23e540f9 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -127,7 +127,8 @@ i915_displaytarget_layout(struct pipe_screen *screen, tex->base.width[0], tex->base.height[0], tex->base.format, - flags); + flags, + tex->base.tex_usage); /* Now extract the goodies: */ diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 599ff2ac45..1d7a1fffe4 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -115,7 +115,8 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, spt->base.width[0], spt->base.height[0], spt->base.format, - flags); + flags, + spt->base.tex_usage); /* Now extract the goodies: */ diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index 87a66b66d7..7ebc285192 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -86,7 +86,8 @@ struct pipe_winsys struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags); + unsigned flags, + unsigned tex_usage); void (*surface_release)(struct pipe_winsys *ws, struct pipe_surface **s); diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 77dec9488d..d15143acfd 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -206,7 +206,8 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags) + unsigned flags, + unsigned tex_usage) { const unsigned alignment = 64; int ret; diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index a70752428a..b14758f333 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -489,7 +489,8 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags) + unsigned flags, + unsigned tex_usage) { const unsigned alignment = 64; diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index f42f7fcc5f..77376099f0 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -276,7 +276,8 @@ aub_i915_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags) + unsigned flags, + unsigned tex_usage) { const unsigned alignment = 64; -- cgit v1.2.3 From 4d1bf8a85eae730ca875194864277602f57582ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 7 May 2008 16:29:36 +0900 Subject: gallium: Output the total of leaked memory. --- src/gallium/auxiliary/util/p_debug_mem.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c index 3b5e4fbaee..78497c5f6a 100644 --- a/src/gallium/auxiliary/util/p_debug_mem.c +++ b/src/gallium/auxiliary/util/p_debug_mem.c @@ -211,6 +211,7 @@ debug_memory_begin(void) void debug_memory_end(unsigned long start_no) { + size_t total_size = 0; struct list_head *entry; entry = list.prev; @@ -220,9 +221,15 @@ debug_memory_end(unsigned long start_no) hdr = LIST_ENTRY(struct debug_memory_header, entry, head); ptr = data_from_header(hdr); if(start_no <= hdr->no && hdr->no < last_no || - last_no < start_no && (hdr->no < last_no || start_no <= hdr->no)) + last_no < start_no && (hdr->no < last_no || start_no <= hdr->no)) { debug_printf("%s:%u:%s: %u bytes at %p not freed\n", hdr->file, hdr->line, hdr->function, hdr->size, ptr); + total_size += hdr->size; + } + } + if(total_size) { + debug_printf("Total of %u KB of system memory apparently leaked\n", + (total_size + 1023)/1024); } } -- cgit v1.2.3 From 942b02956e7889aab977cf465fddb0055b758af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 7 May 2008 19:39:34 +0900 Subject: gallium: Use the u_string.h functions. --- src/gallium/auxiliary/util/p_debug.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index f971ee03ba..0e233580d6 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -67,7 +67,7 @@ void _debug_vprintf(const char *format, va_list ap) static char buf[512 + 1] = {'\0'}; size_t len = strlen(buf); int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap); - if(ret > (int)(sizeof(buf) - len - 1) || strchr(buf + len, '\n')) { + if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) { _EngDebugPrint("%s", buf); buf[0] = '\0'; } @@ -203,15 +203,15 @@ debug_get_bool_option(const char *name, boolean dfault) if(str == NULL) result = dfault; - else if(!strcmp(str, "n")) + else if(!util_strcmp(str, "n")) result = FALSE; - else if(!strcmp(str, "no")) + else if(!util_strcmp(str, "no")) result = FALSE; - else if(!strcmp(str, "0")) + else if(!util_strcmp(str, "0")) result = FALSE; - else if(!strcmp(str, "f")) + else if(!util_strcmp(str, "f")) result = FALSE; - else if(!strcmp(str, "false")) + else if(!util_strcmp(str, "false")) result = FALSE; else result = TRUE; @@ -244,7 +244,7 @@ debug_get_flags_option(const char *name, else { result = 0; while( flags->name ) { - if (!strcmp(str, "all") || strstr(str, flags->name )) + if (!util_strcmp(str, "all") || util_strstr(str, flags->name )) result |= flags->value; ++flags; } @@ -299,10 +299,10 @@ debug_dump_flags(const struct debug_named_value *names, while(names->name) { if((names->value & value) == names->value) { if (!first) - strncat(output, "|", sizeof(output)); + util_strncat(output, "|", sizeof(output)); else first = 0; - strncat(output, names->name, sizeof(output)); + util_strncat(output, names->name, sizeof(output)); value &= ~names->value; } ++names; @@ -310,12 +310,12 @@ debug_dump_flags(const struct debug_named_value *names, if (value) { if (!first) - strncat(output, "|", sizeof(output)); + util_strncat(output, "|", sizeof(output)); else first = 0; util_snprintf(rest, sizeof(rest), "0x%08lx", value); - strncat(output, rest, sizeof(output)); + util_strncat(output, rest, sizeof(output)); } if(first) @@ -325,10 +325,6 @@ debug_dump_flags(const struct debug_named_value *names, } - - - - char *pf_sprint_name( char *str, enum pipe_format format ) { strcpy( str, "PIPE_FORMAT_" ); @@ -469,4 +465,4 @@ void debug_dump_image(const char *prefix, EngUnmapFile(iFile); #endif } -#endif \ No newline at end of file +#endif -- cgit v1.2.3 From 55c13f5af7903c2a0f5a1839259a0a0cc15d6e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 7 May 2008 20:27:42 +0900 Subject: gallium: Implement pf_sprint_name as a simple static table. --- src/gallium/auxiliary/util/p_debug.c | 180 +++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 83 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 0e233580d6..3f3cf620fe 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -327,96 +327,110 @@ debug_dump_flags(const struct debug_named_value *names, char *pf_sprint_name( char *str, enum pipe_format format ) { - strcpy( str, "PIPE_FORMAT_" ); - switch (pf_layout( format )) { - case PIPE_FORMAT_LAYOUT_RGBAZS: - { - pipe_format_rgbazs_t rgbazs = (pipe_format_rgbazs_t) format; - uint i; - uint scale = 1 << (pf_exp8( rgbazs ) * 3); - - for (i = 0; i < 4; i++) { - uint size = pf_size_xyzw( rgbazs, i ); - - if (size == 0) { - break; - } - switch (pf_swizzle_xyzw( rgbazs, i )) { - case PIPE_FORMAT_COMP_R: - strcat( str, "R" ); - break; - case PIPE_FORMAT_COMP_G: - strcat( str, "G" ); - break; - case PIPE_FORMAT_COMP_B: - strcat( str, "B" ); - break; - case PIPE_FORMAT_COMP_A: - strcat( str, "A" ); - break; - case PIPE_FORMAT_COMP_0: - strcat( str, "0" ); - break; - case PIPE_FORMAT_COMP_1: - strcat( str, "1" ); - break; - case PIPE_FORMAT_COMP_Z: - strcat( str, "Z" ); - break; - case PIPE_FORMAT_COMP_S: - strcat( str, "S" ); - break; - } - util_snprintf( &str[strlen( str )], 32, "%u", size * scale ); - } - if (i != 0) { - strcat( str, "_" ); - } - switch (pf_type( rgbazs )) { - case PIPE_FORMAT_TYPE_UNKNOWN: - strcat( str, "NONE" ); - break; - case PIPE_FORMAT_TYPE_FLOAT: - strcat( str, "FLOAT" ); - break; - case PIPE_FORMAT_TYPE_UNORM: - strcat( str, "UNORM" ); - break; - case PIPE_FORMAT_TYPE_SNORM: - strcat( str, "SNORM" ); - break; - case PIPE_FORMAT_TYPE_USCALED: - strcat( str, "USCALED" ); - break; - case PIPE_FORMAT_TYPE_SSCALED: - strcat( str, "SSCALED" ); - break; - } - } - break; - case PIPE_FORMAT_LAYOUT_YCBCR: - { - pipe_format_ycbcr_t ycbcr = (pipe_format_ycbcr_t) format; - - strcat( str, "YCBCR" ); - if (pf_rev( ycbcr )) { - strcat( str, "_REV" ); - } - } - break; - } + strcpy( str, debug_dump_enum(pipe_format_names, fmt) ); return str; } #ifdef DEBUG +static const struct debug_named_value pipe_format_names[] = { + DEBUG_NAMED_VALUE(PIPE_FORMAT_NONE), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A1R5G5B5_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A4R4G4B4_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R5G6B5_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_I8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR), + DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR_REV), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_S8Z24_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24S8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_X8Z24_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24X8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_S8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64A64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_L8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_RGBA), + DEBUG_NAMED_VALUE_END +}; + void debug_print_format(const char *msg, unsigned fmt ) { - char fmtstr[80]; - - pf_sprint_name(fmtstr, (enum pipe_format)fmt); - - debug_printf("%s: %s\n", msg, fmtstr); + debug_printf("%s: %s\n", msg, debug_dump_enum(pipe_format_names, fmt)); } #endif -- cgit v1.2.3 From 5efd2d59eb19cc44624d3f842d3d1d291876ae7d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 7 May 2008 14:24:14 +0200 Subject: gallium: Fix compilation errors. --- src/gallium/auxiliary/util/p_debug.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 3f3cf620fe..0f3a99cf83 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -325,13 +325,6 @@ debug_dump_flags(const struct debug_named_value *names, } -char *pf_sprint_name( char *str, enum pipe_format format ) -{ - strcpy( str, debug_dump_enum(pipe_format_names, fmt) ); - return str; -} - - #ifdef DEBUG static const struct debug_named_value pipe_format_names[] = { DEBUG_NAMED_VALUE(PIPE_FORMAT_NONE), @@ -432,6 +425,12 @@ void debug_print_format(const char *msg, unsigned fmt ) { debug_printf("%s: %s\n", msg, debug_dump_enum(pipe_format_names, fmt)); } + +char *pf_sprint_name( char *str, enum pipe_format format ) +{ + strcpy( str, debug_dump_enum(pipe_format_names, format) ); + return str; +} #endif -- cgit v1.2.3 From 33cda1e5e57838845ec62714677832f7cdabc5dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 7 May 2008 21:37:32 +0900 Subject: gallium: Fix release build. pf_sprint_name might be used there too. --- src/gallium/auxiliary/util/p_debug.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 0f3a99cf83..951dd5a2d4 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -325,8 +325,8 @@ debug_dump_flags(const struct debug_named_value *names, } -#ifdef DEBUG static const struct debug_named_value pipe_format_names[] = { +#ifdef DEBUG DEBUG_NAMED_VALUE(PIPE_FORMAT_NONE), DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_UNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_UNORM), @@ -418,20 +418,22 @@ static const struct debug_named_value pipe_format_names[] = { DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA), DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA), DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_RGBA), +#endif DEBUG_NAMED_VALUE_END }; +#ifdef DEBUG void debug_print_format(const char *msg, unsigned fmt ) { debug_printf("%s: %s\n", msg, debug_dump_enum(pipe_format_names, fmt)); } +#endif char *pf_sprint_name( char *str, enum pipe_format format ) { strcpy( str, debug_dump_enum(pipe_format_names, format) ); return str; } -#endif #ifdef DEBUG -- cgit v1.2.3 From 10b7192747087ec25f97cdfcfc062654a2d8fe6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 7 May 2008 22:01:27 +0900 Subject: gallium: Implement util_pack_color for A8, L8, and I8 formats. --- src/gallium/auxiliary/util/u_pack_color.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 0b917c005f..655e2c8259 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -101,6 +101,19 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); } return; + case PIPE_FORMAT_A8_UNORM: + { + ubyte *d = (ubyte *) dest; + *d = a; + } + return; + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_I8_UNORM: + { + ubyte *d = (ubyte *) dest; + *d = r; + } + return; case PIPE_FORMAT_R32G32B32A32_FLOAT: { float *d = (float *) dest; @@ -198,6 +211,19 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest) *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); } return; + case PIPE_FORMAT_A8_UNORM: + { + ubyte *d = (ubyte *) dest; + *d = a; + } + return; + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_I8_UNORM: + { + ubyte *d = (ubyte *) dest; + *d = r; + } + return; case PIPE_FORMAT_R32G32B32A32_FLOAT: { float *d = (float *) dest; -- cgit v1.2.3 From 53996e562f8623ccb1defeaaa77efdff24477808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 8 May 2008 14:56:03 +0900 Subject: pipebuffer: Don't include standard headers directly. --- src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 8de286e3f9..f6cc7a525b 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -50,7 +50,8 @@ #define PB_BUFMGR_H_ -#include +#include "pipe/p_compiler.h" +#include "pipe/p_error.h" #ifdef __cplusplus @@ -68,7 +69,6 @@ struct pipe_winsys; */ struct pb_manager { - /* XXX: we will likely need more allocation flags */ struct pb_buffer * (*create_buffer)( struct pb_manager *mgr, size_t size, -- cgit v1.2.3 From 665b327a47ce80d136e91cfafedbc165227ea168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 8 May 2008 15:19:07 +0900 Subject: gallium: Really free hash entries. Hook up to the new cso_hash_erase function. --- src/gallium/auxiliary/util/u_hash_table.c | 77 +++++++++++++++++++++++++++---- src/gallium/auxiliary/util/u_hash_table.h | 4 ++ 2 files changed, 72 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c index f3f16a8d94..dd5eca7fca 100644 --- a/src/gallium/auxiliary/util/u_hash_table.c +++ b/src/gallium/auxiliary/util/u_hash_table.c @@ -67,6 +67,13 @@ struct hash_table_item }; +static INLINE struct hash_table_item * +hash_table_item(struct cso_hash_iter iter) +{ + return (struct hash_table_item *)cso_hash_iter_data(iter); +} + + struct hash_table * hash_table_create(unsigned (*hash)(void *key), int (*compare)(void *key1, void *key2)) @@ -90,7 +97,27 @@ hash_table_create(unsigned (*hash)(void *key), } -static struct hash_table_item * +static INLINE struct cso_hash_iter +hash_table_find_iter(struct hash_table *ht, + void *key, + unsigned key_hash) +{ + struct cso_hash_iter iter; + struct hash_table_item *item; + + iter = cso_hash_find(ht->cso, key_hash); + while (!cso_hash_iter_is_null(iter)) { + item = (struct hash_table_item *)cso_hash_iter_data(iter); + if (!ht->compare(item->key, key)) + break; + iter = cso_hash_iter_next(iter); + } + + return iter; +} + + +static INLINE struct hash_table_item * hash_table_find_item(struct hash_table *ht, void *key, unsigned key_hash) @@ -117,6 +144,7 @@ hash_table_set(struct hash_table *ht, { unsigned key_hash; struct hash_table_item *item; + struct cso_hash_iter iter; assert(ht); @@ -136,9 +164,8 @@ hash_table_set(struct hash_table *ht, item->key = key; item->value = value; - cso_hash_insert(ht->cso, key_hash, item); - /* FIXME: there is no OOM propagation in cso_hash */ - if(0) { + iter = cso_hash_insert(ht->cso, key_hash, item); + if(cso_hash_iter_is_null(iter)) { FREE(item); return PIPE_ERROR_OUT_OF_MEMORY; } @@ -171,19 +198,39 @@ hash_table_remove(struct hash_table *ht, void *key) { unsigned key_hash; + struct cso_hash_iter iter; struct hash_table_item *item; assert(ht); key_hash = ht->hash(key); - item = hash_table_find_item(ht, key, key_hash); - if(!item) + iter = hash_table_find_iter(ht, key, key_hash); + if(cso_hash_iter_is_null(iter)) return; - /* FIXME: cso_hash_take takes the first element of the collision list - * indiscriminately, so we can not take the item down. */ - item->value = NULL; + item = hash_table_item(iter); + assert(item); + FREE(item); + + cso_hash_erase(ht->cso, iter); +} + + +void +hash_table_clear(struct hash_table *ht) +{ + struct cso_hash_iter iter; + struct hash_table_item *item; + + assert(ht); + + iter = cso_hash_first_node(ht->cso); + while (!cso_hash_iter_is_null(iter)) { + item = (struct hash_table_item *)cso_hash_take(ht->cso, cso_hash_iter_key(iter)); + FREE(item); + iter = cso_hash_first_node(ht->cso); + } } @@ -196,6 +243,8 @@ hash_table_foreach(struct hash_table *ht, struct hash_table_item *item; enum pipe_error result; + assert(ht); + iter = cso_hash_first_node(ht->cso); while (!cso_hash_iter_is_null(iter)) { item = (struct hash_table_item *)cso_hash_iter_data(iter); @@ -212,7 +261,17 @@ hash_table_foreach(struct hash_table *ht, void hash_table_destroy(struct hash_table *ht) { + struct cso_hash_iter iter; + struct hash_table_item *item; + assert(ht); + + iter = cso_hash_first_node(ht->cso); + while (!cso_hash_iter_is_null(iter)) { + item = (struct hash_table_item *)cso_hash_iter_data(iter); + FREE(item); + iter = cso_hash_iter_next(iter); + } cso_hash_delete(ht->cso); diff --git a/src/gallium/auxiliary/util/u_hash_table.h b/src/gallium/auxiliary/util/u_hash_table.h index 1583bd7548..feee881582 100644 --- a/src/gallium/auxiliary/util/u_hash_table.h +++ b/src/gallium/auxiliary/util/u_hash_table.h @@ -75,6 +75,10 @@ hash_table_remove(struct hash_table *ht, void *key); +void +hash_table_clear(struct hash_table *ht); + + enum pipe_error hash_table_foreach(struct hash_table *ht, enum pipe_error (*callback)(void *key, void *value, void *data), -- cgit v1.2.3 From 82dd0225e7e21a35ca66d439dce8cfa39d782470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 8 May 2008 15:28:42 +0900 Subject: pipebuffer: Preliminary buffer validation. Use table to store a list of buffers to validate. Unfortunately cso_hash shrinks/regrows the hash every time, so still has to be addressed. Multi-thread validation is still WIP. --- src/gallium/auxiliary/pipebuffer/Makefile | 1 + src/gallium/auxiliary/pipebuffer/SConscript | 1 + src/gallium/auxiliary/pipebuffer/pb_validate.c | 170 +++++++++++++++++++++++++ src/gallium/auxiliary/pipebuffer/pb_validate.h | 91 +++++++++++++ 4 files changed, 263 insertions(+) create mode 100644 src/gallium/auxiliary/pipebuffer/pb_validate.c create mode 100644 src/gallium/auxiliary/pipebuffer/pb_validate.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile index d654dbcc91..ff09011b66 100644 --- a/src/gallium/auxiliary/pipebuffer/Makefile +++ b/src/gallium/auxiliary/pipebuffer/Makefile @@ -11,6 +11,7 @@ C_SOURCES = \ pb_bufmgr_mm.c \ pb_bufmgr_pool.c \ pb_bufmgr_slab.c \ + pb_validate.c \ pb_winsys.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript index 604a217982..9db0c0eae3 100644 --- a/src/gallium/auxiliary/pipebuffer/SConscript +++ b/src/gallium/auxiliary/pipebuffer/SConscript @@ -10,6 +10,7 @@ pipebuffer = env.ConvenienceLibrary( 'pb_bufmgr_mm.c', 'pb_bufmgr_pool.c', 'pb_bufmgr_slab.c', + 'pb_validate.c', 'pb_winsys.c', ]) diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c new file mode 100644 index 0000000000..a0a0965a46 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c @@ -0,0 +1,170 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Buffer validation. + * + * @author Jose Fonseca + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_error.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" + +#include "util/u_hash_table.h" + +#include "pb_buffer.h" +#include "pb_buffer_fenced.h" + + +struct pb_validate +{ + struct hash_table *buffer_table; +}; + + +static unsigned buffer_table_hash(void *pb_buf) +{ + return (unsigned)(uintptr_t)pb_buf; +} + + +static int buffer_table_compare(void *pb_buf1, void *pb_buf2) +{ + return (char *)pb_buf2 - (char *)pb_buf1; +} + + +enum pipe_error +pb_validate_add_buffer(struct pb_validate *vl, + struct pb_buffer *buf) +{ + enum pipe_error ret; + + assert(buf); + if(!buf) + return PIPE_ERROR; + + if(!hash_table_get(vl->buffer_table, buf)) { + struct pb_buffer *tmp = NULL; + + ret = hash_table_set(vl->buffer_table, buf, buf); + if(ret != PIPE_OK) + return ret; + + /* Increment reference count */ + pb_reference(&tmp, buf); + } + + return PIPE_OK; +} + + +enum pipe_error +pb_validate_validate(struct pb_validate *vl) +{ + /* FIXME: go through each buffer, ensure its not mapped, its address is + * available -- requires a new pb_buffer interface */ + return PIPE_OK; +} + + +struct pb_validate_fence_data { + struct pb_validate *vl; + struct pipe_fence_handle *fence; +}; + + +static enum pipe_error +pb_validate_fence_cb(void *key, void *value, void *_data) +{ + struct pb_buffer *buf = (struct pb_buffer *)key; + struct pb_validate_fence_data *data = (struct pb_validate_fence_data *)_data; + struct pb_validate *vl = data->vl; + struct pipe_fence_handle *fence = data->fence; + + assert(value == key); + + buffer_fence(buf, fence); + + /* Decrement the reference count -- table entry destroyed later */ + pb_reference(&buf, NULL); + + return PIPE_OK; +} + + +void +pb_validate_fence(struct pb_validate *vl, + struct pipe_fence_handle *fence) +{ + struct pb_validate_fence_data data; + + data.vl = vl; + data.fence = fence; + + hash_table_foreach(vl->buffer_table, + pb_validate_fence_cb, + &data); + + /* FIXME: cso_hash shrinks here, which is not desirable in this use case, + * as it will be refilled right soon */ + hash_table_clear(vl->buffer_table); +} + + +void +pb_validate_destroy(struct pb_validate *vl) +{ + pb_validate_fence(vl, NULL); + hash_table_destroy(vl->buffer_table); + FREE(vl); +} + + +struct pb_validate * +pb_validate_create() +{ + struct pb_validate *vl; + + vl = CALLOC_STRUCT(pb_validate); + if(!vl) + return NULL; + + vl->buffer_table = hash_table_create(buffer_table_hash, + buffer_table_compare); + if(!vl->buffer_table) { + FREE(vl); + return NULL; + } + + return vl; +} + diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.h b/src/gallium/auxiliary/pipebuffer/pb_validate.h new file mode 100644 index 0000000000..b0f05d3119 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.h @@ -0,0 +1,91 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Buffer validation. + * + * @author Jose Fonseca + */ + +#ifndef PB_VALIDATE_H_ +#define PB_VALIDATE_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +struct pb_buffer; +struct pipe_fence_handle; + + +/** + * Buffer validation list. + * + * It holds a list of buffers to be validated and fenced when flushing. + */ +struct pb_validate; + + +enum pipe_error +pb_validate_add_buffer(struct pb_validate *vl, + struct pb_buffer *buf); + +/** + * Validate all buffers for hardware access. + * + * Should be called right before issuing commands to the hardware. + */ +enum pipe_error +pb_validate_validate(struct pb_validate *vl); + +/** + * Fence all buffers and clear the list. + * + * Should be called right before issuing commands to the hardware. + */ +void +pb_validate_fence(struct pb_validate *vl, + struct pipe_fence_handle *fence); + +struct pb_validate * +pb_validate_create(); + +void +pb_validate_destroy(struct pb_validate *vl); + + +#ifdef __cplusplus +} +#endif + +#endif /*PB_VALIDATE_H_*/ -- cgit v1.2.3 From 7ffbfaccfb1484a4ffd5aea0e0e1fbb407977a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 8 May 2008 13:26:23 +0100 Subject: gallium: Make sure functions have proper prototypes and remove unused variable. --- src/gallium/auxiliary/pipebuffer/pb_validate.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_validate.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c index a0a0965a46..b32fe2252e 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_validate.c +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c @@ -42,6 +42,7 @@ #include "pb_buffer.h" #include "pb_buffer_fenced.h" +#include "pb_validate.h" struct pb_validate @@ -107,7 +108,6 @@ pb_validate_fence_cb(void *key, void *value, void *_data) { struct pb_buffer *buf = (struct pb_buffer *)key; struct pb_validate_fence_data *data = (struct pb_validate_fence_data *)_data; - struct pb_validate *vl = data->vl; struct pipe_fence_handle *fence = data->fence; assert(value == key); diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.h b/src/gallium/auxiliary/pipebuffer/pb_validate.h index b0f05d3119..3db1d5330b 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_validate.h +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.h @@ -78,7 +78,7 @@ pb_validate_fence(struct pb_validate *vl, struct pipe_fence_handle *fence); struct pb_validate * -pb_validate_create(); +pb_validate_create(void); void pb_validate_destroy(struct pb_validate *vl); -- cgit v1.2.3 From 8eab7de888bb4056c34f80edfbc90a543736ea3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 9 May 2008 00:08:57 +0900 Subject: pipebuffer: Temporarily reimplement validation as growable array. Jose --- src/gallium/auxiliary/pipebuffer/pb_validate.c | 113 +++++++++++-------------- 1 file changed, 48 insertions(+), 65 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c index b32fe2252e..362fd896f3 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_validate.c +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c @@ -38,52 +38,63 @@ #include "pipe/p_util.h" #include "pipe/p_debug.h" -#include "util/u_hash_table.h" - #include "pb_buffer.h" #include "pb_buffer_fenced.h" #include "pb_validate.h" -struct pb_validate -{ - struct hash_table *buffer_table; -}; +#define PB_VALIDATE_INITIAL_SIZE 1 /* 512 */ -static unsigned buffer_table_hash(void *pb_buf) -{ - return (unsigned)(uintptr_t)pb_buf; -} - - -static int buffer_table_compare(void *pb_buf1, void *pb_buf2) +struct pb_validate { - return (char *)pb_buf2 - (char *)pb_buf1; -} + struct pb_buffer **buffers; + unsigned used; + unsigned size; +}; enum pipe_error pb_validate_add_buffer(struct pb_validate *vl, struct pb_buffer *buf) { - enum pipe_error ret; - assert(buf); if(!buf) return PIPE_ERROR; + + /* We only need to store one reference for each buffer, so avoid storing + * consecutive references for the same buffer. It might not be the more + * common pasttern, but it is easy to implement. + */ + if(vl->used && vl->buffers[vl->used - 1] == buf) { + return PIPE_OK; + } - if(!hash_table_get(vl->buffer_table, buf)) { - struct pb_buffer *tmp = NULL; + /* Grow the table */ + if(vl->used == vl->size) { + unsigned new_size; + struct pb_buffer **new_buffers; + + new_size = vl->size * 2; + if(!new_size) + return PIPE_ERROR_OUT_OF_MEMORY; + + new_buffers = (struct pb_buffer **)REALLOC(vl->buffers, + vl->size*sizeof(struct pb_buffer *), + new_size*sizeof(struct pb_buffer *)); + if(!new_buffers) + return PIPE_ERROR_OUT_OF_MEMORY; - ret = hash_table_set(vl->buffer_table, buf, buf); - if(ret != PIPE_OK) - return ret; + memset(new_buffers + vl->size, 0, (new_size - vl->size)*sizeof(struct pb_buffer *)); - /* Increment reference count */ - pb_reference(&tmp, buf); + vl->size = new_size; + vl->buffers = new_buffers; } + assert(!vl->buffers[vl->used]); + pb_reference(&vl->buffers[vl->used], buf); + ++vl->used; + return PIPE_OK; } @@ -97,54 +108,26 @@ pb_validate_validate(struct pb_validate *vl) } -struct pb_validate_fence_data { - struct pb_validate *vl; - struct pipe_fence_handle *fence; -}; - - -static enum pipe_error -pb_validate_fence_cb(void *key, void *value, void *_data) -{ - struct pb_buffer *buf = (struct pb_buffer *)key; - struct pb_validate_fence_data *data = (struct pb_validate_fence_data *)_data; - struct pipe_fence_handle *fence = data->fence; - - assert(value == key); - - buffer_fence(buf, fence); - - /* Decrement the reference count -- table entry destroyed later */ - pb_reference(&buf, NULL); - - return PIPE_OK; -} - - void pb_validate_fence(struct pb_validate *vl, struct pipe_fence_handle *fence) { - struct pb_validate_fence_data data; - - data.vl = vl; - data.fence = fence; - - hash_table_foreach(vl->buffer_table, - pb_validate_fence_cb, - &data); - - /* FIXME: cso_hash shrinks here, which is not desirable in this use case, - * as it will be refilled right soon */ - hash_table_clear(vl->buffer_table); + unsigned i; + for(i = 0; i < vl->used; ++i) { + buffer_fence(vl->buffers[i], fence); + pb_reference(&vl->buffers[i], NULL); + } + vl->used = 0; } void pb_validate_destroy(struct pb_validate *vl) { - pb_validate_fence(vl, NULL); - hash_table_destroy(vl->buffer_table); + unsigned i; + for(i = 0; i < vl->used; ++i) + pb_reference(&vl->buffers[i], NULL); + FREE(vl->buffers); FREE(vl); } @@ -158,9 +141,9 @@ pb_validate_create() if(!vl) return NULL; - vl->buffer_table = hash_table_create(buffer_table_hash, - buffer_table_compare); - if(!vl->buffer_table) { + vl->size = PB_VALIDATE_INITIAL_SIZE; + vl->buffers = (struct pb_buffer **)CALLOC(vl->size, sizeof(struct pb_buffer *)); + if(!vl->buffers) { FREE(vl); return NULL; } -- cgit v1.2.3 From 1dfb3d4729ce4cd71a593c14dbb2907cd987f8ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 8 May 2008 19:00:11 +0100 Subject: cso_cache: Fix test for currently bound blend state. --- src/gallium/auxiliary/cso_cache/cso_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index eef898f486..a1a3a9efaf 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -84,7 +84,7 @@ static boolean delete_blend_state(struct cso_context *ctx, void *state) { struct cso_blend *cso = (struct cso_blend *)state; - if (ctx->blend == state) + if (ctx->blend == cso->data) return FALSE; if (cso->delete_state) -- cgit v1.2.3 From 2abc1b3641e435e0b68490fa6b0a7ffa7c030c76 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 1 May 2008 12:38:51 -0400 Subject: abstract fetching elts --- src/gallium/auxiliary/draw/draw_pt_varray.c | 17 +++++++++++------ src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 6 ++---- 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index 355093f945..b0bd2b983e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -43,6 +43,8 @@ struct varray_frontend { unsigned draw_count; unsigned fetch_count; + unsigned fetch_start; + struct draw_pt_middle_end *middle; unsigned input_prim; @@ -68,15 +70,18 @@ static void varray_flush(struct varray_frontend *varray) varray->draw_count = 0; } -#if 0 -static void varray_check_flush(struct varray_frontend *varray) +static INLINE void fetch_init(struct varray_frontend *varray, + unsigned current_count, + unsigned count) { - if (varray->draw_count + 6 >= DRAW_MAX/* || - varray->fetch_count + 4 >= FETCH_MAX*/) { - varray_flush(varray); + unsigned idx; + const unsigned end = MIN2(FETCH_MAX, count - current_count); + for (idx = 0; idx < end; ++idx) { + varray->fetch_elts[idx] = varray->fetch_start + idx; } + varray->fetch_start += idx; + varray->fetch_count = idx; } -#endif static INLINE void add_draw_el(struct varray_frontend *varray, int idx, ushort flags) diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h index b9a319b253..a3509613f5 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -20,10 +20,8 @@ static void FUNC(struct draw_pt_front_end *frontend, start, count); #endif - for (i = 0; i < count; ++i) { - varray->fetch_elts[i] = start + i; - } - varray->fetch_count = count; + varray->fetch_start = start; + fetch_init(varray, 0, count); switch (varray->input_prim) { case PIPE_PRIM_POINTS: -- cgit v1.2.3 From 90a46ed277cc887d49c8d8c627174c3bd693ecf7 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 1 May 2008 23:54:39 -0400 Subject: split larger primitives in the simple varray pt --- src/gallium/auxiliary/draw/draw_pt.c | 3 +- src/gallium/auxiliary/draw/draw_pt_varray.c | 62 ++++++++- src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 169 +++++++++++++++++------- 3 files changed, 180 insertions(+), 54 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index c9c5d18313..bccde6c5fd 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -80,8 +80,7 @@ draw_pt_arrays(struct draw_context *draw, /* Pick the right frontend */ - if (draw->pt.user.elts || - count >= 256) { + if (draw->pt.user.elts) { frontend = draw->pt.front.vcache; } else { frontend = draw->pt.front.varray; diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index b0bd2b983e..c9843bded0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -58,6 +58,11 @@ static void varray_flush(struct varray_frontend *varray) debug_printf("FLUSH fc = %d, dc = %d\n", varray->fetch_count, varray->draw_count); + debug_printf("\telt0 = %d, eltx = %d, draw0 = %d, drawx = %d\n", + varray->fetch_elts[0], + varray->fetch_elts[varray->fetch_count-1], + varray->draw_elts[0], + varray->draw_elts[varray->draw_count-1]); #endif varray->middle->run(varray->middle, varray->fetch_elts, @@ -71,18 +76,69 @@ static void varray_flush(struct varray_frontend *varray) } static INLINE void fetch_init(struct varray_frontend *varray, - unsigned current_count, unsigned count) { unsigned idx; - const unsigned end = MIN2(FETCH_MAX, count - current_count); - for (idx = 0; idx < end; ++idx) { +#if 0 + debug_printf("FETCH INIT c = %d, fs = %d\n", + count, + varray->fetch_start); +#endif + for (idx = 0; idx < count; ++idx) { varray->fetch_elts[idx] = varray->fetch_start + idx; } varray->fetch_start += idx; varray->fetch_count = idx; } + +static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr) +{ + switch (prim) { + case PIPE_PRIM_POINTS: + *first = 1; + *incr = 1; + return TRUE; + case PIPE_PRIM_LINES: + *first = 2; + *incr = 2; + return TRUE; + case PIPE_PRIM_LINE_STRIP: + *first = 2; + *incr = 1; + return TRUE; + case PIPE_PRIM_TRIANGLES: + *first = 3; + *incr = 3; + return TRUE; + case PIPE_PRIM_TRIANGLE_STRIP: + *first = 3; + *incr = 1; + return TRUE; + case PIPE_PRIM_TRIANGLE_FAN: + *first = 3; + *incr = 1; + return TRUE; + case PIPE_PRIM_QUADS: + *first = 4; + *incr = 4; + return TRUE; + case PIPE_PRIM_QUAD_STRIP: + *first = 4; + *incr = 2; + return TRUE; + case PIPE_PRIM_POLYGON: + *first = 3; + *incr = 1; + return TRUE; + default: + *first = 0; + *incr = 1; /* set to one so that count % incr works */ + return FALSE; + } +} + + static INLINE void add_draw_el(struct varray_frontend *varray, int idx, ushort flags) { diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h index a3509613f5..073c1aadbf 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -10,30 +10,42 @@ static void FUNC(struct draw_pt_front_end *frontend, boolean flatfirst = (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first); - unsigned i, flags; + unsigned i, j, flags; + unsigned first, incr; -#if 0 - debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count); -#endif -#if 0 - debug_printf("INPUT PRIM = %d (start = %d, count = %d)\n", varray->input_prim, + varray->fetch_start = start; + + split_prim_inplace(varray->input_prim, &first, &incr); + +#if 1 + debug_printf("%s (%d) %d/%d\n", __FUNCTION__, + varray->input_prim, start, count); #endif - varray->fetch_start = start; - fetch_init(varray, 0, count); - switch (varray->input_prim) { case PIPE_PRIM_POINTS: - for (i = 0; i < count; i ++) { - POINT(varray, i + 0); + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i < count; i ++) { + POINT(varray, i + 0); + } + fetch_init(varray, end); + varray_flush(varray); } break; case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - LINE(varray, DRAW_PIPE_RESET_STIPPLE, - i + 0, i + 1); + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+1 < end; i += 2) { + LINE(varray, DRAW_PIPE_RESET_STIPPLE, + i + 0, i + 1); + } + fetch_init(varray, end); + varray_flush(varray); } break; @@ -41,38 +53,68 @@ static void FUNC(struct draw_pt_front_end *frontend, if (count >= 2) { flags = DRAW_PIPE_RESET_STIPPLE; - for (i = 1; i < count; i++, flags = 0) { - LINE(varray, flags, i - 1, i); + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 1; i < end; i++, flags = 0) { + LINE(varray, flags, i - 1, i); + } + LINE(varray, flags, i - 1, 0); + fetch_init(varray, end); + varray_flush(varray); } - LINE(varray, flags, i - 1, 0); } break; case PIPE_PRIM_LINE_STRIP: flags = DRAW_PIPE_RESET_STIPPLE; - for (i = 1; i < count; i++, flags = 0) { - LINE(varray, flags, i - 1, i); + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 1; i < end; i++, flags = 0) { + LINE(varray, flags, i - 1, i); + } + fetch_init(varray, end); + varray_flush(varray); } break; case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - i + 0, i + 1, i + 2); + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+2 < end; i += 3) { + TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + i + 0, i + 1, i + 2); + } + fetch_init(varray, end); + varray_flush(varray); } break; case PIPE_PRIM_TRIANGLE_STRIP: if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - i + 0, i + 1 + (i&1), i + 2 - (i&1)); + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+2 < end; i++) { + TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + i + 0, i + 1 + (i&1), i + 2 - (i&1)); + } + fetch_init(varray, end); + varray_flush(varray); } } else { - for (i = 0; i+2 < count; i++) { - TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - i + 0 + (i&1), i + 1 - (i&1), i + 2); + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+2 < end; i++) { + TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + i + 0 + (i&1), i + 1 - (i&1), i + 2); + } + fetch_init(varray, end); + varray_flush(varray); } } break; @@ -81,51 +123,80 @@ static void FUNC(struct draw_pt_front_end *frontend, if (count >= 3) { if (flatfirst) { flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; - for (i = 0; i+2 < count; i++) { - TRIANGLE(varray, flags, i + 1, i + 2, 0); + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+2 < end; i++) { + TRIANGLE(varray, flags, i + 1, i + 2, 0); + } + fetch_init(varray, end); + varray_flush(varray); } } else { flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; - for (i = 0; i+2 < count; i++) { - TRIANGLE(varray, flags, 0, i + 1, i + 2); + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+2 < end; i++) { + TRIANGLE(varray, flags, 0, i + 1, i + 2); + } + fetch_init(varray, end); + varray_flush(varray); } } } break; case PIPE_PRIM_QUADS: - for (i = 0; i+3 < count; i += 4) { - QUAD(varray, i + 0, i + 1, i + 2, i + 3); + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+3 < end; i += 4) { + QUAD(varray, i + 0, i + 1, i + 2, i + 3); + } + fetch_init(varray, end); + varray_flush(varray); } break; case PIPE_PRIM_QUAD_STRIP: - for (i = 0; i+3 < count; i += 2) { - QUAD(varray, i + 2, i + 0, i + 1, i + 3); + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+3 < end; i += 2) { + QUAD(varray, i + 2, i + 0, i + 1, i + 3); + } + fetch_init(varray, end); + varray_flush(varray); } break; case PIPE_PRIM_POLYGON: { - /* These bitflags look a little odd because we submit the - * vertices as (1,2,0) to satisfy flatshade requirements. - */ - const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2; - const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1; - - flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; - - for (i = 0; i+2 < count; i++, flags = edge_middle) { + /* These bitflags look a little odd because we submit the + * vertices as (1,2,0) to satisfy flatshade requirements. + */ + const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2; + const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0; + const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1; + + flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+2 < end; i++, flags = edge_middle) { if (i + 3 == count) flags |= edge_last; - TRIANGLE(varray, flags, i + 1, i + 2, 0); - } + TRIANGLE(varray, flags, i + 1, i + 2, 0); + } + fetch_init(varray, end); + varray_flush(varray); } - break; + } + break; default: assert(0); -- cgit v1.2.3 From abb08e9335b5d7cb004dc9e6cec390ab6968abe5 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 3 May 2008 22:32:17 -0400 Subject: implement linear emition and fetching and plug it in the varray paths --- src/gallium/auxiliary/draw/draw_pt.h | 18 +++++ src/gallium/auxiliary/draw/draw_pt_emit.c | 45 +++++++++++ src/gallium/auxiliary/draw/draw_pt_fetch.c | 36 +++++++++ .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 88 ++++++++++++++++++++-- src/gallium/auxiliary/draw/draw_pt_varray.c | 26 ++++++- src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 4 +- 6 files changed, 208 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 2dec376cee..2f96ceaf00 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -92,6 +92,12 @@ struct draw_pt_middle_end { const ushort *draw_elts, unsigned draw_count ); + void (*run_linear)(struct draw_pt_middle_end *, + unsigned fetch_start, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count); + void (*finish)( struct draw_pt_middle_end * ); void (*destroy)( struct draw_pt_middle_end * ); }; @@ -152,6 +158,13 @@ void draw_pt_emit( struct pt_emit *emit, const ushort *elts, unsigned count ); +void draw_pt_emit_linear( struct pt_emit *emit, + const float (*vertex_data)[4], + unsigned vertex_count, + unsigned stride, + unsigned start, + unsigned count ); + void draw_pt_emit_destroy( struct pt_emit *emit ); struct pt_emit *draw_pt_emit_create( struct draw_context *draw ); @@ -170,6 +183,11 @@ void draw_pt_fetch_run( struct pt_fetch *fetch, unsigned count, char *verts ); +void draw_pt_fetch_run_linear( struct pt_fetch *fetch, + unsigned start, + unsigned count, + char *verts ); + void draw_pt_fetch_destroy( struct pt_fetch *fetch ); struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ); diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index f9ac16786e..2a961b7088 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -179,6 +179,51 @@ void draw_pt_emit( struct pt_emit *emit, } +void draw_pt_emit_linear(struct pt_emit *emit, + const float (*vertex_data)[4], + unsigned vertex_count, + unsigned stride, + unsigned start, + unsigned count) +{ + struct draw_context *draw = emit->draw; + struct translate *translate = emit->translate; + struct vbuf_render *render = draw->render; + void *hw_verts; + + debug_printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"); + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + + hw_verts = render->allocate_vertices(render, + (ushort)translate->key.output_stride, + (ushort)count); + if (!hw_verts) { + assert(0); + return; + } + + translate->set_buffer(translate, 0, + vertex_data, stride); + + translate->set_buffer(translate, 1, + &draw->rasterizer->point_size, + 0); + + translate->run(translate, + 0, + vertex_count, + hw_verts); + + render->draw_arrays(render, start, count); + + render->release_vertices(render, + hw_verts, + translate->key.output_stride, + vertex_count); +} + struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) { struct pt_emit *emit = CALLOC_STRUCT(pt_emit); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 1f765b73ad..d7cc1807d7 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -167,6 +167,42 @@ void draw_pt_fetch_run( struct pt_fetch *fetch, } +void draw_pt_fetch_run_linear( struct pt_fetch *fetch, + unsigned start, + unsigned count, + char *verts ) +{ + struct draw_context *draw = fetch->draw; + struct translate *translate = fetch->translate; + unsigned i; + + for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { + translate->set_buffer(translate, + i, + ((char *)draw->pt.user.vbuffer[i] + + draw->pt.vertex_buffer[i].buffer_offset), + draw->pt.vertex_buffer[i].pitch ); + } + + translate->run( translate, + start, + count, + verts ); + + /* Edgeflags are hard to fit into a translate program, populate + * them separately if required. In the setup above they are + * defaulted to one, so only need this if there is reason to change + * that default: + */ + if (fetch->need_edgeflags) { + for (i = 0; i < count; i++) { + struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size); + vh->edgeflag = draw_pt_get_edgeflag( draw, start + i ); + } + } +} + + struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) { struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 4ec20493c4..b1e08a8f40 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -162,7 +162,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, fpme->vertex_size, draw_elts, draw_count ); - } + } else { draw_pt_emit( fpme->emit, (const float (*)[4])pipeline_verts->data, @@ -177,6 +177,83 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, } +static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, + unsigned fetch_start, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + struct draw_context *draw = fpme->draw; + struct draw_vertex_shader *shader = draw->vertex_shader; + unsigned opt = fpme->opt; + unsigned alloc_count = align_int( fetch_count, 4 ); + + struct vertex_header *pipeline_verts = + (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); + + if (!pipeline_verts) { + /* Not much we can do here - just skip the rendering. + */ + assert(0); + return; + } + + /* Fetch into our vertex buffer + */ + draw_pt_fetch_run_linear( fpme->fetch, + fetch_start, + fetch_count, + (char *)pipeline_verts ); + + /* Run the shader, note that this overwrites the data[] parts of + * the pipeline verts. If there is no shader, ie a bypass shader, + * then the inputs == outputs, and are already in the correct + * place. + */ + if (opt & PT_SHADE) + { + shader->run_linear(shader, + (const float (*)[4])pipeline_verts->data, + ( float (*)[4])pipeline_verts->data, + (const float (*)[4])draw->pt.user.constants, + fetch_count, + fpme->vertex_size, + fpme->vertex_size); + } + + if (draw_pt_post_vs_run( fpme->post_vs, + pipeline_verts, + fetch_count, + fpme->vertex_size )) + { + opt |= PT_PIPELINE; + } + + /* Do we need to run the pipeline? + */ + if (opt & PT_PIPELINE) { + draw_pipeline_run( fpme->draw, + fpme->prim, + pipeline_verts, + fetch_count, + fpme->vertex_size, + draw_elts, + draw_count ); + } + else { + draw_pt_emit_linear( fpme->emit, + (const float (*)[4])pipeline_verts->data, + fetch_count, + fpme->vertex_size, + 0, /*start*/ + draw_count ); + } + + FREE(pipeline_verts); +} + + static void fetch_pipeline_finish( struct draw_pt_middle_end *middle ) { @@ -206,10 +283,11 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context * if (!fpme) goto fail; - fpme->base.prepare = fetch_pipeline_prepare; - fpme->base.run = fetch_pipeline_run; - fpme->base.finish = fetch_pipeline_finish; - fpme->base.destroy = fetch_pipeline_destroy; + fpme->base.prepare = fetch_pipeline_prepare; + fpme->base.run = fetch_pipeline_run; + fpme->base.run_linear = fetch_pipeline_linear_run; + fpme->base.finish = fetch_pipeline_finish; + fpme->base.destroy = fetch_pipeline_destroy; fpme->draw = draw; diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index c9843bded0..916373acc8 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -75,6 +75,28 @@ static void varray_flush(struct varray_frontend *varray) varray->draw_count = 0; } +static void varray_flush_linear(struct varray_frontend *varray) +{ + if (varray->draw_count) { + debug_printf("FLUSH LINEAR fc = %d, dc = %d\n", + varray->fetch_count, + varray->draw_count); + debug_printf("\telt0 = %d, eltx = %d, draw0 = %d, drawx = %d\n", + varray->fetch_elts[0], + varray->fetch_elts[varray->fetch_count-1], + varray->draw_elts[0], + varray->draw_elts[varray->draw_count-1]); + varray->middle->run_linear(varray->middle, + varray->fetch_elts[0], + varray->fetch_count, + varray->draw_elts, + varray->draw_count); + } + + varray->fetch_count = 0; + varray->draw_count = 0; +} + static INLINE void fetch_init(struct varray_frontend *varray, unsigned count) { @@ -265,8 +287,8 @@ static void varray_prepare(struct draw_pt_front_end *frontend, if (opt & PT_PIPELINE) { varray->base.run = varray_run_extras; - } - else + } + else { varray->base.run = varray_run; } diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h index 073c1aadbf..67baafa3be 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -17,7 +17,7 @@ static void FUNC(struct draw_pt_front_end *frontend, split_prim_inplace(varray->input_prim, &first, &incr); -#if 1 +#if 0 debug_printf("%s (%d) %d/%d\n", __FUNCTION__, varray->input_prim, start, count); @@ -88,7 +88,7 @@ static void FUNC(struct draw_pt_front_end *frontend, i + 0, i + 1, i + 2); } fetch_init(varray, end); - varray_flush(varray); + varray_flush_linear(varray); } break; -- cgit v1.2.3 From ff1fee2cae9fabb47d6a2eb1f9f8094fec3c377f Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sun, 4 May 2008 00:44:27 -0400 Subject: don't fill in linear fetch_elts --- src/gallium/auxiliary/draw/draw_pt_varray.c | 4 +++- src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index 916373acc8..fb1b59d53e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -78,6 +78,7 @@ static void varray_flush(struct varray_frontend *varray) static void varray_flush_linear(struct varray_frontend *varray) { if (varray->draw_count) { +#if 0 debug_printf("FLUSH LINEAR fc = %d, dc = %d\n", varray->fetch_count, varray->draw_count); @@ -86,8 +87,9 @@ static void varray_flush_linear(struct varray_frontend *varray) varray->fetch_elts[varray->fetch_count-1], varray->draw_elts[0], varray->draw_elts[varray->draw_count-1]); +#endif varray->middle->run_linear(varray->middle, - varray->fetch_elts[0], + varray->fetch_start, varray->fetch_count, varray->draw_elts, varray->draw_count); diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h index 67baafa3be..a9f844a357 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -87,8 +87,9 @@ static void FUNC(struct draw_pt_front_end *frontend, TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, i + 0, i + 1, i + 2); } - fetch_init(varray, end); + varray->fetch_count = end; varray_flush_linear(varray); + varray->fetch_start += end; } break; -- cgit v1.2.3 From a24cb269e1ba5434acf8c94abd03517c149b9c51 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sun, 4 May 2008 01:23:01 -0400 Subject: implement linear path for fetch_emit pipeline --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 64 +++++++++++++++++++++++-- src/gallium/auxiliary/draw/draw_pt_varray.c | 1 + 2 files changed, 61 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index a4de341df8..6d5a54cf0e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -257,6 +257,61 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, } +static void fetch_emit_run_linear( struct draw_pt_middle_end *middle, + unsigned fetch_start, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; + struct draw_context *draw = feme->draw; + void *hw_verts; + + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + + hw_verts = draw->render->allocate_vertices( draw->render, + (ushort)feme->translate->key.output_stride, + (ushort)fetch_count ); + if (!hw_verts) { + assert(0); + return; + } + + /* Single routine to fetch vertices and emit HW verts. + */ + feme->translate->run( feme->translate, + fetch_start, + fetch_count, + hw_verts ); + + if (0) { + unsigned i; + for (i = 0; i < fetch_count; i++) { + debug_printf("\n\nvertex %d:\n", i); + draw_dump_emitted_vertex( feme->vinfo, + (const uint8_t *)hw_verts + feme->vinfo->size * 4 * i ); + } + } + + /* XXX: Draw arrays path to avoid re-emitting index list again and + * again. + */ + draw->render->draw_arrays( draw->render, + 0, /*start*/ + draw_count ); + + /* Done -- that was easy, wasn't it: + */ + draw->render->release_vertices( draw->render, + hw_verts, + feme->translate->key.output_stride, + fetch_count ); + +} + + static void fetch_emit_finish( struct draw_pt_middle_end *middle ) { @@ -285,10 +340,11 @@ struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ) return NULL; } - fetch_emit->base.prepare = fetch_emit_prepare; - fetch_emit->base.run = fetch_emit_run; - fetch_emit->base.finish = fetch_emit_finish; - fetch_emit->base.destroy = fetch_emit_destroy; + fetch_emit->base.prepare = fetch_emit_prepare; + fetch_emit->base.run = fetch_emit_run; + fetch_emit->base.run_linear = fetch_emit_run_linear; + fetch_emit->base.finish = fetch_emit_finish; + fetch_emit->base.destroy = fetch_emit_destroy; fetch_emit->draw = draw; diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index fb1b59d53e..e7e21e4bf6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -88,6 +88,7 @@ static void varray_flush_linear(struct varray_frontend *varray) varray->draw_elts[0], varray->draw_elts[varray->draw_count-1]); #endif + assert(varray->middle->run_linear); varray->middle->run_linear(varray->middle, varray->fetch_start, varray->fetch_count, -- cgit v1.2.3 From 66d72f176de2568f053c6dc54e93d423723ae8aa Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sun, 4 May 2008 01:37:32 -0400 Subject: silence debugging output --- src/gallium/auxiliary/draw/draw_pt_emit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 2a961b7088..776ca32cfa 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -191,7 +191,9 @@ void draw_pt_emit_linear(struct pt_emit *emit, struct vbuf_render *render = draw->render; void *hw_verts; - debug_printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"); +#if 0 + debug_printf("Linear emit\n"); +#endif /* XXX: need to flush to get prim_vbuf.c to release its allocation?? */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); -- cgit v1.2.3 From e897fd6cd35c6b9e398e1903d2e79678fe85708a Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 5 May 2008 12:49:40 -0400 Subject: fix the regressions --- src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h index a9f844a357..10ac08ea30 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -28,9 +28,10 @@ static void FUNC(struct draw_pt_front_end *frontend, for (j = 0; j + first <= count; j += i) { unsigned end = MIN2(FETCH_MAX, count - j); end -= (end % incr); - for (i = 0; i < count; i ++) { + for (i = 0; i < count; i++) { POINT(varray, i + 0); } + i = end; fetch_init(varray, end); varray_flush(varray); } @@ -44,6 +45,7 @@ static void FUNC(struct draw_pt_front_end *frontend, LINE(varray, DRAW_PIPE_RESET_STIPPLE, i + 0, i + 1); } + i = end; fetch_init(varray, end); varray_flush(varray); } @@ -60,6 +62,7 @@ static void FUNC(struct draw_pt_front_end *frontend, LINE(varray, flags, i - 1, i); } LINE(varray, flags, i - 1, 0); + i = end; fetch_init(varray, end); varray_flush(varray); } @@ -74,6 +77,7 @@ static void FUNC(struct draw_pt_front_end *frontend, for (i = 1; i < end; i++, flags = 0) { LINE(varray, flags, i - 1, i); } + i = end; fetch_init(varray, end); varray_flush(varray); } @@ -87,6 +91,7 @@ static void FUNC(struct draw_pt_front_end *frontend, TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, i + 0, i + 1, i + 2); } + i = end; varray->fetch_count = end; varray_flush_linear(varray); varray->fetch_start += end; @@ -102,6 +107,7 @@ static void FUNC(struct draw_pt_front_end *frontend, TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, i + 0, i + 1 + (i&1), i + 2 - (i&1)); } + i = end; fetch_init(varray, end); varray_flush(varray); } @@ -114,6 +120,7 @@ static void FUNC(struct draw_pt_front_end *frontend, TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, i + 0 + (i&1), i + 1 - (i&1), i + 2); } + i = end; fetch_init(varray, end); varray_flush(varray); } @@ -130,6 +137,7 @@ static void FUNC(struct draw_pt_front_end *frontend, for (i = 0; i+2 < end; i++) { TRIANGLE(varray, flags, i + 1, i + 2, 0); } + i = end; fetch_init(varray, end); varray_flush(varray); } @@ -142,6 +150,7 @@ static void FUNC(struct draw_pt_front_end *frontend, for (i = 0; i+2 < end; i++) { TRIANGLE(varray, flags, 0, i + 1, i + 2); } + i = end; fetch_init(varray, end); varray_flush(varray); } @@ -156,6 +165,7 @@ static void FUNC(struct draw_pt_front_end *frontend, for (i = 0; i+3 < end; i += 4) { QUAD(varray, i + 0, i + 1, i + 2, i + 3); } + i = end; fetch_init(varray, end); varray_flush(varray); } @@ -168,6 +178,7 @@ static void FUNC(struct draw_pt_front_end *frontend, for (i = 0; i+3 < end; i += 2) { QUAD(varray, i + 2, i + 0, i + 1, i + 3); } + i = end; fetch_init(varray, end); varray_flush(varray); } @@ -193,6 +204,7 @@ static void FUNC(struct draw_pt_front_end *frontend, TRIANGLE(varray, flags, i + 1, i + 2, 0); } + i = end; fetch_init(varray, end); varray_flush(varray); } -- cgit v1.2.3 From fe586f8612dd517b9a1f0d87fbaf3a75e3caf588 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 6 May 2008 18:59:45 -0400 Subject: redo the linear paths --- src/gallium/auxiliary/draw/draw_pipe.c | 39 ++++ src/gallium/auxiliary/draw/draw_private.h | 6 + src/gallium/auxiliary/draw/draw_pt.h | 6 +- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 18 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 36 ++-- src/gallium/auxiliary/draw/draw_pt_varray.c | 27 +-- src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 5 +- .../auxiliary/draw/draw_pt_varray_tmp_linear.h | 198 +++++++++++++++++++++ 8 files changed, 279 insertions(+), 56 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 46afb0f41f..cb97f955b2 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -212,6 +212,45 @@ void draw_pipeline_run( struct draw_context *draw, draw->pipeline.vertex_count = 0; } +void draw_pipeline_run_linear( struct draw_context *draw, + unsigned prim, + struct vertex_header *vertices, + unsigned count, + unsigned stride ) +{ + char *verts = (char *)vertices; + unsigned i; + + draw->pipeline.verts = verts; + draw->pipeline.vertex_stride = stride; + draw->pipeline.vertex_count = count; + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i++) + do_point( draw, + verts + stride * i ); + break; + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) + do_line( draw, + i+0, /* flags */ + verts + stride * ((i+0) & ~DRAW_PIPE_FLAG_MASK), + verts + stride * (i+1)); + break; + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) + do_triangle( draw, + (i+0), /* flags */ + verts + stride * ((i+0) & ~DRAW_PIPE_FLAG_MASK), + verts + stride * (i+1), + verts + stride * (i+2)); + break; + } + + draw->pipeline.verts = NULL; + draw->pipeline.vertex_count = 0; +} void draw_pipeline_flush( struct draw_context *draw, diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index cee58bbf73..e036d498b8 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -247,6 +247,12 @@ void draw_pipeline_run( struct draw_context *draw, const ushort *elts, unsigned count ); +void draw_pipeline_run_linear( struct draw_context *draw, + unsigned prim, + struct vertex_header *vertices, + unsigned count, + unsigned stride ); + void draw_pipeline_flush( struct draw_context *draw, diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 2f96ceaf00..312fdbe4f4 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -93,10 +93,8 @@ struct draw_pt_middle_end { unsigned draw_count ); void (*run_linear)(struct draw_pt_middle_end *, - unsigned fetch_start, - unsigned fetch_count, - const ushort *draw_elts, - unsigned draw_count); + unsigned start, + unsigned count); void (*finish)( struct draw_pt_middle_end * ); void (*destroy)( struct draw_pt_middle_end * ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 6d5a54cf0e..8df4241b82 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -258,10 +258,8 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, static void fetch_emit_run_linear( struct draw_pt_middle_end *middle, - unsigned fetch_start, - unsigned fetch_count, - const ushort *draw_elts, - unsigned draw_count ) + unsigned start, + unsigned count ) { struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; @@ -273,7 +271,7 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle, hw_verts = draw->render->allocate_vertices( draw->render, (ushort)feme->translate->key.output_stride, - (ushort)fetch_count ); + (ushort)count ); if (!hw_verts) { assert(0); return; @@ -282,13 +280,13 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle, /* Single routine to fetch vertices and emit HW verts. */ feme->translate->run( feme->translate, - fetch_start, - fetch_count, + start, + count, hw_verts ); if (0) { unsigned i; - for (i = 0; i < fetch_count; i++) { + for (i = 0; i < count; i++) { debug_printf("\n\nvertex %d:\n", i); draw_dump_emitted_vertex( feme->vinfo, (const uint8_t *)hw_verts + feme->vinfo->size * 4 * i ); @@ -300,14 +298,14 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle, */ draw->render->draw_arrays( draw->render, 0, /*start*/ - draw_count ); + count ); /* Done -- that was easy, wasn't it: */ draw->render->release_vertices( draw->render, hw_verts, feme->translate->key.output_stride, - fetch_count ); + count ); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index b1e08a8f40..dad54690a5 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -178,18 +178,16 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, - unsigned fetch_start, - unsigned fetch_count, - const ushort *draw_elts, - unsigned draw_count ) + unsigned start, + unsigned count) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; struct draw_vertex_shader *shader = draw->vertex_shader; unsigned opt = fpme->opt; - unsigned alloc_count = align_int( fetch_count, 4 ); + unsigned alloc_count = align_int( count, 4 ); - struct vertex_header *pipeline_verts = + struct vertex_header *pipeline_verts = (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); if (!pipeline_verts) { @@ -202,8 +200,8 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, /* Fetch into our vertex buffer */ draw_pt_fetch_run_linear( fpme->fetch, - fetch_start, - fetch_count, + start, + count, (char *)pipeline_verts ); /* Run the shader, note that this overwrites the data[] parts of @@ -213,18 +211,18 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, */ if (opt & PT_SHADE) { - shader->run_linear(shader, + shader->run_linear(shader, (const float (*)[4])pipeline_verts->data, ( float (*)[4])pipeline_verts->data, (const float (*)[4])draw->pt.user.constants, - fetch_count, + count, fpme->vertex_size, fpme->vertex_size); } if (draw_pt_post_vs_run( fpme->post_vs, pipeline_verts, - fetch_count, + count, fpme->vertex_size )) { opt |= PT_PIPELINE; @@ -233,21 +231,19 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, /* Do we need to run the pipeline? */ if (opt & PT_PIPELINE) { - draw_pipeline_run( fpme->draw, - fpme->prim, - pipeline_verts, - fetch_count, - fpme->vertex_size, - draw_elts, - draw_count ); + draw_pipeline_run_linear( fpme->draw, + fpme->prim, + pipeline_verts, + count, + fpme->vertex_size); } else { draw_pt_emit_linear( fpme->emit, (const float (*)[4])pipeline_verts->data, - fetch_count, + count, fpme->vertex_size, 0, /*start*/ - draw_count ); + count ); } FREE(pipeline_verts); diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index e7e21e4bf6..59a9569270 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -75,29 +75,18 @@ static void varray_flush(struct varray_frontend *varray) varray->draw_count = 0; } -static void varray_flush_linear(struct varray_frontend *varray) +static void varray_flush_linear(struct varray_frontend *varray, + unsigned start, unsigned count) { - if (varray->draw_count) { + if (count) { #if 0 - debug_printf("FLUSH LINEAR fc = %d, dc = %d\n", - varray->fetch_count, - varray->draw_count); - debug_printf("\telt0 = %d, eltx = %d, draw0 = %d, drawx = %d\n", - varray->fetch_elts[0], - varray->fetch_elts[varray->fetch_count-1], - varray->draw_elts[0], - varray->draw_elts[varray->draw_count-1]); + debug_printf("FLUSH LINEAR start = %d, count = %d\n", + start, + count); #endif assert(varray->middle->run_linear); - varray->middle->run_linear(varray->middle, - varray->fetch_start, - varray->fetch_count, - varray->draw_elts, - varray->draw_count); + varray->middle->run_linear(varray->middle, start, count); } - - varray->fetch_count = 0; - varray->draw_count = 0; } static INLINE void fetch_init(struct varray_frontend *varray, @@ -261,7 +250,7 @@ static INLINE void varray_ef_quad( struct varray_frontend *varray, #define LINE(vc,flags,i0,i1) varray_line(vc,i0,i1) #define POINT(vc,i0) varray_point(vc,i0) #define FUNC varray_run -#include "draw_pt_varray_tmp.h" +#include "draw_pt_varray_tmp_linear.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h index 10ac08ea30..335c4c89ca 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -92,9 +92,8 @@ static void FUNC(struct draw_pt_front_end *frontend, i + 0, i + 1, i + 2); } i = end; - varray->fetch_count = end; - varray_flush_linear(varray); - varray->fetch_start += end; + fetch_init(varray, end); + varray_flush(varray); } break; diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h new file mode 100644 index 0000000000..dfa4338407 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h @@ -0,0 +1,198 @@ + +static void FUNC(struct draw_pt_front_end *frontend, + pt_elt_func get_elt, + const void *elts, + unsigned count) +{ + struct varray_frontend *varray = (struct varray_frontend *)frontend; + struct draw_context *draw = varray->draw; + unsigned start = (unsigned)elts; + + boolean flatfirst = (draw->rasterizer->flatshade && + draw->rasterizer->flatshade_first); + unsigned i, j, flags; + unsigned first, incr; + + varray->fetch_start = start; + + split_prim_inplace(varray->input_prim, &first, &incr); + +#if 0 + debug_printf("%s (%d) %d/%d\n", __FUNCTION__, + varray->input_prim, + start, count); +#endif + + switch (varray->input_prim) { + case PIPE_PRIM_POINTS: + case PIPE_PRIM_LINES: + case PIPE_PRIM_TRIANGLES: + j = 0; + while (j + first <= count) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + varray_flush_linear(varray, start + j, end); + j += end; + } + break; + + case PIPE_PRIM_LINE_LOOP: + if (count >= 2) { + flags = DRAW_PIPE_RESET_STIPPLE; + + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 1; i < end; i++, flags = 0) { + LINE(varray, flags, i - 1, i); + } + LINE(varray, flags, i - 1, 0); + i = end; + fetch_init(varray, end); + varray_flush(varray); + } + } + break; + + case PIPE_PRIM_LINE_STRIP: + flags = DRAW_PIPE_RESET_STIPPLE; + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 1; i < end; i++, flags = 0) { + LINE(varray, flags, i - 1, i); + } + i = end; + fetch_init(varray, end); + varray_flush(varray); + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + if (flatfirst) { + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+2 < end; i++) { + TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + i + 0, i + 1 + (i&1), i + 2 - (i&1)); + } + i = end; + fetch_init(varray, end); + varray_flush(varray); + } + } + else { + for (j = 0; j + first <= count;) { + unsigned end = MIN2(FETCH_MAX, count - j); + //end -= (end % incr); + for (i = 0; i+2 < end; i++) { + TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + i + 0 + (i&1), i + 1 - (i&1), i + 2); + } + fetch_init(varray, end); + varray_flush(varray); + j += end; + if (j <= count) + j -= incr; + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (count >= 3) { + if (flatfirst) { + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+2 < end; i++) { + TRIANGLE(varray, flags, i + 1, i + 2, 0); + } + i = end; + fetch_init(varray, end); + varray_flush(varray); + } + } + else { + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+2 < end; i++) { + TRIANGLE(varray, flags, 0, i + 1, i + 2); + } + i = end; + fetch_init(varray, end); + varray_flush(varray); + } + } + } + break; + + case PIPE_PRIM_QUADS: + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+3 < end; i += 4) { + QUAD(varray, i + 0, i + 1, i + 2, i + 3); + } + i = end; + fetch_init(varray, end); + varray_flush(varray); + } + break; + + case PIPE_PRIM_QUAD_STRIP: + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+3 < end; i += 2) { + QUAD(varray, i + 2, i + 0, i + 1, i + 3); + } + i = end; + fetch_init(varray, end); + varray_flush(varray); + } + break; + + case PIPE_PRIM_POLYGON: + { + /* These bitflags look a little odd because we submit the + * vertices as (1,2,0) to satisfy flatshade requirements. + */ + const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2; + const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0; + const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1; + + flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; + for (j = 0; j + first <= count; j += i) { + unsigned end = MIN2(FETCH_MAX, count - j); + end -= (end % incr); + for (i = 0; i+2 < end; i++, flags = edge_middle) { + + if (i + 3 == count) + flags |= edge_last; + + TRIANGLE(varray, flags, i + 1, i + 2, 0); + } + i = end; + fetch_init(varray, end); + varray_flush(varray); + } + } + break; + + default: + assert(0); + break; + } + + varray_flush(varray); +} + +#undef TRIANGLE +#undef QUAD +#undef POINT +#undef LINE +#undef FUNC -- cgit v1.2.3 From 22323af525d00022a1fa06fab7ee84df5ef2d1f0 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 7 May 2008 19:34:12 -0400 Subject: fix silly mistakes --- src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 2 +- src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h index 335c4c89ca..fb49452d8b 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -28,7 +28,7 @@ static void FUNC(struct draw_pt_front_end *frontend, for (j = 0; j + first <= count; j += i) { unsigned end = MIN2(FETCH_MAX, count - j); end -= (end % incr); - for (i = 0; i < count; i++) { + for (i = 0; i < end; i++) { POINT(varray, i + 0); } i = end; diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h index dfa4338407..ab28859c35 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h @@ -85,7 +85,7 @@ static void FUNC(struct draw_pt_front_end *frontend, else { for (j = 0; j + first <= count;) { unsigned end = MIN2(FETCH_MAX, count - j); - //end -= (end % incr); + end -= (end % incr); for (i = 0; i+2 < end; i++) { TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, i + 0 + (i&1), i + 1 - (i&1), i + 2); @@ -93,8 +93,6 @@ static void FUNC(struct draw_pt_front_end *frontend, fetch_init(varray, end); varray_flush(varray); j += end; - if (j <= count) - j -= incr; } } break; -- cgit v1.2.3 From 8d709ae1595047b45a81f2fbd22850887fdbfea0 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 8 May 2008 12:10:24 -0400 Subject: fix triangle strips --- src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 12 ++++++++++-- src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h index fb49452d8b..d137a758e2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -109,19 +109,27 @@ static void FUNC(struct draw_pt_front_end *frontend, i = end; fetch_init(varray, end); varray_flush(varray); + if (j + first + i <= count) { + varray->fetch_start -= 2; + i -= 2; + } } } else { for (j = 0; j + first <= count; j += i) { unsigned end = MIN2(FETCH_MAX, count - j); - end -= (end % incr); - for (i = 0; i+2 < end; i++) { + end -= (end % incr); + for (i = 0; i + 2 < end; i++) { TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, i + 0 + (i&1), i + 1 - (i&1), i + 2); } i = end; fetch_init(varray, end); varray_flush(varray); + if (j + first + i <= count) { + varray->fetch_start -= 2; + i -= 2; + } } } break; diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h index ab28859c35..4bf04fa62b 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h @@ -80,19 +80,27 @@ static void FUNC(struct draw_pt_front_end *frontend, i = end; fetch_init(varray, end); varray_flush(varray); + if (j + first + i <= count) { + varray->fetch_start -= 2; + i -= 2; + } } } else { - for (j = 0; j + first <= count;) { + for (j = 0; j + first <= count; j += i) { unsigned end = MIN2(FETCH_MAX, count - j); end -= (end % incr); for (i = 0; i+2 < end; i++) { TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, i + 0 + (i&1), i + 1 - (i&1), i + 2); } + i = end; fetch_init(varray, end); varray_flush(varray); - j += end; + if (j + first + i <= count) { + varray->fetch_start -= 2; + i -= 2; + } } } break; -- cgit v1.2.3 From 8ea6106f01f38853e9c0f1029da55eb449109aea Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 8 May 2008 15:11:16 -0400 Subject: fix quad strips --- src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 4 ++++ src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h index d137a758e2..1395275897 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -188,6 +188,10 @@ static void FUNC(struct draw_pt_front_end *frontend, i = end; fetch_init(varray, end); varray_flush(varray); + if (j + first + i <= count) { + varray->fetch_start -= 2; + i -= 2; + } } break; diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h index 4bf04fa62b..6e2b16d9be 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h @@ -159,6 +159,10 @@ static void FUNC(struct draw_pt_front_end *frontend, i = end; fetch_init(varray, end); varray_flush(varray); + if (j + first + i <= count) { + varray->fetch_start -= 2; + i -= 2; + } } break; -- cgit v1.2.3 From 9002cdb48e65c063ea00e1cb4917d432b22ae0ad Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 8 May 2008 22:07:52 +0100 Subject: softpipe: don't calc det if NO_RAST set --- src/gallium/drivers/softpipe/sp_setup.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index df7be01fcd..5370d85275 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -717,7 +717,7 @@ void setup_tri( struct setup_context *setup, const float (*v1)[4], const float (*v2)[4] ) { - float det = calc_det(v0, v1, v2); + float det; #if DEBUG_VERTS debug_printf("Setup triangle:\n"); @@ -728,7 +728,8 @@ void setup_tri( struct setup_context *setup, if (setup->softpipe->no_rast) return; - + + det = calc_det(v0, v1, v2); /* debug_printf("%s\n", __FUNCTION__ ); */ -- cgit v1.2.3 From fec1d215f623221cb52f22c8f10e5de99ebc9cc2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 8 May 2008 22:10:15 +0100 Subject: xlib: more SP_NO_RAST support For some resaon normal (non-display-buffer) buffers are being allocated through Xshm... Bypass at least for SP_NO_RAST --- src/gallium/winsys/xlib/fakeglx.c | 9 +++++++++ src/gallium/winsys/xlib/xm_api.c | 3 +++ 2 files changed, 12 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c index ec77e81fed..2c0075e934 100644 --- a/src/gallium/winsys/xlib/fakeglx.c +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -1689,6 +1689,15 @@ static void Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) { XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); + static boolean firsttime = 1, no_rast = 0; + + if (firsttime) { + no_rast = getenv("SP_NO_RAST") != NULL; + firsttime = 0; + } + + if (no_rast) + return; if (buffer) { XMesaSwapBuffers(buffer); diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 0c248344b1..26b722f343 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -110,6 +110,9 @@ int xmesa_check_for_xshm( XMesaDisplay *display ) int major, minor, ignore; Bool pixmaps; + if (getenv("SP_NO_RAST")) + return 0; + if (getenv("MESA_NOSHM")) { return 0; } -- cgit v1.2.3 From b514f5f3ba4c9cf6c39cbcdf5bf0d2d8efb8d19b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 8 May 2008 22:13:21 +0100 Subject: draw: only fill in / compare the part of the translate key we're using. It's quite a big struct & we examine it a lot (too much). Reduce the impact of this by just looking at the active part where possible. --- src/gallium/auxiliary/draw/draw_pt_emit.c | 8 ++++---- src/gallium/auxiliary/draw/draw_pt_fetch.c | 8 +++++--- src/gallium/auxiliary/translate/translate.h | 5 ++--- 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index f9ac16786e..671abc25ce 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -49,6 +49,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, const struct vertex_info *vinfo; unsigned dst_offset; struct translate_key hw_key; + unsigned keysize; unsigned i; boolean ok; @@ -58,12 +59,10 @@ void draw_pt_emit_prepare( struct pt_emit *emit, return; } - memset(&hw_key, 0, sizeof(hw_key)); - /* Must do this after set_primitive() above: */ vinfo = draw->render->get_vertex_info(draw->render); - + keysize = 2*4 + vinfo->num_attribs * sizeof(hw_key.element[0]); /* Translate from pipeline vertices to hw vertices. */ @@ -122,8 +121,9 @@ void draw_pt_emit_prepare( struct pt_emit *emit, hw_key.output_stride = vinfo->size * 4; if (!emit->translate || - memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0) + memcmp(&emit->translate->key, &hw_key, keysize) != 0) { + memset((char *)&hw_key + keysize, 0, sizeof(hw_key) - keysize); emit->translate = translate_cache_find(emit->cache, &hw_key); } } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 1f765b73ad..a5bebb4ca1 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -62,10 +62,11 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, unsigned i, nr = 0; unsigned dst_offset = 0; struct translate_key key; + unsigned keysize; fetch->vertex_size = vertex_size; - - memset(&key, 0, sizeof(key)); + keysize = (2*4 + + (draw->pt.nr_vertex_elements + 1) * sizeof(key.element[0])); /* Always emit/leave space for a vertex header. * @@ -110,8 +111,9 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, if (!fetch->translate || - memcmp(&fetch->translate->key, &key, sizeof(key)) != 0) + memcmp(&fetch->translate->key, &key, keysize) != 0) { + memset((char *)&key + keysize, 0, sizeof(key) - keysize); fetch->translate = translate_cache_find(fetch->cache, &key); { diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index 6c15d7e4dc..de6f09d18a 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -47,10 +47,9 @@ struct translate_element { enum pipe_format input_format; - unsigned input_buffer; - unsigned input_offset; - enum pipe_format output_format; + unsigned input_buffer; + unsigned input_offset; /* can't really reduce the size of these */ unsigned output_offset; }; -- cgit v1.2.3 From 044d583ba12689cbe99098eb999854303de57f59 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 8 May 2008 18:38:02 -0600 Subject: gallium: handle null ptrs --- src/gallium/auxiliary/util/u_draw_quad.c | 81 ++++++++++++++++---------------- 1 file changed, 40 insertions(+), 41 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c index e659edb088..bf143815d8 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.c +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -82,52 +82,51 @@ util_draw_texquad(struct pipe_context *pipe, { struct pipe_buffer *vbuf; uint numAttribs = 2, vertexBytes, i, j; - float *v; vertexBytes = 4 * (4 * numAttribs * sizeof(float)); /* XXX create one-time */ vbuf = pipe->winsys->buffer_create(pipe->winsys, 32, PIPE_BUFFER_USAGE_VERTEX, vertexBytes); - assert(vbuf); - - v = (float *) pipe->winsys->buffer_map(pipe->winsys, vbuf, - PIPE_BUFFER_USAGE_CPU_WRITE); - - /* - * Load vertex buffer - */ - for (i = j = 0; i < 4; i++) { - v[j + 2] = z; /* z */ - v[j + 3] = 1.0; /* w */ - v[j + 6] = 0.0; /* r */ - v[j + 7] = 1.0; /* q */ - j += 8; + if (vbuf) { + float *v = (float *) pipe->winsys->buffer_map(pipe->winsys, vbuf, + PIPE_BUFFER_USAGE_CPU_WRITE); + if (v) { + /* + * Load vertex buffer + */ + for (i = j = 0; i < 4; i++) { + v[j + 2] = z; /* z */ + v[j + 3] = 1.0; /* w */ + v[j + 6] = 0.0; /* r */ + v[j + 7] = 1.0; /* q */ + j += 8; + } + + v[0] = x0; + v[1] = y0; + v[4] = 0.0; /*s*/ + v[5] = 0.0; /*t*/ + + v[8] = x1; + v[9] = y0; + v[12] = 1.0; + v[13] = 0.0; + + v[16] = x1; + v[17] = y1; + v[20] = 1.0; + v[21] = 1.0; + + v[24] = x0; + v[25] = y1; + v[28] = 0.0; + v[29] = 1.0; + + pipe->winsys->buffer_unmap(pipe->winsys, vbuf); + util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2); + } + + pipe_buffer_reference(pipe->winsys, &vbuf, NULL); } - - v[0] = x0; - v[1] = y0; - v[4] = 0.0; /*s*/ - v[5] = 0.0; /*t*/ - - v[8] = x1; - v[9] = y0; - v[12] = 1.0; - v[13] = 0.0; - - v[16] = x1; - v[17] = y1; - v[20] = 1.0; - v[21] = 1.0; - - v[24] = x0; - v[25] = y1; - v[28] = 0.0; - v[29] = 1.0; - - pipe->winsys->buffer_unmap(pipe->winsys, vbuf); - - util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2); - - pipe_buffer_reference(pipe->winsys, &vbuf, NULL); } -- cgit v1.2.3 From 2268306f58769dff4b2b1da8bb668bdff2856d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 9 May 2008 11:02:10 +0900 Subject: gallium: Don't serialize GPU writes. Only make sure the GPU is finished with a buffer before mapping. The opposite -- waiting for the CPU to be finished before handing to the CPU -- must be done before fencing. --- .../auxiliary/pipebuffer/pb_buffer_fenced.c | 100 ++++++++++----------- 1 file changed, 50 insertions(+), 50 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 2fa0842971..7f236887a9 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -168,6 +168,28 @@ _fenced_buffer_remove(struct fenced_buffer *fenced_buf) } +static INLINE enum pipe_error +_fenced_buffer_finish(struct fenced_buffer *fenced_buf) +{ + struct fenced_buffer_list *fenced_list = fenced_buf->list; + struct pipe_winsys *winsys = fenced_list->winsys; + + debug_warning("waiting for GPU"); + + assert(fenced_buf->fence); + if(fenced_buf->fence) { + if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) { + return PIPE_ERROR; + } + /* Remove from the fenced list */ + _fenced_buffer_remove(fenced_buf); /* TODO: remove consequents */ + } + + fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE; + return PIPE_OK; +} + + /** * Free as many fenced buffers from the list head as possible. */ @@ -207,40 +229,6 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, } -/** - * Serialize writes, but allow concurrent reads. - */ -static INLINE enum pipe_error -fenced_buffer_serialize(struct fenced_buffer *fenced_buf, unsigned flags) -{ - struct fenced_buffer_list *fenced_list = fenced_buf->list; - struct pipe_winsys *winsys = fenced_list->winsys; - - /* Allow concurrent reads */ - if(((fenced_buf->flags | flags) & PIPE_BUFFER_USAGE_WRITE) == 0) - return PIPE_OK; - - /* Wait for the CPU to finish */ - if(fenced_buf->mapcount) { - /* FIXME: Use thread conditions variables to signal when mapcount - * reaches zero */ - debug_warning("attemp to write concurrently to buffer"); - /* XXX: we must not fail here in order to support texture mipmap generation - return PIPE_ERROR_RETRY; - */ - } - - /* Wait for the GPU to finish */ - if(fenced_buf->fence) { - if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) - return PIPE_ERROR_RETRY; - _fenced_buffer_remove(fenced_buf); - } - - return PIPE_OK; -} - - static void fenced_buffer_destroy(struct pb_buffer *buf) { @@ -280,15 +268,28 @@ fenced_buffer_map(struct pb_buffer *buf, { struct fenced_buffer *fenced_buf = fenced_buffer(buf); void *map; - assert((flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE) == 0); + + assert(!(flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE)); + flags &= PIPE_BUFFER_USAGE_CPU_READ_WRITE; - if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK) - return NULL; + /* Check for GPU read/write access */ + if(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) { + /* Wait for the GPU to finish writing */ + _fenced_buffer_finish(fenced_buf); + } + + /* Check for CPU write access (read is OK) */ + if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) { + /* this is legal -- just for debugging */ + debug_warning("concurrent CPU writes"); + } map = pb_map(fenced_buf->buffer, flags); - if(map) + if(map) { ++fenced_buf->mapcount; - fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE; + fenced_buf->flags |= flags; + } + return map; } @@ -298,10 +299,12 @@ fenced_buffer_unmap(struct pb_buffer *buf) { struct fenced_buffer *fenced_buf = fenced_buffer(buf); assert(fenced_buf->mapcount); - pb_unmap(fenced_buf->buffer); - --fenced_buf->mapcount; - if(!fenced_buf->mapcount) - fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE; + if(fenced_buf->mapcount) { + pb_unmap(fenced_buf->buffer); + --fenced_buf->mapcount; + if(!fenced_buf->mapcount) + fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE; + } } @@ -334,8 +337,10 @@ fenced_buffer_create(struct fenced_buffer_list *fenced_list, return NULL; buf = CALLOC_STRUCT(fenced_buffer); - if(!buf) + if(!buf) { + pb_reference(&buffer, NULL); return NULL; + } buf->base.base.refcount = 1; buf->base.base.alignment = buffer->base.alignment; @@ -374,7 +379,7 @@ buffer_fence(struct pb_buffer *buf, fenced_list = fenced_buf->list; winsys = fenced_list->winsys; - if(fence == fenced_buf->fence) { + if(!fence || fence == fenced_buf->fence) { /* Handle the same fence case specially, not only because it is a fast * path, but mostly to avoid serializing two writes with the same fence, * as that would bring the hardware down to synchronous operation without @@ -384,11 +389,6 @@ buffer_fence(struct pb_buffer *buf, return; } - if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK) { - /* FIXME: propagate error */ - (void)0; - } - _glthread_LOCK_MUTEX(fenced_list->mutex); if (fenced_buf->fence) _fenced_buffer_remove(fenced_buf); -- cgit v1.2.3 From 47f639a62989cea4b3b14cd73bb39de85acec8ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 9 May 2008 14:34:51 +0900 Subject: gallium: Disable debug_get_option for release builds on Windows. It always creates the C:\gallium.cfg , even if it does not exists, which might be confusing. --- src/gallium/auxiliary/util/p_debug.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 951dd5a2d4..ce7fb58956 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -154,6 +154,7 @@ debug_get_option(const char *name, const char *dfault) { const char *result; #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY +#ifdef DEBUG ULONG_PTR iFile = 0; const void *pMap = NULL; const char *sol, *eol, *sep; @@ -183,6 +184,9 @@ debug_get_option(const char *name, const char *dfault) } EngUnmapFile(iFile); } +#else + result = dfault; +#endif #else result = getenv(name); -- cgit v1.2.3 From 54777e124c38812e5e80319048b6c71009bcf9dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 9 May 2008 18:47:44 +0900 Subject: gallium: Define util_vsprintf. --- src/gallium/auxiliary/util/u_string.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h index d7d925ee9b..73c88d87b4 100644 --- a/src/gallium/auxiliary/util/u_string.h +++ b/src/gallium/auxiliary/util/u_string.h @@ -54,6 +54,12 @@ extern "C" { int util_vsnprintf(char *, size_t, const char *, va_list); int util_snprintf(char *str, size_t size, const char *format, ...); +static INLINE void +util_vsprintf(char *str, const char *format, va_list ap) +{ + util_vsnprintf(str, (size_t)-1, format, ap); +} + static INLINE void util_sprintf(char *str, const char *format, ...) { @@ -158,6 +164,7 @@ util_memmove(void *dest, const void *src, size_t n) #define util_vsnprintf vsnprintf #define util_snprintf snprintf +#define util_vsprintf vsprintf #define util_sprintf sprintf #define util_strchr strchr #define util_strcmp strcmp -- cgit v1.2.3 From 80474d576c2e92441f6bcc18faae71a38b91bd70 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 May 2008 13:09:58 +0100 Subject: translate: helper functions for mimizing cost of key compares --- src/gallium/auxiliary/translate/translate.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index de6f09d18a..b8210af50c 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -95,6 +95,27 @@ struct translate *translate_lookup_or_create( struct translate_context *tctx, struct translate *translate_create( const struct translate_key *key ); +static INLINE int translate_keysize( const struct translate_key *key ) +{ + return 2 * sizeof(int) + key->nr_elements * sizeof(struct translate_element); +} + +static INLINE int translate_key_compare( const struct translate_key *a, + const struct translate_key *b ) +{ + int keysize = translate_keysize(a); + return memcmp(a, b, keysize); +} + + +static INLINE void translate_key_sanitize( struct translate_key *a ) +{ + int keysize = translate_keysize(a); + char *ptr = (char *)a; + memset(ptr + keysize, 0, sizeof(*a) - keysize); +} + + /******************************************************************************* * Private: */ -- cgit v1.2.3 From 1a03812fb57e956b438cd42ac68978facb49a99d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 May 2008 13:10:15 +0100 Subject: draw: mimize cost of translate key compares, use cache universally --- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 20 ++++++++++++++------ src/gallium/auxiliary/draw/draw_pt_emit.c | 10 +++++----- src/gallium/auxiliary/draw/draw_pt_fetch.c | 7 ++----- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 3 ++- 4 files changed, 23 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 2a19e6916a..86a7d1c730 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -42,6 +42,7 @@ #include "draw_vertex.h" #include "draw_pipe.h" #include "translate/translate.h" +#include "translate/translate_cache.h" /** @@ -75,6 +76,8 @@ struct vbuf_stage { /* Cache point size somewhere it's address won't change: */ float point_size; + + struct translate_cache *cache; }; @@ -220,7 +223,6 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) /* Translate from pipeline vertices to hw vertices. */ dst_offset = 0; - memset(&hw_key, 0, sizeof(hw_key)); for (i = 0; i < vbuf->vinfo->num_attribs; i++) { unsigned emit_sz = 0; @@ -277,12 +279,10 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) /* Don't bother with caching at this stage: */ if (!vbuf->translate || - memcmp(&vbuf->translate->key, &hw_key, sizeof(hw_key)) != 0) + translate_key_compare(&vbuf->translate->key, &hw_key) != 0) { - if (vbuf->translate) - vbuf->translate->release(vbuf->translate); - - vbuf->translate = translate_create( &hw_key ); + translate_key_sanitize(&hw_key); + vbuf->translate = translate_cache_find(vbuf->cache, &hw_key); vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0); } @@ -433,6 +433,9 @@ static void vbuf_destroy( struct draw_stage *stage ) if (vbuf->render) vbuf->render->destroy( vbuf->render ); + if (vbuf->cache) + translate_cache_destroy(vbuf->cache); + FREE( stage ); } @@ -463,6 +466,11 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, 16 ); if (!vbuf->indices) goto fail; + + vbuf->cache = translate_cache_create(); + if (!vbuf->cache) + goto fail; + vbuf->vertices = NULL; vbuf->vertex_ptr = vbuf->vertices; diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 671abc25ce..e458cbe533 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -49,7 +49,6 @@ void draw_pt_emit_prepare( struct pt_emit *emit, const struct vertex_info *vinfo; unsigned dst_offset; struct translate_key hw_key; - unsigned keysize; unsigned i; boolean ok; @@ -62,7 +61,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, /* Must do this after set_primitive() above: */ vinfo = draw->render->get_vertex_info(draw->render); - keysize = 2*4 + vinfo->num_attribs * sizeof(hw_key.element[0]); + /* Translate from pipeline vertices to hw vertices. */ @@ -121,9 +120,9 @@ void draw_pt_emit_prepare( struct pt_emit *emit, hw_key.output_stride = vinfo->size * 4; if (!emit->translate || - memcmp(&emit->translate->key, &hw_key, keysize) != 0) + translate_key_compare(&emit->translate->key, &hw_key) != 0) { - memset((char *)&hw_key + keysize, 0, sizeof(hw_key) - keysize); + translate_key_sanitize(&hw_key); emit->translate = translate_cache_find(emit->cache, &hw_key); } } @@ -197,7 +196,8 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) void draw_pt_emit_destroy( struct pt_emit *emit ) { - translate_cache_destroy(emit->cache); + if (emit->cache) + translate_cache_destroy(emit->cache); FREE(emit); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index a5bebb4ca1..100117a9ae 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -62,11 +62,8 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, unsigned i, nr = 0; unsigned dst_offset = 0; struct translate_key key; - unsigned keysize; fetch->vertex_size = vertex_size; - keysize = (2*4 + - (draw->pt.nr_vertex_elements + 1) * sizeof(key.element[0])); /* Always emit/leave space for a vertex header. * @@ -111,9 +108,9 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, if (!fetch->translate || - memcmp(&fetch->translate->key, &key, keysize) != 0) + translate_key_compare(&fetch->translate->key, &key) != 0) { - memset((char *)&key + keysize, 0, sizeof(key) - keysize); + translate_key_sanitize(&key); fetch->translate = translate_cache_find(fetch->cache, &key); { diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index a4de341df8..b7b970a297 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -174,8 +174,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, /* Don't bother with caching at this stage: */ if (!feme->translate || - memcmp(&feme->translate->key, &key, sizeof(key)) != 0) + translate_key_compare(&feme->translate->key, &key) != 0) { + translate_key_sanitize(&key); feme->translate = translate_cache_find(feme->cache, &key); -- cgit v1.2.3 From 5ee2b5bdcc62e844079829f4f4301aad5374c62e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 May 2008 15:02:59 +0100 Subject: draw: fix translate double-free, minor cleanups --- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 3 --- src/gallium/auxiliary/draw/draw_pt_fetch.c | 3 ++- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 3 ++- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 86a7d1c730..67b9a9503d 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -427,9 +427,6 @@ static void vbuf_destroy( struct draw_stage *stage ) if(vbuf->indices) align_free( vbuf->indices ); - if(vbuf->translate) - vbuf->translate->release( vbuf->translate ); - if (vbuf->render) vbuf->render->destroy( vbuf->render ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 100117a9ae..b96335b789 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -184,7 +184,8 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) void draw_pt_fetch_destroy( struct pt_fetch *fetch ) { - translate_cache_destroy(fetch->cache); + if (fetch->cache) + translate_cache_destroy(fetch->cache); FREE(fetch); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index b7b970a297..4ea7d4359f 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -268,7 +268,8 @@ static void fetch_emit_destroy( struct draw_pt_middle_end *middle ) { struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; - translate_cache_destroy(feme->cache); + if (feme->cache) + translate_cache_destroy(feme->cache); FREE(middle); } -- cgit v1.2.3 From 501be9c7dd0cc5f985c708fa0e5f35d7fd20deb4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 May 2008 15:02:59 +0100 Subject: draw: fix translate double-free, minor cleanups --- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 3 --- src/gallium/auxiliary/draw/draw_pt_fetch.c | 3 ++- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 3 ++- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 2a19e6916a..64a9f9084f 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -427,9 +427,6 @@ static void vbuf_destroy( struct draw_stage *stage ) if(vbuf->indices) align_free( vbuf->indices ); - if(vbuf->translate) - vbuf->translate->release( vbuf->translate ); - if (vbuf->render) vbuf->render->destroy( vbuf->render ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index d62cd9358b..034e0eccb2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -223,7 +223,8 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) void draw_pt_fetch_destroy( struct pt_fetch *fetch ) { - translate_cache_destroy(fetch->cache); + if (fetch->cache) + translate_cache_destroy(fetch->cache); FREE(fetch); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 8df4241b82..bdbb039f9e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -320,7 +320,8 @@ static void fetch_emit_destroy( struct draw_pt_middle_end *middle ) { struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; - translate_cache_destroy(feme->cache); + if (feme->cache) + translate_cache_destroy(feme->cache); FREE(middle); } -- cgit v1.2.3 From 7462f0557f9cce73ff2d32e62ef110b5d8622f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 9 May 2008 18:04:16 +0100 Subject: draw: Fix number of vertices allocated in draw_pt_emit(). --- src/gallium/auxiliary/draw/draw_pt_emit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index e458cbe533..ce3a153f64 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -146,7 +146,7 @@ void draw_pt_emit( struct pt_emit *emit, hw_verts = render->allocate_vertices(render, (ushort)translate->key.output_stride, - (ushort)count); + (ushort)vertex_count); if (!hw_verts) { assert(0); return; -- cgit v1.2.3 From 140b3f7f9cc682809170d7c311f89e0477dba5aa Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 10 May 2008 12:16:19 -0600 Subject: gallium: remove unused code --- src/gallium/drivers/softpipe/sp_quad_fs.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 625d0f9b48..8c88c192f8 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -53,7 +53,6 @@ struct quad_shade_stage struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS]; struct tgsi_exec_machine machine; struct tgsi_exec_vector *inputs, *outputs; - int colorOutSlot, depthOutSlot; }; @@ -156,20 +155,6 @@ static void shade_begin(struct quad_stage *qs) qss->samplers[i].texture = softpipe->texture[i]; } - /* find output slots for depth, color */ - qss->colorOutSlot = -1; - qss->depthOutSlot = -1; - for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) { - switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) { - case TGSI_SEMANTIC_POSITION: - qss->depthOutSlot = i; - break; - case TGSI_SEMANTIC_COLOR: - qss->colorOutSlot = i; - break; - } - } - softpipe->fs->prepare( softpipe->fs, &qss->machine, qss->samplers ); -- cgit v1.2.3 From 6807b4f6b1fa6ef0412714622ff16fe9d1487a8e Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 10 May 2008 12:46:00 -0600 Subject: gallium: optimize the flush_spans() function --- src/gallium/drivers/softpipe/sp_setup.c | 81 ++++++++++++++++----------------- 1 file changed, 40 insertions(+), 41 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 5370d85275..543d86a5cb 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -208,78 +208,77 @@ static INLINE int block( int x ) } -/** - * Compute mask which indicates which pixels in the 2x2 quad are actually inside - * the triangle's bounds. - * - * this is pretty nasty... may need to rework flush_spans again to - * fix it, if possible. - */ -static unsigned calculate_mask( struct setup_context *setup, int x ) -{ - unsigned mask = 0x0; - - if (x >= setup->span.left[0] && x < setup->span.right[0]) - mask |= MASK_TOP_LEFT; - - if (x >= setup->span.left[1] && x < setup->span.right[1]) - mask |= MASK_BOTTOM_LEFT; - - if (x+1 >= setup->span.left[0] && x+1 < setup->span.right[0]) - mask |= MASK_TOP_RIGHT; - - if (x+1 >= setup->span.left[1] && x+1 < setup->span.right[1]) - mask |= MASK_BOTTOM_RIGHT; - - return mask; -} - - /** * Render a horizontal span of quads */ static void flush_spans( struct setup_context *setup ) { + const int xleft0 = setup->span.left[0]; + const int xleft1 = setup->span.left[1]; + const int xright0 = setup->span.right[0]; + const int xright1 = setup->span.right[1]; int minleft, maxright; int x; switch (setup->span.y_flags) { case 0x3: /* both odd and even lines written (both quad rows) */ - minleft = MIN2(setup->span.left[0], setup->span.left[1]); - maxright = MAX2(setup->span.right[0], setup->span.right[1]); + minleft = block(MIN2(xleft0, xleft1)); + maxright = block(MAX2(xright0, xright1)); + for (x = minleft; x <= maxright; x += 2) { + /* determine which of the four pixels is inside the span bounds */ + uint mask = 0x0; + if (x >= xleft0 && x < xright0) + mask |= MASK_TOP_LEFT; + if (x >= xleft1 && x < xright1) + mask |= MASK_BOTTOM_LEFT; + if (x+1 >= xleft0 && x+1 < xright0) + mask |= MASK_TOP_RIGHT; + if (x+1 >= xleft1 && x+1 < xright1) + mask |= MASK_BOTTOM_RIGHT; + emit_quad( setup, x, setup->span.y, mask ); + } break; case 0x1: /* only even line written (quad top row) */ - minleft = setup->span.left[0]; - maxright = setup->span.right[0]; + minleft = block(xleft0); + maxright = block(xright0); + for (x = minleft; x <= maxright; x += 2) { + uint mask = 0x0; + if (x >= xleft0 && x < xright0) + mask |= MASK_TOP_LEFT; + if (x+1 >= xleft0 && x+1 < xright0) + mask |= MASK_TOP_RIGHT; + emit_quad( setup, x, setup->span.y, mask ); + } break; case 0x2: /* only odd line written (quad bottom row) */ - minleft = setup->span.left[1]; - maxright = setup->span.right[1]; + minleft = block(xleft1); + maxright = block(xright1); + for (x = minleft; x <= maxright; x += 2) { + uint mask = 0x0; + if (x >= xleft1 && x < xright1) + mask |= MASK_BOTTOM_LEFT; + if (x+1 >= xleft1 && x+1 < xright1) + mask |= MASK_BOTTOM_RIGHT; + emit_quad( setup, x, setup->span.y, mask ); + } break; default: return; } - /* XXX this loop could be moved into the above switch cases and - * calculate_mask() could be simplified a bit... - */ - for (x = block(minleft); x <= block(maxright); x += 2) { - emit_quad( setup, x, setup->span.y, - calculate_mask( setup, x ) ); - } - setup->span.y = 0; setup->span.y_flags = 0; setup->span.right[0] = 0; setup->span.right[1] = 0; } + #if DEBUG_VERTS static void print_vertex(const struct setup_context *setup, const float (*v)[4]) -- cgit v1.2.3 From c0a6040f568e0c9be07797b2dc2fdd8a3624ec34 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 May 2008 13:09:58 +0100 Subject: translate: helper functions for mimizing cost of key compares --- src/gallium/auxiliary/translate/translate.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index de6f09d18a..b8210af50c 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -95,6 +95,27 @@ struct translate *translate_lookup_or_create( struct translate_context *tctx, struct translate *translate_create( const struct translate_key *key ); +static INLINE int translate_keysize( const struct translate_key *key ) +{ + return 2 * sizeof(int) + key->nr_elements * sizeof(struct translate_element); +} + +static INLINE int translate_key_compare( const struct translate_key *a, + const struct translate_key *b ) +{ + int keysize = translate_keysize(a); + return memcmp(a, b, keysize); +} + + +static INLINE void translate_key_sanitize( struct translate_key *a ) +{ + int keysize = translate_keysize(a); + char *ptr = (char *)a; + memset(ptr + keysize, 0, sizeof(*a) - keysize); +} + + /******************************************************************************* * Private: */ -- cgit v1.2.3 From 7ddb925b8bc6c18eba953e34d2b630a3a6593f05 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 9 May 2008 13:10:15 +0100 Subject: draw: mimize cost of translate key compares, use cache universally --- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 20 ++++++++++++++------ src/gallium/auxiliary/draw/draw_pt_emit.c | 10 +++++----- src/gallium/auxiliary/draw/draw_pt_fetch.c | 7 ++----- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 3 ++- 4 files changed, 23 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 64a9f9084f..67b9a9503d 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -42,6 +42,7 @@ #include "draw_vertex.h" #include "draw_pipe.h" #include "translate/translate.h" +#include "translate/translate_cache.h" /** @@ -75,6 +76,8 @@ struct vbuf_stage { /* Cache point size somewhere it's address won't change: */ float point_size; + + struct translate_cache *cache; }; @@ -220,7 +223,6 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) /* Translate from pipeline vertices to hw vertices. */ dst_offset = 0; - memset(&hw_key, 0, sizeof(hw_key)); for (i = 0; i < vbuf->vinfo->num_attribs; i++) { unsigned emit_sz = 0; @@ -277,12 +279,10 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) /* Don't bother with caching at this stage: */ if (!vbuf->translate || - memcmp(&vbuf->translate->key, &hw_key, sizeof(hw_key)) != 0) + translate_key_compare(&vbuf->translate->key, &hw_key) != 0) { - if (vbuf->translate) - vbuf->translate->release(vbuf->translate); - - vbuf->translate = translate_create( &hw_key ); + translate_key_sanitize(&hw_key); + vbuf->translate = translate_cache_find(vbuf->cache, &hw_key); vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0); } @@ -430,6 +430,9 @@ static void vbuf_destroy( struct draw_stage *stage ) if (vbuf->render) vbuf->render->destroy( vbuf->render ); + if (vbuf->cache) + translate_cache_destroy(vbuf->cache); + FREE( stage ); } @@ -460,6 +463,11 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, 16 ); if (!vbuf->indices) goto fail; + + vbuf->cache = translate_cache_create(); + if (!vbuf->cache) + goto fail; + vbuf->vertices = NULL; vbuf->vertex_ptr = vbuf->vertices; diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 999b2007a2..4a854f4362 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -49,7 +49,6 @@ void draw_pt_emit_prepare( struct pt_emit *emit, const struct vertex_info *vinfo; unsigned dst_offset; struct translate_key hw_key; - unsigned keysize; unsigned i; boolean ok; @@ -62,7 +61,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, /* Must do this after set_primitive() above: */ vinfo = draw->render->get_vertex_info(draw->render); - keysize = 2*4 + vinfo->num_attribs * sizeof(hw_key.element[0]); + /* Translate from pipeline vertices to hw vertices. */ @@ -121,9 +120,9 @@ void draw_pt_emit_prepare( struct pt_emit *emit, hw_key.output_stride = vinfo->size * 4; if (!emit->translate || - memcmp(&emit->translate->key, &hw_key, keysize) != 0) + translate_key_compare(&emit->translate->key, &hw_key) != 0) { - memset((char *)&hw_key + keysize, 0, sizeof(hw_key) - keysize); + translate_key_sanitize(&hw_key); emit->translate = translate_cache_find(emit->cache, &hw_key); } } @@ -244,7 +243,8 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) void draw_pt_emit_destroy( struct pt_emit *emit ) { - translate_cache_destroy(emit->cache); + if (emit->cache) + translate_cache_destroy(emit->cache); FREE(emit); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 034e0eccb2..07f4c99164 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -62,11 +62,8 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, unsigned i, nr = 0; unsigned dst_offset = 0; struct translate_key key; - unsigned keysize; fetch->vertex_size = vertex_size; - keysize = (2*4 + - (draw->pt.nr_vertex_elements + 1) * sizeof(key.element[0])); /* Always emit/leave space for a vertex header. * @@ -111,9 +108,9 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, if (!fetch->translate || - memcmp(&fetch->translate->key, &key, keysize) != 0) + translate_key_compare(&fetch->translate->key, &key) != 0) { - memset((char *)&key + keysize, 0, sizeof(key) - keysize); + translate_key_sanitize(&key); fetch->translate = translate_cache_find(fetch->cache, &key); { diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index bdbb039f9e..a1d041a74f 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -174,8 +174,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, /* Don't bother with caching at this stage: */ if (!feme->translate || - memcmp(&feme->translate->key, &key, sizeof(key)) != 0) + translate_key_compare(&feme->translate->key, &key) != 0) { + translate_key_sanitize(&key); feme->translate = translate_cache_find(feme->cache, &key); -- cgit v1.2.3 From 2258f6b437705860912be300e728efbde60e2140 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 12 May 2008 14:09:50 +0100 Subject: xlib: add failure paths for context creation --- src/gallium/winsys/xlib/xm_api.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 26b722f343..8a32c54349 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -797,8 +797,14 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) pipe = xmesa_create_i965simple(xmesa_get_pipe_winsys_aub(v)); } + if (pipe == NULL) + goto fail; + c->st = st_create_context(pipe, &v->mesa_visual, share_list ? share_list->st : NULL); + if (c->st == NULL) + goto fail; + mesaCtx = c->st->ctx; c->st->ctx->DriverCtx = c; @@ -818,6 +824,14 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) #endif return c; + + fail: + if (c->st) + st_destroy_context(c->st); + if (pipe) + pipe->destroy(pipe); + FREE(c); + return NULL; } -- cgit v1.2.3 From de818835de70961602bb9ceca86b98e9bbc63fc1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 12 May 2008 14:10:03 +0100 Subject: softpipe: add failure paths for context creation --- src/gallium/drivers/softpipe/sp_context.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index fe9cd8375e..a48e546139 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -88,7 +88,8 @@ static void softpipe_destroy( struct pipe_context *pipe ) struct pipe_winsys *ws = pipe->winsys; uint i; - draw_destroy( softpipe->draw ); + if (softpipe->draw) + draw_destroy( softpipe->draw ); softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple ); softpipe->quad.earlyz->destroy( softpipe->quad.earlyz ); @@ -216,8 +217,12 @@ softpipe_create( struct pipe_screen *screen, * Create drawing context and plug our rendering stage into it. */ softpipe->draw = draw_create(); - assert(softpipe->draw); + if (!softpipe->draw) + goto fail; + softpipe->setup = sp_draw_render_stage(softpipe); + if (!softpipe->setup) + goto fail; if (GETENV( "SP_NO_RAST" ) != NULL) softpipe->no_rast = TRUE; @@ -241,4 +246,8 @@ softpipe_create( struct pipe_screen *screen, sp_init_surface_functions(softpipe); return &softpipe->pipe; + + fail: + softpipe_destroy(&softpipe->pipe); + return NULL; } -- cgit v1.2.3 From b5e5369da5fc50d63a6ece931fac44b555eb0314 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 12 May 2008 15:20:38 +0100 Subject: draw: add fetch-shade-emit path Enable with TEST_FSE=t. Performs fetch from API-provided vertex buffers, transformation with one of three (two working) hard-coded shaders, and final emit to hardware vertices all in a single pass. Currently only really useful for profiling in conjunction with SP_NO_RAST=t. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_private.h | 3 + src/gallium/auxiliary/draw/draw_pt.c | 25 +- src/gallium/auxiliary/draw/draw_pt.h | 3 + .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 714 +++++++++++++++++++++ 5 files changed, 742 insertions(+), 4 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index da7eded21f..68e7744cc5 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -26,6 +26,7 @@ C_SOURCES = \ draw_pt_emit.c \ draw_pt_fetch.c \ draw_pt_fetch_emit.c \ + draw_pt_fetch_shade_emit.c \ draw_pt_fetch_shade_pipeline.c \ draw_pt_post_vs.c \ draw_pt_varray.c \ diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index e036d498b8..cbe64cd290 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -124,12 +124,14 @@ struct draw_context struct { struct { struct draw_pt_middle_end *fetch_emit; + /*struct draw_pt_middle_end *fetch_shade_emit;*/ struct draw_pt_middle_end *general; } middle; struct { struct draw_pt_front_end *vcache; struct draw_pt_front_end *varray; + struct draw_pt_front_end *fetch_shade_emit; /* temp hack */ } front; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; @@ -154,6 +156,7 @@ struct draw_context const void *constants; } user; + boolean test_fse; } pt; struct { diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index bccde6c5fd..448deef98c 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -64,7 +64,7 @@ draw_pt_arrays(struct draw_context *draw, opt |= PT_PIPELINE; } - if (!draw->bypass_clipping) { + if (!draw->bypass_clipping && !draw->pt.test_fse) { opt |= PT_CLIPTEST; } @@ -72,16 +72,20 @@ draw_pt_arrays(struct draw_context *draw, opt |= PT_SHADE; } - if (opt) - middle = draw->pt.middle.general; - else + + if (opt == 0) middle = draw->pt.middle.fetch_emit; + else + middle = draw->pt.middle.general; /* Pick the right frontend */ if (draw->pt.user.elts) { frontend = draw->pt.front.vcache; + } else if (opt == PT_SHADE && draw->pt.test_fse) { + /* should be a middle end.. */ + frontend = draw->pt.front.fetch_shade_emit; } else { frontend = draw->pt.front.varray; } @@ -113,6 +117,14 @@ boolean draw_pt_init( struct draw_context *draw ) if (!draw->pt.middle.fetch_emit) return FALSE; + draw->pt.test_fse = GETENV("DRAW_FSE") != NULL; + if (draw->pt.test_fse) { + draw->pt.front.fetch_shade_emit = draw_pt_fetch_shade_emit( draw ); + if (!draw->pt.front.fetch_shade_emit) + return FALSE; + } + + draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit( draw ); if (!draw->pt.middle.general) return FALSE; @@ -133,6 +145,11 @@ void draw_pt_destroy( struct draw_context *draw ) draw->pt.middle.fetch_emit = NULL; } + if (draw->pt.front.fetch_shade_emit) { + draw->pt.front.fetch_shade_emit->destroy( draw->pt.front.fetch_shade_emit ); + draw->pt.front.fetch_shade_emit = NULL; + } + if (draw->pt.front.vcache) { draw->pt.front.vcache->destroy( draw->pt.front.vcache ); draw->pt.front.vcache = NULL; diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 312fdbe4f4..bcd89f6bd6 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -121,6 +121,8 @@ const void *draw_pt_elt_ptr( struct draw_context *draw, struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ); struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw); +struct draw_pt_front_end *draw_pt_fetch_shade_emit( struct draw_context *draw ); + /* Middle-ends: * * Currently one general-purpose case which can do all possibilities, @@ -132,6 +134,7 @@ struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw); * vertex_elements. */ struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ); +//struct draw_pt_middle_end *draw_pt_fetch_shade_emit( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c new file mode 100644 index 0000000000..9e1d1add36 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -0,0 +1,714 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" +#include "draw/draw_vs.h" + +#include "translate/translate.h" + +struct fetch_shade_emit; + +struct fse_shader { + struct translate_key key; + + void (*run_linear)( const struct fetch_shade_emit *fse, + unsigned start, + unsigned count, + char *buffer ); +}; + +/* Prototype fetch, shade, emit-hw-verts all in one go. + */ +struct fetch_shade_emit { + struct draw_pt_front_end base; + + struct draw_context *draw; + + struct translate_key key; + + /* Temporaries: + */ + const float *constants; + unsigned pitch[PIPE_MAX_ATTRIBS]; + const ubyte *src[PIPE_MAX_ATTRIBS]; + unsigned prim; + + /* Points to one of the three hardwired example shaders, below: + */ + struct fse_shader *active; + + /* Temporary: A list of hard-wired shaders. Of course the plan + * would be to generate these for a given (vertex-shader, + * translate-key) pair... + */ + struct fse_shader shader[10]; + int nr_shaders; +}; + + + +/* Not quite passthrough yet -- we're still running the 'shader' here, + * inlined into the vertex fetch function. + */ +static void fetch_xyz_rgb_st( const struct fetch_shade_emit *fse, + unsigned start, + unsigned count, + char *buffer ) +{ + unsigned i; + + const float *m = fse->constants; + const float m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; + const float m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; + const float m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; + const float m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; + + const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; + const ubyte *st = fse->src[2] + start * fse->pitch[2]; + + float *out = (float *)buffer; + + + assert(fse->pitch[1] == 0); + + /* loop over vertex attributes (vertex shader inputs) + */ + for (i = 0; i < count; i++) { + { + const float *in = (const float *)xyz; + const float ix = in[0], iy = in[1], iz = in[2]; + + out[0] = m0 * ix + m4 * iy + m8 * iz + m12; + out[1] = m1 * ix + m5 * iy + m9 * iz + m13; + out[2] = m2 * ix + m6 * iy + m10 * iz + m14; + out[3] = m3 * ix + m7 * iy + m11 * iz + m15; + xyz += fse->pitch[0]; + } + + { + out[4] = 1.0f; + out[5] = 1.0f; + out[6] = 1.0f; + out[7] = 1.0f; + } + + { + const float *in = (const float *)st; st += fse->pitch[2]; + out[8] = in[0]; + out[9] = in[1]; + out[10] = 0.0f; + out[11] = 1.0f; + } + + out += 12; + } +} + + + +static void fetch_xyz_rgb( const struct fetch_shade_emit *fse, + unsigned start, + unsigned count, + char *buffer ) +{ + unsigned i; + + const float *m = (const float *)fse->constants; + const float m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; + const float m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; + const float m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; + const float m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; + + const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; + const ubyte *rgb = fse->src[1] + start * fse->pitch[1]; + + float *out = (float *)buffer; + +// debug_printf("rgb %f %f %f\n", rgb[0], rgb[1], rgb[2]); + + + for (i = 0; i < count; i++) { + { + const float *in = (const float *)xyz; + const float ix = in[0], iy = in[1], iz = in[2]; + + out[0] = m0 * ix + m4 * iy + m8 * iz + m12; + out[1] = m1 * ix + m5 * iy + m9 * iz + m13; + out[2] = m2 * ix + m6 * iy + m10 * iz + m14; + out[3] = m3 * ix + m7 * iy + m11 * iz + m15; + xyz += fse->pitch[0]; + } + + { + const float *in = (const float *)rgb; + out[4] = in[0]; + out[5] = in[1]; + out[6] = in[2]; + out[7] = 1.0f; + rgb += fse->pitch[1]; + } + + out += 8; + } +} + + + + +static void fetch_xyz_rgb_psiz( const struct fetch_shade_emit *fse, + unsigned start, + unsigned count, + char *buffer ) +{ + unsigned i; + + const float *m = (const float *)fse->constants; + const float m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; + const float m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; + const float m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; + const float m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; + + const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; + const float *rgb = (const float *)(fse->src[1] + start * fse->pitch[1]); + const float psiz = 1.0; + + float *out = (float *)buffer; + + + assert(fse->pitch[1] == 0); + + for (i = 0; i < count; i++) { + { + const float *in = (const float *)xyz; + const float ix = in[0], iy = in[1], iz = in[2]; + + out[0] = m0 * ix + m4 * iy + m8 * iz + m12; + out[1] = m1 * ix + m5 * iy + m9 * iz + m13; + out[2] = m2 * ix + m6 * iy + m10 * iz + m14; + out[3] = m3 * ix + m7 * iy + m11 * iz + m15; + xyz += fse->pitch[0]; + } + + { + out[4] = rgb[0]; + out[5] = rgb[1]; + out[6] = rgb[2]; + out[7] = 1.0f; + } + + { + out[8] = psiz; + } + + out += 9; + } +} + + + + +static boolean set_prim( struct fetch_shade_emit *fse, + unsigned prim, + unsigned count ) +{ + struct draw_context *draw = fse->draw; + + fse->prim = prim; + + switch (prim) { + case PIPE_PRIM_LINE_LOOP: + if (count > 1024) + return FALSE; + draw->render->set_primitive( draw->render, PIPE_PRIM_LINE_STRIP ); + break; + + case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_POLYGON: + if (count > 1024) + return FALSE; + draw->render->set_primitive( draw->render, prim ); + break; + + case PIPE_PRIM_QUADS: + case PIPE_PRIM_QUAD_STRIP: + draw->render->set_primitive( draw->render, PIPE_PRIM_TRIANGLES ); + break; + + default: + draw->render->set_primitive( draw->render, prim ); + break; + } + + return TRUE; +} + + + + + + +static void fse_prepare( struct draw_pt_front_end *fe, + unsigned prim, + struct draw_pt_middle_end *unused, + unsigned opt ) +{ + struct fetch_shade_emit *fse = (struct fetch_shade_emit *)fe; + struct draw_context *draw = fse->draw; + unsigned num_vs_inputs = draw->vertex_shader->info.num_inputs; + unsigned num_vs_outputs = draw->vertex_shader->info.num_outputs; + const struct vertex_info *vinfo; + unsigned i; + boolean need_psize = 0; + + + if (draw->pt.user.elts) { + assert(0); + return ; + } + + if (!set_prim(fse, prim, /*count*/1022 )) { + assert(0); + return ; + } + + /* Must do this after set_primitive() above: + */ + vinfo = draw->render->get_vertex_info(draw->render); + + + + fse->key.nr_elements = MAX2(num_vs_outputs, /* outputs - translate to hw format */ + num_vs_inputs); /* inputs - fetch from api format */ + + fse->key.output_stride = vinfo->size * 4; + memset(fse->key.element, 0, + fse->key.nr_elements * sizeof(fse->key.element[0])); + + for (i = 0; i < num_vs_inputs; i++) { + const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; + fse->key.element[i].input_format = src->src_format; + + /* Consider ignoring these at this point, ie make generated + * programs independent of this state: + */ + fse->key.element[i].input_buffer = 0; //src->vertex_buffer_index; + fse->key.element[i].input_offset = 0; //src->src_offset; + } + + + { + unsigned dst_offset = 0; + + for (i = 0; i < vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned output_format = PIPE_FORMAT_NONE; + unsigned vs_output = vinfo->src_index[i]; + + switch (vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + need_psize = 1; + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + vs_output = num_vs_outputs + 1; + + break; + default: + assert(0); + break; + } + + /* The elements in the key correspond to vertex shader output + * numbers, not to positions in the hw vertex description -- + * that's handled by the output_offset field. + */ + fse->key.element[vs_output].output_format = output_format; + fse->key.element[vs_output].output_offset = dst_offset; + + dst_offset += emit_sz; + assert(fse->key.output_stride >= dst_offset); + } + } + + /* To make psize work, really need to tell the vertex shader to + * copy that value from input->output. For 'translate' this was + * implicit for all elements. + */ +#if 0 + if (need_psize) { + unsigned input = num_vs_inputs + 1; + const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; + fse->key.element[i].input_format = PIPE_FORMAT_R32_FLOAT; + fse->key.element[i].input_buffer = 0; //nr_buffers + 1; + fse->key.element[i].input_offset = 0; + + fse->key.nr_elements += 1; + + } +#endif + + fse->constants = draw->pt.user.constants; + + /* Would normally look up a vertex shader and peruse its list of + * varients somehow. We omitted that step and put all the + * hardcoded "shaders" into an array. We're just making the + * assumption that this happens to be a matching shader... ie + * you're running isosurf, aren't you? + */ + fse->active = NULL; + for (i = 0; i < fse->nr_shaders; i++) { + if (translate_key_compare( &fse->key, &fse->shader[i].key) == 0) + fse->active = &fse->shader[i]; + } + + if (!fse->active) { + assert(0); + return ; + } + + /* Now set buffer pointers: + */ + for (i = 0; i < num_vs_inputs; i++) { + unsigned buf = draw->pt.vertex_element[i].vertex_buffer_index; + + fse->src[i] = ((const ubyte *) draw->pt.user.vbuffer[buf] + + draw->pt.vertex_buffer[buf].buffer_offset + + draw->pt.vertex_element[i].src_offset); + + fse->pitch[i] = draw->pt.vertex_buffer[buf].pitch; + + } + + + //return TRUE; +} + + +static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr) +{ + switch (prim) { + case PIPE_PRIM_POINTS: + *first = 1; + *incr = 1; + return TRUE; + case PIPE_PRIM_LINES: + *first = 2; + *incr = 2; + return TRUE; + case PIPE_PRIM_LINE_STRIP: + *first = 2; + *incr = 1; + return TRUE; + case PIPE_PRIM_TRIANGLES: + *first = 3; + *incr = 3; + return TRUE; + case PIPE_PRIM_TRIANGLE_STRIP: + *first = 3; + *incr = 1; + return TRUE; + case PIPE_PRIM_QUADS: + *first = 4; + *incr = 4; + return TRUE; + case PIPE_PRIM_QUAD_STRIP: + *first = 4; + *incr = 2; + return TRUE; + default: + *first = 0; + *incr = 1; /* set to one so that count % incr works */ + return FALSE; + } +} + + + + +#define INDEX(i) (start + (i)) +static void fse_render_linear( struct vbuf_render *render, + unsigned prim, + unsigned start, + unsigned length ) +{ + ushort *tmp = NULL; + unsigned i, j; + + switch (prim) { + case PIPE_PRIM_LINE_LOOP: + tmp = MALLOC( sizeof(ushort) * (length + 1) ); + + for (i = 0; i < length; i++) + tmp[i] = INDEX(i); + tmp[length] = 0; + + render->draw( render, + tmp, + length+1 ); + break; + + + case PIPE_PRIM_QUAD_STRIP: + tmp = MALLOC( sizeof(ushort) * (length / 2 * 6) ); + + for (j = i = 0; i + 3 < length; i += 2, j += 6) { + tmp[j+0] = INDEX(i+0); + tmp[j+1] = INDEX(i+1); + tmp[j+2] = INDEX(i+3); + + tmp[j+3] = INDEX(i+2); + tmp[j+4] = INDEX(i+0); + tmp[j+5] = INDEX(i+3); + } + + if (j) + render->draw( render, tmp, j ); + break; + + case PIPE_PRIM_QUADS: + tmp = MALLOC( sizeof(int) * (length / 4 * 6) ); + + for (j = i = 0; i + 3 < length; i += 4, j += 6) { + tmp[j+0] = INDEX(i+0); + tmp[j+1] = INDEX(i+1); + tmp[j+2] = INDEX(i+3); + + tmp[j+3] = INDEX(i+1); + tmp[j+4] = INDEX(i+2); + tmp[j+5] = INDEX(i+3); + } + + if (j) + render->draw( render, tmp, j ); + break; + + default: + render->draw_arrays( render, + start, + length ); + break; + } + + if (tmp) + FREE(tmp); +} + + + +static boolean do_draw( struct fetch_shade_emit *fse, + unsigned start, unsigned count ) +{ + struct draw_context *draw = fse->draw; + + char *hw_verts = + draw->render->allocate_vertices( draw->render, + (ushort)fse->key.output_stride, + (ushort)count ); + + if (!hw_verts) + return FALSE; + + /* Single routine to fetch vertices, run shader and emit HW verts. + * Clipping and viewport transformation are done on hardware. + */ + fse->active->run_linear( fse, + start, count, + hw_verts ); + + /* Draw arrays path to avoid re-emitting index list again and + * again. + */ + fse_render_linear( draw->render, + fse->prim, + 0, + count ); + + + draw->render->release_vertices( draw->render, + hw_verts, + fse->key.output_stride, + count ); + + return TRUE; +} + + +static void +fse_run(struct draw_pt_front_end *fe, + pt_elt_func elt_func, + const void *elt_ptr, + unsigned count) +{ + struct fetch_shade_emit *fse = (struct fetch_shade_emit *)fe; + unsigned i = 0; + unsigned first, incr; + unsigned start = elt_func(elt_ptr, 0); + + //debug_printf("%s prim %d start %d count %d\n", __FUNCTION__, prim, start, count); + + split_prim_inplace(fse->prim, &first, &incr); + + count -= (count - first) % incr; + + while (i + first <= count) { + int nr = MIN2( count - i, 1024 ); + + /* snap to prim boundary + */ + nr -= (nr - first) % incr; + + if (!do_draw( fse, start + i, nr )) { + assert(0); + return ; + } + + /* increment allowing for repeated vertices + */ + i += nr - (first - incr); + } + + //return TRUE; +} + + +static void fse_finish( struct draw_pt_front_end *frontend ) +{ +} + + +static void +fse_destroy( struct draw_pt_front_end *frontend ) +{ + FREE(frontend); +} + +struct draw_pt_front_end *draw_pt_fetch_shade_emit( struct draw_context *draw ) +{ + struct fetch_shade_emit *fse = CALLOC_STRUCT(fetch_shade_emit); + if (!fse) + return NULL; + + fse->base.prepare = fse_prepare; + fse->base.run = fse_run; + fse->base.finish = fse_finish; + fse->base.destroy = fse_destroy; + fse->draw = draw; + + fse->shader[0].run_linear = fetch_xyz_rgb_st; + fse->shader[0].key.nr_elements = 3; + fse->shader[0].key.output_stride = 12 * sizeof(float); + + fse->shader[0].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[0].key.element[0].input_buffer = 0; + fse->shader[0].key.element[0].input_offset = 0; + fse->shader[0].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[0].key.element[0].output_offset = 0; + + fse->shader[0].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[0].key.element[1].input_buffer = 0; + fse->shader[0].key.element[1].input_offset = 0; + fse->shader[0].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[0].key.element[1].output_offset = 16; + + fse->shader[0].key.element[1].input_format = PIPE_FORMAT_R32G32_FLOAT; + fse->shader[0].key.element[1].input_buffer = 0; + fse->shader[0].key.element[1].input_offset = 0; + fse->shader[0].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[0].key.element[1].output_offset = 32; + + fse->shader[1].run_linear = fetch_xyz_rgb; + fse->shader[1].key.nr_elements = 2; + fse->shader[1].key.output_stride = 8 * sizeof(float); + + fse->shader[1].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[1].key.element[0].input_buffer = 0; + fse->shader[1].key.element[0].input_offset = 0; + fse->shader[1].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[1].key.element[0].output_offset = 0; + + fse->shader[1].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[1].key.element[1].input_buffer = 0; + fse->shader[1].key.element[1].input_offset = 0; + fse->shader[1].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[1].key.element[1].output_offset = 16; + + fse->shader[2].run_linear = fetch_xyz_rgb_psiz; + fse->shader[2].key.nr_elements = 3; + fse->shader[2].key.output_stride = 9 * sizeof(float); + + fse->shader[2].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[2].key.element[0].input_buffer = 0; + fse->shader[2].key.element[0].input_offset = 0; + fse->shader[2].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[2].key.element[0].output_offset = 0; + + fse->shader[2].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[2].key.element[1].input_buffer = 0; + fse->shader[2].key.element[1].input_offset = 0; + fse->shader[2].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[2].key.element[1].output_offset = 16; + + /* psize is special + * -- effectively add it here as another input!?! + * -- who knows how to add it as a buffer? + */ + fse->shader[2].key.element[2].input_format = PIPE_FORMAT_R32_FLOAT; + fse->shader[2].key.element[2].input_buffer = 0; + fse->shader[2].key.element[2].input_offset = 0; + fse->shader[2].key.element[2].output_format = PIPE_FORMAT_R32_FLOAT; + fse->shader[2].key.element[2].output_offset = 32; + + fse->nr_shaders = 3; + + return &fse->base; +} -- cgit v1.2.3 From 90e86363de7dbcfda3490b5c31d701350a0fa2ef Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 12 May 2008 16:16:04 +0100 Subject: softpipe: make vbuf handle all primitive types --- src/gallium/drivers/softpipe/sp_prim_setup.c | 15 +- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 255 +++++++++++++++------------ 2 files changed, 155 insertions(+), 115 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 1cf9ffa632..941ab62e00 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -64,16 +64,17 @@ static INLINE struct setup_stage *setup_stage( struct draw_stage *stage ) } +typedef const float (*cptrf4)[4]; static void do_tri(struct draw_stage *stage, struct prim_header *prim) { struct setup_stage *setup = setup_stage( stage ); - + setup_tri( setup->setup, - prim->v[0]->data, - prim->v[1]->data, - prim->v[2]->data ); + (cptrf4)prim->v[0]->data, + (cptrf4)prim->v[1]->data, + (cptrf4)prim->v[2]->data ); } static void @@ -82,8 +83,8 @@ do_line(struct draw_stage *stage, struct prim_header *prim) struct setup_stage *setup = setup_stage( stage ); setup_line( setup->setup, - prim->v[0]->data, - prim->v[1]->data ); + (cptrf4)prim->v[0]->data, + (cptrf4)prim->v[1]->data ); } static void @@ -92,7 +93,7 @@ do_point(struct draw_stage *stage, struct prim_header *prim) struct setup_stage *setup = setup_stage( stage ); setup_point( setup->setup, - prim->v[0]->data ); + (cptrf4)prim->v[0]->data ); } diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index e063fe82ef..1399776ff0 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -129,17 +129,22 @@ sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) } +static INLINE cptrf4 get_vert( const void *vertex_buffer, + int index, + int stride ) +{ + return (cptrf4)((char *)vertex_buffer + index * stride); +} static void -sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) +sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); struct softpipe_context *softpipe = cvbr->softpipe; - unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float); - unsigned i, j; - void *vertex_buffer = cvbr->vertex_buffer; - cptrf4 v[3]; + unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float); + unsigned i; + const void *vertex_buffer = cvbr->vertex_buffer; /* XXX: break this dependency - make setup_context live under * softpipe, rename the old "setup" draw stage to something else. @@ -149,40 +154,98 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) switch (cvbr->prim) { - case PIPE_PRIM_TRIANGLES: - for (i = 0; i < nr_indices; i += 3) { - for (j = 0; j < 3; j++) - v[j] = (cptrf4)((char *)vertex_buffer + - indices[i+j] * vertex_size); - - setup_tri( setup_ctx, - v[0], - v[1], - v[2]); + case PIPE_PRIM_POINTS: + for (i = 0; i < nr; i++) { + setup_point( setup_ctx, + get_vert(vertex_buffer, indices[i-0], stride) ); } break; case PIPE_PRIM_LINES: - for (i = 0; i < nr_indices; i += 2) { - for (j = 0; j < 2; j++) - v[j] = (cptrf4)((char *)vertex_buffer + - indices[i+j] * vertex_size); + for (i = 1; i < nr; i += 2) { + setup_line( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + break; + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < nr; i ++) { setup_line( setup_ctx, - v[0], - v[1] ); + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); } break; - case PIPE_PRIM_POINTS: - for (i = 0; i < nr_indices; i++) { - v[0] = (cptrf4)((char *)vertex_buffer + - indices[i] * vertex_size); + case PIPE_PRIM_LINE_LOOP: + for (i = 1; i < nr; i ++) { + setup_line( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + if (nr) { + setup_line( setup_ctx, + get_vert(vertex_buffer, indices[nr-1], stride), + get_vert(vertex_buffer, indices[0], stride) ); + } + break; - setup_point( setup_ctx, - v[0] ); + + case PIPE_PRIM_TRIANGLES: + for (i = 2; i < nr; i += 3) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride)); + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + for (i = 2; i < nr; i += 3) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i+(i&1)-2], stride), + get_vert(vertex_buffer, indices[i-(i&1)-1], stride), + get_vert(vertex_buffer, indices[i-0], stride)); } break; + + case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_POLYGON: + for (i = 2; i < nr; i += 3) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride)); + } + break; + case PIPE_PRIM_QUADS: + for (i = 3; i < nr; i += 4) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride)); + + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride)); + } + break; + case PIPE_PRIM_QUAD_STRIP: + for (i = 3; i < nr; i += 2) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride)); + + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-2], stride)); + } + break; + default: + assert(0); } /* XXX: why are we calling this??? If we had to call something, it @@ -203,130 +266,106 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) struct softpipe_context *softpipe = cvbr->softpipe; struct draw_stage *setup = softpipe->setup; const void *vertex_buffer = cvbr->vertex_buffer; - const unsigned vertex_size = softpipe->vertex_info_vbuf.size * sizeof(float); + const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float); unsigned i; struct setup_context *setup_ctx = sp_draw_setup_context(setup); - cptrf4 v[3]; - -#define VERTEX(I) \ - (cptrf4) ((char *) vertex_buffer + (I) * vertex_size) switch (cvbr->prim) { case PIPE_PRIM_POINTS: for (i = 0; i < nr; i++) { - v[0] = VERTEX(i); - setup_point( setup_ctx, v[0] ); + setup_point( setup_ctx, + get_vert(vertex_buffer, i-0, stride) ); } break; + case PIPE_PRIM_LINES: - assert(nr % 2 == 0); - for (i = 0; i < nr; i += 2) { - v[0] = VERTEX(i); - v[1] = VERTEX(i + 1); - setup_line( setup_ctx, v[0], v[1] ); + for (i = 1; i < nr; i += 2) { + setup_line( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); } break; + case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < nr; i++) { - v[0] = VERTEX(i - 1); - v[1] = VERTEX(i); - setup_line( setup_ctx, v[0], v[1] ); + for (i = 1; i < nr; i ++) { + setup_line( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); } break; + + case PIPE_PRIM_LINE_LOOP: + for (i = 1; i < nr; i ++) { + setup_line( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + if (nr) { + setup_line( setup_ctx, + get_vert(vertex_buffer, nr-1, stride), + get_vert(vertex_buffer, 0, stride) ); + } + break; + + case PIPE_PRIM_TRIANGLES: - assert(nr % 3 == 0); - for (i = 0; i < nr; i += 3) { - v[0] = VERTEX(i + 0); - v[1] = VERTEX(i + 1); - v[2] = VERTEX(i + 2); + for (i = 2; i < nr; i += 3) { setup_tri( setup_ctx, - v[0], - v[1], - v[2] ); + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride)); } break; + case PIPE_PRIM_TRIANGLE_STRIP: - assert(nr >= 3); - for (i = 2; i < nr; i++) { - v[0] = VERTEX(i - 2); - v[1] = VERTEX(i - 1); - v[2] = VERTEX(i); + for (i = 2; i < nr; i += 3) { setup_tri( setup_ctx, - v[0], - v[1], - v[2] ); + get_vert(vertex_buffer, i+(i&1)-2, stride), + get_vert(vertex_buffer, i-(i&1)-1, stride), + get_vert(vertex_buffer, i-0, stride)); } break; + case PIPE_PRIM_TRIANGLE_FAN: - assert(nr >= 3); - for (i = 2; i < nr; i++) { - v[0] = VERTEX(0); - v[1] = VERTEX(i - 1); - v[2] = VERTEX(i); + case PIPE_PRIM_POLYGON: + for (i = 2; i < nr; i += 3) { setup_tri( setup_ctx, - v[0], - v[1], - v[2] ); + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride)); } break; case PIPE_PRIM_QUADS: assert(nr % 4 == 0); - for (i = 0; i < nr; i += 4) { - v[0] = VERTEX(i + 0); - v[1] = VERTEX(i + 1); - v[2] = VERTEX(i + 2); + for (i = 3; i < nr; i += 4) { setup_tri( setup_ctx, - v[0], - v[1], - v[2] ); + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride)); - v[0] = VERTEX(i + 0); - v[1] = VERTEX(i + 2); - v[2] = VERTEX(i + 3); setup_tri( setup_ctx, - v[0], - v[1], - v[2] ); + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride)); } break; case PIPE_PRIM_QUAD_STRIP: assert(nr >= 4); - for (i = 2; i < nr; i += 2) { - v[0] = VERTEX(i - 2); - v[1] = VERTEX(i); - v[2] = VERTEX(i + 1); + for (i = 3; i < nr; i += 2) { setup_tri( setup_ctx, - v[0], - v[1], - v[2] ); + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride)); - v[0] = VERTEX(i - 2); - v[1] = VERTEX(i + 1); - v[2] = VERTEX(i - 1); - setup_tri( setup_ctx, - v[0], - v[1], - v[2] ); - } - break; - case PIPE_PRIM_POLYGON: - /* draw as tri fan */ - for (i = 2; i < nr; i++) { - v[0] = VERTEX(0); - v[1] = VERTEX(i - 1); - v[2] = VERTEX(i); setup_tri( setup_ctx, - v[0], - v[1], - v[2] ); + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-2, stride)); } break; default: - /* XXX finish remaining prim types */ assert(0); } - -#undef VERTEX } -- cgit v1.2.3 From f116a149160d50d43a23b02a3416725d6f895d51 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 12 May 2008 17:30:05 +0100 Subject: softpipe: more work to get non-reduced primitives working in vbuf --- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 45 ++++++++++++----------------- 1 file changed, 19 insertions(+), 26 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 1399776ff0..e9fae951e0 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -116,15 +116,8 @@ sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) - if (prim == PIPE_PRIM_TRIANGLES || - prim == PIPE_PRIM_LINES || - prim == PIPE_PRIM_POINTS) { - cvbr->prim = prim; - return TRUE; - } - else { - return FALSE; - } + cvbr->prim = prim; + return TRUE; } @@ -201,7 +194,7 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 2; i < nr; i += 3) { + for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i+(i&1)-2], stride), get_vert(vertex_buffer, indices[i-(i&1)-1], stride), @@ -211,7 +204,7 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_TRIANGLE_FAN: case PIPE_PRIM_POLYGON: - for (i = 2; i < nr; i += 3) { + for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, get_vert(vertex_buffer, indices[0], stride), get_vert(vertex_buffer, indices[i-1], stride), @@ -223,10 +216,10 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride)); + get_vert(vertex_buffer, indices[i-0], stride)); setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride)); } @@ -234,14 +227,14 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) case PIPE_PRIM_QUAD_STRIP: for (i = 3; i < nr; i += 2) { setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride)); setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-2], stride)); + get_vert(vertex_buffer, indices[i-0], stride)); } break; default: @@ -265,11 +258,13 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); struct softpipe_context *softpipe = cvbr->softpipe; struct draw_stage *setup = softpipe->setup; - const void *vertex_buffer = cvbr->vertex_buffer; + const void *vertex_buffer = NULL; const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float); unsigned i; struct setup_context *setup_ctx = sp_draw_setup_context(setup); + vertex_buffer = (void *)get_vert(cvbr->vertex_buffer, start, stride); + switch (cvbr->prim) { case PIPE_PRIM_POINTS: for (i = 0; i < nr; i++) { @@ -318,7 +313,7 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 2; i < nr; i += 3) { + for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, get_vert(vertex_buffer, i+(i&1)-2, stride), get_vert(vertex_buffer, i-(i&1)-1, stride), @@ -328,7 +323,7 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) case PIPE_PRIM_TRIANGLE_FAN: case PIPE_PRIM_POLYGON: - for (i = 2; i < nr; i += 3) { + for (i = 2; i < nr; i += 1) { setup_tri( setup_ctx, get_vert(vertex_buffer, 0, stride), get_vert(vertex_buffer, i-1, stride), @@ -336,31 +331,29 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) } break; case PIPE_PRIM_QUADS: - assert(nr % 4 == 0); for (i = 3; i < nr; i += 4) { setup_tri( setup_ctx, get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride)); + get_vert(vertex_buffer, i-0, stride)); setup_tri( setup_ctx, - get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride)); } break; case PIPE_PRIM_QUAD_STRIP: - assert(nr >= 4); for (i = 3; i < nr; i += 2) { setup_tri( setup_ctx, + get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride)); setup_tri( setup_ctx, + get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-2, stride)); + get_vert(vertex_buffer, i-0, stride)); } break; default: -- cgit v1.2.3 From 44463b2997826cd14def00abf724a7a65a4fc7cb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 12 May 2008 17:36:35 +0100 Subject: draw: streamline the varray path - drop support for running the pipeline (ie. don't populate the flags values) - pass through all split-able primitives intact to the middle end - only primitives that can't be split are shunted on the draw-element path --- src/gallium/auxiliary/draw/draw_pt.c | 2 +- src/gallium/auxiliary/draw/draw_pt_varray.c | 106 +++---------- .../auxiliary/draw/draw_pt_varray_tmp_linear.h | 165 +++------------------ 3 files changed, 44 insertions(+), 229 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 448deef98c..d9e73a2396 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -81,7 +81,7 @@ draw_pt_arrays(struct draw_context *draw, /* Pick the right frontend */ - if (draw->pt.user.elts) { + if (draw->pt.user.elts || (opt & PT_PIPELINE)) { frontend = draw->pt.front.vcache; } else if (opt == PT_SHADE && draw->pt.test_fse) { /* should be a middle end.. */ diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index 59a9569270..d92ad4fda1 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -154,9 +154,9 @@ static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr static INLINE void add_draw_el(struct varray_frontend *varray, - int idx, ushort flags) + int idx) { - varray->draw_elts[varray->draw_count++] = idx | flags; + varray->draw_elts[varray->draw_count++] = idx; } @@ -165,106 +165,47 @@ static INLINE void varray_triangle( struct varray_frontend *varray, unsigned i1, unsigned i2 ) { - add_draw_el(varray, i0, 0); - add_draw_el(varray, i1, 0); - add_draw_el(varray, i2, 0); -} - -static INLINE void varray_triangle_flags( struct varray_frontend *varray, - ushort flags, - unsigned i0, - unsigned i1, - unsigned i2 ) -{ - add_draw_el(varray, i0, flags); - add_draw_el(varray, i1, 0); - add_draw_el(varray, i2, 0); + add_draw_el(varray, i0); + add_draw_el(varray, i1); + add_draw_el(varray, i2); } static INLINE void varray_line( struct varray_frontend *varray, unsigned i0, unsigned i1 ) { - add_draw_el(varray, i0, 0); - add_draw_el(varray, i1, 0); -} - - -static INLINE void varray_line_flags( struct varray_frontend *varray, - ushort flags, - unsigned i0, - unsigned i1 ) -{ - add_draw_el(varray, i0, flags); - add_draw_el(varray, i1, 0); + add_draw_el(varray, i0); + add_draw_el(varray, i1); } static INLINE void varray_point( struct varray_frontend *varray, unsigned i0 ) { - add_draw_el(varray, i0, 0); -} - -static INLINE void varray_quad( struct varray_frontend *varray, - unsigned i0, - unsigned i1, - unsigned i2, - unsigned i3 ) -{ - varray_triangle( varray, i0, i1, i3 ); - varray_triangle( varray, i1, i2, i3 ); + add_draw_el(varray, i0); } -static INLINE void varray_ef_quad( struct varray_frontend *varray, - unsigned i0, - unsigned i1, - unsigned i2, - unsigned i3 ) -{ - const unsigned omitEdge1 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_2; - const unsigned omitEdge2 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_1; - - varray_triangle_flags( varray, - DRAW_PIPE_RESET_STIPPLE | omitEdge1, - i0, i1, i3 ); - - varray_triangle_flags( varray, - omitEdge2, - i1, i2, i3 ); -} -/* At least for now, we're back to using a template include file for - * this. The two paths aren't too different though - it may be - * possible to reunify them. - */ -#define TRIANGLE(vc,flags,i0,i1,i2) varray_triangle_flags(vc,flags,i0,i1,i2) -#define QUAD(vc,i0,i1,i2,i3) varray_ef_quad(vc,i0,i1,i2,i3) -#define LINE(vc,flags,i0,i1) varray_line_flags(vc,flags,i0,i1) -#define POINT(vc,i0) varray_point(vc,i0) -#define FUNC varray_run_extras -#include "draw_pt_varray_tmp.h" -#define TRIANGLE(vc,flags,i0,i1,i2) varray_triangle(vc,i0,i1,i2) -#define QUAD(vc,i0,i1,i2,i3) varray_quad(vc,i0,i1,i2,i3) -#define LINE(vc,flags,i0,i1) varray_line(vc,i0,i1) +#define TRIANGLE(vc,i0,i1,i2) varray_triangle(vc,i0,i1,i2) +#define LINE(vc,i0,i1) varray_line(vc,i0,i1) #define POINT(vc,i0) varray_point(vc,i0) #define FUNC varray_run #include "draw_pt_varray_tmp_linear.h" -static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { +static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = { PIPE_PRIM_POINTS, PIPE_PRIM_LINES, - PIPE_PRIM_LINES, - PIPE_PRIM_LINES, + PIPE_PRIM_LINE_STRIP, + PIPE_PRIM_LINES, /* decomposed */ PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES + PIPE_PRIM_TRIANGLE_STRIP, + PIPE_PRIM_TRIANGLES, /* decomposed */ + PIPE_PRIM_QUADS, + PIPE_PRIM_QUAD_STRIP, + PIPE_PRIM_TRIANGLES /* decomposed */ }; @@ -276,17 +217,10 @@ static void varray_prepare(struct draw_pt_front_end *frontend, { struct varray_frontend *varray = (struct varray_frontend *)frontend; - if (opt & PT_PIPELINE) - { - varray->base.run = varray_run_extras; - } - else - { - varray->base.run = varray_run; - } + varray->base.run = varray_run; varray->input_prim = prim; - varray->output_prim = reduced_prim[prim]; + varray->output_prim = decompose_prim[prim]; varray->middle = middle; middle->prepare(middle, varray->output_prim, opt); diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h index 6e2b16d9be..b6f1f0cadc 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h @@ -1,3 +1,7 @@ +static unsigned trim( unsigned count, unsigned first, unsigned incr ) +{ + return count - (count - first) % incr; +} static void FUNC(struct draw_pt_front_end *frontend, pt_elt_func get_elt, @@ -5,12 +9,9 @@ static void FUNC(struct draw_pt_front_end *frontend, unsigned count) { struct varray_frontend *varray = (struct varray_frontend *)frontend; - struct draw_context *draw = varray->draw; unsigned start = (unsigned)elts; - boolean flatfirst = (draw->rasterizer->flatshade && - draw->rasterizer->flatshade_first); - unsigned i, j, flags; + unsigned i, j; unsigned first, incr; varray->fetch_start = start; @@ -27,26 +28,30 @@ static void FUNC(struct draw_pt_front_end *frontend, case PIPE_PRIM_POINTS: case PIPE_PRIM_LINES: case PIPE_PRIM_TRIANGLES: - j = 0; - while (j + first <= count) { - unsigned end = MIN2(FETCH_MAX, count - j); - end -= (end % incr); - varray_flush_linear(varray, start + j, end); - j += end; + case PIPE_PRIM_LINE_STRIP: + case PIPE_PRIM_TRIANGLE_STRIP: + case PIPE_PRIM_QUADS: + case PIPE_PRIM_QUAD_STRIP: + + for (j = 0; j < count;) { + unsigned remaining = count - j; + unsigned nr = trim( MIN2(FETCH_MAX, remaining), first, incr ); + varray_flush_linear(varray, start + j, nr); + j += nr; + if (nr != remaining) + j -= (first - incr); } break; case PIPE_PRIM_LINE_LOOP: if (count >= 2) { - flags = DRAW_PIPE_RESET_STIPPLE; - for (j = 0; j + first <= count; j += i) { unsigned end = MIN2(FETCH_MAX, count - j); end -= (end % incr); - for (i = 1; i < end; i++, flags = 0) { - LINE(varray, flags, i - 1, i); + for (i = 1; i < end; i++) { + LINE(varray, i - 1, i); } - LINE(varray, flags, i - 1, 0); + LINE(varray, i - 1, 0); i = end; fetch_init(varray, end); varray_flush(varray); @@ -54,145 +59,21 @@ static void FUNC(struct draw_pt_front_end *frontend, } break; - case PIPE_PRIM_LINE_STRIP: - flags = DRAW_PIPE_RESET_STIPPLE; - for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(FETCH_MAX, count - j); - end -= (end % incr); - for (i = 1; i < end; i++, flags = 0) { - LINE(varray, flags, i - 1, i); - } - i = end; - fetch_init(varray, end); - varray_flush(varray); - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(FETCH_MAX, count - j); - end -= (end % incr); - for (i = 0; i+2 < end; i++) { - TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - i + 0, i + 1 + (i&1), i + 2 - (i&1)); - } - i = end; - fetch_init(varray, end); - varray_flush(varray); - if (j + first + i <= count) { - varray->fetch_start -= 2; - i -= 2; - } - } - } - else { - for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(FETCH_MAX, count - j); - end -= (end % incr); - for (i = 0; i+2 < end; i++) { - TRIANGLE(varray, DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - i + 0 + (i&1), i + 1 - (i&1), i + 2); - } - i = end; - fetch_init(varray, end); - varray_flush(varray); - if (j + first + i <= count) { - varray->fetch_start -= 2; - i -= 2; - } - } - } - break; + case PIPE_PRIM_POLYGON: case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; - for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(FETCH_MAX, count - j); - end -= (end % incr); - for (i = 0; i+2 < end; i++) { - TRIANGLE(varray, flags, i + 1, i + 2, 0); - } - i = end; - fetch_init(varray, end); - varray_flush(varray); - } - } - else { - flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; - for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(FETCH_MAX, count - j); - end -= (end % incr); - for (i = 0; i+2 < end; i++) { - TRIANGLE(varray, flags, 0, i + 1, i + 2); - } - i = end; - fetch_init(varray, end); - varray_flush(varray); - } - } - } - break; - - case PIPE_PRIM_QUADS: - for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(FETCH_MAX, count - j); - end -= (end % incr); - for (i = 0; i+3 < end; i += 4) { - QUAD(varray, i + 0, i + 1, i + 2, i + 3); - } - i = end; - fetch_init(varray, end); - varray_flush(varray); - } - break; - - case PIPE_PRIM_QUAD_STRIP: for (j = 0; j + first <= count; j += i) { unsigned end = MIN2(FETCH_MAX, count - j); end -= (end % incr); - for (i = 0; i+3 < end; i += 2) { - QUAD(varray, i + 2, i + 0, i + 1, i + 3); + for (i = 2; i < end; i++) { + TRIANGLE(varray, 0, i - 1, i); } i = end; fetch_init(varray, end); varray_flush(varray); - if (j + first + i <= count) { - varray->fetch_start -= 2; - i -= 2; - } } break; - case PIPE_PRIM_POLYGON: - { - /* These bitflags look a little odd because we submit the - * vertices as (1,2,0) to satisfy flatshade requirements. - */ - const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2; - const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1; - - flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; - for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(FETCH_MAX, count - j); - end -= (end % incr); - for (i = 0; i+2 < end; i++, flags = edge_middle) { - - if (i + 3 == count) - flags |= edge_last; - - TRIANGLE(varray, flags, i + 1, i + 2, 0); - } - i = end; - fetch_init(varray, end); - varray_flush(varray); - } - } - break; - default: assert(0); break; -- cgit v1.2.3 From bbda45ec769120324f44febf00c6bb170f594f23 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 12 May 2008 19:40:20 +0100 Subject: draw: turn fse path into a middle end Also add some util functions in pt_util.c --- src/gallium/auxiliary/draw/Makefile | 2 + src/gallium/auxiliary/draw/draw_private.h | 2 +- src/gallium/auxiliary/draw/draw_pt.c | 34 +- src/gallium/auxiliary/draw/draw_pt.h | 9 +- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 39 +- src/gallium/auxiliary/draw/draw_pt_middle_fse.c | 705 +++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pt_util.c | 103 +++ src/gallium/auxiliary/draw/draw_pt_varray.c | 45 -- src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 2 +- .../auxiliary/draw/draw_pt_varray_tmp_linear.h | 9 +- src/gallium/auxiliary/draw/draw_pt_vcache.c | 15 +- 11 files changed, 847 insertions(+), 118 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_middle_fse.c create mode 100644 src/gallium/auxiliary/draw/draw_pt_util.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 68e7744cc5..67d78bdbbd 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -27,8 +27,10 @@ C_SOURCES = \ draw_pt_fetch.c \ draw_pt_fetch_emit.c \ draw_pt_fetch_shade_emit.c \ + draw_pt_middle_fse.c \ draw_pt_fetch_shade_pipeline.c \ draw_pt_post_vs.c \ + draw_pt_util.c \ draw_pt_varray.c \ draw_pt_vcache.c \ draw_vertex.c \ diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index cbe64cd290..86b901a3c8 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -124,7 +124,7 @@ struct draw_context struct { struct { struct draw_pt_middle_end *fetch_emit; - /*struct draw_pt_middle_end *fetch_shade_emit;*/ + struct draw_pt_middle_end *fetch_shade_emit; struct draw_pt_middle_end *general; } middle; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index d9e73a2396..91e35db819 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -75,6 +75,8 @@ draw_pt_arrays(struct draw_context *draw, if (opt == 0) middle = draw->pt.middle.fetch_emit; + else if (opt == PT_SHADE && draw->pt.test_fse) + middle = draw->pt.middle.fetch_shade_emit; else middle = draw->pt.middle.general; @@ -83,9 +85,11 @@ draw_pt_arrays(struct draw_context *draw, */ if (draw->pt.user.elts || (opt & PT_PIPELINE)) { frontend = draw->pt.front.vcache; +#if 0 } else if (opt == PT_SHADE && draw->pt.test_fse) { /* should be a middle end.. */ frontend = draw->pt.front.fetch_shade_emit; +#endif } else { frontend = draw->pt.front.varray; } @@ -105,6 +109,8 @@ draw_pt_arrays(struct draw_context *draw, boolean draw_pt_init( struct draw_context *draw ) { + draw->pt.test_fse = GETENV("DRAW_FSE") != NULL; + draw->pt.front.vcache = draw_pt_vcache( draw ); if (!draw->pt.front.vcache) return FALSE; @@ -117,8 +123,11 @@ boolean draw_pt_init( struct draw_context *draw ) if (!draw->pt.middle.fetch_emit) return FALSE; - draw->pt.test_fse = GETENV("DRAW_FSE") != NULL; if (draw->pt.test_fse) { + draw->pt.middle.fetch_shade_emit = draw_pt_middle_fse( draw ); + if (!draw->pt.middle.fetch_shade_emit) + return FALSE; + draw->pt.front.fetch_shade_emit = draw_pt_fetch_shade_emit( draw ); if (!draw->pt.front.fetch_shade_emit) return FALSE; @@ -145,6 +154,11 @@ void draw_pt_destroy( struct draw_context *draw ) draw->pt.middle.fetch_emit = NULL; } + if (draw->pt.middle.fetch_shade_emit) { + draw->pt.middle.fetch_shade_emit->destroy( draw->pt.middle.fetch_shade_emit ); + draw->pt.middle.fetch_shade_emit = NULL; + } + if (draw->pt.front.fetch_shade_emit) { draw->pt.front.fetch_shade_emit->destroy( draw->pt.front.fetch_shade_emit ); draw->pt.front.fetch_shade_emit = NULL; @@ -163,19 +177,6 @@ void draw_pt_destroy( struct draw_context *draw ) -static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { - PIPE_PRIM_POINTS, - PIPE_PRIM_LINES, - PIPE_PRIM_LINES, - PIPE_PRIM_LINES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES -}; - /** * Draw vertex arrays @@ -188,9 +189,10 @@ void draw_arrays(struct draw_context *draw, unsigned prim, unsigned start, unsigned count) { - if (reduced_prim[prim] != draw->reduced_prim) { + unsigned reduced_prim = draw_pt_reduced_prim(prim); + if (reduced_prim != draw->reduced_prim) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->reduced_prim = reduced_prim[prim]; + draw->reduced_prim = reduced_prim; } /* drawing done here: */ diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index bcd89f6bd6..cdae46b8d2 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -134,7 +134,7 @@ struct draw_pt_front_end *draw_pt_fetch_shade_emit( struct draw_context *draw ); * vertex_elements. */ struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ); -//struct draw_pt_middle_end *draw_pt_fetch_shade_emit( struct draw_context *draw ); +struct draw_pt_middle_end *draw_pt_middle_fse( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw); @@ -213,4 +213,11 @@ struct pt_post_vs *draw_pt_post_vs_create( struct draw_context *draw ); void draw_pt_post_vs_destroy( struct pt_post_vs *pvs ); +/******************************************************************************* + * Utils: + */ +void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr); +unsigned draw_pt_reduced_prim(unsigned prim); + + #endif diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 9e1d1add36..f756d3e0bb 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -434,43 +434,6 @@ static void fse_prepare( struct draw_pt_front_end *fe, } -static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr) -{ - switch (prim) { - case PIPE_PRIM_POINTS: - *first = 1; - *incr = 1; - return TRUE; - case PIPE_PRIM_LINES: - *first = 2; - *incr = 2; - return TRUE; - case PIPE_PRIM_LINE_STRIP: - *first = 2; - *incr = 1; - return TRUE; - case PIPE_PRIM_TRIANGLES: - *first = 3; - *incr = 3; - return TRUE; - case PIPE_PRIM_TRIANGLE_STRIP: - *first = 3; - *incr = 1; - return TRUE; - case PIPE_PRIM_QUADS: - *first = 4; - *incr = 4; - return TRUE; - case PIPE_PRIM_QUAD_STRIP: - *first = 4; - *incr = 2; - return TRUE; - default: - *first = 0; - *incr = 1; /* set to one so that count % incr works */ - return FALSE; - } -} @@ -596,7 +559,7 @@ fse_run(struct draw_pt_front_end *fe, //debug_printf("%s prim %d start %d count %d\n", __FUNCTION__, prim, start, count); - split_prim_inplace(fse->prim, &first, &incr); + draw_pt_split_prim(fse->prim, &first, &incr); count -= (count - first) % incr; diff --git a/src/gallium/auxiliary/draw/draw_pt_middle_fse.c b/src/gallium/auxiliary/draw/draw_pt_middle_fse.c new file mode 100644 index 0000000000..cdb7d260da --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_middle_fse.c @@ -0,0 +1,705 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" +#include "draw/draw_vs.h" + +#include "translate/translate.h" + +struct fetch_shade_emit; + +struct fse_shader { + struct translate_key key; + + void (*run_linear)( const struct fetch_shade_emit *fse, + unsigned start, + unsigned count, + char *buffer ); + + void (*run_elts)( const struct fetch_shade_emit *fse, + const unsigned *fetch_elts, + unsigned fetch_count, + char *buffer ); + +}; + +/* Prototype fetch, shade, emit-hw-verts all in one go. + */ +struct fetch_shade_emit { + struct draw_pt_middle_end base; + struct draw_context *draw; + + struct translate_key key; + + /* Temporaries: + */ + const float *constants; + unsigned pitch[PIPE_MAX_ATTRIBS]; + const ubyte *src[PIPE_MAX_ATTRIBS]; + unsigned prim; + + /* Points to one of the three hardwired example shaders, below: + */ + struct fse_shader *active; + + /* Temporary: A list of hard-wired shaders. Of course the plan + * would be to generate these for a given (vertex-shader, + * translate-key) pair... + */ + struct fse_shader shader[10]; + int nr_shaders; +}; + + + +/* Not quite passthrough yet -- we're still running the 'shader' here, + * inlined into the vertex fetch function. + */ +static void shader0_run_linear( const struct fetch_shade_emit *fse, + unsigned start, + unsigned count, + char *buffer ) +{ + unsigned i; + + const float *m = fse->constants; + const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; + const ubyte *rgb = fse->src[1] + start * fse->pitch[1]; + const ubyte *st = fse->src[2] + start * fse->pitch[2]; + + float *out = (float *)buffer; + + /* loop over vertex attributes (vertex shader inputs) + */ + for (i = 0; i < count; i++) { + { + const float *in = (const float *)xyz; + const float ix = in[0], iy = in[1], iz = in[2]; + + out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; + out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; + out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; + out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; + xyz += fse->pitch[0]; + } + + { + const float *in = (const float *)rgb; + out[4] = in[0]; + out[5] = in[1]; + out[6] = in[2]; + out[7] = 1.0f; + rgb += fse->pitch[1]; + } + + { + const float *in = (const float *)st; + out[8] = in[0]; + out[9] = in[1]; + out[10] = 0.0f; + out[11] = 1.0f; + st += fse->pitch[2]; + } + + out += 12; + } +} + + + +static void shader1_run_linear( const struct fetch_shade_emit *fse, + unsigned start, + unsigned count, + char *buffer ) +{ + unsigned i; + const float *m = (const float *)fse->constants; + const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; + const ubyte *rgb = fse->src[1] + start * fse->pitch[1]; + float *out = (float *)buffer; + +// debug_printf("rgb %f %f %f\n", rgb[0], rgb[1], rgb[2]); + + + for (i = 0; i < count; i++) { + { + const float *in = (const float *)xyz; + const float ix = in[0], iy = in[1], iz = in[2]; + + out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; + out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; + out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; + out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; + xyz += fse->pitch[0]; + } + + { + const float *in = (const float *)rgb; + out[4] = in[0]; + out[5] = in[1]; + out[6] = in[2]; + out[7] = 1.0f; + rgb += fse->pitch[1]; + } + + out += 8; + } +} + + + + +static void shader2_run_linear( const struct fetch_shade_emit *fse, + unsigned start, + unsigned count, + char *buffer ) +{ + unsigned i; + const float *m = (const float *)fse->constants; + const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; + const ubyte *rgb = fse->src[1] + start * fse->pitch[1]; + const float psiz = 1.0; + float *out = (float *)buffer; + + + assert(fse->pitch[1] == 0); + + for (i = 0; i < count; i++) { + { + const float *in = (const float *)xyz; + const float ix = in[0], iy = in[1], iz = in[2]; + + out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; + out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; + out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; + out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; + xyz += fse->pitch[0]; + } + + { + const float *in = (const float *)rgb; + out[4] = in[0]; + out[5] = in[1]; + out[6] = in[2]; + out[7] = 1.0f; + rgb += fse->pitch[1]; + } + + { + out[8] = psiz; + } + + out += 9; + } +} + + + + +static void shader0_run_elts( const struct fetch_shade_emit *fse, + const unsigned *elts, + unsigned count, + char *buffer ) +{ + unsigned i; + const float *m = fse->constants; + float *out = (float *)buffer; + + + /* loop over vertex attributes (vertex shader inputs) + */ + for (i = 0; i < count; i++) { + unsigned elt = elts[i]; + { + const ubyte *xyz = fse->src[0] + elt * fse->pitch[0]; + const float *in = (const float *)xyz; + const float ix = in[0], iy = in[1], iz = in[2]; + + out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; + out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; + out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; + out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; + } + + { + const ubyte *rgb = fse->src[1] + elt * fse->pitch[1]; + const float *in = (const float *)rgb; + out[4] = in[0]; + out[5] = in[1]; + out[6] = in[2]; + out[7] = 1.0f; + } + + { + const ubyte *st = fse->src[2] + elt * fse->pitch[2]; + const float *in = (const float *)st; + out[8] = in[0]; + out[9] = in[1]; + out[10] = 0.0f; + out[11] = 1.0f; + } + + out += 12; + } +} + + + +static void shader1_run_elts( const struct fetch_shade_emit *fse, + const unsigned *elts, + unsigned count, + char *buffer ) +{ + unsigned i; + const float *m = (const float *)fse->constants; + float *out = (float *)buffer; + + for (i = 0; i < count; i++) { + unsigned elt = elts[i]; + + { + const ubyte *xyz = fse->src[0] + elt * fse->pitch[0]; + const float *in = (const float *)xyz; + const float ix = in[0], iy = in[1], iz = in[2]; + + out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; + out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; + out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; + out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; + xyz += fse->pitch[0]; + } + + { + const ubyte *rgb = fse->src[1] + elt * fse->pitch[1]; + const float *in = (const float *)rgb; + out[4] = in[0]; + out[5] = in[1]; + out[6] = in[2]; + out[7] = 1.0f; + rgb += fse->pitch[1]; + } + + out += 8; + } +} + + + + +static void shader2_run_elts( const struct fetch_shade_emit *fse, + const unsigned *elts, + unsigned count, + char *buffer ) +{ + unsigned i; + const float *m = (const float *)fse->constants; + const float psiz = 1.0; + float *out = (float *)buffer; + + for (i = 0; i < count; i++) { + unsigned elt = elts[i]; + { + const ubyte *xyz = fse->src[0] + elt * fse->pitch[0]; + const float *in = (const float *)xyz; + const float ix = in[0], iy = in[1], iz = in[2]; + + out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; + out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; + out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; + out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; + } + + { + const ubyte *rgb = fse->src[1] + elt * fse->pitch[1]; + out[4] = rgb[0]; + out[5] = rgb[1]; + out[6] = rgb[2]; + out[7] = 1.0f; + } + + { + out[8] = psiz; + } + + out += 9; + } +} + + + +static void fse_prepare( struct draw_pt_middle_end *middle, + unsigned prim, + unsigned opt ) +{ + struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; + struct draw_context *draw = fse->draw; + unsigned num_vs_inputs = draw->vertex_shader->info.num_inputs; + unsigned num_vs_outputs = draw->vertex_shader->info.num_outputs; + const struct vertex_info *vinfo; + unsigned i; + boolean need_psize = 0; + + + if (draw->pt.user.elts) { + assert(0); + return ; + } + + if (!draw->render->set_primitive( draw->render, + prim )) { + assert(0); + return; + } + + /* Must do this after set_primitive() above: + */ + vinfo = draw->render->get_vertex_info(draw->render); + + + + fse->key.nr_elements = MAX2(num_vs_outputs, /* outputs - translate to hw format */ + num_vs_inputs); /* inputs - fetch from api format */ + + fse->key.output_stride = vinfo->size * 4; + memset(fse->key.element, 0, + fse->key.nr_elements * sizeof(fse->key.element[0])); + + for (i = 0; i < num_vs_inputs; i++) { + const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; + fse->key.element[i].input_format = src->src_format; + + /* Consider ignoring these at this point, ie make generated + * programs independent of this state: + */ + fse->key.element[i].input_buffer = 0; //src->vertex_buffer_index; + fse->key.element[i].input_offset = 0; //src->src_offset; + } + + + { + unsigned dst_offset = 0; + + for (i = 0; i < vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned output_format = PIPE_FORMAT_NONE; + unsigned vs_output = vinfo->src_index[i]; + + switch (vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + need_psize = 1; + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + vs_output = num_vs_outputs + 1; + + break; + default: + assert(0); + break; + } + + /* The elements in the key correspond to vertex shader output + * numbers, not to positions in the hw vertex description -- + * that's handled by the output_offset field. + */ + fse->key.element[vs_output].output_format = output_format; + fse->key.element[vs_output].output_offset = dst_offset; + + dst_offset += emit_sz; + assert(fse->key.output_stride >= dst_offset); + } + } + + /* To make psize work, really need to tell the vertex shader to + * copy that value from input->output. For 'translate' this was + * implicit for all elements. + */ +#if 0 + if (need_psize) { + unsigned input = num_vs_inputs + 1; + const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; + fse->key.element[i].input_format = PIPE_FORMAT_R32_FLOAT; + fse->key.element[i].input_buffer = 0; //nr_buffers + 1; + fse->key.element[i].input_offset = 0; + + fse->key.nr_elements += 1; + + } +#endif + + fse->constants = draw->pt.user.constants; + + /* Would normally look up a vertex shader and peruse its list of + * varients somehow. We omitted that step and put all the + * hardcoded "shaders" into an array. We're just making the + * assumption that this happens to be a matching shader... ie + * you're running isosurf, aren't you? + */ + fse->active = NULL; + for (i = 0; i < fse->nr_shaders; i++) { + if (translate_key_compare( &fse->key, &fse->shader[i].key) == 0) + fse->active = &fse->shader[i]; + } + + if (!fse->active) { + assert(0); + return ; + } + + /* Now set buffer pointers: + */ + for (i = 0; i < num_vs_inputs; i++) { + unsigned buf = draw->pt.vertex_element[i].vertex_buffer_index; + + fse->src[i] = ((const ubyte *) draw->pt.user.vbuffer[buf] + + draw->pt.vertex_buffer[buf].buffer_offset + + draw->pt.vertex_element[i].src_offset); + + fse->pitch[i] = draw->pt.vertex_buffer[buf].pitch; + + } + + + //return TRUE; +} + + + + + + + +static void fse_run_linear( struct draw_pt_middle_end *middle, + unsigned start, + unsigned count ) +{ + struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; + struct draw_context *draw = fse->draw; + + char *hw_verts; + + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + + hw_verts = draw->render->allocate_vertices( draw->render, + (ushort)fse->key.output_stride, + (ushort)count ); + + if (!hw_verts) { + assert(0); + return; + } + + /* Single routine to fetch vertices, run shader and emit HW verts. + * Clipping and viewport transformation are done elsewhere -- + * either by the API or on hardware, or for some other reason not + * required... + */ + fse->active->run_linear( fse, + start, count, + hw_verts ); + + /* Draw arrays path to avoid re-emitting index list again and + * again. + */ + draw->render->draw_arrays( draw->render, + 0, + count ); + + + draw->render->release_vertices( draw->render, + hw_verts, + fse->key.output_stride, + count ); +} + + +static void +fse_run(struct draw_pt_middle_end *middle, + const unsigned *fetch_elts, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; + struct draw_context *draw = fse->draw; + void *hw_verts; + + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + + hw_verts = draw->render->allocate_vertices( draw->render, + (ushort)fse->key.output_stride, + (ushort)fetch_count ); + if (!hw_verts) { + assert(0); + return; + } + + + /* Single routine to fetch vertices, run shader and emit HW verts. + */ + fse->active->run_elts( fse, + fetch_elts, + fetch_count, + hw_verts ); + + draw->render->draw( draw->render, + draw_elts, + draw_count ); + + draw->render->release_vertices( draw->render, + hw_verts, + fse->key.output_stride, + fetch_count ); + +} + + +static void fse_finish( struct draw_pt_middle_end *middle ) +{ +} + + +static void +fse_destroy( struct draw_pt_middle_end *middle ) +{ + FREE(middle); +} + +struct draw_pt_middle_end *draw_pt_middle_fse( struct draw_context *draw ) +{ + struct fetch_shade_emit *fse = CALLOC_STRUCT(fetch_shade_emit); + if (!fse) + return NULL; + + fse->base.prepare = fse_prepare; + fse->base.run = fse_run; + fse->base.run_linear = fse_run_linear; + fse->base.finish = fse_finish; + fse->base.destroy = fse_destroy; + fse->draw = draw; + + fse->shader[0].run_linear = shader0_run_linear; + fse->shader[0].run_elts = shader0_run_elts; + fse->shader[0].key.nr_elements = 3; + fse->shader[0].key.output_stride = 12 * sizeof(float); + + fse->shader[0].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[0].key.element[0].input_buffer = 0; + fse->shader[0].key.element[0].input_offset = 0; + fse->shader[0].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[0].key.element[0].output_offset = 0; + + fse->shader[0].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[0].key.element[1].input_buffer = 0; + fse->shader[0].key.element[1].input_offset = 0; + fse->shader[0].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[0].key.element[1].output_offset = 16; + + fse->shader[0].key.element[1].input_format = PIPE_FORMAT_R32G32_FLOAT; + fse->shader[0].key.element[1].input_buffer = 0; + fse->shader[0].key.element[1].input_offset = 0; + fse->shader[0].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[0].key.element[1].output_offset = 32; + + fse->shader[1].run_linear = shader1_run_linear; + fse->shader[1].run_elts = shader1_run_elts; + fse->shader[1].key.nr_elements = 2; + fse->shader[1].key.output_stride = 8 * sizeof(float); + + fse->shader[1].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[1].key.element[0].input_buffer = 0; + fse->shader[1].key.element[0].input_offset = 0; + fse->shader[1].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[1].key.element[0].output_offset = 0; + + fse->shader[1].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[1].key.element[1].input_buffer = 0; + fse->shader[1].key.element[1].input_offset = 0; + fse->shader[1].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[1].key.element[1].output_offset = 16; + + fse->shader[2].run_linear = shader2_run_linear; + fse->shader[2].run_elts = shader2_run_elts; + fse->shader[2].key.nr_elements = 3; + fse->shader[2].key.output_stride = 9 * sizeof(float); + + fse->shader[2].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[2].key.element[0].input_buffer = 0; + fse->shader[2].key.element[0].input_offset = 0; + fse->shader[2].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[2].key.element[0].output_offset = 0; + + fse->shader[2].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; + fse->shader[2].key.element[1].input_buffer = 0; + fse->shader[2].key.element[1].input_offset = 0; + fse->shader[2].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fse->shader[2].key.element[1].output_offset = 16; + + /* psize is special + * -- effectively add it here as another input!?! + * -- who knows how to add it as a buffer? + */ + fse->shader[2].key.element[2].input_format = PIPE_FORMAT_R32_FLOAT; + fse->shader[2].key.element[2].input_buffer = 0; + fse->shader[2].key.element[2].input_offset = 0; + fse->shader[2].key.element[2].output_format = PIPE_FORMAT_R32_FLOAT; + fse->shader[2].key.element[2].output_offset = 32; + + fse->nr_shaders = 3; + + return &fse->base; +} diff --git a/src/gallium/auxiliary/draw/draw_pt_util.c b/src/gallium/auxiliary/draw/draw_pt_util.c new file mode 100644 index 0000000000..32c8a9632c --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_util.c @@ -0,0 +1,103 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_pt.h" + +void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr) +{ + switch (prim) { + case PIPE_PRIM_POINTS: + *first = 1; + *incr = 1; + break; + case PIPE_PRIM_LINES: + *first = 2; + *incr = 2; + break; + case PIPE_PRIM_LINE_STRIP: + case PIPE_PRIM_LINE_LOOP: + *first = 2; + *incr = 1; + break; + case PIPE_PRIM_TRIANGLES: + *first = 3; + *incr = 3; + break; + case PIPE_PRIM_TRIANGLE_STRIP: + case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_POLYGON: + *first = 3; + *incr = 1; + break; + case PIPE_PRIM_QUADS: + *first = 4; + *incr = 4; + break; + case PIPE_PRIM_QUAD_STRIP: + *first = 4; + *incr = 2; + break; + default: + assert(0); + *first = 0; + *incr = 1; /* set to one so that count % incr works */ + break; + } +} + + +unsigned draw_pt_reduced_prim(unsigned prim) +{ + switch (prim) { + case PIPE_PRIM_POINTS: + return PIPE_PRIM_POINTS; + case PIPE_PRIM_LINES: + case PIPE_PRIM_LINE_STRIP: + case PIPE_PRIM_LINE_LOOP: + return PIPE_PRIM_LINES; + case PIPE_PRIM_TRIANGLES: + case PIPE_PRIM_TRIANGLE_STRIP: + case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_POLYGON: + case PIPE_PRIM_QUADS: + case PIPE_PRIM_QUAD_STRIP: + return PIPE_PRIM_TRIANGLES; + default: + assert(0); + return PIPE_PRIM_POINTS; + } +} + + diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index d92ad4fda1..af6e2d5157 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -106,51 +106,6 @@ static INLINE void fetch_init(struct varray_frontend *varray, } -static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr) -{ - switch (prim) { - case PIPE_PRIM_POINTS: - *first = 1; - *incr = 1; - return TRUE; - case PIPE_PRIM_LINES: - *first = 2; - *incr = 2; - return TRUE; - case PIPE_PRIM_LINE_STRIP: - *first = 2; - *incr = 1; - return TRUE; - case PIPE_PRIM_TRIANGLES: - *first = 3; - *incr = 3; - return TRUE; - case PIPE_PRIM_TRIANGLE_STRIP: - *first = 3; - *incr = 1; - return TRUE; - case PIPE_PRIM_TRIANGLE_FAN: - *first = 3; - *incr = 1; - return TRUE; - case PIPE_PRIM_QUADS: - *first = 4; - *incr = 4; - return TRUE; - case PIPE_PRIM_QUAD_STRIP: - *first = 4; - *incr = 2; - return TRUE; - case PIPE_PRIM_POLYGON: - *first = 3; - *incr = 1; - return TRUE; - default: - *first = 0; - *incr = 1; /* set to one so that count % incr works */ - return FALSE; - } -} static INLINE void add_draw_el(struct varray_frontend *varray, diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h index 1395275897..6979f6b544 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -15,7 +15,7 @@ static void FUNC(struct draw_pt_front_end *frontend, varray->fetch_start = start; - split_prim_inplace(varray->input_prim, &first, &incr); + draw_pt_split_prim(varray->input_prim, &first, &incr); #if 0 debug_printf("%s (%d) %d/%d\n", __FUNCTION__, diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h index b6f1f0cadc..114ed371a0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h @@ -16,7 +16,13 @@ static void FUNC(struct draw_pt_front_end *frontend, varray->fetch_start = start; - split_prim_inplace(varray->input_prim, &first, &incr); + draw_pt_split_prim(varray->input_prim, &first, &incr); + + /* Sanitize primitive length: + */ + count = trim(count, first, incr); + if (count < first) + return; #if 0 debug_printf("%s (%d) %d/%d\n", __FUNCTION__, @@ -32,7 +38,6 @@ static void FUNC(struct draw_pt_front_end *frontend, case PIPE_PRIM_TRIANGLE_STRIP: case PIPE_PRIM_QUADS: case PIPE_PRIM_QUAD_STRIP: - for (j = 0; j < count;) { unsigned remaining = count - j; unsigned nr = trim( MIN2(FETCH_MAX, remaining), first, incr ); diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 6b3fb1406b..a3495f2a30 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -204,19 +204,6 @@ static void vcache_ef_quad( struct vcache_frontend *vcache, -static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { - PIPE_PRIM_POINTS, - PIPE_PRIM_LINES, - PIPE_PRIM_LINES, - PIPE_PRIM_LINES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES, - PIPE_PRIM_TRIANGLES -}; - static void vcache_prepare( struct draw_pt_front_end *frontend, @@ -236,7 +223,7 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, } vcache->input_prim = prim; - vcache->output_prim = reduced_prim[prim]; + vcache->output_prim = draw_pt_reduced_prim(prim); vcache->middle = middle; middle->prepare( middle, vcache->output_prim, opt ); -- cgit v1.2.3 From 19f15277d1871b62902031f9fa9aabf2f1bc7c40 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 12 May 2008 17:17:18 -0400 Subject: adjust llvm code to the changes in 2.3 --- src/gallium/auxiliary/gallivm/instructions.cpp | 30 ++++++++++++-------------- src/gallium/auxiliary/gallivm/storage.cpp | 16 +++++++------- src/gallium/auxiliary/gallivm/storagesoa.cpp | 8 +++---- 3 files changed, 26 insertions(+), 28 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp index 95a670edaf..1a98491b82 100644 --- a/src/gallium/auxiliary/gallivm/instructions.cpp +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -166,10 +166,9 @@ llvm::Value * Instructions::rsq(llvm::Value *in1) Value *abs = callFAbs(x); Value *sqrt = callFSqrt(abs); - Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, - APFloat(1.f)), - sqrt, - name("rsqrt")); + Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)), + sqrt, + name("rsqrt")); return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt); } @@ -278,9 +277,8 @@ llvm::Value * Instructions::rcp(llvm::Value *in1) Value *x1 = m_builder.CreateExtractElement(in1, m_storage->constantInt(0), name("x1")); - Value *res = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, - APFloat(1.f)), - x1, name("rcp")); + Value *res = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)), + x1, name("rcp")); return vectorFromVals(res, res, res, res); } @@ -319,13 +317,13 @@ llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2) m_storage->constantInt(3), name("w")); Value *ry = m_builder.CreateMul(y1, y2, name("tyuy")); - return vectorFromVals(ConstantFP::get(Type::FloatTy, APFloat(1.f)), + return vectorFromVals(ConstantFP::get(APFloat(1.f)), ry, z, w); } llvm::Value * Instructions::ex2(llvm::Value *in) { - llvm::Value *val = callPow(ConstantFP::get(Type::FloatTy, APFloat(2.f)), + llvm::Value *val = callPow(ConstantFP::get(APFloat(2.f)), m_builder.CreateExtractElement( in, m_storage->constantInt(0), name("x1"))); @@ -526,7 +524,7 @@ llvm::Function * Instructions::declarePrintf() llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2) { - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f)); Constant *const0f = Constant::getNullValue(Type::FloatTy); std::vector vec1 = extractVector(in1); @@ -547,7 +545,7 @@ llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2) } llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2) { - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f)); Constant *const0f = Constant::getNullValue(Type::FloatTy); std::vector vec1 = extractVector(in1); @@ -571,7 +569,7 @@ llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2) llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2) { - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f)); Constant *const0f = Constant::getNullValue(Type::FloatTy); std::vector vec1 = extractVector(in1); @@ -814,10 +812,10 @@ llvm::Function * Instructions::findFunction(int label) llvm::Value * Instructions::constVector(float x, float y, float z, float w) { std::vector vec(4); - vec[0] = ConstantFP::get(Type::FloatTy, APFloat(x)); - vec[1] = ConstantFP::get(Type::FloatTy, APFloat(y)); - vec[2] = ConstantFP::get(Type::FloatTy, APFloat(z)); - vec[3] = ConstantFP::get(Type::FloatTy, APFloat(w)); + vec[0] = ConstantFP::get(APFloat(x)); + vec[1] = ConstantFP::get(APFloat(y)); + vec[2] = ConstantFP::get(APFloat(z)); + vec[3] = ConstantFP::get(APFloat(w)); return ConstantVector::get(m_floatVecType, vec); } diff --git a/src/gallium/auxiliary/gallivm/storage.cpp b/src/gallium/auxiliary/gallivm/storage.cpp index 9d9fd12360..6f373f6dd5 100644 --- a/src/gallium/auxiliary/gallivm/storage.cpp +++ b/src/gallium/auxiliary/gallivm/storage.cpp @@ -69,10 +69,10 @@ llvm::Constant *Storage::shuffleMask(int vec) { if (!m_extSwizzleVec) { std::vector elems; - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); + elems.push_back(ConstantFP::get(APFloat(0.f))); + elems.push_back(ConstantFP::get(APFloat(1.f))); + elems.push_back(ConstantFP::get(APFloat(0.f))); + elems.push_back(ConstantFP::get(APFloat(1.f))); m_extSwizzleVec = ConstantVector::get(m_floatVecType, elems); } @@ -295,10 +295,10 @@ llvm::Value * Storage::immediateElement(int idx) void Storage::addImmediate(float *val) { std::vector vec(4); - vec[0] = ConstantFP::get(Type::FloatTy, APFloat(val[0])); - vec[1] = ConstantFP::get(Type::FloatTy, APFloat(val[1])); - vec[2] = ConstantFP::get(Type::FloatTy, APFloat(val[2])); - vec[3] = ConstantFP::get(Type::FloatTy, APFloat(val[3])); + vec[0] = ConstantFP::get(APFloat(val[0])); + vec[1] = ConstantFP::get(APFloat(val[1])); + vec[2] = ConstantFP::get(APFloat(val[2])); + vec[3] = ConstantFP::get(APFloat(val[3])); m_immediates.push_back(ConstantVector::get(m_floatVecType, vec)); } diff --git a/src/gallium/auxiliary/gallivm/storagesoa.cpp b/src/gallium/auxiliary/gallivm/storagesoa.cpp index 0e6e68c9d7..78d754371f 100644 --- a/src/gallium/auxiliary/gallivm/storagesoa.cpp +++ b/src/gallium/auxiliary/gallivm/storagesoa.cpp @@ -264,10 +264,10 @@ llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &v { VectorType *vectorType = VectorType::get(Type::FloatTy, 4); std::vector immValues; - ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0])); - ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1])); - ConstantFP *constz = ConstantFP::get(Type::FloatTy, APFloat(vec[2])); - ConstantFP *constw = ConstantFP::get(Type::FloatTy, APFloat(vec[3])); + ConstantFP *constx = ConstantFP::get(APFloat(vec[0])); + ConstantFP *consty = ConstantFP::get(APFloat(vec[1])); + ConstantFP *constz = ConstantFP::get(APFloat(vec[2])); + ConstantFP *constw = ConstantFP::get(APFloat(vec[3])); immValues.push_back(constx); immValues.push_back(consty); immValues.push_back(constz); -- cgit v1.2.3 From 1c624846a81b0218b4a07328f485e295432c6312 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 13 May 2008 16:06:09 -0400 Subject: decomposition from keith, adds decomposition of more prim to the pipeline --- src/gallium/auxiliary/draw/draw_pipe.c | 74 ++++++++---- src/gallium/auxiliary/draw/draw_pt_decompose.h | 153 +++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pt_varray.c | 11 +- src/gallium/auxiliary/draw/draw_pt_vcache.c | 117 +++++++++---------- 4 files changed, 263 insertions(+), 92 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_decompose.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index cb97f955b2..1d26706dee 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -212,6 +212,55 @@ void draw_pipeline_run( struct draw_context *draw, draw->pipeline.vertex_count = 0; } +#define QUAD(i0,i1,i2,i3) \ + do_triangle( draw, \ + ( DRAW_PIPE_RESET_STIPPLE | \ + DRAW_PIPE_EDGE_FLAG_0 | \ + DRAW_PIPE_EDGE_FLAG_2 ), \ + verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i1), \ + verts + stride * (i3)); \ + do_triangle( draw, \ + ( DRAW_PIPE_EDGE_FLAG_0 | \ + DRAW_PIPE_EDGE_FLAG_1 ), \ + verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i2), \ + verts + stride * (i3)) + +#define TRIANGLE(flags,i0,i1,i2) \ + do_triangle( draw, \ + flags, /* flags */ \ + verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i1), \ + verts + stride * (i2)) + +#define LINE(flags,i0,i1) \ + do_line( draw, \ + flags, \ + verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i+1)) + +#define POINT(i0) \ + do_point( draw, \ + verts + stride * i0 ) + +#define FUNC pipe_run_linear +#define ARGS \ + struct draw_context *draw, \ + unsigned prim, \ + struct vertex_header *vertices, \ + unsigned stride + +#define LOCAL_VARS \ + char *verts = (char *)vertices; \ + boolean flatfirst = (draw->rasterizer->flatshade && \ + draw->rasterizer->flatshade_first); \ + unsigned i, flags + +#define FLUSH + +#include "draw_pt_decompose.h" + void draw_pipeline_run_linear( struct draw_context *draw, unsigned prim, struct vertex_header *vertices, @@ -219,34 +268,11 @@ void draw_pipeline_run_linear( struct draw_context *draw, unsigned stride ) { char *verts = (char *)vertices; - unsigned i; - draw->pipeline.verts = verts; draw->pipeline.vertex_stride = stride; draw->pipeline.vertex_count = count; - switch (prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i++) - do_point( draw, - verts + stride * i ); - break; - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) - do_line( draw, - i+0, /* flags */ - verts + stride * ((i+0) & ~DRAW_PIPE_FLAG_MASK), - verts + stride * (i+1)); - break; - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) - do_triangle( draw, - (i+0), /* flags */ - verts + stride * ((i+0) & ~DRAW_PIPE_FLAG_MASK), - verts + stride * (i+1), - verts + stride * (i+2)); - break; - } + pipe_run_linear(draw, prim, vertices, stride, count); draw->pipeline.verts = NULL; draw->pipeline.vertex_count = 0; diff --git a/src/gallium/auxiliary/draw/draw_pt_decompose.h b/src/gallium/auxiliary/draw/draw_pt_decompose.h new file mode 100644 index 0000000000..dccfde99dd --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_decompose.h @@ -0,0 +1,153 @@ + + +static void FUNC( ARGS, + unsigned count ) +{ + LOCAL_VARS; + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i ++) { + POINT( (i + 0) ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) { + LINE( DRAW_PIPE_RESET_STIPPLE, + (i + 0), + (i + 1)); + } + break; + + case PIPE_PRIM_LINE_LOOP: + if (count >= 2) { + flags = DRAW_PIPE_RESET_STIPPLE; + + for (i = 1; i < count; i++, flags = 0) { + LINE( flags, + (i - 1), + (i )); + } + + LINE( flags, + (i - 1), + (0 )); + } + break; + + case PIPE_PRIM_LINE_STRIP: + flags = DRAW_PIPE_RESET_STIPPLE; + for (i = 1; i < count; i++, flags = 0) { + LINE( flags, + (i - 1), + (i )); + } + break; + + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) { + TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + (i + 0), + (i + 1), + (i + 2 )); + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + (i + 0), + (i + 1 + (i&1)), + (i + 2 - (i&1))); + } + } + else { + for (i = 0; i+2 < count; i++) { + TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + (i + 0 + (i&1)), + (i + 1 - (i&1)), + (i + 2 )); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (count >= 3) { + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + (i + 1), + (i + 2), + (0 )); + } + } + else { + for (i = 0; i+2 < count; i++) { + TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + (0), + (i + 1), + (i + 2 )); + } + } + } + break; + + + case PIPE_PRIM_QUADS: + for (i = 0; i+3 < count; i += 4) { + QUAD( (i + 0), + (i + 1), + (i + 2), + (i + 3)); + } + break; + + case PIPE_PRIM_QUAD_STRIP: + for (i = 0; i+3 < count; i += 2) { + QUAD( (i + 2), + (i + 0), + (i + 1), + (i + 3)); + } + break; + + case PIPE_PRIM_POLYGON: + { + /* These bitflags look a little odd because we submit the + * vertices as (1,2,0) to satisfy flatshade requirements. + */ + const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2; + const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0; + const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1; + + flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; + + for (i = 0; i+2 < count; i++, flags = edge_middle) { + + if (i + 3 == count) + flags |= edge_last; + + TRIANGLE( flags, + (i + 1), + (i + 2), + (0)); + } + } + break; + + default: + assert(0); + break; + } + + FLUSH; +} + + +#undef TRIANGLE +#undef QUAD +#undef POINT +#undef LINE +#undef FUNC diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index af6e2d5157..06fd866ccd 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -141,14 +141,19 @@ static INLINE void varray_point( struct varray_frontend *varray, } - +#if 0 +#define TRIANGLE(flags,i0,i1,i2) varray_triangle(varray,i0,i1,i2) +#define LINE(flags,i0,i1) varray_line(varray,i0,i1) +#define POINT(i0) varray_point(varray,i0) +#define FUNC varray_decompose +#include "draw_pt_decompose.h" +#else #define TRIANGLE(vc,i0,i1,i2) varray_triangle(vc,i0,i1,i2) #define LINE(vc,i0,i1) varray_line(vc,i0,i1) #define POINT(vc,i0) varray_point(vc,i0) #define FUNC varray_run #include "draw_pt_varray_tmp_linear.h" - - +#endif static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = { PIPE_PRIM_POINTS, diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index a3495f2a30..6c17edba34 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -104,22 +104,10 @@ static INLINE void vcache_elt( struct vcache_frontend *vcache, static void vcache_triangle( struct vcache_frontend *vcache, + ushort flags, unsigned i0, unsigned i1, unsigned i2 ) -{ - vcache_elt(vcache, i0, 0); - vcache_elt(vcache, i1, 0); - vcache_elt(vcache, i2, 0); - vcache_check_flush(vcache); -} - - -static void vcache_triangle_flags( struct vcache_frontend *vcache, - ushort flags, - unsigned i0, - unsigned i1, - unsigned i2 ) { vcache_elt(vcache, i0, flags); vcache_elt(vcache, i1, 0); @@ -128,19 +116,9 @@ static void vcache_triangle_flags( struct vcache_frontend *vcache, } static void vcache_line( struct vcache_frontend *vcache, + ushort flags, unsigned i0, unsigned i1 ) -{ - vcache_elt(vcache, i0, 0); - vcache_elt(vcache, i1, 0); - vcache_check_flush(vcache); -} - - -static void vcache_line_flags( struct vcache_frontend *vcache, - ushort flags, - unsigned i0, - unsigned i1 ) { vcache_elt(vcache, i0, flags); vcache_elt(vcache, i1, 0); @@ -161,46 +139,63 @@ static void vcache_quad( struct vcache_frontend *vcache, unsigned i2, unsigned i3 ) { - vcache_triangle( vcache, i0, i1, i3 ); - vcache_triangle( vcache, i1, i2, i3 ); -} - -static void vcache_ef_quad( struct vcache_frontend *vcache, - unsigned i0, - unsigned i1, - unsigned i2, - unsigned i3 ) -{ - const unsigned omitEdge1 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_2; - const unsigned omitEdge2 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_1; - - vcache_triangle_flags( vcache, - DRAW_PIPE_RESET_STIPPLE | omitEdge1, - i0, i1, i3 ); - - vcache_triangle_flags( vcache, - omitEdge2, - i1, i2, i3 ); + vcache_triangle( vcache, + ( DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_2 ), + i0, i1, i3 ); + + vcache_triangle( vcache, + ( DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1 ), + i1, i2, i3 ); } /* At least for now, we're back to using a template include file for * this. The two paths aren't too different though - it may be * possible to reunify them. */ -#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle_flags(vc,flags,i0,i1,i2) -#define QUAD(vc,i0,i1,i2,i3) vcache_ef_quad(vc,i0,i1,i2,i3) -#define LINE(vc,flags,i0,i1) vcache_line_flags(vc,flags,i0,i1) -#define POINT(vc,i0) vcache_point(vc,i0) -#define FUNC vcache_run_extras -#include "draw_pt_vcache_tmp.h" - -#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle(vc,i0,i1,i2) -#define QUAD(vc,i0,i1,i2,i3) vcache_quad(vc,i0,i1,i2,i3) -#define LINE(vc,flags,i0,i1) vcache_line(vc,i0,i1) -#define POINT(vc,i0) vcache_point(vc,i0) +#define TRIANGLE(flags,i0,i1,i2) \ + vcache_triangle(vcache, \ + flags, \ + get_elt(elts,i0), \ + get_elt(elts,i1), \ + get_elt(elts,i2)) + +#define QUAD(i0,i1,i2,i3) \ + vcache_quad(vcache, \ + get_elt(elts,i0), \ + get_elt(elts,i1), \ + get_elt(elts,i2), \ + get_elt(elts,i3)) + +#define LINE(flags,i0,i1) \ + vcache_line(vcache, \ + flags, \ + get_elt(elts,i0), \ + get_elt(elts,i1)) + +#define POINT(i0) \ + vcache_point(vcache, \ + get_elt(elts,i0)) + #define FUNC vcache_run -#include "draw_pt_vcache_tmp.h" +#define ARGS \ + struct draw_pt_front_end *frontend, \ + pt_elt_func get_elt, \ + const void *elts + +#define LOCAL_VARS \ + struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; \ + struct draw_context *draw = vcache->draw; \ + boolean flatfirst = (draw->rasterizer->flatshade && \ + draw->rasterizer->flatshade_first); \ + unsigned prim = vcache->input_prim; \ + unsigned i, flags; +#define FLUSH vcache_flush( vcache ) + +#include "draw_pt_decompose.h" @@ -213,15 +208,7 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; - if (opt & PT_PIPELINE) - { - vcache->base.run = vcache_run_extras; - } - else - { - vcache->base.run = vcache_run; - } - + vcache->base.run = vcache_run; vcache->input_prim = prim; vcache->output_prim = draw_pt_reduced_prim(prim); -- cgit v1.2.3 From d07fbdd93941d5027a1aa7f0726140c6648a1e27 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 14 May 2008 17:19:44 +0200 Subject: i915: Added EGL winsys --- src/gallium/winsys/egl_drm/Makefile | 38 + src/gallium/winsys/egl_drm/Makefile.template | 116 +++ src/gallium/winsys/egl_drm/intel/Makefile | 40 + src/gallium/winsys/egl_drm/intel/SConscript | 39 + .../winsys/egl_drm/intel/intel_batchbuffer.c | 465 ++++++++++ .../winsys/egl_drm/intel/intel_batchbuffer.h | 133 +++ src/gallium/winsys/egl_drm/intel/intel_context.c | 366 ++++++++ src/gallium/winsys/egl_drm/intel/intel_context.h | 162 ++++ src/gallium/winsys/egl_drm/intel/intel_egl.c | 605 +++++++++++++ src/gallium/winsys/egl_drm/intel/intel_egl.h | 42 + src/gallium/winsys/egl_drm/intel/intel_lock.c | 102 +++ src/gallium/winsys/egl_drm/intel/intel_reg.h | 53 ++ src/gallium/winsys/egl_drm/intel/intel_screen.c | 680 +++++++++++++++ src/gallium/winsys/egl_drm/intel/intel_screen.h | 133 +++ .../winsys/egl_drm/intel/intel_swapbuffers.c | 327 +++++++ .../winsys/egl_drm/intel/intel_swapbuffers.h | 47 + src/gallium/winsys/egl_drm/intel/intel_winsys.h | 73 ++ .../winsys/egl_drm/intel/intel_winsys_i915.c | 184 ++++ .../winsys/egl_drm/intel/intel_winsys_pipe.c | 338 +++++++ .../winsys/egl_drm/intel/intel_winsys_softpipe.c | 82 ++ src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c | 953 ++++++++++++++++++++ src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h | 138 +++ src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h | 102 +++ src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c | 268 ++++++ src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c | 377 ++++++++ src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h | 115 +++ .../winsys/egl_drm/intel/ws_dri_mallocpool.c | 162 ++++ src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c | 970 +++++++++++++++++++++ 28 files changed, 7110 insertions(+) create mode 100644 src/gallium/winsys/egl_drm/Makefile create mode 100644 src/gallium/winsys/egl_drm/Makefile.template create mode 100644 src/gallium/winsys/egl_drm/intel/Makefile create mode 100644 src/gallium/winsys/egl_drm/intel/SConscript create mode 100644 src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_context.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_context.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_egl.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_egl.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_lock.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_reg.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_screen.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_screen.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys.h create mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c create mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/Makefile b/src/gallium/winsys/egl_drm/Makefile new file mode 100644 index 0000000000..4139d9e71f --- /dev/null +++ b/src/gallium/winsys/egl_drm/Makefile @@ -0,0 +1,38 @@ +# src/mesa/drivers/egl_drm/Makefile + +TOP = ../../../.. + +include $(TOP)/configs/current + + + +default: $(TOP)/$(LIB_DIR) subdirs + + +$(TOP)/$(LIB_DIR): + -mkdir $(TOP)/$(LIB_DIR) + + +subdirs: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +install: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) install) || exit 1 ; \ + fi \ + done + + +clean: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) clean) ; \ + fi \ + done + -rm -f common/*.o diff --git a/src/gallium/winsys/egl_drm/Makefile.template b/src/gallium/winsys/egl_drm/Makefile.template new file mode 100644 index 0000000000..3bc1fdd4d4 --- /dev/null +++ b/src/gallium/winsys/egl_drm/Makefile.template @@ -0,0 +1,116 @@ +# -*-makefile-*- + +MESA_MODULES = \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + +COMMON_GALLIUM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/utils.c \ + $(TOP)/src/mesa/drivers/dri/common/vblank.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_util.c \ + $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c + +COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ + $(TOP)/src/mesa/drivers/common/driverfuncs.c \ + $(TOP)/src/mesa/drivers/dri/common/texmem.c \ + $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c + +COMMON_BM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/dri_bufmgr.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_drmpool.c + + +ifeq ($(WINDOW_SYSTEM),dri) +WINOBJ= +WINLIB= +INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) + +OBJECTS = \ + $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) + +else +# miniglx +WINOBJ= +WINLIB=-L$(MESA)/src/glx/mini +MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini +INCLUDES = $(MINIGLX_INCLUDES) \ + $(SHARED_INCLUDES) \ + $(PCIACCESS_CFLAGS) + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(MINIGLX_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) +endif + + +### Include directories +SHARED_INCLUDES = \ + -I. \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -Iserver \ + -I$(TOP)/include \ + -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/mesa/math \ + -I$(TOP)/src/mesa/transform \ + -I$(TOP)/src/mesa/shader \ + -I$(TOP)/src/mesa/swrast \ + -I$(TOP)/src/mesa/swrast_setup \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/src/egl/drivers/dri \ + $(LIBDRM_CFLAGS) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) + + +$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template + $(TOP)/bin/mklib -noprefix -o $@ \ + $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) + + +$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) + $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) + + +depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +install: $(LIBNAME) + $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + + +include depend diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile new file mode 100644 index 0000000000..5778ba77c3 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/Makefile @@ -0,0 +1,40 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = EGL_i915.so + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + +DRIVER_SOURCES = \ + intel_winsys_pipe.c \ + intel_winsys_softpipe.c \ + intel_winsys_i915.c \ + intel_batchbuffer.c \ + intel_swapbuffers.c \ + intel_context.c \ + intel_lock.c \ + intel_screen.c \ + ws_dri_bufmgr.c \ + ws_dri_drmpool.c \ + ws_dri_fencemgr.c \ + ws_dri_mallocpool.c \ + ws_dri_slabpool.c \ + intel_egl.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") + +include ../Makefile.template + +intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c + +symlinks: diff --git a/src/gallium/winsys/egl_drm/intel/SConscript b/src/gallium/winsys/egl_drm/intel/SConscript new file mode 100644 index 0000000000..0ad19d42a8 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/SConscript @@ -0,0 +1,39 @@ +Import('*') + +env = drienv.Clone() + +env.Append(CPPPATH = [ + '../intel', + 'server' +]) + +#MINIGLX_SOURCES = server/intel_dri.c + +DRIVER_SOURCES = [ + 'intel_winsys_pipe.c', + 'intel_winsys_softpipe.c', + 'intel_winsys_i915.c', + 'intel_batchbuffer.c', + 'intel_swapbuffers.c', + 'intel_context.c', + 'intel_lock.c', + 'intel_screen.c', + 'intel_batchpool.c', +] + +sources = \ + COMMON_GALLIUM_SOURCES + \ + COMMON_BM_SOURCES + \ + DRIVER_SOURCES + +drivers = [ + softpipe, + i915simple +] + +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions +env.SharedLibrary( + target ='i915tex_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], +) \ No newline at end of file diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c new file mode 100644 index 0000000000..7ffa05a6e6 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c @@ -0,0 +1,465 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "intel_batchbuffer.h" +#include "intel_context.h" +#include "intel_egl.h" + +#include + +#if 0 +static void +intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) +{ + int i; + fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); + for (i = 0; i < count / 4; i += 4) + fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", + offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); + fprintf(stderr, "END BATCH\n\n\n"); +} +#endif + +static void +intel_realloc_relocs(struct intel_batchbuffer *batch, int num_relocs) +{ + unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; + + size *= sizeof(uint32_t); + batch->reloc = realloc(batch->reloc, size); + batch->reloc_size = num_relocs; +} + + +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) +{ + /* + * Get a new, free batchbuffer. + */ + drmBO *bo; + struct drm_bo_info_req *req; + int ret; + + driBOUnrefUserList(batch->list); + driBOResetList(batch->list); + + batch->size = 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; + ret = driBOData(batch->buffer, batch->size, NULL, NULL, 0); + assert(!ret); + + /* + * Add the batchbuffer to the validate list. + */ + + driBOAddListItem(batch->list, batch->buffer, + DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, + &batch->dest_location, &batch->node); + + req = &batch->node->bo_arg.d.req.bo_req; + + /* + * Set up information needed for us to make relocations + * relative to the underlying drm buffer objects. + */ + + driReadLockKernelBO(); + bo = driBOKernel(batch->buffer); + req->presumed_offset = (uint64_t) bo->offset; + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + batch->drmBOVirtual = (uint8_t *) bo->virtual; + driReadUnlockKernelBO(); + + /* + * Adjust the relocation buffer size. + */ + + if (batch->reloc_size > INTEL_MAX_RELOCS || + batch->reloc == NULL) + intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); + + assert(batch->reloc != NULL); + batch->reloc[0] = 0; /* No relocs yet. */ + batch->reloc[1] = 1; /* Reloc type 1 */ + batch->reloc[2] = 0; /* Only a single relocation list. */ + batch->reloc[3] = 0; /* Only a single relocation list. */ + + batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->poolOffset = driBOPoolOffset(batch->buffer); + batch->ptr = batch->map; + batch->dirty_state = ~0; + batch->nr_relocs = 0; + batch->flags = 0; + batch->id = 0;//batch->intel->intelScreen->batch_id++; +} + +/*====================================================================== + * Public functions + */ +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_screen *intel_screen) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel_screen = intel_screen; + + driGenBuffers(intel_screen->batchPool, "batchbuffer", 1, + &batch->buffer, 4096, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); + batch->last_fence = NULL; + batch->list = driBOCreateList(20); + batch->reloc = NULL; + intel_batchbuffer_reset(batch); + return batch; +} + +void +intel_batchbuffer_free(struct intel_batchbuffer *batch) +{ + if (batch->last_fence) { + driFenceFinish(batch->last_fence, + DRM_FENCE_TYPE_EXE, GL_FALSE); + driFenceUnReference(&batch->last_fence); + } + if (batch->map) { + driBOUnmap(batch->buffer); + batch->map = NULL; + } + driBOUnReference(batch->buffer); + driBOFreeList(batch->list); + if (batch->reloc) + free(batch->reloc); + batch->buffer = NULL; + free(batch); +} + +void +intel_offset_relocation(struct intel_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask) +{ + int itemLoc; + struct _drmBONode *node; + uint32_t *reloc; + struct drm_bo_info_req *req; + + driBOAddListItem(batch->list, driBO, val_flags, val_mask, + &itemLoc, &node); + req = &node->bo_arg.d.req.bo_req; + + if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { + + /* + * Stop other threads from tampering with the underlying + * drmBO while we're reading its offset. + */ + + driReadLockKernelBO(); + req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; + driReadUnlockKernelBO(); + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + } + + pre_add += driBOPoolOffset(driBO); + + if (batch->nr_relocs == batch->reloc_size) + intel_realloc_relocs(batch, batch->reloc_size * 2); + + reloc = batch->reloc + + (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); + + reloc[0] = ((uint8_t *)batch->ptr - batch->drmBOVirtual); + intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add); + reloc[1] = pre_add; + reloc[2] = itemLoc; + reloc[3] = batch->dest_location; + batch->nr_relocs++; +} + +static void +i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) +{ + buf->handle = rep->handle; + buf->flags = rep->flags; + buf->size = rep->size; + buf->offset = rep->offset; + buf->mapHandle = rep->arg_handle; + buf->proposedFlags = rep->proposed_flags; + buf->start = rep->buffer_start; + buf->fenceFlags = rep->fence_flags; + buf->replyFlags = rep->rep_flags; + buf->pageAlignment = rep->page_alignment; +} + +static int +i915_execbuf(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, + drmBOList *list, + struct drm_i915_execbuffer *ea) +{ + struct intel_screen *intel_screen = batch->intel_screen; + drmBONode *node; + drmMMListHead *l; + struct drm_i915_op_arg *arg, *first; + struct drm_bo_op_req *req; + struct drm_bo_info_rep *rep; + uint64_t *prevNext = NULL; + drmBO *buf; + int ret = 0; + uint32_t count = 0; + + first = NULL; + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + + arg = &node->bo_arg; + req = &arg->d.req; + + if (!first) + first = arg; + + if (prevNext) + *prevNext = (unsigned long)arg; + + prevNext = &arg->next; + req->bo_req.handle = node->buf->handle; + req->op = drm_bo_validate; + req->bo_req.flags = node->arg0; + req->bo_req.mask = node->arg1; + req->bo_req.hint |= 0; + count++; + } + + memset(ea, 0, sizeof(*ea)); + ea->num_buffers = count; + ea->batch.start = batch->poolOffset; + ea->batch.used = used; +#if 0 /* ZZZ JB: no cliprects used */ + ea->batch.cliprects = intel->pClipRects; + ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); +#else + ea->batch.cliprects = NULL; + ea->batch.num_cliprects = 0; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0; +#endif + ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; + ea->ops_list = (unsigned long) first; + first->reloc_ptr = (unsigned long) batch->reloc; + batch->reloc[0] = batch->nr_relocs; + + //return -EFAULT; + do { + ret = drmCommandWriteRead(intel_screen->device->drmFD, DRM_I915_EXECBUFFER, ea, + sizeof(*ea)); + } while (ret == -EAGAIN); + + if (ret != 0) { + printf("%s somebody set us up the bomb\n", __FUNCTION__); + return ret; + } + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + arg = &node->bo_arg; + rep = &arg->d.rep.bo_info; + + if (!arg->handled) { + return -EFAULT; + } + if (arg->d.rep.ret) + return arg->d.rep.ret; + + buf = node->buf; + i915_drm_copy_reply(rep, buf); + } + return 0; +} + +/* TODO: Push this whole function into bufmgr. + */ +static struct _DriFenceObject * +do_flush_locked(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + struct intel_screen *intel_screen = batch->intel_screen; + struct _DriFenceObject *fo; + drmFence fence; + drmBOList *boList; + struct drm_i915_execbuffer ea; + int ret = 0; + + driBOValidateUserList(batch->list); + boList = driGetdrmBOList(batch->list); + +#if 0 /* ZZZ JB Allways run */ + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { +#else + if (1) { +#endif + ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); + } else { + driPutdrmBOList(batch->list); + fo = NULL; + goto out; + } + driPutdrmBOList(batch->list); + if (ret) + abort(); + + if (ea.fence_arg.error != 0) { + + /* + * The hardware has been idled by the kernel. + * Don't fence the driBOs. + */ + + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); +#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ + _mesa_printf("fence error\n"); +#endif + batch->last_fence = NULL; + fo = NULL; + goto out; + } + + fence.handle = ea.fence_arg.handle; + fence.fence_class = ea.fence_arg.fence_class; + fence.type = ea.fence_arg.type; + fence.flags = ea.fence_arg.flags; + fence.signaled = ea.fence_arg.signaled; + + fo = driBOFenceUserList(intel_screen->mgr, batch->list, + "SuperFence", &fence); + + if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); + /* + * FIXME: Context last fence?? + */ + batch->last_fence = fo; + driFenceReference(fo); + } + out: +#if 0 /* ZZZ JB: fix this */ + intel->vtbl.lost_hardware(intel); +#else +#endif + return fo; +} + + +struct _DriFenceObject * +intel_batchbuffer_flush(struct intel_batchbuffer *batch) +{ + //struct intel_context *intel = batch->intel; + GLuint used = batch->ptr - batch->map; + //GLboolean was_locked = 1; + struct _DriFenceObject *fence; + + if (used == 0) { + driFenceReference(batch->last_fence); + return batch->last_fence; + } + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ +#if 0 /* ZZZ JB: what should we do here? */ + if (used & 4) { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } +#else + if (used & 4) { + ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 8; + } +#endif + driBOUnmap(batch->buffer); + batch->ptr = NULL; + batch->map = NULL; + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ +/* if (!was_locked) + LOCK_HARDWARE(intel);*/ + + fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + GL_FALSE); + +/* if (!was_locked) + UNLOCK_HARDWARE(intel);*/ + + /* Reset the buffer: + */ + intel_batchbuffer_reset(batch); + return fence; +} + +void +intel_batchbuffer_finish(struct intel_batchbuffer *batch) +{ + struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); + driFenceFinish(fence, driFenceType(fence), GL_FALSE); + driFenceUnReference(&fence); +} + +void +intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h new file mode 100644 index 0000000000..6d35cf8b96 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h @@ -0,0 +1,133 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "mtypes.h" +#include "ws_dri_bufmgr.h" + +struct intel_screen; + +#define BATCH_SZ 16384 +#define BATCH_RESERVED 16 + +#define INTEL_DEFAULT_RELOCS 100 +#define INTEL_MAX_RELOCS 400 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct intel_batchbuffer +{ + struct bufmgr *bm; + struct intel_screen *intel_screen; + + struct _DriBufferObject *buffer; + struct _DriFenceObject *last_fence; + GLuint flags; + + struct _DriBufferList *list; + GLuint list_count; + GLubyte *map; + GLubyte *ptr; + + uint32_t *reloc; + GLuint reloc_size; + GLuint nr_relocs; + + GLuint size; + + GLuint dirty_state; + GLuint id; + + uint32_t poolOffset; + uint8_t *drmBOVirtual; + struct _drmBONode *node; /* Validation list node for this buffer */ + int dest_location; /* Validation list sequence for this buffer */ +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_screen + *intel); + +void intel_batchbuffer_free(struct intel_batchbuffer *batch); + + +void intel_batchbuffer_finish(struct intel_batchbuffer *batch); + +struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer + *batch); + +void intel_batchbuffer_reset(struct intel_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags); + +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + GLuint bytes); + +void +intel_offset_relocation(struct intel_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE GLuint +intel_batchbuffer_space(struct intel_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(GLuint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + GLuint sz, GLuint flags) +{ + struct _DriFenceObject *fence; + + assert(sz < batch->size - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) { + fence = intel_batchbuffer_flush(batch); + driFenceUnReference(&fence); + } + + batch->flags |= flags; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, flags) do { \ + assert(!intel->prim.flush); \ + intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ +} while (0) + +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf,flags,mask,delta) do { \ + assert((delta) >= 0); \ + intel_offset_relocation(intel->batch, delta, buf, flags, mask); \ +} while (0) + +#define ADVANCE_BATCH() do { } while(0) + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c new file mode 100644 index 0000000000..394a40d714 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -0,0 +1,366 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" +#include "intel_winsys.h" +#include "intel_batchbuffer.h" + +#include "state_tracker/st_public.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "intel_egl.h" +#include "utils.h" + +#ifdef DEBUG +int __intel_debug = 0; +#endif + + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +/** + * Extension strings exported by the intel driver. + * + * \note + * It appears that ARB_texture_env_crossbar has "disappeared" compared to the + * old i830-specific driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, + {"GL_SGIS_generate_mipmap", NULL }, + {NULL, NULL} +}; + +int +intel_create_context(struct egl_drm_context *eglCon, const __GLcontextModes *visual, void *sharedContextPrivate) +{ + struct intel_context *iCon = CALLOC_STRUCT(intel_context); + struct intel_screen *iScrn = (struct intel_screen *)eglCon->device->priv; + struct pipe_context *pipe; + struct st_context *st_share = NULL; + + eglCon->priv = iCon; + + iCon->intel_screen = iScrn; + iCon->egl_context = eglCon; + iCon->egl_device = eglCon->device; + + iCon->batch = intel_batchbuffer_alloc(iScrn); + iCon->last_swap_fence = NULL; + iCon->first_swap_fence = NULL; + + pipe = intel_create_i915simple(iCon, iScrn->winsys); +// pipe = intel_create_softpipe(iCon, iScrn->winsys); + + pipe->priv = iCon; + + iCon->st = st_create_context(pipe, visual, st_share); + return TRUE; +} + +void +intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read) +{ + if (context) { + struct intel_context *intel = (struct intel_context *)context->priv; + struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; + struct intel_framebuffer *read_fb = (struct intel_framebuffer *)read->priv; + + assert(draw_fb->stfb); + assert(read_fb->stfb); + + st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); + + intel->egl_drawable = draw; + + st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); + + if (draw != read) + st_resize_framebuffer(read_fb->stfb, read->w, read->h); + + //intelUpdateWindowSize(driDrawPriv); + } else { + st_make_current(NULL, NULL, NULL); + } +} + +void +intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) +{ + struct intel_screen *intelScreen = (struct intel_screen *)draw->device->priv; + struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; + + driBOUnReference(draw_fb->front_buffer); + draw_fb->front_buffer = NULL; + draw_fb->front = NULL; + + /* to unbind just call this function with front == NULL */ + if (!front) + return; + + draw_fb->front = front; + + driGenBuffers(intelScreen->staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); + driBOSetReferenced(draw_fb->front_buffer, front->handle); + + st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); +} + +#if 0 +GLboolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct intel_context *intel = CALLOC_STRUCT(intel_context); + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *saPriv = intelScreen->sarea; + int fthrottle_mode; + GLboolean havePools; + struct pipe_context *pipe; + struct st_context *st_share = NULL; + + if (sharedContextPrivate) { + st_share = ((struct intel_context *) sharedContextPrivate)->st; + } + + driContextPriv->driverPrivate = intel; + intel->intelScreen = intelScreen; + intel->driScreen = sPriv; + intel->sarea = saPriv; + + driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i915"); + + + /* + * memory pools + */ + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + // ZZZ JB should be per screen and not be done per context + havePools = intelCreatePools(sPriv); + DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + if (!havePools) + return GL_FALSE; + + + /* Dri stuff */ + intel->hHWContext = driContextPriv->hHWContext; + intel->driFd = sPriv->fd; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + + fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); + intel->iw.irq_seq = -1; + intel->irqsEmitted = 0; + + intel->batch = intel_batchbuffer_alloc(intel); + intel->last_swap_fence = NULL; + intel->first_swap_fence = NULL; + +#ifdef DEBUG + __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); +#endif + + /* + * Pipe-related setup + */ + if (getenv("INTEL_SP")) { + /* use softpipe driver instead of hw */ + pipe = intel_create_softpipe( intel, intelScreen->winsys ); + } + else { + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q33_G: + case PCI_CHIP_Q35_G: + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + pipe = intel_create_i915simple( intel, intelScreen->winsys ); + break; + default: + fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", + intel->intelScreen->deviceID, __FUNCTION__); + + pipe = intel_create_softpipe( intel, intelScreen->winsys ); + break; + } + } + + pipe->priv = intel; + + intel->st = st_create_context(pipe, visual, st_share); + + return GL_TRUE; +} + + +void +intelDestroyContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + + assert(intel); /* should never be null */ + if (intel) { + st_finish(intel->st); + + intel_batchbuffer_free(intel->batch); + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + if (intel->first_swap_fence) { + driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = NULL; + } + + if (intel->intelScreen->dummyContext == intel) + intel->intelScreen->dummyContext = NULL; + + st_destroy_context(intel->st); + free(intel); + } +} + + +GLboolean +intelUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); + /* XXX make_current(NULL)? */ + return GL_TRUE; +} + + +GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + if (driContextPriv) { + struct intel_context *intel = intel_context(driContextPriv); + struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv); + struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv); + + assert(draw_fb->stfb); + assert(read_fb->stfb); + + /* This is for situations in which we need a rendering context but + * there may not be any currently bound. + */ + intel->intelScreen->dummyContext = intel; + + st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); + + if ((intel->driDrawable != driDrawPriv) || + (intel->lastStamp != driDrawPriv->lastStamp)) { + intel->driDrawable = driDrawPriv; + intelUpdateWindowSize(driDrawPriv); + intel->lastStamp = driDrawPriv->lastStamp; + } + + /* The size of the draw buffer will have been updated above. + * If the readbuffer is a different window, check/update its size now. + */ + if (driReadPriv != driDrawPriv) { + intelUpdateWindowSize(driReadPriv); + } + + } + else { + st_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h new file mode 100644 index 0000000000..aa9903f274 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -0,0 +1,162 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_CONTEXT_H +#define INTEL_CONTEXT_H + +#include +#include "drm.h" + +#include "pipe/p_debug.h" + +#include "intel_screen.h" +#include "i915_drm.h" + + +struct pipe_context; +struct intel_context; +struct _DriBufferObject; +struct st_context; +struct egl_drm_device; +struct egl_drm_context; +struct egl_drm_frontbuffer; + + +#define INTEL_MAX_FIXUP 64 + +/** + * Intel rendering context, contains a state tracker and intel-specific info. + */ +struct intel_context +{ + struct st_context *st; + + struct _DriFenceObject *last_swap_fence; + struct _DriFenceObject *first_swap_fence; + + struct intel_batchbuffer *batch; + +#if 0 + boolean locked; + char *prevLockFile; + int prevLockLine; +#endif + + /* pick this up from the screen instead + int drmFd; + */ + + struct intel_screen *intel_screen; + + uint lastStamp; + /* new egl stuff */ + struct egl_drm_device *egl_device; + struct egl_drm_context *egl_context; + struct egl_drm_drawable *egl_drawable; +}; + + + +/** + * Intel framebuffer. + */ +struct intel_framebuffer +{ + struct st_framebuffer *stfb; + + /* other fields TBD */ + int other; + struct _DriBufferObject *front_buffer; + struct egl_drm_frontbuffer *front; +}; + + + + +/* These are functions now: + */ +void LOCK_HARDWARE( struct intel_context *intel ); +void UNLOCK_HARDWARE( struct intel_context *intel ); + +extern char *__progname; + + + +/* ================================================================ + * Debugging: + */ +#ifdef DEBUG +extern int __intel_debug; + +#define DEBUG_SWAP 0x1 +#define DEBUG_LOCK 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BATCH 0x8 + +#define DBG(flag, ...) do { \ + if (__intel_debug & (DEBUG_##flag)) \ + printf(__VA_ARGS__); \ +} while(0) + +#else +#define DBG(flag, ...) +#endif + + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_Q33_G 0x29D2 + + +#if 0 +/** Cast wrapper */ +static INLINE struct intel_context * +intel_context(__DRIcontextPrivate *driContextPriv) +{ + return (struct intel_context *) driContextPriv->driverPrivate; +} + + +/** Cast wrapper */ +static INLINE struct intel_framebuffer * +intel_framebuffer(__DRIdrawablePrivate * driDrawPriv) +{ + return (struct intel_framebuffer *) driDrawPriv->driverPrivate; +} +#endif + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c new file mode 100644 index 0000000000..a9c0218455 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -0,0 +1,605 @@ + +#include +#include +#include +#include + +#include "eglconfig.h" +#include "eglcontext.h" +#include "egldisplay.h" +#include "egldriver.h" +#include "eglglobals.h" +#include "eglmode.h" +#include "eglscreen.h" +#include "eglsurface.h" + +#include "glapi.h" +#include "intel_egl.h" + +#include "xf86drm.h" +#include "xf86drmMode.h" + +#include "intel_context.h" + +#include "ws_dri_bufmgr.h" + +#include "intel_winsys.h" +#include "state_tracker/st_public.h" + +struct egl_drm_device* egl_drm_create_device(int drmFD); + +struct egl_drm_device* +egl_drm_create_device(int drmFD) +{ + struct egl_drm_device *device = malloc(sizeof(*device)); + memset(device, 0, sizeof(*device)); + device->drmFD = drmFD; + + if (!intel_init_driver(device)) { + printf("EGL: failed to initalize device\n"); + free(device); + } + + return device; +} + +__GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size ); + +struct drm_driver +{ + _EGLDriver base; /* base class/object */ + + drmModeResPtr res; + struct egl_drm_device *device; +}; + +struct drm_surface +{ + _EGLSurface base; /* base class/object */ + + struct egl_drm_drawable *drawable; +}; + +struct drm_context +{ + _EGLContext base; /* base class/object */ + + struct egl_drm_context *context; +}; + +struct drm_screen +{ + _EGLScreen base; + + /* backing buffer and crtc */ + drmBO buffer; + drmModeFBPtr fb; + uint32_t fbID; + drmModeCrtcPtr crtc; + + /* currently only support one output */ + drmModeOutputPtr output; + uint32_t outputID; + + struct drm_mode_modeinfo *mode; + + /* geometry of the screen */ + struct egl_drm_frontbuffer front; +}; + +static void +drm_update_res(struct drm_driver *drm_drv) +{ + drmModeFreeResources(drm_drv->res); + drm_drv->res = drmModeGetResources(drm_drv->device->drmFD); +} + +static EGLBoolean +drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) +{ + _EGLDisplay *disp = _eglLookupDisplay(dpy); + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_screen *screen = NULL; + drmModeOutputPtr output = NULL; + drmModeResPtr res = NULL; + + EGLint i; + int fd; + + fd = drmOpen("i915", NULL); + if (fd < 0) { + return EGL_FALSE; + } + + drm_drv->device = egl_drm_create_device(fd); + if (!drm_drv->device) { + drmClose(fd); + return EGL_FALSE; + } + + drm_update_res(drm_drv); + res = drm_drv->res; + + for(i = 0; i < res->count_outputs; i++) { + output = drmModeGetOutput(fd, res->outputs[i]); + + if (!output) + continue; + + if (output->connection == DRM_MODE_DISCONNECTED) { + drmModeFreeOutput(output); + continue; + } + + screen = malloc(sizeof(struct drm_screen)); + memset(screen, 0, sizeof(*screen)); + screen->outputID = res->outputs[i]; + screen->output = output; + _eglInitScreen(&screen->base); + _eglAddScreen(disp, &screen->base); + _eglAddNewMode(&screen->base, 1024, 768, 60 * 1000, "1024x768-60"); + } + + /* for now we only have one config */ + _EGLConfig config; + _eglInitConfig(&config, i + 1); + _eglSetConfigAttrib(&config, EGL_RED_SIZE, 8); + _eglSetConfigAttrib(&config, EGL_GREEN_SIZE, 8); + _eglSetConfigAttrib(&config, EGL_BLUE_SIZE, 8); + _eglSetConfigAttrib(&config, EGL_ALPHA_SIZE, 8); + _eglSetConfigAttrib(&config, EGL_BUFFER_SIZE, 32); + _eglSetConfigAttrib(&config, EGL_DEPTH_SIZE, 24); + _eglSetConfigAttrib(&config, EGL_STENCIL_SIZE, 8); + _eglSetConfigAttrib(&config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); + _eglAddConfig(disp, &config); + + drv->Initialized = EGL_TRUE; + + *major = 1; + *minor = 0; + + return EGL_TRUE; +} + + +static EGLBoolean +drm_terminate(_EGLDriver *drv, EGLDisplay dpy) +{ + /* TODO: clean up */ + free(drv); + return EGL_TRUE; +} + + +static struct drm_context * +lookup_drm_context(EGLContext context) +{ + _EGLContext *c = _eglLookupContext(context); + return (struct drm_context *) c; +} + + +static struct drm_surface * +lookup_drm_surface(EGLSurface surface) +{ + _EGLSurface *s = _eglLookupSurface(surface); + return (struct drm_surface *) s; +} + +static struct drm_screen * +lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen) +{ + _EGLScreen *s = _eglLookupScreen(dpy, screen); + return (struct drm_screen *) s; +} + +static __GLcontextModes* +visual_from_config(_EGLConfig *conf) +{ + __GLcontextModes *visual; + (void)conf; + + visual = _gl_context_modes_create(1, sizeof(*visual)); + visual->redBits = 8; + visual->greenBits = 8; + visual->blueBits = 8; + visual->alphaBits = 8; + + visual->rgbBits = 32; + visual->doubleBufferMode = 1; + + visual->depthBits = 24; + visual->stencilBits = 8; + + return visual; +} + + + +static EGLContext +drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_context *c; + struct drm_egl_context *share = NULL; + _EGLConfig *conf; + int i; + int ret; + __GLcontextModes *visual; + struct egl_drm_context *context; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreateContext"); + return EGL_NO_CONTEXT; + } + + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + /* no attribs defined for now */ + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); + return EGL_NO_CONTEXT; + } + } + + c = (struct drm_context *) calloc(1, sizeof(struct drm_context)); + if (!c) + return EGL_NO_CONTEXT; + + _eglInitContext(drv, dpy, &c->base, config, attrib_list); + + context = malloc(sizeof(*context)); + memset(context, 0, sizeof(*context)); + + if (!context) + goto err_c; + + context->device = drm_drv->device; + visual = visual_from_config(conf); + + ret = intel_create_context(context, visual, share); + free(visual); + + if (!ret) + goto err_gl; + + c->context = context; + + /* generate handle and insert into hash table */ + _eglSaveContext(&c->base); + assert(c->base.Handle); + + return c->base.Handle; +err_gl: + free(context); +err_c: + free(c); + return EGL_NO_CONTEXT; +} + +static EGLBoolean +drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) +{ + struct drm_context *fc = lookup_drm_context(context); + _eglRemoveContext(&fc->base); + if (fc->base.IsBound) { + fc->base.DeletePending = EGL_TRUE; + } else { + free(fc); + } + return EGL_TRUE; +} + + +static EGLSurface +drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) +{ + return EGL_NO_SURFACE; +} + + +static EGLSurface +drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) +{ + return EGL_NO_SURFACE; +} + +static EGLSurface +drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + const EGLint *attrib_list) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + int i; + int ret; + int width = -1; + int height = -1; + struct drm_surface *surf = NULL; + struct egl_drm_drawable *drawable = NULL; + __GLcontextModes *visual; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface"); + return EGL_NO_CONTEXT; + } + + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + case EGL_WIDTH: + width = attrib_list[++i]; + break; + case EGL_HEIGHT: + height = attrib_list[++i]; + break; + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } + } + + if (width < 1 || height < 1) { + _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } + + surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface)); + if (!surf) + goto err; + + if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list)) + goto err_surf; + + drawable = malloc(sizeof(*drawable)); + memset(drawable, 0, sizeof(*drawable)); + + drawable->w = width; + drawable->h = height; + + visual = visual_from_config(conf); + + drawable->device = drm_drv->device; + ret = intel_create_drawable(drawable, visual); + free(visual); + + if (!ret) + goto err_draw; + + surf->drawable = drawable; + + _eglSaveSurface(&surf->base); + return surf->base.Handle; + +err_draw: + free(drawable); +err_surf: + free(surf); +err: + return EGL_NO_SURFACE; +} + +static EGLSurface +drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, + const EGLint *attrib_list) +{ + EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list); + + return surf; +} + +static struct drm_mode_modeinfo * +drm_find_mode(drmModeOutputPtr output, _EGLMode *mode) +{ + int i; + struct drm_mode_modeinfo *m; + + for (i = 0; i < output->count_modes; i++) { + m = &output->modes[i]; + if (m->hdisplay == mode->Width && m->vdisplay == mode->Height) + break; + m = NULL; + } + + return m; +} +static void +draw(size_t x, size_t y, size_t w, size_t h, size_t pitch, size_t v, unsigned int *ptr) +{ + int i, j; + + for (i = x; i < x + w; i++) + for(j = y; j < y + h; j++) + ptr[(i * pitch / 4) + j] = v; + +} + +static void +prettyColors(int fd, unsigned int handle, size_t pitch) +{ + drmBO bo; + unsigned int *ptr; + int i; + + drmBOReference(fd, handle, &bo); + drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void**)&ptr); + + for (i = 0; i < (bo.size / 4); i++) + ptr[i] = 0xFFFFFFFF; + + for (i = 0; i < 4; i++) + draw(i * 40, i * 40, 40, 40, pitch, 0, ptr); + + + draw(200, 100, 40, 40, pitch, 0xff00ff, ptr); + draw(100, 200, 40, 40, pitch, 0xff00ff, ptr); + + drmBOUnmap(fd, &bo); +} + +static EGLBoolean +drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, + EGLScreenMESA screen, + EGLSurface surface, EGLModeMESA m) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_surface *surf = lookup_drm_surface(surface); + struct drm_screen *scrn = lookup_drm_screen(dpy, screen); + //struct intel_framebuffer *intel_fb = NULL; + //struct pipe_surface *front_surf = NULL; + _EGLMode *mode = _eglLookupMode(dpy, m); + size_t pitch = 2048 * 4; + size_t size = mode->Height * pitch; + int ret; + + /* TODO if allready shown take down */ + + printf("setting mode to %i x %i\n", mode->Width, mode->Height); + + ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_NO_EVICT, + DRM_BO_HINT_DONT_FENCE, &scrn->buffer); + + prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); + if (ret) { + printf("failed to create framebuffer (ret %d)\n", ret); + return EGL_FALSE; + } + + ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height, + 32, 32, pitch, + scrn->buffer.handle, + &scrn->fbID); + + if (ret) + goto err_bo; + + scrn->fb = drmModeGetFB(drm_drv->device->drmFD, scrn->fbID); + if (!scrn->fb) + goto err_bo; + + scrn->mode = drm_find_mode(scrn->output, mode); + if (!scrn->mode) { + printf("oh noes, no matching mode found\n"); + goto err_fb; + } + + ret = drmModeSetCrtc( + drm_drv->device->drmFD, + drm_drv->res->crtcs[1], + scrn->fbID, + 0, 0, + &scrn->outputID, 1, + scrn->mode); + + + scrn->front.handle = scrn->buffer.handle; + scrn->front.pitch = pitch; + scrn->front.width = mode->Width; + scrn->front.height = mode->Height; + + intel_bind_frontbuffer(surf->drawable, &scrn->front); + + return EGL_TRUE; + +err_fb: + /* TODO remove fb */ + +err_bo: + drmBOUnreference(drm_drv->device->drmFD, &scrn->buffer); + return EGL_FALSE; +} + +static EGLBoolean +drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +{ + struct drm_surface *fs = lookup_drm_surface(surface); + _eglRemoveSurface(&fs->base); + if (fs->base.IsBound) { + fs->base.DeletePending = EGL_TRUE; + } else { + free(fs); + } + return EGL_TRUE; +} + + + + +static EGLBoolean +drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) +{ + struct drm_surface *readSurf = lookup_drm_surface(read); + struct drm_surface *drawSurf = lookup_drm_surface(draw); + struct drm_context *ctx = lookup_drm_context(context); + EGLBoolean b; + + b = _eglMakeCurrent(drv, dpy, draw, read, context); + if (!b) + return EGL_FALSE; + + /* XXX this is where we'd do the hardware context switch */ + (void) drawSurf; + (void) readSurf; + (void) ctx; + + intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); + return EGL_TRUE; +} + +static EGLBoolean +drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) +{ + struct drm_surface *surf = lookup_drm_surface(draw); + if (!surf) + return EGL_FALSE; + + /* error checking */ + if (!_eglSwapBuffers(drv, dpy, draw)) + return EGL_FALSE; + + intel_swap_buffers(surf->drawable); + return EGL_TRUE; +} + + +/** + * The bootstrap function. Return a new drm_driver object and + * plug in API functions. + */ +_EGLDriver * +_eglMain(_EGLDisplay *dpy) +{ + struct drm_driver *drm; + + drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); + if (!drm) { + return NULL; + } + + /* First fill in the dispatch table with defaults */ + _eglInitDriverFallbacks(&drm->base); + /* then plug in our Drm-specific functions */ + drm->base.API.Initialize = drm_initialize; + drm->base.API.Terminate = drm_terminate; + drm->base.API.CreateContext = drm_create_context; + drm->base.API.MakeCurrent = drm_make_current; + drm->base.API.CreateWindowSurface = drm_create_window_surface; + drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface; + drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface; + drm->base.API.DestroySurface = drm_destroy_surface; + drm->base.API.DestroyContext = drm_destroy_context; + drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa; + drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; + drm->base.API.SwapBuffers = drm_swap_buffers; + + /* enable supported extensions */ + drm->base.Extensions.MESA_screen_surface = EGL_TRUE; + drm->base.Extensions.MESA_copy_context = EGL_TRUE; + + return &drm->base; +} diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h new file mode 100644 index 0000000000..18e84e8eea --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.h @@ -0,0 +1,42 @@ + +#ifndef _INTEL_EGL_H_ +#define _INTEL_EGL_H_ + +struct egl_drm_device +{ + void *priv; + int drmFD; +}; + +struct egl_drm_context +{ + void *priv; + struct egl_drm_device *device; +}; + +struct egl_drm_drawable +{ + void *priv; + struct egl_drm_device *device; + size_t h; + size_t w; +}; + +struct egl_drm_frontbuffer +{ + uint32_t handle; + uint32_t pitch; + uint32_t width; + uint32_t height; +}; + +#include "GL/internal/glcore.h" + +int intel_init_driver(struct egl_drm_device *device); +int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate); +int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual); +void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read); +void intel_swap_buffers(struct egl_drm_drawable *draw); +void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front); + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_lock.c b/src/gallium/winsys/egl_drm/intel/intel_lock.c new file mode 100644 index 0000000000..cec83c7585 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_lock.c @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "main/glheader.h" +#include "glapi/glthread.h" +#include +#include "state_tracker/st_public.h" +#include "intel_context.h" + +#if 0 + +_glthread_DECLARE_STATIC_MUTEX( lockMutex ); + + +static void +intelContendedLock(struct intel_context *intel, uint flags) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIscreenPrivate *sPriv = intel->driScreen; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *sarea = intel->sarea; + + drmGetLock(intel->driFd, intel->hHWContext, flags); + + DBG(LOCK, "%s - got contended lock\n", __progname); + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + if (dPriv) + DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + + if (sarea->width != intelScreen->front.width || + sarea->height != intelScreen->front.height) { + + intelUpdateScreenRotation(sPriv, sarea); + } +} + + +/* Lock the hardware and validate our state. + */ +void LOCK_HARDWARE( struct intel_context *intel ) +{ + char __ret = 0; + + _glthread_LOCK_MUTEX(lockMutex); + assert(!intel->locked); + + DRM_CAS(intel->driHwLock, intel->hHWContext, + (DRM_LOCK_HELD|intel->hHWContext), __ret); + + if (__ret) + intelContendedLock( intel, 0 ); + + DBG(LOCK, "%s - locked\n", __progname); + + intel->locked = 1; +} + + +/* Unlock the hardware using the global current context + */ +void UNLOCK_HARDWARE( struct intel_context *intel ) +{ + assert(intel->locked); + intel->locked = 0; + + DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); + + _glthread_UNLOCK_MUTEX(lockMutex); + + DBG(LOCK, "%s - unlocked\n", __progname); +} +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_reg.h b/src/gallium/winsys/egl_drm/intel/intel_reg.h new file mode 100644 index 0000000000..f37c24fda9 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_reg.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef _INTEL_REG_H_ +#define _INTEL_REG_H_ + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + +#define MI_BATCH_BUFFER_END (0xA<<23) + + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c new file mode 100644 index 0000000000..38c4098087 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.c @@ -0,0 +1,680 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "utils.h" +#include "vblank.h" +#include "xmlpool.h" + +#include "intel_context.h" +#include "intel_screen.h" +#include "intel_batchbuffer.h" +//#include "intel_batchpool.h" +#include "intel_swapbuffers.h" +#include "intel_winsys.h" + +#include "ws_dri_bufpool.h" + +#include "pipe/p_context.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_cb_fbo.h" +#include "intel_egl.h" + +static boolean +intel_create_pools(struct intel_screen *intel_screen) +{ + if (intel_screen->havePools) + return GL_TRUE; + + intel_screen->mgr = driFenceMgrTTMInit(intel_screen->device->drmFD); + if (!intel_screen->mgr) { + fprintf(stderr, "Failed to create fence manager.\n"); + return FALSE; + } + + intel_screen->fMan = driInitFreeSlabManager(10, 10); + if (!intel_screen->fMan) { + fprintf(stderr, "Failed to create free slab manager.\n"); + return FALSE; + } + + intel_screen->staticPool = driDRMPoolInit(intel_screen->device->drmFD); + intel_screen->batchPool = driSlabPoolInit(intel_screen->device->drmFD, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + 4096, //intelScreen->maxBatchSize, + 1, 40, 16*16384, 0, + intel_screen->fMan); + + intel_screen->havePools = GL_TRUE; + + return GL_TRUE; +} + +extern const struct dri_extension card_extensions[]; + +int +intel_init_driver(struct egl_drm_device *device) +{ + struct intel_screen *intel_screen; + + /* Allocate the private area */ + intel_screen = CALLOC_STRUCT(intel_screen); + if (!intel_screen) + return FALSE; + + device->priv = (void *)intel_screen; + intel_screen->device = device; + + if (!intel_create_pools(intel_screen)) + return FALSE; + + intel_screen->batch = intel_batchbuffer_alloc(intel_screen); + + intel_screen->winsys = intel_create_pipe_winsys(device->drmFD, intel_screen->fMan); + + /* hack */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + + return TRUE; +} + +int +intel_create_drawable(struct egl_drm_drawable *drawable, + const __GLcontextModes * visual) +{ + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + drawable->w, + drawable->h, + (void*) intelfb); + + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + drawable->priv = (void *) intelfb; + return GL_TRUE; +} + +#if 0 +PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY + DRI_CONF_FORCE_S3TC_ENABLE(false) + DRI_CONF_ALLOW_LARGE_TEXTURES(1) + DRI_CONF_SECTION_END DRI_CONF_END; + +const uint __driNConfigOptions = 4; + +#ifdef USE_NEW_INTERFACE +static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; +#endif /*USE_NEW_INTERFACE */ + +extern const struct dri_extension card_extensions[]; + + + + +static void +intelPrintDRIInfo(struct intel_screen * intelScreen, + __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) +{ + fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->front.size, intelScreen->front.offset, + intelScreen->front.pitch); + fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); +} + +static void +intelPrintSAREA(const drmI830Sarea * sarea) +{ + fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, + sarea->height); + fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); + fprintf(stderr, + "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->front_offset, sarea->front_size, + (unsigned) sarea->front_handle); + fprintf(stderr, + "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->back_offset, sarea->back_size, + (unsigned) sarea->back_handle); + fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->depth_offset, sarea->depth_size, + (unsigned) sarea->depth_handle); + fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); + fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); + fprintf(stderr, + "SAREA: rotated offset: 0x%08x size: 0x%x\n", + sarea->rotated_offset, sarea->rotated_size); + fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); +} + +/** + * Use the information in the sarea to update the screen parameters + * related to screen rotation. Needs to be called locked. + */ +void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->front.map) { + drmUnmap(intelScreen->front.map, intelScreen->front.size); + intelScreen->front.map = NULL; + } + + if (intelScreen->front.buffer) + driDeleteBuffers(1, &intelScreen->front.buffer); + + intelScreen->front.width = sarea->width; + intelScreen->front.height = sarea->height; + intelScreen->front.offset = sarea->front_offset; + intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp; + intelScreen->front.size = sarea->front_size; + intelScreen->front.handle = sarea->front_handle; + + assert( sarea->front_size >= + intelScreen->front.pitch * intelScreen->front.height ); + +#if 0 /* JB not important */ + if (!sarea->front_handle) + return; + + if (drmMap(sPriv->fd, + sarea->front_handle, + intelScreen->front.size, + (drmAddress *) & intelScreen->front.map) != 0) { + fprintf(stderr, "drmMap(frontbuffer) failed!\n"); + return; + } +#endif + +#if 0 /* JB */ + if (intelScreen->staticPool) { + driGenBuffers(intelScreen->staticPool, "static region", 1, + &intelScreen->front.buffer, 64, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + + driBOSetStatic(intelScreen->front.buffer, + intelScreen->front.offset, + intelScreen->front.pitch * intelScreen->front.height, + intelScreen->front.map, 0); + } +#else + if (intelScreen->staticPool) { + if (intelScreen->front.buffer) + driBOUnReference(intelScreen->front.buffer); + driGenBuffers(intelScreen->staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle); + } +#endif +} + + +boolean +intelCreatePools(__DRIscreenPrivate * sPriv) +{ + //unsigned batchPoolSize = 1024*1024; + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->havePools) + return GL_TRUE; + +#if 0 /* ZZZ JB fix this */ + intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); + if (!intelScreen->staticPool) + return GL_FALSE; + + batchPoolSize /= BATCH_SZ; + intelScreen->batchPool = driBatchPoolInit(sPriv->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_LOCAL, + BATCH_SZ, + batchPoolSize, 5); + if (!intelScreen->batchPool) { + fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); + return GL_FALSE; + } +#else + intelScreen->staticPool = driDRMPoolInit(sPriv->fd); + intelScreen->batchPool = driSlabPoolInit(sPriv->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + 4096, //intelScreen->maxBatchSize, + 1, 40, 16*16384, 0, + intelScreen->fMan); +#endif + intelScreen->havePools = GL_TRUE; + + //intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + return GL_TRUE; +} + + +static boolean +intelInitDriver(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen; + I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; + + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> + getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; + + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { + fprintf(stderr, + "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + + /* Allocate the private area */ + intelScreen = CALLOC_STRUCT(intel_screen); + if (!intelScreen) + return GL_FALSE; + + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + sPriv->private = (void *) intelScreen; + + intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + + gDRIPriv->sarea_priv_offset); + intelScreen->deviceID = gDRIPriv->deviceID; + intelScreen->front.cpp = gDRIPriv->cpp; + intelScreen->drmMinor = sPriv->drmMinor; + + + assert(gDRIPriv->bitsPerPixel == 16 || + gDRIPriv->bitsPerPixel == 32); + + + intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + if (0) + intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); + + if (glx_enable_extension != NULL) { + (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); + (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); + (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); + } + + + +#if 1 // ZZZ JB + intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd); + if (!intelScreen->mgr) { + fprintf(stderr, "Failed to create fence manager.\n"); + return GL_FALSE; + } + + intelScreen->fMan = driInitFreeSlabManager(10, 10); + if (!intelScreen->fMan) { + fprintf(stderr, "Failed to create free slab manager.\n"); + return GL_FALSE; + } + + if (!intelCreatePools(sPriv)) + return GL_FALSE; +#endif + + intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd, intelScreen->fMan); + + return GL_TRUE; +} + + +static void +intelDestroyScreen(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + /* intelUnmapScreenRegions(intelScreen); */ + + if (intelScreen->havePools) { + driPoolTakeDown(intelScreen->staticPool); + driPoolTakeDown(intelScreen->batchPool); + } + FREE(intelScreen); + sPriv->private = NULL; +} + + +/** + * This is called when we need to set up GL rendering to a new X window. + */ +static boolean +intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + const __GLcontextModes * visual, boolean isPixmap) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + driDrawPriv->w, + driDrawPriv->h, + (void*) intelfb); + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + driDrawPriv->driverPrivate = (void *) intelfb; + return GL_TRUE; + } +} + +static void +intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv); + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); +} + + +/** + * Get information about previous buffer swaps. + */ +static int +intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) +{ + if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) + || (sInfo == NULL)) { + return -1; + } + + return 0; +} + + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +static const struct __DriverAPIRec intelAPI = { + .InitDriver = intelInitDriver, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = intelCopySubBuffer, + .setTexOffset = intelSetTexOffset, +}; + + +static __GLcontextModes * +intelFillInModes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, boolean have_back_buffer) +{ + __GLcontextModes *modes; + __GLcontextModes *m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[3]; + u_int8_t stencil_bits_array[3]; + + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + depth_bits_array[2] = depth_bits; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. It will be a sw fallback, but some apps won't + * care about that. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = 0; + if (depth_bits == 24) + stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; + + stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + if (pixel_bits == 16) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + modes = + (*dri_interface->createContextModes) (num_modes, + sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for (m = modes; m != NULL; m = m->next) { + if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, + __DRIscreen * psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 7, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 7, 0 }; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("i915", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &intelAPI); + + if (psp != NULL) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create + * is called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + } + + return (void *) psp; +} +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_screen.h new file mode 100644 index 0000000000..e8c1cdfca4 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.h @@ -0,0 +1,133 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _INTEL_SCREEN_H_ +#define _INTEL_SCREEN_H_ + +#include "ws_dri_bufpool.h" + +#include "pipe/p_compiler.h" + +struct egl_drm_device *device; + +struct intel_screen +{ +#if 0 + struct { + drm_handle_t handle; + + /* We create a static dri buffer for the frontbuffer. + */ + struct _DriBufferObject *buffer; + + char *map; /* memory map */ + int offset; /* from start of video mem, in bytes */ + int pitch; /* row stride, in bytes */ + int width; + int height; + int size; + int cpp; /* for front and back buffers */ + } front; +#endif + + int drmFB; + +#if 0 + int deviceID; + int drmMinor; + + + drmI830Sarea *sarea;*/ + + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; +#endif + + struct _DriBufferPool *batchPool; + struct _DriBufferPool *staticPool; /** for the X screen/framebuffer */ + boolean havePools; + +#if 0 + /** + * Temporary(?) context to use for SwapBuffers or other situations in + * which we need a rendering context, but none is currently bound. + */ + struct intel_context *dummyContext; +#endif + + /* + * New stuff form the i915tex integration + */ + struct _DriFenceMgr *mgr; + struct _DriFreeSlabManager *fMan; + unsigned batch_id; + + struct pipe_winsys *winsys; + struct egl_drm_device *device; + + /* batch buffer used for swap buffers */ + struct intel_batchbuffer *batch; +}; + + + +/** cast wrapper */ +#if 0 +static INLINE struct intel_screen * +intel_screen(__DRIscreenPrivate *sPriv) +{ + return (struct intel_screen *) sPriv->private; +} + + +extern void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); + + +extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); + +extern boolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); + +extern boolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + + +extern boolean +intelCreatePools(__DRIscreenPrivate *sPriv); + +extern boolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + +#endif +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c new file mode 100644 index 0000000000..1ce4b2754a --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -0,0 +1,327 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" +#include "intel_winsys.h" + +#include "pipe/p_context.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_fbo.h" +#include "intel_egl.h" + + +static void +intel_display_surface(struct egl_drm_drawable *draw, + struct pipe_surface *surf); + +void intel_swap_buffers(struct egl_drm_drawable *draw) +{ + struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT); + if (back_surf) { + st_notify_swapbuffers(intel_fb->stfb); + intel_display_surface(draw, back_surf); + st_notify_swapbuffers_complete(intel_fb->stfb); + } +} + +static void +intel_display_surface(struct egl_drm_drawable *draw, + struct pipe_surface *surf) +{ + struct intel_screen *intel = (struct intel_screen *)draw->device->priv; + struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; + struct _DriFenceObject *fence; + + //const int srcWidth = surf->width; + //const int srcHeight = surf->height; + const int srcPitch = surf->pitch; + + const int dstWidth = intel_fb->front->width; + const int dstHeight = intel_fb->front->height; + const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp; + + const int cpp = 4;//intel_fb->front->cpp; + + int BR13, CMD; + //int i; + + + BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + + printf("srcPitch: %u, dstWidth: %u, dstHeight: %u, dstPitch: %u, cpp: %u\n", srcPitch, dstWidth, dstHeight, dstPitch, cpp); + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((0 << 16) | 0); + OUT_BATCH((dstHeight << 16) | dstWidth); + + OUT_RELOC(intel_fb->front_buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + + OUT_BATCH((0 << 16) | 0); + OUT_BATCH((srcPitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + ADVANCE_BATCH(); + + fence = intel_batchbuffer_flush(intel->batch); + driFenceUnReference(&fence); + intel_batchbuffer_finish(intel->batch); +} + +#if 0 +/** + * Display a colorbuffer surface in an X window. + * Used for SwapBuffers and flushing front buffer rendering. + * + * \param dPriv the window/drawable to display into + * \param surf the surface to display + * \param rect optional subrect of surface to display (may be NULL). + */ +void +intelDisplaySurface(__DRIdrawablePrivate *dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + //struct intel_context *intel = intelScreen->dummyContext; + + DBG(SWAP, "%s\n", __FUNCTION__); + +#if 0 + if (!intel) { + /* XXX this is where some kind of extra/meta context could be useful */ + return; + } +#endif + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + /* if this drawable isn't currently bound the LOCK_HARDWARE done on the + * current context (which is what intelScreenContext should return) might + * not get a contended lock and thus cliprects not updated (tests/manywin) + */ + if (intel_context(dPriv->driContextPriv) != intel) + DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); + + + if (dPriv && dPriv->numClipRects) { + const int srcWidth = surf->width; + const int srcHeight = surf->height; + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; + const int cpp = intelScreen->front.cpp; + const int srcpitch = surf->pitch; + int BR13, CMD; + int i; + + ASSERT(surf->buffer); + ASSERT(surf->cpp == cpp); + + DBG(SWAP, "screen pitch %d src surface pitch %d\n", + pitch, surf->pitch); + + if (cpp == 2) { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + } + else { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + } + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + drm_clip_rect_t sbox; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->front.width || + pbox->y2 > intelScreen->front.height) { + /* invalid cliprect, skip it */ + continue; + } + + box = *pbox; + + if (rect) { + /* intersect cliprect with user-provided src rect */ + drm_clip_rect_t rrect; + + rrect.x1 = dPriv->x + rect->x1; + rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; + rrect.x2 = rect->x2 + rrect.x1; + rrect.y2 = rect->y2 + rrect.y1; + if (rrect.x1 > box.x1) + box.x1 = rrect.x1; + if (rrect.y1 > box.y1) + box.y1 = rrect.y1; + if (rrect.x2 < box.x2) + box.x2 = rrect.x2; + if (rrect.y2 < box.y2) + box.y2 = rrect.y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + /* restrict blit to size of actually rendered area */ + if (box.x2 - box.x1 > srcWidth) + box.x2 = srcWidth + box.x1; + if (box.y2 - box.y1 > srcHeight) + box.y2 = srcHeight + box.y1; + + DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", + box.x1, box.x2, box.y1, box.y2); + + sbox.x1 = box.x1 - dPriv->x; + sbox.y1 = box.y1 - dPriv->y; + + assert(box.x1 < box.x2); + assert(box.y1 < box.y2); + + /* XXX this could be done with pipe->surface_copy() */ + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((box.y1 << 16) | box.x1); + OUT_BATCH((box.y2 << 16) | box.x2); + + OUT_RELOC(intelScreen->front.buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + OUT_BATCH((sbox.y1 << 16) | sbox.x1); + OUT_BATCH((srcpitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + ADVANCE_BATCH(); + } + + if (intel->first_swap_fence) + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); + } + + UNLOCK_HARDWARE(intel); + + if (intel->lastStamp != dPriv->lastStamp) { + intelUpdateWindowSize(dPriv); + intel->lastStamp = dPriv->lastStamp; + } +} + + + +/** + * This will be called whenever the currently bound window is moved/resized. + */ +void +intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(dPriv); + assert(intelfb->stfb); + st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); +} + + + +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, NULL); + st_notify_swapbuffers_complete(intel_fb->stfb); + } +} + + +/** + * Called via glXCopySubBufferMESA() to copy a subrect of the back + * buffer to the front buffer/screen. + */ +void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + drm_clip_rect_t rect; + rect.x1 = x; + rect.y1 = y; + rect.x2 = w; + rect.y2 = h; + + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, &rect); + } +} +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h new file mode 100644 index 0000000000..904f26732e --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_SWAPBUFFERS_H +#define INTEL_SWAPBUFFERS_H + + +struct pipe_surface; + +#if 0 +extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t * rect); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, + int x, int y, int w, int h); + +extern void intelUpdateWindowSize(__DRIdrawablePrivate *dPriv); +#endif + +#endif /* INTEL_SWAPBUFFERS_H */ diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys.h b/src/gallium/winsys/egl_drm/intel/intel_winsys.h new file mode 100644 index 0000000000..d0a319f9a4 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_winsys.h @@ -0,0 +1,73 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_WINSYS_H +#define INTEL_WINSYS_H + +#include "pipe/p_state.h" + +struct intel_context; +struct pipe_context; +struct pipe_winsys; +struct pipe_buffer; +struct _DriBufferObject; + +struct pipe_winsys * +intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ); + +void +intel_destroy_pipe_winsys( struct pipe_winsys *winsys ); + +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ); + +struct pipe_context * +intel_create_i915simple( struct intel_context *intel, + struct pipe_winsys *winsys ); + + +struct intel_buffer { + struct pipe_buffer base; + struct _DriBufferObject *driBO; +}; + +static INLINE struct intel_buffer * +intel_buffer( struct pipe_buffer *buf ) +{ + return (struct intel_buffer *)buf; +} + +static INLINE struct _DriBufferObject * +dri_bo( struct pipe_buffer *buf ) +{ + return intel_buffer(buf)->driBO; +} + + + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c new file mode 100644 index 0000000000..8ec5c7e82a --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c @@ -0,0 +1,184 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" + +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_winsys.h" + +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "i915simple/i915_winsys.h" +#include "i915simple/i915_screen.h" + + +struct intel_i915_winsys { + struct i915_winsys winsys; /**< batch buffer funcs */ + struct pipe_winsys *pws; + struct intel_context *intel; +}; + + +/* Turn a i915simple winsys into an intel/i915simple winsys: + */ +static inline struct intel_i915_winsys * +intel_i915_winsys( struct i915_winsys *sws ) +{ + return (struct intel_i915_winsys *)sws; +} + + +/* Simple batchbuffer interface: + */ + +static unsigned *intel_i915_batch_start( struct i915_winsys *sws, + unsigned dwords, + unsigned relocs ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + + /* XXX: check relocs. + */ + if (intel_batchbuffer_space( intel->batch ) >= dwords * 4) { + /* XXX: Hmm, the driver can't really do much with this pointer: + */ + return (unsigned *)intel->batch->ptr; + } + else + return NULL; +} + +static void intel_i915_batch_dword( struct i915_winsys *sws, + unsigned dword ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + intel_batchbuffer_emit_dword( intel->batch, dword ); +} + +static void intel_i915_batch_reloc( struct i915_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta ) +{ + struct intel_context *intel = intel_i915_winsys(sws)->intel; + unsigned flags = DRM_BO_FLAG_MEM_TT; + unsigned mask = DRM_BO_MASK_MEM; + + if (access_flags & I915_BUFFER_ACCESS_WRITE) { + flags |= DRM_BO_FLAG_WRITE; + mask |= DRM_BO_FLAG_WRITE; + } + + if (access_flags & I915_BUFFER_ACCESS_READ) { + flags |= DRM_BO_FLAG_READ; + mask |= DRM_BO_FLAG_READ; + } + +#if 0 /* JB old */ + intel_batchbuffer_emit_reloc( intel->batch, + dri_bo( buf ), + flags, mask, + delta ); +#else /* new */ + intel_offset_relocation( intel->batch, + delta, + dri_bo( buf ), + flags, + mask ); +#endif +} + + + +static void intel_i915_batch_flush( struct i915_winsys *sws, + struct pipe_fence_handle **fence ) +{ + struct intel_i915_winsys *iws = intel_i915_winsys(sws); + struct intel_context *intel = iws->intel; + union { + struct _DriFenceObject *dri; + struct pipe_fence_handle *pipe; + } fu; + + if (fence) + assert(!*fence); + + fu.dri = intel_batchbuffer_flush( intel->batch ); + + if (!fu.dri) { + assert(0); + *fence = NULL; + return; + } + + if (fu.dri) { + if (fence) + *fence = fu.pipe; + else + driFenceUnReference(&fu.dri); + } + +} + + +/** + * Create i915 hardware rendering context. + */ +struct pipe_context * +intel_create_i915simple( struct intel_context *intel, + struct pipe_winsys *winsys ) +{ + struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys ); + struct pipe_screen *screen; + + /* Fill in this struct with callbacks that i915simple will need to + * communicate with the window system, buffer manager, etc. + */ + iws->winsys.batch_start = intel_i915_batch_start; + iws->winsys.batch_dword = intel_i915_batch_dword; + iws->winsys.batch_reloc = intel_i915_batch_reloc; + iws->winsys.batch_flush = intel_i915_batch_flush; + iws->pws = winsys; + iws->intel = intel; + + screen = i915_create_screen(winsys, PCI_CHIP_I945_GM); + assert(screen); + + /* Create the i915simple context: + */ + return i915_create_context( screen, + winsys, + &iws->winsys ); +} diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c new file mode 100644 index 0000000000..8bf8c21439 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c @@ -0,0 +1,338 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include +#include +//#include "dri_bufpool.h" +//#include "dri_bufmgr.h" + +#include "intel_context.h" +#include "intel_winsys.h" +#include "intel_swapbuffers.h" +#include "intel_batchbuffer.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + + + +struct intel_pipe_winsys { + struct pipe_winsys winsys; + struct _DriBufferPool *regionPool; + struct _DriFreeSlabManager *fMan; +}; + + + +/* Turn a pipe winsys into an intel/pipe winsys: + */ +static inline struct intel_pipe_winsys * +intel_pipe_winsys( struct pipe_winsys *winsys ) +{ + return (struct intel_pipe_winsys *)winsys; +} + + +/* Most callbacks map direcly onto dri_bufmgr operations: + */ +static void *intel_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags ) +{ + unsigned drm_flags = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + drm_flags |= DRM_BO_FLAG_WRITE; + + if (flags & PIPE_BUFFER_USAGE_CPU_READ) + drm_flags |= DRM_BO_FLAG_READ; + + return driBOMap( dri_bo(buf), drm_flags, 0 ); +} + +static void intel_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnmap( dri_bo(buf) ); +} + + +static void +intel_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnReference( dri_bo(buf) ); + FREE(buf); +} + + +/* Pipe has no concept of pools. We choose the tex/region pool + * for all buffers. + * Grabs the hardware lock! + */ +static struct pipe_buffer * +intel_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size ) +{ + struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + unsigned flags = 0; + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (usage & (PIPE_BUFFER_USAGE_VERTEX /*| IWS_BUFFER_USAGE_LOCAL*/)) { + flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + } else { + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + } + + if (usage & PIPE_BUFFER_USAGE_GPU_READ) + flags |= DRM_BO_FLAG_READ; + + if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) + flags |= DRM_BO_FLAG_WRITE; + + /* drm complains if we don't set any read/write flags. + */ + if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) + flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + +#if 0 + if (flags & IWS_BUFFER_USAGE_EXE) + flags |= DRM_BO_FLAG_EXE; + + if (usage & IWS_BUFFER_USAGE_CACHED) + flags |= DRM_BO_FLAG_CACHED; +#endif + + driGenBuffers( iws->regionPool, + "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); + + driBOData( buffer->driBO, size, NULL, iws->regionPool, 0 ); + + return &buffer->base; +} + + +static struct pipe_buffer * +intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) +{ + struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + + driGenUserBuffer( iws->regionPool, + "pipe user buffer", &buffer->driBO, ptr, bytes ); + + buffer->base.refcount = 1; + + return &buffer->base; +} + + +/* The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +intel_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ +#if 0 + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + intelDisplaySurface(dPriv, surf, NULL); +#endif +} + + +static struct pipe_surface * +intel_i915_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); + if (surf) { + surf->refcount = 1; + surf->winsys = winsys; + } + return surf; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +/** + * Copied from xm_winsys.c + */ +static int +intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags) +{ + const unsigned alignment = 64; + //int ret; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + + +static void +intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + + +static const char * +intel_get_name( struct pipe_winsys *winsys ) +{ + return "Intel/EGL/ttm"; +} + +static void +intel_fence_reference( struct pipe_winsys *sws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence ) +{ + if (*ptr) + driFenceUnReference((struct _DriFenceObject **)ptr); + + if (fence) + *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); +} + +static int +intel_fence_signalled( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceSignaled((struct _DriFenceObject *)fence, flag); +} + +static int +intel_fence_finish( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + /* JB: Lets allways lazy wait */ + return driFenceFinish((struct _DriFenceObject *)fence, flag, 1); +} + +struct pipe_winsys * +intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) +{ + struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys ); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + * + * Pipe would be happy with a malloc based memory manager, but + * the SwapBuffers implementation in this winsys driver requires + * that rendering be done to an appropriate _DriBufferObject. + */ + iws->winsys.buffer_create = intel_buffer_create; + iws->winsys.user_buffer_create = intel_user_buffer_create; + iws->winsys.buffer_map = intel_buffer_map; + iws->winsys.buffer_unmap = intel_buffer_unmap; + iws->winsys.buffer_destroy = intel_buffer_destroy; + iws->winsys.flush_frontbuffer = intel_flush_frontbuffer; + iws->winsys.get_name = intel_get_name; + iws->winsys.surface_alloc = intel_i915_surface_alloc; + iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; + iws->winsys.surface_release = intel_i915_surface_release; + + iws->winsys.fence_reference = intel_fence_reference; + iws->winsys.fence_signalled = intel_fence_signalled; + iws->winsys.fence_finish = intel_fence_finish; + + if (fd) + iws->regionPool = driSlabPoolInit(fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + 64, 6, 16, 4096, 0, + fMan); + + return &iws->winsys; +} + + +void +intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) +{ + struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); + if (iws->regionPool) { + driPoolTakeDown(iws->regionPool); + } + free(iws); +} + diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c new file mode 100644 index 0000000000..0bc2dc4002 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c @@ -0,0 +1,82 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include "intel_context.h" +#include "intel_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_format.h" +#include "softpipe/sp_winsys.h" + + +struct intel_softpipe_winsys { + struct softpipe_winsys sws; + struct intel_context *intel; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean +intel_is_format_supported(struct softpipe_winsys *sws, + enum pipe_format format) +{ + switch(format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: + return TRUE; + default: + return FALSE; + } +} + + +/** + * Create rendering context which uses software rendering. + */ +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ) +{ + struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); + struct pipe_screen *screen = softpipe_create_screen(winsys); + + /* Fill in this struct with callbacks that softpipe will need to + * communicate with the window system, buffer manager, etc. + */ + isws->sws.is_format_supported = intel_is_format_supported; + isws->intel = intel; + + /* Create the softpipe context: + */ + return softpipe_create( screen, winsys, &isws->sws ); +} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c new file mode 100644 index 0000000000..1bc1089352 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c @@ -0,0 +1,953 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#include +#include +#include "glthread.h" +#include "errno.h" +#include "ws_dri_bufmgr.h" +#include "string.h" +#include "imports.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + +/* + * This lock is here to protect drmBO structs changing underneath us during a + * validate list call, since validatelist cannot take individiual locks for + * each drmBO. Validatelist takes this lock in write mode. Any access to an + * individual drmBO should take this lock in read mode, since in that case, the + * driBufferObject mutex will protect the access. Locking order is + * driBufferObject mutex - > this rw lock. + */ + +_glthread_DECLARE_STATIC_MUTEX(bmMutex); +_glthread_DECLARE_STATIC_COND(bmCond); + +static int kernelReaders = 0; +static int num_buffers = 0; +static int num_user_buffers = 0; + +static drmBO *drmBOListBuf(void *iterator) +{ + drmBONode *node; + drmMMListHead *l = (drmMMListHead *) iterator; + node = DRMLISTENTRY(drmBONode, l, head); + return node->buf; +} + +static void *drmBOListIterator(drmBOList *list) +{ + void *ret = list->list.next; + + if (ret == &list->list) + return NULL; + return ret; +} + +static void *drmBOListNext(drmBOList *list, void *iterator) +{ + void *ret; + + drmMMListHead *l = (drmMMListHead *) iterator; + ret = l->next; + if (ret == &list->list) + return NULL; + return ret; +} + +static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, + uint64_t arg0, + uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } + else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADD(&node->head, &list->list); + list->numOnList++; + return node; +} + +static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, + uint64_t mask, int *newItem) +{ + drmBONode *node, *cur; + drmMMListHead *l; + + *newItem = 0; + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + } + if (!cur) { + cur = drmAddListItem(list, buf, flags, mask); + if (!cur) { + return -ENOMEM; + } + *newItem = 1; + cur->arg0 = flags; + cur->arg1 = mask; + } + else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + return 0; +} + +static void drmBOFreeList(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->list.next; + while(l != &list->list) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->list.next; + list->numCurrent--; + list->numOnList--; + } + + l = list->free.next; + while(l != &list->free) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + } +} + +static int drmAdjustListNodes(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + int ret = 0; + + while(list->numCurrent < list->numTarget) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + ret = -ENOMEM; + break; + } + list->numCurrent++; + DRMLISTADD(&node->head, &list->free); + } + + while(list->numCurrent > list->numTarget) { + l = list->free.next; + if (l == &list->free) + break; + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + list->numCurrent--; + } + return ret; +} + +static int drmBOCreateList(int numTarget, drmBOList *list) +{ + DRMINITLISTHEAD(&list->list); + DRMINITLISTHEAD(&list->free); + list->numTarget = numTarget; + list->numCurrent = 0; + list->numOnList = 0; + return drmAdjustListNodes(list); +} + +static int drmBOResetList(drmBOList *list) +{ + drmMMListHead *l; + int ret; + + ret = drmAdjustListNodes(list); + if (ret) + return ret; + + l = list->list.next; + while (l != &list->list) { + DRMLISTDEL(l); + DRMLISTADD(l, &list->free); + list->numOnList--; + l = list->list.next; + } + return drmAdjustListNodes(list); +} + +void driWriteLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + while(kernelReaders != 0) + _glthread_COND_WAIT(bmCond, bmMutex); +} + +void driWriteUnlockKernelBO(void) +{ + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + kernelReaders++; + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadUnlockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + if (--kernelReaders == 0) + _glthread_COND_BROADCAST(bmCond); + _glthread_UNLOCK_MUTEX(bmMutex); +} + + + + +/* + * TODO: Introduce fence pools in the same way as + * buffer object pools. + */ + +typedef struct _DriBufferObject +{ + DriBufferPool *pool; + _glthread_Mutex mutex; + int refCount; + const char *name; + uint64_t flags; + unsigned hint; + unsigned alignment; + unsigned createdByReference; + void *private; + /* user-space buffer: */ + unsigned userBuffer; + void *userData; + unsigned userSize; +} DriBufferObject; + +typedef struct _DriBufferList { + drmBOList drmBuffers; /* List of kernel buffers needing validation */ + drmBOList driBuffers; /* List of user-space buffers needing validation */ +} DriBufferList; + + +void +bmError(int val, const char *file, const char *function, int line) +{ + _mesa_printf("Fatal video memory manager error \"%s\".\n" + "Check kernel logs or set the LIBGL_DEBUG\n" + "environment variable to \"verbose\" for more info.\n" + "Detected in file %s, line %d, function %s.\n", + strerror(-val), file, line, function); +#ifndef NDEBUG + abort(); +#else + abort(); +#endif +} + +extern drmBO * +driBOKernel(struct _DriBufferObject *buf) +{ + drmBO *ret; + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + ret = buf->pool->kernel(buf->pool, buf->private); + if (!ret) + BM_CKFATAL(-EINVAL); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + + return ret; +} + +void +driBOWaitIdle(struct _DriBufferObject *buf, int lazy) +{ + + /* + * This function may block. Is it sane to keep the mutex held during + * that time?? + */ + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void * +driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) +{ + void *virtual; + int retval; + + if (buf->userBuffer) { + return buf->userData; + } + + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + retval = buf->pool->map(buf->pool, buf->private, flags, hint, + &buf->mutex, &virtual); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval == 0 ? virtual : NULL; +} + +void +driBOUnmap(struct _DriBufferObject *buf) +{ + if (buf->userBuffer) + return; + + assert(buf->private != NULL); + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +unsigned long +driBOOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->offset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +unsigned long +driBOPoolOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->poolOffset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +uint64_t +driBOFlags(struct _DriBufferObject *buf) +{ + uint64_t ret; + + assert(buf->private != NULL); + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->flags(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + return ret; +} + +struct _DriBufferObject * +driBOReference(struct _DriBufferObject *buf) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (++buf->refCount == 1) { + _glthread_UNLOCK_MUTEX(buf->mutex); + BM_CKFATAL(-EINVAL); + } + _glthread_UNLOCK_MUTEX(buf->mutex); + return buf; +} + +void +driBOUnReference(struct _DriBufferObject *buf) +{ + int tmp; + + if (!buf) + return; + + _glthread_LOCK_MUTEX(buf->mutex); + tmp = --buf->refCount; + if (!tmp) { + _glthread_UNLOCK_MUTEX(buf->mutex); + if (buf->private) { + if (buf->createdByReference) + buf->pool->unreference(buf->pool, buf->private); + else + buf->pool->destroy(buf->pool, buf->private); + } + if (buf->userBuffer) + num_user_buffers--; + else + num_buffers--; + free(buf); + } else + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + + +int +driBOData(struct _DriBufferObject *buf, + unsigned size, const void *data, + DriBufferPool *newPool, + uint64_t flags) +{ + void *virtual = NULL; + int newBuffer; + int retval = 0; + struct _DriBufferPool *pool; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + pool = buf->pool; + + if (pool == NULL && newPool != NULL) { + buf->pool = newPool; + pool = newPool; + } + if (newPool == NULL) + newPool = pool; + + if (!pool->create) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "driBOData called on invalid buffer\n"); + BM_CKFATAL(-EINVAL); + } + + newBuffer = (!buf->private || pool != newPool || + pool->size(pool, buf->private) < size); + + if (!flags) + flags = buf->flags; + + if (newBuffer) { + + if (buf->createdByReference) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "driBOData requiring resizing called on " + "shared buffer.\n"); + BM_CKFATAL(-EINVAL); + } + + if (buf->private) + buf->pool->destroy(buf->pool, buf->private); + + pool = newPool; + buf->pool = newPool; + buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (!buf->private) + retval = -ENOMEM; + + if (retval == 0) + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); + } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { + /* + * Buffer is busy. need to create a new one. + */ + + void *newBuf; + + newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (newBuf) { + buf->pool->destroy(buf->pool, buf->private); + buf->private = newBuf; + } + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } else { + uint64_t flag_diff = flags ^ buf->flags; + + /* + * We might need to change buffer flags. + */ + + if (flag_diff){ + assert(pool->setStatus != NULL); + BM_CKFATAL(pool->unmap(pool, buf->private)); + BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, + buf->flags)); + if (!data) + goto out; + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } + } + + if (retval == 0) { + if (data) + memcpy(virtual, data, size); + + BM_CKFATAL(pool->unmap(pool, buf->private)); + } + + out: + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval; +} + +void +driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, const void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, + &virtual)); + memcpy((unsigned char *) virtual + offset, data, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); + memcpy(data, (unsigned char *) virtual + offset, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->private != NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer for setReferenced\n"); + BM_CKFATAL(-EINVAL); + + } + if (buf->pool->reference == NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer pool for setReferenced\n"); + BM_CKFATAL(-EINVAL); + } + buf->private = buf->pool->reference(buf->pool, handle); + if (!buf->private) { + _mesa_error(NULL, GL_OUT_OF_MEMORY, + "Invalid buffer pool for setStatic\n"); + BM_CKFATAL(-ENOMEM); + } + buf->createdByReference = GL_TRUE; + buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +int +driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint) +{ + struct _DriBufferObject *buf; + int i; + + flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + ++num_buffers; + + assert(pool); + + for (i = 0; i < n; ++i) { + buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); + if (!buf) + return -ENOMEM; + + _glthread_INIT_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(buf->mutex); + buf->refCount = 1; + buf->flags = flags; + buf->hint = hint; + buf->name = name; + buf->alignment = alignment; + buf->pool = pool; + buf->createdByReference = 0; + _glthread_UNLOCK_MUTEX(buf->mutex); + buffers[i] = buf; + } + return 0; +} + +void +driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject **buffers, + void *ptr, unsigned bytes) +{ + const unsigned alignment = 1, flags = 0, hint = 0; + + --num_buffers; /* JB: is inced in GenBuffes */ + driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); + ++num_user_buffers; + + (*buffers)->userBuffer = 1; + (*buffers)->userData = ptr; + (*buffers)->userSize = bytes; +} + +void +driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) +{ + int i; + + for (i = 0; i < n; ++i) { + driBOUnReference(buffers[i]); + } +} + + +void +driInitBufMgr(int fd) +{ + ; +} + +/* + * Note that lists are per-context and don't need mutex protection. + */ + +struct _DriBufferList * +driBOCreateList(int target) +{ + struct _DriBufferList *list = calloc(sizeof(*list), 1); + + BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); + BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); + return list; +} + +int +driBOResetList(struct _DriBufferList * list) +{ + int ret; + ret = drmBOResetList(&list->drmBuffers); + if (ret) + return ret; + ret = drmBOResetList(&list->driBuffers); + return ret; +} + +void +driBOFreeList(struct _DriBufferList * list) +{ + drmBOFreeList(&list->drmBuffers); + drmBOFreeList(&list->driBuffers); + free(list); +} + + +/* + * Copied from libdrm, because it is needed by driAddValidateItem. + */ + +static drmBONode * +driAddListItem(drmBOList * list, drmBO * item, + uint64_t arg0, uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + memset(&node->bo_arg, 0, sizeof(node->bo_arg)); + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADDTAIL(&node->head, &list->list); + list->numOnList++; + return node; +} + +/* + * Slightly modified version compared to the libdrm version. + * This one returns the list index of the buffer put on the list. + */ + +static int +driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, + uint64_t mask, int *itemLoc, + struct _drmBONode **pnode) +{ + drmBONode *node, *cur; + drmMMListHead *l; + int count = 0; + + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + count++; + } + if (!cur) { + cur = driAddListItem(list, buf, flags, mask); + if (!cur) + return -ENOMEM; + + cur->arg0 = flags; + cur->arg1 = mask; + } else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + *itemLoc = count; + *pnode = cur; + return 0; +} + + +void +driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node) +{ + int newItem; + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(driAddValidateItem(&list->drmBuffers, + buf->pool->kernel(buf->pool, buf->private), + flags, mask, itemLoc, node)); + BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, + flags, mask, &newItem)); + if (newItem) + buf->refCount++; + + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +drmBOList *driGetdrmBOList(struct _DriBufferList *list) +{ + driWriteLockKernelBO(); + return &list->drmBuffers; +} + +void driPutdrmBOList(struct _DriBufferList *list) +{ + driWriteUnlockKernelBO(); +} + + +void +driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->fence) + BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + +void +driBOUnrefUserList(struct _DriBufferList *list) +{ + struct _DriBufferObject *buf; + void *curBuf; + + curBuf = drmBOListIterator(&list->driBuffers); + while (curBuf) { + buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + +struct _DriFenceObject * +driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, const char *name, + drmFence *kFence) +{ + struct _DriFenceObject *fence; + struct _DriBufferObject *buf; + void *curBuf; + + fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, + kFence, sizeof(*kFence)); + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space fencing callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + driBOFence(buf, fence); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } + + driBOResetList(list); + return fence; +} + +void +driBOValidateUserList(struct _DriBufferList * list) +{ + void *curBuf; + struct _DriBufferObject *buf; + + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space validation callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->validate) + BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); + _glthread_UNLOCK_MUTEX(buf->mutex); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + + +void +driPoolTakeDown(struct _DriBufferPool *pool) +{ + pool->takeDown(pool); + +} + +unsigned long +driBOSize(struct _DriBufferObject *buf) +{ + unsigned long size; + + _glthread_LOCK_MUTEX(buf->mutex); + size = buf->pool->size(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return size; + +} + +drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) +{ + return &list->drmBuffers; +} + +drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) +{ + return &list->driBuffers; +} + diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h new file mode 100644 index 0000000000..fdaf5ee93a --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#ifndef _PSB_BUFMGR_H_ +#define _PSB_BUFMGR_H_ +#include +#include "i915_drm.h" +#include "ws_dri_fencemgr.h" + +typedef struct _drmBONode +{ + drmMMListHead head; + drmBO *buf; + struct drm_i915_op_arg bo_arg; + uint64_t arg0; + uint64_t arg1; +} drmBONode; + +typedef struct _drmBOList { + unsigned numTarget; + unsigned numCurrent; + unsigned numOnList; + drmMMListHead list; + drmMMListHead free; +} drmBOList; + + +struct _DriFenceObject; +struct _DriBufferObject; +struct _DriBufferPool; +struct _DriBufferList; + +/* + * Return a pointer to the libdrm buffer object this DriBufferObject + * uses. + */ + +extern drmBO *driBOKernel(struct _DriBufferObject *buf); +extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, + unsigned hint); +extern void driBOUnmap(struct _DriBufferObject *buf); +extern unsigned long driBOOffset(struct _DriBufferObject *buf); +extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); + +extern uint64_t driBOFlags(struct _DriBufferObject *buf); +extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); +extern void driBOUnReference(struct _DriBufferObject *buf); + +extern int driBOData(struct _DriBufferObject *r_buf, + unsigned size, const void *data, + struct _DriBufferPool *pool, uint64_t flags); + +extern void driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + const void *data); +extern void driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + void *data); +extern int driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint); +extern void driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject *buffers[], + void *ptr, unsigned bytes); +extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); +extern void driInitBufMgr(int fd); +extern struct _DriBufferList *driBOCreateList(int target); +extern int driBOResetList(struct _DriBufferList * list); +extern void driBOAddListItem(struct _DriBufferList * list, + struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node); + +extern void driBOValidateList(int fd, struct _DriBufferList * list); +extern void driBOFreeList(struct _DriBufferList * list); +extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, + const char *name, + drmFence *kFence); +extern void driBOUnrefUserList(struct _DriBufferList *list); +extern void driBOValidateUserList(struct _DriBufferList * list); +extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); +extern void driPutdrmBOList(struct _DriBufferList *list); + +extern void driBOFence(struct _DriBufferObject *buf, + struct _DriFenceObject *fence); + +extern void driPoolTakeDown(struct _DriBufferPool *pool); +extern void driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle); +unsigned long driBOSize(struct _DriBufferObject *buf); +extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); +extern void driPoolTakeDown(struct _DriBufferPool *pool); + +extern void driReadLockKernelBO(void); +extern void driReadUnlockKernelBO(void); +extern void driWriteLockKernelBO(void); +extern void driWriteUnlockKernelBO(void); + +/* + * For debugging purposes. + */ + +extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); +extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); +#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h b/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h new file mode 100644 index 0000000000..3a302e13d3 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#ifndef _PSB_BUFPOOL_H_ +#define _PSB_BUFPOOL_H_ + +#include +#include +struct _DriFenceObject; + +typedef struct _DriBufferPool +{ + int fd; + int (*map) (struct _DriBufferPool * pool, void *private, + unsigned flags, int hint, _glthread_Mutex *mutex, + void **virtual); + int (*unmap) (struct _DriBufferPool * pool, void *private); + int (*destroy) (struct _DriBufferPool * pool, void *private); + unsigned long (*offset) (struct _DriBufferPool * pool, void *private); + unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); + uint64_t (*flags) (struct _DriBufferPool * pool, void *private); + unsigned long (*size) (struct _DriBufferPool * pool, void *private); + void *(*create) (struct _DriBufferPool * pool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment); + void *(*reference) (struct _DriBufferPool * pool, unsigned handle); + int (*unreference) (struct _DriBufferPool * pool, void *private); + int (*fence) (struct _DriBufferPool * pool, void *private, + struct _DriFenceObject * fence); + drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); + int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy); + int (*setStatus) (struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags); + void (*takeDown) (struct _DriBufferPool * pool); + void *data; +} DriBufferPool; + +extern void bmError(int val, const char *file, const char *function, + int line); +#define BM_CKFATAL(val) \ + do{ \ + int tstVal = (val); \ + if (tstVal) \ + bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ + } while(0); + + +/* + * Builtin pools. + */ + +/* + * Kernel buffer objects. Size in multiples of page size. Page size aligned. + */ + +extern struct _DriBufferPool *driDRMPoolInit(int fd); +extern struct _DriBufferPool *driMallocPoolInit(void); + +struct _DriFreeSlabManager; +extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan); +extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); +extern struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); + + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c new file mode 100644 index 0000000000..7c55dbc674 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c @@ -0,0 +1,268 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "assert.h" + +/* + * Buffer pool implementation using DRM buffer objects as DRI buffer objects. + */ + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + unsigned pageSize = getpagesize(); + + if (!buf) + return NULL; + + if ((alignment > pageSize) && (alignment % pageSize)) { + free(buf); + return NULL; + } + + ret = drmBOCreate(pool->fd, size, alignment / pageSize, + NULL, + flags, hint, buf); + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static void * +pool_reference(struct _DriBufferPool *pool, unsigned handle) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + + if (!buf) + return NULL; + + ret = drmBOReference(pool->fd, handle, buf); + + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unreference(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOMap(pool->fd, buf, flags, hint, virtual); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOUnmap(pool->fd, buf); + driReadUnlockKernelBO(); + + return ret; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long offset; + + driReadLockKernelBO(); + assert(buf->flags & DRM_BO_FLAG_NO_MOVE); + offset = buf->offset; + driReadUnlockKernelBO(); + + return buf->offset; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + uint64_t flags; + + driReadLockKernelBO(); + flags = buf->flags; + driReadUnlockKernelBO(); + + return flags; +} + + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long size; + + driReadLockKernelBO(); + size = buf->size; + driReadUnlockKernelBO(); + + return buf->size; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + /* + * Noop. The kernel handles all fencing. + */ + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + return (drmBO *) private; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); + driReadUnlockKernelBO(); + + return ret; +} + + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + +/*static int +pool_setStatus(struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags) +{ + drmBO *buf = (drmBO *) private; + uint64_t new_flags = old_flags ^ flag_diff; + int ret; + + driReadLockKernelBO(); + ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, + 0, 0, 0); + driReadUnlockKernelBO(); + return ret; +}*/ + +struct _DriBufferPool * +driDRMPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->reference = &pool_reference; + pool->unreference = &pool_unreference; + pool->data = NULL; + return pool; +} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c new file mode 100644 index 0000000000..1f893b47ce --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c @@ -0,0 +1,377 @@ +#include "ws_dri_fencemgr.h" +#include "glthread.h" +#include +#include +#include + +/* + * Note: Locking order is + * _DriFenceObject::mutex + * _DriFenceMgr::mutex + */ + +struct _DriFenceMgr { + /* + * Constant members. Need no mutex protection. + */ + struct _DriFenceMgrCreateInfo info; + void *private; + + /* + * These members are protected by this->mutex + */ + _glthread_Mutex mutex; + int refCount; + drmMMListHead *heads; + int num_fences; +}; + +struct _DriFenceObject { + + /* + * These members are constant and need no mutex protection. + */ + struct _DriFenceMgr *mgr; + uint32_t fence_class; + uint32_t fence_type; + + /* + * These members are protected by mgr->mutex. + */ + drmMMListHead head; + int refCount; + + /* + * These members are protected by this->mutex. + */ + _glthread_Mutex mutex; + uint32_t signaled_type; + void *private; +}; + +uint32_t +driFenceType(struct _DriFenceObject *fence) +{ + return fence->fence_type; +} + +struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) +{ + struct _DriFenceMgr *tmp; + uint32_t i; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->refCount = 1; + tmp->info = *info; + tmp->num_fences = 0; + tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); + if (!tmp->heads) + goto out_err; + + for (i=0; iinfo.num_classes; ++i) { + DRMINITLISTHEAD(&tmp->heads[i]); + } + _glthread_UNLOCK_MUTEX(tmp->mutex); + return tmp; + + out_err: + if (tmp) + free(tmp); + return NULL; +} + +static void +driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) +{ + struct _DriFenceMgr *mgr = *pMgr; + + *pMgr = NULL; + if (--mgr->refCount == 0) + free(mgr); + else + _glthread_UNLOCK_MUTEX(mgr->mutex); +} + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr) +{ + _glthread_LOCK_MUTEX((*pMgr)->mutex); + driFenceMgrUnrefUnlock(pMgr); +} + +static void +driFenceUnReferenceLocked(struct _DriFenceObject **pFence) +{ + struct _DriFenceObject *fence = *pFence; + struct _DriFenceMgr *mgr = fence->mgr; + + *pFence = NULL; + if (--fence->refCount == 0) { + DRMLISTDELINIT(&fence->head); + if (fence->private) + mgr->info.unreference(mgr, &fence->private); + --mgr->num_fences; + fence->mgr = NULL; + --mgr->refCount; + free(fence); + + } +} + + +static void +driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, + drmMMListHead *list, + uint32_t fence_class, + uint32_t fence_type) +{ + struct _DriFenceObject *entry; + drmMMListHead *prev; + + while(list != &mgr->heads[fence_class]) { + entry = DRMLISTENTRY(struct _DriFenceObject, list, head); + + /* + * Up refcount so that entry doesn't disappear from under us + * when we unlock-relock mgr to get the correct locking order. + */ + + ++entry->refCount; + _glthread_UNLOCK_MUTEX(mgr->mutex); + _glthread_LOCK_MUTEX(entry->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + + prev = list->prev; + + + + if (list->prev == list) { + + /* + * Somebody else removed the entry from the list. + */ + + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + return; + } + + entry->signaled_type |= (fence_type & entry->fence_type); + if (entry->signaled_type == entry->fence_type) { + DRMLISTDELINIT(list); + mgr->info.unreference(mgr, &entry->private); + } + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + list = prev; + } +} + + +int +driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint) +{ + struct _DriFenceMgr *mgr = fence->mgr; + int ret = 0; + + _glthread_LOCK_MUTEX(fence->mutex); + + if ((fence->signaled_type & fence_type) == fence_type) + goto out0; + + ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); + if (ret) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + fence_type); + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) +{ + uint32_t ret; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = fence->signaled_type; + _glthread_UNLOCK_MUTEX(fence->mutex); + + return ret; +} + +int +driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, + uint32_t *signaled) +{ + int ret = 0; + struct _DriFenceMgr *mgr; + + _glthread_LOCK_MUTEX(fence->mutex); + mgr = fence->mgr; + *signaled = fence->signaled_type; + if ((fence->signaled_type & flush_type) == flush_type) + goto out0; + + ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); + if (ret) { + *signaled = fence->signaled_type; + goto out0; + } + + if ((fence->signaled_type | *signaled) == fence->signaled_type) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + *signaled); + + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +struct _DriFenceObject * +driFenceReference(struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(fence->mgr->mutex); + ++fence->refCount; + _glthread_UNLOCK_MUTEX(fence->mgr->mutex); + return fence; +} + +void +driFenceUnReference(struct _DriFenceObject **pFence) +{ + struct _DriFenceMgr *mgr; + + if (*pFence == NULL) + return; + + mgr = (*pFence)->mgr; + _glthread_LOCK_MUTEX(mgr->mutex); + ++mgr->refCount; + driFenceUnReferenceLocked(pFence); + driFenceMgrUnrefUnlock(&mgr); +} + +struct _DriFenceObject +*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, + uint32_t fence_type, void *private, size_t private_size) +{ + struct _DriFenceObject *fence; + size_t fence_size = sizeof(*fence); + + if (private_size) + fence_size = ((fence_size + 15) & ~15); + + fence = calloc(1, fence_size + private_size); + + if (!fence) { + int ret = mgr->info.finish(mgr, private, fence_type, 0); + + if (ret) + usleep(10000000); + + return NULL; + } + + _glthread_INIT_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + fence->refCount = 1; + DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); + fence->mgr = mgr; + ++mgr->refCount; + ++mgr->num_fences; + _glthread_UNLOCK_MUTEX(mgr->mutex); + fence->fence_class = fence_class; + fence->fence_type = fence_type; + fence->signaled_type = 0; + fence->private = private; + if (private_size) { + fence->private = (void *)(((uint8_t *) fence) + fence_size); + memcpy(fence->private, private, private_size); + } + + _glthread_UNLOCK_MUTEX(fence->mutex); + return fence; +} + + +static int +tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type) +{ + long fd = (long) mgr->private; + int dummy; + drmFence *fence = (drmFence *) private; + int ret; + + *signaled_type = 0; + ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); + if (ret) + return ret; + + *signaled_type = fence->signaled; + + return 0; +} + +static int +tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, + int lazy_hint) +{ + long fd = (long) mgr->private; + unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; + + return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); +} + +static int +tUnref(struct _DriFenceMgr *mgr, void **private) +{ + long fd = (long) mgr->private; + drmFence *fence = (drmFence *) *private; + *private = NULL; + + return drmFenceUnreference(fd, fence); +} + +struct _DriFenceMgr *driFenceMgrTTMInit(int fd) +{ + struct _DriFenceMgrCreateInfo info; + struct _DriFenceMgr *mgr; + + info.flags = DRI_FENCE_CLASS_ORDERED; + info.num_classes = 4; + info.signaled = tSignaled; + info.finish = tFinish; + info.unreference = tUnref; + + mgr = driFenceMgrCreate(&info); + if (mgr == NULL) + return NULL; + + mgr->private = (void *) (long) fd; + return mgr; +} + diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h new file mode 100644 index 0000000000..4ea58dfe18 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h @@ -0,0 +1,115 @@ +#ifndef DRI_FENCEMGR_H +#define DRI_FENCEMGR_H + +#include +#include + +struct _DriFenceObject; +struct _DriFenceMgr; + +/* + * Do a quick check to see if the fence manager has registered the fence + * object as signaled. Note that this function may return a false negative + * answer. + */ +extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); + +/* + * Check if the fence object is signaled. This function can be substantially + * more expensive to call than the above function, but will not return a false + * negative answer. The argument "flush_type" sets the types that the + * underlying mechanism must make sure will eventually signal. + */ +extern int driFenceSignaledType(struct _DriFenceObject *fence, + uint32_t flush_type, uint32_t *signaled); + +/* + * Convenience functions. + */ + +static inline int driFenceSignaled(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types; + int ret = driFenceSignaledType(fence, flush_type, &signaled_types); + if (ret) + return 0; + return ((signaled_types & flush_type) == flush_type); +} + +static inline int driFenceSignaledCached(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types = + driFenceSignaledTypeCached(fence); + + return ((signaled_types & flush_type) == flush_type); +} + +/* + * Reference a fence object. + */ +extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); + +/* + * Unreference a fence object. The fence object pointer will be reset to NULL. + */ + +extern void driFenceUnReference(struct _DriFenceObject **pFence); + + +/* + * Wait for a fence to signal the indicated fence_type. + * If "lazy_hint" is true, it indicates that the wait may sleep to avoid + * busy-wait polling. + */ +extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint); + +/* + * Create a DriFenceObject for manager "mgr". + * + * "private" is a pointer that should be used for the callbacks in + * struct _DriFenceMgrCreateInfo. + * + * if private_size is nonzero, then the info stored at *private, with size + * private size will be copied and the fence manager will instead use a + * pointer to the copied data for the callbacks in + * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by + * "private" may be destroyed after the call to driFenceCreate. + */ +extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, + uint32_t fence_class, + uint32_t fence_type, + void *private, + size_t private_size); + +extern uint32_t driFenceType(struct _DriFenceObject *fence); + +/* + * Fence creations are ordered. If a fence signals a fence_type, + * it is safe to assume that all fences of the same class that was + * created before that fence has signaled the same type. + */ + +#define DRI_FENCE_CLASS_ORDERED (1 << 0) + +struct _DriFenceMgrCreateInfo { + uint32_t flags; + uint32_t num_classes; + int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type); + int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); + int (*unreference) (struct _DriFenceMgr *mgr, void **private); +}; + +extern struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr); + +extern struct _DriFenceMgr * +driFenceMgrTTMInit(int fd); + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c new file mode 100644 index 0000000000..bf97d7e440 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c @@ -0,0 +1,162 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "imports.h" +#include "glthread.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "intel_screen.h" + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + unsigned long *private = malloc(size + 2*sizeof(unsigned long)); + if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) + abort(); + + *private = size; + return (void *)private; +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + free(private); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + *virtual = (void *)((unsigned long *)private + 2); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); + return 0UL; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + return *(unsigned long *) private; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + abort(); + return 0UL; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + abort(); + return NULL; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + + +struct _DriBufferPool * +driMallocPoolInit(void) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = NULL; + pool->fd = -1; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c new file mode 100644 index 0000000000..e69519a01f --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c @@ -0,0 +1,970 @@ +/************************************************************************** + * + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include +#include +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" +#include "ws_dri_bufmgr.h" +#include "glthread.h" + +#define DRI_SLABPOOL_ALLOC_RETRIES 100 + +struct _DriSlab; + +struct _DriSlabBuffer { + int isSlabBuffer; + drmBO *bo; + struct _DriFenceObject *fence; + struct _DriSlab *parent; + drmMMListHead head; + uint32_t mapCount; + uint32_t start; + uint32_t fenceType; + int unFenced; + _glthread_Cond event; +}; + +struct _DriKernelBO { + int fd; + drmBO bo; + drmMMListHead timeoutHead; + drmMMListHead head; + struct timeval timeFreed; + uint32_t pageAlignment; + void *virtual; +}; + +struct _DriSlab{ + drmMMListHead head; + drmMMListHead freeBuffers; + uint32_t numBuffers; + uint32_t numFree; + struct _DriSlabBuffer *buffers; + struct _DriSlabSizeHeader *header; + struct _DriKernelBO *kbo; +}; + + +struct _DriSlabSizeHeader { + drmMMListHead slabs; + drmMMListHead freeSlabs; + drmMMListHead delayedBuffers; + uint32_t numDelayed; + struct _DriSlabPool *slabPool; + uint32_t bufSize; + _glthread_Mutex mutex; +}; + +struct _DriFreeSlabManager { + struct timeval slabTimeout; + struct timeval checkInterval; + struct timeval nextCheck; + drmMMListHead timeoutList; + drmMMListHead unCached; + drmMMListHead cached; + _glthread_Mutex mutex; +}; + + +struct _DriSlabPool { + + /* + * The data of this structure remains constant after + * initialization and thus needs no mutex protection. + */ + + struct _DriFreeSlabManager *fMan; + uint64_t proposedFlags; + uint64_t validMask; + uint32_t *bucketSizes; + uint32_t numBuckets; + uint32_t pageSize; + int fd; + int pageAlignment; + int maxSlabSize; + int desiredNumBuffers; + struct _DriSlabSizeHeader *headers; +}; + +/* + * FIXME: Perhaps arrange timeout slabs in size buckets for fast + * retreival?? + */ + + +static inline int +driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) +{ + return ((arg1->tv_sec > arg2->tv_sec) || + ((arg1->tv_sec == arg2->tv_sec) && + (arg1->tv_usec > arg2->tv_usec))); +} + +static inline void +driTimeAdd(struct timeval *arg, struct timeval *add) +{ + unsigned int sec; + + arg->tv_sec += add->tv_sec; + arg->tv_usec += add->tv_usec; + sec = arg->tv_usec / 1000000; + arg->tv_sec += sec; + arg->tv_usec -= sec*1000000; +} + +static void +driFreeKernelBO(struct _DriKernelBO *kbo) +{ + if (!kbo) + return; + + (void) drmBOUnreference(kbo->fd, &kbo->bo); + free(kbo); +} + + +static void +driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, + struct timeval *time) +{ + drmMMListHead *list, *next; + struct _DriKernelBO *kbo; + + if (!driTimeAfterEq(time, &fMan->nextCheck)) + return; + + for (list = fMan->timeoutList.next, next = list->next; + list != &fMan->timeoutList; + list = next, next = list->next) { + + kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); + + if (!driTimeAfterEq(time, &kbo->timeFreed)) + break; + + DRMLISTDELINIT(&kbo->timeoutHead); + DRMLISTDELINIT(&kbo->head); + driFreeKernelBO(kbo); + } + + fMan->nextCheck = *time; + driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); +} + + +/* + * Add a _DriKernelBO to the free slab manager. + * This means that it is available for reuse, but if it's not + * reused in a while, it will be freed. + */ + +static void +driSetKernelBOFree(struct _DriFreeSlabManager *fMan, + struct _DriKernelBO *kbo) +{ + struct timeval time; + + _glthread_LOCK_MUTEX(fMan->mutex); + gettimeofday(&time, NULL); + driTimeAdd(&time, &fMan->slabTimeout); + + kbo->timeFreed = time; + + if (kbo->bo.flags & DRM_BO_FLAG_CACHED) + DRMLISTADD(&kbo->head, &fMan->cached); + else + DRMLISTADD(&kbo->head, &fMan->unCached); + + DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); + driFreeTimeoutKBOsLocked(fMan, &time); + + _glthread_UNLOCK_MUTEX(fMan->mutex); +} + +/* + * Get a _DriKernelBO for us to use as storage for a slab. + * + */ + +static struct _DriKernelBO * +driAllocKernelBO(struct _DriSlabSizeHeader *header) + +{ + struct _DriSlabPool *slabPool = header->slabPool; + struct _DriFreeSlabManager *fMan = slabPool->fMan; + drmMMListHead *list, *next, *head; + uint32_t size = header->bufSize * slabPool->desiredNumBuffers; + struct _DriKernelBO *kbo; + struct _DriKernelBO *kboTmp; + int ret; + + /* + * FIXME: We should perhaps allow some variation in slabsize in order + * to efficiently reuse slabs. + */ + + size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; + size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); + _glthread_LOCK_MUTEX(fMan->mutex); + + kbo = NULL; + + retry: + head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? + &fMan->cached : &fMan->unCached; + + for (list = head->next, next = list->next; + list != head; + list = next, next = list->next) { + + kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); + + if ((kboTmp->bo.size == size) && + (slabPool->pageAlignment == 0 || + (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { + + if (!kbo) + kbo = kboTmp; + + if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) + break; + + } + } + + if (kbo) { + DRMLISTDELINIT(&kbo->head); + DRMLISTDELINIT(&kbo->timeoutHead); + } + + _glthread_UNLOCK_MUTEX(fMan->mutex); + + if (kbo) { + uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; + + ret = 0; + if (new_mask) { + ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, + new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); + } + if (ret == 0) + return kbo; + + driFreeKernelBO(kbo); + kbo = NULL; + goto retry; + } + + kbo = calloc(1, sizeof(struct _DriKernelBO)); + if (!kbo) + return NULL; + + kbo->fd = slabPool->fd; + DRMINITLISTHEAD(&kbo->head); + DRMINITLISTHEAD(&kbo->timeoutHead); + ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, + slabPool->proposedFlags, + DRM_BO_HINT_DONT_FENCE, &kbo->bo); + if (ret) + goto out_err0; + + ret = drmBOMap(kbo->fd, &kbo->bo, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &kbo->virtual); + + if (ret) + goto out_err1; + + ret = drmBOUnmap(kbo->fd, &kbo->bo); + if (ret) + goto out_err1; + + return kbo; + + out_err1: + drmBOUnreference(kbo->fd, &kbo->bo); + out_err0: + free(kbo); + return NULL; +} + + +static int +driAllocSlab(struct _DriSlabSizeHeader *header) +{ + struct _DriSlab *slab; + struct _DriSlabBuffer *buf; + uint32_t numBuffers; + int ret; + int i; + + slab = calloc(1, sizeof(*slab)); + if (!slab) + return -ENOMEM; + + slab->kbo = driAllocKernelBO(header); + if (!slab->kbo) { + ret = -ENOMEM; + goto out_err0; + } + + numBuffers = slab->kbo->bo.size / header->bufSize; + + slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); + if (!slab->buffers) { + ret = -ENOMEM; + goto out_err1; + } + + DRMINITLISTHEAD(&slab->head); + DRMINITLISTHEAD(&slab->freeBuffers); + slab->numBuffers = numBuffers; + slab->numFree = 0; + slab->header = header; + + buf = slab->buffers; + for (i=0; i < numBuffers; ++i) { + buf->parent = slab; + buf->start = i* header->bufSize; + buf->mapCount = 0; + buf->isSlabBuffer = 1; + _glthread_INIT_COND(buf->event); + DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); + slab->numFree++; + buf++; + } + + DRMLISTADDTAIL(&slab->head, &header->slabs); + + return 0; + + out_err1: + driSetKernelBOFree(header->slabPool->fMan, slab->kbo); + free(slab->buffers); + out_err0: + free(slab); + return ret; +} + +/* + * Delete a buffer from the slab header delayed list and put + * it on the slab free list. + */ + +static void +driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) +{ + struct _DriSlab *slab = buf->parent; + struct _DriSlabSizeHeader *header = slab->header; + drmMMListHead *list = &buf->head; + + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &slab->freeBuffers); + slab->numFree++; + + if (slab->head.next == &slab->head) + DRMLISTADDTAIL(&slab->head, &header->slabs); + + if (slab->numFree == slab->numBuffers) { + list = &slab->head; + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &header->freeSlabs); + } + + if (header->slabs.next == &header->slabs || + slab->numFree != slab->numBuffers) { + + drmMMListHead *next; + struct _DriFreeSlabManager *fMan = header->slabPool->fMan; + + for (list = header->freeSlabs.next, next = list->next; + list != &header->freeSlabs; + list = next, next = list->next) { + + slab = DRMLISTENTRY(struct _DriSlab, list, head); + + DRMLISTDELINIT(list); + driSetKernelBOFree(fMan, slab->kbo); + free(slab->buffers); + free(slab); + } + } +} + +static void +driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) +{ + drmMMListHead *list, *prev, *first; + struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + int firstWasSignaled = 1; + int signaled; + int i; + int ret; + + /* + * Rerun the freeing test if the youngest tested buffer + * was signaled, since there might be more idle buffers + * in the delay list. + */ + + while (firstWasSignaled) { + firstWasSignaled = 0; + signaled = 0; + first = header->delayedBuffers.next; + + /* Only examine the oldest 1/3 of delayed buffers: + */ + if (header->numDelayed > 3) { + for (i = 0; i < header->numDelayed; i += 3) { + first = first->next; + } + } + + for (list = first, prev = list->prev; + list != &header->delayedBuffers; + list = prev, prev = list->prev) { + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + slab = buf->parent; + + if (!signaled) { + if (wait) { + ret = driFenceFinish(buf->fence, buf->fenceType, 0); + if (ret) + break; + signaled = 1; + wait = 0; + } else { + signaled = driFenceSignaled(buf->fence, buf->fenceType); + } + if (signaled) { + if (list == first) + firstWasSignaled = 1; + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } + } +} + + +static struct _DriSlabBuffer * +driSlabAllocBuffer(struct _DriSlabSizeHeader *header) +{ + static struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + drmMMListHead *list; + int count = DRI_SLABPOOL_ALLOC_RETRIES; + + _glthread_LOCK_MUTEX(header->mutex); + while(header->slabs.next == &header->slabs && count > 0) { + driSlabCheckFreeLocked(header, 0); + if (header->slabs.next != &header->slabs) + break; + + _glthread_UNLOCK_MUTEX(header->mutex); + if (count != DRI_SLABPOOL_ALLOC_RETRIES) + usleep(1); + _glthread_LOCK_MUTEX(header->mutex); + (void) driAllocSlab(header); + count--; + } + + list = header->slabs.next; + if (list == &header->slabs) { + _glthread_UNLOCK_MUTEX(header->mutex); + return NULL; + } + slab = DRMLISTENTRY(struct _DriSlab, list, head); + if (--slab->numFree == 0) + DRMLISTDELINIT(list); + + list = slab->freeBuffers.next; + DRMLISTDELINIT(list); + + _glthread_UNLOCK_MUTEX(header->mutex); + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + return buf; +} + +static void * +pool_create(struct _DriBufferPool *driPool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment) +{ + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + struct _DriSlabSizeHeader *header; + struct _DriSlabBuffer *buf; + void *dummy; + int i; + int ret; + + /* + * FIXME: Check for compatibility. + */ + header = pool->headers; + for (i=0; inumBuckets; ++i) { + if (header->bufSize >= size) + break; + header++; + } + + if (i < pool->numBuckets) + return driSlabAllocBuffer(header); + + + /* + * Fall back to allocate a buffer object directly from DRM. + * and wrap it in a driBO structure. + */ + + + buf = calloc(1, sizeof(*buf)); + + if (!buf) + return NULL; + + buf->bo = calloc(1, sizeof(*buf->bo)); + if (!buf->bo) + goto out_err0; + + if (alignment) { + if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) + goto out_err1; + if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) + goto out_err1; + } + + ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, + flags, hint, buf->bo); + if (ret) + goto out_err1; + + ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &dummy); + if (ret) + goto out_err2; + + ret = drmBOUnmap(pool->fd, buf->bo); + if (ret) + goto out_err2; + + return buf; + out_err2: + drmBOUnreference(pool->fd, buf->bo); + out_err1: + free(buf->bo); + out_err0: + free(buf); + return NULL; +} + +static int +pool_destroy(struct _DriBufferPool *driPool, void *private) +{ + struct _DriSlabBuffer *buf = + (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + int ret; + + ret = drmBOUnreference(pool->fd, buf->bo); + free(buf->bo); + free(buf); + return ret; + } + + slab = buf->parent; + header = slab->header; + + _glthread_LOCK_MUTEX(header->mutex); + buf->unFenced = 0; + buf->mapCount = 0; + + if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { + DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); + header->numDelayed++; + } else { + if (buf->fence) + driFenceUnReference(&buf->fence); + driSlabFreeBufferLocked(buf); + } + + _glthread_UNLOCK_MUTEX(header->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *driPool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + while(buf->unFenced) + _glthread_COND_WAIT(buf->event, *mutex); + + if (!buf->fence) + return 0; + + driFenceFinish(buf->fence, buf->fenceType, lazy); + driFenceUnReference(&buf->fence); + + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + int busy; + + if (buf->isSlabBuffer) + busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); + else + busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); + + + if (busy) { + if (hint & DRM_BO_HINT_DONT_BLOCK) + return -EBUSY; + else { + (void) pool_waitIdle(pool, private, mutex, 0); + } + } + + ++buf->mapCount; + *virtual = (buf->isSlabBuffer) ? + (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : + (void *) buf->bo->virtual; + + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + --buf->mapCount; + if (buf->mapCount == 0 && buf->isSlabBuffer) + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return buf->bo->offset; + } + + slab = buf->parent; + header = slab->header; + + (void) header; + assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return slab->kbo->bo.offset + buf->start; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return buf->start; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return buf->bo->flags; + + return buf->parent->kbo->bo.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + if (!buf->isSlabBuffer) + return buf->bo->size; + + return buf->parent->header->bufSize; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + drmBO *bo; + + if (buf->fence) + driFenceUnReference(&buf->fence); + + buf->fence = driFenceReference(fence); + bo = (buf->isSlabBuffer) ? + &buf->parent->kbo->bo: + buf->bo; + buf->fenceType = bo->fenceFlags; + + buf->unFenced = 0; + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf) + return NULL; + + return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return 0; + + while(buf->mapCount != 0) + _glthread_COND_WAIT(buf->event, *mutex); + + buf->unFenced = 1; + return 0; +} + + +struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) +{ + struct _DriFreeSlabManager *tmp; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; + tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; + tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; + + tmp->checkInterval.tv_usec = checkIntervalMsec*1000; + tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; + tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; + + gettimeofday(&tmp->nextCheck, NULL); + driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); + DRMINITLISTHEAD(&tmp->timeoutList); + DRMINITLISTHEAD(&tmp->unCached); + DRMINITLISTHEAD(&tmp->cached); + _glthread_UNLOCK_MUTEX(tmp->mutex); + + return tmp; +} + +void +driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) +{ + struct timeval time; + + time = fMan->nextCheck; + driTimeAdd(&time, &fMan->checkInterval); + + _glthread_LOCK_MUTEX(fMan->mutex); + driFreeTimeoutKBOsLocked(fMan, &time); + _glthread_UNLOCK_MUTEX(fMan->mutex); + + assert(fMan->timeoutList.next == &fMan->timeoutList); + assert(fMan->unCached.next == &fMan->unCached); + assert(fMan->cached.next == &fMan->cached); + + free(fMan); +} + +static void +driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, + struct _DriSlabSizeHeader *header) +{ + _glthread_INIT_MUTEX(header->mutex); + _glthread_LOCK_MUTEX(header->mutex); + + DRMINITLISTHEAD(&header->slabs); + DRMINITLISTHEAD(&header->freeSlabs); + DRMINITLISTHEAD(&header->delayedBuffers); + + header->numDelayed = 0; + header->slabPool = pool; + header->bufSize = size; + + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +driFinishSizeHeader(struct _DriSlabSizeHeader *header) +{ + drmMMListHead *list, *next; + struct _DriSlabBuffer *buf; + + _glthread_LOCK_MUTEX(header->mutex); + for (list = header->delayedBuffers.next, next = list->next; + list != &header->delayedBuffers; + list = next, next = list->next) { + + buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); + if (buf->fence) { + (void) driFenceFinish(buf->fence, buf->fenceType, 0); + driFenceUnReference(&buf->fence); + } + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +pool_takedown(struct _DriBufferPool *driPool) +{ + struct _DriSlabPool *pool = driPool->data; + int i; + + for (i=0; inumBuckets; ++i) { + driFinishSizeHeader(&pool->headers[i]); + } + + free(pool->headers); + free(pool->bucketSizes); + free(pool); + free(driPool); +} + +struct _DriBufferPool * +driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan) +{ + struct _DriBufferPool *driPool; + struct _DriSlabPool *pool; + uint32_t i; + + driPool = calloc(1, sizeof(*driPool)); + if (!driPool) + return NULL; + + pool = calloc(1, sizeof(*pool)); + if (!pool) + goto out_err0; + + pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); + if (!pool->bucketSizes) + goto out_err1; + + pool->headers = calloc(numSizes, sizeof(*pool->headers)); + if (!pool->headers) + goto out_err2; + + pool->fMan = fMan; + pool->proposedFlags = flags; + pool->validMask = validMask; + pool->numBuckets = numSizes; + pool->pageSize = getpagesize(); + pool->fd = fd; + pool->pageAlignment = pageAlignment; + pool->maxSlabSize = maxSlabSize; + pool->desiredNumBuffers = desiredNumBuffers; + + for (i=0; inumBuckets; ++i) { + pool->bucketSizes[i] = (smallestSize << i); + driInitSizeHeader(pool, pool->bucketSizes[i], + &pool->headers[i]); + } + + driPool->data = (void *) pool; + driPool->map = &pool_map; + driPool->unmap = &pool_unmap; + driPool->destroy = &pool_destroy; + driPool->offset = &pool_offset; + driPool->poolOffset = &pool_poolOffset; + driPool->flags = &pool_flags; + driPool->size = &pool_size; + driPool->create = &pool_create; + driPool->fence = &pool_fence; + driPool->kernel = &pool_kernel; + driPool->validate = &pool_validate; + driPool->waitIdle = &pool_waitIdle; + driPool->takeDown = &pool_takedown; + + return driPool; + + out_err2: + free(pool->bucketSizes); + out_err1: + free(pool); + out_err0: + free(driPool); + + return NULL; +} -- cgit v1.2.3 From 718a2d8c7a125609a8dca813703047e24de09653 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 17 May 2008 08:47:56 -0600 Subject: gallium: remove deprecated format names --- src/gallium/include/pipe/p_format.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index e32212d36c..a4bd23c302 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -327,14 +327,6 @@ enum pipe_format { }; -/** XXX remove these deprecated names */ -#define PIPE_FORMAT_U_L8 PIPE_FORMAT_L8_UNORM -#define PIPE_FORMAT_U_A8 PIPE_FORMAT_A8_UNORM -#define PIPE_FORMAT_U_I8 PIPE_FORMAT_I8_UNORM -#define PIPE_FORMAT_U_A8_L8 PIPE_FORMAT_A8L8_UNORM -#define PIPE_FORMAT_U_S8 PIPE_FORMAT_S8_UNORM - - /** * Builds pipe format name from format token. */ -- cgit v1.2.3 From 9671f7ae476cadb46f9f8f9d0363f24aabaf9f87 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 17 May 2008 10:30:21 -0600 Subject: gallium: in drivers, make copy of tokens passed to pipe->create_vs/fs_state() The caller can then free the token array immediately. --- src/gallium/auxiliary/draw/draw_vs_exec.c | 11 ++-- src/gallium/auxiliary/draw/draw_vs_llvm.c | 7 +- src/gallium/auxiliary/draw/draw_vs_sse.c | 5 +- src/gallium/auxiliary/tgsi/util/tgsi_parse.c | 15 +++++ src/gallium/auxiliary/tgsi/util/tgsi_parse.h | 31 ++++++++- src/gallium/drivers/cell/ppu/cell_state_shader.c | 84 +++++++++++++++--------- src/gallium/drivers/i915simple/i915_state.c | 5 +- src/gallium/drivers/i965simple/brw_state.c | 19 +++--- src/gallium/drivers/softpipe/sp_fs_exec.c | 5 +- src/gallium/drivers/softpipe/sp_state.h | 7 +- src/gallium/drivers/softpipe/sp_state_fs.c | 5 +- 11 files changed, 137 insertions(+), 57 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 54a2b2ab04..7a02f6334b 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -39,6 +39,7 @@ #include "draw_vs.h" #include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_scan.h" struct exec_vertex_shader { @@ -165,21 +166,23 @@ draw_create_vs_exec(struct draw_context *draw, const struct pipe_shader_state *state) { struct exec_vertex_shader *vs = CALLOC_STRUCT( exec_vertex_shader ); - uint nt = tgsi_num_tokens(state->tokens); if (vs == NULL) return NULL; /* we make a private copy of the tokens */ - vs->base.state.tokens = mem_dup(state->tokens, nt * sizeof(state->tokens[0])); - tgsi_scan_shader(state->tokens, &vs->base.info); + vs->base.state.tokens = tgsi_dup_tokens(state->tokens); + if (!vs->base.state.tokens) { + FREE(vs); + return NULL; + } + tgsi_scan_shader(state->tokens, &vs->base.info); vs->base.prepare = vs_exec_prepare; vs->base.run_linear = vs_exec_run_linear; vs->base.delete = vs_exec_delete; vs->machine = &draw->machine; - return &vs->base; } diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index dcada66514..be6907ed04 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -138,14 +138,17 @@ draw_create_vs_llvm(struct draw_context *draw, const struct pipe_shader_state *templ) { struct draw_llvm_vertex_shader *vs; - uint nt = tgsi_num_tokens(templ->tokens); vs = CALLOC_STRUCT( draw_llvm_vertex_shader ); if (vs == NULL) return NULL; /* we make a private copy of the tokens */ - vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0])); + vs->base.state.tokens = tgsi_dup_tokens(templ->tokens); + if (!vs->base.state.tokens) { + FREE(vs); + return NULL; + } tgsi_scan_shader(vs->base.state.tokens, &vs->base.info); diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index a57c938fbf..5929ea76b2 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -188,7 +188,6 @@ draw_create_vs_sse(struct draw_context *draw, const struct pipe_shader_state *templ) { struct draw_sse_vertex_shader *vs; - uint nt = tgsi_num_tokens(templ->tokens); if (!rtasm_cpu_has_sse2()) return NULL; @@ -198,7 +197,9 @@ draw_create_vs_sse(struct draw_context *draw, return NULL; /* we make a private copy of the tokens */ - vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0])); + vs->base.state.tokens = tgsi_dup_tokens(templ->tokens); + if (!vs->base.state.tokens) + goto fail; tgsi_scan_shader(templ->tokens, &vs->base.info); diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c index 5bea773840..5c0b0bfd61 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c @@ -330,3 +330,18 @@ tgsi_num_tokens(const struct tgsi_token *tokens) } return 0; } + + +/** + * Make a new copy of a token array. + */ +struct tgsi_token * +tgsi_dup_tokens(const struct tgsi_token *tokens) +{ + unsigned n = tgsi_num_tokens(tokens); + unsigned bytes = n * sizeof(struct tgsi_token); + struct tgsi_token *new_tokens = (struct tgsi_token *) MALLOC(bytes); + if (new_tokens) + memcpy(new_tokens, tokens, bytes); + return new_tokens; +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h index 15e76feb7c..4102101093 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h @@ -1,4 +1,31 @@ -#if !defined TGSI_PARSE_H +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_PARSE_H #define TGSI_PARSE_H #include "pipe/p_shader_tokens.h" @@ -118,6 +145,8 @@ tgsi_parse_token( unsigned tgsi_num_tokens(const struct tgsi_token *tokens); +struct tgsi_token * +tgsi_dup_tokens(const struct tgsi_token *tokens); #if defined __cplusplus } diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c index fb2e940348..c3a3fbd066 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -30,33 +30,50 @@ #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" #include "draw/draw_context.h" -#if 0 -#include "pipe/p_shader_tokens.h" -#include "gallivm/gallivm.h" -#include "tgsi/util/tgsi_dump.h" -#include "tgsi/exec/tgsi_sse2.h" -#endif +#include "tgsi/util/tgsi_parse.h" #include "cell_context.h" #include "cell_state.h" + +/** cast wrapper */ +static INLINE struct cell_fragment_shader_state * +cell_fragment_shader_state(void *shader) +{ + return (struct pipe_shader_state *) shader; +} + + +/** cast wrapper */ +static INLINE struct cell_vertex_shader_state * +cell_vertex_shader_state(void *shader) +{ + return (struct pipe_shader_state *) shader; +} + + + static void * cell_create_fs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) { /*struct cell_context *cell = cell_context(pipe);*/ - struct cell_fragment_shader_state *state; + struct cell_fragment_shader_state *cfs; - state = CALLOC_STRUCT(cell_fragment_shader_state); - if (!state) + cfs = CALLOC_STRUCT(cell_fragment_shader_state); + if (!cfs) return NULL; - state->shader = *templ; + cfs->shader.tokens = tgsi_dup_tokens(templ->tokens); + if (!cfs->shader.tokens) { + FREE(cfs); + return NULL; + } - tgsi_scan_shader(templ->tokens, &state->info); + tgsi_scan_shader(templ->tokens, &cfs->info); - return state; + return cfs; } @@ -65,7 +82,7 @@ cell_bind_fs_state(struct pipe_context *pipe, void *fs) { struct cell_context *cell = cell_context(pipe); - cell->fs = (struct cell_fragment_shader_state *) fs; + cell->fs = cell_fragment_shader_state(fs); cell->dirty |= CELL_NEW_FS; } @@ -74,10 +91,10 @@ cell_bind_fs_state(struct pipe_context *pipe, void *fs) static void cell_delete_fs_state(struct pipe_context *pipe, void *fs) { - struct cell_fragment_shader_state *state = - (struct cell_fragment_shader_state *) fs; + struct cell_fragment_shader_state *cfs = cell_fragment_shader_state(fs); - FREE( state ); + FREE((void *) cfs->shader.tokens); + FREE(cfs); } @@ -86,22 +103,28 @@ cell_create_vs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) { struct cell_context *cell = cell_context(pipe); - struct cell_vertex_shader_state *state; + struct cell_vertex_shader_state *cvs; - state = CALLOC_STRUCT(cell_vertex_shader_state); - if (!state) + cvs = CALLOC_STRUCT(cell_vertex_shader_state); + if (!cvs) return NULL; - state->shader = *templ; - tgsi_scan_shader(templ->tokens, &state->info); + cvs->shader.tokens = tgsi_dup_tokens(templ->tokens); + if (!cvs->shader.tokens) { + FREE(cvs); + return NULL; + } - state->draw_data = draw_create_vertex_shader(cell->draw, &state->shader); - if (state->draw_data == NULL) { - FREE( state ); + tgsi_scan_shader(templ->tokens, &cvs->info); + + cvs->draw_data = draw_create_vertex_shader(cell->draw, &cvs->shader); + if (cvs->draw_data == NULL) { + FREE( (void *) cvs->shader.tokens ); + FREE( cvs ); return NULL; } - return state; + return cvs; } @@ -110,7 +133,7 @@ cell_bind_vs_state(struct pipe_context *pipe, void *vs) { struct cell_context *cell = cell_context(pipe); - cell->vs = (const struct cell_vertex_shader_state *) vs; + cell->vs = cell_vertex_shader_state(vs); draw_bind_vertex_shader(cell->draw, (cell->vs ? cell->vs->draw_data : NULL)); @@ -123,12 +146,11 @@ static void cell_delete_vs_state(struct pipe_context *pipe, void *vs) { struct cell_context *cell = cell_context(pipe); + struct cell_vertex_shader_state *cvs = cell_vertex_shader_state(vs); - struct cell_vertex_shader_state *state = - (struct cell_vertex_shader_state *) vs; - - draw_delete_vertex_shader(cell->draw, state->draw_data); - FREE( state ); + draw_delete_vertex_shader(cell->draw, cvs->draw_data); + FREE( (void *) cvs->shader.tokens ); + FREE( cvs ); } diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 3d94b52366..4adeb37e86 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -33,6 +33,7 @@ #include "pipe/p_winsys.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "tgsi/util/tgsi_parse.h" #include "i915_context.h" #include "i915_reg.h" @@ -436,7 +437,7 @@ i915_create_fs_state(struct pipe_context *pipe, if (!ifs) return NULL; - ifs->state = *templ; + ifs->state.tokens = tgsi_dup_tokens(templ->tokens); tgsi_scan_shader(templ->tokens, &ifs->info); @@ -465,6 +466,8 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader) FREE(ifs->program); ifs->program_len = 0; + FREE(ifs->state.tokens); + FREE(ifs); } diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index 376f1487b2..ac243b7e4f 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -35,6 +35,7 @@ #include "pipe/p_inlines.h" #include "pipe/p_shader_tokens.h" #include "tgsi/util/tgsi_dump.h" +#include "tgsi/util/tgsi_parse.h" #include "brw_context.h" #include "brw_defines.h" @@ -182,9 +183,7 @@ static void * brw_create_fs_state(struct pipe_context *pipe, { struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program); - /* XXX: Do I have to duplicate the tokens as well?? - */ - brw_fp->program = *shader; + brw_fp->program.tokens = tgsi_dup_tokens(shader->tokens); brw_fp->id = brw_context(pipe)->program_id++; tgsi_scan_shader(shader->tokens, &brw_fp->info); @@ -210,7 +209,10 @@ static void brw_bind_fs_state(struct pipe_context *pipe, void *shader) static void brw_delete_fs_state(struct pipe_context *pipe, void *shader) { - FREE(shader); + struct brw_fragment_program *brw_fp = (struct brw_fragment_program *) shader; + + FREE((void *) brw_fp->program.tokens); + FREE(brw_fp); } @@ -223,9 +225,7 @@ static void *brw_create_vs_state(struct pipe_context *pipe, { struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program); - /* XXX: Do I have to duplicate the tokens as well?? - */ - brw_vp->program = *shader; + brw_vp->program.tokens = tgsi_dup_tokens(shader->tokens); brw_vp->id = brw_context(pipe)->program_id++; tgsi_scan_shader(shader->tokens, &brw_vp->info); @@ -251,7 +251,10 @@ static void brw_bind_vs_state(struct pipe_context *pipe, void *vs) static void brw_delete_vs_state(struct pipe_context *pipe, void *shader) { - FREE(shader); + struct brw_vertex_program *brw_vp = (struct brw_vertex_program *) shader; + + FREE((void *) brw_vp->program.tokens); + FREE(brw_vp); } diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index d5bd7a702f..0b199a2193 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -37,6 +37,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_parse.h" struct sp_exec_fragment_shader { struct sp_fragment_shader base; @@ -116,6 +117,7 @@ exec_run( const struct sp_fragment_shader *base, static void exec_delete( struct sp_fragment_shader *base ) { + FREE((void *) base->shader.tokens); FREE(base); } @@ -137,7 +139,8 @@ softpipe_create_fs_exec(struct softpipe_context *softpipe, if (!shader) return NULL; - shader->base.shader = *templ; + /* we need to keep a local copy of the tokens */ + shader->base.shader.tokens = tgsi_dup_tokens(templ->tokens); shader->base.prepare = exec_prepare; shader->base.run = exec_run; shader->base.delete = exec_delete; diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 45056502b8..452e51fa79 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -54,9 +54,11 @@ struct tgsi_sampler; struct tgsi_exec_machine; +struct vertex_info; -/** Subclass of pipe_shader_state (though it doesn't really need to be). +/** + * Subclass of pipe_shader_state (though it doesn't really need to be). * * This is starting to look an awful lot like a quad pipeline stage... */ @@ -80,11 +82,10 @@ struct sp_fragment_shader { void (*delete)( struct sp_fragment_shader * ); }; -struct vertex_info; /** Subclass of pipe_shader_state */ struct sp_vertex_shader { - struct pipe_shader_state shader; + struct pipe_shader_state shader; /* Note: this field not actually used */ struct draw_vertex_shader *draw_data; }; diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 9e77b7e91b..24b91fbc79 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -102,10 +102,7 @@ softpipe_create_vs_state(struct pipe_context *pipe, return NULL; } - state->shader = *templ; - - state->draw_data = draw_create_vertex_shader(softpipe->draw, - &state->shader); + state->draw_data = draw_create_vertex_shader(softpipe->draw, templ); if (state->draw_data == NULL) { FREE( state ); return NULL; -- cgit v1.2.3 From aeae57693b31bf42833a9d51844fe92e3ab61034 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 15 May 2008 12:17:46 -0400 Subject: move the swizzling code to gallivm in preperation for code-generating it also some minor cleanups --- src/gallium/auxiliary/draw/draw_vs_llvm.c | 58 +---- src/gallium/auxiliary/gallivm/gallivm.h | 13 +- src/gallium/auxiliary/gallivm/gallivm_builtins.cpp | 267 ++++++++++----------- src/gallium/auxiliary/gallivm/gallivm_cpu.cpp | 56 ++++- src/gallium/auxiliary/gallivm/llvm_builtins.c | 1 - 5 files changed, 201 insertions(+), 194 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index be6907ed04..171da51dd5 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ /* @@ -72,47 +72,9 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, struct draw_llvm_vertex_shader *shader = (struct draw_llvm_vertex_shader *)base; - struct tgsi_exec_machine *machine = shader->machine; - unsigned int i, j; - unsigned slot; - - - for (i = 0; i < count; i += MAX_TGSI_VERTICES) { - unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); - - /* Swizzle inputs. - */ - for (j = 0; j < max_vertices; j++) { - for (slot = 0; slot < base->info.num_inputs; slot++) { - machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; - machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; - machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; - machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; - } - - input = (const float (*)[4])((const char *)input + input_stride); - } - - /* run shader */ - gallivm_cpu_vs_exec(shader->llvm_prog, - machine->Inputs, - machine->Outputs, - (float (*)[4]) constants, - machine->Temps); - - - /* Unswizzle all output results - */ - for (j = 0; j < max_vertices; j++) { - for (slot = 0; slot < base->info.num_outputs; slot++) { - output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; - } - output = (float (*)[4])((char *)output + output_stride); - } - } + gallivm_cpu_vs_exec(shader->llvm_prog, shader->machine, + input, base->info.num_inputs, output, base->info.num_outputs, + constants, count, input_stride, output_stride); } @@ -120,7 +82,7 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, static void vs_llvm_delete( struct draw_vertex_shader *base ) { - struct draw_llvm_vertex_shader *shader = + struct draw_llvm_vertex_shader *shader = (struct draw_llvm_vertex_shader *)base; /* Do something to free compiled shader: @@ -140,7 +102,7 @@ draw_create_vs_llvm(struct draw_context *draw, struct draw_llvm_vertex_shader *vs; vs = CALLOC_STRUCT( draw_llvm_vertex_shader ); - if (vs == NULL) + if (vs == NULL) return NULL; /* we make a private copy of the tokens */ diff --git a/src/gallium/auxiliary/gallivm/gallivm.h b/src/gallium/auxiliary/gallivm/gallivm.h index b4d6555d2f..36a64a7747 100644 --- a/src/gallium/auxiliary/gallivm/gallivm.h +++ b/src/gallium/auxiliary/gallivm/gallivm.h @@ -90,10 +90,15 @@ void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix); struct gallivm_cpu_engine *gallivm_cpu_engine_create(struct gallivm_prog *prog); struct gallivm_cpu_engine *gallivm_global_cpu_engine(); int gallivm_cpu_vs_exec(struct gallivm_prog *prog, - struct tgsi_exec_vector *inputs, - struct tgsi_exec_vector *dests, - float (*consts)[4], - struct tgsi_exec_vector *temps); + struct tgsi_exec_machine *machine, + const float (*input)[4], + unsigned num_inputs, + float (*output)[4], + unsigned num_outputs, + const float (*constants)[4], + unsigned count, + unsigned input_stride, + unsigned output_stride); int gallivm_cpu_fs_exec(struct gallivm_prog *prog, float x, float y, float (*dests)[PIPE_MAX_SHADER_INPUTS][4], diff --git a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp index a6f8cd043b..0fc5c4ec5c 100644 --- a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp @@ -1,141 +1,140 @@ static const unsigned char llvm_builtins_data[] = { -0x42,0x43,0xc0,0xde,0x21,0x0c,0x00,0x00,0x2b,0x02,0x00,0x00,0x01,0x10,0x00,0x00, +0x42,0x43,0xc0,0xde,0x21,0x0c,0x00,0x00,0x29,0x02,0x00,0x00,0x01,0x10,0x00,0x00, 0x10,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,0x06,0x10,0x32,0x39, 0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,0x80,0x14,0x45,0x02, 0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,0x0a,0x32,0x44,0x24, 0x48,0x0a,0x90,0x21,0x23,0x44,0x72,0x80,0x8c,0x14,0x21,0x86,0x0a,0x8a,0x0a,0x64, 0x0c,0x1f,0x00,0x00,0x49,0x18,0x00,0x00,0x02,0x00,0x00,0x00,0x0b,0x04,0x00,0x0c, -0x00,0x00,0x00,0x00,0x51,0x20,0x00,0x00,0x13,0x00,0x00,0x00,0x32,0x22,0x48,0x09, +0x00,0x00,0x00,0x00,0x51,0x20,0x00,0x00,0x12,0x00,0x00,0x00,0x32,0x22,0x48,0x09, 0x20,0x65,0x82,0x84,0x00,0x26,0x45,0x48,0x05,0x09,0x26,0x45,0xc6,0x05,0x42,0x52, -0x26,0x08,0xb0,0x19,0x80,0x61,0x04,0x02,0x98,0x23,0x00,0x83,0x21,0x80,0x39,0x82, -0x60,0x0a,0x80,0x2e,0xd5,0x61,0x04,0x42,0x20,0x49,0x90,0x22,0x4d,0xa2,0x73,0x04, -0x08,0xb9,0x32,0x00,0x00,0x8a,0x10,0xc2,0x65,0xb8,0x42,0x84,0x10,0x42,0x0d,0x44, -0x11,0x00,0x18,0x01,0x28,0x82,0x08,0x00,0x13,0xa2,0x74,0xb0,0x03,0x3c,0xb0,0x83, -0x36,0x80,0x87,0x71,0x68,0x03,0x76,0x48,0x07,0x77,0xa8,0x07,0x7c,0x68,0x83,0x73, -0x70,0x87,0x7a,0xd8,0x70,0x0f,0xe5,0xd0,0x06,0xf0,0xa0,0x07,0x73,0x20,0x07,0x7a, -0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x90,0x0e,0x71,0xa0,0x07,0x78,0xa0, -0x07,0x78,0xd0,0x06,0xe9,0x80,0x07,0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e, -0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x6d,0x90,0x0e,0x73, -0x20,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x90,0x0e,0x76,0x40, -0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0e,0x73,0x20,0x07, -0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,0x0e,0x76,0x40,0x07,0x7a, -0x30,0x07,0x72,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x76,0x40,0x07,0x7a,0x60, -0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x71,0x20,0x07,0x78,0xa0,0x07, -0x71,0x20,0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xd0,0x06,0xe1,0x00,0x07,0x7a, -0x00,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xe6,0x80,0x07,0x70,0xa0,0x07,0x71,0x20, -0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xa0,0xf3,0x40,0x88,0x04,0x32,0x32,0x02, -0x04,0x60,0x76,0xc6,0xfc,0x6c,0x48,0xa2,0x00,0x40,0x00,0x00,0x00,0x00,0x0c,0x49, -0x14,0x20,0x00,0x00,0x00,0x00,0x80,0x21,0xc9,0x02,0x00,0x01,0x00,0x00,0x00,0x30, -0x24,0x61,0x00,0x20,0x08,0x00,0x00,0x00,0x86,0x24,0x0b,0x00,0x04,0x00,0x00,0x00, -0xc0,0x90,0xa4,0x01,0x02,0x00,0x00,0x00,0x00,0x18,0x92,0x1c,0x40,0x00,0x00,0x00, -0x00,0x00,0x43,0x92,0x05,0x00,0x02,0x00,0x00,0x00,0x60,0x48,0x72,0x00,0x01,0x00, -0x00,0x00,0x00,0x0c,0x49,0x16,0x00,0x08,0x00,0x00,0x00,0x80,0x21,0x89,0x01,0x00, -0x41,0x00,0x00,0x00,0x90,0x05,0x02,0x00,0x10,0x00,0x00,0x00,0x32,0x1e,0x98,0x10, -0x19,0x11,0x4c,0x90,0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x92,0x8a,0x59,0x8b,0x43, -0x50,0xd2,0x09,0x02,0x81,0xd2,0x73,0x50,0xc9,0x0c,0x2a,0x99,0x41,0x25,0x33,0xa8, -0x64,0x56,0x28,0x66,0x2d,0x0e,0x41,0xcf,0x2a,0x15,0x04,0x4a,0xcf,0x41,0x25,0x33, -0xa8,0x64,0x06,0x95,0xcc,0xa0,0x92,0x59,0x01,0x00,0x00,0x00,0x53,0x82,0x26,0x0c, -0x04,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00, -0x05,0x00,0x00,0x00,0x04,0xc6,0x08,0x40,0x10,0x04,0xe1,0x70,0x18,0x23,0x00,0x41, -0x10,0x84,0xc3,0x60,0x04,0x00,0x00,0x00,0x93,0x0c,0xce,0x43,0x4c,0x31,0x3c,0x8e, -0x34,0xc9,0x30,0x41,0xc2,0x14,0x03,0x34,0x51,0x93,0x0c,0x4d,0x44,0x4c,0x31,0x44, -0x8d,0x35,0x56,0x01,0x04,0xc3,0x55,0x21,0x16,0x0e,0x04,0x00,0x0f,0x00,0x00,0x00, -0x46,0x41,0x08,0xcc,0x73,0x9b,0x05,0x21,0x30,0xcf,0x6e,0x18,0x84,0x00,0x2c,0x8b, -0x35,0x04,0x80,0x39,0x04,0x81,0x5d,0x20,0x80,0x0f,0x0c,0x43,0xe4,0xd3,0x36,0x81, -0x04,0x3e,0x30,0x0c,0x91,0x4f,0x5b,0x05,0x12,0xf8,0xc0,0x30,0x44,0x7e,0x7d,0x00, -0x05,0xd1,0x4c,0x11,0x66,0x12,0x83,0xc0,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x61,0x20,0x00,0x00,0x2a,0x00,0x00,0x00,0x13,0x04,0x43,0x2c,0x10,0x00,0x00,0x00, -0x08,0x00,0x00,0x00,0x24,0x8a,0xa0,0x0c,0x46,0x00,0x4a,0x80,0xc2,0x1c,0x84,0x55, -0x55,0xd6,0x1c,0x84,0x45,0x51,0x16,0x81,0x19,0x80,0x11,0x80,0x31,0x02,0x10,0x04, -0x41,0xfc,0x03,0x00,0x63,0x08,0x0d,0x34,0xc9,0x70,0x55,0xc2,0x2c,0x43,0x20,0x60, -0x73,0x0c,0xd3,0x15,0x8d,0x21,0x34,0xd1,0x18,0x42,0xf3,0x8c,0x55,0x00,0x81,0xa0, -0x6d,0x73,0x0c,0x19,0xe7,0x60,0x87,0x52,0x38,0x10,0x00,0x00,0x13,0x00,0x00,0x00, -0x17,0x60,0x20,0xc5,0x74,0x10,0x8d,0x65,0x14,0x13,0xf3,0xd4,0xb4,0x6d,0x14,0x13, -0xf3,0xd4,0xb8,0x69,0x14,0x13,0xf3,0xd4,0xb6,0x75,0x14,0x13,0xf3,0xd4,0xba,0x35, -0x0c,0x13,0xf3,0x9c,0x80,0xe4,0x36,0x48,0x81,0x10,0xc3,0x4a,0x4c,0x54,0xd4,0x6c, -0x8b,0x23,0x28,0x76,0x41,0x4c,0xcc,0xa3,0x1b,0x07,0x21,0x00,0xcb,0x72,0x00,0x05, -0xd1,0x4c,0x11,0x66,0x18,0x83,0xc0,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x61,0x20,0x00,0x00,0x82,0x00,0x00,0x00,0x13,0x04,0x47,0x2c,0x10,0x00,0x00,0x00, -0x08,0x00,0x00,0x00,0x24,0x46,0x00,0x8a,0xa0,0x0c,0x4a,0xa0,0x14,0x8a,0xa1,0x1c, -0x68,0x8c,0x00,0x10,0x9a,0x83,0x80,0xa8,0x48,0x9a,0x83,0x80,0xa6,0x4a,0x9a,0x83, -0x80,0xa6,0xc8,0x02,0x63,0x08,0x0d,0x64,0xdb,0xc0,0x49,0x06,0xee,0x22,0xc6,0x10, -0x9a,0xc9,0xbc,0x81,0x93,0x0c,0xdf,0x45,0x4c,0x31,0x38,0x4f,0x37,0xcb,0x10,0x08, -0x60,0x30,0xc8,0x10,0x06,0x0e,0x36,0x86,0xd0,0x44,0x36,0x06,0x03,0x27,0x19,0xc8, -0xe0,0x22,0x66,0x19,0x06,0xa2,0x0c,0x06,0x19,0xc2,0xe0,0xc1,0xc6,0x10,0x9a,0xc8, -0xce,0x60,0xe0,0x24,0x03,0x1a,0x5c,0xc4,0x2c,0xc3,0x40,0xa4,0xc1,0x40,0x45,0x20, -0x06,0x81,0x19,0x08,0x83,0x0c,0x6a,0xe0,0x64,0x63,0x08,0x8d,0x64,0x6c,0x30,0x70, -0x92,0xa1,0x0d,0x2e,0x62,0x96,0xa1,0x30,0xdc,0x60,0xa0,0x22,0x10,0x83,0xc0,0x0c, -0x84,0x41,0x86,0x37,0x78,0xb2,0x31,0x84,0x46,0xb2,0x38,0x18,0x38,0xc9,0x20,0x07, -0x17,0x31,0xcb,0x50,0x18,0x73,0x30,0x50,0x11,0xac,0xc1,0x00,0x07,0xc4,0x20,0x03, -0x1d,0x38,0x1a,0xd6,0xc1,0x40,0x45,0xb0,0x06,0x03,0x1c,0x10,0x83,0x0c,0x76,0xf0, -0x68,0x78,0x07,0xe1,0x40,0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x56,0x62,0x08,0xcc, -0x63,0xef,0x3a,0xa9,0x00,0x19,0x7b,0x73,0x23,0x73,0xf9,0xa1,0x91,0x31,0x98,0x62, -0x62,0x9e,0x7b,0xb7,0x06,0x62,0x62,0x1e,0xda,0x1c,0x88,0x89,0x79,0x6a,0x7b,0x20, -0x26,0xe6,0xb1,0x6d,0x83,0x98,0x98,0xe7,0x36,0x92,0x43,0x70,0x9a,0xca,0xd6,0x73, -0xa3,0x79,0x26,0xe6,0xb9,0x77,0x3f,0x22,0x0c,0x9b,0x21,0x18,0x9f,0xb6,0x90,0x64, -0x62,0x9e,0xda,0x9f,0x98,0xc7,0x36,0x9b,0x67,0x62,0x9e,0x7b,0xf7,0x23,0xc2,0xb0, -0x19,0x82,0xf1,0x6b,0x53,0x79,0x26,0xe6,0xb1,0x6f,0x3f,0x22,0x0c,0x9b,0x21,0x18, -0x9f,0xb6,0x98,0x62,0x62,0x9e,0xbb,0xb7,0x97,0x67,0x62,0x1e,0xfb,0xf6,0x23,0xc2, -0xb0,0x19,0x82,0xf1,0x6b,0x43,0x31,0x04,0xa7,0xa9,0x6c,0xdd,0x66,0x0a,0x81,0x79, -0xf0,0xfa,0x08,0x16,0xc1,0x69,0x06,0x5f,0x70,0x9a,0xe9,0xc6,0x49,0x01,0xc8,0xd8, -0x9b,0x1b,0x99,0xcb,0x4f,0x0c,0x8d,0xad,0x18,0x13,0xf3,0xdc,0x3b,0x6f,0x35,0xc7, -0xc4,0x3c,0x79,0x5d,0xdf,0x06,0x52,0x08,0xcc,0x53,0xdf,0x26,0x62,0x4c,0xcc,0x63, -0xdf,0xb7,0xb9,0x1c,0x02,0xf3,0xe0,0x75,0x5d,0x5b,0xc7,0x20,0x30,0x8f,0x79,0x14, -0x13,0xf3,0xd4,0xf5,0x19,0x2c,0x82,0xd3,0x0c,0xbe,0xe0,0x34,0x13,0xce,0x5b,0x0b, -0x22,0x38,0x4d,0x85,0xd3,0x35,0x6d,0x37,0xc5,0xc4,0x3c,0x79,0x4d,0x1a,0x40,0xc6, -0xde,0xdc,0xc8,0x5c,0x7e,0x64,0x70,0x8c,0x83,0x10,0x9c,0xa6,0xb2,0x94,0x42,0x60, -0x1e,0x7b,0x37,0x19,0x43,0x70,0x9a,0x0a,0xa7,0xcd,0xa4,0x98,0x98,0xc7,0xbe,0x8d, -0xc5,0x98,0x98,0xe7,0xee,0x7b,0x3b,0x29,0x26,0xe6,0xb1,0xf3,0x13,0x58,0x04,0xa7, -0x19,0x7c,0xc1,0x69,0x26,0x9b,0xb6,0x0f,0x43,0x70,0x9a,0xaa,0xb6,0x6d,0xc4,0x98, -0x98,0xc7,0xce,0xf1,0x03,0x28,0x88,0x66,0x8a,0x30,0x00,0x00,0x00,0x00,0x00,0x00, -0x61,0x20,0x00,0x00,0x4a,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00, -0x07,0x00,0x00,0x00,0x24,0xca,0x60,0x04,0xa0,0x04,0x8a,0x80,0xc2,0x0c,0x00,0xbd, -0x61,0x8c,0x04,0x10,0x1e,0xe1,0x19,0xc6,0x48,0x02,0xe1,0x11,0x1e,0x00,0x00,0x00, -0x63,0x08,0xcd,0x63,0xd5,0xc0,0x31,0x84,0x06,0xb2,0x6b,0xe0,0x18,0x42,0x13,0x59, -0x36,0x70,0x0c,0xa1,0x71,0x6c,0x1b,0x38,0x16,0x02,0x04,0xc7,0x64,0x61,0x1a,0x37, -0x16,0x01,0x04,0x48,0x35,0xc7,0x20,0x79,0xcf,0x58,0x04,0x10,0x20,0xd5,0x1c,0xc3, -0x07,0x06,0xd0,0x58,0x04,0x10,0x20,0xd5,0x1c,0x43,0x18,0x88,0x41,0x34,0x16,0x01, -0x04,0x48,0x35,0xc7,0x30,0x06,0x64,0xe0,0x98,0x37,0xd0,0xc0,0x60,0xa0,0x89,0xc1, -0x40,0x23,0x83,0x81,0x63,0x21,0x40,0x70,0x50,0x66,0x70,0x06,0x68,0x90,0x06,0x58, -0x06,0xe1,0x40,0x00,0x25,0x00,0x00,0x00,0x56,0x52,0x4c,0xcc,0x73,0xd3,0x56,0x41, -0x4c,0xcc,0x53,0xdb,0x05,0x31,0x31,0xcf,0x6d,0x19,0xc4,0xc4,0x3c,0xba,0x6d,0x10, -0x13,0xf3,0xf4,0xd6,0x41,0x08,0xc0,0xb2,0x18,0x46,0x21,0x38,0x4d,0x85,0x9b,0x46, -0x21,0x38,0x4d,0xb5,0x9b,0x8a,0x21,0x00,0xcb,0x82,0xdf,0x66,0x62,0x08,0x4e,0x53, -0xdd,0xb7,0x9d,0x18,0x82,0xd3,0x54,0xb7,0x6e,0x28,0x86,0xe0,0x34,0xd5,0xdd,0xdb, -0x47,0x31,0x31,0x4f,0x9d,0x9b,0x87,0x21,0x00,0xcb,0x52,0xdf,0x06,0x62,0x08,0xc0, -0xb2,0xd4,0xbc,0x59,0x10,0x82,0xd3,0x54,0x96,0x62,0x08,0x4e,0x53,0xe1,0xb6,0x85, -0x14,0x13,0xf3,0xd8,0xb4,0x8d,0x14,0x13,0xf3,0xd8,0xb9,0x89,0x18,0x02,0xb0,0x2c, -0xf6,0x6d,0x24,0x86,0x00,0x2c,0x8b,0xcd,0x1b,0x87,0x21,0x38,0x4d,0x55,0xd3,0xd6, -0x30,0x54,0xc0,0x72,0x00,0x05,0xd1,0x4c,0x11,0x06,0x00,0x00,0x00,0x00,0x00,0x00, -0x61,0x20,0x00,0x00,0x19,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00, -0x03,0x00,0x00,0x00,0x24,0x4a,0x60,0x04,0x80,0xc2,0x0c,0x00,0x00,0x00,0x00,0x00, -0x63,0x08,0xcd,0x33,0x16,0x01,0x04,0x48,0x34,0xc7,0x00,0x49,0xcf,0x58,0x04,0x10, -0x28,0xd1,0x1c,0xc3,0x44,0x39,0x58,0x85,0x03,0x01,0x00,0x00,0x0a,0x00,0x00,0x00, -0x16,0x41,0x4c,0xcc,0x63,0xdb,0x04,0x31,0x31,0x4f,0x6e,0x0d,0x43,0x05,0x2c,0x07, -0x50,0x10,0xcd,0x14,0x61,0x56,0x41,0x4c,0xcc,0xd3,0x1b,0x45,0x21,0x00,0xcb,0xb2, -0x9b,0x04,0x21,0x00,0xcb,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00, -0x1b,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x03,0x00,0x00,0x00, -0x24,0xca,0x60,0x04,0xa0,0x04,0x8a,0x80,0xc2,0x0c,0x00,0x00,0x63,0x08,0xcd,0x33, -0x16,0x01,0x04,0xca,0x34,0xc7,0x20,0x51,0xcf,0x1c,0x43,0x45,0x41,0x73,0x0c,0x16, -0x15,0xcd,0x31,0x5c,0x94,0x83,0x58,0x38,0x10,0x00,0x00,0x00,0x0b,0x00,0x00,0x00, -0x86,0x51,0x4c,0xcc,0x53,0xe7,0x76,0x51,0x4c,0xcc,0x53,0xdb,0x36,0x41,0x4c,0xcc, -0x63,0x5b,0x05,0x31,0x31,0x8f,0x6e,0x0d,0x43,0x05,0x2c,0x66,0x41,0x4c,0xcc,0xd3, -0x1f,0x40,0x41,0x34,0x53,0x84,0x19,0x05,0x21,0x00,0xcb,0x02,0x00,0x00,0x00,0x00, -0x61,0x20,0x00,0x00,0x2f,0x00,0x00,0x00,0x13,0x04,0x45,0x2c,0x10,0x00,0x00,0x00, -0x03,0x00,0x00,0x00,0x24,0xca,0xa0,0x04,0x46,0x00,0x8a,0x80,0xc0,0x08,0x00,0x00, -0x63,0x08,0x0d,0x34,0xc9,0x30,0x49,0xc4,0x2c,0x03,0x11,0x50,0x63,0x08,0xcd,0x33, -0xc9,0x50,0x49,0xc4,0x2c,0x03,0x21,0x58,0x63,0x08,0x4d,0x34,0xc9,0x70,0x49,0xc4, -0x2c,0x03,0x31,0x60,0x63,0x08,0x8d,0x33,0xc9,0x90,0x49,0x84,0x69,0x22,0x70,0xc3, -0x27,0x1c,0x08,0x00,0x1a,0x00,0x00,0x00,0x96,0x51,0x4c,0xcc,0x53,0xdf,0x66,0x41, -0x08,0xcc,0x83,0xdb,0x04,0x31,0x31,0x4f,0x6d,0x15,0xc4,0xc4,0x3c,0xb7,0x61,0x10, -0x02,0xf3,0xf0,0x47,0x20,0xb9,0x0d,0x52,0x20,0xc4,0xb0,0x12,0x13,0x15,0x35,0xdb, -0xe2,0x08,0x8a,0x5d,0x10,0x13,0xf3,0xec,0x37,0x90,0x2c,0x4e,0xf4,0x47,0x87,0x54, -0xd7,0x17,0x70,0x2c,0x4e,0xf4,0x47,0x87,0x74,0x02,0xc8,0xe2,0x44,0x7f,0x74,0x48, -0xb9,0x69,0x14,0x02,0xf3,0xd4,0xb8,0x6d,0x18,0x11,0x31,0x55,0xc0,0x62,0x0d,0x43, -0x05,0x2c,0x07,0x50,0x10,0xcd,0x14,0x61,0x46,0x31,0x08,0xcc,0x03,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x71,0x20,0x00,0x00,0x12,0x00,0x00,0x00,0x66,0x40,0x54,0x82, -0x23,0x59,0xc2,0x20,0x09,0x92,0x1d,0x18,0x4f,0x84,0x34,0x53,0x61,0x03,0xc4,0xe3, -0x58,0x85,0x05,0x14,0xbe,0x34,0x45,0xb5,0x21,0x10,0x82,0x23,0x15,0x46,0x30,0x2c, -0xc8,0x64,0x02,0x06,0xf0,0x3c,0x91,0x73,0x19,0x00,0xe1,0x4b,0x53,0x64,0x0a,0x84, -0x84,0x34,0x85,0x31,0x10,0x0a,0xb2,0x3c,0x56,0x30,0x08,0xcc,0x63,0x0b,0x44,0x25, -0x21,0x0d,0x00,0x00,0x00,0x00,0x00,0x00}; +0x26,0x08,0xae,0x19,0x80,0x61,0x04,0x02,0x98,0x23,0x00,0x83,0x29,0x80,0x21,0x00, +0xb2,0x73,0x04,0x01,0x51,0x8a,0xf4,0x08,0x92,0xa4,0x39,0x47,0x80,0x50,0x2b,0x03, +0x00,0xa0,0x08,0x21,0x5c,0x46,0x2b,0x44,0x08,0x21,0xd4,0x40,0x14,0x01,0x80,0x11, +0x80,0x22,0x88,0x00,0x13,0xa2,0x74,0xb0,0x03,0x3c,0xb0,0x83,0x36,0x80,0x87,0x71, +0x68,0x03,0x76,0x48,0x07,0x77,0xa8,0x07,0x7c,0x68,0x83,0x73,0x70,0x87,0x7a,0xd8, +0x70,0x0f,0xe5,0xd0,0x06,0xf0,0xa0,0x07,0x73,0x20,0x07,0x7a,0x30,0x07,0x72,0xa0, +0x07,0x73,0x20,0x07,0x6d,0x90,0x0e,0x71,0xa0,0x07,0x78,0xa0,0x07,0x78,0xd0,0x06, +0xe9,0x80,0x07,0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e,0x71,0x60,0x07,0x7a, +0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x6d,0x90,0x0e,0x73,0x20,0x07,0x7a,0x30, +0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x90,0x0e,0x76,0x40,0x07,0x7a,0x30,0x07, +0x72,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0e,0x73,0x20,0x07,0x7a,0x30,0x07,0x72, +0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,0x0e,0x76,0x40,0x07,0x7a,0x30,0x07,0x72,0xa0, +0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x76,0x40,0x07,0x7a,0x60,0x07,0x74,0xa0,0x07, +0x76,0x40,0x07,0x6d,0x60,0x0f,0x71,0x20,0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78, +0xa0,0x07,0x71,0x20,0x07,0x78,0xd0,0x06,0xe1,0x00,0x07,0x7a,0x00,0x07,0x7a,0x60, +0x07,0x74,0xd0,0x06,0xe6,0x80,0x07,0x70,0xa0,0x07,0x71,0x20,0x07,0x78,0xa0,0x07, +0x71,0x20,0x07,0x78,0xa0,0xf3,0x40,0x88,0x04,0x32,0x32,0x02,0x04,0x20,0x76,0x46, +0xfc,0x6c,0x48,0x92,0x00,0x40,0x00,0x00,0x00,0x00,0x0c,0x49,0x12,0x20,0x00,0x00, +0x00,0x00,0x80,0x21,0x89,0x02,0x00,0x01,0x00,0x00,0x00,0x30,0x24,0x59,0x00,0x20, +0x08,0x00,0x00,0x00,0x86,0x24,0x0a,0x00,0x04,0x00,0x00,0x00,0xc0,0x90,0x84,0x01, +0x02,0x00,0x00,0x00,0x00,0x18,0x92,0x1c,0x40,0x00,0x00,0x00,0x00,0x00,0x43,0x12, +0x05,0x00,0x02,0x00,0x00,0x00,0x60,0x48,0x72,0x00,0x01,0x00,0x00,0x00,0x00,0x0c, +0x49,0x14,0x00,0x08,0x00,0x00,0x00,0x80,0x21,0x49,0x01,0x00,0x41,0x00,0x00,0x00, +0x90,0x05,0x02,0x00,0x10,0x00,0x00,0x00,0x32,0x1e,0x98,0x10,0x19,0x11,0x4c,0x90, +0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x8a,0x8a,0x59,0x8b,0x43,0x50,0xd2,0x09,0x02, +0x81,0xd2,0x73,0x50,0xc9,0x0c,0x2a,0x99,0x41,0x25,0x33,0xa8,0x64,0x56,0x28,0x66, +0x2d,0x0e,0x41,0xcf,0x2a,0x15,0x04,0x4a,0xcf,0x41,0x25,0x33,0xa8,0x64,0x06,0x95, +0xcc,0xa0,0x92,0x59,0x01,0x00,0x00,0x00,0x53,0x82,0x26,0x0c,0x04,0x00,0x00,0x00, +0x22,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x05,0x00,0x00,0x00, +0x04,0xc6,0x08,0x40,0x10,0x04,0xe1,0x70,0x18,0x23,0x00,0x41,0x10,0x84,0xc3,0x60, +0x04,0x00,0x00,0x00,0x93,0x0c,0xce,0x43,0x4c,0x31,0x3c,0x8e,0x34,0xc9,0x30,0x41, +0xc2,0x14,0x03,0x34,0x51,0x93,0x0c,0x4d,0x44,0x4c,0x31,0x44,0x8d,0x35,0x56,0x01, +0x04,0xc3,0x55,0x21,0x16,0x0e,0x04,0x00,0x0f,0x00,0x00,0x00,0x46,0x41,0x08,0xcc, +0x73,0x9b,0x05,0x21,0x30,0xcf,0x6e,0x18,0x84,0x00,0x2c,0x8b,0x35,0x04,0x80,0x39, +0x04,0x81,0x5d,0x20,0x80,0x0f,0x0c,0x43,0xe4,0xd3,0x36,0x81,0x04,0x3e,0x30,0x0c, +0x91,0x4f,0x5b,0x05,0x12,0xf8,0xc0,0x30,0x44,0x7e,0x7d,0x00,0x05,0xd1,0x4c,0x11, +0x66,0x12,0x83,0xc0,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00, +0x2a,0x00,0x00,0x00,0x13,0x04,0x43,0x2c,0x10,0x00,0x00,0x00,0x08,0x00,0x00,0x00, +0x24,0x8a,0xa0,0x0c,0x46,0x00,0x4a,0x80,0xc2,0x1c,0x84,0x55,0x55,0xd6,0x1c,0x84, +0x45,0x51,0x16,0x81,0x19,0x80,0x11,0x80,0x31,0x02,0x10,0x04,0x41,0xfc,0x03,0x00, +0x63,0x08,0x0d,0x34,0xc9,0x70,0x55,0xc2,0x2c,0x43,0x20,0x60,0x73,0x0c,0xd3,0x15, +0x8d,0x21,0x34,0xd1,0x18,0x42,0xf3,0x8c,0x55,0x00,0x81,0xa0,0x6d,0x73,0x0c,0x19, +0xe7,0x60,0x87,0x52,0x38,0x10,0x00,0x00,0x13,0x00,0x00,0x00,0x17,0x60,0x20,0xc5, +0x74,0x10,0x8d,0x65,0x14,0x13,0xf3,0xd4,0xb4,0x6d,0x14,0x13,0xf3,0xd4,0xb8,0x69, +0x14,0x13,0xf3,0xd4,0xb6,0x75,0x14,0x13,0xf3,0xd4,0xba,0x35,0x0c,0x13,0xf3,0x9c, +0x80,0xe4,0x36,0x48,0x81,0x10,0xc3,0x4a,0x4c,0x54,0xd4,0x6c,0x8b,0x23,0x28,0x76, +0x41,0x4c,0xcc,0xa3,0x1b,0x07,0x21,0x00,0xcb,0x72,0x00,0x05,0xd1,0x4c,0x11,0x66, +0x18,0x83,0xc0,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00, +0x81,0x00,0x00,0x00,0x13,0x04,0x4d,0x2c,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00, +0x24,0xca,0x60,0x04,0xa0,0x04,0x8a,0x80,0xc2,0x0c,0x00,0x91,0x11,0x00,0x00,0x00, +0x63,0x08,0x4d,0x64,0x16,0xc1,0x49,0x86,0xab,0x22,0x66,0x19,0x02,0x01,0x1b,0x43, +0x70,0xa2,0x59,0x82,0x61,0x0c,0xe1,0x89,0x66,0x09,0x86,0x81,0x0a,0x20,0x0b,0x34, +0x61,0x8e,0x81,0xda,0xa2,0x31,0x84,0x46,0xb2,0x8e,0xe0,0x24,0x83,0x57,0x11,0xb3, +0x0c,0x44,0xf1,0x8d,0x21,0x38,0xd2,0x2c,0x81,0x31,0x86,0xf0,0x48,0xb3,0x04,0xc6, +0x40,0x05,0x00,0x06,0x44,0x18,0x14,0x73,0x0c,0x9c,0x18,0x48,0x63,0x08,0xcd,0x64, +0x64,0x40,0x70,0x92,0xa1,0x0c,0x2a,0x62,0x96,0xe1,0x40,0xcc,0x60,0x0c,0xc1,0x99, +0x66,0x09,0x92,0x31,0x84,0x67,0x9a,0x25,0x48,0x06,0x2a,0x80,0x33,0x38,0xd0,0x00, +0x99,0x63,0x18,0x83,0x34,0x98,0xc6,0x10,0x1a,0xc8,0xd6,0x80,0xe0,0x24,0x03,0x1b, +0x54,0xc4,0x2c,0x83,0xb2,0xb4,0xc1,0x18,0x82,0x03,0xcd,0x12,0x30,0x63,0x08,0x0f, +0x34,0x4b,0xc0,0x0c,0x54,0x00,0x6e,0xa0,0xbc,0xc1,0x32,0xc7,0xa0,0x06,0x70,0x00, +0x61,0x1c,0x84,0x03,0x01,0x00,0x00,0x00,0x4e,0x00,0x00,0x00,0x76,0x52,0x4c,0xcc, +0x73,0xd3,0x24,0x05,0x64,0xec,0xcd,0x8d,0xcc,0xe5,0x87,0x46,0xc6,0x50,0x8a,0x89, +0x79,0xee,0xdb,0x54,0x8a,0x89,0x79,0xee,0xdd,0x1a,0x88,0x89,0x79,0x68,0x73,0x20, +0x26,0xe6,0xa9,0xed,0x81,0x98,0x98,0xc7,0x36,0x0b,0x62,0x62,0x9e,0xdb,0x32,0x88, +0x89,0x79,0x72,0xd3,0x20,0x26,0xe6,0xd9,0x8d,0x83,0x98,0x98,0xa7,0xb7,0x95,0x62, +0x62,0x9e,0xbb,0x27,0x2d,0x20,0x63,0x6f,0x6e,0x64,0x2e,0x3a,0x34,0x35,0x56,0x62, +0x08,0x4e,0x53,0xd9,0xba,0xb5,0x14,0x02,0xf3,0xe0,0xf5,0x25,0x2c,0x82,0xd3,0x0c, +0xbe,0xe0,0x34,0xd3,0x8d,0x9b,0x88,0x21,0x38,0xcd,0x60,0xd7,0x24,0x01,0x63,0xec, +0xcd,0x8d,0xcc,0x45,0x87,0x44,0x80,0x8c,0xbd,0xb9,0x91,0xb9,0xfc,0xc4,0xd0,0x90, +0x02,0x8c,0xb1,0x37,0x37,0x32,0x97,0x1f,0x73,0x29,0x26,0xe6,0xc1,0x71,0x7b,0x29, +0x26,0xe6,0xc1,0x77,0xfb,0x28,0x04,0xe6,0xa9,0x6f,0x52,0x01,0x32,0xf6,0xe6,0x46, +0xe6,0xa2,0x13,0x73,0x63,0x18,0x83,0xc0,0x3c,0xb6,0x41,0x08,0x4e,0x33,0x58,0x47, +0x31,0x31,0x4f,0x5d,0x1f,0xc3,0x22,0x38,0xcd,0xe0,0x0b,0x4e,0x33,0xe1,0xbc,0xa5, +0x18,0x82,0xd3,0x0c,0x77,0x6e,0x20,0xc5,0xc4,0x3c,0xb5,0x4e,0x3a,0x40,0xc6,0xde, +0xdc,0xc8,0x5c,0x7e,0x64,0x70,0x2c,0xa4,0x98,0x98,0xa7,0xee,0xed,0x82,0x10,0x9c, +0xa6,0xba,0x81,0x44,0x70,0x9a,0xc1,0x17,0x9c,0x66,0x32,0x93,0x42,0x60,0x1e,0x7b, +0xb7,0x98,0x62,0x62,0x9e,0xbc,0x36,0x16,0x43,0x70,0x9a,0x0a,0xa7,0x6d,0xa4,0x98, +0x98,0xc7,0xbe,0x8d,0xa4,0x98,0x98,0xc7,0xce,0x0d,0xc6,0x10,0x9c,0x66,0xc0,0x7b, +0x12,0x02,0x32,0xf6,0xe6,0x46,0xe6,0xa2,0x33,0x13,0x73,0x06,0x8b,0xe0,0x34,0x83, +0x2f,0x38,0xcd,0x64,0xd3,0xe6,0x61,0x08,0x4e,0x53,0xd5,0xf6,0x01,0x14,0x44,0x33, +0x45,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00,0x4a,0x00,0x00,0x00, +0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x24,0xca,0x60,0x04, +0xa0,0x04,0x8a,0x80,0xc2,0x0c,0x00,0xb9,0x61,0x0c,0x04,0x10,0x1e,0xe1,0x19,0xc6, +0x40,0x02,0xe1,0x11,0x1e,0x00,0x00,0x00,0x63,0x08,0xcd,0x63,0x15,0xc1,0x31,0x84, +0x06,0xb2,0x8b,0xe0,0x18,0x42,0x13,0x59,0x46,0x70,0x0c,0xa1,0x71,0x6c,0x23,0x38, +0x16,0x02,0x04,0xc7,0x64,0x61,0x1a,0x37,0x16,0x01,0x04,0x48,0x35,0xc7,0x20,0x79, +0xcf,0x58,0x04,0x10,0x20,0xd5,0x1c,0xc3,0x07,0x06,0xd0,0x58,0x04,0x10,0x20,0xd5, +0x1c,0x43,0x18,0x88,0x41,0x34,0x16,0x01,0x04,0x48,0x35,0xc7,0x30,0x06,0x64,0xe0, +0x98,0x47,0xd0,0xc0,0x80,0xa0,0x89,0x01,0x41,0x23,0x03,0x82,0x63,0x21,0x40,0x70, +0x50,0x66,0x70,0x06,0x68,0x90,0x06,0x58,0x06,0xe1,0x40,0x00,0x25,0x00,0x00,0x00, +0x56,0x52,0x4c,0xcc,0x73,0xd3,0x56,0x41,0x4c,0xcc,0x53,0xdb,0x05,0x31,0x31,0xcf, +0x6d,0x19,0xc4,0xc4,0x3c,0xba,0x6d,0x10,0x13,0xf3,0xf4,0xd6,0x41,0x08,0xc0,0xb2, +0x18,0x46,0x21,0x38,0x4d,0x85,0x9b,0x46,0x21,0x38,0x4d,0xb5,0x9b,0x8a,0x21,0x00, +0xcb,0x82,0xdf,0x66,0x62,0x08,0x4e,0x53,0xdd,0xb7,0x9d,0x18,0x82,0xd3,0x54,0xb7, +0x6e,0x28,0x86,0xe0,0x34,0xd5,0xdd,0xdb,0x47,0x31,0x31,0x4f,0x9d,0x9b,0x87,0x21, +0x00,0xcb,0x52,0xdf,0x06,0x62,0x08,0xc0,0xb2,0xd4,0xbc,0x59,0x10,0x82,0xd3,0x54, +0x96,0x62,0x08,0x4e,0x53,0xe1,0xb6,0x85,0x14,0x13,0xf3,0xd8,0xb4,0x8d,0x14,0x13, +0xf3,0xd8,0xb9,0x89,0x18,0x02,0xb0,0x2c,0xf6,0x6d,0x24,0x86,0x00,0x2c,0x8b,0xcd, +0x1b,0x87,0x21,0x38,0x4d,0x55,0xd3,0xd6,0x30,0x54,0xc0,0x72,0x00,0x05,0xd1,0x4c, +0x11,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00,0x19,0x00,0x00,0x00, +0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x24,0x4a,0x60,0x04, +0x80,0xc2,0x0c,0x00,0x00,0x00,0x00,0x00,0x63,0x08,0xcd,0x33,0x16,0x01,0x04,0x48, +0x34,0xc7,0x00,0x49,0xcf,0x58,0x04,0x10,0x28,0xd1,0x1c,0xc3,0x44,0x39,0x58,0x85, +0x03,0x01,0x00,0x00,0x0a,0x00,0x00,0x00,0x16,0x41,0x4c,0xcc,0x63,0xdb,0x04,0x31, +0x31,0x4f,0x6e,0x0d,0x43,0x05,0x2c,0x07,0x50,0x10,0xcd,0x14,0x61,0x56,0x41,0x4c, +0xcc,0xd3,0x1b,0x45,0x21,0x00,0xcb,0xb2,0x9b,0x04,0x21,0x00,0xcb,0x02,0x00,0x00, +0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00,0x1b,0x00,0x00,0x00,0x13,0x04,0x41,0x2c, +0x10,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x24,0xca,0x60,0x04,0xa0,0x04,0x8a,0x80, +0xc2,0x0c,0x00,0x00,0x63,0x08,0xcd,0x33,0x16,0x01,0x04,0xca,0x34,0xc7,0x20,0x51, +0xcf,0x1c,0x43,0x45,0x41,0x73,0x0c,0x16,0x15,0xcd,0x31,0x5c,0x94,0x83,0x58,0x38, +0x10,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x86,0x51,0x4c,0xcc,0x53,0xe7,0x76,0x51, +0x4c,0xcc,0x53,0xdb,0x36,0x41,0x4c,0xcc,0x63,0x5b,0x05,0x31,0x31,0x8f,0x6e,0x0d, +0x43,0x05,0x2c,0x66,0x41,0x4c,0xcc,0xd3,0x1f,0x40,0x41,0x34,0x53,0x84,0x19,0x05, +0x21,0x00,0xcb,0x02,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00,0x2f,0x00,0x00,0x00, +0x13,0x04,0x45,0x2c,0x10,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x24,0xca,0xa0,0x04, +0x46,0x00,0x8a,0x80,0xc0,0x08,0x00,0x00,0x63,0x08,0x0d,0x34,0xc9,0x30,0x49,0xc4, +0x2c,0x03,0x11,0x50,0x63,0x08,0xcd,0x33,0xc9,0x50,0x49,0xc4,0x2c,0x03,0x21,0x58, +0x63,0x08,0x4d,0x34,0xc9,0x70,0x49,0xc4,0x2c,0x03,0x31,0x60,0x63,0x08,0x8d,0x33, +0xc9,0x90,0x49,0x84,0x69,0x22,0x70,0xc3,0x27,0x1c,0x08,0x00,0x1a,0x00,0x00,0x00, +0x96,0x51,0x4c,0xcc,0x53,0xdf,0x66,0x41,0x08,0xcc,0x83,0xdb,0x04,0x31,0x31,0x4f, +0x6d,0x15,0xc4,0xc4,0x3c,0xb7,0x61,0x10,0x02,0xf3,0xf0,0x47,0x20,0xb9,0x0d,0x52, +0x20,0xc4,0xb0,0x12,0x13,0x15,0x35,0xdb,0xe2,0x08,0x8a,0x5d,0x10,0x13,0xf3,0xec, +0x37,0x90,0x2c,0x4e,0xf4,0x47,0x87,0x54,0xd7,0x17,0x70,0x2c,0x4e,0xf4,0x47,0x87, +0x74,0x02,0xc8,0xe2,0x44,0x7f,0x74,0x48,0xb9,0x69,0x14,0x02,0xf3,0xd4,0xb8,0x6d, +0x18,0x11,0x31,0x55,0xc0,0x62,0x0d,0x43,0x05,0x2c,0x07,0x50,0x10,0xcd,0x14,0x61, +0x46,0x31,0x08,0xcc,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x71,0x20,0x00,0x00, +0x12,0x00,0x00,0x00,0x66,0x40,0x54,0x82,0x23,0x59,0xc2,0x20,0x09,0x92,0x1d,0x18, +0x4f,0x84,0x34,0x53,0x61,0x03,0xc4,0xe3,0x58,0x85,0x05,0x14,0xbe,0x34,0x45,0xb5, +0x21,0x10,0x82,0x23,0x15,0x46,0x30,0x2c,0xc8,0x64,0x02,0x06,0xf0,0x3c,0x91,0x73, +0x19,0x00,0xe1,0x4b,0x53,0x64,0x0a,0x84,0x84,0x34,0x85,0x31,0x10,0x0a,0xb2,0x3c, +0x56,0x30,0x08,0xcc,0x63,0x0b,0x44,0x25,0x21,0x0d,0x00,0x00,0x00,0x00,0x00,0x00}; diff --git a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp index 8f9830d0b1..857c190f7b 100644 --- a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp @@ -41,6 +41,7 @@ #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" +#include "pipe/p_util.h" #include "tgsi/exec/tgsi_exec.h" #include "tgsi/util/tgsi_dump.h" @@ -179,22 +180,63 @@ typedef void (*vertex_shader_runner)(void *ainputs, float (*aconsts)[4], void *temps); - +#define MAX_TGSI_VERTICES 4 /*! This function is used to execute the gallivm_prog in software. Before calling this function the gallivm_prog has to be JIT compiled with the gallivm_cpu_jit_compile function. */ int gallivm_cpu_vs_exec(struct gallivm_prog *prog, - struct tgsi_exec_vector *inputs, - struct tgsi_exec_vector *dests, - float (*consts)[4], - struct tgsi_exec_vector *temps) + struct tgsi_exec_machine *machine, + const float (*input)[4], + unsigned num_inputs, + float (*output)[4], + unsigned num_outputs, + const float (*constants)[4], + unsigned count, + unsigned input_stride, + unsigned output_stride ) { + unsigned int i, j; + unsigned slot; vertex_shader_runner runner = reinterpret_cast(prog->function); + assert(runner); - /*FIXME*/ - runner(inputs, dests, consts, temps); + + for (i = 0; i < count; i += MAX_TGSI_VERTICES) { + unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); + + /* Swizzle inputs. + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < num_inputs; slot++) { + machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; + machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; + machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; + machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; + } + + input = (const float (*)[4])((const char *)input + input_stride); + } + + /* run shader */ + runner(machine->Inputs, + machine->Outputs, + (float (*)[4]) constants, + machine->Temps); + + /* Unswizzle all output results + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < num_outputs; slot++) { + output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + output = (float (*)[4])((char *)output + output_stride); + } + } return 0; } diff --git a/src/gallium/auxiliary/gallivm/llvm_builtins.c b/src/gallium/auxiliary/gallivm/llvm_builtins.c index 64b5d499a8..6b9d626ed4 100644 --- a/src/gallium/auxiliary/gallivm/llvm_builtins.c +++ b/src/gallium/auxiliary/gallivm/llvm_builtins.c @@ -1,4 +1,3 @@ -/*clang --emit-llvm llvm_builtins.c |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=gallivm_builtins.cpp -f -for=shader -funcname=createGallivmBuiltins*/ /************************************************************************** * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. -- cgit v1.2.3 From 735752e8dceeec9b202147d1d19ef3dc70e08673 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 15 May 2008 14:11:19 -0400 Subject: fix injections of functions from builtins into shaders --- src/gallium/auxiliary/gallivm/gallivm.cpp | 3 --- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 18 +++++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/gallivm.cpp b/src/gallium/auxiliary/gallivm/gallivm.cpp index b6f641a3f8..48a3b18cdc 100644 --- a/src/gallium/auxiliary/gallivm/gallivm.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm.cpp @@ -288,10 +288,7 @@ void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, std::cout << "Creating llvm from: " <module = mod; gallivm_ir_dump(ir, 0); } diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index f0122802db..17e876e32d 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -38,7 +38,6 @@ #include #include #include -//#include #include #include @@ -193,9 +192,13 @@ llvm::Function * InstructionsSoa::function(int op) std::string name = m_functionsMap[op]; + std::cout <<"For op = "< deps = m_builtinDependencies[name]; for (unsigned int i = 0; i < deps.size(); ++i) { - injectFunction(m_builtins->getFunction(deps[i])); + llvm::Function *func = m_builtins->getFunction(deps[i]); + std::cout <<"\tinjecting dep = '"<getName()<<"'"<getFunction(name); @@ -216,8 +219,10 @@ void InstructionsSoa::createBuiltins() { MemoryBuffer *buffer = MemoryBuffer::getMemBuffer( (const char*)&soabuiltins_data[0], - (const char*)&soabuiltins_data[Elements(soabuiltins_data)-1]); + (const char*)&soabuiltins_data[Elements(soabuiltins_data)]); m_builtins = ParseBitcodeFile(buffer); + std::cout<<"Builtins created at "<isDeclaration()) { - std::cout << "function decleration" <getFunctionType(), GlobalValue::ExternalLinkage, originalFunc->getName(), currentModule()); func->setCallingConv(CallingConv::C); @@ -398,17 +402,17 @@ void InstructionsSoa::injectFunction(llvm::Function *originalFunc, int op) } else { DenseMap val; val[m_builtins->getFunction("powf")] = currentModule()->getFunction("powf"); + func = CloneFunction(originalFunc, val); +#if 0 std::cout <<" replacing "<getFunction("powf") <<", with " <getFunction("powf")<getFunctionList().push_back(func); - std::cout << "Func parent is "<getParent() - <<", cur is "< Date: Thu, 15 May 2008 17:46:20 -0400 Subject: llvm: implement sub and abs --- src/gallium/auxiliary/gallivm/gallivm.cpp | 6 ++-- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 35 +++++++++++++++++++-- src/gallium/auxiliary/gallivm/instructionssoa.h | 3 ++ src/gallium/auxiliary/gallivm/soabuiltins.c | 38 ++++++++++++++++------- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 2 ++ 5 files changed, 67 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/gallivm.cpp b/src/gallium/auxiliary/gallivm/gallivm.cpp index 48a3b18cdc..77900e342b 100644 --- a/src/gallium/auxiliary/gallivm/gallivm.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm.cpp @@ -303,11 +303,11 @@ struct gallivm_prog * gallivm_ir_compile(struct gallivm_ir *ir) { struct gallivm_prog *prog = (struct gallivm_prog *)calloc(1, sizeof(struct gallivm_prog)); - + std::cout << "Before optimizations:"<module->dump(); std::cout<<"-------------------------------"<module); @@ -315,7 +315,7 @@ struct gallivm_prog * gallivm_ir_compile(struct gallivm_ir *ir) prog->num_consts = ir->num_consts; memcpy(prog->interpolators, ir->interpolators, sizeof(prog->interpolators)); prog->num_interp = ir->num_interp; - + /* Run optimization passes over it */ PassManager passes; passes.add(new TargetData(mod)); diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 17e876e32d..4520559ba2 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -173,6 +173,7 @@ std::vector InstructionsSoa::extractVector(llvm::Value *vector) void InstructionsSoa::createFunctionMap() { + m_functionsMap[TGSI_OPCODE_ABS] = "abs"; m_functionsMap[TGSI_OPCODE_DP3] = "dp3"; m_functionsMap[TGSI_OPCODE_DP4] = "dp4"; m_functionsMap[TGSI_OPCODE_POWER] = "pow"; @@ -180,9 +181,16 @@ void InstructionsSoa::createFunctionMap() void InstructionsSoa::createDependencies() { - std::vector powDeps(1); - powDeps[0] = "powf"; - m_builtinDependencies["pow"] = powDeps; + { + std::vector powDeps(1); + powDeps[0] = "powf"; + m_builtinDependencies["pow"] = powDeps; + } + { + std::vector absDeps(1); + absDeps[0] = "fabsf"; + m_builtinDependencies["abs"] = absDeps; + } } llvm::Function * InstructionsSoa::function(int op) @@ -226,6 +234,13 @@ void InstructionsSoa::createBuiltins() createDependencies(); } + +std::vector InstructionsSoa::abs(const std::vector in1) +{ + llvm::Function *func = function(TGSI_OPCODE_ABS); + return callBuiltin(func, in1); +} + std::vector InstructionsSoa::dp3(const std::vector in1, const std::vector in2) { @@ -418,3 +433,17 @@ void InstructionsSoa::injectFunction(llvm::Function *originalFunc, int op) m_functions[op] = func; } } + +std::vector InstructionsSoa::sub(const std::vector in1, + const std::vector in2) +{ + std::vector res(4); + + res[0] = m_builder.CreateSub(in1[0], in2[0], name("subx")); + res[1] = m_builder.CreateSub(in1[1], in2[1], name("suby")); + res[2] = m_builder.CreateSub(in1[2], in2[2], name("subz")); + res[3] = m_builder.CreateSub(in1[3], in2[3], name("subw")); + + return res; +} + diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h index 060ee72f2e..02e5fab51f 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -48,6 +48,7 @@ public: InstructionsSoa(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, StorageSoa *storage); + std::vector abs(const std::vector in1); std::vector arl(const std::vector in); std::vector add(const std::vector in1, const std::vector in2); @@ -62,6 +63,8 @@ public: const std::vector in2); std::vector pow(const std::vector in1, const std::vector in2); + std::vector sub(const std::vector in1, + const std::vector in2); void end(); std::vector extractVector(llvm::Value *vector); diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c index 40addebd8c..f04e4c974d 100644 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -33,6 +33,33 @@ */ typedef __attribute__(( ext_vector_type(4) )) float float4; + +extern float fabsf(float val); + +void abs(float4 *res, + float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w) +{ + res[0].x = fabsf(tmp0x.x); + res[0].y = fabsf(tmp0x.y); + res[0].z = fabsf(tmp0x.z); + res[0].w = fabsf(tmp0x.w); + + res[1].x = fabsf(tmp0y.x); + res[1].y = fabsf(tmp0y.y); + res[1].z = fabsf(tmp0y.z); + res[1].w = fabsf(tmp0y.w); + + res[2].x = fabsf(tmp0z.x); + res[2].y = fabsf(tmp0z.y); + res[2].z = fabsf(tmp0z.z); + res[2].w = fabsf(tmp0z.w); + + res[3].x = fabsf(tmp0w.x); + res[3].y = fabsf(tmp0w.y); + res[3].z = fabsf(tmp0w.z); + res[3].w = fabsf(tmp0w.w); +} + void dp3(float4 *res, float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) @@ -77,14 +104,3 @@ void pow(float4 *res, res[2] = p; res[3] = p; } - -#if 0 -void yo(float4 *out, float4 *in) -{ - float4 res[4]; - - dp3(res, in[0], in[1], in[2], in[3], - in[4], in[5], in[6], in[7]); - out[1] = res[1]; -} -#endif diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index ab8c851f14..5465d3a95e 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -740,6 +740,7 @@ translate_instructionir(llvm::Module *module, } break; case TGSI_OPCODE_SUB: { + out = instr->sub(inputs[0], inputs[1]); } break; case TGSI_OPCODE_LERP: { @@ -781,6 +782,7 @@ translate_instructionir(llvm::Module *module, case TGSI_OPCODE_MULTIPLYMATRIX: break; case TGSI_OPCODE_ABS: { + out = instr->abs(inputs[0]); } break; case TGSI_OPCODE_RCC: -- cgit v1.2.3 From ea1a607292ef31df70cda8c6476755e0224c9f7d Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 16 May 2008 14:54:40 -0400 Subject: implement min/max and abstract ops on vectors --- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 30 ++++++++- src/gallium/auxiliary/gallivm/instructionssoa.h | 4 ++ src/gallium/auxiliary/gallivm/soabuiltins.c | 75 ++++++++++++++++++++--- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 2 + 4 files changed, 100 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 4520559ba2..55fdda2791 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -176,14 +176,17 @@ void InstructionsSoa::createFunctionMap() m_functionsMap[TGSI_OPCODE_ABS] = "abs"; m_functionsMap[TGSI_OPCODE_DP3] = "dp3"; m_functionsMap[TGSI_OPCODE_DP4] = "dp4"; + m_functionsMap[TGSI_OPCODE_MIN] = "min"; + m_functionsMap[TGSI_OPCODE_MAX] = "max"; m_functionsMap[TGSI_OPCODE_POWER] = "pow"; } void InstructionsSoa::createDependencies() { { - std::vector powDeps(1); + std::vector powDeps(2); powDeps[0] = "powf"; + powDeps[1] = "powvec"; m_builtinDependencies["pow"] = powDeps; } { @@ -191,6 +194,16 @@ void InstructionsSoa::createDependencies() absDeps[0] = "fabsf"; m_builtinDependencies["abs"] = absDeps; } + { + std::vector maxDeps(1); + maxDeps[0] = "maxvec"; + m_builtinDependencies["max"] = maxDeps; + } + { + std::vector minDeps(1); + minDeps[0] = "minvec"; + m_builtinDependencies["min"] = minDeps; + } } llvm::Function * InstructionsSoa::function(int op) @@ -374,6 +387,21 @@ std::vector InstructionsSoa::pow(const std::vector i return callBuiltin(func, in1, in2); } +std::vector InstructionsSoa::min(const std::vector in1, + const std::vector in2) +{ + llvm::Function *func = function(TGSI_OPCODE_MIN); + return callBuiltin(func, in1, in2); +} + + +std::vector InstructionsSoa::max(const std::vector in1, + const std::vector in2) +{ + llvm::Function *func = function(TGSI_OPCODE_MAX); + return callBuiltin(func, in1, in2); +} + void checkFunction(Function *func) { for (Function::const_iterator BI = func->begin(), BE = func->end(); diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h index 02e5fab51f..5a7f8fdf72 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -59,6 +59,10 @@ public: std::vector madd(const std::vector in1, const std::vector in2, const std::vector in3); + std::vector max(const std::vector in1, + const std::vector in2); + std::vector min(const std::vector in1, + const std::vector in2); std::vector mul(const std::vector in1, const std::vector in2); std::vector pow(const std::vector in1, diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c index f04e4c974d..935283f962 100644 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -89,18 +89,73 @@ void dp4(float4 *res, extern float powf(float num, float p); +float4 powvec(float4 vec, float4 q) +{ + float4 p; + p.x = powf(vec.x, q.x); + p.y = powf(vec.y, q.y); + p.z = powf(vec.z, q.z); + p.w = powf(vec.w, q.w); + return p; +} + void pow(float4 *res, float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) { - float4 p; - p.x = powf(tmp0x.x, tmp1x.x); - p.y = powf(tmp0x.y, tmp1x.y); - p.z = powf(tmp0x.z, tmp1x.z); - p.w = powf(tmp0x.w, tmp1x.w); - - res[0] = p; - res[1] = p; - res[2] = p; - res[3] = p; + res[0] = powvec(tmp0x, tmp1x); + res[1] = res[0]; + res[2] = res[0]; + res[3] = res[0]; +} + +void lit(float4 *res, + float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, + float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) +{ + const float4 zerovec = (float4) {0, 0, 0, 0}; + float4 tmpx = tmp0x; + float4 tmpy = tmp0y; + + res[0] = (float4){1.0, 1.0, 1.0, 1.0}; + res[1] = tmpx; + res[2] = tmpy; + res[3] = (float4){1.0, 1.0, 1.0, 1.0}; +} + +float4 minvec(float4 a, float4 b) +{ + return (float4){(a.x < b.x) ? a.x : b.x, + (a.y < b.y) ? a.y : b.y, + (a.z < b.z) ? a.z : b.z, + (a.w < b.w) ? a.w : b.w}; +} + +void min(float4 *res, + float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, + float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) +{ + res[0] = minvec(tmp0x, tmp1x); + res[1] = minvec(tmp0y, tmp1y); + res[2] = minvec(tmp0z, tmp1z); + res[3] = minvec(tmp0w, tmp1w); +} + + +float4 maxvec(float4 a, float4 b) +{ + return (float4){(a.x > b.x) ? a.x : b.x, + (a.y > b.y) ? a.y : b.y, + (a.z > b.z) ? a.z : b.z, + (a.w > b.w) ? a.w : b.w}; +} + +void max(float4 *res, + float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, + float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) +{ + res[0] = maxvec(tmp0x, tmp1x); + res[1] = maxvec(tmp0y, tmp1y); + res[2] = maxvec(tmp0z, tmp1z); + res[3] = maxvec(tmp0w, tmp1w); } diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 5465d3a95e..007b5c169a 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -724,9 +724,11 @@ translate_instructionir(llvm::Module *module, } break; case TGSI_OPCODE_MIN: { + out = instr->min(inputs[0], inputs[1]); } break; case TGSI_OPCODE_MAX: { + out = instr->max(inputs[0], inputs[1]); } break; case TGSI_OPCODE_SLT: { -- cgit v1.2.3 From 1d1cf8edf6a0409caf9aa7d44e186eb51f51fa1f Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 16 May 2008 16:06:59 -0400 Subject: do the lit (some artifacts present) --- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 15 +++++++++ src/gallium/auxiliary/gallivm/instructionssoa.h | 1 + src/gallium/auxiliary/gallivm/soabuiltins.c | 37 ++++++++++++++--------- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 1 + 4 files changed, 40 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 55fdda2791..074dd0ecd6 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -179,6 +179,7 @@ void InstructionsSoa::createFunctionMap() m_functionsMap[TGSI_OPCODE_MIN] = "min"; m_functionsMap[TGSI_OPCODE_MAX] = "max"; m_functionsMap[TGSI_OPCODE_POWER] = "pow"; + m_functionsMap[TGSI_OPCODE_LIT] = "lit"; } void InstructionsSoa::createDependencies() @@ -204,6 +205,14 @@ void InstructionsSoa::createDependencies() minDeps[0] = "minvec"; m_builtinDependencies["min"] = minDeps; } + { + std::vector litDeps(4); + litDeps[0] = "minvec"; + litDeps[1] = "maxvec"; + litDeps[2] = "powf"; + litDeps[3] = "powvec"; + m_builtinDependencies["lit"] = litDeps; + } } llvm::Function * InstructionsSoa::function(int op) @@ -475,3 +484,9 @@ std::vector InstructionsSoa::sub(const std::vector i return res; } +std::vector InstructionsSoa::lit(const std::vector in) +{ + llvm::Function *func = function(TGSI_OPCODE_LIT); + return callBuiltin(func, in); +} + diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h index 5a7f8fdf72..477ef4a157 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -56,6 +56,7 @@ public: const std::vector in2); std::vector dp4(const std::vector in1, const std::vector in2); + std::vector lit(const std::vector in); std::vector madd(const std::vector in1, const std::vector in2, const std::vector in3); diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c index 935283f962..b3bfebfe50 100644 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -109,20 +109,6 @@ void pow(float4 *res, res[3] = res[0]; } -void lit(float4 *res, - float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, - float4 tmp1x, float4 tmp1y, float4 tmp1z, float4 tmp1w) -{ - const float4 zerovec = (float4) {0, 0, 0, 0}; - float4 tmpx = tmp0x; - float4 tmpy = tmp0y; - - res[0] = (float4){1.0, 1.0, 1.0, 1.0}; - res[1] = tmpx; - res[2] = tmpy; - res[3] = (float4){1.0, 1.0, 1.0, 1.0}; -} - float4 minvec(float4 a, float4 b) { return (float4){(a.x < b.x) ? a.x : b.x, @@ -159,3 +145,26 @@ void max(float4 *res, res[2] = maxvec(tmp0z, tmp1z); res[3] = maxvec(tmp0w, tmp1w); } + + +void lit(float4 *res, + float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w) +{ + const float4 zerovec = (float4) {0, 0, 0, 0}; + const float4 min128 = (float4) {-128.f, -128.f, -128.f, -128.f}; + const float4 plus128 = (float4) {128.f, 128.f, 128.f, 128.f}; + + res[0] = (float4){1.0, 1.0, 1.0, 1.0}; + if (tmp0x.x > 0) { + float4 tmpx = maxvec(tmpx, zerovec); + float4 tmpy = maxvec(tmp0y, zerovec); + float4 tmpw = minvec(tmp0w, plus128); + tmpw = maxvec(tmpw, min128); + res[1] = tmpx; + res[2] = powvec(tmpy, tmpw); + } else { + res[1] = zerovec; + res[2] = zerovec; + } + res[3] = (float4){1.0, 1.0, 1.0, 1.0}; +} diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 007b5c169a..abcb240f46 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -692,6 +692,7 @@ translate_instructionir(llvm::Module *module, } break; case TGSI_OPCODE_LIT: { + out = instr->lit(inputs[0]); } break; case TGSI_OPCODE_RCP: { -- cgit v1.2.3 From 02e45b2dadd42c38247cb992a07eb520ac86519b Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 16 May 2008 17:10:52 -0400 Subject: fix abs and start on rsq --- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 20 +++++++- src/gallium/auxiliary/gallivm/instructionssoa.h | 1 + src/gallium/auxiliary/gallivm/soabuiltins.c | 56 +++++++++++++++-------- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 1 + 4 files changed, 58 insertions(+), 20 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 074dd0ecd6..76049ade7c 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -180,6 +180,7 @@ void InstructionsSoa::createFunctionMap() m_functionsMap[TGSI_OPCODE_MAX] = "max"; m_functionsMap[TGSI_OPCODE_POWER] = "pow"; m_functionsMap[TGSI_OPCODE_LIT] = "lit"; + m_functionsMap[TGSI_OPCODE_RSQ] = "rsq"; } void InstructionsSoa::createDependencies() @@ -191,8 +192,9 @@ void InstructionsSoa::createDependencies() m_builtinDependencies["pow"] = powDeps; } { - std::vector absDeps(1); + std::vector absDeps(2); absDeps[0] = "fabsf"; + absDeps[1] = "absvec"; m_builtinDependencies["abs"] = absDeps; } { @@ -213,6 +215,14 @@ void InstructionsSoa::createDependencies() litDeps[3] = "powvec"; m_builtinDependencies["lit"] = litDeps; } + { + std::vector rsqDeps(4); + rsqDeps[0] = "sqrtf"; + rsqDeps[1] = "sqrtvec"; + rsqDeps[2] = "fabsf"; + rsqDeps[3] = "absvec"; + m_builtinDependencies["rsq"] = rsqDeps; + } } llvm::Function * InstructionsSoa::function(int op) @@ -453,7 +463,9 @@ void InstructionsSoa::injectFunction(llvm::Function *originalFunc, int op) currentModule()->dump(); } else { DenseMap val; + val[m_builtins->getFunction("fabsf")] = currentModule()->getFunction("fabsf"); val[m_builtins->getFunction("powf")] = currentModule()->getFunction("powf"); + val[m_builtins->getFunction("sqrtf")] = currentModule()->getFunction("sqrtf"); func = CloneFunction(originalFunc, val); #if 0 std::cout <<" replacing "<getFunction("powf") @@ -490,3 +502,9 @@ std::vector InstructionsSoa::lit(const std::vector i return callBuiltin(func, in); } +std::vector InstructionsSoa::rsq(const std::vector in) +{ + llvm::Function *func = function(TGSI_OPCODE_RSQ); + return callBuiltin(func, in); +} + diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h index 477ef4a157..3e20b652dd 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -68,6 +68,7 @@ public: const std::vector in2); std::vector pow(const std::vector in1, const std::vector in2); + std::vector rsq(const std::vector in1); std::vector sub(const std::vector in1, const std::vector in2); void end(); diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c index b3bfebfe50..64c02aa967 100644 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -36,28 +36,24 @@ typedef __attribute__(( ext_vector_type(4) )) float float4; extern float fabsf(float val); +float4 absvec(float4 vec) +{ + float4 res; + res.x = fabsf(vec.x); + res.y = fabsf(vec.y); + res.z = fabsf(vec.z); + res.w = fabsf(vec.w); + + return res; +} + void abs(float4 *res, float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w) { - res[0].x = fabsf(tmp0x.x); - res[0].y = fabsf(tmp0x.y); - res[0].z = fabsf(tmp0x.z); - res[0].w = fabsf(tmp0x.w); - - res[1].x = fabsf(tmp0y.x); - res[1].y = fabsf(tmp0y.y); - res[1].z = fabsf(tmp0y.z); - res[1].w = fabsf(tmp0y.w); - - res[2].x = fabsf(tmp0z.x); - res[2].y = fabsf(tmp0z.y); - res[2].z = fabsf(tmp0z.z); - res[2].w = fabsf(tmp0z.w); - - res[3].x = fabsf(tmp0w.x); - res[3].y = fabsf(tmp0w.y); - res[3].z = fabsf(tmp0w.z); - res[3].w = fabsf(tmp0w.w); + res[0] = absvec(tmp0x); + res[1] = absvec(tmp0y); + res[2] = absvec(tmp0z); + res[3] = absvec(tmp0w); } void dp3(float4 *res, @@ -88,6 +84,7 @@ void dp4(float4 *res, } extern float powf(float num, float p); +extern float sqrtf(float x); float4 powvec(float4 vec, float4 q) { @@ -168,3 +165,24 @@ void lit(float4 *res, } res[3] = (float4){1.0, 1.0, 1.0, 1.0}; } + + +float4 sqrtvec(float4 vec) +{ + float4 p; + p.x = sqrtf(vec.x); + p.y = sqrtf(vec.y); + p.z = sqrtf(vec.z); + p.w = sqrtf(vec.w); + return p; +} + +void rsq(float4 *res, + float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w) +{ + const float4 onevec = (float4) {1., 1., 1., 1.}; + res[0] = onevec/sqrtvec(absvec(tmp0x)); + res[1] = res[0]; + res[2] = res[0]; + res[3] = res[0]; +} diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index abcb240f46..9695358ab8 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -699,6 +699,7 @@ translate_instructionir(llvm::Module *module, } break; case TGSI_OPCODE_RSQ: { + out = instr->rsq(inputs[0]); } break; case TGSI_OPCODE_EXP: -- cgit v1.2.3 From a7449d4d840148ccd9261b59e68d45e9d0d2be53 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 16 May 2008 17:35:47 -0400 Subject: fix rsq --- src/gallium/auxiliary/gallivm/soabuiltins.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c index 64c02aa967..62c75f18f4 100644 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -182,7 +182,7 @@ void rsq(float4 *res, { const float4 onevec = (float4) {1., 1., 1., 1.}; res[0] = onevec/sqrtvec(absvec(tmp0x)); - res[1] = res[0]; - res[2] = res[0]; - res[3] = res[0]; + res[1] = onevec/sqrtvec(absvec(tmp0y)); + res[2] = onevec/sqrtvec(absvec(tmp0z)); + res[3] = onevec/sqrtvec(absvec(tmp0w)); } -- cgit v1.2.3 From 0bf82c0111c9d5e33ffc76be2fd0d22eea316952 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 16 May 2008 17:56:38 -0400 Subject: cosmetic changes --- src/gallium/auxiliary/gallivm/soabuiltins.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c index 62c75f18f4..78f84510e2 100644 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -147,17 +147,16 @@ void max(float4 *res, void lit(float4 *res, float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w) { - const float4 zerovec = (float4) {0, 0, 0, 0}; + const float4 zerovec = (float4) {0.0, 0.0, 0.0, 0.0}; const float4 min128 = (float4) {-128.f, -128.f, -128.f, -128.f}; const float4 plus128 = (float4) {128.f, 128.f, 128.f, 128.f}; res[0] = (float4){1.0, 1.0, 1.0, 1.0}; if (tmp0x.x > 0) { - float4 tmpx = maxvec(tmpx, zerovec); float4 tmpy = maxvec(tmp0y, zerovec); float4 tmpw = minvec(tmp0w, plus128); tmpw = maxvec(tmpw, min128); - res[1] = tmpx; + res[1] = tmp0x; res[2] = powvec(tmpy, tmpw); } else { res[1] = zerovec; -- cgit v1.2.3 From 820fe368635c82ed1c3459b0f23cfd9c0cc762de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 17 May 2008 00:12:43 +0900 Subject: gallium: Fix typo. --- src/gallium/README.portability | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/README.portability b/src/gallium/README.portability index 18a97f449b..d5d5987a7f 100644 --- a/src/gallium/README.portability +++ b/src/gallium/README.portability @@ -6,7 +6,7 @@ The state tracker and winsys driver support a rather limited number of platforms. However, the pipe drivers are meant to run in a wide number of platforms. Hence the pipe drivers, the auxiliary modules, and all public -headers in general, should stricly follow these guidelines to ensure +headers in general, should strictly follow these guidelines to ensure = Compiler Support = -- cgit v1.2.3 From 5ca4f9e97ce153ace0fb8f40c772f44895cb20fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 19 May 2008 14:47:37 +0900 Subject: gallium: Additional formats for bump mapping. --- src/gallium/include/pipe/p_format.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index a4bd23c302..9ba00f8d7b 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -307,6 +307,9 @@ enum pipe_format { PIPE_FORMAT_R8G8B8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SNORM ), PIPE_FORMAT_R8G8B8A8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ), PIPE_FORMAT_R8G8B8X8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_B6G5R5_SNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_BGR1, 6, 5, 5, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_A8B8G8R8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGRA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_X8B8G8R8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ), PIPE_FORMAT_R8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R8G8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R8G8B8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SSCALED ), -- cgit v1.2.3 From aafe3ddee276230243ed6767803ce4b6ce2aeec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 19 May 2008 15:18:40 +0900 Subject: i915simple: Fix win9x build. --- src/gallium/drivers/i915simple/i915_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 4adeb37e86..e09c225900 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -466,7 +466,7 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader) FREE(ifs->program); ifs->program_len = 0; - FREE(ifs->state.tokens); + FREE((struct tgsi_token *)ifs->state.tokens); FREE(ifs); } -- cgit v1.2.3 From 59007a811de2d76ea00164e8f1cacb4a375d1458 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 19 May 2008 09:34:28 -0600 Subject: if x86_get_func() returns NULL, handle it properly instead of aborting --- src/gallium/auxiliary/draw/draw_vs_sse.c | 3 +++ src/gallium/drivers/softpipe/sp_fs_sse.c | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 5929ea76b2..e3f4e67472 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -215,6 +215,9 @@ draw_create_vs_sse(struct draw_context *draw, goto fail; vs->func = (codegen_function) x86_get_func( &vs->sse2_program ); + if (!vs->func) { + goto fail; + } return &vs->base; diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 25fdfea491..55741cc1df 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -139,7 +139,11 @@ softpipe_create_fs_sse(struct softpipe_context *softpipe, } shader->func = (codegen_function) x86_get_func( &shader->sse2_program ); - assert(shader->func); + if (!shader->func) { + x86_release_func( &shader->sse2_program ); + FREE(shader); + return NULL; + } shader->base.shader = *templ; shader->base.prepare = fs_sse_prepare; -- cgit v1.2.3 From 21e614eabc5e6a502504f307f3710b4dd0417923 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 19 May 2008 12:40:11 -0600 Subject: gallium: fix some texture object leaks --- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 8 ++++++++ src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 5 +++++ 2 files changed, 13 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index f501b2aed4..346a96e37f 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -713,6 +713,11 @@ static void aaline_destroy(struct draw_stage *stage) { struct aaline_stage *aaline = aaline_stage(stage); + uint i; + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + pipe_texture_reference(&aaline->state.texture[i], NULL); + } if (aaline->sampler_cso) aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); @@ -836,6 +841,9 @@ aaline_set_sampler_textures(struct pipe_context *pipe, for (i = 0; i < num; i++) { pipe_texture_reference(&aaline->state.texture[i], texture[i]); } + for ( ; i < PIPE_MAX_SAMPLERS; i++) { + pipe_texture_reference(&aaline->state.texture[i], NULL); + } aaline->num_textures = num; /* pass-through */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 73ee419858..2dfd1800d5 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -559,6 +559,11 @@ static void pstip_destroy(struct draw_stage *stage) { struct pstip_stage *pstip = pstip_stage(stage); + uint i; + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + pipe_texture_reference(&pstip->state.textures[i], NULL); + } pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso); -- cgit v1.2.3 From bd4eec0561fb021849ac4047fdbf40a616fb68b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 22 May 2008 20:33:17 +0900 Subject: pipebuffer: Don't retry allocating in slab suballocator. In pipebuffer, fencing is done at on a level above sub-allocation, so no matter how many times slab allocator retries no buffer will be freed. The pipebuffer fencing implemention already retries allocating. --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index b931455056..45ba158a4d 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -47,9 +47,6 @@ #include "pb_bufmgr.h" -#define DRI_SLABPOOL_ALLOC_RETRIES 100 - - struct pb_slab; struct pb_slab_buffer @@ -313,7 +310,6 @@ pb_slab_manager_create_buffer(struct pb_manager *_mgr, static struct pb_slab_buffer *buf; struct pb_slab *slab; struct list_head *list; - int count = DRI_SLABPOOL_ALLOC_RETRIES; /* check size */ assert(size == mgr->bufSize); @@ -331,23 +327,14 @@ pb_slab_manager_create_buffer(struct pb_manager *_mgr, /* XXX: check for compatible buffer usage too? */ _glthread_LOCK_MUTEX(mgr->mutex); - while (mgr->slabs.next == &mgr->slabs && count > 0) { - if (mgr->slabs.next != &mgr->slabs) - break; - - _glthread_UNLOCK_MUTEX(mgr->mutex); - if (count != DRI_SLABPOOL_ALLOC_RETRIES) - util_time_sleep(1); - _glthread_LOCK_MUTEX(mgr->mutex); + if (mgr->slabs.next == &mgr->slabs) { (void) pb_slab_create(mgr); - count--; + if (mgr->slabs.next == &mgr->slabs) { + _glthread_UNLOCK_MUTEX(mgr->mutex); + return NULL; + } } - list = mgr->slabs.next; - if (list == &mgr->slabs) { - _glthread_UNLOCK_MUTEX(mgr->mutex); - return NULL; - } slab = LIST_ENTRY(struct pb_slab, list, head); if (--slab->numFree == 0) LIST_DELINIT(list); -- cgit v1.2.3 From 781676c7cc5ae7586ee8edd07de880892c5a2d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 22 May 2008 21:54:41 +0900 Subject: pipebuffer: More robust face null pointers. It is really the caller responsibility not to call pipebuffer with null buffers, etc. But don't let the crash happen here, and still asserting early. --- src/gallium/auxiliary/pipebuffer/pb_buffer.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index 49705cb862..857ea53c78 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -146,6 +146,8 @@ pb_map(struct pb_buffer *buf, unsigned flags) { assert(buf); + if(!buf) + return NULL; return buf->vtbl->map(buf, flags); } @@ -154,6 +156,8 @@ static INLINE void pb_unmap(struct pb_buffer *buf) { assert(buf); + if(!buf) + return; buf->vtbl->unmap(buf); } @@ -163,6 +167,12 @@ pb_get_base_buffer( struct pb_buffer *buf, struct pb_buffer **base_buf, unsigned *offset ) { + assert(buf); + if(!buf) { + base_buf = NULL; + offset = 0; + return; + } buf->vtbl->get_base_buffer(buf, base_buf, offset); } @@ -171,7 +181,8 @@ static INLINE void pb_destroy(struct pb_buffer *buf) { assert(buf); - assert(buf->vtbl); + if(!buf) + return; buf->vtbl->destroy(buf); } -- cgit v1.2.3 From 8b25b5256fad23e8ea11c6931ecac658ca60c0b0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 13 May 2008 09:46:53 +0100 Subject: draw: remove disabled non-sse swizzle code --- src/gallium/auxiliary/draw/draw_vs_sse.c | 50 +------------------------------- 1 file changed, 1 insertion(+), 49 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index e3f4e67472..edf235cddc 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -47,9 +47,7 @@ #include "tgsi/util/tgsi_parse.h" #define SSE_MAX_VERTICES 4 -#define SSE_SWIZZLES 1 -#if SSE_SWIZZLES typedef void (XSTDCALL *codegen_function) ( const struct tgsi_exec_vector *input, /* 1 */ struct tgsi_exec_vector *output, /* 2 */ @@ -62,14 +60,6 @@ typedef void (XSTDCALL *codegen_function) ( float (*aos_output)[4], /* 9 */ uint num_outputs, /* 10 */ uint output_stride ); /* 11 */ -#else -typedef void (XSTDCALL *codegen_function) ( - const struct tgsi_exec_vector *input, - struct tgsi_exec_vector *output, - float (*constant)[4], - struct tgsi_exec_vector *temporary, - float (*immediates)[4] ); -#endif struct draw_sse_vertex_shader { struct draw_vertex_shader base; @@ -111,7 +101,6 @@ vs_sse_run_linear( struct draw_vertex_shader *base, for (i = 0; i < count; i += MAX_TGSI_VERTICES) { unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); -#if SSE_SWIZZLES /* run compiled shader */ shader->func(machine->Inputs, @@ -128,43 +117,6 @@ vs_sse_run_linear( struct draw_vertex_shader *base, input = (const float (*)[4])((const char *)input + input_stride * max_vertices); output = (float (*)[4])((char *)output + output_stride * max_vertices); -#else - unsigned int j, slot; - - /* Swizzle inputs. - */ - for (j = 0; j < max_vertices; j++) { - for (slot = 0; slot < base->info.num_inputs; slot++) { - machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; - machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; - machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; - machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; - } - - input = (const float (*)[4])((const char *)input + input_stride); - } - - /* run compiled shader - */ - shader->func(machine->Inputs, - machine->Outputs, - (float (*)[4])constants, - machine->Temps, - shader->immediates); - - /* Unswizzle all output results. - */ - for (j = 0; j < max_vertices; j++) { - for (slot = 0; slot < base->info.num_outputs; slot++) { - output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; - } - - output = (float (*)[4])((char *)output + output_stride); - } -#endif } } @@ -211,7 +163,7 @@ draw_create_vs_sse(struct draw_context *draw, x86_init_func( &vs->sse2_program ); if (!tgsi_emit_sse2( (struct tgsi_token *) vs->base.state.tokens, - &vs->sse2_program, vs->immediates, SSE_SWIZZLES )) + &vs->sse2_program, vs->immediates, TRUE )) goto fail; vs->func = (codegen_function) x86_get_func( &vs->sse2_program ); -- cgit v1.2.3 From b23706454bb165a62888d264e95a98a2e4cf139c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 13 May 2008 13:35:14 +0100 Subject: draw: get rid of fetch-shade-emit frontend hack The code is now living in it's intended place as a pt middle end. --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/draw_private.h | 1 - src/gallium/auxiliary/draw/draw_pt.c | 14 - src/gallium/auxiliary/draw/draw_pt.h | 1 - .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 677 --------------------- 5 files changed, 694 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 67d78bdbbd..3053682da8 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -26,7 +26,6 @@ C_SOURCES = \ draw_pt_emit.c \ draw_pt_fetch.c \ draw_pt_fetch_emit.c \ - draw_pt_fetch_shade_emit.c \ draw_pt_middle_fse.c \ draw_pt_fetch_shade_pipeline.c \ draw_pt_post_vs.c \ diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 86b901a3c8..fd51a57781 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -131,7 +131,6 @@ struct draw_context struct { struct draw_pt_front_end *vcache; struct draw_pt_front_end *varray; - struct draw_pt_front_end *fetch_shade_emit; /* temp hack */ } front; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 91e35db819..75f44d503e 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -85,11 +85,6 @@ draw_pt_arrays(struct draw_context *draw, */ if (draw->pt.user.elts || (opt & PT_PIPELINE)) { frontend = draw->pt.front.vcache; -#if 0 - } else if (opt == PT_SHADE && draw->pt.test_fse) { - /* should be a middle end.. */ - frontend = draw->pt.front.fetch_shade_emit; -#endif } else { frontend = draw->pt.front.varray; } @@ -127,10 +122,6 @@ boolean draw_pt_init( struct draw_context *draw ) draw->pt.middle.fetch_shade_emit = draw_pt_middle_fse( draw ); if (!draw->pt.middle.fetch_shade_emit) return FALSE; - - draw->pt.front.fetch_shade_emit = draw_pt_fetch_shade_emit( draw ); - if (!draw->pt.front.fetch_shade_emit) - return FALSE; } @@ -159,11 +150,6 @@ void draw_pt_destroy( struct draw_context *draw ) draw->pt.middle.fetch_shade_emit = NULL; } - if (draw->pt.front.fetch_shade_emit) { - draw->pt.front.fetch_shade_emit->destroy( draw->pt.front.fetch_shade_emit ); - draw->pt.front.fetch_shade_emit = NULL; - } - if (draw->pt.front.vcache) { draw->pt.front.vcache->destroy( draw->pt.front.vcache ); draw->pt.front.vcache = NULL; diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index cdae46b8d2..e03816ebbc 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -121,7 +121,6 @@ const void *draw_pt_elt_ptr( struct draw_context *draw, struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ); struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw); -struct draw_pt_front_end *draw_pt_fetch_shade_emit( struct draw_context *draw ); /* Middle-ends: * diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c deleted file mode 100644 index f756d3e0bb..0000000000 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ /dev/null @@ -1,677 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - - -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "draw/draw_private.h" -#include "draw/draw_vbuf.h" -#include "draw/draw_vertex.h" -#include "draw/draw_pt.h" -#include "draw/draw_vs.h" - -#include "translate/translate.h" - -struct fetch_shade_emit; - -struct fse_shader { - struct translate_key key; - - void (*run_linear)( const struct fetch_shade_emit *fse, - unsigned start, - unsigned count, - char *buffer ); -}; - -/* Prototype fetch, shade, emit-hw-verts all in one go. - */ -struct fetch_shade_emit { - struct draw_pt_front_end base; - - struct draw_context *draw; - - struct translate_key key; - - /* Temporaries: - */ - const float *constants; - unsigned pitch[PIPE_MAX_ATTRIBS]; - const ubyte *src[PIPE_MAX_ATTRIBS]; - unsigned prim; - - /* Points to one of the three hardwired example shaders, below: - */ - struct fse_shader *active; - - /* Temporary: A list of hard-wired shaders. Of course the plan - * would be to generate these for a given (vertex-shader, - * translate-key) pair... - */ - struct fse_shader shader[10]; - int nr_shaders; -}; - - - -/* Not quite passthrough yet -- we're still running the 'shader' here, - * inlined into the vertex fetch function. - */ -static void fetch_xyz_rgb_st( const struct fetch_shade_emit *fse, - unsigned start, - unsigned count, - char *buffer ) -{ - unsigned i; - - const float *m = fse->constants; - const float m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; - const float m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; - const float m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; - const float m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; - - const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; - const ubyte *st = fse->src[2] + start * fse->pitch[2]; - - float *out = (float *)buffer; - - - assert(fse->pitch[1] == 0); - - /* loop over vertex attributes (vertex shader inputs) - */ - for (i = 0; i < count; i++) { - { - const float *in = (const float *)xyz; - const float ix = in[0], iy = in[1], iz = in[2]; - - out[0] = m0 * ix + m4 * iy + m8 * iz + m12; - out[1] = m1 * ix + m5 * iy + m9 * iz + m13; - out[2] = m2 * ix + m6 * iy + m10 * iz + m14; - out[3] = m3 * ix + m7 * iy + m11 * iz + m15; - xyz += fse->pitch[0]; - } - - { - out[4] = 1.0f; - out[5] = 1.0f; - out[6] = 1.0f; - out[7] = 1.0f; - } - - { - const float *in = (const float *)st; st += fse->pitch[2]; - out[8] = in[0]; - out[9] = in[1]; - out[10] = 0.0f; - out[11] = 1.0f; - } - - out += 12; - } -} - - - -static void fetch_xyz_rgb( const struct fetch_shade_emit *fse, - unsigned start, - unsigned count, - char *buffer ) -{ - unsigned i; - - const float *m = (const float *)fse->constants; - const float m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; - const float m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; - const float m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; - const float m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; - - const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; - const ubyte *rgb = fse->src[1] + start * fse->pitch[1]; - - float *out = (float *)buffer; - -// debug_printf("rgb %f %f %f\n", rgb[0], rgb[1], rgb[2]); - - - for (i = 0; i < count; i++) { - { - const float *in = (const float *)xyz; - const float ix = in[0], iy = in[1], iz = in[2]; - - out[0] = m0 * ix + m4 * iy + m8 * iz + m12; - out[1] = m1 * ix + m5 * iy + m9 * iz + m13; - out[2] = m2 * ix + m6 * iy + m10 * iz + m14; - out[3] = m3 * ix + m7 * iy + m11 * iz + m15; - xyz += fse->pitch[0]; - } - - { - const float *in = (const float *)rgb; - out[4] = in[0]; - out[5] = in[1]; - out[6] = in[2]; - out[7] = 1.0f; - rgb += fse->pitch[1]; - } - - out += 8; - } -} - - - - -static void fetch_xyz_rgb_psiz( const struct fetch_shade_emit *fse, - unsigned start, - unsigned count, - char *buffer ) -{ - unsigned i; - - const float *m = (const float *)fse->constants; - const float m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; - const float m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; - const float m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; - const float m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; - - const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; - const float *rgb = (const float *)(fse->src[1] + start * fse->pitch[1]); - const float psiz = 1.0; - - float *out = (float *)buffer; - - - assert(fse->pitch[1] == 0); - - for (i = 0; i < count; i++) { - { - const float *in = (const float *)xyz; - const float ix = in[0], iy = in[1], iz = in[2]; - - out[0] = m0 * ix + m4 * iy + m8 * iz + m12; - out[1] = m1 * ix + m5 * iy + m9 * iz + m13; - out[2] = m2 * ix + m6 * iy + m10 * iz + m14; - out[3] = m3 * ix + m7 * iy + m11 * iz + m15; - xyz += fse->pitch[0]; - } - - { - out[4] = rgb[0]; - out[5] = rgb[1]; - out[6] = rgb[2]; - out[7] = 1.0f; - } - - { - out[8] = psiz; - } - - out += 9; - } -} - - - - -static boolean set_prim( struct fetch_shade_emit *fse, - unsigned prim, - unsigned count ) -{ - struct draw_context *draw = fse->draw; - - fse->prim = prim; - - switch (prim) { - case PIPE_PRIM_LINE_LOOP: - if (count > 1024) - return FALSE; - draw->render->set_primitive( draw->render, PIPE_PRIM_LINE_STRIP ); - break; - - case PIPE_PRIM_TRIANGLE_FAN: - case PIPE_PRIM_POLYGON: - if (count > 1024) - return FALSE; - draw->render->set_primitive( draw->render, prim ); - break; - - case PIPE_PRIM_QUADS: - case PIPE_PRIM_QUAD_STRIP: - draw->render->set_primitive( draw->render, PIPE_PRIM_TRIANGLES ); - break; - - default: - draw->render->set_primitive( draw->render, prim ); - break; - } - - return TRUE; -} - - - - - - -static void fse_prepare( struct draw_pt_front_end *fe, - unsigned prim, - struct draw_pt_middle_end *unused, - unsigned opt ) -{ - struct fetch_shade_emit *fse = (struct fetch_shade_emit *)fe; - struct draw_context *draw = fse->draw; - unsigned num_vs_inputs = draw->vertex_shader->info.num_inputs; - unsigned num_vs_outputs = draw->vertex_shader->info.num_outputs; - const struct vertex_info *vinfo; - unsigned i; - boolean need_psize = 0; - - - if (draw->pt.user.elts) { - assert(0); - return ; - } - - if (!set_prim(fse, prim, /*count*/1022 )) { - assert(0); - return ; - } - - /* Must do this after set_primitive() above: - */ - vinfo = draw->render->get_vertex_info(draw->render); - - - - fse->key.nr_elements = MAX2(num_vs_outputs, /* outputs - translate to hw format */ - num_vs_inputs); /* inputs - fetch from api format */ - - fse->key.output_stride = vinfo->size * 4; - memset(fse->key.element, 0, - fse->key.nr_elements * sizeof(fse->key.element[0])); - - for (i = 0; i < num_vs_inputs; i++) { - const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; - fse->key.element[i].input_format = src->src_format; - - /* Consider ignoring these at this point, ie make generated - * programs independent of this state: - */ - fse->key.element[i].input_buffer = 0; //src->vertex_buffer_index; - fse->key.element[i].input_offset = 0; //src->src_offset; - } - - - { - unsigned dst_offset = 0; - - for (i = 0; i < vinfo->num_attribs; i++) { - unsigned emit_sz = 0; - unsigned output_format = PIPE_FORMAT_NONE; - unsigned vs_output = vinfo->src_index[i]; - - switch (vinfo->emit[i]) { - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - need_psize = 1; - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - vs_output = num_vs_outputs + 1; - - break; - default: - assert(0); - break; - } - - /* The elements in the key correspond to vertex shader output - * numbers, not to positions in the hw vertex description -- - * that's handled by the output_offset field. - */ - fse->key.element[vs_output].output_format = output_format; - fse->key.element[vs_output].output_offset = dst_offset; - - dst_offset += emit_sz; - assert(fse->key.output_stride >= dst_offset); - } - } - - /* To make psize work, really need to tell the vertex shader to - * copy that value from input->output. For 'translate' this was - * implicit for all elements. - */ -#if 0 - if (need_psize) { - unsigned input = num_vs_inputs + 1; - const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; - fse->key.element[i].input_format = PIPE_FORMAT_R32_FLOAT; - fse->key.element[i].input_buffer = 0; //nr_buffers + 1; - fse->key.element[i].input_offset = 0; - - fse->key.nr_elements += 1; - - } -#endif - - fse->constants = draw->pt.user.constants; - - /* Would normally look up a vertex shader and peruse its list of - * varients somehow. We omitted that step and put all the - * hardcoded "shaders" into an array. We're just making the - * assumption that this happens to be a matching shader... ie - * you're running isosurf, aren't you? - */ - fse->active = NULL; - for (i = 0; i < fse->nr_shaders; i++) { - if (translate_key_compare( &fse->key, &fse->shader[i].key) == 0) - fse->active = &fse->shader[i]; - } - - if (!fse->active) { - assert(0); - return ; - } - - /* Now set buffer pointers: - */ - for (i = 0; i < num_vs_inputs; i++) { - unsigned buf = draw->pt.vertex_element[i].vertex_buffer_index; - - fse->src[i] = ((const ubyte *) draw->pt.user.vbuffer[buf] + - draw->pt.vertex_buffer[buf].buffer_offset + - draw->pt.vertex_element[i].src_offset); - - fse->pitch[i] = draw->pt.vertex_buffer[buf].pitch; - - } - - - //return TRUE; -} - - - - - - -#define INDEX(i) (start + (i)) -static void fse_render_linear( struct vbuf_render *render, - unsigned prim, - unsigned start, - unsigned length ) -{ - ushort *tmp = NULL; - unsigned i, j; - - switch (prim) { - case PIPE_PRIM_LINE_LOOP: - tmp = MALLOC( sizeof(ushort) * (length + 1) ); - - for (i = 0; i < length; i++) - tmp[i] = INDEX(i); - tmp[length] = 0; - - render->draw( render, - tmp, - length+1 ); - break; - - - case PIPE_PRIM_QUAD_STRIP: - tmp = MALLOC( sizeof(ushort) * (length / 2 * 6) ); - - for (j = i = 0; i + 3 < length; i += 2, j += 6) { - tmp[j+0] = INDEX(i+0); - tmp[j+1] = INDEX(i+1); - tmp[j+2] = INDEX(i+3); - - tmp[j+3] = INDEX(i+2); - tmp[j+4] = INDEX(i+0); - tmp[j+5] = INDEX(i+3); - } - - if (j) - render->draw( render, tmp, j ); - break; - - case PIPE_PRIM_QUADS: - tmp = MALLOC( sizeof(int) * (length / 4 * 6) ); - - for (j = i = 0; i + 3 < length; i += 4, j += 6) { - tmp[j+0] = INDEX(i+0); - tmp[j+1] = INDEX(i+1); - tmp[j+2] = INDEX(i+3); - - tmp[j+3] = INDEX(i+1); - tmp[j+4] = INDEX(i+2); - tmp[j+5] = INDEX(i+3); - } - - if (j) - render->draw( render, tmp, j ); - break; - - default: - render->draw_arrays( render, - start, - length ); - break; - } - - if (tmp) - FREE(tmp); -} - - - -static boolean do_draw( struct fetch_shade_emit *fse, - unsigned start, unsigned count ) -{ - struct draw_context *draw = fse->draw; - - char *hw_verts = - draw->render->allocate_vertices( draw->render, - (ushort)fse->key.output_stride, - (ushort)count ); - - if (!hw_verts) - return FALSE; - - /* Single routine to fetch vertices, run shader and emit HW verts. - * Clipping and viewport transformation are done on hardware. - */ - fse->active->run_linear( fse, - start, count, - hw_verts ); - - /* Draw arrays path to avoid re-emitting index list again and - * again. - */ - fse_render_linear( draw->render, - fse->prim, - 0, - count ); - - - draw->render->release_vertices( draw->render, - hw_verts, - fse->key.output_stride, - count ); - - return TRUE; -} - - -static void -fse_run(struct draw_pt_front_end *fe, - pt_elt_func elt_func, - const void *elt_ptr, - unsigned count) -{ - struct fetch_shade_emit *fse = (struct fetch_shade_emit *)fe; - unsigned i = 0; - unsigned first, incr; - unsigned start = elt_func(elt_ptr, 0); - - //debug_printf("%s prim %d start %d count %d\n", __FUNCTION__, prim, start, count); - - draw_pt_split_prim(fse->prim, &first, &incr); - - count -= (count - first) % incr; - - while (i + first <= count) { - int nr = MIN2( count - i, 1024 ); - - /* snap to prim boundary - */ - nr -= (nr - first) % incr; - - if (!do_draw( fse, start + i, nr )) { - assert(0); - return ; - } - - /* increment allowing for repeated vertices - */ - i += nr - (first - incr); - } - - //return TRUE; -} - - -static void fse_finish( struct draw_pt_front_end *frontend ) -{ -} - - -static void -fse_destroy( struct draw_pt_front_end *frontend ) -{ - FREE(frontend); -} - -struct draw_pt_front_end *draw_pt_fetch_shade_emit( struct draw_context *draw ) -{ - struct fetch_shade_emit *fse = CALLOC_STRUCT(fetch_shade_emit); - if (!fse) - return NULL; - - fse->base.prepare = fse_prepare; - fse->base.run = fse_run; - fse->base.finish = fse_finish; - fse->base.destroy = fse_destroy; - fse->draw = draw; - - fse->shader[0].run_linear = fetch_xyz_rgb_st; - fse->shader[0].key.nr_elements = 3; - fse->shader[0].key.output_stride = 12 * sizeof(float); - - fse->shader[0].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[0].key.element[0].input_buffer = 0; - fse->shader[0].key.element[0].input_offset = 0; - fse->shader[0].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[0].key.element[0].output_offset = 0; - - fse->shader[0].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[0].key.element[1].input_buffer = 0; - fse->shader[0].key.element[1].input_offset = 0; - fse->shader[0].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[0].key.element[1].output_offset = 16; - - fse->shader[0].key.element[1].input_format = PIPE_FORMAT_R32G32_FLOAT; - fse->shader[0].key.element[1].input_buffer = 0; - fse->shader[0].key.element[1].input_offset = 0; - fse->shader[0].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[0].key.element[1].output_offset = 32; - - fse->shader[1].run_linear = fetch_xyz_rgb; - fse->shader[1].key.nr_elements = 2; - fse->shader[1].key.output_stride = 8 * sizeof(float); - - fse->shader[1].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[1].key.element[0].input_buffer = 0; - fse->shader[1].key.element[0].input_offset = 0; - fse->shader[1].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[1].key.element[0].output_offset = 0; - - fse->shader[1].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[1].key.element[1].input_buffer = 0; - fse->shader[1].key.element[1].input_offset = 0; - fse->shader[1].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[1].key.element[1].output_offset = 16; - - fse->shader[2].run_linear = fetch_xyz_rgb_psiz; - fse->shader[2].key.nr_elements = 3; - fse->shader[2].key.output_stride = 9 * sizeof(float); - - fse->shader[2].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[2].key.element[0].input_buffer = 0; - fse->shader[2].key.element[0].input_offset = 0; - fse->shader[2].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[2].key.element[0].output_offset = 0; - - fse->shader[2].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[2].key.element[1].input_buffer = 0; - fse->shader[2].key.element[1].input_offset = 0; - fse->shader[2].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[2].key.element[1].output_offset = 16; - - /* psize is special - * -- effectively add it here as another input!?! - * -- who knows how to add it as a buffer? - */ - fse->shader[2].key.element[2].input_format = PIPE_FORMAT_R32_FLOAT; - fse->shader[2].key.element[2].input_buffer = 0; - fse->shader[2].key.element[2].input_offset = 0; - fse->shader[2].key.element[2].output_format = PIPE_FORMAT_R32_FLOAT; - fse->shader[2].key.element[2].output_offset = 32; - - fse->nr_shaders = 3; - - return &fse->base; -} -- cgit v1.2.3 From 2f0d1396e4c1626b3b1ac799bd29e86a9530369e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 13 May 2008 13:40:22 +0100 Subject: draw: move some state into a new 'vs' area --- src/gallium/auxiliary/draw/draw_context.c | 21 ++++--------- src/gallium/auxiliary/draw/draw_pipe.h | 2 +- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 4 +-- src/gallium/auxiliary/draw/draw_pipe_clip.c | 6 ++-- src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_stipple.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_twoside.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 4 +-- src/gallium/auxiliary/draw/draw_private.h | 28 +++++++++++------ .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 6 ++-- src/gallium/auxiliary/draw/draw_pt_middle_fse.c | 4 +-- src/gallium/auxiliary/draw/draw_vs.c | 35 +++++++++++++++++++--- src/gallium/auxiliary/draw/draw_vs_exec.c | 2 +- src/gallium/auxiliary/draw/draw_vs_sse.c | 2 +- 15 files changed, 75 insertions(+), 47 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 98e23fa830..2242074965 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -56,12 +56,6 @@ struct draw_context *draw_create( void ) draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ - tgsi_exec_machine_init(&draw->machine); - - /* FIXME: give this machine thing a proper constructor: - */ - draw->machine.Inputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); - draw->machine.Outputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); if (!draw_pipeline_init( draw )) goto fail; @@ -69,6 +63,9 @@ struct draw_context *draw_create( void ) if (!draw_pt_init( draw )) goto fail; + if (!draw_vs_init( draw )) + goto fail; + return draw; fail: @@ -83,13 +80,6 @@ void draw_destroy( struct draw_context *draw ) return; - if (draw->machine.Inputs) - align_free(draw->machine.Inputs); - - if (draw->machine.Outputs) - align_free(draw->machine.Outputs); - - tgsi_exec_machine_free_data(&draw->machine); /* Not so fast -- we're just borrowing this at the moment. * @@ -99,6 +89,7 @@ void draw_destroy( struct draw_context *draw ) draw_pipeline_destroy( draw ); draw_pt_destroy( draw ); + draw_vs_destroy( draw ); FREE( draw ); } @@ -295,7 +286,7 @@ int draw_find_vs_output(struct draw_context *draw, uint semantic_name, uint semantic_index) { - const struct draw_vertex_shader *vs = draw->vertex_shader; + const struct draw_vertex_shader *vs = draw->vs.vertex_shader; uint i; for (i = 0; i < vs->info.num_outputs; i++) { if (vs->info.output_semantic_name[i] == semantic_name && @@ -320,7 +311,7 @@ draw_find_vs_output(struct draw_context *draw, uint draw_num_vs_outputs(struct draw_context *draw) { - uint count = draw->vertex_shader->info.num_outputs; + uint count = draw->vs.vertex_shader->info.num_outputs; if (draw->extra_vp_outputs.slot > 0) count++; return count; diff --git a/src/gallium/auxiliary/draw/draw_pipe.h b/src/gallium/auxiliary/draw/draw_pipe.h index f1cb0891ca..dbad8f98ac 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.h +++ b/src/gallium/auxiliary/draw/draw_pipe.h @@ -116,7 +116,7 @@ dup_vert( struct draw_stage *stage, { struct vertex_header *tmp = stage->tmp[idx]; const uint vsize = sizeof(struct vertex_header) - + stage->draw->num_vs_outputs * 4 * sizeof(float); + + stage->draw->vs.num_vs_outputs * 4 * sizeof(float); memcpy(tmp, vert, vsize); tmp->vertex_id = UNDEFINED_VERTEX_ID; return tmp; diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index f501b2aed4..d93708ad3c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -651,7 +651,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) } /* update vertex attrib info */ - aaline->tex_slot = draw->num_vs_outputs; + aaline->tex_slot = draw->vs.num_vs_outputs; assert(aaline->tex_slot > 0); /* output[0] is vertex pos */ /* advertise the extra post-transformed vertex attribute */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 122a48660a..97d74ad693 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -681,7 +681,7 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header) bind_aapoint_fragment_shader(aapoint); /* update vertex attrib info */ - aapoint->tex_slot = draw->num_vs_outputs; + aapoint->tex_slot = draw->vs.num_vs_outputs; assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; @@ -692,7 +692,7 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header) aapoint->psize_slot = -1; if (draw->rasterizer->point_size_per_vertex) { /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vertex_shader; + const struct draw_vertex_shader *vs = draw->vs.vertex_shader; uint i; for (i = 0; i < vs->info.num_outputs; i++) { if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index ce80c94163..c11ed934a4 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -112,7 +112,7 @@ static void interp( const struct clipper *clip, const struct vertex_header *out, const struct vertex_header *in ) { - const unsigned nr_attrs = clip->stage.draw->num_vs_outputs; + const unsigned nr_attrs = clip->stage.draw->vs.num_vs_outputs; unsigned j; /* Vertex header. @@ -180,7 +180,7 @@ static void emit_poly( struct draw_stage *stage, header.flags |= edge_last; if (0) { - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader; uint j, k; debug_printf("Clipped tri:\n"); for (j = 0; j < 3; j++) { @@ -425,7 +425,7 @@ clip_init_state( struct draw_stage *stage ) clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE; if (clipper->flat) { - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader; uint i; clipper->num_color_attribs = 0; diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c index 09b68c4559..21a9c3b77f 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -159,7 +159,7 @@ static void flatshade_line_1( struct draw_stage *stage, static void flatshade_init_state( struct draw_stage *stage ) { struct flat_stage *flat = flat_stage(stage); - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader; uint i; /* Find which vertex shader outputs are colors, make a list */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c index 3cbced362e..4673d5dcba 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c @@ -71,7 +71,7 @@ screen_interp( struct draw_context *draw, const struct vertex_header *v1 ) { uint attr; - for (attr = 0; attr < draw->num_vs_outputs; attr++) { + for (attr = 0; attr < draw->vs.num_vs_outputs; attr++) { const float *val0 = v0->data[attr]; const float *val1 = v1->data[attr]; float *newv = dst->data[attr]; diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c index 50872fdbe9..3ac825f565 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -105,7 +105,7 @@ static void twoside_first_tri( struct draw_stage *stage, struct prim_header *header ) { struct twoside_stage *twoside = twoside_stage(stage); - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader; uint i; twoside->attrib_front0 = 0; diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index ed08573382..df92e3f2d0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -197,7 +197,7 @@ static void widepoint_first_point( struct draw_stage *stage, if (draw->rasterizer->point_sprite) { /* find vertex shader texcoord outputs */ - const struct draw_vertex_shader *vs = draw->vertex_shader; + const struct draw_vertex_shader *vs = draw->vs.vertex_shader; uint i, j = 0; for (i = 0; i < vs->info.num_outputs; i++) { if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { @@ -212,7 +212,7 @@ static void widepoint_first_point( struct draw_stage *stage, wide->psize_slot = -1; if (draw->rasterizer->point_size_per_vertex) { /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vertex_shader; + const struct draw_vertex_shader *vs = draw->vs.vertex_shader; uint i; for (i = 0; i < vs->info.num_outputs; i++) { if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index fd51a57781..3418ee2b88 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -169,13 +169,24 @@ struct draw_context /* pipe state that we need: */ const struct pipe_rasterizer_state *rasterizer; struct pipe_viewport_state viewport; + boolean identity_viewport; - struct draw_vertex_shader *vertex_shader; + struct { + struct draw_vertex_shader *vertex_shader; + uint num_vs_outputs; /**< convenience, from vertex_shader */ - boolean identity_viewport; - uint num_vs_outputs; /**< convenience, from vertex_shader */ + /** TGSI program interpreter runtime state */ + struct tgsi_exec_machine machine; + + /* This (and the tgsi_exec_machine struct) probably need to be moved somewhere private. + */ + struct gallivm_cpu_engine *engine; + + struct translate_cache *fetch_cache; + struct translate_cache *emit_cache; + } vs; /* Clip derived state: */ @@ -192,16 +203,15 @@ struct draw_context unsigned reduced_prim; - /** TGSI program interpreter runtime state */ - struct tgsi_exec_machine machine; - - /* This (and the tgsi_exec_machine struct) probably need to be moved somewhere private. - */ - struct gallivm_cpu_engine *engine; void *driver_private; }; +/******************************************************************************* + * Vertex shader code: + */ +boolean draw_vs_init( struct draw_context *draw ); +void draw_vs_destroy( struct draw_context *draw ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index dad54690a5..06718779a5 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -55,7 +55,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; - struct draw_vertex_shader *vs = draw->vertex_shader; + struct draw_vertex_shader *vs = draw->vs.vertex_shader; /* Add one to num_outputs because the pipeline occasionally tags on * an additional texcoord, eg for AA lines. @@ -107,7 +107,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; - struct draw_vertex_shader *shader = draw->vertex_shader; + struct draw_vertex_shader *shader = draw->vs.vertex_shader; unsigned opt = fpme->opt; unsigned alloc_count = align_int( fetch_count, 4 ); @@ -183,7 +183,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; - struct draw_vertex_shader *shader = draw->vertex_shader; + struct draw_vertex_shader *shader = draw->vs.vertex_shader; unsigned opt = fpme->opt; unsigned alloc_count = align_int( count, 4 ); diff --git a/src/gallium/auxiliary/draw/draw_pt_middle_fse.c b/src/gallium/auxiliary/draw/draw_pt_middle_fse.c index cdb7d260da..643ea151c1 100644 --- a/src/gallium/auxiliary/draw/draw_pt_middle_fse.c +++ b/src/gallium/auxiliary/draw/draw_pt_middle_fse.c @@ -368,8 +368,8 @@ static void fse_prepare( struct draw_pt_middle_end *middle, { struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; struct draw_context *draw = fse->draw; - unsigned num_vs_inputs = draw->vertex_shader->info.num_inputs; - unsigned num_vs_outputs = draw->vertex_shader->info.num_outputs; + unsigned num_vs_inputs = draw->vs.vertex_shader->info.num_inputs; + unsigned num_vs_outputs = draw->vs.vertex_shader->info.num_outputs; const struct vertex_info *vinfo; unsigned i; boolean need_psize = 0; diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 03fe00a951..4142dd9589 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -66,13 +66,13 @@ draw_bind_vertex_shader(struct draw_context *draw, if (dvs) { - draw->vertex_shader = dvs; - draw->num_vs_outputs = dvs->info.num_outputs; + draw->vs.vertex_shader = dvs; + draw->vs.num_vs_outputs = dvs->info.num_outputs; dvs->prepare( dvs, draw ); } else { - draw->vertex_shader = NULL; - draw->num_vs_outputs = 0; + draw->vs.vertex_shader = NULL; + draw->vs.num_vs_outputs = 0; } } @@ -83,3 +83,30 @@ draw_delete_vertex_shader(struct draw_context *draw, { dvs->delete( dvs ); } + + + +boolean +draw_vs_init( struct draw_context *draw ) +{ + tgsi_exec_machine_init(&draw->vs.machine); + /* FIXME: give this machine thing a proper constructor: + */ + draw->vs.machine.Inputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); + draw->vs.machine.Outputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); + + return TRUE; +} + +void +draw_vs_destroy( struct draw_context *draw ) +{ + if (draw->vs.machine.Inputs) + align_free(draw->vs.machine.Inputs); + + if (draw->vs.machine.Outputs) + align_free(draw->vs.machine.Outputs); + + tgsi_exec_machine_free_data(&draw->vs.machine); + +} diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 7a02f6334b..cb80d008cd 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -182,7 +182,7 @@ draw_create_vs_exec(struct draw_context *draw, vs->base.prepare = vs_exec_prepare; vs->base.run_linear = vs_exec_run_linear; vs->base.delete = vs_exec_delete; - vs->machine = &draw->machine; + vs->machine = &draw->vs.machine; return &vs->base; } diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index edf235cddc..13ad032bd3 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -158,7 +158,7 @@ draw_create_vs_sse(struct draw_context *draw, vs->base.prepare = vs_sse_prepare; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; - vs->machine = &draw->machine; + vs->machine = &draw->vs.machine; x86_init_func( &vs->sse2_program ); -- cgit v1.2.3 From 7c99d7fe60e7bb0b7cf103a851aeef4614278ca6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 15 May 2008 12:39:08 +0100 Subject: draw: create specialized vs varients incorporating fetch & emit --- src/gallium/auxiliary/draw/Makefile | 3 +- src/gallium/auxiliary/draw/draw_private.h | 2 + .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 338 +++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs.c | 83 ++++- src/gallium/auxiliary/draw/draw_vs.h | 105 +++++++ src/gallium/auxiliary/draw/draw_vs_exec.c | 2 + src/gallium/auxiliary/draw/draw_vs_llvm.c | 2 + src/gallium/auxiliary/draw/draw_vs_sse.c | 2 + src/gallium/auxiliary/draw/draw_vs_varient.c | 229 ++++++++++++++ 9 files changed, 764 insertions(+), 2 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c create mode 100644 src/gallium/auxiliary/draw/draw_vs_varient.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 3053682da8..84877994fb 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -26,7 +26,7 @@ C_SOURCES = \ draw_pt_emit.c \ draw_pt_fetch.c \ draw_pt_fetch_emit.c \ - draw_pt_middle_fse.c \ + draw_pt_fetch_shade_emit.c \ draw_pt_fetch_shade_pipeline.c \ draw_pt_post_vs.c \ draw_pt_util.c \ @@ -34,6 +34,7 @@ C_SOURCES = \ draw_pt_vcache.c \ draw_vertex.c \ draw_vs.c \ + draw_vs_varient.c \ draw_vs_exec.c \ draw_vs_llvm.c \ draw_vs_sse.c diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 3418ee2b88..c095bf3d7b 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -184,7 +184,9 @@ struct draw_context struct gallivm_cpu_engine *engine; + struct translate *fetch; struct translate_cache *fetch_cache; + struct translate *emit; struct translate_cache *emit_cache; } vs; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c new file mode 100644 index 0000000000..74945dcfe9 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -0,0 +1,338 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" +#include "draw/draw_vs.h" + +#include "translate/translate.h" + +struct fetch_shade_emit; + + +/* Prototype fetch, shade, emit-hw-verts all in one go. + */ +struct fetch_shade_emit { + struct draw_pt_middle_end base; + struct draw_context *draw; + + + /* Temporaries: + */ + const float *constants; + unsigned pitch[PIPE_MAX_ATTRIBS]; + const ubyte *src[PIPE_MAX_ATTRIBS]; + unsigned prim; + + struct draw_vs_varient_key key; + struct draw_vs_varient *active; +}; + + + + +static void fse_prepare( struct draw_pt_middle_end *middle, + unsigned prim, + unsigned opt ) +{ + struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; + struct draw_context *draw = fse->draw; + unsigned num_vs_inputs = draw->vs.vertex_shader->info.num_inputs; + unsigned num_vs_outputs = draw->vs.vertex_shader->info.num_outputs; + const struct vertex_info *vinfo; + unsigned i; + boolean need_psize = 0; + + + if (draw->pt.user.elts) { + assert(0); + return ; + } + + if (!draw->render->set_primitive( draw->render, + prim )) { + assert(0); + return; + } + + /* Must do this after set_primitive() above: + */ + vinfo = draw->render->get_vertex_info(draw->render); + + + + fse->key.nr_elements = MAX2(num_vs_outputs, /* outputs - translate to hw format */ + num_vs_inputs); /* inputs - fetch from api format */ + + fse->key.output_stride = vinfo->size * 4; + memset(fse->key.element, 0, + fse->key.nr_elements * sizeof(fse->key.element[0])); + + for (i = 0; i < num_vs_inputs; i++) { + const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; + fse->key.element[i].in.format = src->src_format; + + /* Consider ignoring these, ie make generated programs + * independent of this state: + */ + fse->key.element[i].in.buffer = src->vertex_buffer_index; + fse->key.element[i].in.offset = src->src_offset; + } + + + { + unsigned dst_offset = 0; + + for (i = 0; i < vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned output_format = PIPE_FORMAT_NONE; + unsigned vs_output = vinfo->src_index[i]; + + switch (vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + need_psize = 1; + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + vs_output = num_vs_outputs + 1; + + break; + default: + assert(0); + break; + } + + /* The elements in the key correspond to vertex shader output + * numbers, not to positions in the hw vertex description -- + * that's handled by the output_offset field. + */ + fse->key.element[vs_output].out.format = output_format; + fse->key.element[vs_output].out.offset = dst_offset; + + dst_offset += emit_sz; + assert(fse->key.output_stride >= dst_offset); + } + } + + /* To make psize work, really need to tell the vertex shader to + * copy that value from input->output. For 'translate' this was + * implicit for all elements. + */ +#if 0 + if (need_psize) { + unsigned input = num_vs_inputs + 1; + const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; + fse->key.element[i].input_format = PIPE_FORMAT_R32_FLOAT; + fse->key.element[i].input_buffer = 0; //nr_buffers + 1; + fse->key.element[i].input_offset = 0; + + fse->key.nr_elements += 1; + + } +#endif + + /* Would normally look up a vertex shader and peruse its list of + * varients somehow. We omitted that step and put all the + * hardcoded "shaders" into an array. We're just making the + * assumption that this happens to be a matching shader... ie + * you're running isosurf, aren't you? + */ + fse->active = draw_vs_lookup_varient( draw->vs.vertex_shader, + &fse->key ); + + if (!fse->active) { + assert(0); + return ; + } + + /* Now set buffer pointers: + */ + for (i = 0; i < num_vs_inputs; i++) { + unsigned buf = draw->pt.vertex_element[i].vertex_buffer_index; + + fse->active->set_input( fse->active, + i, + + ((const ubyte *) draw->pt.user.vbuffer[buf] + + draw->pt.vertex_buffer[buf].buffer_offset), + + draw->pt.vertex_buffer[buf].pitch ); + } + + fse->active->set_constants( fse->active, + (const float (*)[4])draw->pt.user.constants ); + + //return TRUE; +} + + + + + + + +static void fse_run_linear( struct draw_pt_middle_end *middle, + unsigned start, + unsigned count ) +{ + struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; + struct draw_context *draw = fse->draw; + unsigned alloc_count = align(count, 4); + char *hw_verts; + + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + + hw_verts = draw->render->allocate_vertices( draw->render, + (ushort)fse->key.output_stride, + (ushort)alloc_count ); + + if (!hw_verts) { + assert(0); + return; + } + + /* Single routine to fetch vertices, run shader and emit HW verts. + * Clipping and viewport transformation are done elsewhere -- + * either by the API or on hardware, or for some other reason not + * required... + */ + fse->active->run_linear( fse->active, + start, count, + hw_verts ); + + /* Draw arrays path to avoid re-emitting index list again and + * again. + */ + draw->render->draw_arrays( draw->render, + 0, + count ); + + + draw->render->release_vertices( draw->render, + hw_verts, + fse->key.output_stride, + count ); +} + + +static void +fse_run(struct draw_pt_middle_end *middle, + const unsigned *fetch_elts, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; + struct draw_context *draw = fse->draw; + unsigned alloc_count = align(fetch_count, 4); + void *hw_verts; + + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + + hw_verts = draw->render->allocate_vertices( draw->render, + (ushort)fse->key.output_stride, + (ushort)alloc_count ); + if (!hw_verts) { + assert(0); + return; + } + + + /* Single routine to fetch vertices, run shader and emit HW verts. + */ + fse->active->run_elts( fse->active, + fetch_elts, + fetch_count, + hw_verts ); + + draw->render->draw( draw->render, + draw_elts, + draw_count ); + + draw->render->release_vertices( draw->render, + hw_verts, + fse->key.output_stride, + fetch_count ); + +} + + +static void fse_finish( struct draw_pt_middle_end *middle ) +{ +} + + +static void +fse_destroy( struct draw_pt_middle_end *middle ) +{ + FREE(middle); +} + +struct draw_pt_middle_end *draw_pt_middle_fse( struct draw_context *draw ) +{ + struct fetch_shade_emit *fse = CALLOC_STRUCT(fetch_shade_emit); + if (!fse) + return NULL; + + fse->base.prepare = fse_prepare; + fse->base.run = fse_run; + fse->base.run_linear = fse_run_linear; + fse->base.finish = fse_finish; + fse->base.destroy = fse_destroy; + fse->draw = draw; + + return &fse->base; +} diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 4142dd9589..9b899d404e 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -36,6 +36,8 @@ #include "draw_private.h" #include "draw_context.h" #include "draw_vs.h" +#include "translate/translate.h" +#include "translate/translate_cache.h" @@ -90,11 +92,25 @@ boolean draw_vs_init( struct draw_context *draw ) { tgsi_exec_machine_init(&draw->vs.machine); + /* FIXME: give this machine thing a proper constructor: */ draw->vs.machine.Inputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); - draw->vs.machine.Outputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); + if (!draw->vs.machine.Inputs) + return FALSE; + draw->vs.machine.Outputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); + if (!draw->vs.machine.Outputs) + return FALSE; + + draw->vs.emit_cache = translate_cache_create(); + if (!draw->vs.emit_cache) + return FALSE; + + draw->vs.fetch_cache = translate_cache_create(); + if (!draw->vs.fetch_cache) + return FALSE; + return TRUE; } @@ -107,6 +123,71 @@ draw_vs_destroy( struct draw_context *draw ) if (draw->vs.machine.Outputs) align_free(draw->vs.machine.Outputs); + if (draw->vs.fetch_cache) + translate_cache_destroy(draw->vs.fetch_cache); + + if (draw->vs.emit_cache) + translate_cache_destroy(draw->vs.emit_cache); + tgsi_exec_machine_free_data(&draw->vs.machine); } + + +struct draw_vs_varient * +draw_vs_lookup_varient( struct draw_vertex_shader *vs, + const struct draw_vs_varient_key *key ) +{ + struct draw_vs_varient *varient; + unsigned i; + + /* Lookup existing varient: + */ + for (i = 0; i < vs->nr_varients; i++) + if (draw_vs_varient_key_compare(key, &vs->varient[i]->key) == 0) + return vs->varient[i]; + + /* Else have to create a new one: + */ + varient = vs->create_varient( vs, key ); + if (varient == NULL) + return NULL; + + /* Add it to our list: + */ + assert(vs->nr_varients < Elements(vs->varient)); + vs->varient[vs->nr_varients++] = varient; + + /* Done + */ + return varient; +} + + +struct translate * +draw_vs_get_fetch( struct draw_context *draw, + struct translate_key *key ) +{ + if (!draw->vs.fetch || + translate_key_compare(&draw->vs.fetch->key, key) != 0) + { + translate_key_sanitize(key); + draw->vs.fetch = translate_cache_find(draw->vs.fetch_cache, key); + } + + return draw->vs.fetch; +} + +struct translate * +draw_vs_get_emit( struct draw_context *draw, + struct translate_key *key ) +{ + if (!draw->vs.emit || + translate_key_compare(&draw->vs.emit->key, key) != 0) + { + translate_key_sanitize(key); + draw->vs.emit = translate_cache_find(draw->vs.emit_cache, key); + } + + return draw->vs.emit; +} diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index f9772b83b8..677be0d28d 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -38,10 +38,63 @@ struct draw_context; struct pipe_shader_state; +struct draw_vs_input +{ + enum pipe_format format; + unsigned buffer; + unsigned offset; +}; + +struct draw_vs_output +{ + enum pipe_format format; + unsigned offset; +}; + +struct draw_vs_element { + struct draw_vs_input in; + struct draw_vs_output out; +}; + +struct draw_vs_varient_key { + unsigned output_stride; + unsigned nr_elements; + struct draw_vs_element element[PIPE_MAX_ATTRIBS]; +}; + +struct draw_vs_varient { + struct draw_vs_varient_key key; + + struct draw_vertex_shader *vs; + + void (*set_input)( struct draw_vs_varient *, + unsigned i, + const void *ptr, + unsigned stride ); + + void (*set_constants)( struct draw_vs_varient *, + const float (*constants)[4] ); + + + void (*run_linear)( struct draw_vs_varient *shader, + unsigned start, + unsigned count, + void *output_buffer ); + + void (*run_elts)( struct draw_vs_varient *shader, + const unsigned *elts, + unsigned count, + void *output_buffer ); + + void (*destroy)( struct draw_vs_varient * ); +}; + + /** * Private version of the compiled vertex_shader */ struct draw_vertex_shader { + struct draw_context *draw; /* This member will disappear shortly: */ @@ -49,6 +102,14 @@ struct draw_vertex_shader { struct tgsi_shader_info info; + /* + */ + struct draw_vs_varient *varient[16]; + unsigned nr_varients; + struct draw_vs_varient *(*create_varient)( struct draw_vertex_shader *shader, + const struct draw_vs_varient_key *key ); + + void (*prepare)( struct draw_vertex_shader *shader, struct draw_context *draw ); @@ -68,6 +129,15 @@ struct draw_vertex_shader { }; +struct draw_vs_varient * +draw_vs_lookup_varient( struct draw_vertex_shader *base, + const struct draw_vs_varient_key *key ); + + +/******************************************************************************** + * Internal functions: + */ + struct draw_vertex_shader * draw_create_vs_exec(struct draw_context *draw, const struct pipe_shader_state *templ); @@ -80,8 +150,43 @@ struct draw_vertex_shader * draw_create_vs_llvm(struct draw_context *draw, const struct pipe_shader_state *templ); +/******************************************************************************** + * Helpers for vs implementations that don't do their own fetch/emit varients. + * Means these can be shared between shaders. + */ +struct translate; +struct translate_key; + +struct translate *draw_vs_get_fetch( struct draw_context *draw, + struct translate_key *key ); + + +struct translate *draw_vs_get_emit( struct draw_context *draw, + struct translate_key *key ); + +struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, + const struct draw_vs_varient_key *key ); + + + +static INLINE int draw_vs_varient_keysize( const struct draw_vs_varient_key *key ) +{ + return 2 * sizeof(int) + key->nr_elements * sizeof(struct draw_vs_element); +} + +static INLINE int draw_vs_varient_key_compare( const struct draw_vs_varient_key *a, + const struct draw_vs_varient_key *b ) +{ + int keysize = draw_vs_varient_keysize(a); + return memcmp(a, b, keysize); +} + + + + #define MAX_TGSI_VERTICES 4 + #endif diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index cb80d008cd..4501877efc 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -179,9 +179,11 @@ draw_create_vs_exec(struct draw_context *draw, tgsi_scan_shader(state->tokens, &vs->base.info); + vs->base.draw = draw; vs->base.prepare = vs_exec_prepare; vs->base.run_linear = vs_exec_run_linear; vs->base.delete = vs_exec_delete; + vs->base.create_varient = draw_vs_varient_generic; vs->machine = &draw->vs.machine; return &vs->base; diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 171da51dd5..621472ec7c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -114,7 +114,9 @@ draw_create_vs_llvm(struct draw_context *draw, tgsi_scan_shader(vs->base.state.tokens, &vs->base.info); + vs->base.draw = draw; vs->base.prepare = vs_llvm_prepare; + vs->base.create_varient = draw_vs_varient_generic; vs->base.run_linear = vs_llvm_run_linear; vs->base.delete = vs_llvm_delete; vs->machine = &draw->machine; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 13ad032bd3..df94a7e0c7 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -155,6 +155,8 @@ draw_create_vs_sse(struct draw_context *draw, tgsi_scan_shader(templ->tokens, &vs->base.info); + vs->base.draw = draw; + vs->base.create_varient = draw_vs_varient_generic; vs->base.prepare = vs_sse_prepare; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c new file mode 100644 index 0000000000..d27b0f6187 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -0,0 +1,229 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_vs.h" +#include "translate/translate.h" +#include "translate/translate_cache.h" + +/* A first pass at incorporating vertex fetch/emit functionality into + */ +struct draw_vs_varient_generic { + struct draw_vs_varient base; + + + + struct draw_vertex_shader *shader; + struct draw_context *draw; + + /* Basic plan is to run these two translate functions before/after + * the vertex shader's existing run_linear() routine to simulate + * the inclusion of this functionality into the shader... + * + * Next will look at actually including it. + */ + struct translate *fetch; + struct translate *emit; + + const float (*constants)[4]; +}; + + + + +static void vsvg_set_constants( struct draw_vs_varient *varient, + const float (*constants)[4] ) +{ + struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; + + vsvg->constants = constants; +} + + +static void vsvg_set_input( struct draw_vs_varient *varient, + unsigned buffer, + const void *ptr, + unsigned stride ) +{ + struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; + + vsvg->fetch->set_buffer(vsvg->fetch, + buffer, + ptr, + stride); +} + + +static void vsvg_run_elts( struct draw_vs_varient *varient, + const unsigned *elts, + unsigned count, + void *output_buffer) +{ + struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; + + /* Want to do this in small batches for cache locality? + */ + + vsvg->fetch->run_elts( vsvg->fetch, + elts, + count, + output_buffer ); + + //if (!vsvg->base.vs->is_passthrough) + { + vsvg->base.vs->run_linear( vsvg->base.vs, + output_buffer, + output_buffer, + vsvg->constants, + count, + vsvg->base.key.output_stride, + vsvg->base.key.output_stride); + + //if (!vsvg->already_in_emit_format) + + vsvg->emit->set_buffer( vsvg->emit, + 0, + output_buffer, + vsvg->base.key.output_stride ); + + + vsvg->emit->run( vsvg->emit, + 0, count, + output_buffer ); + } +} + + +static void vsvg_run_linear( struct draw_vs_varient *varient, + unsigned start, + unsigned count, + void *output_buffer ) +{ + struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; + + //debug_printf("%s %d %d\n", __FUNCTION__, start, count); + + + vsvg->fetch->run( vsvg->fetch, + start, + count, + output_buffer ); + + //if (!vsvg->base.vs->is_passthrough) + { + vsvg->base.vs->run_linear( vsvg->base.vs, + output_buffer, + output_buffer, + vsvg->constants, + count, + vsvg->base.key.output_stride, + vsvg->base.key.output_stride); + + //if (!vsvg->already_in_emit_format) + vsvg->emit->set_buffer( vsvg->emit, + 0, + output_buffer, + vsvg->base.key.output_stride ); + + + vsvg->emit->run( vsvg->emit, + 0, count, + output_buffer ); + } +} + + + +static void vsvg_destroy( struct draw_vs_varient *varient ) +{ + FREE(varient); +} + + +struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, + const struct draw_vs_varient_key *key ) +{ + unsigned i; + struct translate_key fetch, emit; + + struct draw_vs_varient_generic *vsvg = CALLOC_STRUCT( draw_vs_varient_generic ); + if (vsvg == NULL) + return NULL; + + vsvg->base.key = *key; + vsvg->base.vs = vs; + vsvg->base.set_input = vsvg_set_input; + vsvg->base.set_constants = vsvg_set_constants; + vsvg->base.run_elts = vsvg_run_elts; + vsvg->base.run_linear = vsvg_run_linear; + vsvg->base.destroy = vsvg_destroy; + + + + /* OK, have to build a new one: + */ + fetch.nr_elements = vs->info.num_inputs; + fetch.output_stride = 0; + for (i = 0; i < vs->info.num_inputs; i++) { + fetch.element[i].input_format = key->element[i].in.format; + fetch.element[i].input_buffer = key->element[i].in.buffer; + fetch.element[i].input_offset = key->element[i].in.offset; + fetch.element[i].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fetch.element[i].output_offset = fetch.output_stride; + fetch.output_stride += 4 * sizeof(float); + } + + + emit.nr_elements = vs->info.num_outputs; + emit.output_stride = key->output_stride; + for (i = 0; i < vs->info.num_outputs; i++) { + emit.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit.element[i].input_buffer = 0; + emit.element[i].input_offset = i * 4 * sizeof(float); + emit.element[i].output_format = key->element[i].out.format; + emit.element[i].output_offset = key->element[i].out.offset; + } + + vsvg->fetch = draw_vs_get_fetch( vs->draw, &fetch ); + vsvg->emit = draw_vs_get_emit( vs->draw, &emit ); + + return &vsvg->base; +} + + + + + -- cgit v1.2.3 From 9232f0c023af060b12f77dee5e8b6a533c48e146 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 19 May 2008 16:28:53 +0100 Subject: rtasm: remove unused struct member --- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index eacaeeaf6f..baa10b7d4a 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -44,7 +44,6 @@ struct x86_function { unsigned stack_offset; int need_emms; unsigned char error_overflow[4]; - const char *fn; }; enum x86_reg_file { -- cgit v1.2.3 From 8618e6aa16bdba2c8b08124261bbaedaf7e22447 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 20 May 2008 14:34:06 +0100 Subject: translate: remove spurious comment --- src/gallium/auxiliary/translate/translate_sse.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index a54ac5a82f..582d6f6466 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -472,13 +472,7 @@ static boolean build_vertex_emit( struct translate_sse *p, x86_lea(p->func, vertexECX, x86_make_disp(vertexECX, p->translate.key.output_stride)); /* Incr index - */ /* Emit code for each of the attributes. Currently routes - * everything through SSE registers, even when it might be more - * efficient to stick with regular old x86. No optimization or - * other tricks - enough new ground to cover here just getting - * things working. - */ - + */ if (linear) { x86_inc(p->func, idxEBX); } -- cgit v1.2.3 From d3e64caef6f8654af1a84825803e517ab8221c68 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 08:28:16 +0100 Subject: rtasm: export debug reg print function --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 20 +++++++++----------- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 3 +++ 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 4e036d9032..68ac91ed13 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -36,11 +36,8 @@ #define DUMP_SSE 0 -#if DUMP_SSE -static void -_print_reg( - struct x86_reg reg ) +void x86_print_reg( struct x86_reg reg ) { if (reg.mod != mod_REG) debug_printf( "[" ); @@ -77,6 +74,7 @@ _print_reg( debug_printf( "]" ); } +#if DUMP_SSE #define DUMP_START() debug_printf( "\n" ) #define DUMP_END() debug_printf( "\n" ) @@ -87,7 +85,7 @@ _print_reg( foo++; \ if (*foo) \ foo++; \ - debug_printf( "\n% 15s ", foo ); \ + debug_printf( "\n% 4x% 15s ", p->csr - p->store, foo ); \ } while (0) #define DUMP_I( I ) do { \ @@ -97,27 +95,27 @@ _print_reg( #define DUMP_R( R0 ) do { \ DUMP(); \ - _print_reg( R0 ); \ + x86_print_reg( R0 ); \ } while( 0 ) #define DUMP_RR( R0, R1 ) do { \ DUMP(); \ - _print_reg( R0 ); \ + x86_print_reg( R0 ); \ debug_printf( ", " ); \ - _print_reg( R1 ); \ + x86_print_reg( R1 ); \ } while( 0 ) #define DUMP_RI( R0, I ) do { \ DUMP(); \ - _print_reg( R0 ); \ + x86_print_reg( R0 ); \ debug_printf( ", %u", I ); \ } while( 0 ) #define DUMP_RRI( R0, R1, I ) do { \ DUMP(); \ - _print_reg( R0 ); \ + x86_print_reg( R0 ); \ debug_printf( ", " ); \ - _print_reg( R1 ); \ + x86_print_reg( R1 ); \ debug_printf( ", %u", I ); \ } while( 0 ) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index baa10b7d4a..1e02c6e73b 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -106,6 +106,9 @@ void x86_init_func_size( struct x86_function *p, unsigned code_size ); void x86_release_func( struct x86_function *p ); void (*x86_get_func( struct x86_function *p ))( void ); +/* Debugging: + */ +void x86_print_reg( struct x86_reg reg ); /* Create and manipulate registers and regmem values: -- cgit v1.2.3 From 9343779a8c800cf72e38b09b6f5087a0df258c08 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 08:28:53 +0100 Subject: gallium: define PIPE_CDECL calling convention, which really is cdecl everywhere --- src/gallium/include/pipe/p_compiler.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index a4b772bc4f..01d1807b1c 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -103,6 +103,17 @@ typedef unsigned int uintptr_t; #endif +/* This should match linux gcc cdecl semantics everywhere, so that we + * just codegen one calling convention on all platforms. + */ +#ifdef WIN32 +#define PIPE_CDECL __cdecl +#else +#define PIPE_CDECL +#endif + + + #if defined __GNUC__ #define ALIGN16_DECL(TYPE, NAME, SIZE) TYPE NAME##___aligned[SIZE] __attribute__(( aligned( 16 ) )) #define ALIGN16_ASSIGN(NAME) NAME##___aligned @@ -115,12 +126,16 @@ typedef unsigned int uintptr_t; -/** For calling code-gen'd functions */ +/** + * For calling code-gen'd functions, phase out in favor of + * PIPE_CDECL, above, which really means cdecl on all platforms, not + * like the below... + */ #if !defined(XSTDCALL) #if defined(WIN32) -#define XSTDCALL __stdcall +#define XSTDCALL __stdcall /* phase this out */ #else -#define XSTDCALL +#define XSTDCALL /* XXX: NOTE! not STDCALL! */ #endif #endif -- cgit v1.2.3 From b5c8b3fba6ac90a0d83e02bfe432142f1adee9e5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 08:29:19 +0100 Subject: translate: mark functions as PIPE_CDECL --- src/gallium/auxiliary/translate/translate.h | 18 +++++++++--------- src/gallium/auxiliary/translate/translate_generic.c | 16 ++++++++-------- src/gallium/auxiliary/translate/translate_sse.c | 20 +++++++------------- 3 files changed, 24 insertions(+), 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index b8210af50c..c3b754a902 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -71,15 +71,15 @@ struct translate { const void *ptr, unsigned stride ); - void (*run_elts)( struct translate *, - const unsigned *elts, - unsigned count, - void *output_buffer); - - void (*run)( struct translate *, - unsigned start, - unsigned count, - void *output_buffer); + void (PIPE_CDECL *run_elts)( struct translate *, + const unsigned *elts, + unsigned count, + void *output_buffer); + + void (PIPE_CDECL *run)( struct translate *, + unsigned start, + unsigned count, + void *output_buffer); }; diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 402780ee53..a25d94f2ca 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -541,10 +541,10 @@ static emit_func get_emit_func( enum pipe_format format ) /** * Fetch vertex attributes for 'count' vertices. */ -static void generic_run_elts( struct translate *translate, - const unsigned *elts, - unsigned count, - void *output_buffer ) +static void PIPE_CDECL generic_run_elts( struct translate *translate, + const unsigned *elts, + unsigned count, + void *output_buffer ) { struct translate_generic *tg = translate_generic(translate); char *vert = output_buffer; @@ -580,10 +580,10 @@ static void generic_run_elts( struct translate *translate, -static void generic_run( struct translate *translate, - unsigned start, - unsigned count, - void *output_buffer ) +static void PIPE_CDECL generic_run( struct translate *translate, + unsigned start, + unsigned count, + void *output_buffer ) { struct translate_generic *tg = translate_generic(translate); char *vert = output_buffer; diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index 582d6f6466..2fc8b9d3d0 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -45,22 +45,16 @@ #define W 3 -#ifdef WIN32 -#define RTASM __cdecl -#else -#define RTASM -#endif - -typedef void (RTASM *run_func)( struct translate *translate, - unsigned start, - unsigned count, - void *output_buffer ); - -typedef void (RTASM *run_elts_func)( struct translate *translate, - const unsigned *elts, +typedef void (PIPE_CDECL *run_func)( struct translate *translate, + unsigned start, unsigned count, void *output_buffer ); +typedef void (PIPE_CDECL *run_elts_func)( struct translate *translate, + const unsigned *elts, + unsigned count, + void *output_buffer ); + struct translate_sse { -- cgit v1.2.3 From ba738a3135415de8b381cd8845cd6c435d5747a8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 09:43:30 +0100 Subject: draw: mark varient functions as PIPE_CDECL --- src/gallium/auxiliary/draw/draw_vs.h | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 677be0d28d..6bfc2c8d75 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -62,6 +62,19 @@ struct draw_vs_varient_key { struct draw_vs_element element[PIPE_MAX_ATTRIBS]; }; +struct draw_vs_varient; + +typedef void (PIPE_CDECL *vsv_run_elts_func)( struct draw_vs_varient *, + const unsigned *elts, + unsigned count, + void *output_buffer); + +typedef void (PIPE_CDECL *vsv_run_linear_func)( struct draw_vs_varient *, + unsigned start, + unsigned count, + void *output_buffer); + + struct draw_vs_varient { struct draw_vs_varient_key key; @@ -75,16 +88,15 @@ struct draw_vs_varient { void (*set_constants)( struct draw_vs_varient *, const float (*constants)[4] ); + void (PIPE_CDECL *run_linear)( struct draw_vs_varient *shader, + unsigned start, + unsigned count, + void *output_buffer ); - void (*run_linear)( struct draw_vs_varient *shader, - unsigned start, - unsigned count, - void *output_buffer ); - - void (*run_elts)( struct draw_vs_varient *shader, - const unsigned *elts, - unsigned count, - void *output_buffer ); + void (PIPE_CDECL *run_elts)( struct draw_vs_varient *shader, + const unsigned *elts, + unsigned count, + void *output_buffer ); void (*destroy)( struct draw_vs_varient * ); }; -- cgit v1.2.3 From 1ba10e5ccf5cd0c990922e982e1e9bc6be48a5e4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 09:44:16 +0100 Subject: draw: add aos vertex shader varient --- src/gallium/auxiliary/draw/Makefile | 2 + src/gallium/auxiliary/draw/draw_vs.h | 10 + src/gallium/auxiliary/draw/draw_vs_aos.c | 1739 +++++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_aos.h | 181 +++ src/gallium/auxiliary/draw/draw_vs_aos_io.c | 314 +++++ src/gallium/auxiliary/draw/draw_vs_sse.c | 1 + 6 files changed, 2247 insertions(+) create mode 100644 src/gallium/auxiliary/draw/draw_vs_aos.c create mode 100644 src/gallium/auxiliary/draw/draw_vs_aos.h create mode 100644 src/gallium/auxiliary/draw/draw_vs_aos_io.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 84877994fb..9a88ecc070 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -35,6 +35,8 @@ C_SOURCES = \ draw_vertex.c \ draw_vs.c \ draw_vs_varient.c \ + draw_vs_aos.c \ + draw_vs_aos_io.c \ draw_vs_exec.c \ draw_vs_llvm.c \ draw_vs_sse.c diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 6bfc2c8d75..5a8d0da06d 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -162,6 +162,16 @@ struct draw_vertex_shader * draw_create_vs_llvm(struct draw_context *draw, const struct pipe_shader_state *templ); + + +struct draw_vs_varient_key; +struct draw_vertex_shader; + +struct draw_vs_varient *draw_vs_varient_aos_sse( struct draw_vertex_shader *vs, + const struct draw_vs_varient_key *key ); + + + /******************************************************************************** * Helpers for vs implementations that don't do their own fetch/emit varients. * Means these can be shared between shaders. diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c new file mode 100644 index 0000000000..620f5e3592 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -0,0 +1,1739 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * Translate tgsi vertex programs to x86/x87/SSE/SSE2 machine code + * using the rtasm runtime assembler. Based on the old + * t_vb_arb_program_sse.c + */ + + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_vs.h" +#include "draw_vs_aos.h" + +#include "rtasm/rtasm_x86sse.h" + +#ifdef PIPE_ARCH_X86 + + +#define DISASSEM 0 + + + + + +static INLINE boolean eq( struct x86_reg a, + struct x86_reg b ) +{ + return (a.file == b.file && + a.idx == b.idx && + a.mod == b.mod && + a.disp == b.disp); +} + + +static struct x86_reg get_reg_ptr(struct aos_compilation *cp, + unsigned file, + unsigned idx ) +{ + struct x86_reg ptr = cp->machine_EDX; + + switch (file) { + case TGSI_FILE_INPUT: + return x86_make_disp(ptr, Offset(struct aos_machine, input[idx])); + + case TGSI_FILE_OUTPUT: + return x86_make_disp(ptr, Offset(struct aos_machine, output[idx])); + + case TGSI_FILE_TEMPORARY: + return x86_make_disp(ptr, Offset(struct aos_machine, temp[idx])); + + case TGSI_FILE_IMMEDIATE: + return x86_make_disp(ptr, Offset(struct aos_machine, immediate[idx])); + + case TGSI_FILE_CONSTANT: + return x86_make_disp(ptr, Offset(struct aos_machine, constant[idx])); + + case AOS_FILE_INTERNAL: + return x86_make_disp(ptr, Offset(struct aos_machine, immediate[idx])); + + default: + ERROR(cp, "unknown reg file"); + return x86_make_reg(0,0); + } +} + + +struct x86_reg aos_get_internal( struct aos_compilation *cp, + unsigned imm ) +{ + return get_reg_ptr( cp, + AOS_FILE_INTERNAL, + imm + 1 ); +} + +static void spill( struct aos_compilation *cp, unsigned idx ) +{ + if (!cp->xmm[idx].dirty || + (cp->xmm[idx].file != TGSI_FILE_INPUT && /* inputs are fetched into xmm & set dirty */ + cp->xmm[idx].file != TGSI_FILE_OUTPUT && + cp->xmm[idx].file != TGSI_FILE_TEMPORARY)) { + ERROR(cp, "invalid spill"); + return; + } + else { + struct x86_reg oldval = get_reg_ptr(cp, + cp->xmm[idx].file, + cp->xmm[idx].idx); + + assert(cp->xmm[idx].dirty); + sse_movups(cp->func, oldval, x86_make_reg(file_XMM, idx)); + cp->xmm[idx].dirty = 0; + } +} + +struct x86_reg aos_get_xmm_reg( struct aos_compilation *cp ) +{ + unsigned i; + unsigned oldest = 0; + + for (i = 0; i < 8; i++) + if (cp->xmm[i].last_used < cp->xmm[oldest].last_used) + oldest = i; + + /* Need to write out the old value? + */ + if (cp->xmm[oldest].dirty) + spill(cp, oldest); + + assert(cp->xmm[oldest].last_used != cp->insn_counter); + + cp->xmm[oldest].file = TGSI_FILE_NULL; + cp->xmm[oldest].idx = 0; + cp->xmm[oldest].last_used = cp->insn_counter; + return x86_make_reg(file_XMM, oldest); +} + +void aos_release_xmm_reg( struct aos_compilation *cp, + unsigned idx ) +{ + cp->xmm[idx].file = TGSI_FILE_NULL; + cp->xmm[idx].idx = 0; + cp->xmm[idx].dirty = 0; + cp->xmm[idx].last_used = 0; +} + +static void invalidate_xmm( struct aos_compilation *cp, + unsigned file, unsigned idx ) +{ + unsigned i; + + /* Invalidate any old copy of this register in XMM0-7. + */ + for (i = 0; i < 8; i++) { + if (cp->xmm[i].file == file && cp->xmm[i].idx == idx) { + + if (cp->xmm[i].dirty) + spill(cp, i); + + aos_release_xmm_reg(cp, i); + break; + } + } + + for (; i < 8; i++) { + if (cp->xmm[i].file == file && cp->xmm[i].idx == idx) { + assert(0); + } + } +} + + +void aos_adopt_xmm_reg( struct aos_compilation *cp, + struct x86_reg reg, + unsigned file, + unsigned idx, + unsigned dirty ) +{ + if (reg.file != file_XMM) { + assert(0); + return; + } + + invalidate_xmm(cp, file, idx); + cp->xmm[reg.idx].file = file; + cp->xmm[reg.idx].idx = idx; + cp->xmm[reg.idx].dirty = dirty; +} + + + +static struct x86_reg aos_get_shader_reg_ptr( struct aos_compilation *cp, + unsigned file, + unsigned idx ) +{ + invalidate_xmm( cp, file, idx ); + return get_reg_ptr( cp, file, idx ); +} + + +/* As above, but return a pointer. Note - this pointer may alias + * those returned by get_arg_ptr(). + */ +static struct x86_reg get_dst_ptr( struct aos_compilation *cp, + const struct tgsi_full_dst_register *dst ) +{ + return aos_get_shader_reg_ptr( cp, dst->DstRegister.File, dst->DstRegister.Index ); +} + + + + + +/* Return an XMM reg if the argument is resident, otherwise return a + * base+offset pointer to the saved value. + */ +struct x86_reg aos_get_shader_reg( struct aos_compilation *cp, + unsigned file, + unsigned idx ) +{ + unsigned i; + + for (i = 0; i < 8; i++) { + if (cp->xmm[i].file == file && + cp->xmm[i].idx == idx) + { + cp->xmm[i].last_used = cp->insn_counter; + return x86_make_reg(file_XMM, i); + } + } + + /* If not found in the XMM register file, return an indirect + * reference to the in-memory copy: + */ + return get_reg_ptr( cp, file, idx ); +} + + + + + +/* Emulate pshufd insn in regular SSE, if necessary: + */ +static void emit_pshufd( struct aos_compilation *cp, + struct x86_reg dst, + struct x86_reg arg0, + ubyte shuf ) +{ + if (cp->have_sse2) { + sse2_pshufd(cp->func, dst, arg0, shuf); + } + else { + if (!eq(dst, arg0)) + sse_movups(cp->func, dst, arg0); + + sse_shufps(cp->func, dst, dst, shuf); + } +} + + + + +/* Helper for writemask: + */ +static boolean emit_shuf_copy1( struct aos_compilation *cp, + struct x86_reg dst, + struct x86_reg arg0, + struct x86_reg arg1, + ubyte shuf ) +{ + struct x86_reg tmp = aos_get_xmm_reg(cp); + sse_movups(cp->func, dst, arg1); + emit_pshufd(cp, dst, dst, shuf); + emit_pshufd(cp, tmp, arg0, shuf); + + sse_movss(cp->func, dst, tmp); + + emit_pshufd(cp, dst, dst, shuf); + + aos_release_xmm_reg(cp, tmp.idx); + return TRUE; +} + + +/* Helper for writemask: + */ +static boolean emit_shuf_copy2( struct aos_compilation *cp, + struct x86_reg dst, + struct x86_reg arg0, + struct x86_reg arg1, + ubyte shuf ) +{ + struct x86_reg tmp = aos_get_xmm_reg(cp); + emit_pshufd(cp, dst, arg1, shuf); + emit_pshufd(cp, tmp, arg0, shuf); + + sse_shufps(cp->func, dst, tmp, SHUF(X, Y, Z, W)); + + emit_pshufd(cp, dst, dst, shuf); + + aos_release_xmm_reg(cp, tmp.idx); + return TRUE; +} + +#define SSE_SWIZZLE_NOOP ((0<<0) | (1<<2) | (2<<4) | (3<<6)) + + +/* Locate a source register and perform any required (simple) swizzle. + * + * Just fail on complex swizzles at this point. + */ +static struct x86_reg fetch_src( struct aos_compilation *cp, + const struct tgsi_full_src_register *src ) +{ + struct x86_reg arg0 = aos_get_shader_reg(cp, + src->SrcRegister.File, + src->SrcRegister.Index); + unsigned i; + unsigned swz = 0; + unsigned negs = 0; + unsigned abs = 0; + + for (i = 0; i < 4; i++) { + unsigned swizzle = tgsi_util_get_full_src_register_extswizzle( src, i ); + unsigned neg = tgsi_util_get_full_src_register_sign_mode( src, i ); + + switch (swizzle) { + case TGSI_EXTSWIZZLE_ZERO: + case TGSI_EXTSWIZZLE_ONE: + ERROR(cp, "not supporting full swizzles yet in tgsi_aos_sse2"); + break; + + default: + swz |= (swizzle & 0x3) << (i * 2); + break; + } + + switch (neg) { + case TGSI_UTIL_SIGN_TOGGLE: + negs |= (1<func, dst, arg0); + + aos_release_xmm_reg(cp, tmp.idx); + arg0 = dst; + } + + if (abs && abs != 0xf) { + ERROR(cp, "unsupported partial abs"); + } + + if (abs) { + struct x86_reg neg = aos_get_internal(cp, IMM_NEGS); + struct x86_reg tmp = aos_get_xmm_reg(cp); + + sse_movups(cp->func, tmp, arg0); + sse_mulps(cp->func, tmp, neg); + sse_maxps(cp->func, dst, arg0); + + aos_release_xmm_reg(cp, tmp.idx); + arg0 = dst; + } + } + + return arg0; +} + +static void x87_fld_src( struct aos_compilation *cp, + const struct tgsi_full_src_register *src, + unsigned channel ) +{ + struct x86_reg arg0 = aos_get_shader_reg_ptr(cp, + src->SrcRegister.File, + src->SrcRegister.Index); + + unsigned swizzle = tgsi_util_get_full_src_register_extswizzle( src, channel ); + unsigned neg = tgsi_util_get_full_src_register_sign_mode( src, channel ); + + switch (swizzle) { + case TGSI_EXTSWIZZLE_ZERO: + x87_fldz( cp->func ); + break; + + case TGSI_EXTSWIZZLE_ONE: + x87_fld1( cp->func ); + break; + + default: + x87_fld( cp->func, x86_make_disp(arg0, (swizzle & 3) * sizeof(float)) ); + break; + } + + + switch (neg) { + case TGSI_UTIL_SIGN_TOGGLE: + /* Flip the sign: + */ + x87_fchs( cp->func ); + break; + + case TGSI_UTIL_SIGN_KEEP: + break; + + case TGSI_UTIL_SIGN_CLEAR: + x87_fabs( cp->func ); + break; + + case TGSI_UTIL_SIGN_SET: + x87_fabs( cp->func ); + x87_fchs( cp->func ); + break; + + default: + ERROR(cp, "unsupported sign-mode"); + break; + } +} + + + + + + +/* Used to implement write masking. This and most of the other instructions + * here would be easier to implement if there had been a translation + * to a 2 argument format (dst/arg0, arg1) at the shader level before + * attempting to translate to x86/sse code. + */ +static void store_dest( struct aos_compilation *cp, + const struct tgsi_full_dst_register *reg, + struct x86_reg result ) +{ + if (reg->DstRegister.WriteMask == 0) + { + return; + } + else if (reg->DstRegister.WriteMask == TGSI_WRITEMASK_XYZW) + { + if (result.file == file_XMM) { + aos_adopt_xmm_reg(cp, + result, + reg->DstRegister.File, + reg->DstRegister.Index, + TRUE); + } + else { + struct x86_reg dst = aos_get_xmm_reg(cp); + aos_adopt_xmm_reg(cp, + dst, + reg->DstRegister.File, + reg->DstRegister.Index, + TRUE); + sse_movups(cp->func, dst, result); + } + } + else + { + /* Previous value of the dest register: + */ + struct x86_reg old_dst = aos_get_shader_reg(cp, + reg->DstRegister.File, + reg->DstRegister.Index); + + + /* Alloc an xmm reg to hold the new value of the dest register: + */ + struct x86_reg dst = aos_get_xmm_reg(cp); + + aos_adopt_xmm_reg(cp, + dst, + reg->DstRegister.File, + reg->DstRegister.Index, + TRUE ); + + switch (reg->DstRegister.WriteMask) { + case TGSI_WRITEMASK_X: + if (result.file == file_XMM) { + sse_movups(cp->func, dst, old_dst); + sse_movss(cp->func, dst, result); + } + else { + struct x86_reg tmp = aos_get_xmm_reg(cp); + sse_movups(cp->func, dst, old_dst); + sse_movss(cp->func, tmp, result); + sse_movss(cp->func, dst, tmp); + aos_release_xmm_reg(cp, tmp.idx); + } + break; + + case TGSI_WRITEMASK_XY: + sse_movups(cp->func, dst, old_dst); + sse_shufps(cp->func, dst, result, SHUF(X, Y, Z, W)); + break; + + case TGSI_WRITEMASK_ZW: + sse_movups(cp->func, dst, result); + sse_shufps(cp->func, dst, old_dst, SHUF(X, Y, Z, W)); + break; + + case TGSI_WRITEMASK_YZW: + if (old_dst.file == file_XMM) { + sse_movups(cp->func, dst, result); + sse_movss(cp->func, dst, old_dst); + } + else { + struct x86_reg tmp = aos_get_xmm_reg(cp); + sse_movups(cp->func, dst, result); + sse_movss(cp->func, tmp, old_dst); + sse_movss(cp->func, dst, tmp); + aos_release_xmm_reg(cp, tmp.idx); + } + break; + + case TGSI_WRITEMASK_Y: + emit_shuf_copy1(cp, dst, result, old_dst, SHUF(Y,X,Z,W)); + break; + + case TGSI_WRITEMASK_Z: + emit_shuf_copy1(cp, dst, result, old_dst, SHUF(Z,Y,X,W)); + break; + + case TGSI_WRITEMASK_W: + emit_shuf_copy1(cp, dst, result, old_dst, SHUF(W,Y,Z,X)); + break; + + case TGSI_WRITEMASK_XZ: + emit_shuf_copy2(cp, dst, result, old_dst, SHUF(X,Z,Y,W)); + break; + + case TGSI_WRITEMASK_XW: + emit_shuf_copy2(cp, dst, result, old_dst, SHUF(X,W,Z,Y)); + + case TGSI_WRITEMASK_YZ: + emit_shuf_copy2(cp, dst, result, old_dst, SHUF(Z,Y,X,W)); + break; + + case TGSI_WRITEMASK_YW: + emit_shuf_copy2(cp, dst, result, old_dst, SHUF(W,Y,Z,X)); + break; + + case TGSI_WRITEMASK_XZW: + emit_shuf_copy1(cp, dst, old_dst, result, SHUF(Y,X,Z,W)); + break; + + case TGSI_WRITEMASK_XYW: + emit_shuf_copy1(cp, dst, old_dst, result, SHUF(Z,Y,X,W)); + break; + + case TGSI_WRITEMASK_XYZ: + emit_shuf_copy1(cp, dst, old_dst, result, SHUF(W,Y,Z,X)); + break; + + default: + assert(0); /* not possible */ + break; + } + } +} + + +static void x87_fst_or_nop( struct x86_function *func, + unsigned writemask, + unsigned channel, + struct x86_reg ptr ) +{ + if (writemask & (1<DstRegister.WriteMask; + + x87_fst_or_nop(cp->func, writemask, 0, ptr); + x87_fst_or_nop(cp->func, writemask, 1, ptr); + x87_fst_or_nop(cp->func, writemask, 2, ptr); + x87_fstp_or_pop(cp->func, writemask, 3, ptr); +} + +/* Save current x87 state and put it into single precision mode. + */ +static void save_fpu_state( struct aos_compilation *cp ) +{ +#if 0 + x87_fnstcw( cp->func, x86_make_disp(regEDX, get_offset(m, &m->fpucntl_restore))); + x87_fldcw( cp->func, ); +#endif +} + +static void restore_fpu_state( struct aos_compilation *cp ) +{ +#if 0 + x87_fnclex(cp->func); + x87_fldcw(cp->func, x86_make_disp(regEDX, get_offset(m, &m->fpucntl_restore))); +#endif +} + +static void set_fpu_round_neg_inf( struct aos_compilation *cp ) +{ +#if 0 + if (cp->fpucntl != RND_NEG_FPU) { + struct x86_reg regEDX = x86_make_reg(file_REG32, reg_DX); + struct arb_vp_machine *m = NULL; + + cp->fpucntl = RND_NEG_FPU; + x87_fnclex(cp->func); + x87_fldcw(cp->func, x86_make_disp(regEDX, get_offset(m, &m->fpucntl_rnd_neg))); + } +#endif +} + +static void set_fpu_round_nearest( struct aos_compilation *cp ) +{ +#if 0 +#endif +} + + +static void emit_x87_ex2( struct aos_compilation *cp ) +{ + struct x86_reg st0 = x86_make_reg(file_x87, 0); + struct x86_reg st1 = x86_make_reg(file_x87, 1); + struct x86_reg st3 = x86_make_reg(file_x87, 3); + + set_fpu_round_neg_inf( cp ); + + x87_fld(cp->func, st0); /* a a */ + x87_fprndint( cp->func ); /* int(a) a */ + x87_fld(cp->func, st0); /* int(a) int(a) a */ + x87_fstp(cp->func, st3); /* int(a) a int(a)*/ + x87_fsubp(cp->func, st1); /* frac(a) int(a) */ + x87_f2xm1(cp->func); /* (2^frac(a))-1 int(a)*/ + x87_fld1(cp->func); /* 1 (2^frac(a))-1 int(a)*/ + x87_faddp(cp->func, st1); /* 2^frac(a) int(a) */ + x87_fscale(cp->func); /* 2^a */ +} + + + +/** + * The traditional instructions. All operate on internal registers + * and ignore write masks and swizzling issues. + */ + +static boolean emit_ABS( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg neg = aos_get_internal(cp, IMM_NEGS); + + sse_movups(cp->func, dst, arg0); + sse_mulps(cp->func, dst, neg); + sse_maxps(cp->func, dst, arg0); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + +static boolean emit_ADD( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + + sse_movups(cp->func, dst, arg0); + sse_addps(cp->func, dst, arg1); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + +static boolean emit_COS( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + x87_fld_src(cp, &op->FullSrcRegisters[0], 0); + x87_fcos(cp->func); + x87_fstp_dest4(cp, &op->FullDstRegisters[0]); + return TRUE; +} + + +/* The dotproduct instructions don't really do that well in sse: + */ +static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg tmp = aos_get_xmm_reg(cp); + + sse_movups(cp->func, dst, arg0); + sse_mulps(cp->func, dst, arg1); + + /* Now the hard bit: sum the first 3 values: + */ + sse_movhlps(cp->func, tmp, dst); + sse_addss(cp->func, dst, tmp); /* a*x+c*z, b*y, ?, ? */ + emit_pshufd(cp, tmp, dst, SHUF(Y,X,W,Z)); + sse_addss(cp->func, dst, tmp); + sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); + + aos_release_xmm_reg(cp, tmp.idx); + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + + + +static boolean emit_DP4( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg tmp = aos_get_xmm_reg(cp); + + sse_movups(cp->func, dst, arg0); + sse_mulps(cp->func, dst, arg1); + + /* Now the hard bit: sum the values: + */ + sse_movhlps(cp->func, tmp, dst); + sse_addps(cp->func, dst, tmp); /* a*x+c*z, b*y+d*w, a*x+c*z, b*y+d*w */ + emit_pshufd(cp, tmp, dst, SHUF(Y,X,W,Z)); + sse_addss(cp->func, dst, tmp); + sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); + + aos_release_xmm_reg(cp, tmp.idx); + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + +static boolean emit_DPH( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg tmp = aos_get_xmm_reg(cp); + + sse_movups(cp->func, dst, arg0); + sse_mulps(cp->func, dst, arg1); + + /* Now the hard bit: sum the values (from DP3): + */ + sse_movhlps(cp->func, tmp, dst); + sse_addss(cp->func, dst, tmp); /* a*x+c*z, b*y, ?, ? */ + emit_pshufd(cp, tmp, dst, SHUF(Y,X,W,Z)); + sse_addss(cp->func, dst, tmp); + emit_pshufd(cp, tmp, arg1, SHUF(W,W,W,W)); + sse_addss(cp->func, dst, tmp); + sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); + + aos_release_xmm_reg(cp, tmp.idx); + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + +static boolean emit_DST( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg tmp = aos_get_xmm_reg(cp); + struct x86_reg ones = aos_get_internal(cp, IMM_ONES); + +/* dst[0] = 1.0 * 1.0F; */ +/* dst[1] = arg0[1] * arg1[1]; */ +/* dst[2] = arg0[2] * 1.0; */ +/* dst[3] = 1.0 * arg1[3]; */ + + emit_shuf_copy2(cp, dst, arg0, ones, SHUF(X,W,Z,Y)); + emit_shuf_copy2(cp, tmp, arg1, ones, SHUF(X,Z,Y,W)); + sse_mulps(cp->func, dst, tmp); + + aos_release_xmm_reg(cp, tmp.idx); + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + +static boolean emit_LG2( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + x87_fld1(cp->func); /* 1 */ + x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* a0 1 */ + x87_fyl2x(cp->func); /* log2(a0) */ + x87_fstp_dest4(cp, &op->FullDstRegisters[0]); + return TRUE; +} + + +static boolean emit_EX2( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + x87_fld_src(cp, &op->FullSrcRegisters[0], 0); + + emit_x87_ex2(cp); + + x87_fstp_dest4(cp, &op->FullDstRegisters[0]); + return TRUE; +} + +static boolean emit_EXP( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); + struct x86_reg st0 = x86_make_reg(file_x87, 0); + struct x86_reg st1 = x86_make_reg(file_x87, 1); + struct x86_reg st3 = x86_make_reg(file_x87, 3); + unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask; + + /* CAUTION: dst may alias arg0! + */ + x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* arg0.x */ + x87_fld(cp->func, st0); /* arg arg */ + + /* by default, fpu is setup to round-to-nearest. We want to + * change this now, and track the state through to the end of the + * generated function so that it isn't repeated unnecessarily. + * Alternately, could subtract .5 to get round to -inf behaviour. + */ + set_fpu_round_neg_inf( cp ); + x87_fprndint( cp->func ); /* flr(a) a */ + x87_fld(cp->func, st0); /* flr(a) flr(a) a */ + x87_fld1(cp->func); /* 1 floor(a) floor(a) a */ + x87_fst_or_nop(cp->func, writemask, 3, dst); /* stack unchanged */ + + x87_fscale(cp->func); /* 2^floor(a) floor(a) a */ + x87_fst(cp->func, st3); /* 2^floor(a) floor(a) a 2^floor(a)*/ + + x87_fstp_or_pop(cp->func, writemask, 0, dst); /* flr(a) a 2^flr(a) */ + + x87_fsubrp(cp->func, st1); /* frac(a) 2^flr(a) */ + + x87_fst_or_nop(cp->func, writemask, 1, dst); /* frac(a) 2^flr(a) */ + + x87_f2xm1(cp->func); /* (2^frac(a))-1 2^flr(a)*/ + x87_fld1(cp->func); /* 1 (2^frac(a))-1 2^flr(a)*/ + x87_faddp(cp->func, st1); /* 2^frac(a) 2^flr(a) */ + x87_fmulp(cp->func, st1); /* 2^a */ + + x87_fstp_or_pop(cp->func, writemask, 2, dst); + +/* dst[0] = 2^floor(tmp); */ +/* dst[1] = frac(tmp); */ +/* dst[2] = 2^floor(tmp) * 2^frac(tmp); */ +/* dst[3] = 1.0F; */ + return TRUE; +} + +static boolean emit_LOG( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); + struct x86_reg st0 = x86_make_reg(file_x87, 0); + struct x86_reg st1 = x86_make_reg(file_x87, 1); + struct x86_reg st2 = x86_make_reg(file_x87, 2); + unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask; + + /* CAUTION: dst may alias arg0! + */ + x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* arg0.x */ + x87_fabs(cp->func); /* |arg0.x| */ + x87_fxtract(cp->func); /* mantissa(arg0.x), exponent(arg0.x) */ + x87_fst(cp->func, st2); /* mantissa, exponent, mantissa */ + x87_fld1(cp->func); /* 1, mantissa, exponent, mantissa */ + x87_fyl2x(cp->func); /* log2(mantissa), exponent, mantissa */ + x87_fadd(cp->func, st0, st1); /* e+l2(m), e, m */ + + x87_fstp_or_pop(cp->func, writemask, 2, dst); /* e, m */ + + x87_fld1(cp->func); /* 1, e, m */ + x87_fsub(cp->func, st1, st0); /* 1, e-1, m */ + + x87_fstp_or_pop(cp->func, writemask, 3, dst); /* e-1,m */ + x87_fstp_or_pop(cp->func, writemask, 0, dst); /* m */ + + x87_fadd(cp->func, st0, st0); /* 2m */ + + x87_fstp_or_pop( cp->func, writemask, 1, dst ); + + return TRUE; +} + +static boolean emit_FLR( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); + unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask; + int i; + + set_fpu_round_neg_inf( cp ); + + /* Load all sources first to avoid aliasing + */ + for (i = 0; i < 4; i++) { + if (writemask & (1<FullSrcRegisters[0], i); + } + } + + for (i = 0; i < 4; i++) { + if (writemask & (1<func ); + x87_fstp(cp->func, x86_make_disp(dst, i*4)); + } + } + + return TRUE; +} + + +static boolean emit_RND( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); + unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask; + int i; + + set_fpu_round_nearest( cp ); + + /* Load all sources first to avoid aliasing + */ + for (i = 0; i < 4; i++) { + if (writemask & (1<FullSrcRegisters[0], i); + } + } + + for (i = 0; i < 4; i++) { + if (writemask & (1<func ); + x87_fstp(cp->func, x86_make_disp(dst, i*4)); + } + } + + return TRUE; +} + + +static boolean emit_FRC( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); + struct x86_reg st0 = x86_make_reg(file_x87, 0); + struct x86_reg st1 = x86_make_reg(file_x87, 1); + unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask; + int i; + + set_fpu_round_neg_inf( cp ); + + /* suck all the source values onto the stack before writing out any + * dst, which may alias... + */ + for (i = 0; i < 4; i++) { + if (writemask & (1<FullSrcRegisters[0], i); + } + } + + for (i = 0; i < 4; i++) { + if (writemask & (1<func, st0); /* a a */ + x87_fprndint( cp->func ); /* flr(a) a */ + x87_fsubrp(cp->func, st1); /* frc(a) */ + x87_fstp(cp->func, x86_make_disp(dst, i*4)); + } + } + + return TRUE; +} + + + +static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); + struct x86_reg st1 = x86_make_reg(file_x87, 1); + unsigned fixup1, fixup2; + unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask; + + + /* Load the interesting parts of arg0: + */ + x87_fld_src(cp, &op->FullSrcRegisters[0], 3); + x87_fld_src(cp, &op->FullSrcRegisters[0], 1); + x87_fld_src(cp, &op->FullSrcRegisters[0], 0); + + + if (writemask & TGSI_WRITEMASK_XW) { + x87_fld1(cp->func); + x87_fst_or_nop(cp->func, writemask, 0, dst); + x87_fstp_or_pop(cp->func, writemask, 3, dst); + } + + if (writemask & TGSI_WRITEMASK_YZ) { + + /* Pre-zero destinations, may be overwritten later... fixme. + */ + x87_fldz(cp->func); + x87_fst_or_nop(cp->func, writemask, 1, dst); + x87_fstp_or_pop(cp->func, writemask, 2, dst); + + + /* Check arg0[0]: + */ + x87_fldz(cp->func); /* 0 a0 a1 a3 */ + x87_fucomp(cp->func, st1); /* a0 a1 a3 */ + x87_fnstsw(cp->func, cp->tmp_EAX); + x86_sahf(cp->func); + fixup1 = x86_jcc_forward(cp->func, cc_AE); + + x87_fstp_or_pop(cp->func, writemask, 1, dst); /* a1 a3 */ + + /* Check arg0[1]: + */ + x87_fldz(cp->func); /* 0 a1 a3 */ + x87_fucomp(cp->func, st1); /* a1 a3 */ + x87_fnstsw(cp->func, cp->tmp_EAX); + x86_sahf(cp->func); + fixup2 = x86_jcc_forward(cp->func, cc_AE); + + /* Compute pow(a1, a3) + */ + x87_fyl2x(cp->func); /* a3*log2(a1) */ + + emit_x87_ex2( cp ); /* 2^(a3*log2(a1)) */ + + x87_fstp_or_pop(cp->func, writemask, 2, dst); + + /* Land jumps: + */ + x86_fixup_fwd_jump(cp->func, fixup1); + x86_fixup_fwd_jump(cp->func, fixup2); + } + + return TRUE; +} + + + +static boolean emit_MAX( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + + sse_movups(cp->func, dst, arg0); + sse_maxps(cp->func, dst, arg1); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + + +static boolean emit_MIN( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + + sse_movups(cp->func, dst, arg0); + sse_minps(cp->func, dst, arg1); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + +static boolean emit_MOV( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg dst = aos_get_xmm_reg(cp); + + sse_movups(cp->func, dst, arg0); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + +static boolean emit_MUL( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + + sse_movups(cp->func, dst, arg0); + sse_mulps(cp->func, dst, arg1); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + + +static boolean emit_MAD( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg arg2 = fetch_src(cp, &op->FullSrcRegisters[2]); + struct x86_reg dst = aos_get_xmm_reg(cp); + + sse_movups(cp->func, dst, arg0); + sse_mulps(cp->func, dst, arg1); + sse_addps(cp->func, dst, arg2); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + + +static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + x87_fld_src(cp, &op->FullSrcRegisters[1], 0); /* a1.x */ + x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* a0.x a1.x */ + x87_fyl2x(cp->func); /* a1*log2(a0) */ + + emit_x87_ex2( cp ); /* 2^(a1*log2(a0)) */ + + x87_fstp_dest4(cp, &op->FullDstRegisters[0]); + return TRUE; +} + + +static boolean emit_RCP( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg dst = aos_get_xmm_reg(cp); + + if (cp->have_sse2) { + sse2_rcpss(cp->func, dst, arg0); + /* extend precision here... + */ + } + else { + struct x86_reg ones = aos_get_internal(cp, IMM_ONES); + sse_movss(cp->func, dst, ones); + sse_divss(cp->func, dst, arg0); + } + + sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + +static boolean emit_RSQ( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg dst = aos_get_xmm_reg(cp); + + sse_rsqrtss(cp->func, dst, arg0); + + /* Extend precision here... + */ + + sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + + +static boolean emit_SGE( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg ones = aos_get_internal(cp, IMM_ONES); + + sse_movups(cp->func, dst, arg0); + sse_cmpps(cp->func, dst, arg1, cc_NotLessThan); + sse_andps(cp->func, dst, ones); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + +static boolean emit_SIN( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + x87_fld_src(cp, &op->FullSrcRegisters[0], 0); + x87_fsin(cp->func); + x87_fstp_dest4(cp, &op->FullDstRegisters[0]); + return TRUE; +} + + + +static boolean emit_SLT( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg ones = aos_get_internal(cp, IMM_ONES); + + sse_movups(cp->func, dst, arg0); + sse_cmpps(cp->func, dst, arg1, cc_LessThan); + sse_andps(cp->func, dst, ones); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + +static boolean emit_SUB( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + + sse_movups(cp->func, dst, arg0); + sse_subps(cp->func, dst, arg1); + + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + + +static boolean emit_XPD( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); + struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg tmp0 = aos_get_xmm_reg(cp); + struct x86_reg tmp1 = aos_get_xmm_reg(cp); + + /* Could avoid tmp0, tmp1 if we overwrote arg0, arg1. Need a way + * to invalidate registers. This will come with better analysis + * (liveness analysis) of the incoming program. + */ + emit_pshufd(cp, dst, arg0, SHUF(Y, Z, X, W)); + emit_pshufd(cp, tmp1, arg1, SHUF(Z, X, Y, W)); + sse_mulps(cp->func, dst, tmp1); + emit_pshufd(cp, tmp0, arg0, SHUF(Z, X, Y, W)); + emit_pshufd(cp, tmp1, arg1, SHUF(Y, Z, X, W)); + sse_mulps(cp->func, tmp0, tmp1); + sse_subps(cp->func, dst, tmp0); + +/* dst[0] = arg0[1] * arg1[2] - arg0[2] * arg1[1]; */ +/* dst[1] = arg0[2] * arg1[0] - arg0[0] * arg1[2]; */ +/* dst[2] = arg0[0] * arg1[1] - arg0[1] * arg1[0]; */ +/* dst[3] is undef */ + + + aos_release_xmm_reg(cp, tmp0.idx); + aos_release_xmm_reg(cp, tmp1.idx); + store_dest(cp, &op->FullDstRegisters[0], dst); + return TRUE; +} + + + +static boolean +emit_instruction( struct aos_compilation *cp, + struct tgsi_full_instruction *inst ) +{ + switch( inst->Instruction.Opcode ) { + case TGSI_OPCODE_MOV: + return emit_MOV( cp, inst ); + + case TGSI_OPCODE_LIT: + return emit_LIT(cp, inst); + + case TGSI_OPCODE_RCP: + return emit_RCP(cp, inst); + + case TGSI_OPCODE_RSQ: + return emit_RSQ(cp, inst); + + case TGSI_OPCODE_EXP: + return emit_EXP(cp, inst); + + case TGSI_OPCODE_LOG: + return emit_LOG(cp, inst); + + case TGSI_OPCODE_MUL: + return emit_MUL(cp, inst); + + case TGSI_OPCODE_ADD: + return emit_ADD(cp, inst); + + case TGSI_OPCODE_DP3: + return emit_DP3(cp, inst); + + case TGSI_OPCODE_DP4: + return emit_DP4(cp, inst); + + case TGSI_OPCODE_DST: + return emit_DST(cp, inst); + + case TGSI_OPCODE_MIN: + return emit_MIN(cp, inst); + + case TGSI_OPCODE_MAX: + return emit_MAX(cp, inst); + + case TGSI_OPCODE_SLT: + return emit_SLT(cp, inst); + + case TGSI_OPCODE_SGE: + return emit_SGE(cp, inst); + + case TGSI_OPCODE_MAD: + return emit_MAD(cp, inst); + + case TGSI_OPCODE_SUB: + return emit_SUB(cp, inst); + + case TGSI_OPCODE_LERP: +// return emit_LERP(cp, inst); + return FALSE; + + case TGSI_OPCODE_FRAC: + return emit_FRC(cp, inst); + + case TGSI_OPCODE_CLAMP: +// return emit_CLAMP(cp, inst); + return FALSE; + + case TGSI_OPCODE_FLOOR: + return emit_FLR(cp, inst); + + case TGSI_OPCODE_ROUND: + return emit_RND(cp, inst); + + case TGSI_OPCODE_EXPBASE2: + return emit_EX2(cp, inst); + + case TGSI_OPCODE_LOGBASE2: + return emit_LG2(cp, inst); + + case TGSI_OPCODE_POWER: + return emit_POW(cp, inst); + + case TGSI_OPCODE_CROSSPRODUCT: + return emit_XPD(cp, inst); + + case TGSI_OPCODE_ABS: + return emit_ABS(cp, inst); + + case TGSI_OPCODE_DPH: + return emit_DPH(cp, inst); + + case TGSI_OPCODE_COS: + return emit_COS(cp, inst); + + case TGSI_OPCODE_SIN: + return emit_SIN(cp, inst); + + case TGSI_OPCODE_END: + return TRUE; + + default: + return FALSE; + } +} + +static boolean note_immediate( struct aos_compilation *cp, + struct tgsi_full_immediate *imm ) +{ + unsigned pos = cp->num_immediates++; + unsigned j; + + for (j = 0; j < imm->Immediate.Size; j++) { + cp->vaos->machine->immediate[pos][j] = imm->u.ImmediateFloat32[j].Float; + } + + return TRUE; +} + + + + +static void find_last_write_outputs( struct aos_compilation *cp ) +{ + struct tgsi_parse_context parse; + unsigned this_instruction = 0; + unsigned i; + + tgsi_parse_init( &parse, cp->vaos->base.vs->state.tokens ); + + while (!tgsi_parse_end_of_tokens( &parse )) { + + tgsi_parse_token( &parse ); + + if (parse.FullToken.Token.Type != TGSI_TOKEN_TYPE_INSTRUCTION) + continue; + + for (i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++) { + if (parse.FullToken.FullInstruction.FullDstRegisters[i].DstRegister.File == + TGSI_FILE_OUTPUT) + { + unsigned idx = parse.FullToken.FullInstruction.FullDstRegisters[i].DstRegister.Index; + cp->output_last_write[idx] = this_instruction; + } + } + + this_instruction++; + } + + tgsi_parse_free( &parse ); +} + + +#define ARG_VARIENT 1 +#define ARG_START_ELTS 2 +#define ARG_COUNT 3 +#define ARG_OUTBUF 4 + + +static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, + boolean linear ) +{ + struct tgsi_parse_context parse; + struct aos_compilation cp; + unsigned fixup, label; + + tgsi_parse_init( &parse, varient->base.vs->state.tokens ); + + memset(&cp, 0, sizeof(cp)); + + cp.insn_counter = 1; + cp.vaos = varient; + cp.have_sse2 = 1; + cp.func = &varient->func[ linear ? 0 : 1 ]; + + cp.tmp_EAX = x86_make_reg(file_REG32, reg_AX); + cp.idx_EBX = x86_make_reg(file_REG32, reg_BX); + cp.outbuf_ECX = x86_make_reg(file_REG32, reg_CX); + cp.machine_EDX = x86_make_reg(file_REG32, reg_DX); + cp.count_ESI = x86_make_reg(file_REG32, reg_SI); + + x86_init_func(cp.func); + + find_last_write_outputs(&cp); + + x86_push(cp.func, cp.idx_EBX); + x86_push(cp.func, cp.count_ESI); + + + /* Load arguments into regs: + */ + x86_mov(cp.func, cp.machine_EDX, x86_fn_arg(cp.func, ARG_VARIENT)); + x86_mov(cp.func, cp.idx_EBX, x86_fn_arg(cp.func, ARG_START_ELTS)); + x86_mov(cp.func, cp.count_ESI, x86_fn_arg(cp.func, ARG_COUNT)); + x86_mov(cp.func, cp.outbuf_ECX, x86_fn_arg(cp.func, ARG_OUTBUF)); + + + /* Compare count to zero and possibly bail. + */ + x86_xor(cp.func, cp.tmp_EAX, cp.tmp_EAX); + x86_cmp(cp.func, cp.count_ESI, cp.tmp_EAX); + fixup = x86_jcc_forward(cp.func, cc_E); + + /* Dig out the machine pointer from inside the varient arg + */ + x86_mov(cp.func, cp.machine_EDX, + x86_make_disp(cp.machine_EDX, + Offset( struct draw_vs_varient_aos_sse, machine ))); + + save_fpu_state( &cp ); + + /* Note address for loop jump + */ + label = x86_get_label(cp.func); + { + /* Fetch inputs... TODO: fetch lazily... + */ + if (!aos_fetch_inputs( &cp, linear )) + goto fail; + + /* Emit the shader: + */ + while( !tgsi_parse_end_of_tokens( &parse ) && !cp.error ) + { + tgsi_parse_token( &parse ); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_IMMEDIATE: + if (!note_immediate( &cp, &parse.FullToken.FullImmediate )) + goto fail; + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + if (!emit_instruction( &cp, &parse.FullToken.FullInstruction )) + goto fail; + break; + } + + cp.insn_counter++; + debug_printf("\n"); + } + + if (cp.error) + goto fail; + + /* Emit output... TODO: do this eagerly after the last write to a + * given output. + */ + if (!aos_emit_outputs( &cp )) + goto fail; + + + /* Next vertex: + */ + x86_lea(cp.func, + cp.outbuf_ECX, + x86_make_disp(cp.outbuf_ECX, + cp.vaos->base.key.output_stride)); + + /* Incr index + */ + if (linear) { + x86_inc(cp.func, cp.idx_EBX); + } + else { + x86_lea(cp.func, cp.idx_EBX, x86_make_disp(cp.idx_EBX, 4)); + } + + } + /* decr count, loop if not zero + */ + x86_dec(cp.func, cp.count_ESI); +/* x86_test(cp.func, cp.count_ESI, cp.count_ESI); */ + x86_jcc(cp.func, cc_NZ, label); + + restore_fpu_state(&cp); + + /* Land forward jump here: + */ + x86_fixup_fwd_jump(cp.func, fixup); + + /* Exit mmx state? + */ + if (cp.func->need_emms) + mmx_emms(cp.func); + + x86_pop(cp.func, cp.count_ESI); + x86_pop(cp.func, cp.idx_EBX); + + x86_ret(cp.func); + + tgsi_parse_free( &parse ); + return !cp.error; + + fail: + tgsi_parse_free( &parse ); + return FALSE; +} + + + +static void vaos_set_buffer( struct draw_vs_varient *varient, + unsigned buf, + const void *ptr, + unsigned stride ) +{ + struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + unsigned i; + + for (i = 0; i < vaos->base.vs->info.num_inputs; i++) { + if (vaos->base.key.element[i].in.buffer == buf) { + vaos->machine->attrib[i].input_ptr = ((char *)ptr + + vaos->base.key.element[i].in.offset); + vaos->machine->attrib[i].input_stride = stride; + } + } +} + + +static void vaos_destroy( struct draw_vs_varient *varient ) +{ + struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + + if (vaos->machine) + align_free( vaos->machine ); + + x86_release_func( &vaos->func[0] ); + x86_release_func( &vaos->func[1] ); + + FREE(vaos); +} + +static void vaos_run_elts( struct draw_vs_varient *varient, + const unsigned *elts, + unsigned count, + void *output_buffer ) +{ + struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + + vaos->gen_run_elts( varient, + elts, + count, + output_buffer ); +} + +static void vaos_run_linear( struct draw_vs_varient *varient, + unsigned start, + unsigned count, + void *output_buffer ) +{ + struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + + vaos->gen_run_linear( varient, + start, + count, + output_buffer ); +} + + +static void vaos_set_constants( struct draw_vs_varient *varient, + const float (*constants)[4] ) +{ + struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + + memcpy(vaos->machine->constant, + constants, + (vaos->base.vs->info.file_max[TGSI_FILE_CONSTANT] + 1) * 4 * sizeof(float)); +} + + +static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, + const struct draw_vs_varient_key *key ) +{ + struct draw_vs_varient_aos_sse *vaos = CALLOC_STRUCT(draw_vs_varient_aos_sse); + + if (!vaos) + goto fail; + + vaos->base.key = *key; + vaos->base.vs = vs; + vaos->base.set_input = vaos_set_buffer; + vaos->base.set_constants = vaos_set_constants; + vaos->base.destroy = vaos_destroy; + vaos->base.run_linear = vaos_run_linear; + vaos->base.run_elts = vaos_run_elts; + + vaos->machine = align_malloc( sizeof(struct aos_machine), 16 ); + if (!vaos->machine) + goto fail; + + memset(vaos->machine, 0, sizeof(struct aos_machine)); + + tgsi_dump(vs->state.tokens, 0); + + if (!build_vertex_program( vaos, TRUE )) + goto fail; + + if (!build_vertex_program( vaos, FALSE )) + goto fail; + + vaos->gen_run_linear = (vsv_run_linear_func)x86_get_func(&vaos->func[0]); + if (!vaos->gen_run_linear) + goto fail; + + vaos->gen_run_elts = (vsv_run_elts_func)x86_get_func(&vaos->func[1]); + if (!vaos->gen_run_elts) + goto fail; + + return &vaos->base; + + fail: + if (vaos->machine) + align_free( vaos->machine ); + + if (vaos) + x86_release_func( &vaos->func[0] ); + + if (vaos) + x86_release_func( &vaos->func[1] ); + + FREE(vaos); + + return NULL; +} + + +struct draw_vs_varient *draw_vs_varient_aos_sse( struct draw_vertex_shader *vs, + const struct draw_vs_varient_key *key ) +{ + struct draw_vs_varient *varient = varient_aos_sse( vs, key ); + + if (varient == NULL) { + assert(0); + varient = draw_vs_varient_generic( vs, key ); + } + + return varient; +} + + + +#endif diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h new file mode 100644 index 0000000000..1d8a055a90 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -0,0 +1,181 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef DRAW_VS_AOS_H +#define DRAW_VS_AOS_H + + +struct tgsi_token; +struct x86_function; + +#include "pipe/p_state.h" +#include "rtasm/rtasm_x86sse.h" + + + + + +#define X 0 +#define Y 1 +#define Z 2 +#define W 3 + +#define MAX_INPUTS PIPE_MAX_ATTRIBS +#define MAX_OUTPUTS PIPE_MAX_ATTRIBS +#define MAX_TEMPS PIPE_MAX_ATTRIBS /* say */ +#define MAX_CONSTANTS PIPE_MAX_ATTRIBS /* say */ +#define MAX_IMMEDIATES PIPE_MAX_ATTRIBS /* say */ +#define MAX_INTERNALS 4 + +#define AOS_FILE_INTERNAL TGSI_FILE_COUNT + +/* This is the temporary storage used by all the aos_sse vs varients. + * Create one per context and reuse by passing a pointer in at + * vs_varient creation?? + */ +struct aos_machine { + float input [MAX_INPUTS ][4]; + float output [MAX_OUTPUTS ][4]; + float temp [MAX_TEMPS ][4]; + float constant [MAX_CONSTANTS ][4]; /* fixme -- should just be a pointer */ + float immediate[MAX_IMMEDIATES][4]; /* fixme -- should just be a pointer */ + float internal [MAX_INTERNALS ][4]; + + unsigned fpu_round_nearest; + unsigned fpu_round_neg_inf; + + struct { + const void *input_ptr; + unsigned input_stride; + + unsigned output_offset; + } attrib[PIPE_MAX_ATTRIBS]; +}; + + + + +struct aos_compilation { + struct x86_function *func; + struct draw_vs_varient_aos_sse *vaos; + + unsigned insn_counter; + unsigned num_immediates; + + struct { + unsigned idx:16; + unsigned file:8; + unsigned dirty:8; + unsigned last_used; + } xmm[8]; + + + boolean input_fetched[PIPE_MAX_ATTRIBS]; + unsigned output_last_write[PIPE_MAX_ATTRIBS]; + + boolean have_sse2; + boolean error; + short fpucntl; + + /* these are actually known values, but putting them in a struct + * like this is helpful to keep them in sync across the file. + */ + struct x86_reg tmp_EAX; + struct x86_reg idx_EBX; /* either start+i or &elt[i] */ + struct x86_reg outbuf_ECX; + struct x86_reg machine_EDX; + struct x86_reg count_ESI; /* decrements to zero */ +}; + +struct x86_reg aos_get_xmm_reg( struct aos_compilation *cp ); +void aos_release_xmm_reg( struct aos_compilation *cp, unsigned idx ); + +void aos_adopt_xmm_reg( struct aos_compilation *cp, + struct x86_reg reg, + unsigned file, + unsigned idx, + unsigned dirty ); + +struct x86_reg aos_get_shader_reg( struct aos_compilation *cp, + unsigned file, + unsigned idx ); + +boolean aos_fetch_inputs( struct aos_compilation *cp, + boolean linear ); + +boolean aos_emit_outputs( struct aos_compilation *cp ); + + +#define IMM_ONES 0 /* 1, 1,1,1 */ +#define IMM_NEGS 1 /* 1,-1,0,0 */ +#define IMM_IDENTITY 2 /* 0, 0,0,1 */ +#define IMM_INV_255 3 /* 1/255, 1/255, 1/255, 1/255 */ +#define IMM_255 4 /* 255, 255, 255, 255 */ + +struct x86_reg aos_get_internal( struct aos_compilation *cp, + unsigned imm ); + + +#define ERROR(cp, msg) \ +do { \ + debug_printf("%s: x86 translation failed: %s\n", __FUNCTION__, msg); \ + cp->error = 1; \ + assert(0); \ +} while (0) + + + + + + +struct draw_vs_varient_aos_sse { + struct draw_vs_varient base; + struct draw_context *draw; + +#if 0 + struct { + const void *ptr; + unsigned stride; + } attrib[PIPE_MAX_ATTRIBS]; +#endif + + struct aos_machine *machine; /* XXX: temporarily unshared */ + + vsv_run_linear_func gen_run_linear; + vsv_run_elts_func gen_run_elts; + + + struct x86_function func[2]; +}; + + + +#endif + diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c new file mode 100644 index 0000000000..72b2b3d11d --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -0,0 +1,314 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" +#include "tgsi/exec/tgsi_exec.h" +#include "draw_vs.h" +#include "draw_vs_aos.h" + +#include "rtasm/rtasm_x86sse.h" + +#ifdef PIPE_ARCH_X86 + +/* Note - don't yet have to worry about interacting with the code in + * draw_vs_aos.c as there is no intermingling of generated code... + * That may have to change, we'll see. + */ +static void emit_load_R32G32B32A32( struct aos_compilation *cp, + struct x86_reg data, + struct x86_reg src_ptr ) +{ + sse_movups(cp->func, data, src_ptr); +} + +static void emit_load_R32G32B32( struct aos_compilation *cp, + struct x86_reg data, + struct x86_reg src_ptr ) +{ + sse_movss(cp->func, data, x86_make_disp(src_ptr, 8)); + sse_shufps(cp->func, data, aos_get_internal( cp, IMM_IDENTITY ), SHUF(X,Y,Z,W) ); + sse_shufps(cp->func, data, data, SHUF(Y,Z,X,W) ); + sse_movlps(cp->func, data, src_ptr); +} + +static void emit_load_R32G32( struct aos_compilation *cp, + struct x86_reg data, + struct x86_reg src_ptr ) +{ + sse_movups(cp->func, data, aos_get_internal( cp, IMM_IDENTITY ) ); + sse_movlps(cp->func, data, src_ptr); +} + + +static void emit_load_R32( struct aos_compilation *cp, + struct x86_reg data, + struct x86_reg src_ptr ) +{ + sse_movss(cp->func, data, src_ptr); + sse_orps(cp->func, data, aos_get_internal( cp, IMM_IDENTITY ) ); +} + + +static void emit_load_R8G8B8A8_UNORM( struct aos_compilation *cp, + struct x86_reg data, + struct x86_reg src_ptr ) +{ + sse_movss(cp->func, data, src_ptr); + sse2_punpcklbw(cp->func, data, aos_get_internal( cp, IMM_IDENTITY )); + sse2_punpcklbw(cp->func, data, aos_get_internal( cp, IMM_IDENTITY )); + sse2_cvtdq2ps(cp->func, data, data); + sse_mulps(cp->func, data, aos_get_internal(cp, IMM_INV_255)); +} + + + +static void get_src_ptr( struct x86_function *func, + struct x86_reg src, + struct x86_reg machine, + struct x86_reg elt, + unsigned a ) +{ + struct x86_reg input_ptr = + x86_make_disp(machine, + Offset(struct aos_machine, attrib[a].input_ptr)); + + struct x86_reg input_stride = + x86_make_disp(machine, + Offset(struct aos_machine, attrib[a].input_stride)); + + /* Calculate pointer to current attrib: + */ + x86_mov(func, src, input_stride); + x86_imul(func, src, elt); + x86_add(func, src, input_ptr); +} + + +/* Extended swizzles? Maybe later. + */ +static void emit_swizzle( struct aos_compilation *cp, + struct x86_reg dest, + struct x86_reg src, + unsigned shuffle ) +{ + sse_shufps(cp->func, dest, src, shuffle); +} + + +static boolean load_input( struct aos_compilation *cp, + unsigned idx, + boolean linear ) +{ + unsigned format = cp->vaos->base.key.element[idx].in.format; + struct x86_reg src = cp->tmp_EAX; + struct x86_reg dataXMM = aos_get_xmm_reg(cp); + + /* Figure out source pointer address: + */ + get_src_ptr(cp->func, + src, + cp->machine_EDX, + linear ? cp->idx_EBX : x86_deref(cp->idx_EBX), + idx); + + src = x86_deref(src); + + aos_adopt_xmm_reg( cp, + dataXMM, + TGSI_FILE_INPUT, + idx, + TRUE ); + + switch (format) { + case PIPE_FORMAT_R32_FLOAT: + emit_load_R32(cp, dataXMM, src); + break; + case PIPE_FORMAT_R32G32_FLOAT: + emit_load_R32G32(cp, dataXMM, src); + break; + case PIPE_FORMAT_R32G32B32_FLOAT: + emit_load_R32G32B32(cp, dataXMM, src); + break; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + emit_load_R32G32B32A32(cp, dataXMM, src); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + emit_load_R8G8B8A8_UNORM(cp, dataXMM, src); + emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W)); + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + emit_load_R8G8B8A8_UNORM(cp, dataXMM, src); + break; + default: + ERROR(cp, "unhandled input format"); + return FALSE; + } + + return TRUE; +} + + +boolean aos_fetch_inputs( struct aos_compilation *cp, boolean linear ) +{ + unsigned i; + + for (i = 0; i < cp->vaos->base.vs->info.num_inputs; i++) { + if (!load_input( cp, i, linear )) + return FALSE; + cp->insn_counter++; + debug_printf("\n"); + } + + return TRUE; +} + + + + + + + +static void emit_store_R32G32B32A32( struct aos_compilation *cp, + struct x86_reg dst_ptr, + struct x86_reg dataXMM ) +{ + sse_movups(cp->func, dst_ptr, dataXMM); +} + +static void emit_store_R32G32B32( struct aos_compilation *cp, + struct x86_reg dst_ptr, + struct x86_reg dataXMM ) +{ + sse_movlps(cp->func, dst_ptr, dataXMM); + sse_shufps(cp->func, dataXMM, dataXMM, SHUF(Z,Z,Z,Z) ); /* NOTE! destructive */ + sse_movss(cp->func, x86_make_disp(dst_ptr,8), dataXMM); +} + +static void emit_store_R32G32( struct aos_compilation *cp, + struct x86_reg dst_ptr, + struct x86_reg dataXMM ) +{ + sse_movlps(cp->func, dst_ptr, dataXMM); +} + +static void emit_store_R32( struct aos_compilation *cp, + struct x86_reg dst_ptr, + struct x86_reg dataXMM ) +{ + sse_movss(cp->func, dst_ptr, dataXMM); +} + + + +static void emit_store_R8G8B8A8_UNORM( struct aos_compilation *cp, + struct x86_reg dst_ptr, + struct x86_reg dataXMM ) +{ + sse_mulps(cp->func, dataXMM, aos_get_internal(cp, IMM_255)); + sse2_cvtps2dq(cp->func, dataXMM, dataXMM); + sse2_packssdw(cp->func, dataXMM, dataXMM); + sse2_packuswb(cp->func, dataXMM, dataXMM); + sse_movss(cp->func, dst_ptr, dataXMM); +} + + + + + +static boolean emit_output( struct aos_compilation *cp, + struct x86_reg ptr, + struct x86_reg dataXMM, + unsigned format ) +{ + switch (format) { + case PIPE_FORMAT_R32_FLOAT: + emit_store_R32(cp, ptr, dataXMM); + break; + case PIPE_FORMAT_R32G32_FLOAT: + emit_store_R32G32(cp, ptr, dataXMM); + break; + case PIPE_FORMAT_R32G32B32_FLOAT: + emit_store_R32G32B32(cp, ptr, dataXMM); + break; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + emit_store_R32G32B32A32(cp, ptr, dataXMM); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W)); + emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); + break; + default: + ERROR(cp, "unhandled output format"); + return FALSE; + } + + return TRUE; +} + + + +boolean aos_emit_outputs( struct aos_compilation *cp ) +{ + unsigned i; + + for (i = 0; i < cp->vaos->base.vs->info.num_inputs; i++) { + unsigned format = cp->vaos->base.key.element[i].out.format; + unsigned offset = cp->vaos->base.key.element[i].out.offset; + + struct x86_reg data = aos_get_shader_reg( cp, + TGSI_FILE_OUTPUT, + i ); + + if (data.file != file_XMM) { + struct x86_reg tmp = aos_get_xmm_reg( cp ); + sse_movups(cp->func, tmp, data); + data = tmp; + } + + if (!emit_output( cp, + x86_make_disp( cp->outbuf_ECX, offset ), + data, + format )) + return FALSE; + + aos_release_xmm_reg( cp, data.idx ); + + cp->insn_counter++; + debug_printf("\n"); + } + + return TRUE; +} + +#endif diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index df94a7e0c7..0581c3042f 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -157,6 +157,7 @@ draw_create_vs_sse(struct draw_context *draw, vs->base.draw = draw; vs->base.create_varient = draw_vs_varient_generic; +// vs->base.create_varient = draw_vs_varient_aos_sse; vs->base.prepare = vs_sse_prepare; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; -- cgit v1.2.3 From 030af06691bc5bc82ca141a576da7a2edffe9d1c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 20:14:55 +0100 Subject: rtasm: add x87 instructions and debug-check for x87 stack usage --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 120 +++++++++++++++++++++++++++++ src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 20 ++++- 2 files changed, 138 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 68ac91ed13..a2e8af343b 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -986,6 +986,26 @@ void sse2_movd( struct x86_function *p, /*********************************************************************** * x87 instructions */ +static void note_x87_pop( struct x86_function *p ) +{ + p->x87_stack--; + assert(p->x87_stack >= 0); + debug_printf("\nstack: %d\n", p->x87_stack); +} + +static void note_x87_push( struct x86_function *p ) +{ + p->x87_stack++; + assert(p->x87_stack <= 7); + debug_printf("\nstack: %d\n", p->x87_stack); +} + +void x87_assert_stack_empty( struct x86_function *p ) +{ + assert (p->x87_stack == 0); +} + + void x87_fist( struct x86_function *p, struct x86_reg dst ) { DUMP_R( dst ); @@ -998,6 +1018,7 @@ void x87_fistp( struct x86_function *p, struct x86_reg dst ) DUMP_R( dst ); emit_1ub(p, 0xdb); emit_modrm_noreg(p, 3, dst); + note_x87_pop(p); } void x87_fild( struct x86_function *p, struct x86_reg arg ) @@ -1005,12 +1026,14 @@ void x87_fild( struct x86_function *p, struct x86_reg arg ) DUMP_R( arg ); emit_1ub(p, 0xdf); emit_modrm_noreg(p, 0, arg); + note_x87_push(p); } void x87_fldz( struct x86_function *p ) { DUMP(); emit_2ub(p, 0xd9, 0xee); + note_x87_push(p); } @@ -1027,18 +1050,21 @@ void x87_fld1( struct x86_function *p ) { DUMP(); emit_2ub(p, 0xd9, 0xe8); + note_x87_push(p); } void x87_fldl2e( struct x86_function *p ) { DUMP(); emit_2ub(p, 0xd9, 0xea); + note_x87_push(p); } void x87_fldln2( struct x86_function *p ) { DUMP(); emit_2ub(p, 0xd9, 0xed); + note_x87_push(p); } void x87_fwait( struct x86_function *p ) @@ -1059,6 +1085,49 @@ void x87_fclex( struct x86_function *p ) x87_fnclex(p); } +void x87_fcmovb( struct x86_function *p, struct x86_reg arg ) +{ + DUMP_R( arg ); + assert(arg.file == file_x87); + emit_2ub(p, 0xda, 0xc0+arg.idx); +} + +void x87_fcmove( struct x86_function *p, struct x86_reg arg ) +{ + DUMP_R( arg ); + assert(arg.file == file_x87); + emit_2ub(p, 0xda, 0xc8+arg.idx); +} + +void x87_fcmovbe( struct x86_function *p, struct x86_reg arg ) +{ + DUMP_R( arg ); + assert(arg.file == file_x87); + emit_2ub(p, 0xda, 0xd0+arg.idx); +} + +void x87_fcmovnb( struct x86_function *p, struct x86_reg arg ) +{ + DUMP_R( arg ); + assert(arg.file == file_x87); + emit_2ub(p, 0xdb, 0xc0+arg.idx); +} + +void x87_fcmovne( struct x86_function *p, struct x86_reg arg ) +{ + DUMP_R( arg ); + assert(arg.file == file_x87); + emit_2ub(p, 0xdb, 0xc8+arg.idx); +} + +void x87_fcmovnbe( struct x86_function *p, struct x86_reg arg ) +{ + DUMP_R( arg ); + assert(arg.file == file_x87); + emit_2ub(p, 0xdb, 0xd0+arg.idx); +} + + static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg, unsigned char dst0ub0, @@ -1146,6 +1215,7 @@ void x87_fmulp( struct x86_function *p, struct x86_reg dst ) assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xc8+dst.idx); + note_x87_pop(p); } void x87_fsubp( struct x86_function *p, struct x86_reg dst ) @@ -1154,6 +1224,7 @@ void x87_fsubp( struct x86_function *p, struct x86_reg dst ) assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xe8+dst.idx); + note_x87_pop(p); } void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) @@ -1162,6 +1233,7 @@ void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xe0+dst.idx); + note_x87_pop(p); } void x87_faddp( struct x86_function *p, struct x86_reg dst ) @@ -1170,6 +1242,7 @@ void x87_faddp( struct x86_function *p, struct x86_reg dst ) assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xc0+dst.idx); + note_x87_pop(p); } void x87_fdivp( struct x86_function *p, struct x86_reg dst ) @@ -1178,6 +1251,7 @@ void x87_fdivp( struct x86_function *p, struct x86_reg dst ) assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xf8+dst.idx); + note_x87_pop(p); } void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) @@ -1186,6 +1260,13 @@ void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xf0+dst.idx); + note_x87_pop(p); +} + +void x87_ftst( struct x86_function *p ) +{ + DUMP(); + emit_2ub(p, 0xd9, 0xe4); } void x87_fucom( struct x86_function *p, struct x86_reg arg ) @@ -1200,12 +1281,15 @@ void x87_fucomp( struct x86_function *p, struct x86_reg arg ) DUMP_R( arg ); assert(arg.file == file_x87); emit_2ub(p, 0xdd, 0xe8+arg.idx); + note_x87_pop(p); } void x87_fucompp( struct x86_function *p ) { DUMP(); emit_2ub(p, 0xda, 0xe9); + note_x87_pop(p); /* pop twice */ + note_x87_pop(p); /* pop twice */ } void x87_fxch( struct x86_function *p, struct x86_reg arg ) @@ -1287,6 +1371,7 @@ void x87_fyl2x( struct x86_function *p ) { DUMP(); emit_2ub(p, 0xd9, 0xf1); + note_x87_pop(p); } /* st1 = st1 * log2(st0 + 1.0); @@ -1298,6 +1383,7 @@ void x87_fyl2xp1( struct x86_function *p ) { DUMP(); emit_2ub(p, 0xd9, 0xf9); + note_x87_pop(p); } @@ -1310,6 +1396,7 @@ void x87_fld( struct x86_function *p, struct x86_reg arg ) emit_1ub(p, 0xd9); emit_modrm_noreg(p, 0, arg); } + note_x87_push(p); } void x87_fst( struct x86_function *p, struct x86_reg dst ) @@ -1332,8 +1419,15 @@ void x87_fstp( struct x86_function *p, struct x86_reg dst ) emit_1ub(p, 0xd9); emit_modrm_noreg(p, 3, dst); } + note_x87_pop(p); +} + +void x87_fpop( struct x86_function *p ) +{ + x87_fstp( p, x86_make_reg( file_x87, 0 )); } + void x87_fcom( struct x86_function *p, struct x86_reg dst ) { DUMP_R( dst ); @@ -1345,6 +1439,7 @@ void x87_fcom( struct x86_function *p, struct x86_reg dst ) } } + void x87_fcomp( struct x86_function *p, struct x86_reg dst ) { DUMP_R( dst ); @@ -1354,6 +1449,20 @@ void x87_fcomp( struct x86_function *p, struct x86_reg dst ) emit_1ub(p, 0xd8); emit_modrm_noreg(p, 3, dst); } + note_x87_pop(p); +} + +void x87_fcomi( struct x86_function *p, struct x86_reg arg ) +{ + DUMP_R( arg ); + emit_2ub(p, 0xdb, 0xf0+arg.idx); +} + +void x87_fcomip( struct x86_function *p, struct x86_reg arg ) +{ + DUMP_R( arg ); + emit_2ub(p, 0xdb, 0xf0+arg.idx); + note_x87_pop(p); } @@ -1372,6 +1481,17 @@ void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) } +void x87_fnstcw( struct x86_function *p, struct x86_reg dst ) +{ + DUMP_R( dst ); + assert(dst.file == file_REG32); + + emit_1ub(p, 0x9b); /* WAIT -- needed? */ + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 7, dst); +} + + /*********************************************************************** diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index 1e02c6e73b..9f7e31e055 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -41,8 +41,11 @@ struct x86_function { unsigned size; unsigned char *store; unsigned char *csr; - unsigned stack_offset; - int need_emms; + + unsigned stack_offset:16; + unsigned need_emms:8; + int x87_stack:8; + unsigned char error_overflow[4]; }; @@ -229,13 +232,23 @@ void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_sahf( struct x86_function *p ); +void x87_assert_stack_empty( struct x86_function *p ); + void x87_f2xm1( struct x86_function *p ); void x87_fabs( struct x86_function *p ); void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); void x87_faddp( struct x86_function *p, struct x86_reg dst ); void x87_fchs( struct x86_function *p ); void x87_fclex( struct x86_function *p ); +void x87_fcmovb( struct x86_function *p, struct x86_reg src ); +void x87_fcmovbe( struct x86_function *p, struct x86_reg src ); +void x87_fcmove( struct x86_function *p, struct x86_reg src ); +void x87_fcmovnb( struct x86_function *p, struct x86_reg src ); +void x87_fcmovnbe( struct x86_function *p, struct x86_reg src ); +void x87_fcmovne( struct x86_function *p, struct x86_reg src ); void x87_fcom( struct x86_function *p, struct x86_reg dst ); +void x87_fcomi( struct x86_function *p, struct x86_reg dst ); +void x87_fcomip( struct x86_function *p, struct x86_reg dst ); void x87_fcomp( struct x86_function *p, struct x86_reg dst ); void x87_fcos( struct x86_function *p ); void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); @@ -255,6 +268,7 @@ void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); void x87_fmulp( struct x86_function *p, struct x86_reg dst ); void x87_fnclex( struct x86_function *p ); void x87_fprndint( struct x86_function *p ); +void x87_fpop( struct x86_function *p ); void x87_fscale( struct x86_function *p ); void x87_fsin( struct x86_function *p ); void x87_fsincos( struct x86_function *p ); @@ -265,11 +279,13 @@ void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); void x87_fsubp( struct x86_function *p, struct x86_reg dst ); void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); void x87_fsubrp( struct x86_function *p, struct x86_reg dst ); +void x87_ftst( struct x86_function *p ); void x87_fxch( struct x86_function *p, struct x86_reg dst ); void x87_fxtract( struct x86_function *p ); void x87_fyl2x( struct x86_function *p ); void x87_fyl2xp1( struct x86_function *p ); void x87_fwait( struct x86_function *p ); +void x87_fnstcw( struct x86_function *p, struct x86_reg dst ); void x87_fnstsw( struct x86_function *p, struct x86_reg dst ); void x87_fucompp( struct x86_function *p ); void x87_fucomp( struct x86_function *p, struct x86_reg arg ); -- cgit v1.2.3 From 889473b3f5a216bd753c357974d6bae29fe3c41d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 20:28:56 +0100 Subject: draw: add viewport to varient state --- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 9 +++- src/gallium/auxiliary/draw/draw_vs.h | 8 +++- src/gallium/auxiliary/draw/draw_vs_aos.c | 50 ++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_aos.h | 9 +++- src/gallium/auxiliary/draw/draw_vs_sse.c | 4 +- src/gallium/auxiliary/draw/draw_vs_varient.c | 10 +++++ 6 files changed, 84 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 74945dcfe9..984fbb6767 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -95,10 +95,14 @@ static void fse_prepare( struct draw_pt_middle_end *middle, + fse->key.output_stride = vinfo->size * 4; fse->key.nr_elements = MAX2(num_vs_outputs, /* outputs - translate to hw format */ num_vs_inputs); /* inputs - fetch from api format */ - fse->key.output_stride = vinfo->size * 4; + fse->key.viewport = 1; + fse->key.clip = 0; + fse->key.pad = 0; + memset(fse->key.element, 0, fse->key.nr_elements * sizeof(fse->key.element[0])); @@ -211,6 +215,9 @@ static void fse_prepare( struct draw_pt_middle_end *middle, fse->active->set_constants( fse->active, (const float (*)[4])draw->pt.user.constants ); + fse->active->set_viewport( fse->active, + &draw->viewport ); + //return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 5a8d0da06d..ff3e19b2a8 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -58,7 +58,10 @@ struct draw_vs_element { struct draw_vs_varient_key { unsigned output_stride; - unsigned nr_elements; + unsigned nr_elements:16; + unsigned viewport:1; + unsigned clip:1; + unsigned pad:14; struct draw_vs_element element[PIPE_MAX_ATTRIBS]; }; @@ -88,6 +91,9 @@ struct draw_vs_varient { void (*set_constants)( struct draw_vs_varient *, const float (*constants)[4] ); + void (*set_viewport)( struct draw_vs_varient *, + const struct pipe_viewport_state * ); + void (PIPE_CDECL *run_linear)( struct draw_vs_varient *shader, unsigned start, unsigned count, diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 620f5e3592..b8e66e8b78 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1401,6 +1401,37 @@ emit_instruction( struct aos_compilation *cp, } } + +static boolean emit_viewport( struct aos_compilation *cp ) +{ + struct x86_reg pos = aos_get_shader_reg(cp, + TGSI_FILE_OUTPUT, + 0); + + struct x86_reg scale = x86_make_disp(cp->machine_EDX, + Offset(struct aos_machine, scale)); + + struct x86_reg translate = x86_make_disp(cp->machine_EDX, + Offset(struct aos_machine, translate)); + + if (pos.file != file_XMM) { + struct x86_reg dst = aos_get_xmm_reg(cp); + sse_movups(cp->func, dst, pos); + pos = dst; + } + + sse_mulps(cp->func, pos, scale); + sse_addps(cp->func, pos, translate); + + aos_adopt_xmm_reg( cp, + pos, + TGSI_FILE_OUTPUT, + 0, + TRUE ); + return TRUE; +} + + static boolean note_immediate( struct aos_compilation *cp, struct tgsi_full_immediate *imm ) { @@ -1540,6 +1571,10 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, if (cp.error) goto fail; + if (cp.vaos->base.key.viewport) { + emit_viewport(&cp); + } + /* Emit output... TODO: do this eagerly after the last write to a * given output. */ @@ -1665,11 +1700,25 @@ static void vaos_set_constants( struct draw_vs_varient *varient, } +static void vaos_set_viewport( struct draw_vs_varient *varient, + const struct pipe_viewport_state *viewport ) +{ + struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + + memcpy(vaos->machine->scale, viewport->scale, 4 * sizeof(float)); + memcpy(vaos->machine->translate, viewport->translate, 4 * sizeof(float)); +} + + + static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, const struct draw_vs_varient_key *key ) { struct draw_vs_varient_aos_sse *vaos = CALLOC_STRUCT(draw_vs_varient_aos_sse); + if (key->clip) + return NULL; + if (!vaos) goto fail; @@ -1677,6 +1726,7 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, vaos->base.vs = vs; vaos->base.set_input = vaos_set_buffer; vaos->base.set_constants = vaos_set_constants; + vaos->base.set_viewport = vaos_set_viewport; vaos->base.destroy = vaos_destroy; vaos->base.run_linear = vaos_run_linear; vaos->base.run_elts = vaos_run_elts; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 1d8a055a90..16fef6451c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -68,8 +68,13 @@ struct aos_machine { float immediate[MAX_IMMEDIATES][4]; /* fixme -- should just be a pointer */ float internal [MAX_INTERNALS ][4]; - unsigned fpu_round_nearest; - unsigned fpu_round_neg_inf; + float scale[4]; /* viewport */ + float translate[4]; /* viewport */ + + ushort fpu_round_nearest; + ushort fpu_round_neg_inf; + ushort fpu_restore; + ushort fpucntl; /* one of FPU_* above */ struct { const void *input_ptr; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 0581c3042f..7781782ae8 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -156,8 +156,8 @@ draw_create_vs_sse(struct draw_context *draw, tgsi_scan_shader(templ->tokens, &vs->base.info); vs->base.draw = draw; - vs->base.create_varient = draw_vs_varient_generic; -// vs->base.create_varient = draw_vs_varient_aos_sse; + vs->base.create_varient = draw_vs_varient_aos_sse; +// vs->base.create_varient = draw_vs_varient_generic; vs->base.prepare = vs_sse_prepare; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index d27b0f6187..f6f621a748 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -167,6 +167,12 @@ static void vsvg_run_linear( struct draw_vs_varient *varient, + +static void vsvg_set_viewport( struct draw_vs_varient *varient, + const struct pipe_viewport_state *viewport ) +{ +} + static void vsvg_destroy( struct draw_vs_varient *varient ) { FREE(varient); @@ -179,6 +185,9 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, unsigned i; struct translate_key fetch, emit; + if (key->viewport || key->clip) + return NULL; + struct draw_vs_varient_generic *vsvg = CALLOC_STRUCT( draw_vs_varient_generic ); if (vsvg == NULL) return NULL; @@ -187,6 +196,7 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, vsvg->base.vs = vs; vsvg->base.set_input = vsvg_set_input; vsvg->base.set_constants = vsvg_set_constants; + vsvg->base.set_viewport = vsvg_set_viewport; vsvg->base.run_elts = vsvg_run_elts; vsvg->base.run_linear = vsvg_run_linear; vsvg->base.destroy = vsvg_destroy; -- cgit v1.2.3 From 194a7be28f6eed502f2475d9a637cb3610ca75f6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 20:31:08 +0100 Subject: draw: fix vs aos internal/machine state --- src/gallium/auxiliary/draw/draw_vs_aos.c | 59 ++++++++++++++++++++++++++++++-- src/gallium/auxiliary/draw/draw_vs_aos.h | 9 +++-- 2 files changed, 63 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index b8e66e8b78..67761f881d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -83,7 +83,7 @@ static struct x86_reg get_reg_ptr(struct aos_compilation *cp, return x86_make_disp(ptr, Offset(struct aos_machine, constant[idx])); case AOS_FILE_INTERNAL: - return x86_make_disp(ptr, Offset(struct aos_machine, immediate[idx])); + return x86_make_disp(ptr, Offset(struct aos_machine, internal[idx])); default: ERROR(cp, "unknown reg file"); @@ -97,9 +97,63 @@ struct x86_reg aos_get_internal( struct aos_compilation *cp, { return get_reg_ptr( cp, AOS_FILE_INTERNAL, - imm + 1 ); + imm ); +} + +#define X87_CW_EXCEPTION_INV_OP (1<<0) +#define X87_CW_EXCEPTION_DENORM_OP (1<<1) +#define X87_CW_EXCEPTION_ZERO_DIVIDE (1<<2) +#define X87_CW_EXCEPTION_OVERFLOW (1<<3) +#define X87_CW_EXCEPTION_UNDERFLOW (1<<4) +#define X87_CW_EXCEPTION_PRECISION (1<<5) +#define X87_CW_PRECISION_SINGLE (0<<8) +#define X87_CW_PRECISION_RESERVED (1<<8) +#define X87_CW_PRECISION_DOUBLE (2<<8) +#define X87_CW_PRECISION_DOUBLE_EXT (3<<8) +#define X87_CW_PRECISION_MASK (3<<8) +#define X87_CW_ROUND_NEAREST (0<<10) +#define X87_CW_ROUND_DOWN (1<<10) +#define X87_CW_ROUND_UP (2<<10) +#define X87_CW_ROUND_ZERO (3<<10) +#define X87_CW_ROUND_MASK (3<<10) +#define X87_CW_INFINITY (1<<12) + +static void init_internals( struct aos_machine *machine ) +{ + float inv = 1.0f/255.0f; + float f255 = 255.0f; + + ASSIGN_4V(machine->internal[IMM_ONES], 1.0f, 1.0f, 1.0f, 1.0f); + ASSIGN_4V(machine->internal[IMM_NEGS], -1.0f, -1.0f, -1.0f, -1.0f); + ASSIGN_4V(machine->internal[IMM_IDENTITY], 0.0f, 0.0f, 0.0f, 1.0f); + ASSIGN_4V(machine->internal[IMM_INV_255], inv, inv, inv, inv); + ASSIGN_4V(machine->internal[IMM_255], f255, f255, f255, f255); + + + machine->fpu_rnd_nearest = (X87_CW_EXCEPTION_INV_OP | + X87_CW_EXCEPTION_DENORM_OP | + X87_CW_EXCEPTION_ZERO_DIVIDE | + X87_CW_EXCEPTION_OVERFLOW | + X87_CW_EXCEPTION_UNDERFLOW | + X87_CW_EXCEPTION_PRECISION | + (1<<6) | + X87_CW_ROUND_NEAREST | + X87_CW_PRECISION_DOUBLE_EXT); + + assert(machine->fpu_rnd_nearest == 0x37f); + + machine->fpu_rnd_neg_inf = (X87_CW_EXCEPTION_INV_OP | + X87_CW_EXCEPTION_DENORM_OP | + X87_CW_EXCEPTION_ZERO_DIVIDE | + X87_CW_EXCEPTION_OVERFLOW | + X87_CW_EXCEPTION_UNDERFLOW | + X87_CW_EXCEPTION_PRECISION | + (1<<6) | + X87_CW_ROUND_DOWN | + X87_CW_PRECISION_DOUBLE_EXT); } + static void spill( struct aos_compilation *cp, unsigned idx ) { if (!cp->xmm[idx].dirty || @@ -1736,6 +1790,7 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, goto fail; memset(vaos->machine, 0, sizeof(struct aos_machine)); + init_internals(vaos->machine); tgsi_dump(vs->state.tokens, 0); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 16fef6451c..c2afd4e9a0 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -52,10 +52,13 @@ struct x86_function; #define MAX_TEMPS PIPE_MAX_ATTRIBS /* say */ #define MAX_CONSTANTS PIPE_MAX_ATTRIBS /* say */ #define MAX_IMMEDIATES PIPE_MAX_ATTRIBS /* say */ -#define MAX_INTERNALS 4 +#define MAX_INTERNALS 8 #define AOS_FILE_INTERNAL TGSI_FILE_COUNT +#define FPU_RND_NEG 1 +#define FPU_RND_NEAREST 2 + /* This is the temporary storage used by all the aos_sse vs varients. * Create one per context and reuse by passing a pointer in at * vs_varient creation?? @@ -71,8 +74,8 @@ struct aos_machine { float scale[4]; /* viewport */ float translate[4]; /* viewport */ - ushort fpu_round_nearest; - ushort fpu_round_neg_inf; + ushort fpu_rnd_nearest; + ushort fpu_rnd_neg_inf; ushort fpu_restore; ushort fpucntl; /* one of FPU_* above */ -- cgit v1.2.3 From 2302a5d3c1ea2c682dfc034012a054b8327a81de Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 20:32:43 +0100 Subject: draw: fix fpu control word manipulations --- src/gallium/auxiliary/draw/draw_vs_aos.c | 33 +++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 67761f881d..e736990acc 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -690,41 +690,47 @@ static void x87_fstp_dest4( struct aos_compilation *cp, x87_fstp_or_pop(cp->func, writemask, 3, ptr); } +#define FPU_MANIP 1 /* Save current x87 state and put it into single precision mode. */ static void save_fpu_state( struct aos_compilation *cp ) { -#if 0 - x87_fnstcw( cp->func, x86_make_disp(regEDX, get_offset(m, &m->fpucntl_restore))); - x87_fldcw( cp->func, ); +#if FPU_MANIP + x87_fnstcw( cp->func, x86_make_disp(cp->machine_EDX, + Offset(struct aos_machine, fpu_restore))); #endif } static void restore_fpu_state( struct aos_compilation *cp ) { -#if 0 +#if FPU_MANIP x87_fnclex(cp->func); - x87_fldcw(cp->func, x86_make_disp(regEDX, get_offset(m, &m->fpucntl_restore))); + x87_fldcw( cp->func, x86_make_disp(cp->machine_EDX, + Offset(struct aos_machine, fpu_restore))); #endif } static void set_fpu_round_neg_inf( struct aos_compilation *cp ) { -#if 0 - if (cp->fpucntl != RND_NEG_FPU) { - struct x86_reg regEDX = x86_make_reg(file_REG32, reg_DX); - struct arb_vp_machine *m = NULL; - - cp->fpucntl = RND_NEG_FPU; +#if FPU_MANIP + if (cp->fpucntl != FPU_RND_NEG) { + cp->fpucntl = FPU_RND_NEG; x87_fnclex(cp->func); - x87_fldcw(cp->func, x86_make_disp(regEDX, get_offset(m, &m->fpucntl_rnd_neg))); + x87_fldcw( cp->func, x86_make_disp(cp->machine_EDX, + Offset(struct aos_machine, fpu_rnd_neg_inf))); } #endif } static void set_fpu_round_nearest( struct aos_compilation *cp ) { -#if 0 +#if FPU_MANIP + if (cp->fpucntl != FPU_RND_NEAREST) { + cp->fpucntl = FPU_RND_NEAREST; + x87_fnclex(cp->func); + x87_fldcw( cp->func, x86_make_disp(cp->machine_EDX, + Offset(struct aos_machine, fpu_rnd_nearest))); + } #endif } @@ -1590,6 +1596,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, Offset( struct draw_vs_varient_aos_sse, machine ))); save_fpu_state( &cp ); + set_fpu_round_nearest( &cp ); /* Note address for loop jump */ -- cgit v1.2.3 From 0a7a0d79f64de9794878c42bc5b79a04772d7ed8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 20:34:52 +0100 Subject: draw: fix x87_ex2 and partially fix lit insn --- src/gallium/auxiliary/draw/draw_vs_aos.c | 112 +++++++++++++++---------------- 1 file changed, 56 insertions(+), 56 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index e736990acc..a365d456d1 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -735,23 +735,26 @@ static void set_fpu_round_nearest( struct aos_compilation *cp ) } -static void emit_x87_ex2( struct aos_compilation *cp ) +static void x87_emit_ex2( struct aos_compilation *cp ) { struct x86_reg st0 = x86_make_reg(file_x87, 0); struct x86_reg st1 = x86_make_reg(file_x87, 1); - struct x86_reg st3 = x86_make_reg(file_x87, 3); + int stack = cp->func->x87_stack; set_fpu_round_neg_inf( cp ); - x87_fld(cp->func, st0); /* a a */ - x87_fprndint( cp->func ); /* int(a) a */ - x87_fld(cp->func, st0); /* int(a) int(a) a */ - x87_fstp(cp->func, st3); /* int(a) a int(a)*/ - x87_fsubp(cp->func, st1); /* frac(a) int(a) */ - x87_f2xm1(cp->func); /* (2^frac(a))-1 int(a)*/ - x87_fld1(cp->func); /* 1 (2^frac(a))-1 int(a)*/ - x87_faddp(cp->func, st1); /* 2^frac(a) int(a) */ - x87_fscale(cp->func); /* 2^a */ + x87_fld(cp->func, st0); /* a a */ + x87_fld(cp->func, st0); /* a a a */ + x87_fprndint( cp->func ); /* flr(a) a a*/ + x87_fsubp(cp->func, st1); /* frac(a) a */ + x87_f2xm1(cp->func); /* (2^frac(a))-1 a */ + x87_fld1(cp->func); /* 1 (2^frac(a))-1 a */ + x87_faddp(cp->func, st1); /* 2^frac(a) a */ + x87_fscale(cp->func); /* 2^a a */ + x87_fstp(cp->func, st1); + + assert( stack == cp->func->x87_stack); + } @@ -907,9 +910,7 @@ static boolean emit_LG2( struct aos_compilation *cp, const struct tgsi_full_inst static boolean emit_EX2( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { x87_fld_src(cp, &op->FullSrcRegisters[0], 0); - - emit_x87_ex2(cp); - + x87_emit_ex2(cp); x87_fstp_dest4(cp, &op->FullDstRegisters[0]); return TRUE; } @@ -1084,63 +1085,62 @@ static boolean emit_FRC( struct aos_compilation *cp, const struct tgsi_full_inst static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); - struct x86_reg st1 = x86_make_reg(file_x87, 1); - unsigned fixup1, fixup2; unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask; - /* Load the interesting parts of arg0: - */ - x87_fld_src(cp, &op->FullSrcRegisters[0], 3); - x87_fld_src(cp, &op->FullSrcRegisters[0], 1); - x87_fld_src(cp, &op->FullSrcRegisters[0], 0); - - if (writemask & TGSI_WRITEMASK_XW) { - x87_fld1(cp->func); - x87_fst_or_nop(cp->func, writemask, 0, dst); - x87_fstp_or_pop(cp->func, writemask, 3, dst); - } if (writemask & TGSI_WRITEMASK_YZ) { + struct x86_reg st1 = x86_make_reg(file_x87, 1); + struct x86_reg st2 = x86_make_reg(file_x87, 2); + + - /* Pre-zero destinations, may be overwritten later... fixme. - */ - x87_fldz(cp->func); - x87_fst_or_nop(cp->func, writemask, 1, dst); - x87_fstp_or_pop(cp->func, writemask, 2, dst); + /* a1' = a1 <= 0 ? 1 : a1; + */ + x87_fldz(cp->func); /* 0 */ + x87_fld1(cp->func); /* 1 0 */ + x87_fld_src(cp, &op->FullSrcRegisters[0], 1); /* a1 1 0 */ + x87_fcomi(cp->func, st2); /* a1 1 0 */ + x87_fcmovb(cp->func, st1); /* a1' 1 0 */ + x87_fstp(cp->func, st1); /* a1' 0 */ + x87_fstp(cp->func, st1); /* a1' */ + + x87_fld_src(cp, &op->FullSrcRegisters[0], 3); /* a3 a1' */ + x87_fxch(cp->func, st1); /* a1' a3 */ + - /* Check arg0[0]: + /* Compute pow(a1, a3) */ - x87_fldz(cp->func); /* 0 a0 a1 a3 */ - x87_fucomp(cp->func, st1); /* a0 a1 a3 */ - x87_fnstsw(cp->func, cp->tmp_EAX); - x86_sahf(cp->func); - fixup1 = x86_jcc_forward(cp->func, cc_AE); - - x87_fstp_or_pop(cp->func, writemask, 1, dst); /* a1 a3 */ + x87_fyl2x(cp->func); /* a3*log2(a1) */ + x87_emit_ex2( cp ); /* 2^(a3*log2(a1)) */ - /* Check arg0[1]: - */ - x87_fldz(cp->func); /* 0 a1 a3 */ - x87_fucomp(cp->func, st1); /* a1 a3 */ - x87_fnstsw(cp->func, cp->tmp_EAX); - x86_sahf(cp->func); - fixup2 = x86_jcc_forward(cp->func, cc_AE); - /* Compute pow(a1, a3) + /* a0' = max2(a0, 0): */ - x87_fyl2x(cp->func); /* a3*log2(a1) */ + x87_fldz(cp->func); /* 0 r2 */ + x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* a0 0 r2 */ + x87_fcomi(cp->func, st1); + x87_fcmovb(cp->func, st1); /* a0' 0 r2 */ + x87_fstp(cp->func, st1); /* a0' r2 */ - emit_x87_ex2( cp ); /* 2^(a3*log2(a1)) */ + x87_fxch(cp->func, st1); /* a0' r2 */ + x87_fst_or_nop(cp->func, writemask, 1, dst); /* result[1] = a0' */ + + x87_fldz(cp->func); /* 0 a0' r2 */ + x87_fcomi(cp->func, st1); /* 0 a0' r2 */ + x87_fcmovnbe(cp->func, st2); /* r2' a0' r2 */ x87_fstp_or_pop(cp->func, writemask, 2, dst); - - /* Land jumps: - */ - x86_fixup_fwd_jump(cp->func, fixup1); - x86_fixup_fwd_jump(cp->func, fixup2); + x87_fpop(cp->func); + x87_fpop(cp->func); + } + + if (writemask & TGSI_WRITEMASK_XW) { + x87_fld1(cp->func); + x87_fst_or_nop(cp->func, writemask, 0, dst); + x87_fstp_or_pop(cp->func, writemask, 3, dst); } return TRUE; @@ -1222,7 +1222,7 @@ static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_inst x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* a0.x a1.x */ x87_fyl2x(cp->func); /* a1*log2(a0) */ - emit_x87_ex2( cp ); /* 2^(a1*log2(a0)) */ + x87_emit_ex2( cp ); /* 2^(a1*log2(a0)) */ x87_fstp_dest4(cp, &op->FullDstRegisters[0]); return TRUE; -- cgit v1.2.3 From 083f3f5c32a28d2993a8a5a8b4f5ef81224a5ec3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 20:38:23 +0100 Subject: draw: avoid a pointless mov in many sse opcodes --- src/gallium/auxiliary/draw/draw_vs_aos.c | 94 +++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 31 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index a365d456d1..97de43c232 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -174,14 +174,44 @@ static void spill( struct aos_compilation *cp, unsigned idx ) } } +static boolean is_xmm_tmp( struct aos_compilation *cp, + struct x86_reg reg ) +{ + return (reg.file == file_XMM && + cp->xmm[reg.idx].file == TGSI_FILE_NULL); +} + +static struct x86_reg get_xmm_tmp( struct aos_compilation *cp, + struct x86_reg reg ) +{ + if (!is_xmm_tmp(cp, reg)) { + struct x86_reg tmp = aos_get_xmm_reg(cp); + sse_movups(cp->func, tmp, reg); + reg = tmp; + } + + return reg; +} + + struct x86_reg aos_get_xmm_reg( struct aos_compilation *cp ) { unsigned i; unsigned oldest = 0; + boolean found = FALSE; for (i = 0; i < 8; i++) - if (cp->xmm[i].last_used < cp->xmm[oldest].last_used) + if (cp->xmm[i].last_used != cp->insn_counter && + cp->xmm[i].file == TGSI_FILE_NULL) { oldest = i; + found = TRUE; + } + + if (!found) { + for (i = 0; i < 8; i++) + if (cp->xmm[i].last_used < cp->xmm[oldest].last_used) + oldest = i; + } /* Need to write out the old value? */ @@ -237,15 +267,24 @@ void aos_adopt_xmm_reg( struct aos_compilation *cp, unsigned idx, unsigned dirty ) { + unsigned i; + if (reg.file != file_XMM) { assert(0); return; } - invalidate_xmm(cp, file, idx); + for (i = 0; i < 8; i++) { + if (cp->xmm[i].file == file && + cp->xmm[i].idx == idx) { + aos_release_xmm_reg(cp, i); + } + } + cp->xmm[reg.idx].file = file; cp->xmm[reg.idx].idx = idx; cp->xmm[reg.idx].dirty = dirty; + cp->xmm[reg.idx].last_used = cp->insn_counter; } @@ -659,6 +698,7 @@ static void x87_fst_or_nop( struct x86_function *func, unsigned channel, struct x86_reg ptr ) { + assert(ptr.file == file_REG32); if (writemask & (1<FullSrcRegisters[0]); - struct x86_reg dst = aos_get_xmm_reg(cp); struct x86_reg neg = aos_get_internal(cp, IMM_NEGS); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); sse_mulps(cp->func, dst, neg); sse_maxps(cp->func, dst, arg0); @@ -782,9 +822,8 @@ static boolean emit_ADD( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); sse_addps(cp->func, dst, arg1); store_dest(cp, &op->FullDstRegisters[0], dst); @@ -806,10 +845,9 @@ static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = aos_get_xmm_reg(cp); struct x86_reg tmp = aos_get_xmm_reg(cp); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); sse_mulps(cp->func, dst, arg1); /* Now the hard bit: sum the first 3 values: @@ -831,10 +869,9 @@ static boolean emit_DP4( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = aos_get_xmm_reg(cp); struct x86_reg tmp = aos_get_xmm_reg(cp); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); sse_mulps(cp->func, dst, arg1); /* Now the hard bit: sum the values: @@ -854,10 +891,9 @@ static boolean emit_DPH( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = aos_get_xmm_reg(cp); struct x86_reg tmp = aos_get_xmm_reg(cp); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); sse_mulps(cp->func, dst, arg1); /* Now the hard bit: sum the values (from DP3): @@ -1152,9 +1188,8 @@ static boolean emit_MAX( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); sse_maxps(cp->func, dst, arg1); store_dest(cp, &op->FullDstRegisters[0], dst); @@ -1166,9 +1201,8 @@ static boolean emit_MIN( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); sse_minps(cp->func, dst, arg1); store_dest(cp, &op->FullDstRegisters[0], dst); @@ -1178,9 +1212,9 @@ static boolean emit_MIN( struct aos_compilation *cp, const struct tgsi_full_inst static boolean emit_MOV( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); - struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); + /* potentially nothing to do */ store_dest(cp, &op->FullDstRegisters[0], dst); return TRUE; @@ -1190,9 +1224,8 @@ static boolean emit_MUL( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); sse_mulps(cp->func, dst, arg1); store_dest(cp, &op->FullDstRegisters[0], dst); @@ -1205,13 +1238,15 @@ static boolean emit_MAD( struct aos_compilation *cp, const struct tgsi_full_inst struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); struct x86_reg arg2 = fetch_src(cp, &op->FullSrcRegisters[2]); - struct x86_reg dst = aos_get_xmm_reg(cp); - sse_movups(cp->func, dst, arg0); - sse_mulps(cp->func, dst, arg1); - sse_addps(cp->func, dst, arg2); + /* If we can't clobber old contents of arg0, get a temporary & copy + * it there, then clobber it... + */ + arg0 = get_xmm_tmp(cp, arg0); - store_dest(cp, &op->FullDstRegisters[0], dst); + sse_mulps(cp->func, arg0, arg1); + sse_addps(cp->func, arg0, arg2); + store_dest(cp, &op->FullDstRegisters[0], arg0); return TRUE; } @@ -1272,10 +1307,9 @@ static boolean emit_SGE( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = aos_get_xmm_reg(cp); struct x86_reg ones = aos_get_internal(cp, IMM_ONES); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); sse_cmpps(cp->func, dst, arg1, cc_NotLessThan); sse_andps(cp->func, dst, ones); @@ -1297,10 +1331,9 @@ static boolean emit_SLT( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = aos_get_xmm_reg(cp); struct x86_reg ones = aos_get_internal(cp, IMM_ONES); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); sse_cmpps(cp->func, dst, arg1, cc_LessThan); sse_andps(cp->func, dst, ones); @@ -1312,9 +1345,8 @@ static boolean emit_SUB( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg dst = get_xmm_tmp(cp, arg0); - sse_movups(cp->func, dst, arg0); sse_subps(cp->func, dst, arg1); store_dest(cp, &op->FullDstRegisters[0], dst); -- cgit v1.2.3 From 5b1bd30f22ffa3955150ec008631d0f4754d340f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 20:41:01 +0100 Subject: draw: when preloading args to x87 stack, need to use reverse order --- src/gallium/auxiliary/draw/draw_vs_aos.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 97de43c232..fde92c7226 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -980,7 +980,7 @@ static boolean emit_EXP( struct aos_compilation *cp, const struct tgsi_full_inst x87_fstp_or_pop(cp->func, writemask, 0, dst); /* flr(a) a 2^flr(a) */ - x87_fsubrp(cp->func, st1); /* frac(a) 2^flr(a) */ + x87_fsubp(cp->func, st1); /* frac(a) 2^flr(a) */ x87_fst_or_nop(cp->func, writemask, 1, dst); /* frac(a) 2^flr(a) */ @@ -1041,9 +1041,9 @@ static boolean emit_FLR( struct aos_compilation *cp, const struct tgsi_full_inst /* Load all sources first to avoid aliasing */ - for (i = 0; i < 4; i++) { + for (i = 3; i >= 0; i--) { if (writemask & (1<FullSrcRegisters[0], i); + x87_fld_src(cp, &op->FullSrcRegisters[0], i); } } @@ -1068,9 +1068,9 @@ static boolean emit_RND( struct aos_compilation *cp, const struct tgsi_full_inst /* Load all sources first to avoid aliasing */ - for (i = 0; i < 4; i++) { + for (i = 3; i >= 0; i--) { if (writemask & (1<FullSrcRegisters[0], i); + x87_fld_src(cp, &op->FullSrcRegisters[0], i); } } @@ -1098,7 +1098,7 @@ static boolean emit_FRC( struct aos_compilation *cp, const struct tgsi_full_inst /* suck all the source values onto the stack before writing out any * dst, which may alias... */ - for (i = 0; i < 4; i++) { + for (i = 3; i >= 0; i--) { if (writemask & (1<FullSrcRegisters[0], i); } @@ -1108,7 +1108,7 @@ static boolean emit_FRC( struct aos_compilation *cp, const struct tgsi_full_inst if (writemask & (1<func, st0); /* a a */ x87_fprndint( cp->func ); /* flr(a) a */ - x87_fsubrp(cp->func, st1); /* frc(a) */ + x87_fsubp(cp->func, st1); /* frc(a) */ x87_fstp(cp->func, x86_make_disp(dst, i*4)); } } @@ -1392,6 +1392,8 @@ static boolean emit_instruction( struct aos_compilation *cp, struct tgsi_full_instruction *inst ) { + x87_assert_stack_empty(cp->func); + switch( inst->Instruction.Opcode ) { case TGSI_OPCODE_MOV: return emit_MOV( cp, inst ); @@ -1657,6 +1659,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, break; } + x87_assert_stack_empty(cp.func); cp.insn_counter++; debug_printf("\n"); } @@ -1712,6 +1715,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, x86_pop(cp.func, cp.count_ESI); x86_pop(cp.func, cp.idx_EBX); + x87_assert_stack_empty(cp.func); x86_ret(cp.func); tgsi_parse_free( &parse ); -- cgit v1.2.3 From 6f407b072453eb2bb7077a952257a099db4da025 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 20:50:36 +0100 Subject: rtasm: remove debug --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index a2e8af343b..d78676b8f3 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -990,14 +990,12 @@ static void note_x87_pop( struct x86_function *p ) { p->x87_stack--; assert(p->x87_stack >= 0); - debug_printf("\nstack: %d\n", p->x87_stack); } static void note_x87_push( struct x86_function *p ) { p->x87_stack++; assert(p->x87_stack <= 7); - debug_printf("\nstack: %d\n", p->x87_stack); } void x87_assert_stack_empty( struct x86_function *p ) -- cgit v1.2.3 From a5c3b499fa40f46298389900e74f1db04f99166a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 22 May 2008 13:37:48 +0100 Subject: draw: fse works with elts, remove assert --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 984fbb6767..7fefd391a6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -78,11 +78,6 @@ static void fse_prepare( struct draw_pt_middle_end *middle, boolean need_psize = 0; - if (draw->pt.user.elts) { - assert(0); - return ; - } - if (!draw->render->set_primitive( draw->render, prim )) { assert(0); @@ -250,9 +245,8 @@ static void fse_run_linear( struct draw_pt_middle_end *middle, } /* Single routine to fetch vertices, run shader and emit HW verts. - * Clipping and viewport transformation are done elsewhere -- - * either by the API or on hardware, or for some other reason not - * required... + * Clipping is done elsewhere -- either by the API or on hardware, + * or for some other reason not required... */ fse->active->run_linear( fse->active, start, count, -- cgit v1.2.3 From c684ffa02d8d43ee04b99ee63ccd1adb66e81c1a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 22 May 2008 13:41:49 +0100 Subject: draw: clean up internal immediates in aos sse --- src/gallium/auxiliary/draw/draw_vs_aos.c | 64 +++++++++++++++++++++-------- src/gallium/auxiliary/draw/draw_vs_aos.h | 5 ++- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 10 ++--- 3 files changed, 55 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index fde92c7226..0b8600696a 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -44,12 +44,6 @@ #ifdef PIPE_ARCH_X86 -#define DISASSEM 0 - - - - - static INLINE boolean eq( struct x86_reg a, struct x86_reg b ) { @@ -92,13 +86,6 @@ static struct x86_reg get_reg_ptr(struct aos_compilation *cp, } -struct x86_reg aos_get_internal( struct aos_compilation *cp, - unsigned imm ) -{ - return get_reg_ptr( cp, - AOS_FILE_INTERNAL, - imm ); -} #define X87_CW_EXCEPTION_INV_OP (1<<0) #define X87_CW_EXCEPTION_DENORM_OP (1<<1) @@ -123,6 +110,9 @@ static void init_internals( struct aos_machine *machine ) float inv = 1.0f/255.0f; float f255 = 255.0f; + ASSIGN_4V(machine->internal[IMM_SWZ], 1.0f, -1.0f, 0.0f, 1.0f); + *(unsigned *)&machine->internal[IMM_SWZ][3] = 0xffffffff; + ASSIGN_4V(machine->internal[IMM_ONES], 1.0f, 1.0f, 1.0f, 1.0f); ASSIGN_4V(machine->internal[IMM_NEGS], -1.0f, -1.0f, -1.0f, -1.0f); ASSIGN_4V(machine->internal[IMM_IDENTITY], 0.0f, 0.0f, 0.0f, 1.0f); @@ -337,6 +327,39 @@ struct x86_reg aos_get_shader_reg( struct aos_compilation *cp, +static struct x86_reg aos_get_shader_reg_xmm( struct aos_compilation *cp, + unsigned file, + unsigned idx ) +{ + struct x86_reg reg = aos_get_shader_reg( cp, file, idx ); + + if (reg.file != file_XMM) { + struct x86_reg tmp = aos_get_xmm_reg(cp); + sse_movups(cp->func, tmp, reg); + aos_adopt_xmm_reg( cp, tmp, file, idx, FALSE ); + reg = tmp; + } + + return reg; +} + + + +struct x86_reg aos_get_internal_xmm( struct aos_compilation *cp, + unsigned imm ) +{ + return aos_get_shader_reg_xmm( cp, AOS_FILE_INTERNAL, imm ); +} + + +struct x86_reg aos_get_internal( struct aos_compilation *cp, + unsigned imm ) +{ + return aos_get_shader_reg( cp, AOS_FILE_INTERNAL, imm ); +} + + + /* Emulate pshufd insn in regular SSE, if necessary: @@ -461,15 +484,15 @@ static struct x86_reg fetch_src( struct aos_compilation *cp, arg0 = dst; } - if (negs) { - struct x86_reg imm_negs = aos_get_internal(cp, IMM_NEGS); + if (negs && negs != 0xf) { + struct x86_reg imm_swz = aos_get_internal_xmm(cp, IMM_SWZ); struct x86_reg tmp = aos_get_xmm_reg(cp); /* Load 1,-1,0,0 * Use neg as arg to pshufd * Multiply */ - emit_pshufd(cp, tmp, imm_negs, + emit_pshufd(cp, tmp, imm_swz, SHUF((negs & 1) ? 1 : 0, (negs & 2) ? 1 : 0, (negs & 4) ? 1 : 0, @@ -479,12 +502,17 @@ static struct x86_reg fetch_src( struct aos_compilation *cp, aos_release_xmm_reg(cp, tmp.idx); arg0 = dst; } + else if (negs) { + struct x86_reg imm_negs = aos_get_internal_xmm(cp, IMM_NEGS); + sse_mulps(cp->func, dst, imm_negs); + arg0 = dst; + } + if (abs && abs != 0xf) { ERROR(cp, "unsupported partial abs"); } - - if (abs) { + else if (abs) { struct x86_reg neg = aos_get_internal(cp, IMM_NEGS); struct x86_reg tmp = aos_get_xmm_reg(cp); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index c2afd4e9a0..efdc9a38f4 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -142,13 +142,16 @@ boolean aos_emit_outputs( struct aos_compilation *cp ); #define IMM_ONES 0 /* 1, 1,1,1 */ -#define IMM_NEGS 1 /* 1,-1,0,0 */ +#define IMM_SWZ 1 /* 1,-1,0, 0xffffffff */ #define IMM_IDENTITY 2 /* 0, 0,0,1 */ #define IMM_INV_255 3 /* 1/255, 1/255, 1/255, 1/255 */ #define IMM_255 4 /* 255, 255, 255, 255 */ +#define IMM_NEGS 5 /* -1,-1,-1,-1 */ struct x86_reg aos_get_internal( struct aos_compilation *cp, unsigned imm ); +struct x86_reg aos_get_internal_xmm( struct aos_compilation *cp, + unsigned imm ); #define ERROR(cp, msg) \ diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index 72b2b3d11d..0dda9df97d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -54,7 +54,7 @@ static void emit_load_R32G32B32( struct aos_compilation *cp, struct x86_reg src_ptr ) { sse_movss(cp->func, data, x86_make_disp(src_ptr, 8)); - sse_shufps(cp->func, data, aos_get_internal( cp, IMM_IDENTITY ), SHUF(X,Y,Z,W) ); + sse_shufps(cp->func, data, aos_get_internal_xmm( cp, IMM_IDENTITY ), SHUF(X,Y,Z,W) ); sse_shufps(cp->func, data, data, SHUF(Y,Z,X,W) ); sse_movlps(cp->func, data, src_ptr); } @@ -63,7 +63,7 @@ static void emit_load_R32G32( struct aos_compilation *cp, struct x86_reg data, struct x86_reg src_ptr ) { - sse_movups(cp->func, data, aos_get_internal( cp, IMM_IDENTITY ) ); + sse_movups(cp->func, data, aos_get_internal_xmm( cp, IMM_IDENTITY ) ); sse_movlps(cp->func, data, src_ptr); } @@ -73,7 +73,7 @@ static void emit_load_R32( struct aos_compilation *cp, struct x86_reg src_ptr ) { sse_movss(cp->func, data, src_ptr); - sse_orps(cp->func, data, aos_get_internal( cp, IMM_IDENTITY ) ); + sse_orps(cp->func, data, aos_get_internal_xmm( cp, IMM_IDENTITY ) ); } @@ -82,8 +82,8 @@ static void emit_load_R8G8B8A8_UNORM( struct aos_compilation *cp, struct x86_reg src_ptr ) { sse_movss(cp->func, data, src_ptr); - sse2_punpcklbw(cp->func, data, aos_get_internal( cp, IMM_IDENTITY )); - sse2_punpcklbw(cp->func, data, aos_get_internal( cp, IMM_IDENTITY )); + sse2_punpcklbw(cp->func, data, aos_get_internal_xmm( cp, IMM_IDENTITY )); + sse2_punpcklbw(cp->func, data, aos_get_internal_xmm( cp, IMM_IDENTITY )); sse2_cvtdq2ps(cp->func, data, data); sse_mulps(cp->func, data, aos_get_internal(cp, IMM_INV_255)); } -- cgit v1.2.3 From 05029c919d46299ca259ee8af880d0a65f95ce7c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 22 May 2008 13:46:06 +0100 Subject: draw: clean up masked writes in aos sse, make some xmm function names clearer --- src/gallium/auxiliary/draw/draw_vs_aos.c | 236 +++++++++++-------------------- 1 file changed, 82 insertions(+), 154 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 0b8600696a..708ecadbac 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -171,7 +171,7 @@ static boolean is_xmm_tmp( struct aos_compilation *cp, cp->xmm[reg.idx].file == TGSI_FILE_NULL); } -static struct x86_reg get_xmm_tmp( struct aos_compilation *cp, +static struct x86_reg get_xmm_clone( struct aos_compilation *cp, struct x86_reg reg ) { if (!is_xmm_tmp(cp, reg)) { @@ -380,31 +380,37 @@ static void emit_pshufd( struct aos_compilation *cp, } } - - - -/* Helper for writemask: +/* load masks (pack into negs??) + * pshufd - shuffle according to writemask + * and - result, mask + * nand - dest, mask + * or - dest, result */ -static boolean emit_shuf_copy1( struct aos_compilation *cp, - struct x86_reg dst, - struct x86_reg arg0, - struct x86_reg arg1, - ubyte shuf ) +static boolean mask_write( struct aos_compilation *cp, + struct x86_reg dst, + struct x86_reg result, + unsigned mask ) { + struct x86_reg imm_swz = aos_get_internal_xmm(cp, IMM_SWZ); struct x86_reg tmp = aos_get_xmm_reg(cp); - sse_movups(cp->func, dst, arg1); - emit_pshufd(cp, dst, dst, shuf); - emit_pshufd(cp, tmp, arg0, shuf); - - sse_movss(cp->func, dst, tmp); + + emit_pshufd(cp, tmp, imm_swz, + SHUF((mask & 1) ? 2 : 3, + (mask & 2) ? 2 : 3, + (mask & 4) ? 2 : 3, + (mask & 8) ? 2 : 3)); - emit_pshufd(cp, dst, dst, shuf); + sse_andps(cp->func, dst, tmp); + sse_andnps(cp->func, tmp, result); + sse_orps(cp->func, dst, tmp); aos_release_xmm_reg(cp, tmp.idx); return TRUE; } + + /* Helper for writemask: */ static boolean emit_shuf_copy2( struct aos_compilation *cp, @@ -414,17 +420,18 @@ static boolean emit_shuf_copy2( struct aos_compilation *cp, ubyte shuf ) { struct x86_reg tmp = aos_get_xmm_reg(cp); + emit_pshufd(cp, dst, arg1, shuf); emit_pshufd(cp, tmp, arg0, shuf); - sse_shufps(cp->func, dst, tmp, SHUF(X, Y, Z, W)); - emit_pshufd(cp, dst, dst, shuf); aos_release_xmm_reg(cp, tmp.idx); return TRUE; } + + #define SSE_SWIZZLE_NOOP ((0<<0) | (1<<2) | (2<<4) | (3<<6)) @@ -593,131 +600,58 @@ static void store_dest( struct aos_compilation *cp, const struct tgsi_full_dst_register *reg, struct x86_reg result ) { - if (reg->DstRegister.WriteMask == 0) - { - return; - } - else if (reg->DstRegister.WriteMask == TGSI_WRITEMASK_XYZW) - { - if (result.file == file_XMM) { - aos_adopt_xmm_reg(cp, - result, - reg->DstRegister.File, - reg->DstRegister.Index, - TRUE); - } - else { - struct x86_reg dst = aos_get_xmm_reg(cp); - aos_adopt_xmm_reg(cp, - dst, - reg->DstRegister.File, - reg->DstRegister.Index, - TRUE); - sse_movups(cp->func, dst, result); - } - } - else - { - /* Previous value of the dest register: - */ - struct x86_reg old_dst = aos_get_shader_reg(cp, - reg->DstRegister.File, - reg->DstRegister.Index); - - - /* Alloc an xmm reg to hold the new value of the dest register: - */ - struct x86_reg dst = aos_get_xmm_reg(cp); + struct x86_reg dst; + switch (reg->DstRegister.WriteMask) { + case 0: + return; + + case TGSI_WRITEMASK_XYZW: aos_adopt_xmm_reg(cp, - dst, + get_xmm_clone(cp, result), reg->DstRegister.File, reg->DstRegister.Index, - TRUE ); - - switch (reg->DstRegister.WriteMask) { - case TGSI_WRITEMASK_X: - if (result.file == file_XMM) { - sse_movups(cp->func, dst, old_dst); - sse_movss(cp->func, dst, result); - } - else { - struct x86_reg tmp = aos_get_xmm_reg(cp); - sse_movups(cp->func, dst, old_dst); - sse_movss(cp->func, tmp, result); - sse_movss(cp->func, dst, tmp); - aos_release_xmm_reg(cp, tmp.idx); - } - break; - - case TGSI_WRITEMASK_XY: - sse_movups(cp->func, dst, old_dst); - sse_shufps(cp->func, dst, result, SHUF(X, Y, Z, W)); - break; - - case TGSI_WRITEMASK_ZW: - sse_movups(cp->func, dst, result); - sse_shufps(cp->func, dst, old_dst, SHUF(X, Y, Z, W)); - break; - - case TGSI_WRITEMASK_YZW: - if (old_dst.file == file_XMM) { - sse_movups(cp->func, dst, result); - sse_movss(cp->func, dst, old_dst); - } - else { - struct x86_reg tmp = aos_get_xmm_reg(cp); - sse_movups(cp->func, dst, result); - sse_movss(cp->func, tmp, old_dst); - sse_movss(cp->func, dst, tmp); - aos_release_xmm_reg(cp, tmp.idx); - } - break; - - case TGSI_WRITEMASK_Y: - emit_shuf_copy1(cp, dst, result, old_dst, SHUF(Y,X,Z,W)); - break; - - case TGSI_WRITEMASK_Z: - emit_shuf_copy1(cp, dst, result, old_dst, SHUF(Z,Y,X,W)); - break; - - case TGSI_WRITEMASK_W: - emit_shuf_copy1(cp, dst, result, old_dst, SHUF(W,Y,Z,X)); - break; - - case TGSI_WRITEMASK_XZ: - emit_shuf_copy2(cp, dst, result, old_dst, SHUF(X,Z,Y,W)); - break; + TRUE); + return; + default: + break; + } - case TGSI_WRITEMASK_XW: - emit_shuf_copy2(cp, dst, result, old_dst, SHUF(X,W,Z,Y)); + dst = aos_get_shader_reg_xmm(cp, + reg->DstRegister.File, + reg->DstRegister.Index); - case TGSI_WRITEMASK_YZ: - emit_shuf_copy2(cp, dst, result, old_dst, SHUF(Z,Y,X,W)); - break; + switch (reg->DstRegister.WriteMask) { + case TGSI_WRITEMASK_X: + sse_movss(cp->func, dst, get_xmm_clone(cp, result)); + break; + + case TGSI_WRITEMASK_XY: + sse_shufps(cp->func, dst, get_xmm_clone(cp, result), SHUF(X, Y, Z, W)); + break; - case TGSI_WRITEMASK_YW: - emit_shuf_copy2(cp, dst, result, old_dst, SHUF(W,Y,Z,X)); - break; + case TGSI_WRITEMASK_ZW: + result = get_xmm_clone(cp, result); + sse_shufps(cp->func, result, dst, SHUF(X, Y, Z, W)); + dst = result; + break; - case TGSI_WRITEMASK_XZW: - emit_shuf_copy1(cp, dst, old_dst, result, SHUF(Y,X,Z,W)); - break; + case TGSI_WRITEMASK_YZW: + sse_movss(cp->func, result, dst); + dst = result; + break; - case TGSI_WRITEMASK_XYW: - emit_shuf_copy1(cp, dst, old_dst, result, SHUF(Z,Y,X,W)); - break; + default: + mask_write(cp, dst, result, reg->DstRegister.WriteMask); + break; + } - case TGSI_WRITEMASK_XYZ: - emit_shuf_copy1(cp, dst, old_dst, result, SHUF(W,Y,Z,X)); - break; + aos_adopt_xmm_reg(cp, + dst, + reg->DstRegister.File, + reg->DstRegister.Index, + TRUE); - default: - assert(0); /* not possible */ - break; - } - } } @@ -837,7 +771,7 @@ static boolean emit_ABS( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg neg = aos_get_internal(cp, IMM_NEGS); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); sse_mulps(cp->func, dst, neg); sse_maxps(cp->func, dst, arg0); @@ -850,7 +784,7 @@ static boolean emit_ADD( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); sse_addps(cp->func, dst, arg1); @@ -874,7 +808,7 @@ static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_inst struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); struct x86_reg tmp = aos_get_xmm_reg(cp); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); sse_mulps(cp->func, dst, arg1); @@ -898,7 +832,7 @@ static boolean emit_DP4( struct aos_compilation *cp, const struct tgsi_full_inst struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); struct x86_reg tmp = aos_get_xmm_reg(cp); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); sse_mulps(cp->func, dst, arg1); @@ -920,7 +854,7 @@ static boolean emit_DPH( struct aos_compilation *cp, const struct tgsi_full_inst struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); struct x86_reg tmp = aos_get_xmm_reg(cp); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); sse_mulps(cp->func, dst, arg1); @@ -1216,7 +1150,7 @@ static boolean emit_MAX( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); sse_maxps(cp->func, dst, arg1); @@ -1229,7 +1163,7 @@ static boolean emit_MIN( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); sse_minps(cp->func, dst, arg1); @@ -1240,7 +1174,7 @@ static boolean emit_MIN( struct aos_compilation *cp, const struct tgsi_full_inst static boolean emit_MOV( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); /* potentially nothing to do */ @@ -1252,7 +1186,7 @@ static boolean emit_MUL( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); sse_mulps(cp->func, dst, arg1); @@ -1270,7 +1204,7 @@ static boolean emit_MAD( struct aos_compilation *cp, const struct tgsi_full_inst /* If we can't clobber old contents of arg0, get a temporary & copy * it there, then clobber it... */ - arg0 = get_xmm_tmp(cp, arg0); + arg0 = get_xmm_clone(cp, arg0); sse_mulps(cp->func, arg0, arg1); sse_addps(cp->func, arg0, arg2); @@ -1336,7 +1270,7 @@ static boolean emit_SGE( struct aos_compilation *cp, const struct tgsi_full_inst struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); struct x86_reg ones = aos_get_internal(cp, IMM_ONES); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); sse_cmpps(cp->func, dst, arg1, cc_NotLessThan); sse_andps(cp->func, dst, ones); @@ -1360,7 +1294,7 @@ static boolean emit_SLT( struct aos_compilation *cp, const struct tgsi_full_inst struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); struct x86_reg ones = aos_get_internal(cp, IMM_ONES); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); sse_cmpps(cp->func, dst, arg1, cc_LessThan); sse_andps(cp->func, dst, ones); @@ -1373,7 +1307,7 @@ static boolean emit_SUB( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = get_xmm_tmp(cp, arg0); + struct x86_reg dst = get_xmm_clone(cp, arg0); sse_subps(cp->func, dst, arg1); @@ -1526,9 +1460,9 @@ emit_instruction( struct aos_compilation *cp, static boolean emit_viewport( struct aos_compilation *cp ) { - struct x86_reg pos = aos_get_shader_reg(cp, - TGSI_FILE_OUTPUT, - 0); + struct x86_reg pos = aos_get_shader_reg_xmm(cp, + TGSI_FILE_OUTPUT, + 0); struct x86_reg scale = x86_make_disp(cp->machine_EDX, Offset(struct aos_machine, scale)); @@ -1536,12 +1470,6 @@ static boolean emit_viewport( struct aos_compilation *cp ) struct x86_reg translate = x86_make_disp(cp->machine_EDX, Offset(struct aos_machine, translate)); - if (pos.file != file_XMM) { - struct x86_reg dst = aos_get_xmm_reg(cp); - sse_movups(cp->func, dst, pos); - pos = dst; - } - sse_mulps(cp->func, pos, scale); sse_addps(cp->func, pos, translate); -- cgit v1.2.3 From 7b25c1a4032960752d8a8e950bdf75740b2de2e8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 22 May 2008 13:47:08 +0100 Subject: draw: remove FPU_MANIP ifdef --- src/gallium/auxiliary/draw/draw_vs_aos.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 708ecadbac..d60940bb7a 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -693,48 +693,39 @@ static void x87_fstp_dest4( struct aos_compilation *cp, x87_fstp_or_pop(cp->func, writemask, 3, ptr); } -#define FPU_MANIP 1 /* Save current x87 state and put it into single precision mode. */ static void save_fpu_state( struct aos_compilation *cp ) { -#if FPU_MANIP x87_fnstcw( cp->func, x86_make_disp(cp->machine_EDX, Offset(struct aos_machine, fpu_restore))); -#endif } static void restore_fpu_state( struct aos_compilation *cp ) { -#if FPU_MANIP x87_fnclex(cp->func); x87_fldcw( cp->func, x86_make_disp(cp->machine_EDX, Offset(struct aos_machine, fpu_restore))); -#endif } static void set_fpu_round_neg_inf( struct aos_compilation *cp ) { -#if FPU_MANIP if (cp->fpucntl != FPU_RND_NEG) { cp->fpucntl = FPU_RND_NEG; x87_fnclex(cp->func); x87_fldcw( cp->func, x86_make_disp(cp->machine_EDX, Offset(struct aos_machine, fpu_rnd_neg_inf))); } -#endif } static void set_fpu_round_nearest( struct aos_compilation *cp ) { -#if FPU_MANIP if (cp->fpucntl != FPU_RND_NEAREST) { cp->fpucntl = FPU_RND_NEAREST; x87_fnclex(cp->func); x87_fldcw( cp->func, x86_make_disp(cp->machine_EDX, Offset(struct aos_machine, fpu_rnd_nearest))); } -#endif } @@ -754,7 +745,7 @@ static void x87_emit_ex2( struct aos_compilation *cp ) x87_fld1(cp->func); /* 1 (2^frac(a))-1 a */ x87_faddp(cp->func, st1); /* 2^frac(a) a */ x87_fscale(cp->func); /* 2^a a */ - x87_fstp(cp->func, st1); + x87_fstp(cp->func, st1); /* 2^a */ assert( stack == cp->func->x87_stack); -- cgit v1.2.3 From 6780a6dede31e7f2eb465e1d7b507b3e64fe6ec9 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 22 May 2008 13:48:07 +0100 Subject: draw: shortcircuit shuffle in aos_sse when possible --- src/gallium/auxiliary/draw/draw_vs_aos.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index d60940bb7a..b8fad231ca 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -809,7 +809,9 @@ static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_inst sse_addss(cp->func, dst, tmp); /* a*x+c*z, b*y, ?, ? */ emit_pshufd(cp, tmp, dst, SHUF(Y,X,W,Z)); sse_addss(cp->func, dst, tmp); - sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); + + if (op->FullDstRegisters[0].DstRegister.WriteMask != 0x1) + sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); aos_release_xmm_reg(cp, tmp.idx); store_dest(cp, &op->FullDstRegisters[0], dst); @@ -833,7 +835,9 @@ static boolean emit_DP4( struct aos_compilation *cp, const struct tgsi_full_inst sse_addps(cp->func, dst, tmp); /* a*x+c*z, b*y+d*w, a*x+c*z, b*y+d*w */ emit_pshufd(cp, tmp, dst, SHUF(Y,X,W,Z)); sse_addss(cp->func, dst, tmp); - sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); + + if (op->FullDstRegisters[0].DstRegister.WriteMask != 0x1) + sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); aos_release_xmm_reg(cp, tmp.idx); store_dest(cp, &op->FullDstRegisters[0], dst); @@ -857,7 +861,9 @@ static boolean emit_DPH( struct aos_compilation *cp, const struct tgsi_full_inst sse_addss(cp->func, dst, tmp); emit_pshufd(cp, tmp, arg1, SHUF(W,W,W,W)); sse_addss(cp->func, dst, tmp); - sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); + + if (op->FullDstRegisters[0].DstRegister.WriteMask != 0x1) + sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); aos_release_xmm_reg(cp, tmp.idx); store_dest(cp, &op->FullDstRegisters[0], dst); @@ -1233,7 +1239,8 @@ static boolean emit_RCP( struct aos_compilation *cp, const struct tgsi_full_inst sse_divss(cp->func, dst, arg0); } - sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); + if (op->FullDstRegisters[0].DstRegister.WriteMask != 0x1) + sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); store_dest(cp, &op->FullDstRegisters[0], dst); return TRUE; @@ -1249,7 +1256,8 @@ static boolean emit_RSQ( struct aos_compilation *cp, const struct tgsi_full_inst /* Extend precision here... */ - sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); + if (op->FullDstRegisters[0].DstRegister.WriteMask != 0x1) + sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); store_dest(cp, &op->FullDstRegisters[0], dst); return TRUE; -- cgit v1.2.3 From 65cb09249e750b45ec3fc9a57670fc77250efc5e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 22 May 2008 13:49:38 +0100 Subject: draw: for debug, do rhw divide in aos_sse viewport calcs --- src/gallium/auxiliary/draw/draw_vs_aos.c | 45 +++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index b8fad231ca..40de13a98c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1481,6 +1481,46 @@ static boolean emit_viewport( struct aos_compilation *cp ) } +/* This is useful to be able to see the results on softpipe. Doesn't + * do proper clipping, just assumes the backend can do it during + * rasterization -- for debug only... + */ +static boolean emit_rhw_viewport( struct aos_compilation *cp ) +{ + struct x86_reg tmp = aos_get_xmm_reg(cp); + struct x86_reg pos = aos_get_shader_reg_xmm(cp, + TGSI_FILE_OUTPUT, + 0); + + struct x86_reg scale = x86_make_disp(cp->machine_EDX, + Offset(struct aos_machine, scale)); + + struct x86_reg translate = x86_make_disp(cp->machine_EDX, + Offset(struct aos_machine, translate)); + + + + emit_pshufd(cp, tmp, pos, SHUF(W, W, W, W)); + sse2_rcpss(cp->func, tmp, tmp); + sse_shufps(cp->func, tmp, tmp, SHUF(X, X, X, X)); + + sse_mulps(cp->func, pos, scale); + sse_mulps(cp->func, pos, tmp); + sse_addps(cp->func, pos, translate); + + /* Set pos[3] = w + */ + mask_write(cp, pos, tmp, TGSI_WRITEMASK_W); + + aos_adopt_xmm_reg( cp, + pos, + TGSI_FILE_OUTPUT, + 0, + TRUE ); + return TRUE; +} + + static boolean note_immediate( struct aos_compilation *cp, struct tgsi_full_immediate *imm ) { @@ -1623,7 +1663,10 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, goto fail; if (cp.vaos->base.key.viewport) { - emit_viewport(&cp); + if (0) + emit_viewport(&cp); + else + emit_rhw_viewport(&cp); } /* Emit output... TODO: do this eagerly after the last write to a -- cgit v1.2.3 From 260001430bbd28ea17201f1980ab1ebed93b246f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 22 May 2008 15:24:02 +0100 Subject: draw: use aligned movs within draw_vs_aos.c --- src/gallium/auxiliary/draw/draw_vs_aos.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 40de13a98c..039e233fe8 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -159,7 +159,7 @@ static void spill( struct aos_compilation *cp, unsigned idx ) cp->xmm[idx].idx); assert(cp->xmm[idx].dirty); - sse_movups(cp->func, oldval, x86_make_reg(file_XMM, idx)); + sse_movaps(cp->func, oldval, x86_make_reg(file_XMM, idx)); cp->xmm[idx].dirty = 0; } } @@ -176,7 +176,7 @@ static struct x86_reg get_xmm_clone( struct aos_compilation *cp, { if (!is_xmm_tmp(cp, reg)) { struct x86_reg tmp = aos_get_xmm_reg(cp); - sse_movups(cp->func, tmp, reg); + sse_movaps(cp->func, tmp, reg); reg = tmp; } @@ -335,7 +335,7 @@ static struct x86_reg aos_get_shader_reg_xmm( struct aos_compilation *cp, if (reg.file != file_XMM) { struct x86_reg tmp = aos_get_xmm_reg(cp); - sse_movups(cp->func, tmp, reg); + sse_movaps(cp->func, tmp, reg); aos_adopt_xmm_reg( cp, tmp, file, idx, FALSE ); reg = tmp; } @@ -374,7 +374,7 @@ static void emit_pshufd( struct aos_compilation *cp, } else { if (!eq(dst, arg0)) - sse_movups(cp->func, dst, arg0); + sse_movaps(cp->func, dst, arg0); sse_shufps(cp->func, dst, dst, shuf); } @@ -523,7 +523,7 @@ static struct x86_reg fetch_src( struct aos_compilation *cp, struct x86_reg neg = aos_get_internal(cp, IMM_NEGS); struct x86_reg tmp = aos_get_xmm_reg(cp); - sse_movups(cp->func, tmp, arg0); + sse_movaps(cp->func, tmp, arg0); sse_mulps(cp->func, tmp, neg); sse_maxps(cp->func, dst, arg0); -- cgit v1.2.3 From 43df4642f1d2f3d2673a1d5e4f5126f5175fb899 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 22 May 2008 20:21:49 +0100 Subject: draw: tweak x87_emit_ex2 to avoid changing x87 fpu settings --- src/gallium/auxiliary/draw/draw_vs_aos.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 039e233fe8..93bb4f9bc0 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -735,16 +735,17 @@ static void x87_emit_ex2( struct aos_compilation *cp ) struct x86_reg st1 = x86_make_reg(file_x87, 1); int stack = cp->func->x87_stack; - set_fpu_round_neg_inf( cp ); +// set_fpu_round_neg_inf( cp ); x87_fld(cp->func, st0); /* a a */ - x87_fld(cp->func, st0); /* a a a */ - x87_fprndint( cp->func ); /* flr(a) a a*/ - x87_fsubp(cp->func, st1); /* frac(a) a */ - x87_f2xm1(cp->func); /* (2^frac(a))-1 a */ - x87_fld1(cp->func); /* 1 (2^frac(a))-1 a */ - x87_faddp(cp->func, st1); /* 2^frac(a) a */ - x87_fscale(cp->func); /* 2^a a */ + x87_fprndint( cp->func ); /* int(a) a*/ + x87_fsubr(cp->func, st1, st0); /* int(a) frc(a) */ + x87_fxch(cp->func, st1); /* frc(a) int(a) */ + x87_f2xm1(cp->func); /* (2^frc(a))-1 int(a) */ + x87_fld1(cp->func); /* 1 (2^frc(a))-1 int(a) */ + x87_faddp(cp->func, st1); /* 2^frac(a) int(a) */ + x87_fscale(cp->func); /* (2^frac(a)*2^int(int(a))) int(a) */ + /* 2^a int(a) */ x87_fstp(cp->func, st1); /* 2^a */ assert( stack == cp->func->x87_stack); -- cgit v1.2.3 From 7106da136069f865747e03c30ca245bc030b241b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 22 May 2008 20:22:15 +0100 Subject: draw: correct but slow LIT() in aos varient --- src/gallium/auxiliary/draw/draw_vs_aos.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 93bb4f9bc0..930914f609 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1093,10 +1093,12 @@ static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_inst - /* a1' = a1 <= 0 ? 1 : a1; + /* a1' = a1 <= 0 ? 1 : a1; + * + * Note: use 1.0 to avoid passing zero to */ - x87_fldz(cp->func); /* 0 */ - x87_fld1(cp->func); /* 1 0 */ + x87_fldz(cp->func); /* 1 0 */ + x87_fldz(cp->func); /* 1 0 */ x87_fld_src(cp, &op->FullSrcRegisters[0], 1); /* a1 1 0 */ x87_fcomi(cp->func, st2); /* a1 1 0 */ x87_fcmovb(cp->func, st1); /* a1' 1 0 */ @@ -1119,17 +1121,14 @@ static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_inst x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* a0 0 r2 */ x87_fcomi(cp->func, st1); x87_fcmovb(cp->func, st1); /* a0' 0 r2 */ - x87_fstp(cp->func, st1); /* a0' r2 */ - x87_fxch(cp->func, st1); /* a0' r2 */ x87_fst_or_nop(cp->func, writemask, 1, dst); /* result[1] = a0' */ - x87_fldz(cp->func); /* 0 a0' r2 */ - x87_fcomi(cp->func, st1); /* 0 a0' r2 */ - x87_fcmovnbe(cp->func, st2); /* r2' a0' r2 */ + x87_fcomi(cp->func, st1); /* a0' 0 r2 */ + x87_fcmovnbe(cp->func, st2); /* r2' 0' r2 */ - x87_fstp_or_pop(cp->func, writemask, 2, dst); - x87_fpop(cp->func); + x87_fstp_or_pop(cp->func, writemask, 2, dst); /* 0 r2 */ + x87_fpop(cp->func); /* r2 */ x87_fpop(cp->func); } -- cgit v1.2.3 From 3b41d619a1b7cc8c356c32af777486461ddd7926 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 23 May 2008 09:14:17 +0100 Subject: draw: faster LIT(), incorrect though --- src/gallium/auxiliary/draw/draw_vs_aos.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 930914f609..b0c3ac49d2 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1098,7 +1098,13 @@ static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_inst * Note: use 1.0 to avoid passing zero to */ x87_fldz(cp->func); /* 1 0 */ +#if 1 + x87_fld1(cp->func); /* 1 0 */ +#else + /* Correct but slow due to fp exceptions generated in fyl2x - fix me. + */ x87_fldz(cp->func); /* 1 0 */ +#endif x87_fld_src(cp, &op->FullSrcRegisters[0], 1); /* a1 1 0 */ x87_fcomi(cp->func, st2); /* a1 1 0 */ x87_fcmovb(cp->func, st1); /* a1' 1 0 */ -- cgit v1.2.3 From 45fd9ec462bf338b286d3b757c3e67d54f663dad Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 22 May 2008 16:42:53 +0200 Subject: i915: Use the malloc pool for constant buffers since they don't go to the GPU directly. --- src/gallium/winsys/dri/intel/intel_winsys.h | 2 +- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 29 ++++++++++++------------ 2 files changed, 16 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_winsys.h b/src/gallium/winsys/dri/intel/intel_winsys.h index d0a319f9a4..3d32db10a4 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys.h +++ b/src/gallium/winsys/dri/intel/intel_winsys.h @@ -53,6 +53,7 @@ intel_create_i915simple( struct intel_context *intel, struct intel_buffer { struct pipe_buffer base; + struct _DriBufferPool *pool; struct _DriBufferObject *driBO; }; @@ -69,5 +70,4 @@ dri_bo( struct pipe_buffer *buf ) } - #endif diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 44baa6d9fa..7b1c0acfc9 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -50,6 +50,7 @@ struct intel_pipe_winsys { struct pipe_winsys winsys; struct _DriBufferPool *regionPool; + struct _DriBufferPool *mallocPool; struct _DriFreeSlabManager *fMan; }; @@ -110,16 +111,19 @@ intel_buffer_create(struct pipe_winsys *winsys, struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); unsigned flags = 0; + struct _DriBufferPool *pool; buffer->base.refcount = 1; buffer->base.alignment = alignment; buffer->base.usage = usage; buffer->base.size = size; - if (usage & (PIPE_BUFFER_USAGE_VERTEX /*| IWS_BUFFER_USAGE_LOCAL*/)) { + if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + pool = iws->mallocPool; } else { flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->regionPool; } if (usage & PIPE_BUFFER_USAGE_GPU_READ) @@ -141,10 +145,11 @@ intel_buffer_create(struct pipe_winsys *winsys, flags |= DRM_BO_FLAG_CACHED; #endif - driGenBuffers( iws->regionPool, + buffer->pool = pool; + driGenBuffers( buffer->pool, "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); - driBOData( buffer->driBO, size, NULL, iws->regionPool, 0 ); + driBOData( buffer->driBO, size, NULL, buffer->pool, 0 ); return &buffer->base; } @@ -278,8 +283,7 @@ intel_fence_finish( struct pipe_winsys *sws, struct pipe_fence_handle *fence, unsigned flag ) { - /* JB: Lets allways lazy wait */ - return driFenceFinish((struct _DriFenceObject *)fence, flag, 1); + return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); } struct pipe_winsys * @@ -310,15 +314,9 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) iws->winsys.fence_finish = intel_fence_finish; if (fd) - iws->regionPool = driSlabPoolInit(fd, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - 64, 6, 16, 4096, 0, - fMan); + iws->regionPool = driDRMPoolInit(fd); + + iws->mallocPool = driMallocPoolInit(); return &iws->winsys; } @@ -331,6 +329,9 @@ intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) if (iws->regionPool) { driPoolTakeDown(iws->regionPool); } + if (iws->mallocPool) { + driPoolTakeDown(iws->mallocPool); + } free(iws); } -- cgit v1.2.3 From 01cc1eebe92441ec33e951b95f0a5b52721741f0 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 23 May 2008 11:14:12 +0200 Subject: i915: Make batchbuffers larger. --- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 2 +- src/gallium/winsys/dri/intel/intel_screen.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 3a8591b580..aa2eed53b8 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -65,7 +65,7 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch) driBOUnrefUserList(batch->list); driBOResetList(batch->list); - batch->size = 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; + batch->size = 4 * 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; driBOData(batch->buffer, batch->size, NULL, NULL, 0); /* diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index a3fc6d7344..58bebbe972 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -200,7 +200,7 @@ intelCreatePools(__DRIscreenPrivate * sPriv) DRM_BO_FLAG_MEM_TT, DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, - 4096, //intelScreen->maxBatchSize, + 4 * 4096, //intelScreen->maxBatchSize, 1, 40, 16*16384, 0, intelScreen->fMan); #endif -- cgit v1.2.3 From d607a02da929cd192a3b0896c38dbb468ffa5b0d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 23 May 2008 11:24:33 +0200 Subject: i915: Made EGL report the actual modes on the screen/output pair --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index a9c0218455..ac1825210e 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -94,6 +94,18 @@ drm_update_res(struct drm_driver *drm_drv) drm_drv->res = drmModeGetResources(drm_drv->device->drmFD); } +static void +drm_add_modes_from_output(_EGLScreen *screen, drmModeOutputPtr output) +{ + struct drm_mode_modeinfo *m; + int i; + + for (i = 0; i < output->count_modes; i++) { + m = &output->modes[i]; + _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); + } +} + static EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) { @@ -137,7 +149,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) screen->output = output; _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); - _eglAddNewMode(&screen->base, 1024, 768, 60 * 1000, "1024x768-60"); + drm_add_modes_from_output(&screen->base, output); } /* for now we only have one config */ @@ -396,7 +408,7 @@ drm_find_mode(drmModeOutputPtr output, _EGLMode *mode) for (i = 0; i < output->count_modes; i++) { m = &output->modes[i]; - if (m->hdisplay == mode->Width && m->vdisplay == mode->Height) + if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) break; m = NULL; } -- cgit v1.2.3 From 845db16dbe66c0f741063333a70af79bca5b6544 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 22 May 2008 15:02:54 +0200 Subject: i915: Fix for edgeflags --- src/gallium/drivers/i915simple/i915_state.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 4adeb37e86..964bd7c871 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -717,10 +717,16 @@ static void i915_set_vertex_elements(struct pipe_context *pipe, } +static void i915_set_edgeflags(struct pipe_context *pipe, + const unsigned *bitfield) +{ + /* TODO do something here */ +} void i915_init_state_functions( struct i915_context *i915 ) { + i915->pipe.set_edgeflags = i915_set_edgeflags; i915->pipe.create_blend_state = i915_create_blend_state; i915->pipe.bind_blend_state = i915_bind_blend_state; i915->pipe.delete_blend_state = i915_delete_blend_state; -- cgit v1.2.3 From 5bf6ffb0b2be34ffb000e9700861b177afa9df97 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 23 May 2008 16:11:38 +0200 Subject: i915: Improved vertex buffer performance --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 7b1c0acfc9..62b43cc395 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -51,7 +51,8 @@ struct intel_pipe_winsys { struct pipe_winsys winsys; struct _DriBufferPool *regionPool; struct _DriBufferPool *mallocPool; - struct _DriFreeSlabManager *fMan; + struct _DriBufferPool *vertexPool; + struct _DriFreeSlabManager *fMan; /** shared between all pipes */ }; @@ -119,8 +120,12 @@ intel_buffer_create(struct pipe_winsys *winsys, buffer->base.size = size; if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { - flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + flags |= DRM_BO_FLAG_MEM_LOCAL; pool = iws->mallocPool; + } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { + /* For vertex buffers */ + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->vertexPool; } else { flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; pool = iws->regionPool; @@ -313,8 +318,19 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) iws->winsys.fence_signalled = intel_fence_signalled; iws->winsys.fence_finish = intel_fence_finish; - if (fd) + if (fd) { iws->regionPool = driDRMPoolInit(fd); + iws->vertexPool = driSlabPoolInit(fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + 32 * 4096, + 1, 40, 32 * 4096 * 2, 0, + fMan); + } iws->mallocPool = driMallocPoolInit(); -- cgit v1.2.3 From 7fbb61eedd4b07f07007a172cea227d5c363b908 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 23 May 2008 16:55:30 +0200 Subject: i915: Revert accidental change --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 62b43cc395..6a42c79033 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -120,7 +120,7 @@ intel_buffer_create(struct pipe_winsys *winsys, buffer->base.size = size; if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { - flags |= DRM_BO_FLAG_MEM_LOCAL; + flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; pool = iws->mallocPool; } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { /* For vertex buffers */ -- cgit v1.2.3 From 059a652d64da470ccc7f2f3266fd64721848a7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 24 May 2008 19:25:02 +0900 Subject: scons: New profile build. --- src/gallium/auxiliary/util/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index d55d2c7081..0309de1ac2 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -5,6 +5,7 @@ util = env.ConvenienceLibrary( source = [ 'p_debug.c', 'p_debug_mem.c', + 'p_debug_prof.c', 'p_tile.c', 'p_util.c', 'u_blit.c', -- cgit v1.2.3 From 345eb7fb70840829571cbacdb3980181df8e018a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 24 May 2008 19:25:33 +0900 Subject: gallium: Poor-man profiler for win32 kernel. --- src/gallium/auxiliary/util/p_debug_prof.c | 175 ++++++++++++++++++++++++++++++ src/gallium/include/pipe/p_debug.h | 11 ++ 2 files changed, 186 insertions(+) create mode 100644 src/gallium/auxiliary/util/p_debug_prof.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug_prof.c b/src/gallium/auxiliary/util/p_debug_prof.c new file mode 100644 index 0000000000..958f99c327 --- /dev/null +++ b/src/gallium/auxiliary/util/p_debug_prof.c @@ -0,0 +1,175 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Poor-man profiling. + * + * @author José Fonseca + * + * @sa http://blogs.msdn.com/joshpoley/archive/2008/03/12/poor-man-s-profiler.aspx + * @sa http://www.johnpanzer.com/aci_cuj/index.html + */ + +#include "pipe/p_config.h" + +#if defined(PROFILE) && defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + +#include +#include + +#include "pipe/p_debug.h" +#include "util/u_string.h" + + +#define PROFILE_FILE_SIZE 4*1024*1024 +#define FILE_NAME_SIZE 256 + +static WCHAR wFileName[FILE_NAME_SIZE]; +static ULONG_PTR iFile = 0; +static void *pMap = NULL; +static void *pMapEnd = NULL; + + +/** + * Called at the start of every method or function. + * + * @sa http://msdn.microsoft.com/en-us/library/c63a9b7h.aspx + */ +void __declspec(naked) __cdecl +_penter(void) { + _asm { + push ebx + mov ebx, [pMap] + test ebx, ebx + jz done + cmp ebx, [pMapEnd] + je done + push eax + push edx + mov eax, [esp+12] + and eax, 0xfffffffe + mov [ebx], eax + add ebx, 4 + rdtsc + mov [ebx], eax + add ebx, 4 + mov [pMap], ebx + pop edx + pop eax +done: + pop ebx + ret + } +} + + +/** + * Called at the end of Calls the end of every method or function. + * + * @sa http://msdn.microsoft.com/en-us/library/xc11y76y.aspx + */ +void __declspec(naked) __cdecl +_pexit(void) { + _asm { + push ebx + mov ebx, [pMap] + test ebx, ebx + jz done + cmp ebx, [pMapEnd] + je done + push eax + push edx + mov eax, [esp+12] + or eax, 0x00000001 + mov [ebx], eax + add ebx, 4 + rdtsc + mov [ebx], eax + add ebx, 4 + mov [pMap], ebx + pop edx + pop eax +done: + pop ebx + ret + } +} + + +void __declspec(naked) +__debug_profile_reference1(void) { + _asm { + call _penter + call _pexit + ret + } +} + + +void __declspec(naked) +__debug_profile_reference2(void) { + _asm { + call _penter + call __debug_profile_reference1 + call _pexit + ret + } +} + + +void +debug_profile_start(void) +{ + static unsigned no = 0; + char filename[FILE_NAME_SIZE]; + unsigned i; + + util_snprintf(filename, sizeof(filename), "\\??\\c:\\%03u.prof", ++no); + for(i = 0; i < FILE_NAME_SIZE; ++i) + wFileName[i] = (WCHAR)filename[i]; + + pMap = EngMapFile(wFileName, PROFILE_FILE_SIZE, &iFile); + if(pMap) { + pMapEnd = (unsigned char*)pMap + PROFILE_FILE_SIZE; + /* reference functions for calibration purposes */ + __debug_profile_reference2(); + } +} + +void +debug_profile_stop(void) +{ + if(iFile) { + EngUnmapFile(iFile); + /* TODO: truncate file */ + } + iFile = 0; + pMapEnd = pMap = NULL; +} + +#endif /* PROFILE */ diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 1263d0da61..0af635be57 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -313,6 +313,17 @@ void debug_memory_end(unsigned long beginning); +#if defined(PROFILE) && defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + +void +debug_profile_start(void); + +void +debug_profile_stop(void); + +#endif + + #ifdef DEBUG void debug_dump_image(const char *prefix, unsigned format, unsigned cpp, -- cgit v1.2.3 From 6b3723ee8d084a1abbc971b21c58f7c1e66949a7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 24 May 2008 13:22:15 +0100 Subject: rtasm: add some helpers for calling out from generated code --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 44 ++++++++++++++++++++++++++++-- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 6 ++++ 2 files changed, 47 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index d78676b8f3..2415b0156b 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -218,6 +218,8 @@ static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1 /* Build a modRM byte + possible displacement. No treatment of SIB * indexing. BZZT - no way to encode an absolute address. + * + * This is the "/r" field in the x86 manuals... */ static void emit_modrm( struct x86_function *p, struct x86_reg reg, @@ -256,7 +258,8 @@ static void emit_modrm( struct x86_function *p, } } - +/* Emits the "/0".."/7" specialized versions of the modrm ("/r") bytes. + */ static void emit_modrm_noreg( struct x86_function *p, unsigned op, struct x86_reg regmem ) @@ -365,8 +368,7 @@ void x86_jcc( struct x86_function *p, DUMP_I(cc); if (offset < 0) { - int amt = p->csr - p->store; - assert(amt > -offset); + assert(p->csr - p->store > -offset); } if (offset <= 127 && offset >= -128) { @@ -443,6 +445,16 @@ void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) emit_1i(p, imm); } +void x86_add_reg_imm8( struct x86_function *p, struct x86_reg dst, ubyte imm ) +{ + DUMP_RI( dst, imm ); + assert(dst.mod == mod_REG); + emit_1ub(p, 0x80); + emit_modrm_noreg(p, 0, dst); + emit_1ub(p, imm); +} + + void x86_push( struct x86_function *p, struct x86_reg reg ) { @@ -459,6 +471,17 @@ void x86_push( struct x86_function *p, p->stack_offset += 4; } +void x86_push_imm32( struct x86_function *p, + int imm32 ) +{ + DUMP_I( imm32 ); + emit_1ub(p, 0x68); + emit_1i(p, imm32); + + p->stack_offset += 4; +} + + void x86_pop( struct x86_function *p, struct x86_reg reg ) { @@ -1558,6 +1581,21 @@ void mmx_movq( struct x86_function *p, */ +void x86_cdecl_caller_push_regs( struct x86_function *p ) +{ + x86_push(p, x86_make_reg(file_REG32, reg_AX)); + x86_push(p, x86_make_reg(file_REG32, reg_CX)); + x86_push(p, x86_make_reg(file_REG32, reg_DX)); +} + +void x86_cdecl_caller_pop_regs( struct x86_function *p ) +{ + x86_pop(p, x86_make_reg(file_REG32, reg_DX)); + x86_pop(p, x86_make_reg(file_REG32, reg_CX)); + x86_pop(p, x86_make_reg(file_REG32, reg_AX)); +} + + /* Retreive a reference to one of the function arguments, taking into * account any push/pop activity: */ diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index 9f7e31e055..63e812fac9 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -155,6 +155,7 @@ void x86_call( struct x86_function *p, struct x86_reg reg); * I load the immediate into general purpose register and use it. */ void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ); +void x86_add_reg_imm8( struct x86_function *p, struct x86_reg dst, ubyte imm ); /* Macro for sse_shufps() and sse2_pshufd(): @@ -225,6 +226,7 @@ void x86_imul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_pop( struct x86_function *p, struct x86_reg reg ); void x86_push( struct x86_function *p, struct x86_reg reg ); +void x86_push_imm32( struct x86_function *p, int imm ); void x86_ret( struct x86_function *p ); void x86_retw( struct x86_function *p, unsigned short imm ); void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); @@ -232,6 +234,10 @@ void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_sahf( struct x86_function *p ); + +void x86_cdecl_caller_push_regs( struct x86_function *p ); +void x86_cdecl_caller_pop_regs( struct x86_function *p ); + void x87_assert_stack_empty( struct x86_function *p ); void x87_f2xm1( struct x86_function *p ); -- cgit v1.2.3 From 6172f1295cf812108d8ceba15a83ba87880360d3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 24 May 2008 13:22:29 +0100 Subject: draw: add a debug-print which can be called from inside generated shaders --- src/gallium/auxiliary/draw/draw_vs_aos.c | 67 ++++++++++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_aos.h | 1 + 2 files changed, 68 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index b0c3ac49d2..aa119f242e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -752,7 +752,63 @@ static void x87_emit_ex2( struct aos_compilation *cp ) } +static void PIPE_CDECL print_reg( const char *msg, + const float *reg ) +{ + debug_printf("%s: %f %f %f %f\n", msg, reg[0], reg[1], reg[2], reg[3]); +} + +static void emit_print( struct aos_compilation *cp, + const char *message, /* must point to a static string! */ + unsigned file, + unsigned idx ) +{ + struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); + struct x86_reg arg = get_reg_ptr( cp, file, idx ); + unsigned i; + + /* There shouldn't be anything on the x87 stack. Can add this + * capacity later if need be. + */ + assert(cp->func->x87_stack == 0); + + /* For absolute correctness, need to spill/invalidate all XMM regs + * too. We're obviously not concerned about performance on this + * debug path, so here goes: + */ + for (i = 0; i < 8; i++) { + if (cp->xmm[i].dirty) + spill(cp, i); + aos_release_xmm_reg(cp, i); + } + + /* Push caller-save (ie scratch) regs. + */ + x86_cdecl_caller_push_regs( cp->func ); + + + /* Push the arguments: + */ + x86_lea( cp->func, ecx, arg ); + x86_push( cp->func, ecx ); + x86_push_imm32( cp->func, (int)message ); + + /* Call the helper. Could call debug_printf directly, but + * print_reg is a nice place to put a breakpoint if need be. + */ + x86_mov_reg_imm( cp->func, ecx, (int)print_reg ); + x86_call( cp->func, ecx ); + x86_pop( cp->func, ecx ); + x86_pop( cp->func, ecx ); + + /* Pop caller-save regs + */ + x86_cdecl_caller_pop_regs( cp->func ); + + /* Done... + */ +} /** * The traditional instructions. All operate on internal registers @@ -1798,6 +1854,17 @@ static void vaos_set_constants( struct draw_vs_varient *varient, memcpy(vaos->machine->constant, constants, (vaos->base.vs->info.file_max[TGSI_FILE_CONSTANT] + 1) * 4 * sizeof(float)); + +#if 0 + unsigned i; + for (i =0; i < vaos->base.vs->info.file_max[TGSI_FILE_CONSTANT] + 1; i++) + debug_printf("state %d: %f %f %f %f\n", + i, + constants[i][0], + constants[i][1], + constants[i][2], + constants[i][3]); +#endif } diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index efdc9a38f4..a0680ec63d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -96,6 +96,7 @@ struct aos_compilation { unsigned insn_counter; unsigned num_immediates; + unsigned count; struct { unsigned idx:16; -- cgit v1.2.3 From 86e529ad90411d21bca3d70984b2db202e7a0cd6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 24 May 2008 16:31:11 +0100 Subject: draw: use lookup tables to avoid calling pow() in LIT opcode --- src/gallium/auxiliary/draw/draw_vs_aos.c | 251 ++++++++++++++++++++++++++++++- src/gallium/auxiliary/draw/draw_vs_aos.h | 27 ++++ 2 files changed, 272 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index aa119f242e..1fbb7088ca 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -105,8 +105,31 @@ static struct x86_reg get_reg_ptr(struct aos_compilation *cp, #define X87_CW_ROUND_MASK (3<<10) #define X87_CW_INFINITY (1<<12) +static void do_populate_lut( struct shine_tab *tab, + float unclamped_exponent ) +{ + const float epsilon = 1.0F / 256.0F; + float exponent = CLAMP(unclamped_exponent, -(128.0F - epsilon), (128.0F - epsilon)); + unsigned i; + + tab->exponent = unclamped_exponent; /* for later comparison */ + + tab->values[0] = 0; + if (exponent == 0) { + for (i = 1; i < 258; i++) { + tab->values[i] = 1.0; + } + } + else { + for (i = 1; i < 258; i++) { + tab->values[i] = powf((float)i * epsilon, exponent); + } + } +} + static void init_internals( struct aos_machine *machine ) { + unsigned i; float inv = 1.0f/255.0f; float f255 = 255.0f; @@ -141,6 +164,9 @@ static void init_internals( struct aos_machine *machine ) (1<<6) | X87_CW_ROUND_DOWN | X87_CW_PRECISION_DOUBLE_EXT); + + for (i = 0; i < MAX_SHINE_TAB; i++) + do_populate_lut( &machine->shine_tab[i], 1.0f ); } @@ -1132,26 +1158,231 @@ static boolean emit_FRC( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } +static PIPE_CDECL void do_lit( struct aos_machine *machine, + float *result, + const float *in, + unsigned count ) +{ + if (in[0] > 0) + { + if (in[1] <= 0.0) + { + result[0] = 1.0F; + result[1] = in[0]; + result[2] = 1.0; + result[3] = 1.0F; + } + else + { + const float epsilon = 1.0F / 256.0F; + float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon)); + result[0] = 1.0F; + result[1] = in[0]; + result[2] = powf(in[1], exponent); + result[3] = 1.0; + } + } + else + { + result[0] = 1.0F; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 1.0F; + } +} + + +static PIPE_CDECL void do_lit_lut( struct aos_machine *machine, + float *result, + const float *in, + unsigned count ) +{ + if (in[0] > 0) + { + if (in[1] <= 0.0) + { + result[0] = 1.0F; + result[1] = in[0]; + result[2] = 1.0; + result[3] = 1.0F; + return; + } + + if (machine->lit_info[count].shine_tab->exponent != in[3]) { + machine->lit_info[count].func = do_lit; + goto no_luck; + } + + if (in[1] <= 1.0) + { + const float *tab = machine->lit_info[count].shine_tab->values; + float f = in[1] * 256; + int k = (int)f; + float frac = f - (float)k; + + result[0] = 1.0F; + result[1] = in[0]; + result[2] = tab[k] + frac*(tab[k+1]-tab[k]); + result[3] = 1.0; + return; + } + + no_luck: + { + const float epsilon = 1.0F / 256.0F; + float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon)); + result[0] = 1.0F; + result[1] = in[0]; + result[2] = powf(in[1], exponent); + result[3] = 1.0; + } + } + else + { + result[0] = 1.0F; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 1.0F; + } +} + + + +static void PIPE_CDECL populate_lut( struct aos_machine *machine, + float *result, + const float *in, + unsigned count ) +{ + unsigned i, tab; + + /* Search for an existing table for this value. Note that without + * static analysis we don't really know if in[3] will be constant, + * but it usually is... + */ + for (tab = 0; tab < 4; tab++) { + if (machine->shine_tab[tab].exponent == in[3]) { + goto found; + } + } + + for (tab = 0, i = 1; i < 4; i++) { + if (machine->shine_tab[i].last_used < machine->shine_tab[tab].last_used) + tab = i; + } + + if (machine->shine_tab[tab].last_used == machine->now) { + /* No unused tables (this is not a ffvertex program...). Just + * call pow each time: + */ + machine->lit_info[count].func = do_lit; + machine->lit_info[count].func( machine, result, in, count ); + return; + } + else { + do_populate_lut( &machine->shine_tab[tab], in[3] ); + } + + found: + machine->shine_tab[tab].last_used = machine->now; + machine->lit_info[count].shine_tab = &machine->shine_tab[tab]; + machine->lit_info[count].func = do_lit_lut; + machine->lit_info[count].func( machine, result, in, count ); +} + + + static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { - struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); + struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask; + unsigned lit_count = cp->lit_count++; + struct x86_reg result, arg0; + unsigned i; + +#if 1 + /* For absolute correctness, need to spill/invalidate all XMM regs + * too. + */ + for (i = 0; i < 8; i++) { + if (cp->xmm[i].dirty) + spill(cp, i); + aos_release_xmm_reg(cp, i); + } +#endif + + if (writemask != TGSI_WRITEMASK_XYZW) + result = x86_make_disp(cp->machine_EDX, Offset(struct aos_machine, tmp[0])); + else + result = get_dst_ptr(cp, &op->FullDstRegisters[0]); + + + arg0 = fetch_src( cp, &op->FullSrcRegisters[0] ); + if (arg0.file == file_XMM) { + struct x86_reg tmp = x86_make_disp(cp->machine_EDX, + Offset(struct aos_machine, tmp[1])); + sse_movaps( cp->func, tmp, arg0 ); + arg0 = tmp; + } + + + + /* Push caller-save (ie scratch) regs. + */ + x86_cdecl_caller_push_regs( cp->func ); + + /* Push the arguments: + */ + x86_push_imm32( cp->func, lit_count ); + + x86_lea( cp->func, ecx, arg0 ); + x86_push( cp->func, ecx ); + x86_lea( cp->func, ecx, result ); + x86_push( cp->func, ecx ); + x86_push( cp->func, cp->machine_EDX ); + if (lit_count < MAX_LIT_INFO) { + x86_mov( cp->func, ecx, x86_make_disp( cp->machine_EDX, + Offset(struct aos_machine, lit_info) + + lit_count * sizeof(struct lit_info) + + Offset(struct lit_info, func))); + } + else { + x86_mov_reg_imm( cp->func, ecx, (int)do_lit ); + } + + x86_call( cp->func, ecx ); + + x86_pop( cp->func, ecx ); /* fixme... */ + x86_pop( cp->func, ecx ); + x86_pop( cp->func, ecx ); + x86_pop( cp->func, ecx ); + + x86_cdecl_caller_pop_regs( cp->func ); + + if (writemask != TGSI_WRITEMASK_XYZW) { + store_dest( cp, + &op->FullDstRegisters[0], + get_xmm_clone( cp, result ) ); + } + + return TRUE; +} + + +static boolean emit_inline_LIT( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); + unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask; if (writemask & TGSI_WRITEMASK_YZ) { struct x86_reg st1 = x86_make_reg(file_x87, 1); struct x86_reg st2 = x86_make_reg(file_x87, 2); - - - /* a1' = a1 <= 0 ? 1 : a1; - * - * Note: use 1.0 to avoid passing zero to */ x87_fldz(cp->func); /* 1 0 */ #if 1 @@ -1865,6 +2096,14 @@ static void vaos_set_constants( struct draw_vs_varient *varient, constants[i][2], constants[i][3]); #endif + + { + unsigned i; + for (i = 0; i < MAX_LIT_INFO; i++) { + vaos->machine->lit_info[i].func = populate_lut; + vaos->machine->now++; + } + } } diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index a0680ec63d..c08c73d4bc 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -59,6 +59,25 @@ struct x86_function; #define FPU_RND_NEG 1 #define FPU_RND_NEAREST 2 +struct aos_machine; +typedef void PIPE_CDECL (*lit_func)( struct aos_machine *, + float *result, + const float *in, + unsigned count ); +struct shine_tab { + float exponent; + float values[258]; + unsigned last_used; +}; + +struct lit_info { + lit_func func; + struct shine_tab *shine_tab; +}; + +#define MAX_SHINE_TAB 4 +#define MAX_LIT_INFO 16 + /* This is the temporary storage used by all the aos_sse vs varients. * Create one per context and reuse by passing a pointer in at * vs_varient creation?? @@ -74,6 +93,13 @@ struct aos_machine { float scale[4]; /* viewport */ float translate[4]; /* viewport */ + float tmp[2][4]; /* scratch space for LIT */ + + struct shine_tab shine_tab[MAX_SHINE_TAB]; + struct lit_info lit_info[MAX_LIT_INFO]; + unsigned now; + + ushort fpu_rnd_nearest; ushort fpu_rnd_neg_inf; ushort fpu_restore; @@ -97,6 +123,7 @@ struct aos_compilation { unsigned insn_counter; unsigned num_immediates; unsigned count; + unsigned lit_count; struct { unsigned idx:16; -- cgit v1.2.3 From a6fca8acb5e8ce0e5e6ce91a524e2bb4c180d3ac Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 25 May 2008 11:20:38 +0100 Subject: draw: fix input vs output typo in emit --- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index 0dda9df97d..f39ebb7a17 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -282,7 +282,7 @@ boolean aos_emit_outputs( struct aos_compilation *cp ) { unsigned i; - for (i = 0; i < cp->vaos->base.vs->info.num_inputs; i++) { + for (i = 0; i < cp->vaos->base.vs->info.num_outputs; i++) { unsigned format = cp->vaos->base.key.element[i].out.format; unsigned offset = cp->vaos->base.key.element[i].out.offset; -- cgit v1.2.3 From 584a3dcf8e4042cc1a5d48d83ea63d0a3c9706c1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 25 May 2008 11:25:09 +0100 Subject: draw: add viewport support to generic vs varient code --- src/gallium/auxiliary/draw/draw_vs_varient.c | 43 ++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index f6f621a748..c15c648527 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -44,7 +44,7 @@ struct draw_vs_varient_generic { struct draw_vs_varient base; - + struct pipe_viewport_state viewport; struct draw_vertex_shader *shader; struct draw_context *draw; @@ -87,6 +87,30 @@ static void vsvg_set_input( struct draw_vs_varient *varient, } +/* Mainly for debug at this stage: + */ +static void do_viewport( struct draw_vs_varient_generic *vsvg, + unsigned count, + void *output_buffer ) +{ + char *ptr = (char *)output_buffer; + const float *scale = vsvg->viewport.scale; + const float *trans = vsvg->viewport.translate; + unsigned stride = vsvg->base.key.output_stride; + unsigned j; + + for (j = 0; j < count; j++, ptr += stride) { + float *data = (float *)ptr; + float w = 1.0f / data[3]; + + data[0] = data[0] * w * scale[0] + trans[0]; + data[1] = data[1] * w * scale[1] + trans[1]; + data[2] = data[2] * w * scale[2] + trans[2]; + data[3] = w; + } +} + + static void vsvg_run_elts( struct draw_vs_varient *varient, const unsigned *elts, unsigned count, @@ -112,6 +136,12 @@ static void vsvg_run_elts( struct draw_vs_varient *varient, vsvg->base.key.output_stride, vsvg->base.key.output_stride); + if (vsvg->base.key.viewport) + do_viewport( vsvg, + count, + output_buffer ); + + //if (!vsvg->already_in_emit_format) vsvg->emit->set_buffer( vsvg->emit, @@ -152,6 +182,12 @@ static void vsvg_run_linear( struct draw_vs_varient *varient, vsvg->base.key.output_stride, vsvg->base.key.output_stride); + if (vsvg->base.key.viewport) + do_viewport( vsvg, + count, + output_buffer ); + + //if (!vsvg->already_in_emit_format) vsvg->emit->set_buffer( vsvg->emit, 0, @@ -171,6 +207,9 @@ static void vsvg_run_linear( struct draw_vs_varient *varient, static void vsvg_set_viewport( struct draw_vs_varient *varient, const struct pipe_viewport_state *viewport ) { + struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; + + vsvg->viewport = *viewport; } static void vsvg_destroy( struct draw_vs_varient *varient ) @@ -185,7 +224,7 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, unsigned i; struct translate_key fetch, emit; - if (key->viewport || key->clip) + if (key->clip) return NULL; struct draw_vs_varient_generic *vsvg = CALLOC_STRUCT( draw_vs_varient_generic ); -- cgit v1.2.3 From dc52622fcf5660a9675ed61c359cf7068aa4861b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 25 May 2008 15:28:30 +0100 Subject: cso: use memcpy rather than structure asignment for copying Apparently gcc will omit to copy hidden padding bytes under some circumstances, which means later on memcmp() will indicate a difference between structs even though all the visible members are identical. --- src/gallium/auxiliary/cso_cache/cso_context.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index a1a3a9efaf..7236bff592 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -292,7 +292,7 @@ enum pipe_error cso_set_blend(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state; cso->context = ctx->pipe; @@ -350,7 +350,7 @@ enum pipe_error cso_single_sampler(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state; cso->context = ctx->pipe; @@ -508,7 +508,7 @@ enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state; cso->context = ctx->pipe; @@ -564,7 +564,7 @@ enum pipe_error cso_set_rasterizer(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_rasterizer_state; cso->context = ctx->pipe; @@ -726,7 +726,7 @@ enum pipe_error cso_set_vertex_shader(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_vs_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_vs_state; cso->context = ctx->pipe; -- cgit v1.2.3 From caadc8d944c558e1fa9f23c3616d726337a19862 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 25 May 2008 15:37:47 +0100 Subject: draw: clean up some of the xmm register manipulation function names --- src/gallium/auxiliary/draw/draw_vs_aos.c | 141 +++++++++++++++++-------------- 1 file changed, 78 insertions(+), 63 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 1fbb7088ca..17b9442d6b 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -190,17 +190,26 @@ static void spill( struct aos_compilation *cp, unsigned idx ) } } -static boolean is_xmm_tmp( struct aos_compilation *cp, - struct x86_reg reg ) + +static struct x86_reg get_xmm_writable( struct aos_compilation *cp, + struct x86_reg reg ) { - return (reg.file == file_XMM && - cp->xmm[reg.idx].file == TGSI_FILE_NULL); + if (reg.file != file_XMM || + cp->xmm[reg.idx].file != TGSI_FILE_NULL) + { + struct x86_reg tmp = aos_get_xmm_reg(cp); + sse_movaps(cp->func, tmp, reg); + reg = tmp; + } + + return reg; } -static struct x86_reg get_xmm_clone( struct aos_compilation *cp, - struct x86_reg reg ) +static struct x86_reg get_xmm( struct aos_compilation *cp, + struct x86_reg reg ) { - if (!is_xmm_tmp(cp, reg)) { + if (reg.file != file_XMM) + { struct x86_reg tmp = aos_get_xmm_reg(cp); sse_movaps(cp->func, tmp, reg); reg = tmp; @@ -210,6 +219,9 @@ static struct x86_reg get_xmm_clone( struct aos_compilation *cp, } +/* Allocate an empty xmm register, either as a temporary or later to + * "adopt" as a shader reg. + */ struct x86_reg aos_get_xmm_reg( struct aos_compilation *cp ) { unsigned i; @@ -251,32 +263,11 @@ void aos_release_xmm_reg( struct aos_compilation *cp, cp->xmm[idx].last_used = 0; } -static void invalidate_xmm( struct aos_compilation *cp, - unsigned file, unsigned idx ) -{ - unsigned i; - - /* Invalidate any old copy of this register in XMM0-7. - */ - for (i = 0; i < 8; i++) { - if (cp->xmm[i].file == file && cp->xmm[i].idx == idx) { - - if (cp->xmm[i].dirty) - spill(cp, i); - - aos_release_xmm_reg(cp, i); - break; - } - } - for (; i < 8; i++) { - if (cp->xmm[i].file == file && cp->xmm[i].idx == idx) { - assert(0); - } - } -} - + +/* Mark an xmm reg as holding the current copy of a shader reg. + */ void aos_adopt_xmm_reg( struct aos_compilation *cp, struct x86_reg reg, unsigned file, @@ -290,6 +281,9 @@ void aos_adopt_xmm_reg( struct aos_compilation *cp, return; } + /* If any xmm reg thinks it holds this shader reg, break the + * illusion. + */ for (i = 0; i < 8; i++) { if (cp->xmm[i].file == file && cp->xmm[i].idx == idx) { @@ -304,12 +298,24 @@ void aos_adopt_xmm_reg( struct aos_compilation *cp, } - +/* Return a pointer to the in-memory copy of the reg, making sure it is uptodate. + */ static struct x86_reg aos_get_shader_reg_ptr( struct aos_compilation *cp, unsigned file, unsigned idx ) { - invalidate_xmm( cp, file, idx ); + unsigned i; + + /* Ensure the in-memory copy of this reg is up-to-date + */ + for (i = 0; i < 8; i++) { + if (cp->xmm[i].file == file && + cp->xmm[i].idx == idx && + cp->xmm[i].dirty) { + spill(cp, i); + } + } + return get_reg_ptr( cp, file, idx ); } @@ -320,7 +326,26 @@ static struct x86_reg aos_get_shader_reg_ptr( struct aos_compilation *cp, static struct x86_reg get_dst_ptr( struct aos_compilation *cp, const struct tgsi_full_dst_register *dst ) { - return aos_get_shader_reg_ptr( cp, dst->DstRegister.File, dst->DstRegister.Index ); + unsigned file = dst->DstRegister.File; + unsigned idx = dst->DstRegister.Index; + unsigned i; + + + /* Ensure in-memory copy of this reg is up-to-date and invalidate + * any xmm copies. + */ + for (i = 0; i < 8; i++) { + if (cp->xmm[i].file == file && + cp->xmm[i].idx == idx) + { + if (cp->xmm[i].dirty) + spill(cp, i); + + aos_release_xmm_reg(cp, i); + } + } + + return get_reg_ptr( cp, file, idx ); } @@ -358,15 +383,7 @@ static struct x86_reg aos_get_shader_reg_xmm( struct aos_compilation *cp, unsigned idx ) { struct x86_reg reg = aos_get_shader_reg( cp, file, idx ); - - if (reg.file != file_XMM) { - struct x86_reg tmp = aos_get_xmm_reg(cp); - sse_movaps(cp->func, tmp, reg); - aos_adopt_xmm_reg( cp, tmp, file, idx, FALSE ); - reg = tmp; - } - - return reg; + return get_xmm( cp, reg ); } @@ -634,7 +651,7 @@ static void store_dest( struct aos_compilation *cp, case TGSI_WRITEMASK_XYZW: aos_adopt_xmm_reg(cp, - get_xmm_clone(cp, result), + get_xmm_writable(cp, result), reg->DstRegister.File, reg->DstRegister.Index, TRUE); @@ -649,15 +666,15 @@ static void store_dest( struct aos_compilation *cp, switch (reg->DstRegister.WriteMask) { case TGSI_WRITEMASK_X: - sse_movss(cp->func, dst, get_xmm_clone(cp, result)); + sse_movss(cp->func, dst, get_xmm(cp, result)); break; case TGSI_WRITEMASK_XY: - sse_shufps(cp->func, dst, get_xmm_clone(cp, result), SHUF(X, Y, Z, W)); + sse_shufps(cp->func, dst, get_xmm(cp, result), SHUF(X, Y, Z, W)); break; case TGSI_WRITEMASK_ZW: - result = get_xmm_clone(cp, result); + result = get_xmm_writable(cp, result); sse_shufps(cp->func, result, dst, SHUF(X, Y, Z, W)); dst = result; break; @@ -845,7 +862,7 @@ static boolean emit_ABS( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg neg = aos_get_internal(cp, IMM_NEGS); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); sse_mulps(cp->func, dst, neg); sse_maxps(cp->func, dst, arg0); @@ -858,7 +875,7 @@ static boolean emit_ADD( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); sse_addps(cp->func, dst, arg1); @@ -882,10 +899,9 @@ static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_inst struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); struct x86_reg tmp = aos_get_xmm_reg(cp); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); sse_mulps(cp->func, dst, arg1); - /* Now the hard bit: sum the first 3 values: */ sse_movhlps(cp->func, tmp, dst); @@ -908,7 +924,7 @@ static boolean emit_DP4( struct aos_compilation *cp, const struct tgsi_full_inst struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); struct x86_reg tmp = aos_get_xmm_reg(cp); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); sse_mulps(cp->func, dst, arg1); @@ -932,7 +948,7 @@ static boolean emit_DPH( struct aos_compilation *cp, const struct tgsi_full_inst struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); struct x86_reg tmp = aos_get_xmm_reg(cp); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); sse_mulps(cp->func, dst, arg1); @@ -1366,7 +1382,7 @@ static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_inst if (writemask != TGSI_WRITEMASK_XYZW) { store_dest( cp, &op->FullDstRegisters[0], - get_xmm_clone( cp, result ) ); + get_xmm_writable( cp, result ) ); } return TRUE; @@ -1440,7 +1456,7 @@ static boolean emit_MAX( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); sse_maxps(cp->func, dst, arg1); @@ -1453,7 +1469,7 @@ static boolean emit_MIN( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); sse_minps(cp->func, dst, arg1); @@ -1464,7 +1480,7 @@ static boolean emit_MIN( struct aos_compilation *cp, const struct tgsi_full_inst static boolean emit_MOV( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); /* potentially nothing to do */ @@ -1476,7 +1492,7 @@ static boolean emit_MUL( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); sse_mulps(cp->func, dst, arg1); @@ -1494,7 +1510,7 @@ static boolean emit_MAD( struct aos_compilation *cp, const struct tgsi_full_inst /* If we can't clobber old contents of arg0, get a temporary & copy * it there, then clobber it... */ - arg0 = get_xmm_clone(cp, arg0); + arg0 = get_xmm_writable(cp, arg0); sse_mulps(cp->func, arg0, arg1); sse_addps(cp->func, arg0, arg2); @@ -1562,7 +1578,7 @@ static boolean emit_SGE( struct aos_compilation *cp, const struct tgsi_full_inst struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); struct x86_reg ones = aos_get_internal(cp, IMM_ONES); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); sse_cmpps(cp->func, dst, arg1, cc_NotLessThan); sse_andps(cp->func, dst, ones); @@ -1586,7 +1602,7 @@ static boolean emit_SLT( struct aos_compilation *cp, const struct tgsi_full_inst struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); struct x86_reg ones = aos_get_internal(cp, IMM_ONES); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); sse_cmpps(cp->func, dst, arg1, cc_LessThan); sse_andps(cp->func, dst, ones); @@ -1599,7 +1615,7 @@ static boolean emit_SUB( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = get_xmm_clone(cp, arg0); + struct x86_reg dst = get_xmm_writable(cp, arg0); sse_subps(cp->func, dst, arg1); @@ -1989,7 +2005,6 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, /* decr count, loop if not zero */ x86_dec(cp.func, cp.count_ESI); -/* x86_test(cp.func, cp.count_ESI, cp.count_ESI); */ x86_jcc(cp.func, cc_NZ, label); restore_fpu_state(&cp); -- cgit v1.2.3 From ce331e3a5e2a0505e01637861bdd7f5e6cfbd041 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 25 May 2008 15:44:17 +0100 Subject: draw: special case for writing out scalar results --- src/gallium/auxiliary/draw/draw_vs_aos.c | 127 +++++++++++++++++++++++++------ 1 file changed, 102 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 17b9442d6b..aebc230858 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -697,6 +697,72 @@ static void store_dest( struct aos_compilation *cp, } +static void inject_scalar( struct aos_compilation *cp, + struct x86_reg dst, + struct x86_reg result, + unsigned swizzle ) +{ + sse_shufps(cp->func, dst, dst, swizzle); + sse_movss(cp->func, dst, result); + sse_shufps(cp->func, dst, dst, swizzle); +} + + +static void store_scalar_dest( struct aos_compilation *cp, + const struct tgsi_full_dst_register *reg, + struct x86_reg result ) +{ + unsigned writemask = reg->DstRegister.WriteMask; + struct x86_reg dst; + + if (writemask != TGSI_WRITEMASK_X && + writemask != TGSI_WRITEMASK_Y && + writemask != TGSI_WRITEMASK_Z && + writemask != TGSI_WRITEMASK_W && + writemask != 0) + { + result = get_xmm_writable(cp, result); /* already true, right? */ + sse_shufps(cp->func, result, result, SHUF(X,X,X,X)); + store_dest(cp, reg, result); + return; + } + + result = get_xmm(cp, result); + dst = aos_get_shader_reg_xmm(cp, + reg->DstRegister.File, + reg->DstRegister.Index); + + + + switch (reg->DstRegister.WriteMask) { + case TGSI_WRITEMASK_X: + sse_movss(cp->func, dst, result); + break; + + case TGSI_WRITEMASK_Y: + inject_scalar(cp, dst, result, SHUF(Y, X, Z, W)); + break; + + case TGSI_WRITEMASK_Z: + inject_scalar(cp, dst, result, SHUF(Z, Y, X, W)); + break; + + case TGSI_WRITEMASK_W: + inject_scalar(cp, dst, result, SHUF(W, Y, Z, X)); + break; + + default: + break; + } + + aos_adopt_xmm_reg(cp, + dst, + reg->DstRegister.File, + reg->DstRegister.Index, + TRUE); +} + + static void x87_fst_or_nop( struct x86_function *func, unsigned writemask, @@ -909,11 +975,8 @@ static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_inst emit_pshufd(cp, tmp, dst, SHUF(Y,X,W,Z)); sse_addss(cp->func, dst, tmp); - if (op->FullDstRegisters[0].DstRegister.WriteMask != 0x1) - sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); - aos_release_xmm_reg(cp, tmp.idx); - store_dest(cp, &op->FullDstRegisters[0], dst); + store_scalar_dest(cp, &op->FullDstRegisters[0], dst); return TRUE; } @@ -935,11 +998,8 @@ static boolean emit_DP4( struct aos_compilation *cp, const struct tgsi_full_inst emit_pshufd(cp, tmp, dst, SHUF(Y,X,W,Z)); sse_addss(cp->func, dst, tmp); - if (op->FullDstRegisters[0].DstRegister.WriteMask != 0x1) - sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); - aos_release_xmm_reg(cp, tmp.idx); - store_dest(cp, &op->FullDstRegisters[0], dst); + store_scalar_dest(cp, &op->FullDstRegisters[0], dst); return TRUE; } @@ -961,11 +1021,8 @@ static boolean emit_DPH( struct aos_compilation *cp, const struct tgsi_full_inst emit_pshufd(cp, tmp, arg1, SHUF(W,W,W,W)); sse_addss(cp->func, dst, tmp); - if (op->FullDstRegisters[0].DstRegister.WriteMask != 0x1) - sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); - aos_release_xmm_reg(cp, tmp.idx); - store_dest(cp, &op->FullDstRegisters[0], dst); + store_scalar_dest(cp, &op->FullDstRegisters[0], dst); return TRUE; } @@ -1518,7 +1575,9 @@ static boolean emit_MAD( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } - +/* Really not sufficient -- need to check for conditions that could + * generate inf/nan values, which will slow things down hugely. + */ static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { x87_fld_src(cp, &op->FullSrcRegisters[1], 0); /* a1.x */ @@ -1548,27 +1607,45 @@ static boolean emit_RCP( struct aos_compilation *cp, const struct tgsi_full_inst sse_divss(cp->func, dst, arg0); } - if (op->FullDstRegisters[0].DstRegister.WriteMask != 0x1) - sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); - - store_dest(cp, &op->FullDstRegisters[0], dst); + store_scalar_dest(cp, &op->FullDstRegisters[0], dst); return TRUE; } + +/* Although rsqrtps() and rcpps() are low precision on some/all SSE + * implementations, it is possible to improve its precision at + * fairly low cost, using a newton/raphson step, as below: + * + * x1 = 2 * rcpps(a) - a * rcpps(a) * rcpps(a) + * x1 = 0.5 * rsqrtps(a) * [3.0 - (a * rsqrtps(a))* rsqrtps(a)] + * + * See: http://softwarecommunity.intel.com/articles/eng/1818.htm + */ static boolean emit_RSQ( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg dst = aos_get_xmm_reg(cp); - sse_rsqrtss(cp->func, dst, arg0); - - /* Extend precision here... - */ - - if (op->FullDstRegisters[0].DstRegister.WriteMask != 0x1) - sse_shufps(cp->func, dst, dst, SHUF(X, X, X, X)); + if (1) { + sse_rsqrtss(cp->func, dst, arg0); + } + else { +#if 0 + /* Extend precision here... + */ + sse_movaps( func, dst, get_temp( TGSI_EXEC_TEMP_HALF_I, TGSI_EXEC_TEMP_HALF_C ) ); + sse_movaps( func, tmp0, get_temp( TGSI_EXEC_TEMP_THREE_I, TGSI_EXEC_TEMP_THREE_C ) ); + + sse_rsqrtss( func, tmp1, src ); /* rsqrtss(a) */ + sse_mulss( func, src, tmp1 ); /* a * rsqrtss(a) */ + sse_mulss( func, dst, tmp1 ); /* .5 * rsqrtss(a) */ + sse_mulss( func, src, tmp1 ); /* a * rsqrtss(a) * rsqrtss(a) */ + sse_subss( func, tmp0, src ); /* 3.0 - (a * rsqrtss(a) * rsqrtss(a)) */ + sse_mulss( func, dst, tmp0 ); /* .5 * r * (3.0 - (a * r * r)) */ +#endif + } - store_dest(cp, &op->FullDstRegisters[0], dst); + store_scalar_dest(cp, &op->FullDstRegisters[0], dst); return TRUE; } -- cgit v1.2.3 From 3afb7198e01516dba38bb3248d4c0161e54650fe Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 25 May 2008 15:45:27 +0100 Subject: draw: remove EXP & LOG from vs_aos.c These don't get hit & look like bug magnets to me... --- src/gallium/auxiliary/draw/draw_vs_aos.c | 85 ++------------------------------ 1 file changed, 4 insertions(+), 81 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index aebc230858..34dc09ead7 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1066,85 +1066,6 @@ static boolean emit_EX2( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } -static boolean emit_EXP( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) -{ - struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); - struct x86_reg st0 = x86_make_reg(file_x87, 0); - struct x86_reg st1 = x86_make_reg(file_x87, 1); - struct x86_reg st3 = x86_make_reg(file_x87, 3); - unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask; - - /* CAUTION: dst may alias arg0! - */ - x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* arg0.x */ - x87_fld(cp->func, st0); /* arg arg */ - - /* by default, fpu is setup to round-to-nearest. We want to - * change this now, and track the state through to the end of the - * generated function so that it isn't repeated unnecessarily. - * Alternately, could subtract .5 to get round to -inf behaviour. - */ - set_fpu_round_neg_inf( cp ); - x87_fprndint( cp->func ); /* flr(a) a */ - x87_fld(cp->func, st0); /* flr(a) flr(a) a */ - x87_fld1(cp->func); /* 1 floor(a) floor(a) a */ - x87_fst_or_nop(cp->func, writemask, 3, dst); /* stack unchanged */ - - x87_fscale(cp->func); /* 2^floor(a) floor(a) a */ - x87_fst(cp->func, st3); /* 2^floor(a) floor(a) a 2^floor(a)*/ - - x87_fstp_or_pop(cp->func, writemask, 0, dst); /* flr(a) a 2^flr(a) */ - - x87_fsubp(cp->func, st1); /* frac(a) 2^flr(a) */ - - x87_fst_or_nop(cp->func, writemask, 1, dst); /* frac(a) 2^flr(a) */ - - x87_f2xm1(cp->func); /* (2^frac(a))-1 2^flr(a)*/ - x87_fld1(cp->func); /* 1 (2^frac(a))-1 2^flr(a)*/ - x87_faddp(cp->func, st1); /* 2^frac(a) 2^flr(a) */ - x87_fmulp(cp->func, st1); /* 2^a */ - - x87_fstp_or_pop(cp->func, writemask, 2, dst); - -/* dst[0] = 2^floor(tmp); */ -/* dst[1] = frac(tmp); */ -/* dst[2] = 2^floor(tmp) * 2^frac(tmp); */ -/* dst[3] = 1.0F; */ - return TRUE; -} - -static boolean emit_LOG( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) -{ - struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); - struct x86_reg st0 = x86_make_reg(file_x87, 0); - struct x86_reg st1 = x86_make_reg(file_x87, 1); - struct x86_reg st2 = x86_make_reg(file_x87, 2); - unsigned writemask = op->FullDstRegisters[0].DstRegister.WriteMask; - - /* CAUTION: dst may alias arg0! - */ - x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* arg0.x */ - x87_fabs(cp->func); /* |arg0.x| */ - x87_fxtract(cp->func); /* mantissa(arg0.x), exponent(arg0.x) */ - x87_fst(cp->func, st2); /* mantissa, exponent, mantissa */ - x87_fld1(cp->func); /* 1, mantissa, exponent, mantissa */ - x87_fyl2x(cp->func); /* log2(mantissa), exponent, mantissa */ - x87_fadd(cp->func, st0, st1); /* e+l2(m), e, m */ - - x87_fstp_or_pop(cp->func, writemask, 2, dst); /* e, m */ - - x87_fld1(cp->func); /* 1, e, m */ - x87_fsub(cp->func, st1, st0); /* 1, e-1, m */ - - x87_fstp_or_pop(cp->func, writemask, 3, dst); /* e-1,m */ - x87_fstp_or_pop(cp->func, writemask, 0, dst); /* m */ - - x87_fadd(cp->func, st0, st0); /* 2m */ - - x87_fstp_or_pop( cp->func, writemask, 1, dst ); - - return TRUE; -} static boolean emit_FLR( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { @@ -1755,10 +1676,12 @@ emit_instruction( struct aos_compilation *cp, return emit_RSQ(cp, inst); case TGSI_OPCODE_EXP: - return emit_EXP(cp, inst); + /*return emit_EXP(cp, inst);*/ + return FALSE; case TGSI_OPCODE_LOG: - return emit_LOG(cp, inst); + /*return emit_LOG(cp, inst);*/ + return FALSE; case TGSI_OPCODE_MUL: return emit_MUL(cp, inst); -- cgit v1.2.3 From 9c7568965c00dcc2e9403a2f94f1cd09dcd783ae Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 25 May 2008 15:47:04 +0100 Subject: draw: slight tweak for XPD opcode --- src/gallium/auxiliary/draw/draw_vs_aos.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 34dc09ead7..37d04e45a6 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1626,31 +1626,24 @@ static boolean emit_XPD( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg arg1 = fetch_src(cp, &op->FullSrcRegisters[1]); - struct x86_reg dst = aos_get_xmm_reg(cp); struct x86_reg tmp0 = aos_get_xmm_reg(cp); struct x86_reg tmp1 = aos_get_xmm_reg(cp); - /* Could avoid tmp0, tmp1 if we overwrote arg0, arg1. Need a way - * to invalidate registers. This will come with better analysis - * (liveness analysis) of the incoming program. - */ - emit_pshufd(cp, dst, arg0, SHUF(Y, Z, X, W)); - emit_pshufd(cp, tmp1, arg1, SHUF(Z, X, Y, W)); - sse_mulps(cp->func, dst, tmp1); - emit_pshufd(cp, tmp0, arg0, SHUF(Z, X, Y, W)); emit_pshufd(cp, tmp1, arg1, SHUF(Y, Z, X, W)); - sse_mulps(cp->func, tmp0, tmp1); - sse_subps(cp->func, dst, tmp0); + sse_mulps(cp->func, tmp1, arg0); + emit_pshufd(cp, tmp0, arg0, SHUF(Y, Z, X, W)); + sse_mulps(cp->func, tmp0, arg1); + sse_subps(cp->func, tmp1, tmp0); + sse_shufps(cp->func, tmp1, tmp1, SHUF(Y, Z, X, W)); +/* dst[2] = arg0[0] * arg1[1] - arg0[1] * arg1[0]; */ /* dst[0] = arg0[1] * arg1[2] - arg0[2] * arg1[1]; */ /* dst[1] = arg0[2] * arg1[0] - arg0[0] * arg1[2]; */ -/* dst[2] = arg0[0] * arg1[1] - arg0[1] * arg1[0]; */ /* dst[3] is undef */ aos_release_xmm_reg(cp, tmp0.idx); - aos_release_xmm_reg(cp, tmp1.idx); - store_dest(cp, &op->FullDstRegisters[0], dst); + store_dest(cp, &op->FullDstRegisters[0], tmp1); return TRUE; } -- cgit v1.2.3 From 359058e7b77ddbac5eec7e8d1c77232bcbb1adbf Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 25 May 2008 15:28:30 +0100 Subject: cso: use memcpy rather than structure asignment for copying Apparently gcc will omit to copy hidden padding bytes under some circumstances, which means later on memcmp() will indicate a difference between structs even though all the visible members are identical. --- src/gallium/auxiliary/cso_cache/cso_context.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index dc5987df44..af4af8ac1d 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -292,7 +292,7 @@ enum pipe_error cso_set_blend(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state; cso->context = ctx->pipe; @@ -350,7 +350,7 @@ enum pipe_error cso_single_sampler(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state; cso->context = ctx->pipe; @@ -508,7 +508,7 @@ enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state; cso->context = ctx->pipe; @@ -564,7 +564,7 @@ enum pipe_error cso_set_rasterizer(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_rasterizer_state; cso->context = ctx->pipe; @@ -726,7 +726,7 @@ enum pipe_error cso_set_vertex_shader(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_vs_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_vs_state; cso->context = ctx->pipe; -- cgit v1.2.3 From 721fb5597e687fc1446119002ab03cc428104b29 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 26 May 2008 00:09:02 +0100 Subject: draw: more aos tweaks --- src/gallium/auxiliary/draw/draw_vs_aos.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 37d04e45a6..916203c66b 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -202,6 +202,7 @@ static struct x86_reg get_xmm_writable( struct aos_compilation *cp, reg = tmp; } + cp->xmm[reg.idx].last_used = cp->insn_counter; return reg; } @@ -215,6 +216,7 @@ static struct x86_reg get_xmm( struct aos_compilation *cp, reg = tmp; } + cp->xmm[reg.idx].last_used = cp->insn_counter; return reg; } @@ -281,6 +283,18 @@ void aos_adopt_xmm_reg( struct aos_compilation *cp, return; } + /* If this xmm reg is already holding this shader reg, just update + * last_used, and don't clobber the dirty flag... + */ + if (cp->xmm[reg.idx].file == file && + cp->xmm[reg.idx].idx == idx) + { + cp->xmm[reg.idx].dirty |= dirty; + cp->xmm[reg.idx].last_used = cp->insn_counter; + return; + } + + /* If any xmm reg thinks it holds this shader reg, break the * illusion. */ @@ -382,8 +396,16 @@ static struct x86_reg aos_get_shader_reg_xmm( struct aos_compilation *cp, unsigned file, unsigned idx ) { - struct x86_reg reg = aos_get_shader_reg( cp, file, idx ); - return get_xmm( cp, reg ); + struct x86_reg reg = get_xmm( cp, + aos_get_shader_reg( cp, file, idx ) ); + + aos_adopt_xmm_reg( cp, + reg, + file, + idx, + FALSE ); + + return reg; } -- cgit v1.2.3 From 351eca365c0ba488000c3826d5093de6170381e4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 26 May 2008 11:03:00 +0100 Subject: draw: extend precision in RSQ opcode --- src/gallium/auxiliary/draw/draw_vs_aos.c | 48 ++++++++++++++++++-------------- src/gallium/auxiliary/draw/draw_vs_aos.h | 1 + 2 files changed, 28 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 916203c66b..1622358ae1 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -140,7 +140,8 @@ static void init_internals( struct aos_machine *machine ) ASSIGN_4V(machine->internal[IMM_NEGS], -1.0f, -1.0f, -1.0f, -1.0f); ASSIGN_4V(machine->internal[IMM_IDENTITY], 0.0f, 0.0f, 0.0f, 1.0f); ASSIGN_4V(machine->internal[IMM_INV_255], inv, inv, inv, inv); - ASSIGN_4V(machine->internal[IMM_255], f255, f255, f255, f255); + ASSIGN_4V(machine->internal[IMM_255], f255, f255, f255, f255); + ASSIGN_4V(machine->internal[IMM_RSQ], -.5f, 1.5f, 0.0f, 0.0f); machine->fpu_rnd_nearest = (X87_CW_EXCEPTION_INV_OP | @@ -1561,35 +1562,40 @@ static boolean emit_RCP( struct aos_compilation *cp, const struct tgsi_full_inst * * x1 = 2 * rcpps(a) - a * rcpps(a) * rcpps(a) * x1 = 0.5 * rsqrtps(a) * [3.0 - (a * rsqrtps(a))* rsqrtps(a)] + * or: + * x1 = rsqrtps(a) * [1.5 - .5 * a * rsqrtps(a) * rsqrtps(a)] + * * * See: http://softwarecommunity.intel.com/articles/eng/1818.htm */ static boolean emit_RSQ( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { - struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); - struct x86_reg dst = aos_get_xmm_reg(cp); - if (1) { - sse_rsqrtss(cp->func, dst, arg0); + if (0) { + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg r = aos_get_xmm_reg(cp); + sse_rsqrtss(cp->func, r, arg0); + store_scalar_dest(cp, &op->FullDstRegisters[0], r); + return TRUE; } else { -#if 0 - /* Extend precision here... - */ - sse_movaps( func, dst, get_temp( TGSI_EXEC_TEMP_HALF_I, TGSI_EXEC_TEMP_HALF_C ) ); - sse_movaps( func, tmp0, get_temp( TGSI_EXEC_TEMP_THREE_I, TGSI_EXEC_TEMP_THREE_C ) ); - - sse_rsqrtss( func, tmp1, src ); /* rsqrtss(a) */ - sse_mulss( func, src, tmp1 ); /* a * rsqrtss(a) */ - sse_mulss( func, dst, tmp1 ); /* .5 * rsqrtss(a) */ - sse_mulss( func, src, tmp1 ); /* a * rsqrtss(a) * rsqrtss(a) */ - sse_subss( func, tmp0, src ); /* 3.0 - (a * rsqrtss(a) * rsqrtss(a)) */ - sse_mulss( func, dst, tmp0 ); /* .5 * r * (3.0 - (a * r * r)) */ -#endif - } + struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); + struct x86_reg r = aos_get_xmm_reg(cp); - store_scalar_dest(cp, &op->FullDstRegisters[0], dst); - return TRUE; + struct x86_reg neg_half = get_reg_ptr( cp, AOS_FILE_INTERNAL, IMM_RSQ ); + struct x86_reg one_point_five = x86_make_disp( neg_half, 4 ); + struct x86_reg src = get_xmm_writable( cp, arg0 ); + + sse_rsqrtss( cp->func, r, src ); /* rsqrtss(a) */ + sse_mulss( cp->func, src, neg_half ); /* -.5 * a */ + sse_mulss( cp->func, src, r ); /* -.5 * a * r */ + sse_mulss( cp->func, src, r ); /* -.5 * a * r * r */ + sse_addss( cp->func, src, one_point_five ); /* 1.5 - .5 * a * r * r */ + sse_mulss( cp->func, r, src ); /* r * (1.5 - .5 * a * r * r) */ + + store_scalar_dest(cp, &op->FullDstRegisters[0], r); + return TRUE; + } } diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index c08c73d4bc..fffe2e4658 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -175,6 +175,7 @@ boolean aos_emit_outputs( struct aos_compilation *cp ); #define IMM_INV_255 3 /* 1/255, 1/255, 1/255, 1/255 */ #define IMM_255 4 /* 255, 255, 255, 255 */ #define IMM_NEGS 5 /* -1,-1,-1,-1 */ +#define IMM_RSQ 6 /* -.5,1.5,_,_ */ struct x86_reg aos_get_internal( struct aos_compilation *cp, unsigned imm ); -- cgit v1.2.3 From e0fd3449f824ed8eaec49e83a0f90b7fe47e09a6 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sun, 25 May 2008 17:26:07 +0200 Subject: i915: Fix for tex-surface merge --- src/gallium/drivers/i915simple/i915_texture.c | 29 +++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 3e23e540f9..b08385e7db 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -132,11 +132,11 @@ i915_displaytarget_layout(struct pipe_screen *screen, /* Now extract the goodies: */ - i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); - i915_miptree_set_level_info( tex, 0, 0, 0, 0, + i915_miptree_set_level_info( tex, 0, 1, 0, 0, tex->base.width[0], tex->base.height[0], 1 ); + i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); tex->buffer = surf.buffer; tex->pitch = surf.pitch; @@ -633,6 +633,7 @@ i915_get_tex_surface_screen(struct pipe_screen *screen, if (ps) { assert(ps->refcount); assert(ps->winsys); + pipe_texture_reference(&ps->texture, pt); pipe_buffer_reference(ws, &ps->buffer, tex->buffer); ps->format = pt->format; ps->cpp = pt->cpp; @@ -652,6 +653,29 @@ i915_init_texture_functions(struct i915_context *i915) // i915->pipe.texture_update = i915_texture_update; } +static void +i915_tex_surface_release_screen(struct pipe_screen *screen, + struct pipe_surface **surface) +{ + struct pipe_surface *surf = *surface; + + if (--surf->refcount == 0) { + + /* This really should not be possible, but it's actually + * happening quite a bit... Will fix. + */ + if (surf->status == PIPE_SURFACE_STATUS_CLEAR) { + debug_printf("XXX destroying a surface with pending clears...\n"); + assert(0); + } + + pipe_texture_reference(&surf->texture, NULL); + pipe_buffer_reference(screen->winsys, &surf->buffer, NULL); + FREE(surf); + } + + *surface = NULL; +} void i915_init_screen_texture_functions(struct pipe_screen *screen) @@ -659,4 +683,5 @@ i915_init_screen_texture_functions(struct pipe_screen *screen) screen->texture_create = i915_texture_create_screen; screen->texture_release = i915_texture_release_screen; screen->get_tex_surface = i915_get_tex_surface_screen; + screen->tex_surface_release = i915_tex_surface_release_screen; } -- cgit v1.2.3 From 791eee64e03c7323c8a8907f54b09a015c046e2f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 26 May 2008 11:20:51 +0200 Subject: i915: Removed screen sufixes on texture functions --- src/gallium/drivers/i915simple/i915_texture.c | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index b08385e7db..df11ba0544 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -525,8 +525,8 @@ i945_miptree_layout(struct i915_texture * tex) static struct pipe_texture * -i915_texture_create_screen(struct pipe_screen *screen, - const struct pipe_texture *templat) +i915_texture_create(struct pipe_screen *screen, + const struct pipe_texture *templat) { struct i915_screen *i915screen = i915_screen(screen); struct pipe_winsys *ws = screen->winsys; @@ -571,8 +571,8 @@ i915_texture_create_screen(struct pipe_screen *screen, static void -i915_texture_release_screen(struct pipe_screen *screen, - struct pipe_texture **pt) +i915_texture_release(struct pipe_screen *screen, + struct pipe_texture **pt) { if (!*pt) return; @@ -606,10 +606,10 @@ i915_texture_release_screen(struct pipe_screen *screen, * XXX note: same as code in sp_surface.c */ static struct pipe_surface * -i915_get_tex_surface_screen(struct pipe_screen *screen, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - unsigned flags) +i915_get_tex_surface(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags) { struct i915_texture *tex = (struct i915_texture *)pt; struct pipe_winsys *ws = screen->winsys; @@ -654,8 +654,8 @@ i915_init_texture_functions(struct i915_context *i915) } static void -i915_tex_surface_release_screen(struct pipe_screen *screen, - struct pipe_surface **surface) +i915_tex_surface_release(struct pipe_screen *screen, + struct pipe_surface **surface) { struct pipe_surface *surf = *surface; @@ -680,8 +680,8 @@ i915_tex_surface_release_screen(struct pipe_screen *screen, void i915_init_screen_texture_functions(struct pipe_screen *screen) { - screen->texture_create = i915_texture_create_screen; - screen->texture_release = i915_texture_release_screen; - screen->get_tex_surface = i915_get_tex_surface_screen; - screen->tex_surface_release = i915_tex_surface_release_screen; + screen->texture_create = i915_texture_create; + screen->texture_release = i915_texture_release; + screen->get_tex_surface = i915_get_tex_surface; + screen->tex_surface_release = i915_tex_surface_release; } -- cgit v1.2.3 From 77ce568ff704e6cdcfaa557965c894752d19e462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 26 May 2008 20:14:40 +0900 Subject: Remove CVS keywords. --- src/gallium/winsys/dri/intel/server/i830_common.h | 1 - src/gallium/winsys/dri/intel/server/i830_dri.h | 1 - 2 files changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h index f1fd3939ab..f84f453309 100644 --- a/src/gallium/winsys/dri/intel/server/i830_common.h +++ b/src/gallium/winsys/dri/intel/server/i830_common.h @@ -26,7 +26,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ #ifndef _I830_COMMON_H_ #define _I830_COMMON_H_ diff --git a/src/gallium/winsys/dri/intel/server/i830_dri.h b/src/gallium/winsys/dri/intel/server/i830_dri.h index c2a3af8cbf..685de4a551 100644 --- a/src/gallium/winsys/dri/intel/server/i830_dri.h +++ b/src/gallium/winsys/dri/intel/server/i830_dri.h @@ -1,4 +1,3 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ #ifndef _I830_DRI_H #define _I830_DRI_H -- cgit v1.2.3 From fc72d7e032fc0a4130fae53106f03aa3fbe4e99e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 26 May 2008 20:39:26 +0900 Subject: Remove CVS keywords. --- src/gallium/winsys/dri/intel/server/i830_common.h | 1 - src/gallium/winsys/dri/intel/server/i830_dri.h | 1 - 2 files changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h index d4d58886ce..50bb751709 100644 --- a/src/gallium/winsys/dri/intel/server/i830_common.h +++ b/src/gallium/winsys/dri/intel/server/i830_common.h @@ -26,7 +26,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ #ifndef _I830_COMMON_H_ #define _I830_COMMON_H_ diff --git a/src/gallium/winsys/dri/intel/server/i830_dri.h b/src/gallium/winsys/dri/intel/server/i830_dri.h index c2a3af8cbf..685de4a551 100644 --- a/src/gallium/winsys/dri/intel/server/i830_dri.h +++ b/src/gallium/winsys/dri/intel/server/i830_dri.h @@ -1,4 +1,3 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ #ifndef _I830_DRI_H #define _I830_DRI_H -- cgit v1.2.3 From 253066d716e3039522eeb7b072811cccd89b4a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 26 May 2008 23:29:38 +0900 Subject: Revert DOS line endings. --- src/gallium/drivers/i915simple/i915_context.h | 682 ++++++------ src/gallium/drivers/i965simple/brw_context.h | 1368 ++++++++++++------------- src/gallium/drivers/i965simple/brw_state.c | 938 ++++++++--------- 3 files changed, 1494 insertions(+), 1494 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 38e6a34884..53fc5ed079 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -1,341 +1,341 @@ - /************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef I915_CONTEXT_H -#define I915_CONTEXT_H - - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "draw/draw_vertex.h" - -#include "tgsi/util/tgsi_scan.h" - - -#define I915_TEX_UNITS 8 - -#define I915_DYNAMIC_MODES4 0 -#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */ -#define I915_DYNAMIC_DEPTHSCALE_1 2 -#define I915_DYNAMIC_IAB 3 -#define I915_DYNAMIC_BC_0 4 /* just the header */ -#define I915_DYNAMIC_BC_1 5 -#define I915_DYNAMIC_BFO_0 6 -#define I915_DYNAMIC_BFO_1 7 -#define I915_DYNAMIC_STP_0 8 -#define I915_DYNAMIC_STP_1 9 -#define I915_DYNAMIC_SC_ENA_0 10 -#define I915_DYNAMIC_SC_RECT_0 11 -#define I915_DYNAMIC_SC_RECT_1 12 -#define I915_DYNAMIC_SC_RECT_2 13 -#define I915_MAX_DYNAMIC 14 - - -#define I915_IMMEDIATE_S0 0 -#define I915_IMMEDIATE_S1 1 -#define I915_IMMEDIATE_S2 2 -#define I915_IMMEDIATE_S3 3 -#define I915_IMMEDIATE_S4 4 -#define I915_IMMEDIATE_S5 5 -#define I915_IMMEDIATE_S6 6 -#define I915_IMMEDIATE_S7 7 -#define I915_MAX_IMMEDIATE 8 - -/* These must mach the order of LI0_STATE_* bits, as they will be used - * to generate hardware packets: - */ -#define I915_CACHE_STATIC 0 -#define I915_CACHE_DYNAMIC 1 /* handled specially */ -#define I915_CACHE_SAMPLER 2 -#define I915_CACHE_MAP 3 -#define I915_CACHE_PROGRAM 4 -#define I915_CACHE_CONSTANTS 5 -#define I915_MAX_CACHE 6 - -#define I915_MAX_CONSTANT 32 - - -/** See constant_flags[] below */ -#define I915_CONSTFLAG_USER 0x1f - - -/** - * Subclass of pipe_shader_state - */ -struct i915_fragment_shader -{ - struct pipe_shader_state state; - - struct tgsi_shader_info info; - - uint *program; - uint program_len; - - /** - * constants introduced during translation. - * These are placed at the end of the constant buffer and grow toward - * the beginning (eg: slot 31, 30 29, ...) - * User-provided constants start at 0. - * This allows both types of constants to co-exist (until there's too many) - * and doesn't require regenerating/changing the fragment program to - * shuffle constants around. - */ - uint num_constants; - float constants[I915_MAX_CONSTANT][4]; - - /** - * Status of each constant - * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding - * slot of the user's constant buffer. (set by pipe->set_constant_buffer()) - * Else, the bitmask indicates which components are occupied by immediates. - */ - ubyte constant_flags[I915_MAX_CONSTANT]; -}; - - -struct i915_cache_context; - -/* Use to calculate differences between state emitted to hardware and - * current driver-calculated state. - */ -struct i915_state -{ - unsigned immediate[I915_MAX_IMMEDIATE]; - unsigned dynamic[I915_MAX_DYNAMIC]; - - float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4]; - /** number of constants passed in through a constant buffer */ - uint num_user_constants[PIPE_SHADER_TYPES]; - - /* texture sampler state */ - unsigned sampler[I915_TEX_UNITS][3]; - unsigned sampler_enable_flags; - unsigned sampler_enable_nr; - - /* texture image buffers */ - unsigned texbuffer[I915_TEX_UNITS][2]; - - /** Describes the current hardware vertex layout */ - struct vertex_info vertex_info; - - unsigned id; /* track lost context events */ -}; - -struct i915_blend_state { - unsigned iab; - unsigned modes4; - unsigned LIS5; - unsigned LIS6; -}; - -struct i915_depth_stencil_state { - unsigned stencil_modes4; - unsigned bfo[2]; - unsigned stencil_LIS5; - unsigned depth_LIS6; -}; - -struct i915_rasterizer_state { - int light_twoside : 1; - unsigned st; - enum interp_mode color_interp; - - unsigned LIS4; - unsigned LIS7; - unsigned sc[1]; - - const struct pipe_rasterizer_state *templ; - - union { float f; unsigned u; } ds[2]; -}; - -struct i915_sampler_state { - unsigned state[3]; - const struct pipe_sampler_state *templ; -}; - - -struct i915_texture { - struct pipe_texture base; - - /* Derived from the above: - */ - unsigned pitch; - unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; - - unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; - - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats - * are going to be so diverse that there is no unified way to - * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - */ - unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ - - /* Includes image offset tables: - */ - unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; - - /* The data is held here: - */ - struct pipe_buffer *buffer; -}; - -struct i915_context -{ - struct pipe_context pipe; - struct i915_winsys *winsys; - struct draw_context *draw; - - /* The most recent drawing state as set by the driver: - */ - const struct i915_blend_state *blend; - const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; - const struct i915_depth_stencil_state *depth_stencil; - const struct i915_rasterizer_state *rasterizer; - - struct i915_fragment_shader *fs; - - struct pipe_blend_color blend_color; - struct pipe_clip_state clip; - struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; - struct pipe_framebuffer_state framebuffer; - struct pipe_poly_stipple poly_stipple; - struct pipe_scissor_state scissor; - struct i915_texture *texture[PIPE_MAX_SAMPLERS]; - struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - - unsigned dirty; - - unsigned num_samplers; - unsigned num_textures; - unsigned num_vertex_elements; - unsigned num_vertex_buffers; - - unsigned *batch_start; - - /** Vertex buffer */ - struct pipe_buffer *vbo; - - struct i915_state current; - unsigned hardware_dirty; - - unsigned debug; -}; - -/* A flag for each state_tracker state object: - */ -#define I915_NEW_VIEWPORT 0x1 -#define I915_NEW_RASTERIZER 0x2 -#define I915_NEW_FS 0x4 -#define I915_NEW_BLEND 0x8 -#define I915_NEW_CLIP 0x10 -#define I915_NEW_SCISSOR 0x20 -#define I915_NEW_STIPPLE 0x40 -#define I915_NEW_FRAMEBUFFER 0x80 -#define I915_NEW_ALPHA_TEST 0x100 -#define I915_NEW_DEPTH_STENCIL 0x200 -#define I915_NEW_SAMPLER 0x400 -#define I915_NEW_TEXTURE 0x800 -#define I915_NEW_CONSTANTS 0x1000 -#define I915_NEW_VBO 0x2000 -#define I915_NEW_VS 0x4000 - - -/* Driver's internally generated state flags: - */ -#define I915_NEW_VERTEX_FORMAT 0x10000 - - -/* Dirty flags for hardware emit - */ -#define I915_HW_STATIC (1<set_constant_buffer()) + * Else, the bitmask indicates which components are occupied by immediates. + */ + ubyte constant_flags[I915_MAX_CONSTANT]; +}; + + +struct i915_cache_context; + +/* Use to calculate differences between state emitted to hardware and + * current driver-calculated state. + */ +struct i915_state +{ + unsigned immediate[I915_MAX_IMMEDIATE]; + unsigned dynamic[I915_MAX_DYNAMIC]; + + float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4]; + /** number of constants passed in through a constant buffer */ + uint num_user_constants[PIPE_SHADER_TYPES]; + + /* texture sampler state */ + unsigned sampler[I915_TEX_UNITS][3]; + unsigned sampler_enable_flags; + unsigned sampler_enable_nr; + + /* texture image buffers */ + unsigned texbuffer[I915_TEX_UNITS][2]; + + /** Describes the current hardware vertex layout */ + struct vertex_info vertex_info; + + unsigned id; /* track lost context events */ +}; + +struct i915_blend_state { + unsigned iab; + unsigned modes4; + unsigned LIS5; + unsigned LIS6; +}; + +struct i915_depth_stencil_state { + unsigned stencil_modes4; + unsigned bfo[2]; + unsigned stencil_LIS5; + unsigned depth_LIS6; +}; + +struct i915_rasterizer_state { + int light_twoside : 1; + unsigned st; + enum interp_mode color_interp; + + unsigned LIS4; + unsigned LIS7; + unsigned sc[1]; + + const struct pipe_rasterizer_state *templ; + + union { float f; unsigned u; } ds[2]; +}; + +struct i915_sampler_state { + unsigned state[3]; + const struct pipe_sampler_state *templ; +}; + + +struct i915_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +struct i915_context +{ + struct pipe_context pipe; + struct i915_winsys *winsys; + struct draw_context *draw; + + /* The most recent drawing state as set by the driver: + */ + const struct i915_blend_state *blend; + const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct i915_depth_stencil_state *depth_stencil; + const struct i915_rasterizer_state *rasterizer; + + struct i915_fragment_shader *fs; + + struct pipe_blend_color blend_color; + struct pipe_clip_state clip; + struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; + struct pipe_framebuffer_state framebuffer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct i915_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + + unsigned dirty; + + unsigned num_samplers; + unsigned num_textures; + unsigned num_vertex_elements; + unsigned num_vertex_buffers; + + unsigned *batch_start; + + /** Vertex buffer */ + struct pipe_buffer *vbo; + + struct i915_state current; + unsigned hardware_dirty; + + unsigned debug; +}; + +/* A flag for each state_tracker state object: + */ +#define I915_NEW_VIEWPORT 0x1 +#define I915_NEW_RASTERIZER 0x2 +#define I915_NEW_FS 0x4 +#define I915_NEW_BLEND 0x8 +#define I915_NEW_CLIP 0x10 +#define I915_NEW_SCISSOR 0x20 +#define I915_NEW_STIPPLE 0x40 +#define I915_NEW_FRAMEBUFFER 0x80 +#define I915_NEW_ALPHA_TEST 0x100 +#define I915_NEW_DEPTH_STENCIL 0x200 +#define I915_NEW_SAMPLER 0x400 +#define I915_NEW_TEXTURE 0x800 +#define I915_NEW_CONSTANTS 0x1000 +#define I915_NEW_VBO 0x2000 +#define I915_NEW_VS 0x4000 + + +/* Driver's internally generated state flags: + */ +#define I915_NEW_VERTEX_FORMAT 0x10000 + + +/* Dirty flags for hardware emit + */ +#define I915_HW_STATIC (1< - */ - - -#ifndef BRWCONTEXT_INC -#define BRWCONTEXT_INC - - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "tgsi/util/tgsi_scan.h" - -#include "brw_structs.h" -#include "brw_winsys.h" - - -/* Glossary: - * - * URB - uniform resource buffer. A mid-sized buffer which is - * partitioned between the fixed function units and used for passing - * values (vertices, primitives, constants) between them. - * - * CURBE - constant URB entry. An urb region (entry) used to hold - * constant values which the fixed function units can be instructed to - * preload into the GRF when spawining a thread. - * - * VUE - vertex URB entry. An urb entry holding a vertex and usually - * a vertex header. The header contains control information and - * things like primitive type, Begin/end flags and clip codes. - * - * PUE - primitive URB entry. An urb entry produced by the setup (SF) - * unit holding rasterization and interpolation parameters. - * - * GRF - general register file. One of several register files - * addressable by programmed threads. The inputs (r0, payload, curbe, - * urb) of the thread are preloaded to this area before the thread is - * spawned. The registers are individually 8 dwords wide and suitable - * for general usage. Registers holding thread input values are not - * special and may be overwritten. - * - * MRF - message register file. Threads communicate (and terminate) - * by sending messages. Message parameters are placed in contigous - * MRF registers. All program output is via these messages. URB - * entries are populated by sending a message to the shared URB - * function containing the new data, together with a control word, - * often an unmodified copy of R0. - * - * R0 - GRF register 0. Typically holds control information used when - * sending messages to other threads. - * - * EU or GEN4 EU: The name of the programmable subsystem of the - * i965 hardware. Threads are executed by the EU, the registers - * described above are part of the EU architecture. - * - * Fixed function units: - * - * CS - Command streamer. Notional first unit, little software - * interaction. Holds the URB entries used for constant data, ie the - * CURBEs. - * - * VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of - * this unit is responsible for pulling vertices out of vertex buffers - * in vram and injecting them into the processing pipe as VUEs. If - * enabled, it first passes them to a VS thread which is a good place - * for the driver to implement any active vertex shader. - * - * GS - Geometry Shader. This corresponds to a new DX10 concept. If - * enabled, incoming strips etc are passed to GS threads in individual - * line/triangle/point units. The GS thread may perform arbitary - * computation and emit whatever primtives with whatever vertices it - * chooses. This makes GS an excellent place to implement GL's - * unfilled polygon modes, though of course it is capable of much - * more. Additionally, GS is used to translate away primitives not - * handled by latter units, including Quads and Lineloops. - * - * CS - Clipper. Mesa's clipping algorithms are imported to run on - * this unit. The fixed function part performs cliptesting against - * the 6 fixed clipplanes and makes descisions on whether or not the - * incoming primitive needs to be passed to a thread for clipping. - * User clip planes are handled via cooperation with the VS thread. - * - * SF - Strips Fans or Setup: Triangles are prepared for - * rasterization. Interpolation coefficients are calculated. - * Flatshading and two-side lighting usually performed here. - * - * WM - Windower. Interpolation of vertex attributes performed here. - * Fragment shader implemented here. SIMD aspects of EU taken full - * advantage of, as pixels are processed in blocks of 16. - * - * CC - Color Calculator. No EU threads associated with this unit. - * Handles blending and (presumably) depth and stencil testing. - */ - -#define BRW_MAX_CURBE (32*16) - -struct brw_context; -struct brw_winsys; - - -/* Raised when we receive new state across the pipe interface: - */ -#define BRW_NEW_VIEWPORT 0x1 -#define BRW_NEW_RASTERIZER 0x2 -#define BRW_NEW_FS 0x4 -#define BRW_NEW_BLEND 0x8 -#define BRW_NEW_CLIP 0x10 -#define BRW_NEW_SCISSOR 0x20 -#define BRW_NEW_STIPPLE 0x40 -#define BRW_NEW_FRAMEBUFFER 0x80 -#define BRW_NEW_ALPHA_TEST 0x100 -#define BRW_NEW_DEPTH_STENCIL 0x200 -#define BRW_NEW_SAMPLER 0x400 -#define BRW_NEW_TEXTURE 0x800 -#define BRW_NEW_CONSTANTS 0x1000 -#define BRW_NEW_VBO 0x2000 -#define BRW_NEW_VS 0x4000 - -/* Raised for other internal events: - */ -#define BRW_NEW_URB_FENCE 0x10000 -#define BRW_NEW_PSP 0x20000 -#define BRW_NEW_CURBE_OFFSETS 0x40000 -#define BRW_NEW_REDUCED_PRIMITIVE 0x80000 -#define BRW_NEW_PRIMITIVE 0x100000 -#define BRW_NEW_SCENE 0x200000 -#define BRW_NEW_SF_LINKAGE 0x400000 - -extern int BRW_DEBUG; - -#define DEBUG_TEXTURE 0x1 -#define DEBUG_STATE 0x2 -#define DEBUG_IOCTL 0x4 -#define DEBUG_PRIMS 0x8 -#define DEBUG_VERTS 0x10 -#define DEBUG_FALLBACKS 0x20 -#define DEBUG_VERBOSE 0x40 -#define DEBUG_DRI 0x80 -#define DEBUG_DMA 0x100 -#define DEBUG_SANITY 0x200 -#define DEBUG_SYNC 0x400 -#define DEBUG_SLEEP 0x800 -#define DEBUG_PIXEL 0x1000 -#define DEBUG_STATS 0x2000 -#define DEBUG_TILE 0x4000 -#define DEBUG_SINGLE_THREAD 0x8000 -#define DEBUG_WM 0x10000 -#define DEBUG_URB 0x20000 -#define DEBUG_VS 0x40000 -#define DEBUG_BATCH 0x80000 -#define DEBUG_BUFMGR 0x100000 -#define DEBUG_BLIT 0x200000 -#define DEBUG_REGION 0x400000 -#define DEBUG_MIPTREE 0x800000 - -#define DBG(...) do { \ - if (BRW_DEBUG & FILE_DEBUG_FLAG) \ - debug_printf(__VA_ARGS__); \ -} while(0) - -#define PRINT(...) do { \ - debug_printf(brw->pipe.winsys, __VA_ARGS__); \ -} while(0) - -struct brw_state_flags { - unsigned cache; - unsigned brw; -}; - - -struct brw_vertex_program { - struct pipe_shader_state program; - struct tgsi_shader_info info; - int id; -}; - - -struct brw_fragment_program { - struct pipe_shader_state program; - struct tgsi_shader_info info; - - boolean UsesDepth; /* XXX add this to tgsi_shader_info? */ - int id; -}; - - -struct pipe_setup_linkage { - struct { - unsigned vp_output:5; - unsigned interp_mode:4; - unsigned bf_vp_output:5; - } fp_input[PIPE_MAX_SHADER_INPUTS]; - - unsigned fp_input_count:5; - unsigned max_vp_output:5; -}; - - - -struct brw_texture { - struct pipe_texture base; - - /* Derived from the above: - */ - unsigned pitch; - unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; - - unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; - - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats - * are going to be so diverse that there is no unified way to - * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - */ - unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ - - /* Includes image offset tables: - */ - unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; - - /* The data is held here: - */ - struct pipe_buffer *buffer; -}; - -/* Data about a particular attempt to compile a program. Note that - * there can be many of these, each in a different GL state - * corresponding to a different brw_wm_prog_key struct, with different - * compiled programs: - */ -/* Data about a particular attempt to compile a program. Note that - * there can be many of these, each in a different GL state - * corresponding to a different brw_wm_prog_key struct, with different - * compiled programs: - */ - -struct brw_wm_prog_data { - unsigned curb_read_length; - unsigned urb_read_length; - - unsigned first_curbe_grf; - unsigned total_grf; - unsigned total_scratch; - - /* Internally generated constants for the CURBE. These are loaded - * ahead of the data from the constant buffer. - */ - const float internal_const[8]; - unsigned nr_internal_consts; - unsigned max_const; - - boolean error; -}; - -struct brw_sf_prog_data { - unsigned urb_read_length; - unsigned total_grf; - - /* Each vertex may have upto 12 attributes, 4 components each, - * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11 - * rows. - * - * Actually we use 4 for each, so call it 12 rows. - */ - unsigned urb_entry_size; -}; - -struct brw_clip_prog_data { - unsigned curb_read_length; /* user planes? */ - unsigned clip_mode; - unsigned urb_read_length; - unsigned total_grf; -}; - -struct brw_gs_prog_data { - unsigned urb_read_length; - unsigned total_grf; -}; - -struct brw_vs_prog_data { - unsigned curb_read_length; - unsigned urb_read_length; - unsigned total_grf; - unsigned outputs_written; - - unsigned inputs_read; - - unsigned max_const; - - float imm_buf[PIPE_MAX_CONSTANT][4]; - unsigned num_imm; - unsigned num_consts; - - /* Used for calculating urb partitions: - */ - unsigned urb_entry_size; -}; - - -#define BRW_MAX_TEX_UNIT 8 -#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 - -/* Create a fixed sized struct for caching binding tables: - */ -struct brw_surface_binding_table { - unsigned surf_ss_offset[BRW_WM_MAX_SURF]; -}; - - -struct brw_cache; - -struct brw_mem_pool { - struct pipe_buffer *buffer; - - unsigned size; - unsigned offset; /* offset of first free byte */ - - struct brw_context *brw; -}; - -struct brw_cache_item { - unsigned hash; - unsigned key_size; /* for variable-sized keys */ - const void *key; - - unsigned offset; /* offset within pool's buffer */ - unsigned data_size; - - struct brw_cache_item *next; -}; - - - -struct brw_cache { - unsigned id; - - const char *name; - - struct brw_context *brw; - struct brw_mem_pool *pool; - - struct brw_cache_item **items; - unsigned size, n_items; - - unsigned key_size; /* for fixed-size keys */ - unsigned aux_size; - - unsigned last_addr; /* offset of active item */ -}; - - - - -/* Considered adding a member to this struct to document which flags - * an update might raise so that ordering of the state atoms can be - * checked or derived at runtime. Dropped the idea in favor of having - * a debug mode where the state is monitored for flags which are - * raised that have already been tested against. - */ -struct brw_tracked_state { - struct brw_state_flags dirty; - void (*update)( struct brw_context *brw ); -}; - - -/* Flags for brw->state.cache. - */ -#define CACHE_NEW_CC_VP (1< 32. Wouldn't life - * be easier if C allowed arrays of packed elements? - */ -#define ATTRIB_BIT_DWORDS ((PIPE_MAX_ATTRIBS+31)/32) - - - - -struct brw_vertex_info { - unsigned varying; /* varying:1[PIPE_MAX_ATTRIBS] */ - unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_MAX_ATTRIBS] */ -}; - - - - - -struct brw_context -{ - struct pipe_context pipe; - struct brw_winsys *winsys; - - unsigned primitive; - unsigned reduced_primitive; - - boolean emit_state_always; - - struct { - struct brw_state_flags dirty; - } state; - - - struct { - const struct pipe_blend_state *Blend; - const struct pipe_depth_stencil_alpha_state *DepthStencil; - const struct pipe_poly_stipple *PolygonStipple; - const struct pipe_rasterizer_state *Raster; - const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS]; - const struct brw_vertex_program *VertexProgram; - const struct brw_fragment_program *FragmentProgram; - - struct pipe_clip_state Clip; - struct pipe_blend_color BlendColor; - struct pipe_scissor_state Scissor; - struct pipe_viewport_state Viewport; - struct pipe_framebuffer_state FrameBuffer; - - const struct pipe_constant_buffer *Constants[2]; - const struct brw_texture *Texture[PIPE_MAX_SAMPLERS]; - } attribs; - - unsigned num_samplers; - unsigned num_textures; - - struct brw_mem_pool pool[BRW_MAX_POOL]; - struct brw_cache cache[BRW_MAX_CACHE]; - struct brw_cached_batch_item *cached_batch_items; - - struct { - - /* Arrays with buffer objects to copy non-bufferobj arrays into - * for upload: - */ - const struct pipe_vertex_buffer *vbo_array[PIPE_MAX_ATTRIBS]; - - struct brw_vertex_element_state inputs[PIPE_MAX_ATTRIBS]; - -#define BRW_NR_UPLOAD_BUFS 17 -#define BRW_UPLOAD_INIT_SIZE (128*1024) - - /* Summary of size and varying of active arrays, so we can check - * for changes to this state: - */ - struct brw_vertex_info info; - } vb; - - - unsigned hardware_dirty; - unsigned dirty; - unsigned pci_id; - /* BRW_NEW_URB_ALLOCATIONS: - */ - struct { - unsigned vsize; /* vertex size plus header in urb registers */ - unsigned csize; /* constant buffer size in urb registers */ - unsigned sfsize; /* setup data size in urb registers */ - - boolean constrained; - - unsigned nr_vs_entries; - unsigned nr_gs_entries; - unsigned nr_clip_entries; - unsigned nr_sf_entries; - unsigned nr_cs_entries; - -/* unsigned vs_size; */ -/* unsigned gs_size; */ -/* unsigned clip_size; */ -/* unsigned sf_size; */ -/* unsigned cs_size; */ - - unsigned vs_start; - unsigned gs_start; - unsigned clip_start; - unsigned sf_start; - unsigned cs_start; - } urb; - - - /* BRW_NEW_CURBE_OFFSETS: - */ - struct { - unsigned wm_start; - unsigned wm_size; - unsigned clip_start; - unsigned clip_size; - unsigned vs_start; - unsigned vs_size; - unsigned total_size; - - unsigned gs_offset; - - float *last_buf; - unsigned last_bufsz; - } curbe; - - struct { - struct brw_vs_prog_data *prog_data; - - unsigned prog_gs_offset; - unsigned state_gs_offset; - } vs; - - struct { - struct brw_gs_prog_data *prog_data; - - boolean prog_active; - unsigned prog_gs_offset; - unsigned state_gs_offset; - } gs; - - struct { - struct brw_clip_prog_data *prog_data; - - unsigned prog_gs_offset; - unsigned vp_gs_offset; - unsigned state_gs_offset; - } clip; - - - struct { - struct brw_sf_prog_data *prog_data; - - struct pipe_setup_linkage linkage; - - unsigned prog_gs_offset; - unsigned vp_gs_offset; - unsigned state_gs_offset; - } sf; - - struct { - struct brw_wm_prog_data *prog_data; - -// struct brw_wm_compiler *compile_data; - - - /** - * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER - * cache - */ - struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; - - unsigned render_surf; - unsigned nr_surfaces; - - unsigned max_threads; - struct pipe_buffer *scratch_buffer; - unsigned scratch_buffer_size; - - unsigned sampler_count; - unsigned sampler_gs_offset; - - struct brw_surface_binding_table bind; - unsigned bind_ss_offset; - - unsigned prog_gs_offset; - unsigned state_gs_offset; - } wm; - - - struct { - unsigned vp_gs_offset; - unsigned state_gs_offset; - } cc; - - - /* Used to give every program string a unique id - */ - unsigned program_id; -}; - - -#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a) - - -/*====================================================================== - * brw_vtbl.c - */ -void brw_do_flush( struct brw_context *brw, - unsigned flags ); - - -/*====================================================================== - * brw_state.c - */ -void brw_validate_state(struct brw_context *brw); -void brw_init_state(struct brw_context *brw); -void brw_destroy_state(struct brw_context *brw); - - -/*====================================================================== - * brw_tex.c - */ -void brwUpdateTextureState( struct brw_context *brw ); - - -/* brw_urb.c - */ -void brw_upload_urb_fence(struct brw_context *brw); - -void brw_upload_constant_buffer_state(struct brw_context *brw); - -void brw_init_surface_functions(struct brw_context *brw); -void brw_init_state_functions(struct brw_context *brw); -void brw_init_flush_functions(struct brw_context *brw); -void brw_init_string_functions(struct brw_context *brw); - -/*====================================================================== - * Inline conversion functions. These are better-typed than the - * macros used previously: - */ -static inline struct brw_context * -brw_context( struct pipe_context *ctx ) -{ - return (struct brw_context *)ctx; -} - -#endif - +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRWCONTEXT_INC +#define BRWCONTEXT_INC + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "tgsi/util/tgsi_scan.h" + +#include "brw_structs.h" +#include "brw_winsys.h" + + +/* Glossary: + * + * URB - uniform resource buffer. A mid-sized buffer which is + * partitioned between the fixed function units and used for passing + * values (vertices, primitives, constants) between them. + * + * CURBE - constant URB entry. An urb region (entry) used to hold + * constant values which the fixed function units can be instructed to + * preload into the GRF when spawining a thread. + * + * VUE - vertex URB entry. An urb entry holding a vertex and usually + * a vertex header. The header contains control information and + * things like primitive type, Begin/end flags and clip codes. + * + * PUE - primitive URB entry. An urb entry produced by the setup (SF) + * unit holding rasterization and interpolation parameters. + * + * GRF - general register file. One of several register files + * addressable by programmed threads. The inputs (r0, payload, curbe, + * urb) of the thread are preloaded to this area before the thread is + * spawned. The registers are individually 8 dwords wide and suitable + * for general usage. Registers holding thread input values are not + * special and may be overwritten. + * + * MRF - message register file. Threads communicate (and terminate) + * by sending messages. Message parameters are placed in contigous + * MRF registers. All program output is via these messages. URB + * entries are populated by sending a message to the shared URB + * function containing the new data, together with a control word, + * often an unmodified copy of R0. + * + * R0 - GRF register 0. Typically holds control information used when + * sending messages to other threads. + * + * EU or GEN4 EU: The name of the programmable subsystem of the + * i965 hardware. Threads are executed by the EU, the registers + * described above are part of the EU architecture. + * + * Fixed function units: + * + * CS - Command streamer. Notional first unit, little software + * interaction. Holds the URB entries used for constant data, ie the + * CURBEs. + * + * VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of + * this unit is responsible for pulling vertices out of vertex buffers + * in vram and injecting them into the processing pipe as VUEs. If + * enabled, it first passes them to a VS thread which is a good place + * for the driver to implement any active vertex shader. + * + * GS - Geometry Shader. This corresponds to a new DX10 concept. If + * enabled, incoming strips etc are passed to GS threads in individual + * line/triangle/point units. The GS thread may perform arbitary + * computation and emit whatever primtives with whatever vertices it + * chooses. This makes GS an excellent place to implement GL's + * unfilled polygon modes, though of course it is capable of much + * more. Additionally, GS is used to translate away primitives not + * handled by latter units, including Quads and Lineloops. + * + * CS - Clipper. Mesa's clipping algorithms are imported to run on + * this unit. The fixed function part performs cliptesting against + * the 6 fixed clipplanes and makes descisions on whether or not the + * incoming primitive needs to be passed to a thread for clipping. + * User clip planes are handled via cooperation with the VS thread. + * + * SF - Strips Fans or Setup: Triangles are prepared for + * rasterization. Interpolation coefficients are calculated. + * Flatshading and two-side lighting usually performed here. + * + * WM - Windower. Interpolation of vertex attributes performed here. + * Fragment shader implemented here. SIMD aspects of EU taken full + * advantage of, as pixels are processed in blocks of 16. + * + * CC - Color Calculator. No EU threads associated with this unit. + * Handles blending and (presumably) depth and stencil testing. + */ + +#define BRW_MAX_CURBE (32*16) + +struct brw_context; +struct brw_winsys; + + +/* Raised when we receive new state across the pipe interface: + */ +#define BRW_NEW_VIEWPORT 0x1 +#define BRW_NEW_RASTERIZER 0x2 +#define BRW_NEW_FS 0x4 +#define BRW_NEW_BLEND 0x8 +#define BRW_NEW_CLIP 0x10 +#define BRW_NEW_SCISSOR 0x20 +#define BRW_NEW_STIPPLE 0x40 +#define BRW_NEW_FRAMEBUFFER 0x80 +#define BRW_NEW_ALPHA_TEST 0x100 +#define BRW_NEW_DEPTH_STENCIL 0x200 +#define BRW_NEW_SAMPLER 0x400 +#define BRW_NEW_TEXTURE 0x800 +#define BRW_NEW_CONSTANTS 0x1000 +#define BRW_NEW_VBO 0x2000 +#define BRW_NEW_VS 0x4000 + +/* Raised for other internal events: + */ +#define BRW_NEW_URB_FENCE 0x10000 +#define BRW_NEW_PSP 0x20000 +#define BRW_NEW_CURBE_OFFSETS 0x40000 +#define BRW_NEW_REDUCED_PRIMITIVE 0x80000 +#define BRW_NEW_PRIMITIVE 0x100000 +#define BRW_NEW_SCENE 0x200000 +#define BRW_NEW_SF_LINKAGE 0x400000 + +extern int BRW_DEBUG; + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_PRIMS 0x8 +#define DEBUG_VERTS 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_DRI 0x80 +#define DEBUG_DMA 0x100 +#define DEBUG_SANITY 0x200 +#define DEBUG_SYNC 0x400 +#define DEBUG_SLEEP 0x800 +#define DEBUG_PIXEL 0x1000 +#define DEBUG_STATS 0x2000 +#define DEBUG_TILE 0x4000 +#define DEBUG_SINGLE_THREAD 0x8000 +#define DEBUG_WM 0x10000 +#define DEBUG_URB 0x20000 +#define DEBUG_VS 0x40000 +#define DEBUG_BATCH 0x80000 +#define DEBUG_BUFMGR 0x100000 +#define DEBUG_BLIT 0x200000 +#define DEBUG_REGION 0x400000 +#define DEBUG_MIPTREE 0x800000 + +#define DBG(...) do { \ + if (BRW_DEBUG & FILE_DEBUG_FLAG) \ + debug_printf(__VA_ARGS__); \ +} while(0) + +#define PRINT(...) do { \ + debug_printf(brw->pipe.winsys, __VA_ARGS__); \ +} while(0) + +struct brw_state_flags { + unsigned cache; + unsigned brw; +}; + + +struct brw_vertex_program { + struct pipe_shader_state program; + struct tgsi_shader_info info; + int id; +}; + + +struct brw_fragment_program { + struct pipe_shader_state program; + struct tgsi_shader_info info; + + boolean UsesDepth; /* XXX add this to tgsi_shader_info? */ + int id; +}; + + +struct pipe_setup_linkage { + struct { + unsigned vp_output:5; + unsigned interp_mode:4; + unsigned bf_vp_output:5; + } fp_input[PIPE_MAX_SHADER_INPUTS]; + + unsigned fp_input_count:5; + unsigned max_vp_output:5; +}; + + + +struct brw_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ + +struct brw_wm_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + + unsigned first_curbe_grf; + unsigned total_grf; + unsigned total_scratch; + + /* Internally generated constants for the CURBE. These are loaded + * ahead of the data from the constant buffer. + */ + const float internal_const[8]; + unsigned nr_internal_consts; + unsigned max_const; + + boolean error; +}; + +struct brw_sf_prog_data { + unsigned urb_read_length; + unsigned total_grf; + + /* Each vertex may have upto 12 attributes, 4 components each, + * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11 + * rows. + * + * Actually we use 4 for each, so call it 12 rows. + */ + unsigned urb_entry_size; +}; + +struct brw_clip_prog_data { + unsigned curb_read_length; /* user planes? */ + unsigned clip_mode; + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_gs_prog_data { + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_vs_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + unsigned total_grf; + unsigned outputs_written; + + unsigned inputs_read; + + unsigned max_const; + + float imm_buf[PIPE_MAX_CONSTANT][4]; + unsigned num_imm; + unsigned num_consts; + + /* Used for calculating urb partitions: + */ + unsigned urb_entry_size; +}; + + +#define BRW_MAX_TEX_UNIT 8 +#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 + +/* Create a fixed sized struct for caching binding tables: + */ +struct brw_surface_binding_table { + unsigned surf_ss_offset[BRW_WM_MAX_SURF]; +}; + + +struct brw_cache; + +struct brw_mem_pool { + struct pipe_buffer *buffer; + + unsigned size; + unsigned offset; /* offset of first free byte */ + + struct brw_context *brw; +}; + +struct brw_cache_item { + unsigned hash; + unsigned key_size; /* for variable-sized keys */ + const void *key; + + unsigned offset; /* offset within pool's buffer */ + unsigned data_size; + + struct brw_cache_item *next; +}; + + + +struct brw_cache { + unsigned id; + + const char *name; + + struct brw_context *brw; + struct brw_mem_pool *pool; + + struct brw_cache_item **items; + unsigned size, n_items; + + unsigned key_size; /* for fixed-size keys */ + unsigned aux_size; + + unsigned last_addr; /* offset of active item */ +}; + + + + +/* Considered adding a member to this struct to document which flags + * an update might raise so that ordering of the state atoms can be + * checked or derived at runtime. Dropped the idea in favor of having + * a debug mode where the state is monitored for flags which are + * raised that have already been tested against. + */ +struct brw_tracked_state { + struct brw_state_flags dirty; + void (*update)( struct brw_context *brw ); +}; + + +/* Flags for brw->state.cache. + */ +#define CACHE_NEW_CC_VP (1< 32. Wouldn't life + * be easier if C allowed arrays of packed elements? + */ +#define ATTRIB_BIT_DWORDS ((PIPE_MAX_ATTRIBS+31)/32) + + + + +struct brw_vertex_info { + unsigned varying; /* varying:1[PIPE_MAX_ATTRIBS] */ + unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_MAX_ATTRIBS] */ +}; + + + + + +struct brw_context +{ + struct pipe_context pipe; + struct brw_winsys *winsys; + + unsigned primitive; + unsigned reduced_primitive; + + boolean emit_state_always; + + struct { + struct brw_state_flags dirty; + } state; + + + struct { + const struct pipe_blend_state *Blend; + const struct pipe_depth_stencil_alpha_state *DepthStencil; + const struct pipe_poly_stipple *PolygonStipple; + const struct pipe_rasterizer_state *Raster; + const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS]; + const struct brw_vertex_program *VertexProgram; + const struct brw_fragment_program *FragmentProgram; + + struct pipe_clip_state Clip; + struct pipe_blend_color BlendColor; + struct pipe_scissor_state Scissor; + struct pipe_viewport_state Viewport; + struct pipe_framebuffer_state FrameBuffer; + + const struct pipe_constant_buffer *Constants[2]; + const struct brw_texture *Texture[PIPE_MAX_SAMPLERS]; + } attribs; + + unsigned num_samplers; + unsigned num_textures; + + struct brw_mem_pool pool[BRW_MAX_POOL]; + struct brw_cache cache[BRW_MAX_CACHE]; + struct brw_cached_batch_item *cached_batch_items; + + struct { + + /* Arrays with buffer objects to copy non-bufferobj arrays into + * for upload: + */ + const struct pipe_vertex_buffer *vbo_array[PIPE_MAX_ATTRIBS]; + + struct brw_vertex_element_state inputs[PIPE_MAX_ATTRIBS]; + +#define BRW_NR_UPLOAD_BUFS 17 +#define BRW_UPLOAD_INIT_SIZE (128*1024) + + /* Summary of size and varying of active arrays, so we can check + * for changes to this state: + */ + struct brw_vertex_info info; + } vb; + + + unsigned hardware_dirty; + unsigned dirty; + unsigned pci_id; + /* BRW_NEW_URB_ALLOCATIONS: + */ + struct { + unsigned vsize; /* vertex size plus header in urb registers */ + unsigned csize; /* constant buffer size in urb registers */ + unsigned sfsize; /* setup data size in urb registers */ + + boolean constrained; + + unsigned nr_vs_entries; + unsigned nr_gs_entries; + unsigned nr_clip_entries; + unsigned nr_sf_entries; + unsigned nr_cs_entries; + +/* unsigned vs_size; */ +/* unsigned gs_size; */ +/* unsigned clip_size; */ +/* unsigned sf_size; */ +/* unsigned cs_size; */ + + unsigned vs_start; + unsigned gs_start; + unsigned clip_start; + unsigned sf_start; + unsigned cs_start; + } urb; + + + /* BRW_NEW_CURBE_OFFSETS: + */ + struct { + unsigned wm_start; + unsigned wm_size; + unsigned clip_start; + unsigned clip_size; + unsigned vs_start; + unsigned vs_size; + unsigned total_size; + + unsigned gs_offset; + + float *last_buf; + unsigned last_bufsz; + } curbe; + + struct { + struct brw_vs_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } vs; + + struct { + struct brw_gs_prog_data *prog_data; + + boolean prog_active; + unsigned prog_gs_offset; + unsigned state_gs_offset; + } gs; + + struct { + struct brw_clip_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } clip; + + + struct { + struct brw_sf_prog_data *prog_data; + + struct pipe_setup_linkage linkage; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } sf; + + struct { + struct brw_wm_prog_data *prog_data; + +// struct brw_wm_compiler *compile_data; + + + /** + * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER + * cache + */ + struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; + + unsigned render_surf; + unsigned nr_surfaces; + + unsigned max_threads; + struct pipe_buffer *scratch_buffer; + unsigned scratch_buffer_size; + + unsigned sampler_count; + unsigned sampler_gs_offset; + + struct brw_surface_binding_table bind; + unsigned bind_ss_offset; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } wm; + + + struct { + unsigned vp_gs_offset; + unsigned state_gs_offset; + } cc; + + + /* Used to give every program string a unique id + */ + unsigned program_id; +}; + + +#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a) + + +/*====================================================================== + * brw_vtbl.c + */ +void brw_do_flush( struct brw_context *brw, + unsigned flags ); + + +/*====================================================================== + * brw_state.c + */ +void brw_validate_state(struct brw_context *brw); +void brw_init_state(struct brw_context *brw); +void brw_destroy_state(struct brw_context *brw); + + +/*====================================================================== + * brw_tex.c + */ +void brwUpdateTextureState( struct brw_context *brw ); + + +/* brw_urb.c + */ +void brw_upload_urb_fence(struct brw_context *brw); + +void brw_upload_constant_buffer_state(struct brw_context *brw); + +void brw_init_surface_functions(struct brw_context *brw); +void brw_init_state_functions(struct brw_context *brw); +void brw_init_flush_functions(struct brw_context *brw); +void brw_init_string_functions(struct brw_context *brw); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static inline struct brw_context * +brw_context( struct pipe_context *ctx ) +{ + return (struct brw_context *)ctx; +} + +#endif + diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index ac243b7e4f..caeeba4630 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -1,469 +1,469 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Zack Rusin - * Keith Whitwell - */ - - -#include "pipe/p_winsys.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_dump.h" -#include "tgsi/util/tgsi_parse.h" - -#include "brw_context.h" -#include "brw_defines.h" -#include "brw_state.h" -#include "brw_draw.h" - - -#define DUP( TYPE, VAL ) \ -do { \ - struct TYPE *x = malloc(sizeof(*x)); \ - memcpy(x, VAL, sizeof(*x) ); \ - return x; \ -} while (0) - -/************************************************************************ - * Blend - */ -static void * -brw_create_blend_state(struct pipe_context *pipe, - const struct pipe_blend_state *blend) -{ - DUP( pipe_blend_state, blend ); -} - -static void brw_bind_blend_state(struct pipe_context *pipe, - void *blend) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Blend = (struct pipe_blend_state*)blend; - brw->state.dirty.brw |= BRW_NEW_BLEND; -} - - -static void brw_delete_blend_state(struct pipe_context *pipe, void *blend) -{ - free(blend); -} - -static void brw_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.BlendColor = *blend_color; - - brw->state.dirty.brw |= BRW_NEW_BLEND; -} - -/************************************************************************ - * Sampler - */ - -static void * -brw_create_sampler_state(struct pipe_context *pipe, - const struct pipe_sampler_state *sampler) -{ - DUP( pipe_sampler_state, sampler ); -} - -static void brw_bind_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) -{ - struct brw_context *brw = brw_context(pipe); - - assert(num <= PIPE_MAX_SAMPLERS); - - /* Check for no-op */ - if (num == brw->num_samplers && - !memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *))) - return; - - memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *)); - memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) * - sizeof(void *)); - - brw->num_samplers = num; - - brw->state.dirty.brw |= BRW_NEW_SAMPLER; -} - -static void brw_delete_sampler_state(struct pipe_context *pipe, - void *sampler) -{ - free(sampler); -} - - -/************************************************************************ - * Depth stencil - */ - -static void * -brw_create_depth_stencil_state(struct pipe_context *pipe, - const struct pipe_depth_stencil_alpha_state *depth_stencil) -{ - DUP( pipe_depth_stencil_alpha_state, depth_stencil ); -} - -static void brw_bind_depth_stencil_state(struct pipe_context *pipe, - void *depth_stencil) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; - - brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL; -} - -static void brw_delete_depth_stencil_state(struct pipe_context *pipe, - void *depth_stencil) -{ - free(depth_stencil); -} - -/************************************************************************ - * Scissor - */ -static void brw_set_scissor_state( struct pipe_context *pipe, - const struct pipe_scissor_state *scissor ) -{ - struct brw_context *brw = brw_context(pipe); - - memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) ); - brw->state.dirty.brw |= BRW_NEW_SCISSOR; -} - - -/************************************************************************ - * Stipple - */ - -static void brw_set_polygon_stipple( struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple ) -{ -} - - -/************************************************************************ - * Fragment shader - */ - -static void * brw_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *shader) -{ - struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program); - - brw_fp->program.tokens = tgsi_dup_tokens(shader->tokens); - brw_fp->id = brw_context(pipe)->program_id++; - - tgsi_scan_shader(shader->tokens, &brw_fp->info); - -#if 0 - brw_shader_info(shader->tokens, - &brw_fp->info2); -#endif - - tgsi_dump(shader->tokens, 0); - - - return (void *)brw_fp; -} - -static void brw_bind_fs_state(struct pipe_context *pipe, void *shader) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader; - brw->state.dirty.brw |= BRW_NEW_FS; -} - -static void brw_delete_fs_state(struct pipe_context *pipe, void *shader) -{ - struct brw_fragment_program *brw_fp = (struct brw_fragment_program *) shader; - - FREE((void *) brw_fp->program.tokens); - FREE(brw_fp); -} - - -/************************************************************************ - * Vertex shader and other TNL state - */ - -static void *brw_create_vs_state(struct pipe_context *pipe, - const struct pipe_shader_state *shader) -{ - struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program); - - brw_vp->program.tokens = tgsi_dup_tokens(shader->tokens); - brw_vp->id = brw_context(pipe)->program_id++; - - tgsi_scan_shader(shader->tokens, &brw_vp->info); - -#if 0 - brw_shader_info(shader->tokens, - &brw_vp->info2); -#endif - tgsi_dump(shader->tokens, 0); - - return (void *)brw_vp; -} - -static void brw_bind_vs_state(struct pipe_context *pipe, void *vs) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.VertexProgram = (struct brw_vertex_program *)vs; - brw->state.dirty.brw |= BRW_NEW_VS; - - debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n"); -} - -static void brw_delete_vs_state(struct pipe_context *pipe, void *shader) -{ - struct brw_vertex_program *brw_vp = (struct brw_vertex_program *) shader; - - FREE((void *) brw_vp->program.tokens); - FREE(brw_vp); -} - - -static void brw_set_clip_state( struct pipe_context *pipe, - const struct pipe_clip_state *clip ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Clip = *clip; -} - - -static void brw_set_viewport_state( struct pipe_context *pipe, - const struct pipe_viewport_state *viewport ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Viewport = *viewport; /* struct copy */ - brw->state.dirty.brw |= BRW_NEW_VIEWPORT; - - /* pass the viewport info to the draw module */ - //draw_set_viewport_state(brw->draw, viewport); -} - - -static void brw_set_vertex_buffers(struct pipe_context *pipe, - unsigned count, - const struct pipe_vertex_buffer *buffers) -{ - struct brw_context *brw = brw_context(pipe); - memcpy(brw->vb.vbo_array, buffers, count * sizeof(buffers[0])); -} - -static void brw_set_vertex_elements(struct pipe_context *pipe, - unsigned count, - const struct pipe_vertex_element *elements) -{ - /* flush ? */ - struct brw_context *brw = brw_context(pipe); - uint i; - - assert(count <= PIPE_MAX_ATTRIBS); - - for (i = 0; i < count; i++) { - struct brw_vertex_element_state el; - memset(&el, 0, sizeof(el)); - - el.ve0.src_offset = elements[i].src_offset; - el.ve0.src_format = brw_translate_surface_format(elements[i].src_format); - el.ve0.valid = 1; - el.ve0.vertex_buffer_index = elements[i].vertex_buffer_index; - - el.ve1.dst_offset = i * 4; - - el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; - - switch (elements[i].nr_components) { - case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; - case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; - case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; - break; - } - - brw->vb.inputs[i] = el; - } -} - - - -/************************************************************************ - * Constant buffers - */ - -static void brw_set_constant_buffer(struct pipe_context *pipe, - uint shader, uint index, - const struct pipe_constant_buffer *buf) -{ - struct brw_context *brw = brw_context(pipe); - - assert(buf == 0 || index == 0); - - brw->attribs.Constants[shader] = buf; - brw->state.dirty.brw |= BRW_NEW_CONSTANTS; -} - - -/************************************************************************ - * Texture surfaces - */ - - -static void brw_set_sampler_textures(struct pipe_context *pipe, - unsigned num, - struct pipe_texture **texture) -{ - struct brw_context *brw = brw_context(pipe); - uint i; - - assert(num <= PIPE_MAX_SAMPLERS); - - /* Check for no-op */ - if (num == brw->num_textures && - !memcmp(brw->attribs.Texture, texture, num * - sizeof(struct pipe_texture *))) - return; - - for (i = 0; i < num; i++) - pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], - texture[i]); - - for (i = num; i < brw->num_textures; i++) - pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], - NULL); - - brw->num_textures = num; - - brw->state.dirty.brw |= BRW_NEW_TEXTURE; -} - - -/************************************************************************ - * Render targets, etc - */ - -static void brw_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.FrameBuffer = *fb; /* struct copy */ - - brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER; -} - - - -/************************************************************************ - * Rasterizer state - */ - -static void * -brw_create_rasterizer_state(struct pipe_context *pipe, - const struct pipe_rasterizer_state *rasterizer) -{ - DUP(pipe_rasterizer_state, rasterizer); -} - -static void brw_bind_rasterizer_state( struct pipe_context *pipe, - void *setup ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Raster = (struct pipe_rasterizer_state *)setup; - - /* Also pass-through to draw module: - */ - //draw_set_rasterizer_state(brw->draw, setup); - - brw->state.dirty.brw |= BRW_NEW_RASTERIZER; -} - -static void brw_delete_rasterizer_state(struct pipe_context *pipe, - void *setup) -{ - free(setup); -} - - - -void -brw_init_state_functions( struct brw_context *brw ) -{ - brw->pipe.create_blend_state = brw_create_blend_state; - brw->pipe.bind_blend_state = brw_bind_blend_state; - brw->pipe.delete_blend_state = brw_delete_blend_state; - - brw->pipe.create_sampler_state = brw_create_sampler_state; - brw->pipe.bind_sampler_states = brw_bind_sampler_states; - brw->pipe.delete_sampler_state = brw_delete_sampler_state; - - brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; - brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; - brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; - - brw->pipe.create_rasterizer_state = brw_create_rasterizer_state; - brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state; - brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state; - brw->pipe.create_fs_state = brw_create_fs_state; - brw->pipe.bind_fs_state = brw_bind_fs_state; - brw->pipe.delete_fs_state = brw_delete_fs_state; - brw->pipe.create_vs_state = brw_create_vs_state; - brw->pipe.bind_vs_state = brw_bind_vs_state; - brw->pipe.delete_vs_state = brw_delete_vs_state; - - brw->pipe.set_blend_color = brw_set_blend_color; - brw->pipe.set_clip_state = brw_set_clip_state; - brw->pipe.set_constant_buffer = brw_set_constant_buffer; - brw->pipe.set_framebuffer_state = brw_set_framebuffer_state; - -// brw->pipe.set_feedback_state = brw_set_feedback_state; -// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer; - - brw->pipe.set_polygon_stipple = brw_set_polygon_stipple; - brw->pipe.set_scissor_state = brw_set_scissor_state; - brw->pipe.set_sampler_textures = brw_set_sampler_textures; - brw->pipe.set_viewport_state = brw_set_viewport_state; - brw->pipe.set_vertex_buffers = brw_set_vertex_buffers; - brw->pipe.set_vertex_elements = brw_set_vertex_elements; -} +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Zack Rusin + * Keith Whitwell + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_dump.h" +#include "tgsi/util/tgsi_parse.h" + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_state.h" +#include "brw_draw.h" + + +#define DUP( TYPE, VAL ) \ +do { \ + struct TYPE *x = malloc(sizeof(*x)); \ + memcpy(x, VAL, sizeof(*x) ); \ + return x; \ +} while (0) + +/************************************************************************ + * Blend + */ +static void * +brw_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + DUP( pipe_blend_state, blend ); +} + +static void brw_bind_blend_state(struct pipe_context *pipe, + void *blend) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Blend = (struct pipe_blend_state*)blend; + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + + +static void brw_delete_blend_state(struct pipe_context *pipe, void *blend) +{ + free(blend); +} + +static void brw_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.BlendColor = *blend_color; + + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + +/************************************************************************ + * Sampler + */ + +static void * +brw_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + DUP( pipe_sampler_state, sampler ); +} + +static void brw_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct brw_context *brw = brw_context(pipe); + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == brw->num_samplers && + !memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *))) + return; + + memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *)); + memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) * + sizeof(void *)); + + brw->num_samplers = num; + + brw->state.dirty.brw |= BRW_NEW_SAMPLER; +} + +static void brw_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + free(sampler); +} + + +/************************************************************************ + * Depth stencil + */ + +static void * +brw_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + DUP( pipe_depth_stencil_alpha_state, depth_stencil ); +} + +static void brw_bind_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; + + brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL; +} + +static void brw_delete_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + free(depth_stencil); +} + +/************************************************************************ + * Scissor + */ +static void brw_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct brw_context *brw = brw_context(pipe); + + memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) ); + brw->state.dirty.brw |= BRW_NEW_SCISSOR; +} + + +/************************************************************************ + * Stipple + */ + +static void brw_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ +} + + +/************************************************************************ + * Fragment shader + */ + +static void * brw_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program); + + brw_fp->program.tokens = tgsi_dup_tokens(shader->tokens); + brw_fp->id = brw_context(pipe)->program_id++; + + tgsi_scan_shader(shader->tokens, &brw_fp->info); + +#if 0 + brw_shader_info(shader->tokens, + &brw_fp->info2); +#endif + + tgsi_dump(shader->tokens, 0); + + + return (void *)brw_fp; +} + +static void brw_bind_fs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader; + brw->state.dirty.brw |= BRW_NEW_FS; +} + +static void brw_delete_fs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_fragment_program *brw_fp = (struct brw_fragment_program *) shader; + + FREE((void *) brw_fp->program.tokens); + FREE(brw_fp); +} + + +/************************************************************************ + * Vertex shader and other TNL state + */ + +static void *brw_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program); + + brw_vp->program.tokens = tgsi_dup_tokens(shader->tokens); + brw_vp->id = brw_context(pipe)->program_id++; + + tgsi_scan_shader(shader->tokens, &brw_vp->info); + +#if 0 + brw_shader_info(shader->tokens, + &brw_vp->info2); +#endif + tgsi_dump(shader->tokens, 0); + + return (void *)brw_vp; +} + +static void brw_bind_vs_state(struct pipe_context *pipe, void *vs) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.VertexProgram = (struct brw_vertex_program *)vs; + brw->state.dirty.brw |= BRW_NEW_VS; + + debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n"); +} + +static void brw_delete_vs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_vertex_program *brw_vp = (struct brw_vertex_program *) shader; + + FREE((void *) brw_vp->program.tokens); + FREE(brw_vp); +} + + +static void brw_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Clip = *clip; +} + + +static void brw_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Viewport = *viewport; /* struct copy */ + brw->state.dirty.brw |= BRW_NEW_VIEWPORT; + + /* pass the viewport info to the draw module */ + //draw_set_viewport_state(brw->draw, viewport); +} + + +static void brw_set_vertex_buffers(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_buffer *buffers) +{ + struct brw_context *brw = brw_context(pipe); + memcpy(brw->vb.vbo_array, buffers, count * sizeof(buffers[0])); +} + +static void brw_set_vertex_elements(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_element *elements) +{ + /* flush ? */ + struct brw_context *brw = brw_context(pipe); + uint i; + + assert(count <= PIPE_MAX_ATTRIBS); + + for (i = 0; i < count; i++) { + struct brw_vertex_element_state el; + memset(&el, 0, sizeof(el)); + + el.ve0.src_offset = elements[i].src_offset; + el.ve0.src_format = brw_translate_surface_format(elements[i].src_format); + el.ve0.valid = 1; + el.ve0.vertex_buffer_index = elements[i].vertex_buffer_index; + + el.ve1.dst_offset = i * 4; + + el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; + + switch (elements[i].nr_components) { + case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; + case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; + case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; + break; + } + + brw->vb.inputs[i] = el; + } +} + + + +/************************************************************************ + * Constant buffers + */ + +static void brw_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct brw_context *brw = brw_context(pipe); + + assert(buf == 0 || index == 0); + + brw->attribs.Constants[shader] = buf; + brw->state.dirty.brw |= BRW_NEW_CONSTANTS; +} + + +/************************************************************************ + * Texture surfaces + */ + + +static void brw_set_sampler_textures(struct pipe_context *pipe, + unsigned num, + struct pipe_texture **texture) +{ + struct brw_context *brw = brw_context(pipe); + uint i; + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == brw->num_textures && + !memcmp(brw->attribs.Texture, texture, num * + sizeof(struct pipe_texture *))) + return; + + for (i = 0; i < num; i++) + pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], + texture[i]); + + for (i = num; i < brw->num_textures; i++) + pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], + NULL); + + brw->num_textures = num; + + brw->state.dirty.brw |= BRW_NEW_TEXTURE; +} + + +/************************************************************************ + * Render targets, etc + */ + +static void brw_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FrameBuffer = *fb; /* struct copy */ + + brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER; +} + + + +/************************************************************************ + * Rasterizer state + */ + +static void * +brw_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *rasterizer) +{ + DUP(pipe_rasterizer_state, rasterizer); +} + +static void brw_bind_rasterizer_state( struct pipe_context *pipe, + void *setup ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Raster = (struct pipe_rasterizer_state *)setup; + + /* Also pass-through to draw module: + */ + //draw_set_rasterizer_state(brw->draw, setup); + + brw->state.dirty.brw |= BRW_NEW_RASTERIZER; +} + +static void brw_delete_rasterizer_state(struct pipe_context *pipe, + void *setup) +{ + free(setup); +} + + + +void +brw_init_state_functions( struct brw_context *brw ) +{ + brw->pipe.create_blend_state = brw_create_blend_state; + brw->pipe.bind_blend_state = brw_bind_blend_state; + brw->pipe.delete_blend_state = brw_delete_blend_state; + + brw->pipe.create_sampler_state = brw_create_sampler_state; + brw->pipe.bind_sampler_states = brw_bind_sampler_states; + brw->pipe.delete_sampler_state = brw_delete_sampler_state; + + brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; + brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; + brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; + + brw->pipe.create_rasterizer_state = brw_create_rasterizer_state; + brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state; + brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state; + brw->pipe.create_fs_state = brw_create_fs_state; + brw->pipe.bind_fs_state = brw_bind_fs_state; + brw->pipe.delete_fs_state = brw_delete_fs_state; + brw->pipe.create_vs_state = brw_create_vs_state; + brw->pipe.bind_vs_state = brw_bind_vs_state; + brw->pipe.delete_vs_state = brw_delete_vs_state; + + brw->pipe.set_blend_color = brw_set_blend_color; + brw->pipe.set_clip_state = brw_set_clip_state; + brw->pipe.set_constant_buffer = brw_set_constant_buffer; + brw->pipe.set_framebuffer_state = brw_set_framebuffer_state; + +// brw->pipe.set_feedback_state = brw_set_feedback_state; +// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer; + + brw->pipe.set_polygon_stipple = brw_set_polygon_stipple; + brw->pipe.set_scissor_state = brw_set_scissor_state; + brw->pipe.set_sampler_textures = brw_set_sampler_textures; + brw->pipe.set_viewport_state = brw_set_viewport_state; + brw->pipe.set_vertex_buffers = brw_set_vertex_buffers; + brw->pipe.set_vertex_elements = brw_set_vertex_elements; +} -- cgit v1.2.3 From c428997a521475c46ccd1df4e8ed8ccc6c4f8d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 26 May 2008 23:29:38 +0900 Subject: Revert DOS line endings. --- src/gallium/drivers/i915simple/i915_context.h | 682 ++++++------ src/gallium/drivers/i965simple/brw_context.h | 1368 ++++++++++++------------- src/gallium/drivers/i965simple/brw_state.c | 938 ++++++++--------- 3 files changed, 1494 insertions(+), 1494 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 38e6a34884..53fc5ed079 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -1,341 +1,341 @@ - /************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef I915_CONTEXT_H -#define I915_CONTEXT_H - - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "draw/draw_vertex.h" - -#include "tgsi/util/tgsi_scan.h" - - -#define I915_TEX_UNITS 8 - -#define I915_DYNAMIC_MODES4 0 -#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */ -#define I915_DYNAMIC_DEPTHSCALE_1 2 -#define I915_DYNAMIC_IAB 3 -#define I915_DYNAMIC_BC_0 4 /* just the header */ -#define I915_DYNAMIC_BC_1 5 -#define I915_DYNAMIC_BFO_0 6 -#define I915_DYNAMIC_BFO_1 7 -#define I915_DYNAMIC_STP_0 8 -#define I915_DYNAMIC_STP_1 9 -#define I915_DYNAMIC_SC_ENA_0 10 -#define I915_DYNAMIC_SC_RECT_0 11 -#define I915_DYNAMIC_SC_RECT_1 12 -#define I915_DYNAMIC_SC_RECT_2 13 -#define I915_MAX_DYNAMIC 14 - - -#define I915_IMMEDIATE_S0 0 -#define I915_IMMEDIATE_S1 1 -#define I915_IMMEDIATE_S2 2 -#define I915_IMMEDIATE_S3 3 -#define I915_IMMEDIATE_S4 4 -#define I915_IMMEDIATE_S5 5 -#define I915_IMMEDIATE_S6 6 -#define I915_IMMEDIATE_S7 7 -#define I915_MAX_IMMEDIATE 8 - -/* These must mach the order of LI0_STATE_* bits, as they will be used - * to generate hardware packets: - */ -#define I915_CACHE_STATIC 0 -#define I915_CACHE_DYNAMIC 1 /* handled specially */ -#define I915_CACHE_SAMPLER 2 -#define I915_CACHE_MAP 3 -#define I915_CACHE_PROGRAM 4 -#define I915_CACHE_CONSTANTS 5 -#define I915_MAX_CACHE 6 - -#define I915_MAX_CONSTANT 32 - - -/** See constant_flags[] below */ -#define I915_CONSTFLAG_USER 0x1f - - -/** - * Subclass of pipe_shader_state - */ -struct i915_fragment_shader -{ - struct pipe_shader_state state; - - struct tgsi_shader_info info; - - uint *program; - uint program_len; - - /** - * constants introduced during translation. - * These are placed at the end of the constant buffer and grow toward - * the beginning (eg: slot 31, 30 29, ...) - * User-provided constants start at 0. - * This allows both types of constants to co-exist (until there's too many) - * and doesn't require regenerating/changing the fragment program to - * shuffle constants around. - */ - uint num_constants; - float constants[I915_MAX_CONSTANT][4]; - - /** - * Status of each constant - * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding - * slot of the user's constant buffer. (set by pipe->set_constant_buffer()) - * Else, the bitmask indicates which components are occupied by immediates. - */ - ubyte constant_flags[I915_MAX_CONSTANT]; -}; - - -struct i915_cache_context; - -/* Use to calculate differences between state emitted to hardware and - * current driver-calculated state. - */ -struct i915_state -{ - unsigned immediate[I915_MAX_IMMEDIATE]; - unsigned dynamic[I915_MAX_DYNAMIC]; - - float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4]; - /** number of constants passed in through a constant buffer */ - uint num_user_constants[PIPE_SHADER_TYPES]; - - /* texture sampler state */ - unsigned sampler[I915_TEX_UNITS][3]; - unsigned sampler_enable_flags; - unsigned sampler_enable_nr; - - /* texture image buffers */ - unsigned texbuffer[I915_TEX_UNITS][2]; - - /** Describes the current hardware vertex layout */ - struct vertex_info vertex_info; - - unsigned id; /* track lost context events */ -}; - -struct i915_blend_state { - unsigned iab; - unsigned modes4; - unsigned LIS5; - unsigned LIS6; -}; - -struct i915_depth_stencil_state { - unsigned stencil_modes4; - unsigned bfo[2]; - unsigned stencil_LIS5; - unsigned depth_LIS6; -}; - -struct i915_rasterizer_state { - int light_twoside : 1; - unsigned st; - enum interp_mode color_interp; - - unsigned LIS4; - unsigned LIS7; - unsigned sc[1]; - - const struct pipe_rasterizer_state *templ; - - union { float f; unsigned u; } ds[2]; -}; - -struct i915_sampler_state { - unsigned state[3]; - const struct pipe_sampler_state *templ; -}; - - -struct i915_texture { - struct pipe_texture base; - - /* Derived from the above: - */ - unsigned pitch; - unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; - - unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; - - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats - * are going to be so diverse that there is no unified way to - * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - */ - unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ - - /* Includes image offset tables: - */ - unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; - - /* The data is held here: - */ - struct pipe_buffer *buffer; -}; - -struct i915_context -{ - struct pipe_context pipe; - struct i915_winsys *winsys; - struct draw_context *draw; - - /* The most recent drawing state as set by the driver: - */ - const struct i915_blend_state *blend; - const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; - const struct i915_depth_stencil_state *depth_stencil; - const struct i915_rasterizer_state *rasterizer; - - struct i915_fragment_shader *fs; - - struct pipe_blend_color blend_color; - struct pipe_clip_state clip; - struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; - struct pipe_framebuffer_state framebuffer; - struct pipe_poly_stipple poly_stipple; - struct pipe_scissor_state scissor; - struct i915_texture *texture[PIPE_MAX_SAMPLERS]; - struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - - unsigned dirty; - - unsigned num_samplers; - unsigned num_textures; - unsigned num_vertex_elements; - unsigned num_vertex_buffers; - - unsigned *batch_start; - - /** Vertex buffer */ - struct pipe_buffer *vbo; - - struct i915_state current; - unsigned hardware_dirty; - - unsigned debug; -}; - -/* A flag for each state_tracker state object: - */ -#define I915_NEW_VIEWPORT 0x1 -#define I915_NEW_RASTERIZER 0x2 -#define I915_NEW_FS 0x4 -#define I915_NEW_BLEND 0x8 -#define I915_NEW_CLIP 0x10 -#define I915_NEW_SCISSOR 0x20 -#define I915_NEW_STIPPLE 0x40 -#define I915_NEW_FRAMEBUFFER 0x80 -#define I915_NEW_ALPHA_TEST 0x100 -#define I915_NEW_DEPTH_STENCIL 0x200 -#define I915_NEW_SAMPLER 0x400 -#define I915_NEW_TEXTURE 0x800 -#define I915_NEW_CONSTANTS 0x1000 -#define I915_NEW_VBO 0x2000 -#define I915_NEW_VS 0x4000 - - -/* Driver's internally generated state flags: - */ -#define I915_NEW_VERTEX_FORMAT 0x10000 - - -/* Dirty flags for hardware emit - */ -#define I915_HW_STATIC (1<set_constant_buffer()) + * Else, the bitmask indicates which components are occupied by immediates. + */ + ubyte constant_flags[I915_MAX_CONSTANT]; +}; + + +struct i915_cache_context; + +/* Use to calculate differences between state emitted to hardware and + * current driver-calculated state. + */ +struct i915_state +{ + unsigned immediate[I915_MAX_IMMEDIATE]; + unsigned dynamic[I915_MAX_DYNAMIC]; + + float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4]; + /** number of constants passed in through a constant buffer */ + uint num_user_constants[PIPE_SHADER_TYPES]; + + /* texture sampler state */ + unsigned sampler[I915_TEX_UNITS][3]; + unsigned sampler_enable_flags; + unsigned sampler_enable_nr; + + /* texture image buffers */ + unsigned texbuffer[I915_TEX_UNITS][2]; + + /** Describes the current hardware vertex layout */ + struct vertex_info vertex_info; + + unsigned id; /* track lost context events */ +}; + +struct i915_blend_state { + unsigned iab; + unsigned modes4; + unsigned LIS5; + unsigned LIS6; +}; + +struct i915_depth_stencil_state { + unsigned stencil_modes4; + unsigned bfo[2]; + unsigned stencil_LIS5; + unsigned depth_LIS6; +}; + +struct i915_rasterizer_state { + int light_twoside : 1; + unsigned st; + enum interp_mode color_interp; + + unsigned LIS4; + unsigned LIS7; + unsigned sc[1]; + + const struct pipe_rasterizer_state *templ; + + union { float f; unsigned u; } ds[2]; +}; + +struct i915_sampler_state { + unsigned state[3]; + const struct pipe_sampler_state *templ; +}; + + +struct i915_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +struct i915_context +{ + struct pipe_context pipe; + struct i915_winsys *winsys; + struct draw_context *draw; + + /* The most recent drawing state as set by the driver: + */ + const struct i915_blend_state *blend; + const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct i915_depth_stencil_state *depth_stencil; + const struct i915_rasterizer_state *rasterizer; + + struct i915_fragment_shader *fs; + + struct pipe_blend_color blend_color; + struct pipe_clip_state clip; + struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; + struct pipe_framebuffer_state framebuffer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct i915_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + + unsigned dirty; + + unsigned num_samplers; + unsigned num_textures; + unsigned num_vertex_elements; + unsigned num_vertex_buffers; + + unsigned *batch_start; + + /** Vertex buffer */ + struct pipe_buffer *vbo; + + struct i915_state current; + unsigned hardware_dirty; + + unsigned debug; +}; + +/* A flag for each state_tracker state object: + */ +#define I915_NEW_VIEWPORT 0x1 +#define I915_NEW_RASTERIZER 0x2 +#define I915_NEW_FS 0x4 +#define I915_NEW_BLEND 0x8 +#define I915_NEW_CLIP 0x10 +#define I915_NEW_SCISSOR 0x20 +#define I915_NEW_STIPPLE 0x40 +#define I915_NEW_FRAMEBUFFER 0x80 +#define I915_NEW_ALPHA_TEST 0x100 +#define I915_NEW_DEPTH_STENCIL 0x200 +#define I915_NEW_SAMPLER 0x400 +#define I915_NEW_TEXTURE 0x800 +#define I915_NEW_CONSTANTS 0x1000 +#define I915_NEW_VBO 0x2000 +#define I915_NEW_VS 0x4000 + + +/* Driver's internally generated state flags: + */ +#define I915_NEW_VERTEX_FORMAT 0x10000 + + +/* Dirty flags for hardware emit + */ +#define I915_HW_STATIC (1< - */ - - -#ifndef BRWCONTEXT_INC -#define BRWCONTEXT_INC - - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "tgsi/util/tgsi_scan.h" - -#include "brw_structs.h" -#include "brw_winsys.h" - - -/* Glossary: - * - * URB - uniform resource buffer. A mid-sized buffer which is - * partitioned between the fixed function units and used for passing - * values (vertices, primitives, constants) between them. - * - * CURBE - constant URB entry. An urb region (entry) used to hold - * constant values which the fixed function units can be instructed to - * preload into the GRF when spawining a thread. - * - * VUE - vertex URB entry. An urb entry holding a vertex and usually - * a vertex header. The header contains control information and - * things like primitive type, Begin/end flags and clip codes. - * - * PUE - primitive URB entry. An urb entry produced by the setup (SF) - * unit holding rasterization and interpolation parameters. - * - * GRF - general register file. One of several register files - * addressable by programmed threads. The inputs (r0, payload, curbe, - * urb) of the thread are preloaded to this area before the thread is - * spawned. The registers are individually 8 dwords wide and suitable - * for general usage. Registers holding thread input values are not - * special and may be overwritten. - * - * MRF - message register file. Threads communicate (and terminate) - * by sending messages. Message parameters are placed in contigous - * MRF registers. All program output is via these messages. URB - * entries are populated by sending a message to the shared URB - * function containing the new data, together with a control word, - * often an unmodified copy of R0. - * - * R0 - GRF register 0. Typically holds control information used when - * sending messages to other threads. - * - * EU or GEN4 EU: The name of the programmable subsystem of the - * i965 hardware. Threads are executed by the EU, the registers - * described above are part of the EU architecture. - * - * Fixed function units: - * - * CS - Command streamer. Notional first unit, little software - * interaction. Holds the URB entries used for constant data, ie the - * CURBEs. - * - * VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of - * this unit is responsible for pulling vertices out of vertex buffers - * in vram and injecting them into the processing pipe as VUEs. If - * enabled, it first passes them to a VS thread which is a good place - * for the driver to implement any active vertex shader. - * - * GS - Geometry Shader. This corresponds to a new DX10 concept. If - * enabled, incoming strips etc are passed to GS threads in individual - * line/triangle/point units. The GS thread may perform arbitary - * computation and emit whatever primtives with whatever vertices it - * chooses. This makes GS an excellent place to implement GL's - * unfilled polygon modes, though of course it is capable of much - * more. Additionally, GS is used to translate away primitives not - * handled by latter units, including Quads and Lineloops. - * - * CS - Clipper. Mesa's clipping algorithms are imported to run on - * this unit. The fixed function part performs cliptesting against - * the 6 fixed clipplanes and makes descisions on whether or not the - * incoming primitive needs to be passed to a thread for clipping. - * User clip planes are handled via cooperation with the VS thread. - * - * SF - Strips Fans or Setup: Triangles are prepared for - * rasterization. Interpolation coefficients are calculated. - * Flatshading and two-side lighting usually performed here. - * - * WM - Windower. Interpolation of vertex attributes performed here. - * Fragment shader implemented here. SIMD aspects of EU taken full - * advantage of, as pixels are processed in blocks of 16. - * - * CC - Color Calculator. No EU threads associated with this unit. - * Handles blending and (presumably) depth and stencil testing. - */ - -#define BRW_MAX_CURBE (32*16) - -struct brw_context; -struct brw_winsys; - - -/* Raised when we receive new state across the pipe interface: - */ -#define BRW_NEW_VIEWPORT 0x1 -#define BRW_NEW_RASTERIZER 0x2 -#define BRW_NEW_FS 0x4 -#define BRW_NEW_BLEND 0x8 -#define BRW_NEW_CLIP 0x10 -#define BRW_NEW_SCISSOR 0x20 -#define BRW_NEW_STIPPLE 0x40 -#define BRW_NEW_FRAMEBUFFER 0x80 -#define BRW_NEW_ALPHA_TEST 0x100 -#define BRW_NEW_DEPTH_STENCIL 0x200 -#define BRW_NEW_SAMPLER 0x400 -#define BRW_NEW_TEXTURE 0x800 -#define BRW_NEW_CONSTANTS 0x1000 -#define BRW_NEW_VBO 0x2000 -#define BRW_NEW_VS 0x4000 - -/* Raised for other internal events: - */ -#define BRW_NEW_URB_FENCE 0x10000 -#define BRW_NEW_PSP 0x20000 -#define BRW_NEW_CURBE_OFFSETS 0x40000 -#define BRW_NEW_REDUCED_PRIMITIVE 0x80000 -#define BRW_NEW_PRIMITIVE 0x100000 -#define BRW_NEW_SCENE 0x200000 -#define BRW_NEW_SF_LINKAGE 0x400000 - -extern int BRW_DEBUG; - -#define DEBUG_TEXTURE 0x1 -#define DEBUG_STATE 0x2 -#define DEBUG_IOCTL 0x4 -#define DEBUG_PRIMS 0x8 -#define DEBUG_VERTS 0x10 -#define DEBUG_FALLBACKS 0x20 -#define DEBUG_VERBOSE 0x40 -#define DEBUG_DRI 0x80 -#define DEBUG_DMA 0x100 -#define DEBUG_SANITY 0x200 -#define DEBUG_SYNC 0x400 -#define DEBUG_SLEEP 0x800 -#define DEBUG_PIXEL 0x1000 -#define DEBUG_STATS 0x2000 -#define DEBUG_TILE 0x4000 -#define DEBUG_SINGLE_THREAD 0x8000 -#define DEBUG_WM 0x10000 -#define DEBUG_URB 0x20000 -#define DEBUG_VS 0x40000 -#define DEBUG_BATCH 0x80000 -#define DEBUG_BUFMGR 0x100000 -#define DEBUG_BLIT 0x200000 -#define DEBUG_REGION 0x400000 -#define DEBUG_MIPTREE 0x800000 - -#define DBG(...) do { \ - if (BRW_DEBUG & FILE_DEBUG_FLAG) \ - debug_printf(__VA_ARGS__); \ -} while(0) - -#define PRINT(...) do { \ - debug_printf(brw->pipe.winsys, __VA_ARGS__); \ -} while(0) - -struct brw_state_flags { - unsigned cache; - unsigned brw; -}; - - -struct brw_vertex_program { - struct pipe_shader_state program; - struct tgsi_shader_info info; - int id; -}; - - -struct brw_fragment_program { - struct pipe_shader_state program; - struct tgsi_shader_info info; - - boolean UsesDepth; /* XXX add this to tgsi_shader_info? */ - int id; -}; - - -struct pipe_setup_linkage { - struct { - unsigned vp_output:5; - unsigned interp_mode:4; - unsigned bf_vp_output:5; - } fp_input[PIPE_MAX_SHADER_INPUTS]; - - unsigned fp_input_count:5; - unsigned max_vp_output:5; -}; - - - -struct brw_texture { - struct pipe_texture base; - - /* Derived from the above: - */ - unsigned pitch; - unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; - - unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; - - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats - * are going to be so diverse that there is no unified way to - * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - */ - unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ - - /* Includes image offset tables: - */ - unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; - - /* The data is held here: - */ - struct pipe_buffer *buffer; -}; - -/* Data about a particular attempt to compile a program. Note that - * there can be many of these, each in a different GL state - * corresponding to a different brw_wm_prog_key struct, with different - * compiled programs: - */ -/* Data about a particular attempt to compile a program. Note that - * there can be many of these, each in a different GL state - * corresponding to a different brw_wm_prog_key struct, with different - * compiled programs: - */ - -struct brw_wm_prog_data { - unsigned curb_read_length; - unsigned urb_read_length; - - unsigned first_curbe_grf; - unsigned total_grf; - unsigned total_scratch; - - /* Internally generated constants for the CURBE. These are loaded - * ahead of the data from the constant buffer. - */ - const float internal_const[8]; - unsigned nr_internal_consts; - unsigned max_const; - - boolean error; -}; - -struct brw_sf_prog_data { - unsigned urb_read_length; - unsigned total_grf; - - /* Each vertex may have upto 12 attributes, 4 components each, - * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11 - * rows. - * - * Actually we use 4 for each, so call it 12 rows. - */ - unsigned urb_entry_size; -}; - -struct brw_clip_prog_data { - unsigned curb_read_length; /* user planes? */ - unsigned clip_mode; - unsigned urb_read_length; - unsigned total_grf; -}; - -struct brw_gs_prog_data { - unsigned urb_read_length; - unsigned total_grf; -}; - -struct brw_vs_prog_data { - unsigned curb_read_length; - unsigned urb_read_length; - unsigned total_grf; - unsigned outputs_written; - - unsigned inputs_read; - - unsigned max_const; - - float imm_buf[PIPE_MAX_CONSTANT][4]; - unsigned num_imm; - unsigned num_consts; - - /* Used for calculating urb partitions: - */ - unsigned urb_entry_size; -}; - - -#define BRW_MAX_TEX_UNIT 8 -#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 - -/* Create a fixed sized struct for caching binding tables: - */ -struct brw_surface_binding_table { - unsigned surf_ss_offset[BRW_WM_MAX_SURF]; -}; - - -struct brw_cache; - -struct brw_mem_pool { - struct pipe_buffer *buffer; - - unsigned size; - unsigned offset; /* offset of first free byte */ - - struct brw_context *brw; -}; - -struct brw_cache_item { - unsigned hash; - unsigned key_size; /* for variable-sized keys */ - const void *key; - - unsigned offset; /* offset within pool's buffer */ - unsigned data_size; - - struct brw_cache_item *next; -}; - - - -struct brw_cache { - unsigned id; - - const char *name; - - struct brw_context *brw; - struct brw_mem_pool *pool; - - struct brw_cache_item **items; - unsigned size, n_items; - - unsigned key_size; /* for fixed-size keys */ - unsigned aux_size; - - unsigned last_addr; /* offset of active item */ -}; - - - - -/* Considered adding a member to this struct to document which flags - * an update might raise so that ordering of the state atoms can be - * checked or derived at runtime. Dropped the idea in favor of having - * a debug mode where the state is monitored for flags which are - * raised that have already been tested against. - */ -struct brw_tracked_state { - struct brw_state_flags dirty; - void (*update)( struct brw_context *brw ); -}; - - -/* Flags for brw->state.cache. - */ -#define CACHE_NEW_CC_VP (1< 32. Wouldn't life - * be easier if C allowed arrays of packed elements? - */ -#define ATTRIB_BIT_DWORDS ((PIPE_MAX_ATTRIBS+31)/32) - - - - -struct brw_vertex_info { - unsigned varying; /* varying:1[PIPE_MAX_ATTRIBS] */ - unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_MAX_ATTRIBS] */ -}; - - - - - -struct brw_context -{ - struct pipe_context pipe; - struct brw_winsys *winsys; - - unsigned primitive; - unsigned reduced_primitive; - - boolean emit_state_always; - - struct { - struct brw_state_flags dirty; - } state; - - - struct { - const struct pipe_blend_state *Blend; - const struct pipe_depth_stencil_alpha_state *DepthStencil; - const struct pipe_poly_stipple *PolygonStipple; - const struct pipe_rasterizer_state *Raster; - const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS]; - const struct brw_vertex_program *VertexProgram; - const struct brw_fragment_program *FragmentProgram; - - struct pipe_clip_state Clip; - struct pipe_blend_color BlendColor; - struct pipe_scissor_state Scissor; - struct pipe_viewport_state Viewport; - struct pipe_framebuffer_state FrameBuffer; - - const struct pipe_constant_buffer *Constants[2]; - const struct brw_texture *Texture[PIPE_MAX_SAMPLERS]; - } attribs; - - unsigned num_samplers; - unsigned num_textures; - - struct brw_mem_pool pool[BRW_MAX_POOL]; - struct brw_cache cache[BRW_MAX_CACHE]; - struct brw_cached_batch_item *cached_batch_items; - - struct { - - /* Arrays with buffer objects to copy non-bufferobj arrays into - * for upload: - */ - const struct pipe_vertex_buffer *vbo_array[PIPE_MAX_ATTRIBS]; - - struct brw_vertex_element_state inputs[PIPE_MAX_ATTRIBS]; - -#define BRW_NR_UPLOAD_BUFS 17 -#define BRW_UPLOAD_INIT_SIZE (128*1024) - - /* Summary of size and varying of active arrays, so we can check - * for changes to this state: - */ - struct brw_vertex_info info; - } vb; - - - unsigned hardware_dirty; - unsigned dirty; - unsigned pci_id; - /* BRW_NEW_URB_ALLOCATIONS: - */ - struct { - unsigned vsize; /* vertex size plus header in urb registers */ - unsigned csize; /* constant buffer size in urb registers */ - unsigned sfsize; /* setup data size in urb registers */ - - boolean constrained; - - unsigned nr_vs_entries; - unsigned nr_gs_entries; - unsigned nr_clip_entries; - unsigned nr_sf_entries; - unsigned nr_cs_entries; - -/* unsigned vs_size; */ -/* unsigned gs_size; */ -/* unsigned clip_size; */ -/* unsigned sf_size; */ -/* unsigned cs_size; */ - - unsigned vs_start; - unsigned gs_start; - unsigned clip_start; - unsigned sf_start; - unsigned cs_start; - } urb; - - - /* BRW_NEW_CURBE_OFFSETS: - */ - struct { - unsigned wm_start; - unsigned wm_size; - unsigned clip_start; - unsigned clip_size; - unsigned vs_start; - unsigned vs_size; - unsigned total_size; - - unsigned gs_offset; - - float *last_buf; - unsigned last_bufsz; - } curbe; - - struct { - struct brw_vs_prog_data *prog_data; - - unsigned prog_gs_offset; - unsigned state_gs_offset; - } vs; - - struct { - struct brw_gs_prog_data *prog_data; - - boolean prog_active; - unsigned prog_gs_offset; - unsigned state_gs_offset; - } gs; - - struct { - struct brw_clip_prog_data *prog_data; - - unsigned prog_gs_offset; - unsigned vp_gs_offset; - unsigned state_gs_offset; - } clip; - - - struct { - struct brw_sf_prog_data *prog_data; - - struct pipe_setup_linkage linkage; - - unsigned prog_gs_offset; - unsigned vp_gs_offset; - unsigned state_gs_offset; - } sf; - - struct { - struct brw_wm_prog_data *prog_data; - -// struct brw_wm_compiler *compile_data; - - - /** - * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER - * cache - */ - struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; - - unsigned render_surf; - unsigned nr_surfaces; - - unsigned max_threads; - struct pipe_buffer *scratch_buffer; - unsigned scratch_buffer_size; - - unsigned sampler_count; - unsigned sampler_gs_offset; - - struct brw_surface_binding_table bind; - unsigned bind_ss_offset; - - unsigned prog_gs_offset; - unsigned state_gs_offset; - } wm; - - - struct { - unsigned vp_gs_offset; - unsigned state_gs_offset; - } cc; - - - /* Used to give every program string a unique id - */ - unsigned program_id; -}; - - -#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a) - - -/*====================================================================== - * brw_vtbl.c - */ -void brw_do_flush( struct brw_context *brw, - unsigned flags ); - - -/*====================================================================== - * brw_state.c - */ -void brw_validate_state(struct brw_context *brw); -void brw_init_state(struct brw_context *brw); -void brw_destroy_state(struct brw_context *brw); - - -/*====================================================================== - * brw_tex.c - */ -void brwUpdateTextureState( struct brw_context *brw ); - - -/* brw_urb.c - */ -void brw_upload_urb_fence(struct brw_context *brw); - -void brw_upload_constant_buffer_state(struct brw_context *brw); - -void brw_init_surface_functions(struct brw_context *brw); -void brw_init_state_functions(struct brw_context *brw); -void brw_init_flush_functions(struct brw_context *brw); -void brw_init_string_functions(struct brw_context *brw); - -/*====================================================================== - * Inline conversion functions. These are better-typed than the - * macros used previously: - */ -static inline struct brw_context * -brw_context( struct pipe_context *ctx ) -{ - return (struct brw_context *)ctx; -} - -#endif - +/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + **********************************************************************/ + /* + * Authors: + * Keith Whitwell + */ + + +#ifndef BRWCONTEXT_INC +#define BRWCONTEXT_INC + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "tgsi/util/tgsi_scan.h" + +#include "brw_structs.h" +#include "brw_winsys.h" + + +/* Glossary: + * + * URB - uniform resource buffer. A mid-sized buffer which is + * partitioned between the fixed function units and used for passing + * values (vertices, primitives, constants) between them. + * + * CURBE - constant URB entry. An urb region (entry) used to hold + * constant values which the fixed function units can be instructed to + * preload into the GRF when spawining a thread. + * + * VUE - vertex URB entry. An urb entry holding a vertex and usually + * a vertex header. The header contains control information and + * things like primitive type, Begin/end flags and clip codes. + * + * PUE - primitive URB entry. An urb entry produced by the setup (SF) + * unit holding rasterization and interpolation parameters. + * + * GRF - general register file. One of several register files + * addressable by programmed threads. The inputs (r0, payload, curbe, + * urb) of the thread are preloaded to this area before the thread is + * spawned. The registers are individually 8 dwords wide and suitable + * for general usage. Registers holding thread input values are not + * special and may be overwritten. + * + * MRF - message register file. Threads communicate (and terminate) + * by sending messages. Message parameters are placed in contigous + * MRF registers. All program output is via these messages. URB + * entries are populated by sending a message to the shared URB + * function containing the new data, together with a control word, + * often an unmodified copy of R0. + * + * R0 - GRF register 0. Typically holds control information used when + * sending messages to other threads. + * + * EU or GEN4 EU: The name of the programmable subsystem of the + * i965 hardware. Threads are executed by the EU, the registers + * described above are part of the EU architecture. + * + * Fixed function units: + * + * CS - Command streamer. Notional first unit, little software + * interaction. Holds the URB entries used for constant data, ie the + * CURBEs. + * + * VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of + * this unit is responsible for pulling vertices out of vertex buffers + * in vram and injecting them into the processing pipe as VUEs. If + * enabled, it first passes them to a VS thread which is a good place + * for the driver to implement any active vertex shader. + * + * GS - Geometry Shader. This corresponds to a new DX10 concept. If + * enabled, incoming strips etc are passed to GS threads in individual + * line/triangle/point units. The GS thread may perform arbitary + * computation and emit whatever primtives with whatever vertices it + * chooses. This makes GS an excellent place to implement GL's + * unfilled polygon modes, though of course it is capable of much + * more. Additionally, GS is used to translate away primitives not + * handled by latter units, including Quads and Lineloops. + * + * CS - Clipper. Mesa's clipping algorithms are imported to run on + * this unit. The fixed function part performs cliptesting against + * the 6 fixed clipplanes and makes descisions on whether or not the + * incoming primitive needs to be passed to a thread for clipping. + * User clip planes are handled via cooperation with the VS thread. + * + * SF - Strips Fans or Setup: Triangles are prepared for + * rasterization. Interpolation coefficients are calculated. + * Flatshading and two-side lighting usually performed here. + * + * WM - Windower. Interpolation of vertex attributes performed here. + * Fragment shader implemented here. SIMD aspects of EU taken full + * advantage of, as pixels are processed in blocks of 16. + * + * CC - Color Calculator. No EU threads associated with this unit. + * Handles blending and (presumably) depth and stencil testing. + */ + +#define BRW_MAX_CURBE (32*16) + +struct brw_context; +struct brw_winsys; + + +/* Raised when we receive new state across the pipe interface: + */ +#define BRW_NEW_VIEWPORT 0x1 +#define BRW_NEW_RASTERIZER 0x2 +#define BRW_NEW_FS 0x4 +#define BRW_NEW_BLEND 0x8 +#define BRW_NEW_CLIP 0x10 +#define BRW_NEW_SCISSOR 0x20 +#define BRW_NEW_STIPPLE 0x40 +#define BRW_NEW_FRAMEBUFFER 0x80 +#define BRW_NEW_ALPHA_TEST 0x100 +#define BRW_NEW_DEPTH_STENCIL 0x200 +#define BRW_NEW_SAMPLER 0x400 +#define BRW_NEW_TEXTURE 0x800 +#define BRW_NEW_CONSTANTS 0x1000 +#define BRW_NEW_VBO 0x2000 +#define BRW_NEW_VS 0x4000 + +/* Raised for other internal events: + */ +#define BRW_NEW_URB_FENCE 0x10000 +#define BRW_NEW_PSP 0x20000 +#define BRW_NEW_CURBE_OFFSETS 0x40000 +#define BRW_NEW_REDUCED_PRIMITIVE 0x80000 +#define BRW_NEW_PRIMITIVE 0x100000 +#define BRW_NEW_SCENE 0x200000 +#define BRW_NEW_SF_LINKAGE 0x400000 + +extern int BRW_DEBUG; + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_PRIMS 0x8 +#define DEBUG_VERTS 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_DRI 0x80 +#define DEBUG_DMA 0x100 +#define DEBUG_SANITY 0x200 +#define DEBUG_SYNC 0x400 +#define DEBUG_SLEEP 0x800 +#define DEBUG_PIXEL 0x1000 +#define DEBUG_STATS 0x2000 +#define DEBUG_TILE 0x4000 +#define DEBUG_SINGLE_THREAD 0x8000 +#define DEBUG_WM 0x10000 +#define DEBUG_URB 0x20000 +#define DEBUG_VS 0x40000 +#define DEBUG_BATCH 0x80000 +#define DEBUG_BUFMGR 0x100000 +#define DEBUG_BLIT 0x200000 +#define DEBUG_REGION 0x400000 +#define DEBUG_MIPTREE 0x800000 + +#define DBG(...) do { \ + if (BRW_DEBUG & FILE_DEBUG_FLAG) \ + debug_printf(__VA_ARGS__); \ +} while(0) + +#define PRINT(...) do { \ + debug_printf(brw->pipe.winsys, __VA_ARGS__); \ +} while(0) + +struct brw_state_flags { + unsigned cache; + unsigned brw; +}; + + +struct brw_vertex_program { + struct pipe_shader_state program; + struct tgsi_shader_info info; + int id; +}; + + +struct brw_fragment_program { + struct pipe_shader_state program; + struct tgsi_shader_info info; + + boolean UsesDepth; /* XXX add this to tgsi_shader_info? */ + int id; +}; + + +struct pipe_setup_linkage { + struct { + unsigned vp_output:5; + unsigned interp_mode:4; + unsigned bf_vp_output:5; + } fp_input[PIPE_MAX_SHADER_INPUTS]; + + unsigned fp_input_count:5; + unsigned max_vp_output:5; +}; + + + +struct brw_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ + +struct brw_wm_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + + unsigned first_curbe_grf; + unsigned total_grf; + unsigned total_scratch; + + /* Internally generated constants for the CURBE. These are loaded + * ahead of the data from the constant buffer. + */ + const float internal_const[8]; + unsigned nr_internal_consts; + unsigned max_const; + + boolean error; +}; + +struct brw_sf_prog_data { + unsigned urb_read_length; + unsigned total_grf; + + /* Each vertex may have upto 12 attributes, 4 components each, + * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11 + * rows. + * + * Actually we use 4 for each, so call it 12 rows. + */ + unsigned urb_entry_size; +}; + +struct brw_clip_prog_data { + unsigned curb_read_length; /* user planes? */ + unsigned clip_mode; + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_gs_prog_data { + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_vs_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + unsigned total_grf; + unsigned outputs_written; + + unsigned inputs_read; + + unsigned max_const; + + float imm_buf[PIPE_MAX_CONSTANT][4]; + unsigned num_imm; + unsigned num_consts; + + /* Used for calculating urb partitions: + */ + unsigned urb_entry_size; +}; + + +#define BRW_MAX_TEX_UNIT 8 +#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 + +/* Create a fixed sized struct for caching binding tables: + */ +struct brw_surface_binding_table { + unsigned surf_ss_offset[BRW_WM_MAX_SURF]; +}; + + +struct brw_cache; + +struct brw_mem_pool { + struct pipe_buffer *buffer; + + unsigned size; + unsigned offset; /* offset of first free byte */ + + struct brw_context *brw; +}; + +struct brw_cache_item { + unsigned hash; + unsigned key_size; /* for variable-sized keys */ + const void *key; + + unsigned offset; /* offset within pool's buffer */ + unsigned data_size; + + struct brw_cache_item *next; +}; + + + +struct brw_cache { + unsigned id; + + const char *name; + + struct brw_context *brw; + struct brw_mem_pool *pool; + + struct brw_cache_item **items; + unsigned size, n_items; + + unsigned key_size; /* for fixed-size keys */ + unsigned aux_size; + + unsigned last_addr; /* offset of active item */ +}; + + + + +/* Considered adding a member to this struct to document which flags + * an update might raise so that ordering of the state atoms can be + * checked or derived at runtime. Dropped the idea in favor of having + * a debug mode where the state is monitored for flags which are + * raised that have already been tested against. + */ +struct brw_tracked_state { + struct brw_state_flags dirty; + void (*update)( struct brw_context *brw ); +}; + + +/* Flags for brw->state.cache. + */ +#define CACHE_NEW_CC_VP (1< 32. Wouldn't life + * be easier if C allowed arrays of packed elements? + */ +#define ATTRIB_BIT_DWORDS ((PIPE_MAX_ATTRIBS+31)/32) + + + + +struct brw_vertex_info { + unsigned varying; /* varying:1[PIPE_MAX_ATTRIBS] */ + unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_MAX_ATTRIBS] */ +}; + + + + + +struct brw_context +{ + struct pipe_context pipe; + struct brw_winsys *winsys; + + unsigned primitive; + unsigned reduced_primitive; + + boolean emit_state_always; + + struct { + struct brw_state_flags dirty; + } state; + + + struct { + const struct pipe_blend_state *Blend; + const struct pipe_depth_stencil_alpha_state *DepthStencil; + const struct pipe_poly_stipple *PolygonStipple; + const struct pipe_rasterizer_state *Raster; + const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS]; + const struct brw_vertex_program *VertexProgram; + const struct brw_fragment_program *FragmentProgram; + + struct pipe_clip_state Clip; + struct pipe_blend_color BlendColor; + struct pipe_scissor_state Scissor; + struct pipe_viewport_state Viewport; + struct pipe_framebuffer_state FrameBuffer; + + const struct pipe_constant_buffer *Constants[2]; + const struct brw_texture *Texture[PIPE_MAX_SAMPLERS]; + } attribs; + + unsigned num_samplers; + unsigned num_textures; + + struct brw_mem_pool pool[BRW_MAX_POOL]; + struct brw_cache cache[BRW_MAX_CACHE]; + struct brw_cached_batch_item *cached_batch_items; + + struct { + + /* Arrays with buffer objects to copy non-bufferobj arrays into + * for upload: + */ + const struct pipe_vertex_buffer *vbo_array[PIPE_MAX_ATTRIBS]; + + struct brw_vertex_element_state inputs[PIPE_MAX_ATTRIBS]; + +#define BRW_NR_UPLOAD_BUFS 17 +#define BRW_UPLOAD_INIT_SIZE (128*1024) + + /* Summary of size and varying of active arrays, so we can check + * for changes to this state: + */ + struct brw_vertex_info info; + } vb; + + + unsigned hardware_dirty; + unsigned dirty; + unsigned pci_id; + /* BRW_NEW_URB_ALLOCATIONS: + */ + struct { + unsigned vsize; /* vertex size plus header in urb registers */ + unsigned csize; /* constant buffer size in urb registers */ + unsigned sfsize; /* setup data size in urb registers */ + + boolean constrained; + + unsigned nr_vs_entries; + unsigned nr_gs_entries; + unsigned nr_clip_entries; + unsigned nr_sf_entries; + unsigned nr_cs_entries; + +/* unsigned vs_size; */ +/* unsigned gs_size; */ +/* unsigned clip_size; */ +/* unsigned sf_size; */ +/* unsigned cs_size; */ + + unsigned vs_start; + unsigned gs_start; + unsigned clip_start; + unsigned sf_start; + unsigned cs_start; + } urb; + + + /* BRW_NEW_CURBE_OFFSETS: + */ + struct { + unsigned wm_start; + unsigned wm_size; + unsigned clip_start; + unsigned clip_size; + unsigned vs_start; + unsigned vs_size; + unsigned total_size; + + unsigned gs_offset; + + float *last_buf; + unsigned last_bufsz; + } curbe; + + struct { + struct brw_vs_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } vs; + + struct { + struct brw_gs_prog_data *prog_data; + + boolean prog_active; + unsigned prog_gs_offset; + unsigned state_gs_offset; + } gs; + + struct { + struct brw_clip_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } clip; + + + struct { + struct brw_sf_prog_data *prog_data; + + struct pipe_setup_linkage linkage; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } sf; + + struct { + struct brw_wm_prog_data *prog_data; + +// struct brw_wm_compiler *compile_data; + + + /** + * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER + * cache + */ + struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; + + unsigned render_surf; + unsigned nr_surfaces; + + unsigned max_threads; + struct pipe_buffer *scratch_buffer; + unsigned scratch_buffer_size; + + unsigned sampler_count; + unsigned sampler_gs_offset; + + struct brw_surface_binding_table bind; + unsigned bind_ss_offset; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } wm; + + + struct { + unsigned vp_gs_offset; + unsigned state_gs_offset; + } cc; + + + /* Used to give every program string a unique id + */ + unsigned program_id; +}; + + +#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a) + + +/*====================================================================== + * brw_vtbl.c + */ +void brw_do_flush( struct brw_context *brw, + unsigned flags ); + + +/*====================================================================== + * brw_state.c + */ +void brw_validate_state(struct brw_context *brw); +void brw_init_state(struct brw_context *brw); +void brw_destroy_state(struct brw_context *brw); + + +/*====================================================================== + * brw_tex.c + */ +void brwUpdateTextureState( struct brw_context *brw ); + + +/* brw_urb.c + */ +void brw_upload_urb_fence(struct brw_context *brw); + +void brw_upload_constant_buffer_state(struct brw_context *brw); + +void brw_init_surface_functions(struct brw_context *brw); +void brw_init_state_functions(struct brw_context *brw); +void brw_init_flush_functions(struct brw_context *brw); +void brw_init_string_functions(struct brw_context *brw); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static inline struct brw_context * +brw_context( struct pipe_context *ctx ) +{ + return (struct brw_context *)ctx; +} + +#endif + diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index ac243b7e4f..caeeba4630 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -1,469 +1,469 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Zack Rusin - * Keith Whitwell - */ - - -#include "pipe/p_winsys.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_dump.h" -#include "tgsi/util/tgsi_parse.h" - -#include "brw_context.h" -#include "brw_defines.h" -#include "brw_state.h" -#include "brw_draw.h" - - -#define DUP( TYPE, VAL ) \ -do { \ - struct TYPE *x = malloc(sizeof(*x)); \ - memcpy(x, VAL, sizeof(*x) ); \ - return x; \ -} while (0) - -/************************************************************************ - * Blend - */ -static void * -brw_create_blend_state(struct pipe_context *pipe, - const struct pipe_blend_state *blend) -{ - DUP( pipe_blend_state, blend ); -} - -static void brw_bind_blend_state(struct pipe_context *pipe, - void *blend) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Blend = (struct pipe_blend_state*)blend; - brw->state.dirty.brw |= BRW_NEW_BLEND; -} - - -static void brw_delete_blend_state(struct pipe_context *pipe, void *blend) -{ - free(blend); -} - -static void brw_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.BlendColor = *blend_color; - - brw->state.dirty.brw |= BRW_NEW_BLEND; -} - -/************************************************************************ - * Sampler - */ - -static void * -brw_create_sampler_state(struct pipe_context *pipe, - const struct pipe_sampler_state *sampler) -{ - DUP( pipe_sampler_state, sampler ); -} - -static void brw_bind_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) -{ - struct brw_context *brw = brw_context(pipe); - - assert(num <= PIPE_MAX_SAMPLERS); - - /* Check for no-op */ - if (num == brw->num_samplers && - !memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *))) - return; - - memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *)); - memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) * - sizeof(void *)); - - brw->num_samplers = num; - - brw->state.dirty.brw |= BRW_NEW_SAMPLER; -} - -static void brw_delete_sampler_state(struct pipe_context *pipe, - void *sampler) -{ - free(sampler); -} - - -/************************************************************************ - * Depth stencil - */ - -static void * -brw_create_depth_stencil_state(struct pipe_context *pipe, - const struct pipe_depth_stencil_alpha_state *depth_stencil) -{ - DUP( pipe_depth_stencil_alpha_state, depth_stencil ); -} - -static void brw_bind_depth_stencil_state(struct pipe_context *pipe, - void *depth_stencil) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; - - brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL; -} - -static void brw_delete_depth_stencil_state(struct pipe_context *pipe, - void *depth_stencil) -{ - free(depth_stencil); -} - -/************************************************************************ - * Scissor - */ -static void brw_set_scissor_state( struct pipe_context *pipe, - const struct pipe_scissor_state *scissor ) -{ - struct brw_context *brw = brw_context(pipe); - - memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) ); - brw->state.dirty.brw |= BRW_NEW_SCISSOR; -} - - -/************************************************************************ - * Stipple - */ - -static void brw_set_polygon_stipple( struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple ) -{ -} - - -/************************************************************************ - * Fragment shader - */ - -static void * brw_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *shader) -{ - struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program); - - brw_fp->program.tokens = tgsi_dup_tokens(shader->tokens); - brw_fp->id = brw_context(pipe)->program_id++; - - tgsi_scan_shader(shader->tokens, &brw_fp->info); - -#if 0 - brw_shader_info(shader->tokens, - &brw_fp->info2); -#endif - - tgsi_dump(shader->tokens, 0); - - - return (void *)brw_fp; -} - -static void brw_bind_fs_state(struct pipe_context *pipe, void *shader) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader; - brw->state.dirty.brw |= BRW_NEW_FS; -} - -static void brw_delete_fs_state(struct pipe_context *pipe, void *shader) -{ - struct brw_fragment_program *brw_fp = (struct brw_fragment_program *) shader; - - FREE((void *) brw_fp->program.tokens); - FREE(brw_fp); -} - - -/************************************************************************ - * Vertex shader and other TNL state - */ - -static void *brw_create_vs_state(struct pipe_context *pipe, - const struct pipe_shader_state *shader) -{ - struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program); - - brw_vp->program.tokens = tgsi_dup_tokens(shader->tokens); - brw_vp->id = brw_context(pipe)->program_id++; - - tgsi_scan_shader(shader->tokens, &brw_vp->info); - -#if 0 - brw_shader_info(shader->tokens, - &brw_vp->info2); -#endif - tgsi_dump(shader->tokens, 0); - - return (void *)brw_vp; -} - -static void brw_bind_vs_state(struct pipe_context *pipe, void *vs) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.VertexProgram = (struct brw_vertex_program *)vs; - brw->state.dirty.brw |= BRW_NEW_VS; - - debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n"); -} - -static void brw_delete_vs_state(struct pipe_context *pipe, void *shader) -{ - struct brw_vertex_program *brw_vp = (struct brw_vertex_program *) shader; - - FREE((void *) brw_vp->program.tokens); - FREE(brw_vp); -} - - -static void brw_set_clip_state( struct pipe_context *pipe, - const struct pipe_clip_state *clip ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Clip = *clip; -} - - -static void brw_set_viewport_state( struct pipe_context *pipe, - const struct pipe_viewport_state *viewport ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Viewport = *viewport; /* struct copy */ - brw->state.dirty.brw |= BRW_NEW_VIEWPORT; - - /* pass the viewport info to the draw module */ - //draw_set_viewport_state(brw->draw, viewport); -} - - -static void brw_set_vertex_buffers(struct pipe_context *pipe, - unsigned count, - const struct pipe_vertex_buffer *buffers) -{ - struct brw_context *brw = brw_context(pipe); - memcpy(brw->vb.vbo_array, buffers, count * sizeof(buffers[0])); -} - -static void brw_set_vertex_elements(struct pipe_context *pipe, - unsigned count, - const struct pipe_vertex_element *elements) -{ - /* flush ? */ - struct brw_context *brw = brw_context(pipe); - uint i; - - assert(count <= PIPE_MAX_ATTRIBS); - - for (i = 0; i < count; i++) { - struct brw_vertex_element_state el; - memset(&el, 0, sizeof(el)); - - el.ve0.src_offset = elements[i].src_offset; - el.ve0.src_format = brw_translate_surface_format(elements[i].src_format); - el.ve0.valid = 1; - el.ve0.vertex_buffer_index = elements[i].vertex_buffer_index; - - el.ve1.dst_offset = i * 4; - - el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; - el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; - - switch (elements[i].nr_components) { - case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; - case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; - case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; - break; - } - - brw->vb.inputs[i] = el; - } -} - - - -/************************************************************************ - * Constant buffers - */ - -static void brw_set_constant_buffer(struct pipe_context *pipe, - uint shader, uint index, - const struct pipe_constant_buffer *buf) -{ - struct brw_context *brw = brw_context(pipe); - - assert(buf == 0 || index == 0); - - brw->attribs.Constants[shader] = buf; - brw->state.dirty.brw |= BRW_NEW_CONSTANTS; -} - - -/************************************************************************ - * Texture surfaces - */ - - -static void brw_set_sampler_textures(struct pipe_context *pipe, - unsigned num, - struct pipe_texture **texture) -{ - struct brw_context *brw = brw_context(pipe); - uint i; - - assert(num <= PIPE_MAX_SAMPLERS); - - /* Check for no-op */ - if (num == brw->num_textures && - !memcmp(brw->attribs.Texture, texture, num * - sizeof(struct pipe_texture *))) - return; - - for (i = 0; i < num; i++) - pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], - texture[i]); - - for (i = num; i < brw->num_textures; i++) - pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], - NULL); - - brw->num_textures = num; - - brw->state.dirty.brw |= BRW_NEW_TEXTURE; -} - - -/************************************************************************ - * Render targets, etc - */ - -static void brw_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.FrameBuffer = *fb; /* struct copy */ - - brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER; -} - - - -/************************************************************************ - * Rasterizer state - */ - -static void * -brw_create_rasterizer_state(struct pipe_context *pipe, - const struct pipe_rasterizer_state *rasterizer) -{ - DUP(pipe_rasterizer_state, rasterizer); -} - -static void brw_bind_rasterizer_state( struct pipe_context *pipe, - void *setup ) -{ - struct brw_context *brw = brw_context(pipe); - - brw->attribs.Raster = (struct pipe_rasterizer_state *)setup; - - /* Also pass-through to draw module: - */ - //draw_set_rasterizer_state(brw->draw, setup); - - brw->state.dirty.brw |= BRW_NEW_RASTERIZER; -} - -static void brw_delete_rasterizer_state(struct pipe_context *pipe, - void *setup) -{ - free(setup); -} - - - -void -brw_init_state_functions( struct brw_context *brw ) -{ - brw->pipe.create_blend_state = brw_create_blend_state; - brw->pipe.bind_blend_state = brw_bind_blend_state; - brw->pipe.delete_blend_state = brw_delete_blend_state; - - brw->pipe.create_sampler_state = brw_create_sampler_state; - brw->pipe.bind_sampler_states = brw_bind_sampler_states; - brw->pipe.delete_sampler_state = brw_delete_sampler_state; - - brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; - brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; - brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; - - brw->pipe.create_rasterizer_state = brw_create_rasterizer_state; - brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state; - brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state; - brw->pipe.create_fs_state = brw_create_fs_state; - brw->pipe.bind_fs_state = brw_bind_fs_state; - brw->pipe.delete_fs_state = brw_delete_fs_state; - brw->pipe.create_vs_state = brw_create_vs_state; - brw->pipe.bind_vs_state = brw_bind_vs_state; - brw->pipe.delete_vs_state = brw_delete_vs_state; - - brw->pipe.set_blend_color = brw_set_blend_color; - brw->pipe.set_clip_state = brw_set_clip_state; - brw->pipe.set_constant_buffer = brw_set_constant_buffer; - brw->pipe.set_framebuffer_state = brw_set_framebuffer_state; - -// brw->pipe.set_feedback_state = brw_set_feedback_state; -// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer; - - brw->pipe.set_polygon_stipple = brw_set_polygon_stipple; - brw->pipe.set_scissor_state = brw_set_scissor_state; - brw->pipe.set_sampler_textures = brw_set_sampler_textures; - brw->pipe.set_viewport_state = brw_set_viewport_state; - brw->pipe.set_vertex_buffers = brw_set_vertex_buffers; - brw->pipe.set_vertex_elements = brw_set_vertex_elements; -} +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Zack Rusin + * Keith Whitwell + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_dump.h" +#include "tgsi/util/tgsi_parse.h" + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_state.h" +#include "brw_draw.h" + + +#define DUP( TYPE, VAL ) \ +do { \ + struct TYPE *x = malloc(sizeof(*x)); \ + memcpy(x, VAL, sizeof(*x) ); \ + return x; \ +} while (0) + +/************************************************************************ + * Blend + */ +static void * +brw_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + DUP( pipe_blend_state, blend ); +} + +static void brw_bind_blend_state(struct pipe_context *pipe, + void *blend) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Blend = (struct pipe_blend_state*)blend; + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + + +static void brw_delete_blend_state(struct pipe_context *pipe, void *blend) +{ + free(blend); +} + +static void brw_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.BlendColor = *blend_color; + + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + +/************************************************************************ + * Sampler + */ + +static void * +brw_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + DUP( pipe_sampler_state, sampler ); +} + +static void brw_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct brw_context *brw = brw_context(pipe); + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == brw->num_samplers && + !memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *))) + return; + + memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *)); + memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) * + sizeof(void *)); + + brw->num_samplers = num; + + brw->state.dirty.brw |= BRW_NEW_SAMPLER; +} + +static void brw_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + free(sampler); +} + + +/************************************************************************ + * Depth stencil + */ + +static void * +brw_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + DUP( pipe_depth_stencil_alpha_state, depth_stencil ); +} + +static void brw_bind_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; + + brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL; +} + +static void brw_delete_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + free(depth_stencil); +} + +/************************************************************************ + * Scissor + */ +static void brw_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct brw_context *brw = brw_context(pipe); + + memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) ); + brw->state.dirty.brw |= BRW_NEW_SCISSOR; +} + + +/************************************************************************ + * Stipple + */ + +static void brw_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ +} + + +/************************************************************************ + * Fragment shader + */ + +static void * brw_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program); + + brw_fp->program.tokens = tgsi_dup_tokens(shader->tokens); + brw_fp->id = brw_context(pipe)->program_id++; + + tgsi_scan_shader(shader->tokens, &brw_fp->info); + +#if 0 + brw_shader_info(shader->tokens, + &brw_fp->info2); +#endif + + tgsi_dump(shader->tokens, 0); + + + return (void *)brw_fp; +} + +static void brw_bind_fs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader; + brw->state.dirty.brw |= BRW_NEW_FS; +} + +static void brw_delete_fs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_fragment_program *brw_fp = (struct brw_fragment_program *) shader; + + FREE((void *) brw_fp->program.tokens); + FREE(brw_fp); +} + + +/************************************************************************ + * Vertex shader and other TNL state + */ + +static void *brw_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program); + + brw_vp->program.tokens = tgsi_dup_tokens(shader->tokens); + brw_vp->id = brw_context(pipe)->program_id++; + + tgsi_scan_shader(shader->tokens, &brw_vp->info); + +#if 0 + brw_shader_info(shader->tokens, + &brw_vp->info2); +#endif + tgsi_dump(shader->tokens, 0); + + return (void *)brw_vp; +} + +static void brw_bind_vs_state(struct pipe_context *pipe, void *vs) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.VertexProgram = (struct brw_vertex_program *)vs; + brw->state.dirty.brw |= BRW_NEW_VS; + + debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n"); +} + +static void brw_delete_vs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_vertex_program *brw_vp = (struct brw_vertex_program *) shader; + + FREE((void *) brw_vp->program.tokens); + FREE(brw_vp); +} + + +static void brw_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Clip = *clip; +} + + +static void brw_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Viewport = *viewport; /* struct copy */ + brw->state.dirty.brw |= BRW_NEW_VIEWPORT; + + /* pass the viewport info to the draw module */ + //draw_set_viewport_state(brw->draw, viewport); +} + + +static void brw_set_vertex_buffers(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_buffer *buffers) +{ + struct brw_context *brw = brw_context(pipe); + memcpy(brw->vb.vbo_array, buffers, count * sizeof(buffers[0])); +} + +static void brw_set_vertex_elements(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_element *elements) +{ + /* flush ? */ + struct brw_context *brw = brw_context(pipe); + uint i; + + assert(count <= PIPE_MAX_ATTRIBS); + + for (i = 0; i < count; i++) { + struct brw_vertex_element_state el; + memset(&el, 0, sizeof(el)); + + el.ve0.src_offset = elements[i].src_offset; + el.ve0.src_format = brw_translate_surface_format(elements[i].src_format); + el.ve0.valid = 1; + el.ve0.vertex_buffer_index = elements[i].vertex_buffer_index; + + el.ve1.dst_offset = i * 4; + + el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; + + switch (elements[i].nr_components) { + case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; + case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; + case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; + break; + } + + brw->vb.inputs[i] = el; + } +} + + + +/************************************************************************ + * Constant buffers + */ + +static void brw_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct brw_context *brw = brw_context(pipe); + + assert(buf == 0 || index == 0); + + brw->attribs.Constants[shader] = buf; + brw->state.dirty.brw |= BRW_NEW_CONSTANTS; +} + + +/************************************************************************ + * Texture surfaces + */ + + +static void brw_set_sampler_textures(struct pipe_context *pipe, + unsigned num, + struct pipe_texture **texture) +{ + struct brw_context *brw = brw_context(pipe); + uint i; + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == brw->num_textures && + !memcmp(brw->attribs.Texture, texture, num * + sizeof(struct pipe_texture *))) + return; + + for (i = 0; i < num; i++) + pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], + texture[i]); + + for (i = num; i < brw->num_textures; i++) + pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], + NULL); + + brw->num_textures = num; + + brw->state.dirty.brw |= BRW_NEW_TEXTURE; +} + + +/************************************************************************ + * Render targets, etc + */ + +static void brw_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FrameBuffer = *fb; /* struct copy */ + + brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER; +} + + + +/************************************************************************ + * Rasterizer state + */ + +static void * +brw_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *rasterizer) +{ + DUP(pipe_rasterizer_state, rasterizer); +} + +static void brw_bind_rasterizer_state( struct pipe_context *pipe, + void *setup ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Raster = (struct pipe_rasterizer_state *)setup; + + /* Also pass-through to draw module: + */ + //draw_set_rasterizer_state(brw->draw, setup); + + brw->state.dirty.brw |= BRW_NEW_RASTERIZER; +} + +static void brw_delete_rasterizer_state(struct pipe_context *pipe, + void *setup) +{ + free(setup); +} + + + +void +brw_init_state_functions( struct brw_context *brw ) +{ + brw->pipe.create_blend_state = brw_create_blend_state; + brw->pipe.bind_blend_state = brw_bind_blend_state; + brw->pipe.delete_blend_state = brw_delete_blend_state; + + brw->pipe.create_sampler_state = brw_create_sampler_state; + brw->pipe.bind_sampler_states = brw_bind_sampler_states; + brw->pipe.delete_sampler_state = brw_delete_sampler_state; + + brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; + brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; + brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; + + brw->pipe.create_rasterizer_state = brw_create_rasterizer_state; + brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state; + brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state; + brw->pipe.create_fs_state = brw_create_fs_state; + brw->pipe.bind_fs_state = brw_bind_fs_state; + brw->pipe.delete_fs_state = brw_delete_fs_state; + brw->pipe.create_vs_state = brw_create_vs_state; + brw->pipe.bind_vs_state = brw_bind_vs_state; + brw->pipe.delete_vs_state = brw_delete_vs_state; + + brw->pipe.set_blend_color = brw_set_blend_color; + brw->pipe.set_clip_state = brw_set_clip_state; + brw->pipe.set_constant_buffer = brw_set_constant_buffer; + brw->pipe.set_framebuffer_state = brw_set_framebuffer_state; + +// brw->pipe.set_feedback_state = brw_set_feedback_state; +// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer; + + brw->pipe.set_polygon_stipple = brw_set_polygon_stipple; + brw->pipe.set_scissor_state = brw_set_scissor_state; + brw->pipe.set_sampler_textures = brw_set_sampler_textures; + brw->pipe.set_viewport_state = brw_set_viewport_state; + brw->pipe.set_vertex_buffers = brw_set_vertex_buffers; + brw->pipe.set_vertex_elements = brw_set_vertex_elements; +} -- cgit v1.2.3 From a0e2955a16a8a04afe7f84b1c8551211542a6fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 27 May 2008 00:13:57 +0900 Subject: pipebuffer: Allow slab allocations of buffers of inequal size. --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index 45ba158a4d..b9dff09804 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -312,8 +312,8 @@ pb_slab_manager_create_buffer(struct pb_manager *_mgr, struct list_head *list; /* check size */ - assert(size == mgr->bufSize); - if(size != mgr->bufSize) + assert(size <= mgr->bufSize); + if(size > mgr->bufSize) return NULL; /* check if we can provide the requested alignment */ -- cgit v1.2.3 From 35cfd0a4900750f67cba4f64929ff3347f0bd46f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 27 May 2008 00:19:41 +0900 Subject: pipebuffer: Malloc buffer provider. Simple wrapper around pb_malloc_buffer_create for convenience. --- .../auxiliary/pipebuffer/pb_buffer_malloc.c | 33 +++++++++++++++++++++- src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 9 ++++++ 2 files changed, 41 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c index 9e8244f909..6c3502eea7 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c @@ -30,13 +30,14 @@ * Implementation of malloc-based buffers to store data that can't be processed * by the hardware. * - * \author José Fonseca + * \author Jose Fonseca */ #include "pipe/p_debug.h" #include "pipe/p_util.h" #include "pb_buffer.h" +#include "pb_bufmgr.h" struct malloc_buffer @@ -125,3 +126,33 @@ pb_malloc_buffer_create(size_t size, return &buf->base; } + + +static struct pb_buffer * +pb_malloc_buffer_create_buffer(struct pb_manager *mgr, + size_t size, + const struct pb_desc *desc) +{ + return pb_malloc_buffer_create(size, desc); +} + + +static void +pb_malloc_bufmgr_destroy(struct pb_manager *mgr) +{ + /* No-op */ +} + + +static struct pb_manager +pb_malloc_bufmgr = { + pb_malloc_buffer_create_buffer, + pb_malloc_bufmgr_destroy +}; + + +struct pb_manager * +pb_malloc_bufmgr_create(void) +{ + return &pb_malloc_bufmgr; +} diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index f6cc7a525b..4a922d16c1 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -79,6 +79,15 @@ struct pb_manager }; +/** + * Malloc buffer provider. + * + * Simple wrapper around pb_malloc_buffer_create for convenience. + */ +struct pb_manager * +pb_malloc_bufmgr_create(void); + + /** * Static buffer pool sub-allocator. * -- cgit v1.2.3 From 529762d5df6d9427f9fa0927e38b9886e412a6bc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 26 May 2008 18:29:47 +0100 Subject: draw: add missing break --- src/gallium/auxiliary/draw/draw_pt_emit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 22a83ec78f..e21af3d287 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -100,6 +100,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, case EMIT_4UB: output_format = PIPE_FORMAT_B8G8R8A8_UNORM; emit_sz = 4 * sizeof(ubyte); + break; default: assert(0); output_format = PIPE_FORMAT_NONE; -- cgit v1.2.3 From d80c24a81a9a46c132fe877dde6919a57cacf8c0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 26 May 2008 18:37:34 +0100 Subject: draw: defensively reset render primitive, which can get clobbered by clipping --- src/gallium/auxiliary/draw/draw_pt_emit.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index e21af3d287..01396a749e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -40,6 +40,7 @@ struct pt_emit { struct translate *translate; struct translate_cache *cache; + unsigned prim; }; void draw_pt_emit_prepare( struct pt_emit *emit, @@ -51,8 +52,14 @@ void draw_pt_emit_prepare( struct pt_emit *emit, struct translate_key hw_key; unsigned i; boolean ok; + - ok = draw->render->set_primitive(draw->render, prim); + /* XXX: may need to defensively reset this later on as clipping can + * clobber this state in the render backend. + */ + emit->prim = prim; + + ok = draw->render->set_primitive(draw->render, emit->prim); if (!ok) { assert(0); return; @@ -145,6 +152,14 @@ void draw_pt_emit( struct pt_emit *emit, */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + /* XXX: and work out some way to coordinate the render primitive + * between vbuf.c and here... + */ + if (!draw->render->set_primitive(draw->render, emit->prim)) { + assert(0); + return; + } + hw_verts = render->allocate_vertices(render, (ushort)translate->key.output_stride, (ushort)vertex_count); -- cgit v1.2.3 From 93bfc94c351a2eafd43ac7a20b362d969f98d86a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 26 May 2008 18:54:35 +0100 Subject: draw: defensively reset render primitive some more --- src/gallium/auxiliary/draw/draw_pt_emit.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 01396a749e..d0c9577ee6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -213,6 +213,14 @@ void draw_pt_emit_linear(struct pt_emit *emit, */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + /* XXX: and work out some way to coordinate the render primitive + * between vbuf.c and here... + */ + if (!draw->render->set_primitive(draw->render, emit->prim)) { + assert(0); + return; + } + hw_verts = render->allocate_vertices(render, (ushort)translate->key.output_stride, (ushort)count); -- cgit v1.2.3 From aa16e3a2750993afdba16c24237bb6d8d8e4d91a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 26 May 2008 19:10:44 +0100 Subject: draw: defensively flush pipeline backend when setting primitive --- src/gallium/auxiliary/draw/draw_pt_emit.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index d0c9577ee6..e37256b1ff 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -53,6 +53,10 @@ void draw_pt_emit_prepare( struct pt_emit *emit, unsigned i; boolean ok; + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + /* XXX: may need to defensively reset this later on as clipping can * clobber this state in the render backend. -- cgit v1.2.3 From 4e2567f0ab6afd701bea4c35e388663e90f5cb6c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 10:42:58 +0100 Subject: draw: some possible fixes for spilling --- src/gallium/auxiliary/draw/draw_vs_aos.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 1622358ae1..99630e4f75 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -253,6 +253,7 @@ struct x86_reg aos_get_xmm_reg( struct aos_compilation *cp ) cp->xmm[oldest].file = TGSI_FILE_NULL; cp->xmm[oldest].idx = 0; + cp->xmm[oldest].dirty = 0; cp->xmm[oldest].last_used = cp->insn_counter; return x86_make_reg(file_XMM, oldest); } @@ -284,24 +285,18 @@ void aos_adopt_xmm_reg( struct aos_compilation *cp, return; } - /* If this xmm reg is already holding this shader reg, just update - * last_used, and don't clobber the dirty flag... - */ - if (cp->xmm[reg.idx].file == file && - cp->xmm[reg.idx].idx == idx) - { - cp->xmm[reg.idx].dirty |= dirty; - cp->xmm[reg.idx].last_used = cp->insn_counter; - return; - } - /* If any xmm reg thinks it holds this shader reg, break the * illusion. */ for (i = 0; i < 8; i++) { if (cp->xmm[i].file == file && - cp->xmm[i].idx == idx) { + cp->xmm[i].idx == idx) + { + /* If an xmm reg is already holding this shader reg, take into account its + * dirty flag... + */ + dirty |= cp->xmm[i].dirty; aos_release_xmm_reg(cp, i); } } @@ -1989,6 +1984,17 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, debug_printf("\n"); } + + { + unsigned i; + for (i = 0; i < 8; i++) { + if (cp.xmm[i].file != TGSI_FILE_OUTPUT) { + cp.xmm[i].file = TGSI_FILE_NULL; + cp.xmm[i].dirty = 0; + } + } + } + if (cp.error) goto fail; -- cgit v1.2.3 From 5dc44184fa9f07465b7ff2be94394c55392ce5e9 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 11:10:50 +0100 Subject: draw: fix writemask/shufps confusion --- src/gallium/auxiliary/draw/draw_vs_aos.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 99630e4f75..434bd2a9ab 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -687,17 +687,18 @@ static void store_dest( struct aos_compilation *cp, sse_movss(cp->func, dst, get_xmm(cp, result)); break; - case TGSI_WRITEMASK_XY: + case TGSI_WRITEMASK_ZW: sse_shufps(cp->func, dst, get_xmm(cp, result), SHUF(X, Y, Z, W)); break; - case TGSI_WRITEMASK_ZW: + case TGSI_WRITEMASK_XY: result = get_xmm_writable(cp, result); sse_shufps(cp->func, result, dst, SHUF(X, Y, Z, W)); dst = result; break; case TGSI_WRITEMASK_YZW: + result = get_xmm_writable(cp, result); sse_movss(cp->func, result, dst); dst = result; break; @@ -891,7 +892,7 @@ static void emit_print( struct aos_compilation *cp, unsigned idx ) { struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); - struct x86_reg arg = get_reg_ptr( cp, file, idx ); + struct x86_reg arg = aos_get_shader_reg_ptr( cp, file, idx ); unsigned i; /* There shouldn't be anything on the x87 stack. Can add this -- cgit v1.2.3 From adaaa29218f1babad874f50681ca971fdd3b8a40 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 11:12:42 +0100 Subject: tgsi: export utils for dumping individual instructions --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 24 ++++++++++++------------ src/gallium/auxiliary/tgsi/util/tgsi_dump.h | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 4c65ffd780..648afa2a51 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -539,9 +539,9 @@ static const char *TGSI_MODULATES[] = "MODULATE_EIGHTH" }; -static void -dump_declaration_short( - struct tgsi_full_declaration *decl ) +void +tgsi_dump_declaration( + const struct tgsi_full_declaration *decl ) { TXT( "\nDCL " ); ENM( decl->Declaration.File, TGSI_FILES_SHORT ); @@ -672,9 +672,9 @@ dump_declaration_verbose( } } -static void -dump_immediate_short( - struct tgsi_full_immediate *imm ) +void +tgsi_dump_immediate( + const struct tgsi_full_immediate *imm ) { unsigned i; @@ -727,9 +727,9 @@ dump_immediate_verbose( } } -static void -dump_instruction_short( - struct tgsi_full_instruction *inst, +void +tgsi_dump_instruction( + const struct tgsi_full_instruction *inst, unsigned instno ) { unsigned i; @@ -1281,17 +1281,17 @@ tgsi_dump( switch( parse.FullToken.Token.Type ) { case TGSI_TOKEN_TYPE_DECLARATION: - dump_declaration_short( + tgsi_dump_declaration( &parse.FullToken.FullDeclaration ); break; case TGSI_TOKEN_TYPE_IMMEDIATE: - dump_immediate_short( + tgsi_dump_immediate( &parse.FullToken.FullImmediate ); break; case TGSI_TOKEN_TYPE_INSTRUCTION: - dump_instruction_short( + tgsi_dump_instruction( &parse.FullToken.FullInstruction, instno ); instno++; diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h index beb0155d56..ca83bdef20 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h @@ -14,6 +14,24 @@ tgsi_dump( const struct tgsi_token *tokens, unsigned flags ); +struct tgsi_full_immediate; +struct tgsi_full_instruction; +struct tgsi_full_declaration; + +void +tgsi_dump_immediate( + const struct tgsi_full_immediate *imm ); + +void +tgsi_dump_instruction( + const struct tgsi_full_instruction *inst, + unsigned instno ); + +void +tgsi_dump_declaration( + const struct tgsi_full_declaration *decl ); + + #if defined __cplusplus } #endif -- cgit v1.2.3 From f7946bc7c0435ab2926cd729dfd8312222a3aa2a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 11:15:31 +0100 Subject: draw: dump individual instructions as they are processed --- src/gallium/auxiliary/draw/draw_vs_aos.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 434bd2a9ab..d3989fe107 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -42,7 +42,20 @@ #include "rtasm/rtasm_x86sse.h" #ifdef PIPE_ARCH_X86 +#define DISASSEM 0 +static const char *files[] = +{ + "NULL", + "CONST", + "IN", + "OUT", + "TEMP", + "SAMP", + "ADDR", + "IMM", + "INTERNAL", +}; static INLINE boolean eq( struct x86_reg a, struct x86_reg b ) @@ -184,7 +197,11 @@ static void spill( struct aos_compilation *cp, unsigned idx ) struct x86_reg oldval = get_reg_ptr(cp, cp->xmm[idx].file, cp->xmm[idx].idx); - + + if (0) debug_printf("\nspill %s[%d]", + files[cp->xmm[idx].file], + cp->xmm[idx].idx); + assert(cp->xmm[idx].dirty); sse_movaps(cp->func, oldval, x86_make_reg(file_XMM, idx)); cp->xmm[idx].dirty = 0; @@ -1975,6 +1992,9 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, break; case TGSI_TOKEN_TYPE_INSTRUCTION: + if (DISASSEM) + tgsi_dump_instruction( &parse.FullToken.FullInstruction, cp.insn_counter ); + if (!emit_instruction( &cp, &parse.FullToken.FullInstruction )) goto fail; break; @@ -1982,7 +2002,9 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, x87_assert_stack_empty(cp.func); cp.insn_counter++; - debug_printf("\n"); + + if (DISASSEM) + debug_printf("\n"); } -- cgit v1.2.3 From 50c1d329b95ad78e03ca4d537daee4d11f308c7a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 11:58:55 +0100 Subject: draw: restore extras path in draw_pt_vcache.c, keep pipeline flags out of non-pipeline elts --- src/gallium/auxiliary/draw/draw_pt_vcache.c | 117 +++++++++++++++------------- 1 file changed, 65 insertions(+), 52 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 6c17edba34..96e02fbf3a 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -104,10 +104,22 @@ static INLINE void vcache_elt( struct vcache_frontend *vcache, static void vcache_triangle( struct vcache_frontend *vcache, - ushort flags, unsigned i0, unsigned i1, unsigned i2 ) +{ + vcache_elt(vcache, i0, 0); + vcache_elt(vcache, i1, 0); + vcache_elt(vcache, i2, 0); + vcache_check_flush(vcache); +} + + +static void vcache_triangle_flags( struct vcache_frontend *vcache, + ushort flags, + unsigned i0, + unsigned i1, + unsigned i2 ) { vcache_elt(vcache, i0, flags); vcache_elt(vcache, i1, 0); @@ -116,9 +128,19 @@ static void vcache_triangle( struct vcache_frontend *vcache, } static void vcache_line( struct vcache_frontend *vcache, - ushort flags, unsigned i0, unsigned i1 ) +{ + vcache_elt(vcache, i0, 0); + vcache_elt(vcache, i1, 0); + vcache_check_flush(vcache); +} + + +static void vcache_line_flags( struct vcache_frontend *vcache, + ushort flags, + unsigned i0, + unsigned i1 ) { vcache_elt(vcache, i0, flags); vcache_elt(vcache, i1, 0); @@ -139,63 +161,46 @@ static void vcache_quad( struct vcache_frontend *vcache, unsigned i2, unsigned i3 ) { - vcache_triangle( vcache, - ( DRAW_PIPE_RESET_STIPPLE | - DRAW_PIPE_EDGE_FLAG_0 | - DRAW_PIPE_EDGE_FLAG_2 ), - i0, i1, i3 ); - - vcache_triangle( vcache, - ( DRAW_PIPE_EDGE_FLAG_0 | - DRAW_PIPE_EDGE_FLAG_1 ), - i1, i2, i3 ); + vcache_triangle( vcache, i0, i1, i3 ); + vcache_triangle( vcache, i1, i2, i3 ); +} + +static void vcache_ef_quad( struct vcache_frontend *vcache, + unsigned i0, + unsigned i1, + unsigned i2, + unsigned i3 ) +{ + vcache_triangle_flags( vcache, + ( DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_2 ), + i0, i1, i3 ); + + vcache_triangle_flags( vcache, + ( DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1 ), + i1, i2, i3 ); } /* At least for now, we're back to using a template include file for * this. The two paths aren't too different though - it may be * possible to reunify them. */ -#define TRIANGLE(flags,i0,i1,i2) \ - vcache_triangle(vcache, \ - flags, \ - get_elt(elts,i0), \ - get_elt(elts,i1), \ - get_elt(elts,i2)) - -#define QUAD(i0,i1,i2,i3) \ - vcache_quad(vcache, \ - get_elt(elts,i0), \ - get_elt(elts,i1), \ - get_elt(elts,i2), \ - get_elt(elts,i3)) - -#define LINE(flags,i0,i1) \ - vcache_line(vcache, \ - flags, \ - get_elt(elts,i0), \ - get_elt(elts,i1)) - -#define POINT(i0) \ - vcache_point(vcache, \ - get_elt(elts,i0)) - +#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle_flags(vc,flags,i0,i1,i2) +#define QUAD(vc,i0,i1,i2,i3) vcache_ef_quad(vc,i0,i1,i2,i3) +#define LINE(vc,flags,i0,i1) vcache_line_flags(vc,flags,i0,i1) +#define POINT(vc,i0) vcache_point(vc,i0) +#define FUNC vcache_run_extras +#include "draw_pt_vcache_tmp.h" + +#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle(vc,i0,i1,i2) +#define QUAD(vc,i0,i1,i2,i3) vcache_quad(vc,i0,i1,i2,i3) +#define LINE(vc,flags,i0,i1) vcache_line(vc,i0,i1) +#define POINT(vc,i0) vcache_point(vc,i0) #define FUNC vcache_run -#define ARGS \ - struct draw_pt_front_end *frontend, \ - pt_elt_func get_elt, \ - const void *elts - -#define LOCAL_VARS \ - struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; \ - struct draw_context *draw = vcache->draw; \ - boolean flatfirst = (draw->rasterizer->flatshade && \ - draw->rasterizer->flatshade_first); \ - unsigned prim = vcache->input_prim; \ - unsigned i, flags; +#include "draw_pt_vcache_tmp.h" -#define FLUSH vcache_flush( vcache ) - -#include "draw_pt_decompose.h" @@ -208,7 +213,15 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; - vcache->base.run = vcache_run; + if (opt & PT_PIPELINE) + { + vcache->base.run = vcache_run_extras; + } + else + { + vcache->base.run = vcache_run; + } + vcache->input_prim = prim; vcache->output_prim = draw_pt_reduced_prim(prim); -- cgit v1.2.3 From a08c574bfcf72c7f7ffbeb35c10347b491ef87fb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 12:26:23 +0100 Subject: draw: hook up viewport / rhw emit to varient key state --- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 4 +- src/gallium/auxiliary/draw/draw_vs_aos.c | 16 +++---- src/gallium/auxiliary/draw/draw_vs_varient.c | 52 ++++++++++++++++++---- 3 files changed, 53 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 7fefd391a6..2f2e7195b3 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -94,8 +94,8 @@ static void fse_prepare( struct draw_pt_middle_end *middle, fse->key.nr_elements = MAX2(num_vs_outputs, /* outputs - translate to hw format */ num_vs_inputs); /* inputs - fetch from api format */ - fse->key.viewport = 1; - fse->key.clip = 0; + fse->key.viewport = !draw->identity_viewport; + fse->key.clip = !draw->bypass_clipping; fse->key.pad = 0; memset(fse->key.element, 0, diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index d3989fe107..c63553216c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -2021,11 +2021,14 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, if (cp.error) goto fail; - if (cp.vaos->base.key.viewport) { - if (0) - emit_viewport(&cp); - else - emit_rhw_viewport(&cp); + if (cp.vaos->base.key.clip) { + /* not really handling clipping, just do the rhw so we can + * see the results... + */ + emit_rhw_viewport(&cp); + } + else if (cp.vaos->base.key.viewport) { + emit_viewport(&cp); } /* Emit output... TODO: do this eagerly after the last write to a @@ -2188,9 +2191,6 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, { struct draw_vs_varient_aos_sse *vaos = CALLOC_STRUCT(draw_vs_varient_aos_sse); - if (key->clip) - return NULL; - if (!vaos) goto fail; diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index c15c648527..d4deabfff3 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -89,9 +89,9 @@ static void vsvg_set_input( struct draw_vs_varient *varient, /* Mainly for debug at this stage: */ -static void do_viewport( struct draw_vs_varient_generic *vsvg, - unsigned count, - void *output_buffer ) +static void do_rhw_viewport( struct draw_vs_varient_generic *vsvg, + unsigned count, + void *output_buffer ) { char *ptr = (char *)output_buffer; const float *scale = vsvg->viewport.scale; @@ -109,6 +109,25 @@ static void do_viewport( struct draw_vs_varient_generic *vsvg, data[3] = w; } } + +static void do_viewport( struct draw_vs_varient_generic *vsvg, + unsigned count, + void *output_buffer ) +{ + char *ptr = (char *)output_buffer; + const float *scale = vsvg->viewport.scale; + const float *trans = vsvg->viewport.translate; + unsigned stride = vsvg->base.key.output_stride; + unsigned j; + + for (j = 0; j < count; j++, ptr += stride) { + float *data = (float *)ptr; + + data[0] = data[0] * scale[0] + trans[0]; + data[1] = data[1] * scale[1] + trans[1]; + data[2] = data[2] * scale[2] + trans[2]; + } +} static void vsvg_run_elts( struct draw_vs_varient *varient, @@ -136,10 +155,20 @@ static void vsvg_run_elts( struct draw_vs_varient *varient, vsvg->base.key.output_stride, vsvg->base.key.output_stride); - if (vsvg->base.key.viewport) + + if (vsvg->base.key.clip) { + /* not really handling clipping, just do the rhw so we can + * see the results... + */ + do_rhw_viewport( vsvg, + count, + output_buffer ); + } + else if (vsvg->base.key.viewport) { do_viewport( vsvg, count, output_buffer ); + } //if (!vsvg->already_in_emit_format) @@ -182,11 +211,19 @@ static void vsvg_run_linear( struct draw_vs_varient *varient, vsvg->base.key.output_stride, vsvg->base.key.output_stride); - if (vsvg->base.key.viewport) + if (vsvg->base.key.clip) { + /* not really handling clipping, just do the rhw so we can + * see the results... + */ + do_rhw_viewport( vsvg, + count, + output_buffer ); + } + else if (vsvg->base.key.viewport) { do_viewport( vsvg, count, output_buffer ); - + } //if (!vsvg->already_in_emit_format) vsvg->emit->set_buffer( vsvg->emit, @@ -224,9 +261,6 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, unsigned i; struct translate_key fetch, emit; - if (key->clip) - return NULL; - struct draw_vs_varient_generic *vsvg = CALLOC_STRUCT( draw_vs_varient_generic ); if (vsvg == NULL) return NULL; -- cgit v1.2.3 From 9752ebd99e16646fed3c14712fc0af2c34c9e48f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 27 May 2008 12:59:46 +0200 Subject: draw: Fix for EMIT_4UB case --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 2f2e7195b3..c6249b4b41 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -143,7 +143,10 @@ static void fse_prepare( struct draw_pt_middle_end *middle, output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); vs_output = num_vs_outputs + 1; - + break; + case EMIT_4UB: + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); break; default: assert(0); -- cgit v1.2.3 From 9f9f6c21be105de41a58128605b911e679efe8f0 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 27 May 2008 13:15:52 +0200 Subject: draw: Fixed typo in draw_pt_varray and added comments --- src/gallium/auxiliary/draw/draw_pt_varray.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index 06fd866ccd..260f28f284 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -158,14 +158,14 @@ static INLINE void varray_point( struct varray_frontend *varray, static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = { PIPE_PRIM_POINTS, PIPE_PRIM_LINES, + PIPE_PRIM_LINES, /* decomposed LINELOOP */ PIPE_PRIM_LINE_STRIP, - PIPE_PRIM_LINES, /* decomposed */ PIPE_PRIM_TRIANGLES, PIPE_PRIM_TRIANGLE_STRIP, - PIPE_PRIM_TRIANGLES, /* decomposed */ + PIPE_PRIM_TRIANGLES, /* decomposed TRI_FAN */ PIPE_PRIM_QUADS, PIPE_PRIM_QUAD_STRIP, - PIPE_PRIM_TRIANGLES /* decomposed */ + PIPE_PRIM_TRIANGLES /* decomposed POLYGON */ }; -- cgit v1.2.3 From f64c44ad3e55467ce964871502445cf5a0fb46d6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 14:17:57 +0100 Subject: draw: remove dead file --- src/gallium/auxiliary/draw/draw_pt_middle_fse.c | 705 ------------------------ 1 file changed, 705 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_pt_middle_fse.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_middle_fse.c b/src/gallium/auxiliary/draw/draw_pt_middle_fse.c deleted file mode 100644 index 643ea151c1..0000000000 --- a/src/gallium/auxiliary/draw/draw_pt_middle_fse.c +++ /dev/null @@ -1,705 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Keith Whitwell - */ - - -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "draw/draw_private.h" -#include "draw/draw_vbuf.h" -#include "draw/draw_vertex.h" -#include "draw/draw_pt.h" -#include "draw/draw_vs.h" - -#include "translate/translate.h" - -struct fetch_shade_emit; - -struct fse_shader { - struct translate_key key; - - void (*run_linear)( const struct fetch_shade_emit *fse, - unsigned start, - unsigned count, - char *buffer ); - - void (*run_elts)( const struct fetch_shade_emit *fse, - const unsigned *fetch_elts, - unsigned fetch_count, - char *buffer ); - -}; - -/* Prototype fetch, shade, emit-hw-verts all in one go. - */ -struct fetch_shade_emit { - struct draw_pt_middle_end base; - struct draw_context *draw; - - struct translate_key key; - - /* Temporaries: - */ - const float *constants; - unsigned pitch[PIPE_MAX_ATTRIBS]; - const ubyte *src[PIPE_MAX_ATTRIBS]; - unsigned prim; - - /* Points to one of the three hardwired example shaders, below: - */ - struct fse_shader *active; - - /* Temporary: A list of hard-wired shaders. Of course the plan - * would be to generate these for a given (vertex-shader, - * translate-key) pair... - */ - struct fse_shader shader[10]; - int nr_shaders; -}; - - - -/* Not quite passthrough yet -- we're still running the 'shader' here, - * inlined into the vertex fetch function. - */ -static void shader0_run_linear( const struct fetch_shade_emit *fse, - unsigned start, - unsigned count, - char *buffer ) -{ - unsigned i; - - const float *m = fse->constants; - const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; - const ubyte *rgb = fse->src[1] + start * fse->pitch[1]; - const ubyte *st = fse->src[2] + start * fse->pitch[2]; - - float *out = (float *)buffer; - - /* loop over vertex attributes (vertex shader inputs) - */ - for (i = 0; i < count; i++) { - { - const float *in = (const float *)xyz; - const float ix = in[0], iy = in[1], iz = in[2]; - - out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; - out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; - out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; - out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; - xyz += fse->pitch[0]; - } - - { - const float *in = (const float *)rgb; - out[4] = in[0]; - out[5] = in[1]; - out[6] = in[2]; - out[7] = 1.0f; - rgb += fse->pitch[1]; - } - - { - const float *in = (const float *)st; - out[8] = in[0]; - out[9] = in[1]; - out[10] = 0.0f; - out[11] = 1.0f; - st += fse->pitch[2]; - } - - out += 12; - } -} - - - -static void shader1_run_linear( const struct fetch_shade_emit *fse, - unsigned start, - unsigned count, - char *buffer ) -{ - unsigned i; - const float *m = (const float *)fse->constants; - const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; - const ubyte *rgb = fse->src[1] + start * fse->pitch[1]; - float *out = (float *)buffer; - -// debug_printf("rgb %f %f %f\n", rgb[0], rgb[1], rgb[2]); - - - for (i = 0; i < count; i++) { - { - const float *in = (const float *)xyz; - const float ix = in[0], iy = in[1], iz = in[2]; - - out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; - out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; - out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; - out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; - xyz += fse->pitch[0]; - } - - { - const float *in = (const float *)rgb; - out[4] = in[0]; - out[5] = in[1]; - out[6] = in[2]; - out[7] = 1.0f; - rgb += fse->pitch[1]; - } - - out += 8; - } -} - - - - -static void shader2_run_linear( const struct fetch_shade_emit *fse, - unsigned start, - unsigned count, - char *buffer ) -{ - unsigned i; - const float *m = (const float *)fse->constants; - const ubyte *xyz = fse->src[0] + start * fse->pitch[0]; - const ubyte *rgb = fse->src[1] + start * fse->pitch[1]; - const float psiz = 1.0; - float *out = (float *)buffer; - - - assert(fse->pitch[1] == 0); - - for (i = 0; i < count; i++) { - { - const float *in = (const float *)xyz; - const float ix = in[0], iy = in[1], iz = in[2]; - - out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; - out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; - out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; - out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; - xyz += fse->pitch[0]; - } - - { - const float *in = (const float *)rgb; - out[4] = in[0]; - out[5] = in[1]; - out[6] = in[2]; - out[7] = 1.0f; - rgb += fse->pitch[1]; - } - - { - out[8] = psiz; - } - - out += 9; - } -} - - - - -static void shader0_run_elts( const struct fetch_shade_emit *fse, - const unsigned *elts, - unsigned count, - char *buffer ) -{ - unsigned i; - const float *m = fse->constants; - float *out = (float *)buffer; - - - /* loop over vertex attributes (vertex shader inputs) - */ - for (i = 0; i < count; i++) { - unsigned elt = elts[i]; - { - const ubyte *xyz = fse->src[0] + elt * fse->pitch[0]; - const float *in = (const float *)xyz; - const float ix = in[0], iy = in[1], iz = in[2]; - - out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; - out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; - out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; - out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; - } - - { - const ubyte *rgb = fse->src[1] + elt * fse->pitch[1]; - const float *in = (const float *)rgb; - out[4] = in[0]; - out[5] = in[1]; - out[6] = in[2]; - out[7] = 1.0f; - } - - { - const ubyte *st = fse->src[2] + elt * fse->pitch[2]; - const float *in = (const float *)st; - out[8] = in[0]; - out[9] = in[1]; - out[10] = 0.0f; - out[11] = 1.0f; - } - - out += 12; - } -} - - - -static void shader1_run_elts( const struct fetch_shade_emit *fse, - const unsigned *elts, - unsigned count, - char *buffer ) -{ - unsigned i; - const float *m = (const float *)fse->constants; - float *out = (float *)buffer; - - for (i = 0; i < count; i++) { - unsigned elt = elts[i]; - - { - const ubyte *xyz = fse->src[0] + elt * fse->pitch[0]; - const float *in = (const float *)xyz; - const float ix = in[0], iy = in[1], iz = in[2]; - - out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; - out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; - out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; - out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; - xyz += fse->pitch[0]; - } - - { - const ubyte *rgb = fse->src[1] + elt * fse->pitch[1]; - const float *in = (const float *)rgb; - out[4] = in[0]; - out[5] = in[1]; - out[6] = in[2]; - out[7] = 1.0f; - rgb += fse->pitch[1]; - } - - out += 8; - } -} - - - - -static void shader2_run_elts( const struct fetch_shade_emit *fse, - const unsigned *elts, - unsigned count, - char *buffer ) -{ - unsigned i; - const float *m = (const float *)fse->constants; - const float psiz = 1.0; - float *out = (float *)buffer; - - for (i = 0; i < count; i++) { - unsigned elt = elts[i]; - { - const ubyte *xyz = fse->src[0] + elt * fse->pitch[0]; - const float *in = (const float *)xyz; - const float ix = in[0], iy = in[1], iz = in[2]; - - out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12]; - out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13]; - out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14]; - out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15]; - } - - { - const ubyte *rgb = fse->src[1] + elt * fse->pitch[1]; - out[4] = rgb[0]; - out[5] = rgb[1]; - out[6] = rgb[2]; - out[7] = 1.0f; - } - - { - out[8] = psiz; - } - - out += 9; - } -} - - - -static void fse_prepare( struct draw_pt_middle_end *middle, - unsigned prim, - unsigned opt ) -{ - struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; - struct draw_context *draw = fse->draw; - unsigned num_vs_inputs = draw->vs.vertex_shader->info.num_inputs; - unsigned num_vs_outputs = draw->vs.vertex_shader->info.num_outputs; - const struct vertex_info *vinfo; - unsigned i; - boolean need_psize = 0; - - - if (draw->pt.user.elts) { - assert(0); - return ; - } - - if (!draw->render->set_primitive( draw->render, - prim )) { - assert(0); - return; - } - - /* Must do this after set_primitive() above: - */ - vinfo = draw->render->get_vertex_info(draw->render); - - - - fse->key.nr_elements = MAX2(num_vs_outputs, /* outputs - translate to hw format */ - num_vs_inputs); /* inputs - fetch from api format */ - - fse->key.output_stride = vinfo->size * 4; - memset(fse->key.element, 0, - fse->key.nr_elements * sizeof(fse->key.element[0])); - - for (i = 0; i < num_vs_inputs; i++) { - const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; - fse->key.element[i].input_format = src->src_format; - - /* Consider ignoring these at this point, ie make generated - * programs independent of this state: - */ - fse->key.element[i].input_buffer = 0; //src->vertex_buffer_index; - fse->key.element[i].input_offset = 0; //src->src_offset; - } - - - { - unsigned dst_offset = 0; - - for (i = 0; i < vinfo->num_attribs; i++) { - unsigned emit_sz = 0; - unsigned output_format = PIPE_FORMAT_NONE; - unsigned vs_output = vinfo->src_index[i]; - - switch (vinfo->emit[i]) { - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - need_psize = 1; - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - vs_output = num_vs_outputs + 1; - - break; - default: - assert(0); - break; - } - - /* The elements in the key correspond to vertex shader output - * numbers, not to positions in the hw vertex description -- - * that's handled by the output_offset field. - */ - fse->key.element[vs_output].output_format = output_format; - fse->key.element[vs_output].output_offset = dst_offset; - - dst_offset += emit_sz; - assert(fse->key.output_stride >= dst_offset); - } - } - - /* To make psize work, really need to tell the vertex shader to - * copy that value from input->output. For 'translate' this was - * implicit for all elements. - */ -#if 0 - if (need_psize) { - unsigned input = num_vs_inputs + 1; - const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; - fse->key.element[i].input_format = PIPE_FORMAT_R32_FLOAT; - fse->key.element[i].input_buffer = 0; //nr_buffers + 1; - fse->key.element[i].input_offset = 0; - - fse->key.nr_elements += 1; - - } -#endif - - fse->constants = draw->pt.user.constants; - - /* Would normally look up a vertex shader and peruse its list of - * varients somehow. We omitted that step and put all the - * hardcoded "shaders" into an array. We're just making the - * assumption that this happens to be a matching shader... ie - * you're running isosurf, aren't you? - */ - fse->active = NULL; - for (i = 0; i < fse->nr_shaders; i++) { - if (translate_key_compare( &fse->key, &fse->shader[i].key) == 0) - fse->active = &fse->shader[i]; - } - - if (!fse->active) { - assert(0); - return ; - } - - /* Now set buffer pointers: - */ - for (i = 0; i < num_vs_inputs; i++) { - unsigned buf = draw->pt.vertex_element[i].vertex_buffer_index; - - fse->src[i] = ((const ubyte *) draw->pt.user.vbuffer[buf] + - draw->pt.vertex_buffer[buf].buffer_offset + - draw->pt.vertex_element[i].src_offset); - - fse->pitch[i] = draw->pt.vertex_buffer[buf].pitch; - - } - - - //return TRUE; -} - - - - - - - -static void fse_run_linear( struct draw_pt_middle_end *middle, - unsigned start, - unsigned count ) -{ - struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; - struct draw_context *draw = fse->draw; - - char *hw_verts; - - /* XXX: need to flush to get prim_vbuf.c to release its allocation?? - */ - draw_do_flush( draw, DRAW_FLUSH_BACKEND ); - - hw_verts = draw->render->allocate_vertices( draw->render, - (ushort)fse->key.output_stride, - (ushort)count ); - - if (!hw_verts) { - assert(0); - return; - } - - /* Single routine to fetch vertices, run shader and emit HW verts. - * Clipping and viewport transformation are done elsewhere -- - * either by the API or on hardware, or for some other reason not - * required... - */ - fse->active->run_linear( fse, - start, count, - hw_verts ); - - /* Draw arrays path to avoid re-emitting index list again and - * again. - */ - draw->render->draw_arrays( draw->render, - 0, - count ); - - - draw->render->release_vertices( draw->render, - hw_verts, - fse->key.output_stride, - count ); -} - - -static void -fse_run(struct draw_pt_middle_end *middle, - const unsigned *fetch_elts, - unsigned fetch_count, - const ushort *draw_elts, - unsigned draw_count ) -{ - struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; - struct draw_context *draw = fse->draw; - void *hw_verts; - - /* XXX: need to flush to get prim_vbuf.c to release its allocation?? - */ - draw_do_flush( draw, DRAW_FLUSH_BACKEND ); - - hw_verts = draw->render->allocate_vertices( draw->render, - (ushort)fse->key.output_stride, - (ushort)fetch_count ); - if (!hw_verts) { - assert(0); - return; - } - - - /* Single routine to fetch vertices, run shader and emit HW verts. - */ - fse->active->run_elts( fse, - fetch_elts, - fetch_count, - hw_verts ); - - draw->render->draw( draw->render, - draw_elts, - draw_count ); - - draw->render->release_vertices( draw->render, - hw_verts, - fse->key.output_stride, - fetch_count ); - -} - - -static void fse_finish( struct draw_pt_middle_end *middle ) -{ -} - - -static void -fse_destroy( struct draw_pt_middle_end *middle ) -{ - FREE(middle); -} - -struct draw_pt_middle_end *draw_pt_middle_fse( struct draw_context *draw ) -{ - struct fetch_shade_emit *fse = CALLOC_STRUCT(fetch_shade_emit); - if (!fse) - return NULL; - - fse->base.prepare = fse_prepare; - fse->base.run = fse_run; - fse->base.run_linear = fse_run_linear; - fse->base.finish = fse_finish; - fse->base.destroy = fse_destroy; - fse->draw = draw; - - fse->shader[0].run_linear = shader0_run_linear; - fse->shader[0].run_elts = shader0_run_elts; - fse->shader[0].key.nr_elements = 3; - fse->shader[0].key.output_stride = 12 * sizeof(float); - - fse->shader[0].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[0].key.element[0].input_buffer = 0; - fse->shader[0].key.element[0].input_offset = 0; - fse->shader[0].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[0].key.element[0].output_offset = 0; - - fse->shader[0].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[0].key.element[1].input_buffer = 0; - fse->shader[0].key.element[1].input_offset = 0; - fse->shader[0].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[0].key.element[1].output_offset = 16; - - fse->shader[0].key.element[1].input_format = PIPE_FORMAT_R32G32_FLOAT; - fse->shader[0].key.element[1].input_buffer = 0; - fse->shader[0].key.element[1].input_offset = 0; - fse->shader[0].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[0].key.element[1].output_offset = 32; - - fse->shader[1].run_linear = shader1_run_linear; - fse->shader[1].run_elts = shader1_run_elts; - fse->shader[1].key.nr_elements = 2; - fse->shader[1].key.output_stride = 8 * sizeof(float); - - fse->shader[1].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[1].key.element[0].input_buffer = 0; - fse->shader[1].key.element[0].input_offset = 0; - fse->shader[1].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[1].key.element[0].output_offset = 0; - - fse->shader[1].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[1].key.element[1].input_buffer = 0; - fse->shader[1].key.element[1].input_offset = 0; - fse->shader[1].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[1].key.element[1].output_offset = 16; - - fse->shader[2].run_linear = shader2_run_linear; - fse->shader[2].run_elts = shader2_run_elts; - fse->shader[2].key.nr_elements = 3; - fse->shader[2].key.output_stride = 9 * sizeof(float); - - fse->shader[2].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[2].key.element[0].input_buffer = 0; - fse->shader[2].key.element[0].input_offset = 0; - fse->shader[2].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[2].key.element[0].output_offset = 0; - - fse->shader[2].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT; - fse->shader[2].key.element[1].input_buffer = 0; - fse->shader[2].key.element[1].input_offset = 0; - fse->shader[2].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fse->shader[2].key.element[1].output_offset = 16; - - /* psize is special - * -- effectively add it here as another input!?! - * -- who knows how to add it as a buffer? - */ - fse->shader[2].key.element[2].input_format = PIPE_FORMAT_R32_FLOAT; - fse->shader[2].key.element[2].input_buffer = 0; - fse->shader[2].key.element[2].input_offset = 0; - fse->shader[2].key.element[2].output_format = PIPE_FORMAT_R32_FLOAT; - fse->shader[2].key.element[2].output_offset = 32; - - fse->nr_shaders = 3; - - return &fse->base; -} -- cgit v1.2.3 From f8762ba5234fd1b44e11e76bb5f58d2305c90572 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 14:42:15 +0100 Subject: draw: explicitly list nr_inputs, outputs in varient key --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c | 14 +++++++++----- src/gallium/auxiliary/draw/draw_vs.h | 6 ++++-- src/gallium/auxiliary/draw/draw_vs_aos.c | 2 +- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 4 ++-- src/gallium/auxiliary/draw/draw_vs_varient.c | 10 +++++----- 5 files changed, 21 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index c6249b4b41..581026dcb0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -72,7 +72,6 @@ static void fse_prepare( struct draw_pt_middle_end *middle, struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; struct draw_context *draw = fse->draw; unsigned num_vs_inputs = draw->vs.vertex_shader->info.num_inputs; - unsigned num_vs_outputs = draw->vs.vertex_shader->info.num_outputs; const struct vertex_info *vinfo; unsigned i; boolean need_psize = 0; @@ -91,8 +90,11 @@ static void fse_prepare( struct draw_pt_middle_end *middle, fse->key.output_stride = vinfo->size * 4; - fse->key.nr_elements = MAX2(num_vs_outputs, /* outputs - translate to hw format */ - num_vs_inputs); /* inputs - fetch from api format */ + fse->key.nr_outputs = vinfo->num_attribs; + fse->key.nr_inputs = num_vs_inputs; + + fse->key.nr_elements = MAX2(fse->key.nr_outputs, /* outputs - translate to hw format */ + fse->key.nr_inputs); /* inputs - fetch from api format */ fse->key.viewport = !draw->identity_viewport; fse->key.clip = !draw->bypass_clipping; @@ -142,7 +144,7 @@ static void fse_prepare( struct draw_pt_middle_end *middle, need_psize = 1; output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); - vs_output = num_vs_outputs + 1; + vs_output = vinfo->num_attribs + 1; break; case EMIT_4UB: output_format = PIPE_FORMAT_B8G8R8A8_UNORM; @@ -177,7 +179,9 @@ static void fse_prepare( struct draw_pt_middle_end *middle, fse->key.element[i].input_buffer = 0; //nr_buffers + 1; fse->key.element[i].input_offset = 0; - fse->key.nr_elements += 1; + fse->key.nr_inputs += 1; + fse->key.nr_elements = MAX2(fse->key.nr_inputs, + fse->key.nr_outputs); } #endif diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index ff3e19b2a8..17902ab86a 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -58,10 +58,12 @@ struct draw_vs_element { struct draw_vs_varient_key { unsigned output_stride; - unsigned nr_elements:16; + unsigned nr_elements:8; /* max2(nr_inputs, nr_outputs) */ + unsigned nr_inputs:8; + unsigned nr_outputs:8; unsigned viewport:1; unsigned clip:1; - unsigned pad:14; + unsigned pad:5; struct draw_vs_element element[PIPE_MAX_ATTRIBS]; }; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index c63553216c..e2e96470f7 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -2095,7 +2095,7 @@ static void vaos_set_buffer( struct draw_vs_varient *varient, struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; unsigned i; - for (i = 0; i < vaos->base.vs->info.num_inputs; i++) { + for (i = 0; i < vaos->base.key.nr_inputs; i++) { if (vaos->base.key.element[i].in.buffer == buf) { vaos->machine->attrib[i].input_ptr = ((char *)ptr + vaos->base.key.element[i].in.offset); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index f39ebb7a17..ef265d61cf 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -180,7 +180,7 @@ boolean aos_fetch_inputs( struct aos_compilation *cp, boolean linear ) { unsigned i; - for (i = 0; i < cp->vaos->base.vs->info.num_inputs; i++) { + for (i = 0; i < cp->vaos->base.key.nr_inputs; i++) { if (!load_input( cp, i, linear )) return FALSE; cp->insn_counter++; @@ -282,7 +282,7 @@ boolean aos_emit_outputs( struct aos_compilation *cp ) { unsigned i; - for (i = 0; i < cp->vaos->base.vs->info.num_outputs; i++) { + for (i = 0; i < cp->vaos->base.key.nr_outputs; i++) { unsigned format = cp->vaos->base.key.element[i].out.format; unsigned offset = cp->vaos->base.key.element[i].out.offset; diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index d4deabfff3..dab46e8eed 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -276,11 +276,11 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, - /* OK, have to build a new one: + /* Build free-standing fetch and emit functions: */ - fetch.nr_elements = vs->info.num_inputs; + fetch.nr_elements = key->nr_inputs; fetch.output_stride = 0; - for (i = 0; i < vs->info.num_inputs; i++) { + for (i = 0; i < key->nr_inputs; i++) { fetch.element[i].input_format = key->element[i].in.format; fetch.element[i].input_buffer = key->element[i].in.buffer; fetch.element[i].input_offset = key->element[i].in.offset; @@ -290,9 +290,9 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, } - emit.nr_elements = vs->info.num_outputs; + emit.nr_elements = key->nr_outputs; emit.output_stride = key->output_stride; - for (i = 0; i < vs->info.num_outputs; i++) { + for (i = 0; i < key->nr_outputs; i++) { emit.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; emit.element[i].input_buffer = 0; emit.element[i].input_offset = i * 4 * sizeof(float); -- cgit v1.2.3 From 26f34dcff2a6ad0d44605c8ff34ae2850f655fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 28 May 2008 01:24:26 +0900 Subject: gallium: Autodetect WINCE. --- src/gallium/include/pipe/p_config.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index 5c030bdfff..6ba211a1fc 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -100,6 +100,7 @@ #endif #if defined(PIPE_OS_WINDOWS) +#ifndef _WIN32_WCE #if !defined(PIPE_SUBSYSTEM_USER) && !defined(PIPE_SUBSYSTEM_KERNEL) #error Neither PIPE_SUBSYSTEM_USER or PIPE_SUBSYSTEM_KERNEL defined. #endif @@ -109,12 +110,12 @@ #if 0 /* FIXME */ #define PIPE_SUBSYSTEM_WINDOWS_MINIPORT #endif -#if 0 /* FIXME */ -#define PIPE_SUBSYSTEM_WINDOWS_CE -#endif #if defined(PIPE_SUBSYSTEM_USER) #define PIPE_SUBSYSTEM_WINDOWS_USER #endif +#else /* _WIN32_WCE */ +#define PIPE_SUBSYSTEM_WINDOWS_CE +#endif /* _WIN32_WCE */ #endif /* PIPE_OS_WINDOWS */ -- cgit v1.2.3 From 2ec419d40dba43305c28fca9658ea00541f67821 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 17:45:54 +0100 Subject: draw: fix ABS aliasing bug --- src/gallium/auxiliary/draw/draw_vs_aos.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index e2e96470f7..1c63677e6e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -964,12 +964,13 @@ static boolean emit_ABS( struct aos_compilation *cp, const struct tgsi_full_inst { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); struct x86_reg neg = aos_get_internal(cp, IMM_NEGS); - struct x86_reg dst = get_xmm_writable(cp, arg0); + struct x86_reg tmp = aos_get_xmm_reg(cp); - sse_mulps(cp->func, dst, neg); - sse_maxps(cp->func, dst, arg0); + sse_movaps(cp->func, tmp, arg0); + sse_mulps(cp->func, tmp, neg); + sse_maxps(cp->func, tmp, arg0); - store_dest(cp, &op->FullDstRegisters[0], dst); + store_dest(cp, &op->FullDstRegisters[0], tmp); return TRUE; } -- cgit v1.2.3 From 660fee8351542dadc0d5550164e753f7c2d67261 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 17:49:13 +0100 Subject: draw: ensure vs outputs mapped correctly to vinfo attribs --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c | 1 + src/gallium/auxiliary/draw/draw_vs.h | 19 ++++++++++--------- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 3 ++- 3 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 581026dcb0..43d7095f76 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -160,6 +160,7 @@ static void fse_prepare( struct draw_pt_middle_end *middle, * that's handled by the output_offset field. */ fse->key.element[vs_output].out.format = output_format; + fse->key.element[vs_output].out.vs_output = vs_output; fse->key.element[vs_output].out.offset = dst_offset; dst_offset += emit_sz; diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 17902ab86a..01171bc23d 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -38,22 +38,23 @@ struct draw_context; struct pipe_shader_state; -struct draw_vs_input +struct draw_varient_input { enum pipe_format format; unsigned buffer; unsigned offset; }; -struct draw_vs_output +struct draw_varient_output { - enum pipe_format format; - unsigned offset; + enum pipe_format format; /* output format */ + unsigned vs_output:8; /* which vertex shader output is this? */ + unsigned offset:24; /* offset into output vertex */ }; -struct draw_vs_element { - struct draw_vs_input in; - struct draw_vs_output out; +struct draw_varient_element { + struct draw_varient_input in; + struct draw_varient_output out; }; struct draw_vs_varient_key { @@ -64,7 +65,7 @@ struct draw_vs_varient_key { unsigned viewport:1; unsigned clip:1; unsigned pad:5; - struct draw_vs_element element[PIPE_MAX_ATTRIBS]; + struct draw_varient_element element[PIPE_MAX_ATTRIBS]; }; struct draw_vs_varient; @@ -201,7 +202,7 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, static INLINE int draw_vs_varient_keysize( const struct draw_vs_varient_key *key ) { - return 2 * sizeof(int) + key->nr_elements * sizeof(struct draw_vs_element); + return 2 * sizeof(int) + key->nr_elements * sizeof(struct draw_varient_element); } static INLINE int draw_vs_varient_key_compare( const struct draw_vs_varient_key *a, diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index ef265d61cf..cebfaf6474 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -285,10 +285,11 @@ boolean aos_emit_outputs( struct aos_compilation *cp ) for (i = 0; i < cp->vaos->base.key.nr_outputs; i++) { unsigned format = cp->vaos->base.key.element[i].out.format; unsigned offset = cp->vaos->base.key.element[i].out.offset; + unsigned vs_output = cp->vaos->base.key.element[i].out.vs_output; struct x86_reg data = aos_get_shader_reg( cp, TGSI_FILE_OUTPUT, - i ); + vs_output ); if (data.file != file_XMM) { struct x86_reg tmp = aos_get_xmm_reg( cp ); -- cgit v1.2.3 From fd20d1c7e8bbe2f40d73679b1514023772cfd8f6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 17:51:48 +0100 Subject: draw: add disabled debug code --- src/gallium/auxiliary/draw/draw_pt_emit.c | 15 +++++++++++- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 28 +++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index e37256b1ff..cf87cde996 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -41,6 +41,8 @@ struct pt_emit { struct translate_cache *cache; unsigned prim; + + const struct vertex_info *vinfo; }; void draw_pt_emit_prepare( struct pt_emit *emit, @@ -71,7 +73,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, /* Must do this after set_primitive() above: */ - vinfo = draw->render->get_vertex_info(draw->render); + emit->vinfo = vinfo = draw->render->get_vertex_info(draw->render); /* Translate from pipeline vertices to hw vertices. @@ -245,6 +247,17 @@ void draw_pt_emit_linear(struct pt_emit *emit, vertex_count, hw_verts); + if (0) { + unsigned i; + for (i = 0; i < vertex_count; i++) { + debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i); + draw_dump_emitted_vertex( emit->vinfo, + (const uint8_t *)hw_verts + + translate->key.output_stride * i ); + } + } + + render->draw_arrays(render, start, count); render->release_vertices(render, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 43d7095f76..85d0bdfcab 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -60,6 +60,9 @@ struct fetch_shade_emit { struct draw_vs_varient_key key; struct draw_vs_varient *active; + + + const struct vertex_info *vinfo; }; @@ -85,7 +88,7 @@ static void fse_prepare( struct draw_pt_middle_end *middle, /* Must do this after set_primitive() above: */ - vinfo = draw->render->get_vertex_info(draw->render); + fse->vinfo = vinfo = draw->render->get_vertex_info(draw->render); @@ -267,6 +270,18 @@ static void fse_run_linear( struct draw_pt_middle_end *middle, 0, count ); + if (0) { + unsigned i; + for (i = 0; i < count; i++) { + debug_printf("\n\n%s vertex %d: (stride %d, offset %d)\n", __FUNCTION__, i, + fse->key.output_stride, + fse->key.output_stride * i); + + draw_dump_emitted_vertex( fse->vinfo, + (const uint8_t *)hw_verts + fse->key.output_stride * i ); + } + } + draw->render->release_vertices( draw->render, hw_verts, @@ -311,6 +326,17 @@ fse_run(struct draw_pt_middle_end *middle, draw_elts, draw_count ); + if (0) { + unsigned i; + for (i = 0; i < fetch_count; i++) { + debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i); + draw_dump_emitted_vertex( fse->vinfo, + (const uint8_t *)hw_verts + + fse->key.output_stride * i ); + } + } + + draw->render->release_vertices( draw->render, hw_verts, fse->key.output_stride, -- cgit v1.2.3 From 7b85ea19de09d4e7e077ca147528e90e52683690 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 19:01:57 +0100 Subject: draw: support psize in vs_varient paths Preserve the vinfo "EMIT_*" format descriptors in the varient key, and deal with PSIZE directly in each implementation. --- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 35 ++------------------ src/gallium/auxiliary/draw/draw_vertex.h | 21 ++++++++++++ src/gallium/auxiliary/draw/draw_vs_aos.c | 3 ++ src/gallium/auxiliary/draw/draw_vs_aos.h | 1 + src/gallium/auxiliary/draw/draw_vs_aos_io.c | 37 ++++++++++++++-------- src/gallium/auxiliary/draw/draw_vs_varient.c | 24 +++++++++++--- 6 files changed, 71 insertions(+), 50 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 85d0bdfcab..729c7db999 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -77,7 +77,6 @@ static void fse_prepare( struct draw_pt_middle_end *middle, unsigned num_vs_inputs = draw->vs.vertex_shader->info.num_inputs; const struct vertex_info *vinfo; unsigned i; - boolean need_psize = 0; if (!draw->render->set_primitive( draw->render, @@ -123,34 +122,24 @@ static void fse_prepare( struct draw_pt_middle_end *middle, for (i = 0; i < vinfo->num_attribs; i++) { unsigned emit_sz = 0; - unsigned output_format = PIPE_FORMAT_NONE; - unsigned vs_output = vinfo->src_index[i]; switch (vinfo->emit[i]) { case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; emit_sz = 4 * sizeof(float); break; case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; emit_sz = 3 * sizeof(float); break; case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; emit_sz = 2 * sizeof(float); break; case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); break; case EMIT_1F_PSIZE: - need_psize = 1; - output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); - vs_output = vinfo->num_attribs + 1; break; case EMIT_4UB: - output_format = PIPE_FORMAT_B8G8R8A8_UNORM; emit_sz = 4 * sizeof(ubyte); break; default: @@ -162,33 +151,15 @@ static void fse_prepare( struct draw_pt_middle_end *middle, * numbers, not to positions in the hw vertex description -- * that's handled by the output_offset field. */ - fse->key.element[vs_output].out.format = output_format; - fse->key.element[vs_output].out.vs_output = vs_output; - fse->key.element[vs_output].out.offset = dst_offset; + fse->key.element[i].out.format = vinfo->emit[i]; + fse->key.element[i].out.vs_output = vinfo->src_index[i]; + fse->key.element[i].out.offset = dst_offset; dst_offset += emit_sz; assert(fse->key.output_stride >= dst_offset); } } - /* To make psize work, really need to tell the vertex shader to - * copy that value from input->output. For 'translate' this was - * implicit for all elements. - */ -#if 0 - if (need_psize) { - unsigned input = num_vs_inputs + 1; - const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; - fse->key.element[i].input_format = PIPE_FORMAT_R32_FLOAT; - fse->key.element[i].input_buffer = 0; //nr_buffers + 1; - fse->key.element[i].input_offset = 0; - - fse->key.nr_inputs += 1; - fse->key.nr_elements = MAX2(fse->key.nr_inputs, - fse->key.nr_outputs); - - } -#endif /* Would normally look up a vertex shader and peruse its list of * varients somehow. We omitted that step and put all the diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index 6d8bac5138..16c65c4317 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -109,4 +109,25 @@ extern void draw_compute_vertex_size(struct vertex_info *vinfo); void draw_dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data); + +static INLINE unsigned draw_translate_vinfo_format(unsigned format ) +{ + switch (format) { + case EMIT_1F: + case EMIT_1F_PSIZE: + return PIPE_FORMAT_R32_FLOAT; + case EMIT_2F: + return PIPE_FORMAT_R32G32_FLOAT; + case EMIT_3F: + return PIPE_FORMAT_R32G32B32_FLOAT; + case EMIT_4F: + return PIPE_FORMAT_R32G32B32A32_FLOAT; + case EMIT_4UB: + return PIPE_FORMAT_R8G8B8A8_UNORM; + default: + return PIPE_FORMAT_NONE; + } +} + + #endif /* DRAW_VERTEX_H */ diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 1c63677e6e..d3770b2c53 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -2126,6 +2126,7 @@ static void vaos_run_elts( struct draw_vs_varient *varient, { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; vaos->gen_run_elts( varient, elts, count, @@ -2139,6 +2140,7 @@ static void vaos_run_linear( struct draw_vs_varient *varient, { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; vaos->gen_run_linear( varient, start, count, @@ -2204,6 +2206,7 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, vaos->base.run_linear = vaos_run_linear; vaos->base.run_elts = vaos_run_elts; + vaos->draw = vs->draw; vaos->machine = align_malloc( sizeof(struct aos_machine), 16 ); if (!vaos->machine) goto fail; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index fffe2e4658..b47413ff43 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -176,6 +176,7 @@ boolean aos_emit_outputs( struct aos_compilation *cp ); #define IMM_255 4 /* 255, 255, 255, 255 */ #define IMM_NEGS 5 /* -1,-1,-1,-1 */ #define IMM_RSQ 6 /* -.5,1.5,_,_ */ +#define IMM_PSIZE 7 /* not really an immediate - updated each run */ struct x86_reg aos_get_internal( struct aos_compilation *cp, unsigned imm ); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index cebfaf6474..836110f382 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -33,6 +33,7 @@ #include "tgsi/exec/tgsi_exec.h" #include "draw_vs.h" #include "draw_vs_aos.h" +#include "draw_vertex.h" #include "rtasm/rtasm_x86sse.h" @@ -249,24 +250,27 @@ static boolean emit_output( struct aos_compilation *cp, unsigned format ) { switch (format) { - case PIPE_FORMAT_R32_FLOAT: + case EMIT_1F: + case EMIT_1F_PSIZE: emit_store_R32(cp, ptr, dataXMM); break; - case PIPE_FORMAT_R32G32_FLOAT: + case EMIT_2F: emit_store_R32G32(cp, ptr, dataXMM); break; - case PIPE_FORMAT_R32G32B32_FLOAT: + case EMIT_3F: emit_store_R32G32B32(cp, ptr, dataXMM); break; - case PIPE_FORMAT_R32G32B32A32_FLOAT: + case EMIT_4F: emit_store_R32G32B32A32(cp, ptr, dataXMM); break; - case PIPE_FORMAT_B8G8R8A8_UNORM: - emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W)); - emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); - break; - case PIPE_FORMAT_R8G8B8A8_UNORM: - emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); + case EMIT_4UB: + if (1) { + emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W)); + emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); + } + else { + emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); + } break; default: ERROR(cp, "unhandled output format"); @@ -287,9 +291,16 @@ boolean aos_emit_outputs( struct aos_compilation *cp ) unsigned offset = cp->vaos->base.key.element[i].out.offset; unsigned vs_output = cp->vaos->base.key.element[i].out.vs_output; - struct x86_reg data = aos_get_shader_reg( cp, - TGSI_FILE_OUTPUT, - vs_output ); + struct x86_reg data; + + if (format == EMIT_1F_PSIZE) { + data = aos_get_internal_xmm( cp, IMM_PSIZE ); + } + else { + data = aos_get_shader_reg( cp, + TGSI_FILE_OUTPUT, + vs_output ); + } if (data.file != file_XMM) { struct x86_reg tmp = aos_get_xmm_reg( cp ); diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index dab46e8eed..119a3a04b5 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -231,6 +231,10 @@ static void vsvg_run_linear( struct draw_vs_varient *varient, output_buffer, vsvg->base.key.output_stride ); + vsvg->emit->set_buffer( vsvg->emit, + 1, + &vsvg->draw->rasterizer->point_size, + 0); vsvg->emit->run( vsvg->emit, 0, count, @@ -293,11 +297,21 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, emit.nr_elements = key->nr_outputs; emit.output_stride = key->output_stride; for (i = 0; i < key->nr_outputs; i++) { - emit.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit.element[i].input_buffer = 0; - emit.element[i].input_offset = i * 4 * sizeof(float); - emit.element[i].output_format = key->element[i].out.format; - emit.element[i].output_offset = key->element[i].out.offset; + if (key->element[i].out.format != EMIT_1F_PSIZE) + { + emit.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit.element[i].input_buffer = 0; + emit.element[i].input_offset = key->element[i].out.vs_output * 4 * sizeof(float); + emit.element[i].output_format = draw_translate_vinfo_format(key->element[i].out.format); + emit.element[i].output_offset = key->element[i].out.offset; + } + else { + emit.element[i].input_format = PIPE_FORMAT_R32_FLOAT; + emit.element[i].input_buffer = 1; + emit.element[i].input_offset = 0; + emit.element[i].output_format = PIPE_FORMAT_R32_FLOAT; + emit.element[i].output_offset = key->element[i].out.offset; + } } vsvg->fetch = draw_vs_get_fetch( vs->draw, &fetch ); -- cgit v1.2.3 From e38bb10824fc3dc194d7cc6987f3f4957784310e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 23:21:50 +0100 Subject: draw: reset stipple counter whenever non-line prim encountered --- src/gallium/auxiliary/draw/draw_pipe_stipple.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c index 4673d5dcba..9522b79582 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c @@ -175,6 +175,22 @@ reset_stipple_counter(struct draw_stage *stage) stage->next->reset_stipple_counter( stage->next ); } +static void +stipple_reset_point(struct draw_stage *stage, struct prim_header *header) +{ + struct stipple_stage *stipple = stipple_stage(stage); + stipple->counter = 0; + stage->next->point(stage->next, header); +} + +static void +stipple_reset_tri(struct draw_stage *stage, struct prim_header *header) +{ + struct stipple_stage *stipple = stipple_stage(stage); + stipple->counter = 0; + stage->next->tri(stage->next, header); +} + static void stipple_first_line(struct draw_stage *stage, @@ -220,9 +236,9 @@ struct draw_stage *draw_stipple_stage( struct draw_context *draw ) stipple->stage.draw = draw; stipple->stage.next = NULL; - stipple->stage.point = draw_pipe_passthrough_point; + stipple->stage.point = stipple_reset_point; stipple->stage.line = stipple_first_line; - stipple->stage.tri = draw_pipe_passthrough_tri; + stipple->stage.tri = stipple_reset_tri; stipple->stage.reset_stipple_counter = reset_stipple_counter; stipple->stage.flush = stipple_flush; stipple->stage.destroy = stipple_destroy; -- cgit v1.2.3 From b7b9ce0f8677993c3cd5376add72a684a5653341 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 23:23:37 +0100 Subject: softpipe: enable vbuf by default The non-vbuf option is going away... --- src/gallium/drivers/softpipe/sp_context.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index a48e546139..ed9322a109 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -227,11 +227,13 @@ softpipe_create( struct pipe_screen *screen, if (GETENV( "SP_NO_RAST" ) != NULL) softpipe->no_rast = TRUE; - if (GETENV( "SP_VBUF" ) != NULL) { - sp_init_vbuf(softpipe); + if (GETENV( "SP_NO_VBUF" ) != NULL) { + /* Deprecated path -- vbuf is the intended interface to the draw module: + */ + draw_set_rasterize_stage(softpipe->draw, softpipe->setup); } else { - draw_set_rasterize_stage(softpipe->draw, softpipe->setup); + sp_init_vbuf(softpipe); } /* plug in AA line/point stages */ -- cgit v1.2.3 From 55d29a8d48663982a1aeea414f69a5896b97d1ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 28 May 2008 16:12:14 +0900 Subject: gallium: Windows CE portability fixes. --- src/gallium/auxiliary/draw/draw_pt_elts.c | 8 +- src/gallium/auxiliary/draw/draw_pt_varray.c | 4 +- src/gallium/auxiliary/draw/draw_vs_sse.c | 4 +- src/gallium/auxiliary/rtasm/rtasm_cpu.c | 4 +- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 4 +- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 4 +- src/gallium/auxiliary/tgsi/util/tgsi_util.c | 2 +- src/gallium/auxiliary/translate/translate.c | 3 +- .../auxiliary/translate/translate_generic.c | 236 ++++++++++----------- src/gallium/auxiliary/translate/translate_sse.c | 5 +- src/gallium/auxiliary/util/u_time.h | 2 +- src/gallium/include/pipe/p_compiler.h | 54 +++-- src/gallium/include/pipe/p_config.h | 8 +- src/gallium/include/pipe/p_debug.h | 11 +- 14 files changed, 192 insertions(+), 157 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_elts.c b/src/gallium/auxiliary/draw/draw_pt_elts.c index 2094c081ed..b7780fb507 100644 --- a/src/gallium/auxiliary/draw/draw_pt_elts.c +++ b/src/gallium/auxiliary/draw/draw_pt_elts.c @@ -60,10 +60,10 @@ static unsigned elt_vert( const void *elts, unsigned idx ) pt_elt_func draw_pt_elt_func( struct draw_context *draw ) { switch (draw->pt.user.eltSize) { - case 0: return elt_vert; - case 1: return elt_ubyte; - case 2: return elt_ushort; - case 4: return elt_uint; + case 0: return &elt_vert; + case 1: return &elt_ubyte; + case 2: return &elt_ushort; + case 4: return &elt_uint; default: return NULL; } } diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index 355093f945..c7c66b34d4 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -147,8 +147,8 @@ static INLINE void varray_ef_quad( struct varray_frontend *varray, unsigned i2, unsigned i3 ) { - const unsigned omitEdge1 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_2; - const unsigned omitEdge2 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_1; + const ushort omitEdge1 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_2; + const ushort omitEdge2 = DRAW_PIPE_EDGE_FLAG_0 | DRAW_PIPE_EDGE_FLAG_1; varray_triangle_flags( varray, DRAW_PIPE_RESET_STIPPLE | omitEdge1, diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index e3f4e67472..c88bc137ee 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -31,9 +31,11 @@ * Brian Paul */ +#include "pipe/p_config.h" + #include "draw_vs.h" -#if defined(__i386__) || defined(__386__) +#if defined(PIPE_ARCH_X86) #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c index f01e12faa0..5499018b21 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_cpu.c +++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c @@ -47,7 +47,7 @@ static boolean rtasm_sse_enabled(void) int rtasm_cpu_has_sse(void) { /* FIXME: actually detect this at run-time */ -#if defined(__i386__) || defined(__386__) || defined(i386) +#if defined(PIPE_ARCH_X86) return rtasm_sse_enabled(); #else return 0; @@ -57,7 +57,7 @@ int rtasm_cpu_has_sse(void) int rtasm_cpu_has_sse2(void) { /* FIXME: actually detect this at run-time */ -#if defined(__i386__) || defined(__386__) || defined(i386) +#if defined(PIPE_ARCH_X86) return rtasm_sse_enabled(); #else return 0; diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 4e036d9032..6cd88ebca3 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -21,7 +21,9 @@ * **************************************************************************/ -#if defined(__i386__) || defined(__386__) || defined(i386) +#include "pipe/p_config.h" + +#if defined(PIPE_ARCH_X86) #include "pipe/p_compiler.h" #include "pipe/p_debug.h" diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index eacaeeaf6f..a5afa16395 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -24,7 +24,9 @@ #ifndef _RTASM_X86SSE_H_ #define _RTASM_X86SSE_H_ -#if defined(__i386__) || defined(__386__) || defined(i386) +#include "pipe/p_config.h" + +#if defined(PIPE_ARCH_X86) /* It is up to the caller to ensure that instructions issued are * suitable for the host cpu. There are no checks made in this module diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.c b/src/gallium/auxiliary/tgsi/util/tgsi_util.c index 4cdd89182a..56a50d3b21 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_util.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_util.c @@ -8,7 +8,7 @@ union pointer_hack { void *pointer; - unsigned long long uint64; + uint64_t uint64; }; void * diff --git a/src/gallium/auxiliary/translate/translate.c b/src/gallium/auxiliary/translate/translate.c index b04bc6eefd..b93fbf9033 100644 --- a/src/gallium/auxiliary/translate/translate.c +++ b/src/gallium/auxiliary/translate/translate.c @@ -30,6 +30,7 @@ * Keith Whitwell */ +#include "pipe/p_config.h" #include "pipe/p_util.h" #include "pipe/p_state.h" #include "translate.h" @@ -38,7 +39,7 @@ struct translate *translate_create( const struct translate_key *key ) { struct translate *translate = NULL; -#if defined(__i386__) || defined(__386__) || defined(i386) +#if defined(PIPE_ARCH_X86) translate = translate_sse2_create( key ); if (translate) return translate; diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 402780ee53..8f3b470333 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -255,140 +255,140 @@ static fetch_func get_fetch_func( enum pipe_format format ) { switch (format) { case PIPE_FORMAT_R64_FLOAT: - return fetch_R64_FLOAT; + return &fetch_R64_FLOAT; case PIPE_FORMAT_R64G64_FLOAT: - return fetch_R64G64_FLOAT; + return &fetch_R64G64_FLOAT; case PIPE_FORMAT_R64G64B64_FLOAT: - return fetch_R64G64B64_FLOAT; + return &fetch_R64G64B64_FLOAT; case PIPE_FORMAT_R64G64B64A64_FLOAT: - return fetch_R64G64B64A64_FLOAT; + return &fetch_R64G64B64A64_FLOAT; case PIPE_FORMAT_R32_FLOAT: - return fetch_R32_FLOAT; + return &fetch_R32_FLOAT; case PIPE_FORMAT_R32G32_FLOAT: - return fetch_R32G32_FLOAT; + return &fetch_R32G32_FLOAT; case PIPE_FORMAT_R32G32B32_FLOAT: - return fetch_R32G32B32_FLOAT; + return &fetch_R32G32B32_FLOAT; case PIPE_FORMAT_R32G32B32A32_FLOAT: - return fetch_R32G32B32A32_FLOAT; + return &fetch_R32G32B32A32_FLOAT; case PIPE_FORMAT_R32_UNORM: - return fetch_R32_UNORM; + return &fetch_R32_UNORM; case PIPE_FORMAT_R32G32_UNORM: - return fetch_R32G32_UNORM; + return &fetch_R32G32_UNORM; case PIPE_FORMAT_R32G32B32_UNORM: - return fetch_R32G32B32_UNORM; + return &fetch_R32G32B32_UNORM; case PIPE_FORMAT_R32G32B32A32_UNORM: - return fetch_R32G32B32A32_UNORM; + return &fetch_R32G32B32A32_UNORM; case PIPE_FORMAT_R32_USCALED: - return fetch_R32_USCALED; + return &fetch_R32_USCALED; case PIPE_FORMAT_R32G32_USCALED: - return fetch_R32G32_USCALED; + return &fetch_R32G32_USCALED; case PIPE_FORMAT_R32G32B32_USCALED: - return fetch_R32G32B32_USCALED; + return &fetch_R32G32B32_USCALED; case PIPE_FORMAT_R32G32B32A32_USCALED: - return fetch_R32G32B32A32_USCALED; + return &fetch_R32G32B32A32_USCALED; case PIPE_FORMAT_R32_SNORM: - return fetch_R32_SNORM; + return &fetch_R32_SNORM; case PIPE_FORMAT_R32G32_SNORM: - return fetch_R32G32_SNORM; + return &fetch_R32G32_SNORM; case PIPE_FORMAT_R32G32B32_SNORM: - return fetch_R32G32B32_SNORM; + return &fetch_R32G32B32_SNORM; case PIPE_FORMAT_R32G32B32A32_SNORM: - return fetch_R32G32B32A32_SNORM; + return &fetch_R32G32B32A32_SNORM; case PIPE_FORMAT_R32_SSCALED: - return fetch_R32_SSCALED; + return &fetch_R32_SSCALED; case PIPE_FORMAT_R32G32_SSCALED: - return fetch_R32G32_SSCALED; + return &fetch_R32G32_SSCALED; case PIPE_FORMAT_R32G32B32_SSCALED: - return fetch_R32G32B32_SSCALED; + return &fetch_R32G32B32_SSCALED; case PIPE_FORMAT_R32G32B32A32_SSCALED: - return fetch_R32G32B32A32_SSCALED; + return &fetch_R32G32B32A32_SSCALED; case PIPE_FORMAT_R16_UNORM: - return fetch_R16_UNORM; + return &fetch_R16_UNORM; case PIPE_FORMAT_R16G16_UNORM: - return fetch_R16G16_UNORM; + return &fetch_R16G16_UNORM; case PIPE_FORMAT_R16G16B16_UNORM: - return fetch_R16G16B16_UNORM; + return &fetch_R16G16B16_UNORM; case PIPE_FORMAT_R16G16B16A16_UNORM: - return fetch_R16G16B16A16_UNORM; + return &fetch_R16G16B16A16_UNORM; case PIPE_FORMAT_R16_USCALED: - return fetch_R16_USCALED; + return &fetch_R16_USCALED; case PIPE_FORMAT_R16G16_USCALED: - return fetch_R16G16_USCALED; + return &fetch_R16G16_USCALED; case PIPE_FORMAT_R16G16B16_USCALED: - return fetch_R16G16B16_USCALED; + return &fetch_R16G16B16_USCALED; case PIPE_FORMAT_R16G16B16A16_USCALED: - return fetch_R16G16B16A16_USCALED; + return &fetch_R16G16B16A16_USCALED; case PIPE_FORMAT_R16_SNORM: - return fetch_R16_SNORM; + return &fetch_R16_SNORM; case PIPE_FORMAT_R16G16_SNORM: - return fetch_R16G16_SNORM; + return &fetch_R16G16_SNORM; case PIPE_FORMAT_R16G16B16_SNORM: - return fetch_R16G16B16_SNORM; + return &fetch_R16G16B16_SNORM; case PIPE_FORMAT_R16G16B16A16_SNORM: - return fetch_R16G16B16A16_SNORM; + return &fetch_R16G16B16A16_SNORM; case PIPE_FORMAT_R16_SSCALED: - return fetch_R16_SSCALED; + return &fetch_R16_SSCALED; case PIPE_FORMAT_R16G16_SSCALED: - return fetch_R16G16_SSCALED; + return &fetch_R16G16_SSCALED; case PIPE_FORMAT_R16G16B16_SSCALED: - return fetch_R16G16B16_SSCALED; + return &fetch_R16G16B16_SSCALED; case PIPE_FORMAT_R16G16B16A16_SSCALED: - return fetch_R16G16B16A16_SSCALED; + return &fetch_R16G16B16A16_SSCALED; case PIPE_FORMAT_R8_UNORM: - return fetch_R8_UNORM; + return &fetch_R8_UNORM; case PIPE_FORMAT_R8G8_UNORM: - return fetch_R8G8_UNORM; + return &fetch_R8G8_UNORM; case PIPE_FORMAT_R8G8B8_UNORM: - return fetch_R8G8B8_UNORM; + return &fetch_R8G8B8_UNORM; case PIPE_FORMAT_R8G8B8A8_UNORM: - return fetch_R8G8B8A8_UNORM; + return &fetch_R8G8B8A8_UNORM; case PIPE_FORMAT_R8_USCALED: - return fetch_R8_USCALED; + return &fetch_R8_USCALED; case PIPE_FORMAT_R8G8_USCALED: - return fetch_R8G8_USCALED; + return &fetch_R8G8_USCALED; case PIPE_FORMAT_R8G8B8_USCALED: - return fetch_R8G8B8_USCALED; + return &fetch_R8G8B8_USCALED; case PIPE_FORMAT_R8G8B8A8_USCALED: - return fetch_R8G8B8A8_USCALED; + return &fetch_R8G8B8A8_USCALED; case PIPE_FORMAT_R8_SNORM: - return fetch_R8_SNORM; + return &fetch_R8_SNORM; case PIPE_FORMAT_R8G8_SNORM: - return fetch_R8G8_SNORM; + return &fetch_R8G8_SNORM; case PIPE_FORMAT_R8G8B8_SNORM: - return fetch_R8G8B8_SNORM; + return &fetch_R8G8B8_SNORM; case PIPE_FORMAT_R8G8B8A8_SNORM: - return fetch_R8G8B8A8_SNORM; + return &fetch_R8G8B8A8_SNORM; case PIPE_FORMAT_R8_SSCALED: - return fetch_R8_SSCALED; + return &fetch_R8_SSCALED; case PIPE_FORMAT_R8G8_SSCALED: - return fetch_R8G8_SSCALED; + return &fetch_R8G8_SSCALED; case PIPE_FORMAT_R8G8B8_SSCALED: - return fetch_R8G8B8_SSCALED; + return &fetch_R8G8B8_SSCALED; case PIPE_FORMAT_R8G8B8A8_SSCALED: - return fetch_R8G8B8A8_SSCALED; + return &fetch_R8G8B8A8_SSCALED; case PIPE_FORMAT_A8R8G8B8_UNORM: - return fetch_A8R8G8B8_UNORM; + return &fetch_A8R8G8B8_UNORM; case PIPE_FORMAT_B8G8R8A8_UNORM: - return fetch_B8G8R8A8_UNORM; + return &fetch_B8G8R8A8_UNORM; default: assert(0); - return fetch_NULL; + return &fetch_NULL; } } @@ -399,140 +399,140 @@ static emit_func get_emit_func( enum pipe_format format ) { switch (format) { case PIPE_FORMAT_R64_FLOAT: - return emit_R64_FLOAT; + return &emit_R64_FLOAT; case PIPE_FORMAT_R64G64_FLOAT: - return emit_R64G64_FLOAT; + return &emit_R64G64_FLOAT; case PIPE_FORMAT_R64G64B64_FLOAT: - return emit_R64G64B64_FLOAT; + return &emit_R64G64B64_FLOAT; case PIPE_FORMAT_R64G64B64A64_FLOAT: - return emit_R64G64B64A64_FLOAT; + return &emit_R64G64B64A64_FLOAT; case PIPE_FORMAT_R32_FLOAT: - return emit_R32_FLOAT; + return &emit_R32_FLOAT; case PIPE_FORMAT_R32G32_FLOAT: - return emit_R32G32_FLOAT; + return &emit_R32G32_FLOAT; case PIPE_FORMAT_R32G32B32_FLOAT: - return emit_R32G32B32_FLOAT; + return &emit_R32G32B32_FLOAT; case PIPE_FORMAT_R32G32B32A32_FLOAT: - return emit_R32G32B32A32_FLOAT; + return &emit_R32G32B32A32_FLOAT; case PIPE_FORMAT_R32_UNORM: - return emit_R32_UNORM; + return &emit_R32_UNORM; case PIPE_FORMAT_R32G32_UNORM: - return emit_R32G32_UNORM; + return &emit_R32G32_UNORM; case PIPE_FORMAT_R32G32B32_UNORM: - return emit_R32G32B32_UNORM; + return &emit_R32G32B32_UNORM; case PIPE_FORMAT_R32G32B32A32_UNORM: - return emit_R32G32B32A32_UNORM; + return &emit_R32G32B32A32_UNORM; case PIPE_FORMAT_R32_USCALED: - return emit_R32_USCALED; + return &emit_R32_USCALED; case PIPE_FORMAT_R32G32_USCALED: - return emit_R32G32_USCALED; + return &emit_R32G32_USCALED; case PIPE_FORMAT_R32G32B32_USCALED: - return emit_R32G32B32_USCALED; + return &emit_R32G32B32_USCALED; case PIPE_FORMAT_R32G32B32A32_USCALED: - return emit_R32G32B32A32_USCALED; + return &emit_R32G32B32A32_USCALED; case PIPE_FORMAT_R32_SNORM: - return emit_R32_SNORM; + return &emit_R32_SNORM; case PIPE_FORMAT_R32G32_SNORM: - return emit_R32G32_SNORM; + return &emit_R32G32_SNORM; case PIPE_FORMAT_R32G32B32_SNORM: - return emit_R32G32B32_SNORM; + return &emit_R32G32B32_SNORM; case PIPE_FORMAT_R32G32B32A32_SNORM: - return emit_R32G32B32A32_SNORM; + return &emit_R32G32B32A32_SNORM; case PIPE_FORMAT_R32_SSCALED: - return emit_R32_SSCALED; + return &emit_R32_SSCALED; case PIPE_FORMAT_R32G32_SSCALED: - return emit_R32G32_SSCALED; + return &emit_R32G32_SSCALED; case PIPE_FORMAT_R32G32B32_SSCALED: - return emit_R32G32B32_SSCALED; + return &emit_R32G32B32_SSCALED; case PIPE_FORMAT_R32G32B32A32_SSCALED: - return emit_R32G32B32A32_SSCALED; + return &emit_R32G32B32A32_SSCALED; case PIPE_FORMAT_R16_UNORM: - return emit_R16_UNORM; + return &emit_R16_UNORM; case PIPE_FORMAT_R16G16_UNORM: - return emit_R16G16_UNORM; + return &emit_R16G16_UNORM; case PIPE_FORMAT_R16G16B16_UNORM: - return emit_R16G16B16_UNORM; + return &emit_R16G16B16_UNORM; case PIPE_FORMAT_R16G16B16A16_UNORM: - return emit_R16G16B16A16_UNORM; + return &emit_R16G16B16A16_UNORM; case PIPE_FORMAT_R16_USCALED: - return emit_R16_USCALED; + return &emit_R16_USCALED; case PIPE_FORMAT_R16G16_USCALED: - return emit_R16G16_USCALED; + return &emit_R16G16_USCALED; case PIPE_FORMAT_R16G16B16_USCALED: - return emit_R16G16B16_USCALED; + return &emit_R16G16B16_USCALED; case PIPE_FORMAT_R16G16B16A16_USCALED: - return emit_R16G16B16A16_USCALED; + return &emit_R16G16B16A16_USCALED; case PIPE_FORMAT_R16_SNORM: - return emit_R16_SNORM; + return &emit_R16_SNORM; case PIPE_FORMAT_R16G16_SNORM: - return emit_R16G16_SNORM; + return &emit_R16G16_SNORM; case PIPE_FORMAT_R16G16B16_SNORM: - return emit_R16G16B16_SNORM; + return &emit_R16G16B16_SNORM; case PIPE_FORMAT_R16G16B16A16_SNORM: - return emit_R16G16B16A16_SNORM; + return &emit_R16G16B16A16_SNORM; case PIPE_FORMAT_R16_SSCALED: - return emit_R16_SSCALED; + return &emit_R16_SSCALED; case PIPE_FORMAT_R16G16_SSCALED: - return emit_R16G16_SSCALED; + return &emit_R16G16_SSCALED; case PIPE_FORMAT_R16G16B16_SSCALED: - return emit_R16G16B16_SSCALED; + return &emit_R16G16B16_SSCALED; case PIPE_FORMAT_R16G16B16A16_SSCALED: - return emit_R16G16B16A16_SSCALED; + return &emit_R16G16B16A16_SSCALED; case PIPE_FORMAT_R8_UNORM: - return emit_R8_UNORM; + return &emit_R8_UNORM; case PIPE_FORMAT_R8G8_UNORM: - return emit_R8G8_UNORM; + return &emit_R8G8_UNORM; case PIPE_FORMAT_R8G8B8_UNORM: - return emit_R8G8B8_UNORM; + return &emit_R8G8B8_UNORM; case PIPE_FORMAT_R8G8B8A8_UNORM: - return emit_R8G8B8A8_UNORM; + return &emit_R8G8B8A8_UNORM; case PIPE_FORMAT_R8_USCALED: - return emit_R8_USCALED; + return &emit_R8_USCALED; case PIPE_FORMAT_R8G8_USCALED: - return emit_R8G8_USCALED; + return &emit_R8G8_USCALED; case PIPE_FORMAT_R8G8B8_USCALED: - return emit_R8G8B8_USCALED; + return &emit_R8G8B8_USCALED; case PIPE_FORMAT_R8G8B8A8_USCALED: - return emit_R8G8B8A8_USCALED; + return &emit_R8G8B8A8_USCALED; case PIPE_FORMAT_R8_SNORM: - return emit_R8_SNORM; + return &emit_R8_SNORM; case PIPE_FORMAT_R8G8_SNORM: - return emit_R8G8_SNORM; + return &emit_R8G8_SNORM; case PIPE_FORMAT_R8G8B8_SNORM: - return emit_R8G8B8_SNORM; + return &emit_R8G8B8_SNORM; case PIPE_FORMAT_R8G8B8A8_SNORM: - return emit_R8G8B8A8_SNORM; + return &emit_R8G8B8A8_SNORM; case PIPE_FORMAT_R8_SSCALED: - return emit_R8_SSCALED; + return &emit_R8_SSCALED; case PIPE_FORMAT_R8G8_SSCALED: - return emit_R8G8_SSCALED; + return &emit_R8G8_SSCALED; case PIPE_FORMAT_R8G8B8_SSCALED: - return emit_R8G8B8_SSCALED; + return &emit_R8G8B8_SSCALED; case PIPE_FORMAT_R8G8B8A8_SSCALED: - return emit_R8G8B8A8_SSCALED; + return &emit_R8G8B8A8_SSCALED; case PIPE_FORMAT_A8R8G8B8_UNORM: - return emit_A8R8G8B8_UNORM; + return &emit_A8R8G8B8_UNORM; case PIPE_FORMAT_B8G8R8A8_UNORM: - return emit_B8G8R8A8_UNORM; + return &emit_B8G8R8A8_UNORM; default: assert(0); - return emit_NULL; + return &emit_NULL; } } diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index a54ac5a82f..634b05b8a9 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -26,6 +26,7 @@ */ +#include "pipe/p_config.h" #include "pipe/p_compiler.h" #include "pipe/p_util.h" #include "util/u_simple_list.h" @@ -33,7 +34,7 @@ #include "translate.h" -#if defined(__i386__) || defined(__386__) || defined(i386) +#if defined(PIPE_ARCH_X86) #include "rtasm/rtasm_cpu.h" #include "rtasm/rtasm_x86sse.h" @@ -617,7 +618,7 @@ struct translate *translate_sse2_create( const struct translate_key *key ) #else -void translate_create_sse( const struct translate_key *key ) +struct translate *translate_sse2_create( const struct translate_key *key ) { return NULL; } diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h index 48ec7a4a96..f9963ce0e2 100644 --- a/src/gallium/auxiliary/util/u_time.h +++ b/src/gallium/auxiliary/util/u_time.h @@ -61,7 +61,7 @@ struct util_time #if defined(PIPE_OS_LINUX) struct timeval tv; #else - long long counter; + int64_t counter; #endif }; diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index a4b772bc4f..96b21d998d 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -52,39 +52,55 @@ #endif /* __MSC__ */ -typedef unsigned int uint; -typedef unsigned char ubyte; -typedef unsigned char boolean; -typedef unsigned short ushort; -typedef unsigned long long uint64; - - #if defined(__MSC__) -typedef char int8_t; -typedef unsigned char uint8_t; -typedef short int16_t; -typedef unsigned short uint16_t; -typedef long int32_t; -typedef unsigned long uint32_t; -typedef long long int64_t; -typedef unsigned long long uint64_t; +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; #if defined(_WIN64) typedef __int64 intptr_t; typedef unsigned __int64 uintptr_t; #else -typedef int intptr_t; -typedef unsigned int uintptr_t; +typedef __int32 intptr_t; +typedef unsigned __int32 uintptr_t; #endif +#ifndef __cplusplus +#define false 0 +#define true 1 +#define bool _Bool +typedef int _Bool; +#define __bool_true_false_are_defined 1 +#endif /* !__cplusplus */ + #else #include +#include #endif -#define TRUE 1 -#define FALSE 0 +typedef unsigned int uint; +typedef unsigned char ubyte; +typedef unsigned short ushort; +typedef uint64_t uint64; + +#if 0 +#define boolean bool +#else +typedef unsigned char boolean; +#endif +#ifndef TRUE +#define TRUE true +#endif +#ifndef FALSE +#define FALSE false +#endif /* Function inlining */ diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index 6ba211a1fc..d2d2ae1617 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -35,6 +35,10 @@ * this file is auto-generated by an autoconf-like tool at some point, as some * things cannot be determined by existing defines alone. * + * See also: + * - http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html + * - echo | gcc -dM -E - | sort + * - http://msdn.microsoft.com/en-us/library/b0084kay.aspx * @author José Fonseca */ @@ -63,11 +67,11 @@ * Processor architecture */ -#if defined(_X86_) || defined(__i386__) || defined(__386__) || defined(i386) +#if defined(__i386__) /* gcc */ || defined(_M_IX86) /* msvc */ || defined(_X86_) || defined(__386__) || defined(i386) #define PIPE_ARCH_X86 #endif -#if 0 /* FIXME */ +#if defined(__x86_64__) /* gcc */ || defined(_M_X64) /* msvc */ || defined(_M_AMD64) /* msvc */ #define PIPE_ARCH_X86_64 #endif diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 0af635be57..05eca75201 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -59,6 +59,13 @@ extern "C" { #endif #endif + +/* MSVC bebore VC7 does not have the __FUNCTION__ macro */ +#if defined(_MSC_VER) && _MSC_VER < 1300 +#define __FUNCTION__ "???" +#endif + + void _debug_vprintf(const char *format, va_list ap); @@ -127,8 +134,8 @@ void _debug_break(void); #ifdef DEBUG #if (defined(__i386__) || defined(__386__)) && defined(__GNUC__) #define debug_break() __asm("int3") -#elif (defined(__i386__) || defined(__386__)) && defined(__MSC__) -#define debug_break() _asm {int 3} +#elif defined(_M_IX86) && defined(_MSC_VER) +#define debug_break() do { _asm {int 3} } while(0) #else #define debug_break() _debug_break() #endif -- cgit v1.2.3 From c2bd95abf60a8b6ea83dce3fc67603b36f937484 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 May 2008 01:18:45 +0200 Subject: i915: Make EGL_i915 segfault if modesetting is not working --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index ac1825210e..12eeff2b23 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -114,6 +114,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) struct drm_screen *screen = NULL; drmModeOutputPtr output = NULL; drmModeResPtr res = NULL; + unsigned count_outputs = 0; EGLint i; int fd; @@ -131,8 +132,10 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) drm_update_res(drm_drv); res = drm_drv->res; + if (res) + count_outputs = res->count_outputs; - for(i = 0; i < res->count_outputs; i++) { + for(i = 0; i < count_outputs; i++) { output = drmModeGetOutput(fd, res->outputs[i]); if (!output) -- cgit v1.2.3 From ae3795a968f07fc150d4c34aa1a9cd067f33b914 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 May 2008 12:27:27 +0200 Subject: i915: Make EGL_i915 compile --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 12eeff2b23..98dbe26376 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "eglconfig.h" #include "eglcontext.h" @@ -13,7 +14,6 @@ #include "eglscreen.h" #include "eglsurface.h" -#include "glapi.h" #include "intel_egl.h" #include "xf86drm.h" @@ -283,9 +283,9 @@ drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext /* generate handle and insert into hash table */ _eglSaveContext(&c->base); - assert(c->base.Handle); + assert(_eglGetContextHandle(&c->base)); - return c->base.Handle; + return _eglGetContextHandle(&c->base); err_gl: free(context); err_c: -- cgit v1.2.3 From 5d90f97f48f8ba231d52bb1a4758dd37f81ec8d6 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 May 2008 12:27:52 +0200 Subject: i915: Don't segfault on buffer allocation error --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 98dbe26376..809371fdeb 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -479,12 +479,13 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, DRM_BO_FLAG_NO_EVICT, DRM_BO_HINT_DONT_FENCE, &scrn->buffer); - prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); if (ret) { printf("failed to create framebuffer (ret %d)\n", ret); return EGL_FALSE; } + prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); + ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height, 32, 32, pitch, scrn->buffer.handle, -- cgit v1.2.3 From 08130512b9961da76a6385403d56387125df5e8c Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 27 May 2008 13:18:25 +0200 Subject: i915: Made vbuf work --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 248 +++++++++++++++++++++-- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 4 +- 2 files changed, 228 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index 7fb2adbb53..81293d0d1f 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -62,8 +62,14 @@ struct i915_vbuf_render { /** Vertex size in bytes */ unsigned vertex_size; + /** Software primitive */ + unsigned prim; + /** Hardware primitive */ unsigned hwprim; + + /** Genereate a vertex list */ + unsigned fallback; }; @@ -95,8 +101,8 @@ i915_vbuf_render_get_vertex_info( struct vbuf_render *render ) static void * i915_vbuf_render_allocate_vertices( struct vbuf_render *render, - ushort vertex_size, - ushort nr_vertices ) + ushort vertex_size, + ushort nr_vertices ) { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; @@ -107,9 +113,9 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render, assert(!i915->vbo); i915->vbo = winsys->buffer_create(winsys, 64, I915_BUFFER_USAGE_LIT_VERTEX, size); - + i915->dirty |= I915_NEW_VBO; - + return winsys->buffer_map(winsys, i915->vbo, PIPE_BUFFER_USAGE_CPU_WRITE); @@ -121,16 +127,36 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render, unsigned prim ) { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); - + i915_render->prim = prim; + switch(prim) { case PIPE_PRIM_POINTS: i915_render->hwprim = PRIM3D_POINTLIST; + i915_render->fallback = 0; return TRUE; case PIPE_PRIM_LINES: i915_render->hwprim = PRIM3D_LINELIST; + i915_render->fallback = 0; + return TRUE; + case PIPE_PRIM_LINE_STRIP: + i915_render->hwprim = PRIM3D_LINESTRIP; + i915_render->fallback = 0; return TRUE; case PIPE_PRIM_TRIANGLES: i915_render->hwprim = PRIM3D_TRILIST; + i915_render->fallback = 0; + return TRUE; + case PIPE_PRIM_TRIANGLE_STRIP: + i915_render->hwprim = PRIM3D_TRISTRIP; + i915_render->fallback = 0; + return TRUE; + case PIPE_PRIM_QUADS: + i915_render->hwprim = PRIM3D_TRILIST; + i915_render->fallback = PIPE_PRIM_QUADS; + return TRUE; + case PIPE_PRIM_QUAD_STRIP: + i915_render->hwprim = PRIM3D_TRILIST; + i915_render->fallback = PIPE_PRIM_QUAD_STRIP; return TRUE; default: /* Actually, can handle a lot more just fine... Fixme. @@ -140,6 +166,179 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render, } + +/** + * Used for fallbacks in draw_arrays + */ +static void +draw_arrays_generate_indices( struct vbuf_render *render, + unsigned start, uint nr, + unsigned type ) +{ + struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + struct i915_context *i915 = i915_render->i915; + unsigned i; + unsigned end = start + nr; + switch(type) { + case 0: + for (i = start; i+1 < end; i += 2) + OUT_BATCH( (i+0) | (i+1) << 16 ); + if (i < end) + OUT_BATCH( i ); + break; + case PIPE_PRIM_QUADS: + for (i = start; i + 3 < end; i += 4) { + OUT_BATCH( (i+0) | (i+1) << 16 ); + OUT_BATCH( (i+3) | (i+1) << 16 ); + OUT_BATCH( (i+2) | (i+3) << 16 ); + } + break; + case PIPE_PRIM_QUAD_STRIP: + for (i = start; i + 3 < end; i += 2) { + OUT_BATCH( (i+0) | (i+1) << 16 ); + OUT_BATCH( (i+3) | (i+2) << 16 ); + OUT_BATCH( (i+0) | (i+3) << 16 ); + } + break; + default: + assert(0); + } +} + +static unsigned +draw_arrays_calc_nr_indices( uint nr, unsigned type ) +{ + switch (type) { + case 0: + return nr; + case PIPE_PRIM_QUADS: + return (nr / 4) * 6; + case PIPE_PRIM_QUAD_STRIP: + return ((nr - 2) / 2) * 6; + default: + assert(0); + return 0; + } +} + +static void +draw_arrays_fallback( struct vbuf_render *render, + unsigned start, + uint nr ) +{ + struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + struct i915_context *i915 = i915_render->i915; + struct pipe_winsys *winsys = i915->pipe.winsys; + unsigned nr_indices; + + winsys->buffer_unmap( winsys, i915->vbo ); + if (i915->dirty) + i915_update_derived( i915 ); + + if (i915->hardware_dirty) + i915_emit_hardware_state( i915 ); + + nr_indices = draw_arrays_calc_nr_indices( nr, i915_render->fallback ); + + if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { + FLUSH_BATCH(NULL); + + /* Make sure state is re-emitted after a flush: + */ + i915_update_derived( i915 ); + i915_emit_hardware_state( i915 ); + + if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { + assert(0); + goto out; + } + } + OUT_BATCH( _3DPRIMITIVE | + PRIM_INDIRECT | + i915_render->hwprim | + PRIM_INDIRECT_ELTS | + nr_indices ); + + draw_arrays_generate_indices( render, start, nr, i915_render->fallback ); +out: + winsys->buffer_map( winsys, i915->vbo, PIPE_BUFFER_USAGE_CPU_WRITE ); +} + +static void +i915_vbuf_render_draw_arrays( struct vbuf_render *render, + unsigned start, + uint nr ) +{ + struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + + if (i915_render->fallback) { + draw_arrays_fallback( render, start, nr ); + return; + } + + /* JB: TODO submit direct cmds */ + draw_arrays_fallback( render, start, nr ); +} + +/** + * Used for normal and fallback emitting of indices + * If type is zero normal operation assumed. + */ +static void +draw_generate_indices( struct vbuf_render *render, + const ushort *indices, + uint nr_indices, + unsigned type ) +{ + struct i915_vbuf_render *i915_render = i915_vbuf_render(render); + struct i915_context *i915 = i915_render->i915; + unsigned i; + + switch(type) { + case 0: + for (i = 0; i + 1 < nr_indices; i += 2) { + OUT_BATCH( (indices[i] & 0x0FFF) | ((indices[i+1] & 0x0FFF) << 16) ); + } + if (i < nr_indices) { + OUT_BATCH( indices[i] & 0x0FFF ); + } + break; + case PIPE_PRIM_QUADS: + for (i = 0; i + 3 < nr_indices; i += 4) { + OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 ); + OUT_BATCH( (indices[i+3] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 ); + OUT_BATCH( (indices[i+2] & 0x0FFF) | (indices[i+3] & 0x0FFF) << 16 ); + } + break; + case PIPE_PRIM_QUAD_STRIP: + for (i = 0; i + 3 < nr_indices; i += 2) { + OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 ); + OUT_BATCH( (indices[i+3] & 0x0FFF) | (indices[i+2] & 0x0FFF) << 16 ); + OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+3] & 0x0FFF) << 16 ); + } + break; + default: + assert(0); + break; + } +} + +static unsigned +draw_calc_nr_indices( uint nr_indices, unsigned type ) +{ + switch (type) { + case 0: + return nr_indices; + case PIPE_PRIM_QUADS: + return (nr_indices / 4) * 6; + case PIPE_PRIM_QUAD_STRIP: + return ((nr_indices - 2) / 2) * 6; + default: + assert(0); + return 0; + } +} + static void i915_vbuf_render_draw( struct vbuf_render *render, const ushort *indices, @@ -147,13 +346,15 @@ i915_vbuf_render_draw( struct vbuf_render *render, { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; - unsigned i; + struct pipe_winsys *winsys = i915->pipe.winsys; + unsigned save_nr_indices; + + save_nr_indices = nr_indices; + nr_indices = draw_calc_nr_indices( nr_indices, i915_render->fallback ); assert(nr_indices); + winsys->buffer_unmap( winsys, i915->vbo ); - /* this seems to be bogus, since we validate state right after this */ - /*assert((i915->dirty & ~I915_NEW_VBO) == 0);*/ - if (i915->dirty) i915_update_derived( i915 ); @@ -170,22 +371,23 @@ i915_vbuf_render_draw( struct vbuf_render *render, if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { assert(0); - return; + goto out; } } OUT_BATCH( _3DPRIMITIVE | - PRIM_INDIRECT | - i915_render->hwprim | - PRIM_INDIRECT_ELTS | - nr_indices ); - for (i = 0; i + 1 < nr_indices; i += 2) { - OUT_BATCH( indices[i] | - (indices[i + 1] << 16) ); - } - if (i < nr_indices) { - OUT_BATCH( indices[i] ); - } + PRIM_INDIRECT | + i915_render->hwprim | + PRIM_INDIRECT_ELTS | + nr_indices ); + draw_generate_indices( render, + indices, + save_nr_indices, + i915_render->fallback ); + +out: + winsys->buffer_map( winsys, i915->vbo, PIPE_BUFFER_USAGE_CPU_WRITE ); + return; } @@ -234,6 +436,7 @@ i915_vbuf_render_create( struct i915_context *i915 ) i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices; i915_render->base.set_primitive = i915_vbuf_render_set_primitive; i915_render->base.draw = i915_vbuf_render_draw; + i915_render->base.draw_arrays = i915_vbuf_render_draw_arrays; i915_render->base.release_vertices = i915_vbuf_render_release_vertices; i915_render->base.destroy = i915_vbuf_render_destroy; @@ -258,6 +461,7 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 ) render->destroy(render); return NULL; } - + draw_set_render(i915->draw, render); + return stage; } diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 10e1a84cc1..059b16be3b 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -328,8 +328,8 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_TT, - 32 * 4096, - 1, 40, 32 * 4096 * 2, 0, + 128, + 6, 120, 32 * 4096, 0, fMan); } -- cgit v1.2.3 From cb5e05d99c40d4f7ab1ecbb42a6390caf3966ba4 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 27 May 2008 19:00:16 +0200 Subject: i915: Made vertex submission eaven faster --- src/gallium/drivers/i915simple/i915_context.h | 2 + src/gallium/drivers/i915simple/i915_flush.c | 1 + src/gallium/drivers/i915simple/i915_prim_vbuf.c | 66 +++++++++++++++++----- .../drivers/i915simple/i915_state_immediate.c | 2 +- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 8 +-- 5 files changed, 61 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 53fc5ed079..2da90ae49d 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -245,6 +245,8 @@ struct i915_context /** Vertex buffer */ struct pipe_buffer *vbo; + size_t vbo_offset; + unsigned vbo_flushed; struct i915_state current; unsigned hardware_dirty; diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c index 7d23e6b6b9..4c4718d68e 100644 --- a/src/gallium/drivers/i915simple/i915_flush.c +++ b/src/gallium/drivers/i915simple/i915_flush.c @@ -68,6 +68,7 @@ static void i915_flush( struct pipe_context *pipe, /* If there are no flags, just flush pending commands to hardware: */ FLUSH_BATCH(fence); + i915->vbo_flushed = 1; } diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index 81293d0d1f..4f36c2a22a 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -70,6 +70,13 @@ struct i915_vbuf_render { /** Genereate a vertex list */ unsigned fallback; + + /* Stuff for the vbo */ + struct pipe_buffer *vbo; + size_t vbo_size; + size_t vbo_offset; + void *vbo_ptr; + size_t vbo_alloc_size; }; @@ -111,14 +118,31 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render, /* FIXME: handle failure */ assert(!i915->vbo); - i915->vbo = winsys->buffer_create(winsys, 64, I915_BUFFER_USAGE_LIT_VERTEX, - size); + if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) { + } else { + i915->vbo_flushed = 0; + pipe_buffer_reference(winsys, &i915_render->vbo, NULL); + } + + if (!i915_render->vbo) { + i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size); + i915_render->vbo_offset = 0; + i915_render->vbo = winsys->buffer_create(winsys, + 64, + I915_BUFFER_USAGE_LIT_VERTEX, + i915_render->vbo_size); + i915_render->vbo_ptr = winsys->buffer_map(winsys, + i915_render->vbo, + PIPE_BUFFER_USAGE_CPU_WRITE); + winsys->buffer_unmap(winsys, i915_render->vbo); + } + + i915->vbo = i915_render->vbo; + i915->vbo_offset = i915_render->vbo_offset; i915->dirty |= I915_NEW_VBO; - return winsys->buffer_map(winsys, - i915->vbo, - PIPE_BUFFER_USAGE_CPU_WRITE); + return i915_render->vbo_ptr + i915->vbo_offset; } @@ -231,7 +255,6 @@ draw_arrays_fallback( struct vbuf_render *render, struct pipe_winsys *winsys = i915->pipe.winsys; unsigned nr_indices; - winsys->buffer_unmap( winsys, i915->vbo ); if (i915->dirty) i915_update_derived( i915 ); @@ -247,6 +270,7 @@ draw_arrays_fallback( struct vbuf_render *render, */ i915_update_derived( i915 ); i915_emit_hardware_state( i915 ); + i915->vbo_flushed = 1; if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { assert(0); @@ -260,8 +284,9 @@ draw_arrays_fallback( struct vbuf_render *render, nr_indices ); draw_arrays_generate_indices( render, start, nr, i915_render->fallback ); + out: - winsys->buffer_map( winsys, i915->vbo, PIPE_BUFFER_USAGE_CPU_WRITE ); + return; } static void @@ -353,7 +378,6 @@ i915_vbuf_render_draw( struct vbuf_render *render, nr_indices = draw_calc_nr_indices( nr_indices, i915_render->fallback ); assert(nr_indices); - winsys->buffer_unmap( winsys, i915->vbo ); if (i915->dirty) i915_update_derived( i915 ); @@ -368,6 +392,7 @@ i915_vbuf_render_draw( struct vbuf_render *render, */ i915_update_derived( i915 ); i915_emit_hardware_state( i915 ); + i915->vbo_flushed = 1; if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { assert(0); @@ -386,7 +411,6 @@ i915_vbuf_render_draw( struct vbuf_render *render, i915_render->fallback ); out: - winsys->buffer_map( winsys, i915->vbo, PIPE_BUFFER_USAGE_CPU_WRITE ); return; } @@ -400,10 +424,13 @@ i915_vbuf_render_release_vertices( struct vbuf_render *render, struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; struct pipe_winsys *winsys = i915->pipe.winsys; + size_t size = (size_t)vertex_size * (size_t)vertices_used; assert(i915->vbo); - winsys->buffer_unmap(winsys, i915->vbo); - pipe_buffer_reference(winsys, &i915->vbo, NULL); + + i915_render->vbo_offset += size; + i915->vbo = NULL; + i915->dirty |= I915_NEW_VBO; } @@ -422,6 +449,7 @@ static struct vbuf_render * i915_vbuf_render_create( struct i915_context *i915 ) { struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render); + struct pipe_winsys *winsys = i915->pipe.winsys; i915_render->i915 = i915; @@ -431,7 +459,7 @@ i915_vbuf_render_create( struct i915_context *i915 ) * batch buffer. */ i915_render->base.max_indices = 16*1024; - + i915_render->base.get_vertex_info = i915_vbuf_render_get_vertex_info; i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices; i915_render->base.set_primitive = i915_vbuf_render_set_primitive; @@ -439,7 +467,19 @@ i915_vbuf_render_create( struct i915_context *i915 ) i915_render->base.draw_arrays = i915_vbuf_render_draw_arrays; i915_render->base.release_vertices = i915_vbuf_render_release_vertices; i915_render->base.destroy = i915_vbuf_render_destroy; - + + i915_render->vbo_alloc_size = 128 * 4096; + i915_render->vbo_size = i915_render->vbo_alloc_size; + i915_render->vbo_offset = 0; + i915_render->vbo = winsys->buffer_create(winsys, + 64, + I915_BUFFER_USAGE_LIT_VERTEX, + i915_render->vbo_size); + i915_render->vbo_ptr = winsys->buffer_map(winsys, + i915_render->vbo, + PIPE_BUFFER_USAGE_CPU_WRITE); + winsys->buffer_unmap(winsys, i915_render->vbo); + return &i915_render->base; } diff --git a/src/gallium/drivers/i915simple/i915_state_immediate.c b/src/gallium/drivers/i915simple/i915_state_immediate.c index dfbbcab624..704ea4d838 100644 --- a/src/gallium/drivers/i915simple/i915_state_immediate.c +++ b/src/gallium/drivers/i915simple/i915_state_immediate.c @@ -54,7 +54,7 @@ static void upload_S0S1(struct i915_context *i915) /* INTEL_NEW_VBO */ /* TODO: re-use vertex buffers here? */ - LIS0 = 0; + LIS0 = i915->vbo_offset; /* INTEL_NEW_VERTEX_SIZE -- do this where the vertex size is calculated! */ diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 059b16be3b..fb8f44c845 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -224,7 +224,6 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned tex_usage) { const unsigned alignment = 64; - //int ret; surf->width = width; surf->height = height; @@ -235,7 +234,8 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); + surf->pitch * surf->cpp * surf->height); + if(!surf->buffer) return -1; @@ -328,8 +328,8 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MEM_TT, - 128, - 6, 120, 32 * 4096, 0, + 128 * 4096, + 1, 120, 128 * 4096 * 4, 0, fMan); } -- cgit v1.2.3 From ce56bcb640072496809d2aefede5a32fe9256ace Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 27 May 2008 21:15:36 +0200 Subject: i915: Prepare for tiled private front and back buffers --- src/gallium/drivers/i915simple/i915_state_emit.c | 1 + src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 26 ++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 6f947d4346..8bcc26ad35 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -217,6 +217,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) OUT_BATCH(BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(pitch) | /* pitch in bytes */ +// BUF_3D_TILED_SURFACE); /* JB: Used to force tileing */ BUF_3D_USE_FENCE); OUT_RELOC(cbuf_surface->buffer, diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index fb8f44c845..2e6c452cd1 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -212,6 +212,15 @@ round_up(unsigned n, unsigned multiple) return (n + multiple - 1) & ~(multiple - 1); } +static unsigned +power_of_two(unsigned x) +{ + int value = 1; + while (value <= x) + value = value << 1; + return value; +} + /*pipe_buffer_reference(winsys, &i915_render->vbo, NULL);*/ /** * Copied from xm_winsys.c */ @@ -224,18 +233,31 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned tex_usage) { const unsigned alignment = 64; + assert(!surf->buffer); +#if 0 + surf->width = width; + surf->height = round_up(height, 8); + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = power_of_two(MAX2(width * surf->cpp, 512)); + surf->buffer = winsys->buffer_create(winsys, 2*4096, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->height); + + surf->pitch = surf->pitch / surf->cpp; + surf->height = height; +#else surf->width = width; surf->height = height; surf->format = format; surf->cpp = pf_get_size(format); surf->pitch = round_up(width, alignment / surf->cpp); - assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, surf->pitch * surf->cpp * surf->height); - +#endif if(!surf->buffer) return -1; -- cgit v1.2.3 From 4b1f382e13ba2d8ad08bdf8dac1738ad1d22acf3 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 May 2008 14:22:07 +0200 Subject: i915: Remove workaround for buggy draw module --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index 4f36c2a22a..faf5971abb 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -322,24 +322,24 @@ draw_generate_indices( struct vbuf_render *render, switch(type) { case 0: for (i = 0; i + 1 < nr_indices; i += 2) { - OUT_BATCH( (indices[i] & 0x0FFF) | ((indices[i+1] & 0x0FFF) << 16) ); + OUT_BATCH( indices[i] | indices[i+1] << 16 ); } if (i < nr_indices) { - OUT_BATCH( indices[i] & 0x0FFF ); + OUT_BATCH( indices[i] ); } break; case PIPE_PRIM_QUADS: for (i = 0; i + 3 < nr_indices; i += 4) { - OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 ); - OUT_BATCH( (indices[i+3] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 ); - OUT_BATCH( (indices[i+2] & 0x0FFF) | (indices[i+3] & 0x0FFF) << 16 ); + OUT_BATCH( indices[i+0] | indices[i+1] << 16 ); + OUT_BATCH( indices[i+3] | indices[i+1] << 16 ); + OUT_BATCH( indices[i+2] | indices[i+3] << 16 ); } break; case PIPE_PRIM_QUAD_STRIP: for (i = 0; i + 3 < nr_indices; i += 2) { - OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+1] & 0x0FFF) << 16 ); - OUT_BATCH( (indices[i+3] & 0x0FFF) | (indices[i+2] & 0x0FFF) << 16 ); - OUT_BATCH( (indices[i+0] & 0x0FFF) | (indices[i+3] & 0x0FFF) << 16 ); + OUT_BATCH( indices[i+0] | indices[i+1] << 16 ); + OUT_BATCH( indices[i+3] | indices[i+2] << 16 ); + OUT_BATCH( indices[i+0] | indices[i+3] << 16 ); } break; default: -- cgit v1.2.3 From 2c004a4bece706c590f5ab03432d2aa65d6d0263 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 May 2008 14:22:50 +0200 Subject: i915: DriConfigOptions started complaining on this line --- src/gallium/winsys/dri/intel/intel_screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 58bebbe972..429a2cf8f8 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -50,11 +50,11 @@ PUBLIC const char __driConfigOptions[] = DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY - DRI_CONF_FORCE_S3TC_ENABLE(false) +// DRI_CONF_FORCE_S3TC_ENABLE(false) DRI_CONF_ALLOW_LARGE_TEXTURES(1) DRI_CONF_SECTION_END DRI_CONF_END; -const uint __driNConfigOptions = 4; +const uint __driNConfigOptions = 3; #ifdef USE_NEW_INTERFACE static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; -- cgit v1.2.3 From 4767c10cbb87a77e6cb24c53815c38bd5887c771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 28 May 2008 21:47:25 +0900 Subject: translate: Mark functions as PIPE_CDECL. --- src/gallium/auxiliary/translate/translate_sse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index 2fc8b9d3d0..69dd4d3dff 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -534,7 +534,7 @@ static void translate_sse_release( struct translate *translate ) FREE(p); } -static void translate_sse_run_elts( struct translate *translate, +static void PIPE_CDECL translate_sse_run_elts( struct translate *translate, const unsigned *elts, unsigned count, void *output_buffer ) @@ -547,7 +547,7 @@ static void translate_sse_run_elts( struct translate *translate, output_buffer ); } -static void translate_sse_run( struct translate *translate, +static void PIPE_CDECL translate_sse_run( struct translate *translate, unsigned start, unsigned count, void *output_buffer ) -- cgit v1.2.3 From 7a986792dabe6556c63b2f2a997c7c6217604e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 28 May 2008 21:48:30 +0900 Subject: tgsi: Observe constness. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 648afa2a51..b018ea9fa1 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -754,7 +754,7 @@ tgsi_dump_instruction( } for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + const struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; if( !first_reg ) { CHR( ',' ); @@ -812,7 +812,7 @@ tgsi_dump_instruction( } for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + const struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; if( !first_reg ) { CHR( ',' ); -- cgit v1.2.3 From 276552c0dd8d9d68b8324c42b05c768c45a9db76 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 28 May 2008 14:52:10 +0200 Subject: i915: Add draw_flush to state changes --- src/gallium/drivers/i915simple/i915_state.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index e6c4671700..39d5d5e9d6 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -41,7 +41,6 @@ #include "i915_state_inlines.h" #include "i915_fpc.h" - /* The i915 (and related graphics cores) do not support GL_CLAMP. The * Intel drivers for "other operating systems" implement GL_CLAMP as * GL_CLAMP_TO_EDGE, so the same is done here. @@ -178,6 +177,7 @@ static void i915_bind_blend_state(struct pipe_context *pipe, void *blend) { struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); i915->blend = (struct i915_blend_state*)blend; @@ -194,6 +194,7 @@ 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); i915->blend_color = *blend_color; @@ -280,6 +281,8 @@ static void i915_bind_sampler_states(struct pipe_context *pipe, !memcmp(i915->sampler, sampler, 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) @@ -398,6 +401,7 @@ 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); i915->depth_stencil = (const struct i915_depth_stencil_state *)depth_stencil; @@ -415,6 +419,7 @@ static void i915_set_scissor_state( struct pipe_context *pipe, 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; @@ -451,6 +456,7 @@ static void i915_bind_fs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); i915->fs = (struct i915_fragment_shader*) shader; @@ -506,6 +512,7 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, { struct i915_context *i915 = i915_context(pipe); struct pipe_winsys *ws = pipe->winsys; + draw_flush(i915->draw); assert(shader < PIPE_SHADER_TYPES); assert(index == 0); @@ -574,6 +581,7 @@ static void i915_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); i915->framebuffer = *fb; /* struct copy */ @@ -586,6 +594,7 @@ 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); draw_set_clip_state(i915->draw, clip); @@ -698,6 +707,10 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe, const struct pipe_vertex_buffer *buffers) { struct i915_context *i915 = i915_context(pipe); + /* Because we change state before the draw_set_vertex_buffers call + * we need a flush here, just to be sure. + */ + draw_flush(i915->draw); memcpy(i915->vertex_buffer, buffers, count * sizeof(buffers[0])); i915->num_vertex_buffers = count; @@ -711,6 +724,11 @@ static void i915_set_vertex_elements(struct pipe_context *pipe, const struct pipe_vertex_element *elements) { struct i915_context *i915 = i915_context(pipe); + /* Because we change state before the draw_set_vertex_buffers call + * we need a flush here, just to be sure. + */ + draw_flush(i915->draw); + i915->num_vertex_elements = count; /* pass-through to draw module */ draw_set_vertex_elements(i915->draw, count, elements); -- cgit v1.2.3 From ff44dd5cde47c81f90c5293b904e1c7edd006be5 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 28 May 2008 15:10:19 +0200 Subject: draw: Decorate callbacks with PIPE_CDECL. --- src/gallium/auxiliary/draw/draw_vs_varient.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index 119a3a04b5..784ae41205 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -130,10 +130,10 @@ static void do_viewport( struct draw_vs_varient_generic *vsvg, } -static void vsvg_run_elts( struct draw_vs_varient *varient, - const unsigned *elts, - unsigned count, - void *output_buffer) +static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, + const unsigned *elts, + unsigned count, + void *output_buffer ) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; @@ -186,10 +186,10 @@ static void vsvg_run_elts( struct draw_vs_varient *varient, } -static void vsvg_run_linear( struct draw_vs_varient *varient, - unsigned start, - unsigned count, - void *output_buffer ) +static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, + unsigned start, + unsigned count, + void *output_buffer ) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; -- cgit v1.2.3 From e407e83966f2d7d6d9751fc0069ebacd4808d89d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 28 May 2008 15:10:39 +0200 Subject: scons: List missing files for draw module. --- src/gallium/auxiliary/draw/SConscript | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 3b5d5ed492..96f1ae248f 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -15,7 +15,7 @@ draw = env.ConvenienceLibrary( 'draw_pipe_stipple.c', 'draw_pipe_twoside.c', 'draw_pipe_unfilled.c', - 'draw_pipe_util.c', + 'draw_pipe_util.c', 'draw_pipe_validate.c', 'draw_pipe_vbuf.c', 'draw_pipe_wide_line.c', @@ -25,8 +25,10 @@ draw = env.ConvenienceLibrary( 'draw_pt_emit.c', 'draw_pt_fetch.c', 'draw_pt_fetch_emit.c', + 'draw_pt_fetch_shade_emit.c', 'draw_pt_fetch_shade_pipeline.c', 'draw_pt_post_vs.c', + 'draw_pt_util.c', 'draw_pt_varray.c', 'draw_pt_vcache.c', 'draw_vertex.c', @@ -34,6 +36,7 @@ draw = env.ConvenienceLibrary( 'draw_vs_exec.c', 'draw_vs_llvm.c', 'draw_vs_sse.c', + 'draw_vs_varient.c' ]) auxiliaries.insert(0, draw) -- cgit v1.2.3 From 25cec212d05b613a83eb2bc2167e3dab88da0967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 28 May 2008 22:19:26 +0900 Subject: scons: Add new files. --- src/gallium/auxiliary/draw/SConscript | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 96f1ae248f..26919a2298 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -31,8 +31,11 @@ draw = env.ConvenienceLibrary( 'draw_pt_util.c', 'draw_pt_varray.c', 'draw_pt_vcache.c', + 'draw_pt_util.c', 'draw_vertex.c', 'draw_vs.c', + 'draw_vs_aos.c', + 'draw_vs_aos_io.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', 'draw_vs_sse.c', -- cgit v1.2.3 From 364f75d9dbc2b8e19c884b9cc74676ab6cbee60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 28 May 2008 22:19:58 +0900 Subject: draw: Use PIPE_CDECL. --- src/gallium/auxiliary/draw/draw_vs_aos.c | 20 ++++++++++---------- src/gallium/auxiliary/draw/draw_vs_aos.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index d3770b2c53..0cd82ff599 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1189,7 +1189,7 @@ static boolean emit_FRC( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } -static PIPE_CDECL void do_lit( struct aos_machine *machine, +static void PIPE_CDECL do_lit( struct aos_machine *machine, float *result, const float *in, unsigned count ) @@ -1223,7 +1223,7 @@ static PIPE_CDECL void do_lit( struct aos_machine *machine, } -static PIPE_CDECL void do_lit_lut( struct aos_machine *machine, +static void PIPE_CDECL do_lit_lut( struct aos_machine *machine, float *result, const float *in, unsigned count ) @@ -2119,10 +2119,10 @@ static void vaos_destroy( struct draw_vs_varient *varient ) FREE(vaos); } -static void vaos_run_elts( struct draw_vs_varient *varient, - const unsigned *elts, - unsigned count, - void *output_buffer ) +static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient, + const unsigned *elts, + unsigned count, + void *output_buffer ) { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; @@ -2133,10 +2133,10 @@ static void vaos_run_elts( struct draw_vs_varient *varient, output_buffer ); } -static void vaos_run_linear( struct draw_vs_varient *varient, - unsigned start, - unsigned count, - void *output_buffer ) +static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient, + unsigned start, + unsigned count, + void *output_buffer ) { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index b47413ff43..837b32794f 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -60,7 +60,7 @@ struct x86_function; #define FPU_RND_NEAREST 2 struct aos_machine; -typedef void PIPE_CDECL (*lit_func)( struct aos_machine *, +typedef void (PIPE_CDECL *lit_func)( struct aos_machine *, float *result, const float *in, unsigned count ); -- cgit v1.2.3 From 648da5158e5f418bf859aee6aa4532b6899b0d94 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 28 May 2008 16:36:45 +0100 Subject: rtasm: special case for [ebp] --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 2415b0156b..672d2ff554 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -328,7 +328,7 @@ struct x86_reg x86_make_disp( struct x86_reg reg, else reg.disp += disp; - if (reg.disp == 0) + if (reg.disp == 0 && reg.idx != reg_BP) reg.mod = mod_INDIRECT; else if (reg.disp <= 127 && reg.disp >= -128) reg.mod = mod_DISP8; -- cgit v1.2.3 From 728d1f7f43b6db9f4f42c2d16ba223c492d1147d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 28 May 2008 23:54:18 +0100 Subject: draw: enable FSE by default --- src/gallium/auxiliary/draw/draw_pt.c | 11 ++- src/gallium/auxiliary/draw/draw_vs.h | 4 ++ src/gallium/auxiliary/draw/draw_vs_aos.c | 105 +++++++++++++++++++++------- src/gallium/auxiliary/draw/draw_vs_aos.h | 34 +++++---- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 25 ++++--- src/gallium/auxiliary/draw/draw_vs_sse.c | 14 ++-- 6 files changed, 129 insertions(+), 64 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 75f44d503e..d48c6c220d 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -75,7 +75,7 @@ draw_pt_arrays(struct draw_context *draw, if (opt == 0) middle = draw->pt.middle.fetch_emit; - else if (opt == PT_SHADE && draw->pt.test_fse) + else if (opt == PT_SHADE) middle = draw->pt.middle.fetch_shade_emit; else middle = draw->pt.middle.general; @@ -118,12 +118,9 @@ boolean draw_pt_init( struct draw_context *draw ) if (!draw->pt.middle.fetch_emit) return FALSE; - if (draw->pt.test_fse) { - draw->pt.middle.fetch_shade_emit = draw_pt_middle_fse( draw ); - if (!draw->pt.middle.fetch_shade_emit) - return FALSE; - } - + draw->pt.middle.fetch_shade_emit = draw_pt_middle_fse( draw ); + if (!draw->pt.middle.fetch_shade_emit) + return FALSE; draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit( draw ); if (!draw->pt.middle.general) diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 01171bc23d..7aa0415baf 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -123,6 +123,10 @@ struct draw_vertex_shader { struct tgsi_shader_info info; + /* Extracted from shader: + */ + const float (*immediates)[4]; + /* */ struct draw_vs_varient *varient[16]; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 0cd82ff599..9056785e7a 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -66,6 +66,37 @@ static INLINE boolean eq( struct x86_reg a, a.disp == b.disp); } +struct x86_reg aos_get_x86( struct aos_compilation *cp, + unsigned value ) +{ + if (cp->ebp != value) { + unsigned offset; + + switch (value) { + case X86_IMMEDIATES: + offset = Offset(struct aos_machine, immediates); + break; + case X86_CONSTANTS: + offset = Offset(struct aos_machine, constants); + break; + case X86_ATTRIBS: + offset = Offset(struct aos_machine, attrib); + break; + default: + assert(0); + offset = 0; + } + + x86_mov(cp->func, cp->temp_EBP, + x86_make_disp(cp->machine_EDX, offset)); + /* x86_deref(x86_make_disp(cp->machine_EDX, offset))); */ + + cp->ebp = value; + } + + return cp->temp_EBP; +} + static struct x86_reg get_reg_ptr(struct aos_compilation *cp, unsigned file, @@ -83,15 +114,15 @@ static struct x86_reg get_reg_ptr(struct aos_compilation *cp, case TGSI_FILE_TEMPORARY: return x86_make_disp(ptr, Offset(struct aos_machine, temp[idx])); - case TGSI_FILE_IMMEDIATE: - return x86_make_disp(ptr, Offset(struct aos_machine, immediate[idx])); - - case TGSI_FILE_CONSTANT: - return x86_make_disp(ptr, Offset(struct aos_machine, constant[idx])); - case AOS_FILE_INTERNAL: return x86_make_disp(ptr, Offset(struct aos_machine, internal[idx])); + case TGSI_FILE_IMMEDIATE: + return x86_make_disp(aos_get_x86(cp, X86_IMMEDIATES), idx * 4 * sizeof(float)); + + case TGSI_FILE_CONSTANT: + return x86_make_disp(aos_get_x86(cp, X86_CONSTANTS), idx * 4 * sizeof(float)); + default: ERROR(cp, "unknown reg file"); return x86_make_reg(0,0); @@ -1865,6 +1896,7 @@ static boolean emit_rhw_viewport( struct aos_compilation *cp ) } +#if 0 static boolean note_immediate( struct aos_compilation *cp, struct tgsi_full_immediate *imm ) { @@ -1877,6 +1909,7 @@ static boolean note_immediate( struct aos_compilation *cp, return TRUE; } +#endif @@ -1939,6 +1972,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, cp.outbuf_ECX = x86_make_reg(file_REG32, reg_CX); cp.machine_EDX = x86_make_reg(file_REG32, reg_DX); cp.count_ESI = x86_make_reg(file_REG32, reg_SI); + cp.temp_EBP = x86_make_reg(file_REG32, reg_BP); x86_init_func(cp.func); @@ -1946,6 +1980,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, x86_push(cp.func, cp.idx_EBX); x86_push(cp.func, cp.count_ESI); + x86_push(cp.func, cp.temp_EBP); /* Load arguments into regs: @@ -1988,8 +2023,10 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, switch (parse.FullToken.Token.Type) { case TGSI_TOKEN_TYPE_IMMEDIATE: +#if 0 if (!note_immediate( &cp, &parse.FullToken.FullImmediate )) goto fail; +#endif break; case TGSI_TOKEN_TYPE_INSTRUCTION: @@ -2072,6 +2109,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, if (cp.func->need_emms) mmx_emms(cp.func); + x86_pop(cp.func, cp.temp_EBP); x86_pop(cp.func, cp.count_ESI); x86_pop(cp.func, cp.idx_EBX); @@ -2098,26 +2136,14 @@ static void vaos_set_buffer( struct draw_vs_varient *varient, for (i = 0; i < vaos->base.key.nr_inputs; i++) { if (vaos->base.key.element[i].in.buffer == buf) { - vaos->machine->attrib[i].input_ptr = ((char *)ptr + - vaos->base.key.element[i].in.offset); - vaos->machine->attrib[i].input_stride = stride; + vaos->attrib[i].input_ptr = ((char *)ptr + + vaos->base.key.element[i].in.offset); + vaos->attrib[i].input_stride = stride; } } } -static void vaos_destroy( struct draw_vs_varient *varient ) -{ - struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; - - if (vaos->machine) - align_free( vaos->machine ); - - x86_release_func( &vaos->func[0] ); - x86_release_func( &vaos->func[1] ); - - FREE(vaos); -} static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient, const unsigned *elts, @@ -2127,6 +2153,10 @@ static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient, struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; + vaos->machine->constants = vaos->draw->pt.user.constants; + vaos->machine->immediates = vaos->base.vs->immediates; + vaos->machine->attrib = vaos->attrib; + vaos->gen_run_elts( varient, elts, count, @@ -2141,6 +2171,10 @@ static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient, struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; + vaos->machine->constants = vaos->draw->pt.user.constants; + vaos->machine->immediates = vaos->base.vs->immediates; + vaos->machine->attrib = vaos->attrib; + vaos->gen_run_linear( varient, start, count, @@ -2153,10 +2187,6 @@ static void vaos_set_constants( struct draw_vs_varient *varient, { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; - memcpy(vaos->machine->constant, - constants, - (vaos->base.vs->info.file_max[TGSI_FILE_CONSTANT] + 1) * 4 * sizeof(float)); - #if 0 unsigned i; for (i =0; i < vaos->base.vs->info.file_max[TGSI_FILE_CONSTANT] + 1; i++) @@ -2187,6 +2217,21 @@ static void vaos_set_viewport( struct draw_vs_varient *varient, memcpy(vaos->machine->translate, viewport->translate, 4 * sizeof(float)); } +static void vaos_destroy( struct draw_vs_varient *varient ) +{ + struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + + if (vaos->machine) + align_free( vaos->machine ); + + FREE( vaos->attrib ); + + x86_release_func( &vaos->func[0] ); + x86_release_func( &vaos->func[1] ); + + FREE(vaos); +} + static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, @@ -2207,6 +2252,11 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, vaos->base.run_elts = vaos_run_elts; vaos->draw = vs->draw; + + vaos->attrib = MALLOC( key->nr_inputs * sizeof(vaos->attrib[0]) ); + if (!vaos->attrib) + goto fail; + vaos->machine = align_malloc( sizeof(struct aos_machine), 16 ); if (!vaos->machine) goto fail; @@ -2233,7 +2283,10 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, return &vaos->base; fail: - if (vaos->machine) + if (vaos && vaos->attrib) + FREE(vaos->attrib); + + if (vaos && vaos->machine) align_free( vaos->machine ); if (vaos) diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 837b32794f..295d2cb3fe 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -78,6 +78,14 @@ struct lit_info { #define MAX_SHINE_TAB 4 #define MAX_LIT_INFO 16 +struct aos_attrib { + const void *input_ptr; + unsigned input_stride; +}; + + + + /* This is the temporary storage used by all the aos_sse vs varients. * Create one per context and reuse by passing a pointer in at * vs_varient creation?? @@ -86,8 +94,6 @@ struct aos_machine { float input [MAX_INPUTS ][4]; float output [MAX_OUTPUTS ][4]; float temp [MAX_TEMPS ][4]; - float constant [MAX_CONSTANTS ][4]; /* fixme -- should just be a pointer */ - float immediate[MAX_IMMEDIATES][4]; /* fixme -- should just be a pointer */ float internal [MAX_INTERNALS ][4]; float scale[4]; /* viewport */ @@ -105,12 +111,10 @@ struct aos_machine { ushort fpu_restore; ushort fpucntl; /* one of FPU_* above */ - struct { - const void *input_ptr; - unsigned input_stride; + const float (*immediates)[4]; /* points to shader data */ + const float (*constants)[4]; /* points to draw data */ - unsigned output_offset; - } attrib[PIPE_MAX_ATTRIBS]; + const struct aos_attrib *attrib; /* points to ? */ }; @@ -132,6 +136,7 @@ struct aos_compilation { unsigned last_used; } xmm[8]; + unsigned ebp; /* one of X86_* */ boolean input_fetched[PIPE_MAX_ATTRIBS]; unsigned output_last_write[PIPE_MAX_ATTRIBS]; @@ -148,6 +153,7 @@ struct aos_compilation { struct x86_reg outbuf_ECX; struct x86_reg machine_EDX; struct x86_reg count_ESI; /* decrements to zero */ + struct x86_reg temp_EBP; }; struct x86_reg aos_get_xmm_reg( struct aos_compilation *cp ); @@ -192,20 +198,20 @@ do { \ } while (0) +#define X86_NULL 0 +#define X86_IMMEDIATES 1 +#define X86_CONSTANTS 2 +#define X86_ATTRIBS 3 - +struct x86_reg aos_get_x86( struct aos_compilation *cp, + unsigned value ); struct draw_vs_varient_aos_sse { struct draw_vs_varient base; struct draw_context *draw; -#if 0 - struct { - const void *ptr; - unsigned stride; - } attrib[PIPE_MAX_ATTRIBS]; -#endif + struct aos_attrib *attrib; struct aos_machine *machine; /* XXX: temporarily unshared */ diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index 836110f382..45e2092209 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -91,25 +91,25 @@ static void emit_load_R8G8B8A8_UNORM( struct aos_compilation *cp, -static void get_src_ptr( struct x86_function *func, +static void get_src_ptr( struct aos_compilation *cp, struct x86_reg src, - struct x86_reg machine, struct x86_reg elt, unsigned a ) { - struct x86_reg input_ptr = - x86_make_disp(machine, - Offset(struct aos_machine, attrib[a].input_ptr)); + struct x86_reg attrib = x86_make_disp(aos_get_x86( cp, X86_ATTRIBS ), + a * sizeof(struct aos_attrib)); - struct x86_reg input_stride = - x86_make_disp(machine, - Offset(struct aos_machine, attrib[a].input_stride)); + struct x86_reg input_ptr = x86_make_disp(attrib, + Offset(struct aos_attrib, input_ptr)); + + struct x86_reg input_stride = x86_make_disp(attrib, + Offset(struct aos_attrib, input_stride)); /* Calculate pointer to current attrib: */ - x86_mov(func, src, input_stride); - x86_imul(func, src, elt); - x86_add(func, src, input_ptr); + x86_mov(cp->func, src, input_stride); + x86_imul(cp->func, src, elt); + x86_add(cp->func, src, input_ptr); } @@ -134,9 +134,8 @@ static boolean load_input( struct aos_compilation *cp, /* Figure out source pointer address: */ - get_src_ptr(cp->func, + get_src_ptr(cp, src, - cp->machine_EDX, linear ? cp->idx_EBX : x86_deref(cp->idx_EBX), idx); diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 7781782ae8..24f619a278 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -68,8 +68,6 @@ struct draw_sse_vertex_shader { codegen_function func; struct tgsi_exec_machine *machine; - - float immediates[TGSI_EXEC_NUM_IMMEDIATES][4]; }; @@ -107,7 +105,7 @@ vs_sse_run_linear( struct draw_vertex_shader *base, machine->Outputs, (float (*)[4])constants, machine->Temps, - shader->immediates, + (float (*)[4])shader->base.immediates, input, base->info.num_inputs, input_stride, @@ -130,6 +128,8 @@ vs_sse_delete( struct draw_vertex_shader *base ) x86_release_func( &shader->sse2_program ); + align_free(shader->base.immediates); + FREE( (void*) shader->base.state.tokens ); FREE( shader ); } @@ -161,12 +161,18 @@ draw_create_vs_sse(struct draw_context *draw, vs->base.prepare = vs_sse_prepare; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; + + vs->base.immediates = align_malloc(TGSI_EXEC_NUM_IMMEDIATES * 4 * + sizeof(float), 16); + vs->machine = &draw->vs.machine; x86_init_func( &vs->sse2_program ); if (!tgsi_emit_sse2( (struct tgsi_token *) vs->base.state.tokens, - &vs->sse2_program, vs->immediates, TRUE )) + &vs->sse2_program, + (float (*)[4])vs->base.immediates, + TRUE )) goto fail; vs->func = (codegen_function) x86_get_func( &vs->sse2_program ); -- cgit v1.2.3 From 62628c4d3d497cbca73fde869c9069fa90e6453e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 29 May 2008 00:17:53 +0100 Subject: draw: share machine --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/SConscript | 1 + src/gallium/auxiliary/draw/draw_context.c | 3 + src/gallium/auxiliary/draw/draw_private.h | 9 + .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 6 - src/gallium/auxiliary/draw/draw_vs.c | 43 ++- src/gallium/auxiliary/draw/draw_vs.h | 24 +- src/gallium/auxiliary/draw/draw_vs_aos.c | 282 ++----------------- src/gallium/auxiliary/draw/draw_vs_aos.h | 25 +- src/gallium/auxiliary/draw/draw_vs_aos_machine.c | 297 +++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_varient.c | 49 +--- 11 files changed, 412 insertions(+), 328 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_vs_aos_machine.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 9a88ecc070..f2e36a89e9 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -37,6 +37,7 @@ C_SOURCES = \ draw_vs_varient.c \ draw_vs_aos.c \ draw_vs_aos_io.c \ + draw_vs_aos_machine.c \ draw_vs_exec.c \ draw_vs_llvm.c \ draw_vs_sse.c diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 26919a2298..925e668f22 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -36,6 +36,7 @@ draw = env.ConvenienceLibrary( 'draw_vs.c', 'draw_vs_aos.c', 'draw_vs_aos_io.c', + 'draw_vs_aos_machine.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', 'draw_vs_sse.c', diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 2242074965..8509baf865 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -174,6 +174,8 @@ void draw_set_viewport_state( struct draw_context *draw, viewport->translate[1] == 0.0f && viewport->translate[2] == 0.0f && viewport->translate[3] == 0.0f); + + draw_vs_set_viewport( draw, viewport ); } @@ -218,6 +220,7 @@ draw_set_mapped_constant_buffer(struct draw_context *draw, const void *buffer) { draw->pt.user.constants = buffer; + draw_vs_set_constants( draw, (const float (*)[4])buffer ); } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index c095bf3d7b..4cbccc8b5b 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -183,6 +183,10 @@ struct draw_context */ struct gallivm_cpu_engine *engine; + /* Here's another one: + */ + struct aos_machine *aos_machine; + struct translate *fetch; struct translate_cache *fetch_cache; @@ -215,6 +219,11 @@ struct draw_context boolean draw_vs_init( struct draw_context *draw ); void draw_vs_destroy( struct draw_context *draw ); +void draw_vs_set_viewport( struct draw_context *, + const struct pipe_viewport_state * ); + +void draw_vs_set_constants( struct draw_context *, + const float (*constants)[4] ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 729c7db999..5265a13160 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -189,12 +189,6 @@ static void fse_prepare( struct draw_pt_middle_end *middle, draw->pt.vertex_buffer[buf].pitch ); } - fse->active->set_constants( fse->active, - (const float (*)[4])draw->pt.user.constants ); - - fse->active->set_viewport( fse->active, - &draw->viewport ); - //return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 9b899d404e..a8b6d0c90d 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -41,6 +41,22 @@ + +void draw_vs_set_constants( struct draw_context *draw, + const float (*constants)[4] ) +{ + draw_vs_aos_machine_constants( draw->vs.aos_machine, constants ); +} + + +void draw_vs_set_viewport( struct draw_context *draw, + const struct pipe_viewport_state *viewport ) +{ + draw_vs_aos_machine_viewport( draw->vs.aos_machine, viewport ); +} + + + struct draw_vertex_shader * draw_create_vertex_shader(struct draw_context *draw, const struct pipe_shader_state *shader) @@ -83,6 +99,13 @@ void draw_delete_vertex_shader(struct draw_context *draw, struct draw_vertex_shader *dvs) { + unsigned i; + + for (i = 0; i < dvs->nr_varients; i++) + dvs->varient[i]->destroy( dvs->varient[i] ); + + dvs->nr_varients = 0; + dvs->delete( dvs ); } @@ -110,6 +133,10 @@ draw_vs_init( struct draw_context *draw ) draw->vs.fetch_cache = translate_cache_create(); if (!draw->vs.fetch_cache) return FALSE; + + draw->vs.aos_machine = draw_vs_aos_machine(); + if (!draw->vs.aos_machine) + return FALSE; return TRUE; } @@ -129,6 +156,9 @@ draw_vs_destroy( struct draw_context *draw ) if (draw->vs.emit_cache) translate_cache_destroy(draw->vs.emit_cache); + if (draw->vs.aos_machine) + draw_vs_aos_machine_destroy(draw->vs.aos_machine); + tgsi_exec_machine_free_data(&draw->vs.machine); } @@ -153,10 +183,17 @@ draw_vs_lookup_varient( struct draw_vertex_shader *vs, if (varient == NULL) return NULL; - /* Add it to our list: + /* Add it to our list, could be smarter: */ - assert(vs->nr_varients < Elements(vs->varient)); - vs->varient[vs->nr_varients++] = varient; + if (vs->nr_varients < Elements(vs->varient)) { + vs->varient[vs->nr_varients++] = varient; + } + else { + vs->last_varient++; + vs->last_varient %= Elements(vs->varient); + vs->varient[vs->last_varient]->destroy(vs->varient[vs->last_varient]); + vs->varient[vs->last_varient] = varient; + } /* Done */ diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 7aa0415baf..08c6de8ba8 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -70,16 +70,6 @@ struct draw_vs_varient_key { struct draw_vs_varient; -typedef void (PIPE_CDECL *vsv_run_elts_func)( struct draw_vs_varient *, - const unsigned *elts, - unsigned count, - void *output_buffer); - -typedef void (PIPE_CDECL *vsv_run_linear_func)( struct draw_vs_varient *, - unsigned start, - unsigned count, - void *output_buffer); - struct draw_vs_varient { struct draw_vs_varient_key key; @@ -91,12 +81,6 @@ struct draw_vs_varient { const void *ptr, unsigned stride ); - void (*set_constants)( struct draw_vs_varient *, - const float (*constants)[4] ); - - void (*set_viewport)( struct draw_vs_varient *, - const struct pipe_viewport_state * ); - void (PIPE_CDECL *run_linear)( struct draw_vs_varient *shader, unsigned start, unsigned count, @@ -131,6 +115,7 @@ struct draw_vertex_shader { */ struct draw_vs_varient *varient[16]; unsigned nr_varients; + unsigned last_varient; struct draw_vs_varient *(*create_varient)( struct draw_vertex_shader *shader, const struct draw_vs_varient_key *key ); @@ -217,7 +202,14 @@ static INLINE int draw_vs_varient_key_compare( const struct draw_vs_varient_key } +struct aos_machine *draw_vs_aos_machine( void ); +void draw_vs_aos_machine_destroy( struct aos_machine *machine ); + +void draw_vs_aos_machine_constants( struct aos_machine *machine, + const float (*constants)[4] ); +void draw_vs_aos_machine_viewport( struct aos_machine *machine, + const struct pipe_viewport_state *viewport ); #define MAX_TGSI_VERTICES 4 diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 9056785e7a..b5e4e1e7b1 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -149,70 +149,7 @@ static struct x86_reg get_reg_ptr(struct aos_compilation *cp, #define X87_CW_ROUND_MASK (3<<10) #define X87_CW_INFINITY (1<<12) -static void do_populate_lut( struct shine_tab *tab, - float unclamped_exponent ) -{ - const float epsilon = 1.0F / 256.0F; - float exponent = CLAMP(unclamped_exponent, -(128.0F - epsilon), (128.0F - epsilon)); - unsigned i; - tab->exponent = unclamped_exponent; /* for later comparison */ - - tab->values[0] = 0; - if (exponent == 0) { - for (i = 1; i < 258; i++) { - tab->values[i] = 1.0; - } - } - else { - for (i = 1; i < 258; i++) { - tab->values[i] = powf((float)i * epsilon, exponent); - } - } -} - -static void init_internals( struct aos_machine *machine ) -{ - unsigned i; - float inv = 1.0f/255.0f; - float f255 = 255.0f; - - ASSIGN_4V(machine->internal[IMM_SWZ], 1.0f, -1.0f, 0.0f, 1.0f); - *(unsigned *)&machine->internal[IMM_SWZ][3] = 0xffffffff; - - ASSIGN_4V(machine->internal[IMM_ONES], 1.0f, 1.0f, 1.0f, 1.0f); - ASSIGN_4V(machine->internal[IMM_NEGS], -1.0f, -1.0f, -1.0f, -1.0f); - ASSIGN_4V(machine->internal[IMM_IDENTITY], 0.0f, 0.0f, 0.0f, 1.0f); - ASSIGN_4V(machine->internal[IMM_INV_255], inv, inv, inv, inv); - ASSIGN_4V(machine->internal[IMM_255], f255, f255, f255, f255); - ASSIGN_4V(machine->internal[IMM_RSQ], -.5f, 1.5f, 0.0f, 0.0f); - - - machine->fpu_rnd_nearest = (X87_CW_EXCEPTION_INV_OP | - X87_CW_EXCEPTION_DENORM_OP | - X87_CW_EXCEPTION_ZERO_DIVIDE | - X87_CW_EXCEPTION_OVERFLOW | - X87_CW_EXCEPTION_UNDERFLOW | - X87_CW_EXCEPTION_PRECISION | - (1<<6) | - X87_CW_ROUND_NEAREST | - X87_CW_PRECISION_DOUBLE_EXT); - - assert(machine->fpu_rnd_nearest == 0x37f); - - machine->fpu_rnd_neg_inf = (X87_CW_EXCEPTION_INV_OP | - X87_CW_EXCEPTION_DENORM_OP | - X87_CW_EXCEPTION_ZERO_DIVIDE | - X87_CW_EXCEPTION_OVERFLOW | - X87_CW_EXCEPTION_UNDERFLOW | - X87_CW_EXCEPTION_PRECISION | - (1<<6) | - X87_CW_ROUND_DOWN | - X87_CW_PRECISION_DOUBLE_EXT); - - for (i = 0; i < MAX_SHINE_TAB; i++) - do_populate_lut( &machine->shine_tab[i], 1.0f ); -} static void spill( struct aos_compilation *cp, unsigned idx ) @@ -1220,136 +1157,6 @@ static boolean emit_FRC( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } -static void PIPE_CDECL do_lit( struct aos_machine *machine, - float *result, - const float *in, - unsigned count ) -{ - if (in[0] > 0) - { - if (in[1] <= 0.0) - { - result[0] = 1.0F; - result[1] = in[0]; - result[2] = 1.0; - result[3] = 1.0F; - } - else - { - const float epsilon = 1.0F / 256.0F; - float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon)); - result[0] = 1.0F; - result[1] = in[0]; - result[2] = powf(in[1], exponent); - result[3] = 1.0; - } - } - else - { - result[0] = 1.0F; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 1.0F; - } -} - - -static void PIPE_CDECL do_lit_lut( struct aos_machine *machine, - float *result, - const float *in, - unsigned count ) -{ - if (in[0] > 0) - { - if (in[1] <= 0.0) - { - result[0] = 1.0F; - result[1] = in[0]; - result[2] = 1.0; - result[3] = 1.0F; - return; - } - - if (machine->lit_info[count].shine_tab->exponent != in[3]) { - machine->lit_info[count].func = do_lit; - goto no_luck; - } - - if (in[1] <= 1.0) - { - const float *tab = machine->lit_info[count].shine_tab->values; - float f = in[1] * 256; - int k = (int)f; - float frac = f - (float)k; - - result[0] = 1.0F; - result[1] = in[0]; - result[2] = tab[k] + frac*(tab[k+1]-tab[k]); - result[3] = 1.0; - return; - } - - no_luck: - { - const float epsilon = 1.0F / 256.0F; - float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon)); - result[0] = 1.0F; - result[1] = in[0]; - result[2] = powf(in[1], exponent); - result[3] = 1.0; - } - } - else - { - result[0] = 1.0F; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 1.0F; - } -} - - - -static void PIPE_CDECL populate_lut( struct aos_machine *machine, - float *result, - const float *in, - unsigned count ) -{ - unsigned i, tab; - - /* Search for an existing table for this value. Note that without - * static analysis we don't really know if in[3] will be constant, - * but it usually is... - */ - for (tab = 0; tab < 4; tab++) { - if (machine->shine_tab[tab].exponent == in[3]) { - goto found; - } - } - - for (tab = 0, i = 1; i < 4; i++) { - if (machine->shine_tab[i].last_used < machine->shine_tab[tab].last_used) - tab = i; - } - - if (machine->shine_tab[tab].last_used == machine->now) { - /* No unused tables (this is not a ffvertex program...). Just - * call pow each time: - */ - machine->lit_info[count].func = do_lit; - machine->lit_info[count].func( machine, result, in, count ); - return; - } - else { - do_populate_lut( &machine->shine_tab[tab], in[3] ); - } - - found: - machine->shine_tab[tab].last_used = machine->now; - machine->lit_info[count].shine_tab = &machine->shine_tab[tab]; - machine->lit_info[count].func = do_lit_lut; - machine->lit_info[count].func( machine, result, in, count ); -} @@ -1413,7 +1220,7 @@ static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_inst Offset(struct lit_info, func))); } else { - x86_mov_reg_imm( cp->func, ecx, (int)do_lit ); + x86_mov_reg_imm( cp->func, ecx, (int)aos_do_lit ); } x86_call( cp->func, ecx ); @@ -1434,7 +1241,7 @@ static boolean emit_LIT( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } - +#if 0 static boolean emit_inline_LIT( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { struct x86_reg dst = get_dst_ptr(cp, &op->FullDstRegisters[0]); @@ -1495,6 +1302,7 @@ static boolean emit_inline_LIT( struct aos_compilation *cp, const struct tgsi_fu return TRUE; } +#endif @@ -1945,7 +1753,7 @@ static void find_last_write_outputs( struct aos_compilation *cp ) } -#define ARG_VARIENT 1 +#define ARG_MACHINE 1 #define ARG_START_ELTS 2 #define ARG_COUNT 3 #define ARG_OUTBUF 4 @@ -1985,7 +1793,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, /* Load arguments into regs: */ - x86_mov(cp.func, cp.machine_EDX, x86_fn_arg(cp.func, ARG_VARIENT)); + x86_mov(cp.func, cp.machine_EDX, x86_fn_arg(cp.func, ARG_MACHINE)); x86_mov(cp.func, cp.idx_EBX, x86_fn_arg(cp.func, ARG_START_ELTS)); x86_mov(cp.func, cp.count_ESI, x86_fn_arg(cp.func, ARG_COUNT)); x86_mov(cp.func, cp.outbuf_ECX, x86_fn_arg(cp.func, ARG_OUTBUF)); @@ -1997,11 +1805,6 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, x86_cmp(cp.func, cp.count_ESI, cp.tmp_EAX); fixup = x86_jcc_forward(cp.func, cc_E); - /* Dig out the machine pointer from inside the varient arg - */ - x86_mov(cp.func, cp.machine_EDX, - x86_make_disp(cp.machine_EDX, - Offset( struct draw_vs_varient_aos_sse, machine ))); save_fpu_state( &cp ); set_fpu_round_nearest( &cp ); @@ -2151,13 +1954,14 @@ static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient, void *output_buffer ) { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + struct aos_machine *machine = vaos->draw->vs.aos_machine; - vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; - vaos->machine->constants = vaos->draw->pt.user.constants; - vaos->machine->immediates = vaos->base.vs->immediates; - vaos->machine->attrib = vaos->attrib; + machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; + machine->constants = (const float (*)[4])vaos->draw->pt.user.constants; + machine->immediates = vaos->base.vs->immediates; + machine->attrib = vaos->attrib; - vaos->gen_run_elts( varient, + vaos->gen_run_elts( machine, elts, count, output_buffer ); @@ -2169,61 +1973,25 @@ static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient, void *output_buffer ) { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + struct aos_machine *machine = vaos->draw->vs.aos_machine; - vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; - vaos->machine->constants = vaos->draw->pt.user.constants; - vaos->machine->immediates = vaos->base.vs->immediates; - vaos->machine->attrib = vaos->attrib; + machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; + machine->constants = (const float (*)[4])vaos->draw->pt.user.constants; + machine->immediates = vaos->base.vs->immediates; + machine->attrib = vaos->attrib; - vaos->gen_run_linear( varient, + vaos->gen_run_linear( machine, start, count, output_buffer ); } -static void vaos_set_constants( struct draw_vs_varient *varient, - const float (*constants)[4] ) -{ - struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; - -#if 0 - unsigned i; - for (i =0; i < vaos->base.vs->info.file_max[TGSI_FILE_CONSTANT] + 1; i++) - debug_printf("state %d: %f %f %f %f\n", - i, - constants[i][0], - constants[i][1], - constants[i][2], - constants[i][3]); -#endif - - { - unsigned i; - for (i = 0; i < MAX_LIT_INFO; i++) { - vaos->machine->lit_info[i].func = populate_lut; - vaos->machine->now++; - } - } -} - - -static void vaos_set_viewport( struct draw_vs_varient *varient, - const struct pipe_viewport_state *viewport ) -{ - struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; - - memcpy(vaos->machine->scale, viewport->scale, 4 * sizeof(float)); - memcpy(vaos->machine->translate, viewport->translate, 4 * sizeof(float)); -} static void vaos_destroy( struct draw_vs_varient *varient ) { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; - if (vaos->machine) - align_free( vaos->machine ); - FREE( vaos->attrib ); x86_release_func( &vaos->func[0] ); @@ -2245,8 +2013,6 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, vaos->base.key = *key; vaos->base.vs = vs; vaos->base.set_input = vaos_set_buffer; - vaos->base.set_constants = vaos_set_constants; - vaos->base.set_viewport = vaos_set_viewport; vaos->base.destroy = vaos_destroy; vaos->base.run_linear = vaos_run_linear; vaos->base.run_elts = vaos_run_elts; @@ -2257,13 +2023,6 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, if (!vaos->attrib) goto fail; - vaos->machine = align_malloc( sizeof(struct aos_machine), 16 ); - if (!vaos->machine) - goto fail; - - memset(vaos->machine, 0, sizeof(struct aos_machine)); - init_internals(vaos->machine); - tgsi_dump(vs->state.tokens, 0); if (!build_vertex_program( vaos, TRUE )) @@ -2272,11 +2031,11 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, if (!build_vertex_program( vaos, FALSE )) goto fail; - vaos->gen_run_linear = (vsv_run_linear_func)x86_get_func(&vaos->func[0]); + vaos->gen_run_linear = (vaos_run_linear_func)x86_get_func(&vaos->func[0]); if (!vaos->gen_run_linear) goto fail; - vaos->gen_run_elts = (vsv_run_elts_func)x86_get_func(&vaos->func[1]); + vaos->gen_run_elts = (vaos_run_elts_func)x86_get_func(&vaos->func[1]); if (!vaos->gen_run_elts) goto fail; @@ -2286,9 +2045,6 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, if (vaos && vaos->attrib) FREE(vaos->attrib); - if (vaos && vaos->machine) - align_free( vaos->machine ); - if (vaos) x86_release_func( &vaos->func[0] ); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 295d2cb3fe..89a9174151 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -60,10 +60,16 @@ struct x86_function; #define FPU_RND_NEAREST 2 struct aos_machine; -typedef void (PIPE_CDECL *lit_func)( struct aos_machine *, +typedef void PIPE_CDECL (*lit_func)( struct aos_machine *, float *result, const float *in, unsigned count ); + +PIPE_CDECL void aos_do_lit( struct aos_machine *machine, + float *result, + const float *in, + unsigned count ); + struct shine_tab { float exponent; float values[258]; @@ -207,16 +213,25 @@ struct x86_reg aos_get_x86( struct aos_compilation *cp, unsigned value ); +typedef void (PIPE_CDECL *vaos_run_elts_func)( struct aos_machine *, + const unsigned *elts, + unsigned count, + void *output_buffer); + +typedef void (PIPE_CDECL *vaos_run_linear_func)( struct aos_machine *, + unsigned start, + unsigned count, + void *output_buffer); + + struct draw_vs_varient_aos_sse { struct draw_vs_varient base; struct draw_context *draw; struct aos_attrib *attrib; - struct aos_machine *machine; /* XXX: temporarily unshared */ - - vsv_run_linear_func gen_run_linear; - vsv_run_elts_func gen_run_elts; + vaos_run_linear_func gen_run_linear; + vaos_run_elts_func gen_run_elts; struct x86_function func[2]; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c new file mode 100644 index 0000000000..53e999b191 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c @@ -0,0 +1,297 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" +#include "tgsi/exec/tgsi_exec.h" +#include "draw_vs.h" +#include "draw_vs_aos.h" +#include "draw_vertex.h" + +#include "rtasm/rtasm_x86sse.h" + + +#define X87_CW_EXCEPTION_INV_OP (1<<0) +#define X87_CW_EXCEPTION_DENORM_OP (1<<1) +#define X87_CW_EXCEPTION_ZERO_DIVIDE (1<<2) +#define X87_CW_EXCEPTION_OVERFLOW (1<<3) +#define X87_CW_EXCEPTION_UNDERFLOW (1<<4) +#define X87_CW_EXCEPTION_PRECISION (1<<5) +#define X87_CW_PRECISION_SINGLE (0<<8) +#define X87_CW_PRECISION_RESERVED (1<<8) +#define X87_CW_PRECISION_DOUBLE (2<<8) +#define X87_CW_PRECISION_DOUBLE_EXT (3<<8) +#define X87_CW_PRECISION_MASK (3<<8) +#define X87_CW_ROUND_NEAREST (0<<10) +#define X87_CW_ROUND_DOWN (1<<10) +#define X87_CW_ROUND_UP (2<<10) +#define X87_CW_ROUND_ZERO (3<<10) +#define X87_CW_ROUND_MASK (3<<10) +#define X87_CW_INFINITY (1<<12) + + +PIPE_CDECL void aos_do_lit( struct aos_machine *machine, + float *result, + const float *in, + unsigned count ) +{ + if (in[0] > 0) + { + if (in[1] <= 0.0) + { + result[0] = 1.0F; + result[1] = in[0]; + result[2] = 1.0; + result[3] = 1.0F; + } + else + { + const float epsilon = 1.0F / 256.0F; + float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon)); + result[0] = 1.0F; + result[1] = in[0]; + result[2] = powf(in[1], exponent); + result[3] = 1.0; + } + } + else + { + result[0] = 1.0F; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 1.0F; + } +} + + +static PIPE_CDECL void do_lit_lut( struct aos_machine *machine, + float *result, + const float *in, + unsigned count ) +{ + if (in[0] > 0) + { + if (in[1] <= 0.0) + { + result[0] = 1.0F; + result[1] = in[0]; + result[2] = 1.0; + result[3] = 1.0F; + return; + } + + if (machine->lit_info[count].shine_tab->exponent != in[3]) { + machine->lit_info[count].func = aos_do_lit; + goto no_luck; + } + + if (in[1] <= 1.0) + { + const float *tab = machine->lit_info[count].shine_tab->values; + float f = in[1] * 256; + int k = (int)f; + float frac = f - (float)k; + + result[0] = 1.0F; + result[1] = in[0]; + result[2] = tab[k] + frac*(tab[k+1]-tab[k]); + result[3] = 1.0; + return; + } + + no_luck: + { + const float epsilon = 1.0F / 256.0F; + float exponent = CLAMP(in[3], -(128.0F - epsilon), (128.0F - epsilon)); + result[0] = 1.0F; + result[1] = in[0]; + result[2] = powf(in[1], exponent); + result[3] = 1.0; + } + } + else + { + result[0] = 1.0F; + result[1] = 0.0; + result[2] = 0.0; + result[3] = 1.0F; + } +} + + +static void do_populate_lut( struct shine_tab *tab, + float unclamped_exponent ) +{ + const float epsilon = 1.0F / 256.0F; + float exponent = CLAMP(unclamped_exponent, -(128.0F - epsilon), (128.0F - epsilon)); + unsigned i; + + tab->exponent = unclamped_exponent; /* for later comparison */ + + tab->values[0] = 0; + if (exponent == 0) { + for (i = 1; i < 258; i++) { + tab->values[i] = 1.0; + } + } + else { + for (i = 1; i < 258; i++) { + tab->values[i] = powf((float)i * epsilon, exponent); + } + } +} + + + + +static void PIPE_CDECL populate_lut( struct aos_machine *machine, + float *result, + const float *in, + unsigned count ) +{ + unsigned i, tab; + + /* Search for an existing table for this value. Note that without + * static analysis we don't really know if in[3] will be constant, + * but it usually is... + */ + for (tab = 0; tab < 4; tab++) { + if (machine->shine_tab[tab].exponent == in[3]) { + goto found; + } + } + + for (tab = 0, i = 1; i < 4; i++) { + if (machine->shine_tab[i].last_used < machine->shine_tab[tab].last_used) + tab = i; + } + + if (machine->shine_tab[tab].last_used == machine->now) { + /* No unused tables (this is not a ffvertex program...). Just + * call pow each time: + */ + machine->lit_info[count].func = aos_do_lit; + machine->lit_info[count].func( machine, result, in, count ); + return; + } + else { + do_populate_lut( &machine->shine_tab[tab], in[3] ); + } + + found: + machine->shine_tab[tab].last_used = machine->now; + machine->lit_info[count].shine_tab = &machine->shine_tab[tab]; + machine->lit_info[count].func = do_lit_lut; + machine->lit_info[count].func( machine, result, in, count ); +} + + +void draw_vs_aos_machine_constants( struct aos_machine *machine, + const float (*constants)[4] ) +{ + machine->constants = constants; + + { + unsigned i; + for (i = 0; i < MAX_LIT_INFO; i++) { + machine->lit_info[i].func = populate_lut; + machine->now++; + } + } +} + + +void draw_vs_aos_machine_viewport( struct aos_machine *machine, + const struct pipe_viewport_state *viewport ) +{ + memcpy(machine->scale, viewport->scale, 4 * sizeof(float)); + memcpy(machine->translate, viewport->translate, 4 * sizeof(float)); +} + + + +void draw_vs_aos_machine_destroy( struct aos_machine *machine ) +{ + align_free(machine); +} + +struct aos_machine *draw_vs_aos_machine( void ) +{ + struct aos_machine *machine; + unsigned i; + float inv = 1.0f/255.0f; + float f255 = 255.0f; + + machine = align_malloc(sizeof(struct aos_machine), 16); + if (!machine) + return NULL; + + memset(machine, 0, sizeof(*machine)); + + ASSIGN_4V(machine->internal[IMM_SWZ], 1.0f, -1.0f, 0.0f, 1.0f); + *(unsigned *)&machine->internal[IMM_SWZ][3] = 0xffffffff; + + ASSIGN_4V(machine->internal[IMM_ONES], 1.0f, 1.0f, 1.0f, 1.0f); + ASSIGN_4V(machine->internal[IMM_NEGS], -1.0f, -1.0f, -1.0f, -1.0f); + ASSIGN_4V(machine->internal[IMM_IDENTITY], 0.0f, 0.0f, 0.0f, 1.0f); + ASSIGN_4V(machine->internal[IMM_INV_255], inv, inv, inv, inv); + ASSIGN_4V(machine->internal[IMM_255], f255, f255, f255, f255); + ASSIGN_4V(machine->internal[IMM_RSQ], -.5f, 1.5f, 0.0f, 0.0f); + + + machine->fpu_rnd_nearest = (X87_CW_EXCEPTION_INV_OP | + X87_CW_EXCEPTION_DENORM_OP | + X87_CW_EXCEPTION_ZERO_DIVIDE | + X87_CW_EXCEPTION_OVERFLOW | + X87_CW_EXCEPTION_UNDERFLOW | + X87_CW_EXCEPTION_PRECISION | + (1<<6) | + X87_CW_ROUND_NEAREST | + X87_CW_PRECISION_DOUBLE_EXT); + + assert(machine->fpu_rnd_nearest == 0x37f); + + machine->fpu_rnd_neg_inf = (X87_CW_EXCEPTION_INV_OP | + X87_CW_EXCEPTION_DENORM_OP | + X87_CW_EXCEPTION_ZERO_DIVIDE | + X87_CW_EXCEPTION_OVERFLOW | + X87_CW_EXCEPTION_UNDERFLOW | + X87_CW_EXCEPTION_PRECISION | + (1<<6) | + X87_CW_ROUND_DOWN | + X87_CW_PRECISION_DOUBLE_EXT); + + for (i = 0; i < MAX_SHINE_TAB; i++) + do_populate_lut( &machine->shine_tab[i], 1.0f ); + + return machine; +} + + diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index 784ae41205..18cb06e374 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -44,8 +44,6 @@ struct draw_vs_varient_generic { struct draw_vs_varient base; - struct pipe_viewport_state viewport; - struct draw_vertex_shader *shader; struct draw_context *draw; @@ -57,21 +55,11 @@ struct draw_vs_varient_generic { */ struct translate *fetch; struct translate *emit; - - const float (*constants)[4]; }; -static void vsvg_set_constants( struct draw_vs_varient *varient, - const float (*constants)[4] ) -{ - struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; - - vsvg->constants = constants; -} - static void vsvg_set_input( struct draw_vs_varient *varient, unsigned buffer, @@ -94,8 +82,8 @@ static void do_rhw_viewport( struct draw_vs_varient_generic *vsvg, void *output_buffer ) { char *ptr = (char *)output_buffer; - const float *scale = vsvg->viewport.scale; - const float *trans = vsvg->viewport.translate; + const float *scale = vsvg->base.vs->draw->viewport.scale; + const float *trans = vsvg->base.vs->draw->viewport.translate; unsigned stride = vsvg->base.key.output_stride; unsigned j; @@ -115,8 +103,8 @@ static void do_viewport( struct draw_vs_varient_generic *vsvg, void *output_buffer ) { char *ptr = (char *)output_buffer; - const float *scale = vsvg->viewport.scale; - const float *trans = vsvg->viewport.translate; + const float *scale = vsvg->base.vs->draw->viewport.scale; + const float *trans = vsvg->base.vs->draw->viewport.translate; unsigned stride = vsvg->base.key.output_stride; unsigned j; @@ -130,10 +118,10 @@ static void do_viewport( struct draw_vs_varient_generic *vsvg, } -static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, - const unsigned *elts, - unsigned count, - void *output_buffer ) +static void vsvg_run_elts( struct draw_vs_varient *varient, + const unsigned *elts, + unsigned count, + void *output_buffer) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; @@ -150,7 +138,7 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, vsvg->base.vs->run_linear( vsvg->base.vs, output_buffer, output_buffer, - vsvg->constants, + (const float (*)[4])vsvg->base.vs->draw->pt.user.constants, count, vsvg->base.key.output_stride, vsvg->base.key.output_stride); @@ -186,10 +174,10 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, } -static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, - unsigned start, - unsigned count, - void *output_buffer ) +static void vsvg_run_linear( struct draw_vs_varient *varient, + unsigned start, + unsigned count, + void *output_buffer ) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; @@ -206,7 +194,7 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, vsvg->base.vs->run_linear( vsvg->base.vs, output_buffer, output_buffer, - vsvg->constants, + (const float (*)[4])vsvg->base.vs->draw->pt.user.constants, count, vsvg->base.key.output_stride, vsvg->base.key.output_stride); @@ -245,13 +233,6 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, -static void vsvg_set_viewport( struct draw_vs_varient *varient, - const struct pipe_viewport_state *viewport ) -{ - struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; - - vsvg->viewport = *viewport; -} static void vsvg_destroy( struct draw_vs_varient *varient ) { @@ -272,8 +253,6 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, vsvg->base.key = *key; vsvg->base.vs = vs; vsvg->base.set_input = vsvg_set_input; - vsvg->base.set_constants = vsvg_set_constants; - vsvg->base.set_viewport = vsvg_set_viewport; vsvg->base.run_elts = vsvg_run_elts; vsvg->base.run_linear = vsvg_run_linear; vsvg->base.destroy = vsvg_destroy; -- cgit v1.2.3 From 6945bcb89370501e0a218bc656e68e30e4dadcda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 29 May 2008 18:28:02 +0900 Subject: draw: Put PIPE_CDECL in the right places. MSVC seems picky about this. --- src/gallium/auxiliary/draw/draw_vs_aos.h | 4 ++-- src/gallium/auxiliary/draw/draw_vs_aos_machine.c | 4 ++-- src/gallium/auxiliary/draw/draw_vs_varient.c | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 89a9174151..665b425e68 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -60,12 +60,12 @@ struct x86_function; #define FPU_RND_NEAREST 2 struct aos_machine; -typedef void PIPE_CDECL (*lit_func)( struct aos_machine *, +typedef void (PIPE_CDECL *lit_func)( struct aos_machine *, float *result, const float *in, unsigned count ); -PIPE_CDECL void aos_do_lit( struct aos_machine *machine, +void PIPE_CDECL aos_do_lit( struct aos_machine *machine, float *result, const float *in, unsigned count ); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c index 53e999b191..b7864e9f2f 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c @@ -57,7 +57,7 @@ #define X87_CW_INFINITY (1<<12) -PIPE_CDECL void aos_do_lit( struct aos_machine *machine, +void PIPE_CDECL aos_do_lit( struct aos_machine *machine, float *result, const float *in, unsigned count ) @@ -91,7 +91,7 @@ PIPE_CDECL void aos_do_lit( struct aos_machine *machine, } -static PIPE_CDECL void do_lit_lut( struct aos_machine *machine, +static void PIPE_CDECL do_lit_lut( struct aos_machine *machine, float *result, const float *in, unsigned count ) diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index 18cb06e374..4a155251b5 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -118,10 +118,10 @@ static void do_viewport( struct draw_vs_varient_generic *vsvg, } -static void vsvg_run_elts( struct draw_vs_varient *varient, - const unsigned *elts, - unsigned count, - void *output_buffer) +static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, + const unsigned *elts, + unsigned count, + void *output_buffer) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; @@ -174,10 +174,10 @@ static void vsvg_run_elts( struct draw_vs_varient *varient, } -static void vsvg_run_linear( struct draw_vs_varient *varient, - unsigned start, - unsigned count, - void *output_buffer ) +static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, + unsigned start, + unsigned count, + void *output_buffer ) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; -- cgit v1.2.3 From cb87d7e44a6d6b1b4239b4e38c76c6bb848d2ef6 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 29 May 2008 12:11:37 +0200 Subject: scons: Remove duplicate entry. --- src/gallium/auxiliary/draw/SConscript | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 925e668f22..544a04918b 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -31,7 +31,6 @@ draw = env.ConvenienceLibrary( 'draw_pt_util.c', 'draw_pt_varray.c', 'draw_pt_vcache.c', - 'draw_pt_util.c', 'draw_vertex.c', 'draw_vs.c', 'draw_vs_aos.c', -- cgit v1.2.3 From 82605d7bcd533d7c96cc619c45970efd7229dc3b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 29 May 2008 11:46:43 +0100 Subject: draw: draw_range_elements trial --- src/gallium/auxiliary/draw/draw_context.c | 20 +++- src/gallium/auxiliary/draw/draw_context.h | 10 +- src/gallium/auxiliary/draw/draw_private.h | 2 + src/gallium/auxiliary/draw/draw_pt.h | 9 ++ src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 48 ++++++++ .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 49 ++++++++ .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 80 +++++++++++++- src/gallium/auxiliary/draw/draw_pt_vcache.c | 123 ++++++++++++++++++++- src/gallium/drivers/softpipe/sp_context.c | 1 + src/gallium/drivers/softpipe/sp_draw_arrays.c | 31 +++++- src/gallium/drivers/softpipe/sp_state.h | 7 ++ src/gallium/include/pipe/p_context.h | 14 +++ 12 files changed, 381 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 8509baf865..bcec85c2ef 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -348,14 +348,30 @@ void draw_set_edgeflags( struct draw_context *draw, * \param elements the element buffer ptr */ void -draw_set_mapped_element_buffer( struct draw_context *draw, - unsigned eltSize, void *elements ) +draw_set_mapped_element_buffer_range( struct draw_context *draw, + unsigned eltSize, + unsigned min_index, + unsigned max_index, + void *elements ) { draw->pt.user.elts = elements; draw->pt.user.eltSize = eltSize; + draw->pt.user.min_index = min_index; + draw->pt.user.max_index = max_index; } +void +draw_set_mapped_element_buffer( struct draw_context *draw, + unsigned eltSize, + void *elements ) +{ + draw->pt.user.elts = elements; + draw->pt.user.eltSize = eltSize; + draw->pt.user.min_index = 0; + draw->pt.user.max_index = 0xffffffff; +} + /* Revamp me please: */ diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index c5c3d3b09e..8dd03cb79e 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -118,8 +118,16 @@ void draw_set_vertex_elements(struct draw_context *draw, unsigned count, const struct pipe_vertex_element *elements); +void +draw_set_mapped_element_buffer_range( struct draw_context *draw, + unsigned eltSize, + unsigned min_index, + unsigned max_index, + void *elements ); + void draw_set_mapped_element_buffer( struct draw_context *draw, - unsigned eltSize, void *elements ); + unsigned eltSize, + void *elements ); void draw_set_mapped_vertex_buffer(struct draw_context *draw, unsigned attr, const void *buffer); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 4cbccc8b5b..40f1d978f2 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -147,6 +147,8 @@ struct draw_context const void *elts; /** bytes per index (0, 1, 2 or 4) */ unsigned eltSize; + unsigned min_index; + unsigned max_index; /** vertex arrays */ const void *vbuffer[PIPE_MAX_ATTRIBS]; diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index e03816ebbc..6b8ba1d171 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -96,6 +96,15 @@ struct draw_pt_middle_end { unsigned start, unsigned count); + /* Transform all vertices in a linear range and then draw them with + * the supplied element list. + */ + void (*run_linear_elts)( struct draw_pt_middle_end *, + unsigned fetch_start, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ); + void (*finish)( struct draw_pt_middle_end * ); void (*destroy)( struct draw_pt_middle_end * ); }; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index a1d041a74f..09bdc5fb5e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -311,6 +311,53 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle, } +static void fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle, + unsigned start, + unsigned count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; + struct draw_context *draw = feme->draw; + void *hw_verts; + + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + + hw_verts = draw->render->allocate_vertices( draw->render, + (ushort)feme->translate->key.output_stride, + (ushort)count ); + if (!hw_verts) { + assert(0); + return; + } + + /* Single routine to fetch vertices and emit HW verts. + */ + feme->translate->run( feme->translate, + start, + count, + hw_verts ); + + /* XXX: Draw arrays path to avoid re-emitting index list again and + * again. + */ + draw->render->draw( draw->render, + draw_elts, + draw_count ); + + /* Done -- that was easy, wasn't it: + */ + draw->render->release_vertices( draw->render, + hw_verts, + feme->translate->key.output_stride, + count ); + +} + + + static void fetch_emit_finish( struct draw_pt_middle_end *middle ) { @@ -343,6 +390,7 @@ struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ) fetch_emit->base.prepare = fetch_emit_prepare; fetch_emit->base.run = fetch_emit_run; fetch_emit->base.run_linear = fetch_emit_run_linear; + fetch_emit->base.run_linear_elts = fetch_emit_run_linear_elts; fetch_emit->base.finish = fetch_emit_finish; fetch_emit->base.destroy = fetch_emit_destroy; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 5265a13160..efa6dddbda 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -310,6 +310,54 @@ fse_run(struct draw_pt_middle_end *middle, } + +static void fse_run_linear_elts( struct draw_pt_middle_end *middle, + unsigned start, + unsigned count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; + struct draw_context *draw = fse->draw; + unsigned alloc_count = align(count, 4); + char *hw_verts; + + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + + hw_verts = draw->render->allocate_vertices( draw->render, + (ushort)fse->key.output_stride, + (ushort)alloc_count ); + + if (!hw_verts) { + assert(0); + return; + } + + /* Single routine to fetch vertices, run shader and emit HW verts. + * Clipping is done elsewhere -- either by the API or on hardware, + * or for some other reason not required... + */ + fse->active->run_linear( fse->active, + start, count, + hw_verts ); + + + draw->render->draw( draw->render, + draw_elts, + draw_count ); + + + + draw->render->release_vertices( draw->render, + hw_verts, + fse->key.output_stride, + count ); +} + + + static void fse_finish( struct draw_pt_middle_end *middle ) { } @@ -330,6 +378,7 @@ struct draw_pt_middle_end *draw_pt_middle_fse( struct draw_context *draw ) fse->base.prepare = fse_prepare; fse->base.run = fse_run; fse->base.run_linear = fse_run_linear; + fse->base.run_linear_elts = fse_run_linear_elts; fse->base.finish = fse_finish; fse->base.destroy = fse_destroy; fse->draw = draw; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 06718779a5..c58a900867 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -98,7 +98,6 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, - static void fetch_pipeline_run( struct draw_pt_middle_end *middle, const unsigned *fetch_elts, unsigned fetch_count, @@ -251,6 +250,84 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, +static void fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle, + unsigned start, + unsigned count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + struct draw_context *draw = fpme->draw; + struct draw_vertex_shader *shader = draw->vs.vertex_shader; + unsigned opt = fpme->opt; + unsigned alloc_count = align_int( count, 4 ); + + struct vertex_header *pipeline_verts = + (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); + + if (!pipeline_verts) { + /* Not much we can do here - just skip the rendering. + */ + assert(0); + return; + } + + /* Fetch into our vertex buffer + */ + draw_pt_fetch_run_linear( fpme->fetch, + start, + count, + (char *)pipeline_verts ); + + /* Run the shader, note that this overwrites the data[] parts of + * the pipeline verts. If there is no shader, ie a bypass shader, + * then the inputs == outputs, and are already in the correct + * place. + */ + if (opt & PT_SHADE) + { + shader->run_linear(shader, + (const float (*)[4])pipeline_verts->data, + ( float (*)[4])pipeline_verts->data, + (const float (*)[4])draw->pt.user.constants, + count, + fpme->vertex_size, + fpme->vertex_size); + } + + if (draw_pt_post_vs_run( fpme->post_vs, + pipeline_verts, + count, + fpme->vertex_size )) + { + opt |= PT_PIPELINE; + } + + /* Do we need to run the pipeline? + */ + if (opt & PT_PIPELINE) { + draw_pipeline_run( fpme->draw, + fpme->prim, + pipeline_verts, + count, + fpme->vertex_size, + draw_elts, + draw_count ); + } + else { + draw_pt_emit( fpme->emit, + (const float (*)[4])pipeline_verts->data, + count, + fpme->vertex_size, + draw_elts, + draw_count ); + } + + FREE(pipeline_verts); +} + + + static void fetch_pipeline_finish( struct draw_pt_middle_end *middle ) { /* nothing to do */ @@ -282,6 +359,7 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context * fpme->base.prepare = fetch_pipeline_prepare; fpme->base.run = fetch_pipeline_run; fpme->base.run_linear = fetch_pipeline_linear_run; + fpme->base.run_linear_elts = fetch_pipeline_linear_run_elts; fpme->base.finish = fetch_pipeline_finish; fpme->base.destroy = fetch_pipeline_destroy; diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 96e02fbf3a..720b91b8e6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -36,8 +36,8 @@ #include "draw/draw_pt.h" -#define CACHE_MAX 32 -#define FETCH_MAX 128 +#define CACHE_MAX 1024 +#define FETCH_MAX 4096 #define DRAW_MAX (16*1024) struct vcache_frontend { @@ -201,7 +201,124 @@ static void vcache_ef_quad( struct vcache_frontend *vcache, #define FUNC vcache_run #include "draw_pt_vcache_tmp.h" +static void translate_uint_elts( const unsigned *src, + unsigned count, + int delta, + ushort *dest ) +{ + unsigned i; + + for (i = 0; i < count; i++) + dest[i] = (ushort)(src[i] + delta); +} + +static void translate_ushort_elts( const ushort *src, + unsigned count, + int delta, + ushort *dest ) +{ + unsigned i; + + for (i = 0; i < count; i++) + dest[i] = (ushort)(src[i] + delta); +} +static void translate_ubyte_elts( const ubyte *src, + unsigned count, + int delta, + ushort *dest ) +{ + unsigned i; + + for (i = 0; i < count; i++) + dest[i] = (ushort)(src[i] + delta); +} + +#if 0 +static enum pipe_format format_from_get_elt( pt_elt_func get_elt ) +{ + switch (draw->pt.user.eltSize) { + case 1: return PIPE_FORMAT_R8_UNORM; + case 2: return PIPE_FORMAT_R16_UNORM; + case 4: return PIPE_FORMAT_R32_UNORM; + default: return PIPE_FORMAT_NONE; + } +} +#endif + +static void vcache_check_run( struct draw_pt_front_end *frontend, + pt_elt_func get_elt, + const void *elts, + unsigned draw_count ) +{ + struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; + struct draw_context *draw = vcache->draw; + unsigned min_index = draw->pt.user.min_index; + unsigned max_index = draw->pt.user.max_index; + unsigned index_size = draw->pt.user.eltSize; + unsigned fetch_count = MAX2(max_index, max_index + 1 - min_index); + const ushort *transformed_elts; + ushort *storage = NULL; + + printf("fetch_count %x\n", fetch_count); + + if (fetch_count >= FETCH_MAX || + fetch_count > draw_count) + goto fail; + + + if (min_index == 0 && + index_size == 2) + { + transformed_elts = (const ushort *)elts; + } + else + { + storage = MALLOC( draw_count * sizeof(ushort) ); + if (!storage) + goto fail; + + switch(index_size) { + case 1: + translate_ubyte_elts( (const ubyte *)elts, + draw_count, + 0 - (int)min_index, + storage ); + break; + + case 2: + translate_ushort_elts( (const ushort *)elts, + draw_count, + 0 - (int)min_index, + storage ); + break; + + case 4: + translate_uint_elts( (const uint *)elts, + draw_count, + 0 - (int)min_index, + storage ); + break; + + default: + assert(0); + return; + } + transformed_elts = storage; + } + + vcache->middle->run_linear_elts( vcache->middle, + min_index, /* start */ + fetch_count, + transformed_elts, + draw_count ); + + FREE(storage); + return; + + fail: + vcache_run( frontend, get_elt, elts, draw_count ); +} @@ -219,7 +336,7 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, } else { - vcache->base.run = vcache_run; + vcache->base.run = vcache_check_run; } vcache->input_prim = prim; diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 045a1f74a9..1e0106b86c 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -179,6 +179,7 @@ softpipe_create( struct pipe_screen *screen, softpipe->pipe.draw_arrays = softpipe_draw_arrays; softpipe->pipe.draw_elements = softpipe_draw_elements; + softpipe->pipe.draw_range_elements = softpipe_draw_range_elements; softpipe->pipe.set_edgeflags = softpipe_set_edgeflags; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 6c58f9909d..dbecf6865f 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -108,11 +108,14 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, * * XXX should the element buffer be specified/bound with a separate function? */ + boolean -softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned mode, unsigned start, unsigned count) +softpipe_draw_range_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned min_index, + unsigned max_index, + unsigned mode, unsigned start, unsigned count) { struct softpipe_context *sp = softpipe_context(pipe); struct draw_context *draw = sp->draw; @@ -141,11 +144,14 @@ softpipe_draw_elements(struct pipe_context *pipe, void *mapped_indexes = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); + draw_set_mapped_element_buffer_range(draw, indexSize, + min_index, + max_index, + mapped_indexes); } else { /* no index/element buffer */ - draw_set_mapped_element_buffer(draw, 0, NULL); + draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL); } @@ -171,6 +177,19 @@ softpipe_draw_elements(struct pipe_context *pipe, return TRUE; } +boolean +softpipe_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + return softpipe_draw_range_elements( pipe, indexBuffer, + indexSize, + 0, 0xffffffff, + mode, start, count ); +} + + void softpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags) diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 452e51fa79..701e02b295 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -171,6 +171,13 @@ boolean softpipe_draw_elements(struct pipe_context *pipe, struct pipe_buffer *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); +boolean +softpipe_draw_range_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned min_index, + unsigned max_index, + unsigned mode, unsigned start, unsigned count); void softpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 0f68f592f7..faf112c6d6 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -76,6 +76,20 @@ struct pipe_context { struct pipe_buffer *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); + + /* XXX: this is (probably) a temporary entrypoint, as the range + * information should be available from the vertex_buffer state. + * Using this to quickly evaluate a specialized path in the draw + * module. + */ + boolean (*draw_range_elements)( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned minIndex, + unsigned maxIndex, + unsigned mode, + unsigned start, + unsigned count); /*@}*/ -- cgit v1.2.3 From 0cd75a4c99ec63b514b6fbb53152858fa20f53ec Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 12:54:01 +0200 Subject: i915: Get up to date with the latest EGL changes --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 809371fdeb..41b7eac4ed 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -588,7 +588,7 @@ drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) * plug in API functions. */ _EGLDriver * -_eglMain(_EGLDisplay *dpy) +_eglMain(_EGLDisplay *dpy, const char *args) { struct drm_driver *drm; -- cgit v1.2.3 From 837601af522b9d1e687040015672769392884fa1 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 12:43:09 +0200 Subject: i915: Ops how did that get there --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 2e6c452cd1..b3e5f29c3e 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -220,7 +220,7 @@ power_of_two(unsigned x) value = value << 1; return value; } - /*pipe_buffer_reference(winsys, &i915_render->vbo, NULL);*/ + /** * Copied from xm_winsys.c */ -- cgit v1.2.3 From 79b67d8408d1ba5b2232791ae35e731a5953b52d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 12:44:53 +0200 Subject: i915: Remove last usage of surface_alloc_storage --- src/gallium/drivers/i915simple/i915_texture.c | 42 +++++++++--------------- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 31 +---------------- 2 files changed, 17 insertions(+), 56 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index df11ba0544..122f88fe3a 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -104,7 +104,7 @@ i915_miptree_set_image_offset(struct i915_texture *tex, */ } - +#if 0 /* Hack it up to use the old winsys->surface_alloc_storage() * method for now: */ @@ -145,10 +145,7 @@ i915_displaytarget_layout(struct pipe_screen *screen, return tex->buffer != NULL; } - - - - +#endif static void i945_miptree_layout_2d( struct i915_texture *tex ) @@ -539,32 +536,25 @@ i915_texture_create(struct pipe_screen *screen, tex->base.refcount = 1; tex->base.screen = screen; - if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { - if (!i915_displaytarget_layout(screen, tex)) - goto fail; + if (i915screen->is_i945) { + if (!i945_miptree_layout(tex)) + goto fail; + } else { + if (!i915_miptree_layout(tex)) + goto fail; } - else { - if (i915screen->is_i945) { - if (!i945_miptree_layout(tex)) - goto fail; - } - else { - if (!i915_miptree_layout(tex)) - goto fail; - } - - tex->buffer = ws->buffer_create(ws, 64, - PIPE_BUFFER_USAGE_PIXEL, - tex->pitch * tex->base.cpp * - tex->total_height); - if (!tex->buffer) - goto fail; - } + tex->buffer = ws->buffer_create(ws, 64, + PIPE_BUFFER_USAGE_PIXEL, + tex->pitch * tex->base.cpp * + tex->total_height); + + if (!tex->buffer) + goto fail; return &tex->base; - fail: +fail: FREE(tex); return NULL; } diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index b3e5f29c3e..a7f3047352 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -232,36 +232,7 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned flags, unsigned tex_usage) { - const unsigned alignment = 64; - assert(!surf->buffer); -#if 0 - surf->width = width; - surf->height = round_up(height, 8); - surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = power_of_two(MAX2(width * surf->cpp, 512)); - - surf->buffer = winsys->buffer_create(winsys, 2*4096, - PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->height); - - surf->pitch = surf->pitch / surf->cpp; - surf->height = height; -#else - surf->width = width; - surf->height = height; - surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); - - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * surf->height); -#endif - if(!surf->buffer) - return -1; - - return 0; + return -1; } -- cgit v1.2.3 From bb2e13b9e82b68ec3b9fc56a4c35e7ead8fd138f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 29 May 2008 12:38:49 +0100 Subject: draw: make sure constant buffer data is aligned before passing to aos.c --- src/gallium/auxiliary/draw/draw_context.c | 5 +++-- src/gallium/auxiliary/draw/draw_context.h | 3 ++- src/gallium/auxiliary/draw/draw_private.h | 9 ++++++++- src/gallium/auxiliary/draw/draw_vs.c | 19 ++++++++++++++++++- src/gallium/auxiliary/draw/draw_vs_aos.c | 4 ++-- src/gallium/drivers/i915simple/i915_context.c | 4 +++- src/gallium/drivers/softpipe/sp_draw_arrays.c | 5 +++-- 7 files changed, 39 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index bcec85c2ef..2f263cf06a 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -217,10 +217,11 @@ draw_set_mapped_vertex_buffer(struct draw_context *draw, void draw_set_mapped_constant_buffer(struct draw_context *draw, - const void *buffer) + const void *buffer, + unsigned size ) { draw->pt.user.constants = buffer; - draw_vs_set_constants( draw, (const float (*)[4])buffer ); + draw_vs_set_constants( draw, (const float (*)[4])buffer, size ); } diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 8dd03cb79e..b8f2bfa332 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -133,7 +133,8 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw, unsigned attr, const void *buffer); void draw_set_mapped_constant_buffer(struct draw_context *draw, - const void *buffer); + const void *buffer, + unsigned size ); void draw_set_edgeflags( struct draw_context *draw, const unsigned *edgeflag ); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 40f1d978f2..88a7224b62 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -190,6 +190,12 @@ struct draw_context struct aos_machine *aos_machine; + const float (*aligned_constants)[4]; + + const float (*aligned_constant_storage)[4]; + unsigned const_storage_size; + + struct translate *fetch; struct translate_cache *fetch_cache; struct translate *emit; @@ -225,7 +231,8 @@ void draw_vs_set_viewport( struct draw_context *, const struct pipe_viewport_state * ); void draw_vs_set_constants( struct draw_context *, - const float (*constants)[4] ); + const float (*constants)[4], + unsigned size ); diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index a8b6d0c90d..ce35112fc1 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -43,8 +43,22 @@ void draw_vs_set_constants( struct draw_context *draw, - const float (*constants)[4] ) + const float (*constants)[4], + unsigned size ) { + if (((unsigned)constants) & 0xf) { + if (size > draw->vs.const_storage_size) { + if (draw->vs.aligned_constant_storage) + align_free(draw->vs.aligned_constant_storage); + draw->vs.aligned_constant_storage = align_malloc( size, 16 ); + } + memcpy( draw->vs.aligned_constant_storage, + constants, + size ); + constants = draw->vs.aligned_constant_storage; + } + + draw->vs.aligned_constants = constants; draw_vs_aos_machine_constants( draw->vs.aos_machine, constants ); } @@ -159,6 +173,9 @@ draw_vs_destroy( struct draw_context *draw ) if (draw->vs.aos_machine) draw_vs_aos_machine_destroy(draw->vs.aos_machine); + if (draw->vs.aligned_constant_storage) + align_free(draw->vs.aligned_constant_storage); + tgsi_exec_machine_free_data(&draw->vs.machine); } diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index b5e4e1e7b1..55cabb6df9 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1957,7 +1957,7 @@ static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient, struct aos_machine *machine = vaos->draw->vs.aos_machine; machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; - machine->constants = (const float (*)[4])vaos->draw->pt.user.constants; + machine->constants = vaos->draw->vs.aligned_constants; machine->immediates = vaos->base.vs->immediates; machine->attrib = vaos->attrib; @@ -1976,7 +1976,7 @@ static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient, struct aos_machine *machine = vaos->draw->vs.aos_machine; machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; - machine->constants = (const float (*)[4])vaos->draw->pt.user.constants; + machine->constants = vaos->draw->vs.aligned_constants; machine->immediates = vaos->base.vs->immediates; machine->attrib = vaos->attrib; diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 4bef21619c..c609d16a5a 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -86,7 +86,9 @@ i915_draw_elements( struct pipe_context *pipe, draw_set_mapped_constant_buffer(draw, - i915->current.constants[PIPE_SHADER_VERTEX]); + i915->current.constants[PIPE_SHADER_VERTEX], + ( i915->current.num_user_constants[PIPE_SHADER_VERTEX] * + 4 * sizeof(float) )); /* draw! */ draw_arrays(i915->draw, prim, start, count); diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index dbecf6865f..d4d5fa744f 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -54,7 +54,8 @@ softpipe_map_constant_buffers(struct softpipe_context *sp) } draw_set_mapped_constant_buffer(sp->draw, - sp->mapped_constants[PIPE_SHADER_VERTEX]); + sp->mapped_constants[PIPE_SHADER_VERTEX], + sp->constants[i].size); } static void @@ -68,7 +69,7 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp) */ draw_flush(sp->draw); - draw_set_mapped_constant_buffer(sp->draw, NULL); + draw_set_mapped_constant_buffer(sp->draw, NULL, 0); for (i = 0; i < 2; i++) { if (sp->constants[i].size) -- cgit v1.2.3 From 45eecb93920c5a33e71b3c152749273908cb62fd Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 29 May 2008 12:42:39 +0100 Subject: draw: remove printf --- src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 720b91b8e6..64fab61271 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -260,8 +260,6 @@ static void vcache_check_run( struct draw_pt_front_end *frontend, const ushort *transformed_elts; ushort *storage = NULL; - printf("fetch_count %x\n", fetch_count); - if (fetch_count >= FETCH_MAX || fetch_count > draw_count) goto fail; -- cgit v1.2.3 From a233f65f9b79734498c120e8052aa8d6255586e4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 29 May 2008 13:08:15 +0100 Subject: draw: better calculation of fetch_count --- src/gallium/auxiliary/draw/draw_pt_vcache.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 64fab61271..957b8edec2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -256,13 +256,19 @@ static void vcache_check_run( struct draw_pt_front_end *frontend, unsigned min_index = draw->pt.user.min_index; unsigned max_index = draw->pt.user.max_index; unsigned index_size = draw->pt.user.eltSize; - unsigned fetch_count = MAX2(max_index, max_index + 1 - min_index); + unsigned fetch_count = max_index + 1 - min_index; const ushort *transformed_elts; ushort *storage = NULL; - if (fetch_count >= FETCH_MAX || - fetch_count > draw_count) + + if (0) debug_printf("fetch_count %d draw_count %d\n", fetch_count, draw_count); + + if (max_index == 0xffffffff || + fetch_count >= FETCH_MAX || + fetch_count > draw_count) { + debug_printf("fail\n"); goto fail; + } if (min_index == 0 && -- cgit v1.2.3 From 8f887b4252208e60e7e86217ec3b72fb639a4e82 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 29 May 2008 13:26:01 +0100 Subject: draw: michal's patch for calling powf... teapot still not quite right --- src/gallium/auxiliary/draw/draw_vs_aos.c | 46 ++++++++++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_aos.h | 1 + 2 files changed, 47 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 55cabb6df9..725f36b502 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1372,11 +1372,20 @@ static boolean emit_MAD( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } +/* A wrapper for powf(). + * Makes sure it is cdecl and operates on floats. + */ +static float PIPE_CDECL _powerf( float x, float y ) +{ + return powf( x, y ); +} + /* Really not sufficient -- need to check for conditions that could * generate inf/nan values, which will slow things down hugely. */ static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { +#if 0 x87_fld_src(cp, &op->FullSrcRegisters[1], 0); /* a1.x */ x87_fld_src(cp, &op->FullSrcRegisters[0], 0); /* a0.x a1.x */ x87_fyl2x(cp->func); /* a1*log2(a0) */ @@ -1384,6 +1393,42 @@ static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_inst x87_emit_ex2( cp ); /* 2^(a1*log2(a0)) */ x87_fstp_dest4(cp, &op->FullDstRegisters[0]); +#else + uint i; + + /* For absolute correctness, need to spill/invalidate all XMM regs + * too. + */ + for (i = 0; i < 8; i++) { + if (cp->xmm[i].dirty) + spill(cp, i); + aos_release_xmm_reg(cp, i); + } + + /* Push caller-save (ie scratch) regs. + */ + x86_cdecl_caller_push_regs( cp->func ); + + x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, -8) ); + + x87_fld_src( cp, &op->FullSrcRegisters[1], 0 ); + x87_fstp( cp->func, x86_make_disp( cp->stack_ESP, 4 ) ); + x87_fld_src( cp, &op->FullSrcRegisters[0], 0 ); + x87_fstp( cp->func, x86_make_disp( cp->stack_ESP, 0 ) ); + + x86_mov_reg_imm( cp->func, cp->tmp_EAX, (unsigned long) _powerf ); + x86_call( cp->func, cp->tmp_EAX ); + + x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, 8) ); + + x86_cdecl_caller_pop_regs( cp->func ); + + /* Note retval on x87 stack: + */ + cp->func->x87_stack++; + + x87_fstp_dest4( cp, &op->FullDstRegisters[0] ); +#endif return TRUE; } @@ -1781,6 +1826,7 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, cp.machine_EDX = x86_make_reg(file_REG32, reg_DX); cp.count_ESI = x86_make_reg(file_REG32, reg_SI); cp.temp_EBP = x86_make_reg(file_REG32, reg_BP); + cp.stack_ESP = x86_make_reg( file_REG32, reg_SP ); x86_init_func(cp.func); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 665b425e68..fb6d43d32e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -160,6 +160,7 @@ struct aos_compilation { struct x86_reg machine_EDX; struct x86_reg count_ESI; /* decrements to zero */ struct x86_reg temp_EBP; + struct x86_reg stack_ESP; }; struct x86_reg aos_get_xmm_reg( struct aos_compilation *cp ); -- cgit v1.2.3 From 4a7198fdcfe3256bdefff5d1d766327ae7f18b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 29 May 2008 22:20:51 +0900 Subject: psb: Make msvc happy. Conflicts: src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index c58a900867..eb6988ff03 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -81,9 +81,9 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, * but gl vs dx9 clip spaces. */ draw_pt_post_vs_prepare( fpme->post_vs, - draw->bypass_clipping, - draw->identity_viewport, - draw->rasterizer->gl_rasterization_rules ); + (boolean)draw->bypass_clipping, + (boolean)draw->identity_viewport, + (boolean)draw->rasterizer->gl_rasterization_rules ); if (!(opt & PT_PIPELINE)) -- cgit v1.2.3 From 8808d62f608d1397ee75d0087301d0b0a0278244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 29 May 2008 22:26:56 +0900 Subject: gallium: MSVC warning fixes. Conflicts: src/gallium/auxiliary/draw/draw_pt_varray.c src/gallium/auxiliary/draw/draw_pt_varray_tmp.h src/gallium/auxiliary/draw/draw_pt_vcache.c --- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 2 +- src/gallium/auxiliary/draw/draw_pt_varray_tmp.h | 9 +++++---- src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h | 9 +++++---- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2 +- src/gallium/auxiliary/translate/translate_sse.c | 2 +- 5 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 67b9a9503d..d514e28b77 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -145,7 +145,7 @@ emit_vertex( struct vbuf_stage *vbuf, vertex->vertex_id = vbuf->nr_vertices++; } - return vertex->vertex_id; + return (ushort)vertex->vertex_id; } diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h index 6979f6b544..7c722457c3 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp.h @@ -10,7 +10,8 @@ static void FUNC(struct draw_pt_front_end *frontend, boolean flatfirst = (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first); - unsigned i, j, flags; + unsigned i, j; + ushort flags; unsigned first, incr; varray->fetch_start = start; @@ -200,9 +201,9 @@ static void FUNC(struct draw_pt_front_end *frontend, /* These bitflags look a little odd because we submit the * vertices as (1,2,0) to satisfy flatshade requirements. */ - const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2; - const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1; + const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; + const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; + const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; for (j = 0; j + first <= count; j += i) { diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h index cf9f394aa3..5c99a47e49 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h @@ -10,7 +10,8 @@ static void FUNC( struct draw_pt_front_end *frontend, boolean flatfirst = (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first); - unsigned i, flags; + unsigned i; + ushort flags; switch (vcache->input_prim) { @@ -138,9 +139,9 @@ static void FUNC( struct draw_pt_front_end *frontend, /* These bitflags look a little odd because we submit the * vertices as (1,2,0) to satisfy flatshade requirements. */ - const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2; - const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1; + const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; + const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; + const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 8018bd7fa4..189dc6024d 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -198,7 +198,7 @@ get_coef( static void emit_retw( struct x86_function *func, - unsigned size ) + unsigned short size ) { x86_retw( func, size ); } diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index 69dd4d3dff..be48a14737 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -309,7 +309,7 @@ static void get_src_ptr( struct translate_sse *p, static void emit_swizzle( struct translate_sse *p, struct x86_reg dest, struct x86_reg src, - unsigned shuffle ) + unsigned char shuffle ) { sse_shufps(p->func, dest, src, shuffle); } -- cgit v1.2.3 From 807e7c4ccfdaebf8e568357fb1fd8090ccae638c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 29 May 2008 14:35:30 +0100 Subject: draw: add more switches to turn FSE on/off --- src/gallium/auxiliary/draw/draw_private.h | 3 ++- src/gallium/auxiliary/draw/draw_pt.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 88a7224b62..4f8cceee1e 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -157,7 +157,8 @@ struct draw_context const void *constants; } user; - boolean test_fse; + boolean test_fse; /* enable FSE even though its not correct (eg for softpipe) */ + boolean no_fse; /* disable FSE even when it is correct */ } pt; struct { diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index d48c6c220d..723077159b 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -75,7 +75,7 @@ draw_pt_arrays(struct draw_context *draw, if (opt == 0) middle = draw->pt.middle.fetch_emit; - else if (opt == PT_SHADE) + else if (opt == PT_SHADE && !draw->pt.no_fse) middle = draw->pt.middle.fetch_shade_emit; else middle = draw->pt.middle.general; @@ -105,6 +105,7 @@ draw_pt_arrays(struct draw_context *draw, boolean draw_pt_init( struct draw_context *draw ) { draw->pt.test_fse = GETENV("DRAW_FSE") != NULL; + draw->pt.no_fse = GETENV("DRAW_NO_FSE") != NULL; draw->pt.front.vcache = draw_pt_vcache( draw ); if (!draw->pt.front.vcache) -- cgit v1.2.3 From 056bea86b013858832a6ab390fe6efe310a7bc8f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 15:49:23 +0200 Subject: i915: Deprecated pipe_winsys buffer functions --- src/gallium/drivers/i915simple/i915_texture.c | 2 +- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 45 ++++-------------------- 2 files changed, 8 insertions(+), 39 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 122f88fe3a..935bc742b1 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -619,7 +619,7 @@ i915_get_tex_surface(struct pipe_screen *screen, assert(zslice == 0); } - ps = ws->surface_alloc(ws); + ps = CALLOC_STRUCT(pipe_surface);//ws->surface_alloc(ws); if (ps) { assert(ps->refcount); assert(ps->winsys); diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index a7f3047352..af439a796f 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -190,40 +190,16 @@ intel_flush_frontbuffer( struct pipe_winsys *winsys, intelDisplaySurface(dPriv, surf, NULL); } - +/* + * Deprecated surface functions + */ static struct pipe_surface * intel_i915_surface_alloc(struct pipe_winsys *winsys) { - struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); - if (surf) { - surf->refcount = 1; - surf->winsys = winsys; - } - return surf; + assert("intel_i915_surface_alloc is deprecated" & 0); + return NULL; } - -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - -static unsigned -power_of_two(unsigned x) -{ - int value = 1; - while (value <= x) - value = value << 1; - return value; -} - -/** - * Copied from xm_winsys.c - */ static int intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, @@ -232,21 +208,14 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned flags, unsigned tex_usage) { + assert("intel_i915_surface_alloc_storage is deprecated" & 0); return -1; } - static void intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) { - struct pipe_surface *surf = *s; - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - pipe_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; + assert("intel_i915_surface_release is deprecated" & 0); } -- cgit v1.2.3 From 643cc9387d03b5002a4a1e1a95f0dbcfff83b2d2 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 16:03:21 +0200 Subject: i915: Cleaned up intel_winsys_pipe.c --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 76 ++++++++++++------------ 1 file changed, 39 insertions(+), 37 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index af439a796f..51a79ca535 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -31,8 +31,6 @@ #include #include -//#include "dri_bufpool.h" -//#include "dri_bufmgr.h" #include "intel_context.h" #include "intel_winsys.h" @@ -45,8 +43,6 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" - - struct intel_pipe_winsys { struct pipe_winsys winsys; struct _DriBufferPool *regionPool; @@ -56,7 +52,6 @@ struct intel_pipe_winsys { }; - /* Turn a pipe winsys into an intel/pipe winsys: */ static inline struct intel_pipe_winsys * @@ -66,8 +61,12 @@ intel_pipe_winsys( struct pipe_winsys *winsys ) } -/* Most callbacks map direcly onto dri_bufmgr operations: +/* + * Buffer functions. + * + * Most callbacks map direcly onto dri_bufmgr operations: */ + static void *intel_buffer_map(struct pipe_winsys *winsys, struct pipe_buffer *buf, unsigned flags ) @@ -89,7 +88,6 @@ static void intel_buffer_unmap(struct pipe_winsys *winsys, driBOUnmap( dri_bo(buf) ); } - static void intel_buffer_destroy(struct pipe_winsys *winsys, struct pipe_buffer *buf) @@ -98,11 +96,6 @@ intel_buffer_destroy(struct pipe_winsys *winsys, FREE(buf); } - -/* Pipe has no concept of pools. We choose the tex/region pool - * for all buffers. - * Grabs the hardware lock! - */ static struct pipe_buffer * intel_buffer_create(struct pipe_winsys *winsys, unsigned alignment, @@ -175,24 +168,12 @@ intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) } -/* The state tracker (should!) keep track of whether the fake - * frontbuffer has been touched by any rendering since the last time - * we copied its contents to the real frontbuffer. Our task is easy: - */ -static void -intel_flush_frontbuffer( struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ - struct intel_context *intel = (struct intel_context *) context_private; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - intelDisplaySurface(dPriv, surf, NULL); -} - /* - * Deprecated surface functions + * Surface functions. + * + * Deprecated! */ + static struct pipe_surface * intel_i915_surface_alloc(struct pipe_winsys *winsys) { @@ -218,13 +199,9 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) assert("intel_i915_surface_release is deprecated" & 0); } - - -static const char * -intel_get_name( struct pipe_winsys *winsys ) -{ - return "Intel/DRI/ttm"; -} +/* + * Fence functions + */ static void intel_fence_reference( struct pipe_winsys *sws, @@ -254,6 +231,33 @@ intel_fence_finish( struct pipe_winsys *sws, return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); } + +/* + * Mixed functions + */ + +static const char * +intel_get_name( struct pipe_winsys *winsys ) +{ + return "Intel/DRI/ttm"; +} + +/* + * The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +intel_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + intelDisplaySurface(dPriv, surf, NULL); +} + struct pipe_winsys * intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) { @@ -300,7 +304,6 @@ intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) return &iws->winsys; } - void intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) { @@ -313,4 +316,3 @@ intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) } free(iws); } - -- cgit v1.2.3 From 529b3f4cc0ce3a3219daf5e1e8d4248cd1afe286 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 19:07:40 +0200 Subject: i915: Fix GPU lockup on resize --- src/gallium/drivers/i915simple/i915_texture.c | 66 ++++++++++++++------------- 1 file changed, 35 insertions(+), 31 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 935bc742b1..b216e3bfb9 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -104,48 +104,49 @@ i915_miptree_set_image_offset(struct i915_texture *tex, */ } -#if 0 -/* Hack it up to use the old winsys->surface_alloc_storage() - * method for now: +static unsigned +power_of_two(unsigned x) +{ + int value = 1; + while (value <= x) + value = value << 1; + return value; +} + +static unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +/** + * Special case to deal with display targets. */ static boolean i915_displaytarget_layout(struct pipe_screen *screen, struct i915_texture *tex) { - struct pipe_winsys *ws = screen->winsys; - struct pipe_surface surf; - unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ | - PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_READ | - PIPE_BUFFER_USAGE_GPU_WRITE); - - - memset(&surf, 0, sizeof(surf)); - - ws->surface_alloc_storage( ws, - &surf, - tex->base.width[0], - tex->base.height[0], - tex->base.format, - flags, - tex->base.tex_usage); - - /* Now extract the goodies: - */ + struct pipe_texture *pt = &tex->base; + + if (pt->last_level > 1 || pt->cpp != 4) + return 0; + i915_miptree_set_level_info( tex, 0, 1, 0, 0, tex->base.width[0], tex->base.height[0], 1 ); i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); - tex->buffer = surf.buffer; - tex->pitch = surf.pitch; - tex->total_height = 0; - +#if 0 + tex->pitch = MAX2(512, power_of_two(tex->base.width[0] * pt->cpp)) / pt->cpp; + tex->total_height = round_up(tex->base.height[0], 8); +#else + tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp); + tex->total_height = tex->base.height[0]; +#endif - return tex->buffer != NULL; + return 1; } -#endif static void i945_miptree_layout_2d( struct i915_texture *tex ) @@ -529,14 +530,17 @@ i915_texture_create(struct pipe_screen *screen, struct pipe_winsys *ws = screen->winsys; struct i915_texture *tex = CALLOC_STRUCT(i915_texture); - if (!tex) + if (!tex) return NULL; tex->base = *templat; tex->base.refcount = 1; tex->base.screen = screen; - if (i915screen->is_i945) { + if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if (!i915_displaytarget_layout(screen, tex)) + goto fail; + } else if (i915screen->is_i945) { if (!i945_miptree_layout(tex)) goto fail; } else { -- cgit v1.2.3 From 22be9ea4a63ff051604123de5e82cf4050792ef8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 29 May 2008 18:18:56 +0100 Subject: draw: quieten some debug --- src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 957b8edec2..9ffc99abf9 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -266,7 +266,7 @@ static void vcache_check_run( struct draw_pt_front_end *frontend, if (max_index == 0xffffffff || fetch_count >= FETCH_MAX || fetch_count > draw_count) { - debug_printf("fail\n"); + if (0) debug_printf("fail\n"); goto fail; } -- cgit v1.2.3 From 2691c228701e0d3a048eaaa698ba2236c2650d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 29 May 2008 19:24:53 +0900 Subject: gallium: Replace getenv by placeholder code on WinCE. WinCE processes supposedly have environment, but it is not clear which API to use. --- src/gallium/auxiliary/util/p_debug.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index ce7fb58956..d1dfc377f8 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -153,7 +153,9 @@ const char * debug_get_option(const char *name, const char *dfault) { const char *result; -#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + /* EngMapFile creates the file if it does not exists, so it must either be + * disabled on release versions (or put in a less conspicuous place). */ #ifdef DEBUG ULONG_PTR iFile = 0; const void *pMap = NULL; @@ -161,9 +163,6 @@ debug_get_option(const char *name, const char *dfault) static char output[1024]; result = dfault; - /* XXX: this creates the file if it does not exists, so it must either be - * disabled on release versions, or put in a less conspicuous place. - */ pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile); if(pMap) { sol = (const char *)pMap; @@ -187,13 +186,15 @@ debug_get_option(const char *name, const char *dfault) #else result = dfault; #endif +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) + /* TODO: implement */ + result = dfault; #else - result = getenv(name); if(!result) result = dfault; #endif - + debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? result : "(null)"); return result; -- cgit v1.2.3 From ae10775b731c8c58aa42f8046b6b557b4659cb7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 29 May 2008 21:09:06 +0900 Subject: gallium: Provide the INT64_C/UINT64_C macros. "long long" types and 1234LL constants are not supported by eVC. --- src/gallium/include/pipe/p_compiler.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index 29b7f9c262..f6707385cd 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -71,6 +71,9 @@ typedef __int32 intptr_t; typedef unsigned __int32 uintptr_t; #endif +#define INT64_C(__val) __val##i64 +#define UINT64_C(__val) __val##ui64 + #ifndef __cplusplus #define false 0 #define true 1 @@ -80,6 +83,9 @@ typedef int _Bool; #endif /* !__cplusplus */ #else +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif #include #include #endif -- cgit v1.2.3 From bee79eb9b9ef649585dc507dc756b1e79eb00d2c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 29 May 2008 17:02:55 -0600 Subject: egl: new EGL/gallium/softpipe/xlib winsys Checkpoint commit. Most required code is in place, and compiles, but totally untested. --- src/gallium/winsys/egl_xlib/Makefile | 87 ++++++ src/gallium/winsys/egl_xlib/egl_xlib.c | 461 ++++++++++++++++++++++++++++++++ src/gallium/winsys/egl_xlib/sw_winsys.c | 244 +++++++++++++++++ src/gallium/winsys/egl_xlib/sw_winsys.h | 40 +++ 4 files changed, 832 insertions(+) create mode 100644 src/gallium/winsys/egl_xlib/Makefile create mode 100644 src/gallium/winsys/egl_xlib/egl_xlib.c create mode 100644 src/gallium/winsys/egl_xlib/sw_winsys.c create mode 100644 src/gallium/winsys/egl_xlib/sw_winsys.h (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile new file mode 100644 index 0000000000..fe4b931e30 --- /dev/null +++ b/src/gallium/winsys/egl_xlib/Makefile @@ -0,0 +1,87 @@ +# src/gallium/winsys/egl_xlib/Makefile + +# Build softpipe/xlib/EGL driver library/object: "softpipe_egl.so" + + +TOP = ../../../.. +include $(TOP)/configs/current + + +LIBNAME = softpipe_egl.so + + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/auxiliary + +WINSYS_SOURCES = \ + egl_xlib.c \ + sw_winsys.c + +WINSYS_OBJECTS = $(WINSYS_SOURCES:.c=.o) + + +LIBS = \ + $(GALLIUM_DRIVERS) \ + $(TOP)/src/mesa/libglapi.a \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + + +LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1 + + +.SUFFIXES : .cpp + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $(LOCAL_CFLAGS) $< -o $@ + + + +default: $(TOP)/$(LIB_DIR)/$(LIBNAME) + + +# Make the softpipe_egl.so library +$(TOP)/$(LIB_DIR)/$(LIBNAME): $(WINSYS_OBJECTS) $(LIBS) + $(TOP)/bin/mklib -o $(LIBNAME) \ + -linker "$(CC)" \ + -noprefix \ + -install $(TOP)/$(LIB_DIR) \ + $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) \ + --start-group $(LIBS) --end-group + +# $(GL_LIB_DEPS) + + +depend: $(ALL_SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend # workaround oops on gutsy?!? + @ touch depend + @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \ + > /dev/null 2>/dev/null + + +install: default + $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) + @if [ -e $(TOP)/$(LIB_DIR) ]; then \ + $(INSTALL) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(INSTALL_DIR)/$(LIB_DIR); \ + fi + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h + +clean: + -rm -f *.o *~ *.bak + + +include depend diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c new file mode 100644 index 0000000000..4741da87cd --- /dev/null +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -0,0 +1,461 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * EGL / softpipe / xlib winsys module + * + * Authors: Brian Paul + */ + + +#include + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "softpipe/sp_winsys.h" + +#include "eglconfig.h" +#include "eglconfigutil.h" +#include "eglcontext.h" +#include "egldisplay.h" +#include "egldriver.h" +#include "eglglobals.h" +#include "egllog.h" +#include "eglsurface.h" + +#include "state_tracker/st_public.h" + +#include "sw_winsys.h" + + +/** subclass of _EGLDriver */ +struct xlib_egl_driver +{ + _EGLDriver Base; /**< base class */ + + struct pipe_winsys *winsys; + struct pipe_screen *screen; +}; + + +/** subclass of _EGLContext */ +struct xlib_egl_context +{ + _EGLContext Base; /**< base class */ + + struct pipe_context *pipe; /**< Gallium driver context */ + struct st_context *Context; /**< Mesa/gallium state tracker context */ +}; + + +/** subclass of _EGLSurface */ +struct xlib_egl_surface +{ + _EGLSurface Base; /**< base class */ + + Display *Dpy; /**< The X Display of the window */ + Window Win; /**< The user-created window ID */ + GC Gc; + XVisualInfo VisInfo; + + struct pipe_winsys *winsys; + + struct st_framebuffer *Framebuffer; +}; + + +/** cast wrapper */ +static INLINE struct xlib_egl_driver * +xlib_egl_driver(_EGLDriver *drv) +{ + return (struct xlib_egl_driver *) drv; +} + + +static struct xlib_egl_surface * +lookup_surface(EGLSurface surf) +{ + _EGLSurface *surface = _eglLookupSurface(surf); + return (struct xlib_egl_surface *) surface; +} + + +static struct xlib_egl_context * +lookup_context(EGLContext surf) +{ + _EGLContext *context = _eglLookupContext(surf); + return (struct xlib_egl_context *) context; +} + + +/** + * XXX temporary + * Need to query X server's GLX visuals. + */ +static void +init_configs(_EGLDriver *drv, EGLDisplay dpy) +{ + _EGLDisplay *disp = _eglLookupDisplay(dpy); + int i; + + for (i = 0; i < 2; i++) { + _EGLConfig config; + int id = i + 1; + _eglInitConfig(&config, id); + SET_CONFIG_ATTRIB(&config, EGL_RED_SIZE, 8); + SET_CONFIG_ATTRIB(&config, EGL_GREEN_SIZE, 8); + SET_CONFIG_ATTRIB(&config, EGL_BLUE_SIZE, 8); + SET_CONFIG_ATTRIB(&config, EGL_ALPHA_SIZE, 8); + if (i > 0) { + SET_CONFIG_ATTRIB(&config, EGL_DEPTH_SIZE, 24); + SET_CONFIG_ATTRIB(&config, EGL_STENCIL_SIZE, 8); + } + _eglAddConfig(disp, &config); + } +} + + + +/** + * Called via eglInitialize(), drv->API.Initialize(). + */ +static EGLBoolean +xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, + EGLint *minor, EGLint *major) +{ + /* visual configs */ + + init_configs(drv, dpy); + + + drv->Initialized = EGL_TRUE; + + /* we're supporting EGL 1.4 */ + *minor = 1; + *major = 4; + + return EGL_TRUE; +} + + +/** + * Called via eglTerminate(), drv->API.Terminate(). + */ +static EGLBoolean +xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) +{ + + return EGL_TRUE; +} + + +/** Get size of given window */ +static Status +get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) +{ + Window root; + Status stat; + int xpos, ypos; + unsigned int w, h, bw, depth; + stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); + *width = w; + *height = h; + return stat; +} + + +static void +display_surface(struct pipe_winsys *pws, + struct pipe_surface *psurf, + struct xlib_egl_surface *xsurf) +{ + XImage *ximage; + void *data; + + ximage = XCreateImage(xsurf->Dpy, + xsurf->VisInfo.visual, + xsurf->VisInfo.depth, + ZPixmap, 0, /* format, offset */ + NULL, /* data */ + 0, 0, /* size */ + 32, /* bitmap_pad */ + 0); /* bytes_per_line */ + + + assert(ximage->format); + assert(ximage->bitmap_unit); + + data = pws->buffer_map(pws, psurf->buffer, 0); + + /* update XImage's fields */ + ximage->data = data; + ximage->width = psurf->width; + ximage->height = psurf->height; + ximage->bytes_per_line = psurf->pitch * psurf->cpp; + + XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc, + ximage, 0, 0, 0, 0, psurf->width, psurf->height); + + ximage->data = NULL; + XDestroyImage(ximage); + + pws->buffer_unmap(pws, psurf->buffer); +} + + + +/** Display gallium surface in X window */ +static void +flush_frontbuffer(struct pipe_winsys *pws, + struct pipe_surface *psurf, + void *context_private) +{ + struct xlib_egl_surface *xsurf = (struct xlib_egl_surface *) context_private; + display_surface(pws, psurf, xsurf); +} + + + +/** + * Called via eglCreateContext(), drv->API.CreateContext(). + */ +static EGLContext +xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + EGLContext share_list, const EGLint *attrib_list) +{ + struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); + _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); + struct xlib_egl_context *ctx; + struct st_context *share_ctx = NULL; /* XXX fix */ + __GLcontextModes visual; + + ctx = CALLOC_STRUCT(xlib_egl_context); + if (!ctx) + return EGL_NO_CONTEXT; + + /* let EGL lib init the common stuff */ + if (!_eglInitContext(drv, dpy, &ctx->Base, config, attrib_list)) { + free(ctx); + return EGL_NO_CONTEXT; + } + + /* create a softpipe context */ + ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL); + + /* Now do xlib / state tracker inits here */ + _eglConfigToContextModesRec(conf, &visual); + ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx); + + + return _eglGetContextHandle(&ctx->Base); +} + + +static EGLBoolean +xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) +{ + struct xlib_egl_context *context = lookup_context(ctx); + if (context) { + if (context->Base.IsBound) { + context->Base.DeletePending = EGL_TRUE; + } + else { + st_destroy_context(context->Context); + free(context); + } + return EGL_TRUE; + } + else { + _eglError(EGL_BAD_CONTEXT, "eglDestroyContext"); + return EGL_TRUE; + } +} + + +/** + * Called via eglMakeCurrent(), drv->API.MakeCurrent(). + */ +static EGLBoolean +xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, + EGLSurface r, EGLContext context) +{ + if (!_eglMakeCurrent(drv, dpy, d, r, context)) + return EGL_FALSE; + + /* XXX anything todo? */ + + return EGL_TRUE; +} + + +static enum pipe_format +choose_color_format(const __GLcontextModes *visual) +{ + if (visual->redBits == 8 && + visual->greenBits == 8 && + visual->blueBits == 8 && + visual->alphaBits == 8) { + /* XXX this really also depends on the ordering of R,G,B,A */ + return PIPE_FORMAT_A8R8G8B8_UNORM; + } + else { + assert(0); + return PIPE_FORMAT_NONE; + } +} + + +static enum pipe_format +choose_depth_format(const __GLcontextModes *visual) +{ + if (visual->depthBits > 0) + return PIPE_FORMAT_Z24S8_UNORM; + else + return PIPE_FORMAT_NONE; +} + + +static enum pipe_format +choose_stencil_format(const __GLcontextModes *visual) +{ + if (visual->stencilBits > 0) + return PIPE_FORMAT_Z24S8_UNORM; + else + return PIPE_FORMAT_NONE; +} + + +/** + * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). + */ +static EGLSurface +xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + NativeWindowType window, const EGLint *attrib_list) +{ + struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); + _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); + + struct xlib_egl_surface *surf; + __GLcontextModes visual; + uint width, height; + + surf = CALLOC_STRUCT(xlib_egl_surface); + if (!surf) + return EGL_NO_SURFACE; + + /* Let EGL lib init the common stuff */ + if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_WINDOW_BIT, + config, attrib_list)) { + free(surf); + return EGL_NO_SURFACE; + } + + /* + * Now init the Xlib and gallium stuff + */ + surf->Win = (Window) window; /* The X window ID */ + surf->Dpy = disp->Xdpy; /* The X display */ + surf->Gc = XCreateGC(surf->Dpy, surf->Win, 0, NULL); + + surf->winsys = xdrv->winsys; + + _eglConfigToContextModesRec(conf, &visual); + get_drawable_size(surf->Dpy, surf->Win, &width, &height); + + /* Create GL statetracker framebuffer */ + surf->Framebuffer = st_create_framebuffer(&visual, + choose_color_format(&visual), + choose_depth_format(&visual), + choose_stencil_format(&visual), + width, height, + (void *) surf); + return surf; +} + + +static EGLBoolean +xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) +{ + /* error checking step: */ + if (!_eglSwapBuffers(drv, dpy, draw)) + return EGL_FALSE; + + { + struct xlib_egl_surface *xsurf = lookup_surface(draw); + struct pipe_winsys *pws = xsurf->winsys; + struct pipe_surface *psurf = + st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT); + + display_surface(pws, psurf, xsurf); + } + + return EGL_TRUE; +} + + +/** + * This is the main entrypoint into the driver. + * Called by libEGL to instantiate an _EGLDriver object. + */ +_EGLDriver * +_eglMain(_EGLDisplay *dpy, const char *args) +{ + struct xlib_egl_driver *xdrv; + + _eglLog(_EGL_INFO, "Entering EGL/Xlib _eglMain(%s)", args); + + xdrv = CALLOC_STRUCT(xlib_egl_driver); + if (!xdrv) + return NULL; + + _eglInitDriverFallbacks(&xdrv->Base); + xdrv->Base.API.Initialize = xlib_eglInitialize; + xdrv->Base.API.Terminate = xlib_eglTerminate; + xdrv->Base.API.CreateContext = xlib_eglCreateContext; + xdrv->Base.API.DestroyContext = xlib_eglDestroyContext; + xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface; + xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; + xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; + + + xdrv->Base.ClientAPIs = "OpenGL"; /* "OpenGL_ES" */ + xdrv->Base.Name = "Xlib/softpipe"; + + /* create one winsys and use it for all contexts/surfaces */ + xdrv->winsys = create_sw_winsys(); + xdrv->winsys->flush_frontbuffer = flush_frontbuffer; + + xdrv->screen = softpipe_create_screen(xdrv->winsys); + + + return &xdrv->Base; +} + diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c new file mode 100644 index 0000000000..0e71bdee9d --- /dev/null +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -0,0 +1,244 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Totally software-based winsys layer. + * Note that the one winsys function that we can't implement here + * is flush_frontbuffer(). + * Whoever uses this code will have to provide that. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "sw_winsys.h" + + + +/** Subclass of pipe_winsys */ +struct sw_pipe_winsys +{ + struct pipe_winsys Base; + /* no extra fields for now */ +}; + + +/** subclass of pipe_buffer */ +struct sw_pipe_buffer +{ + struct pipe_buffer Base; + boolean UserBuffer; /** Is this a user-space buffer? */ + void *Data; + void *Mapped; +}; + + +/** cast wrapper */ +static INLINE struct sw_pipe_buffer * +sw_pipe_buffer(struct pipe_buffer *b) +{ + return (struct sw_pipe_buffer *) b; +} + + + +static const char * +get_name(struct pipe_winsys *pws) +{ + return "software"; +} + + +/** Create new pipe_buffer and allocate storage of given size */ +static struct pipe_buffer * +buffer_create(struct pipe_winsys *pws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer); + if (!buffer) + return NULL; + + buffer->Base.refcount = 1; + buffer->Base.alignment = alignment; + buffer->Base.usage = usage; + buffer->Base.size = size; + + /* align to 16-byte multiple for Cell */ + buffer->Data = align_malloc(size, MAX2(alignment, 16)); + + return &buffer->Base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) +{ + struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer); + if (!buffer) + return NULL; + + buffer->Base.refcount = 1; + buffer->Base.size = bytes; + buffer->UserBuffer = TRUE; + buffer->Data = ptr; + + return &buffer->Base; +} + + +static void * +buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags) +{ + struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf); + buffer->Mapped = buffer->Data; + return buffer->Mapped; +} + + +static void +buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf); + buffer->Mapped = NULL; +} + + +static void +buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf); + + if (buffer->Data && !buffer->UserBuffer) { + align_free(buffer->Data); + buffer->Data = NULL; + } + + free(buffer); +} + + +/** + * Called via winsys->surface_alloc() to create new surfaces. + */ +static struct pipe_surface * +surface_alloc(struct pipe_winsys *ws) +{ + struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); + if (!surf) + return NULL; + + surf->refcount = 1; + surf->winsys = ws; + + return surf; +} + + +static void +surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + assert(!surf->texture); + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + +static void +fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ + /* no-op */ +} + + +static int +fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + /* no-op */ + return 0; +} + + +static int +fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + /* no-op */ + return 0; +} + + +/** + * Create/return a new pipe_winsys object. + */ +struct pipe_winsys * +create_sw_winsys(void) +{ + struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys); + if (!ws) + return NULL; + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + */ + ws->Base.buffer_create = buffer_create; + ws->Base.user_buffer_create = user_buffer_create; + ws->Base.buffer_map = buffer_map; + ws->Base.buffer_unmap = buffer_unmap; + ws->Base.buffer_destroy = buffer_destroy; + + ws->Base.surface_alloc = surface_alloc; + ws->Base.surface_alloc_storage = NULL; /* unused */ + ws->Base.surface_release = surface_release; + + ws->Base.fence_reference = fence_reference; + ws->Base.fence_signalled = fence_signalled; + ws->Base.fence_finish = fence_finish; + + ws->Base.flush_frontbuffer = NULL; /* not implemented here! */ + + ws->Base.get_name = get_name; + + return &ws->Base; +} diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.h b/src/gallium/winsys/egl_xlib/sw_winsys.h new file mode 100644 index 0000000000..f96c5a14b0 --- /dev/null +++ b/src/gallium/winsys/egl_xlib/sw_winsys.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef SW_WINSYS_H +#define SW_WINSYS_H + + +struct pipe_winsys; + + +extern struct pipe_winsys * +create_sw_winsys(void); + + +#endif /* SW_WINSYS_H */ -- cgit v1.2.3 From 9760ab234951d18c9606e962c6e3ac1f56fc6385 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 30 May 2008 13:30:51 +0200 Subject: i915: Fix extentions not being set --- src/gallium/winsys/dri/intel/intel_context.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index cc2fc11c5e..6a0c381849 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -35,6 +35,7 @@ #include "intel_batchbuffer.h" #include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" #include "pipe/p_defines.h" #include "pipe/p_context.h" @@ -218,6 +219,8 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); + driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); + return GL_TRUE; } -- cgit v1.2.3 From 2ade5268dca67a73d3f5f8cc41ea86d1e48de9f0 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 30 May 2008 13:31:42 +0200 Subject: i915: Remade texture allocation code again --- src/gallium/drivers/i915simple/i915_texture.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index b216e3bfb9..4c0c7ce3f3 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -128,7 +128,7 @@ i915_displaytarget_layout(struct pipe_screen *screen, { struct pipe_texture *pt = &tex->base; - if (pt->last_level > 1 || pt->cpp != 4) + if (pt->last_level > 0 || pt->cpp != 4) return 0; i915_miptree_set_level_info( tex, 0, 1, 0, 0, @@ -177,7 +177,7 @@ i945_miptree_layout_2d( struct i915_texture *tex ) /* Pitch must be a whole number of dwords, even though we * express it in texels. */ - tex->pitch = align_int(tex->pitch * pt->cpp, 4) / pt->cpp; + tex->pitch = align_int(tex->pitch * pt->cpp, 64) / pt->cpp; tex->total_height = 0; for (level = 0; level <= pt->last_level; level++) { @@ -537,10 +537,7 @@ i915_texture_create(struct pipe_screen *screen, tex->base.refcount = 1; tex->base.screen = screen; - if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { - if (!i915_displaytarget_layout(screen, tex)) - goto fail; - } else if (i915screen->is_i945) { + if (i915screen->is_i945) { if (!i945_miptree_layout(tex)) goto fail; } else { -- cgit v1.2.3 From 7b0a551c4cebc44cc06face712eb9659ccdebcc9 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 16:56:42 +0200 Subject: i915: Made batch buffer size much larger --- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 2 +- src/gallium/winsys/dri/intel/intel_screen.c | 6 +++--- src/gallium/winsys/dri/intel/intel_screen.h | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index aa2eed53b8..09d4eef484 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -65,7 +65,7 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch) driBOUnrefUserList(batch->list); driBOResetList(batch->list); - batch->size = 4 * 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; + batch->size = batch->intel->intelScreen->max_batch_size; driBOData(batch->buffer, batch->size, NULL, NULL, 0); /* diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 429a2cf8f8..0be88974f4 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -200,8 +200,8 @@ intelCreatePools(__DRIscreenPrivate * sPriv) DRM_BO_FLAG_MEM_TT, DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, - 4 * 4096, //intelScreen->maxBatchSize, - 1, 40, 16*16384, 0, + intelScreen->max_batch_size, + 1, 40, intelScreen->max_batch_size * 16, 0, intelScreen->fMan); #endif intelScreen->havePools = GL_TRUE; @@ -262,7 +262,7 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - + intelScreen->max_batch_size = 16 * 4096; #if 1 // ZZZ JB intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd); diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index c17f0202e4..1db0502b13 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -80,6 +80,7 @@ struct intel_screen struct _DriFenceMgr *mgr; struct _DriFreeSlabManager *fMan; unsigned batch_id; + unsigned max_batch_size; struct pipe_winsys *winsys; }; -- cgit v1.2.3 From b12a31f59d80a1d5703181b00b42df3fa712497b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 29 May 2008 16:57:34 +0200 Subject: i915: Now using draw_elements_range --- src/gallium/drivers/i915simple/i915_context.c | 29 +++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index c609d16a5a..81cab75738 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -50,10 +50,12 @@ static void i915_destroy( struct pipe_context *pipe ) static boolean -i915_draw_elements( struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned prim, unsigned start, unsigned count) +i915_draw_range_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned min_index, + unsigned max_index, + unsigned prim, unsigned start, unsigned count) { struct i915_context *i915 = i915_context( pipe ); struct draw_context *draw = i915->draw; @@ -77,7 +79,10 @@ i915_draw_elements( struct pipe_context *pipe, void *mapped_indexes = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ); - draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); + draw_set_mapped_element_buffer_range(draw, indexSize, + min_index, + max_index, + mapped_indexes); } else { /* no index/element buffer */ @@ -102,12 +107,23 @@ i915_draw_elements( struct pipe_context *pipe, } if (indexBuffer) { pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); - draw_set_mapped_element_buffer(draw, 0, NULL); + draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL); } return TRUE; } +static boolean +i915_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned prim, unsigned start, unsigned count) +{ + return i915_draw_range_elements( pipe, indexBuffer, + indexSize, + 0, 0xffffffff, + prim, start, count ); +} static boolean i915_draw_arrays( struct pipe_context *pipe, unsigned prim, unsigned start, unsigned count) @@ -138,6 +154,7 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen, i915->pipe.draw_arrays = i915_draw_arrays; i915->pipe.draw_elements = i915_draw_elements; + i915->pipe.draw_range_elements = i915_draw_range_elements; /* * Create drawing context and plug our rendering stage into it. -- cgit v1.2.3 From 1529a2c983f70ed7ff661ae6e8995cdfbca6d9cf Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 30 May 2008 14:51:09 +0100 Subject: draw: trim incoming primitives --- src/gallium/auxiliary/draw/draw_pt.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 723077159b..f0d7b51ad7 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -35,6 +35,10 @@ #include "draw/draw_private.h" #include "draw/draw_pt.h" +static unsigned trim( unsigned count, unsigned first, unsigned incr ) +{ + return count - (count - first) % incr; +} @@ -54,6 +58,17 @@ draw_pt_arrays(struct draw_context *draw, struct draw_pt_middle_end *middle = NULL; unsigned opt = 0; + /* Sanitize primitive length: + */ + { + unsigned first, incr; + draw_pt_split_prim(prim, &first, &incr); + count = trim(count, first, incr); + if (count < first) + return TRUE; + } + + if (!draw->render) { opt |= PT_PIPELINE; } -- cgit v1.2.3 From 057ee55720faee0e1269937d70bbafe6df5c57e6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 11:41:18 -0600 Subject: egl: added surface_alloc_storage() --- src/gallium/winsys/egl_xlib/sw_winsys.c | 39 ++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index 0e71bdee9d..fd0cb9fb12 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -70,6 +70,15 @@ sw_pipe_buffer(struct pipe_buffer *b) } +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + static const char * get_name(struct pipe_winsys *pws) @@ -168,6 +177,34 @@ surface_alloc(struct pipe_winsys *ws) } +static int +surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + + static void surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) { @@ -229,7 +266,7 @@ create_sw_winsys(void) ws->Base.buffer_destroy = buffer_destroy; ws->Base.surface_alloc = surface_alloc; - ws->Base.surface_alloc_storage = NULL; /* unused */ + ws->Base.surface_alloc_storage = surface_alloc_storage; ws->Base.surface_release = surface_release; ws->Base.fence_reference = fence_reference; -- cgit v1.2.3 From 750782a327a1d295f4ed00a590c362f32912d597 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 11:42:08 -0600 Subject: egl: assorted fixes. The code works now. --- src/gallium/winsys/egl_xlib/egl_xlib.c | 67 ++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 4741da87cd..555bb8b7b4 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -176,6 +176,28 @@ xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) } +static void +get_drawable_visual_info(Display *dpy, Drawable d, XVisualInfo *visInfo) +{ + XWindowAttributes attr; + XVisualInfo visTemp, *vis; + int num_visuals; + + XGetWindowAttributes(dpy, d, &attr); + + visTemp.screen = DefaultScreen(dpy); + visTemp.visualid = attr.visual->visualid; + vis = XGetVisualInfo(dpy, + (VisualScreenMask | VisualIDMask), + &visTemp, &num_visuals); + if (vis) + *visInfo = *vis; + + XFree(vis); +} + + + /** Get size of given window */ static Status get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) @@ -191,6 +213,16 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) } +static void +check_and_update_buffer_size(struct xlib_egl_surface *surface) +{ + uint width, height; + get_drawable_size(surface->Dpy, surface->Win, &width, &height); + st_resize_framebuffer(surface->Framebuffer, width, height); +} + + + static void display_surface(struct pipe_winsys *pws, struct pipe_surface *psurf, @@ -223,6 +255,8 @@ display_surface(struct pipe_winsys *pws, XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc, ximage, 0, 0, 0, 0, psurf->width, psurf->height); + XSync(xsurf->Dpy, 0); + ximage->data = NULL; XDestroyImage(ximage); @@ -303,13 +337,21 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) * Called via eglMakeCurrent(), drv->API.MakeCurrent(). */ static EGLBoolean -xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, - EGLSurface r, EGLContext context) +xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, + EGLSurface draw, EGLSurface read, EGLContext ctx) { - if (!_eglMakeCurrent(drv, dpy, d, r, context)) + struct xlib_egl_context *context = lookup_context(ctx); + struct xlib_egl_surface *draw_surf = lookup_surface(draw); + struct xlib_egl_surface *read_surf = lookup_surface(read); + + if (!_eglMakeCurrent(drv, dpy, draw, read, context)) return EGL_FALSE; - /* XXX anything todo? */ + st_make_current((context ? context->Context : NULL), + (draw_surf ? draw_surf->Framebuffer : NULL), + (read_surf ? read_surf->Framebuffer : NULL)); + + check_and_update_buffer_size(draw_surf); return EGL_TRUE; } @@ -336,7 +378,7 @@ static enum pipe_format choose_depth_format(const __GLcontextModes *visual) { if (visual->depthBits > 0) - return PIPE_FORMAT_Z24S8_UNORM; + return PIPE_FORMAT_S8Z24_UNORM; else return PIPE_FORMAT_NONE; } @@ -346,7 +388,7 @@ static enum pipe_format choose_stencil_format(const __GLcontextModes *visual) { if (visual->stencilBits > 0) - return PIPE_FORMAT_Z24S8_UNORM; + return PIPE_FORMAT_S8Z24_UNORM; else return PIPE_FORMAT_NONE; } @@ -378,6 +420,8 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, return EGL_NO_SURFACE; } + _eglSaveSurface(&surf->Base); + /* * Now init the Xlib and gallium stuff */ @@ -389,6 +433,10 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, _eglConfigToContextModesRec(conf, &visual); get_drawable_size(surf->Dpy, surf->Win, &width, &height); + get_drawable_visual_info(surf->Dpy, surf->Win, &surf->VisInfo); + + surf->Base.Width = width; + surf->Base.Height = height; /* Create GL statetracker framebuffer */ surf->Framebuffer = st_create_framebuffer(&visual, @@ -397,7 +445,10 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, choose_stencil_format(&visual), width, height, (void *) surf); - return surf; + + st_resize_framebuffer(surf->Framebuffer, width, height); + + return _eglGetSurfaceHandle(&surf->Base); } @@ -414,6 +465,8 @@ xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) struct pipe_surface *psurf = st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT); + st_notify_swapbuffers(xsurf->Framebuffer); + display_surface(pws, psurf, xsurf); } -- cgit v1.2.3 From 64d0eb111d5a19bc251dfc59884c945cf93c6bb0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 11:51:50 -0600 Subject: egl: fix-up window resizes --- src/gallium/winsys/egl_xlib/egl_xlib.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 555bb8b7b4..b683898dcb 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -219,6 +219,8 @@ check_and_update_buffer_size(struct xlib_egl_surface *surface) uint width, height; get_drawable_size(surface->Dpy, surface->Win, &width, &height); st_resize_framebuffer(surface->Framebuffer, width, height); + surface->Base.Width = width; + surface->Base.Height = height; } @@ -468,6 +470,8 @@ xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) st_notify_swapbuffers(xsurf->Framebuffer); display_surface(pws, psurf, xsurf); + + check_and_update_buffer_size(xsurf); } return EGL_TRUE; -- cgit v1.2.3 From 52676207e338b4c2b4953747521921ab79d70f06 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 12:06:06 -0600 Subject: egl: added eglDestroySurface function --- src/gallium/winsys/egl_xlib/egl_xlib.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index b683898dcb..bd2acd0411 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -454,6 +454,28 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, } +static EGLBoolean +xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +{ + struct xlib_egl_surface *surf = lookup_surface(surface); + if (surf) { + _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface); + if (surf->Base.IsBound) { + surf->Base.DeletePending = EGL_TRUE; + } + else { + st_unreference_framebuffer(&surf->Framebuffer); + free(surf); + } + return EGL_TRUE; + } + else { + _eglError(EGL_BAD_SURFACE, "eglDestroySurface"); + return EGL_FALSE; + } +} + + static EGLBoolean xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) { @@ -499,6 +521,7 @@ _eglMain(_EGLDisplay *dpy, const char *args) xdrv->Base.API.CreateContext = xlib_eglCreateContext; xdrv->Base.API.DestroyContext = xlib_eglDestroyContext; xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface; + xdrv->Base.API.DestroySurface = xlib_eglDestroySurface; xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; -- cgit v1.2.3 From ba7aeb8b34c2e310b6ba0d3dbfdc68b0d6ab82c8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 13:46:31 -0600 Subject: egl: specify client API by bit flag, not string --- src/gallium/winsys/egl_xlib/egl_xlib.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index bd2acd0411..1458f83c02 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -302,6 +302,12 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, return EGL_NO_CONTEXT; } + if (ctx->Base.ClientAPI != EGL_OPENGL_API) { + _eglError(EGL_BAD_MATCH, "eglCreateContext(only OpenGL API supported)"); + free(ctx); + return EGL_NO_CONTEXT; + } + /* create a softpipe context */ ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL); @@ -309,6 +315,7 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, _eglConfigToContextModesRec(conf, &visual); ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx); + _eglSaveContext(&ctx->Base); return _eglGetContextHandle(&ctx->Base); } @@ -525,8 +532,8 @@ _eglMain(_EGLDisplay *dpy, const char *args) xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; + xdrv->Base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; - xdrv->Base.ClientAPIs = "OpenGL"; /* "OpenGL_ES" */ xdrv->Base.Name = "Xlib/softpipe"; /* create one winsys and use it for all contexts/surfaces */ @@ -535,7 +542,6 @@ _eglMain(_EGLDisplay *dpy, const char *args) xdrv->screen = softpipe_create_screen(xdrv->winsys); - return &xdrv->Base; } -- cgit v1.2.3 From 3c4162ed2afe4da252d2a32c14e486515935ba39 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 14:51:40 -0600 Subject: egl: eglGetProcAddress() stub --- src/gallium/winsys/egl_xlib/egl_xlib.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 1458f83c02..99389970f5 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -176,6 +176,17 @@ xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) } +static _EGLProc +xlib_eglGetProcAddress(const char *procname) +{ + /* XXX for each supported API, evaluate GetProcAddress(name) */ + /* + return _glapi_get_proc_address(procname); + */ + return NULL; +} + + static void get_drawable_visual_info(Display *dpy, Drawable d, XVisualInfo *visInfo) { @@ -525,6 +536,7 @@ _eglMain(_EGLDisplay *dpy, const char *args) _eglInitDriverFallbacks(&xdrv->Base); xdrv->Base.API.Initialize = xlib_eglInitialize; xdrv->Base.API.Terminate = xlib_eglTerminate; + xdrv->Base.API.GetProcAddress = xlib_eglGetProcAddress; xdrv->Base.API.CreateContext = xlib_eglCreateContext; xdrv->Base.API.DestroyContext = xlib_eglDestroyContext; xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface; -- cgit v1.2.3 From 12bb9075221da6bf8121f3d705888f29ca11cc0f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 15:07:58 -0600 Subject: gallium: fix some PIPE_FORMAT_Z24S8_UNORM bugs in softpipe driver --- src/gallium/drivers/softpipe/sp_quad_depth_test.c | 2 +- src/gallium/drivers/softpipe/sp_tile_cache.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index a1859f9883..33888abcc5 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -230,7 +230,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) int x = quad->x0 % TILE_SIZE + (j & 1); int y = quad->y0 % TILE_SIZE + (j >> 1); uint z24s8 = tile->data.depth32[y][x]; - z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 24); + z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 8); tile->data.depth32[y][x] = z24s8; } break; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 28c29da87c..0e4c8c41ee 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -169,6 +169,7 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, PIPE_BUFFER_USAGE_CPU_WRITE); tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || + ps->format == PIPE_FORMAT_Z24S8_UNORM || ps->format == PIPE_FORMAT_Z16_UNORM || ps->format == PIPE_FORMAT_Z32_UNORM || ps->format == PIPE_FORMAT_S8_UNORM); -- cgit v1.2.3 From a9d6b1afa5b548a98c2b95db50236c4139d9f569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 31 May 2008 15:18:55 +0900 Subject: gallium: Port timing functions to WinCE. --- src/gallium/auxiliary/util/u_time.c | 74 ++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c index 9b97050d51..c6ce0afab0 100644 --- a/src/gallium/auxiliary/util/u_time.c +++ b/src/gallium/auxiliary/util/u_time.c @@ -33,26 +33,44 @@ */ -#include "util/u_time.h" +#include "pipe/p_config.h" #if defined(PIPE_OS_LINUX) #include #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) #include #include -#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) +#include +extern VOID KeQuerySystemTime(PLARGE_INTEGER); +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) #include #else #error Unsupported OS #endif +#include "util/u_time.h" + -#if defined(PIPE_OS_WINDOWS) -static LONGLONG frequency = 0; -#if !defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) -#define EngQueryPerformanceFrequency(p) QueryPerformanceFrequency((LARGE_INTEGER*)(p)) -#define EngQueryPerformanceCounter(p) QueryPerformanceCounter((LARGE_INTEGER*)(p)) +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) + +static int64_t frequency = 0; + +static INLINE void +util_time_get_frequency(void) +{ + if(!frequency) { +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + LONGLONG temp; + EngQueryPerformanceFrequency(&temp); + frequency = temp; +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) + LARGE_INTEGER temp; + QueryPerformanceFrequency(&temp); + frequency = temp.QuadPart; #endif + } +} #endif @@ -61,8 +79,20 @@ util_time_get(struct util_time *t) { #if defined(PIPE_OS_LINUX) gettimeofday(&t->tv, NULL); -#elif defined(PIPE_OS_WINDOWS) - EngQueryPerformanceCounter(&t->counter); +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + LONGLONG temp; + EngQueryPerformanceCounter(&temp); + t->counter = temp; +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + /* Updated every 10 miliseconds, measured in units of 100 nanoseconds. + * http://msdn.microsoft.com/en-us/library/ms801642.aspx */ + LARGE_INTEGER temp; + KeQuerySystemTime(&temp); + t->counter = temp.QuadPart; +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) + LARGE_INTEGER temp; + QueryPerformanceCounter(&temp); + t->counter = temp.QuadPart; #endif } @@ -75,10 +105,17 @@ util_time_add(const struct util_time *t1, #if defined(PIPE_OS_LINUX) t2->tv.tv_sec = t1->tv.tv_sec + usecs / 1000000; t2->tv.tv_usec = t1->tv.tv_usec + usecs % 1000000; -#elif defined(PIPE_OS_WINDOWS) - if(!frequency) - EngQueryPerformanceFrequency(&frequency); - t2->counter = t1->counter + (usecs * frequency + 999999LL)/1000000LL; +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) + util_time_get_frequency(); + t2->counter = t1->counter + (usecs * frequency + INT64_C(999999))/INT64_C(1000000); +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + /* 1 tick = 100 nano seconds. */ + t2->counter = t1->counter + usecs * 10; +#elif + LARGE_INTEGER temp; + LONGLONG freq; + freq = temp.QuadPart; + t2->counter = t1->counter + (usecs * freq)/1000000L; #endif } @@ -90,10 +127,11 @@ util_time_diff(const struct util_time *t1, #if defined(PIPE_OS_LINUX) return (t2->tv.tv_usec - t1->tv.tv_usec) + (t2->tv.tv_sec - t1->tv.tv_sec)*1000000; -#elif defined(PIPE_OS_WINDOWS) - if(!frequency) - EngQueryPerformanceFrequency(&frequency); - return (t2->counter - t1->counter)*1000000LL/frequency; +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) + util_time_get_frequency(); + return (t2->counter - t1->counter)*INT64_C(1000000)/frequency; +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + return (t2->counter - t1->counter)/10; #endif } @@ -142,7 +180,7 @@ util_time_timeout(const struct util_time *start, } -#if defined(PIPE_OS_WINDOWS) +#if defined(PIPE_SUBSYSYEM_WINDOWS_DISPLAY) void util_time_sleep(unsigned usecs) { LONGLONG start, curr, end; -- cgit v1.2.3 From 054189e87abcd399aadb449d13b2e331c060e65f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 31 May 2008 18:07:39 +0900 Subject: gallium: MSVC 8.0 already defines the cosf, sinf, etc. --- src/gallium/include/pipe/p_util.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 597354ca96..fe4ba3a689 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -410,8 +410,7 @@ extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, -#ifdef WIN32 - +#if !defined(_MSC_VER) && _MSC_VER < 0x800 #if !defined(_INC_MATH) || !defined(__cplusplus) static INLINE float cosf( float f ) @@ -453,6 +452,7 @@ static INLINE float logf( float f ) { return (float) cos( (double) f ); } + #endif /* _INC_MATH */ #endif -- cgit v1.2.3 From 45b2c23d7a2f1bd723d0719b13470125de09c243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 31 May 2008 18:08:24 +0900 Subject: i915: Eliminate void pointer arithmetic. --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index faf5971abb..cdbb5feb23 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -142,7 +142,7 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render, i915->vbo_offset = i915_render->vbo_offset; i915->dirty |= I915_NEW_VBO; - return i915_render->vbo_ptr + i915->vbo_offset; + return (unsigned char *)i915_render->vbo_ptr + i915->vbo_offset; } -- cgit v1.2.3 From 3b77f391db7827d1fb19a5dc3d8e8d3d705185ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 31 May 2008 18:51:44 +0900 Subject: draw: Eliminate stdio usage. --- src/gallium/auxiliary/draw/draw_vs_sse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 37cbe9bf9e..243d3eee23 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -185,7 +185,7 @@ draw_create_vs_sse(struct draw_context *draw, return &vs->base; fail: - fprintf(stderr, "tgsi_emit_sse2() failed, falling back to interpreter\n"); + debug_error("tgsi_emit_sse2() failed, falling back to interpreter\n"); x86_release_func( &vs->sse2_program ); -- cgit v1.2.3 From 13581958bd99396ab8ec314f10cf61f717b18a9b Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 18:19:21 +0200 Subject: draw: Remove const qualifier. --- src/gallium/auxiliary/draw/draw_private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 4f8cceee1e..423f64262b 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -193,7 +193,7 @@ struct draw_context const float (*aligned_constants)[4]; - const float (*aligned_constant_storage)[4]; + float (*aligned_constant_storage)[4]; unsigned const_storage_size; -- cgit v1.2.3 From 9046d1acfa91621ee83b3933fe6e4b52deb00cbf Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 18:40:00 +0200 Subject: gallium: Fix preprocessor logic. --- src/gallium/include/pipe/p_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index fe4ba3a689..9497eeeec9 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -410,7 +410,7 @@ extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, -#if !defined(_MSC_VER) && _MSC_VER < 0x800 +#if !defined(_MSC_VER) || _MSC_VER < 0x800 #if !defined(_INC_MATH) || !defined(__cplusplus) static INLINE float cosf( float f ) -- cgit v1.2.3 From a4abedc4f56e0442083aee9b39980900abf6ef40 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 18:40:39 +0200 Subject: draw: Remove const qualifier. --- src/gallium/auxiliary/draw/draw_vs_sse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 243d3eee23..f638208bf5 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -130,7 +130,7 @@ vs_sse_delete( struct draw_vertex_shader *base ) x86_release_func( &shader->sse2_program ); - align_free(shader->base.immediates); + align_free( (void *) shader->base.immediates ); FREE( (void*) shader->base.state.tokens ); FREE( shader ); -- cgit v1.2.3 From 9b3c1582befd0c64d9b48f7ed39566f9ae2e24d9 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 18:42:17 +0200 Subject: i915: Add mising include. --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index cdbb5feb23..f9297e29fc 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -38,6 +38,7 @@ */ +#include "draw/draw_context.h" #include "draw/draw_vbuf.h" #include "pipe/p_debug.h" #include "pipe/p_util.h" -- cgit v1.2.3 From 140e0e071890f24653e333e309778f6242c8d8f9 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 18:44:47 +0200 Subject: i915: Comment out dead & problematic code. --- src/gallium/drivers/i915simple/i915_texture.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 4c0c7ce3f3..f0d00280c2 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -104,6 +104,7 @@ i915_miptree_set_image_offset(struct i915_texture *tex, */ } +#if 0 static unsigned power_of_two(unsigned x) { @@ -112,6 +113,7 @@ power_of_two(unsigned x) value = value << 1; return value; } +#endif static unsigned round_up(unsigned n, unsigned multiple) -- cgit v1.2.3 From 4e33edfd06999e7c65b761be2d1cdc16e5b659c5 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 18:56:20 +0200 Subject: gallium: Refactor TGSI decalaration tokens. * Incorporate declaration_interpolation into declaration itself. * Remove declaration_mask -- always use declaration_range. --- src/gallium/include/pipe/p_shader_tokens.h | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index f05e1a34b3..282d32910e 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -55,9 +55,6 @@ enum tgsi_file_type { }; -#define TGSI_DECLARE_RANGE 0 -#define TGSI_DECLARE_MASK 1 - #define TGSI_WRITEMASK_NONE 0x00 #define TGSI_WRITEMASK_X 0x01 #define TGSI_WRITEMASK_Y 0x02 @@ -75,16 +72,19 @@ enum tgsi_file_type { #define TGSI_WRITEMASK_YZW 0x0E #define TGSI_WRITEMASK_XYZW 0x0F +#define TGSI_INTERPOLATE_CONSTANT 0 +#define TGSI_INTERPOLATE_LINEAR 1 +#define TGSI_INTERPOLATE_PERSPECTIVE 2 + struct tgsi_declaration { unsigned Type : 4; /* TGSI_TOKEN_TYPE_DECLARATION */ unsigned Size : 8; /* UINT */ unsigned File : 4; /* one of TGSI_FILE_x */ - unsigned Declare : 4; /* one of TGSI_DECLARE_x */ unsigned UsageMask : 4; /* bitmask of TGSI_WRITEMASK_x flags */ - unsigned Interpolate : 1; /* BOOL, any interpolation info? */ + unsigned Interpolate : 4; /* TGSI_INTERPOLATE_ */ unsigned Semantic : 1; /* BOOL, any semantic info? */ - unsigned Padding : 5; + unsigned Padding : 6; unsigned Extended : 1; /* BOOL */ }; @@ -94,21 +94,6 @@ struct tgsi_declaration_range unsigned Last : 16; /* UINT */ }; -struct tgsi_declaration_mask -{ - unsigned Mask : 32; /* UINT */ -}; - -#define TGSI_INTERPOLATE_CONSTANT 0 -#define TGSI_INTERPOLATE_LINEAR 1 -#define TGSI_INTERPOLATE_PERSPECTIVE 2 - -struct tgsi_declaration_interpolation -{ - unsigned Interpolate : 4; /* TGSI_INTERPOLATE_ */ - unsigned Padding : 28; -}; - #define TGSI_SEMANTIC_POSITION 0 #define TGSI_SEMANTIC_COLOR 1 #define TGSI_SEMANTIC_BCOLOR 2 /**< back-face color */ -- cgit v1.2.3 From c2ff3a66a1d9fe0b5303ded0503323a73a6a7391 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 19:40:36 +0200 Subject: draw: Fix build after TGSI declaration interface changes. --- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 35 ++++++++++++------------- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 27 +++++++++---------- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 27 +++++++++---------- 3 files changed, 43 insertions(+), 46 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index fd48b224b4..634bf067f1 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -141,18 +141,18 @@ aa_transform_decl(struct tgsi_transform_context *ctx, if (decl->Declaration.File == TGSI_FILE_OUTPUT && decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && decl->Semantic.SemanticIndex == 0) { - aactx->colorOutput = decl->u.DeclarationRange.First; + aactx->colorOutput = decl->DeclarationRange.First; } else if (decl->Declaration.File == TGSI_FILE_SAMPLER) { uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { + for (i = decl->DeclarationRange.First; + i <= decl->DeclarationRange.Last; i++) { aactx->samplersUsed |= 1 << i; } } else if (decl->Declaration.File == TGSI_FILE_INPUT) { - if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) - aactx->maxInput = decl->u.DeclarationRange.Last; + if ((int) decl->DeclarationRange.Last > aactx->maxInput) + aactx->maxInput = decl->DeclarationRange.Last; if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { aactx->maxGeneric = decl->Semantic.SemanticIndex; @@ -160,8 +160,8 @@ aa_transform_decl(struct tgsi_transform_context *ctx, } else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { + for (i = decl->DeclarationRange.First; + i <= decl->DeclarationRange.Last; i++) { aactx->tempsUsed |= (1 << i); } } @@ -225,34 +225,33 @@ aa_transform_inst(struct tgsi_transform_context *ctx, /* declare new generic input/texcoord */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; + /* XXX this could be linear... */ + decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; - decl.Declaration.Interpolate = 1; - /* XXX this could be linear... */ - decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->maxInput + 1; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = aactx->maxInput + 1; ctx->emit_declaration(ctx, &decl); /* declare new sampler */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_SAMPLER; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->freeSampler; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = aactx->freeSampler; ctx->emit_declaration(ctx, &decl); /* declare new temp regs */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->texTemp; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = aactx->texTemp; ctx->emit_declaration(ctx, &decl); decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->colorTemp; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = aactx->colorTemp; ctx->emit_declaration(ctx, &decl); aactx->firstInstruction = FALSE; diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 97d74ad693..96dcdb43d5 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -131,11 +131,11 @@ aa_transform_decl(struct tgsi_transform_context *ctx, if (decl->Declaration.File == TGSI_FILE_OUTPUT && decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && decl->Semantic.SemanticIndex == 0) { - aactx->colorOutput = decl->u.DeclarationRange.First; + aactx->colorOutput = decl->DeclarationRange.First; } else if (decl->Declaration.File == TGSI_FILE_INPUT) { - if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) - aactx->maxInput = decl->u.DeclarationRange.Last; + if ((int) decl->DeclarationRange.Last > aactx->maxInput) + aactx->maxInput = decl->DeclarationRange.Last; if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { aactx->maxGeneric = decl->Semantic.SemanticIndex; @@ -143,8 +143,8 @@ aa_transform_decl(struct tgsi_transform_context *ctx, } else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { + for (i = decl->DeclarationRange.First; + i <= decl->DeclarationRange.Last; i++) { aactx->tempsUsed |= (1 << i); } } @@ -193,27 +193,26 @@ aa_transform_inst(struct tgsi_transform_context *ctx, /* declare new generic input/texcoord */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; + /* XXX this could be linear... */ + decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; - decl.Declaration.Interpolate = 1; - /* XXX this could be linear... */ - decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = texInput; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = texInput; ctx->emit_declaration(ctx, &decl); /* declare new temp regs */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = tmp0; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = tmp0; ctx->emit_declaration(ctx, &decl); decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->colorTemp; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = aactx->colorTemp; ctx->emit_declaration(ctx, &decl); aactx->firstInstruction = FALSE; diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 4c92416eb1..4087cf7a49 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -132,20 +132,20 @@ pstip_transform_decl(struct tgsi_transform_context *ctx, if (decl->Declaration.File == TGSI_FILE_SAMPLER) { uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { + for (i = decl->DeclarationRange.First; + i <= decl->DeclarationRange.Last; i++) { pctx->samplersUsed |= 1 << i; } } else if (decl->Declaration.File == TGSI_FILE_INPUT) { - pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last); + pctx->maxInput = MAX2(pctx->maxInput, (int) decl->DeclarationRange.Last); if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) - pctx->wincoordInput = (int) decl->u.DeclarationRange.First; + pctx->wincoordInput = (int) decl->DeclarationRange.First; } else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { + for (i = decl->DeclarationRange.First; + i <= decl->DeclarationRange.Last; i++) { pctx->tempsUsed |= (1 << i); } } @@ -223,28 +223,27 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, /* declare new position input reg */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */ decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; decl.Semantic.SemanticIndex = 0; - decl.Declaration.Interpolate = 1; - decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */ - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = wincoordInput; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = wincoordInput; ctx->emit_declaration(ctx, &decl); } /* declare new sampler */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_SAMPLER; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = pctx->freeSampler; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = pctx->freeSampler; ctx->emit_declaration(ctx, &decl); /* declare new temp regs */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = pctx->texTemp; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = pctx->texTemp; ctx->emit_declaration(ctx, &decl); /* emit immediate = {1/32, 1/32, 1, 1} -- cgit v1.2.3 From 3de18c2ac3cf679875d22d7ae9e62a11f5ea03c9 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 19:41:29 +0200 Subject: gallivm: Fix build after TGSI declaration interface changes. --- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 9695358ab8..98014bdaa1 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -96,10 +96,8 @@ translate_declaration(struct gallivm_ir *prog, unsigned first, last, mask; uint interp_method; - assert(decl->Declaration.Declare == TGSI_DECLARE_RANGE); - - first = decl->u.DeclarationRange.First; - last = decl->u.DeclarationRange.Last; + first = decl->DeclarationRange.First; + last = decl->DeclarationRange.Last; mask = decl->Declaration.UsageMask; /* Do not touch WPOS.xy */ @@ -113,7 +111,7 @@ translate_declaration(struct gallivm_ir *prog, } } - interp_method = decl->Interpolation.Interpolate; + interp_method = decl->Declaration.Interpolate; if (mask == TGSI_WRITEMASK_XYZW) { unsigned i, j; @@ -153,7 +151,7 @@ translate_declarationir(struct gallivm_ir *, struct tgsi_full_declaration *) { if (decl->Declaration.File == TGSI_FILE_ADDRESS) { - int idx = decl->u.DeclarationRange.First; + int idx = decl->DeclarationRange.First; storage->addAddress(idx); } } -- cgit v1.2.3 From a49381587f73c67469ec7546419cfc41387f938c Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 19:48:13 +0200 Subject: tgsi: Fix build after TGSI declaration interface changes. --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 8 +- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 8 +- src/gallium/auxiliary/tgsi/util/tgsi_build.c | 126 ++++++--------------------- src/gallium/auxiliary/tgsi/util/tgsi_build.h | 19 +--- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 58 +++--------- src/gallium/auxiliary/tgsi/util/tgsi_parse.c | 17 +--- src/gallium/auxiliary/tgsi/util/tgsi_parse.h | 9 +- src/gallium/auxiliary/tgsi/util/tgsi_scan.c | 4 +- 8 files changed, 52 insertions(+), 197 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index 826b432f09..6ba0949183 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -1411,13 +1411,11 @@ exec_declaration( unsigned first, last, mask; eval_coef_func eval; - assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); - - first = decl->u.DeclarationRange.First; - last = decl->u.DeclarationRange.Last; + first = decl->DeclarationRange.First; + last = decl->DeclarationRange.Last; mask = decl->Declaration.UsageMask; - switch( decl->Interpolation.Interpolate ) { + switch( decl->Declaration.Interpolate ) { case TGSI_INTERPOLATE_CONSTANT: eval = eval_constant_coef; break; diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 189dc6024d..a59e22b6ea 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -1923,16 +1923,14 @@ emit_declaration( unsigned first, last, mask; unsigned i, j; - assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); - - first = decl->u.DeclarationRange.First; - last = decl->u.DeclarationRange.Last; + first = decl->DeclarationRange.First; + last = decl->DeclarationRange.Last; mask = decl->Declaration.UsageMask; for( i = first; i <= last; i++ ) { for( j = 0; j < NUM_CHANNELS; j++ ) { if( mask & (1 << j) ) { - switch( decl->Interpolation.Interpolate ) { + switch( decl->Declaration.Interpolate ) { case TGSI_INTERPOLATE_CONSTANT: emit_coef_a0( func, 0, i, j ); emit_inputs( func, 0, i, j ); diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.c b/src/gallium/auxiliary/tgsi/util/tgsi_build.c index 9c883ab704..63cc27becc 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.c @@ -90,9 +90,8 @@ tgsi_default_declaration( void ) declaration.Type = TGSI_TOKEN_TYPE_DECLARATION; declaration.Size = 1; declaration.File = TGSI_FILE_NULL; - declaration.Declare = TGSI_DECLARE_RANGE; declaration.UsageMask = TGSI_WRITEMASK_XYZW; - declaration.Interpolate = 0; + declaration.Interpolate = TGSI_INTERPOLATE_CONSTANT; declaration.Semantic = 0; declaration.Padding = 0; declaration.Extended = 0; @@ -103,7 +102,6 @@ tgsi_default_declaration( void ) struct tgsi_declaration tgsi_build_declaration( unsigned file, - unsigned declare, unsigned usage_mask, unsigned interpolate, unsigned semantic, @@ -112,11 +110,10 @@ tgsi_build_declaration( struct tgsi_declaration declaration; assert( file <= TGSI_FILE_IMMEDIATE ); - assert( declare <= TGSI_DECLARE_MASK ); + assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE ); declaration = tgsi_default_declaration(); declaration.File = file; - declaration.Declare = declare; declaration.UsageMask = usage_mask; declaration.Interpolate = interpolate; declaration.Semantic = semantic; @@ -144,7 +141,7 @@ tgsi_default_full_declaration( void ) struct tgsi_full_declaration full_declaration; full_declaration.Declaration = tgsi_default_declaration(); - full_declaration.Interpolation = tgsi_default_declaration_interpolation(); + full_declaration.DeclarationRange = tgsi_default_declaration_range(); full_declaration.Semantic = tgsi_default_declaration_semantic(); return full_declaration; @@ -159,6 +156,7 @@ tgsi_build_full_declaration( { unsigned size = 0; struct tgsi_declaration *declaration; + struct tgsi_declaration_range *dr; if( maxsize <= size ) return 0; @@ -167,63 +165,21 @@ tgsi_build_full_declaration( *declaration = tgsi_build_declaration( full_decl->Declaration.File, - full_decl->Declaration.Declare, full_decl->Declaration.UsageMask, full_decl->Declaration.Interpolate, full_decl->Declaration.Semantic, header ); - switch( full_decl->Declaration.Declare ) { - case TGSI_DECLARE_RANGE: - { - struct tgsi_declaration_range *dr; - - if( maxsize <= size ) - return 0; - dr = (struct tgsi_declaration_range *) &tokens[size]; - size++; - - *dr = tgsi_build_declaration_range( - full_decl->u.DeclarationRange.First, - full_decl->u.DeclarationRange.Last, - declaration, - header ); - break; - } - - case TGSI_DECLARE_MASK: - { - struct tgsi_declaration_mask *dm; - - if( maxsize <= size ) - return 0; - dm = (struct tgsi_declaration_mask *) &tokens[size]; - size++; - - *dm = tgsi_build_declaration_mask( - full_decl->u.DeclarationMask.Mask, - declaration, - header ); - break; - } - - default: - assert( 0 ); - } - - if( full_decl->Declaration.Interpolate ) { - struct tgsi_declaration_interpolation *di; - - if( maxsize <= size ) - return 0; - di = (struct tgsi_declaration_interpolation *) &tokens[size]; - size++; + if (maxsize <= size) + return 0; + dr = (struct tgsi_declaration_range *) &tokens[size]; + size++; - *di = tgsi_build_declaration_interpolation( - full_decl->Interpolation.Interpolate, - declaration, - header ); - } + *dr = tgsi_build_declaration_range( + full_decl->DeclarationRange.First, + full_decl->DeclarationRange.Last, + declaration, + header ); if( full_decl->Declaration.Semantic ) { struct tgsi_declaration_semantic *ds; @@ -243,6 +199,17 @@ tgsi_build_full_declaration( return size; } +struct tgsi_declaration_range +tgsi_default_declaration_range( void ) +{ + struct tgsi_declaration_range dr; + + dr.First = 0; + dr.Last = 0; + + return dr; +} + struct tgsi_declaration_range tgsi_build_declaration_range( unsigned first, @@ -255,6 +222,7 @@ tgsi_build_declaration_range( assert( last >= first ); assert( last <= 0xFFFF ); + declaration_range = tgsi_default_declaration_range(); declaration_range.First = first; declaration_range.Last = last; @@ -263,50 +231,6 @@ tgsi_build_declaration_range( return declaration_range; } -struct tgsi_declaration_mask -tgsi_build_declaration_mask( - unsigned mask, - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - struct tgsi_declaration_mask declaration_mask; - - declaration_mask.Mask = mask; - - declaration_grow( declaration, header ); - - return declaration_mask; -} - -struct tgsi_declaration_interpolation -tgsi_default_declaration_interpolation( void ) -{ - struct tgsi_declaration_interpolation di; - - di.Interpolate = TGSI_INTERPOLATE_CONSTANT; - di.Padding = 0; - - return di; -} - -struct tgsi_declaration_interpolation -tgsi_build_declaration_interpolation( - unsigned interpolate, - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - struct tgsi_declaration_interpolation di; - - assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE ); - - di = tgsi_default_declaration_interpolation(); - di.Interpolate = interpolate; - - declaration_grow( declaration, header ); - - return di; -} - struct tgsi_declaration_semantic tgsi_default_declaration_semantic( void ) { diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.h b/src/gallium/auxiliary/tgsi/util/tgsi_build.h index 80bffc4ae7..423cf141f5 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.h @@ -37,7 +37,6 @@ tgsi_default_declaration( void ); struct tgsi_declaration tgsi_build_declaration( unsigned file, - unsigned declare, unsigned usage_mask, unsigned interpolate, unsigned semantic, @@ -53,6 +52,9 @@ tgsi_build_full_declaration( struct tgsi_header *header, unsigned maxsize ); +struct tgsi_declaration_range +tgsi_default_declaration_range( void ); + struct tgsi_declaration_range tgsi_build_declaration_range( unsigned first, @@ -60,21 +62,6 @@ tgsi_build_declaration_range( struct tgsi_declaration *declaration, struct tgsi_header *header ); -struct tgsi_declaration_mask -tgsi_build_declaration_mask( - unsigned mask, - struct tgsi_declaration *declaration, - struct tgsi_header *header ); - -struct tgsi_declaration_interpolation -tgsi_default_declaration_interpolation( void ); - -struct tgsi_declaration_interpolation -tgsi_build_declaration_interpolation( - unsigned interpolate, - struct tgsi_declaration *declaration, - struct tgsi_header *header ); - struct tgsi_declaration_semantic tgsi_default_declaration_semantic( void ); diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index b018ea9fa1..d1a3dfd9c7 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -546,19 +546,13 @@ tgsi_dump_declaration( TXT( "\nDCL " ); ENM( decl->Declaration.File, TGSI_FILES_SHORT ); - switch( decl->Declaration.Declare ) { - case TGSI_DECLARE_RANGE: - CHR( '[' ); - UID( decl->u.DeclarationRange.First ); - if( decl->u.DeclarationRange.First != decl->u.DeclarationRange.Last ) { - TXT( ".." ); - UID( decl->u.DeclarationRange.Last ); - } - CHR( ']' ); - break; - default: - assert( 0 ); + CHR( '[' ); + UID( decl->DeclarationRange.First ); + if (decl->DeclarationRange.First != decl->DeclarationRange.Last) { + TXT( ".." ); + UID( decl->DeclarationRange.Last ); } + CHR( ']' ); if( decl->Declaration.UsageMask != TGSI_WRITEMASK_XYZW ) { CHR( '.' ); @@ -586,10 +580,8 @@ tgsi_dump_declaration( } } - if (decl->Declaration.Interpolate) { - TXT( ", " ); - ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES_SHORT ); - } + TXT( ", " ); + ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES_SHORT ); } static void @@ -601,8 +593,6 @@ dump_declaration_verbose( { TXT( "\nFile : " ); ENM( decl->Declaration.File, TGSI_FILES ); - TXT( "\nDeclare : " ); - ENM( decl->Declaration.Declare, TGSI_DECLARES ); if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) { TXT( "\nUsageMask : " ); if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { @@ -620,7 +610,7 @@ dump_declaration_verbose( } if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) { TXT( "\nInterpolate: " ); - UID( decl->Declaration.Interpolate ); + ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES ); } if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) { TXT( "\nSemantic : " ); @@ -632,32 +622,10 @@ dump_declaration_verbose( } EOL(); - switch( decl->Declaration.Declare ) { - case TGSI_DECLARE_RANGE: - TXT( "\nFirst: " ); - UID( decl->u.DeclarationRange.First ); - TXT( "\nLast : " ); - UID( decl->u.DeclarationRange.Last ); - break; - - case TGSI_DECLARE_MASK: - TXT( "\nMask: " ); - UIX( decl->u.DeclarationMask.Mask ); - break; - - default: - assert( 0 ); - } - - if( decl->Declaration.Interpolate ) { - EOL(); - TXT( "\nInterpolate: " ); - ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES ); - if( ignored ) { - TXT( "\nPadding : " ); - UIX( decl->Interpolation.Padding ); - } - } + TXT( "\nFirst: " ); + UID( decl->DeclarationRange.First ); + TXT( "\nLast : " ); + UID( decl->DeclarationRange.Last ); if( decl->Declaration.Semantic ) { EOL(); diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c index 5c0b0bfd61..d16f0cdcad 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c @@ -118,22 +118,7 @@ tgsi_parse_token( *decl = tgsi_default_full_declaration(); decl->Declaration = *(struct tgsi_declaration *) &token; - switch( decl->Declaration.Type ) { - case TGSI_DECLARE_RANGE: - next_token( ctx, &decl->u.DeclarationRange ); - break; - - case TGSI_DECLARE_MASK: - next_token( ctx, &decl->u.DeclarationMask ); - break; - - default: - assert (0); - } - - if( decl->Declaration.Interpolate ) { - next_token( ctx, &decl->Interpolation ); - } + next_token( ctx, &decl->DeclarationRange ); if( decl->Declaration.Semantic ) { next_token( ctx, &decl->Semantic ); diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h index 4102101093..054350712d 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h @@ -65,13 +65,8 @@ struct tgsi_full_src_register struct tgsi_full_declaration { struct tgsi_declaration Declaration; - union - { - struct tgsi_declaration_range DeclarationRange; - struct tgsi_declaration_mask DeclarationMask; - } u; - struct tgsi_declaration_interpolation Interpolation; - struct tgsi_declaration_semantic Semantic; + struct tgsi_declaration_range DeclarationRange; + struct tgsi_declaration_semantic Semantic; }; struct tgsi_full_immediate diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c index 65650ed22a..bda7bc2e2e 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c @@ -93,8 +93,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens, = &parse.FullToken.FullDeclaration; uint file = fulldecl->Declaration.File; uint i; - for (i = fulldecl->u.DeclarationRange.First; - i <= fulldecl->u.DeclarationRange.Last; + for (i = fulldecl->DeclarationRange.First; + i <= fulldecl->DeclarationRange.Last; i++) { /* only first 32 regs will appear in this bitfield */ -- cgit v1.2.3 From 56fc7690d791819d81ff1c6e6e22d22017c68919 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 19:50:58 +0200 Subject: util: Fix build after TGSI declaration interface changes. --- src/gallium/auxiliary/util/u_simple_shaders.c | 33 +++++++++++++-------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index 5f8d12191d..505d93d727 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -92,8 +92,8 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, decl.Semantic.SemanticName = semantic_names[i]; decl.Semantic.SemanticIndex = semantic_indexes[i]; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = i; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = i; ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, @@ -107,8 +107,8 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe, decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = semantic_names[i]; decl.Semantic.SemanticIndex = semantic_indexes[i]; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = i; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = i; ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, @@ -190,14 +190,13 @@ util_make_fragment_tex_shader(struct pipe_context *pipe, /* declare TEX[0] input */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; + /* XXX this could be linear... */ + decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; decl.Semantic.SemanticIndex = 0; - /* XXX this could be linear... */ - decl.Declaration.Interpolate = 1; - decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = 0; ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, @@ -209,8 +208,8 @@ util_make_fragment_tex_shader(struct pipe_context *pipe, decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; decl.Semantic.SemanticIndex = 0; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = 0; ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, @@ -219,8 +218,8 @@ util_make_fragment_tex_shader(struct pipe_context *pipe, /* declare sampler */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_SAMPLER; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = 0; ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, @@ -303,8 +302,8 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe, decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; decl.Semantic.SemanticIndex = 0; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = 0; ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, @@ -316,8 +315,8 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe, decl.Declaration.Semantic = 1; decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR; decl.Semantic.SemanticIndex = 0; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = 0; + decl.DeclarationRange.First = + decl.DeclarationRange.Last = 0; ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, -- cgit v1.2.3 From 347d28fd20645674c3509b9fb8ebf8c31a24c239 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 19:51:50 +0200 Subject: cell: Fix build after TGSI declaration interface changes. --- src/gallium/drivers/cell/spu/spu_exec.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 48edc62f49..69b0526120 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -830,13 +830,11 @@ exec_declaration(struct spu_exec_machine *mach, unsigned first, last, mask; interpolation_func interp; - assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); - - first = decl->u.DeclarationRange.First; - last = decl->u.DeclarationRange.Last; + first = decl->DeclarationRange.First; + last = decl->DeclarationRange.Last; mask = decl->Declaration.UsageMask; - switch( decl->Interpolation.Interpolate ) { + switch( decl->Declaration.Interpolate ) { case TGSI_INTERPOLATE_CONSTANT: interp = constant_interpolation; break; -- cgit v1.2.3 From 99b46555499005bd9454fb4a91d28d4e7d93dba4 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 19:52:41 +0200 Subject: i915: Fix build after TGSI declaration interface changes. --- src/gallium/drivers/i915simple/i915_fpc_translate.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 3ccf74c72c..48f3ceb2e8 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -943,8 +943,8 @@ i915_translate_instructions(struct i915_fp_compile *p, if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_CONSTANT) { uint i; - for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First; - i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last; + for (i = parse.FullToken.FullDeclaration.DeclarationRange.First; + i <= parse.FullToken.FullDeclaration.DeclarationRange.Last; i++) { assert(ifs->constant_flags[i] == 0x0); ifs->constant_flags[i] = I915_CONSTFLAG_USER; @@ -954,8 +954,8 @@ i915_translate_instructions(struct i915_fp_compile *p, else if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_TEMPORARY) { uint i; - for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First; - i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last; + for (i = parse.FullToken.FullDeclaration.DeclarationRange.First; + i <= parse.FullToken.FullDeclaration.DeclarationRange.Last; i++) { assert(i < I915_MAX_TEMPORARY); /* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */ -- cgit v1.2.3 From 01122116144619a93c7ebb852eaffb3a6c96fe67 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 31 May 2008 19:54:20 +0200 Subject: brw: Fix build after TGSI declaration interface changes. --- src/gallium/drivers/i965simple/brw_sf.c | 10 +++++----- src/gallium/drivers/i965simple/brw_shader_info.c | 4 +--- src/gallium/drivers/i965simple/brw_vs_emit.c | 6 ++---- src/gallium/drivers/i965simple/brw_wm_decl.c | 8 +++----- 4 files changed, 11 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_sf.c b/src/gallium/drivers/i965simple/brw_sf.c index c3b815a82b..96f8fb87a3 100644 --- a/src/gallium/drivers/i965simple/brw_sf.c +++ b/src/gallium/drivers/i965simple/brw_sf.c @@ -169,9 +169,9 @@ static void upload_sf_prog( struct brw_context *brw ) case TGSI_TOKEN_TYPE_DECLARATION: if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_INPUT) { - int first = parse.FullToken.FullDeclaration.u.DeclarationRange.First; - int last = parse.FullToken.FullDeclaration.u.DeclarationRange.Last; - int interp_mode = parse.FullToken.FullDeclaration.Interpolation.Interpolate; + int first = parse.FullToken.FullDeclaration.DeclarationRange.First; + int last = parse.FullToken.FullDeclaration.DeclarationRange.Last; + int interp_mode = parse.FullToken.FullDeclaration.Declaration.Interpolate; //int semantic = parse.FullToken.FullDeclaration.Semantic.SemanticName; //int semantic_index = parse.FullToken.FullDeclaration.Semantic.SemanticIndex; @@ -291,8 +291,8 @@ static void update_sf_linkage( struct brw_context *brw ) case TGSI_TOKEN_TYPE_DECLARATION: if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_INPUT) { - int first = parse.FullToken.FullDeclaration.u.DeclarationRange.First; - int last = parse.FullToken.FullDeclaration.u.DeclarationRange.Last; + int first = parse.FullToken.FullDeclaration.DeclarationRange.First; + int last = parse.FullToken.FullDeclaration.DeclarationRange.Last; for (i = first; i < last; i++) { vp_semantic[i].semantic = diff --git a/src/gallium/drivers/i965simple/brw_shader_info.c b/src/gallium/drivers/i965simple/brw_shader_info.c index f4694a4433..fb3da92421 100644 --- a/src/gallium/drivers/i965simple/brw_shader_info.c +++ b/src/gallium/drivers/i965simple/brw_shader_info.c @@ -26,9 +26,7 @@ void brw_shader_info(const struct tgsi_token *tokens, case TGSI_TOKEN_TYPE_DECLARATION: { const struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration; - unsigned last = decl->u.DeclarationRange.Last; - - assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); + unsigned last = decl->DeclarationRange.Last; // Broken by crazy wpos init: //assert( info->nr_regs[decl->Declaration.File] <= last); diff --git a/src/gallium/drivers/i965simple/brw_vs_emit.c b/src/gallium/drivers/i965simple/brw_vs_emit.c index 9020fcc001..a1432fece1 100644 --- a/src/gallium/drivers/i965simple/brw_vs_emit.c +++ b/src/gallium/drivers/i965simple/brw_vs_emit.c @@ -988,10 +988,8 @@ post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst ) static void process_declaration(const struct tgsi_full_declaration *decl, struct brw_prog_info *info) { - int first = decl->u.DeclarationRange.First; - int last = decl->u.DeclarationRange.Last; - - assert (decl->Declaration.Declare != TGSI_DECLARE_MASK); + int first = decl->DeclarationRange.First; + int last = decl->DeclarationRange.Last; switch(decl->Declaration.File) { case TGSI_FILE_CONSTANT: diff --git a/src/gallium/drivers/i965simple/brw_wm_decl.c b/src/gallium/drivers/i965simple/brw_wm_decl.c index 74ccfd494a..bf1b4d961a 100644 --- a/src/gallium/drivers/i965simple/brw_wm_decl.c +++ b/src/gallium/drivers/i965simple/brw_wm_decl.c @@ -351,18 +351,16 @@ void brw_wm_emit_decls(struct brw_wm_compile *c) case TGSI_TOKEN_TYPE_DECLARATION: { const struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration; - unsigned first = decl->u.DeclarationRange.First; - unsigned last = decl->u.DeclarationRange.Last; + unsigned first = decl->DeclarationRange.First; + unsigned last = decl->DeclarationRange.Last; unsigned mask = decl->Declaration.UsageMask; /* ? */ unsigned i; if (decl->Declaration.File != TGSI_FILE_INPUT) break; - assert(decl->Declaration.Interpolate); - for( i = first; i <= last; i++ ) { - switch (decl->Interpolation.Interpolate) { + switch (decl->Declaration.Interpolate) { case TGSI_INTERPOLATE_CONSTANT: emit_cinterp(c, i, mask); break; -- cgit v1.2.3 From 837d49a84e24420dbc06924f4862a5f7dcf4cace Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 2 Jun 2008 11:31:52 +0200 Subject: gallium: The SWZ opcode no longer aliases MOV. Also, when the extended swizzle token is used, the simple swizzle and negate are set to X,Y,Z,W and FALSE, respectively. --- src/gallium/include/pipe/p_shader_tokens.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 282d32910e..84e5096418 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -232,7 +232,7 @@ struct tgsi_immediate_float32 /* * GL_ARB_vertex_program */ -#define TGSI_OPCODE_SWZ TGSI_OPCODE_MOV +#define TGSI_OPCODE_SWZ 118 #define TGSI_OPCODE_XPD TGSI_OPCODE_CROSSPRODUCT /* @@ -388,7 +388,7 @@ struct tgsi_immediate_float32 #define TGSI_OPCODE_KIL 116 /* unpredicated kill */ #define TGSI_OPCODE_END 117 /* aka HALT */ -#define TGSI_OPCODE_LAST 118 +#define TGSI_OPCODE_LAST 119 #define TGSI_SAT_NONE 0 /* do not saturate */ #define TGSI_SAT_ZERO_ONE 1 /* clamp to [0,1] */ @@ -621,6 +621,10 @@ struct tgsi_src_register_ext * * NegateX, NegateY, NegateZ and NegateW negate individual components of the * source register. + * + * NOTE: To simplify matter, if this token is present, the corresponding Swizzle + * and Negate fields in tgsi_src_register should be set to X,Y,Z,W + * and FALSE, respectively. */ struct tgsi_src_register_ext_swz -- cgit v1.2.3 From c6ae627fdca417318d27a8c26e6d9bc23577aabe Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 2 Jun 2008 11:39:59 +0200 Subject: tgsi: SWZ no longer aliases to MOV. --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 2 +- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index 6ba0949183..6689c3f1fb 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -1477,7 +1477,7 @@ exec_instruction( break; case TGSI_OPCODE_MOV: - /* TGSI_OPCODE_SWZ */ + case TGSI_OPCODE_SWZ: FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( &r[0], 0, chan_index ); STORE( &r[0], 0, chan_index ); diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index a59e22b6ea..cdce5ea9c5 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -1190,7 +1190,7 @@ emit_instruction( break; case TGSI_OPCODE_MOV: - /* TGSI_OPCODE_SWZ */ + case TGSI_OPCODE_SWZ: FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); STORE( func, *inst, 0, 0, chan_index ); -- cgit v1.2.3 From dc6068a8bcd66e2cbcf76962c70ba202e0078a49 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 2 Jun 2008 11:40:44 +0200 Subject: cell: SWZ no longer aliases MOV. --- src/gallium/drivers/cell/spu/spu_exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 69b0526120..3a80df427d 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -896,7 +896,7 @@ exec_instruction( break; case TGSI_OPCODE_MOV: - /* TGSI_OPCODE_SWZ */ + case TGSI_OPCODE_SWZ: FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( &r[0], 0, chan_index ); STORE( &r[0], 0, chan_index ); -- cgit v1.2.3 From dfd30b878680dd6dca96928a06a301b837b7a650 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 2 Jun 2008 11:41:17 +0200 Subject: i915: SWZ no longer aliases MOV. --- src/gallium/drivers/i915simple/i915_fpc_translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 48f3ceb2e8..23cd909337 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -676,7 +676,7 @@ i915_translate_instruction(struct i915_fp_compile *p, break; case TGSI_OPCODE_MOV: - /* aka TGSI_OPCODE_SWZ */ + case TGSI_OPCODE_SWZ: emit_simple_arith(p, inst, A0_MOV, 1); break; -- cgit v1.2.3 From 49ed85d6b1cdb74a7985e2d743635c73151bbfdb Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 2 Jun 2008 11:42:16 +0200 Subject: brw: SWZ no longer aliases MOV. --- src/gallium/drivers/i965simple/brw_vs_emit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_vs_emit.c b/src/gallium/drivers/i965simple/brw_vs_emit.c index a1432fece1..81423e2d7d 100644 --- a/src/gallium/drivers/i965simple/brw_vs_emit.c +++ b/src/gallium/drivers/i965simple/brw_vs_emit.c @@ -1135,8 +1135,8 @@ static void process_instruction(struct brw_vs_compile *c, emit_min(p, dst, args[0], args[1]); break; case TGSI_OPCODE_MOV: -#if 0 case TGSI_OPCODE_SWZ: +#if 0 /* The args[0] value can't be used here as it won't have * correctly encoded the full swizzle: */ -- cgit v1.2.3 From 2c7ae3371b6058988f7f10bf031d630b649f3831 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 2 Jun 2008 11:59:04 +0200 Subject: tgsi: Add assertions to the new rule that when an extended swizzle is used, the simple swizzle must be set to identity. --- src/gallium/auxiliary/tgsi/util/tgsi_build.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.c b/src/gallium/auxiliary/tgsi/util/tgsi_build.c index 63cc27becc..18e44b38c2 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.c @@ -628,6 +628,14 @@ tgsi_build_full_instruction( tgsi_default_src_register_ext_swz() ) ) { struct tgsi_src_register_ext_swz *src_register_ext_swz; + /* Use of the extended swizzle requires the simple swizzle to be identity. + */ + assert( reg->SrcRegister.SwizzleX == TGSI_SWIZZLE_X ); + assert( reg->SrcRegister.SwizzleY == TGSI_SWIZZLE_Y ); + assert( reg->SrcRegister.SwizzleZ == TGSI_SWIZZLE_Z ); + assert( reg->SrcRegister.SwizzleW == TGSI_SWIZZLE_W ); + assert( reg->SrcRegister.Negate == FALSE ); + if( maxsize <= size ) return 0; src_register_ext_swz = -- cgit v1.2.3 From 5b86ae60fe339ae0b813d16ec328a68ccb2b9514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 30 May 2008 01:46:59 +0900 Subject: draw: Fix MSVC warnings. --- src/gallium/auxiliary/draw/draw_pipe.c | 3 ++- src/gallium/auxiliary/draw/draw_pt_decompose.h | 6 +++--- src/gallium/auxiliary/draw/draw_pt_varray.c | 4 ++-- src/gallium/auxiliary/draw/draw_vs.c | 6 +++--- src/gallium/auxiliary/draw/draw_vs_aos.c | 4 ++-- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 2 +- 6 files changed, 13 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 1d26706dee..3355c871ee 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -255,7 +255,8 @@ void draw_pipeline_run( struct draw_context *draw, char *verts = (char *)vertices; \ boolean flatfirst = (draw->rasterizer->flatshade && \ draw->rasterizer->flatshade_first); \ - unsigned i, flags + unsigned i; \ + ushort flags #define FLUSH diff --git a/src/gallium/auxiliary/draw/draw_pt_decompose.h b/src/gallium/auxiliary/draw/draw_pt_decompose.h index dccfde99dd..3fb0695687 100644 --- a/src/gallium/auxiliary/draw/draw_pt_decompose.h +++ b/src/gallium/auxiliary/draw/draw_pt_decompose.h @@ -118,9 +118,9 @@ static void FUNC( ARGS, /* These bitflags look a little odd because we submit the * vertices as (1,2,0) to satisfy flatshade requirements. */ - const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2; - const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1; + const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; + const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; + const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index 260f28f284..f19e8850b3 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -109,9 +109,9 @@ static INLINE void fetch_init(struct varray_frontend *varray, static INLINE void add_draw_el(struct varray_frontend *varray, - int idx) + unsigned idx) { - varray->draw_elts[varray->draw_count++] = idx; + varray->draw_elts[varray->draw_count++] = (ushort)idx; } diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index ce35112fc1..979f9864fd 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -49,10 +49,10 @@ void draw_vs_set_constants( struct draw_context *draw, if (((unsigned)constants) & 0xf) { if (size > draw->vs.const_storage_size) { if (draw->vs.aligned_constant_storage) - align_free(draw->vs.aligned_constant_storage); + align_free((void *)draw->vs.aligned_constant_storage); draw->vs.aligned_constant_storage = align_malloc( size, 16 ); } - memcpy( draw->vs.aligned_constant_storage, + memcpy( (void*)draw->vs.aligned_constant_storage, constants, size ); constants = draw->vs.aligned_constant_storage; @@ -174,7 +174,7 @@ draw_vs_destroy( struct draw_context *draw ) draw_vs_aos_machine_destroy(draw->vs.aos_machine); if (draw->vs.aligned_constant_storage) - align_free(draw->vs.aligned_constant_storage); + align_free((void*)draw->vs.aligned_constant_storage); tgsi_exec_machine_free_data(&draw->vs.machine); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 725f36b502..9e9f8bac1e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -492,7 +492,7 @@ static struct x86_reg fetch_src( struct aos_compilation *cp, src->SrcRegister.File, src->SrcRegister.Index); unsigned i; - unsigned swz = 0; + ubyte swz = 0; unsigned negs = 0; unsigned abs = 0; @@ -704,7 +704,7 @@ static void store_dest( struct aos_compilation *cp, static void inject_scalar( struct aos_compilation *cp, struct x86_reg dst, struct x86_reg result, - unsigned swizzle ) + ubyte swizzle ) { sse_shufps(cp->func, dst, dst, swizzle); sse_movss(cp->func, dst, result); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index 45e2092209..b720185709 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -118,7 +118,7 @@ static void get_src_ptr( struct aos_compilation *cp, static void emit_swizzle( struct aos_compilation *cp, struct x86_reg dest, struct x86_reg src, - unsigned shuffle ) + ubyte shuffle ) { sse_shufps(cp->func, dest, src, shuffle); } -- cgit v1.2.3 From 275fc32d588fb6d2b78038f5a97cc2bcd2cd61dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 2 Jun 2008 19:36:53 +0900 Subject: gallium: Identify each Windows platform individually from scons. --- src/gallium/include/pipe/p_config.h | 51 ++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index d2d2ae1617..af3746c026 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -33,12 +33,13 @@ * architecture, and operating system being used. These defines should be used * throughout the code to facilitate porting to new platforms. It is likely that * this file is auto-generated by an autoconf-like tool at some point, as some - * things cannot be determined by existing defines alone. + * things cannot be determined by pre-defined environment alone. * * See also: * - http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html * - echo | gcc -dM -E - | sort * - http://msdn.microsoft.com/en-us/library/b0084kay.aspx + * * @author José Fonseca */ @@ -54,6 +55,15 @@ #define PIPE_CC_GCC #endif +/* + * Meaning of _MSC_VER value: + * - 1400: Visual C++ 2005 + * - 1310: Visual C++ .NET 2003 + * - 1300: Visual C++ .NET 2002 + * + * __MSC__ seems to be an old macro -- it is not pre-defined on recent MSVC + * versions. + */ #if defined(_MSC_VER) || defined(__MSC__) #define PIPE_CC_MSVC #endif @@ -81,7 +91,9 @@ /* - * Operating system + * Operating system family. + * + * See subsystem below for a more fine-grained distinction. */ #if defined(__linux__) @@ -94,32 +106,31 @@ /* - * Subsystem + * Subsystem. * - * XXX: There is no way to autodetect this. + * NOTE: There is no way to auto-detect most of these. */ #if defined(PIPE_OS_LINUX) #define PIPE_SUBSYSTEM_DRI -#endif +#endif /* PIPE_OS_LINUX */ #if defined(PIPE_OS_WINDOWS) -#ifndef _WIN32_WCE -#if !defined(PIPE_SUBSYSTEM_USER) && !defined(PIPE_SUBSYSTEM_KERNEL) -#error Neither PIPE_SUBSYSTEM_USER or PIPE_SUBSYSTEM_KERNEL defined. -#endif -#if defined(PIPE_SUBSYSTEM_KERNEL) -#define PIPE_SUBSYSTEM_WINDOWS_DISPLAY -#endif -#if 0 /* FIXME */ -#define PIPE_SUBSYSTEM_WINDOWS_MINIPORT -#endif -#if defined(PIPE_SUBSYSTEM_USER) -#define PIPE_SUBSYSTEM_WINDOWS_USER -#endif -#else /* _WIN32_WCE */ +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) +/* Windows 2000/XP Display Driver */ +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) +/* Windows 2000/XP Miniport Driver */ +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) +/* Windows User-space Library */ +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) +/* Windows CE 5.0/6.0 */ +#else +#ifdef _WIN32_WCE #define PIPE_SUBSYSTEM_WINDOWS_CE -#endif /* _WIN32_WCE */ +#else /* !_WIN32_WCE */ +#error No PIPE_SUBSYSTEM_WINDOWS_xxx subsystem defined. +#endif /* !_WIN32_WCE */ +#endif #endif /* PIPE_OS_WINDOWS */ -- cgit v1.2.3 From 9b50043ea9e20c15a1be6735e533f5cc25a253ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 2 Jun 2008 19:46:05 +0900 Subject: gallium: Hopefully fix the cosf/sinf/etc. conditional compolation logic for good. --- src/gallium/include/pipe/p_util.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 9497eeeec9..cb3cd264e9 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -410,8 +410,7 @@ extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, -#if !defined(_MSC_VER) || _MSC_VER < 0x800 -#if !defined(_INC_MATH) || !defined(__cplusplus) +#if defined(_MSC_VER) && !defined(__cplusplus) static INLINE float cosf( float f ) { @@ -453,7 +452,6 @@ static INLINE float logf( float f ) return (float) cos( (double) f ); } -#endif /* _INC_MATH */ #endif -- cgit v1.2.3 From f4364cd1a6f9e825ea183c1fa6d1050b7e113695 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 30 May 2008 18:46:40 +0200 Subject: i915: Fixed initialization of surface --- src/gallium/drivers/i915simple/i915_texture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index f0d00280c2..16354dce50 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -624,8 +624,8 @@ i915_get_tex_surface(struct pipe_screen *screen, ps = CALLOC_STRUCT(pipe_surface);//ws->surface_alloc(ws); if (ps) { - assert(ps->refcount); - assert(ps->winsys); + ps->refcount = 1; + ps->winsys = ws; pipe_texture_reference(&ps->texture, pt); pipe_buffer_reference(ws, &ps->buffer, tex->buffer); ps->format = pt->format; -- cgit v1.2.3 From c1949e2bd3acc45c23cc434eef2b0d6aae9092ca Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 2 Jun 2008 12:55:35 +0200 Subject: i915: Fixed some warnings --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 4 +--- src/gallium/drivers/i915simple/i915_state_emit.c | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index f9297e29fc..adfb16fbc5 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -253,7 +253,6 @@ draw_arrays_fallback( struct vbuf_render *render, { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; - struct pipe_winsys *winsys = i915->pipe.winsys; unsigned nr_indices; if (i915->dirty) @@ -372,7 +371,6 @@ i915_vbuf_render_draw( struct vbuf_render *render, { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; - struct pipe_winsys *winsys = i915->pipe.winsys; unsigned save_nr_indices; save_nr_indices = nr_indices; @@ -424,7 +422,6 @@ i915_vbuf_render_release_vertices( struct vbuf_render *render, { struct i915_vbuf_render *i915_render = i915_vbuf_render(render); struct i915_context *i915 = i915_render->i915; - struct pipe_winsys *winsys = i915->pipe.winsys; size_t size = (size_t)vertex_size * (size_t)vertices_used; assert(i915->vbo); @@ -502,6 +499,7 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 ) render->destroy(render); return NULL; } + /** TODO JB: this shouldn't be here */ draw_set_render(i915->draw, render); return stage; diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 8bcc26ad35..de0c1a787a 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -377,6 +377,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) { uint w, h; boolean k = framebuffer_size(&i915->framebuffer, &w, &h); + (void)k; assert(k); OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); -- cgit v1.2.3 From 969a207fe356d152b65085a9113502c7fbb5712e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 2 Jun 2008 20:16:49 +0900 Subject: gallium: Fix log<->cos typo in logf. --- src/gallium/include/pipe/p_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 0d8ed167b2..3d8ad48d4f 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -452,7 +452,7 @@ static INLINE float fabsf( float f ) static INLINE float logf( float f ) { - return (float) cos( (double) f ); + return (float) log( (double) f ); } #endif /* _INC_MATH */ #endif -- cgit v1.2.3 From acdf24e53047892b83dc5b92567694600ffb8cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 2 Jun 2008 20:16:49 +0900 Subject: gallium: Fix log<->cos typo in logf. --- src/gallium/include/pipe/p_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index cb3cd264e9..0a9e2ef1b6 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -449,7 +449,7 @@ static INLINE float fabsf( float f ) static INLINE float logf( float f ) { - return (float) cos( (double) f ); + return (float) log( (double) f ); } #endif -- cgit v1.2.3 From aa1a39d1a742c1bb346ba14814d6bf7b44e646cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 2 Jun 2008 20:46:05 +0900 Subject: rtasm: Use enum sse_cc in sse_cmpps. --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 2 +- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 664a69a537..f4ca282dd9 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -888,7 +888,7 @@ void sse_unpcklps( struct x86_function *p, struct x86_reg dst, struct x86_reg sr void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, - unsigned char cc) + enum sse_cc cc) { DUMP_RRI( dst, src, cc ); emit_2ub(p, X86_TWOB, 0xC2); diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index bd76e1729c..af94577aab 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -191,7 +191,7 @@ void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, - unsigned char cc ); + enum sse_cc cc ); void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -- cgit v1.2.3 From 50274111341e82e1f26b1f3316042e5fe610ec8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 2 Jun 2008 21:43:31 +0900 Subject: gallium: More tweaks for the cosf/sinf logic. --- src/gallium/include/pipe/p_util.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 0a9e2ef1b6..5547e57833 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -410,8 +410,9 @@ extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, -#if defined(_MSC_VER) && !defined(__cplusplus) - +#if defined(_MSC_VER) +#if _MSC_VER < 1400 && !defined(__cplusplus) + static INLINE float cosf( float f ) { return (float) cos( (double) f ); @@ -452,7 +453,14 @@ static INLINE float logf( float f ) return (float) log( (double) f ); } +#else +/* Work-around an extra semi-colon in VS 2005 logf definition */ +#ifdef logf +#undef logf +#define logf(x) ((float)log((double)(x))) +#endif /* logf */ #endif +#endif /* _MSC_VER */ #ifdef __cplusplus -- cgit v1.2.3 From 8d9a96386a5be7f15968bed63ca8b3e5555bbeeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 2 Jun 2008 21:45:25 +0900 Subject: gallium: Port util_time functions to windows userspace. --- src/gallium/auxiliary/util/u_time.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c index c6ce0afab0..49dce75289 100644 --- a/src/gallium/auxiliary/util/u_time.c +++ b/src/gallium/auxiliary/util/u_time.c @@ -43,7 +43,7 @@ #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) #include extern VOID KeQuerySystemTime(PLARGE_INTEGER); -#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) #include #else #error Unsupported OS @@ -52,7 +52,7 @@ extern VOID KeQuerySystemTime(PLARGE_INTEGER); #include "util/u_time.h" -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) static int64_t frequency = 0; @@ -64,7 +64,7 @@ util_time_get_frequency(void) LONGLONG temp; EngQueryPerformanceFrequency(&temp); frequency = temp; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) LARGE_INTEGER temp; QueryPerformanceFrequency(&temp); frequency = temp.QuadPart; @@ -89,7 +89,7 @@ util_time_get(struct util_time *t) LARGE_INTEGER temp; KeQuerySystemTime(&temp); t->counter = temp.QuadPart; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) LARGE_INTEGER temp; QueryPerformanceCounter(&temp); t->counter = temp.QuadPart; @@ -105,7 +105,7 @@ util_time_add(const struct util_time *t1, #if defined(PIPE_OS_LINUX) t2->tv.tv_sec = t1->tv.tv_sec + usecs / 1000000; t2->tv.tv_usec = t1->tv.tv_usec + usecs % 1000000; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) util_time_get_frequency(); t2->counter = t1->counter + (usecs * frequency + INT64_C(999999))/INT64_C(1000000); #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) @@ -127,7 +127,7 @@ util_time_diff(const struct util_time *t1, #if defined(PIPE_OS_LINUX) return (t2->tv.tv_usec - t1->tv.tv_usec) + (t2->tv.tv_sec - t1->tv.tv_sec)*1000000; -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) util_time_get_frequency(); return (t2->counter - t1->counter)*INT64_C(1000000)/frequency; #elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) -- cgit v1.2.3 From e0860518dfb5a5c6ba6584e3c1b5d7b203277dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 2 Jun 2008 22:31:02 +0900 Subject: gallium: Replace XSTDCALL by PIPE_CDECL. --- src/gallium/auxiliary/draw/draw_vs_sse.c | 2 +- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 38 +++++++---------------------- src/gallium/drivers/softpipe/sp_fs_sse.c | 2 +- src/gallium/include/pipe/p_compiler.h | 16 +----------- 4 files changed, 12 insertions(+), 46 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index f638208bf5..0aa0c9a76b 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -50,7 +50,7 @@ #define SSE_MAX_VERTICES 4 -typedef void (XSTDCALL *codegen_function) ( +typedef void (PIPE_CDECL *codegen_function) ( const struct tgsi_exec_vector *input, /* 1 */ struct tgsi_exec_vector *output, /* 2 */ float (*constant)[4], /* 3 */ diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index cdce5ea9c5..cdbdf5c882 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -194,22 +194,12 @@ get_coef( } -#ifdef WIN32 -static void -emit_retw( - struct x86_function *func, - unsigned short size ) -{ - x86_retw( func, size ); -} -#else static void emit_ret( struct x86_function *func ) { x86_ret( func ); } -#endif /** @@ -475,7 +465,7 @@ static void emit_func_call_dst( struct x86_function *func, unsigned xmm_dst, - void (*code)() ) + void (PIPE_CDECL *code)() ) { sse_movaps( func, @@ -496,9 +486,7 @@ emit_func_call_dst( x86_push( func, ecx ); x86_mov_reg_imm( func, ecx, (unsigned long) code ); x86_call( func, ecx ); -#ifndef WIN32 x86_pop(func, ecx ); -#endif } @@ -516,7 +504,7 @@ emit_func_call_dst_src( struct x86_function *func, unsigned xmm_dst, unsigned xmm_src, - void (*code)() ) + void (PIPE_CDECL *code)() ) { sse_movaps( func, @@ -558,7 +546,7 @@ emit_add( make_xmm( xmm_src ) ); } -static void XSTDCALL +static void PIPE_CDECL cos4f( float *store ) { @@ -581,7 +569,7 @@ emit_cos( cos4f ); } -static void XSTDCALL +static void PIPE_CDECL ex24f( float *store ) { @@ -615,7 +603,7 @@ emit_f2it( make_xmm( xmm ) ); } -static void XSTDCALL +static void PIPE_CDECL flr4f( float *store ) { @@ -638,7 +626,7 @@ emit_flr( flr4f ); } -static void XSTDCALL +static void PIPE_CDECL frc4f( float *store ) { @@ -661,7 +649,7 @@ emit_frc( frc4f ); } -static void XSTDCALL +static void PIPE_CDECL lg24f( float *store ) { @@ -720,7 +708,7 @@ emit_neg( TGSI_EXEC_TEMP_80000000_C ) ); } -static void XSTDCALL +static void PIPE_CDECL pow4f( float *store ) { @@ -820,7 +808,7 @@ emit_setsign( TGSI_EXEC_TEMP_80000000_C ) ); } -static void XSTDCALL +static void PIPE_CDECL sin4f( float *store ) { @@ -1736,11 +1724,7 @@ emit_instruction( break; case TGSI_OPCODE_RET: -#ifdef WIN32 - emit_retw( func, 16 ); -#else emit_ret( func ); -#endif break; case TGSI_OPCODE_END: @@ -2281,11 +2265,7 @@ tgsi_emit_sse2( func, get_immediate_base() ); -#ifdef WIN32 - emit_retw( func, 16 ); -#else emit_ret( func ); -#endif tgsi_parse_free( &parse ); diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 55741cc1df..69f7f960aa 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -46,7 +46,7 @@ /* Surely this should be defined somewhere in a tgsi header: */ -typedef void (XSTDCALL *codegen_function)( +typedef void (PIPE_CDECL *codegen_function)( const struct tgsi_exec_vector *input, struct tgsi_exec_vector *output, const float (*constant)[4], diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index f6707385cd..b14260dd90 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -128,7 +128,7 @@ typedef unsigned char boolean; /* This should match linux gcc cdecl semantics everywhere, so that we * just codegen one calling convention on all platforms. */ -#ifdef WIN32 +#ifdef _MSC_VER #define PIPE_CDECL __cdecl #else #define PIPE_CDECL @@ -148,18 +148,4 @@ typedef unsigned char boolean; -/** - * For calling code-gen'd functions, phase out in favor of - * PIPE_CDECL, above, which really means cdecl on all platforms, not - * like the below... - */ -#if !defined(XSTDCALL) -#if defined(WIN32) -#define XSTDCALL __stdcall /* phase this out */ -#else -#define XSTDCALL /* XXX: NOTE! not STDCALL! */ -#endif -#endif - - #endif /* P_COMPILER_H */ -- cgit v1.2.3 From 6a39bcf3752df7c22cdd38b4645a885eb318add8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 2 Jun 2008 14:36:27 +0100 Subject: draw: fast element translate path without delta --- src/gallium/auxiliary/draw/draw_pt_vcache.c | 124 +++++++++++++++++++++------- 1 file changed, 93 insertions(+), 31 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 9ffc99abf9..ad86ab4292 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -201,39 +201,74 @@ static void vcache_ef_quad( struct vcache_frontend *vcache, #define FUNC vcache_run #include "draw_pt_vcache_tmp.h" +static void rebase_uint_elts( const unsigned *src, + unsigned count, + int delta, + ushort *dest ) +{ + unsigned i; + + for (i = 0; i < count; i++) + dest[i] = (ushort)(src[i] + delta); +} + +static void rebase_ushort_elts( const ushort *src, + unsigned count, + int delta, + ushort *dest ) +{ + unsigned i; + + for (i = 0; i < count; i++) + dest[i] = (ushort)(src[i] + delta); +} + +static void rebase_ubyte_elts( const ubyte *src, + unsigned count, + int delta, + ushort *dest ) +{ + unsigned i; + + for (i = 0; i < count; i++) + dest[i] = (ushort)(src[i] + delta); +} + + + static void translate_uint_elts( const unsigned *src, unsigned count, - int delta, ushort *dest ) { unsigned i; for (i = 0; i < count; i++) - dest[i] = (ushort)(src[i] + delta); + dest[i] = (ushort)(src[i]); } static void translate_ushort_elts( const ushort *src, unsigned count, - int delta, ushort *dest ) { unsigned i; for (i = 0; i < count; i++) - dest[i] = (ushort)(src[i] + delta); + dest[i] = (ushort)(src[i]); } static void translate_ubyte_elts( const ubyte *src, unsigned count, - int delta, ushort *dest ) { unsigned i; for (i = 0; i < count; i++) - dest[i] = (ushort)(src[i] + delta); + dest[i] = (ushort)(src[i]); } + + + #if 0 static enum pipe_format format_from_get_elt( pt_elt_func get_elt ) { @@ -282,31 +317,58 @@ static void vcache_check_run( struct draw_pt_front_end *frontend, if (!storage) goto fail; - switch(index_size) { - case 1: - translate_ubyte_elts( (const ubyte *)elts, - draw_count, - 0 - (int)min_index, - storage ); - break; - - case 2: - translate_ushort_elts( (const ushort *)elts, - draw_count, - 0 - (int)min_index, - storage ); - break; - - case 4: - translate_uint_elts( (const uint *)elts, - draw_count, - 0 - (int)min_index, - storage ); - break; - - default: - assert(0); - return; + if (min_index == 0) { + switch(index_size) { + case 1: + translate_ubyte_elts( (const ubyte *)elts, + draw_count, + storage ); + break; + + case 2: + translate_ushort_elts( (const ushort *)elts, + draw_count, + storage ); + break; + + case 4: + translate_uint_elts( (const uint *)elts, + draw_count, + storage ); + break; + + default: + assert(0); + return; + } + } + else { + switch(index_size) { + case 1: + rebase_ubyte_elts( (const ubyte *)elts, + draw_count, + 0 - (int)min_index, + storage ); + break; + + case 2: + rebase_ushort_elts( (const ushort *)elts, + draw_count, + 0 - (int)min_index, + storage ); + break; + + case 4: + rebase_uint_elts( (const uint *)elts, + draw_count, + 0 - (int)min_index, + storage ); + break; + + default: + assert(0); + return; + } } transformed_elts = storage; } -- cgit v1.2.3 From 7c22bb383a8fcccf71d7916ce91ae6cb17ac1e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 3 Jun 2008 00:03:17 +0900 Subject: gdi: Port of the gdi mesa driver to gallium (Alan Hourihane). --- src/gallium/winsys/gdi/SConscript | 33 ++ src/gallium/winsys/gdi/colors.h | 29 ++ src/gallium/winsys/gdi/opengl32.def | 859 ++++++++++++++++++++++++++++++++++ src/gallium/winsys/gdi/wgl.c | 703 ++++++++++++++++++++++++++++ src/gallium/winsys/gdi/wmesa.c | 890 ++++++++++++++++++++++++++++++++++++ src/gallium/winsys/gdi/wmesadef.h | 40 ++ 6 files changed, 2554 insertions(+) create mode 100644 src/gallium/winsys/gdi/SConscript create mode 100644 src/gallium/winsys/gdi/colors.h create mode 100644 src/gallium/winsys/gdi/opengl32.def create mode 100644 src/gallium/winsys/gdi/wgl.c create mode 100644 src/gallium/winsys/gdi/wmesa.c create mode 100644 src/gallium/winsys/gdi/wmesadef.h (limited to 'src/gallium') diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript new file mode 100644 index 0000000000..170fdf5127 --- /dev/null +++ b/src/gallium/winsys/gdi/SConscript @@ -0,0 +1,33 @@ +####################################################################### +# SConscript for gdi winsys + +Import('*') + +if env['platform'] == 'windows': + + env = env.Clone() + + env.Append(CPPPATH = [ + '#src/mesa/glapi', + '#src/mesa', + '#src/mesa/main', + ]) + + sources = [ + 'opengl32.def', + 'wgl.c', + 'wmesa.c', + ] + + drivers = [ + softpipe, + ] + + env.Append(LIBS = ['gdi32', 'user32']) + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='opengl32', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/winsys/gdi/colors.h b/src/gallium/winsys/gdi/colors.h new file mode 100644 index 0000000000..03e512c1fa --- /dev/null +++ b/src/gallium/winsys/gdi/colors.h @@ -0,0 +1,29 @@ +/* Values for wmesa->pixelformat: */ + +#define PF_8A8B8G8R 3 /* 32-bit TrueColor: 8-A, 8-B, 8-G, 8-R */ +#define PF_8R8G8B 4 /* 32-bit TrueColor: 8-R, 8-G, 8-B */ +#define PF_5R6G5B 5 /* 16-bit TrueColor: 5-R, 6-G, 5-B bits */ +#define PF_DITHER8 6 /* Dithered RGB using a lookup table */ +#define PF_LOOKUP 7 /* Undithered RGB using a lookup table */ +#define PF_GRAYSCALE 10 /* Grayscale or StaticGray */ +#define PF_BADFORMAT 11 +#define PF_INDEX8 12 + + +#define BGR8(r,g,b) (unsigned)(((BYTE)((b & 0xc0) | ((g & 0xe0)>>2) | \ + ((r & 0xe0)>>5)))) + +/* Windows uses 5,5,5 for 16-bit */ +#define BGR16(r,g,b) ( (((unsigned short)b ) >> 3) | \ + (((unsigned short)g & 0xf8) << 2) | \ + (((unsigned short)r & 0xf8) << 7) ) + +#define BGR24(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \ + ((WORD)((BYTE)(g))<<8))| \ + (((DWORD)(BYTE)(r))<<16))) + +#define BGR32(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \ + ((WORD)((BYTE)(g))<<8))| \ + (((DWORD)(BYTE)(r))<<16))) + + diff --git a/src/gallium/winsys/gdi/opengl32.def b/src/gallium/winsys/gdi/opengl32.def new file mode 100644 index 0000000000..54e72f57b1 --- /dev/null +++ b/src/gallium/winsys/gdi/opengl32.def @@ -0,0 +1,859 @@ +; DO NOT EDIT - This file generated automatically by mesadef.py script +;DESCRIPTION 'Mesa (OpenGL work-alike) for Win32' +VERSION 6.5 +; +; Module definition file for Mesa (OPENGL32.DLL) +; +; Note: The OpenGL functions use the STDCALL +; function calling convention. Microsoft's +; OPENGL32 uses this convention and so must the +; Mesa OPENGL32 so that the Mesa DLL can be used +; as a drop-in replacement. +; +; The linker exports STDCALL entry points with +; 'decorated' names; e.g., _glBegin@0, where the +; trailing number is the number of bytes of +; parameter data pushed onto the stack. The +; callee is responsible for popping this data +; off the stack, usually via a RETF n instruction. +; +; However, the Microsoft OPENGL32.DLL does not export +; the decorated names, even though the calling convention +; is STDCALL. So, this module definition file is +; needed to force the Mesa OPENGL32.DLL to export the +; symbols in the same manner as the Microsoft DLL. +; Were it not for this problem, this file would not +; be needed (for the gl* functions) since the entry +; points are compiled with dllexport declspec. +; +; However, this file is still needed to export "internal" +; Mesa symbols for the benefit of the OSMESA32.DLL. +; +EXPORTS + glNewList + glEndList + glCallList + glCallLists + glDeleteLists + glGenLists + glListBase + glBegin + glBitmap + glColor3b + glColor3bv + glColor3d + glColor3dv + glColor3f + glColor3fv + glColor3i + glColor3iv + glColor3s + glColor3sv + glColor3ub + glColor3ubv + glColor3ui + glColor3uiv + glColor3us + glColor3usv + glColor4b + glColor4bv + glColor4d + glColor4dv + glColor4f + glColor4fv + glColor4i + glColor4iv + glColor4s + glColor4sv + glColor4ub + glColor4ubv + glColor4ui + glColor4uiv + glColor4us + glColor4usv + glEdgeFlag + glEdgeFlagv + glEnd + glIndexd + glIndexdv + glIndexf + glIndexfv + glIndexi + glIndexiv + glIndexs + glIndexsv + glNormal3b + glNormal3bv + glNormal3d + glNormal3dv + glNormal3f + glNormal3fv + glNormal3i + glNormal3iv + glNormal3s + glNormal3sv + glRasterPos2d + glRasterPos2dv + glRasterPos2f + glRasterPos2fv + glRasterPos2i + glRasterPos2iv + glRasterPos2s + glRasterPos2sv + glRasterPos3d + glRasterPos3dv + glRasterPos3f + glRasterPos3fv + glRasterPos3i + glRasterPos3iv + glRasterPos3s + glRasterPos3sv + glRasterPos4d + glRasterPos4dv + glRasterPos4f + glRasterPos4fv + glRasterPos4i + glRasterPos4iv + glRasterPos4s + glRasterPos4sv + glRectd + glRectdv + glRectf + glRectfv + glRecti + glRectiv + glRects + glRectsv + glTexCoord1d + glTexCoord1dv + glTexCoord1f + glTexCoord1fv + glTexCoord1i + glTexCoord1iv + glTexCoord1s + glTexCoord1sv + glTexCoord2d + glTexCoord2dv + glTexCoord2f + glTexCoord2fv + glTexCoord2i + glTexCoord2iv + glTexCoord2s + glTexCoord2sv + glTexCoord3d + glTexCoord3dv + glTexCoord3f + glTexCoord3fv + glTexCoord3i + glTexCoord3iv + glTexCoord3s + glTexCoord3sv + glTexCoord4d + glTexCoord4dv + glTexCoord4f + glTexCoord4fv + glTexCoord4i + glTexCoord4iv + glTexCoord4s + glTexCoord4sv + glVertex2d + glVertex2dv + glVertex2f + glVertex2fv + glVertex2i + glVertex2iv + glVertex2s + glVertex2sv + glVertex3d + glVertex3dv + glVertex3f + glVertex3fv + glVertex3i + glVertex3iv + glVertex3s + glVertex3sv + glVertex4d + glVertex4dv + glVertex4f + glVertex4fv + glVertex4i + glVertex4iv + glVertex4s + glVertex4sv + glClipPlane + glColorMaterial + glCullFace + glFogf + glFogfv + glFogi + glFogiv + glFrontFace + glHint + glLightf + glLightfv + glLighti + glLightiv + glLightModelf + glLightModelfv + glLightModeli + glLightModeliv + glLineStipple + glLineWidth + glMaterialf + glMaterialfv + glMateriali + glMaterialiv + glPointSize + glPolygonMode + glPolygonStipple + glScissor + glShadeModel + glTexParameterf + glTexParameterfv + glTexParameteri + glTexParameteriv + glTexImage1D + glTexImage2D + glTexEnvf + glTexEnvfv + glTexEnvi + glTexEnviv + glTexGend + glTexGendv + glTexGenf + glTexGenfv + glTexGeni + glTexGeniv + glFeedbackBuffer + glSelectBuffer + glRenderMode + glInitNames + glLoadName + glPassThrough + glPopName + glPushName + glDrawBuffer + glClear + glClearAccum + glClearIndex + glClearColor + glClearStencil + glClearDepth + glStencilMask + glColorMask + glDepthMask + glIndexMask + glAccum + glDisable + glEnable + glFinish + glFlush + glPopAttrib + glPushAttrib + glMap1d + glMap1f + glMap2d + glMap2f + glMapGrid1d + glMapGrid1f + glMapGrid2d + glMapGrid2f + glEvalCoord1d + glEvalCoord1dv + glEvalCoord1f + glEvalCoord1fv + glEvalCoord2d + glEvalCoord2dv + glEvalCoord2f + glEvalCoord2fv + glEvalMesh1 + glEvalPoint1 + glEvalMesh2 + glEvalPoint2 + glAlphaFunc + glBlendFunc + glLogicOp + glStencilFunc + glStencilOp + glDepthFunc + glPixelZoom + glPixelTransferf + glPixelTransferi + glPixelStoref + glPixelStorei + glPixelMapfv + glPixelMapuiv + glPixelMapusv + glReadBuffer + glCopyPixels + glReadPixels + glDrawPixels + glGetBooleanv + glGetClipPlane + glGetDoublev + glGetError + glGetFloatv + glGetIntegerv + glGetLightfv + glGetLightiv + glGetMapdv + glGetMapfv + glGetMapiv + glGetMaterialfv + glGetMaterialiv + glGetPixelMapfv + glGetPixelMapuiv + glGetPixelMapusv + glGetPolygonStipple + glGetString + glGetTexEnvfv + glGetTexEnviv + glGetTexGendv + glGetTexGenfv + glGetTexGeniv + glGetTexImage + glGetTexParameterfv + glGetTexParameteriv + glGetTexLevelParameterfv + glGetTexLevelParameteriv + glIsEnabled + glIsList + glDepthRange + glFrustum + glLoadIdentity + glLoadMatrixf + glLoadMatrixd + glMatrixMode + glMultMatrixf + glMultMatrixd + glOrtho + glPopMatrix + glPushMatrix + glRotated + glRotatef + glScaled + glScalef + glTranslated + glTranslatef + glViewport + glArrayElement + glColorPointer + glDisableClientState + glDrawArrays + glDrawElements + glEdgeFlagPointer + glEnableClientState + glGetPointerv + glIndexPointer + glInterleavedArrays + glNormalPointer + glTexCoordPointer + glVertexPointer + glPolygonOffset + glCopyTexImage1D + glCopyTexImage2D + glCopyTexSubImage1D + glCopyTexSubImage2D + glTexSubImage1D + glTexSubImage2D + glAreTexturesResident + glBindTexture + glDeleteTextures + glGenTextures + glIsTexture + glPrioritizeTextures + glIndexub + glIndexubv + glPopClientAttrib + glPushClientAttrib + glBlendColor + glBlendEquation + glDrawRangeElements + glColorTable + glColorTableParameterfv + glColorTableParameteriv + glCopyColorTable + glGetColorTable + glGetColorTableParameterfv + glGetColorTableParameteriv + glColorSubTable + glCopyColorSubTable + glConvolutionFilter1D + glConvolutionFilter2D + glConvolutionParameterf + glConvolutionParameterfv + glConvolutionParameteri + glConvolutionParameteriv + glCopyConvolutionFilter1D + glCopyConvolutionFilter2D + glGetConvolutionFilter + glGetConvolutionParameterfv + glGetConvolutionParameteriv + glGetSeparableFilter + glSeparableFilter2D + glGetHistogram + glGetHistogramParameterfv + glGetHistogramParameteriv + glGetMinmax + glGetMinmaxParameterfv + glGetMinmaxParameteriv + glHistogram + glMinmax + glResetHistogram + glResetMinmax + glTexImage3D + glTexSubImage3D + glCopyTexSubImage3D + glActiveTextureARB + glClientActiveTextureARB + glMultiTexCoord1dARB + glMultiTexCoord1dvARB + glMultiTexCoord1fARB + glMultiTexCoord1fvARB + glMultiTexCoord1iARB + glMultiTexCoord1ivARB + glMultiTexCoord1sARB + glMultiTexCoord1svARB + glMultiTexCoord2dARB + glMultiTexCoord2dvARB + glMultiTexCoord2fARB + glMultiTexCoord2fvARB + glMultiTexCoord2iARB + glMultiTexCoord2ivARB + glMultiTexCoord2sARB + glMultiTexCoord2svARB + glMultiTexCoord3dARB + glMultiTexCoord3dvARB + glMultiTexCoord3fARB + glMultiTexCoord3fvARB + glMultiTexCoord3iARB + glMultiTexCoord3ivARB + glMultiTexCoord3sARB + glMultiTexCoord3svARB + glMultiTexCoord4dARB + glMultiTexCoord4dvARB + glMultiTexCoord4fARB + glMultiTexCoord4fvARB + glMultiTexCoord4iARB + glMultiTexCoord4ivARB + glMultiTexCoord4sARB + glMultiTexCoord4svARB + glLoadTransposeMatrixfARB + glLoadTransposeMatrixdARB + glMultTransposeMatrixfARB + glMultTransposeMatrixdARB + glSampleCoverageARB + glCompressedTexImage3DARB + glCompressedTexImage2DARB + glCompressedTexImage1DARB + glCompressedTexSubImage3DARB + glCompressedTexSubImage2DARB + glCompressedTexSubImage1DARB + glGetCompressedTexImageARB + glActiveTexture + glClientActiveTexture + glMultiTexCoord1d + glMultiTexCoord1dv + glMultiTexCoord1f + glMultiTexCoord1fv + glMultiTexCoord1i + glMultiTexCoord1iv + glMultiTexCoord1s + glMultiTexCoord1sv + glMultiTexCoord2d + glMultiTexCoord2dv + glMultiTexCoord2f + glMultiTexCoord2fv + glMultiTexCoord2i + glMultiTexCoord2iv + glMultiTexCoord2s + glMultiTexCoord2sv + glMultiTexCoord3d + glMultiTexCoord3dv + glMultiTexCoord3f + glMultiTexCoord3fv + glMultiTexCoord3i + glMultiTexCoord3iv + glMultiTexCoord3s + glMultiTexCoord3sv + glMultiTexCoord4d + glMultiTexCoord4dv + glMultiTexCoord4f + glMultiTexCoord4fv + glMultiTexCoord4i + glMultiTexCoord4iv + glMultiTexCoord4s + glMultiTexCoord4sv + glLoadTransposeMatrixf + glLoadTransposeMatrixd + glMultTransposeMatrixf + glMultTransposeMatrixd + glSampleCoverage + glCompressedTexImage3D + glCompressedTexImage2D + glCompressedTexImage1D + glCompressedTexSubImage3D + glCompressedTexSubImage2D + glCompressedTexSubImage1D + glGetCompressedTexImage + glBlendColorEXT + glPolygonOffsetEXT + glTexImage3DEXT + glTexSubImage3DEXT + glTexSubImage1DEXT + glTexSubImage2DEXT + glCopyTexImage1DEXT + glCopyTexImage2DEXT + glCopyTexSubImage1DEXT + glCopyTexSubImage2DEXT + glCopyTexSubImage3DEXT + glAreTexturesResidentEXT + glBindTextureEXT + glDeleteTexturesEXT + glGenTexturesEXT + glIsTextureEXT + glPrioritizeTexturesEXT + glArrayElementEXT + glColorPointerEXT + glDrawArraysEXT + glEdgeFlagPointerEXT + glGetPointervEXT + glIndexPointerEXT + glNormalPointerEXT + glTexCoordPointerEXT + glVertexPointerEXT + glBlendEquationEXT + glPointParameterfEXT + glPointParameterfvEXT + glPointParameterfARB + glPointParameterfvARB + glColorTableEXT + glGetColorTableEXT + glGetColorTableParameterivEXT + glGetColorTableParameterfvEXT + glLockArraysEXT + glUnlockArraysEXT + glDrawRangeElementsEXT + glSecondaryColor3bEXT + glSecondaryColor3bvEXT + glSecondaryColor3dEXT + glSecondaryColor3dvEXT + glSecondaryColor3fEXT + glSecondaryColor3fvEXT + glSecondaryColor3iEXT + glSecondaryColor3ivEXT + glSecondaryColor3sEXT + glSecondaryColor3svEXT + glSecondaryColor3ubEXT + glSecondaryColor3ubvEXT + glSecondaryColor3uiEXT + glSecondaryColor3uivEXT + glSecondaryColor3usEXT + glSecondaryColor3usvEXT + glSecondaryColorPointerEXT + glMultiDrawArraysEXT + glMultiDrawElementsEXT + glFogCoordfEXT + glFogCoordfvEXT + glFogCoorddEXT + glFogCoorddvEXT + glFogCoordPointerEXT + glBlendFuncSeparateEXT + glFlushVertexArrayRangeNV + glVertexArrayRangeNV + glCombinerParameterfvNV + glCombinerParameterfNV + glCombinerParameterivNV + glCombinerParameteriNV + glCombinerInputNV + glCombinerOutputNV + glFinalCombinerInputNV + glGetCombinerInputParameterfvNV + glGetCombinerInputParameterivNV + glGetCombinerOutputParameterfvNV + glGetCombinerOutputParameterivNV + glGetFinalCombinerInputParameterfvNV + glGetFinalCombinerInputParameterivNV + glResizeBuffersMESA + glWindowPos2dMESA + glWindowPos2dvMESA + glWindowPos2fMESA + glWindowPos2fvMESA + glWindowPos2iMESA + glWindowPos2ivMESA + glWindowPos2sMESA + glWindowPos2svMESA + glWindowPos3dMESA + glWindowPos3dvMESA + glWindowPos3fMESA + glWindowPos3fvMESA + glWindowPos3iMESA + glWindowPos3ivMESA + glWindowPos3sMESA + glWindowPos3svMESA + glWindowPos4dMESA + glWindowPos4dvMESA + glWindowPos4fMESA + glWindowPos4fvMESA + glWindowPos4iMESA + glWindowPos4ivMESA + glWindowPos4sMESA + glWindowPos4svMESA + glWindowPos2dARB + glWindowPos2fARB + glWindowPos2iARB + glWindowPos2sARB + glWindowPos2dvARB + glWindowPos2fvARB + glWindowPos2ivARB + glWindowPos2svARB + glWindowPos3dARB + glWindowPos3fARB + glWindowPos3iARB + glWindowPos3sARB + glWindowPos3dvARB + glWindowPos3fvARB + glWindowPos3ivARB + glWindowPos3svARB + glAreProgramsResidentNV + glBindProgramNV + glDeleteProgramsNV + glExecuteProgramNV + glGenProgramsNV + glGetProgramParameterdvNV + glGetProgramParameterfvNV + glGetProgramivNV + glGetProgramStringNV + glGetTrackMatrixivNV + glGetVertexAttribdvNV + glGetVertexAttribfvNV + glGetVertexAttribivNV + glGetVertexAttribPointervNV + glIsProgramNV + glLoadProgramNV + glProgramParameter4dNV + glProgramParameter4dvNV + glProgramParameter4fNV + glProgramParameter4fvNV + glProgramParameters4dvNV + glProgramParameters4fvNV + glRequestResidentProgramsNV + glTrackMatrixNV + glVertexAttribPointerNV + glVertexAttrib1dNV + glVertexAttrib1dvNV + glVertexAttrib1fNV + glVertexAttrib1fvNV + glVertexAttrib1sNV + glVertexAttrib1svNV + glVertexAttrib2dNV + glVertexAttrib2dvNV + glVertexAttrib2fNV + glVertexAttrib2fvNV + glVertexAttrib2sNV + glVertexAttrib2svNV + glVertexAttrib3dNV + glVertexAttrib3dvNV + glVertexAttrib3fNV + glVertexAttrib3fvNV + glVertexAttrib3sNV + glVertexAttrib3svNV + glVertexAttrib4dNV + glVertexAttrib4dvNV + glVertexAttrib4fNV + glVertexAttrib4fvNV + glVertexAttrib4sNV + glVertexAttrib4svNV + glVertexAttrib4ubNV + glVertexAttrib4ubvNV + glVertexAttribs1dvNV + glVertexAttribs1fvNV + glVertexAttribs1svNV + glVertexAttribs2dvNV + glVertexAttribs2fvNV + glVertexAttribs2svNV + glVertexAttribs3dvNV + glVertexAttribs3fvNV + glVertexAttribs3svNV + glVertexAttribs4dvNV + glVertexAttribs4fvNV + glVertexAttribs4svNV + glVertexAttribs4ubvNV + glPointParameteriNV + glPointParameterivNV + glFogCoordf + glFogCoordfv + glFogCoordd + glFogCoorddv + glFogCoordPointer + glMultiDrawArrays + glMultiDrawElements + glPointParameterf + glPointParameterfv + glPointParameteri + glPointParameteriv + glSecondaryColor3b + glSecondaryColor3bv + glSecondaryColor3d + glSecondaryColor3dv + glSecondaryColor3f + glSecondaryColor3fv + glSecondaryColor3i + glSecondaryColor3iv + glSecondaryColor3s + glSecondaryColor3sv + glSecondaryColor3ub + glSecondaryColor3ubv + glSecondaryColor3ui + glSecondaryColor3uiv + glSecondaryColor3us + glSecondaryColor3usv + glSecondaryColorPointer + glWindowPos2d + glWindowPos2dv + glWindowPos2f + glWindowPos2fv + glWindowPos2i + glWindowPos2iv + glWindowPos2s + glWindowPos2sv + glWindowPos3d + glWindowPos3dv + glWindowPos3f + glWindowPos3fv + glWindowPos3i + glWindowPos3iv + glWindowPos3s + glWindowPos3sv + glVertexAttrib1sARB + glVertexAttrib1fARB + glVertexAttrib1dARB + glVertexAttrib2sARB + glVertexAttrib2fARB + glVertexAttrib2dARB + glVertexAttrib3sARB + glVertexAttrib3fARB + glVertexAttrib3dARB + glVertexAttrib4sARB + glVertexAttrib4fARB + glVertexAttrib4dARB + glVertexAttrib4NubARB + glVertexAttrib1svARB + glVertexAttrib1fvARB + glVertexAttrib1dvARB + glVertexAttrib2svARB + glVertexAttrib2fvARB + glVertexAttrib2dvARB + glVertexAttrib3svARB + glVertexAttrib3fvARB + glVertexAttrib3dvARB + glVertexAttrib4bvARB + glVertexAttrib4svARB + glVertexAttrib4ivARB + glVertexAttrib4ubvARB + glVertexAttrib4usvARB + glVertexAttrib4uivARB + glVertexAttrib4fvARB + glVertexAttrib4dvARB + glVertexAttrib4NbvARB + glVertexAttrib4NsvARB + glVertexAttrib4NivARB + glVertexAttrib4NubvARB + glVertexAttrib4NusvARB + glVertexAttrib4NuivARB + glVertexAttribPointerARB + glEnableVertexAttribArrayARB + glDisableVertexAttribArrayARB + glProgramStringARB + glBindProgramARB + glDeleteProgramsARB + glGenProgramsARB + glIsProgramARB + glProgramEnvParameter4dARB + glProgramEnvParameter4dvARB + glProgramEnvParameter4fARB + glProgramEnvParameter4fvARB + glProgramLocalParameter4dARB + glProgramLocalParameter4dvARB + glProgramLocalParameter4fARB + glProgramLocalParameter4fvARB + glGetProgramEnvParameterdvARB + glGetProgramEnvParameterfvARB + glGetProgramLocalParameterdvARB + glGetProgramLocalParameterfvARB + glGetProgramivARB + glGetProgramStringARB + glGetVertexAttribdvARB + glGetVertexAttribfvARB + glGetVertexAttribivARB + glGetVertexAttribPointervARB + glProgramNamedParameter4fNV + glProgramNamedParameter4dNV + glProgramNamedParameter4fvNV + glProgramNamedParameter4dvNV + glGetProgramNamedParameterfvNV + glGetProgramNamedParameterdvNV + glBindBufferARB + glBufferDataARB + glBufferSubDataARB + glDeleteBuffersARB + glGenBuffersARB + glGetBufferParameterivARB + glGetBufferPointervARB + glGetBufferSubDataARB + glIsBufferARB + glMapBufferARB + glUnmapBufferARB + glGenQueriesARB + glDeleteQueriesARB + glIsQueryARB + glBeginQueryARB + glEndQueryARB + glGetQueryivARB + glGetQueryObjectivARB + glGetQueryObjectuivARB + glBindBuffer + glBufferData + glBufferSubData + glDeleteBuffers + glGenBuffers + glGetBufferParameteriv + glGetBufferPointerv + glGetBufferSubData + glIsBuffer + glMapBuffer + glUnmapBuffer + glGenQueries + glDeleteQueries + glIsQuery + glBeginQuery + glEndQuery + glGetQueryiv + glGetQueryObjectiv + glGetQueryObjectuiv +; +; WGL API + wglChoosePixelFormat + wglCopyContext + wglCreateContext + wglCreateLayerContext + wglDeleteContext + wglDescribeLayerPlane + wglDescribePixelFormat + wglGetCurrentContext + wglGetCurrentDC + wglGetLayerPaletteEntries + wglGetPixelFormat + wglGetProcAddress + wglMakeCurrent + wglRealizeLayerPalette + wglSetLayerPaletteEntries + wglSetPixelFormat + wglShareLists + wglSwapBuffers + wglSwapLayerBuffers + wglUseFontBitmapsA + wglUseFontBitmapsW + wglUseFontOutlinesA + wglUseFontOutlinesW + wglGetExtensionsStringARB diff --git a/src/gallium/winsys/gdi/wgl.c b/src/gallium/winsys/gdi/wgl.c new file mode 100644 index 0000000000..50126014a8 --- /dev/null +++ b/src/gallium/winsys/gdi/wgl.c @@ -0,0 +1,703 @@ +/* $Id: wgl.c,v 1.12 2006/03/30 07:58:24 kschultz Exp $ */ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * File name : wgl.c + * WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru + * Some things originated from the 3Dfx WGL functions + */ + +/* + * This file contains the implementation of the wgl* functions for + * Mesa on Windows. Since these functions are provided by Windows in + * GDI/OpenGL, we must supply our versions that work with Mesa here. + */ + + +/* We're essentially building part of GDI here, so define this so that + * we get the right export linkage. */ +#ifdef __MINGW32__ + +#include +#include +#include +#include + +# if defined(BUILD_GL32) +# define WINGDIAPI __declspec(dllexport) +# else +# define __W32API_USE_DLLIMPORT__ +# endif + +#include +#include "GL/mesa_wgl.h" +#include + +#else + +#define _GDI32_ +#include + +#endif + +#include "glapi.h" +#include "GL/wmesa.h" /* protos for wmesa* functions */ + +/* + * Pixel Format Descriptors + */ + +/* Extend the PFD to include DB flag */ +struct __pixelformat__ +{ + PIXELFORMATDESCRIPTOR pfd; + GLboolean doubleBuffered; +}; + +/* These are the PFD's supported by this driver. */ +struct __pixelformat__ pfd[] = +{ + /* Double Buffer, alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 8, 24, + 0, 0, 0, 0, 0, + 16, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_TRUE + }, + /* Single Buffer, alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 8, 24, + 0, 0, 0, 0, 0, + 16, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_FALSE + }, + /* Double Buffer, no alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 0, 0, + 0, 0, 0, 0, 0, + 16, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_TRUE + }, + /* Single Buffer, no alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 0, 0, + 0, 0, 0, 0, 0, + 16, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_FALSE + }, +}; + +int npfd = sizeof(pfd) / sizeof(pfd[0]); + + +/* + * Contexts + */ + +typedef struct { + WMesaContext ctx; +} MesaWglCtx; + +#define MESAWGL_CTX_MAX_COUNT 20 + +static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT]; + +static unsigned ctx_count = 0; +static int ctx_current = -1; +static unsigned curPFD = 0; + +static HDC CurrentHDC = 0; + + +WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc) +{ + int i = 0; + if (!ctx_count) { + for(i=0;inSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1) + { + SetLastError(0); + return(0); + } + for(i = 0; i < npfd;i++) + { + delta = 0; + if( + (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) && + !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW)) + continue; + if( + (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) && + !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP)) + continue; + if( + (ppfd->dwFlags & PFD_SUPPORT_GDI) && + !(pfd[i].pfd.dwFlags & PFD_SUPPORT_GDI)) + continue; + if( + (ppfd->dwFlags & PFD_SUPPORT_OPENGL) && + !(pfd[i].pfd.dwFlags & PFD_SUPPORT_OPENGL)) + continue; + if( + !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) && + ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != + (pfd[i].pfd.dwFlags & PFD_DOUBLEBUFFER))) + continue; + if( + !(ppfd->dwFlags & PFD_STEREO_DONTCARE) && + ((ppfd->dwFlags & PFD_STEREO) != + (pfd[i].pfd.dwFlags & PFD_STEREO))) + continue; + if(ppfd->iPixelType != pfd[i].pfd.iPixelType) + delta++; + if(ppfd->cAlphaBits != pfd[i].pfd.cAlphaBits) + delta++; + if(delta < bestdelta) + { + best = i + 1; + bestdelta = delta; + if(bestdelta == 0) + break; + } + } + if(best == -1) + { + SetLastError(0); + return(0); + } + return(best); +} + +WINGDIAPI int GLAPIENTRY wglDescribePixelFormat(HDC hdc, + int iPixelFormat, + UINT nBytes, + LPPIXELFORMATDESCRIPTOR ppfd) +{ + (void) hdc; + + if(ppfd == NULL) + return(npfd); + if(iPixelFormat < 1 || iPixelFormat > npfd || + nBytes != sizeof(PIXELFORMATDESCRIPTOR)) + { + SetLastError(0); + return(0); + } + *ppfd = pfd[iPixelFormat - 1].pfd; + return(npfd); +} + +WINGDIAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc) +{ + PROC p = (PROC) _glapi_get_proc_address((const char *) lpszProc); + if (p) + return p; + + SetLastError(0); + return(NULL); +} + +WINGDIAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc) +{ + (void) hdc; + if(curPFD == 0) { + SetLastError(0); + return(0); + } + return(curPFD); +} + +WINGDIAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat, + const PIXELFORMATDESCRIPTOR *ppfd) +{ + (void) hdc; + + if(iPixelFormat < 1 || iPixelFormat > npfd || + ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) { + SetLastError(0); + return(FALSE); + } + curPFD = iPixelFormat; + return(TRUE); +} + +WINGDIAPI BOOL GLAPIENTRY wglSwapBuffers(HDC hdc) +{ + WMesaSwapBuffers(hdc); + return TRUE; +} + +static FIXED FixedFromDouble(double d) +{ + long l = (long) (d * 65536L); + return *(FIXED *) (void *) &l; +} + + +/* +** This is cribbed from FX/fxwgl.c, and seems to implement support +** for bitmap fonts where the wglUseFontBitmapsA() code implements +** support for outline fonts. In combination they hopefully give +** fairly generic support for fonts. +*/ +static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar, + DWORD numChars, DWORD listBase) +{ +#define VERIFY(a) a + + TEXTMETRIC metric; + BITMAPINFO *dibInfo; + HDC bitDevice; + COLORREF tempColor; + int i; + + VERIFY(GetTextMetrics(fontDevice, &metric)); + + dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1); + dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + dibInfo->bmiHeader.biPlanes = 1; + dibInfo->bmiHeader.biBitCount = 1; + dibInfo->bmiHeader.biCompression = BI_RGB; + + bitDevice = CreateCompatibleDC(fontDevice); + + /* Swap fore and back colors so the bitmap has the right polarity */ + tempColor = GetBkColor(bitDevice); + SetBkColor(bitDevice, GetTextColor(bitDevice)); + SetTextColor(bitDevice, tempColor); + + /* Place chars based on base line */ + VERIFY(SetTextAlign(bitDevice, TA_BASELINE) != GDI_ERROR ? 1 : 0); + + for(i = 0; i < (int)numChars; i++) { + SIZE size; + char curChar; + int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res; + HBITMAP bitObject; + HGDIOBJ origBmap; + unsigned char *bmap; + + curChar = (char)(i + firstChar); + + /* Find how high/wide this character is */ + VERIFY(GetTextExtentPoint32(bitDevice, (LPCWSTR)&curChar, 1, &size)); + + /* Create the output bitmap */ + charWidth = size.cx; + charHeight = size.cy; + /* Round up to the next multiple of 32 bits */ + bmapWidth = ((charWidth + 31) / 32) * 32; + bmapHeight = charHeight; + bitObject = CreateCompatibleBitmap(bitDevice, + bmapWidth, + bmapHeight); + /* VERIFY(bitObject); */ + + /* Assign the output bitmap to the device */ + origBmap = SelectObject(bitDevice, bitObject); + (void) VERIFY(origBmap); + + VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) ); + + /* Use our source font on the device */ + VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT))); + + /* Draw the character */ + VERIFY(TextOut(bitDevice, 0, metric.tmAscent, (LPCWSTR)&curChar, 1)); + + /* Unselect our bmap object */ + VERIFY(SelectObject(bitDevice, origBmap)); + + /* Convert the display dependant representation to a 1 bit deep DIB */ + numBytes = (bmapWidth * bmapHeight) / 8; + bmap = (unsigned char *)malloc(numBytes); + dibInfo->bmiHeader.biWidth = bmapWidth; + dibInfo->bmiHeader.biHeight = bmapHeight; + res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap, + dibInfo, + DIB_RGB_COLORS); + /* VERIFY(res); */ + + /* Create the GL object */ + glNewList(i + listBase, GL_COMPILE); + glBitmap(bmapWidth, bmapHeight, 0.0, (GLfloat)metric.tmDescent, + (GLfloat)charWidth, 0.0, + bmap); + glEndList(); + /* CheckGL(); */ + + /* Destroy the bmap object */ + DeleteObject(bitObject); + + /* Deallocate the bitmap data */ + free(bmap); + } + + /* Destroy the DC */ + VERIFY(DeleteDC(bitDevice)); + + free(dibInfo); + + return TRUE; +#undef VERIFY +} + +WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first, + DWORD count, DWORD listBase) +{ + int i; + GLuint font_list; + DWORD size; + GLYPHMETRICS gm; + HANDLE hBits; + LPSTR lpBits; + MAT2 mat; + int success = TRUE; + + if (count == 0) + return FALSE; + + font_list = listBase; + + mat.eM11 = FixedFromDouble(1); + mat.eM12 = FixedFromDouble(0); + mat.eM21 = FixedFromDouble(0); + mat.eM22 = FixedFromDouble(-1); + + memset(&gm,0,sizeof(gm)); + + /* + ** If we can't get the glyph outline, it may be because this is a fixed + ** font. Try processing it that way. + */ + if( GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat) + == GDI_ERROR ) { + return wglUseFontBitmaps_FX( hdc, first, count, listBase ); + } + + /* + ** Otherwise process all desired characters. + */ + for (i = 0; i < (int)count; i++) { + DWORD err; + + glNewList( font_list+i, GL_COMPILE ); + + /* allocate space for the bitmap/outline */ + size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, + &gm, 0, NULL, &mat); + if (size == GDI_ERROR) { + glEndList( ); + err = GetLastError(); + success = FALSE; + continue; + } + + hBits = GlobalAlloc(GHND, size+1); + lpBits = GlobalLock(hBits); + + err = + GetGlyphOutline(hdc, /* handle to device context */ + first + i, /* character to query */ + GGO_BITMAP, /* format of data to return */ + &gm, /* ptr to structure for metrics*/ + size, /* size of buffer for data */ + lpBits, /* pointer to buffer for data */ + &mat /* pointer to transformation */ + /* matrix structure */ + ); + + if (err == GDI_ERROR) { + GlobalUnlock(hBits); + GlobalFree(hBits); + + glEndList( ); + err = GetLastError(); + success = FALSE; + continue; + } + + glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY, + (GLfloat)-gm.gmptGlyphOrigin.x, + (GLfloat)gm.gmptGlyphOrigin.y, + (GLfloat)gm.gmCellIncX, + (GLfloat)gm.gmCellIncY, + (const GLubyte * )lpBits); + + GlobalUnlock(hBits); + GlobalFree(hBits); + + glEndList( ); + } + + return success; +} + + + +/* NOT IMPLEMENTED YET */ +WINGDIAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc, + HGLRC hglrcDst, + UINT mask) +{ + (void) hglrcSrc; (void) hglrcDst; (void) mask; + return(FALSE); +} + +WINGDIAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc, + int iLayerPlane) +{ + (void) hdc; (void) iLayerPlane; + SetLastError(0); + return(NULL); +} + +WINGDIAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1, + HGLRC hglrc2) +{ + (void) hglrc1; (void) hglrc2; + return(TRUE); +} + + +WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase) +{ + (void) hdc; (void) first; (void) count; (void) listBase; + return FALSE; +} + +WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase, + FLOAT deviation, + FLOAT extrusion, + int format, + LPGLYPHMETRICSFLOAT lpgmf) +{ + (void) hdc; (void) first; (void) count; + (void) listBase; (void) deviation; (void) extrusion; (void) format; + (void) lpgmf; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase, + FLOAT deviation, + FLOAT extrusion, + int format, + LPGLYPHMETRICSFLOAT lpgmf) +{ + (void) hdc; (void) first; (void) count; + (void) listBase; (void) deviation; (void) extrusion; (void) format; + (void) lpgmf; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nBytes, + LPLAYERPLANEDESCRIPTOR plpd) +{ + (void) hdc; (void) iPixelFormat; (void) iLayerPlane; + (void) nBytes; (void) plpd; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc, + int iLayerPlane, + int iStart, + int cEntries, + CONST COLORREF *pcr) +{ + (void) hdc; (void) iLayerPlane; (void) iStart; + (void) cEntries; (void) pcr; + SetLastError(0); + return(0); +} + +WINGDIAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc, + int iLayerPlane, + int iStart, + int cEntries, + COLORREF *pcr) +{ + (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr; + SetLastError(0); + return(0); +} + +WINGDIAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc, + int iLayerPlane, + BOOL bRealize) +{ + (void) hdc; (void) iLayerPlane; (void) bRealize; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc, + UINT fuPlanes) +{ + (void) hdc; (void) fuPlanes; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI const char * GLAPIENTRY wglGetExtensionsStringARB(HDC hdc) +{ + return "WGL_ARB_extensions_string"; +} diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c new file mode 100644 index 0000000000..74a8292352 --- /dev/null +++ b/src/gallium/winsys/gdi/wmesa.c @@ -0,0 +1,890 @@ +/* + * Windows (Win32/Win64) device driver for Mesa + * + */ + +#include "mtypes.h" +#include +#include "wmesadef.h" + +#undef Elements + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "softpipe/sp_winsys.h" +#include "glapi/glapi.h" +#include "colors.h" + +extern GLvisual * +_mesa_create_visual( GLboolean rgbFlag, + GLboolean dbFlag, + GLboolean stereoFlag, + GLint redBits, + GLint greenBits, + GLint blueBits, + GLint alphaBits, + GLint indexBits, + GLint depthBits, + GLint stencilBits, + GLint accumRedBits, + GLint accumGreenBits, + GLint accumBlueBits, + GLint accumAlphaBits, + GLint numSamples ); + +/* linked list of our Framebuffers (windows) */ +WMesaFramebuffer FirstFramebuffer = NULL; + +struct wmesa_pipe_winsys +{ + struct pipe_winsys base; +}; + +/** + * Choose the pixel format for the given visual. + * This will tell the gallium driver how to pack pixel data into + * drawing surfaces. + */ +static GLuint +choose_pixel_format(GLvisual *v) +{ +#if 1 + return PIPE_FORMAT_A8R8G8B8_UNORM; +#else + if ( GET_REDMASK(v) == 0x0000ff + && GET_GREENMASK(v) == 0x00ff00 + && GET_BLUEMASK(v) == 0xff0000 + && v->BitsPerPixel == 32) { + if (CHECK_BYTE_ORDER(v)) { + /* no byteswapping needed */ + return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; + } + else { + return PIPE_FORMAT_R8G8B8A8_UNORM; + } + } + else if ( GET_REDMASK(v) == 0xff0000 + && GET_GREENMASK(v) == 0x00ff00 + && GET_BLUEMASK(v) == 0x0000ff + && v->BitsPerPixel == 32) { + if (CHECK_BYTE_ORDER(v)) { + /* no byteswapping needed */ + return PIPE_FORMAT_A8R8G8B8_UNORM; + } + else { + return PIPE_FORMAT_B8G8R8A8_UNORM; + } + } + else if ( GET_REDMASK(v) == 0xf800 + && GET_GREENMASK(v) == 0x07e0 + && GET_BLUEMASK(v) == 0x001f + && CHECK_BYTE_ORDER(v) + && v->BitsPerPixel == 16) { + /* 5-6-5 RGB */ + return PIPE_FORMAT_R5G6B5_UNORM; + } + +printf("BITS %d\n",v->BitsPerPixel); + assert(0); + return 0; +#endif +} + +/* + * Determine the pixel format based on the pixel size. + */ +static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC) +{ + /* Only 16 and 32 bit targets are supported now */ + assert(pwfb->cColorBits == 0 || + pwfb->cColorBits == 16 || + pwfb->cColorBits == 32); + + switch(pwfb->cColorBits){ + case 8: + pwfb->pixelformat = PF_INDEX8; + break; + case 16: + pwfb->pixelformat = PF_5R6G5B; + break; + case 32: + pwfb->pixelformat = PF_8R8G8B; + break; + default: + pwfb->pixelformat = PF_BADFORMAT; + } +} + + +/** + * Create DIB for back buffer. + * We write into this memory with the span routines and then blit it + * to the window on a buffer swap. + */ +BOOL wmCreateBackingStore(WMesaFramebuffer pwfb, long lxSize, long lySize) +{ + HDC hdc = pwfb->hDC; + BITMAPINFO bmi; + LPBITMAPINFO pbmi = &bmi; + HDC hic; + + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = lxSize; + pbmi->bmiHeader.biHeight= -lySize; + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = pwfb->cColorBits; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = 0; + pbmi->bmiHeader.biClrImportant = 0; + + hic = CreateIC("display", NULL, NULL, NULL); + pwfb->dib_hDC = CreateCompatibleDC(hic); + + pwfb->hbmDIB = CreateDIBSection(hic, + pbmi, + DIB_RGB_COLORS, + (void **)&(pwfb->pbPixels), + 0, + 0); + pwfb->hOldBitmap = SelectObject(pwfb->dib_hDC, pwfb->hbmDIB); + + DeleteDC(hic); + + wmSetPixelFormat(pwfb, pwfb->hDC); + return TRUE; +} + +/** + * Create a new WMesaFramebuffer object which will correspond to the + * given HDC (Window handle). + */ +WMesaFramebuffer +wmesa_new_framebuffer(HDC hdc, GLvisual *visual, GLuint width, GLuint height) +{ + WMesaFramebuffer pwfb + = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer)); + if (pwfb) { + enum pipe_format colorFormat, depthFormat, stencilFormat; + + /* determine PIPE_FORMATs for buffers */ + colorFormat = choose_pixel_format(visual); + + if (visual->depthBits == 0) + depthFormat = PIPE_FORMAT_NONE; + else if (visual->depthBits <= 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits <= 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_Z32_UNORM; + + if (visual->stencilBits == 8) { + if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) + stencilFormat = depthFormat; + else + stencilFormat = PIPE_FORMAT_S8_UNORM; + } + else { + stencilFormat = PIPE_FORMAT_NONE; + } + + pwfb->stfb = st_create_framebuffer(visual, + colorFormat, depthFormat, stencilFormat, + width, height, + (void *) pwfb); + + pwfb->cColorBits = GetDeviceCaps(hdc, BITSPIXEL); + +#if 0 + wmCreateBackingStore(pwfb, width, height); +#endif + + pwfb->hDC = hdc; + /* insert at head of list */ + pwfb->next = FirstFramebuffer; + FirstFramebuffer = pwfb; + } + return pwfb; +} + +/** + * Given an hdc, free the corresponding WMesaFramebuffer + */ +void +wmesa_free_framebuffer(HDC hdc) +{ + WMesaFramebuffer pwfb, prev; + for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { + if (pwfb->hDC == hdc) + break; + prev = pwfb; + } + if (pwfb) { + if (pwfb == FirstFramebuffer) + FirstFramebuffer = pwfb->next; + else + prev->next = pwfb->next; + free(pwfb); + } +} + +/** + * Given an hdc, return the corresponding WMesaFramebuffer + */ +WMesaFramebuffer +wmesa_lookup_framebuffer(HDC hdc) +{ + WMesaFramebuffer pwfb; + for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { + if (pwfb->hDC == hdc) + return pwfb; + } + return NULL; +} + + +/** + * Given a GLframebuffer, return the corresponding WMesaFramebuffer. + */ +static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb) +{ + return (WMesaFramebuffer) fb; +} + + +/** + * Given a GLcontext, return the corresponding WMesaContext. + */ +static WMesaContext wmesa_context(const GLcontext *ctx) +{ + return (WMesaContext) ctx; +} + +static wmDeleteBackingStore(WMesaFramebuffer pwfb) +{ + if (pwfb->hbmDIB) { + SelectObject(pwfb->dib_hDC, pwfb->hOldBitmap); + DeleteDC(pwfb->dib_hDC); + DeleteObject(pwfb->hbmDIB); + } +} + + +/** + * Find the width and height of the window named by hdc. + */ +static void +get_window_size(HDC hdc, GLuint *width, GLuint *height) +{ + if (WindowFromDC(hdc)) { + RECT rect; + GetClientRect(WindowFromDC(hdc), &rect); + *width = rect.right - rect.left; + *height = rect.bottom - rect.top; + } + else { /* Memory context */ + /* From contributed code - use the size of the desktop + * for the size of a memory context (?) */ + *width = GetDeviceCaps(hdc, HORZRES); + *height = GetDeviceCaps(hdc, VERTRES); + } +} + +/** + * Low-level OS/window system memory buffer + */ +struct wm_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + +struct wmesa_surface +{ + struct pipe_surface surface; + + int no_swap; +}; + + +/** Cast wrapper */ +static INLINE struct wmesa_surface * +wmesa_surface(struct pipe_surface *ps) +{ +// assert(0); + return (struct wmesa_surface *) ps; +} + +/** + * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque + * buffer pointer... + */ +static INLINE struct wm_buffer * +wm_buffer( struct pipe_buffer *buf ) +{ + return (struct wm_buffer *)buf; +} + + + +/* Most callbacks map direcly onto dri_bufmgr operations: + */ +static void * +wm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, + unsigned flags) +{ + struct wm_buffer *wm_buf = wm_buffer(buf); + wm_buf->mapped = wm_buf->data; + return wm_buf->mapped; +} + +static void +wm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf) +{ + struct wm_buffer *wm_buf = wm_buffer(buf); + wm_buf->mapped = NULL; +} + +static void +wm_buffer_destroy(struct pipe_winsys *pws, + struct pipe_buffer *buf) +{ + struct wm_buffer *oldBuf = wm_buffer(buf); + + if (oldBuf->data) { + { + if (!oldBuf->userBuffer) { + align_free(oldBuf->data); + } + } + + oldBuf->data = NULL; + } + + free(oldBuf); +} + + +static void +wm_flush_frontbuffer(struct pipe_winsys *pws, + struct pipe_surface *surf, + void *context_private) +{ + WMesaContext pwc = context_private; + WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(pwc->hDC); + struct wm_buffer *wm_buf; + BITMAPINFO bmi, *pbmi; + +#if 0 + if (pwfb) + BitBlt(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, + pwfb->dib_hDC, 0, 0, SRCCOPY); +#else + wm_buf = wm_buffer(surf->buffer); + + pbmi = &bmi; + memset(pbmi, 0, sizeof(BITMAPINFO)); + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = pwfb->stfb->Base.Width; + pbmi->bmiHeader.biHeight= -((long)pwfb->stfb->Base.Height); + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = pwfb->cColorBits; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = 0; + pbmi->bmiHeader.biClrImportant = 0; + + StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY); +#endif +} + + + +static const char * +wm_get_name(struct pipe_winsys *pws) +{ + return "gdi"; +} + +static struct pipe_buffer * +wm_buffer_create(struct pipe_winsys *pws, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct wm_buffer *buffer = CALLOC_STRUCT(wm_buffer); + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (buffer->data == NULL) { + /* align to 16-byte multiple for Cell */ + buffer->data = align_malloc(size, max(alignment, 16)); + } + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +wm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes) +{ + struct wm_buffer *buffer = CALLOC_STRUCT(wm_buffer); + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + +static int +wm_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + surf->cpp = pf_get_size(format); + surf->pitch = round_up(width, alignment / surf->cpp); + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->pitch * surf->cpp * height); + if(!surf->buffer) + return -1; + + return 0; +} + + +/** + * Called via winsys->surface_alloc() to create new surfaces. + */ +static struct pipe_surface * +wm_surface_alloc(struct pipe_winsys *ws) +{ + struct wmesa_surface *wms = CALLOC_STRUCT(wmesa_surface); + static boolean no_swap = 0; + static boolean firsttime = 1; + + if (firsttime) { + no_swap = getenv("SP_NO_RAST") != NULL; + firsttime = 0; + } + + assert(ws); + + wms->surface.refcount = 1; + wms->surface.winsys = ws; + + wms->no_swap = no_swap; + + return &wms->surface; +} + +static void +wm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + +/* + * Fence functions - basically nothing to do, as we don't create any actual + * fence objects. + */ + +static void +wm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +wm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +wm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + + +struct pipe_winsys * +wmesa_get_pipe_winsys(GLvisual *visual) +{ + static struct wmesa_pipe_winsys *ws = NULL; + + if (!ws) { + ws = CALLOC_STRUCT(wmesa_pipe_winsys); + + /* Fill in this struct with callbacks that pipe will need to + * communicate with the window system, buffer manager, etc. + */ + ws->base.buffer_create = wm_buffer_create; + ws->base.user_buffer_create = wm_user_buffer_create; + ws->base.buffer_map = wm_buffer_map; + ws->base.buffer_unmap = wm_buffer_unmap; + ws->base.buffer_destroy = wm_buffer_destroy; + + ws->base.surface_alloc = wm_surface_alloc; + ws->base.surface_alloc_storage = wm_surface_alloc_storage; + ws->base.surface_release = wm_surface_release; + + ws->base.fence_reference = wm_fence_reference; + ws->base.fence_signalled = wm_fence_signalled; + ws->base.fence_finish = wm_fence_finish; + + ws->base.flush_frontbuffer = wm_flush_frontbuffer; + ws->base.get_name = wm_get_name; + } + + return &ws->base; +} + + + +/**********************************************************************/ +/***** WMESA Functions *****/ +/**********************************************************************/ + +WMesaContext WMesaCreateContext(HDC hDC, + HPALETTE* Pal, + GLboolean rgb_flag, + GLboolean db_flag, + GLboolean alpha_flag) +{ + WMesaContext c; + struct pipe_winsys *pws; + struct pipe_context *pipe; + struct pipe_screen *screen; + GLint red_bits, green_bits, blue_bits, alpha_bits; + GLvisual *visual; + + (void) Pal; + + /* Indexed mode not supported */ + if (!rgb_flag) + return NULL; + + /* Allocate wmesa context */ + c = CALLOC_STRUCT(wmesa_context); + if (!c) + return NULL; + + c->hDC = hDC; + + /* Get data for visual */ + /* Dealing with this is actually a bit of overkill because Mesa will end + * up treating all color component size requests less than 8 by using + * a single byte per channel. In addition, the interface to the span + * routines passes colors as an entire byte per channel anyway, so there + * is nothing to be saved by telling the visual to be 16 bits if the device + * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per + * channel anyway. + * But we go through the motions here anyway. + */ + c->cColorBits = GetDeviceCaps(c->hDC, BITSPIXEL); + + switch (c->cColorBits) { + case 16: + red_bits = green_bits = blue_bits = 5; + alpha_bits = 0; + break; + default: + red_bits = green_bits = blue_bits = 8; + alpha_bits = 8; + break; + } + /* Create visual based on flags */ + visual = _mesa_create_visual(rgb_flag, + db_flag, /* db_flag */ + GL_FALSE, /* stereo */ + red_bits, green_bits, blue_bits, /* color RGB */ + alpha_flag ? alpha_bits : 0, /* color A */ + 0, /* index bits */ + DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */ + 8, /* stencil_bits */ + 16,16,16, /* accum RGB */ + alpha_flag ? 16 : 0, /* accum A */ + 1); /* num samples */ + + if (!visual) { + _mesa_free(c); + return NULL; + } + + pws = wmesa_get_pipe_winsys(visual); + + screen = softpipe_create_screen(pws); + + if (!screen) { + _mesa_free(c); + return NULL; + } + + pipe = softpipe_create(screen, pws, NULL); + + if (!pipe) { + /* FIXME - free screen */ + _mesa_free(c); + return NULL; + } + + pipe->priv = c; + + c->st = st_create_context(pipe, visual, NULL); + + c->st->ctx->DriverCtx = c; + + return c; +} + + +void WMesaDestroyContext( WMesaContext pwc ) +{ + GLcontext *ctx = pwc->st->ctx; + WMesaFramebuffer pwfb; + GET_CURRENT_CONTEXT(cur_ctx); + + if (cur_ctx == ctx) { + /* unbind current if deleting current context */ + WMesaMakeCurrent(NULL, NULL); + } + + /* clean up frame buffer resources */ + pwfb = wmesa_lookup_framebuffer(pwc->hDC); + if (pwfb) { +#if 0 + wmDeleteBackingStore(pwfb); +#endif + wmesa_free_framebuffer(pwc->hDC); + } + + /* Release for device, not memory contexts */ + if (WindowFromDC(pwc->hDC) != NULL) + { + ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC); + } + + st_destroy_context(pwc->st); + _mesa_free(pwc); +} + + +void WMesaMakeCurrent(WMesaContext c, HDC hdc) +{ + GLuint width = 0, height = 0; + WMesaFramebuffer pwfb; + + { + /* return if already current */ + GET_CURRENT_CONTEXT(ctx); + WMesaContext pwc = wmesa_context(ctx); + if (pwc && c == pwc && pwc->hDC == hdc) + return; + } + + pwfb = wmesa_lookup_framebuffer(hdc); + + if (hdc) { + get_window_size(hdc, &width, &height); + } + + /* Lazy creation of framebuffers */ + if (c && !pwfb && (hdc != 0)) { + GLvisual *visual = &c->st->ctx->Visual; + + pwfb = wmesa_new_framebuffer(hdc, visual, width, height); + } + + if (c && pwfb) { + st_make_current(c->st, pwfb->stfb, pwfb->stfb); + + st_resize_framebuffer(pwfb->stfb, width, height); + } + else { + /* Detach */ + st_make_current( NULL, NULL, NULL ); + } +} + + +void WMesaSwapBuffers( HDC hdc ) +{ + struct pipe_surface *surf; + struct wm_buffer *wm_buf; + WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc); + BITMAPINFO bmi, *pbmi; + + if (!pwfb) { + _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc"); + return; + } + + + /* If we're swapping the buffer associated with the current context + * we have to flush any pending rendering commands first. + */ + st_notify_swapbuffers(pwfb->stfb); + +#if 0 + BitBlt(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, + pwfb->dib_hDC, 0, 0, SRCCOPY); +#else + surf = st_get_framebuffer_surface(pwfb->stfb, ST_SURFACE_BACK_LEFT); + wm_buf = wm_buffer(surf->buffer); + + pbmi = &bmi; + memset(pbmi, 0, sizeof(BITMAPINFO)); + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = pwfb->stfb->Base.Width; + pbmi->bmiHeader.biHeight= -((long)pwfb->stfb->Base.Height); + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = pwfb->cColorBits; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = 0; + pbmi->bmiHeader.biClrImportant = 0; + + StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY); + + { + GLuint width = 0, height = 0; + + get_window_size(pwfb->hDC, &width, &height); + + st_resize_framebuffer(pwfb->stfb, width, height); + } +#endif +} + +/* This is hopefully a temporary hack to define some needed dispatch + * table entries. Hopefully, I'll find a better solution. The + * dispatch table generation scripts ought to be making these dummy + * stubs as well. */ +#if !defined(__MINGW32__) || !defined(GL_NO_STDCALL) +void gl_dispatch_stub_543(void){} +void gl_dispatch_stub_544(void){} +void gl_dispatch_stub_545(void){} +void gl_dispatch_stub_546(void){} +void gl_dispatch_stub_547(void){} +void gl_dispatch_stub_548(void){} +void gl_dispatch_stub_549(void){} +void gl_dispatch_stub_550(void){} +void gl_dispatch_stub_551(void){} +void gl_dispatch_stub_552(void){} +void gl_dispatch_stub_553(void){} +void gl_dispatch_stub_554(void){} +void gl_dispatch_stub_555(void){} +void gl_dispatch_stub_556(void){} +void gl_dispatch_stub_557(void){} +void gl_dispatch_stub_558(void){} +void gl_dispatch_stub_559(void){} +void gl_dispatch_stub_560(void){} +void gl_dispatch_stub_561(void){} +void gl_dispatch_stub_565(void){} +void gl_dispatch_stub_566(void){} +void gl_dispatch_stub_577(void){} +void gl_dispatch_stub_578(void){} +void gl_dispatch_stub_603(void){} +void gl_dispatch_stub_645(void){} +void gl_dispatch_stub_646(void){} +void gl_dispatch_stub_647(void){} +void gl_dispatch_stub_648(void){} +void gl_dispatch_stub_649(void){} +void gl_dispatch_stub_650(void){} +void gl_dispatch_stub_651(void){} +void gl_dispatch_stub_652(void){} +void gl_dispatch_stub_653(void){} +void gl_dispatch_stub_733(void){} +void gl_dispatch_stub_734(void){} +void gl_dispatch_stub_735(void){} +void gl_dispatch_stub_736(void){} +void gl_dispatch_stub_737(void){} +void gl_dispatch_stub_738(void){} +void gl_dispatch_stub_744(void){} +void gl_dispatch_stub_745(void){} +void gl_dispatch_stub_746(void){} +void gl_dispatch_stub_760(void){} +void gl_dispatch_stub_761(void){} +void gl_dispatch_stub_763(void){} +void gl_dispatch_stub_765(void){} +void gl_dispatch_stub_766(void){} +void gl_dispatch_stub_767(void){} +void gl_dispatch_stub_768(void){} + +void gl_dispatch_stub_562(void){} +void gl_dispatch_stub_563(void){} +void gl_dispatch_stub_564(void){} +void gl_dispatch_stub_567(void){} +void gl_dispatch_stub_568(void){} +void gl_dispatch_stub_569(void){} +void gl_dispatch_stub_580(void){} +void gl_dispatch_stub_581(void){} +void gl_dispatch_stub_606(void){} +void gl_dispatch_stub_654(void){} +void gl_dispatch_stub_655(void){} +void gl_dispatch_stub_656(void){} +void gl_dispatch_stub_739(void){} +void gl_dispatch_stub_740(void){} +void gl_dispatch_stub_741(void){} +void gl_dispatch_stub_748(void){} +void gl_dispatch_stub_749(void){} +void gl_dispatch_stub_769(void){} +void gl_dispatch_stub_770(void){} +void gl_dispatch_stub_771(void){} +void gl_dispatch_stub_772(void){} +void gl_dispatch_stub_773(void){} + +#endif diff --git a/src/gallium/winsys/gdi/wmesadef.h b/src/gallium/winsys/gdi/wmesadef.h new file mode 100644 index 0000000000..fb8ce30a08 --- /dev/null +++ b/src/gallium/winsys/gdi/wmesadef.h @@ -0,0 +1,40 @@ +#ifndef WMESADEF_H +#define WMESADEF_H +#ifdef __MINGW32__ +#include +#endif +#if 0 +#include "context.h" +#endif +#include "state_tracker/st_context.h" +#include "state_tracker/st_public.h" + + +/** + * The Windows Mesa rendering context, derived from GLcontext. + */ +struct wmesa_context { + struct st_context *st; + HDC hDC; + BYTE cColorBits; +}; + +/** + * Windows framebuffer, derived from gl_framebuffer + */ +struct wmesa_framebuffer +{ + struct st_framebuffer *stfb; + HDC hDC; + int pixelformat; + BYTE cColorBits; + HDC dib_hDC; + HBITMAP hbmDIB; + HBITMAP hOldBitmap; + PBYTE pbPixels; + struct wmesa_framebuffer *next; +}; + +typedef struct wmesa_framebuffer *WMesaFramebuffer; + +#endif /* WMESADEF_H */ -- cgit v1.2.3 From 5a67df6d7cc8c74bfb71a8f19b8f6fdfb525091b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 3 Jun 2008 00:04:19 +0900 Subject: scons: Integrate gdi winsys. Conditional build of the winsys based on the platform. --- src/gallium/winsys/SConscript | 9 ++- src/gallium/winsys/dri/SConscript | 101 ++++++++++++++++---------------- src/gallium/winsys/dri/intel/SConscript | 76 ++++++++++++------------ src/gallium/winsys/xlib/SConscript | 50 ++++++++-------- 4 files changed, 124 insertions(+), 112 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index e8a581adb2..bf1718e7a5 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -1,11 +1,16 @@ Import('*') -if 'intel' in env['winsys'] and dri: +if env['dri']: SConscript([ 'dri/SConscript', ]) -if 'xlib' in env['winsys'] and not dri: +if 'xlib' in env['winsys']: SConscript([ 'xlib/SConscript', ]) + +if 'gdi' in env['winsys']: + SConscript([ + 'gdi/SConscript', + ]) diff --git a/src/gallium/winsys/dri/SConscript b/src/gallium/winsys/dri/SConscript index 8c56ce917c..aef5210a32 100644 --- a/src/gallium/winsys/dri/SConscript +++ b/src/gallium/winsys/dri/SConscript @@ -1,51 +1,54 @@ Import('*') -drienv = env.Clone() - -drienv.Replace(CPPPATH = [ - '#src/mesa/drivers/dri/common', - '#include', - '#include/GL/internal', - '#src/gallium/include', - '#src/gallium/auxiliary', - '#src/gallium/drivers', - '#src/mesa', - '#src/mesa/main', - '#src/mesa/glapi', - '#src/mesa/math', - '#src/mesa/transform', - '#src/mesa/shader', - '#src/mesa/swrast', - '#src/mesa/swrast_setup', - '#src/egl/main', - '#src/egl/drivers/dri', -]) - -drienv.ParseConfig('pkg-config --cflags --libs libdrm') - -COMMON_GALLIUM_SOURCES = [ - '#src/mesa/drivers/dri/common/utils.c', - '#src/mesa/drivers/dri/common/vblank.c', - '#src/mesa/drivers/dri/common/dri_util.c', - '#src/mesa/drivers/dri/common/xmlconfig.c', -] - -COMMON_BM_SOURCES = [ - '#src/mesa/drivers/dri/common/dri_bufmgr.c', - '#src/mesa/drivers/dri/common/dri_drmpool.c', -] - -Export([ - 'drienv', - 'COMMON_GALLIUM_SOURCES', - 'COMMON_BM_SOURCES', -]) - -# TODO: Installation -#install: $(LIBNAME) -# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) -# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) - -SConscript([ - 'intel/SConscript', -]) +if env['dri']: + + drienv = env.Clone() + + drienv.Replace(CPPPATH = [ + '#src/mesa/drivers/dri/common', + '#include', + '#include/GL/internal', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', + ]) + + drienv.ParseConfig('pkg-config --cflags --libs libdrm') + + COMMON_GALLIUM_SOURCES = [ + '#src/mesa/drivers/dri/common/utils.c', + '#src/mesa/drivers/dri/common/vblank.c', + '#src/mesa/drivers/dri/common/dri_util.c', + '#src/mesa/drivers/dri/common/xmlconfig.c', + ] + + COMMON_BM_SOURCES = [ + '#src/mesa/drivers/dri/common/dri_bufmgr.c', + '#src/mesa/drivers/dri/common/dri_drmpool.c', + ] + + Export([ + 'drienv', + 'COMMON_GALLIUM_SOURCES', + 'COMMON_BM_SOURCES', + ]) + + # TODO: Installation + #install: $(LIBNAME) + # $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) + # $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + + if 'intel' in env['winsys']: + SConscript([ + 'intel/SConscript', + ]) diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index 0ad19d42a8..6a4f50afcc 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -1,39 +1,41 @@ Import('*') -env = drienv.Clone() - -env.Append(CPPPATH = [ - '../intel', - 'server' -]) - -#MINIGLX_SOURCES = server/intel_dri.c - -DRIVER_SOURCES = [ - 'intel_winsys_pipe.c', - 'intel_winsys_softpipe.c', - 'intel_winsys_i915.c', - 'intel_batchbuffer.c', - 'intel_swapbuffers.c', - 'intel_context.c', - 'intel_lock.c', - 'intel_screen.c', - 'intel_batchpool.c', -] - -sources = \ - COMMON_GALLIUM_SOURCES + \ - COMMON_BM_SOURCES + \ - DRIVER_SOURCES - -drivers = [ - softpipe, - i915simple -] - -# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -env.SharedLibrary( - target ='i915tex_dri.so', - source = sources, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], -) \ No newline at end of file +if 'mesa' in env['statetrackers']: + + env = drienv.Clone() + + env.Append(CPPPATH = [ + '../intel', + 'server' + ]) + + #MINIGLX_SOURCES = server/intel_dri.c + + DRIVER_SOURCES = [ + 'intel_winsys_pipe.c', + 'intel_winsys_softpipe.c', + 'intel_winsys_i915.c', + 'intel_batchbuffer.c', + 'intel_swapbuffers.c', + 'intel_context.c', + 'intel_lock.c', + 'intel_screen.c', + 'intel_batchpool.c', + ] + + sources = \ + COMMON_GALLIUM_SOURCES + \ + COMMON_BM_SOURCES + \ + DRIVER_SOURCES + + drivers = [ + softpipe, + i915simple + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='i915tex_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 218b89285f..5e98a36abc 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -3,30 +3,32 @@ Import('*') -env = env.Clone() +if env['platform'] == 'linux' and 'mesa' in env['statetrackers'] and not env['dri']: -env.Append(CPPPATH = [ - '#/src/mesa', - '#/src/mesa/main', -]) + env = env.Clone() -sources = [ - 'glxapi.c', - 'fakeglx.c', - 'xfonts.c', - 'xm_api.c', - 'xm_winsys.c', - 'xm_winsys_aub.c', - 'brw_aub.c', -] - -drivers = [ - softpipe, -] + env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', + ]) -# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -env.SharedLibrary( - target ='GL', - source = sources, - LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], -) + sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'xm_winsys.c', + 'xm_winsys_aub.c', + 'brw_aub.c', + ] + + drivers = [ + softpipe, + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + ) -- cgit v1.2.3 From 4ee14279f3a466093869f1f40819e6c6d5af378d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 2 Jun 2008 14:55:06 +0200 Subject: i915: Rework of batchbuffer code --- src/gallium/drivers/i915simple/i915_batch.h | 92 +++++++++++++++++++++++++-- src/gallium/drivers/i915simple/i915_context.c | 3 +- src/gallium/drivers/i915simple/i915_context.h | 4 +- src/gallium/drivers/i915simple/i915_debug.c | 2 +- 4 files changed, 94 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h index 4ea06ce02b..6c62e84bc3 100644 --- a/src/gallium/drivers/i915simple/i915_batch.h +++ b/src/gallium/drivers/i915simple/i915_batch.h @@ -31,23 +31,107 @@ #include "i915_winsys.h" #include "i915_debug.h" +struct i915_batchbuffer +{ + struct pipe_buffer *buffer; + struct i915_winsys *winsys; + + unsigned char *map; + unsigned char *ptr; + + size_t size; + + size_t relocs; + size_t max_relocs; +}; + +static INLINE boolean +i915_batchbuffer_check( struct i915_batchbuffer *batch, + size_t dwords, + size_t relocs ) +{ +#if 0 /* To be used */ + /** TODO JB: Check relocs */ + return dwords * 4 <= batch->size - (batch->ptr - batch->map); +#else + if (batch->winsys->batch_start( batch->winsys, dwords, relocs )) + return 1; + return 0; +#endif +} + +static INLINE size_t +i915_batchbuffer_space( struct i915_batchbuffer *batch ) +{ +#if 0 /* To be used */ + return batch->size - (batch->ptr - batch->map); +#else + return 0; +#endif +} + +static INLINE void +i915_batchbuffer_dword( struct i915_batchbuffer *batch, + unsigned dword ) +{ +#if 0 /* To be used */ + if (i915_batchbuffer_space(batch) < 4) + return; + + *(unsigned *)batch->ptr = dword; + batch->ptr += 4; +#else + batch->winsys->batch_dword( batch->winsys, dword ); +#endif +} + +static INLINE void +i915_batchbuffer_write( struct i915_batchbuffer *batch, + void *data, + size_t size ) +{ +#if 0 /* To be used */ + if (i915_batchbuffer_space(batch) < size) + return; + + memcpy(data, batch->ptr, size); + batch->ptr += size; +#else +#endif +} + +static INLINE void +i915_batchbuffer_reloc( struct i915_batchbuffer *batch, + struct pipe_buffer *buffer, + size_t flags, + size_t offset ) +{ + batch->winsys->batch_reloc( batch->winsys, buffer, flags, offset ); +} + +static INLINE void +i915_batchbuffer_flush( struct i915_batchbuffer *batch, + struct pipe_fence_handle **fence ) +{ + batch->winsys->batch_flush( batch->winsys, fence ); +} + #define BATCH_LOCALS #define BEGIN_BATCH( dwords, relocs ) \ - (i915->batch_start = i915->winsys->batch_start( i915->winsys, dwords, relocs )) + (i915_batchbuffer_check( i915->batch, dwords, relocs )) #define OUT_BATCH( dword ) \ - i915->winsys->batch_dword( i915->winsys, dword ) + i915_batchbuffer_dword( i915->batch, dword ) #define OUT_RELOC( buf, flags, delta ) \ - i915->winsys->batch_reloc( i915->winsys, buf, flags, delta ) + i915_batchbuffer_reloc( i915->batch, buf, flags, delta ) #define ADVANCE_BATCH() #define FLUSH_BATCH(fence) do { \ if (0) i915_dump_batchbuffer( i915 ); \ i915->winsys->batch_flush( i915->winsys, fence ); \ - i915->batch_start = NULL; \ i915->hardware_dirty = ~0; \ } while (0) diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 81cab75738..378e4a5d4d 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -181,7 +181,8 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen, /* Batch stream debugging is a bit hacked up at the moment: */ - i915->batch_start = NULL; + i915->batch = CALLOC_STRUCT(i915_batchbuffer); + i915->batch->winsys = i915_winsys; return &i915->pipe; } diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 2da90ae49d..2ee0381648 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -209,6 +209,8 @@ struct i915_texture { struct pipe_buffer *buffer; }; +struct i915_batchbuffer; + struct i915_context { struct pipe_context pipe; @@ -241,7 +243,7 @@ struct i915_context unsigned num_vertex_elements; unsigned num_vertex_buffers; - unsigned *batch_start; + struct i915_batchbuffer *batch; /** Vertex buffer */ struct pipe_buffer *vbo; diff --git a/src/gallium/drivers/i915simple/i915_debug.c b/src/gallium/drivers/i915simple/i915_debug.c index 9b9111167f..a121dc0af4 100644 --- a/src/gallium/drivers/i915simple/i915_debug.c +++ b/src/gallium/drivers/i915simple/i915_debug.c @@ -861,7 +861,7 @@ void i915_dump_batchbuffer( struct i915_context *i915 ) { struct debug_stream stream; - unsigned *start = i915->batch_start; + unsigned *start = 0;/*i915->batch_start;*/ unsigned *end = i915->winsys->batch_start( i915->winsys, 0, 0 ); unsigned long bytes = (unsigned long) (end - start) * 4; boolean done = FALSE; -- cgit v1.2.3 From 7cc23a9eaebc788ae34f6e06c6227524d08a7693 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 2 Jun 2008 17:22:45 +0200 Subject: i915: Implement and use the reworked batchbuffer code --- src/gallium/drivers/i915simple/i915_batch.h | 20 ++--------- src/gallium/drivers/i915simple/i915_context.c | 2 +- src/gallium/drivers/i915simple/i915_debug.c | 3 +- src/gallium/drivers/i915simple/i915_winsys.h | 22 +++++------- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 46 ++++++++++++------------ src/gallium/winsys/dri/intel/intel_batchbuffer.h | 19 +++++----- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 35 +++--------------- 7 files changed, 52 insertions(+), 95 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h index 6c62e84bc3..9379d1fb5d 100644 --- a/src/gallium/drivers/i915simple/i915_batch.h +++ b/src/gallium/drivers/i915simple/i915_batch.h @@ -40,6 +40,7 @@ struct i915_batchbuffer unsigned char *ptr; size_t size; + size_t actual_size; size_t relocs; size_t max_relocs; @@ -50,39 +51,25 @@ i915_batchbuffer_check( struct i915_batchbuffer *batch, size_t dwords, size_t relocs ) { -#if 0 /* To be used */ /** TODO JB: Check relocs */ return dwords * 4 <= batch->size - (batch->ptr - batch->map); -#else - if (batch->winsys->batch_start( batch->winsys, dwords, relocs )) - return 1; - return 0; -#endif } static INLINE size_t i915_batchbuffer_space( struct i915_batchbuffer *batch ) { -#if 0 /* To be used */ return batch->size - (batch->ptr - batch->map); -#else - return 0; -#endif } static INLINE void i915_batchbuffer_dword( struct i915_batchbuffer *batch, unsigned dword ) { -#if 0 /* To be used */ if (i915_batchbuffer_space(batch) < 4) return; *(unsigned *)batch->ptr = dword; batch->ptr += 4; -#else - batch->winsys->batch_dword( batch->winsys, dword ); -#endif } static INLINE void @@ -90,14 +77,11 @@ i915_batchbuffer_write( struct i915_batchbuffer *batch, void *data, size_t size ) { -#if 0 /* To be used */ if (i915_batchbuffer_space(batch) < size) return; memcpy(data, batch->ptr, size); batch->ptr += size; -#else -#endif } static INLINE void @@ -135,4 +119,4 @@ i915_batchbuffer_flush( struct i915_batchbuffer *batch, i915->hardware_dirty = ~0; \ } while (0) -#endif +#endif diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 378e4a5d4d..243b4a6852 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -181,7 +181,7 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen, /* Batch stream debugging is a bit hacked up at the moment: */ - i915->batch = CALLOC_STRUCT(i915_batchbuffer); + i915->batch = i915_winsys->batch_get(i915_winsys); i915->batch->winsys = i915_winsys; return &i915->pipe; diff --git a/src/gallium/drivers/i915simple/i915_debug.c b/src/gallium/drivers/i915simple/i915_debug.c index a121dc0af4..5e26d1b905 100644 --- a/src/gallium/drivers/i915simple/i915_debug.c +++ b/src/gallium/drivers/i915simple/i915_debug.c @@ -861,8 +861,9 @@ void i915_dump_batchbuffer( struct i915_context *i915 ) { struct debug_stream stream; + /* TODO fix me */ unsigned *start = 0;/*i915->batch_start;*/ - unsigned *end = i915->winsys->batch_start( i915->winsys, 0, 0 ); + unsigned *end = 0;/*i915->winsys->batch_start( i915->winsys, 0, 0 );*/ unsigned long bytes = (unsigned long) (end - start) * 4; boolean done = FALSE; diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h index 5e16543f4e..9afaa16a62 100644 --- a/src/gallium/drivers/i915simple/i915_winsys.h +++ b/src/gallium/drivers/i915simple/i915_winsys.h @@ -55,6 +55,7 @@ extern "C" { * etc. */ +struct i915_batchbuffer; struct pipe_buffer; struct pipe_fence_handle; struct pipe_winsys; @@ -75,20 +76,10 @@ struct pipe_screen; struct i915_winsys { /** - * Reserve space on batch buffer. - * - * Returns a null pointer if there is insufficient space in the batch buffer - * to hold the requested number of dwords and relocations. - * - * The number of dwords should also include the number of relocations. + * Get the current batch buffer from the winsys. */ - unsigned *(*batch_start)( struct i915_winsys *sws, - unsigned dwords, - unsigned relocs ); - - void (*batch_dword)( struct i915_winsys *sws, - unsigned dword ); - + struct i915_batchbuffer *(*batch_get)( struct i915_winsys *sws ); + /** * Emit a relocation to a buffer. * @@ -103,7 +94,10 @@ struct i915_winsys { struct pipe_buffer *buf, unsigned access_flags, unsigned delta ); - + + /** + * Flush the batch. + */ void (*batch_flush)( struct i915_winsys *sws, struct pipe_fence_handle **fence ); }; diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c index 09d4eef484..aa33c12045 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c @@ -65,8 +65,10 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch) driBOUnrefUserList(batch->list); driBOResetList(batch->list); - batch->size = batch->intel->intelScreen->max_batch_size; - driBOData(batch->buffer, batch->size, NULL, NULL, 0); + /* base.size is the size available to the i915simple driver */ + batch->base.size = batch->intel->intelScreen->max_batch_size - BATCH_RESERVED; + batch->base.actual_size = batch->intel->intelScreen->max_batch_size; + driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0); /* * Add the batchbuffer to the validate list. @@ -105,9 +107,9 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch) batch->reloc[2] = 0; /* Only a single relocation list. */ batch->reloc[3] = 0; /* Only a single relocation list. */ - batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); batch->poolOffset = driBOPoolOffset(batch->buffer); - batch->ptr = batch->map; + batch->base.ptr = batch->base.map; batch->dirty_state = ~0; batch->nr_relocs = 0; batch->flags = 0; @@ -142,9 +144,9 @@ intel_batchbuffer_free(struct intel_batchbuffer *batch) DRM_FENCE_TYPE_EXE, GL_FALSE); driFenceUnReference(&batch->last_fence); } - if (batch->map) { + if (batch->base.map) { driBOUnmap(batch->buffer); - batch->map = NULL; + batch->base.map = NULL; } driBOUnReference(batch->buffer); driBOFreeList(batch->list); @@ -191,7 +193,7 @@ intel_offset_relocation(struct intel_batchbuffer *batch, reloc = batch->reloc + (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); - reloc[0] = ((uint8_t *)batch->ptr - batch->drmBOVirtual); + reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual); intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add); reloc[1] = pre_add; reloc[2] = itemLoc; @@ -382,7 +384,7 @@ struct _DriFenceObject * intel_batchbuffer_flush(struct intel_batchbuffer *batch) { struct intel_context *intel = batch->intel; - GLuint used = batch->ptr - batch->map; + GLuint used = batch->base.ptr - batch->base.map; GLboolean was_locked = intel->locked; struct _DriFenceObject *fence; @@ -396,32 +398,32 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) */ #if 0 /* ZZZ JB: what should we do here? */ if (used & 4) { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END; used += 12; } else { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END; used += 8; } #else if (used & 4) { - ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; used += 12; } else { - ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; used += 8; } #endif driBOUnmap(batch->buffer); - batch->ptr = NULL; - batch->map = NULL; + batch->base.ptr = NULL; + batch->base.map = NULL; /* TODO: Just pass the relocation list and dma buffer up to the * kernel. @@ -455,6 +457,6 @@ intel_batchbuffer_data(struct intel_batchbuffer *batch, { assert((bytes & 3) == 0); intel_batchbuffer_require_space(batch, bytes, flags); - memcpy(batch->ptr, data, bytes); - batch->ptr += bytes; + memcpy(batch->base.ptr, data, bytes); + batch->base.ptr += bytes; } diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h index 9e4b8043bf..dcb2121ddf 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -3,6 +3,7 @@ #include "mtypes.h" #include "ws_dri_bufmgr.h" +#include "i915simple/i915_batch.h" struct intel_context; @@ -17,7 +18,8 @@ struct intel_context; struct intel_batchbuffer { - struct bufmgr *bm; + struct i915_batchbuffer base; + struct intel_context *intel; struct _DriBufferObject *buffer; @@ -26,15 +28,11 @@ struct intel_batchbuffer struct _DriBufferList *list; GLuint list_count; - GLubyte *map; - GLubyte *ptr; uint32_t *reloc; GLuint reloc_size; GLuint nr_relocs; - GLuint size; - GLuint dirty_state; GLuint id; @@ -83,7 +81,7 @@ intel_offset_relocation(struct intel_batchbuffer *batch, static INLINE GLuint intel_batchbuffer_space(struct intel_batchbuffer *batch) { - return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); + return (batch->base.size - BATCH_RESERVED) - (batch->base.ptr - batch->base.map); } @@ -92,8 +90,8 @@ intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) { assert(batch->map); assert(intel_batchbuffer_space(batch) >= 4); - *(GLuint *) (batch->ptr) = dword; - batch->ptr += 4; + *(GLuint *) (batch->base.ptr) = dword; + batch->base.ptr += 4; } static INLINE void @@ -114,20 +112,25 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch, /* Here are the crusty old macros, to be removed: */ +#undef BATCH_LOCALS #define BATCH_LOCALS +#undef BEGIN_BATCH #define BEGIN_BATCH(n, flags) do { \ assert(!intel->prim.flush); \ intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ } while (0) +#undef OUT_BATCH #define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) +#undef OUT_RELOC #define OUT_RELOC(buf,flags,mask,delta) do { \ assert((delta) >= 0); \ intel_offset_relocation(intel->batch, delta, buf, flags, mask); \ } while (0) +#undef ADVANCE_BATCH #define ADVANCE_BATCH() do { } while(0) diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c index a35825d36a..013291364a 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c @@ -63,28 +63,11 @@ intel_i915_winsys( struct i915_winsys *sws ) /* Simple batchbuffer interface: */ -static unsigned *intel_i915_batch_start( struct i915_winsys *sws, - unsigned dwords, - unsigned relocs ) +static struct i915_batchbuffer* +intel_i915_batch_get( struct i915_winsys *sws ) { struct intel_context *intel = intel_i915_winsys(sws)->intel; - - /* XXX: check relocs. - */ - if (intel_batchbuffer_space( intel->batch ) >= dwords * 4) { - /* XXX: Hmm, the driver can't really do much with this pointer: - */ - return (unsigned *)intel->batch->ptr; - } - else - return NULL; -} - -static void intel_i915_batch_dword( struct i915_winsys *sws, - unsigned dword ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - intel_batchbuffer_emit_dword( intel->batch, dword ); + return &intel->batch->base; } static void intel_i915_batch_reloc( struct i915_winsys *sws, @@ -106,22 +89,13 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws, mask |= DRM_BO_FLAG_READ; } -#if 0 /* JB old */ - intel_batchbuffer_emit_reloc( intel->batch, - dri_bo( buf ), - flags, mask, - delta ); -#else /* new */ intel_offset_relocation( intel->batch, delta, dri_bo( buf ), flags, mask ); -#endif } - - static void intel_i915_batch_flush( struct i915_winsys *sws, struct pipe_fence_handle **fence ) { @@ -166,8 +140,7 @@ intel_create_i915simple( struct intel_context *intel, /* Fill in this struct with callbacks that i915simple will need to * communicate with the window system, buffer manager, etc. */ - iws->winsys.batch_start = intel_i915_batch_start; - iws->winsys.batch_dword = intel_i915_batch_dword; + iws->winsys.batch_get = intel_i915_batch_get; iws->winsys.batch_reloc = intel_i915_batch_reloc; iws->winsys.batch_flush = intel_i915_batch_flush; iws->pws = winsys; -- cgit v1.2.3 From 6a3aab1983d999a3a9eccbeaab88195820abf467 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 2 Jun 2008 17:23:30 +0200 Subject: i915: Removed useless defines --- src/gallium/drivers/i915simple/i915_batch.h | 4 ---- src/gallium/drivers/i915simple/i915_blit.c | 4 ---- src/gallium/drivers/i915simple/i915_flush.c | 1 - 3 files changed, 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h index 9379d1fb5d..987d0b4d28 100644 --- a/src/gallium/drivers/i915simple/i915_batch.h +++ b/src/gallium/drivers/i915simple/i915_batch.h @@ -100,8 +100,6 @@ i915_batchbuffer_flush( struct i915_batchbuffer *batch, batch->winsys->batch_flush( batch->winsys, fence ); } -#define BATCH_LOCALS - #define BEGIN_BATCH( dwords, relocs ) \ (i915_batchbuffer_check( i915->batch, dwords, relocs )) @@ -111,8 +109,6 @@ i915_batchbuffer_flush( struct i915_batchbuffer *batch, #define OUT_RELOC( buf, flags, delta ) \ i915_batchbuffer_reloc( i915->batch, buf, flags, delta ) -#define ADVANCE_BATCH() - #define FLUSH_BATCH(fence) do { \ if (0) i915_dump_batchbuffer( i915 ); \ i915->winsys->batch_flush( i915->winsys, fence ); \ diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c index 24449e3fb3..b500ff36a8 100644 --- a/src/gallium/drivers/i915simple/i915_blit.c +++ b/src/gallium/drivers/i915simple/i915_blit.c @@ -45,7 +45,6 @@ i915_fill_blit(struct i915_context *i915, unsigned color) { unsigned BR13, CMD; - BATCH_LOCALS; dst_pitch *= (short) cpp; @@ -79,7 +78,6 @@ i915_fill_blit(struct i915_context *i915, OUT_BATCH(((y + h) << 16) | (x + w)); OUT_RELOC( dst_buffer, I915_BUFFER_ACCESS_WRITE, dst_offset); OUT_BATCH(color); - ADVANCE_BATCH(); } @@ -100,7 +98,6 @@ i915_copy_blit( struct i915_context *i915, unsigned CMD, BR13; int dst_y2 = dst_y + h; int dst_x2 = dst_x + w; - BATCH_LOCALS; I915_DBG(i915, @@ -156,7 +153,6 @@ i915_copy_blit( struct i915_context *i915, OUT_BATCH((src_y << 16) | src_x); OUT_BATCH(((int) src_pitch & 0xffff)); OUT_RELOC(src_buffer, I915_BUFFER_ACCESS_READ, src_offset); - ADVANCE_BATCH(); } diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c index 4c4718d68e..472e0ab774 100644 --- a/src/gallium/drivers/i915simple/i915_flush.c +++ b/src/gallium/drivers/i915simple/i915_flush.c @@ -62,7 +62,6 @@ static void i915_flush( struct pipe_context *pipe, assert(BEGIN_BATCH(1, 0)); } OUT_BATCH( flush ); - ADVANCE_BATCH(); } /* If there are no flags, just flush pending commands to hardware: -- cgit v1.2.3 From 58cccc8d6b49c75eeabe9b61055e69de824ff757 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 2 Jun 2008 21:51:31 +0200 Subject: draw: Fix DP3 implementation by replacing SSE with x87 version. --- src/gallium/auxiliary/draw/draw_vs_aos.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 725f36b502..5bfcd96ac3 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -962,8 +962,35 @@ static boolean emit_COS( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } +#if 1 + +/* The x87 version. + */ +static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + struct x86_reg st1 = x86_make_reg( file_x87, 1 ); + + x87_fld_src( cp, &op->FullSrcRegisters[0], 0 ); + x87_fld_src( cp, &op->FullSrcRegisters[1], 0 ); + x87_fmulp( cp->func, st1 ); + x87_fld_src( cp, &op->FullSrcRegisters[0], 1 ); + x87_fld_src( cp, &op->FullSrcRegisters[1], 1 ); + x87_fmulp( cp->func, st1 ); + x87_faddp( cp->func, st1 ); + x87_fld_src( cp, &op->FullSrcRegisters[0], 2 ); + x87_fld_src( cp, &op->FullSrcRegisters[1], 2 ); + x87_fmulp( cp->func, st1 ); + x87_faddp( cp->func, st1 ); + + x87_fstp_dest4( cp, &op->FullDstRegisters[0] ); + + return TRUE; +} + +#else /* The dotproduct instructions don't really do that well in sse: + * XXX: produces wrong results -- disabled. */ static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { @@ -985,7 +1012,7 @@ static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } - +#endif static boolean emit_DP4( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { -- cgit v1.2.3 From 183d490ab139483c88d0b0f541714919de86235c Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 3 Jun 2008 10:59:46 +0200 Subject: draw: Fix fetch_src(). Resurrect SSE version of DP3. --- src/gallium/auxiliary/draw/draw_vs_aos.c | 43 +++++--------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 5bfcd96ac3..891f8c211a 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -532,10 +532,11 @@ static struct x86_reg fetch_src( struct aos_compilation *cp, if (swz != SSE_SWIZZLE_NOOP || negs != 0 || abs != 0) { struct x86_reg dst = aos_get_xmm_reg(cp); - if (swz != SSE_SWIZZLE_NOOP) { + if (swz != SSE_SWIZZLE_NOOP) emit_pshufd(cp, dst, arg0, swz); - arg0 = dst; - } + else + sse_movaps(cp->func, dst, arg0); + arg0 = dst; if (negs && negs != 0xf) { struct x86_reg imm_swz = aos_get_internal_xmm(cp, IMM_SWZ); @@ -550,15 +551,13 @@ static struct x86_reg fetch_src( struct aos_compilation *cp, (negs & 2) ? 1 : 0, (negs & 4) ? 1 : 0, (negs & 8) ? 1 : 0)); - sse_mulps(cp->func, dst, arg0); + sse_mulps(cp->func, dst, tmp); aos_release_xmm_reg(cp, tmp.idx); - arg0 = dst; } else if (negs) { struct x86_reg imm_negs = aos_get_internal_xmm(cp, IMM_NEGS); sse_mulps(cp->func, dst, imm_negs); - arg0 = dst; } @@ -571,10 +570,9 @@ static struct x86_reg fetch_src( struct aos_compilation *cp, sse_movaps(cp->func, tmp, arg0); sse_mulps(cp->func, tmp, neg); - sse_maxps(cp->func, dst, arg0); + sse_maxps(cp->func, dst, tmp); aos_release_xmm_reg(cp, tmp.idx); - arg0 = dst; } } @@ -962,33 +960,6 @@ static boolean emit_COS( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } -#if 1 - -/* The x87 version. - */ -static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) -{ - struct x86_reg st1 = x86_make_reg( file_x87, 1 ); - - x87_fld_src( cp, &op->FullSrcRegisters[0], 0 ); - x87_fld_src( cp, &op->FullSrcRegisters[1], 0 ); - x87_fmulp( cp->func, st1 ); - x87_fld_src( cp, &op->FullSrcRegisters[0], 1 ); - x87_fld_src( cp, &op->FullSrcRegisters[1], 1 ); - x87_fmulp( cp->func, st1 ); - x87_faddp( cp->func, st1 ); - x87_fld_src( cp, &op->FullSrcRegisters[0], 2 ); - x87_fld_src( cp, &op->FullSrcRegisters[1], 2 ); - x87_fmulp( cp->func, st1 ); - x87_faddp( cp->func, st1 ); - - x87_fstp_dest4( cp, &op->FullDstRegisters[0] ); - - return TRUE; -} - -#else - /* The dotproduct instructions don't really do that well in sse: * XXX: produces wrong results -- disabled. */ @@ -1012,8 +983,6 @@ static boolean emit_DP3( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } -#endif - static boolean emit_DP4( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); -- cgit v1.2.3 From 0a5df5bc7d711a766c9d0963fb2029d60cf70a8b Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 3 Jun 2008 11:22:00 +0200 Subject: draw: Use register names more consistently. --- src/gallium/auxiliary/draw/draw_vs_aos.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 891f8c211a..3cf4a4d125 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -536,7 +536,6 @@ static struct x86_reg fetch_src( struct aos_compilation *cp, emit_pshufd(cp, dst, arg0, swz); else sse_movaps(cp->func, dst, arg0); - arg0 = dst; if (negs && negs != 0xf) { struct x86_reg imm_swz = aos_get_internal_xmm(cp, IMM_SWZ); @@ -568,12 +567,14 @@ static struct x86_reg fetch_src( struct aos_compilation *cp, struct x86_reg neg = aos_get_internal(cp, IMM_NEGS); struct x86_reg tmp = aos_get_xmm_reg(cp); - sse_movaps(cp->func, tmp, arg0); + sse_movaps(cp->func, tmp, dst); sse_mulps(cp->func, tmp, neg); sse_maxps(cp->func, dst, tmp); aos_release_xmm_reg(cp, tmp.idx); } + + return dst; } return arg0; -- cgit v1.2.3 From afd635a95056abc0909ebd1503131660d6e78cf6 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 3 Jun 2008 12:35:01 +0200 Subject: i915: Fix compile on linux-dri-debug --- src/gallium/drivers/i915simple/i915_batch.h | 2 -- src/gallium/drivers/i915simple/i915_blit.c | 1 + src/gallium/winsys/dri/intel/intel_batchbuffer.h | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h index 987d0b4d28..45bf4f4028 100644 --- a/src/gallium/drivers/i915simple/i915_batch.h +++ b/src/gallium/drivers/i915simple/i915_batch.h @@ -29,7 +29,6 @@ #define I915_BATCH_H #include "i915_winsys.h" -#include "i915_debug.h" struct i915_batchbuffer { @@ -110,7 +109,6 @@ i915_batchbuffer_flush( struct i915_batchbuffer *batch, i915_batchbuffer_reloc( i915->batch, buf, flags, delta ) #define FLUSH_BATCH(fence) do { \ - if (0) i915_dump_batchbuffer( i915 ); \ i915->winsys->batch_flush( i915->winsys, fence ); \ i915->hardware_dirty = ~0; \ } while (0) diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c index b500ff36a8..22f91fab92 100644 --- a/src/gallium/drivers/i915simple/i915_blit.c +++ b/src/gallium/drivers/i915simple/i915_blit.c @@ -31,6 +31,7 @@ #include "i915_blit.h" #include "i915_reg.h" #include "i915_batch.h" +#include "i915_debug.h" #define FILE_DEBUG_FLAG DEBUG_BLIT diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h index dcb2121ddf..abb7a624f5 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -88,7 +88,7 @@ intel_batchbuffer_space(struct intel_batchbuffer *batch) static INLINE void intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) { - assert(batch->map); + assert(batch->base.map); assert(intel_batchbuffer_space(batch) >= 4); *(GLuint *) (batch->base.ptr) = dword; batch->base.ptr += 4; @@ -100,7 +100,7 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch, { struct _DriFenceObject *fence; - assert(sz < batch->size - 8); + assert(sz < batch->base.size - 8); if (intel_batchbuffer_space(batch) < sz || (batch->flags != 0 && flags != 0 && batch->flags != flags)) { fence = intel_batchbuffer_flush(batch); -- cgit v1.2.3 From 0a4aea0e86a897d9afb9f2a0ec27f03faf8f1b21 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 2 Jun 2008 12:59:16 +0100 Subject: draw: respect driver's max vertex buffer size --- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 6 ++++++ src/gallium/auxiliary/draw/draw_private.h | 1 + src/gallium/auxiliary/draw/draw_pt.h | 8 ++++++-- src/gallium/auxiliary/draw/draw_pt_emit.c | 6 +++++- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 6 +++++- src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c | 17 ++++++++++------- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 16 ++++++++++++---- src/gallium/auxiliary/draw/draw_pt_varray.c | 5 ++++- src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h | 11 +++++++---- src/gallium/auxiliary/draw/draw_pt_vcache.c | 13 ++++++++----- 10 files changed, 64 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index d514e28b77..9e5597c32c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -387,6 +387,12 @@ vbuf_alloc_vertices( struct vbuf_stage *vbuf ) /* Allocate a new vertex buffer */ vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; + + /* Must always succeed -- driver gives us a + * 'max_vertex_buffer_bytes' which it guarantees it can allocate, + * and it will flush itself if necessary to do so. If this does + * fail, we are basically without usable hardware. + */ vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, (ushort) vbuf->vertex_size, (ushort) vbuf->max_vertices); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 423f64262b..1865601cc0 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -265,6 +265,7 @@ void draw_pipeline_destroy( struct draw_context *draw ); * These flags expected at first vertex of lines & triangles when * unfilled and/or line stipple modes are operational. */ +#define DRAW_PIPE_MAX_VERTICES (0x1<<12) #define DRAW_PIPE_EDGE_FLAG_0 (0x1<<12) #define DRAW_PIPE_EDGE_FLAG_1 (0x2<<12) #define DRAW_PIPE_EDGE_FLAG_2 (0x4<<12) diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 6b8ba1d171..3d2a9c78b7 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -84,7 +84,8 @@ struct draw_pt_front_end { struct draw_pt_middle_end { void (*prepare)( struct draw_pt_middle_end *, unsigned prim, - unsigned opt ); + unsigned opt, + unsigned *max_vertices ); void (*run)( struct draw_pt_middle_end *, const unsigned *fetch_elts, @@ -105,6 +106,8 @@ struct draw_pt_middle_end { const ushort *draw_elts, unsigned draw_count ); + int (*get_max_vertex_count)( struct draw_pt_middle_end * ); + void (*finish)( struct draw_pt_middle_end * ); void (*destroy)( struct draw_pt_middle_end * ); }; @@ -158,7 +161,8 @@ boolean draw_pt_get_edgeflag( struct draw_context *draw, struct pt_emit; void draw_pt_emit_prepare( struct pt_emit *emit, - unsigned prim ); + unsigned prim, + unsigned *max_vertices ); void draw_pt_emit( struct pt_emit *emit, const float (*vertex_data)[4], diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index cf87cde996..a02f1f46fe 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -46,7 +46,8 @@ struct pt_emit { }; void draw_pt_emit_prepare( struct pt_emit *emit, - unsigned prim ) + unsigned prim, + unsigned *max_vertices ) { struct draw_context *draw = emit->draw; const struct vertex_info *vinfo; @@ -139,6 +140,9 @@ void draw_pt_emit_prepare( struct pt_emit *emit, translate_key_sanitize(&hw_key); emit->translate = translate_cache_find(emit->cache, &hw_key); } + + *max_vertices = (draw->render->max_vertex_buffer_bytes / + (vinfo->size * 4)); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 09bdc5fb5e..083ce105bf 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -90,7 +90,8 @@ struct fetch_emit_middle_end { static void fetch_emit_prepare( struct draw_pt_middle_end *middle, unsigned prim, - unsigned opt ) + unsigned opt, + unsigned *max_vertices ) { struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; @@ -196,6 +197,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, draw->pt.vertex_buffer[i].buffer_offset), draw->pt.vertex_buffer[i].pitch ); } + + *max_vertices = (draw->render->max_vertex_buffer_bytes / + (vinfo->size * 4)); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index efa6dddbda..5a1d79d996 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -70,7 +70,8 @@ struct fetch_shade_emit { static void fse_prepare( struct draw_pt_middle_end *middle, unsigned prim, - unsigned opt ) + unsigned opt, + unsigned *max_vertices ) { struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; struct draw_context *draw = fse->draw; @@ -189,6 +190,11 @@ static void fse_prepare( struct draw_pt_middle_end *middle, draw->pt.vertex_buffer[buf].pitch ); } + *max_vertices = (draw->render->max_vertex_buffer_bytes / + (vinfo->size * 4)); + + + //return TRUE; } @@ -204,7 +210,6 @@ static void fse_run_linear( struct draw_pt_middle_end *middle, { struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; struct draw_context *draw = fse->draw; - unsigned alloc_count = align(count, 4); char *hw_verts; /* XXX: need to flush to get prim_vbuf.c to release its allocation?? @@ -213,7 +218,7 @@ static void fse_run_linear( struct draw_pt_middle_end *middle, hw_verts = draw->render->allocate_vertices( draw->render, (ushort)fse->key.output_stride, - (ushort)alloc_count ); + (ushort)count ); if (!hw_verts) { assert(0); @@ -264,7 +269,6 @@ fse_run(struct draw_pt_middle_end *middle, { struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; struct draw_context *draw = fse->draw; - unsigned alloc_count = align(fetch_count, 4); void *hw_verts; /* XXX: need to flush to get prim_vbuf.c to release its allocation?? @@ -273,7 +277,7 @@ fse_run(struct draw_pt_middle_end *middle, hw_verts = draw->render->allocate_vertices( draw->render, (ushort)fse->key.output_stride, - (ushort)alloc_count ); + (ushort)fetch_count ); if (!hw_verts) { assert(0); return; @@ -319,7 +323,6 @@ static void fse_run_linear_elts( struct draw_pt_middle_end *middle, { struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; struct draw_context *draw = fse->draw; - unsigned alloc_count = align(count, 4); char *hw_verts; /* XXX: need to flush to get prim_vbuf.c to release its allocation?? @@ -328,7 +331,7 @@ static void fse_run_linear_elts( struct draw_pt_middle_end *middle, hw_verts = draw->render->allocate_vertices( draw->render, (ushort)fse->key.output_stride, - (ushort)alloc_count ); + (ushort)count ); if (!hw_verts) { assert(0); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index eb6988ff03..25118712a6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -51,7 +51,8 @@ struct fetch_pipeline_middle_end { static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned prim, - unsigned opt ) + unsigned opt, + unsigned *max_vertices ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; @@ -86,14 +87,21 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, (boolean)draw->rasterizer->gl_rasterization_rules ); - if (!(opt & PT_PIPELINE)) + if (!(opt & PT_PIPELINE)) { draw_pt_emit_prepare( fpme->emit, - prim ); + prim, + max_vertices ); + + *max_vertices = MAX2( *max_vertices, + DRAW_PIPE_MAX_VERTICES ); + } + else { + *max_vertices = DRAW_PIPE_MAX_VERTICES; + } /* No need to prepare the shader. */ vs->prepare(vs, draw); - } diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index f19e8850b3..f5495a80c7 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -45,6 +45,9 @@ struct varray_frontend { unsigned fetch_start; + unsigned driver_fetch_max; + unsigned fetch_max; + struct draw_pt_middle_end *middle; unsigned input_prim; @@ -183,7 +186,7 @@ static void varray_prepare(struct draw_pt_front_end *frontend, varray->output_prim = decompose_prim[prim]; varray->middle = middle; - middle->prepare(middle, varray->output_prim, opt); + middle->prepare(middle, varray->output_prim, opt, &varray->fetch_max ); } diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h index 114ed371a0..6e5e30f38e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h @@ -40,7 +40,7 @@ static void FUNC(struct draw_pt_front_end *frontend, case PIPE_PRIM_QUAD_STRIP: for (j = 0; j < count;) { unsigned remaining = count - j; - unsigned nr = trim( MIN2(FETCH_MAX, remaining), first, incr ); + unsigned nr = trim( MIN2(varray->fetch_max, remaining), first, incr ); varray_flush_linear(varray, start + j, nr); j += nr; if (nr != remaining) @@ -50,8 +50,9 @@ static void FUNC(struct draw_pt_front_end *frontend, case PIPE_PRIM_LINE_LOOP: if (count >= 2) { + unsigned fetch_max = MIN2(FETCH_MAX, varray->fetch_max); for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(FETCH_MAX, count - j); + unsigned end = MIN2(fetch_max, count - j); end -= (end % incr); for (i = 1; i < end; i++) { LINE(varray, i - 1, i); @@ -66,9 +67,10 @@ static void FUNC(struct draw_pt_front_end *frontend, case PIPE_PRIM_POLYGON: - case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_TRIANGLE_FAN: { + unsigned fetch_max = MIN2(FETCH_MAX, varray->fetch_max); for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(FETCH_MAX, count - j); + unsigned end = MIN2(fetch_max, count - j); end -= (end % incr); for (i = 2; i < end; i++) { TRIANGLE(varray, 0, i - 1, i); @@ -78,6 +80,7 @@ static void FUNC(struct draw_pt_front_end *frontend, varray_flush(varray); } break; + } default: assert(0); diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index ad86ab4292..2eafe270bc 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -36,8 +36,8 @@ #include "draw/draw_pt.h" -#define CACHE_MAX 1024 -#define FETCH_MAX 4096 +#define CACHE_MAX 256 +#define FETCH_MAX 256 #define DRAW_MAX (16*1024) struct vcache_frontend { @@ -52,6 +52,7 @@ struct vcache_frontend { unsigned draw_count; unsigned fetch_count; + unsigned fetch_max; struct draw_pt_middle_end *middle; @@ -296,10 +297,12 @@ static void vcache_check_run( struct draw_pt_front_end *frontend, ushort *storage = NULL; - if (0) debug_printf("fetch_count %d draw_count %d\n", fetch_count, draw_count); + if (0) debug_printf("fetch_count %d fetch_max %d draw_count %d\n", fetch_count, + vcache->fetch_max, + draw_count); if (max_index == 0xffffffff || - fetch_count >= FETCH_MAX || + fetch_count >= vcache->fetch_max || fetch_count > draw_count) { if (0) debug_printf("fail\n"); goto fail; @@ -409,7 +412,7 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, vcache->output_prim = draw_pt_reduced_prim(prim); vcache->middle = middle; - middle->prepare( middle, vcache->output_prim, opt ); + middle->prepare( middle, vcache->output_prim, opt, &vcache->fetch_max ); } -- cgit v1.2.3 From 43b92a6424a4d4f4f29b47c35092264c60822f1b Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 30 May 2008 18:36:16 +0200 Subject: gallium: Define PIPE_CAP_GUARD_BAND_* capabilities. --- src/gallium/include/pipe/p_defines.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 83330ef22f..f8fadf31b6 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -274,6 +274,10 @@ enum pipe_texture_target { #define PIPE_CAP_MAX_POINT_WIDTH_AA 17 #define PIPE_CAP_MAX_TEXTURE_ANISOTROPY 18 #define PIPE_CAP_MAX_TEXTURE_LOD_BIAS 19 +#define PIPE_CAP_GUARD_BAND_LEFT 20 /*< float */ +#define PIPE_CAP_GUARD_BAND_TOP 21 /*< float */ +#define PIPE_CAP_GUARD_BAND_RIGHT 22 /*< float */ +#define PIPE_CAP_GUARD_BAND_BOTTOM 23 /*< float */ #ifdef __cplusplus -- cgit v1.2.3 From b98ac1d47257bf7b2661ae7c1a8904b7bc5d623c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 4 Jun 2008 15:49:18 +0100 Subject: draw: init vsvg draw pointer --- src/gallium/auxiliary/draw/draw_vs_sse.c | 6 ++++-- src/gallium/auxiliary/draw/draw_vs_varient.c | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 0aa0c9a76b..c3189c707d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -158,8 +158,10 @@ draw_create_vs_sse(struct draw_context *draw, tgsi_scan_shader(templ->tokens, &vs->base.info); vs->base.draw = draw; - vs->base.create_varient = draw_vs_varient_aos_sse; -// vs->base.create_varient = draw_vs_varient_generic; + if (1) + vs->base.create_varient = draw_vs_varient_aos_sse; + else + vs->base.create_varient = draw_vs_varient_generic; vs->base.prepare = vs_sse_prepare; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index 4a155251b5..3ceca5e849 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -124,6 +124,8 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, void *output_buffer) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; + + if (0) debug_printf("%s %d \n", __FUNCTION__, count); /* Want to do this in small batches for cache locality? */ @@ -181,7 +183,7 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; - //debug_printf("%s %d %d\n", __FUNCTION__, start, count); + if (0) debug_printf("%s %d %d\n", __FUNCTION__, start, count); vsvg->fetch->run( vsvg->fetch, @@ -257,6 +259,7 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, vsvg->base.run_linear = vsvg_run_linear; vsvg->base.destroy = vsvg_destroy; + vsvg->draw = vs->draw; /* Build free-standing fetch and emit functions: -- cgit v1.2.3 From 4ebfc3c8ffccadaed98c4e032b7691eaf299b0bc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 30 May 2008 15:23:03 -0600 Subject: egl: prototype some multi-API code --- src/gallium/winsys/egl_xlib/egl_xlib.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 99389970f5..ce3a0ae0da 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -313,19 +313,21 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, return EGL_NO_CONTEXT; } - if (ctx->Base.ClientAPI != EGL_OPENGL_API) { - _eglError(EGL_BAD_MATCH, "eglCreateContext(only OpenGL API supported)"); + /* API-dependent context creation */ + switch (ctx->Base.ClientAPI) { + case EGL_OPENGL_API: + /* create a softpipe context */ + ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL); + /* Now do xlib / state tracker inits here */ + _eglConfigToContextModesRec(conf, &visual); + ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx); + break; + default: + _eglError(EGL_BAD_MATCH, "eglCreateContext(unsupported API)"); free(ctx); return EGL_NO_CONTEXT; } - /* create a softpipe context */ - ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL); - - /* Now do xlib / state tracker inits here */ - _eglConfigToContextModesRec(conf, &visual); - ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx); - _eglSaveContext(&ctx->Base); return _eglGetContextHandle(&ctx->Base); @@ -341,7 +343,14 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) context->Base.DeletePending = EGL_TRUE; } else { - st_destroy_context(context->Context); + /* API-dependent clean-up */ + switch (context->Base.ClientAPI) { + case EGL_OPENGL_API: + st_destroy_context(context->Context); + break; + default: + assert(0); + } free(context); } return EGL_TRUE; -- cgit v1.2.3 From 8223add3304451d5e75737a6d1be1739e4517943 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 4 Jun 2008 08:56:06 -0600 Subject: gallium: added tgsi_is_passthrough_shader() function Checks if all instructions are of the form MOV OUT[n], IN[n] Untested at this time. --- src/gallium/auxiliary/tgsi/util/tgsi_scan.c | 83 +++++++++++++++++++++++++++++ src/gallium/auxiliary/tgsi/util/tgsi_scan.h | 4 ++ 2 files changed, 87 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c index bda7bc2e2e..240aaaf362 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c @@ -141,3 +141,86 @@ tgsi_scan_shader(const struct tgsi_token *tokens, tgsi_parse_free (&parse); } + + + +/** + * Check if the given shader is a "passthrough" shader consisting of only + * MOV instructions of the form: MOV OUT[n], IN[n] + * + */ +boolean +tgsi_is_passthrough_shader(const struct tgsi_token *tokens) +{ + struct tgsi_parse_context parse; + + /** + ** Setup to begin parsing input shader + **/ + if (tgsi_parse_init(&parse, tokens) != TGSI_PARSE_OK) { + debug_printf("tgsi_parse_init() failed in tgsi_is_passthrough_shader()!\n"); + return FALSE; + } + + /** + ** Loop over incoming program tokens/instructions + */ + while (!tgsi_parse_end_of_tokens(&parse)) { + + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *fullinst = + &parse.FullToken.FullInstruction; + const struct tgsi_full_src_register *src = + &fullinst->FullSrcRegisters[0]; + const struct tgsi_full_dst_register *dst = + &fullinst->FullDstRegisters[0]; + + /* Do a whole bunch of checks for a simple move */ + if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV || + src->SrcRegister.File != TGSI_FILE_INPUT || + dst->DstRegister.File != TGSI_FILE_OUTPUT || + src->SrcRegister.Index != dst->DstRegister.Index || + + src->SrcRegister.Negate || + src->SrcRegisterExtMod.Negate || + src->SrcRegisterExtMod.Absolute || + src->SrcRegisterExtMod.Scale2X || + src->SrcRegisterExtMod.Bias || + src->SrcRegisterExtMod.Complement || + + src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || + src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || + src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || + src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W || + + src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || + src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || + src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || + src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W || + + dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW) + { + tgsi_parse_free(&parse); + return FALSE; + } + } + break; + + case TGSI_TOKEN_TYPE_DECLARATION: + /* fall-through */ + case TGSI_TOKEN_TYPE_IMMEDIATE: + /* fall-through */ + default: + ; /* no-op */ + } + } + + tgsi_parse_free(&parse); + + /* if we get here, it's a pass-through shader */ + return TRUE; +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h index 0530bc6b51..5cb6efb343 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h @@ -67,4 +67,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens, struct tgsi_shader_info *info); +extern boolean +tgsi_is_passthrough_shader(const struct tgsi_token *tokens); + + #endif /* TGSI_SCAN_H */ -- cgit v1.2.3 From af31e5d42982088821bdf8deaeb33d45f01fd004 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 4 Jun 2008 11:35:41 -0600 Subject: egl: do proper setup/init of EGL configs --- src/gallium/winsys/egl_xlib/egl_xlib.c | 73 ++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index ce3a0ae0da..07b3c0eb00 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -115,34 +115,68 @@ lookup_context(EGLContext surf) } +static unsigned int +bitcount(unsigned int n) +{ + unsigned int bits; + for (bits = 0; n > 0; n = n >> 1) { + bits += (n & 1); + } + return bits; +} + + /** - * XXX temporary - * Need to query X server's GLX visuals. + * Create the EGLConfigs. (one per X visual) */ static void -init_configs(_EGLDriver *drv, EGLDisplay dpy) +create_configs(_EGLDriver *drv, EGLDisplay dpy) { _EGLDisplay *disp = _eglLookupDisplay(dpy); - int i; + XVisualInfo *visInfo, visTemplate; + int num_visuals, i; + + /* get list of all X visuals, create an EGL config for each */ + visTemplate.screen = DefaultScreen(disp->Xdpy); + visInfo = XGetVisualInfo(disp->Xdpy, VisualScreenMask, + &visTemplate, &num_visuals); + if (!visInfo) { + printf("egl_xlib.c: couldn't get any X visuals\n"); + abort(); + } - for (i = 0; i < 2; i++) { - _EGLConfig config; + for (i = 0; i < num_visuals; i++) { + _EGLConfig *config = calloc(1, sizeof(_EGLConfig)); int id = i + 1; - _eglInitConfig(&config, id); - SET_CONFIG_ATTRIB(&config, EGL_RED_SIZE, 8); - SET_CONFIG_ATTRIB(&config, EGL_GREEN_SIZE, 8); - SET_CONFIG_ATTRIB(&config, EGL_BLUE_SIZE, 8); - SET_CONFIG_ATTRIB(&config, EGL_ALPHA_SIZE, 8); - if (i > 0) { - SET_CONFIG_ATTRIB(&config, EGL_DEPTH_SIZE, 24); - SET_CONFIG_ATTRIB(&config, EGL_STENCIL_SIZE, 8); - } - _eglAddConfig(disp, &config); + int rbits = bitcount(visInfo[i].red_mask); + int gbits = bitcount(visInfo[i].green_mask); + int bbits = bitcount(visInfo[i].blue_mask); + int abits = bbits == 8 ? 8 : 0; + int zbits = 24; + int sbits = 8; + int visid = visInfo[i].visualid; +#if defined(__cplusplus) || defined(c_plusplus) + int vistype = visInfo[i].c_class; +#else + int vistype = visInfo[i].class; +#endif + + _eglInitConfig(config, id); + SET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE, rbits + gbits + bbits + abits); + SET_CONFIG_ATTRIB(config, EGL_RED_SIZE, rbits); + SET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE, gbits); + SET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE, bbits); + SET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE, abits); + SET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE, zbits); + SET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE, sbits); + SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_ID, visid); + SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, vistype); + + _eglAddConfig(disp, config); } } - /** * Called via eglInitialize(), drv->API.Initialize(). */ @@ -150,10 +184,7 @@ static EGLBoolean xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *minor, EGLint *major) { - /* visual configs */ - - init_configs(drv, dpy); - + create_configs(drv, dpy); drv->Initialized = EGL_TRUE; -- cgit v1.2.3 From fe1a2d1fffe69018e30158ee21ed9842384fd233 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Thu, 5 Jun 2008 15:07:03 -0600 Subject: egl: assorted fixes for Windows Note that int32_t is typedef'd both in p_compiler.h and eglplatform.h --- src/gallium/include/pipe/p_compiler.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index b14260dd90..521ef2d189 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -58,7 +58,9 @@ typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; +#ifndef __eglplatform_h_ typedef __int32 int32_t; +#endif typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; -- cgit v1.2.3 From f27c7729a98937a761eacceabdfd03f9d694d257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 6 Jun 2008 13:29:59 +0900 Subject: draw: Compile draw_vs_aos only on x86. --- src/gallium/auxiliary/draw/draw_vs_aos.h | 4 ++++ src/gallium/auxiliary/draw/draw_vs_aos_machine.c | 6 ++++++ 2 files changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index fb6d43d32e..f6f6af2dd9 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -31,6 +31,9 @@ #ifndef DRAW_VS_AOS_H #define DRAW_VS_AOS_H +#include "pipe/p_config.h" + +#ifdef PIPE_ARCH_X86 struct tgsi_token; struct x86_function; @@ -239,6 +242,7 @@ struct draw_vs_varient_aos_sse { }; +#endif #endif diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c index b7864e9f2f..dcb6c2c8d4 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c @@ -26,6 +26,10 @@ **************************************************************************/ +#include "pipe/p_config.h" + +#ifdef PIPE_ARCH_X86 + #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "tgsi/util/tgsi_parse.h" @@ -295,3 +299,5 @@ struct aos_machine *draw_vs_aos_machine( void ) } +#endif + -- cgit v1.2.3 From adbdabb85ae322d5c80cadcee931e36d5c688d98 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 6 Jun 2008 14:49:02 +0200 Subject: i915: Moved pipe_buffer and i915_winsys functions to a common folder --- src/gallium/Makefile | 2 +- src/gallium/winsys/common/Makefile | 20 + src/gallium/winsys/common/Makefile.template | 64 + src/gallium/winsys/common/intel_drm/Makefile | 23 + src/gallium/winsys/common/intel_drm/glthread.h | 359 ++++++ .../winsys/common/intel_drm/intel_be_batchbuffer.c | 429 +++++++ .../winsys/common/intel_drm/intel_be_batchbuffer.h | 69 ++ .../winsys/common/intel_drm/intel_be_context.c | 107 ++ .../winsys/common/intel_drm/intel_be_context.h | 40 + .../winsys/common/intel_drm/intel_be_device.c | 257 ++++ .../winsys/common/intel_drm/intel_be_device.h | 58 + .../winsys/common/intel_drm/ws_dri_bufmgr.c | 949 ++++++++++++++ .../winsys/common/intel_drm/ws_dri_bufmgr.h | 138 +++ .../winsys/common/intel_drm/ws_dri_bufpool.h | 102 ++ .../winsys/common/intel_drm/ws_dri_drmpool.c | 268 ++++ .../winsys/common/intel_drm/ws_dri_fencemgr.c | 377 ++++++ .../winsys/common/intel_drm/ws_dri_fencemgr.h | 115 ++ .../winsys/common/intel_drm/ws_dri_mallocpool.c | 161 +++ .../winsys/common/intel_drm/ws_dri_slabpool.c | 968 +++++++++++++++ src/gallium/winsys/dri/Makefile.template | 1 + src/gallium/winsys/dri/intel/Makefile | 17 +- src/gallium/winsys/dri/intel/intel_batchbuffer.c | 462 ------- src/gallium/winsys/dri/intel/intel_batchbuffer.h | 131 +- src/gallium/winsys/dri/intel/intel_context.c | 71 +- src/gallium/winsys/dri/intel/intel_context.h | 17 +- src/gallium/winsys/dri/intel/intel_lock.c | 14 +- src/gallium/winsys/dri/intel/intel_reg.h | 10 +- src/gallium/winsys/dri/intel/intel_screen.c | 106 +- src/gallium/winsys/dri/intel/intel_screen.h | 25 +- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 33 +- src/gallium/winsys/dri/intel/intel_swapbuffers.h | 10 +- src/gallium/winsys/dri/intel/intel_winsys.h | 73 -- src/gallium/winsys/dri/intel/intel_winsys_i915.c | 156 --- src/gallium/winsys/dri/intel/intel_winsys_pipe.c | 318 ----- .../winsys/dri/intel/intel_winsys_softpipe.c | 20 +- .../winsys/dri/intel/intel_winsys_softpipe.h | 39 + src/gallium/winsys/dri/intel/server/i830_common.h | 8 +- src/gallium/winsys/dri/intel/server/i830_dri.h | 2 +- src/gallium/winsys/dri/intel/server/intel.h | 331 ----- src/gallium/winsys/dri/intel/server/intel_dri.c | 1306 -------------------- src/gallium/winsys/dri/intel/ws_dri_bufmgr.c | 953 -------------- src/gallium/winsys/dri/intel/ws_dri_bufmgr.h | 138 --- src/gallium/winsys/dri/intel/ws_dri_bufpool.h | 102 -- src/gallium/winsys/dri/intel/ws_dri_drmpool.c | 268 ---- src/gallium/winsys/dri/intel/ws_dri_fencemgr.c | 377 ------ src/gallium/winsys/dri/intel/ws_dri_fencemgr.h | 115 -- src/gallium/winsys/dri/intel/ws_dri_mallocpool.c | 162 --- src/gallium/winsys/dri/intel/ws_dri_slabpool.c | 968 --------------- 48 files changed, 4730 insertions(+), 6009 deletions(-) create mode 100644 src/gallium/winsys/common/Makefile create mode 100644 src/gallium/winsys/common/Makefile.template create mode 100644 src/gallium/winsys/common/intel_drm/Makefile create mode 100644 src/gallium/winsys/common/intel_drm/glthread.h create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_context.c create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_context.h create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_device.c create mode 100644 src/gallium/winsys/common/intel_drm/intel_be_device.h create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c create mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c delete mode 100644 src/gallium/winsys/dri/intel/intel_batchbuffer.c delete mode 100644 src/gallium/winsys/dri/intel/intel_winsys.h delete mode 100644 src/gallium/winsys/dri/intel/intel_winsys_i915.c delete mode 100644 src/gallium/winsys/dri/intel/intel_winsys_pipe.c create mode 100644 src/gallium/winsys/dri/intel/intel_winsys_softpipe.h delete mode 100644 src/gallium/winsys/dri/intel/server/intel.h delete mode 100644 src/gallium/winsys/dri/intel/server/intel_dri.c delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufmgr.c delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufmgr.h delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_bufpool.h delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_drmpool.c delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_fencemgr.c delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_fencemgr.h delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_mallocpool.c delete mode 100644 src/gallium/winsys/dri/intel/ws_dri_slabpool.c (limited to 'src/gallium') diff --git a/src/gallium/Makefile b/src/gallium/Makefile index aa77021daf..291973c904 100644 --- a/src/gallium/Makefile +++ b/src/gallium/Makefile @@ -2,7 +2,7 @@ TOP = ../.. include $(TOP)/configs/current -SUBDIRS = auxiliary drivers +SUBDIRS = auxiliary drivers winsys/common default: subdirs diff --git a/src/gallium/winsys/common/Makefile b/src/gallium/winsys/common/Makefile new file mode 100644 index 0000000000..4c0f3545a5 --- /dev/null +++ b/src/gallium/winsys/common/Makefile @@ -0,0 +1,20 @@ +TOP = ../../../.. +include $(TOP)/configs/current + + +SUBDIRS = $(GALLIUM_WINSYS_COMMON_DIRS) + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` diff --git a/src/gallium/winsys/common/Makefile.template b/src/gallium/winsys/common/Makefile.template new file mode 100644 index 0000000000..67af778157 --- /dev/null +++ b/src/gallium/winsys/common/Makefile.template @@ -0,0 +1,64 @@ +# -*-makefile-*- + + +# We still have a dependency on the "dri" buffer manager. Most likely +# the interface can be reused in non-dri environments, and also as a +# frontend to simpler memory managers. +# +COMMON_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(CPP_SOURCES:.cpp=.o) \ + $(ASM_SOURCES:.S=.o) + + +### Include directories +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/include \ + $(DRIVER_INCLUDES) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) + + +$(LIBNAME): $(OBJECTS) Makefile $(TOP)/src/gallium/winsys/common/Makefile.template + $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) + + +depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean:: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +include depend diff --git a/src/gallium/winsys/common/intel_drm/Makefile b/src/gallium/winsys/common/intel_drm/Makefile new file mode 100644 index 0000000000..913dbeff20 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/Makefile @@ -0,0 +1,23 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = inteldrm + +C_SOURCES = \ + intel_be_batchbuffer.c \ + intel_be_context.c \ + intel_be_device.c \ + ws_dri_bufmgr.c \ + ws_dri_drmpool.c \ + ws_dri_fencemgr.c \ + ws_dri_mallocpool.c \ + ws_dri_slabpool.c + + +include ../Makefile.template + +DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \ + && pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +symlinks: + diff --git a/src/gallium/winsys/common/intel_drm/glthread.h b/src/gallium/winsys/common/intel_drm/glthread.h new file mode 100644 index 0000000000..b8e9d5f59b --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/glthread.h @@ -0,0 +1,359 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* + * Thread support for gl dispatch. + * + * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) + * and Christoph Poliwoda (poliwoda@volumegraphics.com) + * Revised by Keith Whitwell + * Adapted for new gl dispatcher by Brian Paul + * + * + * + * DOCUMENTATION + * + * This thread module exports the following types: + * _glthread_TSD Thread-specific data area + * _glthread_Thread Thread datatype + * _glthread_Mutex Mutual exclusion lock + * + * Macros: + * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex + * _glthread_INIT_MUTEX(name) Initialize a mutex + * _glthread_LOCK_MUTEX(name) Lock a mutex + * _glthread_UNLOCK_MUTEX(name) Unlock a mutex + * + * Functions: + * _glthread_GetID(v) Get integer thread ID + * _glthread_InitTSD() Initialize thread-specific data + * _glthread_GetTSD() Get thread-specific data + * _glthread_SetTSD() Set thread-specific data + * + */ + +/* + * If this file is accidentally included by a non-threaded build, + * it should not cause the build to fail, or otherwise cause problems. + * In general, it should only be included when needed however. + */ + +#ifndef GLTHREAD_H +#define GLTHREAD_H + + +#if defined(USE_MGL_NAMESPACE) +#define _glapi_Dispatch _mglapi_Dispatch +#endif + + + +#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ + defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ + && !defined(THREADS) +# define THREADS +#endif + +#ifdef VMS +#include +#endif + +/* + * POSIX threads. This should be your choice in the Unix world + * whenever possible. When building with POSIX threads, be sure + * to enable any compiler flags which will cause the MT-safe + * libc (if one exists) to be used when linking, as well as any + * header macros for MT-safe errno, etc. For Solaris, this is the -mt + * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable + * proper compiling for MT-safe libc etc. + */ +#if defined(PTHREADS) +#include /* POSIX threads headers */ + +typedef struct { + pthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef pthread_t _glthread_Thread; + +typedef pthread_mutex_t _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER + +#define _glthread_INIT_MUTEX(name) \ + pthread_mutex_init(&(name), NULL) + +#define _glthread_DESTROY_MUTEX(name) \ + pthread_mutex_destroy(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) pthread_mutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) pthread_mutex_unlock(&(name)) + +typedef pthread_cond_t _glthread_Cond; + +#define _glthread_DECLARE_STATIC_COND(name) \ + static _glthread_Cond name = PTHREAD_COND_INITIALIZER + +#define _glthread_INIT_COND(cond) \ + pthread_cond_init(&(cond), NULL) + +#define _glthread_DESTROY_COND(name) \ + pthread_cond_destroy(&(name)) + +#define _glthread_COND_WAIT(cond, mutex) \ + pthread_cond_wait(&(cond), &(mutex)) + +#define _glthread_COND_SIGNAL(cond) \ + pthread_cond_signal(&(cond)) + +#define _glthread_COND_BROADCAST(cond) \ + pthread_cond_broadcast(&(cond)) + + +#else /* PTHREADS */ + +typedef unsigned int _glthread_Cond; +#define _glthread_DECLARE_STATIC_COND(name) \ +// #warning Condition variables not implemented. + +#define _glthread_INIT_COND(cond) \ + abort(); + +#define _glthread_DESTROY_COND(name) \ + abort(); + +#define _glthread_COND_WAIT(cond, mutex) \ + abort(); + +#define _glthread_COND_SIGNAL(cond) \ + abort(); + +#define _glthread_COND_BROADCAST(cond) \ + abort(); + +#endif + + +/* + * Solaris threads. Use only up to Solaris 2.4. + * Solaris 2.5 and higher provide POSIX threads. + * Be sure to compile with -mt on the Solaris compilers, or + * use -D_REENTRANT if using gcc. + */ +#ifdef SOLARIS_THREADS +#include + +typedef struct { + thread_key_t key; + mutex_t keylock; + int initMagic; +} _glthread_TSD; + +typedef thread_t _glthread_Thread; + +typedef mutex_t _glthread_Mutex; + +/* XXX need to really implement mutex-related macros */ +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 +#define _glthread_INIT_MUTEX(name) (void) name +#define _glthread_DESTROY_MUTEX(name) (void) name +#define _glthread_LOCK_MUTEX(name) (void) name +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* SOLARIS_THREADS */ + + + + +/* + * Windows threads. Should work with Windows NT and 95. + * IMPORTANT: Link with multithreaded runtime library when THREADS are + * used! + */ +#ifdef WIN32_THREADS +#include + +typedef struct { + DWORD key; + int initMagic; +} _glthread_TSD; + +typedef HANDLE _glthread_Thread; + +typedef CRITICAL_SECTION _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) /*static*/ _glthread_Mutex name = {0,0,0,0,0,0} +#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name) +#define _glthread_DESTROY_MUTEX(name) DeleteCriticalSection(&name) +#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name) +#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name) + +#endif /* WIN32_THREADS */ + + + + +/* + * XFree86 has its own thread wrapper, Xthreads.h + * We wrap it again for GL. + */ +#ifdef USE_XTHREADS +#include + +typedef struct { + xthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef xthread_t _glthread_Thread; + +typedef xmutex_rec _glthread_Mutex; + +#ifdef XMUTEX_INITIALIZER +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = XMUTEX_INITIALIZER +#else +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name +#endif + +#define _glthread_INIT_MUTEX(name) \ + xmutex_init(&(name)) + +#define _glthread_DESTROY_MUTEX(name) \ + xmutex_clear(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) xmutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) xmutex_unlock(&(name)) + +#endif /* USE_XTHREADS */ + + + +/* + * BeOS threads. R5.x required. + */ +#ifdef BEOS_THREADS + +#include +#include + +typedef struct { + int32 key; + int initMagic; +} _glthread_TSD; + +typedef thread_id _glthread_Thread; + +/* Use Benaphore, aka speeder semaphore */ +typedef struct { + int32 lock; + sem_id sem; +} benaphore; +typedef benaphore _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = { 0, 0 } +#define _glthread_INIT_MUTEX(name) name.sem = create_sem(0, #name"_benaphore"), name.lock = 0 +#define _glthread_DESTROY_MUTEX(name) delete_sem(name.sem), name.lock = 0 +#define _glthread_LOCK_MUTEX(name) if (name.sem == 0) _glthread_INIT_MUTEX(name); \ + if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem) +#define _glthread_UNLOCK_MUTEX(name) if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem) + +#endif /* BEOS_THREADS */ + + + +#ifndef THREADS + +/* + * THREADS not defined + */ + +typedef GLuint _glthread_TSD; + +typedef GLuint _glthread_Thread; + +typedef GLuint _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 + +#define _glthread_INIT_MUTEX(name) (void) name + +#define _glthread_DESTROY_MUTEX(name) (void) name + +#define _glthread_LOCK_MUTEX(name) (void) name + +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* THREADS */ + + + +/* + * Platform independent thread specific data API. + */ + +extern unsigned long +_glthread_GetID(void); + + +extern void +_glthread_InitTSD(_glthread_TSD *); + + +extern void * +_glthread_GetTSD(_glthread_TSD *); + + +extern void +_glthread_SetTSD(_glthread_TSD *, void *); + +#if defined(GLX_USE_TLS) + +extern __thread struct _glapi_table * _glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))); + +#define GET_DISPATCH() _glapi_tls_Dispatch + +#elif !defined(GL_CALL) +# if defined(THREADS) +# define GET_DISPATCH() \ + ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ + ? _glapi_Dispatch : _glapi_get_dispatch()) +# else +# define GET_DISPATCH() _glapi_Dispatch +# endif /* defined(THREADS) */ +#endif /* ndef GL_CALL */ + + +#endif /* THREADS_H */ diff --git a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c new file mode 100644 index 0000000000..bc13a5761e --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c @@ -0,0 +1,429 @@ + +#include "intel_be_batchbuffer.h" +#include "intel_be_context.h" +#include "intel_be_device.h" +#include + +#include "xf86drm.h" + +static void +intel_realloc_relocs(struct intel_be_batchbuffer *batch, int num_relocs) +{ + unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; + + size *= sizeof(uint32_t); + batch->reloc = realloc(batch->reloc, size); + batch->reloc_size = num_relocs; +} + + +void +intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch) +{ + /* + * Get a new, free batchbuffer. + */ + drmBO *bo; + struct drm_bo_info_req *req; + + driBOUnrefUserList(batch->list); + driBOResetList(batch->list); + + /* base.size is the size available to the i915simple driver */ + batch->base.size = batch->device->max_batch_size - BATCH_RESERVED; + batch->base.actual_size = batch->device->max_batch_size; + driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0); + + /* + * Add the batchbuffer to the validate list. + */ + + driBOAddListItem(batch->list, batch->buffer, + DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, + &batch->dest_location, &batch->node); + + req = &batch->node->bo_arg.d.req.bo_req; + + /* + * Set up information needed for us to make relocations + * relative to the underlying drm buffer objects. + */ + + driReadLockKernelBO(); + bo = driBOKernel(batch->buffer); + req->presumed_offset = (uint64_t) bo->offset; + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + batch->drmBOVirtual = (uint8_t *) bo->virtual; + driReadUnlockKernelBO(); + + /* + * Adjust the relocation buffer size. + */ + + if (batch->reloc_size > INTEL_MAX_RELOCS || + batch->reloc == NULL) + intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); + + assert(batch->reloc != NULL); + batch->reloc[0] = 0; /* No relocs yet. */ + batch->reloc[1] = 1; /* Reloc type 1 */ + batch->reloc[2] = 0; /* Only a single relocation list. */ + batch->reloc[3] = 0; /* Only a single relocation list. */ + + batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->poolOffset = driBOPoolOffset(batch->buffer); + batch->base.ptr = batch->base.map; + batch->dirty_state = ~0; + batch->nr_relocs = 0; + batch->flags = 0; + batch->id = 0;//batch->intel->intelScreen->batch_id++; +} + +/*====================================================================== + * Public functions + */ +struct intel_be_batchbuffer * +intel_be_batchbuffer_alloc(struct intel_be_context *intel) +{ + struct intel_be_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + batch->device = intel->device; + + driGenBuffers(intel->device->batchPool, "batchbuffer", 1, + &batch->buffer, 4096, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); + batch->last_fence = NULL; + batch->list = driBOCreateList(20); + batch->reloc = NULL; + intel_be_batchbuffer_reset(batch); + return batch; +} + +void +intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch) +{ + if (batch->last_fence) { + driFenceFinish(batch->last_fence, + DRM_FENCE_TYPE_EXE, FALSE); + driFenceUnReference(&batch->last_fence); + } + if (batch->base.map) { + driBOUnmap(batch->buffer); + batch->base.map = NULL; + } + driBOUnReference(batch->buffer); + driBOFreeList(batch->list); + if (batch->reloc) + free(batch->reloc); + batch->buffer = NULL; + free(batch); +} + +void +intel_be_offset_relocation(struct intel_be_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask) +{ + int itemLoc; + struct _drmBONode *node; + uint32_t *reloc; + struct drm_bo_info_req *req; + + driBOAddListItem(batch->list, driBO, val_flags, val_mask, + &itemLoc, &node); + req = &node->bo_arg.d.req.bo_req; + + if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { + + /* + * Stop other threads from tampering with the underlying + * drmBO while we're reading its offset. + */ + + driReadLockKernelBO(); + req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; + driReadUnlockKernelBO(); + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + } + + pre_add += driBOPoolOffset(driBO); + + if (batch->nr_relocs == batch->reloc_size) + intel_realloc_relocs(batch, batch->reloc_size * 2); + + reloc = batch->reloc + + (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); + + reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual); + i915_batchbuffer_dword(&batch->base, req->presumed_offset + pre_add); + reloc[1] = pre_add; + reloc[2] = itemLoc; + reloc[3] = batch->dest_location; + batch->nr_relocs++; +} + +static void +i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) +{ + buf->handle = rep->handle; + buf->flags = rep->flags; + buf->size = rep->size; + buf->offset = rep->offset; + buf->mapHandle = rep->arg_handle; + buf->proposedFlags = rep->proposed_flags; + buf->start = rep->buffer_start; + buf->fenceFlags = rep->fence_flags; + buf->replyFlags = rep->rep_flags; + buf->pageAlignment = rep->page_alignment; +} + +static int +i915_execbuf(struct intel_be_batchbuffer *batch, + unsigned int used, + boolean ignore_cliprects, + drmBOList *list, + struct drm_i915_execbuffer *ea) +{ +// struct intel_be_context *intel = batch->intel; + drmBONode *node; + drmMMListHead *l; + struct drm_i915_op_arg *arg, *first; + struct drm_bo_op_req *req; + struct drm_bo_info_rep *rep; + uint64_t *prevNext = NULL; + drmBO *buf; + int ret = 0; + uint32_t count = 0; + + first = NULL; + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + + arg = &node->bo_arg; + req = &arg->d.req; + + if (!first) + first = arg; + + if (prevNext) + *prevNext = (unsigned long)arg; + + prevNext = &arg->next; + req->bo_req.handle = node->buf->handle; + req->op = drm_bo_validate; + req->bo_req.flags = node->arg0; + req->bo_req.mask = node->arg1; + req->bo_req.hint |= 0; + count++; + } + + memset(ea, 0, sizeof(*ea)); + ea->num_buffers = count; + ea->batch.start = batch->poolOffset; + ea->batch.used = used; +#if 0 /* ZZZ JB: no cliprects used */ + ea->batch.cliprects = intel->pClipRects; + ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); +#else + ea->batch.cliprects = NULL; + ea->batch.num_cliprects = 0; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0; +#endif + ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; + ea->ops_list = (unsigned long) first; + first->reloc_ptr = (unsigned long) batch->reloc; + batch->reloc[0] = batch->nr_relocs; + + //return -EFAULT; + do { + ret = drmCommandWriteRead(batch->device->fd, DRM_I915_EXECBUFFER, ea, + sizeof(*ea)); + } while (ret == -EAGAIN); + + if (ret != 0) + return ret; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + arg = &node->bo_arg; + rep = &arg->d.rep.bo_info; + + if (!arg->handled) { + return -EFAULT; + } + if (arg->d.rep.ret) + return arg->d.rep.ret; + + buf = node->buf; + i915_drm_copy_reply(rep, buf); + } + return 0; +} + +/* TODO: Push this whole function into bufmgr. + */ +static struct _DriFenceObject * +do_flush_locked(struct intel_be_batchbuffer *batch, + unsigned int used, + boolean ignore_cliprects, boolean allow_unlock) +{ + struct intel_be_context *intel = batch->intel; + struct _DriFenceObject *fo; + drmFence fence; + drmBOList *boList; + struct drm_i915_execbuffer ea; + int ret = 0; + + driBOValidateUserList(batch->list); + boList = driGetdrmBOList(batch->list); + +#if 0 /* ZZZ JB Allways run */ + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { +#else + if (1) { +#endif + ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); + } else { + driPutdrmBOList(batch->list); + fo = NULL; + goto out; + } + driPutdrmBOList(batch->list); + if (ret) + abort(); + + if (ea.fence_arg.error != 0) { + + /* + * The hardware has been idled by the kernel. + * Don't fence the driBOs. + */ + + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); +#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ + _mesa_printf("fence error\n"); +#endif + batch->last_fence = NULL; + fo = NULL; + goto out; + } + + fence.handle = ea.fence_arg.handle; + fence.fence_class = ea.fence_arg.fence_class; + fence.type = ea.fence_arg.type; + fence.flags = ea.fence_arg.flags; + fence.signaled = ea.fence_arg.signaled; + + fo = driBOFenceUserList(batch->device->fenceMgr, batch->list, + "SuperFence", &fence); + + if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); + /* + * FIXME: Context last fence?? + */ + batch->last_fence = fo; + driFenceReference(fo); + } + out: +#if 0 /* ZZZ JB: fix this */ + intel->vtbl.lost_hardware(intel); +#else + (void)intel; +#endif + return fo; +} + + +struct _DriFenceObject * +intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch) +{ + struct intel_be_context *intel = batch->intel; + unsigned int used = batch->base.ptr - batch->base.map; + boolean was_locked = batch->intel->hardware_locked(intel); + struct _DriFenceObject *fence; + + if (used == 0) { + driFenceReference(batch->last_fence); + return batch->last_fence; + } + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ +#if 0 /* ZZZ JB: what should we do here? */ + if (used & 4) { + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } +#else + if (used & 4) { + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 8; + } +#endif + driBOUnmap(batch->buffer); + batch->base.ptr = NULL; + batch->base.map = NULL; + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!was_locked) + intel->hardware_lock(intel); + + fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + FALSE); + + if (!was_locked) + intel->hardware_unlock(intel); + + /* Reset the buffer: + */ + intel_be_batchbuffer_reset(batch); + return fence; +} + +void +intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch) +{ + struct _DriFenceObject *fence = intel_be_batchbuffer_flush(batch); + driFenceFinish(fence, driFenceType(fence), FALSE); + driFenceUnReference(&fence); +} + +#if 0 +void +intel_be_batchbuffer_data(struct intel_be_batchbuffer *batch, + const void *data, unsigned int bytes, unsigned int flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + memcpy(batch->base.ptr, data, bytes); + batch->base.ptr += bytes; +} +#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h new file mode 100644 index 0000000000..f150e3a674 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h @@ -0,0 +1,69 @@ + +#ifndef INTEL_BE_BATCHBUFFER_H +#define INTEL_BE_BATCHBUFFER_H + +#include "i915simple/i915_batch.h" + +#include "ws_dri_bufmgr.h" + +#define BATCH_RESERVED 16 + +#define INTEL_DEFAULT_RELOCS 100 +#define INTEL_MAX_RELOCS 400 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct intel_be_context; +struct intel_be_device; + +struct intel_be_batchbuffer +{ + struct i915_batchbuffer base; + + struct intel_be_context *intel; + struct intel_be_device *device; + + struct _DriBufferObject *buffer; + struct _DriFenceObject *last_fence; + uint32_t flags; + + struct _DriBufferList *list; + size_t list_count; + + uint32_t *reloc; + size_t reloc_size; + size_t nr_relocs; + + uint32_t dirty_state; + uint32_t id; + + uint32_t poolOffset; + uint8_t *drmBOVirtual; + struct _drmBONode *node; /* Validation list node for this buffer */ + int dest_location; /* Validation list sequence for this buffer */ +}; + +struct intel_be_batchbuffer * +intel_be_batchbuffer_alloc(struct intel_be_context *intel); + +void +intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch); + +void +intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch); + +struct _DriFenceObject * +intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch); + +void +intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch); + +void +intel_be_offset_relocation(struct intel_be_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask); + +#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_context.c b/src/gallium/winsys/common/intel_drm/intel_be_context.c new file mode 100644 index 0000000000..1af39674f4 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_context.c @@ -0,0 +1,107 @@ + +/* + * Authors: Jakob Bornecrantz + */ + +#include "ws_dri_fencemgr.h" +#include "intel_be_device.h" +#include "intel_be_context.h" +#include "intel_be_batchbuffer.h" + +static INLINE struct intel_be_context * +intel_be_context(struct i915_winsys *sws) +{ + return (struct intel_be_context *)sws; +} + +/* Simple batchbuffer interface: + */ + +static struct i915_batchbuffer* +intel_i915_batch_get(struct i915_winsys *sws) +{ + struct intel_be_context *intel = intel_be_context(sws); + return &intel->batch->base; +} + +static void intel_i915_batch_reloc(struct i915_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta) +{ + struct intel_be_context *intel = intel_be_context(sws); + + unsigned flags = DRM_BO_FLAG_MEM_TT; + unsigned mask = DRM_BO_MASK_MEM; + + if (access_flags & I915_BUFFER_ACCESS_WRITE) { + flags |= DRM_BO_FLAG_WRITE; + mask |= DRM_BO_FLAG_WRITE; + } + + if (access_flags & I915_BUFFER_ACCESS_READ) { + flags |= DRM_BO_FLAG_READ; + mask |= DRM_BO_FLAG_READ; + } + + intel_be_offset_relocation(intel->batch, + delta, + dri_bo(buf), + flags, + mask); +} + +static void intel_i915_batch_flush(struct i915_winsys *sws, + struct pipe_fence_handle **fence) +{ + struct intel_be_context *intel = intel_be_context(sws); + + union { + struct _DriFenceObject *dri; + struct pipe_fence_handle *pipe; + } fu; + + if (fence) + assert(!*fence); + + fu.dri = intel_be_batchbuffer_flush(intel->batch); + + if (!fu.dri) { + assert(0); + *fence = NULL; + return; + } + + if (fu.dri) { + if (fence) + *fence = fu.pipe; + else + driFenceUnReference(&fu.dri); + } + +} + +boolean +intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device) +{ + assert(intel); + assert(device); + + intel->device = device; + + /* TODO move framebuffer createion to the driver */ + + intel->base.batch_get = intel_i915_batch_get; + intel->base.batch_reloc = intel_i915_batch_reloc; + intel->base.batch_flush = intel_i915_batch_flush; + + intel->batch = intel_be_batchbuffer_alloc(intel); + + return true; +} + +void +intel_be_destroy_context(struct intel_be_context *intel) +{ + intel_be_batchbuffer_free(intel->batch); +} diff --git a/src/gallium/winsys/common/intel_drm/intel_be_context.h b/src/gallium/winsys/common/intel_drm/intel_be_context.h new file mode 100644 index 0000000000..d5cbc93594 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_context.h @@ -0,0 +1,40 @@ +/* These need to be diffrent from the intel winsys */ +#ifndef INTEL_BE_CONTEXT_H +#define INTEL_BE_CONTEXT_H + +#include "i915simple/i915_winsys.h" + +struct intel_be_context +{ + /** Interface to i915simple driver */ + struct i915_winsys base; + + struct intel_be_device *device; + struct intel_be_batchbuffer *batch; + + /* + * Hardware lock functions. + * + * Needs to be filled in by the winsys. + */ + void (*hardware_lock)(struct intel_be_context *context); + void (*hardware_unlock)(struct intel_be_context *context); + boolean (*hardware_locked)(struct intel_be_context *context); +}; + +/** + * Intialize a allocated intel_be_context struct. + * + * Remember to set the hardware_* functions. + */ +boolean +intel_be_init_context(struct intel_be_context *intel, + struct intel_be_device *device); + +/** + * Destroy a intel_be_context. + * Does not free the struct that is up to the winsys. + */ +void +intel_be_destroy_context(struct intel_be_context *intel); +#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c new file mode 100644 index 0000000000..0fc1894eaa --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c @@ -0,0 +1,257 @@ + + +/* + * Authors: Keith Whitwell + * Jakob Bornecrantz + */ + +#include "intel_be_device.h" +#include "ws_dri_bufmgr.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +/* Turn a pipe winsys into an intel/pipe winsys: + */ +static INLINE struct intel_be_device * +intel_be_device( struct pipe_winsys *winsys ) +{ + return (struct intel_be_device *)winsys; +} + + +/* + * Buffer functions. + * + * Most callbacks map direcly onto dri_bufmgr operations: + */ + +static void *intel_be_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags ) +{ + unsigned drm_flags = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + drm_flags |= DRM_BO_FLAG_WRITE; + + if (flags & PIPE_BUFFER_USAGE_CPU_READ) + drm_flags |= DRM_BO_FLAG_READ; + + return driBOMap( dri_bo(buf), drm_flags, 0 ); +} + +static void intel_be_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnmap( dri_bo(buf) ); +} + +static void +intel_be_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnReference( dri_bo(buf) ); + FREE(buf); +} + +static struct pipe_buffer * +intel_be_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size ) +{ + struct intel_be_buffer *buffer = CALLOC_STRUCT( intel_be_buffer ); + struct intel_be_device *iws = intel_be_device(winsys); + unsigned flags = 0; + struct _DriBufferPool *pool; + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { + flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + pool = iws->mallocPool; + } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { + /* For vertex buffers */ + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->vertexPool; + } else { + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->regionPool; + } + + if (usage & PIPE_BUFFER_USAGE_GPU_READ) + flags |= DRM_BO_FLAG_READ; + + if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) + flags |= DRM_BO_FLAG_WRITE; + + /* drm complains if we don't set any read/write flags. + */ + if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) + flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + buffer->pool = pool; + driGenBuffers( buffer->pool, + "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); + + driBOData( buffer->driBO, size, NULL, buffer->pool, 0 ); + + return &buffer->base; +} + + +static struct pipe_buffer * +intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) +{ + struct intel_be_buffer *buffer = CALLOC_STRUCT( intel_be_buffer ); + struct intel_be_device *iws = intel_be_device(winsys); + + driGenUserBuffer( iws->regionPool, + "pipe user buffer", &buffer->driBO, ptr, bytes ); + + buffer->base.refcount = 1; + + return &buffer->base; +} + + +/* + * Surface functions. + * + * Deprecated! + */ + +static struct pipe_surface * +intel_i915_surface_alloc(struct pipe_winsys *winsys) +{ + assert((size_t)"intel_i915_surface_alloc is deprecated" & 0); + return NULL; +} + +static int +intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + assert((size_t)"intel_i915_surface_alloc_storage is deprecated" & 0); + return -1; +} + +static void +intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + assert((size_t)"intel_i915_surface_release is deprecated" & 0); +} + +/* + * Fence functions + */ + +static void +intel_be_fence_reference( struct pipe_winsys *sws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence ) +{ + if (*ptr) + driFenceUnReference((struct _DriFenceObject **)ptr); + + if (fence) + *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); +} + +static int +intel_be_fence_signalled( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceSignaled((struct _DriFenceObject *)fence, flag); +} + +static int +intel_be_fence_finish( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); +} + +/* + * Misc functions + */ + +boolean +intel_be_init_device(struct intel_be_device *dev, int fd) +{ + dev->fd = fd; + dev->max_batch_size = 16 * 4096; + dev->max_vertex_size = 128 * 4096; + + dev->base.buffer_create = intel_be_buffer_create; + dev->base.user_buffer_create = intel_be_user_buffer_create; + dev->base.buffer_map = intel_be_buffer_map; + dev->base.buffer_unmap = intel_be_buffer_unmap; + dev->base.buffer_destroy = intel_be_buffer_destroy; + dev->base.surface_alloc = intel_i915_surface_alloc; + dev->base.surface_alloc_storage = intel_i915_surface_alloc_storage; + dev->base.surface_release = intel_i915_surface_release; + dev->base.fence_reference = intel_be_fence_reference; + dev->base.fence_signalled = intel_be_fence_signalled; + dev->base.fence_finish = intel_be_fence_finish; + +#if 0 /* Set by the winsys */ + dev->base.flush_frontbuffer = intel_flush_frontbuffer; + dev->base.get_name = intel_get_name; +#endif + + dev->fMan = driInitFreeSlabManager(10, 10); + dev->fenceMgr = driFenceMgrTTMInit(dev->fd); + + dev->mallocPool = driMallocPoolInit(); + dev->staticPool = driDRMPoolInit(dev->fd); + dev->regionPool = driDRMPoolInit(dev->fd); + dev->vertexPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + dev->max_vertex_size, + 1, 120, dev->max_vertex_size * 4, 0, + dev->fMan); + + dev->batchPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + dev->max_batch_size, + 1, 40, dev->max_batch_size * 16, 0, + dev->fMan); + + return true; +} + +void +intel_be_destroy_device(struct intel_be_device *dev) +{ + driPoolTakeDown(dev->mallocPool); + driPoolTakeDown(dev->staticPool); + driPoolTakeDown(dev->regionPool); + driPoolTakeDown(dev->vertexPool); + driPoolTakeDown(dev->batchPool); + + /** TODO takedown fenceMgr and fMan */ +} diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h new file mode 100644 index 0000000000..ec5cace71c --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.h @@ -0,0 +1,58 @@ +#ifndef INTEL_DRM_DEVICE_H +#define INTEL_DRM_DEVICE_H + +#include "pipe/p_winsys.h" +#include "pipe/p_context.h" + +/* + * Device + */ + +struct intel_be_device +{ + struct pipe_winsys base; + + int fd; /**< Drm file discriptor */ + + size_t max_batch_size; + size_t max_vertex_size; + + struct _DriFenceMgr *fenceMgr; + + struct _DriBufferPool *batchPool; + struct _DriBufferPool *regionPool; + struct _DriBufferPool *mallocPool; + struct _DriBufferPool *vertexPool; + struct _DriBufferPool *staticPool; + struct _DriFreeSlabManager *fMan; +}; + +boolean +intel_be_init_device(struct intel_be_device *device, int fd); + +void +intel_be_destroy_device(struct intel_be_device *dev); + +/* + * Buffer + */ + +struct intel_be_buffer { + struct pipe_buffer base; + struct _DriBufferPool *pool; + struct _DriBufferObject *driBO; +}; + +static INLINE struct intel_be_buffer * +intel_be_buffer( struct pipe_buffer *buf ) +{ + return (struct intel_be_buffer *)buf; +} + +static INLINE struct _DriBufferObject * +dri_bo( struct pipe_buffer *buf ) +{ + return intel_be_buffer(buf)->driBO; +} + +#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c new file mode 100644 index 0000000000..b6d901f85e --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c @@ -0,0 +1,949 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#include +#include +#include +#include "glthread.h" +#include "errno.h" +#include "ws_dri_bufmgr.h" +#include "string.h" +#include "pipe/p_debug.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + + +/* + * This lock is here to protect drmBO structs changing underneath us during a + * validate list call, since validatelist cannot take individiual locks for + * each drmBO. Validatelist takes this lock in write mode. Any access to an + * individual drmBO should take this lock in read mode, since in that case, the + * driBufferObject mutex will protect the access. Locking order is + * driBufferObject mutex - > this rw lock. + */ + +_glthread_DECLARE_STATIC_MUTEX(bmMutex); +_glthread_DECLARE_STATIC_COND(bmCond); + +static int kernelReaders = 0; +static int num_buffers = 0; +static int num_user_buffers = 0; + +static drmBO *drmBOListBuf(void *iterator) +{ + drmBONode *node; + drmMMListHead *l = (drmMMListHead *) iterator; + node = DRMLISTENTRY(drmBONode, l, head); + return node->buf; +} + +static void *drmBOListIterator(drmBOList *list) +{ + void *ret = list->list.next; + + if (ret == &list->list) + return NULL; + return ret; +} + +static void *drmBOListNext(drmBOList *list, void *iterator) +{ + void *ret; + + drmMMListHead *l = (drmMMListHead *) iterator; + ret = l->next; + if (ret == &list->list) + return NULL; + return ret; +} + +static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, + uint64_t arg0, + uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } + else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADD(&node->head, &list->list); + list->numOnList++; + return node; +} + +static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, + uint64_t mask, int *newItem) +{ + drmBONode *node, *cur; + drmMMListHead *l; + + *newItem = 0; + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + } + if (!cur) { + cur = drmAddListItem(list, buf, flags, mask); + if (!cur) { + return -ENOMEM; + } + *newItem = 1; + cur->arg0 = flags; + cur->arg1 = mask; + } + else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + return 0; +} + +static void drmBOFreeList(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->list.next; + while(l != &list->list) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->list.next; + list->numCurrent--; + list->numOnList--; + } + + l = list->free.next; + while(l != &list->free) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + } +} + +static int drmAdjustListNodes(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + int ret = 0; + + while(list->numCurrent < list->numTarget) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + ret = -ENOMEM; + break; + } + list->numCurrent++; + DRMLISTADD(&node->head, &list->free); + } + + while(list->numCurrent > list->numTarget) { + l = list->free.next; + if (l == &list->free) + break; + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + list->numCurrent--; + } + return ret; +} + +static int drmBOCreateList(int numTarget, drmBOList *list) +{ + DRMINITLISTHEAD(&list->list); + DRMINITLISTHEAD(&list->free); + list->numTarget = numTarget; + list->numCurrent = 0; + list->numOnList = 0; + return drmAdjustListNodes(list); +} + +static int drmBOResetList(drmBOList *list) +{ + drmMMListHead *l; + int ret; + + ret = drmAdjustListNodes(list); + if (ret) + return ret; + + l = list->list.next; + while (l != &list->list) { + DRMLISTDEL(l); + DRMLISTADD(l, &list->free); + list->numOnList--; + l = list->list.next; + } + return drmAdjustListNodes(list); +} + +void driWriteLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + while(kernelReaders != 0) + _glthread_COND_WAIT(bmCond, bmMutex); +} + +void driWriteUnlockKernelBO(void) +{ + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + kernelReaders++; + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadUnlockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + if (--kernelReaders == 0) + _glthread_COND_BROADCAST(bmCond); + _glthread_UNLOCK_MUTEX(bmMutex); +} + + + + +/* + * TODO: Introduce fence pools in the same way as + * buffer object pools. + */ + +typedef struct _DriBufferObject +{ + DriBufferPool *pool; + _glthread_Mutex mutex; + int refCount; + const char *name; + uint64_t flags; + unsigned hint; + unsigned alignment; + unsigned createdByReference; + void *private; + /* user-space buffer: */ + unsigned userBuffer; + void *userData; + unsigned userSize; +} DriBufferObject; + +typedef struct _DriBufferList { + drmBOList drmBuffers; /* List of kernel buffers needing validation */ + drmBOList driBuffers; /* List of user-space buffers needing validation */ +} DriBufferList; + + +void +bmError(int val, const char *file, const char *function, int line) +{ + printf("Fatal video memory manager error \"%s\".\n" + "Check kernel logs or set the LIBGL_DEBUG\n" + "environment variable to \"verbose\" for more info.\n" + "Detected in file %s, line %d, function %s.\n", + strerror(-val), file, line, function); +#ifndef NDEBUG + abort(); +#else + abort(); +#endif +} + +extern drmBO * +driBOKernel(struct _DriBufferObject *buf) +{ + drmBO *ret; + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + ret = buf->pool->kernel(buf->pool, buf->private); + if (!ret) + BM_CKFATAL(-EINVAL); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + + return ret; +} + +void +driBOWaitIdle(struct _DriBufferObject *buf, int lazy) +{ + + /* + * This function may block. Is it sane to keep the mutex held during + * that time?? + */ + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void * +driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) +{ + void *virtual; + int retval; + + if (buf->userBuffer) { + return buf->userData; + } + + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + retval = buf->pool->map(buf->pool, buf->private, flags, hint, + &buf->mutex, &virtual); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval == 0 ? virtual : NULL; +} + +void +driBOUnmap(struct _DriBufferObject *buf) +{ + if (buf->userBuffer) + return; + + assert(buf->private != NULL); + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +unsigned long +driBOOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->offset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +unsigned long +driBOPoolOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->poolOffset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +uint64_t +driBOFlags(struct _DriBufferObject *buf) +{ + uint64_t ret; + + assert(buf->private != NULL); + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->flags(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + return ret; +} + +struct _DriBufferObject * +driBOReference(struct _DriBufferObject *buf) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (++buf->refCount == 1) { + _glthread_UNLOCK_MUTEX(buf->mutex); + BM_CKFATAL(-EINVAL); + } + _glthread_UNLOCK_MUTEX(buf->mutex); + return buf; +} + +void +driBOUnReference(struct _DriBufferObject *buf) +{ + int tmp; + + if (!buf) + return; + + _glthread_LOCK_MUTEX(buf->mutex); + tmp = --buf->refCount; + if (!tmp) { + _glthread_UNLOCK_MUTEX(buf->mutex); + if (buf->private) { + if (buf->createdByReference) + buf->pool->unreference(buf->pool, buf->private); + else + buf->pool->destroy(buf->pool, buf->private); + } + if (buf->userBuffer) + num_user_buffers--; + else + num_buffers--; + free(buf); + } else + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + + +int +driBOData(struct _DriBufferObject *buf, + unsigned size, const void *data, + DriBufferPool *newPool, + uint64_t flags) +{ + void *virtual = NULL; + int newBuffer; + int retval = 0; + struct _DriBufferPool *pool; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + pool = buf->pool; + + if (pool == NULL && newPool != NULL) { + buf->pool = newPool; + pool = newPool; + } + if (newPool == NULL) + newPool = pool; + + if (!pool->create) { + assert((size_t)"driBOData called on invalid buffer\n" & 0); + BM_CKFATAL(-EINVAL); + } + + newBuffer = (!buf->private || pool != newPool || + pool->size(pool, buf->private) < size); + + if (!flags) + flags = buf->flags; + + if (newBuffer) { + + if (buf->createdByReference) { + assert((size_t)"driBOData requiring resizing called on shared buffer.\n" & 0); + BM_CKFATAL(-EINVAL); + } + + if (buf->private) + buf->pool->destroy(buf->pool, buf->private); + + pool = newPool; + buf->pool = newPool; + buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (!buf->private) + retval = -ENOMEM; + + if (retval == 0) + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); + } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { + /* + * Buffer is busy. need to create a new one. + */ + + void *newBuf; + + newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (newBuf) { + buf->pool->destroy(buf->pool, buf->private); + buf->private = newBuf; + } + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } else { + uint64_t flag_diff = flags ^ buf->flags; + + /* + * We might need to change buffer flags. + */ + + if (flag_diff){ + assert(pool->setStatus != NULL); + BM_CKFATAL(pool->unmap(pool, buf->private)); + BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, + buf->flags)); + if (!data) + goto out; + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } + } + + if (retval == 0) { + if (data) + memcpy(virtual, data, size); + + BM_CKFATAL(pool->unmap(pool, buf->private)); + } + + out: + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval; +} + +void +driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, const void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, + &virtual)); + memcpy((unsigned char *) virtual + offset, data, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); + memcpy(data, (unsigned char *) virtual + offset, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->private != NULL) { + assert((size_t)"Invalid buffer for setReferenced\n" & 0); + BM_CKFATAL(-EINVAL); + + } + if (buf->pool->reference == NULL) { + assert((size_t)"Invalid buffer pool for setReferenced\n" & 0); + BM_CKFATAL(-EINVAL); + } + buf->private = buf->pool->reference(buf->pool, handle); + if (!buf->private) { + assert((size_t)"Invalid buffer pool for setStatic\n" & 0); + BM_CKFATAL(-ENOMEM); + } + buf->createdByReference = TRUE; + buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +int +driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint) +{ + struct _DriBufferObject *buf; + int i; + + flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + ++num_buffers; + + assert(pool); + + for (i = 0; i < n; ++i) { + buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); + if (!buf) + return -ENOMEM; + + _glthread_INIT_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(buf->mutex); + buf->refCount = 1; + buf->flags = flags; + buf->hint = hint; + buf->name = name; + buf->alignment = alignment; + buf->pool = pool; + buf->createdByReference = 0; + _glthread_UNLOCK_MUTEX(buf->mutex); + buffers[i] = buf; + } + return 0; +} + +void +driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject **buffers, + void *ptr, unsigned bytes) +{ + const unsigned alignment = 1, flags = 0, hint = 0; + + --num_buffers; /* JB: is inced in GenBuffes */ + driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); + ++num_user_buffers; + + (*buffers)->userBuffer = 1; + (*buffers)->userData = ptr; + (*buffers)->userSize = bytes; +} + +void +driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) +{ + int i; + + for (i = 0; i < n; ++i) { + driBOUnReference(buffers[i]); + } +} + + +void +driInitBufMgr(int fd) +{ + ; +} + +/* + * Note that lists are per-context and don't need mutex protection. + */ + +struct _DriBufferList * +driBOCreateList(int target) +{ + struct _DriBufferList *list = calloc(sizeof(*list), 1); + + BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); + BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); + return list; +} + +int +driBOResetList(struct _DriBufferList * list) +{ + int ret; + ret = drmBOResetList(&list->drmBuffers); + if (ret) + return ret; + ret = drmBOResetList(&list->driBuffers); + return ret; +} + +void +driBOFreeList(struct _DriBufferList * list) +{ + drmBOFreeList(&list->drmBuffers); + drmBOFreeList(&list->driBuffers); + free(list); +} + + +/* + * Copied from libdrm, because it is needed by driAddValidateItem. + */ + +static drmBONode * +driAddListItem(drmBOList * list, drmBO * item, + uint64_t arg0, uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + memset(&node->bo_arg, 0, sizeof(node->bo_arg)); + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADDTAIL(&node->head, &list->list); + list->numOnList++; + return node; +} + +/* + * Slightly modified version compared to the libdrm version. + * This one returns the list index of the buffer put on the list. + */ + +static int +driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, + uint64_t mask, int *itemLoc, + struct _drmBONode **pnode) +{ + drmBONode *node, *cur; + drmMMListHead *l; + int count = 0; + + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + count++; + } + if (!cur) { + cur = driAddListItem(list, buf, flags, mask); + if (!cur) + return -ENOMEM; + + cur->arg0 = flags; + cur->arg1 = mask; + } else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + *itemLoc = count; + *pnode = cur; + return 0; +} + + +void +driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node) +{ + int newItem; + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(driAddValidateItem(&list->drmBuffers, + buf->pool->kernel(buf->pool, buf->private), + flags, mask, itemLoc, node)); + BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, + flags, mask, &newItem)); + if (newItem) + buf->refCount++; + + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +drmBOList *driGetdrmBOList(struct _DriBufferList *list) +{ + driWriteLockKernelBO(); + return &list->drmBuffers; +} + +void driPutdrmBOList(struct _DriBufferList *list) +{ + driWriteUnlockKernelBO(); +} + + +void +driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->fence) + BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + +void +driBOUnrefUserList(struct _DriBufferList *list) +{ + struct _DriBufferObject *buf; + void *curBuf; + + curBuf = drmBOListIterator(&list->driBuffers); + while (curBuf) { + buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + +struct _DriFenceObject * +driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, const char *name, + drmFence *kFence) +{ + struct _DriFenceObject *fence; + struct _DriBufferObject *buf; + void *curBuf; + + fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, + kFence, sizeof(*kFence)); + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space fencing callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + driBOFence(buf, fence); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } + + driBOResetList(list); + return fence; +} + +void +driBOValidateUserList(struct _DriBufferList * list) +{ + void *curBuf; + struct _DriBufferObject *buf; + + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space validation callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->validate) + BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); + _glthread_UNLOCK_MUTEX(buf->mutex); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + + +void +driPoolTakeDown(struct _DriBufferPool *pool) +{ + pool->takeDown(pool); + +} + +unsigned long +driBOSize(struct _DriBufferObject *buf) +{ + unsigned long size; + + _glthread_LOCK_MUTEX(buf->mutex); + size = buf->pool->size(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return size; + +} + +drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) +{ + return &list->drmBuffers; +} + +drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) +{ + return &list->driBuffers; +} + diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h new file mode 100644 index 0000000000..e6c0cff0a0 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#ifndef _PSB_BUFMGR_H_ +#define _PSB_BUFMGR_H_ +#include +#include "i915_drm.h" +#include "ws_dri_fencemgr.h" + +typedef struct _drmBONode +{ + drmMMListHead head; + drmBO *buf; + struct drm_i915_op_arg bo_arg; + uint64_t arg0; + uint64_t arg1; +} drmBONode; + +typedef struct _drmBOList { + unsigned numTarget; + unsigned numCurrent; + unsigned numOnList; + drmMMListHead list; + drmMMListHead free; +} drmBOList; + + +struct _DriFenceObject; +struct _DriBufferObject; +struct _DriBufferPool; +struct _DriBufferList; + +/* + * Return a pointer to the libdrm buffer object this DriBufferObject + * uses. + */ + +extern drmBO *driBOKernel(struct _DriBufferObject *buf); +extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, + unsigned hint); +extern void driBOUnmap(struct _DriBufferObject *buf); +extern unsigned long driBOOffset(struct _DriBufferObject *buf); +extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); + +extern uint64_t driBOFlags(struct _DriBufferObject *buf); +extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); +extern void driBOUnReference(struct _DriBufferObject *buf); + +extern int driBOData(struct _DriBufferObject *r_buf, + unsigned size, const void *data, + struct _DriBufferPool *pool, uint64_t flags); + +extern void driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + const void *data); +extern void driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + void *data); +extern int driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint); +extern void driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject *buffers[], + void *ptr, unsigned bytes); +extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); +extern void driInitBufMgr(int fd); +extern struct _DriBufferList *driBOCreateList(int target); +extern int driBOResetList(struct _DriBufferList * list); +extern void driBOAddListItem(struct _DriBufferList * list, + struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node); + +extern void driBOValidateList(int fd, struct _DriBufferList * list); +extern void driBOFreeList(struct _DriBufferList * list); +extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, + const char *name, + drmFence *kFence); +extern void driBOUnrefUserList(struct _DriBufferList *list); +extern void driBOValidateUserList(struct _DriBufferList * list); +extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); +extern void driPutdrmBOList(struct _DriBufferList *list); + +extern void driBOFence(struct _DriBufferObject *buf, + struct _DriFenceObject *fence); + +extern void driPoolTakeDown(struct _DriBufferPool *pool); +extern void driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle); +unsigned long driBOSize(struct _DriBufferObject *buf); +extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); +extern void driPoolTakeDown(struct _DriBufferPool *pool); + +extern void driReadLockKernelBO(void); +extern void driReadUnlockKernelBO(void); +extern void driWriteLockKernelBO(void); +extern void driWriteUnlockKernelBO(void); + +/* + * For debugging purposes. + */ + +extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); +extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); +#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h b/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h new file mode 100644 index 0000000000..bf60798924 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#ifndef _PSB_BUFPOOL_H_ +#define _PSB_BUFPOOL_H_ + +#include +#include +struct _DriFenceObject; + +typedef struct _DriBufferPool +{ + int fd; + int (*map) (struct _DriBufferPool * pool, void *private, + unsigned flags, int hint, _glthread_Mutex *mutex, + void **virtual); + int (*unmap) (struct _DriBufferPool * pool, void *private); + int (*destroy) (struct _DriBufferPool * pool, void *private); + unsigned long (*offset) (struct _DriBufferPool * pool, void *private); + unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); + uint64_t (*flags) (struct _DriBufferPool * pool, void *private); + unsigned long (*size) (struct _DriBufferPool * pool, void *private); + void *(*create) (struct _DriBufferPool * pool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment); + void *(*reference) (struct _DriBufferPool * pool, unsigned handle); + int (*unreference) (struct _DriBufferPool * pool, void *private); + int (*fence) (struct _DriBufferPool * pool, void *private, + struct _DriFenceObject * fence); + drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); + int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy); + int (*setStatus) (struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags); + void (*takeDown) (struct _DriBufferPool * pool); + void *data; +} DriBufferPool; + +extern void bmError(int val, const char *file, const char *function, + int line); +#define BM_CKFATAL(val) \ + do{ \ + int tstVal = (val); \ + if (tstVal) \ + bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ + } while(0); + + +/* + * Builtin pools. + */ + +/* + * Kernel buffer objects. Size in multiples of page size. Page size aligned. + */ + +extern struct _DriBufferPool *driDRMPoolInit(int fd); +extern struct _DriBufferPool *driMallocPoolInit(void); + +struct _DriFreeSlabManager; +extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan); +extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); +extern struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); + + +#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c new file mode 100644 index 0000000000..40929efa2f --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c @@ -0,0 +1,268 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "assert.h" + +/* + * Buffer pool implementation using DRM buffer objects as DRI buffer objects. + */ + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + unsigned pageSize = getpagesize(); + + if (!buf) + return NULL; + + if ((alignment > pageSize) && (alignment % pageSize)) { + free(buf); + return NULL; + } + + ret = drmBOCreate(pool->fd, size, alignment / pageSize, + NULL, + flags, hint, buf); + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static void * +pool_reference(struct _DriBufferPool *pool, unsigned handle) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + + if (!buf) + return NULL; + + ret = drmBOReference(pool->fd, handle, buf); + + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unreference(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOMap(pool->fd, buf, flags, hint, virtual); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOUnmap(pool->fd, buf); + driReadUnlockKernelBO(); + + return ret; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long offset; + + driReadLockKernelBO(); + assert(buf->flags & DRM_BO_FLAG_NO_MOVE); + offset = buf->offset; + driReadUnlockKernelBO(); + + return buf->offset; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + uint64_t flags; + + driReadLockKernelBO(); + flags = buf->flags; + driReadUnlockKernelBO(); + + return flags; +} + + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long size; + + driReadLockKernelBO(); + size = buf->size; + driReadUnlockKernelBO(); + + return buf->size; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + /* + * Noop. The kernel handles all fencing. + */ + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + return (drmBO *) private; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); + driReadUnlockKernelBO(); + + return ret; +} + + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + +/*static int +pool_setStatus(struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags) +{ + drmBO *buf = (drmBO *) private; + uint64_t new_flags = old_flags ^ flag_diff; + int ret; + + driReadLockKernelBO(); + ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, + 0, 0, 0); + driReadUnlockKernelBO(); + return ret; +}*/ + +struct _DriBufferPool * +driDRMPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->reference = &pool_reference; + pool->unreference = &pool_unreference; + pool->data = NULL; + return pool; +} diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c new file mode 100644 index 0000000000..b56bc269da --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c @@ -0,0 +1,377 @@ +#include "ws_dri_fencemgr.h" +#include "glthread.h" +#include +#include +#include + +/* + * Note: Locking order is + * _DriFenceObject::mutex + * _DriFenceMgr::mutex + */ + +struct _DriFenceMgr { + /* + * Constant members. Need no mutex protection. + */ + struct _DriFenceMgrCreateInfo info; + void *private; + + /* + * These members are protected by this->mutex + */ + _glthread_Mutex mutex; + int refCount; + drmMMListHead *heads; + int num_fences; +}; + +struct _DriFenceObject { + + /* + * These members are constant and need no mutex protection. + */ + struct _DriFenceMgr *mgr; + uint32_t fence_class; + uint32_t fence_type; + + /* + * These members are protected by mgr->mutex. + */ + drmMMListHead head; + int refCount; + + /* + * These members are protected by this->mutex. + */ + _glthread_Mutex mutex; + uint32_t signaled_type; + void *private; +}; + +uint32_t +driFenceType(struct _DriFenceObject *fence) +{ + return fence->fence_type; +} + +struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) +{ + struct _DriFenceMgr *tmp; + uint32_t i; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->refCount = 1; + tmp->info = *info; + tmp->num_fences = 0; + tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); + if (!tmp->heads) + goto out_err; + + for (i=0; iinfo.num_classes; ++i) { + DRMINITLISTHEAD(&tmp->heads[i]); + } + _glthread_UNLOCK_MUTEX(tmp->mutex); + return tmp; + + out_err: + if (tmp) + free(tmp); + return NULL; +} + +static void +driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) +{ + struct _DriFenceMgr *mgr = *pMgr; + + *pMgr = NULL; + if (--mgr->refCount == 0) + free(mgr); + else + _glthread_UNLOCK_MUTEX(mgr->mutex); +} + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr) +{ + _glthread_LOCK_MUTEX((*pMgr)->mutex); + driFenceMgrUnrefUnlock(pMgr); +} + +static void +driFenceUnReferenceLocked(struct _DriFenceObject **pFence) +{ + struct _DriFenceObject *fence = *pFence; + struct _DriFenceMgr *mgr = fence->mgr; + + *pFence = NULL; + if (--fence->refCount == 0) { + DRMLISTDELINIT(&fence->head); + if (fence->private) + mgr->info.unreference(mgr, &fence->private); + --mgr->num_fences; + fence->mgr = NULL; + --mgr->refCount; + free(fence); + + } +} + + +static void +driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, + drmMMListHead *list, + uint32_t fence_class, + uint32_t fence_type) +{ + struct _DriFenceObject *entry; + drmMMListHead *prev; + + while(list != &mgr->heads[fence_class]) { + entry = DRMLISTENTRY(struct _DriFenceObject, list, head); + + /* + * Up refcount so that entry doesn't disappear from under us + * when we unlock-relock mgr to get the correct locking order. + */ + + ++entry->refCount; + _glthread_UNLOCK_MUTEX(mgr->mutex); + _glthread_LOCK_MUTEX(entry->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + + prev = list->prev; + + + + if (list->prev == list) { + + /* + * Somebody else removed the entry from the list. + */ + + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + return; + } + + entry->signaled_type |= (fence_type & entry->fence_type); + if (entry->signaled_type == entry->fence_type) { + DRMLISTDELINIT(list); + mgr->info.unreference(mgr, &entry->private); + } + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + list = prev; + } +} + + +int +driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint) +{ + struct _DriFenceMgr *mgr = fence->mgr; + int ret = 0; + + _glthread_LOCK_MUTEX(fence->mutex); + + if ((fence->signaled_type & fence_type) == fence_type) + goto out0; + + ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); + if (ret) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + fence_type); + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) +{ + uint32_t ret; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = fence->signaled_type; + _glthread_UNLOCK_MUTEX(fence->mutex); + + return ret; +} + +int +driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, + uint32_t *signaled) +{ + int ret = 0; + struct _DriFenceMgr *mgr; + + _glthread_LOCK_MUTEX(fence->mutex); + mgr = fence->mgr; + *signaled = fence->signaled_type; + if ((fence->signaled_type & flush_type) == flush_type) + goto out0; + + ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); + if (ret) { + *signaled = fence->signaled_type; + goto out0; + } + + if ((fence->signaled_type | *signaled) == fence->signaled_type) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + *signaled); + + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +struct _DriFenceObject * +driFenceReference(struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(fence->mgr->mutex); + ++fence->refCount; + _glthread_UNLOCK_MUTEX(fence->mgr->mutex); + return fence; +} + +void +driFenceUnReference(struct _DriFenceObject **pFence) +{ + struct _DriFenceMgr *mgr; + + if (*pFence == NULL) + return; + + mgr = (*pFence)->mgr; + _glthread_LOCK_MUTEX(mgr->mutex); + ++mgr->refCount; + driFenceUnReferenceLocked(pFence); + driFenceMgrUnrefUnlock(&mgr); +} + +struct _DriFenceObject +*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, + uint32_t fence_type, void *private, size_t private_size) +{ + struct _DriFenceObject *fence; + size_t fence_size = sizeof(*fence); + + if (private_size) + fence_size = ((fence_size + 15) & ~15); + + fence = calloc(1, fence_size + private_size); + + if (!fence) { + int ret = mgr->info.finish(mgr, private, fence_type, 0); + + if (ret) + usleep(10000000); + + return NULL; + } + + _glthread_INIT_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + fence->refCount = 1; + DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); + fence->mgr = mgr; + ++mgr->refCount; + ++mgr->num_fences; + _glthread_UNLOCK_MUTEX(mgr->mutex); + fence->fence_class = fence_class; + fence->fence_type = fence_type; + fence->signaled_type = 0; + fence->private = private; + if (private_size) { + fence->private = (void *)(((uint8_t *) fence) + fence_size); + memcpy(fence->private, private, private_size); + } + + _glthread_UNLOCK_MUTEX(fence->mutex); + return fence; +} + + +static int +tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type) +{ + long fd = (long) mgr->private; + int dummy; + drmFence *fence = (drmFence *) private; + int ret; + + *signaled_type = 0; + ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); + if (ret) + return ret; + + *signaled_type = fence->signaled; + + return 0; +} + +static int +tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, + int lazy_hint) +{ + long fd = (long) mgr->private; + unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; + + return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); +} + +static int +tUnref(struct _DriFenceMgr *mgr, void **private) +{ + long fd = (long) mgr->private; + drmFence *fence = (drmFence *) *private; + *private = NULL; + + return drmFenceUnreference(fd, fence); +} + +struct _DriFenceMgr *driFenceMgrTTMInit(int fd) +{ + struct _DriFenceMgrCreateInfo info; + struct _DriFenceMgr *mgr; + + info.flags = DRI_FENCE_CLASS_ORDERED; + info.num_classes = 4; + info.signaled = tSignaled; + info.finish = tFinish; + info.unreference = tUnref; + + mgr = driFenceMgrCreate(&info); + if (mgr == NULL) + return NULL; + + mgr->private = (void *) (long) fd; + return mgr; +} + diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h new file mode 100644 index 0000000000..4ea58dfe18 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h @@ -0,0 +1,115 @@ +#ifndef DRI_FENCEMGR_H +#define DRI_FENCEMGR_H + +#include +#include + +struct _DriFenceObject; +struct _DriFenceMgr; + +/* + * Do a quick check to see if the fence manager has registered the fence + * object as signaled. Note that this function may return a false negative + * answer. + */ +extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); + +/* + * Check if the fence object is signaled. This function can be substantially + * more expensive to call than the above function, but will not return a false + * negative answer. The argument "flush_type" sets the types that the + * underlying mechanism must make sure will eventually signal. + */ +extern int driFenceSignaledType(struct _DriFenceObject *fence, + uint32_t flush_type, uint32_t *signaled); + +/* + * Convenience functions. + */ + +static inline int driFenceSignaled(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types; + int ret = driFenceSignaledType(fence, flush_type, &signaled_types); + if (ret) + return 0; + return ((signaled_types & flush_type) == flush_type); +} + +static inline int driFenceSignaledCached(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types = + driFenceSignaledTypeCached(fence); + + return ((signaled_types & flush_type) == flush_type); +} + +/* + * Reference a fence object. + */ +extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); + +/* + * Unreference a fence object. The fence object pointer will be reset to NULL. + */ + +extern void driFenceUnReference(struct _DriFenceObject **pFence); + + +/* + * Wait for a fence to signal the indicated fence_type. + * If "lazy_hint" is true, it indicates that the wait may sleep to avoid + * busy-wait polling. + */ +extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint); + +/* + * Create a DriFenceObject for manager "mgr". + * + * "private" is a pointer that should be used for the callbacks in + * struct _DriFenceMgrCreateInfo. + * + * if private_size is nonzero, then the info stored at *private, with size + * private size will be copied and the fence manager will instead use a + * pointer to the copied data for the callbacks in + * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by + * "private" may be destroyed after the call to driFenceCreate. + */ +extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, + uint32_t fence_class, + uint32_t fence_type, + void *private, + size_t private_size); + +extern uint32_t driFenceType(struct _DriFenceObject *fence); + +/* + * Fence creations are ordered. If a fence signals a fence_type, + * it is safe to assume that all fences of the same class that was + * created before that fence has signaled the same type. + */ + +#define DRI_FENCE_CLASS_ORDERED (1 << 0) + +struct _DriFenceMgrCreateInfo { + uint32_t flags; + uint32_t num_classes; + int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type); + int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); + int (*unreference) (struct _DriFenceMgr *mgr, void **private); +}; + +extern struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr); + +extern struct _DriFenceMgr * +driFenceMgrTTMInit(int fd); + +#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c new file mode 100644 index 0000000000..a80555c9c7 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c @@ -0,0 +1,161 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "pipe/p_debug.h" +#include "glthread.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + unsigned long *private = malloc(size + 2*sizeof(unsigned long)); + if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) + abort(); + + *private = size; + return (void *)private; +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + free(private); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + *virtual = (void *)((unsigned long *)private + 2); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); + return 0UL; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + return *(unsigned long *) private; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + abort(); + return 0UL; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + abort(); + return NULL; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + + +struct _DriBufferPool * +driMallocPoolInit(void) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = NULL; + pool->fd = -1; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c new file mode 100644 index 0000000000..dfcf6d6b19 --- /dev/null +++ b/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c @@ -0,0 +1,968 @@ +/************************************************************************** + * + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include +#include +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" +#include "ws_dri_bufmgr.h" +#include "glthread.h" + +#define DRI_SLABPOOL_ALLOC_RETRIES 100 + +struct _DriSlab; + +struct _DriSlabBuffer { + int isSlabBuffer; + drmBO *bo; + struct _DriFenceObject *fence; + struct _DriSlab *parent; + drmMMListHead head; + uint32_t mapCount; + uint32_t start; + uint32_t fenceType; + int unFenced; + _glthread_Cond event; +}; + +struct _DriKernelBO { + int fd; + drmBO bo; + drmMMListHead timeoutHead; + drmMMListHead head; + struct timeval timeFreed; + uint32_t pageAlignment; + void *virtual; +}; + +struct _DriSlab{ + drmMMListHead head; + drmMMListHead freeBuffers; + uint32_t numBuffers; + uint32_t numFree; + struct _DriSlabBuffer *buffers; + struct _DriSlabSizeHeader *header; + struct _DriKernelBO *kbo; +}; + + +struct _DriSlabSizeHeader { + drmMMListHead slabs; + drmMMListHead freeSlabs; + drmMMListHead delayedBuffers; + uint32_t numDelayed; + struct _DriSlabPool *slabPool; + uint32_t bufSize; + _glthread_Mutex mutex; +}; + +struct _DriFreeSlabManager { + struct timeval slabTimeout; + struct timeval checkInterval; + struct timeval nextCheck; + drmMMListHead timeoutList; + drmMMListHead unCached; + drmMMListHead cached; + _glthread_Mutex mutex; +}; + + +struct _DriSlabPool { + + /* + * The data of this structure remains constant after + * initialization and thus needs no mutex protection. + */ + + struct _DriFreeSlabManager *fMan; + uint64_t proposedFlags; + uint64_t validMask; + uint32_t *bucketSizes; + uint32_t numBuckets; + uint32_t pageSize; + int fd; + int pageAlignment; + int maxSlabSize; + int desiredNumBuffers; + struct _DriSlabSizeHeader *headers; +}; + +/* + * FIXME: Perhaps arrange timeout slabs in size buckets for fast + * retreival?? + */ + + +static inline int +driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) +{ + return ((arg1->tv_sec > arg2->tv_sec) || + ((arg1->tv_sec == arg2->tv_sec) && + (arg1->tv_usec > arg2->tv_usec))); +} + +static inline void +driTimeAdd(struct timeval *arg, struct timeval *add) +{ + unsigned int sec; + + arg->tv_sec += add->tv_sec; + arg->tv_usec += add->tv_usec; + sec = arg->tv_usec / 1000000; + arg->tv_sec += sec; + arg->tv_usec -= sec*1000000; +} + +static void +driFreeKernelBO(struct _DriKernelBO *kbo) +{ + if (!kbo) + return; + + (void) drmBOUnreference(kbo->fd, &kbo->bo); + free(kbo); +} + + +static void +driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, + struct timeval *time) +{ + drmMMListHead *list, *next; + struct _DriKernelBO *kbo; + + if (!driTimeAfterEq(time, &fMan->nextCheck)) + return; + + for (list = fMan->timeoutList.next, next = list->next; + list != &fMan->timeoutList; + list = next, next = list->next) { + + kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); + + if (!driTimeAfterEq(time, &kbo->timeFreed)) + break; + + DRMLISTDELINIT(&kbo->timeoutHead); + DRMLISTDELINIT(&kbo->head); + driFreeKernelBO(kbo); + } + + fMan->nextCheck = *time; + driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); +} + + +/* + * Add a _DriKernelBO to the free slab manager. + * This means that it is available for reuse, but if it's not + * reused in a while, it will be freed. + */ + +static void +driSetKernelBOFree(struct _DriFreeSlabManager *fMan, + struct _DriKernelBO *kbo) +{ + struct timeval time; + + _glthread_LOCK_MUTEX(fMan->mutex); + gettimeofday(&time, NULL); + driTimeAdd(&time, &fMan->slabTimeout); + + kbo->timeFreed = time; + + if (kbo->bo.flags & DRM_BO_FLAG_CACHED) + DRMLISTADD(&kbo->head, &fMan->cached); + else + DRMLISTADD(&kbo->head, &fMan->unCached); + + DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); + driFreeTimeoutKBOsLocked(fMan, &time); + + _glthread_UNLOCK_MUTEX(fMan->mutex); +} + +/* + * Get a _DriKernelBO for us to use as storage for a slab. + * + */ + +static struct _DriKernelBO * +driAllocKernelBO(struct _DriSlabSizeHeader *header) + +{ + struct _DriSlabPool *slabPool = header->slabPool; + struct _DriFreeSlabManager *fMan = slabPool->fMan; + drmMMListHead *list, *next, *head; + uint32_t size = header->bufSize * slabPool->desiredNumBuffers; + struct _DriKernelBO *kbo; + struct _DriKernelBO *kboTmp; + int ret; + + /* + * FIXME: We should perhaps allow some variation in slabsize in order + * to efficiently reuse slabs. + */ + + size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; + size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); + _glthread_LOCK_MUTEX(fMan->mutex); + + kbo = NULL; + + retry: + head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? + &fMan->cached : &fMan->unCached; + + for (list = head->next, next = list->next; + list != head; + list = next, next = list->next) { + + kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); + + if ((kboTmp->bo.size == size) && + (slabPool->pageAlignment == 0 || + (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { + + if (!kbo) + kbo = kboTmp; + + if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) + break; + + } + } + + if (kbo) { + DRMLISTDELINIT(&kbo->head); + DRMLISTDELINIT(&kbo->timeoutHead); + } + + _glthread_UNLOCK_MUTEX(fMan->mutex); + + if (kbo) { + uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; + + ret = 0; + if (new_mask) { + ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, + new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); + } + if (ret == 0) + return kbo; + + driFreeKernelBO(kbo); + kbo = NULL; + goto retry; + } + + kbo = calloc(1, sizeof(struct _DriKernelBO)); + if (!kbo) + return NULL; + + kbo->fd = slabPool->fd; + DRMINITLISTHEAD(&kbo->head); + DRMINITLISTHEAD(&kbo->timeoutHead); + ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, + slabPool->proposedFlags, + DRM_BO_HINT_DONT_FENCE, &kbo->bo); + if (ret) + goto out_err0; + + ret = drmBOMap(kbo->fd, &kbo->bo, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &kbo->virtual); + + if (ret) + goto out_err1; + + ret = drmBOUnmap(kbo->fd, &kbo->bo); + if (ret) + goto out_err1; + + return kbo; + + out_err1: + drmBOUnreference(kbo->fd, &kbo->bo); + out_err0: + free(kbo); + return NULL; +} + + +static int +driAllocSlab(struct _DriSlabSizeHeader *header) +{ + struct _DriSlab *slab; + struct _DriSlabBuffer *buf; + uint32_t numBuffers; + int ret; + int i; + + slab = calloc(1, sizeof(*slab)); + if (!slab) + return -ENOMEM; + + slab->kbo = driAllocKernelBO(header); + if (!slab->kbo) { + ret = -ENOMEM; + goto out_err0; + } + + numBuffers = slab->kbo->bo.size / header->bufSize; + + slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); + if (!slab->buffers) { + ret = -ENOMEM; + goto out_err1; + } + + DRMINITLISTHEAD(&slab->head); + DRMINITLISTHEAD(&slab->freeBuffers); + slab->numBuffers = numBuffers; + slab->numFree = 0; + slab->header = header; + + buf = slab->buffers; + for (i=0; i < numBuffers; ++i) { + buf->parent = slab; + buf->start = i* header->bufSize; + buf->mapCount = 0; + buf->isSlabBuffer = 1; + _glthread_INIT_COND(buf->event); + DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); + slab->numFree++; + buf++; + } + + DRMLISTADDTAIL(&slab->head, &header->slabs); + + return 0; + + out_err1: + driSetKernelBOFree(header->slabPool->fMan, slab->kbo); + free(slab->buffers); + out_err0: + free(slab); + return ret; +} + +/* + * Delete a buffer from the slab header delayed list and put + * it on the slab free list. + */ + +static void +driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) +{ + struct _DriSlab *slab = buf->parent; + struct _DriSlabSizeHeader *header = slab->header; + drmMMListHead *list = &buf->head; + + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &slab->freeBuffers); + slab->numFree++; + + if (slab->head.next == &slab->head) + DRMLISTADDTAIL(&slab->head, &header->slabs); + + if (slab->numFree == slab->numBuffers) { + list = &slab->head; + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &header->freeSlabs); + } + + if (header->slabs.next == &header->slabs || + slab->numFree != slab->numBuffers) { + + drmMMListHead *next; + struct _DriFreeSlabManager *fMan = header->slabPool->fMan; + + for (list = header->freeSlabs.next, next = list->next; + list != &header->freeSlabs; + list = next, next = list->next) { + + slab = DRMLISTENTRY(struct _DriSlab, list, head); + + DRMLISTDELINIT(list); + driSetKernelBOFree(fMan, slab->kbo); + free(slab->buffers); + free(slab); + } + } +} + +static void +driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) +{ + drmMMListHead *list, *prev, *first; + struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + int firstWasSignaled = 1; + int signaled; + int i; + int ret; + + /* + * Rerun the freeing test if the youngest tested buffer + * was signaled, since there might be more idle buffers + * in the delay list. + */ + + while (firstWasSignaled) { + firstWasSignaled = 0; + signaled = 0; + first = header->delayedBuffers.next; + + /* Only examine the oldest 1/3 of delayed buffers: + */ + if (header->numDelayed > 3) { + for (i = 0; i < header->numDelayed; i += 3) { + first = first->next; + } + } + + for (list = first, prev = list->prev; + list != &header->delayedBuffers; + list = prev, prev = list->prev) { + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + slab = buf->parent; + + if (!signaled) { + if (wait) { + ret = driFenceFinish(buf->fence, buf->fenceType, 0); + if (ret) + break; + signaled = 1; + wait = 0; + } else { + signaled = driFenceSignaled(buf->fence, buf->fenceType); + } + if (signaled) { + if (list == first) + firstWasSignaled = 1; + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } + } +} + + +static struct _DriSlabBuffer * +driSlabAllocBuffer(struct _DriSlabSizeHeader *header) +{ + static struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + drmMMListHead *list; + int count = DRI_SLABPOOL_ALLOC_RETRIES; + + _glthread_LOCK_MUTEX(header->mutex); + while(header->slabs.next == &header->slabs && count > 0) { + driSlabCheckFreeLocked(header, 0); + if (header->slabs.next != &header->slabs) + break; + + _glthread_UNLOCK_MUTEX(header->mutex); + if (count != DRI_SLABPOOL_ALLOC_RETRIES) + usleep(1); + _glthread_LOCK_MUTEX(header->mutex); + (void) driAllocSlab(header); + count--; + } + + list = header->slabs.next; + if (list == &header->slabs) { + _glthread_UNLOCK_MUTEX(header->mutex); + return NULL; + } + slab = DRMLISTENTRY(struct _DriSlab, list, head); + if (--slab->numFree == 0) + DRMLISTDELINIT(list); + + list = slab->freeBuffers.next; + DRMLISTDELINIT(list); + + _glthread_UNLOCK_MUTEX(header->mutex); + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + return buf; +} + +static void * +pool_create(struct _DriBufferPool *driPool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment) +{ + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + struct _DriSlabSizeHeader *header; + struct _DriSlabBuffer *buf; + void *dummy; + int i; + int ret; + + /* + * FIXME: Check for compatibility. + */ + + header = pool->headers; + for (i=0; inumBuckets; ++i) { + if (header->bufSize >= size) + break; + header++; + } + + if (i < pool->numBuckets) + return driSlabAllocBuffer(header); + + + /* + * Fall back to allocate a buffer object directly from DRM. + * and wrap it in a driBO structure. + */ + + + buf = calloc(1, sizeof(*buf)); + + if (!buf) + return NULL; + + buf->bo = calloc(1, sizeof(*buf->bo)); + if (!buf->bo) + goto out_err0; + + if (alignment) { + if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) + goto out_err1; + if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) + goto out_err1; + } + + ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, + flags, hint, buf->bo); + if (ret) + goto out_err1; + + ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &dummy); + if (ret) + goto out_err2; + + ret = drmBOUnmap(pool->fd, buf->bo); + if (ret) + goto out_err2; + + return buf; + out_err2: + drmBOUnreference(pool->fd, buf->bo); + out_err1: + free(buf->bo); + out_err0: + free(buf); + return NULL; +} + +static int +pool_destroy(struct _DriBufferPool *driPool, void *private) +{ + struct _DriSlabBuffer *buf = + (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + int ret; + + ret = drmBOUnreference(pool->fd, buf->bo); + free(buf->bo); + free(buf); + return ret; + } + + slab = buf->parent; + header = slab->header; + + _glthread_LOCK_MUTEX(header->mutex); + buf->unFenced = 0; + buf->mapCount = 0; + + if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { + DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); + header->numDelayed++; + } else { + if (buf->fence) + driFenceUnReference(&buf->fence); + driSlabFreeBufferLocked(buf); + } + + _glthread_UNLOCK_MUTEX(header->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *driPool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + while(buf->unFenced) + _glthread_COND_WAIT(buf->event, *mutex); + + if (!buf->fence) + return 0; + + driFenceFinish(buf->fence, buf->fenceType, lazy); + driFenceUnReference(&buf->fence); + + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + int busy; + + if (buf->isSlabBuffer) + busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); + else + busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); + + + if (busy) { + if (hint & DRM_BO_HINT_DONT_BLOCK) + return -EBUSY; + else { + (void) pool_waitIdle(pool, private, mutex, 0); + } + } + + ++buf->mapCount; + *virtual = (buf->isSlabBuffer) ? + (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : + (void *) buf->bo->virtual; + + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + --buf->mapCount; + if (buf->mapCount == 0 && buf->isSlabBuffer) + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return buf->bo->offset; + } + + slab = buf->parent; + header = slab->header; + + (void) header; + assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return slab->kbo->bo.offset + buf->start; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return buf->start; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return buf->bo->flags; + + return buf->parent->kbo->bo.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + if (!buf->isSlabBuffer) + return buf->bo->size; + + return buf->parent->header->bufSize; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + drmBO *bo; + + if (buf->fence) + driFenceUnReference(&buf->fence); + + buf->fence = driFenceReference(fence); + bo = (buf->isSlabBuffer) ? + &buf->parent->kbo->bo: + buf->bo; + buf->fenceType = bo->fenceFlags; + + buf->unFenced = 0; + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return 0; + + while(buf->mapCount != 0) + _glthread_COND_WAIT(buf->event, *mutex); + + buf->unFenced = 1; + return 0; +} + + +struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) +{ + struct _DriFreeSlabManager *tmp; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; + tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; + tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; + + tmp->checkInterval.tv_usec = checkIntervalMsec*1000; + tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; + tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; + + gettimeofday(&tmp->nextCheck, NULL); + driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); + DRMINITLISTHEAD(&tmp->timeoutList); + DRMINITLISTHEAD(&tmp->unCached); + DRMINITLISTHEAD(&tmp->cached); + _glthread_UNLOCK_MUTEX(tmp->mutex); + + return tmp; +} + +void +driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) +{ + struct timeval time; + + time = fMan->nextCheck; + driTimeAdd(&time, &fMan->checkInterval); + + _glthread_LOCK_MUTEX(fMan->mutex); + driFreeTimeoutKBOsLocked(fMan, &time); + _glthread_UNLOCK_MUTEX(fMan->mutex); + + assert(fMan->timeoutList.next == &fMan->timeoutList); + assert(fMan->unCached.next == &fMan->unCached); + assert(fMan->cached.next == &fMan->cached); + + free(fMan); +} + +static void +driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, + struct _DriSlabSizeHeader *header) +{ + _glthread_INIT_MUTEX(header->mutex); + _glthread_LOCK_MUTEX(header->mutex); + + DRMINITLISTHEAD(&header->slabs); + DRMINITLISTHEAD(&header->freeSlabs); + DRMINITLISTHEAD(&header->delayedBuffers); + + header->numDelayed = 0; + header->slabPool = pool; + header->bufSize = size; + + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +driFinishSizeHeader(struct _DriSlabSizeHeader *header) +{ + drmMMListHead *list, *next; + struct _DriSlabBuffer *buf; + + _glthread_LOCK_MUTEX(header->mutex); + for (list = header->delayedBuffers.next, next = list->next; + list != &header->delayedBuffers; + list = next, next = list->next) { + + buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); + if (buf->fence) { + (void) driFenceFinish(buf->fence, buf->fenceType, 0); + driFenceUnReference(&buf->fence); + } + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +pool_takedown(struct _DriBufferPool *driPool) +{ + struct _DriSlabPool *pool = driPool->data; + int i; + + for (i=0; inumBuckets; ++i) { + driFinishSizeHeader(&pool->headers[i]); + } + + free(pool->headers); + free(pool->bucketSizes); + free(pool); + free(driPool); +} + +struct _DriBufferPool * +driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan) +{ + struct _DriBufferPool *driPool; + struct _DriSlabPool *pool; + uint32_t i; + + driPool = calloc(1, sizeof(*driPool)); + if (!driPool) + return NULL; + + pool = calloc(1, sizeof(*pool)); + if (!pool) + goto out_err0; + + pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); + if (!pool->bucketSizes) + goto out_err1; + + pool->headers = calloc(numSizes, sizeof(*pool->headers)); + if (!pool->headers) + goto out_err2; + + pool->fMan = fMan; + pool->proposedFlags = flags; + pool->validMask = validMask; + pool->numBuckets = numSizes; + pool->pageSize = getpagesize(); + pool->fd = fd; + pool->pageAlignment = pageAlignment; + pool->maxSlabSize = maxSlabSize; + pool->desiredNumBuffers = desiredNumBuffers; + + for (i=0; inumBuckets; ++i) { + pool->bucketSizes[i] = (smallestSize << i); + driInitSizeHeader(pool, pool->bucketSizes[i], + &pool->headers[i]); + } + + driPool->data = (void *) pool; + driPool->map = &pool_map; + driPool->unmap = &pool_unmap; + driPool->destroy = &pool_destroy; + driPool->offset = &pool_offset; + driPool->poolOffset = &pool_poolOffset; + driPool->flags = &pool_flags; + driPool->size = &pool_size; + driPool->create = &pool_create; + driPool->fence = &pool_fence; + driPool->kernel = &pool_kernel; + driPool->validate = &pool_validate; + driPool->waitIdle = &pool_waitIdle; + driPool->takeDown = &pool_takedown; + + return driPool; + + out_err2: + free(pool->bucketSizes); + out_err1: + free(pool); + out_err0: + free(driPool); + + return NULL; +} diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 3bc1fdd4d4..07abfa53f3 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -54,6 +54,7 @@ SHARED_INCLUDES = \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys/common \ -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/main \ -I$(TOP)/src/mesa/glapi \ diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index c0ce2f927b..00ce21f690 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -4,26 +4,17 @@ include $(TOP)/configs/current LIBNAME = i915_dri.so -MINIGLX_SOURCES = server/intel_dri.c - PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ + $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a DRIVER_SOURCES = \ - intel_winsys_pipe.c \ intel_winsys_softpipe.c \ - intel_winsys_i915.c \ - intel_batchbuffer.c \ intel_swapbuffers.c \ intel_context.c \ intel_lock.c \ - intel_screen.c \ - ws_dri_bufmgr.c \ - ws_dri_drmpool.c \ - ws_dri_fencemgr.c \ - ws_dri_mallocpool.c \ - ws_dri_slabpool.c + intel_screen.c C_SOURCES = \ $(COMMON_GALLIUM_SOURCES) \ @@ -36,6 +27,6 @@ DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm - include ../Makefile.template -intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c +#intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c symlinks: diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c deleted file mode 100644 index aa33c12045..0000000000 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c +++ /dev/null @@ -1,462 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "intel_batchbuffer.h" -#include "intel_context.h" -#include - -#if 0 -static void -intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) -{ - int i; - fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); - for (i = 0; i < count / 4; i += 4) - fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", - offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); - fprintf(stderr, "END BATCH\n\n\n"); -} -#endif - -static void -intel_realloc_relocs(struct intel_batchbuffer *batch, int num_relocs) -{ - unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; - - size *= sizeof(uint32_t); - batch->reloc = realloc(batch->reloc, size); - batch->reloc_size = num_relocs; -} - - -void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) -{ - /* - * Get a new, free batchbuffer. - */ - drmBO *bo; - struct drm_bo_info_req *req; - - driBOUnrefUserList(batch->list); - driBOResetList(batch->list); - - /* base.size is the size available to the i915simple driver */ - batch->base.size = batch->intel->intelScreen->max_batch_size - BATCH_RESERVED; - batch->base.actual_size = batch->intel->intelScreen->max_batch_size; - driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0); - - /* - * Add the batchbuffer to the validate list. - */ - - driBOAddListItem(batch->list, batch->buffer, - DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, - &batch->dest_location, &batch->node); - - req = &batch->node->bo_arg.d.req.bo_req; - - /* - * Set up information needed for us to make relocations - * relative to the underlying drm buffer objects. - */ - - driReadLockKernelBO(); - bo = driBOKernel(batch->buffer); - req->presumed_offset = (uint64_t) bo->offset; - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - batch->drmBOVirtual = (uint8_t *) bo->virtual; - driReadUnlockKernelBO(); - - /* - * Adjust the relocation buffer size. - */ - - if (batch->reloc_size > INTEL_MAX_RELOCS || - batch->reloc == NULL) - intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); - - assert(batch->reloc != NULL); - batch->reloc[0] = 0; /* No relocs yet. */ - batch->reloc[1] = 1; /* Reloc type 1 */ - batch->reloc[2] = 0; /* Only a single relocation list. */ - batch->reloc[3] = 0; /* Only a single relocation list. */ - - batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); - batch->poolOffset = driBOPoolOffset(batch->buffer); - batch->base.ptr = batch->base.map; - batch->dirty_state = ~0; - batch->nr_relocs = 0; - batch->flags = 0; - batch->id = 0;//batch->intel->intelScreen->batch_id++; -} - -/*====================================================================== - * Public functions - */ -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_context *intel) -{ - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel = intel; - - driGenBuffers(intel->intelScreen->batchPool, "batchbuffer", 1, - &batch->buffer, 4096, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); - batch->last_fence = NULL; - batch->list = driBOCreateList(20); - batch->reloc = NULL; - intel_batchbuffer_reset(batch); - return batch; -} - -void -intel_batchbuffer_free(struct intel_batchbuffer *batch) -{ - if (batch->last_fence) { - driFenceFinish(batch->last_fence, - DRM_FENCE_TYPE_EXE, GL_FALSE); - driFenceUnReference(&batch->last_fence); - } - if (batch->base.map) { - driBOUnmap(batch->buffer); - batch->base.map = NULL; - } - driBOUnReference(batch->buffer); - driBOFreeList(batch->list); - if (batch->reloc) - free(batch->reloc); - batch->buffer = NULL; - free(batch); -} - -void -intel_offset_relocation(struct intel_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask) -{ - int itemLoc; - struct _drmBONode *node; - uint32_t *reloc; - struct drm_bo_info_req *req; - - driBOAddListItem(batch->list, driBO, val_flags, val_mask, - &itemLoc, &node); - req = &node->bo_arg.d.req.bo_req; - - if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { - - /* - * Stop other threads from tampering with the underlying - * drmBO while we're reading its offset. - */ - - driReadLockKernelBO(); - req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; - driReadUnlockKernelBO(); - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - } - - pre_add += driBOPoolOffset(driBO); - - if (batch->nr_relocs == batch->reloc_size) - intel_realloc_relocs(batch, batch->reloc_size * 2); - - reloc = batch->reloc + - (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); - - reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual); - intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add); - reloc[1] = pre_add; - reloc[2] = itemLoc; - reloc[3] = batch->dest_location; - batch->nr_relocs++; -} - -static void -i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) -{ - buf->handle = rep->handle; - buf->flags = rep->flags; - buf->size = rep->size; - buf->offset = rep->offset; - buf->mapHandle = rep->arg_handle; - buf->proposedFlags = rep->proposed_flags; - buf->start = rep->buffer_start; - buf->fenceFlags = rep->fence_flags; - buf->replyFlags = rep->rep_flags; - buf->pageAlignment = rep->page_alignment; -} - -static int -i915_execbuf(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, - drmBOList *list, - struct drm_i915_execbuffer *ea) -{ - struct intel_context *intel = batch->intel; - drmBONode *node; - drmMMListHead *l; - struct drm_i915_op_arg *arg, *first; - struct drm_bo_op_req *req; - struct drm_bo_info_rep *rep; - uint64_t *prevNext = NULL; - drmBO *buf; - int ret = 0; - uint32_t count = 0; - - first = NULL; - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - - arg = &node->bo_arg; - req = &arg->d.req; - - if (!first) - first = arg; - - if (prevNext) - *prevNext = (unsigned long)arg; - - prevNext = &arg->next; - req->bo_req.handle = node->buf->handle; - req->op = drm_bo_validate; - req->bo_req.flags = node->arg0; - req->bo_req.mask = node->arg1; - req->bo_req.hint |= 0; - count++; - } - - memset(ea, 0, sizeof(*ea)); - ea->num_buffers = count; - ea->batch.start = batch->poolOffset; - ea->batch.used = used; -#if 0 /* ZZZ JB: no cliprects used */ - ea->batch.cliprects = intel->pClipRects; - ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | - (((GLuint) intel->drawY) << 16)); -#else - ea->batch.cliprects = NULL; - ea->batch.num_cliprects = 0; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0; -#endif - ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; - ea->ops_list = (unsigned long) first; - first->reloc_ptr = (unsigned long) batch->reloc; - batch->reloc[0] = batch->nr_relocs; - - //return -EFAULT; - do { - ret = drmCommandWriteRead(intel->driFd, DRM_I915_EXECBUFFER, ea, - sizeof(*ea)); - } while (ret == -EAGAIN); - - if (ret != 0) - return ret; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - arg = &node->bo_arg; - rep = &arg->d.rep.bo_info; - - if (!arg->handled) { - return -EFAULT; - } - if (arg->d.rep.ret) - return arg->d.rep.ret; - - buf = node->buf; - i915_drm_copy_reply(rep, buf); - } - return 0; -} - -/* TODO: Push this whole function into bufmgr. - */ -static struct _DriFenceObject * -do_flush_locked(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - struct intel_context *intel = batch->intel; - struct _DriFenceObject *fo; - drmFence fence; - drmBOList *boList; - struct drm_i915_execbuffer ea; - int ret = 0; - - driBOValidateUserList(batch->list); - boList = driGetdrmBOList(batch->list); - -#if 0 /* ZZZ JB Allways run */ - if (!(intel->numClipRects == 0 && !ignore_cliprects)) { -#else - if (1) { -#endif - ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); - } else { - driPutdrmBOList(batch->list); - fo = NULL; - goto out; - } - driPutdrmBOList(batch->list); - if (ret) - abort(); - - if (ea.fence_arg.error != 0) { - - /* - * The hardware has been idled by the kernel. - * Don't fence the driBOs. - */ - - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); -#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ - _mesa_printf("fence error\n"); -#endif - batch->last_fence = NULL; - fo = NULL; - goto out; - } - - fence.handle = ea.fence_arg.handle; - fence.fence_class = ea.fence_arg.fence_class; - fence.type = ea.fence_arg.type; - fence.flags = ea.fence_arg.flags; - fence.signaled = ea.fence_arg.signaled; - - fo = driBOFenceUserList(batch->intel->intelScreen->mgr, batch->list, - "SuperFence", &fence); - - if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); - /* - * FIXME: Context last fence?? - */ - batch->last_fence = fo; - driFenceReference(fo); - } - out: -#if 0 /* ZZZ JB: fix this */ - intel->vtbl.lost_hardware(intel); -#else - (void)intel; -#endif - return fo; -} - - -struct _DriFenceObject * -intel_batchbuffer_flush(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - GLuint used = batch->base.ptr - batch->base.map; - GLboolean was_locked = intel->locked; - struct _DriFenceObject *fence; - - if (used == 0) { - driFenceReference(batch->last_fence); - return batch->last_fence; - } - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a - * performance drain that we would like to avoid. - */ -#if 0 /* ZZZ JB: what should we do here? */ - if (used & 4) { - ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->base.ptr)[1] = 0; - ((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END; - used += 8; - } -#else - if (used & 4) { - ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->base.ptr)[1] = 0; - ((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 8; - } -#endif - driBOUnmap(batch->buffer); - batch->base.ptr = NULL; - batch->base.map = NULL; - - /* TODO: Just pass the relocation list and dma buffer up to the - * kernel. - */ - if (!was_locked) - LOCK_HARDWARE(intel); - - fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), - GL_FALSE); - - if (!was_locked) - UNLOCK_HARDWARE(intel); - - /* Reset the buffer: - */ - intel_batchbuffer_reset(batch); - return fence; -} - -void -intel_batchbuffer_finish(struct intel_batchbuffer *batch) -{ - struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); - driFenceFinish(fence, driFenceType(fence), GL_FALSE); - driFenceUnReference(&fence); -} - -void -intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags) -{ - assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, flags); - memcpy(batch->base.ptr, data, bytes); - batch->base.ptr += bytes; -} diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h index abb7a624f5..1fa2719845 100644 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h @@ -1,137 +1,24 @@ #ifndef INTEL_BATCHBUFFER_H #define INTEL_BATCHBUFFER_H -#include "mtypes.h" -#include "ws_dri_bufmgr.h" -#include "i915simple/i915_batch.h" +#include "intel_drm/intel_be_batchbuffer.h" -struct intel_context; - -#define BATCH_SZ 16384 -#define BATCH_RESERVED 16 - -#define INTEL_DEFAULT_RELOCS 100 -#define INTEL_MAX_RELOCS 400 - -#define INTEL_BATCH_NO_CLIPRECTS 0x1 -#define INTEL_BATCH_CLIPRECTS 0x2 - -struct intel_batchbuffer -{ - struct i915_batchbuffer base; - - struct intel_context *intel; - - struct _DriBufferObject *buffer; - struct _DriFenceObject *last_fence; - GLuint flags; - - struct _DriBufferList *list; - GLuint list_count; - - uint32_t *reloc; - GLuint reloc_size; - GLuint nr_relocs; - - GLuint dirty_state; - GLuint id; - - uint32_t poolOffset; - uint8_t *drmBOVirtual; - struct _drmBONode *node; /* Validation list node for this buffer */ - int dest_location; /* Validation list sequence for this buffer */ -}; - -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context - *intel); - -void intel_batchbuffer_free(struct intel_batchbuffer *batch); - - -void intel_batchbuffer_finish(struct intel_batchbuffer *batch); - -struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer - *batch); - -void intel_batchbuffer_reset(struct intel_batchbuffer *batch); - - -/* Unlike bmBufferData, this currently requires the buffer be mapped. - * Consider it a convenience function wrapping multple - * intel_buffer_dword() calls. - */ -void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags); - -void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - GLuint bytes); - -void -intel_offset_relocation(struct intel_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask); - -/* Inline functions - might actually be better off with these - * non-inlined. Certainly better off switching all command packets to - * be passed as structs rather than dwords, but that's a little bit of - * work... - */ -static INLINE GLuint -intel_batchbuffer_space(struct intel_batchbuffer *batch) -{ - return (batch->base.size - BATCH_RESERVED) - (batch->base.ptr - batch->base.map); -} - - -static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) -{ - assert(batch->base.map); - assert(intel_batchbuffer_space(batch) >= 4); - *(GLuint *) (batch->base.ptr) = dword; - batch->base.ptr += 4; -} - -static INLINE void -intel_batchbuffer_require_space(struct intel_batchbuffer *batch, - GLuint sz, GLuint flags) -{ - struct _DriFenceObject *fence; - - assert(sz < batch->base.size - 8); - if (intel_batchbuffer_space(batch) < sz || - (batch->flags != 0 && flags != 0 && batch->flags != flags)) { - fence = intel_batchbuffer_flush(batch); - driFenceUnReference(&fence); - } - - batch->flags |= flags; -} - -/* Here are the crusty old macros, to be removed: +/* + * Need to redefine the BATCH defines */ -#undef BATCH_LOCALS -#define BATCH_LOCALS #undef BEGIN_BATCH -#define BEGIN_BATCH(n, flags) do { \ - assert(!intel->prim.flush); \ - intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ -} while (0) +#define BEGIN_BATCH(dwords, relocs) \ + (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) #undef OUT_BATCH -#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) +#define OUT_BATCH(d) \ + i915_batchbuffer_dword(&intel->base.batch->base, d) #undef OUT_RELOC -#define OUT_RELOC(buf,flags,mask,delta) do { \ +#define OUT_RELOC(buf,flags,mask,delta) do { \ assert((delta) >= 0); \ - intel_offset_relocation(intel->batch, delta, buf, flags, mask); \ + intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ } while (0) -#undef ADVANCE_BATCH -#define ADVANCE_BATCH() do { } while(0) - - #endif diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 6a0c381849..8284e0edbb 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ @@ -31,8 +31,10 @@ #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" -#include "intel_winsys.h" #include "intel_batchbuffer.h" +#include "intel_winsys_softpipe.h" + +#include "i915simple/i915_screen.h" #include "state_tracker/st_public.h" #include "state_tracker/st_context.h" @@ -132,6 +134,46 @@ static const struct dri_debug_control debug_control[] = { +/** + * Create i915 hardware rendering context. + */ +static struct pipe_context * +intel_create_i915simple(struct intel_context *intel, + struct pipe_winsys *winsys) +{ + struct pipe_screen *screen; + + /* Fill in this struct with callbacks that i915simple will need to + * communicate with the window system, buffer manager, etc. + */ + screen = i915_create_screen(winsys, intel->intelScreen->deviceID); + + /* Create the i915simple context: + */ + return i915_create_context(screen, winsys, &intel->base.base ); +} + +static void +intel_lock_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + LOCK_HARDWARE(intel); +} + +static void +intel_unlock_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + UNLOCK_HARDWARE(intel); +} + +static boolean +intel_locked_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + return intel->locked ? TRUE : FALSE; +} + GLboolean intelCreateContext(const __GLcontextModes * visual, __DRIcontextPrivate * driContextPriv, @@ -179,20 +221,24 @@ intelCreateContext(const __GLcontextModes * visual, intel->iw.irq_seq = -1; intel->irqsEmitted = 0; - intel->batch = intel_batchbuffer_alloc(intel); intel->last_swap_fence = NULL; intel->first_swap_fence = NULL; #ifdef DEBUG __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); #endif + intel->base.hardware_lock = intel_lock_hardware; + intel->base.hardware_unlock = intel_unlock_hardware; + intel->base.hardware_locked = intel_locked_hardware; + + intel_be_init_context(&intel->base, &intelScreen->base); /* * Pipe-related setup */ if (getenv("INTEL_SP")) { /* use softpipe driver instead of hw */ - pipe = intel_create_softpipe( intel, intelScreen->winsys ); + pipe = intel_create_softpipe( intel, &intelScreen->base.base ); } else { switch (intel->intelScreen->deviceID) { @@ -204,13 +250,13 @@ intelCreateContext(const __GLcontextModes * visual, case PCI_CHIP_Q35_G: case PCI_CHIP_I915_G: case PCI_CHIP_I915_GM: - pipe = intel_create_i915simple( intel, intelScreen->winsys ); + pipe = intel_create_i915simple( intel, &intelScreen->base.base ); break; default: - fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", + fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", intel->intelScreen->deviceID, __FUNCTION__); - pipe = intel_create_softpipe( intel, intelScreen->winsys ); + pipe = intel_create_softpipe( intel, &intelScreen->base.base ); break; } } @@ -234,8 +280,6 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) if (intel) { st_finish(intel->st); - intel_batchbuffer_free(intel->batch); - if (intel->last_swap_fence) { driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); driFenceUnReference(&intel->last_swap_fence); @@ -251,6 +295,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) intel->intelScreen->dummyContext = NULL; st_destroy_context(intel->st); + intel_be_destroy_context(&intel->base); free(intel); } } diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h index 597dc13830..ced18da143 100644 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #ifndef INTEL_CONTEXT_H @@ -36,6 +36,8 @@ #include "intel_screen.h" #include "i915_drm.h" +#include "intel_drm/intel_be_context.h" + struct pipe_context; struct intel_context; @@ -50,12 +52,13 @@ struct st_context; */ struct intel_context { + struct intel_be_context base; struct st_context *st; struct _DriFenceObject *last_swap_fence; struct _DriFenceObject *first_swap_fence; - struct intel_batchbuffer *batch; +// struct intel_batchbuffer *batch; boolean locked; char *prevLockFile; @@ -123,7 +126,7 @@ extern int __intel_debug; } while(0) #else -#define DBG(flag, ...) +#define DBG(flag, ...) #endif diff --git a/src/gallium/winsys/dri/intel/intel_lock.c b/src/gallium/winsys/dri/intel/intel_lock.c index 70aa7ea5f4..406284c98f 100644 --- a/src/gallium/winsys/dri/intel/intel_lock.c +++ b/src/gallium/winsys/dri/intel/intel_lock.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ @@ -87,7 +87,7 @@ void LOCK_HARDWARE( struct intel_context *intel ) } -/* Unlock the hardware using the global current context +/* Unlock the hardware using the global current context */ void UNLOCK_HARDWARE( struct intel_context *intel ) { @@ -99,4 +99,4 @@ void UNLOCK_HARDWARE( struct intel_context *intel ) _glthread_UNLOCK_MUTEX(lockMutex); DBG(LOCK, "%s - unlocked\n", __progname); -} +} diff --git a/src/gallium/winsys/dri/intel/intel_reg.h b/src/gallium/winsys/dri/intel/intel_reg.h index f37c24fda9..4f33bee438 100644 --- a/src/gallium/winsys/dri/intel/intel_reg.h +++ b/src/gallium/winsys/dri/intel/intel_reg.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 0be88974f4..8817a80a5a 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #include "utils.h" @@ -32,12 +32,10 @@ #include "intel_context.h" #include "intel_screen.h" #include "intel_batchbuffer.h" -//#include "intel_batchpool.h" #include "intel_swapbuffers.h" -#include "intel_winsys.h" #include "i830_dri.h" -#include "ws_dri_bufpool.h" +#include "intel_drm/ws_dri_bufpool.h" #include "pipe/p_context.h" #include "state_tracker/st_public.h" @@ -152,16 +150,16 @@ intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - driBOSetStatic(intelScreen->front.buffer, - intelScreen->front.offset, - intelScreen->front.pitch * intelScreen->front.height, + driBOSetStatic(intelScreen->front.buffer, + intelScreen->front.offset, + intelScreen->front.pitch * intelScreen->front.height, intelScreen->front.map, 0); } #else - if (intelScreen->staticPool) { + if (intelScreen->base.staticPool) { if (intelScreen->front.buffer) driBOUnReference(intelScreen->front.buffer); - driGenBuffers(intelScreen->staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle); } #endif @@ -177,33 +175,6 @@ intelCreatePools(__DRIscreenPrivate * sPriv) if (intelScreen->havePools) return GL_TRUE; -#if 0 /* ZZZ JB fix this */ - intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); - if (!intelScreen->staticPool) - return GL_FALSE; - - batchPoolSize /= BATCH_SZ; - intelScreen->batchPool = driBatchPoolInit(sPriv->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_MEM_LOCAL, - BATCH_SZ, - batchPoolSize, 5); - if (!intelScreen->batchPool) { - fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); - return GL_FALSE; - } -#else - intelScreen->staticPool = driDRMPoolInit(sPriv->fd); - intelScreen->batchPool = driSlabPoolInit(sPriv->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - intelScreen->max_batch_size, - 1, 40, intelScreen->max_batch_size * 16, 0, - intelScreen->fMan); -#endif intelScreen->havePools = GL_TRUE; intelUpdateScreenRotation(sPriv, intelScreen->sarea); @@ -211,6 +182,27 @@ intelCreatePools(__DRIscreenPrivate * sPriv) return GL_TRUE; } +static const char * +intel_get_name( struct pipe_winsys *winsys ) +{ + return "Intel/DRI/ttm"; +} + +/* + * The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +intel_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + intelDisplaySurface(dPriv, surf, NULL); +} static boolean intelInitDriver(__DRIscreenPrivate * sPriv) @@ -231,7 +223,7 @@ intelInitDriver(__DRIscreenPrivate * sPriv) /* Allocate the private area */ intelScreen = CALLOC_STRUCT(intel_screen); - if (!intelScreen) + if (!intelScreen) return GL_FALSE; /* parse information in __driConfigOptions */ @@ -262,26 +254,9 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - intelScreen->max_batch_size = 16 * 4096; - -#if 1 // ZZZ JB - intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd); - if (!intelScreen->mgr) { - fprintf(stderr, "Failed to create fence manager.\n"); - return GL_FALSE; - } - - intelScreen->fMan = driInitFreeSlabManager(10, 10); - if (!intelScreen->fMan) { - fprintf(stderr, "Failed to create free slab manager.\n"); - return GL_FALSE; - } - - if (!intelCreatePools(sPriv)) - return GL_FALSE; -#endif - - intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd, intelScreen->fMan); + intel_be_init_device(&intelScreen->base, sPriv->fd); + intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; + intelScreen->base.base.get_name = intel_get_name; return GL_TRUE; } @@ -292,12 +267,9 @@ intelDestroyScreen(__DRIscreenPrivate * sPriv) { struct intel_screen *intelScreen = intel_screen(sPriv); + intel_be_destroy_device(&intelScreen->base); /* intelUnmapScreenRegions(intelScreen); */ - if (intelScreen->havePools) { - driPoolTakeDown(intelScreen->staticPool); - driPoolTakeDown(intelScreen->batchPool); - } FREE(intelScreen); sPriv->private = NULL; } @@ -518,8 +490,8 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, * This routine also fills in the linked list pointed to by \c driver_modes * with the \c __GLcontextModes that the driver can support for windows or * pbuffers. - * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on * failure. */ PUBLIC void * diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index 1db0502b13..8036917903 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #ifndef _INTEL_SCREEN_H_ @@ -31,13 +31,16 @@ #include "dri_util.h" #include "i830_common.h" #include "xmlconfig.h" -#include "ws_dri_bufpool.h" +#include "intel_drm/ws_dri_bufpool.h" #include "pipe/p_compiler.h" +#include "intel_drm/intel_be_device.h" struct intel_screen { + struct intel_be_device base; + struct { drm_handle_t handle; @@ -51,7 +54,7 @@ struct intel_screen int width; int height; int size; - int cpp; /* for front and back buffers */ + int cpp; /* for front and back buffers */ } front; int deviceID; @@ -64,8 +67,6 @@ struct intel_screen */ driOptionCache optionCache; - struct _DriBufferPool *batchPool; - struct _DriBufferPool *staticPool; /** for the X screen/framebuffer */ boolean havePools; /** @@ -74,13 +75,11 @@ struct intel_screen */ struct intel_context *dummyContext; - /* + /* * New stuff form the i915tex integration */ - struct _DriFenceMgr *mgr; - struct _DriFreeSlabManager *fMan; unsigned batch_id; - unsigned max_batch_size; + struct pipe_winsys *winsys; }; diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 923b542771..7f3babd98e 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,21 +22,22 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" -#include "intel_batchbuffer.h" + #include "intel_reg.h" -#include "intel_winsys.h" #include "pipe/p_context.h" #include "state_tracker/st_public.h" #include "state_tracker/st_context.h" #include "state_tracker/st_cb_fbo.h" +#include "intel_drm/ws_dri_bufmgr.h" +#include "intel_batchbuffer.h" /** * Display a colorbuffer surface in an X window. @@ -114,7 +115,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, if (pbox->x1 > pbox->x2 || pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->front.width || + pbox->x2 > intelScreen->front.width || pbox->y2 > intelScreen->front.height) { /* invalid cliprect, skip it */ continue; @@ -159,13 +160,22 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, assert(box.y1 < box.y2); /* XXX this could be done with pipe->surface_copy() */ - BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + /* XXX should have its own batch buffer */ + if (!BEGIN_BATCH(8, 2)) { + /* + * Since we share this batch buffer with a context + * we can't flush it since that risks a GPU lockup + */ + assert(0); + continue; + } + OUT_BATCH(CMD); OUT_BATCH(BR13); OUT_BATCH((box.y1 << 16) | box.x1); OUT_BATCH((box.y2 << 16) | box.x2); - OUT_RELOC(intelScreen->front.buffer, + OUT_RELOC(intelScreen->front.buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); OUT_BATCH((sbox.y1 << 16) | sbox.x1); @@ -174,12 +184,11 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - ADVANCE_BATCH(); } if (intel->first_swap_fence) driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); + intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); } UNLOCK_HARDWARE(intel); diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.h b/src/gallium/winsys/dri/intel/intel_swapbuffers.h index 7ae5fd15a5..46c9bab3af 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.h +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #ifndef INTEL_SWAPBUFFERS_H diff --git a/src/gallium/winsys/dri/intel/intel_winsys.h b/src/gallium/winsys/dri/intel/intel_winsys.h deleted file mode 100644 index 3d32db10a4..0000000000 --- a/src/gallium/winsys/dri/intel/intel_winsys.h +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_WINSYS_H -#define INTEL_WINSYS_H - -#include "pipe/p_state.h" - -struct intel_context; -struct pipe_context; -struct pipe_winsys; -struct pipe_buffer; -struct _DriBufferObject; - -struct pipe_winsys * -intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ); - -void -intel_destroy_pipe_winsys( struct pipe_winsys *winsys ); - -struct pipe_context * -intel_create_softpipe( struct intel_context *intel, - struct pipe_winsys *winsys ); - -struct pipe_context * -intel_create_i915simple( struct intel_context *intel, - struct pipe_winsys *winsys ); - - -struct intel_buffer { - struct pipe_buffer base; - struct _DriBufferPool *pool; - struct _DriBufferObject *driBO; -}; - -static INLINE struct intel_buffer * -intel_buffer( struct pipe_buffer *buf ) -{ - return (struct intel_buffer *)buf; -} - -static INLINE struct _DriBufferObject * -dri_bo( struct pipe_buffer *buf ) -{ - return intel_buffer(buf)->driBO; -} - - -#endif diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c deleted file mode 100644 index 013291364a..0000000000 --- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c +++ /dev/null @@ -1,156 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" - -#include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_winsys.h" - -#include "pipe/p_util.h" -#include "pipe/p_winsys.h" -#include "i915simple/i915_winsys.h" -#include "i915simple/i915_screen.h" - - -struct intel_i915_winsys { - struct i915_winsys winsys; /**< batch buffer funcs */ - struct pipe_winsys *pws; - struct intel_context *intel; -}; - - -/* Turn a i915simple winsys into an intel/i915simple winsys: - */ -static inline struct intel_i915_winsys * -intel_i915_winsys( struct i915_winsys *sws ) -{ - return (struct intel_i915_winsys *)sws; -} - - -/* Simple batchbuffer interface: - */ - -static struct i915_batchbuffer* -intel_i915_batch_get( struct i915_winsys *sws ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - return &intel->batch->base; -} - -static void intel_i915_batch_reloc( struct i915_winsys *sws, - struct pipe_buffer *buf, - unsigned access_flags, - unsigned delta ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - unsigned flags = DRM_BO_FLAG_MEM_TT; - unsigned mask = DRM_BO_MASK_MEM; - - if (access_flags & I915_BUFFER_ACCESS_WRITE) { - flags |= DRM_BO_FLAG_WRITE; - mask |= DRM_BO_FLAG_WRITE; - } - - if (access_flags & I915_BUFFER_ACCESS_READ) { - flags |= DRM_BO_FLAG_READ; - mask |= DRM_BO_FLAG_READ; - } - - intel_offset_relocation( intel->batch, - delta, - dri_bo( buf ), - flags, - mask ); -} - -static void intel_i915_batch_flush( struct i915_winsys *sws, - struct pipe_fence_handle **fence ) -{ - struct intel_i915_winsys *iws = intel_i915_winsys(sws); - struct intel_context *intel = iws->intel; - union { - struct _DriFenceObject *dri; - struct pipe_fence_handle *pipe; - } fu; - - if (fence) - assert(!*fence); - - fu.dri = intel_batchbuffer_flush( intel->batch ); - - if (!fu.dri) { - assert(0); - *fence = NULL; - return; - } - - if (fu.dri) { - if (fence) - *fence = fu.pipe; - else - driFenceUnReference(&fu.dri); - } - -} - - -/** - * Create i915 hardware rendering context. - */ -struct pipe_context * -intel_create_i915simple( struct intel_context *intel, - struct pipe_winsys *winsys ) -{ - struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys ); - struct pipe_screen *screen; - - /* Fill in this struct with callbacks that i915simple will need to - * communicate with the window system, buffer manager, etc. - */ - iws->winsys.batch_get = intel_i915_batch_get; - iws->winsys.batch_reloc = intel_i915_batch_reloc; - iws->winsys.batch_flush = intel_i915_batch_flush; - iws->pws = winsys; - iws->intel = intel; - - screen = i915_create_screen(winsys, intel->intelScreen->deviceID); - - /* Create the i915simple context: - */ - return i915_create_context( screen, - winsys, - &iws->winsys ); -} diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c deleted file mode 100644 index 51a79ca535..0000000000 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ /dev/null @@ -1,318 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include -#include - -#include "intel_context.h" -#include "intel_winsys.h" -#include "intel_swapbuffers.h" -#include "intel_batchbuffer.h" - -#include "pipe/p_winsys.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" - -struct intel_pipe_winsys { - struct pipe_winsys winsys; - struct _DriBufferPool *regionPool; - struct _DriBufferPool *mallocPool; - struct _DriBufferPool *vertexPool; - struct _DriFreeSlabManager *fMan; /** shared between all pipes */ -}; - - -/* Turn a pipe winsys into an intel/pipe winsys: - */ -static inline struct intel_pipe_winsys * -intel_pipe_winsys( struct pipe_winsys *winsys ) -{ - return (struct intel_pipe_winsys *)winsys; -} - - -/* - * Buffer functions. - * - * Most callbacks map direcly onto dri_bufmgr operations: - */ - -static void *intel_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags ) -{ - unsigned drm_flags = 0; - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) - drm_flags |= DRM_BO_FLAG_WRITE; - - if (flags & PIPE_BUFFER_USAGE_CPU_READ) - drm_flags |= DRM_BO_FLAG_READ; - - return driBOMap( dri_bo(buf), drm_flags, 0 ); -} - -static void intel_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnmap( dri_bo(buf) ); -} - -static void -intel_buffer_destroy(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnReference( dri_bo(buf) ); - FREE(buf); -} - -static struct pipe_buffer * -intel_buffer_create(struct pipe_winsys *winsys, - unsigned alignment, - unsigned usage, - unsigned size ) -{ - struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - unsigned flags = 0; - struct _DriBufferPool *pool; - - buffer->base.refcount = 1; - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - - if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { - flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; - pool = iws->mallocPool; - } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { - /* For vertex buffers */ - flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; - pool = iws->vertexPool; - } else { - flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; - pool = iws->regionPool; - } - - if (usage & PIPE_BUFFER_USAGE_GPU_READ) - flags |= DRM_BO_FLAG_READ; - - if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) - flags |= DRM_BO_FLAG_WRITE; - - /* drm complains if we don't set any read/write flags. - */ - if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) - flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - -#if 0 - if (flags & IWS_BUFFER_USAGE_EXE) - flags |= DRM_BO_FLAG_EXE; - - if (usage & IWS_BUFFER_USAGE_CACHED) - flags |= DRM_BO_FLAG_CACHED; -#endif - - buffer->pool = pool; - driGenBuffers( buffer->pool, - "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); - - driBOData( buffer->driBO, size, NULL, buffer->pool, 0 ); - - return &buffer->base; -} - - -static struct pipe_buffer * -intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) -{ - struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - - driGenUserBuffer( iws->regionPool, - "pipe user buffer", &buffer->driBO, ptr, bytes ); - - buffer->base.refcount = 1; - - return &buffer->base; -} - - -/* - * Surface functions. - * - * Deprecated! - */ - -static struct pipe_surface * -intel_i915_surface_alloc(struct pipe_winsys *winsys) -{ - assert("intel_i915_surface_alloc is deprecated" & 0); - return NULL; -} - -static int -intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, - unsigned flags, - unsigned tex_usage) -{ - assert("intel_i915_surface_alloc_storage is deprecated" & 0); - return -1; -} - -static void -intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - assert("intel_i915_surface_release is deprecated" & 0); -} - -/* - * Fence functions - */ - -static void -intel_fence_reference( struct pipe_winsys *sws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence ) -{ - if (*ptr) - driFenceUnReference((struct _DriFenceObject **)ptr); - - if (fence) - *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); -} - -static int -intel_fence_signalled( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - return driFenceSignaled((struct _DriFenceObject *)fence, flag); -} - -static int -intel_fence_finish( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); -} - - -/* - * Mixed functions - */ - -static const char * -intel_get_name( struct pipe_winsys *winsys ) -{ - return "Intel/DRI/ttm"; -} - -/* - * The state tracker (should!) keep track of whether the fake - * frontbuffer has been touched by any rendering since the last time - * we copied its contents to the real frontbuffer. Our task is easy: - */ -static void -intel_flush_frontbuffer( struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ - struct intel_context *intel = (struct intel_context *) context_private; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - intelDisplaySurface(dPriv, surf, NULL); -} - -struct pipe_winsys * -intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) -{ - struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys ); - - /* Fill in this struct with callbacks that pipe will need to - * communicate with the window system, buffer manager, etc. - * - * Pipe would be happy with a malloc based memory manager, but - * the SwapBuffers implementation in this winsys driver requires - * that rendering be done to an appropriate _DriBufferObject. - */ - iws->winsys.buffer_create = intel_buffer_create; - iws->winsys.user_buffer_create = intel_user_buffer_create; - iws->winsys.buffer_map = intel_buffer_map; - iws->winsys.buffer_unmap = intel_buffer_unmap; - iws->winsys.buffer_destroy = intel_buffer_destroy; - iws->winsys.flush_frontbuffer = intel_flush_frontbuffer; - iws->winsys.get_name = intel_get_name; - iws->winsys.surface_alloc = intel_i915_surface_alloc; - iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; - iws->winsys.surface_release = intel_i915_surface_release; - - iws->winsys.fence_reference = intel_fence_reference; - iws->winsys.fence_signalled = intel_fence_signalled; - iws->winsys.fence_finish = intel_fence_finish; - - if (fd) { - iws->regionPool = driDRMPoolInit(fd); - iws->vertexPool = driSlabPoolInit(fd, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - 128 * 4096, - 1, 120, 128 * 4096 * 4, 0, - fMan); - } - - iws->mallocPool = driMallocPoolInit(); - - return &iws->winsys; -} - -void -intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) -{ - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - if (iws->regionPool) { - driPoolTakeDown(iws->regionPool); - } - if (iws->mallocPool) { - driPoolTakeDown(iws->mallocPool); - } - free(iws); -} diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c index 0bc2dc4002..0d98d16cf1 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,27 +10,27 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * - * + * + * **************************************************************************/ /* * Authors: Keith Whitwell */ #include "intel_context.h" -#include "intel_winsys.h" +#include "intel_winsys_softpipe.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" #include "pipe/p_format.h" @@ -69,9 +69,9 @@ intel_create_softpipe( struct intel_context *intel, { struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); struct pipe_screen *screen = softpipe_create_screen(winsys); - + /* Fill in this struct with callbacks that softpipe will need to - * communicate with the window system, buffer manager, etc. + * communicate with the window system, buffer manager, etc. */ isws->sws.is_format_supported = intel_is_format_supported; isws->intel = intel; diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h new file mode 100644 index 0000000000..5fa14cb749 --- /dev/null +++ b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_SOFTPIPE_H +#define INTEL_SOFTPIPE_H + +struct pipe_winsys; +struct pipe_context; +struct intel_context; + +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ); + +#endif diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h index f84f453309..3452ddb3c9 100644 --- a/src/gallium/winsys/dri/intel/server/i830_common.h +++ b/src/gallium/winsys/dri/intel/server/i830_common.h @@ -88,9 +88,9 @@ typedef struct { /** Last context that used the buffer manager. */ int texAge; int pf_enabled; /* is pageflipping allowed? */ - int pf_active; + int pf_active; int pf_current_page; /* which buffer is being displayed? */ - int perf_boxes; /* performance boxes to be displayed */ + int perf_boxes; /* performance boxes to be displayed */ int width, height; /* screen size in pixels */ drm_handle_t front_handle; @@ -173,7 +173,7 @@ typedef struct { int num_cliprects; /* mulitpass with multiple cliprects? */ drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ } drmI830CmdBuffer; - + typedef struct { int *irq_seq; } drmI830IrqEmit; @@ -188,7 +188,7 @@ typedef struct { } drmI830GetParam; #define I830_PARAM_IRQ_ACTIVE 1 -#define I830_PARAM_ALLOW_BATCHBUFFER 2 +#define I830_PARAM_ALLOW_BATCHBUFFER 2 typedef struct { int param; diff --git a/src/gallium/winsys/dri/intel/server/i830_dri.h b/src/gallium/winsys/dri/intel/server/i830_dri.h index 685de4a551..0d514b6c38 100644 --- a/src/gallium/winsys/dri/intel/server/i830_dri.h +++ b/src/gallium/winsys/dri/intel/server/i830_dri.h @@ -40,7 +40,7 @@ typedef struct _I830DRIRec { int bitsPerPixel; int unused11[8]; /* was front/back/depth/rotated offset/pitch */ - + int unused12; /* logTextureGranularity */ int unused13; /* textureOffset */ diff --git a/src/gallium/winsys/dri/intel/server/intel.h b/src/gallium/winsys/dri/intel/server/intel.h deleted file mode 100644 index 6ea72499c1..0000000000 --- a/src/gallium/winsys/dri/intel/server/intel.h +++ /dev/null @@ -1,331 +0,0 @@ -#ifndef _INTEL_H_ -#define _INTEL_H_ - -#include "xf86drm.h" /* drm_handle_t, etc */ - -/* Intel */ -#ifndef PCI_CHIP_I810 -#define PCI_CHIP_I810 0x7121 -#define PCI_CHIP_I810_DC100 0x7123 -#define PCI_CHIP_I810_E 0x7125 -#define PCI_CHIP_I815 0x1132 -#define PCI_CHIP_I810_BRIDGE 0x7120 -#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 -#define PCI_CHIP_I810_E_BRIDGE 0x7124 -#define PCI_CHIP_I815_BRIDGE 0x1130 -#endif - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 - -#ifndef PCI_CHIP_I855_GM -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I855_GM_BRIDGE 0x3580 -#endif - -#ifndef PCI_CHIP_I865_G -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I865_G_BRIDGE 0x2570 -#endif - -#ifndef PCI_CHIP_I915_G -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I915_GM -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I915_GM_BRIDGE 0x2590 -#endif - -#ifndef PCI_CHIP_E7221_G -#define PCI_CHIP_E7221_G 0x258A -/* Same as I915_G_BRIDGE */ -#define PCI_CHIP_E7221_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I945_G -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_G_BRIDGE 0x2770 -#endif - -#ifndef PCI_CHIP_I945_GM -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 -#endif - -#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ - pI810->Chipset == PCI_CHIP_I810_DC100 || \ - pI810->Chipset == PCI_CHIP_I810_E) -#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) -#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) -#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) -#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) -#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) -#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) -#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) - -#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) -#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) -#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) -#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) -#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) - -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) - -#define I830_GMCH_CTRL 0x52 - -#define I830_GMCH_MEM_MASK 0x1 -#define I830_GMCH_MEM_64M 0x1 -#define I830_GMCH_MEM_128M 0 - -#define I830_GMCH_GMS_MASK 0x70 -#define I830_GMCH_GMS_DISABLED 0x00 -#define I830_GMCH_GMS_LOCAL 0x10 -#define I830_GMCH_GMS_STOLEN_512 0x20 -#define I830_GMCH_GMS_STOLEN_1024 0x30 -#define I830_GMCH_GMS_STOLEN_8192 0x40 - -#define I855_GMCH_GMS_MASK (0x7 << 4) -#define I855_GMCH_GMS_DISABLED 0x00 -#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) -#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) -#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) -#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) -#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) -#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) -#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) - -typedef unsigned char Bool; -#define TRUE 1 -#define FALSE 0 - -#define PIPE_NONE 0<<0 -#define PIPE_CRT 1<<0 -#define PIPE_TV 1<<1 -#define PIPE_DFP 1<<2 -#define PIPE_LFP 1<<3 -#define PIPE_CRT2 1<<4 -#define PIPE_TV2 1<<5 -#define PIPE_DFP2 1<<6 -#define PIPE_LFP2 1<<7 - -typedef struct _I830MemPool *I830MemPoolPtr; -typedef struct _I830MemRange *I830MemRangePtr; -typedef struct _I830MemRange { - long Start; - long End; - long Size; - unsigned long Physical; - unsigned long Offset; /* Offset of AGP-allocated portion */ - unsigned long Alignment; - drm_handle_t Key; - unsigned long Pitch; // add pitch - I830MemPoolPtr Pool; -} I830MemRange; - -typedef struct _I830MemPool { - I830MemRange Total; - I830MemRange Free; - I830MemRange Fixed; - I830MemRange Allocated; -} I830MemPool; - -typedef struct { - int tail_mask; - I830MemRange mem; - unsigned char *virtual_start; - int head; - int tail; - int space; -} I830RingBuffer; - -typedef struct _I830Rec { - unsigned char *MMIOBase; - unsigned char *FbBase; - int cpp; - uint32_t aper_size; - unsigned int bios_version; - - /* These are set in PreInit and never changed. */ - long FbMapSize; - long TotalVideoRam; - I830MemRange StolenMemory; /* pre-allocated memory */ - long BIOSMemorySize; /* min stolen pool size */ - int BIOSMemSizeLoc; - - /* These change according to what has been allocated. */ - long FreeMemory; - I830MemRange MemoryAperture; - I830MemPool StolenPool; - long allocatedMemory; - - /* Regions allocated either from the above pools, or from agpgart. */ - /* for single and dual head configurations */ - I830MemRange FrontBuffer; - I830MemRange FrontBuffer2; - I830MemRange Scratch; - I830MemRange Scratch2; - - I830RingBuffer *LpRing; - - I830MemRange BackBuffer; - I830MemRange DepthBuffer; - I830MemRange TexMem; - int TexGranularity; - I830MemRange ContextMem; - int drmMinor; - Bool have3DWindows; - - Bool NeedRingBufferLow; - Bool allowPageFlip; - Bool disableTiling; - - int Chipset; - unsigned long LinearAddr; - unsigned long MMIOAddr; - - drmSize registerSize; /**< \brief MMIO register map size */ - drm_handle_t registerHandle; /**< \brief MMIO register map handle */ - // IOADDRESS ioBase; - int irq; /**< \brief IRQ number */ - int GttBound; - - drm_handle_t ring_map; - unsigned int Fence[8]; - -} I830Rec; - -/* - * 12288 is set as the maximum, chosen because it is enough for - * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. - */ -#define I830_MAXIMUM_VBIOS_MEM 12288 -#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) -#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) - -/* Flags for memory allocation function */ -#define FROM_ANYWHERE 0x00000000 -#define FROM_POOL_ONLY 0x00000001 -#define FROM_NEW_ONLY 0x00000002 -#define FROM_MASK 0x0000000f - -#define ALLOCATE_AT_TOP 0x00000010 -#define ALLOCATE_AT_BOTTOM 0x00000020 -#define FORCE_GAPS 0x00000040 - -#define NEED_PHYSICAL_ADDR 0x00000100 -#define ALIGN_BOTH_ENDS 0x00000200 -#define FORCE_LOW 0x00000400 - -#define ALLOC_NO_TILING 0x00001000 -#define ALLOC_INITIAL 0x00002000 - -#define ALLOCATE_DRY_RUN 0x80000000 - -/* Chipset registers for VIDEO BIOS memory RW access */ -#define _855_DRAM_RW_CONTROL 0x58 -#define _845_DRAM_RW_CONTROL 0x90 -#define DRAM_WRITE 0x33330000 - -#define KB(x) ((x) * 1024) -#define MB(x) ((x) * KB(1024)) - -#define GTT_PAGE_SIZE KB(4) -#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) -#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) -#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) -#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) -#define PRIMARY_RINGBUFFER_SIZE KB(128) - - -/* Ring buffer registers, p277, overview p19 - */ -#define LP_RING 0x2030 -#define HP_RING 0x2040 - -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 -#define I830_TAIL_MASK 0x001FFFF8 - -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define I830_HEAD_MASK 0x001FFFFC - -#define RING_START 0x08 -#define START_ADDR 0x03FFFFF8 -#define I830_RING_START_MASK 0xFFFFF000 - -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 -#define I830_RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - - -/* Fence/Tiling ranges [0..7] - */ -#define FENCE 0x2000 -#define FENCE_NR 8 - -#define I915G_FENCE_START_MASK 0x0ff00000 - -#define I830_FENCE_START_MASK 0x07f80000 - -#define FENCE_START_MASK 0x03F80000 -#define FENCE_X_MAJOR 0x00000000 -#define FENCE_Y_MAJOR 0x00001000 -#define FENCE_SIZE_MASK 0x00000700 -#define FENCE_SIZE_512K 0x00000000 -#define FENCE_SIZE_1M 0x00000100 -#define FENCE_SIZE_2M 0x00000200 -#define FENCE_SIZE_4M 0x00000300 -#define FENCE_SIZE_8M 0x00000400 -#define FENCE_SIZE_16M 0x00000500 -#define FENCE_SIZE_32M 0x00000600 -#define FENCE_SIZE_64M 0x00000700 -#define I915G_FENCE_SIZE_1M 0x00000000 -#define I915G_FENCE_SIZE_2M 0x00000100 -#define I915G_FENCE_SIZE_4M 0x00000200 -#define I915G_FENCE_SIZE_8M 0x00000300 -#define I915G_FENCE_SIZE_16M 0x00000400 -#define I915G_FENCE_SIZE_32M 0x00000500 -#define I915G_FENCE_SIZE_64M 0x00000600 -#define I915G_FENCE_SIZE_128M 0x00000700 -#define FENCE_PITCH_1 0x00000000 -#define FENCE_PITCH_2 0x00000010 -#define FENCE_PITCH_4 0x00000020 -#define FENCE_PITCH_8 0x00000030 -#define FENCE_PITCH_16 0x00000040 -#define FENCE_PITCH_32 0x00000050 -#define FENCE_PITCH_64 0x00000060 -#define FENCE_VALID 0x00000001 - -#include - -# define MMIO_IN8(base, offset) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) -# define MMIO_IN32(base, offset) \ - read_MMIO_LE32(base, offset) -# define MMIO_OUT8(base, offset, val) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) -# define MMIO_OUT32(base, offset, val) \ - *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) - - - /* Memory mapped register access macros */ -#define INREG8(addr) MMIO_IN8(MMIO, addr) -#define INREG(addr) MMIO_IN32(MMIO, addr) -#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) -#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) - -#define DSPABASE 0x70184 - -#endif diff --git a/src/gallium/winsys/dri/intel/server/intel_dri.c b/src/gallium/winsys/dri/intel/server/intel_dri.c deleted file mode 100644 index e49c4214ad..0000000000 --- a/src/gallium/winsys/dri/intel/server/intel_dri.c +++ /dev/null @@ -1,1306 +0,0 @@ -/** - * \file server/intel_dri.c - * \brief File to perform the device-specific initialization tasks typically - * done in the X server. - * - * Here they are converted to run in the client (or perhaps a standalone - * process), and to work with the frame buffer device rather than the X - * server infrastructure. - * - * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sub license, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial portions - of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" - -#include "intel.h" -#include "i830_dri.h" - -#include "memops.h" -#include "pciaccess.h" - -static size_t drm_page_size; -static int nextTile = 0; -#define xf86DrvMsg(...) do {} while(0) - -static const int pitches[] = { - 128 * 8, - 128 * 16, - 128 * 32, - 128 * 64, - 0 -}; - -static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); - -static unsigned long -GetBestTileAlignment(unsigned long size) -{ - unsigned long i; - - for (i = KB(512); i < size; i <<= 1) - ; - - if (i > MB(64)) - i = MB(64); - - return i; -} - -static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - unsigned char *MMIO = ctx->MMIOAddress; - - for (i = 0; i < 8; i++) { - OUTREG(FENCE + i * 4, pI830->Fence[i]); - // if (I810_DEBUG & DEBUG_VERBOSE_VGA) - fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); - } -} - -/* Tiled memory is good... really, really good... - * - * Need to make it less likely that we miss out on this - probably - * need to move the frontbuffer away from the 'guarenteed' alignment - * of the first memory segment, or perhaps allocate a discontigous - * framebuffer to get more alignment 'sweet spots'. - */ -static void -SetFence(const DRIDriverContext *ctx, I830Rec *pI830, - int nr, unsigned int start, unsigned int pitch, - unsigned int size) -{ - unsigned int val; - unsigned int fence_mask = 0; - unsigned int fence_pitch; - - if (nr < 0 || nr > 7) { - fprintf(stderr, - "SetFence: fence %d out of range\n",nr); - return; - } - - pI830->Fence[nr] = 0; - - if (IS_I9XX(pI830)) - fence_mask = ~I915G_FENCE_START_MASK; - else - fence_mask = ~I830_FENCE_START_MASK; - - if (start & fence_mask) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not %s aligned\n", - nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); - return; - } - - if (start % size) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", - nr, start, size / 1024); - return; - } - - if (pitch & 127) { - fprintf(stderr, - "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", - nr, pitch); - return; - } - - val = (start | FENCE_X_MAJOR | FENCE_VALID); - - if (IS_I9XX(pI830)) { - switch (size) { - case MB(1): - val |= I915G_FENCE_SIZE_1M; - break; - case MB(2): - val |= I915G_FENCE_SIZE_2M; - break; - case MB(4): - val |= I915G_FENCE_SIZE_4M; - break; - case MB(8): - val |= I915G_FENCE_SIZE_8M; - break; - case MB(16): - val |= I915G_FENCE_SIZE_16M; - break; - case MB(32): - val |= I915G_FENCE_SIZE_32M; - break; - case MB(64): - val |= I915G_FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } else { - switch (size) { - case KB(512): - val |= FENCE_SIZE_512K; - break; - case MB(1): - val |= FENCE_SIZE_1M; - break; - case MB(2): - val |= FENCE_SIZE_2M; - break; - case MB(4): - val |= FENCE_SIZE_4M; - break; - case MB(8): - val |= FENCE_SIZE_8M; - break; - case MB(16): - val |= FENCE_SIZE_16M; - break; - case MB(32): - val |= FENCE_SIZE_32M; - break; - case MB(64): - val |= FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } - - if (IS_I9XX(pI830)) - fence_pitch = pitch / 512; - else - fence_pitch = pitch / 128; - - switch (fence_pitch) { - case 1: - val |= FENCE_PITCH_1; - break; - case 2: - val |= FENCE_PITCH_2; - break; - case 4: - val |= FENCE_PITCH_4; - break; - case 8: - val |= FENCE_PITCH_8; - break; - case 16: - val |= FENCE_PITCH_16; - break; - case 32: - val |= FENCE_PITCH_32; - break; - case 64: - val |= FENCE_PITCH_64; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal pitch (%d)\n", nr, pitch); - return; - } - - pI830->Fence[nr] = val; -} - -static Bool -MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) -{ - int pitch, ntiles, i; - - pitch = pMem->Pitch * ctx->cpp; - /* - * Simply try to break the region up into at most four pieces of size - * equal to the alignment. - */ - ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; - if (ntiles >= 4) { - return FALSE; - } - - for (i = 0; i < ntiles; i++, nextTile++) { - SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, - pitch, pMem->Alignment); - } - return TRUE; -} - -static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - - /* Clear out */ - for (i = 0; i < 8; i++) - pI830->Fence[i] = 0; - - nextTile = 0; - - if (pI830->BackBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { - fprintf(stderr, - "Activating tiled memory for the back buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the back buffer.\n"); - pI830->allowPageFlip = FALSE; - } - } - - if (pI830->DepthBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { - fprintf(stderr, - "Activating tiled memory for the depth buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the depth buffer.\n"); - } - } - - return; -} - -static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - struct pci_device host_bridge, ig_dev; - uint32_t gmch_ctrl; - int memsize = 0; - int range; - uint32_t aper_size; - uint32_t membase2 = 0; - - memset(&host_bridge, 0, sizeof(host_bridge)); - memset(&ig_dev, 0, sizeof(ig_dev)); - - ig_dev.dev = 2; - - pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); - - if (IS_I830(pI830) || IS_845G(pI830)) { - if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { - aper_size = 0x80000000; - } else { - aper_size = 0x40000000; - } - } else { - if (IS_I9XX(pI830)) { - int ret; - ret = pci_device_cfg_read_u32(&ig_dev, &membase2, 0x18); - if (membase2 & 0x08000000) - aper_size = 0x8000000; - else - aper_size = 0x10000000; - - fprintf(stderr,"aper size is %08X %08x %d\n", aper_size, membase2, ret); - } else - aper_size = 0x8000000; - } - - pI830->aper_size = aper_size; - - - /* We need to reduce the stolen size, by the GTT and the popup. - * The GTT varying according the the FbMapSize and the popup is 4KB */ - range = (ctx->shared.fbSize / (1024*1024)) + 4; - - if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I855_GMCH_GMS_STOLEN_1M: - memsize = MB(1) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_4M: - memsize = MB(4) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_8M: - memsize = MB(8) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_16M: - memsize = MB(16) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_32M: - memsize = MB(32) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_48M: - if (IS_I9XX(pI830)) - memsize = MB(48) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_64M: - if (IS_I9XX(pI830)) - memsize = MB(64) - KB(range); - break; - } - } else { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I830_GMCH_GMS_STOLEN_512: - memsize = KB(512) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_1024: - memsize = MB(1) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_8192: - memsize = MB(8) - KB(range); - break; - case I830_GMCH_GMS_LOCAL: - memsize = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Local memory found, but won't be used.\n"); - break; - } - } - if (memsize > 0) { - fprintf(stderr, - "detected %d kB stolen memory.\n", memsize / 1024); - } else { - fprintf(stderr, - "no video memory detected.\n"); - } - return memsize; -} - -static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) -{ - unsigned long mode = 0x4; - - if (drmAgpAcquire(ctx->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - if (drmAgpEnable(ctx->drmFD, mode) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(ctx->drmFD); - return 0; - } - else - fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); - - return 1; -} - -/* - * Allocate memory from the given pool. Grow the pool if needed and if - * possible. - */ -static unsigned long -AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, - long size, unsigned long alignment, int flags) -{ - long needed, start, end; - - if (!result || !pool || !size) - return 0; - - /* Calculate how much space is needed. */ - if (alignment <= GTT_PAGE_SIZE) - needed = size; - else { - start = ROUND_TO(pool->Free.Start, alignment); - end = ROUND_TO(start + size, alignment); - needed = end - pool->Free.Start; - } - if (needed > pool->Free.Size) { - return 0; - } - - result->Start = ROUND_TO(pool->Free.Start, alignment); - pool->Free.Start += needed; - result->End = pool->Free.Start; - - pool->Free.Size = pool->Free.End - pool->Free.Start; - result->Size = result->End - result->Start; - result->Pool = pool; - result->Alignment = alignment; - return needed; -} - -static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) -{ - unsigned long start, end; - unsigned long newApStart, newApEnd; - int ret; - if (!result || !size) - return 0; - - if (!alignment) - alignment = 4; - - start = ROUND_TO(pI830->MemoryAperture.Start, alignment); - end = ROUND_TO(start + size, alignment); - newApStart = end; - newApEnd = pI830->MemoryAperture.End; - - ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); - - if (ret) - { - fprintf(stderr,"drmAgpAlloc failed %d\n", ret); - return 0; - } - pI830->allocatedMemory += size; - pI830->MemoryAperture.Start = newApStart; - pI830->MemoryAperture.End = newApEnd; - pI830->MemoryAperture.Size = newApEnd - newApStart; - // pI830->FreeMemory -= size; - result->Start = start; - result->End = start + size; - result->Size = size; - result->Offset = start; - result->Alignment = alignment; - result->Pool = NULL; - - return size; -} - -unsigned long -I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, long size, - unsigned long alignment, int flags) -{ - unsigned long ret; - - if (!result) - return 0; - - /* Make sure these are initialised. */ - result->Size = 0; - result->Key = -1; - - if (!size) { - return 0; - } - - if (pool->Free.Size < size) { - ret = AllocFromAGP(ctx, pI830, size, alignment, result); - } - else { - ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); - if (ret == 0) - ret = AllocFromAGP(ctx, pI830, size, alignment, result); - } - return ret; -} - -static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) -{ - if (!mem) - return FALSE; - - if (mem->Key == -1) - return TRUE; - - return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); -} - -/* simple memory allocation routines needed */ -/* put ring buffer in low memory */ -/* need to allocate front, back, depth buffers aligned correctly, - allocate ring buffer, -*/ - -/* */ -static Bool -I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned long size, ret; - unsigned long lines, lineSize, align; - - /* allocate ring buffer */ - memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); - pI830->LpRing->mem.Key = -1; - - size = PRIMARY_RINGBUFFER_SIZE; - - ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); - - if (ret != size) - { - fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); - return FALSE; - } - - pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; - - - /* allocate front buffer */ - memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); - pI830->FrontBuffer.Key = -1; - pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; - - align = KB(512); - - lineSize = ctx->shared.virtualWidth * ctx->cpp; - lines = (ctx->shared.virtualHeight + 15) / 16 * 16; - size = lineSize * lines; - size = ROUND_TO_PAGE(size); - - align = GetBestTileAlignment(size); - - ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate front buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); - pI830->BackBuffer.Key = -1; - pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate back buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); - pI830->DepthBuffer.Key = -1; - pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); - pI830->ContextMem.Key = -1; - size = KB(32); - - ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate context buffer %ld\n", ret); - return FALSE; - } - -#if 0 - memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); - pI830->TexMem.Key = -1; - - size = 32768 * 1024; - ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); - if (ret < size) - { - fprintf(stderr,"unable to allocate texture memory %ld\n", ret); - return FALSE; - } -#endif - - return TRUE; -} - -static Bool -I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - if (!BindAgpRange(ctx, &pI830->LpRing->mem)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->FrontBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->BackBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->DepthBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->ContextMem)) - return FALSE; -#if 0 - if (!BindAgpRange(ctx, &pI830->TexMem)) - return FALSE; -#endif - return TRUE; -} - -static void SetupDRIMM(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned long aperEnd = ROUND_DOWN_TO(pI830->aper_size, GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - unsigned long aperStart = ROUND_TO(pI830->aper_size - KB(32768), GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - - fprintf(stderr, "aper size is %08X\n", ctx->shared.fbSize); - if (drmMMInit(ctx->drmFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) { - fprintf(stderr, - "DRM MM Initialization Failed\n"); - } else { - fprintf(stderr, - "DRM MM Initialized at offset 0x%lx length %d page\n", aperStart, aperEnd-aperStart); - } - -} - -static Bool -I830CleanupDma(const DRIDriverContext *ctx) -{ - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_CLEANUP_DMA; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, "I830 Dma Cleanup Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) -{ - I830RingBuffer *ring = pI830->LpRing; - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_INIT_DMA; - - info.ring_start = ring->mem.Start + pI830->LinearAddr; - info.ring_end = ring->mem.End + pI830->LinearAddr; - info.ring_size = ring->mem.Size; - - info.mmio_offset = (unsigned int)ctx->MMIOStart; - - info.sarea_priv_offset = sizeof(drm_sarea_t); - - info.front_offset = pI830->FrontBuffer.Start; - info.back_offset = pI830->BackBuffer.Start; - info.depth_offset = pI830->DepthBuffer.Start; - info.w = ctx->shared.virtualWidth; - info.h = ctx->shared.virtualHeight; - info.pitch = ctx->shared.virtualWidth; - info.back_pitch = pI830->BackBuffer.Pitch; - info.depth_pitch = pI830->DepthBuffer.Pitch; - info.cpp = ctx->cpp; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, - "I830 Dma Initialization Failed\n"); - return FALSE; - } - - return TRUE; -} - -static int I830CheckDRMVersion( const DRIDriverContext *ctx, - I830Rec *pI830 ) -{ - drmVersionPtr version; - - version = drmGetVersion(ctx->drmFD); - - if (version) { - int req_minor, req_patch; - - req_minor = 4; - req_patch = 0; - - if (version->version_major != 1 || - version->version_minor < req_minor || - (version->version_minor == req_minor && - version->version_patchlevel < req_patch)) { - /* Incompatible drm version */ - fprintf(stderr, - "[dri] I830DRIScreenInit failed because of a version " - "mismatch.\n" - "[dri] i915.o kernel module version is %d.%d.%d " - "but version 1.%d.%d or newer is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel, - req_minor, - req_patch); - drmFreeVersion(version); - return 0; - } - - pI830->drmMinor = version->version_minor; - drmFreeVersion(version); - } - return 1; -} - -static void -I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned int itemp; - unsigned char *MMIO = ctx->MMIOAddress; - - OUTREG(LP_RING + RING_LEN, 0); - OUTREG(LP_RING + RING_TAIL, 0); - OUTREG(LP_RING + RING_HEAD, 0); - - if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != - pI830->LpRing->mem.Start) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer start (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; - OUTREG(LP_RING + RING_START, itemp); - - if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != - pI830->LpRing->mem.Size - 4096) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Size - 4096, - I830_RING_NR_PAGES); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; - itemp |= (RING_NO_REPORT | RING_VALID); - OUTREG(LP_RING + RING_LEN, itemp); - - pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; - pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); - pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); - if (pI830->LpRing->space < 0) - pI830->LpRing->space += pI830->LpRing->mem.Size; - - SetFenceRegs(ctx, pI830); - - /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky - hacky hacky */ - OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); - -} - -static Bool -I830SetParam(const DRIDriverContext *ctx, int param, int value) -{ - drmI830SetParam sp; - - memset(&sp, 0, sizeof(sp)); - sp.param = param; - sp.value = value; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { - fprintf(stderr, "I830 SetParam Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - fprintf(stderr, - "[drm] Mapping front buffer\n"); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), - sarea->front_size, - DRM_FRAME_BUFFER, /*DRM_AGP,*/ - 0, - &sarea->front_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); - return FALSE; - } - ctx->shared.hFrameBuffer = sarea->front_handle; - ctx->shared.fbSize = sarea->front_size; - fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", - sarea->front_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->back_offset), - sarea->back_size, DRM_AGP, 0, - &sarea->back_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", - sarea->back_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->depth_offset, - sarea->depth_size, DRM_AGP, 0, - &sarea->depth_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", - sarea->depth_handle); - -#if 0 - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->tex_offset, - sarea->tex_size, DRM_AGP, 0, - &sarea->tex_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] textures = 0x%08x\n", - sarea->tex_handle); -#endif - return TRUE; -} - - -static void -I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ -#if 1 - if (sarea->front_handle) { - drmRmMap(ctx->drmFD, sarea->front_handle); - sarea->front_handle = 0; - } -#endif - if (sarea->back_handle) { - drmRmMap(ctx->drmFD, sarea->back_handle); - sarea->back_handle = 0; - } - if (sarea->depth_handle) { - drmRmMap(ctx->drmFD, sarea->depth_handle); - sarea->depth_handle = 0; - } - if (sarea->tex_handle) { - drmRmMap(ctx->drmFD, sarea->tex_handle); - sarea->tex_handle = 0; - } -} - -static Bool -I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - if (drmAddMap(ctx->drmFD, - (drm_handle_t)pI830->LpRing->mem.Start, - pI830->LpRing->mem.Size, DRM_AGP, 0, - &pI830->ring_map) < 0) { - fprintf(stderr, - "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] ring buffer = 0x%08x\n", - pI830->ring_map); - - if (I830InitDma(ctx, pI830) == FALSE) { - return FALSE; - } - - /* init to zero to be safe */ - - I830DRIMapScreenRegions(ctx, pI830, sarea); - SetupDRIMM(ctx, pI830); - - if (ctx->pciDevice != PCI_CHIP_845_G && - ctx->pciDevice != PCI_CHIP_I830_M) { - I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); - } - - /* Okay now initialize the dma engine */ - { - pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { - fprintf(stderr, - "[drm] failure adding irq handler\n"); - pI830->irq = 0; - return FALSE; - } - else - fprintf(stderr, - "[drm] dma control initialized, using IRQ %d\n", - pI830->irq); - } - - fprintf(stderr, "[dri] visual configs initialized\n"); - - return TRUE; -} - -static Bool -I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - /* need to drmMap front and back buffers and zero them */ - drmAddress map_addr; - int ret; - - ret = drmMap(ctx->drmFD, - sarea->front_handle, - sarea->front_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map front buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->front_size); - drmUnmap(map_addr, sarea->front_size); - - - ret = drmMap(ctx->drmFD, - sarea->back_handle, - sarea->back_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map back buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->back_size); - drmUnmap(map_addr, sarea->back_size); - - return TRUE; -} - -static Bool -I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) - -{ - I830DRIPtr pI830DRI; - drmI830Sarea *pSAREAPriv; - int err; - - drm_page_size = getpagesize(); - - pI830->registerSize = ctx->MMIOSize; - /* This is a hack for now. We have to have more than a 4k page here - * because of the size of the state. However, the state should be - * in a per-context mapping. This will be added in the Mesa 3.5 port - * of the I830 driver. - */ - ctx->shared.SAREASize = SAREA_MAX; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("i915", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - - } - - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - - if (drmAddMap(ctx->drmFD, - ctx->MMIOStart, - ctx->MMIOSize, - DRM_REGISTERS, - DRM_READ_ONLY, - &pI830->registerHandle) < 0) { - fprintf(stderr, "[drm] drmAddMap mmio failed\n"); - return 0; - } - fprintf(stderr, - "[drm] register handle = 0x%08x\n", pI830->registerHandle); - - - if (!I830CheckDRMVersion(ctx, pI830)) { - return FALSE; - } - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the SAREA private data structure */ - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - - pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); - pI830->StolenMemory.Start = 0; - pI830->StolenMemory.End = pI830->StolenMemory.Size; - - pI830->MemoryAperture.Start = pI830->StolenMemory.End; - pI830->MemoryAperture.End = KB(40000); - pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; - - pI830->StolenPool.Fixed = pI830->StolenMemory; - pI830->StolenPool.Total = pI830->StolenMemory; - pI830->StolenPool.Free = pI830->StolenPool.Total; - pI830->FreeMemory = pI830->StolenPool.Total.Size; - - if (!AgpInit(ctx, pI830)) - return FALSE; - - if (I830AllocateMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - if (I830BindMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - pSAREAPriv->rotated_offset = -1; - pSAREAPriv->rotated_size = 0; - pSAREAPriv->rotated_pitch = ctx->shared.virtualWidth; - - pSAREAPriv->front_offset = pI830->FrontBuffer.Start; - pSAREAPriv->front_size = pI830->FrontBuffer.Size; - pSAREAPriv->width = ctx->shared.virtualWidth; - pSAREAPriv->height = ctx->shared.virtualHeight; - pSAREAPriv->pitch = ctx->shared.virtualWidth; - pSAREAPriv->virtualX = ctx->shared.virtualWidth; - pSAREAPriv->virtualY = ctx->shared.virtualHeight; - pSAREAPriv->back_offset = pI830->BackBuffer.Start; - pSAREAPriv->back_size = pI830->BackBuffer.Size; - pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; - pSAREAPriv->depth_size = pI830->DepthBuffer.Size; -#if 0 - pSAREAPriv->tex_offset = pI830->TexMem.Start; - pSAREAPriv->tex_size = pI830->TexMem.Size; -#endif - pSAREAPriv->log_tex_granularity = pI830->TexGranularity; - - ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); - ctx->driverClientMsgSize = sizeof(I830DRIRec); - pI830DRI = (I830DRIPtr)ctx->driverClientMsg; - pI830DRI->deviceID = pI830->Chipset; - pI830DRI->regsSize = I830_REG_SIZE; - pI830DRI->width = ctx->shared.virtualWidth; - pI830DRI->height = ctx->shared.virtualHeight; - pI830DRI->mem = ctx->shared.fbSize; - pI830DRI->cpp = ctx->cpp; - - pI830DRI->bitsPerPixel = ctx->bpp; - pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); - - err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); - if (err == FALSE) - return FALSE; - - I830SetupMemoryTiling(ctx, pI830); - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - I830ClearScreen(ctx, pI830, pSAREAPriv); - - I830SetRingRegs(ctx, pI830); - - return TRUE; -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa radeonValidateMode(). - */ -static int i830ValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa i810ValidateMode(). - */ -static int i830PostValidateMode( const DRIDriverContext *ctx ) -{ - I830Rec *pI830 = ctx->driverPrivate; - - I830SetRingRegs(ctx, pI830); - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p ctx - * and then calls I810ScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int i830InitFBDev( DRIDriverContext *ctx ) -{ - I830Rec *pI830 = calloc(1, sizeof(I830Rec)); - int i; - - { - int dummy = ctx->shared.virtualWidth; - - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - - ctx->shared.virtualWidth = dummy; - ctx->shared.Width = ctx->shared.virtualWidth; - } - - - for (i = 0; pitches[i] != 0; i++) { - if (pitches[i] >= ctx->shared.virtualWidth) { - ctx->shared.virtualWidth = pitches[i]; - break; - } - } - - ctx->driverPrivate = (void *)pI830; - - pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); - pI830->Chipset = ctx->chipset; - pI830->LinearAddr = ctx->FBStart; - - if (!I830ScreenInit( ctx, pI830 )) - return 0; - - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void i830HaltFBDev( DRIDriverContext *ctx ) -{ - drmI830Sarea *pSAREAPriv; - I830Rec *pI830 = ctx->driverPrivate; - - if (pI830->irq) { - drmCtlUninstHandler(ctx->drmFD); - pI830->irq = 0; } - - I830CleanupDma(ctx); - - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - - I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - - -extern void i810NotifyFocus( int ); - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -const struct DRIDriverRec __driDriver = { - i830ValidateMode, - i830PostValidateMode, - i830InitFBDev, - i830HaltFBDev, - NULL,//I830EngineShutdown, - NULL, //I830EngineRestore, -#ifndef _EMBEDDED - 0, -#else - i810NotifyFocus, -#endif -}; diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c deleted file mode 100644 index 1bc1089352..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c +++ /dev/null @@ -1,953 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - * Keith Whitwell - */ - -#include -#include -#include "glthread.h" -#include "errno.h" -#include "ws_dri_bufmgr.h" -#include "string.h" -#include "imports.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" - -/* - * This lock is here to protect drmBO structs changing underneath us during a - * validate list call, since validatelist cannot take individiual locks for - * each drmBO. Validatelist takes this lock in write mode. Any access to an - * individual drmBO should take this lock in read mode, since in that case, the - * driBufferObject mutex will protect the access. Locking order is - * driBufferObject mutex - > this rw lock. - */ - -_glthread_DECLARE_STATIC_MUTEX(bmMutex); -_glthread_DECLARE_STATIC_COND(bmCond); - -static int kernelReaders = 0; -static int num_buffers = 0; -static int num_user_buffers = 0; - -static drmBO *drmBOListBuf(void *iterator) -{ - drmBONode *node; - drmMMListHead *l = (drmMMListHead *) iterator; - node = DRMLISTENTRY(drmBONode, l, head); - return node->buf; -} - -static void *drmBOListIterator(drmBOList *list) -{ - void *ret = list->list.next; - - if (ret == &list->list) - return NULL; - return ret; -} - -static void *drmBOListNext(drmBOList *list, void *iterator) -{ - void *ret; - - drmMMListHead *l = (drmMMListHead *) iterator; - ret = l->next; - if (ret == &list->list) - return NULL; - return ret; -} - -static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, - uint64_t arg0, - uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } - else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADD(&node->head, &list->list); - list->numOnList++; - return node; -} - -static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, - uint64_t mask, int *newItem) -{ - drmBONode *node, *cur; - drmMMListHead *l; - - *newItem = 0; - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - } - if (!cur) { - cur = drmAddListItem(list, buf, flags, mask); - if (!cur) { - return -ENOMEM; - } - *newItem = 1; - cur->arg0 = flags; - cur->arg1 = mask; - } - else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - return 0; -} - -static void drmBOFreeList(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->list.next; - while(l != &list->list) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->list.next; - list->numCurrent--; - list->numOnList--; - } - - l = list->free.next; - while(l != &list->free) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->free.next; - list->numCurrent--; - } -} - -static int drmAdjustListNodes(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - int ret = 0; - - while(list->numCurrent < list->numTarget) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - ret = -ENOMEM; - break; - } - list->numCurrent++; - DRMLISTADD(&node->head, &list->free); - } - - while(list->numCurrent > list->numTarget) { - l = list->free.next; - if (l == &list->free) - break; - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - list->numCurrent--; - } - return ret; -} - -static int drmBOCreateList(int numTarget, drmBOList *list) -{ - DRMINITLISTHEAD(&list->list); - DRMINITLISTHEAD(&list->free); - list->numTarget = numTarget; - list->numCurrent = 0; - list->numOnList = 0; - return drmAdjustListNodes(list); -} - -static int drmBOResetList(drmBOList *list) -{ - drmMMListHead *l; - int ret; - - ret = drmAdjustListNodes(list); - if (ret) - return ret; - - l = list->list.next; - while (l != &list->list) { - DRMLISTDEL(l); - DRMLISTADD(l, &list->free); - list->numOnList--; - l = list->list.next; - } - return drmAdjustListNodes(list); -} - -void driWriteLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - while(kernelReaders != 0) - _glthread_COND_WAIT(bmCond, bmMutex); -} - -void driWriteUnlockKernelBO(void) -{ - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - kernelReaders++; - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadUnlockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - if (--kernelReaders == 0) - _glthread_COND_BROADCAST(bmCond); - _glthread_UNLOCK_MUTEX(bmMutex); -} - - - - -/* - * TODO: Introduce fence pools in the same way as - * buffer object pools. - */ - -typedef struct _DriBufferObject -{ - DriBufferPool *pool; - _glthread_Mutex mutex; - int refCount; - const char *name; - uint64_t flags; - unsigned hint; - unsigned alignment; - unsigned createdByReference; - void *private; - /* user-space buffer: */ - unsigned userBuffer; - void *userData; - unsigned userSize; -} DriBufferObject; - -typedef struct _DriBufferList { - drmBOList drmBuffers; /* List of kernel buffers needing validation */ - drmBOList driBuffers; /* List of user-space buffers needing validation */ -} DriBufferList; - - -void -bmError(int val, const char *file, const char *function, int line) -{ - _mesa_printf("Fatal video memory manager error \"%s\".\n" - "Check kernel logs or set the LIBGL_DEBUG\n" - "environment variable to \"verbose\" for more info.\n" - "Detected in file %s, line %d, function %s.\n", - strerror(-val), file, line, function); -#ifndef NDEBUG - abort(); -#else - abort(); -#endif -} - -extern drmBO * -driBOKernel(struct _DriBufferObject *buf) -{ - drmBO *ret; - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - ret = buf->pool->kernel(buf->pool, buf->private); - if (!ret) - BM_CKFATAL(-EINVAL); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - - return ret; -} - -void -driBOWaitIdle(struct _DriBufferObject *buf, int lazy) -{ - - /* - * This function may block. Is it sane to keep the mutex held during - * that time?? - */ - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void * -driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) -{ - void *virtual; - int retval; - - if (buf->userBuffer) { - return buf->userData; - } - - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - retval = buf->pool->map(buf->pool, buf->private, flags, hint, - &buf->mutex, &virtual); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval == 0 ? virtual : NULL; -} - -void -driBOUnmap(struct _DriBufferObject *buf) -{ - if (buf->userBuffer) - return; - - assert(buf->private != NULL); - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -unsigned long -driBOOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->offset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -unsigned long -driBOPoolOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->poolOffset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -uint64_t -driBOFlags(struct _DriBufferObject *buf) -{ - uint64_t ret; - - assert(buf->private != NULL); - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->flags(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - return ret; -} - -struct _DriBufferObject * -driBOReference(struct _DriBufferObject *buf) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (++buf->refCount == 1) { - _glthread_UNLOCK_MUTEX(buf->mutex); - BM_CKFATAL(-EINVAL); - } - _glthread_UNLOCK_MUTEX(buf->mutex); - return buf; -} - -void -driBOUnReference(struct _DriBufferObject *buf) -{ - int tmp; - - if (!buf) - return; - - _glthread_LOCK_MUTEX(buf->mutex); - tmp = --buf->refCount; - if (!tmp) { - _glthread_UNLOCK_MUTEX(buf->mutex); - if (buf->private) { - if (buf->createdByReference) - buf->pool->unreference(buf->pool, buf->private); - else - buf->pool->destroy(buf->pool, buf->private); - } - if (buf->userBuffer) - num_user_buffers--; - else - num_buffers--; - free(buf); - } else - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - - -int -driBOData(struct _DriBufferObject *buf, - unsigned size, const void *data, - DriBufferPool *newPool, - uint64_t flags) -{ - void *virtual = NULL; - int newBuffer; - int retval = 0; - struct _DriBufferPool *pool; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - pool = buf->pool; - - if (pool == NULL && newPool != NULL) { - buf->pool = newPool; - pool = newPool; - } - if (newPool == NULL) - newPool = pool; - - if (!pool->create) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "driBOData called on invalid buffer\n"); - BM_CKFATAL(-EINVAL); - } - - newBuffer = (!buf->private || pool != newPool || - pool->size(pool, buf->private) < size); - - if (!flags) - flags = buf->flags; - - if (newBuffer) { - - if (buf->createdByReference) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "driBOData requiring resizing called on " - "shared buffer.\n"); - BM_CKFATAL(-EINVAL); - } - - if (buf->private) - buf->pool->destroy(buf->pool, buf->private); - - pool = newPool; - buf->pool = newPool; - buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (!buf->private) - retval = -ENOMEM; - - if (retval == 0) - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); - } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { - /* - * Buffer is busy. need to create a new one. - */ - - void *newBuf; - - newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (newBuf) { - buf->pool->destroy(buf->pool, buf->private); - buf->private = newBuf; - } - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } else { - uint64_t flag_diff = flags ^ buf->flags; - - /* - * We might need to change buffer flags. - */ - - if (flag_diff){ - assert(pool->setStatus != NULL); - BM_CKFATAL(pool->unmap(pool, buf->private)); - BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, - buf->flags)); - if (!data) - goto out; - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } - } - - if (retval == 0) { - if (data) - memcpy(virtual, data, size); - - BM_CKFATAL(pool->unmap(pool, buf->private)); - } - - out: - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval; -} - -void -driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, const void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, - &virtual)); - memcpy((unsigned char *) virtual + offset, data, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); - memcpy(data, (unsigned char *) virtual + offset, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->private != NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer for setReferenced\n"); - BM_CKFATAL(-EINVAL); - - } - if (buf->pool->reference == NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer pool for setReferenced\n"); - BM_CKFATAL(-EINVAL); - } - buf->private = buf->pool->reference(buf->pool, handle); - if (!buf->private) { - _mesa_error(NULL, GL_OUT_OF_MEMORY, - "Invalid buffer pool for setStatic\n"); - BM_CKFATAL(-ENOMEM); - } - buf->createdByReference = GL_TRUE; - buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -int -driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint) -{ - struct _DriBufferObject *buf; - int i; - - flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - - ++num_buffers; - - assert(pool); - - for (i = 0; i < n; ++i) { - buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); - if (!buf) - return -ENOMEM; - - _glthread_INIT_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(buf->mutex); - buf->refCount = 1; - buf->flags = flags; - buf->hint = hint; - buf->name = name; - buf->alignment = alignment; - buf->pool = pool; - buf->createdByReference = 0; - _glthread_UNLOCK_MUTEX(buf->mutex); - buffers[i] = buf; - } - return 0; -} - -void -driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject **buffers, - void *ptr, unsigned bytes) -{ - const unsigned alignment = 1, flags = 0, hint = 0; - - --num_buffers; /* JB: is inced in GenBuffes */ - driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); - ++num_user_buffers; - - (*buffers)->userBuffer = 1; - (*buffers)->userData = ptr; - (*buffers)->userSize = bytes; -} - -void -driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) -{ - int i; - - for (i = 0; i < n; ++i) { - driBOUnReference(buffers[i]); - } -} - - -void -driInitBufMgr(int fd) -{ - ; -} - -/* - * Note that lists are per-context and don't need mutex protection. - */ - -struct _DriBufferList * -driBOCreateList(int target) -{ - struct _DriBufferList *list = calloc(sizeof(*list), 1); - - BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); - BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); - return list; -} - -int -driBOResetList(struct _DriBufferList * list) -{ - int ret; - ret = drmBOResetList(&list->drmBuffers); - if (ret) - return ret; - ret = drmBOResetList(&list->driBuffers); - return ret; -} - -void -driBOFreeList(struct _DriBufferList * list) -{ - drmBOFreeList(&list->drmBuffers); - drmBOFreeList(&list->driBuffers); - free(list); -} - - -/* - * Copied from libdrm, because it is needed by driAddValidateItem. - */ - -static drmBONode * -driAddListItem(drmBOList * list, drmBO * item, - uint64_t arg0, uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - memset(&node->bo_arg, 0, sizeof(node->bo_arg)); - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADDTAIL(&node->head, &list->list); - list->numOnList++; - return node; -} - -/* - * Slightly modified version compared to the libdrm version. - * This one returns the list index of the buffer put on the list. - */ - -static int -driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, - uint64_t mask, int *itemLoc, - struct _drmBONode **pnode) -{ - drmBONode *node, *cur; - drmMMListHead *l; - int count = 0; - - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - count++; - } - if (!cur) { - cur = driAddListItem(list, buf, flags, mask); - if (!cur) - return -ENOMEM; - - cur->arg0 = flags; - cur->arg1 = mask; - } else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - *itemLoc = count; - *pnode = cur; - return 0; -} - - -void -driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node) -{ - int newItem; - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(driAddValidateItem(&list->drmBuffers, - buf->pool->kernel(buf->pool, buf->private), - flags, mask, itemLoc, node)); - BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, - flags, mask, &newItem)); - if (newItem) - buf->refCount++; - - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -drmBOList *driGetdrmBOList(struct _DriBufferList *list) -{ - driWriteLockKernelBO(); - return &list->drmBuffers; -} - -void driPutdrmBOList(struct _DriBufferList *list) -{ - driWriteUnlockKernelBO(); -} - - -void -driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->fence) - BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - -void -driBOUnrefUserList(struct _DriBufferList *list) -{ - struct _DriBufferObject *buf; - void *curBuf; - - curBuf = drmBOListIterator(&list->driBuffers); - while (curBuf) { - buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - -struct _DriFenceObject * -driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, const char *name, - drmFence *kFence) -{ - struct _DriFenceObject *fence; - struct _DriBufferObject *buf; - void *curBuf; - - fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, - kFence, sizeof(*kFence)); - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space fencing callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - driBOFence(buf, fence); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } - - driBOResetList(list); - return fence; -} - -void -driBOValidateUserList(struct _DriBufferList * list) -{ - void *curBuf; - struct _DriBufferObject *buf; - - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space validation callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->validate) - BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); - _glthread_UNLOCK_MUTEX(buf->mutex); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - - -void -driPoolTakeDown(struct _DriBufferPool *pool) -{ - pool->takeDown(pool); - -} - -unsigned long -driBOSize(struct _DriBufferObject *buf) -{ - unsigned long size; - - _glthread_LOCK_MUTEX(buf->mutex); - size = buf->pool->size(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return size; - -} - -drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) -{ - return &list->drmBuffers; -} - -drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) -{ - return &list->driBuffers; -} - diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h deleted file mode 100644 index fdaf5ee93a..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - * Keith Whitwell - */ - -#ifndef _PSB_BUFMGR_H_ -#define _PSB_BUFMGR_H_ -#include -#include "i915_drm.h" -#include "ws_dri_fencemgr.h" - -typedef struct _drmBONode -{ - drmMMListHead head; - drmBO *buf; - struct drm_i915_op_arg bo_arg; - uint64_t arg0; - uint64_t arg1; -} drmBONode; - -typedef struct _drmBOList { - unsigned numTarget; - unsigned numCurrent; - unsigned numOnList; - drmMMListHead list; - drmMMListHead free; -} drmBOList; - - -struct _DriFenceObject; -struct _DriBufferObject; -struct _DriBufferPool; -struct _DriBufferList; - -/* - * Return a pointer to the libdrm buffer object this DriBufferObject - * uses. - */ - -extern drmBO *driBOKernel(struct _DriBufferObject *buf); -extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, - unsigned hint); -extern void driBOUnmap(struct _DriBufferObject *buf); -extern unsigned long driBOOffset(struct _DriBufferObject *buf); -extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); - -extern uint64_t driBOFlags(struct _DriBufferObject *buf); -extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); -extern void driBOUnReference(struct _DriBufferObject *buf); - -extern int driBOData(struct _DriBufferObject *r_buf, - unsigned size, const void *data, - struct _DriBufferPool *pool, uint64_t flags); - -extern void driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - const void *data); -extern void driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - void *data); -extern int driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint); -extern void driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject *buffers[], - void *ptr, unsigned bytes); -extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); -extern void driInitBufMgr(int fd); -extern struct _DriBufferList *driBOCreateList(int target); -extern int driBOResetList(struct _DriBufferList * list); -extern void driBOAddListItem(struct _DriBufferList * list, - struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node); - -extern void driBOValidateList(int fd, struct _DriBufferList * list); -extern void driBOFreeList(struct _DriBufferList * list); -extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, - const char *name, - drmFence *kFence); -extern void driBOUnrefUserList(struct _DriBufferList *list); -extern void driBOValidateUserList(struct _DriBufferList * list); -extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); -extern void driPutdrmBOList(struct _DriBufferList *list); - -extern void driBOFence(struct _DriBufferObject *buf, - struct _DriFenceObject *fence); - -extern void driPoolTakeDown(struct _DriBufferPool *pool); -extern void driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle); -unsigned long driBOSize(struct _DriBufferObject *buf); -extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); -extern void driPoolTakeDown(struct _DriBufferPool *pool); - -extern void driReadLockKernelBO(void); -extern void driReadUnlockKernelBO(void); -extern void driWriteLockKernelBO(void); -extern void driWriteUnlockKernelBO(void); - -/* - * For debugging purposes. - */ - -extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); -extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); -#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufpool.h b/src/gallium/winsys/dri/intel/ws_dri_bufpool.h deleted file mode 100644 index 3a302e13d3..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_bufpool.h +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#ifndef _PSB_BUFPOOL_H_ -#define _PSB_BUFPOOL_H_ - -#include -#include -struct _DriFenceObject; - -typedef struct _DriBufferPool -{ - int fd; - int (*map) (struct _DriBufferPool * pool, void *private, - unsigned flags, int hint, _glthread_Mutex *mutex, - void **virtual); - int (*unmap) (struct _DriBufferPool * pool, void *private); - int (*destroy) (struct _DriBufferPool * pool, void *private); - unsigned long (*offset) (struct _DriBufferPool * pool, void *private); - unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); - uint64_t (*flags) (struct _DriBufferPool * pool, void *private); - unsigned long (*size) (struct _DriBufferPool * pool, void *private); - void *(*create) (struct _DriBufferPool * pool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment); - void *(*reference) (struct _DriBufferPool * pool, unsigned handle); - int (*unreference) (struct _DriBufferPool * pool, void *private); - int (*fence) (struct _DriBufferPool * pool, void *private, - struct _DriFenceObject * fence); - drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); - int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); - int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy); - int (*setStatus) (struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags); - void (*takeDown) (struct _DriBufferPool * pool); - void *data; -} DriBufferPool; - -extern void bmError(int val, const char *file, const char *function, - int line); -#define BM_CKFATAL(val) \ - do{ \ - int tstVal = (val); \ - if (tstVal) \ - bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ - } while(0); - - -/* - * Builtin pools. - */ - -/* - * Kernel buffer objects. Size in multiples of page size. Page size aligned. - */ - -extern struct _DriBufferPool *driDRMPoolInit(int fd); -extern struct _DriBufferPool *driMallocPoolInit(void); - -struct _DriFreeSlabManager; -extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan); -extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); -extern struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); - - -#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_drmpool.c b/src/gallium/winsys/dri/intel/ws_dri_drmpool.c deleted file mode 100644 index 7c55dbc674..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_drmpool.c +++ /dev/null @@ -1,268 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" -#include "assert.h" - -/* - * Buffer pool implementation using DRM buffer objects as DRI buffer objects. - */ - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - unsigned pageSize = getpagesize(); - - if (!buf) - return NULL; - - if ((alignment > pageSize) && (alignment % pageSize)) { - free(buf); - return NULL; - } - - ret = drmBOCreate(pool->fd, size, alignment / pageSize, - NULL, - flags, hint, buf); - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static void * -pool_reference(struct _DriBufferPool *pool, unsigned handle) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - - if (!buf) - return NULL; - - ret = drmBOReference(pool->fd, handle, buf); - - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unreference(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOMap(pool->fd, buf, flags, hint, virtual); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOUnmap(pool->fd, buf); - driReadUnlockKernelBO(); - - return ret; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long offset; - - driReadLockKernelBO(); - assert(buf->flags & DRM_BO_FLAG_NO_MOVE); - offset = buf->offset; - driReadUnlockKernelBO(); - - return buf->offset; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - uint64_t flags; - - driReadLockKernelBO(); - flags = buf->flags; - driReadUnlockKernelBO(); - - return flags; -} - - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long size; - - driReadLockKernelBO(); - size = buf->size; - driReadUnlockKernelBO(); - - return buf->size; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - /* - * Noop. The kernel handles all fencing. - */ - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - return (drmBO *) private; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); - driReadUnlockKernelBO(); - - return ret; -} - - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - -/*static int -pool_setStatus(struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags) -{ - drmBO *buf = (drmBO *) private; - uint64_t new_flags = old_flags ^ flag_diff; - int ret; - - driReadLockKernelBO(); - ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, - 0, 0, 0); - driReadUnlockKernelBO(); - return ret; -}*/ - -struct _DriBufferPool * -driDRMPoolInit(int fd) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - - if (!pool) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - pool->reference = &pool_reference; - pool->unreference = &pool_unreference; - pool->data = NULL; - return pool; -} diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c deleted file mode 100644 index 1f893b47ce..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c +++ /dev/null @@ -1,377 +0,0 @@ -#include "ws_dri_fencemgr.h" -#include "glthread.h" -#include -#include -#include - -/* - * Note: Locking order is - * _DriFenceObject::mutex - * _DriFenceMgr::mutex - */ - -struct _DriFenceMgr { - /* - * Constant members. Need no mutex protection. - */ - struct _DriFenceMgrCreateInfo info; - void *private; - - /* - * These members are protected by this->mutex - */ - _glthread_Mutex mutex; - int refCount; - drmMMListHead *heads; - int num_fences; -}; - -struct _DriFenceObject { - - /* - * These members are constant and need no mutex protection. - */ - struct _DriFenceMgr *mgr; - uint32_t fence_class; - uint32_t fence_type; - - /* - * These members are protected by mgr->mutex. - */ - drmMMListHead head; - int refCount; - - /* - * These members are protected by this->mutex. - */ - _glthread_Mutex mutex; - uint32_t signaled_type; - void *private; -}; - -uint32_t -driFenceType(struct _DriFenceObject *fence) -{ - return fence->fence_type; -} - -struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) -{ - struct _DriFenceMgr *tmp; - uint32_t i; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->refCount = 1; - tmp->info = *info; - tmp->num_fences = 0; - tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); - if (!tmp->heads) - goto out_err; - - for (i=0; iinfo.num_classes; ++i) { - DRMINITLISTHEAD(&tmp->heads[i]); - } - _glthread_UNLOCK_MUTEX(tmp->mutex); - return tmp; - - out_err: - if (tmp) - free(tmp); - return NULL; -} - -static void -driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) -{ - struct _DriFenceMgr *mgr = *pMgr; - - *pMgr = NULL; - if (--mgr->refCount == 0) - free(mgr); - else - _glthread_UNLOCK_MUTEX(mgr->mutex); -} - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr) -{ - _glthread_LOCK_MUTEX((*pMgr)->mutex); - driFenceMgrUnrefUnlock(pMgr); -} - -static void -driFenceUnReferenceLocked(struct _DriFenceObject **pFence) -{ - struct _DriFenceObject *fence = *pFence; - struct _DriFenceMgr *mgr = fence->mgr; - - *pFence = NULL; - if (--fence->refCount == 0) { - DRMLISTDELINIT(&fence->head); - if (fence->private) - mgr->info.unreference(mgr, &fence->private); - --mgr->num_fences; - fence->mgr = NULL; - --mgr->refCount; - free(fence); - - } -} - - -static void -driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, - drmMMListHead *list, - uint32_t fence_class, - uint32_t fence_type) -{ - struct _DriFenceObject *entry; - drmMMListHead *prev; - - while(list != &mgr->heads[fence_class]) { - entry = DRMLISTENTRY(struct _DriFenceObject, list, head); - - /* - * Up refcount so that entry doesn't disappear from under us - * when we unlock-relock mgr to get the correct locking order. - */ - - ++entry->refCount; - _glthread_UNLOCK_MUTEX(mgr->mutex); - _glthread_LOCK_MUTEX(entry->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - - prev = list->prev; - - - - if (list->prev == list) { - - /* - * Somebody else removed the entry from the list. - */ - - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - return; - } - - entry->signaled_type |= (fence_type & entry->fence_type); - if (entry->signaled_type == entry->fence_type) { - DRMLISTDELINIT(list); - mgr->info.unreference(mgr, &entry->private); - } - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - list = prev; - } -} - - -int -driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint) -{ - struct _DriFenceMgr *mgr = fence->mgr; - int ret = 0; - - _glthread_LOCK_MUTEX(fence->mutex); - - if ((fence->signaled_type & fence_type) == fence_type) - goto out0; - - ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); - if (ret) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - fence_type); - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) -{ - uint32_t ret; - - _glthread_LOCK_MUTEX(fence->mutex); - ret = fence->signaled_type; - _glthread_UNLOCK_MUTEX(fence->mutex); - - return ret; -} - -int -driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, - uint32_t *signaled) -{ - int ret = 0; - struct _DriFenceMgr *mgr; - - _glthread_LOCK_MUTEX(fence->mutex); - mgr = fence->mgr; - *signaled = fence->signaled_type; - if ((fence->signaled_type & flush_type) == flush_type) - goto out0; - - ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); - if (ret) { - *signaled = fence->signaled_type; - goto out0; - } - - if ((fence->signaled_type | *signaled) == fence->signaled_type) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - *signaled); - - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -struct _DriFenceObject * -driFenceReference(struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(fence->mgr->mutex); - ++fence->refCount; - _glthread_UNLOCK_MUTEX(fence->mgr->mutex); - return fence; -} - -void -driFenceUnReference(struct _DriFenceObject **pFence) -{ - struct _DriFenceMgr *mgr; - - if (*pFence == NULL) - return; - - mgr = (*pFence)->mgr; - _glthread_LOCK_MUTEX(mgr->mutex); - ++mgr->refCount; - driFenceUnReferenceLocked(pFence); - driFenceMgrUnrefUnlock(&mgr); -} - -struct _DriFenceObject -*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, - uint32_t fence_type, void *private, size_t private_size) -{ - struct _DriFenceObject *fence; - size_t fence_size = sizeof(*fence); - - if (private_size) - fence_size = ((fence_size + 15) & ~15); - - fence = calloc(1, fence_size + private_size); - - if (!fence) { - int ret = mgr->info.finish(mgr, private, fence_type, 0); - - if (ret) - usleep(10000000); - - return NULL; - } - - _glthread_INIT_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - fence->refCount = 1; - DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); - fence->mgr = mgr; - ++mgr->refCount; - ++mgr->num_fences; - _glthread_UNLOCK_MUTEX(mgr->mutex); - fence->fence_class = fence_class; - fence->fence_type = fence_type; - fence->signaled_type = 0; - fence->private = private; - if (private_size) { - fence->private = (void *)(((uint8_t *) fence) + fence_size); - memcpy(fence->private, private, private_size); - } - - _glthread_UNLOCK_MUTEX(fence->mutex); - return fence; -} - - -static int -tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type) -{ - long fd = (long) mgr->private; - int dummy; - drmFence *fence = (drmFence *) private; - int ret; - - *signaled_type = 0; - ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); - if (ret) - return ret; - - *signaled_type = fence->signaled; - - return 0; -} - -static int -tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, - int lazy_hint) -{ - long fd = (long) mgr->private; - unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; - - return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); -} - -static int -tUnref(struct _DriFenceMgr *mgr, void **private) -{ - long fd = (long) mgr->private; - drmFence *fence = (drmFence *) *private; - *private = NULL; - - return drmFenceUnreference(fd, fence); -} - -struct _DriFenceMgr *driFenceMgrTTMInit(int fd) -{ - struct _DriFenceMgrCreateInfo info; - struct _DriFenceMgr *mgr; - - info.flags = DRI_FENCE_CLASS_ORDERED; - info.num_classes = 4; - info.signaled = tSignaled; - info.finish = tFinish; - info.unreference = tUnref; - - mgr = driFenceMgrCreate(&info); - if (mgr == NULL) - return NULL; - - mgr->private = (void *) (long) fd; - return mgr; -} - diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h deleted file mode 100644 index 4ea58dfe18..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef DRI_FENCEMGR_H -#define DRI_FENCEMGR_H - -#include -#include - -struct _DriFenceObject; -struct _DriFenceMgr; - -/* - * Do a quick check to see if the fence manager has registered the fence - * object as signaled. Note that this function may return a false negative - * answer. - */ -extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); - -/* - * Check if the fence object is signaled. This function can be substantially - * more expensive to call than the above function, but will not return a false - * negative answer. The argument "flush_type" sets the types that the - * underlying mechanism must make sure will eventually signal. - */ -extern int driFenceSignaledType(struct _DriFenceObject *fence, - uint32_t flush_type, uint32_t *signaled); - -/* - * Convenience functions. - */ - -static inline int driFenceSignaled(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types; - int ret = driFenceSignaledType(fence, flush_type, &signaled_types); - if (ret) - return 0; - return ((signaled_types & flush_type) == flush_type); -} - -static inline int driFenceSignaledCached(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types = - driFenceSignaledTypeCached(fence); - - return ((signaled_types & flush_type) == flush_type); -} - -/* - * Reference a fence object. - */ -extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); - -/* - * Unreference a fence object. The fence object pointer will be reset to NULL. - */ - -extern void driFenceUnReference(struct _DriFenceObject **pFence); - - -/* - * Wait for a fence to signal the indicated fence_type. - * If "lazy_hint" is true, it indicates that the wait may sleep to avoid - * busy-wait polling. - */ -extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint); - -/* - * Create a DriFenceObject for manager "mgr". - * - * "private" is a pointer that should be used for the callbacks in - * struct _DriFenceMgrCreateInfo. - * - * if private_size is nonzero, then the info stored at *private, with size - * private size will be copied and the fence manager will instead use a - * pointer to the copied data for the callbacks in - * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by - * "private" may be destroyed after the call to driFenceCreate. - */ -extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, - uint32_t fence_class, - uint32_t fence_type, - void *private, - size_t private_size); - -extern uint32_t driFenceType(struct _DriFenceObject *fence); - -/* - * Fence creations are ordered. If a fence signals a fence_type, - * it is safe to assume that all fences of the same class that was - * created before that fence has signaled the same type. - */ - -#define DRI_FENCE_CLASS_ORDERED (1 << 0) - -struct _DriFenceMgrCreateInfo { - uint32_t flags; - uint32_t num_classes; - int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type); - int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); - int (*unreference) (struct _DriFenceMgr *mgr, void **private); -}; - -extern struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr); - -extern struct _DriFenceMgr * -driFenceMgrTTMInit(int fd); - -#endif diff --git a/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c b/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c deleted file mode 100644 index bf97d7e440..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c +++ /dev/null @@ -1,162 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include -#include -#include "imports.h" -#include "glthread.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" -#include "intel_screen.h" - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - unsigned long *private = malloc(size + 2*sizeof(unsigned long)); - if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) - abort(); - - *private = size; - return (void *)private; -} - - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - free(private); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - *virtual = (void *)((unsigned long *)private + 2); - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); - return 0UL; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - return *(unsigned long *) private; -} - - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - abort(); - return 0UL; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - abort(); - return NULL; -} - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - - -struct _DriBufferPool * -driMallocPoolInit(void) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - if (!pool) - return NULL; - - pool->data = NULL; - pool->fd = -1; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - return pool; -} diff --git a/src/gallium/winsys/dri/intel/ws_dri_slabpool.c b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c deleted file mode 100644 index 62d82bbd94..0000000000 --- a/src/gallium/winsys/dri/intel/ws_dri_slabpool.c +++ /dev/null @@ -1,968 +0,0 @@ -/************************************************************************** - * - * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#include -#include -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" -#include "ws_dri_bufmgr.h" -#include "glthread.h" - -#define DRI_SLABPOOL_ALLOC_RETRIES 100 - -struct _DriSlab; - -struct _DriSlabBuffer { - int isSlabBuffer; - drmBO *bo; - struct _DriFenceObject *fence; - struct _DriSlab *parent; - drmMMListHead head; - uint32_t mapCount; - uint32_t start; - uint32_t fenceType; - int unFenced; - _glthread_Cond event; -}; - -struct _DriKernelBO { - int fd; - drmBO bo; - drmMMListHead timeoutHead; - drmMMListHead head; - struct timeval timeFreed; - uint32_t pageAlignment; - void *virtual; -}; - -struct _DriSlab{ - drmMMListHead head; - drmMMListHead freeBuffers; - uint32_t numBuffers; - uint32_t numFree; - struct _DriSlabBuffer *buffers; - struct _DriSlabSizeHeader *header; - struct _DriKernelBO *kbo; -}; - - -struct _DriSlabSizeHeader { - drmMMListHead slabs; - drmMMListHead freeSlabs; - drmMMListHead delayedBuffers; - uint32_t numDelayed; - struct _DriSlabPool *slabPool; - uint32_t bufSize; - _glthread_Mutex mutex; -}; - -struct _DriFreeSlabManager { - struct timeval slabTimeout; - struct timeval checkInterval; - struct timeval nextCheck; - drmMMListHead timeoutList; - drmMMListHead unCached; - drmMMListHead cached; - _glthread_Mutex mutex; -}; - - -struct _DriSlabPool { - - /* - * The data of this structure remains constant after - * initialization and thus needs no mutex protection. - */ - - struct _DriFreeSlabManager *fMan; - uint64_t proposedFlags; - uint64_t validMask; - uint32_t *bucketSizes; - uint32_t numBuckets; - uint32_t pageSize; - int fd; - int pageAlignment; - int maxSlabSize; - int desiredNumBuffers; - struct _DriSlabSizeHeader *headers; -}; - -/* - * FIXME: Perhaps arrange timeout slabs in size buckets for fast - * retreival?? - */ - - -static inline int -driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) -{ - return ((arg1->tv_sec > arg2->tv_sec) || - ((arg1->tv_sec == arg2->tv_sec) && - (arg1->tv_usec > arg2->tv_usec))); -} - -static inline void -driTimeAdd(struct timeval *arg, struct timeval *add) -{ - unsigned int sec; - - arg->tv_sec += add->tv_sec; - arg->tv_usec += add->tv_usec; - sec = arg->tv_usec / 1000000; - arg->tv_sec += sec; - arg->tv_usec -= sec*1000000; -} - -static void -driFreeKernelBO(struct _DriKernelBO *kbo) -{ - if (!kbo) - return; - - (void) drmBOUnreference(kbo->fd, &kbo->bo); - free(kbo); -} - - -static void -driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, - struct timeval *time) -{ - drmMMListHead *list, *next; - struct _DriKernelBO *kbo; - - if (!driTimeAfterEq(time, &fMan->nextCheck)) - return; - - for (list = fMan->timeoutList.next, next = list->next; - list != &fMan->timeoutList; - list = next, next = list->next) { - - kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); - - if (!driTimeAfterEq(time, &kbo->timeFreed)) - break; - - DRMLISTDELINIT(&kbo->timeoutHead); - DRMLISTDELINIT(&kbo->head); - driFreeKernelBO(kbo); - } - - fMan->nextCheck = *time; - driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); -} - - -/* - * Add a _DriKernelBO to the free slab manager. - * This means that it is available for reuse, but if it's not - * reused in a while, it will be freed. - */ - -static void -driSetKernelBOFree(struct _DriFreeSlabManager *fMan, - struct _DriKernelBO *kbo) -{ - struct timeval time; - - _glthread_LOCK_MUTEX(fMan->mutex); - gettimeofday(&time, NULL); - driTimeAdd(&time, &fMan->slabTimeout); - - kbo->timeFreed = time; - - if (kbo->bo.flags & DRM_BO_FLAG_CACHED) - DRMLISTADD(&kbo->head, &fMan->cached); - else - DRMLISTADD(&kbo->head, &fMan->unCached); - - DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); - driFreeTimeoutKBOsLocked(fMan, &time); - - _glthread_UNLOCK_MUTEX(fMan->mutex); -} - -/* - * Get a _DriKernelBO for us to use as storage for a slab. - * - */ - -static struct _DriKernelBO * -driAllocKernelBO(struct _DriSlabSizeHeader *header) - -{ - struct _DriSlabPool *slabPool = header->slabPool; - struct _DriFreeSlabManager *fMan = slabPool->fMan; - drmMMListHead *list, *next, *head; - uint32_t size = header->bufSize * slabPool->desiredNumBuffers; - struct _DriKernelBO *kbo; - struct _DriKernelBO *kboTmp; - int ret; - - /* - * FIXME: We should perhaps allow some variation in slabsize in order - * to efficiently reuse slabs. - */ - - size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; - size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); - _glthread_LOCK_MUTEX(fMan->mutex); - - kbo = NULL; - - retry: - head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? - &fMan->cached : &fMan->unCached; - - for (list = head->next, next = list->next; - list != head; - list = next, next = list->next) { - - kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); - - if ((kboTmp->bo.size == size) && - (slabPool->pageAlignment == 0 || - (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { - - if (!kbo) - kbo = kboTmp; - - if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) - break; - - } - } - - if (kbo) { - DRMLISTDELINIT(&kbo->head); - DRMLISTDELINIT(&kbo->timeoutHead); - } - - _glthread_UNLOCK_MUTEX(fMan->mutex); - - if (kbo) { - uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; - - ret = 0; - if (new_mask) { - ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, - new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); - } - if (ret == 0) - return kbo; - - driFreeKernelBO(kbo); - kbo = NULL; - goto retry; - } - - kbo = calloc(1, sizeof(struct _DriKernelBO)); - if (!kbo) - return NULL; - - kbo->fd = slabPool->fd; - DRMINITLISTHEAD(&kbo->head); - DRMINITLISTHEAD(&kbo->timeoutHead); - ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, - slabPool->proposedFlags, - DRM_BO_HINT_DONT_FENCE, &kbo->bo); - if (ret) - goto out_err0; - - ret = drmBOMap(kbo->fd, &kbo->bo, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &kbo->virtual); - - if (ret) - goto out_err1; - - ret = drmBOUnmap(kbo->fd, &kbo->bo); - if (ret) - goto out_err1; - - return kbo; - - out_err1: - drmBOUnreference(kbo->fd, &kbo->bo); - out_err0: - free(kbo); - return NULL; -} - - -static int -driAllocSlab(struct _DriSlabSizeHeader *header) -{ - struct _DriSlab *slab; - struct _DriSlabBuffer *buf; - uint32_t numBuffers; - int ret; - int i; - - slab = calloc(1, sizeof(*slab)); - if (!slab) - return -ENOMEM; - - slab->kbo = driAllocKernelBO(header); - if (!slab->kbo) { - ret = -ENOMEM; - goto out_err0; - } - - numBuffers = slab->kbo->bo.size / header->bufSize; - - slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); - if (!slab->buffers) { - ret = -ENOMEM; - goto out_err1; - } - - DRMINITLISTHEAD(&slab->head); - DRMINITLISTHEAD(&slab->freeBuffers); - slab->numBuffers = numBuffers; - slab->numFree = 0; - slab->header = header; - - buf = slab->buffers; - for (i=0; i < numBuffers; ++i) { - buf->parent = slab; - buf->start = i* header->bufSize; - buf->mapCount = 0; - buf->isSlabBuffer = 1; - _glthread_INIT_COND(buf->event); - DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); - slab->numFree++; - buf++; - } - - DRMLISTADDTAIL(&slab->head, &header->slabs); - - return 0; - - out_err1: - driSetKernelBOFree(header->slabPool->fMan, slab->kbo); - free(slab->buffers); - out_err0: - free(slab); - return ret; -} - -/* - * Delete a buffer from the slab header delayed list and put - * it on the slab free list. - */ - -static void -driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) -{ - struct _DriSlab *slab = buf->parent; - struct _DriSlabSizeHeader *header = slab->header; - drmMMListHead *list = &buf->head; - - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &slab->freeBuffers); - slab->numFree++; - - if (slab->head.next == &slab->head) - DRMLISTADDTAIL(&slab->head, &header->slabs); - - if (slab->numFree == slab->numBuffers) { - list = &slab->head; - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &header->freeSlabs); - } - - if (header->slabs.next == &header->slabs || - slab->numFree != slab->numBuffers) { - - drmMMListHead *next; - struct _DriFreeSlabManager *fMan = header->slabPool->fMan; - - for (list = header->freeSlabs.next, next = list->next; - list != &header->freeSlabs; - list = next, next = list->next) { - - slab = DRMLISTENTRY(struct _DriSlab, list, head); - - DRMLISTDELINIT(list); - driSetKernelBOFree(fMan, slab->kbo); - free(slab->buffers); - free(slab); - } - } -} - -static void -driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) -{ - drmMMListHead *list, *prev, *first; - struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - int firstWasSignaled = 1; - int signaled; - int i; - int ret; - - /* - * Rerun the freeing test if the youngest tested buffer - * was signaled, since there might be more idle buffers - * in the delay list. - */ - - while (firstWasSignaled) { - firstWasSignaled = 0; - signaled = 0; - first = header->delayedBuffers.next; - - /* Only examine the oldest 1/3 of delayed buffers: - */ - if (header->numDelayed > 3) { - for (i = 0; i < header->numDelayed; i += 3) { - first = first->next; - } - } - - for (list = first, prev = list->prev; - list != &header->delayedBuffers; - list = prev, prev = list->prev) { - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - slab = buf->parent; - - if (!signaled) { - if (wait) { - ret = driFenceFinish(buf->fence, buf->fenceType, 0); - if (ret) - break; - signaled = 1; - wait = 0; - } else { - signaled = driFenceSignaled(buf->fence, buf->fenceType); - } - if (signaled) { - if (list == first) - firstWasSignaled = 1; - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } - } -} - - -static struct _DriSlabBuffer * -driSlabAllocBuffer(struct _DriSlabSizeHeader *header) -{ - static struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - drmMMListHead *list; - int count = DRI_SLABPOOL_ALLOC_RETRIES; - - _glthread_LOCK_MUTEX(header->mutex); - while(header->slabs.next == &header->slabs && count > 0) { - driSlabCheckFreeLocked(header, 0); - if (header->slabs.next != &header->slabs) - break; - - _glthread_UNLOCK_MUTEX(header->mutex); - if (count != DRI_SLABPOOL_ALLOC_RETRIES) - usleep(1); - _glthread_LOCK_MUTEX(header->mutex); - (void) driAllocSlab(header); - count--; - } - - list = header->slabs.next; - if (list == &header->slabs) { - _glthread_UNLOCK_MUTEX(header->mutex); - return NULL; - } - slab = DRMLISTENTRY(struct _DriSlab, list, head); - if (--slab->numFree == 0) - DRMLISTDELINIT(list); - - list = slab->freeBuffers.next; - DRMLISTDELINIT(list); - - _glthread_UNLOCK_MUTEX(header->mutex); - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - return buf; -} - -static void * -pool_create(struct _DriBufferPool *driPool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment) -{ - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - struct _DriSlabSizeHeader *header; - struct _DriSlabBuffer *buf; - void *dummy; - int i; - int ret; - - /* - * FIXME: Check for compatibility. - */ - - header = pool->headers; - for (i=0; inumBuckets; ++i) { - if (header->bufSize >= size) - break; - header++; - } - - if (i < pool->numBuckets) - return driSlabAllocBuffer(header); - - - /* - * Fall back to allocate a buffer object directly from DRM. - * and wrap it in a driBO structure. - */ - - - buf = calloc(1, sizeof(*buf)); - - if (!buf) - return NULL; - - buf->bo = calloc(1, sizeof(*buf->bo)); - if (!buf->bo) - goto out_err0; - - if (alignment) { - if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) - goto out_err1; - if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) - goto out_err1; - } - - ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, - flags, hint, buf->bo); - if (ret) - goto out_err1; - - ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &dummy); - if (ret) - goto out_err2; - - ret = drmBOUnmap(pool->fd, buf->bo); - if (ret) - goto out_err2; - - return buf; - out_err2: - drmBOUnreference(pool->fd, buf->bo); - out_err1: - free(buf->bo); - out_err0: - free(buf); - return NULL; -} - -static int -pool_destroy(struct _DriBufferPool *driPool, void *private) -{ - struct _DriSlabBuffer *buf = - (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - int ret; - - ret = drmBOUnreference(pool->fd, buf->bo); - free(buf->bo); - free(buf); - return ret; - } - - slab = buf->parent; - header = slab->header; - - _glthread_LOCK_MUTEX(header->mutex); - buf->unFenced = 0; - buf->mapCount = 0; - - if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { - DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); - header->numDelayed++; - } else { - if (buf->fence) - driFenceUnReference(&buf->fence); - driSlabFreeBufferLocked(buf); - } - - _glthread_UNLOCK_MUTEX(header->mutex); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *driPool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - while(buf->unFenced) - _glthread_COND_WAIT(buf->event, *mutex); - - if (!buf->fence) - return 0; - - driFenceFinish(buf->fence, buf->fenceType, lazy); - driFenceUnReference(&buf->fence); - - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - int busy; - - if (buf->isSlabBuffer) - busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); - else - busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); - - - if (busy) { - if (hint & DRM_BO_HINT_DONT_BLOCK) - return -EBUSY; - else { - (void) pool_waitIdle(pool, private, mutex, 0); - } - } - - ++buf->mapCount; - *virtual = (buf->isSlabBuffer) ? - (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : - (void *) buf->bo->virtual; - - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - --buf->mapCount; - if (buf->mapCount == 0 && buf->isSlabBuffer) - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return buf->bo->offset; - } - - slab = buf->parent; - header = slab->header; - - (void) header; - assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return slab->kbo->bo.offset + buf->start; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - return buf->start; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return buf->bo->flags; - - return buf->parent->kbo->bo.flags; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - if (!buf->isSlabBuffer) - return buf->bo->size; - - return buf->parent->header->bufSize; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - drmBO *bo; - - if (buf->fence) - driFenceUnReference(&buf->fence); - - buf->fence = driFenceReference(fence); - bo = (buf->isSlabBuffer) ? - &buf->parent->kbo->bo: - buf->bo; - buf->fenceType = bo->fenceFlags; - - buf->unFenced = 0; - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; -} - -static int -pool_validate(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return 0; - - while(buf->mapCount != 0) - _glthread_COND_WAIT(buf->event, *mutex); - - buf->unFenced = 1; - return 0; -} - - -struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) -{ - struct _DriFreeSlabManager *tmp; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; - tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; - tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; - - tmp->checkInterval.tv_usec = checkIntervalMsec*1000; - tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; - tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; - - gettimeofday(&tmp->nextCheck, NULL); - driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); - DRMINITLISTHEAD(&tmp->timeoutList); - DRMINITLISTHEAD(&tmp->unCached); - DRMINITLISTHEAD(&tmp->cached); - _glthread_UNLOCK_MUTEX(tmp->mutex); - - return tmp; -} - -void -driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) -{ - struct timeval time; - - time = fMan->nextCheck; - driTimeAdd(&time, &fMan->checkInterval); - - _glthread_LOCK_MUTEX(fMan->mutex); - driFreeTimeoutKBOsLocked(fMan, &time); - _glthread_UNLOCK_MUTEX(fMan->mutex); - - assert(fMan->timeoutList.next == &fMan->timeoutList); - assert(fMan->unCached.next == &fMan->unCached); - assert(fMan->cached.next == &fMan->cached); - - free(fMan); -} - -static void -driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, - struct _DriSlabSizeHeader *header) -{ - _glthread_INIT_MUTEX(header->mutex); - _glthread_LOCK_MUTEX(header->mutex); - - DRMINITLISTHEAD(&header->slabs); - DRMINITLISTHEAD(&header->freeSlabs); - DRMINITLISTHEAD(&header->delayedBuffers); - - header->numDelayed = 0; - header->slabPool = pool; - header->bufSize = size; - - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -driFinishSizeHeader(struct _DriSlabSizeHeader *header) -{ - drmMMListHead *list, *next; - struct _DriSlabBuffer *buf; - - _glthread_LOCK_MUTEX(header->mutex); - for (list = header->delayedBuffers.next, next = list->next; - list != &header->delayedBuffers; - list = next, next = list->next) { - - buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); - if (buf->fence) { - (void) driFenceFinish(buf->fence, buf->fenceType, 0); - driFenceUnReference(&buf->fence); - } - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -pool_takedown(struct _DriBufferPool *driPool) -{ - struct _DriSlabPool *pool = driPool->data; - int i; - - for (i=0; inumBuckets; ++i) { - driFinishSizeHeader(&pool->headers[i]); - } - - free(pool->headers); - free(pool->bucketSizes); - free(pool); - free(driPool); -} - -struct _DriBufferPool * -driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan) -{ - struct _DriBufferPool *driPool; - struct _DriSlabPool *pool; - uint32_t i; - - driPool = calloc(1, sizeof(*driPool)); - if (!driPool) - return NULL; - - pool = calloc(1, sizeof(*pool)); - if (!pool) - goto out_err0; - - pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); - if (!pool->bucketSizes) - goto out_err1; - - pool->headers = calloc(numSizes, sizeof(*pool->headers)); - if (!pool->headers) - goto out_err2; - - pool->fMan = fMan; - pool->proposedFlags = flags; - pool->validMask = validMask; - pool->numBuckets = numSizes; - pool->pageSize = getpagesize(); - pool->fd = fd; - pool->pageAlignment = pageAlignment; - pool->maxSlabSize = maxSlabSize; - pool->desiredNumBuffers = desiredNumBuffers; - - for (i=0; inumBuckets; ++i) { - pool->bucketSizes[i] = (smallestSize << i); - driInitSizeHeader(pool, pool->bucketSizes[i], - &pool->headers[i]); - } - - driPool->data = (void *) pool; - driPool->map = &pool_map; - driPool->unmap = &pool_unmap; - driPool->destroy = &pool_destroy; - driPool->offset = &pool_offset; - driPool->poolOffset = &pool_poolOffset; - driPool->flags = &pool_flags; - driPool->size = &pool_size; - driPool->create = &pool_create; - driPool->fence = &pool_fence; - driPool->kernel = &pool_kernel; - driPool->validate = &pool_validate; - driPool->waitIdle = &pool_waitIdle; - driPool->takeDown = &pool_takedown; - - return driPool; - - out_err2: - free(pool->bucketSizes); - out_err1: - free(pool); - out_err0: - free(driPool); - - return NULL; -} -- cgit v1.2.3 From 1a2c445baf9f493b1590d715314a1c240e4c9ef7 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 6 Jun 2008 14:51:11 +0200 Subject: i915: Moved EGL_i915 to the common code --- src/gallium/winsys/egl_drm/Makefile.template | 1 + src/gallium/winsys/egl_drm/intel/Makefile | 15 +- .../winsys/egl_drm/intel/intel_batchbuffer.c | 465 ---------- .../winsys/egl_drm/intel/intel_batchbuffer.h | 133 +-- src/gallium/winsys/egl_drm/intel/intel_context.c | 343 +++----- src/gallium/winsys/egl_drm/intel/intel_context.h | 81 +- src/gallium/winsys/egl_drm/intel/intel_egl.c | 15 +- src/gallium/winsys/egl_drm/intel/intel_lock.c | 102 --- src/gallium/winsys/egl_drm/intel/intel_reg.h | 10 +- src/gallium/winsys/egl_drm/intel/intel_screen.c | 599 +------------ src/gallium/winsys/egl_drm/intel/intel_screen.h | 110 +-- .../winsys/egl_drm/intel/intel_swapbuffers.c | 243 +----- .../winsys/egl_drm/intel/intel_swapbuffers.h | 47 - src/gallium/winsys/egl_drm/intel/intel_winsys.h | 73 -- .../winsys/egl_drm/intel/intel_winsys_i915.c | 184 ---- .../winsys/egl_drm/intel/intel_winsys_pipe.c | 338 ------- .../winsys/egl_drm/intel/intel_winsys_softpipe.c | 82 -- src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c | 953 -------------------- src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h | 138 --- src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h | 102 --- src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c | 268 ------ src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c | 377 -------- src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h | 115 --- .../winsys/egl_drm/intel/ws_dri_mallocpool.c | 162 ---- src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c | 970 --------------------- 25 files changed, 185 insertions(+), 5741 deletions(-) delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_lock.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c delete mode 100644 src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/Makefile.template b/src/gallium/winsys/egl_drm/Makefile.template index 3bc1fdd4d4..07abfa53f3 100644 --- a/src/gallium/winsys/egl_drm/Makefile.template +++ b/src/gallium/winsys/egl_drm/Makefile.template @@ -54,6 +54,7 @@ SHARED_INCLUDES = \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys/common \ -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/main \ -I$(TOP)/src/mesa/glapi \ diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile index 5778ba77c3..9c7ff065ff 100644 --- a/src/gallium/winsys/egl_drm/intel/Makefile +++ b/src/gallium/winsys/egl_drm/intel/Makefile @@ -6,22 +6,13 @@ LIBNAME = EGL_i915.so PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ + $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a DRIVER_SOURCES = \ - intel_winsys_pipe.c \ - intel_winsys_softpipe.c \ - intel_winsys_i915.c \ - intel_batchbuffer.c \ intel_swapbuffers.c \ intel_context.c \ - intel_lock.c \ intel_screen.c \ - ws_dri_bufmgr.c \ - ws_dri_drmpool.c \ - ws_dri_fencemgr.c \ - ws_dri_mallocpool.c \ - ws_dri_slabpool.c \ intel_egl.c C_SOURCES = \ @@ -35,6 +26,4 @@ DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm - include ../Makefile.template -intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c - symlinks: diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c deleted file mode 100644 index 7ffa05a6e6..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c +++ /dev/null @@ -1,465 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "intel_batchbuffer.h" -#include "intel_context.h" -#include "intel_egl.h" - -#include - -#if 0 -static void -intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) -{ - int i; - fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); - for (i = 0; i < count / 4; i += 4) - fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", - offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); - fprintf(stderr, "END BATCH\n\n\n"); -} -#endif - -static void -intel_realloc_relocs(struct intel_batchbuffer *batch, int num_relocs) -{ - unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; - - size *= sizeof(uint32_t); - batch->reloc = realloc(batch->reloc, size); - batch->reloc_size = num_relocs; -} - - -void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) -{ - /* - * Get a new, free batchbuffer. - */ - drmBO *bo; - struct drm_bo_info_req *req; - int ret; - - driBOUnrefUserList(batch->list); - driBOResetList(batch->list); - - batch->size = 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize; - ret = driBOData(batch->buffer, batch->size, NULL, NULL, 0); - assert(!ret); - - /* - * Add the batchbuffer to the validate list. - */ - - driBOAddListItem(batch->list, batch->buffer, - DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, - &batch->dest_location, &batch->node); - - req = &batch->node->bo_arg.d.req.bo_req; - - /* - * Set up information needed for us to make relocations - * relative to the underlying drm buffer objects. - */ - - driReadLockKernelBO(); - bo = driBOKernel(batch->buffer); - req->presumed_offset = (uint64_t) bo->offset; - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - batch->drmBOVirtual = (uint8_t *) bo->virtual; - driReadUnlockKernelBO(); - - /* - * Adjust the relocation buffer size. - */ - - if (batch->reloc_size > INTEL_MAX_RELOCS || - batch->reloc == NULL) - intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); - - assert(batch->reloc != NULL); - batch->reloc[0] = 0; /* No relocs yet. */ - batch->reloc[1] = 1; /* Reloc type 1 */ - batch->reloc[2] = 0; /* Only a single relocation list. */ - batch->reloc[3] = 0; /* Only a single relocation list. */ - - batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); - batch->poolOffset = driBOPoolOffset(batch->buffer); - batch->ptr = batch->map; - batch->dirty_state = ~0; - batch->nr_relocs = 0; - batch->flags = 0; - batch->id = 0;//batch->intel->intelScreen->batch_id++; -} - -/*====================================================================== - * Public functions - */ -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_screen *intel_screen) -{ - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel_screen = intel_screen; - - driGenBuffers(intel_screen->batchPool, "batchbuffer", 1, - &batch->buffer, 4096, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); - batch->last_fence = NULL; - batch->list = driBOCreateList(20); - batch->reloc = NULL; - intel_batchbuffer_reset(batch); - return batch; -} - -void -intel_batchbuffer_free(struct intel_batchbuffer *batch) -{ - if (batch->last_fence) { - driFenceFinish(batch->last_fence, - DRM_FENCE_TYPE_EXE, GL_FALSE); - driFenceUnReference(&batch->last_fence); - } - if (batch->map) { - driBOUnmap(batch->buffer); - batch->map = NULL; - } - driBOUnReference(batch->buffer); - driBOFreeList(batch->list); - if (batch->reloc) - free(batch->reloc); - batch->buffer = NULL; - free(batch); -} - -void -intel_offset_relocation(struct intel_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask) -{ - int itemLoc; - struct _drmBONode *node; - uint32_t *reloc; - struct drm_bo_info_req *req; - - driBOAddListItem(batch->list, driBO, val_flags, val_mask, - &itemLoc, &node); - req = &node->bo_arg.d.req.bo_req; - - if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { - - /* - * Stop other threads from tampering with the underlying - * drmBO while we're reading its offset. - */ - - driReadLockKernelBO(); - req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; - driReadUnlockKernelBO(); - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - } - - pre_add += driBOPoolOffset(driBO); - - if (batch->nr_relocs == batch->reloc_size) - intel_realloc_relocs(batch, batch->reloc_size * 2); - - reloc = batch->reloc + - (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); - - reloc[0] = ((uint8_t *)batch->ptr - batch->drmBOVirtual); - intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add); - reloc[1] = pre_add; - reloc[2] = itemLoc; - reloc[3] = batch->dest_location; - batch->nr_relocs++; -} - -static void -i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) -{ - buf->handle = rep->handle; - buf->flags = rep->flags; - buf->size = rep->size; - buf->offset = rep->offset; - buf->mapHandle = rep->arg_handle; - buf->proposedFlags = rep->proposed_flags; - buf->start = rep->buffer_start; - buf->fenceFlags = rep->fence_flags; - buf->replyFlags = rep->rep_flags; - buf->pageAlignment = rep->page_alignment; -} - -static int -i915_execbuf(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, - drmBOList *list, - struct drm_i915_execbuffer *ea) -{ - struct intel_screen *intel_screen = batch->intel_screen; - drmBONode *node; - drmMMListHead *l; - struct drm_i915_op_arg *arg, *first; - struct drm_bo_op_req *req; - struct drm_bo_info_rep *rep; - uint64_t *prevNext = NULL; - drmBO *buf; - int ret = 0; - uint32_t count = 0; - - first = NULL; - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - - arg = &node->bo_arg; - req = &arg->d.req; - - if (!first) - first = arg; - - if (prevNext) - *prevNext = (unsigned long)arg; - - prevNext = &arg->next; - req->bo_req.handle = node->buf->handle; - req->op = drm_bo_validate; - req->bo_req.flags = node->arg0; - req->bo_req.mask = node->arg1; - req->bo_req.hint |= 0; - count++; - } - - memset(ea, 0, sizeof(*ea)); - ea->num_buffers = count; - ea->batch.start = batch->poolOffset; - ea->batch.used = used; -#if 0 /* ZZZ JB: no cliprects used */ - ea->batch.cliprects = intel->pClipRects; - ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | - (((GLuint) intel->drawY) << 16)); -#else - ea->batch.cliprects = NULL; - ea->batch.num_cliprects = 0; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0; -#endif - ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; - ea->ops_list = (unsigned long) first; - first->reloc_ptr = (unsigned long) batch->reloc; - batch->reloc[0] = batch->nr_relocs; - - //return -EFAULT; - do { - ret = drmCommandWriteRead(intel_screen->device->drmFD, DRM_I915_EXECBUFFER, ea, - sizeof(*ea)); - } while (ret == -EAGAIN); - - if (ret != 0) { - printf("%s somebody set us up the bomb\n", __FUNCTION__); - return ret; - } - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - arg = &node->bo_arg; - rep = &arg->d.rep.bo_info; - - if (!arg->handled) { - return -EFAULT; - } - if (arg->d.rep.ret) - return arg->d.rep.ret; - - buf = node->buf; - i915_drm_copy_reply(rep, buf); - } - return 0; -} - -/* TODO: Push this whole function into bufmgr. - */ -static struct _DriFenceObject * -do_flush_locked(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - struct intel_screen *intel_screen = batch->intel_screen; - struct _DriFenceObject *fo; - drmFence fence; - drmBOList *boList; - struct drm_i915_execbuffer ea; - int ret = 0; - - driBOValidateUserList(batch->list); - boList = driGetdrmBOList(batch->list); - -#if 0 /* ZZZ JB Allways run */ - if (!(intel->numClipRects == 0 && !ignore_cliprects)) { -#else - if (1) { -#endif - ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); - } else { - driPutdrmBOList(batch->list); - fo = NULL; - goto out; - } - driPutdrmBOList(batch->list); - if (ret) - abort(); - - if (ea.fence_arg.error != 0) { - - /* - * The hardware has been idled by the kernel. - * Don't fence the driBOs. - */ - - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); -#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ - _mesa_printf("fence error\n"); -#endif - batch->last_fence = NULL; - fo = NULL; - goto out; - } - - fence.handle = ea.fence_arg.handle; - fence.fence_class = ea.fence_arg.fence_class; - fence.type = ea.fence_arg.type; - fence.flags = ea.fence_arg.flags; - fence.signaled = ea.fence_arg.signaled; - - fo = driBOFenceUserList(intel_screen->mgr, batch->list, - "SuperFence", &fence); - - if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); - /* - * FIXME: Context last fence?? - */ - batch->last_fence = fo; - driFenceReference(fo); - } - out: -#if 0 /* ZZZ JB: fix this */ - intel->vtbl.lost_hardware(intel); -#else -#endif - return fo; -} - - -struct _DriFenceObject * -intel_batchbuffer_flush(struct intel_batchbuffer *batch) -{ - //struct intel_context *intel = batch->intel; - GLuint used = batch->ptr - batch->map; - //GLboolean was_locked = 1; - struct _DriFenceObject *fence; - - if (used == 0) { - driFenceReference(batch->last_fence); - return batch->last_fence; - } - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a - * performance drain that we would like to avoid. - */ -#if 0 /* ZZZ JB: what should we do here? */ - if (used & 4) { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; - used += 8; - } -#else - if (used & 4) { - ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 8; - } -#endif - driBOUnmap(batch->buffer); - batch->ptr = NULL; - batch->map = NULL; - - /* TODO: Just pass the relocation list and dma buffer up to the - * kernel. - */ -/* if (!was_locked) - LOCK_HARDWARE(intel);*/ - - fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), - GL_FALSE); - -/* if (!was_locked) - UNLOCK_HARDWARE(intel);*/ - - /* Reset the buffer: - */ - intel_batchbuffer_reset(batch); - return fence; -} - -void -intel_batchbuffer_finish(struct intel_batchbuffer *batch) -{ - struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); - driFenceFinish(fence, driFenceType(fence), GL_FALSE); - driFenceUnReference(&fence); -} - -void -intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags) -{ - assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, flags); - memcpy(batch->ptr, data, bytes); - batch->ptr += bytes; -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h index 6d35cf8b96..1fa2719845 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h +++ b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h @@ -1,133 +1,24 @@ #ifndef INTEL_BATCHBUFFER_H #define INTEL_BATCHBUFFER_H -#include "mtypes.h" -#include "ws_dri_bufmgr.h" +#include "intel_drm/intel_be_batchbuffer.h" -struct intel_screen; - -#define BATCH_SZ 16384 -#define BATCH_RESERVED 16 - -#define INTEL_DEFAULT_RELOCS 100 -#define INTEL_MAX_RELOCS 400 - -#define INTEL_BATCH_NO_CLIPRECTS 0x1 -#define INTEL_BATCH_CLIPRECTS 0x2 - -struct intel_batchbuffer -{ - struct bufmgr *bm; - struct intel_screen *intel_screen; - - struct _DriBufferObject *buffer; - struct _DriFenceObject *last_fence; - GLuint flags; - - struct _DriBufferList *list; - GLuint list_count; - GLubyte *map; - GLubyte *ptr; - - uint32_t *reloc; - GLuint reloc_size; - GLuint nr_relocs; - - GLuint size; - - GLuint dirty_state; - GLuint id; - - uint32_t poolOffset; - uint8_t *drmBOVirtual; - struct _drmBONode *node; /* Validation list node for this buffer */ - int dest_location; /* Validation list sequence for this buffer */ -}; - -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_screen - *intel); - -void intel_batchbuffer_free(struct intel_batchbuffer *batch); - - -void intel_batchbuffer_finish(struct intel_batchbuffer *batch); - -struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer - *batch); - -void intel_batchbuffer_reset(struct intel_batchbuffer *batch); - - -/* Unlike bmBufferData, this currently requires the buffer be mapped. - * Consider it a convenience function wrapping multple - * intel_buffer_dword() calls. - */ -void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags); - -void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - GLuint bytes); - -void -intel_offset_relocation(struct intel_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask); - -/* Inline functions - might actually be better off with these - * non-inlined. Certainly better off switching all command packets to - * be passed as structs rather than dwords, but that's a little bit of - * work... +/* + * Need to redefine the BATCH defines */ -static INLINE GLuint -intel_batchbuffer_space(struct intel_batchbuffer *batch) -{ - return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); -} - - -static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) -{ - assert(batch->map); - assert(intel_batchbuffer_space(batch) >= 4); - *(GLuint *) (batch->ptr) = dword; - batch->ptr += 4; -} -static INLINE void -intel_batchbuffer_require_space(struct intel_batchbuffer *batch, - GLuint sz, GLuint flags) -{ - struct _DriFenceObject *fence; +#undef BEGIN_BATCH +#define BEGIN_BATCH(dwords, relocs) \ + (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) - assert(sz < batch->size - 8); - if (intel_batchbuffer_space(batch) < sz || - (batch->flags != 0 && flags != 0 && batch->flags != flags)) { - fence = intel_batchbuffer_flush(batch); - driFenceUnReference(&fence); - } +#undef OUT_BATCH +#define OUT_BATCH(d) \ + i915_batchbuffer_dword(&intel->base.batch->base, d) - batch->flags |= flags; -} - -/* Here are the crusty old macros, to be removed: - */ -#define BATCH_LOCALS - -#define BEGIN_BATCH(n, flags) do { \ - assert(!intel->prim.flush); \ - intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ -} while (0) - -#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) - -#define OUT_RELOC(buf,flags,mask,delta) do { \ +#undef OUT_RELOC +#define OUT_RELOC(buf,flags,mask,delta) do { \ assert((delta) >= 0); \ - intel_offset_relocation(intel->batch, delta, buf, flags, mask); \ + intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ } while (0) -#define ADVANCE_BATCH() do { } while(0) - #endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index 394a40d714..fdbaa230e5 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,14 +22,13 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ +#include "i915simple/i915_screen.h" #include "intel_screen.h" #include "intel_context.h" -#include "intel_swapbuffers.h" -#include "intel_winsys.h" #include "intel_batchbuffer.h" #include "state_tracker/st_public.h" @@ -70,74 +69,109 @@ int __intel_debug = 0; * old i830-specific driver. */ const struct dri_extension card_extensions[] = { - {"GL_ARB_multisample", GL_ARB_multisample_functions}, - {"GL_ARB_multitexture", NULL}, - {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, - {"GL_ARB_texture_border_clamp", NULL}, - {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, - {"GL_ARB_texture_cube_map", NULL}, - {"GL_ARB_texture_env_add", NULL}, - {"GL_ARB_texture_env_combine", NULL}, - {"GL_ARB_texture_env_dot3", NULL}, - {"GL_ARB_texture_mirrored_repeat", NULL}, - {"GL_ARB_texture_rectangle", NULL}, - {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, - {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, - {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, - {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, - {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, - {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, - {"GL_EXT_blend_subtract", NULL}, - {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, - {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, - {"GL_EXT_packed_depth_stencil", NULL}, - {"GL_EXT_pixel_buffer_object", NULL}, - {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, - {"GL_EXT_stencil_wrap", NULL}, - {"GL_EXT_texture_edge_clamp", NULL}, - {"GL_EXT_texture_env_combine", NULL}, - {"GL_EXT_texture_env_dot3", NULL}, - {"GL_EXT_texture_filter_anisotropic", NULL}, - {"GL_EXT_texture_lod_bias", NULL}, - {"GL_3DFX_texture_compression_FXT1", NULL}, - {"GL_APPLE_client_storage", NULL}, - {"GL_MESA_pack_invert", NULL}, - {"GL_MESA_ycbcr_texture", NULL}, - {"GL_NV_blend_square", NULL}, - {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, - {"GL_NV_vertex_program1_1", NULL}, - {"GL_SGIS_generate_mipmap", NULL }, - {NULL, NULL} + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, + {"GL_SGIS_generate_mipmap", NULL }, + {NULL, NULL} }; + +/* + * Hardware lock functions. + * Doesn't do anything in EGL + */ + +static void +intel_lock_hardware(struct intel_be_context *context) +{ + (void)context; +} + +static void +intel_unlock_hardware(struct intel_be_context *context) +{ + (void)context; +} + +static boolean +intel_locked_hardware(struct intel_be_context *context) +{ + (void)context; + return FALSE; +} + + +/* + * Misc functions. + */ + int -intel_create_context(struct egl_drm_context *eglCon, const __GLcontextModes *visual, void *sharedContextPrivate) +intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) { - struct intel_context *iCon = CALLOC_STRUCT(intel_context); - struct intel_screen *iScrn = (struct intel_screen *)eglCon->device->priv; + struct intel_context *intel = CALLOC_STRUCT(intel_context); + struct intel_screen *screen = (struct intel_screen *)egl_context->device->priv; struct pipe_context *pipe; struct st_context *st_share = NULL; - eglCon->priv = iCon; + egl_context->priv = intel; + + intel->intel_screen = screen; + intel->egl_context = egl_context; + intel->egl_device = egl_context->device; - iCon->intel_screen = iScrn; - iCon->egl_context = eglCon; - iCon->egl_device = eglCon->device; + intel->base.hardware_lock = intel_lock_hardware; + intel->base.hardware_unlock = intel_unlock_hardware; + intel->base.hardware_locked = intel_locked_hardware; - iCon->batch = intel_batchbuffer_alloc(iScrn); - iCon->last_swap_fence = NULL; - iCon->first_swap_fence = NULL; + intel_be_init_context(&intel->base, &screen->base); - pipe = intel_create_i915simple(iCon, iScrn->winsys); -// pipe = intel_create_softpipe(iCon, iScrn->winsys); +#if 0 + pipe = intel_create_softpipe(intel, screen->winsys); +#else + pipe = i915_create_context(screen->pipe, &screen->base.base, &intel->base.base); +#endif - pipe->priv = iCon; + pipe->priv = intel; - iCon->st = st_create_context(pipe, visual, st_share); + intel->st = st_create_context(pipe, visual, st_share); return TRUE; } @@ -161,7 +195,6 @@ intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *dra if (draw != read) st_resize_framebuffer(read_fb->stfb, read->w, read->h); - //intelUpdateWindowSize(driDrawPriv); } else { st_make_current(NULL, NULL, NULL); } @@ -173,7 +206,9 @@ intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer struct intel_screen *intelScreen = (struct intel_screen *)draw->device->priv; struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; - driBOUnReference(draw_fb->front_buffer); + if (draw_fb->front_buffer) + driBOUnReference(draw_fb->front_buffer); + draw_fb->front_buffer = NULL; draw_fb->front = NULL; @@ -183,184 +218,8 @@ intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer draw_fb->front = front; - driGenBuffers(intelScreen->staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); + driGenBuffers(intelScreen->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); driBOSetReferenced(draw_fb->front_buffer, front->handle); st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); } - -#if 0 -GLboolean -intelCreateContext(const __GLcontextModes * visual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate) -{ - struct intel_context *intel = CALLOC_STRUCT(intel_context); - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - struct intel_screen *intelScreen = intel_screen(sPriv); - drmI830Sarea *saPriv = intelScreen->sarea; - int fthrottle_mode; - GLboolean havePools; - struct pipe_context *pipe; - struct st_context *st_share = NULL; - - if (sharedContextPrivate) { - st_share = ((struct intel_context *) sharedContextPrivate)->st; - } - - driContextPriv->driverPrivate = intel; - intel->intelScreen = intelScreen; - intel->driScreen = sPriv; - intel->sarea = saPriv; - - driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, - intel->driScreen->myNum, "i915"); - - - /* - * memory pools - */ - DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); - // ZZZ JB should be per screen and not be done per context - havePools = intelCreatePools(sPriv); - DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); - if (!havePools) - return GL_FALSE; - - - /* Dri stuff */ - intel->hHWContext = driContextPriv->hHWContext; - intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; - - fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); - intel->iw.irq_seq = -1; - intel->irqsEmitted = 0; - - intel->batch = intel_batchbuffer_alloc(intel); - intel->last_swap_fence = NULL; - intel->first_swap_fence = NULL; - -#ifdef DEBUG - __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); -#endif - - /* - * Pipe-related setup - */ - if (getenv("INTEL_SP")) { - /* use softpipe driver instead of hw */ - pipe = intel_create_softpipe( intel, intelScreen->winsys ); - } - else { - switch (intel->intelScreen->deviceID) { - case PCI_CHIP_I945_G: - case PCI_CHIP_I945_GM: - case PCI_CHIP_I945_GME: - case PCI_CHIP_G33_G: - case PCI_CHIP_Q33_G: - case PCI_CHIP_Q35_G: - case PCI_CHIP_I915_G: - case PCI_CHIP_I915_GM: - pipe = intel_create_i915simple( intel, intelScreen->winsys ); - break; - default: - fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", - intel->intelScreen->deviceID, __FUNCTION__); - - pipe = intel_create_softpipe( intel, intelScreen->winsys ); - break; - } - } - - pipe->priv = intel; - - intel->st = st_create_context(pipe, visual, st_share); - - return GL_TRUE; -} - - -void -intelDestroyContext(__DRIcontextPrivate * driContextPriv) -{ - struct intel_context *intel = intel_context(driContextPriv); - - assert(intel); /* should never be null */ - if (intel) { - st_finish(intel->st); - - intel_batchbuffer_free(intel->batch); - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - if (intel->first_swap_fence) { - driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = NULL; - } - - if (intel->intelScreen->dummyContext == intel) - intel->intelScreen->dummyContext = NULL; - - st_destroy_context(intel->st); - free(intel); - } -} - - -GLboolean -intelUnbindContext(__DRIcontextPrivate * driContextPriv) -{ - struct intel_context *intel = intel_context(driContextPriv); - st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); - /* XXX make_current(NULL)? */ - return GL_TRUE; -} - - -GLboolean -intelMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv) -{ - if (driContextPriv) { - struct intel_context *intel = intel_context(driContextPriv); - struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv); - struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv); - - assert(draw_fb->stfb); - assert(read_fb->stfb); - - /* This is for situations in which we need a rendering context but - * there may not be any currently bound. - */ - intel->intelScreen->dummyContext = intel; - - st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); - - if ((intel->driDrawable != driDrawPriv) || - (intel->lastStamp != driDrawPriv->lastStamp)) { - intel->driDrawable = driDrawPriv; - intelUpdateWindowSize(driDrawPriv); - intel->lastStamp = driDrawPriv->lastStamp; - } - - /* The size of the draw buffer will have been updated above. - * If the readbuffer is a different window, check/update its size now. - */ - if (driReadPriv != driDrawPriv) { - intelUpdateWindowSize(driReadPriv); - } - - } - else { - st_make_current(NULL, NULL, NULL); - } - - return GL_TRUE; -} -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h index aa9903f274..ccf8120761 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,61 +22,37 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #ifndef INTEL_CONTEXT_H #define INTEL_CONTEXT_H -#include -#include "drm.h" - #include "pipe/p_debug.h" - -#include "intel_screen.h" -#include "i915_drm.h" +#include "intel_drm/intel_be_context.h" -struct pipe_context; -struct intel_context; -struct _DriBufferObject; struct st_context; struct egl_drm_device; struct egl_drm_context; struct egl_drm_frontbuffer; -#define INTEL_MAX_FIXUP 64 - /** * Intel rendering context, contains a state tracker and intel-specific info. */ struct intel_context { - struct st_context *st; - - struct _DriFenceObject *last_swap_fence; - struct _DriFenceObject *first_swap_fence; + struct intel_be_context base; - struct intel_batchbuffer *batch; + struct st_context *st; -#if 0 - boolean locked; - char *prevLockFile; - int prevLockLine; -#endif - - /* pick this up from the screen instead - int drmFd; - */ + struct intel_screen *intel_screen; - struct intel_screen *intel_screen; - - uint lastStamp; - /* new egl stuff */ - struct egl_drm_device *egl_device; - struct egl_drm_context *egl_context; - struct egl_drm_drawable *egl_drawable; + /* new egl stuff */ + struct egl_drm_device *egl_device; + struct egl_drm_context *egl_context; + struct egl_drm_drawable *egl_drawable; }; @@ -86,12 +62,12 @@ struct intel_context */ struct intel_framebuffer { - struct st_framebuffer *stfb; + struct st_framebuffer *stfb; - /* other fields TBD */ - int other; - struct _DriBufferObject *front_buffer; - struct egl_drm_frontbuffer *front; + /* other fields TBD */ + int other; + struct _DriBufferObject *front_buffer; + struct egl_drm_frontbuffer *front; }; @@ -123,11 +99,10 @@ extern int __intel_debug; } while(0) #else -#define DBG(flag, ...) +#define DBG(flag, ...) #endif - #define PCI_CHIP_845_G 0x2562 #define PCI_CHIP_I830_M 0x3577 #define PCI_CHIP_I855_GM 0x3582 @@ -141,22 +116,4 @@ extern int __intel_debug; #define PCI_CHIP_Q35_G 0x29B2 #define PCI_CHIP_Q33_G 0x29D2 - -#if 0 -/** Cast wrapper */ -static INLINE struct intel_context * -intel_context(__DRIcontextPrivate *driContextPriv) -{ - return (struct intel_context *) driContextPriv->driverPrivate; -} - - -/** Cast wrapper */ -static INLINE struct intel_framebuffer * -intel_framebuffer(__DRIdrawablePrivate * driDrawPriv) -{ - return (struct intel_framebuffer *) driDrawPriv->driverPrivate; -} -#endif - #endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 41b7eac4ed..3b4ab330f5 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -21,9 +21,6 @@ #include "intel_context.h" -#include "ws_dri_bufmgr.h" - -#include "intel_winsys.h" #include "state_tracker/st_public.h" struct egl_drm_device* egl_drm_create_device(int drmFD); @@ -434,10 +431,12 @@ prettyColors(int fd, unsigned int handle, size_t pitch) { drmBO bo; unsigned int *ptr; + void *p; int i; drmBOReference(fd, handle, &bo); - drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void**)&ptr); + drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &p); + ptr = (unsigned int*)p; for (i = 0; i < (bo.size / 4); i++) ptr[i] = 0xFFFFFFFF; @@ -460,8 +459,6 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, struct drm_driver *drm_drv = (struct drm_driver *)drv; struct drm_surface *surf = lookup_drm_surface(surface); struct drm_screen *scrn = lookup_drm_screen(dpy, screen); - //struct intel_framebuffer *intel_fb = NULL; - //struct pipe_surface *front_surf = NULL; _EGLMode *mode = _eglLookupMode(dpy, m); size_t pitch = 2048 * 4; size_t size = mode->Height * pitch; @@ -469,8 +466,6 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, /* TODO if allready shown take down */ - printf("setting mode to %i x %i\n", mode->Width, mode->Height); - ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | @@ -554,6 +549,7 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re struct drm_context *ctx = lookup_drm_context(context); EGLBoolean b; + printf("drm_make_current\n"); b = _eglMakeCurrent(drv, dpy, draw, read, context); if (!b) return EGL_FALSE; @@ -563,6 +559,7 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re (void) readSurf; (void) ctx; + printf("enter intel_make_current\n"); intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); return EGL_TRUE; } @@ -613,6 +610,8 @@ _eglMain(_EGLDisplay *dpy, const char *args) drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; drm->base.API.SwapBuffers = drm_swap_buffers; + drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; + /* enable supported extensions */ drm->base.Extensions.MESA_screen_surface = EGL_TRUE; drm->base.Extensions.MESA_copy_context = EGL_TRUE; diff --git a/src/gallium/winsys/egl_drm/intel/intel_lock.c b/src/gallium/winsys/egl_drm/intel/intel_lock.c deleted file mode 100644 index cec83c7585..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_lock.c +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "main/glheader.h" -#include "glapi/glthread.h" -#include -#include "state_tracker/st_public.h" -#include "intel_context.h" - -#if 0 - -_glthread_DECLARE_STATIC_MUTEX( lockMutex ); - - -static void -intelContendedLock(struct intel_context *intel, uint flags) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - __DRIscreenPrivate *sPriv = intel->driScreen; - struct intel_screen *intelScreen = intel_screen(sPriv); - drmI830Sarea *sarea = intel->sarea; - - drmGetLock(intel->driFd, intel->hHWContext, flags); - - DBG(LOCK, "%s - got contended lock\n", __progname); - - /* If the window moved, may need to set a new cliprect now. - * - * NOTE: This releases and regains the hw lock, so all state - * checking must be done *after* this call: - */ - if (dPriv) - DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); - - if (sarea->width != intelScreen->front.width || - sarea->height != intelScreen->front.height) { - - intelUpdateScreenRotation(sPriv, sarea); - } -} - - -/* Lock the hardware and validate our state. - */ -void LOCK_HARDWARE( struct intel_context *intel ) -{ - char __ret = 0; - - _glthread_LOCK_MUTEX(lockMutex); - assert(!intel->locked); - - DRM_CAS(intel->driHwLock, intel->hHWContext, - (DRM_LOCK_HELD|intel->hHWContext), __ret); - - if (__ret) - intelContendedLock( intel, 0 ); - - DBG(LOCK, "%s - locked\n", __progname); - - intel->locked = 1; -} - - -/* Unlock the hardware using the global current context - */ -void UNLOCK_HARDWARE( struct intel_context *intel ) -{ - assert(intel->locked); - intel->locked = 0; - - DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); - - _glthread_UNLOCK_MUTEX(lockMutex); - - DBG(LOCK, "%s - unlocked\n", __progname); -} -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_reg.h b/src/gallium/winsys/egl_drm/intel/intel_reg.h index f37c24fda9..4f33bee438 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_reg.h +++ b/src/gallium/winsys/egl_drm/intel/intel_reg.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c index 38c4098087..96b0bf1b85 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,62 +22,24 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ + #include "utils.h" -#include "vblank.h" -#include "xmlpool.h" + +#include "state_tracker/st_public.h" +#include "i915simple/i915_screen.h" #include "intel_context.h" #include "intel_screen.h" #include "intel_batchbuffer.h" -//#include "intel_batchpool.h" -#include "intel_swapbuffers.h" -#include "intel_winsys.h" - -#include "ws_dri_bufpool.h" - -#include "pipe/p_context.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_cb_fbo.h" #include "intel_egl.h" -static boolean -intel_create_pools(struct intel_screen *intel_screen) -{ - if (intel_screen->havePools) - return GL_TRUE; - - intel_screen->mgr = driFenceMgrTTMInit(intel_screen->device->drmFD); - if (!intel_screen->mgr) { - fprintf(stderr, "Failed to create fence manager.\n"); - return FALSE; - } - - intel_screen->fMan = driInitFreeSlabManager(10, 10); - if (!intel_screen->fMan) { - fprintf(stderr, "Failed to create free slab manager.\n"); - return FALSE; - } - - intel_screen->staticPool = driDRMPoolInit(intel_screen->device->drmFD); - intel_screen->batchPool = driSlabPoolInit(intel_screen->device->drmFD, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - 4096, //intelScreen->maxBatchSize, - 1, 40, 16*16384, 0, - intel_screen->fMan); - - intel_screen->havePools = GL_TRUE; - - return GL_TRUE; -} extern const struct dri_extension card_extensions[]; + int intel_init_driver(struct egl_drm_device *device) { @@ -85,18 +47,18 @@ intel_init_driver(struct egl_drm_device *device) /* Allocate the private area */ intel_screen = CALLOC_STRUCT(intel_screen); - if (!intel_screen) + if (!intel_screen) return FALSE; device->priv = (void *)intel_screen; intel_screen->device = device; - if (!intel_create_pools(intel_screen)) - return FALSE; + /** TODO JB: ugly hack */ + intel_screen->deviceID = PCI_CHIP_I945_GM; - intel_screen->batch = intel_batchbuffer_alloc(intel_screen); + intel_be_init_device(&intel_screen->base, device->drmFD); - intel_screen->winsys = intel_create_pipe_winsys(device->drmFD, intel_screen->fMan); + intel_screen->pipe = i915_create_screen(&intel_screen->base.base, intel_screen->deviceID); /* hack */ driInitExtensions(NULL, card_extensions, GL_FALSE); @@ -147,534 +109,3 @@ intel_create_drawable(struct egl_drm_drawable *drawable, drawable->priv = (void *) intelfb; return GL_TRUE; } - -#if 0 -PUBLIC const char __driConfigOptions[] = - DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE - DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) - DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) - DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY - DRI_CONF_FORCE_S3TC_ENABLE(false) - DRI_CONF_ALLOW_LARGE_TEXTURES(1) - DRI_CONF_SECTION_END DRI_CONF_END; - -const uint __driNConfigOptions = 4; - -#ifdef USE_NEW_INTERFACE -static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; -#endif /*USE_NEW_INTERFACE */ - -extern const struct dri_extension card_extensions[]; - - - - -static void -intelPrintDRIInfo(struct intel_screen * intelScreen, - __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) -{ - fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->front.size, intelScreen->front.offset, - intelScreen->front.pitch); - fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); -} - -static void -intelPrintSAREA(const drmI830Sarea * sarea) -{ - fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, - sarea->height); - fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); - fprintf(stderr, - "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->front_offset, sarea->front_size, - (unsigned) sarea->front_handle); - fprintf(stderr, - "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->back_offset, sarea->back_size, - (unsigned) sarea->back_handle); - fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->depth_offset, sarea->depth_size, - (unsigned) sarea->depth_handle); - fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); - fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); - fprintf(stderr, - "SAREA: rotated offset: 0x%08x size: 0x%x\n", - sarea->rotated_offset, sarea->rotated_size); - fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); -} - -/** - * Use the information in the sarea to update the screen parameters - * related to screen rotation. Needs to be called locked. - */ -void -intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) -{ - struct intel_screen *intelScreen = intel_screen(sPriv); - - if (intelScreen->front.map) { - drmUnmap(intelScreen->front.map, intelScreen->front.size); - intelScreen->front.map = NULL; - } - - if (intelScreen->front.buffer) - driDeleteBuffers(1, &intelScreen->front.buffer); - - intelScreen->front.width = sarea->width; - intelScreen->front.height = sarea->height; - intelScreen->front.offset = sarea->front_offset; - intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp; - intelScreen->front.size = sarea->front_size; - intelScreen->front.handle = sarea->front_handle; - - assert( sarea->front_size >= - intelScreen->front.pitch * intelScreen->front.height ); - -#if 0 /* JB not important */ - if (!sarea->front_handle) - return; - - if (drmMap(sPriv->fd, - sarea->front_handle, - intelScreen->front.size, - (drmAddress *) & intelScreen->front.map) != 0) { - fprintf(stderr, "drmMap(frontbuffer) failed!\n"); - return; - } -#endif - -#if 0 /* JB */ - if (intelScreen->staticPool) { - driGenBuffers(intelScreen->staticPool, "static region", 1, - &intelScreen->front.buffer, 64, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - - driBOSetStatic(intelScreen->front.buffer, - intelScreen->front.offset, - intelScreen->front.pitch * intelScreen->front.height, - intelScreen->front.map, 0); - } -#else - if (intelScreen->staticPool) { - if (intelScreen->front.buffer) - driBOUnReference(intelScreen->front.buffer); - driGenBuffers(intelScreen->staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); - driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle); - } -#endif -} - - -boolean -intelCreatePools(__DRIscreenPrivate * sPriv) -{ - //unsigned batchPoolSize = 1024*1024; - struct intel_screen *intelScreen = intel_screen(sPriv); - - if (intelScreen->havePools) - return GL_TRUE; - -#if 0 /* ZZZ JB fix this */ - intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); - if (!intelScreen->staticPool) - return GL_FALSE; - - batchPoolSize /= BATCH_SZ; - intelScreen->batchPool = driBatchPoolInit(sPriv->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_MEM_LOCAL, - BATCH_SZ, - batchPoolSize, 5); - if (!intelScreen->batchPool) { - fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); - return GL_FALSE; - } -#else - intelScreen->staticPool = driDRMPoolInit(sPriv->fd); - intelScreen->batchPool = driSlabPoolInit(sPriv->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - 4096, //intelScreen->maxBatchSize, - 1, 40, 16*16384, 0, - intelScreen->fMan); -#endif - intelScreen->havePools = GL_TRUE; - - //intelUpdateScreenRotation(sPriv, intelScreen->sarea); - - return GL_TRUE; -} - - -static boolean -intelInitDriver(__DRIscreenPrivate * sPriv) -{ - struct intel_screen *intelScreen; - I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; - - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> - getProcAddress("glxEnableExtension")); - void *const psc = sPriv->psc->screenConfigs; - - if (sPriv->devPrivSize != sizeof(I830DRIRec)) { - fprintf(stderr, - "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); - return GL_FALSE; - } - - /* Allocate the private area */ - intelScreen = CALLOC_STRUCT(intel_screen); - if (!intelScreen) - return GL_FALSE; - - /* parse information in __driConfigOptions */ - driParseOptionInfo(&intelScreen->optionCache, - __driConfigOptions, __driNConfigOptions); - - sPriv->private = (void *) intelScreen; - - intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + - gDRIPriv->sarea_priv_offset); - intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->front.cpp = gDRIPriv->cpp; - intelScreen->drmMinor = sPriv->drmMinor; - - - assert(gDRIPriv->bitsPerPixel == 16 || - gDRIPriv->bitsPerPixel == 32); - - - intelUpdateScreenRotation(sPriv, intelScreen->sarea); - - if (0) - intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - - if (glx_enable_extension != NULL) { - (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); - (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); - (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); - } - - - -#if 1 // ZZZ JB - intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd); - if (!intelScreen->mgr) { - fprintf(stderr, "Failed to create fence manager.\n"); - return GL_FALSE; - } - - intelScreen->fMan = driInitFreeSlabManager(10, 10); - if (!intelScreen->fMan) { - fprintf(stderr, "Failed to create free slab manager.\n"); - return GL_FALSE; - } - - if (!intelCreatePools(sPriv)) - return GL_FALSE; -#endif - - intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd, intelScreen->fMan); - - return GL_TRUE; -} - - -static void -intelDestroyScreen(__DRIscreenPrivate * sPriv) -{ - struct intel_screen *intelScreen = intel_screen(sPriv); - - /* intelUnmapScreenRegions(intelScreen); */ - - if (intelScreen->havePools) { - driPoolTakeDown(intelScreen->staticPool); - driPoolTakeDown(intelScreen->batchPool); - } - FREE(intelScreen); - sPriv->private = NULL; -} - - -/** - * This is called when we need to set up GL rendering to a new X window. - */ -static boolean -intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, - __DRIdrawablePrivate * driDrawPriv, - const __GLcontextModes * visual, boolean isPixmap) -{ - if (isPixmap) { - return GL_FALSE; /* not implemented */ - } - else { - enum pipe_format colorFormat, depthFormat, stencilFormat; - struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); - - if (!intelfb) - return GL_FALSE; - - if (visual->redBits == 5) - colorFormat = PIPE_FORMAT_R5G6B5_UNORM; - else - colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; - - if (visual->depthBits == 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits == 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_NONE; - - if (visual->stencilBits == 8) - stencilFormat = PIPE_FORMAT_S8Z24_UNORM; - else - stencilFormat = PIPE_FORMAT_NONE; - - intelfb->stfb = st_create_framebuffer(visual, - colorFormat, - depthFormat, - stencilFormat, - driDrawPriv->w, - driDrawPriv->h, - (void*) intelfb); - if (!intelfb->stfb) { - free(intelfb); - return GL_FALSE; - } - - driDrawPriv->driverPrivate = (void *) intelfb; - return GL_TRUE; - } -} - -static void -intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) -{ - struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv); - assert(intelfb->stfb); - st_unreference_framebuffer(&intelfb->stfb); - free(intelfb); -} - - -/** - * Get information about previous buffer swaps. - */ -static int -intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) -{ - if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) - || (sInfo == NULL)) { - return -1; - } - - return 0; -} - - -static void -intelSetTexOffset(__DRIcontext *pDRICtx, int texname, - unsigned long long offset, int depth, uint pitch) -{ - abort(); -#if 0 - struct intel_context *intel = (struct intel_context*) - ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; - struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); - struct st_texture_object *stObj = st_texture_object(tObj); - - if (!stObj) - return; - - if (stObj->pt) - st->pipe->texture_release(intel->st->pipe, &stObj->pt); - - stObj->imageOverride = GL_TRUE; - stObj->depthOverride = depth; - stObj->pitchOverride = pitch; - - if (offset) - stObj->textureOffset = offset; -#endif -} - - -static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetMSC = driGetMSC32, - .WaitForMSC = driWaitForMSC32, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = intelCopySubBuffer, - .setTexOffset = intelSetTexOffset, -}; - - -static __GLcontextModes * -intelFillInModes(unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, boolean have_back_buffer) -{ - __GLcontextModes *modes; - __GLcontextModes *m; - unsigned num_modes; - unsigned depth_buffer_factor; - unsigned back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML - }; - - u_int8_t depth_bits_array[3]; - u_int8_t stencil_bits_array[3]; - - - depth_bits_array[0] = 0; - depth_bits_array[1] = depth_bits; - depth_bits_array[2] = depth_bits; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = 0; - if (depth_bits == 24) - stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; - - stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; - - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; - back_buffer_factor = (have_back_buffer) ? 3 : 1; - - num_modes = depth_buffer_factor * back_buffer_factor * 4; - - if (pixel_bits == 16) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } - else { - fb_format = GL_BGRA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - modes = - (*dri_interface->createContextModes) (num_modes, - sizeof(__GLcontextModes)); - m = modes; - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_DIRECT_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for (m = modes; m != NULL; m = m->next) { - if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { - m->visualRating = GLX_SLOW_CONFIG; - } - } - - return modes; -} - - -/** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. - * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. - */ -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, - __DRIscreen * psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) -{ - __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 7, 0 }; - static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 7, 0 }; - - dri_interface = interface; - - if (!driCheckDriDdxDrmVersions2("i915", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { - return NULL; - } - - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - - if (psp != NULL) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes(dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create - * is called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions(NULL, card_extensions, GL_FALSE); - } - - return (void *) psp; -} -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_screen.h index e8c1cdfca4..87c4406f54 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.h +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.h @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,112 +22,26 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #ifndef _INTEL_SCREEN_H_ #define _INTEL_SCREEN_H_ -#include "ws_dri_bufpool.h" +#include "intel_drm/intel_be_device.h" #include "pipe/p_compiler.h" -struct egl_drm_device *device; +struct pipe_screen; +struct egl_drm_device; struct intel_screen { -#if 0 - struct { - drm_handle_t handle; + struct intel_be_device base; + struct pipe_screen *pipe; - /* We create a static dri buffer for the frontbuffer. - */ - struct _DriBufferObject *buffer; - - char *map; /* memory map */ - int offset; /* from start of video mem, in bytes */ - int pitch; /* row stride, in bytes */ - int width; - int height; - int size; - int cpp; /* for front and back buffers */ - } front; -#endif - - int drmFB; - -#if 0 - int deviceID; - int drmMinor; - - - drmI830Sarea *sarea;*/ - - - /** - * Configuration cache with default values for all contexts - */ - driOptionCache optionCache; -#endif - - struct _DriBufferPool *batchPool; - struct _DriBufferPool *staticPool; /** for the X screen/framebuffer */ - boolean havePools; - -#if 0 - /** - * Temporary(?) context to use for SwapBuffers or other situations in - * which we need a rendering context, but none is currently bound. - */ - struct intel_context *dummyContext; -#endif - - /* - * New stuff form the i915tex integration - */ - struct _DriFenceMgr *mgr; - struct _DriFreeSlabManager *fMan; - unsigned batch_id; - - struct pipe_winsys *winsys; - struct egl_drm_device *device; - - /* batch buffer used for swap buffers */ - struct intel_batchbuffer *batch; + int deviceID; + struct egl_drm_device *device; }; - - -/** cast wrapper */ -#if 0 -static INLINE struct intel_screen * -intel_screen(__DRIscreenPrivate *sPriv) -{ - return (struct intel_screen *) sPriv->private; -} - - -extern void -intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); - - -extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); - -extern boolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); - -extern boolean -intelMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv); - - -extern boolean -intelCreatePools(__DRIscreenPrivate *sPriv); - -extern boolean -intelCreateContext(const __GLcontextModes * visual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - -#endif #endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c index 1ce4b2754a..24e55f1568 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -22,15 +22,13 @@ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * **************************************************************************/ #include "intel_screen.h" #include "intel_context.h" -#include "intel_swapbuffers.h" #include "intel_batchbuffer.h" #include "intel_reg.h" -#include "intel_winsys.h" #include "pipe/p_context.h" #include "state_tracker/st_public.h" @@ -54,7 +52,8 @@ void intel_swap_buffers(struct egl_drm_drawable *draw) back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT); if (back_surf) { st_notify_swapbuffers(intel_fb->stfb); - intel_display_surface(draw, back_surf); + if (intel_fb->front) + intel_display_surface(draw, back_surf); st_notify_swapbuffers_complete(intel_fb->stfb); } } @@ -63,7 +62,7 @@ static void intel_display_surface(struct egl_drm_drawable *draw, struct pipe_surface *surf) { - struct intel_screen *intel = (struct intel_screen *)draw->device->priv; + struct intel_context *intel = NULL; struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; struct _DriFenceObject *fence; @@ -85,8 +84,7 @@ intel_display_surface(struct egl_drm_drawable *draw, CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); - printf("srcPitch: %u, dstWidth: %u, dstHeight: %u, dstPitch: %u, cpp: %u\n", srcPitch, dstWidth, dstHeight, dstPitch, cpp); - BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + BEGIN_BATCH(8, 2); OUT_BATCH(CMD); OUT_BATCH(BR13); OUT_BATCH((0 << 16) | 0); @@ -102,226 +100,7 @@ intel_display_surface(struct egl_drm_drawable *draw, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - ADVANCE_BATCH(); - - fence = intel_batchbuffer_flush(intel->batch); + fence = intel_be_batchbuffer_flush(intel->base.batch); driFenceUnReference(&fence); - intel_batchbuffer_finish(intel->batch); -} - -#if 0 -/** - * Display a colorbuffer surface in an X window. - * Used for SwapBuffers and flushing front buffer rendering. - * - * \param dPriv the window/drawable to display into - * \param surf the surface to display - * \param rect optional subrect of surface to display (may be NULL). - */ -void -intelDisplaySurface(__DRIdrawablePrivate *dPriv, - struct pipe_surface *surf, - const drm_clip_rect_t *rect) -{ - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - //struct intel_context *intel = intelScreen->dummyContext; - - DBG(SWAP, "%s\n", __FUNCTION__); - -#if 0 - if (!intel) { - /* XXX this is where some kind of extra/meta context could be useful */ - return; - } -#endif - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - intel->last_swap_fence = intel->first_swap_fence; - intel->first_swap_fence = NULL; - - /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets - * should work regardless. - */ - LOCK_HARDWARE(intel); - /* if this drawable isn't currently bound the LOCK_HARDWARE done on the - * current context (which is what intelScreenContext should return) might - * not get a contended lock and thus cliprects not updated (tests/manywin) - */ - if (intel_context(dPriv->driContextPriv) != intel) - DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); - - - if (dPriv && dPriv->numClipRects) { - const int srcWidth = surf->width; - const int srcHeight = surf->height; - const int nbox = dPriv->numClipRects; - const drm_clip_rect_t *pbox = dPriv->pClipRects; - const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; - const int cpp = intelScreen->front.cpp; - const int srcpitch = surf->pitch; - int BR13, CMD; - int i; - - ASSERT(surf->buffer); - ASSERT(surf->cpp == cpp); - - DBG(SWAP, "screen pitch %d src surface pitch %d\n", - pitch, surf->pitch); - - if (cpp == 2) { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); - CMD = XY_SRC_COPY_BLT_CMD; - } - else { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - } - - for (i = 0; i < nbox; i++, pbox++) { - drm_clip_rect_t box; - drm_clip_rect_t sbox; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->front.width || - pbox->y2 > intelScreen->front.height) { - /* invalid cliprect, skip it */ - continue; - } - - box = *pbox; - - if (rect) { - /* intersect cliprect with user-provided src rect */ - drm_clip_rect_t rrect; - - rrect.x1 = dPriv->x + rect->x1; - rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; - rrect.x2 = rect->x2 + rrect.x1; - rrect.y2 = rect->y2 + rrect.y1; - if (rrect.x1 > box.x1) - box.x1 = rrect.x1; - if (rrect.y1 > box.y1) - box.y1 = rrect.y1; - if (rrect.x2 < box.x2) - box.x2 = rrect.x2; - if (rrect.y2 < box.y2) - box.y2 = rrect.y2; - - if (box.x1 > box.x2 || box.y1 > box.y2) - continue; - } - - /* restrict blit to size of actually rendered area */ - if (box.x2 - box.x1 > srcWidth) - box.x2 = srcWidth + box.x1; - if (box.y2 - box.y1 > srcHeight) - box.y2 = srcHeight + box.y1; - - DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", - box.x1, box.x2, box.y1, box.y2); - - sbox.x1 = box.x1 - dPriv->x; - sbox.y1 = box.y1 - dPriv->y; - - assert(box.x1 < box.x2); - assert(box.y1 < box.y2); - - /* XXX this could be done with pipe->surface_copy() */ - BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((box.y1 << 16) | box.x1); - OUT_BATCH((box.y2 << 16) | box.x2); - - OUT_RELOC(intelScreen->front.buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); - OUT_BATCH((sbox.y1 << 16) | sbox.x1); - OUT_BATCH((srcpitch * cpp) & 0xffff); - OUT_RELOC(dri_bo(surf->buffer), - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - - ADVANCE_BATCH(); - } - - if (intel->first_swap_fence) - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); - } - - UNLOCK_HARDWARE(intel); - - if (intel->lastStamp != dPriv->lastStamp) { - intelUpdateWindowSize(dPriv); - intel->lastStamp = dPriv->lastStamp; - } -} - - - -/** - * This will be called whenever the currently bound window is moved/resized. - */ -void -intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) -{ - struct intel_framebuffer *intelfb = intel_framebuffer(dPriv); - assert(intelfb->stfb); - st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); -} - - - -void -intelSwapBuffers(__DRIdrawablePrivate * dPriv) -{ - struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; - - assert(intel_fb); - assert(intel_fb->stfb); - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { - st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, NULL); - st_notify_swapbuffers_complete(intel_fb->stfb); - } -} - - -/** - * Called via glXCopySubBufferMESA() to copy a subrect of the back - * buffer to the front buffer/screen. - */ -void -intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) -{ - struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; - - assert(intel_fb); - assert(intel_fb->stfb); - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { - drm_clip_rect_t rect; - rect.x1 = x; - rect.y1 = y; - rect.x2 = w; - rect.y2 = h; - - st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, &rect); - } + intel_be_batchbuffer_finish(intel->base.batch); } -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h deleted file mode 100644 index 904f26732e..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_SWAPBUFFERS_H -#define INTEL_SWAPBUFFERS_H - - -struct pipe_surface; - -#if 0 -extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, - struct pipe_surface *surf, - const drm_clip_rect_t * rect); - -extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); - -extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, - int x, int y, int w, int h); - -extern void intelUpdateWindowSize(__DRIdrawablePrivate *dPriv); -#endif - -#endif /* INTEL_SWAPBUFFERS_H */ diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys.h b/src/gallium/winsys/egl_drm/intel/intel_winsys.h deleted file mode 100644 index d0a319f9a4..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_winsys.h +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_WINSYS_H -#define INTEL_WINSYS_H - -#include "pipe/p_state.h" - -struct intel_context; -struct pipe_context; -struct pipe_winsys; -struct pipe_buffer; -struct _DriBufferObject; - -struct pipe_winsys * -intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ); - -void -intel_destroy_pipe_winsys( struct pipe_winsys *winsys ); - -struct pipe_context * -intel_create_softpipe( struct intel_context *intel, - struct pipe_winsys *winsys ); - -struct pipe_context * -intel_create_i915simple( struct intel_context *intel, - struct pipe_winsys *winsys ); - - -struct intel_buffer { - struct pipe_buffer base; - struct _DriBufferObject *driBO; -}; - -static INLINE struct intel_buffer * -intel_buffer( struct pipe_buffer *buf ) -{ - return (struct intel_buffer *)buf; -} - -static INLINE struct _DriBufferObject * -dri_bo( struct pipe_buffer *buf ) -{ - return intel_buffer(buf)->driBO; -} - - - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c deleted file mode 100644 index 8ec5c7e82a..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c +++ /dev/null @@ -1,184 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" - -#include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_winsys.h" - -#include "pipe/p_util.h" -#include "pipe/p_winsys.h" -#include "i915simple/i915_winsys.h" -#include "i915simple/i915_screen.h" - - -struct intel_i915_winsys { - struct i915_winsys winsys; /**< batch buffer funcs */ - struct pipe_winsys *pws; - struct intel_context *intel; -}; - - -/* Turn a i915simple winsys into an intel/i915simple winsys: - */ -static inline struct intel_i915_winsys * -intel_i915_winsys( struct i915_winsys *sws ) -{ - return (struct intel_i915_winsys *)sws; -} - - -/* Simple batchbuffer interface: - */ - -static unsigned *intel_i915_batch_start( struct i915_winsys *sws, - unsigned dwords, - unsigned relocs ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - - /* XXX: check relocs. - */ - if (intel_batchbuffer_space( intel->batch ) >= dwords * 4) { - /* XXX: Hmm, the driver can't really do much with this pointer: - */ - return (unsigned *)intel->batch->ptr; - } - else - return NULL; -} - -static void intel_i915_batch_dword( struct i915_winsys *sws, - unsigned dword ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - intel_batchbuffer_emit_dword( intel->batch, dword ); -} - -static void intel_i915_batch_reloc( struct i915_winsys *sws, - struct pipe_buffer *buf, - unsigned access_flags, - unsigned delta ) -{ - struct intel_context *intel = intel_i915_winsys(sws)->intel; - unsigned flags = DRM_BO_FLAG_MEM_TT; - unsigned mask = DRM_BO_MASK_MEM; - - if (access_flags & I915_BUFFER_ACCESS_WRITE) { - flags |= DRM_BO_FLAG_WRITE; - mask |= DRM_BO_FLAG_WRITE; - } - - if (access_flags & I915_BUFFER_ACCESS_READ) { - flags |= DRM_BO_FLAG_READ; - mask |= DRM_BO_FLAG_READ; - } - -#if 0 /* JB old */ - intel_batchbuffer_emit_reloc( intel->batch, - dri_bo( buf ), - flags, mask, - delta ); -#else /* new */ - intel_offset_relocation( intel->batch, - delta, - dri_bo( buf ), - flags, - mask ); -#endif -} - - - -static void intel_i915_batch_flush( struct i915_winsys *sws, - struct pipe_fence_handle **fence ) -{ - struct intel_i915_winsys *iws = intel_i915_winsys(sws); - struct intel_context *intel = iws->intel; - union { - struct _DriFenceObject *dri; - struct pipe_fence_handle *pipe; - } fu; - - if (fence) - assert(!*fence); - - fu.dri = intel_batchbuffer_flush( intel->batch ); - - if (!fu.dri) { - assert(0); - *fence = NULL; - return; - } - - if (fu.dri) { - if (fence) - *fence = fu.pipe; - else - driFenceUnReference(&fu.dri); - } - -} - - -/** - * Create i915 hardware rendering context. - */ -struct pipe_context * -intel_create_i915simple( struct intel_context *intel, - struct pipe_winsys *winsys ) -{ - struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys ); - struct pipe_screen *screen; - - /* Fill in this struct with callbacks that i915simple will need to - * communicate with the window system, buffer manager, etc. - */ - iws->winsys.batch_start = intel_i915_batch_start; - iws->winsys.batch_dword = intel_i915_batch_dword; - iws->winsys.batch_reloc = intel_i915_batch_reloc; - iws->winsys.batch_flush = intel_i915_batch_flush; - iws->pws = winsys; - iws->intel = intel; - - screen = i915_create_screen(winsys, PCI_CHIP_I945_GM); - assert(screen); - - /* Create the i915simple context: - */ - return i915_create_context( screen, - winsys, - &iws->winsys ); -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c deleted file mode 100644 index 8bf8c21439..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c +++ /dev/null @@ -1,338 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include -#include -//#include "dri_bufpool.h" -//#include "dri_bufmgr.h" - -#include "intel_context.h" -#include "intel_winsys.h" -#include "intel_swapbuffers.h" -#include "intel_batchbuffer.h" - -#include "pipe/p_winsys.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" - - - -struct intel_pipe_winsys { - struct pipe_winsys winsys; - struct _DriBufferPool *regionPool; - struct _DriFreeSlabManager *fMan; -}; - - - -/* Turn a pipe winsys into an intel/pipe winsys: - */ -static inline struct intel_pipe_winsys * -intel_pipe_winsys( struct pipe_winsys *winsys ) -{ - return (struct intel_pipe_winsys *)winsys; -} - - -/* Most callbacks map direcly onto dri_bufmgr operations: - */ -static void *intel_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags ) -{ - unsigned drm_flags = 0; - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) - drm_flags |= DRM_BO_FLAG_WRITE; - - if (flags & PIPE_BUFFER_USAGE_CPU_READ) - drm_flags |= DRM_BO_FLAG_READ; - - return driBOMap( dri_bo(buf), drm_flags, 0 ); -} - -static void intel_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnmap( dri_bo(buf) ); -} - - -static void -intel_buffer_destroy(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnReference( dri_bo(buf) ); - FREE(buf); -} - - -/* Pipe has no concept of pools. We choose the tex/region pool - * for all buffers. - * Grabs the hardware lock! - */ -static struct pipe_buffer * -intel_buffer_create(struct pipe_winsys *winsys, - unsigned alignment, - unsigned usage, - unsigned size ) -{ - struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - unsigned flags = 0; - - buffer->base.refcount = 1; - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - - if (usage & (PIPE_BUFFER_USAGE_VERTEX /*| IWS_BUFFER_USAGE_LOCAL*/)) { - flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; - } else { - flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; - } - - if (usage & PIPE_BUFFER_USAGE_GPU_READ) - flags |= DRM_BO_FLAG_READ; - - if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) - flags |= DRM_BO_FLAG_WRITE; - - /* drm complains if we don't set any read/write flags. - */ - if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) - flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - -#if 0 - if (flags & IWS_BUFFER_USAGE_EXE) - flags |= DRM_BO_FLAG_EXE; - - if (usage & IWS_BUFFER_USAGE_CACHED) - flags |= DRM_BO_FLAG_CACHED; -#endif - - driGenBuffers( iws->regionPool, - "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); - - driBOData( buffer->driBO, size, NULL, iws->regionPool, 0 ); - - return &buffer->base; -} - - -static struct pipe_buffer * -intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) -{ - struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer ); - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - - driGenUserBuffer( iws->regionPool, - "pipe user buffer", &buffer->driBO, ptr, bytes ); - - buffer->base.refcount = 1; - - return &buffer->base; -} - - -/* The state tracker (should!) keep track of whether the fake - * frontbuffer has been touched by any rendering since the last time - * we copied its contents to the real frontbuffer. Our task is easy: - */ -static void -intel_flush_frontbuffer( struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ -#if 0 - struct intel_context *intel = (struct intel_context *) context_private; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - intelDisplaySurface(dPriv, surf, NULL); -#endif -} - - -static struct pipe_surface * -intel_i915_surface_alloc(struct pipe_winsys *winsys) -{ - struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface); - if (surf) { - surf->refcount = 1; - surf->winsys = winsys; - } - return surf; -} - - -/** - * Round n up to next multiple. - */ -static INLINE unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} - -/** - * Copied from xm_winsys.c - */ -static int -intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, - unsigned flags) -{ - const unsigned alignment = 64; - //int ret; - - surf->width = width; - surf->height = height; - surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); - if(!surf->buffer) - return -1; - - return 0; -} - - -static void -intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - struct pipe_surface *surf = *s; - surf->refcount--; - if (surf->refcount == 0) { - if (surf->buffer) - pipe_buffer_reference(winsys, &surf->buffer, NULL); - free(surf); - } - *s = NULL; -} - - - -static const char * -intel_get_name( struct pipe_winsys *winsys ) -{ - return "Intel/EGL/ttm"; -} - -static void -intel_fence_reference( struct pipe_winsys *sws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence ) -{ - if (*ptr) - driFenceUnReference((struct _DriFenceObject **)ptr); - - if (fence) - *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); -} - -static int -intel_fence_signalled( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - return driFenceSignaled((struct _DriFenceObject *)fence, flag); -} - -static int -intel_fence_finish( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - /* JB: Lets allways lazy wait */ - return driFenceFinish((struct _DriFenceObject *)fence, flag, 1); -} - -struct pipe_winsys * -intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan ) -{ - struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys ); - - /* Fill in this struct with callbacks that pipe will need to - * communicate with the window system, buffer manager, etc. - * - * Pipe would be happy with a malloc based memory manager, but - * the SwapBuffers implementation in this winsys driver requires - * that rendering be done to an appropriate _DriBufferObject. - */ - iws->winsys.buffer_create = intel_buffer_create; - iws->winsys.user_buffer_create = intel_user_buffer_create; - iws->winsys.buffer_map = intel_buffer_map; - iws->winsys.buffer_unmap = intel_buffer_unmap; - iws->winsys.buffer_destroy = intel_buffer_destroy; - iws->winsys.flush_frontbuffer = intel_flush_frontbuffer; - iws->winsys.get_name = intel_get_name; - iws->winsys.surface_alloc = intel_i915_surface_alloc; - iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; - iws->winsys.surface_release = intel_i915_surface_release; - - iws->winsys.fence_reference = intel_fence_reference; - iws->winsys.fence_signalled = intel_fence_signalled; - iws->winsys.fence_finish = intel_fence_finish; - - if (fd) - iws->regionPool = driSlabPoolInit(fd, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - 64, 6, 16, 4096, 0, - fMan); - - return &iws->winsys; -} - - -void -intel_destroy_pipe_winsys( struct pipe_winsys *winsys ) -{ - struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys); - if (iws->regionPool) { - driPoolTakeDown(iws->regionPool); - } - free(iws); -} - diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c deleted file mode 100644 index 0bc2dc4002..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include "intel_context.h" -#include "intel_winsys.h" -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "pipe/p_format.h" -#include "softpipe/sp_winsys.h" - - -struct intel_softpipe_winsys { - struct softpipe_winsys sws; - struct intel_context *intel; -}; - -/** - * Return list of surface formats supported by this driver. - */ -static boolean -intel_is_format_supported(struct softpipe_winsys *sws, - enum pipe_format format) -{ - switch(format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_S8Z24_UNORM: - return TRUE; - default: - return FALSE; - } -} - - -/** - * Create rendering context which uses software rendering. - */ -struct pipe_context * -intel_create_softpipe( struct intel_context *intel, - struct pipe_winsys *winsys ) -{ - struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); - struct pipe_screen *screen = softpipe_create_screen(winsys); - - /* Fill in this struct with callbacks that softpipe will need to - * communicate with the window system, buffer manager, etc. - */ - isws->sws.is_format_supported = intel_is_format_supported; - isws->intel = intel; - - /* Create the softpipe context: - */ - return softpipe_create( screen, winsys, &isws->sws ); -} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c deleted file mode 100644 index 1bc1089352..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c +++ /dev/null @@ -1,953 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - * Keith Whitwell - */ - -#include -#include -#include "glthread.h" -#include "errno.h" -#include "ws_dri_bufmgr.h" -#include "string.h" -#include "imports.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" - -/* - * This lock is here to protect drmBO structs changing underneath us during a - * validate list call, since validatelist cannot take individiual locks for - * each drmBO. Validatelist takes this lock in write mode. Any access to an - * individual drmBO should take this lock in read mode, since in that case, the - * driBufferObject mutex will protect the access. Locking order is - * driBufferObject mutex - > this rw lock. - */ - -_glthread_DECLARE_STATIC_MUTEX(bmMutex); -_glthread_DECLARE_STATIC_COND(bmCond); - -static int kernelReaders = 0; -static int num_buffers = 0; -static int num_user_buffers = 0; - -static drmBO *drmBOListBuf(void *iterator) -{ - drmBONode *node; - drmMMListHead *l = (drmMMListHead *) iterator; - node = DRMLISTENTRY(drmBONode, l, head); - return node->buf; -} - -static void *drmBOListIterator(drmBOList *list) -{ - void *ret = list->list.next; - - if (ret == &list->list) - return NULL; - return ret; -} - -static void *drmBOListNext(drmBOList *list, void *iterator) -{ - void *ret; - - drmMMListHead *l = (drmMMListHead *) iterator; - ret = l->next; - if (ret == &list->list) - return NULL; - return ret; -} - -static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, - uint64_t arg0, - uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } - else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADD(&node->head, &list->list); - list->numOnList++; - return node; -} - -static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, - uint64_t mask, int *newItem) -{ - drmBONode *node, *cur; - drmMMListHead *l; - - *newItem = 0; - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - } - if (!cur) { - cur = drmAddListItem(list, buf, flags, mask); - if (!cur) { - return -ENOMEM; - } - *newItem = 1; - cur->arg0 = flags; - cur->arg1 = mask; - } - else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - return 0; -} - -static void drmBOFreeList(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->list.next; - while(l != &list->list) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->list.next; - list->numCurrent--; - list->numOnList--; - } - - l = list->free.next; - while(l != &list->free) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->free.next; - list->numCurrent--; - } -} - -static int drmAdjustListNodes(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - int ret = 0; - - while(list->numCurrent < list->numTarget) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - ret = -ENOMEM; - break; - } - list->numCurrent++; - DRMLISTADD(&node->head, &list->free); - } - - while(list->numCurrent > list->numTarget) { - l = list->free.next; - if (l == &list->free) - break; - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - list->numCurrent--; - } - return ret; -} - -static int drmBOCreateList(int numTarget, drmBOList *list) -{ - DRMINITLISTHEAD(&list->list); - DRMINITLISTHEAD(&list->free); - list->numTarget = numTarget; - list->numCurrent = 0; - list->numOnList = 0; - return drmAdjustListNodes(list); -} - -static int drmBOResetList(drmBOList *list) -{ - drmMMListHead *l; - int ret; - - ret = drmAdjustListNodes(list); - if (ret) - return ret; - - l = list->list.next; - while (l != &list->list) { - DRMLISTDEL(l); - DRMLISTADD(l, &list->free); - list->numOnList--; - l = list->list.next; - } - return drmAdjustListNodes(list); -} - -void driWriteLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - while(kernelReaders != 0) - _glthread_COND_WAIT(bmCond, bmMutex); -} - -void driWriteUnlockKernelBO(void) -{ - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - kernelReaders++; - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadUnlockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - if (--kernelReaders == 0) - _glthread_COND_BROADCAST(bmCond); - _glthread_UNLOCK_MUTEX(bmMutex); -} - - - - -/* - * TODO: Introduce fence pools in the same way as - * buffer object pools. - */ - -typedef struct _DriBufferObject -{ - DriBufferPool *pool; - _glthread_Mutex mutex; - int refCount; - const char *name; - uint64_t flags; - unsigned hint; - unsigned alignment; - unsigned createdByReference; - void *private; - /* user-space buffer: */ - unsigned userBuffer; - void *userData; - unsigned userSize; -} DriBufferObject; - -typedef struct _DriBufferList { - drmBOList drmBuffers; /* List of kernel buffers needing validation */ - drmBOList driBuffers; /* List of user-space buffers needing validation */ -} DriBufferList; - - -void -bmError(int val, const char *file, const char *function, int line) -{ - _mesa_printf("Fatal video memory manager error \"%s\".\n" - "Check kernel logs or set the LIBGL_DEBUG\n" - "environment variable to \"verbose\" for more info.\n" - "Detected in file %s, line %d, function %s.\n", - strerror(-val), file, line, function); -#ifndef NDEBUG - abort(); -#else - abort(); -#endif -} - -extern drmBO * -driBOKernel(struct _DriBufferObject *buf) -{ - drmBO *ret; - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - ret = buf->pool->kernel(buf->pool, buf->private); - if (!ret) - BM_CKFATAL(-EINVAL); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - - return ret; -} - -void -driBOWaitIdle(struct _DriBufferObject *buf, int lazy) -{ - - /* - * This function may block. Is it sane to keep the mutex held during - * that time?? - */ - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void * -driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) -{ - void *virtual; - int retval; - - if (buf->userBuffer) { - return buf->userData; - } - - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - retval = buf->pool->map(buf->pool, buf->private, flags, hint, - &buf->mutex, &virtual); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval == 0 ? virtual : NULL; -} - -void -driBOUnmap(struct _DriBufferObject *buf) -{ - if (buf->userBuffer) - return; - - assert(buf->private != NULL); - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -unsigned long -driBOOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->offset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -unsigned long -driBOPoolOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->poolOffset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -uint64_t -driBOFlags(struct _DriBufferObject *buf) -{ - uint64_t ret; - - assert(buf->private != NULL); - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->flags(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - return ret; -} - -struct _DriBufferObject * -driBOReference(struct _DriBufferObject *buf) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (++buf->refCount == 1) { - _glthread_UNLOCK_MUTEX(buf->mutex); - BM_CKFATAL(-EINVAL); - } - _glthread_UNLOCK_MUTEX(buf->mutex); - return buf; -} - -void -driBOUnReference(struct _DriBufferObject *buf) -{ - int tmp; - - if (!buf) - return; - - _glthread_LOCK_MUTEX(buf->mutex); - tmp = --buf->refCount; - if (!tmp) { - _glthread_UNLOCK_MUTEX(buf->mutex); - if (buf->private) { - if (buf->createdByReference) - buf->pool->unreference(buf->pool, buf->private); - else - buf->pool->destroy(buf->pool, buf->private); - } - if (buf->userBuffer) - num_user_buffers--; - else - num_buffers--; - free(buf); - } else - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - - -int -driBOData(struct _DriBufferObject *buf, - unsigned size, const void *data, - DriBufferPool *newPool, - uint64_t flags) -{ - void *virtual = NULL; - int newBuffer; - int retval = 0; - struct _DriBufferPool *pool; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - pool = buf->pool; - - if (pool == NULL && newPool != NULL) { - buf->pool = newPool; - pool = newPool; - } - if (newPool == NULL) - newPool = pool; - - if (!pool->create) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "driBOData called on invalid buffer\n"); - BM_CKFATAL(-EINVAL); - } - - newBuffer = (!buf->private || pool != newPool || - pool->size(pool, buf->private) < size); - - if (!flags) - flags = buf->flags; - - if (newBuffer) { - - if (buf->createdByReference) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "driBOData requiring resizing called on " - "shared buffer.\n"); - BM_CKFATAL(-EINVAL); - } - - if (buf->private) - buf->pool->destroy(buf->pool, buf->private); - - pool = newPool; - buf->pool = newPool; - buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (!buf->private) - retval = -ENOMEM; - - if (retval == 0) - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); - } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { - /* - * Buffer is busy. need to create a new one. - */ - - void *newBuf; - - newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (newBuf) { - buf->pool->destroy(buf->pool, buf->private); - buf->private = newBuf; - } - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } else { - uint64_t flag_diff = flags ^ buf->flags; - - /* - * We might need to change buffer flags. - */ - - if (flag_diff){ - assert(pool->setStatus != NULL); - BM_CKFATAL(pool->unmap(pool, buf->private)); - BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, - buf->flags)); - if (!data) - goto out; - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } - } - - if (retval == 0) { - if (data) - memcpy(virtual, data, size); - - BM_CKFATAL(pool->unmap(pool, buf->private)); - } - - out: - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval; -} - -void -driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, const void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, - &virtual)); - memcpy((unsigned char *) virtual + offset, data, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); - memcpy(data, (unsigned char *) virtual + offset, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->private != NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer for setReferenced\n"); - BM_CKFATAL(-EINVAL); - - } - if (buf->pool->reference == NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer pool for setReferenced\n"); - BM_CKFATAL(-EINVAL); - } - buf->private = buf->pool->reference(buf->pool, handle); - if (!buf->private) { - _mesa_error(NULL, GL_OUT_OF_MEMORY, - "Invalid buffer pool for setStatic\n"); - BM_CKFATAL(-ENOMEM); - } - buf->createdByReference = GL_TRUE; - buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -int -driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint) -{ - struct _DriBufferObject *buf; - int i; - - flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - - ++num_buffers; - - assert(pool); - - for (i = 0; i < n; ++i) { - buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); - if (!buf) - return -ENOMEM; - - _glthread_INIT_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(buf->mutex); - buf->refCount = 1; - buf->flags = flags; - buf->hint = hint; - buf->name = name; - buf->alignment = alignment; - buf->pool = pool; - buf->createdByReference = 0; - _glthread_UNLOCK_MUTEX(buf->mutex); - buffers[i] = buf; - } - return 0; -} - -void -driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject **buffers, - void *ptr, unsigned bytes) -{ - const unsigned alignment = 1, flags = 0, hint = 0; - - --num_buffers; /* JB: is inced in GenBuffes */ - driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); - ++num_user_buffers; - - (*buffers)->userBuffer = 1; - (*buffers)->userData = ptr; - (*buffers)->userSize = bytes; -} - -void -driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) -{ - int i; - - for (i = 0; i < n; ++i) { - driBOUnReference(buffers[i]); - } -} - - -void -driInitBufMgr(int fd) -{ - ; -} - -/* - * Note that lists are per-context and don't need mutex protection. - */ - -struct _DriBufferList * -driBOCreateList(int target) -{ - struct _DriBufferList *list = calloc(sizeof(*list), 1); - - BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); - BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); - return list; -} - -int -driBOResetList(struct _DriBufferList * list) -{ - int ret; - ret = drmBOResetList(&list->drmBuffers); - if (ret) - return ret; - ret = drmBOResetList(&list->driBuffers); - return ret; -} - -void -driBOFreeList(struct _DriBufferList * list) -{ - drmBOFreeList(&list->drmBuffers); - drmBOFreeList(&list->driBuffers); - free(list); -} - - -/* - * Copied from libdrm, because it is needed by driAddValidateItem. - */ - -static drmBONode * -driAddListItem(drmBOList * list, drmBO * item, - uint64_t arg0, uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - memset(&node->bo_arg, 0, sizeof(node->bo_arg)); - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADDTAIL(&node->head, &list->list); - list->numOnList++; - return node; -} - -/* - * Slightly modified version compared to the libdrm version. - * This one returns the list index of the buffer put on the list. - */ - -static int -driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, - uint64_t mask, int *itemLoc, - struct _drmBONode **pnode) -{ - drmBONode *node, *cur; - drmMMListHead *l; - int count = 0; - - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - count++; - } - if (!cur) { - cur = driAddListItem(list, buf, flags, mask); - if (!cur) - return -ENOMEM; - - cur->arg0 = flags; - cur->arg1 = mask; - } else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - *itemLoc = count; - *pnode = cur; - return 0; -} - - -void -driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node) -{ - int newItem; - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(driAddValidateItem(&list->drmBuffers, - buf->pool->kernel(buf->pool, buf->private), - flags, mask, itemLoc, node)); - BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, - flags, mask, &newItem)); - if (newItem) - buf->refCount++; - - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -drmBOList *driGetdrmBOList(struct _DriBufferList *list) -{ - driWriteLockKernelBO(); - return &list->drmBuffers; -} - -void driPutdrmBOList(struct _DriBufferList *list) -{ - driWriteUnlockKernelBO(); -} - - -void -driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->fence) - BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - -void -driBOUnrefUserList(struct _DriBufferList *list) -{ - struct _DriBufferObject *buf; - void *curBuf; - - curBuf = drmBOListIterator(&list->driBuffers); - while (curBuf) { - buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - -struct _DriFenceObject * -driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, const char *name, - drmFence *kFence) -{ - struct _DriFenceObject *fence; - struct _DriBufferObject *buf; - void *curBuf; - - fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, - kFence, sizeof(*kFence)); - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space fencing callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - driBOFence(buf, fence); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } - - driBOResetList(list); - return fence; -} - -void -driBOValidateUserList(struct _DriBufferList * list) -{ - void *curBuf; - struct _DriBufferObject *buf; - - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space validation callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->validate) - BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); - _glthread_UNLOCK_MUTEX(buf->mutex); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - - -void -driPoolTakeDown(struct _DriBufferPool *pool) -{ - pool->takeDown(pool); - -} - -unsigned long -driBOSize(struct _DriBufferObject *buf) -{ - unsigned long size; - - _glthread_LOCK_MUTEX(buf->mutex); - size = buf->pool->size(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return size; - -} - -drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) -{ - return &list->drmBuffers; -} - -drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) -{ - return &list->driBuffers; -} - diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h deleted file mode 100644 index fdaf5ee93a..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - * Keith Whitwell - */ - -#ifndef _PSB_BUFMGR_H_ -#define _PSB_BUFMGR_H_ -#include -#include "i915_drm.h" -#include "ws_dri_fencemgr.h" - -typedef struct _drmBONode -{ - drmMMListHead head; - drmBO *buf; - struct drm_i915_op_arg bo_arg; - uint64_t arg0; - uint64_t arg1; -} drmBONode; - -typedef struct _drmBOList { - unsigned numTarget; - unsigned numCurrent; - unsigned numOnList; - drmMMListHead list; - drmMMListHead free; -} drmBOList; - - -struct _DriFenceObject; -struct _DriBufferObject; -struct _DriBufferPool; -struct _DriBufferList; - -/* - * Return a pointer to the libdrm buffer object this DriBufferObject - * uses. - */ - -extern drmBO *driBOKernel(struct _DriBufferObject *buf); -extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, - unsigned hint); -extern void driBOUnmap(struct _DriBufferObject *buf); -extern unsigned long driBOOffset(struct _DriBufferObject *buf); -extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); - -extern uint64_t driBOFlags(struct _DriBufferObject *buf); -extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); -extern void driBOUnReference(struct _DriBufferObject *buf); - -extern int driBOData(struct _DriBufferObject *r_buf, - unsigned size, const void *data, - struct _DriBufferPool *pool, uint64_t flags); - -extern void driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - const void *data); -extern void driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - void *data); -extern int driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint); -extern void driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject *buffers[], - void *ptr, unsigned bytes); -extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); -extern void driInitBufMgr(int fd); -extern struct _DriBufferList *driBOCreateList(int target); -extern int driBOResetList(struct _DriBufferList * list); -extern void driBOAddListItem(struct _DriBufferList * list, - struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node); - -extern void driBOValidateList(int fd, struct _DriBufferList * list); -extern void driBOFreeList(struct _DriBufferList * list); -extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, - const char *name, - drmFence *kFence); -extern void driBOUnrefUserList(struct _DriBufferList *list); -extern void driBOValidateUserList(struct _DriBufferList * list); -extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); -extern void driPutdrmBOList(struct _DriBufferList *list); - -extern void driBOFence(struct _DriBufferObject *buf, - struct _DriFenceObject *fence); - -extern void driPoolTakeDown(struct _DriBufferPool *pool); -extern void driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle); -unsigned long driBOSize(struct _DriBufferObject *buf); -extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); -extern void driPoolTakeDown(struct _DriBufferPool *pool); - -extern void driReadLockKernelBO(void); -extern void driReadUnlockKernelBO(void); -extern void driWriteLockKernelBO(void); -extern void driWriteUnlockKernelBO(void); - -/* - * For debugging purposes. - */ - -extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); -extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); -#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h b/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h deleted file mode 100644 index 3a302e13d3..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#ifndef _PSB_BUFPOOL_H_ -#define _PSB_BUFPOOL_H_ - -#include -#include -struct _DriFenceObject; - -typedef struct _DriBufferPool -{ - int fd; - int (*map) (struct _DriBufferPool * pool, void *private, - unsigned flags, int hint, _glthread_Mutex *mutex, - void **virtual); - int (*unmap) (struct _DriBufferPool * pool, void *private); - int (*destroy) (struct _DriBufferPool * pool, void *private); - unsigned long (*offset) (struct _DriBufferPool * pool, void *private); - unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); - uint64_t (*flags) (struct _DriBufferPool * pool, void *private); - unsigned long (*size) (struct _DriBufferPool * pool, void *private); - void *(*create) (struct _DriBufferPool * pool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment); - void *(*reference) (struct _DriBufferPool * pool, unsigned handle); - int (*unreference) (struct _DriBufferPool * pool, void *private); - int (*fence) (struct _DriBufferPool * pool, void *private, - struct _DriFenceObject * fence); - drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); - int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); - int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy); - int (*setStatus) (struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags); - void (*takeDown) (struct _DriBufferPool * pool); - void *data; -} DriBufferPool; - -extern void bmError(int val, const char *file, const char *function, - int line); -#define BM_CKFATAL(val) \ - do{ \ - int tstVal = (val); \ - if (tstVal) \ - bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ - } while(0); - - -/* - * Builtin pools. - */ - -/* - * Kernel buffer objects. Size in multiples of page size. Page size aligned. - */ - -extern struct _DriBufferPool *driDRMPoolInit(int fd); -extern struct _DriBufferPool *driMallocPoolInit(void); - -struct _DriFreeSlabManager; -extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan); -extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); -extern struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); - - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c deleted file mode 100644 index 7c55dbc674..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c +++ /dev/null @@ -1,268 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" -#include "assert.h" - -/* - * Buffer pool implementation using DRM buffer objects as DRI buffer objects. - */ - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - unsigned pageSize = getpagesize(); - - if (!buf) - return NULL; - - if ((alignment > pageSize) && (alignment % pageSize)) { - free(buf); - return NULL; - } - - ret = drmBOCreate(pool->fd, size, alignment / pageSize, - NULL, - flags, hint, buf); - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static void * -pool_reference(struct _DriBufferPool *pool, unsigned handle) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - - if (!buf) - return NULL; - - ret = drmBOReference(pool->fd, handle, buf); - - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unreference(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOMap(pool->fd, buf, flags, hint, virtual); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOUnmap(pool->fd, buf); - driReadUnlockKernelBO(); - - return ret; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long offset; - - driReadLockKernelBO(); - assert(buf->flags & DRM_BO_FLAG_NO_MOVE); - offset = buf->offset; - driReadUnlockKernelBO(); - - return buf->offset; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - uint64_t flags; - - driReadLockKernelBO(); - flags = buf->flags; - driReadUnlockKernelBO(); - - return flags; -} - - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long size; - - driReadLockKernelBO(); - size = buf->size; - driReadUnlockKernelBO(); - - return buf->size; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - /* - * Noop. The kernel handles all fencing. - */ - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - return (drmBO *) private; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); - driReadUnlockKernelBO(); - - return ret; -} - - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - -/*static int -pool_setStatus(struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags) -{ - drmBO *buf = (drmBO *) private; - uint64_t new_flags = old_flags ^ flag_diff; - int ret; - - driReadLockKernelBO(); - ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, - 0, 0, 0); - driReadUnlockKernelBO(); - return ret; -}*/ - -struct _DriBufferPool * -driDRMPoolInit(int fd) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - - if (!pool) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - pool->reference = &pool_reference; - pool->unreference = &pool_unreference; - pool->data = NULL; - return pool; -} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c deleted file mode 100644 index 1f893b47ce..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c +++ /dev/null @@ -1,377 +0,0 @@ -#include "ws_dri_fencemgr.h" -#include "glthread.h" -#include -#include -#include - -/* - * Note: Locking order is - * _DriFenceObject::mutex - * _DriFenceMgr::mutex - */ - -struct _DriFenceMgr { - /* - * Constant members. Need no mutex protection. - */ - struct _DriFenceMgrCreateInfo info; - void *private; - - /* - * These members are protected by this->mutex - */ - _glthread_Mutex mutex; - int refCount; - drmMMListHead *heads; - int num_fences; -}; - -struct _DriFenceObject { - - /* - * These members are constant and need no mutex protection. - */ - struct _DriFenceMgr *mgr; - uint32_t fence_class; - uint32_t fence_type; - - /* - * These members are protected by mgr->mutex. - */ - drmMMListHead head; - int refCount; - - /* - * These members are protected by this->mutex. - */ - _glthread_Mutex mutex; - uint32_t signaled_type; - void *private; -}; - -uint32_t -driFenceType(struct _DriFenceObject *fence) -{ - return fence->fence_type; -} - -struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) -{ - struct _DriFenceMgr *tmp; - uint32_t i; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->refCount = 1; - tmp->info = *info; - tmp->num_fences = 0; - tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); - if (!tmp->heads) - goto out_err; - - for (i=0; iinfo.num_classes; ++i) { - DRMINITLISTHEAD(&tmp->heads[i]); - } - _glthread_UNLOCK_MUTEX(tmp->mutex); - return tmp; - - out_err: - if (tmp) - free(tmp); - return NULL; -} - -static void -driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) -{ - struct _DriFenceMgr *mgr = *pMgr; - - *pMgr = NULL; - if (--mgr->refCount == 0) - free(mgr); - else - _glthread_UNLOCK_MUTEX(mgr->mutex); -} - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr) -{ - _glthread_LOCK_MUTEX((*pMgr)->mutex); - driFenceMgrUnrefUnlock(pMgr); -} - -static void -driFenceUnReferenceLocked(struct _DriFenceObject **pFence) -{ - struct _DriFenceObject *fence = *pFence; - struct _DriFenceMgr *mgr = fence->mgr; - - *pFence = NULL; - if (--fence->refCount == 0) { - DRMLISTDELINIT(&fence->head); - if (fence->private) - mgr->info.unreference(mgr, &fence->private); - --mgr->num_fences; - fence->mgr = NULL; - --mgr->refCount; - free(fence); - - } -} - - -static void -driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, - drmMMListHead *list, - uint32_t fence_class, - uint32_t fence_type) -{ - struct _DriFenceObject *entry; - drmMMListHead *prev; - - while(list != &mgr->heads[fence_class]) { - entry = DRMLISTENTRY(struct _DriFenceObject, list, head); - - /* - * Up refcount so that entry doesn't disappear from under us - * when we unlock-relock mgr to get the correct locking order. - */ - - ++entry->refCount; - _glthread_UNLOCK_MUTEX(mgr->mutex); - _glthread_LOCK_MUTEX(entry->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - - prev = list->prev; - - - - if (list->prev == list) { - - /* - * Somebody else removed the entry from the list. - */ - - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - return; - } - - entry->signaled_type |= (fence_type & entry->fence_type); - if (entry->signaled_type == entry->fence_type) { - DRMLISTDELINIT(list); - mgr->info.unreference(mgr, &entry->private); - } - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - list = prev; - } -} - - -int -driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint) -{ - struct _DriFenceMgr *mgr = fence->mgr; - int ret = 0; - - _glthread_LOCK_MUTEX(fence->mutex); - - if ((fence->signaled_type & fence_type) == fence_type) - goto out0; - - ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); - if (ret) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - fence_type); - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) -{ - uint32_t ret; - - _glthread_LOCK_MUTEX(fence->mutex); - ret = fence->signaled_type; - _glthread_UNLOCK_MUTEX(fence->mutex); - - return ret; -} - -int -driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, - uint32_t *signaled) -{ - int ret = 0; - struct _DriFenceMgr *mgr; - - _glthread_LOCK_MUTEX(fence->mutex); - mgr = fence->mgr; - *signaled = fence->signaled_type; - if ((fence->signaled_type & flush_type) == flush_type) - goto out0; - - ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); - if (ret) { - *signaled = fence->signaled_type; - goto out0; - } - - if ((fence->signaled_type | *signaled) == fence->signaled_type) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - *signaled); - - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -struct _DriFenceObject * -driFenceReference(struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(fence->mgr->mutex); - ++fence->refCount; - _glthread_UNLOCK_MUTEX(fence->mgr->mutex); - return fence; -} - -void -driFenceUnReference(struct _DriFenceObject **pFence) -{ - struct _DriFenceMgr *mgr; - - if (*pFence == NULL) - return; - - mgr = (*pFence)->mgr; - _glthread_LOCK_MUTEX(mgr->mutex); - ++mgr->refCount; - driFenceUnReferenceLocked(pFence); - driFenceMgrUnrefUnlock(&mgr); -} - -struct _DriFenceObject -*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, - uint32_t fence_type, void *private, size_t private_size) -{ - struct _DriFenceObject *fence; - size_t fence_size = sizeof(*fence); - - if (private_size) - fence_size = ((fence_size + 15) & ~15); - - fence = calloc(1, fence_size + private_size); - - if (!fence) { - int ret = mgr->info.finish(mgr, private, fence_type, 0); - - if (ret) - usleep(10000000); - - return NULL; - } - - _glthread_INIT_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - fence->refCount = 1; - DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); - fence->mgr = mgr; - ++mgr->refCount; - ++mgr->num_fences; - _glthread_UNLOCK_MUTEX(mgr->mutex); - fence->fence_class = fence_class; - fence->fence_type = fence_type; - fence->signaled_type = 0; - fence->private = private; - if (private_size) { - fence->private = (void *)(((uint8_t *) fence) + fence_size); - memcpy(fence->private, private, private_size); - } - - _glthread_UNLOCK_MUTEX(fence->mutex); - return fence; -} - - -static int -tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type) -{ - long fd = (long) mgr->private; - int dummy; - drmFence *fence = (drmFence *) private; - int ret; - - *signaled_type = 0; - ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); - if (ret) - return ret; - - *signaled_type = fence->signaled; - - return 0; -} - -static int -tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, - int lazy_hint) -{ - long fd = (long) mgr->private; - unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; - - return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); -} - -static int -tUnref(struct _DriFenceMgr *mgr, void **private) -{ - long fd = (long) mgr->private; - drmFence *fence = (drmFence *) *private; - *private = NULL; - - return drmFenceUnreference(fd, fence); -} - -struct _DriFenceMgr *driFenceMgrTTMInit(int fd) -{ - struct _DriFenceMgrCreateInfo info; - struct _DriFenceMgr *mgr; - - info.flags = DRI_FENCE_CLASS_ORDERED; - info.num_classes = 4; - info.signaled = tSignaled; - info.finish = tFinish; - info.unreference = tUnref; - - mgr = driFenceMgrCreate(&info); - if (mgr == NULL) - return NULL; - - mgr->private = (void *) (long) fd; - return mgr; -} - diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h deleted file mode 100644 index 4ea58dfe18..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef DRI_FENCEMGR_H -#define DRI_FENCEMGR_H - -#include -#include - -struct _DriFenceObject; -struct _DriFenceMgr; - -/* - * Do a quick check to see if the fence manager has registered the fence - * object as signaled. Note that this function may return a false negative - * answer. - */ -extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); - -/* - * Check if the fence object is signaled. This function can be substantially - * more expensive to call than the above function, but will not return a false - * negative answer. The argument "flush_type" sets the types that the - * underlying mechanism must make sure will eventually signal. - */ -extern int driFenceSignaledType(struct _DriFenceObject *fence, - uint32_t flush_type, uint32_t *signaled); - -/* - * Convenience functions. - */ - -static inline int driFenceSignaled(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types; - int ret = driFenceSignaledType(fence, flush_type, &signaled_types); - if (ret) - return 0; - return ((signaled_types & flush_type) == flush_type); -} - -static inline int driFenceSignaledCached(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types = - driFenceSignaledTypeCached(fence); - - return ((signaled_types & flush_type) == flush_type); -} - -/* - * Reference a fence object. - */ -extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); - -/* - * Unreference a fence object. The fence object pointer will be reset to NULL. - */ - -extern void driFenceUnReference(struct _DriFenceObject **pFence); - - -/* - * Wait for a fence to signal the indicated fence_type. - * If "lazy_hint" is true, it indicates that the wait may sleep to avoid - * busy-wait polling. - */ -extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint); - -/* - * Create a DriFenceObject for manager "mgr". - * - * "private" is a pointer that should be used for the callbacks in - * struct _DriFenceMgrCreateInfo. - * - * if private_size is nonzero, then the info stored at *private, with size - * private size will be copied and the fence manager will instead use a - * pointer to the copied data for the callbacks in - * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by - * "private" may be destroyed after the call to driFenceCreate. - */ -extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, - uint32_t fence_class, - uint32_t fence_type, - void *private, - size_t private_size); - -extern uint32_t driFenceType(struct _DriFenceObject *fence); - -/* - * Fence creations are ordered. If a fence signals a fence_type, - * it is safe to assume that all fences of the same class that was - * created before that fence has signaled the same type. - */ - -#define DRI_FENCE_CLASS_ORDERED (1 << 0) - -struct _DriFenceMgrCreateInfo { - uint32_t flags; - uint32_t num_classes; - int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type); - int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); - int (*unreference) (struct _DriFenceMgr *mgr, void **private); -}; - -extern struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr); - -extern struct _DriFenceMgr * -driFenceMgrTTMInit(int fd); - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c deleted file mode 100644 index bf97d7e440..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c +++ /dev/null @@ -1,162 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include -#include -#include "imports.h" -#include "glthread.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" -#include "intel_screen.h" - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - unsigned long *private = malloc(size + 2*sizeof(unsigned long)); - if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) - abort(); - - *private = size; - return (void *)private; -} - - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - free(private); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - *virtual = (void *)((unsigned long *)private + 2); - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); - return 0UL; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - return *(unsigned long *) private; -} - - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - abort(); - return 0UL; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - abort(); - return NULL; -} - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - - -struct _DriBufferPool * -driMallocPoolInit(void) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - if (!pool) - return NULL; - - pool->data = NULL; - pool->fd = -1; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - return pool; -} diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c deleted file mode 100644 index e69519a01f..0000000000 --- a/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c +++ /dev/null @@ -1,970 +0,0 @@ -/************************************************************************** - * - * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#include -#include -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" -#include "ws_dri_bufmgr.h" -#include "glthread.h" - -#define DRI_SLABPOOL_ALLOC_RETRIES 100 - -struct _DriSlab; - -struct _DriSlabBuffer { - int isSlabBuffer; - drmBO *bo; - struct _DriFenceObject *fence; - struct _DriSlab *parent; - drmMMListHead head; - uint32_t mapCount; - uint32_t start; - uint32_t fenceType; - int unFenced; - _glthread_Cond event; -}; - -struct _DriKernelBO { - int fd; - drmBO bo; - drmMMListHead timeoutHead; - drmMMListHead head; - struct timeval timeFreed; - uint32_t pageAlignment; - void *virtual; -}; - -struct _DriSlab{ - drmMMListHead head; - drmMMListHead freeBuffers; - uint32_t numBuffers; - uint32_t numFree; - struct _DriSlabBuffer *buffers; - struct _DriSlabSizeHeader *header; - struct _DriKernelBO *kbo; -}; - - -struct _DriSlabSizeHeader { - drmMMListHead slabs; - drmMMListHead freeSlabs; - drmMMListHead delayedBuffers; - uint32_t numDelayed; - struct _DriSlabPool *slabPool; - uint32_t bufSize; - _glthread_Mutex mutex; -}; - -struct _DriFreeSlabManager { - struct timeval slabTimeout; - struct timeval checkInterval; - struct timeval nextCheck; - drmMMListHead timeoutList; - drmMMListHead unCached; - drmMMListHead cached; - _glthread_Mutex mutex; -}; - - -struct _DriSlabPool { - - /* - * The data of this structure remains constant after - * initialization and thus needs no mutex protection. - */ - - struct _DriFreeSlabManager *fMan; - uint64_t proposedFlags; - uint64_t validMask; - uint32_t *bucketSizes; - uint32_t numBuckets; - uint32_t pageSize; - int fd; - int pageAlignment; - int maxSlabSize; - int desiredNumBuffers; - struct _DriSlabSizeHeader *headers; -}; - -/* - * FIXME: Perhaps arrange timeout slabs in size buckets for fast - * retreival?? - */ - - -static inline int -driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) -{ - return ((arg1->tv_sec > arg2->tv_sec) || - ((arg1->tv_sec == arg2->tv_sec) && - (arg1->tv_usec > arg2->tv_usec))); -} - -static inline void -driTimeAdd(struct timeval *arg, struct timeval *add) -{ - unsigned int sec; - - arg->tv_sec += add->tv_sec; - arg->tv_usec += add->tv_usec; - sec = arg->tv_usec / 1000000; - arg->tv_sec += sec; - arg->tv_usec -= sec*1000000; -} - -static void -driFreeKernelBO(struct _DriKernelBO *kbo) -{ - if (!kbo) - return; - - (void) drmBOUnreference(kbo->fd, &kbo->bo); - free(kbo); -} - - -static void -driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, - struct timeval *time) -{ - drmMMListHead *list, *next; - struct _DriKernelBO *kbo; - - if (!driTimeAfterEq(time, &fMan->nextCheck)) - return; - - for (list = fMan->timeoutList.next, next = list->next; - list != &fMan->timeoutList; - list = next, next = list->next) { - - kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); - - if (!driTimeAfterEq(time, &kbo->timeFreed)) - break; - - DRMLISTDELINIT(&kbo->timeoutHead); - DRMLISTDELINIT(&kbo->head); - driFreeKernelBO(kbo); - } - - fMan->nextCheck = *time; - driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); -} - - -/* - * Add a _DriKernelBO to the free slab manager. - * This means that it is available for reuse, but if it's not - * reused in a while, it will be freed. - */ - -static void -driSetKernelBOFree(struct _DriFreeSlabManager *fMan, - struct _DriKernelBO *kbo) -{ - struct timeval time; - - _glthread_LOCK_MUTEX(fMan->mutex); - gettimeofday(&time, NULL); - driTimeAdd(&time, &fMan->slabTimeout); - - kbo->timeFreed = time; - - if (kbo->bo.flags & DRM_BO_FLAG_CACHED) - DRMLISTADD(&kbo->head, &fMan->cached); - else - DRMLISTADD(&kbo->head, &fMan->unCached); - - DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); - driFreeTimeoutKBOsLocked(fMan, &time); - - _glthread_UNLOCK_MUTEX(fMan->mutex); -} - -/* - * Get a _DriKernelBO for us to use as storage for a slab. - * - */ - -static struct _DriKernelBO * -driAllocKernelBO(struct _DriSlabSizeHeader *header) - -{ - struct _DriSlabPool *slabPool = header->slabPool; - struct _DriFreeSlabManager *fMan = slabPool->fMan; - drmMMListHead *list, *next, *head; - uint32_t size = header->bufSize * slabPool->desiredNumBuffers; - struct _DriKernelBO *kbo; - struct _DriKernelBO *kboTmp; - int ret; - - /* - * FIXME: We should perhaps allow some variation in slabsize in order - * to efficiently reuse slabs. - */ - - size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; - size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); - _glthread_LOCK_MUTEX(fMan->mutex); - - kbo = NULL; - - retry: - head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? - &fMan->cached : &fMan->unCached; - - for (list = head->next, next = list->next; - list != head; - list = next, next = list->next) { - - kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); - - if ((kboTmp->bo.size == size) && - (slabPool->pageAlignment == 0 || - (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { - - if (!kbo) - kbo = kboTmp; - - if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) - break; - - } - } - - if (kbo) { - DRMLISTDELINIT(&kbo->head); - DRMLISTDELINIT(&kbo->timeoutHead); - } - - _glthread_UNLOCK_MUTEX(fMan->mutex); - - if (kbo) { - uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; - - ret = 0; - if (new_mask) { - ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, - new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); - } - if (ret == 0) - return kbo; - - driFreeKernelBO(kbo); - kbo = NULL; - goto retry; - } - - kbo = calloc(1, sizeof(struct _DriKernelBO)); - if (!kbo) - return NULL; - - kbo->fd = slabPool->fd; - DRMINITLISTHEAD(&kbo->head); - DRMINITLISTHEAD(&kbo->timeoutHead); - ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, - slabPool->proposedFlags, - DRM_BO_HINT_DONT_FENCE, &kbo->bo); - if (ret) - goto out_err0; - - ret = drmBOMap(kbo->fd, &kbo->bo, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &kbo->virtual); - - if (ret) - goto out_err1; - - ret = drmBOUnmap(kbo->fd, &kbo->bo); - if (ret) - goto out_err1; - - return kbo; - - out_err1: - drmBOUnreference(kbo->fd, &kbo->bo); - out_err0: - free(kbo); - return NULL; -} - - -static int -driAllocSlab(struct _DriSlabSizeHeader *header) -{ - struct _DriSlab *slab; - struct _DriSlabBuffer *buf; - uint32_t numBuffers; - int ret; - int i; - - slab = calloc(1, sizeof(*slab)); - if (!slab) - return -ENOMEM; - - slab->kbo = driAllocKernelBO(header); - if (!slab->kbo) { - ret = -ENOMEM; - goto out_err0; - } - - numBuffers = slab->kbo->bo.size / header->bufSize; - - slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); - if (!slab->buffers) { - ret = -ENOMEM; - goto out_err1; - } - - DRMINITLISTHEAD(&slab->head); - DRMINITLISTHEAD(&slab->freeBuffers); - slab->numBuffers = numBuffers; - slab->numFree = 0; - slab->header = header; - - buf = slab->buffers; - for (i=0; i < numBuffers; ++i) { - buf->parent = slab; - buf->start = i* header->bufSize; - buf->mapCount = 0; - buf->isSlabBuffer = 1; - _glthread_INIT_COND(buf->event); - DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); - slab->numFree++; - buf++; - } - - DRMLISTADDTAIL(&slab->head, &header->slabs); - - return 0; - - out_err1: - driSetKernelBOFree(header->slabPool->fMan, slab->kbo); - free(slab->buffers); - out_err0: - free(slab); - return ret; -} - -/* - * Delete a buffer from the slab header delayed list and put - * it on the slab free list. - */ - -static void -driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) -{ - struct _DriSlab *slab = buf->parent; - struct _DriSlabSizeHeader *header = slab->header; - drmMMListHead *list = &buf->head; - - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &slab->freeBuffers); - slab->numFree++; - - if (slab->head.next == &slab->head) - DRMLISTADDTAIL(&slab->head, &header->slabs); - - if (slab->numFree == slab->numBuffers) { - list = &slab->head; - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &header->freeSlabs); - } - - if (header->slabs.next == &header->slabs || - slab->numFree != slab->numBuffers) { - - drmMMListHead *next; - struct _DriFreeSlabManager *fMan = header->slabPool->fMan; - - for (list = header->freeSlabs.next, next = list->next; - list != &header->freeSlabs; - list = next, next = list->next) { - - slab = DRMLISTENTRY(struct _DriSlab, list, head); - - DRMLISTDELINIT(list); - driSetKernelBOFree(fMan, slab->kbo); - free(slab->buffers); - free(slab); - } - } -} - -static void -driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) -{ - drmMMListHead *list, *prev, *first; - struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - int firstWasSignaled = 1; - int signaled; - int i; - int ret; - - /* - * Rerun the freeing test if the youngest tested buffer - * was signaled, since there might be more idle buffers - * in the delay list. - */ - - while (firstWasSignaled) { - firstWasSignaled = 0; - signaled = 0; - first = header->delayedBuffers.next; - - /* Only examine the oldest 1/3 of delayed buffers: - */ - if (header->numDelayed > 3) { - for (i = 0; i < header->numDelayed; i += 3) { - first = first->next; - } - } - - for (list = first, prev = list->prev; - list != &header->delayedBuffers; - list = prev, prev = list->prev) { - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - slab = buf->parent; - - if (!signaled) { - if (wait) { - ret = driFenceFinish(buf->fence, buf->fenceType, 0); - if (ret) - break; - signaled = 1; - wait = 0; - } else { - signaled = driFenceSignaled(buf->fence, buf->fenceType); - } - if (signaled) { - if (list == first) - firstWasSignaled = 1; - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } - } -} - - -static struct _DriSlabBuffer * -driSlabAllocBuffer(struct _DriSlabSizeHeader *header) -{ - static struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - drmMMListHead *list; - int count = DRI_SLABPOOL_ALLOC_RETRIES; - - _glthread_LOCK_MUTEX(header->mutex); - while(header->slabs.next == &header->slabs && count > 0) { - driSlabCheckFreeLocked(header, 0); - if (header->slabs.next != &header->slabs) - break; - - _glthread_UNLOCK_MUTEX(header->mutex); - if (count != DRI_SLABPOOL_ALLOC_RETRIES) - usleep(1); - _glthread_LOCK_MUTEX(header->mutex); - (void) driAllocSlab(header); - count--; - } - - list = header->slabs.next; - if (list == &header->slabs) { - _glthread_UNLOCK_MUTEX(header->mutex); - return NULL; - } - slab = DRMLISTENTRY(struct _DriSlab, list, head); - if (--slab->numFree == 0) - DRMLISTDELINIT(list); - - list = slab->freeBuffers.next; - DRMLISTDELINIT(list); - - _glthread_UNLOCK_MUTEX(header->mutex); - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - return buf; -} - -static void * -pool_create(struct _DriBufferPool *driPool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment) -{ - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - struct _DriSlabSizeHeader *header; - struct _DriSlabBuffer *buf; - void *dummy; - int i; - int ret; - - /* - * FIXME: Check for compatibility. - */ - header = pool->headers; - for (i=0; inumBuckets; ++i) { - if (header->bufSize >= size) - break; - header++; - } - - if (i < pool->numBuckets) - return driSlabAllocBuffer(header); - - - /* - * Fall back to allocate a buffer object directly from DRM. - * and wrap it in a driBO structure. - */ - - - buf = calloc(1, sizeof(*buf)); - - if (!buf) - return NULL; - - buf->bo = calloc(1, sizeof(*buf->bo)); - if (!buf->bo) - goto out_err0; - - if (alignment) { - if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) - goto out_err1; - if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) - goto out_err1; - } - - ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, - flags, hint, buf->bo); - if (ret) - goto out_err1; - - ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &dummy); - if (ret) - goto out_err2; - - ret = drmBOUnmap(pool->fd, buf->bo); - if (ret) - goto out_err2; - - return buf; - out_err2: - drmBOUnreference(pool->fd, buf->bo); - out_err1: - free(buf->bo); - out_err0: - free(buf); - return NULL; -} - -static int -pool_destroy(struct _DriBufferPool *driPool, void *private) -{ - struct _DriSlabBuffer *buf = - (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - int ret; - - ret = drmBOUnreference(pool->fd, buf->bo); - free(buf->bo); - free(buf); - return ret; - } - - slab = buf->parent; - header = slab->header; - - _glthread_LOCK_MUTEX(header->mutex); - buf->unFenced = 0; - buf->mapCount = 0; - - if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { - DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); - header->numDelayed++; - } else { - if (buf->fence) - driFenceUnReference(&buf->fence); - driSlabFreeBufferLocked(buf); - } - - _glthread_UNLOCK_MUTEX(header->mutex); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *driPool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - while(buf->unFenced) - _glthread_COND_WAIT(buf->event, *mutex); - - if (!buf->fence) - return 0; - - driFenceFinish(buf->fence, buf->fenceType, lazy); - driFenceUnReference(&buf->fence); - - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - int busy; - - if (buf->isSlabBuffer) - busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); - else - busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); - - - if (busy) { - if (hint & DRM_BO_HINT_DONT_BLOCK) - return -EBUSY; - else { - (void) pool_waitIdle(pool, private, mutex, 0); - } - } - - ++buf->mapCount; - *virtual = (buf->isSlabBuffer) ? - (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : - (void *) buf->bo->virtual; - - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - --buf->mapCount; - if (buf->mapCount == 0 && buf->isSlabBuffer) - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return buf->bo->offset; - } - - slab = buf->parent; - header = slab->header; - - (void) header; - assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return slab->kbo->bo.offset + buf->start; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - return buf->start; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return buf->bo->flags; - - return buf->parent->kbo->bo.flags; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - if (!buf->isSlabBuffer) - return buf->bo->size; - - return buf->parent->header->bufSize; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - drmBO *bo; - - if (buf->fence) - driFenceUnReference(&buf->fence); - - buf->fence = driFenceReference(fence); - bo = (buf->isSlabBuffer) ? - &buf->parent->kbo->bo: - buf->bo; - buf->fenceType = bo->fenceFlags; - - buf->unFenced = 0; - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf) - return NULL; - - return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; -} - -static int -pool_validate(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return 0; - - while(buf->mapCount != 0) - _glthread_COND_WAIT(buf->event, *mutex); - - buf->unFenced = 1; - return 0; -} - - -struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) -{ - struct _DriFreeSlabManager *tmp; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; - tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; - tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; - - tmp->checkInterval.tv_usec = checkIntervalMsec*1000; - tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; - tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; - - gettimeofday(&tmp->nextCheck, NULL); - driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); - DRMINITLISTHEAD(&tmp->timeoutList); - DRMINITLISTHEAD(&tmp->unCached); - DRMINITLISTHEAD(&tmp->cached); - _glthread_UNLOCK_MUTEX(tmp->mutex); - - return tmp; -} - -void -driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) -{ - struct timeval time; - - time = fMan->nextCheck; - driTimeAdd(&time, &fMan->checkInterval); - - _glthread_LOCK_MUTEX(fMan->mutex); - driFreeTimeoutKBOsLocked(fMan, &time); - _glthread_UNLOCK_MUTEX(fMan->mutex); - - assert(fMan->timeoutList.next == &fMan->timeoutList); - assert(fMan->unCached.next == &fMan->unCached); - assert(fMan->cached.next == &fMan->cached); - - free(fMan); -} - -static void -driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, - struct _DriSlabSizeHeader *header) -{ - _glthread_INIT_MUTEX(header->mutex); - _glthread_LOCK_MUTEX(header->mutex); - - DRMINITLISTHEAD(&header->slabs); - DRMINITLISTHEAD(&header->freeSlabs); - DRMINITLISTHEAD(&header->delayedBuffers); - - header->numDelayed = 0; - header->slabPool = pool; - header->bufSize = size; - - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -driFinishSizeHeader(struct _DriSlabSizeHeader *header) -{ - drmMMListHead *list, *next; - struct _DriSlabBuffer *buf; - - _glthread_LOCK_MUTEX(header->mutex); - for (list = header->delayedBuffers.next, next = list->next; - list != &header->delayedBuffers; - list = next, next = list->next) { - - buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); - if (buf->fence) { - (void) driFenceFinish(buf->fence, buf->fenceType, 0); - driFenceUnReference(&buf->fence); - } - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -pool_takedown(struct _DriBufferPool *driPool) -{ - struct _DriSlabPool *pool = driPool->data; - int i; - - for (i=0; inumBuckets; ++i) { - driFinishSizeHeader(&pool->headers[i]); - } - - free(pool->headers); - free(pool->bucketSizes); - free(pool); - free(driPool); -} - -struct _DriBufferPool * -driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan) -{ - struct _DriBufferPool *driPool; - struct _DriSlabPool *pool; - uint32_t i; - - driPool = calloc(1, sizeof(*driPool)); - if (!driPool) - return NULL; - - pool = calloc(1, sizeof(*pool)); - if (!pool) - goto out_err0; - - pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); - if (!pool->bucketSizes) - goto out_err1; - - pool->headers = calloc(numSizes, sizeof(*pool->headers)); - if (!pool->headers) - goto out_err2; - - pool->fMan = fMan; - pool->proposedFlags = flags; - pool->validMask = validMask; - pool->numBuckets = numSizes; - pool->pageSize = getpagesize(); - pool->fd = fd; - pool->pageAlignment = pageAlignment; - pool->maxSlabSize = maxSlabSize; - pool->desiredNumBuffers = desiredNumBuffers; - - for (i=0; inumBuckets; ++i) { - pool->bucketSizes[i] = (smallestSize << i); - driInitSizeHeader(pool, pool->bucketSizes[i], - &pool->headers[i]); - } - - driPool->data = (void *) pool; - driPool->map = &pool_map; - driPool->unmap = &pool_unmap; - driPool->destroy = &pool_destroy; - driPool->offset = &pool_offset; - driPool->poolOffset = &pool_poolOffset; - driPool->flags = &pool_flags; - driPool->size = &pool_size; - driPool->create = &pool_create; - driPool->fence = &pool_fence; - driPool->kernel = &pool_kernel; - driPool->validate = &pool_validate; - driPool->waitIdle = &pool_waitIdle; - driPool->takeDown = &pool_takedown; - - return driPool; - - out_err2: - free(pool->bucketSizes); - out_err1: - free(pool); - out_err0: - free(driPool); - - return NULL; -} -- cgit v1.2.3 From 0931b421d67b8ce471f17d43c183017f1eb92e31 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 6 Jun 2008 15:04:45 +0100 Subject: draw: make sure middle-end primitive is uptodate in vcache --- src/gallium/auxiliary/draw/draw_pt_vcache.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 2eafe270bc..cda2987c9e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -58,10 +58,21 @@ struct vcache_frontend { unsigned input_prim; unsigned output_prim; + + unsigned middle_prim; + unsigned opt; }; static void vcache_flush( struct vcache_frontend *vcache ) { + if (vcache->middle_prim != vcache->output_prim) { + vcache->middle_prim = vcache->output_prim; + vcache->middle->prepare( vcache->middle, + vcache->middle_prim, + vcache->opt, + &vcache->fetch_max ); + } + if (vcache->draw_count) { vcache->middle->run( vcache->middle, vcache->fetch_elts, @@ -308,6 +319,14 @@ static void vcache_check_run( struct draw_pt_front_end *frontend, goto fail; } + if (vcache->middle_prim != vcache->input_prim) { + vcache->middle_prim = vcache->input_prim; + vcache->middle->prepare( vcache->middle, + vcache->middle_prim, + vcache->opt, + &vcache->fetch_max ); + } + if (min_index == 0 && index_size == 2) @@ -412,7 +431,13 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, vcache->output_prim = draw_pt_reduced_prim(prim); vcache->middle = middle; - middle->prepare( middle, vcache->output_prim, opt, &vcache->fetch_max ); + vcache->opt = opt; + + /* Have to run prepare here, but try and guess a good prim for + * doing so: + */ + vcache->middle_prim = (opt & PT_PIPELINE) ? vcache->output_prim : vcache->input_prim; + middle->prepare( middle, vcache->middle_prim, opt, &vcache->fetch_max ); } -- cgit v1.2.3 From 0a84d327de8258104b98b176c0eaf0fb6712a982 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 6 Jun 2008 10:42:13 -0600 Subject: egl: open X display if needed --- src/gallium/winsys/egl_xlib/egl_xlib.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 07b3c0eb00..7bef46d560 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -573,6 +573,10 @@ _eglMain(_EGLDisplay *dpy, const char *args) if (!xdrv) return NULL; + if (!dpy->Xdpy) { + dpy->Xdpy = XOpenDisplay(NULL); + } + _eglInitDriverFallbacks(&xdrv->Base); xdrv->Base.API.Initialize = xlib_eglInitialize; xdrv->Base.API.Terminate = xlib_eglTerminate; -- cgit v1.2.3 From 463a47bf59398e850d5a6537da1186d855bd2919 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 6 Jun 2008 18:09:32 +0100 Subject: draw: fix intermediate buffer confusion in draw_vs_varient.c The final output buffer can't be used to hold intermediate results as the intermediate vertex size may be greater than the final vertex size, and in any case the output buffer may be uncached in hw drivers. --- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 7 + src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h | 2 + src/gallium/auxiliary/draw/draw_vs_varient.c | 175 +++++++++++---------- 3 files changed, 101 insertions(+), 83 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 5a1d79d996..5ce3aba2a2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -193,6 +193,13 @@ static void fse_prepare( struct draw_pt_middle_end *middle, *max_vertices = (draw->render->max_vertex_buffer_bytes / (vinfo->size * 4)); + /* Probably need to do this somewhere (or fix exec shader not to + * need it): + */ + if (1) { + struct draw_vertex_shader *vs = draw->vs.vertex_shader; + vs->prepare(vs, draw); + } //return TRUE; diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h index 5c99a47e49..ec05bbeab4 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h @@ -13,6 +13,8 @@ static void FUNC( struct draw_pt_front_end *frontend, unsigned i; ushort flags; + if (0) debug_printf("%s %d\n", __FUNCTION__, count); + switch (vcache->input_prim) { case PIPE_PRIM_POINTS: diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index 3ceca5e849..d8317d3bbe 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -55,6 +55,8 @@ struct draw_vs_varient_generic { */ struct translate *fetch; struct translate *emit; + + unsigned temp_vertex_stride; }; @@ -84,7 +86,7 @@ static void do_rhw_viewport( struct draw_vs_varient_generic *vsvg, char *ptr = (char *)output_buffer; const float *scale = vsvg->base.vs->draw->viewport.scale; const float *trans = vsvg->base.vs->draw->viewport.translate; - unsigned stride = vsvg->base.key.output_stride; + unsigned stride = vsvg->temp_vertex_stride; unsigned j; for (j = 0; j < count; j++, ptr += stride) { @@ -99,13 +101,13 @@ static void do_rhw_viewport( struct draw_vs_varient_generic *vsvg, } static void do_viewport( struct draw_vs_varient_generic *vsvg, - unsigned count, - void *output_buffer ) + unsigned count, + void *output_buffer ) { char *ptr = (char *)output_buffer; const float *scale = vsvg->base.vs->draw->viewport.scale; const float *trans = vsvg->base.vs->draw->viewport.translate; - unsigned stride = vsvg->base.key.output_stride; + unsigned stride = vsvg->temp_vertex_stride; unsigned j; for (j = 0; j < count; j++, ptr += stride) { @@ -124,7 +126,9 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, void *output_buffer) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; - + unsigned temp_vertex_stride = vsvg->temp_vertex_stride; + void *temp_buffer = MALLOC( align(count,4) * temp_vertex_stride ); + if (0) debug_printf("%s %d \n", __FUNCTION__, count); /* Want to do this in small batches for cache locality? @@ -135,44 +139,45 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, count, output_buffer ); - //if (!vsvg->base.vs->is_passthrough) - { - vsvg->base.vs->run_linear( vsvg->base.vs, - output_buffer, - output_buffer, - (const float (*)[4])vsvg->base.vs->draw->pt.user.constants, - count, - vsvg->base.key.output_stride, - vsvg->base.key.output_stride); - - - if (vsvg->base.key.clip) { - /* not really handling clipping, just do the rhw so we can - * see the results... - */ - do_rhw_viewport( vsvg, - count, - output_buffer ); - } - else if (vsvg->base.key.viewport) { - do_viewport( vsvg, - count, - output_buffer ); - } + vsvg->base.vs->run_linear( vsvg->base.vs, + temp_buffer, + temp_buffer, + (const float (*)[4])vsvg->base.vs->draw->pt.user.constants, + count, + temp_vertex_stride, + temp_vertex_stride); + + + if (vsvg->base.key.clip) { + /* not really handling clipping, just do the rhw so we can + * see the results... + */ + do_rhw_viewport( vsvg, + count, + temp_buffer ); + } + else if (vsvg->base.key.viewport) { + do_viewport( vsvg, + count, + temp_buffer ); + } - //if (!vsvg->already_in_emit_format) + vsvg->emit->set_buffer( vsvg->emit, + 0, + temp_buffer, + temp_vertex_stride ); - vsvg->emit->set_buffer( vsvg->emit, - 0, - output_buffer, - vsvg->base.key.output_stride ); + vsvg->emit->set_buffer( vsvg->emit, + 1, + &vsvg->draw->rasterizer->point_size, + 0); + vsvg->emit->run( vsvg->emit, + 0, count, + output_buffer ); - vsvg->emit->run( vsvg->emit, - 0, count, - output_buffer ); - } + FREE(temp_buffer); } @@ -182,54 +187,55 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, void *output_buffer ) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; + unsigned temp_vertex_stride = vsvg->temp_vertex_stride; + void *temp_buffer = MALLOC( align(count,4) * temp_vertex_stride ); - if (0) debug_printf("%s %d %d\n", __FUNCTION__, start, count); - - + if (0) debug_printf("%s %d %d (sz %d, %d)\n", __FUNCTION__, start, count, + vsvg->base.key.output_stride, + temp_vertex_stride); + vsvg->fetch->run( vsvg->fetch, start, count, - output_buffer ); - - //if (!vsvg->base.vs->is_passthrough) - { - vsvg->base.vs->run_linear( vsvg->base.vs, - output_buffer, - output_buffer, - (const float (*)[4])vsvg->base.vs->draw->pt.user.constants, - count, - vsvg->base.key.output_stride, - vsvg->base.key.output_stride); - - if (vsvg->base.key.clip) { - /* not really handling clipping, just do the rhw so we can - * see the results... - */ - do_rhw_viewport( vsvg, - count, - output_buffer ); - } - else if (vsvg->base.key.viewport) { - do_viewport( vsvg, - count, - output_buffer ); - } - - //if (!vsvg->already_in_emit_format) - vsvg->emit->set_buffer( vsvg->emit, - 0, - output_buffer, - vsvg->base.key.output_stride ); + temp_buffer ); + + vsvg->base.vs->run_linear( vsvg->base.vs, + temp_buffer, + temp_buffer, + (const float (*)[4])vsvg->base.vs->draw->pt.user.constants, + count, + temp_vertex_stride, + temp_vertex_stride); + + if (vsvg->base.key.clip) { + /* not really handling clipping, just do the rhw so we can + * see the results... + */ + do_rhw_viewport( vsvg, + count, + temp_buffer ); + } + else if (vsvg->base.key.viewport) { + do_viewport( vsvg, + count, + temp_buffer ); + } - vsvg->emit->set_buffer( vsvg->emit, - 1, - &vsvg->draw->rasterizer->point_size, - 0); + vsvg->emit->set_buffer( vsvg->emit, + 0, + temp_buffer, + temp_vertex_stride ); + + vsvg->emit->set_buffer( vsvg->emit, + 1, + &vsvg->draw->rasterizer->point_size, + 0); + + vsvg->emit->run( vsvg->emit, + 0, count, + output_buffer ); - vsvg->emit->run( vsvg->emit, - 0, count, - output_buffer ); - } + FREE(temp_buffer); } @@ -261,18 +267,20 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, vsvg->draw = vs->draw; + vsvg->temp_vertex_stride = MAX2(key->nr_inputs, + vsvg->base.vs->info.num_outputs) * 4 * sizeof(float); /* Build free-standing fetch and emit functions: */ fetch.nr_elements = key->nr_inputs; - fetch.output_stride = 0; + fetch.output_stride = vsvg->temp_vertex_stride; for (i = 0; i < key->nr_inputs; i++) { fetch.element[i].input_format = key->element[i].in.format; fetch.element[i].input_buffer = key->element[i].in.buffer; fetch.element[i].input_offset = key->element[i].in.offset; fetch.element[i].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fetch.element[i].output_offset = fetch.output_stride; - fetch.output_stride += 4 * sizeof(float); + fetch.element[i].output_offset = i * 4 * sizeof(float); + assert(fetch.element[i].output_offset < fetch.output_stride); } @@ -286,6 +294,7 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, emit.element[i].input_offset = key->element[i].out.vs_output * 4 * sizeof(float); emit.element[i].output_format = draw_translate_vinfo_format(key->element[i].out.format); emit.element[i].output_offset = key->element[i].out.offset; + assert(emit.element[i].input_offset < fetch.output_stride); } else { emit.element[i].input_format = PIPE_FORMAT_R32_FLOAT; -- cgit v1.2.3 From f0fdf0c23a16b9e0338eb945c6f88c7a57a9fbd0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 6 Jun 2008 12:33:53 -0600 Subject: gallium: additional comment --- src/gallium/winsys/xlib/Makefile | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index c443330942..ec92c79068 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -1,5 +1,9 @@ # src/gallium/winsys/xlib/Makefile +# This makefile produces a "stand-alone" libGL.so which is based on +# Xlib (no DRI HW acceleration) + + TOP = ../../../.. include $(TOP)/configs/current -- cgit v1.2.3 From ab102d5a9f1db0f76eabbf22cd05b08ff7bb8448 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 6 Jun 2008 15:42:08 -0600 Subject: egl: clean-ups --- src/gallium/winsys/egl_xlib/Makefile | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile index fe4b931e30..46666650b0 100644 --- a/src/gallium/winsys/egl_xlib/Makefile +++ b/src/gallium/winsys/egl_xlib/Makefile @@ -7,7 +7,7 @@ TOP = ../../../.. include $(TOP)/configs/current -LIBNAME = softpipe_egl.so +DRIVER_NAME = softpipe_egl.so INCLUDE_DIRS = \ @@ -36,30 +36,28 @@ LIBS = \ LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1 -.SUFFIXES : .cpp - .c.o: $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@ -.cpp.o: - $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $(LOCAL_CFLAGS) $< -o $@ + +.PHONY: library +default: depend library Makefile -default: $(TOP)/$(LIB_DIR)/$(LIBNAME) + +library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) # Make the softpipe_egl.so library -$(TOP)/$(LIB_DIR)/$(LIBNAME): $(WINSYS_OBJECTS) $(LIBS) - $(TOP)/bin/mklib -o $(LIBNAME) \ +$(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(WINSYS_OBJECTS) $(LIBS) + $(TOP)/bin/mklib -o $(DRIVER_NAME) \ -linker "$(CC)" \ -noprefix \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) \ --start-group $(LIBS) --end-group -# $(GL_LIB_DEPS) - depend: $(ALL_SOURCES) @ echo "running $(MKDEP)" @@ -72,7 +70,7 @@ depend: $(ALL_SOURCES) install: default $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) @if [ -e $(TOP)/$(LIB_DIR) ]; then \ - $(INSTALL) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(INSTALL_DIR)/$(LIB_DIR); \ + $(INSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(INSTALL_DIR)/$(LIB_DIR); \ fi -- cgit v1.2.3 From a47c222803483c208f720e3fb5015050d4d0eaf4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 7 Jun 2008 13:27:53 +0100 Subject: draw: fix temp vs output buffer typo in vsvg_run_elts --- src/gallium/auxiliary/draw/draw_vs_varient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index d8317d3bbe..abe8c5ec2d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -137,7 +137,7 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, vsvg->fetch->run_elts( vsvg->fetch, elts, count, - output_buffer ); + temp_buffer ); vsvg->base.vs->run_linear( vsvg->base.vs, temp_buffer, -- cgit v1.2.3 From cfc23bc54c8cae2615d447bc199ff87ef7e9298e Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 9 Jun 2008 16:17:35 +0200 Subject: i915: Disable color buffer writes if no color buffer is attached --- src/gallium/drivers/i915simple/i915_state_immediate.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state_immediate.c b/src/gallium/drivers/i915simple/i915_state_immediate.c index 704ea4d838..2501f2d7cb 100644 --- a/src/gallium/drivers/i915simple/i915_state_immediate.c +++ b/src/gallium/drivers/i915simple/i915_state_immediate.c @@ -156,8 +156,12 @@ const struct i915_tracked_state i915_upload_S5 = { */ static void upload_S6( struct i915_context *i915 ) { - unsigned LIS6 = (S6_COLOR_WRITE_ENABLE | - (2 << S6_TRISTRIP_PV_SHIFT)); + unsigned LIS6 = (2 << S6_TRISTRIP_PV_SHIFT); + + /* I915_NEW_FRAMEBUFFER + */ + if (i915->framebuffer.cbufs[0]) + LIS6 |= S6_COLOR_WRITE_ENABLE; /* I915_NEW_BLEND */ @@ -174,7 +178,7 @@ static void upload_S6( struct i915_context *i915 ) } const struct i915_tracked_state i915_upload_S6 = { - I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL, + I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL | I915_NEW_FRAMEBUFFER, upload_S6 }; -- cgit v1.2.3 From 1c316f1e824b094977059145a1abcdb50a391f1c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 9 Jun 2008 09:27:52 -0600 Subject: gallium: disable a tgsi_dump() call --- src/gallium/auxiliary/draw/draw_vs_aos.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 45f36cff2a..458bbbe376 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -2066,7 +2066,9 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, if (!vaos->attrib) goto fail; +#if 0 tgsi_dump(vs->state.tokens, 0); +#endif if (!build_vertex_program( vaos, TRUE )) goto fail; -- cgit v1.2.3 From 6420a62cf0f5812708a4c649691ba62c573eaced Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 9 Jun 2008 12:26:20 -0600 Subject: egl: s/softpipe_egl.so/egl_softpipe.so/ --- src/gallium/winsys/egl_xlib/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile index 46666650b0..d5595b819a 100644 --- a/src/gallium/winsys/egl_xlib/Makefile +++ b/src/gallium/winsys/egl_xlib/Makefile @@ -1,13 +1,13 @@ # src/gallium/winsys/egl_xlib/Makefile -# Build softpipe/xlib/EGL driver library/object: "softpipe_egl.so" +# Build softpipe/xlib/EGL driver library/object: "egl_softpipe.so" TOP = ../../../.. include $(TOP)/configs/current -DRIVER_NAME = softpipe_egl.so +DRIVER_NAME = egl_softpipe.so INCLUDE_DIRS = \ @@ -49,7 +49,7 @@ default: depend library Makefile library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) -# Make the softpipe_egl.so library +# Make the egl_softpipe.so library $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(WINSYS_OBJECTS) $(LIBS) $(TOP)/bin/mklib -o $(DRIVER_NAME) \ -linker "$(CC)" \ -- cgit v1.2.3 From a70684bf256c3d5bc3a729bf9e9cf1a64cb2064a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 10 Jun 2008 08:32:52 +0900 Subject: gallium: Deprecate GETENV. Replace by debug_get_bool_option. debug_get_bool_option will interpret "n", "no", "0", "f", or "false" as FALSE; and everything else as TRUE. The default value (used when the variable is not set) is received as a parameter. --- src/gallium/auxiliary/draw/draw_pt.c | 4 ++-- src/gallium/drivers/i915simple/i915_context.c | 2 +- src/gallium/drivers/softpipe/sp_context.c | 4 ++-- src/gallium/include/pipe/p_util.h | 2 -- 4 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index f0d7b51ad7..9140faeea9 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -119,8 +119,8 @@ draw_pt_arrays(struct draw_context *draw, boolean draw_pt_init( struct draw_context *draw ) { - draw->pt.test_fse = GETENV("DRAW_FSE") != NULL; - draw->pt.no_fse = GETENV("DRAW_NO_FSE") != NULL; + draw->pt.test_fse = debug_get_bool_option("DRAW_FSE", FALSE); + draw->pt.no_fse = debug_get_bool_option("DRAW_NO_FSE", FALSE); draw->pt.front.vcache = draw_pt_vcache( draw ); if (!draw->pt.front.vcache) diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 243b4a6852..4c01b8d5b1 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -161,7 +161,7 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen, */ i915->draw = draw_create(); assert(i915->draw); - if (!GETENV("I915_NO_VBUF")) { + if (!debug_get_bool_option("I915_NO_VBUF", FALSE)) { draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915)); } else { diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 1e0106b86c..6e14f684f1 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -129,12 +129,12 @@ softpipe_create( struct pipe_screen *screen, uint i; #ifdef PIPE_ARCH_X86 - softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; + softpipe->use_sse = !debug_get_bool_option( "GALLIUM_NOSSE", FALSE ); #else softpipe->use_sse = FALSE; #endif - softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL; + softpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE ); softpipe->pipe.winsys = pipe_winsys; softpipe->pipe.screen = screen; diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 5547e57833..8b3003bcef 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -140,8 +140,6 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define CALLOC_STRUCT(T) (struct T *) CALLOC(1, sizeof(struct T)) -#define GETENV( X ) debug_get_option( X, NULL ) - /** * Return memory on given byte alignment -- cgit v1.2.3 From 4b52f4df1b37918a363d05e0b3db22125e801367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 9 Jun 2008 18:49:13 +0900 Subject: pipebuffer: Be more lenient when matching cached buffer sizes. Reuse cached buffers up to twice as big a requested. --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 4bd3f94a6c..f1a457dde4 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -207,8 +207,11 @@ pb_cache_is_buffer_compat(struct pb_cache_buffer *buf, size_t size, const struct pb_desc *desc) { - /* TODO: be more lenient with size */ - if(buf->base.base.size != size) + if(buf->base.base.size < size) + return FALSE; + + /* be lenient with size */ + if(buf->base.base.size >= 2*size) return FALSE; if(!pb_check_alignment(desc->alignment, buf->base.base.alignment)) -- cgit v1.2.3 From 0c5b1a8ffb21f72fcde64a7daa13d5dab5b90425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 10 Jun 2008 08:38:24 +0900 Subject: pipebuffer: Alternative buffer manager. For situations where one has a reserve memory pool, or a faster/slower pool. --- src/gallium/auxiliary/pipebuffer/Makefile | 1 + src/gallium/auxiliary/pipebuffer/SConscript | 1 + src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 5 ++ src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c | 101 +++++++++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile index ff09011b66..1d9b036c07 100644 --- a/src/gallium/auxiliary/pipebuffer/Makefile +++ b/src/gallium/auxiliary/pipebuffer/Makefile @@ -6,6 +6,7 @@ LIBNAME = pipebuffer C_SOURCES = \ pb_buffer_fenced.c \ pb_buffer_malloc.c \ + pb_bufmgr_alt.c \ pb_bufmgr_cache.c \ pb_bufmgr_fenced.c \ pb_bufmgr_mm.c \ diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript index 9db0c0eae3..e52177bc79 100644 --- a/src/gallium/auxiliary/pipebuffer/SConscript +++ b/src/gallium/auxiliary/pipebuffer/SConscript @@ -5,6 +5,7 @@ pipebuffer = env.ConvenienceLibrary( source = [ 'pb_buffer_fenced.c', 'pb_buffer_malloc.c', + 'pb_bufmgr_alt.c', 'pb_bufmgr_cache.c', 'pb_bufmgr_fenced.c', 'pb_bufmgr_mm.c', diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 4a922d16c1..00279f7010 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -171,6 +171,11 @@ fenced_bufmgr_create(struct pb_manager *provider, struct pipe_winsys *winsys); +struct pb_manager * +pb_alt_manager_create(struct pb_manager *provider1, + struct pb_manager *provider2); + + #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c new file mode 100644 index 0000000000..702bef1c04 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c @@ -0,0 +1,101 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Allocate buffers from two alternative buffer providers. + * + * \author Jose Fonseca + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" + +#include "pb_buffer.h" +#include "pb_bufmgr.h" + + +struct pb_alt_manager +{ + struct pb_manager base; + + struct pb_manager *provider1; + struct pb_manager *provider2; +}; + + +static INLINE struct pb_alt_manager * +pb_alt_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct pb_alt_manager *)mgr; +} + + +static struct pb_buffer * +pb_alt_manager_create_buffer(struct pb_manager *_mgr, + size_t size, + const struct pb_desc *desc) +{ + struct pb_alt_manager *mgr = pb_alt_manager(_mgr); + struct pb_buffer *buf; + + buf = mgr->provider1->create_buffer(mgr->provider1, size, desc); + if(buf) + return buf; + + buf = mgr->provider2->create_buffer(mgr->provider2, size, desc); + return buf; +} + + +static void +pb_alt_manager_destroy(struct pb_manager *mgr) +{ + FREE(mgr); +} + + +struct pb_manager * +pb_alt_manager_create(struct pb_manager *provider1, + struct pb_manager *provider2) +{ + struct pb_alt_manager *mgr; + + mgr = CALLOC_STRUCT(pb_alt_manager); + if (!mgr) + return NULL; + + mgr->base.destroy = pb_alt_manager_destroy; + mgr->base.create_buffer = pb_alt_manager_create_buffer; + mgr->provider1 = provider1; + mgr->provider2 = provider2; + + return &mgr->base; +} -- cgit v1.2.3 From 3531c5284bb8dc772cd97c6be5bf589c160f9ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 9 Jun 2008 19:56:52 +0900 Subject: gallium: Detect buffer overflows in the homegrown memory debugger. --- src/gallium/auxiliary/util/p_debug_mem.c | 49 ++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c index 78497c5f6a..51dbd0a710 100644 --- a/src/gallium/auxiliary/util/p_debug_mem.c +++ b/src/gallium/auxiliary/util/p_debug_mem.c @@ -75,6 +75,12 @@ struct debug_memory_header unsigned magic; }; +struct debug_memory_footer +{ + unsigned magic; +}; + + static struct list_head list = { &list, &list }; static unsigned long last_no = 0; @@ -98,14 +104,24 @@ data_from_header(struct debug_memory_header *hdr) return NULL; } +static INLINE struct debug_memory_footer * +footer_from_header(struct debug_memory_header *hdr) +{ + if(hdr) + return (struct debug_memory_footer *)((char *)hdr + sizeof(struct debug_memory_header) + hdr->size); + else + return NULL; +} + void * debug_malloc(const char *file, unsigned line, const char *function, size_t size) { struct debug_memory_header *hdr; + struct debug_memory_footer *ftr; - hdr = real_malloc(sizeof(*hdr) + size); + hdr = real_malloc(sizeof(*hdr) + size + sizeof(*ftr)); if(!hdr) return NULL; @@ -116,6 +132,9 @@ debug_malloc(const char *file, unsigned line, const char *function, hdr->size = size; hdr->magic = DEBUG_MEMORY_MAGIC; + ftr = footer_from_header(hdr); + ftr->magic = DEBUG_MEMORY_MAGIC; + LIST_ADDTAIL(&hdr->head, &list); return data_from_header(hdr); @@ -126,6 +145,7 @@ debug_free(const char *file, unsigned line, const char *function, void *ptr) { struct debug_memory_header *hdr; + struct debug_memory_footer *ftr; if(!ptr) return; @@ -139,8 +159,17 @@ debug_free(const char *file, unsigned line, const char *function, return; } + ftr = footer_from_header(hdr); + if(ftr->magic != DEBUG_MEMORY_MAGIC) { + debug_printf("%s:%u:%s: buffer overflow %p\n", + hdr->file, hdr->line, hdr->function, + ptr); + debug_assert(0); + } + LIST_DEL(&hdr->head); hdr->magic = 0; + ftr->magic = 0; real_free(hdr); } @@ -160,6 +189,7 @@ debug_realloc(const char *file, unsigned line, const char *function, void *old_ptr, size_t old_size, size_t new_size ) { struct debug_memory_header *old_hdr, *new_hdr; + struct debug_memory_footer *old_ftr, *new_ftr; void *new_ptr; if(!old_ptr) @@ -179,8 +209,16 @@ debug_realloc(const char *file, unsigned line, const char *function, return NULL; } + old_ftr = footer_from_header(old_hdr); + if(old_ftr->magic != DEBUG_MEMORY_MAGIC) { + debug_printf("%s:%u:%s: buffer overflow %p\n", + old_hdr->file, old_hdr->line, old_hdr->function, + old_ptr); + debug_assert(0); + } + /* alloc new */ - new_hdr = real_malloc(sizeof(*new_hdr) + new_size); + new_hdr = real_malloc(sizeof(*new_hdr) + new_size + sizeof(*new_ftr)); if(!new_hdr) return NULL; new_hdr->no = old_hdr->no; @@ -189,14 +227,19 @@ debug_realloc(const char *file, unsigned line, const char *function, new_hdr->function = old_hdr->function; new_hdr->size = new_size; new_hdr->magic = DEBUG_MEMORY_MAGIC; - LIST_REPLACE(&old_hdr->head, &new_hdr->head); + new_ftr = footer_from_header(new_hdr); + new_ftr->magic = DEBUG_MEMORY_MAGIC; + + LIST_REPLACE(&old_hdr->head, &new_hdr->head); + /* copy data */ new_ptr = data_from_header(new_hdr); memcpy( new_ptr, old_ptr, old_size < new_size ? old_size : new_size ); /* free old */ old_hdr->magic = 0; + old_ftr->magic = 0; real_free(old_hdr); return new_ptr; -- cgit v1.2.3 From 7d3bab537c7559df7bdc7a4fae42f8218185b9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 10 Jun 2008 08:52:10 +0900 Subject: softpipe: Replace GETENV by debug_get_bool_option. --- src/gallium/drivers/softpipe/sp_context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 6e14f684f1..626c3a9d4e 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -225,10 +225,10 @@ softpipe_create( struct pipe_screen *screen, if (!softpipe->setup) goto fail; - if (GETENV( "SP_NO_RAST" ) != NULL) + if (debug_get_bool_option( "SP_NO_RAST", FALSE )) softpipe->no_rast = TRUE; - if (GETENV( "SP_NO_VBUF" ) != NULL) { + if (debug_get_bool_option( "SP_NO_VBUF", FALSE )) { /* Deprecated path -- vbuf is the intended interface to the draw module: */ draw_set_rasterize_stage(softpipe->draw, softpipe->setup); -- cgit v1.2.3 From 061e1c6c57703a92ac17b553f592c0c6114cb227 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 10 Jun 2008 09:16:34 +0100 Subject: draw: rework splitting of fan/loop prims in varray.c, fix flatshade issues --- src/gallium/auxiliary/draw/draw_pt_varray.c | 138 ++++++++------------- .../auxiliary/draw/draw_pt_varray_tmp_linear.h | 54 ++++---- 2 files changed, 76 insertions(+), 116 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index f5495a80c7..4479963db1 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -31,7 +31,7 @@ #include "draw/draw_pt.h" #define FETCH_MAX 256 -#define DRAW_MAX (16*FETCH_MAX) +#define DRAW_MAX (FETCH_MAX+8) struct varray_frontend { struct draw_pt_front_end base; @@ -40,11 +40,6 @@ struct varray_frontend { ushort draw_elts[DRAW_MAX]; unsigned fetch_elts[FETCH_MAX]; - unsigned draw_count; - unsigned fetch_count; - - unsigned fetch_start; - unsigned driver_fetch_max; unsigned fetch_max; @@ -54,121 +49,86 @@ struct varray_frontend { unsigned output_prim; }; -static void varray_flush(struct varray_frontend *varray) -{ - if (varray->draw_count) { -#if 0 - debug_printf("FLUSH fc = %d, dc = %d\n", - varray->fetch_count, - varray->draw_count); - debug_printf("\telt0 = %d, eltx = %d, draw0 = %d, drawx = %d\n", - varray->fetch_elts[0], - varray->fetch_elts[varray->fetch_count-1], - varray->draw_elts[0], - varray->draw_elts[varray->draw_count-1]); -#endif - varray->middle->run(varray->middle, - varray->fetch_elts, - varray->fetch_count, - varray->draw_elts, - varray->draw_count); - } - - varray->fetch_count = 0; - varray->draw_count = 0; -} static void varray_flush_linear(struct varray_frontend *varray, unsigned start, unsigned count) { if (count) { -#if 0 - debug_printf("FLUSH LINEAR start = %d, count = %d\n", - start, - count); -#endif assert(varray->middle->run_linear); varray->middle->run_linear(varray->middle, start, count); } } -static INLINE void fetch_init(struct varray_frontend *varray, - unsigned count) +static void varray_line_loop_segment(struct varray_frontend *varray, + unsigned start, + unsigned segment_start, + unsigned segment_count, + boolean end ) { - unsigned idx; -#if 0 - debug_printf("FETCH INIT c = %d, fs = %d\n", - count, - varray->fetch_start); -#endif - for (idx = 0; idx < count; ++idx) { - varray->fetch_elts[idx] = varray->fetch_start + idx; - } - varray->fetch_start += idx; - varray->fetch_count = idx; -} + assert(segment_count+1 < varray->fetch_max); + if (segment_count >= 1) { + unsigned nr = 0, i; + for (i = 0; i < segment_count; i++) + varray->fetch_elts[nr++] = start + segment_start + i; + if (end) + varray->fetch_elts[nr++] = start; + assert(nr < FETCH_MAX); -static INLINE void add_draw_el(struct varray_frontend *varray, - unsigned idx) -{ - varray->draw_elts[varray->draw_count++] = (ushort)idx; + varray->middle->run(varray->middle, + varray->fetch_elts, + nr, + varray->draw_elts, /* ie. linear */ + nr); + } } -static INLINE void varray_triangle( struct varray_frontend *varray, - unsigned i0, - unsigned i1, - unsigned i2 ) -{ - add_draw_el(varray, i0); - add_draw_el(varray, i1); - add_draw_el(varray, i2); -} -static INLINE void varray_line( struct varray_frontend *varray, - unsigned i0, - unsigned i1 ) +static void varray_fan_segment(struct varray_frontend *varray, + unsigned start, + unsigned segment_start, + unsigned segment_count ) { - add_draw_el(varray, i0); - add_draw_el(varray, i1); -} + assert(segment_count+1 < varray->fetch_max); + if (segment_count >= 2) { + unsigned nr = 0, i; + if (segment_start != 0) + varray->fetch_elts[nr++] = start; -static INLINE void varray_point( struct varray_frontend *varray, - unsigned i0 ) -{ - add_draw_el(varray, i0); + for (i = 0 ; i < segment_count; i++) + varray->fetch_elts[nr++] = start + segment_start + i; + + assert(nr < FETCH_MAX); + + varray->middle->run(varray->middle, + varray->fetch_elts, + nr, + varray->draw_elts, /* ie. linear */ + nr); + } } -#if 0 -#define TRIANGLE(flags,i0,i1,i2) varray_triangle(varray,i0,i1,i2) -#define LINE(flags,i0,i1) varray_line(varray,i0,i1) -#define POINT(i0) varray_point(varray,i0) -#define FUNC varray_decompose -#include "draw_pt_decompose.h" -#else -#define TRIANGLE(vc,i0,i1,i2) varray_triangle(vc,i0,i1,i2) -#define LINE(vc,i0,i1) varray_line(vc,i0,i1) -#define POINT(vc,i0) varray_point(vc,i0) + + #define FUNC varray_run #include "draw_pt_varray_tmp_linear.h" -#endif static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = { PIPE_PRIM_POINTS, PIPE_PRIM_LINES, - PIPE_PRIM_LINES, /* decomposed LINELOOP */ + PIPE_PRIM_LINE_STRIP, /* decomposed LINELOOP */ PIPE_PRIM_LINE_STRIP, PIPE_PRIM_TRIANGLES, PIPE_PRIM_TRIANGLE_STRIP, - PIPE_PRIM_TRIANGLES, /* decomposed TRI_FAN */ + PIPE_PRIM_TRIANGLE_FAN, PIPE_PRIM_QUADS, PIPE_PRIM_QUAD_STRIP, - PIPE_PRIM_TRIANGLES /* decomposed POLYGON */ + PIPE_PRIM_POLYGON }; @@ -186,7 +146,8 @@ static void varray_prepare(struct draw_pt_front_end *frontend, varray->output_prim = decompose_prim[prim]; varray->middle = middle; - middle->prepare(middle, varray->output_prim, opt, &varray->fetch_max ); + middle->prepare(middle, varray->output_prim, opt, &varray->driver_fetch_max ); + varray->fetch_max = MIN2(FETCH_MAX, varray->driver_fetch_max); } @@ -207,6 +168,7 @@ static void varray_destroy(struct draw_pt_front_end *frontend) struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw) { + unsigned i; struct varray_frontend *varray = CALLOC_STRUCT(varray_frontend); if (varray == NULL) return NULL; @@ -217,5 +179,9 @@ struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw) varray->base.destroy = varray_destroy; varray->draw = draw; + for (i = 0; i < DRAW_MAX; i++) { + varray->draw_elts[i] = i; + } + return &varray->base; } diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h index 6e5e30f38e..55a8e6521d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h @@ -11,11 +11,9 @@ static void FUNC(struct draw_pt_front_end *frontend, struct varray_frontend *varray = (struct varray_frontend *)frontend; unsigned start = (unsigned)elts; - unsigned i, j; + unsigned j; unsigned first, incr; - varray->fetch_start = start; - draw_pt_split_prim(varray->input_prim, &first, &incr); /* Sanitize primitive length: @@ -40,7 +38,7 @@ static void FUNC(struct draw_pt_front_end *frontend, case PIPE_PRIM_QUAD_STRIP: for (j = 0; j < count;) { unsigned remaining = count - j; - unsigned nr = trim( MIN2(varray->fetch_max, remaining), first, incr ); + unsigned nr = trim( MIN2(varray->driver_fetch_max, remaining), first, incr ); varray_flush_linear(varray, start + j, nr); j += nr; if (nr != remaining) @@ -49,45 +47,41 @@ static void FUNC(struct draw_pt_front_end *frontend, break; case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - unsigned fetch_max = MIN2(FETCH_MAX, varray->fetch_max); - for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(fetch_max, count - j); - end -= (end % incr); - for (i = 1; i < end; i++) { - LINE(varray, i - 1, i); - } - LINE(varray, i - 1, 0); - i = end; - fetch_init(varray, end); - varray_flush(varray); - } + /* Always have to decompose as we've stated that this will be + * emitted as a line-strip. + */ + for (j = 0; j < count;) { + unsigned remaining = count - j; + unsigned nr = trim( MIN2(varray->fetch_max-1, remaining), first, incr ); + varray_line_loop_segment(varray, start, j, nr, nr == remaining); + j += nr; + if (nr != remaining) + j -= (first - incr); } break; case PIPE_PRIM_POLYGON: - case PIPE_PRIM_TRIANGLE_FAN: { - unsigned fetch_max = MIN2(FETCH_MAX, varray->fetch_max); - for (j = 0; j + first <= count; j += i) { - unsigned end = MIN2(fetch_max, count - j); - end -= (end % incr); - for (i = 2; i < end; i++) { - TRIANGLE(varray, 0, i - 1, i); + case PIPE_PRIM_TRIANGLE_FAN: + if (count < varray->driver_fetch_max) { + varray_flush_linear(varray, start, count); + } + else { + for ( j = 0; j < count;) { + unsigned remaining = count - j; + unsigned nr = trim( MIN2(varray->fetch_max-1, remaining), first, incr ); + varray_fan_segment(varray, start, j, nr); + j += nr; + if (nr != remaining) + j -= (first - incr); } - i = end; - fetch_init(varray, end); - varray_flush(varray); } break; - } default: assert(0); break; } - - varray_flush(varray); } #undef TRIANGLE -- cgit v1.2.3 From 14a13e3767f080a48a4ae01f803dd0bc8754f441 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 10 Jun 2008 14:45:34 +0100 Subject: draw: fix edgeflags on clipped poly emit --- src/gallium/auxiliary/draw/draw_pipe_clip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index c11ed934a4..77ccddac4a 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -171,7 +171,7 @@ static void emit_poly( struct draw_stage *stage, header.flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; header.pad = 0; - for (i = 2; i < n; i++, header.flags = 0) { + for (i = 2; i < n; i++, header.flags = edge_middle) { header.v[0] = inlist[i-1]; header.v[1] = inlist[i]; header.v[2] = inlist[0]; /* keep in v[2] for flatshading */ -- cgit v1.2.3 From ad44e68706877ab06929747e7a82c718c1c27e02 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 10 Jun 2008 14:46:25 +0100 Subject: draw: no need to rearrange most primitives in vcache for flatshade-first The driver/pipeline will still be applying flatshade-first state to the triangles emitted from vcache, so there's no need to rotate the vertices of most primitives. The only exception is POLYGON, as explained in the code. --- src/gallium/auxiliary/draw/draw_pt_fetch.c | 5 +- src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h | 123 +++++++++++++----------- 2 files changed, 72 insertions(+), 56 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 07f4c99164..b8fd3aa1d8 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -114,7 +114,10 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, fetch->translate = translate_cache_find(fetch->cache, &key); { - static struct vertex_header vh = { 0, 1, 0, 0xffff }; + static struct vertex_header vh = { 0, + 1, /* edgeflag */ + 0, + 0xffff }; fetch->translate->set_buffer(fetch->translate, draw->pt.nr_vertex_buffers, &vh, diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h index ec05bbeab4..f2334a84f6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h @@ -7,15 +7,18 @@ static void FUNC( struct draw_pt_front_end *frontend, { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; struct draw_context *draw = vcache->draw; - - boolean flatfirst = (draw->rasterizer->flatshade && - draw->rasterizer->flatshade_first); unsigned i; ushort flags; if (0) debug_printf("%s %d\n", __FUNCTION__, count); - + /* Note that no adjustment is made here for flatshade provoking + * vertex. This was previously the case, but was incorrect as the + * same logic would be applied twice both here & in the pipeline + * code or driver. The rule is now that we just preserve the + * original order in this code, and leave identification of the PV + * to the pipeline and driver. + */ switch (vcache->input_prim) { case PIPE_PRIM_POINTS: for (i = 0; i < count; i ++) { @@ -72,45 +75,23 @@ static void FUNC( struct draw_pt_front_end *frontend, break; case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 0), - get_elt(elts, i + 1 + (i&1)), - get_elt(elts, i + 2 - (i&1))); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 0 + (i&1)), - get_elt(elts, i + 1 - (i&1)), - get_elt(elts, i + 2 )); - } + for (i = 0; i+2 < count; i++) { + TRIANGLE( vcache, + DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + get_elt(elts, i + 0 + (i&1)), + get_elt(elts, i + 1 - (i&1)), + get_elt(elts, i + 2 )); } break; case PIPE_PRIM_TRIANGLE_FAN: if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, 0 )); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2 )); - } + for (i = 0; i+2 < count; i++) { + TRIANGLE( vcache, + DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0 )); } } break; @@ -138,26 +119,58 @@ static void FUNC( struct draw_pt_front_end *frontend, case PIPE_PRIM_POLYGON: { + boolean flatfirst = (draw->rasterizer->flatshade && + draw->rasterizer->flatshade_first); + /* These bitflags look a little odd because we submit the * vertices as (1,2,0) to satisfy flatshade requirements. + * + * Polygon is defined has having vertex 0 be the provoking + * flatshade vertex and all known API's match this usage. + * However, the PV's for the triangles we emit from this + * decomposition vary according to the API, and hence we have + * to choose between two ways of emitting the triangles. */ - const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; - const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; - - flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; - - for (i = 0; i+2 < count; i++, flags = edge_middle) { - - if (i + 3 == count) - flags |= edge_last; - - TRIANGLE( vcache, - flags, - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, 0)); - } + if (flatfirst) { + const ushort edge_first = DRAW_PIPE_EDGE_FLAG_0; + const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_1; + const ushort edge_last = DRAW_PIPE_EDGE_FLAG_2; + + flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; + + for (i = 0; i+2 < count; i++, flags = edge_middle) { + + if (i + 3 == count) + flags |= edge_last; + + /* PV is first vertex */ + TRIANGLE( vcache, + flags, + get_elt(elts, 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2)); + } + } + else { + const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; + const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; + const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; + + flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; + + for (i = 0; i+2 < count; i++, flags = edge_middle) { + + if (i + 3 == count) + flags |= edge_last; + + /* PV is third vertex */ + TRIANGLE( vcache, + flags, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0)); + } + } } break; -- cgit v1.2.3 From aa7c21a45b90e6e502c4967f892f1691411d761f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 10 Jun 2008 16:56:32 +0100 Subject: Revert "draw: no need to rearrange most primitives in vcache for flatshade-first" This reverts commit ad44e68706877ab06929747e7a82c718c1c27e02. --- src/gallium/auxiliary/draw/draw_pt_fetch.c | 5 +- src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h | 123 +++++++++++------------- 2 files changed, 56 insertions(+), 72 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index b8fd3aa1d8..07f4c99164 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -114,10 +114,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, fetch->translate = translate_cache_find(fetch->cache, &key); { - static struct vertex_header vh = { 0, - 1, /* edgeflag */ - 0, - 0xffff }; + static struct vertex_header vh = { 0, 1, 0, 0xffff }; fetch->translate->set_buffer(fetch->translate, draw->pt.nr_vertex_buffers, &vh, diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h index f2334a84f6..ec05bbeab4 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h @@ -7,18 +7,15 @@ static void FUNC( struct draw_pt_front_end *frontend, { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; struct draw_context *draw = vcache->draw; + + boolean flatfirst = (draw->rasterizer->flatshade && + draw->rasterizer->flatshade_first); unsigned i; ushort flags; if (0) debug_printf("%s %d\n", __FUNCTION__, count); - /* Note that no adjustment is made here for flatshade provoking - * vertex. This was previously the case, but was incorrect as the - * same logic would be applied twice both here & in the pipeline - * code or driver. The rule is now that we just preserve the - * original order in this code, and leave identification of the PV - * to the pipeline and driver. - */ + switch (vcache->input_prim) { case PIPE_PRIM_POINTS: for (i = 0; i < count; i ++) { @@ -75,23 +72,45 @@ static void FUNC( struct draw_pt_front_end *frontend, break; case PIPE_PRIM_TRIANGLE_STRIP: - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 0 + (i&1)), - get_elt(elts, i + 1 - (i&1)), - get_elt(elts, i + 2 )); + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + TRIANGLE( vcache, + DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + get_elt(elts, i + 0), + get_elt(elts, i + 1 + (i&1)), + get_elt(elts, i + 2 - (i&1))); + } + } + else { + for (i = 0; i+2 < count; i++) { + TRIANGLE( vcache, + DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + get_elt(elts, i + 0 + (i&1)), + get_elt(elts, i + 1 - (i&1)), + get_elt(elts, i + 2 )); + } } break; case PIPE_PRIM_TRIANGLE_FAN: if (count >= 3) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, 0 )); + if (flatfirst) { + for (i = 0; i+2 < count; i++) { + TRIANGLE( vcache, + DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0 )); + } + } + else { + for (i = 0; i+2 < count; i++) { + TRIANGLE( vcache, + DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, + get_elt(elts, 0), + get_elt(elts, i + 1), + get_elt(elts, i + 2 )); + } } } break; @@ -119,58 +138,26 @@ static void FUNC( struct draw_pt_front_end *frontend, case PIPE_PRIM_POLYGON: { - boolean flatfirst = (draw->rasterizer->flatshade && - draw->rasterizer->flatshade_first); - /* These bitflags look a little odd because we submit the * vertices as (1,2,0) to satisfy flatshade requirements. - * - * Polygon is defined has having vertex 0 be the provoking - * flatshade vertex and all known API's match this usage. - * However, the PV's for the triangles we emit from this - * decomposition vary according to the API, and hence we have - * to choose between two ways of emitting the triangles. */ - if (flatfirst) { - const ushort edge_first = DRAW_PIPE_EDGE_FLAG_0; - const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_1; - const ushort edge_last = DRAW_PIPE_EDGE_FLAG_2; - - flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; - - for (i = 0; i+2 < count; i++, flags = edge_middle) { - - if (i + 3 == count) - flags |= edge_last; - - /* PV is first vertex */ - TRIANGLE( vcache, - flags, - get_elt(elts, 0), - get_elt(elts, i + 1), - get_elt(elts, i + 2)); - } - } - else { - const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; - const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; - - flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; - - for (i = 0; i+2 < count; i++, flags = edge_middle) { - - if (i + 3 == count) - flags |= edge_last; - - /* PV is third vertex */ - TRIANGLE( vcache, - flags, - get_elt(elts, i + 1), - get_elt(elts, i + 2), - get_elt(elts, 0)); - } - } + const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; + const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; + const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; + + flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; + + for (i = 0; i+2 < count; i++, flags = edge_middle) { + + if (i + 3 == count) + flags |= edge_last; + + TRIANGLE( vcache, + flags, + get_elt(elts, i + 1), + get_elt(elts, i + 2), + get_elt(elts, 0)); + } } break; -- cgit v1.2.3 From ab399b555c99c46958c421d900109f78901ddc99 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 11 Jun 2008 09:15:54 +0100 Subject: draw: remove debug assert on failover to generic vs varient --- src/gallium/auxiliary/draw/draw_vs_aos.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 458bbbe376..c47647ea72 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -2108,7 +2108,6 @@ struct draw_vs_varient *draw_vs_varient_aos_sse( struct draw_vertex_shader *vs, struct draw_vs_varient *varient = varient_aos_sse( vs, key ); if (varient == NULL) { - assert(0); varient = draw_vs_varient_generic( vs, key ); } -- cgit v1.2.3 From bd9264210097d08073a4ea3619ca25db56245280 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 11 Jun 2008 09:36:00 +0100 Subject: draw: remove another debug assert on failover to generic vs varient --- src/gallium/auxiliary/draw/draw_vs_aos.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index f6f6af2dd9..66944a4e33 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -202,9 +202,8 @@ struct x86_reg aos_get_internal_xmm( struct aos_compilation *cp, #define ERROR(cp, msg) \ do { \ - debug_printf("%s: x86 translation failed: %s\n", __FUNCTION__, msg); \ + if (0) debug_printf("%s: x86 translation failed: %s\n", __FUNCTION__, msg); \ cp->error = 1; \ - assert(0); \ } while (0) -- cgit v1.2.3 From 4566b006f1a6bbdb96871e511e10e16f18bad23e Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 10 Jun 2008 20:17:16 +0100 Subject: Bring in DRI2 changes --- src/gallium/winsys/dri/intel/intel_context.c | 83 ++++- src/gallium/winsys/dri/intel/intel_screen.c | 449 ++++++++++++++++++--------- 2 files changed, 379 insertions(+), 153 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 8284e0edbb..ecc4b0aa53 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -67,7 +67,6 @@ int __intel_debug = 0; #define need_GL_NV_vertex_program #include "extension_helper.h" - /** * Extension strings exported by the intel driver. * @@ -75,7 +74,7 @@ int __intel_debug = 0; * It appears that ARB_texture_env_crossbar has "disappeared" compared to the * old i830-specific driver. */ -const struct dri_extension card_extensions[] = { +static const struct dri_extension card_extensions[] = { {"GL_ARB_multisample", GL_ARB_multisample_functions}, {"GL_ARB_multitexture", NULL}, {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, @@ -86,22 +85,27 @@ const struct dri_extension card_extensions[] = { {"GL_ARB_texture_env_combine", NULL}, {"GL_ARB_texture_env_dot3", NULL}, {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_non_power_of_two", NULL }, {"GL_ARB_texture_rectangle", NULL}, + {"GL_NV_texture_rectangle", NULL}, + {"GL_EXT_texture_rectangle", NULL}, + {"GL_ARB_point_parameters", NULL}, {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_equation_separate", + GL_EXT_blend_equation_separate_functions}, {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_logic_op", NULL}, {"GL_EXT_blend_subtract", NULL}, {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, +#if 1 /* XXX FBO temporary? */ {"GL_EXT_packed_depth_stencil", NULL}, - {"GL_EXT_pixel_buffer_object", NULL}, +#endif {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, {"GL_EXT_stencil_wrap", NULL}, {"GL_EXT_texture_edge_clamp", NULL}, @@ -116,10 +120,67 @@ const struct dri_extension card_extensions[] = { {"GL_NV_blend_square", NULL}, {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, {"GL_NV_vertex_program1_1", NULL}, - {"GL_SGIS_generate_mipmap", NULL }, + { "GL_SGIS_generate_mipmap", NULL }, {NULL, NULL} }; +#if 0 +static const struct dri_extension brw_extensions[] = { + { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions}, + { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions}, + { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions}, + { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, + { "GL_ARB_point_sprite", NULL}, + { "GL_ARB_fragment_shader", NULL }, + { "GL_ARB_draw_buffers", NULL }, + { "GL_ARB_depth_texture", NULL }, + { "GL_ARB_fragment_program", NULL }, + { "GL_ARB_shadow", NULL }, + { "GL_EXT_shadow_funcs", NULL }, + /* ARB extn won't work if not enabled */ + { "GL_SGIX_depth_texture", NULL }, + { "GL_ARB_texture_env_crossbar", NULL }, + { "GL_EXT_texture_sRGB", NULL}, + { NULL, NULL } +}; + +static const struct dri_extension arb_oc_extensions[] = { + {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, + {NULL, NULL} +}; + +static const struct dri_extension ttm_extensions[] = { + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {NULL, NULL} +}; +#endif + +/** + * Initializes potential list of extensions if ctx == NULL, or actually enables + * extensions for a context. + */ +void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging) +{ + /* Disable imaging extension until convolution is working in teximage paths. + */ + enable_imaging = GL_FALSE; + + driInitExtensions(ctx, card_extensions, enable_imaging); + +#if 0 + if (intel == NULL || intel->ttm) + driInitExtensions(ctx, ttm_extensions, GL_FALSE); + + if (intel == NULL || + (IS_965(intel->intelScreen->deviceID) && + intel->intelScreen->drmMinor >= 8)) + driInitExtensions(ctx, arb_oc_extensions, GL_FALSE); + + if (intel == NULL || IS_965(intel->intelScreen->deviceID)) + driInitExtensions(ctx, brw_extensions, GL_FALSE); +#endif +} #ifdef DEBUG @@ -204,10 +265,10 @@ intelCreateContext(const __GLcontextModes * visual, /* * memory pools */ - DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); // ZZZ JB should be per screen and not be done per context havePools = intelCreatePools(sPriv); - DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + DRM_UNLOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); if (!havePools) return GL_FALSE; @@ -215,7 +276,7 @@ intelCreateContext(const __GLcontextModes * visual, /* Dri stuff */ intel->hHWContext = driContextPriv->hHWContext; intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + intel->driHwLock = (drmLock *) & sPriv->lock; fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); intel->iw.irq_seq = -1; @@ -265,7 +326,7 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); - driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); + intelInitExtensions( intel->st->ctx, GL_TRUE ); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 8817a80a5a..23889c80b8 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -60,7 +60,190 @@ static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; extern const struct dri_extension card_extensions[]; +static GLboolean +intel_get_param(__DRIscreenPrivate *psp, int param, int *value) +{ + int ret; + struct drm_i915_getparam gp; + + gp.param = param; + gp.value = value; + + ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drm_i915_getparam: %d\n", ret); + return GL_FALSE; + } + + return GL_TRUE; +} + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +static void +intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, + __DRIDrawableConfigEvent *event) +{ + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + struct intel_region *region = NULL; + struct intel_renderbuffer *rb, *depth_rb, *stencil_rb; + struct intel_context *intel = pcp->driverPrivate; + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + int cpp, pitch; + +#if 0 + cpp = intelScreen->front.cpp; + pitch = ((cpp * dPriv->w + 63) & ~63) / cpp; + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + rb = intel_fb->color_rb[1]; + if (rb) { + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + intel_renderbuffer_set_region(rb, region); + } + + rb = intel_fb->color_rb[2]; + if (rb) { + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + intel_renderbuffer_set_region(rb, region); + } + + depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + if (depth_rb || stencil_rb) + region = intel_region_alloc(intel, cpp, pitch, dPriv->h); + if (depth_rb) + intel_renderbuffer_set_region(depth_rb, region); + if (stencil_rb) + intel_renderbuffer_set_region(stencil_rb, region); + + /* FIXME: Tell the X server about the regions we just allocated and + * attached. */ +#endif + +} + +#define BUFFER_FLAG_TILED 0x0100 + +static void +intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, + __DRIcontextPrivate *pcp, + __DRIBufferAttachEvent *ba) +{ + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + struct intel_renderbuffer *rb; + struct intel_region *region; + struct intel_context *intel = pcp->driverPrivate; + struct pipe_surface *surf; + GLuint tiled; + + switch (ba->buffer.attachment) { + case DRI_DRAWABLE_BUFFER_FRONT_LEFT: + #if 0 + intelScreen->front.width = ba->width; + intelScreen->front.height = ba->height; + intelScreen->front.offset = sarea->front_offset; + #endif + intelScreen->front.pitch = ba->buffer.pitch * ba->buffer.cpp; + #if 0 + intelScreen->front.size = sarea->front_size; + #endif + driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driBOSetReferenced(intelScreen->front.buffer, ba->buffer.handle); + + break; + +#if 0 + case DRI_DRAWABLE_BUFFER_BACK_LEFT: + rb = intel_fb->color_rb[0]; + break; + + case DRI_DRAWABLE_BUFFER_DEPTH: + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + break; + + case DRI_DRAWABLE_BUFFER_STENCIL: + rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + break; +#endif + + case DRI_DRAWABLE_BUFFER_ACCUM: + default: + fprintf(stderr, "unhandled buffer attach event, attacment type %d\n", + ba->buffer.attachment); + return; + } + +#if 0 + /* FIXME: Add this so we can filter out when the X server sends us + * attachment events for the buffers we just allocated. Need to + * get the BO handle for a render buffer. */ + if (intel_renderbuffer_get_region_handle(rb) == ba->buffer.handle) + return; +#endif + +#if 0 + tiled = (ba->buffer.flags & BUFFER_FLAG_TILED) > 0; + + region = intel_region_alloc_for_handle(intel, ba->buffer.cpp, + ba->buffer.pitch / ba->buffer.cpp, + dPriv->h, tiled, + ba->buffer.handle); + + intel_renderbuffer_set_region(rb, region); +#endif +} + +static const __DRItexOffsetExtension intelTexOffsetExtension = { + { __DRI_TEX_OFFSET }, + intelSetTexOffset, +}; + +#if 0 +static const __DRItexBufferExtension intelTexBufferExtension = { + { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, + intelSetTexBuffer, +}; +#endif +static const __DRIextension *intelScreenExtensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + &intelTexOffsetExtension.base, +// &intelTexBufferExtension.base, + NULL +}; static void @@ -177,7 +360,8 @@ intelCreatePools(__DRIscreenPrivate * sPriv) intelScreen->havePools = GL_TRUE; - intelUpdateScreenRotation(sPriv, intelScreen->sarea); + if (intelScreen->sarea) + intelUpdateScreenRotation(sPriv, intelScreen->sarea); return GL_TRUE; } @@ -210,11 +394,6 @@ intelInitDriver(__DRIscreenPrivate * sPriv) struct intel_screen *intelScreen; I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> - getProcAddress("glxEnableExtension")); - void *const psc = sPriv->psc->screenConfigs; - if (sPriv->devPrivSize != sizeof(I830DRIRec)) { fprintf(stderr, "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); @@ -231,28 +410,17 @@ intelInitDriver(__DRIscreenPrivate * sPriv) __driConfigOptions, __driNConfigOptions); sPriv->private = (void *) intelScreen; - intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + - gDRIPriv->sarea_priv_offset); - intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->front.cpp = gDRIPriv->cpp; - intelScreen->drmMinor = sPriv->drmMinor; + gDRIPriv->sarea_priv_offset); - assert(gDRIPriv->bitsPerPixel == 16 || - gDRIPriv->bitsPerPixel == 32); + intelScreen->deviceID = gDRIPriv->deviceID; intelUpdateScreenRotation(sPriv, intelScreen->sarea); if (0) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - if (glx_enable_extension != NULL) { - (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); - (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); - (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); - } + sPriv->extensions = intelScreenExtensions; intel_be_init_device(&intelScreen->base, sPriv->fd); intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; @@ -351,65 +519,19 @@ intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) return 0; } - -static void -intelSetTexOffset(__DRIcontext *pDRICtx, int texname, - unsigned long long offset, int depth, uint pitch) +static __DRIconfig ** +intelFillInModes(__DRIscreenPrivate *psp, + unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) { - abort(); -#if 0 - struct intel_context *intel = (struct intel_context*) - ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; - struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); - struct st_texture_object *stObj = st_texture_object(tObj); - - if (!stObj) - return; - - if (stObj->pt) - st->pipe->texture_release(intel->st->pipe, &stObj->pt); - - stObj->imageOverride = GL_TRUE; - stObj->depthOverride = depth; - stObj->pitchOverride = pitch; - - if (offset) - stObj->textureOffset = offset; -#endif -} - - -static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetMSC = driGetMSC32, - .WaitForMSC = driWaitForMSC32, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = intelCopySubBuffer, - .setTexOffset = intelSetTexOffset, -}; - - -static __GLcontextModes * -intelFillInModes(unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, boolean have_back_buffer) -{ - __GLcontextModes *modes; + __DRIconfig **configs; __GLcontextModes *m; unsigned num_modes; unsigned depth_buffer_factor; unsigned back_buffer_factor; GLenum fb_format; GLenum fb_type; + int i; /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't * support pageflipping at all. @@ -451,100 +573,143 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; } - modes = - (*dri_interface->createContextModes) (num_modes, - sizeof(__GLcontextModes)); - m = modes; - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_DIRECT_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + configs = driCreateConfigs(fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor); + if (configs == NULL) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; } /* Mark the visual as slow if there are "fake" stencil bits. */ - for (m = modes; m != NULL; m = m->next) { + for (i = 0; configs[i]; i++) { + m = &configs[i]->modes; if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { m->visualRating = GLX_SLOW_CONFIG; } } - return modes; + return configs; } - /** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. + * This is the driver specific part of the createNewScreen entry point. + * + * \todo maybe fold this into intelInitDriver * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. + * \return the __GLcontextModes supported by this driver */ -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, - __DRIscreen * psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) +static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp) { - __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 7, 0 }; +#ifdef I915 + static const __DRIversion ddx_expected = { 1, 5, 0 }; +#else + static const __DRIversion ddx_expected = { 1, 6, 0 }; +#endif static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 7, 0 }; - - dri_interface = interface; + static const __DRIversion drm_expected = { 1, 5, 0 }; + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; if (!driCheckDriDdxDrmVersions2("i915", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { + &psp->dri_version, &dri_expected, + &psp->ddx_version, &ddx_expected, + &psp->drm_version, &drm_expected)) { return NULL; } - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - - if (psp != NULL) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes(dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create - * is called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions(NULL, card_extensions, GL_FALSE); + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + intelInitExtensions(NULL, GL_TRUE); + + if (!intelInitDriver(psp)) + return NULL; + + psp->extensions = intelScreenExtensions; + + return (const __DRIconfig **) + intelFillInModes(psp, dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); +} + +/** + * This is the driver specific part of the createNewScreen entry point. + * + * \return the __GLcontextModes supported by this driver + */ +static const +__DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp) +{ + struct intel_screen *intelScreen; + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is + * called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + intelInitExtensions(NULL, GL_TRUE); + + /* Allocate the private area */ + intelScreen = CALLOC_STRUCT(intel_screen); + if (!intelScreen) { + fprintf(stderr, "\nERROR! Allocating private area failed\n"); + return GL_FALSE; } + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); - return (void *) psp; + psp->private = (void *) intelScreen; + + intelScreen->drmMinor = psp->drm_version.minor; + + /* Determine chipset ID? */ + if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID, + &intelScreen->deviceID)) + return GL_FALSE; + + psp->extensions = intelScreenExtensions; + + intel_be_init_device(&intelScreen->base, psp->fd); + intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; + intelScreen->base.base.get_name = intel_get_name; + + return driConcatConfigs(intelFillInModes(psp, 16, 16, 0, 1), + intelFillInModes(psp, 32, 24, 8, 1)); } +const struct __DriverAPIRec driDriverAPI = { + .InitScreen = intelInitScreen, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetDrawableMSC = driDrawableGetMSC32, + .WaitForMSC = driWaitForMSC32, + .CopySubBuffer = intelCopySubBuffer, + + .InitScreen2 = intelInitScreen2, + .HandleDrawableConfig = intelHandleDrawableConfig, + .HandleBufferAttach = intelHandleBufferAttach, +}; -- cgit v1.2.3 From 4dd1917e4be3ae48b436ed333bd2fcd37603d1ed Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 11 Jun 2008 14:51:41 +0100 Subject: small optimization --- src/gallium/auxiliary/util/u_pack_color.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 655e2c8259..06abb34d5a 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -255,20 +255,28 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest) static INLINE uint util_pack_z(enum pipe_format format, double z) { + if (z == 0.0) + return 0; + switch (format) { case PIPE_FORMAT_Z16_UNORM: + if (z == 1.0) + return 0xffff; return (uint) (z * 0xffff); case PIPE_FORMAT_Z32_UNORM: /* special-case to avoid overflow */ if (z == 1.0) return 0xffffffff; - else - return (uint) (z * 0xffffffff); + return (uint) (z * 0xffffffff); case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: + if (z == 1.0) + return 0xffffff; return (uint) (z * 0xffffff); case PIPE_FORMAT_Z24S8_UNORM: case PIPE_FORMAT_Z24X8_UNORM: + if (z == 1.0) + return 0xffffff00; return ((uint) (z * 0xffffff)) << 8; default: debug_print_format("gallium: unhandled format in util_pack_z()", format); -- cgit v1.2.3 From 1bcb817167773d6a148dd4b2cd63777d0f072c08 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 11 Jun 2008 14:52:55 +0100 Subject: Hook gallium i915 up to DRI2 --- src/gallium/winsys/dri/intel/intel_context.c | 9 ++- src/gallium/winsys/dri/intel/intel_lock.c | 7 +- src/gallium/winsys/dri/intel/intel_screen.c | 98 +++--------------------- src/gallium/winsys/dri/intel/intel_screen.h | 4 +- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 3 +- 5 files changed, 26 insertions(+), 95 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index ecc4b0aa53..af44018053 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -28,6 +28,8 @@ #include "i830_dri.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" @@ -36,8 +38,6 @@ #include "i915simple/i915_screen.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" #include "pipe/p_defines.h" #include "pipe/p_context.h" @@ -160,8 +160,9 @@ static const struct dri_extension ttm_extensions[] = { * Initializes potential list of extensions if ctx == NULL, or actually enables * extensions for a context. */ -void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging) +void intelInitExtensions(struct st_context *st, GLboolean enable_imaging) { + GLcontext *ctx = st ? st->ctx : NULL; /* Disable imaging extension until convolution is working in teximage paths. */ enable_imaging = GL_FALSE; @@ -326,7 +327,7 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); - intelInitExtensions( intel->st->ctx, GL_TRUE ); + intelInitExtensions( intel->st, GL_TRUE ); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_lock.c b/src/gallium/winsys/dri/intel/intel_lock.c index 406284c98f..469090c0e1 100644 --- a/src/gallium/winsys/dri/intel/intel_lock.c +++ b/src/gallium/winsys/dri/intel/intel_lock.c @@ -50,6 +50,9 @@ intelContendedLock(struct intel_context *intel, uint flags) DBG(LOCK, "%s - got contended lock\n", __progname); + if (sPriv->dri2.enabled) + return; + /* If the window moved, may need to set a new cliprect now. * * NOTE: This releases and regains the hw lock, so all state @@ -58,8 +61,8 @@ intelContendedLock(struct intel_context *intel, uint flags) if (dPriv) DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); - if (sarea->width != intelScreen->front.width || - sarea->height != intelScreen->front.height) { + if (sarea && (sarea->width != intelScreen->front.width || + sarea->height != intelScreen->front.height)) { intelUpdateScreenRotation(sPriv, sarea); } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 23889c80b8..a36c9407d4 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -110,116 +110,40 @@ intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, __DRIcontextPrivate *pcp, __DRIDrawableConfigEvent *event) { - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - struct intel_region *region = NULL; - struct intel_renderbuffer *rb, *depth_rb, *stencil_rb; - struct intel_context *intel = pcp->driverPrivate; - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - int cpp, pitch; - -#if 0 - cpp = intelScreen->front.cpp; - pitch = ((cpp * dPriv->w + 63) & ~63) / cpp; - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - rb = intel_fb->color_rb[1]; - if (rb) { - region = intel_region_alloc(intel, cpp, pitch, dPriv->h); - intel_renderbuffer_set_region(rb, region); - } - - rb = intel_fb->color_rb[2]; - if (rb) { - region = intel_region_alloc(intel, cpp, pitch, dPriv->h); - intel_renderbuffer_set_region(rb, region); - } - - depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); - stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); - if (depth_rb || stencil_rb) - region = intel_region_alloc(intel, cpp, pitch, dPriv->h); - if (depth_rb) - intel_renderbuffer_set_region(depth_rb, region); - if (stencil_rb) - intel_renderbuffer_set_region(stencil_rb, region); - - /* FIXME: Tell the X server about the regions we just allocated and - * attached. */ -#endif - + (void) dPriv; + (void) pcp; + (void) event; } -#define BUFFER_FLAG_TILED 0x0100 - static void intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, __DRIcontextPrivate *pcp, __DRIBufferAttachEvent *ba) { struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - struct intel_renderbuffer *rb; - struct intel_region *region; - struct intel_context *intel = pcp->driverPrivate; - struct pipe_surface *surf; - GLuint tiled; switch (ba->buffer.attachment) { case DRI_DRAWABLE_BUFFER_FRONT_LEFT: - #if 0 - intelScreen->front.width = ba->width; - intelScreen->front.height = ba->height; - intelScreen->front.offset = sarea->front_offset; - #endif - intelScreen->front.pitch = ba->buffer.pitch * ba->buffer.cpp; - #if 0 - intelScreen->front.size = sarea->front_size; - #endif + intelScreen->front.width = dPriv->w; + intelScreen->front.height = dPriv->h; + intelScreen->front.cpp = ba->buffer.cpp; + intelScreen->front.pitch = ba->buffer.pitch; driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); driBOSetReferenced(intelScreen->front.buffer, ba->buffer.handle); - break; -#if 0 case DRI_DRAWABLE_BUFFER_BACK_LEFT: - rb = intel_fb->color_rb[0]; - break; - case DRI_DRAWABLE_BUFFER_DEPTH: - rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); - break; - case DRI_DRAWABLE_BUFFER_STENCIL: - rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); - break; -#endif - case DRI_DRAWABLE_BUFFER_ACCUM: + /* anything ?? */ + break; + default: - fprintf(stderr, "unhandled buffer attach event, attacment type %d\n", + fprintf(stderr, "unhandled buffer attach event, attachment type %d\n", ba->buffer.attachment); return; } - -#if 0 - /* FIXME: Add this so we can filter out when the X server sends us - * attachment events for the buffers we just allocated. Need to - * get the BO handle for a render buffer. */ - if (intel_renderbuffer_get_region_handle(rb) == ba->buffer.handle) - return; -#endif - -#if 0 - tiled = (ba->buffer.flags & BUFFER_FLAG_TILED) > 0; - - region = intel_region_alloc_for_handle(intel, ba->buffer.cpp, - ba->buffer.pitch / ba->buffer.cpp, - dPriv->h, tiled, - ba->buffer.handle); - - intel_renderbuffer_set_region(rb, region); -#endif } static const __DRItexOffsetExtension intelTexOffsetExtension = { diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index 8036917903..d1389a31fb 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -32,7 +32,7 @@ #include "i830_common.h" #include "xmlconfig.h" #include "intel_drm/ws_dri_bufpool.h" - +#include "state_tracker/st_context.h" #include "pipe/p_compiler.h" #include "intel_drm/intel_be_device.h" @@ -116,5 +116,7 @@ intelCreateContext(const __GLcontextModes * visual, __DRIcontextPrivate * driContextPriv, void *sharedContextPrivate); +extern void +intelInitExtensions(struct st_context *st, GLboolean enable_imaging); #endif diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 7f3babd98e..8b17154cf9 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -78,7 +78,8 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, * current context (which is what intelScreenContext should return) might * not get a contended lock and thus cliprects not updated (tests/manywin) */ - if (intel_context(dPriv->driContextPriv) != intel) + if (!intel->driScreen->dri2.enabled && + intel_context(dPriv->driContextPriv) != intel) DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); -- cgit v1.2.3 From f851ba705ae878f62149afa377c755286cf53c85 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 11 Jun 2008 15:35:12 +0100 Subject: fix legacy DRI --- src/gallium/winsys/dri/intel/intel_screen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index a36c9407d4..e456c28d0d 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -339,6 +339,8 @@ intelInitDriver(__DRIscreenPrivate * sPriv) intelScreen->deviceID = gDRIPriv->deviceID; + intelScreen->front.cpp = gDRIPriv->cpp; + intelScreen->drmMinor = sPriv->drm_version.minor; intelUpdateScreenRotation(sPriv, intelScreen->sarea); if (0) -- cgit v1.2.3 From d45e99060d531d3a3889bb59fb55875bde05811f Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 11 Jun 2008 15:50:07 +0100 Subject: fix card_extensions --- src/gallium/winsys/dri/intel/intel_context.c | 17 +++++------------ src/gallium/winsys/dri/intel/intel_screen.h | 2 +- 2 files changed, 6 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index af44018053..9d78e9ebf8 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -141,6 +141,8 @@ static const struct dri_extension brw_extensions[] = { { "GL_SGIX_depth_texture", NULL }, { "GL_ARB_texture_env_crossbar", NULL }, { "GL_EXT_texture_sRGB", NULL}, + { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + { "GL_ARB_pixel_buffer_object", NULL}, { NULL, NULL } }; @@ -148,21 +150,15 @@ static const struct dri_extension arb_oc_extensions[] = { {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, {NULL, NULL} }; - -static const struct dri_extension ttm_extensions[] = { - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, - {NULL, NULL} -}; #endif /** * Initializes potential list of extensions if ctx == NULL, or actually enables * extensions for a context. */ -void intelInitExtensions(struct st_context *st, GLboolean enable_imaging) +void intelInitExtensions(struct intel_context *intel, GLboolean enable_imaging) { - GLcontext *ctx = st ? st->ctx : NULL; + GLcontext *ctx = intel ? intel->st->ctx : NULL; /* Disable imaging extension until convolution is working in teximage paths. */ enable_imaging = GL_FALSE; @@ -170,9 +166,6 @@ void intelInitExtensions(struct st_context *st, GLboolean enable_imaging) driInitExtensions(ctx, card_extensions, enable_imaging); #if 0 - if (intel == NULL || intel->ttm) - driInitExtensions(ctx, ttm_extensions, GL_FALSE); - if (intel == NULL || (IS_965(intel->intelScreen->deviceID) && intel->intelScreen->drmMinor >= 8)) @@ -327,7 +320,7 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); - intelInitExtensions( intel->st, GL_TRUE ); + intelInitExtensions( intel, GL_TRUE ); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index d1389a31fb..5a3ae1dc0f 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -117,6 +117,6 @@ intelCreateContext(const __GLcontextModes * visual, void *sharedContextPrivate); extern void -intelInitExtensions(struct st_context *st, GLboolean enable_imaging); +intelInitExtensions(struct intel_context *intel, GLboolean enable_imaging); #endif -- cgit v1.2.3 From 807f8f177b3a2833806d84a70e71019f8849239f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 11 Jun 2008 18:46:26 +0100 Subject: draw: preserve specular alpha when flatshading -- may be FOGC --- src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 30 ++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c index 21a9c3b77f..4741b22d02 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -40,9 +40,19 @@ struct flat_stage struct draw_stage stage; uint num_color_attribs; - uint color_attribs[4]; /* front/back primary/secondary colors */ + uint color_attribs[2]; /* front/back primary colors */ + + uint num_spec_attribs; + uint spec_attribs[2]; /* front/back secondary colors */ }; +#define COPY_3FV( DST, SRC ) \ +do { \ + (DST)[0] = (SRC)[0]; \ + (DST)[1] = (SRC)[1]; \ + (DST)[2] = (SRC)[2]; \ +} while (0) + static INLINE struct flat_stage * flat_stage(struct draw_stage *stage) @@ -58,10 +68,16 @@ static INLINE void copy_colors( struct draw_stage *stage, { const struct flat_stage *flat = flat_stage(stage); uint i; + for (i = 0; i < flat->num_color_attribs; i++) { const uint attr = flat->color_attribs[i]; COPY_4FV(dst->data[attr], src->data[attr]); } + + for (i = 0; i < flat->num_spec_attribs; i++) { + const uint attr = flat->spec_attribs[i]; + COPY_3FV(dst->data[attr], src->data[attr]); + } } @@ -78,6 +94,12 @@ static INLINE void copy_colors2( struct draw_stage *stage, COPY_4FV(dst0->data[attr], src->data[attr]); COPY_4FV(dst1->data[attr], src->data[attr]); } + + for (i = 0; i < flat->num_spec_attribs; i++) { + const uint attr = flat->spec_attribs[i]; + COPY_3FV(dst0->data[attr], src->data[attr]); + COPY_3FV(dst1->data[attr], src->data[attr]); + } } @@ -164,10 +186,14 @@ static void flatshade_init_state( struct draw_stage *stage ) /* Find which vertex shader outputs are colors, make a list */ flat->num_color_attribs = 0; + flat->num_spec_attribs = 0; for (i = 0; i < vs->info.num_outputs; i++) { if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { - flat->color_attribs[flat->num_color_attribs++] = i; + if (vs->info.output_semantic_index[i] == 0) + flat->color_attribs[flat->num_color_attribs++] = i; + else + flat->spec_attribs[flat->num_spec_attribs++] = i; } } -- cgit v1.2.3 From 2161b0fafcdc16703162dd489d2ec1e7114cce4c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 11 Jun 2008 23:48:13 +0100 Subject: draw: don't assume vertex position is in data[0] --- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 25 ++++++++------- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 12 ++++--- src/gallium/auxiliary/draw/draw_pipe_clip.c | 16 +++++----- src/gallium/auxiliary/draw/draw_pipe_cull.c | 8 +++-- src/gallium/auxiliary/draw/draw_pipe_offset.c | 7 +++-- src/gallium/auxiliary/draw/draw_pipe_stipple.c | 5 +-- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 2 ++ src/gallium/auxiliary/draw/draw_pipe_wide_line.c | 9 +++--- src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 9 +++--- src/gallium/auxiliary/draw/draw_private.h | 2 +- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 38 +++++++++++++---------- src/gallium/auxiliary/draw/draw_vs.c | 11 +++++++ src/gallium/auxiliary/draw/draw_vs.h | 1 + src/gallium/auxiliary/draw/draw_vs_aos.c | 8 ++--- src/gallium/auxiliary/draw/draw_vs_varient.c | 4 +++ 15 files changed, 97 insertions(+), 60 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 634bf067f1..ecdebca5f1 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -78,6 +78,8 @@ struct aaline_stage /** For AA lines, this is the vertex attrib slot for the new texcoords */ uint tex_slot; + /** position, not necessarily output zero */ + uint pos_slot; void *sampler_cso; struct pipe_texture *texture; @@ -520,9 +522,10 @@ aaline_line(struct draw_stage *stage, struct prim_header *header) struct prim_header tri; struct vertex_header *v[8]; uint texPos = aaline->tex_slot; + uint posPos = aaline->pos_slot; float *pos, *tex; - float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; - float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; + float dx = header->v[1]->data[posPos][0] - header->v[0]->data[posPos][0]; + float dy = header->v[1]->data[posPos][1] - header->v[0]->data[posPos][1]; double a = atan2(dy, dx); float c_a = (float) cos(a), s_a = (float) sin(a); uint i; @@ -549,35 +552,35 @@ aaline_line(struct draw_stage *stage, struct prim_header *header) */ /* new verts */ - pos = v[0]->data[0]; + pos = v[0]->data[posPos]; pos[0] += (-dx * c_a - dy * s_a); pos[1] += (-dx * s_a + dy * c_a); - pos = v[1]->data[0]; + pos = v[1]->data[posPos]; pos[0] += (-dx * c_a - -dy * s_a); pos[1] += (-dx * s_a + -dy * c_a); - pos = v[2]->data[0]; + pos = v[2]->data[posPos]; pos[0] += ( dx * c_a - dy * s_a); pos[1] += ( dx * s_a + dy * c_a); - pos = v[3]->data[0]; + pos = v[3]->data[posPos]; pos[0] += ( dx * c_a - -dy * s_a); pos[1] += ( dx * s_a + -dy * c_a); - pos = v[4]->data[0]; + pos = v[4]->data[posPos]; pos[0] += (-dx * c_a - dy * s_a); pos[1] += (-dx * s_a + dy * c_a); - pos = v[5]->data[0]; + pos = v[5]->data[posPos]; pos[0] += (-dx * c_a - -dy * s_a); pos[1] += (-dx * s_a + -dy * c_a); - pos = v[6]->data[0]; + pos = v[6]->data[posPos]; pos[0] += ( dx * c_a - dy * s_a); pos[1] += ( dx * s_a + dy * c_a); - pos = v[7]->data[0]; + pos = v[7]->data[posPos]; pos[0] += ( dx * c_a - -dy * s_a); pos[1] += ( dx * s_a + -dy * c_a); @@ -653,7 +656,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) /* update vertex attrib info */ aaline->tex_slot = draw->vs.num_vs_outputs; - assert(aaline->tex_slot > 0); /* output[0] is vertex pos */ + aaline->pos_slot = draw->vs.position_output; /* advertise the extra post-transformed vertex attribute */ draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 96dcdb43d5..87fd303649 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -85,6 +85,7 @@ struct aapoint_stage /** this is the vertex attrib slot for the new texcoords */ uint tex_slot; + uint pos_slot; /* * Currently bound state @@ -570,6 +571,7 @@ aapoint_point(struct draw_stage *stage, struct prim_header *header) struct prim_header tri; struct vertex_header *v[4]; uint texPos = aapoint->tex_slot; + uint pos_slot = aapoint->pos_slot; float radius, *pos, *tex; uint i; float k; @@ -619,19 +621,19 @@ aapoint_point(struct draw_stage *stage, struct prim_header *header) } /* new verts */ - pos = v[0]->data[0]; + pos = v[0]->data[pos_slot]; pos[0] -= radius; pos[1] -= radius; - pos = v[1]->data[0]; + pos = v[1]->data[pos_slot]; pos[0] += radius; pos[1] -= radius; - pos = v[2]->data[0]; + pos = v[2]->data[pos_slot]; pos[0] += radius; pos[1] += radius; - pos = v[3]->data[0]; + pos = v[3]->data[pos_slot]; pos[0] -= radius; pos[1] += radius; @@ -683,6 +685,8 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header) aapoint->tex_slot = draw->vs.num_vs_outputs; assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ + aapoint->pos_slot = draw->vs.position_output; + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib; draw->extra_vp_outputs.slot = aapoint->tex_slot; diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 77ccddac4a..fa10f8efca 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -113,6 +113,7 @@ static void interp( const struct clipper *clip, const struct vertex_header *in ) { const unsigned nr_attrs = clip->stage.draw->vs.num_vs_outputs; + const unsigned pos_attr = clip->stage.draw->vs.position_output; unsigned j; /* Vertex header. @@ -138,18 +139,17 @@ static void interp( const struct clipper *clip, const float *trans = clip->stage.draw->viewport.translate; const float oow = 1.0f / pos[3]; - dst->data[0][0] = pos[0] * oow * scale[0] + trans[0]; - dst->data[0][1] = pos[1] * oow * scale[1] + trans[1]; - dst->data[0][2] = pos[2] * oow * scale[2] + trans[2]; - dst->data[0][3] = oow; + dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0]; + dst->data[pos_attr][1] = pos[1] * oow * scale[1] + trans[1]; + dst->data[pos_attr][2] = pos[2] * oow * scale[2] + trans[2]; + dst->data[pos_attr][3] = oow; } /* Other attributes - * Note: start at 1 to skip winpos (data[0]) since we just computed - * it above. */ - for (j = 1; j < nr_attrs; j++) { - interp_attr(dst->data[j], t, in->data[j], out->data[j]); + for (j = 0; j < nr_attrs; j++) { + if (j != pos_attr) + interp_attr(dst->data[j], t, in->data[j], out->data[j]); } } diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c index 87aaf1f85b..d0d22a38e0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_cull.c +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -55,10 +55,12 @@ static INLINE struct cull_stage *cull_stage( struct draw_stage *stage ) static void cull_tri( struct draw_stage *stage, struct prim_header *header ) { + const unsigned pos = stage->draw->vs.position_output; + /* Window coords: */ - const float *v0 = header->v[0]->data[0]; - const float *v1 = header->v[1]->data[0]; - const float *v2 = header->v[2]->data[0]; + const float *v0 = header->v[0]->data[pos]; + const float *v1 = header->v[1]->data[pos]; + const float *v2 = header->v[2]->data[pos]; /* edge vectors e = v0 - v2, f = v1 - v2 */ const float ex = v0[0] - v2[0]; diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index ea6de8c571..8f1650e55c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -62,14 +62,15 @@ static INLINE struct offset_stage *offset_stage( struct draw_stage *stage ) static void do_offset_tri( struct draw_stage *stage, struct prim_header *header ) { + const unsigned pos = stage->draw->vs.position_output; struct offset_stage *offset = offset_stage(stage); float inv_det = 1.0f / header->det; /* Window coords: */ - float *v0 = header->v[0]->data[0]; - float *v1 = header->v[1]->data[0]; - float *v2 = header->v[2]->data[0]; + float *v0 = header->v[0]->data[pos]; + float *v1 = header->v[1]->data[pos]; + float *v2 = header->v[2]->data[pos]; /* edge vectors e = v0 - v2, f = v1 - v2 */ float ex = v0[0] - v2[0]; diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c index 9522b79582..bf0db18a68 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c @@ -119,8 +119,9 @@ stipple_line(struct draw_stage *stage, struct prim_header *header) struct stipple_stage *stipple = stipple_stage(stage); struct vertex_header *v0 = header->v[0]; struct vertex_header *v1 = header->v[1]; - const float *pos0 = v0->data[0]; - const float *pos1 = v1->data[0]; + const unsigned pos = stage->draw->vs.position_output; + const float *pos0 = v0->data[pos]; + const float *pos1 = v1->data[pos]; float start = 0; int state = 0; diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 9e5597c32c..10a1f7df79 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -136,6 +136,8 @@ emit_vertex( struct vbuf_stage *vbuf, * set_buffer is efficient. Consider a special one-shot mode for * translate. */ + /* Note: we really do want data[0] here, not data[pos]: + */ vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c index 878c9c7169..29649f5787 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -58,6 +58,7 @@ static void wideline_line( struct draw_stage *stage, struct prim_header *header ) { /*const struct wideline_stage *wide = wideline_stage(stage);*/ + const unsigned pos = stage->draw->vs.position_output; const float half_width = 0.5f * stage->draw->rasterizer->line_width; struct prim_header tri; @@ -67,10 +68,10 @@ static void wideline_line( struct draw_stage *stage, struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; + float *pos0 = v0->data[pos]; + float *pos1 = v1->data[pos]; + float *pos2 = v2->data[pos]; + float *pos3 = v3->data[pos]; const float dx = FABSF(pos0[0] - pos2[0]); const float dy = FABSF(pos0[1] - pos2[1]); diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index df92e3f2d0..d40a07f4ae 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -96,6 +96,7 @@ static void widepoint_point( struct draw_stage *stage, struct prim_header *header ) { const struct widepoint_stage *wide = widepoint_stage(stage); + const unsigned pos = stage->draw->vs.position_output; const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; float half_size; float left_adj, right_adj, bot_adj, top_adj; @@ -108,10 +109,10 @@ static void widepoint_point( struct draw_stage *stage, struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; + float *pos0 = v0->data[pos]; + float *pos1 = v1->data[pos]; + float *pos2 = v2->data[pos]; + float *pos3 = v3->data[pos]; /* point size is either per-vertex or fixed size */ if (wide->psize_slot >= 0) { diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 1865601cc0..7bd1e670b4 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -177,7 +177,7 @@ struct draw_context struct { struct draw_vertex_shader *vertex_shader; uint num_vs_outputs; /**< convenience, from vertex_shader */ - + uint position_output; /** TGSI program interpreter runtime state */ struct tgsi_exec_machine machine; diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index c4a67c8289..af6306b1c6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -100,16 +100,19 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, struct vertex_header *out = vertices; const float *scale = pvs->draw->viewport.scale; const float *trans = pvs->draw->viewport.translate; + const unsigned pos = pvs->draw->vs.position_output; unsigned clipped = 0; unsigned j; if (0) debug_printf("%s\n"); for (j = 0; j < count; j++) { - out->clip[0] = out->data[0][0]; - out->clip[1] = out->data[0][1]; - out->clip[2] = out->data[0][2]; - out->clip[3] = out->data[0][3]; + float *position = out->data[pos]; + + out->clip[0] = position[0]; + out->clip[1] = position[1]; + out->clip[2] = position[2]; + out->clip[3] = position[3]; out->vertex_id = 0xffff; out->clipmask = compute_clipmask_gl(out->clip, @@ -120,19 +123,19 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, if (out->clipmask == 0) { /* divide by w */ - float w = 1.0f / out->data[0][3]; + float w = 1.0f / position[3]; /* Viewport mapping */ - out->data[0][0] = out->data[0][0] * w * scale[0] + trans[0]; - out->data[0][1] = out->data[0][1] * w * scale[1] + trans[1]; - out->data[0][2] = out->data[0][2] * w * scale[2] + trans[2]; - out->data[0][3] = w; + position[0] = position[0] * w * scale[0] + trans[0]; + position[1] = position[1] * w * scale[1] + trans[1]; + position[2] = position[2] * w * scale[2] + trans[2]; + position[3] = w; #if 0 debug_printf("post viewport: %f %f %f %f\n", - out->data[0][0], - out->data[0][1], - out->data[0][2], - out->data[0][3]); + position[0], + position[1], + position[2], + position[3]); #endif } @@ -154,15 +157,18 @@ static boolean post_vs_viewport( struct pt_post_vs *pvs, struct vertex_header *out = vertices; const float *scale = pvs->draw->viewport.scale; const float *trans = pvs->draw->viewport.translate; + const unsigned pos = pvs->draw->vs.position_output; unsigned j; if (0) debug_printf("%s\n", __FUNCTION__); for (j = 0; j < count; j++) { + float *position = out->data[pos]; + /* Viewport mapping only, no cliptest/rhw divide */ - out->data[0][0] = out->data[0][0] * scale[0] + trans[0]; - out->data[0][1] = out->data[0][1] * scale[1] + trans[1]; - out->data[0][2] = out->data[0][2] * scale[2] + trans[2]; + position[0] = position[0] * scale[0] + trans[0]; + position[1] = position[1] * scale[1] + trans[1]; + position[2] = position[2] * scale[2] + trans[2]; out = (struct vertex_header *)((char *)out + stride); } diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 979f9864fd..978954e91c 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -85,6 +85,16 @@ draw_create_vertex_shader(struct draw_context *draw, } } + if (vs) + { + uint i; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION && + vs->info.output_semantic_index[i] == 0) + vs->position_output = i; + } + } + assert(vs); return vs; } @@ -100,6 +110,7 @@ draw_bind_vertex_shader(struct draw_context *draw, { draw->vs.vertex_shader = dvs; draw->vs.num_vs_outputs = dvs->info.num_outputs; + draw->vs.position_output = dvs->position_output; dvs->prepare( dvs, draw ); } else { diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 08c6de8ba8..45992d1986 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -106,6 +106,7 @@ struct draw_vertex_shader { struct pipe_shader_state state; struct tgsi_shader_info info; + unsigned position_output; /* Extracted from shader: */ diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index c47647ea72..5d4a8b38c8 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1686,7 +1686,7 @@ static boolean emit_viewport( struct aos_compilation *cp ) { struct x86_reg pos = aos_get_shader_reg_xmm(cp, TGSI_FILE_OUTPUT, - 0); + cp->vaos->draw->vs.position_output ); struct x86_reg scale = x86_make_disp(cp->machine_EDX, Offset(struct aos_machine, scale)); @@ -1700,7 +1700,7 @@ static boolean emit_viewport( struct aos_compilation *cp ) aos_adopt_xmm_reg( cp, pos, TGSI_FILE_OUTPUT, - 0, + cp->vaos->draw->vs.position_output, TRUE ); return TRUE; } @@ -1715,7 +1715,7 @@ static boolean emit_rhw_viewport( struct aos_compilation *cp ) struct x86_reg tmp = aos_get_xmm_reg(cp); struct x86_reg pos = aos_get_shader_reg_xmm(cp, TGSI_FILE_OUTPUT, - 0); + cp->vaos->draw->vs.position_output); struct x86_reg scale = x86_make_disp(cp->machine_EDX, Offset(struct aos_machine, scale)); @@ -1740,7 +1740,7 @@ static boolean emit_rhw_viewport( struct aos_compilation *cp ) aos_adopt_xmm_reg( cp, pos, TGSI_FILE_OUTPUT, - 0, + cp->vaos->draw->vs.position_output, TRUE ); return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index abe8c5ec2d..ad0b829afa 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -89,6 +89,8 @@ static void do_rhw_viewport( struct draw_vs_varient_generic *vsvg, unsigned stride = vsvg->temp_vertex_stride; unsigned j; + ptr += vsvg->base.vs->position_output * 4 * sizeof(float); + for (j = 0; j < count; j++, ptr += stride) { float *data = (float *)ptr; float w = 1.0f / data[3]; @@ -110,6 +112,8 @@ static void do_viewport( struct draw_vs_varient_generic *vsvg, unsigned stride = vsvg->temp_vertex_stride; unsigned j; + ptr += vsvg->base.vs->position_output * 4 * sizeof(float); + for (j = 0; j < count; j++, ptr += stride) { float *data = (float *)ptr; -- cgit v1.2.3 From 6f7ed99b306990f284f9d57c0b66efaa7f2277e1 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Thu, 12 Jun 2008 00:11:54 +0100 Subject: revert the DRI2 commits --- src/gallium/winsys/dri/intel/intel_context.c | 81 +---- src/gallium/winsys/dri/intel/intel_lock.c | 7 +- src/gallium/winsys/dri/intel/intel_screen.c | 375 +++++++++-------------- src/gallium/winsys/dri/intel/intel_screen.h | 4 +- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 3 +- 5 files changed, 159 insertions(+), 311 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 9d78e9ebf8..8284e0edbb 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -28,8 +28,6 @@ #include "i830_dri.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" @@ -38,6 +36,8 @@ #include "i915simple/i915_screen.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" #include "pipe/p_defines.h" #include "pipe/p_context.h" @@ -67,6 +67,7 @@ int __intel_debug = 0; #define need_GL_NV_vertex_program #include "extension_helper.h" + /** * Extension strings exported by the intel driver. * @@ -74,7 +75,7 @@ int __intel_debug = 0; * It appears that ARB_texture_env_crossbar has "disappeared" compared to the * old i830-specific driver. */ -static const struct dri_extension card_extensions[] = { +const struct dri_extension card_extensions[] = { {"GL_ARB_multisample", GL_ARB_multisample_functions}, {"GL_ARB_multitexture", NULL}, {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, @@ -85,27 +86,22 @@ static const struct dri_extension card_extensions[] = { {"GL_ARB_texture_env_combine", NULL}, {"GL_ARB_texture_env_dot3", NULL}, {"GL_ARB_texture_mirrored_repeat", NULL}, - {"GL_ARB_texture_non_power_of_two", NULL }, {"GL_ARB_texture_rectangle", NULL}, - {"GL_NV_texture_rectangle", NULL}, - {"GL_EXT_texture_rectangle", NULL}, - {"GL_ARB_point_parameters", NULL}, {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", - GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, - {"GL_EXT_blend_logic_op", NULL}, {"GL_EXT_blend_subtract", NULL}, {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, -#if 1 /* XXX FBO temporary? */ {"GL_EXT_packed_depth_stencil", NULL}, -#endif + {"GL_EXT_pixel_buffer_object", NULL}, {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, {"GL_EXT_stencil_wrap", NULL}, {"GL_EXT_texture_edge_clamp", NULL}, @@ -120,61 +116,10 @@ static const struct dri_extension card_extensions[] = { {"GL_NV_blend_square", NULL}, {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, {"GL_NV_vertex_program1_1", NULL}, - { "GL_SGIS_generate_mipmap", NULL }, + {"GL_SGIS_generate_mipmap", NULL }, {NULL, NULL} }; -#if 0 -static const struct dri_extension brw_extensions[] = { - { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions}, - { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions}, - { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions}, - { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, - { "GL_ARB_point_sprite", NULL}, - { "GL_ARB_fragment_shader", NULL }, - { "GL_ARB_draw_buffers", NULL }, - { "GL_ARB_depth_texture", NULL }, - { "GL_ARB_fragment_program", NULL }, - { "GL_ARB_shadow", NULL }, - { "GL_EXT_shadow_funcs", NULL }, - /* ARB extn won't work if not enabled */ - { "GL_SGIX_depth_texture", NULL }, - { "GL_ARB_texture_env_crossbar", NULL }, - { "GL_EXT_texture_sRGB", NULL}, - { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - { "GL_ARB_pixel_buffer_object", NULL}, - { NULL, NULL } -}; - -static const struct dri_extension arb_oc_extensions[] = { - {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, - {NULL, NULL} -}; -#endif - -/** - * Initializes potential list of extensions if ctx == NULL, or actually enables - * extensions for a context. - */ -void intelInitExtensions(struct intel_context *intel, GLboolean enable_imaging) -{ - GLcontext *ctx = intel ? intel->st->ctx : NULL; - /* Disable imaging extension until convolution is working in teximage paths. - */ - enable_imaging = GL_FALSE; - - driInitExtensions(ctx, card_extensions, enable_imaging); - -#if 0 - if (intel == NULL || - (IS_965(intel->intelScreen->deviceID) && - intel->intelScreen->drmMinor >= 8)) - driInitExtensions(ctx, arb_oc_extensions, GL_FALSE); - - if (intel == NULL || IS_965(intel->intelScreen->deviceID)) - driInitExtensions(ctx, brw_extensions, GL_FALSE); -#endif -} #ifdef DEBUG @@ -259,10 +204,10 @@ intelCreateContext(const __GLcontextModes * visual, /* * memory pools */ - DRM_LIGHT_LOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); // ZZZ JB should be per screen and not be done per context havePools = intelCreatePools(sPriv); - DRM_UNLOCK(sPriv->fd, &sPriv->lock, driContextPriv->hHWContext); + DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); if (!havePools) return GL_FALSE; @@ -270,7 +215,7 @@ intelCreateContext(const __GLcontextModes * visual, /* Dri stuff */ intel->hHWContext = driContextPriv->hHWContext; intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->lock; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); intel->iw.irq_seq = -1; @@ -320,7 +265,7 @@ intelCreateContext(const __GLcontextModes * visual, intel->st = st_create_context(pipe, visual, st_share); - intelInitExtensions( intel, GL_TRUE ); + driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); return GL_TRUE; } diff --git a/src/gallium/winsys/dri/intel/intel_lock.c b/src/gallium/winsys/dri/intel/intel_lock.c index 469090c0e1..406284c98f 100644 --- a/src/gallium/winsys/dri/intel/intel_lock.c +++ b/src/gallium/winsys/dri/intel/intel_lock.c @@ -50,9 +50,6 @@ intelContendedLock(struct intel_context *intel, uint flags) DBG(LOCK, "%s - got contended lock\n", __progname); - if (sPriv->dri2.enabled) - return; - /* If the window moved, may need to set a new cliprect now. * * NOTE: This releases and regains the hw lock, so all state @@ -61,8 +58,8 @@ intelContendedLock(struct intel_context *intel, uint flags) if (dPriv) DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); - if (sarea && (sarea->width != intelScreen->front.width || - sarea->height != intelScreen->front.height)) { + if (sarea->width != intelScreen->front.width || + sarea->height != intelScreen->front.height) { intelUpdateScreenRotation(sPriv, sarea); } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index e456c28d0d..8817a80a5a 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -60,114 +60,7 @@ static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; extern const struct dri_extension card_extensions[]; -static GLboolean -intel_get_param(__DRIscreenPrivate *psp, int param, int *value) -{ - int ret; - struct drm_i915_getparam gp; - - gp.param = param; - gp.value = value; - ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "drm_i915_getparam: %d\n", ret); - return GL_FALSE; - } - - return GL_TRUE; -} - -static void -intelSetTexOffset(__DRIcontext *pDRICtx, int texname, - unsigned long long offset, int depth, uint pitch) -{ - abort(); -#if 0 - struct intel_context *intel = (struct intel_context*) - ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; - struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); - struct st_texture_object *stObj = st_texture_object(tObj); - - if (!stObj) - return; - - if (stObj->pt) - st->pipe->texture_release(intel->st->pipe, &stObj->pt); - - stObj->imageOverride = GL_TRUE; - stObj->depthOverride = depth; - stObj->pitchOverride = pitch; - - if (offset) - stObj->textureOffset = offset; -#endif -} - - -static void -intelHandleDrawableConfig(__DRIdrawablePrivate *dPriv, - __DRIcontextPrivate *pcp, - __DRIDrawableConfigEvent *event) -{ - (void) dPriv; - (void) pcp; - (void) event; -} - -static void -intelHandleBufferAttach(__DRIdrawablePrivate *dPriv, - __DRIcontextPrivate *pcp, - __DRIBufferAttachEvent *ba) -{ - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - - switch (ba->buffer.attachment) { - case DRI_DRAWABLE_BUFFER_FRONT_LEFT: - intelScreen->front.width = dPriv->w; - intelScreen->front.height = dPriv->h; - intelScreen->front.cpp = ba->buffer.cpp; - intelScreen->front.pitch = ba->buffer.pitch; - driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); - driBOSetReferenced(intelScreen->front.buffer, ba->buffer.handle); - break; - - case DRI_DRAWABLE_BUFFER_BACK_LEFT: - case DRI_DRAWABLE_BUFFER_DEPTH: - case DRI_DRAWABLE_BUFFER_STENCIL: - case DRI_DRAWABLE_BUFFER_ACCUM: - /* anything ?? */ - break; - - default: - fprintf(stderr, "unhandled buffer attach event, attachment type %d\n", - ba->buffer.attachment); - return; - } -} - -static const __DRItexOffsetExtension intelTexOffsetExtension = { - { __DRI_TEX_OFFSET }, - intelSetTexOffset, -}; - -#if 0 -static const __DRItexBufferExtension intelTexBufferExtension = { - { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, - intelSetTexBuffer, -}; -#endif - -static const __DRIextension *intelScreenExtensions[] = { - &driReadDrawableExtension, - &driCopySubBufferExtension.base, - &driSwapControlExtension.base, - &driFrameTrackingExtension.base, - &driMediaStreamCounterExtension.base, - &intelTexOffsetExtension.base, -// &intelTexBufferExtension.base, - NULL -}; static void @@ -284,8 +177,7 @@ intelCreatePools(__DRIscreenPrivate * sPriv) intelScreen->havePools = GL_TRUE; - if (intelScreen->sarea) - intelUpdateScreenRotation(sPriv, intelScreen->sarea); + intelUpdateScreenRotation(sPriv, intelScreen->sarea); return GL_TRUE; } @@ -318,6 +210,11 @@ intelInitDriver(__DRIscreenPrivate * sPriv) struct intel_screen *intelScreen; I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> + getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { fprintf(stderr, "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); @@ -334,19 +231,28 @@ intelInitDriver(__DRIscreenPrivate * sPriv) __driConfigOptions, __driNConfigOptions); sPriv->private = (void *) intelScreen; - intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + - gDRIPriv->sarea_priv_offset); + intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + + gDRIPriv->sarea_priv_offset); intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->front.cpp = gDRIPriv->cpp; - intelScreen->drmMinor = sPriv->drm_version.minor; + intelScreen->drmMinor = sPriv->drmMinor; + + assert(gDRIPriv->bitsPerPixel == 16 || + gDRIPriv->bitsPerPixel == 32); + intelUpdateScreenRotation(sPriv, intelScreen->sarea); if (0) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - sPriv->extensions = intelScreenExtensions; + if (glx_enable_extension != NULL) { + (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); + (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); + (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); + } intel_be_init_device(&intelScreen->base, sPriv->fd); intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; @@ -445,19 +351,65 @@ intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) return 0; } -static __DRIconfig ** -intelFillInModes(__DRIscreenPrivate *psp, - unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +static const struct __DriverAPIRec intelAPI = { + .InitDriver = intelInitDriver, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = intelCopySubBuffer, + .setTexOffset = intelSetTexOffset, +}; + + +static __GLcontextModes * +intelFillInModes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, boolean have_back_buffer) { - __DRIconfig **configs; + __GLcontextModes *modes; __GLcontextModes *m; unsigned num_modes; unsigned depth_buffer_factor; unsigned back_buffer_factor; GLenum fb_format; GLenum fb_type; - int i; /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't * support pageflipping at all. @@ -499,143 +451,100 @@ intelFillInModes(__DRIscreenPrivate *psp, fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; } - configs = driCreateConfigs(fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor); - if (configs == NULL) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + modes = + (*dri_interface->createContextModes) (num_modes, + sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; } /* Mark the visual as slow if there are "fake" stencil bits. */ - for (i = 0; configs[i]; i++) { - m = &configs[i]->modes; + for (m = modes; m != NULL; m = m->next) { if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { m->visualRating = GLX_SLOW_CONFIG; } } - return configs; + return modes; } + /** - * This is the driver specific part of the createNewScreen entry point. - * - * \todo maybe fold this into intelInitDriver + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. * - * \return the __GLcontextModes supported by this driver + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. */ -static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp) +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, + __DRIscreen * psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) { -#ifdef I915 - static const __DRIversion ddx_expected = { 1, 5, 0 }; -#else - static const __DRIversion ddx_expected = { 1, 6, 0 }; -#endif + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 7, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 5, 0 }; - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + static const __DRIversion drm_expected = { 1, 7, 0 }; + + dri_interface = interface; if (!driCheckDriDdxDrmVersions2("i915", - &psp->dri_version, &dri_expected, - &psp->ddx_version, &ddx_expected, - &psp->drm_version, &drm_expected)) { + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { return NULL; } - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is - * called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - intelInitExtensions(NULL, GL_TRUE); - - if (!intelInitDriver(psp)) - return NULL; - - psp->extensions = intelScreenExtensions; - - return (const __DRIconfig **) - intelFillInModes(psp, dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); -} - -/** - * This is the driver specific part of the createNewScreen entry point. - * - * \return the __GLcontextModes supported by this driver - */ -static const -__DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp) -{ - struct intel_screen *intelScreen; - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is - * called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - intelInitExtensions(NULL, GL_TRUE); - - /* Allocate the private area */ - intelScreen = CALLOC_STRUCT(intel_screen); - if (!intelScreen) { - fprintf(stderr, "\nERROR! Allocating private area failed\n"); - return GL_FALSE; + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &intelAPI); + + if (psp != NULL) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create + * is called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); } - /* parse information in __driConfigOptions */ - driParseOptionInfo(&intelScreen->optionCache, - __driConfigOptions, __driNConfigOptions); - - psp->private = (void *) intelScreen; - - intelScreen->drmMinor = psp->drm_version.minor; - /* Determine chipset ID? */ - if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID, - &intelScreen->deviceID)) - return GL_FALSE; - - psp->extensions = intelScreenExtensions; - - intel_be_init_device(&intelScreen->base, psp->fd); - intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; - intelScreen->base.base.get_name = intel_get_name; - - return driConcatConfigs(intelFillInModes(psp, 16, 16, 0, 1), - intelFillInModes(psp, 32, 24, 8, 1)); + return (void *) psp; } -const struct __DriverAPIRec driDriverAPI = { - .InitScreen = intelInitScreen, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetDrawableMSC = driDrawableGetMSC32, - .WaitForMSC = driWaitForMSC32, - .CopySubBuffer = intelCopySubBuffer, - - .InitScreen2 = intelInitScreen2, - .HandleDrawableConfig = intelHandleDrawableConfig, - .HandleBufferAttach = intelHandleBufferAttach, -}; diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index 5a3ae1dc0f..8036917903 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -32,7 +32,7 @@ #include "i830_common.h" #include "xmlconfig.h" #include "intel_drm/ws_dri_bufpool.h" -#include "state_tracker/st_context.h" + #include "pipe/p_compiler.h" #include "intel_drm/intel_be_device.h" @@ -116,7 +116,5 @@ intelCreateContext(const __GLcontextModes * visual, __DRIcontextPrivate * driContextPriv, void *sharedContextPrivate); -extern void -intelInitExtensions(struct intel_context *intel, GLboolean enable_imaging); #endif diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 8b17154cf9..7f3babd98e 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -78,8 +78,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, * current context (which is what intelScreenContext should return) might * not get a contended lock and thus cliprects not updated (tests/manywin) */ - if (!intel->driScreen->dri2.enabled && - intel_context(dPriv->driContextPriv) != intel) + if (intel_context(dPriv->driContextPriv) != intel) DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); -- cgit v1.2.3 From 23422d603ae002a1f368e20cd0f158e057876cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 10 Jun 2008 23:22:12 +0900 Subject: gallium: Implement debug_get_num_option. For numeric options. --- src/gallium/auxiliary/util/p_debug.c | 30 ++++++++++++++++++++++++++++-- src/gallium/include/pipe/p_debug.h | 2 +- 2 files changed, 29 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index d1dfc377f8..a0ffb024e4 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -230,8 +230,34 @@ debug_get_bool_option(const char *name, boolean dfault) long debug_get_num_option(const char *name, long dfault) { - /* FIXME */ - return dfault; + long result; + const char *str; + + str = debug_get_option(name, NULL); + if(!str) + result = dfault; + else { + long sign; + char c; + c = *str++; + if(c == '-') { + sign = -1; + c = *str++; + } + else { + sign = 1; + } + result = 0; + while('0' <= c && c <= '9') { + result = result*10 + (c - '0'); + c = *str++; + } + result *= sign; + } + + debug_printf("%s: %s = %li\n", __FUNCTION__, name, result); + + return result; } diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 05eca75201..9011557006 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -289,7 +289,7 @@ boolean debug_get_bool_option(const char *name, boolean dfault); long -debug_get_unsigned_option(const char *name, long dfault); +debug_get_num_option(const char *name, long dfault); unsigned long debug_get_flags_option(const char *name, -- cgit v1.2.3 From 0f552f500c05d041eda751867c779a8ecc11849c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 11 Jun 2008 10:33:41 +0900 Subject: pipebuffer: Fix improper memory free. --- src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c index 6c3502eea7..e90d2e5623 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c @@ -120,7 +120,7 @@ pb_malloc_buffer_create(size_t size, buf->data = align_malloc(size, desc->alignment < sizeof(void*) ? sizeof(void*) : desc->alignment); if(!buf->data) { - align_free(buf); + FREE(buf); return NULL; } -- cgit v1.2.3 From 2fed8d8496af4aa9105de298c6f320a85eb01623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 11 Jun 2008 12:25:47 +0900 Subject: gallium: Support L16 pixel format. --- src/gallium/auxiliary/util/p_debug.c | 1 + src/gallium/include/pipe/p_format.h | 1 + 2 files changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index a0ffb024e4..e4de12167a 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -370,6 +370,7 @@ static const struct debug_named_value pipe_format_names[] = { DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_UNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_I8_UNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_L16_UNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR), DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR_REV), DEBUG_NAMED_VALUE(PIPE_FORMAT_Z16_UNORM), diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 9ba00f8d7b..3aad463049 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -242,6 +242,7 @@ enum pipe_format { PIPE_FORMAT_A8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_000R, 0, 0, 0, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha */ PIPE_FORMAT_I8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRR, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte intensity */ PIPE_FORMAT_A8L8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha, luminance */ + PIPE_FORMAT_L16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 2, 2, 2, 0, PIPE_FORMAT_TYPE_UNORM ), /**< ushort luminance */ PIPE_FORMAT_YCBCR = _PIPE_FORMAT_YCBCR( 0 ), PIPE_FORMAT_YCBCR_REV = _PIPE_FORMAT_YCBCR( 1 ), PIPE_FORMAT_Z16_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_Z000, 2, 0, 0, 0, PIPE_FORMAT_TYPE_UNORM ), -- cgit v1.2.3 From 23d340c9edbbe64a99478b922c008ae3e2ec7103 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 12 Jun 2008 14:39:57 +0100 Subject: pb: don't assert(0) on failure to allocate - this is a normal condition in many drivers --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 66256f3fa7..0a1e8c83b1 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -184,7 +184,6 @@ mm_bufmgr_create_buffer(struct pb_manager *mgr, mm_buf->block = mmAllocMem(mm->heap, size, mm->align2, 0); if(!mm_buf->block) { - assert(0); FREE(mm_buf); _glthread_UNLOCK_MUTEX(mm->mutex); return NULL; -- cgit v1.2.3 From 68ef8e89a5f25cd9f80e2b9088604631a28edc3c Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 10 Jun 2008 16:59:44 -0400 Subject: glsl: implement variable array indexes --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index d1a3dfd9c7..92aff88925 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -803,7 +803,14 @@ tgsi_dump_instruction( ENM( src->SrcRegister.File, TGSI_FILES_SHORT ); CHR( '[' ); - SID( src->SrcRegister.Index ); + if (src->SrcRegister.Indirect) { + TXT( "addr" ); + if (src->SrcRegister.Index > 0) + CHR( '+' ); + SID( src->SrcRegister.Index ); + } + else + SID( src->SrcRegister.Index ); CHR( ']' ); if (src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || -- cgit v1.2.3 From 08f1b8ac709105d42ec34f8b8a81421e3b0fbc81 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 12 Jun 2008 16:01:05 -0600 Subject: gallium: fix SSE codegen for instructions that use both a CONSTANT and IMMEDIATE Fixes codegen for instructions like MUL dst, CONST[0], IMM[0]; the two operands would up getting aliased in the x86/sse code. Fixes glean/vertProg1/fogparams test. --- src/gallium/auxiliary/draw/draw_vs_aos.c | 26 +++++++++++++++++++------- src/gallium/auxiliary/draw/draw_vs_aos.h | 3 ++- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 2 +- 3 files changed, 22 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 5d4a8b38c8..388dd3fbee 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -67,19 +67,30 @@ static INLINE boolean eq( struct x86_reg a, } struct x86_reg aos_get_x86( struct aos_compilation *cp, + unsigned which_reg, /* quick hack */ unsigned value ) { - if (cp->ebp != value) { + struct x86_reg reg; + + if (which_reg == 0) + reg = cp->temp_EBP; + else + reg = cp->tmp_EAX; + + if (cp->x86_reg[which_reg] != value) { unsigned offset; switch (value) { case X86_IMMEDIATES: + assert(which_reg == 0); offset = Offset(struct aos_machine, immediates); break; case X86_CONSTANTS: + assert(which_reg == 1); offset = Offset(struct aos_machine, constants); break; case X86_ATTRIBS: + assert(which_reg == 0); offset = Offset(struct aos_machine, attrib); break; default: @@ -87,14 +98,14 @@ struct x86_reg aos_get_x86( struct aos_compilation *cp, offset = 0; } - x86_mov(cp->func, cp->temp_EBP, + + x86_mov(cp->func, reg, x86_make_disp(cp->machine_EDX, offset)); - /* x86_deref(x86_make_disp(cp->machine_EDX, offset))); */ - cp->ebp = value; + cp->x86_reg[which_reg] = value; } - return cp->temp_EBP; + return reg; } @@ -118,10 +129,10 @@ static struct x86_reg get_reg_ptr(struct aos_compilation *cp, return x86_make_disp(ptr, Offset(struct aos_machine, internal[idx])); case TGSI_FILE_IMMEDIATE: - return x86_make_disp(aos_get_x86(cp, X86_IMMEDIATES), idx * 4 * sizeof(float)); + return x86_make_disp(aos_get_x86(cp, 0, X86_IMMEDIATES), idx * 4 * sizeof(float)); case TGSI_FILE_CONSTANT: - return x86_make_disp(aos_get_x86(cp, X86_CONSTANTS), idx * 4 * sizeof(float)); + return x86_make_disp(aos_get_x86(cp, 1, X86_CONSTANTS), idx * 4 * sizeof(float)); default: ERROR(cp, "unknown reg file"); @@ -1413,6 +1424,7 @@ static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_inst x87_fld_src( cp, &op->FullSrcRegisters[0], 0 ); x87_fstp( cp->func, x86_make_disp( cp->stack_ESP, 0 ) ); + /* tmp_EAX has been pushed & will be restored below */ x86_mov_reg_imm( cp->func, cp->tmp_EAX, (unsigned long) _powerf ); x86_call( cp->func, cp->tmp_EAX ); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 66944a4e33..64e021ff6b 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -145,7 +145,7 @@ struct aos_compilation { unsigned last_used; } xmm[8]; - unsigned ebp; /* one of X86_* */ + unsigned x86_reg[2]; /* one of X86_* */ boolean input_fetched[PIPE_MAX_ATTRIBS]; unsigned output_last_write[PIPE_MAX_ATTRIBS]; @@ -213,6 +213,7 @@ do { \ #define X86_ATTRIBS 3 struct x86_reg aos_get_x86( struct aos_compilation *cp, + unsigned which_reg, unsigned value ); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index b720185709..6b92811870 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -96,7 +96,7 @@ static void get_src_ptr( struct aos_compilation *cp, struct x86_reg elt, unsigned a ) { - struct x86_reg attrib = x86_make_disp(aos_get_x86( cp, X86_ATTRIBS ), + struct x86_reg attrib = x86_make_disp(aos_get_x86( cp, 0, X86_ATTRIBS ), a * sizeof(struct aos_attrib)); struct x86_reg input_ptr = x86_make_disp(attrib, -- cgit v1.2.3 From 20ee00754d432cf6c9aca2ba61e004a83795e160 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 12 Jun 2008 16:01:43 -0600 Subject: gallium: disable the codegen for TGSI_OPCODE_EXPBASE2 for now. The x86 code seems to fail for exponents of 4 or larger. See glean's vertProg1/EX2 test. --- src/gallium/auxiliary/draw/draw_vs_aos.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 388dd3fbee..1f926b3e85 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1662,7 +1662,14 @@ emit_instruction( struct aos_compilation *cp, return emit_RND(cp, inst); case TGSI_OPCODE_EXPBASE2: +#if 0 + /* this seems to fail for "larger" exponents. + * See glean tvertProg1's EX2 test. + */ return emit_EX2(cp, inst); +#else + return FALSE; +#endif case TGSI_OPCODE_LOGBASE2: return emit_LG2(cp, inst); -- cgit v1.2.3 From e9b8df69b40c55953e1b3503690b54f993773223 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 13 Jun 2008 12:21:58 +0200 Subject: i915: Support all primtive types in vbuf path --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 44 +++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index adfb16fbc5..c7a31fdb70 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -163,6 +163,10 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render, i915_render->hwprim = PRIM3D_LINELIST; i915_render->fallback = 0; return TRUE; + case PIPE_PRIM_LINE_LOOP: + i915_render->hwprim = PRIM3D_LINELIST; + i915_render->fallback = PIPE_PRIM_LINE_LOOP; + return TRUE; case PIPE_PRIM_LINE_STRIP: i915_render->hwprim = PRIM3D_LINESTRIP; i915_render->fallback = 0; @@ -175,6 +179,10 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render, i915_render->hwprim = PRIM3D_TRISTRIP; i915_render->fallback = 0; return TRUE; + case PIPE_PRIM_TRIANGLE_FAN: + i915_render->hwprim = PRIM3D_TRIFAN; + i915_render->fallback = 0; + return TRUE; case PIPE_PRIM_QUADS: i915_render->hwprim = PRIM3D_TRILIST; i915_render->fallback = PIPE_PRIM_QUADS; @@ -183,7 +191,12 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render, i915_render->hwprim = PRIM3D_TRILIST; i915_render->fallback = PIPE_PRIM_QUAD_STRIP; return TRUE; + case PIPE_PRIM_POLYGON: + i915_render->hwprim = PRIM3D_POLY; + i915_render->fallback = 0; + return TRUE; default: + assert((int)"Error unkown primtive type" & 0); /* Actually, can handle a lot more just fine... Fixme. */ return FALSE; @@ -211,6 +224,13 @@ draw_arrays_generate_indices( struct vbuf_render *render, if (i < end) OUT_BATCH( i ); break; + case PIPE_PRIM_LINE_LOOP: + if (nr >= 2) { + for (i = start + 1; i < end; i++) + OUT_BATCH( (i-0) | (i+0) << 16 ); + OUT_BATCH( (i-0) | ( 0) << 16 ); + } + break; case PIPE_PRIM_QUADS: for (i = start; i + 3 < end; i += 4) { OUT_BATCH( (i+0) | (i+1) << 16 ); @@ -236,6 +256,11 @@ draw_arrays_calc_nr_indices( uint nr, unsigned type ) switch (type) { case 0: return nr; + case PIPE_PRIM_LINE_LOOP: + if (nr >= 2) + return nr * 2; + else + return 0; case PIPE_PRIM_QUADS: return (nr / 4) * 6; case PIPE_PRIM_QUAD_STRIP: @@ -262,6 +287,8 @@ draw_arrays_fallback( struct vbuf_render *render, i915_emit_hardware_state( i915 ); nr_indices = draw_arrays_calc_nr_indices( nr, i915_render->fallback ); + if (!nr_indices) + return; if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) { FLUSH_BATCH(NULL); @@ -328,6 +355,13 @@ draw_generate_indices( struct vbuf_render *render, OUT_BATCH( indices[i] ); } break; + case PIPE_PRIM_LINE_LOOP: + if (nr_indices >= 2) { + for (i = 1; i < nr_indices; i++) + OUT_BATCH( indices[i-0] | indices[i+0] << 16 ); + OUT_BATCH( indices[i-0] | indices[0] << 16 ); + } + break; case PIPE_PRIM_QUADS: for (i = 0; i + 3 < nr_indices; i += 4) { OUT_BATCH( indices[i+0] | indices[i+1] << 16 ); @@ -354,6 +388,11 @@ draw_calc_nr_indices( uint nr_indices, unsigned type ) switch (type) { case 0: return nr_indices; + case PIPE_PRIM_LINE_LOOP: + if (nr_indices >= 2) + return nr_indices * 2; + else + return 0; case PIPE_PRIM_QUADS: return (nr_indices / 4) * 6; case PIPE_PRIM_QUAD_STRIP: @@ -374,9 +413,10 @@ i915_vbuf_render_draw( struct vbuf_render *render, unsigned save_nr_indices; save_nr_indices = nr_indices; - nr_indices = draw_calc_nr_indices( nr_indices, i915_render->fallback ); - assert(nr_indices); + nr_indices = draw_calc_nr_indices( nr_indices, i915_render->fallback ); + if (!nr_indices) + return; if (i915->dirty) i915_update_derived( i915 ); -- cgit v1.2.3 From de35bf5bdca83f05dc919bf175588ce749009dfc Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 13 Jun 2008 14:11:20 +0200 Subject: i915: Messed up lineloop now works --- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index c7a31fdb70..aef3682bbf 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -228,7 +228,7 @@ draw_arrays_generate_indices( struct vbuf_render *render, if (nr >= 2) { for (i = start + 1; i < end; i++) OUT_BATCH( (i-0) | (i+0) << 16 ); - OUT_BATCH( (i-0) | ( 0) << 16 ); + OUT_BATCH( (i-0) | ( start) << 16 ); } break; case PIPE_PRIM_QUADS: @@ -358,8 +358,8 @@ draw_generate_indices( struct vbuf_render *render, case PIPE_PRIM_LINE_LOOP: if (nr_indices >= 2) { for (i = 1; i < nr_indices; i++) - OUT_BATCH( indices[i-0] | indices[i+0] << 16 ); - OUT_BATCH( indices[i-0] | indices[0] << 16 ); + OUT_BATCH( indices[i-1] | indices[i] << 16 ); + OUT_BATCH( indices[i-1] | indices[0] << 16 ); } break; case PIPE_PRIM_QUADS: -- cgit v1.2.3 From 6f548c88e265c70cd0eb6bc148e23d8ce8d83133 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 13 Jun 2008 14:50:29 +0200 Subject: gallium: Allow pipe format component sizes to be specified with finer granularity. This will allow us to define A2R10G10B10 format. --- src/gallium/include/pipe/p_format.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 3aad463049..b7716363b8 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -121,21 +121,21 @@ static INLINE uint pf_get(pipe_format_rgbazs_t f, uint shift, uint mask) #define pf_size_z(f) pf_get(f, 20, 0x7) /**< Size of Z */ #define pf_size_w(f) pf_get(f, 23, 0x7) /**< Size of W */ #define pf_size_xyzw(f,i) pf_get(f, 14+((i)*3), 0x7) -#define pf_exp8(f) pf_get(f, 26, 0x3) /**< Scale size by 8 ^ exp8 */ -#define pf_type(f) pf_get(f, 28, 0xf) /**< PIPE_FORMAT_TYPE_ */ +#define pf_exp2(f) pf_get(f, 26, 0x7) /**< Scale size by 2 ^ exp2 */ +#define pf_type(f) pf_get(f, 29, 0x7) /**< PIPE_FORMAT_TYPE_ */ /** * Helper macro to encode the above structure into a 32-bit value. */ -#define _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, EXP8, TYPE ) (\ +#define _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, EXP2, TYPE ) (\ (PIPE_FORMAT_LAYOUT_RGBAZS << 0) |\ ((SWZ) << 2) |\ ((SIZEX) << 14) |\ ((SIZEY) << 17) |\ ((SIZEZ) << 20) |\ ((SIZEW) << 23) |\ - ((EXP8) << 26) |\ - ((TYPE) << 28) ) + ((EXP2) << 26) |\ + ((TYPE) << 29) ) /** * Helper macro to encode the swizzle part of the structure above. @@ -148,17 +148,23 @@ static INLINE uint pf_get(pipe_format_rgbazs_t f, uint shift, uint mask) #define _PIPE_FORMAT_RGBAZS_1( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\ _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 0, TYPE ) +/** + * Shorthand macro for RGBAZS layout with component sizes in 2-bit units. + */ +#define _PIPE_FORMAT_RGBAZS_2( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\ + _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 1, TYPE ) + /** * Shorthand macro for RGBAZS layout with component sizes in 8-bit units. */ #define _PIPE_FORMAT_RGBAZS_8( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\ - _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 1, TYPE ) + _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 3, TYPE ) /** * Shorthand macro for RGBAZS layout with component sizes in 64-bit units. */ #define _PIPE_FORMAT_RGBAZS_64( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\ - _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 2, TYPE ) + _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 6, TYPE ) /** * Shorthand macro for common format swizzles. @@ -359,7 +365,7 @@ static INLINE uint pf_get_component_bits( enum pipe_format format, uint comp ) else { size = 0; } - return size << (pf_exp8(format) * 3); + return size << pf_exp2(format); } /** -- cgit v1.2.3 From b03a0373a234af00e50652a6a2d75fd9ed8fc19b Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 13 Jun 2008 14:58:24 +0200 Subject: gallium: Add PIPE_FORMAT_A2B10G10R10_UNORM. --- src/gallium/include/pipe/p_format.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index b7716363b8..b4d6399c02 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -174,6 +174,7 @@ static INLINE uint pf_get(pipe_format_rgbazs_t f, uint shift, uint mask) #define _PIPE_FORMAT_RGB1 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_1 ) #define _PIPE_FORMAT_RGBA _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_A ) #define _PIPE_FORMAT_ARGB _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_A, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B ) +#define _PIPE_FORMAT_ABGR _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_A, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R ) #define _PIPE_FORMAT_BGRA _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_A ) #define _PIPE_FORMAT_1RGB _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_1, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B ) #define _PIPE_FORMAT_BGR1 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_1 ) @@ -244,6 +245,7 @@ enum pipe_format { PIPE_FORMAT_A1R5G5B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 1, 5, 5, 5, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_A4R4G4B4_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_R5G6B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_RGB1, 5, 6, 5, 0, PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_A2B10G10R10_UNORM = _PIPE_FORMAT_RGBAZS_2 ( _PIPE_FORMAT_ABGR, 2, 10,10,10,PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_L8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte luminance */ PIPE_FORMAT_A8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_000R, 0, 0, 0, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha */ PIPE_FORMAT_I8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRR, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte intensity */ -- cgit v1.2.3 From 62f03a9ecc1d73ff67f5c2a9e5f9638bc6f7d458 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 13 Jun 2008 15:21:11 +0200 Subject: gallium: Fix PIPE_FORMAT_A2B10G10R10_UNORM definition. Whoops! --- src/gallium/include/pipe/p_format.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index b4d6399c02..b1bad8ab0e 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -245,7 +245,7 @@ enum pipe_format { PIPE_FORMAT_A1R5G5B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 1, 5, 5, 5, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_A4R4G4B4_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_ARGB, 4, 4, 4, 4, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_R5G6B5_UNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_RGB1, 5, 6, 5, 0, PIPE_FORMAT_TYPE_UNORM ), - PIPE_FORMAT_A2B10G10R10_UNORM = _PIPE_FORMAT_RGBAZS_2 ( _PIPE_FORMAT_ABGR, 2, 10,10,10,PIPE_FORMAT_TYPE_UNORM ), + PIPE_FORMAT_A2B10G10R10_UNORM = _PIPE_FORMAT_RGBAZS_2 ( _PIPE_FORMAT_ABGR, 1, 5, 5, 5, PIPE_FORMAT_TYPE_UNORM ), PIPE_FORMAT_L8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte luminance */ PIPE_FORMAT_A8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_000R, 0, 0, 0, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte alpha */ PIPE_FORMAT_I8_UNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRR, 1, 1, 1, 1, PIPE_FORMAT_TYPE_UNORM ), /**< ubyte intensity */ -- cgit v1.2.3 From c341094921da7c4ff30f81706279ead39cb3b812 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 13 Jun 2008 19:03:51 +0200 Subject: i915: Fix most of the clear problems trivial/clear-undefined still fails --- src/gallium/drivers/i915simple/i915_clear.c | 1 + src/gallium/drivers/i915simple/i915_texture.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_clear.c b/src/gallium/drivers/i915simple/i915_clear.c index cde69daacc..8a2d3ca43f 100644 --- a/src/gallium/drivers/i915simple/i915_clear.c +++ b/src/gallium/drivers/i915simple/i915_clear.c @@ -44,4 +44,5 @@ i915_clear(struct pipe_context *pipe, struct pipe_surface *ps, unsigned clearValue) { pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); + ps->status = PIPE_SURFACE_STATUS_DEFINED; } diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 16354dce50..7a1665d48b 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -635,6 +635,7 @@ i915_get_tex_surface(struct pipe_screen *screen, ps->pitch = tex->pitch; ps->offset = offset; ps->usage = flags; + ps->status = PIPE_SURFACE_STATUS_DEFINED; } return ps; } -- cgit v1.2.3 From d1397fd779ce63416bb59662a3c96f9c0a6ef7f5 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 13 Jun 2008 19:07:29 +0200 Subject: i915: Fix offsets not being used for surface targets --- src/gallium/drivers/i915simple/i915_state_emit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index de0c1a787a..480b0b54c4 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -222,7 +222,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) OUT_RELOC(cbuf_surface->buffer, I915_BUFFER_ACCESS_WRITE, - 0); + cbuf_surface->offset); } /* What happens if no zbuf?? @@ -238,7 +238,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) OUT_RELOC(depth_surface->buffer, I915_BUFFER_ACCESS_WRITE, - 0); + depth_surface->offset); } { -- cgit v1.2.3 From 3da77b33bb0093ff27c16833ed93a3a114c3e95e Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 13 Jun 2008 20:46:14 +0200 Subject: i915: Improved the not used tile code --- src/gallium/drivers/i915simple/i915_state_emit.c | 21 ++++++++++----- src/gallium/drivers/i915simple/i915_texture.c | 33 +++++++++++++++--------- 2 files changed, 36 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 480b0b54c4..bc801a82f0 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -211,14 +211,18 @@ i915_emit_hardware_state(struct i915_context *i915 ) struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; if (cbuf_surface) { - unsigned pitch = (cbuf_surface->pitch * cbuf_surface->cpp); + unsigned cpitch = (cbuf_surface->pitch * cbuf_surface->cpp); + unsigned ctile = BUF_3D_USE_FENCE; +#if 0 + if (!((cpitch - 1) & cpitch) && cpitch >= 512) + ctile = BUF_3D_TILED_SURFACE; +#endif OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(pitch) | /* pitch in bytes */ -// BUF_3D_TILED_SURFACE); /* JB: Used to force tileing */ - BUF_3D_USE_FENCE); + BUF_3D_PITCH(cpitch) | /* pitch in bytes */ + ctile); OUT_RELOC(cbuf_surface->buffer, I915_BUFFER_ACCESS_WRITE, @@ -229,12 +233,17 @@ i915_emit_hardware_state(struct i915_context *i915 ) */ if (depth_surface) { unsigned zpitch = (depth_surface->pitch * depth_surface->cpp); - + unsigned ztile = BUF_3D_USE_FENCE; +#if 0 + if (!((zpitch - 1) & zpitch) && zpitch >= 512) + ztile = BUF_3D_TILED_SURFACE; +#endif + OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(BUF_3D_ID_DEPTH | BUF_3D_PITCH(zpitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); + ztile); OUT_RELOC(depth_surface->buffer, I915_BUFFER_ACCESS_WRITE, diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 7a1665d48b..d591b09e3c 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -104,16 +104,14 @@ i915_miptree_set_image_offset(struct i915_texture *tex, */ } -#if 0 static unsigned power_of_two(unsigned x) { - int value = 1; + unsigned value = 1; while (value <= x) value = value << 1; return value; } -#endif static unsigned round_up(unsigned n, unsigned multiple) @@ -125,8 +123,7 @@ round_up(unsigned n, unsigned multiple) * Special case to deal with display targets. */ static boolean -i915_displaytarget_layout(struct pipe_screen *screen, - struct i915_texture *tex) +i915_displaytarget_layout(struct i915_texture *tex) { struct pipe_texture *pt = &tex->base; @@ -139,13 +136,19 @@ i915_displaytarget_layout(struct pipe_screen *screen, 1 ); i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); -#if 0 - tex->pitch = MAX2(512, power_of_two(tex->base.width[0] * pt->cpp)) / pt->cpp; - tex->total_height = round_up(tex->base.height[0], 8); -#else - tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp); - tex->total_height = tex->base.height[0]; -#endif + if (tex->base.width[0] >= 128) { + tex->pitch = power_of_two(tex->base.width[0] * pt->cpp) / pt->cpp; + tex->total_height = round_up(tex->base.height[0], 8); + } else { + tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp); + tex->total_height = tex->base.height[0]; + } + +/* + printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, + tex->base.width[0], tex->base.height[0], pt->cpp, + tex->pitch, tex->total_height, tex->pitch * tex->total_height * 4); +*/ return 1; } @@ -161,6 +164,12 @@ i945_miptree_layout_2d( struct i915_texture *tex ) unsigned width = pt->width[0]; unsigned height = pt->height[0]; +#if 0 /* used for tiled display targets */ + if (pt->last_level == 0 && pt->cpp == 4) + if (i915_displaytarget_layout(tex)) + return; +#endif + tex->pitch = pt->width[0]; /* May need to adjust pitch to accomodate the placement of -- cgit v1.2.3 From 64d854ebf7074f4a86bb9d45bb2e1003f86a86a1 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 13 Jun 2008 17:22:11 +0200 Subject: util: Use pf_get_size(). --- src/gallium/auxiliary/util/u_blit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 999a3e5099..7b9415d49a 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -281,7 +281,7 @@ util_blit_pixels(struct blit_state *ctx, texTemp.height[0] = srcH; texTemp.depth[0] = 1; texTemp.compressed = 0; - texTemp.cpp = pf_get_bits(src->format) / 8; + texTemp.cpp = pf_get_size(src->format); tex = screen->texture_create(screen, &texTemp); if (!tex) -- cgit v1.2.3 From d9d1e39d95fef4a8da15147956ff0c3e0a188b5b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 17 Jun 2008 15:47:01 +0200 Subject: i915: Max and Min lod now works --- src/gallium/drivers/i915simple/i915_context.h | 2 + src/gallium/drivers/i915simple/i915_state.c | 10 ++- .../drivers/i915simple/i915_state_sampler.c | 84 ++++++++++++++++++---- 3 files changed, 79 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 2ee0381648..892a88fd2c 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -178,6 +178,8 @@ struct i915_rasterizer_state { struct i915_sampler_state { unsigned state[3]; const struct pipe_sampler_state *templ; + unsigned minlod; + unsigned maxlod; }; diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 39d5d5e9d6..dbb33f2695 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -251,11 +251,17 @@ i915_create_sampler_state(struct pipe_context *pipe, if (sampler->normalized_coords) cso->state[1] |= SS3_NORMALIZED_COORDS; - if (0) /* XXX not tested yet */ { int minlod = (int) (16.0 * sampler->min_lod); + int maxlod = (int) (16.0 * sampler->max_lod); minlod = CLAMP(minlod, 0, 16 * 11); - cso->state[1] |= (minlod << SS3_MIN_LOD_SHIFT); + maxlod = CLAMP(maxlod, 0, 16 * 11); + + if (minlod > maxlod) + maxlod = minlod; + + cso->minlod = minlod; + cso->maxlod = maxlod; } { diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c index 982eec4a1b..fbdc1a3b68 100644 --- a/src/gallium/drivers/i915simple/i915_state_sampler.c +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -35,6 +35,35 @@ #include "i915_state.h" +/* + * A note about min_lod & max_lod. + * + * There is a circular dependancy between the sampler state + * and the map state to be submitted to hw. + * + * Two condition must be meet: + * min_lod =< max_lod == true + * max_lod =< last_level == true + * + * + * This is all fine and dandy if it where for the fact that max_lod + * is set on the map state instead of the sampler state. That is + * the max_lod we submit on map is: + * max_lod = MIN2(last_level, max_lod); + * + * So we need to update the map state when we change samplers and + * we need to be change the sampler state when map state is changed. + * The first part is done by calling i915_update_texture in + * i915_update_samplers and the second part is done else where in + * code tracking the state changes. + */ + +static void +i915_update_texture(struct i915_context *i915, + uint unit, + const struct i915_texture *tex, + const struct i915_sampler_state *sampler, + uint state[6]); /** * Compute i915 texture sampling state. * @@ -50,6 +79,7 @@ static void update_sampler(struct i915_context *i915, unsigned state[3] ) { const struct pipe_texture *pt = &tex->base; + unsigned minlod, lastlod; /* Need to do this after updating the maps, which call the * intel_finalize_mipmap_tree and hence can update firstLevel: @@ -95,6 +125,15 @@ static void update_sampler(struct i915_context *i915, } #endif + /* See note at the top of file */ + minlod = sampler->minlod; + lastlod = pt->last_level << 4; + + if (lastlod < minlod) { + minlod = lastlod; + } + + state[1] |= (sampler->minlod << SS3_MIN_LOD_SHIFT); state[1] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT); } @@ -112,18 +151,23 @@ void i915_update_samplers( struct i915_context *i915 ) /* could also examine the fragment program? */ if (i915->texture[unit]) { update_sampler( i915, - unit, - i915->sampler[unit], /* sampler state */ - i915->texture[unit], /* texture */ - i915->current.sampler[unit] /* the result */ - ); - - i915->current.sampler_enable_nr++; - i915->current.sampler_enable_flags |= (1 << unit); + unit, + i915->sampler[unit], /* sampler state */ + i915->texture[unit], /* texture */ + i915->current.sampler[unit] /* the result */ + ); + i915_update_texture( i915, + unit, + i915->texture[unit], /* texture */ + i915->sampler[unit], /* sampler state */ + i915->current.texbuffer[unit] ); + + i915->current.sampler_enable_nr++; + i915->current.sampler_enable_flags |= (1 << unit); } } - i915->hardware_dirty |= I915_HW_SAMPLER; + i915->hardware_dirty |= I915_HW_SAMPLER | I915_HW_MAP; } @@ -179,14 +223,17 @@ translate_texture_format(enum pipe_format pipeFormat) static void -i915_update_texture(struct i915_context *i915, uint unit, +i915_update_texture(struct i915_context *i915, + uint unit, + const struct i915_texture *tex, + const struct i915_sampler_state *sampler, uint state[6]) { - const struct i915_texture *tex = i915->texture[unit]; const struct pipe_texture *pt = &tex->base; uint format, pitch; const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; const uint num_levels = pt->last_level; + unsigned max_lod = num_levels * 4; assert(tex); assert(width); @@ -207,16 +254,19 @@ i915_update_texture(struct i915_context *i915, uint unit, | MS3_USE_FENCE_REGS); /* - * XXX sampler->max_lod should be used to program the MAX_LOD field below. - * Also, when min_filter != mag_filter and there's just one mipmap level, + * XXX When min_filter != mag_filter and there's just one mipmap level, * set max_lod = 1 to make sure i915 chooses between min/mag filtering. */ + /* See note at the top of file */ + if (max_lod > (sampler->maxlod >> 2)) + max_lod = sampler->maxlod >> 2; + /* MS4 state */ state[1] = ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK - | ((num_levels * 4) << MS4_MAX_LOD_SHIFT) + | ((max_lod) << MS4_MAX_LOD_SHIFT) | ((depth - 1) << MS4_VOLUME_DEPTH_SHIFT)); } @@ -231,7 +281,11 @@ i915_update_textures(struct i915_context *i915) /* determine unit enable/disable by looking for a bound texture */ /* could also examine the fragment program? */ if (i915->texture[unit]) { - i915_update_texture(i915, unit, i915->current.texbuffer[unit]); + i915_update_texture( i915, + unit, + i915->texture[unit], /* texture */ + i915->sampler[unit], /* sampler state */ + i915->current.texbuffer[unit] ); } } -- cgit v1.2.3 From 5805a9e32881831f320bcd1a95fbfacf17aef5d5 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 17 Jun 2008 17:46:45 +0200 Subject: i915: Made region pool a slabpool --- src/gallium/winsys/common/intel_drm/intel_be_device.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c index 0fc1894eaa..3eed0fe410 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.c +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c @@ -220,7 +220,18 @@ intel_be_init_device(struct intel_be_device *dev, int fd) dev->mallocPool = driMallocPoolInit(); dev->staticPool = driDRMPoolInit(dev->fd); - dev->regionPool = driDRMPoolInit(dev->fd); + /* Sizes: 64 128 256 512 1024 2048 4096 8192 16384 32768 */ + dev->regionPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + 64, + 10, 120, 4096 * 64, 0, + dev->fMan); + dev->vertexPool = driSlabPoolInit(dev->fd, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | -- cgit v1.2.3 From 4539410d71d5cf5c7d7344b1d3012a8a3e825a18 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 17 Jun 2008 21:43:41 +0200 Subject: gallium: Add facilities for mixed pipe formats. --- src/gallium/include/pipe/p_format.h | 48 ++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index b1bad8ab0e..e7d63350ef 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -50,7 +50,7 @@ extern "C" { #define PIPE_FORMAT_LAYOUT_RGBAZS 0 #define PIPE_FORMAT_LAYOUT_YCBCR 1 #define PIPE_FORMAT_LAYOUT_DXT 2 /**< XXX temporary? */ - +#define PIPE_FORMAT_LAYOUT_MIXED 3 static INLINE uint pf_layout(uint f) /**< PIPE_FORMAT_LAYOUT_ */ { @@ -62,7 +62,7 @@ static INLINE uint pf_layout(uint f) /**< PIPE_FORMAT_LAYOUT_ */ */ /** - * Format component selectors for RGBAZS layout. + * Format component selectors for RGBAZS & MIXED layout. */ #define PIPE_FORMAT_COMP_R 0 #define PIPE_FORMAT_COMP_G 1 @@ -109,8 +109,6 @@ static INLINE uint pf_get(pipe_format_rgbazs_t f, uint shift, uint mask) return (f >> shift) & mask; } -/* XXX: The bit layout needs to be revised, can't currently encode 10-bit components. */ - #define pf_swizzle_x(f) pf_get(f, 2, 0x7) /**< PIPE_FORMAT_COMP_ */ #define pf_swizzle_y(f) pf_get(f, 5, 0x7) /**< PIPE_FORMAT_COMP_ */ #define pf_swizzle_z(f) pf_get(f, 8, 0x7) /**< PIPE_FORMAT_COMP_ */ @@ -166,6 +164,36 @@ static INLINE uint pf_get(pipe_format_rgbazs_t f, uint shift, uint mask) #define _PIPE_FORMAT_RGBAZS_64( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, TYPE )\ _PIPE_FORMAT_RGBAZS( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, 6, TYPE ) +typedef uint pipe_format_mixed_t; + +/* NOTE: Use pf_swizzle_* and pf_size_* macros for swizzles and sizes. + */ + +#define pf_mixed_sign_x(f) pf_get( f, 26, 0x1 ) /*< Sign of X */ +#define pf_mixed_sign_y(f) pf_get( f, 27, 0x1 ) /*< Sign of Y */ +#define pf_mixed_sign_z(f) pf_get( f, 28, 0x1 ) /*< Sign of Z */ +#define pf_mixed_sign_w(f) pf_get( f, 29, 0x1 ) /*< Sign of W */ +#define pf_mixed_sign_xyzw(f, i) pf_get( f, 26 + (i), 0x1 ) +#define pf_mixed_normalized(f) pf_get( f, 30, 0x1 ) /*< Type is NORM (1) or SCALED (0) */ +#define pf_mixed_scale8(f) pf_get( f, 31, 0x1 ) /*< Scale size by either one (0) or eight (1) */ + +/** + * Helper macro to encode the above structure into a 32-bit value. + */ +#define _PIPE_FORMAT_MIXED( SWZ, SIZEX, SIZEY, SIZEZ, SIZEW, SIGNX, SIGNY, SIGNZ, SIGNW, NORMALIZED, SCALE8 ) (\ + (PIPE_FORMAT_LAYOUT_MIXED << 0) |\ + ((SWZ) << 2) |\ + ((SIZEX) << 14) |\ + ((SIZEY) << 17) |\ + ((SIZEZ) << 20) |\ + ((SIZEW) << 23) |\ + ((SIGNX) << 26) |\ + ((SIGNY) << 27) |\ + ((SIGNZ) << 28) |\ + ((SIGNW) << 29) |\ + ((NORMALIZED) << 30) |\ + ((SCALE8) << 31) ) + /** * Shorthand macro for common format swizzles. */ @@ -177,6 +205,7 @@ static INLINE uint pf_get(pipe_format_rgbazs_t f, uint shift, uint mask) #define _PIPE_FORMAT_ABGR _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_A, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R ) #define _PIPE_FORMAT_BGRA _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_A ) #define _PIPE_FORMAT_1RGB _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_1, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_B ) +#define _PIPE_FORMAT_1BGR _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_1, PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R ) #define _PIPE_FORMAT_BGR1 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_B, PIPE_FORMAT_COMP_G, PIPE_FORMAT_COMP_R, PIPE_FORMAT_COMP_1 ) #define _PIPE_FORMAT_0000 _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0 ) #define _PIPE_FORMAT_000R _PIPE_FORMAT_SWZ( PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_0, PIPE_FORMAT_COMP_R ) @@ -331,6 +360,11 @@ enum pipe_format { PIPE_FORMAT_R8G8B8A8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), PIPE_FORMAT_R8G8B8X8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), + /* mixed formats */ + PIPE_FORMAT_A8UB8UG8SR8S_NORM = _PIPE_FORMAT_MIXED( _PIPE_FORMAT_ABGR, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 ), + PIPE_FORMAT_X8UB8UG8SR8S_NORM = _PIPE_FORMAT_MIXED( _PIPE_FORMAT_1BGR, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 ), + PIPE_FORMAT_B6UG5SR5S_NORM = _PIPE_FORMAT_MIXED( _PIPE_FORMAT_BGR1, 6, 5, 5, 0, 0, 1, 1, 0, 1, 0 ), + /* compressed formats */ PIPE_FORMAT_DXT1_RGB = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 0 ), PIPE_FORMAT_DXT1_RGBA = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 8 ), @@ -338,7 +372,6 @@ enum pipe_format { PIPE_FORMAT_DXT5_RGBA = _PIPE_FORMAT_DXT( 5, 8, 8, 8, 8 ) }; - /** * Builds pipe format name from format token. */ @@ -367,7 +400,9 @@ static INLINE uint pf_get_component_bits( enum pipe_format format, uint comp ) else { size = 0; } - return size << pf_exp2(format); + if (pf_layout( format ) == PIPE_FORMAT_LAYOUT_RGBAZS) + return size << pf_exp2( format ); + return size << (pf_mixed_scale8( format ) * 3); } /** @@ -377,6 +412,7 @@ static INLINE uint pf_get_bits( enum pipe_format format ) { switch (pf_layout(format)) { case PIPE_FORMAT_LAYOUT_RGBAZS: + case PIPE_FORMAT_LAYOUT_MIXED: return pf_get_component_bits( format, PIPE_FORMAT_COMP_0 ) + pf_get_component_bits( format, PIPE_FORMAT_COMP_1 ) + -- cgit v1.2.3 From 081c05605f1c308c35fcf4168aac09fbf3c0a108 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 18 Jun 2008 01:45:21 +0200 Subject: i915: Fix for s8_z24 textures not being shown --- src/gallium/drivers/i915simple/i915_state_sampler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c index fbdc1a3b68..24440843f3 100644 --- a/src/gallium/drivers/i915simple/i915_state_sampler.c +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -212,7 +212,7 @@ translate_texture_format(enum pipe_format pipeFormat) return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); #endif case PIPE_FORMAT_S8Z24_UNORM: - return (MAPSURF_32BIT | MT_32BIT_xL824); + return (MAPSURF_32BIT | MT_32BIT_xI824); default: debug_printf("i915: translate_texture_format() bad image format %x\n", pipeFormat); -- cgit v1.2.3 From 28ac7d37fe9576428417351bf1acd180b179502a Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 18 Jun 2008 08:51:38 +0200 Subject: gallium: Remove PIPE_FORMAT_A8UB8UG8SR8S_NORM definition. --- src/gallium/include/pipe/p_format.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index e7d63350ef..579fdb2957 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -361,7 +361,6 @@ enum pipe_format { PIPE_FORMAT_R8G8B8X8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), /* mixed formats */ - PIPE_FORMAT_A8UB8UG8SR8S_NORM = _PIPE_FORMAT_MIXED( _PIPE_FORMAT_ABGR, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 ), PIPE_FORMAT_X8UB8UG8SR8S_NORM = _PIPE_FORMAT_MIXED( _PIPE_FORMAT_1BGR, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 ), PIPE_FORMAT_B6UG5SR5S_NORM = _PIPE_FORMAT_MIXED( _PIPE_FORMAT_BGR1, 6, 5, 5, 0, 0, 1, 1, 0, 1, 0 ), -- cgit v1.2.3 From 1496bba42904cbc9b827816b7924fa930661c22a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 17 Jun 2008 14:28:07 -0600 Subject: egl: call st_get_proc_address() --- src/gallium/winsys/egl_xlib/egl_xlib.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 7bef46d560..194bf2842a 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -210,11 +210,7 @@ xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) static _EGLProc xlib_eglGetProcAddress(const char *procname) { - /* XXX for each supported API, evaluate GetProcAddress(name) */ - /* - return _glapi_get_proc_address(procname); - */ - return NULL; + return (_EGLProc) st_get_proc_address(procname); } -- cgit v1.2.3 From 51f24ef5bae3fa1f1ae6172fd5c5e6235f3f6857 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 17 Jun 2008 16:58:22 -0600 Subject: gallium: remove duplicated u_mm.c in file list --- src/gallium/auxiliary/util/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index 05bc43131a..db3d810a2e 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -15,8 +15,7 @@ C_SOURCES = \ u_mm.c \ u_simple_shaders.c \ u_snprintf.c \ - u_time.c \ - u_mm.c + u_time.c include ../../Makefile.template -- cgit v1.2.3 From 0cf79316d076d598f143b68f61308df9ddaf5e9a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 18 Jun 2008 09:21:09 -0600 Subject: egl: omit libmesa.a glapi.c from library --- src/gallium/winsys/egl_xlib/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile index d5595b819a..76f1b56da4 100644 --- a/src/gallium/winsys/egl_xlib/Makefile +++ b/src/gallium/winsys/egl_xlib/Makefile @@ -28,9 +28,13 @@ WINSYS_OBJECTS = $(WINSYS_SOURCES:.c=.o) LIBS = \ $(GALLIUM_DRIVERS) \ + $(GALLIUM_AUXILIARIES) + +# XXX temporary (should create a separate lib with the GL API funcs and +# mesa code, as done for ES 1.x, 2.x, OpenVG, etc) +UNUSED_LIBS = \ $(TOP)/src/mesa/libglapi.a \ $(TOP)/src/mesa/libmesa.a \ - $(GALLIUM_AUXILIARIES) LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1 @@ -56,7 +60,7 @@ $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(WINSYS_OBJECTS) $(LIBS) -noprefix \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) \ - --start-group $(LIBS) --end-group + --whole-archive $(LIBS) --no-whole-archive depend: $(ALL_SOURCES) -- cgit v1.2.3 From 7d7f3e2c9451b2233c196d82d523c50b5d2616cc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 18 Jun 2008 14:50:35 -0600 Subject: gallium: split long prims into chunks with an even number of vertices This fixes culling "parity" errors when splitting long tri strips. Splitting strips into chunks with an odd number of vertices causes front/back-face orientation to get reversed and upsets culling. --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c | 9 +++++++++ src/gallium/auxiliary/draw/draw_pt_varray.c | 4 ++++ 2 files changed, 13 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 5ce3aba2a2..fdf9b6fe6a 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -193,6 +193,15 @@ static void fse_prepare( struct draw_pt_middle_end *middle, *max_vertices = (draw->render->max_vertex_buffer_bytes / (vinfo->size * 4)); + /* Return an even number of verts. + * This prevents "parity" errors when splitting long triangle strips which + * can lead to front/back culling mix-ups. + * Every other triangle in a strip has an alternate front/back orientation + * so splitting at an odd position can cause the orientation of subsequent + * triangles to get reversed. + */ + *max_vertices = *max_vertices & ~1; + /* Probably need to do this somewhere (or fix exec shader not to * need it): */ diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index 4479963db1..2cc08a9e93 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -147,6 +147,10 @@ static void varray_prepare(struct draw_pt_front_end *frontend, varray->middle = middle; middle->prepare(middle, varray->output_prim, opt, &varray->driver_fetch_max ); + + /* check that the max is even */ + assert((varray->driver_fetch_max & 1) == 0); + varray->fetch_max = MIN2(FETCH_MAX, varray->driver_fetch_max); } -- cgit v1.2.3 From f1401385587882bb9d18a5f5b01dcbb71ddf0a2f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 18 Jun 2008 15:08:19 -0600 Subject: gallium: additional fixes to ensure even number of vertices per buffer --- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 3 +++ src/gallium/auxiliary/draw/draw_pt_emit.c | 3 +++ src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 9 +++++++++ src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 3 +++ 4 files changed, 18 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 10a1f7df79..a6fde77a0e 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -390,6 +390,9 @@ vbuf_alloc_vertices( struct vbuf_stage *vbuf ) /* Allocate a new vertex buffer */ vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; + /* even number */ + vbuf->max_vertices = vbuf->max_vertices & ~1; + /* Must always succeed -- driver gives us a * 'max_vertex_buffer_bytes' which it guarantees it can allocate, * and it will flush itself if necessary to do so. If this does diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index a02f1f46fe..40f05cb9e0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -143,6 +143,9 @@ void draw_pt_emit_prepare( struct pt_emit *emit, *max_vertices = (draw->render->max_vertex_buffer_bytes / (vinfo->size * 4)); + + /* even number */ + *max_vertices = *max_vertices & ~1; } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 083ce105bf..4a1f3b0953 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -200,6 +200,15 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, *max_vertices = (draw->render->max_vertex_buffer_bytes / (vinfo->size * 4)); + + /* Return an even number of verts. + * This prevents "parity" errors when splitting long triangle strips which + * can lead to front/back culling mix-ups. + * Every other triangle in a strip has an alternate front/back orientation + * so splitting at an odd position can cause the orientation of subsequent + * triangles to get reversed. + */ + *max_vertices = *max_vertices & ~1; } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 25118712a6..0aec4b71ba 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -99,6 +99,9 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, *max_vertices = DRAW_PIPE_MAX_VERTICES; } + /* return even number */ + *max_vertices = *max_vertices & ~1; + /* No need to prepare the shader. */ vs->prepare(vs, draw); -- cgit v1.2.3 From aa816d114ee90d0c5b861f622c0063b54f7eb612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 12 Jun 2008 23:34:21 +0900 Subject: draw: Fix MSVC integer size conversion warning. --- src/gallium/auxiliary/draw/draw_pt_varray.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index 2cc08a9e93..46e722a154 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -172,7 +172,7 @@ static void varray_destroy(struct draw_pt_front_end *frontend) struct draw_pt_front_end *draw_pt_varray(struct draw_context *draw) { - unsigned i; + ushort i; struct varray_frontend *varray = CALLOC_STRUCT(varray_frontend); if (varray == NULL) return NULL; -- cgit v1.2.3 From b440cea343b007ca97edb2cd4e1e6150c989417b Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 19 Jun 2008 14:06:28 +0200 Subject: util: Add missing format names. --- src/gallium/auxiliary/util/p_debug.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index e4de12167a..9d56f8bfab 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -366,6 +366,7 @@ static const struct debug_named_value pipe_format_names[] = { DEBUG_NAMED_VALUE(PIPE_FORMAT_A1R5G5B5_UNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_A4R4G4B4_UNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_R5G6B5_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A2B10G10R10_UNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_UNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_UNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_I8_UNORM), @@ -436,6 +437,9 @@ static const struct debug_named_value pipe_format_names[] = { DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_B6G5R5_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8B8G8R8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_X8B8G8R8_SNORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SSCALED), DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SSCALED), DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SSCALED), @@ -446,6 +450,8 @@ static const struct debug_named_value pipe_format_names[] = { DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SRGB), DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SRGB), DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_X8UB8UG8SR8S_NORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_B6UG5SR5S_NORM), DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGB), DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA), DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA), -- cgit v1.2.3 From c5bf215b1b955c8dafeae84a5f526052fd2e0256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 19 Jun 2008 21:16:16 +0900 Subject: gallium: Add extra parenthesis as advised by gcc. --- src/gallium/auxiliary/util/p_debug_mem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c index 51dbd0a710..ed18c6540e 100644 --- a/src/gallium/auxiliary/util/p_debug_mem.c +++ b/src/gallium/auxiliary/util/p_debug_mem.c @@ -263,8 +263,8 @@ debug_memory_end(unsigned long start_no) void *ptr; hdr = LIST_ENTRY(struct debug_memory_header, entry, head); ptr = data_from_header(hdr); - if(start_no <= hdr->no && hdr->no < last_no || - last_no < start_no && (hdr->no < last_no || start_no <= hdr->no)) { + if((start_no <= hdr->no && hdr->no < last_no) || + (last_no < start_no && (hdr->no < last_no || start_no <= hdr->no))) { debug_printf("%s:%u:%s: %u bytes at %p not freed\n", hdr->file, hdr->line, hdr->function, hdr->size, ptr); -- cgit v1.2.3 From 6cbc2734d19567afeaa6c5d93149ef87b08cd167 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 19 Jun 2008 14:42:17 +0200 Subject: i915: Refractored and clean up i915_texture.c --- src/gallium/drivers/i915simple/i915_texture.c | 269 ++++++++++++++------------ 1 file changed, 141 insertions(+), 128 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index d591b09e3c..09518fafe7 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -42,12 +42,58 @@ #include "i915_debug.h" #include "i915_screen.h" +/* + * Helper function and arrays + */ + +/** + * Initial offset for Cube map. + */ +static const int initial_offsets[6][2] = { + {0, 0}, + {0, 2}, + {1, 0}, + {1, 2}, + {1, 1}, + {1, 3} +}; + +/** + * Step offsets for Cube map. + */ +static const int step_offsets[6][2] = { + {0, 2}, + {0, 2}, + {-1, 2}, + {-1, 2}, + {-1, 1}, + {-1, 1} +}; static unsigned minify( unsigned d ) { return MAX2(1, d>>1); } +static unsigned +power_of_two(unsigned x) +{ + unsigned value = 1; + while (value <= x) + value = value << 1; + return value; +} + +static unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + + +/* + * More advanced helper funcs + */ static void @@ -86,7 +132,6 @@ i915_miptree_set_level_info(struct i915_texture *tex, tex->image_offset[level][0] = 0; } - static void i915_miptree_set_image_offset(struct i915_texture *tex, unsigned level, unsigned img, unsigned x, unsigned y) @@ -97,27 +142,17 @@ i915_miptree_set_image_offset(struct i915_texture *tex, assert(img < tex->nr_images[level]); tex->image_offset[level][img] = (x + y * tex->pitch); - /* - DBG("%s level %d img %d pos %d,%d image_offset %x\n", + printf("%s level %d img %d pos %d,%d image_offset %x\n", __FUNCTION__, level, img, x, y, tex->image_offset[level][img]); */ } -static unsigned -power_of_two(unsigned x) -{ - unsigned value = 1; - while (value <= x) - value = value << 1; - return value; -} -static unsigned -round_up(unsigned n, unsigned multiple) -{ - return (n + multiple - 1) & ~(multiple - 1); -} +/* + * Layout functions + */ + /** * Special case to deal with display targets. @@ -144,11 +179,11 @@ i915_displaytarget_layout(struct i915_texture *tex) tex->total_height = tex->base.height[0]; } -/* + /* printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, tex->base.width[0], tex->base.height[0], pt->cpp, tex->pitch, tex->total_height, tex->pitch * tex->total_height * 4); -*/ + */ return 1; } @@ -221,25 +256,93 @@ i945_miptree_layout_2d( struct i915_texture *tex ) } } +static void +i945_miptree_layout_cube(struct i915_texture *tex) +{ + struct pipe_texture *pt = &tex->base; + unsigned level; -static const int initial_offsets[6][2] = { - {0, 0}, - {0, 2}, - {1, 0}, - {1, 2}, - {1, 1}, - {1, 3} -}; + const unsigned dim = pt->width[0]; + unsigned face; + unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; -static const int step_offsets[6][2] = { - {0, 2}, - {0, 2}, - {-1, 2}, - {-1, 2}, - {-1, 1}, - {-1, 1} -}; + assert(lvlWidth == lvlHeight); /* cubemap images are square */ + + /* Depending on the size of the largest images, pitch can be + * determined either by the old-style packing of cubemap faces, + * or the final row of 4x4, 2x2 and 1x1 faces below this. + */ + if (dim > 32) + tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; + else + tex->pitch = 14 * 8; + + tex->total_height = dim * 4 + 4; + + /* Set all the levels to effectively occupy the whole rectangular region. + */ + for (level = 0; level <= pt->last_level; level++) { + i915_miptree_set_level_info(tex, level, 6, 0, 0, lvlWidth, lvlHeight, 1); + lvlWidth /= 2; + lvlHeight /= 2; + } + for (face = 0; face < 6; face++) { + unsigned x = initial_offsets[face][0] * dim; + unsigned y = initial_offsets[face][1] * dim; + unsigned d = dim; + + if (dim == 4 && face >= 4) { + y = tex->total_height - 4; + x = (face - 4) * 8; + } + else if (dim < 4 && (face > 0)) { + y = tex->total_height - 4; + x = face * 8; + } + + for (level = 0; level <= pt->last_level; level++) { + i915_miptree_set_image_offset(tex, level, face, x, y); + + d >>= 1; + + switch (d) { + case 4: + switch (face) { + case PIPE_TEX_FACE_POS_X: + case PIPE_TEX_FACE_NEG_X: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + case PIPE_TEX_FACE_POS_Y: + case PIPE_TEX_FACE_NEG_Y: + y += 12; + x -= 8; + break; + case PIPE_TEX_FACE_POS_Z: + case PIPE_TEX_FACE_NEG_Z: + y = tex->total_height - 4; + x = (face - 4) * 8; + break; + } + + case 2: + y = tex->total_height - 4; + x = 16 + face * 8; + break; + + case 1: + x += 48; + break; + + default: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + } + } + } +} static boolean i915_miptree_layout(struct i915_texture * tex) @@ -372,99 +475,15 @@ i945_miptree_layout(struct i915_texture * tex) unsigned level; switch (pt->target) { - case PIPE_TEXTURE_CUBE:{ - const unsigned dim = pt->width[0]; - unsigned face; - unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; - - assert(lvlWidth == lvlHeight); /* cubemap images are square */ - - /* Depending on the size of the largest images, pitch can be - * determined either by the old-style packing of cubemap faces, - * or the final row of 4x4, 2x2 and 1x1 faces below this. - */ - if (dim > 32) - tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; - else - tex->pitch = 14 * 8; - - tex->total_height = dim * 4 + 4; - - /* Set all the levels to effectively occupy the whole rectangular region. - */ - for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_level_info(tex, level, 6, - 0, 0, - lvlWidth, lvlHeight, 1); - lvlWidth /= 2; - lvlHeight /= 2; - } - - - for (face = 0; face < 6; face++) { - unsigned x = initial_offsets[face][0] * dim; - unsigned y = initial_offsets[face][1] * dim; - unsigned d = dim; - - if (dim == 4 && face >= 4) { - y = tex->total_height - 4; - x = (face - 4) * 8; - } - else if (dim < 4 && (face > 0)) { - y = tex->total_height - 4; - x = face * 8; - } - - for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_image_offset(tex, level, face, x, y); - - d >>= 1; - - switch (d) { - case 4: - switch (face) { - case PIPE_TEX_FACE_POS_X: - case PIPE_TEX_FACE_NEG_X: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - case PIPE_TEX_FACE_POS_Y: - case PIPE_TEX_FACE_NEG_Y: - y += 12; - x -= 8; - break; - case PIPE_TEX_FACE_POS_Z: - case PIPE_TEX_FACE_NEG_Z: - y = tex->total_height - 4; - x = (face - 4) * 8; - break; - } - - case 2: - y = tex->total_height - 4; - x = 16 + face * 8; - break; - - case 1: - x += 48; - break; - - default: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - } - } - } - break; - } + case PIPE_TEXTURE_CUBE: + i945_miptree_layout_cube(tex); + break; case PIPE_TEXTURE_3D:{ unsigned width = pt->width[0]; unsigned height = pt->height[0]; unsigned depth = pt->depth[0]; unsigned pack_x_pitch, pack_x_nr; unsigned pack_y_pitch; - unsigned level; tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; tex->total_height = 0; @@ -602,11 +621,6 @@ i915_texture_release(struct pipe_screen *screen, *pt = NULL; } - - -/* - * XXX note: same as code in sp_surface.c - */ static struct pipe_surface * i915_get_tex_surface(struct pipe_screen *screen, struct pipe_texture *pt, @@ -631,7 +645,7 @@ i915_get_tex_surface(struct pipe_screen *screen, assert(zslice == 0); } - ps = CALLOC_STRUCT(pipe_surface);//ws->surface_alloc(ws); + ps = CALLOC_STRUCT(pipe_surface); if (ps) { ps->refcount = 1; ps->winsys = ws; @@ -649,7 +663,6 @@ i915_get_tex_surface(struct pipe_screen *screen, return ps; } - void i915_init_texture_functions(struct i915_context *i915) { -- cgit v1.2.3 From 6fbfcf922210ddf29b73290557f9d40171b09d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 19 Jun 2008 22:57:33 +0900 Subject: gallium: Handle malloc failure. --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index 6689c3f1fb..13b8c2e5bf 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -165,9 +165,17 @@ tgsi_exec_machine_bind_shader( declarations = (struct tgsi_full_declaration *) MALLOC( maxDeclarations * sizeof(struct tgsi_full_declaration) ); + if (!declarations) { + return; + } + instructions = (struct tgsi_full_instruction *) MALLOC( maxInstructions * sizeof(struct tgsi_full_instruction) ); + if (!instructions) { + FREE( declarations ); + return; + } while( !tgsi_parse_end_of_tokens( &parse ) ) { uint pointer = parse.Position; -- cgit v1.2.3 From 8d0329fb6af657a53cb010a3d7a8f4282e2715b8 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 19 Jun 2008 17:09:09 +0200 Subject: i915: Fixed cubemap layouts Apprently we shouldn't do all the advanced layout operation for none compressed formats. The compressed code was also broken, its currently disabled, but should be fixed once i915simple starts to support compressed formats. --- src/gallium/drivers/i915simple/i915_texture.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 09518fafe7..9cd32e3919 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -142,6 +142,7 @@ i915_miptree_set_image_offset(struct i915_texture *tex, assert(img < tex->nr_images[level]); tex->image_offset[level][img] = (x + y * tex->pitch); + /* printf("%s level %d img %d pos %d,%d image_offset %x\n", __FUNCTION__, level, img, x, y, tex->image_offset[level][img]); @@ -266,9 +267,17 @@ i945_miptree_layout_cube(struct i915_texture *tex) unsigned face; unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; + /* + printf("%s %i, %i\n", __FUNCTION__, pt->width[0], pt->height[0]); + */ + assert(lvlWidth == lvlHeight); /* cubemap images are square */ - /* Depending on the size of the largest images, pitch can be + /* + * XXX Should only be used for compressed formats. But lets + * keep this code active just in case. + * + * Depending on the size of the largest images, pitch can be * determined either by the old-style packing of cubemap faces, * or the final row of 4x4, 2x2 and 1x1 faces below this. */ @@ -277,6 +286,9 @@ i945_miptree_layout_cube(struct i915_texture *tex) else tex->pitch = 14 * 8; + /* + * XXX The 4 is only needed for compressed formats. See above. + */ tex->total_height = dim * 4 + 4; /* Set all the levels to effectively occupy the whole rectangular region. @@ -292,6 +304,7 @@ i945_miptree_layout_cube(struct i915_texture *tex) unsigned y = initial_offsets[face][1] * dim; unsigned d = dim; +#if 0 /* Fix and enable this code for compressed formats */ if (dim == 4 && face >= 4) { y = tex->total_height - 4; x = (face - 4) * 8; @@ -300,12 +313,14 @@ i945_miptree_layout_cube(struct i915_texture *tex) y = tex->total_height - 4; x = face * 8; } +#endif for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_image_offset(tex, level, face, x, y); d >>= 1; +#if 0 /* Fix and enable this code for compressed formats */ switch (d) { case 4: switch (face) { @@ -325,7 +340,6 @@ i945_miptree_layout_cube(struct i915_texture *tex) x = (face - 4) * 8; break; } - case 2: y = tex->total_height - 4; x = 16 + face * 8; @@ -334,12 +348,14 @@ i945_miptree_layout_cube(struct i915_texture *tex) case 1: x += 48; break; - default: +#endif x += step_offsets[face][0] * d; y += step_offsets[face][1] * d; +#if 0 break; } +#endif } } } -- cgit v1.2.3 From 064001dbe7fd6cbb6bd5c91bdf7f0831b9c351a9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 19 Jun 2008 16:12:17 -0600 Subject: egl: use dlsym() to try to identify APIs --- src/gallium/winsys/egl_xlib/egl_xlib.c | 47 ++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 194bf2842a..85fc83a4dc 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -32,6 +32,7 @@ */ +#include #include #include "pipe/p_compiler.h" @@ -202,7 +203,6 @@ xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy, static EGLBoolean xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy) { - return EGL_TRUE; } @@ -342,6 +342,10 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, /* API-dependent context creation */ switch (ctx->Base.ClientAPI) { + case EGL_OPENGL_ES_API: + _eglLog(_EGL_DEBUG, "Create Context for ES version %d\n", + ctx->Base.ClientVersion); + /* fall-through */ case EGL_OPENGL_API: /* create a softpipe context */ ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL); @@ -372,6 +376,8 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx) else { /* API-dependent clean-up */ switch (context->Base.ClientAPI) { + case EGL_OPENGL_ES_API: + /* fall-through */ case EGL_OPENGL_API: st_destroy_context(context->Context); break; @@ -554,6 +560,36 @@ xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) } +/** + * Determine which API(s) is(are) present by looking for some specific + * global symbols. + */ +static EGLint +find_supported_apis(void) +{ + EGLint mask = 0; + void *handle; + + handle = dlopen(NULL, 0); + + if (dlsym(handle, "st_api_OpenGL_ES1")) + mask |= EGL_OPENGL_ES_BIT; + + if (dlsym(handle, "st_api_OpenGL_ES2")) + mask |= EGL_OPENGL_ES2_BIT; + + if (dlsym(handle, "st_api_OpenGL")) + mask |= EGL_OPENGL_BIT; + + if (dlsym(handle, "st_api_OpenVG")) + mask |= EGL_OPENVG_BIT; + + dlclose(handle); + + return mask; +} + + /** * This is the main entrypoint into the driver. * Called by libEGL to instantiate an _EGLDriver object. @@ -584,7 +620,14 @@ _eglMain(_EGLDisplay *dpy, const char *args) xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; - xdrv->Base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; + xdrv->Base.ClientAPIsMask = find_supported_apis(); + if (xdrv->Base.ClientAPIsMask == 0x0) { + /* the app isn't directly linked with any EGL-supprted APIs + * (such as libGLESv2.so) so use an EGL utility to see what + * APIs might be loaded dynamically on this system. + */ + xdrv->Base.ClientAPIsMask = _eglFindAPIs(); + } xdrv->Base.Name = "Xlib/softpipe"; -- cgit v1.2.3 From a87e717d0d302bc376eff29d17d35f1314ff1a57 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 20 Jun 2008 10:20:47 -0600 Subject: egl: added null ptr checks --- src/gallium/winsys/egl_xlib/egl_xlib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 85fc83a4dc..eeb15e30a9 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -413,7 +413,10 @@ xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, (draw_surf ? draw_surf->Framebuffer : NULL), (read_surf ? read_surf->Framebuffer : NULL)); - check_and_update_buffer_size(draw_surf); + if (draw_surf) + check_and_update_buffer_size(draw_surf); + if (read_surf && read_surf != draw_surf) + check_and_update_buffer_size(draw_surf); return EGL_TRUE; } -- cgit v1.2.3 From 78791d1065c93694a105d4c2cdaee7678a69213a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 20 Jun 2008 14:30:21 -0600 Subject: egl: added cpp assertions/sanity checks --- src/gallium/winsys/egl_xlib/sw_winsys.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index fd0cb9fb12..28cca9e581 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -194,6 +194,8 @@ surface_alloc_storage(struct pipe_winsys *winsys, surf->pitch = round_up(width, alignment / surf->cpp); surf->usage = flags; + assert(surf->cpp >= 1); + assert(surf->cpp <= 16); assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, -- cgit v1.2.3 From f38bb109694f2879036c54c97c1c69ea2fecd6c8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 20 Jun 2008 15:58:19 -0600 Subject: gallium: fix some surface usage bugs When a surface is created with GPU_WRITE that really means "GPU render" and that can involve reads (blending). Set surface usage to PIPE_BUFFER_USAGE_CPU_READ + WRITE. Fixes progs/demos/lodbias demo. Also, mark texture as 'modified' when mapped for writing so that the tile cache can know when to freshen a cached tile. Fixes glTexSubImage2D(). --- src/gallium/drivers/softpipe/sp_texture.c | 11 +++++++++-- src/gallium/drivers/softpipe/sp_texture.h | 2 ++ src/gallium/drivers/softpipe/sp_tile_cache.c | 10 ++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 1d7a1fffe4..ef8c5bd6b0 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -207,12 +207,19 @@ softpipe_get_tex_surface(struct pipe_screen *screen, * done with the CPU. Let's adjust the flags to take that into * account. */ - if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) - ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE; + if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) { + /* GPU_WRITE means "render" and that can involve reads (blending) */ + ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ; + } if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; + if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_WRITE)) { + /* Mark the surface as dirty. The tile cache will look for this. */ + spt->modified = TRUE; + } pipe_texture_reference(&ps->texture, pt); ps->face = face; diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index 779a9d8fc9..0e1017632c 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -47,6 +47,8 @@ struct softpipe_texture /* The data is held here: */ struct pipe_buffer *buffer; + + boolean modified; }; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 0e4c8c41ee..2d5d2b50f5 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -37,6 +37,7 @@ #include "util/p_tile.h" #include "sp_context.h" #include "sp_surface.h" +#include "sp_texture.h" #include "sp_tile_cache.h" #define NUM_ENTRIES 32 @@ -506,6 +507,15 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, face, level); struct softpipe_cached_tile *tile = tc->entries + pos; + if (tc->texture) { + struct softpipe_texture *spt = softpipe_texture(tc->texture); + if (spt->modified) { + /* texture was modified, force a cache reload */ + tile->x = -1; + spt->modified = FALSE; + } + } + if (tile_x != tile->x || tile_y != tile->y || z != tile->z || -- cgit v1.2.3 From be4259b06cbb2b4c1d8a2dacc19313a30fa909d8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 20 Jun 2008 17:28:42 -0600 Subject: gallium: fix invalid call to draw_set_mapped_constant_buffer() We were indexing sp_constants[i] outside the loop so i was 2. Replace i with PIPE_SHADER_VERTEX. Also, replace magic '2' with PIPE_SHADER_TYPES in a few places. --- src/gallium/drivers/softpipe/sp_context.h | 2 +- src/gallium/drivers/softpipe/sp_draw_arrays.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 62eabfb30e..078886f93c 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -69,7 +69,7 @@ struct softpipe_context { struct pipe_blend_color blend_color; struct pipe_clip_state clip; - struct pipe_constant_buffer constants[2]; + struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index d4d5fa744f..12b44a8211 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -47,7 +47,7 @@ softpipe_map_constant_buffers(struct softpipe_context *sp) { struct pipe_winsys *ws = sp->pipe.winsys; uint i; - for (i = 0; i < 2; i++) { + for (i = 0; i < PIPE_SHADER_TYPES; i++) { if (sp->constants[i].size) sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, PIPE_BUFFER_USAGE_CPU_READ); @@ -55,7 +55,7 @@ softpipe_map_constant_buffers(struct softpipe_context *sp) draw_set_mapped_constant_buffer(sp->draw, sp->mapped_constants[PIPE_SHADER_VERTEX], - sp->constants[i].size); + sp->constants[PIPE_SHADER_VERTEX].size); } static void -- cgit v1.2.3 From e2c3f06e9649b5b87fc9adbca7d1f07841bba895 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 22 Jun 2008 13:14:29 +0100 Subject: draw: fix non-i386 builds --- src/gallium/auxiliary/draw/draw_vs_aos_machine.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c index dcb6c2c8d4..6a54917ae3 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c @@ -28,7 +28,6 @@ #include "pipe/p_config.h" -#ifdef PIPE_ARCH_X86 #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" @@ -39,6 +38,8 @@ #include "draw_vs_aos.h" #include "draw_vertex.h" +#ifdef PIPE_ARCH_X86 + #include "rtasm/rtasm_x86sse.h" @@ -298,6 +299,25 @@ struct aos_machine *draw_vs_aos_machine( void ) return machine; } +#else + +void draw_vs_aos_machine_viewport( struct aos_machine *machine, + const struct pipe_viewport_state *viewport ) +{ +} + +void draw_vs_aos_machine_constants( struct aos_machine *machine, + const float (*constants)[4] ) +{ +} + +void draw_vs_aos_machine_destroy( struct aos_machine *machine ) +{ +} +struct aos_machine *draw_vs_aos_machine( void ) +{ + return NULL; +} #endif -- cgit v1.2.3 From d40ff294510236faff4bb9a58b81282705b98562 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 19 Jun 2008 20:28:20 +0200 Subject: i915: Removed level_offset from i915_texture All offsets are now on image_offset. --- src/gallium/drivers/i915simple/i915_context.h | 4 ---- src/gallium/drivers/i915simple/i915_texture.c | 27 ++++++++++++--------------- 2 files changed, 12 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 892a88fd2c..9e02f78714 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -202,10 +202,6 @@ struct i915_texture { */ unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ - /* Includes image offset tables: - */ - unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; - /* The data is held here: */ struct pipe_buffer *buffer; diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 9cd32e3919..d9b33df1d5 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -100,7 +100,7 @@ static void i915_miptree_set_level_info(struct i915_texture *tex, unsigned level, unsigned nr_images, - unsigned x, unsigned y, unsigned w, unsigned h, unsigned d) + unsigned w, unsigned h, unsigned d) { struct pipe_texture *pt = &tex->base; @@ -110,7 +110,6 @@ i915_miptree_set_level_info(struct i915_texture *tex, pt->height[level] = h; pt->depth[level] = d; - tex->level_offset[level] = (x + y * tex->pitch) * pt->cpp; tex->nr_images[level] = nr_images; /* @@ -166,7 +165,7 @@ i915_displaytarget_layout(struct i915_texture *tex) if (pt->last_level > 0 || pt->cpp != 4) return 0; - i915_miptree_set_level_info( tex, 0, 1, 0, 0, + i915_miptree_set_level_info( tex, 0, 1, tex->base.width[0], tex->base.height[0], 1 ); @@ -230,7 +229,8 @@ i945_miptree_layout_2d( struct i915_texture *tex ) for (level = 0; level <= pt->last_level; level++) { unsigned img_height; - i915_miptree_set_level_info(tex, level, 1, x, y, width, height, 1); + i915_miptree_set_level_info(tex, level, 1, width, height, 1); + i915_miptree_set_image_offset(tex, level, 0, x, y); if (pt->compressed) img_height = MAX2(1, height/4); @@ -294,7 +294,7 @@ i945_miptree_layout_cube(struct i915_texture *tex) /* Set all the levels to effectively occupy the whole rectangular region. */ for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_level_info(tex, level, 6, 0, 0, lvlWidth, lvlHeight, 1); + i915_miptree_set_level_info(tex, level, 6, lvlWidth, lvlHeight, 1); lvlWidth /= 2; lvlHeight /= 2; } @@ -380,8 +380,6 @@ i915_miptree_layout(struct i915_texture * tex) for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 6, - 0, 0, - /*OLD: tex->pitch, tex->total_height,*/ lvlWidth, lvlHeight, 1); lvlWidth /= 2; @@ -416,7 +414,7 @@ i915_miptree_layout(struct i915_texture * tex) */ for (level = 0; level <= MAX2(8, pt->last_level); level++) { - i915_miptree_set_level_info(tex, level, depth, 0, tex->total_height, + i915_miptree_set_level_info(tex, level, depth, width, height, depth); @@ -458,8 +456,9 @@ i915_miptree_layout(struct i915_texture * tex) for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 1, - 0, tex->total_height, width, height, 1); + i915_miptree_set_image_offset(tex, level, 0, + 0, tex->total_height); if (pt->compressed) img_height = MAX2(1, height / 4); @@ -515,12 +514,11 @@ i945_miptree_layout(struct i915_texture * tex) unsigned q, j; i915_miptree_set_level_info(tex, level, nr_images, - 0, tex->total_height, width, height, depth); for (q = 0; q < nr_images;) { for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { - i915_miptree_set_image_offset(tex, level, q, x, y); + i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_height); x += pack_x_pitch; } @@ -648,15 +646,14 @@ i915_get_tex_surface(struct pipe_screen *screen, struct pipe_surface *ps; unsigned offset; /* in bytes */ - offset = tex->level_offset[level]; - if (pt->target == PIPE_TEXTURE_CUBE) { - offset += tex->image_offset[level][face] * pt->cpp; + offset = tex->image_offset[level][face] * pt->cpp; } else if (pt->target == PIPE_TEXTURE_3D) { - offset += tex->image_offset[level][zslice] * pt->cpp; + offset = tex->image_offset[level][zslice] * pt->cpp; } else { + offset = tex->image_offset[level][0] * pt->cpp; assert(face == 0); assert(zslice == 0); } -- cgit v1.2.3 From f08da6b8214f1bf1d4a33e19dac4eeb155302481 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 23 Jun 2008 12:31:46 +0200 Subject: gallium: Fix warning in u_draw_quad.h --- src/gallium/auxiliary/util/u_draw_quad.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h index 5b6539a99c..ec4862ead3 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.h +++ b/src/gallium/auxiliary/util/u_draw_quad.h @@ -33,6 +33,7 @@ extern "C" { #endif +struct pipe_buffer; extern void util_draw_vertex_buffer(struct pipe_context *pipe, -- cgit v1.2.3 From 708bb35194e16bf7aaf5cd676f572b7200a156d1 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 23 Jun 2008 16:01:41 +0200 Subject: util: Blit can now copy from texture to surface --- src/gallium/auxiliary/util/u_blit.c | 101 ++++++++++++++++++++++++++++++++++++ src/gallium/auxiliary/util/u_blit.h | 14 +++-- 2 files changed, 112 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 7b9415d49a..28513f54e6 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -362,3 +362,104 @@ util_blit_pixels(struct blit_state *ctx, screen->texture_release(screen, &tex); } +/** + * Copy pixel block from src texture to dst surface. + * Overlapping regions are acceptable. + * + * XXX Should support selection of level. + * XXX need some control over blitting Z and/or stencil. + */ +void +util_blit_pixels_tex(struct blit_state *ctx, + struct pipe_texture *tex, + int srcX0, int srcY0, + int srcX1, int srcY1, + struct pipe_surface *dst, + int dstX0, int dstY0, + int dstX1, int dstY1, + float z, uint filter) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_framebuffer_state fb; + const int srcLeft = MIN2(srcX0, srcX1); + const int srcTop = MIN2(srcY0, srcY1); + + assert(filter == PIPE_TEX_MIPFILTER_NEAREST || + filter == PIPE_TEX_MIPFILTER_LINEAR); + + if (srcLeft != srcX0) { + /* left-right flip */ + int tmp = dstX0; + dstX0 = dstX1; + dstX1 = tmp; + } + + if (srcTop != srcY0) { + /* up-down flip */ + int tmp = dstY0; + dstY0 = dstY1; + dstY1 = tmp; + } + + assert(screen->is_format_supported(screen, dst->format, PIPE_SURFACE)); + + /* save state (restored below) */ + cso_save_blend(ctx->cso); + cso_save_depth_stencil_alpha(ctx->cso); + cso_save_rasterizer(ctx->cso); + cso_save_samplers(ctx->cso); + cso_save_sampler_textures(ctx->cso); + cso_save_framebuffer(ctx->cso); + cso_save_fragment_shader(ctx->cso); + cso_save_vertex_shader(ctx->cso); + cso_save_viewport(ctx->cso); + + /* set misc state we care about */ + cso_set_blend(ctx->cso, &ctx->blend); + cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); + cso_set_rasterizer(ctx->cso, &ctx->rasterizer); + cso_set_viewport(ctx->cso, &ctx->viewport); + + /* sampler */ + ctx->sampler.min_img_filter = filter; + ctx->sampler.mag_img_filter = filter; + cso_single_sampler(ctx->cso, 0, &ctx->sampler); + cso_single_sampler_done(ctx->cso); + + /* texture */ + cso_set_sampler_textures(ctx->cso, 1, &tex); + + /* shaders */ + cso_set_fragment_shader_handle(ctx->cso, ctx->fs); + cso_set_vertex_shader_handle(ctx->cso, ctx->vs); + + /* drawing dest */ + memset(&fb, 0, sizeof(fb)); + fb.width = dst->width; + fb.height = dst->height; + fb.num_cbufs = 1; + fb.cbufs[0] = dst; + cso_set_framebuffer(ctx->cso, &fb); + + /* draw quad */ + setup_vertex_data(ctx, + (float) dstX0, (float) dstY0, + (float) dstX1, (float) dstY1, z); + + util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, + PIPE_PRIM_TRIANGLE_FAN, + 4, /* verts */ + 2); /* attribs/vert */ + + /* restore state we changed */ + cso_restore_blend(ctx->cso); + cso_restore_depth_stencil_alpha(ctx->cso); + cso_restore_rasterizer(ctx->cso); + cso_restore_samplers(ctx->cso); + cso_restore_sampler_textures(ctx->cso); + cso_restore_framebuffer(ctx->cso); + cso_restore_fragment_shader(ctx->cso); + cso_restore_vertex_shader(ctx->cso); + cso_restore_viewport(ctx->cso); +} diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h index 0ce9732e62..7d0406c104 100644 --- a/src/gallium/auxiliary/util/u_blit.h +++ b/src/gallium/auxiliary/util/u_blit.h @@ -42,15 +42,13 @@ struct cso_context; struct blit_state; + extern struct blit_state * util_create_blit(struct pipe_context *pipe, struct cso_context *cso); - extern void util_destroy_blit(struct blit_state *ctx); - - extern void util_blit_pixels(struct blit_state *ctx, struct pipe_surface *src, @@ -61,6 +59,16 @@ util_blit_pixels(struct blit_state *ctx, int dstX1, int dstY1, float z, uint filter); +extern void +util_blit_pixels_tex(struct blit_state *ctx, + struct pipe_texture *tex, + int srcX0, int srcY0, + int srcX1, int srcY1, + struct pipe_surface *dst, + int dstX0, int dstY0, + int dstX1, int dstY1, + float z, uint filter); + #ifdef __cplusplus } -- cgit v1.2.3 From 016dbb0cf395702cfad046f827e3cc4541ae5818 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 23 Jun 2008 08:35:41 -0600 Subject: gallium: added some assertions --- src/gallium/auxiliary/util/p_util.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_util.c b/src/gallium/auxiliary/util/p_util.c index 2a92f8e408..0e3f082b3e 100644 --- a/src/gallium/auxiliary/util/p_util.c +++ b/src/gallium/auxiliary/util/p_util.c @@ -53,6 +53,12 @@ pipe_copy_rect(ubyte * dst, { unsigned i; + assert(cpp > 0); + assert(src_x >= 0); + assert(src_y >= 0); + assert(dst_x >= 0); + assert(dst_y >= 0); + dst_pitch *= cpp; src_pitch *= cpp; dst += dst_x * cpp; -- cgit v1.2.3 From 92d48a4cb9481adc7abd7cdf9550fbf5a9c9613d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 23 Jun 2008 08:44:30 -0600 Subject: gallium: fix bad srcy coord if do_flip --- src/gallium/drivers/softpipe/sp_surface.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index 29a1e92416..acedebfcc5 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -35,7 +35,11 @@ -/* Assumes all values are within bounds -- no checking at this level - +/** + * Copy a rectangular region from one surface to another. + * Surfaces must have same bpp. + * + * Assumes all values are within bounds -- no checking at this level - * do it higher up if required. */ static void @@ -54,9 +58,11 @@ sp_surface_copy(struct pipe_context *pipe, src, PIPE_BUFFER_USAGE_CPU_READ ); - assert( dst->cpp == src->cpp ); - assert(src_map && dst_map); + assert(dst->cpp == src->cpp); + assert(src_map); + assert(dst_map); + /* If do_flip, invert src_y position and pass negative src stride */ pipe_copy_rect(dst_map, dst->cpp, dst->pitch, @@ -64,7 +70,7 @@ sp_surface_copy(struct pipe_context *pipe, width, height, src_map, do_flip ? -(int) src->pitch : src->pitch, - srcx, do_flip ? 1 - srcy - height : srcy); + srcx, do_flip ? src->height - 1 - srcy : srcy); pipe->screen->surface_unmap(pipe->screen, src); pipe->screen->surface_unmap(pipe->screen, dst); -- cgit v1.2.3 From f1601c2b75ca4c2223079f676cf796843b284df2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 23 Jun 2008 08:51:00 -0600 Subject: gallium: fix bad srcy coord if do_flip --- src/gallium/drivers/cell/ppu/cell_surface.c | 2 +- src/gallium/drivers/i915simple/i915_surface.c | 2 +- src/gallium/drivers/i965simple/brw_surface.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c index a35db0ef99..4a098101e1 100644 --- a/src/gallium/drivers/cell/ppu/cell_surface.c +++ b/src/gallium/drivers/cell/ppu/cell_surface.c @@ -76,7 +76,7 @@ cell_surface_copy(struct pipe_context *pipe, width, height, pipe_surface_map(src), do_flip ? -src->pitch : src->pitch, - srcx, do_flip ? 1 - srcy - height : srcy); + srcx, do_flip ? height - 1 - srcy : srcy); pipe_surface_unmap(src); pipe_surface_unmap(dst); diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index 98367ac073..1729ea26f5 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -66,7 +66,7 @@ i915_surface_copy(struct pipe_context *pipe, width, height, src_map, do_flip ? -(int) src->pitch : src->pitch, - srcx, do_flip ? 1 - srcy - height : srcy); + srcx, do_flip ? height - 1 - srcy : srcy); pipe->screen->surface_unmap(pipe->screen, src); pipe->screen->surface_unmap(pipe->screen, dst); diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index 3e3736b280..62d75bc251 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -66,7 +66,7 @@ brw_surface_copy(struct pipe_context *pipe, width, height, src_map, do_flip ? -(int) src->pitch : src->pitch, - srcx, do_flip ? 1 - srcy - height : srcy); + srcx, do_flip ? height - 1 - srcy : srcy); pipe->screen->surface_unmap(pipe->screen, src); pipe->screen->surface_unmap(pipe->screen, dst); -- cgit v1.2.3 From e14126ec811e4f37cf085be27cac4f750d9e011a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 23 Jun 2008 08:54:16 -0600 Subject: gallium: change surface_copy()'s do_flip to boolean --- src/gallium/drivers/cell/ppu/cell_surface.c | 2 +- src/gallium/drivers/i915simple/i915_surface.c | 2 +- src/gallium/drivers/i965simple/brw_surface.c | 2 +- src/gallium/drivers/softpipe/sp_surface.c | 2 +- src/gallium/include/pipe/p_context.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c index 4a098101e1..18f3791924 100644 --- a/src/gallium/drivers/cell/ppu/cell_surface.c +++ b/src/gallium/drivers/cell/ppu/cell_surface.c @@ -60,7 +60,7 @@ cell_surface_data(struct pipe_context *pipe, static void cell_surface_copy(struct pipe_context *pipe, - unsigned do_flip, + boolean do_flip, struct pipe_surface *dst, unsigned dstx, unsigned dsty, struct pipe_surface *src, diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index 1729ea26f5..cc55a0910e 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -41,7 +41,7 @@ */ static void i915_surface_copy(struct pipe_context *pipe, - unsigned do_flip, + boolean do_flip, struct pipe_surface *dst, unsigned dstx, unsigned dsty, struct pipe_surface *src, diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index 62d75bc251..3d98a2bf19 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -41,7 +41,7 @@ */ static void brw_surface_copy(struct pipe_context *pipe, - unsigned do_flip, + boolean do_flip, struct pipe_surface *dst, unsigned dstx, unsigned dsty, struct pipe_surface *src, diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index acedebfcc5..9fd48aeccc 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -44,7 +44,7 @@ */ static void sp_surface_copy(struct pipe_context *pipe, - unsigned do_flip, + boolean do_flip, struct pipe_surface *dst, unsigned dstx, unsigned dsty, struct pipe_surface *src, diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index faf112c6d6..2646706ff2 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -192,7 +192,7 @@ struct pipe_context { */ /*@{*/ void (*surface_copy)(struct pipe_context *pipe, - unsigned do_flip, /*<< flip surface contents vertically */ + boolean do_flip,/**< flip surface contents vertically */ struct pipe_surface *dest, unsigned destx, unsigned desty, struct pipe_surface *src, /* don't make this const - -- cgit v1.2.3 From f738c3acaca235c68a26c7b7d41903c64a36ae9f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 23 Jun 2008 09:47:12 -0600 Subject: gallium: fix Y-inverted copies Don't require the caller to pass a non-intuitive negative src_y coord anymore when doing a src-inverted copy. --- src/gallium/auxiliary/util/p_util.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_util.c b/src/gallium/auxiliary/util/p_util.c index 0e3f082b3e..4e60b1b841 100644 --- a/src/gallium/auxiliary/util/p_util.c +++ b/src/gallium/auxiliary/util/p_util.c @@ -37,6 +37,7 @@ /** * Copy 2D rect from one place to another. * Position and sizes are in pixels. + * src_pitch may be negative to do vertical flip of pixels from source. */ void pipe_copy_rect(ubyte * dst, @@ -52,6 +53,7 @@ pipe_copy_rect(ubyte * dst, int src_y) { unsigned i; + int src_pitch_pos = src_pitch < 0 ? -src_pitch : src_pitch; assert(cpp > 0); assert(src_x >= 0); @@ -61,10 +63,11 @@ pipe_copy_rect(ubyte * dst, dst_pitch *= cpp; src_pitch *= cpp; + src_pitch_pos *= cpp; dst += dst_x * cpp; src += src_x * cpp; dst += dst_y * dst_pitch; - src += src_y * src_pitch; + src += src_y * src_pitch_pos; width *= cpp; if (width == dst_pitch && width == src_pitch) -- cgit v1.2.3 From f52ab4cc22bfb6708724f3c3966ce734d605cddd Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 23 Jun 2008 17:57:45 +0200 Subject: i915: Add render and texture support for tiled texture and buffers This is step towards tiled textures and buffer support for i915. But the tiled attribute is never set. --- src/gallium/drivers/i915simple/i915_context.h | 2 ++ src/gallium/drivers/i915simple/i915_state_emit.c | 12 ++++++------ src/gallium/drivers/i915simple/i915_state_sampler.c | 8 +++++++- src/gallium/drivers/i915simple/i915_texture.c | 1 + 4 files changed, 16 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 9e02f78714..5d411a6648 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -192,6 +192,8 @@ struct i915_texture { unsigned depth_pitch; /* per-image on i945? */ unsigned total_height; + unsigned tiled; + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; /* Explicitly store the offset of each image for each cube face or diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index bc801a82f0..19d968fd8b 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -213,10 +213,10 @@ i915_emit_hardware_state(struct i915_context *i915 ) if (cbuf_surface) { unsigned cpitch = (cbuf_surface->pitch * cbuf_surface->cpp); unsigned ctile = BUF_3D_USE_FENCE; -#if 0 - if (!((cpitch - 1) & cpitch) && cpitch >= 512) + if (cbuf_surface->texture && + ((struct i915_texture*)(cbuf_surface->texture))->tiled) { ctile = BUF_3D_TILED_SURFACE; -#endif + } OUT_BATCH(_3DSTATE_BUF_INFO_CMD); @@ -234,10 +234,10 @@ i915_emit_hardware_state(struct i915_context *i915 ) if (depth_surface) { unsigned zpitch = (depth_surface->pitch * depth_surface->cpp); unsigned ztile = BUF_3D_USE_FENCE; -#if 0 - if (!((zpitch - 1) & zpitch) && zpitch >= 512) + if (depth_surface->texture && + ((struct i915_texture*)(depth_surface->texture))->tiled) { ztile = BUF_3D_TILED_SURFACE; -#endif + } OUT_BATCH(_3DSTATE_BUF_INFO_CMD); diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c index 24440843f3..379aff3846 100644 --- a/src/gallium/drivers/i915simple/i915_state_sampler.c +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -234,6 +234,7 @@ i915_update_texture(struct i915_context *i915, const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; const uint num_levels = pt->last_level; unsigned max_lod = num_levels * 4; + unsigned tiled = MS3_USE_FENCE_REGS; assert(tex); assert(width); @@ -246,12 +247,17 @@ i915_update_texture(struct i915_context *i915, assert(format); assert(pitch); + if (tex->tiled) { + assert(!((pitch - 1) & pitch)); + tiled = MS3_TILED_SURFACE; + } + /* MS3 state */ state[0] = (((height - 1) << MS3_HEIGHT_SHIFT) | ((width - 1) << MS3_WIDTH_SHIFT) | format - | MS3_USE_FENCE_REGS); + | tiled); /* * XXX When min_filter != mag_filter and there's just one mipmap level, diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index d9b33df1d5..ae107c6676 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -174,6 +174,7 @@ i915_displaytarget_layout(struct i915_texture *tex) if (tex->base.width[0] >= 128) { tex->pitch = power_of_two(tex->base.width[0] * pt->cpp) / pt->cpp; tex->total_height = round_up(tex->base.height[0], 8); + tex->tiled = 1; } else { tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp); tex->total_height = tex->base.height[0]; -- cgit v1.2.3 From 25da42a650048cd960c81af56744e5fdadd923ad Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 23 Jun 2008 11:27:44 -0600 Subject: gallium: in softpipe_get_tex_surface() use the pitch specified in the softpipe_texture object. Fixes a pitch/width mix-up. --- src/gallium/drivers/softpipe/sp_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index ef8c5bd6b0..2ef17a220b 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -198,7 +198,7 @@ softpipe_get_tex_surface(struct pipe_screen *screen, ps->cpp = pt->cpp; ps->width = pt->width[level]; ps->height = pt->height[level]; - ps->pitch = ps->width; + ps->pitch = spt->pitch[level]; ps->offset = spt->level_offset[level]; ps->usage = usage; -- cgit v1.2.3 From 72b6fddefb15b98499eda422a30a1e92da4c2850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 24 Jun 2008 01:25:20 +0900 Subject: gallium: WinCE does not have cosf, sinf, etc. --- src/gallium/include/pipe/p_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 8b3003bcef..f62faf616a 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -409,7 +409,7 @@ extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, #if defined(_MSC_VER) -#if _MSC_VER < 1400 && !defined(__cplusplus) +#if _MSC_VER < 1400 && !defined(__cplusplus) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) static INLINE float cosf( float f ) { -- cgit v1.2.3 From d9f38a2ad1477cc6aeb94c083ab439b8c704be2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 24 Jun 2008 01:26:22 +0900 Subject: gallium: Use the more portable PIPE_ARCH_* PIPE_CC_* macros instead of ad-hoc ones. --- src/gallium/auxiliary/util/p_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 9d56f8bfab..b1106a5e55 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -100,9 +100,9 @@ void debug_print_blob( const char *name, void _debug_break(void) { -#if (defined(__i386__) || defined(__386__)) && defined(__GNUC__) +#if defined(PIPE_ARCH_X86) && defined(PIPE_CC_GCC) __asm("int3"); -#elif (defined(__i386__) || defined(__386__)) && defined(__MSC__) +#elif defined(PIPE_ARCH_X86) && defined(PIPE_CC_MSVC) _asm {int 3}; #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) EngDebugBreak(); -- cgit v1.2.3 From dc73d15a9a1cc830781f8f3ef81507bfff79b7f9 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Mon, 23 Jun 2008 16:24:58 -0600 Subject: gallium: code for PIPE_SUBSYSTEM_WINDOWS_USER --- src/gallium/auxiliary/util/p_debug.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index b1106a5e55..7b28900a25 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -30,14 +30,28 @@ #include + #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY + #include #include + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#endif +#include + #else + #include #include + #endif + + #include "pipe/p_compiler.h" #include "pipe/p_util.h" #include "pipe/p_debug.h" @@ -74,6 +88,17 @@ void _debug_vprintf(const char *format, va_list ap) #else /* TODO: Implement debug print for WINCE */ #endif +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + /* EngDebugPrint does not handle float point arguments, so we need to use + * our own vsnprintf implementation. It is also very slow, so buffer until + * we find a newline. */ + static char buf[512 + 1] = {'\0'}; + size_t len = strlen(buf); + int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap); + if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) { + OutputDebugStringA(buf); + buf[0] = '\0'; + } #else vfprintf(stderr, format, ap); #endif -- cgit v1.2.3 From 89e9d6b6db933c870443714c3d7c9539d117cddf Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 23 Jun 2008 17:13:14 -0600 Subject: gallium: added support for fixed-point formats, drawing --- src/gallium/auxiliary/translate/translate_generic.c | 18 ++++++++++++++++++ src/gallium/include/pipe/p_format.h | 5 +++++ 2 files changed, 23 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 3fec89b36e..17e37d1745 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -121,6 +121,8 @@ emit_##NAME(const float *attrib, void *ptr) \ #define FROM_16_SNORM(i) ((float) ((short *) ptr)[i] / 32767.0f) #define FROM_32_SNORM(i) ((float) ((int *) ptr)[i] / 2147483647.0f) +#define FROM_32_FIXED(i) (((int *) ptr)[i] / 65536.0) + #define TO_64_FLOAT(x) ((double) x) #define TO_32_FLOAT(x) (x) @@ -140,6 +142,8 @@ emit_##NAME(const float *attrib, void *ptr) \ #define TO_16_SNORM(x) ((short) (x * 32767.0f)) #define TO_32_SNORM(x) ((int) (x * 2147483647.0f)) +#define TO_32_FIXED(x) ((int) (x * 65536.0f)) + ATTRIB( R64G64B64A64_FLOAT, 4, double, FROM_64_FLOAT, TO_64_FLOAT ) @@ -215,6 +219,11 @@ ATTRIB( R8_SNORM, 1, char, FROM_8_SNORM, TO_8_SNORM ) ATTRIB( A8R8G8B8_UNORM, 4, ubyte, FROM_8_UNORM, TO_8_UNORM ) //ATTRIB( R8G8B8A8_UNORM, 4, ubyte, FROM_8_UNORM, TO_8_UNORM ) +ATTRIB( R32G32B32A32_FIXED, 4, int, FROM_32_FIXED, TO_32_FIXED ) +ATTRIB( R32G32B32_FIXED, 3, int, FROM_32_FIXED, TO_32_FIXED ) +ATTRIB( R32G32_FIXED, 2, int, FROM_32_FIXED, TO_32_FIXED ) +ATTRIB( R32_FIXED, 1, int, FROM_32_FIXED, TO_32_FIXED ) + static void @@ -386,6 +395,15 @@ static fetch_func get_fetch_func( enum pipe_format format ) case PIPE_FORMAT_B8G8R8A8_UNORM: return &fetch_B8G8R8A8_UNORM; + case PIPE_FORMAT_R32_FIXED: + return &fetch_R32_FIXED; + case PIPE_FORMAT_R32G32_FIXED: + return &fetch_R32G32_FIXED; + case PIPE_FORMAT_R32G32B32_FIXED: + return &fetch_R32G32B32_FIXED; + case PIPE_FORMAT_R32G32B32A32_FIXED: + return &fetch_R32G32B32A32_FIXED; + default: assert(0); return &fetch_NULL; diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 579fdb2957..00aa02311c 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -83,6 +83,7 @@ static INLINE uint pf_layout(uint f) /**< PIPE_FORMAT_LAYOUT_ */ #define PIPE_FORMAT_TYPE_USCALED 4 /**< uints, not normalized */ #define PIPE_FORMAT_TYPE_SSCALED 5 /**< ints, not normalized */ #define PIPE_FORMAT_TYPE_SRGB 6 /**< sRGB colorspace */ +#define PIPE_FORMAT_TYPE_FIXED 7 /**< 16.16 fixed point */ /** @@ -353,6 +354,10 @@ enum pipe_format { PIPE_FORMAT_R8G8B8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R8G8B8A8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R8G8B8X8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ), + PIPE_FORMAT_R32_FIXED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 4, 0, 0, 0, PIPE_FORMAT_TYPE_FIXED ), + PIPE_FORMAT_R32G32_FIXED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 4, 4, 0, 0, PIPE_FORMAT_TYPE_FIXED ), + PIPE_FORMAT_R32G32B32_FIXED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 4, 4, 4, 0, PIPE_FORMAT_TYPE_FIXED ), + PIPE_FORMAT_R32G32B32A32_FIXED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 4, 4, 4, 4, PIPE_FORMAT_TYPE_FIXED ), /* sRGB formats */ PIPE_FORMAT_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB ), PIPE_FORMAT_A8_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ), -- cgit v1.2.3 From b750b5326df0a067f9baf237bee50d31ca69729d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 24 Jun 2008 11:40:25 +0900 Subject: gdi: Update for surface_alloc_storage changes. --- src/gallium/winsys/gdi/wmesa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c index 74a8292352..0b93f8c4c3 100644 --- a/src/gallium/winsys/gdi/wmesa.c +++ b/src/gallium/winsys/gdi/wmesa.c @@ -469,7 +469,8 @@ wm_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags) + unsigned flags, + unsigned tex_usage) { const unsigned alignment = 64; -- cgit v1.2.3 From e8b52b3f5682c969e58077d42f5aebdad5d32e89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 24 Jun 2008 13:56:41 +0900 Subject: gallium: Drop deprecated __MSC__ macro. --- src/gallium/include/pipe/p_compiler.h | 15 +++++---------- src/gallium/include/pipe/p_debug.h | 4 ++-- src/gallium/include/pipe/p_util.h | 6 +++--- 3 files changed, 10 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index 521ef2d189..d2b8c41be3 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -39,20 +39,15 @@ #define __WIN32__ #endif -#if defined(_MSC_VER) && !defined(__MSC__) -#define __MSC__ -#endif - - -#if defined(__MSC__) +#if defined(_MSC_VER) /* Avoid 'expression is always true' warning */ #pragma warning(disable: 4296) -#endif /* __MSC__ */ +#endif /* _MSC_VER */ -#if defined(__MSC__) +#if defined(_MSC_VER) typedef __int8 int8_t; typedef unsigned __int8 uint8_t; @@ -114,7 +109,7 @@ typedef unsigned char boolean; /* Function inlining */ #if defined(__GNUC__) # define INLINE __inline__ -#elif defined(__MSC__) +#elif defined(_MSC_VER) # define INLINE __inline #elif defined(__ICL) # define INLINE __inline @@ -138,7 +133,7 @@ typedef unsigned char boolean; -#if defined __GNUC__ +#if defined(__GNUC__) #define ALIGN16_DECL(TYPE, NAME, SIZE) TYPE NAME##___aligned[SIZE] __attribute__(( aligned( 16 ) )) #define ALIGN16_ASSIGN(NAME) NAME##___aligned #define ALIGN16_ATTRIB __attribute__(( aligned( 16 ) )) diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 9011557006..a5816c3cbb 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -132,9 +132,9 @@ void _debug_break(void); * Hard-coded breakpoint. */ #ifdef DEBUG -#if (defined(__i386__) || defined(__386__)) && defined(__GNUC__) +#if defined(PIPE_ARCH_X86) && defined(PIPE_CC_GCC) #define debug_break() __asm("int3") -#elif defined(_M_IX86) && defined(_MSC_VER) +#elif defined(PIPE_ARCH_X86) && defined(PIPE_CC_MSVC) #define debug_break() do { _asm {int 3} } while(0) #else #define debug_break() _debug_break() diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index f62faf616a..cf2447822a 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -224,7 +224,7 @@ static INLINE int align_int(int x, int align) -#if defined(__MSC__) && defined(__WIN32__) +#if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) static INLINE unsigned ffs( unsigned u ) { unsigned i; @@ -341,14 +341,14 @@ static INLINE int ifloor(float f) } -#if defined(__GNUC__) && defined(__i386__) +#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) static INLINE int iround(float f) { int r; __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st"); return r; } -#elif defined(__MSC__) && defined(__WIN32__) +#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) static INLINE int iround(float f) { int r; -- cgit v1.2.3 From 4802a687a7050b7b5dd3683ae43fd4f26c4a718e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 24 Jun 2008 14:00:10 +0900 Subject: dri/intel: Use standard integer types. --- src/gallium/winsys/dri/intel/intel_screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 8817a80a5a..1d61617ab5 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -418,8 +418,8 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML }; - u_int8_t depth_bits_array[3]; - u_int8_t stencil_bits_array[3]; + uint8_t depth_bits_array[3]; + uint8_t stencil_bits_array[3]; depth_bits_array[0] = 0; -- cgit v1.2.3 From 9dfa6063be5ea506cc5a43d352fa2f7dcfa68dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 24 Jun 2008 14:22:09 +0900 Subject: gallium: Avoid double arithmetic. --- src/gallium/auxiliary/translate/translate_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 17e37d1745..4c8179ffa8 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -121,7 +121,7 @@ emit_##NAME(const float *attrib, void *ptr) \ #define FROM_16_SNORM(i) ((float) ((short *) ptr)[i] / 32767.0f) #define FROM_32_SNORM(i) ((float) ((int *) ptr)[i] / 2147483647.0f) -#define FROM_32_FIXED(i) (((int *) ptr)[i] / 65536.0) +#define FROM_32_FIXED(i) (((int *) ptr)[i] / 65536.0f) #define TO_64_FLOAT(x) ((double) x) #define TO_32_FLOAT(x) (x) -- cgit v1.2.3 From e8af160b247a4cf60c82a3d0c63ec952aef22d96 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 24 Jun 2008 13:00:42 +0200 Subject: gallium: Fix warning in u_blit.h --- src/gallium/auxiliary/util/u_blit.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h index 7d0406c104..308075698f 100644 --- a/src/gallium/auxiliary/util/u_blit.h +++ b/src/gallium/auxiliary/util/u_blit.h @@ -37,6 +37,7 @@ extern "C" { struct pipe_context; struct pipe_surface; +struct pipe_texture; struct cso_context; -- cgit v1.2.3 From 2d11411b19f725591e096b8a75dec94831d7bce7 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 24 Jun 2008 13:09:43 +0200 Subject: i915: Moved screen creation to intel_be_device --- .../winsys/common/intel_drm/intel_be_device.c | 9 ++++++++- .../winsys/common/intel_drm/intel_be_device.h | 7 ++++++- src/gallium/winsys/dri/intel/Makefile | 5 +++-- src/gallium/winsys/dri/intel/intel_context.c | 23 +++------------------- src/gallium/winsys/dri/intel/intel_screen.c | 10 ++++++---- 5 files changed, 26 insertions(+), 28 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c index 3eed0fe410..efb57a394e 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.c +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c @@ -16,6 +16,8 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "i915simple/i915_screen.h" + /* Turn a pipe winsys into an intel/pipe winsys: */ static INLINE struct intel_be_device * @@ -192,7 +194,7 @@ intel_be_fence_finish( struct pipe_winsys *sws, */ boolean -intel_be_init_device(struct intel_be_device *dev, int fd) +intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) { dev->fd = fd; dev->max_batch_size = 16 * 4096; @@ -252,6 +254,11 @@ intel_be_init_device(struct intel_be_device *dev, int fd) 1, 40, dev->max_batch_size * 16, 0, dev->fMan); + /* Fill in this struct with callbacks that i915simple will need to + * communicate with the window system, buffer manager, etc. + */ + dev->screen = i915_create_screen(&dev->base, id); + return true; } diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h index ec5cace71c..abf0253917 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.h +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.h @@ -12,6 +12,11 @@ struct intel_be_device { struct pipe_winsys base; + /** + * Hw level screen + */ + struct pipe_screen *screen; + int fd; /**< Drm file discriptor */ size_t max_batch_size; @@ -28,7 +33,7 @@ struct intel_be_device }; boolean -intel_be_init_device(struct intel_be_device *device, int fd); +intel_be_init_device(struct intel_be_device *device, int fd, unsigned id); void intel_be_destroy_device(struct intel_be_device *dev); diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index 00ce21f690..5b51f0815d 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -6,8 +6,9 @@ LIBNAME = i915_dri.so PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ - $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a + $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a \ + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + DRIVER_SOURCES = \ intel_winsys_softpipe.c \ diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c index 8284e0edbb..97ef731aaa 100644 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ b/src/gallium/winsys/dri/intel/intel_context.c @@ -134,25 +134,6 @@ static const struct dri_debug_control debug_control[] = { -/** - * Create i915 hardware rendering context. - */ -static struct pipe_context * -intel_create_i915simple(struct intel_context *intel, - struct pipe_winsys *winsys) -{ - struct pipe_screen *screen; - - /* Fill in this struct with callbacks that i915simple will need to - * communicate with the window system, buffer manager, etc. - */ - screen = i915_create_screen(winsys, intel->intelScreen->deviceID); - - /* Create the i915simple context: - */ - return i915_create_context(screen, winsys, &intel->base.base ); -} - static void intel_lock_hardware(struct intel_be_context *context) { @@ -250,7 +231,9 @@ intelCreateContext(const __GLcontextModes * visual, case PCI_CHIP_Q35_G: case PCI_CHIP_I915_G: case PCI_CHIP_I915_GM: - pipe = intel_create_i915simple( intel, &intelScreen->base.base ); + pipe = i915_create_context(intelScreen->base.screen, + &intelScreen->base.base, + &intel->base.base); break; default: fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 1d61617ab5..809af2e553 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -198,10 +198,12 @@ intel_flush_frontbuffer( struct pipe_winsys *winsys, struct pipe_surface *surf, void *context_private) { - struct intel_context *intel = (struct intel_context *) context_private; - __DRIdrawablePrivate *dPriv = intel->driDrawable; + //struct intel_context *intel = (struct intel_context *) context_private; + //__DRIdrawablePrivate *dPriv = intel->driDrawable; - intelDisplaySurface(dPriv, surf, NULL); + assert((int)"Doesn't work currently" & 0); + + //intelDisplaySurface(dPriv, surf, NULL); } static boolean @@ -254,9 +256,9 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - intel_be_init_device(&intelScreen->base, sPriv->fd); intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; intelScreen->base.base.get_name = intel_get_name; + intel_be_init_device(&intelScreen->base, sPriv->fd, intelScreen->deviceID); return GL_TRUE; } -- cgit v1.2.3 From 19dad109bb7b271e0bb4b55e1374c299770b107e Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 24 Jun 2008 14:19:30 +0200 Subject: i915: Added texture_blanket function --- src/gallium/drivers/i915simple/i915_texture.c | 34 +++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index ae107c6676..9d8a6d6de4 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -677,6 +677,39 @@ i915_get_tex_surface(struct pipe_screen *screen, return ps; } +static struct pipe_texture * +i915_texture_blanket(struct pipe_screen * screen, + const struct pipe_texture *base, + const unsigned *pitch, + struct pipe_buffer *buffer) +{ + struct i915_texture *tex; + assert(screen); + assert(templat); + + /* Only supports one type */ + if (base->target != PIPE_TEXTURE_2D || + base->last_level != 0 || + base->depth[0] != 1) { + return NULL; + } + + tex = CALLOC_STRUCT(i915_texture); + if (!tex) + return NULL; + + tex->base = *base; + + tex->pitch = pitch[0]; + + i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1); + i915_miptree_set_image_offset(tex, 0, 0, 0, 0); + + pipe_buffer_reference(screen->winsys, &tex->buffer, buffer); + + return &tex->base; +} + void i915_init_texture_functions(struct i915_context *i915) { @@ -713,5 +746,6 @@ i915_init_screen_texture_functions(struct pipe_screen *screen) screen->texture_create = i915_texture_create; screen->texture_release = i915_texture_release; screen->get_tex_surface = i915_get_tex_surface; + screen->texture_blanket = i915_texture_blanket; screen->tex_surface_release = i915_tex_surface_release; } -- cgit v1.2.3 From e95697758eda9b92a01a504bce823acd5201b48d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 24 Jun 2008 14:42:12 +0200 Subject: i915: Create a texture and surface for shared frontbuffer --- src/gallium/winsys/dri/intel/intel_screen.c | 67 +++++++++++++++++++++++++++-- src/gallium/winsys/dri/intel/intel_screen.h | 2 + 2 files changed, 66 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 809af2e553..18427a4586 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -38,10 +38,69 @@ #include "intel_drm/ws_dri_bufpool.h" #include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_inlines.h" #include "state_tracker/st_public.h" #include "state_tracker/st_cb_fbo.h" +static void +intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle); +static void +intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle) +{ + struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); + struct pipe_screen *screen = intelScreen->base.screen; + struct pipe_texture *texture; + struct pipe_texture templat; + struct pipe_surface *surface; + struct pipe_buffer *buffer = &be_buf->base; + unsigned pitch; + + assert(intelScreen->front.cpp == 4); + + /* XXX create a intel_be function for this */ + { + driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); + driBOSetReferenced(intelScreen->front.buffer, handle); + + memset(be_buf, 0, sizeof(*be_buf)); + buffer->refcount = 1; + buffer->alignment = 0; + buffer->usage = 0; + buffer->size = driBOSize(intelScreen->front.buffer); + be_buf->driBO = intelScreen->front.buffer; + } + + memset(&templat, 0, sizeof(templat)); + templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + templat.target = PIPE_TEXTURE_2D; + templat.last_level = 0; + templat.depth[0] = 1; + templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templat.cpp = intelScreen->front.cpp; + templat.width[0] = intelScreen->front.width; + templat.height[0] = intelScreen->front.height; + pitch = intelScreen->front.pitch / intelScreen->front.cpp; + + texture = screen->texture_blanket(screen, + &templat, + &pitch, + buffer); + + /* Unref the buffer we don't need it anyways */ + pipe_buffer_reference(screen->winsys, &buffer, NULL); + + surface = screen->get_tex_surface(screen, + texture, + 0, + 0, + 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + + intelScreen->front.texture = texture; + intelScreen->front.surface = surface; +} PUBLIC const char __driConfigOptions[] = DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE @@ -157,10 +216,12 @@ intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) } #else if (intelScreen->base.staticPool) { - if (intelScreen->front.buffer) + if (intelScreen->front.buffer) { driBOUnReference(intelScreen->front.buffer); - driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); - driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle); + pipe_surface_reference(&intelScreen->front.surface, NULL); + pipe_texture_reference(&intelScreen->front.texture, NULL); + } + intelCreateSurface(intelScreen, &intelScreen->base.base, sarea->front_bo_handle); } #endif } diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h index 8036917903..e62f9e71ec 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ b/src/gallium/winsys/dri/intel/intel_screen.h @@ -47,6 +47,8 @@ struct intel_screen /* We create a static dri buffer for the frontbuffer. */ struct _DriBufferObject *buffer; + struct pipe_surface *surface; + struct pipe_texture *texture; char *map; /* memory map */ int offset; /* from start of video mem, in bytes */ -- cgit v1.2.3 From 62fd280c524b282f2448995a353d94f973d904d4 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 24 Jun 2008 16:06:59 +0200 Subject: gallium: Fix whole source being used in u_blit --- src/gallium/auxiliary/util/u_blit.c | 70 ++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 28513f54e6..6555dcd588 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -222,6 +222,49 @@ setup_vertex_data(struct blit_state *ctx, } +/** + * Setup vertex data for the textured quad we'll draw. + * Note: y=0=top + */ +static void +setup_vertex_data_tex(struct blit_state *ctx, + float x0, float y0, float x1, float y1, + float s0, float t0, float s1, float t1, + float z) +{ + void *buf; + + ctx->vertices[0][0][0] = x0; + ctx->vertices[0][0][1] = y0; + ctx->vertices[0][0][2] = z; + ctx->vertices[0][1][0] = s0; /*s*/ + ctx->vertices[0][1][1] = t0; /*t*/ + + ctx->vertices[1][0][0] = x1; + ctx->vertices[1][0][1] = y0; + ctx->vertices[1][0][2] = z; + ctx->vertices[1][1][0] = s1; /*s*/ + ctx->vertices[1][1][1] = t0; /*t*/ + + ctx->vertices[2][0][0] = x1; + ctx->vertices[2][0][1] = y1; + ctx->vertices[2][0][2] = z; + ctx->vertices[2][1][0] = s1; + ctx->vertices[2][1][1] = t1; + + ctx->vertices[3][0][0] = x0; + ctx->vertices[3][0][1] = y1; + ctx->vertices[3][0][2] = z; + ctx->vertices[3][1][0] = s0; + ctx->vertices[3][1][1] = t1; + + buf = ctx->pipe->winsys->buffer_map(ctx->pipe->winsys, ctx->vbuf, + PIPE_BUFFER_USAGE_CPU_WRITE); + + memcpy(buf, ctx->vertices, sizeof(ctx->vertices)); + + ctx->pipe->winsys->buffer_unmap(ctx->pipe->winsys, ctx->vbuf); +} /** * Copy pixel block from src surface to dst surface. * Overlapping regions are acceptable. @@ -382,25 +425,18 @@ util_blit_pixels_tex(struct blit_state *ctx, struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_framebuffer_state fb; - const int srcLeft = MIN2(srcX0, srcX1); - const int srcTop = MIN2(srcY0, srcY1); + float s0, t0, s1, t1; assert(filter == PIPE_TEX_MIPFILTER_NEAREST || filter == PIPE_TEX_MIPFILTER_LINEAR); - if (srcLeft != srcX0) { - /* left-right flip */ - int tmp = dstX0; - dstX0 = dstX1; - dstX1 = tmp; - } + assert(tex->width[0] != 0); + assert(tex->height[0] != 0); - if (srcTop != srcY0) { - /* up-down flip */ - int tmp = dstY0; - dstY0 = dstY1; - dstY1 = tmp; - } + s0 = srcX0 / (float)tex->width[0]; + s1 = srcX1 / (float)tex->width[0]; + t0 = srcY0 / (float)tex->height[0]; + t1 = srcY1 / (float)tex->height[0]; assert(screen->is_format_supported(screen, dst->format, PIPE_SURFACE)); @@ -443,9 +479,11 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_set_framebuffer(ctx->cso, &fb); /* draw quad */ - setup_vertex_data(ctx, + setup_vertex_data_tex(ctx, (float) dstX0, (float) dstY0, - (float) dstX1, (float) dstY1, z); + (float) dstX1, (float) dstY1, + s0, t0, s1, t1, + z); util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, PIPE_PRIM_TRIANGLE_FAN, -- cgit v1.2.3 From 2b692335101d248106b4e1c2d116a1f95712fd25 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 24 Jun 2008 08:45:59 -0600 Subject: gallium: remove bad assertion --- src/gallium/drivers/i915simple/i915_texture.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 9d8a6d6de4..b2e490c7db 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -685,7 +685,6 @@ i915_texture_blanket(struct pipe_screen * screen, { struct i915_texture *tex; assert(screen); - assert(templat); /* Only supports one type */ if (base->target != PIPE_TEXTURE_2D || -- cgit v1.2.3 From 0561a293b6596641c0200df7e6580599ecb8b111 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 24 Jun 2008 08:47:15 -0600 Subject: gallium: remove some old dispatch code --- src/gallium/include/pipe/p_thread.h | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/include/pipe/p_thread.h index af9150aafb..6e526b7aa8 100644 --- a/src/gallium/include/pipe/p_thread.h +++ b/src/gallium/include/pipe/p_thread.h @@ -62,12 +62,6 @@ #define _P_THREAD_H_ -#if defined(USE_MGL_NAMESPACE) -#define _glapi_Dispatch _mglapi_Dispatch -#endif - - - #if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ && !defined(THREADS) @@ -330,22 +324,6 @@ _glthread_GetTSD(_glthread_TSD *); extern void _glthread_SetTSD(_glthread_TSD *, void *); -#if defined(GLX_USE_TLS) - -extern __thread struct _glapi_table * _glapi_tls_Dispatch - __attribute__((tls_model("initial-exec"))); - -#define GET_DISPATCH() _glapi_tls_Dispatch - -#elif !defined(GL_CALL) -# if defined(THREADS) -# define GET_DISPATCH() \ - ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ - ? _glapi_Dispatch : _glapi_get_dispatch()) -# else -# define GET_DISPATCH() _glapi_Dispatch -# endif /* defined(THREADS) */ -#endif /* ndef GL_CALL */ #endif /* _P_THREAD_H_ */ -- cgit v1.2.3 From 38d779a3e68bb0ed78135c868e5bd435e1d91fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 26 Jun 2008 23:39:13 +0900 Subject: gallium: Describe pixel block. Chars-per-pixel paradigm is not enough to represent compressed and yuv pixel formats. --- src/gallium/include/pipe/p_format.h | 56 +++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 00aa02311c..d973fb357b 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -445,6 +445,62 @@ static INLINE uint pf_get_size( enum pipe_format format ) return pf_get_bits(format) / 8; } +/** + * Describe accurately the pixel format. + * + * The chars-per-pixel concept falls apart with compressed and yuv images, where + * more than one pixel are coded in a single data block. This structure + * describes that block. + * + * Simple pixel formats are effectively a 1x1xcpp block. + */ +struct pipe_format_block +{ + /** Block size in bytes */ + unsigned size; + + /** Block width in pixels */ + unsigned width; + + /** Block height in pixels */ + unsigned height; +}; + +/** + * Describe pixel format's block. + * + * @sa http://msdn2.microsoft.com/en-us/library/ms796147.aspx + */ +static INLINE void +pf_get_block(enum pipe_format format, struct pipe_format_block *block) +{ + switch(format) { + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT1_RGB: + block->size = 8; + block->width = 4; + block->height = 4; + break; + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: + block->size = 16; + block->width = 4; + block->height = 4; + break; + case PIPE_FORMAT_YCBCR: + case PIPE_FORMAT_YCBCR_REV: + block->size = 4; /* 2*cpp */ + block->width = 2; + block->height = 1; + break; + default: + block->size = pf_get_size(format); + block->width = 1; + block->height = 1; + break; + } +} + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 6106db4c5da6fc5ae9ef157c939ce0834cdc5b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 27 Jun 2008 13:01:37 +0900 Subject: scons: Fix i965/xlib build. --- src/gallium/drivers/i965simple/SConscript | 1 + src/gallium/winsys/xlib/SConscript | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/SConscript b/src/gallium/drivers/i965simple/SConscript index c0825c4de3..43fc2a4005 100644 --- a/src/gallium/drivers/i965simple/SConscript +++ b/src/gallium/drivers/i965simple/SConscript @@ -26,6 +26,7 @@ i965simple = env.ConvenienceLibrary( 'brw_gs_emit.c', 'brw_gs_state.c', 'brw_misc_state.c', + 'brw_screen.c', 'brw_sf.c', 'brw_sf_emit.c', 'brw_sf_state.c', diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 5e98a36abc..14a85ae0f2 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -3,7 +3,11 @@ Import('*') -if env['platform'] == 'linux' and 'mesa' in env['statetrackers'] and not env['dri']: +if env['platform'] == 'linux' \ + and 'mesa' in env['statetrackers'] \ + and 'softpipe' in env['drivers'] \ + and 'i965simple' in env['drivers'] \ + and not env['dri']: env = env.Clone() @@ -24,6 +28,7 @@ if env['platform'] == 'linux' and 'mesa' in env['statetrackers'] and not env['dr drivers = [ softpipe, + i965simple ] # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -- cgit v1.2.3 From 4ddd65967915ca4846f2831bc676c878a29dae4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 27 Jun 2008 19:37:56 +0900 Subject: gallium: Drop pipe_texture->cpp and pipe_surface->cpp. The chars-per-pixel concept falls apart with compressed and yuv images, where more than one pixel are coded in a single data block. --- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 4 +- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 6 +- src/gallium/auxiliary/util/p_tile.c | 98 ++++------- src/gallium/auxiliary/util/p_util.c | 100 +++++++++-- src/gallium/auxiliary/util/u_blit.c | 2 +- src/gallium/auxiliary/util/u_gen_mipmap.c | 8 +- src/gallium/drivers/i915simple/i915_blit.c | 2 - src/gallium/drivers/i915simple/i915_context.h | 6 +- src/gallium/drivers/i915simple/i915_state_emit.c | 4 +- .../drivers/i915simple/i915_state_sampler.c | 2 +- src/gallium/drivers/i915simple/i915_surface.c | 68 ++----- src/gallium/drivers/i915simple/i915_texture.c | 196 +++++++++++---------- src/gallium/drivers/i965simple/brw_context.h | 4 +- src/gallium/drivers/i965simple/brw_misc_state.c | 8 +- src/gallium/drivers/i965simple/brw_surface.c | 69 ++------ src/gallium/drivers/i965simple/brw_tex_layout.c | 117 ++++++------ .../drivers/i965simple/brw_wm_surface_state.c | 6 +- src/gallium/drivers/softpipe/sp_surface.c | 45 ++--- src/gallium/drivers/softpipe/sp_texture.c | 20 ++- src/gallium/drivers/softpipe/sp_texture.h | 2 +- src/gallium/include/pipe/p_format.h | 41 +++++ src/gallium/include/pipe/p_state.h | 11 +- src/gallium/include/pipe/p_util.h | 15 +- src/gallium/winsys/xlib/brw_aub.c | 9 +- src/gallium/winsys/xlib/xm_winsys.c | 24 +-- src/gallium/winsys/xlib/xm_winsys_aub.c | 31 ++-- 26 files changed, 458 insertions(+), 440 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index ecdebca5f1..3dd7ee19fd 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -398,7 +398,7 @@ aaline_create_texture(struct aaline_stage *aaline) texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL; texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL; texTemp.depth[0] = 1; - texTemp.cpp = 1; + pf_get_block(texTemp.format, &texTemp.block); aaline->texture = screen->texture_create(screen, &texTemp); if (!aaline->texture) @@ -439,7 +439,7 @@ aaline_create_texture(struct aaline_stage *aaline) else { d = 255; } - data[i * surface->pitch + j] = d; + data[i * surface->stride + j] = d; } } diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 4087cf7a49..1f63f94365 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -394,11 +394,11 @@ pstip_update_texture(struct pstip_stage *pstip) for (j = 0; j < 32; j++) { if (stipple[i] & (bit31 >> j)) { /* fragment "on" */ - data[i * surface->pitch + j] = 0; + data[i * surface->stride + j] = 0; } else { /* fragment "off" */ - data[i * surface->pitch + j] = 255; + data[i * surface->stride + j] = 255; } } } @@ -426,7 +426,7 @@ pstip_create_texture(struct pstip_stage *pstip) texTemp.width[0] = 32; texTemp.height[0] = 32; texTemp.depth[0] = 1; - texTemp.cpp = 1; + pf_get_block(texTemp.format, &texTemp.block); pstip->texture = screen->texture_create(screen, &texTemp); if (pstip->texture == NULL) diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 5728757d2f..ab603ff6e4 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -48,34 +48,23 @@ void pipe_get_tile_raw(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, - void *p, int dst_stride) + void *dst, int dst_stride) { struct pipe_screen *screen = pipe->screen; - const uint cpp = ps->cpp; - const ubyte *pSrc; - const uint src_stride = ps->pitch * cpp; - ubyte *pDest; - uint i; - - if (dst_stride == 0) { - dst_stride = w * cpp; - } + const void *src; if (pipe_clip_tile(x, y, &w, &h, ps)) return; - pSrc = (const ubyte *) screen->surface_map(screen, ps, - PIPE_BUFFER_USAGE_CPU_READ); - assert(pSrc); /* XXX: proper error handling! */ + if (dst_stride == 0) + dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; - pSrc += (y * ps->pitch + x) * cpp; - pDest = (ubyte *) p; + src = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + assert(src); + if(!src) + return; - for (i = 0; i < h; i++) { - memcpy(pDest, pSrc, w * cpp); - pDest += dst_stride; - pSrc += src_stride; - } + pipe_copy_rect(dst, &ps->block, dst_stride, 0, 0, w, h, src, ps->stride, x, y); screen->surface_unmap(screen, ps); } @@ -89,34 +78,23 @@ void pipe_put_tile_raw(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, - const void *p, int src_stride) + const void *src, int src_stride) { struct pipe_screen *screen = pipe->screen; - const uint cpp = ps->cpp; - const ubyte *pSrc; - const uint dst_stride = ps->pitch * cpp; - ubyte *pDest; - uint i; - - if (src_stride == 0) { - src_stride = w * cpp; - } + void *dst; if (pipe_clip_tile(x, y, &w, &h, ps)) return; - pSrc = (const ubyte *) p; + if (src_stride == 0) + src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; - pDest = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); - assert(pDest); /* XXX: proper error handling */ - - pDest += (y * ps->pitch + x) * cpp; + dst = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + assert(dst); + if(!dst) + return; - for (i = 0; i < h; i++) { - memcpy(pDest, pSrc, w * cpp); - pDest += dst_stride; - pSrc += src_stride; - } + pipe_copy_rect(dst, &ps->block, ps->stride, x, y, w, h, src, src_stride, 0, 0); screen->surface_unmap(screen, ps); } @@ -692,12 +670,12 @@ pipe_get_tile_rgba(struct pipe_context *pipe, if (pipe_clip_tile(x, y, &w, &h, ps)) return; - packed = MALLOC(h * w * ps->cpp); + packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size); if (!packed) return; - pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp); + pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, 0); switch (ps->format) { case PIPE_FORMAT_A8R8G8B8_UNORM: @@ -774,7 +752,7 @@ pipe_put_tile_rgba(struct pipe_context *pipe, if (pipe_clip_tile(x, y, &w, &h, ps)) return; - packed = MALLOC(h * w * ps->cpp); + packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size); if (!packed) return; @@ -829,7 +807,7 @@ pipe_put_tile_rgba(struct pipe_context *pipe, assert(0); } - pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp); + pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, 0); FREE(packed); } @@ -846,14 +824,14 @@ pipe_get_tile_z(struct pipe_context *pipe, { struct pipe_screen *screen = pipe->screen; const uint dstStride = w; - void *map; + ubyte *map; uint *pDest = z; uint i, j; if (pipe_clip_tile(x, y, &w, &h, ps)) return; - map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); if (!map) { assert(0); return; @@ -863,11 +841,11 @@ pipe_get_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_Z32_UNORM: { const uint *pSrc - = (const uint *)map + (y * ps->pitch + x); + = (const uint *)(map + y * ps->stride + x*4); for (i = 0; i < h; i++) { memcpy(pDest, pSrc, 4 * w); pDest += dstStride; - pSrc += ps->pitch; + pSrc += ps->stride/4; } } break; @@ -875,28 +853,28 @@ pipe_get_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_X8Z24_UNORM: { const uint *pSrc - = (const uint *)map + (y * ps->pitch + x); + = (const uint *)(map + y * ps->stride + x*4); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 24-bit Z to 32-bit Z */ pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff); } pDest += dstStride; - pSrc += ps->pitch; + pSrc += ps->stride/4; } } break; case PIPE_FORMAT_Z16_UNORM: { const ushort *pSrc - = (const ushort *)map + (y * ps->pitch + x); + = (const ushort *)(map + y * ps->stride + x*2); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 16-bit Z to 32-bit Z */ pDest[j] = (pSrc[j] << 16) | pSrc[j]; } pDest += dstStride; - pSrc += ps->pitch; + pSrc += ps->stride/2; } } break; @@ -917,13 +895,13 @@ pipe_put_tile_z(struct pipe_context *pipe, struct pipe_screen *screen = pipe->screen; const uint srcStride = w; const uint *pSrc = zSrc; - void *map; + ubyte *map; uint i, j; if (pipe_clip_tile(x, y, &w, &h, ps)) return; - map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); if (!map) { assert(0); return; @@ -932,10 +910,10 @@ pipe_put_tile_z(struct pipe_context *pipe, switch (ps->format) { case PIPE_FORMAT_Z32_UNORM: { - uint *pDest = (uint *) map + (y * ps->pitch + x); + uint *pDest = (uint *) (map + y * ps->stride + x*4); for (i = 0; i < h; i++) { memcpy(pDest, pSrc, 4 * w); - pDest += ps->pitch; + pDest += ps->stride/4; pSrc += srcStride; } } @@ -943,26 +921,26 @@ pipe_put_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: { - uint *pDest = (uint *) map + (y * ps->pitch + x); + uint *pDest = (uint *) (map + y * ps->stride + x*4); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 24-bit Z (0 stencil) */ pDest[j] = pSrc[j] >> 8; } - pDest += ps->pitch; + pDest += ps->stride/4; pSrc += srcStride; } } break; case PIPE_FORMAT_Z16_UNORM: { - ushort *pDest = (ushort *) map + (y * ps->pitch + x); + ushort *pDest = (ushort *) (map + y * ps->stride + x*2); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 16-bit Z */ pDest[j] = pSrc[j] >> 16; } - pDest += ps->pitch; + pDest += ps->stride/2; pSrc += srcStride; } } diff --git a/src/gallium/auxiliary/util/p_util.c b/src/gallium/auxiliary/util/p_util.c index 4e60b1b841..271be4edf1 100644 --- a/src/gallium/auxiliary/util/p_util.c +++ b/src/gallium/auxiliary/util/p_util.c @@ -32,6 +32,7 @@ #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "pipe/p_format.h" /** @@ -41,42 +42,109 @@ */ void pipe_copy_rect(ubyte * dst, - unsigned cpp, - unsigned dst_pitch, + const struct pipe_format_block *block, + unsigned dst_stride, unsigned dst_x, unsigned dst_y, unsigned width, unsigned height, const ubyte * src, - int src_pitch, + int src_stride, unsigned src_x, int src_y) { unsigned i; - int src_pitch_pos = src_pitch < 0 ? -src_pitch : src_pitch; + int src_stride_pos = src_stride < 0 ? -src_stride : src_stride; - assert(cpp > 0); + assert(block->size > 0); + assert(block->width > 0); + assert(block->height > 0); assert(src_x >= 0); assert(src_y >= 0); assert(dst_x >= 0); assert(dst_y >= 0); - dst_pitch *= cpp; - src_pitch *= cpp; - src_pitch_pos *= cpp; - dst += dst_x * cpp; - src += src_x * cpp; - dst += dst_y * dst_pitch; - src += src_y * src_pitch_pos; - width *= cpp; + dst_x /= block->width; + dst_y /= block->height; + width = (width + block->width - 1)/block->width; + height = (height + block->height - 1)/block->height; + src_x /= block->width; + src_y /= block->height; + + dst += dst_x * block->size; + src += src_x * block->size; + dst += dst_y * dst_stride; + src += src_y * src_stride_pos; + width *= block->size; - if (width == dst_pitch && width == src_pitch) + if (width == dst_stride && width == src_stride) memcpy(dst, src, height * width); else { for (i = 0; i < height; i++) { memcpy(dst, src, width); - dst += dst_pitch; - src += src_pitch; + dst += dst_stride; + src += src_stride; } } } + +void +pipe_fill_rect(ubyte * dst, + const struct pipe_format_block *block, + unsigned dst_stride, + unsigned dst_x, + unsigned dst_y, + unsigned width, + unsigned height, + uint32_t value) +{ + unsigned i, j; + unsigned width_size; + + assert(block->size > 0); + assert(block->width > 0); + assert(block->height > 0); + assert(dst_x >= 0); + assert(dst_y >= 0); + + dst_x /= block->width; + dst_y /= block->height; + width = (width + block->width - 1)/block->width; + height = (height + block->height - 1)/block->height; + + dst += dst_x * block->size; + dst += dst_y * dst_stride; + width_size = width * block->size; + + switch (block->size) { + case 1: + if(dst_stride == width_size) + memset(dst, (ubyte) value, height * width_size); + else { + for (i = 0; i < height; i++) { + memset(dst, (ubyte) value, width_size); + dst += dst_stride; + } + } + break; + case 2: + for (i = 0; i < height; i++) { + uint16_t *row = (uint16_t *)dst; + for (j = 0; j < width; j++) + *row++ = (uint16_t) value; + dst += dst_stride; + } + break; + case 4: + for (i = 0; i < height; i++) { + uint32_t *row = (uint32_t *)dst; + for (j = 0; j < width; j++) + *row++ = value; + dst += dst_stride; + } + break; + default: + assert(0); + break; + } +} diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 6555dcd588..ae779335dc 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -324,7 +324,7 @@ util_blit_pixels(struct blit_state *ctx, texTemp.height[0] = srcH; texTemp.depth[0] = 1; texTemp.compressed = 0; - texTemp.cpp = pf_get_size(src->format); + pf_get_block(src->format, &texTemp.block); tex = screen->texture_create(screen, &texTemp); if (!tex) diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 7d71aefda9..5313a8008a 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -625,7 +625,9 @@ make_2d_mipmap(struct gen_mipmap_state *ctx, struct pipe_winsys *winsys = pipe->winsys; const uint zslice = 0; uint dstLevel; - const int bpt = pf_get_size(pt->format); + + assert(pt->block.width == 1); + assert(pt->block.height == 1); for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { const uint srcLevel = dstLevel - 1; @@ -646,9 +648,9 @@ make_2d_mipmap(struct gen_mipmap_state *ctx, reduce_2d(pt->format, srcSurf->width, srcSurf->height, - srcSurf->pitch * bpt, srcMap, + srcSurf->stride, srcMap, dstSurf->width, dstSurf->height, - dstSurf->pitch * bpt, dstMap); + dstSurf->stride, dstMap); winsys->buffer_unmap(winsys, srcSurf->buffer); winsys->buffer_unmap(winsys, dstSurf->buffer); diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c index 22f91fab92..45fae4c999 100644 --- a/src/gallium/drivers/i915simple/i915_blit.c +++ b/src/gallium/drivers/i915simple/i915_blit.c @@ -47,8 +47,6 @@ i915_fill_blit(struct i915_context *i915, { unsigned BR13, CMD; - dst_pitch *= (short) cpp; - switch (cpp) { case 1: case 2: diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 5d411a6648..c8db4f608c 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -188,9 +188,9 @@ struct i915_texture { /* Derived from the above: */ - unsigned pitch; - unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; + unsigned stride; + unsigned depth_stride; /* per-image on i945? */ + unsigned total_nblocksy; unsigned tiled; diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c index 19d968fd8b..9bd6f92323 100644 --- a/src/gallium/drivers/i915simple/i915_state_emit.c +++ b/src/gallium/drivers/i915simple/i915_state_emit.c @@ -211,7 +211,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; if (cbuf_surface) { - unsigned cpitch = (cbuf_surface->pitch * cbuf_surface->cpp); + unsigned cpitch = cbuf_surface->stride; unsigned ctile = BUF_3D_USE_FENCE; if (cbuf_surface->texture && ((struct i915_texture*)(cbuf_surface->texture))->tiled) { @@ -232,7 +232,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) /* What happens if no zbuf?? */ if (depth_surface) { - unsigned zpitch = (depth_surface->pitch * depth_surface->cpp); + unsigned zpitch = depth_surface->stride; unsigned ztile = BUF_3D_USE_FENCE; if (depth_surface->texture && ((struct i915_texture*)(depth_surface->texture))->tiled) { diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c index 379aff3846..7868f21ca6 100644 --- a/src/gallium/drivers/i915simple/i915_state_sampler.c +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -242,7 +242,7 @@ i915_update_texture(struct i915_context *i915, assert(depth); format = translate_texture_format(pt->format); - pitch = tex->pitch * pt->cpp; + pitch = tex->stride; assert(format); assert(pitch); diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index cc55a0910e..0061b22f26 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -48,7 +48,9 @@ i915_surface_copy(struct pipe_context *pipe, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { assert( dst != src ); - assert( dst->cpp == src->cpp ); + assert( dst->block.size == src->block.size ); + assert( dst->block.width == src->block.height ); + assert( dst->block.height == src->block.height ); if (0) { void *dst_map = pipe->screen->surface_map( pipe->screen, @@ -60,38 +62,30 @@ i915_surface_copy(struct pipe_context *pipe, PIPE_BUFFER_USAGE_CPU_READ ); pipe_copy_rect(dst_map, - dst->cpp, - dst->pitch, + &dst->block, + dst->stride, dstx, dsty, width, height, src_map, - do_flip ? -(int) src->pitch : src->pitch, + do_flip ? -(int) src->stride : src->stride, srcx, do_flip ? height - 1 - srcy : srcy); pipe->screen->surface_unmap(pipe->screen, src); pipe->screen->surface_unmap(pipe->screen, dst); } else { + assert(dst->block.width == 1); + assert(dst->block.height == 1); i915_copy_blit( i915_context(pipe), do_flip, - dst->cpp, - (short) src->pitch, src->buffer, src->offset, - (short) dst->pitch, dst->buffer, dst->offset, + dst->block.size, + (short) src->stride/src->block.size, src->buffer, src->offset, + (short) dst->stride/dst->block.size, dst->buffer, dst->offset, (short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height ); } } -/* Fill a rectangular sub-region. Need better logic about when to - * push buffers into AGP - will currently do so whenever possible. - */ -static void * -get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) -{ - return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; -} - - static void i915_surface_fill(struct pipe_context *pipe, struct pipe_surface *dst, @@ -99,50 +93,20 @@ i915_surface_fill(struct pipe_context *pipe, unsigned width, unsigned height, unsigned value) { if (0) { - unsigned i, j; void *dst_map = pipe->screen->surface_map( pipe->screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE ); - - switch (dst->cpp) { - case 1: { - ubyte *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - memset(row, value, width); - row += dst->pitch; - } - } - break; - case 2: { - ushort *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = (ushort) value; - row += dst->pitch; - } - } - break; - case 4: { - unsigned *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = value; - row += dst->pitch; - } - } - break; - default: - assert(0); - break; - } + pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value); pipe->screen->surface_unmap(pipe->screen, dst); } else { + assert(dst->block.width == 1); + assert(dst->block.height == 1); i915_fill_blit( i915_context(pipe), - dst->cpp, - (short) dst->pitch, + dst->block.size, + (short) dst->stride/dst->block.size, dst->buffer, dst->offset, (short) dstx, (short) dsty, (short) width, (short) height, diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index b2e490c7db..2815e61345 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -109,6 +109,9 @@ i915_miptree_set_level_info(struct i915_texture *tex, pt->width[level] = w; pt->height[level] = h; pt->depth[level] = d; + + pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w); + pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h); tex->nr_images[level] = nr_images; @@ -140,7 +143,7 @@ i915_miptree_set_image_offset(struct i915_texture *tex, assert(img < tex->nr_images[level]); - tex->image_offset[level][img] = (x + y * tex->pitch); + tex->image_offset[level][img] = y * tex->stride + x * tex->base.block.size; /* printf("%s level %d img %d pos %d,%d image_offset %x\n", @@ -162,7 +165,7 @@ i915_displaytarget_layout(struct i915_texture *tex) { struct pipe_texture *pt = &tex->base; - if (pt->last_level > 0 || pt->cpp != 4) + if (pt->last_level > 0 || pt->block.size != 4) return 0; i915_miptree_set_level_info( tex, 0, 1, @@ -172,18 +175,18 @@ i915_displaytarget_layout(struct i915_texture *tex) i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); if (tex->base.width[0] >= 128) { - tex->pitch = power_of_two(tex->base.width[0] * pt->cpp) / pt->cpp; - tex->total_height = round_up(tex->base.height[0], 8); + tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size); + tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8); tex->tiled = 1; } else { - tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp); - tex->total_height = tex->base.height[0]; + tex->stride = round_up(tex->base.nblocksx[0] * pt->block.size, 64); + tex->total_nblocksy = tex->base.nblocksy[0]; } /* printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, - tex->base.width[0], tex->base.height[0], pt->cpp, - tex->pitch, tex->total_height, tex->pitch * tex->total_height * 4); + tex->base.width[0], tex->base.height[0], pt->block.size, + tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy); */ return 1; @@ -193,12 +196,14 @@ static void i945_miptree_layout_2d( struct i915_texture *tex ) { struct pipe_texture *pt = &tex->base; - int align_h = 2, align_w = 4; + const int align_x = 2, align_y = 4; unsigned level; unsigned x = 0; unsigned y = 0; unsigned width = pt->width[0]; unsigned height = pt->height[0]; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; #if 0 /* used for tiled display targets */ if (pt->last_level == 0 && pt->cpp == 4) @@ -206,7 +211,7 @@ i945_miptree_layout_2d( struct i915_texture *tex ) return; #endif - tex->pitch = pt->width[0]; + tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); /* May need to adjust pitch to accomodate the placement of * the 2nd mipmap level. This occurs when the alignment @@ -214,47 +219,43 @@ i945_miptree_layout_2d( struct i915_texture *tex ) * 2nd mipmap level out past the width of its parent. */ if (pt->last_level > 0) { - unsigned mip1_width = align_int(minify(pt->width[0]), align_w) - + minify(minify(pt->width[0])); + unsigned mip1_nblocksx + = align_int(pf_get_nblocksx(&pt->block, minify(width)), align_x) + + pf_get_nblocksx(&pt->block, minify(minify(width))); - if (mip1_width > pt->width[0]) - tex->pitch = mip1_width; + if (mip1_nblocksx > nblocksx) + tex->stride = mip1_nblocksx * pt->block.size; } - /* Pitch must be a whole number of dwords, even though we - * express it in texels. + /* Pitch must be a whole number of dwords */ - tex->pitch = align_int(tex->pitch * pt->cpp, 64) / pt->cpp; - tex->total_height = 0; + tex->stride = align_int(tex->stride, 64); + tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { - unsigned img_height; - i915_miptree_set_level_info(tex, level, 1, width, height, 1); i915_miptree_set_image_offset(tex, level, 0, x, y); - if (pt->compressed) - img_height = MAX2(1, height/4); - else - img_height = align_int(height, align_h); - + nblocksy = align_int(nblocksy, align_y); /* Because the images are packed better, the final offset * might not be the maximal one: */ - tex->total_height = MAX2(tex->total_height, y + img_height); + tex->total_nblocksy = MAX2(tex->total_nblocksy, y + nblocksy); /* Layout_below: step right after second mipmap level. */ if (level == 1) { - x += align_int(width, align_w); + x += align_int(nblocksx, align_x); } else { - y += img_height; + y += nblocksy; } width = minify(width); height = minify(height); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); } } @@ -264,15 +265,16 @@ i945_miptree_layout_cube(struct i915_texture *tex) struct pipe_texture *pt = &tex->base; unsigned level; - const unsigned dim = pt->width[0]; + const unsigned nblocks = pt->nblocksx[0]; unsigned face; - unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; /* printf("%s %i, %i\n", __FUNCTION__, pt->width[0], pt->height[0]); */ - assert(lvlWidth == lvlHeight); /* cubemap images are square */ + assert(width == height); /* cubemap images are square */ /* * XXX Should only be used for compressed formats. But lets @@ -282,35 +284,32 @@ i945_miptree_layout_cube(struct i915_texture *tex) * determined either by the old-style packing of cubemap faces, * or the final row of 4x4, 2x2 and 1x1 faces below this. */ - if (dim > 32) - tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; + if (nblocks > 32) + tex->stride = round_up(nblocks * pt->block.size * 2, 4); else - tex->pitch = 14 * 8; + tex->stride = 14 * 8 * pt->block.size; - /* - * XXX The 4 is only needed for compressed formats. See above. - */ - tex->total_height = dim * 4 + 4; + tex->total_nblocksy = nblocks * 4; /* Set all the levels to effectively occupy the whole rectangular region. */ for (level = 0; level <= pt->last_level; level++) { - i915_miptree_set_level_info(tex, level, 6, lvlWidth, lvlHeight, 1); - lvlWidth /= 2; - lvlHeight /= 2; + i915_miptree_set_level_info(tex, level, 6, width, height, 1); + width /= 2; + height /= 2; } for (face = 0; face < 6; face++) { - unsigned x = initial_offsets[face][0] * dim; - unsigned y = initial_offsets[face][1] * dim; - unsigned d = dim; + unsigned x = initial_offsets[face][0] * nblocks; + unsigned y = initial_offsets[face][1] * nblocks; + unsigned d = nblocks; #if 0 /* Fix and enable this code for compressed formats */ - if (dim == 4 && face >= 4) { + if (nblocks == 4 && face >= 4) { y = tex->total_height - 4; x = (face - 4) * 8; } - else if (dim < 4 && (face > 0)) { + else if (nblocks < 4 && (face > 0)) { y = tex->total_height - 4; x = face * 8; } @@ -369,28 +368,28 @@ i915_miptree_layout(struct i915_texture * tex) switch (pt->target) { case PIPE_TEXTURE_CUBE: { - const unsigned dim = pt->width[0]; + const unsigned nblocks = pt->nblocksx[0]; unsigned face; - unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; + unsigned width = pt->width[0], height = pt->height[0]; - assert(lvlWidth == lvlHeight); /* cubemap images are square */ + assert(width == height); /* cubemap images are square */ /* double pitch for cube layouts */ - tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; - tex->total_height = dim * 4; + tex->stride = round_up(nblocks * pt->block.size * 2, 4); + tex->total_nblocksy = nblocks * 4; for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 6, - lvlWidth, lvlHeight, + width, height, 1); - lvlWidth /= 2; - lvlHeight /= 2; + width /= 2; + height /= 2; } for (face = 0; face < 6; face++) { - unsigned x = initial_offsets[face][0] * dim; - unsigned y = initial_offsets[face][1] * dim; - unsigned d = dim; + unsigned x = initial_offsets[face][0] * nblocks; + unsigned y = initial_offsets[face][1] * nblocks; + unsigned d = nblocks; for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_image_offset(tex, level, face, x, y); @@ -405,25 +404,29 @@ i915_miptree_layout(struct i915_texture * tex) unsigned width = pt->width[0]; unsigned height = pt->height[0]; unsigned depth = pt->depth[0]; - unsigned stack_height = 0; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; + unsigned stack_nblocksy = 0; /* Calculate the size of a single slice. */ - tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; + tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); /* XXX: hardware expects/requires 9 levels at minimum. */ for (level = 0; level <= MAX2(8, pt->last_level); level++) { i915_miptree_set_level_info(tex, level, depth, - width, height, depth); + width, height, depth); - stack_height += MAX2(2, height); + stack_nblocksy += MAX2(2, nblocksy); width = minify(width); height = minify(height); depth = minify(depth); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); } /* Fixup depth image_offsets: @@ -433,7 +436,7 @@ i915_miptree_layout(struct i915_texture * tex) unsigned i; for (i = 0; i < depth; i++) i915_miptree_set_image_offset(tex, level, i, - 0, i * stack_height); + 0, i * stack_nblocksy); depth = minify(depth); } @@ -443,33 +446,33 @@ i915_miptree_layout(struct i915_texture * tex) * remarkable how wasteful of memory the i915 texture layouts * are. They are largely fixed in the i945. */ - tex->total_height = stack_height * pt->depth[0]; + tex->total_nblocksy = stack_nblocksy * pt->depth[0]; break; } default:{ unsigned width = pt->width[0]; unsigned height = pt->height[0]; - unsigned img_height; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; - tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; - tex->total_height = 0; + tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); + tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 1, - width, height, 1); + width, height, 1); i915_miptree_set_image_offset(tex, level, 0, - 0, tex->total_height); + 0, tex->total_nblocksy); - if (pt->compressed) - img_height = MAX2(1, height / 4); - else - img_height = (MAX2(2, height) + 1) & ~1; + nblocksy = round_up(MAX2(2, nblocksy), 2); - tex->total_height += img_height; + tex->total_nblocksy += nblocksy; width = minify(width); height = minify(height); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); } break; } @@ -477,7 +480,7 @@ i915_miptree_layout(struct i915_texture * tex) /* DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, tex->pitch, - tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp); + tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy); */ return TRUE; @@ -498,14 +501,16 @@ i945_miptree_layout(struct i915_texture * tex) unsigned width = pt->width[0]; unsigned height = pt->height[0]; unsigned depth = pt->depth[0]; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; unsigned pack_x_pitch, pack_x_nr; unsigned pack_y_pitch; - tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; - tex->total_height = 0; + tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4); + tex->total_nblocksy = 0; - pack_y_pitch = MAX2(pt->height[0], 2); - pack_x_pitch = tex->pitch; + pack_y_pitch = MAX2(pt->nblocksy[0], 2); + pack_x_pitch = tex->stride / pt->block.size; pack_x_nr = 1; for (level = 0; level <= pt->last_level; level++) { @@ -515,11 +520,11 @@ i945_miptree_layout(struct i915_texture * tex) unsigned q, j; i915_miptree_set_level_info(tex, level, nr_images, - width, height, depth); + width, height, depth); for (q = 0; q < nr_images;) { for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { - i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_height); + i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy); x += pack_x_pitch; } @@ -528,12 +533,12 @@ i945_miptree_layout(struct i915_texture * tex) } - tex->total_height += y; + tex->total_nblocksy += y; if (pack_x_pitch > 4) { pack_x_pitch >>= 1; pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= tex->pitch); + assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride); } if (pack_y_pitch > 2) { @@ -543,6 +548,8 @@ i945_miptree_layout(struct i915_texture * tex) width = minify(width); height = minify(height); depth = minify(depth); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); } break; } @@ -560,7 +567,7 @@ i945_miptree_layout(struct i915_texture * tex) /* DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, tex->pitch, - tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp); + tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy); */ return TRUE; @@ -582,6 +589,9 @@ i915_texture_create(struct pipe_screen *screen, tex->base.refcount = 1; tex->base.screen = screen; + tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]); + tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]); + if (i915screen->is_i945) { if (!i945_miptree_layout(tex)) goto fail; @@ -592,8 +602,8 @@ i915_texture_create(struct pipe_screen *screen, tex->buffer = ws->buffer_create(ws, 64, PIPE_BUFFER_USAGE_PIXEL, - tex->pitch * tex->base.cpp * - tex->total_height); + tex->stride * + tex->total_nblocksy); if (!tex->buffer) goto fail; @@ -648,13 +658,13 @@ i915_get_tex_surface(struct pipe_screen *screen, unsigned offset; /* in bytes */ if (pt->target == PIPE_TEXTURE_CUBE) { - offset = tex->image_offset[level][face] * pt->cpp; + offset = tex->image_offset[level][face]; } else if (pt->target == PIPE_TEXTURE_3D) { - offset = tex->image_offset[level][zslice] * pt->cpp; + offset = tex->image_offset[level][zslice]; } else { - offset = tex->image_offset[level][0] * pt->cpp; + offset = tex->image_offset[level][0]; assert(face == 0); assert(zslice == 0); } @@ -666,10 +676,12 @@ i915_get_tex_surface(struct pipe_screen *screen, pipe_texture_reference(&ps->texture, pt); pipe_buffer_reference(ws, &ps->buffer, tex->buffer); ps->format = pt->format; - ps->cpp = pt->cpp; ps->width = pt->width[level]; ps->height = pt->height[level]; - ps->pitch = tex->pitch; + ps->block = pt->block; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = tex->stride; ps->offset = offset; ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; @@ -680,7 +692,7 @@ i915_get_tex_surface(struct pipe_screen *screen, static struct pipe_texture * i915_texture_blanket(struct pipe_screen * screen, const struct pipe_texture *base, - const unsigned *pitch, + const unsigned *stride, struct pipe_buffer *buffer) { struct i915_texture *tex; @@ -699,7 +711,7 @@ i915_texture_blanket(struct pipe_screen * screen, tex->base = *base; - tex->pitch = pitch[0]; + tex->stride = stride[0]; i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1); i915_miptree_set_image_offset(tex, 0, 0, 0, 0); diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index 8ac6b4e689..2cae7665f7 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -231,9 +231,9 @@ struct brw_texture { /* Derived from the above: */ - unsigned pitch; + unsigned stride; unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; + unsigned total_nblocksy; unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; diff --git a/src/gallium/drivers/i965simple/brw_misc_state.c b/src/gallium/drivers/i965simple/brw_misc_state.c index 925049ecc1..be812c5da9 100644 --- a/src/gallium/drivers/i965simple/brw_misc_state.c +++ b/src/gallium/drivers/i965simple/brw_misc_state.c @@ -224,7 +224,9 @@ static void upload_depthbuffer(struct brw_context *brw) } else { unsigned int format; - switch (depth_surface->cpp) { + assert(depth_surface->block.width == 1); + assert(depth_surface->block.height == 1); + switch (depth_surface->block.size) { case 2: format = BRW_DEPTHFORMAT_D16_UNORM; break; @@ -239,7 +241,7 @@ static void upload_depthbuffer(struct brw_context *brw) return; } - OUT_BATCH(((depth_surface->pitch * depth_surface->cpp) - 1) | + OUT_BATCH((depth_surface->stride - 1) | (format << 18) | (BRW_TILEWALK_YMAJOR << 26) | // (depth_surface->region->tiled << 27) | @@ -247,7 +249,7 @@ static void upload_depthbuffer(struct brw_context *brw) OUT_RELOC(depth_surface->buffer, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE, 0); OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) | - ((depth_surface->pitch - 1) << 6) | + ((depth_surface->stride/depth_surface->block.size - 1) << 6) | ((depth_surface->height - 1) << 19)); OUT_BATCH(0); } diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index 3d98a2bf19..0be3dfc743 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -47,8 +47,10 @@ brw_surface_copy(struct pipe_context *pipe, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { - assert(dst != src); - assert(dst->cpp == src->cpp); + assert( dst != src ); + assert( dst->block.size == src->block.size ); + assert( dst->block.width == src->block.height ); + assert( dst->block.height == src->block.height ); if (0) { void *dst_map = pipe->screen->surface_map( pipe->screen, @@ -60,37 +62,30 @@ brw_surface_copy(struct pipe_context *pipe, PIPE_BUFFER_USAGE_CPU_READ ); pipe_copy_rect(dst_map, - dst->cpp, - dst->pitch, + &dst->block, + dst->stride, dstx, dsty, width, height, src_map, - do_flip ? -(int) src->pitch : src->pitch, + do_flip ? -(int) src->stride : src->stride, srcx, do_flip ? height - 1 - srcy : srcy); pipe->screen->surface_unmap(pipe->screen, src); pipe->screen->surface_unmap(pipe->screen, dst); } else { + assert(dst->block.width == 1); + assert(dst->block.height == 1); brw_copy_blit(brw_context(pipe), do_flip, - dst->cpp, - (short) src->pitch, src->buffer, src->offset, FALSE, - (short) dst->pitch, dst->buffer, dst->offset, FALSE, + dst->block.size, + (short) src->stride/src->block.size, src->buffer, src->offset, FALSE, + (short) dst->stride/dst->block.size, dst->buffer, dst->offset, FALSE, (short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height, PIPE_LOGICOP_COPY); } } -/* Fill a rectangular sub-region. Need better logic about when to - * push buffers into AGP - will currently do so whenever possible. - */ -static void * -get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) -{ - return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; -} - static void brw_surface_fill(struct pipe_context *pipe, @@ -99,50 +94,20 @@ brw_surface_fill(struct pipe_context *pipe, unsigned width, unsigned height, unsigned value) { if (0) { - unsigned i, j; void *dst_map = pipe->screen->surface_map( pipe->screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE ); - - switch (dst->cpp) { - case 1: { - ubyte *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - memset(row, value, width); - row += dst->pitch; - } - } - break; - case 2: { - ushort *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = (ushort) value; - row += dst->pitch; - } - } - break; - case 4: { - unsigned *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = value; - row += dst->pitch; - } - } - break; - default: - assert(0); - break; - } + pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value); pipe->screen->surface_unmap(pipe->screen, dst); } else { + assert(dst->block.width == 1); + assert(dst->block.height == 1); brw_fill_blit(brw_context(pipe), - dst->cpp, - (short) dst->pitch, + dst->block.size, + (short) dst->stride/dst->block.size, dst->buffer, dst->offset, FALSE, (short) dstx, (short) dsty, (short) width, (short) height, diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 78ae0b1223..8c7725605b 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -81,7 +81,7 @@ static void intel_miptree_set_image_offset(struct brw_texture *tex, assert(x == 0 && y == 0); assert(img < tex->nr_images[level]); - tex->image_offset[level][img] = (x + y * tex->pitch) * pt->cpp; + tex->image_offset[level][img] = y * tex->stride + x * pt->block.size; } static void intel_miptree_set_level_info(struct brw_texture *tex, @@ -97,8 +97,11 @@ static void intel_miptree_set_level_info(struct brw_texture *tex, pt->width[level] = w; pt->height[level] = h; pt->depth[level] = d; + + pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w); + pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h); - tex->level_offset[level] = (x + y * tex->pitch) * pt->cpp; + tex->level_offset[level] = y * tex->stride + x * tex->base.block.size; tex->nr_images[level] = nr_images; /* @@ -123,77 +126,60 @@ static void intel_miptree_set_level_info(struct brw_texture *tex, static void i945_miptree_layout_2d(struct brw_texture *tex) { struct pipe_texture *pt = &tex->base; - unsigned align_h = 2, align_w = 4; + const int align_x = 2, align_y = 4; unsigned level; unsigned x = 0; unsigned y = 0; unsigned width = pt->width[0]; unsigned height = pt->height[0]; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; - tex->pitch = pt->width[0]; - -#if 0 - if (pt->compressed) { - align_w = intel_compressed_alignment(pt->internal_format); - tex->pitch = ALIGN(pt->width[0], align_w); - } -#endif + tex->stride = align(pt->nblocksx[0] * pt->block.size, 4); /* May need to adjust pitch to accomodate the placement of - * the 2nd mipmap. This occurs when the alignment + * the 2nd mipmap level. This occurs when the alignment * constraints of mipmap placement push the right edge of the - * 2nd mipmap out past the width of its parent. + * 2nd mipmap level out past the width of its parent. */ if (pt->last_level > 0) { - unsigned mip1_width; - - if (pt->compressed) { - mip1_width = align(minify(pt->width[0]), align_w) - + align(minify(minify(pt->width[0])), align_w); - } else { - mip1_width = align(minify(pt->width[0]), align_w) - + minify(minify(pt->width[0])); - } + unsigned mip1_nblocksx + = align_int(pf_get_nblocksx(&pt->block, minify(width)), align_x) + + pf_get_nblocksx(&pt->block, minify(minify(width))); - if (mip1_width > tex->pitch) { - tex->pitch = mip1_width; - } + if (mip1_nblocksx > nblocksx) + tex->stride = mip1_nblocksx * pt->block.size; } - /* Pitch must be a whole number of dwords, even though we - * express it in texels. + /* Pitch must be a whole number of dwords */ - tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp; - tex->total_height = 0; + tex->stride = align_int(tex->stride, 64); + tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { - unsigned img_height; - intel_miptree_set_level_info(tex, level, 1, x, y, width, height, 1); - if (pt->compressed) - img_height = MAX2(1, height/4); - else - img_height = align(height, align_h); - + nblocksy = align_int(nblocksy, align_y); /* Because the images are packed better, the final offset * might not be the maximal one: */ - tex->total_height = MAX2(tex->total_height, y + img_height); + tex->total_nblocksy = MAX2(tex->total_nblocksy, y + nblocksy); - /* Layout_below: step right after second mipmap. + /* Layout_below: step right after second mipmap level. */ if (level == 1) { - x += align(width, align_w); + x += align_int(nblocksx, align_x); } else { - y += img_height; + y += nblocksy; } width = minify(width); height = minify(height); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); } } @@ -210,26 +196,20 @@ static boolean brw_miptree_layout(struct brw_texture *tex) unsigned width = pt->width[0]; unsigned height = pt->height[0]; unsigned depth = pt->depth[0]; + unsigned nblocksx = pt->nblocksx[0]; + unsigned nblocksy = pt->nblocksy[0]; unsigned pack_x_pitch, pack_x_nr; unsigned pack_y_pitch; unsigned level; unsigned align_h = 2; unsigned align_w = 4; - tex->total_height = 0; -#if 0 - if (pt->compressed) { - align_w = intel_compressed_alignment(pt->internal_format); - pt->pitch = align(width, align_w); - pack_y_pitch = (height + 3) / 4; - } else -#endif - { - tex->pitch = align(pt->width[0] * pt->cpp, 4) / pt->cpp; - pack_y_pitch = align(pt->height[0], align_h); - } + tex->total_nblocksy = 0; + + tex->stride = align(pt->nblocksx[0], 4); + pack_y_pitch = align(pt->nblocksy[0], align_h); - pack_x_pitch = tex->pitch; + pack_x_pitch = tex->stride / pt->block.size; pack_x_nr = 1; for (level = 0; level <= pt->last_level; level++) { @@ -239,7 +219,7 @@ static boolean brw_miptree_layout(struct brw_texture *tex) uint q, j; intel_miptree_set_level_info(tex, level, nr_images, - 0, tex->total_height, + 0, tex->total_nblocksy, width, height, depth); for (q = 0; q < nr_images;) { @@ -253,10 +233,12 @@ static boolean brw_miptree_layout(struct brw_texture *tex) } - tex->total_height += y; + tex->total_nblocksy += y; width = minify(width); height = minify(height); depth = minify(depth); + nblocksx = pf_get_nblocksx(&pt->block, width); + nblocksy = pf_get_nblocksy(&pt->block, height); if (pt->compressed) { pack_y_pitch = (height + 3) / 4; @@ -269,7 +251,7 @@ static boolean brw_miptree_layout(struct brw_texture *tex) if (pack_x_pitch > 4) { pack_x_pitch >>= 1; pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= tex->pitch); + assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride); } if (pack_y_pitch > 2) { @@ -289,9 +271,9 @@ static boolean brw_miptree_layout(struct brw_texture *tex) #if 0 PRINT("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, pt->pitch, - pt->total_height, - pt->cpp, - pt->pitch * pt->total_height * pt->cpp ); + pt->total_nblocksy, + pt->block.size, + pt->stride * pt->total_nblocksy ); #endif return TRUE; @@ -309,11 +291,14 @@ brw_texture_create_screen(struct pipe_screen *screen, tex->base = *templat; tex->base.refcount = 1; + tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]); + tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]); + if (brw_miptree_layout(tex)) tex->buffer = ws->buffer_create(ws, 64, PIPE_BUFFER_USAGE_PIXEL, - tex->pitch * tex->base.cpp * - tex->total_height); + tex->stride * + tex->total_nblocksy); if (!tex->buffer) { FREE(tex); @@ -370,10 +355,10 @@ brw_get_tex_surface_screen(struct pipe_screen *screen, offset = tex->level_offset[level]; if (pt->target == PIPE_TEXTURE_CUBE) { - offset += tex->image_offset[level][face] * pt->cpp; + offset += tex->image_offset[level][face]; } else if (pt->target == PIPE_TEXTURE_3D) { - offset += tex->image_offset[level][zslice] * pt->cpp; + offset += tex->image_offset[level][zslice]; } else { assert(face == 0); @@ -386,10 +371,12 @@ brw_get_tex_surface_screen(struct pipe_screen *screen, assert(ps->refcount); pipe_buffer_reference(ws, &ps->buffer, tex->buffer); ps->format = pt->format; - ps->cpp = pt->cpp; ps->width = pt->width[level]; ps->height = pt->height[level]; - ps->pitch = tex->pitch; + ps->block = pt->block; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = tex->stride; ps->offset = offset; } return ps; diff --git a/src/gallium/drivers/i965simple/brw_wm_surface_state.c b/src/gallium/drivers/i965simple/brw_wm_surface_state.c index 69e56dc8bd..1a326f9918 100644 --- a/src/gallium/drivers/i965simple/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965simple/brw_wm_surface_state.c @@ -160,7 +160,7 @@ void brw_update_texture_surface( struct brw_context *brw, surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR; surf.ss3.tiled_surface = 0; /* always zero */ - surf.ss3.pitch = tObj->pitch - 1; + surf.ss3.pitch = tObj->stride - 1; surf.ss3.depth = tObj->base.depth[0] - 1; surf.ss4.min_lod = 0; @@ -197,7 +197,7 @@ static void upload_wm_surfaces(struct brw_context *brw ) memset(&surf, 0, sizeof(surf)); if (pipe_surface != NULL) { - if (pipe_surface->cpp == 4) + if (pipe_surface->block.size == 4) surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; else surf.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM; @@ -210,7 +210,7 @@ static void upload_wm_surfaces(struct brw_context *brw ) surf.ss2.height = pipe_surface->height - 1; surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR; surf.ss3.tiled_surface = 0; - surf.ss3.pitch = (pipe_surface->pitch * pipe_surface->cpp) - 1; + surf.ss3.pitch = pipe_surface->stride - 1; } else { surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; surf.ss0.surface_type = BRW_SURFACE_NULL; diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index 9fd48aeccc..7dc15c38d1 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -58,18 +58,20 @@ sp_surface_copy(struct pipe_context *pipe, src, PIPE_BUFFER_USAGE_CPU_READ ); - assert(dst->cpp == src->cpp); + assert(dst->block.size == src->block.size); + assert(dst->block.width == src->block.width); + assert(dst->block.height == src->block.height); assert(src_map); assert(dst_map); /* If do_flip, invert src_y position and pass negative src stride */ pipe_copy_rect(dst_map, - dst->cpp, - dst->pitch, + &dst->block, + dst->stride, dstx, dsty, width, height, src_map, - do_flip ? -(int) src->pitch : src->pitch, + do_flip ? -(int) src->stride : src->stride, srcx, do_flip ? src->height - 1 - srcy : srcy); pipe->screen->surface_unmap(pipe->screen, src); @@ -80,7 +82,7 @@ sp_surface_copy(struct pipe_context *pipe, static void * get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) { - return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; + return (char *)dst_map + y / dst->block.height * dst->stride + x / dst->block.width * dst->block.size; } @@ -102,39 +104,14 @@ sp_surface_fill(struct pipe_context *pipe, dst, PIPE_BUFFER_USAGE_CPU_WRITE ); - assert(dst->pitch > 0); - assert(width <= dst->pitch); + assert(dst->stride > 0); - switch (dst->cpp) { + switch (dst->block.size) { case 1: - { - ubyte *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - memset(row, value, width); - row += dst->pitch; - } - } - break; case 2: - { - ushort *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = (ushort) value; - row += dst->pitch; - } - } - break; case 4: - { - unsigned *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = value; - row += dst->pitch; - } - } + pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value); break; case 8: { @@ -155,7 +132,7 @@ sp_surface_fill(struct pipe_context *pipe, row[j*4+2] = val2; row[j*4+3] = val3; } - row += dst->pitch * 4; + row += dst->stride/2; } } break; diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 2ef17a220b..4db045cdc3 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -71,13 +71,15 @@ softpipe_texture_layout(struct pipe_screen *screen, pt->width[level] = width; pt->height[level] = height; pt->depth[level] = depth; - spt->pitch[level] = width; + pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height); + spt->stride[level] = pt->nblocksx[level]*pt->block.size; spt->level_offset[level] = buffer_size; - buffer_size += (((pt->compressed) ? MAX2(1, height/4) : height) * + buffer_size += (pt->nblocksy[level] * ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * - width * pt->cpp); + spt->stride[level]); width = minify(width); height = minify(height); @@ -121,7 +123,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, /* Now extract the goodies: */ spt->buffer = surf.buffer; - spt->pitch[0] = surf.pitch; + spt->stride[0] = surf.stride; return spt->buffer != NULL; } @@ -195,10 +197,12 @@ softpipe_get_tex_surface(struct pipe_screen *screen, assert(ps->winsys); pipe_buffer_reference(ws, &ps->buffer, spt->buffer); ps->format = pt->format; - ps->cpp = pt->cpp; + ps->block = pt->block; ps->width = pt->width[level]; ps->height = pt->height[level]; - ps->pitch = spt->pitch[level]; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = spt->stride[level]; ps->offset = spt->level_offset[level]; ps->usage = usage; @@ -228,8 +232,8 @@ softpipe_get_tex_surface(struct pipe_screen *screen, if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * - (pt->compressed ? ps->height/4 : ps->height) * - ps->width * ps->cpp; + ps->nblocksy * + ps->stride; } else { assert(face == 0); diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index 0e1017632c..bf437a7c61 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -42,7 +42,7 @@ struct softpipe_texture struct pipe_texture base; unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; - unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long stride[PIPE_MAX_TEXTURE_LEVELS]; /* The data is held here: */ diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index d973fb357b..a2c6155d01 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -501,6 +501,47 @@ pf_get_block(enum pipe_format format, struct pipe_format_block *block) } } +static INLINE unsigned +pf_get_nblocksx(const struct pipe_format_block *block, unsigned x) +{ + return (x + block->width - 1)/block->width; +} + +static INLINE unsigned +pf_get_nblocksy(const struct pipe_format_block *block, unsigned y) +{ + return (y + block->height - 1)/block->height; +} + +static INLINE unsigned +pf_get_nblocks(const struct pipe_format_block *block, unsigned width, unsigned height) +{ + return pf_get_nblocksx(block, width)*pf_get_nblocksy(block, height); +} + +static INLINE void +pipe_rect_to_blocks(const struct pipe_format_block *block, + unsigned *width, unsigned *height, + unsigned *src_x, unsigned *src_y, + unsigned *dst_x, unsigned *dst_y) +{ + assert(block->size > 0); + assert(block->width > 0); + assert(block->height > 0); + if(width) + *width = pf_get_nblocksx(block, *width); + if(height) + *height = pf_get_nblocksy(block, *height); + if(src_x) + *src_x /= block->width; + if(src_y) + *src_y /= block->height; + if(dst_x) + *dst_x /= block->width; + if(dst_y) + *dst_y /= block->height; +} + #ifdef __cplusplus } #endif diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index e7ee8c97ed..2992e2f3b3 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -267,10 +267,12 @@ struct pipe_surface enum pipe_format format; /**< PIPE_FORMAT_x */ unsigned status; /**< PIPE_SURFACE_STATUS_x */ unsigned clear_value; /**< XXX may be temporary */ - unsigned cpp; /**< bytes per pixel */ unsigned width; unsigned height; - unsigned pitch; /**< in pixels */ + struct pipe_format_block block; + unsigned nblocksx; + unsigned nblocksy; + unsigned stride; /**< in bytes */ unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ unsigned offset; /**< offset from start of buffer, in bytes */ unsigned refcount; @@ -303,7 +305,10 @@ struct pipe_texture unsigned height[PIPE_MAX_TEXTURE_LEVELS]; unsigned depth[PIPE_MAX_TEXTURE_LEVELS]; - unsigned cpp:8; + struct pipe_format_block block; + unsigned nblocksx[PIPE_MAX_TEXTURE_LEVELS]; + unsigned nblocksy[PIPE_MAX_TEXTURE_LEVELS]; + unsigned last_level:8; /**< Index of last mipmap level present/defined */ unsigned compressed:1; diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index cf2447822a..7dcdd28287 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -31,6 +31,7 @@ #include "p_config.h" #include "p_compiler.h" #include "p_debug.h" +#include "p_format.h" #include "p_pointer.h" #include #include @@ -401,11 +402,15 @@ static INLINE int align(int value, int alignment) /* util/p_util.c */ -extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, - unsigned dst_x, unsigned dst_y, unsigned width, - unsigned height, const ubyte * src, - int src_pitch, unsigned src_x, int src_y); - +extern void pipe_copy_rect(ubyte * dst, const struct pipe_format_block *block, + unsigned dst_stride, unsigned dst_x, unsigned dst_y, + unsigned width, unsigned height, const ubyte * src, + int src_stride, unsigned src_x, int src_y); + +extern void +pipe_fill_rect(ubyte * dst, const struct pipe_format_block *block, + unsigned dst_stride, unsigned dst_x, unsigned dst_y, + unsigned width, unsigned height, uint32_t value); #if defined(_MSC_VER) diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index 10eedd8402..6e814ce5d1 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -322,7 +322,10 @@ void brw_aub_dump_bmp( struct brw_aubfile *aubfile, struct aub_dump_bmp db; unsigned format; - if (surface->cpp == 4) + assert(surface->block.width == 1); + assert(surface->block.height == 1); + + if (surface->block.size == 4) format = 0x7; else format = 0x3; @@ -331,8 +334,8 @@ void brw_aub_dump_bmp( struct brw_aubfile *aubfile, db.xmin = 0; db.ymin = 0; db.format = format; - db.bpp = surface->cpp * 8; - db.pitch = surface->pitch; + db.bpp = surface->block.size * 8; + db.pitch = surface->stride/surface->block.size; db.xsize = surface->width; db.ysize = surface->height; db.addr = gtt_offset; diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index b14758f333..9225ee510d 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -364,9 +364,10 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) return; } - if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) { - alloc_shm_ximage(xm_buf, b, surf->pitch, surf->height); + assert(surf->block.width == 1); + assert(surf->block.height == 1); + alloc_shm_ximage(xm_buf, b, surf->stride/surf->block.size, surf->height); } ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; @@ -386,7 +387,7 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) /* update XImage's fields */ ximage->width = surf->width; ximage->height = surf->height; - ximage->bytes_per_line = surf->pitch * surf->cpp; + ximage->bytes_per_line = surf->stride; XPutImage(b->xm_visual->display, b->drawable, b->gc, ximage, 0, 0, 0, 0, surf->width, surf->height); @@ -497,18 +498,21 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, surf->width = width; surf->height = height; surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); surf->usage = flags; -#ifdef GALLIUM_CELL /* XXX a bit of a hack */ - height = round_up(height, TILE_SIZE); -#endif - assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); +#ifdef GALLIUM_CELL /* XXX a bit of a hack */ + surf->stride * round_up(surf->nblocksy, TILE_SIZE)); +#else + surf->stride * surf->nblocksy); +#endif + if(!surf->buffer) return -1; diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index 77376099f0..7fc9debdd5 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -279,22 +279,25 @@ aub_i915_surface_alloc_storage(struct pipe_winsys *winsys, unsigned flags, unsigned tex_usage) { - const unsigned alignment = 64; - - surf->width = width; - surf->height = height; - surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); - - assert(!surf->buffer); - surf->buffer = winsys->buffer_create(winsys, alignment, - PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->stride * surf->nblocksy); if(!surf->buffer) - return -1; + return -1; - return 0; + return 0; } static void -- cgit v1.2.3 From 891469a3a5525a741094fd3f1e4a1270ec8b3c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 27 Jun 2008 20:10:04 +0900 Subject: cell: Update for cpp removal. Not tested -- just mymic the softpipe changes. --- src/gallium/drivers/cell/ppu/cell_surface.c | 65 ++++------------------------- src/gallium/drivers/cell/ppu/cell_texture.c | 16 ++++--- 2 files changed, 18 insertions(+), 63 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c index 18f3791924..5549eb496d 100644 --- a/src/gallium/drivers/cell/ppu/cell_surface.c +++ b/src/gallium/drivers/cell/ppu/cell_surface.c @@ -34,30 +34,6 @@ #include "cell_surface.h" -/* Upload data to a rectangular sub-region. Lots of choices how to do this: - * - * - memcpy by span to current destination - * - upload data as new buffer and blit - * - * Currently always memcpy. - */ -static void -cell_surface_data(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - const void *src, unsigned src_pitch, - unsigned srcx, unsigned srcy, - unsigned width, unsigned height) -{ - pipe_copy_rect(pipe_surface_map(dst), - dst->cpp, - dst->pitch, - dstx, dsty, width, height, src, src_pitch, srcx, srcy); - - pipe_surface_unmap(dst); -} - - static void cell_surface_copy(struct pipe_context *pipe, boolean do_flip, @@ -70,12 +46,12 @@ cell_surface_copy(struct pipe_context *pipe, assert( dst->cpp == src->cpp ); pipe_copy_rect(pipe_surface_map(dst), - dst->cpp, - dst->pitch, + &dst->block, + dst->stride, dstx, dsty, width, height, pipe_surface_map(src), - do_flip ? -src->pitch : src->pitch, + do_flip ? -src->stride : src->stride, srcx, do_flip ? height - 1 - srcy : srcy); pipe_surface_unmap(src); @@ -86,7 +62,7 @@ cell_surface_copy(struct pipe_context *pipe, static void * get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) { - return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; + return (char *)dst_map + y / dst->block.height * dst->stride + x / dst->block.width * dst->block.size; } @@ -106,38 +82,13 @@ cell_surface_fill(struct pipe_context *pipe, unsigned i, j; void *dst_map = pipe_surface_map(dst); - assert(dst->pitch > 0); - assert(width <= dst->pitch); + assert(dst->stride > 0); - switch (dst->cpp) { + switch (dst->block.size) { case 1: - { - ubyte *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - memset(row, value, width); - row += dst->pitch; - } - } - break; case 2: - { - ushort *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = (ushort) value; - row += dst->pitch; - } - } - break; case 4: - { - unsigned *row = get_pointer(dst, dst_map, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = value; - row += dst->pitch; - } - } + pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value); break; case 8: { @@ -158,7 +109,7 @@ cell_surface_fill(struct pipe_context *pipe, row[j*4+2] = val2; row[j*4+3] = val3; } - row += dst->pitch * 4; + row += dst->stride/2; } } break; diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index 07717da8f6..533b64227d 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -65,12 +65,14 @@ cell_texture_layout(struct cell_texture * spt) pt->width[level] = width; pt->height[level] = height; pt->depth[level] = depth; + pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height); spt->level_offset[level] = spt->buffer_size; - spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * + spt->buffer_size += (pt->nblocksy[level] * ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * - width * pt->cpp; + pt->nblocksx[level] * pt->block.size; width = minify(width); height = minify(height); @@ -157,16 +159,18 @@ cell_get_tex_surface_screen(struct pipe_screen *screen, assert(ps->winsys); pipe_buffer_reference(ws, &ps->buffer, spt->buffer); ps->format = pt->format; - ps->cpp = pt->cpp; + ps->block = pt->block; ps->width = pt->width[level]; ps->height = pt->height[level]; - ps->pitch = ps->width; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = spt->stride[level]; ps->offset = spt->level_offset[level]; if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * - (pt->compressed ? ps->height/4 : ps->height) * - ps->width * ps->cpp; + ps->nblocksy * + ps->stride; } else { assert(face == 0); assert(zslice == 0); -- cgit v1.2.3 From 4f45dbc6aa9b55d96cf6aeb32117e117e333b4a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 27 Jun 2008 20:56:29 +0900 Subject: gdi: Update for cpp removal. --- src/gallium/winsys/gdi/wmesa.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c index 0b93f8c4c3..86b085ab84 100644 --- a/src/gallium/winsys/gdi/wmesa.c +++ b/src/gallium/winsys/gdi/wmesa.c @@ -477,13 +477,15 @@ wm_surface_alloc_storage(struct pipe_winsys *winsys, surf->width = width; surf->height = height; surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); + surf->nblocksy * surf->stride); if(!surf->buffer) return -1; -- cgit v1.2.3 From 5b9d823545ec588ea97cc599a278626b99430d81 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 27 Jun 2008 14:16:42 +0200 Subject: i915: Fix the last of the stride/pitch changes --- src/gallium/drivers/i915simple/i915_surface.c | 18 +++++++++--------- src/gallium/winsys/dri/intel/intel_screen.c | 4 ++-- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index 0061b22f26..4430e81626 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -64,10 +64,10 @@ i915_surface_copy(struct pipe_context *pipe, pipe_copy_rect(dst_map, &dst->block, dst->stride, - dstx, dsty, - width, height, - src_map, - do_flip ? -(int) src->stride : src->stride, + dstx, dsty, + width, height, + src_map, + do_flip ? -(int) src->stride : src->stride, srcx, do_flip ? height - 1 - srcy : srcy); pipe->screen->surface_unmap(pipe->screen, src); @@ -79,8 +79,8 @@ i915_surface_copy(struct pipe_context *pipe, i915_copy_blit( i915_context(pipe), do_flip, dst->block.size, - (short) src->stride/src->block.size, src->buffer, src->offset, - (short) dst->stride/dst->block.size, dst->buffer, dst->offset, + (short) src->stride, src->buffer, src->offset, + (short) dst->stride, dst->buffer, dst->offset, (short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height ); } } @@ -106,10 +106,10 @@ i915_surface_fill(struct pipe_context *pipe, assert(dst->block.height == 1); i915_fill_blit( i915_context(pipe), dst->block.size, - (short) dst->stride/dst->block.size, + (short) dst->stride, dst->buffer, dst->offset, - (short) dstx, (short) dsty, - (short) width, (short) height, + (short) dstx, (short) dsty, + (short) width, (short) height, value ); } } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 18427a4586..89de188ada 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -78,10 +78,10 @@ intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, templat.last_level = 0; templat.depth[0] = 1; templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; - templat.cpp = intelScreen->front.cpp; templat.width[0] = intelScreen->front.width; templat.height[0] = intelScreen->front.height; - pitch = intelScreen->front.pitch / intelScreen->front.cpp; + pf_get_block(templat.format, &templat.block); + pitch = intelScreen->front.pitch; texture = screen->texture_blanket(screen, &templat, diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 7f3babd98e..f58da97c64 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -89,7 +89,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, const drm_clip_rect_t *pbox = dPriv->pClipRects; const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; const int cpp = intelScreen->front.cpp; - const int srcpitch = surf->pitch; + const int srcpitch = surf->stride / cpp; int BR13, CMD; int i; -- cgit v1.2.3 From a1fb565ea7ac9f86beb4deece6a24d79e7b7860e Mon Sep 17 00:00:00 2001 From: Robert Ellison Date: Thu, 26 Jun 2008 08:55:00 -0600 Subject: egl: These changes allow an eglBindAPI(EGL_OPENGL_ES_API) to succeed, and to work correctly with GLES1 and GLES2. - egl_xdri.c just sets the EGL_OPENGL_ES_BIT as well as the EGL_OPENGL_BIT in ClientAPIsMask - eglconfig.c allows the renderable type to include EGL_OPENGL_ES2_BIT as well as EGL_OPENGL_ES_BIT. - egl_xlib.c sets the EGL_NATIVE_RENDERABLE attribute to EGL_FALSE for all softpipe configurations. (Otherwise, an eglChooseConfig() that looks for particular values of EGL_NATIVE_RENDERABLE will fail.) --- src/gallium/winsys/egl_xlib/egl_xlib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index eeb15e30a9..8045c0d0ca 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -172,6 +172,7 @@ create_configs(_EGLDriver *drv, EGLDisplay dpy) SET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE, sbits); SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_ID, visid); SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, vistype); + SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE); _eglAddConfig(disp, config); } -- cgit v1.2.3 From 429a08384c2ea66d446e46beb28e33ee3b764d52 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 27 Jun 2008 16:02:43 +0200 Subject: gallium: handle msaa --- src/gallium/include/pipe/p_state.h | 6 ++++-- src/gallium/winsys/dri/intel/intel_screen.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 2992e2f3b3..5546796936 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -276,7 +276,7 @@ struct pipe_surface unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ unsigned offset; /**< offset from start of buffer, in bytes */ unsigned refcount; - unsigned usage; /**< PIPE_BUFFER_USAGE_* */ + unsigned usage; /**< PIPE_BUFFER_USAGE_* */ struct pipe_winsys *winsys; /**< winsys which owns/created the surface */ @@ -311,7 +311,9 @@ struct pipe_texture unsigned last_level:8; /**< Index of last mipmap level present/defined */ unsigned compressed:1; - + + unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */ + unsigned tex_usage; /* PIPE_TEXTURE_USAGE_* */ /* These are also refcounted: diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index 89de188ada..cfecebdb8c 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -483,11 +483,13 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, uint8_t depth_bits_array[3]; uint8_t stencil_bits_array[3]; + uint8_t msaa_samples_array[1]; depth_bits_array[0] = 0; depth_bits_array[1] = depth_bits; depth_bits_array[2] = depth_bits; + msaa_samples_array[0] = 0; /* Just like with the accumulation buffer, always provide some modes * with a stencil buffer. It will be a sw fallback, but some apps won't @@ -521,7 +523,7 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_TRUE_COLOR)) { + back_buffer_factor, msaa_samples_array, 1, GLX_TRUE_COLOR)) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; @@ -529,7 +531,7 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_DIRECT_COLOR)) { + back_buffer_factor, msaa_samples_array, 1, GLX_DIRECT_COLOR)) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; -- cgit v1.2.3 From 838b0d6e480c9ae90abb067c1ba4aee413df6fd9 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 27 Jun 2008 15:56:09 -0400 Subject: eh, we need a buildbot... fix the compilation --- src/gallium/winsys/egl_xlib/egl_xlib.c | 2 +- src/gallium/winsys/egl_xlib/sw_winsys.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 8045c0d0ca..042d7a5457 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -291,7 +291,7 @@ display_surface(struct pipe_winsys *pws, ximage->data = data; ximage->width = psurf->width; ximage->height = psurf->height; - ximage->bytes_per_line = psurf->pitch * psurf->cpp; + ximage->bytes_per_line = psurf->stride; XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc, ximage, 0, 0, 0, 0, psurf->width, psurf->height); diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index 28cca9e581..6956fb5b6f 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -190,16 +190,14 @@ surface_alloc_storage(struct pipe_winsys *winsys, surf->width = width; surf->height = height; surf->format = format; - surf->cpp = pf_get_size(format); - surf->pitch = round_up(width, alignment / surf->cpp); + pf_get_block(format, &surf->block); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); surf->usage = flags; - assert(surf->cpp >= 1); - assert(surf->cpp <= 16); assert(!surf->buffer); surf->buffer = winsys->buffer_create(winsys, alignment, PIPE_BUFFER_USAGE_PIXEL, - surf->pitch * surf->cpp * height); + surf->stride * height); if(!surf->buffer) return -1; -- cgit v1.2.3 From a7499b7fc753653fd24a91b1ab6a5b68e479193b Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 27 Jun 2008 16:47:22 -0400 Subject: egl: helps if the stride is right --- src/gallium/winsys/egl_xlib/sw_winsys.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index 6956fb5b6f..f4199e6f89 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -190,7 +190,9 @@ surface_alloc_storage(struct pipe_winsys *winsys, surf->width = width; surf->height = height; surf->format = format; - pf_get_block(format, &surf->block); + pf_get_block(surf->format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); surf->usage = flags; -- cgit v1.2.3 From d4b100a6a1f13ceaedf603bdce5ce95c2ce7e12c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 28 Jun 2008 16:04:01 -0600 Subject: egl: set config's EGL_CONFORMANT, EGL_RENDERABLE_TYPE, EGL_SURFACE_TYPE attributes --- src/gallium/winsys/egl_xlib/egl_xlib.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 042d7a5457..83b8bb95b1 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -133,6 +133,10 @@ bitcount(unsigned int n) static void create_configs(_EGLDriver *drv, EGLDisplay dpy) { + static const EGLint all_apis = (EGL_OPENGL_ES_BIT | + EGL_OPENGL_ES2_BIT | + EGL_OPENVG_BIT | + EGL_OPENGL_BIT); _EGLDisplay *disp = _eglLookupDisplay(dpy); XVisualInfo *visInfo, visTemplate; int num_visuals, i; @@ -173,6 +177,9 @@ create_configs(_EGLDriver *drv, EGLDisplay dpy) SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_ID, visid); SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, vistype); SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE); + SET_CONFIG_ATTRIB(config, EGL_CONFORMANT, all_apis); + SET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE, all_apis); + SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT); _eglAddConfig(disp, config); } -- cgit v1.2.3 From b3da2a9524b47838da33d8f7fd63c5d90a659cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 1 Jul 2008 22:04:58 +0900 Subject: gallium: Use the inline keyword on C++. --- src/gallium/include/pipe/p_compiler.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index d2b8c41be3..2afb8464c7 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -107,7 +107,9 @@ typedef unsigned char boolean; /* Function inlining */ -#if defined(__GNUC__) +#ifdef __cplusplus +# define INLINE inline +#elif defined(__GNUC__) # define INLINE __inline__ #elif defined(_MSC_VER) # define INLINE __inline -- cgit v1.2.3 From e99ce4af8a6a6f9b257bfceb0f9133a29f06f2c7 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 1 Jul 2008 15:52:37 +0200 Subject: i915: Last reference to surface -> pitch --- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index f58da97c64..f751f97524 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -97,7 +97,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv, ASSERT(surf->cpp == cpp); DBG(SWAP, "screen pitch %d src surface pitch %d\n", - pitch, surf->pitch); + pitch, surf->stride); if (cpp == 2) { BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); -- cgit v1.2.3 From ea4ca10b1bec67c8a60db0e4e5581318ce9f62f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 2 Jul 2008 12:22:51 +0900 Subject: pipebuffer: Verify usage flag consistency. Minor cleanups. --- src/gallium/auxiliary/pipebuffer/pb_buffer.h | 19 +++++++++++++++---- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c | 3 +++ src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 10 +++++++--- src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 6 +++--- src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 9 ++++++--- src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 9 +++++++-- 8 files changed, 43 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index 857ea53c78..83ea0be74b 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -204,13 +204,24 @@ pb_reference(struct pb_buffer **dst, /** - * Utility function to check whether a requested alignment is consistent with - * the provided alignment or not. + * Utility function to check whether the provided alignment is consistent with + * the requested or not. */ -static INLINE int +static INLINE boolean pb_check_alignment(size_t requested, size_t provided) { - return requested <= provided && (provided % requested) == 0; + return requested <= provided && (provided % requested) == 0 ? TRUE : FALSE; +} + + +/** + * Utility function to check whether the provided alignment is consistent with + * the requested or not. + */ +static INLINE boolean +pb_check_usage(unsigned requested, unsigned provided) +{ + return (requested & provided) == provided ? TRUE : FALSE; } diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 7f236887a9..0ffca298cd 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -406,7 +406,7 @@ fenced_buffer_list_create(struct pipe_winsys *winsys) { struct fenced_buffer_list *fenced_list; - fenced_list = (struct fenced_buffer_list *)CALLOC(1, sizeof(*fenced_list)); + fenced_list = CALLOC_STRUCT(fenced_buffer_list); if (!fenced_list) return NULL; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c index 702bef1c04..0d2d6c0c1b 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c @@ -88,6 +88,9 @@ pb_alt_manager_create(struct pb_manager *provider1, { struct pb_alt_manager *mgr; + if(!provider1 || !provider2) + return NULL; + mgr = CALLOC_STRUCT(pb_alt_manager); if (!mgr) return NULL; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index f1a457dde4..bed4bec4fe 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -217,7 +217,8 @@ pb_cache_is_buffer_compat(struct pb_cache_buffer *buf, if(!pb_check_alignment(desc->alignment, buf->base.base.alignment)) return FALSE; - /* XXX: check usage too? */ + if(!pb_check_usage(desc->usage, buf->base.base.usage)) + return FALSE; return TRUE; } @@ -282,7 +283,7 @@ pb_cache_manager_create_buffer(struct pb_manager *_mgr, assert(buf->buffer->base.refcount >= 1); assert(pb_check_alignment(desc->alignment, buf->buffer->base.alignment)); - assert((buf->buffer->base.usage & desc->usage) == desc->usage); + assert(pb_check_usage(desc->usage, buf->buffer->base.usage)); assert(buf->buffer->base.size >= size); buf->base.base.refcount = 1; @@ -331,7 +332,10 @@ pb_cache_manager_create(struct pb_manager *provider, { struct pb_cache_manager *mgr; - mgr = (struct pb_cache_manager *)CALLOC(1, sizeof(*mgr)); + if(!provider) + return NULL; + + mgr = CALLOC_STRUCT(pb_cache_manager); if (!mgr) return NULL; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c index 9d809e2f9b..05efd8ce41 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c @@ -117,7 +117,7 @@ fenced_bufmgr_create(struct pb_manager *provider, if(!provider) return NULL; - fenced_mgr = (struct fenced_pb_manager *)CALLOC(1, sizeof(*fenced_mgr)); + fenced_mgr = CALLOC_STRUCT(fenced_pb_manager); if (!fenced_mgr) return NULL; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 0a1e8c83b1..c51e582611 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -29,7 +29,7 @@ * \file * Buffer manager using the old texture memory manager. * - * \author José Fonseca + * \author José Fonseca */ @@ -271,8 +271,8 @@ mm_bufmgr_create(struct pb_manager *provider, struct pb_manager *mgr; struct pb_desc desc; - assert(provider); - assert(provider->create_buffer); + if(!provider) + return NULL; memset(&desc, 0, sizeof(desc)); desc.alignment = 1 << align2; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index 528e9528f6..95af08929a 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -30,8 +30,8 @@ * \file * Batch buffer pool management. * - * \author José Fonseca - * \author Thomas Hellström + * \author José Fonseca + * \author Thomas Hellström */ @@ -229,7 +229,10 @@ pool_bufmgr_create(struct pb_manager *provider, struct pool_buffer *pool_buf; size_t i; - pool = (struct pool_pb_manager *)CALLOC(1, sizeof(*pool)); + if(!provider) + return NULL; + + pool = CALLOC_STRUCT(pool_pb_manager); if (!pool) return NULL; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index b9dff09804..598d9ce310 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -324,8 +324,10 @@ pb_slab_manager_create_buffer(struct pb_manager *_mgr, if(!pb_check_alignment(desc->alignment, mgr->bufSize)) return NULL; - /* XXX: check for compatible buffer usage too? */ - + assert(pb_check_usage(desc->usage, mgr->desc.usage)); + if(!pb_check_usage(desc->usage, mgr->desc.usage)) + return NULL; + _glthread_LOCK_MUTEX(mgr->mutex); if (mgr->slabs.next == &mgr->slabs) { (void) pb_slab_create(mgr); @@ -438,6 +440,9 @@ pb_slab_range_manager_create(struct pb_manager *provider, size_t bufSize; unsigned i; + if(!provider) + return NULL; + mgr = CALLOC_STRUCT(pb_slab_range_manager); if (!mgr) goto out_err0; -- cgit v1.2.3 From d16fcd07f876fe7fb29f5f4e3df4e83ff7de3422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 2 Jul 2008 12:24:19 +0900 Subject: pipebuffer: Debug buffer manager to detect buffer under- and overflows. It should detect both cpu and gpu buffer overflows. --- src/gallium/auxiliary/pipebuffer/Makefile | 1 + src/gallium/auxiliary/pipebuffer/SConscript | 1 + src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 11 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c | 297 +++++++++++++++++++++ 4 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile index 1d9b036c07..f9b39d9ce0 100644 --- a/src/gallium/auxiliary/pipebuffer/Makefile +++ b/src/gallium/auxiliary/pipebuffer/Makefile @@ -8,6 +8,7 @@ C_SOURCES = \ pb_buffer_malloc.c \ pb_bufmgr_alt.c \ pb_bufmgr_cache.c \ + pb_bufmgr_debug.c \ pb_bufmgr_fenced.c \ pb_bufmgr_mm.c \ pb_bufmgr_pool.c \ diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript index e52177bc79..56a40dda0d 100644 --- a/src/gallium/auxiliary/pipebuffer/SConscript +++ b/src/gallium/auxiliary/pipebuffer/SConscript @@ -7,6 +7,7 @@ pipebuffer = env.ConvenienceLibrary( 'pb_buffer_malloc.c', 'pb_bufmgr_alt.c', 'pb_bufmgr_cache.c', + 'pb_bufmgr_debug.c', 'pb_bufmgr_fenced.c', 'pb_bufmgr_mm.c', 'pb_bufmgr_pool.c', diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 00279f7010..32867029ee 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -175,7 +175,16 @@ struct pb_manager * pb_alt_manager_create(struct pb_manager *provider1, struct pb_manager *provider2); - + +/** + * Debug buffer manager to detect buffer under- and overflows. + * + * Band size should be a multiple of the largest alignment + */ +struct pb_manager * +pb_debug_manager_create(struct pb_manager *provider, size_t band_size); + + #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c new file mode 100644 index 0000000000..acb9d7ad14 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -0,0 +1,297 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Debug buffer manager to detect buffer under- and overflows. + * + * \author José Fonseca + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_winsys.h" +#include "pipe/p_thread.h" +#include "pipe/p_util.h" +#include "util/u_double_list.h" +#include "util/u_time.h" + +#include "pb_buffer.h" +#include "pb_bufmgr.h" + + +#ifdef DEBUG + + +/** + * Convenience macro (type safe). + */ +#define SUPER(__derived) (&(__derived)->base) + + +struct pb_debug_manager; + + +/** + * Wrapper around a pipe buffer which adds delayed destruction. + */ +struct pb_debug_buffer +{ + struct pb_buffer base; + + struct pb_buffer *buffer; + struct pb_debug_manager *mgr; + + size_t underflow_size; + size_t overflow_size; +}; + + +struct pb_debug_manager +{ + struct pb_manager base; + + struct pb_manager *provider; + + size_t band_size; +}; + + +static INLINE struct pb_debug_buffer * +pb_debug_buffer(struct pb_buffer *buf) +{ + assert(buf); + return (struct pb_debug_buffer *)buf; +} + + +static INLINE struct pb_debug_manager * +pb_debug_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct pb_debug_manager *)mgr; +} + + +static const uint8_t random_pattern[32] = { + 0xaf, 0xcf, 0xa5, 0xa2, 0xc2, 0x63, 0x15, 0x1a, + 0x7e, 0xe2, 0x7e, 0x84, 0x15, 0x49, 0xa2, 0x1e, + 0x49, 0x63, 0xf5, 0x52, 0x74, 0x66, 0x9e, 0xc4, + 0x6d, 0xcf, 0x2c, 0x4a, 0x74, 0xe6, 0xfd, 0x94 +}; + + +static INLINE void +fill_random_pattern(uint8_t *dst, size_t size) +{ + unsigned i = 0; + while(size--) { + *dst++ = random_pattern[i++]; + i &= sizeof(random_pattern) - 1; + } +} + + +static INLINE boolean +check_random_pattern(const uint8_t *dst, size_t size) +{ + unsigned i = 0; + while(size--) { + if(*dst++ != random_pattern[i++]) + return FALSE; + i &= sizeof(random_pattern) - 1; + } + return TRUE; +} + + +static void +pb_debug_buffer_destroy(struct pb_buffer *_buf) +{ + struct pb_debug_buffer *buf = pb_debug_buffer(_buf); + uint8_t *map; + + assert(!buf->base.base.refcount); + + map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_CPU_READ); + assert(map); + if(map) { + if(!check_random_pattern(map, buf->underflow_size)) { + debug_printf("buffer underflow\n"); + debug_assert(0); + } + if(!check_random_pattern(map + buf->underflow_size + buf->base.base.size, + buf->overflow_size)) { + debug_printf("buffer overflow\n"); + debug_assert(0); + } + pb_unmap(buf->buffer); + } + + pb_reference(&buf->buffer, NULL); + FREE(buf); +} + + +static void * +pb_debug_buffer_map(struct pb_buffer *_buf, + unsigned flags) +{ + struct pb_debug_buffer *buf = pb_debug_buffer(_buf); + void *map = pb_map(buf->buffer, flags); + if(!map) + return NULL; + return (uint8_t *)map + buf->underflow_size; +} + + +static void +pb_debug_buffer_unmap(struct pb_buffer *_buf) +{ + struct pb_debug_buffer *buf = pb_debug_buffer(_buf); + pb_unmap(buf->buffer); +} + + +static void +pb_debug_buffer_get_base_buffer(struct pb_buffer *_buf, + struct pb_buffer **base_buf, + unsigned *offset) +{ + struct pb_debug_buffer *buf = pb_debug_buffer(_buf); + pb_get_base_buffer(buf->buffer, base_buf, offset); + *offset += buf->underflow_size; +} + + +const struct pb_vtbl +pb_debug_buffer_vtbl = { + pb_debug_buffer_destroy, + pb_debug_buffer_map, + pb_debug_buffer_unmap, + pb_debug_buffer_get_base_buffer +}; + + +static struct pb_buffer * +pb_debug_manager_create_buffer(struct pb_manager *_mgr, + size_t size, + const struct pb_desc *desc) +{ + struct pb_debug_manager *mgr = pb_debug_manager(_mgr); + struct pb_debug_buffer *buf; + struct pb_desc real_desc; + size_t real_size; + uint8_t *map; + + buf = CALLOC_STRUCT(pb_debug_buffer); + if(!buf) + return NULL; + + real_size = size + 2*mgr->band_size; + real_desc = *desc; + real_desc.usage |= PIPE_BUFFER_USAGE_CPU_WRITE; + real_desc.usage |= PIPE_BUFFER_USAGE_CPU_READ; + + buf->buffer = mgr->provider->create_buffer(mgr->provider, + real_size, + &real_desc); + if(!buf->buffer) { + FREE(buf); + return NULL; + } + + assert(buf->buffer->base.refcount >= 1); + assert(pb_check_alignment(real_desc.alignment, buf->buffer->base.alignment)); + assert(pb_check_usage(real_desc.usage, buf->buffer->base.usage)); + assert(buf->buffer->base.size >= real_size); + + buf->base.base.refcount = 1; + buf->base.base.alignment = desc->alignment; + buf->base.base.usage = desc->usage; + buf->base.base.size = size; + + buf->base.vtbl = &pb_debug_buffer_vtbl; + buf->mgr = mgr; + + buf->underflow_size = mgr->band_size; + buf->overflow_size = buf->buffer->base.size - buf->underflow_size - size; + + map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + assert(map); + if(map) { + fill_random_pattern(map, buf->underflow_size); + fill_random_pattern(map + buf->underflow_size + size, buf->overflow_size); + pb_unmap(buf->buffer); + } + + return &buf->base; +} + + +static void +pb_debug_manager_destroy(struct pb_manager *_mgr) +{ + struct pb_debug_manager *mgr = pb_debug_manager(_mgr); + mgr->provider->destroy(mgr->provider); + FREE(mgr); +} + + +struct pb_manager * +pb_debug_manager_create(struct pb_manager *provider, size_t band_size) +{ + struct pb_debug_manager *mgr; + + if(!provider) + return NULL; + + mgr = CALLOC_STRUCT(pb_debug_manager); + if (!mgr) + return NULL; + + mgr->base.destroy = pb_debug_manager_destroy; + mgr->base.create_buffer = pb_debug_manager_create_buffer; + mgr->provider = provider; + mgr->band_size = band_size; + + return &mgr->base; +} + + +#else /* !DEBUG */ + + +struct pb_manager * +pb_debug_manager_create(struct pb_manager *provider, size_t band_size) +{ + return provider; +} + + +#endif /* !DEBUG */ -- cgit v1.2.3 From cc31eecbcb90dabacabac3e6be7c01cfe3a7a2a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 2 Jul 2008 12:10:15 +0200 Subject: gallium: Allow draw module to work on non-x86 platforms again. --- src/gallium/auxiliary/draw/draw_vs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 978954e91c..f798b20492 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -160,8 +160,10 @@ draw_vs_init( struct draw_context *draw ) return FALSE; draw->vs.aos_machine = draw_vs_aos_machine(); +#ifdef PIPE_ARCH_X86 if (!draw->vs.aos_machine) return FALSE; +#endif return TRUE; } -- cgit v1.2.3 From 019ad5e284db08b46b484b409c1a54c302afd50b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 2 Jul 2008 12:41:18 -0600 Subject: gallium: replace 128 with MAX_LABELS --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 2 +- src/gallium/auxiliary/tgsi/exec/tgsi_exec.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index 13b8c2e5bf..9649396c9b 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -214,7 +214,7 @@ tgsi_exec_machine_bind_shader( break; case TGSI_TOKEN_TYPE_INSTRUCTION: - assert( labels->count < 128 ); + assert( labels->count < MAX_LABELS ); labels->labels[labels->count][0] = instno; labels->labels[labels->count][1] = pointer; diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h index 19bd78df3d..ea182bc454 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h @@ -34,6 +34,8 @@ extern "C" { #endif +#define MAX_LABELS 1024 + #define NUM_CHANNELS 4 /* R,G,B,A */ #define QUAD_SIZE 4 /* 4 pixel/quad */ @@ -93,7 +95,7 @@ struct tgsi_sampler */ struct tgsi_exec_labels { - unsigned labels[128][2]; + unsigned labels[MAX_LABELS][2]; unsigned count; }; -- cgit v1.2.3 From 8fb4d602db48d425380e5508e3fd71cbdc2e7095 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 2 Jul 2008 19:05:18 -0600 Subject: gallium: nr_attrs was off by one, updated comments, minor code movement --- src/gallium/drivers/softpipe/sp_setup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 543d86a5cb..e99df9d018 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -1266,12 +1266,14 @@ void setup_prepare( struct setup_context *setup ) sp->framebuffer.zsbuf->status = PIPE_SURFACE_STATUS_DEFINED; } + /* Note: nr_attrs is only used for debugging (vertex printing) */ { const struct sp_fragment_shader *fs = setup->softpipe->fs; - setup->quad.nr_attrs = fs->info.num_inputs; - sp->quad.first->begin(sp->quad.first); + setup->quad.nr_attrs = fs->info.num_inputs + 1; /* +1 for vert pos */ } + sp->quad.first->begin(sp->quad.first); + if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES && sp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && sp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { -- cgit v1.2.3 From 8ccab313561d8cca3caf8d76504119bf5eb2e9ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 3 Jul 2008 15:02:56 +0900 Subject: gallium: Use surface_copy for 1:1 blits. --- src/gallium/auxiliary/util/u_blit.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index ae779335dc..c9e3abc88b 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -308,6 +308,16 @@ util_blit_pixels(struct blit_state *ctx, } assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE)); + assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE)); + + if(dst->format == src->format && (dstX1 - dstX0) == srcW && (dstY1 - dstY0) == srcH) { + pipe->surface_copy(pipe, FALSE, + dst, dstX0, dstY0, /* dest */ + src, srcX0, srcY0, /* src */ + srcW, srcH); /* size */ + return; + } + assert(screen->is_format_supported(screen, dst->format, PIPE_SURFACE)); /* -- cgit v1.2.3 From d94c7063ec9e87dbefea386606f0f21cdbd1d6f3 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 3 Jul 2008 12:12:25 +0200 Subject: i915: EGL almost works again --- src/gallium/winsys/egl_drm/intel/intel_context.c | 3 + src/gallium/winsys/egl_drm/intel/intel_context.h | 3 +- src/gallium/winsys/egl_drm/intel/intel_egl.c | 85 +++++++++++++--------- src/gallium/winsys/egl_drm/intel/intel_screen.c | 4 +- src/gallium/winsys/egl_drm/intel/intel_screen.h | 3 + .../winsys/egl_drm/intel/intel_swapbuffers.c | 9 ++- 6 files changed, 67 insertions(+), 40 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index fdbaa230e5..7205fa4483 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -172,6 +172,9 @@ intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes pipe->priv = intel; intel->st = st_create_context(pipe, visual, st_share); + + screen->dummy = intel; + return TRUE; } diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h index ccf8120761..f05a213ff0 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -64,8 +64,7 @@ struct intel_framebuffer { struct st_framebuffer *stfb; - /* other fields TBD */ - int other; + struct intel_screen *screen; struct _DriBufferObject *front_buffer; struct egl_drm_frontbuffer *front; }; diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 3b4ab330f5..6865bfa3d4 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -74,9 +74,11 @@ struct drm_screen uint32_t fbID; drmModeCrtcPtr crtc; - /* currently only support one output */ - drmModeOutputPtr output; - uint32_t outputID; + /* currently only support one connector */ + drmModeConnectorPtr connector; + drmModeEncoderPtr encoder; + uint32_t connectorID; + uint32_t encoderID; struct drm_mode_modeinfo *mode; @@ -92,26 +94,39 @@ drm_update_res(struct drm_driver *drm_drv) } static void -drm_add_modes_from_output(_EGLScreen *screen, drmModeOutputPtr output) +drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) { struct drm_mode_modeinfo *m; int i; - for (i = 0; i < output->count_modes; i++) { - m = &output->modes[i]; + for (i = 0; i < connector->count_modes; i++) { + m = &connector->modes[i]; _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); } } +static void +print_modes(drmModeConnectorPtr connector) +{ + struct drm_mode_modeinfo *m; + int i; + + for (i = 0; i < connector->count_modes; i++) { + m = &connector->modes[i]; + printf("dfm %p %i %i %i\n", m, m->hdisplay, m->vdisplay, m->vrefresh); + } +} + static EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) { + printf("%s enter\n", __FUNCTION__); _EGLDisplay *disp = _eglLookupDisplay(dpy); struct drm_driver *drm_drv = (struct drm_driver *)drv; struct drm_screen *screen = NULL; - drmModeOutputPtr output = NULL; + drmModeConnectorPtr connector = NULL; drmModeResPtr res = NULL; - unsigned count_outputs = 0; + unsigned count_connectors = 0; EGLint i; int fd; @@ -130,40 +145,41 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) drm_update_res(drm_drv); res = drm_drv->res; if (res) - count_outputs = res->count_outputs; + count_connectors = res->count_connectors; - for(i = 0; i < count_outputs; i++) { - output = drmModeGetOutput(fd, res->outputs[i]); + for(i = 0; i < count_connectors; i++) { + connector = drmModeGetConnector(fd, res->connectors[i]); - if (!output) + if (!connector) continue; - if (output->connection == DRM_MODE_DISCONNECTED) { - drmModeFreeOutput(output); + if (connector->connection == DRM_MODE_DISCONNECTED) { + drmModeFreeConnector(connector); continue; } screen = malloc(sizeof(struct drm_screen)); memset(screen, 0, sizeof(*screen)); - screen->outputID = res->outputs[i]; - screen->output = output; + screen->connectorID = res->connectors[i]; + screen->connector = connector; _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); - drm_add_modes_from_output(&screen->base, output); + drm_add_modes_from_connector(&screen->base, connector); } /* for now we only have one config */ - _EGLConfig config; - _eglInitConfig(&config, i + 1); - _eglSetConfigAttrib(&config, EGL_RED_SIZE, 8); - _eglSetConfigAttrib(&config, EGL_GREEN_SIZE, 8); - _eglSetConfigAttrib(&config, EGL_BLUE_SIZE, 8); - _eglSetConfigAttrib(&config, EGL_ALPHA_SIZE, 8); - _eglSetConfigAttrib(&config, EGL_BUFFER_SIZE, 32); - _eglSetConfigAttrib(&config, EGL_DEPTH_SIZE, 24); - _eglSetConfigAttrib(&config, EGL_STENCIL_SIZE, 8); - _eglSetConfigAttrib(&config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); - _eglAddConfig(disp, &config); + _EGLConfig *config = calloc(1, sizeof(*config)); + memset(config, 1, sizeof(*config)); + _eglInitConfig(config, 1); + _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); + _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); + _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); + _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); + _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); + _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24); + _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); + _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); + _eglAddConfig(disp, config); drv->Initialized = EGL_TRUE; @@ -401,13 +417,13 @@ drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, } static struct drm_mode_modeinfo * -drm_find_mode(drmModeOutputPtr output, _EGLMode *mode) +drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) { int i; struct drm_mode_modeinfo *m; - for (i = 0; i < output->count_modes; i++) { - m = &output->modes[i]; + for (i = 0; i < connector->count_modes; i++) { + m = &connector->modes[i]; if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) break; m = NULL; @@ -493,7 +509,7 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, if (!scrn->fb) goto err_bo; - scrn->mode = drm_find_mode(scrn->output, mode); + scrn->mode = drm_find_mode(scrn->connector, mode); if (!scrn->mode) { printf("oh noes, no matching mode found\n"); goto err_fb; @@ -504,7 +520,7 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, drm_drv->res->crtcs[1], scrn->fbID, 0, 0, - &scrn->outputID, 1, + &scrn->connectorID, 1, scrn->mode); @@ -549,7 +565,6 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re struct drm_context *ctx = lookup_drm_context(context); EGLBoolean b; - printf("drm_make_current\n"); b = _eglMakeCurrent(drv, dpy, draw, read, context); if (!b) return EGL_FALSE; @@ -559,7 +574,6 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re (void) readSurf; (void) ctx; - printf("enter intel_make_current\n"); intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); return EGL_TRUE; } @@ -588,6 +602,7 @@ _EGLDriver * _eglMain(_EGLDisplay *dpy, const char *args) { struct drm_driver *drm; + printf("%s enter\n", __FUNCTION__); drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); if (!drm) { diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c index 96b0bf1b85..2818b9676c 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.c @@ -56,7 +56,7 @@ intel_init_driver(struct egl_drm_device *device) /** TODO JB: ugly hack */ intel_screen->deviceID = PCI_CHIP_I945_GM; - intel_be_init_device(&intel_screen->base, device->drmFD); + intel_be_init_device(&intel_screen->base, device->drmFD, PCI_CHIP_I945_GM); intel_screen->pipe = i915_create_screen(&intel_screen->base.base, intel_screen->deviceID); @@ -76,6 +76,8 @@ intel_create_drawable(struct egl_drm_drawable *drawable, if (!intelfb) return GL_FALSE; + intelfb->screen = drawable->device->priv; + if (visual->redBits == 5) colorFormat = PIPE_FORMAT_R5G6B5_UNORM; else diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_screen.h index 87c4406f54..9b990b48e7 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.h +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.h @@ -34,6 +34,7 @@ struct pipe_screen; struct egl_drm_device; +struct intel_context; struct intel_screen { @@ -42,6 +43,8 @@ struct intel_screen int deviceID; struct egl_drm_device *device; + + struct intel_context *dummy; }; #endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c index 24e55f1568..bfff6f935f 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -68,18 +68,23 @@ intel_display_surface(struct egl_drm_drawable *draw, //const int srcWidth = surf->width; //const int srcHeight = surf->height; - const int srcPitch = surf->pitch; + + intel = intel_fb->screen->dummy; + if (!intel) { + printf("No dummy context\n"); + return; + } const int dstWidth = intel_fb->front->width; const int dstHeight = intel_fb->front->height; const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp; const int cpp = 4;//intel_fb->front->cpp; + const int srcPitch = surf->stride / cpp; int BR13, CMD; //int i; - BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); -- cgit v1.2.3 From c193cc506f74443c805a0df42e3364b39245d265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 3 Jul 2008 19:52:05 +0900 Subject: gallium: Don't forget to get overllaping blits working again. --- src/gallium/auxiliary/util/u_blit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index c9e3abc88b..3dc9fdd11e 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -311,6 +311,7 @@ util_blit_pixels(struct blit_state *ctx, assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE)); if(dst->format == src->format && (dstX1 - dstX0) == srcW && (dstY1 - dstY0) == srcH) { + /* FIXME: this will most surely fail for overlapping rectangles */ pipe->surface_copy(pipe, FALSE, dst, dstX0, dstY0, /* dest */ src, srcX0, srcY0, /* src */ -- cgit v1.2.3 From ade03755bcaec2dedb5cd4d13160ba366ee804cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 3 Jul 2008 21:28:56 +0900 Subject: pipebuffer: Silent warnings. Although rarely hit in normal apps, they are too noisy with test suites. --- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 0ffca298cd..f599bee07e 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -174,7 +174,9 @@ _fenced_buffer_finish(struct fenced_buffer *fenced_buf) struct fenced_buffer_list *fenced_list = fenced_buf->list; struct pipe_winsys *winsys = fenced_list->winsys; +#if 0 debug_warning("waiting for GPU"); +#endif assert(fenced_buf->fence); if(fenced_buf->fence) { @@ -278,11 +280,13 @@ fenced_buffer_map(struct pb_buffer *buf, _fenced_buffer_finish(fenced_buf); } +#if 0 /* Check for CPU write access (read is OK) */ if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) { /* this is legal -- just for debugging */ debug_warning("concurrent CPU writes"); } +#endif map = pb_map(fenced_buf->buffer, flags); if(map) { -- cgit v1.2.3 From 3c128748579c637ba7c777ba91ff4287a03190f6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Jul 2008 10:42:31 -0600 Subject: gallium: increase TGSI_EXEC_MAX_COND_NESTING, etc --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h index ea182bc454..c89dfcb167 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h @@ -147,9 +147,9 @@ struct tgsi_exec_labels #define TGSI_EXEC_NUM_ADDRS 1 #define TGSI_EXEC_NUM_IMMEDIATES 256 -#define TGSI_EXEC_MAX_COND_NESTING 10 -#define TGSI_EXEC_MAX_LOOP_NESTING 10 -#define TGSI_EXEC_MAX_CALL_NESTING 10 +#define TGSI_EXEC_MAX_COND_NESTING 20 +#define TGSI_EXEC_MAX_LOOP_NESTING 20 +#define TGSI_EXEC_MAX_CALL_NESTING 20 /** * Run-time virtual machine state for executing TGSI shader. -- cgit v1.2.3 From f042d662e2cec4315ddaae1ee536f593139f703d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Jul 2008 12:56:33 -0600 Subject: gallium: increase TGSI interpreter's number of temp registers to 64 Also, clean up the definitions of the misc/extra temp regs. A few new assertions too. --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 4 ++- src/gallium/auxiliary/tgsi/exec/tgsi_exec.h | 48 +++++++++++++++-------------- 2 files changed, 28 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index 9649396c9b..46949661af 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -262,7 +262,7 @@ tgsi_exec_machine_init( uint i; mach->Temps = (struct tgsi_exec_vector *) tgsi_align_128bit( mach->_Temps); - mach->Addrs = &mach->Temps[TGSI_EXEC_NUM_TEMPS]; + mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR]; /* Setup constants. */ for( i = 0; i < 4; i++ ) { @@ -941,6 +941,7 @@ fetch_src_file_channel( break; case TGSI_FILE_TEMPORARY: + assert(index->i[0] < TGSI_EXEC_NUM_TEMPS); chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0]; chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1]; chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2]; @@ -1127,6 +1128,7 @@ store_dest( break; case TGSI_FILE_TEMPORARY: + assert(reg->DstRegister.Index < TGSI_EXEC_NUM_TEMPS); dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index]; break; diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h index c89dfcb167..18abdd9ac0 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h @@ -99,53 +99,57 @@ struct tgsi_exec_labels unsigned count; }; + +#define TGSI_EXEC_NUM_TEMPS 64 +#define TGSI_EXEC_NUM_TEMP_EXTRAS 6 +#define TGSI_EXEC_NUM_IMMEDIATES 256 + /* * Locations of various utility registers (_I = Index, _C = Channel) */ -#define TGSI_EXEC_TEMP_00000000_I 32 +#define TGSI_EXEC_TEMP_00000000_I (TGSI_EXEC_NUM_TEMPS + 0) #define TGSI_EXEC_TEMP_00000000_C 0 -#define TGSI_EXEC_TEMP_7FFFFFFF_I 32 +#define TGSI_EXEC_TEMP_7FFFFFFF_I (TGSI_EXEC_NUM_TEMPS + 0) #define TGSI_EXEC_TEMP_7FFFFFFF_C 1 -#define TGSI_EXEC_TEMP_80000000_I 32 +#define TGSI_EXEC_TEMP_80000000_I (TGSI_EXEC_NUM_TEMPS + 0) #define TGSI_EXEC_TEMP_80000000_C 2 -#define TGSI_EXEC_TEMP_FFFFFFFF_I 32 +#define TGSI_EXEC_TEMP_FFFFFFFF_I (TGSI_EXEC_NUM_TEMPS + 0) #define TGSI_EXEC_TEMP_FFFFFFFF_C 3 -#define TGSI_EXEC_TEMP_ONE_I 33 +#define TGSI_EXEC_TEMP_ONE_I (TGSI_EXEC_NUM_TEMPS + 1) #define TGSI_EXEC_TEMP_ONE_C 0 -#define TGSI_EXEC_TEMP_TWO_I 33 +#define TGSI_EXEC_TEMP_TWO_I (TGSI_EXEC_NUM_TEMPS + 1) #define TGSI_EXEC_TEMP_TWO_C 1 -#define TGSI_EXEC_TEMP_128_I 33 +#define TGSI_EXEC_TEMP_128_I (TGSI_EXEC_NUM_TEMPS + 1) #define TGSI_EXEC_TEMP_128_C 2 -#define TGSI_EXEC_TEMP_MINUS_128_I 33 +#define TGSI_EXEC_TEMP_MINUS_128_I (TGSI_EXEC_NUM_TEMPS + 1) #define TGSI_EXEC_TEMP_MINUS_128_C 3 -#define TGSI_EXEC_TEMP_KILMASK_I 34 +#define TGSI_EXEC_TEMP_KILMASK_I (TGSI_EXEC_NUM_TEMPS + 2) #define TGSI_EXEC_TEMP_KILMASK_C 0 -#define TGSI_EXEC_TEMP_OUTPUT_I 34 +#define TGSI_EXEC_TEMP_OUTPUT_I (TGSI_EXEC_NUM_TEMPS + 2) #define TGSI_EXEC_TEMP_OUTPUT_C 1 -#define TGSI_EXEC_TEMP_PRIMITIVE_I 34 +#define TGSI_EXEC_TEMP_PRIMITIVE_I (TGSI_EXEC_NUM_TEMPS + 2) #define TGSI_EXEC_TEMP_PRIMITIVE_C 2 -#define TGSI_EXEC_TEMP_THREE_I 34 +#define TGSI_EXEC_TEMP_THREE_I (TGSI_EXEC_NUM_TEMPS + 2) #define TGSI_EXEC_TEMP_THREE_C 3 -#define TGSI_EXEC_TEMP_HALF_I 35 +#define TGSI_EXEC_TEMP_HALF_I (TGSI_EXEC_NUM_TEMPS + 3) #define TGSI_EXEC_TEMP_HALF_C 0 -#define TGSI_EXEC_TEMP_R0 36 +#define TGSI_EXEC_TEMP_R0 (TGSI_EXEC_NUM_TEMPS + 4) + +#define TGSI_EXEC_TEMP_ADDR (TGSI_EXEC_NUM_TEMPS + 5) -#define TGSI_EXEC_NUM_TEMPS (32 + 5) -#define TGSI_EXEC_NUM_ADDRS 1 -#define TGSI_EXEC_NUM_IMMEDIATES 256 #define TGSI_EXEC_MAX_COND_NESTING 20 #define TGSI_EXEC_MAX_LOOP_NESTING 20 @@ -156,13 +160,11 @@ struct tgsi_exec_labels */ struct tgsi_exec_machine { - /* - * 32 program temporaries - * 4 internal temporaries - * 1 address - * 1 temporary of padding to align to 16 bytes + /* Total = program temporaries + internal temporaries + * + 1 padding to align to 16 bytes */ - struct tgsi_exec_vector _Temps[TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_ADDRS + 1]; + struct tgsi_exec_vector _Temps[TGSI_EXEC_NUM_TEMPS + + TGSI_EXEC_NUM_TEMP_EXTRAS + 1]; /* * This will point to _Temps after aligning to 16B boundary. -- cgit v1.2.3 From 51abbdd227224c596ae2232ff3137dc3f346d563 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Jul 2008 14:55:14 -0600 Subject: gallium: added a4r4g4b4_put_tile_rgba() --- src/gallium/auxiliary/util/p_tile.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index ab603ff6e4..93abef9879 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -298,6 +298,33 @@ a4r4g4b4_get_tile_rgba(ushort *src, } +static void +a4r4g4b4_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b, a; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + r >>= 4; + g >>= 4; + b >>= 4; + a >>= 4; + *dst++ = (a << 12) | (r << 16) | (g << 4) | b; + } + p += src_stride; + } +} + + /*** PIPE_FORMAT_R5G6B5_UNORM ***/ static void @@ -774,6 +801,10 @@ pipe_put_tile_rgba(struct pipe_context *pipe, r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_R8G8B8A8_UNORM: + assert(0); + break; + case PIPE_FORMAT_A4R4G4B4_UNORM: + a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_L8_UNORM: /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ -- cgit v1.2.3 From 1942e29bf7e4df34164ed815ccd77b08cd28ed56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 5 Jul 2008 00:55:18 +0900 Subject: softpipe: Implement texture blankets. --- src/gallium/drivers/softpipe/sp_texture.c | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 4db045cdc3..20ad336b4f 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -162,6 +162,39 @@ softpipe_texture_create(struct pipe_screen *screen, } +static struct pipe_texture * +softpipe_texture_blanket(struct pipe_screen * screen, + const struct pipe_texture *base, + const unsigned *stride, + struct pipe_buffer *buffer) +{ + struct softpipe_texture *spt; + assert(screen); + + /* Only supports one type */ + if (base->target != PIPE_TEXTURE_2D || + base->last_level != 0 || + base->depth[0] != 1) { + return NULL; + } + + spt = CALLOC_STRUCT(softpipe_texture); + if (!spt) + return NULL; + + spt->base = *base; + spt->base.refcount = 1; + spt->base.screen = screen; + spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]); + spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]); + spt->stride[0] = stride[0]; + + pipe_buffer_reference(screen->winsys, &spt->buffer, buffer); + + return &spt->base; +} + + static void softpipe_texture_release(struct pipe_screen *screen, struct pipe_texture **pt) @@ -309,6 +342,7 @@ void softpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = softpipe_texture_create; + screen->texture_blanket = softpipe_texture_blanket; screen->texture_release = softpipe_texture_release; screen->get_tex_surface = softpipe_get_tex_surface; -- cgit v1.2.3 From 4a18324c0bca4ae806b1c62cad44e859f0924a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 5 Jul 2008 00:56:36 +0900 Subject: psb: Fill all texture fields when creating texture blanket. --- src/gallium/drivers/i915simple/i915_texture.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 2815e61345..5d6769924c 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -710,6 +710,8 @@ i915_texture_blanket(struct pipe_screen * screen, return NULL; tex->base = *base; + tex->base.refcount = 1; + tex->base.screen = screen; tex->stride = stride[0]; -- cgit v1.2.3 From ba9e6339028c36269cb50bb8535e415fa8e6e4c9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 4 Jul 2008 09:59:43 -0600 Subject: gallium: fix trim() function bug when count < first If the user called glDrawArrays(GL_TRIANGLES, count=1), trim() returned a very large integer because of the unsigned arithmetic. --- src/gallium/auxiliary/draw/draw_pt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 9140faeea9..85a75525c8 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -37,6 +37,8 @@ static unsigned trim( unsigned count, unsigned first, unsigned incr ) { + if (count < first) + return 0; return count - (count - first) % incr; } -- cgit v1.2.3 From f6e8963bb152166c28dae896a0c8c83ce554f987 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 4 Jul 2008 19:20:08 +0200 Subject: i915: Clean up intel_egl.c a bit --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 6865bfa3d4..cc4fb247d5 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -33,8 +33,8 @@ egl_drm_create_device(int drmFD) device->drmFD = drmFD; if (!intel_init_driver(device)) { - printf("EGL: failed to initalize device\n"); free(device); + return NULL; } return device; @@ -105,22 +105,9 @@ drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) } } -static void -print_modes(drmModeConnectorPtr connector) -{ - struct drm_mode_modeinfo *m; - int i; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - printf("dfm %p %i %i %i\n", m, m->hdisplay, m->vdisplay, m->vrefresh); - } -} - static EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) { - printf("%s enter\n", __FUNCTION__); _EGLDisplay *disp = _eglLookupDisplay(dpy); struct drm_driver *drm_drv = (struct drm_driver *)drv; struct drm_screen *screen = NULL; @@ -490,10 +477,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, DRM_BO_FLAG_NO_EVICT, DRM_BO_HINT_DONT_FENCE, &scrn->buffer); - if (ret) { - printf("failed to create framebuffer (ret %d)\n", ret); + if (ret) return EGL_FALSE; - } prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); @@ -510,10 +495,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, goto err_bo; scrn->mode = drm_find_mode(scrn->connector, mode); - if (!scrn->mode) { - printf("oh noes, no matching mode found\n"); + if (!scrn->mode) goto err_fb; - } ret = drmModeSetCrtc( drm_drv->device->drmFD, @@ -602,7 +585,6 @@ _EGLDriver * _eglMain(_EGLDisplay *dpy, const char *args) { struct drm_driver *drm; - printf("%s enter\n", __FUNCTION__); drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); if (!drm) { -- cgit v1.2.3 From e6c24539c3d482271a8c1bcba697b08e24344e05 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 4 Jul 2008 19:23:52 +0200 Subject: i915: Added debug filling code of texture, not active --- src/gallium/drivers/i915simple/i915_texture.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 5d6769924c..cf4964b26b 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -581,6 +581,7 @@ i915_texture_create(struct pipe_screen *screen, struct i915_screen *i915screen = i915_screen(screen); struct pipe_winsys *ws = screen->winsys; struct i915_texture *tex = CALLOC_STRUCT(i915_texture); + size_t tex_size; if (!tex) return NULL; @@ -600,14 +601,22 @@ i915_texture_create(struct pipe_screen *screen, goto fail; } + tex_size = tex->stride * tex->total_nblocksy; + tex->buffer = ws->buffer_create(ws, 64, PIPE_BUFFER_USAGE_PIXEL, - tex->stride * - tex->total_nblocksy); + tex_size); if (!tex->buffer) goto fail; +#if 0 + void *ptr = ws->buffer_map(ws, tex->buffer, + PIPE_BUFFER_USAGE_CPU_WRITE); + memset(ptr, 0x80, tex_size); + ws->buffer_unmap(ws, tex->buffer); +#endif + return &tex->base; fail: -- cgit v1.2.3 From c23b64f1646ac5349c395ede47707906ddff7b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 5 Jul 2008 03:19:56 +0900 Subject: softpipe: Compute block size for display targets. --- src/gallium/drivers/softpipe/sp_texture.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 20ad336b4f..f775591352 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -122,8 +122,10 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, /* Now extract the goodies: */ - spt->buffer = surf.buffer; + spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]); + spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]); spt->stride[0] = surf.stride; + spt->buffer = surf.buffer; return spt->buffer != NULL; } -- cgit v1.2.3 From 152ed98b84acf500f4b5122cf3fde82c6e5206f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 5 Jul 2008 03:21:27 +0900 Subject: softpipe: Prevent NULL ptr derreference on takedown. --- src/gallium/drivers/softpipe/sp_state_fs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 24b91fbc79..901c8f83e7 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -154,8 +154,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, /* note: reference counting */ pipe_buffer_reference(ws, &softpipe->constants[shader].buffer, - buf->buffer); - softpipe->constants[shader].size = buf->size; + buf ? buf->buffer : NULL); + softpipe->constants[shader].size = buf ? buf->size : 0; softpipe->dirty |= SP_NEW_CONSTANTS; } -- cgit v1.2.3 From 74db8e9b3f354b5afa30f7cd52a511504693a3c8 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sat, 5 Jul 2008 14:04:02 +0200 Subject: i915: Fix haveDepth and haveStencil for visual in EGL --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index cc4fb247d5..a008d952bf 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -224,7 +224,9 @@ visual_from_config(_EGLConfig *conf) visual->doubleBufferMode = 1; visual->depthBits = 24; + visual->haveDepthBuffer = visual->depthBits > 0; visual->stencilBits = 8; + visual->haveStencilBuffer = visual->stencilBits > 0; return visual; } -- cgit v1.2.3 From c6d6a57424b77ff7de611333046c054d1948ae7a Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sat, 5 Jul 2008 15:58:42 +0200 Subject: i915: Added a intel be function to wrap a drm bo handle --- .../winsys/common/intel_drm/intel_be_device.c | 33 ++++++++++++++++++++++ .../winsys/common/intel_drm/intel_be_device.h | 13 +++++++-- src/gallium/winsys/dri/intel/intel_screen.c | 22 ++++++--------- 3 files changed, 52 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c index efb57a394e..8db0329615 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.c +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c @@ -125,6 +125,37 @@ intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned byte return &buffer->base; } +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle) +{ + struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); + struct pipe_buffer *buffer; + + if (!be_buf) + goto err; + + memset(be_buf, 0, sizeof(*be_buf)); + + driGenBuffers(device->staticPool, name, 1, &be_buf->driBO, 0, 0, 0); + driBOSetReferenced(be_buf->driBO, handle); + + if (0) /** XXX TODO check error */ + goto err_bo; + + buffer = &be_buf->base; + buffer->refcount = 1; + buffer->alignment = 0; + buffer->usage = 0; + buffer->size = driBOSize(be_buf->driBO); + + return buffer; +err_bo: + free(be_buf); +err: + return NULL; +} + /* * Surface functions. @@ -157,6 +188,7 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) assert((size_t)"intel_i915_surface_release is deprecated" & 0); } + /* * Fence functions */ @@ -189,6 +221,7 @@ intel_be_fence_finish( struct pipe_winsys *sws, return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); } + /* * Misc functions */ diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h index abf0253917..3f8b3f585c 100644 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.h +++ b/src/gallium/winsys/common/intel_drm/intel_be_device.h @@ -48,14 +48,23 @@ struct intel_be_buffer { struct _DriBufferObject *driBO; }; +/** + * Create a be buffer from a drm bo handle + * + * Takes a reference + */ +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle); + static INLINE struct intel_be_buffer * -intel_be_buffer( struct pipe_buffer *buf ) +intel_be_buffer(struct pipe_buffer *buf) { return (struct intel_be_buffer *)buf; } static INLINE struct _DriBufferObject * -dri_bo( struct pipe_buffer *buf ) +dri_bo(struct pipe_buffer *buf) { return intel_be_buffer(buf)->driBO; } diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index cfecebdb8c..f2412217f3 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -49,28 +49,22 @@ intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, static void intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle) { - struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); struct pipe_screen *screen = intelScreen->base.screen; struct pipe_texture *texture; struct pipe_texture templat; struct pipe_surface *surface; - struct pipe_buffer *buffer = &be_buf->base; + struct pipe_buffer *buffer; unsigned pitch; assert(intelScreen->front.cpp == 4); - /* XXX create a intel_be function for this */ - { - driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0); - driBOSetReferenced(intelScreen->front.buffer, handle); - - memset(be_buf, 0, sizeof(*be_buf)); - buffer->refcount = 1; - buffer->alignment = 0; - buffer->usage = 0; - buffer->size = driBOSize(intelScreen->front.buffer); - be_buf->driBO = intelScreen->front.buffer; - } + buffer = intel_be_buffer_from_handle(&intelScreen->base, + "front", handle); + + if (!buffer) + return; + + intelScreen->front.buffer = dri_bo(buffer); memset(&templat, 0, sizeof(templat)); templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; -- cgit v1.2.3 From b30fb6d54019c84174379a773121438ba943557a Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sat, 5 Jul 2008 16:46:04 +0200 Subject: i915: Fix EGL version and name --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index a008d952bf..e078b9eda1 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -171,7 +171,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) drv->Initialized = EGL_TRUE; *major = 1; - *minor = 0; + *minor = 4; return EGL_TRUE; } @@ -610,6 +610,7 @@ _eglMain(_EGLDisplay *dpy, const char *args) drm->base.API.SwapBuffers = drm_swap_buffers; drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; + drm->base.Name = "DRM/Gallium"; /* enable supported extensions */ drm->base.Extensions.MESA_screen_surface = EGL_TRUE; -- cgit v1.2.3 From 1315f720ba80596b866103a7e153bfc2f2bd267b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Jul 2008 13:24:09 +0200 Subject: i915: Destruction of surface, context and device in EGL --- src/gallium/winsys/egl_drm/intel/intel_context.c | 14 +++++++++++ src/gallium/winsys/egl_drm/intel/intel_egl.c | 21 ++++++++++++---- src/gallium/winsys/egl_drm/intel/intel_egl.h | 8 +++++- src/gallium/winsys/egl_drm/intel/intel_screen.c | 31 +++++++++++++++++++++--- 4 files changed, 65 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index 7205fa4483..7513f3feef 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -178,6 +178,20 @@ intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes return TRUE; } +int +intel_destroy_context(struct egl_drm_context *egl_context) +{ + struct intel_context *intel = egl_context->priv; + + if (intel->intel_screen->dummy == intel) + intel->intel_screen->dummy = NULL; + + st_destroy_context(intel->st); + intel_be_destroy_context(&intel->base); + free(intel); + return TRUE; +} + void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read) { diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index e078b9eda1..9e12a024eb 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -32,7 +32,7 @@ egl_drm_create_device(int drmFD) memset(device, 0, sizeof(*device)); device->drmFD = drmFD; - if (!intel_init_driver(device)) { + if (!intel_create_device(device)) { free(device); return NULL; } @@ -180,8 +180,15 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) static EGLBoolean drm_terminate(_EGLDriver *drv, EGLDisplay dpy) { - /* TODO: clean up */ - free(drv); + struct drm_driver *drm_drv = (struct drm_driver *)drv; + + intel_destroy_device(drm_drv->device); + + drmClose(drm_drv->device->drmFD); + + free(drm_drv->device); + free(drm_drv); + return EGL_TRUE; } @@ -303,6 +310,8 @@ drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) if (fc->base.IsBound) { fc->base.DeletePending = EGL_TRUE; } else { + intel_destroy_context(fc->context); + free(fc->context); free(fc); } return EGL_TRUE; @@ -322,6 +331,7 @@ drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, Nat return EGL_NO_SURFACE; } + static EGLSurface drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) @@ -534,14 +544,15 @@ drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) if (fs->base.IsBound) { fs->base.DeletePending = EGL_TRUE; } else { + intel_bind_frontbuffer(fs->drawable, NULL); + intel_destroy_drawable(fs->drawable); + free(fs->drawable); free(fs); } return EGL_TRUE; } - - static EGLBoolean drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) { diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h index 18e84e8eea..84b6c212bf 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.h +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.h @@ -32,9 +32,15 @@ struct egl_drm_frontbuffer #include "GL/internal/glcore.h" -int intel_init_driver(struct egl_drm_device *device); +int intel_create_device(struct egl_drm_device *device); +int intel_destroy_device(struct egl_drm_device *device); + int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate); +int intel_destroy_context(struct egl_drm_context *context); + int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual); +int intel_destroy_drawable(struct egl_drm_drawable *drawable); + void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read); void intel_swap_buffers(struct egl_drm_drawable *draw); void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front); diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c index 2818b9676c..12f605e0be 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.c @@ -41,7 +41,7 @@ extern const struct dri_extension card_extensions[]; int -intel_init_driver(struct egl_drm_device *device) +intel_create_device(struct egl_drm_device *device) { struct intel_screen *intel_screen; @@ -66,6 +66,19 @@ intel_init_driver(struct egl_drm_device *device) return TRUE; } +int +intel_destroy_device(struct egl_drm_device *device) +{ + struct intel_screen *intel_screen = (struct intel_screen *)device->priv; + + intel_be_destroy_device(&intel_screen->base); + + free(intel_screen); + device->priv = NULL; + + return TRUE; +} + int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual) @@ -108,6 +121,18 @@ intel_create_drawable(struct egl_drm_drawable *drawable, return GL_FALSE; } - drawable->priv = (void *) intelfb; - return GL_TRUE; + drawable->priv = (void *) intelfb; + return GL_TRUE; +} + +int +intel_destroy_drawable(struct egl_drm_drawable *drawable) +{ + struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; + drawable->priv = NULL; + + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); + return TRUE; } -- cgit v1.2.3 From 687c8d8941bb62fdb4fbdbb0ff5f359851c290b5 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Jul 2008 14:29:11 +0200 Subject: i915: Fetch the real deviceID for EGL --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 30 +++++++++++++++++++++++-- src/gallium/winsys/egl_drm/intel/intel_egl.h | 5 +++++ src/gallium/winsys/egl_drm/intel/intel_screen.c | 3 +-- 3 files changed, 34 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 9e12a024eb..ed96703e37 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -13,6 +13,7 @@ #include "eglmode.h" #include "eglscreen.h" #include "eglsurface.h" +#include "egllog.h" #include "intel_egl.h" @@ -23,15 +24,38 @@ #include "state_tracker/st_public.h" -struct egl_drm_device* egl_drm_create_device(int drmFD); +static void +drm_get_device_id(struct egl_drm_device *device) +{ + char path[512]; + FILE *file; + + /* TODO get the real minor */ + int minor = 0; + + snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); + file = fopen(path, "r"); + if (!file) { + _eglLog(_EGL_WARNING, "Could not retrive device ID\n"); + return; + } -struct egl_drm_device* + fgets(path, sizeof( path ), file); + sscanf(path, "%x", &device->deviceID); + fclose(file); +} + +static struct egl_drm_device* egl_drm_create_device(int drmFD) { struct egl_drm_device *device = malloc(sizeof(*device)); memset(device, 0, sizeof(*device)); device->drmFD = drmFD; + device->version = drmGetVersion(device->drmFD); + + drm_get_device_id(device); + if (!intel_create_device(device)) { free(device); return NULL; @@ -105,6 +129,7 @@ drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) } } + static EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) { @@ -183,6 +208,7 @@ drm_terminate(_EGLDriver *drv, EGLDisplay dpy) struct drm_driver *drm_drv = (struct drm_driver *)drv; intel_destroy_device(drm_drv->device); + drmFreeVersion(drm_drv->device->version); drmClose(drm_drv->device->drmFD); diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h index 84b6c212bf..1ee27e0847 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.h +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.h @@ -2,10 +2,15 @@ #ifndef _INTEL_EGL_H_ #define _INTEL_EGL_H_ +#include + struct egl_drm_device { void *priv; int drmFD; + + drmVersionPtr version; + int deviceID; }; struct egl_drm_context diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c index 12f605e0be..8e6d184440 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ b/src/gallium/winsys/egl_drm/intel/intel_screen.c @@ -53,8 +53,7 @@ intel_create_device(struct egl_drm_device *device) device->priv = (void *)intel_screen; intel_screen->device = device; - /** TODO JB: ugly hack */ - intel_screen->deviceID = PCI_CHIP_I945_GM; + intel_screen->deviceID = device->deviceID; intel_be_init_device(&intel_screen->base, device->drmFD, PCI_CHIP_I945_GM); -- cgit v1.2.3 From 88b806a0697efa9f7fde6aa59530675908f7294d Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Jul 2008 15:26:47 +0200 Subject: i915: More cleanup of display --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index ed96703e37..4d7e0f4bd5 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -213,6 +213,8 @@ drm_terminate(_EGLDriver *drv, EGLDisplay dpy) drmClose(drm_drv->device->drmFD); free(drm_drv->device); + + _eglCleanupDisplay(drv); free(drm_drv); return EGL_TRUE; -- cgit v1.2.3 From 7420bc05a862db09b8d5f34a7760fa19b578b4d0 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Jul 2008 15:49:09 +0200 Subject: i915: Fix EGL make current --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 4d7e0f4bd5..98928979e7 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -593,12 +593,15 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re if (!b) return EGL_FALSE; - /* XXX this is where we'd do the hardware context switch */ - (void) drawSurf; - (void) readSurf; - (void) ctx; + if (ctx) { + if (!drawSurf || !readSurf) + return EGL_FALSE; + + intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); + } else { + intel_make_current(NULL, NULL, NULL); + } - intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); return EGL_TRUE; } -- cgit v1.2.3 From 3596339d31d05b7d5120290a7b866485c395b5f2 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 7 Jul 2008 15:49:59 +0200 Subject: i915: Fix wrong pointer to cleanup --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 98928979e7..a476490b90 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -214,7 +214,7 @@ drm_terminate(_EGLDriver *drv, EGLDisplay dpy) free(drm_drv->device); - _eglCleanupDisplay(drv); + _eglCleanupDisplay(_eglLookupDisplay(dpy)); free(drm_drv); return EGL_TRUE; -- cgit v1.2.3 From b13b1210c0174e4fd315bad3e6e18b6cbeeb1518 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Jul 2008 14:16:15 +0200 Subject: i915: Renamed intel_screen to intel_device The renameing makes more sense, why because: In egl you have a display/driver/device as the basis, and you have screens as outputs. --- src/gallium/winsys/egl_drm/intel/Makefile | 2 +- src/gallium/winsys/egl_drm/intel/intel_context.c | 12 +- src/gallium/winsys/egl_drm/intel/intel_context.h | 4 +- src/gallium/winsys/egl_drm/intel/intel_device.c | 137 +++++++++++++++++++++ src/gallium/winsys/egl_drm/intel/intel_device.h | 50 ++++++++ src/gallium/winsys/egl_drm/intel/intel_screen.c | 137 --------------------- src/gallium/winsys/egl_drm/intel/intel_screen.h | 50 -------- .../winsys/egl_drm/intel/intel_swapbuffers.c | 2 +- 8 files changed, 197 insertions(+), 197 deletions(-) create mode 100644 src/gallium/winsys/egl_drm/intel/intel_device.c create mode 100644 src/gallium/winsys/egl_drm/intel/intel_device.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_screen.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_screen.h (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile index 9c7ff065ff..e67b49f3ad 100644 --- a/src/gallium/winsys/egl_drm/intel/Makefile +++ b/src/gallium/winsys/egl_drm/intel/Makefile @@ -12,7 +12,7 @@ PIPE_DRIVERS = \ DRIVER_SOURCES = \ intel_swapbuffers.c \ intel_context.c \ - intel_screen.c \ + intel_device.c \ intel_egl.c C_SOURCES = \ diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index 7513f3feef..c2003f5e0e 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -27,7 +27,7 @@ #include "i915simple/i915_screen.h" -#include "intel_screen.h" +#include "intel_device.h" #include "intel_context.h" #include "intel_batchbuffer.h" @@ -147,13 +147,13 @@ int intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) { struct intel_context *intel = CALLOC_STRUCT(intel_context); - struct intel_screen *screen = (struct intel_screen *)egl_context->device->priv; + struct intel_device *screen = (struct intel_device *)egl_context->device->priv; struct pipe_context *pipe; struct st_context *st_share = NULL; egl_context->priv = intel; - intel->intel_screen = screen; + intel->intel_device = screen; intel->egl_context = egl_context; intel->egl_device = egl_context->device; @@ -183,8 +183,8 @@ intel_destroy_context(struct egl_drm_context *egl_context) { struct intel_context *intel = egl_context->priv; - if (intel->intel_screen->dummy == intel) - intel->intel_screen->dummy = NULL; + if (intel->intel_device->dummy == intel) + intel->intel_device->dummy = NULL; st_destroy_context(intel->st); intel_be_destroy_context(&intel->base); @@ -220,7 +220,7 @@ intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *dra void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) { - struct intel_screen *intelScreen = (struct intel_screen *)draw->device->priv; + struct intel_device *intelScreen = (struct intel_device *)draw->device->priv; struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; if (draw_fb->front_buffer) diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h index f05a213ff0..48f9e21b5d 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -47,7 +47,7 @@ struct intel_context struct st_context *st; - struct intel_screen *intel_screen; + struct intel_device *intel_device; /* new egl stuff */ struct egl_drm_device *egl_device; @@ -64,7 +64,7 @@ struct intel_framebuffer { struct st_framebuffer *stfb; - struct intel_screen *screen; + struct intel_device *screen; struct _DriBufferObject *front_buffer; struct egl_drm_frontbuffer *front; }; diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.c b/src/gallium/winsys/egl_drm/intel/intel_device.c new file mode 100644 index 0000000000..7496c1bb30 --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_device.c @@ -0,0 +1,137 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "utils.h" + +#include "state_tracker/st_public.h" +#include "i915simple/i915_screen.h" + +#include "intel_context.h" +#include "intel_device.h" +#include "intel_batchbuffer.h" +#include "intel_egl.h" + + +extern const struct dri_extension card_extensions[]; + + +int +intel_create_device(struct egl_drm_device *device) +{ + struct intel_device *intel_device; + + /* Allocate the private area */ + intel_device = CALLOC_STRUCT(intel_device); + if (!intel_device) + return FALSE; + + device->priv = (void *)intel_device; + intel_device->device = device; + + intel_device->deviceID = device->deviceID; + + intel_be_init_device(&intel_device->base, device->drmFD, PCI_CHIP_I945_GM); + + intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID); + + /* hack */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + + return TRUE; +} + +int +intel_destroy_device(struct egl_drm_device *device) +{ + struct intel_device *intel_device = (struct intel_device *)device->priv; + + intel_be_destroy_device(&intel_device->base); + + free(intel_device); + device->priv = NULL; + + return TRUE; +} + +int +intel_create_drawable(struct egl_drm_drawable *drawable, + const __GLcontextModes * visual) +{ + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + intelfb->screen = drawable->device->priv; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + drawable->w, + drawable->h, + (void*) intelfb); + + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + drawable->priv = (void *) intelfb; + return GL_TRUE; +} + +int +intel_destroy_drawable(struct egl_drm_drawable *drawable) +{ + struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; + drawable->priv = NULL; + + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); + return TRUE; +} diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.h b/src/gallium/winsys/egl_drm/intel/intel_device.h new file mode 100644 index 0000000000..2f9d4f887e --- /dev/null +++ b/src/gallium/winsys/egl_drm/intel/intel_device.h @@ -0,0 +1,50 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _INTEL_SCREEN_H_ +#define _INTEL_SCREEN_H_ + +#include "intel_drm/intel_be_device.h" + +#include "pipe/p_compiler.h" + +struct pipe_screen; +struct egl_drm_device; +struct intel_context; + +struct intel_device +{ + struct intel_be_device base; + struct pipe_screen *pipe; + + int deviceID; + struct egl_drm_device *device; + + struct intel_context *dummy; +}; + +#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c deleted file mode 100644 index 8e6d184440..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.c +++ /dev/null @@ -1,137 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "utils.h" - -#include "state_tracker/st_public.h" -#include "i915simple/i915_screen.h" - -#include "intel_context.h" -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_egl.h" - - -extern const struct dri_extension card_extensions[]; - - -int -intel_create_device(struct egl_drm_device *device) -{ - struct intel_screen *intel_screen; - - /* Allocate the private area */ - intel_screen = CALLOC_STRUCT(intel_screen); - if (!intel_screen) - return FALSE; - - device->priv = (void *)intel_screen; - intel_screen->device = device; - - intel_screen->deviceID = device->deviceID; - - intel_be_init_device(&intel_screen->base, device->drmFD, PCI_CHIP_I945_GM); - - intel_screen->pipe = i915_create_screen(&intel_screen->base.base, intel_screen->deviceID); - - /* hack */ - driInitExtensions(NULL, card_extensions, GL_FALSE); - - return TRUE; -} - -int -intel_destroy_device(struct egl_drm_device *device) -{ - struct intel_screen *intel_screen = (struct intel_screen *)device->priv; - - intel_be_destroy_device(&intel_screen->base); - - free(intel_screen); - device->priv = NULL; - - return TRUE; -} - -int -intel_create_drawable(struct egl_drm_drawable *drawable, - const __GLcontextModes * visual) -{ - enum pipe_format colorFormat, depthFormat, stencilFormat; - struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); - - if (!intelfb) - return GL_FALSE; - - intelfb->screen = drawable->device->priv; - - if (visual->redBits == 5) - colorFormat = PIPE_FORMAT_R5G6B5_UNORM; - else - colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; - - if (visual->depthBits == 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits == 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_NONE; - - if (visual->stencilBits == 8) - stencilFormat = PIPE_FORMAT_S8Z24_UNORM; - else - stencilFormat = PIPE_FORMAT_NONE; - - intelfb->stfb = st_create_framebuffer(visual, - colorFormat, - depthFormat, - stencilFormat, - drawable->w, - drawable->h, - (void*) intelfb); - - if (!intelfb->stfb) { - free(intelfb); - return GL_FALSE; - } - - drawable->priv = (void *) intelfb; - return GL_TRUE; -} - -int -intel_destroy_drawable(struct egl_drm_drawable *drawable) -{ - struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; - drawable->priv = NULL; - - assert(intelfb->stfb); - st_unreference_framebuffer(&intelfb->stfb); - free(intelfb); - return TRUE; -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_screen.h deleted file mode 100644 index 9b990b48e7..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_screen.h +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef _INTEL_SCREEN_H_ -#define _INTEL_SCREEN_H_ - -#include "intel_drm/intel_be_device.h" - -#include "pipe/p_compiler.h" - -struct pipe_screen; -struct egl_drm_device; -struct intel_context; - -struct intel_screen -{ - struct intel_be_device base; - struct pipe_screen *pipe; - - int deviceID; - struct egl_drm_device *device; - - struct intel_context *dummy; -}; - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c index bfff6f935f..86e4a0f92a 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "intel_screen.h" +#include "intel_device.h" #include "intel_context.h" #include "intel_batchbuffer.h" #include "intel_reg.h" -- cgit v1.2.3 From 0c6efeb02beba32a35dda7c5d5a3086ca2d8cbc4 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Jul 2008 14:41:17 +0200 Subject: i915: Complete the screen -> device renaming --- src/gallium/winsys/egl_drm/intel/intel_context.c | 14 +++++++------- src/gallium/winsys/egl_drm/intel/intel_context.h | 2 +- src/gallium/winsys/egl_drm/intel/intel_device.c | 2 +- src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c index c2003f5e0e..927addb834 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ b/src/gallium/winsys/egl_drm/intel/intel_context.c @@ -147,13 +147,13 @@ int intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) { struct intel_context *intel = CALLOC_STRUCT(intel_context); - struct intel_device *screen = (struct intel_device *)egl_context->device->priv; + struct intel_device *device = (struct intel_device *)egl_context->device->priv; struct pipe_context *pipe; struct st_context *st_share = NULL; egl_context->priv = intel; - intel->intel_device = screen; + intel->intel_device = device; intel->egl_context = egl_context; intel->egl_device = egl_context->device; @@ -161,19 +161,19 @@ intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes intel->base.hardware_unlock = intel_unlock_hardware; intel->base.hardware_locked = intel_locked_hardware; - intel_be_init_context(&intel->base, &screen->base); + intel_be_init_context(&intel->base, &device->base); #if 0 pipe = intel_create_softpipe(intel, screen->winsys); #else - pipe = i915_create_context(screen->pipe, &screen->base.base, &intel->base.base); + pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base); #endif pipe->priv = intel; intel->st = st_create_context(pipe, visual, st_share); - screen->dummy = intel; + device->dummy = intel; return TRUE; } @@ -220,7 +220,7 @@ intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *dra void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) { - struct intel_device *intelScreen = (struct intel_device *)draw->device->priv; + struct intel_device *device = (struct intel_device *)draw->device->priv; struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; if (draw_fb->front_buffer) @@ -235,7 +235,7 @@ intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer draw_fb->front = front; - driGenBuffers(intelScreen->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); + driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); driBOSetReferenced(draw_fb->front_buffer, front->handle); st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h index 48f9e21b5d..dfa4720b08 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ b/src/gallium/winsys/egl_drm/intel/intel_context.h @@ -64,7 +64,7 @@ struct intel_framebuffer { struct st_framebuffer *stfb; - struct intel_device *screen; + struct intel_device *device; struct _DriBufferObject *front_buffer; struct egl_drm_frontbuffer *front; }; diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.c b/src/gallium/winsys/egl_drm/intel/intel_device.c index 7496c1bb30..a601904ba4 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_device.c +++ b/src/gallium/winsys/egl_drm/intel/intel_device.c @@ -88,7 +88,7 @@ intel_create_drawable(struct egl_drm_drawable *drawable, if (!intelfb) return GL_FALSE; - intelfb->screen = drawable->device->priv; + intelfb->device = drawable->device->priv; if (visual->redBits == 5) colorFormat = PIPE_FORMAT_R5G6B5_UNORM; diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c index 86e4a0f92a..2edcbc79ff 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c @@ -69,7 +69,7 @@ intel_display_surface(struct egl_drm_drawable *draw, //const int srcWidth = surf->width; //const int srcHeight = surf->height; - intel = intel_fb->screen->dummy; + intel = intel_fb->device->dummy; if (!intel) { printf("No dummy context\n"); return; -- cgit v1.2.3 From 1257bb9b130c9487a32e422a8ce8ddba2f14a568 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Jul 2008 14:44:23 +0200 Subject: i915: Use deviceID in EGL device create --- src/gallium/winsys/egl_drm/intel/intel_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.c b/src/gallium/winsys/egl_drm/intel/intel_device.c index a601904ba4..b9649cbec7 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_device.c +++ b/src/gallium/winsys/egl_drm/intel/intel_device.c @@ -55,7 +55,7 @@ intel_create_device(struct egl_drm_device *device) intel_device->deviceID = device->deviceID; - intel_be_init_device(&intel_device->base, device->drmFD, PCI_CHIP_I945_GM); + intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID); intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID); -- cgit v1.2.3 From 2e7e1837512c1959a97f51903a770cf182fc9820 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 8 Jul 2008 16:54:22 +0200 Subject: i915: Takedown EGL screen --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 81 ++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index a476490b90..55f4d92afb 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -24,6 +24,8 @@ #include "state_tracker/st_public.h" +#define MAX_SCREENS 16 + static void drm_get_device_id(struct egl_drm_device *device) { @@ -66,11 +68,17 @@ egl_drm_create_device(int drmFD) __GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size ); +struct drm_screen; + struct drm_driver { _EGLDriver base; /* base class/object */ drmModeResPtr res; + + struct drm_screen *screens[MAX_SCREENS]; + size_t count_screens; + struct egl_drm_device *device; }; @@ -92,17 +100,26 @@ struct drm_screen { _EGLScreen base; - /* backing buffer and crtc */ + /* currently only support one connector */ + drmModeConnectorPtr connector; + uint32_t connectorID; + + /* Has this screen been shown */ + int shown; + + /* Surface that is currently attached to this screen */ + struct drm_surface *surf; + + /* backing buffer */ drmBO buffer; + + /* framebuffer */ drmModeFBPtr fb; uint32_t fbID; - drmModeCrtcPtr crtc; - /* currently only support one connector */ - drmModeConnectorPtr connector; - drmModeEncoderPtr encoder; - uint32_t connectorID; - uint32_t encoderID; + /* crtc and mode used */ + drmModeCrtcPtr crtc; + uint32_t crtcID; struct drm_mode_modeinfo *mode; @@ -139,6 +156,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) drmModeConnectorPtr connector = NULL; drmModeResPtr res = NULL; unsigned count_connectors = 0; + int num_screens = 0; EGLint i; int fd; @@ -159,13 +177,13 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) if (res) count_connectors = res->count_connectors; - for(i = 0; i < count_connectors; i++) { + for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { connector = drmModeGetConnector(fd, res->connectors[i]); if (!connector) continue; - if (connector->connection == DRM_MODE_DISCONNECTED) { + if (connector->connection != DRM_MODE_CONNECTED) { drmModeFreeConnector(connector); continue; } @@ -177,7 +195,9 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); drm_add_modes_from_connector(&screen->base, connector); + drm_drv->screens[num_screens++] = screen; } + drm_drv->count_screens = num_screens; /* for now we only have one config */ _EGLConfig *config = calloc(1, sizeof(*config)); @@ -201,15 +221,52 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) return EGL_TRUE; } +static void +drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + + intel_bind_frontbuffer(screen->surf->drawable, NULL); + screen->surf = NULL; + + drmModeSetCrtc( + drm_drv->device->drmFD, + drm_drv->res->crtcs[1], + 0, // FD + 0, 0, + NULL, 0, // List of output ids + NULL); + + drmModeRmFB(drm_drv->device->drmFD, screen->fbID); + drmModeFreeFB(screen->fb); + screen->fb = NULL; + + drmBOUnreference(drm_drv->device->drmFD, &screen->buffer); + + screen->shown = 0; +} static EGLBoolean drm_terminate(_EGLDriver *drv, EGLDisplay dpy) { struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_screen *screen; + int i = 0; intel_destroy_device(drm_drv->device); drmFreeVersion(drm_drv->device->version); + for (i = 0; i < drm_drv->count_screens; i++) { + screen = drm_drv->screens[i]; + + if (screen->shown) + drm_takedown_shown_screen(drv, screen); + + drmModeFreeConnector(screen->connector); + _eglDestroyScreen(&screen->base); + drm_drv->screens[i] = NULL; + } + drmClose(drm_drv->device->drmFD); free(drm_drv->device); @@ -507,7 +564,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, size_t size = mode->Height * pitch; int ret; - /* TODO if allready shown take down */ + if (scrn->shown) + drm_takedown_shown_screen(drv, scrn); ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, DRM_BO_FLAG_READ | @@ -552,8 +610,11 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, scrn->front.width = mode->Width; scrn->front.height = mode->Height; + scrn->surf = surf; intel_bind_frontbuffer(surf->drawable, &scrn->front); + scrn->shown = 1; + return EGL_TRUE; err_fb: -- cgit v1.2.3 From 7cbc244c52610eb59b0fe1fc7275f307b560c281 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 8 Jul 2008 15:00:11 -0600 Subject: gallium: tweak printing of generic declarations --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 92aff88925..a395c630cc 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -573,7 +573,8 @@ tgsi_dump_declaration( if (decl->Declaration.Semantic) { TXT( ", " ); ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT ); - if (decl->Semantic.SemanticIndex != 0) { + if (decl->Semantic.SemanticIndex != 0 || + decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC) { CHR( '[' ); UID( decl->Semantic.SemanticIndex ); CHR( ']' ); -- cgit v1.2.3 From d25709df1d5d9dccdeb173b33a57018004fe849c Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 9 Jul 2008 09:29:49 -0400 Subject: draw: remove some debug output --- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index 6b92811870..8e834501a4 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -184,7 +184,6 @@ boolean aos_fetch_inputs( struct aos_compilation *cp, boolean linear ) if (!load_input( cp, i, linear )) return FALSE; cp->insn_counter++; - debug_printf("\n"); } return TRUE; @@ -316,7 +315,6 @@ boolean aos_emit_outputs( struct aos_compilation *cp ) aos_release_xmm_reg( cp, data.idx ); cp->insn_counter++; - debug_printf("\n"); } return TRUE; -- cgit v1.2.3 From 48b8a32c6dcd259046958b187927ac584b1a564a Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Wed, 9 Jul 2008 10:20:28 -0400 Subject: egl: plug a small memleak --- src/gallium/winsys/egl_xlib/egl_xlib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 83b8bb95b1..708a58b781 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -535,6 +535,7 @@ xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) surf->Base.DeletePending = EGL_TRUE; } else { + XFreeGC(surf->Dpy, surf->Gc); st_unreference_framebuffer(&surf->Framebuffer); free(surf); } -- cgit v1.2.3 From 93ff702b4f1c6016e249c4d326e71cdc4932f57c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 9 Jul 2008 11:46:16 -0600 Subject: gallium: fix logic in pb_check_usage() --- src/gallium/auxiliary/pipebuffer/pb_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index 83ea0be74b..8505d333bd 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -221,7 +221,7 @@ pb_check_alignment(size_t requested, size_t provided) static INLINE boolean pb_check_usage(unsigned requested, unsigned provided) { - return (requested & provided) == provided ? TRUE : FALSE; + return (requested & provided) == requested ? TRUE : FALSE; } -- cgit v1.2.3 From f5cdc657b244ec7840cff1f36892f105b4aa2ef2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 10 Jul 2008 13:30:37 -0600 Subject: egl: added EGL_OPENVG_API case (allow all APIs) --- src/gallium/winsys/egl_xlib/egl_xlib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 708a58b781..829732eea8 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -350,6 +350,7 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, /* API-dependent context creation */ switch (ctx->Base.ClientAPI) { + case EGL_OPENVG_API: case EGL_OPENGL_ES_API: _eglLog(_EGL_DEBUG, "Create Context for ES version %d\n", ctx->Base.ClientVersion); -- cgit v1.2.3 From 6e938e4f82755c20472532907cc47c2d501aaee2 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 11 Jul 2008 20:01:33 +0200 Subject: gallium: Make dri drivers create a egl_name_dri.so if supported --- src/gallium/winsys/dri/Makefile.template | 10 +++++++++- src/gallium/winsys/dri/intel/Makefile | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 07abfa53f3..80e817b808 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -79,17 +79,25 @@ SHARED_INCLUDES = \ ##### TARGETS ##### -default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) +default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR)/$(LIBNAME_EGL) $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template $(TOP)/bin/mklib -noprefix -o $@ \ $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) +$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS) + $(TOP)/bin/mklib -o $(LIBNAME_EGL) \ + -linker "$(CC)" \ + -noprefix \ + $(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \ + --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive $(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) +$(TOP)/$(LIB_DIR)/$(LIBNAME_EGL): $(LIBNAME_EGL) + $(INSTALL) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR) depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) rm -f depend diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile index 5b51f0815d..e0716ea28e 100644 --- a/src/gallium/winsys/dri/intel/Makefile +++ b/src/gallium/winsys/dri/intel/Makefile @@ -3,6 +3,7 @@ TOP = ../../../../.. include $(TOP)/configs/current LIBNAME = i915_dri.so +LIBNAME_EGL = egl_i915_dri.so PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ -- cgit v1.2.3 From 7279d663e984ae8a243f56c010f175fee9ffccb3 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 12 Jul 2008 11:16:01 +0200 Subject: tgsi: Add missing copyright headers. --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h | 30 +++++++++++++++++++++++++-- src/gallium/auxiliary/tgsi/util/tgsi_build.c | 28 ++++++++++++++++++++++++- src/gallium/auxiliary/tgsi/util/tgsi_build.h | 30 +++++++++++++++++++++++++-- src/gallium/auxiliary/tgsi/util/tgsi_dump.h | 31 +++++++++++++++++++++++++--- src/gallium/auxiliary/tgsi/util/tgsi_util.c | 28 ++++++++++++++++++++++++- src/gallium/auxiliary/tgsi/util/tgsi_util.h | 30 +++++++++++++++++++++++++-- 6 files changed, 166 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h index e66d115283..af838b2a25 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h @@ -1,4 +1,31 @@ -#if !defined TGSI_SSE2_H +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_SSE2_H #define TGSI_SSE2_H #if defined __cplusplus @@ -20,4 +47,3 @@ tgsi_emit_sse2( #endif #endif /* TGSI_SSE2_H */ - diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.c b/src/gallium/auxiliary/tgsi/util/tgsi_build.c index 18e44b38c2..742ef14c35 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include "pipe/p_debug.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" @@ -1295,4 +1322,3 @@ tgsi_build_dst_register_ext_modulate( return dst_register_ext_modulate; } - diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.h b/src/gallium/auxiliary/tgsi/util/tgsi_build.h index 423cf141f5..ed25830248 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.h @@ -1,4 +1,31 @@ -#if !defined TGSI_BUILD_H +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_BUILD_H #define TGSI_BUILD_H #if defined __cplusplus @@ -303,4 +330,3 @@ tgsi_build_dst_register_ext_modulate( #endif #endif /* TGSI_BUILD_H */ - diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h index ca83bdef20..ba7692b511 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h @@ -1,4 +1,31 @@ -#if !defined TGSI_DUMP_H +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_DUMP_H #define TGSI_DUMP_H #if defined __cplusplus @@ -31,10 +58,8 @@ void tgsi_dump_declaration( const struct tgsi_full_declaration *decl ); - #if defined __cplusplus } #endif #endif /* TGSI_DUMP_H */ - diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.c b/src/gallium/auxiliary/tgsi/util/tgsi_util.c index 56a50d3b21..10762b6c1a 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_util.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_util.c @@ -1,3 +1,30 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #include "pipe/p_debug.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" @@ -271,4 +298,3 @@ tgsi_util_set_full_src_register_sign_mode( assert( 0 ); } } - diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.h b/src/gallium/auxiliary/tgsi/util/tgsi_util.h index 45f5f0be0e..7877f34558 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_util.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_util.h @@ -1,4 +1,31 @@ -#if !defined TGSI_UTIL_H +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_UTIL_H #define TGSI_UTIL_H #if defined __cplusplus @@ -67,4 +94,3 @@ tgsi_util_set_full_src_register_sign_mode( #endif #endif /* TGSI_UTIL_H */ - -- cgit v1.2.3 From 9ea485f8865404e3e2e10cdb3b1627e7194c27fe Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 12 Jul 2008 17:03:30 +0200 Subject: tgsi: Fix dumping of indirect addressing. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index a395c630cc..6356b6de06 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -805,10 +805,12 @@ tgsi_dump_instruction( CHR( '[' ); if (src->SrcRegister.Indirect) { - TXT( "addr" ); - if (src->SrcRegister.Index > 0) - CHR( '+' ); - SID( src->SrcRegister.Index ); + TXT( "ADDR[0]" ); + if (src->SrcRegister.Index != 0) { + if (src->SrcRegister.Index > 0) + CHR( '+' ); + SID( src->SrcRegister.Index ); + } } else SID( src->SrcRegister.Index ); -- cgit v1.2.3 From d0386d55ff257ab09475178d058ddcd9f1e37c2d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 12 Jul 2008 17:06:37 +0200 Subject: tgsi: Add tgsi_text utility module. Translates textual shader into a binary token stream. The syntax matches the tgsi_dump module, so it's possible to simply copy-paste the shader dump and transform it back to a binary form. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 580 ++++++++++++++++++++++++++++ src/gallium/auxiliary/tgsi/util/tgsi_text.h | 47 +++ 2 files changed, 627 insertions(+) create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_text.c create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_text.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c new file mode 100644 index 0000000000..bb365d1efe --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -0,0 +1,580 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "tgsi_text.h" +#include "tgsi_build.h" +#include "tgsi_parse.h" +#include "tgsi_util.h" + +static boolean is_alpha_underscore( const char *cur ) +{ + return + (*cur >= 'a' && *cur <= 'z') || + (*cur >= 'A' && *cur <= 'Z') || + *cur == '_'; +} + +static boolean is_digit( const char *cur ) +{ + return *cur >= '0' && *cur <= '9'; +} + +static boolean is_digit_alpha_underscore( const char *cur ) +{ + return is_digit( cur ) || is_alpha_underscore( cur ); +} + +/* Eat zero or more whitespaces. + */ +static void eat_opt_white( const char **pcur ) +{ + while (**pcur == ' ' || **pcur == '\t' || **pcur == '\n') + (*pcur)++; +} + +/* Eat one or more whitespaces. + * Return TRUE if at least one whitespace eaten. + */ +static boolean eat_white( const char **pcur ) +{ + const char *cur = *pcur; + + eat_opt_white( pcur ); + return *pcur > cur; +} + +/* Parse unsigned integer. + * No checks for overflow. + */ +static boolean parse_uint( const char **pcur, uint *val ) +{ + const char *cur = *pcur; + + if (is_digit( cur )) { + *val = *cur++ - '0'; + while (is_digit( cur )) + *val = *val * 10 + *cur++ - '0'; + *pcur = cur; + return TRUE; + } + return FALSE; +} + +struct translate_ctx +{ + const char *text; + const char *cur; + struct tgsi_token *tokens; + struct tgsi_token *tokens_cur; + struct tgsi_token *tokens_end; + struct tgsi_header *header; +}; + +static void report_error( struct translate_ctx *ctx, const char *msg ) +{ + debug_printf( "\nError: %s", msg ); +} + +/* Parse shader header. + * Return TRUE for one of the following headers. + * FRAG1.1 + * GEOM1.1 + * VERT1.1 + */ +static boolean parse_header( struct translate_ctx *ctx ) +{ + uint processor; + + if (ctx->cur[0] == 'F' && ctx->cur[1] == 'R' && ctx->cur[2] == 'A' && ctx->cur[3] == 'G') { + ctx->cur += 4; + processor = TGSI_PROCESSOR_FRAGMENT; + } + else if (ctx->cur[0] == 'V' && ctx->cur[1] == 'E' && ctx->cur[2] == 'R' && ctx->cur[3] == 'T') { + ctx->cur += 4; + processor = TGSI_PROCESSOR_VERTEX; + } + else if (ctx->cur[0] == 'G' && ctx->cur[1] == 'E' && ctx->cur[2] == 'O' && ctx->cur[3] == 'M') { + ctx->cur += 4; + processor = TGSI_PROCESSOR_GEOMETRY; + } + else { + report_error( ctx, "Unknown processor type" ); + return FALSE; + } + + if (ctx->cur[0] == '1' && ctx->cur[1] == '.' && ctx->cur[2] == '1') { + ctx->cur += 3; + } + else { + report_error( ctx, "Unknown version" ); + return FALSE; + } + + if (ctx->tokens_cur >= ctx->tokens_end) + return FALSE; + *(struct tgsi_version *) ctx->tokens_cur++ = tgsi_build_version(); + + if (ctx->tokens_cur >= ctx->tokens_end) + return FALSE; + ctx->header = (struct tgsi_header *) ctx->tokens_cur++; + *ctx->header = tgsi_build_header(); + + if (ctx->tokens_cur >= ctx->tokens_end) + return FALSE; + *(struct tgsi_processor *) ctx->tokens_cur++ = tgsi_build_processor( processor, ctx->header ); + + return TRUE; +} + +static boolean parse_label( struct translate_ctx *ctx, uint *val ) +{ + const char *cur = ctx->cur; + + if (parse_uint( &cur, val )) { + eat_opt_white( &cur ); + if (*cur == ':') { + cur++; + ctx->cur = cur; + return TRUE; + } + } + return FALSE; +} + +static const char *file_names[TGSI_FILE_COUNT] = +{ + "NULL", + "CONST", + "IN", + "OUT", + "TEMP", + "SAMP", + "ADDR", + "IMM" +}; + +static boolean +parse_file( + struct translate_ctx *ctx, + uint *file ) +{ + uint i; + + for (i = 0; i < TGSI_FILE_COUNT; i++) { + const char *cur = ctx->cur; + const char *name = file_names[i]; + + while (*name != '\0' && *name == toupper( *cur )) { + name++; + cur++; + } + if (*name == '\0' && !is_digit_alpha_underscore( cur )) { + ctx->cur = cur; + *file = i; + return TRUE; + } + } + report_error( ctx, "Unknown register file" ); + return FALSE; +} + +static boolean +parse_register( + struct translate_ctx *ctx, + uint *file, + uint *index ) +{ + if (!parse_file( ctx, file )) + return FALSE; + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '[') { + report_error( ctx, "Expected `['" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (!parse_uint( &ctx->cur, index )) { + report_error( ctx, "Expected literal integer" ); + return FALSE; + } + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ']') { + report_error( ctx, "Expected `]'" ); + return FALSE; + } + ctx->cur++; + /* TODO: Modulate suffix */ + return TRUE; +} + +static boolean +parse_dst_operand( + struct translate_ctx *ctx, + struct tgsi_full_dst_register *dst ) +{ + const char *cur; + uint file; + uint index; + + if (!parse_register( ctx, &file, &index )) + return FALSE; + dst->DstRegister.File = file; + dst->DstRegister.Index = index; + + /* Parse optional write mask. + */ + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == '.') { + uint writemask = TGSI_WRITEMASK_NONE; + + cur++; + eat_opt_white( &cur ); + if (toupper( *cur ) == 'X') { + cur++; + writemask |= TGSI_WRITEMASK_X; + } + if (toupper( *cur ) == 'Y') { + cur++; + writemask |= TGSI_WRITEMASK_Y; + } + if (toupper( *cur ) == 'Z') { + cur++; + writemask |= TGSI_WRITEMASK_Z; + } + if (toupper( *cur ) == 'W') { + cur++; + writemask |= TGSI_WRITEMASK_W; + } + + if (writemask == TGSI_WRITEMASK_NONE) { + report_error( ctx, "Writemask expected" ); + return FALSE; + } + + dst->DstRegister.WriteMask = writemask; + ctx->cur = cur; + } + return TRUE; +} + +static boolean +parse_src_operand( + struct translate_ctx *ctx, + struct tgsi_full_src_register *src ) +{ + const char *cur; + uint file; + uint index; + + /* TODO: Extended register modifiers */ + if (*ctx->cur == '-') { + ctx->cur++; + src->SrcRegister.Negate = 1; + eat_opt_white( &ctx->cur ); + } + + if (!parse_register( ctx, &file, &index )) + return FALSE; + src->SrcRegister.File = file; + src->SrcRegister.Index = index; + + /* Parse optional swizzle + */ + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == '.') { + uint i; + + cur++; + eat_opt_white( &cur ); + for (i = 0; i < 4; i++) { + uint swizzle; + + if (toupper( *cur ) == 'X') + swizzle = TGSI_SWIZZLE_X; + else if (toupper( *cur ) == 'Y') + swizzle = TGSI_SWIZZLE_Y; + else if (toupper( *cur ) == 'Z') + swizzle = TGSI_SWIZZLE_Z; + else if (toupper( *cur ) == 'W') + swizzle = TGSI_SWIZZLE_W; + else { + report_error( ctx, "Expected register swizzle component either `x', `y', `z' or `w'" ); + return FALSE; + } + cur++; + tgsi_util_set_src_register_swizzle( &src->SrcRegister, swizzle, i ); + } + + ctx->cur = cur; + } + return TRUE; +} + +struct opcode_info +{ + uint num_dst; + uint num_src; + const char *mnemonic; +}; + +static const struct opcode_info opcode_info[TGSI_OPCODE_LAST] = +{ +{ 1, 1, "ARL" }, + { 1, 1, "MOV" }, +{ 1, 1, "LIT" }, + { 1, 1, "RCP" }, + { 1, 1, "RSQ" }, + { 1, 1, "EXP" }, + { 1, 1, "LOG" }, + { 1, 2, "MUL" }, + { 1, 2, "ADD" }, + { 1, 2, "DP3" }, + { 1, 2, "DP4" }, +{ 1, 2, "DST" }, + { 1, 2, "MIN" }, + { 1, 2, "MAX" }, +{ 1, 2, "SLT" }, +{ 1, 2, "SGE" }, + { 1, 3, "MAD" }, + { 1, 2, "SUB" }, +{ 1, 3, "LERP" }, +{ 1, 2, "CND" }, +{ 1, 2, "CND0" }, +{ 1, 2, "DOT2ADD" }, +{ 1, 2, "INDEX" }, +{ 1, 2, "NEGATE" }, +{ 1, 2, "FRAC" }, +{ 1, 2, "CLAMP" }, +{ 1, 2, "FLOOR" }, +{ 1, 2, "ROUND" }, +{ 1, 2, "EXPBASE2" }, +{ 1, 2, "LOGBASE2" }, +{ 1, 2, "POWER" }, +{ 1, 2, "CROSSPRODUCT" }, +{ 1, 2, "MULTIPLYMATRIX" }, + { 1, 2, "ABS" }, +{ 1, 2, "RCC" }, +{ 1, 2, "DPH" }, +{ 1, 2, "COS" }, +{ 1, 2, "DDX" }, +{ 1, 2, "DDY" }, +{ 1, 2, "KILP" }, +{ 1, 2, "PK2H" }, +{ 1, 2, "PK2US" }, +{ 1, 2, "PK4B" }, +{ 1, 2, "PK4UB" }, +{ 1, 2, "RFL" }, +{ 1, 2, "SEQ" }, +{ 1, 2, "SFL" }, +{ 1, 2, "SGT" }, +{ 1, 2, "SIN" }, +{ 1, 2, "SLE" }, +{ 1, 2, "SNE" }, +{ 1, 2, "STR" }, +{ 1, 2, "TEX" }, +{ 1, 2, "TXD" }, +{ 1, 2, "TXP" }, +{ 1, 2, "UP2H" }, +{ 1, 2, "UP2US" }, +{ 1, 2, "UP4B" }, +{ 1, 2, "UP4UB" }, +{ 1, 2, "X2D" }, +{ 1, 2, "ARA" }, +{ 1, 2, "ARR" }, +{ 1, 2, "BRA" }, +{ 1, 2, "CAL" }, +{ 1, 2, "RET" }, +{ 1, 2, "SSG" }, +{ 1, 2, "CMP" }, +{ 1, 2, "SCS" }, +{ 1, 2, "TXB" }, +{ 1, 2, "NRM" }, +{ 1, 2, "DIV" }, +{ 1, 2, "DP2" }, +{ 1, 2, "TXL" }, +{ 1, 2, "BRK" }, +{ 1, 2, "IF" }, +{ 1, 2, "LOOP" }, +{ 1, 2, "REP" }, +{ 1, 2, "ELSE" }, +{ 1, 2, "ENDIF" }, +{ 1, 2, "ENDLOOP" }, +{ 1, 2, "ENDREP" }, +{ 1, 2, "PUSHA" }, +{ 1, 2, "POPA" }, +{ 1, 2, "CEIL" }, +{ 1, 2, "I2F" }, +{ 1, 2, "NOT" }, +{ 1, 2, "TRUNC" }, +{ 1, 2, "SHL" }, +{ 1, 2, "SHR" }, +{ 1, 2, "AND" }, +{ 1, 2, "OR" }, +{ 1, 2, "MOD" }, +{ 1, 2, "XOR" }, +{ 1, 2, "SAD" }, +{ 1, 2, "TXF" }, +{ 1, 2, "TXQ" }, +{ 1, 2, "CONT" }, +{ 1, 2, "EMIT" }, +{ 1, 2, "ENDPRIM" }, +{ 1, 2, "BGNLOOP2" }, +{ 1, 2, "BGNSUB" }, +{ 1, 2, "ENDLOOP2" }, +{ 1, 2, "ENDSUB" }, +{ 1, 2, "NOISE1" }, +{ 1, 2, "NOISE2" }, +{ 1, 2, "NOISE3" }, +{ 1, 2, "NOISE4" }, +{ 1, 2, "NOP" }, +{ 1, 2, "M4X3" }, +{ 1, 2, "M3X4" }, +{ 1, 2, "M3X3" }, +{ 1, 2, "M3X2" }, +{ 1, 2, "NRM4" }, +{ 1, 2, "CALLNZ" }, +{ 1, 2, "IFC" }, +{ 1, 2, "BREAKC" }, +{ 1, 2, "KIL" }, + { 0, 0, "END" } +}; + +static boolean parse_instruction( struct translate_ctx *ctx ) +{ + uint i; + const struct opcode_info *info; + struct tgsi_full_instruction inst; + uint advance; + + /* Parse instruction name. + */ + eat_opt_white( &ctx->cur ); + for (i = 0; i < TGSI_OPCODE_LAST; i++) { + const char *cur = ctx->cur; + const char *op = opcode_info[i].mnemonic; + + while (*op != '\0' && *op == toupper( *cur )) { + op++; + cur++; + } + if (*op == '\0') { + /* TODO: _SAT suffix */ + if (*cur == '\0' || eat_white( &cur )) { + ctx->cur = cur; + break; + } + } + } + if (i == TGSI_OPCODE_LAST) { + report_error( ctx, "Unknown opcode" ); + return FALSE; + } + info = &opcode_info[i]; + + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = i; + inst.Instruction.NumDstRegs = info->num_dst; + inst.Instruction.NumSrcRegs = info->num_src; + + /* Parse instruction operands. + */ + for (i = 0; i < info->num_dst + info->num_src; i++) { + if (i > 0) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ',') { + report_error( ctx, "Expected `,'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + } + + if (i < info->num_dst) { + if (!parse_dst_operand( ctx, &inst.FullDstRegisters[i] )) + return FALSE; + } + else { + if (!parse_src_operand( ctx, &inst.FullSrcRegisters[i - info->num_dst] )) + return FALSE; + } + } + eat_opt_white( &ctx->cur ); + + advance = tgsi_build_full_instruction( + &inst, + ctx->tokens_cur, + ctx->header, + (uint) (ctx->tokens_end - ctx->tokens_cur) ); + if (advance == 0) + return FALSE; + ctx->tokens_cur += advance; + + return TRUE; +} + +static boolean translate( struct translate_ctx *ctx ) +{ + eat_opt_white( &ctx->cur ); + if (!parse_header( ctx )) + return FALSE; + + eat_white( &ctx->cur ); + while (*ctx->cur != '\0') { + uint label_val = 0; + + if (parse_label( ctx, &label_val )) { + if (!parse_instruction( ctx )) + return FALSE; + } + else { + report_error( ctx, "Instruction expected" ); + return FALSE; + } + } + + return TRUE; +} + +boolean +tgsi_text_translate( + const char *text, + struct tgsi_token *tokens, + uint num_tokens ) +{ + struct translate_ctx ctx; + + ctx.text = text; + ctx.cur = text; + ctx.tokens = tokens; + ctx.tokens_cur = tokens; + ctx.tokens_end = tokens + num_tokens; + + return translate( &ctx ); +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.h b/src/gallium/auxiliary/tgsi/util/tgsi_text.h new file mode 100644 index 0000000000..8eeeeef140 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_TEXT_H +#define TGSI_TEXT_H + +#include "pipe/p_shader_tokens.h" + +#if defined __cplusplus +extern "C" { +#endif + +boolean +tgsi_text_translate( + const char *text, + struct tgsi_token *tokens, + uint num_tokens ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_TEXT_H */ -- cgit v1.2.3 From c415de5e251eb4004b1ef5bc57299032d95c4842 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 12 Jul 2008 17:10:21 +0200 Subject: scons: List `util/tgsi_text.c'. --- src/gallium/auxiliary/tgsi/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript index 4632dcc072..b62c8efe02 100644 --- a/src/gallium/auxiliary/tgsi/SConscript +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -9,6 +9,7 @@ tgsi = env.ConvenienceLibrary( 'util/tgsi_dump.c', 'util/tgsi_parse.c', 'util/tgsi_scan.c', + 'util/tgsi_text.c', 'util/tgsi_transform.c', 'util/tgsi_util.c', ]) -- cgit v1.2.3 From 92d711e9e6c1934e1cec774bfa4581869530cda6 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 13 Jul 2008 11:33:41 +0200 Subject: llvm: build fixes. --- src/gallium/auxiliary/draw/draw_vs_llvm.c | 10 +++++----- src/gallium/auxiliary/gallivm/instructions.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 621472ec7c..c63bd51a10 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -119,7 +119,7 @@ draw_create_vs_llvm(struct draw_context *draw, vs->base.create_varient = draw_vs_varient_generic; vs->base.run_linear = vs_llvm_run_linear; vs->base.delete = vs_llvm_delete; - vs->machine = &draw->machine; + vs->machine = &draw->vs.machine; { struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); @@ -130,16 +130,16 @@ draw_create_vs_llvm(struct draw_context *draw, gallivm_ir_delete(ir); } - draw->engine = gallivm_global_cpu_engine(); + draw->vs.engine = gallivm_global_cpu_engine(); /* XXX: Why are there two versions of this? Shouldn't creating the * engine be a separate operation to compiling a shader? */ - if (!draw->engine) { - draw->engine = gallivm_cpu_engine_create(vs->llvm_prog); + if (!draw->vs.engine) { + draw->vs.engine = gallivm_cpu_engine_create(vs->llvm_prog); } else { - gallivm_cpu_jit_compile(draw->engine, vs->llvm_prog); + gallivm_cpu_jit_compile(draw->vs.engine, vs->llvm_prog); } return &vs->base; diff --git a/src/gallium/auxiliary/gallivm/instructions.h b/src/gallium/auxiliary/gallivm/instructions.h index 19ca84ddc6..3a476928b6 100644 --- a/src/gallium/auxiliary/gallivm/instructions.h +++ b/src/gallium/auxiliary/gallivm/instructions.h @@ -85,7 +85,7 @@ public: llvm::Value *lit(llvm::Value *in); llvm::Value *lg2(llvm::Value *in); llvm::Value *madd(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in2); + llvm::Value *in3); llvm::Value *min(llvm::Value *in1, llvm::Value *in2); llvm::Value *max(llvm::Value *in1, llvm::Value *in2); llvm::Value *mul(llvm::Value *in1, llvm::Value *in2); -- cgit v1.2.3 From bd3b47590e2a8e91a8f5545d7c8872b26879c228 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 13 Jul 2008 11:30:02 +0200 Subject: tgsi: Remove depricated ATTRIB interpolate mode. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 3 +-- src/gallium/include/pipe/p_shader_tokens.h | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 6356b6de06..59e7aaeceb 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -119,8 +119,7 @@ static const char *TGSI_INTERPOLATES_SHORT[] = { "CONSTANT", "LINEAR", - "PERSPECTIVE", - "ATTRIB" + "PERSPECTIVE" }; static const char *TGSI_SEMANTICS[] = diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 84e5096418..33268553ff 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -75,6 +75,7 @@ enum tgsi_file_type { #define TGSI_INTERPOLATE_CONSTANT 0 #define TGSI_INTERPOLATE_LINEAR 1 #define TGSI_INTERPOLATE_PERSPECTIVE 2 +#define TGSI_INTERPOLATE_COUNT 3 struct tgsi_declaration { -- cgit v1.2.3 From ee647b9020b5e16b9b6d399edfa4a2c99f491863 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 13 Jul 2008 11:37:36 +0200 Subject: tgsi: Parse DCL statements. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 330 +++++++++++++++++++++------- 1 file changed, 256 insertions(+), 74 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index bb365d1efe..03c9217243 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -49,6 +49,21 @@ static boolean is_digit_alpha_underscore( const char *cur ) return is_digit( cur ) || is_alpha_underscore( cur ); } +static boolean str_match_no_case( const char **pcur, const char *str ) +{ + const char *cur = *pcur; + + while (*str != '\0' && *str == toupper( *cur )) { + str++; + cur++; + } + if (*str == '\0') { + *pcur = cur; + return TRUE; + } + return FALSE; +} + /* Eat zero or more whitespaces. */ static void eat_opt_white( const char **pcur ) @@ -110,28 +125,14 @@ static boolean parse_header( struct translate_ctx *ctx ) { uint processor; - if (ctx->cur[0] == 'F' && ctx->cur[1] == 'R' && ctx->cur[2] == 'A' && ctx->cur[3] == 'G') { - ctx->cur += 4; + if (str_match_no_case( &ctx->cur, "FRAG1.1" )) processor = TGSI_PROCESSOR_FRAGMENT; - } - else if (ctx->cur[0] == 'V' && ctx->cur[1] == 'E' && ctx->cur[2] == 'R' && ctx->cur[3] == 'T') { - ctx->cur += 4; + else if (str_match_no_case( &ctx->cur, "VERT1.1" )) processor = TGSI_PROCESSOR_VERTEX; - } - else if (ctx->cur[0] == 'G' && ctx->cur[1] == 'E' && ctx->cur[2] == 'O' && ctx->cur[3] == 'M') { - ctx->cur += 4; + else if (str_match_no_case( &ctx->cur, "GEOM1.1" )) processor = TGSI_PROCESSOR_GEOMETRY; - } - else { - report_error( ctx, "Unknown processor type" ); - return FALSE; - } - - if (ctx->cur[0] == '1' && ctx->cur[1] == '.' && ctx->cur[2] == '1') { - ctx->cur += 3; - } else { - report_error( ctx, "Unknown version" ); + report_error( ctx, "Unknown header" ); return FALSE; } @@ -187,16 +188,13 @@ parse_file( for (i = 0; i < TGSI_FILE_COUNT; i++) { const char *cur = ctx->cur; - const char *name = file_names[i]; - while (*name != '\0' && *name == toupper( *cur )) { - name++; - cur++; - } - if (*name == '\0' && !is_digit_alpha_underscore( cur )) { - ctx->cur = cur; - *file = i; - return TRUE; + if (str_match_no_case( &cur, file_names[i] )) { + if (!is_digit_alpha_underscore( cur )) { + ctx->cur = cur; + *file = i; + return TRUE; + } } } report_error( ctx, "Unknown register file" ); @@ -204,7 +202,53 @@ parse_file( } static boolean -parse_register( +parse_opt_writemask( + struct translate_ctx *ctx, + uint *writemask ) +{ + const char *cur; + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == '.') { + cur++; + *writemask = TGSI_WRITEMASK_NONE; + eat_opt_white( &cur ); + if (toupper( *cur ) == 'X') { + cur++; + *writemask |= TGSI_WRITEMASK_X; + } + if (toupper( *cur ) == 'Y') { + cur++; + *writemask |= TGSI_WRITEMASK_Y; + } + if (toupper( *cur ) == 'Z') { + cur++; + *writemask |= TGSI_WRITEMASK_Z; + } + if (toupper( *cur ) == 'W') { + cur++; + *writemask |= TGSI_WRITEMASK_W; + } + + if (*writemask == TGSI_WRITEMASK_NONE) { + report_error( ctx, "Writemask expected" ); + return FALSE; + } + + ctx->cur = cur; + } + else { + *writemask = TGSI_WRITEMASK_XYZW; + } + return TRUE; +} + +/* Parse register part common for decls and operands. + * ::= `[' + */ +static boolean +parse_register_prefix( struct translate_ctx *ctx, uint *file, uint *index ) @@ -222,6 +266,20 @@ parse_register( report_error( ctx, "Expected literal integer" ); return FALSE; } + return TRUE; +} + +/* Parse register operand. + * ::= `]' + */ +static boolean +parse_register( + struct translate_ctx *ctx, + uint *file, + uint *index ) +{ + if (!parse_register_prefix( ctx, file, index )) + return FALSE; eat_opt_white( &ctx->cur ); if (*ctx->cur != ']') { report_error( ctx, "Expected `]'" ); @@ -232,54 +290,55 @@ parse_register( return TRUE; } +/* Parse register declaration. + * ::= `]' | `..' `]' + */ +static boolean +parse_register_dcl( + struct translate_ctx *ctx, + uint *file, + uint *first, + uint *last ) +{ + if (!parse_register_prefix( ctx, file, first )) + return FALSE; + eat_opt_white( &ctx->cur ); + if (ctx->cur[0] == '.' && ctx->cur[1] == '.') { + ctx->cur += 2; + eat_opt_white( &ctx->cur ); + if (!parse_uint( &ctx->cur, last )) { + report_error( ctx, "Expected literal integer" ); + return FALSE; + } + eat_opt_white( &ctx->cur ); + } + else { + *last = *first; + } + if (*ctx->cur != ']') { + report_error( ctx, "Expected `]' or `..'" ); + return FALSE; + } + ctx->cur++; + return TRUE; +} + static boolean parse_dst_operand( struct translate_ctx *ctx, struct tgsi_full_dst_register *dst ) { - const char *cur; uint file; uint index; + uint writemask; if (!parse_register( ctx, &file, &index )) return FALSE; + if (!parse_opt_writemask( ctx, &writemask )) + return FALSE; dst->DstRegister.File = file; dst->DstRegister.Index = index; - - /* Parse optional write mask. - */ - cur = ctx->cur; - eat_opt_white( &cur ); - if (*cur == '.') { - uint writemask = TGSI_WRITEMASK_NONE; - - cur++; - eat_opt_white( &cur ); - if (toupper( *cur ) == 'X') { - cur++; - writemask |= TGSI_WRITEMASK_X; - } - if (toupper( *cur ) == 'Y') { - cur++; - writemask |= TGSI_WRITEMASK_Y; - } - if (toupper( *cur ) == 'Z') { - cur++; - writemask |= TGSI_WRITEMASK_Z; - } - if (toupper( *cur ) == 'W') { - cur++; - writemask |= TGSI_WRITEMASK_W; - } - - if (writemask == TGSI_WRITEMASK_NONE) { - report_error( ctx, "Writemask expected" ); - return FALSE; - } - - dst->DstRegister.WriteMask = writemask; - ctx->cur = cur; - } + dst->DstRegister.WriteMask = writemask; return TRUE; } @@ -478,15 +537,10 @@ static boolean parse_instruction( struct translate_ctx *ctx ) eat_opt_white( &ctx->cur ); for (i = 0; i < TGSI_OPCODE_LAST; i++) { const char *cur = ctx->cur; - const char *op = opcode_info[i].mnemonic; - while (*op != '\0' && *op == toupper( *cur )) { - op++; - cur++; - } - if (*op == '\0') { + if (str_match_no_case( &cur, opcode_info[i].mnemonic )) { /* TODO: _SAT suffix */ - if (*cur == '\0' || eat_white( &cur )) { + if (eat_white( &cur )) { ctx->cur = cur; break; } @@ -525,7 +579,6 @@ static boolean parse_instruction( struct translate_ctx *ctx ) return FALSE; } } - eat_opt_white( &ctx->cur ); advance = tgsi_build_full_instruction( &inst, @@ -539,22 +592,151 @@ static boolean parse_instruction( struct translate_ctx *ctx ) return TRUE; } +static const char *semantic_names[TGSI_SEMANTIC_COUNT] = +{ + "POSITION", + "COLOR", + "BCOLOR", + "FOG", + "PSIZE", + "GENERIC", + "NORMAL" +}; + +static const char *interpolate_names[TGSI_INTERPOLATE_COUNT] = +{ + "CONSTANT", + "LINEAR", + "PERSPECTIVE" +}; + +static boolean parse_declaration( struct translate_ctx *ctx ) +{ + struct tgsi_full_declaration decl; + uint file; + uint first; + uint last; + uint writemask; + const char *cur; + uint advance; + + if (!eat_white( &ctx->cur )) { + report_error( ctx, "Syntax error" ); + return FALSE; + } + if (!parse_register_dcl( ctx, &file, &first, &last )) + return FALSE; + if (!parse_opt_writemask( ctx, &writemask )) + return FALSE; + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = file; + decl.Declaration.UsageMask = writemask; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == ',') { + uint i; + + cur++; + eat_opt_white( &cur ); + for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) { + if (str_match_no_case( &cur, semantic_names[i] )) { + const char *cur2 = cur; + uint index; + + if (is_digit_alpha_underscore( cur )) + continue; + eat_opt_white( &cur2 ); + if (*cur2 == '[') { + cur2++; + eat_opt_white( &cur2 ); + if (!parse_uint( &cur2, &index )) { + report_error( ctx, "Expected literal integer" ); + return FALSE; + } + eat_opt_white( &cur2 ); + if (*cur2 != ']') { + report_error( ctx, "Expected `]'" ); + return FALSE; + } + cur2++; + + decl.Semantic.SemanticIndex = index; + + cur = cur2; + } + + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = i; + + ctx->cur = cur; + break; + } + } + } + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == ',') { + uint i; + + cur++; + eat_opt_white( &cur ); + for (i = 0; i < TGSI_INTERPOLATE_COUNT; i++) { + if (str_match_no_case( &cur, interpolate_names[i] )) { + if (is_digit_alpha_underscore( cur )) + continue; + decl.Declaration.Interpolate = i; + + ctx->cur = cur; + break; + } + } + if (i == TGSI_INTERPOLATE_COUNT) { + report_error( ctx, "Expected semantic or interpolate attribute" ); + return FALSE; + } + } + + advance = tgsi_build_full_declaration( + &decl, + ctx->tokens_cur, + ctx->header, + (uint) (ctx->tokens_end - ctx->tokens_cur) ); + if (advance == 0) + return FALSE; + ctx->tokens_cur += advance; + + return TRUE; +} + static boolean translate( struct translate_ctx *ctx ) { eat_opt_white( &ctx->cur ); if (!parse_header( ctx )) return FALSE; - eat_white( &ctx->cur ); while (*ctx->cur != '\0') { uint label_val = 0; + if (!eat_white( &ctx->cur )) { + report_error( ctx, "Syntax error" ); + return FALSE; + } + if (parse_label( ctx, &label_val )) { if (!parse_instruction( ctx )) return FALSE; } + else if (str_match_no_case( &ctx->cur, "DCL" )) { + if (!parse_declaration( ctx )) + return FALSE; + } else { - report_error( ctx, "Instruction expected" ); + report_error( ctx, "Expected `DCL' or a label" ); return FALSE; } } -- cgit v1.2.3 From 625034104aacaca793ff373414eff4ee53afc1fe Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 13 Jul 2008 11:42:33 +0200 Subject: tgsi: Add missing SWZ opcode. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 3 ++- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 59e7aaeceb..cae74a9267 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -395,7 +395,8 @@ static const char *TGSI_OPCODES_SHORT[TGSI_OPCODE_LAST] = "IFC", "BREAKC", "KIL", - "END" + "END", + "SWZ" }; static const char *TGSI_SATS[] = diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index 03c9217243..3415b38f9c 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -522,7 +522,8 @@ static const struct opcode_info opcode_info[TGSI_OPCODE_LAST] = { 1, 2, "IFC" }, { 1, 2, "BREAKC" }, { 1, 2, "KIL" }, - { 0, 0, "END" } + { 0, 0, "END" }, + { 1, 1, "SWZ" } }; static boolean parse_instruction( struct translate_ctx *ctx ) -- cgit v1.2.3 From cfd2bf9fa127a7f0b1a89650fde34a23f318f90c Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 13 Jul 2008 11:43:30 +0200 Subject: tgsi: Fix instruction opcode parsing. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index 3415b38f9c..7848f3d55f 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -541,7 +541,7 @@ static boolean parse_instruction( struct translate_ctx *ctx ) if (str_match_no_case( &cur, opcode_info[i].mnemonic )) { /* TODO: _SAT suffix */ - if (eat_white( &cur )) { + if (*cur == '\0' || eat_white( &cur )) { ctx->cur = cur; break; } -- cgit v1.2.3 From 46a7843099f02b6dcff56a52c9247c11d5c4aa8b Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 13 Jul 2008 12:16:16 +0200 Subject: tgsi: Fix instruction operand counts. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 208 ++++++++++++++-------------- 1 file changed, 104 insertions(+), 104 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index 7848f3d55f..3c7a4688c9 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -405,9 +405,9 @@ struct opcode_info static const struct opcode_info opcode_info[TGSI_OPCODE_LAST] = { -{ 1, 1, "ARL" }, + { 1, 1, "ARL" }, { 1, 1, "MOV" }, -{ 1, 1, "LIT" }, + { 1, 1, "LIT" }, { 1, 1, "RCP" }, { 1, 1, "RSQ" }, { 1, 1, "EXP" }, @@ -416,112 +416,112 @@ static const struct opcode_info opcode_info[TGSI_OPCODE_LAST] = { 1, 2, "ADD" }, { 1, 2, "DP3" }, { 1, 2, "DP4" }, -{ 1, 2, "DST" }, + { 1, 2, "DST" }, { 1, 2, "MIN" }, { 1, 2, "MAX" }, -{ 1, 2, "SLT" }, -{ 1, 2, "SGE" }, + { 1, 2, "SLT" }, + { 1, 2, "SGE" }, { 1, 3, "MAD" }, { 1, 2, "SUB" }, -{ 1, 3, "LERP" }, -{ 1, 2, "CND" }, -{ 1, 2, "CND0" }, -{ 1, 2, "DOT2ADD" }, -{ 1, 2, "INDEX" }, -{ 1, 2, "NEGATE" }, -{ 1, 2, "FRAC" }, -{ 1, 2, "CLAMP" }, -{ 1, 2, "FLOOR" }, -{ 1, 2, "ROUND" }, -{ 1, 2, "EXPBASE2" }, -{ 1, 2, "LOGBASE2" }, -{ 1, 2, "POWER" }, -{ 1, 2, "CROSSPRODUCT" }, -{ 1, 2, "MULTIPLYMATRIX" }, - { 1, 2, "ABS" }, -{ 1, 2, "RCC" }, -{ 1, 2, "DPH" }, -{ 1, 2, "COS" }, -{ 1, 2, "DDX" }, -{ 1, 2, "DDY" }, -{ 1, 2, "KILP" }, -{ 1, 2, "PK2H" }, -{ 1, 2, "PK2US" }, -{ 1, 2, "PK4B" }, -{ 1, 2, "PK4UB" }, -{ 1, 2, "RFL" }, -{ 1, 2, "SEQ" }, -{ 1, 2, "SFL" }, -{ 1, 2, "SGT" }, -{ 1, 2, "SIN" }, -{ 1, 2, "SLE" }, -{ 1, 2, "SNE" }, -{ 1, 2, "STR" }, -{ 1, 2, "TEX" }, -{ 1, 2, "TXD" }, -{ 1, 2, "TXP" }, -{ 1, 2, "UP2H" }, -{ 1, 2, "UP2US" }, -{ 1, 2, "UP4B" }, -{ 1, 2, "UP4UB" }, -{ 1, 2, "X2D" }, -{ 1, 2, "ARA" }, -{ 1, 2, "ARR" }, -{ 1, 2, "BRA" }, -{ 1, 2, "CAL" }, -{ 1, 2, "RET" }, -{ 1, 2, "SSG" }, -{ 1, 2, "CMP" }, -{ 1, 2, "SCS" }, -{ 1, 2, "TXB" }, -{ 1, 2, "NRM" }, -{ 1, 2, "DIV" }, -{ 1, 2, "DP2" }, -{ 1, 2, "TXL" }, -{ 1, 2, "BRK" }, -{ 1, 2, "IF" }, -{ 1, 2, "LOOP" }, -{ 1, 2, "REP" }, -{ 1, 2, "ELSE" }, -{ 1, 2, "ENDIF" }, -{ 1, 2, "ENDLOOP" }, -{ 1, 2, "ENDREP" }, -{ 1, 2, "PUSHA" }, -{ 1, 2, "POPA" }, -{ 1, 2, "CEIL" }, -{ 1, 2, "I2F" }, -{ 1, 2, "NOT" }, -{ 1, 2, "TRUNC" }, -{ 1, 2, "SHL" }, -{ 1, 2, "SHR" }, -{ 1, 2, "AND" }, -{ 1, 2, "OR" }, -{ 1, 2, "MOD" }, -{ 1, 2, "XOR" }, -{ 1, 2, "SAD" }, -{ 1, 2, "TXF" }, -{ 1, 2, "TXQ" }, -{ 1, 2, "CONT" }, -{ 1, 2, "EMIT" }, -{ 1, 2, "ENDPRIM" }, -{ 1, 2, "BGNLOOP2" }, -{ 1, 2, "BGNSUB" }, -{ 1, 2, "ENDLOOP2" }, -{ 1, 2, "ENDSUB" }, -{ 1, 2, "NOISE1" }, -{ 1, 2, "NOISE2" }, -{ 1, 2, "NOISE3" }, -{ 1, 2, "NOISE4" }, -{ 1, 2, "NOP" }, -{ 1, 2, "M4X3" }, -{ 1, 2, "M3X4" }, -{ 1, 2, "M3X3" }, -{ 1, 2, "M3X2" }, -{ 1, 2, "NRM4" }, -{ 1, 2, "CALLNZ" }, -{ 1, 2, "IFC" }, -{ 1, 2, "BREAKC" }, -{ 1, 2, "KIL" }, + { 1, 3, "LERP" }, + { 1, 3, "CND" }, + { 1, 3, "CND0" }, + { 1, 3, "DOT2ADD" }, + { 1, 2, "INDEX" }, + { 1, 1, "NEGATE" }, + { 1, 1, "FRAC" }, + { 1, 3, "CLAMP" }, + { 1, 1, "FLOOR" }, + { 1, 1, "ROUND" }, + { 1, 1, "EXPBASE2" }, + { 1, 1, "LOGBASE2" }, + { 1, 2, "POWER" }, + { 1, 2, "CROSSPRODUCT" }, + { 1, 2, "MULTIPLYMATRIX" }, + { 1, 1, "ABS" }, + { 1, 1, "RCC" }, + { 1, 2, "DPH" }, + { 1, 1, "COS" }, + { 1, 1, "DDX" }, + { 1, 1, "DDY" }, + { 0, 1, "KILP" }, + { 1, 1, "PK2H" }, + { 1, 1, "PK2US" }, + { 1, 1, "PK4B" }, + { 1, 1, "PK4UB" }, + { 1, 2, "RFL" }, + { 1, 2, "SEQ" }, + { 1, 2, "SFL" }, + { 1, 2, "SGT" }, + { 1, 1, "SIN" }, + { 1, 2, "SLE" }, + { 1, 2, "SNE" }, + { 1, 2, "STR" }, + { 1, 1, "TEX" }, + { 1, 3, "TXD" }, + { 1, 1, "TXP" }, + { 1, 1, "UP2H" }, + { 1, 1, "UP2US" }, + { 1, 1, "UP4B" }, + { 1, 1, "UP4UB" }, + { 1, 3, "X2D" }, + { 1, 1, "ARA" }, + { 1, 1, "ARR" }, + { 0, 1, "BRA" }, + { 0, 0, "CAL" }, + { 0, 0, "RET" }, + { 1, 1, "SSG" }, + { 1, 3, "CMP" }, + { 1, 1, "SCS" }, + { 1, 1, "TXB" }, + { 1, 1, "NRM" }, + { 1, 2, "DIV" }, + { 1, 2, "DP2" }, + { 1, 1, "TXL" }, + { 0, 0, "BRK" }, + { 0, 1, "IF" }, + { 0, 0, "LOOP" }, + { 0, 1, "REP" }, + { 0, 0, "ELSE" }, + { 0, 0, "ENDIF" }, + { 0, 0, "ENDLOOP" }, + { 0, 0, "ENDREP" }, + { 0, 1, "PUSHA" }, + { 1, 0, "POPA" }, + { 1, 1, "CEIL" }, + { 1, 1, "I2F" }, + { 1, 1, "NOT" }, + { 1, 1, "TRUNC" }, + { 1, 2, "SHL" }, + { 1, 2, "SHR" }, + { 1, 2, "AND" }, + { 1, 2, "OR" }, + { 1, 2, "MOD" }, + { 1, 2, "XOR" }, + { 1, 3, "SAD" }, + { 1, 1, "TXF" }, + { 1, 1, "TXQ" }, + { 0, 0, "CONT" }, + { 0, 0, "EMIT" }, + { 0, 0, "ENDPRIM" }, + { 0, 0, "BGNLOOP2" }, + { 0, 0, "BGNSUB" }, + { 0, 0, "ENDLOOP2" }, + { 0, 0, "ENDSUB" }, + { 1, 1, "NOISE1" }, + { 1, 1, "NOISE2" }, + { 1, 1, "NOISE3" }, + { 1, 1, "NOISE4" }, + { 0, 0, "NOP" }, + { 1, 2, "M4X3" }, + { 1, 2, "M3X4" }, + { 1, 2, "M3X3" }, + { 1, 2, "M3X2" }, + { 1, 1, "NRM4" }, + { 0, 1, "CALLNZ" }, + { 0, 1, "IFC" }, + { 0, 1, "BREAKC" }, + { 0, 0, "KIL" }, { 0, 0, "END" }, { 1, 1, "SWZ" } }; -- cgit v1.2.3 From 3d5dcc2203f5018863ad51958871542696e1ed1b Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 13 Jul 2008 13:13:39 +0200 Subject: tgsi: Parse texture instructions correctly. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 272 +++++++++++++++------------- src/gallium/include/pipe/p_shader_tokens.h | 1 + 2 files changed, 152 insertions(+), 121 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index 3c7a4688c9..7485002862 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -400,130 +400,144 @@ struct opcode_info { uint num_dst; uint num_src; + uint is_tex; const char *mnemonic; }; static const struct opcode_info opcode_info[TGSI_OPCODE_LAST] = { - { 1, 1, "ARL" }, - { 1, 1, "MOV" }, - { 1, 1, "LIT" }, - { 1, 1, "RCP" }, - { 1, 1, "RSQ" }, - { 1, 1, "EXP" }, - { 1, 1, "LOG" }, - { 1, 2, "MUL" }, - { 1, 2, "ADD" }, - { 1, 2, "DP3" }, - { 1, 2, "DP4" }, - { 1, 2, "DST" }, - { 1, 2, "MIN" }, - { 1, 2, "MAX" }, - { 1, 2, "SLT" }, - { 1, 2, "SGE" }, - { 1, 3, "MAD" }, - { 1, 2, "SUB" }, - { 1, 3, "LERP" }, - { 1, 3, "CND" }, - { 1, 3, "CND0" }, - { 1, 3, "DOT2ADD" }, - { 1, 2, "INDEX" }, - { 1, 1, "NEGATE" }, - { 1, 1, "FRAC" }, - { 1, 3, "CLAMP" }, - { 1, 1, "FLOOR" }, - { 1, 1, "ROUND" }, - { 1, 1, "EXPBASE2" }, - { 1, 1, "LOGBASE2" }, - { 1, 2, "POWER" }, - { 1, 2, "CROSSPRODUCT" }, - { 1, 2, "MULTIPLYMATRIX" }, - { 1, 1, "ABS" }, - { 1, 1, "RCC" }, - { 1, 2, "DPH" }, - { 1, 1, "COS" }, - { 1, 1, "DDX" }, - { 1, 1, "DDY" }, - { 0, 1, "KILP" }, - { 1, 1, "PK2H" }, - { 1, 1, "PK2US" }, - { 1, 1, "PK4B" }, - { 1, 1, "PK4UB" }, - { 1, 2, "RFL" }, - { 1, 2, "SEQ" }, - { 1, 2, "SFL" }, - { 1, 2, "SGT" }, - { 1, 1, "SIN" }, - { 1, 2, "SLE" }, - { 1, 2, "SNE" }, - { 1, 2, "STR" }, - { 1, 1, "TEX" }, - { 1, 3, "TXD" }, - { 1, 1, "TXP" }, - { 1, 1, "UP2H" }, - { 1, 1, "UP2US" }, - { 1, 1, "UP4B" }, - { 1, 1, "UP4UB" }, - { 1, 3, "X2D" }, - { 1, 1, "ARA" }, - { 1, 1, "ARR" }, - { 0, 1, "BRA" }, - { 0, 0, "CAL" }, - { 0, 0, "RET" }, - { 1, 1, "SSG" }, - { 1, 3, "CMP" }, - { 1, 1, "SCS" }, - { 1, 1, "TXB" }, - { 1, 1, "NRM" }, - { 1, 2, "DIV" }, - { 1, 2, "DP2" }, - { 1, 1, "TXL" }, - { 0, 0, "BRK" }, - { 0, 1, "IF" }, - { 0, 0, "LOOP" }, - { 0, 1, "REP" }, - { 0, 0, "ELSE" }, - { 0, 0, "ENDIF" }, - { 0, 0, "ENDLOOP" }, - { 0, 0, "ENDREP" }, - { 0, 1, "PUSHA" }, - { 1, 0, "POPA" }, - { 1, 1, "CEIL" }, - { 1, 1, "I2F" }, - { 1, 1, "NOT" }, - { 1, 1, "TRUNC" }, - { 1, 2, "SHL" }, - { 1, 2, "SHR" }, - { 1, 2, "AND" }, - { 1, 2, "OR" }, - { 1, 2, "MOD" }, - { 1, 2, "XOR" }, - { 1, 3, "SAD" }, - { 1, 1, "TXF" }, - { 1, 1, "TXQ" }, - { 0, 0, "CONT" }, - { 0, 0, "EMIT" }, - { 0, 0, "ENDPRIM" }, - { 0, 0, "BGNLOOP2" }, - { 0, 0, "BGNSUB" }, - { 0, 0, "ENDLOOP2" }, - { 0, 0, "ENDSUB" }, - { 1, 1, "NOISE1" }, - { 1, 1, "NOISE2" }, - { 1, 1, "NOISE3" }, - { 1, 1, "NOISE4" }, - { 0, 0, "NOP" }, - { 1, 2, "M4X3" }, - { 1, 2, "M3X4" }, - { 1, 2, "M3X3" }, - { 1, 2, "M3X2" }, - { 1, 1, "NRM4" }, - { 0, 1, "CALLNZ" }, - { 0, 1, "IFC" }, - { 0, 1, "BREAKC" }, - { 0, 0, "KIL" }, - { 0, 0, "END" }, - { 1, 1, "SWZ" } + { 1, 1, 0, "ARL" }, + { 1, 1, 0, "MOV" }, + { 1, 1, 0, "LIT" }, + { 1, 1, 0, "RCP" }, + { 1, 1, 0, "RSQ" }, + { 1, 1, 0, "EXP" }, + { 1, 1, 0, "LOG" }, + { 1, 2, 0, "MUL" }, + { 1, 2, 0, "ADD" }, + { 1, 2, 0, "DP3" }, + { 1, 2, 0, "DP4" }, + { 1, 2, 0, "DST" }, + { 1, 2, 0, "MIN" }, + { 1, 2, 0, "MAX" }, + { 1, 2, 0, "SLT" }, + { 1, 2, 0, "SGE" }, + { 1, 3, 0, "MAD" }, + { 1, 2, 0, "SUB" }, + { 1, 3, 0, "LERP" }, + { 1, 3, 0, "CND" }, + { 1, 3, 0, "CND0" }, + { 1, 3, 0, "DOT2ADD" }, + { 1, 2, 0, "INDEX" }, + { 1, 1, 0, "NEGATE" }, + { 1, 1, 0, "FRAC" }, + { 1, 3, 0, "CLAMP" }, + { 1, 1, 0, "FLOOR" }, + { 1, 1, 0, "ROUND" }, + { 1, 1, 0, "EXPBASE2" }, + { 1, 1, 0, "LOGBASE2" }, + { 1, 2, 0, "POWER" }, + { 1, 2, 0, "CROSSPRODUCT" }, + { 1, 2, 0, "MULTIPLYMATRIX" }, + { 1, 1, 0, "ABS" }, + { 1, 1, 0, "RCC" }, + { 1, 2, 0, "DPH" }, + { 1, 1, 0, "COS" }, + { 1, 1, 0, "DDX" }, + { 1, 1, 0, "DDY" }, + { 0, 1, 0, "KILP" }, + { 1, 1, 0, "PK2H" }, + { 1, 1, 0, "PK2US" }, + { 1, 1, 0, "PK4B" }, + { 1, 1, 0, "PK4UB" }, + { 1, 2, 0, "RFL" }, + { 1, 2, 0, "SEQ" }, + { 1, 2, 0, "SFL" }, + { 1, 2, 0, "SGT" }, + { 1, 1, 0, "SIN" }, + { 1, 2, 0, "SLE" }, + { 1, 2, 0, "SNE" }, + { 1, 2, 0, "STR" }, + { 1, 2, 1, "TEX" }, + { 1, 4, 1, "TXD" }, + { 1, 2, 1, "TXP" }, + { 1, 1, 0, "UP2H" }, + { 1, 1, 0, "UP2US" }, + { 1, 1, 0, "UP4B" }, + { 1, 1, 0, "UP4UB" }, + { 1, 3, 0, "X2D" }, + { 1, 1, 0, "ARA" }, + { 1, 1, 0, "ARR" }, + { 0, 1, 0, "BRA" }, + { 0, 0, 0, "CAL" }, + { 0, 0, 0, "RET" }, + { 1, 1, 0, "SSG" }, + { 1, 3, 0, "CMP" }, + { 1, 1, 0, "SCS" }, + { 1, 2, 1, "TXB" }, + { 1, 1, 0, "NRM" }, + { 1, 2, 0, "DIV" }, + { 1, 2, 0, "DP2" }, + { 1, 2, 1, "TXL" }, + { 0, 0, 0, "BRK" }, + { 0, 1, 0, "IF" }, + { 0, 0, 0, "LOOP" }, + { 0, 1, 0, "REP" }, + { 0, 0, 0, "ELSE" }, + { 0, 0, 0, "ENDIF" }, + { 0, 0, 0, "ENDLOOP" }, + { 0, 0, 0, "ENDREP" }, + { 0, 1, 0, "PUSHA" }, + { 1, 0, 0, "POPA" }, + { 1, 1, 0, "CEIL" }, + { 1, 1, 0, "I2F" }, + { 1, 1, 0, "NOT" }, + { 1, 1, 0, "TRUNC" }, + { 1, 2, 0, "SHL" }, + { 1, 2, 0, "SHR" }, + { 1, 2, 0, "AND" }, + { 1, 2, 0, "OR" }, + { 1, 2, 0, "MOD" }, + { 1, 2, 0, "XOR" }, + { 1, 3, 0, "SAD" }, + { 1, 2, 1, "TXF" }, + { 1, 2, 1, "TXQ" }, + { 0, 0, 0, "CONT" }, + { 0, 0, 0, "EMIT" }, + { 0, 0, 0, "ENDPRIM" }, + { 0, 0, 0, "BGNLOOP2" }, + { 0, 0, 0, "BGNSUB" }, + { 0, 0, 0, "ENDLOOP2" }, + { 0, 0, 0, "ENDSUB" }, + { 1, 1, 0, "NOISE1" }, + { 1, 1, 0, "NOISE2" }, + { 1, 1, 0, "NOISE3" }, + { 1, 1, 0, "NOISE4" }, + { 0, 0, 0, "NOP" }, + { 1, 2, 0, "M4X3" }, + { 1, 2, 0, "M3X4" }, + { 1, 2, 0, "M3X3" }, + { 1, 2, 0, "M3X2" }, + { 1, 1, 0, "NRM4" }, + { 0, 1, 0, "CALLNZ" }, + { 0, 1, 0, "IFC" }, + { 0, 1, 0, "BREAKC" }, + { 0, 0, 0, "KIL" }, + { 0, 0, 0, "END" }, + { 1, 1, 0, "SWZ" } +}; + +static const char *texture_names[TGSI_TEXTURE_COUNT] = +{ + "UNKNOWN", + "1D", + "2D", + "3D", + "CUBE", + "RECT", + "SHADOW1D", + "SHADOW2D", + "SHADOWRECT" }; static boolean parse_instruction( struct translate_ctx *ctx ) @@ -560,7 +574,7 @@ static boolean parse_instruction( struct translate_ctx *ctx ) /* Parse instruction operands. */ - for (i = 0; i < info->num_dst + info->num_src; i++) { + for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) { if (i > 0) { eat_opt_white( &ctx->cur ); if (*ctx->cur != ',') { @@ -575,10 +589,26 @@ static boolean parse_instruction( struct translate_ctx *ctx ) if (!parse_dst_operand( ctx, &inst.FullDstRegisters[i] )) return FALSE; } - else { + else if (i < info->num_dst + info->num_src) { if (!parse_src_operand( ctx, &inst.FullSrcRegisters[i - info->num_dst] )) return FALSE; } + else { + uint j; + + for (j = 0; j < TGSI_TEXTURE_COUNT; j++) { + if (str_match_no_case( &ctx->cur, texture_names[j] )) { + if (!is_digit_alpha_underscore( ctx->cur )) { + inst.InstructionExtTexture.Texture = j; + break; + } + } + } + if (j == TGSI_TEXTURE_COUNT) { + report_error( ctx, "Expected texture target" ); + return FALSE; + } + } } advance = tgsi_build_full_instruction( diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 33268553ff..c8e2830516 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -529,6 +529,7 @@ struct tgsi_instruction_ext_label #define TGSI_TEXTURE_SHADOW1D 6 #define TGSI_TEXTURE_SHADOW2D 7 #define TGSI_TEXTURE_SHADOWRECT 8 +#define TGSI_TEXTURE_COUNT 9 struct tgsi_instruction_ext_texture { -- cgit v1.2.3 From a7d8eed61c1fd0bd3d99ebcd10c24bc70f8e3293 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 13 Jul 2008 14:03:21 +0200 Subject: tgsi: Parse IMM statements. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 111 +++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index 7485002862..d5a9480f4a 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -100,6 +100,51 @@ static boolean parse_uint( const char **pcur, uint *val ) return FALSE; } +/* Parse floating point. + */ +static boolean parse_float( const char **pcur, float *val ) +{ + const char *cur = *pcur; + boolean integral_part = FALSE; + boolean fractional_part = FALSE; + + *val = (float) atof( cur ); + + if (*cur == '-' || *cur == '+') + cur++; + if (is_digit( cur )) { + cur++; + integral_part = TRUE; + while (is_digit( cur )) + cur++; + } + if (*cur == '.') { + cur++; + if (is_digit( cur )) { + cur++; + fractional_part = TRUE; + while (is_digit( cur )) + cur++; + } + } + if (!integral_part && !fractional_part) + return FALSE; + if (toupper( *cur ) == 'E') { + cur++; + if (*cur == '-' || *cur == '+') + cur++; + if (is_digit( cur )) { + cur++; + while (is_digit( cur )) + cur++; + } + else + return FALSE; + } + *pcur = cur; + return TRUE; +} + struct translate_ctx { const char *text; @@ -744,6 +789,66 @@ static boolean parse_declaration( struct translate_ctx *ctx ) return TRUE; } +static boolean parse_immediate( struct translate_ctx *ctx ) +{ + struct tgsi_full_immediate imm; + uint i; + float values[4]; + uint advance; + + if (!eat_white( &ctx->cur )) { + report_error( ctx, "Syntax error" ); + return FALSE; + } + if (!str_match_no_case( &ctx->cur, "FLT32" ) || is_digit_alpha_underscore( ctx->cur )) { + report_error( ctx, "Expected `FLT32'" ); + return FALSE; + } + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '{') { + report_error( ctx, "Expected `{'" ); + return FALSE; + } + ctx->cur++; + for (i = 0; i < 4; i++) { + eat_opt_white( &ctx->cur ); + if (i > 0) { + if (*ctx->cur != ',') { + report_error( ctx, "Expected `,'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + } + if (!parse_float( &ctx->cur, &values[i] )) { + report_error( ctx, "Expected literal floating point" ); + return FALSE; + } + } + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '}') { + report_error( ctx, "Expected `}'" ); + return FALSE; + } + ctx->cur++; + + imm = tgsi_default_full_immediate(); + imm.Immediate.Size += 4; + imm.Immediate.DataType = TGSI_IMM_FLOAT32; + imm.u.Pointer = values; + + advance = tgsi_build_full_immediate( + &imm, + ctx->tokens_cur, + ctx->header, + (uint) (ctx->tokens_end - ctx->tokens_cur) ); + if (advance == 0) + return FALSE; + ctx->tokens_cur += advance; + + return TRUE; +} + static boolean translate( struct translate_ctx *ctx ) { eat_opt_white( &ctx->cur ); @@ -766,8 +871,12 @@ static boolean translate( struct translate_ctx *ctx ) if (!parse_declaration( ctx )) return FALSE; } + else if (str_match_no_case( &ctx->cur, "IMM" )) { + if (!parse_immediate( ctx )) + return FALSE; + } else { - report_error( ctx, "Expected `DCL' or a label" ); + report_error( ctx, "Expected `DCL', `IMM' or a label" ); return FALSE; } } -- cgit v1.2.3 From 47a45aaa0fd1dbc0de45de2ed2995f81a0154baf Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 13 Jul 2008 14:50:12 +0200 Subject: tgsi: Parse _SAT and _SAT opcode suffix. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 2 +- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index cae74a9267..8220e09199 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -716,7 +716,7 @@ tgsi_dump_instruction( TXT( "_SAT" ); break; case TGSI_SAT_MINUS_PLUS_ONE: - TXT( "_SAT[-1,1]" ); + TXT( "_SATNV" ); break; default: assert( 0 ); diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index d5a9480f4a..f3fc675807 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -588,6 +588,7 @@ static const char *texture_names[TGSI_TEXTURE_COUNT] = static boolean parse_instruction( struct translate_ctx *ctx ) { uint i; + uint saturate = TGSI_SAT_NONE; const struct opcode_info *info; struct tgsi_full_instruction inst; uint advance; @@ -599,7 +600,11 @@ static boolean parse_instruction( struct translate_ctx *ctx ) const char *cur = ctx->cur; if (str_match_no_case( &cur, opcode_info[i].mnemonic )) { - /* TODO: _SAT suffix */ + if (str_match_no_case( &cur, "_SATNV" )) + saturate = TGSI_SAT_MINUS_PLUS_ONE; + else if (str_match_no_case( &cur, "_SAT" )) + saturate = TGSI_SAT_ZERO_ONE; + if (*cur == '\0' || eat_white( &cur )) { ctx->cur = cur; break; @@ -614,6 +619,7 @@ static boolean parse_instruction( struct translate_ctx *ctx ) inst = tgsi_default_full_instruction(); inst.Instruction.Opcode = i; + inst.Instruction.Saturate = saturate; inst.Instruction.NumDstRegs = info->num_dst; inst.Instruction.NumSrcRegs = info->num_src; -- cgit v1.2.3 From 94013b66b91112f31802c3d935e8d918ba12be62 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 13 Jul 2008 15:14:31 +0200 Subject: tgsi: Parse extended source register modifiers. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 127 +++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index f3fc675807..c618a50fb9 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -393,14 +393,78 @@ parse_src_operand( struct tgsi_full_src_register *src ) { const char *cur; + float value; uint file; uint index; - /* TODO: Extended register modifiers */ + if (*ctx->cur == '-') { + cur = ctx->cur; + cur++; + eat_opt_white( &cur ); + if (*cur == '(') { + cur++; + src->SrcRegisterExtMod.Negate = 1; + eat_opt_white( &cur ); + ctx->cur = cur; + } + } + + if (*ctx->cur == '|') { + ctx->cur++; + eat_opt_white( &ctx->cur ); + src->SrcRegisterExtMod.Absolute = 1; + } + if (*ctx->cur == '-') { ctx->cur++; + eat_opt_white( &ctx->cur ); src->SrcRegister.Negate = 1; + } + + cur = ctx->cur; + if (parse_float( &cur, &value )) { + if (value == 2.0f) { + eat_opt_white( &cur ); + if (*cur != '*') { + report_error( ctx, "Expected `*'" ); + return FALSE; + } + cur++; + if (*cur != '(') { + report_error( ctx, "Expected `('" ); + return FALSE; + } + cur++; + src->SrcRegisterExtMod.Scale2X = 1; + eat_opt_white( &cur ); + ctx->cur = cur; + } + } + + if (*ctx->cur == '(') { + ctx->cur++; eat_opt_white( &ctx->cur ); + src->SrcRegisterExtMod.Bias = 1; + } + + cur = ctx->cur; + if (parse_float( &cur, &value )) { + if (value == 1.0f) { + eat_opt_white( &cur ); + if (*cur != '-') { + report_error( ctx, "Expected `-'" ); + return FALSE; + } + cur++; + if (*cur != '(') { + report_error( ctx, "Expected `('" ); + return FALSE; + } + cur++; + src->SrcRegisterExtMod.Complement = 1; + eat_opt_white( &cur ); + ctx->cur = cur; + } } if (!parse_register( ctx, &file, &index )) @@ -438,6 +502,67 @@ parse_src_operand( ctx->cur = cur; } + + if (src->SrcRegisterExtMod.Complement) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + } + + if (src->SrcRegisterExtMod.Bias) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '-') { + report_error( ctx, "Expected `-'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (!parse_float( &ctx->cur, &value )) { + report_error( ctx, "Expected literal floating point" ); + return FALSE; + } + if (value != 0.5f) { + report_error( ctx, "Expected 0.5" ); + return FALSE; + } + } + + if (src->SrcRegisterExtMod.Scale2X) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + } + + if (src->SrcRegisterExtMod.Absolute) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '|') { + report_error( ctx, "Expected `|'" ); + return FALSE; + } + ctx->cur++; + } + + if (src->SrcRegisterExtMod.Negate) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + } + return TRUE; } -- cgit v1.2.3 From f5c51ebd2afdfc87de40dca115526a5e0f6ab115 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 13 Jul 2008 15:23:14 +0200 Subject: tgsi: Parse destination operand modulate modifier. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 36 ++++++++++------------------- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 30 ++++++++++++++++++++++++ src/gallium/include/pipe/p_shader_tokens.h | 1 + 3 files changed, 43 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 8220e09199..0cf4454f25 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -539,6 +539,17 @@ static const char *TGSI_MODULATES[] = "MODULATE_EIGHTH" }; +static const char *TGSI_MODULATES_SHORT[TGSI_MODULATE_COUNT] = +{ + "", + "_2X", + "_4X", + "_8X", + "_D2", + "_D4", + "_D8" +}; + void tgsi_dump_declaration( const struct tgsi_full_declaration *decl ) @@ -736,30 +747,7 @@ tgsi_dump_instruction( SID( dst->DstRegister.Index ); CHR( ']' ); - switch (dst->DstRegisterExtModulate.Modulate) { - case TGSI_MODULATE_1X: - break; - case TGSI_MODULATE_2X: - TXT( "_2X" ); - break; - case TGSI_MODULATE_4X: - TXT( "_4X" ); - break; - case TGSI_MODULATE_8X: - TXT( "_8X" ); - break; - case TGSI_MODULATE_HALF: - TXT( "_D2" ); - break; - case TGSI_MODULATE_QUARTER: - TXT( "_D4" ); - break; - case TGSI_MODULATE_EIGHTH: - TXT( "_D8" ); - break; - default: - assert( 0 ); - } + ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES_SHORT ); if( dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW ) { CHR( '.' ); diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index c618a50fb9..1b283feb4c 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -368,6 +368,17 @@ parse_register_dcl( return TRUE; } +static const char *modulate_names[TGSI_MODULATE_COUNT] = +{ + "_1X", + "_2X", + "_4X", + "_8X", + "_D2", + "_D4", + "_D8" +}; + static boolean parse_dst_operand( struct translate_ctx *ctx, @@ -376,11 +387,30 @@ parse_dst_operand( uint file; uint index; uint writemask; + const char *cur; if (!parse_register( ctx, &file, &index )) return FALSE; + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == '_') { + uint i; + + for (i = 0; i < TGSI_MODULATE_COUNT; i++) { + if (str_match_no_case( &cur, modulate_names[i] )) { + if (!is_digit_alpha_underscore( cur )) { + dst->DstRegisterExtModulate.Modulate = i; + ctx->cur = cur; + break; + } + } + } + } + if (!parse_opt_writemask( ctx, &writemask )) return FALSE; + dst->DstRegister.File = file; dst->DstRegister.Index = index; dst->DstRegister.WriteMask = writemask; diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index c8e2830516..ed931d24b9 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -743,6 +743,7 @@ struct tgsi_dst_register_ext_concode #define TGSI_MODULATE_HALF 4 #define TGSI_MODULATE_QUARTER 5 #define TGSI_MODULATE_EIGHTH 6 +#define TGSI_MODULATE_COUNT 7 struct tgsi_dst_register_ext_modulate { -- cgit v1.2.3 From 17af66fc1a141920969ddf404bd7ffb52a94fb31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 13 Jul 2008 22:37:47 +0900 Subject: pb: buffer over/underflows are errors. --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index acb9d7ad14..affa6aa85c 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -142,12 +142,12 @@ pb_debug_buffer_destroy(struct pb_buffer *_buf) assert(map); if(map) { if(!check_random_pattern(map, buf->underflow_size)) { - debug_printf("buffer underflow\n"); + debug_error("buffer underflow detected\n"); debug_assert(0); } if(!check_random_pattern(map + buf->underflow_size + buf->base.base.size, buf->overflow_size)) { - debug_printf("buffer overflow\n"); + debug_error("buffer overflow detected\n"); debug_assert(0); } pb_unmap(buf->buffer); -- cgit v1.2.3 From 36dd89c8a7f2a911e8f7f18d1edcaf982a75a438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 13 Jul 2008 22:39:58 +0900 Subject: util: Eliminate pipe from the arguments to pipe_get/put_tile_xxx functions. You don't need a pipe_context * for this, and all other necessary info is already inside pipe_surface. --- src/gallium/auxiliary/util/p_tile.c | 42 +++++++++++----------------- src/gallium/auxiliary/util/p_tile.h | 19 ++++--------- src/gallium/drivers/softpipe/sp_tile_cache.c | 16 +++++------ 3 files changed, 30 insertions(+), 47 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 93abef9879..1a1a2d96cc 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -45,12 +45,10 @@ * This should be usable by any hw driver that has mappable surfaces. */ void -pipe_get_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_raw(struct pipe_surface *ps, uint x, uint y, uint w, uint h, void *dst, int dst_stride) { - struct pipe_screen *screen = pipe->screen; const void *src; if (pipe_clip_tile(x, y, &w, &h, ps)) @@ -59,14 +57,14 @@ pipe_get_tile_raw(struct pipe_context *pipe, if (dst_stride == 0) dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; - src = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + src = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ); assert(src); if(!src) return; pipe_copy_rect(dst, &ps->block, dst_stride, 0, 0, w, h, src, ps->stride, x, y); - screen->surface_unmap(screen, ps); + pipe_surface_unmap(ps); } @@ -75,12 +73,10 @@ pipe_get_tile_raw(struct pipe_context *pipe, * This should be usable by any hw driver that has mappable surfaces. */ void -pipe_put_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_raw(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const void *src, int src_stride) { - struct pipe_screen *screen = pipe->screen; void *dst; if (pipe_clip_tile(x, y, &w, &h, ps)) @@ -89,14 +85,14 @@ pipe_put_tile_raw(struct pipe_context *pipe, if (src_stride == 0) src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; - dst = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + dst = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE); assert(dst); if(!dst) return; pipe_copy_rect(dst, &ps->block, ps->stride, x, y, w, h, src, src_stride, 0, 0); - screen->surface_unmap(screen, ps); + pipe_surface_unmap(ps); } @@ -686,8 +682,7 @@ ycbcr_get_tile_rgba(ushort *src, void -pipe_get_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_rgba(struct pipe_surface *ps, uint x, uint y, uint w, uint h, float *p) { @@ -702,7 +697,7 @@ pipe_get_tile_rgba(struct pipe_context *pipe, if (!packed) return; - pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, 0); + pipe_get_tile_raw(ps, x, y, w, h, packed, 0); switch (ps->format) { case PIPE_FORMAT_A8R8G8B8_UNORM: @@ -768,8 +763,7 @@ pipe_get_tile_rgba(struct pipe_context *pipe, void -pipe_put_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_rgba(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const float *p) { @@ -838,7 +832,7 @@ pipe_put_tile_rgba(struct pipe_context *pipe, assert(0); } - pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, 0); + pipe_put_tile_raw(ps, x, y, w, h, packed, 0); FREE(packed); } @@ -848,12 +842,10 @@ pipe_put_tile_rgba(struct pipe_context *pipe, * Get a block of Z values, converted to 32-bit range. */ void -pipe_get_tile_z(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_z(struct pipe_surface *ps, uint x, uint y, uint w, uint h, uint *z) { - struct pipe_screen *screen = pipe->screen; const uint dstStride = w; ubyte *map; uint *pDest = z; @@ -862,7 +854,7 @@ pipe_get_tile_z(struct pipe_context *pipe, if (pipe_clip_tile(x, y, &w, &h, ps)) return; - map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ); if (!map) { assert(0); return; @@ -913,17 +905,15 @@ pipe_get_tile_z(struct pipe_context *pipe, assert(0); } - screen->surface_unmap(screen, ps); + pipe_surface_unmap(ps); } void -pipe_put_tile_z(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_z(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const uint *zSrc) { - struct pipe_screen *screen = pipe->screen; const uint srcStride = w; const uint *pSrc = zSrc; ubyte *map; @@ -932,7 +922,7 @@ pipe_put_tile_z(struct pipe_context *pipe, if (pipe_clip_tile(x, y, &w, &h, ps)) return; - map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE); if (!map) { assert(0); return; @@ -980,7 +970,7 @@ pipe_put_tile_z(struct pipe_context *pipe, assert(0); } - screen->surface_unmap(screen, ps); + pipe_surface_unmap(ps); } diff --git a/src/gallium/auxiliary/util/p_tile.h b/src/gallium/auxiliary/util/p_tile.h index fdc80a13b3..adfec8bcee 100644 --- a/src/gallium/auxiliary/util/p_tile.h +++ b/src/gallium/auxiliary/util/p_tile.h @@ -30,7 +30,6 @@ #include "pipe/p_compiler.h" -struct pipe_context; struct pipe_surface; @@ -57,40 +56,34 @@ extern "C" { #endif void -pipe_get_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_raw(struct pipe_surface *ps, uint x, uint y, uint w, uint h, void *p, int dst_stride); void -pipe_put_tile_raw(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_raw(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const void *p, int src_stride); void -pipe_get_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_rgba(struct pipe_surface *ps, uint x, uint y, uint w, uint h, float *p); void -pipe_put_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_rgba(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const float *p); void -pipe_get_tile_z(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_get_tile_z(struct pipe_surface *ps, uint x, uint y, uint w, uint h, uint *z); void -pipe_put_tile_z(struct pipe_context *pipe, - struct pipe_surface *ps, +pipe_put_tile_z(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const uint *z); diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 2d5d2b50f5..bfdaaa6b8f 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -339,7 +339,7 @@ sp_tile_cache_flush_clear(struct pipe_context *pipe, for (y = 0; y < h; y += TILE_SIZE) { for (x = 0; x < w; x += TILE_SIZE) { if (is_clear_flag_set(tc->clear_flags, x, y)) { - pipe_put_tile_raw(pipe, ps, + pipe_put_tile_raw(ps, x, y, TILE_SIZE, TILE_SIZE, tc->tile.data.color32, 0/*STRIDE*/); @@ -374,12 +374,12 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, struct softpipe_cached_tile *tile = tc->entries + pos; if (tile->x >= 0) { if (tc->depth_stencil) { - pipe_put_tile_raw(pipe, ps, + pipe_put_tile_raw(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { - pipe_put_tile_rgba(pipe, ps, + pipe_put_tile_rgba(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } @@ -431,12 +431,12 @@ sp_get_cached_tile(struct softpipe_context *softpipe, if (tile->x != -1) { /* put dirty tile back in framebuffer */ if (tc->depth_stencil) { - pipe_put_tile_raw(pipe, ps, + pipe_put_tile_raw(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { - pipe_put_tile_rgba(pipe, ps, + pipe_put_tile_rgba(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } @@ -458,12 +458,12 @@ sp_get_cached_tile(struct softpipe_context *softpipe, else { /* get new tile data from surface */ if (tc->depth_stencil) { - pipe_get_tile_raw(pipe, ps, + pipe_get_tile_raw(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { - pipe_get_tile_rgba(pipe, ps, + pipe_get_tile_rgba(ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } @@ -544,7 +544,7 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, } /* get tile from the surface (view into texture) */ - pipe_get_tile_rgba(pipe, tc->tex_surf, + pipe_get_tile_rgba(tc->tex_surf, tile_x, tile_y, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); tile->x = tile_x; -- cgit v1.2.3 From 6410e94b966148dde81b5121e53a250d7b530d91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 13 Jul 2008 23:36:59 +0900 Subject: python: New state tracker which exposes the pipe driver to python scripts. Still under development. Just barely works. --- src/gallium/SConscript | 2 + src/gallium/state_trackers/python/README | 32 ++ src/gallium/state_trackers/python/SConscript | 24 ++ src/gallium/state_trackers/python/gallium.i | 448 +++++++++++++++++++++ src/gallium/state_trackers/python/p_format.i | 152 +++++++ .../state_trackers/python/samples/simple.py | 158 ++++++++ src/gallium/state_trackers/python/st_device.c | 169 ++++++++ src/gallium/state_trackers/python/st_device.h | 83 ++++ .../state_trackers/python/st_softpipe_winsys.c | 321 +++++++++++++++ src/gallium/state_trackers/python/st_winsys.h | 58 +++ 10 files changed, 1447 insertions(+) create mode 100644 src/gallium/state_trackers/python/README create mode 100644 src/gallium/state_trackers/python/SConscript create mode 100644 src/gallium/state_trackers/python/gallium.i create mode 100644 src/gallium/state_trackers/python/p_format.i create mode 100644 src/gallium/state_trackers/python/samples/simple.py create mode 100644 src/gallium/state_trackers/python/st_device.c create mode 100644 src/gallium/state_trackers/python/st_device.h create mode 100644 src/gallium/state_trackers/python/st_softpipe_winsys.c create mode 100644 src/gallium/state_trackers/python/st_winsys.h (limited to 'src/gallium') diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 2653f91bd2..6a3e7e77ed 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -25,3 +25,5 @@ SConscript([ for driver in env['drivers']: SConscript(os.path.join('drivers', driver, 'SConscript')) + +SConscript('state_trackers/python/SConscript') diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README new file mode 100644 index 0000000000..75341aa28c --- /dev/null +++ b/src/gallium/state_trackers/python/README @@ -0,0 +1,32 @@ +This directory contains Python bindings to Gallium3D. It looks like a state +tracker from the pipe driver perspective, and it looks like a pipe driver from +the python script perspective. + + +To build you'll need: +* Python (with development packages) +* SCons +* SWIG +* Python Imaging Library (for the samples) + +Invoke scons on the top dir as + + scons statetrackers=python + +To use do + + export PYTHONPATH=build/XXXX-XXXX-XXXX/gallium/state_trackers/python + +and then try running + + python src/gallium/state_trackers/python/samples/simple.py + +which should create a simple.png + + +This is still in experimental phase, and there many limitations to what you can +do with from Python. + + +-- +Jose Fonseca diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript new file mode 100644 index 0000000000..57a3fb2075 --- /dev/null +++ b/src/gallium/state_trackers/python/SConscript @@ -0,0 +1,24 @@ +Import('*') + +if 'python' in env['statetrackers']: + + env = env.Clone() + + env.Append(CPPPATH = '.') + + env.Tool('swig') + env.Append(SWIGPATH = ['#src/gallium/include', '#src/gallium/include/pipe']) + env.Append(SWIGFLAGS = ['-python', '-keyword']) + + env.ParseConfig('python-config --cflags --ldflags --libs') + + env.SharedLibrary( + target = '_gallium', + source = [ + 'gallium.i', + 'st_device.c', + 'st_softpipe_winsys.c', + ], + SHLIBPREFIX = '', + LIBS = softpipe + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i new file mode 100644 index 0000000000..d6594f3a87 --- /dev/null +++ b/src/gallium/state_trackers/python/gallium.i @@ -0,0 +1,448 @@ + /************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca + */ + +%module gallium; + +%{ + +#include +#include + +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "util/u_draw_quad.h" +#include "util/p_tile.h" +#include "cso_cache/cso_context.h" + +#include "st_device.h" + +%} + +%include "carrays.i" +%array_class(int, IntArray); +%array_class(float, FloatArray); + + +%rename(Device) st_device; +%rename(Context) st_context; +%rename(Texture) pipe_texture; +%rename(Surface) pipe_surface; + +%rename(Buffer) pipe_buffer; +%rename(BlendColor) pipe_blend_color; +%rename(Blend) pipe_blend_state; +%rename(Clip) pipe_clip_state; +%rename(ConstantBuffer) pipe_constant_buffer; +%rename(DepthStencilAlpha) pipe_depth_stencil_alpha_state; +%rename(FormatBlock) pipe_format_block; +%rename(Framebuffer) pipe_framebuffer_state; +%rename(PolyStipple) pipe_poly_stipple; +%rename(Rasterizer) pipe_rasterizer_state; +%rename(Sampler) pipe_sampler_state; +%rename(Scissor) pipe_scissor_state; +%rename(Shader) pipe_shader_state; +%rename(VertexBuffer) pipe_vertex_buffer; +%rename(VertexElement) pipe_vertex_element; +%rename(Viewport) pipe_viewport_state; + +%include "p_format.i"; +%include "pipe/p_defines.h"; +%include "pipe/p_state.h"; +%include "pipe/p_shader_tokens.h"; + + +%nodefaultctor; +%nodefaultdtor; + +struct st_device { +}; + +struct st_context { +}; + + +%extend st_device { + + st_device(int hardware = 0) { + return st_device_create(hardware ? TRUE : FALSE); + } + + ~st_device() { + st_device_destroy($self); + } + + const char * get_name( void ) { + return $self->screen->get_name($self->screen); + } + + const char * get_vendor( void ) { + return $self->screen->get_vendor($self->screen); + } + + /** + * Query an integer-valued capability/parameter/limit + * \param param one of PIPE_CAP_x + */ + int get_param( int param ) { + return $self->screen->get_param($self->screen, param); + } + + /** + * Query a float-valued capability/parameter/limit + * \param param one of PIPE_CAP_x + */ + float get_paramf( int param ) { + return $self->screen->get_paramf($self->screen, param); + } + + /** + * Check if the given pipe_format is supported as a texture or + * drawing surface. + * \param type one of PIPE_TEXTURE, PIPE_SURFACE + */ + int is_format_supported( enum pipe_format format, unsigned type ) { + return $self->screen->is_format_supported( $self->screen, format, type); + } + + struct st_context * + context_create(void) { + return st_context_create($self); + } + + struct pipe_texture * + texture_create( + enum pipe_format format, + unsigned width, + unsigned height, + unsigned depth = 1, + unsigned last_level = 0, + enum pipe_texture_target target = PIPE_TEXTURE_2D, + unsigned usage = 0 + ) { + struct pipe_texture templat; + memset(&templat, 0, sizeof(templat)); + templat.format = format; + pf_get_block(templat.format, &templat.block); + templat.width[0] = width; + templat.height[0] = height; + templat.depth[0] = depth; + templat.last_level = last_level; + templat.target = target; + templat.tex_usage = usage; + return $self->screen->texture_create($self->screen, &templat); + } + + struct pipe_buffer * + buffer_create(unsigned size, unsigned alignment = 0, unsigned usage = 0) { + return $self->screen->winsys->buffer_create($self->screen->winsys, alignment, usage, size); + } + +}; + + +%extend st_context { + + ~st_context() { + st_context_destroy($self); + } + + /* + * State functions (create/bind/destroy state objects) + */ + + void set_blend( const struct pipe_blend_state *state ) { + cso_set_blend($self->cso, state); + } + + void set_sampler( unsigned index, const struct pipe_sampler_state *state ) { + cso_single_sampler($self->cso, index, state); + cso_single_sampler_done($self->cso); + } + + void set_rasterizer( const struct pipe_rasterizer_state *state ) { + cso_set_rasterizer($self->cso, state); + } + + void set_depth_stencil_alpha(const struct pipe_depth_stencil_alpha_state *state) { + cso_set_depth_stencil_alpha($self->cso, state); + } + + + void * create_fs( const struct pipe_shader_state *state ) { + return $self->pipe->create_fs_state($self->pipe, state); + } + + void bind_fs( void *state_obj ) { + $self->pipe->bind_fs_state($self->pipe, state_obj); + } + + void delete_fs( void *state_obj ) { + $self->pipe->delete_fs_state($self->pipe, state_obj); + } + + void * create_vs( const struct pipe_shader_state *state ) { + return $self->pipe->create_vs_state($self->pipe, state); + } + + void bind_vs( void *state_obj ) { + $self->pipe->bind_vs_state($self->pipe, state_obj); + } + + void delete_vs( void *state_obj ) { + $self->pipe->delete_vs_state($self->pipe, state_obj); + } + + /* + * Parameter-like state (or properties) + */ + + void set_blend_color(const struct pipe_blend_color *state ) { + cso_set_blend_color($self->cso, state); + } + + void set_clip(const struct pipe_clip_state *state ) { + $self->pipe->set_clip_state($self->pipe, state); + } + + void set_constant_buffer(unsigned shader, unsigned index, + const struct pipe_constant_buffer *buf ) { + $self->pipe->set_constant_buffer($self->pipe, shader, index, buf); + } + + void set_framebuffer(const struct pipe_framebuffer_state *state ) { + cso_set_framebuffer($self->cso, state); + } + + void set_polygon_stipple(const struct pipe_poly_stipple *state ) { + $self->pipe->set_polygon_stipple($self->pipe, state); + } + + void set_scissor(const struct pipe_scissor_state *state ) { + $self->pipe->set_scissor_state($self->pipe, state); + } + + void set_viewport(const struct pipe_viewport_state *state) { + cso_set_viewport($self->cso, state); + } + + void set_sampler_texture(unsigned index, + struct pipe_texture *texture) { + pipe_texture_reference(&$self->sampler_textures[index], texture); + $self->pipe->set_sampler_textures($self->pipe, + PIPE_MAX_SAMPLERS, + $self->sampler_textures); + } + + void set_vertex_buffer(unsigned index, + const struct pipe_vertex_buffer *buffer) { + memcpy(&$self->vertex_buffers[index], buffer, sizeof(*buffer)); + $self->pipe->set_vertex_buffers($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_buffers); + } + + void set_vertex_element(unsigned index, + const struct pipe_vertex_element *element) { + memcpy(&$self->vertex_elements[index], element, sizeof(*element)); + $self->pipe->set_vertex_elements($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_elements); + } + + /* + * Draw functions + */ + + void draw_arrays(unsigned mode, unsigned start, unsigned count) { + $self->pipe->draw_arrays($self->pipe, mode, start, count); + } + + void draw_elements( struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) { + $self->pipe->draw_elements($self->pipe, indexBuffer, indexSize, mode, start, count); + } + + void draw_vertices(unsigned prim, + unsigned num_verts, + unsigned num_attribs, + const float *vertices) + { + struct pipe_context *pipe = $self->pipe; + struct pipe_winsys *winsys = pipe->winsys; + struct pipe_buffer *vbuf; + float *map; + unsigned size; + + size = num_verts * num_attribs * 4 * sizeof(float); + + vbuf = winsys->buffer_create(winsys, + 32, + PIPE_BUFFER_USAGE_VERTEX, + size); + if(!vbuf) + goto error1; + + map = winsys->buffer_map(winsys, vbuf, PIPE_BUFFER_USAGE_CPU_WRITE); + if (!map) + goto error2; + memcpy(map, vertices, size); + pipe->winsys->buffer_unmap(pipe->winsys, vbuf); + + util_draw_vertex_buffer(pipe, vbuf, prim, num_verts, num_attribs); + +error2: + pipe_buffer_reference(pipe->winsys, &vbuf, NULL); +error1: + ; + } + + void draw_quad(float x0, float y0, float x1, float y1, float z = 0.0f) { + util_draw_texquad($self->pipe, x0, y0, x1, y1, z); + } + + void + flush(void) { + struct pipe_fence_handle *fence = NULL; + $self->pipe->flush($self->pipe, PIPE_FLUSH_RENDER_CACHE, &fence); + /* TODO: allow asynchronous operation */ + $self->pipe->winsys->fence_finish( $self->pipe->winsys, fence, 0 ); + $self->pipe->winsys->fence_reference( $self->pipe->winsys, &fence, NULL ); + } + + /* + * Surface functions + */ + + void surface_copy(int do_flip, + struct pipe_surface *dest, + unsigned destx, unsigned desty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) { + $self->pipe->surface_copy($self->pipe, do_flip, dest, destx, desty, src, srcx, srcy, width, height); + } + + void surface_fill(struct pipe_surface *dst, + unsigned x, unsigned y, + unsigned width, unsigned height, + unsigned value) { + $self->pipe->surface_fill($self->pipe, dst, x, y, width, height, value); + } + + void clear(struct pipe_surface *surface, unsigned value) { + $self->pipe->clear($self->pipe, surface, value); + } + +}; + + +%extend pipe_texture { + + ~pipe_texture() { + struct pipe_texture *ptr = $self; + pipe_texture_reference(&ptr, NULL); + } + + /** Get a surface which is a "view" into a texture */ + struct pipe_surface * + get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0, unsigned usage=0 ) + { + struct pipe_screen *screen = $self->screen; + return screen->get_tex_surface(screen, $self, face, level, zslice, usage); + } + +}; + + +%extend pipe_surface { + + ~pipe_surface() { + struct pipe_surface *ptr = $self; + pipe_surface_reference(&ptr, NULL); + } + + // gets mapped to pipe_surface_map automatically + void * map( unsigned flags ); + + // gets mapped to pipe_surface_unmap automatically + void unmap( void ); + + void + get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *p) { + pipe_get_tile_rgba($self, x, y, w, h, p); + } + + void + put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *p) { + pipe_put_tile_rgba($self, x, y, w, h, p); + } + + void + get_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z) { + pipe_get_tile_z($self, x, y, w, h, z); + } + + void + put_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z) { + pipe_put_tile_z($self, x, y, w, h, z); + } + +}; + + +%extend pipe_framebuffer_state { + + pipe_framebuffer_state(void) { + return CALLOC_STRUCT(pipe_framebuffer_state); + } + + ~pipe_framebuffer_state() { + unsigned index; + for(index = 0; index < PIPE_MAX_COLOR_BUFS; ++index) + pipe_surface_reference(&$self->cbufs[index], NULL); + pipe_surface_reference(&$self->zsbuf, NULL); + FREE($self); + } + + void + set_cbuf(unsigned index, struct pipe_surface *surface) { + pipe_surface_reference(&$self->cbufs[index], surface); + } + + void + set_zsbuf(struct pipe_surface *surface) { + pipe_surface_reference(&$self->zsbuf, surface); + } + +}; diff --git a/src/gallium/state_trackers/python/p_format.i b/src/gallium/state_trackers/python/p_format.i new file mode 100644 index 0000000000..51ad4bebcd --- /dev/null +++ b/src/gallium/state_trackers/python/p_format.i @@ -0,0 +1,152 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* + * XXX: SWIG can't parse p_format.h, so we need to duplicate the relevant + * declarations here + */ + +%{ +#include "pipe/p_format.h" +%} + +enum pipe_format { + PIPE_FORMAT_NONE, + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_X8R8G8B8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_B8G8R8X8_UNORM, + PIPE_FORMAT_A1R5G5B5_UNORM, + PIPE_FORMAT_A4R4G4B4_UNORM, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_A2B10G10R10_UNORM, + PIPE_FORMAT_L8_UNORM, + PIPE_FORMAT_A8_UNORM, + PIPE_FORMAT_I8_UNORM, + PIPE_FORMAT_A8L8_UNORM, + PIPE_FORMAT_L16_UNORM, + PIPE_FORMAT_YCBCR, + PIPE_FORMAT_YCBCR_REV, + PIPE_FORMAT_Z16_UNORM, + PIPE_FORMAT_Z32_UNORM, + PIPE_FORMAT_Z32_FLOAT, + PIPE_FORMAT_S8Z24_UNORM, + PIPE_FORMAT_Z24S8_UNORM, + PIPE_FORMAT_X8Z24_UNORM, + PIPE_FORMAT_Z24X8_UNORM, + PIPE_FORMAT_S8_UNORM, + PIPE_FORMAT_R64_FLOAT, + PIPE_FORMAT_R64G64_FLOAT, + PIPE_FORMAT_R64G64B64_FLOAT, + PIPE_FORMAT_R64G64B64A64_FLOAT, + PIPE_FORMAT_R32_FLOAT, + PIPE_FORMAT_R32G32_FLOAT, + PIPE_FORMAT_R32G32B32_FLOAT, + PIPE_FORMAT_R32G32B32A32_FLOAT, + PIPE_FORMAT_R32_UNORM, + PIPE_FORMAT_R32G32_UNORM, + PIPE_FORMAT_R32G32B32_UNORM, + PIPE_FORMAT_R32G32B32A32_UNORM, + PIPE_FORMAT_R32_USCALED, + PIPE_FORMAT_R32G32_USCALED, + PIPE_FORMAT_R32G32B32_USCALED, + PIPE_FORMAT_R32G32B32A32_USCALED, + PIPE_FORMAT_R32_SNORM, + PIPE_FORMAT_R32G32_SNORM, + PIPE_FORMAT_R32G32B32_SNORM, + PIPE_FORMAT_R32G32B32A32_SNORM, + PIPE_FORMAT_R32_SSCALED, + PIPE_FORMAT_R32G32_SSCALED, + PIPE_FORMAT_R32G32B32_SSCALED, + PIPE_FORMAT_R32G32B32A32_SSCALED, + PIPE_FORMAT_R16_UNORM, + PIPE_FORMAT_R16G16_UNORM, + PIPE_FORMAT_R16G16B16_UNORM, + PIPE_FORMAT_R16G16B16A16_UNORM, + PIPE_FORMAT_R16_USCALED, + PIPE_FORMAT_R16G16_USCALED, + PIPE_FORMAT_R16G16B16_USCALED, + PIPE_FORMAT_R16G16B16A16_USCALED, + PIPE_FORMAT_R16_SNORM, + PIPE_FORMAT_R16G16_SNORM, + PIPE_FORMAT_R16G16B16_SNORM, + PIPE_FORMAT_R16G16B16A16_SNORM, + PIPE_FORMAT_R16_SSCALED, + PIPE_FORMAT_R16G16_SSCALED, + PIPE_FORMAT_R16G16B16_SSCALED, + PIPE_FORMAT_R16G16B16A16_SSCALED, + PIPE_FORMAT_R8_UNORM, + PIPE_FORMAT_R8G8_UNORM, + PIPE_FORMAT_R8G8B8_UNORM, + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_R8G8B8X8_UNORM, + PIPE_FORMAT_R8_USCALED, + PIPE_FORMAT_R8G8_USCALED, + PIPE_FORMAT_R8G8B8_USCALED, + PIPE_FORMAT_R8G8B8A8_USCALED, + PIPE_FORMAT_R8G8B8X8_USCALED, + PIPE_FORMAT_R8_SNORM, + PIPE_FORMAT_R8G8_SNORM, + PIPE_FORMAT_R8G8B8_SNORM, + PIPE_FORMAT_R8G8B8A8_SNORM, + PIPE_FORMAT_R8G8B8X8_SNORM, + PIPE_FORMAT_B6G5R5_SNORM, + PIPE_FORMAT_A8B8G8R8_SNORM, + PIPE_FORMAT_X8B8G8R8_SNORM, + PIPE_FORMAT_R8_SSCALED, + PIPE_FORMAT_R8G8_SSCALED, + PIPE_FORMAT_R8G8B8_SSCALED, + PIPE_FORMAT_R8G8B8A8_SSCALED, + PIPE_FORMAT_R8G8B8X8_SSCALED, + PIPE_FORMAT_R32_FIXED, + PIPE_FORMAT_R32G32_FIXED, + PIPE_FORMAT_R32G32B32_FIXED, + PIPE_FORMAT_R32G32B32A32_FIXED, + + PIPE_FORMAT_L8_SRGB, + PIPE_FORMAT_A8_L8_SRGB, + PIPE_FORMAT_R8G8B8_SRGB, + PIPE_FORMAT_R8G8B8A8_SRGB, + PIPE_FORMAT_R8G8B8X8_SRGB, + + PIPE_FORMAT_X8UB8UG8SR8S_NORM, + PIPE_FORMAT_B6UG5SR5S_NORM, + + PIPE_FORMAT_DXT1_RGB, + PIPE_FORMAT_DXT1_RGBA, + PIPE_FORMAT_DXT3_RGBA, + PIPE_FORMAT_DXT5_RGBA, +}; + + +struct pipe_format_block +{ + unsigned size; + unsigned width; + unsigned height; +}; + diff --git a/src/gallium/state_trackers/python/samples/simple.py b/src/gallium/state_trackers/python/samples/simple.py new file mode 100644 index 0000000000..77e182b644 --- /dev/null +++ b/src/gallium/state_trackers/python/samples/simple.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +########################################################################## + + +from gallium import * + + +def save_image(filename, surface): + pixels = FloatArray(surface.height*surface.width*4) + surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) + + import Image + outimage = Image.new( + mode='RGB', + size=(surface.width, surface.height), + color=(0,0,0)) + outpixels = outimage.load() + for y in range(0, surface.height): + for x in range(0, surface.width): + offset = (y*surface.width + x)*4 + r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] + outpixels[x, y] = r, g, b + outimage.save(filename, "PNG") + + +def test(dev): + ctx = dev.context_create() + + width = 256 + height = 256 + + # disabled blending/masking + blend = Blend() + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.colormask = PIPE_MASK_RGBA + ctx.set_blend(blend) + + # no-op depth/stencil/alpha + depth_stencil_alpha = DepthStencilAlpha() + ctx.set_depth_stencil_alpha(depth_stencil_alpha) + + # rasterizer + rasterizer = Rasterizer() + rasterizer.front_winding = PIPE_WINDING_CW + rasterizer.cull_mode = PIPE_WINDING_NONE + rasterizer.bypass_clipping = 1 + #rasterizer.bypass_vs = 1 + ctx.set_rasterizer(rasterizer) + + # viewport (identity, we setup vertices in wincoords) + viewport = Viewport() + scale = FloatArray(4) + scale[0] = 1.0 + scale[1] = 1.0 + scale[2] = 1.0 + scale[3] = 1.0 + viewport.scale = scale + translate = FloatArray(4) + translate[0] = 0.0 + translate[1] = 0.0 + translate[2] = 0.0 + translate[3] = 0.0 + viewport.translate = translate + ctx.set_viewport(viewport) + + # samplers + sampler = Sampler() + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE + sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.normalized_coords = 1 + ctx.set_sampler(0, sampler) + + # texture + texture = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, width, height, usage=PIPE_TEXTURE_USAGE_RENDER_TARGET) + ctx.set_sampler_texture(0, texture) + + # drawing dest + surface = texture.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE) + fb = Framebuffer() + fb.width = surface.width + fb.height = surface.height + fb.num_cbufs = 1 + fb.set_cbuf(0, surface) + ctx.set_framebuffer(fb) + + # vertex shader + # vs = Shader() + #ctx.set_vertex_shader(vs) + + # fragment shader + #fs = Shader() + #ctx.set_fragment_shader(fs) + + if 0: + nverts = 4 + nattrs = 1 + vertices = FloatArray(n_verts * nattrs * 4) + + # init vertex data that doesn't change + for i in range(nverts): + for j in range(nattrs): + vertices[(i*nattrs +j)*4 + 0] = 0.0 + vertices[(i*nattrs +j)*4 + 1] = 0.0 + vertices[(i*nattrs +j)*4 + 2] = 0.0 + vertices[(i*nattrs +j)*4 + 3] = 0.0 + + ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN, + 4, # verts + 2, # attribs/vert + vertices) + else: + ctx.draw_quad(32.0, 32.0, 224.0, 224.0) + + ctx.flush() + + save_image("simple.png", surface) + + + +def main(): + dev = Device(0) + test(dev) + + +if __name__ == '__main__': + main() diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c new file mode 100644 index 0000000000..430a7af176 --- /dev/null +++ b/src/gallium/state_trackers/python/st_device.c @@ -0,0 +1,169 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_inlines.h" +#include "cso_cache/cso_context.h" +#include "util/u_simple_shaders.h" +#include "st_device.h" +#include "st_winsys.h" + + +static void +st_device_really_destroy(struct st_device *st_dev) +{ + if(st_dev->screen) + st_dev->st_ws->screen_destroy(st_dev->screen); + + FREE(st_dev); +} + + +void +st_device_destroy(struct st_device *st_dev) +{ + if(!--st_dev->refcount) + st_device_really_destroy(st_dev); +} + + +static struct st_device * +st_device_create_from_st_winsys(const struct st_winsys *st_ws) +{ + struct st_device *st_dev; + + if(!st_ws->screen_create || + !st_ws->screen_destroy || + !st_ws->context_create || + !st_ws->context_destroy) + return NULL; + + st_dev = CALLOC_STRUCT(st_device); + if(!st_dev) + return NULL; + + st_dev->st_ws = st_ws; + + st_dev->screen = st_ws->screen_create(); + if(!st_dev->screen) + st_device_destroy(st_dev); + + return st_dev; +} + + +struct st_device * +st_device_create(boolean hardware) { +#if 0 + if(hardware) + return st_device_create_from_st_winsys(&st_hardware_winsys); + else +#endif + return st_device_create_from_st_winsys(&st_software_winsys); +} + + +void +st_context_destroy(struct st_context *st_ctx) +{ + unsigned i; + + if(st_ctx) { + struct st_device *st_dev = st_ctx->st_dev; + + if(st_ctx->vs) { + st_ctx->pipe->bind_vs_state(st_ctx->pipe, NULL); + st_ctx->pipe->delete_vs_state(st_ctx->pipe, st_ctx->vs); + } + + if(st_ctx->fs) { + st_ctx->pipe->bind_fs_state(st_ctx->pipe, NULL); + st_ctx->pipe->delete_fs_state(st_ctx->pipe, st_ctx->fs); + } + + if(st_ctx->cso) + cso_destroy_context(st_ctx->cso); + + if(st_ctx->pipe) + st_ctx->st_dev->st_ws->context_destroy(st_ctx->pipe); + + for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) + pipe_texture_reference(&st_ctx->sampler_textures[i], NULL); + + FREE(st_ctx); + + if(!--st_dev->refcount) + st_device_really_destroy(st_dev); + } +} + + +struct st_context * +st_context_create(struct st_device *st_dev) +{ + struct st_context *st_ctx; + + st_ctx = CALLOC_STRUCT(st_context); + if(!st_ctx) + return NULL; + + st_ctx->st_dev = st_dev; + ++st_dev->refcount; + + st_ctx->pipe = st_dev->st_ws->context_create(st_dev->screen); + if(!st_ctx->pipe) + st_context_destroy(st_ctx); + + st_ctx->cso = cso_create_context(st_ctx->pipe); + if(!st_ctx->cso) + st_context_destroy(st_ctx); + + /* vertex shader */ + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + st_ctx->vs = util_make_vertex_passthrough_shader(st_ctx->pipe, + 2, + semantic_names, + semantic_indexes, + &st_ctx->vert_shader); + } + + /* fragment shader */ + st_ctx->fs = util_make_fragment_passthrough_shader(st_ctx->pipe, + &st_ctx->frag_shader); + + st_ctx->pipe->bind_fs_state(st_ctx->pipe, st_ctx->fs); + st_ctx->pipe->bind_vs_state(st_ctx->pipe, st_ctx->vs); + + return st_ctx; +} diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h new file mode 100644 index 0000000000..46db20acd7 --- /dev/null +++ b/src/gallium/state_trackers/python/st_device.h @@ -0,0 +1,83 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef ST_DEVICE_H_ +#define ST_DEVICE_H_ + + +#include "pipe/p_state.h" + +struct cso_context; +struct pipe_screen; +struct pipe_context; +struct st_winsys; + + +struct st_context { + struct st_device *st_dev; + + struct pipe_context *pipe; + + struct cso_context *cso; + + struct pipe_shader_state vert_shader; + struct pipe_shader_state frag_shader; + + void *vs; + void *fs; + + struct pipe_texture *sampler_textures[PIPE_MAX_SAMPLERS]; + struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS]; +}; + + +struct st_device { + const struct st_winsys *st_ws; + + struct pipe_screen *screen; + + /* FIXME: we also need to refcount for textures and surfaces... */ + unsigned refcount; +}; + + +struct st_context * +st_context_create(struct st_device *st_dev); + +void +st_context_destroy(struct st_context *st_ctx); + +struct st_device * +st_device_create(boolean hardware); + +void +st_device_destroy(struct st_device *st_dev); + + +#endif /* ST_DEVICE_H_ */ diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c new file mode 100644 index 0000000000..964d60de1d --- /dev/null +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -0,0 +1,321 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * @file + * Softpipe support. + * + * @author Keith Whitwell + * @author Brian Paul + * @author Jose Fonseca + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "softpipe/sp_winsys.h" +#include "st_winsys.h" + + +struct st_softpipe_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + + +/** Cast wrapper */ +static INLINE struct st_softpipe_buffer * +st_softpipe_buffer( struct pipe_buffer *buf ) +{ + return (struct st_softpipe_buffer *)buf; +} + + +static void * +st_softpipe_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = st_softpipe_buf->data; + return st_softpipe_buf->mapped; +} + + +static void +st_softpipe_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = NULL; +} + + +static void +st_softpipe_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf); + + if (oldBuf->data) { + if (!oldBuf->userBuffer) + align_free(oldBuf->data); + + oldBuf->data = NULL; + } + + FREE(oldBuf); +} + + +static void +st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ +} + + + +static const char * +st_softpipe_get_name(struct pipe_winsys *winsys) +{ + return "softpipe"; +} + + +static struct pipe_buffer * +st_softpipe_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer); + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + buffer->data = align_malloc(size, alignment); + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +st_softpipe_user_buffer_create(struct pipe_winsys *winsys, + void *ptr, + unsigned bytes) +{ + struct st_softpipe_buffer *buffer; + + buffer = CALLOC_STRUCT(st_softpipe_buffer); + if(!buffer) + return NULL; + + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + + +static int +st_softpipe_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->stride * surf->nblocksy); + if(!surf->buffer) + return -1; + + return 0; +} + + +static struct pipe_surface * +st_softpipe_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); + + assert(winsys); + + surface->refcount = 1; + surface->winsys = winsys; + + return surface; +} + + +static void +st_softpipe_surface_release(struct pipe_winsys *winsys, + struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + assert(!surf->texture); + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + +static void +st_softpipe_fence_reference(struct pipe_winsys *winsys, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +st_softpipe_fence_signalled(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +st_softpipe_fence_finish(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static void +st_softpipe_screen_destroy(struct pipe_screen *screen) +{ + struct pipe_winsys *winsys = screen->winsys; + + screen->destroy(screen); + + FREE(winsys); +} + + +static struct pipe_screen * +st_softpipe_screen_create(void) +{ + static struct pipe_winsys *winsys; + struct pipe_screen *screen; + + winsys = CALLOC_STRUCT(pipe_winsys); + if(!winsys) + return NULL; + + winsys->buffer_create = st_softpipe_buffer_create; + winsys->user_buffer_create = st_softpipe_user_buffer_create; + winsys->buffer_map = st_softpipe_buffer_map; + winsys->buffer_unmap = st_softpipe_buffer_unmap; + winsys->buffer_destroy = st_softpipe_buffer_destroy; + + winsys->surface_alloc = st_softpipe_surface_alloc; + winsys->surface_alloc_storage = st_softpipe_surface_alloc_storage; + winsys->surface_release = st_softpipe_surface_release; + + winsys->fence_reference = st_softpipe_fence_reference; + winsys->fence_signalled = st_softpipe_fence_signalled; + winsys->fence_finish = st_softpipe_fence_finish; + + winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer; + winsys->get_name = st_softpipe_get_name; + + screen = softpipe_create_screen(winsys); + if(!screen) + FREE(winsys); + + return screen; +} + + +static void +st_softpipe_context_destroy(struct pipe_context *pipe) +{ + pipe->destroy(pipe); +} + + +static struct pipe_context * +st_softpipe_context_create(struct pipe_screen *screen) +{ + return softpipe_create(screen, screen->winsys, NULL); +} + + +const struct st_winsys st_software_winsys = { + &st_softpipe_screen_create, + &st_softpipe_screen_destroy, + &st_softpipe_context_create, + &st_softpipe_context_destroy +}; diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h new file mode 100644 index 0000000000..992fc9ab4b --- /dev/null +++ b/src/gallium/state_trackers/python/st_winsys.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef ST_WINSYS_H_ +#define ST_WINSYS_H_ + + +struct pipe_screen; +struct pipe_context; + + +struct st_winsys +{ + struct pipe_screen * + (*screen_create)(void); + + void + (*screen_destroy)(struct pipe_screen *screen); + + struct pipe_context * + (*context_create)(struct pipe_screen *screen); + + void + (*context_destroy)(struct pipe_context *pipe); +}; + + +extern const struct st_winsys st_software_winsys; + +extern const struct st_winsys st_hardware_winsys; + + +#endif /* ST_WINSYS_H_ */ -- cgit v1.2.3 From 930a863c4f6f11d0fd5cf396ef76054d52c69b9f Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Thu, 10 Jul 2008 20:20:46 +0200 Subject: i915: WIP swap rework --- src/gallium/drivers/i915simple/i915_texture.c | 6 +- src/gallium/winsys/dri/intel/intel_context.h | 6 + src/gallium/winsys/dri/intel/intel_swapbuffers.c | 303 ++++++++++------------- src/gallium/winsys/dri/intel/intel_swapbuffers.h | 4 +- 4 files changed, 147 insertions(+), 172 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index cf4964b26b..8427d8271a 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -79,7 +79,7 @@ static unsigned power_of_two(unsigned x) { unsigned value = 1; - while (value <= x) + while (value < x) value = value << 1; return value; } @@ -205,8 +205,8 @@ i945_miptree_layout_2d( struct i915_texture *tex ) unsigned nblocksx = pt->nblocksx[0]; unsigned nblocksy = pt->nblocksy[0]; -#if 0 /* used for tiled display targets */ - if (pt->last_level == 0 && pt->cpp == 4) +#if 1 /* used for tiled display targets */ + if (pt->last_level == 0 /*&& pt->bpp == 4*/) if (i915_displaytarget_layout(tex)) return; #endif diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h index ced18da143..18b96217ac 100644 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -32,6 +32,7 @@ #include "drm.h" #include "pipe/p_debug.h" +#include "util/u_blit.h" #include "intel_screen.h" #include "i915_drm.h" @@ -82,6 +83,11 @@ struct intel_context * Configuration cache */ driOptionCache optionCache; + + /** + * Blit state for swapbuffers + */ + struct blit_state *blit; }; diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index f751f97524..6e10235e89 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -28,16 +28,13 @@ #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" - +#include "intel_batchbuffer.h" #include "intel_reg.h" -#include "pipe/p_context.h" #include "state_tracker/st_public.h" #include "state_tracker/st_context.h" -#include "state_tracker/st_cb_fbo.h" - #include "intel_drm/ws_dri_bufmgr.h" -#include "intel_batchbuffer.h" + /** * Display a colorbuffer surface in an X window. @@ -49,158 +46,130 @@ */ void intelDisplaySurface(__DRIdrawablePrivate *dPriv, - struct pipe_surface *surf, - const drm_clip_rect_t *rect) + struct pipe_texture *tex, + const drm_clip_rect_t *rect) { - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - struct intel_context *intel = intelScreen->dummyContext; - - DBG(SWAP, "%s\n", __FUNCTION__); - - if (!intel) { - /* XXX this is where some kind of extra/meta context could be useful */ - return; - } - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - intel->last_swap_fence = intel->first_swap_fence; - intel->first_swap_fence = NULL; - - /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets - * should work regardless. - */ - LOCK_HARDWARE(intel); - /* if this drawable isn't currently bound the LOCK_HARDWARE done on the - * current context (which is what intelScreenContext should return) might - * not get a contended lock and thus cliprects not updated (tests/manywin) - */ - if (intel_context(dPriv->driContextPriv) != intel) - DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); - - - if (dPriv && dPriv->numClipRects) { - const int srcWidth = surf->width; - const int srcHeight = surf->height; - const int nbox = dPriv->numClipRects; - const drm_clip_rect_t *pbox = dPriv->pClipRects; - const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; - const int cpp = intelScreen->front.cpp; - const int srcpitch = surf->stride / cpp; - int BR13, CMD; - int i; - - ASSERT(surf->buffer); - ASSERT(surf->cpp == cpp); - - DBG(SWAP, "screen pitch %d src surface pitch %d\n", - pitch, surf->stride); - - if (cpp == 2) { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); - CMD = XY_SRC_COPY_BLT_CMD; - } - else { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - } - - for (i = 0; i < nbox; i++, pbox++) { - drm_clip_rect_t box; - drm_clip_rect_t sbox; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->front.width || - pbox->y2 > intelScreen->front.height) { - /* invalid cliprect, skip it */ - continue; - } - - box = *pbox; - - if (rect) { - /* intersect cliprect with user-provided src rect */ - drm_clip_rect_t rrect; - - rrect.x1 = dPriv->x + rect->x1; - rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; - rrect.x2 = rect->x2 + rrect.x1; - rrect.y2 = rect->y2 + rrect.y1; - if (rrect.x1 > box.x1) - box.x1 = rrect.x1; - if (rrect.y1 > box.y1) - box.y1 = rrect.y1; - if (rrect.x2 < box.x2) - box.x2 = rrect.x2; - if (rrect.y2 < box.y2) - box.y2 = rrect.y2; - - if (box.x1 > box.x2 || box.y1 > box.y2) - continue; - } - - /* restrict blit to size of actually rendered area */ - if (box.x2 - box.x1 > srcWidth) - box.x2 = srcWidth + box.x1; - if (box.y2 - box.y1 > srcHeight) - box.y2 = srcHeight + box.y1; - - DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", - box.x1, box.x2, box.y1, box.y2); - - sbox.x1 = box.x1 - dPriv->x; - sbox.y1 = box.y1 - dPriv->y; - - assert(box.x1 < box.x2); - assert(box.y1 < box.y2); - - /* XXX this could be done with pipe->surface_copy() */ - /* XXX should have its own batch buffer */ - if (!BEGIN_BATCH(8, 2)) { - /* - * Since we share this batch buffer with a context - * we can't flush it since that risks a GPU lockup - */ - assert(0); - continue; - } - - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((box.y1 << 16) | box.x1); - OUT_BATCH((box.y2 << 16) | box.x2); - - OUT_RELOC(intelScreen->front.buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); - OUT_BATCH((sbox.y1 << 16) | sbox.x1); - OUT_BATCH((srcpitch * cpp) & 0xffff); - OUT_RELOC(dri_bo(surf->buffer), - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - - } - - if (intel->first_swap_fence) - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); - } - - UNLOCK_HARDWARE(intel); - - if (intel->lastStamp != dPriv->lastStamp) { - intelUpdateWindowSize(dPriv); - intel->lastStamp = dPriv->lastStamp; - } + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + struct intel_context *intel = intelScreen->dummyContext; + + DBG(SWAP, "%s\n", __FUNCTION__); + + if (!intel) { + /* XXX this is where some kind of extra/meta context could be useful */ + return; + } else if (!intel->blit) { + intel->blit = util_create_blit(intel->st->pipe, intel->st->cso_context); + } + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + /* if this drawable isn't currently bound the LOCK_HARDWARE done on the + * current context (which is what intelScreenContext should return) might + * not get a contended lock and thus cliprects not updated (tests/manywin) + */ + if (intel_context(dPriv->driContextPriv) != intel) + DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); + + if (dPriv && dPriv->numClipRects) { + const int srcWidth = tex->width[0]; + const int srcHeight = tex->height[0]; + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + int i; + + assert(surf->buffer); + assert(surf->cpp == cpp); + + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + drm_clip_rect_t sbox; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->front.width || + pbox->y2 > intelScreen->front.height) { + /* invalid cliprect, skip it */ + continue; + } + + box = *pbox; + + if (rect) { + /* intersect cliprect with user-provided src rect */ + drm_clip_rect_t rrect; + + rrect.x1 = dPriv->x + rect->x1; + rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; + rrect.x2 = rect->x2 + rrect.x1; + rrect.y2 = rect->y2 + rrect.y1; + if (rrect.x1 > box.x1) + box.x1 = rrect.x1; + if (rrect.y1 > box.y1) + box.y1 = rrect.y1; + if (rrect.x2 < box.x2) + box.x2 = rrect.x2; + if (rrect.y2 < box.y2) + box.y2 = rrect.y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + /* restrict blit to size of actually rendered area */ + if (box.x2 - box.x1 > srcWidth) + box.x2 = srcWidth + box.x1; + if (box.y2 - box.y1 > srcHeight) + box.y2 = srcHeight + box.y1; + + DBG(SWAP, "\tdbox x1 x2 y1 y2 %d %d %d %d\n", + box.x1, box.x2, box.y1, box.y2); + + sbox.x1 = box.x1 - dPriv->x; + sbox.y1 = box.y1 - dPriv->y; + sbox.x2 = box.x2 - dPriv->x; + sbox.y2 = box.y2 - dPriv->y; + DBG(SWAP, "\tsbox x1 x2 y1 y2 %d %d %d %d\n", + sbox.x1, sbox.x2, sbox.y1, sbox.y2); + + assert(box.x1 < box.x2); + assert(box.y1 < box.y2); + + util_blit_pixels_tex(intel->blit, + tex, + sbox.x1, sbox.y1, + sbox.x2, sbox.y2, + intelScreen->front.surface, + box.x1, box.y1, + box.x2, box.y2, + 0.0, + PIPE_TEX_MIPFILTER_NEAREST); + } + + if (intel->first_swap_fence) + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); + } + + + UNLOCK_HARDWARE(intel); + + if (intel->lastStamp != dPriv->lastStamp) { + intelUpdateWindowSize(dPriv); + intel->lastStamp = dPriv->lastStamp; + } } - - /** * This will be called whenever the currently bound window is moved/resized. */ @@ -212,27 +181,27 @@ intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); } - - +/** + * Called from glx code + */ void intelSwapBuffers(__DRIdrawablePrivate * dPriv) { struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; + struct pipe_texture *back_tex; assert(intel_fb); assert(intel_fb->stfb); - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { + back_tex = st_get_framebuffer_texture(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_tex) { st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, NULL); + intelDisplaySurface(dPriv, back_tex, NULL); st_notify_swapbuffers_complete(intel_fb->stfb); } } - /** * Called via glXCopySubBufferMESA() to copy a subrect of the back * buffer to the front buffer/screen. @@ -241,14 +210,14 @@ void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) { struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; + struct pipe_texture *back_tex; assert(intel_fb); assert(intel_fb->stfb); - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { + back_tex = st_get_framebuffer_texture(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_tex) { drm_clip_rect_t rect; rect.x1 = x; rect.y1 = y; @@ -256,6 +225,6 @@ intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) rect.y2 = h; st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, &rect); + intelDisplaySurface(dPriv, back_tex, &rect); } } diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.h b/src/gallium/winsys/dri/intel/intel_swapbuffers.h index 46c9bab3af..88c479f81d 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.h +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.h @@ -29,11 +29,11 @@ #define INTEL_SWAPBUFFERS_H -struct pipe_surface; +struct pipe_texture; extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, - struct pipe_surface *surf, + struct pipe_texture *surf, const drm_clip_rect_t * rect); extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); -- cgit v1.2.3 From 16c2267d55fb14d0ffcb676540345a14ecc0f323 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Sun, 13 Jul 2008 18:55:38 +0200 Subject: i915: Ops should not have pushed that This reverts commit 930a863c4f6f11d0fd5cf396ef76054d52c69b9f. --- src/gallium/drivers/i915simple/i915_texture.c | 6 +- src/gallium/winsys/dri/intel/intel_context.h | 6 - src/gallium/winsys/dri/intel/intel_swapbuffers.c | 303 +++++++++++++---------- src/gallium/winsys/dri/intel/intel_swapbuffers.h | 4 +- 4 files changed, 172 insertions(+), 147 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 8427d8271a..cf4964b26b 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -79,7 +79,7 @@ static unsigned power_of_two(unsigned x) { unsigned value = 1; - while (value < x) + while (value <= x) value = value << 1; return value; } @@ -205,8 +205,8 @@ i945_miptree_layout_2d( struct i915_texture *tex ) unsigned nblocksx = pt->nblocksx[0]; unsigned nblocksy = pt->nblocksy[0]; -#if 1 /* used for tiled display targets */ - if (pt->last_level == 0 /*&& pt->bpp == 4*/) +#if 0 /* used for tiled display targets */ + if (pt->last_level == 0 && pt->cpp == 4) if (i915_displaytarget_layout(tex)) return; #endif diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h index 18b96217ac..ced18da143 100644 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ b/src/gallium/winsys/dri/intel/intel_context.h @@ -32,7 +32,6 @@ #include "drm.h" #include "pipe/p_debug.h" -#include "util/u_blit.h" #include "intel_screen.h" #include "i915_drm.h" @@ -83,11 +82,6 @@ struct intel_context * Configuration cache */ driOptionCache optionCache; - - /** - * Blit state for swapbuffers - */ - struct blit_state *blit; }; diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c index 6e10235e89..f751f97524 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c @@ -28,13 +28,16 @@ #include "intel_screen.h" #include "intel_context.h" #include "intel_swapbuffers.h" -#include "intel_batchbuffer.h" + #include "intel_reg.h" +#include "pipe/p_context.h" #include "state_tracker/st_public.h" #include "state_tracker/st_context.h" -#include "intel_drm/ws_dri_bufmgr.h" +#include "state_tracker/st_cb_fbo.h" +#include "intel_drm/ws_dri_bufmgr.h" +#include "intel_batchbuffer.h" /** * Display a colorbuffer surface in an X window. @@ -46,130 +49,158 @@ */ void intelDisplaySurface(__DRIdrawablePrivate *dPriv, - struct pipe_texture *tex, - const drm_clip_rect_t *rect) + struct pipe_surface *surf, + const drm_clip_rect_t *rect) { - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - struct intel_context *intel = intelScreen->dummyContext; - - DBG(SWAP, "%s\n", __FUNCTION__); - - if (!intel) { - /* XXX this is where some kind of extra/meta context could be useful */ - return; - } else if (!intel->blit) { - intel->blit = util_create_blit(intel->st->pipe, intel->st->cso_context); - } - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - intel->last_swap_fence = intel->first_swap_fence; - intel->first_swap_fence = NULL; - - /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets - * should work regardless. - */ - LOCK_HARDWARE(intel); - /* if this drawable isn't currently bound the LOCK_HARDWARE done on the - * current context (which is what intelScreenContext should return) might - * not get a contended lock and thus cliprects not updated (tests/manywin) - */ - if (intel_context(dPriv->driContextPriv) != intel) - DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); - - if (dPriv && dPriv->numClipRects) { - const int srcWidth = tex->width[0]; - const int srcHeight = tex->height[0]; - const int nbox = dPriv->numClipRects; - const drm_clip_rect_t *pbox = dPriv->pClipRects; - int i; - - assert(surf->buffer); - assert(surf->cpp == cpp); - - - for (i = 0; i < nbox; i++, pbox++) { - drm_clip_rect_t box; - drm_clip_rect_t sbox; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->front.width || - pbox->y2 > intelScreen->front.height) { - /* invalid cliprect, skip it */ - continue; - } - - box = *pbox; - - if (rect) { - /* intersect cliprect with user-provided src rect */ - drm_clip_rect_t rrect; - - rrect.x1 = dPriv->x + rect->x1; - rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; - rrect.x2 = rect->x2 + rrect.x1; - rrect.y2 = rect->y2 + rrect.y1; - if (rrect.x1 > box.x1) - box.x1 = rrect.x1; - if (rrect.y1 > box.y1) - box.y1 = rrect.y1; - if (rrect.x2 < box.x2) - box.x2 = rrect.x2; - if (rrect.y2 < box.y2) - box.y2 = rrect.y2; - - if (box.x1 > box.x2 || box.y1 > box.y2) - continue; - } - - /* restrict blit to size of actually rendered area */ - if (box.x2 - box.x1 > srcWidth) - box.x2 = srcWidth + box.x1; - if (box.y2 - box.y1 > srcHeight) - box.y2 = srcHeight + box.y1; - - DBG(SWAP, "\tdbox x1 x2 y1 y2 %d %d %d %d\n", - box.x1, box.x2, box.y1, box.y2); - - sbox.x1 = box.x1 - dPriv->x; - sbox.y1 = box.y1 - dPriv->y; - sbox.x2 = box.x2 - dPriv->x; - sbox.y2 = box.y2 - dPriv->y; - DBG(SWAP, "\tsbox x1 x2 y1 y2 %d %d %d %d\n", - sbox.x1, sbox.x2, sbox.y1, sbox.y2); - - assert(box.x1 < box.x2); - assert(box.y1 < box.y2); - - util_blit_pixels_tex(intel->blit, - tex, - sbox.x1, sbox.y1, - sbox.x2, sbox.y2, - intelScreen->front.surface, - box.x1, box.y1, - box.x2, box.y2, - 0.0, - PIPE_TEX_MIPFILTER_NEAREST); - } - - if (intel->first_swap_fence) - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); - } - - - UNLOCK_HARDWARE(intel); - - if (intel->lastStamp != dPriv->lastStamp) { - intelUpdateWindowSize(dPriv); - intel->lastStamp = dPriv->lastStamp; - } + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + struct intel_context *intel = intelScreen->dummyContext; + + DBG(SWAP, "%s\n", __FUNCTION__); + + if (!intel) { + /* XXX this is where some kind of extra/meta context could be useful */ + return; + } + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + /* if this drawable isn't currently bound the LOCK_HARDWARE done on the + * current context (which is what intelScreenContext should return) might + * not get a contended lock and thus cliprects not updated (tests/manywin) + */ + if (intel_context(dPriv->driContextPriv) != intel) + DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); + + + if (dPriv && dPriv->numClipRects) { + const int srcWidth = surf->width; + const int srcHeight = surf->height; + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; + const int cpp = intelScreen->front.cpp; + const int srcpitch = surf->stride / cpp; + int BR13, CMD; + int i; + + ASSERT(surf->buffer); + ASSERT(surf->cpp == cpp); + + DBG(SWAP, "screen pitch %d src surface pitch %d\n", + pitch, surf->stride); + + if (cpp == 2) { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + } + else { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + } + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + drm_clip_rect_t sbox; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->front.width || + pbox->y2 > intelScreen->front.height) { + /* invalid cliprect, skip it */ + continue; + } + + box = *pbox; + + if (rect) { + /* intersect cliprect with user-provided src rect */ + drm_clip_rect_t rrect; + + rrect.x1 = dPriv->x + rect->x1; + rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; + rrect.x2 = rect->x2 + rrect.x1; + rrect.y2 = rect->y2 + rrect.y1; + if (rrect.x1 > box.x1) + box.x1 = rrect.x1; + if (rrect.y1 > box.y1) + box.y1 = rrect.y1; + if (rrect.x2 < box.x2) + box.x2 = rrect.x2; + if (rrect.y2 < box.y2) + box.y2 = rrect.y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + /* restrict blit to size of actually rendered area */ + if (box.x2 - box.x1 > srcWidth) + box.x2 = srcWidth + box.x1; + if (box.y2 - box.y1 > srcHeight) + box.y2 = srcHeight + box.y1; + + DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", + box.x1, box.x2, box.y1, box.y2); + + sbox.x1 = box.x1 - dPriv->x; + sbox.y1 = box.y1 - dPriv->y; + + assert(box.x1 < box.x2); + assert(box.y1 < box.y2); + + /* XXX this could be done with pipe->surface_copy() */ + /* XXX should have its own batch buffer */ + if (!BEGIN_BATCH(8, 2)) { + /* + * Since we share this batch buffer with a context + * we can't flush it since that risks a GPU lockup + */ + assert(0); + continue; + } + + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((box.y1 << 16) | box.x1); + OUT_BATCH((box.y2 << 16) | box.x2); + + OUT_RELOC(intelScreen->front.buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + OUT_BATCH((sbox.y1 << 16) | sbox.x1); + OUT_BATCH((srcpitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + } + + if (intel->first_swap_fence) + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); + } + + UNLOCK_HARDWARE(intel); + + if (intel->lastStamp != dPriv->lastStamp) { + intelUpdateWindowSize(dPriv); + intel->lastStamp = dPriv->lastStamp; + } } + + /** * This will be called whenever the currently bound window is moved/resized. */ @@ -181,27 +212,27 @@ intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); } -/** - * Called from glx code - */ + + void intelSwapBuffers(__DRIdrawablePrivate * dPriv) { struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_texture *back_tex; + struct pipe_surface *back_surf; assert(intel_fb); assert(intel_fb->stfb); - back_tex = st_get_framebuffer_texture(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_tex) { + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_tex, NULL); + intelDisplaySurface(dPriv, back_surf, NULL); st_notify_swapbuffers_complete(intel_fb->stfb); } } + /** * Called via glXCopySubBufferMESA() to copy a subrect of the back * buffer to the front buffer/screen. @@ -210,14 +241,14 @@ void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) { struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_texture *back_tex; + struct pipe_surface *back_surf; assert(intel_fb); assert(intel_fb->stfb); - back_tex = st_get_framebuffer_texture(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_tex) { + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { drm_clip_rect_t rect; rect.x1 = x; rect.y1 = y; @@ -225,6 +256,6 @@ intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) rect.y2 = h; st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_tex, &rect); + intelDisplaySurface(dPriv, back_surf, &rect); } } diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.h b/src/gallium/winsys/dri/intel/intel_swapbuffers.h index 88c479f81d..46c9bab3af 100644 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.h +++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.h @@ -29,11 +29,11 @@ #define INTEL_SWAPBUFFERS_H -struct pipe_texture; +struct pipe_surface; extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, - struct pipe_texture *surf, + struct pipe_surface *surf, const drm_clip_rect_t * rect); extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); -- cgit v1.2.3 From 05a23e6c6f08d4d901dc9fc9995b3444fa6355dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 14 Jul 2008 10:45:40 +0900 Subject: python: Allow to create/specify shaders. --- src/gallium/state_trackers/python/gallium.i | 88 ++++++++++++++++------ .../state_trackers/python/samples/simple.py | 29 +++++-- src/gallium/state_trackers/python/st_device.c | 20 ++--- 3 files changed, 97 insertions(+), 40 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index d6594f3a87..53d160ef6c 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -44,9 +44,11 @@ #include "pipe/p_inlines.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" +#include "cso_cache/cso_context.h" #include "util/u_draw_quad.h" #include "util/p_tile.h" -#include "cso_cache/cso_context.h" +#include "tgsi/util/tgsi_text.h" +#include "tgsi/util/tgsi_dump.h" #include "st_device.h" @@ -201,29 +203,32 @@ struct st_context { cso_set_depth_stencil_alpha($self->cso, state); } - - void * create_fs( const struct pipe_shader_state *state ) { - return $self->pipe->create_fs_state($self->pipe, state); - } - - void bind_fs( void *state_obj ) { - $self->pipe->bind_fs_state($self->pipe, state_obj); - } - - void delete_fs( void *state_obj ) { - $self->pipe->delete_fs_state($self->pipe, state_obj); - } + void set_fragment_shader( const struct pipe_shader_state *state ) { + void *fs; + + fs = $self->pipe->create_fs_state($self->pipe, state); + if(!fs) + return; + + if(cso_set_fragment_shader_handle($self->cso, fs) != PIPE_OK) + return; - void * create_vs( const struct pipe_shader_state *state ) { - return $self->pipe->create_vs_state($self->pipe, state); - } - - void bind_vs( void *state_obj ) { - $self->pipe->bind_vs_state($self->pipe, state_obj); + cso_delete_fragment_shader($self->cso, $self->fs); + $self->fs = fs; } - - void delete_vs( void *state_obj ) { - $self->pipe->delete_vs_state($self->pipe, state_obj); + + void set_vertex_shader( const struct pipe_shader_state *state ) { + void *vs; + + vs = $self->pipe->create_vs_state($self->pipe, state); + if(!vs) + return; + + if(cso_set_vertex_shader_handle($self->cso, vs) != PIPE_OK) + return; + + cso_delete_vertex_shader($self->cso, $self->vs); + $self->vs = vs; } /* @@ -446,3 +451,42 @@ error1: } }; + + +%extend pipe_shader_state { + + pipe_shader_state(const char *text, unsigned num_tokens = 1024) { + struct tgsi_token *tokens; + struct pipe_shader_state *shader; + + tokens = MALLOC(num_tokens * sizeof(struct tgsi_token)); + if(!tokens) + goto error1; + + if(tgsi_text_translate(text, tokens, num_tokens ) != TRUE) + goto error2; + + shader = CALLOC_STRUCT(pipe_shader_state); + if(!shader) + goto error3; + + shader->tokens = tokens; + + return shader; + +error3: +error2: + FREE(tokens); +error1: + return NULL; + } + + ~pipe_shader_state() { + FREE((void*)$self->tokens); + FREE($self); + } + + void dump(unsigned flags = 0) { + tgsi_dump($self->tokens, flags); + } +} \ No newline at end of file diff --git a/src/gallium/state_trackers/python/samples/simple.py b/src/gallium/state_trackers/python/samples/simple.py index 77e182b644..6e90eec28a 100644 --- a/src/gallium/state_trackers/python/samples/simple.py +++ b/src/gallium/state_trackers/python/samples/simple.py @@ -103,7 +103,9 @@ def test(dev): ctx.set_sampler(0, sampler) # texture - texture = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, width, height, usage=PIPE_TEXTURE_USAGE_RENDER_TARGET) + texture = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, + width, height, + usage=PIPE_TEXTURE_USAGE_RENDER_TARGET) ctx.set_sampler_texture(0, texture) # drawing dest @@ -116,12 +118,29 @@ def test(dev): ctx.set_framebuffer(fb) # vertex shader - # vs = Shader() - #ctx.set_vertex_shader(vs) + vs = Shader(''' + VERT1.1 + DCL IN[0], POSITION, CONSTANT + DCL IN[1], GENERIC[0], CONSTANT + DCL OUT[0], POSITION, CONSTANT + DCL OUT[1], GENERIC[0], CONSTANT + 0:MOV OUT[0], IN[0] + 1:MOV OUT[1], IN[1] + 2:END + ''') + #vs.dump() + ctx.set_vertex_shader(vs) # fragment shader - #fs = Shader() - #ctx.set_fragment_shader(fs) + fs = Shader(''' + FRAG1.1 + DCL IN[0], COLOR, CONSTANT + DCL OUT[0], COLOR, CONSTANT + 0:MOV OUT[0], IN[0] + 1:END + ''') + #fs.dump() + ctx.set_fragment_shader(fs) if 0: nverts = 4 diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index 430a7af176..e9002b493d 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -99,18 +99,12 @@ st_context_destroy(struct st_context *st_ctx) if(st_ctx) { struct st_device *st_dev = st_ctx->st_dev; - if(st_ctx->vs) { - st_ctx->pipe->bind_vs_state(st_ctx->pipe, NULL); - st_ctx->pipe->delete_vs_state(st_ctx->pipe, st_ctx->vs); - } - - if(st_ctx->fs) { - st_ctx->pipe->bind_fs_state(st_ctx->pipe, NULL); - st_ctx->pipe->delete_fs_state(st_ctx->pipe, st_ctx->fs); - } - - if(st_ctx->cso) + if(st_ctx->cso) { + cso_delete_vertex_shader(st_ctx->cso, st_ctx->vs); + cso_delete_fragment_shader(st_ctx->cso, st_ctx->fs); + cso_destroy_context(st_ctx->cso); + } if(st_ctx->pipe) st_ctx->st_dev->st_ws->context_destroy(st_ctx->pipe); @@ -162,8 +156,8 @@ st_context_create(struct st_device *st_dev) st_ctx->fs = util_make_fragment_passthrough_shader(st_ctx->pipe, &st_ctx->frag_shader); - st_ctx->pipe->bind_fs_state(st_ctx->pipe, st_ctx->fs); - st_ctx->pipe->bind_vs_state(st_ctx->pipe, st_ctx->vs); + cso_set_fragment_shader_handle(st_ctx->cso, st_ctx->fs); + cso_set_vertex_shader_handle(st_ctx->cso, st_ctx->vs); return st_ctx; } -- cgit v1.2.3 From 3679f690230b9691157d44cfa5baf947d84e1487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 14 Jul 2008 11:38:44 +0900 Subject: python: Set default state. --- src/gallium/state_trackers/python/gallium.i | 2 + src/gallium/state_trackers/python/st_device.c | 120 ++++++++++++++++++++++++-- src/gallium/state_trackers/python/st_device.h | 4 +- 3 files changed, 116 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 53d160ef6c..6e355b7975 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -266,6 +266,8 @@ struct st_context { void set_sampler_texture(unsigned index, struct pipe_texture *texture) { + if(!texture) + texture = $self->default_texture; pipe_texture_reference(&$self->sampler_textures[index], texture); $self->pipe->set_sampler_textures($self->pipe, PIPE_MAX_SAMPLERS, diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index e9002b493d..25b5a4fa8c 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -111,7 +111,8 @@ st_context_destroy(struct st_context *st_ctx) for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) pipe_texture_reference(&st_ctx->sampler_textures[i], NULL); - + pipe_texture_reference(&st_ctx->default_texture, NULL); + FREE(st_ctx); if(!--st_dev->refcount) @@ -140,8 +141,111 @@ st_context_create(struct st_device *st_dev) if(!st_ctx->cso) st_context_destroy(st_ctx); + /* disabled blending/masking */ + { + struct pipe_blend_state blend; + memset(&blend, 0, sizeof(blend)); + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.colormask = PIPE_MASK_RGBA; + cso_set_blend(st_ctx->cso, &blend); + } + + /* no-op depth/stencil/alpha */ + { + struct pipe_depth_stencil_alpha_state depthstencil; + memset(&depthstencil, 0, sizeof(depthstencil)); + cso_set_depth_stencil_alpha(st_ctx->cso, &depthstencil); + } + + /* rasterizer */ + { + struct pipe_rasterizer_state rasterizer; + memset(&rasterizer, 0, sizeof(rasterizer)); + rasterizer.front_winding = PIPE_WINDING_CW; + rasterizer.cull_mode = PIPE_WINDING_NONE; + rasterizer.bypass_clipping = 1; + /*rasterizer.bypass_vs = 1;*/ + cso_set_rasterizer(st_ctx->cso, &rasterizer); + } + + /* identity viewport */ + { + struct pipe_viewport_state viewport; + viewport.scale[0] = 1.0; + viewport.scale[1] = 1.0; + viewport.scale[2] = 1.0; + viewport.scale[3] = 1.0; + viewport.translate[0] = 0.0; + viewport.translate[1] = 0.0; + viewport.translate[2] = 0.0; + viewport.translate[3] = 0.0; + cso_set_viewport(st_ctx->cso, &viewport); + } + + /* samplers */ + { + struct pipe_sampler_state sampler; + unsigned i; + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST; + sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; + sampler.normalized_coords = 1; + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + cso_single_sampler(st_ctx->cso, i, &sampler); + cso_single_sampler_done(st_ctx->cso); + } + + /* default textures */ + { + struct pipe_screen *screen = st_dev->screen; + struct pipe_texture templat; + struct pipe_surface *surface; + unsigned i; + + memset( &templat, 0, sizeof( templat ) ); + templat.target = PIPE_TEXTURE_2D; + templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templat.block.size = 4; + templat.block.width = 1; + templat.block.height = 1; + templat.width[0] = 1; + templat.height[0] = 1; + templat.depth[0] = 1; + templat.last_level = 0; + + st_ctx->default_texture = screen->texture_create( screen, &templat ); + if(st_ctx->default_texture) { + surface = screen->get_tex_surface( screen, + st_ctx->default_texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE ); + if(surface) { + uint32_t *map; + map = (uint32_t *) pipe_surface_map(surface, PIPE_BUFFER_USAGE_CPU_WRITE ); + if(map) { + *map = 0x00000000; + pipe_surface_unmap( surface ); + } + pipe_surface_reference(&surface, NULL); + } + } + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + pipe_texture_reference(&st_ctx->sampler_textures[i], st_ctx->default_texture); + + cso_set_sampler_textures(st_ctx->cso, PIPE_MAX_SAMPLERS, st_ctx->sampler_textures); + } + /* vertex shader */ { + struct pipe_shader_state vert_shader; + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC }; const uint semantic_indexes[] = { 0, 0 }; @@ -149,15 +253,17 @@ st_context_create(struct st_device *st_dev) 2, semantic_names, semantic_indexes, - &st_ctx->vert_shader); + &vert_shader); + cso_set_vertex_shader_handle(st_ctx->cso, st_ctx->vs); } /* fragment shader */ - st_ctx->fs = util_make_fragment_passthrough_shader(st_ctx->pipe, - &st_ctx->frag_shader); - - cso_set_fragment_shader_handle(st_ctx->cso, st_ctx->fs); - cso_set_vertex_shader_handle(st_ctx->cso, st_ctx->vs); + { + struct pipe_shader_state frag_shader; + st_ctx->fs = util_make_fragment_passthrough_shader(st_ctx->pipe, + &frag_shader); + cso_set_fragment_shader_handle(st_ctx->cso, st_ctx->fs); + } return st_ctx; } diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h index 46db20acd7..2d95c2da73 100644 --- a/src/gallium/state_trackers/python/st_device.h +++ b/src/gallium/state_trackers/python/st_device.h @@ -45,12 +45,10 @@ struct st_context { struct cso_context *cso; - struct pipe_shader_state vert_shader; - struct pipe_shader_state frag_shader; - void *vs; void *fs; + struct pipe_texture *default_texture; struct pipe_texture *sampler_textures[PIPE_MAX_SAMPLERS]; struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS]; -- cgit v1.2.3 From f07ad529af96b903e7b19fa26c3372d16b507bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 14 Jul 2008 11:44:21 +0900 Subject: python: Surface clears. --- src/gallium/state_trackers/python/gallium.i | 2 +- src/gallium/state_trackers/python/samples/simple.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 6e355b7975..f616037ec2 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -367,7 +367,7 @@ error1: $self->pipe->surface_fill($self->pipe, dst, x, y, width, height, value); } - void clear(struct pipe_surface *surface, unsigned value) { + void surface_clear(struct pipe_surface *surface, unsigned value = 0) { $self->pipe->clear($self->pipe, surface, value); } diff --git a/src/gallium/state_trackers/python/samples/simple.py b/src/gallium/state_trackers/python/samples/simple.py index 6e90eec28a..10742db0dc 100644 --- a/src/gallium/state_trackers/python/samples/simple.py +++ b/src/gallium/state_trackers/python/samples/simple.py @@ -142,6 +142,8 @@ def test(dev): #fs.dump() ctx.set_fragment_shader(fs) + ctx.surface_clear(surface, 0x00ff0000) + if 0: nverts = 4 nattrs = 1 -- cgit v1.2.3 From 00cd96b68f21cb281aa30199f520aae8b2f93083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 14 Jul 2008 12:40:50 +0900 Subject: python: Get the sample app to draw triangle like trivial/tri exanple. --- .../state_trackers/python/samples/simple.py | 179 ------------------- src/gallium/state_trackers/python/samples/tri.py | 193 +++++++++++++++++++++ 2 files changed, 193 insertions(+), 179 deletions(-) delete mode 100644 src/gallium/state_trackers/python/samples/simple.py create mode 100644 src/gallium/state_trackers/python/samples/tri.py (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/samples/simple.py b/src/gallium/state_trackers/python/samples/simple.py deleted file mode 100644 index 10742db0dc..0000000000 --- a/src/gallium/state_trackers/python/samples/simple.py +++ /dev/null @@ -1,179 +0,0 @@ -#!/usr/bin/env python -########################################################################## -# -# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. -# All Rights Reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sub license, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice (including the -# next paragraph) shall be included in all copies or substantial portions -# of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR -# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -########################################################################## - - -from gallium import * - - -def save_image(filename, surface): - pixels = FloatArray(surface.height*surface.width*4) - surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) - - import Image - outimage = Image.new( - mode='RGB', - size=(surface.width, surface.height), - color=(0,0,0)) - outpixels = outimage.load() - for y in range(0, surface.height): - for x in range(0, surface.width): - offset = (y*surface.width + x)*4 - r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] - outpixels[x, y] = r, g, b - outimage.save(filename, "PNG") - - -def test(dev): - ctx = dev.context_create() - - width = 256 - height = 256 - - # disabled blending/masking - blend = Blend() - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO - blend.colormask = PIPE_MASK_RGBA - ctx.set_blend(blend) - - # no-op depth/stencil/alpha - depth_stencil_alpha = DepthStencilAlpha() - ctx.set_depth_stencil_alpha(depth_stencil_alpha) - - # rasterizer - rasterizer = Rasterizer() - rasterizer.front_winding = PIPE_WINDING_CW - rasterizer.cull_mode = PIPE_WINDING_NONE - rasterizer.bypass_clipping = 1 - #rasterizer.bypass_vs = 1 - ctx.set_rasterizer(rasterizer) - - # viewport (identity, we setup vertices in wincoords) - viewport = Viewport() - scale = FloatArray(4) - scale[0] = 1.0 - scale[1] = 1.0 - scale[2] = 1.0 - scale[3] = 1.0 - viewport.scale = scale - translate = FloatArray(4) - translate[0] = 0.0 - translate[1] = 0.0 - translate[2] = 0.0 - translate[3] = 0.0 - viewport.translate = translate - ctx.set_viewport(viewport) - - # samplers - sampler = Sampler() - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE - sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE - sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE - sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST - sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST - sampler.normalized_coords = 1 - ctx.set_sampler(0, sampler) - - # texture - texture = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, - width, height, - usage=PIPE_TEXTURE_USAGE_RENDER_TARGET) - ctx.set_sampler_texture(0, texture) - - # drawing dest - surface = texture.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE) - fb = Framebuffer() - fb.width = surface.width - fb.height = surface.height - fb.num_cbufs = 1 - fb.set_cbuf(0, surface) - ctx.set_framebuffer(fb) - - # vertex shader - vs = Shader(''' - VERT1.1 - DCL IN[0], POSITION, CONSTANT - DCL IN[1], GENERIC[0], CONSTANT - DCL OUT[0], POSITION, CONSTANT - DCL OUT[1], GENERIC[0], CONSTANT - 0:MOV OUT[0], IN[0] - 1:MOV OUT[1], IN[1] - 2:END - ''') - #vs.dump() - ctx.set_vertex_shader(vs) - - # fragment shader - fs = Shader(''' - FRAG1.1 - DCL IN[0], COLOR, CONSTANT - DCL OUT[0], COLOR, CONSTANT - 0:MOV OUT[0], IN[0] - 1:END - ''') - #fs.dump() - ctx.set_fragment_shader(fs) - - ctx.surface_clear(surface, 0x00ff0000) - - if 0: - nverts = 4 - nattrs = 1 - vertices = FloatArray(n_verts * nattrs * 4) - - # init vertex data that doesn't change - for i in range(nverts): - for j in range(nattrs): - vertices[(i*nattrs +j)*4 + 0] = 0.0 - vertices[(i*nattrs +j)*4 + 1] = 0.0 - vertices[(i*nattrs +j)*4 + 2] = 0.0 - vertices[(i*nattrs +j)*4 + 3] = 0.0 - - ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN, - 4, # verts - 2, # attribs/vert - vertices) - else: - ctx.draw_quad(32.0, 32.0, 224.0, 224.0) - - ctx.flush() - - save_image("simple.png", surface) - - - -def main(): - dev = Device(0) - test(dev) - - -if __name__ == '__main__': - main() diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py new file mode 100644 index 0000000000..7a10905ddb --- /dev/null +++ b/src/gallium/state_trackers/python/samples/tri.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +########################################################################## + + +from gallium import * + + +def save_image(filename, surface): + pixels = FloatArray(surface.height*surface.width*4) + surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) + + import Image + outimage = Image.new( + mode='RGB', + size=(surface.width, surface.height), + color=(0,0,0)) + outpixels = outimage.load() + for y in range(0, surface.height): + for x in range(0, surface.width): + offset = (y*surface.width + x)*4 + r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] + outpixels[x, y] = r, g, b + outimage.save(filename, "PNG") + + +def test(dev): + ctx = dev.context_create() + + width = 256 + height = 256 + + # disabled blending/masking + blend = Blend() + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.colormask = PIPE_MASK_RGBA + ctx.set_blend(blend) + + # no-op depth/stencil/alpha + depth_stencil_alpha = DepthStencilAlpha() + ctx.set_depth_stencil_alpha(depth_stencil_alpha) + + # rasterizer + rasterizer = Rasterizer() + rasterizer.front_winding = PIPE_WINDING_CW + rasterizer.cull_mode = PIPE_WINDING_NONE + rasterizer.bypass_clipping = 1 + #rasterizer.bypass_vs = 1 + ctx.set_rasterizer(rasterizer) + + # viewport (identity, we setup vertices in wincoords) + viewport = Viewport() + scale = FloatArray(4) + scale[0] = 1.0 + scale[1] = 1.0 + scale[2] = 1.0 + scale[3] = 1.0 + viewport.scale = scale + translate = FloatArray(4) + translate[0] = 0.0 + translate[1] = 0.0 + translate[2] = 0.0 + translate[3] = 0.0 + viewport.translate = translate + ctx.set_viewport(viewport) + + # samplers + sampler = Sampler() + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE + sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.normalized_coords = 1 + ctx.set_sampler(0, sampler) + + # texture + texture = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, + width, height, + usage=PIPE_TEXTURE_USAGE_RENDER_TARGET) + ctx.set_sampler_texture(0, texture) + + # drawing dest + surface = texture.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE) + fb = Framebuffer() + fb.width = surface.width + fb.height = surface.height + fb.num_cbufs = 1 + fb.set_cbuf(0, surface) + ctx.set_framebuffer(fb) + + # vertex shader + vs = Shader(''' + VERT1.1 + DCL IN[0], POSITION, CONSTANT + DCL IN[1], COLOR, CONSTANT + DCL OUT[0], POSITION, CONSTANT + DCL OUT[1], COLOR, CONSTANT + 0:MOV OUT[0], IN[0] + 1:MOV OUT[1], IN[1] + 2:END + ''') + #vs.dump() + ctx.set_vertex_shader(vs) + + # fragment shader + fs = Shader(''' + FRAG1.1 + DCL IN[0], COLOR, LINEAR + DCL OUT[0], COLOR, CONSTANT + 0:MOV OUT[0], IN[0] + 1:END + ''') + #fs.dump() + ctx.set_fragment_shader(fs) + + nverts = 3 + nattrs = 2 + verts = FloatArray(nverts * nattrs * 4) + + verts[ 0] = 128.0 # x1 + verts[ 1] = 32.0 # y1 + verts[ 2] = 0.0 # z1 + verts[ 3] = 1.0 # w1 + verts[ 4] = 1.0 # r1 + verts[ 5] = 0.0 # g1 + verts[ 6] = 0.0 # b1 + verts[ 7] = 1.0 # a1 + verts[ 8] = 32.0 # x2 + verts[ 9] = 224.0 # y2 + verts[10] = 0.0 # z2 + verts[11] = 1.0 # w2 + verts[12] = 0.0 # r2 + verts[13] = 1.0 # g2 + verts[14] = 0.0 # b2 + verts[15] = 1.0 # a2 + verts[16] = 224.0 # x3 + verts[17] = 224.0 # y3 + verts[18] = 0.0 # z3 + verts[19] = 1.0 # w3 + verts[20] = 0.0 # r3 + verts[21] = 0.0 # g3 + verts[22] = 1.0 # b3 + verts[23] = 1.0 # a3 + + ctx.surface_clear(surface, 0x00000000) + + ctx.draw_vertices(PIPE_PRIM_TRIANGLES, + nverts, + nattrs, + verts) + + ctx.flush() + + save_image("tri.png", surface) + + + +def main(): + dev = Device(hardware = False) + test(dev) + + +if __name__ == '__main__': + main() -- cgit v1.2.3 From 3aea28b9b1e9100be6836d4f88444e3cdfe5c4be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 14 Jul 2008 22:26:40 +0900 Subject: python: Raw tile access to surface. --- src/gallium/state_trackers/python/gallium.i | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index f616037ec2..60f8e50300 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -55,6 +55,7 @@ %} %include "carrays.i" +%array_class(unsigned char, ByteArray); %array_class(int, IntArray); %array_class(float, FloatArray); @@ -405,6 +406,16 @@ error1: // gets mapped to pipe_surface_unmap automatically void unmap( void ); + void + get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, unsigned char *p, unsigned stride) { + pipe_get_tile_raw($self, x, y, w, h, p, stride); + } + + void + put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned char *p, unsigned stride) { + pipe_put_tile_raw($self, x, y, w, h, p, stride); + } + void get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *p) { pipe_get_tile_rgba($self, x, y, w, h, p); -- cgit v1.2.3 From 64979d618a24e8378d95944d5f1d1b5847880a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 14 Jul 2008 22:27:40 +0900 Subject: python: Basic test case for 2d texture. --- src/gallium/state_trackers/python/tests/base.py | 96 ++++++++ src/gallium/state_trackers/python/tests/data.py | 274 +++++++++++++++++++++ src/gallium/state_trackers/python/tests/texture.py | 236 ++++++++++++++++++ 3 files changed, 606 insertions(+) create mode 100644 src/gallium/state_trackers/python/tests/base.py create mode 100644 src/gallium/state_trackers/python/tests/data.py create mode 100644 src/gallium/state_trackers/python/tests/texture.py (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/tests/base.py b/src/gallium/state_trackers/python/tests/base.py new file mode 100644 index 0000000000..5778ad4382 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/base.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +########################################################################## + + +from gallium import * + + +# Enumerate all pixel formats +formats = {} +for name, value in globals().items(): + if name.startswith("PIPE_FORMAT_") and isinstance(value, int): + formats[value] = name + + +def save_image(filename, surface): + pixels = FloatArray(surface.height*surface.width*4) + surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) + + import Image + outimage = Image.new( + mode='RGB', + size=(surface.width, surface.height), + color=(0,0,0)) + outpixels = outimage.load() + for y in range(0, surface.height): + for x in range(0, surface.width): + offset = (y*surface.width + x)*4 + r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] + outpixels[x, y] = r, g, b + outimage.save(filename, "PNG") + + + +class Test: + + def __init__(self): + pass + + def run(self): + raise NotImplementedError + + +class TestSuite(Test): + + def __init__(self, tests = None): + Test.__init__(self) + if tests is None: + self.tests = [] + else: + self.tests = tests + + def add_test(self, test): + self.tests.append(test) + + def run(self): + for test in self.tests: + self.test.run() + + +class TextureTemplate: + + def __init__(self, format=PIPE_FORMAT_R8G8B8A8_UNORM, width=1, height=1, depth=1, last_level=0, target=PIPE_TEXTURE_2D): + self.format = format + self.width = width + self.height = height + self.depth = depth + self.last_level = last_level + self.target = target + + + diff --git a/src/gallium/state_trackers/python/tests/data.py b/src/gallium/state_trackers/python/tests/data.py new file mode 100644 index 0000000000..2287884285 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/data.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +########################################################################## + +"""Texture data generation for use in testing.""" + + +import random + +from gallium import * + + +dxt1_rgb_data = [ + ( + [ + [0x99, 0xb0, 0x8e, 0xff], + [0x5d, 0x62, 0x89, 0xff], + [0x99, 0xb0, 0x8e, 0xff], + [0x99, 0xb0, 0x8e, 0xff], + [0xd6, 0xff, 0x94, 0xff], + [0x5d, 0x62, 0x89, 0xff], + [0x99, 0xb0, 0x8e, 0xff], + [0xd6, 0xff, 0x94, 0xff], + [0x5d, 0x62, 0x89, 0xff], + [0x5d, 0x62, 0x89, 0xff], + [0x99, 0xb0, 0x8e, 0xff], + [0x21, 0x14, 0x84, 0xff], + [0x5d, 0x62, 0x89, 0xff], + [0x21, 0x14, 0x84, 0xff], + [0x21, 0x14, 0x84, 0xff], + [0x99, 0xb0, 0x8e, 0xff], + ], + [0xf2, 0xd7, 0xb0, 0x20, 0xae, 0x2c, 0x6f, 0x97], + ), + ( + [ + [0xb5, 0xcf, 0x9c, 0xff], + [0x83, 0x8c, 0x8b, 0xff], + [0x21, 0x08, 0x6b, 0xff], + [0x83, 0x8c, 0x8b, 0xff], + [0x52, 0x4a, 0x7b, 0xff], + [0x83, 0x8c, 0x8b, 0xff], + [0x83, 0x8c, 0x8b, 0xff], + [0xb5, 0xcf, 0x9c, 0xff], + [0x21, 0x08, 0x6b, 0xff], + [0xb5, 0xcf, 0x9c, 0xff], + [0x83, 0x8c, 0x8b, 0xff], + [0x52, 0x4a, 0x7b, 0xff], + [0xb5, 0xcf, 0x9c, 0xff], + [0x83, 0x8c, 0x8b, 0xff], + [0x52, 0x4a, 0x7b, 0xff], + [0x83, 0x8c, 0x8b, 0xff], + ], + [0x73, 0xb6, 0x4d, 0x20, 0x98, 0x2b, 0xe1, 0xb8], + ), + ( + [ + [0x00, 0x2c, 0xff, 0xff], + [0x94, 0x8d, 0x7b, 0xff], + [0x4a, 0x5c, 0xbd, 0xff], + [0x4a, 0x5c, 0xbd, 0xff], + [0x4a, 0x5c, 0xbd, 0xff], + [0x94, 0x8d, 0x7b, 0xff], + [0x94, 0x8d, 0x7b, 0xff], + [0x94, 0x8d, 0x7b, 0xff], + [0xde, 0xbe, 0x39, 0xff], + [0x94, 0x8d, 0x7b, 0xff], + [0xde, 0xbe, 0x39, 0xff], + [0xde, 0xbe, 0x39, 0xff], + [0xde, 0xbe, 0x39, 0xff], + [0xde, 0xbe, 0x39, 0xff], + [0xde, 0xbe, 0x39, 0xff], + [0x94, 0x8d, 0x7b, 0xff], + ], + [0xe7, 0xdd, 0x7f, 0x01, 0xf9, 0xab, 0x08, 0x80], + ), + ( + [ + [0x6b, 0x24, 0x21, 0xff], + [0x7b, 0x4f, 0x5d, 0xff], + [0x7b, 0x4f, 0x5d, 0xff], + [0x8b, 0x7a, 0x99, 0xff], + [0x7b, 0x4f, 0x5d, 0xff], + [0x7b, 0x4f, 0x5d, 0xff], + [0x6b, 0x24, 0x21, 0xff], + [0x8b, 0x7a, 0x99, 0xff], + [0x9c, 0xa6, 0xd6, 0xff], + [0x6b, 0x24, 0x21, 0xff], + [0x7b, 0x4f, 0x5d, 0xff], + [0x8b, 0x7a, 0x99, 0xff], + [0x6b, 0x24, 0x21, 0xff], + [0x8b, 0x7a, 0x99, 0xff], + [0x7b, 0x4f, 0x5d, 0xff], + [0x9c, 0xa6, 0xd6, 0xff], + ], + [0x3a, 0x9d, 0x24, 0x69, 0xbd, 0x9f, 0xb4, 0x39], + ), +] + +dxt1_rgba = [ + ( + [ + [0x00, 0x00, 0x00, 0x00], + [0x4e, 0xaa, 0x90, 0xff], + [0x4e, 0xaa, 0x90, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0x4e, 0xaa, 0x90, 0xff], + [0x29, 0xff, 0xff, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0x4e, 0xaa, 0x90, 0xff], + [0x73, 0x55, 0x21, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x4e, 0xaa, 0x90, 0xff], + [0x4e, 0xaa, 0x90, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x4e, 0xaa, 0x90, 0xff], + ], + [0xff, 0x2f, 0xa4, 0x72, 0xeb, 0xb2, 0xbd, 0xbe], + ), + ( + [ + [0xb5, 0xe3, 0x63, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0x6b, 0x24, 0x84, 0xff], + [0xb5, 0xe3, 0x63, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0xb5, 0xe3, 0x63, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x6b, 0x24, 0x84, 0xff], + [0x6b, 0x24, 0x84, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0xb5, 0xe3, 0x63, 0xff], + [0x90, 0x83, 0x73, 0xff], + [0xb5, 0xe3, 0x63, 0xff], + ], + [0x30, 0x69, 0x0c, 0xb7, 0x4d, 0xf7, 0x0f, 0x67], + ), + ( + [ + [0x00, 0x00, 0x00, 0x00], + [0xc6, 0x86, 0x8c, 0xff], + [0xc6, 0x86, 0x8c, 0xff], + [0x21, 0x65, 0x42, 0xff], + [0x21, 0x65, 0x42, 0xff], + [0x21, 0x65, 0x42, 0xff], + [0x21, 0x65, 0x42, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x21, 0x65, 0x42, 0xff], + [0xc6, 0x86, 0x8c, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0xc6, 0x86, 0x8c, 0xff], + ], + [0x28, 0x23, 0x31, 0xc4, 0x17, 0xc0, 0xd3, 0x7f], + ), + ( + [ + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0xc6, 0xe3, 0x9c, 0xff], + [0x7b, 0x1c, 0x52, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0x00, 0x00], + [0x7b, 0x1c, 0x52, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0x7b, 0x1c, 0x52, 0xff], + [0xa0, 0x7f, 0x77, 0xff], + [0xc6, 0xe3, 0x9c, 0xff], + [0x00, 0x00, 0x00, 0x00], + [0xa0, 0x7f, 0x77, 0xff], + ], + [0xea, 0x78, 0x13, 0xc7, 0x7f, 0xfc, 0x33, 0xb6], + ), +] + + + +def generate_data_compressed(surface, blocks): + pixels, block = blocks[0] + + stride = surface.nblocksx*surface.block.size + size = surface.nblocksy*stride + + raw = ByteArray(size) + rgba = FloatArray(surface.height*surface.width*4) + + for y in range(0, surface.nblocksx): + for x in range(0, surface.nblocksy): + + offset = (y*surface.nblocksx + x)*surface.block.width + for i in range(0, surface.block.size): + raw[offset + i] = block[i] + + for j in range(0, surface.block.width): + for i in range(0, surface.block.height): + offset = ((y*surface.block.height + j)*surface.width + x*surface.block.width + i)*4 + pixel = pixels[j*surface.block.width + i] + for ch in range(0, 4): + rgba[offset + ch] = float(pixel[ch])/255.0 + + surface.put_tile_raw(0, 0, surface.width, surface.height, raw, stride) + + return rgba + + +def generate_data_simple(surface): + stride = surface.nblocksx*surface.block.size + size = surface.nblocksy*stride + + raw = ByteArray(size) + rgba = FloatArray(surface.height*surface.width*4) + + for i in range(0, size): + raw[i] = random.randint(0, 255) + + surface.put_tile_raw(0, 0, surface.width, surface.height, raw, stride) + + surface.get_tile_rgba(0, 0, surface.width, surface.height, rgba) + + return rgba + + +def generate_data(surface): + width = surface.width + height = surface.height + + if surface.format == PIPE_FORMAT_DXT1_RGB: + return generate_data_compressed(surface, dxt1_rgb_data) + if surface.format == PIPE_FORMAT_DXT1_RGBA: + return generate_data_compressed(surface, dxt1_rgba_data) + if surface.format == PIPE_FORMAT_DXT3_RGBA: + assert 0 + if surface.format == PIPE_FORMAT_DXT5_RGBA: + assert 0 + + return generate_data_simple(surface) + + + diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py new file mode 100644 index 0000000000..d0b657423e --- /dev/null +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python +########################################################################## +# +# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +########################################################################## + + +from gallium import * +from base import * +from data import generate_data + + +def compare_rgba(width, height, rgba1, rgba2, tol=0.01): + result = True + for y in range(0, height): + for x in range(0, width): + for ch in range(4): + offset = (y*width + x)*4 + ch + v1 = rgba1[offset] + v2 = rgba2[offset] + if abs(v1 - v2) > tol: + sys.stderr.write("x=%u, y=%u, ch=%u differ: %f vs %f\n", + x, y, ch, v1, v2) + result = False + + +class TextureTest(Test): + + def __init__(self, **kargs): + Test.__init__(self) + self.__dict__.update(kargs) + + def run(self): + dev = self.dev + + format = PIPE_FORMAT_A8R8G8B8_UNORM + #format = PIPE_FORMAT_DXT1_RGB + + if not dev.is_format_supported(format, PIPE_TEXTURE): + pass + if not dev.is_format_supported(format, PIPE_SURFACE): + pass + + ctx = dev.context_create() + + width = 256 + height = 256 + + # disabled blending/masking + blend = Blend() + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.colormask = PIPE_MASK_RGBA + ctx.set_blend(blend) + + # no-op depth/stencil/alpha + depth_stencil_alpha = DepthStencilAlpha() + ctx.set_depth_stencil_alpha(depth_stencil_alpha) + + # rasterizer + rasterizer = Rasterizer() + rasterizer.front_winding = PIPE_WINDING_CW + rasterizer.cull_mode = PIPE_WINDING_NONE + rasterizer.bypass_clipping = 1 + #rasterizer.bypass_vs = 1 + ctx.set_rasterizer(rasterizer) + + # viewport (identity, we setup vertices in wincoords) + viewport = Viewport() + scale = FloatArray(4) + scale[0] = 1.0 + scale[1] = 1.0 + scale[2] = 1.0 + scale[3] = 1.0 + viewport.scale = scale + translate = FloatArray(4) + translate[0] = 0.0 + translate[1] = 0.0 + translate[2] = 0.0 + translate[3] = 0.0 + viewport.translate = translate + ctx.set_viewport(viewport) + + # samplers + sampler = Sampler() + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE + sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.normalized_coords = 1 + ctx.set_sampler(0, sampler) + + # texture + texture = dev.texture_create(format, + width, + height) + ctx.set_sampler_texture(0, texture) + + surface = texture.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE) + + expected_rgba = generate_data(surface) + + cbuf_tex = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, + width, + height) + + # drawing dest + cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE) + fb = Framebuffer() + fb.width = cbuf.width + fb.height = cbuf.height + fb.num_cbufs = 1 + fb.set_cbuf(0, cbuf) + ctx.set_framebuffer(fb) + + # vertex shader + vs = Shader(''' + VERT1.1 + DCL IN[0], POSITION, CONSTANT + DCL IN[1], GENERIC, CONSTANT + DCL OUT[0], POSITION, CONSTANT + DCL OUT[1], GENERIC, CONSTANT + 0:MOV OUT[0], IN[0] + 1:MOV OUT[1], IN[1] + 2:END + ''') + #vs.dump() + ctx.set_vertex_shader(vs) + + # fragment shader + fs = Shader(''' + FRAG1.1 + DCL IN[0], GENERIC[0], PERSPECTIVE + DCL OUT[0], COLOR, CONSTANT + DCL SAMP[0], CONSTANT + 0:TEX OUT[0], IN[0], SAMP[0], 2D + 1:END + ''') + fs.dump() + ctx.set_fragment_shader(fs) + + nverts = 4 + nattrs = 2 + verts = FloatArray(nverts * nattrs * 4) + + x = 0 + y = 0 + w = width + h = height + + verts[ 0] = x # x1 + verts[ 1] = y # y1 + verts[ 2] = 0.0 # z1 + verts[ 3] = 1.0 # w1 + verts[ 4] = 0.0 # s1 + verts[ 5] = 0.0 # t + verts[ 6] = 0.0 + verts[ 7] = 0.0 + verts[ 8] = x + w # x2 + verts[ 9] = y # y2 + verts[10] = 0.0 # z2 + verts[11] = 1.0 # w2 + verts[12] = 1.0 # s2 + verts[13] = 0.0 # t2 + verts[14] = 0.0 + verts[15] = 0.0 + verts[16] = x + w # x3 + verts[17] = y + h # y3 + verts[18] = 0.0 # z3 + verts[19] = 1.0 # w3 + verts[20] = 1.0 # s3 + verts[21] = 1.0 # t3 + verts[22] = 0.0 + verts[23] = 0.0 + verts[24] = x # x4 + verts[25] = y + h # y4 + verts[26] = 0.0 # z4 + verts[27] = 1.0 # w4 + verts[28] = 0.0 # s4 + verts[29] = 1.0 # t4 + verts[30] = 0.0 + verts[31] = 0.0 + + ctx.surface_clear(cbuf, 0x00000000) + + ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN, + nverts, + nattrs, + verts) + + ctx.flush() + + rgba = FloatArray(surface.height*surface.width*4) + + cbuf.get_tile_rgba(x, y, w, h, rgba) + + compare_rgba(width, height, rgba, expected_rgba) + + #save_image("texture1.png", surface) + #save_image("texture2.png", cbuf) + + +def main(): + dev = Device(hardware = False) + test = TextureTest(dev = dev) + test.run() + + +if __name__ == '__main__': + main() -- cgit v1.2.3 From 6eb7f763fbbbb7a32640760cd5d122020866fea1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 14 Jul 2008 18:08:52 -0600 Subject: tgsi: fix bug in execution of loops inside of conditionals. Fixes infinite loop bug. --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index 46949661af..001a4c4b15 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -2400,7 +2400,8 @@ exec_instruction( /* Restore ContMask, but don't pop */ assert(mach->ContStackTop > 0); mach->ContMask = mach->ContStack[mach->ContStackTop - 1]; - if (mach->LoopMask) { + UPDATE_EXEC_MASK(mach); + if (mach->ExecMask) { /* repeat loop: jump to instruction just past BGNLOOP */ *pc = inst->InstructionExtLabel.Label + 1; } -- cgit v1.2.3 From c60e009a9138a573d2219ee2ad85e3203b09a7ae Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 15 Jul 2008 10:56:30 +0200 Subject: tgsi: Numerical label before an instruction is optional. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index 1b283feb4c..6cab475b88 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -740,7 +740,10 @@ static const char *texture_names[TGSI_TEXTURE_COUNT] = "SHADOWRECT" }; -static boolean parse_instruction( struct translate_ctx *ctx ) +static boolean +parse_instruction( + struct translate_ctx *ctx, + boolean has_label ) { uint i; uint saturate = TGSI_SAT_NONE; @@ -767,7 +770,10 @@ static boolean parse_instruction( struct translate_ctx *ctx ) } } if (i == TGSI_OPCODE_LAST) { - report_error( ctx, "Unknown opcode" ); + if (has_label) + report_error( ctx, "Unknown opcode" ); + else + report_error( ctx, "Expected `DCL', `IMM' or a label" ); return FALSE; } info = &opcode_info[i]; @@ -1025,7 +1031,7 @@ static boolean translate( struct translate_ctx *ctx ) } if (parse_label( ctx, &label_val )) { - if (!parse_instruction( ctx )) + if (!parse_instruction( ctx, TRUE )) return FALSE; } else if (str_match_no_case( &ctx->cur, "DCL" )) { @@ -1036,8 +1042,7 @@ static boolean translate( struct translate_ctx *ctx ) if (!parse_immediate( ctx )) return FALSE; } - else { - report_error( ctx, "Expected `DCL', `IMM' or a label" ); + else if (!parse_instruction( ctx, FALSE )) { return FALSE; } } -- cgit v1.2.3 From ead8fcd92a737c7184020768203496a08eb3b7dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Jul 2008 00:33:54 +0900 Subject: python: Get it to build on windows too. --- src/gallium/state_trackers/python/SConscript | 36 ++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index 57a3fb2075..854cd83b7c 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -1,3 +1,6 @@ +import sys +import os.path + Import('*') if 'python' in env['statetrackers']: @@ -10,8 +13,38 @@ if 'python' in env['statetrackers']: env.Append(SWIGPATH = ['#src/gallium/include', '#src/gallium/include/pipe']) env.Append(SWIGFLAGS = ['-python', '-keyword']) - env.ParseConfig('python-config --cflags --ldflags --libs') + # http://www.scons.org/wiki/PythonExtensions + #env.AppendUnique(CPPATH = [distutils.sysconfig.get_python_inc()]) + #distutils.sysconfig.get_config_vars('SO') + + env['SHLIBPREFIX'] = '' + if platform in ['linux']: + env.ParseConfig('python-config --cflags --ldflags --libs') + + if platform in ['windows']: + python_root = sys.prefix + python_version = '%u%u' % sys.version_info[:2] + python_include = os.path.join(python_root, 'include') + python_libs = os.path.join(python_root, 'libs') + python_lib = os.path.join(python_libs, 'python' + python_version + '.lib') + + env.Append(CPPPATH = [python_include]) + env.Append(LIBPATH = [python_libs]) + env.Append(LIBS = ['python' + python_version + '.lib']) + env.Replace(SHLIBSUFFIX = '.pyd') + + if env['debug']: + # XXX; python25_d.lib is not included in Python for windows, and + # we'll get missing symbols unless we undefine _DEBUG + cppdefines = env['CPPDEFINES'] + cppdefines = [define for define in cppdefines if define != '_DEBUG'] + env.Replace(CPPDEFINES = cppdefines) + + # http://www.swig.org/Doc1.3/Windows.html + env['ENV']['PYTHON_INCLUDE'] = python_include + env['ENV']['PYTHON_LIB'] = python_lib + env.SharedLibrary( target = '_gallium', source = [ @@ -19,6 +52,5 @@ if 'python' in env['statetrackers']: 'st_device.c', 'st_softpipe_winsys.c', ], - SHLIBPREFIX = '', LIBS = softpipe + auxiliaries + env['LIBS'], ) -- cgit v1.2.3 From 2c4349aa3ac9a6d5ee1f7b1aeb5eb0ee1cb54690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Jul 2008 07:56:42 +0900 Subject: python: Move the python scons code to a separate tool module. --- src/gallium/state_trackers/python/SConscript | 44 +++++----------------------- 1 file changed, 7 insertions(+), 37 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index 854cd83b7c..687c46bfd7 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -7,50 +7,20 @@ if 'python' in env['statetrackers']: env = env.Clone() - env.Append(CPPPATH = '.') + env.Tool('python') env.Tool('swig') env.Append(SWIGPATH = ['#src/gallium/include', '#src/gallium/include/pipe']) env.Append(SWIGFLAGS = ['-python', '-keyword']) - # http://www.scons.org/wiki/PythonExtensions - #env.AppendUnique(CPPATH = [distutils.sysconfig.get_python_inc()]) - #distutils.sysconfig.get_config_vars('SO') - - env['SHLIBPREFIX'] = '' - - if platform in ['linux']: - env.ParseConfig('python-config --cflags --ldflags --libs') - - if platform in ['windows']: - python_root = sys.prefix - python_version = '%u%u' % sys.version_info[:2] - python_include = os.path.join(python_root, 'include') - python_libs = os.path.join(python_root, 'libs') - python_lib = os.path.join(python_libs, 'python' + python_version + '.lib') - - env.Append(CPPPATH = [python_include]) - env.Append(LIBPATH = [python_libs]) - env.Append(LIBS = ['python' + python_version + '.lib']) - env.Replace(SHLIBSUFFIX = '.pyd') - - if env['debug']: - # XXX; python25_d.lib is not included in Python for windows, and - # we'll get missing symbols unless we undefine _DEBUG - cppdefines = env['CPPDEFINES'] - cppdefines = [define for define in cppdefines if define != '_DEBUG'] - env.Replace(CPPDEFINES = cppdefines) - - # http://www.swig.org/Doc1.3/Windows.html - env['ENV']['PYTHON_INCLUDE'] = python_include - env['ENV']['PYTHON_LIB'] = python_lib - + env.Append(CPPPATH = '.') + env.SharedLibrary( - target = '_gallium', - source = [ - 'gallium.i', + target = '_gallium', + source = [ + 'gallium.i', 'st_device.c', 'st_softpipe_winsys.c', - ], + ], LIBS = softpipe + auxiliaries + env['LIBS'], ) -- cgit v1.2.3 From 1d03102b319f7bca2bf76c5d6e3996dc87f03634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Jul 2008 08:42:16 +0900 Subject: python: Allow hardware support. --- src/gallium/state_trackers/python/SConscript | 13 +++- src/gallium/state_trackers/python/gallium.i | 2 +- src/gallium/state_trackers/python/samples/tri.py | 2 +- src/gallium/state_trackers/python/st_device.c | 6 +- .../state_trackers/python/st_hardpipe_winsys.c | 78 ++++++++++++++++++++++ .../state_trackers/python/st_softpipe_winsys.c | 2 +- src/gallium/state_trackers/python/st_winsys.h | 4 +- src/gallium/state_trackers/python/tests/texture.py | 2 +- 8 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 src/gallium/state_trackers/python/st_hardpipe_winsys.c (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index 687c46bfd7..b284d2020b 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -15,12 +15,19 @@ if 'python' in env['statetrackers']: env.Append(CPPPATH = '.') - env.SharedLibrary( - target = '_gallium', + pyst = env.ConvenienceLibrary( + target = 'pyst', source = [ 'gallium.i', 'st_device.c', 'st_softpipe_winsys.c', ], - LIBS = softpipe + auxiliaries + env['LIBS'], + ) + + env.SharedLibrary( + target = '_gallium', + source = [ + 'st_hardpipe_winsys.c', + ], + LIBS = [pyst, softpipe] + auxiliaries + env['LIBS'], ) diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 60f8e50300..967840a063 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -100,7 +100,7 @@ struct st_context { %extend st_device { - st_device(int hardware = 0) { + st_device(int hardware = 1) { return st_device_create(hardware ? TRUE : FALSE); } diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py index 7a10905ddb..f915c26215 100644 --- a/src/gallium/state_trackers/python/samples/tri.py +++ b/src/gallium/state_trackers/python/samples/tri.py @@ -185,7 +185,7 @@ def test(dev): def main(): - dev = Device(hardware = False) + dev = Device() test(dev) diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index 25b5a4fa8c..d88d2de3c6 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -82,12 +82,10 @@ st_device_create_from_st_winsys(const struct st_winsys *st_ws) struct st_device * st_device_create(boolean hardware) { -#if 0 if(hardware) - return st_device_create_from_st_winsys(&st_hardware_winsys); + return st_device_create_from_st_winsys(&st_hardpipe_winsys); else -#endif - return st_device_create_from_st_winsys(&st_software_winsys); + return st_device_create_from_st_winsys(&st_softpipe_winsys); } diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c new file mode 100644 index 0000000000..33b75637b3 --- /dev/null +++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c @@ -0,0 +1,78 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * @file + * Stub for hardware pipe driver support. + */ + + +#include "pipe/p_compiler.h" + +#include "st_winsys.h" + + +extern void init_gallium(void); + +void (*force_init_gallium_linkage)(void) = &init_gallium; + + +static void +st_hardpipe_screen_destroy(struct pipe_screen *screen) +{ + st_softpipe_winsys.screen_destroy(screen); +} + + +static struct pipe_screen * +st_hardpipe_screen_create(void) +{ + return st_softpipe_winsys.screen_create(); +} + + +static void +st_hardpipe_context_destroy(struct pipe_context *pipe) +{ + st_softpipe_winsys.context_destroy(pipe); +} + + +static struct pipe_context * +st_hardpipe_context_create(struct pipe_screen *screen) +{ + return st_softpipe_winsys.context_create(screen); +} + + +const struct st_winsys st_hardpipe_winsys = { + &st_hardpipe_screen_create, + &st_hardpipe_screen_destroy, + &st_hardpipe_context_create, + &st_hardpipe_context_destroy +}; diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c index 964d60de1d..1fda70ca00 100644 --- a/src/gallium/state_trackers/python/st_softpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -313,7 +313,7 @@ st_softpipe_context_create(struct pipe_screen *screen) } -const struct st_winsys st_software_winsys = { +const struct st_winsys st_softpipe_winsys = { &st_softpipe_screen_create, &st_softpipe_screen_destroy, &st_softpipe_context_create, diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h index 992fc9ab4b..43db8b6bff 100644 --- a/src/gallium/state_trackers/python/st_winsys.h +++ b/src/gallium/state_trackers/python/st_winsys.h @@ -50,9 +50,9 @@ struct st_winsys }; -extern const struct st_winsys st_software_winsys; +extern const struct st_winsys st_softpipe_winsys; -extern const struct st_winsys st_hardware_winsys; +extern const struct st_winsys st_hardpipe_winsys; #endif /* ST_WINSYS_H_ */ diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index d0b657423e..ad11e8dcc9 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -227,7 +227,7 @@ class TextureTest(Test): def main(): - dev = Device(hardware = False) + dev = Device() test = TextureTest(dev = dev) test.run() -- cgit v1.2.3 From d5ed158dc87669f62bb7d3fb65c23fb2a465442b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Jul 2008 17:13:37 +0900 Subject: python: Get object ownership done correctly. --- src/gallium/state_trackers/python/gallium.i | 44 +++++++++++++++++----- src/gallium/state_trackers/python/st_device.c | 1 + .../state_trackers/python/st_hardpipe_winsys.c | 2 +- 3 files changed, 37 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 967840a063..2f1d8b22fb 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -66,6 +66,7 @@ %rename(Surface) pipe_surface; %rename(Buffer) pipe_buffer; + %rename(BlendColor) pipe_blend_color; %rename(Blend) pipe_blend_state; %rename(Clip) pipe_clip_state; @@ -82,15 +83,30 @@ %rename(VertexElement) pipe_vertex_element; %rename(Viewport) pipe_viewport_state; +%nodefaultctor st_device; +%nodefaultctor st_context; +%nodefaultctor pipe_texture; +%nodefaultctor pipe_surface; +%nodefaultctor pipe_buffer; + +%nodefaultdtor st_device; +%nodefaultdtor st_context; +%nodefaultdtor pipe_texture; +%nodefaultdtor pipe_surface; +%nodefaultdtor pipe_buffer; + +%ignore pipe_texture::screen; + +%ignore pipe_surface::winsys; +%immutable pipe_surface::texture; +%immutable pipe_surface::buffer; + %include "p_format.i"; %include "pipe/p_defines.h"; %include "pipe/p_state.h"; %include "pipe/p_shader_tokens.h"; -%nodefaultctor; -%nodefaultdtor; - struct st_device { }; @@ -98,6 +114,10 @@ struct st_context { }; +%newobject st_device::texture_create; +%newobject st_device::context_create; +%newobject st_device::buffer_create; + %extend st_device { st_device(int hardware = 1) { @@ -157,6 +177,7 @@ struct st_context { unsigned usage = 0 ) { struct pipe_texture templat; + struct pipe_texture *texture; memset(&templat, 0, sizeof(templat)); templat.format = format; pf_get_block(templat.format, &templat.block); @@ -166,7 +187,9 @@ struct st_context { templat.last_level = last_level; templat.target = target; templat.tex_usage = usage; - return $self->screen->texture_create($self->screen, &templat); + texture = $self->screen->texture_create($self->screen, &templat); + fprintf(stderr, "creating texture %p\n", texture); + return texture; } struct pipe_buffer * @@ -335,10 +358,6 @@ error1: ; } - void draw_quad(float x0, float y0, float x1, float y1, float z = 0.0f) { - util_draw_texquad($self->pipe, x0, y0, x1, y1, z); - } - void flush(void) { struct pipe_fence_handle *fence = NULL; @@ -375,10 +394,13 @@ error1: }; +%newobject pipe_texture::get_surface; + %extend pipe_texture { ~pipe_texture() { struct pipe_texture *ptr = $self; + fprintf(stderr, "destroying texture %p\n", $self); pipe_texture_reference(&ptr, NULL); } @@ -387,7 +409,10 @@ error1: get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0, unsigned usage=0 ) { struct pipe_screen *screen = $self->screen; - return screen->get_tex_surface(screen, $self, face, level, zslice, usage); + struct pipe_surface *surface; + surface = screen->get_tex_surface(screen, $self, face, level, zslice, usage); + fprintf(stderr, "creating surface %p\n", surface); + return surface; } }; @@ -397,6 +422,7 @@ error1: ~pipe_surface() { struct pipe_surface *ptr = $self; + fprintf(stderr, "destroying surface %p\n", $self); pipe_surface_reference(&ptr, NULL); } diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index d88d2de3c6..9e625ae2e0 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -70,6 +70,7 @@ st_device_create_from_st_winsys(const struct st_winsys *st_ws) if(!st_dev) return NULL; + st_dev->refcount = 1; st_dev->st_ws = st_ws; st_dev->screen = st_ws->screen_create(); diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c index 33b75637b3..1e04998232 100644 --- a/src/gallium/state_trackers/python/st_hardpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c @@ -37,8 +37,8 @@ #include "st_winsys.h" +/* XXX: Force init_gallium symbol to be linked */ extern void init_gallium(void); - void (*force_init_gallium_linkage)(void) = &init_gallium; -- cgit v1.2.3 From ee470020e17bc4999f3540fbad49fe645a4b914e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Jul 2008 17:14:07 +0900 Subject: python: Request/respect the texture & buffer usage flags in the examples. --- src/gallium/state_trackers/python/samples/tri.py | 81 +++++++++++++++++----- src/gallium/state_trackers/python/tests/base.py | 35 +++++++++- src/gallium/state_trackers/python/tests/texture.py | 46 ++++++------ 3 files changed, 121 insertions(+), 41 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py index f915c26215..e5044a0245 100644 --- a/src/gallium/state_trackers/python/samples/tri.py +++ b/src/gallium/state_trackers/python/samples/tri.py @@ -30,7 +30,7 @@ from gallium import * -def save_image(filename, surface): +def make_image(surface): pixels = FloatArray(surface.height*surface.width*4) surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) @@ -45,14 +45,38 @@ def save_image(filename, surface): offset = (y*surface.width + x)*4 r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] outpixels[x, y] = r, g, b + return outimage + +def save_image(filename, surface): + outimage = make_image(surface) outimage.save(filename, "PNG") +def show_image(surface): + outimage = make_image(surface) + + import Tkinter as tk + from PIL import Image, ImageTk + root = tk.Tk() + + root.title('background image') + + image1 = ImageTk.PhotoImage(outimage) + w = image1.width() + h = image1.height() + x = 100 + y = 100 + root.geometry("%dx%d+%d+%d" % (w, h, x, y)) + panel1 = tk.Label(root, image=image1) + panel1.pack(side='top', fill='both', expand='yes') + panel1.image = image1 + root.mainloop() + def test(dev): ctx = dev.context_create() - width = 256 - height = 256 + width = 255 + height = 255 # disabled blending/masking blend = Blend() @@ -72,6 +96,7 @@ def test(dev): rasterizer.front_winding = PIPE_WINDING_CW rasterizer.cull_mode = PIPE_WINDING_NONE rasterizer.bypass_clipping = 1 + rasterizer.scissor = 1 #rasterizer.bypass_vs = 1 ctx.set_rasterizer(rasterizer) @@ -102,21 +127,41 @@ def test(dev): sampler.normalized_coords = 1 ctx.set_sampler(0, sampler) - # texture - texture = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, - width, height, - usage=PIPE_TEXTURE_USAGE_RENDER_TARGET) - ctx.set_sampler_texture(0, texture) - - # drawing dest - surface = texture.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE) + # scissor + scissor = Scissor() + scissor.minx = 0 + scissor.miny = 0 + scissor.maxx = width + scissor.maxy = height + ctx.set_scissor(scissor) + + clip = Clip() + clip.nr = 0 + ctx.set_clip(clip) + + # framebuffer + cbuf = dev.texture_create(PIPE_FORMAT_X8R8G8B8_UNORM, + width, height, + usage=PIPE_TEXTURE_USAGE_DISPLAY_TARGET) + zbuf = dev.texture_create(PIPE_FORMAT_X8Z24_UNORM, + width, height, + usage=PIPE_TEXTURE_USAGE_DEPTH_STENCIL) + _cbuf = cbuf.get_surface(usage = PIPE_BUFFER_USAGE_GPU_READ|PIPE_BUFFER_USAGE_GPU_WRITE) + _zsbuf = zbuf.get_surface(usage = PIPE_BUFFER_USAGE_GPU_READ|PIPE_BUFFER_USAGE_GPU_WRITE) fb = Framebuffer() - fb.width = surface.width - fb.height = surface.height + fb.width = width + fb.height = height fb.num_cbufs = 1 - fb.set_cbuf(0, surface) + fb.set_cbuf(0, _cbuf) + fb.set_zsbuf(_zsbuf) ctx.set_framebuffer(fb) - + _cbuf.clear_value = 0x00000000 + _zsbuf.clear_value = 0x00ffffff + ctx.surface_clear(_cbuf, _cbuf.clear_value) + ctx.surface_clear(_zsbuf, _zsbuf.clear_value) + del _cbuf + del _zsbuf + # vertex shader vs = Shader(''' VERT1.1 @@ -171,16 +216,14 @@ def test(dev): verts[22] = 1.0 # b3 verts[23] = 1.0 # a3 - ctx.surface_clear(surface, 0x00000000) - ctx.draw_vertices(PIPE_PRIM_TRIANGLES, nverts, nattrs, verts) ctx.flush() - - save_image("tri.png", surface) + + show_image(cbuf.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE)) diff --git a/src/gallium/state_trackers/python/tests/base.py b/src/gallium/state_trackers/python/tests/base.py index 5778ad4382..185a59996e 100644 --- a/src/gallium/state_trackers/python/tests/base.py +++ b/src/gallium/state_trackers/python/tests/base.py @@ -37,7 +37,7 @@ for name, value in globals().items(): formats[value] = name -def save_image(filename, surface): +def make_image(surface): pixels = FloatArray(surface.height*surface.width*4) surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) @@ -52,8 +52,41 @@ def save_image(filename, surface): offset = (y*surface.width + x)*4 r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] outpixels[x, y] = r, g, b + return outimage + +def save_image(filename, surface): + outimage = make_image(surface) outimage.save(filename, "PNG") +def show_image(*surfaces): + import Tkinter as tk + from PIL import Image, ImageTk + + root = tk.Tk() + + x = 64 + y = 64 + + for i in range(len(surfaces)): + surface = surfaces[i] + outimage = make_image(surface) + + if i: + window = tk.Toplevel(root) + else: + window = root + window.title('Image %u' % (i+1)) + image1 = ImageTk.PhotoImage(outimage) + w = image1.width() + h = image1.height() + window.geometry("%dx%d+%d+%d" % (w, h, x, y)) + panel1 = tk.Label(window, image=image1) + panel1.pack(side='top', fill='both', expand='yes') + panel1.image = image1 + x += w + 2 + + root.mainloop() + class Test: diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index ad11e8dcc9..84ceebb169 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -27,13 +27,14 @@ ########################################################################## +import sys from gallium import * from base import * from data import generate_data def compare_rgba(width, height, rgba1, rgba2, tol=0.01): - result = True + errors = 0 for y in range(0, height): for x in range(0, width): for ch in range(4): @@ -41,9 +42,14 @@ def compare_rgba(width, height, rgba1, rgba2, tol=0.01): v1 = rgba1[offset] v2 = rgba2[offset] if abs(v1 - v2) > tol: - sys.stderr.write("x=%u, y=%u, ch=%u differ: %f vs %f\n", - x, y, ch, v1, v2) - result = False + if errors == 0: + sys.stderr.write("x=%u, y=%u, ch=%u differ: %f vs %f\n" % (x, y, ch, v1, v2)) + if errors == 1: + sys.stderr.write("...\n") + errors += 1 + if errors: + sys.stderr.write("%u out of %u pixels differ\n" % (errors/4, height*width)) + return errors == 0 class TextureTest(Test): @@ -65,8 +71,8 @@ class TextureTest(Test): ctx = dev.context_create() - width = 256 - height = 256 + width = 64 + height = 64 # disabled blending/masking blend = Blend() @@ -122,21 +128,21 @@ class TextureTest(Test): height) ctx.set_sampler_texture(0, texture) - surface = texture.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE) - - expected_rgba = generate_data(surface) + expected_rgba = generate_data(texture.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE)) cbuf_tex = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, width, - height) + height, + usage = PIPE_TEXTURE_USAGE_RENDER_TARGET) # drawing dest - cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE) + cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE|PIPE_BUFFER_USAGE_GPU_READ) fb = Framebuffer() - fb.width = cbuf.width - fb.height = cbuf.height + fb.width = width + fb.height = height fb.num_cbufs = 1 fb.set_cbuf(0, cbuf) + ctx.surface_clear(cbuf, 0x00000000) ctx.set_framebuffer(fb) # vertex shader @@ -164,7 +170,7 @@ class TextureTest(Test): ''') fs.dump() ctx.set_fragment_shader(fs) - + nverts = 4 nattrs = 2 verts = FloatArray(nverts * nattrs * 4) @@ -207,23 +213,21 @@ class TextureTest(Test): verts[30] = 0.0 verts[31] = 0.0 - ctx.surface_clear(cbuf, 0x00000000) - ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN, nverts, nattrs, verts) ctx.flush() - - rgba = FloatArray(surface.height*surface.width*4) - cbuf.get_tile_rgba(x, y, w, h, rgba) + rgba = FloatArray(height*width*4) + + cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ).get_tile_rgba(x, y, w, h, rgba) compare_rgba(width, height, rgba, expected_rgba) - #save_image("texture1.png", surface) - #save_image("texture2.png", cbuf) + show_image(texture.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ), + cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ)) def main(): -- cgit v1.2.3 From 3392bcaaa823bd791e8d7e4c5a7ce013831899bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 15 Jul 2008 17:57:48 +0900 Subject: python: Cleanup. --- src/gallium/state_trackers/python/samples/tri.py | 8 ------ src/gallium/state_trackers/python/tests/base.py | 31 +++++++++++----------- src/gallium/state_trackers/python/tests/texture.py | 14 +++++----- 3 files changed, 23 insertions(+), 30 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py index e5044a0245..3665922929 100644 --- a/src/gallium/state_trackers/python/samples/tri.py +++ b/src/gallium/state_trackers/python/samples/tri.py @@ -143,24 +143,16 @@ def test(dev): cbuf = dev.texture_create(PIPE_FORMAT_X8R8G8B8_UNORM, width, height, usage=PIPE_TEXTURE_USAGE_DISPLAY_TARGET) - zbuf = dev.texture_create(PIPE_FORMAT_X8Z24_UNORM, - width, height, - usage=PIPE_TEXTURE_USAGE_DEPTH_STENCIL) _cbuf = cbuf.get_surface(usage = PIPE_BUFFER_USAGE_GPU_READ|PIPE_BUFFER_USAGE_GPU_WRITE) - _zsbuf = zbuf.get_surface(usage = PIPE_BUFFER_USAGE_GPU_READ|PIPE_BUFFER_USAGE_GPU_WRITE) fb = Framebuffer() fb.width = width fb.height = height fb.num_cbufs = 1 fb.set_cbuf(0, _cbuf) - fb.set_zsbuf(_zsbuf) ctx.set_framebuffer(fb) _cbuf.clear_value = 0x00000000 - _zsbuf.clear_value = 0x00ffffff ctx.surface_clear(_cbuf, _cbuf.clear_value) - ctx.surface_clear(_zsbuf, _zsbuf.clear_value) del _cbuf - del _zsbuf # vertex shader vs = Shader(''' diff --git a/src/gallium/state_trackers/python/tests/base.py b/src/gallium/state_trackers/python/tests/base.py index 185a59996e..d5d6114a45 100644 --- a/src/gallium/state_trackers/python/tests/base.py +++ b/src/gallium/state_trackers/python/tests/base.py @@ -37,28 +37,25 @@ for name, value in globals().items(): formats[value] = name -def make_image(surface): - pixels = FloatArray(surface.height*surface.width*4) - surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) - +def make_image(width, height, rgba): import Image outimage = Image.new( mode='RGB', - size=(surface.width, surface.height), + size=(width, height), color=(0,0,0)) outpixels = outimage.load() - for y in range(0, surface.height): - for x in range(0, surface.width): - offset = (y*surface.width + x)*4 - r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] + for y in range(0, height): + for x in range(0, width): + offset = (y*width + x)*4 + r, g, b, a = [int(rgba[offset + ch]*255) for ch in range(4)] outpixels[x, y] = r, g, b return outimage -def save_image(filename, surface): - outimage = make_image(surface) +def save_image(width, height, rgba, filename): + outimage = make_image(width, height, rgba) outimage.save(filename, "PNG") -def show_image(*surfaces): +def show_image(width, height, **rgbas): import Tkinter as tk from PIL import Image, ImageTk @@ -67,15 +64,17 @@ def show_image(*surfaces): x = 64 y = 64 - for i in range(len(surfaces)): - surface = surfaces[i] - outimage = make_image(surface) + labels = rgbas.keys() + labels.sort() + for i in range(len(labels)): + label = labels[i] + outimage = make_image(width, height, rgbas[label]) if i: window = tk.Toplevel(root) else: window = root - window.title('Image %u' % (i+1)) + window.title(label) image1 = ImageTk.PhotoImage(outimage) w = image1.width() h = image1.height() diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index 84ceebb169..6a5ffb38b9 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -61,8 +61,8 @@ class TextureTest(Test): def run(self): dev = self.dev - format = PIPE_FORMAT_A8R8G8B8_UNORM - #format = PIPE_FORMAT_DXT1_RGB + #format = PIPE_FORMAT_A8R8G8B8_UNORM + format = PIPE_FORMAT_DXT1_RGB if not dev.is_format_supported(format, PIPE_TEXTURE): pass @@ -130,20 +130,21 @@ class TextureTest(Test): expected_rgba = generate_data(texture.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE)) + # framebuffer cbuf_tex = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, width, height, usage = PIPE_TEXTURE_USAGE_RENDER_TARGET) - # drawing dest cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE|PIPE_BUFFER_USAGE_GPU_READ) fb = Framebuffer() fb.width = width fb.height = height fb.num_cbufs = 1 fb.set_cbuf(0, cbuf) - ctx.surface_clear(cbuf, 0x00000000) ctx.set_framebuffer(fb) + ctx.surface_clear(cbuf, 0x00000000) + del fb # vertex shader vs = Shader(''' @@ -220,14 +221,15 @@ class TextureTest(Test): ctx.flush() + del ctx + rgba = FloatArray(height*width*4) cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ).get_tile_rgba(x, y, w, h, rgba) compare_rgba(width, height, rgba, expected_rgba) - show_image(texture.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ), - cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ)) + show_image(width, height, Result=rgba, Expected=expected_rgba) def main(): -- cgit v1.2.3 From f006358d56e6b24c3e32665e088d5ee11877ec2c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 15 Jul 2008 13:27:44 -0600 Subject: gallium: added some sanity check assertions --- src/gallium/drivers/softpipe/sp_setup.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index e99df9d018..4321ca46f4 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -941,6 +941,11 @@ setup_line(struct setup_context *setup, print_vertex(setup, v1); #endif + assert(v0[0][0] < 1.0e9); + assert(v0[0][1] < 1.0e9); + assert(v1[0][0] < 1.0e9); + assert(v1[0][1] < 1.0e9); + if (setup->softpipe->no_rast) return; -- cgit v1.2.3 From 0c2c0a862c40c0ed39a9ac52344d22c8a7c8b100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 16 Jul 2008 14:10:10 +0900 Subject: softpipe: DXT formats not really supported. --- src/gallium/drivers/softpipe/sp_screen.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index e9926bf41f..f6193bfaf9 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -119,11 +119,16 @@ softpipe_is_format_supported( struct pipe_screen *screen, { switch (type) { case PIPE_TEXTURE: - /* softpipe supports all texture formats */ - return TRUE; case PIPE_SURFACE: - /* softpipe supports all (off-screen) surface formats */ - return TRUE; + switch(format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: + return FALSE; + default: + return TRUE; + } default: assert(0); return FALSE; -- cgit v1.2.3 From fbf0f6bd4d6ec20ead2797042866e6e910cd0f77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 16 Jul 2008 14:10:35 +0900 Subject: gallium: Add pf_is_compressed utility function. --- src/gallium/include/pipe/p_format.h | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index a2c6155d01..fefb8fdf1b 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -519,27 +519,18 @@ pf_get_nblocks(const struct pipe_format_block *block, unsigned width, unsigned h return pf_get_nblocksx(block, width)*pf_get_nblocksy(block, height); } -static INLINE void -pipe_rect_to_blocks(const struct pipe_format_block *block, - unsigned *width, unsigned *height, - unsigned *src_x, unsigned *src_y, - unsigned *dst_x, unsigned *dst_y) +static INLINE boolean +pf_is_compressed( enum pipe_format format ) { - assert(block->size > 0); - assert(block->width > 0); - assert(block->height > 0); - if(width) - *width = pf_get_nblocksx(block, *width); - if(height) - *height = pf_get_nblocksy(block, *height); - if(src_x) - *src_x /= block->width; - if(src_y) - *src_y /= block->height; - if(dst_x) - *dst_x /= block->width; - if(dst_y) - *dst_y /= block->height; + switch (format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: + return TRUE; + default: + return FALSE; + } } #ifdef __cplusplus -- cgit v1.2.3 From 61c4de53c360fd2893b0490075d760f2ca3bac33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 16 Jul 2008 14:10:51 +0900 Subject: python: Silent debug output. --- src/gallium/state_trackers/python/gallium.i | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 2f1d8b22fb..fe0afb18a9 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -177,7 +177,6 @@ struct st_context { unsigned usage = 0 ) { struct pipe_texture templat; - struct pipe_texture *texture; memset(&templat, 0, sizeof(templat)); templat.format = format; pf_get_block(templat.format, &templat.block); @@ -187,9 +186,7 @@ struct st_context { templat.last_level = last_level; templat.target = target; templat.tex_usage = usage; - texture = $self->screen->texture_create($self->screen, &templat); - fprintf(stderr, "creating texture %p\n", texture); - return texture; + return $self->screen->texture_create($self->screen, &templat); } struct pipe_buffer * @@ -400,7 +397,6 @@ error1: ~pipe_texture() { struct pipe_texture *ptr = $self; - fprintf(stderr, "destroying texture %p\n", $self); pipe_texture_reference(&ptr, NULL); } @@ -409,10 +405,7 @@ error1: get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0, unsigned usage=0 ) { struct pipe_screen *screen = $self->screen; - struct pipe_surface *surface; - surface = screen->get_tex_surface(screen, $self, face, level, zslice, usage); - fprintf(stderr, "creating surface %p\n", surface); - return surface; + return screen->get_tex_surface(screen, $self, face, level, zslice, usage); } }; @@ -422,7 +415,6 @@ error1: ~pipe_surface() { struct pipe_surface *ptr = $self; - fprintf(stderr, "destroying surface %p\n", $self); pipe_surface_reference(&ptr, NULL); } -- cgit v1.2.3 From 70b1ff9ff39ca29bdbd25b31ebb183eea683d625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 16 Jul 2008 14:11:45 +0900 Subject: python: Expand the texture test suit to cover one YUV and one DXT format. --- src/gallium/state_trackers/python/tests/base.py | 6 +++- src/gallium/state_trackers/python/tests/data.py | 31 +++++++++++------ src/gallium/state_trackers/python/tests/texture.py | 40 +++++++++++++++------- 3 files changed, 53 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/tests/base.py b/src/gallium/state_trackers/python/tests/base.py index d5d6114a45..d83abdfa76 100644 --- a/src/gallium/state_trackers/python/tests/base.py +++ b/src/gallium/state_trackers/python/tests/base.py @@ -93,6 +93,9 @@ class Test: def __init__(self): pass + def description(self): + raise NotImplementedError + def run(self): raise NotImplementedError @@ -111,7 +114,8 @@ class TestSuite(Test): def run(self): for test in self.tests: - self.test.run() + print "Running %s..." % test.description() + test.run() class TextureTemplate: diff --git a/src/gallium/state_trackers/python/tests/data.py b/src/gallium/state_trackers/python/tests/data.py index 2287884285..3c1cda59d7 100644 --- a/src/gallium/state_trackers/python/tests/data.py +++ b/src/gallium/state_trackers/python/tests/data.py @@ -211,7 +211,6 @@ dxt1_rgba = [ def generate_data_compressed(surface, blocks): - pixels, block = blocks[0] stride = surface.nblocksx*surface.block.size size = surface.nblocksy*stride @@ -219,19 +218,23 @@ def generate_data_compressed(surface, blocks): raw = ByteArray(size) rgba = FloatArray(surface.height*surface.width*4) - for y in range(0, surface.nblocksx): - for x in range(0, surface.nblocksy): + for yj in range(0, surface.nblocksy): + for xj in range(0, surface.nblocksx): + pixels, block = blocks[random.randint(0, len(blocks) - 1)] - offset = (y*surface.nblocksx + x)*surface.block.width + offset = (yj*surface.nblocksx + xj)*surface.block.size for i in range(0, surface.block.size): raw[offset + i] = block[i] - for j in range(0, surface.block.width): - for i in range(0, surface.block.height): - offset = ((y*surface.block.height + j)*surface.width + x*surface.block.width + i)*4 - pixel = pixels[j*surface.block.width + i] - for ch in range(0, 4): - rgba[offset + ch] = float(pixel[ch])/255.0 + for yi in range(0, surface.block.height): + for xi in range(0, surface.block.width): + y = yj*surface.block.height + yi + x = xj*surface.block.width + xi + if y < surface.height and x < surface.width: + offset = (y*surface.width + x)*4 + pixel = pixels[yi*surface.block.width + xi] + for ch in range(0, 4): + rgba[offset + ch] = float(pixel[ch])/255.0 surface.put_tile_raw(0, 0, surface.width, surface.height, raw, stride) @@ -252,6 +255,14 @@ def generate_data_simple(surface): surface.get_tile_rgba(0, 0, surface.width, surface.height, rgba) + if surface.format in (PIPE_FORMAT_YCBCR, PIPE_FORMAT_YCBCR_REV): + # normalize + for y in range(0, surface.height): + for x in range(0, surface.width): + for ch in range(4): + offset = (y*surface.width + x)*4 + ch + rgba[offset] = min(max(rgba[offset], 0.0), 1.0) + return rgba diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index 6a5ffb38b9..7812d8aebf 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -33,7 +33,7 @@ from base import * from data import generate_data -def compare_rgba(width, height, rgba1, rgba2, tol=0.01): +def compare_rgba(width, height, rgba1, rgba2, tol=4.0/256): errors = 0 for y in range(0, height): for x in range(0, width): @@ -58,22 +58,25 @@ class TextureTest(Test): Test.__init__(self) self.__dict__.update(kargs) + def description(self): + return "%s %ux%u" % (formats[self.format], self.width, self.height) + def run(self): dev = self.dev - #format = PIPE_FORMAT_A8R8G8B8_UNORM - format = PIPE_FORMAT_DXT1_RGB + format = self.format + width = self.width + height = self.height if not dev.is_format_supported(format, PIPE_TEXTURE): - pass + print "SKIP" + return if not dev.is_format_supported(format, PIPE_SURFACE): - pass + print "SKIP" + return ctx = dev.context_create() - width = 64 - height = 64 - # disabled blending/masking blend = Blend() blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE @@ -169,7 +172,7 @@ class TextureTest(Test): 0:TEX OUT[0], IN[0], SAMP[0], 2D 1:END ''') - fs.dump() + #fs.dump() ctx.set_fragment_shader(fs) nverts = 4 @@ -227,15 +230,26 @@ class TextureTest(Test): cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ).get_tile_rgba(x, y, w, h, rgba) - compare_rgba(width, height, rgba, expected_rgba) + if compare_rgba(width, height, rgba, expected_rgba): + print "OK" + else: + print "FAIL" - show_image(width, height, Result=rgba, Expected=expected_rgba) + show_image(width, height, Result=rgba, Expected=expected_rgba) + #save_image(width, height, rgba, "result.png") + #save_image(width, height, expected_rgba, "expected.png") + sys.exit(0) def main(): dev = Device() - test = TextureTest(dev = dev) - test.run() + suite = TestSuite() + formats = [PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_YCBCR, PIPE_FORMAT_DXT1_RGB] + sizes = [64, 32, 16, 8, 4, 2] + for format in formats: + for size in sizes: + suite.add_test(TextureTest(dev=dev, format=format, width=size, height=size)) + suite.run() if __name__ == '__main__': -- cgit v1.2.3 From 78d18bb690d47eba6d13f8f154e64f1c33ef29fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 16 Jul 2008 19:36:36 +0900 Subject: gallium: ycbcr_get_tile_rgba allow reading an uneven number of pixels from yuv surfaces. --- src/gallium/auxiliary/util/p_tile.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 1a1a2d96cc..580a95568e 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -632,13 +632,10 @@ ycbcr_get_tile_rgba(ushort *src, const float scale = 1.0f / 255.0f; unsigned i, j; - /* we're assuming we're being asked for an even number of texels */ - assert((w & 1) == 0); - for (i = 0; i < h; i++) { float *pRow = p; /* do two texels at a time */ - for (j = 0; j < w; j += 2, src += 2) { + for (j = 0; j < (w & ~1); j += 2, src += 2) { const ushort t0 = src[0]; const ushort t1 = src[1]; const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ @@ -676,6 +673,33 @@ ycbcr_get_tile_rgba(ushort *src, pRow += 4; } + /* do the last texel */ + if (w & 1) { + const ushort t0 = src[0]; + const ushort t1 = src[1]; + const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ + ubyte cb, cr; + float r, g, b; + + if (rev) { + cb = t1 & 0xff; /* chroma U */ + cr = t0 & 0xff; /* chroma V */ + } + else { + cb = t0 & 0xff; /* chroma U */ + cr = t1 & 0xff; /* chroma V */ + } + + /* even pixel: y0,cr,cb */ + r = 1.164f * (y0-16) + 1.596f * (cr-128); + g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128); + b = 1.164f * (y0-16) + 2.018f * (cb-128); + pRow[0] = r * scale; + pRow[1] = g * scale; + pRow[2] = b * scale; + pRow[3] = 1.0f; + pRow += 4; + } p += dst_stride; } } -- cgit v1.2.3 From 32fe752d31a07293ad68cccb2fffbbfef32ab449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 16 Jul 2008 19:36:59 +0900 Subject: python: Test all miplevels. --- src/gallium/state_trackers/python/tests/base.py | 87 ++++++++++++++++++---- src/gallium/state_trackers/python/tests/texture.py | 72 +++++++++++------- 2 files changed, 116 insertions(+), 43 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/tests/base.py b/src/gallium/state_trackers/python/tests/base.py index d83abdfa76..c50abf7f69 100644 --- a/src/gallium/state_trackers/python/tests/base.py +++ b/src/gallium/state_trackers/python/tests/base.py @@ -27,6 +27,12 @@ ########################################################################## +"""Base classes for tests. + +Loosely inspired on Python's unittest module. +""" + + from gallium import * @@ -87,17 +93,54 @@ def show_image(width, height, **rgbas): root.mainloop() +class TestFailure(Exception): -class Test: + pass + +class TestSkip(Exception): + pass + + +class Test: + def __init__(self): pass + + def _run(self, result): + raise NotImplementedError + def run(self): + result = TestResult() + self._run(result) + result.summary() + + +class TestCase(Test): + + def __init__(self, dev, **kargs): + Test.__init__(self) + self.dev = dev + self.__dict__.update(kargs) + def description(self): raise NotImplementedError - def run(self): + def test(self): raise NotImplementedError + + def _run(self, result): + result.test_start(self) + try: + self.test() + except KeyboardInterrupt: + raise + except TestSkip: + result.test_skipped(self) + except TestFailure: + result.test_failed(self) + else: + result.test_passed(self) class TestSuite(Test): @@ -112,21 +155,35 @@ class TestSuite(Test): def add_test(self, test): self.tests.append(test) - def run(self): + def _run(self, result): for test in self.tests: - print "Running %s..." % test.description() - test.run() + test._run(result) -class TextureTemplate: +class TestResult: - def __init__(self, format=PIPE_FORMAT_R8G8B8A8_UNORM, width=1, height=1, depth=1, last_level=0, target=PIPE_TEXTURE_2D): - self.format = format - self.width = width - self.height = height - self.depth = depth - self.last_level = last_level - self.target = target - - + def __init__(self): + self.tests = 0 + self.passed = 0 + self.skipped = 0 + self.failed = 0 + + def test_start(self, test): + self.tests += 1 + print "Running %s..." % test.description() + + def test_passed(self, test): + self.passed += 1 + print "PASS" + + def test_skipped(self, test): + self.skipped += 1 + print "SKIP" + + def test_failed(self): + self.failed += 1 + print "FAIL" + def summary(self): + print "%u tests, %u passed, %u skipped, %u failed" % (self.tests, self.passed, self.skipped, self.failed) + \ No newline at end of file diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index 7812d8aebf..7c7245e65c 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -52,30 +52,39 @@ def compare_rgba(width, height, rgba1, rgba2, tol=4.0/256): return errors == 0 -class TextureTest(Test): - - def __init__(self, **kargs): - Test.__init__(self) - self.__dict__.update(kargs) +def lods(*dims): + size = max(dims) + lods = 0 + while size: + lods += 1 + size >>= 1 + return lods + + +def minify(dims, level = 1): + return [max(dim>>level, 1) for dim in dims] + +class TextureTest(TestCase): + def description(self): - return "%s %ux%u" % (formats[self.format], self.width, self.height) - - def run(self): + return "%s %ux%u level=%u" % (formats[self.format], self.width, self.height, self.level) + + def test(self): dev = self.dev format = self.format width = self.width height = self.height + level = self.level + + levels = lods(width, height) + if not dev.is_format_supported(format, PIPE_TEXTURE): - print "SKIP" - return - if not dev.is_format_supported(format, PIPE_SURFACE): - print "SKIP" - return + raise TestSkip - ctx = dev.context_create() + ctx = self.dev.context_create() # disabled blending/masking blend = Blend() @@ -123,15 +132,20 @@ class TextureTest(Test): sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST sampler.normalized_coords = 1 + sampler.min_lod = level + sampler.max_lod = level ctx.set_sampler(0, sampler) # texture texture = dev.texture_create(format, width, - height) + height, + last_level = levels - 1) ctx.set_sampler_texture(0, texture) - expected_rgba = generate_data(texture.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE)) + expected_rgba = generate_data(texture.get_surface( + usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE, + level = level)) # framebuffer cbuf_tex = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, @@ -181,8 +195,7 @@ class TextureTest(Test): x = 0 y = 0 - w = width - h = height + w, h = minify((width, height), level) verts[ 0] = x # x1 verts[ 1] = y # y1 @@ -223,32 +236,35 @@ class TextureTest(Test): verts) ctx.flush() - - del ctx - - rgba = FloatArray(height*width*4) + + rgba = FloatArray(h*w*4) cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ).get_tile_rgba(x, y, w, h, rgba) - if compare_rgba(width, height, rgba, expected_rgba): - print "OK" - else: - print "FAIL" + if not compare_rgba(w, h, rgba, expected_rgba): - show_image(width, height, Result=rgba, Expected=expected_rgba) + show_image(w, h, Result=rgba, Expected=expected_rgba) #save_image(width, height, rgba, "result.png") #save_image(width, height, expected_rgba, "expected.png") sys.exit(0) + + raise TestFailure + + del ctx + def main(): dev = Device() suite = TestSuite() formats = [PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_YCBCR, PIPE_FORMAT_DXT1_RGB] + #formats = [PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_DXT1_RGB] sizes = [64, 32, 16, 8, 4, 2] for format in formats: for size in sizes: - suite.add_test(TextureTest(dev=dev, format=format, width=size, height=size)) + levels = lods(size) + for level in range(levels): + suite.add_test(TextureTest(dev=dev, format=format, width=size, height=size, level=level)) suite.run() -- cgit v1.2.3 From 1049e65240539228f64a91cc7b55af37bbd0417b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 16 Jul 2008 23:26:23 +0900 Subject: python: Set PIPE_TEX_MIPFILTER_NONE by default. --- src/gallium/state_trackers/python/st_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index 9e625ae2e0..2e53a83eea 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -192,7 +192,7 @@ st_context_create(struct st_device *st_dev) sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST; sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; sampler.normalized_coords = 1; -- cgit v1.2.3 From 7f32834df3c428fa283e966982926c94630b1b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 16 Jul 2008 23:27:15 +0900 Subject: python/tests: Extend the texture tests to cover cube maps. --- src/gallium/state_trackers/python/tests/base.py | 8 +- src/gallium/state_trackers/python/tests/texture.py | 215 +++++++++++++++------ 2 files changed, 162 insertions(+), 61 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/tests/base.py b/src/gallium/state_trackers/python/tests/base.py index c50abf7f69..8477aa5fc9 100644 --- a/src/gallium/state_trackers/python/tests/base.py +++ b/src/gallium/state_trackers/python/tests/base.py @@ -53,7 +53,7 @@ def make_image(width, height, rgba): for y in range(0, height): for x in range(0, width): offset = (y*width + x)*4 - r, g, b, a = [int(rgba[offset + ch]*255) for ch in range(4)] + r, g, b, a = [int(min(max(rgba[offset + ch], 0.0), 1.0)*255) for ch in range(4)] outpixels[x, y] = r, g, b return outimage @@ -167,6 +167,7 @@ class TestResult: self.passed = 0 self.skipped = 0 self.failed = 0 + self.failed_descriptions = [] def test_start(self, test): self.tests += 1 @@ -180,10 +181,13 @@ class TestResult: self.skipped += 1 print "SKIP" - def test_failed(self): + def test_failed(self, test): self.failed += 1 + self.failed_descriptions.append(test.description()) print "FAIL" def summary(self): print "%u tests, %u passed, %u skipped, %u failed" % (self.tests, self.passed, self.skipped, self.failed) + for description in self.failed_descriptions: + print " %s" % description \ No newline at end of file diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index 7c7245e65c..448bdbcd3e 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -33,10 +33,11 @@ from base import * from data import generate_data -def compare_rgba(width, height, rgba1, rgba2, tol=4.0/256): +def compare_rgba(width, height, rgba1, rgba2, tol=4.0/256, ratio=0.85): errors = 0 for y in range(0, height): for x in range(0, width): + differs = 0 for ch in range(4): offset = (y*width + x)*4 + ch v1 = rgba1[offset] @@ -44,12 +45,14 @@ def compare_rgba(width, height, rgba1, rgba2, tol=4.0/256): if abs(v1 - v2) > tol: if errors == 0: sys.stderr.write("x=%u, y=%u, ch=%u differ: %f vs %f\n" % (x, y, ch, v1, v2)) - if errors == 1: + if errors == 1 and ch == 0: sys.stderr.write("...\n") - errors += 1 + differs = 1 + errors += differs + total = height*width if errors: - sys.stderr.write("%u out of %u pixels differ\n" % (errors/4, height*width)) - return errors == 0 + sys.stderr.write("%u out of %u pixels differ\n" % (errors, total)) + return float(total - errors)/float(total) >= ratio def lods(*dims): @@ -65,22 +68,87 @@ def minify(dims, level = 1): return [max(dim>>level, 1) for dim in dims] +def tex_coords(texture, face, level, zslice): + st = [ + [0.0, 0.0], + [1.0, 0.0], + [1.0, 1.0], + [0.0, 1.0], + ] + + if texture.target == PIPE_TEXTURE_2D: + return [[s, t, 0.0] for s, t in st] + elif texture.target == PIPE_TEXTURE_3D: + assert 0 + elif texture.target == PIPE_TEXTURE_CUBE: + result = [] + for s, t in st: + # See http://developer.nvidia.com/object/cube_map_ogl_tutorial.html + sc = 2.0*s - 1.0 + tc = 2.0*t - 1.0 + if face == PIPE_TEX_FACE_POS_X: + rx = 1.0 + ry = -tc + rz = -sc + if face == PIPE_TEX_FACE_NEG_X: + rx = -1.0 + ry = -tc + rz = sc + if face == PIPE_TEX_FACE_POS_Y: + rx = sc + ry = 1.0 + rz = tc + if face == PIPE_TEX_FACE_NEG_Y: + rx = sc + ry = -1.0 + rz = -tc + if face == PIPE_TEX_FACE_POS_Z: + rx = sc + ry = -tc + rz = 1.0 + if face == PIPE_TEX_FACE_NEG_Z: + rx = -sc + ry = -tc + rz = -1.0 + result.append([rx, ry, rz]) + return result + + class TextureTest(TestCase): def description(self): - return "%s %ux%u level=%u" % (formats[self.format], self.width, self.height, self.level) + target = { + PIPE_TEXTURE_1D: "1d", + PIPE_TEXTURE_2D: "2d", + PIPE_TEXTURE_3D: "3d", + PIPE_TEXTURE_CUBE: "cube", + }[self.target] + format = formats[self.format] + if self.target == PIPE_TEXTURE_CUBE: + face = { + PIPE_TEX_FACE_POS_X: "+x", + PIPE_TEX_FACE_NEG_X: "-x", + PIPE_TEX_FACE_POS_Y: "+y", + PIPE_TEX_FACE_NEG_Y: "-y", + PIPE_TEX_FACE_POS_Z: "+z", + PIPE_TEX_FACE_NEG_Z: "-z", + }[self.face] + else: + face = "" + return "%s %s %ux%u %s level=%u" % (target, format, self.width, self.height, face, self.level) def test(self): dev = self.dev + target = self.target format = self.format width = self.width height = self.height level = self.level + face = self.face levels = lods(width, height) - if not dev.is_format_supported(format, PIPE_TEXTURE): raise TestSkip @@ -128,23 +196,25 @@ class TextureTest(TestCase): sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST sampler.normalized_coords = 1 - sampler.min_lod = level - sampler.max_lod = level + sampler.min_lod = 0 + sampler.max_lod = PIPE_MAX_TEXTURE_LEVELS - 1 ctx.set_sampler(0, sampler) # texture - texture = dev.texture_create(format, - width, - height, + texture = dev.texture_create(target=target, + format=format, + width=width, + height=height, last_level = levels - 1) ctx.set_sampler_texture(0, texture) expected_rgba = generate_data(texture.get_surface( usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE, + face = face, level = level)) # framebuffer @@ -178,14 +248,20 @@ class TextureTest(TestCase): ctx.set_vertex_shader(vs) # fragment shader + op = { + PIPE_TEXTURE_1D: "1D", + PIPE_TEXTURE_2D: "2D", + PIPE_TEXTURE_3D: "3D", + PIPE_TEXTURE_CUBE: "CUBE", + }[target] fs = Shader(''' FRAG1.1 - DCL IN[0], GENERIC[0], PERSPECTIVE + DCL IN[0], GENERIC[0], LINEAR DCL OUT[0], COLOR, CONSTANT DCL SAMP[0], CONSTANT - 0:TEX OUT[0], IN[0], SAMP[0], 2D + 0:TEX OUT[0], IN[0], SAMP[0], %s 1:END - ''') + ''' % op) #fs.dump() ctx.set_fragment_shader(fs) @@ -197,38 +273,25 @@ class TextureTest(TestCase): y = 0 w, h = minify((width, height), level) - verts[ 0] = x # x1 - verts[ 1] = y # y1 - verts[ 2] = 0.0 # z1 - verts[ 3] = 1.0 # w1 - verts[ 4] = 0.0 # s1 - verts[ 5] = 0.0 # t - verts[ 6] = 0.0 - verts[ 7] = 0.0 - verts[ 8] = x + w # x2 - verts[ 9] = y # y2 - verts[10] = 0.0 # z2 - verts[11] = 1.0 # w2 - verts[12] = 1.0 # s2 - verts[13] = 0.0 # t2 - verts[14] = 0.0 - verts[15] = 0.0 - verts[16] = x + w # x3 - verts[17] = y + h # y3 - verts[18] = 0.0 # z3 - verts[19] = 1.0 # w3 - verts[20] = 1.0 # s3 - verts[21] = 1.0 # t3 - verts[22] = 0.0 - verts[23] = 0.0 - verts[24] = x # x4 - verts[25] = y + h # y4 - verts[26] = 0.0 # z4 - verts[27] = 1.0 # w4 - verts[28] = 0.0 # s4 - verts[29] = 1.0 # t4 - verts[30] = 0.0 - verts[31] = 0.0 + pos = [ + [x, y], + [x+w, y], + [x+w, y+h], + [x, y+h], + ] + + tex = tex_coords(texture, face, level, zslice=0) + + for i in range(0, 4): + j = 8*i + verts[j + 0] = pos[i][0] # x + verts[j + 1] = pos[i][1] # y + verts[j + 2] = 0.0 # z + verts[j + 3] = 1.0 # w + verts[j + 4] = tex[i][0] # s + verts[j + 5] = tex[i][1] # r + verts[j + 6] = tex[i][2] # q + verts[j + 7] = 1.0 ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN, nverts, @@ -243,10 +306,10 @@ class TextureTest(TestCase): if not compare_rgba(w, h, rgba, expected_rgba): - show_image(w, h, Result=rgba, Expected=expected_rgba) - #save_image(width, height, rgba, "result.png") - #save_image(width, height, expected_rgba, "expected.png") - sys.exit(0) + #show_image(w, h, Result=rgba, Expected=expected_rgba) + #save_image(w, h, rgba, "result.png") + #save_image(w, h, expected_rgba, "expected.png") + #sys.exit(0) raise TestFailure @@ -257,14 +320,48 @@ class TextureTest(TestCase): def main(): dev = Device() suite = TestSuite() - formats = [PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_YCBCR, PIPE_FORMAT_DXT1_RGB] - #formats = [PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_DXT1_RGB] + + targets = [] + targets += [PIPE_TEXTURE_2D] + targets += [PIPE_TEXTURE_CUBE] + + formats = [] + formats += [PIPE_FORMAT_A8R8G8B8_UNORM] + formats += [PIPE_FORMAT_R5G6B5_UNORM] + formats += [PIPE_FORMAT_L8_UNORM] + formats += [PIPE_FORMAT_YCBCR] + formats += [PIPE_FORMAT_DXT1_RGB] + sizes = [64, 32, 16, 8, 4, 2] - for format in formats: - for size in sizes: - levels = lods(size) - for level in range(levels): - suite.add_test(TextureTest(dev=dev, format=format, width=size, height=size, level=level)) + #sizes = [16] + + for target in targets: + for format in formats: + for size in sizes: + if target == PIPE_TEXTURE_CUBE: + faces = [ + PIPE_TEX_FACE_POS_X, + PIPE_TEX_FACE_NEG_X, + PIPE_TEX_FACE_POS_Y, + PIPE_TEX_FACE_NEG_Y, + PIPE_TEX_FACE_POS_Z, + PIPE_TEX_FACE_NEG_Z, + ] + else: + faces = [0] + for face in faces: + levels = lods(size) + for level in range(levels): + test = TextureTest( + dev=dev, + target=target, + format=format, + width=size, + height=size, + face=face, + level=level, + ) + suite.add_test(test) suite.run() -- cgit v1.2.3 From f610deed37dc09922eaef1c55e3d4afe8aaa7327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 17 Jul 2008 08:21:58 +0900 Subject: python/tests: Cover all last_level combinations. --- src/gallium/state_trackers/python/tests/texture.py | 43 +++++++++++++--------- 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index 448bdbcd3e..edaa2b8b26 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -135,7 +135,11 @@ class TextureTest(TestCase): }[self.face] else: face = "" - return "%s %s %ux%u %s level=%u" % (target, format, self.width, self.height, face, self.level) + return "%s %s %ux%u last_level=%u %s level=%u" % ( + target, format, + self.width, self.height, + self.last_level, face, self.level, + ) def test(self): dev = self.dev @@ -144,11 +148,10 @@ class TextureTest(TestCase): format = self.format width = self.width height = self.height + last_level = self.last_level level = self.level face = self.face - levels = lods(width, height) - if not dev.is_format_supported(format, PIPE_TEXTURE): raise TestSkip @@ -209,14 +212,15 @@ class TextureTest(TestCase): format=format, width=width, height=height, - last_level = levels - 1) - ctx.set_sampler_texture(0, texture) + last_level = last_level) expected_rgba = generate_data(texture.get_surface( usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE, face = face, level = level)) + ctx.set_sampler_texture(0, texture) + # framebuffer cbuf_tex = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, width, @@ -332,8 +336,8 @@ def main(): formats += [PIPE_FORMAT_YCBCR] formats += [PIPE_FORMAT_DXT1_RGB] - sizes = [64, 32, 16, 8, 4, 2] - #sizes = [16] + sizes = [64, 32, 16, 8, 4, 2, 1] + #sizes = [64] for target in targets: for format in formats: @@ -347,21 +351,24 @@ def main(): PIPE_TEX_FACE_POS_Z, PIPE_TEX_FACE_NEG_Z, ] + #faces = [PIPE_TEX_FACE_NEG_X] else: faces = [0] for face in faces: levels = lods(size) - for level in range(levels): - test = TextureTest( - dev=dev, - target=target, - format=format, - width=size, - height=size, - face=face, - level=level, - ) - suite.add_test(test) + for last_level in range(levels): + for level in range(0, last_level + 1): + test = TextureTest( + dev=dev, + target=target, + format=format, + width=size, + height=size, + face=face, + last_level = last_level, + level=level, + ) + suite.add_test(test) suite.run() -- cgit v1.2.3 From d398e1360d5c1c0f44a4ba9cd167c39a29ce8254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 17 Jul 2008 10:27:10 +0900 Subject: python: Reimplement tile comparison in C to speed up tests. --- src/gallium/state_trackers/python/gallium.i | 48 ++++++++++++++++++---- src/gallium/state_trackers/python/tests/texture.py | 20 +++++---- 2 files changed, 53 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index fe0afb18a9..1c207a41b9 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -425,23 +425,23 @@ error1: void unmap( void ); void - get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, unsigned char *p, unsigned stride) { - pipe_get_tile_raw($self, x, y, w, h, p, stride); + get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, unsigned char *raw, unsigned stride) { + pipe_get_tile_raw($self, x, y, w, h, raw, stride); } void - put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned char *p, unsigned stride) { - pipe_put_tile_raw($self, x, y, w, h, p, stride); + put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned char *raw, unsigned stride) { + pipe_put_tile_raw($self, x, y, w, h, raw, stride); } void - get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *p) { - pipe_get_tile_rgba($self, x, y, w, h, p); + get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *rgba) { + pipe_get_tile_rgba($self, x, y, w, h, rgba); } void - put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *p) { - pipe_put_tile_rgba($self, x, y, w, h, p); + put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba) { + pipe_put_tile_rgba($self, x, y, w, h, rgba); } void @@ -454,6 +454,38 @@ error1: pipe_put_tile_z($self, x, y, w, h, z); } + unsigned + compare_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba, float tol = 0.0) + { + float *rgba2; + const float *p1; + const float *p2; + unsigned i, j, n; + + rgba2 = MALLOC(h*w*4*sizeof(float)); + if(!rgba2) + return ~0; + + pipe_get_tile_rgba($self, x, y, w, h, rgba2); + + p1 = rgba; + p2 = rgba2; + n = 0; + for(i = h*w; i; --i) { + unsigned differs = 0; + for(j = 4; j; --j) { + float delta = *p2++ - *p1++; + if (delta < -tol || delta > tol) + differs = 1; + } + n += differs; + } + + FREE(rgba2); + + return n; + } + }; diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index edaa2b8b26..3d76953126 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -304,15 +304,21 @@ class TextureTest(TestCase): ctx.flush() - rgba = FloatArray(h*w*4) - - cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ).get_tile_rgba(x, y, w, h, rgba) + cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ) + + total = h*w + different = cbuf.compare_tile_rgba(x, y, w, h, expected_rgba, tol=4.0/256) + if different: + sys.stderr.write("%u out of %u pixels differ\n" % (different, total)) - if not compare_rgba(w, h, rgba, expected_rgba): + if float(total - different)/float(total) < 0.85: - #show_image(w, h, Result=rgba, Expected=expected_rgba) - #save_image(w, h, rgba, "result.png") - #save_image(w, h, expected_rgba, "expected.png") + if 0: + rgba = FloatArray(h*w*4) + cbuf.get_tile_rgba(x, y, w, h, rgba) + show_image(w, h, Result=rgba, Expected=expected_rgba) + save_image(w, h, rgba, "result.png") + save_image(w, h, expected_rgba, "expected.png") #sys.exit(0) raise TestFailure -- cgit v1.2.3 From 6a65a0d9efb82b11cafe5b411abddd57a4fb838a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 17 Jul 2008 11:26:53 +0900 Subject: gallium: Be less verbose with debug options messages. --- src/gallium/auxiliary/util/p_debug.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 7b28900a25..b0240ad737 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -174,20 +174,19 @@ copy(char *dst, const char *start, const char *end, size_t n) #endif -const char * -debug_get_option(const char *name, const char *dfault) +static INLINE const char * +_debug_get_option(const char *name) { - const char *result; #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) /* EngMapFile creates the file if it does not exists, so it must either be * disabled on release versions (or put in a less conspicuous place). */ #ifdef DEBUG + const char *result = NULL; ULONG_PTR iFile = 0; const void *pMap = NULL; const char *sol, *eol, *sep; static char output[1024]; - result = dfault; pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile); if(pMap) { sol = (const char *)pMap; @@ -208,18 +207,27 @@ debug_get_option(const char *name, const char *dfault) } EngUnmapFile(iFile); } + return result; #else - result = dfault; + return NULL; #endif #elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) /* TODO: implement */ - result = dfault; + return NULL; #else - result = getenv(name); - if(!result) - result = dfault; + return getenv(name); #endif +} +const char * +debug_get_option(const char *name, const char *dfault) +{ + const char *result; + + result = _debug_get_option(name); + if(!result) + result = dfault; + debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? result : "(null)"); return result; @@ -228,7 +236,7 @@ debug_get_option(const char *name, const char *dfault) boolean debug_get_bool_option(const char *name, boolean dfault) { - const char *str = debug_get_option(name, NULL); + const char *str = _debug_get_option(name); boolean result; if(str == NULL) @@ -258,7 +266,7 @@ debug_get_num_option(const char *name, long dfault) long result; const char *str; - str = debug_get_option(name, NULL); + str = _debug_get_option(name); if(!str) result = dfault; else { @@ -294,7 +302,7 @@ debug_get_flags_option(const char *name, unsigned long result; const char *str; - str = debug_get_option(name, NULL); + str = _debug_get_option(name); if(!str) result = dfault; else { -- cgit v1.2.3 From 174c6912d68a954ff5eddf8b953b813e2eac3deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 17 Jul 2008 22:54:14 +0900 Subject: gallium: Expose the ability to get a tile outside a surface. --- src/gallium/auxiliary/util/p_tile.c | 83 +++++++++++++++++++++---------------- src/gallium/auxiliary/util/p_tile.h | 7 ++++ 2 files changed, 54 insertions(+), 36 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 580a95568e..1daae6b640 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -706,81 +706,92 @@ ycbcr_get_tile_rgba(ushort *src, void -pipe_get_tile_rgba(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - float *p) +pipe_tile_raw_to_rgba(enum pipe_format format, + void *src, + uint w, uint h, + float *dst, unsigned dst_stride) { - unsigned dst_stride = w * 4; - void *packed; - - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - - packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size); - - if (!packed) - return; - - pipe_get_tile_raw(ps, x, y, w, h, packed, 0); - - switch (ps->format) { + switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: - a8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_X8R8G8B8_UNORM: - x8r8g8b8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_B8G8R8A8_UNORM: - b8g8r8a8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_A1R5G5B5_UNORM: - a1r5g5b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_A4R4G4B4_UNORM: - a4r4g4b4_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_R5G6B5_UNORM: - r5g6b5_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_L8_UNORM: - l8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); + l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_A8_UNORM: - a8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); + a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_I8_UNORM: - i8_get_tile_rgba((ubyte *) packed, w, h, p, dst_stride); + i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_A8L8_UNORM: - a8_l8_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + a8_l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_R16G16B16A16_SNORM: - r16g16b16a16_get_tile_rgba((short *) packed, w, h, p, dst_stride); + r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_Z16_UNORM: - z16_get_tile_rgba((ushort *) packed, w, h, p, dst_stride); + z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_Z32_UNORM: - z32_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: - s8z24_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_Z24S8_UNORM: - z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); + z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_YCBCR: - assert((x & 1) == 0); - ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, FALSE); + ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE); break; case PIPE_FORMAT_YCBCR_REV: - assert((x & 1) == 0); - ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, TRUE); + ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE); break; default: assert(0); } +} + + +void +pipe_get_tile_rgba(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + float *p) +{ + unsigned dst_stride = w * 4; + void *packed; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size); + + if (!packed) + return; + + if(ps->format == PIPE_FORMAT_YCBCR || ps->format == PIPE_FORMAT_YCBCR_REV) + assert((x & 1) == 0); + + pipe_get_tile_raw(ps, x, y, w, h, packed, 0); + + pipe_tile_raw_to_rgba(ps->format, packed, w, h, p, dst_stride); FREE(packed); } diff --git a/src/gallium/auxiliary/util/p_tile.h b/src/gallium/auxiliary/util/p_tile.h index adfec8bcee..a8ac805308 100644 --- a/src/gallium/auxiliary/util/p_tile.h +++ b/src/gallium/auxiliary/util/p_tile.h @@ -87,6 +87,13 @@ pipe_put_tile_z(struct pipe_surface *ps, uint x, uint y, uint w, uint h, const uint *z); +void +pipe_tile_raw_to_rgba(enum pipe_format format, + void *src, + uint w, uint h, + float *dst, unsigned dst_stride); + + #ifdef __cplusplus } #endif -- cgit v1.2.3 From e74f94b39ac47a319ee21c526315fb6fbc1513de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 18 Jul 2008 01:08:06 +0900 Subject: python: Reimplement the generation of random texture samples in C. --- src/gallium/state_trackers/python/SConscript | 1 + src/gallium/state_trackers/python/gallium.i | 6 + src/gallium/state_trackers/python/st_sample.c | 548 +++++++++++++++++++++ src/gallium/state_trackers/python/st_sample.h | 47 ++ src/gallium/state_trackers/python/tests/data.py | 285 ----------- src/gallium/state_trackers/python/tests/texture.py | 29 +- 6 files changed, 606 insertions(+), 310 deletions(-) create mode 100644 src/gallium/state_trackers/python/st_sample.c create mode 100644 src/gallium/state_trackers/python/st_sample.h delete mode 100644 src/gallium/state_trackers/python/tests/data.py (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index b284d2020b..973d96d55a 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -20,6 +20,7 @@ if 'python' in env['statetrackers']: source = [ 'gallium.i', 'st_device.c', + 'st_sample.c', 'st_softpipe_winsys.c', ], ) diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 1c207a41b9..d5b24b04ff 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -51,6 +51,7 @@ #include "tgsi/util/tgsi_dump.h" #include "st_device.h" +#include "st_sample.h" %} @@ -454,6 +455,11 @@ error1: pipe_put_tile_z($self, x, y, w, h, z); } + void + sample_rgba(float *rgba) { + st_sample_surface($self, rgba); + } + unsigned compare_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba, float tol = 0.0) { diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c new file mode 100644 index 0000000000..b47c7be293 --- /dev/null +++ b/src/gallium/state_trackers/python/st_sample.c @@ -0,0 +1,548 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "util/p_tile.h" + +#include "st_sample.h" + + +/** + * Use our own pseudo random generator to ensure consistent runs among + * multiple runs and platforms. + * + * @sa http://en.wikipedia.org/wiki/Linear_congruential_generator + */ +static uint32_t st_random(void) { + static uint64_t seed = UINT64_C(0xbb9a063afb0a739d); + + seed = UINT64_C(134775813) * seed + UINT64_C(1); + + return (uint16_t)(seed >> 32); +} + + +/** + * We don't want to include the patent-encumbered DXT code here, so instead + * we store several uncompressed/compressed data pairs for hardware testing + * purposes. + */ +struct dxt_data +{ + uint8_t rgba[16*4]; + uint8_t raw[16]; +}; + + +static const struct dxt_data +dxt1_rgb_data[] = { + { + { + 0x99, 0xb0, 0x8e, 0xff, + 0x5d, 0x62, 0x89, 0xff, + 0x99, 0xb0, 0x8e, 0xff, + 0x99, 0xb0, 0x8e, 0xff, + 0xd6, 0xff, 0x94, 0xff, + 0x5d, 0x62, 0x89, 0xff, + 0x99, 0xb0, 0x8e, 0xff, + 0xd6, 0xff, 0x94, 0xff, + 0x5d, 0x62, 0x89, 0xff, + 0x5d, 0x62, 0x89, 0xff, + 0x99, 0xb0, 0x8e, 0xff, + 0x21, 0x14, 0x84, 0xff, + 0x5d, 0x62, 0x89, 0xff, + 0x21, 0x14, 0x84, 0xff, + 0x21, 0x14, 0x84, 0xff, + 0x99, 0xb0, 0x8e, 0xff + }, + {0xf2, 0xd7, 0xb0, 0x20, 0xae, 0x2c, 0x6f, 0x97} + }, + { + { + 0xb5, 0xcf, 0x9c, 0xff, + 0x83, 0x8c, 0x8b, 0xff, + 0x21, 0x08, 0x6b, 0xff, + 0x83, 0x8c, 0x8b, 0xff, + 0x52, 0x4a, 0x7b, 0xff, + 0x83, 0x8c, 0x8b, 0xff, + 0x83, 0x8c, 0x8b, 0xff, + 0xb5, 0xcf, 0x9c, 0xff, + 0x21, 0x08, 0x6b, 0xff, + 0xb5, 0xcf, 0x9c, 0xff, + 0x83, 0x8c, 0x8b, 0xff, + 0x52, 0x4a, 0x7b, 0xff, + 0xb5, 0xcf, 0x9c, 0xff, + 0x83, 0x8c, 0x8b, 0xff, + 0x52, 0x4a, 0x7b, 0xff, + 0x83, 0x8c, 0x8b, 0xff + }, + {0x73, 0xb6, 0x4d, 0x20, 0x98, 0x2b, 0xe1, 0xb8} + }, + { + { + 0x00, 0x2c, 0xff, 0xff, + 0x94, 0x8d, 0x7b, 0xff, + 0x4a, 0x5c, 0xbd, 0xff, + 0x4a, 0x5c, 0xbd, 0xff, + 0x4a, 0x5c, 0xbd, 0xff, + 0x94, 0x8d, 0x7b, 0xff, + 0x94, 0x8d, 0x7b, 0xff, + 0x94, 0x8d, 0x7b, 0xff, + 0xde, 0xbe, 0x39, 0xff, + 0x94, 0x8d, 0x7b, 0xff, + 0xde, 0xbe, 0x39, 0xff, + 0xde, 0xbe, 0x39, 0xff, + 0xde, 0xbe, 0x39, 0xff, + 0xde, 0xbe, 0x39, 0xff, + 0xde, 0xbe, 0x39, 0xff, + 0x94, 0x8d, 0x7b, 0xff + }, + {0xe7, 0xdd, 0x7f, 0x01, 0xf9, 0xab, 0x08, 0x80} + }, + { + { + 0x6b, 0x24, 0x21, 0xff, + 0x7b, 0x4f, 0x5d, 0xff, + 0x7b, 0x4f, 0x5d, 0xff, + 0x8b, 0x7a, 0x99, 0xff, + 0x7b, 0x4f, 0x5d, 0xff, + 0x7b, 0x4f, 0x5d, 0xff, + 0x6b, 0x24, 0x21, 0xff, + 0x8b, 0x7a, 0x99, 0xff, + 0x9c, 0xa6, 0xd6, 0xff, + 0x6b, 0x24, 0x21, 0xff, + 0x7b, 0x4f, 0x5d, 0xff, + 0x8b, 0x7a, 0x99, 0xff, + 0x6b, 0x24, 0x21, 0xff, + 0x8b, 0x7a, 0x99, 0xff, + 0x7b, 0x4f, 0x5d, 0xff, + 0x9c, 0xa6, 0xd6, 0xff + }, + {0x3a, 0x9d, 0x24, 0x69, 0xbd, 0x9f, 0xb4, 0x39} + } +}; + + +static const struct dxt_data +dxt1_rgba_data[] = { + { + { + 0x00, 0x00, 0x00, 0x00, + 0x4e, 0xaa, 0x90, 0xff, + 0x4e, 0xaa, 0x90, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x4e, 0xaa, 0x90, 0xff, + 0x29, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x4e, 0xaa, 0x90, 0xff, + 0x73, 0x55, 0x21, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x4e, 0xaa, 0x90, 0xff, + 0x4e, 0xaa, 0x90, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x4e, 0xaa, 0x90, 0xff + }, + {0xff, 0x2f, 0xa4, 0x72, 0xeb, 0xb2, 0xbd, 0xbe} + }, + { + { + 0xb5, 0xe3, 0x63, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x6b, 0x24, 0x84, 0xff, + 0xb5, 0xe3, 0x63, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0xb5, 0xe3, 0x63, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x6b, 0x24, 0x84, 0xff, + 0x6b, 0x24, 0x84, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0xb5, 0xe3, 0x63, 0xff, + 0x90, 0x83, 0x73, 0xff, + 0xb5, 0xe3, 0x63, 0xff + }, + {0x30, 0x69, 0x0c, 0xb7, 0x4d, 0xf7, 0x0f, 0x67} + }, + { + { + 0x00, 0x00, 0x00, 0x00, + 0xc6, 0x86, 0x8c, 0xff, + 0xc6, 0x86, 0x8c, 0xff, + 0x21, 0x65, 0x42, 0xff, + 0x21, 0x65, 0x42, 0xff, + 0x21, 0x65, 0x42, 0xff, + 0x21, 0x65, 0x42, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x21, 0x65, 0x42, 0xff, + 0xc6, 0x86, 0x8c, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xc6, 0x86, 0x8c, 0xff + }, + {0x28, 0x23, 0x31, 0xc4, 0x17, 0xc0, 0xd3, 0x7f} + }, + { + { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0xc6, 0xe3, 0x9c, 0xff, + 0x7b, 0x1c, 0x52, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x7b, 0x1c, 0x52, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x7b, 0x1c, 0x52, 0xff, + 0xa0, 0x7f, 0x77, 0xff, + 0xc6, 0xe3, 0x9c, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x7f, 0x77, 0xff + }, + {0xea, 0x78, 0x13, 0xc7, 0x7f, 0xfc, 0x33, 0xb6} + }, +}; + + +static const struct dxt_data +dxt3_rgba_data[] = { + { + { + 0x6d, 0xc6, 0x96, 0x77, + 0x6d, 0xc6, 0x96, 0xee, + 0x6d, 0xc6, 0x96, 0xaa, + 0x8c, 0xff, 0xb5, 0x44, + 0x6d, 0xc6, 0x96, 0xff, + 0x6d, 0xc6, 0x96, 0x88, + 0x31, 0x55, 0x5a, 0x66, + 0x6d, 0xc6, 0x96, 0x99, + 0x31, 0x55, 0x5a, 0xbb, + 0x31, 0x55, 0x5a, 0x55, + 0x31, 0x55, 0x5a, 0x11, + 0x6d, 0xc6, 0x96, 0xcc, + 0x6d, 0xc6, 0x96, 0xcc, + 0x6d, 0xc6, 0x96, 0x11, + 0x31, 0x55, 0x5a, 0x44, + 0x31, 0x55, 0x5a, 0x88 + }, + {0xe7, 0x4a, 0x8f, 0x96, 0x5b, 0xc1, 0x1c, 0x84, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a} + }, + { + { + 0xad, 0xeb, 0x73, 0x99, + 0x97, 0xaa, 0x86, 0x66, + 0x6b, 0x28, 0xad, 0x99, + 0xad, 0xeb, 0x73, 0x99, + 0x6b, 0x28, 0xad, 0x22, + 0xad, 0xeb, 0x73, 0xff, + 0x97, 0xaa, 0x86, 0x55, + 0x6b, 0x28, 0xad, 0x55, + 0x6b, 0x28, 0xad, 0x44, + 0xad, 0xeb, 0x73, 0x33, + 0x6b, 0x28, 0xad, 0xee, + 0x6b, 0x28, 0xad, 0x99, + 0x97, 0xaa, 0x86, 0x66, + 0xad, 0xeb, 0x73, 0xbb, + 0x97, 0xaa, 0x86, 0x99, + 0xad, 0xeb, 0x73, 0xbb + }, + {0x69, 0x99, 0xf2, 0x55, 0x34, 0x9e, 0xb6, 0xb9, 0x4e, 0xaf, 0x55, 0x69, 0x18, 0x61, 0x51, 0x22} + }, + { + { + 0x63, 0xd7, 0xd6, 0x00, + 0x57, 0x62, 0x5d, 0xdd, + 0x57, 0x62, 0x5d, 0xcc, + 0x57, 0x62, 0x5d, 0xbb, + 0x52, 0x28, 0x21, 0xaa, + 0x57, 0x62, 0x5d, 0xcc, + 0x57, 0x62, 0x5d, 0xcc, + 0x57, 0x62, 0x5d, 0x66, + 0x57, 0x62, 0x5d, 0x22, + 0x57, 0x62, 0x5d, 0xdd, + 0x63, 0xd7, 0xd6, 0xee, + 0x57, 0x62, 0x5d, 0x33, + 0x63, 0xd7, 0xd6, 0x55, + 0x52, 0x28, 0x21, 0x55, + 0x57, 0x62, 0x5d, 0x11, + 0x5d, 0x9c, 0x99, 0xee + }, + {0xd0, 0xbc, 0xca, 0x6c, 0xd2, 0x3e, 0x55, 0xe1, 0xba, 0x66, 0x44, 0x51, 0xfc, 0xfd, 0xcf, 0xb4} + }, + { + { + 0x94, 0x6f, 0x60, 0x22, + 0x94, 0x6f, 0x60, 0x22, + 0xc5, 0xab, 0x76, 0x11, + 0xc5, 0xab, 0x76, 0xee, + 0x63, 0x34, 0x4a, 0xdd, + 0x63, 0x34, 0x4a, 0x33, + 0x94, 0x6f, 0x60, 0x77, + 0xf7, 0xe7, 0x8c, 0x00, + 0x94, 0x6f, 0x60, 0x33, + 0x63, 0x34, 0x4a, 0xaa, + 0x94, 0x6f, 0x60, 0x77, + 0x63, 0x34, 0x4a, 0xcc, + 0x94, 0x6f, 0x60, 0xaa, + 0xf7, 0xe7, 0x8c, 0x99, + 0x63, 0x34, 0x4a, 0x44, + 0xc5, 0xab, 0x76, 0xaa + }, + {0x22, 0xe1, 0x3d, 0x07, 0xa3, 0xc7, 0x9a, 0xa4, 0x31, 0xf7, 0xa9, 0x61, 0xaf, 0x35, 0x77, 0x93} + }, +}; + + +static const struct dxt_data +dxt5_rgba_data[] = { + { + { + 0x6d, 0xc6, 0x96, 0x74, + 0x6d, 0xc6, 0x96, 0xf8, + 0x6d, 0xc6, 0x96, 0xb6, + 0x8c, 0xff, 0xb5, 0x53, + 0x6d, 0xc6, 0x96, 0xf8, + 0x6d, 0xc6, 0x96, 0x95, + 0x31, 0x55, 0x5a, 0x53, + 0x6d, 0xc6, 0x96, 0x95, + 0x31, 0x55, 0x5a, 0xb6, + 0x31, 0x55, 0x5a, 0x53, + 0x31, 0x55, 0x5a, 0x11, + 0x6d, 0xc6, 0x96, 0xd7, + 0x6d, 0xc6, 0x96, 0xb6, + 0x6d, 0xc6, 0x96, 0x11, + 0x31, 0x55, 0x5a, 0x32, + 0x31, 0x55, 0x5a, 0x95 + }, + {0xf8, 0x11, 0xc5, 0x0c, 0x9a, 0x73, 0xb4, 0x9c, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a} + }, + { + { + 0xad, 0xeb, 0x73, 0xa1, + 0x97, 0xaa, 0x86, 0x65, + 0x6b, 0x28, 0xad, 0xa1, + 0xad, 0xeb, 0x73, 0xa1, + 0x6b, 0x28, 0xad, 0x2a, + 0xad, 0xeb, 0x73, 0xfb, + 0x97, 0xaa, 0x86, 0x47, + 0x6b, 0x28, 0xad, 0x65, + 0x6b, 0x28, 0xad, 0x47, + 0xad, 0xeb, 0x73, 0x47, + 0x6b, 0x28, 0xad, 0xdd, + 0x6b, 0x28, 0xad, 0xa1, + 0x97, 0xaa, 0x86, 0x65, + 0xad, 0xeb, 0x73, 0xbf, + 0x97, 0xaa, 0x86, 0xa1, + 0xad, 0xeb, 0x73, 0xbf + }, + {0xfb, 0x2a, 0x34, 0x19, 0xdc, 0xbf, 0xe8, 0x71, 0x4e, 0xaf, 0x55, 0x69, 0x18, 0x61, 0x51, 0x22} + }, + { + { + 0x63, 0xd7, 0xd6, 0x00, + 0x57, 0x62, 0x5d, 0xf5, + 0x57, 0x62, 0x5d, 0xd2, + 0x57, 0x62, 0x5d, 0xaf, + 0x52, 0x28, 0x21, 0xaf, + 0x57, 0x62, 0x5d, 0xd2, + 0x57, 0x62, 0x5d, 0xd2, + 0x57, 0x62, 0x5d, 0x69, + 0x57, 0x62, 0x5d, 0x23, + 0x57, 0x62, 0x5d, 0xd2, + 0x63, 0xd7, 0xd6, 0xf5, + 0x57, 0x62, 0x5d, 0x46, + 0x63, 0xd7, 0xd6, 0x46, + 0x52, 0x28, 0x21, 0x69, + 0x57, 0x62, 0x5d, 0x23, + 0x5d, 0x9c, 0x99, 0xf5 + }, + {0xf5, 0x00, 0x81, 0x36, 0xa9, 0x17, 0xec, 0x1e, 0xba, 0x66, 0x44, 0x51, 0xfc, 0xfd, 0xcf, 0xb4} + }, + { + { + 0x94, 0x6f, 0x60, 0x25, + 0x94, 0x6f, 0x60, 0x25, + 0xc5, 0xab, 0x76, 0x05, + 0xc5, 0xab, 0x76, 0xe8, + 0x63, 0x34, 0x4a, 0xe8, + 0x63, 0x34, 0x4a, 0x25, + 0x94, 0x6f, 0x60, 0x86, + 0xf7, 0xe7, 0x8c, 0x05, + 0x94, 0x6f, 0x60, 0x25, + 0x63, 0x34, 0x4a, 0xa7, + 0x94, 0x6f, 0x60, 0x66, + 0x63, 0x34, 0x4a, 0xc7, + 0x94, 0x6f, 0x60, 0xa7, + 0xf7, 0xe7, 0x8c, 0xa7, + 0x63, 0x34, 0x4a, 0x45, + 0xc5, 0xab, 0x76, 0xa7 + }, + {0xe8, 0x05, 0x7f, 0x80, 0x33, 0x5f, 0xb5, 0x79, 0x31, 0xf7, 0xa9, 0x61, 0xaf, 0x35, 0x77, 0x93} + }, +}; + + +static INLINE void +st_sample_dxt_pixel_block(enum pipe_format format, + const struct pipe_format_block *block, + uint8_t *raw, + float *rgba, unsigned rgba_stride, + unsigned w, unsigned h) +{ + const struct dxt_data *data; + unsigned n; + unsigned i; + unsigned x, y, ch; + + switch(format) { + case PIPE_FORMAT_DXT1_RGB: + data = dxt1_rgb_data; + n = sizeof(dxt1_rgb_data)/sizeof(dxt1_rgb_data[0]); + break; + case PIPE_FORMAT_DXT1_RGBA: + data = dxt1_rgba_data; + n = sizeof(dxt1_rgba_data)/sizeof(dxt1_rgba_data[0]); + break; + case PIPE_FORMAT_DXT3_RGBA: + data = dxt3_rgba_data; + n = sizeof(dxt3_rgba_data)/sizeof(dxt3_rgba_data[0]); + break; + case PIPE_FORMAT_DXT5_RGBA: + data = dxt5_rgba_data; + n = sizeof(dxt5_rgba_data)/sizeof(dxt5_rgba_data[0]); + break; + default: + assert(0); + } + + i = st_random() % n; + + for(y = 0; y < h; ++y) + for(x = 0; x < w; ++x) + for(ch = 0; ch < 4; ++ch) + rgba[y*rgba_stride + x*4 + ch] = (float)(data[i].rgba[y*4*4 + x*4 + ch])/255.0f; + + memcpy(raw, data[i].raw, block->size); +} + + +static INLINE void +st_sample_generic_pixel_block(enum pipe_format format, + const struct pipe_format_block *block, + uint8_t *raw, + float *rgba, unsigned rgba_stride, + unsigned w, unsigned h) +{ + unsigned i; + unsigned x, y, ch; + + for(i = 0; i < block->size; ++i) + raw[i] = (uint8_t)st_random(); + + + pipe_tile_raw_to_rgba(format, + raw, + w, h, + rgba, rgba_stride); + + if(format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV) { + for(y = 0; y < h; ++y) { + for(x = 0; x < w; ++x) { + for(ch = 0; ch < 4; ++ch) { + unsigned offset = y*rgba_stride + x*4 + ch; + rgba[offset] = CLAMP(rgba[offset], 0.0f, 1.0f); + } + } + } + } +} + + +/** + * Randomly sample pixels. + */ +void +st_sample_pixel_block(enum pipe_format format, + const struct pipe_format_block *block, + void *raw, + float *rgba, unsigned rgba_stride, + unsigned w, unsigned h) +{ + switch(format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: + st_sample_dxt_pixel_block(format, block, raw, rgba, rgba_stride, w, h); + break; + + default: + st_sample_generic_pixel_block(format, block, raw, rgba, rgba_stride, w, h); + break; + } +} + + +void +st_sample_surface(struct pipe_surface *surface, float *rgba) +{ + const struct pipe_format_block *block = &surface->block; + unsigned rgba_stride = surface->width*4; + void *raw; + unsigned x, y; + + raw = pipe_surface_map(surface, PIPE_BUFFER_USAGE_CPU_READ); + if(!raw) + return; + + for (y = 0; y < surface->nblocksy; ++y) { + for(x = 0; x < surface->nblocksx; ++x) { + st_sample_pixel_block(surface->format, + block, + (uint8_t*)raw + y*surface->stride + x*block->size, + rgba + y*block->height*rgba_stride + x*block->width*4, + rgba_stride, + MIN2(block->width, surface->width - x*block->width), + MIN2(block->height, surface->height - y*block->height)); + } + } + + pipe_surface_unmap(surface); +} diff --git a/src/gallium/state_trackers/python/st_sample.h b/src/gallium/state_trackers/python/st_sample.h new file mode 100644 index 0000000000..ff04a12613 --- /dev/null +++ b/src/gallium/state_trackers/python/st_sample.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef ST_SAMPLE_H_ +#define ST_SAMPLE_H_ + + +#include "pipe/p_format.h" + + +void +st_sample_pixel_block(enum pipe_format format, + const struct pipe_format_block *block, + void *raw, + float *rgba, unsigned rgba_stride, + unsigned w, unsigned h); + +void +st_sample_surface(struct pipe_surface *surface, float *rgba); + + +#endif /* ST_SAMPLE_H_ */ diff --git a/src/gallium/state_trackers/python/tests/data.py b/src/gallium/state_trackers/python/tests/data.py deleted file mode 100644 index 3c1cda59d7..0000000000 --- a/src/gallium/state_trackers/python/tests/data.py +++ /dev/null @@ -1,285 +0,0 @@ -#!/usr/bin/env python -########################################################################## -# -# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. -# All Rights Reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sub license, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice (including the -# next paragraph) shall be included in all copies or substantial portions -# of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR -# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -########################################################################## - -"""Texture data generation for use in testing.""" - - -import random - -from gallium import * - - -dxt1_rgb_data = [ - ( - [ - [0x99, 0xb0, 0x8e, 0xff], - [0x5d, 0x62, 0x89, 0xff], - [0x99, 0xb0, 0x8e, 0xff], - [0x99, 0xb0, 0x8e, 0xff], - [0xd6, 0xff, 0x94, 0xff], - [0x5d, 0x62, 0x89, 0xff], - [0x99, 0xb0, 0x8e, 0xff], - [0xd6, 0xff, 0x94, 0xff], - [0x5d, 0x62, 0x89, 0xff], - [0x5d, 0x62, 0x89, 0xff], - [0x99, 0xb0, 0x8e, 0xff], - [0x21, 0x14, 0x84, 0xff], - [0x5d, 0x62, 0x89, 0xff], - [0x21, 0x14, 0x84, 0xff], - [0x21, 0x14, 0x84, 0xff], - [0x99, 0xb0, 0x8e, 0xff], - ], - [0xf2, 0xd7, 0xb0, 0x20, 0xae, 0x2c, 0x6f, 0x97], - ), - ( - [ - [0xb5, 0xcf, 0x9c, 0xff], - [0x83, 0x8c, 0x8b, 0xff], - [0x21, 0x08, 0x6b, 0xff], - [0x83, 0x8c, 0x8b, 0xff], - [0x52, 0x4a, 0x7b, 0xff], - [0x83, 0x8c, 0x8b, 0xff], - [0x83, 0x8c, 0x8b, 0xff], - [0xb5, 0xcf, 0x9c, 0xff], - [0x21, 0x08, 0x6b, 0xff], - [0xb5, 0xcf, 0x9c, 0xff], - [0x83, 0x8c, 0x8b, 0xff], - [0x52, 0x4a, 0x7b, 0xff], - [0xb5, 0xcf, 0x9c, 0xff], - [0x83, 0x8c, 0x8b, 0xff], - [0x52, 0x4a, 0x7b, 0xff], - [0x83, 0x8c, 0x8b, 0xff], - ], - [0x73, 0xb6, 0x4d, 0x20, 0x98, 0x2b, 0xe1, 0xb8], - ), - ( - [ - [0x00, 0x2c, 0xff, 0xff], - [0x94, 0x8d, 0x7b, 0xff], - [0x4a, 0x5c, 0xbd, 0xff], - [0x4a, 0x5c, 0xbd, 0xff], - [0x4a, 0x5c, 0xbd, 0xff], - [0x94, 0x8d, 0x7b, 0xff], - [0x94, 0x8d, 0x7b, 0xff], - [0x94, 0x8d, 0x7b, 0xff], - [0xde, 0xbe, 0x39, 0xff], - [0x94, 0x8d, 0x7b, 0xff], - [0xde, 0xbe, 0x39, 0xff], - [0xde, 0xbe, 0x39, 0xff], - [0xde, 0xbe, 0x39, 0xff], - [0xde, 0xbe, 0x39, 0xff], - [0xde, 0xbe, 0x39, 0xff], - [0x94, 0x8d, 0x7b, 0xff], - ], - [0xe7, 0xdd, 0x7f, 0x01, 0xf9, 0xab, 0x08, 0x80], - ), - ( - [ - [0x6b, 0x24, 0x21, 0xff], - [0x7b, 0x4f, 0x5d, 0xff], - [0x7b, 0x4f, 0x5d, 0xff], - [0x8b, 0x7a, 0x99, 0xff], - [0x7b, 0x4f, 0x5d, 0xff], - [0x7b, 0x4f, 0x5d, 0xff], - [0x6b, 0x24, 0x21, 0xff], - [0x8b, 0x7a, 0x99, 0xff], - [0x9c, 0xa6, 0xd6, 0xff], - [0x6b, 0x24, 0x21, 0xff], - [0x7b, 0x4f, 0x5d, 0xff], - [0x8b, 0x7a, 0x99, 0xff], - [0x6b, 0x24, 0x21, 0xff], - [0x8b, 0x7a, 0x99, 0xff], - [0x7b, 0x4f, 0x5d, 0xff], - [0x9c, 0xa6, 0xd6, 0xff], - ], - [0x3a, 0x9d, 0x24, 0x69, 0xbd, 0x9f, 0xb4, 0x39], - ), -] - -dxt1_rgba = [ - ( - [ - [0x00, 0x00, 0x00, 0x00], - [0x4e, 0xaa, 0x90, 0xff], - [0x4e, 0xaa, 0x90, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0x4e, 0xaa, 0x90, 0xff], - [0x29, 0xff, 0xff, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0x4e, 0xaa, 0x90, 0xff], - [0x73, 0x55, 0x21, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x4e, 0xaa, 0x90, 0xff], - [0x4e, 0xaa, 0x90, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x4e, 0xaa, 0x90, 0xff], - ], - [0xff, 0x2f, 0xa4, 0x72, 0xeb, 0xb2, 0xbd, 0xbe], - ), - ( - [ - [0xb5, 0xe3, 0x63, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0x6b, 0x24, 0x84, 0xff], - [0xb5, 0xe3, 0x63, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0xb5, 0xe3, 0x63, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x6b, 0x24, 0x84, 0xff], - [0x6b, 0x24, 0x84, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0xb5, 0xe3, 0x63, 0xff], - [0x90, 0x83, 0x73, 0xff], - [0xb5, 0xe3, 0x63, 0xff], - ], - [0x30, 0x69, 0x0c, 0xb7, 0x4d, 0xf7, 0x0f, 0x67], - ), - ( - [ - [0x00, 0x00, 0x00, 0x00], - [0xc6, 0x86, 0x8c, 0xff], - [0xc6, 0x86, 0x8c, 0xff], - [0x21, 0x65, 0x42, 0xff], - [0x21, 0x65, 0x42, 0xff], - [0x21, 0x65, 0x42, 0xff], - [0x21, 0x65, 0x42, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x21, 0x65, 0x42, 0xff], - [0xc6, 0x86, 0x8c, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0xc6, 0x86, 0x8c, 0xff], - ], - [0x28, 0x23, 0x31, 0xc4, 0x17, 0xc0, 0xd3, 0x7f], - ), - ( - [ - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0xc6, 0xe3, 0x9c, 0xff], - [0x7b, 0x1c, 0x52, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0x00, 0x00], - [0x7b, 0x1c, 0x52, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0x7b, 0x1c, 0x52, 0xff], - [0xa0, 0x7f, 0x77, 0xff], - [0xc6, 0xe3, 0x9c, 0xff], - [0x00, 0x00, 0x00, 0x00], - [0xa0, 0x7f, 0x77, 0xff], - ], - [0xea, 0x78, 0x13, 0xc7, 0x7f, 0xfc, 0x33, 0xb6], - ), -] - - - -def generate_data_compressed(surface, blocks): - - stride = surface.nblocksx*surface.block.size - size = surface.nblocksy*stride - - raw = ByteArray(size) - rgba = FloatArray(surface.height*surface.width*4) - - for yj in range(0, surface.nblocksy): - for xj in range(0, surface.nblocksx): - pixels, block = blocks[random.randint(0, len(blocks) - 1)] - - offset = (yj*surface.nblocksx + xj)*surface.block.size - for i in range(0, surface.block.size): - raw[offset + i] = block[i] - - for yi in range(0, surface.block.height): - for xi in range(0, surface.block.width): - y = yj*surface.block.height + yi - x = xj*surface.block.width + xi - if y < surface.height and x < surface.width: - offset = (y*surface.width + x)*4 - pixel = pixels[yi*surface.block.width + xi] - for ch in range(0, 4): - rgba[offset + ch] = float(pixel[ch])/255.0 - - surface.put_tile_raw(0, 0, surface.width, surface.height, raw, stride) - - return rgba - - -def generate_data_simple(surface): - stride = surface.nblocksx*surface.block.size - size = surface.nblocksy*stride - - raw = ByteArray(size) - rgba = FloatArray(surface.height*surface.width*4) - - for i in range(0, size): - raw[i] = random.randint(0, 255) - - surface.put_tile_raw(0, 0, surface.width, surface.height, raw, stride) - - surface.get_tile_rgba(0, 0, surface.width, surface.height, rgba) - - if surface.format in (PIPE_FORMAT_YCBCR, PIPE_FORMAT_YCBCR_REV): - # normalize - for y in range(0, surface.height): - for x in range(0, surface.width): - for ch in range(4): - offset = (y*surface.width + x)*4 + ch - rgba[offset] = min(max(rgba[offset], 0.0), 1.0) - - return rgba - - -def generate_data(surface): - width = surface.width - height = surface.height - - if surface.format == PIPE_FORMAT_DXT1_RGB: - return generate_data_compressed(surface, dxt1_rgb_data) - if surface.format == PIPE_FORMAT_DXT1_RGBA: - return generate_data_compressed(surface, dxt1_rgba_data) - if surface.format == PIPE_FORMAT_DXT3_RGBA: - assert 0 - if surface.format == PIPE_FORMAT_DXT5_RGBA: - assert 0 - - return generate_data_simple(surface) - - - diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index 3d76953126..2c9231349f 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -30,29 +30,6 @@ import sys from gallium import * from base import * -from data import generate_data - - -def compare_rgba(width, height, rgba1, rgba2, tol=4.0/256, ratio=0.85): - errors = 0 - for y in range(0, height): - for x in range(0, width): - differs = 0 - for ch in range(4): - offset = (y*width + x)*4 + ch - v1 = rgba1[offset] - v2 = rgba2[offset] - if abs(v1 - v2) > tol: - if errors == 0: - sys.stderr.write("x=%u, y=%u, ch=%u differ: %f vs %f\n" % (x, y, ch, v1, v2)) - if errors == 1 and ch == 0: - sys.stderr.write("...\n") - differs = 1 - errors += differs - total = height*width - if errors: - sys.stderr.write("%u out of %u pixels differ\n" % (errors, total)) - return float(total - errors)/float(total) >= ratio def lods(*dims): @@ -214,10 +191,12 @@ class TextureTest(TestCase): height=height, last_level = last_level) - expected_rgba = generate_data(texture.get_surface( + expected_rgba = FloatArray(height*width*4) + texture.get_surface( usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE, face = face, - level = level)) + level = level, + ).sample_rgba(expected_rgba) ctx.set_sampler_texture(0, texture) -- cgit v1.2.3 From 2727702b1731a478de8806481416080d02af5862 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 17 Jul 2008 20:19:40 +0200 Subject: tgsi: New file. --- src/gallium/auxiliary/tgsi/util/tgsi_sanity.c | 258 ++++++++++++++++++++++++++ src/gallium/auxiliary/tgsi/util/tgsi_sanity.h | 49 +++++ 2 files changed, 307 insertions(+) create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_sanity.c create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_sanity.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c new file mode 100644 index 0000000000..377309c3fd --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c @@ -0,0 +1,258 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "tgsi_sanity.h" +#include "tgsi_transform.h" + +#define MAX_REGISTERS 256 + +typedef uint reg_flag; + +#define BITS_IN_REG_FLAG (sizeof( reg_flag ) * 8) + +struct sanity_check_ctx +{ + struct tgsi_transform_context xform; + + reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REGISTERS / sizeof( uint ) / 8]; + reg_flag regs_used[TGSI_FILE_COUNT][MAX_REGISTERS / sizeof( uint ) / 8]; + uint num_imms; + uint num_instructions; + uint index_of_END; + + uint errors; + uint warnings; +}; + +static void +report_error( + struct sanity_check_ctx *ctx, + const char *msg ) +{ + debug_printf( "\nError: %s", msg ); + ctx->errors++; +} + +static void +report_warning( + struct sanity_check_ctx *ctx, + const char *msg ) +{ + debug_printf( "\nWarning: %s", msg ); + ctx->warnings++; +} + +static boolean +check_file_name( + struct sanity_check_ctx *ctx, + uint file ) +{ + if (file <= TGSI_FILE_NULL || file >= TGSI_FILE_COUNT) { + report_error( ctx, "Invalid file name" ); + return FALSE; + } + return TRUE; +} + +static boolean +is_register_declared( + struct sanity_check_ctx *ctx, + uint file, + uint index ) +{ + assert( index < MAX_REGISTERS ); + + return (ctx->regs_decl[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; +} + +static boolean +is_register_used( + struct sanity_check_ctx *ctx, + uint file, + uint index ) +{ + assert( index < MAX_REGISTERS ); + + return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; +} + +static void xform_instruction( + struct tgsi_transform_context *xform, + struct tgsi_full_instruction *inst ) +{ + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) xform; + uint i; + + /* There must be no other instructions after END. + */ + if (ctx->index_of_END != ~0) { + report_error( ctx, "Unexpected instruction after END" ); + } + else if (inst->Instruction.Opcode == TGSI_OPCODE_END) { + ctx->index_of_END = ctx->num_instructions; + } + + /* Check destination and source registers' validity. + * Mark the registers as used. + */ + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { + uint file; + uint index; + + file = inst->FullDstRegisters[i].DstRegister.File; + if (!check_file_name( ctx, file )) + return; + index = inst->FullDstRegisters[i].DstRegister.Index; + if (!is_register_declared( ctx, file, index )) + report_error( ctx, "Undeclared destination register" ); + ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG)); + } + for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { + uint file; + uint index; + + file = inst->FullSrcRegisters[i].SrcRegister.File; + if (!check_file_name( ctx, file )) + return; + index = inst->FullSrcRegisters[i].SrcRegister.Index; + if (!is_register_declared( ctx, file, index )) + report_error( ctx, "Undeclared source register" ); + ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG)); + } + + ctx->num_instructions++; +} + +static void xform_declaration( + struct tgsi_transform_context *xform, + struct tgsi_full_declaration *decl ) +{ + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) xform; + uint file; + uint i; + + /* No declarations allowed after the first instruction. + */ + if (ctx->num_instructions > 0) + report_error( ctx, "Instruction expected but declaration found" ); + + /* Check registers' validity. + * Mark the registers as declared. + */ + file = decl->Declaration.File; + if (!check_file_name( ctx, file )) + return; + for (i = decl->DeclarationRange.First; i <= decl->DeclarationRange.Last; i++) { + if (is_register_declared( ctx, file, i )) + report_error( ctx, "The same register declared twice" ); + ctx->regs_decl[file][i / BITS_IN_REG_FLAG] |= (1 << (i % BITS_IN_REG_FLAG)); + } +} + +static void xform_immediate( + struct tgsi_transform_context *xform, + struct tgsi_full_immediate *imm ) +{ + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) xform; + + assert( ctx->num_imms < MAX_REGISTERS ); + + /* No immediates allowed after the first instruction. + */ + if (ctx->num_instructions > 0) + report_error( ctx, "Instruction expected but immediate found" ); + + /* Mark the register as declared. + */ + ctx->num_imms++; + ctx->regs_decl[TGSI_FILE_IMMEDIATE][ctx->num_imms / BITS_IN_REG_FLAG] |= (1 << (ctx->num_imms % BITS_IN_REG_FLAG)); + + /* Check data type validity. + */ + if (imm->Immediate.DataType != TGSI_IMM_FLOAT32) { + report_error( ctx, "Invalid immediate data type" ); + return; + } +} + +static void epilog( + struct tgsi_transform_context *xform ) +{ + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) xform; + uint file; + + /* There must be an END instruction at the end. + */ + if (ctx->index_of_END == ~0 || ctx->index_of_END != ctx->num_instructions - 1) { + report_error( ctx, "Expected END at end of instruction sequence" ); + } + + /* Check if all declared registers were used. + */ + for (file = TGSI_FILE_NULL; file < TGSI_FILE_COUNT; file++) { + uint i; + + for (i = 0; i < MAX_REGISTERS; i++) { + if (is_register_declared( ctx, file, i ) && !is_register_used( ctx, file, i )) { + report_warning( ctx, "Register never used" ); + } + } + } + + /* Print totals, if any. + */ + if (ctx->errors || ctx->warnings) + debug_printf( "\n%u errors, %u warnings", ctx->errors, ctx->warnings ); +} + +boolean +tgsi_sanity_check( + struct tgsi_token *tokens ) +{ + struct sanity_check_ctx ctx; + struct tgsi_token dummy_tokens[16]; + + ctx.xform.transform_instruction = xform_instruction; + ctx.xform.transform_declaration = xform_declaration; + ctx.xform.transform_immediate = xform_immediate; + ctx.xform.epilog = epilog; + + memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) ); + memset( ctx.regs_used, 0, sizeof( ctx.regs_used ) ); + ctx.num_imms = 0; + ctx.num_instructions = 0; + ctx.index_of_END = ~0; + + ctx.errors = 0; + ctx.warnings = 0; + + if (tgsi_transform_shader( tokens, dummy_tokens, 16, &ctx.xform ) == -1) + return FALSE; + + return ctx.errors > 0; +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.h b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.h new file mode 100644 index 0000000000..ca45e94c7a --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.h @@ -0,0 +1,49 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_SANITY_H +#define TGSI_SANITY_H + +#include "pipe/p_shader_tokens.h" + +#if defined __cplusplus +extern "C" { +#endif + +/* Check the given token stream for errors and common mistakes. + * Diagnostic messages are printed out to the debug output. + * Returns TRUE if there are no errors, even though there could be some warnings. + */ +boolean +tgsi_sanity_check( + struct tgsi_token *tokens ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_SANITY_H */ -- cgit v1.2.3 From 3c5ec98e45880d6a896f3c094f8004000f50a149 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 17 Jul 2008 20:22:47 +0200 Subject: scons: List util/tgsi_sanity.c. --- src/gallium/auxiliary/tgsi/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript index b62c8efe02..67230f6ce0 100644 --- a/src/gallium/auxiliary/tgsi/SConscript +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -8,6 +8,7 @@ tgsi = env.ConvenienceLibrary( 'util/tgsi_build.c', 'util/tgsi_dump.c', 'util/tgsi_parse.c', + 'util/tgsi_sanity.c', 'util/tgsi_scan.c', 'util/tgsi_text.c', 'util/tgsi_transform.c', -- cgit v1.2.3 From 10d1dc68a413eaf642bf1bda2e5452835f7b7050 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 17 Jul 2008 20:23:26 +0200 Subject: tgsi: Perform a sanity check after reading a shader from text. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index 6cab475b88..803f7a23b8 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -29,6 +29,7 @@ #include "tgsi_text.h" #include "tgsi_build.h" #include "tgsi_parse.h" +#include "tgsi_sanity.h" #include "tgsi_util.h" static boolean is_alpha_underscore( const char *cur ) @@ -1064,5 +1065,8 @@ tgsi_text_translate( ctx.tokens_cur = tokens; ctx.tokens_end = tokens + num_tokens; - return translate( &ctx ); + if (!translate( &ctx )) + return FALSE; + + return tgsi_sanity_check( tokens ); } -- cgit v1.2.3 From f2053cfa1ac4e4e2e0083670aac5df766adad5f9 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 17 Jul 2008 20:40:13 +0200 Subject: tgsi: Fix parsing an instruction with no operands. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index 803f7a23b8..9ed0f52fc7 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -758,13 +758,20 @@ parse_instruction( for (i = 0; i < TGSI_OPCODE_LAST; i++) { const char *cur = ctx->cur; - if (str_match_no_case( &cur, opcode_info[i].mnemonic )) { + info = &opcode_info[i]; + if (str_match_no_case( &cur, info->mnemonic )) { if (str_match_no_case( &cur, "_SATNV" )) saturate = TGSI_SAT_MINUS_PLUS_ONE; else if (str_match_no_case( &cur, "_SAT" )) saturate = TGSI_SAT_ZERO_ONE; - if (*cur == '\0' || eat_white( &cur )) { + if (info->num_dst + info->num_src + info->is_tex == 0) { + if (!is_digit_alpha_underscore( cur )) { + ctx->cur = cur; + break; + } + } + else if (*cur == '\0' || eat_white( &cur )) { ctx->cur = cur; break; } @@ -777,7 +784,6 @@ parse_instruction( report_error( ctx, "Expected `DCL', `IMM' or a label" ); return FALSE; } - info = &opcode_info[i]; inst = tgsi_default_full_instruction(); inst.Instruction.Opcode = i; @@ -1031,6 +1037,9 @@ static boolean translate( struct translate_ctx *ctx ) return FALSE; } + if (*ctx->cur == '\0') + break; + if (parse_label( ctx, &label_val )) { if (!parse_instruction( ctx, TRUE )) return FALSE; -- cgit v1.2.3 From 638ecbda3eed8319ce82be9c119ca1f96f21d976 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 18 Jul 2008 00:39:23 +0200 Subject: tgsi: Add tgsi_iterate_shader utility. Walks the token stream and invokes callbacks. --- src/gallium/auxiliary/tgsi/util/tgsi_iterate.c | 82 ++++++++++++++++++++++++++ src/gallium/auxiliary/tgsi/util/tgsi_iterate.h | 73 +++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_iterate.c create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_iterate.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c new file mode 100644 index 0000000000..43d7a6b1d5 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c @@ -0,0 +1,82 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "tgsi_iterate.h" + +boolean +tgsi_iterate_shader( + const struct tgsi_token *tokens, + struct tgsi_iterate_context *ctx ) +{ + struct tgsi_parse_context parse; + + if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) + return FALSE; + + if (ctx->prolog) + if (!ctx->prolog( ctx )) + goto fail; + + while (!tgsi_parse_end_of_tokens( &parse )) { + tgsi_parse_token( &parse ); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + if (ctx->iterate_instruction) + if (!ctx->iterate_instruction( ctx, &parse.FullToken.FullInstruction )) + goto fail; + break; + + case TGSI_TOKEN_TYPE_DECLARATION: + if (ctx->iterate_declaration) + if (!ctx->iterate_declaration( ctx, &parse.FullToken.FullDeclaration )) + goto fail; + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + if (ctx->iterate_immediate) + if (!ctx->iterate_immediate( ctx, &parse.FullToken.FullImmediate )) + goto fail; + break; + + default: + assert( 0 ); + } + } + + if (ctx->epilog) + if (!ctx->epilog( ctx )) + goto fail; + + tgsi_parse_free( &parse ); + return TRUE; + +fail: + tgsi_parse_free( &parse ); + return FALSE; +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h new file mode 100644 index 0000000000..18729c2d1a --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h @@ -0,0 +1,73 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_ITERATE_H +#define TGSI_ITERATE_H + +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" + +#if defined __cplusplus +extern "C" { +#endif + +struct tgsi_iterate_context +{ + boolean + (* prolog)( + struct tgsi_iterate_context *ctx ); + + boolean + (* iterate_instruction)( + struct tgsi_iterate_context *ctx, + struct tgsi_full_instruction *inst ); + + boolean + (* iterate_declaration)( + struct tgsi_iterate_context *ctx, + struct tgsi_full_declaration *decl ); + + boolean + (* iterate_immediate)( + struct tgsi_iterate_context *ctx, + struct tgsi_full_immediate *imm ); + + boolean + (* epilog)( + struct tgsi_iterate_context *ctx ); +}; + +boolean +tgsi_iterate_shader( + const struct tgsi_token *tokens, + struct tgsi_iterate_context *ctx ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_ITERATE_H */ -- cgit v1.2.3 From e1fd3ea415db1bc80d0bc6d94645eaac60bb4121 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 18 Jul 2008 00:40:28 +0200 Subject: scons: List util/tgsi_iterate.c. --- src/gallium/auxiliary/tgsi/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript index 67230f6ce0..54f5c75db4 100644 --- a/src/gallium/auxiliary/tgsi/SConscript +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -7,6 +7,7 @@ tgsi = env.ConvenienceLibrary( 'exec/tgsi_sse2.c', 'util/tgsi_build.c', 'util/tgsi_dump.c', + 'util/tgsi_iterate.c', 'util/tgsi_parse.c', 'util/tgsi_sanity.c', 'util/tgsi_scan.c', -- cgit v1.2.3 From 1e5419fa3061386413a98b75d0908cb3e3c6894e Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Fri, 18 Jul 2008 00:41:45 +0200 Subject: tgsi: Express tgsi_sanity in terms of tgsi_iterate. --- src/gallium/auxiliary/tgsi/util/tgsi_sanity.c | 60 ++++++++++++++++----------- 1 file changed, 36 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c index 377309c3fd..933127e661 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c @@ -27,7 +27,7 @@ #include "pipe/p_debug.h" #include "tgsi_sanity.h" -#include "tgsi_transform.h" +#include "tgsi_iterate.h" #define MAX_REGISTERS 256 @@ -37,7 +37,7 @@ typedef uint reg_flag; struct sanity_check_ctx { - struct tgsi_transform_context xform; + struct tgsi_iterate_context iter; reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REGISTERS / sizeof( uint ) / 8]; reg_flag regs_used[TGSI_FILE_COUNT][MAX_REGISTERS / sizeof( uint ) / 8]; @@ -101,11 +101,12 @@ is_register_used( return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; } -static void xform_instruction( - struct tgsi_transform_context *xform, +static boolean +iter_instruction( + struct tgsi_iterate_context *iter, struct tgsi_full_instruction *inst ) { - struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) xform; + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; uint i; /* There must be no other instructions after END. @@ -126,7 +127,7 @@ static void xform_instruction( file = inst->FullDstRegisters[i].DstRegister.File; if (!check_file_name( ctx, file )) - return; + return TRUE; index = inst->FullDstRegisters[i].DstRegister.Index; if (!is_register_declared( ctx, file, index )) report_error( ctx, "Undeclared destination register" ); @@ -138,7 +139,7 @@ static void xform_instruction( file = inst->FullSrcRegisters[i].SrcRegister.File; if (!check_file_name( ctx, file )) - return; + return TRUE; index = inst->FullSrcRegisters[i].SrcRegister.Index; if (!is_register_declared( ctx, file, index )) report_error( ctx, "Undeclared source register" ); @@ -146,13 +147,16 @@ static void xform_instruction( } ctx->num_instructions++; + + return TRUE; } -static void xform_declaration( - struct tgsi_transform_context *xform, +static boolean +iter_declaration( + struct tgsi_iterate_context *iter, struct tgsi_full_declaration *decl ) { - struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) xform; + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; uint file; uint i; @@ -166,19 +170,22 @@ static void xform_declaration( */ file = decl->Declaration.File; if (!check_file_name( ctx, file )) - return; + return TRUE; for (i = decl->DeclarationRange.First; i <= decl->DeclarationRange.Last; i++) { if (is_register_declared( ctx, file, i )) report_error( ctx, "The same register declared twice" ); ctx->regs_decl[file][i / BITS_IN_REG_FLAG] |= (1 << (i % BITS_IN_REG_FLAG)); } + + return TRUE; } -static void xform_immediate( - struct tgsi_transform_context *xform, +static boolean +iter_immediate( + struct tgsi_iterate_context *iter, struct tgsi_full_immediate *imm ) { - struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) xform; + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; assert( ctx->num_imms < MAX_REGISTERS ); @@ -196,14 +203,17 @@ static void xform_immediate( */ if (imm->Immediate.DataType != TGSI_IMM_FLOAT32) { report_error( ctx, "Invalid immediate data type" ); - return; + return TRUE; } + + return TRUE; } -static void epilog( - struct tgsi_transform_context *xform ) +static boolean +epilog( + struct tgsi_iterate_context *iter ) { - struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) xform; + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; uint file; /* There must be an END instruction at the end. @@ -228,6 +238,8 @@ static void epilog( */ if (ctx->errors || ctx->warnings) debug_printf( "\n%u errors, %u warnings", ctx->errors, ctx->warnings ); + + return TRUE; } boolean @@ -235,12 +247,12 @@ tgsi_sanity_check( struct tgsi_token *tokens ) { struct sanity_check_ctx ctx; - struct tgsi_token dummy_tokens[16]; - ctx.xform.transform_instruction = xform_instruction; - ctx.xform.transform_declaration = xform_declaration; - ctx.xform.transform_immediate = xform_immediate; - ctx.xform.epilog = epilog; + ctx.iter.prolog = NULL; + ctx.iter.iterate_instruction = iter_instruction; + ctx.iter.iterate_declaration = iter_declaration; + ctx.iter.iterate_immediate = iter_immediate; + ctx.iter.epilog = epilog; memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) ); memset( ctx.regs_used, 0, sizeof( ctx.regs_used ) ); @@ -251,7 +263,7 @@ tgsi_sanity_check( ctx.errors = 0; ctx.warnings = 0; - if (tgsi_transform_shader( tokens, dummy_tokens, 16, &ctx.xform ) == -1) + if (tgsi_iterate_shader( tokens, &ctx.iter ) == -1) return FALSE; return ctx.errors > 0; -- cgit v1.2.3 From bfee84df8665a474fa025150f57d896bf1aa6bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 18 Jul 2008 10:11:29 +0900 Subject: python: Add methods to get texture width, height, etc. SWIG does a poor job with arrays inside structures. --- src/gallium/state_trackers/python/gallium.i | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index d5b24b04ff..c08ac87aca 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -401,6 +401,26 @@ error1: pipe_texture_reference(&ptr, NULL); } + unsigned get_width(unsigned level=0) { + return $self->width[level]; + } + + unsigned get_height(unsigned level=0) { + return $self->height[level]; + } + + unsigned get_depth(unsigned level=0) { + return $self->depth[level]; + } + + unsigned get_nblocksx(unsigned level=0) { + return $self->nblocksx[level]; + } + + unsigned get_nblocksy(unsigned level=0) { + return $self->nblocksy[level]; + } + /** Get a surface which is a "view" into a texture */ struct pipe_surface * get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0, unsigned usage=0 ) -- cgit v1.2.3 From 3ca935d9efaef4dd9746d3b2207e329b77bb1018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 18 Jul 2008 10:12:07 +0900 Subject: python/tests: Extend the texture tests to cover volumes. --- src/gallium/state_trackers/python/tests/texture.py | 65 ++++++++++++++-------- 1 file changed, 43 insertions(+), 22 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index 2c9231349f..16ad78c8aa 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -56,7 +56,12 @@ def tex_coords(texture, face, level, zslice): if texture.target == PIPE_TEXTURE_2D: return [[s, t, 0.0] for s, t in st] elif texture.target == PIPE_TEXTURE_3D: - assert 0 + depth = texture.get_depth(level) + if depth > 1: + r = float(zslice)/float(depth - 1) + else: + r = 0.0 + return [[s, t, r] for s, t in st] elif texture.target == PIPE_TEXTURE_CUBE: result = [] for s, t in st: @@ -112,10 +117,10 @@ class TextureTest(TestCase): }[self.face] else: face = "" - return "%s %s %ux%u last_level=%u %s level=%u" % ( + return "%s %s %ux%ux%u last_level=%u face=%s level=%u zslice=%u" % ( target, format, - self.width, self.height, - self.last_level, face, self.level, + self.width, self.height, self.depth, self.last_level, + face, self.level, self.zslice, ) def test(self): @@ -125,9 +130,11 @@ class TextureTest(TestCase): format = self.format width = self.width height = self.height + depth = self.depth last_level = self.last_level - level = self.level face = self.face + level = self.level + zslice = self.zslice if not dev.is_format_supported(format, PIPE_TEXTURE): raise TestSkip @@ -185,17 +192,21 @@ class TextureTest(TestCase): ctx.set_sampler(0, sampler) # texture - texture = dev.texture_create(target=target, - format=format, - width=width, - height=height, - last_level = last_level) + texture = dev.texture_create( + target = target, + format = format, + width = width, + height = height, + depth = depth, + last_level = last_level, + ) expected_rgba = FloatArray(height*width*4) texture.get_surface( usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE, face = face, level = level, + zslice = zslice, ).sample_rgba(expected_rgba) ctx.set_sampler_texture(0, texture) @@ -263,7 +274,7 @@ class TextureTest(TestCase): [x, y+h], ] - tex = tex_coords(texture, face, level, zslice=0) + tex = tex_coords(texture, face, level, zslice) for i in range(0, 4): j = 8*i @@ -313,6 +324,7 @@ def main(): targets = [] targets += [PIPE_TEXTURE_2D] targets += [PIPE_TEXTURE_CUBE] + targets += [PIPE_TEXTURE_3D] formats = [] formats += [PIPE_FORMAT_A8R8G8B8_UNORM] @@ -322,7 +334,9 @@ def main(): formats += [PIPE_FORMAT_DXT1_RGB] sizes = [64, 32, 16, 8, 4, 2, 1] + #sizes = [1020, 508, 252, 62, 30, 14, 6, 3] #sizes = [64] + #sizes = [63] for target in targets: for format in formats: @@ -339,21 +353,28 @@ def main(): #faces = [PIPE_TEX_FACE_NEG_X] else: faces = [0] + if target == PIPE_TEXTURE_3D: + depth = size + else: + depth = 1 for face in faces: levels = lods(size) for last_level in range(levels): for level in range(0, last_level + 1): - test = TextureTest( - dev=dev, - target=target, - format=format, - width=size, - height=size, - face=face, - last_level = last_level, - level=level, - ) - suite.add_test(test) + for zslice in range(0, depth >> level): + test = TextureTest( + dev = dev, + target = target, + format = format, + width = size, + height = size, + depth = depth, + last_level = last_level, + face = face, + level = level, + zslice = zslice, + ) + suite.add_test(test) suite.run() -- cgit v1.2.3 From 583b9ccbd5961678fa7e594c3117d7c895ef6b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 18 Jul 2008 22:22:22 +0900 Subject: gallium: Add a pf_is_ycbcr utility function. --- src/gallium/include/pipe/p_format.h | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index fefb8fdf1b..947c445583 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -522,15 +522,13 @@ pf_get_nblocks(const struct pipe_format_block *block, unsigned width, unsigned h static INLINE boolean pf_is_compressed( enum pipe_format format ) { - switch (format) { - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT5_RGBA: - return TRUE; - default: - return FALSE; - } + return pf_layout(format) == PIPE_FORMAT_LAYOUT_DXT ? TRUE : FALSE; +} + +static INLINE boolean +pf_is_ycbcr( enum pipe_format format ) +{ + return pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR ? TRUE : FALSE; } #ifdef __cplusplus -- cgit v1.2.3 From 1a8ceb3828c64fb758955c85a1d3d06f53f15ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 19 Jul 2008 08:38:35 +0900 Subject: gallium: Move PIPE_TEXTURE_USAGE* to p_defines.h --- src/gallium/include/pipe/p_defines.h | 6 ++++++ src/gallium/include/pipe/p_state.h | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index f8fadf31b6..bc4d7c845a 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -166,6 +166,12 @@ enum pipe_texture_target { #define PIPE_TEX_FACE_NEG_Z 5 #define PIPE_TEX_FACE_MAX 6 +#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1 +#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */ +#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */ +#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8 +#define PIPE_TEXTURE_USAGE_SAMPLER 0x10 + /** * Surfaces, textures, etc. (others may be added) */ diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 5546796936..2401305eb7 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -287,12 +287,6 @@ struct pipe_surface }; -#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1 -#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */ -#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */ -#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8 -#define PIPE_TEXTURE_USAGE_SAMPLER 0x10 - /** * Texture object. */ -- cgit v1.2.3 From ff26c50153b3a348b35843262ceb27062ab37214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 19 Jul 2008 11:52:41 +0900 Subject: tgsi: Make tgsi_sanity return TRUE on success as documented. --- src/gallium/auxiliary/tgsi/util/tgsi_sanity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c index 933127e661..7fc4c29c68 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c @@ -266,5 +266,5 @@ tgsi_sanity_check( if (tgsi_iterate_shader( tokens, &ctx.iter ) == -1) return FALSE; - return ctx.errors > 0; + return ctx.errors == 0; } -- cgit v1.2.3 From 8aafc03b260ab8923f1b373f7effa75bcdb40a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 19 Jul 2008 12:04:37 +0900 Subject: gallium: Finer grained is_format_supported. --- src/gallium/auxiliary/util/u_blit.c | 12 ++++++---- src/gallium/auxiliary/util/u_gen_mipmap.c | 3 ++- src/gallium/drivers/cell/ppu/cell_screen.c | 24 ++++++++------------ src/gallium/drivers/i915simple/i915_screen.c | 18 ++++++--------- src/gallium/drivers/i965simple/brw_screen.c | 5 ++++- src/gallium/drivers/softpipe/sp_screen.c | 26 +++++++++------------- src/gallium/include/pipe/p_defines.h | 7 ++---- src/gallium/include/pipe/p_screen.h | 9 +++++--- src/gallium/state_trackers/python/gallium.i | 15 +++++++++---- src/gallium/state_trackers/python/samples/tri.py | 8 ++++--- src/gallium/state_trackers/python/tests/texture.py | 13 ++++++----- 11 files changed, 73 insertions(+), 67 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 3dc9fdd11e..ae087df4cf 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -307,8 +307,10 @@ util_blit_pixels(struct blit_state *ctx, dstY1 = tmp; } - assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE)); - assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE)); + assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_SAMPLER, 0)); + assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_SAMPLER, 0)); if(dst->format == src->format && (dstX1 - dstX0) == srcW && (dstY1 - dstY0) == srcH) { /* FIXME: this will most surely fail for overlapping rectangles */ @@ -319,7 +321,8 @@ util_blit_pixels(struct blit_state *ctx, return; } - assert(screen->is_format_supported(screen, dst->format, PIPE_SURFACE)); + assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); /* * XXX for now we're always creating a temporary texture. @@ -449,7 +452,8 @@ util_blit_pixels_tex(struct blit_state *ctx, t0 = srcY0 / (float)tex->height[0]; t1 = srcY1 / (float)tex->height[0]; - assert(screen->is_format_supported(screen, dst->format, PIPE_SURFACE)); + assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); /* save state (restored below) */ cso_save_blend(ctx->cso); diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 5313a8008a..4999822068 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -858,7 +858,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, uint zslice = 0; /* check if we can render in the texture's format */ - if (!screen->is_format_supported(screen, pt->format, PIPE_SURFACE)) { + if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); return; } diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 5198b51441..cf9b68b695 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -115,23 +115,17 @@ cell_get_paramf(struct pipe_screen *screen, int param) static boolean cell_is_format_supported( struct pipe_screen *screen, - enum pipe_format format, uint type ) + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags ) { - switch (type) { - case PIPE_TEXTURE: - /* cell supports most texture formats, XXX for now anyway */ - if (format == PIPE_FORMAT_DXT5_RGBA || - format == PIPE_FORMAT_R8G8B8A8_SRGB) - return FALSE; - else - return TRUE; - case PIPE_SURFACE: - /* cell supports all (off-screen) surface formats, XXX for now */ - return TRUE; - default: - assert(0); + /* cell supports most formats, XXX for now anyway */ + if (format == PIPE_FORMAT_DXT5_RGBA || + format == PIPE_FORMAT_R8G8B8A8_SRGB) return FALSE; - } + else + return TRUE; } diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index ba8f183bdf..4b1b8af7da 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -148,7 +148,10 @@ i915_get_paramf(struct pipe_screen *screen, int param) static boolean i915_is_format_supported( struct pipe_screen *screen, - enum pipe_format format, uint type ) + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags ) { static const enum pipe_format tex_supported[] = { PIPE_FORMAT_R8G8B8A8_UNORM, @@ -173,17 +176,10 @@ i915_is_format_supported( struct pipe_screen *screen, const enum pipe_format *list; uint i; - switch (type) { - case PIPE_TEXTURE: - list = tex_supported; - break; - case PIPE_SURFACE: + if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) list = surface_supported; - break; - default: - assert(0); - return FALSE; - } + else + list = tex_supported; for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { if (list[i] == format) diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c index b700f7e4f5..6d8f24d1c4 100644 --- a/src/gallium/drivers/i965simple/brw_screen.c +++ b/src/gallium/drivers/i965simple/brw_screen.c @@ -136,7 +136,10 @@ brw_get_paramf(struct pipe_screen *screen, int param) static boolean brw_is_format_supported( struct pipe_screen *screen, - enum pipe_format format, uint type ) + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags ) { #if 0 /* XXX: This is broken -- rewrite if still needed. */ diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index f6193bfaf9..3f9d4b0ed3 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -115,23 +115,19 @@ softpipe_get_paramf(struct pipe_screen *screen, int param) */ static boolean softpipe_is_format_supported( struct pipe_screen *screen, - enum pipe_format format, uint type ) + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags ) { - switch (type) { - case PIPE_TEXTURE: - case PIPE_SURFACE: - switch(format) { - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT5_RGBA: - return FALSE; - default: - return TRUE; - } - default: - assert(0); + switch(format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: return FALSE; + default: + return TRUE; } } diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index bc4d7c845a..b1d100ef53 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -172,11 +172,8 @@ enum pipe_texture_target { #define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8 #define PIPE_TEXTURE_USAGE_SAMPLER 0x10 -/** - * Surfaces, textures, etc. (others may be added) - */ -#define PIPE_TEXTURE 1 -#define PIPE_SURFACE 2 /**< user-created surfaces */ +#define PIPE_TEXTURE_GEOM_NON_SQUARE 0x1 +#define PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO 0x2 /** diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index cc8430dae1..b15affef7a 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -77,11 +77,14 @@ struct pipe_screen { /** * Check if the given pipe_format is supported as a texture or * drawing surface. - * \param type one of PIPE_TEXTURE, PIPE_SURFACE + * \param tex_usage bitmask of PIPE_TEXTURE_USAGE_* + * \param flags bitmask of PIPE_TEXTURE_GEOM_* */ boolean (*is_format_supported)( struct pipe_screen *, - enum pipe_format format, - uint type ); + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags ); /** * Create a new texture object, using the given template info. diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index c08ac87aca..8d8b762ea5 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -158,8 +158,15 @@ struct st_context { * drawing surface. * \param type one of PIPE_TEXTURE, PIPE_SURFACE */ - int is_format_supported( enum pipe_format format, unsigned type ) { - return $self->screen->is_format_supported( $self->screen, format, type); + int is_format_supported( enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags ) { + return $self->screen->is_format_supported( $self->screen, + format, + target, + tex_usage, + geom_flags ); } struct st_context * @@ -175,7 +182,7 @@ struct st_context { unsigned depth = 1, unsigned last_level = 0, enum pipe_texture_target target = PIPE_TEXTURE_2D, - unsigned usage = 0 + unsigned tex_usage = 0 ) { struct pipe_texture templat; memset(&templat, 0, sizeof(templat)); @@ -186,7 +193,7 @@ struct st_context { templat.depth[0] = depth; templat.last_level = last_level; templat.target = target; - templat.tex_usage = usage; + templat.tex_usage = tex_usage; return $self->screen->texture_create($self->screen, &templat); } diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py index 3665922929..1271c67627 100644 --- a/src/gallium/state_trackers/python/samples/tri.py +++ b/src/gallium/state_trackers/python/samples/tri.py @@ -140,9 +140,11 @@ def test(dev): ctx.set_clip(clip) # framebuffer - cbuf = dev.texture_create(PIPE_FORMAT_X8R8G8B8_UNORM, - width, height, - usage=PIPE_TEXTURE_USAGE_DISPLAY_TARGET) + cbuf = dev.texture_create( + PIPE_FORMAT_X8R8G8B8_UNORM, + width, height, + tex_usage=PIPE_TEXTURE_USAGE_DISPLAY_TARGET, + ) _cbuf = cbuf.get_surface(usage = PIPE_BUFFER_USAGE_GPU_READ|PIPE_BUFFER_USAGE_GPU_WRITE) fb = Framebuffer() fb.width = width diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index 16ad78c8aa..b2ca9f416f 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -136,7 +136,7 @@ class TextureTest(TestCase): level = self.level zslice = self.zslice - if not dev.is_format_supported(format, PIPE_TEXTURE): + if not dev.is_format_supported(format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER, 0): raise TestSkip ctx = self.dev.context_create() @@ -199,6 +199,7 @@ class TextureTest(TestCase): height = height, depth = depth, last_level = last_level, + tex_usage = PIPE_TEXTURE_USAGE_SAMPLER, ) expected_rgba = FloatArray(height*width*4) @@ -212,10 +213,12 @@ class TextureTest(TestCase): ctx.set_sampler_texture(0, texture) # framebuffer - cbuf_tex = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, - width, - height, - usage = PIPE_TEXTURE_USAGE_RENDER_TARGET) + cbuf_tex = dev.texture_create( + PIPE_FORMAT_A8R8G8B8_UNORM, + width, + height, + tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET, + ) cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE|PIPE_BUFFER_USAGE_GPU_READ) fb = Framebuffer() -- cgit v1.2.3 From b1d6ff1afd3ec8460f746c76764dc89f9cd70556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 19 Jul 2008 12:30:54 +0900 Subject: python/tests: Specify the right texture target when querying formats. --- src/gallium/state_trackers/python/tests/texture.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index b2ca9f416f..861070c8d2 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -136,7 +136,7 @@ class TextureTest(TestCase): level = self.level zslice = self.zslice - if not dev.is_format_supported(format, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER, 0): + if not dev.is_format_supported(format, target, PIPE_TEXTURE_USAGE_SAMPLER, 0): raise TestSkip ctx = self.dev.context_create() @@ -364,7 +364,8 @@ def main(): levels = lods(size) for last_level in range(levels): for level in range(0, last_level + 1): - for zslice in range(0, depth >> level): + zslice = 0 + while zslice < depth >> level: test = TextureTest( dev = dev, target = target, @@ -378,6 +379,7 @@ def main(): zslice = zslice, ) suite.add_test(test) + zslice = (zslice + 1)*2 - 1 suite.run() -- cgit v1.2.3 From 43df2fe2d9fe242174aba58b5de191c3d1fff212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 20 Jul 2008 09:27:48 +0900 Subject: gallium: Fix typo in function name. --- src/gallium/auxiliary/util/p_tile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 1daae6b640..1bf0d72733 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -346,7 +346,7 @@ r5g6b5_get_tile_rgba(ushort *src, static void -r5g5b5_put_tile_rgba(ushort *dst, +r5g6b5_put_tile_rgba(ushort *dst, unsigned w, unsigned h, const float *p, unsigned src_stride) @@ -827,7 +827,7 @@ pipe_put_tile_rgba(struct pipe_surface *ps, /*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ break; case PIPE_FORMAT_R5G6B5_UNORM: - r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); + r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_R8G8B8A8_UNORM: assert(0); -- cgit v1.2.3 From 5853b6c2fe10223738a15d294e2a1605ec076953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 20 Jul 2008 09:28:27 +0900 Subject: python/tests: Check support for non-pot/non-square textures. --- src/gallium/state_trackers/python/tests/texture.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py index 861070c8d2..880a61306c 100644 --- a/src/gallium/state_trackers/python/tests/texture.py +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -94,7 +94,10 @@ def tex_coords(texture, face, level, zslice): rz = -1.0 result.append([rx, ry, rz]) return result - + +def is_pot(n): + return n & (n - 1) == 0 + class TextureTest(TestCase): @@ -136,7 +139,14 @@ class TextureTest(TestCase): level = self.level zslice = self.zslice - if not dev.is_format_supported(format, target, PIPE_TEXTURE_USAGE_SAMPLER, 0): + tex_usage = PIPE_TEXTURE_USAGE_SAMPLER + geom_flags = 0 + if width != height: + geom_flags |= PIPE_TEXTURE_GEOM_NON_SQUARE + if not is_pot(width) or not is_pot(height) or not is_pot(depth): + geom_flags |= PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO + + if not dev.is_format_supported(format, target, tex_usage, geom_flags): raise TestSkip ctx = self.dev.context_create() @@ -199,7 +209,7 @@ class TextureTest(TestCase): height = height, depth = depth, last_level = last_level, - tex_usage = PIPE_TEXTURE_USAGE_SAMPLER, + tex_usage = tex_usage, ) expected_rgba = FloatArray(height*width*4) -- cgit v1.2.3 From 2170ec9048eab751828700728c1cc8264c860229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 20 Jul 2008 18:11:43 +0900 Subject: pipebuffer: More detailed description of bufer over-/undereflows. --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c | 49 +++++++++++++++------- 1 file changed, 34 insertions(+), 15 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index affa6aa85c..d02e3500ff 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -109,7 +109,7 @@ static const uint8_t random_pattern[32] = { static INLINE void fill_random_pattern(uint8_t *dst, size_t size) { - unsigned i = 0; + size_t i = 0; while(size--) { *dst++ = random_pattern[i++]; i &= sizeof(random_pattern) - 1; @@ -118,15 +118,21 @@ fill_random_pattern(uint8_t *dst, size_t size) static INLINE boolean -check_random_pattern(const uint8_t *dst, size_t size) +check_random_pattern(const uint8_t *dst, size_t size, + size_t *min_ofs, size_t *max_ofs) { - unsigned i = 0; - while(size--) { - if(*dst++ != random_pattern[i++]) - return FALSE; - i &= sizeof(random_pattern) - 1; + boolean result = TRUE; + size_t i; + *min_ofs = size; + *max_ofs = 0; + for(i = 0; i < size; ++i) { + if(*dst++ != random_pattern[i % sizeof(random_pattern)]) { + *min_ofs = MIN2(*min_ofs, i); + *max_ofs = MIN2(*max_ofs, i); + result = FALSE; + } } - return TRUE; + return result; } @@ -141,15 +147,28 @@ pb_debug_buffer_destroy(struct pb_buffer *_buf) map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_CPU_READ); assert(map); if(map) { - if(!check_random_pattern(map, buf->underflow_size)) { - debug_error("buffer underflow detected\n"); - debug_assert(0); + boolean underflow, overflow; + size_t min_ofs, max_ofs; + + underflow = !check_random_pattern(map, buf->underflow_size, + &min_ofs, &max_ofs); + if(underflow) { + debug_printf("buffer underflow (%u of %u bytes) detected\n", + buf->underflow_size - min_ofs, + buf->underflow_size); } - if(!check_random_pattern(map + buf->underflow_size + buf->base.base.size, - buf->overflow_size)) { - debug_error("buffer overflow detected\n"); - debug_assert(0); + + overflow = !check_random_pattern(map + buf->underflow_size + buf->base.base.size, + buf->overflow_size, + &min_ofs, &max_ofs); + if(overflow) { + debug_printf("buffer overflow (%u of %u bytes) detected\n", + max_ofs, + buf->overflow_size); } + + debug_assert(!underflow && !overflow); + pb_unmap(buf->buffer); } -- cgit v1.2.3 From 5ded4ffc506eb051b151d3e8b1e71b13576e951a Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 16:01:50 +0200 Subject: tgsi: Split tgsi_dump into two modules. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 791 +----------------------- src/gallium/auxiliary/tgsi/util/tgsi_dump.h | 17 +- src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c | 853 ++++++++++++++++++++++++++ src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h | 49 ++ 4 files changed, 916 insertions(+), 794 deletions(-) create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c create mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 0cf4454f25..5a84b99166 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -27,7 +27,6 @@ #include "pipe/p_debug.h" #include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" #include "util/u_string.h" #include "tgsi_dump.h" #include "tgsi_parse.h" @@ -56,13 +55,6 @@ dump_enum( #define FLT(F) debug_printf( "%10.4f", F ) #define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) -static const char *TGSI_PROCESSOR_TYPES[] = -{ - "PROCESSOR_FRAGMENT", - "PROCESSOR_VERTEX", - "PROCESSOR_GEOMETRY" -}; - static const char *TGSI_PROCESSOR_TYPES_SHORT[] = { "FRAG", @@ -70,25 +62,6 @@ static const char *TGSI_PROCESSOR_TYPES_SHORT[] = "GEOM" }; -static const char *TGSI_TOKEN_TYPES[] = -{ - "TOKEN_TYPE_DECLARATION", - "TOKEN_TYPE_IMMEDIATE", - "TOKEN_TYPE_INSTRUCTION" -}; - -static const char *TGSI_FILES[] = -{ - "FILE_NULL", - "FILE_CONSTANT", - "FILE_INPUT", - "FILE_OUTPUT", - "FILE_TEMPORARY", - "FILE_SAMPLER", - "FILE_ADDRESS", - "FILE_IMMEDIATE" -}; - static const char *TGSI_FILES_SHORT[] = { "NULL", @@ -101,20 +74,6 @@ static const char *TGSI_FILES_SHORT[] = "IMM" }; -static const char *TGSI_DECLARES[] = -{ - "DECLARE_RANGE", - "DECLARE_MASK" -}; - -static const char *TGSI_INTERPOLATES[] = -{ - "INTERPOLATE_CONSTANT", - "INTERPOLATE_LINEAR", - "INTERPOLATE_PERSPECTIVE", - "INTERPOLATE_ATTRIB" -}; - static const char *TGSI_INTERPOLATES_SHORT[] = { "CONSTANT", @@ -122,17 +81,6 @@ static const char *TGSI_INTERPOLATES_SHORT[] = "PERSPECTIVE" }; -static const char *TGSI_SEMANTICS[] = -{ - "SEMANTIC_POSITION", - "SEMANTIC_COLOR", - "SEMANTIC_BCOLOR", - "SEMANTIC_FOG", - "SEMANTIC_PSIZE", - "SEMANTIC_GENERIC", - "SEMANTIC_NORMAL" -}; - static const char *TGSI_SEMANTICS_SHORT[] = { "POSITION", @@ -144,138 +92,11 @@ static const char *TGSI_SEMANTICS_SHORT[] = "NORMAL" }; -static const char *TGSI_IMMS[] = -{ - "IMM_FLOAT32" -}; - static const char *TGSI_IMMS_SHORT[] = { "FLT32" }; -static const char *TGSI_OPCODES[TGSI_OPCODE_LAST] = -{ - "OPCODE_ARL", - "OPCODE_MOV", - "OPCODE_LIT", - "OPCODE_RCP", - "OPCODE_RSQ", - "OPCODE_EXP", - "OPCODE_LOG", - "OPCODE_MUL", - "OPCODE_ADD", - "OPCODE_DP3", - "OPCODE_DP4", - "OPCODE_DST", - "OPCODE_MIN", - "OPCODE_MAX", - "OPCODE_SLT", - "OPCODE_SGE", - "OPCODE_MAD", - "OPCODE_SUB", - "OPCODE_LERP", - "OPCODE_CND", - "OPCODE_CND0", - "OPCODE_DOT2ADD", - "OPCODE_INDEX", - "OPCODE_NEGATE", - "OPCODE_FRAC", - "OPCODE_CLAMP", - "OPCODE_FLOOR", - "OPCODE_ROUND", - "OPCODE_EXPBASE2", - "OPCODE_LOGBASE2", - "OPCODE_POWER", - "OPCODE_CROSSPRODUCT", - "OPCODE_MULTIPLYMATRIX", - "OPCODE_ABS", - "OPCODE_RCC", - "OPCODE_DPH", - "OPCODE_COS", - "OPCODE_DDX", - "OPCODE_DDY", - "OPCODE_KILP", - "OPCODE_PK2H", - "OPCODE_PK2US", - "OPCODE_PK4B", - "OPCODE_PK4UB", - "OPCODE_RFL", - "OPCODE_SEQ", - "OPCODE_SFL", - "OPCODE_SGT", - "OPCODE_SIN", - "OPCODE_SLE", - "OPCODE_SNE", - "OPCODE_STR", - "OPCODE_TEX", - "OPCODE_TXD", - "OPCODE_TXP", - "OPCODE_UP2H", - "OPCODE_UP2US", - "OPCODE_UP4B", - "OPCODE_UP4UB", - "OPCODE_X2D", - "OPCODE_ARA", - "OPCODE_ARR", - "OPCODE_BRA", - "OPCODE_CAL", - "OPCODE_RET", - "OPCODE_SSG", - "OPCODE_CMP", - "OPCODE_SCS", - "OPCODE_TXB", - "OPCODE_NRM", - "OPCODE_DIV", - "OPCODE_DP2", - "OPCODE_TXL", - "OPCODE_BRK", - "OPCODE_IF", - "OPCODE_LOOP", - "OPCODE_REP", - "OPCODE_ELSE", - "OPCODE_ENDIF", - "OPCODE_ENDLOOP", - "OPCODE_ENDREP", - "OPCODE_PUSHA", - "OPCODE_POPA", - "OPCODE_CEIL", - "OPCODE_I2F", - "OPCODE_NOT", - "OPCODE_TRUNC", - "OPCODE_SHL", - "OPCODE_SHR", - "OPCODE_AND", - "OPCODE_OR", - "OPCODE_MOD", - "OPCODE_XOR", - "OPCODE_SAD", - "OPCODE_TXF", - "OPCODE_TXQ", - "OPCODE_CONT", - "OPCODE_EMIT", - "OPCODE_ENDPRIM", - "OPCODE_BGNLOOP2", - "OPCODE_BGNSUB", - "OPCODE_ENDLOOP2", - "OPCODE_ENDSUB", - "OPCODE_NOISE1", - "OPCODE_NOISE2", - "OPCODE_NOISE3", - "OPCODE_NOISE4", - "OPCODE_NOP", - "OPCODE_M4X3", - "OPCODE_M3X4", - "OPCODE_M3X3", - "OPCODE_M3X2", - "OPCODE_NRM4", - "OPCODE_CALLNZ", - "OPCODE_IFC", - "OPCODE_BREAKC", - "OPCODE_KIL", - "OPCODE_END" -}; - static const char *TGSI_OPCODES_SHORT[TGSI_OPCODE_LAST] = { "ARL", @@ -399,49 +220,6 @@ static const char *TGSI_OPCODES_SHORT[TGSI_OPCODE_LAST] = "SWZ" }; -static const char *TGSI_SATS[] = -{ - "SAT_NONE", - "SAT_ZERO_ONE", - "SAT_MINUS_PLUS_ONE" -}; - -static const char *TGSI_INSTRUCTION_EXTS[] = -{ - "INSTRUCTION_EXT_TYPE_NV", - "INSTRUCTION_EXT_TYPE_LABEL", - "INSTRUCTION_EXT_TYPE_TEXTURE" -}; - -static const char *TGSI_PRECISIONS[] = -{ - "PRECISION_DEFAULT", - "TGSI_PRECISION_FLOAT32", - "TGSI_PRECISION_FLOAT16", - "TGSI_PRECISION_FIXED12" -}; - -static const char *TGSI_CCS[] = -{ - "CC_GT", - "CC_EQ", - "CC_LT", - "CC_UN", - "CC_GE", - "CC_LE", - "CC_NE", - "CC_TR", - "CC_FL" -}; - -static const char *TGSI_SWIZZLES[] = -{ - "SWIZZLE_X", - "SWIZZLE_Y", - "SWIZZLE_Z", - "SWIZZLE_W" -}; - static const char *TGSI_SWIZZLES_SHORT[] = { "x", @@ -450,19 +228,6 @@ static const char *TGSI_SWIZZLES_SHORT[] = "w" }; -static const char *TGSI_TEXTURES[] = -{ - "TEXTURE_UNKNOWN", - "TEXTURE_1D", - "TEXTURE_2D", - "TEXTURE_3D", - "TEXTURE_CUBE", - "TEXTURE_RECT", - "TEXTURE_SHADOW1D", - "TEXTURE_SHADOW2D", - "TEXTURE_SHADOWRECT" -}; - static const char *TGSI_TEXTURES_SHORT[] = { "UNKNOWN", @@ -476,22 +241,6 @@ static const char *TGSI_TEXTURES_SHORT[] = "SHADOWRECT" }; -static const char *TGSI_SRC_REGISTER_EXTS[] = -{ - "SRC_REGISTER_EXT_TYPE_SWZ", - "SRC_REGISTER_EXT_TYPE_MOD" -}; - -static const char *TGSI_EXTSWIZZLES[] = -{ - "EXTSWIZZLE_X", - "EXTSWIZZLE_Y", - "EXTSWIZZLE_Z", - "EXTSWIZZLE_W", - "EXTSWIZZLE_ZERO", - "EXTSWIZZLE_ONE" -}; - static const char *TGSI_EXTSWIZZLES_SHORT[] = { "x", @@ -502,43 +251,6 @@ static const char *TGSI_EXTSWIZZLES_SHORT[] = "1" }; -static const char *TGSI_WRITEMASKS[] = -{ - "0", - "WRITEMASK_X", - "WRITEMASK_Y", - "WRITEMASK_XY", - "WRITEMASK_Z", - "WRITEMASK_XZ", - "WRITEMASK_YZ", - "WRITEMASK_XYZ", - "WRITEMASK_W", - "WRITEMASK_XW", - "WRITEMASK_YW", - "WRITEMASK_XYW", - "WRITEMASK_ZW", - "WRITEMASK_XZW", - "WRITEMASK_YZW", - "WRITEMASK_XYZW" -}; - -static const char *TGSI_DST_REGISTER_EXTS[] = -{ - "DST_REGISTER_EXT_TYPE_CONDCODE", - "DST_REGISTER_EXT_TYPE_MODULATE" -}; - -static const char *TGSI_MODULATES[] = -{ - "MODULATE_1X", - "MODULATE_2X", - "MODULATE_4X", - "MODULATE_8X", - "MODULATE_HALF", - "MODULATE_QUARTER", - "MODULATE_EIGHTH" -}; - static const char *TGSI_MODULATES_SHORT[TGSI_MODULATE_COUNT] = { "", @@ -552,7 +264,7 @@ static const char *TGSI_MODULATES_SHORT[TGSI_MODULATE_COUNT] = void tgsi_dump_declaration( - const struct tgsi_full_declaration *decl ) + const struct tgsi_full_declaration *decl ) { TXT( "\nDCL " ); ENM( decl->Declaration.File, TGSI_FILES_SHORT ); @@ -596,62 +308,6 @@ tgsi_dump_declaration( ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES_SHORT ); } -static void -dump_declaration_verbose( - struct tgsi_full_declaration *decl, - unsigned ignored, - unsigned deflt, - struct tgsi_full_declaration *fd ) -{ - TXT( "\nFile : " ); - ENM( decl->Declaration.File, TGSI_FILES ); - if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) { - TXT( "\nUsageMask : " ); - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { - CHR( 'X' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { - CHR( 'Y' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { - CHR( 'Z' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { - CHR( 'W' ); - } - } - if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) { - TXT( "\nInterpolate: " ); - ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES ); - } - if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) { - TXT( "\nSemantic : " ); - UID( decl->Declaration.Semantic ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( decl->Declaration.Padding ); - } - - EOL(); - TXT( "\nFirst: " ); - UID( decl->DeclarationRange.First ); - TXT( "\nLast : " ); - UID( decl->DeclarationRange.Last ); - - if( decl->Declaration.Semantic ) { - EOL(); - TXT( "\nSemanticName : " ); - ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS ); - TXT( "\nSemanticIndex: " ); - UID( decl->Semantic.SemanticIndex ); - if( ignored ) { - TXT( "\nPadding : " ); - UIX( decl->Semantic.Padding ); - } - } -} - void tgsi_dump_immediate( const struct tgsi_full_immediate *imm ) @@ -679,38 +335,10 @@ tgsi_dump_immediate( TXT( " }" ); } -static void -dump_immediate_verbose( - struct tgsi_full_immediate *imm, - unsigned ignored ) -{ - unsigned i; - - TXT( "\nDataType : " ); - ENM( imm->Immediate.DataType, TGSI_IMMS ); - if( ignored ) { - TXT( "\nPadding : " ); - UIX( imm->Immediate.Padding ); - } - - for( i = 0; i < imm->Immediate.Size - 1; i++ ) { - EOL(); - switch( imm->Immediate.DataType ) { - case TGSI_IMM_FLOAT32: - TXT( "\nFloat: " ); - FLT( imm->u.ImmediateFloat32[i].Float ); - break; - - default: - assert( 0 ); - } - } -} - void tgsi_dump_instruction( - const struct tgsi_full_instruction *inst, - unsigned instno ) + const struct tgsi_full_instruction *inst, + uint instno ) { unsigned i; boolean first_reg = TRUE; @@ -856,389 +484,28 @@ tgsi_dump_instruction( } } -static void -dump_instruction_verbose( - struct tgsi_full_instruction *inst, - unsigned ignored, - unsigned deflt, - struct tgsi_full_instruction *fi ) -{ - unsigned i; - - TXT( "\nOpcode : " ); - ENM( inst->Instruction.Opcode, TGSI_OPCODES ); - if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) { - TXT( "\nSaturate : " ); - ENM( inst->Instruction.Saturate, TGSI_SATS ); - } - if( deflt || fi->Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) { - TXT( "\nNumDstRegs : " ); - UID( inst->Instruction.NumDstRegs ); - } - if( deflt || fi->Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) { - TXT( "\nNumSrcRegs : " ); - UID( inst->Instruction.NumSrcRegs ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->Instruction.Padding ); - } - - if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi->InstructionExtNv ) ) { - EOL(); - TXT( "\nType : " ); - ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS ); - if( deflt || fi->InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) { - TXT( "\nPrecision : " ); - ENM( inst->InstructionExtNv.Precision, TGSI_PRECISIONS ); - } - if( deflt || fi->InstructionExtNv.CondDstIndex != inst->InstructionExtNv.CondDstIndex ) { - TXT( "\nCondDstIndex : " ); - UID( inst->InstructionExtNv.CondDstIndex ); - } - if( deflt || fi->InstructionExtNv.CondFlowIndex != inst->InstructionExtNv.CondFlowIndex ) { - TXT( "\nCondFlowIndex : " ); - UID( inst->InstructionExtNv.CondFlowIndex ); - } - if( deflt || fi->InstructionExtNv.CondMask != inst->InstructionExtNv.CondMask ) { - TXT( "\nCondMask : " ); - ENM( inst->InstructionExtNv.CondMask, TGSI_CCS ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleX != inst->InstructionExtNv.CondSwizzleX ) { - TXT( "\nCondSwizzleX : " ); - ENM( inst->InstructionExtNv.CondSwizzleX, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleY != inst->InstructionExtNv.CondSwizzleY ) { - TXT( "\nCondSwizzleY : " ); - ENM( inst->InstructionExtNv.CondSwizzleY, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleZ != inst->InstructionExtNv.CondSwizzleZ ) { - TXT( "\nCondSwizzleZ : " ); - ENM( inst->InstructionExtNv.CondSwizzleZ, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleW != inst->InstructionExtNv.CondSwizzleW ) { - TXT( "\nCondSwizzleW : " ); - ENM( inst->InstructionExtNv.CondSwizzleW, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondDstUpdate != inst->InstructionExtNv.CondDstUpdate ) { - TXT( "\nCondDstUpdate : " ); - UID( inst->InstructionExtNv.CondDstUpdate ); - } - if( deflt || fi->InstructionExtNv.CondFlowEnable != inst->InstructionExtNv.CondFlowEnable ) { - TXT( "\nCondFlowEnable: " ); - UID( inst->InstructionExtNv.CondFlowEnable ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->InstructionExtNv.Padding ); - if( deflt || fi->InstructionExtNv.Extended != inst->InstructionExtNv.Extended ) { - TXT( "\nExtended : " ); - UID( inst->InstructionExtNv.Extended ); - } - } - } - - if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) { - EOL(); - TXT( "\nType : " ); - ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS ); - if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) { - TXT( "\nLabel : " ); - UID( inst->InstructionExtLabel.Label ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->InstructionExtLabel.Padding ); - if( deflt || fi->InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) { - TXT( "\nExtended: " ); - UID( inst->InstructionExtLabel.Extended ); - } - } - } - - if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) { - EOL(); - TXT( "\nType : " ); - ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS ); - if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) { - TXT( "\nTexture : " ); - ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->InstructionExtTexture.Padding ); - if( deflt || fi->InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) { - TXT( "\nExtended: " ); - UID( inst->InstructionExtTexture.Extended ); - } - } - } - - for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i]; - - EOL(); - TXT( "\nFile : " ); - ENM( dst->DstRegister.File, TGSI_FILES ); - if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) { - TXT( "\nWriteMask: " ); - ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS ); - } - if( ignored ) { - if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) { - TXT( "\nIndirect : " ); - UID( dst->DstRegister.Indirect ); - } - if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) { - TXT( "\nDimension: " ); - UID( dst->DstRegister.Dimension ); - } - } - if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) { - TXT( "\nIndex : " ); - SID( dst->DstRegister.Index ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( dst->DstRegister.Padding ); - if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) { - TXT( "\nExtended : " ); - UID( dst->DstRegister.Extended ); - } - } - - if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) { - EOL(); - TXT( "\nType : " ); - ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS ); - if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) { - TXT( "\nCondMask : " ); - ENM( dst->DstRegisterExtConcode.CondMask, TGSI_CCS ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleX != dst->DstRegisterExtConcode.CondSwizzleX ) { - TXT( "\nCondSwizzleX: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleX, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleY != dst->DstRegisterExtConcode.CondSwizzleY ) { - TXT( "\nCondSwizzleY: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleY, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleZ != dst->DstRegisterExtConcode.CondSwizzleZ ) { - TXT( "\nCondSwizzleZ: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleZ, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleW != dst->DstRegisterExtConcode.CondSwizzleW ) { - TXT( "\nCondSwizzleW: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleW, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSrcIndex != dst->DstRegisterExtConcode.CondSrcIndex ) { - TXT( "\nCondSrcIndex: " ); - UID( dst->DstRegisterExtConcode.CondSrcIndex ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( dst->DstRegisterExtConcode.Padding ); - if( deflt || fd->DstRegisterExtConcode.Extended != dst->DstRegisterExtConcode.Extended ) { - TXT( "\nExtended : " ); - UID( dst->DstRegisterExtConcode.Extended ); - } - } - } - - if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) { - EOL(); - TXT( "\nType : " ); - ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS ); - if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) { - TXT( "\nModulate: " ); - ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( dst->DstRegisterExtModulate.Padding ); - if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) { - TXT( "\nExtended: " ); - UID( dst->DstRegisterExtModulate.Extended ); - } - } - } - } - - for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i]; - - EOL(); - TXT( "\nFile : "); - ENM( src->SrcRegister.File, TGSI_FILES ); - if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) { - TXT( "\nSwizzleX : " ); - ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) { - TXT( "\nSwizzleY : " ); - ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) { - TXT( "\nSwizzleZ : " ); - ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) { - TXT( "\nSwizzleW : " ); - ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) { - TXT( "\nNegate : " ); - UID( src->SrcRegister.Negate ); - } - if( ignored ) { - if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) { - TXT( "\nIndirect : " ); - UID( src->SrcRegister.Indirect ); - } - if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) { - TXT( "\nDimension: " ); - UID( src->SrcRegister.Dimension ); - } - } - if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) { - TXT( "\nIndex : " ); - SID( src->SrcRegister.Index ); - } - if( ignored ) { - if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) { - TXT( "\nExtended : " ); - UID( src->SrcRegister.Extended ); - } - } - - if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) { - EOL(); - TXT( "\nType : " ); - ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS ); - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) { - TXT( "\nExtSwizzleX: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleY != src->SrcRegisterExtSwz.ExtSwizzleY ) { - TXT( "\nExtSwizzleY: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleZ != src->SrcRegisterExtSwz.ExtSwizzleZ ) { - TXT( "\nExtSwizzleZ: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleW != src->SrcRegisterExtSwz.ExtSwizzleW ) { - TXT( "\nExtSwizzleW: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateX != src->SrcRegisterExtSwz.NegateX ) { - TXT( "\nNegateX : " ); - UID( src->SrcRegisterExtSwz.NegateX ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateY != src->SrcRegisterExtSwz.NegateY ) { - TXT( "\nNegateY : " ); - UID( src->SrcRegisterExtSwz.NegateY ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateZ != src->SrcRegisterExtSwz.NegateZ ) { - TXT( "\nNegateZ : " ); - UID( src->SrcRegisterExtSwz.NegateZ ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateW != src->SrcRegisterExtSwz.NegateW ) { - TXT( "\nNegateW : " ); - UID( src->SrcRegisterExtSwz.NegateW ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( src->SrcRegisterExtSwz.Padding ); - if( deflt || fs->SrcRegisterExtSwz.Extended != src->SrcRegisterExtSwz.Extended ) { - TXT( "\nExtended : " ); - UID( src->SrcRegisterExtSwz.Extended ); - } - } - } - - if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) { - EOL(); - TXT( "\nType : " ); - ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS ); - if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) { - TXT( "\nComplement: " ); - UID( src->SrcRegisterExtMod.Complement ); - } - if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) { - TXT( "\nBias : " ); - UID( src->SrcRegisterExtMod.Bias ); - } - if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) { - TXT( "\nScale2X : " ); - UID( src->SrcRegisterExtMod.Scale2X ); - } - if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) { - TXT( "\nAbsolute : " ); - UID( src->SrcRegisterExtMod.Absolute ); - } - if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) { - TXT( "\nNegate : " ); - UID( src->SrcRegisterExtMod.Negate ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( src->SrcRegisterExtMod.Padding ); - if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) { - TXT( "\nExtended : " ); - UID( src->SrcRegisterExtMod.Extended ); - } - } - } - } -} - void tgsi_dump( - const struct tgsi_token *tokens, - unsigned flags ) + const struct tgsi_token *tokens ) { struct tgsi_parse_context parse; struct tgsi_full_instruction fi; struct tgsi_full_declaration fd; - unsigned verbose = flags & TGSI_DUMP_VERBOSE; - unsigned ignored = !(flags & TGSI_DUMP_NO_IGNORED); - unsigned deflt = !(flags & TGSI_DUMP_NO_DEFAULT); unsigned instno = 0; /* sanity checks */ - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); + assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); + assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "OPCODE_END") == 0); assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "END") == 0); tgsi_parse_init( &parse, tokens ); - TXT( "tgsi-dump begin -----------------" ); - EOL(); ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES_SHORT ); UID( parse.FullVersion.Version.MajorVersion ); CHR( '.' ); UID( parse.FullVersion.Version.MinorVersion ); - if( verbose ) { - TXT( "\nMajorVersion: " ); - UID( parse.FullVersion.Version.MajorVersion ); - TXT( "\nMinorVersion: " ); - UID( parse.FullVersion.Version.MinorVersion ); - EOL(); - - TXT( "\nHeaderSize: " ); - UID( parse.FullHeader.Header.HeaderSize ); - TXT( "\nBodySize : " ); - UID( parse.FullHeader.Header.BodySize ); - TXT( "\nProcessor : " ); - ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); - EOL(); - } - fi = tgsi_default_full_instruction(); fd = tgsi_default_full_declaration(); @@ -1266,51 +533,7 @@ tgsi_dump( default: assert( 0 ); } - - if( verbose ) { - TXT( "\nType : " ); - ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES ); - if( ignored ) { - TXT( "\nSize : " ); - UID( parse.FullToken.Token.Size ); - if( deflt || parse.FullToken.Token.Extended ) { - TXT( "\nExtended : " ); - UID( parse.FullToken.Token.Extended ); - } - } - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - dump_declaration_verbose( - &parse.FullToken.FullDeclaration, - ignored, - deflt, - &fd ); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - dump_immediate_verbose( - &parse.FullToken.FullImmediate, - ignored ); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - dump_instruction_verbose( - &parse.FullToken.FullInstruction, - ignored, - deflt, - &fi ); - break; - - default: - assert( 0 ); - } - - EOL(); - } } - TXT( "\ntgsi-dump end -------------------\n" ); - tgsi_parse_free( &parse ); } diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h index ba7692b511..c130b9f1b7 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -28,18 +28,15 @@ #ifndef TGSI_DUMP_H #define TGSI_DUMP_H +#include "pipe/p_shader_tokens.h" + #if defined __cplusplus extern "C" { #endif -#define TGSI_DUMP_VERBOSE 1 -#define TGSI_DUMP_NO_IGNORED 2 -#define TGSI_DUMP_NO_DEFAULT 4 - void tgsi_dump( - const struct tgsi_token *tokens, - unsigned flags ); + const struct tgsi_token *tokens ); struct tgsi_full_immediate; struct tgsi_full_instruction; @@ -51,12 +48,12 @@ tgsi_dump_immediate( void tgsi_dump_instruction( - const struct tgsi_full_instruction *inst, - unsigned instno ); + const struct tgsi_full_instruction *inst, + uint instno ); void tgsi_dump_declaration( - const struct tgsi_full_declaration *decl ); + const struct tgsi_full_declaration *decl ); #if defined __cplusplus } diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c new file mode 100644 index 0000000000..27b085dc07 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c @@ -0,0 +1,853 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "util/u_string.h" +#include "tgsi_dump_c.h" +#include "tgsi_parse.h" +#include "tgsi_build.h" + +static void +dump_enum( + const unsigned e, + const char **enums, + const unsigned enums_count ) +{ + if (e >= enums_count) { + debug_printf( "%u", e ); + } + else { + debug_printf( "%s", enums[e] ); + } +} + +#define EOL() debug_printf( "\n" ) +#define TXT(S) debug_printf( "%s", S ) +#define CHR(C) debug_printf( "%c", C ) +#define UIX(I) debug_printf( "0x%x", I ) +#define UID(I) debug_printf( "%u", I ) +#define SID(I) debug_printf( "%d", I ) +#define FLT(F) debug_printf( "%10.4f", F ) +#define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) + +static const char *TGSI_PROCESSOR_TYPES[] = +{ + "PROCESSOR_FRAGMENT", + "PROCESSOR_VERTEX", + "PROCESSOR_GEOMETRY" +}; + +static const char *TGSI_TOKEN_TYPES[] = +{ + "TOKEN_TYPE_DECLARATION", + "TOKEN_TYPE_IMMEDIATE", + "TOKEN_TYPE_INSTRUCTION" +}; + +static const char *TGSI_FILES[] = +{ + "FILE_NULL", + "FILE_CONSTANT", + "FILE_INPUT", + "FILE_OUTPUT", + "FILE_TEMPORARY", + "FILE_SAMPLER", + "FILE_ADDRESS", + "FILE_IMMEDIATE" +}; + +static const char *TGSI_DECLARES[] = +{ + "DECLARE_RANGE", + "DECLARE_MASK" +}; + +static const char *TGSI_INTERPOLATES[] = +{ + "INTERPOLATE_CONSTANT", + "INTERPOLATE_LINEAR", + "INTERPOLATE_PERSPECTIVE", + "INTERPOLATE_ATTRIB" +}; + +static const char *TGSI_SEMANTICS[] = +{ + "SEMANTIC_POSITION", + "SEMANTIC_COLOR", + "SEMANTIC_BCOLOR", + "SEMANTIC_FOG", + "SEMANTIC_PSIZE", + "SEMANTIC_GENERIC", + "SEMANTIC_NORMAL" +}; + +static const char *TGSI_IMMS[] = +{ + "IMM_FLOAT32" +}; + +static const char *TGSI_OPCODES[TGSI_OPCODE_LAST] = +{ + "OPCODE_ARL", + "OPCODE_MOV", + "OPCODE_LIT", + "OPCODE_RCP", + "OPCODE_RSQ", + "OPCODE_EXP", + "OPCODE_LOG", + "OPCODE_MUL", + "OPCODE_ADD", + "OPCODE_DP3", + "OPCODE_DP4", + "OPCODE_DST", + "OPCODE_MIN", + "OPCODE_MAX", + "OPCODE_SLT", + "OPCODE_SGE", + "OPCODE_MAD", + "OPCODE_SUB", + "OPCODE_LERP", + "OPCODE_CND", + "OPCODE_CND0", + "OPCODE_DOT2ADD", + "OPCODE_INDEX", + "OPCODE_NEGATE", + "OPCODE_FRAC", + "OPCODE_CLAMP", + "OPCODE_FLOOR", + "OPCODE_ROUND", + "OPCODE_EXPBASE2", + "OPCODE_LOGBASE2", + "OPCODE_POWER", + "OPCODE_CROSSPRODUCT", + "OPCODE_MULTIPLYMATRIX", + "OPCODE_ABS", + "OPCODE_RCC", + "OPCODE_DPH", + "OPCODE_COS", + "OPCODE_DDX", + "OPCODE_DDY", + "OPCODE_KILP", + "OPCODE_PK2H", + "OPCODE_PK2US", + "OPCODE_PK4B", + "OPCODE_PK4UB", + "OPCODE_RFL", + "OPCODE_SEQ", + "OPCODE_SFL", + "OPCODE_SGT", + "OPCODE_SIN", + "OPCODE_SLE", + "OPCODE_SNE", + "OPCODE_STR", + "OPCODE_TEX", + "OPCODE_TXD", + "OPCODE_TXP", + "OPCODE_UP2H", + "OPCODE_UP2US", + "OPCODE_UP4B", + "OPCODE_UP4UB", + "OPCODE_X2D", + "OPCODE_ARA", + "OPCODE_ARR", + "OPCODE_BRA", + "OPCODE_CAL", + "OPCODE_RET", + "OPCODE_SSG", + "OPCODE_CMP", + "OPCODE_SCS", + "OPCODE_TXB", + "OPCODE_NRM", + "OPCODE_DIV", + "OPCODE_DP2", + "OPCODE_TXL", + "OPCODE_BRK", + "OPCODE_IF", + "OPCODE_LOOP", + "OPCODE_REP", + "OPCODE_ELSE", + "OPCODE_ENDIF", + "OPCODE_ENDLOOP", + "OPCODE_ENDREP", + "OPCODE_PUSHA", + "OPCODE_POPA", + "OPCODE_CEIL", + "OPCODE_I2F", + "OPCODE_NOT", + "OPCODE_TRUNC", + "OPCODE_SHL", + "OPCODE_SHR", + "OPCODE_AND", + "OPCODE_OR", + "OPCODE_MOD", + "OPCODE_XOR", + "OPCODE_SAD", + "OPCODE_TXF", + "OPCODE_TXQ", + "OPCODE_CONT", + "OPCODE_EMIT", + "OPCODE_ENDPRIM", + "OPCODE_BGNLOOP2", + "OPCODE_BGNSUB", + "OPCODE_ENDLOOP2", + "OPCODE_ENDSUB", + "OPCODE_NOISE1", + "OPCODE_NOISE2", + "OPCODE_NOISE3", + "OPCODE_NOISE4", + "OPCODE_NOP", + "OPCODE_M4X3", + "OPCODE_M3X4", + "OPCODE_M3X3", + "OPCODE_M3X2", + "OPCODE_NRM4", + "OPCODE_CALLNZ", + "OPCODE_IFC", + "OPCODE_BREAKC", + "OPCODE_KIL", + "OPCODE_END" +}; + +static const char *TGSI_SATS[] = +{ + "SAT_NONE", + "SAT_ZERO_ONE", + "SAT_MINUS_PLUS_ONE" +}; + +static const char *TGSI_INSTRUCTION_EXTS[] = +{ + "INSTRUCTION_EXT_TYPE_NV", + "INSTRUCTION_EXT_TYPE_LABEL", + "INSTRUCTION_EXT_TYPE_TEXTURE" +}; + +static const char *TGSI_PRECISIONS[] = +{ + "PRECISION_DEFAULT", + "TGSI_PRECISION_FLOAT32", + "TGSI_PRECISION_FLOAT16", + "TGSI_PRECISION_FIXED12" +}; + +static const char *TGSI_CCS[] = +{ + "CC_GT", + "CC_EQ", + "CC_LT", + "CC_UN", + "CC_GE", + "CC_LE", + "CC_NE", + "CC_TR", + "CC_FL" +}; + +static const char *TGSI_SWIZZLES[] = +{ + "SWIZZLE_X", + "SWIZZLE_Y", + "SWIZZLE_Z", + "SWIZZLE_W" +}; + +static const char *TGSI_TEXTURES[] = +{ + "TEXTURE_UNKNOWN", + "TEXTURE_1D", + "TEXTURE_2D", + "TEXTURE_3D", + "TEXTURE_CUBE", + "TEXTURE_RECT", + "TEXTURE_SHADOW1D", + "TEXTURE_SHADOW2D", + "TEXTURE_SHADOWRECT" +}; + +static const char *TGSI_SRC_REGISTER_EXTS[] = +{ + "SRC_REGISTER_EXT_TYPE_SWZ", + "SRC_REGISTER_EXT_TYPE_MOD" +}; + +static const char *TGSI_EXTSWIZZLES[] = +{ + "EXTSWIZZLE_X", + "EXTSWIZZLE_Y", + "EXTSWIZZLE_Z", + "EXTSWIZZLE_W", + "EXTSWIZZLE_ZERO", + "EXTSWIZZLE_ONE" +}; + +static const char *TGSI_WRITEMASKS[] = +{ + "0", + "WRITEMASK_X", + "WRITEMASK_Y", + "WRITEMASK_XY", + "WRITEMASK_Z", + "WRITEMASK_XZ", + "WRITEMASK_YZ", + "WRITEMASK_XYZ", + "WRITEMASK_W", + "WRITEMASK_XW", + "WRITEMASK_YW", + "WRITEMASK_XYW", + "WRITEMASK_ZW", + "WRITEMASK_XZW", + "WRITEMASK_YZW", + "WRITEMASK_XYZW" +}; + +static const char *TGSI_DST_REGISTER_EXTS[] = +{ + "DST_REGISTER_EXT_TYPE_CONDCODE", + "DST_REGISTER_EXT_TYPE_MODULATE" +}; + +static const char *TGSI_MODULATES[] = +{ + "MODULATE_1X", + "MODULATE_2X", + "MODULATE_4X", + "MODULATE_8X", + "MODULATE_HALF", + "MODULATE_QUARTER", + "MODULATE_EIGHTH" +}; + +static void +dump_declaration_verbose( + struct tgsi_full_declaration *decl, + unsigned ignored, + unsigned deflt, + struct tgsi_full_declaration *fd ) +{ + TXT( "\nFile : " ); + ENM( decl->Declaration.File, TGSI_FILES ); + if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) { + TXT( "\nUsageMask : " ); + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { + CHR( 'X' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { + CHR( 'Y' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { + CHR( 'Z' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { + CHR( 'W' ); + } + } + if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) { + TXT( "\nInterpolate: " ); + ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES ); + } + if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) { + TXT( "\nSemantic : " ); + UID( decl->Declaration.Semantic ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Declaration.Padding ); + } + + EOL(); + TXT( "\nFirst: " ); + UID( decl->DeclarationRange.First ); + TXT( "\nLast : " ); + UID( decl->DeclarationRange.Last ); + + if( decl->Declaration.Semantic ) { + EOL(); + TXT( "\nSemanticName : " ); + ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS ); + TXT( "\nSemanticIndex: " ); + UID( decl->Semantic.SemanticIndex ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Semantic.Padding ); + } + } +} + +static void +dump_immediate_verbose( + struct tgsi_full_immediate *imm, + unsigned ignored ) +{ + unsigned i; + + TXT( "\nDataType : " ); + ENM( imm->Immediate.DataType, TGSI_IMMS ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( imm->Immediate.Padding ); + } + + for( i = 0; i < imm->Immediate.Size - 1; i++ ) { + EOL(); + switch( imm->Immediate.DataType ) { + case TGSI_IMM_FLOAT32: + TXT( "\nFloat: " ); + FLT( imm->u.ImmediateFloat32[i].Float ); + break; + + default: + assert( 0 ); + } + } +} + +static void +dump_instruction_verbose( + struct tgsi_full_instruction *inst, + unsigned ignored, + unsigned deflt, + struct tgsi_full_instruction *fi ) +{ + unsigned i; + + TXT( "\nOpcode : " ); + ENM( inst->Instruction.Opcode, TGSI_OPCODES ); + if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) { + TXT( "\nSaturate : " ); + ENM( inst->Instruction.Saturate, TGSI_SATS ); + } + if( deflt || fi->Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) { + TXT( "\nNumDstRegs : " ); + UID( inst->Instruction.NumDstRegs ); + } + if( deflt || fi->Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) { + TXT( "\nNumSrcRegs : " ); + UID( inst->Instruction.NumSrcRegs ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->Instruction.Padding ); + } + + if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi->InstructionExtNv ) ) { + EOL(); + TXT( "\nType : " ); + ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) { + TXT( "\nPrecision : " ); + ENM( inst->InstructionExtNv.Precision, TGSI_PRECISIONS ); + } + if( deflt || fi->InstructionExtNv.CondDstIndex != inst->InstructionExtNv.CondDstIndex ) { + TXT( "\nCondDstIndex : " ); + UID( inst->InstructionExtNv.CondDstIndex ); + } + if( deflt || fi->InstructionExtNv.CondFlowIndex != inst->InstructionExtNv.CondFlowIndex ) { + TXT( "\nCondFlowIndex : " ); + UID( inst->InstructionExtNv.CondFlowIndex ); + } + if( deflt || fi->InstructionExtNv.CondMask != inst->InstructionExtNv.CondMask ) { + TXT( "\nCondMask : " ); + ENM( inst->InstructionExtNv.CondMask, TGSI_CCS ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleX != inst->InstructionExtNv.CondSwizzleX ) { + TXT( "\nCondSwizzleX : " ); + ENM( inst->InstructionExtNv.CondSwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleY != inst->InstructionExtNv.CondSwizzleY ) { + TXT( "\nCondSwizzleY : " ); + ENM( inst->InstructionExtNv.CondSwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleZ != inst->InstructionExtNv.CondSwizzleZ ) { + TXT( "\nCondSwizzleZ : " ); + ENM( inst->InstructionExtNv.CondSwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleW != inst->InstructionExtNv.CondSwizzleW ) { + TXT( "\nCondSwizzleW : " ); + ENM( inst->InstructionExtNv.CondSwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondDstUpdate != inst->InstructionExtNv.CondDstUpdate ) { + TXT( "\nCondDstUpdate : " ); + UID( inst->InstructionExtNv.CondDstUpdate ); + } + if( deflt || fi->InstructionExtNv.CondFlowEnable != inst->InstructionExtNv.CondFlowEnable ) { + TXT( "\nCondFlowEnable: " ); + UID( inst->InstructionExtNv.CondFlowEnable ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtNv.Padding ); + if( deflt || fi->InstructionExtNv.Extended != inst->InstructionExtNv.Extended ) { + TXT( "\nExtended : " ); + UID( inst->InstructionExtNv.Extended ); + } + } + } + + if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) { + EOL(); + TXT( "\nType : " ); + ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) { + TXT( "\nLabel : " ); + UID( inst->InstructionExtLabel.Label ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtLabel.Padding ); + if( deflt || fi->InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) { + TXT( "\nExtended: " ); + UID( inst->InstructionExtLabel.Extended ); + } + } + } + + if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) { + EOL(); + TXT( "\nType : " ); + ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) { + TXT( "\nTexture : " ); + ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtTexture.Padding ); + if( deflt || fi->InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) { + TXT( "\nExtended: " ); + UID( inst->InstructionExtTexture.Extended ); + } + } + } + + for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i]; + + EOL(); + TXT( "\nFile : " ); + ENM( dst->DstRegister.File, TGSI_FILES ); + if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) { + TXT( "\nWriteMask: " ); + ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS ); + } + if( ignored ) { + if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) { + TXT( "\nIndirect : " ); + UID( dst->DstRegister.Indirect ); + } + if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) { + TXT( "\nDimension: " ); + UID( dst->DstRegister.Dimension ); + } + } + if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) { + TXT( "\nIndex : " ); + SID( dst->DstRegister.Index ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegister.Padding ); + if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) { + TXT( "\nExtended : " ); + UID( dst->DstRegister.Extended ); + } + } + + if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) { + EOL(); + TXT( "\nType : " ); + ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS ); + if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) { + TXT( "\nCondMask : " ); + ENM( dst->DstRegisterExtConcode.CondMask, TGSI_CCS ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleX != dst->DstRegisterExtConcode.CondSwizzleX ) { + TXT( "\nCondSwizzleX: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleY != dst->DstRegisterExtConcode.CondSwizzleY ) { + TXT( "\nCondSwizzleY: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleZ != dst->DstRegisterExtConcode.CondSwizzleZ ) { + TXT( "\nCondSwizzleZ: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleW != dst->DstRegisterExtConcode.CondSwizzleW ) { + TXT( "\nCondSwizzleW: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSrcIndex != dst->DstRegisterExtConcode.CondSrcIndex ) { + TXT( "\nCondSrcIndex: " ); + UID( dst->DstRegisterExtConcode.CondSrcIndex ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegisterExtConcode.Padding ); + if( deflt || fd->DstRegisterExtConcode.Extended != dst->DstRegisterExtConcode.Extended ) { + TXT( "\nExtended : " ); + UID( dst->DstRegisterExtConcode.Extended ); + } + } + } + + if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) { + EOL(); + TXT( "\nType : " ); + ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS ); + if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) { + TXT( "\nModulate: " ); + ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegisterExtModulate.Padding ); + if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) { + TXT( "\nExtended: " ); + UID( dst->DstRegisterExtModulate.Extended ); + } + } + } + } + + for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i]; + + EOL(); + TXT( "\nFile : "); + ENM( src->SrcRegister.File, TGSI_FILES ); + if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) { + TXT( "\nSwizzleX : " ); + ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) { + TXT( "\nSwizzleY : " ); + ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) { + TXT( "\nSwizzleZ : " ); + ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) { + TXT( "\nSwizzleW : " ); + ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) { + TXT( "\nNegate : " ); + UID( src->SrcRegister.Negate ); + } + if( ignored ) { + if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) { + TXT( "\nIndirect : " ); + UID( src->SrcRegister.Indirect ); + } + if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) { + TXT( "\nDimension: " ); + UID( src->SrcRegister.Dimension ); + } + } + if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) { + TXT( "\nIndex : " ); + SID( src->SrcRegister.Index ); + } + if( ignored ) { + if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegister.Extended ); + } + } + + if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) { + EOL(); + TXT( "\nType : " ); + ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS ); + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) { + TXT( "\nExtSwizzleX: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleY != src->SrcRegisterExtSwz.ExtSwizzleY ) { + TXT( "\nExtSwizzleY: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleZ != src->SrcRegisterExtSwz.ExtSwizzleZ ) { + TXT( "\nExtSwizzleZ: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleW != src->SrcRegisterExtSwz.ExtSwizzleW ) { + TXT( "\nExtSwizzleW: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateX != src->SrcRegisterExtSwz.NegateX ) { + TXT( "\nNegateX : " ); + UID( src->SrcRegisterExtSwz.NegateX ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateY != src->SrcRegisterExtSwz.NegateY ) { + TXT( "\nNegateY : " ); + UID( src->SrcRegisterExtSwz.NegateY ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateZ != src->SrcRegisterExtSwz.NegateZ ) { + TXT( "\nNegateZ : " ); + UID( src->SrcRegisterExtSwz.NegateZ ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateW != src->SrcRegisterExtSwz.NegateW ) { + TXT( "\nNegateW : " ); + UID( src->SrcRegisterExtSwz.NegateW ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( src->SrcRegisterExtSwz.Padding ); + if( deflt || fs->SrcRegisterExtSwz.Extended != src->SrcRegisterExtSwz.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegisterExtSwz.Extended ); + } + } + } + + if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) { + EOL(); + TXT( "\nType : " ); + ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS ); + if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) { + TXT( "\nComplement: " ); + UID( src->SrcRegisterExtMod.Complement ); + } + if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) { + TXT( "\nBias : " ); + UID( src->SrcRegisterExtMod.Bias ); + } + if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) { + TXT( "\nScale2X : " ); + UID( src->SrcRegisterExtMod.Scale2X ); + } + if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) { + TXT( "\nAbsolute : " ); + UID( src->SrcRegisterExtMod.Absolute ); + } + if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) { + TXT( "\nNegate : " ); + UID( src->SrcRegisterExtMod.Negate ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( src->SrcRegisterExtMod.Padding ); + if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegisterExtMod.Extended ); + } + } + } + } +} + +void +tgsi_dump_c( + const struct tgsi_token *tokens, + uint flags ) +{ + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + uint ignored = flags & TGSI_DUMP_C_IGNORED; + uint deflt = flags & TGSI_DUMP_C_DEFAULT; + uint instno = 0; + + /* sanity checks */ + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "END") == 0); + + tgsi_parse_init( &parse, tokens ); + + TXT( "tgsi-dump begin -----------------" ); + + TXT( "\nMajorVersion: " ); + UID( parse.FullVersion.Version.MajorVersion ); + TXT( "\nMinorVersion: " ); + UID( parse.FullVersion.Version.MinorVersion ); + EOL(); + + TXT( "\nHeaderSize: " ); + UID( parse.FullHeader.Header.HeaderSize ); + TXT( "\nBodySize : " ); + UID( parse.FullHeader.Header.BodySize ); + TXT( "\nProcessor : " ); + ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); + EOL(); + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + + while( !tgsi_parse_end_of_tokens( &parse ) ) { + tgsi_parse_token( &parse ); + + TXT( "\nType : " ); + ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES ); + if( ignored ) { + TXT( "\nSize : " ); + UID( parse.FullToken.Token.Size ); + if( deflt || parse.FullToken.Token.Extended ) { + TXT( "\nExtended : " ); + UID( parse.FullToken.Token.Extended ); + } + } + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + dump_declaration_verbose( + &parse.FullToken.FullDeclaration, + ignored, + deflt, + &fd ); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + dump_immediate_verbose( + &parse.FullToken.FullImmediate, + ignored ); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + dump_instruction_verbose( + &parse.FullToken.FullInstruction, + ignored, + deflt, + &fi ); + break; + + default: + assert( 0 ); + } + + EOL(); + } + + TXT( "\ntgsi-dump end -------------------\n" ); + + tgsi_parse_free( &parse ); +} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h new file mode 100644 index 0000000000..d91cd35b3b --- /dev/null +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h @@ -0,0 +1,49 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_DUMP_C_H +#define TGSI_DUMP_C_H + +#include "pipe/p_shader_tokens.h" + +#if defined __cplusplus +extern "C" { +#endif + +#define TGSI_DUMP_C_IGNORED 1 +#define TGSI_DUMP_C_DEFAULT 2 + +void +tgsi_dump_c( + const struct tgsi_token *tokens, + uint flags ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_DUMP_C_H */ -- cgit v1.2.3 From 5e9ea9d938e9734524707e46be29e243e96f32a9 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 16:07:06 +0200 Subject: scons: List util/tgsi_dump_c.c. --- src/gallium/auxiliary/tgsi/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript index 54f5c75db4..3bbfa1be54 100644 --- a/src/gallium/auxiliary/tgsi/SConscript +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -7,6 +7,7 @@ tgsi = env.ConvenienceLibrary( 'exec/tgsi_sse2.c', 'util/tgsi_build.c', 'util/tgsi_dump.c', + 'util/tgsi_dump_c.c', 'util/tgsi_iterate.c', 'util/tgsi_parse.c', 'util/tgsi_sanity.c', -- cgit v1.2.3 From 15c902455fe1b4572e614bf30912d92fe9c7bb28 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 16:08:36 +0200 Subject: tgsi: Preserve flags parameter for tgsi_dump(). --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 3 ++- src/gallium/auxiliary/tgsi/util/tgsi_dump.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 5a84b99166..1056951bc8 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -486,7 +486,8 @@ tgsi_dump_instruction( void tgsi_dump( - const struct tgsi_token *tokens ) + const struct tgsi_token *tokens, + uint flags ) { struct tgsi_parse_context parse; struct tgsi_full_instruction fi; diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h index c130b9f1b7..51c230b5db 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h @@ -36,7 +36,8 @@ extern "C" { void tgsi_dump( - const struct tgsi_token *tokens ); + const struct tgsi_token *tokens, + uint flags ); struct tgsi_full_immediate; struct tgsi_full_instruction; -- cgit v1.2.3 From 307a252d1529e8e9ffa10c88cc8f5d5412f587f5 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 16:12:44 +0200 Subject: tgsi: Fix dump enums. --- src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c index 27b085dc07..acb1246b7a 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c @@ -81,18 +81,11 @@ static const char *TGSI_FILES[] = "FILE_IMMEDIATE" }; -static const char *TGSI_DECLARES[] = -{ - "DECLARE_RANGE", - "DECLARE_MASK" -}; - static const char *TGSI_INTERPOLATES[] = { "INTERPOLATE_CONSTANT", "INTERPOLATE_LINEAR", - "INTERPOLATE_PERSPECTIVE", - "INTERPOLATE_ATTRIB" + "INTERPOLATE_PERSPECTIVE" }; static const char *TGSI_SEMANTICS[] = @@ -250,9 +243,9 @@ static const char *TGSI_INSTRUCTION_EXTS[] = static const char *TGSI_PRECISIONS[] = { "PRECISION_DEFAULT", - "TGSI_PRECISION_FLOAT32", - "TGSI_PRECISION_FLOAT16", - "TGSI_PRECISION_FIXED12" + "PRECISION_FLOAT32", + "PRECISION_FLOAT16", + "PRECISION_FIXED12" }; static const char *TGSI_CCS[] = -- cgit v1.2.3 From 82f11f7e7c0bbe0452da65f08195c2a346f820e9 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 16:28:59 +0200 Subject: tgsi: Tidy up and fix tgsi_dump. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 215 ++++++++++++-------------- src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c | 2 +- 2 files changed, 101 insertions(+), 116 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 1056951bc8..fe8742dc02 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -34,16 +34,14 @@ static void dump_enum( - const unsigned e, - const char **enums, - const unsigned enums_count ) + uint e, + const char **enums, + uint enum_count ) { - if (e >= enums_count) { + if (e >= enum_count) debug_printf( "%u", e ); - } - else { + else debug_printf( "%s", enums[e] ); - } } #define EOL() debug_printf( "\n" ) @@ -55,14 +53,14 @@ dump_enum( #define FLT(F) debug_printf( "%10.4f", F ) #define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) -static const char *TGSI_PROCESSOR_TYPES_SHORT[] = +static const char *processor_type_names[] = { "FRAG", "VERT", "GEOM" }; -static const char *TGSI_FILES_SHORT[] = +static const char *file_names[] = { "NULL", "CONST", @@ -74,14 +72,14 @@ static const char *TGSI_FILES_SHORT[] = "IMM" }; -static const char *TGSI_INTERPOLATES_SHORT[] = +static const char *interpolate_names[] = { "CONSTANT", "LINEAR", "PERSPECTIVE" }; -static const char *TGSI_SEMANTICS_SHORT[] = +static const char *semantic_names[] = { "POSITION", "COLOR", @@ -92,12 +90,12 @@ static const char *TGSI_SEMANTICS_SHORT[] = "NORMAL" }; -static const char *TGSI_IMMS_SHORT[] = +static const char *immediate_type_names[] = { "FLT32" }; -static const char *TGSI_OPCODES_SHORT[TGSI_OPCODE_LAST] = +static const char *opcode_names[TGSI_OPCODE_LAST] = { "ARL", "MOV", @@ -220,7 +218,7 @@ static const char *TGSI_OPCODES_SHORT[TGSI_OPCODE_LAST] = "SWZ" }; -static const char *TGSI_SWIZZLES_SHORT[] = +static const char *swizzle_names[] = { "x", "y", @@ -228,7 +226,7 @@ static const char *TGSI_SWIZZLES_SHORT[] = "w" }; -static const char *TGSI_TEXTURES_SHORT[] = +static const char *texture_names[] = { "UNKNOWN", "1D", @@ -241,7 +239,7 @@ static const char *TGSI_TEXTURES_SHORT[] = "SHADOWRECT" }; -static const char *TGSI_EXTSWIZZLES_SHORT[] = +static const char *extswizzle_names[] = { "x", "y", @@ -251,7 +249,7 @@ static const char *TGSI_EXTSWIZZLES_SHORT[] = "1" }; -static const char *TGSI_MODULATES_SHORT[TGSI_MODULATE_COUNT] = +static const char *modulate_names[TGSI_MODULATE_COUNT] = { "", "_2X", @@ -262,40 +260,55 @@ static const char *TGSI_MODULATES_SHORT[TGSI_MODULATE_COUNT] = "_D8" }; -void -tgsi_dump_declaration( - const struct tgsi_full_declaration *decl ) +static void +_dump_register( + uint file, + uint first, + uint last ) { - TXT( "\nDCL " ); - ENM( decl->Declaration.File, TGSI_FILES_SHORT ); - + ENM( file, file_names ); CHR( '[' ); - UID( decl->DeclarationRange.First ); - if (decl->DeclarationRange.First != decl->DeclarationRange.Last) { + UID( first ); + if (first != last) { TXT( ".." ); - UID( decl->DeclarationRange.Last ); + UID( last ); } CHR( ']' ); +} - if( decl->Declaration.UsageMask != TGSI_WRITEMASK_XYZW ) { +static void +_dump_writemask( + uint writemask ) +{ + if (writemask != TGSI_WRITEMASK_XYZW) { CHR( '.' ); - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { + if (writemask & TGSI_WRITEMASK_X) CHR( 'x' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { + if (writemask & TGSI_WRITEMASK_Y) CHR( 'y' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { + if (writemask & TGSI_WRITEMASK_Z) CHR( 'z' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { + if (writemask & TGSI_WRITEMASK_W) CHR( 'w' ); - } } +} + +void +tgsi_dump_declaration( + const struct tgsi_full_declaration *decl ) +{ + TXT( "\nDCL " ); + + _dump_register( + decl->Declaration.File, + decl->DeclarationRange.First, + decl->DeclarationRange.Last ); + _dump_writemask( + decl->Declaration.UsageMask ); if (decl->Declaration.Semantic) { TXT( ", " ); - ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT ); + ENM( decl->Semantic.SemanticName, semantic_names ); if (decl->Semantic.SemanticIndex != 0 || decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC) { CHR( '[' ); @@ -305,32 +318,30 @@ tgsi_dump_declaration( } TXT( ", " ); - ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES_SHORT ); + ENM( decl->Declaration.Interpolate, interpolate_names ); } void tgsi_dump_immediate( const struct tgsi_full_immediate *imm ) { - unsigned i; + uint i; TXT( "\nIMM " ); - ENM( imm->Immediate.DataType, TGSI_IMMS_SHORT ); + ENM( imm->Immediate.DataType, immediate_type_names ); TXT( " { " ); - for( i = 0; i < imm->Immediate.Size - 1; i++ ) { - switch( imm->Immediate.DataType ) { + for (i = 0; i < imm->Immediate.Size - 1; i++) { + switch (imm->Immediate.DataType) { case TGSI_IMM_FLOAT32: FLT( imm->u.ImmediateFloat32[i].Float ); break; - default: assert( 0 ); } - if( i < imm->Immediate.Size - 2 ) { + if (i < imm->Immediate.Size - 2) TXT( ", " ); - } } TXT( " }" ); } @@ -340,15 +351,15 @@ tgsi_dump_instruction( const struct tgsi_full_instruction *inst, uint instno ) { - unsigned i; - boolean first_reg = TRUE; + uint i; + boolean first_reg = TRUE; EOL(); UID( instno ); CHR( ':' ); - ENM( inst->Instruction.Opcode, TGSI_OPCODES_SHORT ); + ENM( inst->Instruction.Opcode, opcode_names ); - switch( inst->Instruction.Saturate ) { + switch (inst->Instruction.Saturate) { case TGSI_SAT_NONE: break; case TGSI_SAT_ZERO_ONE: @@ -361,47 +372,28 @@ tgsi_dump_instruction( assert( 0 ); } - for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { const struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - if( !first_reg ) { + if (!first_reg) CHR( ',' ); - } CHR( ' ' ); - ENM( dst->DstRegister.File, TGSI_FILES_SHORT ); - - CHR( '[' ); - SID( dst->DstRegister.Index ); - CHR( ']' ); - - ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES_SHORT ); - - if( dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW ) { - CHR( '.' ); - if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_X ) { - CHR( 'x' ); - } - if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_Y ) { - CHR( 'y' ); - } - if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_Z ) { - CHR( 'z' ); - } - if( dst->DstRegister.WriteMask & TGSI_WRITEMASK_W ) { - CHR( 'w' ); - } - } + _dump_register( + dst->DstRegister.File, + dst->DstRegister.Index, + dst->DstRegister.Index ); + ENM( dst->DstRegisterExtModulate.Modulate, modulate_names ); + _dump_writemask( dst->DstRegister.WriteMask ); first_reg = FALSE; } - for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { const struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - if( !first_reg ) { + if (!first_reg) CHR( ',' ); - } CHR( ' ' ); if (src->SrcRegisterExtMod.Negate) @@ -417,40 +409,45 @@ tgsi_dump_instruction( if (src->SrcRegister.Negate) CHR( '-' ); - ENM( src->SrcRegister.File, TGSI_FILES_SHORT ); - - CHR( '[' ); if (src->SrcRegister.Indirect) { + /* TODO: Tidy up + */ + ENM( src->SrcRegister.File, file_names ); + CHR( '[' ); TXT( "ADDR[0]" ); if (src->SrcRegister.Index != 0) { if (src->SrcRegister.Index > 0) CHR( '+' ); SID( src->SrcRegister.Index ); } + CHR( ']' ); + } + else { + _dump_register( + src->SrcRegister.File, + src->SrcRegister.Index, + src->SrcRegister.Index ); } - else - SID( src->SrcRegister.Index ); - CHR( ']' ); if (src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W) { CHR( '.' ); - ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES_SHORT ); - ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES_SHORT ); - ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES_SHORT ); - ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES_SHORT ); + ENM( src->SrcRegister.SwizzleX, swizzle_names ); + ENM( src->SrcRegister.SwizzleY, swizzle_names ); + ENM( src->SrcRegister.SwizzleZ, swizzle_names ); + ENM( src->SrcRegister.SwizzleW, swizzle_names ); } if (src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) { CHR( '.' ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES_SHORT ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES_SHORT ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES_SHORT ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES_SHORT ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleX, extswizzle_names ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleY, extswizzle_names ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, extswizzle_names ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleW, extswizzle_names ); } if (src->SrcRegisterExtMod.Complement) @@ -469,10 +466,10 @@ tgsi_dump_instruction( if (inst->InstructionExtTexture.Texture != TGSI_TEXTURE_UNKNOWN) { TXT( ", " ); - ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES_SHORT ); + ENM( inst->InstructionExtTexture.Texture, texture_names ); } - switch( inst->Instruction.Opcode ) { + switch (inst->Instruction.Opcode) { case TGSI_OPCODE_IF: case TGSI_OPCODE_ELSE: case TGSI_OPCODE_BGNLOOP2: @@ -490,47 +487,35 @@ tgsi_dump( uint flags ) { struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - unsigned instno = 0; + uint instno = 0; /* sanity checks */ - assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); - assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "OPCODE_END") == 0); - assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "END") == 0); + assert( strcmp( opcode_names[TGSI_OPCODE_CONT], "CONT" ) == 0 ); + assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); + assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); tgsi_parse_init( &parse, tokens ); EOL(); - ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES_SHORT ); + ENM( parse.FullHeader.Processor.Processor, processor_type_names ); UID( parse.FullVersion.Version.MajorVersion ); CHR( '.' ); UID( parse.FullVersion.Version.MinorVersion ); - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - - while( !tgsi_parse_end_of_tokens( &parse ) ) { + while (!tgsi_parse_end_of_tokens( &parse )) { tgsi_parse_token( &parse ); - switch( parse.FullToken.Token.Type ) { + switch (parse.FullToken.Token.Type) { case TGSI_TOKEN_TYPE_DECLARATION: - tgsi_dump_declaration( - &parse.FullToken.FullDeclaration ); + tgsi_dump_declaration( &parse.FullToken.FullDeclaration ); break; - case TGSI_TOKEN_TYPE_IMMEDIATE: - tgsi_dump_immediate( - &parse.FullToken.FullImmediate ); + tgsi_dump_immediate( &parse.FullToken.FullImmediate ); break; - case TGSI_TOKEN_TYPE_INSTRUCTION: - tgsi_dump_instruction( - &parse.FullToken.FullInstruction, - instno ); + tgsi_dump_instruction( &parse.FullToken.FullInstruction, instno ); instno++; break; - default: assert( 0 ); } diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c index acb1246b7a..e7d1079588 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c @@ -773,7 +773,7 @@ tgsi_dump_c( /* sanity checks */ assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "END") == 0); + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); tgsi_parse_init( &parse, tokens ); -- cgit v1.2.3 From fef7f2b070ab797f78ebc210bb40a24685c6d4b7 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 16:42:43 +0200 Subject: tgsi: Fix error handling. --- src/gallium/auxiliary/tgsi/util/tgsi_sanity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c index 7fc4c29c68..a4edbb6d08 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c @@ -263,7 +263,7 @@ tgsi_sanity_check( ctx.errors = 0; ctx.warnings = 0; - if (tgsi_iterate_shader( tokens, &ctx.iter ) == -1) + if (!tgsi_iterate_shader( tokens, &ctx.iter )) return FALSE; return ctx.errors == 0; -- cgit v1.2.3 From 57482e1549e131fa1aebd442a677a95909b22508 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 16:42:57 +0200 Subject: tgsi: Keep version and processor info in iterate_ctx. --- src/gallium/auxiliary/tgsi/util/tgsi_iterate.c | 3 +++ src/gallium/auxiliary/tgsi/util/tgsi_iterate.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c index 43d7a6b1d5..5371a88b96 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c @@ -38,6 +38,9 @@ tgsi_iterate_shader( if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) return FALSE; + ctx->processor = parse.FullHeader.Processor; + ctx->version = parse.FullVersion.Version; + if (ctx->prolog) if (!ctx->prolog( ctx )) goto fail; diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h index 18729c2d1a..f5bebf89b8 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h @@ -59,6 +59,9 @@ struct tgsi_iterate_context boolean (* epilog)( struct tgsi_iterate_context *ctx ); + + struct tgsi_processor processor; + struct tgsi_version version; }; boolean -- cgit v1.2.3 From 83f245bd242cd2c5f59f072095dcc47aa6153b21 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 16:43:26 +0200 Subject: tgsi: Use tgsi_iterate in tgsi_dump. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 89 ++++++++++++++++++----------- 1 file changed, 57 insertions(+), 32 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index fe8742dc02..08d0d5200c 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -26,11 +26,15 @@ **************************************************************************/ #include "pipe/p_debug.h" -#include "pipe/p_util.h" -#include "util/u_string.h" #include "tgsi_dump.h" -#include "tgsi_parse.h" -#include "tgsi_build.h" +#include "tgsi_iterate.h" + +struct dump_ctx +{ + struct tgsi_iterate_context iter; + + uint instno; +}; static void dump_enum( @@ -321,6 +325,15 @@ tgsi_dump_declaration( ENM( decl->Declaration.Interpolate, interpolate_names ); } +static boolean +iter_declaration( + struct tgsi_iterate_context *iter, + struct tgsi_full_declaration *decl ) +{ + tgsi_dump_declaration( decl ); + return TRUE; +} + void tgsi_dump_immediate( const struct tgsi_full_immediate *imm ) @@ -346,6 +359,15 @@ tgsi_dump_immediate( TXT( " }" ); } +static boolean +iter_immediate( + struct tgsi_iterate_context *iter, + struct tgsi_full_immediate *imm ) +{ + tgsi_dump_immediate( imm ); + return TRUE; +} + void tgsi_dump_instruction( const struct tgsi_full_instruction *inst, @@ -481,45 +503,48 @@ tgsi_dump_instruction( } } +static boolean +iter_instruction( + struct tgsi_iterate_context *iter, + struct tgsi_full_instruction *inst ) +{ + struct dump_ctx *ctx = (struct dump_ctx *) iter; + + tgsi_dump_instruction( inst, ctx->instno++ ); + return TRUE; +} + +static boolean +prolog( + struct tgsi_iterate_context *ctx ) +{ + EOL(); + ENM( ctx->processor.Processor, processor_type_names ); + UID( ctx->version.MajorVersion ); + CHR( '.' ); + UID( ctx->version.MinorVersion ); + return TRUE; +} + void tgsi_dump( const struct tgsi_token *tokens, uint flags ) { - struct tgsi_parse_context parse; - uint instno = 0; + struct dump_ctx ctx; /* sanity checks */ assert( strcmp( opcode_names[TGSI_OPCODE_CONT], "CONT" ) == 0 ); assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); - tgsi_parse_init( &parse, tokens ); - - EOL(); - ENM( parse.FullHeader.Processor.Processor, processor_type_names ); - UID( parse.FullVersion.Version.MajorVersion ); - CHR( '.' ); - UID( parse.FullVersion.Version.MinorVersion ); - - while (!tgsi_parse_end_of_tokens( &parse )) { - tgsi_parse_token( &parse ); + ctx.iter.prolog = prolog; + ctx.iter.iterate_instruction = iter_instruction; + ctx.iter.iterate_declaration = iter_declaration; + ctx.iter.iterate_immediate = iter_immediate; + ctx.iter.epilog = NULL; - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - tgsi_dump_declaration( &parse.FullToken.FullDeclaration ); - break; - case TGSI_TOKEN_TYPE_IMMEDIATE: - tgsi_dump_immediate( &parse.FullToken.FullImmediate ); - break; - case TGSI_TOKEN_TYPE_INSTRUCTION: - tgsi_dump_instruction( &parse.FullToken.FullInstruction, instno ); - instno++; - break; - default: - assert( 0 ); - } - } + ctx.instno = 0; - tgsi_parse_free( &parse ); + tgsi_iterate_shader( tokens, &ctx.iter ); } -- cgit v1.2.3 From 613f0df64dd2c2db71dd73b595225016ae596576 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 19:29:52 +0200 Subject: tgsi: Remove redundant code. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 1 - src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c | 1 - 2 files changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 08d0d5200c..a9d500c8cf 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -536,7 +536,6 @@ tgsi_dump( /* sanity checks */ assert( strcmp( opcode_names[TGSI_OPCODE_CONT], "CONT" ) == 0 ); assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); - assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); ctx.iter.prolog = prolog; ctx.iter.iterate_instruction = iter_instruction; diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c index e7d1079588..eabd74bd6d 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c @@ -773,7 +773,6 @@ tgsi_dump_c( /* sanity checks */ assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); tgsi_parse_init( &parse, tokens ); -- cgit v1.2.3 From 73e1d0be756537376495547bc1e798805884b8ef Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 21:23:04 +0200 Subject: tgsi: Add support for indirect addressing in dump, sanity and text modules. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 53 +++++++--- src/gallium/auxiliary/tgsi/util/tgsi_sanity.c | 86 ++++++++++----- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 147 ++++++++++++++++++++------ 3 files changed, 215 insertions(+), 71 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index a9d500c8cf..94180f7e50 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -265,17 +265,48 @@ static const char *modulate_names[TGSI_MODULATE_COUNT] = }; static void -_dump_register( +_dump_register_prefix( uint file, uint first, uint last ) { + + +} + +static void +_dump_register( + uint file, + int first, + int last ) +{ ENM( file, file_names ); CHR( '[' ); - UID( first ); + SID( first ); if (first != last) { TXT( ".." ); - UID( last ); + SID( last ); + } + CHR( ']' ); +} + +static void +_dump_register_ind( + uint file, + int index, + uint ind_file, + int ind_index ) +{ + ENM( file, file_names ); + CHR( '[' ); + ENM( ind_file, file_names ); + CHR( '[' ); + SID( ind_index ); + CHR( ']' ); + if (index != 0) { + if (index > 0) + CHR( '+' ); + SID( index ); } CHR( ']' ); } @@ -432,17 +463,11 @@ tgsi_dump_instruction( CHR( '-' ); if (src->SrcRegister.Indirect) { - /* TODO: Tidy up - */ - ENM( src->SrcRegister.File, file_names ); - CHR( '[' ); - TXT( "ADDR[0]" ); - if (src->SrcRegister.Index != 0) { - if (src->SrcRegister.Index > 0) - CHR( '+' ); - SID( src->SrcRegister.Index ); - } - CHR( ']' ); + _dump_register_ind( + src->SrcRegister.File, + src->SrcRegister.Index, + src->SrcRegisterInd.File, + src->SrcRegisterInd.Index ); } else { _dump_register( diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c index a4edbb6d08..f11de815b0 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c @@ -39,8 +39,9 @@ struct sanity_check_ctx { struct tgsi_iterate_context iter; - reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REGISTERS / sizeof( uint ) / 8]; - reg_flag regs_used[TGSI_FILE_COUNT][MAX_REGISTERS / sizeof( uint ) / 8]; + reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REGISTERS / BITS_IN_REG_FLAG]; + reg_flag regs_used[TGSI_FILE_COUNT][MAX_REGISTERS / BITS_IN_REG_FLAG]; + boolean regs_ind_used[TGSI_FILE_COUNT]; uint num_imms; uint num_instructions; uint index_of_END; @@ -83,24 +84,59 @@ static boolean is_register_declared( struct sanity_check_ctx *ctx, uint file, - uint index ) + int index ) { - assert( index < MAX_REGISTERS ); + assert( index >= 0 && index < MAX_REGISTERS ); return (ctx->regs_decl[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; } +static boolean +is_any_register_declared( + struct sanity_check_ctx *ctx, + uint file ) +{ + uint i; + + for (i = 0; i < MAX_REGISTERS / BITS_IN_REG_FLAG; i++) + if (ctx->regs_decl[file][i]) + return TRUE; + return FALSE; +} + static boolean is_register_used( struct sanity_check_ctx *ctx, uint file, - uint index ) + int index ) { assert( index < MAX_REGISTERS ); return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; } +static boolean +check_register_usage( + struct sanity_check_ctx *ctx, + uint file, + int index, + boolean indirect ) +{ + if (!check_file_name( ctx, file )) + return FALSE; + if (indirect) { + if (!is_any_register_declared( ctx, file )) + report_error( ctx, "Undeclared source register" ); + ctx->regs_ind_used[file] = TRUE; + } + else { + if (!is_register_declared( ctx, file, index )) + report_error( ctx, "Undeclared destination register" ); + ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG)); + } + return TRUE; +} + static boolean iter_instruction( struct tgsi_iterate_context *iter, @@ -122,28 +158,25 @@ iter_instruction( * Mark the registers as used. */ for (i = 0; i < inst->Instruction.NumDstRegs; i++) { - uint file; - uint index; - - file = inst->FullDstRegisters[i].DstRegister.File; - if (!check_file_name( ctx, file )) - return TRUE; - index = inst->FullDstRegisters[i].DstRegister.Index; - if (!is_register_declared( ctx, file, index )) - report_error( ctx, "Undeclared destination register" ); - ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG)); + check_register_usage( + ctx, + inst->FullDstRegisters[i].DstRegister.File, + inst->FullDstRegisters[i].DstRegister.Index, + FALSE ); } for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { - uint file; - uint index; - - file = inst->FullSrcRegisters[i].SrcRegister.File; - if (!check_file_name( ctx, file )) - return TRUE; - index = inst->FullSrcRegisters[i].SrcRegister.Index; - if (!is_register_declared( ctx, file, index )) - report_error( ctx, "Undeclared source register" ); - ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG)); + check_register_usage( + ctx, + inst->FullSrcRegisters[i].SrcRegister.File, + inst->FullSrcRegisters[i].SrcRegister.Index, + inst->FullSrcRegisters[i].SrcRegister.Indirect ); + if (inst->FullSrcRegisters[i].SrcRegister.Indirect) { + check_register_usage( + ctx, + inst->FullSrcRegisters[i].SrcRegisterInd.File, + inst->FullSrcRegisters[i].SrcRegisterInd.Index, + FALSE ); + } } ctx->num_instructions++; @@ -228,7 +261,7 @@ epilog( uint i; for (i = 0; i < MAX_REGISTERS; i++) { - if (is_register_declared( ctx, file, i ) && !is_register_used( ctx, file, i )) { + if (is_register_declared( ctx, file, i ) && !is_register_used( ctx, file, i ) && !ctx->regs_ind_used[file]) { report_warning( ctx, "Register never used" ); } } @@ -256,6 +289,7 @@ tgsi_sanity_check( memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) ); memset( ctx.regs_used, 0, sizeof( ctx.regs_used ) ); + memset( ctx.regs_ind_used, 0, sizeof( ctx.regs_ind_used ) ); ctx.num_imms = 0; ctx.num_instructions = 0; ctx.index_of_END = ~0; diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index 9ed0f52fc7..2a50315463 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -226,24 +226,21 @@ static const char *file_names[TGSI_FILE_COUNT] = }; static boolean -parse_file( - struct translate_ctx *ctx, - uint *file ) +parse_file( const char **pcur, uint *file ) { uint i; for (i = 0; i < TGSI_FILE_COUNT; i++) { - const char *cur = ctx->cur; + const char *cur = *pcur; if (str_match_no_case( &cur, file_names[i] )) { if (!is_digit_alpha_underscore( cur )) { - ctx->cur = cur; + *pcur = cur; *file = i; return TRUE; } } } - report_error( ctx, "Unknown register file" ); return FALSE; } @@ -290,41 +287,57 @@ parse_opt_writemask( return TRUE; } -/* Parse register part common for decls and operands. - * ::= `[' +/* ::= `[' */ static boolean -parse_register_prefix( +parse_register_file_bracket( struct translate_ctx *ctx, - uint *file, - uint *index ) + uint *file ) { - if (!parse_file( ctx, file )) + if (!parse_file( &ctx->cur, file )) { + report_error( ctx, "Unknown register file" ); return FALSE; + } eat_opt_white( &ctx->cur ); if (*ctx->cur != '[') { report_error( ctx, "Expected `['" ); return FALSE; } ctx->cur++; + return TRUE; +} + +/* ::= + */ +static boolean +parse_register_file_bracket_index( + struct translate_ctx *ctx, + uint *file, + int *index ) +{ + uint uindex; + + if (!parse_register_file_bracket( ctx, file )) + return FALSE; eat_opt_white( &ctx->cur ); - if (!parse_uint( &ctx->cur, index )) { - report_error( ctx, "Expected literal integer" ); + if (!parse_uint( &ctx->cur, &uindex )) { + report_error( ctx, "Expected literal unsigned integer" ); return FALSE; } + *index = (int) uindex; return TRUE; } -/* Parse register operand. - * ::= `]' +/* Parse destination register operand. + * ::= `]' */ static boolean -parse_register( +parse_register_dst( struct translate_ctx *ctx, uint *file, - uint *index ) + int *index ) { - if (!parse_register_prefix( ctx, file, index )) + if (!parse_register_file_bracket_index( ctx, file, index )) return FALSE; eat_opt_white( &ctx->cur ); if (*ctx->cur != ']') { @@ -332,30 +345,95 @@ parse_register( return FALSE; } ctx->cur++; - /* TODO: Modulate suffix */ + return TRUE; +} + +/* Parse source register operand. + * ::= `]' | + * `]' | + * `+' `]' | + * `-' `]' + */ +static boolean +parse_register_src( + struct translate_ctx *ctx, + uint *file, + int *index, + uint *ind_file, + int *ind_index ) +{ + const char *cur; + uint uindex; + + if (!parse_register_file_bracket( ctx, file )) + return FALSE; + eat_opt_white( &ctx->cur ); + cur = ctx->cur; + if (parse_file( &cur, ind_file )) { + if (!parse_register_dst( ctx, ind_file, ind_index )) + return FALSE; + eat_opt_white( &ctx->cur ); + if (*ctx->cur == '+' || *ctx->cur == '-') { + boolean negate; + + negate = *ctx->cur == '-'; + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (!parse_uint( &ctx->cur, &uindex )) { + report_error( ctx, "Expected literal unsigned integer" ); + return FALSE; + } + if (negate) + *index = -(int) uindex; + else + *index = (int) uindex; + } + else { + *index = 0; + } + } + else { + if (!parse_uint( &ctx->cur, &uindex )) { + report_error( ctx, "Expected literal unsigned integer" ); + return FALSE; + } + *index = (int) uindex; + *ind_file = TGSI_FILE_NULL; + *ind_index = 0; + } + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ']') { + report_error( ctx, "Expected `]'" ); + return FALSE; + } + ctx->cur++; return TRUE; } /* Parse register declaration. - * ::= `]' | `..' `]' + * ::= `]' | + * `..' `]' */ static boolean parse_register_dcl( struct translate_ctx *ctx, uint *file, - uint *first, - uint *last ) + int *first, + int *last ) { - if (!parse_register_prefix( ctx, file, first )) + if (!parse_register_file_bracket_index( ctx, file, first )) return FALSE; eat_opt_white( &ctx->cur ); if (ctx->cur[0] == '.' && ctx->cur[1] == '.') { + uint uindex; + ctx->cur += 2; eat_opt_white( &ctx->cur ); - if (!parse_uint( &ctx->cur, last )) { + if (!parse_uint( &ctx->cur, &uindex )) { report_error( ctx, "Expected literal integer" ); return FALSE; } + *last = (int) uindex; eat_opt_white( &ctx->cur ); } else { @@ -386,11 +464,11 @@ parse_dst_operand( struct tgsi_full_dst_register *dst ) { uint file; - uint index; + int index; uint writemask; const char *cur; - if (!parse_register( ctx, &file, &index )) + if (!parse_register_dst( ctx, &file, &index )) return FALSE; cur = ctx->cur; @@ -426,7 +504,9 @@ parse_src_operand( const char *cur; float value; uint file; - uint index; + int index; + uint ind_file; + int ind_index; if (*ctx->cur == '-') { cur = ctx->cur; @@ -498,10 +578,15 @@ parse_src_operand( } } - if (!parse_register( ctx, &file, &index )) + if (!parse_register_src( ctx, &file, &index, &ind_file, &ind_index )) return FALSE; src->SrcRegister.File = file; src->SrcRegister.Index = index; + if (ind_file != TGSI_FILE_NULL) { + src->SrcRegister.Indirect = 1; + src->SrcRegisterInd.File = ind_file; + src->SrcRegisterInd.Index = ind_index; + } /* Parse optional swizzle */ @@ -864,8 +949,8 @@ static boolean parse_declaration( struct translate_ctx *ctx ) { struct tgsi_full_declaration decl; uint file; - uint first; - uint last; + int first; + int last; uint writemask; const char *cur; uint advance; -- cgit v1.2.3 From 25a7f422b4e307dce966220d47794fb056d04aac Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 21:28:28 +0200 Subject: tgsi: Warn if an indirect register not ADDR[0]. --- src/gallium/auxiliary/tgsi/util/tgsi_sanity.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c index f11de815b0..08f3995b13 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c @@ -171,11 +171,14 @@ iter_instruction( inst->FullSrcRegisters[i].SrcRegister.Index, inst->FullSrcRegisters[i].SrcRegister.Indirect ); if (inst->FullSrcRegisters[i].SrcRegister.Indirect) { - check_register_usage( - ctx, - inst->FullSrcRegisters[i].SrcRegisterInd.File, - inst->FullSrcRegisters[i].SrcRegisterInd.Index, - FALSE ); + uint file; + int index; + + file = inst->FullSrcRegisters[i].SrcRegisterInd.File; + index = inst->FullSrcRegisters[i].SrcRegisterInd.Index; + check_register_usage( ctx, file, index, FALSE ); + if (file != TGSI_FILE_ADDRESS || index != 0) + report_warning( ctx, "Indirect register not ADDR[0]" ); } } -- cgit v1.2.3 From 9d068d4b90813d5afa243d669e8437b8922ac656 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 21:38:20 +0200 Subject: tgsi: Add support for branch instructions with target labels. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 256 +++++++++++++++------------- 1 file changed, 137 insertions(+), 119 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index 2a50315463..442016104b 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -687,130 +687,131 @@ struct opcode_info uint num_dst; uint num_src; uint is_tex; + uint is_branch; const char *mnemonic; }; static const struct opcode_info opcode_info[TGSI_OPCODE_LAST] = { - { 1, 1, 0, "ARL" }, - { 1, 1, 0, "MOV" }, - { 1, 1, 0, "LIT" }, - { 1, 1, 0, "RCP" }, - { 1, 1, 0, "RSQ" }, - { 1, 1, 0, "EXP" }, - { 1, 1, 0, "LOG" }, - { 1, 2, 0, "MUL" }, - { 1, 2, 0, "ADD" }, - { 1, 2, 0, "DP3" }, - { 1, 2, 0, "DP4" }, - { 1, 2, 0, "DST" }, - { 1, 2, 0, "MIN" }, - { 1, 2, 0, "MAX" }, - { 1, 2, 0, "SLT" }, - { 1, 2, 0, "SGE" }, - { 1, 3, 0, "MAD" }, - { 1, 2, 0, "SUB" }, - { 1, 3, 0, "LERP" }, - { 1, 3, 0, "CND" }, - { 1, 3, 0, "CND0" }, - { 1, 3, 0, "DOT2ADD" }, - { 1, 2, 0, "INDEX" }, - { 1, 1, 0, "NEGATE" }, - { 1, 1, 0, "FRAC" }, - { 1, 3, 0, "CLAMP" }, - { 1, 1, 0, "FLOOR" }, - { 1, 1, 0, "ROUND" }, - { 1, 1, 0, "EXPBASE2" }, - { 1, 1, 0, "LOGBASE2" }, - { 1, 2, 0, "POWER" }, - { 1, 2, 0, "CROSSPRODUCT" }, - { 1, 2, 0, "MULTIPLYMATRIX" }, - { 1, 1, 0, "ABS" }, - { 1, 1, 0, "RCC" }, - { 1, 2, 0, "DPH" }, - { 1, 1, 0, "COS" }, - { 1, 1, 0, "DDX" }, - { 1, 1, 0, "DDY" }, - { 0, 1, 0, "KILP" }, - { 1, 1, 0, "PK2H" }, - { 1, 1, 0, "PK2US" }, - { 1, 1, 0, "PK4B" }, - { 1, 1, 0, "PK4UB" }, - { 1, 2, 0, "RFL" }, - { 1, 2, 0, "SEQ" }, - { 1, 2, 0, "SFL" }, - { 1, 2, 0, "SGT" }, - { 1, 1, 0, "SIN" }, - { 1, 2, 0, "SLE" }, - { 1, 2, 0, "SNE" }, - { 1, 2, 0, "STR" }, - { 1, 2, 1, "TEX" }, - { 1, 4, 1, "TXD" }, - { 1, 2, 1, "TXP" }, - { 1, 1, 0, "UP2H" }, - { 1, 1, 0, "UP2US" }, - { 1, 1, 0, "UP4B" }, - { 1, 1, 0, "UP4UB" }, - { 1, 3, 0, "X2D" }, - { 1, 1, 0, "ARA" }, - { 1, 1, 0, "ARR" }, - { 0, 1, 0, "BRA" }, - { 0, 0, 0, "CAL" }, - { 0, 0, 0, "RET" }, - { 1, 1, 0, "SSG" }, - { 1, 3, 0, "CMP" }, - { 1, 1, 0, "SCS" }, - { 1, 2, 1, "TXB" }, - { 1, 1, 0, "NRM" }, - { 1, 2, 0, "DIV" }, - { 1, 2, 0, "DP2" }, - { 1, 2, 1, "TXL" }, - { 0, 0, 0, "BRK" }, - { 0, 1, 0, "IF" }, - { 0, 0, 0, "LOOP" }, - { 0, 1, 0, "REP" }, - { 0, 0, 0, "ELSE" }, - { 0, 0, 0, "ENDIF" }, - { 0, 0, 0, "ENDLOOP" }, - { 0, 0, 0, "ENDREP" }, - { 0, 1, 0, "PUSHA" }, - { 1, 0, 0, "POPA" }, - { 1, 1, 0, "CEIL" }, - { 1, 1, 0, "I2F" }, - { 1, 1, 0, "NOT" }, - { 1, 1, 0, "TRUNC" }, - { 1, 2, 0, "SHL" }, - { 1, 2, 0, "SHR" }, - { 1, 2, 0, "AND" }, - { 1, 2, 0, "OR" }, - { 1, 2, 0, "MOD" }, - { 1, 2, 0, "XOR" }, - { 1, 3, 0, "SAD" }, - { 1, 2, 1, "TXF" }, - { 1, 2, 1, "TXQ" }, - { 0, 0, 0, "CONT" }, - { 0, 0, 0, "EMIT" }, - { 0, 0, 0, "ENDPRIM" }, - { 0, 0, 0, "BGNLOOP2" }, - { 0, 0, 0, "BGNSUB" }, - { 0, 0, 0, "ENDLOOP2" }, - { 0, 0, 0, "ENDSUB" }, - { 1, 1, 0, "NOISE1" }, - { 1, 1, 0, "NOISE2" }, - { 1, 1, 0, "NOISE3" }, - { 1, 1, 0, "NOISE4" }, - { 0, 0, 0, "NOP" }, - { 1, 2, 0, "M4X3" }, - { 1, 2, 0, "M3X4" }, - { 1, 2, 0, "M3X3" }, - { 1, 2, 0, "M3X2" }, - { 1, 1, 0, "NRM4" }, - { 0, 1, 0, "CALLNZ" }, - { 0, 1, 0, "IFC" }, - { 0, 1, 0, "BREAKC" }, - { 0, 0, 0, "KIL" }, - { 0, 0, 0, "END" }, - { 1, 1, 0, "SWZ" } + { 1, 1, 0, 0, "ARL" }, + { 1, 1, 0, 0, "MOV" }, + { 1, 1, 0, 0, "LIT" }, + { 1, 1, 0, 0, "RCP" }, + { 1, 1, 0, 0, "RSQ" }, + { 1, 1, 0, 0, "EXP" }, + { 1, 1, 0, 0, "LOG" }, + { 1, 2, 0, 0, "MUL" }, + { 1, 2, 0, 0, "ADD" }, + { 1, 2, 0, 0, "DP3" }, + { 1, 2, 0, 0, "DP4" }, + { 1, 2, 0, 0, "DST" }, + { 1, 2, 0, 0, "MIN" }, + { 1, 2, 0, 0, "MAX" }, + { 1, 2, 0, 0, "SLT" }, + { 1, 2, 0, 0, "SGE" }, + { 1, 3, 0, 0, "MAD" }, + { 1, 2, 0, 0, "SUB" }, + { 1, 3, 0, 0, "LERP" }, + { 1, 3, 0, 0, "CND" }, + { 1, 3, 0, 0, "CND0" }, + { 1, 3, 0, 0, "DOT2ADD" }, + { 1, 2, 0, 0, "INDEX" }, + { 1, 1, 0, 0, "NEGATE" }, + { 1, 1, 0, 0, "FRAC" }, + { 1, 3, 0, 0, "CLAMP" }, + { 1, 1, 0, 0, "FLOOR" }, + { 1, 1, 0, 0, "ROUND" }, + { 1, 1, 0, 0, "EXPBASE2" }, + { 1, 1, 0, 0, "LOGBASE2" }, + { 1, 2, 0, 0, "POWER" }, + { 1, 2, 0, 0, "CROSSPRODUCT" }, + { 1, 2, 0, 0, "MULTIPLYMATRIX" }, + { 1, 1, 0, 0, "ABS" }, + { 1, 1, 0, 0, "RCC" }, + { 1, 2, 0, 0, "DPH" }, + { 1, 1, 0, 0, "COS" }, + { 1, 1, 0, 0, "DDX" }, + { 1, 1, 0, 0, "DDY" }, + { 0, 1, 0, 0, "KILP" }, + { 1, 1, 0, 0, "PK2H" }, + { 1, 1, 0, 0, "PK2US" }, + { 1, 1, 0, 0, "PK4B" }, + { 1, 1, 0, 0, "PK4UB" }, + { 1, 2, 0, 0, "RFL" }, + { 1, 2, 0, 0, "SEQ" }, + { 1, 2, 0, 0, "SFL" }, + { 1, 2, 0, 0, "SGT" }, + { 1, 1, 0, 0, "SIN" }, + { 1, 2, 0, 0, "SLE" }, + { 1, 2, 0, 0, "SNE" }, + { 1, 2, 0, 0, "STR" }, + { 1, 2, 1, 0, "TEX" }, + { 1, 4, 1, 0, "TXD" }, + { 1, 2, 1, 0, "TXP" }, + { 1, 1, 0, 0, "UP2H" }, + { 1, 1, 0, 0, "UP2US" }, + { 1, 1, 0, 0, "UP4B" }, + { 1, 1, 0, 0, "UP4UB" }, + { 1, 3, 0, 0, "X2D" }, + { 1, 1, 0, 0, "ARA" }, + { 1, 1, 0, 0, "ARR" }, + { 0, 1, 0, 0, "BRA" }, + { 0, 0, 0, 1, "CAL" }, + { 0, 0, 0, 0, "RET" }, + { 1, 1, 0, 0, "SSG" }, + { 1, 3, 0, 0, "CMP" }, + { 1, 1, 0, 0, "SCS" }, + { 1, 2, 1, 0, "TXB" }, + { 1, 1, 0, 0, "NRM" }, + { 1, 2, 0, 0, "DIV" }, + { 1, 2, 0, 0, "DP2" }, + { 1, 2, 1, 0, "TXL" }, + { 0, 0, 0, 0, "BRK" }, + { 0, 1, 0, 1, "IF" }, + { 0, 0, 0, 0, "LOOP" }, + { 0, 1, 0, 0, "REP" }, + { 0, 0, 0, 1, "ELSE" }, + { 0, 0, 0, 0, "ENDIF" }, + { 0, 0, 0, 0, "ENDLOOP" }, + { 0, 0, 0, 0, "ENDREP" }, + { 0, 1, 0, 0, "PUSHA" }, + { 1, 0, 0, 0, "POPA" }, + { 1, 1, 0, 0, "CEIL" }, + { 1, 1, 0, 0, "I2F" }, + { 1, 1, 0, 0, "NOT" }, + { 1, 1, 0, 0, "TRUNC" }, + { 1, 2, 0, 0, "SHL" }, + { 1, 2, 0, 0, "SHR" }, + { 1, 2, 0, 0, "AND" }, + { 1, 2, 0, 0, "OR" }, + { 1, 2, 0, 0, "MOD" }, + { 1, 2, 0, 0, "XOR" }, + { 1, 3, 0, 0, "SAD" }, + { 1, 2, 1, 0, "TXF" }, + { 1, 2, 1, 0, "TXQ" }, + { 0, 0, 0, 0, "CONT" }, + { 0, 0, 0, 0, "EMIT" }, + { 0, 0, 0, 0, "ENDPRIM" }, + { 0, 0, 0, 1, "BGNLOOP2" }, + { 0, 0, 0, 0, "BGNSUB" }, + { 0, 0, 0, 1, "ENDLOOP2" }, + { 0, 0, 0, 0, "ENDSUB" }, + { 1, 1, 0, 0, "NOISE1" }, + { 1, 1, 0, 0, "NOISE2" }, + { 1, 1, 0, 0, "NOISE3" }, + { 1, 1, 0, 0, "NOISE4" }, + { 0, 0, 0, 0, "NOP" }, + { 1, 2, 0, 0, "M4X3" }, + { 1, 2, 0, 0, "M3X4" }, + { 1, 2, 0, 0, "M3X3" }, + { 1, 2, 0, 0, "M3X2" }, + { 1, 1, 0, 0, "NRM4" }, + { 0, 1, 0, 0, "CALLNZ" }, + { 0, 1, 0, 0, "IFC" }, + { 0, 1, 0, 0, "BREAKC" }, + { 0, 0, 0, 0, "KIL" }, + { 0, 0, 0, 0, "END" }, + { 1, 1, 0, 0, "SWZ" } }; static const char *texture_names[TGSI_TEXTURE_COUNT] = @@ -915,6 +916,23 @@ parse_instruction( } } + if (info->is_branch) { + uint target; + + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ':') { + report_error( ctx, "Expected `:'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (!parse_uint( &ctx->cur, &target )) { + report_error( ctx, "Expected a label" ); + return FALSE; + } + inst.InstructionExtLabel.Label = target; + } + advance = tgsi_build_full_instruction( &inst, ctx->tokens_cur, -- cgit v1.2.3 From b3c8d0c348c5d894e4df0314f060361893bdd38e Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sun, 20 Jul 2008 21:58:07 +0200 Subject: tgsi: Parse source register extended swizzle. --- src/gallium/auxiliary/tgsi/util/tgsi_text.c | 91 ++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 27 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c index 442016104b..35cb3055bb 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_text.c @@ -496,6 +496,52 @@ parse_dst_operand( return TRUE; } +static boolean +parse_optional_swizzle( + struct translate_ctx *ctx, + uint swizzle[4], + boolean *parsed_swizzle, + boolean *parsed_extswizzle ) +{ + const char *cur = ctx->cur; + + *parsed_swizzle = FALSE; + *parsed_extswizzle = FALSE; + + eat_opt_white( &cur ); + if (*cur == '.') { + uint i; + + cur++; + eat_opt_white( &cur ); + for (i = 0; i < 4; i++) { + if (toupper( *cur ) == 'X') + swizzle[i] = TGSI_SWIZZLE_X; + else if (toupper( *cur ) == 'Y') + swizzle[i] = TGSI_SWIZZLE_Y; + else if (toupper( *cur ) == 'Z') + swizzle[i] = TGSI_SWIZZLE_Z; + else if (toupper( *cur ) == 'W') + swizzle[i] = TGSI_SWIZZLE_W; + else { + if (*cur == '0') + swizzle[i] = TGSI_EXTSWIZZLE_ZERO; + else if (*cur == '1') + swizzle[i] = TGSI_EXTSWIZZLE_ONE; + else { + report_error( ctx, "Expected register swizzle component `x', `y', `z', `w', `0' or `1'" ); + return FALSE; + } + *parsed_extswizzle = TRUE; + } + cur++; + } + *parsed_swizzle = TRUE; + ctx->cur = cur; + } + return TRUE; +} + static boolean parse_src_operand( struct translate_ctx *ctx, @@ -507,6 +553,9 @@ parse_src_operand( int index; uint ind_file; int ind_index; + uint swizzle[4]; + boolean parsed_swizzle; + boolean parsed_extswizzle; if (*ctx->cur == '-') { cur = ctx->cur; @@ -588,35 +637,23 @@ parse_src_operand( src->SrcRegisterInd.Index = ind_index; } - /* Parse optional swizzle + /* Parse optional swizzle. */ - cur = ctx->cur; - eat_opt_white( &cur ); - if (*cur == '.') { - uint i; - - cur++; - eat_opt_white( &cur ); - for (i = 0; i < 4; i++) { - uint swizzle; - - if (toupper( *cur ) == 'X') - swizzle = TGSI_SWIZZLE_X; - else if (toupper( *cur ) == 'Y') - swizzle = TGSI_SWIZZLE_Y; - else if (toupper( *cur ) == 'Z') - swizzle = TGSI_SWIZZLE_Z; - else if (toupper( *cur ) == 'W') - swizzle = TGSI_SWIZZLE_W; - else { - report_error( ctx, "Expected register swizzle component either `x', `y', `z' or `w'" ); - return FALSE; - } - cur++; - tgsi_util_set_src_register_swizzle( &src->SrcRegister, swizzle, i ); + if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, &parsed_extswizzle )) { + if (parsed_extswizzle) { + assert( parsed_swizzle ); + + src->SrcRegisterExtSwz.ExtSwizzleX = swizzle[0]; + src->SrcRegisterExtSwz.ExtSwizzleY = swizzle[1]; + src->SrcRegisterExtSwz.ExtSwizzleZ = swizzle[2]; + src->SrcRegisterExtSwz.ExtSwizzleW = swizzle[3]; + } + else if (parsed_swizzle) { + src->SrcRegister.SwizzleX = swizzle[0]; + src->SrcRegister.SwizzleY = swizzle[1]; + src->SrcRegister.SwizzleZ = swizzle[2]; + src->SrcRegister.SwizzleW = swizzle[3]; } - - ctx->cur = cur; } if (src->SrcRegisterExtMod.Complement) { -- cgit v1.2.3 From 1753ff9872562bc05aff2472fc1256539085bbfc Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Mon, 21 Jul 2008 14:38:57 +0200 Subject: tgsi: Update Makefile to include tgsi_iterate.c --- src/gallium/auxiliary/tgsi/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index 5555639b70..9c4b967651 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -6,6 +6,7 @@ LIBNAME = tgsi C_SOURCES = \ exec/tgsi_exec.c \ exec/tgsi_sse2.c \ + util/tgsi_iterate.c \ util/tgsi_build.c \ util/tgsi_dump.c \ util/tgsi_parse.c \ -- cgit v1.2.3 From 4db631a3994ed2f5b7cf6e4ac6c08c0a4c091730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 21 Jul 2008 19:38:25 +0900 Subject: gallium: Open a new file when existing profile memory map is exhausted. --- src/gallium/auxiliary/util/p_debug_prof.c | 147 +++++++++++++++++++++++------- 1 file changed, 113 insertions(+), 34 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug_prof.c b/src/gallium/auxiliary/util/p_debug_prof.c index 958f99c327..69c914c780 100644 --- a/src/gallium/auxiliary/util/p_debug_prof.c +++ b/src/gallium/auxiliary/util/p_debug_prof.c @@ -49,12 +49,97 @@ #define PROFILE_FILE_SIZE 4*1024*1024 #define FILE_NAME_SIZE 256 -static WCHAR wFileName[FILE_NAME_SIZE]; +static WCHAR wFileName[FILE_NAME_SIZE] = L"\\??\\c:\\00000000.trace"; static ULONG_PTR iFile = 0; -static void *pMap = NULL; -static void *pMapEnd = NULL; +static BYTE *pMap = NULL; +static BYTE *pMapBegin = NULL; +static BYTE *pMapEnd = NULL; +void __declspec(naked) __cdecl +debug_profile_close(void) +{ + _asm { + push eax + push ebx + push ecx + push edx + push ebp + push edi + push esi + } + + if(iFile) { + EngUnmapFile(iFile); + /* Truncate the file */ + pMap = EngMapFile(wFileName, pMap - pMapBegin, &iFile); + if(pMap) + EngUnmapFile(iFile); + } + iFile = 0; + pMapBegin = pMapEnd = pMap = NULL; + + _asm { + pop esi + pop edi + pop ebp + pop edx + pop ecx + pop ebx + pop eax + ret + } +} + + +void __declspec(naked) __cdecl +debug_profile_open(void) +{ + WCHAR *p; + + _asm { + push eax + push ebx + push ecx + push edx + push ebp + push edi + push esi + } + + debug_profile_close(); + + // increment starting from the less significant digit + p = &wFileName[14]; + while(1) { + if(*p == '9') { + *p-- = '0'; + } + else { + *p += 1; + break; + } + } + + pMap = EngMapFile(wFileName, PROFILE_FILE_SIZE, &iFile); + if(pMap) { + pMapBegin = pMap; + pMapEnd = pMap + PROFILE_FILE_SIZE; + } + + _asm { + pop esi + pop edi + pop ebp + pop edx + pop ecx + pop ebx + pop eax + ret + } +} + + /** * Called at the start of every method or function. * @@ -64,11 +149,15 @@ void __declspec(naked) __cdecl _penter(void) { _asm { push ebx +retry: mov ebx, [pMap] test ebx, ebx jz done cmp ebx, [pMapEnd] - je done + jne ready + call debug_profile_open + jmp retry +ready: push eax push edx mov eax, [esp+12] @@ -97,11 +186,15 @@ void __declspec(naked) __cdecl _pexit(void) { _asm { push ebx +retry: mov ebx, [pMap] test ebx, ebx jz done cmp ebx, [pMapEnd] - je done + jne ready + call debug_profile_open + jmp retry +ready: push eax push edx mov eax, [esp+12] @@ -121,21 +214,13 @@ done: } +/** + * Reference function for calibration. + */ void __declspec(naked) -__debug_profile_reference1(void) { - _asm { - call _penter - call _pexit - ret - } -} - - -void __declspec(naked) -__debug_profile_reference2(void) { +__debug_profile_reference(void) { _asm { call _penter - call __debug_profile_reference1 call _pexit ret } @@ -145,31 +230,25 @@ __debug_profile_reference2(void) { void debug_profile_start(void) { - static unsigned no = 0; - char filename[FILE_NAME_SIZE]; - unsigned i; - - util_snprintf(filename, sizeof(filename), "\\??\\c:\\%03u.prof", ++no); - for(i = 0; i < FILE_NAME_SIZE; ++i) - wFileName[i] = (WCHAR)filename[i]; + debug_profile_open(); - pMap = EngMapFile(wFileName, PROFILE_FILE_SIZE, &iFile); if(pMap) { - pMapEnd = (unsigned char*)pMap + PROFILE_FILE_SIZE; - /* reference functions for calibration purposes */ - __debug_profile_reference2(); + unsigned i; + for(i = 0; i < 8; ++i) { + _asm { + call _penter + call __debug_profile_reference + call _pexit + } + } } } + void debug_profile_stop(void) { - if(iFile) { - EngUnmapFile(iFile); - /* TODO: truncate file */ - } - iFile = 0; - pMapEnd = pMap = NULL; + debug_profile_close(); } #endif /* PROFILE */ -- cgit v1.2.3 From 883097053d1d3550cab92362a07f413e110520ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 22 Jul 2008 09:45:10 +0900 Subject: win32kprof: Store the profile data as an caller->callee hash table, instead of a trace. --- src/gallium/auxiliary/util/p_debug_prof.c | 308 ++++++++++++++++++------------ 1 file changed, 187 insertions(+), 121 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug_prof.c b/src/gallium/auxiliary/util/p_debug_prof.c index 69c914c780..5f9772ef91 100644 --- a/src/gallium/auxiliary/util/p_debug_prof.c +++ b/src/gallium/auxiliary/util/p_debug_prof.c @@ -46,97 +46,83 @@ #include "util/u_string.h" -#define PROFILE_FILE_SIZE 4*1024*1024 +#define PROFILE_TABLE_SIZE (1024*1024) #define FILE_NAME_SIZE 256 -static WCHAR wFileName[FILE_NAME_SIZE] = L"\\??\\c:\\00000000.trace"; -static ULONG_PTR iFile = 0; -static BYTE *pMap = NULL; -static BYTE *pMapBegin = NULL; -static BYTE *pMapEnd = NULL; +struct debug_profile_entry +{ + uintptr_t caller; + uintptr_t callee; + uint64_t samples; +}; +static unsigned long enabled = 0; -void __declspec(naked) __cdecl -debug_profile_close(void) -{ - _asm { - push eax - push ebx - push ecx - push edx - push ebp - push edi - push esi - } +static WCHAR wFileName[FILE_NAME_SIZE] = L"\\??\\c:\\00000000.prof"; +static ULONG_PTR iFile = 0; - if(iFile) { - EngUnmapFile(iFile); - /* Truncate the file */ - pMap = EngMapFile(wFileName, pMap - pMapBegin, &iFile); - if(pMap) - EngUnmapFile(iFile); - } - iFile = 0; - pMapBegin = pMapEnd = pMap = NULL; - - _asm { - pop esi - pop edi - pop ebp - pop edx - pop ecx - pop ebx - pop eax - ret - } -} +static struct debug_profile_entry *table = NULL; +static unsigned long free_table_entries = 0; +static unsigned long max_table_entries = 0; +uint64_t start_stamp = 0; +uint64_t end_stamp = 0; -void __declspec(naked) __cdecl -debug_profile_open(void) -{ - WCHAR *p; - - _asm { - push eax - push ebx - push ecx - push edx - push ebp - push edi - push esi - } - debug_profile_close(); +static void +debug_profile_entry(uintptr_t caller, uintptr_t callee, uint64_t samples) +{ + unsigned hash = ( caller + callee ) & PROFILE_TABLE_SIZE - 1; - // increment starting from the less significant digit - p = &wFileName[14]; while(1) { - if(*p == '9') { - *p-- = '0'; + if(table[hash].caller == 0 && table[hash].callee == 0) { + table[hash].caller = caller; + table[hash].callee = callee; + table[hash].samples = samples; + --free_table_entries; + break; } - else { - *p += 1; + else if(table[hash].caller == caller && table[hash].callee == callee) { + table[hash].samples += samples; break; } + else { + ++hash; + } } +} - pMap = EngMapFile(wFileName, PROFILE_FILE_SIZE, &iFile); - if(pMap) { - pMapBegin = pMap; - pMapEnd = pMap + PROFILE_FILE_SIZE; - } - - _asm { - pop esi - pop edi - pop ebp - pop edx - pop ecx - pop ebx - pop eax - ret - } + +static uintptr_t caller_stack[1024]; +static unsigned last_caller = 0; + + +static int64_t delta(void) { + int64_t result = end_stamp - start_stamp; + if(result > UINT64_C(0xffffffff)) + result = 0; + return result; +} + + +static void __cdecl +debug_profile_enter(uintptr_t callee) +{ + uintptr_t caller = last_caller ? caller_stack[last_caller - 1] : 0; + + if (caller) + debug_profile_entry(caller, 0, delta()); + debug_profile_entry(caller, callee, 1); + caller_stack[last_caller++] = callee; +} + + +static void __cdecl +debug_profile_exit(uintptr_t callee) +{ + debug_profile_entry(callee, 0, delta()); + if(last_caller) + --last_caller; } @@ -148,31 +134,49 @@ debug_profile_open(void) void __declspec(naked) __cdecl _penter(void) { _asm { - push ebx -retry: - mov ebx, [pMap] - test ebx, ebx - jz done - cmp ebx, [pMapEnd] - jne ready - call debug_profile_open - jmp retry -ready: push eax + mov eax, [enabled] + test eax, eax + jz skip + push edx - mov eax, [esp+12] - and eax, 0xfffffffe - mov [ebx], eax - add ebx, 4 + rdtsc - mov [ebx], eax - add ebx, 4 - mov [pMap], ebx + mov dword ptr [end_stamp], eax + mov dword ptr [end_stamp+4], edx + + xor eax, eax + mov [enabled], eax + + mov eax, [esp+8] + + push ebx + push ecx + push ebp + push edi + push esi + + push eax + call debug_profile_enter + add esp, 4 + + pop esi + pop edi + pop ebp + pop ecx + pop ebx + + mov eax, 1 + mov [enabled], eax + + rdtsc + mov dword ptr [start_stamp], eax + mov dword ptr [start_stamp+4], edx + pop edx +skip: pop eax -done: - pop ebx - ret + ret } } @@ -185,30 +189,48 @@ done: void __declspec(naked) __cdecl _pexit(void) { _asm { - push ebx -retry: - mov ebx, [pMap] - test ebx, ebx - jz done - cmp ebx, [pMapEnd] - jne ready - call debug_profile_open - jmp retry -ready: push eax + mov eax, [enabled] + test eax, eax + jz skip + push edx - mov eax, [esp+12] - or eax, 0x00000001 - mov [ebx], eax - add ebx, 4 + rdtsc - mov [ebx], eax - add ebx, 4 - mov [pMap], ebx + mov dword ptr [end_stamp], eax + mov dword ptr [end_stamp+4], edx + + xor eax, eax + mov [enabled], eax + + mov eax, [esp+8] + + push ebx + push ecx + push ebp + push edi + push esi + + push eax + call debug_profile_exit + add esp, 4 + + pop esi + pop edi + pop ebp + pop ecx + pop ebx + + mov eax, 1 + mov [enabled], eax + + rdtsc + mov dword ptr [start_stamp], eax + mov dword ptr [start_stamp+4], edx + pop edx +skip: pop eax -done: - pop ebx ret } } @@ -230,15 +252,53 @@ __debug_profile_reference(void) { void debug_profile_start(void) { - debug_profile_open(); - - if(pMap) { + WCHAR *p; + + // increment starting from the less significant digit + p = &wFileName[14]; + while(1) { + if(*p == '9') { + *p-- = '0'; + } + else { + *p += 1; + break; + } + } + + table = EngMapFile(wFileName, + PROFILE_TABLE_SIZE*sizeof(struct debug_profile_entry), + &iFile); + if(table) { unsigned i; + + free_table_entries = max_table_entries = PROFILE_TABLE_SIZE; + memset(table, 0, PROFILE_TABLE_SIZE*sizeof(struct debug_profile_entry)); + + table[0].caller = (uintptr_t)&__debug_profile_reference; + table[0].callee = 0; + table[0].samples = 0; + --free_table_entries; + + _asm { + push edx + push eax + + rdtsc + mov dword ptr [start_stamp], eax + mov dword ptr [start_stamp+4], edx + + pop edx + pop eax + } + + last_caller = 0; + + enabled = 1; + for(i = 0; i < 8; ++i) { _asm { - call _penter call __debug_profile_reference - call _pexit } } } @@ -248,7 +308,13 @@ debug_profile_start(void) void debug_profile_stop(void) { - debug_profile_close(); + enabled = 0; + + if(iFile) + EngUnmapFile(iFile); + iFile = 0; + table = NULL; + free_table_entries = max_table_entries = 0; } #endif /* PROFILE */ -- cgit v1.2.3 From 51d219dbfe6852d348755574184639940af444e3 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 22 Jul 2008 17:14:54 +0200 Subject: tgsi: Fix immediate usage checks. Provide more info for register usage errors/warnings. --- src/gallium/auxiliary/tgsi/util/tgsi_sanity.c | 56 +++++++++++++++++++++------ 1 file changed, 45 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c index 08f3995b13..9673f061ce 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c @@ -53,18 +53,32 @@ struct sanity_check_ctx static void report_error( struct sanity_check_ctx *ctx, - const char *msg ) + const char *format, + ... ) { - debug_printf( "\nError: %s", msg ); + va_list args; + + debug_printf( "Error : " ); + va_start( args, format ); + _debug_vprintf( format, args ); + va_end( args ); + debug_printf( "\n" ); ctx->errors++; } static void report_warning( struct sanity_check_ctx *ctx, - const char *msg ) + const char *format, + ... ) { - debug_printf( "\nWarning: %s", msg ); + va_list args; + + debug_printf( "Warning: " ); + va_start( args, format ); + _debug_vprintf( format, args ); + va_end( args ); + debug_printf( "\n" ); ctx->warnings++; } @@ -74,7 +88,7 @@ check_file_name( uint file ) { if (file <= TGSI_FILE_NULL || file >= TGSI_FILE_COUNT) { - report_error( ctx, "Invalid file name" ); + report_error( ctx, "Invalid register file name" ); return FALSE; } return TRUE; @@ -115,23 +129,36 @@ is_register_used( return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; } +static const char *file_names[] = +{ + "NULL", + "CONST", + "IN", + "OUT", + "TEMP", + "SAMP", + "ADDR", + "IMM" +}; + static boolean check_register_usage( struct sanity_check_ctx *ctx, uint file, int index, - boolean indirect ) + const char *name, + boolean indirect_access ) { if (!check_file_name( ctx, file )) return FALSE; - if (indirect) { + if (indirect_access) { if (!is_any_register_declared( ctx, file )) - report_error( ctx, "Undeclared source register" ); + report_error( ctx, "%s: Undeclared %s register", file_names[file], name ); ctx->regs_ind_used[file] = TRUE; } else { if (!is_register_declared( ctx, file, index )) - report_error( ctx, "Undeclared destination register" ); + report_error( ctx, "%s[%d]: Undeclared %s register", file_names[file], index, name ); ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG)); } return TRUE; @@ -162,6 +189,7 @@ iter_instruction( ctx, inst->FullDstRegisters[i].DstRegister.File, inst->FullDstRegisters[i].DstRegister.Index, + "destination", FALSE ); } for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { @@ -169,6 +197,7 @@ iter_instruction( ctx, inst->FullSrcRegisters[i].SrcRegister.File, inst->FullSrcRegisters[i].SrcRegister.Index, + "source", inst->FullSrcRegisters[i].SrcRegister.Indirect ); if (inst->FullSrcRegisters[i].SrcRegister.Indirect) { uint file; @@ -176,7 +205,12 @@ iter_instruction( file = inst->FullSrcRegisters[i].SrcRegisterInd.File; index = inst->FullSrcRegisters[i].SrcRegisterInd.Index; - check_register_usage( ctx, file, index, FALSE ); + check_register_usage( + ctx, + file, + index, + "indirect", + FALSE ); if (file != TGSI_FILE_ADDRESS || index != 0) report_warning( ctx, "Indirect register not ADDR[0]" ); } @@ -232,8 +266,8 @@ iter_immediate( /* Mark the register as declared. */ - ctx->num_imms++; ctx->regs_decl[TGSI_FILE_IMMEDIATE][ctx->num_imms / BITS_IN_REG_FLAG] |= (1 << (ctx->num_imms % BITS_IN_REG_FLAG)); + ctx->num_imms++; /* Check data type validity. */ -- cgit v1.2.3 From 818cd9dca2861dfb9d8f2d36ff141c55472df2ba Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 23 Jul 2008 14:02:33 +0200 Subject: i915: intel_flush_frontbuffer does work --- src/gallium/winsys/dri/intel/intel_screen.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c index f2412217f3..b3022fd17a 100644 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ b/src/gallium/winsys/dri/intel/intel_screen.c @@ -253,12 +253,10 @@ intel_flush_frontbuffer( struct pipe_winsys *winsys, struct pipe_surface *surf, void *context_private) { - //struct intel_context *intel = (struct intel_context *) context_private; - //__DRIdrawablePrivate *dPriv = intel->driDrawable; + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; - assert((int)"Doesn't work currently" & 0); - - //intelDisplaySurface(dPriv, surf, NULL); + intelDisplaySurface(dPriv, surf, NULL); } static boolean -- cgit v1.2.3 From 0aa0141e0cd7b5231140805b1cda821bb3d32a86 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 23 Jul 2008 17:52:56 +0200 Subject: tgsi: Fix tgsi_util_get_full_src_register_extswizzle(). --- src/gallium/auxiliary/tgsi/util/tgsi_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.c b/src/gallium/auxiliary/tgsi/util/tgsi_util.c index 10762b6c1a..09486e649e 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_util.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_util.c @@ -119,7 +119,7 @@ tgsi_util_get_full_src_register_extswizzle( if( swizzle <= TGSI_SWIZZLE_W ) { swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegister, - component ); + swizzle ); } return swizzle; -- cgit v1.2.3 From 5f2a5f6164ace6e12c1a3ba95f1103dc8fafa68f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Jul 2008 09:56:44 -0600 Subject: gallium: print extended swizzle negation flags --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index 94180f7e50..d2e6375212 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -491,9 +491,17 @@ tgsi_dump_instruction( src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) { CHR( '.' ); + if (src->SrcRegisterExtSwz.NegateX) + TXT("-"); ENM( src->SrcRegisterExtSwz.ExtSwizzleX, extswizzle_names ); + if (src->SrcRegisterExtSwz.NegateY) + TXT("-"); ENM( src->SrcRegisterExtSwz.ExtSwizzleY, extswizzle_names ); + if (src->SrcRegisterExtSwz.NegateZ) + TXT("-"); ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, extswizzle_names ); + if (src->SrcRegisterExtSwz.NegateW) + TXT("-"); ENM( src->SrcRegisterExtSwz.ExtSwizzleW, extswizzle_names ); } -- cgit v1.2.3 From f7be39ea105aa951d0f6e1d8ffbea63412e30801 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Jul 2008 16:28:15 -0600 Subject: gallium: bump TGSI_EXEC_NUM_TEMPS to 128 --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h index 18abdd9ac0..4f30650b07 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h @@ -100,7 +100,7 @@ struct tgsi_exec_labels }; -#define TGSI_EXEC_NUM_TEMPS 64 +#define TGSI_EXEC_NUM_TEMPS 128 #define TGSI_EXEC_NUM_TEMP_EXTRAS 6 #define TGSI_EXEC_NUM_IMMEDIATES 256 -- cgit v1.2.3 From 83869ceab5b3faed8569a5ca752d4dc426db1aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 22 Jul 2008 22:07:22 +0900 Subject: tgsi: Silent msvc warning. Rather stupid warning: msvc is warning that converting from a 1bit structure bitfield to a unsigned char looses precision... /WX makes this an error. --- src/gallium/auxiliary/tgsi/util/tgsi_sanity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c index 9673f061ce..2e3ec96b5b 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c @@ -198,7 +198,7 @@ iter_instruction( inst->FullSrcRegisters[i].SrcRegister.File, inst->FullSrcRegisters[i].SrcRegister.Index, "source", - inst->FullSrcRegisters[i].SrcRegister.Indirect ); + (boolean)inst->FullSrcRegisters[i].SrcRegister.Indirect ); if (inst->FullSrcRegisters[i].SrcRegister.Indirect) { uint file; int index; -- cgit v1.2.3 From fd6865c7e5c3c38c273b8269ff30a1acec469b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 23 Jul 2008 11:15:54 +0900 Subject: softpipe: Remove unused variables. --- src/gallium/drivers/softpipe/sp_tile_cache.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index bfdaaa6b8f..5d10234945 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -364,7 +364,6 @@ void sp_flush_tile_cache(struct softpipe_context *softpipe, struct softpipe_tile_cache *tc) { - struct pipe_context *pipe = &softpipe->pipe; struct pipe_surface *ps = tc->surface; int inuse = 0, pos; @@ -414,7 +413,6 @@ struct softpipe_cached_tile * sp_get_cached_tile(struct softpipe_context *softpipe, struct softpipe_tile_cache *tc, int x, int y) { - struct pipe_context *pipe = &softpipe->pipe; struct pipe_surface *ps = tc->surface; /* tile pos in framebuffer: */ -- cgit v1.2.3 From ff7a7031caa0ac592f210aca696a20c9de6dc0d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 26 Jul 2008 09:17:10 +0900 Subject: gallium: Windows miniport portability fixes. --- src/gallium/auxiliary/util/p_debug.c | 12 +++---- src/gallium/auxiliary/util/u_snprintf.c | 10 ++++++ src/gallium/include/pipe/p_util.h | 63 +++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index b0240ad737..cdc7e66361 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -73,8 +73,7 @@ _EngDebugPrint(const char *format, ...) void _debug_vprintf(const char *format, va_list ap) { -#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY -#ifndef WINCE +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) /* EngDebugPrint does not handle float point arguments, so we need to use * our own vsnprintf implementation. It is also very slow, so buffer until * we find a newline. */ @@ -85,9 +84,6 @@ void _debug_vprintf(const char *format, va_list ap) _EngDebugPrint("%s", buf); buf[0] = '\0'; } -#else - /* TODO: Implement debug print for WINCE */ -#endif #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) /* EngDebugPrint does not handle float point arguments, so we need to use * our own vsnprintf implementation. It is also very slow, so buffer until @@ -99,7 +95,9 @@ void _debug_vprintf(const char *format, va_list ap) OutputDebugStringA(buf); buf[0] = '\0'; } -#else +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + /* TODO */ +#else /* !PIPE_SUBSYSTEM_WINDOWS */ vfprintf(stderr, format, ap); #endif } @@ -211,7 +209,7 @@ _debug_get_option(const char *name) #else return NULL; #endif -#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) +#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) /* TODO: implement */ return NULL; #else diff --git a/src/gallium/auxiliary/util/u_snprintf.c b/src/gallium/auxiliary/util/u_snprintf.c index c4f4bbd30c..7fa84d8bec 100644 --- a/src/gallium/auxiliary/util/u_snprintf.c +++ b/src/gallium/auxiliary/util/u_snprintf.c @@ -162,6 +162,8 @@ * . */ +#include "pipe/p_config.h" + #if HAVE_CONFIG_H #include #else @@ -1102,7 +1104,11 @@ again: * Factor of ten with the number of digits needed for the fractional * part. For example, if the precision is 3, the mask will be 1000. */ +#if defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + mask = (unsigned long)mypow10(precision); +#else mask = (UINTMAX_T)mypow10(precision); +#endif /* * We "cheat" by converting the fractional part to integer by * multiplying by a factor of ten. @@ -1354,7 +1360,11 @@ cast(LDOUBLE value) if (value >= UINTMAX_MAX) return UINTMAX_MAX; +#if defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + result = (unsigned long)value; +#else result = (UINTMAX_T)value; +#endif /* * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 7dcdd28287..892bd4bf8a 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -33,8 +33,71 @@ #include "p_debug.h" #include "p_format.h" #include "p_pointer.h" + +#if defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) +__inline double ceil(double val) +{ + double ceil_val; + + if((val - (long) val) == 0) { + ceil_val = val; + } else { + if(val > 0) { + ceil_val = (long) val + 1; + } else { + ceil_val = (long) val; + } + } + + return ceil_val; +} + +#ifndef PIPE_SUBSYSTEM_WINDOWS_CE +__inline double floor(double val) +{ + double floor_val; + + if((val - (long) val) == 0) { + floor_val = val; + } else { + if(val > 0) { + floor_val = (long) val; + } else { + floor_val = (long) val - 1; + } + } + + return floor_val; +} +#endif + +#pragma function(pow) +__inline double __cdecl pow(double val, double exponent) +{ + /* XXX */ + assert(0); + return 0; +} + +#pragma function(log) +__inline double __cdecl log(double val) +{ + /* XXX */ + assert(0); + return 0; +} + +#pragma function(atan2) +__inline double __cdecl atan2(double val) +{ + /* XXX */ + assert(0); + return 0; +} +#else #include #include +#endif #ifdef __cplusplus -- cgit v1.2.3 From c208a2c791fa24c7c5887fc496738cbddbfafc72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 28 Jul 2008 12:42:13 +0900 Subject: Merge tgsi/exec and tgsi/util directories. --- src/gallium/auxiliary/cso_cache/cso_context.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 4 +- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 4 +- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 4 +- src/gallium/auxiliary/draw/draw_private.h | 4 +- src/gallium/auxiliary/draw/draw_vs_aos.c | 8 +- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 6 +- src/gallium/auxiliary/draw/draw_vs_aos_machine.c | 6 +- src/gallium/auxiliary/draw/draw_vs_exec.c | 4 +- src/gallium/auxiliary/draw/draw_vs_llvm.c | 2 +- src/gallium/auxiliary/draw/draw_vs_sse.c | 4 +- src/gallium/auxiliary/gallivm/gallivm.cpp | 4 +- src/gallium/auxiliary/gallivm/gallivm_cpu.cpp | 4 +- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 10 +- src/gallium/auxiliary/tgsi/Makefile | 18 +- src/gallium/auxiliary/tgsi/SConscript | 24 +- src/gallium/auxiliary/tgsi/exec/Makefile | 2 - src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 2522 -------------------- src/gallium/auxiliary/tgsi/exec/tgsi_exec.h | 253 -- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2275 ------------------ src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h | 49 - src/gallium/auxiliary/tgsi/tgsi_build.c | 1324 ++++++++++ src/gallium/auxiliary/tgsi/tgsi_build.h | 332 +++ src/gallium/auxiliary/tgsi/tgsi_dump.c | 582 +++++ src/gallium/auxiliary/tgsi/tgsi_dump.h | 63 + src/gallium/auxiliary/tgsi/tgsi_dump_c.c | 845 +++++++ src/gallium/auxiliary/tgsi/tgsi_dump_c.h | 49 + src/gallium/auxiliary/tgsi/tgsi_exec.c | 2522 ++++++++++++++++++++ src/gallium/auxiliary/tgsi/tgsi_exec.h | 253 ++ src/gallium/auxiliary/tgsi/tgsi_iterate.c | 85 + src/gallium/auxiliary/tgsi/tgsi_iterate.h | 76 + src/gallium/auxiliary/tgsi/tgsi_parse.c | 332 +++ src/gallium/auxiliary/tgsi/tgsi_parse.h | 151 ++ src/gallium/auxiliary/tgsi/tgsi_sanity.c | 341 +++ src/gallium/auxiliary/tgsi/tgsi_sanity.h | 49 + src/gallium/auxiliary/tgsi/tgsi_scan.c | 226 ++ src/gallium/auxiliary/tgsi/tgsi_scan.h | 74 + src/gallium/auxiliary/tgsi/tgsi_sse2.c | 2275 ++++++++++++++++++ src/gallium/auxiliary/tgsi/tgsi_sse2.h | 49 + src/gallium/auxiliary/tgsi/tgsi_text.c | 1221 ++++++++++ src/gallium/auxiliary/tgsi/tgsi_text.h | 47 + src/gallium/auxiliary/tgsi/tgsi_transform.c | 199 ++ src/gallium/auxiliary/tgsi/tgsi_transform.h | 93 + src/gallium/auxiliary/tgsi/tgsi_util.c | 300 +++ src/gallium/auxiliary/tgsi/tgsi_util.h | 96 + src/gallium/auxiliary/tgsi/util/tgsi_build.c | 1324 ---------- src/gallium/auxiliary/tgsi/util/tgsi_build.h | 332 --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 582 ----- src/gallium/auxiliary/tgsi/util/tgsi_dump.h | 63 - src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c | 845 ------- src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h | 49 - src/gallium/auxiliary/tgsi/util/tgsi_iterate.c | 85 - src/gallium/auxiliary/tgsi/util/tgsi_iterate.h | 76 - src/gallium/auxiliary/tgsi/util/tgsi_parse.c | 332 --- src/gallium/auxiliary/tgsi/util/tgsi_parse.h | 151 -- src/gallium/auxiliary/tgsi/util/tgsi_sanity.c | 341 --- src/gallium/auxiliary/tgsi/util/tgsi_sanity.h | 49 - src/gallium/auxiliary/tgsi/util/tgsi_scan.c | 226 -- src/gallium/auxiliary/tgsi/util/tgsi_scan.h | 74 - src/gallium/auxiliary/tgsi/util/tgsi_text.c | 1221 ---------- src/gallium/auxiliary/tgsi/util/tgsi_text.h | 47 - src/gallium/auxiliary/tgsi/util/tgsi_transform.c | 199 -- src/gallium/auxiliary/tgsi/util/tgsi_transform.h | 93 - src/gallium/auxiliary/tgsi/util/tgsi_util.c | 300 --- src/gallium/auxiliary/tgsi/util/tgsi_util.h | 96 - src/gallium/auxiliary/util/u_gen_mipmap.c | 6 +- src/gallium/auxiliary/util/u_simple_shaders.c | 6 +- src/gallium/drivers/cell/ppu/cell_context.h | 2 +- src/gallium/drivers/cell/ppu/cell_state_shader.c | 2 +- src/gallium/drivers/cell/spu/spu_exec.c | 4 +- src/gallium/drivers/cell/spu/spu_exec.h | 2 +- src/gallium/drivers/cell/spu/spu_util.c | 4 +- src/gallium/drivers/i915simple/i915_context.h | 2 +- .../drivers/i915simple/i915_fpc_translate.c | 4 +- src/gallium/drivers/i915simple/i915_state.c | 2 +- src/gallium/drivers/i965simple/brw_context.h | 2 +- src/gallium/drivers/i965simple/brw_sf.c | 2 +- src/gallium/drivers/i965simple/brw_shader_info.c | 2 +- src/gallium/drivers/i965simple/brw_state.c | 4 +- src/gallium/drivers/i965simple/brw_vs_emit.c | 2 +- src/gallium/drivers/i965simple/brw_wm_decl.c | 2 +- src/gallium/drivers/i965simple/brw_wm_glsl.c | 2 +- src/gallium/drivers/softpipe/sp_fs_exec.c | 4 +- src/gallium/drivers/softpipe/sp_fs_llvm.c | 2 +- src/gallium/drivers/softpipe/sp_fs_sse.c | 4 +- src/gallium/drivers/softpipe/sp_headers.h | 2 +- src/gallium/drivers/softpipe/sp_state.h | 2 +- src/gallium/drivers/softpipe/sp_state_fs.c | 4 +- src/gallium/drivers/softpipe/sp_tex_sample.c | 2 +- src/gallium/state_trackers/python/gallium.i | 4 +- 90 files changed, 11675 insertions(+), 11677 deletions(-) delete mode 100644 src/gallium/auxiliary/tgsi/exec/Makefile delete mode 100644 src/gallium/auxiliary/tgsi/exec/tgsi_exec.c delete mode 100644 src/gallium/auxiliary/tgsi/exec/tgsi_exec.h delete mode 100755 src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c delete mode 100755 src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_build.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_build.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_dump.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_dump.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_dump_c.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_dump_c.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_exec.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_exec.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_iterate.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_iterate.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_parse.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_parse.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_sanity.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_sanity.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_scan.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_scan.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_sse2.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_sse2.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_text.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_text.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_transform.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_transform.h create mode 100644 src/gallium/auxiliary/tgsi/tgsi_util.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_util.h delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_build.c delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_build.h delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_dump.c delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_dump.h delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_iterate.c delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_iterate.h delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_parse.c delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_parse.h delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_sanity.c delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_sanity.h delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_scan.c delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_scan.h delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_text.c delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_text.h delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_transform.c delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_transform.h delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_util.c delete mode 100644 src/gallium/auxiliary/tgsi/util/tgsi_util.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index af4af8ac1d..86e4d46a20 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -38,7 +38,7 @@ #include "pipe/p_state.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" #include "cso_cache/cso_context.h" #include "cso_cache/cso_cache.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 3dd7ee19fd..991304b2c8 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -38,8 +38,8 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_transform.h" -#include "tgsi/util/tgsi_dump.h" +#include "tgsi/tgsi_transform.h" +#include "tgsi/tgsi_dump.h" #include "draw_context.h" #include "draw_private.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 87fd303649..13b4401521 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -44,8 +44,8 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_transform.h" -#include "tgsi/util/tgsi_dump.h" +#include "tgsi/tgsi_transform.h" +#include "tgsi/tgsi_dump.h" #include "draw_context.h" #include "draw_vs.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 1f63f94365..d3bd9baddd 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -40,8 +40,8 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_transform.h" -#include "tgsi/util/tgsi_dump.h" +#include "tgsi/tgsi_transform.h" +#include "tgsi/tgsi_dump.h" #include "draw_context.h" #include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 7bd1e670b4..626a2e3e30 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -44,8 +44,8 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_exec.h" +#include "tgsi/tgsi_scan.h" struct pipe_context; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 1f926b3e85..441877d46f 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -31,10 +31,10 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_dump.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" +#include "tgsi/tgsi_exec.h" +#include "tgsi/tgsi_dump.h" #include "draw_vs.h" #include "draw_vs_aos.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index 8e834501a4..eda677cc62 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -28,9 +28,9 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" -#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" +#include "tgsi/tgsi_exec.h" #include "draw_vs.h" #include "draw_vs_aos.h" #include "draw_vertex.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c index 6a54917ae3..e029b7b4bb 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c @@ -31,9 +31,9 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" -#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" +#include "tgsi/tgsi_exec.h" #include "draw_vs.h" #include "draw_vs_aos.h" #include "draw_vertex.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 4501877efc..e26903d8cc 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -38,8 +38,8 @@ #include "draw_context.h" #include "draw_vs.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_scan.h" struct exec_vertex_shader { diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index c63bd51a10..fc03473b91 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -38,7 +38,7 @@ #include "draw_context.h" #include "draw_vs.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" #ifdef MESA_LLVM diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index c3189c707d..61f0c084c3 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -45,8 +45,8 @@ #include "rtasm/rtasm_cpu.h" #include "rtasm/rtasm_x86sse.h" -#include "tgsi/exec/tgsi_sse2.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_sse2.h" +#include "tgsi/tgsi_parse.h" #define SSE_MAX_VERTICES 4 diff --git a/src/gallium/auxiliary/gallivm/gallivm.cpp b/src/gallium/auxiliary/gallivm/gallivm.cpp index 77900e342b..29adeea47d 100644 --- a/src/gallium/auxiliary/gallivm/gallivm.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm.cpp @@ -42,8 +42,8 @@ #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_dump.h" +#include "tgsi/tgsi_exec.h" +#include "tgsi/tgsi_dump.h" #include #include diff --git a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp index 857c190f7b..cf5b978837 100644 --- a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp @@ -43,8 +43,8 @@ #include "pipe/p_shader_tokens.h" #include "pipe/p_util.h" -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_dump.h" +#include "tgsi/tgsi_exec.h" +#include "tgsi/tgsi_dump.h" #include #include diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index 98014bdaa1..b14e2affd6 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -10,11 +10,11 @@ #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_util.h" -#include "tgsi/util/tgsi_build.h" -#include "tgsi/util/tgsi_dump.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_exec.h" +#include "tgsi/tgsi_util.h" +#include "tgsi/tgsi_build.h" +#include "tgsi/tgsi_dump.h" #include diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index 9c4b967651..bbeff1304d 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -4,15 +4,15 @@ include $(TOP)/configs/current LIBNAME = tgsi C_SOURCES = \ - exec/tgsi_exec.c \ - exec/tgsi_sse2.c \ - util/tgsi_iterate.c \ - util/tgsi_build.c \ - util/tgsi_dump.c \ - util/tgsi_parse.c \ - util/tgsi_scan.c \ - util/tgsi_transform.c \ - util/tgsi_util.c + tgsi_build.c \ + tgsi_dump.c \ + tgsi_exec.c \ + tgsi_iterate.c \ + tgsi_parse.c \ + tgsi_scan.c \ + tgsi_sse2.c \ + tgsi_transform.c \ + tgsi_util.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript index 3bbfa1be54..03982e2194 100644 --- a/src/gallium/auxiliary/tgsi/SConscript +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -3,18 +3,18 @@ Import('*') tgsi = env.ConvenienceLibrary( target = 'tgsi', source = [ - 'exec/tgsi_exec.c', - 'exec/tgsi_sse2.c', - 'util/tgsi_build.c', - 'util/tgsi_dump.c', - 'util/tgsi_dump_c.c', - 'util/tgsi_iterate.c', - 'util/tgsi_parse.c', - 'util/tgsi_sanity.c', - 'util/tgsi_scan.c', - 'util/tgsi_text.c', - 'util/tgsi_transform.c', - 'util/tgsi_util.c', + 'tgsi_build.c', + 'tgsi_dump.c', + 'tgsi_dump_c.c', + 'tgsi_exec.c', + 'tgsi_iterate.c', + 'tgsi_parse.c', + 'tgsi_sanity.c', + 'tgsi_scan.c', + 'tgsi_sse2.c', + 'tgsi_text.c', + 'tgsi_transform.c', + 'tgsi_util.c', ]) auxiliaries.insert(0, tgsi) diff --git a/src/gallium/auxiliary/tgsi/exec/Makefile b/src/gallium/auxiliary/tgsi/exec/Makefile deleted file mode 100644 index 451911a354..0000000000 --- a/src/gallium/auxiliary/tgsi/exec/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -default: - cd .. ; make diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c deleted file mode 100644 index 001a4c4b15..0000000000 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ /dev/null @@ -1,2522 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * TGSI interpretor/executor. - * - * Flow control information: - * - * Since we operate on 'quads' (4 pixels or 4 vertices in parallel) - * flow control statements (IF/ELSE/ENDIF, LOOP/ENDLOOP) require special - * care since a condition may be true for some quad components but false - * for other components. - * - * We basically execute all statements (even if they're in the part of - * an IF/ELSE clause that's "not taken") and use a special mask to - * control writing to destination registers. This is the ExecMask. - * See store_dest(). - * - * The ExecMask is computed from three other masks (CondMask, LoopMask and - * ContMask) which are controlled by the flow control instructions (namely: - * (IF/ELSE/ENDIF, LOOP/ENDLOOP and CONT). - * - * - * Authors: - * Michal Krol - * Brian Paul - */ - -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" -#include "tgsi_exec.h" - -#define TILE_TOP_LEFT 0 -#define TILE_TOP_RIGHT 1 -#define TILE_BOTTOM_LEFT 2 -#define TILE_BOTTOM_RIGHT 3 - -/* - * Shorthand locations of various utility registers (_I = Index, _C = Channel) - */ -#define TEMP_0_I TGSI_EXEC_TEMP_00000000_I -#define TEMP_0_C TGSI_EXEC_TEMP_00000000_C -#define TEMP_7F_I TGSI_EXEC_TEMP_7FFFFFFF_I -#define TEMP_7F_C TGSI_EXEC_TEMP_7FFFFFFF_C -#define TEMP_80_I TGSI_EXEC_TEMP_80000000_I -#define TEMP_80_C TGSI_EXEC_TEMP_80000000_C -#define TEMP_FF_I TGSI_EXEC_TEMP_FFFFFFFF_I -#define TEMP_FF_C TGSI_EXEC_TEMP_FFFFFFFF_C -#define TEMP_1_I TGSI_EXEC_TEMP_ONE_I -#define TEMP_1_C TGSI_EXEC_TEMP_ONE_C -#define TEMP_2_I TGSI_EXEC_TEMP_TWO_I -#define TEMP_2_C TGSI_EXEC_TEMP_TWO_C -#define TEMP_128_I TGSI_EXEC_TEMP_128_I -#define TEMP_128_C TGSI_EXEC_TEMP_128_C -#define TEMP_M128_I TGSI_EXEC_TEMP_MINUS_128_I -#define TEMP_M128_C TGSI_EXEC_TEMP_MINUS_128_C -#define TEMP_KILMASK_I TGSI_EXEC_TEMP_KILMASK_I -#define TEMP_KILMASK_C TGSI_EXEC_TEMP_KILMASK_C -#define TEMP_OUTPUT_I TGSI_EXEC_TEMP_OUTPUT_I -#define TEMP_OUTPUT_C TGSI_EXEC_TEMP_OUTPUT_C -#define TEMP_PRIMITIVE_I TGSI_EXEC_TEMP_PRIMITIVE_I -#define TEMP_PRIMITIVE_C TGSI_EXEC_TEMP_PRIMITIVE_C -#define TEMP_3_I TGSI_EXEC_TEMP_THREE_I -#define TEMP_3_C TGSI_EXEC_TEMP_THREE_C -#define TEMP_HALF_I TGSI_EXEC_TEMP_HALF_I -#define TEMP_HALF_C TGSI_EXEC_TEMP_HALF_C -#define TEMP_R0 TGSI_EXEC_TEMP_R0 - -#define FOR_EACH_CHANNEL(CHAN)\ - for (CHAN = 0; CHAN < 4; CHAN++) - -#define IS_CHANNEL_ENABLED(INST, CHAN)\ - ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) - -#define IS_CHANNEL_ENABLED2(INST, CHAN)\ - ((INST).FullDstRegisters[1].DstRegister.WriteMask & (1 << (CHAN))) - -#define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\ - FOR_EACH_CHANNEL( CHAN )\ - if (IS_CHANNEL_ENABLED( INST, CHAN )) - -#define FOR_EACH_ENABLED_CHANNEL2(INST, CHAN)\ - FOR_EACH_CHANNEL( CHAN )\ - if (IS_CHANNEL_ENABLED2( INST, CHAN )) - - -/** The execution mask depends on the conditional mask and the loop mask */ -#define UPDATE_EXEC_MASK(MACH) \ - MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask - - -#define CHAN_X 0 -#define CHAN_Y 1 -#define CHAN_Z 2 -#define CHAN_W 3 - - - -/** - * Initialize machine state by expanding tokens to full instructions, - * allocating temporary storage, setting up constants, etc. - * After this, we can call tgsi_exec_machine_run() many times. - */ -void -tgsi_exec_machine_bind_shader( - struct tgsi_exec_machine *mach, - const struct tgsi_token *tokens, - uint numSamplers, - struct tgsi_sampler *samplers) -{ - uint k; - struct tgsi_parse_context parse; - struct tgsi_exec_labels *labels = &mach->Labels; - struct tgsi_full_instruction *instructions; - struct tgsi_full_declaration *declarations; - uint maxInstructions = 10, numInstructions = 0; - uint maxDeclarations = 10, numDeclarations = 0; - uint instno = 0; - -#if 0 - tgsi_dump(tokens, 0); -#endif - - mach->Tokens = tokens; - mach->Samplers = samplers; - - k = tgsi_parse_init (&parse, mach->Tokens); - if (k != TGSI_PARSE_OK) { - debug_printf( "Problem parsing!\n" ); - return; - } - - mach->Processor = parse.FullHeader.Processor.Processor; - mach->ImmLimit = 0; - labels->count = 0; - - declarations = (struct tgsi_full_declaration *) - MALLOC( maxDeclarations * sizeof(struct tgsi_full_declaration) ); - - if (!declarations) { - return; - } - - instructions = (struct tgsi_full_instruction *) - MALLOC( maxInstructions * sizeof(struct tgsi_full_instruction) ); - - if (!instructions) { - FREE( declarations ); - return; - } - - while( !tgsi_parse_end_of_tokens( &parse ) ) { - uint pointer = parse.Position; - uint i; - - tgsi_parse_token( &parse ); - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - /* save expanded declaration */ - if (numDeclarations == maxDeclarations) { - declarations = REALLOC(declarations, - maxDeclarations - * sizeof(struct tgsi_full_declaration), - (maxDeclarations + 10) - * sizeof(struct tgsi_full_declaration)); - maxDeclarations += 10; - } - memcpy(declarations + numDeclarations, - &parse.FullToken.FullDeclaration, - sizeof(declarations[0])); - numDeclarations++; - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - { - uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; - assert( size % 4 == 0 ); - assert( mach->ImmLimit + size / 4 <= TGSI_EXEC_NUM_IMMEDIATES ); - - for( i = 0; i < size; i++ ) { - mach->Imms[mach->ImmLimit + i / 4][i % 4] = - parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; - } - mach->ImmLimit += size / 4; - } - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - assert( labels->count < MAX_LABELS ); - - labels->labels[labels->count][0] = instno; - labels->labels[labels->count][1] = pointer; - labels->count++; - - /* save expanded instruction */ - if (numInstructions == maxInstructions) { - instructions = REALLOC(instructions, - maxInstructions - * sizeof(struct tgsi_full_instruction), - (maxInstructions + 10) - * sizeof(struct tgsi_full_instruction)); - maxInstructions += 10; - } - memcpy(instructions + numInstructions, - &parse.FullToken.FullInstruction, - sizeof(instructions[0])); - numInstructions++; - break; - - default: - assert( 0 ); - } - } - tgsi_parse_free (&parse); - - if (mach->Declarations) { - FREE( mach->Declarations ); - } - mach->Declarations = declarations; - mach->NumDeclarations = numDeclarations; - - if (mach->Instructions) { - FREE( mach->Instructions ); - } - mach->Instructions = instructions; - mach->NumInstructions = numInstructions; -} - - -void -tgsi_exec_machine_init( - struct tgsi_exec_machine *mach ) -{ - uint i; - - mach->Temps = (struct tgsi_exec_vector *) tgsi_align_128bit( mach->_Temps); - mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR]; - - /* Setup constants. */ - for( i = 0; i < 4; i++ ) { - mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].u[i] = 0x00000000; - mach->Temps[TEMP_7F_I].xyzw[TEMP_7F_C].u[i] = 0x7FFFFFFF; - mach->Temps[TEMP_80_I].xyzw[TEMP_80_C].u[i] = 0x80000000; - mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].u[i] = 0xFFFFFFFF; - mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].f[i] = 1.0f; - mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].f[i] = 2.0f; - mach->Temps[TEMP_128_I].xyzw[TEMP_128_C].f[i] = 128.0f; - mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C].f[i] = -128.0f; - mach->Temps[TEMP_3_I].xyzw[TEMP_3_C].f[i] = 3.0f; - mach->Temps[TEMP_HALF_I].xyzw[TEMP_HALF_C].f[i] = 0.5f; - } -} - - -void -tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach) -{ - if (mach->Instructions) { - FREE(mach->Instructions); - mach->Instructions = NULL; - mach->NumInstructions = 0; - } - if (mach->Declarations) { - FREE(mach->Declarations); - mach->Declarations = NULL; - mach->NumDeclarations = 0; - } -} - - -static void -micro_abs( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = fabsf( src->f[0] ); - dst->f[1] = fabsf( src->f[1] ); - dst->f[2] = fabsf( src->f[2] ); - dst->f[3] = fabsf( src->f[3] ); -} - -static void -micro_add( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] + src1->f[0]; - dst->f[1] = src0->f[1] + src1->f[1]; - dst->f[2] = src0->f[2] + src1->f[2]; - dst->f[3] = src0->f[3] + src1->f[3]; -} - -static void -micro_iadd( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] + src1->i[0]; - dst->i[1] = src0->i[1] + src1->i[1]; - dst->i[2] = src0->i[2] + src1->i[2]; - dst->i[3] = src0->i[3] + src1->i[3]; -} - -static void -micro_and( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] & src1->u[0]; - dst->u[1] = src0->u[1] & src1->u[1]; - dst->u[2] = src0->u[2] & src1->u[2]; - dst->u[3] = src0->u[3] & src1->u[3]; -} - -static void -micro_ceil( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = ceilf( src->f[0] ); - dst->f[1] = ceilf( src->f[1] ); - dst->f[2] = ceilf( src->f[2] ); - dst->f[3] = ceilf( src->f[3] ); -} - -static void -micro_cos( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = cosf( src->f[0] ); - dst->f[1] = cosf( src->f[1] ); - dst->f[2] = cosf( src->f[2] ); - dst->f[3] = cosf( src->f[3] ); -} - -static void -micro_ddx( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = - dst->f[1] = - dst->f[2] = - dst->f[3] = src->f[TILE_BOTTOM_RIGHT] - src->f[TILE_BOTTOM_LEFT]; -} - -static void -micro_ddy( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = - dst->f[1] = - dst->f[2] = - dst->f[3] = src->f[TILE_TOP_LEFT] - src->f[TILE_BOTTOM_LEFT]; -} - -static void -micro_div( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] / src1->f[0]; - dst->f[1] = src0->f[1] / src1->f[1]; - dst->f[2] = src0->f[2] / src1->f[2]; - dst->f[3] = src0->f[3] / src1->f[3]; -} - -static void -micro_udiv( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] / src1->u[0]; - dst->u[1] = src0->u[1] / src1->u[1]; - dst->u[2] = src0->u[2] / src1->u[2]; - dst->u[3] = src0->u[3] / src1->u[3]; -} - -static void -micro_eq( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->f[0] = src0->f[0] == src1->f[0] ? src2->f[0] : src3->f[0]; - dst->f[1] = src0->f[1] == src1->f[1] ? src2->f[1] : src3->f[1]; - dst->f[2] = src0->f[2] == src1->f[2] ? src2->f[2] : src3->f[2]; - dst->f[3] = src0->f[3] == src1->f[3] ? src2->f[3] : src3->f[3]; -} - -static void -micro_ieq( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->i[0] = src0->i[0] == src1->i[0] ? src2->i[0] : src3->i[0]; - dst->i[1] = src0->i[1] == src1->i[1] ? src2->i[1] : src3->i[1]; - dst->i[2] = src0->i[2] == src1->i[2] ? src2->i[2] : src3->i[2]; - dst->i[3] = src0->i[3] == src1->i[3] ? src2->i[3] : src3->i[3]; -} - -static void -micro_exp2( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src) -{ - dst->f[0] = powf( 2.0f, src->f[0] ); - dst->f[1] = powf( 2.0f, src->f[1] ); - dst->f[2] = powf( 2.0f, src->f[2] ); - dst->f[3] = powf( 2.0f, src->f[3] ); -} - -static void -micro_f2it( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->i[0] = (int) src->f[0]; - dst->i[1] = (int) src->f[1]; - dst->i[2] = (int) src->f[2]; - dst->i[3] = (int) src->f[3]; -} - -static void -micro_f2ut( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->u[0] = (uint) src->f[0]; - dst->u[1] = (uint) src->f[1]; - dst->u[2] = (uint) src->f[2]; - dst->u[3] = (uint) src->f[3]; -} - -static void -micro_flr( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = floorf( src->f[0] ); - dst->f[1] = floorf( src->f[1] ); - dst->f[2] = floorf( src->f[2] ); - dst->f[3] = floorf( src->f[3] ); -} - -static void -micro_frc( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = src->f[0] - floorf( src->f[0] ); - dst->f[1] = src->f[1] - floorf( src->f[1] ); - dst->f[2] = src->f[2] - floorf( src->f[2] ); - dst->f[3] = src->f[3] - floorf( src->f[3] ); -} - -static void -micro_ge( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->f[0] = src0->f[0] >= src1->f[0] ? src2->f[0] : src3->f[0]; - dst->f[1] = src0->f[1] >= src1->f[1] ? src2->f[1] : src3->f[1]; - dst->f[2] = src0->f[2] >= src1->f[2] ? src2->f[2] : src3->f[2]; - dst->f[3] = src0->f[3] >= src1->f[3] ? src2->f[3] : src3->f[3]; -} - -static void -micro_i2f( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) src->i[0]; - dst->f[1] = (float) src->i[1]; - dst->f[2] = (float) src->i[2]; - dst->f[3] = (float) src->i[3]; -} - -static void -micro_lg2( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = logf( src->f[0] ) * 1.442695f; - dst->f[1] = logf( src->f[1] ) * 1.442695f; - dst->f[2] = logf( src->f[2] ) * 1.442695f; - dst->f[3] = logf( src->f[3] ) * 1.442695f; -} - -static void -micro_le( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->f[0] = src0->f[0] <= src1->f[0] ? src2->f[0] : src3->f[0]; - dst->f[1] = src0->f[1] <= src1->f[1] ? src2->f[1] : src3->f[1]; - dst->f[2] = src0->f[2] <= src1->f[2] ? src2->f[2] : src3->f[2]; - dst->f[3] = src0->f[3] <= src1->f[3] ? src2->f[3] : src3->f[3]; -} - -static void -micro_lt( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->f[0] = src0->f[0] < src1->f[0] ? src2->f[0] : src3->f[0]; - dst->f[1] = src0->f[1] < src1->f[1] ? src2->f[1] : src3->f[1]; - dst->f[2] = src0->f[2] < src1->f[2] ? src2->f[2] : src3->f[2]; - dst->f[3] = src0->f[3] < src1->f[3] ? src2->f[3] : src3->f[3]; -} - -static void -micro_ilt( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->i[0] = src0->i[0] < src1->i[0] ? src2->i[0] : src3->i[0]; - dst->i[1] = src0->i[1] < src1->i[1] ? src2->i[1] : src3->i[1]; - dst->i[2] = src0->i[2] < src1->i[2] ? src2->i[2] : src3->i[2]; - dst->i[3] = src0->i[3] < src1->i[3] ? src2->i[3] : src3->i[3]; -} - -static void -micro_ult( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2, - const union tgsi_exec_channel *src3 ) -{ - dst->u[0] = src0->u[0] < src1->u[0] ? src2->u[0] : src3->u[0]; - dst->u[1] = src0->u[1] < src1->u[1] ? src2->u[1] : src3->u[1]; - dst->u[2] = src0->u[2] < src1->u[2] ? src2->u[2] : src3->u[2]; - dst->u[3] = src0->u[3] < src1->u[3] ? src2->u[3] : src3->u[3]; -} - -static void -micro_max( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] > src1->f[0] ? src0->f[0] : src1->f[0]; - dst->f[1] = src0->f[1] > src1->f[1] ? src0->f[1] : src1->f[1]; - dst->f[2] = src0->f[2] > src1->f[2] ? src0->f[2] : src1->f[2]; - dst->f[3] = src0->f[3] > src1->f[3] ? src0->f[3] : src1->f[3]; -} - -static void -micro_imax( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] > src1->i[0] ? src0->i[0] : src1->i[0]; - dst->i[1] = src0->i[1] > src1->i[1] ? src0->i[1] : src1->i[1]; - dst->i[2] = src0->i[2] > src1->i[2] ? src0->i[2] : src1->i[2]; - dst->i[3] = src0->i[3] > src1->i[3] ? src0->i[3] : src1->i[3]; -} - -static void -micro_umax( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] > src1->u[0] ? src0->u[0] : src1->u[0]; - dst->u[1] = src0->u[1] > src1->u[1] ? src0->u[1] : src1->u[1]; - dst->u[2] = src0->u[2] > src1->u[2] ? src0->u[2] : src1->u[2]; - dst->u[3] = src0->u[3] > src1->u[3] ? src0->u[3] : src1->u[3]; -} - -static void -micro_min( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] < src1->f[0] ? src0->f[0] : src1->f[0]; - dst->f[1] = src0->f[1] < src1->f[1] ? src0->f[1] : src1->f[1]; - dst->f[2] = src0->f[2] < src1->f[2] ? src0->f[2] : src1->f[2]; - dst->f[3] = src0->f[3] < src1->f[3] ? src0->f[3] : src1->f[3]; -} - -static void -micro_imin( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] < src1->i[0] ? src0->i[0] : src1->i[0]; - dst->i[1] = src0->i[1] < src1->i[1] ? src0->i[1] : src1->i[1]; - dst->i[2] = src0->i[2] < src1->i[2] ? src0->i[2] : src1->i[2]; - dst->i[3] = src0->i[3] < src1->i[3] ? src0->i[3] : src1->i[3]; -} - -static void -micro_umin( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] < src1->u[0] ? src0->u[0] : src1->u[0]; - dst->u[1] = src0->u[1] < src1->u[1] ? src0->u[1] : src1->u[1]; - dst->u[2] = src0->u[2] < src1->u[2] ? src0->u[2] : src1->u[2]; - dst->u[3] = src0->u[3] < src1->u[3] ? src0->u[3] : src1->u[3]; -} - -static void -micro_umod( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] % src1->u[0]; - dst->u[1] = src0->u[1] % src1->u[1]; - dst->u[2] = src0->u[2] % src1->u[2]; - dst->u[3] = src0->u[3] % src1->u[3]; -} - -static void -micro_mul( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] * src1->f[0]; - dst->f[1] = src0->f[1] * src1->f[1]; - dst->f[2] = src0->f[2] * src1->f[2]; - dst->f[3] = src0->f[3] * src1->f[3]; -} - -static void -micro_imul( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] * src1->i[0]; - dst->i[1] = src0->i[1] * src1->i[1]; - dst->i[2] = src0->i[2] * src1->i[2]; - dst->i[3] = src0->i[3] * src1->i[3]; -} - -static void -micro_imul64( - union tgsi_exec_channel *dst0, - union tgsi_exec_channel *dst1, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst1->i[0] = src0->i[0] * src1->i[0]; - dst1->i[1] = src0->i[1] * src1->i[1]; - dst1->i[2] = src0->i[2] * src1->i[2]; - dst1->i[3] = src0->i[3] * src1->i[3]; - dst0->i[0] = 0; - dst0->i[1] = 0; - dst0->i[2] = 0; - dst0->i[3] = 0; -} - -static void -micro_umul64( - union tgsi_exec_channel *dst0, - union tgsi_exec_channel *dst1, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst1->u[0] = src0->u[0] * src1->u[0]; - dst1->u[1] = src0->u[1] * src1->u[1]; - dst1->u[2] = src0->u[2] * src1->u[2]; - dst1->u[3] = src0->u[3] * src1->u[3]; - dst0->u[0] = 0; - dst0->u[1] = 0; - dst0->u[2] = 0; - dst0->u[3] = 0; -} - -static void -micro_movc( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2 ) -{ - dst->u[0] = src0->u[0] ? src1->u[0] : src2->u[0]; - dst->u[1] = src0->u[1] ? src1->u[1] : src2->u[1]; - dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2]; - dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3]; -} - -static void -micro_neg( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = -src->f[0]; - dst->f[1] = -src->f[1]; - dst->f[2] = -src->f[2]; - dst->f[3] = -src->f[3]; -} - -static void -micro_ineg( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->i[0] = -src->i[0]; - dst->i[1] = -src->i[1]; - dst->i[2] = -src->i[2]; - dst->i[3] = -src->i[3]; -} - -static void -micro_not( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->u[0] = ~src->u[0]; - dst->u[1] = ~src->u[1]; - dst->u[2] = ~src->u[2]; - dst->u[3] = ~src->u[3]; -} - -static void -micro_or( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] | src1->u[0]; - dst->u[1] = src0->u[1] | src1->u[1]; - dst->u[2] = src0->u[2] | src1->u[2]; - dst->u[3] = src0->u[3] | src1->u[3]; -} - -static void -micro_pow( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = powf( src0->f[0], src1->f[0] ); - dst->f[1] = powf( src0->f[1], src1->f[1] ); - dst->f[2] = powf( src0->f[2], src1->f[2] ); - dst->f[3] = powf( src0->f[3], src1->f[3] ); -} - -static void -micro_rnd( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = floorf( src->f[0] + 0.5f ); - dst->f[1] = floorf( src->f[1] + 0.5f ); - dst->f[2] = floorf( src->f[2] + 0.5f ); - dst->f[3] = floorf( src->f[3] + 0.5f ); -} - -static void -micro_shl( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] << src1->i[0]; - dst->i[1] = src0->i[1] << src1->i[1]; - dst->i[2] = src0->i[2] << src1->i[2]; - dst->i[3] = src0->i[3] << src1->i[3]; -} - -static void -micro_ishr( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->i[0] = src0->i[0] >> src1->i[0]; - dst->i[1] = src0->i[1] >> src1->i[1]; - dst->i[2] = src0->i[2] >> src1->i[2]; - dst->i[3] = src0->i[3] >> src1->i[3]; -} - -static void -micro_trunc( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0 ) -{ - dst->f[0] = (float) (int) src0->f[0]; - dst->f[1] = (float) (int) src0->f[1]; - dst->f[2] = (float) (int) src0->f[2]; - dst->f[3] = (float) (int) src0->f[3]; -} - -static void -micro_ushr( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] >> src1->u[0]; - dst->u[1] = src0->u[1] >> src1->u[1]; - dst->u[2] = src0->u[2] >> src1->u[2]; - dst->u[3] = src0->u[3] >> src1->u[3]; -} - -static void -micro_sin( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = sinf( src->f[0] ); - dst->f[1] = sinf( src->f[1] ); - dst->f[2] = sinf( src->f[2] ); - dst->f[3] = sinf( src->f[3] ); -} - -static void -micro_sqrt( union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = sqrtf( src->f[0] ); - dst->f[1] = sqrtf( src->f[1] ); - dst->f[2] = sqrtf( src->f[2] ); - dst->f[3] = sqrtf( src->f[3] ); -} - -static void -micro_sub( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->f[0] = src0->f[0] - src1->f[0]; - dst->f[1] = src0->f[1] - src1->f[1]; - dst->f[2] = src0->f[2] - src1->f[2]; - dst->f[3] = src0->f[3] - src1->f[3]; -} - -static void -micro_u2f( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src ) -{ - dst->f[0] = (float) src->u[0]; - dst->f[1] = (float) src->u[1]; - dst->f[2] = (float) src->u[2]; - dst->f[3] = (float) src->u[3]; -} - -static void -micro_xor( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst->u[0] = src0->u[0] ^ src1->u[0]; - dst->u[1] = src0->u[1] ^ src1->u[1]; - dst->u[2] = src0->u[2] ^ src1->u[2]; - dst->u[3] = src0->u[3] ^ src1->u[3]; -} - -static void -fetch_src_file_channel( - const struct tgsi_exec_machine *mach, - const uint file, - const uint swizzle, - const union tgsi_exec_channel *index, - union tgsi_exec_channel *chan ) -{ - switch( swizzle ) { - case TGSI_EXTSWIZZLE_X: - case TGSI_EXTSWIZZLE_Y: - case TGSI_EXTSWIZZLE_Z: - case TGSI_EXTSWIZZLE_W: - switch( file ) { - case TGSI_FILE_CONSTANT: - chan->f[0] = mach->Consts[index->i[0]][swizzle]; - chan->f[1] = mach->Consts[index->i[1]][swizzle]; - chan->f[2] = mach->Consts[index->i[2]][swizzle]; - chan->f[3] = mach->Consts[index->i[3]][swizzle]; - break; - - case TGSI_FILE_INPUT: - chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Inputs[index->i[3]].xyzw[swizzle].u[3]; - break; - - case TGSI_FILE_TEMPORARY: - assert(index->i[0] < TGSI_EXEC_NUM_TEMPS); - chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Temps[index->i[3]].xyzw[swizzle].u[3]; - break; - - case TGSI_FILE_IMMEDIATE: - assert( index->i[0] < (int) mach->ImmLimit ); - chan->f[0] = mach->Imms[index->i[0]][swizzle]; - assert( index->i[1] < (int) mach->ImmLimit ); - chan->f[1] = mach->Imms[index->i[1]][swizzle]; - assert( index->i[2] < (int) mach->ImmLimit ); - chan->f[2] = mach->Imms[index->i[2]][swizzle]; - assert( index->i[3] < (int) mach->ImmLimit ); - chan->f[3] = mach->Imms[index->i[3]][swizzle]; - break; - - case TGSI_FILE_ADDRESS: - chan->u[0] = mach->Addrs[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Addrs[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Addrs[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Addrs[index->i[3]].xyzw[swizzle].u[3]; - break; - - case TGSI_FILE_OUTPUT: - /* vertex/fragment output vars can be read too */ - chan->u[0] = mach->Outputs[index->i[0]].xyzw[swizzle].u[0]; - chan->u[1] = mach->Outputs[index->i[1]].xyzw[swizzle].u[1]; - chan->u[2] = mach->Outputs[index->i[2]].xyzw[swizzle].u[2]; - chan->u[3] = mach->Outputs[index->i[3]].xyzw[swizzle].u[3]; - break; - - default: - assert( 0 ); - } - break; - - case TGSI_EXTSWIZZLE_ZERO: - *chan = mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]; - break; - - case TGSI_EXTSWIZZLE_ONE: - *chan = mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]; - break; - - default: - assert( 0 ); - } -} - -static void -fetch_source( - const struct tgsi_exec_machine *mach, - union tgsi_exec_channel *chan, - const struct tgsi_full_src_register *reg, - const uint chan_index ) -{ - union tgsi_exec_channel index; - uint swizzle; - - index.i[0] = - index.i[1] = - index.i[2] = - index.i[3] = reg->SrcRegister.Index; - - if (reg->SrcRegister.Indirect) { - union tgsi_exec_channel index2; - union tgsi_exec_channel indir_index; - - index2.i[0] = - index2.i[1] = - index2.i[2] = - index2.i[3] = reg->SrcRegisterInd.Index; - - swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterInd, CHAN_X ); - fetch_src_file_channel( - mach, - reg->SrcRegisterInd.File, - swizzle, - &index2, - &indir_index ); - - index.i[0] += indir_index.i[0]; - index.i[1] += indir_index.i[1]; - index.i[2] += indir_index.i[2]; - index.i[3] += indir_index.i[3]; - } - - if( reg->SrcRegister.Dimension ) { - switch( reg->SrcRegister.File ) { - case TGSI_FILE_INPUT: - index.i[0] *= 17; - index.i[1] *= 17; - index.i[2] *= 17; - index.i[3] *= 17; - break; - case TGSI_FILE_CONSTANT: - index.i[0] *= 4096; - index.i[1] *= 4096; - index.i[2] *= 4096; - index.i[3] *= 4096; - break; - default: - assert( 0 ); - } - - index.i[0] += reg->SrcRegisterDim.Index; - index.i[1] += reg->SrcRegisterDim.Index; - index.i[2] += reg->SrcRegisterDim.Index; - index.i[3] += reg->SrcRegisterDim.Index; - - if (reg->SrcRegisterDim.Indirect) { - union tgsi_exec_channel index2; - union tgsi_exec_channel indir_index; - - index2.i[0] = - index2.i[1] = - index2.i[2] = - index2.i[3] = reg->SrcRegisterDimInd.Index; - - swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterDimInd, CHAN_X ); - fetch_src_file_channel( - mach, - reg->SrcRegisterDimInd.File, - swizzle, - &index2, - &indir_index ); - - index.i[0] += indir_index.i[0]; - index.i[1] += indir_index.i[1]; - index.i[2] += indir_index.i[2]; - index.i[3] += indir_index.i[3]; - } - } - - swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); - fetch_src_file_channel( - mach, - reg->SrcRegister.File, - swizzle, - &index, - chan ); - - switch (tgsi_util_get_full_src_register_sign_mode( reg, chan_index )) { - case TGSI_UTIL_SIGN_CLEAR: - micro_abs( chan, chan ); - break; - - case TGSI_UTIL_SIGN_SET: - micro_abs( chan, chan ); - micro_neg( chan, chan ); - break; - - case TGSI_UTIL_SIGN_TOGGLE: - micro_neg( chan, chan ); - break; - - case TGSI_UTIL_SIGN_KEEP: - break; - } - - if (reg->SrcRegisterExtMod.Complement) { - micro_sub( chan, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], chan ); - } -} - -static void -store_dest( - struct tgsi_exec_machine *mach, - const union tgsi_exec_channel *chan, - const struct tgsi_full_dst_register *reg, - const struct tgsi_full_instruction *inst, - uint chan_index ) -{ - union tgsi_exec_channel *dst; - - switch( reg->DstRegister.File ) { - case TGSI_FILE_NULL: - return; - - case TGSI_FILE_OUTPUT: - dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] - + reg->DstRegister.Index].xyzw[chan_index]; - break; - - case TGSI_FILE_TEMPORARY: - assert(reg->DstRegister.Index < TGSI_EXEC_NUM_TEMPS); - dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index]; - break; - - case TGSI_FILE_ADDRESS: - dst = &mach->Addrs[reg->DstRegister.Index].xyzw[chan_index]; - break; - - default: - assert( 0 ); - return; - } - - switch (inst->Instruction.Saturate) - { - case TGSI_SAT_NONE: - if (mach->ExecMask & 0x1) - dst->i[0] = chan->i[0]; - if (mach->ExecMask & 0x2) - dst->i[1] = chan->i[1]; - if (mach->ExecMask & 0x4) - dst->i[2] = chan->i[2]; - if (mach->ExecMask & 0x8) - dst->i[3] = chan->i[3]; - break; - - case TGSI_SAT_ZERO_ONE: - /* XXX need to obey ExecMask here */ - micro_max(dst, chan, &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]); - micro_min(dst, dst, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]); - break; - - case TGSI_SAT_MINUS_PLUS_ONE: - assert( 0 ); - break; - - default: - assert( 0 ); - } -} - -#define FETCH(VAL,INDEX,CHAN)\ - fetch_source (mach, VAL, &inst->FullSrcRegisters[INDEX], CHAN) - -#define STORE(VAL,INDEX,CHAN)\ - store_dest (mach, VAL, &inst->FullDstRegisters[INDEX], inst, CHAN ) - - -/** - * Execute ARB-style KIL which is predicated by a src register. - * Kill fragment if any of the four values is less than zero. - */ -static void -exec_kilp(struct tgsi_exec_machine *mach, - const struct tgsi_full_instruction *inst) -{ - uint uniquemask; - uint chan_index; - uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ - union tgsi_exec_channel r[1]; - - /* This mask stores component bits that were already tested. Note that - * we test if the value is less than zero, so 1.0 and 0.0 need not to be - * tested. */ - uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); - - for (chan_index = 0; chan_index < 4; chan_index++) - { - uint swizzle; - uint i; - - /* unswizzle channel */ - swizzle = tgsi_util_get_full_src_register_extswizzle ( - &inst->FullSrcRegisters[0], - chan_index); - - /* check if the component has not been already tested */ - if (uniquemask & (1 << swizzle)) - continue; - uniquemask |= 1 << swizzle; - - FETCH(&r[0], 0, chan_index); - for (i = 0; i < 4; i++) - if (r[0].f[i] < 0.0f) - kilmask |= 1 << i; - } - - mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; -} - - -/* - * Fetch a texel using STR texture coordinates. - */ -static void -fetch_texel( struct tgsi_sampler *sampler, - const union tgsi_exec_channel *s, - const union tgsi_exec_channel *t, - const union tgsi_exec_channel *p, - float lodbias, /* XXX should be float[4] */ - union tgsi_exec_channel *r, - union tgsi_exec_channel *g, - union tgsi_exec_channel *b, - union tgsi_exec_channel *a ) -{ - uint j; - float rgba[NUM_CHANNELS][QUAD_SIZE]; - - sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, rgba); - - for (j = 0; j < 4; j++) { - r->f[j] = rgba[0][j]; - g->f[j] = rgba[1][j]; - b->f[j] = rgba[2][j]; - a->f[j] = rgba[3][j]; - } -} - - -static void -exec_tex(struct tgsi_exec_machine *mach, - const struct tgsi_full_instruction *inst, - boolean biasLod, - boolean projected) -{ - const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; - union tgsi_exec_channel r[8]; - uint chan_index; - float lodBias; - - /* debug_printf("Sampler %u unit %u\n", sampler, unit); */ - - switch (inst->InstructionExtTexture.Texture) { - case TGSI_TEXTURE_1D: - - FETCH(&r[0], 0, CHAN_X); - - if (projected) { - FETCH(&r[1], 0, CHAN_W); - micro_div( &r[0], &r[0], &r[1] ); - } - - if (biasLod) { - FETCH(&r[1], 0, CHAN_W); - lodBias = r[2].f[0]; - } - else - lodBias = 0.0; - - fetch_texel(&mach->Samplers[unit], - &r[0], NULL, NULL, lodBias, /* S, T, P, BIAS */ - &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */ - break; - - case TGSI_TEXTURE_2D: - case TGSI_TEXTURE_RECT: - - FETCH(&r[0], 0, CHAN_X); - FETCH(&r[1], 0, CHAN_Y); - FETCH(&r[2], 0, CHAN_Z); - - if (projected) { - FETCH(&r[3], 0, CHAN_W); - micro_div( &r[0], &r[0], &r[3] ); - micro_div( &r[1], &r[1], &r[3] ); - micro_div( &r[2], &r[2], &r[3] ); - } - - if (biasLod) { - FETCH(&r[3], 0, CHAN_W); - lodBias = r[3].f[0]; - } - else - lodBias = 0.0; - - fetch_texel(&mach->Samplers[unit], - &r[0], &r[1], &r[2], lodBias, /* inputs */ - &r[0], &r[1], &r[2], &r[3]); /* outputs */ - break; - - case TGSI_TEXTURE_3D: - case TGSI_TEXTURE_CUBE: - - FETCH(&r[0], 0, CHAN_X); - FETCH(&r[1], 0, CHAN_Y); - FETCH(&r[2], 0, CHAN_Z); - - if (projected) { - FETCH(&r[3], 0, CHAN_W); - micro_div( &r[0], &r[0], &r[3] ); - micro_div( &r[1], &r[1], &r[3] ); - micro_div( &r[2], &r[2], &r[3] ); - } - - if (biasLod) { - FETCH(&r[3], 0, CHAN_W); - lodBias = r[3].f[0]; - } - else - lodBias = 0.0; - - fetch_texel(&mach->Samplers[unit], - &r[0], &r[1], &r[2], lodBias, - &r[0], &r[1], &r[2], &r[3]); - break; - - default: - assert (0); - } - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[chan_index], 0, chan_index ); - } -} - - -/** - * Evaluate a constant-valued coefficient at the position of the - * current quad. - */ -static void -eval_constant_coef( - struct tgsi_exec_machine *mach, - unsigned attrib, - unsigned chan ) -{ - unsigned i; - - for( i = 0; i < QUAD_SIZE; i++ ) { - mach->Inputs[attrib].xyzw[chan].f[i] = mach->InterpCoefs[attrib].a0[chan]; - } -} - -/** - * Evaluate a linear-valued coefficient at the position of the - * current quad. - */ -static void -eval_linear_coef( - struct tgsi_exec_machine *mach, - unsigned attrib, - unsigned chan ) -{ - const float x = mach->QuadPos.xyzw[0].f[0]; - const float y = mach->QuadPos.xyzw[1].f[0]; - const float dadx = mach->InterpCoefs[attrib].dadx[chan]; - const float dady = mach->InterpCoefs[attrib].dady[chan]; - const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; - mach->Inputs[attrib].xyzw[chan].f[0] = a0; - mach->Inputs[attrib].xyzw[chan].f[1] = a0 + dadx; - mach->Inputs[attrib].xyzw[chan].f[2] = a0 + dady; - mach->Inputs[attrib].xyzw[chan].f[3] = a0 + dadx + dady; -} - -/** - * Evaluate a perspective-valued coefficient at the position of the - * current quad. - */ -static void -eval_perspective_coef( - struct tgsi_exec_machine *mach, - unsigned attrib, - unsigned chan ) -{ - const float x = mach->QuadPos.xyzw[0].f[0]; - const float y = mach->QuadPos.xyzw[1].f[0]; - const float dadx = mach->InterpCoefs[attrib].dadx[chan]; - const float dady = mach->InterpCoefs[attrib].dady[chan]; - const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; - const float *w = mach->QuadPos.xyzw[3].f; - /* divide by W here */ - mach->Inputs[attrib].xyzw[chan].f[0] = a0 / w[0]; - mach->Inputs[attrib].xyzw[chan].f[1] = (a0 + dadx) / w[1]; - mach->Inputs[attrib].xyzw[chan].f[2] = (a0 + dady) / w[2]; - mach->Inputs[attrib].xyzw[chan].f[3] = (a0 + dadx + dady) / w[3]; -} - - -typedef void (* eval_coef_func)( - struct tgsi_exec_machine *mach, - unsigned attrib, - unsigned chan ); - -static void -exec_declaration( - struct tgsi_exec_machine *mach, - const struct tgsi_full_declaration *decl ) -{ - if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { - if( decl->Declaration.File == TGSI_FILE_INPUT ) { - unsigned first, last, mask; - eval_coef_func eval; - - first = decl->DeclarationRange.First; - last = decl->DeclarationRange.Last; - mask = decl->Declaration.UsageMask; - - switch( decl->Declaration.Interpolate ) { - case TGSI_INTERPOLATE_CONSTANT: - eval = eval_constant_coef; - break; - - case TGSI_INTERPOLATE_LINEAR: - eval = eval_linear_coef; - break; - - case TGSI_INTERPOLATE_PERSPECTIVE: - eval = eval_perspective_coef; - break; - - default: - assert( 0 ); - } - - if( mask == TGSI_WRITEMASK_XYZW ) { - unsigned i, j; - - for( i = first; i <= last; i++ ) { - for( j = 0; j < NUM_CHANNELS; j++ ) { - eval( mach, i, j ); - } - } - } - else { - unsigned i, j; - - for( j = 0; j < NUM_CHANNELS; j++ ) { - if( mask & (1 << j) ) { - for( i = first; i <= last; i++ ) { - eval( mach, i, j ); - } - } - } - } - } - } -} - -static void -exec_instruction( - struct tgsi_exec_machine *mach, - const struct tgsi_full_instruction *inst, - int *pc ) -{ - uint chan_index; - union tgsi_exec_channel r[8]; - - (*pc)++; - - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_ARL: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_f2it( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_MOV: - case TGSI_OPCODE_SWZ: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_LIT: - if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y ) || IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - FETCH( &r[0], 0, CHAN_X ); - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - micro_max( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - STORE( &r[0], 0, CHAN_Y ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - FETCH( &r[1], 0, CHAN_Y ); - micro_max( &r[1], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - - FETCH( &r[2], 0, CHAN_W ); - micro_min( &r[2], &r[2], &mach->Temps[TEMP_128_I].xyzw[TEMP_128_C] ); - micro_max( &r[2], &r[2], &mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C] ); - micro_pow( &r[1], &r[1], &r[2] ); - micro_lt( &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - STORE( &r[0], 0, CHAN_Z ); - } - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_RCP: - /* TGSI_OPCODE_RECIP */ - FETCH( &r[0], 0, CHAN_X ); - micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_RSQ: - /* TGSI_OPCODE_RECIPSQRT */ - FETCH( &r[0], 0, CHAN_X ); - micro_sqrt( &r[0], &r[0] ); - micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_EXP: - FETCH( &r[0], 0, CHAN_X ); - micro_flr( &r[1], &r[0] ); /* r1 = floor(r0) */ - if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - micro_exp2( &r[2], &r[1] ); /* r2 = 2 ^ r1 */ - STORE( &r[2], 0, CHAN_X ); /* store r2 */ - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - micro_sub( &r[2], &r[0], &r[1] ); /* r2 = r0 - r1 */ - STORE( &r[2], 0, CHAN_Y ); /* store r2 */ - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - micro_exp2( &r[2], &r[0] ); /* r2 = 2 ^ r0 */ - STORE( &r[2], 0, CHAN_Z ); /* store r2 */ - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_LOG: - FETCH( &r[0], 0, CHAN_X ); - micro_abs( &r[2], &r[0] ); /* r2 = abs(r0) */ - micro_lg2( &r[1], &r[2] ); /* r1 = lg2(r2) */ - micro_flr( &r[0], &r[1] ); /* r0 = floor(r1) */ - if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - STORE( &r[0], 0, CHAN_X ); - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - micro_exp2( &r[0], &r[0] ); /* r0 = 2 ^ r0 */ - micro_div( &r[0], &r[2], &r[0] ); /* r0 = r2 / r0 */ - STORE( &r[0], 0, CHAN_Y ); - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - STORE( &r[1], 0, CHAN_Z ); - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_MUL: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) - { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - - micro_mul( &r[0], &r[0], &r[1] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_ADD: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_add( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_DP3: - /* TGSI_OPCODE_DOT3 */ - FETCH( &r[0], 0, CHAN_X ); - FETCH( &r[1], 1, CHAN_X ); - micro_mul( &r[0], &r[0], &r[1] ); - - FETCH( &r[1], 0, CHAN_Y ); - FETCH( &r[2], 1, CHAN_Y ); - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FETCH( &r[1], 0, CHAN_Z ); - FETCH( &r[2], 1, CHAN_Z ); - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_DP4: - /* TGSI_OPCODE_DOT4 */ - FETCH(&r[0], 0, CHAN_X); - FETCH(&r[1], 1, CHAN_X); - - micro_mul( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 0, CHAN_Y); - FETCH(&r[2], 1, CHAN_Y); - - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 0, CHAN_Z); - FETCH(&r[2], 1, CHAN_Z); - - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 0, CHAN_W); - FETCH(&r[2], 1, CHAN_W); - - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_DST: - if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - FETCH( &r[0], 0, CHAN_Y ); - FETCH( &r[1], 1, CHAN_Y); - micro_mul( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, CHAN_Y ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - FETCH( &r[0], 0, CHAN_Z ); - STORE( &r[0], 0, CHAN_Z ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - FETCH( &r[0], 1, CHAN_W ); - STORE( &r[0], 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_MIN: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - - /* XXX use micro_min()?? */ - micro_lt( &r[0], &r[0], &r[1], &r[0], &r[1] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_MAX: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - - /* XXX use micro_max()?? */ - micro_lt( &r[0], &r[0], &r[1], &r[1], &r[0] ); - - STORE(&r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SLT: - /* TGSI_OPCODE_SETLT */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SGE: - /* TGSI_OPCODE_SETGE */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_ge( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_MAD: - /* TGSI_OPCODE_MADD */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_mul( &r[0], &r[0], &r[1] ); - FETCH( &r[1], 2, chan_index ); - micro_add( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SUB: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - - micro_sub( &r[0], &r[0], &r[1] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_LERP: - /* TGSI_OPCODE_LRP */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - FETCH(&r[2], 2, chan_index); - - micro_sub( &r[1], &r[1], &r[2] ); - micro_mul( &r[0], &r[0], &r[1] ); - micro_add( &r[0], &r[0], &r[2] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_CND: - assert (0); - break; - - case TGSI_OPCODE_CND0: - assert (0); - break; - - case TGSI_OPCODE_DOT2ADD: - /* TGSI_OPCODE_DP2A */ - assert (0); - break; - - case TGSI_OPCODE_INDEX: - assert (0); - break; - - case TGSI_OPCODE_NEGATE: - assert (0); - break; - - case TGSI_OPCODE_FRAC: - /* TGSI_OPCODE_FRC */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_frc( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_CLAMP: - assert (0); - break; - - case TGSI_OPCODE_FLOOR: - /* TGSI_OPCODE_FLR */ - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_flr( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_ROUND: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_rnd( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_EXPBASE2: - /* TGSI_OPCODE_EX2 */ - FETCH(&r[0], 0, CHAN_X); - - micro_pow( &r[0], &mach->Temps[TEMP_2_I].xyzw[TEMP_2_C], &r[0] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_LOGBASE2: - /* TGSI_OPCODE_LG2 */ - FETCH( &r[0], 0, CHAN_X ); - micro_lg2( &r[0], &r[0] ); - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_POWER: - /* TGSI_OPCODE_POW */ - FETCH(&r[0], 0, CHAN_X); - FETCH(&r[1], 1, CHAN_X); - - micro_pow( &r[0], &r[0], &r[1] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_CROSSPRODUCT: - /* TGSI_OPCODE_XPD */ - FETCH(&r[0], 0, CHAN_Y); - FETCH(&r[1], 1, CHAN_Z); - - micro_mul( &r[2], &r[0], &r[1] ); - - FETCH(&r[3], 0, CHAN_Z); - FETCH(&r[4], 1, CHAN_Y); - - micro_mul( &r[5], &r[3], &r[4] ); - micro_sub( &r[2], &r[2], &r[5] ); - - if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - STORE( &r[2], 0, CHAN_X ); - } - - FETCH(&r[2], 1, CHAN_X); - - micro_mul( &r[3], &r[3], &r[2] ); - - FETCH(&r[5], 0, CHAN_X); - - micro_mul( &r[1], &r[1], &r[5] ); - micro_sub( &r[3], &r[3], &r[1] ); - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - STORE( &r[3], 0, CHAN_Y ); - } - - micro_mul( &r[5], &r[5], &r[4] ); - micro_mul( &r[0], &r[0], &r[2] ); - micro_sub( &r[5], &r[5], &r[0] ); - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - STORE( &r[5], 0, CHAN_Z ); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_MULTIPLYMATRIX: - assert (0); - break; - - case TGSI_OPCODE_ABS: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - - micro_abs( &r[0], &r[0] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_RCC: - assert (0); - break; - - case TGSI_OPCODE_DPH: - FETCH(&r[0], 0, CHAN_X); - FETCH(&r[1], 1, CHAN_X); - - micro_mul( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 0, CHAN_Y); - FETCH(&r[2], 1, CHAN_Y); - - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 0, CHAN_Z); - FETCH(&r[2], 1, CHAN_Z); - - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FETCH(&r[1], 1, CHAN_W); - - micro_add( &r[0], &r[0], &r[1] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_COS: - FETCH(&r[0], 0, CHAN_X); - - micro_cos( &r[0], &r[0] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_DDX: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_ddx( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_DDY: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_ddy( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_KILP: - exec_kilp (mach, inst); - break; - - case TGSI_OPCODE_KIL: - /* for enabled ExecMask bits, set the killed bit */ - mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= mach->ExecMask; - break; - - case TGSI_OPCODE_PK2H: - assert (0); - break; - - case TGSI_OPCODE_PK2US: - assert (0); - break; - - case TGSI_OPCODE_PK4B: - assert (0); - break; - - case TGSI_OPCODE_PK4UB: - assert (0); - break; - - case TGSI_OPCODE_RFL: - assert (0); - break; - - case TGSI_OPCODE_SEQ: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_eq( &r[0], &r[0], &r[1], - &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], - &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SFL: - assert (0); - break; - - case TGSI_OPCODE_SGT: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_le( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SIN: - FETCH( &r[0], 0, CHAN_X ); - micro_sin( &r[0], &r[0] ); - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SLE: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_le( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SNE: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_eq( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_STR: - assert (0); - break; - - case TGSI_OPCODE_TEX: - /* simple texture lookup */ - /* src[0] = texcoord */ - /* src[1] = sampler unit */ - exec_tex(mach, inst, FALSE, FALSE); - break; - - case TGSI_OPCODE_TXB: - /* Texture lookup with lod bias */ - /* src[0] = texcoord (src[0].w = LOD bias) */ - /* src[1] = sampler unit */ - exec_tex(mach, inst, TRUE, FALSE); - break; - - case TGSI_OPCODE_TXD: - /* Texture lookup with explict partial derivatives */ - /* src[0] = texcoord */ - /* src[1] = d[strq]/dx */ - /* src[2] = d[strq]/dy */ - /* src[3] = sampler unit */ - assert (0); - break; - - case TGSI_OPCODE_TXL: - /* Texture lookup with explit LOD */ - /* src[0] = texcoord (src[0].w = LOD) */ - /* src[1] = sampler unit */ - exec_tex(mach, inst, TRUE, FALSE); - break; - - case TGSI_OPCODE_TXP: - /* Texture lookup with projection */ - /* src[0] = texcoord (src[0].w = projection) */ - /* src[1] = sampler unit */ - exec_tex(mach, inst, FALSE, TRUE); - break; - - case TGSI_OPCODE_UP2H: - assert (0); - break; - - case TGSI_OPCODE_UP2US: - assert (0); - break; - - case TGSI_OPCODE_UP4B: - assert (0); - break; - - case TGSI_OPCODE_UP4UB: - assert (0); - break; - - case TGSI_OPCODE_X2D: - assert (0); - break; - - case TGSI_OPCODE_ARA: - assert (0); - break; - - case TGSI_OPCODE_ARR: - assert (0); - break; - - case TGSI_OPCODE_BRA: - assert (0); - break; - - case TGSI_OPCODE_CAL: - /* skip the call if no execution channels are enabled */ - if (mach->ExecMask) { - /* do the call */ - - /* push the Cond, Loop, Cont stacks */ - assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); - mach->CondStack[mach->CondStackTop++] = mach->CondMask; - assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); - mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; - assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); - mach->ContStack[mach->ContStackTop++] = mach->ContMask; - - assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING); - mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask; - - /* note that PC was already incremented above */ - mach->CallStack[mach->CallStackTop++] = *pc; - *pc = inst->InstructionExtLabel.Label; - } - break; - - case TGSI_OPCODE_RET: - mach->FuncMask &= ~mach->ExecMask; - UPDATE_EXEC_MASK(mach); - - if (mach->ExecMask == 0x0) { - /* really return now (otherwise, keep executing */ - - if (mach->CallStackTop == 0) { - /* returning from main() */ - *pc = -1; - return; - } - *pc = mach->CallStack[--mach->CallStackTop]; - - /* pop the Cond, Loop, Cont stacks */ - assert(mach->CondStackTop > 0); - mach->CondMask = mach->CondStack[--mach->CondStackTop]; - assert(mach->LoopStackTop > 0); - mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; - assert(mach->ContStackTop > 0); - mach->ContMask = mach->ContStack[--mach->ContStackTop]; - assert(mach->FuncStackTop > 0); - mach->FuncMask = mach->FuncStack[--mach->FuncStackTop]; - - UPDATE_EXEC_MASK(mach); - } - break; - - case TGSI_OPCODE_SSG: - assert (0); - break; - - case TGSI_OPCODE_CMP: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH(&r[0], 0, chan_index); - FETCH(&r[1], 1, chan_index); - FETCH(&r[2], 2, chan_index); - - micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] ); - - STORE(&r[0], 0, chan_index); - } - break; - - case TGSI_OPCODE_SCS: - if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) || IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { - FETCH( &r[0], 0, CHAN_X ); - } - if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) ) { - micro_cos( &r[1], &r[0] ); - STORE( &r[1], 0, CHAN_X ); - } - if( IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { - micro_sin( &r[1], &r[0] ); - STORE( &r[1], 0, CHAN_Y ); - } - if( IS_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { - STORE( &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], 0, CHAN_Z ); - } - if( IS_CHANNEL_ENABLED( *inst, CHAN_W ) ) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_NRM: - assert (0); - break; - - case TGSI_OPCODE_DIV: - assert( 0 ); - break; - - case TGSI_OPCODE_DP2: - FETCH( &r[0], 0, CHAN_X ); - FETCH( &r[1], 1, CHAN_X ); - micro_mul( &r[0], &r[0], &r[1] ); - - FETCH( &r[1], 0, CHAN_Y ); - FETCH( &r[2], 1, CHAN_Y ); - micro_mul( &r[1], &r[1], &r[2] ); - micro_add( &r[0], &r[0], &r[1] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_IF: - /* push CondMask */ - assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); - mach->CondStack[mach->CondStackTop++] = mach->CondMask; - FETCH( &r[0], 0, CHAN_X ); - /* update CondMask */ - if( ! r[0].u[0] ) { - mach->CondMask &= ~0x1; - } - if( ! r[0].u[1] ) { - mach->CondMask &= ~0x2; - } - if( ! r[0].u[2] ) { - mach->CondMask &= ~0x4; - } - if( ! r[0].u[3] ) { - mach->CondMask &= ~0x8; - } - UPDATE_EXEC_MASK(mach); - /* Todo: If CondMask==0, jump to ELSE */ - break; - - case TGSI_OPCODE_ELSE: - /* invert CondMask wrt previous mask */ - { - uint prevMask; - assert(mach->CondStackTop > 0); - prevMask = mach->CondStack[mach->CondStackTop - 1]; - mach->CondMask = ~mach->CondMask & prevMask; - UPDATE_EXEC_MASK(mach); - /* Todo: If CondMask==0, jump to ENDIF */ - } - break; - - case TGSI_OPCODE_ENDIF: - /* pop CondMask */ - assert(mach->CondStackTop > 0); - mach->CondMask = mach->CondStack[--mach->CondStackTop]; - UPDATE_EXEC_MASK(mach); - break; - - case TGSI_OPCODE_END: - /* halt execution */ - *pc = -1; - break; - - case TGSI_OPCODE_REP: - assert (0); - break; - - case TGSI_OPCODE_ENDREP: - assert (0); - break; - - case TGSI_OPCODE_PUSHA: - assert (0); - break; - - case TGSI_OPCODE_POPA: - assert (0); - break; - - case TGSI_OPCODE_CEIL: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_ceil( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_I2F: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_i2f( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_NOT: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_not( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_TRUNC: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_trunc( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SHL: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_shl( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SHR: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_ishr( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_AND: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_and( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_OR: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_or( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_MOD: - assert (0); - break; - - case TGSI_OPCODE_XOR: - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - FETCH( &r[1], 1, chan_index ); - micro_xor( &r[0], &r[0], &r[1] ); - STORE( &r[0], 0, chan_index ); - } - break; - - case TGSI_OPCODE_SAD: - assert (0); - break; - - case TGSI_OPCODE_TXF: - assert (0); - break; - - case TGSI_OPCODE_TXQ: - assert (0); - break; - - case TGSI_OPCODE_EMIT: - mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16; - mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++; - break; - - case TGSI_OPCODE_ENDPRIM: - mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++; - mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0; - break; - - case TGSI_OPCODE_LOOP: - /* fall-through (for now) */ - case TGSI_OPCODE_BGNLOOP2: - /* push LoopMask and ContMasks */ - assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); - mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; - assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); - mach->ContStack[mach->ContStackTop++] = mach->ContMask; - break; - - case TGSI_OPCODE_ENDLOOP: - /* fall-through (for now at least) */ - case TGSI_OPCODE_ENDLOOP2: - /* Restore ContMask, but don't pop */ - assert(mach->ContStackTop > 0); - mach->ContMask = mach->ContStack[mach->ContStackTop - 1]; - UPDATE_EXEC_MASK(mach); - if (mach->ExecMask) { - /* repeat loop: jump to instruction just past BGNLOOP */ - *pc = inst->InstructionExtLabel.Label + 1; - } - else { - /* exit loop: pop LoopMask */ - assert(mach->LoopStackTop > 0); - mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; - /* pop ContMask */ - assert(mach->ContStackTop > 0); - mach->ContMask = mach->ContStack[--mach->ContStackTop]; - } - UPDATE_EXEC_MASK(mach); - break; - - case TGSI_OPCODE_BRK: - /* turn off loop channels for each enabled exec channel */ - mach->LoopMask &= ~mach->ExecMask; - /* Todo: if mach->LoopMask == 0, jump to end of loop */ - UPDATE_EXEC_MASK(mach); - break; - - case TGSI_OPCODE_CONT: - /* turn off cont channels for each enabled exec channel */ - mach->ContMask &= ~mach->ExecMask; - /* Todo: if mach->LoopMask == 0, jump to end of loop */ - UPDATE_EXEC_MASK(mach); - break; - - case TGSI_OPCODE_BGNSUB: - /* no-op */ - break; - - case TGSI_OPCODE_ENDSUB: - /* no-op */ - break; - - case TGSI_OPCODE_NOISE1: - assert( 0 ); - break; - - case TGSI_OPCODE_NOISE2: - assert( 0 ); - break; - - case TGSI_OPCODE_NOISE3: - assert( 0 ); - break; - - case TGSI_OPCODE_NOISE4: - assert( 0 ); - break; - - case TGSI_OPCODE_NOP: - break; - - default: - assert( 0 ); - } -} - - -/** - * Run TGSI interpreter. - * \return bitmask of "alive" quad components - */ -uint -tgsi_exec_machine_run( struct tgsi_exec_machine *mach ) -{ - uint i; - int pc = 0; - - mach->CondMask = 0xf; - mach->LoopMask = 0xf; - mach->ContMask = 0xf; - mach->FuncMask = 0xf; - mach->ExecMask = 0xf; - - mach->CondStackTop = 0; /* temporarily subvert this assertion */ - assert(mach->CondStackTop == 0); - assert(mach->LoopStackTop == 0); - assert(mach->ContStackTop == 0); - assert(mach->CallStackTop == 0); - - mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0; - mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0; - - if( mach->Processor == TGSI_PROCESSOR_GEOMETRY ) { - mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0] = 0; - mach->Primitives[0] = 0; - } - - - /* execute declarations (interpolants) */ - for (i = 0; i < mach->NumDeclarations; i++) { - exec_declaration( mach, mach->Declarations+i ); - } - - /* execute instructions, until pc is set to -1 */ - while (pc != -1) { - assert(pc < (int) mach->NumInstructions); - exec_instruction( mach, mach->Instructions + pc, &pc ); - } - -#if 0 - /* we scale from floats in [0,1] to Zbuffer ints in sp_quad_depth_test.c */ - if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) { - /* - * Scale back depth component. - */ - for (i = 0; i < 4; i++) - mach->Outputs[0].xyzw[2].f[i] *= ctx->DrawBuffer->_DepthMaxF; - } -#endif - - return ~mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0]; -} - - diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h deleted file mode 100644 index 4f30650b07..0000000000 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h +++ /dev/null @@ -1,253 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#if !defined TGSI_EXEC_H -#define TGSI_EXEC_H - -#include "pipe/p_compiler.h" - -#if defined __cplusplus -extern "C" { -#endif - -#define MAX_LABELS 1024 - -#define NUM_CHANNELS 4 /* R,G,B,A */ -#define QUAD_SIZE 4 /* 4 pixel/quad */ - -/** - * Registers may be treated as float, signed int or unsigned int. - */ -union tgsi_exec_channel -{ - float f[QUAD_SIZE]; - int i[QUAD_SIZE]; - unsigned u[QUAD_SIZE]; -}; - -/** - * A vector[RGBA] of channels[4 pixels] - */ -struct tgsi_exec_vector -{ - union tgsi_exec_channel xyzw[NUM_CHANNELS]; -}; - -/** - * For fragment programs, information for computing fragment input - * values from plane equation of the triangle/line. - */ -struct tgsi_interp_coef -{ - float a0[NUM_CHANNELS]; /* in an xyzw layout */ - float dadx[NUM_CHANNELS]; - float dady[NUM_CHANNELS]; -}; - - -struct softpipe_tile_cache; /**< Opaque to TGSI */ - -/** - * Information for sampling textures, which must be implemented - * by code outside the TGSI executor. - */ -struct tgsi_sampler -{ - const struct pipe_sampler_state *state; - struct pipe_texture *texture; - /** Get samples for four fragments in a quad */ - void (*get_samples)(struct tgsi_sampler *sampler, - const float s[QUAD_SIZE], - const float t[QUAD_SIZE], - const float p[QUAD_SIZE], - float lodbias, - float rgba[NUM_CHANNELS][QUAD_SIZE]); - void *pipe; /*XXX temporary*/ - struct softpipe_tile_cache *cache; -}; - -/** - * For branching/calling subroutines. - */ -struct tgsi_exec_labels -{ - unsigned labels[MAX_LABELS][2]; - unsigned count; -}; - - -#define TGSI_EXEC_NUM_TEMPS 128 -#define TGSI_EXEC_NUM_TEMP_EXTRAS 6 -#define TGSI_EXEC_NUM_IMMEDIATES 256 - -/* - * Locations of various utility registers (_I = Index, _C = Channel) - */ -#define TGSI_EXEC_TEMP_00000000_I (TGSI_EXEC_NUM_TEMPS + 0) -#define TGSI_EXEC_TEMP_00000000_C 0 - -#define TGSI_EXEC_TEMP_7FFFFFFF_I (TGSI_EXEC_NUM_TEMPS + 0) -#define TGSI_EXEC_TEMP_7FFFFFFF_C 1 - -#define TGSI_EXEC_TEMP_80000000_I (TGSI_EXEC_NUM_TEMPS + 0) -#define TGSI_EXEC_TEMP_80000000_C 2 - -#define TGSI_EXEC_TEMP_FFFFFFFF_I (TGSI_EXEC_NUM_TEMPS + 0) -#define TGSI_EXEC_TEMP_FFFFFFFF_C 3 - -#define TGSI_EXEC_TEMP_ONE_I (TGSI_EXEC_NUM_TEMPS + 1) -#define TGSI_EXEC_TEMP_ONE_C 0 - -#define TGSI_EXEC_TEMP_TWO_I (TGSI_EXEC_NUM_TEMPS + 1) -#define TGSI_EXEC_TEMP_TWO_C 1 - -#define TGSI_EXEC_TEMP_128_I (TGSI_EXEC_NUM_TEMPS + 1) -#define TGSI_EXEC_TEMP_128_C 2 - -#define TGSI_EXEC_TEMP_MINUS_128_I (TGSI_EXEC_NUM_TEMPS + 1) -#define TGSI_EXEC_TEMP_MINUS_128_C 3 - -#define TGSI_EXEC_TEMP_KILMASK_I (TGSI_EXEC_NUM_TEMPS + 2) -#define TGSI_EXEC_TEMP_KILMASK_C 0 - -#define TGSI_EXEC_TEMP_OUTPUT_I (TGSI_EXEC_NUM_TEMPS + 2) -#define TGSI_EXEC_TEMP_OUTPUT_C 1 - -#define TGSI_EXEC_TEMP_PRIMITIVE_I (TGSI_EXEC_NUM_TEMPS + 2) -#define TGSI_EXEC_TEMP_PRIMITIVE_C 2 - -#define TGSI_EXEC_TEMP_THREE_I (TGSI_EXEC_NUM_TEMPS + 2) -#define TGSI_EXEC_TEMP_THREE_C 3 - -#define TGSI_EXEC_TEMP_HALF_I (TGSI_EXEC_NUM_TEMPS + 3) -#define TGSI_EXEC_TEMP_HALF_C 0 - -#define TGSI_EXEC_TEMP_R0 (TGSI_EXEC_NUM_TEMPS + 4) - -#define TGSI_EXEC_TEMP_ADDR (TGSI_EXEC_NUM_TEMPS + 5) - - -#define TGSI_EXEC_MAX_COND_NESTING 20 -#define TGSI_EXEC_MAX_LOOP_NESTING 20 -#define TGSI_EXEC_MAX_CALL_NESTING 20 - -/** - * Run-time virtual machine state for executing TGSI shader. - */ -struct tgsi_exec_machine -{ - /* Total = program temporaries + internal temporaries - * + 1 padding to align to 16 bytes - */ - struct tgsi_exec_vector _Temps[TGSI_EXEC_NUM_TEMPS + - TGSI_EXEC_NUM_TEMP_EXTRAS + 1]; - - /* - * This will point to _Temps after aligning to 16B boundary. - */ - struct tgsi_exec_vector *Temps; - struct tgsi_exec_vector *Addrs; - - struct tgsi_sampler *Samplers; - - float Imms[TGSI_EXEC_NUM_IMMEDIATES][4]; - unsigned ImmLimit; - const float (*Consts)[4]; - struct tgsi_exec_vector *Inputs; - struct tgsi_exec_vector *Outputs; - const struct tgsi_token *Tokens; - unsigned Processor; - - /* GEOMETRY processor only. */ - unsigned *Primitives; - - /* FRAGMENT processor only. */ - const struct tgsi_interp_coef *InterpCoefs; - struct tgsi_exec_vector QuadPos; - - /* Conditional execution masks */ - uint CondMask; /**< For IF/ELSE/ENDIF */ - uint LoopMask; /**< For BGNLOOP/ENDLOOP */ - uint ContMask; /**< For loop CONT statements */ - uint FuncMask; /**< For function calls */ - uint ExecMask; /**< = CondMask & LoopMask */ - - /** Condition mask stack (for nested conditionals) */ - uint CondStack[TGSI_EXEC_MAX_COND_NESTING]; - int CondStackTop; - - /** Loop mask stack (for nested loops) */ - uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING]; - int LoopStackTop; - - /** Loop continue mask stack (see comments in tgsi_exec.c) */ - uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING]; - int ContStackTop; - - /** Function execution mask stack (for executing subroutine code) */ - uint FuncStack[TGSI_EXEC_MAX_CALL_NESTING]; - int FuncStackTop; - - /** Function call stack for saving/restoring the program counter */ - uint CallStack[TGSI_EXEC_MAX_CALL_NESTING]; - int CallStackTop; - - struct tgsi_full_instruction *Instructions; - uint NumInstructions; - - struct tgsi_full_declaration *Declarations; - uint NumDeclarations; - - struct tgsi_exec_labels Labels; -}; - -void -tgsi_exec_machine_init( - struct tgsi_exec_machine *mach ); - - -void -tgsi_exec_machine_bind_shader( - struct tgsi_exec_machine *mach, - const struct tgsi_token *tokens, - uint numSamplers, - struct tgsi_sampler *samplers); - -uint -tgsi_exec_machine_run( - struct tgsi_exec_machine *mach ); - - -void -tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach); - - -#if defined __cplusplus -} /* extern "C" */ -#endif - -#endif /* TGSI_EXEC_H */ diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c deleted file mode 100755 index cdbdf5c882..0000000000 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ /dev/null @@ -1,2275 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" -#include "tgsi_exec.h" -#include "tgsi_sse2.h" - -#include "rtasm/rtasm_x86sse.h" - -#ifdef PIPE_ARCH_X86 - -/* for 1/sqrt() - * - * This costs about 100fps (close to 10%) in gears: - */ -#define HIGH_PRECISION 1 - - -#define FOR_EACH_CHANNEL( CHAN )\ - for( CHAN = 0; CHAN < 4; CHAN++ ) - -#define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ - ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) - -#define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ - if( IS_DST0_CHANNEL_ENABLED( INST, CHAN )) - -#define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\ - FOR_EACH_CHANNEL( CHAN )\ - IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN ) - -#define CHAN_X 0 -#define CHAN_Y 1 -#define CHAN_Z 2 -#define CHAN_W 3 - -#define TEMP_R0 TGSI_EXEC_TEMP_R0 - -/** - * X86 utility functions. - */ - -static struct x86_reg -make_xmm( - unsigned xmm ) -{ - return x86_make_reg( - file_XMM, - (enum x86_reg_name) xmm ); -} - -/** - * X86 register mapping helpers. - */ - -static struct x86_reg -get_const_base( void ) -{ - return x86_make_reg( - file_REG32, - reg_CX ); -} - -static struct x86_reg -get_input_base( void ) -{ - return x86_make_reg( - file_REG32, - reg_AX ); -} - -static struct x86_reg -get_output_base( void ) -{ - return x86_make_reg( - file_REG32, - reg_DX ); -} - -static struct x86_reg -get_temp_base( void ) -{ - return x86_make_reg( - file_REG32, - reg_BX ); -} - -static struct x86_reg -get_coef_base( void ) -{ - return get_output_base(); -} - -static struct x86_reg -get_immediate_base( void ) -{ - return x86_make_reg( - file_REG32, - reg_DI ); -} - - -/** - * Data access helpers. - */ - - -static struct x86_reg -get_immediate( - unsigned vec, - unsigned chan ) -{ - return x86_make_disp( - get_immediate_base(), - (vec * 4 + chan) * 4 ); -} - -static struct x86_reg -get_const( - unsigned vec, - unsigned chan ) -{ - return x86_make_disp( - get_const_base(), - (vec * 4 + chan) * 4 ); -} - -static struct x86_reg -get_input( - unsigned vec, - unsigned chan ) -{ - return x86_make_disp( - get_input_base(), - (vec * 4 + chan) * 16 ); -} - -static struct x86_reg -get_output( - unsigned vec, - unsigned chan ) -{ - return x86_make_disp( - get_output_base(), - (vec * 4 + chan) * 16 ); -} - -static struct x86_reg -get_temp( - unsigned vec, - unsigned chan ) -{ - return x86_make_disp( - get_temp_base(), - (vec * 4 + chan) * 16 ); -} - -static struct x86_reg -get_coef( - unsigned vec, - unsigned chan, - unsigned member ) -{ - return x86_make_disp( - get_coef_base(), - ((vec * 3 + member) * 4 + chan) * 4 ); -} - - -static void -emit_ret( - struct x86_function *func ) -{ - x86_ret( func ); -} - - -/** - * Data fetch helpers. - */ - -/** - * Copy a shader constant to xmm register - * \param xmm the destination xmm register - * \param vec the src const buffer index - * \param chan src channel to fetch (X, Y, Z or W) - */ -static void -emit_const( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - sse_movss( - func, - make_xmm( xmm ), - get_const( vec, chan ) ); - sse_shufps( - func, - make_xmm( xmm ), - make_xmm( xmm ), - SHUF( 0, 0, 0, 0 ) ); -} - -static void -emit_immediate( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - sse_movss( - func, - make_xmm( xmm ), - get_immediate( vec, chan ) ); - sse_shufps( - func, - make_xmm( xmm ), - make_xmm( xmm ), - SHUF( 0, 0, 0, 0 ) ); -} - - -/** - * Copy a shader input to xmm register - * \param xmm the destination xmm register - * \param vec the src input attrib - * \param chan src channel to fetch (X, Y, Z or W) - */ -static void -emit_inputf( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - sse_movups( - func, - make_xmm( xmm ), - get_input( vec, chan ) ); -} - -/** - * Store an xmm register to a shader output - * \param xmm the source xmm register - * \param vec the dest output attrib - * \param chan src dest channel to store (X, Y, Z or W) - */ -static void -emit_output( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - sse_movups( - func, - get_output( vec, chan ), - make_xmm( xmm ) ); -} - -/** - * Copy a shader temporary to xmm register - * \param xmm the destination xmm register - * \param vec the src temp register - * \param chan src channel to fetch (X, Y, Z or W) - */ -static void -emit_tempf( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - sse_movaps( - func, - make_xmm( xmm ), - get_temp( vec, chan ) ); -} - -/** - * Load an xmm register with an input attrib coefficient (a0, dadx or dady) - * \param xmm the destination xmm register - * \param vec the src input/attribute coefficient index - * \param chan src channel to fetch (X, Y, Z or W) - * \param member 0=a0, 1=dadx, 2=dady - */ -static void -emit_coef( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan, - unsigned member ) -{ - sse_movss( - func, - make_xmm( xmm ), - get_coef( vec, chan, member ) ); - sse_shufps( - func, - make_xmm( xmm ), - make_xmm( xmm ), - SHUF( 0, 0, 0, 0 ) ); -} - -/** - * Data store helpers. - */ - -static void -emit_inputs( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - sse_movups( - func, - get_input( vec, chan ), - make_xmm( xmm ) ); -} - -static void -emit_temps( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - sse_movaps( - func, - get_temp( vec, chan ), - make_xmm( xmm ) ); -} - -static void -emit_addrs( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_temps( - func, - xmm, - vec + TGSI_EXEC_NUM_TEMPS, - chan ); -} - -/** - * Coefficent fetch helpers. - */ - -static void -emit_coef_a0( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_coef( - func, - xmm, - vec, - chan, - 0 ); -} - -static void -emit_coef_dadx( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_coef( - func, - xmm, - vec, - chan, - 1 ); -} - -static void -emit_coef_dady( - struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - emit_coef( - func, - xmm, - vec, - chan, - 2 ); -} - -/** - * Function call helpers. - */ - -static void -emit_push_gp( - struct x86_function *func ) -{ - x86_push( - func, - x86_make_reg( file_REG32, reg_AX) ); - x86_push( - func, - x86_make_reg( file_REG32, reg_CX) ); - x86_push( - func, - x86_make_reg( file_REG32, reg_DX) ); -} - -static void -x86_pop_gp( - struct x86_function *func ) -{ - /* Restore GP registers in a reverse order. - */ - x86_pop( - func, - x86_make_reg( file_REG32, reg_DX) ); - x86_pop( - func, - x86_make_reg( file_REG32, reg_CX) ); - x86_pop( - func, - x86_make_reg( file_REG32, reg_AX) ); -} - -static void -emit_func_call_dst( - struct x86_function *func, - unsigned xmm_dst, - void (PIPE_CDECL *code)() ) -{ - sse_movaps( - func, - get_temp( TEMP_R0, 0 ), - make_xmm( xmm_dst ) ); - - emit_push_gp( - func ); - - { - struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); - - x86_lea( - func, - ecx, - get_temp( TEMP_R0, 0 ) ); - - x86_push( func, ecx ); - x86_mov_reg_imm( func, ecx, (unsigned long) code ); - x86_call( func, ecx ); - x86_pop(func, ecx ); - } - - - x86_pop_gp( - func ); - - sse_movaps( - func, - make_xmm( xmm_dst ), - get_temp( TEMP_R0, 0 ) ); -} - -static void -emit_func_call_dst_src( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src, - void (PIPE_CDECL *code)() ) -{ - sse_movaps( - func, - get_temp( TEMP_R0, 1 ), - make_xmm( xmm_src ) ); - - emit_func_call_dst( - func, - xmm_dst, - code ); -} - -/** - * Low-level instruction translators. - */ - -static void -emit_abs( - struct x86_function *func, - unsigned xmm ) -{ - sse_andps( - func, - make_xmm( xmm ), - get_temp( - TGSI_EXEC_TEMP_7FFFFFFF_I, - TGSI_EXEC_TEMP_7FFFFFFF_C ) ); -} - -static void -emit_add( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ - sse_addps( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -} - -static void PIPE_CDECL -cos4f( - float *store ) -{ - const unsigned X = 0; - - store[X + 0] = cosf( store[X + 0] ); - store[X + 1] = cosf( store[X + 1] ); - store[X + 2] = cosf( store[X + 2] ); - store[X + 3] = cosf( store[X + 3] ); -} - -static void -emit_cos( - struct x86_function *func, - unsigned xmm_dst ) -{ - emit_func_call_dst( - func, - xmm_dst, - cos4f ); -} - -static void PIPE_CDECL -ex24f( - float *store ) -{ - const unsigned X = 0; - - store[X + 0] = powf( 2.0f, store[X + 0] ); - store[X + 1] = powf( 2.0f, store[X + 1] ); - store[X + 2] = powf( 2.0f, store[X + 2] ); - store[X + 3] = powf( 2.0f, store[X + 3] ); -} - -static void -emit_ex2( - struct x86_function *func, - unsigned xmm_dst ) -{ - emit_func_call_dst( - func, - xmm_dst, - ex24f ); -} - -static void -emit_f2it( - struct x86_function *func, - unsigned xmm ) -{ - sse2_cvttps2dq( - func, - make_xmm( xmm ), - make_xmm( xmm ) ); -} - -static void PIPE_CDECL -flr4f( - float *store ) -{ - const unsigned X = 0; - - store[X + 0] = floorf( store[X + 0] ); - store[X + 1] = floorf( store[X + 1] ); - store[X + 2] = floorf( store[X + 2] ); - store[X + 3] = floorf( store[X + 3] ); -} - -static void -emit_flr( - struct x86_function *func, - unsigned xmm_dst ) -{ - emit_func_call_dst( - func, - xmm_dst, - flr4f ); -} - -static void PIPE_CDECL -frc4f( - float *store ) -{ - const unsigned X = 0; - - store[X + 0] -= floorf( store[X + 0] ); - store[X + 1] -= floorf( store[X + 1] ); - store[X + 2] -= floorf( store[X + 2] ); - store[X + 3] -= floorf( store[X + 3] ); -} - -static void -emit_frc( - struct x86_function *func, - unsigned xmm_dst ) -{ - emit_func_call_dst( - func, - xmm_dst, - frc4f ); -} - -static void PIPE_CDECL -lg24f( - float *store ) -{ - const unsigned X = 0; - - store[X + 0] = LOG2( store[X + 0] ); - store[X + 1] = LOG2( store[X + 1] ); - store[X + 2] = LOG2( store[X + 2] ); - store[X + 3] = LOG2( store[X + 3] ); -} - -static void -emit_lg2( - struct x86_function *func, - unsigned xmm_dst ) -{ - emit_func_call_dst( - func, - xmm_dst, - lg24f ); -} - -static void -emit_MOV( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ - sse_movups( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -} - -static void -emit_mul (struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src) -{ - sse_mulps( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -} - -static void -emit_neg( - struct x86_function *func, - unsigned xmm ) -{ - sse_xorps( - func, - make_xmm( xmm ), - get_temp( - TGSI_EXEC_TEMP_80000000_I, - TGSI_EXEC_TEMP_80000000_C ) ); -} - -static void PIPE_CDECL -pow4f( - float *store ) -{ - const unsigned X = 0; - - store[X + 0] = powf( store[X + 0], store[X + 4] ); - store[X + 1] = powf( store[X + 1], store[X + 5] ); - store[X + 2] = powf( store[X + 2], store[X + 6] ); - store[X + 3] = powf( store[X + 3], store[X + 7] ); -} - -static void -emit_pow( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ - emit_func_call_dst_src( - func, - xmm_dst, - xmm_src, - pow4f ); -} - -static void -emit_rcp ( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ - /* On Intel CPUs at least, this is only accurate to 12 bits -- not - * good enough. Need to either emit a proper divide or use the - * iterative technique described below in emit_rsqrt(). - */ - sse2_rcpps( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -} - -static void -emit_rsqrt( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ -#if HIGH_PRECISION - /* Although rsqrtps() and rcpps() are low precision on some/all SSE - * implementations, it is possible to improve its precision at - * fairly low cost, using a newton/raphson step, as below: - * - * x1 = 2 * rcpps(a) - a * rcpps(a) * rcpps(a) - * x1 = 0.5 * rsqrtps(a) * [3.0 - (a * rsqrtps(a))* rsqrtps(a)] - * - * See: http://softwarecommunity.intel.com/articles/eng/1818.htm - */ - { - struct x86_reg dst = make_xmm( xmm_dst ); - struct x86_reg src = make_xmm( xmm_src ); - struct x86_reg tmp0 = make_xmm( 2 ); - struct x86_reg tmp1 = make_xmm( 3 ); - - assert( xmm_dst != xmm_src ); - assert( xmm_dst != 2 && xmm_dst != 3 ); - assert( xmm_src != 2 && xmm_src != 3 ); - - sse_movaps( func, dst, get_temp( TGSI_EXEC_TEMP_HALF_I, TGSI_EXEC_TEMP_HALF_C ) ); - sse_movaps( func, tmp0, get_temp( TGSI_EXEC_TEMP_THREE_I, TGSI_EXEC_TEMP_THREE_C ) ); - sse_rsqrtps( func, tmp1, src ); - sse_mulps( func, src, tmp1 ); - sse_mulps( func, dst, tmp1 ); - sse_mulps( func, src, tmp1 ); - sse_subps( func, tmp0, src ); - sse_mulps( func, dst, tmp0 ); - } -#else - /* On Intel CPUs at least, this is only accurate to 12 bits -- not - * good enough. - */ - sse_rsqrtps( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -#endif -} - -static void -emit_setsign( - struct x86_function *func, - unsigned xmm ) -{ - sse_orps( - func, - make_xmm( xmm ), - get_temp( - TGSI_EXEC_TEMP_80000000_I, - TGSI_EXEC_TEMP_80000000_C ) ); -} - -static void PIPE_CDECL -sin4f( - float *store ) -{ - const unsigned X = 0; - - store[X + 0] = sinf( store[X + 0] ); - store[X + 1] = sinf( store[X + 1] ); - store[X + 2] = sinf( store[X + 2] ); - store[X + 3] = sinf( store[X + 3] ); -} - -static void -emit_sin (struct x86_function *func, - unsigned xmm_dst) -{ - emit_func_call_dst( - func, - xmm_dst, - sin4f ); -} - -static void -emit_sub( - struct x86_function *func, - unsigned xmm_dst, - unsigned xmm_src ) -{ - sse_subps( - func, - make_xmm( xmm_dst ), - make_xmm( xmm_src ) ); -} - -/** - * Register fetch. - */ - -static void -emit_fetch( - struct x86_function *func, - unsigned xmm, - const struct tgsi_full_src_register *reg, - const unsigned chan_index ) -{ - unsigned swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); - - switch( swizzle ) { - case TGSI_EXTSWIZZLE_X: - case TGSI_EXTSWIZZLE_Y: - case TGSI_EXTSWIZZLE_Z: - case TGSI_EXTSWIZZLE_W: - switch( reg->SrcRegister.File ) { - case TGSI_FILE_CONSTANT: - emit_const( - func, - xmm, - reg->SrcRegister.Index, - swizzle ); - break; - - case TGSI_FILE_IMMEDIATE: - emit_immediate( - func, - xmm, - reg->SrcRegister.Index, - swizzle ); - break; - - case TGSI_FILE_INPUT: - emit_inputf( - func, - xmm, - reg->SrcRegister.Index, - swizzle ); - break; - - case TGSI_FILE_TEMPORARY: - emit_tempf( - func, - xmm, - reg->SrcRegister.Index, - swizzle ); - break; - - default: - assert( 0 ); - } - break; - - case TGSI_EXTSWIZZLE_ZERO: - emit_tempf( - func, - xmm, - TGSI_EXEC_TEMP_00000000_I, - TGSI_EXEC_TEMP_00000000_C ); - break; - - case TGSI_EXTSWIZZLE_ONE: - emit_tempf( - func, - xmm, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); - break; - - default: - assert( 0 ); - } - - switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) { - case TGSI_UTIL_SIGN_CLEAR: - emit_abs( func, xmm ); - break; - - case TGSI_UTIL_SIGN_SET: - emit_setsign( func, xmm ); - break; - - case TGSI_UTIL_SIGN_TOGGLE: - emit_neg( func, xmm ); - break; - - case TGSI_UTIL_SIGN_KEEP: - break; - } -} - -#define FETCH( FUNC, INST, XMM, INDEX, CHAN )\ - emit_fetch( FUNC, XMM, &(INST).FullSrcRegisters[INDEX], CHAN ) - -/** - * Register store. - */ - -static void -emit_store( - struct x86_function *func, - unsigned xmm, - const struct tgsi_full_dst_register *reg, - const struct tgsi_full_instruction *inst, - unsigned chan_index ) -{ - switch( reg->DstRegister.File ) { - case TGSI_FILE_OUTPUT: - emit_output( - func, - xmm, - reg->DstRegister.Index, - chan_index ); - break; - - case TGSI_FILE_TEMPORARY: - emit_temps( - func, - xmm, - reg->DstRegister.Index, - chan_index ); - break; - - case TGSI_FILE_ADDRESS: - emit_addrs( - func, - xmm, - reg->DstRegister.Index, - chan_index ); - break; - - default: - assert( 0 ); - } - - switch( inst->Instruction.Saturate ) { - case TGSI_SAT_NONE: - break; - - case TGSI_SAT_ZERO_ONE: - /* assert( 0 ); */ - break; - - case TGSI_SAT_MINUS_PLUS_ONE: - assert( 0 ); - break; - } -} - -#define STORE( FUNC, INST, XMM, INDEX, CHAN )\ - emit_store( FUNC, XMM, &(INST).FullDstRegisters[INDEX], &(INST), CHAN ) - -/** - * High-level instruction translators. - */ - -static void -emit_kil( - struct x86_function *func, - const struct tgsi_full_src_register *reg ) -{ - unsigned uniquemask; - unsigned registers[4]; - unsigned nextregister = 0; - unsigned firstchan = ~0; - unsigned chan_index; - - /* This mask stores component bits that were already tested. Note that - * we test if the value is less than zero, so 1.0 and 0.0 need not to be - * tested. */ - uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); - - FOR_EACH_CHANNEL( chan_index ) { - unsigned swizzle; - - /* unswizzle channel */ - swizzle = tgsi_util_get_full_src_register_extswizzle( - reg, - chan_index ); - - /* check if the component has not been already tested */ - if( !(uniquemask & (1 << swizzle)) ) { - uniquemask |= 1 << swizzle; - - /* allocate register */ - registers[chan_index] = nextregister; - emit_fetch( - func, - nextregister, - reg, - chan_index ); - nextregister++; - - /* mark the first channel used */ - if( firstchan == ~0 ) { - firstchan = chan_index; - } - } - } - - x86_push( - func, - x86_make_reg( file_REG32, reg_AX ) ); - x86_push( - func, - x86_make_reg( file_REG32, reg_DX ) ); - - FOR_EACH_CHANNEL( chan_index ) { - if( uniquemask & (1 << chan_index) ) { - sse_cmpps( - func, - make_xmm( registers[chan_index] ), - get_temp( - TGSI_EXEC_TEMP_00000000_I, - TGSI_EXEC_TEMP_00000000_C ), - cc_LessThan ); - - if( chan_index == firstchan ) { - sse_pmovmskb( - func, - x86_make_reg( file_REG32, reg_AX ), - make_xmm( registers[chan_index] ) ); - } - else { - sse_pmovmskb( - func, - x86_make_reg( file_REG32, reg_DX ), - make_xmm( registers[chan_index] ) ); - x86_or( - func, - x86_make_reg( file_REG32, reg_AX ), - x86_make_reg( file_REG32, reg_DX ) ); - } - } - } - - x86_or( - func, - get_temp( - TGSI_EXEC_TEMP_KILMASK_I, - TGSI_EXEC_TEMP_KILMASK_C ), - x86_make_reg( file_REG32, reg_AX ) ); - - x86_pop( - func, - x86_make_reg( file_REG32, reg_DX ) ); - x86_pop( - func, - x86_make_reg( file_REG32, reg_AX ) ); -} - -static void -emit_setcc( - struct x86_function *func, - struct tgsi_full_instruction *inst, - enum sse_cc cc ) -{ - unsigned chan_index; - - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - sse_cmpps( - func, - make_xmm( 0 ), - make_xmm( 1 ), - cc ); - sse_andps( - func, - make_xmm( 0 ), - get_temp( - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ) ); - STORE( func, *inst, 0, 0, chan_index ); - } -} - -static void -emit_cmp( - struct x86_function *func, - struct tgsi_full_instruction *inst ) -{ - unsigned chan_index; - - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - FETCH( func, *inst, 2, 2, chan_index ); - sse_cmpps( - func, - make_xmm( 0 ), - get_temp( - TGSI_EXEC_TEMP_00000000_I, - TGSI_EXEC_TEMP_00000000_C ), - cc_LessThan ); - sse_andps( - func, - make_xmm( 1 ), - make_xmm( 0 ) ); - sse_andnps( - func, - make_xmm( 0 ), - make_xmm( 2 ) ); - sse_orps( - func, - make_xmm( 0 ), - make_xmm( 1 ) ); - STORE( func, *inst, 0, 0, chan_index ); - } -} - -static int -emit_instruction( - struct x86_function *func, - struct tgsi_full_instruction *inst ) -{ - unsigned chan_index; - - switch( inst->Instruction.Opcode ) { - case TGSI_OPCODE_ARL: -#if 0 - /* XXX this isn't working properly (see glean vertProg1 test) */ - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - emit_f2it( func, 0 ); - STORE( func, *inst, 0, 0, chan_index ); - } -#else - return 0; -#endif - break; - - case TGSI_OPCODE_MOV: - case TGSI_OPCODE_SWZ: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_LIT: - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || - IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) { - emit_tempf( - func, - 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C); - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ) { - STORE( func, *inst, 0, 0, CHAN_X ); - } - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) { - STORE( func, *inst, 0, 0, CHAN_W ); - } - } - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || - IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { - FETCH( func, *inst, 0, 0, CHAN_X ); - sse_maxps( - func, - make_xmm( 0 ), - get_temp( - TGSI_EXEC_TEMP_00000000_I, - TGSI_EXEC_TEMP_00000000_C ) ); - STORE( func, *inst, 0, 0, CHAN_Y ); - } - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { - /* XMM[1] = SrcReg[0].yyyy */ - FETCH( func, *inst, 1, 0, CHAN_Y ); - /* XMM[1] = max(XMM[1], 0) */ - sse_maxps( - func, - make_xmm( 1 ), - get_temp( - TGSI_EXEC_TEMP_00000000_I, - TGSI_EXEC_TEMP_00000000_C ) ); - /* XMM[2] = SrcReg[0].wwww */ - FETCH( func, *inst, 2, 0, CHAN_W ); - /* XMM[2] = min(XMM[2], 128.0) */ - sse_minps( - func, - make_xmm( 2 ), - get_temp( - TGSI_EXEC_TEMP_128_I, - TGSI_EXEC_TEMP_128_C ) ); - /* XMM[2] = max(XMM[2], -128.0) */ - sse_maxps( - func, - make_xmm( 2 ), - get_temp( - TGSI_EXEC_TEMP_MINUS_128_I, - TGSI_EXEC_TEMP_MINUS_128_C ) ); - emit_pow( func, 1, 2 ); - FETCH( func, *inst, 0, 0, CHAN_X ); - sse_xorps( - func, - make_xmm( 2 ), - make_xmm( 2 ) ); - sse_cmpps( - func, - make_xmm( 2 ), - make_xmm( 0 ), - cc_LessThanEqual ); - sse_andps( - func, - make_xmm( 2 ), - make_xmm( 1 ) ); - STORE( func, *inst, 2, 0, CHAN_Z ); - } - } - break; - - case TGSI_OPCODE_RCP: - /* TGSI_OPCODE_RECIP */ - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_rcp( func, 0, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_RSQ: - /* TGSI_OPCODE_RECIPSQRT */ - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_rsqrt( func, 1, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 1, 0, chan_index ); - } - break; - - case TGSI_OPCODE_EXP: - return 0; - break; - - case TGSI_OPCODE_LOG: - return 0; - break; - - case TGSI_OPCODE_MUL: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - emit_mul( func, 0, 1 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_ADD: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - emit_add( func, 0, 1 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_DP3: - /* TGSI_OPCODE_DOT3 */ - FETCH( func, *inst, 0, 0, CHAN_X ); - FETCH( func, *inst, 1, 1, CHAN_X ); - emit_mul( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Y ); - FETCH( func, *inst, 2, 1, CHAN_Y ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Z ); - FETCH( func, *inst, 2, 1, CHAN_Z ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_DP4: - /* TGSI_OPCODE_DOT4 */ - FETCH( func, *inst, 0, 0, CHAN_X ); - FETCH( func, *inst, 1, 1, CHAN_X ); - emit_mul( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Y ); - FETCH( func, *inst, 2, 1, CHAN_Y ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Z ); - FETCH( func, *inst, 2, 1, CHAN_Z ); - emit_mul(func, 1, 2 ); - emit_add(func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_W ); - FETCH( func, *inst, 2, 1, CHAN_W ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_DST: - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { - emit_tempf( - func, - 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); - STORE( func, *inst, 0, 0, CHAN_X ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { - FETCH( func, *inst, 0, 0, CHAN_Y ); - FETCH( func, *inst, 1, 1, CHAN_Y ); - emit_mul( func, 0, 1 ); - STORE( func, *inst, 0, 0, CHAN_Y ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { - FETCH( func, *inst, 0, 0, CHAN_Z ); - STORE( func, *inst, 0, 0, CHAN_Z ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { - FETCH( func, *inst, 0, 1, CHAN_W ); - STORE( func, *inst, 0, 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_MIN: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - sse_minps( - func, - make_xmm( 0 ), - make_xmm( 1 ) ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_MAX: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - sse_maxps( - func, - make_xmm( 0 ), - make_xmm( 1 ) ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_SLT: - /* TGSI_OPCODE_SETLT */ - emit_setcc( func, inst, cc_LessThan ); - break; - - case TGSI_OPCODE_SGE: - /* TGSI_OPCODE_SETGE */ - emit_setcc( func, inst, cc_NotLessThan ); - break; - - case TGSI_OPCODE_MAD: - /* TGSI_OPCODE_MADD */ - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - FETCH( func, *inst, 2, 2, chan_index ); - emit_mul( func, 0, 1 ); - emit_add( func, 0, 2 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_SUB: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - emit_sub( func, 0, 1 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_LERP: - /* TGSI_OPCODE_LRP */ - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - FETCH( func, *inst, 1, 1, chan_index ); - FETCH( func, *inst, 2, 2, chan_index ); - emit_sub( func, 1, 2 ); - emit_mul( func, 0, 1 ); - emit_add( func, 0, 2 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_CND: - return 0; - break; - - case TGSI_OPCODE_CND0: - return 0; - break; - - case TGSI_OPCODE_DOT2ADD: - /* TGSI_OPCODE_DP2A */ - return 0; - break; - - case TGSI_OPCODE_INDEX: - return 0; - break; - - case TGSI_OPCODE_NEGATE: - return 0; - break; - - case TGSI_OPCODE_FRAC: - /* TGSI_OPCODE_FRC */ - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - emit_frc( func, 0 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_CLAMP: - return 0; - break; - - case TGSI_OPCODE_FLOOR: - /* TGSI_OPCODE_FLR */ - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - emit_flr( func, 0 ); - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_ROUND: - return 0; - break; - - case TGSI_OPCODE_EXPBASE2: - /* TGSI_OPCODE_EX2 */ - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_ex2( func, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_LOGBASE2: - /* TGSI_OPCODE_LG2 */ - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_lg2( func, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_POWER: - /* TGSI_OPCODE_POW */ - FETCH( func, *inst, 0, 0, CHAN_X ); - FETCH( func, *inst, 1, 1, CHAN_X ); - emit_pow( func, 0, 1 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_CROSSPRODUCT: - /* TGSI_OPCODE_XPD */ - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || - IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { - FETCH( func, *inst, 1, 1, CHAN_Z ); - FETCH( func, *inst, 3, 0, CHAN_Z ); - } - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || - IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { - FETCH( func, *inst, 0, 0, CHAN_Y ); - FETCH( func, *inst, 4, 1, CHAN_Y ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { - emit_MOV( func, 2, 0 ); - emit_mul( func, 2, 1 ); - emit_MOV( func, 5, 3 ); - emit_mul( func, 5, 4 ); - emit_sub( func, 2, 5 ); - STORE( func, *inst, 2, 0, CHAN_X ); - } - if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || - IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { - FETCH( func, *inst, 2, 1, CHAN_X ); - FETCH( func, *inst, 5, 0, CHAN_X ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { - emit_mul( func, 3, 2 ); - emit_mul( func, 1, 5 ); - emit_sub( func, 3, 1 ); - STORE( func, *inst, 3, 0, CHAN_Y ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { - emit_mul( func, 5, 4 ); - emit_mul( func, 0, 2 ); - emit_sub( func, 5, 0 ); - STORE( func, *inst, 5, 0, CHAN_Z ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { - emit_tempf( - func, - 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); - STORE( func, *inst, 0, 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_MULTIPLYMATRIX: - return 0; - break; - - case TGSI_OPCODE_ABS: - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - emit_abs( func, 0) ; - - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_RCC: - return 0; - break; - - case TGSI_OPCODE_DPH: - FETCH( func, *inst, 0, 0, CHAN_X ); - FETCH( func, *inst, 1, 1, CHAN_X ); - emit_mul( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Y ); - FETCH( func, *inst, 2, 1, CHAN_Y ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FETCH( func, *inst, 1, 0, CHAN_Z ); - FETCH( func, *inst, 2, 1, CHAN_Z ); - emit_mul( func, 1, 2 ); - emit_add( func, 0, 1 ); - FETCH( func, *inst, 1, 1, CHAN_W ); - emit_add( func, 0, 1 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_COS: - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_cos( func, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_DDX: - return 0; - break; - - case TGSI_OPCODE_DDY: - return 0; - break; - - case TGSI_OPCODE_KIL: - emit_kil( func, &inst->FullSrcRegisters[0] ); - break; - - case TGSI_OPCODE_PK2H: - return 0; - break; - - case TGSI_OPCODE_PK2US: - return 0; - break; - - case TGSI_OPCODE_PK4B: - return 0; - break; - - case TGSI_OPCODE_PK4UB: - return 0; - break; - - case TGSI_OPCODE_RFL: - return 0; - break; - - case TGSI_OPCODE_SEQ: - return 0; - break; - - case TGSI_OPCODE_SFL: - return 0; - break; - - case TGSI_OPCODE_SGT: - return 0; - break; - - case TGSI_OPCODE_SIN: - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_sin( func, 0 ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - break; - - case TGSI_OPCODE_SLE: - return 0; - break; - - case TGSI_OPCODE_SNE: - return 0; - break; - - case TGSI_OPCODE_STR: - return 0; - break; - - case TGSI_OPCODE_TEX: - if (0) { - /* Disable dummy texture code: - */ - emit_tempf( - func, - 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); - FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( func, *inst, 0, 0, chan_index ); - } - } - else { - return 0; - } - break; - - case TGSI_OPCODE_TXD: - return 0; - break; - - case TGSI_OPCODE_UP2H: - return 0; - break; - - case TGSI_OPCODE_UP2US: - return 0; - break; - - case TGSI_OPCODE_UP4B: - return 0; - break; - - case TGSI_OPCODE_UP4UB: - return 0; - break; - - case TGSI_OPCODE_X2D: - return 0; - break; - - case TGSI_OPCODE_ARA: - return 0; - break; - - case TGSI_OPCODE_ARR: - return 0; - break; - - case TGSI_OPCODE_BRA: - return 0; - break; - - case TGSI_OPCODE_CAL: - return 0; - break; - - case TGSI_OPCODE_RET: - emit_ret( func ); - break; - - case TGSI_OPCODE_END: - break; - - case TGSI_OPCODE_SSG: - return 0; - break; - - case TGSI_OPCODE_CMP: - emit_cmp (func, inst); - break; - - case TGSI_OPCODE_SCS: - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_cos( func, 0 ); - STORE( func, *inst, 0, 0, CHAN_X ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { - FETCH( func, *inst, 0, 0, CHAN_X ); - emit_sin( func, 0 ); - STORE( func, *inst, 0, 0, CHAN_Y ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { - emit_tempf( - func, - 0, - TGSI_EXEC_TEMP_00000000_I, - TGSI_EXEC_TEMP_00000000_C ); - STORE( func, *inst, 0, 0, CHAN_Z ); - } - IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { - emit_tempf( - func, - 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); - STORE( func, *inst, 0, 0, CHAN_W ); - } - break; - - case TGSI_OPCODE_TXB: - return 0; - break; - - case TGSI_OPCODE_NRM: - return 0; - break; - - case TGSI_OPCODE_DIV: - return 0; - break; - - case TGSI_OPCODE_DP2: - return 0; - break; - - case TGSI_OPCODE_TXL: - return 0; - break; - - case TGSI_OPCODE_BRK: - return 0; - break; - - case TGSI_OPCODE_IF: - return 0; - break; - - case TGSI_OPCODE_LOOP: - return 0; - break; - - case TGSI_OPCODE_REP: - return 0; - break; - - case TGSI_OPCODE_ELSE: - return 0; - break; - - case TGSI_OPCODE_ENDIF: - return 0; - break; - - case TGSI_OPCODE_ENDLOOP: - return 0; - break; - - case TGSI_OPCODE_ENDREP: - return 0; - break; - - case TGSI_OPCODE_PUSHA: - return 0; - break; - - case TGSI_OPCODE_POPA: - return 0; - break; - - case TGSI_OPCODE_CEIL: - return 0; - break; - - case TGSI_OPCODE_I2F: - return 0; - break; - - case TGSI_OPCODE_NOT: - return 0; - break; - - case TGSI_OPCODE_TRUNC: - return 0; - break; - - case TGSI_OPCODE_SHL: - return 0; - break; - - case TGSI_OPCODE_SHR: - return 0; - break; - - case TGSI_OPCODE_AND: - return 0; - break; - - case TGSI_OPCODE_OR: - return 0; - break; - - case TGSI_OPCODE_MOD: - return 0; - break; - - case TGSI_OPCODE_XOR: - return 0; - break; - - case TGSI_OPCODE_SAD: - return 0; - break; - - case TGSI_OPCODE_TXF: - return 0; - break; - - case TGSI_OPCODE_TXQ: - return 0; - break; - - case TGSI_OPCODE_CONT: - return 0; - break; - - case TGSI_OPCODE_EMIT: - return 0; - break; - - case TGSI_OPCODE_ENDPRIM: - return 0; - break; - - default: - return 0; - } - - return 1; -} - -static void -emit_declaration( - struct x86_function *func, - struct tgsi_full_declaration *decl ) -{ - if( decl->Declaration.File == TGSI_FILE_INPUT ) { - unsigned first, last, mask; - unsigned i, j; - - first = decl->DeclarationRange.First; - last = decl->DeclarationRange.Last; - mask = decl->Declaration.UsageMask; - - for( i = first; i <= last; i++ ) { - for( j = 0; j < NUM_CHANNELS; j++ ) { - if( mask & (1 << j) ) { - switch( decl->Declaration.Interpolate ) { - case TGSI_INTERPOLATE_CONSTANT: - emit_coef_a0( func, 0, i, j ); - emit_inputs( func, 0, i, j ); - break; - - case TGSI_INTERPOLATE_LINEAR: - emit_tempf( func, 0, 0, TGSI_SWIZZLE_X ); - emit_coef_dadx( func, 1, i, j ); - emit_tempf( func, 2, 0, TGSI_SWIZZLE_Y ); - emit_coef_dady( func, 3, i, j ); - emit_mul( func, 0, 1 ); /* x * dadx */ - emit_coef_a0( func, 4, i, j ); - emit_mul( func, 2, 3 ); /* y * dady */ - emit_add( func, 0, 4 ); /* x * dadx + a0 */ - emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */ - emit_inputs( func, 0, i, j ); - break; - - case TGSI_INTERPOLATE_PERSPECTIVE: - emit_tempf( func, 0, 0, TGSI_SWIZZLE_X ); - emit_coef_dadx( func, 1, i, j ); - emit_tempf( func, 2, 0, TGSI_SWIZZLE_Y ); - emit_coef_dady( func, 3, i, j ); - emit_mul( func, 0, 1 ); /* x * dadx */ - emit_tempf( func, 4, 0, TGSI_SWIZZLE_W ); - emit_coef_a0( func, 5, i, j ); - emit_rcp( func, 4, 4 ); /* 1.0 / w */ - emit_mul( func, 2, 3 ); /* y * dady */ - emit_add( func, 0, 5 ); /* x * dadx + a0 */ - emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */ - emit_mul( func, 0, 4 ); /* (x * dadx + y * dady + a0) / w */ - emit_inputs( func, 0, i, j ); - break; - - default: - assert( 0 ); - break; - } - } - } - } - } -} - -static void aos_to_soa( struct x86_function *func, - uint arg_aos, - uint arg_soa, - uint arg_num, - uint arg_stride ) -{ - struct x86_reg soa_input = x86_make_reg( file_REG32, reg_AX ); - struct x86_reg aos_input = x86_make_reg( file_REG32, reg_BX ); - struct x86_reg num_inputs = x86_make_reg( file_REG32, reg_CX ); - struct x86_reg stride = x86_make_reg( file_REG32, reg_DX ); - int inner_loop; - - - /* Save EBX */ - x86_push( func, x86_make_reg( file_REG32, reg_BX ) ); - - x86_mov( func, aos_input, x86_fn_arg( func, arg_aos ) ); - x86_mov( func, soa_input, x86_fn_arg( func, arg_soa ) ); - x86_mov( func, num_inputs, x86_fn_arg( func, arg_num ) ); - x86_mov( func, stride, x86_fn_arg( func, arg_stride ) ); - - /* do */ - inner_loop = x86_get_label( func ); - { - x86_push( func, aos_input ); - sse_movlps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); - sse_movlps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); - x86_add( func, aos_input, stride ); - sse_movhps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); - sse_movhps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); - x86_add( func, aos_input, stride ); - sse_movlps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); - sse_movlps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); - x86_add( func, aos_input, stride ); - sse_movhps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); - sse_movhps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); - x86_pop( func, aos_input ); - - sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) ); - sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) ); - sse_shufps( func, make_xmm( 0 ), make_xmm( 1 ), 0x88 ); - sse_shufps( func, make_xmm( 2 ), make_xmm( 1 ), 0xdd ); - sse_shufps( func, make_xmm( 3 ), make_xmm( 4 ), 0x88 ); - sse_shufps( func, make_xmm( 5 ), make_xmm( 4 ), 0xdd ); - - sse_movups( func, x86_make_disp( soa_input, 0 ), make_xmm( 0 ) ); - sse_movups( func, x86_make_disp( soa_input, 16 ), make_xmm( 2 ) ); - sse_movups( func, x86_make_disp( soa_input, 32 ), make_xmm( 3 ) ); - sse_movups( func, x86_make_disp( soa_input, 48 ), make_xmm( 5 ) ); - - /* Advance to next input */ - x86_lea( func, aos_input, x86_make_disp(aos_input, 16) ); - x86_lea( func, soa_input, x86_make_disp(soa_input, 64) ); - } - /* while --num_inputs */ - x86_dec( func, num_inputs ); - x86_jcc( func, cc_NE, inner_loop ); - - /* Restore EBX */ - x86_pop( func, aos_input ); -} - -static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, uint stride ) -{ - struct x86_reg soa_output; - struct x86_reg aos_output; - struct x86_reg num_outputs; - struct x86_reg temp; - int inner_loop; - - soa_output = x86_make_reg( file_REG32, reg_AX ); - aos_output = x86_make_reg( file_REG32, reg_BX ); - num_outputs = x86_make_reg( file_REG32, reg_CX ); - temp = x86_make_reg( file_REG32, reg_DX ); - - /* Save EBX */ - x86_push( func, aos_output ); - - x86_mov( func, soa_output, x86_fn_arg( func, soa ) ); - x86_mov( func, aos_output, x86_fn_arg( func, aos ) ); - x86_mov( func, num_outputs, x86_fn_arg( func, num ) ); - - /* do */ - inner_loop = x86_get_label( func ); - { - sse_movups( func, make_xmm( 0 ), x86_make_disp( soa_output, 0 ) ); - sse_movups( func, make_xmm( 1 ), x86_make_disp( soa_output, 16 ) ); - sse_movups( func, make_xmm( 3 ), x86_make_disp( soa_output, 32 ) ); - sse_movups( func, make_xmm( 4 ), x86_make_disp( soa_output, 48 ) ); - - sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) ); - sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) ); - sse_unpcklps( func, make_xmm( 0 ), make_xmm( 1 ) ); - sse_unpckhps( func, make_xmm( 2 ), make_xmm( 1 ) ); - sse_unpcklps( func, make_xmm( 3 ), make_xmm( 4 ) ); - sse_unpckhps( func, make_xmm( 5 ), make_xmm( 4 ) ); - - x86_mov( func, temp, x86_fn_arg( func, stride ) ); - x86_push( func, aos_output ); - sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) ); - sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) ); - x86_add( func, aos_output, temp ); - sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) ); - sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) ); - x86_add( func, aos_output, temp ); - sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) ); - sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) ); - x86_add( func, aos_output, temp ); - sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) ); - sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) ); - x86_pop( func, aos_output ); - - /* Advance to next output */ - x86_lea( func, aos_output, x86_make_disp(aos_output, 16) ); - x86_lea( func, soa_output, x86_make_disp(soa_output, 64) ); - } - /* while --num_outputs */ - x86_dec( func, num_outputs ); - x86_jcc( func, cc_NE, inner_loop ); - - /* Restore EBX */ - x86_pop( func, aos_output ); -} - -/** - * Translate a TGSI vertex/fragment shader to SSE2 code. - * Slightly different things are done for vertex vs. fragment shaders. - * - * Note that fragment shaders are responsible for interpolating shader - * inputs. Because on x86 we have only 4 GP registers, and here we - * have 5 shader arguments (input, output, const, temp and coef), the - * code is split into two phases -- DECLARATION and INSTRUCTION phase. - * GP register holding the output argument is aliased with the coeff - * argument, as outputs are not needed in the DECLARATION phase. - * - * \param tokens the TGSI input shader - * \param func the output SSE code/function - * \param immediates buffer to place immediates, later passed to SSE func - * \param return 1 for success, 0 if translation failed - */ -unsigned -tgsi_emit_sse2( - const struct tgsi_token *tokens, - struct x86_function *func, - float (*immediates)[4], - boolean do_swizzles ) -{ - struct tgsi_parse_context parse; - boolean instruction_phase = FALSE; - unsigned ok = 1; - uint num_immediates = 0; - - func->csr = func->store; - - tgsi_parse_init( &parse, tokens ); - - /* Can't just use EDI, EBX without save/restoring them: - */ - x86_push( - func, - get_immediate_base() ); - - x86_push( - func, - get_temp_base() ); - - - /* - * Different function args for vertex/fragment shaders: - */ - if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { - /* DECLARATION phase, do not load output argument. */ - x86_mov( - func, - get_input_base(), - x86_fn_arg( func, 1 ) ); - /* skipping outputs argument here */ - x86_mov( - func, - get_const_base(), - x86_fn_arg( func, 3 ) ); - x86_mov( - func, - get_temp_base(), - x86_fn_arg( func, 4 ) ); - x86_mov( - func, - get_coef_base(), - x86_fn_arg( func, 5 ) ); - x86_mov( - func, - get_immediate_base(), - x86_fn_arg( func, 6 ) ); - } - else { - assert(parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX); - - if (do_swizzles) - aos_to_soa( func, - 6, /* aos_input */ - 1, /* machine->input */ - 7, /* num_inputs */ - 8 ); /* input_stride */ - - x86_mov( - func, - get_input_base(), - x86_fn_arg( func, 1 ) ); - x86_mov( - func, - get_output_base(), - x86_fn_arg( func, 2 ) ); - x86_mov( - func, - get_const_base(), - x86_fn_arg( func, 3 ) ); - x86_mov( - func, - get_temp_base(), - x86_fn_arg( func, 4 ) ); - x86_mov( - func, - get_immediate_base(), - x86_fn_arg( func, 5 ) ); - } - - while( !tgsi_parse_end_of_tokens( &parse ) && ok ) { - tgsi_parse_token( &parse ); - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { - emit_declaration( - func, - &parse.FullToken.FullDeclaration ); - } - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { - if( !instruction_phase ) { - /* INSTRUCTION phase, overwrite coeff with output. */ - instruction_phase = TRUE; - x86_mov( - func, - get_output_base(), - x86_fn_arg( func, 2 ) ); - } - } - - ok = emit_instruction( - func, - &parse.FullToken.FullInstruction ); - - if (!ok) { - debug_printf("failed to translate tgsi opcode %d to SSE (%s)\n", - parse.FullToken.FullInstruction.Instruction.Opcode, - parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ? - "vertex shader" : "fragment shader"); - } - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - /* simply copy the immediate values into the next immediates[] slot */ - { - const uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; - uint i; - assert(size <= 4); - assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES); - for( i = 0; i < size; i++ ) { - immediates[num_immediates][i] = - parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; - } -#if 0 - debug_printf("SSE FS immediate[%d] = %f %f %f %f\n", - num_immediates, - immediates[num_immediates][0], - immediates[num_immediates][1], - immediates[num_immediates][2], - immediates[num_immediates][3]); -#endif - num_immediates++; - } - break; - - default: - ok = 0; - assert( 0 ); - } - } - - if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) { - if (do_swizzles) - soa_to_aos( func, 9, 2, 10, 11 ); - } - - /* Can't just use EBX, EDI without save/restoring them: - */ - x86_pop( - func, - get_temp_base() ); - - x86_pop( - func, - get_immediate_base() ); - - emit_ret( func ); - - tgsi_parse_free( &parse ); - - return ok; -} - -#endif /* PIPE_ARCH_X86 */ diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h deleted file mode 100755 index af838b2a25..0000000000 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h +++ /dev/null @@ -1,49 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_SSE2_H -#define TGSI_SSE2_H - -#if defined __cplusplus -extern "C" { -#endif - -struct tgsi_token; -struct x86_function; - -unsigned -tgsi_emit_sse2( - const struct tgsi_token *tokens, - struct x86_function *function, - float (*immediates)[4], - boolean do_swizzles ); - -#if defined __cplusplus -} -#endif - -#endif /* TGSI_SSE2_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c new file mode 100644 index 0000000000..742ef14c35 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -0,0 +1,1324 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi_build.h" +#include "tgsi_parse.h" + +/* + * version + */ + +struct tgsi_version +tgsi_build_version( void ) +{ + struct tgsi_version version; + + version.MajorVersion = 1; + version.MinorVersion = 1; + version.Padding = 0; + + return version; +} + +/* + * header + */ + +struct tgsi_header +tgsi_build_header( void ) +{ + struct tgsi_header header; + + header.HeaderSize = 1; + header.BodySize = 0; + + return header; +} + +static void +header_headersize_grow( struct tgsi_header *header ) +{ + assert( header->HeaderSize < 0xFF ); + assert( header->BodySize == 0 ); + + header->HeaderSize++; +} + +static void +header_bodysize_grow( struct tgsi_header *header ) +{ + assert( header->BodySize < 0xFFFFFF ); + + header->BodySize++; +} + +struct tgsi_processor +tgsi_default_processor( void ) +{ + struct tgsi_processor processor; + + processor.Processor = TGSI_PROCESSOR_FRAGMENT; + processor.Padding = 0; + + return processor; +} + +struct tgsi_processor +tgsi_build_processor( + unsigned type, + struct tgsi_header *header ) +{ + struct tgsi_processor processor; + + processor = tgsi_default_processor(); + processor.Processor = type; + + header_headersize_grow( header ); + + return processor; +} + +/* + * declaration + */ + +struct tgsi_declaration +tgsi_default_declaration( void ) +{ + struct tgsi_declaration declaration; + + declaration.Type = TGSI_TOKEN_TYPE_DECLARATION; + declaration.Size = 1; + declaration.File = TGSI_FILE_NULL; + declaration.UsageMask = TGSI_WRITEMASK_XYZW; + declaration.Interpolate = TGSI_INTERPOLATE_CONSTANT; + declaration.Semantic = 0; + declaration.Padding = 0; + declaration.Extended = 0; + + return declaration; +} + +struct tgsi_declaration +tgsi_build_declaration( + unsigned file, + unsigned usage_mask, + unsigned interpolate, + unsigned semantic, + struct tgsi_header *header ) +{ + struct tgsi_declaration declaration; + + assert( file <= TGSI_FILE_IMMEDIATE ); + assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE ); + + declaration = tgsi_default_declaration(); + declaration.File = file; + declaration.UsageMask = usage_mask; + declaration.Interpolate = interpolate; + declaration.Semantic = semantic; + + header_bodysize_grow( header ); + + return declaration; +} + +static void +declaration_grow( + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + assert( declaration->Size < 0xFF ); + + declaration->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_full_declaration +tgsi_default_full_declaration( void ) +{ + struct tgsi_full_declaration full_declaration; + + full_declaration.Declaration = tgsi_default_declaration(); + full_declaration.DeclarationRange = tgsi_default_declaration_range(); + full_declaration.Semantic = tgsi_default_declaration_semantic(); + + return full_declaration; +} + +unsigned +tgsi_build_full_declaration( + const struct tgsi_full_declaration *full_decl, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ) +{ + unsigned size = 0; + struct tgsi_declaration *declaration; + struct tgsi_declaration_range *dr; + + if( maxsize <= size ) + return 0; + declaration = (struct tgsi_declaration *) &tokens[size]; + size++; + + *declaration = tgsi_build_declaration( + full_decl->Declaration.File, + full_decl->Declaration.UsageMask, + full_decl->Declaration.Interpolate, + full_decl->Declaration.Semantic, + header ); + + if (maxsize <= size) + return 0; + dr = (struct tgsi_declaration_range *) &tokens[size]; + size++; + + *dr = tgsi_build_declaration_range( + full_decl->DeclarationRange.First, + full_decl->DeclarationRange.Last, + declaration, + header ); + + if( full_decl->Declaration.Semantic ) { + struct tgsi_declaration_semantic *ds; + + if( maxsize <= size ) + return 0; + ds = (struct tgsi_declaration_semantic *) &tokens[size]; + size++; + + *ds = tgsi_build_declaration_semantic( + full_decl->Semantic.SemanticName, + full_decl->Semantic.SemanticIndex, + declaration, + header ); + } + + return size; +} + +struct tgsi_declaration_range +tgsi_default_declaration_range( void ) +{ + struct tgsi_declaration_range dr; + + dr.First = 0; + dr.Last = 0; + + return dr; +} + +struct tgsi_declaration_range +tgsi_build_declaration_range( + unsigned first, + unsigned last, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_range declaration_range; + + assert( last >= first ); + assert( last <= 0xFFFF ); + + declaration_range = tgsi_default_declaration_range(); + declaration_range.First = first; + declaration_range.Last = last; + + declaration_grow( declaration, header ); + + return declaration_range; +} + +struct tgsi_declaration_semantic +tgsi_default_declaration_semantic( void ) +{ + struct tgsi_declaration_semantic ds; + + ds.SemanticName = TGSI_SEMANTIC_POSITION; + ds.SemanticIndex = 0; + ds.Padding = 0; + + return ds; +} + +struct tgsi_declaration_semantic +tgsi_build_declaration_semantic( + unsigned semantic_name, + unsigned semantic_index, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_semantic ds; + + assert( semantic_name <= TGSI_SEMANTIC_COUNT ); + assert( semantic_index <= 0xFFFF ); + + ds = tgsi_default_declaration_semantic(); + ds.SemanticName = semantic_name; + ds.SemanticIndex = semantic_index; + + declaration_grow( declaration, header ); + + return ds; +} + +/* + * immediate + */ + +struct tgsi_immediate +tgsi_default_immediate( void ) +{ + struct tgsi_immediate immediate; + + immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE; + immediate.Size = 1; + immediate.DataType = TGSI_IMM_FLOAT32; + immediate.Padding = 0; + immediate.Extended = 0; + + return immediate; +} + +struct tgsi_immediate +tgsi_build_immediate( + struct tgsi_header *header ) +{ + struct tgsi_immediate immediate; + + immediate = tgsi_default_immediate(); + + header_bodysize_grow( header ); + + return immediate; +} + +struct tgsi_full_immediate +tgsi_default_full_immediate( void ) +{ + struct tgsi_full_immediate fullimm; + + fullimm.Immediate = tgsi_default_immediate(); + fullimm.u.Pointer = (void *) 0; + + return fullimm; +} + +static void +immediate_grow( + struct tgsi_immediate *immediate, + struct tgsi_header *header ) +{ + assert( immediate->Size < 0xFF ); + + immediate->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_immediate_float32 +tgsi_build_immediate_float32( + float value, + struct tgsi_immediate *immediate, + struct tgsi_header *header ) +{ + struct tgsi_immediate_float32 immediate_float32; + + immediate_float32.Float = value; + + immediate_grow( immediate, header ); + + return immediate_float32; +} + +unsigned +tgsi_build_full_immediate( + const struct tgsi_full_immediate *full_imm, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ) +{ + unsigned size = 0, i; + struct tgsi_immediate *immediate; + + if( maxsize <= size ) + return 0; + immediate = (struct tgsi_immediate *) &tokens[size]; + size++; + + *immediate = tgsi_build_immediate( header ); + + for( i = 0; i < full_imm->Immediate.Size - 1; i++ ) { + struct tgsi_immediate_float32 *if32; + + if( maxsize <= size ) + return 0; + if32 = (struct tgsi_immediate_float32 *) &tokens[size]; + size++; + + *if32 = tgsi_build_immediate_float32( + full_imm->u.ImmediateFloat32[i].Float, + immediate, + header ); + } + + return size; +} + +/* + * instruction + */ + +struct tgsi_instruction +tgsi_default_instruction( void ) +{ + struct tgsi_instruction instruction; + + instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; + instruction.Size = 1; + instruction.Opcode = TGSI_OPCODE_MOV; + instruction.Saturate = TGSI_SAT_NONE; + instruction.NumDstRegs = 1; + instruction.NumSrcRegs = 1; + instruction.Padding = 0; + instruction.Extended = 0; + + return instruction; +} + +struct tgsi_instruction +tgsi_build_instruction( + unsigned opcode, + unsigned saturate, + unsigned num_dst_regs, + unsigned num_src_regs, + struct tgsi_header *header ) +{ + struct tgsi_instruction instruction; + + assert (opcode <= TGSI_OPCODE_LAST); + assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE); + assert (num_dst_regs <= 3); + assert (num_src_regs <= 15); + + instruction = tgsi_default_instruction(); + instruction.Opcode = opcode; + instruction.Saturate = saturate; + instruction.NumDstRegs = num_dst_regs; + instruction.NumSrcRegs = num_src_regs; + + header_bodysize_grow( header ); + + return instruction; +} + +static void +instruction_grow( + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + assert (instruction->Size < 0xFF); + + instruction->Size++; + + header_bodysize_grow( header ); +} + +struct tgsi_full_instruction +tgsi_default_full_instruction( void ) +{ + struct tgsi_full_instruction full_instruction; + unsigned i; + + full_instruction.Instruction = tgsi_default_instruction(); + full_instruction.InstructionExtNv = tgsi_default_instruction_ext_nv(); + full_instruction.InstructionExtLabel = tgsi_default_instruction_ext_label(); + full_instruction.InstructionExtTexture = tgsi_default_instruction_ext_texture(); + for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) { + full_instruction.FullDstRegisters[i] = tgsi_default_full_dst_register(); + } + for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) { + full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register(); + } + + return full_instruction; +} + +unsigned +tgsi_build_full_instruction( + const struct tgsi_full_instruction *full_inst, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ) +{ + unsigned size = 0; + unsigned i; + struct tgsi_instruction *instruction; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + instruction = (struct tgsi_instruction *) &tokens[size]; + size++; + + *instruction = tgsi_build_instruction( + full_inst->Instruction.Opcode, + full_inst->Instruction.Saturate, + full_inst->Instruction.NumDstRegs, + full_inst->Instruction.NumSrcRegs, + header ); + prev_token = (struct tgsi_token *) instruction; + + if( tgsi_compare_instruction_ext_nv( + full_inst->InstructionExtNv, + tgsi_default_instruction_ext_nv() ) ) { + struct tgsi_instruction_ext_nv *instruction_ext_nv; + + if( maxsize <= size ) + return 0; + instruction_ext_nv = + (struct tgsi_instruction_ext_nv *) &tokens[size]; + size++; + + *instruction_ext_nv = tgsi_build_instruction_ext_nv( + full_inst->InstructionExtNv.Precision, + full_inst->InstructionExtNv.CondDstIndex, + full_inst->InstructionExtNv.CondFlowIndex, + full_inst->InstructionExtNv.CondMask, + full_inst->InstructionExtNv.CondSwizzleX, + full_inst->InstructionExtNv.CondSwizzleY, + full_inst->InstructionExtNv.CondSwizzleZ, + full_inst->InstructionExtNv.CondSwizzleW, + full_inst->InstructionExtNv.CondDstUpdate, + full_inst->InstructionExtNv.CondFlowEnable, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_nv; + } + + if( tgsi_compare_instruction_ext_label( + full_inst->InstructionExtLabel, + tgsi_default_instruction_ext_label() ) ) { + struct tgsi_instruction_ext_label *instruction_ext_label; + + if( maxsize <= size ) + return 0; + instruction_ext_label = + (struct tgsi_instruction_ext_label *) &tokens[size]; + size++; + + *instruction_ext_label = tgsi_build_instruction_ext_label( + full_inst->InstructionExtLabel.Label, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_label; + } + + if( tgsi_compare_instruction_ext_texture( + full_inst->InstructionExtTexture, + tgsi_default_instruction_ext_texture() ) ) { + struct tgsi_instruction_ext_texture *instruction_ext_texture; + + if( maxsize <= size ) + return 0; + instruction_ext_texture = + (struct tgsi_instruction_ext_texture *) &tokens[size]; + size++; + + *instruction_ext_texture = tgsi_build_instruction_ext_texture( + full_inst->InstructionExtTexture.Texture, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) instruction_ext_texture; + } + + for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { + const struct tgsi_full_dst_register *reg = &full_inst->FullDstRegisters[i]; + struct tgsi_dst_register *dst_register; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + dst_register = (struct tgsi_dst_register *) &tokens[size]; + size++; + + *dst_register = tgsi_build_dst_register( + reg->DstRegister.File, + reg->DstRegister.WriteMask, + reg->DstRegister.Index, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register; + + if( tgsi_compare_dst_register_ext_concode( + reg->DstRegisterExtConcode, + tgsi_default_dst_register_ext_concode() ) ) { + struct tgsi_dst_register_ext_concode *dst_register_ext_concode; + + if( maxsize <= size ) + return 0; + dst_register_ext_concode = + (struct tgsi_dst_register_ext_concode *) &tokens[size]; + size++; + + *dst_register_ext_concode = tgsi_build_dst_register_ext_concode( + reg->DstRegisterExtConcode.CondMask, + reg->DstRegisterExtConcode.CondSwizzleX, + reg->DstRegisterExtConcode.CondSwizzleY, + reg->DstRegisterExtConcode.CondSwizzleZ, + reg->DstRegisterExtConcode.CondSwizzleW, + reg->DstRegisterExtConcode.CondSrcIndex, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register_ext_concode; + } + + if( tgsi_compare_dst_register_ext_modulate( + reg->DstRegisterExtModulate, + tgsi_default_dst_register_ext_modulate() ) ) { + struct tgsi_dst_register_ext_modulate *dst_register_ext_modulate; + + if( maxsize <= size ) + return 0; + dst_register_ext_modulate = + (struct tgsi_dst_register_ext_modulate *) &tokens[size]; + size++; + + *dst_register_ext_modulate = tgsi_build_dst_register_ext_modulate( + reg->DstRegisterExtModulate.Modulate, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) dst_register_ext_modulate; + } + } + + for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { + const struct tgsi_full_src_register *reg = &full_inst->FullSrcRegisters[i]; + struct tgsi_src_register *src_register; + struct tgsi_token *prev_token; + + if( maxsize <= size ) + return 0; + src_register = (struct tgsi_src_register *) &tokens[size]; + size++; + + *src_register = tgsi_build_src_register( + reg->SrcRegister.File, + reg->SrcRegister.SwizzleX, + reg->SrcRegister.SwizzleY, + reg->SrcRegister.SwizzleZ, + reg->SrcRegister.SwizzleW, + reg->SrcRegister.Negate, + reg->SrcRegister.Indirect, + reg->SrcRegister.Dimension, + reg->SrcRegister.Index, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register; + + if( tgsi_compare_src_register_ext_swz( + reg->SrcRegisterExtSwz, + tgsi_default_src_register_ext_swz() ) ) { + struct tgsi_src_register_ext_swz *src_register_ext_swz; + + /* Use of the extended swizzle requires the simple swizzle to be identity. + */ + assert( reg->SrcRegister.SwizzleX == TGSI_SWIZZLE_X ); + assert( reg->SrcRegister.SwizzleY == TGSI_SWIZZLE_Y ); + assert( reg->SrcRegister.SwizzleZ == TGSI_SWIZZLE_Z ); + assert( reg->SrcRegister.SwizzleW == TGSI_SWIZZLE_W ); + assert( reg->SrcRegister.Negate == FALSE ); + + if( maxsize <= size ) + return 0; + src_register_ext_swz = + (struct tgsi_src_register_ext_swz *) &tokens[size]; + size++; + + *src_register_ext_swz = tgsi_build_src_register_ext_swz( + reg->SrcRegisterExtSwz.ExtSwizzleX, + reg->SrcRegisterExtSwz.ExtSwizzleY, + reg->SrcRegisterExtSwz.ExtSwizzleZ, + reg->SrcRegisterExtSwz.ExtSwizzleW, + reg->SrcRegisterExtSwz.NegateX, + reg->SrcRegisterExtSwz.NegateY, + reg->SrcRegisterExtSwz.NegateZ, + reg->SrcRegisterExtSwz.NegateW, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register_ext_swz; + } + + if( tgsi_compare_src_register_ext_mod( + reg->SrcRegisterExtMod, + tgsi_default_src_register_ext_mod() ) ) { + struct tgsi_src_register_ext_mod *src_register_ext_mod; + + if( maxsize <= size ) + return 0; + src_register_ext_mod = + (struct tgsi_src_register_ext_mod *) &tokens[size]; + size++; + + *src_register_ext_mod = tgsi_build_src_register_ext_mod( + reg->SrcRegisterExtMod.Complement, + reg->SrcRegisterExtMod.Bias, + reg->SrcRegisterExtMod.Scale2X, + reg->SrcRegisterExtMod.Absolute, + reg->SrcRegisterExtMod.Negate, + prev_token, + instruction, + header ); + prev_token = (struct tgsi_token *) src_register_ext_mod; + } + + if( reg->SrcRegister.Indirect ) { + struct tgsi_src_register *ind; + + if( maxsize <= size ) + return 0; + ind = (struct tgsi_src_register *) &tokens[size]; + size++; + + *ind = tgsi_build_src_register( + reg->SrcRegisterInd.File, + reg->SrcRegisterInd.SwizzleX, + reg->SrcRegisterInd.SwizzleY, + reg->SrcRegisterInd.SwizzleZ, + reg->SrcRegisterInd.SwizzleW, + reg->SrcRegisterInd.Negate, + reg->SrcRegisterInd.Indirect, + reg->SrcRegisterInd.Dimension, + reg->SrcRegisterInd.Index, + instruction, + header ); + } + + if( reg->SrcRegister.Dimension ) { + struct tgsi_dimension *dim; + + assert( !reg->SrcRegisterDim.Dimension ); + + if( maxsize <= size ) + return 0; + dim = (struct tgsi_dimension *) &tokens[size]; + size++; + + *dim = tgsi_build_dimension( + reg->SrcRegisterDim.Indirect, + reg->SrcRegisterDim.Index, + instruction, + header ); + + if( reg->SrcRegisterDim.Indirect ) { + struct tgsi_src_register *ind; + + if( maxsize <= size ) + return 0; + ind = (struct tgsi_src_register *) &tokens[size]; + size++; + + *ind = tgsi_build_src_register( + reg->SrcRegisterDimInd.File, + reg->SrcRegisterDimInd.SwizzleX, + reg->SrcRegisterDimInd.SwizzleY, + reg->SrcRegisterDimInd.SwizzleZ, + reg->SrcRegisterDimInd.SwizzleW, + reg->SrcRegisterDimInd.Negate, + reg->SrcRegisterDimInd.Indirect, + reg->SrcRegisterDimInd.Dimension, + reg->SrcRegisterDimInd.Index, + instruction, + header ); + } + } + } + + return size; +} + +struct tgsi_instruction_ext_nv +tgsi_default_instruction_ext_nv( void ) +{ + struct tgsi_instruction_ext_nv instruction_ext_nv; + + instruction_ext_nv.Type = TGSI_INSTRUCTION_EXT_TYPE_NV; + instruction_ext_nv.Precision = TGSI_PRECISION_DEFAULT; + instruction_ext_nv.CondDstIndex = 0; + instruction_ext_nv.CondFlowIndex = 0; + instruction_ext_nv.CondMask = TGSI_CC_TR; + instruction_ext_nv.CondSwizzleX = TGSI_SWIZZLE_X; + instruction_ext_nv.CondSwizzleY = TGSI_SWIZZLE_Y; + instruction_ext_nv.CondSwizzleZ = TGSI_SWIZZLE_Z; + instruction_ext_nv.CondSwizzleW = TGSI_SWIZZLE_W; + instruction_ext_nv.CondDstUpdate = 0; + instruction_ext_nv.CondFlowEnable = 0; + instruction_ext_nv.Padding = 0; + instruction_ext_nv.Extended = 0; + + return instruction_ext_nv; +} + +union token_u32 +{ + unsigned u32; +}; + +unsigned +tgsi_compare_instruction_ext_nv( + struct tgsi_instruction_ext_nv a, + struct tgsi_instruction_ext_nv b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_instruction_ext_nv +tgsi_build_instruction_ext_nv( + unsigned precision, + unsigned cond_dst_index, + unsigned cond_flow_index, + unsigned cond_mask, + unsigned cond_swizzle_x, + unsigned cond_swizzle_y, + unsigned cond_swizzle_z, + unsigned cond_swizzle_w, + unsigned cond_dst_update, + unsigned cond_flow_update, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_nv instruction_ext_nv; + + instruction_ext_nv = tgsi_default_instruction_ext_nv(); + instruction_ext_nv.Precision = precision; + instruction_ext_nv.CondDstIndex = cond_dst_index; + instruction_ext_nv.CondFlowIndex = cond_flow_index; + instruction_ext_nv.CondMask = cond_mask; + instruction_ext_nv.CondSwizzleX = cond_swizzle_x; + instruction_ext_nv.CondSwizzleY = cond_swizzle_y; + instruction_ext_nv.CondSwizzleZ = cond_swizzle_z; + instruction_ext_nv.CondSwizzleW = cond_swizzle_w; + instruction_ext_nv.CondDstUpdate = cond_dst_update; + instruction_ext_nv.CondFlowEnable = cond_flow_update; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_nv; +} + +struct tgsi_instruction_ext_label +tgsi_default_instruction_ext_label( void ) +{ + struct tgsi_instruction_ext_label instruction_ext_label; + + instruction_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL; + instruction_ext_label.Label = 0; + instruction_ext_label.Padding = 0; + instruction_ext_label.Extended = 0; + + return instruction_ext_label; +} + +unsigned +tgsi_compare_instruction_ext_label( + struct tgsi_instruction_ext_label a, + struct tgsi_instruction_ext_label b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_instruction_ext_label +tgsi_build_instruction_ext_label( + unsigned label, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_label instruction_ext_label; + + instruction_ext_label = tgsi_default_instruction_ext_label(); + instruction_ext_label.Label = label; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_label; +} + +struct tgsi_instruction_ext_texture +tgsi_default_instruction_ext_texture( void ) +{ + struct tgsi_instruction_ext_texture instruction_ext_texture; + + instruction_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE; + instruction_ext_texture.Texture = TGSI_TEXTURE_UNKNOWN; + instruction_ext_texture.Padding = 0; + instruction_ext_texture.Extended = 0; + + return instruction_ext_texture; +} + +unsigned +tgsi_compare_instruction_ext_texture( + struct tgsi_instruction_ext_texture a, + struct tgsi_instruction_ext_texture b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_instruction_ext_texture +tgsi_build_instruction_ext_texture( + unsigned texture, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_ext_texture instruction_ext_texture; + + instruction_ext_texture = tgsi_default_instruction_ext_texture(); + instruction_ext_texture.Texture = texture; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return instruction_ext_texture; +} + +struct tgsi_src_register +tgsi_default_src_register( void ) +{ + struct tgsi_src_register src_register; + + src_register.File = TGSI_FILE_NULL; + src_register.SwizzleX = TGSI_SWIZZLE_X; + src_register.SwizzleY = TGSI_SWIZZLE_Y; + src_register.SwizzleZ = TGSI_SWIZZLE_Z; + src_register.SwizzleW = TGSI_SWIZZLE_W; + src_register.Negate = 0; + src_register.Indirect = 0; + src_register.Dimension = 0; + src_register.Index = 0; + src_register.Extended = 0; + + return src_register; +} + +struct tgsi_src_register +tgsi_build_src_register( + unsigned file, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + unsigned negate, + unsigned indirect, + unsigned dimension, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register src_register; + + assert( file <= TGSI_FILE_IMMEDIATE ); + assert( swizzle_x <= TGSI_SWIZZLE_W ); + assert( swizzle_y <= TGSI_SWIZZLE_W ); + assert( swizzle_z <= TGSI_SWIZZLE_W ); + assert( swizzle_w <= TGSI_SWIZZLE_W ); + assert( negate <= 1 ); + assert( index >= -0x8000 && index <= 0x7FFF ); + + src_register = tgsi_default_src_register(); + src_register.File = file; + src_register.SwizzleX = swizzle_x; + src_register.SwizzleY = swizzle_y; + src_register.SwizzleZ = swizzle_z; + src_register.SwizzleW = swizzle_w; + src_register.Negate = negate; + src_register.Indirect = indirect; + src_register.Dimension = dimension; + src_register.Index = index; + + instruction_grow( instruction, header ); + + return src_register; +} + +struct tgsi_full_src_register +tgsi_default_full_src_register( void ) +{ + struct tgsi_full_src_register full_src_register; + + full_src_register.SrcRegister = tgsi_default_src_register(); + full_src_register.SrcRegisterExtSwz = tgsi_default_src_register_ext_swz(); + full_src_register.SrcRegisterExtMod = tgsi_default_src_register_ext_mod(); + full_src_register.SrcRegisterInd = tgsi_default_src_register(); + full_src_register.SrcRegisterDim = tgsi_default_dimension(); + full_src_register.SrcRegisterDimInd = tgsi_default_src_register(); + + return full_src_register; +} + +struct tgsi_src_register_ext_swz +tgsi_default_src_register_ext_swz( void ) +{ + struct tgsi_src_register_ext_swz src_register_ext_swz; + + src_register_ext_swz.Type = TGSI_SRC_REGISTER_EXT_TYPE_SWZ; + src_register_ext_swz.ExtSwizzleX = TGSI_EXTSWIZZLE_X; + src_register_ext_swz.ExtSwizzleY = TGSI_EXTSWIZZLE_Y; + src_register_ext_swz.ExtSwizzleZ = TGSI_EXTSWIZZLE_Z; + src_register_ext_swz.ExtSwizzleW = TGSI_EXTSWIZZLE_W; + src_register_ext_swz.NegateX = 0; + src_register_ext_swz.NegateY = 0; + src_register_ext_swz.NegateZ = 0; + src_register_ext_swz.NegateW = 0; + src_register_ext_swz.Padding = 0; + src_register_ext_swz.Extended = 0; + + return src_register_ext_swz; +} + +unsigned +tgsi_compare_src_register_ext_swz( + struct tgsi_src_register_ext_swz a, + struct tgsi_src_register_ext_swz b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_src_register_ext_swz +tgsi_build_src_register_ext_swz( + unsigned ext_swizzle_x, + unsigned ext_swizzle_y, + unsigned ext_swizzle_z, + unsigned ext_swizzle_w, + unsigned negate_x, + unsigned negate_y, + unsigned negate_z, + unsigned negate_w, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register_ext_swz src_register_ext_swz; + + assert( ext_swizzle_x <= TGSI_EXTSWIZZLE_ONE ); + assert( ext_swizzle_y <= TGSI_EXTSWIZZLE_ONE ); + assert( ext_swizzle_z <= TGSI_EXTSWIZZLE_ONE ); + assert( ext_swizzle_w <= TGSI_EXTSWIZZLE_ONE ); + assert( negate_x <= 1 ); + assert( negate_y <= 1 ); + assert( negate_z <= 1 ); + assert( negate_w <= 1 ); + + src_register_ext_swz = tgsi_default_src_register_ext_swz(); + src_register_ext_swz.ExtSwizzleX = ext_swizzle_x; + src_register_ext_swz.ExtSwizzleY = ext_swizzle_y; + src_register_ext_swz.ExtSwizzleZ = ext_swizzle_z; + src_register_ext_swz.ExtSwizzleW = ext_swizzle_w; + src_register_ext_swz.NegateX = negate_x; + src_register_ext_swz.NegateY = negate_y; + src_register_ext_swz.NegateZ = negate_z; + src_register_ext_swz.NegateW = negate_w; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return src_register_ext_swz; +} + +struct tgsi_src_register_ext_mod +tgsi_default_src_register_ext_mod( void ) +{ + struct tgsi_src_register_ext_mod src_register_ext_mod; + + src_register_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD; + src_register_ext_mod.Complement = 0; + src_register_ext_mod.Bias = 0; + src_register_ext_mod.Scale2X = 0; + src_register_ext_mod.Absolute = 0; + src_register_ext_mod.Negate = 0; + src_register_ext_mod.Padding = 0; + src_register_ext_mod.Extended = 0; + + return src_register_ext_mod; +} + +unsigned +tgsi_compare_src_register_ext_mod( + struct tgsi_src_register_ext_mod a, + struct tgsi_src_register_ext_mod b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_src_register_ext_mod +tgsi_build_src_register_ext_mod( + unsigned complement, + unsigned bias, + unsigned scale_2x, + unsigned absolute, + unsigned negate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register_ext_mod src_register_ext_mod; + + assert( complement <= 1 ); + assert( bias <= 1 ); + assert( scale_2x <= 1 ); + assert( absolute <= 1 ); + assert( negate <= 1 ); + + src_register_ext_mod = tgsi_default_src_register_ext_mod(); + src_register_ext_mod.Complement = complement; + src_register_ext_mod.Bias = bias; + src_register_ext_mod.Scale2X = scale_2x; + src_register_ext_mod.Absolute = absolute; + src_register_ext_mod.Negate = negate; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return src_register_ext_mod; +} + +struct tgsi_dimension +tgsi_default_dimension( void ) +{ + struct tgsi_dimension dimension; + + dimension.Indirect = 0; + dimension.Dimension = 0; + dimension.Padding = 0; + dimension.Index = 0; + dimension.Extended = 0; + + return dimension; +} + +struct tgsi_dimension +tgsi_build_dimension( + unsigned indirect, + unsigned index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dimension dimension; + + dimension = tgsi_default_dimension(); + dimension.Indirect = indirect; + dimension.Index = index; + + instruction_grow( instruction, header ); + + return dimension; +} + +struct tgsi_dst_register +tgsi_default_dst_register( void ) +{ + struct tgsi_dst_register dst_register; + + dst_register.File = TGSI_FILE_NULL; + dst_register.WriteMask = TGSI_WRITEMASK_XYZW; + dst_register.Indirect = 0; + dst_register.Dimension = 0; + dst_register.Index = 0; + dst_register.Padding = 0; + dst_register.Extended = 0; + + return dst_register; +} + +struct tgsi_dst_register +tgsi_build_dst_register( + unsigned file, + unsigned mask, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register dst_register; + + assert( file <= TGSI_FILE_IMMEDIATE ); + assert( mask <= TGSI_WRITEMASK_XYZW ); + assert( index >= -32768 && index <= 32767 ); + + dst_register = tgsi_default_dst_register(); + dst_register.File = file; + dst_register.WriteMask = mask; + dst_register.Index = index; + + instruction_grow( instruction, header ); + + return dst_register; +} + +struct tgsi_full_dst_register +tgsi_default_full_dst_register( void ) +{ + struct tgsi_full_dst_register full_dst_register; + + full_dst_register.DstRegister = tgsi_default_dst_register(); + full_dst_register.DstRegisterExtConcode = + tgsi_default_dst_register_ext_concode(); + full_dst_register.DstRegisterExtModulate = + tgsi_default_dst_register_ext_modulate(); + + return full_dst_register; +} + +struct tgsi_dst_register_ext_concode +tgsi_default_dst_register_ext_concode( void ) +{ + struct tgsi_dst_register_ext_concode dst_register_ext_concode; + + dst_register_ext_concode.Type = TGSI_DST_REGISTER_EXT_TYPE_CONDCODE; + dst_register_ext_concode.CondMask = TGSI_CC_TR; + dst_register_ext_concode.CondSwizzleX = TGSI_SWIZZLE_X; + dst_register_ext_concode.CondSwizzleY = TGSI_SWIZZLE_Y; + dst_register_ext_concode.CondSwizzleZ = TGSI_SWIZZLE_Z; + dst_register_ext_concode.CondSwizzleW = TGSI_SWIZZLE_W; + dst_register_ext_concode.CondSrcIndex = 0; + dst_register_ext_concode.Padding = 0; + dst_register_ext_concode.Extended = 0; + + return dst_register_ext_concode; +} + +unsigned +tgsi_compare_dst_register_ext_concode( + struct tgsi_dst_register_ext_concode a, + struct tgsi_dst_register_ext_concode b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_dst_register_ext_concode +tgsi_build_dst_register_ext_concode( + unsigned cc, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + int index, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register_ext_concode dst_register_ext_concode; + + assert( cc <= TGSI_CC_FL ); + assert( swizzle_x <= TGSI_SWIZZLE_W ); + assert( swizzle_y <= TGSI_SWIZZLE_W ); + assert( swizzle_z <= TGSI_SWIZZLE_W ); + assert( swizzle_w <= TGSI_SWIZZLE_W ); + assert( index >= -32768 && index <= 32767 ); + + dst_register_ext_concode = tgsi_default_dst_register_ext_concode(); + dst_register_ext_concode.CondMask = cc; + dst_register_ext_concode.CondSwizzleX = swizzle_x; + dst_register_ext_concode.CondSwizzleY = swizzle_y; + dst_register_ext_concode.CondSwizzleZ = swizzle_z; + dst_register_ext_concode.CondSwizzleW = swizzle_w; + dst_register_ext_concode.CondSrcIndex = index; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return dst_register_ext_concode; +} + +struct tgsi_dst_register_ext_modulate +tgsi_default_dst_register_ext_modulate( void ) +{ + struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; + + dst_register_ext_modulate.Type = TGSI_DST_REGISTER_EXT_TYPE_MODULATE; + dst_register_ext_modulate.Modulate = TGSI_MODULATE_1X; + dst_register_ext_modulate.Padding = 0; + dst_register_ext_modulate.Extended = 0; + + return dst_register_ext_modulate; +} + +unsigned +tgsi_compare_dst_register_ext_modulate( + struct tgsi_dst_register_ext_modulate a, + struct tgsi_dst_register_ext_modulate b ) +{ + a.Padding = b.Padding = 0; + a.Extended = b.Extended = 0; + return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; +} + +struct tgsi_dst_register_ext_modulate +tgsi_build_dst_register_ext_modulate( + unsigned modulate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; + + assert( modulate <= TGSI_MODULATE_EIGHTH ); + + dst_register_ext_modulate = tgsi_default_dst_register_ext_modulate(); + dst_register_ext_modulate.Modulate = modulate; + + prev_token->Extended = 1; + instruction_grow( instruction, header ); + + return dst_register_ext_modulate; +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h new file mode 100644 index 0000000000..ed25830248 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_build.h @@ -0,0 +1,332 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_BUILD_H +#define TGSI_BUILD_H + +#if defined __cplusplus +extern "C" { +#endif + +/* + * version + */ + +struct tgsi_version +tgsi_build_version( void ); + +/* + * header + */ + +struct tgsi_header +tgsi_build_header( void ); + +struct tgsi_processor +tgsi_default_processor( void ); + +struct tgsi_processor +tgsi_build_processor( + unsigned processor, + struct tgsi_header *header ); + +/* + * declaration + */ + +struct tgsi_declaration +tgsi_default_declaration( void ); + +struct tgsi_declaration +tgsi_build_declaration( + unsigned file, + unsigned usage_mask, + unsigned interpolate, + unsigned semantic, + struct tgsi_header *header ); + +struct tgsi_full_declaration +tgsi_default_full_declaration( void ); + +unsigned +tgsi_build_full_declaration( + const struct tgsi_full_declaration *full_decl, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ); + +struct tgsi_declaration_range +tgsi_default_declaration_range( void ); + +struct tgsi_declaration_range +tgsi_build_declaration_range( + unsigned first, + unsigned last, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +struct tgsi_declaration_semantic +tgsi_default_declaration_semantic( void ); + +struct tgsi_declaration_semantic +tgsi_build_declaration_semantic( + unsigned semantic_name, + unsigned semantic_index, + struct tgsi_declaration *declaration, + struct tgsi_header *header ); + +/* + * immediate + */ + +struct tgsi_immediate +tgsi_default_immediate( void ); + +struct tgsi_immediate +tgsi_build_immediate( + struct tgsi_header *header ); + +struct tgsi_full_immediate +tgsi_default_full_immediate( void ); + +struct tgsi_immediate_float32 +tgsi_build_immediate_float32( + float value, + struct tgsi_immediate *immediate, + struct tgsi_header *header ); + +unsigned +tgsi_build_full_immediate( + const struct tgsi_full_immediate *full_imm, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ); + +/* + * instruction + */ + +struct tgsi_instruction +tgsi_default_instruction( void ); + +struct tgsi_instruction +tgsi_build_instruction( + unsigned opcode, + unsigned saturate, + unsigned num_dst_regs, + unsigned num_src_regs, + struct tgsi_header *header ); + +struct tgsi_full_instruction +tgsi_default_full_instruction( void ); + +unsigned +tgsi_build_full_instruction( + const struct tgsi_full_instruction *full_inst, + struct tgsi_token *tokens, + struct tgsi_header *header, + unsigned maxsize ); + +struct tgsi_instruction_ext_nv +tgsi_default_instruction_ext_nv( void ); + +unsigned +tgsi_compare_instruction_ext_nv( + struct tgsi_instruction_ext_nv a, + struct tgsi_instruction_ext_nv b ); + +struct tgsi_instruction_ext_nv +tgsi_build_instruction_ext_nv( + unsigned precision, + unsigned cond_dst_index, + unsigned cond_flow_index, + unsigned cond_mask, + unsigned cond_swizzle_x, + unsigned cond_swizzle_y, + unsigned cond_swizzle_z, + unsigned cond_swizzle_w, + unsigned cond_dst_update, + unsigned cond_flow_update, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_instruction_ext_label +tgsi_default_instruction_ext_label( void ); + +unsigned +tgsi_compare_instruction_ext_label( + struct tgsi_instruction_ext_label a, + struct tgsi_instruction_ext_label b ); + +struct tgsi_instruction_ext_label +tgsi_build_instruction_ext_label( + unsigned label, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_instruction_ext_texture +tgsi_default_instruction_ext_texture( void ); + +unsigned +tgsi_compare_instruction_ext_texture( + struct tgsi_instruction_ext_texture a, + struct tgsi_instruction_ext_texture b ); + +struct tgsi_instruction_ext_texture +tgsi_build_instruction_ext_texture( + unsigned texture, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_src_register +tgsi_default_src_register( void ); + +struct tgsi_src_register +tgsi_build_src_register( + unsigned file, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + unsigned negate, + unsigned indirect, + unsigned dimension, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_full_src_register +tgsi_default_full_src_register( void ); + +struct tgsi_src_register_ext_swz +tgsi_default_src_register_ext_swz( void ); + +unsigned +tgsi_compare_src_register_ext_swz( + struct tgsi_src_register_ext_swz a, + struct tgsi_src_register_ext_swz b ); + +struct tgsi_src_register_ext_swz +tgsi_build_src_register_ext_swz( + unsigned ext_swizzle_x, + unsigned ext_swizzle_y, + unsigned ext_swizzle_z, + unsigned ext_swizzle_w, + unsigned negate_x, + unsigned negate_y, + unsigned negate_z, + unsigned negate_w, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_src_register_ext_mod +tgsi_default_src_register_ext_mod( void ); + +unsigned +tgsi_compare_src_register_ext_mod( + struct tgsi_src_register_ext_mod a, + struct tgsi_src_register_ext_mod b ); + +struct tgsi_src_register_ext_mod +tgsi_build_src_register_ext_mod( + unsigned complement, + unsigned bias, + unsigned scale_2x, + unsigned absolute, + unsigned negate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dimension +tgsi_default_dimension( void ); + +struct tgsi_dimension +tgsi_build_dimension( + unsigned indirect, + unsigned index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dst_register +tgsi_default_dst_register( void ); + +struct tgsi_dst_register +tgsi_build_dst_register( + unsigned file, + unsigned mask, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_full_dst_register +tgsi_default_full_dst_register( void ); + +struct tgsi_dst_register_ext_concode +tgsi_default_dst_register_ext_concode( void ); + +unsigned +tgsi_compare_dst_register_ext_concode( + struct tgsi_dst_register_ext_concode a, + struct tgsi_dst_register_ext_concode b ); + +struct tgsi_dst_register_ext_concode +tgsi_build_dst_register_ext_concode( + unsigned cc, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + int index, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +struct tgsi_dst_register_ext_modulate +tgsi_default_dst_register_ext_modulate( void ); + +unsigned +tgsi_compare_dst_register_ext_modulate( + struct tgsi_dst_register_ext_modulate a, + struct tgsi_dst_register_ext_modulate b ); + +struct tgsi_dst_register_ext_modulate +tgsi_build_dst_register_ext_modulate( + unsigned modulate, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_BUILD_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c new file mode 100644 index 0000000000..d2e6375212 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -0,0 +1,582 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "tgsi_dump.h" +#include "tgsi_iterate.h" + +struct dump_ctx +{ + struct tgsi_iterate_context iter; + + uint instno; +}; + +static void +dump_enum( + uint e, + const char **enums, + uint enum_count ) +{ + if (e >= enum_count) + debug_printf( "%u", e ); + else + debug_printf( "%s", enums[e] ); +} + +#define EOL() debug_printf( "\n" ) +#define TXT(S) debug_printf( "%s", S ) +#define CHR(C) debug_printf( "%c", C ) +#define UIX(I) debug_printf( "0x%x", I ) +#define UID(I) debug_printf( "%u", I ) +#define SID(I) debug_printf( "%d", I ) +#define FLT(F) debug_printf( "%10.4f", F ) +#define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) + +static const char *processor_type_names[] = +{ + "FRAG", + "VERT", + "GEOM" +}; + +static const char *file_names[] = +{ + "NULL", + "CONST", + "IN", + "OUT", + "TEMP", + "SAMP", + "ADDR", + "IMM" +}; + +static const char *interpolate_names[] = +{ + "CONSTANT", + "LINEAR", + "PERSPECTIVE" +}; + +static const char *semantic_names[] = +{ + "POSITION", + "COLOR", + "BCOLOR", + "FOG", + "PSIZE", + "GENERIC", + "NORMAL" +}; + +static const char *immediate_type_names[] = +{ + "FLT32" +}; + +static const char *opcode_names[TGSI_OPCODE_LAST] = +{ + "ARL", + "MOV", + "LIT", + "RCP", + "RSQ", + "EXP", + "LOG", + "MUL", + "ADD", + "DP3", + "DP4", + "DST", + "MIN", + "MAX", + "SLT", + "SGE", + "MAD", + "SUB", + "LERP", + "CND", + "CND0", + "DOT2ADD", + "INDEX", + "NEGATE", + "FRAC", + "CLAMP", + "FLOOR", + "ROUND", + "EXPBASE2", + "LOGBASE2", + "POWER", + "CROSSPRODUCT", + "MULTIPLYMATRIX", + "ABS", + "RCC", + "DPH", + "COS", + "DDX", + "DDY", + "KILP", + "PK2H", + "PK2US", + "PK4B", + "PK4UB", + "RFL", + "SEQ", + "SFL", + "SGT", + "SIN", + "SLE", + "SNE", + "STR", + "TEX", + "TXD", + "TXP", + "UP2H", + "UP2US", + "UP4B", + "UP4UB", + "X2D", + "ARA", + "ARR", + "BRA", + "CAL", + "RET", + "SSG", + "CMP", + "SCS", + "TXB", + "NRM", + "DIV", + "DP2", + "TXL", + "BRK", + "IF", + "LOOP", + "REP", + "ELSE", + "ENDIF", + "ENDLOOP", + "ENDREP", + "PUSHA", + "POPA", + "CEIL", + "I2F", + "NOT", + "TRUNC", + "SHL", + "SHR", + "AND", + "OR", + "MOD", + "XOR", + "SAD", + "TXF", + "TXQ", + "CONT", + "EMIT", + "ENDPRIM", + "BGNLOOP2", + "BGNSUB", + "ENDLOOP2", + "ENDSUB", + "NOISE1", + "NOISE2", + "NOISE3", + "NOISE4", + "NOP", + "M4X3", + "M3X4", + "M3X3", + "M3X2", + "NRM4", + "CALLNZ", + "IFC", + "BREAKC", + "KIL", + "END", + "SWZ" +}; + +static const char *swizzle_names[] = +{ + "x", + "y", + "z", + "w" +}; + +static const char *texture_names[] = +{ + "UNKNOWN", + "1D", + "2D", + "3D", + "CUBE", + "RECT", + "SHADOW1D", + "SHADOW2D", + "SHADOWRECT" +}; + +static const char *extswizzle_names[] = +{ + "x", + "y", + "z", + "w", + "0", + "1" +}; + +static const char *modulate_names[TGSI_MODULATE_COUNT] = +{ + "", + "_2X", + "_4X", + "_8X", + "_D2", + "_D4", + "_D8" +}; + +static void +_dump_register_prefix( + uint file, + uint first, + uint last ) +{ + + +} + +static void +_dump_register( + uint file, + int first, + int last ) +{ + ENM( file, file_names ); + CHR( '[' ); + SID( first ); + if (first != last) { + TXT( ".." ); + SID( last ); + } + CHR( ']' ); +} + +static void +_dump_register_ind( + uint file, + int index, + uint ind_file, + int ind_index ) +{ + ENM( file, file_names ); + CHR( '[' ); + ENM( ind_file, file_names ); + CHR( '[' ); + SID( ind_index ); + CHR( ']' ); + if (index != 0) { + if (index > 0) + CHR( '+' ); + SID( index ); + } + CHR( ']' ); +} + +static void +_dump_writemask( + uint writemask ) +{ + if (writemask != TGSI_WRITEMASK_XYZW) { + CHR( '.' ); + if (writemask & TGSI_WRITEMASK_X) + CHR( 'x' ); + if (writemask & TGSI_WRITEMASK_Y) + CHR( 'y' ); + if (writemask & TGSI_WRITEMASK_Z) + CHR( 'z' ); + if (writemask & TGSI_WRITEMASK_W) + CHR( 'w' ); + } +} + +void +tgsi_dump_declaration( + const struct tgsi_full_declaration *decl ) +{ + TXT( "\nDCL " ); + + _dump_register( + decl->Declaration.File, + decl->DeclarationRange.First, + decl->DeclarationRange.Last ); + _dump_writemask( + decl->Declaration.UsageMask ); + + if (decl->Declaration.Semantic) { + TXT( ", " ); + ENM( decl->Semantic.SemanticName, semantic_names ); + if (decl->Semantic.SemanticIndex != 0 || + decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC) { + CHR( '[' ); + UID( decl->Semantic.SemanticIndex ); + CHR( ']' ); + } + } + + TXT( ", " ); + ENM( decl->Declaration.Interpolate, interpolate_names ); +} + +static boolean +iter_declaration( + struct tgsi_iterate_context *iter, + struct tgsi_full_declaration *decl ) +{ + tgsi_dump_declaration( decl ); + return TRUE; +} + +void +tgsi_dump_immediate( + const struct tgsi_full_immediate *imm ) +{ + uint i; + + TXT( "\nIMM " ); + ENM( imm->Immediate.DataType, immediate_type_names ); + + TXT( " { " ); + for (i = 0; i < imm->Immediate.Size - 1; i++) { + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + FLT( imm->u.ImmediateFloat32[i].Float ); + break; + default: + assert( 0 ); + } + + if (i < imm->Immediate.Size - 2) + TXT( ", " ); + } + TXT( " }" ); +} + +static boolean +iter_immediate( + struct tgsi_iterate_context *iter, + struct tgsi_full_immediate *imm ) +{ + tgsi_dump_immediate( imm ); + return TRUE; +} + +void +tgsi_dump_instruction( + const struct tgsi_full_instruction *inst, + uint instno ) +{ + uint i; + boolean first_reg = TRUE; + + EOL(); + UID( instno ); + CHR( ':' ); + ENM( inst->Instruction.Opcode, opcode_names ); + + switch (inst->Instruction.Saturate) { + case TGSI_SAT_NONE: + break; + case TGSI_SAT_ZERO_ONE: + TXT( "_SAT" ); + break; + case TGSI_SAT_MINUS_PLUS_ONE: + TXT( "_SATNV" ); + break; + default: + assert( 0 ); + } + + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { + const struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + + if (!first_reg) + CHR( ',' ); + CHR( ' ' ); + + _dump_register( + dst->DstRegister.File, + dst->DstRegister.Index, + dst->DstRegister.Index ); + ENM( dst->DstRegisterExtModulate.Modulate, modulate_names ); + _dump_writemask( dst->DstRegister.WriteMask ); + + first_reg = FALSE; + } + + for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { + const struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + + if (!first_reg) + CHR( ',' ); + CHR( ' ' ); + + if (src->SrcRegisterExtMod.Negate) + TXT( "-(" ); + if (src->SrcRegisterExtMod.Absolute) + CHR( '|' ); + if (src->SrcRegisterExtMod.Scale2X) + TXT( "2*(" ); + if (src->SrcRegisterExtMod.Bias) + CHR( '(' ); + if (src->SrcRegisterExtMod.Complement) + TXT( "1-(" ); + if (src->SrcRegister.Negate) + CHR( '-' ); + + if (src->SrcRegister.Indirect) { + _dump_register_ind( + src->SrcRegister.File, + src->SrcRegister.Index, + src->SrcRegisterInd.File, + src->SrcRegisterInd.Index ); + } + else { + _dump_register( + src->SrcRegister.File, + src->SrcRegister.Index, + src->SrcRegister.Index ); + } + + if (src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || + src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || + src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || + src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W) { + CHR( '.' ); + ENM( src->SrcRegister.SwizzleX, swizzle_names ); + ENM( src->SrcRegister.SwizzleY, swizzle_names ); + ENM( src->SrcRegister.SwizzleZ, swizzle_names ); + ENM( src->SrcRegister.SwizzleW, swizzle_names ); + } + if (src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || + src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || + src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || + src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) { + CHR( '.' ); + if (src->SrcRegisterExtSwz.NegateX) + TXT("-"); + ENM( src->SrcRegisterExtSwz.ExtSwizzleX, extswizzle_names ); + if (src->SrcRegisterExtSwz.NegateY) + TXT("-"); + ENM( src->SrcRegisterExtSwz.ExtSwizzleY, extswizzle_names ); + if (src->SrcRegisterExtSwz.NegateZ) + TXT("-"); + ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, extswizzle_names ); + if (src->SrcRegisterExtSwz.NegateW) + TXT("-"); + ENM( src->SrcRegisterExtSwz.ExtSwizzleW, extswizzle_names ); + } + + if (src->SrcRegisterExtMod.Complement) + CHR( ')' ); + if (src->SrcRegisterExtMod.Bias) + TXT( ")-.5" ); + if (src->SrcRegisterExtMod.Scale2X) + CHR( ')' ); + if (src->SrcRegisterExtMod.Absolute) + CHR( '|' ); + if (src->SrcRegisterExtMod.Negate) + CHR( ')' ); + + first_reg = FALSE; + } + + if (inst->InstructionExtTexture.Texture != TGSI_TEXTURE_UNKNOWN) { + TXT( ", " ); + ENM( inst->InstructionExtTexture.Texture, texture_names ); + } + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_IF: + case TGSI_OPCODE_ELSE: + case TGSI_OPCODE_BGNLOOP2: + case TGSI_OPCODE_ENDLOOP2: + case TGSI_OPCODE_CAL: + TXT( " :" ); + UID( inst->InstructionExtLabel.Label ); + break; + } +} + +static boolean +iter_instruction( + struct tgsi_iterate_context *iter, + struct tgsi_full_instruction *inst ) +{ + struct dump_ctx *ctx = (struct dump_ctx *) iter; + + tgsi_dump_instruction( inst, ctx->instno++ ); + return TRUE; +} + +static boolean +prolog( + struct tgsi_iterate_context *ctx ) +{ + EOL(); + ENM( ctx->processor.Processor, processor_type_names ); + UID( ctx->version.MajorVersion ); + CHR( '.' ); + UID( ctx->version.MinorVersion ); + return TRUE; +} + +void +tgsi_dump( + const struct tgsi_token *tokens, + uint flags ) +{ + struct dump_ctx ctx; + + /* sanity checks */ + assert( strcmp( opcode_names[TGSI_OPCODE_CONT], "CONT" ) == 0 ); + assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); + + ctx.iter.prolog = prolog; + ctx.iter.iterate_instruction = iter_instruction; + ctx.iter.iterate_declaration = iter_declaration; + ctx.iter.iterate_immediate = iter_immediate; + ctx.iter.epilog = NULL; + + ctx.instno = 0; + + tgsi_iterate_shader( tokens, &ctx.iter ); +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.h b/src/gallium/auxiliary/tgsi/tgsi_dump.h new file mode 100644 index 0000000000..51c230b5db --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.h @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_DUMP_H +#define TGSI_DUMP_H + +#include "pipe/p_shader_tokens.h" + +#if defined __cplusplus +extern "C" { +#endif + +void +tgsi_dump( + const struct tgsi_token *tokens, + uint flags ); + +struct tgsi_full_immediate; +struct tgsi_full_instruction; +struct tgsi_full_declaration; + +void +tgsi_dump_immediate( + const struct tgsi_full_immediate *imm ); + +void +tgsi_dump_instruction( + const struct tgsi_full_instruction *inst, + uint instno ); + +void +tgsi_dump_declaration( + const struct tgsi_full_declaration *decl ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_DUMP_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c new file mode 100644 index 0000000000..eabd74bd6d --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c @@ -0,0 +1,845 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "util/u_string.h" +#include "tgsi_dump_c.h" +#include "tgsi_parse.h" +#include "tgsi_build.h" + +static void +dump_enum( + const unsigned e, + const char **enums, + const unsigned enums_count ) +{ + if (e >= enums_count) { + debug_printf( "%u", e ); + } + else { + debug_printf( "%s", enums[e] ); + } +} + +#define EOL() debug_printf( "\n" ) +#define TXT(S) debug_printf( "%s", S ) +#define CHR(C) debug_printf( "%c", C ) +#define UIX(I) debug_printf( "0x%x", I ) +#define UID(I) debug_printf( "%u", I ) +#define SID(I) debug_printf( "%d", I ) +#define FLT(F) debug_printf( "%10.4f", F ) +#define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) + +static const char *TGSI_PROCESSOR_TYPES[] = +{ + "PROCESSOR_FRAGMENT", + "PROCESSOR_VERTEX", + "PROCESSOR_GEOMETRY" +}; + +static const char *TGSI_TOKEN_TYPES[] = +{ + "TOKEN_TYPE_DECLARATION", + "TOKEN_TYPE_IMMEDIATE", + "TOKEN_TYPE_INSTRUCTION" +}; + +static const char *TGSI_FILES[] = +{ + "FILE_NULL", + "FILE_CONSTANT", + "FILE_INPUT", + "FILE_OUTPUT", + "FILE_TEMPORARY", + "FILE_SAMPLER", + "FILE_ADDRESS", + "FILE_IMMEDIATE" +}; + +static const char *TGSI_INTERPOLATES[] = +{ + "INTERPOLATE_CONSTANT", + "INTERPOLATE_LINEAR", + "INTERPOLATE_PERSPECTIVE" +}; + +static const char *TGSI_SEMANTICS[] = +{ + "SEMANTIC_POSITION", + "SEMANTIC_COLOR", + "SEMANTIC_BCOLOR", + "SEMANTIC_FOG", + "SEMANTIC_PSIZE", + "SEMANTIC_GENERIC", + "SEMANTIC_NORMAL" +}; + +static const char *TGSI_IMMS[] = +{ + "IMM_FLOAT32" +}; + +static const char *TGSI_OPCODES[TGSI_OPCODE_LAST] = +{ + "OPCODE_ARL", + "OPCODE_MOV", + "OPCODE_LIT", + "OPCODE_RCP", + "OPCODE_RSQ", + "OPCODE_EXP", + "OPCODE_LOG", + "OPCODE_MUL", + "OPCODE_ADD", + "OPCODE_DP3", + "OPCODE_DP4", + "OPCODE_DST", + "OPCODE_MIN", + "OPCODE_MAX", + "OPCODE_SLT", + "OPCODE_SGE", + "OPCODE_MAD", + "OPCODE_SUB", + "OPCODE_LERP", + "OPCODE_CND", + "OPCODE_CND0", + "OPCODE_DOT2ADD", + "OPCODE_INDEX", + "OPCODE_NEGATE", + "OPCODE_FRAC", + "OPCODE_CLAMP", + "OPCODE_FLOOR", + "OPCODE_ROUND", + "OPCODE_EXPBASE2", + "OPCODE_LOGBASE2", + "OPCODE_POWER", + "OPCODE_CROSSPRODUCT", + "OPCODE_MULTIPLYMATRIX", + "OPCODE_ABS", + "OPCODE_RCC", + "OPCODE_DPH", + "OPCODE_COS", + "OPCODE_DDX", + "OPCODE_DDY", + "OPCODE_KILP", + "OPCODE_PK2H", + "OPCODE_PK2US", + "OPCODE_PK4B", + "OPCODE_PK4UB", + "OPCODE_RFL", + "OPCODE_SEQ", + "OPCODE_SFL", + "OPCODE_SGT", + "OPCODE_SIN", + "OPCODE_SLE", + "OPCODE_SNE", + "OPCODE_STR", + "OPCODE_TEX", + "OPCODE_TXD", + "OPCODE_TXP", + "OPCODE_UP2H", + "OPCODE_UP2US", + "OPCODE_UP4B", + "OPCODE_UP4UB", + "OPCODE_X2D", + "OPCODE_ARA", + "OPCODE_ARR", + "OPCODE_BRA", + "OPCODE_CAL", + "OPCODE_RET", + "OPCODE_SSG", + "OPCODE_CMP", + "OPCODE_SCS", + "OPCODE_TXB", + "OPCODE_NRM", + "OPCODE_DIV", + "OPCODE_DP2", + "OPCODE_TXL", + "OPCODE_BRK", + "OPCODE_IF", + "OPCODE_LOOP", + "OPCODE_REP", + "OPCODE_ELSE", + "OPCODE_ENDIF", + "OPCODE_ENDLOOP", + "OPCODE_ENDREP", + "OPCODE_PUSHA", + "OPCODE_POPA", + "OPCODE_CEIL", + "OPCODE_I2F", + "OPCODE_NOT", + "OPCODE_TRUNC", + "OPCODE_SHL", + "OPCODE_SHR", + "OPCODE_AND", + "OPCODE_OR", + "OPCODE_MOD", + "OPCODE_XOR", + "OPCODE_SAD", + "OPCODE_TXF", + "OPCODE_TXQ", + "OPCODE_CONT", + "OPCODE_EMIT", + "OPCODE_ENDPRIM", + "OPCODE_BGNLOOP2", + "OPCODE_BGNSUB", + "OPCODE_ENDLOOP2", + "OPCODE_ENDSUB", + "OPCODE_NOISE1", + "OPCODE_NOISE2", + "OPCODE_NOISE3", + "OPCODE_NOISE4", + "OPCODE_NOP", + "OPCODE_M4X3", + "OPCODE_M3X4", + "OPCODE_M3X3", + "OPCODE_M3X2", + "OPCODE_NRM4", + "OPCODE_CALLNZ", + "OPCODE_IFC", + "OPCODE_BREAKC", + "OPCODE_KIL", + "OPCODE_END" +}; + +static const char *TGSI_SATS[] = +{ + "SAT_NONE", + "SAT_ZERO_ONE", + "SAT_MINUS_PLUS_ONE" +}; + +static const char *TGSI_INSTRUCTION_EXTS[] = +{ + "INSTRUCTION_EXT_TYPE_NV", + "INSTRUCTION_EXT_TYPE_LABEL", + "INSTRUCTION_EXT_TYPE_TEXTURE" +}; + +static const char *TGSI_PRECISIONS[] = +{ + "PRECISION_DEFAULT", + "PRECISION_FLOAT32", + "PRECISION_FLOAT16", + "PRECISION_FIXED12" +}; + +static const char *TGSI_CCS[] = +{ + "CC_GT", + "CC_EQ", + "CC_LT", + "CC_UN", + "CC_GE", + "CC_LE", + "CC_NE", + "CC_TR", + "CC_FL" +}; + +static const char *TGSI_SWIZZLES[] = +{ + "SWIZZLE_X", + "SWIZZLE_Y", + "SWIZZLE_Z", + "SWIZZLE_W" +}; + +static const char *TGSI_TEXTURES[] = +{ + "TEXTURE_UNKNOWN", + "TEXTURE_1D", + "TEXTURE_2D", + "TEXTURE_3D", + "TEXTURE_CUBE", + "TEXTURE_RECT", + "TEXTURE_SHADOW1D", + "TEXTURE_SHADOW2D", + "TEXTURE_SHADOWRECT" +}; + +static const char *TGSI_SRC_REGISTER_EXTS[] = +{ + "SRC_REGISTER_EXT_TYPE_SWZ", + "SRC_REGISTER_EXT_TYPE_MOD" +}; + +static const char *TGSI_EXTSWIZZLES[] = +{ + "EXTSWIZZLE_X", + "EXTSWIZZLE_Y", + "EXTSWIZZLE_Z", + "EXTSWIZZLE_W", + "EXTSWIZZLE_ZERO", + "EXTSWIZZLE_ONE" +}; + +static const char *TGSI_WRITEMASKS[] = +{ + "0", + "WRITEMASK_X", + "WRITEMASK_Y", + "WRITEMASK_XY", + "WRITEMASK_Z", + "WRITEMASK_XZ", + "WRITEMASK_YZ", + "WRITEMASK_XYZ", + "WRITEMASK_W", + "WRITEMASK_XW", + "WRITEMASK_YW", + "WRITEMASK_XYW", + "WRITEMASK_ZW", + "WRITEMASK_XZW", + "WRITEMASK_YZW", + "WRITEMASK_XYZW" +}; + +static const char *TGSI_DST_REGISTER_EXTS[] = +{ + "DST_REGISTER_EXT_TYPE_CONDCODE", + "DST_REGISTER_EXT_TYPE_MODULATE" +}; + +static const char *TGSI_MODULATES[] = +{ + "MODULATE_1X", + "MODULATE_2X", + "MODULATE_4X", + "MODULATE_8X", + "MODULATE_HALF", + "MODULATE_QUARTER", + "MODULATE_EIGHTH" +}; + +static void +dump_declaration_verbose( + struct tgsi_full_declaration *decl, + unsigned ignored, + unsigned deflt, + struct tgsi_full_declaration *fd ) +{ + TXT( "\nFile : " ); + ENM( decl->Declaration.File, TGSI_FILES ); + if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) { + TXT( "\nUsageMask : " ); + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { + CHR( 'X' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { + CHR( 'Y' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { + CHR( 'Z' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { + CHR( 'W' ); + } + } + if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) { + TXT( "\nInterpolate: " ); + ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES ); + } + if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) { + TXT( "\nSemantic : " ); + UID( decl->Declaration.Semantic ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Declaration.Padding ); + } + + EOL(); + TXT( "\nFirst: " ); + UID( decl->DeclarationRange.First ); + TXT( "\nLast : " ); + UID( decl->DeclarationRange.Last ); + + if( decl->Declaration.Semantic ) { + EOL(); + TXT( "\nSemanticName : " ); + ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS ); + TXT( "\nSemanticIndex: " ); + UID( decl->Semantic.SemanticIndex ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( decl->Semantic.Padding ); + } + } +} + +static void +dump_immediate_verbose( + struct tgsi_full_immediate *imm, + unsigned ignored ) +{ + unsigned i; + + TXT( "\nDataType : " ); + ENM( imm->Immediate.DataType, TGSI_IMMS ); + if( ignored ) { + TXT( "\nPadding : " ); + UIX( imm->Immediate.Padding ); + } + + for( i = 0; i < imm->Immediate.Size - 1; i++ ) { + EOL(); + switch( imm->Immediate.DataType ) { + case TGSI_IMM_FLOAT32: + TXT( "\nFloat: " ); + FLT( imm->u.ImmediateFloat32[i].Float ); + break; + + default: + assert( 0 ); + } + } +} + +static void +dump_instruction_verbose( + struct tgsi_full_instruction *inst, + unsigned ignored, + unsigned deflt, + struct tgsi_full_instruction *fi ) +{ + unsigned i; + + TXT( "\nOpcode : " ); + ENM( inst->Instruction.Opcode, TGSI_OPCODES ); + if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) { + TXT( "\nSaturate : " ); + ENM( inst->Instruction.Saturate, TGSI_SATS ); + } + if( deflt || fi->Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) { + TXT( "\nNumDstRegs : " ); + UID( inst->Instruction.NumDstRegs ); + } + if( deflt || fi->Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) { + TXT( "\nNumSrcRegs : " ); + UID( inst->Instruction.NumSrcRegs ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->Instruction.Padding ); + } + + if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi->InstructionExtNv ) ) { + EOL(); + TXT( "\nType : " ); + ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) { + TXT( "\nPrecision : " ); + ENM( inst->InstructionExtNv.Precision, TGSI_PRECISIONS ); + } + if( deflt || fi->InstructionExtNv.CondDstIndex != inst->InstructionExtNv.CondDstIndex ) { + TXT( "\nCondDstIndex : " ); + UID( inst->InstructionExtNv.CondDstIndex ); + } + if( deflt || fi->InstructionExtNv.CondFlowIndex != inst->InstructionExtNv.CondFlowIndex ) { + TXT( "\nCondFlowIndex : " ); + UID( inst->InstructionExtNv.CondFlowIndex ); + } + if( deflt || fi->InstructionExtNv.CondMask != inst->InstructionExtNv.CondMask ) { + TXT( "\nCondMask : " ); + ENM( inst->InstructionExtNv.CondMask, TGSI_CCS ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleX != inst->InstructionExtNv.CondSwizzleX ) { + TXT( "\nCondSwizzleX : " ); + ENM( inst->InstructionExtNv.CondSwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleY != inst->InstructionExtNv.CondSwizzleY ) { + TXT( "\nCondSwizzleY : " ); + ENM( inst->InstructionExtNv.CondSwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleZ != inst->InstructionExtNv.CondSwizzleZ ) { + TXT( "\nCondSwizzleZ : " ); + ENM( inst->InstructionExtNv.CondSwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondSwizzleW != inst->InstructionExtNv.CondSwizzleW ) { + TXT( "\nCondSwizzleW : " ); + ENM( inst->InstructionExtNv.CondSwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fi->InstructionExtNv.CondDstUpdate != inst->InstructionExtNv.CondDstUpdate ) { + TXT( "\nCondDstUpdate : " ); + UID( inst->InstructionExtNv.CondDstUpdate ); + } + if( deflt || fi->InstructionExtNv.CondFlowEnable != inst->InstructionExtNv.CondFlowEnable ) { + TXT( "\nCondFlowEnable: " ); + UID( inst->InstructionExtNv.CondFlowEnable ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtNv.Padding ); + if( deflt || fi->InstructionExtNv.Extended != inst->InstructionExtNv.Extended ) { + TXT( "\nExtended : " ); + UID( inst->InstructionExtNv.Extended ); + } + } + } + + if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) { + EOL(); + TXT( "\nType : " ); + ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) { + TXT( "\nLabel : " ); + UID( inst->InstructionExtLabel.Label ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtLabel.Padding ); + if( deflt || fi->InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) { + TXT( "\nExtended: " ); + UID( inst->InstructionExtLabel.Extended ); + } + } + } + + if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) { + EOL(); + TXT( "\nType : " ); + ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS ); + if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) { + TXT( "\nTexture : " ); + ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( inst->InstructionExtTexture.Padding ); + if( deflt || fi->InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) { + TXT( "\nExtended: " ); + UID( inst->InstructionExtTexture.Extended ); + } + } + } + + for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i]; + + EOL(); + TXT( "\nFile : " ); + ENM( dst->DstRegister.File, TGSI_FILES ); + if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) { + TXT( "\nWriteMask: " ); + ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS ); + } + if( ignored ) { + if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) { + TXT( "\nIndirect : " ); + UID( dst->DstRegister.Indirect ); + } + if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) { + TXT( "\nDimension: " ); + UID( dst->DstRegister.Dimension ); + } + } + if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) { + TXT( "\nIndex : " ); + SID( dst->DstRegister.Index ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegister.Padding ); + if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) { + TXT( "\nExtended : " ); + UID( dst->DstRegister.Extended ); + } + } + + if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) { + EOL(); + TXT( "\nType : " ); + ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS ); + if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) { + TXT( "\nCondMask : " ); + ENM( dst->DstRegisterExtConcode.CondMask, TGSI_CCS ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleX != dst->DstRegisterExtConcode.CondSwizzleX ) { + TXT( "\nCondSwizzleX: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleY != dst->DstRegisterExtConcode.CondSwizzleY ) { + TXT( "\nCondSwizzleY: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleZ != dst->DstRegisterExtConcode.CondSwizzleZ ) { + TXT( "\nCondSwizzleZ: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSwizzleW != dst->DstRegisterExtConcode.CondSwizzleW ) { + TXT( "\nCondSwizzleW: " ); + ENM( dst->DstRegisterExtConcode.CondSwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fd->DstRegisterExtConcode.CondSrcIndex != dst->DstRegisterExtConcode.CondSrcIndex ) { + TXT( "\nCondSrcIndex: " ); + UID( dst->DstRegisterExtConcode.CondSrcIndex ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegisterExtConcode.Padding ); + if( deflt || fd->DstRegisterExtConcode.Extended != dst->DstRegisterExtConcode.Extended ) { + TXT( "\nExtended : " ); + UID( dst->DstRegisterExtConcode.Extended ); + } + } + } + + if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) { + EOL(); + TXT( "\nType : " ); + ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS ); + if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) { + TXT( "\nModulate: " ); + ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( dst->DstRegisterExtModulate.Padding ); + if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) { + TXT( "\nExtended: " ); + UID( dst->DstRegisterExtModulate.Extended ); + } + } + } + } + + for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i]; + + EOL(); + TXT( "\nFile : "); + ENM( src->SrcRegister.File, TGSI_FILES ); + if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) { + TXT( "\nSwizzleX : " ); + ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) { + TXT( "\nSwizzleY : " ); + ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) { + TXT( "\nSwizzleZ : " ); + ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) { + TXT( "\nSwizzleW : " ); + ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES ); + } + if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) { + TXT( "\nNegate : " ); + UID( src->SrcRegister.Negate ); + } + if( ignored ) { + if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) { + TXT( "\nIndirect : " ); + UID( src->SrcRegister.Indirect ); + } + if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) { + TXT( "\nDimension: " ); + UID( src->SrcRegister.Dimension ); + } + } + if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) { + TXT( "\nIndex : " ); + SID( src->SrcRegister.Index ); + } + if( ignored ) { + if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegister.Extended ); + } + } + + if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) { + EOL(); + TXT( "\nType : " ); + ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS ); + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) { + TXT( "\nExtSwizzleX: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleY != src->SrcRegisterExtSwz.ExtSwizzleY ) { + TXT( "\nExtSwizzleY: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleZ != src->SrcRegisterExtSwz.ExtSwizzleZ ) { + TXT( "\nExtSwizzleZ: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleW != src->SrcRegisterExtSwz.ExtSwizzleW ) { + TXT( "\nExtSwizzleW: " ); + ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateX != src->SrcRegisterExtSwz.NegateX ) { + TXT( "\nNegateX : " ); + UID( src->SrcRegisterExtSwz.NegateX ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateY != src->SrcRegisterExtSwz.NegateY ) { + TXT( "\nNegateY : " ); + UID( src->SrcRegisterExtSwz.NegateY ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateZ != src->SrcRegisterExtSwz.NegateZ ) { + TXT( "\nNegateZ : " ); + UID( src->SrcRegisterExtSwz.NegateZ ); + } + if( deflt || fs->SrcRegisterExtSwz.NegateW != src->SrcRegisterExtSwz.NegateW ) { + TXT( "\nNegateW : " ); + UID( src->SrcRegisterExtSwz.NegateW ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( src->SrcRegisterExtSwz.Padding ); + if( deflt || fs->SrcRegisterExtSwz.Extended != src->SrcRegisterExtSwz.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegisterExtSwz.Extended ); + } + } + } + + if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) { + EOL(); + TXT( "\nType : " ); + ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS ); + if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) { + TXT( "\nComplement: " ); + UID( src->SrcRegisterExtMod.Complement ); + } + if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) { + TXT( "\nBias : " ); + UID( src->SrcRegisterExtMod.Bias ); + } + if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) { + TXT( "\nScale2X : " ); + UID( src->SrcRegisterExtMod.Scale2X ); + } + if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) { + TXT( "\nAbsolute : " ); + UID( src->SrcRegisterExtMod.Absolute ); + } + if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) { + TXT( "\nNegate : " ); + UID( src->SrcRegisterExtMod.Negate ); + } + if( ignored ) { + TXT( "\nPadding : " ); + UIX( src->SrcRegisterExtMod.Padding ); + if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) { + TXT( "\nExtended : " ); + UID( src->SrcRegisterExtMod.Extended ); + } + } + } + } +} + +void +tgsi_dump_c( + const struct tgsi_token *tokens, + uint flags ) +{ + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + uint ignored = flags & TGSI_DUMP_C_IGNORED; + uint deflt = flags & TGSI_DUMP_C_DEFAULT; + uint instno = 0; + + /* sanity checks */ + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); + + tgsi_parse_init( &parse, tokens ); + + TXT( "tgsi-dump begin -----------------" ); + + TXT( "\nMajorVersion: " ); + UID( parse.FullVersion.Version.MajorVersion ); + TXT( "\nMinorVersion: " ); + UID( parse.FullVersion.Version.MinorVersion ); + EOL(); + + TXT( "\nHeaderSize: " ); + UID( parse.FullHeader.Header.HeaderSize ); + TXT( "\nBodySize : " ); + UID( parse.FullHeader.Header.BodySize ); + TXT( "\nProcessor : " ); + ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); + EOL(); + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + + while( !tgsi_parse_end_of_tokens( &parse ) ) { + tgsi_parse_token( &parse ); + + TXT( "\nType : " ); + ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES ); + if( ignored ) { + TXT( "\nSize : " ); + UID( parse.FullToken.Token.Size ); + if( deflt || parse.FullToken.Token.Extended ) { + TXT( "\nExtended : " ); + UID( parse.FullToken.Token.Extended ); + } + } + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + dump_declaration_verbose( + &parse.FullToken.FullDeclaration, + ignored, + deflt, + &fd ); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + dump_immediate_verbose( + &parse.FullToken.FullImmediate, + ignored ); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + dump_instruction_verbose( + &parse.FullToken.FullInstruction, + ignored, + deflt, + &fi ); + break; + + default: + assert( 0 ); + } + + EOL(); + } + + TXT( "\ntgsi-dump end -------------------\n" ); + + tgsi_parse_free( &parse ); +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump_c.h b/src/gallium/auxiliary/tgsi/tgsi_dump_c.h new file mode 100644 index 0000000000..d91cd35b3b --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_dump_c.h @@ -0,0 +1,49 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_DUMP_C_H +#define TGSI_DUMP_C_H + +#include "pipe/p_shader_tokens.h" + +#if defined __cplusplus +extern "C" { +#endif + +#define TGSI_DUMP_C_IGNORED 1 +#define TGSI_DUMP_C_DEFAULT 2 + +void +tgsi_dump_c( + const struct tgsi_token *tokens, + uint flags ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_DUMP_C_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c new file mode 100644 index 0000000000..8b430548bc --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -0,0 +1,2522 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * TGSI interpretor/executor. + * + * Flow control information: + * + * Since we operate on 'quads' (4 pixels or 4 vertices in parallel) + * flow control statements (IF/ELSE/ENDIF, LOOP/ENDLOOP) require special + * care since a condition may be true for some quad components but false + * for other components. + * + * We basically execute all statements (even if they're in the part of + * an IF/ELSE clause that's "not taken") and use a special mask to + * control writing to destination registers. This is the ExecMask. + * See store_dest(). + * + * The ExecMask is computed from three other masks (CondMask, LoopMask and + * ContMask) which are controlled by the flow control instructions (namely: + * (IF/ELSE/ENDIF, LOOP/ENDLOOP and CONT). + * + * + * Authors: + * Michal Krol + * Brian Paul + */ + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" +#include "tgsi_exec.h" + +#define TILE_TOP_LEFT 0 +#define TILE_TOP_RIGHT 1 +#define TILE_BOTTOM_LEFT 2 +#define TILE_BOTTOM_RIGHT 3 + +/* + * Shorthand locations of various utility registers (_I = Index, _C = Channel) + */ +#define TEMP_0_I TGSI_EXEC_TEMP_00000000_I +#define TEMP_0_C TGSI_EXEC_TEMP_00000000_C +#define TEMP_7F_I TGSI_EXEC_TEMP_7FFFFFFF_I +#define TEMP_7F_C TGSI_EXEC_TEMP_7FFFFFFF_C +#define TEMP_80_I TGSI_EXEC_TEMP_80000000_I +#define TEMP_80_C TGSI_EXEC_TEMP_80000000_C +#define TEMP_FF_I TGSI_EXEC_TEMP_FFFFFFFF_I +#define TEMP_FF_C TGSI_EXEC_TEMP_FFFFFFFF_C +#define TEMP_1_I TGSI_EXEC_TEMP_ONE_I +#define TEMP_1_C TGSI_EXEC_TEMP_ONE_C +#define TEMP_2_I TGSI_EXEC_TEMP_TWO_I +#define TEMP_2_C TGSI_EXEC_TEMP_TWO_C +#define TEMP_128_I TGSI_EXEC_TEMP_128_I +#define TEMP_128_C TGSI_EXEC_TEMP_128_C +#define TEMP_M128_I TGSI_EXEC_TEMP_MINUS_128_I +#define TEMP_M128_C TGSI_EXEC_TEMP_MINUS_128_C +#define TEMP_KILMASK_I TGSI_EXEC_TEMP_KILMASK_I +#define TEMP_KILMASK_C TGSI_EXEC_TEMP_KILMASK_C +#define TEMP_OUTPUT_I TGSI_EXEC_TEMP_OUTPUT_I +#define TEMP_OUTPUT_C TGSI_EXEC_TEMP_OUTPUT_C +#define TEMP_PRIMITIVE_I TGSI_EXEC_TEMP_PRIMITIVE_I +#define TEMP_PRIMITIVE_C TGSI_EXEC_TEMP_PRIMITIVE_C +#define TEMP_3_I TGSI_EXEC_TEMP_THREE_I +#define TEMP_3_C TGSI_EXEC_TEMP_THREE_C +#define TEMP_HALF_I TGSI_EXEC_TEMP_HALF_I +#define TEMP_HALF_C TGSI_EXEC_TEMP_HALF_C +#define TEMP_R0 TGSI_EXEC_TEMP_R0 + +#define FOR_EACH_CHANNEL(CHAN)\ + for (CHAN = 0; CHAN < 4; CHAN++) + +#define IS_CHANNEL_ENABLED(INST, CHAN)\ + ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) + +#define IS_CHANNEL_ENABLED2(INST, CHAN)\ + ((INST).FullDstRegisters[1].DstRegister.WriteMask & (1 << (CHAN))) + +#define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\ + FOR_EACH_CHANNEL( CHAN )\ + if (IS_CHANNEL_ENABLED( INST, CHAN )) + +#define FOR_EACH_ENABLED_CHANNEL2(INST, CHAN)\ + FOR_EACH_CHANNEL( CHAN )\ + if (IS_CHANNEL_ENABLED2( INST, CHAN )) + + +/** The execution mask depends on the conditional mask and the loop mask */ +#define UPDATE_EXEC_MASK(MACH) \ + MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask + + +#define CHAN_X 0 +#define CHAN_Y 1 +#define CHAN_Z 2 +#define CHAN_W 3 + + + +/** + * Initialize machine state by expanding tokens to full instructions, + * allocating temporary storage, setting up constants, etc. + * After this, we can call tgsi_exec_machine_run() many times. + */ +void +tgsi_exec_machine_bind_shader( + struct tgsi_exec_machine *mach, + const struct tgsi_token *tokens, + uint numSamplers, + struct tgsi_sampler *samplers) +{ + uint k; + struct tgsi_parse_context parse; + struct tgsi_exec_labels *labels = &mach->Labels; + struct tgsi_full_instruction *instructions; + struct tgsi_full_declaration *declarations; + uint maxInstructions = 10, numInstructions = 0; + uint maxDeclarations = 10, numDeclarations = 0; + uint instno = 0; + +#if 0 + tgsi_dump(tokens, 0); +#endif + + mach->Tokens = tokens; + mach->Samplers = samplers; + + k = tgsi_parse_init (&parse, mach->Tokens); + if (k != TGSI_PARSE_OK) { + debug_printf( "Problem parsing!\n" ); + return; + } + + mach->Processor = parse.FullHeader.Processor.Processor; + mach->ImmLimit = 0; + labels->count = 0; + + declarations = (struct tgsi_full_declaration *) + MALLOC( maxDeclarations * sizeof(struct tgsi_full_declaration) ); + + if (!declarations) { + return; + } + + instructions = (struct tgsi_full_instruction *) + MALLOC( maxInstructions * sizeof(struct tgsi_full_instruction) ); + + if (!instructions) { + FREE( declarations ); + return; + } + + while( !tgsi_parse_end_of_tokens( &parse ) ) { + uint pointer = parse.Position; + uint i; + + tgsi_parse_token( &parse ); + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + /* save expanded declaration */ + if (numDeclarations == maxDeclarations) { + declarations = REALLOC(declarations, + maxDeclarations + * sizeof(struct tgsi_full_declaration), + (maxDeclarations + 10) + * sizeof(struct tgsi_full_declaration)); + maxDeclarations += 10; + } + memcpy(declarations + numDeclarations, + &parse.FullToken.FullDeclaration, + sizeof(declarations[0])); + numDeclarations++; + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; + assert( size % 4 == 0 ); + assert( mach->ImmLimit + size / 4 <= TGSI_EXEC_NUM_IMMEDIATES ); + + for( i = 0; i < size; i++ ) { + mach->Imms[mach->ImmLimit + i / 4][i % 4] = + parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; + } + mach->ImmLimit += size / 4; + } + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + assert( labels->count < MAX_LABELS ); + + labels->labels[labels->count][0] = instno; + labels->labels[labels->count][1] = pointer; + labels->count++; + + /* save expanded instruction */ + if (numInstructions == maxInstructions) { + instructions = REALLOC(instructions, + maxInstructions + * sizeof(struct tgsi_full_instruction), + (maxInstructions + 10) + * sizeof(struct tgsi_full_instruction)); + maxInstructions += 10; + } + memcpy(instructions + numInstructions, + &parse.FullToken.FullInstruction, + sizeof(instructions[0])); + numInstructions++; + break; + + default: + assert( 0 ); + } + } + tgsi_parse_free (&parse); + + if (mach->Declarations) { + FREE( mach->Declarations ); + } + mach->Declarations = declarations; + mach->NumDeclarations = numDeclarations; + + if (mach->Instructions) { + FREE( mach->Instructions ); + } + mach->Instructions = instructions; + mach->NumInstructions = numInstructions; +} + + +void +tgsi_exec_machine_init( + struct tgsi_exec_machine *mach ) +{ + uint i; + + mach->Temps = (struct tgsi_exec_vector *) tgsi_align_128bit( mach->_Temps); + mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR]; + + /* Setup constants. */ + for( i = 0; i < 4; i++ ) { + mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].u[i] = 0x00000000; + mach->Temps[TEMP_7F_I].xyzw[TEMP_7F_C].u[i] = 0x7FFFFFFF; + mach->Temps[TEMP_80_I].xyzw[TEMP_80_C].u[i] = 0x80000000; + mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].u[i] = 0xFFFFFFFF; + mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].f[i] = 1.0f; + mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].f[i] = 2.0f; + mach->Temps[TEMP_128_I].xyzw[TEMP_128_C].f[i] = 128.0f; + mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C].f[i] = -128.0f; + mach->Temps[TEMP_3_I].xyzw[TEMP_3_C].f[i] = 3.0f; + mach->Temps[TEMP_HALF_I].xyzw[TEMP_HALF_C].f[i] = 0.5f; + } +} + + +void +tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach) +{ + if (mach->Instructions) { + FREE(mach->Instructions); + mach->Instructions = NULL; + mach->NumInstructions = 0; + } + if (mach->Declarations) { + FREE(mach->Declarations); + mach->Declarations = NULL; + mach->NumDeclarations = 0; + } +} + + +static void +micro_abs( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = fabsf( src->f[0] ); + dst->f[1] = fabsf( src->f[1] ); + dst->f[2] = fabsf( src->f[2] ); + dst->f[3] = fabsf( src->f[3] ); +} + +static void +micro_add( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] + src1->f[0]; + dst->f[1] = src0->f[1] + src1->f[1]; + dst->f[2] = src0->f[2] + src1->f[2]; + dst->f[3] = src0->f[3] + src1->f[3]; +} + +static void +micro_iadd( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] + src1->i[0]; + dst->i[1] = src0->i[1] + src1->i[1]; + dst->i[2] = src0->i[2] + src1->i[2]; + dst->i[3] = src0->i[3] + src1->i[3]; +} + +static void +micro_and( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] & src1->u[0]; + dst->u[1] = src0->u[1] & src1->u[1]; + dst->u[2] = src0->u[2] & src1->u[2]; + dst->u[3] = src0->u[3] & src1->u[3]; +} + +static void +micro_ceil( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = ceilf( src->f[0] ); + dst->f[1] = ceilf( src->f[1] ); + dst->f[2] = ceilf( src->f[2] ); + dst->f[3] = ceilf( src->f[3] ); +} + +static void +micro_cos( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = cosf( src->f[0] ); + dst->f[1] = cosf( src->f[1] ); + dst->f[2] = cosf( src->f[2] ); + dst->f[3] = cosf( src->f[3] ); +} + +static void +micro_ddx( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = + dst->f[1] = + dst->f[2] = + dst->f[3] = src->f[TILE_BOTTOM_RIGHT] - src->f[TILE_BOTTOM_LEFT]; +} + +static void +micro_ddy( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = + dst->f[1] = + dst->f[2] = + dst->f[3] = src->f[TILE_TOP_LEFT] - src->f[TILE_BOTTOM_LEFT]; +} + +static void +micro_div( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] / src1->f[0]; + dst->f[1] = src0->f[1] / src1->f[1]; + dst->f[2] = src0->f[2] / src1->f[2]; + dst->f[3] = src0->f[3] / src1->f[3]; +} + +static void +micro_udiv( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] / src1->u[0]; + dst->u[1] = src0->u[1] / src1->u[1]; + dst->u[2] = src0->u[2] / src1->u[2]; + dst->u[3] = src0->u[3] / src1->u[3]; +} + +static void +micro_eq( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] == src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] == src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] == src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] == src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_ieq( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->i[0] = src0->i[0] == src1->i[0] ? src2->i[0] : src3->i[0]; + dst->i[1] = src0->i[1] == src1->i[1] ? src2->i[1] : src3->i[1]; + dst->i[2] = src0->i[2] == src1->i[2] ? src2->i[2] : src3->i[2]; + dst->i[3] = src0->i[3] == src1->i[3] ? src2->i[3] : src3->i[3]; +} + +static void +micro_exp2( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src) +{ + dst->f[0] = powf( 2.0f, src->f[0] ); + dst->f[1] = powf( 2.0f, src->f[1] ); + dst->f[2] = powf( 2.0f, src->f[2] ); + dst->f[3] = powf( 2.0f, src->f[3] ); +} + +static void +micro_f2it( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->i[0] = (int) src->f[0]; + dst->i[1] = (int) src->f[1]; + dst->i[2] = (int) src->f[2]; + dst->i[3] = (int) src->f[3]; +} + +static void +micro_f2ut( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->u[0] = (uint) src->f[0]; + dst->u[1] = (uint) src->f[1]; + dst->u[2] = (uint) src->f[2]; + dst->u[3] = (uint) src->f[3]; +} + +static void +micro_flr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = floorf( src->f[0] ); + dst->f[1] = floorf( src->f[1] ); + dst->f[2] = floorf( src->f[2] ); + dst->f[3] = floorf( src->f[3] ); +} + +static void +micro_frc( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = src->f[0] - floorf( src->f[0] ); + dst->f[1] = src->f[1] - floorf( src->f[1] ); + dst->f[2] = src->f[2] - floorf( src->f[2] ); + dst->f[3] = src->f[3] - floorf( src->f[3] ); +} + +static void +micro_ge( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] >= src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] >= src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] >= src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] >= src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_i2f( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) src->i[0]; + dst->f[1] = (float) src->i[1]; + dst->f[2] = (float) src->i[2]; + dst->f[3] = (float) src->i[3]; +} + +static void +micro_lg2( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = logf( src->f[0] ) * 1.442695f; + dst->f[1] = logf( src->f[1] ) * 1.442695f; + dst->f[2] = logf( src->f[2] ) * 1.442695f; + dst->f[3] = logf( src->f[3] ) * 1.442695f; +} + +static void +micro_le( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] <= src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] <= src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] <= src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] <= src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_lt( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->f[0] = src0->f[0] < src1->f[0] ? src2->f[0] : src3->f[0]; + dst->f[1] = src0->f[1] < src1->f[1] ? src2->f[1] : src3->f[1]; + dst->f[2] = src0->f[2] < src1->f[2] ? src2->f[2] : src3->f[2]; + dst->f[3] = src0->f[3] < src1->f[3] ? src2->f[3] : src3->f[3]; +} + +static void +micro_ilt( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->i[0] = src0->i[0] < src1->i[0] ? src2->i[0] : src3->i[0]; + dst->i[1] = src0->i[1] < src1->i[1] ? src2->i[1] : src3->i[1]; + dst->i[2] = src0->i[2] < src1->i[2] ? src2->i[2] : src3->i[2]; + dst->i[3] = src0->i[3] < src1->i[3] ? src2->i[3] : src3->i[3]; +} + +static void +micro_ult( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2, + const union tgsi_exec_channel *src3 ) +{ + dst->u[0] = src0->u[0] < src1->u[0] ? src2->u[0] : src3->u[0]; + dst->u[1] = src0->u[1] < src1->u[1] ? src2->u[1] : src3->u[1]; + dst->u[2] = src0->u[2] < src1->u[2] ? src2->u[2] : src3->u[2]; + dst->u[3] = src0->u[3] < src1->u[3] ? src2->u[3] : src3->u[3]; +} + +static void +micro_max( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] > src1->f[0] ? src0->f[0] : src1->f[0]; + dst->f[1] = src0->f[1] > src1->f[1] ? src0->f[1] : src1->f[1]; + dst->f[2] = src0->f[2] > src1->f[2] ? src0->f[2] : src1->f[2]; + dst->f[3] = src0->f[3] > src1->f[3] ? src0->f[3] : src1->f[3]; +} + +static void +micro_imax( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] > src1->i[0] ? src0->i[0] : src1->i[0]; + dst->i[1] = src0->i[1] > src1->i[1] ? src0->i[1] : src1->i[1]; + dst->i[2] = src0->i[2] > src1->i[2] ? src0->i[2] : src1->i[2]; + dst->i[3] = src0->i[3] > src1->i[3] ? src0->i[3] : src1->i[3]; +} + +static void +micro_umax( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] > src1->u[0] ? src0->u[0] : src1->u[0]; + dst->u[1] = src0->u[1] > src1->u[1] ? src0->u[1] : src1->u[1]; + dst->u[2] = src0->u[2] > src1->u[2] ? src0->u[2] : src1->u[2]; + dst->u[3] = src0->u[3] > src1->u[3] ? src0->u[3] : src1->u[3]; +} + +static void +micro_min( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] < src1->f[0] ? src0->f[0] : src1->f[0]; + dst->f[1] = src0->f[1] < src1->f[1] ? src0->f[1] : src1->f[1]; + dst->f[2] = src0->f[2] < src1->f[2] ? src0->f[2] : src1->f[2]; + dst->f[3] = src0->f[3] < src1->f[3] ? src0->f[3] : src1->f[3]; +} + +static void +micro_imin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] < src1->i[0] ? src0->i[0] : src1->i[0]; + dst->i[1] = src0->i[1] < src1->i[1] ? src0->i[1] : src1->i[1]; + dst->i[2] = src0->i[2] < src1->i[2] ? src0->i[2] : src1->i[2]; + dst->i[3] = src0->i[3] < src1->i[3] ? src0->i[3] : src1->i[3]; +} + +static void +micro_umin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] < src1->u[0] ? src0->u[0] : src1->u[0]; + dst->u[1] = src0->u[1] < src1->u[1] ? src0->u[1] : src1->u[1]; + dst->u[2] = src0->u[2] < src1->u[2] ? src0->u[2] : src1->u[2]; + dst->u[3] = src0->u[3] < src1->u[3] ? src0->u[3] : src1->u[3]; +} + +static void +micro_umod( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] % src1->u[0]; + dst->u[1] = src0->u[1] % src1->u[1]; + dst->u[2] = src0->u[2] % src1->u[2]; + dst->u[3] = src0->u[3] % src1->u[3]; +} + +static void +micro_mul( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] * src1->f[0]; + dst->f[1] = src0->f[1] * src1->f[1]; + dst->f[2] = src0->f[2] * src1->f[2]; + dst->f[3] = src0->f[3] * src1->f[3]; +} + +static void +micro_imul( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] * src1->i[0]; + dst->i[1] = src0->i[1] * src1->i[1]; + dst->i[2] = src0->i[2] * src1->i[2]; + dst->i[3] = src0->i[3] * src1->i[3]; +} + +static void +micro_imul64( + union tgsi_exec_channel *dst0, + union tgsi_exec_channel *dst1, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst1->i[0] = src0->i[0] * src1->i[0]; + dst1->i[1] = src0->i[1] * src1->i[1]; + dst1->i[2] = src0->i[2] * src1->i[2]; + dst1->i[3] = src0->i[3] * src1->i[3]; + dst0->i[0] = 0; + dst0->i[1] = 0; + dst0->i[2] = 0; + dst0->i[3] = 0; +} + +static void +micro_umul64( + union tgsi_exec_channel *dst0, + union tgsi_exec_channel *dst1, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst1->u[0] = src0->u[0] * src1->u[0]; + dst1->u[1] = src0->u[1] * src1->u[1]; + dst1->u[2] = src0->u[2] * src1->u[2]; + dst1->u[3] = src0->u[3] * src1->u[3]; + dst0->u[0] = 0; + dst0->u[1] = 0; + dst0->u[2] = 0; + dst0->u[3] = 0; +} + +static void +micro_movc( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1, + const union tgsi_exec_channel *src2 ) +{ + dst->u[0] = src0->u[0] ? src1->u[0] : src2->u[0]; + dst->u[1] = src0->u[1] ? src1->u[1] : src2->u[1]; + dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2]; + dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3]; +} + +static void +micro_neg( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = -src->f[0]; + dst->f[1] = -src->f[1]; + dst->f[2] = -src->f[2]; + dst->f[3] = -src->f[3]; +} + +static void +micro_ineg( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->i[0] = -src->i[0]; + dst->i[1] = -src->i[1]; + dst->i[2] = -src->i[2]; + dst->i[3] = -src->i[3]; +} + +static void +micro_not( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->u[0] = ~src->u[0]; + dst->u[1] = ~src->u[1]; + dst->u[2] = ~src->u[2]; + dst->u[3] = ~src->u[3]; +} + +static void +micro_or( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] | src1->u[0]; + dst->u[1] = src0->u[1] | src1->u[1]; + dst->u[2] = src0->u[2] | src1->u[2]; + dst->u[3] = src0->u[3] | src1->u[3]; +} + +static void +micro_pow( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = powf( src0->f[0], src1->f[0] ); + dst->f[1] = powf( src0->f[1], src1->f[1] ); + dst->f[2] = powf( src0->f[2], src1->f[2] ); + dst->f[3] = powf( src0->f[3], src1->f[3] ); +} + +static void +micro_rnd( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = floorf( src->f[0] + 0.5f ); + dst->f[1] = floorf( src->f[1] + 0.5f ); + dst->f[2] = floorf( src->f[2] + 0.5f ); + dst->f[3] = floorf( src->f[3] + 0.5f ); +} + +static void +micro_shl( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] << src1->i[0]; + dst->i[1] = src0->i[1] << src1->i[1]; + dst->i[2] = src0->i[2] << src1->i[2]; + dst->i[3] = src0->i[3] << src1->i[3]; +} + +static void +micro_ishr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->i[0] = src0->i[0] >> src1->i[0]; + dst->i[1] = src0->i[1] >> src1->i[1]; + dst->i[2] = src0->i[2] >> src1->i[2]; + dst->i[3] = src0->i[3] >> src1->i[3]; +} + +static void +micro_trunc( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0 ) +{ + dst->f[0] = (float) (int) src0->f[0]; + dst->f[1] = (float) (int) src0->f[1]; + dst->f[2] = (float) (int) src0->f[2]; + dst->f[3] = (float) (int) src0->f[3]; +} + +static void +micro_ushr( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] >> src1->u[0]; + dst->u[1] = src0->u[1] >> src1->u[1]; + dst->u[2] = src0->u[2] >> src1->u[2]; + dst->u[3] = src0->u[3] >> src1->u[3]; +} + +static void +micro_sin( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = sinf( src->f[0] ); + dst->f[1] = sinf( src->f[1] ); + dst->f[2] = sinf( src->f[2] ); + dst->f[3] = sinf( src->f[3] ); +} + +static void +micro_sqrt( union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = sqrtf( src->f[0] ); + dst->f[1] = sqrtf( src->f[1] ); + dst->f[2] = sqrtf( src->f[2] ); + dst->f[3] = sqrtf( src->f[3] ); +} + +static void +micro_sub( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->f[0] = src0->f[0] - src1->f[0]; + dst->f[1] = src0->f[1] - src1->f[1]; + dst->f[2] = src0->f[2] - src1->f[2]; + dst->f[3] = src0->f[3] - src1->f[3]; +} + +static void +micro_u2f( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src ) +{ + dst->f[0] = (float) src->u[0]; + dst->f[1] = (float) src->u[1]; + dst->f[2] = (float) src->u[2]; + dst->f[3] = (float) src->u[3]; +} + +static void +micro_xor( + union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src0, + const union tgsi_exec_channel *src1 ) +{ + dst->u[0] = src0->u[0] ^ src1->u[0]; + dst->u[1] = src0->u[1] ^ src1->u[1]; + dst->u[2] = src0->u[2] ^ src1->u[2]; + dst->u[3] = src0->u[3] ^ src1->u[3]; +} + +static void +fetch_src_file_channel( + const struct tgsi_exec_machine *mach, + const uint file, + const uint swizzle, + const union tgsi_exec_channel *index, + union tgsi_exec_channel *chan ) +{ + switch( swizzle ) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + switch( file ) { + case TGSI_FILE_CONSTANT: + chan->f[0] = mach->Consts[index->i[0]][swizzle]; + chan->f[1] = mach->Consts[index->i[1]][swizzle]; + chan->f[2] = mach->Consts[index->i[2]][swizzle]; + chan->f[3] = mach->Consts[index->i[3]][swizzle]; + break; + + case TGSI_FILE_INPUT: + chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Inputs[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_TEMPORARY: + assert(index->i[0] < TGSI_EXEC_NUM_TEMPS); + chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Temps[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_IMMEDIATE: + assert( index->i[0] < (int) mach->ImmLimit ); + chan->f[0] = mach->Imms[index->i[0]][swizzle]; + assert( index->i[1] < (int) mach->ImmLimit ); + chan->f[1] = mach->Imms[index->i[1]][swizzle]; + assert( index->i[2] < (int) mach->ImmLimit ); + chan->f[2] = mach->Imms[index->i[2]][swizzle]; + assert( index->i[3] < (int) mach->ImmLimit ); + chan->f[3] = mach->Imms[index->i[3]][swizzle]; + break; + + case TGSI_FILE_ADDRESS: + chan->u[0] = mach->Addrs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Addrs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Addrs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Addrs[index->i[3]].xyzw[swizzle].u[3]; + break; + + case TGSI_FILE_OUTPUT: + /* vertex/fragment output vars can be read too */ + chan->u[0] = mach->Outputs[index->i[0]].xyzw[swizzle].u[0]; + chan->u[1] = mach->Outputs[index->i[1]].xyzw[swizzle].u[1]; + chan->u[2] = mach->Outputs[index->i[2]].xyzw[swizzle].u[2]; + chan->u[3] = mach->Outputs[index->i[3]].xyzw[swizzle].u[3]; + break; + + default: + assert( 0 ); + } + break; + + case TGSI_EXTSWIZZLE_ZERO: + *chan = mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]; + break; + + case TGSI_EXTSWIZZLE_ONE: + *chan = mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]; + break; + + default: + assert( 0 ); + } +} + +static void +fetch_source( + const struct tgsi_exec_machine *mach, + union tgsi_exec_channel *chan, + const struct tgsi_full_src_register *reg, + const uint chan_index ) +{ + union tgsi_exec_channel index; + uint swizzle; + + index.i[0] = + index.i[1] = + index.i[2] = + index.i[3] = reg->SrcRegister.Index; + + if (reg->SrcRegister.Indirect) { + union tgsi_exec_channel index2; + union tgsi_exec_channel indir_index; + + index2.i[0] = + index2.i[1] = + index2.i[2] = + index2.i[3] = reg->SrcRegisterInd.Index; + + swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterInd, CHAN_X ); + fetch_src_file_channel( + mach, + reg->SrcRegisterInd.File, + swizzle, + &index2, + &indir_index ); + + index.i[0] += indir_index.i[0]; + index.i[1] += indir_index.i[1]; + index.i[2] += indir_index.i[2]; + index.i[3] += indir_index.i[3]; + } + + if( reg->SrcRegister.Dimension ) { + switch( reg->SrcRegister.File ) { + case TGSI_FILE_INPUT: + index.i[0] *= 17; + index.i[1] *= 17; + index.i[2] *= 17; + index.i[3] *= 17; + break; + case TGSI_FILE_CONSTANT: + index.i[0] *= 4096; + index.i[1] *= 4096; + index.i[2] *= 4096; + index.i[3] *= 4096; + break; + default: + assert( 0 ); + } + + index.i[0] += reg->SrcRegisterDim.Index; + index.i[1] += reg->SrcRegisterDim.Index; + index.i[2] += reg->SrcRegisterDim.Index; + index.i[3] += reg->SrcRegisterDim.Index; + + if (reg->SrcRegisterDim.Indirect) { + union tgsi_exec_channel index2; + union tgsi_exec_channel indir_index; + + index2.i[0] = + index2.i[1] = + index2.i[2] = + index2.i[3] = reg->SrcRegisterDimInd.Index; + + swizzle = tgsi_util_get_src_register_swizzle( ®->SrcRegisterDimInd, CHAN_X ); + fetch_src_file_channel( + mach, + reg->SrcRegisterDimInd.File, + swizzle, + &index2, + &indir_index ); + + index.i[0] += indir_index.i[0]; + index.i[1] += indir_index.i[1]; + index.i[2] += indir_index.i[2]; + index.i[3] += indir_index.i[3]; + } + } + + swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); + fetch_src_file_channel( + mach, + reg->SrcRegister.File, + swizzle, + &index, + chan ); + + switch (tgsi_util_get_full_src_register_sign_mode( reg, chan_index )) { + case TGSI_UTIL_SIGN_CLEAR: + micro_abs( chan, chan ); + break; + + case TGSI_UTIL_SIGN_SET: + micro_abs( chan, chan ); + micro_neg( chan, chan ); + break; + + case TGSI_UTIL_SIGN_TOGGLE: + micro_neg( chan, chan ); + break; + + case TGSI_UTIL_SIGN_KEEP: + break; + } + + if (reg->SrcRegisterExtMod.Complement) { + micro_sub( chan, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], chan ); + } +} + +static void +store_dest( + struct tgsi_exec_machine *mach, + const union tgsi_exec_channel *chan, + const struct tgsi_full_dst_register *reg, + const struct tgsi_full_instruction *inst, + uint chan_index ) +{ + union tgsi_exec_channel *dst; + + switch( reg->DstRegister.File ) { + case TGSI_FILE_NULL: + return; + + case TGSI_FILE_OUTPUT: + dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] + + reg->DstRegister.Index].xyzw[chan_index]; + break; + + case TGSI_FILE_TEMPORARY: + assert(reg->DstRegister.Index < TGSI_EXEC_NUM_TEMPS); + dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index]; + break; + + case TGSI_FILE_ADDRESS: + dst = &mach->Addrs[reg->DstRegister.Index].xyzw[chan_index]; + break; + + default: + assert( 0 ); + return; + } + + switch (inst->Instruction.Saturate) + { + case TGSI_SAT_NONE: + if (mach->ExecMask & 0x1) + dst->i[0] = chan->i[0]; + if (mach->ExecMask & 0x2) + dst->i[1] = chan->i[1]; + if (mach->ExecMask & 0x4) + dst->i[2] = chan->i[2]; + if (mach->ExecMask & 0x8) + dst->i[3] = chan->i[3]; + break; + + case TGSI_SAT_ZERO_ONE: + /* XXX need to obey ExecMask here */ + micro_max(dst, chan, &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]); + micro_min(dst, dst, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]); + break; + + case TGSI_SAT_MINUS_PLUS_ONE: + assert( 0 ); + break; + + default: + assert( 0 ); + } +} + +#define FETCH(VAL,INDEX,CHAN)\ + fetch_source (mach, VAL, &inst->FullSrcRegisters[INDEX], CHAN) + +#define STORE(VAL,INDEX,CHAN)\ + store_dest (mach, VAL, &inst->FullDstRegisters[INDEX], inst, CHAN ) + + +/** + * Execute ARB-style KIL which is predicated by a src register. + * Kill fragment if any of the four values is less than zero. + */ +static void +exec_kilp(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + uint uniquemask; + uint chan_index; + uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ + union tgsi_exec_channel r[1]; + + /* This mask stores component bits that were already tested. Note that + * we test if the value is less than zero, so 1.0 and 0.0 need not to be + * tested. */ + uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); + + for (chan_index = 0; chan_index < 4; chan_index++) + { + uint swizzle; + uint i; + + /* unswizzle channel */ + swizzle = tgsi_util_get_full_src_register_extswizzle ( + &inst->FullSrcRegisters[0], + chan_index); + + /* check if the component has not been already tested */ + if (uniquemask & (1 << swizzle)) + continue; + uniquemask |= 1 << swizzle; + + FETCH(&r[0], 0, chan_index); + for (i = 0; i < 4; i++) + if (r[0].f[i] < 0.0f) + kilmask |= 1 << i; + } + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; +} + + +/* + * Fetch a texel using STR texture coordinates. + */ +static void +fetch_texel( struct tgsi_sampler *sampler, + const union tgsi_exec_channel *s, + const union tgsi_exec_channel *t, + const union tgsi_exec_channel *p, + float lodbias, /* XXX should be float[4] */ + union tgsi_exec_channel *r, + union tgsi_exec_channel *g, + union tgsi_exec_channel *b, + union tgsi_exec_channel *a ) +{ + uint j; + float rgba[NUM_CHANNELS][QUAD_SIZE]; + + sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, rgba); + + for (j = 0; j < 4; j++) { + r->f[j] = rgba[0][j]; + g->f[j] = rgba[1][j]; + b->f[j] = rgba[2][j]; + a->f[j] = rgba[3][j]; + } +} + + +static void +exec_tex(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst, + boolean biasLod, + boolean projected) +{ + const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; + union tgsi_exec_channel r[8]; + uint chan_index; + float lodBias; + + /* debug_printf("Sampler %u unit %u\n", sampler, unit); */ + + switch (inst->InstructionExtTexture.Texture) { + case TGSI_TEXTURE_1D: + + FETCH(&r[0], 0, CHAN_X); + + if (projected) { + FETCH(&r[1], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[1] ); + } + + if (biasLod) { + FETCH(&r[1], 0, CHAN_W); + lodBias = r[2].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], NULL, NULL, lodBias, /* S, T, P, BIAS */ + &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */ + break; + + case TGSI_TEXTURE_2D: + case TGSI_TEXTURE_RECT: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + if (projected) { + FETCH(&r[3], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[3] ); + micro_div( &r[1], &r[1], &r[3] ); + micro_div( &r[2], &r[2], &r[3] ); + } + + if (biasLod) { + FETCH(&r[3], 0, CHAN_W); + lodBias = r[3].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], &r[1], &r[2], lodBias, /* inputs */ + &r[0], &r[1], &r[2], &r[3]); /* outputs */ + break; + + case TGSI_TEXTURE_3D: + case TGSI_TEXTURE_CUBE: + + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 0, CHAN_Z); + + if (projected) { + FETCH(&r[3], 0, CHAN_W); + micro_div( &r[0], &r[0], &r[3] ); + micro_div( &r[1], &r[1], &r[3] ); + micro_div( &r[2], &r[2], &r[3] ); + } + + if (biasLod) { + FETCH(&r[3], 0, CHAN_W); + lodBias = r[3].f[0]; + } + else + lodBias = 0.0; + + fetch_texel(&mach->Samplers[unit], + &r[0], &r[1], &r[2], lodBias, + &r[0], &r[1], &r[2], &r[3]); + break; + + default: + assert (0); + } + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[chan_index], 0, chan_index ); + } +} + + +/** + * Evaluate a constant-valued coefficient at the position of the + * current quad. + */ +static void +eval_constant_coef( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + mach->Inputs[attrib].xyzw[chan].f[i] = mach->InterpCoefs[attrib].a0[chan]; + } +} + +/** + * Evaluate a linear-valued coefficient at the position of the + * current quad. + */ +static void +eval_linear_coef( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + const float x = mach->QuadPos.xyzw[0].f[0]; + const float y = mach->QuadPos.xyzw[1].f[0]; + const float dadx = mach->InterpCoefs[attrib].dadx[chan]; + const float dady = mach->InterpCoefs[attrib].dady[chan]; + const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; + mach->Inputs[attrib].xyzw[chan].f[0] = a0; + mach->Inputs[attrib].xyzw[chan].f[1] = a0 + dadx; + mach->Inputs[attrib].xyzw[chan].f[2] = a0 + dady; + mach->Inputs[attrib].xyzw[chan].f[3] = a0 + dadx + dady; +} + +/** + * Evaluate a perspective-valued coefficient at the position of the + * current quad. + */ +static void +eval_perspective_coef( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + const float x = mach->QuadPos.xyzw[0].f[0]; + const float y = mach->QuadPos.xyzw[1].f[0]; + const float dadx = mach->InterpCoefs[attrib].dadx[chan]; + const float dady = mach->InterpCoefs[attrib].dady[chan]; + const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y; + const float *w = mach->QuadPos.xyzw[3].f; + /* divide by W here */ + mach->Inputs[attrib].xyzw[chan].f[0] = a0 / w[0]; + mach->Inputs[attrib].xyzw[chan].f[1] = (a0 + dadx) / w[1]; + mach->Inputs[attrib].xyzw[chan].f[2] = (a0 + dady) / w[2]; + mach->Inputs[attrib].xyzw[chan].f[3] = (a0 + dadx + dady) / w[3]; +} + + +typedef void (* eval_coef_func)( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ); + +static void +exec_declaration( + struct tgsi_exec_machine *mach, + const struct tgsi_full_declaration *decl ) +{ + if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { + if( decl->Declaration.File == TGSI_FILE_INPUT ) { + unsigned first, last, mask; + eval_coef_func eval; + + first = decl->DeclarationRange.First; + last = decl->DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + switch( decl->Declaration.Interpolate ) { + case TGSI_INTERPOLATE_CONSTANT: + eval = eval_constant_coef; + break; + + case TGSI_INTERPOLATE_LINEAR: + eval = eval_linear_coef; + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + eval = eval_perspective_coef; + break; + + default: + assert( 0 ); + } + + if( mask == TGSI_WRITEMASK_XYZW ) { + unsigned i, j; + + for( i = first; i <= last; i++ ) { + for( j = 0; j < NUM_CHANNELS; j++ ) { + eval( mach, i, j ); + } + } + } + else { + unsigned i, j; + + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + for( i = first; i <= last; i++ ) { + eval( mach, i, j ); + } + } + } + } + } + } +} + +static void +exec_instruction( + struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst, + int *pc ) +{ + uint chan_index; + union tgsi_exec_channel r[8]; + + (*pc)++; + + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_f2it( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOV: + case TGSI_OPCODE_SWZ: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_LIT: + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y ) || IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[0], 0, CHAN_X ); + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + micro_max( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, CHAN_Y ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[1], 0, CHAN_Y ); + micro_max( &r[1], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + + FETCH( &r[2], 0, CHAN_W ); + micro_min( &r[2], &r[2], &mach->Temps[TEMP_128_I].xyzw[TEMP_128_C] ); + micro_max( &r[2], &r[2], &mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C] ); + micro_pow( &r[1], &r[1], &r[2] ); + micro_lt( &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, CHAN_Z ); + } + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_RCP: + /* TGSI_OPCODE_RECIP */ + FETCH( &r[0], 0, CHAN_X ); + micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_RSQ: + /* TGSI_OPCODE_RECIPSQRT */ + FETCH( &r[0], 0, CHAN_X ); + micro_sqrt( &r[0], &r[0] ); + micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXP: + FETCH( &r[0], 0, CHAN_X ); + micro_flr( &r[1], &r[0] ); /* r1 = floor(r0) */ + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + micro_exp2( &r[2], &r[1] ); /* r2 = 2 ^ r1 */ + STORE( &r[2], 0, CHAN_X ); /* store r2 */ + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + micro_sub( &r[2], &r[0], &r[1] ); /* r2 = r0 - r1 */ + STORE( &r[2], 0, CHAN_Y ); /* store r2 */ + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + micro_exp2( &r[2], &r[0] ); /* r2 = 2 ^ r0 */ + STORE( &r[2], 0, CHAN_Z ); /* store r2 */ + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_LOG: + FETCH( &r[0], 0, CHAN_X ); + micro_abs( &r[2], &r[0] ); /* r2 = abs(r0) */ + micro_lg2( &r[1], &r[2] ); /* r1 = lg2(r2) */ + micro_flr( &r[0], &r[1] ); /* r0 = floor(r1) */ + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &r[0], 0, CHAN_X ); + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + micro_exp2( &r[0], &r[0] ); /* r0 = 2 ^ r0 */ + micro_div( &r[0], &r[2], &r[0] ); /* r0 = r2 / r0 */ + STORE( &r[0], 0, CHAN_Y ); + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + STORE( &r[1], 0, CHAN_Z ); + } + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MUL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) + { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + micro_mul( &r[0], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_ADD: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_add( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP3: + /* TGSI_OPCODE_DOT3 */ + FETCH( &r[0], 0, CHAN_X ); + FETCH( &r[1], 1, CHAN_X ); + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Y ); + FETCH( &r[2], 1, CHAN_Y ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Z ); + FETCH( &r[2], 1, CHAN_Z ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP4: + /* TGSI_OPCODE_DOT4 */ + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 1, CHAN_Y); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Z); + FETCH(&r[2], 1, CHAN_Z); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_W); + FETCH(&r[2], 1, CHAN_W); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DST: + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + FETCH( &r[0], 0, CHAN_Y ); + FETCH( &r[1], 1, CHAN_Y); + micro_mul( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, CHAN_Y ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( &r[0], 0, CHAN_Z ); + STORE( &r[0], 0, CHAN_Z ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + FETCH( &r[0], 1, CHAN_W ); + STORE( &r[0], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MIN: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + /* XXX use micro_min()?? */ + micro_lt( &r[0], &r[0], &r[1], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_MAX: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + /* XXX use micro_max()?? */ + micro_lt( &r[0], &r[0], &r[1], &r[1], &r[0] ); + + STORE(&r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLT: + /* TGSI_OPCODE_SETLT */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_lt( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SGE: + /* TGSI_OPCODE_SETGE */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_ge( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MAD: + /* TGSI_OPCODE_MADD */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_mul( &r[0], &r[0], &r[1] ); + FETCH( &r[1], 2, chan_index ); + micro_add( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SUB: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + + micro_sub( &r[0], &r[0], &r[1] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_LERP: + /* TGSI_OPCODE_LRP */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + FETCH(&r[2], 2, chan_index); + + micro_sub( &r[1], &r[1], &r[2] ); + micro_mul( &r[0], &r[0], &r[1] ); + micro_add( &r[0], &r[0], &r[2] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_CND: + assert (0); + break; + + case TGSI_OPCODE_CND0: + assert (0); + break; + + case TGSI_OPCODE_DOT2ADD: + /* TGSI_OPCODE_DP2A */ + assert (0); + break; + + case TGSI_OPCODE_INDEX: + assert (0); + break; + + case TGSI_OPCODE_NEGATE: + assert (0); + break; + + case TGSI_OPCODE_FRAC: + /* TGSI_OPCODE_FRC */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_frc( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_CLAMP: + assert (0); + break; + + case TGSI_OPCODE_FLOOR: + /* TGSI_OPCODE_FLR */ + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_flr( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_ROUND: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_rnd( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXPBASE2: + /* TGSI_OPCODE_EX2 */ + FETCH(&r[0], 0, CHAN_X); + + micro_pow( &r[0], &mach->Temps[TEMP_2_I].xyzw[TEMP_2_C], &r[0] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_LOGBASE2: + /* TGSI_OPCODE_LG2 */ + FETCH( &r[0], 0, CHAN_X ); + micro_lg2( &r[0], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_POWER: + /* TGSI_OPCODE_POW */ + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_pow( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_CROSSPRODUCT: + /* TGSI_OPCODE_XPD */ + FETCH(&r[0], 0, CHAN_Y); + FETCH(&r[1], 1, CHAN_Z); + + micro_mul( &r[2], &r[0], &r[1] ); + + FETCH(&r[3], 0, CHAN_Z); + FETCH(&r[4], 1, CHAN_Y); + + micro_mul( &r[5], &r[3], &r[4] ); + micro_sub( &r[2], &r[2], &r[5] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( &r[2], 0, CHAN_X ); + } + + FETCH(&r[2], 1, CHAN_X); + + micro_mul( &r[3], &r[3], &r[2] ); + + FETCH(&r[5], 0, CHAN_X); + + micro_mul( &r[1], &r[1], &r[5] ); + micro_sub( &r[3], &r[3], &r[1] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { + STORE( &r[3], 0, CHAN_Y ); + } + + micro_mul( &r[5], &r[5], &r[4] ); + micro_mul( &r[0], &r[0], &r[2] ); + micro_sub( &r[5], &r[5], &r[0] ); + + if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { + STORE( &r[5], 0, CHAN_Z ); + } + + if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MULTIPLYMATRIX: + assert (0); + break; + + case TGSI_OPCODE_ABS: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + + micro_abs( &r[0], &r[0] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_RCC: + assert (0); + break; + + case TGSI_OPCODE_DPH: + FETCH(&r[0], 0, CHAN_X); + FETCH(&r[1], 1, CHAN_X); + + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Y); + FETCH(&r[2], 1, CHAN_Y); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 0, CHAN_Z); + FETCH(&r[2], 1, CHAN_Z); + + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FETCH(&r[1], 1, CHAN_W); + + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_COS: + FETCH(&r[0], 0, CHAN_X); + + micro_cos( &r[0], &r[0] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDX: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_ddx( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDY: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_ddy( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_KILP: + exec_kilp (mach, inst); + break; + + case TGSI_OPCODE_KIL: + /* for enabled ExecMask bits, set the killed bit */ + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= mach->ExecMask; + break; + + case TGSI_OPCODE_PK2H: + assert (0); + break; + + case TGSI_OPCODE_PK2US: + assert (0); + break; + + case TGSI_OPCODE_PK4B: + assert (0); + break; + + case TGSI_OPCODE_PK4UB: + assert (0); + break; + + case TGSI_OPCODE_RFL: + assert (0); + break; + + case TGSI_OPCODE_SEQ: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_eq( &r[0], &r[0], &r[1], + &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], + &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SFL: + assert (0); + break; + + case TGSI_OPCODE_SGT: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_le( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SIN: + FETCH( &r[0], 0, CHAN_X ); + micro_sin( &r[0], &r[0] ); + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLE: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_le( &r[0], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SNE: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_eq( &r[0], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_STR: + assert (0); + break; + + case TGSI_OPCODE_TEX: + /* simple texture lookup */ + /* src[0] = texcoord */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, FALSE, FALSE); + break; + + case TGSI_OPCODE_TXB: + /* Texture lookup with lod bias */ + /* src[0] = texcoord (src[0].w = LOD bias) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, TRUE, FALSE); + break; + + case TGSI_OPCODE_TXD: + /* Texture lookup with explict partial derivatives */ + /* src[0] = texcoord */ + /* src[1] = d[strq]/dx */ + /* src[2] = d[strq]/dy */ + /* src[3] = sampler unit */ + assert (0); + break; + + case TGSI_OPCODE_TXL: + /* Texture lookup with explit LOD */ + /* src[0] = texcoord (src[0].w = LOD) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, TRUE, FALSE); + break; + + case TGSI_OPCODE_TXP: + /* Texture lookup with projection */ + /* src[0] = texcoord (src[0].w = projection) */ + /* src[1] = sampler unit */ + exec_tex(mach, inst, FALSE, TRUE); + break; + + case TGSI_OPCODE_UP2H: + assert (0); + break; + + case TGSI_OPCODE_UP2US: + assert (0); + break; + + case TGSI_OPCODE_UP4B: + assert (0); + break; + + case TGSI_OPCODE_UP4UB: + assert (0); + break; + + case TGSI_OPCODE_X2D: + assert (0); + break; + + case TGSI_OPCODE_ARA: + assert (0); + break; + + case TGSI_OPCODE_ARR: + assert (0); + break; + + case TGSI_OPCODE_BRA: + assert (0); + break; + + case TGSI_OPCODE_CAL: + /* skip the call if no execution channels are enabled */ + if (mach->ExecMask) { + /* do the call */ + + /* push the Cond, Loop, Cont stacks */ + assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); + mach->CondStack[mach->CondStackTop++] = mach->CondMask; + assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; + assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->ContStack[mach->ContStackTop++] = mach->ContMask; + + assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING); + mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask; + + /* note that PC was already incremented above */ + mach->CallStack[mach->CallStackTop++] = *pc; + *pc = inst->InstructionExtLabel.Label; + } + break; + + case TGSI_OPCODE_RET: + mach->FuncMask &= ~mach->ExecMask; + UPDATE_EXEC_MASK(mach); + + if (mach->ExecMask == 0x0) { + /* really return now (otherwise, keep executing */ + + if (mach->CallStackTop == 0) { + /* returning from main() */ + *pc = -1; + return; + } + *pc = mach->CallStack[--mach->CallStackTop]; + + /* pop the Cond, Loop, Cont stacks */ + assert(mach->CondStackTop > 0); + mach->CondMask = mach->CondStack[--mach->CondStackTop]; + assert(mach->LoopStackTop > 0); + mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[--mach->ContStackTop]; + assert(mach->FuncStackTop > 0); + mach->FuncMask = mach->FuncStack[--mach->FuncStackTop]; + + UPDATE_EXEC_MASK(mach); + } + break; + + case TGSI_OPCODE_SSG: + assert (0); + break; + + case TGSI_OPCODE_CMP: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH(&r[0], 0, chan_index); + FETCH(&r[1], 1, chan_index); + FETCH(&r[2], 2, chan_index); + + micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] ); + + STORE(&r[0], 0, chan_index); + } + break; + + case TGSI_OPCODE_SCS: + if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) || IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + FETCH( &r[0], 0, CHAN_X ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) ) { + micro_cos( &r[1], &r[0] ); + STORE( &r[1], 0, CHAN_X ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + micro_sin( &r[1], &r[0] ); + STORE( &r[1], 0, CHAN_Y ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + STORE( &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], 0, CHAN_Z ); + } + if( IS_CHANNEL_ENABLED( *inst, CHAN_W ) ) { + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_NRM: + assert (0); + break; + + case TGSI_OPCODE_DIV: + assert( 0 ); + break; + + case TGSI_OPCODE_DP2: + FETCH( &r[0], 0, CHAN_X ); + FETCH( &r[1], 1, CHAN_X ); + micro_mul( &r[0], &r[0], &r[1] ); + + FETCH( &r[1], 0, CHAN_Y ); + FETCH( &r[2], 1, CHAN_Y ); + micro_mul( &r[1], &r[1], &r[2] ); + micro_add( &r[0], &r[0], &r[1] ); + + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_IF: + /* push CondMask */ + assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING); + mach->CondStack[mach->CondStackTop++] = mach->CondMask; + FETCH( &r[0], 0, CHAN_X ); + /* update CondMask */ + if( ! r[0].u[0] ) { + mach->CondMask &= ~0x1; + } + if( ! r[0].u[1] ) { + mach->CondMask &= ~0x2; + } + if( ! r[0].u[2] ) { + mach->CondMask &= ~0x4; + } + if( ! r[0].u[3] ) { + mach->CondMask &= ~0x8; + } + UPDATE_EXEC_MASK(mach); + /* Todo: If CondMask==0, jump to ELSE */ + break; + + case TGSI_OPCODE_ELSE: + /* invert CondMask wrt previous mask */ + { + uint prevMask; + assert(mach->CondStackTop > 0); + prevMask = mach->CondStack[mach->CondStackTop - 1]; + mach->CondMask = ~mach->CondMask & prevMask; + UPDATE_EXEC_MASK(mach); + /* Todo: If CondMask==0, jump to ENDIF */ + } + break; + + case TGSI_OPCODE_ENDIF: + /* pop CondMask */ + assert(mach->CondStackTop > 0); + mach->CondMask = mach->CondStack[--mach->CondStackTop]; + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_END: + /* halt execution */ + *pc = -1; + break; + + case TGSI_OPCODE_REP: + assert (0); + break; + + case TGSI_OPCODE_ENDREP: + assert (0); + break; + + case TGSI_OPCODE_PUSHA: + assert (0); + break; + + case TGSI_OPCODE_POPA: + assert (0); + break; + + case TGSI_OPCODE_CEIL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_ceil( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_I2F: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_i2f( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_NOT: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_not( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_TRUNC: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + micro_trunc( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SHL: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_shl( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SHR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_ishr( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_AND: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_and( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_OR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_or( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_MOD: + assert (0); + break; + + case TGSI_OPCODE_XOR: + FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( &r[0], 0, chan_index ); + FETCH( &r[1], 1, chan_index ); + micro_xor( &r[0], &r[0], &r[1] ); + STORE( &r[0], 0, chan_index ); + } + break; + + case TGSI_OPCODE_SAD: + assert (0); + break; + + case TGSI_OPCODE_TXF: + assert (0); + break; + + case TGSI_OPCODE_TXQ: + assert (0); + break; + + case TGSI_OPCODE_EMIT: + mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16; + mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++; + break; + + case TGSI_OPCODE_ENDPRIM: + mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++; + mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0; + break; + + case TGSI_OPCODE_LOOP: + /* fall-through (for now) */ + case TGSI_OPCODE_BGNLOOP2: + /* push LoopMask and ContMasks */ + assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask; + assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING); + mach->ContStack[mach->ContStackTop++] = mach->ContMask; + break; + + case TGSI_OPCODE_ENDLOOP: + /* fall-through (for now at least) */ + case TGSI_OPCODE_ENDLOOP2: + /* Restore ContMask, but don't pop */ + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[mach->ContStackTop - 1]; + UPDATE_EXEC_MASK(mach); + if (mach->ExecMask) { + /* repeat loop: jump to instruction just past BGNLOOP */ + *pc = inst->InstructionExtLabel.Label + 1; + } + else { + /* exit loop: pop LoopMask */ + assert(mach->LoopStackTop > 0); + mach->LoopMask = mach->LoopStack[--mach->LoopStackTop]; + /* pop ContMask */ + assert(mach->ContStackTop > 0); + mach->ContMask = mach->ContStack[--mach->ContStackTop]; + } + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_BRK: + /* turn off loop channels for each enabled exec channel */ + mach->LoopMask &= ~mach->ExecMask; + /* Todo: if mach->LoopMask == 0, jump to end of loop */ + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_CONT: + /* turn off cont channels for each enabled exec channel */ + mach->ContMask &= ~mach->ExecMask; + /* Todo: if mach->LoopMask == 0, jump to end of loop */ + UPDATE_EXEC_MASK(mach); + break; + + case TGSI_OPCODE_BGNSUB: + /* no-op */ + break; + + case TGSI_OPCODE_ENDSUB: + /* no-op */ + break; + + case TGSI_OPCODE_NOISE1: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE2: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE3: + assert( 0 ); + break; + + case TGSI_OPCODE_NOISE4: + assert( 0 ); + break; + + case TGSI_OPCODE_NOP: + break; + + default: + assert( 0 ); + } +} + + +/** + * Run TGSI interpreter. + * \return bitmask of "alive" quad components + */ +uint +tgsi_exec_machine_run( struct tgsi_exec_machine *mach ) +{ + uint i; + int pc = 0; + + mach->CondMask = 0xf; + mach->LoopMask = 0xf; + mach->ContMask = 0xf; + mach->FuncMask = 0xf; + mach->ExecMask = 0xf; + + mach->CondStackTop = 0; /* temporarily subvert this assertion */ + assert(mach->CondStackTop == 0); + assert(mach->LoopStackTop == 0); + assert(mach->ContStackTop == 0); + assert(mach->CallStackTop == 0); + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0; + mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] = 0; + + if( mach->Processor == TGSI_PROCESSOR_GEOMETRY ) { + mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0] = 0; + mach->Primitives[0] = 0; + } + + + /* execute declarations (interpolants) */ + for (i = 0; i < mach->NumDeclarations; i++) { + exec_declaration( mach, mach->Declarations+i ); + } + + /* execute instructions, until pc is set to -1 */ + while (pc != -1) { + assert(pc < (int) mach->NumInstructions); + exec_instruction( mach, mach->Instructions + pc, &pc ); + } + +#if 0 + /* we scale from floats in [0,1] to Zbuffer ints in sp_quad_depth_test.c */ + if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) { + /* + * Scale back depth component. + */ + for (i = 0; i < 4; i++) + mach->Outputs[0].xyzw[2].f[i] *= ctx->DrawBuffer->_DepthMaxF; + } +#endif + + return ~mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0]; +} + + diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h new file mode 100644 index 0000000000..4f30650b07 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -0,0 +1,253 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#if !defined TGSI_EXEC_H +#define TGSI_EXEC_H + +#include "pipe/p_compiler.h" + +#if defined __cplusplus +extern "C" { +#endif + +#define MAX_LABELS 1024 + +#define NUM_CHANNELS 4 /* R,G,B,A */ +#define QUAD_SIZE 4 /* 4 pixel/quad */ + +/** + * Registers may be treated as float, signed int or unsigned int. + */ +union tgsi_exec_channel +{ + float f[QUAD_SIZE]; + int i[QUAD_SIZE]; + unsigned u[QUAD_SIZE]; +}; + +/** + * A vector[RGBA] of channels[4 pixels] + */ +struct tgsi_exec_vector +{ + union tgsi_exec_channel xyzw[NUM_CHANNELS]; +}; + +/** + * For fragment programs, information for computing fragment input + * values from plane equation of the triangle/line. + */ +struct tgsi_interp_coef +{ + float a0[NUM_CHANNELS]; /* in an xyzw layout */ + float dadx[NUM_CHANNELS]; + float dady[NUM_CHANNELS]; +}; + + +struct softpipe_tile_cache; /**< Opaque to TGSI */ + +/** + * Information for sampling textures, which must be implemented + * by code outside the TGSI executor. + */ +struct tgsi_sampler +{ + const struct pipe_sampler_state *state; + struct pipe_texture *texture; + /** Get samples for four fragments in a quad */ + void (*get_samples)(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]); + void *pipe; /*XXX temporary*/ + struct softpipe_tile_cache *cache; +}; + +/** + * For branching/calling subroutines. + */ +struct tgsi_exec_labels +{ + unsigned labels[MAX_LABELS][2]; + unsigned count; +}; + + +#define TGSI_EXEC_NUM_TEMPS 128 +#define TGSI_EXEC_NUM_TEMP_EXTRAS 6 +#define TGSI_EXEC_NUM_IMMEDIATES 256 + +/* + * Locations of various utility registers (_I = Index, _C = Channel) + */ +#define TGSI_EXEC_TEMP_00000000_I (TGSI_EXEC_NUM_TEMPS + 0) +#define TGSI_EXEC_TEMP_00000000_C 0 + +#define TGSI_EXEC_TEMP_7FFFFFFF_I (TGSI_EXEC_NUM_TEMPS + 0) +#define TGSI_EXEC_TEMP_7FFFFFFF_C 1 + +#define TGSI_EXEC_TEMP_80000000_I (TGSI_EXEC_NUM_TEMPS + 0) +#define TGSI_EXEC_TEMP_80000000_C 2 + +#define TGSI_EXEC_TEMP_FFFFFFFF_I (TGSI_EXEC_NUM_TEMPS + 0) +#define TGSI_EXEC_TEMP_FFFFFFFF_C 3 + +#define TGSI_EXEC_TEMP_ONE_I (TGSI_EXEC_NUM_TEMPS + 1) +#define TGSI_EXEC_TEMP_ONE_C 0 + +#define TGSI_EXEC_TEMP_TWO_I (TGSI_EXEC_NUM_TEMPS + 1) +#define TGSI_EXEC_TEMP_TWO_C 1 + +#define TGSI_EXEC_TEMP_128_I (TGSI_EXEC_NUM_TEMPS + 1) +#define TGSI_EXEC_TEMP_128_C 2 + +#define TGSI_EXEC_TEMP_MINUS_128_I (TGSI_EXEC_NUM_TEMPS + 1) +#define TGSI_EXEC_TEMP_MINUS_128_C 3 + +#define TGSI_EXEC_TEMP_KILMASK_I (TGSI_EXEC_NUM_TEMPS + 2) +#define TGSI_EXEC_TEMP_KILMASK_C 0 + +#define TGSI_EXEC_TEMP_OUTPUT_I (TGSI_EXEC_NUM_TEMPS + 2) +#define TGSI_EXEC_TEMP_OUTPUT_C 1 + +#define TGSI_EXEC_TEMP_PRIMITIVE_I (TGSI_EXEC_NUM_TEMPS + 2) +#define TGSI_EXEC_TEMP_PRIMITIVE_C 2 + +#define TGSI_EXEC_TEMP_THREE_I (TGSI_EXEC_NUM_TEMPS + 2) +#define TGSI_EXEC_TEMP_THREE_C 3 + +#define TGSI_EXEC_TEMP_HALF_I (TGSI_EXEC_NUM_TEMPS + 3) +#define TGSI_EXEC_TEMP_HALF_C 0 + +#define TGSI_EXEC_TEMP_R0 (TGSI_EXEC_NUM_TEMPS + 4) + +#define TGSI_EXEC_TEMP_ADDR (TGSI_EXEC_NUM_TEMPS + 5) + + +#define TGSI_EXEC_MAX_COND_NESTING 20 +#define TGSI_EXEC_MAX_LOOP_NESTING 20 +#define TGSI_EXEC_MAX_CALL_NESTING 20 + +/** + * Run-time virtual machine state for executing TGSI shader. + */ +struct tgsi_exec_machine +{ + /* Total = program temporaries + internal temporaries + * + 1 padding to align to 16 bytes + */ + struct tgsi_exec_vector _Temps[TGSI_EXEC_NUM_TEMPS + + TGSI_EXEC_NUM_TEMP_EXTRAS + 1]; + + /* + * This will point to _Temps after aligning to 16B boundary. + */ + struct tgsi_exec_vector *Temps; + struct tgsi_exec_vector *Addrs; + + struct tgsi_sampler *Samplers; + + float Imms[TGSI_EXEC_NUM_IMMEDIATES][4]; + unsigned ImmLimit; + const float (*Consts)[4]; + struct tgsi_exec_vector *Inputs; + struct tgsi_exec_vector *Outputs; + const struct tgsi_token *Tokens; + unsigned Processor; + + /* GEOMETRY processor only. */ + unsigned *Primitives; + + /* FRAGMENT processor only. */ + const struct tgsi_interp_coef *InterpCoefs; + struct tgsi_exec_vector QuadPos; + + /* Conditional execution masks */ + uint CondMask; /**< For IF/ELSE/ENDIF */ + uint LoopMask; /**< For BGNLOOP/ENDLOOP */ + uint ContMask; /**< For loop CONT statements */ + uint FuncMask; /**< For function calls */ + uint ExecMask; /**< = CondMask & LoopMask */ + + /** Condition mask stack (for nested conditionals) */ + uint CondStack[TGSI_EXEC_MAX_COND_NESTING]; + int CondStackTop; + + /** Loop mask stack (for nested loops) */ + uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING]; + int LoopStackTop; + + /** Loop continue mask stack (see comments in tgsi_exec.c) */ + uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING]; + int ContStackTop; + + /** Function execution mask stack (for executing subroutine code) */ + uint FuncStack[TGSI_EXEC_MAX_CALL_NESTING]; + int FuncStackTop; + + /** Function call stack for saving/restoring the program counter */ + uint CallStack[TGSI_EXEC_MAX_CALL_NESTING]; + int CallStackTop; + + struct tgsi_full_instruction *Instructions; + uint NumInstructions; + + struct tgsi_full_declaration *Declarations; + uint NumDeclarations; + + struct tgsi_exec_labels Labels; +}; + +void +tgsi_exec_machine_init( + struct tgsi_exec_machine *mach ); + + +void +tgsi_exec_machine_bind_shader( + struct tgsi_exec_machine *mach, + const struct tgsi_token *tokens, + uint numSamplers, + struct tgsi_sampler *samplers); + +uint +tgsi_exec_machine_run( + struct tgsi_exec_machine *mach ); + + +void +tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach); + + +#if defined __cplusplus +} /* extern "C" */ +#endif + +#endif /* TGSI_EXEC_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_iterate.c b/src/gallium/auxiliary/tgsi/tgsi_iterate.c new file mode 100644 index 0000000000..5371a88b96 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_iterate.c @@ -0,0 +1,85 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "tgsi_iterate.h" + +boolean +tgsi_iterate_shader( + const struct tgsi_token *tokens, + struct tgsi_iterate_context *ctx ) +{ + struct tgsi_parse_context parse; + + if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) + return FALSE; + + ctx->processor = parse.FullHeader.Processor; + ctx->version = parse.FullVersion.Version; + + if (ctx->prolog) + if (!ctx->prolog( ctx )) + goto fail; + + while (!tgsi_parse_end_of_tokens( &parse )) { + tgsi_parse_token( &parse ); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + if (ctx->iterate_instruction) + if (!ctx->iterate_instruction( ctx, &parse.FullToken.FullInstruction )) + goto fail; + break; + + case TGSI_TOKEN_TYPE_DECLARATION: + if (ctx->iterate_declaration) + if (!ctx->iterate_declaration( ctx, &parse.FullToken.FullDeclaration )) + goto fail; + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + if (ctx->iterate_immediate) + if (!ctx->iterate_immediate( ctx, &parse.FullToken.FullImmediate )) + goto fail; + break; + + default: + assert( 0 ); + } + } + + if (ctx->epilog) + if (!ctx->epilog( ctx )) + goto fail; + + tgsi_parse_free( &parse ); + return TRUE; + +fail: + tgsi_parse_free( &parse ); + return FALSE; +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_iterate.h b/src/gallium/auxiliary/tgsi/tgsi_iterate.h new file mode 100644 index 0000000000..ec7b85bf63 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_iterate.h @@ -0,0 +1,76 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_ITERATE_H +#define TGSI_ITERATE_H + +#include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_parse.h" + +#if defined __cplusplus +extern "C" { +#endif + +struct tgsi_iterate_context +{ + boolean + (* prolog)( + struct tgsi_iterate_context *ctx ); + + boolean + (* iterate_instruction)( + struct tgsi_iterate_context *ctx, + struct tgsi_full_instruction *inst ); + + boolean + (* iterate_declaration)( + struct tgsi_iterate_context *ctx, + struct tgsi_full_declaration *decl ); + + boolean + (* iterate_immediate)( + struct tgsi_iterate_context *ctx, + struct tgsi_full_immediate *imm ); + + boolean + (* epilog)( + struct tgsi_iterate_context *ctx ); + + struct tgsi_processor processor; + struct tgsi_version version; +}; + +boolean +tgsi_iterate_shader( + const struct tgsi_token *tokens, + struct tgsi_iterate_context *ctx ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_ITERATE_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c new file mode 100644 index 0000000000..d16f0cdcad --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c @@ -0,0 +1,332 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi_parse.h" +#include "tgsi_build.h" + +void +tgsi_full_token_init( + union tgsi_full_token *full_token ) +{ + full_token->Token.Type = TGSI_TOKEN_TYPE_DECLARATION; +} + +void +tgsi_full_token_free( + union tgsi_full_token *full_token ) +{ + if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE ) { + FREE( (void *) full_token->FullImmediate.u.Pointer ); + } +} + +unsigned +tgsi_parse_init( + struct tgsi_parse_context *ctx, + const struct tgsi_token *tokens ) +{ + ctx->FullVersion.Version = *(struct tgsi_version *) &tokens[0]; + if( ctx->FullVersion.Version.MajorVersion > 1 ) { + return TGSI_PARSE_ERROR; + } + + ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[1]; + if( ctx->FullHeader.Header.HeaderSize >= 2 ) { + ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[2]; + } + else { + ctx->FullHeader.Processor = tgsi_default_processor(); + } + + ctx->Tokens = tokens; + ctx->Position = 1 + ctx->FullHeader.Header.HeaderSize; + + tgsi_full_token_init( &ctx->FullToken ); + + return TGSI_PARSE_OK; +} + +void +tgsi_parse_free( + struct tgsi_parse_context *ctx ) +{ + tgsi_full_token_free( &ctx->FullToken ); +} + +boolean +tgsi_parse_end_of_tokens( + struct tgsi_parse_context *ctx ) +{ + return ctx->Position >= + 1 + ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize; +} + +static void +next_token( + struct tgsi_parse_context *ctx, + void *token ) +{ + assert( !tgsi_parse_end_of_tokens( ctx ) ); + + *(struct tgsi_token *) token = ctx->Tokens[ctx->Position++]; +} + +void +tgsi_parse_token( + struct tgsi_parse_context *ctx ) +{ + struct tgsi_token token; + unsigned i; + + tgsi_full_token_free( &ctx->FullToken ); + tgsi_full_token_init( &ctx->FullToken ); + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + { + struct tgsi_full_declaration *decl = &ctx->FullToken.FullDeclaration; + + *decl = tgsi_default_full_declaration(); + decl->Declaration = *(struct tgsi_declaration *) &token; + + next_token( ctx, &decl->DeclarationRange ); + + if( decl->Declaration.Semantic ) { + next_token( ctx, &decl->Semantic ); + } + + break; + } + + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate; + + *imm = tgsi_default_full_immediate(); + imm->Immediate = *(struct tgsi_immediate *) &token; + + assert( !imm->Immediate.Extended ); + + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + imm->u.Pointer = MALLOC( + sizeof( struct tgsi_immediate_float32 ) * (imm->Immediate.Size - 1) ); + for( i = 0; i < imm->Immediate.Size - 1; i++ ) { + next_token( ctx, (struct tgsi_immediate_float32 *) &imm->u.ImmediateFloat32[i] ); + } + break; + + default: + assert( 0 ); + } + + break; + } + + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction; + unsigned extended; + + *inst = tgsi_default_full_instruction(); + inst->Instruction = *(struct tgsi_instruction *) &token; + + extended = inst->Instruction.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_INSTRUCTION_EXT_TYPE_NV: + inst->InstructionExtNv = + *(struct tgsi_instruction_ext_nv *) &token; + break; + + case TGSI_INSTRUCTION_EXT_TYPE_LABEL: + inst->InstructionExtLabel = + *(struct tgsi_instruction_ext_label *) &token; + break; + + case TGSI_INSTRUCTION_EXT_TYPE_TEXTURE: + inst->InstructionExtTexture = + *(struct tgsi_instruction_ext_texture *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + + assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS ); + + for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { + unsigned extended; + + next_token( ctx, &inst->FullDstRegisters[i].DstRegister ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullDstRegisters[i].DstRegister.Indirect ); + assert( !inst->FullDstRegisters[i].DstRegister.Dimension ); + + extended = inst->FullDstRegisters[i].DstRegister.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_DST_REGISTER_EXT_TYPE_CONDCODE: + inst->FullDstRegisters[i].DstRegisterExtConcode = + *(struct tgsi_dst_register_ext_concode *) &token; + break; + + case TGSI_DST_REGISTER_EXT_TYPE_MODULATE: + inst->FullDstRegisters[i].DstRegisterExtModulate = + *(struct tgsi_dst_register_ext_modulate *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + } + + assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS ); + + for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { + unsigned extended; + + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegister ); + + extended = inst->FullSrcRegisters[i].SrcRegister.Extended; + + while( extended ) { + struct tgsi_src_register_ext token; + + next_token( ctx, &token ); + + switch( token.Type ) { + case TGSI_SRC_REGISTER_EXT_TYPE_SWZ: + inst->FullSrcRegisters[i].SrcRegisterExtSwz = + *(struct tgsi_src_register_ext_swz *) &token; + break; + + case TGSI_SRC_REGISTER_EXT_TYPE_MOD: + inst->FullSrcRegisters[i].SrcRegisterExtMod = + *(struct tgsi_src_register_ext_mod *) &token; + break; + + default: + assert( 0 ); + } + + extended = token.Extended; + } + + if( inst->FullSrcRegisters[i].SrcRegister.Indirect ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterInd ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); + } + + if( inst->FullSrcRegisters[i].SrcRegister.Dimension ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDim ); + + /* + * No support for multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Extended ); + + if( inst->FullSrcRegisters[i].SrcRegisterDim.Indirect ) { + next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDimInd ); + + /* + * No support for indirect or multi-dimensional addressing. + */ + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); + assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); + } + } + } + + break; + } + + default: + assert( 0 ); + } +} + + +unsigned +tgsi_num_tokens(const struct tgsi_token *tokens) +{ + struct tgsi_parse_context ctx; + if (tgsi_parse_init(&ctx, tokens) == TGSI_PARSE_OK) { + unsigned len = (ctx.FullHeader.Header.HeaderSize + + ctx.FullHeader.Header.BodySize + + 1); + return len; + } + return 0; +} + + +/** + * Make a new copy of a token array. + */ +struct tgsi_token * +tgsi_dup_tokens(const struct tgsi_token *tokens) +{ + unsigned n = tgsi_num_tokens(tokens); + unsigned bytes = n * sizeof(struct tgsi_token); + struct tgsi_token *new_tokens = (struct tgsi_token *) MALLOC(bytes); + if (new_tokens) + memcpy(new_tokens, tokens, bytes); + return new_tokens; +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h new file mode 100644 index 0000000000..054350712d --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h @@ -0,0 +1,151 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_PARSE_H +#define TGSI_PARSE_H + +#include "pipe/p_shader_tokens.h" + +#if defined __cplusplus +extern "C" { +#endif + +struct tgsi_full_version +{ + struct tgsi_version Version; +}; + +struct tgsi_full_header +{ + struct tgsi_header Header; + struct tgsi_processor Processor; +}; + +struct tgsi_full_dst_register +{ + struct tgsi_dst_register DstRegister; + struct tgsi_dst_register_ext_concode DstRegisterExtConcode; + struct tgsi_dst_register_ext_modulate DstRegisterExtModulate; +}; + +struct tgsi_full_src_register +{ + struct tgsi_src_register SrcRegister; + struct tgsi_src_register_ext_swz SrcRegisterExtSwz; + struct tgsi_src_register_ext_mod SrcRegisterExtMod; + struct tgsi_src_register SrcRegisterInd; + struct tgsi_dimension SrcRegisterDim; + struct tgsi_src_register SrcRegisterDimInd; +}; + +struct tgsi_full_declaration +{ + struct tgsi_declaration Declaration; + struct tgsi_declaration_range DeclarationRange; + struct tgsi_declaration_semantic Semantic; +}; + +struct tgsi_full_immediate +{ + struct tgsi_immediate Immediate; + union + { + const void *Pointer; + const struct tgsi_immediate_float32 *ImmediateFloat32; + } u; +}; + +#define TGSI_FULL_MAX_DST_REGISTERS 2 +#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */ + +struct tgsi_full_instruction +{ + struct tgsi_instruction Instruction; + struct tgsi_instruction_ext_nv InstructionExtNv; + struct tgsi_instruction_ext_label InstructionExtLabel; + struct tgsi_instruction_ext_texture InstructionExtTexture; + struct tgsi_full_dst_register FullDstRegisters[TGSI_FULL_MAX_DST_REGISTERS]; + struct tgsi_full_src_register FullSrcRegisters[TGSI_FULL_MAX_SRC_REGISTERS]; +}; + +union tgsi_full_token +{ + struct tgsi_token Token; + struct tgsi_full_declaration FullDeclaration; + struct tgsi_full_immediate FullImmediate; + struct tgsi_full_instruction FullInstruction; +}; + +void +tgsi_full_token_init( + union tgsi_full_token *full_token ); + +void +tgsi_full_token_free( + union tgsi_full_token *full_token ); + +struct tgsi_parse_context +{ + const struct tgsi_token *Tokens; + unsigned Position; + struct tgsi_full_version FullVersion; + struct tgsi_full_header FullHeader; + union tgsi_full_token FullToken; +}; + +#define TGSI_PARSE_OK 0 +#define TGSI_PARSE_ERROR 1 + +unsigned +tgsi_parse_init( + struct tgsi_parse_context *ctx, + const struct tgsi_token *tokens ); + +void +tgsi_parse_free( + struct tgsi_parse_context *ctx ); + +boolean +tgsi_parse_end_of_tokens( + struct tgsi_parse_context *ctx ); + +void +tgsi_parse_token( + struct tgsi_parse_context *ctx ); + +unsigned +tgsi_num_tokens(const struct tgsi_token *tokens); + +struct tgsi_token * +tgsi_dup_tokens(const struct tgsi_token *tokens); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_PARSE_H */ + diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c new file mode 100644 index 0000000000..2e3ec96b5b --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c @@ -0,0 +1,341 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "tgsi_sanity.h" +#include "tgsi_iterate.h" + +#define MAX_REGISTERS 256 + +typedef uint reg_flag; + +#define BITS_IN_REG_FLAG (sizeof( reg_flag ) * 8) + +struct sanity_check_ctx +{ + struct tgsi_iterate_context iter; + + reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REGISTERS / BITS_IN_REG_FLAG]; + reg_flag regs_used[TGSI_FILE_COUNT][MAX_REGISTERS / BITS_IN_REG_FLAG]; + boolean regs_ind_used[TGSI_FILE_COUNT]; + uint num_imms; + uint num_instructions; + uint index_of_END; + + uint errors; + uint warnings; +}; + +static void +report_error( + struct sanity_check_ctx *ctx, + const char *format, + ... ) +{ + va_list args; + + debug_printf( "Error : " ); + va_start( args, format ); + _debug_vprintf( format, args ); + va_end( args ); + debug_printf( "\n" ); + ctx->errors++; +} + +static void +report_warning( + struct sanity_check_ctx *ctx, + const char *format, + ... ) +{ + va_list args; + + debug_printf( "Warning: " ); + va_start( args, format ); + _debug_vprintf( format, args ); + va_end( args ); + debug_printf( "\n" ); + ctx->warnings++; +} + +static boolean +check_file_name( + struct sanity_check_ctx *ctx, + uint file ) +{ + if (file <= TGSI_FILE_NULL || file >= TGSI_FILE_COUNT) { + report_error( ctx, "Invalid register file name" ); + return FALSE; + } + return TRUE; +} + +static boolean +is_register_declared( + struct sanity_check_ctx *ctx, + uint file, + int index ) +{ + assert( index >= 0 && index < MAX_REGISTERS ); + + return (ctx->regs_decl[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; +} + +static boolean +is_any_register_declared( + struct sanity_check_ctx *ctx, + uint file ) +{ + uint i; + + for (i = 0; i < MAX_REGISTERS / BITS_IN_REG_FLAG; i++) + if (ctx->regs_decl[file][i]) + return TRUE; + return FALSE; +} + +static boolean +is_register_used( + struct sanity_check_ctx *ctx, + uint file, + int index ) +{ + assert( index < MAX_REGISTERS ); + + return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; +} + +static const char *file_names[] = +{ + "NULL", + "CONST", + "IN", + "OUT", + "TEMP", + "SAMP", + "ADDR", + "IMM" +}; + +static boolean +check_register_usage( + struct sanity_check_ctx *ctx, + uint file, + int index, + const char *name, + boolean indirect_access ) +{ + if (!check_file_name( ctx, file )) + return FALSE; + if (indirect_access) { + if (!is_any_register_declared( ctx, file )) + report_error( ctx, "%s: Undeclared %s register", file_names[file], name ); + ctx->regs_ind_used[file] = TRUE; + } + else { + if (!is_register_declared( ctx, file, index )) + report_error( ctx, "%s[%d]: Undeclared %s register", file_names[file], index, name ); + ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG)); + } + return TRUE; +} + +static boolean +iter_instruction( + struct tgsi_iterate_context *iter, + struct tgsi_full_instruction *inst ) +{ + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; + uint i; + + /* There must be no other instructions after END. + */ + if (ctx->index_of_END != ~0) { + report_error( ctx, "Unexpected instruction after END" ); + } + else if (inst->Instruction.Opcode == TGSI_OPCODE_END) { + ctx->index_of_END = ctx->num_instructions; + } + + /* Check destination and source registers' validity. + * Mark the registers as used. + */ + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { + check_register_usage( + ctx, + inst->FullDstRegisters[i].DstRegister.File, + inst->FullDstRegisters[i].DstRegister.Index, + "destination", + FALSE ); + } + for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { + check_register_usage( + ctx, + inst->FullSrcRegisters[i].SrcRegister.File, + inst->FullSrcRegisters[i].SrcRegister.Index, + "source", + (boolean)inst->FullSrcRegisters[i].SrcRegister.Indirect ); + if (inst->FullSrcRegisters[i].SrcRegister.Indirect) { + uint file; + int index; + + file = inst->FullSrcRegisters[i].SrcRegisterInd.File; + index = inst->FullSrcRegisters[i].SrcRegisterInd.Index; + check_register_usage( + ctx, + file, + index, + "indirect", + FALSE ); + if (file != TGSI_FILE_ADDRESS || index != 0) + report_warning( ctx, "Indirect register not ADDR[0]" ); + } + } + + ctx->num_instructions++; + + return TRUE; +} + +static boolean +iter_declaration( + struct tgsi_iterate_context *iter, + struct tgsi_full_declaration *decl ) +{ + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; + uint file; + uint i; + + /* No declarations allowed after the first instruction. + */ + if (ctx->num_instructions > 0) + report_error( ctx, "Instruction expected but declaration found" ); + + /* Check registers' validity. + * Mark the registers as declared. + */ + file = decl->Declaration.File; + if (!check_file_name( ctx, file )) + return TRUE; + for (i = decl->DeclarationRange.First; i <= decl->DeclarationRange.Last; i++) { + if (is_register_declared( ctx, file, i )) + report_error( ctx, "The same register declared twice" ); + ctx->regs_decl[file][i / BITS_IN_REG_FLAG] |= (1 << (i % BITS_IN_REG_FLAG)); + } + + return TRUE; +} + +static boolean +iter_immediate( + struct tgsi_iterate_context *iter, + struct tgsi_full_immediate *imm ) +{ + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; + + assert( ctx->num_imms < MAX_REGISTERS ); + + /* No immediates allowed after the first instruction. + */ + if (ctx->num_instructions > 0) + report_error( ctx, "Instruction expected but immediate found" ); + + /* Mark the register as declared. + */ + ctx->regs_decl[TGSI_FILE_IMMEDIATE][ctx->num_imms / BITS_IN_REG_FLAG] |= (1 << (ctx->num_imms % BITS_IN_REG_FLAG)); + ctx->num_imms++; + + /* Check data type validity. + */ + if (imm->Immediate.DataType != TGSI_IMM_FLOAT32) { + report_error( ctx, "Invalid immediate data type" ); + return TRUE; + } + + return TRUE; +} + +static boolean +epilog( + struct tgsi_iterate_context *iter ) +{ + struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; + uint file; + + /* There must be an END instruction at the end. + */ + if (ctx->index_of_END == ~0 || ctx->index_of_END != ctx->num_instructions - 1) { + report_error( ctx, "Expected END at end of instruction sequence" ); + } + + /* Check if all declared registers were used. + */ + for (file = TGSI_FILE_NULL; file < TGSI_FILE_COUNT; file++) { + uint i; + + for (i = 0; i < MAX_REGISTERS; i++) { + if (is_register_declared( ctx, file, i ) && !is_register_used( ctx, file, i ) && !ctx->regs_ind_used[file]) { + report_warning( ctx, "Register never used" ); + } + } + } + + /* Print totals, if any. + */ + if (ctx->errors || ctx->warnings) + debug_printf( "\n%u errors, %u warnings", ctx->errors, ctx->warnings ); + + return TRUE; +} + +boolean +tgsi_sanity_check( + struct tgsi_token *tokens ) +{ + struct sanity_check_ctx ctx; + + ctx.iter.prolog = NULL; + ctx.iter.iterate_instruction = iter_instruction; + ctx.iter.iterate_declaration = iter_declaration; + ctx.iter.iterate_immediate = iter_immediate; + ctx.iter.epilog = epilog; + + memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) ); + memset( ctx.regs_used, 0, sizeof( ctx.regs_used ) ); + memset( ctx.regs_ind_used, 0, sizeof( ctx.regs_ind_used ) ); + ctx.num_imms = 0; + ctx.num_instructions = 0; + ctx.index_of_END = ~0; + + ctx.errors = 0; + ctx.warnings = 0; + + if (!tgsi_iterate_shader( tokens, &ctx.iter )) + return FALSE; + + return ctx.errors == 0; +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.h b/src/gallium/auxiliary/tgsi/tgsi_sanity.h new file mode 100644 index 0000000000..ca45e94c7a --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.h @@ -0,0 +1,49 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_SANITY_H +#define TGSI_SANITY_H + +#include "pipe/p_shader_tokens.h" + +#if defined __cplusplus +extern "C" { +#endif + +/* Check the given token stream for errors and common mistakes. + * Diagnostic messages are printed out to the debug output. + * Returns TRUE if there are no errors, even though there could be some warnings. + */ +boolean +tgsi_sanity_check( + struct tgsi_token *tokens ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_SANITY_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c new file mode 100644 index 0000000000..59bcf10b53 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c @@ -0,0 +1,226 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * TGSI program scan utility. + * Used to determine which registers and instructions are used by a shader. + * + * Authors: Brian Paul + */ + + +#include "tgsi_scan.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_build.h" + +#include "pipe/p_util.h" + + + +/** + */ +void +tgsi_scan_shader(const struct tgsi_token *tokens, + struct tgsi_shader_info *info) +{ + uint procType, i; + struct tgsi_parse_context parse; + + memset(info, 0, sizeof(*info)); + for (i = 0; i < TGSI_FILE_COUNT; i++) + info->file_max[i] = -1; + + /** + ** Setup to begin parsing input shader + **/ + if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) { + debug_printf("tgsi_parse_init() failed in tgsi_scan_shader()!\n"); + return; + } + procType = parse.FullHeader.Processor.Processor; + assert(procType == TGSI_PROCESSOR_FRAGMENT || + procType == TGSI_PROCESSOR_VERTEX || + procType == TGSI_PROCESSOR_GEOMETRY); + + + /** + ** Loop over incoming program tokens/instructions + */ + while( !tgsi_parse_end_of_tokens( &parse ) ) { + + info->num_tokens++; + + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *fullinst + = &parse.FullToken.FullInstruction; + + assert(fullinst->Instruction.Opcode < TGSI_OPCODE_LAST); + info->opcode_count[fullinst->Instruction.Opcode]++; + } + break; + + case TGSI_TOKEN_TYPE_DECLARATION: + { + struct tgsi_full_declaration *fulldecl + = &parse.FullToken.FullDeclaration; + uint file = fulldecl->Declaration.File; + uint i; + for (i = fulldecl->DeclarationRange.First; + i <= fulldecl->DeclarationRange.Last; + i++) { + + /* only first 32 regs will appear in this bitfield */ + info->file_mask[file] |= (1 << i); + info->file_count[file]++; + info->file_max[file] = MAX2(info->file_max[file], (int)i); + + if (file == TGSI_FILE_INPUT) { + info->input_semantic_name[i] = (ubyte)fulldecl->Semantic.SemanticName; + info->input_semantic_index[i] = (ubyte)fulldecl->Semantic.SemanticIndex; + info->num_inputs++; + } + + if (file == TGSI_FILE_OUTPUT) { + info->output_semantic_name[i] = (ubyte)fulldecl->Semantic.SemanticName; + info->output_semantic_index[i] = (ubyte)fulldecl->Semantic.SemanticIndex; + info->num_outputs++; + } + + /* special case */ + if (procType == TGSI_PROCESSOR_FRAGMENT && + file == TGSI_FILE_OUTPUT && + fulldecl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { + info->writes_z = TRUE; + } + } + } + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + info->immediate_count++; + break; + + default: + assert( 0 ); + } + } + + assert( info->file_max[TGSI_FILE_INPUT] + 1 == info->num_inputs ); + assert( info->file_max[TGSI_FILE_OUTPUT] + 1 == info->num_outputs ); + + info->uses_kill = (info->opcode_count[TGSI_OPCODE_KIL] || + info->opcode_count[TGSI_OPCODE_KILP]); + + tgsi_parse_free (&parse); +} + + + +/** + * Check if the given shader is a "passthrough" shader consisting of only + * MOV instructions of the form: MOV OUT[n], IN[n] + * + */ +boolean +tgsi_is_passthrough_shader(const struct tgsi_token *tokens) +{ + struct tgsi_parse_context parse; + + /** + ** Setup to begin parsing input shader + **/ + if (tgsi_parse_init(&parse, tokens) != TGSI_PARSE_OK) { + debug_printf("tgsi_parse_init() failed in tgsi_is_passthrough_shader()!\n"); + return FALSE; + } + + /** + ** Loop over incoming program tokens/instructions + */ + while (!tgsi_parse_end_of_tokens(&parse)) { + + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *fullinst = + &parse.FullToken.FullInstruction; + const struct tgsi_full_src_register *src = + &fullinst->FullSrcRegisters[0]; + const struct tgsi_full_dst_register *dst = + &fullinst->FullDstRegisters[0]; + + /* Do a whole bunch of checks for a simple move */ + if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV || + src->SrcRegister.File != TGSI_FILE_INPUT || + dst->DstRegister.File != TGSI_FILE_OUTPUT || + src->SrcRegister.Index != dst->DstRegister.Index || + + src->SrcRegister.Negate || + src->SrcRegisterExtMod.Negate || + src->SrcRegisterExtMod.Absolute || + src->SrcRegisterExtMod.Scale2X || + src->SrcRegisterExtMod.Bias || + src->SrcRegisterExtMod.Complement || + + src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || + src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || + src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || + src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W || + + src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || + src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || + src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || + src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W || + + dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW) + { + tgsi_parse_free(&parse); + return FALSE; + } + } + break; + + case TGSI_TOKEN_TYPE_DECLARATION: + /* fall-through */ + case TGSI_TOKEN_TYPE_IMMEDIATE: + /* fall-through */ + default: + ; /* no-op */ + } + } + + tgsi_parse_free(&parse); + + /* if we get here, it's a pass-through shader */ + return TRUE; +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h new file mode 100644 index 0000000000..5cb6efb343 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h @@ -0,0 +1,74 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_SCAN_H +#define TGSI_SCAN_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" +#include "pipe/p_shader_tokens.h" + + +/** + * Shader summary info + */ +struct tgsi_shader_info +{ + uint num_tokens; + + /* XXX eventually remove the corresponding fields from pipe_shader_state: */ + ubyte num_inputs; + ubyte num_outputs; + ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */ + ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; + ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */ + ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; + + uint file_mask[TGSI_FILE_COUNT]; /**< bitmask of declared registers */ + uint file_count[TGSI_FILE_COUNT]; /**< number of declared registers */ + int file_max[TGSI_FILE_COUNT]; /**< highest index of declared registers */ + + uint immediate_count; /**< number of immediates declared */ + + uint opcode_count[TGSI_OPCODE_LAST]; /**< opcode histogram */ + + boolean writes_z; /**< does fragment shader write Z value? */ + boolean uses_kill; /**< KIL or KILP instruction used? */ +}; + + +extern void +tgsi_scan_shader(const struct tgsi_token *tokens, + struct tgsi_shader_info *info); + + +extern boolean +tgsi_is_passthrough_shader(const struct tgsi_token *tokens); + + +#endif /* TGSI_SCAN_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c new file mode 100644 index 0000000000..0cb1f11ef2 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -0,0 +1,2275 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" +#include "tgsi_exec.h" +#include "tgsi_sse2.h" + +#include "rtasm/rtasm_x86sse.h" + +#ifdef PIPE_ARCH_X86 + +/* for 1/sqrt() + * + * This costs about 100fps (close to 10%) in gears: + */ +#define HIGH_PRECISION 1 + + +#define FOR_EACH_CHANNEL( CHAN )\ + for( CHAN = 0; CHAN < 4; CHAN++ ) + +#define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ + ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) + +#define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ + if( IS_DST0_CHANNEL_ENABLED( INST, CHAN )) + +#define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\ + FOR_EACH_CHANNEL( CHAN )\ + IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN ) + +#define CHAN_X 0 +#define CHAN_Y 1 +#define CHAN_Z 2 +#define CHAN_W 3 + +#define TEMP_R0 TGSI_EXEC_TEMP_R0 + +/** + * X86 utility functions. + */ + +static struct x86_reg +make_xmm( + unsigned xmm ) +{ + return x86_make_reg( + file_XMM, + (enum x86_reg_name) xmm ); +} + +/** + * X86 register mapping helpers. + */ + +static struct x86_reg +get_const_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_CX ); +} + +static struct x86_reg +get_input_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_AX ); +} + +static struct x86_reg +get_output_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_DX ); +} + +static struct x86_reg +get_temp_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_BX ); +} + +static struct x86_reg +get_coef_base( void ) +{ + return get_output_base(); +} + +static struct x86_reg +get_immediate_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_DI ); +} + + +/** + * Data access helpers. + */ + + +static struct x86_reg +get_immediate( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_immediate_base(), + (vec * 4 + chan) * 4 ); +} + +static struct x86_reg +get_const( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_const_base(), + (vec * 4 + chan) * 4 ); +} + +static struct x86_reg +get_input( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_input_base(), + (vec * 4 + chan) * 16 ); +} + +static struct x86_reg +get_output( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_output_base(), + (vec * 4 + chan) * 16 ); +} + +static struct x86_reg +get_temp( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_temp_base(), + (vec * 4 + chan) * 16 ); +} + +static struct x86_reg +get_coef( + unsigned vec, + unsigned chan, + unsigned member ) +{ + return x86_make_disp( + get_coef_base(), + ((vec * 3 + member) * 4 + chan) * 4 ); +} + + +static void +emit_ret( + struct x86_function *func ) +{ + x86_ret( func ); +} + + +/** + * Data fetch helpers. + */ + +/** + * Copy a shader constant to xmm register + * \param xmm the destination xmm register + * \param vec the src const buffer index + * \param chan src channel to fetch (X, Y, Z or W) + */ +static void +emit_const( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + sse_movss( + func, + make_xmm( xmm ), + get_const( vec, chan ) ); + sse_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); +} + +static void +emit_immediate( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + sse_movss( + func, + make_xmm( xmm ), + get_immediate( vec, chan ) ); + sse_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); +} + + +/** + * Copy a shader input to xmm register + * \param xmm the destination xmm register + * \param vec the src input attrib + * \param chan src channel to fetch (X, Y, Z or W) + */ +static void +emit_inputf( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + sse_movups( + func, + make_xmm( xmm ), + get_input( vec, chan ) ); +} + +/** + * Store an xmm register to a shader output + * \param xmm the source xmm register + * \param vec the dest output attrib + * \param chan src dest channel to store (X, Y, Z or W) + */ +static void +emit_output( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + sse_movups( + func, + get_output( vec, chan ), + make_xmm( xmm ) ); +} + +/** + * Copy a shader temporary to xmm register + * \param xmm the destination xmm register + * \param vec the src temp register + * \param chan src channel to fetch (X, Y, Z or W) + */ +static void +emit_tempf( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + sse_movaps( + func, + make_xmm( xmm ), + get_temp( vec, chan ) ); +} + +/** + * Load an xmm register with an input attrib coefficient (a0, dadx or dady) + * \param xmm the destination xmm register + * \param vec the src input/attribute coefficient index + * \param chan src channel to fetch (X, Y, Z or W) + * \param member 0=a0, 1=dadx, 2=dady + */ +static void +emit_coef( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan, + unsigned member ) +{ + sse_movss( + func, + make_xmm( xmm ), + get_coef( vec, chan, member ) ); + sse_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); +} + +/** + * Data store helpers. + */ + +static void +emit_inputs( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + sse_movups( + func, + get_input( vec, chan ), + make_xmm( xmm ) ); +} + +static void +emit_temps( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + sse_movaps( + func, + get_temp( vec, chan ), + make_xmm( xmm ) ); +} + +static void +emit_addrs( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_temps( + func, + xmm, + vec + TGSI_EXEC_NUM_TEMPS, + chan ); +} + +/** + * Coefficent fetch helpers. + */ + +static void +emit_coef_a0( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_coef( + func, + xmm, + vec, + chan, + 0 ); +} + +static void +emit_coef_dadx( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_coef( + func, + xmm, + vec, + chan, + 1 ); +} + +static void +emit_coef_dady( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_coef( + func, + xmm, + vec, + chan, + 2 ); +} + +/** + * Function call helpers. + */ + +static void +emit_push_gp( + struct x86_function *func ) +{ + x86_push( + func, + x86_make_reg( file_REG32, reg_AX) ); + x86_push( + func, + x86_make_reg( file_REG32, reg_CX) ); + x86_push( + func, + x86_make_reg( file_REG32, reg_DX) ); +} + +static void +x86_pop_gp( + struct x86_function *func ) +{ + /* Restore GP registers in a reverse order. + */ + x86_pop( + func, + x86_make_reg( file_REG32, reg_DX) ); + x86_pop( + func, + x86_make_reg( file_REG32, reg_CX) ); + x86_pop( + func, + x86_make_reg( file_REG32, reg_AX) ); +} + +static void +emit_func_call_dst( + struct x86_function *func, + unsigned xmm_dst, + void (PIPE_CDECL *code)() ) +{ + sse_movaps( + func, + get_temp( TEMP_R0, 0 ), + make_xmm( xmm_dst ) ); + + emit_push_gp( + func ); + + { + struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); + + x86_lea( + func, + ecx, + get_temp( TEMP_R0, 0 ) ); + + x86_push( func, ecx ); + x86_mov_reg_imm( func, ecx, (unsigned long) code ); + x86_call( func, ecx ); + x86_pop(func, ecx ); + } + + + x86_pop_gp( + func ); + + sse_movaps( + func, + make_xmm( xmm_dst ), + get_temp( TEMP_R0, 0 ) ); +} + +static void +emit_func_call_dst_src( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src, + void (PIPE_CDECL *code)() ) +{ + sse_movaps( + func, + get_temp( TEMP_R0, 1 ), + make_xmm( xmm_src ) ); + + emit_func_call_dst( + func, + xmm_dst, + code ); +} + +/** + * Low-level instruction translators. + */ + +static void +emit_abs( + struct x86_function *func, + unsigned xmm ) +{ + sse_andps( + func, + make_xmm( xmm ), + get_temp( + TGSI_EXEC_TEMP_7FFFFFFF_I, + TGSI_EXEC_TEMP_7FFFFFFF_C ) ); +} + +static void +emit_add( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + sse_addps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void PIPE_CDECL +cos4f( + float *store ) +{ + const unsigned X = 0; + + store[X + 0] = cosf( store[X + 0] ); + store[X + 1] = cosf( store[X + 1] ); + store[X + 2] = cosf( store[X + 2] ); + store[X + 3] = cosf( store[X + 3] ); +} + +static void +emit_cos( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + cos4f ); +} + +static void PIPE_CDECL +ex24f( + float *store ) +{ + const unsigned X = 0; + + store[X + 0] = powf( 2.0f, store[X + 0] ); + store[X + 1] = powf( 2.0f, store[X + 1] ); + store[X + 2] = powf( 2.0f, store[X + 2] ); + store[X + 3] = powf( 2.0f, store[X + 3] ); +} + +static void +emit_ex2( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + ex24f ); +} + +static void +emit_f2it( + struct x86_function *func, + unsigned xmm ) +{ + sse2_cvttps2dq( + func, + make_xmm( xmm ), + make_xmm( xmm ) ); +} + +static void PIPE_CDECL +flr4f( + float *store ) +{ + const unsigned X = 0; + + store[X + 0] = floorf( store[X + 0] ); + store[X + 1] = floorf( store[X + 1] ); + store[X + 2] = floorf( store[X + 2] ); + store[X + 3] = floorf( store[X + 3] ); +} + +static void +emit_flr( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + flr4f ); +} + +static void PIPE_CDECL +frc4f( + float *store ) +{ + const unsigned X = 0; + + store[X + 0] -= floorf( store[X + 0] ); + store[X + 1] -= floorf( store[X + 1] ); + store[X + 2] -= floorf( store[X + 2] ); + store[X + 3] -= floorf( store[X + 3] ); +} + +static void +emit_frc( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + frc4f ); +} + +static void PIPE_CDECL +lg24f( + float *store ) +{ + const unsigned X = 0; + + store[X + 0] = LOG2( store[X + 0] ); + store[X + 1] = LOG2( store[X + 1] ); + store[X + 2] = LOG2( store[X + 2] ); + store[X + 3] = LOG2( store[X + 3] ); +} + +static void +emit_lg2( + struct x86_function *func, + unsigned xmm_dst ) +{ + emit_func_call_dst( + func, + xmm_dst, + lg24f ); +} + +static void +emit_MOV( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + sse_movups( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void +emit_mul (struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src) +{ + sse_mulps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void +emit_neg( + struct x86_function *func, + unsigned xmm ) +{ + sse_xorps( + func, + make_xmm( xmm ), + get_temp( + TGSI_EXEC_TEMP_80000000_I, + TGSI_EXEC_TEMP_80000000_C ) ); +} + +static void PIPE_CDECL +pow4f( + float *store ) +{ + const unsigned X = 0; + + store[X + 0] = powf( store[X + 0], store[X + 4] ); + store[X + 1] = powf( store[X + 1], store[X + 5] ); + store[X + 2] = powf( store[X + 2], store[X + 6] ); + store[X + 3] = powf( store[X + 3], store[X + 7] ); +} + +static void +emit_pow( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + emit_func_call_dst_src( + func, + xmm_dst, + xmm_src, + pow4f ); +} + +static void +emit_rcp ( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + /* On Intel CPUs at least, this is only accurate to 12 bits -- not + * good enough. Need to either emit a proper divide or use the + * iterative technique described below in emit_rsqrt(). + */ + sse2_rcpps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +static void +emit_rsqrt( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ +#if HIGH_PRECISION + /* Although rsqrtps() and rcpps() are low precision on some/all SSE + * implementations, it is possible to improve its precision at + * fairly low cost, using a newton/raphson step, as below: + * + * x1 = 2 * rcpps(a) - a * rcpps(a) * rcpps(a) + * x1 = 0.5 * rsqrtps(a) * [3.0 - (a * rsqrtps(a))* rsqrtps(a)] + * + * See: http://softwarecommunity.intel.com/articles/eng/1818.htm + */ + { + struct x86_reg dst = make_xmm( xmm_dst ); + struct x86_reg src = make_xmm( xmm_src ); + struct x86_reg tmp0 = make_xmm( 2 ); + struct x86_reg tmp1 = make_xmm( 3 ); + + assert( xmm_dst != xmm_src ); + assert( xmm_dst != 2 && xmm_dst != 3 ); + assert( xmm_src != 2 && xmm_src != 3 ); + + sse_movaps( func, dst, get_temp( TGSI_EXEC_TEMP_HALF_I, TGSI_EXEC_TEMP_HALF_C ) ); + sse_movaps( func, tmp0, get_temp( TGSI_EXEC_TEMP_THREE_I, TGSI_EXEC_TEMP_THREE_C ) ); + sse_rsqrtps( func, tmp1, src ); + sse_mulps( func, src, tmp1 ); + sse_mulps( func, dst, tmp1 ); + sse_mulps( func, src, tmp1 ); + sse_subps( func, tmp0, src ); + sse_mulps( func, dst, tmp0 ); + } +#else + /* On Intel CPUs at least, this is only accurate to 12 bits -- not + * good enough. + */ + sse_rsqrtps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +#endif +} + +static void +emit_setsign( + struct x86_function *func, + unsigned xmm ) +{ + sse_orps( + func, + make_xmm( xmm ), + get_temp( + TGSI_EXEC_TEMP_80000000_I, + TGSI_EXEC_TEMP_80000000_C ) ); +} + +static void PIPE_CDECL +sin4f( + float *store ) +{ + const unsigned X = 0; + + store[X + 0] = sinf( store[X + 0] ); + store[X + 1] = sinf( store[X + 1] ); + store[X + 2] = sinf( store[X + 2] ); + store[X + 3] = sinf( store[X + 3] ); +} + +static void +emit_sin (struct x86_function *func, + unsigned xmm_dst) +{ + emit_func_call_dst( + func, + xmm_dst, + sin4f ); +} + +static void +emit_sub( + struct x86_function *func, + unsigned xmm_dst, + unsigned xmm_src ) +{ + sse_subps( + func, + make_xmm( xmm_dst ), + make_xmm( xmm_src ) ); +} + +/** + * Register fetch. + */ + +static void +emit_fetch( + struct x86_function *func, + unsigned xmm, + const struct tgsi_full_src_register *reg, + const unsigned chan_index ) +{ + unsigned swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); + + switch( swizzle ) { + case TGSI_EXTSWIZZLE_X: + case TGSI_EXTSWIZZLE_Y: + case TGSI_EXTSWIZZLE_Z: + case TGSI_EXTSWIZZLE_W: + switch( reg->SrcRegister.File ) { + case TGSI_FILE_CONSTANT: + emit_const( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + + case TGSI_FILE_IMMEDIATE: + emit_immediate( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + + case TGSI_FILE_INPUT: + emit_inputf( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + + case TGSI_FILE_TEMPORARY: + emit_tempf( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + + default: + assert( 0 ); + } + break; + + case TGSI_EXTSWIZZLE_ZERO: + emit_tempf( + func, + xmm, + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ); + break; + + case TGSI_EXTSWIZZLE_ONE: + emit_tempf( + func, + xmm, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); + break; + + default: + assert( 0 ); + } + + switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) { + case TGSI_UTIL_SIGN_CLEAR: + emit_abs( func, xmm ); + break; + + case TGSI_UTIL_SIGN_SET: + emit_setsign( func, xmm ); + break; + + case TGSI_UTIL_SIGN_TOGGLE: + emit_neg( func, xmm ); + break; + + case TGSI_UTIL_SIGN_KEEP: + break; + } +} + +#define FETCH( FUNC, INST, XMM, INDEX, CHAN )\ + emit_fetch( FUNC, XMM, &(INST).FullSrcRegisters[INDEX], CHAN ) + +/** + * Register store. + */ + +static void +emit_store( + struct x86_function *func, + unsigned xmm, + const struct tgsi_full_dst_register *reg, + const struct tgsi_full_instruction *inst, + unsigned chan_index ) +{ + switch( reg->DstRegister.File ) { + case TGSI_FILE_OUTPUT: + emit_output( + func, + xmm, + reg->DstRegister.Index, + chan_index ); + break; + + case TGSI_FILE_TEMPORARY: + emit_temps( + func, + xmm, + reg->DstRegister.Index, + chan_index ); + break; + + case TGSI_FILE_ADDRESS: + emit_addrs( + func, + xmm, + reg->DstRegister.Index, + chan_index ); + break; + + default: + assert( 0 ); + } + + switch( inst->Instruction.Saturate ) { + case TGSI_SAT_NONE: + break; + + case TGSI_SAT_ZERO_ONE: + /* assert( 0 ); */ + break; + + case TGSI_SAT_MINUS_PLUS_ONE: + assert( 0 ); + break; + } +} + +#define STORE( FUNC, INST, XMM, INDEX, CHAN )\ + emit_store( FUNC, XMM, &(INST).FullDstRegisters[INDEX], &(INST), CHAN ) + +/** + * High-level instruction translators. + */ + +static void +emit_kil( + struct x86_function *func, + const struct tgsi_full_src_register *reg ) +{ + unsigned uniquemask; + unsigned registers[4]; + unsigned nextregister = 0; + unsigned firstchan = ~0; + unsigned chan_index; + + /* This mask stores component bits that were already tested. Note that + * we test if the value is less than zero, so 1.0 and 0.0 need not to be + * tested. */ + uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE); + + FOR_EACH_CHANNEL( chan_index ) { + unsigned swizzle; + + /* unswizzle channel */ + swizzle = tgsi_util_get_full_src_register_extswizzle( + reg, + chan_index ); + + /* check if the component has not been already tested */ + if( !(uniquemask & (1 << swizzle)) ) { + uniquemask |= 1 << swizzle; + + /* allocate register */ + registers[chan_index] = nextregister; + emit_fetch( + func, + nextregister, + reg, + chan_index ); + nextregister++; + + /* mark the first channel used */ + if( firstchan == ~0 ) { + firstchan = chan_index; + } + } + } + + x86_push( + func, + x86_make_reg( file_REG32, reg_AX ) ); + x86_push( + func, + x86_make_reg( file_REG32, reg_DX ) ); + + FOR_EACH_CHANNEL( chan_index ) { + if( uniquemask & (1 << chan_index) ) { + sse_cmpps( + func, + make_xmm( registers[chan_index] ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ), + cc_LessThan ); + + if( chan_index == firstchan ) { + sse_pmovmskb( + func, + x86_make_reg( file_REG32, reg_AX ), + make_xmm( registers[chan_index] ) ); + } + else { + sse_pmovmskb( + func, + x86_make_reg( file_REG32, reg_DX ), + make_xmm( registers[chan_index] ) ); + x86_or( + func, + x86_make_reg( file_REG32, reg_AX ), + x86_make_reg( file_REG32, reg_DX ) ); + } + } + } + + x86_or( + func, + get_temp( + TGSI_EXEC_TEMP_KILMASK_I, + TGSI_EXEC_TEMP_KILMASK_C ), + x86_make_reg( file_REG32, reg_AX ) ); + + x86_pop( + func, + x86_make_reg( file_REG32, reg_DX ) ); + x86_pop( + func, + x86_make_reg( file_REG32, reg_AX ) ); +} + +static void +emit_setcc( + struct x86_function *func, + struct tgsi_full_instruction *inst, + enum sse_cc cc ) +{ + unsigned chan_index; + + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + sse_cmpps( + func, + make_xmm( 0 ), + make_xmm( 1 ), + cc ); + sse_andps( + func, + make_xmm( 0 ), + get_temp( + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ) ); + STORE( func, *inst, 0, 0, chan_index ); + } +} + +static void +emit_cmp( + struct x86_function *func, + struct tgsi_full_instruction *inst ) +{ + unsigned chan_index; + + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + FETCH( func, *inst, 2, 2, chan_index ); + sse_cmpps( + func, + make_xmm( 0 ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ), + cc_LessThan ); + sse_andps( + func, + make_xmm( 1 ), + make_xmm( 0 ) ); + sse_andnps( + func, + make_xmm( 0 ), + make_xmm( 2 ) ); + sse_orps( + func, + make_xmm( 0 ), + make_xmm( 1 ) ); + STORE( func, *inst, 0, 0, chan_index ); + } +} + +static int +emit_instruction( + struct x86_function *func, + struct tgsi_full_instruction *inst ) +{ + unsigned chan_index; + + switch( inst->Instruction.Opcode ) { + case TGSI_OPCODE_ARL: +#if 0 + /* XXX this isn't working properly (see glean vertProg1 test) */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_f2it( func, 0 ); + STORE( func, *inst, 0, 0, chan_index ); + } +#else + return 0; +#endif + break; + + case TGSI_OPCODE_MOV: + case TGSI_OPCODE_SWZ: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_LIT: + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) { + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C); + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ) { + STORE( func, *inst, 0, 0, CHAN_X ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) ) { + STORE( func, *inst, 0, 0, CHAN_W ); + } + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + FETCH( func, *inst, 0, 0, CHAN_X ); + sse_maxps( + func, + make_xmm( 0 ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ) ); + STORE( func, *inst, 0, 0, CHAN_Y ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + /* XMM[1] = SrcReg[0].yyyy */ + FETCH( func, *inst, 1, 0, CHAN_Y ); + /* XMM[1] = max(XMM[1], 0) */ + sse_maxps( + func, + make_xmm( 1 ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ) ); + /* XMM[2] = SrcReg[0].wwww */ + FETCH( func, *inst, 2, 0, CHAN_W ); + /* XMM[2] = min(XMM[2], 128.0) */ + sse_minps( + func, + make_xmm( 2 ), + get_temp( + TGSI_EXEC_TEMP_128_I, + TGSI_EXEC_TEMP_128_C ) ); + /* XMM[2] = max(XMM[2], -128.0) */ + sse_maxps( + func, + make_xmm( 2 ), + get_temp( + TGSI_EXEC_TEMP_MINUS_128_I, + TGSI_EXEC_TEMP_MINUS_128_C ) ); + emit_pow( func, 1, 2 ); + FETCH( func, *inst, 0, 0, CHAN_X ); + sse_xorps( + func, + make_xmm( 2 ), + make_xmm( 2 ) ); + sse_cmpps( + func, + make_xmm( 2 ), + make_xmm( 0 ), + cc_LessThanEqual ); + sse_andps( + func, + make_xmm( 2 ), + make_xmm( 1 ) ); + STORE( func, *inst, 2, 0, CHAN_Z ); + } + } + break; + + case TGSI_OPCODE_RCP: + /* TGSI_OPCODE_RECIP */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_rcp( func, 0, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_RSQ: + /* TGSI_OPCODE_RECIPSQRT */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_rsqrt( func, 1, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 1, 0, chan_index ); + } + break; + + case TGSI_OPCODE_EXP: + return 0; + break; + + case TGSI_OPCODE_LOG: + return 0; + break; + + case TGSI_OPCODE_MUL: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_mul( func, 0, 1 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_ADD: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_add( func, 0, 1 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP3: + /* TGSI_OPCODE_DOT3 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_mul( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Y ); + FETCH( func, *inst, 2, 1, CHAN_Y ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Z ); + FETCH( func, *inst, 2, 1, CHAN_Z ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DP4: + /* TGSI_OPCODE_DOT4 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_mul( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Y ); + FETCH( func, *inst, 2, 1, CHAN_Y ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Z ); + FETCH( func, *inst, 2, 1, CHAN_Z ); + emit_mul(func, 1, 2 ); + emit_add(func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_W ); + FETCH( func, *inst, 2, 1, CHAN_W ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DST: + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); + STORE( func, *inst, 0, 0, CHAN_X ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { + FETCH( func, *inst, 0, 0, CHAN_Y ); + FETCH( func, *inst, 1, 1, CHAN_Y ); + emit_mul( func, 0, 1 ); + STORE( func, *inst, 0, 0, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { + FETCH( func, *inst, 0, 0, CHAN_Z ); + STORE( func, *inst, 0, 0, CHAN_Z ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { + FETCH( func, *inst, 0, 1, CHAN_W ); + STORE( func, *inst, 0, 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MIN: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + sse_minps( + func, + make_xmm( 0 ), + make_xmm( 1 ) ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_MAX: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + sse_maxps( + func, + make_xmm( 0 ), + make_xmm( 1 ) ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLT: + /* TGSI_OPCODE_SETLT */ + emit_setcc( func, inst, cc_LessThan ); + break; + + case TGSI_OPCODE_SGE: + /* TGSI_OPCODE_SETGE */ + emit_setcc( func, inst, cc_NotLessThan ); + break; + + case TGSI_OPCODE_MAD: + /* TGSI_OPCODE_MADD */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + FETCH( func, *inst, 2, 2, chan_index ); + emit_mul( func, 0, 1 ); + emit_add( func, 0, 2 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_SUB: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + emit_sub( func, 0, 1 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_LERP: + /* TGSI_OPCODE_LRP */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 1, 1, chan_index ); + FETCH( func, *inst, 2, 2, chan_index ); + emit_sub( func, 1, 2 ); + emit_mul( func, 0, 1 ); + emit_add( func, 0, 2 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_CND: + return 0; + break; + + case TGSI_OPCODE_CND0: + return 0; + break; + + case TGSI_OPCODE_DOT2ADD: + /* TGSI_OPCODE_DP2A */ + return 0; + break; + + case TGSI_OPCODE_INDEX: + return 0; + break; + + case TGSI_OPCODE_NEGATE: + return 0; + break; + + case TGSI_OPCODE_FRAC: + /* TGSI_OPCODE_FRC */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_frc( func, 0 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_CLAMP: + return 0; + break; + + case TGSI_OPCODE_FLOOR: + /* TGSI_OPCODE_FLR */ + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_flr( func, 0 ); + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_ROUND: + return 0; + break; + + case TGSI_OPCODE_EXPBASE2: + /* TGSI_OPCODE_EX2 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_ex2( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_LOGBASE2: + /* TGSI_OPCODE_LG2 */ + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_lg2( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_POWER: + /* TGSI_OPCODE_POW */ + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_pow( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_CROSSPRODUCT: + /* TGSI_OPCODE_XPD */ + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { + FETCH( func, *inst, 1, 1, CHAN_Z ); + FETCH( func, *inst, 3, 0, CHAN_Z ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + FETCH( func, *inst, 0, 0, CHAN_Y ); + FETCH( func, *inst, 4, 1, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { + emit_MOV( func, 2, 0 ); + emit_mul( func, 2, 1 ); + emit_MOV( func, 5, 3 ); + emit_mul( func, 5, 4 ); + emit_sub( func, 2, 5 ); + STORE( func, *inst, 2, 0, CHAN_X ); + } + if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + FETCH( func, *inst, 2, 1, CHAN_X ); + FETCH( func, *inst, 5, 0, CHAN_X ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { + emit_mul( func, 3, 2 ); + emit_mul( func, 1, 5 ); + emit_sub( func, 3, 1 ); + STORE( func, *inst, 3, 0, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { + emit_mul( func, 5, 4 ); + emit_mul( func, 0, 2 ); + emit_sub( func, 5, 0 ); + STORE( func, *inst, 5, 0, CHAN_Z ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); + STORE( func, *inst, 0, 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_MULTIPLYMATRIX: + return 0; + break; + + case TGSI_OPCODE_ABS: + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + FETCH( func, *inst, 0, 0, chan_index ); + emit_abs( func, 0) ; + + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_RCC: + return 0; + break; + + case TGSI_OPCODE_DPH: + FETCH( func, *inst, 0, 0, CHAN_X ); + FETCH( func, *inst, 1, 1, CHAN_X ); + emit_mul( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Y ); + FETCH( func, *inst, 2, 1, CHAN_Y ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 0, CHAN_Z ); + FETCH( func, *inst, 2, 1, CHAN_Z ); + emit_mul( func, 1, 2 ); + emit_add( func, 0, 1 ); + FETCH( func, *inst, 1, 1, CHAN_W ); + emit_add( func, 0, 1 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_COS: + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_cos( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_DDX: + return 0; + break; + + case TGSI_OPCODE_DDY: + return 0; + break; + + case TGSI_OPCODE_KIL: + emit_kil( func, &inst->FullSrcRegisters[0] ); + break; + + case TGSI_OPCODE_PK2H: + return 0; + break; + + case TGSI_OPCODE_PK2US: + return 0; + break; + + case TGSI_OPCODE_PK4B: + return 0; + break; + + case TGSI_OPCODE_PK4UB: + return 0; + break; + + case TGSI_OPCODE_RFL: + return 0; + break; + + case TGSI_OPCODE_SEQ: + return 0; + break; + + case TGSI_OPCODE_SFL: + return 0; + break; + + case TGSI_OPCODE_SGT: + return 0; + break; + + case TGSI_OPCODE_SIN: + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_sin( func, 0 ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + break; + + case TGSI_OPCODE_SLE: + return 0; + break; + + case TGSI_OPCODE_SNE: + return 0; + break; + + case TGSI_OPCODE_STR: + return 0; + break; + + case TGSI_OPCODE_TEX: + if (0) { + /* Disable dummy texture code: + */ + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 0, 0, chan_index ); + } + } + else { + return 0; + } + break; + + case TGSI_OPCODE_TXD: + return 0; + break; + + case TGSI_OPCODE_UP2H: + return 0; + break; + + case TGSI_OPCODE_UP2US: + return 0; + break; + + case TGSI_OPCODE_UP4B: + return 0; + break; + + case TGSI_OPCODE_UP4UB: + return 0; + break; + + case TGSI_OPCODE_X2D: + return 0; + break; + + case TGSI_OPCODE_ARA: + return 0; + break; + + case TGSI_OPCODE_ARR: + return 0; + break; + + case TGSI_OPCODE_BRA: + return 0; + break; + + case TGSI_OPCODE_CAL: + return 0; + break; + + case TGSI_OPCODE_RET: + emit_ret( func ); + break; + + case TGSI_OPCODE_END: + break; + + case TGSI_OPCODE_SSG: + return 0; + break; + + case TGSI_OPCODE_CMP: + emit_cmp (func, inst); + break; + + case TGSI_OPCODE_SCS: + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) { + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_cos( func, 0 ); + STORE( func, *inst, 0, 0, CHAN_X ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_sin( func, 0 ); + STORE( func, *inst, 0, 0, CHAN_Y ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) { + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ); + STORE( func, *inst, 0, 0, CHAN_Z ); + } + IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) { + emit_tempf( + func, + 0, + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ); + STORE( func, *inst, 0, 0, CHAN_W ); + } + break; + + case TGSI_OPCODE_TXB: + return 0; + break; + + case TGSI_OPCODE_NRM: + return 0; + break; + + case TGSI_OPCODE_DIV: + return 0; + break; + + case TGSI_OPCODE_DP2: + return 0; + break; + + case TGSI_OPCODE_TXL: + return 0; + break; + + case TGSI_OPCODE_BRK: + return 0; + break; + + case TGSI_OPCODE_IF: + return 0; + break; + + case TGSI_OPCODE_LOOP: + return 0; + break; + + case TGSI_OPCODE_REP: + return 0; + break; + + case TGSI_OPCODE_ELSE: + return 0; + break; + + case TGSI_OPCODE_ENDIF: + return 0; + break; + + case TGSI_OPCODE_ENDLOOP: + return 0; + break; + + case TGSI_OPCODE_ENDREP: + return 0; + break; + + case TGSI_OPCODE_PUSHA: + return 0; + break; + + case TGSI_OPCODE_POPA: + return 0; + break; + + case TGSI_OPCODE_CEIL: + return 0; + break; + + case TGSI_OPCODE_I2F: + return 0; + break; + + case TGSI_OPCODE_NOT: + return 0; + break; + + case TGSI_OPCODE_TRUNC: + return 0; + break; + + case TGSI_OPCODE_SHL: + return 0; + break; + + case TGSI_OPCODE_SHR: + return 0; + break; + + case TGSI_OPCODE_AND: + return 0; + break; + + case TGSI_OPCODE_OR: + return 0; + break; + + case TGSI_OPCODE_MOD: + return 0; + break; + + case TGSI_OPCODE_XOR: + return 0; + break; + + case TGSI_OPCODE_SAD: + return 0; + break; + + case TGSI_OPCODE_TXF: + return 0; + break; + + case TGSI_OPCODE_TXQ: + return 0; + break; + + case TGSI_OPCODE_CONT: + return 0; + break; + + case TGSI_OPCODE_EMIT: + return 0; + break; + + case TGSI_OPCODE_ENDPRIM: + return 0; + break; + + default: + return 0; + } + + return 1; +} + +static void +emit_declaration( + struct x86_function *func, + struct tgsi_full_declaration *decl ) +{ + if( decl->Declaration.File == TGSI_FILE_INPUT ) { + unsigned first, last, mask; + unsigned i, j; + + first = decl->DeclarationRange.First; + last = decl->DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + for( i = first; i <= last; i++ ) { + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + switch( decl->Declaration.Interpolate ) { + case TGSI_INTERPOLATE_CONSTANT: + emit_coef_a0( func, 0, i, j ); + emit_inputs( func, 0, i, j ); + break; + + case TGSI_INTERPOLATE_LINEAR: + emit_tempf( func, 0, 0, TGSI_SWIZZLE_X ); + emit_coef_dadx( func, 1, i, j ); + emit_tempf( func, 2, 0, TGSI_SWIZZLE_Y ); + emit_coef_dady( func, 3, i, j ); + emit_mul( func, 0, 1 ); /* x * dadx */ + emit_coef_a0( func, 4, i, j ); + emit_mul( func, 2, 3 ); /* y * dady */ + emit_add( func, 0, 4 ); /* x * dadx + a0 */ + emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */ + emit_inputs( func, 0, i, j ); + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + emit_tempf( func, 0, 0, TGSI_SWIZZLE_X ); + emit_coef_dadx( func, 1, i, j ); + emit_tempf( func, 2, 0, TGSI_SWIZZLE_Y ); + emit_coef_dady( func, 3, i, j ); + emit_mul( func, 0, 1 ); /* x * dadx */ + emit_tempf( func, 4, 0, TGSI_SWIZZLE_W ); + emit_coef_a0( func, 5, i, j ); + emit_rcp( func, 4, 4 ); /* 1.0 / w */ + emit_mul( func, 2, 3 ); /* y * dady */ + emit_add( func, 0, 5 ); /* x * dadx + a0 */ + emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */ + emit_mul( func, 0, 4 ); /* (x * dadx + y * dady + a0) / w */ + emit_inputs( func, 0, i, j ); + break; + + default: + assert( 0 ); + break; + } + } + } + } + } +} + +static void aos_to_soa( struct x86_function *func, + uint arg_aos, + uint arg_soa, + uint arg_num, + uint arg_stride ) +{ + struct x86_reg soa_input = x86_make_reg( file_REG32, reg_AX ); + struct x86_reg aos_input = x86_make_reg( file_REG32, reg_BX ); + struct x86_reg num_inputs = x86_make_reg( file_REG32, reg_CX ); + struct x86_reg stride = x86_make_reg( file_REG32, reg_DX ); + int inner_loop; + + + /* Save EBX */ + x86_push( func, x86_make_reg( file_REG32, reg_BX ) ); + + x86_mov( func, aos_input, x86_fn_arg( func, arg_aos ) ); + x86_mov( func, soa_input, x86_fn_arg( func, arg_soa ) ); + x86_mov( func, num_inputs, x86_fn_arg( func, arg_num ) ); + x86_mov( func, stride, x86_fn_arg( func, arg_stride ) ); + + /* do */ + inner_loop = x86_get_label( func ); + { + x86_push( func, aos_input ); + sse_movlps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); + sse_movlps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); + x86_add( func, aos_input, stride ); + sse_movhps( func, make_xmm( 0 ), x86_make_disp( aos_input, 0 ) ); + sse_movhps( func, make_xmm( 3 ), x86_make_disp( aos_input, 8 ) ); + x86_add( func, aos_input, stride ); + sse_movlps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); + sse_movlps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); + x86_add( func, aos_input, stride ); + sse_movhps( func, make_xmm( 1 ), x86_make_disp( aos_input, 0 ) ); + sse_movhps( func, make_xmm( 4 ), x86_make_disp( aos_input, 8 ) ); + x86_pop( func, aos_input ); + + sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) ); + sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) ); + sse_shufps( func, make_xmm( 0 ), make_xmm( 1 ), 0x88 ); + sse_shufps( func, make_xmm( 2 ), make_xmm( 1 ), 0xdd ); + sse_shufps( func, make_xmm( 3 ), make_xmm( 4 ), 0x88 ); + sse_shufps( func, make_xmm( 5 ), make_xmm( 4 ), 0xdd ); + + sse_movups( func, x86_make_disp( soa_input, 0 ), make_xmm( 0 ) ); + sse_movups( func, x86_make_disp( soa_input, 16 ), make_xmm( 2 ) ); + sse_movups( func, x86_make_disp( soa_input, 32 ), make_xmm( 3 ) ); + sse_movups( func, x86_make_disp( soa_input, 48 ), make_xmm( 5 ) ); + + /* Advance to next input */ + x86_lea( func, aos_input, x86_make_disp(aos_input, 16) ); + x86_lea( func, soa_input, x86_make_disp(soa_input, 64) ); + } + /* while --num_inputs */ + x86_dec( func, num_inputs ); + x86_jcc( func, cc_NE, inner_loop ); + + /* Restore EBX */ + x86_pop( func, aos_input ); +} + +static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, uint stride ) +{ + struct x86_reg soa_output; + struct x86_reg aos_output; + struct x86_reg num_outputs; + struct x86_reg temp; + int inner_loop; + + soa_output = x86_make_reg( file_REG32, reg_AX ); + aos_output = x86_make_reg( file_REG32, reg_BX ); + num_outputs = x86_make_reg( file_REG32, reg_CX ); + temp = x86_make_reg( file_REG32, reg_DX ); + + /* Save EBX */ + x86_push( func, aos_output ); + + x86_mov( func, soa_output, x86_fn_arg( func, soa ) ); + x86_mov( func, aos_output, x86_fn_arg( func, aos ) ); + x86_mov( func, num_outputs, x86_fn_arg( func, num ) ); + + /* do */ + inner_loop = x86_get_label( func ); + { + sse_movups( func, make_xmm( 0 ), x86_make_disp( soa_output, 0 ) ); + sse_movups( func, make_xmm( 1 ), x86_make_disp( soa_output, 16 ) ); + sse_movups( func, make_xmm( 3 ), x86_make_disp( soa_output, 32 ) ); + sse_movups( func, make_xmm( 4 ), x86_make_disp( soa_output, 48 ) ); + + sse_movaps( func, make_xmm( 2 ), make_xmm( 0 ) ); + sse_movaps( func, make_xmm( 5 ), make_xmm( 3 ) ); + sse_unpcklps( func, make_xmm( 0 ), make_xmm( 1 ) ); + sse_unpckhps( func, make_xmm( 2 ), make_xmm( 1 ) ); + sse_unpcklps( func, make_xmm( 3 ), make_xmm( 4 ) ); + sse_unpckhps( func, make_xmm( 5 ), make_xmm( 4 ) ); + + x86_mov( func, temp, x86_fn_arg( func, stride ) ); + x86_push( func, aos_output ); + sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) ); + sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) ); + x86_add( func, aos_output, temp ); + sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) ); + sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) ); + x86_add( func, aos_output, temp ); + sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) ); + sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) ); + x86_add( func, aos_output, temp ); + sse_movhps( func, x86_make_disp( aos_output, 0 ), make_xmm( 2 ) ); + sse_movhps( func, x86_make_disp( aos_output, 8 ), make_xmm( 5 ) ); + x86_pop( func, aos_output ); + + /* Advance to next output */ + x86_lea( func, aos_output, x86_make_disp(aos_output, 16) ); + x86_lea( func, soa_output, x86_make_disp(soa_output, 64) ); + } + /* while --num_outputs */ + x86_dec( func, num_outputs ); + x86_jcc( func, cc_NE, inner_loop ); + + /* Restore EBX */ + x86_pop( func, aos_output ); +} + +/** + * Translate a TGSI vertex/fragment shader to SSE2 code. + * Slightly different things are done for vertex vs. fragment shaders. + * + * Note that fragment shaders are responsible for interpolating shader + * inputs. Because on x86 we have only 4 GP registers, and here we + * have 5 shader arguments (input, output, const, temp and coef), the + * code is split into two phases -- DECLARATION and INSTRUCTION phase. + * GP register holding the output argument is aliased with the coeff + * argument, as outputs are not needed in the DECLARATION phase. + * + * \param tokens the TGSI input shader + * \param func the output SSE code/function + * \param immediates buffer to place immediates, later passed to SSE func + * \param return 1 for success, 0 if translation failed + */ +unsigned +tgsi_emit_sse2( + const struct tgsi_token *tokens, + struct x86_function *func, + float (*immediates)[4], + boolean do_swizzles ) +{ + struct tgsi_parse_context parse; + boolean instruction_phase = FALSE; + unsigned ok = 1; + uint num_immediates = 0; + + func->csr = func->store; + + tgsi_parse_init( &parse, tokens ); + + /* Can't just use EDI, EBX without save/restoring them: + */ + x86_push( + func, + get_immediate_base() ); + + x86_push( + func, + get_temp_base() ); + + + /* + * Different function args for vertex/fragment shaders: + */ + if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { + /* DECLARATION phase, do not load output argument. */ + x86_mov( + func, + get_input_base(), + x86_fn_arg( func, 1 ) ); + /* skipping outputs argument here */ + x86_mov( + func, + get_const_base(), + x86_fn_arg( func, 3 ) ); + x86_mov( + func, + get_temp_base(), + x86_fn_arg( func, 4 ) ); + x86_mov( + func, + get_coef_base(), + x86_fn_arg( func, 5 ) ); + x86_mov( + func, + get_immediate_base(), + x86_fn_arg( func, 6 ) ); + } + else { + assert(parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX); + + if (do_swizzles) + aos_to_soa( func, + 6, /* aos_input */ + 1, /* machine->input */ + 7, /* num_inputs */ + 8 ); /* input_stride */ + + x86_mov( + func, + get_input_base(), + x86_fn_arg( func, 1 ) ); + x86_mov( + func, + get_output_base(), + x86_fn_arg( func, 2 ) ); + x86_mov( + func, + get_const_base(), + x86_fn_arg( func, 3 ) ); + x86_mov( + func, + get_temp_base(), + x86_fn_arg( func, 4 ) ); + x86_mov( + func, + get_immediate_base(), + x86_fn_arg( func, 5 ) ); + } + + while( !tgsi_parse_end_of_tokens( &parse ) && ok ) { + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_DECLARATION: + if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { + emit_declaration( + func, + &parse.FullToken.FullDeclaration ); + } + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { + if( !instruction_phase ) { + /* INSTRUCTION phase, overwrite coeff with output. */ + instruction_phase = TRUE; + x86_mov( + func, + get_output_base(), + x86_fn_arg( func, 2 ) ); + } + } + + ok = emit_instruction( + func, + &parse.FullToken.FullInstruction ); + + if (!ok) { + debug_printf("failed to translate tgsi opcode %d to SSE (%s)\n", + parse.FullToken.FullInstruction.Instruction.Opcode, + parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ? + "vertex shader" : "fragment shader"); + } + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + /* simply copy the immediate values into the next immediates[] slot */ + { + const uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; + uint i; + assert(size <= 4); + assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES); + for( i = 0; i < size; i++ ) { + immediates[num_immediates][i] = + parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; + } +#if 0 + debug_printf("SSE FS immediate[%d] = %f %f %f %f\n", + num_immediates, + immediates[num_immediates][0], + immediates[num_immediates][1], + immediates[num_immediates][2], + immediates[num_immediates][3]); +#endif + num_immediates++; + } + break; + + default: + ok = 0; + assert( 0 ); + } + } + + if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) { + if (do_swizzles) + soa_to_aos( func, 9, 2, 10, 11 ); + } + + /* Can't just use EBX, EDI without save/restoring them: + */ + x86_pop( + func, + get_temp_base() ); + + x86_pop( + func, + get_immediate_base() ); + + emit_ret( func ); + + tgsi_parse_free( &parse ); + + return ok; +} + +#endif /* PIPE_ARCH_X86 */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/tgsi_sse2.h new file mode 100644 index 0000000000..af838b2a25 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.h @@ -0,0 +1,49 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_SSE2_H +#define TGSI_SSE2_H + +#if defined __cplusplus +extern "C" { +#endif + +struct tgsi_token; +struct x86_function; + +unsigned +tgsi_emit_sse2( + const struct tgsi_token *tokens, + struct x86_function *function, + float (*immediates)[4], + boolean do_swizzles ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_SSE2_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c new file mode 100644 index 0000000000..35cb3055bb --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -0,0 +1,1221 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "tgsi_text.h" +#include "tgsi_build.h" +#include "tgsi_parse.h" +#include "tgsi_sanity.h" +#include "tgsi_util.h" + +static boolean is_alpha_underscore( const char *cur ) +{ + return + (*cur >= 'a' && *cur <= 'z') || + (*cur >= 'A' && *cur <= 'Z') || + *cur == '_'; +} + +static boolean is_digit( const char *cur ) +{ + return *cur >= '0' && *cur <= '9'; +} + +static boolean is_digit_alpha_underscore( const char *cur ) +{ + return is_digit( cur ) || is_alpha_underscore( cur ); +} + +static boolean str_match_no_case( const char **pcur, const char *str ) +{ + const char *cur = *pcur; + + while (*str != '\0' && *str == toupper( *cur )) { + str++; + cur++; + } + if (*str == '\0') { + *pcur = cur; + return TRUE; + } + return FALSE; +} + +/* Eat zero or more whitespaces. + */ +static void eat_opt_white( const char **pcur ) +{ + while (**pcur == ' ' || **pcur == '\t' || **pcur == '\n') + (*pcur)++; +} + +/* Eat one or more whitespaces. + * Return TRUE if at least one whitespace eaten. + */ +static boolean eat_white( const char **pcur ) +{ + const char *cur = *pcur; + + eat_opt_white( pcur ); + return *pcur > cur; +} + +/* Parse unsigned integer. + * No checks for overflow. + */ +static boolean parse_uint( const char **pcur, uint *val ) +{ + const char *cur = *pcur; + + if (is_digit( cur )) { + *val = *cur++ - '0'; + while (is_digit( cur )) + *val = *val * 10 + *cur++ - '0'; + *pcur = cur; + return TRUE; + } + return FALSE; +} + +/* Parse floating point. + */ +static boolean parse_float( const char **pcur, float *val ) +{ + const char *cur = *pcur; + boolean integral_part = FALSE; + boolean fractional_part = FALSE; + + *val = (float) atof( cur ); + + if (*cur == '-' || *cur == '+') + cur++; + if (is_digit( cur )) { + cur++; + integral_part = TRUE; + while (is_digit( cur )) + cur++; + } + if (*cur == '.') { + cur++; + if (is_digit( cur )) { + cur++; + fractional_part = TRUE; + while (is_digit( cur )) + cur++; + } + } + if (!integral_part && !fractional_part) + return FALSE; + if (toupper( *cur ) == 'E') { + cur++; + if (*cur == '-' || *cur == '+') + cur++; + if (is_digit( cur )) { + cur++; + while (is_digit( cur )) + cur++; + } + else + return FALSE; + } + *pcur = cur; + return TRUE; +} + +struct translate_ctx +{ + const char *text; + const char *cur; + struct tgsi_token *tokens; + struct tgsi_token *tokens_cur; + struct tgsi_token *tokens_end; + struct tgsi_header *header; +}; + +static void report_error( struct translate_ctx *ctx, const char *msg ) +{ + debug_printf( "\nError: %s", msg ); +} + +/* Parse shader header. + * Return TRUE for one of the following headers. + * FRAG1.1 + * GEOM1.1 + * VERT1.1 + */ +static boolean parse_header( struct translate_ctx *ctx ) +{ + uint processor; + + if (str_match_no_case( &ctx->cur, "FRAG1.1" )) + processor = TGSI_PROCESSOR_FRAGMENT; + else if (str_match_no_case( &ctx->cur, "VERT1.1" )) + processor = TGSI_PROCESSOR_VERTEX; + else if (str_match_no_case( &ctx->cur, "GEOM1.1" )) + processor = TGSI_PROCESSOR_GEOMETRY; + else { + report_error( ctx, "Unknown header" ); + return FALSE; + } + + if (ctx->tokens_cur >= ctx->tokens_end) + return FALSE; + *(struct tgsi_version *) ctx->tokens_cur++ = tgsi_build_version(); + + if (ctx->tokens_cur >= ctx->tokens_end) + return FALSE; + ctx->header = (struct tgsi_header *) ctx->tokens_cur++; + *ctx->header = tgsi_build_header(); + + if (ctx->tokens_cur >= ctx->tokens_end) + return FALSE; + *(struct tgsi_processor *) ctx->tokens_cur++ = tgsi_build_processor( processor, ctx->header ); + + return TRUE; +} + +static boolean parse_label( struct translate_ctx *ctx, uint *val ) +{ + const char *cur = ctx->cur; + + if (parse_uint( &cur, val )) { + eat_opt_white( &cur ); + if (*cur == ':') { + cur++; + ctx->cur = cur; + return TRUE; + } + } + return FALSE; +} + +static const char *file_names[TGSI_FILE_COUNT] = +{ + "NULL", + "CONST", + "IN", + "OUT", + "TEMP", + "SAMP", + "ADDR", + "IMM" +}; + +static boolean +parse_file( const char **pcur, uint *file ) +{ + uint i; + + for (i = 0; i < TGSI_FILE_COUNT; i++) { + const char *cur = *pcur; + + if (str_match_no_case( &cur, file_names[i] )) { + if (!is_digit_alpha_underscore( cur )) { + *pcur = cur; + *file = i; + return TRUE; + } + } + } + return FALSE; +} + +static boolean +parse_opt_writemask( + struct translate_ctx *ctx, + uint *writemask ) +{ + const char *cur; + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == '.') { + cur++; + *writemask = TGSI_WRITEMASK_NONE; + eat_opt_white( &cur ); + if (toupper( *cur ) == 'X') { + cur++; + *writemask |= TGSI_WRITEMASK_X; + } + if (toupper( *cur ) == 'Y') { + cur++; + *writemask |= TGSI_WRITEMASK_Y; + } + if (toupper( *cur ) == 'Z') { + cur++; + *writemask |= TGSI_WRITEMASK_Z; + } + if (toupper( *cur ) == 'W') { + cur++; + *writemask |= TGSI_WRITEMASK_W; + } + + if (*writemask == TGSI_WRITEMASK_NONE) { + report_error( ctx, "Writemask expected" ); + return FALSE; + } + + ctx->cur = cur; + } + else { + *writemask = TGSI_WRITEMASK_XYZW; + } + return TRUE; +} + +/* ::= `[' + */ +static boolean +parse_register_file_bracket( + struct translate_ctx *ctx, + uint *file ) +{ + if (!parse_file( &ctx->cur, file )) { + report_error( ctx, "Unknown register file" ); + return FALSE; + } + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '[') { + report_error( ctx, "Expected `['" ); + return FALSE; + } + ctx->cur++; + return TRUE; +} + +/* ::= + */ +static boolean +parse_register_file_bracket_index( + struct translate_ctx *ctx, + uint *file, + int *index ) +{ + uint uindex; + + if (!parse_register_file_bracket( ctx, file )) + return FALSE; + eat_opt_white( &ctx->cur ); + if (!parse_uint( &ctx->cur, &uindex )) { + report_error( ctx, "Expected literal unsigned integer" ); + return FALSE; + } + *index = (int) uindex; + return TRUE; +} + +/* Parse destination register operand. + * ::= `]' + */ +static boolean +parse_register_dst( + struct translate_ctx *ctx, + uint *file, + int *index ) +{ + if (!parse_register_file_bracket_index( ctx, file, index )) + return FALSE; + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ']') { + report_error( ctx, "Expected `]'" ); + return FALSE; + } + ctx->cur++; + return TRUE; +} + +/* Parse source register operand. + * ::= `]' | + * `]' | + * `+' `]' | + * `-' `]' + */ +static boolean +parse_register_src( + struct translate_ctx *ctx, + uint *file, + int *index, + uint *ind_file, + int *ind_index ) +{ + const char *cur; + uint uindex; + + if (!parse_register_file_bracket( ctx, file )) + return FALSE; + eat_opt_white( &ctx->cur ); + cur = ctx->cur; + if (parse_file( &cur, ind_file )) { + if (!parse_register_dst( ctx, ind_file, ind_index )) + return FALSE; + eat_opt_white( &ctx->cur ); + if (*ctx->cur == '+' || *ctx->cur == '-') { + boolean negate; + + negate = *ctx->cur == '-'; + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (!parse_uint( &ctx->cur, &uindex )) { + report_error( ctx, "Expected literal unsigned integer" ); + return FALSE; + } + if (negate) + *index = -(int) uindex; + else + *index = (int) uindex; + } + else { + *index = 0; + } + } + else { + if (!parse_uint( &ctx->cur, &uindex )) { + report_error( ctx, "Expected literal unsigned integer" ); + return FALSE; + } + *index = (int) uindex; + *ind_file = TGSI_FILE_NULL; + *ind_index = 0; + } + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ']') { + report_error( ctx, "Expected `]'" ); + return FALSE; + } + ctx->cur++; + return TRUE; +} + +/* Parse register declaration. + * ::= `]' | + * `..' `]' + */ +static boolean +parse_register_dcl( + struct translate_ctx *ctx, + uint *file, + int *first, + int *last ) +{ + if (!parse_register_file_bracket_index( ctx, file, first )) + return FALSE; + eat_opt_white( &ctx->cur ); + if (ctx->cur[0] == '.' && ctx->cur[1] == '.') { + uint uindex; + + ctx->cur += 2; + eat_opt_white( &ctx->cur ); + if (!parse_uint( &ctx->cur, &uindex )) { + report_error( ctx, "Expected literal integer" ); + return FALSE; + } + *last = (int) uindex; + eat_opt_white( &ctx->cur ); + } + else { + *last = *first; + } + if (*ctx->cur != ']') { + report_error( ctx, "Expected `]' or `..'" ); + return FALSE; + } + ctx->cur++; + return TRUE; +} + +static const char *modulate_names[TGSI_MODULATE_COUNT] = +{ + "_1X", + "_2X", + "_4X", + "_8X", + "_D2", + "_D4", + "_D8" +}; + +static boolean +parse_dst_operand( + struct translate_ctx *ctx, + struct tgsi_full_dst_register *dst ) +{ + uint file; + int index; + uint writemask; + const char *cur; + + if (!parse_register_dst( ctx, &file, &index )) + return FALSE; + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == '_') { + uint i; + + for (i = 0; i < TGSI_MODULATE_COUNT; i++) { + if (str_match_no_case( &cur, modulate_names[i] )) { + if (!is_digit_alpha_underscore( cur )) { + dst->DstRegisterExtModulate.Modulate = i; + ctx->cur = cur; + break; + } + } + } + } + + if (!parse_opt_writemask( ctx, &writemask )) + return FALSE; + + dst->DstRegister.File = file; + dst->DstRegister.Index = index; + dst->DstRegister.WriteMask = writemask; + return TRUE; +} + +static boolean +parse_optional_swizzle( + struct translate_ctx *ctx, + uint swizzle[4], + boolean *parsed_swizzle, + boolean *parsed_extswizzle ) +{ + const char *cur = ctx->cur; + + *parsed_swizzle = FALSE; + *parsed_extswizzle = FALSE; + + eat_opt_white( &cur ); + if (*cur == '.') { + uint i; + + cur++; + eat_opt_white( &cur ); + for (i = 0; i < 4; i++) { + if (toupper( *cur ) == 'X') + swizzle[i] = TGSI_SWIZZLE_X; + else if (toupper( *cur ) == 'Y') + swizzle[i] = TGSI_SWIZZLE_Y; + else if (toupper( *cur ) == 'Z') + swizzle[i] = TGSI_SWIZZLE_Z; + else if (toupper( *cur ) == 'W') + swizzle[i] = TGSI_SWIZZLE_W; + else { + if (*cur == '0') + swizzle[i] = TGSI_EXTSWIZZLE_ZERO; + else if (*cur == '1') + swizzle[i] = TGSI_EXTSWIZZLE_ONE; + else { + report_error( ctx, "Expected register swizzle component `x', `y', `z', `w', `0' or `1'" ); + return FALSE; + } + *parsed_extswizzle = TRUE; + } + cur++; + } + *parsed_swizzle = TRUE; + ctx->cur = cur; + } + return TRUE; +} + +static boolean +parse_src_operand( + struct translate_ctx *ctx, + struct tgsi_full_src_register *src ) +{ + const char *cur; + float value; + uint file; + int index; + uint ind_file; + int ind_index; + uint swizzle[4]; + boolean parsed_swizzle; + boolean parsed_extswizzle; + + if (*ctx->cur == '-') { + cur = ctx->cur; + cur++; + eat_opt_white( &cur ); + if (*cur == '(') { + cur++; + src->SrcRegisterExtMod.Negate = 1; + eat_opt_white( &cur ); + ctx->cur = cur; + } + } + + if (*ctx->cur == '|') { + ctx->cur++; + eat_opt_white( &ctx->cur ); + src->SrcRegisterExtMod.Absolute = 1; + } + + if (*ctx->cur == '-') { + ctx->cur++; + eat_opt_white( &ctx->cur ); + src->SrcRegister.Negate = 1; + } + + cur = ctx->cur; + if (parse_float( &cur, &value )) { + if (value == 2.0f) { + eat_opt_white( &cur ); + if (*cur != '*') { + report_error( ctx, "Expected `*'" ); + return FALSE; + } + cur++; + if (*cur != '(') { + report_error( ctx, "Expected `('" ); + return FALSE; + } + cur++; + src->SrcRegisterExtMod.Scale2X = 1; + eat_opt_white( &cur ); + ctx->cur = cur; + } + } + + if (*ctx->cur == '(') { + ctx->cur++; + eat_opt_white( &ctx->cur ); + src->SrcRegisterExtMod.Bias = 1; + } + + cur = ctx->cur; + if (parse_float( &cur, &value )) { + if (value == 1.0f) { + eat_opt_white( &cur ); + if (*cur != '-') { + report_error( ctx, "Expected `-'" ); + return FALSE; + } + cur++; + if (*cur != '(') { + report_error( ctx, "Expected `('" ); + return FALSE; + } + cur++; + src->SrcRegisterExtMod.Complement = 1; + eat_opt_white( &cur ); + ctx->cur = cur; + } + } + + if (!parse_register_src( ctx, &file, &index, &ind_file, &ind_index )) + return FALSE; + src->SrcRegister.File = file; + src->SrcRegister.Index = index; + if (ind_file != TGSI_FILE_NULL) { + src->SrcRegister.Indirect = 1; + src->SrcRegisterInd.File = ind_file; + src->SrcRegisterInd.Index = ind_index; + } + + /* Parse optional swizzle. + */ + if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, &parsed_extswizzle )) { + if (parsed_extswizzle) { + assert( parsed_swizzle ); + + src->SrcRegisterExtSwz.ExtSwizzleX = swizzle[0]; + src->SrcRegisterExtSwz.ExtSwizzleY = swizzle[1]; + src->SrcRegisterExtSwz.ExtSwizzleZ = swizzle[2]; + src->SrcRegisterExtSwz.ExtSwizzleW = swizzle[3]; + } + else if (parsed_swizzle) { + src->SrcRegister.SwizzleX = swizzle[0]; + src->SrcRegister.SwizzleY = swizzle[1]; + src->SrcRegister.SwizzleZ = swizzle[2]; + src->SrcRegister.SwizzleW = swizzle[3]; + } + } + + if (src->SrcRegisterExtMod.Complement) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + } + + if (src->SrcRegisterExtMod.Bias) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '-') { + report_error( ctx, "Expected `-'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (!parse_float( &ctx->cur, &value )) { + report_error( ctx, "Expected literal floating point" ); + return FALSE; + } + if (value != 0.5f) { + report_error( ctx, "Expected 0.5" ); + return FALSE; + } + } + + if (src->SrcRegisterExtMod.Scale2X) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + } + + if (src->SrcRegisterExtMod.Absolute) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '|') { + report_error( ctx, "Expected `|'" ); + return FALSE; + } + ctx->cur++; + } + + if (src->SrcRegisterExtMod.Negate) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ')') { + report_error( ctx, "Expected `)'" ); + return FALSE; + } + ctx->cur++; + } + + return TRUE; +} + +struct opcode_info +{ + uint num_dst; + uint num_src; + uint is_tex; + uint is_branch; + const char *mnemonic; +}; + +static const struct opcode_info opcode_info[TGSI_OPCODE_LAST] = +{ + { 1, 1, 0, 0, "ARL" }, + { 1, 1, 0, 0, "MOV" }, + { 1, 1, 0, 0, "LIT" }, + { 1, 1, 0, 0, "RCP" }, + { 1, 1, 0, 0, "RSQ" }, + { 1, 1, 0, 0, "EXP" }, + { 1, 1, 0, 0, "LOG" }, + { 1, 2, 0, 0, "MUL" }, + { 1, 2, 0, 0, "ADD" }, + { 1, 2, 0, 0, "DP3" }, + { 1, 2, 0, 0, "DP4" }, + { 1, 2, 0, 0, "DST" }, + { 1, 2, 0, 0, "MIN" }, + { 1, 2, 0, 0, "MAX" }, + { 1, 2, 0, 0, "SLT" }, + { 1, 2, 0, 0, "SGE" }, + { 1, 3, 0, 0, "MAD" }, + { 1, 2, 0, 0, "SUB" }, + { 1, 3, 0, 0, "LERP" }, + { 1, 3, 0, 0, "CND" }, + { 1, 3, 0, 0, "CND0" }, + { 1, 3, 0, 0, "DOT2ADD" }, + { 1, 2, 0, 0, "INDEX" }, + { 1, 1, 0, 0, "NEGATE" }, + { 1, 1, 0, 0, "FRAC" }, + { 1, 3, 0, 0, "CLAMP" }, + { 1, 1, 0, 0, "FLOOR" }, + { 1, 1, 0, 0, "ROUND" }, + { 1, 1, 0, 0, "EXPBASE2" }, + { 1, 1, 0, 0, "LOGBASE2" }, + { 1, 2, 0, 0, "POWER" }, + { 1, 2, 0, 0, "CROSSPRODUCT" }, + { 1, 2, 0, 0, "MULTIPLYMATRIX" }, + { 1, 1, 0, 0, "ABS" }, + { 1, 1, 0, 0, "RCC" }, + { 1, 2, 0, 0, "DPH" }, + { 1, 1, 0, 0, "COS" }, + { 1, 1, 0, 0, "DDX" }, + { 1, 1, 0, 0, "DDY" }, + { 0, 1, 0, 0, "KILP" }, + { 1, 1, 0, 0, "PK2H" }, + { 1, 1, 0, 0, "PK2US" }, + { 1, 1, 0, 0, "PK4B" }, + { 1, 1, 0, 0, "PK4UB" }, + { 1, 2, 0, 0, "RFL" }, + { 1, 2, 0, 0, "SEQ" }, + { 1, 2, 0, 0, "SFL" }, + { 1, 2, 0, 0, "SGT" }, + { 1, 1, 0, 0, "SIN" }, + { 1, 2, 0, 0, "SLE" }, + { 1, 2, 0, 0, "SNE" }, + { 1, 2, 0, 0, "STR" }, + { 1, 2, 1, 0, "TEX" }, + { 1, 4, 1, 0, "TXD" }, + { 1, 2, 1, 0, "TXP" }, + { 1, 1, 0, 0, "UP2H" }, + { 1, 1, 0, 0, "UP2US" }, + { 1, 1, 0, 0, "UP4B" }, + { 1, 1, 0, 0, "UP4UB" }, + { 1, 3, 0, 0, "X2D" }, + { 1, 1, 0, 0, "ARA" }, + { 1, 1, 0, 0, "ARR" }, + { 0, 1, 0, 0, "BRA" }, + { 0, 0, 0, 1, "CAL" }, + { 0, 0, 0, 0, "RET" }, + { 1, 1, 0, 0, "SSG" }, + { 1, 3, 0, 0, "CMP" }, + { 1, 1, 0, 0, "SCS" }, + { 1, 2, 1, 0, "TXB" }, + { 1, 1, 0, 0, "NRM" }, + { 1, 2, 0, 0, "DIV" }, + { 1, 2, 0, 0, "DP2" }, + { 1, 2, 1, 0, "TXL" }, + { 0, 0, 0, 0, "BRK" }, + { 0, 1, 0, 1, "IF" }, + { 0, 0, 0, 0, "LOOP" }, + { 0, 1, 0, 0, "REP" }, + { 0, 0, 0, 1, "ELSE" }, + { 0, 0, 0, 0, "ENDIF" }, + { 0, 0, 0, 0, "ENDLOOP" }, + { 0, 0, 0, 0, "ENDREP" }, + { 0, 1, 0, 0, "PUSHA" }, + { 1, 0, 0, 0, "POPA" }, + { 1, 1, 0, 0, "CEIL" }, + { 1, 1, 0, 0, "I2F" }, + { 1, 1, 0, 0, "NOT" }, + { 1, 1, 0, 0, "TRUNC" }, + { 1, 2, 0, 0, "SHL" }, + { 1, 2, 0, 0, "SHR" }, + { 1, 2, 0, 0, "AND" }, + { 1, 2, 0, 0, "OR" }, + { 1, 2, 0, 0, "MOD" }, + { 1, 2, 0, 0, "XOR" }, + { 1, 3, 0, 0, "SAD" }, + { 1, 2, 1, 0, "TXF" }, + { 1, 2, 1, 0, "TXQ" }, + { 0, 0, 0, 0, "CONT" }, + { 0, 0, 0, 0, "EMIT" }, + { 0, 0, 0, 0, "ENDPRIM" }, + { 0, 0, 0, 1, "BGNLOOP2" }, + { 0, 0, 0, 0, "BGNSUB" }, + { 0, 0, 0, 1, "ENDLOOP2" }, + { 0, 0, 0, 0, "ENDSUB" }, + { 1, 1, 0, 0, "NOISE1" }, + { 1, 1, 0, 0, "NOISE2" }, + { 1, 1, 0, 0, "NOISE3" }, + { 1, 1, 0, 0, "NOISE4" }, + { 0, 0, 0, 0, "NOP" }, + { 1, 2, 0, 0, "M4X3" }, + { 1, 2, 0, 0, "M3X4" }, + { 1, 2, 0, 0, "M3X3" }, + { 1, 2, 0, 0, "M3X2" }, + { 1, 1, 0, 0, "NRM4" }, + { 0, 1, 0, 0, "CALLNZ" }, + { 0, 1, 0, 0, "IFC" }, + { 0, 1, 0, 0, "BREAKC" }, + { 0, 0, 0, 0, "KIL" }, + { 0, 0, 0, 0, "END" }, + { 1, 1, 0, 0, "SWZ" } +}; + +static const char *texture_names[TGSI_TEXTURE_COUNT] = +{ + "UNKNOWN", + "1D", + "2D", + "3D", + "CUBE", + "RECT", + "SHADOW1D", + "SHADOW2D", + "SHADOWRECT" +}; + +static boolean +parse_instruction( + struct translate_ctx *ctx, + boolean has_label ) +{ + uint i; + uint saturate = TGSI_SAT_NONE; + const struct opcode_info *info; + struct tgsi_full_instruction inst; + uint advance; + + /* Parse instruction name. + */ + eat_opt_white( &ctx->cur ); + for (i = 0; i < TGSI_OPCODE_LAST; i++) { + const char *cur = ctx->cur; + + info = &opcode_info[i]; + if (str_match_no_case( &cur, info->mnemonic )) { + if (str_match_no_case( &cur, "_SATNV" )) + saturate = TGSI_SAT_MINUS_PLUS_ONE; + else if (str_match_no_case( &cur, "_SAT" )) + saturate = TGSI_SAT_ZERO_ONE; + + if (info->num_dst + info->num_src + info->is_tex == 0) { + if (!is_digit_alpha_underscore( cur )) { + ctx->cur = cur; + break; + } + } + else if (*cur == '\0' || eat_white( &cur )) { + ctx->cur = cur; + break; + } + } + } + if (i == TGSI_OPCODE_LAST) { + if (has_label) + report_error( ctx, "Unknown opcode" ); + else + report_error( ctx, "Expected `DCL', `IMM' or a label" ); + return FALSE; + } + + inst = tgsi_default_full_instruction(); + inst.Instruction.Opcode = i; + inst.Instruction.Saturate = saturate; + inst.Instruction.NumDstRegs = info->num_dst; + inst.Instruction.NumSrcRegs = info->num_src; + + /* Parse instruction operands. + */ + for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) { + if (i > 0) { + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ',') { + report_error( ctx, "Expected `,'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + } + + if (i < info->num_dst) { + if (!parse_dst_operand( ctx, &inst.FullDstRegisters[i] )) + return FALSE; + } + else if (i < info->num_dst + info->num_src) { + if (!parse_src_operand( ctx, &inst.FullSrcRegisters[i - info->num_dst] )) + return FALSE; + } + else { + uint j; + + for (j = 0; j < TGSI_TEXTURE_COUNT; j++) { + if (str_match_no_case( &ctx->cur, texture_names[j] )) { + if (!is_digit_alpha_underscore( ctx->cur )) { + inst.InstructionExtTexture.Texture = j; + break; + } + } + } + if (j == TGSI_TEXTURE_COUNT) { + report_error( ctx, "Expected texture target" ); + return FALSE; + } + } + } + + if (info->is_branch) { + uint target; + + eat_opt_white( &ctx->cur ); + if (*ctx->cur != ':') { + report_error( ctx, "Expected `:'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + if (!parse_uint( &ctx->cur, &target )) { + report_error( ctx, "Expected a label" ); + return FALSE; + } + inst.InstructionExtLabel.Label = target; + } + + advance = tgsi_build_full_instruction( + &inst, + ctx->tokens_cur, + ctx->header, + (uint) (ctx->tokens_end - ctx->tokens_cur) ); + if (advance == 0) + return FALSE; + ctx->tokens_cur += advance; + + return TRUE; +} + +static const char *semantic_names[TGSI_SEMANTIC_COUNT] = +{ + "POSITION", + "COLOR", + "BCOLOR", + "FOG", + "PSIZE", + "GENERIC", + "NORMAL" +}; + +static const char *interpolate_names[TGSI_INTERPOLATE_COUNT] = +{ + "CONSTANT", + "LINEAR", + "PERSPECTIVE" +}; + +static boolean parse_declaration( struct translate_ctx *ctx ) +{ + struct tgsi_full_declaration decl; + uint file; + int first; + int last; + uint writemask; + const char *cur; + uint advance; + + if (!eat_white( &ctx->cur )) { + report_error( ctx, "Syntax error" ); + return FALSE; + } + if (!parse_register_dcl( ctx, &file, &first, &last )) + return FALSE; + if (!parse_opt_writemask( ctx, &writemask )) + return FALSE; + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = file; + decl.Declaration.UsageMask = writemask; + decl.DeclarationRange.First = first; + decl.DeclarationRange.Last = last; + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == ',') { + uint i; + + cur++; + eat_opt_white( &cur ); + for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) { + if (str_match_no_case( &cur, semantic_names[i] )) { + const char *cur2 = cur; + uint index; + + if (is_digit_alpha_underscore( cur )) + continue; + eat_opt_white( &cur2 ); + if (*cur2 == '[') { + cur2++; + eat_opt_white( &cur2 ); + if (!parse_uint( &cur2, &index )) { + report_error( ctx, "Expected literal integer" ); + return FALSE; + } + eat_opt_white( &cur2 ); + if (*cur2 != ']') { + report_error( ctx, "Expected `]'" ); + return FALSE; + } + cur2++; + + decl.Semantic.SemanticIndex = index; + + cur = cur2; + } + + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = i; + + ctx->cur = cur; + break; + } + } + } + + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == ',') { + uint i; + + cur++; + eat_opt_white( &cur ); + for (i = 0; i < TGSI_INTERPOLATE_COUNT; i++) { + if (str_match_no_case( &cur, interpolate_names[i] )) { + if (is_digit_alpha_underscore( cur )) + continue; + decl.Declaration.Interpolate = i; + + ctx->cur = cur; + break; + } + } + if (i == TGSI_INTERPOLATE_COUNT) { + report_error( ctx, "Expected semantic or interpolate attribute" ); + return FALSE; + } + } + + advance = tgsi_build_full_declaration( + &decl, + ctx->tokens_cur, + ctx->header, + (uint) (ctx->tokens_end - ctx->tokens_cur) ); + if (advance == 0) + return FALSE; + ctx->tokens_cur += advance; + + return TRUE; +} + +static boolean parse_immediate( struct translate_ctx *ctx ) +{ + struct tgsi_full_immediate imm; + uint i; + float values[4]; + uint advance; + + if (!eat_white( &ctx->cur )) { + report_error( ctx, "Syntax error" ); + return FALSE; + } + if (!str_match_no_case( &ctx->cur, "FLT32" ) || is_digit_alpha_underscore( ctx->cur )) { + report_error( ctx, "Expected `FLT32'" ); + return FALSE; + } + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '{') { + report_error( ctx, "Expected `{'" ); + return FALSE; + } + ctx->cur++; + for (i = 0; i < 4; i++) { + eat_opt_white( &ctx->cur ); + if (i > 0) { + if (*ctx->cur != ',') { + report_error( ctx, "Expected `,'" ); + return FALSE; + } + ctx->cur++; + eat_opt_white( &ctx->cur ); + } + if (!parse_float( &ctx->cur, &values[i] )) { + report_error( ctx, "Expected literal floating point" ); + return FALSE; + } + } + eat_opt_white( &ctx->cur ); + if (*ctx->cur != '}') { + report_error( ctx, "Expected `}'" ); + return FALSE; + } + ctx->cur++; + + imm = tgsi_default_full_immediate(); + imm.Immediate.Size += 4; + imm.Immediate.DataType = TGSI_IMM_FLOAT32; + imm.u.Pointer = values; + + advance = tgsi_build_full_immediate( + &imm, + ctx->tokens_cur, + ctx->header, + (uint) (ctx->tokens_end - ctx->tokens_cur) ); + if (advance == 0) + return FALSE; + ctx->tokens_cur += advance; + + return TRUE; +} + +static boolean translate( struct translate_ctx *ctx ) +{ + eat_opt_white( &ctx->cur ); + if (!parse_header( ctx )) + return FALSE; + + while (*ctx->cur != '\0') { + uint label_val = 0; + + if (!eat_white( &ctx->cur )) { + report_error( ctx, "Syntax error" ); + return FALSE; + } + + if (*ctx->cur == '\0') + break; + + if (parse_label( ctx, &label_val )) { + if (!parse_instruction( ctx, TRUE )) + return FALSE; + } + else if (str_match_no_case( &ctx->cur, "DCL" )) { + if (!parse_declaration( ctx )) + return FALSE; + } + else if (str_match_no_case( &ctx->cur, "IMM" )) { + if (!parse_immediate( ctx )) + return FALSE; + } + else if (!parse_instruction( ctx, FALSE )) { + return FALSE; + } + } + + return TRUE; +} + +boolean +tgsi_text_translate( + const char *text, + struct tgsi_token *tokens, + uint num_tokens ) +{ + struct translate_ctx ctx; + + ctx.text = text; + ctx.cur = text; + ctx.tokens = tokens; + ctx.tokens_cur = tokens; + ctx.tokens_end = tokens + num_tokens; + + if (!translate( &ctx )) + return FALSE; + + return tgsi_sanity_check( tokens ); +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.h b/src/gallium/auxiliary/tgsi/tgsi_text.h new file mode 100644 index 0000000000..8eeeeef140 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_text.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_TEXT_H +#define TGSI_TEXT_H + +#include "pipe/p_shader_tokens.h" + +#if defined __cplusplus +extern "C" { +#endif + +boolean +tgsi_text_translate( + const char *text, + struct tgsi_token *tokens, + uint num_tokens ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_TEXT_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_transform.c b/src/gallium/auxiliary/tgsi/tgsi_transform.c new file mode 100644 index 0000000000..357f77b05a --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_transform.c @@ -0,0 +1,199 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * TGSI program transformation utility. + * + * Authors: Brian Paul + */ + + +#include "tgsi_transform.h" + + + +static void +emit_instruction(struct tgsi_transform_context *ctx, + const struct tgsi_full_instruction *inst) +{ + uint ti = ctx->ti; + + ti += tgsi_build_full_instruction(inst, + ctx->tokens_out + ti, + ctx->header, + ctx->max_tokens_out - ti); + ctx->ti = ti; +} + + +static void +emit_declaration(struct tgsi_transform_context *ctx, + const struct tgsi_full_declaration *decl) +{ + uint ti = ctx->ti; + + ti += tgsi_build_full_declaration(decl, + ctx->tokens_out + ti, + ctx->header, + ctx->max_tokens_out - ti); + ctx->ti = ti; +} + + +static void +emit_immediate(struct tgsi_transform_context *ctx, + const struct tgsi_full_immediate *imm) +{ + uint ti = ctx->ti; + + ti += tgsi_build_full_immediate(imm, + ctx->tokens_out + ti, + ctx->header, + ctx->max_tokens_out - ti); + ctx->ti = ti; +} + + + +/** + * Apply user-defined transformations to the input shader to produce + * the output shader. + * For example, a register search-and-replace operation could be applied + * by defining a transform_instruction() callback that examined and changed + * the instruction src/dest regs. + * + * \return number of tokens emitted + */ +int +tgsi_transform_shader(const struct tgsi_token *tokens_in, + struct tgsi_token *tokens_out, + uint max_tokens_out, + struct tgsi_transform_context *ctx) +{ + uint procType; + + /* input shader */ + struct tgsi_parse_context parse; + + /* output shader */ + struct tgsi_processor *processor; + + + /** + ** callback context init + **/ + ctx->emit_instruction = emit_instruction; + ctx->emit_declaration = emit_declaration; + ctx->emit_immediate = emit_immediate; + ctx->tokens_out = tokens_out; + ctx->max_tokens_out = max_tokens_out; + + + /** + ** Setup to begin parsing input shader + **/ + if (tgsi_parse_init( &parse, tokens_in ) != TGSI_PARSE_OK) { + debug_printf("tgsi_parse_init() failed in tgsi_transform_shader()!\n"); + return -1; + } + procType = parse.FullHeader.Processor.Processor; + assert(procType == TGSI_PROCESSOR_FRAGMENT || + procType == TGSI_PROCESSOR_VERTEX || + procType == TGSI_PROCESSOR_GEOMETRY); + + + /** + ** Setup output shader + **/ + *(struct tgsi_version *) &tokens_out[0] = tgsi_build_version(); + + ctx->header = (struct tgsi_header *) (tokens_out + 1); + *ctx->header = tgsi_build_header(); + + processor = (struct tgsi_processor *) (tokens_out + 2); + *processor = tgsi_build_processor( procType, ctx->header ); + + ctx->ti = 3; + + + /** + ** Loop over incoming program tokens/instructions + */ + while( !tgsi_parse_end_of_tokens( &parse ) ) { + + tgsi_parse_token( &parse ); + + switch( parse.FullToken.Token.Type ) { + case TGSI_TOKEN_TYPE_INSTRUCTION: + { + struct tgsi_full_instruction *fullinst + = &parse.FullToken.FullInstruction; + + if (ctx->transform_instruction) + ctx->transform_instruction(ctx, fullinst); + else + ctx->emit_instruction(ctx, fullinst); + } + break; + + case TGSI_TOKEN_TYPE_DECLARATION: + { + struct tgsi_full_declaration *fulldecl + = &parse.FullToken.FullDeclaration; + + if (ctx->transform_declaration) + ctx->transform_declaration(ctx, fulldecl); + else + ctx->emit_declaration(ctx, fulldecl); + } + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + { + struct tgsi_full_immediate *fullimm + = &parse.FullToken.FullImmediate; + + if (ctx->transform_immediate) + ctx->transform_immediate(ctx, fullimm); + else + ctx->emit_immediate(ctx, fullimm); + } + break; + + default: + assert( 0 ); + } + } + + if (ctx->epilog) { + ctx->epilog(ctx); + } + + tgsi_parse_free (&parse); + + return ctx->ti; +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_transform.h b/src/gallium/auxiliary/tgsi/tgsi_transform.h new file mode 100644 index 0000000000..3da0b38271 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_transform.h @@ -0,0 +1,93 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_TRANSFORM_H +#define TGSI_TRANSFORM_H + + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_build.h" + + + +/** + * Subclass this to add caller-specific data + */ +struct tgsi_transform_context +{ +/**** PUBLIC ***/ + + /** + * User-defined callbacks invoked per instruction. + */ + void (*transform_instruction)(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst); + + void (*transform_declaration)(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl); + + void (*transform_immediate)(struct tgsi_transform_context *ctx, + struct tgsi_full_immediate *imm); + + /** + * Called at end of input program to allow caller to append extra + * instructions. Return number of tokens emitted. + */ + void (*epilog)(struct tgsi_transform_context *ctx); + + +/*** PRIVATE ***/ + + /** + * These are setup by tgsi_transform_shader() and cannot be overridden. + * Meant to be called from in the above user callback functions. + */ + void (*emit_instruction)(struct tgsi_transform_context *ctx, + const struct tgsi_full_instruction *inst); + void (*emit_declaration)(struct tgsi_transform_context *ctx, + const struct tgsi_full_declaration *decl); + void (*emit_immediate)(struct tgsi_transform_context *ctx, + const struct tgsi_full_immediate *imm); + + struct tgsi_header *header; + uint max_tokens_out; + struct tgsi_token *tokens_out; + uint ti; +}; + + + +extern int +tgsi_transform_shader(const struct tgsi_token *tokens_in, + struct tgsi_token *tokens_out, + uint max_tokens_out, + struct tgsi_transform_context *ctx); + + +#endif /* TGSI_TRANSFORM_H */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.c b/src/gallium/auxiliary/tgsi/tgsi_util.c new file mode 100644 index 0000000000..09486e649e --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_util.c @@ -0,0 +1,300 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi_parse.h" +#include "tgsi_build.h" +#include "tgsi_util.h" + +union pointer_hack +{ + void *pointer; + uint64_t uint64; +}; + +void * +tgsi_align_128bit( + void *unaligned ) +{ + union pointer_hack ph; + + ph.uint64 = 0; + ph.pointer = unaligned; + ph.uint64 = (ph.uint64 + 15) & ~15; + return ph.pointer; +} + +unsigned +tgsi_util_get_src_register_swizzle( + const struct tgsi_src_register *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->SwizzleX; + case 1: + return reg->SwizzleY; + case 2: + return reg->SwizzleZ; + case 3: + return reg->SwizzleW; + default: + assert( 0 ); + } + return 0; +} + +unsigned +tgsi_util_get_src_register_extswizzle( + const struct tgsi_src_register_ext_swz *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->ExtSwizzleX; + case 1: + return reg->ExtSwizzleY; + case 2: + return reg->ExtSwizzleZ; + case 3: + return reg->ExtSwizzleW; + default: + assert( 0 ); + } + return 0; +} + +unsigned +tgsi_util_get_full_src_register_extswizzle( + const struct tgsi_full_src_register *reg, + unsigned component ) +{ + unsigned swizzle; + + /* + * First, calculate the extended swizzle for a given channel. This will give + * us either a channel index into the simple swizzle or a constant 1 or 0. + */ + swizzle = tgsi_util_get_src_register_extswizzle( + ®->SrcRegisterExtSwz, + component ); + + assert (TGSI_SWIZZLE_X == TGSI_EXTSWIZZLE_X); + assert (TGSI_SWIZZLE_Y == TGSI_EXTSWIZZLE_Y); + assert (TGSI_SWIZZLE_Z == TGSI_EXTSWIZZLE_Z); + assert (TGSI_SWIZZLE_W == TGSI_EXTSWIZZLE_W); + assert (TGSI_EXTSWIZZLE_ZERO > TGSI_SWIZZLE_W); + assert (TGSI_EXTSWIZZLE_ONE > TGSI_SWIZZLE_W); + + /* + * Second, calculate the simple swizzle for the unswizzled channel index. + * Leave the constants intact, they are not affected by the simple swizzle. + */ + if( swizzle <= TGSI_SWIZZLE_W ) { + swizzle = tgsi_util_get_src_register_swizzle( + ®->SrcRegister, + swizzle ); + } + + return swizzle; +} + +void +tgsi_util_set_src_register_swizzle( + struct tgsi_src_register *reg, + unsigned swizzle, + unsigned component ) +{ + switch( component ) { + case 0: + reg->SwizzleX = swizzle; + break; + case 1: + reg->SwizzleY = swizzle; + break; + case 2: + reg->SwizzleZ = swizzle; + break; + case 3: + reg->SwizzleW = swizzle; + break; + default: + assert( 0 ); + } +} + +void +tgsi_util_set_src_register_extswizzle( + struct tgsi_src_register_ext_swz *reg, + unsigned swizzle, + unsigned component ) +{ + switch( component ) { + case 0: + reg->ExtSwizzleX = swizzle; + break; + case 1: + reg->ExtSwizzleY = swizzle; + break; + case 2: + reg->ExtSwizzleZ = swizzle; + break; + case 3: + reg->ExtSwizzleW = swizzle; + break; + default: + assert( 0 ); + } +} + +unsigned +tgsi_util_get_src_register_extnegate( + const struct tgsi_src_register_ext_swz *reg, + unsigned component ) +{ + switch( component ) { + case 0: + return reg->NegateX; + case 1: + return reg->NegateY; + case 2: + return reg->NegateZ; + case 3: + return reg->NegateW; + default: + assert( 0 ); + } + return 0; +} + +void +tgsi_util_set_src_register_extnegate( + struct tgsi_src_register_ext_swz *reg, + unsigned negate, + unsigned component ) +{ + switch( component ) { + case 0: + reg->NegateX = negate; + break; + case 1: + reg->NegateY = negate; + break; + case 2: + reg->NegateZ = negate; + break; + case 3: + reg->NegateW = negate; + break; + default: + assert( 0 ); + } +} + +unsigned +tgsi_util_get_full_src_register_sign_mode( + const struct tgsi_full_src_register *reg, + unsigned component ) +{ + unsigned sign_mode; + + if( reg->SrcRegisterExtMod.Absolute ) { + /* Consider only the post-abs negation. */ + + if( reg->SrcRegisterExtMod.Negate ) { + sign_mode = TGSI_UTIL_SIGN_SET; + } + else { + sign_mode = TGSI_UTIL_SIGN_CLEAR; + } + } + else { + /* Accumulate the three negations. */ + + unsigned negate; + + negate = reg->SrcRegister.Negate; + if( tgsi_util_get_src_register_extnegate( ®->SrcRegisterExtSwz, component ) ) { + negate = !negate; + } + if( reg->SrcRegisterExtMod.Negate ) { + negate = !negate; + } + + if( negate ) { + sign_mode = TGSI_UTIL_SIGN_TOGGLE; + } + else { + sign_mode = TGSI_UTIL_SIGN_KEEP; + } + } + + return sign_mode; +} + +void +tgsi_util_set_full_src_register_sign_mode( + struct tgsi_full_src_register *reg, + unsigned sign_mode ) +{ + reg->SrcRegisterExtSwz.NegateX = 0; + reg->SrcRegisterExtSwz.NegateY = 0; + reg->SrcRegisterExtSwz.NegateZ = 0; + reg->SrcRegisterExtSwz.NegateW = 0; + + switch (sign_mode) + { + case TGSI_UTIL_SIGN_CLEAR: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 1; + reg->SrcRegisterExtMod.Negate = 0; + break; + + case TGSI_UTIL_SIGN_SET: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 1; + reg->SrcRegisterExtMod.Negate = 1; + break; + + case TGSI_UTIL_SIGN_TOGGLE: + reg->SrcRegister.Negate = 1; + reg->SrcRegisterExtMod.Absolute = 0; + reg->SrcRegisterExtMod.Negate = 0; + break; + + case TGSI_UTIL_SIGN_KEEP: + reg->SrcRegister.Negate = 0; + reg->SrcRegisterExtMod.Absolute = 0; + reg->SrcRegisterExtMod.Negate = 0; + break; + + default: + assert( 0 ); + } +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.h b/src/gallium/auxiliary/tgsi/tgsi_util.h new file mode 100644 index 0000000000..7877f34558 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_util.h @@ -0,0 +1,96 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_UTIL_H +#define TGSI_UTIL_H + +#if defined __cplusplus +extern "C" { +#endif + +void * +tgsi_align_128bit( + void *unaligned ); + +unsigned +tgsi_util_get_src_register_swizzle( + const struct tgsi_src_register *reg, + unsigned component ); + +unsigned +tgsi_util_get_src_register_extswizzle( + const struct tgsi_src_register_ext_swz *reg, + unsigned component); + +unsigned +tgsi_util_get_full_src_register_extswizzle( + const struct tgsi_full_src_register *reg, + unsigned component ); + +void +tgsi_util_set_src_register_swizzle( + struct tgsi_src_register *reg, + unsigned swizzle, + unsigned component ); + +void +tgsi_util_set_src_register_extswizzle( + struct tgsi_src_register_ext_swz *reg, + unsigned swizzle, + unsigned component ); + +unsigned +tgsi_util_get_src_register_extnegate( + const struct tgsi_src_register_ext_swz *reg, + unsigned component ); + +void +tgsi_util_set_src_register_extnegate( + struct tgsi_src_register_ext_swz *reg, + unsigned negate, + unsigned component ); + +#define TGSI_UTIL_SIGN_CLEAR 0 /* Force positive */ +#define TGSI_UTIL_SIGN_SET 1 /* Force negative */ +#define TGSI_UTIL_SIGN_TOGGLE 2 /* Negate */ +#define TGSI_UTIL_SIGN_KEEP 3 /* No change */ + +unsigned +tgsi_util_get_full_src_register_sign_mode( + const struct tgsi_full_src_register *reg, + unsigned component ); + +void +tgsi_util_set_full_src_register_sign_mode( + struct tgsi_full_src_register *reg, + unsigned sign_mode ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_UTIL_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.c b/src/gallium/auxiliary/tgsi/util/tgsi_build.c deleted file mode 100644 index 742ef14c35..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.c +++ /dev/null @@ -1,1324 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi_build.h" -#include "tgsi_parse.h" - -/* - * version - */ - -struct tgsi_version -tgsi_build_version( void ) -{ - struct tgsi_version version; - - version.MajorVersion = 1; - version.MinorVersion = 1; - version.Padding = 0; - - return version; -} - -/* - * header - */ - -struct tgsi_header -tgsi_build_header( void ) -{ - struct tgsi_header header; - - header.HeaderSize = 1; - header.BodySize = 0; - - return header; -} - -static void -header_headersize_grow( struct tgsi_header *header ) -{ - assert( header->HeaderSize < 0xFF ); - assert( header->BodySize == 0 ); - - header->HeaderSize++; -} - -static void -header_bodysize_grow( struct tgsi_header *header ) -{ - assert( header->BodySize < 0xFFFFFF ); - - header->BodySize++; -} - -struct tgsi_processor -tgsi_default_processor( void ) -{ - struct tgsi_processor processor; - - processor.Processor = TGSI_PROCESSOR_FRAGMENT; - processor.Padding = 0; - - return processor; -} - -struct tgsi_processor -tgsi_build_processor( - unsigned type, - struct tgsi_header *header ) -{ - struct tgsi_processor processor; - - processor = tgsi_default_processor(); - processor.Processor = type; - - header_headersize_grow( header ); - - return processor; -} - -/* - * declaration - */ - -struct tgsi_declaration -tgsi_default_declaration( void ) -{ - struct tgsi_declaration declaration; - - declaration.Type = TGSI_TOKEN_TYPE_DECLARATION; - declaration.Size = 1; - declaration.File = TGSI_FILE_NULL; - declaration.UsageMask = TGSI_WRITEMASK_XYZW; - declaration.Interpolate = TGSI_INTERPOLATE_CONSTANT; - declaration.Semantic = 0; - declaration.Padding = 0; - declaration.Extended = 0; - - return declaration; -} - -struct tgsi_declaration -tgsi_build_declaration( - unsigned file, - unsigned usage_mask, - unsigned interpolate, - unsigned semantic, - struct tgsi_header *header ) -{ - struct tgsi_declaration declaration; - - assert( file <= TGSI_FILE_IMMEDIATE ); - assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE ); - - declaration = tgsi_default_declaration(); - declaration.File = file; - declaration.UsageMask = usage_mask; - declaration.Interpolate = interpolate; - declaration.Semantic = semantic; - - header_bodysize_grow( header ); - - return declaration; -} - -static void -declaration_grow( - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - assert( declaration->Size < 0xFF ); - - declaration->Size++; - - header_bodysize_grow( header ); -} - -struct tgsi_full_declaration -tgsi_default_full_declaration( void ) -{ - struct tgsi_full_declaration full_declaration; - - full_declaration.Declaration = tgsi_default_declaration(); - full_declaration.DeclarationRange = tgsi_default_declaration_range(); - full_declaration.Semantic = tgsi_default_declaration_semantic(); - - return full_declaration; -} - -unsigned -tgsi_build_full_declaration( - const struct tgsi_full_declaration *full_decl, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ) -{ - unsigned size = 0; - struct tgsi_declaration *declaration; - struct tgsi_declaration_range *dr; - - if( maxsize <= size ) - return 0; - declaration = (struct tgsi_declaration *) &tokens[size]; - size++; - - *declaration = tgsi_build_declaration( - full_decl->Declaration.File, - full_decl->Declaration.UsageMask, - full_decl->Declaration.Interpolate, - full_decl->Declaration.Semantic, - header ); - - if (maxsize <= size) - return 0; - dr = (struct tgsi_declaration_range *) &tokens[size]; - size++; - - *dr = tgsi_build_declaration_range( - full_decl->DeclarationRange.First, - full_decl->DeclarationRange.Last, - declaration, - header ); - - if( full_decl->Declaration.Semantic ) { - struct tgsi_declaration_semantic *ds; - - if( maxsize <= size ) - return 0; - ds = (struct tgsi_declaration_semantic *) &tokens[size]; - size++; - - *ds = tgsi_build_declaration_semantic( - full_decl->Semantic.SemanticName, - full_decl->Semantic.SemanticIndex, - declaration, - header ); - } - - return size; -} - -struct tgsi_declaration_range -tgsi_default_declaration_range( void ) -{ - struct tgsi_declaration_range dr; - - dr.First = 0; - dr.Last = 0; - - return dr; -} - -struct tgsi_declaration_range -tgsi_build_declaration_range( - unsigned first, - unsigned last, - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - struct tgsi_declaration_range declaration_range; - - assert( last >= first ); - assert( last <= 0xFFFF ); - - declaration_range = tgsi_default_declaration_range(); - declaration_range.First = first; - declaration_range.Last = last; - - declaration_grow( declaration, header ); - - return declaration_range; -} - -struct tgsi_declaration_semantic -tgsi_default_declaration_semantic( void ) -{ - struct tgsi_declaration_semantic ds; - - ds.SemanticName = TGSI_SEMANTIC_POSITION; - ds.SemanticIndex = 0; - ds.Padding = 0; - - return ds; -} - -struct tgsi_declaration_semantic -tgsi_build_declaration_semantic( - unsigned semantic_name, - unsigned semantic_index, - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - struct tgsi_declaration_semantic ds; - - assert( semantic_name <= TGSI_SEMANTIC_COUNT ); - assert( semantic_index <= 0xFFFF ); - - ds = tgsi_default_declaration_semantic(); - ds.SemanticName = semantic_name; - ds.SemanticIndex = semantic_index; - - declaration_grow( declaration, header ); - - return ds; -} - -/* - * immediate - */ - -struct tgsi_immediate -tgsi_default_immediate( void ) -{ - struct tgsi_immediate immediate; - - immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE; - immediate.Size = 1; - immediate.DataType = TGSI_IMM_FLOAT32; - immediate.Padding = 0; - immediate.Extended = 0; - - return immediate; -} - -struct tgsi_immediate -tgsi_build_immediate( - struct tgsi_header *header ) -{ - struct tgsi_immediate immediate; - - immediate = tgsi_default_immediate(); - - header_bodysize_grow( header ); - - return immediate; -} - -struct tgsi_full_immediate -tgsi_default_full_immediate( void ) -{ - struct tgsi_full_immediate fullimm; - - fullimm.Immediate = tgsi_default_immediate(); - fullimm.u.Pointer = (void *) 0; - - return fullimm; -} - -static void -immediate_grow( - struct tgsi_immediate *immediate, - struct tgsi_header *header ) -{ - assert( immediate->Size < 0xFF ); - - immediate->Size++; - - header_bodysize_grow( header ); -} - -struct tgsi_immediate_float32 -tgsi_build_immediate_float32( - float value, - struct tgsi_immediate *immediate, - struct tgsi_header *header ) -{ - struct tgsi_immediate_float32 immediate_float32; - - immediate_float32.Float = value; - - immediate_grow( immediate, header ); - - return immediate_float32; -} - -unsigned -tgsi_build_full_immediate( - const struct tgsi_full_immediate *full_imm, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ) -{ - unsigned size = 0, i; - struct tgsi_immediate *immediate; - - if( maxsize <= size ) - return 0; - immediate = (struct tgsi_immediate *) &tokens[size]; - size++; - - *immediate = tgsi_build_immediate( header ); - - for( i = 0; i < full_imm->Immediate.Size - 1; i++ ) { - struct tgsi_immediate_float32 *if32; - - if( maxsize <= size ) - return 0; - if32 = (struct tgsi_immediate_float32 *) &tokens[size]; - size++; - - *if32 = tgsi_build_immediate_float32( - full_imm->u.ImmediateFloat32[i].Float, - immediate, - header ); - } - - return size; -} - -/* - * instruction - */ - -struct tgsi_instruction -tgsi_default_instruction( void ) -{ - struct tgsi_instruction instruction; - - instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; - instruction.Size = 1; - instruction.Opcode = TGSI_OPCODE_MOV; - instruction.Saturate = TGSI_SAT_NONE; - instruction.NumDstRegs = 1; - instruction.NumSrcRegs = 1; - instruction.Padding = 0; - instruction.Extended = 0; - - return instruction; -} - -struct tgsi_instruction -tgsi_build_instruction( - unsigned opcode, - unsigned saturate, - unsigned num_dst_regs, - unsigned num_src_regs, - struct tgsi_header *header ) -{ - struct tgsi_instruction instruction; - - assert (opcode <= TGSI_OPCODE_LAST); - assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE); - assert (num_dst_regs <= 3); - assert (num_src_regs <= 15); - - instruction = tgsi_default_instruction(); - instruction.Opcode = opcode; - instruction.Saturate = saturate; - instruction.NumDstRegs = num_dst_regs; - instruction.NumSrcRegs = num_src_regs; - - header_bodysize_grow( header ); - - return instruction; -} - -static void -instruction_grow( - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - assert (instruction->Size < 0xFF); - - instruction->Size++; - - header_bodysize_grow( header ); -} - -struct tgsi_full_instruction -tgsi_default_full_instruction( void ) -{ - struct tgsi_full_instruction full_instruction; - unsigned i; - - full_instruction.Instruction = tgsi_default_instruction(); - full_instruction.InstructionExtNv = tgsi_default_instruction_ext_nv(); - full_instruction.InstructionExtLabel = tgsi_default_instruction_ext_label(); - full_instruction.InstructionExtTexture = tgsi_default_instruction_ext_texture(); - for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) { - full_instruction.FullDstRegisters[i] = tgsi_default_full_dst_register(); - } - for( i = 0; i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) { - full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register(); - } - - return full_instruction; -} - -unsigned -tgsi_build_full_instruction( - const struct tgsi_full_instruction *full_inst, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ) -{ - unsigned size = 0; - unsigned i; - struct tgsi_instruction *instruction; - struct tgsi_token *prev_token; - - if( maxsize <= size ) - return 0; - instruction = (struct tgsi_instruction *) &tokens[size]; - size++; - - *instruction = tgsi_build_instruction( - full_inst->Instruction.Opcode, - full_inst->Instruction.Saturate, - full_inst->Instruction.NumDstRegs, - full_inst->Instruction.NumSrcRegs, - header ); - prev_token = (struct tgsi_token *) instruction; - - if( tgsi_compare_instruction_ext_nv( - full_inst->InstructionExtNv, - tgsi_default_instruction_ext_nv() ) ) { - struct tgsi_instruction_ext_nv *instruction_ext_nv; - - if( maxsize <= size ) - return 0; - instruction_ext_nv = - (struct tgsi_instruction_ext_nv *) &tokens[size]; - size++; - - *instruction_ext_nv = tgsi_build_instruction_ext_nv( - full_inst->InstructionExtNv.Precision, - full_inst->InstructionExtNv.CondDstIndex, - full_inst->InstructionExtNv.CondFlowIndex, - full_inst->InstructionExtNv.CondMask, - full_inst->InstructionExtNv.CondSwizzleX, - full_inst->InstructionExtNv.CondSwizzleY, - full_inst->InstructionExtNv.CondSwizzleZ, - full_inst->InstructionExtNv.CondSwizzleW, - full_inst->InstructionExtNv.CondDstUpdate, - full_inst->InstructionExtNv.CondFlowEnable, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) instruction_ext_nv; - } - - if( tgsi_compare_instruction_ext_label( - full_inst->InstructionExtLabel, - tgsi_default_instruction_ext_label() ) ) { - struct tgsi_instruction_ext_label *instruction_ext_label; - - if( maxsize <= size ) - return 0; - instruction_ext_label = - (struct tgsi_instruction_ext_label *) &tokens[size]; - size++; - - *instruction_ext_label = tgsi_build_instruction_ext_label( - full_inst->InstructionExtLabel.Label, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) instruction_ext_label; - } - - if( tgsi_compare_instruction_ext_texture( - full_inst->InstructionExtTexture, - tgsi_default_instruction_ext_texture() ) ) { - struct tgsi_instruction_ext_texture *instruction_ext_texture; - - if( maxsize <= size ) - return 0; - instruction_ext_texture = - (struct tgsi_instruction_ext_texture *) &tokens[size]; - size++; - - *instruction_ext_texture = tgsi_build_instruction_ext_texture( - full_inst->InstructionExtTexture.Texture, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) instruction_ext_texture; - } - - for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { - const struct tgsi_full_dst_register *reg = &full_inst->FullDstRegisters[i]; - struct tgsi_dst_register *dst_register; - struct tgsi_token *prev_token; - - if( maxsize <= size ) - return 0; - dst_register = (struct tgsi_dst_register *) &tokens[size]; - size++; - - *dst_register = tgsi_build_dst_register( - reg->DstRegister.File, - reg->DstRegister.WriteMask, - reg->DstRegister.Index, - instruction, - header ); - prev_token = (struct tgsi_token *) dst_register; - - if( tgsi_compare_dst_register_ext_concode( - reg->DstRegisterExtConcode, - tgsi_default_dst_register_ext_concode() ) ) { - struct tgsi_dst_register_ext_concode *dst_register_ext_concode; - - if( maxsize <= size ) - return 0; - dst_register_ext_concode = - (struct tgsi_dst_register_ext_concode *) &tokens[size]; - size++; - - *dst_register_ext_concode = tgsi_build_dst_register_ext_concode( - reg->DstRegisterExtConcode.CondMask, - reg->DstRegisterExtConcode.CondSwizzleX, - reg->DstRegisterExtConcode.CondSwizzleY, - reg->DstRegisterExtConcode.CondSwizzleZ, - reg->DstRegisterExtConcode.CondSwizzleW, - reg->DstRegisterExtConcode.CondSrcIndex, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) dst_register_ext_concode; - } - - if( tgsi_compare_dst_register_ext_modulate( - reg->DstRegisterExtModulate, - tgsi_default_dst_register_ext_modulate() ) ) { - struct tgsi_dst_register_ext_modulate *dst_register_ext_modulate; - - if( maxsize <= size ) - return 0; - dst_register_ext_modulate = - (struct tgsi_dst_register_ext_modulate *) &tokens[size]; - size++; - - *dst_register_ext_modulate = tgsi_build_dst_register_ext_modulate( - reg->DstRegisterExtModulate.Modulate, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) dst_register_ext_modulate; - } - } - - for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { - const struct tgsi_full_src_register *reg = &full_inst->FullSrcRegisters[i]; - struct tgsi_src_register *src_register; - struct tgsi_token *prev_token; - - if( maxsize <= size ) - return 0; - src_register = (struct tgsi_src_register *) &tokens[size]; - size++; - - *src_register = tgsi_build_src_register( - reg->SrcRegister.File, - reg->SrcRegister.SwizzleX, - reg->SrcRegister.SwizzleY, - reg->SrcRegister.SwizzleZ, - reg->SrcRegister.SwizzleW, - reg->SrcRegister.Negate, - reg->SrcRegister.Indirect, - reg->SrcRegister.Dimension, - reg->SrcRegister.Index, - instruction, - header ); - prev_token = (struct tgsi_token *) src_register; - - if( tgsi_compare_src_register_ext_swz( - reg->SrcRegisterExtSwz, - tgsi_default_src_register_ext_swz() ) ) { - struct tgsi_src_register_ext_swz *src_register_ext_swz; - - /* Use of the extended swizzle requires the simple swizzle to be identity. - */ - assert( reg->SrcRegister.SwizzleX == TGSI_SWIZZLE_X ); - assert( reg->SrcRegister.SwizzleY == TGSI_SWIZZLE_Y ); - assert( reg->SrcRegister.SwizzleZ == TGSI_SWIZZLE_Z ); - assert( reg->SrcRegister.SwizzleW == TGSI_SWIZZLE_W ); - assert( reg->SrcRegister.Negate == FALSE ); - - if( maxsize <= size ) - return 0; - src_register_ext_swz = - (struct tgsi_src_register_ext_swz *) &tokens[size]; - size++; - - *src_register_ext_swz = tgsi_build_src_register_ext_swz( - reg->SrcRegisterExtSwz.ExtSwizzleX, - reg->SrcRegisterExtSwz.ExtSwizzleY, - reg->SrcRegisterExtSwz.ExtSwizzleZ, - reg->SrcRegisterExtSwz.ExtSwizzleW, - reg->SrcRegisterExtSwz.NegateX, - reg->SrcRegisterExtSwz.NegateY, - reg->SrcRegisterExtSwz.NegateZ, - reg->SrcRegisterExtSwz.NegateW, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) src_register_ext_swz; - } - - if( tgsi_compare_src_register_ext_mod( - reg->SrcRegisterExtMod, - tgsi_default_src_register_ext_mod() ) ) { - struct tgsi_src_register_ext_mod *src_register_ext_mod; - - if( maxsize <= size ) - return 0; - src_register_ext_mod = - (struct tgsi_src_register_ext_mod *) &tokens[size]; - size++; - - *src_register_ext_mod = tgsi_build_src_register_ext_mod( - reg->SrcRegisterExtMod.Complement, - reg->SrcRegisterExtMod.Bias, - reg->SrcRegisterExtMod.Scale2X, - reg->SrcRegisterExtMod.Absolute, - reg->SrcRegisterExtMod.Negate, - prev_token, - instruction, - header ); - prev_token = (struct tgsi_token *) src_register_ext_mod; - } - - if( reg->SrcRegister.Indirect ) { - struct tgsi_src_register *ind; - - if( maxsize <= size ) - return 0; - ind = (struct tgsi_src_register *) &tokens[size]; - size++; - - *ind = tgsi_build_src_register( - reg->SrcRegisterInd.File, - reg->SrcRegisterInd.SwizzleX, - reg->SrcRegisterInd.SwizzleY, - reg->SrcRegisterInd.SwizzleZ, - reg->SrcRegisterInd.SwizzleW, - reg->SrcRegisterInd.Negate, - reg->SrcRegisterInd.Indirect, - reg->SrcRegisterInd.Dimension, - reg->SrcRegisterInd.Index, - instruction, - header ); - } - - if( reg->SrcRegister.Dimension ) { - struct tgsi_dimension *dim; - - assert( !reg->SrcRegisterDim.Dimension ); - - if( maxsize <= size ) - return 0; - dim = (struct tgsi_dimension *) &tokens[size]; - size++; - - *dim = tgsi_build_dimension( - reg->SrcRegisterDim.Indirect, - reg->SrcRegisterDim.Index, - instruction, - header ); - - if( reg->SrcRegisterDim.Indirect ) { - struct tgsi_src_register *ind; - - if( maxsize <= size ) - return 0; - ind = (struct tgsi_src_register *) &tokens[size]; - size++; - - *ind = tgsi_build_src_register( - reg->SrcRegisterDimInd.File, - reg->SrcRegisterDimInd.SwizzleX, - reg->SrcRegisterDimInd.SwizzleY, - reg->SrcRegisterDimInd.SwizzleZ, - reg->SrcRegisterDimInd.SwizzleW, - reg->SrcRegisterDimInd.Negate, - reg->SrcRegisterDimInd.Indirect, - reg->SrcRegisterDimInd.Dimension, - reg->SrcRegisterDimInd.Index, - instruction, - header ); - } - } - } - - return size; -} - -struct tgsi_instruction_ext_nv -tgsi_default_instruction_ext_nv( void ) -{ - struct tgsi_instruction_ext_nv instruction_ext_nv; - - instruction_ext_nv.Type = TGSI_INSTRUCTION_EXT_TYPE_NV; - instruction_ext_nv.Precision = TGSI_PRECISION_DEFAULT; - instruction_ext_nv.CondDstIndex = 0; - instruction_ext_nv.CondFlowIndex = 0; - instruction_ext_nv.CondMask = TGSI_CC_TR; - instruction_ext_nv.CondSwizzleX = TGSI_SWIZZLE_X; - instruction_ext_nv.CondSwizzleY = TGSI_SWIZZLE_Y; - instruction_ext_nv.CondSwizzleZ = TGSI_SWIZZLE_Z; - instruction_ext_nv.CondSwizzleW = TGSI_SWIZZLE_W; - instruction_ext_nv.CondDstUpdate = 0; - instruction_ext_nv.CondFlowEnable = 0; - instruction_ext_nv.Padding = 0; - instruction_ext_nv.Extended = 0; - - return instruction_ext_nv; -} - -union token_u32 -{ - unsigned u32; -}; - -unsigned -tgsi_compare_instruction_ext_nv( - struct tgsi_instruction_ext_nv a, - struct tgsi_instruction_ext_nv b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_instruction_ext_nv -tgsi_build_instruction_ext_nv( - unsigned precision, - unsigned cond_dst_index, - unsigned cond_flow_index, - unsigned cond_mask, - unsigned cond_swizzle_x, - unsigned cond_swizzle_y, - unsigned cond_swizzle_z, - unsigned cond_swizzle_w, - unsigned cond_dst_update, - unsigned cond_flow_update, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_instruction_ext_nv instruction_ext_nv; - - instruction_ext_nv = tgsi_default_instruction_ext_nv(); - instruction_ext_nv.Precision = precision; - instruction_ext_nv.CondDstIndex = cond_dst_index; - instruction_ext_nv.CondFlowIndex = cond_flow_index; - instruction_ext_nv.CondMask = cond_mask; - instruction_ext_nv.CondSwizzleX = cond_swizzle_x; - instruction_ext_nv.CondSwizzleY = cond_swizzle_y; - instruction_ext_nv.CondSwizzleZ = cond_swizzle_z; - instruction_ext_nv.CondSwizzleW = cond_swizzle_w; - instruction_ext_nv.CondDstUpdate = cond_dst_update; - instruction_ext_nv.CondFlowEnable = cond_flow_update; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return instruction_ext_nv; -} - -struct tgsi_instruction_ext_label -tgsi_default_instruction_ext_label( void ) -{ - struct tgsi_instruction_ext_label instruction_ext_label; - - instruction_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL; - instruction_ext_label.Label = 0; - instruction_ext_label.Padding = 0; - instruction_ext_label.Extended = 0; - - return instruction_ext_label; -} - -unsigned -tgsi_compare_instruction_ext_label( - struct tgsi_instruction_ext_label a, - struct tgsi_instruction_ext_label b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_instruction_ext_label -tgsi_build_instruction_ext_label( - unsigned label, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_instruction_ext_label instruction_ext_label; - - instruction_ext_label = tgsi_default_instruction_ext_label(); - instruction_ext_label.Label = label; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return instruction_ext_label; -} - -struct tgsi_instruction_ext_texture -tgsi_default_instruction_ext_texture( void ) -{ - struct tgsi_instruction_ext_texture instruction_ext_texture; - - instruction_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE; - instruction_ext_texture.Texture = TGSI_TEXTURE_UNKNOWN; - instruction_ext_texture.Padding = 0; - instruction_ext_texture.Extended = 0; - - return instruction_ext_texture; -} - -unsigned -tgsi_compare_instruction_ext_texture( - struct tgsi_instruction_ext_texture a, - struct tgsi_instruction_ext_texture b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_instruction_ext_texture -tgsi_build_instruction_ext_texture( - unsigned texture, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_instruction_ext_texture instruction_ext_texture; - - instruction_ext_texture = tgsi_default_instruction_ext_texture(); - instruction_ext_texture.Texture = texture; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return instruction_ext_texture; -} - -struct tgsi_src_register -tgsi_default_src_register( void ) -{ - struct tgsi_src_register src_register; - - src_register.File = TGSI_FILE_NULL; - src_register.SwizzleX = TGSI_SWIZZLE_X; - src_register.SwizzleY = TGSI_SWIZZLE_Y; - src_register.SwizzleZ = TGSI_SWIZZLE_Z; - src_register.SwizzleW = TGSI_SWIZZLE_W; - src_register.Negate = 0; - src_register.Indirect = 0; - src_register.Dimension = 0; - src_register.Index = 0; - src_register.Extended = 0; - - return src_register; -} - -struct tgsi_src_register -tgsi_build_src_register( - unsigned file, - unsigned swizzle_x, - unsigned swizzle_y, - unsigned swizzle_z, - unsigned swizzle_w, - unsigned negate, - unsigned indirect, - unsigned dimension, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_src_register src_register; - - assert( file <= TGSI_FILE_IMMEDIATE ); - assert( swizzle_x <= TGSI_SWIZZLE_W ); - assert( swizzle_y <= TGSI_SWIZZLE_W ); - assert( swizzle_z <= TGSI_SWIZZLE_W ); - assert( swizzle_w <= TGSI_SWIZZLE_W ); - assert( negate <= 1 ); - assert( index >= -0x8000 && index <= 0x7FFF ); - - src_register = tgsi_default_src_register(); - src_register.File = file; - src_register.SwizzleX = swizzle_x; - src_register.SwizzleY = swizzle_y; - src_register.SwizzleZ = swizzle_z; - src_register.SwizzleW = swizzle_w; - src_register.Negate = negate; - src_register.Indirect = indirect; - src_register.Dimension = dimension; - src_register.Index = index; - - instruction_grow( instruction, header ); - - return src_register; -} - -struct tgsi_full_src_register -tgsi_default_full_src_register( void ) -{ - struct tgsi_full_src_register full_src_register; - - full_src_register.SrcRegister = tgsi_default_src_register(); - full_src_register.SrcRegisterExtSwz = tgsi_default_src_register_ext_swz(); - full_src_register.SrcRegisterExtMod = tgsi_default_src_register_ext_mod(); - full_src_register.SrcRegisterInd = tgsi_default_src_register(); - full_src_register.SrcRegisterDim = tgsi_default_dimension(); - full_src_register.SrcRegisterDimInd = tgsi_default_src_register(); - - return full_src_register; -} - -struct tgsi_src_register_ext_swz -tgsi_default_src_register_ext_swz( void ) -{ - struct tgsi_src_register_ext_swz src_register_ext_swz; - - src_register_ext_swz.Type = TGSI_SRC_REGISTER_EXT_TYPE_SWZ; - src_register_ext_swz.ExtSwizzleX = TGSI_EXTSWIZZLE_X; - src_register_ext_swz.ExtSwizzleY = TGSI_EXTSWIZZLE_Y; - src_register_ext_swz.ExtSwizzleZ = TGSI_EXTSWIZZLE_Z; - src_register_ext_swz.ExtSwizzleW = TGSI_EXTSWIZZLE_W; - src_register_ext_swz.NegateX = 0; - src_register_ext_swz.NegateY = 0; - src_register_ext_swz.NegateZ = 0; - src_register_ext_swz.NegateW = 0; - src_register_ext_swz.Padding = 0; - src_register_ext_swz.Extended = 0; - - return src_register_ext_swz; -} - -unsigned -tgsi_compare_src_register_ext_swz( - struct tgsi_src_register_ext_swz a, - struct tgsi_src_register_ext_swz b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_src_register_ext_swz -tgsi_build_src_register_ext_swz( - unsigned ext_swizzle_x, - unsigned ext_swizzle_y, - unsigned ext_swizzle_z, - unsigned ext_swizzle_w, - unsigned negate_x, - unsigned negate_y, - unsigned negate_z, - unsigned negate_w, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_src_register_ext_swz src_register_ext_swz; - - assert( ext_swizzle_x <= TGSI_EXTSWIZZLE_ONE ); - assert( ext_swizzle_y <= TGSI_EXTSWIZZLE_ONE ); - assert( ext_swizzle_z <= TGSI_EXTSWIZZLE_ONE ); - assert( ext_swizzle_w <= TGSI_EXTSWIZZLE_ONE ); - assert( negate_x <= 1 ); - assert( negate_y <= 1 ); - assert( negate_z <= 1 ); - assert( negate_w <= 1 ); - - src_register_ext_swz = tgsi_default_src_register_ext_swz(); - src_register_ext_swz.ExtSwizzleX = ext_swizzle_x; - src_register_ext_swz.ExtSwizzleY = ext_swizzle_y; - src_register_ext_swz.ExtSwizzleZ = ext_swizzle_z; - src_register_ext_swz.ExtSwizzleW = ext_swizzle_w; - src_register_ext_swz.NegateX = negate_x; - src_register_ext_swz.NegateY = negate_y; - src_register_ext_swz.NegateZ = negate_z; - src_register_ext_swz.NegateW = negate_w; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return src_register_ext_swz; -} - -struct tgsi_src_register_ext_mod -tgsi_default_src_register_ext_mod( void ) -{ - struct tgsi_src_register_ext_mod src_register_ext_mod; - - src_register_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD; - src_register_ext_mod.Complement = 0; - src_register_ext_mod.Bias = 0; - src_register_ext_mod.Scale2X = 0; - src_register_ext_mod.Absolute = 0; - src_register_ext_mod.Negate = 0; - src_register_ext_mod.Padding = 0; - src_register_ext_mod.Extended = 0; - - return src_register_ext_mod; -} - -unsigned -tgsi_compare_src_register_ext_mod( - struct tgsi_src_register_ext_mod a, - struct tgsi_src_register_ext_mod b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_src_register_ext_mod -tgsi_build_src_register_ext_mod( - unsigned complement, - unsigned bias, - unsigned scale_2x, - unsigned absolute, - unsigned negate, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_src_register_ext_mod src_register_ext_mod; - - assert( complement <= 1 ); - assert( bias <= 1 ); - assert( scale_2x <= 1 ); - assert( absolute <= 1 ); - assert( negate <= 1 ); - - src_register_ext_mod = tgsi_default_src_register_ext_mod(); - src_register_ext_mod.Complement = complement; - src_register_ext_mod.Bias = bias; - src_register_ext_mod.Scale2X = scale_2x; - src_register_ext_mod.Absolute = absolute; - src_register_ext_mod.Negate = negate; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return src_register_ext_mod; -} - -struct tgsi_dimension -tgsi_default_dimension( void ) -{ - struct tgsi_dimension dimension; - - dimension.Indirect = 0; - dimension.Dimension = 0; - dimension.Padding = 0; - dimension.Index = 0; - dimension.Extended = 0; - - return dimension; -} - -struct tgsi_dimension -tgsi_build_dimension( - unsigned indirect, - unsigned index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_dimension dimension; - - dimension = tgsi_default_dimension(); - dimension.Indirect = indirect; - dimension.Index = index; - - instruction_grow( instruction, header ); - - return dimension; -} - -struct tgsi_dst_register -tgsi_default_dst_register( void ) -{ - struct tgsi_dst_register dst_register; - - dst_register.File = TGSI_FILE_NULL; - dst_register.WriteMask = TGSI_WRITEMASK_XYZW; - dst_register.Indirect = 0; - dst_register.Dimension = 0; - dst_register.Index = 0; - dst_register.Padding = 0; - dst_register.Extended = 0; - - return dst_register; -} - -struct tgsi_dst_register -tgsi_build_dst_register( - unsigned file, - unsigned mask, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_dst_register dst_register; - - assert( file <= TGSI_FILE_IMMEDIATE ); - assert( mask <= TGSI_WRITEMASK_XYZW ); - assert( index >= -32768 && index <= 32767 ); - - dst_register = tgsi_default_dst_register(); - dst_register.File = file; - dst_register.WriteMask = mask; - dst_register.Index = index; - - instruction_grow( instruction, header ); - - return dst_register; -} - -struct tgsi_full_dst_register -tgsi_default_full_dst_register( void ) -{ - struct tgsi_full_dst_register full_dst_register; - - full_dst_register.DstRegister = tgsi_default_dst_register(); - full_dst_register.DstRegisterExtConcode = - tgsi_default_dst_register_ext_concode(); - full_dst_register.DstRegisterExtModulate = - tgsi_default_dst_register_ext_modulate(); - - return full_dst_register; -} - -struct tgsi_dst_register_ext_concode -tgsi_default_dst_register_ext_concode( void ) -{ - struct tgsi_dst_register_ext_concode dst_register_ext_concode; - - dst_register_ext_concode.Type = TGSI_DST_REGISTER_EXT_TYPE_CONDCODE; - dst_register_ext_concode.CondMask = TGSI_CC_TR; - dst_register_ext_concode.CondSwizzleX = TGSI_SWIZZLE_X; - dst_register_ext_concode.CondSwizzleY = TGSI_SWIZZLE_Y; - dst_register_ext_concode.CondSwizzleZ = TGSI_SWIZZLE_Z; - dst_register_ext_concode.CondSwizzleW = TGSI_SWIZZLE_W; - dst_register_ext_concode.CondSrcIndex = 0; - dst_register_ext_concode.Padding = 0; - dst_register_ext_concode.Extended = 0; - - return dst_register_ext_concode; -} - -unsigned -tgsi_compare_dst_register_ext_concode( - struct tgsi_dst_register_ext_concode a, - struct tgsi_dst_register_ext_concode b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_dst_register_ext_concode -tgsi_build_dst_register_ext_concode( - unsigned cc, - unsigned swizzle_x, - unsigned swizzle_y, - unsigned swizzle_z, - unsigned swizzle_w, - int index, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_dst_register_ext_concode dst_register_ext_concode; - - assert( cc <= TGSI_CC_FL ); - assert( swizzle_x <= TGSI_SWIZZLE_W ); - assert( swizzle_y <= TGSI_SWIZZLE_W ); - assert( swizzle_z <= TGSI_SWIZZLE_W ); - assert( swizzle_w <= TGSI_SWIZZLE_W ); - assert( index >= -32768 && index <= 32767 ); - - dst_register_ext_concode = tgsi_default_dst_register_ext_concode(); - dst_register_ext_concode.CondMask = cc; - dst_register_ext_concode.CondSwizzleX = swizzle_x; - dst_register_ext_concode.CondSwizzleY = swizzle_y; - dst_register_ext_concode.CondSwizzleZ = swizzle_z; - dst_register_ext_concode.CondSwizzleW = swizzle_w; - dst_register_ext_concode.CondSrcIndex = index; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return dst_register_ext_concode; -} - -struct tgsi_dst_register_ext_modulate -tgsi_default_dst_register_ext_modulate( void ) -{ - struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; - - dst_register_ext_modulate.Type = TGSI_DST_REGISTER_EXT_TYPE_MODULATE; - dst_register_ext_modulate.Modulate = TGSI_MODULATE_1X; - dst_register_ext_modulate.Padding = 0; - dst_register_ext_modulate.Extended = 0; - - return dst_register_ext_modulate; -} - -unsigned -tgsi_compare_dst_register_ext_modulate( - struct tgsi_dst_register_ext_modulate a, - struct tgsi_dst_register_ext_modulate b ) -{ - a.Padding = b.Padding = 0; - a.Extended = b.Extended = 0; - return ((union token_u32 *) &a)->u32 != ((union token_u32 *) &b)->u32; -} - -struct tgsi_dst_register_ext_modulate -tgsi_build_dst_register_ext_modulate( - unsigned modulate, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_dst_register_ext_modulate dst_register_ext_modulate; - - assert( modulate <= TGSI_MODULATE_EIGHTH ); - - dst_register_ext_modulate = tgsi_default_dst_register_ext_modulate(); - dst_register_ext_modulate.Modulate = modulate; - - prev_token->Extended = 1; - instruction_grow( instruction, header ); - - return dst_register_ext_modulate; -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.h b/src/gallium/auxiliary/tgsi/util/tgsi_build.h deleted file mode 100644 index ed25830248..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_build.h +++ /dev/null @@ -1,332 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_BUILD_H -#define TGSI_BUILD_H - -#if defined __cplusplus -extern "C" { -#endif - -/* - * version - */ - -struct tgsi_version -tgsi_build_version( void ); - -/* - * header - */ - -struct tgsi_header -tgsi_build_header( void ); - -struct tgsi_processor -tgsi_default_processor( void ); - -struct tgsi_processor -tgsi_build_processor( - unsigned processor, - struct tgsi_header *header ); - -/* - * declaration - */ - -struct tgsi_declaration -tgsi_default_declaration( void ); - -struct tgsi_declaration -tgsi_build_declaration( - unsigned file, - unsigned usage_mask, - unsigned interpolate, - unsigned semantic, - struct tgsi_header *header ); - -struct tgsi_full_declaration -tgsi_default_full_declaration( void ); - -unsigned -tgsi_build_full_declaration( - const struct tgsi_full_declaration *full_decl, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ); - -struct tgsi_declaration_range -tgsi_default_declaration_range( void ); - -struct tgsi_declaration_range -tgsi_build_declaration_range( - unsigned first, - unsigned last, - struct tgsi_declaration *declaration, - struct tgsi_header *header ); - -struct tgsi_declaration_semantic -tgsi_default_declaration_semantic( void ); - -struct tgsi_declaration_semantic -tgsi_build_declaration_semantic( - unsigned semantic_name, - unsigned semantic_index, - struct tgsi_declaration *declaration, - struct tgsi_header *header ); - -/* - * immediate - */ - -struct tgsi_immediate -tgsi_default_immediate( void ); - -struct tgsi_immediate -tgsi_build_immediate( - struct tgsi_header *header ); - -struct tgsi_full_immediate -tgsi_default_full_immediate( void ); - -struct tgsi_immediate_float32 -tgsi_build_immediate_float32( - float value, - struct tgsi_immediate *immediate, - struct tgsi_header *header ); - -unsigned -tgsi_build_full_immediate( - const struct tgsi_full_immediate *full_imm, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ); - -/* - * instruction - */ - -struct tgsi_instruction -tgsi_default_instruction( void ); - -struct tgsi_instruction -tgsi_build_instruction( - unsigned opcode, - unsigned saturate, - unsigned num_dst_regs, - unsigned num_src_regs, - struct tgsi_header *header ); - -struct tgsi_full_instruction -tgsi_default_full_instruction( void ); - -unsigned -tgsi_build_full_instruction( - const struct tgsi_full_instruction *full_inst, - struct tgsi_token *tokens, - struct tgsi_header *header, - unsigned maxsize ); - -struct tgsi_instruction_ext_nv -tgsi_default_instruction_ext_nv( void ); - -unsigned -tgsi_compare_instruction_ext_nv( - struct tgsi_instruction_ext_nv a, - struct tgsi_instruction_ext_nv b ); - -struct tgsi_instruction_ext_nv -tgsi_build_instruction_ext_nv( - unsigned precision, - unsigned cond_dst_index, - unsigned cond_flow_index, - unsigned cond_mask, - unsigned cond_swizzle_x, - unsigned cond_swizzle_y, - unsigned cond_swizzle_z, - unsigned cond_swizzle_w, - unsigned cond_dst_update, - unsigned cond_flow_update, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_instruction_ext_label -tgsi_default_instruction_ext_label( void ); - -unsigned -tgsi_compare_instruction_ext_label( - struct tgsi_instruction_ext_label a, - struct tgsi_instruction_ext_label b ); - -struct tgsi_instruction_ext_label -tgsi_build_instruction_ext_label( - unsigned label, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_instruction_ext_texture -tgsi_default_instruction_ext_texture( void ); - -unsigned -tgsi_compare_instruction_ext_texture( - struct tgsi_instruction_ext_texture a, - struct tgsi_instruction_ext_texture b ); - -struct tgsi_instruction_ext_texture -tgsi_build_instruction_ext_texture( - unsigned texture, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_src_register -tgsi_default_src_register( void ); - -struct tgsi_src_register -tgsi_build_src_register( - unsigned file, - unsigned swizzle_x, - unsigned swizzle_y, - unsigned swizzle_z, - unsigned swizzle_w, - unsigned negate, - unsigned indirect, - unsigned dimension, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_full_src_register -tgsi_default_full_src_register( void ); - -struct tgsi_src_register_ext_swz -tgsi_default_src_register_ext_swz( void ); - -unsigned -tgsi_compare_src_register_ext_swz( - struct tgsi_src_register_ext_swz a, - struct tgsi_src_register_ext_swz b ); - -struct tgsi_src_register_ext_swz -tgsi_build_src_register_ext_swz( - unsigned ext_swizzle_x, - unsigned ext_swizzle_y, - unsigned ext_swizzle_z, - unsigned ext_swizzle_w, - unsigned negate_x, - unsigned negate_y, - unsigned negate_z, - unsigned negate_w, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_src_register_ext_mod -tgsi_default_src_register_ext_mod( void ); - -unsigned -tgsi_compare_src_register_ext_mod( - struct tgsi_src_register_ext_mod a, - struct tgsi_src_register_ext_mod b ); - -struct tgsi_src_register_ext_mod -tgsi_build_src_register_ext_mod( - unsigned complement, - unsigned bias, - unsigned scale_2x, - unsigned absolute, - unsigned negate, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_dimension -tgsi_default_dimension( void ); - -struct tgsi_dimension -tgsi_build_dimension( - unsigned indirect, - unsigned index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_dst_register -tgsi_default_dst_register( void ); - -struct tgsi_dst_register -tgsi_build_dst_register( - unsigned file, - unsigned mask, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_full_dst_register -tgsi_default_full_dst_register( void ); - -struct tgsi_dst_register_ext_concode -tgsi_default_dst_register_ext_concode( void ); - -unsigned -tgsi_compare_dst_register_ext_concode( - struct tgsi_dst_register_ext_concode a, - struct tgsi_dst_register_ext_concode b ); - -struct tgsi_dst_register_ext_concode -tgsi_build_dst_register_ext_concode( - unsigned cc, - unsigned swizzle_x, - unsigned swizzle_y, - unsigned swizzle_z, - unsigned swizzle_w, - int index, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_dst_register_ext_modulate -tgsi_default_dst_register_ext_modulate( void ); - -unsigned -tgsi_compare_dst_register_ext_modulate( - struct tgsi_dst_register_ext_modulate a, - struct tgsi_dst_register_ext_modulate b ); - -struct tgsi_dst_register_ext_modulate -tgsi_build_dst_register_ext_modulate( - unsigned modulate, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -#if defined __cplusplus -} -#endif - -#endif /* TGSI_BUILD_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c deleted file mode 100644 index d2e6375212..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ /dev/null @@ -1,582 +0,0 @@ -/************************************************************************** - * - * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_debug.h" -#include "tgsi_dump.h" -#include "tgsi_iterate.h" - -struct dump_ctx -{ - struct tgsi_iterate_context iter; - - uint instno; -}; - -static void -dump_enum( - uint e, - const char **enums, - uint enum_count ) -{ - if (e >= enum_count) - debug_printf( "%u", e ); - else - debug_printf( "%s", enums[e] ); -} - -#define EOL() debug_printf( "\n" ) -#define TXT(S) debug_printf( "%s", S ) -#define CHR(C) debug_printf( "%c", C ) -#define UIX(I) debug_printf( "0x%x", I ) -#define UID(I) debug_printf( "%u", I ) -#define SID(I) debug_printf( "%d", I ) -#define FLT(F) debug_printf( "%10.4f", F ) -#define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) - -static const char *processor_type_names[] = -{ - "FRAG", - "VERT", - "GEOM" -}; - -static const char *file_names[] = -{ - "NULL", - "CONST", - "IN", - "OUT", - "TEMP", - "SAMP", - "ADDR", - "IMM" -}; - -static const char *interpolate_names[] = -{ - "CONSTANT", - "LINEAR", - "PERSPECTIVE" -}; - -static const char *semantic_names[] = -{ - "POSITION", - "COLOR", - "BCOLOR", - "FOG", - "PSIZE", - "GENERIC", - "NORMAL" -}; - -static const char *immediate_type_names[] = -{ - "FLT32" -}; - -static const char *opcode_names[TGSI_OPCODE_LAST] = -{ - "ARL", - "MOV", - "LIT", - "RCP", - "RSQ", - "EXP", - "LOG", - "MUL", - "ADD", - "DP3", - "DP4", - "DST", - "MIN", - "MAX", - "SLT", - "SGE", - "MAD", - "SUB", - "LERP", - "CND", - "CND0", - "DOT2ADD", - "INDEX", - "NEGATE", - "FRAC", - "CLAMP", - "FLOOR", - "ROUND", - "EXPBASE2", - "LOGBASE2", - "POWER", - "CROSSPRODUCT", - "MULTIPLYMATRIX", - "ABS", - "RCC", - "DPH", - "COS", - "DDX", - "DDY", - "KILP", - "PK2H", - "PK2US", - "PK4B", - "PK4UB", - "RFL", - "SEQ", - "SFL", - "SGT", - "SIN", - "SLE", - "SNE", - "STR", - "TEX", - "TXD", - "TXP", - "UP2H", - "UP2US", - "UP4B", - "UP4UB", - "X2D", - "ARA", - "ARR", - "BRA", - "CAL", - "RET", - "SSG", - "CMP", - "SCS", - "TXB", - "NRM", - "DIV", - "DP2", - "TXL", - "BRK", - "IF", - "LOOP", - "REP", - "ELSE", - "ENDIF", - "ENDLOOP", - "ENDREP", - "PUSHA", - "POPA", - "CEIL", - "I2F", - "NOT", - "TRUNC", - "SHL", - "SHR", - "AND", - "OR", - "MOD", - "XOR", - "SAD", - "TXF", - "TXQ", - "CONT", - "EMIT", - "ENDPRIM", - "BGNLOOP2", - "BGNSUB", - "ENDLOOP2", - "ENDSUB", - "NOISE1", - "NOISE2", - "NOISE3", - "NOISE4", - "NOP", - "M4X3", - "M3X4", - "M3X3", - "M3X2", - "NRM4", - "CALLNZ", - "IFC", - "BREAKC", - "KIL", - "END", - "SWZ" -}; - -static const char *swizzle_names[] = -{ - "x", - "y", - "z", - "w" -}; - -static const char *texture_names[] = -{ - "UNKNOWN", - "1D", - "2D", - "3D", - "CUBE", - "RECT", - "SHADOW1D", - "SHADOW2D", - "SHADOWRECT" -}; - -static const char *extswizzle_names[] = -{ - "x", - "y", - "z", - "w", - "0", - "1" -}; - -static const char *modulate_names[TGSI_MODULATE_COUNT] = -{ - "", - "_2X", - "_4X", - "_8X", - "_D2", - "_D4", - "_D8" -}; - -static void -_dump_register_prefix( - uint file, - uint first, - uint last ) -{ - - -} - -static void -_dump_register( - uint file, - int first, - int last ) -{ - ENM( file, file_names ); - CHR( '[' ); - SID( first ); - if (first != last) { - TXT( ".." ); - SID( last ); - } - CHR( ']' ); -} - -static void -_dump_register_ind( - uint file, - int index, - uint ind_file, - int ind_index ) -{ - ENM( file, file_names ); - CHR( '[' ); - ENM( ind_file, file_names ); - CHR( '[' ); - SID( ind_index ); - CHR( ']' ); - if (index != 0) { - if (index > 0) - CHR( '+' ); - SID( index ); - } - CHR( ']' ); -} - -static void -_dump_writemask( - uint writemask ) -{ - if (writemask != TGSI_WRITEMASK_XYZW) { - CHR( '.' ); - if (writemask & TGSI_WRITEMASK_X) - CHR( 'x' ); - if (writemask & TGSI_WRITEMASK_Y) - CHR( 'y' ); - if (writemask & TGSI_WRITEMASK_Z) - CHR( 'z' ); - if (writemask & TGSI_WRITEMASK_W) - CHR( 'w' ); - } -} - -void -tgsi_dump_declaration( - const struct tgsi_full_declaration *decl ) -{ - TXT( "\nDCL " ); - - _dump_register( - decl->Declaration.File, - decl->DeclarationRange.First, - decl->DeclarationRange.Last ); - _dump_writemask( - decl->Declaration.UsageMask ); - - if (decl->Declaration.Semantic) { - TXT( ", " ); - ENM( decl->Semantic.SemanticName, semantic_names ); - if (decl->Semantic.SemanticIndex != 0 || - decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC) { - CHR( '[' ); - UID( decl->Semantic.SemanticIndex ); - CHR( ']' ); - } - } - - TXT( ", " ); - ENM( decl->Declaration.Interpolate, interpolate_names ); -} - -static boolean -iter_declaration( - struct tgsi_iterate_context *iter, - struct tgsi_full_declaration *decl ) -{ - tgsi_dump_declaration( decl ); - return TRUE; -} - -void -tgsi_dump_immediate( - const struct tgsi_full_immediate *imm ) -{ - uint i; - - TXT( "\nIMM " ); - ENM( imm->Immediate.DataType, immediate_type_names ); - - TXT( " { " ); - for (i = 0; i < imm->Immediate.Size - 1; i++) { - switch (imm->Immediate.DataType) { - case TGSI_IMM_FLOAT32: - FLT( imm->u.ImmediateFloat32[i].Float ); - break; - default: - assert( 0 ); - } - - if (i < imm->Immediate.Size - 2) - TXT( ", " ); - } - TXT( " }" ); -} - -static boolean -iter_immediate( - struct tgsi_iterate_context *iter, - struct tgsi_full_immediate *imm ) -{ - tgsi_dump_immediate( imm ); - return TRUE; -} - -void -tgsi_dump_instruction( - const struct tgsi_full_instruction *inst, - uint instno ) -{ - uint i; - boolean first_reg = TRUE; - - EOL(); - UID( instno ); - CHR( ':' ); - ENM( inst->Instruction.Opcode, opcode_names ); - - switch (inst->Instruction.Saturate) { - case TGSI_SAT_NONE: - break; - case TGSI_SAT_ZERO_ONE: - TXT( "_SAT" ); - break; - case TGSI_SAT_MINUS_PLUS_ONE: - TXT( "_SATNV" ); - break; - default: - assert( 0 ); - } - - for (i = 0; i < inst->Instruction.NumDstRegs; i++) { - const struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - - if (!first_reg) - CHR( ',' ); - CHR( ' ' ); - - _dump_register( - dst->DstRegister.File, - dst->DstRegister.Index, - dst->DstRegister.Index ); - ENM( dst->DstRegisterExtModulate.Modulate, modulate_names ); - _dump_writemask( dst->DstRegister.WriteMask ); - - first_reg = FALSE; - } - - for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { - const struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - - if (!first_reg) - CHR( ',' ); - CHR( ' ' ); - - if (src->SrcRegisterExtMod.Negate) - TXT( "-(" ); - if (src->SrcRegisterExtMod.Absolute) - CHR( '|' ); - if (src->SrcRegisterExtMod.Scale2X) - TXT( "2*(" ); - if (src->SrcRegisterExtMod.Bias) - CHR( '(' ); - if (src->SrcRegisterExtMod.Complement) - TXT( "1-(" ); - if (src->SrcRegister.Negate) - CHR( '-' ); - - if (src->SrcRegister.Indirect) { - _dump_register_ind( - src->SrcRegister.File, - src->SrcRegister.Index, - src->SrcRegisterInd.File, - src->SrcRegisterInd.Index ); - } - else { - _dump_register( - src->SrcRegister.File, - src->SrcRegister.Index, - src->SrcRegister.Index ); - } - - if (src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || - src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || - src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || - src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W) { - CHR( '.' ); - ENM( src->SrcRegister.SwizzleX, swizzle_names ); - ENM( src->SrcRegister.SwizzleY, swizzle_names ); - ENM( src->SrcRegister.SwizzleZ, swizzle_names ); - ENM( src->SrcRegister.SwizzleW, swizzle_names ); - } - if (src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || - src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || - src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || - src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W) { - CHR( '.' ); - if (src->SrcRegisterExtSwz.NegateX) - TXT("-"); - ENM( src->SrcRegisterExtSwz.ExtSwizzleX, extswizzle_names ); - if (src->SrcRegisterExtSwz.NegateY) - TXT("-"); - ENM( src->SrcRegisterExtSwz.ExtSwizzleY, extswizzle_names ); - if (src->SrcRegisterExtSwz.NegateZ) - TXT("-"); - ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, extswizzle_names ); - if (src->SrcRegisterExtSwz.NegateW) - TXT("-"); - ENM( src->SrcRegisterExtSwz.ExtSwizzleW, extswizzle_names ); - } - - if (src->SrcRegisterExtMod.Complement) - CHR( ')' ); - if (src->SrcRegisterExtMod.Bias) - TXT( ")-.5" ); - if (src->SrcRegisterExtMod.Scale2X) - CHR( ')' ); - if (src->SrcRegisterExtMod.Absolute) - CHR( '|' ); - if (src->SrcRegisterExtMod.Negate) - CHR( ')' ); - - first_reg = FALSE; - } - - if (inst->InstructionExtTexture.Texture != TGSI_TEXTURE_UNKNOWN) { - TXT( ", " ); - ENM( inst->InstructionExtTexture.Texture, texture_names ); - } - - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_IF: - case TGSI_OPCODE_ELSE: - case TGSI_OPCODE_BGNLOOP2: - case TGSI_OPCODE_ENDLOOP2: - case TGSI_OPCODE_CAL: - TXT( " :" ); - UID( inst->InstructionExtLabel.Label ); - break; - } -} - -static boolean -iter_instruction( - struct tgsi_iterate_context *iter, - struct tgsi_full_instruction *inst ) -{ - struct dump_ctx *ctx = (struct dump_ctx *) iter; - - tgsi_dump_instruction( inst, ctx->instno++ ); - return TRUE; -} - -static boolean -prolog( - struct tgsi_iterate_context *ctx ) -{ - EOL(); - ENM( ctx->processor.Processor, processor_type_names ); - UID( ctx->version.MajorVersion ); - CHR( '.' ); - UID( ctx->version.MinorVersion ); - return TRUE; -} - -void -tgsi_dump( - const struct tgsi_token *tokens, - uint flags ) -{ - struct dump_ctx ctx; - - /* sanity checks */ - assert( strcmp( opcode_names[TGSI_OPCODE_CONT], "CONT" ) == 0 ); - assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); - - ctx.iter.prolog = prolog; - ctx.iter.iterate_instruction = iter_instruction; - ctx.iter.iterate_declaration = iter_declaration; - ctx.iter.iterate_immediate = iter_immediate; - ctx.iter.epilog = NULL; - - ctx.instno = 0; - - tgsi_iterate_shader( tokens, &ctx.iter ); -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h deleted file mode 100644 index 51c230b5db..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************************************** - * - * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_DUMP_H -#define TGSI_DUMP_H - -#include "pipe/p_shader_tokens.h" - -#if defined __cplusplus -extern "C" { -#endif - -void -tgsi_dump( - const struct tgsi_token *tokens, - uint flags ); - -struct tgsi_full_immediate; -struct tgsi_full_instruction; -struct tgsi_full_declaration; - -void -tgsi_dump_immediate( - const struct tgsi_full_immediate *imm ); - -void -tgsi_dump_instruction( - const struct tgsi_full_instruction *inst, - uint instno ); - -void -tgsi_dump_declaration( - const struct tgsi_full_declaration *decl ); - -#if defined __cplusplus -} -#endif - -#endif /* TGSI_DUMP_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c deleted file mode 100644 index eabd74bd6d..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.c +++ /dev/null @@ -1,845 +0,0 @@ -/************************************************************************** - * - * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" -#include "util/u_string.h" -#include "tgsi_dump_c.h" -#include "tgsi_parse.h" -#include "tgsi_build.h" - -static void -dump_enum( - const unsigned e, - const char **enums, - const unsigned enums_count ) -{ - if (e >= enums_count) { - debug_printf( "%u", e ); - } - else { - debug_printf( "%s", enums[e] ); - } -} - -#define EOL() debug_printf( "\n" ) -#define TXT(S) debug_printf( "%s", S ) -#define CHR(C) debug_printf( "%c", C ) -#define UIX(I) debug_printf( "0x%x", I ) -#define UID(I) debug_printf( "%u", I ) -#define SID(I) debug_printf( "%d", I ) -#define FLT(F) debug_printf( "%10.4f", F ) -#define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) - -static const char *TGSI_PROCESSOR_TYPES[] = -{ - "PROCESSOR_FRAGMENT", - "PROCESSOR_VERTEX", - "PROCESSOR_GEOMETRY" -}; - -static const char *TGSI_TOKEN_TYPES[] = -{ - "TOKEN_TYPE_DECLARATION", - "TOKEN_TYPE_IMMEDIATE", - "TOKEN_TYPE_INSTRUCTION" -}; - -static const char *TGSI_FILES[] = -{ - "FILE_NULL", - "FILE_CONSTANT", - "FILE_INPUT", - "FILE_OUTPUT", - "FILE_TEMPORARY", - "FILE_SAMPLER", - "FILE_ADDRESS", - "FILE_IMMEDIATE" -}; - -static const char *TGSI_INTERPOLATES[] = -{ - "INTERPOLATE_CONSTANT", - "INTERPOLATE_LINEAR", - "INTERPOLATE_PERSPECTIVE" -}; - -static const char *TGSI_SEMANTICS[] = -{ - "SEMANTIC_POSITION", - "SEMANTIC_COLOR", - "SEMANTIC_BCOLOR", - "SEMANTIC_FOG", - "SEMANTIC_PSIZE", - "SEMANTIC_GENERIC", - "SEMANTIC_NORMAL" -}; - -static const char *TGSI_IMMS[] = -{ - "IMM_FLOAT32" -}; - -static const char *TGSI_OPCODES[TGSI_OPCODE_LAST] = -{ - "OPCODE_ARL", - "OPCODE_MOV", - "OPCODE_LIT", - "OPCODE_RCP", - "OPCODE_RSQ", - "OPCODE_EXP", - "OPCODE_LOG", - "OPCODE_MUL", - "OPCODE_ADD", - "OPCODE_DP3", - "OPCODE_DP4", - "OPCODE_DST", - "OPCODE_MIN", - "OPCODE_MAX", - "OPCODE_SLT", - "OPCODE_SGE", - "OPCODE_MAD", - "OPCODE_SUB", - "OPCODE_LERP", - "OPCODE_CND", - "OPCODE_CND0", - "OPCODE_DOT2ADD", - "OPCODE_INDEX", - "OPCODE_NEGATE", - "OPCODE_FRAC", - "OPCODE_CLAMP", - "OPCODE_FLOOR", - "OPCODE_ROUND", - "OPCODE_EXPBASE2", - "OPCODE_LOGBASE2", - "OPCODE_POWER", - "OPCODE_CROSSPRODUCT", - "OPCODE_MULTIPLYMATRIX", - "OPCODE_ABS", - "OPCODE_RCC", - "OPCODE_DPH", - "OPCODE_COS", - "OPCODE_DDX", - "OPCODE_DDY", - "OPCODE_KILP", - "OPCODE_PK2H", - "OPCODE_PK2US", - "OPCODE_PK4B", - "OPCODE_PK4UB", - "OPCODE_RFL", - "OPCODE_SEQ", - "OPCODE_SFL", - "OPCODE_SGT", - "OPCODE_SIN", - "OPCODE_SLE", - "OPCODE_SNE", - "OPCODE_STR", - "OPCODE_TEX", - "OPCODE_TXD", - "OPCODE_TXP", - "OPCODE_UP2H", - "OPCODE_UP2US", - "OPCODE_UP4B", - "OPCODE_UP4UB", - "OPCODE_X2D", - "OPCODE_ARA", - "OPCODE_ARR", - "OPCODE_BRA", - "OPCODE_CAL", - "OPCODE_RET", - "OPCODE_SSG", - "OPCODE_CMP", - "OPCODE_SCS", - "OPCODE_TXB", - "OPCODE_NRM", - "OPCODE_DIV", - "OPCODE_DP2", - "OPCODE_TXL", - "OPCODE_BRK", - "OPCODE_IF", - "OPCODE_LOOP", - "OPCODE_REP", - "OPCODE_ELSE", - "OPCODE_ENDIF", - "OPCODE_ENDLOOP", - "OPCODE_ENDREP", - "OPCODE_PUSHA", - "OPCODE_POPA", - "OPCODE_CEIL", - "OPCODE_I2F", - "OPCODE_NOT", - "OPCODE_TRUNC", - "OPCODE_SHL", - "OPCODE_SHR", - "OPCODE_AND", - "OPCODE_OR", - "OPCODE_MOD", - "OPCODE_XOR", - "OPCODE_SAD", - "OPCODE_TXF", - "OPCODE_TXQ", - "OPCODE_CONT", - "OPCODE_EMIT", - "OPCODE_ENDPRIM", - "OPCODE_BGNLOOP2", - "OPCODE_BGNSUB", - "OPCODE_ENDLOOP2", - "OPCODE_ENDSUB", - "OPCODE_NOISE1", - "OPCODE_NOISE2", - "OPCODE_NOISE3", - "OPCODE_NOISE4", - "OPCODE_NOP", - "OPCODE_M4X3", - "OPCODE_M3X4", - "OPCODE_M3X3", - "OPCODE_M3X2", - "OPCODE_NRM4", - "OPCODE_CALLNZ", - "OPCODE_IFC", - "OPCODE_BREAKC", - "OPCODE_KIL", - "OPCODE_END" -}; - -static const char *TGSI_SATS[] = -{ - "SAT_NONE", - "SAT_ZERO_ONE", - "SAT_MINUS_PLUS_ONE" -}; - -static const char *TGSI_INSTRUCTION_EXTS[] = -{ - "INSTRUCTION_EXT_TYPE_NV", - "INSTRUCTION_EXT_TYPE_LABEL", - "INSTRUCTION_EXT_TYPE_TEXTURE" -}; - -static const char *TGSI_PRECISIONS[] = -{ - "PRECISION_DEFAULT", - "PRECISION_FLOAT32", - "PRECISION_FLOAT16", - "PRECISION_FIXED12" -}; - -static const char *TGSI_CCS[] = -{ - "CC_GT", - "CC_EQ", - "CC_LT", - "CC_UN", - "CC_GE", - "CC_LE", - "CC_NE", - "CC_TR", - "CC_FL" -}; - -static const char *TGSI_SWIZZLES[] = -{ - "SWIZZLE_X", - "SWIZZLE_Y", - "SWIZZLE_Z", - "SWIZZLE_W" -}; - -static const char *TGSI_TEXTURES[] = -{ - "TEXTURE_UNKNOWN", - "TEXTURE_1D", - "TEXTURE_2D", - "TEXTURE_3D", - "TEXTURE_CUBE", - "TEXTURE_RECT", - "TEXTURE_SHADOW1D", - "TEXTURE_SHADOW2D", - "TEXTURE_SHADOWRECT" -}; - -static const char *TGSI_SRC_REGISTER_EXTS[] = -{ - "SRC_REGISTER_EXT_TYPE_SWZ", - "SRC_REGISTER_EXT_TYPE_MOD" -}; - -static const char *TGSI_EXTSWIZZLES[] = -{ - "EXTSWIZZLE_X", - "EXTSWIZZLE_Y", - "EXTSWIZZLE_Z", - "EXTSWIZZLE_W", - "EXTSWIZZLE_ZERO", - "EXTSWIZZLE_ONE" -}; - -static const char *TGSI_WRITEMASKS[] = -{ - "0", - "WRITEMASK_X", - "WRITEMASK_Y", - "WRITEMASK_XY", - "WRITEMASK_Z", - "WRITEMASK_XZ", - "WRITEMASK_YZ", - "WRITEMASK_XYZ", - "WRITEMASK_W", - "WRITEMASK_XW", - "WRITEMASK_YW", - "WRITEMASK_XYW", - "WRITEMASK_ZW", - "WRITEMASK_XZW", - "WRITEMASK_YZW", - "WRITEMASK_XYZW" -}; - -static const char *TGSI_DST_REGISTER_EXTS[] = -{ - "DST_REGISTER_EXT_TYPE_CONDCODE", - "DST_REGISTER_EXT_TYPE_MODULATE" -}; - -static const char *TGSI_MODULATES[] = -{ - "MODULATE_1X", - "MODULATE_2X", - "MODULATE_4X", - "MODULATE_8X", - "MODULATE_HALF", - "MODULATE_QUARTER", - "MODULATE_EIGHTH" -}; - -static void -dump_declaration_verbose( - struct tgsi_full_declaration *decl, - unsigned ignored, - unsigned deflt, - struct tgsi_full_declaration *fd ) -{ - TXT( "\nFile : " ); - ENM( decl->Declaration.File, TGSI_FILES ); - if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) { - TXT( "\nUsageMask : " ); - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { - CHR( 'X' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { - CHR( 'Y' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { - CHR( 'Z' ); - } - if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { - CHR( 'W' ); - } - } - if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) { - TXT( "\nInterpolate: " ); - ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES ); - } - if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) { - TXT( "\nSemantic : " ); - UID( decl->Declaration.Semantic ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( decl->Declaration.Padding ); - } - - EOL(); - TXT( "\nFirst: " ); - UID( decl->DeclarationRange.First ); - TXT( "\nLast : " ); - UID( decl->DeclarationRange.Last ); - - if( decl->Declaration.Semantic ) { - EOL(); - TXT( "\nSemanticName : " ); - ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS ); - TXT( "\nSemanticIndex: " ); - UID( decl->Semantic.SemanticIndex ); - if( ignored ) { - TXT( "\nPadding : " ); - UIX( decl->Semantic.Padding ); - } - } -} - -static void -dump_immediate_verbose( - struct tgsi_full_immediate *imm, - unsigned ignored ) -{ - unsigned i; - - TXT( "\nDataType : " ); - ENM( imm->Immediate.DataType, TGSI_IMMS ); - if( ignored ) { - TXT( "\nPadding : " ); - UIX( imm->Immediate.Padding ); - } - - for( i = 0; i < imm->Immediate.Size - 1; i++ ) { - EOL(); - switch( imm->Immediate.DataType ) { - case TGSI_IMM_FLOAT32: - TXT( "\nFloat: " ); - FLT( imm->u.ImmediateFloat32[i].Float ); - break; - - default: - assert( 0 ); - } - } -} - -static void -dump_instruction_verbose( - struct tgsi_full_instruction *inst, - unsigned ignored, - unsigned deflt, - struct tgsi_full_instruction *fi ) -{ - unsigned i; - - TXT( "\nOpcode : " ); - ENM( inst->Instruction.Opcode, TGSI_OPCODES ); - if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) { - TXT( "\nSaturate : " ); - ENM( inst->Instruction.Saturate, TGSI_SATS ); - } - if( deflt || fi->Instruction.NumDstRegs != inst->Instruction.NumDstRegs ) { - TXT( "\nNumDstRegs : " ); - UID( inst->Instruction.NumDstRegs ); - } - if( deflt || fi->Instruction.NumSrcRegs != inst->Instruction.NumSrcRegs ) { - TXT( "\nNumSrcRegs : " ); - UID( inst->Instruction.NumSrcRegs ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->Instruction.Padding ); - } - - if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi->InstructionExtNv ) ) { - EOL(); - TXT( "\nType : " ); - ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS ); - if( deflt || fi->InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) { - TXT( "\nPrecision : " ); - ENM( inst->InstructionExtNv.Precision, TGSI_PRECISIONS ); - } - if( deflt || fi->InstructionExtNv.CondDstIndex != inst->InstructionExtNv.CondDstIndex ) { - TXT( "\nCondDstIndex : " ); - UID( inst->InstructionExtNv.CondDstIndex ); - } - if( deflt || fi->InstructionExtNv.CondFlowIndex != inst->InstructionExtNv.CondFlowIndex ) { - TXT( "\nCondFlowIndex : " ); - UID( inst->InstructionExtNv.CondFlowIndex ); - } - if( deflt || fi->InstructionExtNv.CondMask != inst->InstructionExtNv.CondMask ) { - TXT( "\nCondMask : " ); - ENM( inst->InstructionExtNv.CondMask, TGSI_CCS ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleX != inst->InstructionExtNv.CondSwizzleX ) { - TXT( "\nCondSwizzleX : " ); - ENM( inst->InstructionExtNv.CondSwizzleX, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleY != inst->InstructionExtNv.CondSwizzleY ) { - TXT( "\nCondSwizzleY : " ); - ENM( inst->InstructionExtNv.CondSwizzleY, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleZ != inst->InstructionExtNv.CondSwizzleZ ) { - TXT( "\nCondSwizzleZ : " ); - ENM( inst->InstructionExtNv.CondSwizzleZ, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondSwizzleW != inst->InstructionExtNv.CondSwizzleW ) { - TXT( "\nCondSwizzleW : " ); - ENM( inst->InstructionExtNv.CondSwizzleW, TGSI_SWIZZLES ); - } - if( deflt || fi->InstructionExtNv.CondDstUpdate != inst->InstructionExtNv.CondDstUpdate ) { - TXT( "\nCondDstUpdate : " ); - UID( inst->InstructionExtNv.CondDstUpdate ); - } - if( deflt || fi->InstructionExtNv.CondFlowEnable != inst->InstructionExtNv.CondFlowEnable ) { - TXT( "\nCondFlowEnable: " ); - UID( inst->InstructionExtNv.CondFlowEnable ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->InstructionExtNv.Padding ); - if( deflt || fi->InstructionExtNv.Extended != inst->InstructionExtNv.Extended ) { - TXT( "\nExtended : " ); - UID( inst->InstructionExtNv.Extended ); - } - } - } - - if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) { - EOL(); - TXT( "\nType : " ); - ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS ); - if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) { - TXT( "\nLabel : " ); - UID( inst->InstructionExtLabel.Label ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->InstructionExtLabel.Padding ); - if( deflt || fi->InstructionExtLabel.Extended != inst->InstructionExtLabel.Extended ) { - TXT( "\nExtended: " ); - UID( inst->InstructionExtLabel.Extended ); - } - } - } - - if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) { - EOL(); - TXT( "\nType : " ); - ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS ); - if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) { - TXT( "\nTexture : " ); - ENM( inst->InstructionExtTexture.Texture, TGSI_TEXTURES ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( inst->InstructionExtTexture.Padding ); - if( deflt || fi->InstructionExtTexture.Extended != inst->InstructionExtTexture.Extended ) { - TXT( "\nExtended: " ); - UID( inst->InstructionExtTexture.Extended ); - } - } - } - - for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i]; - - EOL(); - TXT( "\nFile : " ); - ENM( dst->DstRegister.File, TGSI_FILES ); - if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) { - TXT( "\nWriteMask: " ); - ENM( dst->DstRegister.WriteMask, TGSI_WRITEMASKS ); - } - if( ignored ) { - if( deflt || fd->DstRegister.Indirect != dst->DstRegister.Indirect ) { - TXT( "\nIndirect : " ); - UID( dst->DstRegister.Indirect ); - } - if( deflt || fd->DstRegister.Dimension != dst->DstRegister.Dimension ) { - TXT( "\nDimension: " ); - UID( dst->DstRegister.Dimension ); - } - } - if( deflt || fd->DstRegister.Index != dst->DstRegister.Index ) { - TXT( "\nIndex : " ); - SID( dst->DstRegister.Index ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( dst->DstRegister.Padding ); - if( deflt || fd->DstRegister.Extended != dst->DstRegister.Extended ) { - TXT( "\nExtended : " ); - UID( dst->DstRegister.Extended ); - } - } - - if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) { - EOL(); - TXT( "\nType : " ); - ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS ); - if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) { - TXT( "\nCondMask : " ); - ENM( dst->DstRegisterExtConcode.CondMask, TGSI_CCS ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleX != dst->DstRegisterExtConcode.CondSwizzleX ) { - TXT( "\nCondSwizzleX: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleX, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleY != dst->DstRegisterExtConcode.CondSwizzleY ) { - TXT( "\nCondSwizzleY: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleY, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleZ != dst->DstRegisterExtConcode.CondSwizzleZ ) { - TXT( "\nCondSwizzleZ: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleZ, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSwizzleW != dst->DstRegisterExtConcode.CondSwizzleW ) { - TXT( "\nCondSwizzleW: " ); - ENM( dst->DstRegisterExtConcode.CondSwizzleW, TGSI_SWIZZLES ); - } - if( deflt || fd->DstRegisterExtConcode.CondSrcIndex != dst->DstRegisterExtConcode.CondSrcIndex ) { - TXT( "\nCondSrcIndex: " ); - UID( dst->DstRegisterExtConcode.CondSrcIndex ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( dst->DstRegisterExtConcode.Padding ); - if( deflt || fd->DstRegisterExtConcode.Extended != dst->DstRegisterExtConcode.Extended ) { - TXT( "\nExtended : " ); - UID( dst->DstRegisterExtConcode.Extended ); - } - } - } - - if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) { - EOL(); - TXT( "\nType : " ); - ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS ); - if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) { - TXT( "\nModulate: " ); - ENM( dst->DstRegisterExtModulate.Modulate, TGSI_MODULATES ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( dst->DstRegisterExtModulate.Padding ); - if( deflt || fd->DstRegisterExtModulate.Extended != dst->DstRegisterExtModulate.Extended ) { - TXT( "\nExtended: " ); - UID( dst->DstRegisterExtModulate.Extended ); - } - } - } - } - - for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i]; - - EOL(); - TXT( "\nFile : "); - ENM( src->SrcRegister.File, TGSI_FILES ); - if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) { - TXT( "\nSwizzleX : " ); - ENM( src->SrcRegister.SwizzleX, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.SwizzleY != src->SrcRegister.SwizzleY ) { - TXT( "\nSwizzleY : " ); - ENM( src->SrcRegister.SwizzleY, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.SwizzleZ != src->SrcRegister.SwizzleZ ) { - TXT( "\nSwizzleZ : " ); - ENM( src->SrcRegister.SwizzleZ, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.SwizzleW != src->SrcRegister.SwizzleW ) { - TXT( "\nSwizzleW : " ); - ENM( src->SrcRegister.SwizzleW, TGSI_SWIZZLES ); - } - if( deflt || fs->SrcRegister.Negate != src->SrcRegister.Negate ) { - TXT( "\nNegate : " ); - UID( src->SrcRegister.Negate ); - } - if( ignored ) { - if( deflt || fs->SrcRegister.Indirect != src->SrcRegister.Indirect ) { - TXT( "\nIndirect : " ); - UID( src->SrcRegister.Indirect ); - } - if( deflt || fs->SrcRegister.Dimension != src->SrcRegister.Dimension ) { - TXT( "\nDimension: " ); - UID( src->SrcRegister.Dimension ); - } - } - if( deflt || fs->SrcRegister.Index != src->SrcRegister.Index ) { - TXT( "\nIndex : " ); - SID( src->SrcRegister.Index ); - } - if( ignored ) { - if( deflt || fs->SrcRegister.Extended != src->SrcRegister.Extended ) { - TXT( "\nExtended : " ); - UID( src->SrcRegister.Extended ); - } - } - - if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) { - EOL(); - TXT( "\nType : " ); - ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS ); - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) { - TXT( "\nExtSwizzleX: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleX, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleY != src->SrcRegisterExtSwz.ExtSwizzleY ) { - TXT( "\nExtSwizzleY: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleY, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleZ != src->SrcRegisterExtSwz.ExtSwizzleZ ) { - TXT( "\nExtSwizzleZ: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleZ, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleW != src->SrcRegisterExtSwz.ExtSwizzleW ) { - TXT( "\nExtSwizzleW: " ); - ENM( src->SrcRegisterExtSwz.ExtSwizzleW, TGSI_EXTSWIZZLES ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateX != src->SrcRegisterExtSwz.NegateX ) { - TXT( "\nNegateX : " ); - UID( src->SrcRegisterExtSwz.NegateX ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateY != src->SrcRegisterExtSwz.NegateY ) { - TXT( "\nNegateY : " ); - UID( src->SrcRegisterExtSwz.NegateY ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateZ != src->SrcRegisterExtSwz.NegateZ ) { - TXT( "\nNegateZ : " ); - UID( src->SrcRegisterExtSwz.NegateZ ); - } - if( deflt || fs->SrcRegisterExtSwz.NegateW != src->SrcRegisterExtSwz.NegateW ) { - TXT( "\nNegateW : " ); - UID( src->SrcRegisterExtSwz.NegateW ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( src->SrcRegisterExtSwz.Padding ); - if( deflt || fs->SrcRegisterExtSwz.Extended != src->SrcRegisterExtSwz.Extended ) { - TXT( "\nExtended : " ); - UID( src->SrcRegisterExtSwz.Extended ); - } - } - } - - if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) { - EOL(); - TXT( "\nType : " ); - ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS ); - if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) { - TXT( "\nComplement: " ); - UID( src->SrcRegisterExtMod.Complement ); - } - if( deflt || fs->SrcRegisterExtMod.Bias != src->SrcRegisterExtMod.Bias ) { - TXT( "\nBias : " ); - UID( src->SrcRegisterExtMod.Bias ); - } - if( deflt || fs->SrcRegisterExtMod.Scale2X != src->SrcRegisterExtMod.Scale2X ) { - TXT( "\nScale2X : " ); - UID( src->SrcRegisterExtMod.Scale2X ); - } - if( deflt || fs->SrcRegisterExtMod.Absolute != src->SrcRegisterExtMod.Absolute ) { - TXT( "\nAbsolute : " ); - UID( src->SrcRegisterExtMod.Absolute ); - } - if( deflt || fs->SrcRegisterExtMod.Negate != src->SrcRegisterExtMod.Negate ) { - TXT( "\nNegate : " ); - UID( src->SrcRegisterExtMod.Negate ); - } - if( ignored ) { - TXT( "\nPadding : " ); - UIX( src->SrcRegisterExtMod.Padding ); - if( deflt || fs->SrcRegisterExtMod.Extended != src->SrcRegisterExtMod.Extended ) { - TXT( "\nExtended : " ); - UID( src->SrcRegisterExtMod.Extended ); - } - } - } - } -} - -void -tgsi_dump_c( - const struct tgsi_token *tokens, - uint flags ) -{ - struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - uint ignored = flags & TGSI_DUMP_C_IGNORED; - uint deflt = flags & TGSI_DUMP_C_DEFAULT; - uint instno = 0; - - /* sanity checks */ - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); - - tgsi_parse_init( &parse, tokens ); - - TXT( "tgsi-dump begin -----------------" ); - - TXT( "\nMajorVersion: " ); - UID( parse.FullVersion.Version.MajorVersion ); - TXT( "\nMinorVersion: " ); - UID( parse.FullVersion.Version.MinorVersion ); - EOL(); - - TXT( "\nHeaderSize: " ); - UID( parse.FullHeader.Header.HeaderSize ); - TXT( "\nBodySize : " ); - UID( parse.FullHeader.Header.BodySize ); - TXT( "\nProcessor : " ); - ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); - EOL(); - - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - - while( !tgsi_parse_end_of_tokens( &parse ) ) { - tgsi_parse_token( &parse ); - - TXT( "\nType : " ); - ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES ); - if( ignored ) { - TXT( "\nSize : " ); - UID( parse.FullToken.Token.Size ); - if( deflt || parse.FullToken.Token.Extended ) { - TXT( "\nExtended : " ); - UID( parse.FullToken.Token.Extended ); - } - } - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - dump_declaration_verbose( - &parse.FullToken.FullDeclaration, - ignored, - deflt, - &fd ); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - dump_immediate_verbose( - &parse.FullToken.FullImmediate, - ignored ); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - dump_instruction_verbose( - &parse.FullToken.FullInstruction, - ignored, - deflt, - &fi ); - break; - - default: - assert( 0 ); - } - - EOL(); - } - - TXT( "\ntgsi-dump end -------------------\n" ); - - tgsi_parse_free( &parse ); -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h deleted file mode 100644 index d91cd35b3b..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump_c.h +++ /dev/null @@ -1,49 +0,0 @@ -/************************************************************************** - * - * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_DUMP_C_H -#define TGSI_DUMP_C_H - -#include "pipe/p_shader_tokens.h" - -#if defined __cplusplus -extern "C" { -#endif - -#define TGSI_DUMP_C_IGNORED 1 -#define TGSI_DUMP_C_DEFAULT 2 - -void -tgsi_dump_c( - const struct tgsi_token *tokens, - uint flags ); - -#if defined __cplusplus -} -#endif - -#endif /* TGSI_DUMP_C_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c deleted file mode 100644 index 5371a88b96..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.c +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_debug.h" -#include "tgsi_iterate.h" - -boolean -tgsi_iterate_shader( - const struct tgsi_token *tokens, - struct tgsi_iterate_context *ctx ) -{ - struct tgsi_parse_context parse; - - if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) - return FALSE; - - ctx->processor = parse.FullHeader.Processor; - ctx->version = parse.FullVersion.Version; - - if (ctx->prolog) - if (!ctx->prolog( ctx )) - goto fail; - - while (!tgsi_parse_end_of_tokens( &parse )) { - tgsi_parse_token( &parse ); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_INSTRUCTION: - if (ctx->iterate_instruction) - if (!ctx->iterate_instruction( ctx, &parse.FullToken.FullInstruction )) - goto fail; - break; - - case TGSI_TOKEN_TYPE_DECLARATION: - if (ctx->iterate_declaration) - if (!ctx->iterate_declaration( ctx, &parse.FullToken.FullDeclaration )) - goto fail; - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - if (ctx->iterate_immediate) - if (!ctx->iterate_immediate( ctx, &parse.FullToken.FullImmediate )) - goto fail; - break; - - default: - assert( 0 ); - } - } - - if (ctx->epilog) - if (!ctx->epilog( ctx )) - goto fail; - - tgsi_parse_free( &parse ); - return TRUE; - -fail: - tgsi_parse_free( &parse ); - return FALSE; -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h b/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h deleted file mode 100644 index f5bebf89b8..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_iterate.h +++ /dev/null @@ -1,76 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_ITERATE_H -#define TGSI_ITERATE_H - -#include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" - -#if defined __cplusplus -extern "C" { -#endif - -struct tgsi_iterate_context -{ - boolean - (* prolog)( - struct tgsi_iterate_context *ctx ); - - boolean - (* iterate_instruction)( - struct tgsi_iterate_context *ctx, - struct tgsi_full_instruction *inst ); - - boolean - (* iterate_declaration)( - struct tgsi_iterate_context *ctx, - struct tgsi_full_declaration *decl ); - - boolean - (* iterate_immediate)( - struct tgsi_iterate_context *ctx, - struct tgsi_full_immediate *imm ); - - boolean - (* epilog)( - struct tgsi_iterate_context *ctx ); - - struct tgsi_processor processor; - struct tgsi_version version; -}; - -boolean -tgsi_iterate_shader( - const struct tgsi_token *tokens, - struct tgsi_iterate_context *ctx ); - -#if defined __cplusplus -} -#endif - -#endif /* TGSI_ITERATE_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c deleted file mode 100644 index d16f0cdcad..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c +++ /dev/null @@ -1,332 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi_parse.h" -#include "tgsi_build.h" - -void -tgsi_full_token_init( - union tgsi_full_token *full_token ) -{ - full_token->Token.Type = TGSI_TOKEN_TYPE_DECLARATION; -} - -void -tgsi_full_token_free( - union tgsi_full_token *full_token ) -{ - if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE ) { - FREE( (void *) full_token->FullImmediate.u.Pointer ); - } -} - -unsigned -tgsi_parse_init( - struct tgsi_parse_context *ctx, - const struct tgsi_token *tokens ) -{ - ctx->FullVersion.Version = *(struct tgsi_version *) &tokens[0]; - if( ctx->FullVersion.Version.MajorVersion > 1 ) { - return TGSI_PARSE_ERROR; - } - - ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[1]; - if( ctx->FullHeader.Header.HeaderSize >= 2 ) { - ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[2]; - } - else { - ctx->FullHeader.Processor = tgsi_default_processor(); - } - - ctx->Tokens = tokens; - ctx->Position = 1 + ctx->FullHeader.Header.HeaderSize; - - tgsi_full_token_init( &ctx->FullToken ); - - return TGSI_PARSE_OK; -} - -void -tgsi_parse_free( - struct tgsi_parse_context *ctx ) -{ - tgsi_full_token_free( &ctx->FullToken ); -} - -boolean -tgsi_parse_end_of_tokens( - struct tgsi_parse_context *ctx ) -{ - return ctx->Position >= - 1 + ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize; -} - -static void -next_token( - struct tgsi_parse_context *ctx, - void *token ) -{ - assert( !tgsi_parse_end_of_tokens( ctx ) ); - - *(struct tgsi_token *) token = ctx->Tokens[ctx->Position++]; -} - -void -tgsi_parse_token( - struct tgsi_parse_context *ctx ) -{ - struct tgsi_token token; - unsigned i; - - tgsi_full_token_free( &ctx->FullToken ); - tgsi_full_token_init( &ctx->FullToken ); - - next_token( ctx, &token ); - - switch( token.Type ) { - case TGSI_TOKEN_TYPE_DECLARATION: - { - struct tgsi_full_declaration *decl = &ctx->FullToken.FullDeclaration; - - *decl = tgsi_default_full_declaration(); - decl->Declaration = *(struct tgsi_declaration *) &token; - - next_token( ctx, &decl->DeclarationRange ); - - if( decl->Declaration.Semantic ) { - next_token( ctx, &decl->Semantic ); - } - - break; - } - - case TGSI_TOKEN_TYPE_IMMEDIATE: - { - struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate; - - *imm = tgsi_default_full_immediate(); - imm->Immediate = *(struct tgsi_immediate *) &token; - - assert( !imm->Immediate.Extended ); - - switch (imm->Immediate.DataType) { - case TGSI_IMM_FLOAT32: - imm->u.Pointer = MALLOC( - sizeof( struct tgsi_immediate_float32 ) * (imm->Immediate.Size - 1) ); - for( i = 0; i < imm->Immediate.Size - 1; i++ ) { - next_token( ctx, (struct tgsi_immediate_float32 *) &imm->u.ImmediateFloat32[i] ); - } - break; - - default: - assert( 0 ); - } - - break; - } - - case TGSI_TOKEN_TYPE_INSTRUCTION: - { - struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction; - unsigned extended; - - *inst = tgsi_default_full_instruction(); - inst->Instruction = *(struct tgsi_instruction *) &token; - - extended = inst->Instruction.Extended; - - while( extended ) { - struct tgsi_src_register_ext token; - - next_token( ctx, &token ); - - switch( token.Type ) { - case TGSI_INSTRUCTION_EXT_TYPE_NV: - inst->InstructionExtNv = - *(struct tgsi_instruction_ext_nv *) &token; - break; - - case TGSI_INSTRUCTION_EXT_TYPE_LABEL: - inst->InstructionExtLabel = - *(struct tgsi_instruction_ext_label *) &token; - break; - - case TGSI_INSTRUCTION_EXT_TYPE_TEXTURE: - inst->InstructionExtTexture = - *(struct tgsi_instruction_ext_texture *) &token; - break; - - default: - assert( 0 ); - } - - extended = token.Extended; - } - - assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS ); - - for( i = 0; i < inst->Instruction.NumDstRegs; i++ ) { - unsigned extended; - - next_token( ctx, &inst->FullDstRegisters[i].DstRegister ); - - /* - * No support for indirect or multi-dimensional addressing. - */ - assert( !inst->FullDstRegisters[i].DstRegister.Indirect ); - assert( !inst->FullDstRegisters[i].DstRegister.Dimension ); - - extended = inst->FullDstRegisters[i].DstRegister.Extended; - - while( extended ) { - struct tgsi_src_register_ext token; - - next_token( ctx, &token ); - - switch( token.Type ) { - case TGSI_DST_REGISTER_EXT_TYPE_CONDCODE: - inst->FullDstRegisters[i].DstRegisterExtConcode = - *(struct tgsi_dst_register_ext_concode *) &token; - break; - - case TGSI_DST_REGISTER_EXT_TYPE_MODULATE: - inst->FullDstRegisters[i].DstRegisterExtModulate = - *(struct tgsi_dst_register_ext_modulate *) &token; - break; - - default: - assert( 0 ); - } - - extended = token.Extended; - } - } - - assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS ); - - for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) { - unsigned extended; - - next_token( ctx, &inst->FullSrcRegisters[i].SrcRegister ); - - extended = inst->FullSrcRegisters[i].SrcRegister.Extended; - - while( extended ) { - struct tgsi_src_register_ext token; - - next_token( ctx, &token ); - - switch( token.Type ) { - case TGSI_SRC_REGISTER_EXT_TYPE_SWZ: - inst->FullSrcRegisters[i].SrcRegisterExtSwz = - *(struct tgsi_src_register_ext_swz *) &token; - break; - - case TGSI_SRC_REGISTER_EXT_TYPE_MOD: - inst->FullSrcRegisters[i].SrcRegisterExtMod = - *(struct tgsi_src_register_ext_mod *) &token; - break; - - default: - assert( 0 ); - } - - extended = token.Extended; - } - - if( inst->FullSrcRegisters[i].SrcRegister.Indirect ) { - next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterInd ); - - /* - * No support for indirect or multi-dimensional addressing. - */ - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); - } - - if( inst->FullSrcRegisters[i].SrcRegister.Dimension ) { - next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDim ); - - /* - * No support for multi-dimensional addressing. - */ - assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Dimension ); - assert( !inst->FullSrcRegisters[i].SrcRegisterDim.Extended ); - - if( inst->FullSrcRegisters[i].SrcRegisterDim.Indirect ) { - next_token( ctx, &inst->FullSrcRegisters[i].SrcRegisterDimInd ); - - /* - * No support for indirect or multi-dimensional addressing. - */ - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Indirect ); - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Dimension ); - assert( !inst->FullSrcRegisters[i].SrcRegisterInd.Extended ); - } - } - } - - break; - } - - default: - assert( 0 ); - } -} - - -unsigned -tgsi_num_tokens(const struct tgsi_token *tokens) -{ - struct tgsi_parse_context ctx; - if (tgsi_parse_init(&ctx, tokens) == TGSI_PARSE_OK) { - unsigned len = (ctx.FullHeader.Header.HeaderSize + - ctx.FullHeader.Header.BodySize + - 1); - return len; - } - return 0; -} - - -/** - * Make a new copy of a token array. - */ -struct tgsi_token * -tgsi_dup_tokens(const struct tgsi_token *tokens) -{ - unsigned n = tgsi_num_tokens(tokens); - unsigned bytes = n * sizeof(struct tgsi_token); - struct tgsi_token *new_tokens = (struct tgsi_token *) MALLOC(bytes); - if (new_tokens) - memcpy(new_tokens, tokens, bytes); - return new_tokens; -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h deleted file mode 100644 index 054350712d..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h +++ /dev/null @@ -1,151 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_PARSE_H -#define TGSI_PARSE_H - -#include "pipe/p_shader_tokens.h" - -#if defined __cplusplus -extern "C" { -#endif - -struct tgsi_full_version -{ - struct tgsi_version Version; -}; - -struct tgsi_full_header -{ - struct tgsi_header Header; - struct tgsi_processor Processor; -}; - -struct tgsi_full_dst_register -{ - struct tgsi_dst_register DstRegister; - struct tgsi_dst_register_ext_concode DstRegisterExtConcode; - struct tgsi_dst_register_ext_modulate DstRegisterExtModulate; -}; - -struct tgsi_full_src_register -{ - struct tgsi_src_register SrcRegister; - struct tgsi_src_register_ext_swz SrcRegisterExtSwz; - struct tgsi_src_register_ext_mod SrcRegisterExtMod; - struct tgsi_src_register SrcRegisterInd; - struct tgsi_dimension SrcRegisterDim; - struct tgsi_src_register SrcRegisterDimInd; -}; - -struct tgsi_full_declaration -{ - struct tgsi_declaration Declaration; - struct tgsi_declaration_range DeclarationRange; - struct tgsi_declaration_semantic Semantic; -}; - -struct tgsi_full_immediate -{ - struct tgsi_immediate Immediate; - union - { - const void *Pointer; - const struct tgsi_immediate_float32 *ImmediateFloat32; - } u; -}; - -#define TGSI_FULL_MAX_DST_REGISTERS 2 -#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */ - -struct tgsi_full_instruction -{ - struct tgsi_instruction Instruction; - struct tgsi_instruction_ext_nv InstructionExtNv; - struct tgsi_instruction_ext_label InstructionExtLabel; - struct tgsi_instruction_ext_texture InstructionExtTexture; - struct tgsi_full_dst_register FullDstRegisters[TGSI_FULL_MAX_DST_REGISTERS]; - struct tgsi_full_src_register FullSrcRegisters[TGSI_FULL_MAX_SRC_REGISTERS]; -}; - -union tgsi_full_token -{ - struct tgsi_token Token; - struct tgsi_full_declaration FullDeclaration; - struct tgsi_full_immediate FullImmediate; - struct tgsi_full_instruction FullInstruction; -}; - -void -tgsi_full_token_init( - union tgsi_full_token *full_token ); - -void -tgsi_full_token_free( - union tgsi_full_token *full_token ); - -struct tgsi_parse_context -{ - const struct tgsi_token *Tokens; - unsigned Position; - struct tgsi_full_version FullVersion; - struct tgsi_full_header FullHeader; - union tgsi_full_token FullToken; -}; - -#define TGSI_PARSE_OK 0 -#define TGSI_PARSE_ERROR 1 - -unsigned -tgsi_parse_init( - struct tgsi_parse_context *ctx, - const struct tgsi_token *tokens ); - -void -tgsi_parse_free( - struct tgsi_parse_context *ctx ); - -boolean -tgsi_parse_end_of_tokens( - struct tgsi_parse_context *ctx ); - -void -tgsi_parse_token( - struct tgsi_parse_context *ctx ); - -unsigned -tgsi_num_tokens(const struct tgsi_token *tokens); - -struct tgsi_token * -tgsi_dup_tokens(const struct tgsi_token *tokens); - -#if defined __cplusplus -} -#endif - -#endif /* TGSI_PARSE_H */ - diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c deleted file mode 100644 index 2e3ec96b5b..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.c +++ /dev/null @@ -1,341 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_debug.h" -#include "tgsi_sanity.h" -#include "tgsi_iterate.h" - -#define MAX_REGISTERS 256 - -typedef uint reg_flag; - -#define BITS_IN_REG_FLAG (sizeof( reg_flag ) * 8) - -struct sanity_check_ctx -{ - struct tgsi_iterate_context iter; - - reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REGISTERS / BITS_IN_REG_FLAG]; - reg_flag regs_used[TGSI_FILE_COUNT][MAX_REGISTERS / BITS_IN_REG_FLAG]; - boolean regs_ind_used[TGSI_FILE_COUNT]; - uint num_imms; - uint num_instructions; - uint index_of_END; - - uint errors; - uint warnings; -}; - -static void -report_error( - struct sanity_check_ctx *ctx, - const char *format, - ... ) -{ - va_list args; - - debug_printf( "Error : " ); - va_start( args, format ); - _debug_vprintf( format, args ); - va_end( args ); - debug_printf( "\n" ); - ctx->errors++; -} - -static void -report_warning( - struct sanity_check_ctx *ctx, - const char *format, - ... ) -{ - va_list args; - - debug_printf( "Warning: " ); - va_start( args, format ); - _debug_vprintf( format, args ); - va_end( args ); - debug_printf( "\n" ); - ctx->warnings++; -} - -static boolean -check_file_name( - struct sanity_check_ctx *ctx, - uint file ) -{ - if (file <= TGSI_FILE_NULL || file >= TGSI_FILE_COUNT) { - report_error( ctx, "Invalid register file name" ); - return FALSE; - } - return TRUE; -} - -static boolean -is_register_declared( - struct sanity_check_ctx *ctx, - uint file, - int index ) -{ - assert( index >= 0 && index < MAX_REGISTERS ); - - return (ctx->regs_decl[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; -} - -static boolean -is_any_register_declared( - struct sanity_check_ctx *ctx, - uint file ) -{ - uint i; - - for (i = 0; i < MAX_REGISTERS / BITS_IN_REG_FLAG; i++) - if (ctx->regs_decl[file][i]) - return TRUE; - return FALSE; -} - -static boolean -is_register_used( - struct sanity_check_ctx *ctx, - uint file, - int index ) -{ - assert( index < MAX_REGISTERS ); - - return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE; -} - -static const char *file_names[] = -{ - "NULL", - "CONST", - "IN", - "OUT", - "TEMP", - "SAMP", - "ADDR", - "IMM" -}; - -static boolean -check_register_usage( - struct sanity_check_ctx *ctx, - uint file, - int index, - const char *name, - boolean indirect_access ) -{ - if (!check_file_name( ctx, file )) - return FALSE; - if (indirect_access) { - if (!is_any_register_declared( ctx, file )) - report_error( ctx, "%s: Undeclared %s register", file_names[file], name ); - ctx->regs_ind_used[file] = TRUE; - } - else { - if (!is_register_declared( ctx, file, index )) - report_error( ctx, "%s[%d]: Undeclared %s register", file_names[file], index, name ); - ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG)); - } - return TRUE; -} - -static boolean -iter_instruction( - struct tgsi_iterate_context *iter, - struct tgsi_full_instruction *inst ) -{ - struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; - uint i; - - /* There must be no other instructions after END. - */ - if (ctx->index_of_END != ~0) { - report_error( ctx, "Unexpected instruction after END" ); - } - else if (inst->Instruction.Opcode == TGSI_OPCODE_END) { - ctx->index_of_END = ctx->num_instructions; - } - - /* Check destination and source registers' validity. - * Mark the registers as used. - */ - for (i = 0; i < inst->Instruction.NumDstRegs; i++) { - check_register_usage( - ctx, - inst->FullDstRegisters[i].DstRegister.File, - inst->FullDstRegisters[i].DstRegister.Index, - "destination", - FALSE ); - } - for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { - check_register_usage( - ctx, - inst->FullSrcRegisters[i].SrcRegister.File, - inst->FullSrcRegisters[i].SrcRegister.Index, - "source", - (boolean)inst->FullSrcRegisters[i].SrcRegister.Indirect ); - if (inst->FullSrcRegisters[i].SrcRegister.Indirect) { - uint file; - int index; - - file = inst->FullSrcRegisters[i].SrcRegisterInd.File; - index = inst->FullSrcRegisters[i].SrcRegisterInd.Index; - check_register_usage( - ctx, - file, - index, - "indirect", - FALSE ); - if (file != TGSI_FILE_ADDRESS || index != 0) - report_warning( ctx, "Indirect register not ADDR[0]" ); - } - } - - ctx->num_instructions++; - - return TRUE; -} - -static boolean -iter_declaration( - struct tgsi_iterate_context *iter, - struct tgsi_full_declaration *decl ) -{ - struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; - uint file; - uint i; - - /* No declarations allowed after the first instruction. - */ - if (ctx->num_instructions > 0) - report_error( ctx, "Instruction expected but declaration found" ); - - /* Check registers' validity. - * Mark the registers as declared. - */ - file = decl->Declaration.File; - if (!check_file_name( ctx, file )) - return TRUE; - for (i = decl->DeclarationRange.First; i <= decl->DeclarationRange.Last; i++) { - if (is_register_declared( ctx, file, i )) - report_error( ctx, "The same register declared twice" ); - ctx->regs_decl[file][i / BITS_IN_REG_FLAG] |= (1 << (i % BITS_IN_REG_FLAG)); - } - - return TRUE; -} - -static boolean -iter_immediate( - struct tgsi_iterate_context *iter, - struct tgsi_full_immediate *imm ) -{ - struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; - - assert( ctx->num_imms < MAX_REGISTERS ); - - /* No immediates allowed after the first instruction. - */ - if (ctx->num_instructions > 0) - report_error( ctx, "Instruction expected but immediate found" ); - - /* Mark the register as declared. - */ - ctx->regs_decl[TGSI_FILE_IMMEDIATE][ctx->num_imms / BITS_IN_REG_FLAG] |= (1 << (ctx->num_imms % BITS_IN_REG_FLAG)); - ctx->num_imms++; - - /* Check data type validity. - */ - if (imm->Immediate.DataType != TGSI_IMM_FLOAT32) { - report_error( ctx, "Invalid immediate data type" ); - return TRUE; - } - - return TRUE; -} - -static boolean -epilog( - struct tgsi_iterate_context *iter ) -{ - struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; - uint file; - - /* There must be an END instruction at the end. - */ - if (ctx->index_of_END == ~0 || ctx->index_of_END != ctx->num_instructions - 1) { - report_error( ctx, "Expected END at end of instruction sequence" ); - } - - /* Check if all declared registers were used. - */ - for (file = TGSI_FILE_NULL; file < TGSI_FILE_COUNT; file++) { - uint i; - - for (i = 0; i < MAX_REGISTERS; i++) { - if (is_register_declared( ctx, file, i ) && !is_register_used( ctx, file, i ) && !ctx->regs_ind_used[file]) { - report_warning( ctx, "Register never used" ); - } - } - } - - /* Print totals, if any. - */ - if (ctx->errors || ctx->warnings) - debug_printf( "\n%u errors, %u warnings", ctx->errors, ctx->warnings ); - - return TRUE; -} - -boolean -tgsi_sanity_check( - struct tgsi_token *tokens ) -{ - struct sanity_check_ctx ctx; - - ctx.iter.prolog = NULL; - ctx.iter.iterate_instruction = iter_instruction; - ctx.iter.iterate_declaration = iter_declaration; - ctx.iter.iterate_immediate = iter_immediate; - ctx.iter.epilog = epilog; - - memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) ); - memset( ctx.regs_used, 0, sizeof( ctx.regs_used ) ); - memset( ctx.regs_ind_used, 0, sizeof( ctx.regs_ind_used ) ); - ctx.num_imms = 0; - ctx.num_instructions = 0; - ctx.index_of_END = ~0; - - ctx.errors = 0; - ctx.warnings = 0; - - if (!tgsi_iterate_shader( tokens, &ctx.iter )) - return FALSE; - - return ctx.errors == 0; -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.h b/src/gallium/auxiliary/tgsi/util/tgsi_sanity.h deleted file mode 100644 index ca45e94c7a..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_sanity.h +++ /dev/null @@ -1,49 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_SANITY_H -#define TGSI_SANITY_H - -#include "pipe/p_shader_tokens.h" - -#if defined __cplusplus -extern "C" { -#endif - -/* Check the given token stream for errors and common mistakes. - * Diagnostic messages are printed out to the debug output. - * Returns TRUE if there are no errors, even though there could be some warnings. - */ -boolean -tgsi_sanity_check( - struct tgsi_token *tokens ); - -#if defined __cplusplus -} -#endif - -#endif /* TGSI_SANITY_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c deleted file mode 100644 index 240aaaf362..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c +++ /dev/null @@ -1,226 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * TGSI program scan utility. - * Used to determine which registers and instructions are used by a shader. - * - * Authors: Brian Paul - */ - - -#include "tgsi_scan.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_build.h" - -#include "pipe/p_util.h" - - - -/** - */ -void -tgsi_scan_shader(const struct tgsi_token *tokens, - struct tgsi_shader_info *info) -{ - uint procType, i; - struct tgsi_parse_context parse; - - memset(info, 0, sizeof(*info)); - for (i = 0; i < TGSI_FILE_COUNT; i++) - info->file_max[i] = -1; - - /** - ** Setup to begin parsing input shader - **/ - if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) { - debug_printf("tgsi_parse_init() failed in tgsi_scan_shader()!\n"); - return; - } - procType = parse.FullHeader.Processor.Processor; - assert(procType == TGSI_PROCESSOR_FRAGMENT || - procType == TGSI_PROCESSOR_VERTEX || - procType == TGSI_PROCESSOR_GEOMETRY); - - - /** - ** Loop over incoming program tokens/instructions - */ - while( !tgsi_parse_end_of_tokens( &parse ) ) { - - info->num_tokens++; - - tgsi_parse_token( &parse ); - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_INSTRUCTION: - { - struct tgsi_full_instruction *fullinst - = &parse.FullToken.FullInstruction; - - assert(fullinst->Instruction.Opcode < TGSI_OPCODE_LAST); - info->opcode_count[fullinst->Instruction.Opcode]++; - } - break; - - case TGSI_TOKEN_TYPE_DECLARATION: - { - struct tgsi_full_declaration *fulldecl - = &parse.FullToken.FullDeclaration; - uint file = fulldecl->Declaration.File; - uint i; - for (i = fulldecl->DeclarationRange.First; - i <= fulldecl->DeclarationRange.Last; - i++) { - - /* only first 32 regs will appear in this bitfield */ - info->file_mask[file] |= (1 << i); - info->file_count[file]++; - info->file_max[file] = MAX2(info->file_max[file], (int)i); - - if (file == TGSI_FILE_INPUT) { - info->input_semantic_name[i] = (ubyte)fulldecl->Semantic.SemanticName; - info->input_semantic_index[i] = (ubyte)fulldecl->Semantic.SemanticIndex; - info->num_inputs++; - } - - if (file == TGSI_FILE_OUTPUT) { - info->output_semantic_name[i] = (ubyte)fulldecl->Semantic.SemanticName; - info->output_semantic_index[i] = (ubyte)fulldecl->Semantic.SemanticIndex; - info->num_outputs++; - } - - /* special case */ - if (procType == TGSI_PROCESSOR_FRAGMENT && - file == TGSI_FILE_OUTPUT && - fulldecl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) { - info->writes_z = TRUE; - } - } - } - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - info->immediate_count++; - break; - - default: - assert( 0 ); - } - } - - assert( info->file_max[TGSI_FILE_INPUT] + 1 == info->num_inputs ); - assert( info->file_max[TGSI_FILE_OUTPUT] + 1 == info->num_outputs ); - - info->uses_kill = (info->opcode_count[TGSI_OPCODE_KIL] || - info->opcode_count[TGSI_OPCODE_KILP]); - - tgsi_parse_free (&parse); -} - - - -/** - * Check if the given shader is a "passthrough" shader consisting of only - * MOV instructions of the form: MOV OUT[n], IN[n] - * - */ -boolean -tgsi_is_passthrough_shader(const struct tgsi_token *tokens) -{ - struct tgsi_parse_context parse; - - /** - ** Setup to begin parsing input shader - **/ - if (tgsi_parse_init(&parse, tokens) != TGSI_PARSE_OK) { - debug_printf("tgsi_parse_init() failed in tgsi_is_passthrough_shader()!\n"); - return FALSE; - } - - /** - ** Loop over incoming program tokens/instructions - */ - while (!tgsi_parse_end_of_tokens(&parse)) { - - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_INSTRUCTION: - { - struct tgsi_full_instruction *fullinst = - &parse.FullToken.FullInstruction; - const struct tgsi_full_src_register *src = - &fullinst->FullSrcRegisters[0]; - const struct tgsi_full_dst_register *dst = - &fullinst->FullDstRegisters[0]; - - /* Do a whole bunch of checks for a simple move */ - if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV || - src->SrcRegister.File != TGSI_FILE_INPUT || - dst->DstRegister.File != TGSI_FILE_OUTPUT || - src->SrcRegister.Index != dst->DstRegister.Index || - - src->SrcRegister.Negate || - src->SrcRegisterExtMod.Negate || - src->SrcRegisterExtMod.Absolute || - src->SrcRegisterExtMod.Scale2X || - src->SrcRegisterExtMod.Bias || - src->SrcRegisterExtMod.Complement || - - src->SrcRegister.SwizzleX != TGSI_SWIZZLE_X || - src->SrcRegister.SwizzleY != TGSI_SWIZZLE_Y || - src->SrcRegister.SwizzleZ != TGSI_SWIZZLE_Z || - src->SrcRegister.SwizzleW != TGSI_SWIZZLE_W || - - src->SrcRegisterExtSwz.ExtSwizzleX != TGSI_EXTSWIZZLE_X || - src->SrcRegisterExtSwz.ExtSwizzleY != TGSI_EXTSWIZZLE_Y || - src->SrcRegisterExtSwz.ExtSwizzleZ != TGSI_EXTSWIZZLE_Z || - src->SrcRegisterExtSwz.ExtSwizzleW != TGSI_EXTSWIZZLE_W || - - dst->DstRegister.WriteMask != TGSI_WRITEMASK_XYZW) - { - tgsi_parse_free(&parse); - return FALSE; - } - } - break; - - case TGSI_TOKEN_TYPE_DECLARATION: - /* fall-through */ - case TGSI_TOKEN_TYPE_IMMEDIATE: - /* fall-through */ - default: - ; /* no-op */ - } - } - - tgsi_parse_free(&parse); - - /* if we get here, it's a pass-through shader */ - return TRUE; -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h b/src/gallium/auxiliary/tgsi/util/tgsi_scan.h deleted file mode 100644 index 5cb6efb343..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.h +++ /dev/null @@ -1,74 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_SCAN_H -#define TGSI_SCAN_H - - -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" -#include "pipe/p_shader_tokens.h" - - -/** - * Shader summary info - */ -struct tgsi_shader_info -{ - uint num_tokens; - - /* XXX eventually remove the corresponding fields from pipe_shader_state: */ - ubyte num_inputs; - ubyte num_outputs; - ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */ - ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; - ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */ - ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; - - uint file_mask[TGSI_FILE_COUNT]; /**< bitmask of declared registers */ - uint file_count[TGSI_FILE_COUNT]; /**< number of declared registers */ - int file_max[TGSI_FILE_COUNT]; /**< highest index of declared registers */ - - uint immediate_count; /**< number of immediates declared */ - - uint opcode_count[TGSI_OPCODE_LAST]; /**< opcode histogram */ - - boolean writes_z; /**< does fragment shader write Z value? */ - boolean uses_kill; /**< KIL or KILP instruction used? */ -}; - - -extern void -tgsi_scan_shader(const struct tgsi_token *tokens, - struct tgsi_shader_info *info); - - -extern boolean -tgsi_is_passthrough_shader(const struct tgsi_token *tokens); - - -#endif /* TGSI_SCAN_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.c b/src/gallium/auxiliary/tgsi/util/tgsi_text.c deleted file mode 100644 index 35cb3055bb..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.c +++ /dev/null @@ -1,1221 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_debug.h" -#include "tgsi_text.h" -#include "tgsi_build.h" -#include "tgsi_parse.h" -#include "tgsi_sanity.h" -#include "tgsi_util.h" - -static boolean is_alpha_underscore( const char *cur ) -{ - return - (*cur >= 'a' && *cur <= 'z') || - (*cur >= 'A' && *cur <= 'Z') || - *cur == '_'; -} - -static boolean is_digit( const char *cur ) -{ - return *cur >= '0' && *cur <= '9'; -} - -static boolean is_digit_alpha_underscore( const char *cur ) -{ - return is_digit( cur ) || is_alpha_underscore( cur ); -} - -static boolean str_match_no_case( const char **pcur, const char *str ) -{ - const char *cur = *pcur; - - while (*str != '\0' && *str == toupper( *cur )) { - str++; - cur++; - } - if (*str == '\0') { - *pcur = cur; - return TRUE; - } - return FALSE; -} - -/* Eat zero or more whitespaces. - */ -static void eat_opt_white( const char **pcur ) -{ - while (**pcur == ' ' || **pcur == '\t' || **pcur == '\n') - (*pcur)++; -} - -/* Eat one or more whitespaces. - * Return TRUE if at least one whitespace eaten. - */ -static boolean eat_white( const char **pcur ) -{ - const char *cur = *pcur; - - eat_opt_white( pcur ); - return *pcur > cur; -} - -/* Parse unsigned integer. - * No checks for overflow. - */ -static boolean parse_uint( const char **pcur, uint *val ) -{ - const char *cur = *pcur; - - if (is_digit( cur )) { - *val = *cur++ - '0'; - while (is_digit( cur )) - *val = *val * 10 + *cur++ - '0'; - *pcur = cur; - return TRUE; - } - return FALSE; -} - -/* Parse floating point. - */ -static boolean parse_float( const char **pcur, float *val ) -{ - const char *cur = *pcur; - boolean integral_part = FALSE; - boolean fractional_part = FALSE; - - *val = (float) atof( cur ); - - if (*cur == '-' || *cur == '+') - cur++; - if (is_digit( cur )) { - cur++; - integral_part = TRUE; - while (is_digit( cur )) - cur++; - } - if (*cur == '.') { - cur++; - if (is_digit( cur )) { - cur++; - fractional_part = TRUE; - while (is_digit( cur )) - cur++; - } - } - if (!integral_part && !fractional_part) - return FALSE; - if (toupper( *cur ) == 'E') { - cur++; - if (*cur == '-' || *cur == '+') - cur++; - if (is_digit( cur )) { - cur++; - while (is_digit( cur )) - cur++; - } - else - return FALSE; - } - *pcur = cur; - return TRUE; -} - -struct translate_ctx -{ - const char *text; - const char *cur; - struct tgsi_token *tokens; - struct tgsi_token *tokens_cur; - struct tgsi_token *tokens_end; - struct tgsi_header *header; -}; - -static void report_error( struct translate_ctx *ctx, const char *msg ) -{ - debug_printf( "\nError: %s", msg ); -} - -/* Parse shader header. - * Return TRUE for one of the following headers. - * FRAG1.1 - * GEOM1.1 - * VERT1.1 - */ -static boolean parse_header( struct translate_ctx *ctx ) -{ - uint processor; - - if (str_match_no_case( &ctx->cur, "FRAG1.1" )) - processor = TGSI_PROCESSOR_FRAGMENT; - else if (str_match_no_case( &ctx->cur, "VERT1.1" )) - processor = TGSI_PROCESSOR_VERTEX; - else if (str_match_no_case( &ctx->cur, "GEOM1.1" )) - processor = TGSI_PROCESSOR_GEOMETRY; - else { - report_error( ctx, "Unknown header" ); - return FALSE; - } - - if (ctx->tokens_cur >= ctx->tokens_end) - return FALSE; - *(struct tgsi_version *) ctx->tokens_cur++ = tgsi_build_version(); - - if (ctx->tokens_cur >= ctx->tokens_end) - return FALSE; - ctx->header = (struct tgsi_header *) ctx->tokens_cur++; - *ctx->header = tgsi_build_header(); - - if (ctx->tokens_cur >= ctx->tokens_end) - return FALSE; - *(struct tgsi_processor *) ctx->tokens_cur++ = tgsi_build_processor( processor, ctx->header ); - - return TRUE; -} - -static boolean parse_label( struct translate_ctx *ctx, uint *val ) -{ - const char *cur = ctx->cur; - - if (parse_uint( &cur, val )) { - eat_opt_white( &cur ); - if (*cur == ':') { - cur++; - ctx->cur = cur; - return TRUE; - } - } - return FALSE; -} - -static const char *file_names[TGSI_FILE_COUNT] = -{ - "NULL", - "CONST", - "IN", - "OUT", - "TEMP", - "SAMP", - "ADDR", - "IMM" -}; - -static boolean -parse_file( const char **pcur, uint *file ) -{ - uint i; - - for (i = 0; i < TGSI_FILE_COUNT; i++) { - const char *cur = *pcur; - - if (str_match_no_case( &cur, file_names[i] )) { - if (!is_digit_alpha_underscore( cur )) { - *pcur = cur; - *file = i; - return TRUE; - } - } - } - return FALSE; -} - -static boolean -parse_opt_writemask( - struct translate_ctx *ctx, - uint *writemask ) -{ - const char *cur; - - cur = ctx->cur; - eat_opt_white( &cur ); - if (*cur == '.') { - cur++; - *writemask = TGSI_WRITEMASK_NONE; - eat_opt_white( &cur ); - if (toupper( *cur ) == 'X') { - cur++; - *writemask |= TGSI_WRITEMASK_X; - } - if (toupper( *cur ) == 'Y') { - cur++; - *writemask |= TGSI_WRITEMASK_Y; - } - if (toupper( *cur ) == 'Z') { - cur++; - *writemask |= TGSI_WRITEMASK_Z; - } - if (toupper( *cur ) == 'W') { - cur++; - *writemask |= TGSI_WRITEMASK_W; - } - - if (*writemask == TGSI_WRITEMASK_NONE) { - report_error( ctx, "Writemask expected" ); - return FALSE; - } - - ctx->cur = cur; - } - else { - *writemask = TGSI_WRITEMASK_XYZW; - } - return TRUE; -} - -/* ::= `[' - */ -static boolean -parse_register_file_bracket( - struct translate_ctx *ctx, - uint *file ) -{ - if (!parse_file( &ctx->cur, file )) { - report_error( ctx, "Unknown register file" ); - return FALSE; - } - eat_opt_white( &ctx->cur ); - if (*ctx->cur != '[') { - report_error( ctx, "Expected `['" ); - return FALSE; - } - ctx->cur++; - return TRUE; -} - -/* ::= - */ -static boolean -parse_register_file_bracket_index( - struct translate_ctx *ctx, - uint *file, - int *index ) -{ - uint uindex; - - if (!parse_register_file_bracket( ctx, file )) - return FALSE; - eat_opt_white( &ctx->cur ); - if (!parse_uint( &ctx->cur, &uindex )) { - report_error( ctx, "Expected literal unsigned integer" ); - return FALSE; - } - *index = (int) uindex; - return TRUE; -} - -/* Parse destination register operand. - * ::= `]' - */ -static boolean -parse_register_dst( - struct translate_ctx *ctx, - uint *file, - int *index ) -{ - if (!parse_register_file_bracket_index( ctx, file, index )) - return FALSE; - eat_opt_white( &ctx->cur ); - if (*ctx->cur != ']') { - report_error( ctx, "Expected `]'" ); - return FALSE; - } - ctx->cur++; - return TRUE; -} - -/* Parse source register operand. - * ::= `]' | - * `]' | - * `+' `]' | - * `-' `]' - */ -static boolean -parse_register_src( - struct translate_ctx *ctx, - uint *file, - int *index, - uint *ind_file, - int *ind_index ) -{ - const char *cur; - uint uindex; - - if (!parse_register_file_bracket( ctx, file )) - return FALSE; - eat_opt_white( &ctx->cur ); - cur = ctx->cur; - if (parse_file( &cur, ind_file )) { - if (!parse_register_dst( ctx, ind_file, ind_index )) - return FALSE; - eat_opt_white( &ctx->cur ); - if (*ctx->cur == '+' || *ctx->cur == '-') { - boolean negate; - - negate = *ctx->cur == '-'; - ctx->cur++; - eat_opt_white( &ctx->cur ); - if (!parse_uint( &ctx->cur, &uindex )) { - report_error( ctx, "Expected literal unsigned integer" ); - return FALSE; - } - if (negate) - *index = -(int) uindex; - else - *index = (int) uindex; - } - else { - *index = 0; - } - } - else { - if (!parse_uint( &ctx->cur, &uindex )) { - report_error( ctx, "Expected literal unsigned integer" ); - return FALSE; - } - *index = (int) uindex; - *ind_file = TGSI_FILE_NULL; - *ind_index = 0; - } - eat_opt_white( &ctx->cur ); - if (*ctx->cur != ']') { - report_error( ctx, "Expected `]'" ); - return FALSE; - } - ctx->cur++; - return TRUE; -} - -/* Parse register declaration. - * ::= `]' | - * `..' `]' - */ -static boolean -parse_register_dcl( - struct translate_ctx *ctx, - uint *file, - int *first, - int *last ) -{ - if (!parse_register_file_bracket_index( ctx, file, first )) - return FALSE; - eat_opt_white( &ctx->cur ); - if (ctx->cur[0] == '.' && ctx->cur[1] == '.') { - uint uindex; - - ctx->cur += 2; - eat_opt_white( &ctx->cur ); - if (!parse_uint( &ctx->cur, &uindex )) { - report_error( ctx, "Expected literal integer" ); - return FALSE; - } - *last = (int) uindex; - eat_opt_white( &ctx->cur ); - } - else { - *last = *first; - } - if (*ctx->cur != ']') { - report_error( ctx, "Expected `]' or `..'" ); - return FALSE; - } - ctx->cur++; - return TRUE; -} - -static const char *modulate_names[TGSI_MODULATE_COUNT] = -{ - "_1X", - "_2X", - "_4X", - "_8X", - "_D2", - "_D4", - "_D8" -}; - -static boolean -parse_dst_operand( - struct translate_ctx *ctx, - struct tgsi_full_dst_register *dst ) -{ - uint file; - int index; - uint writemask; - const char *cur; - - if (!parse_register_dst( ctx, &file, &index )) - return FALSE; - - cur = ctx->cur; - eat_opt_white( &cur ); - if (*cur == '_') { - uint i; - - for (i = 0; i < TGSI_MODULATE_COUNT; i++) { - if (str_match_no_case( &cur, modulate_names[i] )) { - if (!is_digit_alpha_underscore( cur )) { - dst->DstRegisterExtModulate.Modulate = i; - ctx->cur = cur; - break; - } - } - } - } - - if (!parse_opt_writemask( ctx, &writemask )) - return FALSE; - - dst->DstRegister.File = file; - dst->DstRegister.Index = index; - dst->DstRegister.WriteMask = writemask; - return TRUE; -} - -static boolean -parse_optional_swizzle( - struct translate_ctx *ctx, - uint swizzle[4], - boolean *parsed_swizzle, - boolean *parsed_extswizzle ) -{ - const char *cur = ctx->cur; - - *parsed_swizzle = FALSE; - *parsed_extswizzle = FALSE; - - eat_opt_white( &cur ); - if (*cur == '.') { - uint i; - - cur++; - eat_opt_white( &cur ); - for (i = 0; i < 4; i++) { - if (toupper( *cur ) == 'X') - swizzle[i] = TGSI_SWIZZLE_X; - else if (toupper( *cur ) == 'Y') - swizzle[i] = TGSI_SWIZZLE_Y; - else if (toupper( *cur ) == 'Z') - swizzle[i] = TGSI_SWIZZLE_Z; - else if (toupper( *cur ) == 'W') - swizzle[i] = TGSI_SWIZZLE_W; - else { - if (*cur == '0') - swizzle[i] = TGSI_EXTSWIZZLE_ZERO; - else if (*cur == '1') - swizzle[i] = TGSI_EXTSWIZZLE_ONE; - else { - report_error( ctx, "Expected register swizzle component `x', `y', `z', `w', `0' or `1'" ); - return FALSE; - } - *parsed_extswizzle = TRUE; - } - cur++; - } - *parsed_swizzle = TRUE; - ctx->cur = cur; - } - return TRUE; -} - -static boolean -parse_src_operand( - struct translate_ctx *ctx, - struct tgsi_full_src_register *src ) -{ - const char *cur; - float value; - uint file; - int index; - uint ind_file; - int ind_index; - uint swizzle[4]; - boolean parsed_swizzle; - boolean parsed_extswizzle; - - if (*ctx->cur == '-') { - cur = ctx->cur; - cur++; - eat_opt_white( &cur ); - if (*cur == '(') { - cur++; - src->SrcRegisterExtMod.Negate = 1; - eat_opt_white( &cur ); - ctx->cur = cur; - } - } - - if (*ctx->cur == '|') { - ctx->cur++; - eat_opt_white( &ctx->cur ); - src->SrcRegisterExtMod.Absolute = 1; - } - - if (*ctx->cur == '-') { - ctx->cur++; - eat_opt_white( &ctx->cur ); - src->SrcRegister.Negate = 1; - } - - cur = ctx->cur; - if (parse_float( &cur, &value )) { - if (value == 2.0f) { - eat_opt_white( &cur ); - if (*cur != '*') { - report_error( ctx, "Expected `*'" ); - return FALSE; - } - cur++; - if (*cur != '(') { - report_error( ctx, "Expected `('" ); - return FALSE; - } - cur++; - src->SrcRegisterExtMod.Scale2X = 1; - eat_opt_white( &cur ); - ctx->cur = cur; - } - } - - if (*ctx->cur == '(') { - ctx->cur++; - eat_opt_white( &ctx->cur ); - src->SrcRegisterExtMod.Bias = 1; - } - - cur = ctx->cur; - if (parse_float( &cur, &value )) { - if (value == 1.0f) { - eat_opt_white( &cur ); - if (*cur != '-') { - report_error( ctx, "Expected `-'" ); - return FALSE; - } - cur++; - if (*cur != '(') { - report_error( ctx, "Expected `('" ); - return FALSE; - } - cur++; - src->SrcRegisterExtMod.Complement = 1; - eat_opt_white( &cur ); - ctx->cur = cur; - } - } - - if (!parse_register_src( ctx, &file, &index, &ind_file, &ind_index )) - return FALSE; - src->SrcRegister.File = file; - src->SrcRegister.Index = index; - if (ind_file != TGSI_FILE_NULL) { - src->SrcRegister.Indirect = 1; - src->SrcRegisterInd.File = ind_file; - src->SrcRegisterInd.Index = ind_index; - } - - /* Parse optional swizzle. - */ - if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, &parsed_extswizzle )) { - if (parsed_extswizzle) { - assert( parsed_swizzle ); - - src->SrcRegisterExtSwz.ExtSwizzleX = swizzle[0]; - src->SrcRegisterExtSwz.ExtSwizzleY = swizzle[1]; - src->SrcRegisterExtSwz.ExtSwizzleZ = swizzle[2]; - src->SrcRegisterExtSwz.ExtSwizzleW = swizzle[3]; - } - else if (parsed_swizzle) { - src->SrcRegister.SwizzleX = swizzle[0]; - src->SrcRegister.SwizzleY = swizzle[1]; - src->SrcRegister.SwizzleZ = swizzle[2]; - src->SrcRegister.SwizzleW = swizzle[3]; - } - } - - if (src->SrcRegisterExtMod.Complement) { - eat_opt_white( &ctx->cur ); - if (*ctx->cur != ')') { - report_error( ctx, "Expected `)'" ); - return FALSE; - } - ctx->cur++; - } - - if (src->SrcRegisterExtMod.Bias) { - eat_opt_white( &ctx->cur ); - if (*ctx->cur != ')') { - report_error( ctx, "Expected `)'" ); - return FALSE; - } - ctx->cur++; - eat_opt_white( &ctx->cur ); - if (*ctx->cur != '-') { - report_error( ctx, "Expected `-'" ); - return FALSE; - } - ctx->cur++; - eat_opt_white( &ctx->cur ); - if (!parse_float( &ctx->cur, &value )) { - report_error( ctx, "Expected literal floating point" ); - return FALSE; - } - if (value != 0.5f) { - report_error( ctx, "Expected 0.5" ); - return FALSE; - } - } - - if (src->SrcRegisterExtMod.Scale2X) { - eat_opt_white( &ctx->cur ); - if (*ctx->cur != ')') { - report_error( ctx, "Expected `)'" ); - return FALSE; - } - ctx->cur++; - } - - if (src->SrcRegisterExtMod.Absolute) { - eat_opt_white( &ctx->cur ); - if (*ctx->cur != '|') { - report_error( ctx, "Expected `|'" ); - return FALSE; - } - ctx->cur++; - } - - if (src->SrcRegisterExtMod.Negate) { - eat_opt_white( &ctx->cur ); - if (*ctx->cur != ')') { - report_error( ctx, "Expected `)'" ); - return FALSE; - } - ctx->cur++; - } - - return TRUE; -} - -struct opcode_info -{ - uint num_dst; - uint num_src; - uint is_tex; - uint is_branch; - const char *mnemonic; -}; - -static const struct opcode_info opcode_info[TGSI_OPCODE_LAST] = -{ - { 1, 1, 0, 0, "ARL" }, - { 1, 1, 0, 0, "MOV" }, - { 1, 1, 0, 0, "LIT" }, - { 1, 1, 0, 0, "RCP" }, - { 1, 1, 0, 0, "RSQ" }, - { 1, 1, 0, 0, "EXP" }, - { 1, 1, 0, 0, "LOG" }, - { 1, 2, 0, 0, "MUL" }, - { 1, 2, 0, 0, "ADD" }, - { 1, 2, 0, 0, "DP3" }, - { 1, 2, 0, 0, "DP4" }, - { 1, 2, 0, 0, "DST" }, - { 1, 2, 0, 0, "MIN" }, - { 1, 2, 0, 0, "MAX" }, - { 1, 2, 0, 0, "SLT" }, - { 1, 2, 0, 0, "SGE" }, - { 1, 3, 0, 0, "MAD" }, - { 1, 2, 0, 0, "SUB" }, - { 1, 3, 0, 0, "LERP" }, - { 1, 3, 0, 0, "CND" }, - { 1, 3, 0, 0, "CND0" }, - { 1, 3, 0, 0, "DOT2ADD" }, - { 1, 2, 0, 0, "INDEX" }, - { 1, 1, 0, 0, "NEGATE" }, - { 1, 1, 0, 0, "FRAC" }, - { 1, 3, 0, 0, "CLAMP" }, - { 1, 1, 0, 0, "FLOOR" }, - { 1, 1, 0, 0, "ROUND" }, - { 1, 1, 0, 0, "EXPBASE2" }, - { 1, 1, 0, 0, "LOGBASE2" }, - { 1, 2, 0, 0, "POWER" }, - { 1, 2, 0, 0, "CROSSPRODUCT" }, - { 1, 2, 0, 0, "MULTIPLYMATRIX" }, - { 1, 1, 0, 0, "ABS" }, - { 1, 1, 0, 0, "RCC" }, - { 1, 2, 0, 0, "DPH" }, - { 1, 1, 0, 0, "COS" }, - { 1, 1, 0, 0, "DDX" }, - { 1, 1, 0, 0, "DDY" }, - { 0, 1, 0, 0, "KILP" }, - { 1, 1, 0, 0, "PK2H" }, - { 1, 1, 0, 0, "PK2US" }, - { 1, 1, 0, 0, "PK4B" }, - { 1, 1, 0, 0, "PK4UB" }, - { 1, 2, 0, 0, "RFL" }, - { 1, 2, 0, 0, "SEQ" }, - { 1, 2, 0, 0, "SFL" }, - { 1, 2, 0, 0, "SGT" }, - { 1, 1, 0, 0, "SIN" }, - { 1, 2, 0, 0, "SLE" }, - { 1, 2, 0, 0, "SNE" }, - { 1, 2, 0, 0, "STR" }, - { 1, 2, 1, 0, "TEX" }, - { 1, 4, 1, 0, "TXD" }, - { 1, 2, 1, 0, "TXP" }, - { 1, 1, 0, 0, "UP2H" }, - { 1, 1, 0, 0, "UP2US" }, - { 1, 1, 0, 0, "UP4B" }, - { 1, 1, 0, 0, "UP4UB" }, - { 1, 3, 0, 0, "X2D" }, - { 1, 1, 0, 0, "ARA" }, - { 1, 1, 0, 0, "ARR" }, - { 0, 1, 0, 0, "BRA" }, - { 0, 0, 0, 1, "CAL" }, - { 0, 0, 0, 0, "RET" }, - { 1, 1, 0, 0, "SSG" }, - { 1, 3, 0, 0, "CMP" }, - { 1, 1, 0, 0, "SCS" }, - { 1, 2, 1, 0, "TXB" }, - { 1, 1, 0, 0, "NRM" }, - { 1, 2, 0, 0, "DIV" }, - { 1, 2, 0, 0, "DP2" }, - { 1, 2, 1, 0, "TXL" }, - { 0, 0, 0, 0, "BRK" }, - { 0, 1, 0, 1, "IF" }, - { 0, 0, 0, 0, "LOOP" }, - { 0, 1, 0, 0, "REP" }, - { 0, 0, 0, 1, "ELSE" }, - { 0, 0, 0, 0, "ENDIF" }, - { 0, 0, 0, 0, "ENDLOOP" }, - { 0, 0, 0, 0, "ENDREP" }, - { 0, 1, 0, 0, "PUSHA" }, - { 1, 0, 0, 0, "POPA" }, - { 1, 1, 0, 0, "CEIL" }, - { 1, 1, 0, 0, "I2F" }, - { 1, 1, 0, 0, "NOT" }, - { 1, 1, 0, 0, "TRUNC" }, - { 1, 2, 0, 0, "SHL" }, - { 1, 2, 0, 0, "SHR" }, - { 1, 2, 0, 0, "AND" }, - { 1, 2, 0, 0, "OR" }, - { 1, 2, 0, 0, "MOD" }, - { 1, 2, 0, 0, "XOR" }, - { 1, 3, 0, 0, "SAD" }, - { 1, 2, 1, 0, "TXF" }, - { 1, 2, 1, 0, "TXQ" }, - { 0, 0, 0, 0, "CONT" }, - { 0, 0, 0, 0, "EMIT" }, - { 0, 0, 0, 0, "ENDPRIM" }, - { 0, 0, 0, 1, "BGNLOOP2" }, - { 0, 0, 0, 0, "BGNSUB" }, - { 0, 0, 0, 1, "ENDLOOP2" }, - { 0, 0, 0, 0, "ENDSUB" }, - { 1, 1, 0, 0, "NOISE1" }, - { 1, 1, 0, 0, "NOISE2" }, - { 1, 1, 0, 0, "NOISE3" }, - { 1, 1, 0, 0, "NOISE4" }, - { 0, 0, 0, 0, "NOP" }, - { 1, 2, 0, 0, "M4X3" }, - { 1, 2, 0, 0, "M3X4" }, - { 1, 2, 0, 0, "M3X3" }, - { 1, 2, 0, 0, "M3X2" }, - { 1, 1, 0, 0, "NRM4" }, - { 0, 1, 0, 0, "CALLNZ" }, - { 0, 1, 0, 0, "IFC" }, - { 0, 1, 0, 0, "BREAKC" }, - { 0, 0, 0, 0, "KIL" }, - { 0, 0, 0, 0, "END" }, - { 1, 1, 0, 0, "SWZ" } -}; - -static const char *texture_names[TGSI_TEXTURE_COUNT] = -{ - "UNKNOWN", - "1D", - "2D", - "3D", - "CUBE", - "RECT", - "SHADOW1D", - "SHADOW2D", - "SHADOWRECT" -}; - -static boolean -parse_instruction( - struct translate_ctx *ctx, - boolean has_label ) -{ - uint i; - uint saturate = TGSI_SAT_NONE; - const struct opcode_info *info; - struct tgsi_full_instruction inst; - uint advance; - - /* Parse instruction name. - */ - eat_opt_white( &ctx->cur ); - for (i = 0; i < TGSI_OPCODE_LAST; i++) { - const char *cur = ctx->cur; - - info = &opcode_info[i]; - if (str_match_no_case( &cur, info->mnemonic )) { - if (str_match_no_case( &cur, "_SATNV" )) - saturate = TGSI_SAT_MINUS_PLUS_ONE; - else if (str_match_no_case( &cur, "_SAT" )) - saturate = TGSI_SAT_ZERO_ONE; - - if (info->num_dst + info->num_src + info->is_tex == 0) { - if (!is_digit_alpha_underscore( cur )) { - ctx->cur = cur; - break; - } - } - else if (*cur == '\0' || eat_white( &cur )) { - ctx->cur = cur; - break; - } - } - } - if (i == TGSI_OPCODE_LAST) { - if (has_label) - report_error( ctx, "Unknown opcode" ); - else - report_error( ctx, "Expected `DCL', `IMM' or a label" ); - return FALSE; - } - - inst = tgsi_default_full_instruction(); - inst.Instruction.Opcode = i; - inst.Instruction.Saturate = saturate; - inst.Instruction.NumDstRegs = info->num_dst; - inst.Instruction.NumSrcRegs = info->num_src; - - /* Parse instruction operands. - */ - for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) { - if (i > 0) { - eat_opt_white( &ctx->cur ); - if (*ctx->cur != ',') { - report_error( ctx, "Expected `,'" ); - return FALSE; - } - ctx->cur++; - eat_opt_white( &ctx->cur ); - } - - if (i < info->num_dst) { - if (!parse_dst_operand( ctx, &inst.FullDstRegisters[i] )) - return FALSE; - } - else if (i < info->num_dst + info->num_src) { - if (!parse_src_operand( ctx, &inst.FullSrcRegisters[i - info->num_dst] )) - return FALSE; - } - else { - uint j; - - for (j = 0; j < TGSI_TEXTURE_COUNT; j++) { - if (str_match_no_case( &ctx->cur, texture_names[j] )) { - if (!is_digit_alpha_underscore( ctx->cur )) { - inst.InstructionExtTexture.Texture = j; - break; - } - } - } - if (j == TGSI_TEXTURE_COUNT) { - report_error( ctx, "Expected texture target" ); - return FALSE; - } - } - } - - if (info->is_branch) { - uint target; - - eat_opt_white( &ctx->cur ); - if (*ctx->cur != ':') { - report_error( ctx, "Expected `:'" ); - return FALSE; - } - ctx->cur++; - eat_opt_white( &ctx->cur ); - if (!parse_uint( &ctx->cur, &target )) { - report_error( ctx, "Expected a label" ); - return FALSE; - } - inst.InstructionExtLabel.Label = target; - } - - advance = tgsi_build_full_instruction( - &inst, - ctx->tokens_cur, - ctx->header, - (uint) (ctx->tokens_end - ctx->tokens_cur) ); - if (advance == 0) - return FALSE; - ctx->tokens_cur += advance; - - return TRUE; -} - -static const char *semantic_names[TGSI_SEMANTIC_COUNT] = -{ - "POSITION", - "COLOR", - "BCOLOR", - "FOG", - "PSIZE", - "GENERIC", - "NORMAL" -}; - -static const char *interpolate_names[TGSI_INTERPOLATE_COUNT] = -{ - "CONSTANT", - "LINEAR", - "PERSPECTIVE" -}; - -static boolean parse_declaration( struct translate_ctx *ctx ) -{ - struct tgsi_full_declaration decl; - uint file; - int first; - int last; - uint writemask; - const char *cur; - uint advance; - - if (!eat_white( &ctx->cur )) { - report_error( ctx, "Syntax error" ); - return FALSE; - } - if (!parse_register_dcl( ctx, &file, &first, &last )) - return FALSE; - if (!parse_opt_writemask( ctx, &writemask )) - return FALSE; - - decl = tgsi_default_full_declaration(); - decl.Declaration.File = file; - decl.Declaration.UsageMask = writemask; - decl.DeclarationRange.First = first; - decl.DeclarationRange.Last = last; - - cur = ctx->cur; - eat_opt_white( &cur ); - if (*cur == ',') { - uint i; - - cur++; - eat_opt_white( &cur ); - for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) { - if (str_match_no_case( &cur, semantic_names[i] )) { - const char *cur2 = cur; - uint index; - - if (is_digit_alpha_underscore( cur )) - continue; - eat_opt_white( &cur2 ); - if (*cur2 == '[') { - cur2++; - eat_opt_white( &cur2 ); - if (!parse_uint( &cur2, &index )) { - report_error( ctx, "Expected literal integer" ); - return FALSE; - } - eat_opt_white( &cur2 ); - if (*cur2 != ']') { - report_error( ctx, "Expected `]'" ); - return FALSE; - } - cur2++; - - decl.Semantic.SemanticIndex = index; - - cur = cur2; - } - - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = i; - - ctx->cur = cur; - break; - } - } - } - - cur = ctx->cur; - eat_opt_white( &cur ); - if (*cur == ',') { - uint i; - - cur++; - eat_opt_white( &cur ); - for (i = 0; i < TGSI_INTERPOLATE_COUNT; i++) { - if (str_match_no_case( &cur, interpolate_names[i] )) { - if (is_digit_alpha_underscore( cur )) - continue; - decl.Declaration.Interpolate = i; - - ctx->cur = cur; - break; - } - } - if (i == TGSI_INTERPOLATE_COUNT) { - report_error( ctx, "Expected semantic or interpolate attribute" ); - return FALSE; - } - } - - advance = tgsi_build_full_declaration( - &decl, - ctx->tokens_cur, - ctx->header, - (uint) (ctx->tokens_end - ctx->tokens_cur) ); - if (advance == 0) - return FALSE; - ctx->tokens_cur += advance; - - return TRUE; -} - -static boolean parse_immediate( struct translate_ctx *ctx ) -{ - struct tgsi_full_immediate imm; - uint i; - float values[4]; - uint advance; - - if (!eat_white( &ctx->cur )) { - report_error( ctx, "Syntax error" ); - return FALSE; - } - if (!str_match_no_case( &ctx->cur, "FLT32" ) || is_digit_alpha_underscore( ctx->cur )) { - report_error( ctx, "Expected `FLT32'" ); - return FALSE; - } - eat_opt_white( &ctx->cur ); - if (*ctx->cur != '{') { - report_error( ctx, "Expected `{'" ); - return FALSE; - } - ctx->cur++; - for (i = 0; i < 4; i++) { - eat_opt_white( &ctx->cur ); - if (i > 0) { - if (*ctx->cur != ',') { - report_error( ctx, "Expected `,'" ); - return FALSE; - } - ctx->cur++; - eat_opt_white( &ctx->cur ); - } - if (!parse_float( &ctx->cur, &values[i] )) { - report_error( ctx, "Expected literal floating point" ); - return FALSE; - } - } - eat_opt_white( &ctx->cur ); - if (*ctx->cur != '}') { - report_error( ctx, "Expected `}'" ); - return FALSE; - } - ctx->cur++; - - imm = tgsi_default_full_immediate(); - imm.Immediate.Size += 4; - imm.Immediate.DataType = TGSI_IMM_FLOAT32; - imm.u.Pointer = values; - - advance = tgsi_build_full_immediate( - &imm, - ctx->tokens_cur, - ctx->header, - (uint) (ctx->tokens_end - ctx->tokens_cur) ); - if (advance == 0) - return FALSE; - ctx->tokens_cur += advance; - - return TRUE; -} - -static boolean translate( struct translate_ctx *ctx ) -{ - eat_opt_white( &ctx->cur ); - if (!parse_header( ctx )) - return FALSE; - - while (*ctx->cur != '\0') { - uint label_val = 0; - - if (!eat_white( &ctx->cur )) { - report_error( ctx, "Syntax error" ); - return FALSE; - } - - if (*ctx->cur == '\0') - break; - - if (parse_label( ctx, &label_val )) { - if (!parse_instruction( ctx, TRUE )) - return FALSE; - } - else if (str_match_no_case( &ctx->cur, "DCL" )) { - if (!parse_declaration( ctx )) - return FALSE; - } - else if (str_match_no_case( &ctx->cur, "IMM" )) { - if (!parse_immediate( ctx )) - return FALSE; - } - else if (!parse_instruction( ctx, FALSE )) { - return FALSE; - } - } - - return TRUE; -} - -boolean -tgsi_text_translate( - const char *text, - struct tgsi_token *tokens, - uint num_tokens ) -{ - struct translate_ctx ctx; - - ctx.text = text; - ctx.cur = text; - ctx.tokens = tokens; - ctx.tokens_cur = tokens; - ctx.tokens_end = tokens + num_tokens; - - if (!translate( &ctx )) - return FALSE; - - return tgsi_sanity_check( tokens ); -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_text.h b/src/gallium/auxiliary/tgsi/util/tgsi_text.h deleted file mode 100644 index 8eeeeef140..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_text.h +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_TEXT_H -#define TGSI_TEXT_H - -#include "pipe/p_shader_tokens.h" - -#if defined __cplusplus -extern "C" { -#endif - -boolean -tgsi_text_translate( - const char *text, - struct tgsi_token *tokens, - uint num_tokens ); - -#if defined __cplusplus -} -#endif - -#endif /* TGSI_TEXT_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_transform.c b/src/gallium/auxiliary/tgsi/util/tgsi_transform.c deleted file mode 100644 index 357f77b05a..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_transform.c +++ /dev/null @@ -1,199 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * TGSI program transformation utility. - * - * Authors: Brian Paul - */ - - -#include "tgsi_transform.h" - - - -static void -emit_instruction(struct tgsi_transform_context *ctx, - const struct tgsi_full_instruction *inst) -{ - uint ti = ctx->ti; - - ti += tgsi_build_full_instruction(inst, - ctx->tokens_out + ti, - ctx->header, - ctx->max_tokens_out - ti); - ctx->ti = ti; -} - - -static void -emit_declaration(struct tgsi_transform_context *ctx, - const struct tgsi_full_declaration *decl) -{ - uint ti = ctx->ti; - - ti += tgsi_build_full_declaration(decl, - ctx->tokens_out + ti, - ctx->header, - ctx->max_tokens_out - ti); - ctx->ti = ti; -} - - -static void -emit_immediate(struct tgsi_transform_context *ctx, - const struct tgsi_full_immediate *imm) -{ - uint ti = ctx->ti; - - ti += tgsi_build_full_immediate(imm, - ctx->tokens_out + ti, - ctx->header, - ctx->max_tokens_out - ti); - ctx->ti = ti; -} - - - -/** - * Apply user-defined transformations to the input shader to produce - * the output shader. - * For example, a register search-and-replace operation could be applied - * by defining a transform_instruction() callback that examined and changed - * the instruction src/dest regs. - * - * \return number of tokens emitted - */ -int -tgsi_transform_shader(const struct tgsi_token *tokens_in, - struct tgsi_token *tokens_out, - uint max_tokens_out, - struct tgsi_transform_context *ctx) -{ - uint procType; - - /* input shader */ - struct tgsi_parse_context parse; - - /* output shader */ - struct tgsi_processor *processor; - - - /** - ** callback context init - **/ - ctx->emit_instruction = emit_instruction; - ctx->emit_declaration = emit_declaration; - ctx->emit_immediate = emit_immediate; - ctx->tokens_out = tokens_out; - ctx->max_tokens_out = max_tokens_out; - - - /** - ** Setup to begin parsing input shader - **/ - if (tgsi_parse_init( &parse, tokens_in ) != TGSI_PARSE_OK) { - debug_printf("tgsi_parse_init() failed in tgsi_transform_shader()!\n"); - return -1; - } - procType = parse.FullHeader.Processor.Processor; - assert(procType == TGSI_PROCESSOR_FRAGMENT || - procType == TGSI_PROCESSOR_VERTEX || - procType == TGSI_PROCESSOR_GEOMETRY); - - - /** - ** Setup output shader - **/ - *(struct tgsi_version *) &tokens_out[0] = tgsi_build_version(); - - ctx->header = (struct tgsi_header *) (tokens_out + 1); - *ctx->header = tgsi_build_header(); - - processor = (struct tgsi_processor *) (tokens_out + 2); - *processor = tgsi_build_processor( procType, ctx->header ); - - ctx->ti = 3; - - - /** - ** Loop over incoming program tokens/instructions - */ - while( !tgsi_parse_end_of_tokens( &parse ) ) { - - tgsi_parse_token( &parse ); - - switch( parse.FullToken.Token.Type ) { - case TGSI_TOKEN_TYPE_INSTRUCTION: - { - struct tgsi_full_instruction *fullinst - = &parse.FullToken.FullInstruction; - - if (ctx->transform_instruction) - ctx->transform_instruction(ctx, fullinst); - else - ctx->emit_instruction(ctx, fullinst); - } - break; - - case TGSI_TOKEN_TYPE_DECLARATION: - { - struct tgsi_full_declaration *fulldecl - = &parse.FullToken.FullDeclaration; - - if (ctx->transform_declaration) - ctx->transform_declaration(ctx, fulldecl); - else - ctx->emit_declaration(ctx, fulldecl); - } - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - { - struct tgsi_full_immediate *fullimm - = &parse.FullToken.FullImmediate; - - if (ctx->transform_immediate) - ctx->transform_immediate(ctx, fullimm); - else - ctx->emit_immediate(ctx, fullimm); - } - break; - - default: - assert( 0 ); - } - } - - if (ctx->epilog) { - ctx->epilog(ctx); - } - - tgsi_parse_free (&parse); - - return ctx->ti; -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_transform.h b/src/gallium/auxiliary/tgsi/util/tgsi_transform.h deleted file mode 100644 index fcf85d603b..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_transform.h +++ /dev/null @@ -1,93 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_TRANSFORM_H -#define TGSI_TRANSFORM_H - - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_build.h" - - - -/** - * Subclass this to add caller-specific data - */ -struct tgsi_transform_context -{ -/**** PUBLIC ***/ - - /** - * User-defined callbacks invoked per instruction. - */ - void (*transform_instruction)(struct tgsi_transform_context *ctx, - struct tgsi_full_instruction *inst); - - void (*transform_declaration)(struct tgsi_transform_context *ctx, - struct tgsi_full_declaration *decl); - - void (*transform_immediate)(struct tgsi_transform_context *ctx, - struct tgsi_full_immediate *imm); - - /** - * Called at end of input program to allow caller to append extra - * instructions. Return number of tokens emitted. - */ - void (*epilog)(struct tgsi_transform_context *ctx); - - -/*** PRIVATE ***/ - - /** - * These are setup by tgsi_transform_shader() and cannot be overridden. - * Meant to be called from in the above user callback functions. - */ - void (*emit_instruction)(struct tgsi_transform_context *ctx, - const struct tgsi_full_instruction *inst); - void (*emit_declaration)(struct tgsi_transform_context *ctx, - const struct tgsi_full_declaration *decl); - void (*emit_immediate)(struct tgsi_transform_context *ctx, - const struct tgsi_full_immediate *imm); - - struct tgsi_header *header; - uint max_tokens_out; - struct tgsi_token *tokens_out; - uint ti; -}; - - - -extern int -tgsi_transform_shader(const struct tgsi_token *tokens_in, - struct tgsi_token *tokens_out, - uint max_tokens_out, - struct tgsi_transform_context *ctx); - - -#endif /* TGSI_TRANSFORM_H */ diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.c b/src/gallium/auxiliary/tgsi/util/tgsi_util.c deleted file mode 100644 index 09486e649e..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_util.c +++ /dev/null @@ -1,300 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "tgsi_parse.h" -#include "tgsi_build.h" -#include "tgsi_util.h" - -union pointer_hack -{ - void *pointer; - uint64_t uint64; -}; - -void * -tgsi_align_128bit( - void *unaligned ) -{ - union pointer_hack ph; - - ph.uint64 = 0; - ph.pointer = unaligned; - ph.uint64 = (ph.uint64 + 15) & ~15; - return ph.pointer; -} - -unsigned -tgsi_util_get_src_register_swizzle( - const struct tgsi_src_register *reg, - unsigned component ) -{ - switch( component ) { - case 0: - return reg->SwizzleX; - case 1: - return reg->SwizzleY; - case 2: - return reg->SwizzleZ; - case 3: - return reg->SwizzleW; - default: - assert( 0 ); - } - return 0; -} - -unsigned -tgsi_util_get_src_register_extswizzle( - const struct tgsi_src_register_ext_swz *reg, - unsigned component ) -{ - switch( component ) { - case 0: - return reg->ExtSwizzleX; - case 1: - return reg->ExtSwizzleY; - case 2: - return reg->ExtSwizzleZ; - case 3: - return reg->ExtSwizzleW; - default: - assert( 0 ); - } - return 0; -} - -unsigned -tgsi_util_get_full_src_register_extswizzle( - const struct tgsi_full_src_register *reg, - unsigned component ) -{ - unsigned swizzle; - - /* - * First, calculate the extended swizzle for a given channel. This will give - * us either a channel index into the simple swizzle or a constant 1 or 0. - */ - swizzle = tgsi_util_get_src_register_extswizzle( - ®->SrcRegisterExtSwz, - component ); - - assert (TGSI_SWIZZLE_X == TGSI_EXTSWIZZLE_X); - assert (TGSI_SWIZZLE_Y == TGSI_EXTSWIZZLE_Y); - assert (TGSI_SWIZZLE_Z == TGSI_EXTSWIZZLE_Z); - assert (TGSI_SWIZZLE_W == TGSI_EXTSWIZZLE_W); - assert (TGSI_EXTSWIZZLE_ZERO > TGSI_SWIZZLE_W); - assert (TGSI_EXTSWIZZLE_ONE > TGSI_SWIZZLE_W); - - /* - * Second, calculate the simple swizzle for the unswizzled channel index. - * Leave the constants intact, they are not affected by the simple swizzle. - */ - if( swizzle <= TGSI_SWIZZLE_W ) { - swizzle = tgsi_util_get_src_register_swizzle( - ®->SrcRegister, - swizzle ); - } - - return swizzle; -} - -void -tgsi_util_set_src_register_swizzle( - struct tgsi_src_register *reg, - unsigned swizzle, - unsigned component ) -{ - switch( component ) { - case 0: - reg->SwizzleX = swizzle; - break; - case 1: - reg->SwizzleY = swizzle; - break; - case 2: - reg->SwizzleZ = swizzle; - break; - case 3: - reg->SwizzleW = swizzle; - break; - default: - assert( 0 ); - } -} - -void -tgsi_util_set_src_register_extswizzle( - struct tgsi_src_register_ext_swz *reg, - unsigned swizzle, - unsigned component ) -{ - switch( component ) { - case 0: - reg->ExtSwizzleX = swizzle; - break; - case 1: - reg->ExtSwizzleY = swizzle; - break; - case 2: - reg->ExtSwizzleZ = swizzle; - break; - case 3: - reg->ExtSwizzleW = swizzle; - break; - default: - assert( 0 ); - } -} - -unsigned -tgsi_util_get_src_register_extnegate( - const struct tgsi_src_register_ext_swz *reg, - unsigned component ) -{ - switch( component ) { - case 0: - return reg->NegateX; - case 1: - return reg->NegateY; - case 2: - return reg->NegateZ; - case 3: - return reg->NegateW; - default: - assert( 0 ); - } - return 0; -} - -void -tgsi_util_set_src_register_extnegate( - struct tgsi_src_register_ext_swz *reg, - unsigned negate, - unsigned component ) -{ - switch( component ) { - case 0: - reg->NegateX = negate; - break; - case 1: - reg->NegateY = negate; - break; - case 2: - reg->NegateZ = negate; - break; - case 3: - reg->NegateW = negate; - break; - default: - assert( 0 ); - } -} - -unsigned -tgsi_util_get_full_src_register_sign_mode( - const struct tgsi_full_src_register *reg, - unsigned component ) -{ - unsigned sign_mode; - - if( reg->SrcRegisterExtMod.Absolute ) { - /* Consider only the post-abs negation. */ - - if( reg->SrcRegisterExtMod.Negate ) { - sign_mode = TGSI_UTIL_SIGN_SET; - } - else { - sign_mode = TGSI_UTIL_SIGN_CLEAR; - } - } - else { - /* Accumulate the three negations. */ - - unsigned negate; - - negate = reg->SrcRegister.Negate; - if( tgsi_util_get_src_register_extnegate( ®->SrcRegisterExtSwz, component ) ) { - negate = !negate; - } - if( reg->SrcRegisterExtMod.Negate ) { - negate = !negate; - } - - if( negate ) { - sign_mode = TGSI_UTIL_SIGN_TOGGLE; - } - else { - sign_mode = TGSI_UTIL_SIGN_KEEP; - } - } - - return sign_mode; -} - -void -tgsi_util_set_full_src_register_sign_mode( - struct tgsi_full_src_register *reg, - unsigned sign_mode ) -{ - reg->SrcRegisterExtSwz.NegateX = 0; - reg->SrcRegisterExtSwz.NegateY = 0; - reg->SrcRegisterExtSwz.NegateZ = 0; - reg->SrcRegisterExtSwz.NegateW = 0; - - switch (sign_mode) - { - case TGSI_UTIL_SIGN_CLEAR: - reg->SrcRegister.Negate = 0; - reg->SrcRegisterExtMod.Absolute = 1; - reg->SrcRegisterExtMod.Negate = 0; - break; - - case TGSI_UTIL_SIGN_SET: - reg->SrcRegister.Negate = 0; - reg->SrcRegisterExtMod.Absolute = 1; - reg->SrcRegisterExtMod.Negate = 1; - break; - - case TGSI_UTIL_SIGN_TOGGLE: - reg->SrcRegister.Negate = 1; - reg->SrcRegisterExtMod.Absolute = 0; - reg->SrcRegisterExtMod.Negate = 0; - break; - - case TGSI_UTIL_SIGN_KEEP: - reg->SrcRegister.Negate = 0; - reg->SrcRegisterExtMod.Absolute = 0; - reg->SrcRegisterExtMod.Negate = 0; - break; - - default: - assert( 0 ); - } -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.h b/src/gallium/auxiliary/tgsi/util/tgsi_util.h deleted file mode 100644 index 7877f34558..0000000000 --- a/src/gallium/auxiliary/tgsi/util/tgsi_util.h +++ /dev/null @@ -1,96 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef TGSI_UTIL_H -#define TGSI_UTIL_H - -#if defined __cplusplus -extern "C" { -#endif - -void * -tgsi_align_128bit( - void *unaligned ); - -unsigned -tgsi_util_get_src_register_swizzle( - const struct tgsi_src_register *reg, - unsigned component ); - -unsigned -tgsi_util_get_src_register_extswizzle( - const struct tgsi_src_register_ext_swz *reg, - unsigned component); - -unsigned -tgsi_util_get_full_src_register_extswizzle( - const struct tgsi_full_src_register *reg, - unsigned component ); - -void -tgsi_util_set_src_register_swizzle( - struct tgsi_src_register *reg, - unsigned swizzle, - unsigned component ); - -void -tgsi_util_set_src_register_extswizzle( - struct tgsi_src_register_ext_swz *reg, - unsigned swizzle, - unsigned component ); - -unsigned -tgsi_util_get_src_register_extnegate( - const struct tgsi_src_register_ext_swz *reg, - unsigned component ); - -void -tgsi_util_set_src_register_extnegate( - struct tgsi_src_register_ext_swz *reg, - unsigned negate, - unsigned component ); - -#define TGSI_UTIL_SIGN_CLEAR 0 /* Force positive */ -#define TGSI_UTIL_SIGN_SET 1 /* Force negative */ -#define TGSI_UTIL_SIGN_TOGGLE 2 /* Negate */ -#define TGSI_UTIL_SIGN_KEEP 3 /* No change */ - -unsigned -tgsi_util_get_full_src_register_sign_mode( - const struct tgsi_full_src_register *reg, - unsigned component ); - -void -tgsi_util_set_full_src_register_sign_mode( - struct tgsi_full_src_register *reg, - unsigned sign_mode ); - -#if defined __cplusplus -} -#endif - -#endif /* TGSI_UTIL_H */ diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 4999822068..8713ff5d58 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -45,9 +45,9 @@ #include "util/u_gen_mipmap.h" #include "util/u_simple_shaders.h" -#include "tgsi/util/tgsi_build.h" -#include "tgsi/util/tgsi_dump.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_build.h" +#include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_parse.h" #include "cso_cache/cso_context.h" diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index 505d93d727..c34fb6ee33 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -43,9 +43,9 @@ #include "util/u_simple_shaders.h" -#include "tgsi/util/tgsi_build.h" -#include "tgsi/util/tgsi_dump.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_build.h" +#include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 8df41c1d4c..f1d1ca89a9 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -37,7 +37,7 @@ #include "cell_winsys.h" #include "cell/common.h" #include "rtasm/rtasm_ppc_spe.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_scan.h" struct cell_vbuf_render; diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c index c3a3fbd066..f5707f2bb8 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -30,7 +30,7 @@ #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" #include "draw/draw_context.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" #include "cell_context.h" #include "cell_state.h" diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 3a80df427d..96393732ed 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -65,8 +65,8 @@ #include "pipe/p_state.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_util.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" #include "spu_exec.h" #include "spu_main.h" #include "spu_vertex_shader.h" diff --git a/src/gallium/drivers/cell/spu/spu_exec.h b/src/gallium/drivers/cell/spu/spu_exec.h index 3e17c490d2..c68f78f59b 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.h +++ b/src/gallium/drivers/cell/spu/spu_exec.h @@ -29,7 +29,7 @@ #define SPU_EXEC_H #include "pipe/p_compiler.h" -#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/tgsi_exec.h" #if defined __cplusplus extern "C" { diff --git a/src/gallium/drivers/cell/spu/spu_util.c b/src/gallium/drivers/cell/spu/spu_util.c index ea4274a0a7..74ab2bbd1f 100644 --- a/src/gallium/drivers/cell/spu/spu_util.c +++ b/src/gallium/drivers/cell/spu/spu_util.c @@ -1,8 +1,8 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" //#include "tgsi_build.h" -#include "tgsi/util/tgsi_util.h" +#include "tgsi/tgsi_util.h" unsigned tgsi_util_get_src_register_swizzle( diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index c8db4f608c..3cdabe45f9 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -35,7 +35,7 @@ #include "draw/draw_vertex.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_scan.h" #define I915_TEX_UNITS 8 diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 23cd909337..04507ab8ad 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -34,8 +34,8 @@ #include "pipe/p_shader_tokens.h" #include "util/u_string.h" -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/util/tgsi_dump.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_dump.h" #include "draw/draw_vertex.h" diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index dbb33f2695..e8521b385e 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -33,7 +33,7 @@ #include "pipe/p_winsys.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" #include "i915_context.h" #include "i915_reg.h" diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index 2cae7665f7..f00eb34f92 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -38,7 +38,7 @@ #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_scan.h" #include "brw_structs.h" #include "brw_winsys.h" diff --git a/src/gallium/drivers/i965simple/brw_sf.c b/src/gallium/drivers/i965simple/brw_sf.c index 96f8fb87a3..b82a2e143b 100644 --- a/src/gallium/drivers/i965simple/brw_sf.c +++ b/src/gallium/drivers/i965simple/brw_sf.c @@ -36,7 +36,7 @@ #include "brw_util.h" #include "brw_sf.h" #include "brw_state.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" static void compile_sf_prog( struct brw_context *brw, diff --git a/src/gallium/drivers/i965simple/brw_shader_info.c b/src/gallium/drivers/i965simple/brw_shader_info.c index fb3da92421..30f37a99d4 100644 --- a/src/gallium/drivers/i965simple/brw_shader_info.c +++ b/src/gallium/drivers/i965simple/brw_shader_info.c @@ -3,7 +3,7 @@ #include "brw_state.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" /** diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index caeeba4630..27ca32843d 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -34,8 +34,8 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_dump.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_parse.h" #include "brw_context.h" #include "brw_defines.h" diff --git a/src/gallium/drivers/i965simple/brw_vs_emit.c b/src/gallium/drivers/i965simple/brw_vs_emit.c index 81423e2d7d..34dbc0624d 100644 --- a/src/gallium/drivers/i965simple/brw_vs_emit.c +++ b/src/gallium/drivers/i965simple/brw_vs_emit.c @@ -33,7 +33,7 @@ #include "brw_vs.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" struct brw_prog_info { unsigned num_temps; diff --git a/src/gallium/drivers/i965simple/brw_wm_decl.c b/src/gallium/drivers/i965simple/brw_wm_decl.c index bf1b4d961a..e6f1a44817 100644 --- a/src/gallium/drivers/i965simple/brw_wm_decl.c +++ b/src/gallium/drivers/i965simple/brw_wm_decl.c @@ -4,7 +4,7 @@ #include "brw_wm.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" static struct brw_reg alloc_tmp(struct brw_wm_compile *c) { diff --git a/src/gallium/drivers/i965simple/brw_wm_glsl.c b/src/gallium/drivers/i965simple/brw_wm_glsl.c index 5c90583824..6a4a5aef09 100644 --- a/src/gallium/drivers/i965simple/brw_wm_glsl.c +++ b/src/gallium/drivers/i965simple/brw_wm_glsl.c @@ -4,7 +4,7 @@ #include "brw_wm.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index 0b199a2193..cc171bbc39 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -36,8 +36,8 @@ #include "pipe/p_defines.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_parse.h" +#include "tgsi/tgsi_exec.h" +#include "tgsi/tgsi_parse.h" struct sp_exec_fragment_shader { struct sp_fragment_shader base; diff --git a/src/gallium/drivers/softpipe/sp_fs_llvm.c b/src/gallium/drivers/softpipe/sp_fs_llvm.c index 6e1d9280bb..20226da78c 100644 --- a/src/gallium/drivers/softpipe/sp_fs_llvm.c +++ b/src/gallium/drivers/softpipe/sp_fs_llvm.c @@ -38,7 +38,7 @@ #include "pipe/p_defines.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "tgsi/exec/tgsi_sse2.h" +#include "tgsi/tgsi_sse2.h" #if 0 diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 69f7f960aa..8b7da7c747 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -36,8 +36,8 @@ #include "pipe/p_defines.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/exec/tgsi_sse2.h" +#include "tgsi/tgsi_exec.h" +#include "tgsi/tgsi_sse2.h" #ifdef PIPE_ARCH_X86 diff --git a/src/gallium/drivers/softpipe/sp_headers.h b/src/gallium/drivers/softpipe/sp_headers.h index 3d9ede69bb..ae2ee210fc 100644 --- a/src/gallium/drivers/softpipe/sp_headers.h +++ b/src/gallium/drivers/softpipe/sp_headers.h @@ -32,7 +32,7 @@ #define SP_HEADERS_H #include "pipe/p_state.h" -#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/tgsi_exec.h" #define PRIM_POINT 1 #define PRIM_LINE 2 diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 701e02b295..476ef3dc8f 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -32,7 +32,7 @@ #define SP_STATE_H #include "pipe/p_state.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_scan.h" #define SP_NEW_VIEWPORT 0x1 diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 901c8f83e7..76fe6bfef9 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -35,8 +35,8 @@ #include "pipe/p_winsys.h" #include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" -#include "tgsi/util/tgsi_dump.h" -#include "tgsi/util/tgsi_scan.h" +#include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_scan.h" void * diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index be0b57d9fa..63b3b91110 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -40,7 +40,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" -#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/tgsi_exec.h" /* diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 8d8b762ea5..284ecb827d 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -47,8 +47,8 @@ #include "cso_cache/cso_context.h" #include "util/u_draw_quad.h" #include "util/p_tile.h" -#include "tgsi/util/tgsi_text.h" -#include "tgsi/util/tgsi_dump.h" +#include "tgsi/tgsi_text.h" +#include "tgsi/tgsi_dump.h" #include "st_device.h" #include "st_sample.h" -- cgit v1.2.3 From 28454a512a9b1c1e9f70a04b43c34f239abd6ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 28 Jul 2008 22:42:18 +0900 Subject: util: Don't define replacement math functions for CE. It appears to be working without this before, and it is probably necessary. --- src/gallium/include/pipe/p_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 892bd4bf8a..eec413842f 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -34,7 +34,7 @@ #include "p_format.h" #include "p_pointer.h" -#if defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) +#if defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) __inline double ceil(double val) { double ceil_val; -- cgit v1.2.3 From 76164bf7a20ef6dabc3204a766f604becfba9997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 30 Jul 2008 00:44:56 +0900 Subject: tgsi: Insert newlines after the statements, instead of before. Prevents shader dumps from getting concatenated with the next debug message. --- src/gallium/auxiliary/tgsi/tgsi_dump.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index d2e6375212..290d78bb14 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -332,7 +332,7 @@ void tgsi_dump_declaration( const struct tgsi_full_declaration *decl ) { - TXT( "\nDCL " ); + TXT( "DCL " ); _dump_register( decl->Declaration.File, @@ -354,6 +354,8 @@ tgsi_dump_declaration( TXT( ", " ); ENM( decl->Declaration.Interpolate, interpolate_names ); + + EOL(); } static boolean @@ -407,7 +409,6 @@ tgsi_dump_instruction( uint i; boolean first_reg = TRUE; - EOL(); UID( instno ); CHR( ':' ); ENM( inst->Instruction.Opcode, opcode_names ); @@ -534,6 +535,8 @@ tgsi_dump_instruction( UID( inst->InstructionExtLabel.Label ); break; } + + EOL(); } static boolean @@ -551,11 +554,11 @@ static boolean prolog( struct tgsi_iterate_context *ctx ) { - EOL(); ENM( ctx->processor.Processor, processor_type_names ); UID( ctx->version.MajorVersion ); CHR( '.' ); UID( ctx->version.MinorVersion ); + EOL(); return TRUE; } -- cgit v1.2.3 From 4a8b908a46375ea2543a81bdd8d5b313d807f140 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Sat, 2 Aug 2008 19:37:16 +0200 Subject: softpipe: support PIPE_FORMAT_R16_SNORM. --- src/gallium/auxiliary/util/p_tile.c | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 1bf0d72733..2b6db43bee 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -441,6 +441,46 @@ a8_get_tile_rgba(ubyte *src, } } +/*** PIPE_FORMAT_R16_SNORM ***/ + +static void +r16_get_tile_rgba(short *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src++, pRow += 4) { + pRow[0] = SHORT_TO_FLOAT(src[0]); + pRow[1] = + pRow[2] = 0.0; + pRow[3] = 1.0; + } + p += dst_stride; + } +} + + +static void +r16_put_tile_rgba(short *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, dst++, pRow += 4) { + UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); + } + p += src_stride; + } +} + /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ @@ -742,6 +782,9 @@ pipe_tile_raw_to_rgba(enum pipe_format format, case PIPE_FORMAT_A8L8_UNORM: a8_l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); break; + case PIPE_FORMAT_R16_SNORM: + r16_get_tile_rgba((short *) src, w, h, dst, dst_stride); + break; case PIPE_FORMAT_R16G16B16A16_SNORM: r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride); break; @@ -847,6 +890,9 @@ pipe_put_tile_rgba(struct pipe_surface *ps, case PIPE_FORMAT_A8L8_UNORM: /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ break; + case PIPE_FORMAT_R16_SNORM: + /*r16_put_tile_rgba((short *) packed, w, h, p, src_stride);*/ + break; case PIPE_FORMAT_R16G16B16A16_SNORM: r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride); break; -- cgit v1.2.3 From 2783f3bfabd6e316f7e221e950499c3631c041ce Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 4 Aug 2008 12:18:09 +0200 Subject: tgsi: Put a newline after IMM. --- src/gallium/auxiliary/tgsi/tgsi_dump.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index 290d78bb14..0eedb1c91e 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -264,16 +264,6 @@ static const char *modulate_names[TGSI_MODULATE_COUNT] = "_D8" }; -static void -_dump_register_prefix( - uint file, - uint first, - uint last ) -{ - - -} - static void _dump_register( uint file, @@ -354,7 +344,7 @@ tgsi_dump_declaration( TXT( ", " ); ENM( decl->Declaration.Interpolate, interpolate_names ); - + EOL(); } @@ -373,7 +363,7 @@ tgsi_dump_immediate( { uint i; - TXT( "\nIMM " ); + TXT( "IMM " ); ENM( imm->Immediate.DataType, immediate_type_names ); TXT( " { " ); @@ -390,6 +380,8 @@ tgsi_dump_immediate( TXT( ", " ); } TXT( " }" ); + + EOL(); } static boolean @@ -535,7 +527,7 @@ tgsi_dump_instruction( UID( inst->InstructionExtLabel.Label ); break; } - + EOL(); } -- cgit v1.2.3 From ea0007cc4ca077c7e3951c4fda122bd242728d70 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 Aug 2008 17:14:22 -0600 Subject: softpipe: add texture border color code --- src/gallium/drivers/softpipe/sp_tex_sample.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 63b3b91110..ed150527e2 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -601,15 +601,25 @@ get_texel(struct tgsi_sampler *sampler, unsigned face, unsigned level, int x, int y, int z, float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) { - const int tx = x % TILE_SIZE; - const int ty = y % TILE_SIZE; - const struct softpipe_cached_tile *tile - = sp_get_cached_tile_tex(sampler->pipe, sampler->cache, - x, y, z, face, level); - rgba[0][j] = tile->data.color[ty][tx][0]; - rgba[1][j] = tile->data.color[ty][tx][1]; - rgba[2][j] = tile->data.color[ty][tx][2]; - rgba[3][j] = tile->data.color[ty][tx][3]; + if (x < 0 || x >= sampler->texture->width[level] || + y < 0 || y >= sampler->texture->height[level] || + z < 0 || z >= sampler->texture->depth[level]) { + rgba[0][j] = sampler->state->border_color[0]; + rgba[1][j] = sampler->state->border_color[1]; + rgba[2][j] = sampler->state->border_color[2]; + rgba[3][j] = sampler->state->border_color[3]; + } + else { + const int tx = x % TILE_SIZE; + const int ty = y % TILE_SIZE; + const struct softpipe_cached_tile *tile + = sp_get_cached_tile_tex(sampler->pipe, sampler->cache, + x, y, z, face, level); + rgba[0][j] = tile->data.color[ty][tx][0]; + rgba[1][j] = tile->data.color[ty][tx][1]; + rgba[2][j] = tile->data.color[ty][tx][2]; + rgba[3][j] = tile->data.color[ty][tx][3]; + } } -- cgit v1.2.3 From be66a8f43172327e3cdde27281e40377cacbb121 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 Aug 2008 17:22:29 -0600 Subject: gallium: added PIPE_CAP_TEXTURE_MIRROR_CLAMP, PIPE_CAP_TEXTURE_MIRROR_REPEAT Check for these caps in state tracker and enable corresponding GL extensions if supported. --- src/gallium/drivers/softpipe/sp_screen.c | 4 ++++ src/gallium/include/pipe/p_defines.h | 3 +++ 2 files changed, 7 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 3f9d4b0ed3..ceb5616b5d 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -72,6 +72,10 @@ softpipe_get_param(struct pipe_screen *screen, int param) return PIPE_MAX_COLOR_BUFS; case PIPE_CAP_OCCLUSION_QUERY: return 1; + case PIPE_CAP_TEXTURE_MIRROR_CLAMP: + return 1; + case PIPE_CAP_TEXTURE_MIRROR_REPEAT: + return 1; case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index b1d100ef53..bdc6d4ef46 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -281,6 +281,9 @@ enum pipe_texture_target { #define PIPE_CAP_GUARD_BAND_TOP 21 /*< float */ #define PIPE_CAP_GUARD_BAND_RIGHT 22 /*< float */ #define PIPE_CAP_GUARD_BAND_BOTTOM 23 /*< float */ +#define PIPE_CAP_TEXTURE_MIRROR_CLAMP 24 +#define PIPE_CAP_TEXTURE_MIRROR_REPEAT 25 + #ifdef __cplusplus -- cgit v1.2.3 From a56ccb90c6a374c86158ac2323f844a4003560fa Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 Aug 2008 19:15:10 -0600 Subject: gallium: fix clipping/stride bugs in pipe_get_tile_raw(), pipe_put_tile_raw() We need to compute the default dst_stride and src_stride _before_ clipping. After clipping, the width value may have changed. This fixes visible tile glitches in some demos like progs/glsl/texdemo.c --- src/gallium/auxiliary/util/p_tile.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 2b6db43bee..d65e603785 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -51,12 +51,12 @@ pipe_get_tile_raw(struct pipe_surface *ps, { const void *src; - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - if (dst_stride == 0) dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + src = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ); assert(src); if(!src) @@ -79,12 +79,12 @@ pipe_put_tile_raw(struct pipe_surface *ps, { void *dst; - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - if (src_stride == 0) src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + dst = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE); assert(dst); if(!dst) -- cgit v1.2.3 From d50d7a54de89e602a9951264878dfe06924e1adb Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 7 Aug 2008 16:22:34 +0200 Subject: softpipe: Silence compiler warnings on Windows. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index ed150527e2..8e39269533 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -601,9 +601,9 @@ get_texel(struct tgsi_sampler *sampler, unsigned face, unsigned level, int x, int y, int z, float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) { - if (x < 0 || x >= sampler->texture->width[level] || - y < 0 || y >= sampler->texture->height[level] || - z < 0 || z >= sampler->texture->depth[level]) { + if (x < 0 || x >= (int) sampler->texture->width[level] || + y < 0 || y >= (int) sampler->texture->height[level] || + z < 0 || z >= (int) sampler->texture->depth[level]) { rgba[0][j] = sampler->state->border_color[0]; rgba[1][j] = sampler->state->border_color[1]; rgba[2][j] = sampler->state->border_color[2]; -- cgit v1.2.3 From 72a5e479789febb552ec783a1cba0ed628dfa427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 6 Aug 2008 14:48:11 +0100 Subject: gallium: New function to dump surfaces. --- src/gallium/auxiliary/util/p_debug.c | 43 +++++++++++++++++++++++++++++++----- src/gallium/include/pipe/p_debug.h | 8 +++++-- 2 files changed, 44 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index cdc7e66361..a3db13f96d 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -50,12 +50,12 @@ #endif - - #include "pipe/p_compiler.h" #include "pipe/p_util.h" #include "pipe/p_debug.h" #include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" #include "util/u_string.h" @@ -509,7 +509,7 @@ char *pf_sprint_name( char *str, enum pipe_format format ) void debug_dump_image(const char *prefix, unsigned format, unsigned cpp, unsigned width, unsigned height, - unsigned pitch, + unsigned stride, const void *data) { #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY @@ -530,7 +530,7 @@ void debug_dump_image(const char *prefix, for(i = 0; i < sizeof(filename); ++i) wfilename[i] = (WCHAR)filename[i]; - pMap = (unsigned char *)EngMapFile(wfilename, sizeof(header) + cpp*width*height, &iFile); + pMap = (unsigned char *)EngMapFile(wfilename, sizeof(header) + height*width*cpp, &iFile); if(!pMap) return; @@ -542,11 +542,44 @@ void debug_dump_image(const char *prefix, pMap += sizeof(header); for(i = 0; i < height; ++i) { - memcpy(pMap, (unsigned char *)data + cpp*pitch*i, cpp*width); + memcpy(pMap, (unsigned char *)data + stride*i, cpp*width); pMap += cpp*width; } EngUnmapFile(iFile); #endif } + +void debug_dump_surface(const char *prefix, + struct pipe_surface *surface) +{ + unsigned surface_usage; + void *data; + + if (!surface) + goto error1; + + /* XXX: force mappable surface */ + surface_usage = surface->usage; + surface->usage |= PIPE_BUFFER_USAGE_CPU_READ; + + data = pipe_surface_map(surface, + PIPE_BUFFER_USAGE_CPU_READ); + if(!data) + goto error2; + + debug_dump_image(prefix, + surface->format, + surface->block.size, + surface->nblocksx, + surface->nblocksy, + surface->stride, + data); + + pipe_surface_unmap(surface); +error2: + surface->usage = surface_usage; +error1: + ; +} #endif diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index a5816c3cbb..6478ae2f08 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -332,13 +332,17 @@ debug_profile_stop(void); #ifdef DEBUG +struct pipe_surface; void debug_dump_image(const char *prefix, unsigned format, unsigned cpp, unsigned width, unsigned height, - unsigned pitch, + unsigned stride, const void *data); +void debug_dump_surface(const char *prefix, + struct pipe_surface *surface); #else -#define debug_dump_image(prefix, format, cpp, width, height, pitch, data) ((void)0) +#define debug_dump_image(prefix, format, cpp, width, height, stride, data) ((void)0) +#define debug_dump_surface(prefix, surface) ((void)0) #endif -- cgit v1.2.3 From 1ee500ac73fa657f02321c46cf5d9a4bfdea54de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 6 Aug 2008 14:51:15 +0100 Subject: pipebuffer: Add an extra assertion to ensure buffers do not jump between lists. --- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index f599bee07e..ce41418a0f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -142,12 +142,13 @@ _fenced_buffer_destroy(struct fenced_buffer *fenced_buf) static INLINE void -_fenced_buffer_remove(struct fenced_buffer *fenced_buf) +_fenced_buffer_remove(struct fenced_buffer_list *fenced_list, + struct fenced_buffer *fenced_buf) { - struct fenced_buffer_list *fenced_list = fenced_buf->list; struct pipe_winsys *winsys = fenced_list->winsys; assert(fenced_buf->fence); + assert(fenced_buf->list == fenced_list); winsys->fence_reference(winsys, &fenced_buf->fence, NULL); fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE; @@ -184,7 +185,8 @@ _fenced_buffer_finish(struct fenced_buffer *fenced_buf) return PIPE_ERROR; } /* Remove from the fenced list */ - _fenced_buffer_remove(fenced_buf); /* TODO: remove consequents */ + /* TODO: remove consequents */ + _fenced_buffer_remove(fenced_list, fenced_buf); } fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE; @@ -223,7 +225,7 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0); } - _fenced_buffer_remove(fenced_buf); + _fenced_buffer_remove(fenced_list, fenced_buf); curr = next; next = curr->next; @@ -248,7 +250,7 @@ fenced_buffer_destroy(struct pb_buffer *buf) do { fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0); - _fenced_buffer_remove(fenced_buf); + _fenced_buffer_remove(fenced_list, fenced_buf); curr = prev; prev = curr->prev; } while (curr != &fenced_list->delayed); @@ -395,7 +397,7 @@ buffer_fence(struct pb_buffer *buf, _glthread_LOCK_MUTEX(fenced_list->mutex); if (fenced_buf->fence) - _fenced_buffer_remove(fenced_buf); + _fenced_buffer_remove(fenced_list, fenced_buf); if (fence) { winsys->fence_reference(winsys, &fenced_buf->fence, fence); fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE; -- cgit v1.2.3 From 35355f7610b69dcd2fdba451db4554478fe0acaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 6 Aug 2008 21:36:25 +0100 Subject: trace: New pipe driver to trace incoming calls. Only pipe_screen calls traced, and only linux supported, for now. --- src/gallium/drivers/trace/README | 37 ++++ src/gallium/drivers/trace/SConscript | 15 ++ src/gallium/drivers/trace/tr_context.c | 41 ++++ src/gallium/drivers/trace/tr_context.h | 58 +++++ src/gallium/drivers/trace/tr_dump.c | 329 ++++++++++++++++++++++++++++ src/gallium/drivers/trace/tr_dump.h | 102 +++++++++ src/gallium/drivers/trace/tr_screen.c | 385 +++++++++++++++++++++++++++++++++ src/gallium/drivers/trace/tr_screen.h | 65 ++++++ src/gallium/drivers/trace/tr_state.c | 72 ++++++ src/gallium/drivers/trace/tr_state.h | 44 ++++ src/gallium/drivers/trace/tr_stream.c | 100 +++++++++ src/gallium/drivers/trace/tr_stream.h | 52 +++++ 12 files changed, 1300 insertions(+) create mode 100644 src/gallium/drivers/trace/README create mode 100644 src/gallium/drivers/trace/SConscript create mode 100644 src/gallium/drivers/trace/tr_context.c create mode 100644 src/gallium/drivers/trace/tr_context.h create mode 100644 src/gallium/drivers/trace/tr_dump.c create mode 100644 src/gallium/drivers/trace/tr_dump.h create mode 100644 src/gallium/drivers/trace/tr_screen.c create mode 100644 src/gallium/drivers/trace/tr_screen.h create mode 100644 src/gallium/drivers/trace/tr_state.c create mode 100644 src/gallium/drivers/trace/tr_state.h create mode 100644 src/gallium/drivers/trace/tr_stream.c create mode 100644 src/gallium/drivers/trace/tr_stream.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README new file mode 100644 index 0000000000..81da610bd5 --- /dev/null +++ b/src/gallium/drivers/trace/README @@ -0,0 +1,37 @@ +This directory contains a Gallium3D pipe driver which traces all incoming calls. + +To build, invoke scons on the top dir as + + scons statetrackers=mesa drivers=softpipe,i915simple,trace winsys=xlib + +To use do + + ln -s libGL.so build/linux-x86-debug/gallium/winsys/xlib/libGL.so.1 + export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/gallium/winsys/xlib + export GALLIUM_TRACE=y + +ensure the right libGL.so is being picked by doing + + ldd `which glxingo` + +and then try running + + glxinfo + +which should create a gallium.*.trace file, which is an XML file. You can view +copying trace.xsl and trace.css to the same directory, and opening with a +XSLT capable browser like Firefox or Internet Explorer. It often happens that +the trace file was not properly terminated, and a + + + +closing tag is missing from the file end. Add it before try to open or +further transform it by doing + + echo '' >> gallium.??.trace + + +This is still work in progress. + +-- +Jose Fonseca diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript new file mode 100644 index 0000000000..30225b5a54 --- /dev/null +++ b/src/gallium/drivers/trace/SConscript @@ -0,0 +1,15 @@ +Import('*') + +env = env.Clone() + +trace = env.ConvenienceLibrary( + target = 'trace', + source = [ + 'tr_context.c', + 'tr_dump.c', + 'tr_screen.c', + 'tr_state.c', + 'tr_stream.c', + ]) + +Export('trace') \ No newline at end of file diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c new file mode 100644 index 0000000000..67a67b3da6 --- /dev/null +++ b/src/gallium/drivers/trace/tr_context.c @@ -0,0 +1,41 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" + +#include "tr_stream.h" +#include "tr_dump.h" +#include "tr_state.h" +#include "tr_context.h" + + +struct pipe_context * +trace_context_create(struct pipe_context *pipe) +{ + /* TODO */ + return pipe; +} diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h new file mode 100644 index 0000000000..75b8d11a7a --- /dev/null +++ b/src/gallium/drivers/trace/tr_context.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TR_CONTEXT_H_ +#define TR_CONTEXT_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_context.h" + + +struct trace_context +{ + struct pipe_context base; + + /* TODO */ +}; + + +static INLINE struct trace_context * +trace_context(struct pipe_context *context) +{ + assert(context); + return (struct trace_context *)context; +} + + + +struct pipe_context * +trace_context_create(struct pipe_context *context); + + +#endif /* TR_CONTEXT_H_ */ diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c new file mode 100644 index 0000000000..30c0986363 --- /dev/null +++ b/src/gallium/drivers/trace/tr_dump.c @@ -0,0 +1,329 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * @file + * Trace dumping functions. + * + * For now we just use standard XML for dumping the trace calls, as this is + * simple to write, parse, and visually inspect, but the actual representation + * is abstracted out of this file, so that we can switch to a binary + * representation if/when it becomes justified. + * + * @author Jose Fonseca + */ + + +#include "pipe/p_compiler.h" +#include "util/u_string.h" + +#include "tr_stream.h" +#include "tr_dump.h" + + +static INLINE void +trace_dump_write(struct trace_stream *stream, const char *s) +{ + trace_stream_write(stream, s, strlen(s)); +} + + +static INLINE void +trace_dump_writef(struct trace_stream *stream, const char *format, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, format); + util_vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + trace_dump_write(stream, buf); +} + + +static INLINE void +trace_dump_escape(struct trace_stream *stream, const char *str) +{ + const unsigned char *p = (const unsigned char *)str; + unsigned char c; + while((c = *p++) != 0) { + if(c == '<') + trace_dump_write(stream, "<"); + else if(c == '>') + trace_dump_write(stream, ">"); + else if(c == '&') + trace_dump_write(stream, "&"); + else if(c == '\'') + trace_dump_write(stream, "'"); + else if(c == '\"') + trace_dump_write(stream, """); + else if(c >= 0x20 && c <= 0x7e) + trace_dump_writef(stream, "%c", c); + else + trace_dump_writef(stream, "&#%u;", c); + } +} + + +static INLINE void +trace_dump_indent(struct trace_stream *stream, unsigned level) +{ + unsigned i; + for(i = 0; i < level; ++i) + trace_dump_write(stream, "\t"); +} + + +static INLINE void +trace_dump_newline(struct trace_stream *stream) +{ + trace_dump_write(stream, "\n"); +} + + +static INLINE void +trace_dump_tag(struct trace_stream *stream, + const char *name) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, "/>"); +} + + +static INLINE void +trace_dump_tag_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, ">"); +} + +static INLINE void +trace_dump_tag_begin1(struct trace_stream *stream, + const char *name, + const char *attr1, const char *value1) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, " "); + trace_dump_write(stream, attr1); + trace_dump_write(stream, "='"); + trace_dump_escape(stream, value1); + trace_dump_write(stream, "'>"); +} + + +static INLINE void +trace_dump_tag_begin2(struct trace_stream *stream, + const char *name, + const char *attr1, const char *value1, + const char *attr2, const char *value2) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, " "); + trace_dump_write(stream, attr1); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value1); + trace_dump_write(stream, "\' "); + trace_dump_write(stream, attr2); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value2); + trace_dump_write(stream, "\'>"); +} + + +static INLINE void +trace_dump_tag_begin3(struct trace_stream *stream, + const char *name, + const char *attr1, const char *value1, + const char *attr2, const char *value2, + const char *attr3, const char *value3) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, " "); + trace_dump_write(stream, attr1); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value1); + trace_dump_write(stream, "\' "); + trace_dump_write(stream, attr2); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value2); + trace_dump_write(stream, "\' "); + trace_dump_write(stream, attr3); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value3); + trace_dump_write(stream, "\'>"); +} + + +static INLINE void +trace_dump_tag_end(struct trace_stream *stream, + const char *name) +{ + trace_dump_write(stream, ""); +} + + +void trace_dump_trace_begin(struct trace_stream *stream, + unsigned version) +{ + trace_dump_write(stream, "\n"); + trace_dump_write(stream, "\n"); + trace_dump_writef(stream, "\n", version); +} + + +void trace_dump_trace_end(struct trace_stream *stream) +{ + trace_dump_write(stream, "\n"); +} + +void trace_dump_call_begin(struct trace_stream *stream, + const char *klass, const char *method) +{ + trace_dump_indent(stream, 1); + trace_dump_tag_begin2(stream, "call", "class", klass, "method", method); + trace_dump_newline(stream); +} + +void trace_dump_call_end(struct trace_stream *stream) +{ + trace_dump_indent(stream, 1); + trace_dump_tag_end(stream, "call"); + trace_dump_newline(stream); +} + +void trace_dump_arg_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_indent(stream, 2); + trace_dump_tag_begin1(stream, "arg", "name", name); +} + +void trace_dump_arg_end(struct trace_stream *stream) +{ + trace_dump_tag_end(stream, "arg"); + trace_dump_newline(stream); +} + +void trace_dump_ret_begin(struct trace_stream *stream) +{ + trace_dump_indent(stream, 2); + trace_dump_tag_begin(stream, "ret"); +} + +void trace_dump_ret_end(struct trace_stream *stream) +{ + trace_dump_tag_end(stream, "ret"); + trace_dump_newline(stream); +} + +void trace_dump_bool(struct trace_stream *stream, + int value) +{ + trace_dump_writef(stream, "%c", value ? '1' : '0'); +} + +void trace_dump_int(struct trace_stream *stream, + long int value) +{ + trace_dump_writef(stream, "%li", value); +} + +void trace_dump_uint(struct trace_stream *stream, + long unsigned value) +{ + trace_dump_writef(stream, "%lu", value); +} + +void trace_dump_float(struct trace_stream *stream, + double value) +{ + trace_dump_writef(stream, "%g", value); +} + +void trace_dump_string(struct trace_stream *stream, + const char *str) +{ + trace_dump_write(stream, ""); + trace_dump_escape(stream, str); + trace_dump_write(stream, ""); +} + +void trace_dump_array_begin(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_array_end(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_elem_begin(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_elem_end(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_struct_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_writef(stream, "", name); +} + +void trace_dump_struct_end(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_member_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_writef(stream, "", name); +} + +void trace_dump_member_end(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_ptr(struct trace_stream *stream, + const void *value) +{ + trace_dump_writef(stream, "%p", value); +} diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h new file mode 100644 index 0000000000..f086486591 --- /dev/null +++ b/src/gallium/drivers/trace/tr_dump.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation streams (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Trace data dumping primitives. + */ + +#ifndef TR_DUMP_H +#define TR_DUMP_H + + +struct trace_stream; + + +void trace_dump_trace_begin(struct trace_stream *stream, unsigned version); +void trace_dump_trace_end(struct trace_stream *stream); +void trace_dump_call_begin(struct trace_stream *stream, const char *klass, const char *method); +void trace_dump_call_end(struct trace_stream *stream); +void trace_dump_arg_begin(struct trace_stream *stream, const char *name); +void trace_dump_arg_end(struct trace_stream *stream); +void trace_dump_ret_begin(struct trace_stream *stream); +void trace_dump_ret_end(struct trace_stream *stream); +void trace_dump_bool(struct trace_stream *stream, int value); +void trace_dump_int(struct trace_stream *stream, long int value); +void trace_dump_uint(struct trace_stream *stream, long unsigned value); +void trace_dump_float(struct trace_stream *stream, double value); +void trace_dump_string(struct trace_stream *stream, const char *str); +void trace_dump_array_begin(struct trace_stream *stream); +void trace_dump_array_end(struct trace_stream *stream); +void trace_dump_elem_begin(struct trace_stream *stream); +void trace_dump_elem_end(struct trace_stream *stream); +void trace_dump_struct_begin(struct trace_stream *stream, const char *name); +void trace_dump_struct_end(struct trace_stream *stream); +void trace_dump_member_begin(struct trace_stream *stream, const char *name); +void trace_dump_member_end(struct trace_stream *stream); +void trace_dump_ptr(struct trace_stream *stream, const void *value); + + +/* + * Code saving macros. + */ + +#define trace_dump_arg(_stream, _type, _arg) \ + do { \ + trace_dump_arg_begin(_stream, #_arg); \ + trace_dump_##_type(_stream, _arg); \ + trace_dump_arg_end(_stream); \ + } while(0) + +#define trace_dump_ret(_stream, _type, _arg) \ + do { \ + trace_dump_ret_begin(_stream); \ + trace_dump_##_type(_stream, _arg); \ + trace_dump_ret_end(_stream); \ + } while(0) + +#define trace_dump_array(_stream, _type, _obj, _size) \ + do { \ + unsigned long idx; \ + trace_dump_array_begin(_stream); \ + for(idx = 0; idx < _size; ++idx) { \ + trace_dump_elem_begin(_stream); \ + trace_dump_##_type(_stream, _obj[idx]); \ + trace_dump_elem_end(_stream); \ + } \ + trace_dump_array_end(_stream); \ + } while(0) + +#define trace_dump_member(_stream, _type, _obj, _member) \ + do { \ + trace_dump_member_begin(_stream, #_member); \ + trace_dump_##_type(_stream, _obj->_member); \ + trace_dump_member_end(_stream); \ + } while(0) + + +#endif /* TR_DUMP_H */ diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c new file mode 100644 index 0000000000..20a2026e1d --- /dev/null +++ b/src/gallium/drivers/trace/tr_screen.c @@ -0,0 +1,385 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" + +#include "tr_stream.h" +#include "tr_dump.h" +#include "tr_state.h" +#include "tr_screen.h" + + +static const char * +trace_screen_get_name(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + const char *result; + + trace_dump_call_begin(stream, "pipe_screen", "get_name"); + + trace_dump_arg(stream, ptr, screen); + + result = screen->get_name(screen); + + trace_dump_ret(stream, string, result); + + trace_dump_call_end(stream); + + return result; +} + + +static const char * +trace_screen_get_vendor(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + const char *result; + + trace_dump_call_begin(stream, "pipe_screen", "get_vendor"); + + trace_dump_arg(stream, ptr, screen); + + result = screen->get_vendor(screen); + + trace_dump_ret(stream, string, result); + + trace_dump_call_end(stream); + + return result; +} + + +static int +trace_screen_get_param(struct pipe_screen *_screen, + int param) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + int result; + + trace_dump_call_begin(stream, "pipe_screen", "get_param"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, int, param); + + result = screen->get_param(screen, param); + + trace_dump_ret(stream, int, result); + + trace_dump_call_end(stream); + + return result; +} + + +static float +trace_screen_get_paramf(struct pipe_screen *_screen, + int param) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + float result; + + trace_dump_call_begin(stream, "pipe_screen", "get_paramf"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, int, param); + + result = screen->get_paramf(screen, param); + + trace_dump_ret(stream, float, result); + + trace_dump_call_end(stream); + + return result; +} + + +static boolean +trace_screen_is_format_supported(struct pipe_screen *_screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + boolean result; + + trace_dump_call_begin(stream, "pipe_screen", "is_format_supported"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, int, format); + trace_dump_arg(stream, int, target); + trace_dump_arg(stream, uint, tex_usage); + trace_dump_arg(stream, uint, geom_flags); + + result = screen->is_format_supported(screen, format, target, tex_usage, geom_flags); + + trace_dump_ret(stream, bool, result); + + trace_dump_call_end(stream); + + return result; +} + + +static struct pipe_texture * +trace_screen_texture_create(struct pipe_screen *_screen, + const struct pipe_texture *templat) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_texture *result; + + trace_dump_call_begin(stream, "pipe_screen", "texture_create"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, template, templat); + + result = screen->texture_create(screen, templat); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static struct pipe_texture * +trace_screen_texture_blanket(struct pipe_screen *_screen, + const struct pipe_texture *templat, + const unsigned *ppitch, + struct pipe_buffer *buffer) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + unsigned pitch = *ppitch; + struct pipe_texture *result; + + trace_dump_call_begin(stream, "pipe_screen", "texture_blanket"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, template, templat); + trace_dump_arg(stream, uint, pitch); + trace_dump_arg(stream, ptr, buffer); + + result = screen->texture_blanket(screen, templat, ppitch, buffer); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_screen_texture_release(struct pipe_screen *_screen, + struct pipe_texture **ptexture) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_texture *texture = *ptexture; + + trace_dump_call_begin(stream, "pipe_screen", "texture_release"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, texture); + + screen->texture_release(screen, ptexture); + + trace_dump_call_end(stream); +} + +static struct pipe_surface * +trace_screen_get_tex_surface(struct pipe_screen *_screen, + struct pipe_texture *texture, + unsigned face, unsigned level, + unsigned zslice, + unsigned usage) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_surface *result; + + trace_dump_call_begin(stream, "pipe_screen", "get_tex_surface"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, texture); + trace_dump_arg(stream, uint, face); + trace_dump_arg(stream, uint, level); + trace_dump_arg(stream, uint, zslice); + trace_dump_arg(stream, uint, usage); + + result = screen->get_tex_surface(screen, texture, face, level, zslice, usage); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_screen_tex_surface_release(struct pipe_screen *_screen, + struct pipe_surface **psurface) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_surface *surface = *psurface; + + trace_dump_call_begin(stream, "pipe_screen", "tex_surface_release"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, surface); + + screen->tex_surface_release(screen, psurface); + + trace_dump_call_end(stream); +} + + +static void * +trace_screen_surface_map(struct pipe_screen *_screen, + struct pipe_surface *surface, + unsigned flags) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_surface *result; + + trace_dump_call_begin(stream, "pipe_screen", "surface_map"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, surface); + trace_dump_arg(stream, uint, flags); + + result = screen->surface_map(screen, surface, flags); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_screen_surface_unmap(struct pipe_screen *_screen, + struct pipe_surface *surface) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + + trace_dump_call_begin(stream, "pipe_screen", "surface_unmap"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, surface); + + screen->surface_unmap(screen, surface); + + trace_dump_call_end(stream); +} + + +static void +trace_screen_destroy(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + + trace_dump_call_begin(stream, "pipe_screen", "destroy"); + + trace_dump_arg(stream, ptr, screen); + + screen->destroy(screen); + + trace_dump_call_end(stream); + + trace_dump_trace_end(stream); + + trace_stream_close(tr_scr->stream); + + FREE(tr_scr); +} + + +struct pipe_screen * +trace_screen_create(struct pipe_screen *screen) +{ + struct trace_screen *tr_scr; + + if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) + return screen; + + tr_scr = CALLOC_STRUCT(trace_screen); + if(!tr_scr) + return NULL; + + tr_scr->base.winsys = screen->winsys; + tr_scr->base.destroy = trace_screen_destroy; + tr_scr->base.get_name = trace_screen_get_name; + tr_scr->base.get_vendor = trace_screen_get_vendor; + tr_scr->base.get_param = trace_screen_get_param; + tr_scr->base.get_paramf = trace_screen_get_paramf; + tr_scr->base.is_format_supported = trace_screen_is_format_supported; + tr_scr->base.texture_create = trace_screen_texture_create; + tr_scr->base.texture_blanket = trace_screen_texture_blanket; + tr_scr->base.texture_release = trace_screen_texture_release; + tr_scr->base.get_tex_surface = trace_screen_get_tex_surface; + tr_scr->base.tex_surface_release = trace_screen_tex_surface_release; + tr_scr->base.surface_map = trace_screen_surface_map; + tr_scr->base.surface_unmap = trace_screen_surface_unmap; + + tr_scr->screen = screen; + + tr_scr->stream = trace_stream_create("gallium", "trace"); + if(!tr_scr->stream) + return NULL; + + trace_dump_trace_begin(tr_scr->stream, 0); + + return &tr_scr->base; +} diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h new file mode 100644 index 0000000000..5d7d667f71 --- /dev/null +++ b/src/gallium/drivers/trace/tr_screen.h @@ -0,0 +1,65 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TR_SCREEN_H_ +#define TR_SCREEN_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_screen.h" + + +struct trace_stream; + + +struct trace_screen +{ + struct pipe_screen base; + + struct pipe_screen *screen; + + struct trace_stream *stream; + + unsigned event_no; +}; + + +static INLINE struct trace_screen * +trace_screen(struct pipe_screen *screen) +{ + assert(screen); + return (struct trace_screen *)screen; +} + + + +struct pipe_screen * +trace_screen_create(struct pipe_screen *screen); + + +#endif /* TR_SCREEN_H_ */ diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c new file mode 100644 index 0000000000..1e0e87f7fd --- /dev/null +++ b/src/gallium/drivers/trace/tr_state.c @@ -0,0 +1,72 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "tr_dump.h" +#include "tr_state.h" + + +void trace_dump_block(struct trace_stream *stream, + const struct pipe_format_block *block) +{ + trace_dump_struct_begin(stream, "pipe_format_block"); + trace_dump_member(stream, uint, block, size); + trace_dump_member(stream, uint, block, width); + trace_dump_member(stream, uint, block, height); + trace_dump_struct_end(stream); +} + + +void trace_dump_template(struct trace_stream *stream, + const struct pipe_texture *templat) +{ + trace_dump_struct_begin(stream, "pipe_texture"); + + trace_dump_member(stream, int, templat, target); + trace_dump_member(stream, int, templat, format); + + trace_dump_member_begin(stream, "width"); + trace_dump_array(stream, uint, templat->width, 1); + trace_dump_member_end(stream); + + trace_dump_member_begin(stream, "height"); + trace_dump_array(stream, uint, templat->height, 1); + trace_dump_member_end(stream); + + trace_dump_member_begin(stream, "block"); + trace_dump_block(stream, &templat->block); + trace_dump_member_end(stream); + + trace_dump_member(stream, uint, templat, last_level); + trace_dump_member(stream, uint, templat, tex_usage); + + trace_dump_struct_end(stream); +} + diff --git a/src/gallium/drivers/trace/tr_state.h b/src/gallium/drivers/trace/tr_state.h new file mode 100644 index 0000000000..e52524ee90 --- /dev/null +++ b/src/gallium/drivers/trace/tr_state.h @@ -0,0 +1,44 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation streams (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TR_STATE_H +#define TR_STATE_H + + +struct trace_stream; + +struct pipe_format_block; +struct pipe_texture; + +void trace_dump_block(struct trace_stream *stream, + const struct pipe_format_block *block); + +void trace_dump_template(struct trace_stream *stream, + const struct pipe_texture *templat); + + +#endif /* TR_STATE_H */ diff --git a/src/gallium/drivers/trace/tr_stream.c b/src/gallium/drivers/trace/tr_stream.c new file mode 100644 index 0000000000..14cc257e15 --- /dev/null +++ b/src/gallium/drivers/trace/tr_stream.c @@ -0,0 +1,100 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_config.h" + +#if defined(PIPE_OS_LINUX) +#include +#else +#error Unsupported platform +#endif + +#include "pipe/p_util.h" + +#include "tr_stream.h" + + +struct trace_stream +{ +#if defined(PIPE_OS_LINUX) + FILE *file; +#endif +}; + + +struct trace_stream * +trace_stream_create(const char *name, const char *ext) +{ + struct trace_stream *stream; + static unsigned file_no = 0; + char filename[1024]; + + stream = CALLOC_STRUCT(trace_stream); + if(!stream) + goto error1; + + snprintf(filename, sizeof(filename), "%s.%u.%s", name, file_no, ext); + +#if defined(PIPE_OS_LINUX) + stream->file = fopen(filename, "w"); + if(!stream->file) + goto error2; +#endif + + return stream; + +error2: + FREE(stream); +error1: + return NULL; +} + + +boolean +trace_stream_write(struct trace_stream *stream, const void *data, size_t size) +{ + if(!stream) + return FALSE; + +#if defined(PIPE_OS_LINUX) + return fwrite(data, size, 1, stream->file) == size ? TRUE : FALSE; +#endif +} + + +void +trace_stream_close(struct trace_stream *stream) +{ + if(!stream) + return; + +#if defined(PIPE_OS_LINUX) + fclose(stream->file); +#endif + + FREE(stream); +} diff --git a/src/gallium/drivers/trace/tr_stream.h b/src/gallium/drivers/trace/tr_stream.h new file mode 100644 index 0000000000..d50fed2691 --- /dev/null +++ b/src/gallium/drivers/trace/tr_stream.h @@ -0,0 +1,52 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation streams (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Cross-platform sequential access stream abstraction. + */ + +#ifndef TR_STREAM_H +#define TR_STREAM_H + + +#include "pipe/p_compiler.h" + +struct trace_stream; + + +struct trace_stream * +trace_stream_create(const char *name, const char *ext); + +boolean +trace_stream_write(struct trace_stream *stream, const void *data, size_t size); + +void +trace_stream_close(struct trace_stream *stream); + + +#endif /* TR_STREAM_H */ -- cgit v1.2.3 From 18fb8f148679ddddc5a781014d36a51afc304727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 6 Aug 2008 21:37:00 +0100 Subject: xlib: Integrate with the trace pipe driver. --- src/gallium/winsys/xlib/SConscript | 54 ++++++++++++++++++++----------------- src/gallium/winsys/xlib/xm_winsys.c | 13 +++++++++ 2 files changed, 42 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 14a85ae0f2..8650f595a7 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -9,31 +9,35 @@ if env['platform'] == 'linux' \ and 'i965simple' in env['drivers'] \ and not env['dri']: - env = env.Clone() + env = env.Clone() - env.Append(CPPPATH = [ - '#/src/mesa', - '#/src/mesa/main', - ]) + env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', + ]) - sources = [ - 'glxapi.c', - 'fakeglx.c', - 'xfonts.c', - 'xm_api.c', - 'xm_winsys.c', - 'xm_winsys_aub.c', - 'brw_aub.c', - ] - - drivers = [ - softpipe, - i965simple - ] + sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'xm_winsys.c', + 'xm_winsys_aub.c', + 'brw_aub.c', + ] + + drivers = [ + softpipe, + i965simple, + ] + + if 'trace' in env['drivers']: + env.Append(CPPDEFINES = 'GALLIUM_TRACE') + drivers += [trace] - # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions - env.SharedLibrary( - target ='GL', - source = sources, - LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], - ) + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 9225ee510d..5a01b6167b 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -54,6 +54,11 @@ #define TILE_SIZE 32 /* avoid compilation errors */ #endif +#ifdef GALLIUM_TRACE +#include "trace/tr_screen.h" +#include "trace/tr_context.h" +#endif + #include "xm_winsys_aub.h" @@ -674,7 +679,15 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) { struct pipe_screen *screen = softpipe_create_screen(pws); +#ifdef GALLIUM_TRACE + screen = trace_screen_create(screen); +#endif + pipe = softpipe_create(screen, pws, NULL); + +#ifdef GALLIUM_TRACE + pipe = trace_context_create(pipe); +#endif } if (pipe) -- cgit v1.2.3 From f6e0514736bb763813a49ae5542b2c8648641595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 6 Aug 2008 21:39:25 +0100 Subject: trace: Add missing XSL and CSS. --- src/gallium/drivers/trace/trace.css | 72 +++++++++++++++++++++++ src/gallium/drivers/trace/trace.xsl | 114 ++++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 src/gallium/drivers/trace/trace.css create mode 100644 src/gallium/drivers/trace/trace.xsl (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/trace.css b/src/gallium/drivers/trace/trace.css new file mode 100644 index 0000000000..d92c433791 --- /dev/null +++ b/src/gallium/drivers/trace/trace.css @@ -0,0 +1,72 @@ +/**************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + ****************************************************************************/ + +body { + font-family: verdana, sans-serif; + font-size: 11px; + font-weight: normal; + text-align : left; +} + +ul.calls { + list-style: none; + margin-left: 0px; + padding-left: 0px; +} + +ul.args { + display:inline; + list-style: none; + margin-left: 0px; + padding-left: 0px; +} + +ul.args li { + display:inline; +} + +ul.elems { + list-style: none; + margin-left: 2em; + padding-left: 0px; +} + +ul.elems li { + display:block; +} + +.fun { + font-weight: bold; +} + +.var { + font-style: italic; +} + +.typ { + display: none; +} + +.lit { + color: #0000ff; +} + +.ptr { + color: #008000; +} diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl new file mode 100644 index 0000000000..ace4020cf9 --- /dev/null +++ b/src/gallium/drivers/trace/trace.xsl @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + Gallium Trace + + + +
    + +
+ + +
+ + +
  • + + + :: + + + ( +
      + +
    + ) + +
  • +
    + + +
  • + + = + + + , + +
  • +
    + + + = + + + + + + + + + + + + " + + " + + + + + { + + } + + + +
  • + + + , + +
  • +
    + + + + + + + + + + + + +
    -- cgit v1.2.3 From f2e19c34e06dfc33557a481f764fc75a5aef15ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 13:20:02 +0100 Subject: trace: Trace pipe context calls. --- src/gallium/drivers/trace/tr_context.c | 1017 +++++++++++++++++++++++++++++++- src/gallium/drivers/trace/tr_context.h | 10 +- src/gallium/drivers/trace/tr_dump.h | 7 + 3 files changed, 1027 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 67a67b3da6..6161e35fa5 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -30,12 +30,1025 @@ #include "tr_stream.h" #include "tr_dump.h" #include "tr_state.h" +#include "tr_screen.h" #include "tr_context.h" +static INLINE void +trace_context_set_edgeflags(struct pipe_context *_pipe, + const unsigned *bitfield) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_edgeflags"); + + trace_dump_arg(stream, ptr, pipe); + /* FIXME: we don't know how big this array is */ + trace_dump_arg(stream, ptr, bitfield); + + pipe->set_edgeflags(pipe, bitfield);; + + trace_dump_call_end(stream); +} + + +static INLINE boolean +trace_context_draw_arrays(struct pipe_context *_pipe, + unsigned mode, unsigned start, unsigned count) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + boolean result; + + trace_dump_call_begin(stream, "pipe_context", "draw_arrays"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, mode); + trace_dump_arg(stream, uint, start); + trace_dump_arg(stream, uint, count); + + result = pipe->draw_arrays(pipe, mode, start, count);; + + trace_dump_ret(stream, bool, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE boolean +trace_context_draw_elements(struct pipe_context *_pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + boolean result; + + trace_dump_call_begin(stream, "pipe_context", "draw_elements"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, indexBuffer); + trace_dump_arg(stream, uint, indexSize); + trace_dump_arg(stream, uint, mode); + trace_dump_arg(stream, uint, start); + trace_dump_arg(stream, uint, count); + + result = pipe->draw_elements(pipe, indexBuffer, indexSize, mode, start, count);; + + trace_dump_ret(stream, bool, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE boolean +trace_context_draw_range_elements(struct pipe_context *_pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned minIndex, + unsigned maxIndex, + unsigned mode, + unsigned start, + unsigned count) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + boolean result; + + trace_dump_call_begin(stream, "pipe_context", "draw_range_elements"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, indexBuffer); + trace_dump_arg(stream, uint, indexSize); + trace_dump_arg(stream, uint, minIndex); + trace_dump_arg(stream, uint, maxIndex); + trace_dump_arg(stream, uint, mode); + trace_dump_arg(stream, uint, start); + trace_dump_arg(stream, uint, count); + + result = pipe->draw_range_elements(pipe, + indexBuffer, + indexSize, minIndex, maxIndex, + mode, start, count); + + trace_dump_ret(stream, bool, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE struct pipe_query * +trace_context_create_query(struct pipe_context *_pipe, + unsigned query_type) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_query *result; + + trace_dump_call_begin(stream, "pipe_context", "create_query"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, query_type); + + result = pipe->create_query(pipe, query_type);; + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_destroy_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "destroy_query"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, query); + + pipe->destroy_query(pipe, query);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_begin_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "begin_query"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, query); + + pipe->begin_query(pipe, query);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_end_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "end_query"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, query); + + pipe->end_query(pipe, query); + + trace_dump_call_end(stream); +} + + +static INLINE boolean +trace_context_get_query_result(struct pipe_context *_pipe, + struct pipe_query *query, + boolean wait, + uint64 *presult) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + uint64 result; + boolean _result; + + trace_dump_call_begin(stream, "pipe_context", "get_query_result"); + + trace_dump_arg(stream, ptr, pipe); + + _result = pipe->get_query_result(pipe, query, wait, presult);; + result = *presult; + + trace_dump_arg(stream, uint, result); + trace_dump_ret(stream, bool, _result); + + trace_dump_call_end(stream); + + return _result; +} + + +static INLINE void * +trace_context_create_blend_state(struct pipe_context *_pipe, + const struct pipe_blend_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_blend_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + result = pipe->create_blend_state(pipe, state);; + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_blend_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_blend_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->bind_blend_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_blend_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_blend_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_blend_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void * +trace_context_create_sampler_state(struct pipe_context *_pipe, + const struct pipe_sampler_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_sampler_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + result = pipe->create_sampler_state(pipe, state);; + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_sampler_states(struct pipe_context *_pipe, + unsigned num_states, void **states) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_sampler_states"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, num_states); + trace_dump_arg_array(stream, ptr, states, num_states); + + pipe->bind_sampler_states(pipe, num_states, states);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_sampler_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_sampler_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_sampler_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void * +trace_context_create_rasterizer_state(struct pipe_context *_pipe, + const struct pipe_rasterizer_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_rasterizer_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + result = pipe->create_rasterizer_state(pipe, state);; + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_rasterizer_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_rasterizer_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->bind_rasterizer_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_rasterizer_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_rasterizer_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_rasterizer_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void * +trace_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe, + const struct pipe_depth_stencil_alpha_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_depth_stencil_alpha_state"); + + result = pipe->create_depth_stencil_alpha_state(pipe, state);; + + trace_dump_ret(stream, ptr, result); + trace_dump_arg(stream, ptr, state); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_depth_stencil_alpha_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->bind_depth_stencil_alpha_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_depth_stencil_alpha_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_depth_stencil_alpha_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void * +trace_context_create_fs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_fs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + result = pipe->create_fs_state(pipe, state);; + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_fs_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_fs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->bind_fs_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_fs_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_fs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_fs_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void * +trace_context_create_vs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + void * result; + + trace_dump_call_begin(stream, "pipe_context", "create_vs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + result = pipe->create_vs_state(pipe, state);; + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static INLINE void +trace_context_bind_vs_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "bind_vs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->bind_vs_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_delete_vs_state(struct pipe_context *_pipe, + void *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "delete_vs_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->delete_vs_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_blend_color(struct pipe_context *_pipe, + const struct pipe_blend_color *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_blend_color"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->set_blend_color(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_clip_state(struct pipe_context *_pipe, + const struct pipe_clip_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_clip_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->set_clip_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_constant_buffer(struct pipe_context *_pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buffer) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_constant_buffer"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, shader); + trace_dump_arg(stream, uint, index); + trace_dump_arg(stream, ptr, buffer); + + pipe->set_constant_buffer(pipe, shader, index, buffer);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_framebuffer_state(struct pipe_context *_pipe, + const struct pipe_framebuffer_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_framebuffer_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->set_framebuffer_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_polygon_stipple(struct pipe_context *_pipe, + const struct pipe_poly_stipple *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_polygon_stipple"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->set_polygon_stipple(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_scissor_state(struct pipe_context *_pipe, + const struct pipe_scissor_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_scissor_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->set_scissor_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_viewport_state(struct pipe_context *_pipe, + const struct pipe_viewport_state *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_viewport_state"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, state); + + pipe->set_viewport_state(pipe, state);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_sampler_textures(struct pipe_context *_pipe, + unsigned num_textures, + struct pipe_texture **textures) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_sampler_textures"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, num_textures); + trace_dump_arg_array(stream, ptr, textures, num_textures); + + pipe->set_sampler_textures(pipe, num_textures, textures);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_vertex_buffers(struct pipe_context *_pipe, + unsigned num_buffers, + const struct pipe_vertex_buffer *buffers) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_vertex_buffers"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, num_buffers); + trace_dump_arg(stream, ptr, buffers); + //trace_dump_arg_array(stream, ptr, buffers, num_buffers); + + pipe->set_vertex_buffers(pipe, num_buffers, buffers);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_set_vertex_elements(struct pipe_context *_pipe, + unsigned num_elements, + const struct pipe_vertex_element *elements) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "set_vertex_elements"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, num_elements); + trace_dump_arg(stream, ptr, elements); + //trace_dump_arg_array(stream, ptr, elements, num_elements); + + pipe->set_vertex_elements(pipe, num_elements, elements);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_surface_copy(struct pipe_context *_pipe, + boolean do_flip, + struct pipe_surface *dest, + unsigned destx, unsigned desty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "surface_copy"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, bool, do_flip); + trace_dump_arg(stream, ptr, dest); + trace_dump_arg(stream, uint, destx); + trace_dump_arg(stream, uint, desty); + trace_dump_arg(stream, ptr, src); + trace_dump_arg(stream, uint, srcx); + trace_dump_arg(stream, uint, srcy); + trace_dump_arg(stream, uint, width); + trace_dump_arg(stream, uint, height); + + pipe->surface_copy(pipe, do_flip, + dest, destx, desty, + src, srcx, srcy, width, height); + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_surface_fill(struct pipe_context *_pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + unsigned value) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "surface_fill"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, dst); + trace_dump_arg(stream, uint, dstx); + trace_dump_arg(stream, uint, dsty); + trace_dump_arg(stream, uint, width); + trace_dump_arg(stream, uint, height); + + pipe->surface_fill(pipe, dst, dstx, dsty, width, height, value);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_clear(struct pipe_context *_pipe, + struct pipe_surface *surface, + unsigned clearValue) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "clear"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, ptr, surface); + trace_dump_arg(stream, uint, clearValue); + + pipe->clear(pipe, surface, clearValue);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_flush(struct pipe_context *_pipe, + unsigned flags, + struct pipe_fence_handle **fence) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "flush"); + + trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(stream, uint, flags); + trace_dump_arg(stream, ptr, fence); + + pipe->flush(pipe, flags, fence);; + + trace_dump_call_end(stream); +} + + +static INLINE void +trace_context_destroy(struct pipe_context *_pipe) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct trace_screen *tr_scr = trace_screen(_pipe->screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin(stream, "pipe_context", "destroy"); + + trace_dump_arg(stream, ptr, pipe); + + pipe->destroy(pipe); + + trace_dump_call_end(stream); + + FREE(tr_ctx); +} + + struct pipe_context * trace_context_create(struct pipe_context *pipe) { - /* TODO */ - return pipe; + struct trace_context *tr_ctx; + + if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) + return pipe; + + tr_ctx = CALLOC_STRUCT(trace_context); + if(!tr_ctx) + return NULL; + + tr_ctx->base.winsys = pipe->winsys; + tr_ctx->base.screen = pipe->screen; + tr_ctx->base.destroy = trace_context_destroy; + tr_ctx->base.set_edgeflags = trace_context_set_edgeflags; + tr_ctx->base.draw_arrays = trace_context_draw_arrays; + tr_ctx->base.draw_elements = trace_context_draw_elements; + tr_ctx->base.draw_range_elements = trace_context_draw_range_elements; + tr_ctx->base.create_query = trace_context_create_query; + tr_ctx->base.destroy_query = trace_context_destroy_query; + tr_ctx->base.begin_query = trace_context_begin_query; + tr_ctx->base.end_query = trace_context_end_query; + tr_ctx->base.get_query_result = trace_context_get_query_result; + tr_ctx->base.create_blend_state = trace_context_create_blend_state; + tr_ctx->base.bind_blend_state = trace_context_bind_blend_state; + tr_ctx->base.delete_blend_state = trace_context_delete_blend_state; + tr_ctx->base.create_sampler_state = trace_context_create_sampler_state; + tr_ctx->base.bind_sampler_states = trace_context_bind_sampler_states; + tr_ctx->base.delete_sampler_state = trace_context_delete_sampler_state; + tr_ctx->base.create_rasterizer_state = trace_context_create_rasterizer_state; + tr_ctx->base.bind_rasterizer_state = trace_context_bind_rasterizer_state; + tr_ctx->base.delete_rasterizer_state = trace_context_delete_rasterizer_state; + tr_ctx->base.create_depth_stencil_alpha_state = trace_context_create_depth_stencil_alpha_state; + tr_ctx->base.bind_depth_stencil_alpha_state = trace_context_bind_depth_stencil_alpha_state; + tr_ctx->base.delete_depth_stencil_alpha_state = trace_context_delete_depth_stencil_alpha_state; + tr_ctx->base.create_fs_state = trace_context_create_fs_state; + tr_ctx->base.bind_fs_state = trace_context_bind_fs_state; + tr_ctx->base.delete_fs_state = trace_context_delete_fs_state; + tr_ctx->base.create_vs_state = trace_context_create_vs_state; + tr_ctx->base.bind_vs_state = trace_context_bind_vs_state; + tr_ctx->base.delete_vs_state = trace_context_delete_vs_state; + tr_ctx->base.set_blend_color = trace_context_set_blend_color; + tr_ctx->base.set_clip_state = trace_context_set_clip_state; + tr_ctx->base.set_constant_buffer = trace_context_set_constant_buffer; + tr_ctx->base.set_framebuffer_state = trace_context_set_framebuffer_state; + tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple; + tr_ctx->base.set_scissor_state = trace_context_set_scissor_state; + tr_ctx->base.set_viewport_state = trace_context_set_viewport_state; + tr_ctx->base.set_sampler_textures = trace_context_set_sampler_textures; + tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers; + tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements; + tr_ctx->base.surface_copy = trace_context_surface_copy; + tr_ctx->base.surface_fill = trace_context_surface_fill; + tr_ctx->base.clear = trace_context_clear; + tr_ctx->base.flush = trace_context_flush; + + tr_ctx->pipe = pipe; + + return &tr_ctx->base; } diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 75b8d11a7a..80fb5980d6 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -38,21 +38,21 @@ struct trace_context { struct pipe_context base; - /* TODO */ + struct pipe_context *pipe; }; static INLINE struct trace_context * -trace_context(struct pipe_context *context) +trace_context(struct pipe_context *pipe) { - assert(context); - return (struct trace_context *)context; + assert(pipe); + return (struct trace_context *)pipe; } struct pipe_context * -trace_context_create(struct pipe_context *context); +trace_context_create(struct pipe_context *pipe); #endif /* TR_CONTEXT_H_ */ diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index f086486591..0be0812ce8 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -91,6 +91,13 @@ void trace_dump_ptr(struct trace_stream *stream, const void *value); trace_dump_array_end(_stream); \ } while(0) +#define trace_dump_arg_array(_stream, _type, _arg, _size) \ + do { \ + trace_dump_arg_begin(_stream, #_arg); \ + trace_dump_array(_stream, _type, _arg, _size); \ + trace_dump_arg_end(_stream); \ + } while(0) + #define trace_dump_member(_stream, _type, _obj, _member) \ do { \ trace_dump_member_begin(_stream, #_member); \ -- cgit v1.2.3 From 9dee60969df7ff263e05430e69ef26982fe2bd94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 18:55:05 +0100 Subject: trace: Dump state. --- src/gallium/drivers/trace/tr_context.c | 37 +-- src/gallium/drivers/trace/tr_dump.c | 10 +- src/gallium/drivers/trace/tr_dump.h | 31 ++- src/gallium/drivers/trace/tr_state.c | 433 ++++++++++++++++++++++++++++++++- src/gallium/drivers/trace/tr_state.h | 57 ++++- src/gallium/drivers/trace/trace.xsl | 6 + 6 files changed, 549 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 6161e35fa5..ee8ad5eb97 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -280,7 +280,7 @@ trace_context_create_blend_state(struct pipe_context *_pipe, trace_dump_call_begin(stream, "pipe_context", "create_blend_state"); trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(stream, blend_state, state); result = pipe->create_blend_state(pipe, state);; @@ -347,7 +347,7 @@ trace_context_create_sampler_state(struct pipe_context *_pipe, result = pipe->create_sampler_state(pipe, state);; - trace_dump_ret(stream, ptr, result); + trace_dump_ret(stream, sampler_state, result); trace_dump_call_end(stream); @@ -409,7 +409,7 @@ trace_context_create_rasterizer_state(struct pipe_context *_pipe, trace_dump_call_begin(stream, "pipe_context", "create_rasterizer_state"); trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(stream, rasterizer_state, state); result = pipe->create_rasterizer_state(pipe, state);; @@ -476,7 +476,7 @@ trace_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe, result = pipe->create_depth_stencil_alpha_state(pipe, state);; trace_dump_ret(stream, ptr, result); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(stream, depth_stencil_alpha_state, state); trace_dump_call_end(stream); @@ -537,7 +537,7 @@ trace_context_create_fs_state(struct pipe_context *_pipe, trace_dump_call_begin(stream, "pipe_context", "create_fs_state"); trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(stream, shader_state, state); result = pipe->create_fs_state(pipe, state);; @@ -602,7 +602,7 @@ trace_context_create_vs_state(struct pipe_context *_pipe, trace_dump_call_begin(stream, "pipe_context", "create_vs_state"); trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(stream, shader_state, state); result = pipe->create_vs_state(pipe, state);; @@ -666,7 +666,7 @@ trace_context_set_blend_color(struct pipe_context *_pipe, trace_dump_call_begin(stream, "pipe_context", "set_blend_color"); trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(stream, blend_color, state); pipe->set_blend_color(pipe, state);; @@ -686,7 +686,7 @@ trace_context_set_clip_state(struct pipe_context *_pipe, trace_dump_call_begin(stream, "pipe_context", "set_clip_state"); trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(stream, clip_state, state); pipe->set_clip_state(pipe, state);; @@ -709,7 +709,7 @@ trace_context_set_constant_buffer(struct pipe_context *_pipe, trace_dump_arg(stream, ptr, pipe); trace_dump_arg(stream, uint, shader); trace_dump_arg(stream, uint, index); - trace_dump_arg(stream, ptr, buffer); + trace_dump_arg(stream, constant_buffer, buffer); pipe->set_constant_buffer(pipe, shader, index, buffer);; @@ -729,7 +729,7 @@ trace_context_set_framebuffer_state(struct pipe_context *_pipe, trace_dump_call_begin(stream, "pipe_context", "set_framebuffer_state"); trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(stream, framebuffer_state, state); pipe->set_framebuffer_state(pipe, state);; @@ -749,7 +749,7 @@ trace_context_set_polygon_stipple(struct pipe_context *_pipe, trace_dump_call_begin(stream, "pipe_context", "set_polygon_stipple"); trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(stream, poly_stipple, state); pipe->set_polygon_stipple(pipe, state);; @@ -769,7 +769,7 @@ trace_context_set_scissor_state(struct pipe_context *_pipe, trace_dump_call_begin(stream, "pipe_context", "set_scissor_state"); trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(stream, scissor_state, state); pipe->set_scissor_state(pipe, state);; @@ -789,7 +789,7 @@ trace_context_set_viewport_state(struct pipe_context *_pipe, trace_dump_call_begin(stream, "pipe_context", "set_viewport_state"); trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(stream, viewport_state, state); pipe->set_viewport_state(pipe, state);; @@ -833,8 +833,10 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe, trace_dump_arg(stream, ptr, pipe); trace_dump_arg(stream, uint, num_buffers); - trace_dump_arg(stream, ptr, buffers); - //trace_dump_arg_array(stream, ptr, buffers, num_buffers); + + trace_dump_arg_begin(stream, "buffers"); + trace_dump_struct_array(stream, vertex_buffer, buffers, num_buffers); + trace_dump_arg_end(stream); pipe->set_vertex_buffers(pipe, num_buffers, buffers);; @@ -857,7 +859,10 @@ trace_context_set_vertex_elements(struct pipe_context *_pipe, trace_dump_arg(stream, ptr, pipe); trace_dump_arg(stream, uint, num_elements); trace_dump_arg(stream, ptr, elements); - //trace_dump_arg_array(stream, ptr, elements, num_elements); + + trace_dump_arg_begin(stream, "elements"); + trace_dump_struct_array(stream, vertex_element, elements, num_elements); + trace_dump_arg_end(stream); pipe->set_vertex_elements(pipe, num_elements, elements);; diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 30c0986363..0591b9fc33 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -322,8 +322,16 @@ void trace_dump_member_end(struct trace_stream *stream) trace_dump_write(stream, ""); } +void trace_dump_null(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + void trace_dump_ptr(struct trace_stream *stream, const void *value) { - trace_dump_writef(stream, "%p", value); + if(value) + trace_dump_writef(stream, "%p", value); + else + trace_dump_null(stream); } diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index 0be0812ce8..5eeac8d3c5 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -34,6 +34,9 @@ #define TR_DUMP_H +#include "pipe/p_util.h" + + struct trace_stream; @@ -58,6 +61,7 @@ void trace_dump_struct_begin(struct trace_stream *stream, const char *name); void trace_dump_struct_end(struct trace_stream *stream); void trace_dump_member_begin(struct trace_stream *stream, const char *name); void trace_dump_member_end(struct trace_stream *stream); +void trace_dump_null(struct trace_stream *stream); void trace_dump_ptr(struct trace_stream *stream, const void *value); @@ -83,14 +87,33 @@ void trace_dump_ptr(struct trace_stream *stream, const void *value); do { \ unsigned long idx; \ trace_dump_array_begin(_stream); \ - for(idx = 0; idx < _size; ++idx) { \ + for(idx = 0; idx < (_size); ++idx) { \ + trace_dump_elem_begin(_stream); \ + trace_dump_##_type(_stream, (_obj)[idx]); \ + trace_dump_elem_end(_stream); \ + } \ + trace_dump_array_end(_stream); \ + } while(0) + +#define trace_dump_struct_array(_stream, _type, _obj, _size) \ + do { \ + unsigned long idx; \ + trace_dump_array_begin(_stream); \ + for(idx = 0; idx < (_size); ++idx) { \ trace_dump_elem_begin(_stream); \ - trace_dump_##_type(_stream, _obj[idx]); \ + trace_dump_##_type(_stream, &(_obj)[idx]); \ trace_dump_elem_end(_stream); \ } \ trace_dump_array_end(_stream); \ } while(0) +#define trace_dump_member(_stream, _type, _obj, _member) \ + do { \ + trace_dump_member_begin(_stream, #_member); \ + trace_dump_##_type(_stream, (_obj)->_member); \ + trace_dump_member_end(_stream); \ + } while(0) + #define trace_dump_arg_array(_stream, _type, _arg, _size) \ do { \ trace_dump_arg_begin(_stream, #_arg); \ @@ -98,10 +121,10 @@ void trace_dump_ptr(struct trace_stream *stream, const void *value); trace_dump_arg_end(_stream); \ } while(0) -#define trace_dump_member(_stream, _type, _obj, _member) \ +#define trace_dump_member_array(_stream, _type, _obj, _member) \ do { \ trace_dump_member_begin(_stream, #_member); \ - trace_dump_##_type(_stream, _obj->_member); \ + trace_dump_array(_stream, _type, (_obj)->_member, sizeof((_obj)->_member)/sizeof((_obj)->_member[0])); \ trace_dump_member_end(_stream); \ } while(0) diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index 1e0e87f7fd..f18f5c611e 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -27,12 +27,19 @@ #include "pipe/p_compiler.h" -#include "pipe/p_state.h" +#include "tgsi/tgsi_parse.h" #include "tr_dump.h" #include "tr_state.h" +void trace_dump_format(struct trace_stream *stream, + enum pipe_format format) +{ + trace_dump_int(stream, format); +} + + void trace_dump_block(struct trace_stream *stream, const struct pipe_format_block *block) { @@ -44,9 +51,32 @@ void trace_dump_block(struct trace_stream *stream, } +void trace_dump_buffer(struct trace_stream *stream, + const struct pipe_buffer *buffer) +{ + if(!buffer) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_buffer"); + trace_dump_member(stream, uint, buffer, alignment); + trace_dump_member(stream, uint, buffer, usage); + trace_dump_member(stream, uint, buffer, size); + /* TODO: buffer data */ + trace_dump_struct_end(stream); +} + + void trace_dump_template(struct trace_stream *stream, const struct pipe_texture *templat) { + assert(templat); + if(!templat) { + trace_dump_null(stream); + return; + } + trace_dump_struct_begin(stream, "pipe_texture"); trace_dump_member(stream, int, templat, target); @@ -70,3 +100,404 @@ void trace_dump_template(struct trace_stream *stream, trace_dump_struct_end(stream); } + +void trace_dump_rasterizer_state(struct trace_stream *stream, + const struct pipe_rasterizer_state *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_rasterizer_state"); + + trace_dump_member(stream, bool, state, flatshade); + trace_dump_member(stream, bool, state, light_twoside); + trace_dump_member(stream, uint, state, front_winding); + trace_dump_member(stream, uint, state, cull_mode); + trace_dump_member(stream, uint, state, fill_cw); + trace_dump_member(stream, uint, state, fill_ccw); + trace_dump_member(stream, bool, state, offset_cw); + trace_dump_member(stream, bool, state, offset_ccw); + trace_dump_member(stream, bool, state, scissor); + trace_dump_member(stream, bool, state, poly_smooth); + trace_dump_member(stream, bool, state, poly_stipple_enable); + trace_dump_member(stream, bool, state, point_smooth); + trace_dump_member(stream, bool, state, point_sprite); + trace_dump_member(stream, bool, state, point_size_per_vertex); + trace_dump_member(stream, bool, state, multisample); + trace_dump_member(stream, bool, state, line_smooth); + trace_dump_member(stream, bool, state, line_stipple_enable); + trace_dump_member(stream, uint, state, line_stipple_factor); + trace_dump_member(stream, uint, state, line_stipple_pattern); + trace_dump_member(stream, bool, state, line_last_pixel); + trace_dump_member(stream, bool, state, bypass_clipping); + trace_dump_member(stream, bool, state, bypass_vs); + trace_dump_member(stream, bool, state, origin_lower_left); + trace_dump_member(stream, bool, state, flatshade_first); + trace_dump_member(stream, bool, state, gl_rasterization_rules); + + trace_dump_member(stream, float, state, line_width); + trace_dump_member(stream, float, state, point_size); + trace_dump_member(stream, float, state, point_size_min); + trace_dump_member(stream, float, state, point_size_max); + trace_dump_member(stream, float, state, offset_units); + trace_dump_member(stream, float, state, offset_scale); + + trace_dump_member_array(stream, uint, state, sprite_coord_mode); + + trace_dump_struct_end(stream); +} + + +void trace_dump_poly_stipple(struct trace_stream *stream, + const struct pipe_poly_stipple *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_poly_stipple"); + + trace_dump_member_array(stream, uint, state, stipple); + + trace_dump_struct_end(stream); +} + + +void trace_dump_viewport_state(struct trace_stream *stream, + const struct pipe_viewport_state *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_viewport_state"); + + trace_dump_member_array(stream, float, state, scale); + trace_dump_member_array(stream, float, state, translate); + + trace_dump_struct_end(stream); +} + + +void trace_dump_scissor_state(struct trace_stream *stream, + const struct pipe_scissor_state *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_scissor_state"); + + trace_dump_member(stream, uint, state, minx); + trace_dump_member(stream, uint, state, miny); + trace_dump_member(stream, uint, state, maxx); + trace_dump_member(stream, uint, state, maxy); + + trace_dump_struct_end(stream); +} + + +void trace_dump_clip_state(struct trace_stream *stream, + const struct pipe_clip_state *state) +{ + unsigned i; + + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_scissor_state"); + + trace_dump_member_begin(stream, "ucp"); + trace_dump_array_begin(stream); + for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) + trace_dump_array(stream, float, state->ucp[i], 4); + trace_dump_array_end(stream); + trace_dump_member_end(stream); + + trace_dump_member(stream, uint, state, nr); + + trace_dump_struct_end(stream); +} + + +void trace_dump_constant_buffer(struct trace_stream *stream, + const struct pipe_constant_buffer *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_constant_buffer"); + + trace_dump_member(stream, buffer, state, buffer); + trace_dump_member(stream, uint, state, size); + + trace_dump_struct_end(stream); +} + + +void trace_dump_shader_state(struct trace_stream *stream, + const struct pipe_shader_state *state) +{ + uint32_t *p = (uint32_t *)state->tokens; + unsigned n = tgsi_num_tokens(state->tokens); + + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + assert(sizeof(struct tgsi_token) == 4); + + trace_dump_struct_begin(stream, "pipe_shader_state"); + + trace_dump_member_begin(stream, "tokens"); + trace_dump_array(stream, uint, p, n); + trace_dump_member_end(stream); + + trace_dump_struct_end(stream); +} + + +void trace_dump_depth_stencil_alpha_state(struct trace_stream *stream, + const struct pipe_depth_stencil_alpha_state *state) +{ + unsigned i; + + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_depth_stencil_alpha_state"); + + trace_dump_member_begin(stream, "depth"); + trace_dump_struct_begin(stream, ""); + trace_dump_member(stream, bool, &state->depth, enabled); + trace_dump_member(stream, bool, &state->depth, writemask); + trace_dump_member(stream, uint, &state->depth, func); + trace_dump_member(stream, bool, &state->depth, occlusion_count); + trace_dump_struct_end(stream); + trace_dump_member_end(stream); + + trace_dump_member_begin(stream, "stencil"); + trace_dump_array_begin(stream); + for(i = 0; i < Elements(state->stencil); ++i) { + trace_dump_elem_begin(stream); + trace_dump_struct_begin(stream, ""); + trace_dump_member(stream, bool, &state->stencil[i], enabled); + trace_dump_member(stream, uint, &state->stencil[i], func); + trace_dump_member(stream, uint, &state->stencil[i], fail_op); + trace_dump_member(stream, uint, &state->stencil[i], zpass_op); + trace_dump_member(stream, uint, &state->stencil[i], zfail_op); + trace_dump_member(stream, uint, &state->stencil[i], ref_value); + trace_dump_member(stream, uint, &state->stencil[i], value_mask); + trace_dump_member(stream, uint, &state->stencil[i], write_mask); + trace_dump_struct_end(stream); + trace_dump_elem_end(stream); + } + trace_dump_array_end(stream); + trace_dump_member_end(stream); + + trace_dump_member_begin(stream, "alpha"); + trace_dump_struct_begin(stream, ""); + trace_dump_member(stream, bool, &state->alpha, enabled); + trace_dump_member(stream, uint, &state->alpha, func); + trace_dump_member(stream, float, &state->alpha, ref); + trace_dump_struct_end(stream); + trace_dump_member_end(stream); + + trace_dump_struct_end(stream); +} + + +void trace_dump_blend_state(struct trace_stream *stream, + const struct pipe_blend_state *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_blend_state"); + + trace_dump_member(stream, bool, state, blend_enable); + + trace_dump_member(stream, uint, state, rgb_func); + trace_dump_member(stream, uint, state, rgb_src_factor); + trace_dump_member(stream, uint, state, rgb_dst_factor); + + trace_dump_member(stream, uint, state, alpha_func); + trace_dump_member(stream, uint, state, alpha_src_factor); + trace_dump_member(stream, uint, state, alpha_dst_factor); + + trace_dump_member(stream, bool, state, logicop_enable); + trace_dump_member(stream, uint, state, logicop_func); + + trace_dump_member(stream, uint, state, colormask); + trace_dump_member(stream, bool, state, dither); + + trace_dump_struct_end(stream); +} + + +void trace_dump_blend_color(struct trace_stream *stream, + const struct pipe_blend_color *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_blend_color"); + + trace_dump_member_array(stream, float, state, color); + + trace_dump_struct_end(stream); +} + + +void trace_dump_framebuffer_state(struct trace_stream *stream, + const struct pipe_framebuffer_state *state) +{ + trace_dump_struct_begin(stream, "pipe_framebuffer_state"); + + trace_dump_member(stream, uint, state, width); + trace_dump_member(stream, uint, state, height); + trace_dump_member(stream, uint, state, num_cbufs); + trace_dump_member_array(stream, ptr, state, cbufs); + trace_dump_member(stream, ptr, state, zsbuf); + + trace_dump_struct_end(stream); +} + + +void trace_dump_sampler_state(struct trace_stream *stream, + const struct pipe_sampler_state *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_sampler_state"); + + trace_dump_member(stream, uint, state, wrap_s); + trace_dump_member(stream, uint, state, wrap_t); + trace_dump_member(stream, uint, state, wrap_r); + trace_dump_member(stream, uint, state, min_img_filter); + trace_dump_member(stream, uint, state, min_mip_filter); + trace_dump_member(stream, uint, state, mag_img_filter); + trace_dump_member(stream, bool, state, compare_mode); + trace_dump_member(stream, uint, state, compare_func); + trace_dump_member(stream, bool, state, normalized_coords); + trace_dump_member(stream, uint, state, prefilter); + trace_dump_member(stream, float, state, shadow_ambient); + trace_dump_member(stream, float, state, lod_bias); + trace_dump_member(stream, float, state, min_lod); + trace_dump_member(stream, float, state, max_lod); + trace_dump_member_array(stream, float, state, border_color); + trace_dump_member(stream, float, state, max_anisotropy); + + trace_dump_struct_end(stream); +} + + +void trace_dump_surface(struct trace_stream *stream, + const struct pipe_surface *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_surface"); + + trace_dump_member(stream, buffer, state, buffer); + trace_dump_member(stream, format, state, format); + trace_dump_member(stream, uint, state, status); + trace_dump_member(stream, uint, state, clear_value); + trace_dump_member(stream, uint, state, width); + trace_dump_member(stream, uint, state, height); + + trace_dump_member_begin(stream, "block"); + trace_dump_block(stream, &state->block); + trace_dump_member_end(stream); + + trace_dump_member(stream, uint, state, nblocksx); + trace_dump_member(stream, uint, state, nblocksy); + trace_dump_member(stream, uint, state, stride); + trace_dump_member(stream, uint, state, layout); + trace_dump_member(stream, uint, state, offset); + trace_dump_member(stream, uint, state, refcount); + trace_dump_member(stream, uint, state, usage); + + trace_dump_member(stream, ptr, state, texture); + trace_dump_member(stream, uint, state, face); + trace_dump_member(stream, uint, state, level); + trace_dump_member(stream, uint, state, zslice); + + trace_dump_struct_end(stream); +} + + +void trace_dump_vertex_buffer(struct trace_stream *stream, + const struct pipe_vertex_buffer *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_vertex_buffer"); + + trace_dump_member(stream, uint, state, pitch); + trace_dump_member(stream, uint, state, max_index); + trace_dump_member(stream, uint, state, buffer_offset); + trace_dump_member(stream, buffer, state, buffer); + + trace_dump_struct_end(stream); +} + + +void trace_dump_vertex_element(struct trace_stream *stream, + const struct pipe_vertex_element *state) +{ + assert(state); + if(!state) { + trace_dump_null(stream); + return; + } + + trace_dump_struct_begin(stream, "pipe_vertex_element"); + + trace_dump_member(stream, uint, state, src_offset); + + trace_dump_member(stream, uint, state, vertex_buffer_index); + trace_dump_member(stream, uint, state, nr_components); + + trace_dump_member(stream, format, state, src_format); + + trace_dump_struct_end(stream); +} diff --git a/src/gallium/drivers/trace/tr_state.h b/src/gallium/drivers/trace/tr_state.h index e52524ee90..c1df63db6a 100644 --- a/src/gallium/drivers/trace/tr_state.h +++ b/src/gallium/drivers/trace/tr_state.h @@ -28,11 +28,13 @@ #ifndef TR_STATE_H #define TR_STATE_H +#include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "pipe/p_shader_tokens.h" -struct trace_stream; -struct pipe_format_block; -struct pipe_texture; +void trace_dump_format(struct trace_stream *stream, + enum pipe_format format); void trace_dump_block(struct trace_stream *stream, const struct pipe_format_block *block); @@ -41,4 +43,53 @@ void trace_dump_template(struct trace_stream *stream, const struct pipe_texture *templat); +void trace_dump_rasterizer_state(struct trace_stream *stream, + const struct pipe_rasterizer_state *state); + +void trace_dump_poly_stipple(struct trace_stream *stream, + const struct pipe_poly_stipple *state); + +void trace_dump_viewport_state(struct trace_stream *stream, + const struct pipe_viewport_state *state); + +void trace_dump_scissor_state(struct trace_stream *stream, + const struct pipe_scissor_state *state); + +void trace_dump_clip_state(struct trace_stream *stream, + const struct pipe_clip_state *state); + +void trace_dump_constant_buffer(struct trace_stream *stream, + const struct pipe_constant_buffer *state); + +void trace_dump_token(struct trace_stream *stream, + const struct tgsi_token *token); + +void trace_dump_shader_state(struct trace_stream *stream, + const struct pipe_shader_state *state); + +void trace_dump_depth_stencil_alpha_state(struct trace_stream *stream, + const struct pipe_depth_stencil_alpha_state *state); + +void trace_dump_blend_state(struct trace_stream *stream, + const struct pipe_blend_state *state); + +void trace_dump_blend_color(struct trace_stream *stream, + const struct pipe_blend_color *state); + +void trace_dump_framebuffer_state(struct trace_stream *stream, + const struct pipe_framebuffer_state *state); + +void trace_dump_sampler_state(struct trace_stream *stream, + const struct pipe_sampler_state *state); + +void trace_dump_surface(struct trace_stream *stream, + const struct pipe_surface *state); + +void trace_dump_vertex_buffer(struct trace_stream *stream, + const struct pipe_vertex_buffer *state); + +void trace_dump_vertex_element(struct trace_stream *stream, + const struct pipe_vertex_element *state); + + #endif /* TR_STATE_H */ diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl index ace4020cf9..194c8b2efd 100644 --- a/src/gallium/drivers/trace/trace.xsl +++ b/src/gallium/drivers/trace/trace.xsl @@ -100,6 +100,12 @@ along with this program. If not, see . + + + NULL + + + -- cgit v1.2.3 From fdafa1f8632bf4e92996291a094e98f4e58dc37c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 19:25:28 +0100 Subject: gallium: Simplify format->name conversion. --- src/gallium/auxiliary/util/p_debug.c | 7 +++---- src/gallium/include/pipe/p_format.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index a3db13f96d..082b0e9fb5 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -335,7 +335,7 @@ const char * debug_dump_enum(const struct debug_named_value *names, unsigned long value) { - static char rest[256]; + static char rest[64]; while(names->name) { if(names->value == value) @@ -498,10 +498,9 @@ void debug_print_format(const char *msg, unsigned fmt ) } #endif -char *pf_sprint_name( char *str, enum pipe_format format ) +const char *pf_name( enum pipe_format format ) { - strcpy( str, debug_dump_enum(pipe_format_names, format) ); - return str; + return debug_dump_enum(pipe_format_names, format); } diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 947c445583..0a9cad8993 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -379,7 +379,7 @@ enum pipe_format { /** * Builds pipe format name from format token. */ -extern char *pf_sprint_name( char *str, enum pipe_format format ); +extern const char *pf_name( enum pipe_format format ); /** * Return bits for a particular component. -- cgit v1.2.3 From c8f319138355a5365303e6649a953422ecc88c5f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 Aug 2008 11:04:05 -0600 Subject: gallium: enable the call to r16_put_tile_rgba(), silences warning --- src/gallium/auxiliary/util/p_tile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index d65e603785..5521a6d08f 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -891,7 +891,7 @@ pipe_put_tile_rgba(struct pipe_surface *ps, /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ break; case PIPE_FORMAT_R16_SNORM: - /*r16_put_tile_rgba((short *) packed, w, h, p, src_stride);*/ + r16_put_tile_rgba((short *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_R16G16B16A16_SNORM: r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride); -- cgit v1.2.3 From 600aa7501f95c520ad97ac894cfd1a639562f94c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 Aug 2008 13:30:24 -0600 Subject: gallium: implement a bunch of missing put_tile functions --- src/gallium/auxiliary/util/p_tile.c | 163 ++++++++++++++++++++++++++++++------ 1 file changed, 137 insertions(+), 26 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 5521a6d08f..e366039a27 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -109,7 +109,7 @@ pipe_put_tile_raw(struct pipe_surface *ps, /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ static void -a8r8g8b8_get_tile_rgba(unsigned *src, +a8r8g8b8_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -156,7 +156,7 @@ a8r8g8b8_put_tile_rgba(unsigned *dst, /*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ static void -x8r8g8b8_get_tile_rgba(unsigned *src, +x8r8g8b8_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -202,7 +202,7 @@ x8r8g8b8_put_tile_rgba(unsigned *dst, /*** PIPE_FORMAT_B8G8R8A8_UNORM ***/ static void -b8g8r8a8_get_tile_rgba(unsigned *src, +b8g8r8a8_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -249,7 +249,7 @@ b8g8r8a8_put_tile_rgba(unsigned *dst, /*** PIPE_FORMAT_A1R5G5B5_UNORM ***/ static void -a1r5g5b5_get_tile_rgba(ushort *src, +a1r5g5b5_get_tile_rgba(const ushort *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -270,10 +270,37 @@ a1r5g5b5_get_tile_rgba(ushort *src, } +static void +a1r5g5b5_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b, a; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + r = r >> 3; /* 5 bits */ + g = g >> 3; /* 5 bits */ + b = b >> 3; /* 5 bits */ + a = a >> 7; /* 1 bit */ + *dst++ = (a << 15) | (r << 10) | (g << 5) | b; + } + p += src_stride; + } +} + + /*** PIPE_FORMAT_A4R4G4B4_UNORM ***/ static void -a4r4g4b4_get_tile_rgba(ushort *src, +a4r4g4b4_get_tile_rgba(const ushort *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -324,7 +351,7 @@ a4r4g4b4_put_tile_rgba(ushort *dst, /*** PIPE_FORMAT_R5G6B5_UNORM ***/ static void -r5g6b5_get_tile_rgba(ushort *src, +r5g6b5_get_tile_rgba(const ushort *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -373,7 +400,7 @@ r5g6b5_put_tile_rgba(ushort *dst, * Return each Z value as four floats in [0,1]. */ static void -z16_get_tile_rgba(ushort *src, +z16_get_tile_rgba(const ushort *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -399,7 +426,7 @@ z16_get_tile_rgba(ushort *src, /*** PIPE_FORMAT_L8_UNORM ***/ static void -l8_get_tile_rgba(ubyte *src, +l8_get_tile_rgba(const ubyte *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -419,10 +446,31 @@ l8_get_tile_rgba(ubyte *src, } +static void +l8_put_tile_rgba(ubyte *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + *dst++ = r; + } + p += src_stride; + } +} + + + /*** PIPE_FORMAT_A8_UNORM ***/ static void -a8_get_tile_rgba(ubyte *src, +a8_get_tile_rgba(const ubyte *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -441,10 +489,32 @@ a8_get_tile_rgba(ubyte *src, } } + +static void +a8_put_tile_rgba(ubyte *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned a; + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + *dst++ = a; + } + p += src_stride; + } +} + + + /*** PIPE_FORMAT_R16_SNORM ***/ static void -r16_get_tile_rgba(short *src, +r16_get_tile_rgba(const short *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -485,7 +555,7 @@ r16_put_tile_rgba(short *dst, /*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ static void -r16g16b16a16_get_tile_rgba(short *src, +r16g16b16a16_get_tile_rgba(const short *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -530,7 +600,7 @@ r16g16b16a16_put_tile_rgba(short *dst, /*** PIPE_FORMAT_I8_UNORM ***/ static void -i8_get_tile_rgba(ubyte *src, +i8_get_tile_rgba(const ubyte *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -550,13 +620,33 @@ i8_get_tile_rgba(ubyte *src, } +static void +i8_put_tile_rgba(ubyte *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + *dst++ = r; + } + p += src_stride; + } +} + + /*** PIPE_FORMAT_A8L8_UNORM ***/ static void -a8_l8_get_tile_rgba(ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) +a8l8_get_tile_rgba(const ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) { unsigned i, j; @@ -574,6 +664,27 @@ a8_l8_get_tile_rgba(ushort *src, } +static void +a8l8_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, a; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + *dst++ = (a << 8) | r; + } + p += src_stride; + } +} + + /*** PIPE_FORMAT_Z32_UNORM ***/ @@ -582,7 +693,7 @@ a8_l8_get_tile_rgba(ushort *src, * Return each Z value as four floats in [0,1]. */ static void -z32_get_tile_rgba(unsigned *src, +z32_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -609,7 +720,7 @@ z32_get_tile_rgba(unsigned *src, * Return Z component as four float in [0,1]. Stencil part ignored. */ static void -s8z24_get_tile_rgba(unsigned *src, +s8z24_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -636,7 +747,7 @@ s8z24_get_tile_rgba(unsigned *src, * Return Z component as four float in [0,1]. Stencil part ignored. */ static void -z24s8_get_tile_rgba(unsigned *src, +z24s8_get_tile_rgba(const unsigned *src, unsigned w, unsigned h, float *p, unsigned dst_stride) @@ -663,7 +774,7 @@ z24s8_get_tile_rgba(unsigned *src, * Convert YCbCr (or YCrCb) to RGBA. */ static void -ycbcr_get_tile_rgba(ushort *src, +ycbcr_get_tile_rgba(const ushort *src, unsigned w, unsigned h, float *p, unsigned dst_stride, @@ -780,7 +891,7 @@ pipe_tile_raw_to_rgba(enum pipe_format format, i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_A8L8_UNORM: - a8_l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); + a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); break; case PIPE_FORMAT_R16_SNORM: r16_get_tile_rgba((short *) src, w, h, dst, dst_stride); @@ -867,7 +978,7 @@ pipe_put_tile_rgba(struct pipe_surface *ps, b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_A1R5G5B5_UNORM: - /*a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ + a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_R5G6B5_UNORM: r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); @@ -879,16 +990,16 @@ pipe_put_tile_rgba(struct pipe_surface *ps, a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_L8_UNORM: - /*l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_A8_UNORM: - /*a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_I8_UNORM: - /*i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);*/ + i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_A8L8_UNORM: - /*a8_l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ + a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride); break; case PIPE_FORMAT_R16_SNORM: r16_put_tile_rgba((short *) packed, w, h, p, src_stride); -- cgit v1.2.3 From b1ff7dac537947d412bf423a73e7eacd76f90d84 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 Aug 2008 13:30:49 -0600 Subject: gallium: new/better debug code (disabled) --- src/gallium/drivers/softpipe/sp_setup.c | 4 ++-- src/gallium/drivers/softpipe/sp_tex_sample.c | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 4321ca46f4..b48eec730b 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -284,9 +284,9 @@ static void print_vertex(const struct setup_context *setup, const float (*v)[4]) { int i; - debug_printf("Vertex: (%p)\n", v); + debug_printf(" Vertex: (%p)\n", v); for (i = 0; i < setup->quad.nr_attrs; i++) { - debug_printf(" %d: %f %f %f %f\n", i, + debug_printf(" %d: %f %f %f %f\n", i, v[i][0], v[i][1], v[i][2], v[i][3]); } } diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 8e39269533..5d7a8cc61a 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -619,6 +619,13 @@ get_texel(struct tgsi_sampler *sampler, rgba[1][j] = tile->data.color[ty][tx][1]; rgba[2][j] = tile->data.color[ty][tx][2]; rgba[3][j] = tile->data.color[ty][tx][3]; + if (0) + { + char fmt[100]; + pf_sprint_name( fmt, sampler->texture->format); + printf("Get texel %f %f %f %f from %s\n", + rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j], fmt); + } } } -- cgit v1.2.3 From ae2195caf56d2eb782475254c68858a25ee7c857 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 Aug 2008 13:31:57 -0600 Subject: gallium: s/printf/debug_printf/ --- src/gallium/drivers/softpipe/sp_tex_sample.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 5d7a8cc61a..508db5aa61 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -623,8 +623,8 @@ get_texel(struct tgsi_sampler *sampler, { char fmt[100]; pf_sprint_name( fmt, sampler->texture->format); - printf("Get texel %f %f %f %f from %s\n", - rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j], fmt); + debug_printf("Get texel %f %f %f %f from %s\n", + rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j], fmt); } } } -- cgit v1.2.3 From 8fb55dab783f2de5111e7440093e1458fce5fb3d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 Aug 2008 13:35:21 -0600 Subject: gallium: s/pf_sprint_name/pf_name/ --- src/gallium/drivers/softpipe/sp_tex_sample.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 508db5aa61..01f4d0ca81 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -621,10 +621,9 @@ get_texel(struct tgsi_sampler *sampler, rgba[3][j] = tile->data.color[ty][tx][3]; if (0) { - char fmt[100]; - pf_sprint_name( fmt, sampler->texture->format); debug_printf("Get texel %f %f %f %f from %s\n", - rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j], fmt); + rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j], + pf_name(sampler->texture->format)); } } } -- cgit v1.2.3 From ce2137a6a4c2648a77b9697a3aa0479c9c61bacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 19:46:39 +0100 Subject: trace: Dump format names. --- src/gallium/drivers/trace/tr_dump.c | 8 ++++++++ src/gallium/drivers/trace/tr_dump.h | 1 + src/gallium/drivers/trace/tr_screen.c | 2 +- src/gallium/drivers/trace/tr_state.c | 4 ++-- src/gallium/drivers/trace/trace.xsl | 2 +- 5 files changed, 13 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 0591b9fc33..359a903ab9 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -280,6 +280,14 @@ void trace_dump_string(struct trace_stream *stream, trace_dump_write(stream, ""); } +void trace_dump_enum(struct trace_stream *stream, + const char *value) +{ + trace_dump_write(stream, ""); + trace_dump_escape(stream, value); + trace_dump_write(stream, ""); +} + void trace_dump_array_begin(struct trace_stream *stream) { trace_dump_write(stream, ""); diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index 5eeac8d3c5..7b15da3033 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -53,6 +53,7 @@ void trace_dump_int(struct trace_stream *stream, long int value); void trace_dump_uint(struct trace_stream *stream, long unsigned value); void trace_dump_float(struct trace_stream *stream, double value); void trace_dump_string(struct trace_stream *stream, const char *str); +void trace_dump_enum(struct trace_stream *stream, const char *value); void trace_dump_array_begin(struct trace_stream *stream); void trace_dump_array_end(struct trace_stream *stream); void trace_dump_elem_begin(struct trace_stream *stream); diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 20a2026e1d..3a48654609 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -140,7 +140,7 @@ trace_screen_is_format_supported(struct pipe_screen *_screen, trace_dump_call_begin(stream, "pipe_screen", "is_format_supported"); trace_dump_arg(stream, ptr, screen); - trace_dump_arg(stream, int, format); + trace_dump_arg(stream, format, format); trace_dump_arg(stream, int, target); trace_dump_arg(stream, uint, tex_usage); trace_dump_arg(stream, uint, geom_flags); diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index f18f5c611e..f17006dd81 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -36,7 +36,7 @@ void trace_dump_format(struct trace_stream *stream, enum pipe_format format) { - trace_dump_int(stream, format); + trace_dump_enum(stream, pf_name(format) ); } @@ -80,7 +80,7 @@ void trace_dump_template(struct trace_stream *stream, trace_dump_struct_begin(stream, "pipe_texture"); trace_dump_member(stream, int, templat, target); - trace_dump_member(stream, int, templat, format); + trace_dump_member(stream, format, templat, format); trace_dump_member_begin(stream, "width"); trace_dump_array(stream, uint, templat->width, 1); diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl index 194c8b2efd..3c84c4c35a 100644 --- a/src/gallium/drivers/trace/trace.xsl +++ b/src/gallium/drivers/trace/trace.xsl @@ -71,7 +71,7 @@ along with this program. If not, see . - + -- cgit v1.2.3 From 05e90964cfd99bb8cad2d9146ab042730052b8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 19:58:20 +0100 Subject: trace: Merge the CSS into the XSL. --- src/gallium/drivers/trace/trace.css | 72 ------------------------------------- src/gallium/drivers/trace/trace.xsl | 58 ++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 74 deletions(-) delete mode 100644 src/gallium/drivers/trace/trace.css (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/trace.css b/src/gallium/drivers/trace/trace.css deleted file mode 100644 index d92c433791..0000000000 --- a/src/gallium/drivers/trace/trace.css +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc. - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - ****************************************************************************/ - -body { - font-family: verdana, sans-serif; - font-size: 11px; - font-weight: normal; - text-align : left; -} - -ul.calls { - list-style: none; - margin-left: 0px; - padding-left: 0px; -} - -ul.args { - display:inline; - list-style: none; - margin-left: 0px; - padding-left: 0px; -} - -ul.args li { - display:inline; -} - -ul.elems { - list-style: none; - margin-left: 2em; - padding-left: 0px; -} - -ul.elems li { - display:block; -} - -.fun { - font-weight: bold; -} - -.var { - font-style: italic; -} - -.typ { - display: none; -} - -.lit { - color: #0000ff; -} - -.ptr { - color: #008000; -} diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl index 3c84c4c35a..5a876e0f21 100644 --- a/src/gallium/drivers/trace/trace.xsl +++ b/src/gallium/drivers/trace/trace.xsl @@ -29,8 +29,62 @@ along with this program. If not, see . Gallium Trace - +
      @@ -71,7 +125,7 @@ along with this program. If not, see . - + -- cgit v1.2.3 From 6a82ea2ed21c47749676e765311baed97f5dea9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 20:57:03 +0100 Subject: trace: Simplify HTML output. --- src/gallium/drivers/trace/trace.xsl | 47 ++++++------------------------------- 1 file changed, 7 insertions(+), 40 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl index 5a876e0f21..13039d44c4 100644 --- a/src/gallium/drivers/trace/trace.xsl +++ b/src/gallium/drivers/trace/trace.xsl @@ -38,33 +38,6 @@ along with this program. If not, see . text-align : left; } - ul.calls { - list-style: none; - margin-left: 0px; - padding-left: 0px; - } - - ul.args { - display:inline; - list-style: none; - margin-left: 0px; - padding-left: 0px; - } - - ul.args li { - display:inline; - } - - ul.elems { - list-style: none; - margin-left: 2em; - padding-left: 0px; - } - - ul.elems li { - display:block; - } - .fun { font-weight: bold; } @@ -86,9 +59,9 @@ along with this program. If not, see . } -
        +
          -
      +
      @@ -101,23 +74,19 @@ along with this program. If not, see . ( -
        - -
      + )
      -
    • = , -
    • @@ -146,12 +115,10 @@ along with this program. If not, see . -
    • - - - , - -
    • + + + , +
      -- cgit v1.2.3 From fdb7dc889f4251183915c811566ced083fdac40d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 Aug 2008 15:05:13 -0600 Subject: softpipe: add support for PIPE_FORMAT_X8Z24_UNORM, PIPE_FORMAT_Z24X8_UNORM --- src/gallium/drivers/softpipe/sp_quad_depth_test.c | 14 ++++++++++++++ src/gallium/drivers/softpipe/sp_tile_cache.c | 2 ++ 2 files changed, 16 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 33888abcc5..0c82692c6e 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -104,6 +104,8 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) } } break; + case PIPE_FORMAT_X8Z24_UNORM: + /* fall-through */ case PIPE_FORMAT_S8Z24_UNORM: { float scale = (float) ((1 << 24) - 1); @@ -119,6 +121,8 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) } } break; + case PIPE_FORMAT_Z24X8_UNORM: + /* fall-through */ case PIPE_FORMAT_Z24S8_UNORM: { float scale = (float) ((1 << 24) - 1); @@ -209,6 +213,9 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) tile->data.depth16[y][x] = (ushort) bzzzz[j]; } break; + case PIPE_FORMAT_X8Z24_UNORM: + /* fall-through */ + /* (yes, this falls through to a different case than above) */ case PIPE_FORMAT_Z32_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); @@ -234,6 +241,13 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) tile->data.depth32[y][x] = z24s8; } break; + case PIPE_FORMAT_Z24X8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->x0 % TILE_SIZE + (j & 1); + int y = quad->y0 % TILE_SIZE + (j >> 1); + tile->data.depth32[y][x] = bzzzz[j] << 8; + } + break; default: assert(0); } diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 5d10234945..57c12ffe33 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -170,7 +170,9 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, PIPE_BUFFER_USAGE_CPU_WRITE); tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || + ps->format == PIPE_FORMAT_X8Z24_UNORM || ps->format == PIPE_FORMAT_Z24S8_UNORM || + ps->format == PIPE_FORMAT_Z24X8_UNORM || ps->format == PIPE_FORMAT_Z16_UNORM || ps->format == PIPE_FORMAT_Z32_UNORM || ps->format == PIPE_FORMAT_S8_UNORM); -- cgit v1.2.3 From c1c4ff28f0af0b14ae64eb01ef1d087b987af2c1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 Aug 2008 15:11:54 -0600 Subject: gallium: use PIPE_FORMAT_X8Z24_UNORM for 24-bit Z but no stencil --- src/gallium/winsys/xlib/xm_api.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 8a32c54349..4e5441a13d 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -363,7 +363,12 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, stencilFormat = PIPE_FORMAT_S8_UNORM; } else { + /* no stencil */ stencilFormat = PIPE_FORMAT_NONE; + if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) { + /* use 24-bit Z, undefined stencil channel */ + depthFormat = PIPE_FORMAT_X8Z24_UNORM; + } } -- cgit v1.2.3 From be36f7869e8ecc4b00e414557a9699ba373e6bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 23:32:45 +0100 Subject: i965: Remove extraneous arg to debug_printf. --- src/gallium/drivers/i965simple/brw_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index f00eb34f92..3079485180 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -188,7 +188,7 @@ extern int BRW_DEBUG; } while(0) #define PRINT(...) do { \ - debug_printf(brw->pipe.winsys, __VA_ARGS__); \ + debug_printf(__VA_ARGS__); \ } while(0) struct brw_state_flags { -- cgit v1.2.3 From 9dcb956a0618931c97693f7c74493cf296cfe86c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 8 Aug 2008 12:23:21 +0100 Subject: gallium: Add destroy callback to all *_winsys interfaces. For consistency and to simplify these objects' destruction. --- src/gallium/drivers/cell/ppu/cell_screen.c | 5 +++++ src/gallium/drivers/i915simple/i915_context.c | 3 +++ src/gallium/drivers/i915simple/i915_screen.c | 5 +++++ src/gallium/drivers/i915simple/i915_winsys.h | 2 ++ src/gallium/drivers/i965simple/brw_context.c | 3 +++ src/gallium/drivers/i965simple/brw_screen.c | 5 +++++ src/gallium/drivers/i965simple/brw_winsys.h | 2 ++ src/gallium/drivers/softpipe/sp_screen.c | 5 +++++ src/gallium/include/pipe/p_winsys.h | 2 ++ 9 files changed, 32 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index cf9b68b695..2bf441a0c5 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -132,6 +132,11 @@ cell_is_format_supported( struct pipe_screen *screen, static void cell_destroy_screen( struct pipe_screen *screen ) { + struct pipe_winsys *winsys = screen->winsys; + + if(winsys->destroy) + winsys->destroy(winsys); + FREE(screen); } diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 4c01b8d5b1..e3d19017b5 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -44,6 +44,9 @@ static void i915_destroy( struct pipe_context *pipe ) struct i915_context *i915 = i915_context( pipe ); draw_destroy( i915->draw ); + + if(i915->winsys) + i915->winsys->destroy(i915->winsys); FREE( i915 ); } diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 4b1b8af7da..0afa17bed8 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -193,6 +193,11 @@ i915_is_format_supported( struct pipe_screen *screen, static void i915_destroy_screen( struct pipe_screen *screen ) { + struct pipe_winsys *winsys = screen->winsys; + + if(winsys->destroy) + winsys->destroy(winsys); + FREE(screen); } diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h index 9afaa16a62..81904c2a74 100644 --- a/src/gallium/drivers/i915simple/i915_winsys.h +++ b/src/gallium/drivers/i915simple/i915_winsys.h @@ -75,6 +75,8 @@ struct pipe_screen; */ struct i915_winsys { + void (*destroy)( struct i915_winsys *sws ); + /** * Get the current batch buffer from the winsys. */ diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index a276cc0535..8326f7b9c4 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -52,6 +52,9 @@ static void brw_destroy(struct pipe_context *pipe) { struct brw_context *brw = brw_context(pipe); + if(brw->winsys->destroy) + brw->winsys->destroy(brw->winsys); + FREE(brw); } diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c index 6d8f24d1c4..fadfbf94ab 100644 --- a/src/gallium/drivers/i965simple/brw_screen.c +++ b/src/gallium/drivers/i965simple/brw_screen.c @@ -206,6 +206,11 @@ brw_is_format_supported( struct pipe_screen *screen, static void brw_destroy_screen( struct pipe_screen *screen ) { + struct pipe_winsys *winsys = screen->winsys; + + if(winsys->destroy) + winsys->destroy(winsys); + FREE(screen); } diff --git a/src/gallium/drivers/i965simple/brw_winsys.h b/src/gallium/drivers/i965simple/brw_winsys.h index b67bd73750..ec1e400418 100644 --- a/src/gallium/drivers/i965simple/brw_winsys.h +++ b/src/gallium/drivers/i965simple/brw_winsys.h @@ -112,6 +112,8 @@ enum brw_cache_id { */ struct brw_winsys { + void (*destroy)(struct brw_winsys *); + /** * Reserve space on batch buffer. * diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index ceb5616b5d..f6b3d7ac24 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -139,6 +139,11 @@ softpipe_is_format_supported( struct pipe_screen *screen, static void softpipe_destroy_screen( struct pipe_screen *screen ) { + struct pipe_winsys *winsys = screen->winsys; + + if(winsys->destroy) + winsys->destroy(winsys); + FREE(screen); } diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index 7ebc285192..5d18291dc6 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -62,6 +62,8 @@ struct pipe_surface; */ struct pipe_winsys { + void (*destroy)( struct pipe_winsys *ws ); + /** Returns name of this winsys interface */ const char *(*get_name)( struct pipe_winsys *ws ); -- cgit v1.2.3 From 74d649d9a9e85be6dfec170b018b31626d40914b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 8 Aug 2008 12:31:23 +0100 Subject: trace: Prevent from internal calls from pipe_context to pipe_screen from being traced. --- src/gallium/drivers/trace/tr_context.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index ee8ad5eb97..242a03ccb0 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -999,11 +999,14 @@ trace_context_destroy(struct pipe_context *_pipe) struct pipe_context * trace_context_create(struct pipe_context *pipe) { + struct trace_screen *tr_scr; struct trace_context *tr_ctx; if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) return pipe; + tr_scr = trace_screen(pipe->screen); + tr_ctx = CALLOC_STRUCT(trace_context); if(!tr_ctx) return NULL; @@ -1055,5 +1058,8 @@ trace_context_create(struct pipe_context *pipe) tr_ctx->pipe = pipe; + /* We don't want to trace the pipe calls */ + pipe->screen = tr_scr->screen; + return &tr_ctx->base; } -- cgit v1.2.3 From fcfe63805d1a4b1815dec7d85a21772d02ac12b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 8 Aug 2008 22:13:13 +0100 Subject: trace: Remove unused code. --- src/gallium/drivers/trace/tr_screen.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h index 5d7d667f71..40b844778f 100644 --- a/src/gallium/drivers/trace/tr_screen.h +++ b/src/gallium/drivers/trace/tr_screen.h @@ -44,8 +44,6 @@ struct trace_screen struct pipe_screen *screen; struct trace_stream *stream; - - unsigned event_no; }; -- cgit v1.2.3 From 6c7aff209ca3b310008dd345836ebc020d2db004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 8 Aug 2008 23:11:56 +0100 Subject: trace: Trace pipe_winsys calls. --- src/gallium/drivers/trace/SConscript | 1 + src/gallium/drivers/trace/tr_screen.c | 9 +- src/gallium/drivers/trace/tr_winsys.c | 410 ++++++++++++++++++++++++++++++++++ src/gallium/drivers/trace/tr_winsys.h | 63 ++++++ src/gallium/winsys/xlib/xm_winsys.c | 7 +- 5 files changed, 482 insertions(+), 8 deletions(-) create mode 100644 src/gallium/drivers/trace/tr_winsys.c create mode 100644 src/gallium/drivers/trace/tr_winsys.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript index 30225b5a54..35507e21e4 100644 --- a/src/gallium/drivers/trace/SConscript +++ b/src/gallium/drivers/trace/SConscript @@ -10,6 +10,7 @@ trace = env.ConvenienceLibrary( 'tr_screen.c', 'tr_state.c', 'tr_stream.c', + 'tr_winsys.c', ]) Export('trace') \ No newline at end of file diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 3a48654609..b40d56bcff 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -30,6 +30,7 @@ #include "tr_stream.h" #include "tr_dump.h" #include "tr_state.h" +#include "tr_winsys.h" #include "tr_screen.h" @@ -338,10 +339,6 @@ trace_screen_destroy(struct pipe_screen *_screen) trace_dump_call_end(stream); - trace_dump_trace_end(stream); - - trace_stream_close(tr_scr->stream); - FREE(tr_scr); } @@ -375,11 +372,9 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->screen = screen; - tr_scr->stream = trace_stream_create("gallium", "trace"); + tr_scr->stream = trace_winsys(screen->winsys)->stream; if(!tr_scr->stream) return NULL; - trace_dump_trace_begin(tr_scr->stream, 0); - return &tr_scr->base; } diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c new file mode 100644 index 0000000000..f1ef7cbebb --- /dev/null +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -0,0 +1,410 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" + +#include "tr_stream.h" +#include "tr_dump.h" +#include "tr_state.h" +#include "tr_winsys.h" + + +static const char * +trace_winsys_get_name(struct pipe_winsys *_winsys) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + const char *result; + + trace_dump_call_begin(stream, "pipe_winsys", "get_name"); + + trace_dump_arg(stream, ptr, winsys); + + result = winsys->get_name(winsys); + + trace_dump_ret(stream, string, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_winsys_flush_frontbuffer(struct pipe_winsys *_winsys, + struct pipe_surface *surface, + void *context_private) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + + trace_dump_call_begin(stream, "pipe_winsys", "flush_frontbuffer"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, surface); + trace_dump_arg(stream, ptr, context_private); + + winsys->flush_frontbuffer(winsys, surface, context_private); + + trace_dump_call_end(stream); +} + + +static struct pipe_surface * +trace_winsys_surface_alloc(struct pipe_winsys *_winsys) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + struct pipe_surface *result; + + trace_dump_call_begin(stream, "pipe_winsys", "surface_alloc"); + + trace_dump_arg(stream, ptr, winsys); + + result = winsys->surface_alloc(winsys); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static int +trace_winsys_surface_alloc_storage(struct pipe_winsys *_winsys, + struct pipe_surface *surface, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + int result; + + trace_dump_call_begin(stream, "pipe_winsys", "surface_alloc_storage"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, surface); + trace_dump_arg(stream, uint, width); + trace_dump_arg(stream, uint, height); + trace_dump_arg(stream, format, format); + trace_dump_arg(stream, uint, flags); + trace_dump_arg(stream, uint, tex_usage); + + result = winsys->surface_alloc_storage(winsys, + surface, + width, height, + format, + flags, + tex_usage); + + trace_dump_ret(stream, int, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_winsys_surface_release(struct pipe_winsys *_winsys, + struct pipe_surface **psurface) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + struct pipe_surface *surface = *psurface; + + trace_dump_call_begin(stream, "pipe_winsys", "surface_release"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, surface); + + winsys->surface_release(winsys, psurface); + + trace_dump_call_end(stream); +} + + +static struct pipe_buffer * +trace_winsys_buffer_create(struct pipe_winsys *_winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + struct pipe_buffer *result; + + trace_dump_call_begin(stream, "pipe_winsys", "buffer_create"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, uint, alignment); + trace_dump_arg(stream, uint, usage); + trace_dump_arg(stream, uint, size); + + result = winsys->buffer_create(winsys, alignment, usage, size); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static struct pipe_buffer * +trace_winsys_user_buffer_create(struct pipe_winsys *_winsys, + void *ptr, + unsigned bytes) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + struct pipe_buffer *result; + + trace_dump_call_begin(stream, "pipe_winsys", "user_buffer_create"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, ptr); + trace_dump_arg(stream, uint, bytes); + + result = winsys->user_buffer_create(winsys, ptr, bytes); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void * +trace_winsys_buffer_map(struct pipe_winsys *_winsys, + struct pipe_buffer *buffer, + unsigned usage) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + void *result; + + trace_dump_call_begin(stream, "pipe_winsys", "buffer_map"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, buffer); + trace_dump_arg(stream, uint, usage); + + result = winsys->buffer_map(winsys, buffer, usage); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_winsys_buffer_unmap(struct pipe_winsys *_winsys, + struct pipe_buffer *buffer) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + + trace_dump_call_begin(stream, "pipe_winsys", "buffer_unmap"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, buffer); + + winsys->buffer_unmap(winsys, buffer); + + trace_dump_call_end(stream); +} + + +static void +trace_winsys_buffer_destroy(struct pipe_winsys *_winsys, + struct pipe_buffer *buffer) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + + trace_dump_call_begin(stream, "pipe_winsys", "buffer_destroy"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, buffer); + + winsys->buffer_destroy(winsys, buffer); + + trace_dump_call_end(stream); +} + + +static void +trace_winsys_fence_reference(struct pipe_winsys *_winsys, + struct pipe_fence_handle **pdst, + struct pipe_fence_handle *src) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + struct pipe_fence_handle *dst = *pdst; + + trace_dump_call_begin(stream, "pipe_winsys", "fence_reference"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, dst); + trace_dump_arg(stream, ptr, src); + + winsys->fence_reference(winsys, pdst, src); + + trace_dump_call_end(stream); +} + + +static int +trace_winsys_fence_signalled(struct pipe_winsys *_winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + int result; + + trace_dump_call_begin(stream, "pipe_winsys", "fence_signalled"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, fence); + trace_dump_arg(stream, uint, flag); + + result = winsys->fence_signalled(winsys, fence, flag); + + trace_dump_ret(stream, int, result); + + trace_dump_call_end(stream); + + return result; +} + + +static int +trace_winsys_fence_finish(struct pipe_winsys *_winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + int result; + + trace_dump_call_begin(stream, "pipe_winsys", "fence_finish"); + + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, fence); + trace_dump_arg(stream, uint, flag); + + result = winsys->fence_finish(winsys, fence, flag); + + trace_dump_ret(stream, int, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_winsys_destroy(struct pipe_winsys *_winsys) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct trace_stream *stream = tr_ws->stream; + struct pipe_winsys *winsys = tr_ws->winsys; + + trace_dump_call_begin(stream, "pipe_winsys", "destroy"); + + trace_dump_arg(stream, ptr, winsys); + + winsys->destroy(winsys); + + trace_dump_call_end(stream); + + trace_dump_trace_end(stream); + + trace_stream_close(tr_ws->stream); + + FREE(tr_ws); +} + + +struct pipe_winsys * +trace_winsys_create(struct pipe_winsys *winsys) +{ + struct trace_winsys *tr_ws; + + if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) + return winsys; + + tr_ws = CALLOC_STRUCT(trace_winsys); + if(!tr_ws) + return NULL; + + tr_ws->base.destroy = trace_winsys_destroy; + tr_ws->base.get_name = trace_winsys_get_name; + tr_ws->base.flush_frontbuffer = trace_winsys_flush_frontbuffer; + tr_ws->base.surface_alloc = trace_winsys_surface_alloc; + tr_ws->base.surface_alloc_storage = trace_winsys_surface_alloc_storage; + tr_ws->base.surface_release = trace_winsys_surface_release; + tr_ws->base.buffer_create = trace_winsys_buffer_create; + tr_ws->base.user_buffer_create = trace_winsys_user_buffer_create; + tr_ws->base.buffer_map = trace_winsys_buffer_map; + tr_ws->base.buffer_unmap = trace_winsys_buffer_unmap; + tr_ws->base.buffer_destroy = trace_winsys_buffer_destroy; + tr_ws->base.fence_reference = trace_winsys_fence_reference; + tr_ws->base.fence_signalled = trace_winsys_fence_signalled; + tr_ws->base.fence_finish = trace_winsys_fence_finish; + + tr_ws->winsys = winsys; + + tr_ws->stream = trace_stream_create("gallium", "trace"); + if(!tr_ws->stream) + return NULL; + + trace_dump_trace_begin(tr_ws->stream, 0); + + return &tr_ws->base; +} diff --git a/src/gallium/drivers/trace/tr_winsys.h b/src/gallium/drivers/trace/tr_winsys.h new file mode 100644 index 0000000000..353b0ea7b6 --- /dev/null +++ b/src/gallium/drivers/trace/tr_winsys.h @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TR_WINSYS_H_ +#define TR_WINSYS_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_winsys.h" + + +struct trace_stream; + + +struct trace_winsys +{ + struct pipe_winsys base; + + struct pipe_winsys *winsys; + + struct trace_stream *stream; +}; + + +static INLINE struct trace_winsys * +trace_winsys(struct pipe_winsys *winsys) +{ + assert(winsys); + return (struct trace_winsys *)winsys; +} + + + +struct pipe_winsys * +trace_winsys_create(struct pipe_winsys *winsys); + + +#endif /* TR_WINSYS_H_ */ diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 5a01b6167b..6071a5ad5e 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -55,6 +55,7 @@ #endif #ifdef GALLIUM_TRACE +#include "trace/tr_winsys.h" #include "trace/tr_screen.h" #include "trace/tr_context.h" #endif @@ -650,7 +651,11 @@ xmesa_get_pipe_winsys(struct xmesa_visual *xm_vis) ws->base.get_name = xm_get_name; } - return &ws->base; +#ifdef GALLIUM_TRACE + return trace_winsys_create(&ws->base); +#else + return &ws->base; +#endif } -- cgit v1.2.3 From b65259de6c0a2e77550bbef6b291c6d09dfb5867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 8 Aug 2008 23:53:53 +0100 Subject: trace: Allow to dump binary data. --- src/gallium/drivers/trace/tr_dump.c | 19 ++++++++++++++++++ src/gallium/drivers/trace/tr_dump.h | 1 + src/gallium/drivers/trace/tr_state.c | 38 +++++++++++------------------------- src/gallium/drivers/trace/trace.xsl | 6 ++++++ 4 files changed, 37 insertions(+), 27 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 359a903ab9..f545de30f4 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -272,6 +272,25 @@ void trace_dump_float(struct trace_stream *stream, trace_dump_writef(stream, "%g", value); } +void trace_dump_bytes(struct trace_stream *stream, + const void *data, + long unsigned size) +{ + static char hex_table[] = "0123456789ABCDE"; + const uint8_t *p = data; + long unsigned i; + trace_dump_write(stream, ""); + for(i = 0; i < size; ++i) { + uint8_t byte = *p++; + char str[3]; + str[0] = hex_table[byte >> 4]; + str[1] = hex_table[byte & 0xf]; + str[2] = 0; + trace_dump_write(stream, str); + } + trace_dump_write(stream, ""); +} + void trace_dump_string(struct trace_stream *stream, const char *str) { diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index 7b15da3033..b2367c3288 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -52,6 +52,7 @@ void trace_dump_bool(struct trace_stream *stream, int value); void trace_dump_int(struct trace_stream *stream, long int value); void trace_dump_uint(struct trace_stream *stream, long unsigned value); void trace_dump_float(struct trace_stream *stream, double value); +void trace_dump_bytes(struct trace_stream *stream, const void *data, long unsigned size); void trace_dump_string(struct trace_stream *stream, const char *str); void trace_dump_enum(struct trace_stream *stream, const char *value); void trace_dump_array_begin(struct trace_stream *stream); diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index f17006dd81..e0e48185fa 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -51,23 +51,6 @@ void trace_dump_block(struct trace_stream *stream, } -void trace_dump_buffer(struct trace_stream *stream, - const struct pipe_buffer *buffer) -{ - if(!buffer) { - trace_dump_null(stream); - return; - } - - trace_dump_struct_begin(stream, "pipe_buffer"); - trace_dump_member(stream, uint, buffer, alignment); - trace_dump_member(stream, uint, buffer, usage); - trace_dump_member(stream, uint, buffer, size); - /* TODO: buffer data */ - trace_dump_struct_end(stream); -} - - void trace_dump_template(struct trace_stream *stream, const struct pipe_texture *templat) { @@ -162,7 +145,11 @@ void trace_dump_poly_stipple(struct trace_stream *stream, trace_dump_struct_begin(stream, "pipe_poly_stipple"); - trace_dump_member_array(stream, uint, state, stipple); + trace_dump_member_begin(stream, "stipple"); + trace_dump_bytes(stream, + state->stipple, + sizeof(state->stipple)); + trace_dump_member_end(stream); trace_dump_struct_end(stream); } @@ -243,7 +230,7 @@ void trace_dump_constant_buffer(struct trace_stream *stream, trace_dump_struct_begin(stream, "pipe_constant_buffer"); - trace_dump_member(stream, buffer, state, buffer); + trace_dump_member(stream, ptr, state, buffer); trace_dump_member(stream, uint, state, size); trace_dump_struct_end(stream); @@ -253,21 +240,18 @@ void trace_dump_constant_buffer(struct trace_stream *stream, void trace_dump_shader_state(struct trace_stream *stream, const struct pipe_shader_state *state) { - uint32_t *p = (uint32_t *)state->tokens; - unsigned n = tgsi_num_tokens(state->tokens); - assert(state); if(!state) { trace_dump_null(stream); return; } - assert(sizeof(struct tgsi_token) == 4); - trace_dump_struct_begin(stream, "pipe_shader_state"); trace_dump_member_begin(stream, "tokens"); - trace_dump_array(stream, uint, p, n); + trace_dump_bytes(stream, + state->tokens, + sizeof(struct tgsi_token) * tgsi_num_tokens(state->tokens)); trace_dump_member_end(stream); trace_dump_struct_end(stream); @@ -433,7 +417,7 @@ void trace_dump_surface(struct trace_stream *stream, trace_dump_struct_begin(stream, "pipe_surface"); - trace_dump_member(stream, buffer, state, buffer); + trace_dump_member(stream, ptr, state, buffer); trace_dump_member(stream, format, state, format); trace_dump_member(stream, uint, state, status); trace_dump_member(stream, uint, state, clear_value); @@ -475,7 +459,7 @@ void trace_dump_vertex_buffer(struct trace_stream *stream, trace_dump_member(stream, uint, state, pitch); trace_dump_member(stream, uint, state, max_index); trace_dump_member(stream, uint, state, buffer_offset); - trace_dump_member(stream, buffer, state, buffer); + trace_dump_member(stream, ptr, state, buffer); trace_dump_struct_end(stream); } diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl index 13039d44c4..991e5bf935 100644 --- a/src/gallium/drivers/trace/trace.xsl +++ b/src/gallium/drivers/trace/trace.xsl @@ -100,6 +100,12 @@ along with this program. If not, see . + + + ... + + + " -- cgit v1.2.3 From 3e1974f94ef8796a5ac9e750d47ccb63c677a85b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 9 Aug 2008 11:51:29 +0100 Subject: util: Utility functions to print to a string buffer without overflowing. --- src/gallium/auxiliary/util/u_string.h | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h index 73c88d87b4..abc3232b49 100644 --- a/src/gallium/auxiliary/util/u_string.h +++ b/src/gallium/auxiliary/util/u_string.h @@ -176,6 +176,43 @@ util_memmove(void *dest, const void *src, size_t n) #endif +/** + * Printable string buffer + */ +struct util_strbuf +{ + char *str; + char *ptr; + size_t left; +}; + + +static INLINE void +util_strbuf_init(struct util_strbuf *sbuf, char *str, size_t size) +{ + sbuf->str = str; + sbuf->str[0] = 0; + sbuf->ptr = sbuf->str; + sbuf->left = size; +} + + +static INLINE void +util_strbuf_printf(struct util_strbuf *sbuf, const char *format, ...) +{ + if(sbuf->left > 1) { + size_t written; + va_list ap; + va_start(ap, format); + written = util_vsnprintf(sbuf->ptr, sbuf->left, format, ap); + va_end(ap); + sbuf->ptr += written; + sbuf->left -= written; + } +} + + + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 673489fa5cde4ce8d49918f20f007201a17bc45e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 9 Aug 2008 11:52:27 +0100 Subject: tgsi: Dump shaders to a string too. Again. --- src/gallium/auxiliary/tgsi/tgsi_dump.c | 166 ++++++++++++++++++++++++--------- src/gallium/auxiliary/tgsi/tgsi_dump.h | 7 ++ 2 files changed, 127 insertions(+), 46 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index 0eedb1c91e..29bb530b4d 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -26,6 +26,7 @@ **************************************************************************/ #include "pipe/p_debug.h" +#include "util/u_string.h" #include "tgsi_dump.h" #include "tgsi_iterate.h" @@ -34,28 +35,31 @@ struct dump_ctx struct tgsi_iterate_context iter; uint instno; + + struct util_strbuf *sbuf; }; static void dump_enum( + struct util_strbuf *sbuf, uint e, const char **enums, uint enum_count ) { if (e >= enum_count) - debug_printf( "%u", e ); + util_strbuf_printf( sbuf, "%u", e ); else - debug_printf( "%s", enums[e] ); + util_strbuf_printf( sbuf, "%s", enums[e] ); } -#define EOL() debug_printf( "\n" ) -#define TXT(S) debug_printf( "%s", S ) -#define CHR(C) debug_printf( "%c", C ) -#define UIX(I) debug_printf( "0x%x", I ) -#define UID(I) debug_printf( "%u", I ) -#define SID(I) debug_printf( "%d", I ) -#define FLT(F) debug_printf( "%10.4f", F ) -#define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) +#define EOL() util_strbuf_printf( sbuf, "\n" ) +#define TXT(S) util_strbuf_printf( sbuf, "%s", S ) +#define CHR(C) util_strbuf_printf( sbuf, "%c", C ) +#define UIX(I) util_strbuf_printf( sbuf, "0x%x", I ) +#define UID(I) util_strbuf_printf( sbuf, "%u", I ) +#define SID(I) util_strbuf_printf( sbuf, "%d", I ) +#define FLT(F) util_strbuf_printf( sbuf, "%10.4f", F ) +#define ENM(E,ENUMS) dump_enum( sbuf, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) static const char *processor_type_names[] = { @@ -266,6 +270,7 @@ static const char *modulate_names[TGSI_MODULATE_COUNT] = static void _dump_register( + struct util_strbuf *sbuf, uint file, int first, int last ) @@ -282,6 +287,7 @@ _dump_register( static void _dump_register_ind( + struct util_strbuf *sbuf, uint file, int index, uint ind_file, @@ -303,6 +309,7 @@ _dump_register_ind( static void _dump_writemask( + struct util_strbuf *sbuf, uint writemask ) { if (writemask != TGSI_WRITEMASK_XYZW) { @@ -318,17 +325,23 @@ _dump_writemask( } } -void -tgsi_dump_declaration( - const struct tgsi_full_declaration *decl ) +static boolean +iter_declaration( + struct tgsi_iterate_context *iter, + struct tgsi_full_declaration *decl ) { + struct dump_ctx *ctx = (struct dump_ctx *) iter; + struct util_strbuf *sbuf = ctx->sbuf; + TXT( "DCL " ); _dump_register( + sbuf, decl->Declaration.File, decl->DeclarationRange.First, decl->DeclarationRange.Last ); _dump_writemask( + sbuf, decl->Declaration.UsageMask ); if (decl->Declaration.Semantic) { @@ -346,21 +359,35 @@ tgsi_dump_declaration( ENM( decl->Declaration.Interpolate, interpolate_names ); EOL(); -} -static boolean -iter_declaration( - struct tgsi_iterate_context *iter, - struct tgsi_full_declaration *decl ) -{ - tgsi_dump_declaration( decl ); return TRUE; } void -tgsi_dump_immediate( - const struct tgsi_full_immediate *imm ) +tgsi_dump_declaration( + const struct tgsi_full_declaration *decl ) { + static char str[1024]; + struct util_strbuf sbuf; + struct dump_ctx ctx; + + util_strbuf_init(&sbuf, str, sizeof(str)); + + ctx.sbuf = &sbuf; + + iter_declaration( &ctx.iter, (struct tgsi_full_declaration *)decl ); + + debug_printf("%s", str); +} + +static boolean +iter_immediate( + struct tgsi_iterate_context *iter, + struct tgsi_full_immediate *imm ) +{ + struct dump_ctx *ctx = (struct dump_ctx *) iter; + struct util_strbuf *sbuf = ctx->sbuf; + uint i; TXT( "IMM " ); @@ -382,22 +409,36 @@ tgsi_dump_immediate( TXT( " }" ); EOL(); -} -static boolean -iter_immediate( - struct tgsi_iterate_context *iter, - struct tgsi_full_immediate *imm ) -{ - tgsi_dump_immediate( imm ); return TRUE; } void -tgsi_dump_instruction( - const struct tgsi_full_instruction *inst, - uint instno ) +tgsi_dump_immediate( + const struct tgsi_full_immediate *imm ) { + static char str[1024]; + struct util_strbuf sbuf; + struct dump_ctx ctx; + + util_strbuf_init(&sbuf, str, sizeof(str)); + + ctx.sbuf = &sbuf; + + iter_immediate( &ctx.iter, (struct tgsi_full_immediate *)imm ); + + debug_printf("%s", str); +} + +static boolean +iter_instruction( + struct tgsi_iterate_context *iter, + struct tgsi_full_instruction *inst ) +{ + struct dump_ctx *ctx = (struct dump_ctx *) iter; + struct util_strbuf *sbuf = ctx->sbuf; + uint instno = ctx->instno++; + uint i; boolean first_reg = TRUE; @@ -426,11 +467,12 @@ tgsi_dump_instruction( CHR( ' ' ); _dump_register( + sbuf, dst->DstRegister.File, dst->DstRegister.Index, dst->DstRegister.Index ); ENM( dst->DstRegisterExtModulate.Modulate, modulate_names ); - _dump_writemask( dst->DstRegister.WriteMask ); + _dump_writemask( sbuf, dst->DstRegister.WriteMask ); first_reg = FALSE; } @@ -457,6 +499,7 @@ tgsi_dump_instruction( if (src->SrcRegister.Indirect) { _dump_register_ind( + sbuf, src->SrcRegister.File, src->SrcRegister.Index, src->SrcRegisterInd.File, @@ -464,6 +507,7 @@ tgsi_dump_instruction( } else { _dump_register( + sbuf, src->SrcRegister.File, src->SrcRegister.Index, src->SrcRegister.Index ); @@ -529,38 +573,55 @@ tgsi_dump_instruction( } EOL(); + + return TRUE; } -static boolean -iter_instruction( - struct tgsi_iterate_context *iter, - struct tgsi_full_instruction *inst ) +void +tgsi_dump_instruction( + const struct tgsi_full_instruction *inst, + uint instno ) { - struct dump_ctx *ctx = (struct dump_ctx *) iter; + static char str[1024]; + struct util_strbuf sbuf; + struct dump_ctx ctx; - tgsi_dump_instruction( inst, ctx->instno++ ); - return TRUE; + util_strbuf_init(&sbuf, str, sizeof(str)); + + ctx.instno = instno; + ctx.sbuf = &sbuf; + + iter_instruction( &ctx.iter, (struct tgsi_full_instruction *)inst ); + + debug_printf("%s", str); } static boolean prolog( - struct tgsi_iterate_context *ctx ) + struct tgsi_iterate_context *iter ) { - ENM( ctx->processor.Processor, processor_type_names ); - UID( ctx->version.MajorVersion ); + struct dump_ctx *ctx = (struct dump_ctx *) iter; + struct util_strbuf *sbuf = ctx->sbuf; + ENM( iter->processor.Processor, processor_type_names ); + UID( iter->version.MajorVersion ); CHR( '.' ); - UID( ctx->version.MinorVersion ); + UID( iter->version.MinorVersion ); EOL(); return TRUE; } void -tgsi_dump( +tgsi_dump_str( const struct tgsi_token *tokens, - uint flags ) + uint flags, + char *str, + size_t size) { + struct util_strbuf sbuf; struct dump_ctx ctx; + util_strbuf_init(&sbuf, str, size); + /* sanity checks */ assert( strcmp( opcode_names[TGSI_OPCODE_CONT], "CONT" ) == 0 ); assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); @@ -572,6 +633,19 @@ tgsi_dump( ctx.iter.epilog = NULL; ctx.instno = 0; + ctx.sbuf = &sbuf; tgsi_iterate_shader( tokens, &ctx.iter ); } + +void +tgsi_dump( + const struct tgsi_token *tokens, + uint flags ) +{ + static char str[4096]; + + tgsi_dump_str(tokens, flags, str, sizeof(str)); + + debug_printf("%s", str); +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.h b/src/gallium/auxiliary/tgsi/tgsi_dump.h index 51c230b5db..ad1e647ec9 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.h @@ -34,6 +34,13 @@ extern "C" { #endif +void +tgsi_dump_str( + const struct tgsi_token *tokens, + uint flags, + char *str, + size_t size); + void tgsi_dump( const struct tgsi_token *tokens, -- cgit v1.2.3 From 696067e781977ad54bb31b3843355701124f1b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 9 Aug 2008 11:52:53 +0100 Subject: trace: Dump shaders as text. --- src/gallium/drivers/trace/tr_state.c | 9 ++++---- src/gallium/drivers/trace/trace.xsl | 40 +++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index e0e48185fa..9ffe77146d 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -27,7 +27,7 @@ #include "pipe/p_compiler.h" -#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_dump.h" #include "tr_dump.h" #include "tr_state.h" @@ -240,18 +240,19 @@ void trace_dump_constant_buffer(struct trace_stream *stream, void trace_dump_shader_state(struct trace_stream *stream, const struct pipe_shader_state *state) { + static char str[8192]; assert(state); if(!state) { trace_dump_null(stream); return; } + tgsi_dump_str(state->tokens, 0, str, sizeof(str)); + trace_dump_struct_begin(stream, "pipe_shader_state"); trace_dump_member_begin(stream, "tokens"); - trace_dump_bytes(stream, - state->tokens, - sizeof(struct tgsi_token) * tgsi_num_tokens(state->tokens)); + trace_dump_string(stream, str); trace_dump_member_end(stream); trace_dump_struct_end(stream); diff --git a/src/gallium/drivers/trace/trace.xsl b/src/gallium/drivers/trace/trace.xsl index 991e5bf935..9cd621e7ab 100644 --- a/src/gallium/drivers/trace/trace.xsl +++ b/src/gallium/drivers/trace/trace.xsl @@ -109,7 +109,9 @@ along with this program. If not, see . " - + + + " @@ -144,4 +146,40 @@ along with this program. If not, see . + + + + + + +
      + + + +
      + + + +
      +
      + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From dc31bb5076df914ad16e063fdcc46fd2ecba9dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 9 Aug 2008 11:53:16 +0100 Subject: gallium: Invert include order. --- src/gallium/include/pipe/p_format.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 0a9cad8993..d9aa5792a4 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -28,11 +28,11 @@ #ifndef PIPE_FORMAT_H #define PIPE_FORMAT_H -#include "util/u_string.h" - #include "p_compiler.h" #include "p_debug.h" +#include "util/u_string.h" + #ifdef __cplusplus extern "C" { #endif -- cgit v1.2.3 From 376f2cbb190389807c8ba6df401e06743ead9eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 9 Aug 2008 11:53:56 +0100 Subject: trace: Prevent tracing internal pipe driver calls. --- src/gallium/drivers/trace/tr_context.c | 9 ++++----- src/gallium/drivers/trace/tr_screen.c | 3 +++ 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 242a03ccb0..47a217ec7c 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -30,6 +30,7 @@ #include "tr_stream.h" #include "tr_dump.h" #include "tr_state.h" +#include "tr_winsys.h" #include "tr_screen.h" #include "tr_context.h" @@ -999,14 +1000,11 @@ trace_context_destroy(struct pipe_context *_pipe) struct pipe_context * trace_context_create(struct pipe_context *pipe) { - struct trace_screen *tr_scr; struct trace_context *tr_ctx; if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) return pipe; - tr_scr = trace_screen(pipe->screen); - tr_ctx = CALLOC_STRUCT(trace_context); if(!tr_ctx) return NULL; @@ -1058,8 +1056,9 @@ trace_context_create(struct pipe_context *pipe) tr_ctx->pipe = pipe; - /* We don't want to trace the pipe calls */ - pipe->screen = tr_scr->screen; + /* We don't want to trace the internal pipe calls */ + pipe->winsys = trace_winsys(pipe->winsys)->winsys; + pipe->screen = trace_screen(pipe->screen)->screen; return &tr_ctx->base; } diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index b40d56bcff..de885abae2 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -376,5 +376,8 @@ trace_screen_create(struct pipe_screen *screen) if(!tr_scr->stream) return NULL; + /* We don't want to trace the internal pipe calls */ + screen->winsys = trace_winsys(screen->winsys)->winsys; + return &tr_scr->base; } -- cgit v1.2.3 From 5549d35db5323829702099af6e53a8dd7c451524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 9 Aug 2008 11:54:35 +0100 Subject: trace: Dump writes to pipe_buffers. --- src/gallium/drivers/trace/tr_winsys.c | 54 ++++++++++++++++++++++++++++++++++- src/gallium/drivers/trace/tr_winsys.h | 3 ++ 2 files changed, 56 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index f1ef7cbebb..964da5677b 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -26,6 +26,7 @@ **************************************************************************/ #include "pipe/p_util.h" +#include "util/u_hash_table.h" #include "tr_stream.h" #include "tr_dump.h" @@ -33,6 +34,18 @@ #include "tr_winsys.h" +static unsigned trace_buffer_hash(void *buffer) +{ + return (unsigned)(uintptr_t)buffer; +} + + +static int trace_buffer_compare(void *buffer1, void *buffer2) +{ + return (char *)buffer2 - (char *)buffer1; +} + + static const char * trace_winsys_get_name(struct pipe_winsys *_winsys) { @@ -232,6 +245,13 @@ trace_winsys_buffer_map(struct pipe_winsys *_winsys, trace_dump_call_end(stream); + if(result) { + if(usage & PIPE_BUFFER_USAGE_CPU_WRITE) { + assert(!hash_table_get(tr_ws->buffer_maps, buffer)); + hash_table_set(tr_ws->buffer_maps, buffer, result); + } + } + return result; } @@ -243,6 +263,30 @@ trace_winsys_buffer_unmap(struct pipe_winsys *_winsys, struct trace_winsys *tr_ws = trace_winsys(_winsys); struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; + const void *map; + + map = hash_table_get(tr_ws->buffer_maps, buffer); + if(map) { + trace_dump_call_begin(stream, "", "memcpy"); + + trace_dump_arg_begin(stream, "dst"); + trace_dump_ptr(stream, map); + trace_dump_arg_end(stream); + + trace_dump_arg_begin(stream, "src"); + trace_dump_bytes(stream, map, buffer->size); + trace_dump_arg_end(stream); + + trace_dump_arg_begin(stream, "size"); + trace_dump_uint(stream, buffer->size); + trace_dump_arg_end(stream); + + trace_dump_call_end(stream); + + winsys->buffer_unmap(winsys, buffer); + + hash_table_remove(tr_ws->buffer_maps, buffer); + } trace_dump_call_begin(stream, "pipe_winsys", "buffer_unmap"); @@ -365,6 +409,8 @@ trace_winsys_destroy(struct pipe_winsys *_winsys) trace_dump_trace_end(stream); + hash_table_destroy(tr_ws->buffer_maps); + trace_stream_close(tr_ws->stream); FREE(tr_ws); @@ -399,11 +445,17 @@ trace_winsys_create(struct pipe_winsys *winsys) tr_ws->base.fence_finish = trace_winsys_fence_finish; tr_ws->winsys = winsys; - + tr_ws->stream = trace_stream_create("gallium", "trace"); if(!tr_ws->stream) return NULL; + tr_ws->buffer_maps = hash_table_create(trace_buffer_hash, + trace_buffer_compare); + if(!tr_ws->buffer_maps) + return NULL; + + trace_dump_trace_begin(tr_ws->stream, 0); return &tr_ws->base; diff --git a/src/gallium/drivers/trace/tr_winsys.h b/src/gallium/drivers/trace/tr_winsys.h index 353b0ea7b6..a3576da867 100644 --- a/src/gallium/drivers/trace/tr_winsys.h +++ b/src/gallium/drivers/trace/tr_winsys.h @@ -34,6 +34,7 @@ #include "pipe/p_winsys.h" +struct hash_table; struct trace_stream; @@ -44,6 +45,8 @@ struct trace_winsys struct pipe_winsys *winsys; struct trace_stream *stream; + + struct hash_table *buffer_maps; }; -- cgit v1.2.3 From 22604727e469f4a9881f722be319670d5cde4519 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 11 Aug 2008 14:59:26 -0600 Subject: gallium: emit sprite coords (gl_PointCoord) --- src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index d40a07f4ae..54590984c6 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -50,6 +50,8 @@ struct widepoint_stage { uint num_texcoords; int psize_slot; + + int point_coord_fs_input; /**< input for pointcoord (and fog) */ }; @@ -84,6 +86,13 @@ static void set_texcoords(const struct widepoint_stage *wide, v->data[j][3] = tc[3]; } } + + if (wide->point_coord_fs_input >= 0) { + /* put gl_PointCoord into extra vertex output's zw components */ + uint k = wide->stage.draw->extra_vp_outputs.slot; + v->data[k][2] = tc[0]; + v->data[k][3] = tc[1]; + } } @@ -208,6 +217,18 @@ static void widepoint_first_point( struct draw_stage *stage, } } wide->num_texcoords = j; + + /* find fragment shader PointCoord/Fog input */ + wide->point_coord_fs_input = 0; /* XXX fix this! */ + + /* setup extra vp output */ + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_FOG; + draw->extra_vp_outputs.semantic_index = 0; + draw->extra_vp_outputs.slot = draw->vs.num_vs_outputs; + } + else { + wide->point_coord_fs_input = -1; + draw->extra_vp_outputs.slot = 0; } wide->psize_slot = -1; -- cgit v1.2.3 From d506fc0acf68c861c4e160a3d931a3f81757242b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 11 Aug 2008 15:01:35 -0600 Subject: gallium: debug/print vertex tweak --- src/gallium/drivers/softpipe/sp_setup.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index b48eec730b..14aacd73c2 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -1272,10 +1272,7 @@ void setup_prepare( struct setup_context *setup ) } /* Note: nr_attrs is only used for debugging (vertex printing) */ - { - const struct sp_fragment_shader *fs = setup->softpipe->fs; - setup->quad.nr_attrs = fs->info.num_inputs + 1; /* +1 for vert pos */ - } + setup->quad.nr_attrs = draw_num_vs_outputs(sp->draw); sp->quad.first->begin(sp->quad.first); -- cgit v1.2.3 From 66ef96f6dc4cd898edb862e45965795fac46caed Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 12 Aug 2008 11:30:50 +0200 Subject: softpipe: Include missing header. --- src/gallium/drivers/softpipe/sp_setup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 14aacd73c2..b7f2f16307 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -39,6 +39,7 @@ #include "sp_quad.h" #include "sp_state.h" #include "sp_prim_setup.h" +#include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_vertex.h" #include "pipe/p_util.h" -- cgit v1.2.3 From 23e8c92543d95c216f3459a5618611c079e86174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 9 Aug 2008 15:07:40 +0100 Subject: python: Update the documentation. --- src/gallium/state_trackers/python/README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README index 75341aa28c..8ab88ab2f8 100644 --- a/src/gallium/state_trackers/python/README +++ b/src/gallium/state_trackers/python/README @@ -7,7 +7,7 @@ To build you'll need: * Python (with development packages) * SCons * SWIG -* Python Imaging Library (for the samples) +* Python Imaging Library with TK support (for the samples) Invoke scons on the top dir as @@ -19,9 +19,9 @@ To use do and then try running - python src/gallium/state_trackers/python/samples/simple.py + python src/gallium/state_trackers/python/samples/tri.py -which should create a simple.png +which should show a triangle. This is still in experimental phase, and there many limitations to what you can -- cgit v1.2.3 From 91f6032919f8e5718004bb7ac0ee2b015fb403d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 10 Aug 2008 16:24:15 +0100 Subject: trace: Trace texture depth. --- src/gallium/drivers/trace/tr_state.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index 9ffe77146d..3c7b007bfe 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -73,6 +73,10 @@ void trace_dump_template(struct trace_stream *stream, trace_dump_array(stream, uint, templat->height, 1); trace_dump_member_end(stream); + trace_dump_member_begin(stream, "depth"); + trace_dump_array(stream, uint, templat->depth, 1); + trace_dump_member_end(stream); + trace_dump_member_begin(stream, "block"); trace_dump_block(stream, &templat->block); trace_dump_member_end(stream); -- cgit v1.2.3 From 94cf4f15c3a94311ffeb670459e285d2c70a5d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 10 Aug 2008 16:24:43 +0100 Subject: trace: Trace winsys/screen/context creation. --- src/gallium/drivers/trace/tr_context.c | 135 +++++++++++++-------------------- src/gallium/drivers/trace/tr_context.h | 5 ++ src/gallium/drivers/trace/tr_screen.c | 13 +++- src/gallium/drivers/trace/tr_winsys.c | 8 +- 4 files changed, 71 insertions(+), 90 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 47a217ec7c..c9c15b2bb9 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -40,8 +40,7 @@ trace_context_set_edgeflags(struct pipe_context *_pipe, const unsigned *bitfield) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "set_edgeflags"); @@ -61,8 +60,7 @@ trace_context_draw_arrays(struct pipe_context *_pipe, unsigned mode, unsigned start, unsigned count) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; boolean result; @@ -90,8 +88,7 @@ trace_context_draw_elements(struct pipe_context *_pipe, unsigned mode, unsigned start, unsigned count) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; boolean result; @@ -125,8 +122,7 @@ trace_context_draw_range_elements(struct pipe_context *_pipe, unsigned count) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; boolean result; @@ -159,8 +155,7 @@ trace_context_create_query(struct pipe_context *_pipe, unsigned query_type) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; struct pipe_query *result; @@ -184,8 +179,7 @@ trace_context_destroy_query(struct pipe_context *_pipe, struct pipe_query *query) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "destroy_query"); @@ -204,8 +198,7 @@ trace_context_begin_query(struct pipe_context *_pipe, struct pipe_query *query) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "begin_query"); @@ -224,8 +217,7 @@ trace_context_end_query(struct pipe_context *_pipe, struct pipe_query *query) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "end_query"); @@ -246,8 +238,7 @@ trace_context_get_query_result(struct pipe_context *_pipe, uint64 *presult) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; uint64 result; boolean _result; @@ -273,8 +264,7 @@ trace_context_create_blend_state(struct pipe_context *_pipe, const struct pipe_blend_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; @@ -296,8 +286,7 @@ trace_context_bind_blend_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "bind_blend_state"); @@ -316,8 +305,7 @@ trace_context_delete_blend_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "delete_blend_state"); @@ -336,8 +324,7 @@ trace_context_create_sampler_state(struct pipe_context *_pipe, const struct pipe_sampler_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; @@ -361,8 +348,7 @@ trace_context_bind_sampler_states(struct pipe_context *_pipe, unsigned num_states, void **states) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "bind_sampler_states"); @@ -382,8 +368,7 @@ trace_context_delete_sampler_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "delete_sampler_state"); @@ -402,8 +387,7 @@ trace_context_create_rasterizer_state(struct pipe_context *_pipe, const struct pipe_rasterizer_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; @@ -427,8 +411,7 @@ trace_context_bind_rasterizer_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "bind_rasterizer_state"); @@ -447,8 +430,7 @@ trace_context_delete_rasterizer_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "delete_rasterizer_state"); @@ -467,8 +449,7 @@ trace_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe, const struct pipe_depth_stencil_alpha_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; @@ -490,8 +471,7 @@ trace_context_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "bind_depth_stencil_alpha_state"); @@ -510,8 +490,7 @@ trace_context_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "delete_depth_stencil_alpha_state"); @@ -530,8 +509,7 @@ trace_context_create_fs_state(struct pipe_context *_pipe, const struct pipe_shader_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; @@ -555,8 +533,7 @@ trace_context_bind_fs_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "bind_fs_state"); @@ -575,8 +552,7 @@ trace_context_delete_fs_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "delete_fs_state"); @@ -595,8 +571,7 @@ trace_context_create_vs_state(struct pipe_context *_pipe, const struct pipe_shader_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; @@ -620,8 +595,7 @@ trace_context_bind_vs_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "bind_vs_state"); @@ -640,8 +614,7 @@ trace_context_delete_vs_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "delete_vs_state"); @@ -660,8 +633,7 @@ trace_context_set_blend_color(struct pipe_context *_pipe, const struct pipe_blend_color *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "set_blend_color"); @@ -680,8 +652,7 @@ trace_context_set_clip_state(struct pipe_context *_pipe, const struct pipe_clip_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "set_clip_state"); @@ -701,8 +672,7 @@ trace_context_set_constant_buffer(struct pipe_context *_pipe, const struct pipe_constant_buffer *buffer) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "set_constant_buffer"); @@ -723,8 +693,7 @@ trace_context_set_framebuffer_state(struct pipe_context *_pipe, const struct pipe_framebuffer_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "set_framebuffer_state"); @@ -743,8 +712,7 @@ trace_context_set_polygon_stipple(struct pipe_context *_pipe, const struct pipe_poly_stipple *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "set_polygon_stipple"); @@ -763,8 +731,7 @@ trace_context_set_scissor_state(struct pipe_context *_pipe, const struct pipe_scissor_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "set_scissor_state"); @@ -783,8 +750,7 @@ trace_context_set_viewport_state(struct pipe_context *_pipe, const struct pipe_viewport_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "set_viewport_state"); @@ -804,8 +770,7 @@ trace_context_set_sampler_textures(struct pipe_context *_pipe, struct pipe_texture **textures) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "set_sampler_textures"); @@ -826,8 +791,7 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe, const struct pipe_vertex_buffer *buffers) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "set_vertex_buffers"); @@ -851,8 +815,7 @@ trace_context_set_vertex_elements(struct pipe_context *_pipe, const struct pipe_vertex_element *elements) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "set_vertex_elements"); @@ -881,8 +844,7 @@ trace_context_surface_copy(struct pipe_context *_pipe, unsigned width, unsigned height) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "surface_copy"); @@ -914,8 +876,7 @@ trace_context_surface_fill(struct pipe_context *_pipe, unsigned value) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "surface_fill"); @@ -939,8 +900,7 @@ trace_context_clear(struct pipe_context *_pipe, unsigned clearValue) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "clear"); @@ -961,8 +921,7 @@ trace_context_flush(struct pipe_context *_pipe, struct pipe_fence_handle **fence) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "flush"); @@ -981,8 +940,7 @@ static INLINE void trace_context_destroy(struct pipe_context *_pipe) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_screen *tr_scr = trace_screen(_pipe->screen); - struct trace_stream *stream = tr_scr->stream; + struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; trace_dump_call_begin(stream, "pipe_context", "destroy"); @@ -1000,6 +958,7 @@ trace_context_destroy(struct pipe_context *_pipe) struct pipe_context * trace_context_create(struct pipe_context *pipe) { + struct trace_stream *stream; struct trace_context *tr_ctx; if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) @@ -1055,10 +1014,18 @@ trace_context_create(struct pipe_context *pipe) tr_ctx->base.flush = trace_context_flush; tr_ctx->pipe = pipe; + tr_ctx->stream = stream = trace_winsys(pipe->winsys)->stream; /* We don't want to trace the internal pipe calls */ pipe->winsys = trace_winsys(pipe->winsys)->winsys; pipe->screen = trace_screen(pipe->screen)->screen; + trace_dump_call_begin(stream, "", "pipe_context_create"); + trace_dump_arg_begin(stream, "screen"); + trace_dump_ptr(stream, pipe->screen); + trace_dump_arg_end(stream); + trace_dump_ret(stream, ptr, pipe); + trace_dump_call_end(stream); + return &tr_ctx->base; } diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 80fb5980d6..2c0b0c72e4 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -34,11 +34,16 @@ #include "pipe/p_context.h" +struct trace_stream; + + struct trace_context { struct pipe_context base; struct pipe_context *pipe; + + struct trace_stream *stream; }; diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index de885abae2..27c218039e 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -346,6 +346,7 @@ trace_screen_destroy(struct pipe_screen *_screen) struct pipe_screen * trace_screen_create(struct pipe_screen *screen) { + struct trace_stream *stream; struct trace_screen *tr_scr; if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) @@ -371,13 +372,17 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->base.surface_unmap = trace_screen_surface_unmap; tr_scr->screen = screen; - - tr_scr->stream = trace_winsys(screen->winsys)->stream; - if(!tr_scr->stream) - return NULL; + tr_scr->stream = stream = trace_winsys(screen->winsys)->stream; /* We don't want to trace the internal pipe calls */ screen->winsys = trace_winsys(screen->winsys)->winsys; + trace_dump_call_begin(stream, "", "pipe_screen_create"); + trace_dump_arg_begin(stream, "winsys"); + trace_dump_ptr(stream, screen->winsys); + trace_dump_arg_end(stream); + trace_dump_ret(stream, ptr, screen); + trace_dump_call_end(stream); + return &tr_scr->base; } diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index 964da5677b..128e502ffc 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -420,6 +420,7 @@ trace_winsys_destroy(struct pipe_winsys *_winsys) struct pipe_winsys * trace_winsys_create(struct pipe_winsys *winsys) { + struct trace_stream *stream; struct trace_winsys *tr_ws; if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) @@ -446,7 +447,7 @@ trace_winsys_create(struct pipe_winsys *winsys) tr_ws->winsys = winsys; - tr_ws->stream = trace_stream_create("gallium", "trace"); + tr_ws->stream = stream = trace_stream_create("gallium", "trace"); if(!tr_ws->stream) return NULL; @@ -455,8 +456,11 @@ trace_winsys_create(struct pipe_winsys *winsys) if(!tr_ws->buffer_maps) return NULL; - trace_dump_trace_begin(tr_ws->stream, 0); + trace_dump_call_begin(stream, "", "pipe_winsys_create"); + trace_dump_ret(stream, ptr, winsys); + trace_dump_call_end(stream); + return &tr_ws->base; } -- cgit v1.2.3 From e5a606883f24980dd8e2378c25e6fb3b8f1937ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 10 Aug 2008 18:51:23 +0100 Subject: trace: Fix hexadecimal dumping. --- src/gallium/drivers/trace/tr_dump.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index f545de30f4..5269c4ddc8 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -276,17 +276,16 @@ void trace_dump_bytes(struct trace_stream *stream, const void *data, long unsigned size) { - static char hex_table[] = "0123456789ABCDE"; + static const char hex_table[16] = "0123456789ABCDEF"; const uint8_t *p = data; long unsigned i; trace_dump_write(stream, ""); for(i = 0; i < size; ++i) { uint8_t byte = *p++; - char str[3]; - str[0] = hex_table[byte >> 4]; - str[1] = hex_table[byte & 0xf]; - str[2] = 0; - trace_dump_write(stream, str); + char hex[2]; + hex[0] = hex_table[byte >> 4]; + hex[1] = hex_table[byte & 0xf]; + trace_stream_write(stream, hex, 2); } trace_dump_write(stream, ""); } -- cgit v1.2.3 From a304d271185af935974850055da74ec8263b00e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 10 Aug 2008 18:52:00 +0100 Subject: python: Allow writing to buffers. --- src/gallium/state_trackers/python/gallium.i | 37 +++++++++++++++++++++------ src/gallium/state_trackers/python/st_device.c | 33 ++++++++++++++++++++++++ src/gallium/state_trackers/python/st_device.h | 14 ++++++++++ 3 files changed, 76 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 284ecb827d..8f731ca905 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -65,8 +65,7 @@ %rename(Context) st_context; %rename(Texture) pipe_texture; %rename(Surface) pipe_surface; - -%rename(Buffer) pipe_buffer; +%rename(Buffer) st_buffer; %rename(BlendColor) pipe_blend_color; %rename(Blend) pipe_blend_state; @@ -88,13 +87,13 @@ %nodefaultctor st_context; %nodefaultctor pipe_texture; %nodefaultctor pipe_surface; -%nodefaultctor pipe_buffer; +%nodefaultctor st_buffer; %nodefaultdtor st_device; %nodefaultdtor st_context; %nodefaultdtor pipe_texture; %nodefaultdtor pipe_surface; -%nodefaultdtor pipe_buffer; +%nodefaultdtor st_buffer; %ignore pipe_texture::screen; @@ -114,6 +113,9 @@ struct st_device { struct st_context { }; +struct st_buffer { +}; + %newobject st_device::texture_create; %newobject st_device::context_create; @@ -197,9 +199,9 @@ struct st_context { return $self->screen->texture_create($self->screen, &templat); } - struct pipe_buffer * + struct st_buffer * buffer_create(unsigned size, unsigned alignment = 0, unsigned usage = 0) { - return $self->screen->winsys->buffer_create($self->screen->winsys, alignment, usage, size); + return st_buffer_create($self, alignment, usage, size); } }; @@ -323,10 +325,10 @@ struct st_context { $self->pipe->draw_arrays($self->pipe, mode, start, count); } - void draw_elements( struct pipe_buffer *indexBuffer, + void draw_elements( struct st_buffer *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { - $self->pipe->draw_elements($self->pipe, indexBuffer, indexSize, mode, start, count); + $self->pipe->draw_elements($self->pipe, indexBuffer->buffer, indexSize, mode, start, count); } void draw_vertices(unsigned prim, @@ -522,6 +524,25 @@ error1: }; +%extend st_buffer { + + ~st_buffer() { + st_buffer_destroy($self); + } + + void write( const char *STRING, unsigned LENGTH, unsigned offset = 0) { + struct pipe_winsys *winsys = $self->st_dev->screen->winsys; + char *map; + + map = winsys->buffer_map(winsys, $self->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + if(!map) { + memcpy(map + offset, STRING, LENGTH); + winsys->buffer_unmap(winsys, $self->buffer); + } + } +}; + + %extend pipe_framebuffer_state { pipe_framebuffer_state(void) { diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index 2e53a83eea..fbd56712e0 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -266,3 +266,36 @@ st_context_create(struct st_device *st_dev) return st_ctx; } + + +void +st_buffer_destroy(struct st_buffer *st_buf) +{ + if(st_buf) { + struct pipe_winsys *winsys = st_buf->st_dev->screen->winsys; + pipe_buffer_reference(winsys, &st_buf->buffer, NULL); + FREE(st_buf); + } +} + + +struct st_buffer * +st_buffer_create(struct st_device *st_dev, + unsigned alignment, unsigned usage, unsigned size) +{ + struct pipe_winsys *winsys = st_dev->screen->winsys; + struct st_buffer *st_buf; + + st_buf = CALLOC_STRUCT(st_buffer); + if(!st_buf) + return NULL; + + st_buf->st_dev = st_dev; + + st_buf->buffer = winsys->buffer_create(winsys, alignment, usage, size); + if(!st_buf->buffer) + st_buffer_destroy(st_buf); + + return st_buf; +} + diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h index 2d95c2da73..5b7adbe1a0 100644 --- a/src/gallium/state_trackers/python/st_device.h +++ b/src/gallium/state_trackers/python/st_device.h @@ -38,6 +38,13 @@ struct pipe_context; struct st_winsys; +struct st_buffer { + struct st_device *st_dev; + + struct pipe_buffer *buffer; +}; + + struct st_context { struct st_device *st_dev; @@ -65,6 +72,13 @@ struct st_device { }; +struct st_buffer * +st_buffer_create(struct st_device *st_dev, + unsigned alignment, unsigned usage, unsigned size); + +void +st_buffer_destroy(struct st_buffer *st_buf); + struct st_context * st_context_create(struct st_device *st_dev); -- cgit v1.2.3 From a318325b516b53fc321669453e4abe53c51f917a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 10 Aug 2008 18:54:10 +0100 Subject: trace: Zero the buffers to avoid dumping uninitialized memory. --- src/gallium/drivers/trace/tr_winsys.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index 128e502ffc..60a69626c0 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -26,6 +26,7 @@ **************************************************************************/ #include "pipe/p_util.h" +#include "pipe/p_state.h" #include "util/u_hash_table.h" #include "tr_stream.h" @@ -178,7 +179,7 @@ trace_winsys_buffer_create(struct pipe_winsys *_winsys, struct trace_winsys *tr_ws = trace_winsys(_winsys); struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; - struct pipe_buffer *result; + struct pipe_buffer *buffer; trace_dump_call_begin(stream, "pipe_winsys", "buffer_create"); @@ -187,13 +188,23 @@ trace_winsys_buffer_create(struct pipe_winsys *_winsys, trace_dump_arg(stream, uint, usage); trace_dump_arg(stream, uint, size); - result = winsys->buffer_create(winsys, alignment, usage, size); + buffer = winsys->buffer_create(winsys, alignment, usage, size); - trace_dump_ret(stream, ptr, result); + trace_dump_ret(stream, ptr, buffer); trace_dump_call_end(stream); + + /* Zero the buffer to avoid dumping uninitialized memory */ + if(buffer->usage & PIPE_BUFFER_USAGE_CPU_WRITE) { + void *map; + map = winsys->buffer_map(winsys, buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + if(map) { + memset(map, 0, buffer->size); + winsys->buffer_unmap(winsys, buffer); + } + } - return result; + return buffer; } -- cgit v1.2.3 From 8dbb3011a11ff3b6e8ebcf19e64ed4fbef17356b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 11 Aug 2008 00:15:07 +0100 Subject: trace: Replace buffer_map+memcpy+buffer_unmap by buffer_write --- src/gallium/drivers/trace/tr_winsys.c | 39 +++++++---------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index 60a69626c0..0a43f1f7f4 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -240,30 +240,18 @@ trace_winsys_buffer_map(struct pipe_winsys *_winsys, unsigned usage) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; - void *result; - - trace_dump_call_begin(stream, "pipe_winsys", "buffer_map"); - - trace_dump_arg(stream, ptr, winsys); - trace_dump_arg(stream, ptr, buffer); - trace_dump_arg(stream, uint, usage); - - result = winsys->buffer_map(winsys, buffer, usage); - - trace_dump_ret(stream, ptr, result); - - trace_dump_call_end(stream); + void *map; - if(result) { + map = winsys->buffer_map(winsys, buffer, usage); + if(map) { if(usage & PIPE_BUFFER_USAGE_CPU_WRITE) { assert(!hash_table_get(tr_ws->buffer_maps, buffer)); - hash_table_set(tr_ws->buffer_maps, buffer, result); + hash_table_set(tr_ws->buffer_maps, buffer, map); } } - return result; + return map; } @@ -278,13 +266,11 @@ trace_winsys_buffer_unmap(struct pipe_winsys *_winsys, map = hash_table_get(tr_ws->buffer_maps, buffer); if(map) { - trace_dump_call_begin(stream, "", "memcpy"); + trace_dump_call_begin(stream, "pipe_winsys", "buffer_write"); - trace_dump_arg_begin(stream, "dst"); - trace_dump_ptr(stream, map); - trace_dump_arg_end(stream); + trace_dump_arg(stream, ptr, buffer); - trace_dump_arg_begin(stream, "src"); + trace_dump_arg_begin(stream, "data"); trace_dump_bytes(stream, map, buffer->size); trace_dump_arg_end(stream); @@ -294,19 +280,10 @@ trace_winsys_buffer_unmap(struct pipe_winsys *_winsys, trace_dump_call_end(stream); - winsys->buffer_unmap(winsys, buffer); - hash_table_remove(tr_ws->buffer_maps, buffer); } - trace_dump_call_begin(stream, "pipe_winsys", "buffer_unmap"); - - trace_dump_arg(stream, ptr, winsys); - trace_dump_arg(stream, ptr, buffer); - winsys->buffer_unmap(winsys, buffer); - - trace_dump_call_end(stream); } -- cgit v1.2.3 From b5f7dd0c08dbe3f140630345c331aeccaf2a7a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 11 Aug 2008 00:16:20 +0100 Subject: python: Add unsigned arrays. --- src/gallium/state_trackers/python/gallium.i | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 8f731ca905..9d9a50b520 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -58,6 +58,7 @@ %include "carrays.i" %array_class(unsigned char, ByteArray); %array_class(int, IntArray); +%array_class(unsigned, UnsignedArray); %array_class(float, FloatArray); @@ -606,4 +607,4 @@ error1: void dump(unsigned flags = 0) { tgsi_dump($self->tokens, flags); } -} \ No newline at end of file +} -- cgit v1.2.3 From e7f1ac39be5ab8c627f66a4a8488697c274079e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 11 Aug 2008 14:06:24 +0100 Subject: python: Split the interface definition file in smaller ones. --- src/gallium/state_trackers/python/gallium.i | 524 +------------------------- src/gallium/state_trackers/python/p_context.i | 232 ++++++++++++ src/gallium/state_trackers/python/p_device.i | 130 +++++++ src/gallium/state_trackers/python/p_state.i | 103 +++++ src/gallium/state_trackers/python/p_texture.i | 192 ++++++++++ 5 files changed, 662 insertions(+), 519 deletions(-) create mode 100644 src/gallium/state_trackers/python/p_context.i create mode 100644 src/gallium/state_trackers/python/p_device.i create mode 100644 src/gallium/state_trackers/python/p_state.i create mode 100644 src/gallium/state_trackers/python/p_texture.i (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 9d9a50b520..4e21eef7be 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -84,527 +84,13 @@ %rename(VertexElement) pipe_vertex_element; %rename(Viewport) pipe_viewport_state; -%nodefaultctor st_device; -%nodefaultctor st_context; -%nodefaultctor pipe_texture; -%nodefaultctor pipe_surface; -%nodefaultctor st_buffer; -%nodefaultdtor st_device; -%nodefaultdtor st_context; -%nodefaultdtor pipe_texture; -%nodefaultdtor pipe_surface; -%nodefaultdtor st_buffer; - -%ignore pipe_texture::screen; - -%ignore pipe_surface::winsys; -%immutable pipe_surface::texture; -%immutable pipe_surface::buffer; - -%include "p_format.i"; %include "pipe/p_defines.h"; -%include "pipe/p_state.h"; %include "pipe/p_shader_tokens.h"; +%include "p_format.i" +%include "p_device.i" +%include "p_context.i" +%include "p_texture.i" +%include "p_state.i" -struct st_device { -}; - -struct st_context { -}; - -struct st_buffer { -}; - - -%newobject st_device::texture_create; -%newobject st_device::context_create; -%newobject st_device::buffer_create; - -%extend st_device { - - st_device(int hardware = 1) { - return st_device_create(hardware ? TRUE : FALSE); - } - - ~st_device() { - st_device_destroy($self); - } - - const char * get_name( void ) { - return $self->screen->get_name($self->screen); - } - - const char * get_vendor( void ) { - return $self->screen->get_vendor($self->screen); - } - - /** - * Query an integer-valued capability/parameter/limit - * \param param one of PIPE_CAP_x - */ - int get_param( int param ) { - return $self->screen->get_param($self->screen, param); - } - - /** - * Query a float-valued capability/parameter/limit - * \param param one of PIPE_CAP_x - */ - float get_paramf( int param ) { - return $self->screen->get_paramf($self->screen, param); - } - - /** - * Check if the given pipe_format is supported as a texture or - * drawing surface. - * \param type one of PIPE_TEXTURE, PIPE_SURFACE - */ - int is_format_supported( enum pipe_format format, - enum pipe_texture_target target, - unsigned tex_usage, - unsigned geom_flags ) { - return $self->screen->is_format_supported( $self->screen, - format, - target, - tex_usage, - geom_flags ); - } - - struct st_context * - context_create(void) { - return st_context_create($self); - } - - struct pipe_texture * - texture_create( - enum pipe_format format, - unsigned width, - unsigned height, - unsigned depth = 1, - unsigned last_level = 0, - enum pipe_texture_target target = PIPE_TEXTURE_2D, - unsigned tex_usage = 0 - ) { - struct pipe_texture templat; - memset(&templat, 0, sizeof(templat)); - templat.format = format; - pf_get_block(templat.format, &templat.block); - templat.width[0] = width; - templat.height[0] = height; - templat.depth[0] = depth; - templat.last_level = last_level; - templat.target = target; - templat.tex_usage = tex_usage; - return $self->screen->texture_create($self->screen, &templat); - } - - struct st_buffer * - buffer_create(unsigned size, unsigned alignment = 0, unsigned usage = 0) { - return st_buffer_create($self, alignment, usage, size); - } - -}; - - -%extend st_context { - - ~st_context() { - st_context_destroy($self); - } - - /* - * State functions (create/bind/destroy state objects) - */ - - void set_blend( const struct pipe_blend_state *state ) { - cso_set_blend($self->cso, state); - } - - void set_sampler( unsigned index, const struct pipe_sampler_state *state ) { - cso_single_sampler($self->cso, index, state); - cso_single_sampler_done($self->cso); - } - - void set_rasterizer( const struct pipe_rasterizer_state *state ) { - cso_set_rasterizer($self->cso, state); - } - - void set_depth_stencil_alpha(const struct pipe_depth_stencil_alpha_state *state) { - cso_set_depth_stencil_alpha($self->cso, state); - } - - void set_fragment_shader( const struct pipe_shader_state *state ) { - void *fs; - - fs = $self->pipe->create_fs_state($self->pipe, state); - if(!fs) - return; - - if(cso_set_fragment_shader_handle($self->cso, fs) != PIPE_OK) - return; - - cso_delete_fragment_shader($self->cso, $self->fs); - $self->fs = fs; - } - - void set_vertex_shader( const struct pipe_shader_state *state ) { - void *vs; - - vs = $self->pipe->create_vs_state($self->pipe, state); - if(!vs) - return; - - if(cso_set_vertex_shader_handle($self->cso, vs) != PIPE_OK) - return; - - cso_delete_vertex_shader($self->cso, $self->vs); - $self->vs = vs; - } - - /* - * Parameter-like state (or properties) - */ - - void set_blend_color(const struct pipe_blend_color *state ) { - cso_set_blend_color($self->cso, state); - } - - void set_clip(const struct pipe_clip_state *state ) { - $self->pipe->set_clip_state($self->pipe, state); - } - - void set_constant_buffer(unsigned shader, unsigned index, - const struct pipe_constant_buffer *buf ) { - $self->pipe->set_constant_buffer($self->pipe, shader, index, buf); - } - - void set_framebuffer(const struct pipe_framebuffer_state *state ) { - cso_set_framebuffer($self->cso, state); - } - - void set_polygon_stipple(const struct pipe_poly_stipple *state ) { - $self->pipe->set_polygon_stipple($self->pipe, state); - } - - void set_scissor(const struct pipe_scissor_state *state ) { - $self->pipe->set_scissor_state($self->pipe, state); - } - - void set_viewport(const struct pipe_viewport_state *state) { - cso_set_viewport($self->cso, state); - } - - void set_sampler_texture(unsigned index, - struct pipe_texture *texture) { - if(!texture) - texture = $self->default_texture; - pipe_texture_reference(&$self->sampler_textures[index], texture); - $self->pipe->set_sampler_textures($self->pipe, - PIPE_MAX_SAMPLERS, - $self->sampler_textures); - } - - void set_vertex_buffer(unsigned index, - const struct pipe_vertex_buffer *buffer) { - memcpy(&$self->vertex_buffers[index], buffer, sizeof(*buffer)); - $self->pipe->set_vertex_buffers($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_buffers); - } - - void set_vertex_element(unsigned index, - const struct pipe_vertex_element *element) { - memcpy(&$self->vertex_elements[index], element, sizeof(*element)); - $self->pipe->set_vertex_elements($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_elements); - } - - /* - * Draw functions - */ - - void draw_arrays(unsigned mode, unsigned start, unsigned count) { - $self->pipe->draw_arrays($self->pipe, mode, start, count); - } - - void draw_elements( struct st_buffer *indexBuffer, - unsigned indexSize, - unsigned mode, unsigned start, unsigned count) { - $self->pipe->draw_elements($self->pipe, indexBuffer->buffer, indexSize, mode, start, count); - } - - void draw_vertices(unsigned prim, - unsigned num_verts, - unsigned num_attribs, - const float *vertices) - { - struct pipe_context *pipe = $self->pipe; - struct pipe_winsys *winsys = pipe->winsys; - struct pipe_buffer *vbuf; - float *map; - unsigned size; - - size = num_verts * num_attribs * 4 * sizeof(float); - - vbuf = winsys->buffer_create(winsys, - 32, - PIPE_BUFFER_USAGE_VERTEX, - size); - if(!vbuf) - goto error1; - - map = winsys->buffer_map(winsys, vbuf, PIPE_BUFFER_USAGE_CPU_WRITE); - if (!map) - goto error2; - memcpy(map, vertices, size); - pipe->winsys->buffer_unmap(pipe->winsys, vbuf); - - util_draw_vertex_buffer(pipe, vbuf, prim, num_verts, num_attribs); - -error2: - pipe_buffer_reference(pipe->winsys, &vbuf, NULL); -error1: - ; - } - - void - flush(void) { - struct pipe_fence_handle *fence = NULL; - $self->pipe->flush($self->pipe, PIPE_FLUSH_RENDER_CACHE, &fence); - /* TODO: allow asynchronous operation */ - $self->pipe->winsys->fence_finish( $self->pipe->winsys, fence, 0 ); - $self->pipe->winsys->fence_reference( $self->pipe->winsys, &fence, NULL ); - } - - /* - * Surface functions - */ - - void surface_copy(int do_flip, - struct pipe_surface *dest, - unsigned destx, unsigned desty, - struct pipe_surface *src, - unsigned srcx, unsigned srcy, - unsigned width, unsigned height) { - $self->pipe->surface_copy($self->pipe, do_flip, dest, destx, desty, src, srcx, srcy, width, height); - } - - void surface_fill(struct pipe_surface *dst, - unsigned x, unsigned y, - unsigned width, unsigned height, - unsigned value) { - $self->pipe->surface_fill($self->pipe, dst, x, y, width, height, value); - } - - void surface_clear(struct pipe_surface *surface, unsigned value = 0) { - $self->pipe->clear($self->pipe, surface, value); - } - -}; - - -%newobject pipe_texture::get_surface; - -%extend pipe_texture { - - ~pipe_texture() { - struct pipe_texture *ptr = $self; - pipe_texture_reference(&ptr, NULL); - } - - unsigned get_width(unsigned level=0) { - return $self->width[level]; - } - - unsigned get_height(unsigned level=0) { - return $self->height[level]; - } - - unsigned get_depth(unsigned level=0) { - return $self->depth[level]; - } - - unsigned get_nblocksx(unsigned level=0) { - return $self->nblocksx[level]; - } - - unsigned get_nblocksy(unsigned level=0) { - return $self->nblocksy[level]; - } - - /** Get a surface which is a "view" into a texture */ - struct pipe_surface * - get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0, unsigned usage=0 ) - { - struct pipe_screen *screen = $self->screen; - return screen->get_tex_surface(screen, $self, face, level, zslice, usage); - } - -}; - - -%extend pipe_surface { - - ~pipe_surface() { - struct pipe_surface *ptr = $self; - pipe_surface_reference(&ptr, NULL); - } - - // gets mapped to pipe_surface_map automatically - void * map( unsigned flags ); - - // gets mapped to pipe_surface_unmap automatically - void unmap( void ); - - void - get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, unsigned char *raw, unsigned stride) { - pipe_get_tile_raw($self, x, y, w, h, raw, stride); - } - - void - put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned char *raw, unsigned stride) { - pipe_put_tile_raw($self, x, y, w, h, raw, stride); - } - - void - get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *rgba) { - pipe_get_tile_rgba($self, x, y, w, h, rgba); - } - - void - put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba) { - pipe_put_tile_rgba($self, x, y, w, h, rgba); - } - - void - get_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z) { - pipe_get_tile_z($self, x, y, w, h, z); - } - - void - put_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z) { - pipe_put_tile_z($self, x, y, w, h, z); - } - - void - sample_rgba(float *rgba) { - st_sample_surface($self, rgba); - } - - unsigned - compare_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba, float tol = 0.0) - { - float *rgba2; - const float *p1; - const float *p2; - unsigned i, j, n; - - rgba2 = MALLOC(h*w*4*sizeof(float)); - if(!rgba2) - return ~0; - - pipe_get_tile_rgba($self, x, y, w, h, rgba2); - - p1 = rgba; - p2 = rgba2; - n = 0; - for(i = h*w; i; --i) { - unsigned differs = 0; - for(j = 4; j; --j) { - float delta = *p2++ - *p1++; - if (delta < -tol || delta > tol) - differs = 1; - } - n += differs; - } - - FREE(rgba2); - - return n; - } - -}; - - -%extend st_buffer { - - ~st_buffer() { - st_buffer_destroy($self); - } - - void write( const char *STRING, unsigned LENGTH, unsigned offset = 0) { - struct pipe_winsys *winsys = $self->st_dev->screen->winsys; - char *map; - - map = winsys->buffer_map(winsys, $self->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); - if(!map) { - memcpy(map + offset, STRING, LENGTH); - winsys->buffer_unmap(winsys, $self->buffer); - } - } -}; - - -%extend pipe_framebuffer_state { - - pipe_framebuffer_state(void) { - return CALLOC_STRUCT(pipe_framebuffer_state); - } - - ~pipe_framebuffer_state() { - unsigned index; - for(index = 0; index < PIPE_MAX_COLOR_BUFS; ++index) - pipe_surface_reference(&$self->cbufs[index], NULL); - pipe_surface_reference(&$self->zsbuf, NULL); - FREE($self); - } - - void - set_cbuf(unsigned index, struct pipe_surface *surface) { - pipe_surface_reference(&$self->cbufs[index], surface); - } - - void - set_zsbuf(struct pipe_surface *surface) { - pipe_surface_reference(&$self->zsbuf, surface); - } - -}; - - -%extend pipe_shader_state { - - pipe_shader_state(const char *text, unsigned num_tokens = 1024) { - struct tgsi_token *tokens; - struct pipe_shader_state *shader; - - tokens = MALLOC(num_tokens * sizeof(struct tgsi_token)); - if(!tokens) - goto error1; - - if(tgsi_text_translate(text, tokens, num_tokens ) != TRUE) - goto error2; - - shader = CALLOC_STRUCT(pipe_shader_state); - if(!shader) - goto error3; - - shader->tokens = tokens; - - return shader; - -error3: -error2: - FREE(tokens); -error1: - return NULL; - } - - ~pipe_shader_state() { - FREE((void*)$self->tokens); - FREE($self); - } - - void dump(unsigned flags = 0) { - tgsi_dump($self->tokens, flags); - } -} diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i new file mode 100644 index 0000000000..172dc7256c --- /dev/null +++ b/src/gallium/state_trackers/python/p_context.i @@ -0,0 +1,232 @@ + /************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca + */ + +%nodefaultctor st_context; +%nodefaultdtor st_context; + +struct st_context { +}; + +%extend st_context { + + ~st_context() { + st_context_destroy($self); + } + + /* + * State functions (create/bind/destroy state objects) + */ + + void set_blend( const struct pipe_blend_state *state ) { + cso_set_blend($self->cso, state); + } + + void set_sampler( unsigned index, const struct pipe_sampler_state *state ) { + cso_single_sampler($self->cso, index, state); + cso_single_sampler_done($self->cso); + } + + void set_rasterizer( const struct pipe_rasterizer_state *state ) { + cso_set_rasterizer($self->cso, state); + } + + void set_depth_stencil_alpha(const struct pipe_depth_stencil_alpha_state *state) { + cso_set_depth_stencil_alpha($self->cso, state); + } + + void set_fragment_shader( const struct pipe_shader_state *state ) { + void *fs; + + fs = $self->pipe->create_fs_state($self->pipe, state); + if(!fs) + return; + + if(cso_set_fragment_shader_handle($self->cso, fs) != PIPE_OK) + return; + + cso_delete_fragment_shader($self->cso, $self->fs); + $self->fs = fs; + } + + void set_vertex_shader( const struct pipe_shader_state *state ) { + void *vs; + + vs = $self->pipe->create_vs_state($self->pipe, state); + if(!vs) + return; + + if(cso_set_vertex_shader_handle($self->cso, vs) != PIPE_OK) + return; + + cso_delete_vertex_shader($self->cso, $self->vs); + $self->vs = vs; + } + + /* + * Parameter-like state (or properties) + */ + + void set_blend_color(const struct pipe_blend_color *state ) { + cso_set_blend_color($self->cso, state); + } + + void set_clip(const struct pipe_clip_state *state ) { + $self->pipe->set_clip_state($self->pipe, state); + } + + void set_constant_buffer(unsigned shader, unsigned index, + const struct pipe_constant_buffer *buf ) { + $self->pipe->set_constant_buffer($self->pipe, shader, index, buf); + } + + void set_framebuffer(const struct pipe_framebuffer_state *state ) { + cso_set_framebuffer($self->cso, state); + } + + void set_polygon_stipple(const struct pipe_poly_stipple *state ) { + $self->pipe->set_polygon_stipple($self->pipe, state); + } + + void set_scissor(const struct pipe_scissor_state *state ) { + $self->pipe->set_scissor_state($self->pipe, state); + } + + void set_viewport(const struct pipe_viewport_state *state) { + cso_set_viewport($self->cso, state); + } + + void set_sampler_texture(unsigned index, + struct pipe_texture *texture) { + if(!texture) + texture = $self->default_texture; + pipe_texture_reference(&$self->sampler_textures[index], texture); + $self->pipe->set_sampler_textures($self->pipe, + PIPE_MAX_SAMPLERS, + $self->sampler_textures); + } + + void set_vertex_buffer(unsigned index, + const struct pipe_vertex_buffer *buffer) { + memcpy(&$self->vertex_buffers[index], buffer, sizeof(*buffer)); + $self->pipe->set_vertex_buffers($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_buffers); + } + + void set_vertex_element(unsigned index, + const struct pipe_vertex_element *element) { + memcpy(&$self->vertex_elements[index], element, sizeof(*element)); + $self->pipe->set_vertex_elements($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_elements); + } + + /* + * Draw functions + */ + + void draw_arrays(unsigned mode, unsigned start, unsigned count) { + $self->pipe->draw_arrays($self->pipe, mode, start, count); + } + + void draw_elements( struct st_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) { + $self->pipe->draw_elements($self->pipe, indexBuffer->buffer, indexSize, mode, start, count); + } + + void draw_vertices(unsigned prim, + unsigned num_verts, + unsigned num_attribs, + const float *vertices) + { + struct pipe_context *pipe = $self->pipe; + struct pipe_winsys *winsys = pipe->winsys; + struct pipe_buffer *vbuf; + float *map; + unsigned size; + + size = num_verts * num_attribs * 4 * sizeof(float); + + vbuf = winsys->buffer_create(winsys, + 32, + PIPE_BUFFER_USAGE_VERTEX, + size); + if(!vbuf) + goto error1; + + map = winsys->buffer_map(winsys, vbuf, PIPE_BUFFER_USAGE_CPU_WRITE); + if (!map) + goto error2; + memcpy(map, vertices, size); + pipe->winsys->buffer_unmap(pipe->winsys, vbuf); + + util_draw_vertex_buffer(pipe, vbuf, prim, num_verts, num_attribs); + +error2: + pipe_buffer_reference(pipe->winsys, &vbuf, NULL); +error1: + ; + } + + void + flush(void) { + struct pipe_fence_handle *fence = NULL; + $self->pipe->flush($self->pipe, PIPE_FLUSH_RENDER_CACHE, &fence); + /* TODO: allow asynchronous operation */ + $self->pipe->winsys->fence_finish( $self->pipe->winsys, fence, 0 ); + $self->pipe->winsys->fence_reference( $self->pipe->winsys, &fence, NULL ); + } + + /* + * Surface functions + */ + + void surface_copy(int do_flip, + struct pipe_surface *dest, + unsigned destx, unsigned desty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) { + $self->pipe->surface_copy($self->pipe, do_flip, dest, destx, desty, src, srcx, srcy, width, height); + } + + void surface_fill(struct pipe_surface *dst, + unsigned x, unsigned y, + unsigned width, unsigned height, + unsigned value) { + $self->pipe->surface_fill($self->pipe, dst, x, y, width, height, value); + } + + void surface_clear(struct pipe_surface *surface, unsigned value = 0) { + $self->pipe->clear($self->pipe, surface, value); + } + +}; diff --git a/src/gallium/state_trackers/python/p_device.i b/src/gallium/state_trackers/python/p_device.i new file mode 100644 index 0000000000..84fd2e4349 --- /dev/null +++ b/src/gallium/state_trackers/python/p_device.i @@ -0,0 +1,130 @@ + /************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca + */ + + +%nodefaultctor st_device; +%nodefaultdtor st_device; + + +struct st_device { +}; + +%newobject st_device::texture_create; +%newobject st_device::context_create; +%newobject st_device::buffer_create; + +%extend st_device { + + st_device(int hardware = 1) { + return st_device_create(hardware ? TRUE : FALSE); + } + + ~st_device() { + st_device_destroy($self); + } + + const char * get_name( void ) { + return $self->screen->get_name($self->screen); + } + + const char * get_vendor( void ) { + return $self->screen->get_vendor($self->screen); + } + + /** + * Query an integer-valued capability/parameter/limit + * \param param one of PIPE_CAP_x + */ + int get_param( int param ) { + return $self->screen->get_param($self->screen, param); + } + + /** + * Query a float-valued capability/parameter/limit + * \param param one of PIPE_CAP_x + */ + float get_paramf( int param ) { + return $self->screen->get_paramf($self->screen, param); + } + + /** + * Check if the given pipe_format is supported as a texture or + * drawing surface. + * \param type one of PIPE_TEXTURE, PIPE_SURFACE + */ + int is_format_supported( enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags ) { + return $self->screen->is_format_supported( $self->screen, + format, + target, + tex_usage, + geom_flags ); + } + + struct st_context * + context_create(void) { + return st_context_create($self); + } + + struct pipe_texture * + texture_create( + enum pipe_format format, + unsigned width, + unsigned height, + unsigned depth = 1, + unsigned last_level = 0, + enum pipe_texture_target target = PIPE_TEXTURE_2D, + unsigned tex_usage = 0 + ) { + struct pipe_texture templat; + memset(&templat, 0, sizeof(templat)); + templat.format = format; + pf_get_block(templat.format, &templat.block); + templat.width[0] = width; + templat.height[0] = height; + templat.depth[0] = depth; + templat.last_level = last_level; + templat.target = target; + templat.tex_usage = tex_usage; + return $self->screen->texture_create($self->screen, &templat); + } + + struct st_buffer * + buffer_create(unsigned size, unsigned alignment = 0, unsigned usage = 0) { + return st_buffer_create($self, alignment, usage, size); + } + +}; diff --git a/src/gallium/state_trackers/python/p_state.i b/src/gallium/state_trackers/python/p_state.i new file mode 100644 index 0000000000..9834229b4b --- /dev/null +++ b/src/gallium/state_trackers/python/p_state.i @@ -0,0 +1,103 @@ + /************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca + */ + +%module gallium; + +%include "pipe/p_state.h"; + + +%extend pipe_framebuffer_state { + + pipe_framebuffer_state(void) { + return CALLOC_STRUCT(pipe_framebuffer_state); + } + + ~pipe_framebuffer_state() { + unsigned index; + for(index = 0; index < PIPE_MAX_COLOR_BUFS; ++index) + pipe_surface_reference(&$self->cbufs[index], NULL); + pipe_surface_reference(&$self->zsbuf, NULL); + FREE($self); + } + + void + set_cbuf(unsigned index, struct pipe_surface *surface) { + pipe_surface_reference(&$self->cbufs[index], surface); + } + + void + set_zsbuf(struct pipe_surface *surface) { + pipe_surface_reference(&$self->zsbuf, surface); + } + +}; + + +%extend pipe_shader_state { + + pipe_shader_state(const char *text, unsigned num_tokens = 1024) { + struct tgsi_token *tokens; + struct pipe_shader_state *shader; + + tokens = MALLOC(num_tokens * sizeof(struct tgsi_token)); + if(!tokens) + goto error1; + + if(tgsi_text_translate(text, tokens, num_tokens ) != TRUE) + goto error2; + + shader = CALLOC_STRUCT(pipe_shader_state); + if(!shader) + goto error3; + + shader->tokens = tokens; + + return shader; + +error3: +error2: + FREE(tokens); +error1: + return NULL; + } + + ~pipe_shader_state() { + FREE((void*)$self->tokens); + FREE($self); + } + + void dump(unsigned flags = 0) { + tgsi_dump($self->tokens, flags); + } +} diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i new file mode 100644 index 0000000000..fd38e0733f --- /dev/null +++ b/src/gallium/state_trackers/python/p_texture.i @@ -0,0 +1,192 @@ + /************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca + */ + + +%nodefaultctor pipe_texture; +%nodefaultctor pipe_surface; +%nodefaultctor st_buffer; + +%nodefaultdtor pipe_texture; +%nodefaultdtor pipe_surface; +%nodefaultdtor st_buffer; + +%ignore pipe_texture::screen; + +%ignore pipe_surface::winsys; +%immutable pipe_surface::texture; +%immutable pipe_surface::buffer; + +%newobject pipe_texture::get_surface; + + +%extend pipe_texture { + + ~pipe_texture() { + struct pipe_texture *ptr = $self; + pipe_texture_reference(&ptr, NULL); + } + + unsigned get_width(unsigned level=0) { + return $self->width[level]; + } + + unsigned get_height(unsigned level=0) { + return $self->height[level]; + } + + unsigned get_depth(unsigned level=0) { + return $self->depth[level]; + } + + unsigned get_nblocksx(unsigned level=0) { + return $self->nblocksx[level]; + } + + unsigned get_nblocksy(unsigned level=0) { + return $self->nblocksy[level]; + } + + /** Get a surface which is a "view" into a texture */ + struct pipe_surface * + get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0, unsigned usage=0 ) + { + struct pipe_screen *screen = $self->screen; + return screen->get_tex_surface(screen, $self, face, level, zslice, usage); + } + +}; + + +%extend pipe_surface { + + ~pipe_surface() { + struct pipe_surface *ptr = $self; + pipe_surface_reference(&ptr, NULL); + } + + // gets mapped to pipe_surface_map automatically + void * map( unsigned flags ); + + // gets mapped to pipe_surface_unmap automatically + void unmap( void ); + + void + get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, unsigned char *raw, unsigned stride) { + pipe_get_tile_raw($self, x, y, w, h, raw, stride); + } + + void + put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned char *raw, unsigned stride) { + pipe_put_tile_raw($self, x, y, w, h, raw, stride); + } + + void + get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *rgba) { + pipe_get_tile_rgba($self, x, y, w, h, rgba); + } + + void + put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba) { + pipe_put_tile_rgba($self, x, y, w, h, rgba); + } + + void + get_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z) { + pipe_get_tile_z($self, x, y, w, h, z); + } + + void + put_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z) { + pipe_put_tile_z($self, x, y, w, h, z); + } + + void + sample_rgba(float *rgba) { + st_sample_surface($self, rgba); + } + + unsigned + compare_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba, float tol = 0.0) + { + float *rgba2; + const float *p1; + const float *p2; + unsigned i, j, n; + + rgba2 = MALLOC(h*w*4*sizeof(float)); + if(!rgba2) + return ~0; + + pipe_get_tile_rgba($self, x, y, w, h, rgba2); + + p1 = rgba; + p2 = rgba2; + n = 0; + for(i = h*w; i; --i) { + unsigned differs = 0; + for(j = 4; j; --j) { + float delta = *p2++ - *p1++; + if (delta < -tol || delta > tol) + differs = 1; + } + n += differs; + } + + FREE(rgba2); + + return n; + } + +}; + +struct st_buffer { +}; + +%extend st_buffer { + + ~st_buffer() { + st_buffer_destroy($self); + } + + void write( const char *STRING, unsigned LENGTH, unsigned offset = 0) { + struct pipe_winsys *winsys = $self->st_dev->screen->winsys; + char *map; + + map = winsys->buffer_map(winsys, $self->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + if(!map) { + memcpy(map + offset, STRING, LENGTH); + winsys->buffer_unmap(winsys, $self->buffer); + } + } +}; -- cgit v1.2.3 From ae0c9b56d4bec52f9accabbcaf8d42ef41a0153c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 11 Aug 2008 14:31:04 +0100 Subject: python: Simplify setting the constant buffers. --- src/gallium/state_trackers/python/p_context.i | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 172dc7256c..df07f3bc47 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -106,8 +106,13 @@ struct st_context { } void set_constant_buffer(unsigned shader, unsigned index, - const struct pipe_constant_buffer *buf ) { - $self->pipe->set_constant_buffer($self->pipe, shader, index, buf); + const struct pipe_constant_buffer *buf ) + { + struct pipe_constant_buffer state; + memset(&state, 0, sizeof(state)); + state.buffer = buf->buffer; + state.size = buf->buffer->size; + $self->pipe->set_constant_buffer($self->pipe, shader, index, &state); } void set_framebuffer(const struct pipe_framebuffer_state *state ) { -- cgit v1.2.3 From ca826d79a64d46e7f3bffff22640f148c044cdad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 11 Aug 2008 16:55:30 +0100 Subject: gallium: Name pipe_depth_stencil_alpha_state member structures. So that the previously anonymous depth/stencil/alpha structures can be identified in the traces. This is just syntactic sugar: it does not break source or binary compatibility. --- src/gallium/include/pipe/p_state.h | 51 ++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 21 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 2401305eb7..4d0f3597e6 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -170,29 +170,38 @@ struct pipe_shader_state }; +struct pipe_depth_state { + unsigned enabled:1; /**< depth test enabled? */ + unsigned writemask:1; /**< allow depth buffer writes? */ + unsigned func:3; /**< depth test func (PIPE_FUNC_x) */ + unsigned occlusion_count:1; /**< do occlusion counting? */ +}; + + +struct pipe_stencil_state { + unsigned enabled:1; /**< stencil[0]: stencil enabled, stencil[1]: two-side enabled */ + unsigned func:3; /**< PIPE_FUNC_x */ + unsigned fail_op:3; /**< PIPE_STENCIL_OP_x */ + unsigned zpass_op:3; /**< PIPE_STENCIL_OP_x */ + unsigned zfail_op:3; /**< PIPE_STENCIL_OP_x */ + ubyte ref_value; + ubyte value_mask; + ubyte write_mask; +}; + + +struct pipe_alpha_state { + unsigned enabled:1; + unsigned func:3; /**< PIPE_FUNC_x */ + float ref; /**< reference value */ +}; + + struct pipe_depth_stencil_alpha_state { - struct { - unsigned enabled:1; /**< depth test enabled? */ - unsigned writemask:1; /**< allow depth buffer writes? */ - unsigned func:3; /**< depth test func (PIPE_FUNC_x) */ - unsigned occlusion_count:1; /**< do occlusion counting? */ - } depth; - struct { - unsigned enabled:1; /**< stencil[0]: stencil enabled, stencil[1]: two-side enabled */ - unsigned func:3; /**< PIPE_FUNC_x */ - unsigned fail_op:3; /**< PIPE_STENCIL_OP_x */ - unsigned zpass_op:3; /**< PIPE_STENCIL_OP_x */ - unsigned zfail_op:3; /**< PIPE_STENCIL_OP_x */ - ubyte ref_value; - ubyte value_mask; - ubyte write_mask; - } stencil[2]; /**< [0] = front, [1] = back */ - struct { - unsigned enabled:1; - unsigned func:3; /**< PIPE_FUNC_x */ - float ref; /**< reference value */ - } alpha; + struct pipe_depth_state depth; + struct pipe_stencil_state stencil[2]; /**< [0] = front, [1] = back */ + struct pipe_alpha_state alpha; }; -- cgit v1.2.3 From 166b939d523a8683f1aee819f73e002e627a49ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 11 Aug 2008 16:56:08 +0100 Subject: trace: Dump pipe_{depth,stencil,alpha}_state names. --- src/gallium/drivers/trace/tr_state.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index 3c7b007bfe..961705b9ee 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -277,7 +277,7 @@ void trace_dump_depth_stencil_alpha_state(struct trace_stream *stream, trace_dump_struct_begin(stream, "pipe_depth_stencil_alpha_state"); trace_dump_member_begin(stream, "depth"); - trace_dump_struct_begin(stream, ""); + trace_dump_struct_begin(stream, "pipe_depth_state"); trace_dump_member(stream, bool, &state->depth, enabled); trace_dump_member(stream, bool, &state->depth, writemask); trace_dump_member(stream, uint, &state->depth, func); @@ -289,7 +289,7 @@ void trace_dump_depth_stencil_alpha_state(struct trace_stream *stream, trace_dump_array_begin(stream); for(i = 0; i < Elements(state->stencil); ++i) { trace_dump_elem_begin(stream); - trace_dump_struct_begin(stream, ""); + trace_dump_struct_begin(stream, "pipe_stencil_state"); trace_dump_member(stream, bool, &state->stencil[i], enabled); trace_dump_member(stream, uint, &state->stencil[i], func); trace_dump_member(stream, uint, &state->stencil[i], fail_op); @@ -305,7 +305,7 @@ void trace_dump_depth_stencil_alpha_state(struct trace_stream *stream, trace_dump_member_end(stream); trace_dump_member_begin(stream, "alpha"); - trace_dump_struct_begin(stream, ""); + trace_dump_struct_begin(stream, "pipe_alpha_state"); trace_dump_member(stream, bool, &state->alpha, enabled); trace_dump_member(stream, uint, &state->alpha, func); trace_dump_member(stream, float, &state->alpha, ref); -- cgit v1.2.3 From e69e94d3010b33cf690a2e4e54b61437a1836617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 11 Aug 2008 16:57:50 +0100 Subject: python: Bindings for pipe_{depth,stencil,alpha}_state. --- src/gallium/state_trackers/python/gallium.i | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 4e21eef7be..1792f63c3c 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -72,6 +72,9 @@ %rename(Blend) pipe_blend_state; %rename(Clip) pipe_clip_state; %rename(ConstantBuffer) pipe_constant_buffer; +%rename(Depth) pipe_depth_state; +%rename(Stencil) pipe_stencil_state; +%rename(Alpha) pipe_alpha_state; %rename(DepthStencilAlpha) pipe_depth_stencil_alpha_state; %rename(FormatBlock) pipe_format_block; %rename(Framebuffer) pipe_framebuffer_state; @@ -86,7 +89,6 @@ %include "pipe/p_defines.h"; -%include "pipe/p_shader_tokens.h"; %include "p_format.i" %include "p_device.i" -- cgit v1.2.3 From d4d8f803884584525a36713b76ce04802658bd0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 11 Aug 2008 17:08:27 +0100 Subject: trace: Fix create_depth_stencil_alpha_state trace. --- src/gallium/drivers/trace/tr_context.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index c9c15b2bb9..1df6842b71 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -457,8 +457,10 @@ trace_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe, result = pipe->create_depth_stencil_alpha_state(pipe, state);; - trace_dump_ret(stream, ptr, result); + trace_dump_arg(stream, ptr, pipe); trace_dump_arg(stream, depth_stencil_alpha_state, state); + + trace_dump_ret(stream, ptr, result); trace_dump_call_end(stream); -- cgit v1.2.3 From e08072c5db137e3fc19964ea8705c62cb00b6343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 11 Aug 2008 17:08:53 +0100 Subject: python: Bindings for p_compiler.h types. --- src/gallium/state_trackers/python/gallium.i | 1 + src/gallium/state_trackers/python/p_compiler.i | 29 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/gallium/state_trackers/python/p_compiler.i (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 1792f63c3c..8d7a49cee7 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -88,6 +88,7 @@ %rename(Viewport) pipe_viewport_state; +%include "p_compiler.i" %include "pipe/p_defines.h"; %include "p_format.i" diff --git a/src/gallium/state_trackers/python/p_compiler.i b/src/gallium/state_trackers/python/p_compiler.i new file mode 100644 index 0000000000..15f6ba5b9d --- /dev/null +++ b/src/gallium/state_trackers/python/p_compiler.i @@ -0,0 +1,29 @@ + /************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +typedef unsigned char ubyte; -- cgit v1.2.3 From e54fa77d130582ee48b699917324040ef254ed74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 11 Aug 2008 18:09:36 +0100 Subject: trace: Dump polygon stipple state as an array. --- src/gallium/drivers/trace/tr_state.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index 961705b9ee..e074ae7abc 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -150,9 +150,10 @@ void trace_dump_poly_stipple(struct trace_stream *stream, trace_dump_struct_begin(stream, "pipe_poly_stipple"); trace_dump_member_begin(stream, "stipple"); - trace_dump_bytes(stream, + trace_dump_array(stream, + uint, state->stipple, - sizeof(state->stipple)); + Elements(state->stipple)); trace_dump_member_end(stream); trace_dump_struct_end(stream); -- cgit v1.2.3 From 7b8fa937eb9bbc63a59f2db399781c32b20f339f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 11 Aug 2008 18:29:04 +0100 Subject: trace: Fix create_blend_state dump. --- src/gallium/drivers/trace/tr_context.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 1df6842b71..3e098128c9 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -275,6 +275,8 @@ trace_context_create_blend_state(struct pipe_context *_pipe, result = pipe->create_blend_state(pipe, state);; + trace_dump_ret(stream, ptr, result); + trace_dump_call_end(stream); return result; -- cgit v1.2.3 From 4a77fadd102264f1bf2caec3263e193eb831dade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 12 Aug 2008 11:32:42 +0100 Subject: trace: More dump fixes. --- src/gallium/drivers/trace/tr_context.c | 1 - src/gallium/drivers/trace/tr_winsys.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 3e098128c9..f82126370c 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -826,7 +826,6 @@ trace_context_set_vertex_elements(struct pipe_context *_pipe, trace_dump_arg(stream, ptr, pipe); trace_dump_arg(stream, uint, num_elements); - trace_dump_arg(stream, ptr, elements); trace_dump_arg_begin(stream, "elements"); trace_dump_struct_array(stream, vertex_element, elements, num_elements); diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index 0a43f1f7f4..eec84a1981 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -268,6 +268,8 @@ trace_winsys_buffer_unmap(struct pipe_winsys *_winsys, if(map) { trace_dump_call_begin(stream, "pipe_winsys", "buffer_write"); + trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(stream, ptr, buffer); trace_dump_arg_begin(stream, "data"); -- cgit v1.2.3 From 506b8ebdba73f85c169599ce861b339e97370eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 12 Aug 2008 11:33:20 +0100 Subject: python: Use st_buffers instead of pipe_buffers. --- src/gallium/state_trackers/python/p_context.i | 32 ++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index df07f3bc47..521a2dee07 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -106,12 +106,12 @@ struct st_context { } void set_constant_buffer(unsigned shader, unsigned index, - const struct pipe_constant_buffer *buf ) + struct st_buffer *buffer ) { struct pipe_constant_buffer state; memset(&state, 0, sizeof(state)); - state.buffer = buf->buffer; - state.size = buf->buffer->size; + state.buffer = buffer->buffer; + state.size = buffer->buffer->size; $self->pipe->set_constant_buffer($self->pipe, shader, index, &state); } @@ -142,9 +142,29 @@ struct st_context { } void set_vertex_buffer(unsigned index, - const struct pipe_vertex_buffer *buffer) { - memcpy(&$self->vertex_buffers[index], buffer, sizeof(*buffer)); - $self->pipe->set_vertex_buffers($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_buffers); + unsigned pitch, + unsigned max_index, + unsigned buffer_offset, + struct st_buffer *buffer) + { + unsigned i, num_vertex_buffers; + struct pipe_vertex_buffer state; + + memset(&state, 0, sizeof(state)); + state.pitch = pitch; + state.max_index = max_index; + state.buffer_offset = buffer_offset; + state.buffer = buffer->buffer; + + memcpy(&$self->vertex_buffers[index], &state, sizeof(state)); + + for(i = 0; i < PIPE_MAX_ATTRIBS; ++i) + if(self->vertex_buffers[i].buffer) + num_vertex_buffers = i + 1; + + $self->pipe->set_vertex_buffers($self->pipe, + num_vertex_buffers, + $self->vertex_buffers); } void set_vertex_element(unsigned index, -- cgit v1.2.3 From cf16285d1bcb9f172a930f9d4f3402e379b53c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 09:03:52 +0100 Subject: gdi: Remove CVS keyword. --- src/gallium/winsys/gdi/wgl.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/gdi/wgl.c b/src/gallium/winsys/gdi/wgl.c index 50126014a8..3ce470480d 100644 --- a/src/gallium/winsys/gdi/wgl.c +++ b/src/gallium/winsys/gdi/wgl.c @@ -1,5 +1,3 @@ -/* $Id: wgl.c,v 1.12 2006/03/30 07:58:24 kschultz Exp $ */ - /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public -- cgit v1.2.3 From 3b5ee3d6de2c08faf69c701bf05d8f33ccd01502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 09:12:55 +0100 Subject: gallium: Allow compilation inside X. --- src/gallium/auxiliary/util/u_string.h | 12 ++++++------ src/gallium/include/pipe/p_compiler.h | 5 +++++ 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h index abc3232b49..08c89bbf77 100644 --- a/src/gallium/auxiliary/util/u_string.h +++ b/src/gallium/auxiliary/util/u_string.h @@ -28,14 +28,14 @@ /** * @file * Platform independent functions for string manipulation. - * + * * @author Jose Fonseca */ #ifndef U_STRING_H_ #define U_STRING_H_ -#ifndef WIN32 +#if !defined(WIN32) && !defined(XF86_LIBC_H) #include #endif #include @@ -48,19 +48,19 @@ extern "C" { #endif - + #ifdef WIN32 - + int util_vsnprintf(char *, size_t, const char *, va_list); int util_snprintf(char *str, size_t size, const char *format, ...); -static INLINE void +static INLINE void util_vsprintf(char *str, const char *format, va_list ap) { util_vsnprintf(str, (size_t)-1, format, ap); } -static INLINE void +static INLINE void util_sprintf(char *str, const char *format, ...) { va_list ap; diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index 2afb8464c7..4d64c74a4a 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -31,8 +31,13 @@ #include "p_config.h" +#ifndef XFree86Server #include #include +#else +#include "xf86_ansic.h" +#include "xf86_libc.h" +#endif #if defined(_WIN32) && !defined(__WIN32__) -- cgit v1.2.3 From 80d3a653f0172f01be694a29456c70f1f4da1812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 09:13:11 +0100 Subject: tgsi: Prevent division by zero. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 8b430548bc..b93f3d5222 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -393,10 +393,18 @@ micro_div( const union tgsi_exec_channel *src0, const union tgsi_exec_channel *src1 ) { - dst->f[0] = src0->f[0] / src1->f[0]; - dst->f[1] = src0->f[1] / src1->f[1]; - dst->f[2] = src0->f[2] / src1->f[2]; - dst->f[3] = src0->f[3] / src1->f[3]; + if (src1->f[0] != 0) { + dst->f[0] = src0->f[0] / src1->f[0]; + } + if (src1->f[1] != 0) { + dst->f[1] = src0->f[1] / src1->f[1]; + } + if (src1->f[2] != 0) { + dst->f[2] = src0->f[2] / src1->f[2]; + } + if (src1->f[3] != 0) { + dst->f[3] = src0->f[3] / src1->f[3]; + } } static void -- cgit v1.2.3 From 0f5a2ebec4c16e71bde7132edb8c2209b4000c61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 7 Aug 2008 09:15:32 +0100 Subject: gallium: Disable debug break by default on windows. --- src/gallium/auxiliary/util/p_debug.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 082b0e9fb5..2c2f2f8931 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -324,7 +324,11 @@ void _debug_assert_fail(const char *expr, const char *function) { _debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file, line, function, expr); +#if defined(PIPE_OS_WINDOWS) + if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", FALSE)) +#else if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", TRUE)) +#endif debug_break(); else _debug_printf("continuing...\n"); -- cgit v1.2.3 From faad6655946968dd16ab30cc8d5fbd5a09321976 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 12 Aug 2008 12:00:57 -0600 Subject: gallium: distinguish between KIL and KILP Note: KIL (unconditional) not done yet. --- src/gallium/auxiliary/tgsi/tgsi_sse2.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 0cb1f11ef2..f3a202ae89 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -1002,7 +1002,7 @@ emit_store( */ static void -emit_kil( +emit_kilp( struct x86_function *func, const struct tgsi_full_src_register *reg ) { @@ -1096,6 +1096,15 @@ emit_kil( x86_make_reg( file_REG32, reg_AX ) ); } + +static void +emit_kil( + struct x86_function *func ) +{ + /* XXX todo / fix me */ +} + + static void emit_setcc( struct x86_function *func, @@ -1609,8 +1618,15 @@ emit_instruction( return 0; break; + case TGSI_OPCODE_KILP: + /* predicated kill */ + emit_kilp( func, &inst->FullSrcRegisters[0] ); + break; + case TGSI_OPCODE_KIL: - emit_kil( func, &inst->FullSrcRegisters[0] ); + /* unconditional kill */ + emit_kil( func ); + return 0; /* XXX fix me */ break; case TGSI_OPCODE_PK2H: -- cgit v1.2.3 From 9804ab9accb3c6607c64a65bebe70124578240cd Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 09:15:27 +0200 Subject: gallium: Make a note that OPCODE_KIL is a conditional kill. Map OPCODE_TEXKILL to OPCODE_KIL. --- src/gallium/include/pipe/p_shader_tokens.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index ed931d24b9..3ab0c7deaf 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -240,6 +240,7 @@ struct tgsi_immediate_float32 * GL_ARB_fragment_program */ #define TGSI_OPCODE_CMP 66 +#define TGSI_OPCODE_KIL 116 /* conditional kill */ #define TGSI_OPCODE_SCS 67 #define TGSI_OPCODE_TXB 68 @@ -327,7 +328,7 @@ struct tgsi_immediate_float32 /* * ps_1_1 */ -#define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KILP +#define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KIL /* * ps_1_2 @@ -386,7 +387,6 @@ struct tgsi_immediate_float32 * vs_2_x */ -#define TGSI_OPCODE_KIL 116 /* unpredicated kill */ #define TGSI_OPCODE_END 117 /* aka HALT */ #define TGSI_OPCODE_LAST 119 -- cgit v1.2.3 From 0c8f4c25ff1cdf8d4cad21789e0c73b41aa29c98 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 10:52:55 +0200 Subject: draw: Use KIL instead of KILP. --- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 4 ++-- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 13b4401521..c7f4349cb3 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -301,9 +301,9 @@ aa_transform_inst(struct tgsi_transform_context *ctx, newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; ctx->emit_instruction(ctx, &newInst); - /* KILP -t0.yyyy; # if b, KILL */ + /* KIL -tmp0.yyyy; # if -tmp0.y < 0, KILL */ newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_KILP; + newInst.Instruction.Opcode = TGSI_OPCODE_KIL; newInst.Instruction.NumDstRegs = 0; newInst.Instruction.NumSrcRegs = 1; newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index d3bd9baddd..e97136fa1f 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -299,9 +299,9 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler; ctx->emit_instruction(ctx, &newInst); - /* KILP texTemp; # if texTemp < 0, KILL fragment */ + /* KIL -texTemp; # if -texTemp < 0, KILL fragment */ newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_KILP; + newInst.Instruction.Opcode = TGSI_OPCODE_KIL; newInst.Instruction.NumDstRegs = 0; newInst.Instruction.NumSrcRegs = 1; newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; -- cgit v1.2.3 From f633b14b92352d8abc2a178a1f6ff80a58662bb1 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 10:58:54 +0200 Subject: gallivm: Translate KIL instead of KILP. --- src/gallium/auxiliary/gallivm/instructions.cpp | 4 ++-- src/gallium/auxiliary/gallivm/instructions.h | 2 +- src/gallium/auxiliary/gallivm/llvm_builtins.c | 2 +- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 18 +++++++++--------- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp index 1a98491b82..035224e8f3 100644 --- a/src/gallium/auxiliary/gallivm/instructions.cpp +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -878,9 +878,9 @@ llvm::Value * Instructions::scs(llvm::Value *in) return call; } -llvm::Value * Instructions::kilp(llvm::Value *in) +llvm::Value * Instructions::kil(llvm::Value *in) { - llvm::Function *func = m_mod->getFunction("kilp"); + llvm::Function *func = m_mod->getFunction("kil"); assert(func); CallInst *call = m_builder.CreateCall(func, in, name("kilpres")); diff --git a/src/gallium/auxiliary/gallivm/instructions.h b/src/gallium/auxiliary/gallivm/instructions.h index 3a476928b6..d286ce80c7 100644 --- a/src/gallium/auxiliary/gallivm/instructions.h +++ b/src/gallium/auxiliary/gallivm/instructions.h @@ -79,7 +79,7 @@ public: llvm::Value *floor(llvm::Value *in); llvm::Value *frc(llvm::Value *in); void ifop(llvm::Value *in); - llvm::Value *kilp(llvm::Value *in); + llvm::Value *kil(llvm::Value *in); llvm::Value *lerp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); llvm::Value *lit(llvm::Value *in); diff --git a/src/gallium/auxiliary/gallivm/llvm_builtins.c b/src/gallium/auxiliary/gallivm/llvm_builtins.c index 6b9d626ed4..d5a003a48b 100644 --- a/src/gallium/auxiliary/gallivm/llvm_builtins.c +++ b/src/gallium/auxiliary/gallivm/llvm_builtins.c @@ -105,7 +105,7 @@ inline float4 vsin(float4 val) return result; } -inline int kilp(float4 val) +inline int kil(float4 val) { if (val.x < 0 || val.y < 0 || val.z < 0 || val.w < 0) return 1; diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index b14e2affd6..cc1516a45e 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -396,11 +396,7 @@ translate_instruction(llvm::Module *module, break; case TGSI_OPCODE_DDY: break; - case TGSI_OPCODE_KILP: { - out = instr->kilp(inputs[0]); - storage->setKilElement(out); - return; - } + case TGSI_OPCODE_KILP: break; case TGSI_OPCODE_PK2H: break; @@ -602,7 +598,11 @@ translate_instruction(llvm::Module *module, break; case TGSI_OPCODE_BREAKC: break; - case TGSI_OPCODE_KIL: + case TGSI_OPCODE_KIL: { + out = instr->kil(inputs[0]); + storage->setKilElement(out); + return; + } break; case TGSI_OPCODE_END: instr->end(); @@ -799,8 +799,7 @@ translate_instructionir(llvm::Module *module, break; case TGSI_OPCODE_DDY: break; - case TGSI_OPCODE_KILP: { - } + case TGSI_OPCODE_KILP: break; case TGSI_OPCODE_PK2H: break; @@ -967,7 +966,8 @@ translate_instructionir(llvm::Module *module, break; case TGSI_OPCODE_BREAKC: break; - case TGSI_OPCODE_KIL: + case TGSI_OPCODE_KIL: { + } break; case TGSI_OPCODE_END: instr->end(); -- cgit v1.2.3 From f0874d1a6b832e1bb29256661cb8beab3ddeb528 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 11:09:20 +0200 Subject: tgsi: Swap meanings of KIL and KILP opcodes. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 22 ++++++++++++++++++---- src/gallium/auxiliary/tgsi/tgsi_sse2.c | 12 ++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index b93f3d5222..c4ba667d32 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1189,8 +1189,8 @@ store_dest( * Kill fragment if any of the four values is less than zero. */ static void -exec_kilp(struct tgsi_exec_machine *mach, - const struct tgsi_full_instruction *inst) +exec_kil(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) { uint uniquemask; uint chan_index; @@ -1226,6 +1226,21 @@ exec_kilp(struct tgsi_exec_machine *mach, mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; } +/** + * Execute NVIDIA-style KIL which is predicated by a condition code. + * Kill fragment if the condition code is TRUE. + */ +static void +exec_kilp(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ + + /* TODO: build kilmask from CC mask */ + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; +} + /* * Fetch a texel using STR texture coordinates. @@ -1971,8 +1986,7 @@ exec_instruction( break; case TGSI_OPCODE_KIL: - /* for enabled ExecMask bits, set the killed bit */ - mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= mach->ExecMask; + exec_kil (mach, inst); break; case TGSI_OPCODE_PK2H: diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index f3a202ae89..47dc06faf6 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -1002,7 +1002,7 @@ emit_store( */ static void -emit_kilp( +emit_kil( struct x86_function *func, const struct tgsi_full_src_register *reg ) { @@ -1098,7 +1098,7 @@ emit_kilp( static void -emit_kil( +emit_kilp( struct x86_function *func ) { /* XXX todo / fix me */ @@ -1620,13 +1620,13 @@ emit_instruction( case TGSI_OPCODE_KILP: /* predicated kill */ - emit_kilp( func, &inst->FullSrcRegisters[0] ); + emit_kilp( func ); + return 0; /* XXX fix me */ break; case TGSI_OPCODE_KIL: - /* unconditional kill */ - emit_kil( func ); - return 0; /* XXX fix me */ + /* conditional kill */ + emit_kil( func, &inst->FullSrcRegisters[0] ); break; case TGSI_OPCODE_PK2H: -- cgit v1.2.3 From e8e75c8c865bb5bbff9db2682b130c8d147f3a38 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 11:10:58 +0200 Subject: cell: KILP is a predicated discard, KIL is a conditional discard. --- src/gallium/drivers/cell/spu/spu_exec.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 96393732ed..42e5022f30 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -603,8 +603,8 @@ store_dest( * Kill fragment if any of the four values is less than zero. */ static void -exec_kilp(struct spu_exec_machine *mach, - const struct tgsi_full_instruction *inst) +exec_kil(struct spu_exec_machine *mach, + const struct tgsi_full_instruction *inst) { uint uniquemask; uint chan_index; @@ -640,6 +640,20 @@ exec_kilp(struct spu_exec_machine *mach, mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; } +/** + * Execute NVIDIA-style KIL which is predicated by a condition code. + * Kill fragment if the condition code is TRUE. + */ +static void +exec_kilp(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ + + /* TODO: build kilmask from CC mask */ + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; +} /* * Fetch a texel using STR texture coordinates. @@ -1336,8 +1350,7 @@ exec_instruction( break; case TGSI_OPCODE_KIL: - /* for enabled ExecMask bits, set the killed bit */ - mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= mach->ExecMask; + exec_kil (mach, inst); break; case TGSI_OPCODE_PK2H: -- cgit v1.2.3 From db38708c43d7e9bbc744893ad2e9c2a77e9ec15c Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 11:13:46 +0200 Subject: i915: Swap meanings of KIL and KILP. --- src/gallium/drivers/i915simple/i915_fpc_translate.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 04507ab8ad..64432982c4 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -560,18 +560,6 @@ i915_translate_instruction(struct i915_fp_compile *p, break; case TGSI_OPCODE_KIL: - /* unconditional kill */ - assert(0); /* not tested yet */ -#if 0 - src0 = src_vector(p, &inst->FullSrcRegisters[0]); - tmp = i915_get_utemp(p); - - i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */ - 0, src0, T0_TEXKILL); -#endif - break; - - case TGSI_OPCODE_KILP: /* kill if src[0].x < 0 || src[0].y < 0 ... */ src0 = src_vector(p, &inst->FullSrcRegisters[0]); tmp = i915_get_utemp(p); @@ -584,6 +572,10 @@ i915_translate_instruction(struct i915_fp_compile *p, T0_TEXKILL); /* opcode */ break; + case TGSI_OPCODE_KILP: + assert(0); /* not tested yet */ + break; + case TGSI_OPCODE_LG2: src0 = src_vector(p, &inst->FullSrcRegisters[0]); -- cgit v1.2.3 From 94f9faab31f7fbf5f14d23d993f9830fa51ce076 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 17:16:59 +0200 Subject: tgsi: Opcode information. --- src/gallium/auxiliary/tgsi/tgsi_info.c | 161 +++++++++++++++++++++++++++++++++ src/gallium/auxiliary/tgsi/tgsi_info.h | 53 +++++++++++ 2 files changed, 214 insertions(+) create mode 100644 src/gallium/auxiliary/tgsi/tgsi_info.c create mode 100644 src/gallium/auxiliary/tgsi/tgsi_info.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c new file mode 100644 index 0000000000..a4899cd4c2 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c @@ -0,0 +1,161 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_debug.h" +#include "tgsi_info.h" + +static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] = +{ + { 1, 1, 0, 0, "ARL" }, + { 1, 1, 0, 0, "MOV" }, + { 1, 1, 0, 0, "LIT" }, + { 1, 1, 0, 0, "RCP" }, + { 1, 1, 0, 0, "RSQ" }, + { 1, 1, 0, 0, "EXP" }, + { 1, 1, 0, 0, "LOG" }, + { 1, 2, 0, 0, "MUL" }, + { 1, 2, 0, 0, "ADD" }, + { 1, 2, 0, 0, "DP3" }, + { 1, 2, 0, 0, "DP4" }, + { 1, 2, 0, 0, "DST" }, + { 1, 2, 0, 0, "MIN" }, + { 1, 2, 0, 0, "MAX" }, + { 1, 2, 0, 0, "SLT" }, + { 1, 2, 0, 0, "SGE" }, + { 1, 3, 0, 0, "MAD" }, + { 1, 2, 0, 0, "SUB" }, + { 1, 3, 0, 0, "LERP" }, + { 1, 3, 0, 0, "CND" }, + { 1, 3, 0, 0, "CND0" }, + { 1, 3, 0, 0, "DOT2ADD" }, + { 1, 2, 0, 0, "INDEX" }, + { 1, 1, 0, 0, "NEGATE" }, + { 1, 1, 0, 0, "FRAC" }, + { 1, 3, 0, 0, "CLAMP" }, + { 1, 1, 0, 0, "FLOOR" }, + { 1, 1, 0, 0, "ROUND" }, + { 1, 1, 0, 0, "EXPBASE2" }, + { 1, 1, 0, 0, "LOGBASE2" }, + { 1, 2, 0, 0, "POWER" }, + { 1, 2, 0, 0, "CROSSPRODUCT" }, + { 1, 2, 0, 0, "MULTIPLYMATRIX" }, + { 1, 1, 0, 0, "ABS" }, + { 1, 1, 0, 0, "RCC" }, + { 1, 2, 0, 0, "DPH" }, + { 1, 1, 0, 0, "COS" }, + { 1, 1, 0, 0, "DDX" }, + { 1, 1, 0, 0, "DDY" }, + { 0, 1, 0, 0, "KILP" }, + { 1, 1, 0, 0, "PK2H" }, + { 1, 1, 0, 0, "PK2US" }, + { 1, 1, 0, 0, "PK4B" }, + { 1, 1, 0, 0, "PK4UB" }, + { 1, 2, 0, 0, "RFL" }, + { 1, 2, 0, 0, "SEQ" }, + { 1, 2, 0, 0, "SFL" }, + { 1, 2, 0, 0, "SGT" }, + { 1, 1, 0, 0, "SIN" }, + { 1, 2, 0, 0, "SLE" }, + { 1, 2, 0, 0, "SNE" }, + { 1, 2, 0, 0, "STR" }, + { 1, 2, 1, 0, "TEX" }, + { 1, 4, 1, 0, "TXD" }, + { 1, 2, 1, 0, "TXP" }, + { 1, 1, 0, 0, "UP2H" }, + { 1, 1, 0, 0, "UP2US" }, + { 1, 1, 0, 0, "UP4B" }, + { 1, 1, 0, 0, "UP4UB" }, + { 1, 3, 0, 0, "X2D" }, + { 1, 1, 0, 0, "ARA" }, + { 1, 1, 0, 0, "ARR" }, + { 0, 1, 0, 0, "BRA" }, + { 0, 0, 0, 1, "CAL" }, + { 0, 0, 0, 0, "RET" }, + { 1, 1, 0, 0, "SSG" }, + { 1, 3, 0, 0, "CMP" }, + { 1, 1, 0, 0, "SCS" }, + { 1, 2, 1, 0, "TXB" }, + { 1, 1, 0, 0, "NRM" }, + { 1, 2, 0, 0, "DIV" }, + { 1, 2, 0, 0, "DP2" }, + { 1, 2, 1, 0, "TXL" }, + { 0, 0, 0, 0, "BRK" }, + { 0, 1, 0, 1, "IF" }, + { 0, 0, 0, 0, "LOOP" }, + { 0, 1, 0, 0, "REP" }, + { 0, 0, 0, 1, "ELSE" }, + { 0, 0, 0, 0, "ENDIF" }, + { 0, 0, 0, 0, "ENDLOOP" }, + { 0, 0, 0, 0, "ENDREP" }, + { 0, 1, 0, 0, "PUSHA" }, + { 1, 0, 0, 0, "POPA" }, + { 1, 1, 0, 0, "CEIL" }, + { 1, 1, 0, 0, "I2F" }, + { 1, 1, 0, 0, "NOT" }, + { 1, 1, 0, 0, "TRUNC" }, + { 1, 2, 0, 0, "SHL" }, + { 1, 2, 0, 0, "SHR" }, + { 1, 2, 0, 0, "AND" }, + { 1, 2, 0, 0, "OR" }, + { 1, 2, 0, 0, "MOD" }, + { 1, 2, 0, 0, "XOR" }, + { 1, 3, 0, 0, "SAD" }, + { 1, 2, 1, 0, "TXF" }, + { 1, 2, 1, 0, "TXQ" }, + { 0, 0, 0, 0, "CONT" }, + { 0, 0, 0, 0, "EMIT" }, + { 0, 0, 0, 0, "ENDPRIM" }, + { 0, 0, 0, 1, "BGNLOOP2" }, + { 0, 0, 0, 0, "BGNSUB" }, + { 0, 0, 0, 1, "ENDLOOP2" }, + { 0, 0, 0, 0, "ENDSUB" }, + { 1, 1, 0, 0, "NOISE1" }, + { 1, 1, 0, 0, "NOISE2" }, + { 1, 1, 0, 0, "NOISE3" }, + { 1, 1, 0, 0, "NOISE4" }, + { 0, 0, 0, 0, "NOP" }, + { 1, 2, 0, 0, "M4X3" }, + { 1, 2, 0, 0, "M3X4" }, + { 1, 2, 0, 0, "M3X3" }, + { 1, 2, 0, 0, "M3X2" }, + { 1, 1, 0, 0, "NRM4" }, + { 0, 1, 0, 0, "CALLNZ" }, + { 0, 1, 0, 0, "IFC" }, + { 0, 1, 0, 0, "BREAKC" }, + { 0, 0, 0, 0, "KIL" }, + { 0, 0, 0, 0, "END" }, + { 1, 1, 0, 0, "SWZ" } +}; + +const struct tgsi_opcode_info * +tgsi_get_opcode_info( uint opcode ) +{ + if (opcode < TGSI_OPCODE_LAST) + return &opcode_info[opcode]; + assert( 0 ); + return NULL; +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.h b/src/gallium/auxiliary/tgsi/tgsi_info.h new file mode 100644 index 0000000000..7230bdaae3 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/tgsi_info.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TGSI_INFO_H +#define TGSI_INFO_H + +#include "pipe/p_shader_tokens.h" + +#if defined __cplusplus +extern "C" { +#endif + +struct tgsi_opcode_info +{ + uint num_dst; + uint num_src; + boolean is_tex; + boolean is_branch; + const char *mnemonic; +}; + +const struct tgsi_opcode_info * +tgsi_get_opcode_info( uint opcode ); + +#if defined __cplusplus +} +#endif + +#endif /* TGSI_INFO_H */ -- cgit v1.2.3 From 668ac2572548b7818b89a424f44e9c9c59786df0 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 17:19:20 +0200 Subject: scons: List tgsi_info.c. --- src/gallium/auxiliary/tgsi/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript index 03982e2194..45bf3f6d57 100644 --- a/src/gallium/auxiliary/tgsi/SConscript +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -7,6 +7,7 @@ tgsi = env.ConvenienceLibrary( 'tgsi_dump.c', 'tgsi_dump_c.c', 'tgsi_exec.c', + 'tgsi_info.c', 'tgsi_iterate.c', 'tgsi_parse.c', 'tgsi_sanity.c', -- cgit v1.2.3 From 6d83a0cc6846adb546794c0483694fdb1d1b4664 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 17:20:14 +0200 Subject: make: List tgsi_info.c. --- src/gallium/auxiliary/tgsi/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index bbeff1304d..806a2bd4c5 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -7,6 +7,7 @@ C_SOURCES = \ tgsi_build.c \ tgsi_dump.c \ tgsi_exec.c \ + tgsi_info.c \ tgsi_iterate.c \ tgsi_parse.c \ tgsi_scan.c \ -- cgit v1.2.3 From 79e52779bdcd1fa0ff8e1cbdc7555746205ee519 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 17:22:34 +0200 Subject: tgsi: Use tgsi_opcode_info. --- src/gallium/auxiliary/tgsi/tgsi_text.c | 137 +-------------------------------- 1 file changed, 3 insertions(+), 134 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 35cb3055bb..7cdf1b67c5 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -28,6 +28,7 @@ #include "pipe/p_debug.h" #include "tgsi_text.h" #include "tgsi_build.h" +#include "tgsi_info.h" #include "tgsi_parse.h" #include "tgsi_sanity.h" #include "tgsi_util.h" @@ -719,138 +720,6 @@ parse_src_operand( return TRUE; } -struct opcode_info -{ - uint num_dst; - uint num_src; - uint is_tex; - uint is_branch; - const char *mnemonic; -}; - -static const struct opcode_info opcode_info[TGSI_OPCODE_LAST] = -{ - { 1, 1, 0, 0, "ARL" }, - { 1, 1, 0, 0, "MOV" }, - { 1, 1, 0, 0, "LIT" }, - { 1, 1, 0, 0, "RCP" }, - { 1, 1, 0, 0, "RSQ" }, - { 1, 1, 0, 0, "EXP" }, - { 1, 1, 0, 0, "LOG" }, - { 1, 2, 0, 0, "MUL" }, - { 1, 2, 0, 0, "ADD" }, - { 1, 2, 0, 0, "DP3" }, - { 1, 2, 0, 0, "DP4" }, - { 1, 2, 0, 0, "DST" }, - { 1, 2, 0, 0, "MIN" }, - { 1, 2, 0, 0, "MAX" }, - { 1, 2, 0, 0, "SLT" }, - { 1, 2, 0, 0, "SGE" }, - { 1, 3, 0, 0, "MAD" }, - { 1, 2, 0, 0, "SUB" }, - { 1, 3, 0, 0, "LERP" }, - { 1, 3, 0, 0, "CND" }, - { 1, 3, 0, 0, "CND0" }, - { 1, 3, 0, 0, "DOT2ADD" }, - { 1, 2, 0, 0, "INDEX" }, - { 1, 1, 0, 0, "NEGATE" }, - { 1, 1, 0, 0, "FRAC" }, - { 1, 3, 0, 0, "CLAMP" }, - { 1, 1, 0, 0, "FLOOR" }, - { 1, 1, 0, 0, "ROUND" }, - { 1, 1, 0, 0, "EXPBASE2" }, - { 1, 1, 0, 0, "LOGBASE2" }, - { 1, 2, 0, 0, "POWER" }, - { 1, 2, 0, 0, "CROSSPRODUCT" }, - { 1, 2, 0, 0, "MULTIPLYMATRIX" }, - { 1, 1, 0, 0, "ABS" }, - { 1, 1, 0, 0, "RCC" }, - { 1, 2, 0, 0, "DPH" }, - { 1, 1, 0, 0, "COS" }, - { 1, 1, 0, 0, "DDX" }, - { 1, 1, 0, 0, "DDY" }, - { 0, 1, 0, 0, "KILP" }, - { 1, 1, 0, 0, "PK2H" }, - { 1, 1, 0, 0, "PK2US" }, - { 1, 1, 0, 0, "PK4B" }, - { 1, 1, 0, 0, "PK4UB" }, - { 1, 2, 0, 0, "RFL" }, - { 1, 2, 0, 0, "SEQ" }, - { 1, 2, 0, 0, "SFL" }, - { 1, 2, 0, 0, "SGT" }, - { 1, 1, 0, 0, "SIN" }, - { 1, 2, 0, 0, "SLE" }, - { 1, 2, 0, 0, "SNE" }, - { 1, 2, 0, 0, "STR" }, - { 1, 2, 1, 0, "TEX" }, - { 1, 4, 1, 0, "TXD" }, - { 1, 2, 1, 0, "TXP" }, - { 1, 1, 0, 0, "UP2H" }, - { 1, 1, 0, 0, "UP2US" }, - { 1, 1, 0, 0, "UP4B" }, - { 1, 1, 0, 0, "UP4UB" }, - { 1, 3, 0, 0, "X2D" }, - { 1, 1, 0, 0, "ARA" }, - { 1, 1, 0, 0, "ARR" }, - { 0, 1, 0, 0, "BRA" }, - { 0, 0, 0, 1, "CAL" }, - { 0, 0, 0, 0, "RET" }, - { 1, 1, 0, 0, "SSG" }, - { 1, 3, 0, 0, "CMP" }, - { 1, 1, 0, 0, "SCS" }, - { 1, 2, 1, 0, "TXB" }, - { 1, 1, 0, 0, "NRM" }, - { 1, 2, 0, 0, "DIV" }, - { 1, 2, 0, 0, "DP2" }, - { 1, 2, 1, 0, "TXL" }, - { 0, 0, 0, 0, "BRK" }, - { 0, 1, 0, 1, "IF" }, - { 0, 0, 0, 0, "LOOP" }, - { 0, 1, 0, 0, "REP" }, - { 0, 0, 0, 1, "ELSE" }, - { 0, 0, 0, 0, "ENDIF" }, - { 0, 0, 0, 0, "ENDLOOP" }, - { 0, 0, 0, 0, "ENDREP" }, - { 0, 1, 0, 0, "PUSHA" }, - { 1, 0, 0, 0, "POPA" }, - { 1, 1, 0, 0, "CEIL" }, - { 1, 1, 0, 0, "I2F" }, - { 1, 1, 0, 0, "NOT" }, - { 1, 1, 0, 0, "TRUNC" }, - { 1, 2, 0, 0, "SHL" }, - { 1, 2, 0, 0, "SHR" }, - { 1, 2, 0, 0, "AND" }, - { 1, 2, 0, 0, "OR" }, - { 1, 2, 0, 0, "MOD" }, - { 1, 2, 0, 0, "XOR" }, - { 1, 3, 0, 0, "SAD" }, - { 1, 2, 1, 0, "TXF" }, - { 1, 2, 1, 0, "TXQ" }, - { 0, 0, 0, 0, "CONT" }, - { 0, 0, 0, 0, "EMIT" }, - { 0, 0, 0, 0, "ENDPRIM" }, - { 0, 0, 0, 1, "BGNLOOP2" }, - { 0, 0, 0, 0, "BGNSUB" }, - { 0, 0, 0, 1, "ENDLOOP2" }, - { 0, 0, 0, 0, "ENDSUB" }, - { 1, 1, 0, 0, "NOISE1" }, - { 1, 1, 0, 0, "NOISE2" }, - { 1, 1, 0, 0, "NOISE3" }, - { 1, 1, 0, 0, "NOISE4" }, - { 0, 0, 0, 0, "NOP" }, - { 1, 2, 0, 0, "M4X3" }, - { 1, 2, 0, 0, "M3X4" }, - { 1, 2, 0, 0, "M3X3" }, - { 1, 2, 0, 0, "M3X2" }, - { 1, 1, 0, 0, "NRM4" }, - { 0, 1, 0, 0, "CALLNZ" }, - { 0, 1, 0, 0, "IFC" }, - { 0, 1, 0, 0, "BREAKC" }, - { 0, 0, 0, 0, "KIL" }, - { 0, 0, 0, 0, "END" }, - { 1, 1, 0, 0, "SWZ" } -}; - static const char *texture_names[TGSI_TEXTURE_COUNT] = { "UNKNOWN", @@ -871,7 +740,7 @@ parse_instruction( { uint i; uint saturate = TGSI_SAT_NONE; - const struct opcode_info *info; + const struct tgsi_opcode_info *info; struct tgsi_full_instruction inst; uint advance; @@ -881,7 +750,7 @@ parse_instruction( for (i = 0; i < TGSI_OPCODE_LAST; i++) { const char *cur = ctx->cur; - info = &opcode_info[i]; + info = tgsi_get_opcode_info( i ); if (str_match_no_case( &cur, info->mnemonic )) { if (str_match_no_case( &cur, "_SATNV" )) saturate = TGSI_SAT_MINUS_PLUS_ONE; -- cgit v1.2.3 From 2caaba8195d1019702246bd7f0c02aa95364a8bd Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 17:27:15 +0200 Subject: tgsi: Use tgsi_info to dump opcode names. --- src/gallium/auxiliary/tgsi/tgsi_dump.c | 130 +----------------------------- src/gallium/auxiliary/tgsi/tgsi_dump_c.c | 133 +------------------------------ 2 files changed, 6 insertions(+), 257 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index 29bb530b4d..4309d1bc76 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -28,6 +28,7 @@ #include "pipe/p_debug.h" #include "util/u_string.h" #include "tgsi_dump.h" +#include "tgsi_info.h" #include "tgsi_iterate.h" struct dump_ctx @@ -103,129 +104,6 @@ static const char *immediate_type_names[] = "FLT32" }; -static const char *opcode_names[TGSI_OPCODE_LAST] = -{ - "ARL", - "MOV", - "LIT", - "RCP", - "RSQ", - "EXP", - "LOG", - "MUL", - "ADD", - "DP3", - "DP4", - "DST", - "MIN", - "MAX", - "SLT", - "SGE", - "MAD", - "SUB", - "LERP", - "CND", - "CND0", - "DOT2ADD", - "INDEX", - "NEGATE", - "FRAC", - "CLAMP", - "FLOOR", - "ROUND", - "EXPBASE2", - "LOGBASE2", - "POWER", - "CROSSPRODUCT", - "MULTIPLYMATRIX", - "ABS", - "RCC", - "DPH", - "COS", - "DDX", - "DDY", - "KILP", - "PK2H", - "PK2US", - "PK4B", - "PK4UB", - "RFL", - "SEQ", - "SFL", - "SGT", - "SIN", - "SLE", - "SNE", - "STR", - "TEX", - "TXD", - "TXP", - "UP2H", - "UP2US", - "UP4B", - "UP4UB", - "X2D", - "ARA", - "ARR", - "BRA", - "CAL", - "RET", - "SSG", - "CMP", - "SCS", - "TXB", - "NRM", - "DIV", - "DP2", - "TXL", - "BRK", - "IF", - "LOOP", - "REP", - "ELSE", - "ENDIF", - "ENDLOOP", - "ENDREP", - "PUSHA", - "POPA", - "CEIL", - "I2F", - "NOT", - "TRUNC", - "SHL", - "SHR", - "AND", - "OR", - "MOD", - "XOR", - "SAD", - "TXF", - "TXQ", - "CONT", - "EMIT", - "ENDPRIM", - "BGNLOOP2", - "BGNSUB", - "ENDLOOP2", - "ENDSUB", - "NOISE1", - "NOISE2", - "NOISE3", - "NOISE4", - "NOP", - "M4X3", - "M3X4", - "M3X3", - "M3X2", - "NRM4", - "CALLNZ", - "IFC", - "BREAKC", - "KIL", - "END", - "SWZ" -}; - static const char *swizzle_names[] = { "x", @@ -444,7 +322,7 @@ iter_instruction( UID( instno ); CHR( ':' ); - ENM( inst->Instruction.Opcode, opcode_names ); + TXT( tgsi_get_opcode_info( inst->Instruction.Opcode )->mnemonic ); switch (inst->Instruction.Saturate) { case TGSI_SAT_NONE: @@ -622,10 +500,6 @@ tgsi_dump_str( util_strbuf_init(&sbuf, str, size); - /* sanity checks */ - assert( strcmp( opcode_names[TGSI_OPCODE_CONT], "CONT" ) == 0 ); - assert( strcmp( opcode_names[TGSI_OPCODE_END], "END" ) == 0 ); - ctx.iter.prolog = prolog; ctx.iter.iterate_instruction = iter_instruction; ctx.iter.iterate_declaration = iter_declaration; diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c index eabd74bd6d..1025866a25 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c @@ -29,8 +29,9 @@ #include "pipe/p_util.h" #include "util/u_string.h" #include "tgsi_dump_c.h" -#include "tgsi_parse.h" #include "tgsi_build.h" +#include "tgsi_info.h" +#include "tgsi_parse.h" static void dump_enum( @@ -104,128 +105,6 @@ static const char *TGSI_IMMS[] = "IMM_FLOAT32" }; -static const char *TGSI_OPCODES[TGSI_OPCODE_LAST] = -{ - "OPCODE_ARL", - "OPCODE_MOV", - "OPCODE_LIT", - "OPCODE_RCP", - "OPCODE_RSQ", - "OPCODE_EXP", - "OPCODE_LOG", - "OPCODE_MUL", - "OPCODE_ADD", - "OPCODE_DP3", - "OPCODE_DP4", - "OPCODE_DST", - "OPCODE_MIN", - "OPCODE_MAX", - "OPCODE_SLT", - "OPCODE_SGE", - "OPCODE_MAD", - "OPCODE_SUB", - "OPCODE_LERP", - "OPCODE_CND", - "OPCODE_CND0", - "OPCODE_DOT2ADD", - "OPCODE_INDEX", - "OPCODE_NEGATE", - "OPCODE_FRAC", - "OPCODE_CLAMP", - "OPCODE_FLOOR", - "OPCODE_ROUND", - "OPCODE_EXPBASE2", - "OPCODE_LOGBASE2", - "OPCODE_POWER", - "OPCODE_CROSSPRODUCT", - "OPCODE_MULTIPLYMATRIX", - "OPCODE_ABS", - "OPCODE_RCC", - "OPCODE_DPH", - "OPCODE_COS", - "OPCODE_DDX", - "OPCODE_DDY", - "OPCODE_KILP", - "OPCODE_PK2H", - "OPCODE_PK2US", - "OPCODE_PK4B", - "OPCODE_PK4UB", - "OPCODE_RFL", - "OPCODE_SEQ", - "OPCODE_SFL", - "OPCODE_SGT", - "OPCODE_SIN", - "OPCODE_SLE", - "OPCODE_SNE", - "OPCODE_STR", - "OPCODE_TEX", - "OPCODE_TXD", - "OPCODE_TXP", - "OPCODE_UP2H", - "OPCODE_UP2US", - "OPCODE_UP4B", - "OPCODE_UP4UB", - "OPCODE_X2D", - "OPCODE_ARA", - "OPCODE_ARR", - "OPCODE_BRA", - "OPCODE_CAL", - "OPCODE_RET", - "OPCODE_SSG", - "OPCODE_CMP", - "OPCODE_SCS", - "OPCODE_TXB", - "OPCODE_NRM", - "OPCODE_DIV", - "OPCODE_DP2", - "OPCODE_TXL", - "OPCODE_BRK", - "OPCODE_IF", - "OPCODE_LOOP", - "OPCODE_REP", - "OPCODE_ELSE", - "OPCODE_ENDIF", - "OPCODE_ENDLOOP", - "OPCODE_ENDREP", - "OPCODE_PUSHA", - "OPCODE_POPA", - "OPCODE_CEIL", - "OPCODE_I2F", - "OPCODE_NOT", - "OPCODE_TRUNC", - "OPCODE_SHL", - "OPCODE_SHR", - "OPCODE_AND", - "OPCODE_OR", - "OPCODE_MOD", - "OPCODE_XOR", - "OPCODE_SAD", - "OPCODE_TXF", - "OPCODE_TXQ", - "OPCODE_CONT", - "OPCODE_EMIT", - "OPCODE_ENDPRIM", - "OPCODE_BGNLOOP2", - "OPCODE_BGNSUB", - "OPCODE_ENDLOOP2", - "OPCODE_ENDSUB", - "OPCODE_NOISE1", - "OPCODE_NOISE2", - "OPCODE_NOISE3", - "OPCODE_NOISE4", - "OPCODE_NOP", - "OPCODE_M4X3", - "OPCODE_M3X4", - "OPCODE_M3X3", - "OPCODE_M3X2", - "OPCODE_NRM4", - "OPCODE_CALLNZ", - "OPCODE_IFC", - "OPCODE_BREAKC", - "OPCODE_KIL", - "OPCODE_END" -}; - static const char *TGSI_SATS[] = { "SAT_NONE", @@ -428,8 +307,8 @@ dump_instruction_verbose( { unsigned i; - TXT( "\nOpcode : " ); - ENM( inst->Instruction.Opcode, TGSI_OPCODES ); + TXT( "\nOpcode : OPCODE_" ); + TXT( tgsi_get_opcode_info( inst->Instruction.Opcode )->mnemonic ); if( deflt || fi->Instruction.Saturate != inst->Instruction.Saturate ) { TXT( "\nSaturate : " ); ENM( inst->Instruction.Saturate, TGSI_SATS ); @@ -770,10 +649,6 @@ tgsi_dump_c( uint deflt = flags & TGSI_DUMP_C_DEFAULT; uint instno = 0; - /* sanity checks */ - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); - tgsi_parse_init( &parse, tokens ); TXT( "tgsi-dump begin -----------------" ); -- cgit v1.2.3 From 4b929b32d03a58d80cacbd63c172dbd7221c8a8f Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 17:31:26 +0200 Subject: tgsi: Validate instruction opcode and operand counts. --- src/gallium/auxiliary/tgsi/tgsi_sanity.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c index 2e3ec96b5b..0b5bdd6ba1 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c @@ -27,6 +27,7 @@ #include "pipe/p_debug.h" #include "tgsi_sanity.h" +#include "tgsi_info.h" #include "tgsi_iterate.h" #define MAX_REGISTERS 256 @@ -170,6 +171,7 @@ iter_instruction( struct tgsi_full_instruction *inst ) { struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter; + const struct tgsi_opcode_info *info; uint i; /* There must be no other instructions after END. @@ -181,6 +183,19 @@ iter_instruction( ctx->index_of_END = ctx->num_instructions; } + info = tgsi_get_opcode_info( inst->Instruction.Opcode ); + if (info == NULL) { + report_error( ctx, "Invalid instruction opcode" ); + return TRUE; + } + + if (info->num_dst != inst->Instruction.NumDstRegs) { + report_error( ctx, "Invalid number of destination operands" ); + } + if (info->num_src != inst->Instruction.NumSrcRegs) { + report_error( ctx, "Invalid number of source operands" ); + } + /* Check destination and source registers' validity. * Mark the registers as used. */ -- cgit v1.2.3 From bfdb1d55d58d70044af9fcd6f8465179145581dd Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 19:28:10 +0200 Subject: tgsi: Fix typo. --- src/gallium/auxiliary/tgsi/tgsi_build.c | 4 ++-- src/gallium/auxiliary/tgsi/tgsi_build.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index 742ef14c35..050b448fe7 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -820,7 +820,7 @@ tgsi_build_instruction_ext_nv( unsigned cond_swizzle_z, unsigned cond_swizzle_w, unsigned cond_dst_update, - unsigned cond_flow_update, + unsigned cond_flow_enable, struct tgsi_token *prev_token, struct tgsi_instruction *instruction, struct tgsi_header *header ) @@ -837,7 +837,7 @@ tgsi_build_instruction_ext_nv( instruction_ext_nv.CondSwizzleZ = cond_swizzle_z; instruction_ext_nv.CondSwizzleW = cond_swizzle_w; instruction_ext_nv.CondDstUpdate = cond_dst_update; - instruction_ext_nv.CondFlowEnable = cond_flow_update; + instruction_ext_nv.CondFlowEnable = cond_flow_enable; prev_token->Extended = 1; instruction_grow( instruction, header ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h index ed25830248..6ae7f324f8 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.h +++ b/src/gallium/auxiliary/tgsi/tgsi_build.h @@ -170,7 +170,7 @@ tgsi_build_instruction_ext_nv( unsigned cond_swizzle_z, unsigned cond_swizzle_w, unsigned cond_dst_update, - unsigned cond_flow_update, + unsigned cond_flow_enable, struct tgsi_token *prev_token, struct tgsi_instruction *instruction, struct tgsi_header *header ); -- cgit v1.2.3 From 83a5a225d773c119857f58672fd51c1d425f21d3 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 19:31:13 +0200 Subject: tgsi: Use a homebrew version of toupper(). --- src/gallium/auxiliary/tgsi/tgsi_text.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 7cdf1b67c5..9454563361 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -51,11 +51,18 @@ static boolean is_digit_alpha_underscore( const char *cur ) return is_digit( cur ) || is_alpha_underscore( cur ); } +static boolean uprcase( char c ) +{ + if (c >= 'a' && c <= 'z') + return c += 'A' - 'a'; + return c; +} + static boolean str_match_no_case( const char **pcur, const char *str ) { const char *cur = *pcur; - while (*str != '\0' && *str == toupper( *cur )) { + while (*str != '\0' && *str == uprcase( *cur )) { str++; cur++; } @@ -131,7 +138,7 @@ static boolean parse_float( const char **pcur, float *val ) } if (!integral_part && !fractional_part) return FALSE; - if (toupper( *cur ) == 'E') { + if (uprcase( *cur ) == 'E') { cur++; if (*cur == '-' || *cur == '+') cur++; @@ -258,19 +265,19 @@ parse_opt_writemask( cur++; *writemask = TGSI_WRITEMASK_NONE; eat_opt_white( &cur ); - if (toupper( *cur ) == 'X') { + if (uprcase( *cur ) == 'X') { cur++; *writemask |= TGSI_WRITEMASK_X; } - if (toupper( *cur ) == 'Y') { + if (uprcase( *cur ) == 'Y') { cur++; *writemask |= TGSI_WRITEMASK_Y; } - if (toupper( *cur ) == 'Z') { + if (uprcase( *cur ) == 'Z') { cur++; *writemask |= TGSI_WRITEMASK_Z; } - if (toupper( *cur ) == 'W') { + if (uprcase( *cur ) == 'W') { cur++; *writemask |= TGSI_WRITEMASK_W; } @@ -516,13 +523,13 @@ parse_optional_swizzle( cur++; eat_opt_white( &cur ); for (i = 0; i < 4; i++) { - if (toupper( *cur ) == 'X') + if (uprcase( *cur ) == 'X') swizzle[i] = TGSI_SWIZZLE_X; - else if (toupper( *cur ) == 'Y') + else if (uprcase( *cur ) == 'Y') swizzle[i] = TGSI_SWIZZLE_Y; - else if (toupper( *cur ) == 'Z') + else if (uprcase( *cur ) == 'Z') swizzle[i] = TGSI_SWIZZLE_Z; - else if (toupper( *cur ) == 'W') + else if (uprcase( *cur ) == 'W') swizzle[i] = TGSI_SWIZZLE_W; else { if (*cur == '0') -- cgit v1.2.3 From 3a1af846fe13c2a9b8c24eb7e37e11a9b42668d5 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Wed, 13 Aug 2008 20:09:56 +0200 Subject: tgsi: Initial code for KILP, needs CCs working to be complete. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index c4ba667d32..df2a7cc4b3 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1234,11 +1234,29 @@ static void exec_kilp(struct tgsi_exec_machine *mach, const struct tgsi_full_instruction *inst) { - uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ + if (inst->InstructionExtNv.CondFlowEnable) { + uint swizzle[4]; + uint chan_index; + uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ - /* TODO: build kilmask from CC mask */ + swizzle[0] = inst->InstructionExtNv.CondSwizzleX; + swizzle[1] = inst->InstructionExtNv.CondSwizzleY; + swizzle[2] = inst->InstructionExtNv.CondSwizzleZ; + swizzle[3] = inst->InstructionExtNv.CondSwizzleW; - mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; + for (chan_index = 0; chan_index < 4; chan_index++) + { + uint i; + + for (i = 0; i < 4; i++) { + /* TODO: evaluate the condition code */ + if (0) + kilmask |= 1 << i; + } + } + + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; + } } -- cgit v1.2.3 From 19ff2326e94a7a773bcb1dd9bfd22197b999daf9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 13 Aug 2008 17:20:40 -0600 Subject: gallium: fix exec_kilp(), fix Exec/FuncMask test for TGSI_OPCODE_RET Fixes a few glean glsl regressions. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index df2a7cc4b3..a96209db1a 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1234,10 +1234,13 @@ static void exec_kilp(struct tgsi_exec_machine *mach, const struct tgsi_full_instruction *inst) { + uint kilmask; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ + if (inst->InstructionExtNv.CondFlowEnable) { uint swizzle[4]; uint chan_index; - uint kilmask = 0; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */ + + kilmask = 0x0; swizzle[0] = inst->InstructionExtNv.CondSwizzleX; swizzle[1] = inst->InstructionExtNv.CondSwizzleY; @@ -1254,9 +1257,12 @@ exec_kilp(struct tgsi_exec_machine *mach, kilmask |= 1 << i; } } - - mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; } + else { + /* "unconditional" kil */ + kilmask = mach->ExecMask; + } + mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask; } @@ -2176,7 +2182,7 @@ exec_instruction( mach->FuncMask &= ~mach->ExecMask; UPDATE_EXEC_MASK(mach); - if (mach->ExecMask == 0x0) { + if (mach->FuncMask == 0x0) { /* really return now (otherwise, keep executing */ if (mach->CallStackTop == 0) { -- cgit v1.2.3 From 73467e1080d94e6d5cfb52f71c845c09a78adcd9 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Thu, 14 Aug 2008 09:52:15 +0100 Subject: check for winsys->destroy before calling --- src/gallium/drivers/i915simple/i915_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index e3d19017b5..e2bf5ab678 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -45,7 +45,7 @@ static void i915_destroy( struct pipe_context *pipe ) draw_destroy( i915->draw ); - if(i915->winsys) + if(i915->winsys->destroy) i915->winsys->destroy(i915->winsys); FREE( i915 ); -- cgit v1.2.3 From d756f9512d295531ff6a600c736a68ac2dcff58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 13 Aug 2008 12:13:54 +0100 Subject: translate: Draw can request up to PIPE_MAX_ATTRIBS + 1 vertex elements. --- src/gallium/auxiliary/translate/translate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index c3b754a902..650cd81fa6 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -57,7 +57,7 @@ struct translate_element struct translate_key { unsigned output_stride; unsigned nr_elements; - struct translate_element element[PIPE_MAX_ATTRIBS]; + struct translate_element element[PIPE_MAX_ATTRIBS + 1]; }; -- cgit v1.2.3 From 0ecaa37e49ff3a745b821ba7027eebeed938547a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 13 Aug 2008 12:31:53 +0100 Subject: python: Bindings fixes. --- src/gallium/state_trackers/python/gallium.i | 2 ++ src/gallium/state_trackers/python/p_context.i | 32 ++++++++++++++++++--------- src/gallium/state_trackers/python/p_state.i | 6 +++++ src/gallium/state_trackers/python/st_device.h | 4 ++++ 4 files changed, 34 insertions(+), 10 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 8d7a49cee7..641b19e940 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -55,6 +55,8 @@ %} +%include "typemaps.i" + %include "carrays.i" %array_class(unsigned char, ByteArray); %array_class(int, IntArray); diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 521a2dee07..a23c805852 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -110,7 +110,7 @@ struct st_context { { struct pipe_constant_buffer state; memset(&state, 0, sizeof(state)); - state.buffer = buffer->buffer; + state.buffer = buffer ? buffer->buffer : NULL; state.size = buffer->buffer->size; $self->pipe->set_constant_buffer($self->pipe, shader, index, &state); } @@ -154,23 +154,31 @@ struct st_context { state.pitch = pitch; state.max_index = max_index; state.buffer_offset = buffer_offset; - state.buffer = buffer->buffer; + state.buffer = buffer ? buffer->buffer : NULL; memcpy(&$self->vertex_buffers[index], &state, sizeof(state)); for(i = 0; i < PIPE_MAX_ATTRIBS; ++i) if(self->vertex_buffers[i].buffer) - num_vertex_buffers = i + 1; + $self->num_vertex_buffers = i + 1; $self->pipe->set_vertex_buffers($self->pipe, - num_vertex_buffers, + $self->num_vertex_buffers, $self->vertex_buffers); } void set_vertex_element(unsigned index, - const struct pipe_vertex_element *element) { + const struct pipe_vertex_element *element) + { memcpy(&$self->vertex_elements[index], element, sizeof(*element)); - $self->pipe->set_vertex_elements($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_elements); + } + + void set_vertex_elements(unsigned num) + { + $self->num_vertex_elements = num; + $self->pipe->set_vertex_elements($self->pipe, + $self->num_vertex_elements, + $self->vertex_elements); } /* @@ -183,8 +191,12 @@ struct st_context { void draw_elements( struct st_buffer *indexBuffer, unsigned indexSize, - unsigned mode, unsigned start, unsigned count) { - $self->pipe->draw_elements($self->pipe, indexBuffer->buffer, indexSize, mode, start, count); + unsigned mode, unsigned start, unsigned count) + { + $self->pipe->draw_elements($self->pipe, + indexBuffer->buffer, + indexSize, + mode, start, count); } void draw_vertices(unsigned prim, @@ -222,9 +234,9 @@ error1: } void - flush(void) { + flush(unsigned flags = 0) { struct pipe_fence_handle *fence = NULL; - $self->pipe->flush($self->pipe, PIPE_FLUSH_RENDER_CACHE, &fence); + $self->pipe->flush($self->pipe, flags | PIPE_FLUSH_RENDER_CACHE, &fence); /* TODO: allow asynchronous operation */ $self->pipe->winsys->fence_finish( $self->pipe->winsys, fence, 0 ); $self->pipe->winsys->fence_reference( $self->pipe->winsys, &fence, NULL ); diff --git a/src/gallium/state_trackers/python/p_state.i b/src/gallium/state_trackers/python/p_state.i index 9834229b4b..7f5760b3b6 100644 --- a/src/gallium/state_trackers/python/p_state.i +++ b/src/gallium/state_trackers/python/p_state.i @@ -34,9 +34,15 @@ %module gallium; +%ignore winsys; +%ignore pipe_vertex_buffer::buffer; + %include "pipe/p_state.h"; +%array_class(struct pipe_stencil_state, StencilArray); + + %extend pipe_framebuffer_state { pipe_framebuffer_state(void) { diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h index 5b7adbe1a0..644c263b53 100644 --- a/src/gallium/state_trackers/python/st_device.h +++ b/src/gallium/state_trackers/python/st_device.h @@ -57,7 +57,11 @@ struct st_context { struct pipe_texture *default_texture; struct pipe_texture *sampler_textures[PIPE_MAX_SAMPLERS]; + + unsigned num_vertex_buffers; struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; + + unsigned num_vertex_elements; struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS]; }; -- cgit v1.2.3 From 50c6092355edf9e978a3c34cb816d4833bcf92fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 13 Aug 2008 12:41:19 +0100 Subject: python: Simplify st_winsys. --- src/gallium/state_trackers/python/st_device.c | 8 +++----- .../state_trackers/python/st_hardpipe_winsys.c | 18 +----------------- .../state_trackers/python/st_softpipe_winsys.c | 21 +++++---------------- src/gallium/state_trackers/python/st_winsys.h | 6 ------ 4 files changed, 9 insertions(+), 44 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index fbd56712e0..c82261e4e7 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -41,7 +41,7 @@ static void st_device_really_destroy(struct st_device *st_dev) { if(st_dev->screen) - st_dev->st_ws->screen_destroy(st_dev->screen); + st_dev->screen->destroy(st_dev->screen); FREE(st_dev); } @@ -61,9 +61,7 @@ st_device_create_from_st_winsys(const struct st_winsys *st_ws) struct st_device *st_dev; if(!st_ws->screen_create || - !st_ws->screen_destroy || - !st_ws->context_create || - !st_ws->context_destroy) + !st_ws->context_create) return NULL; st_dev = CALLOC_STRUCT(st_device); @@ -106,7 +104,7 @@ st_context_destroy(struct st_context *st_ctx) } if(st_ctx->pipe) - st_ctx->st_dev->st_ws->context_destroy(st_ctx->pipe); + st_ctx->pipe->destroy(st_ctx->pipe); for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) pipe_texture_reference(&st_ctx->sampler_textures[i], NULL); diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c index 1e04998232..8b33c70fd7 100644 --- a/src/gallium/state_trackers/python/st_hardpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c @@ -42,13 +42,6 @@ extern void init_gallium(void); void (*force_init_gallium_linkage)(void) = &init_gallium; -static void -st_hardpipe_screen_destroy(struct pipe_screen *screen) -{ - st_softpipe_winsys.screen_destroy(screen); -} - - static struct pipe_screen * st_hardpipe_screen_create(void) { @@ -56,13 +49,6 @@ st_hardpipe_screen_create(void) } -static void -st_hardpipe_context_destroy(struct pipe_context *pipe) -{ - st_softpipe_winsys.context_destroy(pipe); -} - - static struct pipe_context * st_hardpipe_context_create(struct pipe_screen *screen) { @@ -72,7 +58,5 @@ st_hardpipe_context_create(struct pipe_screen *screen) const struct st_winsys st_hardpipe_winsys = { &st_hardpipe_screen_create, - &st_hardpipe_screen_destroy, - &st_hardpipe_context_create, - &st_hardpipe_context_destroy + &st_hardpipe_context_create }; diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c index 1fda70ca00..6ea3c9a5cf 100644 --- a/src/gallium/state_trackers/python/st_softpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -253,13 +253,9 @@ st_softpipe_fence_finish(struct pipe_winsys *winsys, } -static void -st_softpipe_screen_destroy(struct pipe_screen *screen) +static void +st_softpipe_destroy(struct pipe_winsys *winsys) { - struct pipe_winsys *winsys = screen->winsys; - - screen->destroy(screen); - FREE(winsys); } @@ -274,6 +270,8 @@ st_softpipe_screen_create(void) if(!winsys) return NULL; + winsys->destroy = st_softpipe_destroy; + winsys->buffer_create = st_softpipe_buffer_create; winsys->user_buffer_create = st_softpipe_user_buffer_create; winsys->buffer_map = st_softpipe_buffer_map; @@ -293,19 +291,12 @@ st_softpipe_screen_create(void) screen = softpipe_create_screen(winsys); if(!screen) - FREE(winsys); + st_softpipe_destroy(winsys); return screen; } -static void -st_softpipe_context_destroy(struct pipe_context *pipe) -{ - pipe->destroy(pipe); -} - - static struct pipe_context * st_softpipe_context_create(struct pipe_screen *screen) { @@ -315,7 +306,5 @@ st_softpipe_context_create(struct pipe_screen *screen) const struct st_winsys st_softpipe_winsys = { &st_softpipe_screen_create, - &st_softpipe_screen_destroy, &st_softpipe_context_create, - &st_softpipe_context_destroy }; diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h index 43db8b6bff..b8cb612d86 100644 --- a/src/gallium/state_trackers/python/st_winsys.h +++ b/src/gallium/state_trackers/python/st_winsys.h @@ -39,14 +39,8 @@ struct st_winsys struct pipe_screen * (*screen_create)(void); - void - (*screen_destroy)(struct pipe_screen *screen); - struct pipe_context * (*context_create)(struct pipe_screen *screen); - - void - (*context_destroy)(struct pipe_context *pipe); }; -- cgit v1.2.3 From a8540ef9fb22bbedc788c374fda3354047df110f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 09:44:49 +0100 Subject: gallium: Catch errors from posix_memalign. --- src/gallium/include/pipe/p_util.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index eec413842f..4e1a996122 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -213,7 +213,8 @@ align_malloc(size_t bytes, uint alignment) { #if defined(HAVE_POSIX_MEMALIGN) void *mem; - (void) posix_memalign(& mem, alignment, bytes); + if(posix_memalign(& mem, alignment, bytes) != 0) + return NULL; return mem; #else char *ptr, *buf; -- cgit v1.2.3 From 449cb6b37b54bd6e4a7058e97739d9634ccefaa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 10:10:53 +0100 Subject: mesa: posix_memalign requires alignment to be multiple of sizeof(void*) --- src/gallium/include/pipe/p_util.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 4e1a996122..b4ab70a3fc 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -213,6 +213,7 @@ align_malloc(size_t bytes, uint alignment) { #if defined(HAVE_POSIX_MEMALIGN) void *mem; + alignment = (alignment + (uint)sizeof(void*) - 1) & ~((uint)sizeof(void*) - 1); if(posix_memalign(& mem, alignment, bytes) != 0) return NULL; return mem; -- cgit v1.2.3 From 3c90678ea69ee8be832e16d42a1b8049a49535e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 10:46:38 +0100 Subject: trace: Separate the trace screen/context vs the original screen/context. --- src/gallium/drivers/trace/tr_context.c | 13 +++++-------- src/gallium/drivers/trace/tr_context.h | 3 ++- src/gallium/drivers/trace/tr_screen.c | 24 ++++++++++++++++++------ src/gallium/drivers/trace/tr_winsys.c | 23 +++++++---------------- src/gallium/drivers/trace/tr_winsys.h | 3 ++- 5 files changed, 34 insertions(+), 32 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index f82126370c..e43fc01c55 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -959,7 +959,8 @@ trace_context_destroy(struct pipe_context *_pipe) struct pipe_context * -trace_context_create(struct pipe_context *pipe) +trace_context_create(struct pipe_screen *screen, + struct pipe_context *pipe) { struct trace_stream *stream; struct trace_context *tr_ctx; @@ -971,8 +972,8 @@ trace_context_create(struct pipe_context *pipe) if(!tr_ctx) return NULL; - tr_ctx->base.winsys = pipe->winsys; - tr_ctx->base.screen = pipe->screen; + tr_ctx->base.winsys = screen->winsys; + tr_ctx->base.screen = screen; tr_ctx->base.destroy = trace_context_destroy; tr_ctx->base.set_edgeflags = trace_context_set_edgeflags; tr_ctx->base.draw_arrays = trace_context_draw_arrays; @@ -1017,11 +1018,7 @@ trace_context_create(struct pipe_context *pipe) tr_ctx->base.flush = trace_context_flush; tr_ctx->pipe = pipe; - tr_ctx->stream = stream = trace_winsys(pipe->winsys)->stream; - - /* We don't want to trace the internal pipe calls */ - pipe->winsys = trace_winsys(pipe->winsys)->winsys; - pipe->screen = trace_screen(pipe->screen)->screen; + tr_ctx->stream = stream = trace_screen(screen)->stream; trace_dump_call_begin(stream, "", "pipe_context_create"); trace_dump_arg_begin(stream, "screen"); diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 2c0b0c72e4..1aa822ba02 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -57,7 +57,8 @@ trace_context(struct pipe_context *pipe) struct pipe_context * -trace_context_create(struct pipe_context *pipe); +trace_context_create(struct pipe_screen *screen, + struct pipe_context *pipe); #endif /* TR_CONTEXT_H_ */ diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 27c218039e..0e253123ae 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -338,7 +338,11 @@ trace_screen_destroy(struct pipe_screen *_screen) screen->destroy(screen); trace_dump_call_end(stream); - + + trace_dump_trace_end(stream); + + trace_stream_close(stream); + FREE(tr_scr); } @@ -348,6 +352,7 @@ trace_screen_create(struct pipe_screen *screen) { struct trace_stream *stream; struct trace_screen *tr_scr; + struct pipe_winsys *winsys; if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) return screen; @@ -356,7 +361,17 @@ trace_screen_create(struct pipe_screen *screen) if(!tr_scr) return NULL; - tr_scr->base.winsys = screen->winsys; + tr_scr->stream = stream = trace_stream_create("gallium", "trace"); + if(!tr_scr->stream) + return NULL; + + trace_dump_trace_begin(stream, 0); + + winsys = trace_winsys_create(stream, screen->winsys); + if(!winsys) + return NULL; + + tr_scr->base.winsys = winsys; tr_scr->base.destroy = trace_screen_destroy; tr_scr->base.get_name = trace_screen_get_name; tr_scr->base.get_vendor = trace_screen_get_vendor; @@ -372,10 +387,7 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->base.surface_unmap = trace_screen_surface_unmap; tr_scr->screen = screen; - tr_scr->stream = stream = trace_winsys(screen->winsys)->stream; - - /* We don't want to trace the internal pipe calls */ - screen->winsys = trace_winsys(screen->winsys)->winsys; + tr_scr->stream = stream = trace_winsys(winsys)->stream; trace_dump_call_begin(stream, "", "pipe_screen_create"); trace_dump_arg_begin(stream, "winsys"); diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index eec84a1981..524049148d 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -393,28 +393,24 @@ trace_winsys_destroy(struct pipe_winsys *_winsys) trace_dump_arg(stream, ptr, winsys); - winsys->destroy(winsys); + /* + winsys->destroy(winsys); + */ trace_dump_call_end(stream); - trace_dump_trace_end(stream); - hash_table_destroy(tr_ws->buffer_maps); - trace_stream_close(tr_ws->stream); - FREE(tr_ws); } struct pipe_winsys * -trace_winsys_create(struct pipe_winsys *winsys) +trace_winsys_create(struct trace_stream *stream, + struct pipe_winsys *winsys) { - struct trace_stream *stream; - struct trace_winsys *tr_ws; - if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) - return winsys; + struct trace_winsys *tr_ws; tr_ws = CALLOC_STRUCT(trace_winsys); if(!tr_ws) @@ -436,18 +432,13 @@ trace_winsys_create(struct pipe_winsys *winsys) tr_ws->base.fence_finish = trace_winsys_fence_finish; tr_ws->winsys = winsys; - - tr_ws->stream = stream = trace_stream_create("gallium", "trace"); - if(!tr_ws->stream) - return NULL; + tr_ws->stream = stream; tr_ws->buffer_maps = hash_table_create(trace_buffer_hash, trace_buffer_compare); if(!tr_ws->buffer_maps) return NULL; - trace_dump_trace_begin(tr_ws->stream, 0); - trace_dump_call_begin(stream, "", "pipe_winsys_create"); trace_dump_ret(stream, ptr, winsys); trace_dump_call_end(stream); diff --git a/src/gallium/drivers/trace/tr_winsys.h b/src/gallium/drivers/trace/tr_winsys.h index a3576da867..704d2c57c8 100644 --- a/src/gallium/drivers/trace/tr_winsys.h +++ b/src/gallium/drivers/trace/tr_winsys.h @@ -60,7 +60,8 @@ trace_winsys(struct pipe_winsys *winsys) struct pipe_winsys * -trace_winsys_create(struct pipe_winsys *winsys); +trace_winsys_create(struct trace_stream *stream, + struct pipe_winsys *winsys); #endif /* TR_WINSYS_H_ */ -- cgit v1.2.3 From 969ff9e9bf3dfae08d087bbc47ce43f17d107bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 10:47:39 +0100 Subject: xlib: Use trace usage. --- src/gallium/winsys/xlib/xm_api.c | 5 ++++- src/gallium/winsys/xlib/xm_winsys.c | 15 ++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index 4e5441a13d..d2f92a0875 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -67,6 +67,7 @@ #include "state_tracker/st_public.h" #include "state_tracker/st_context.h" #include "pipe/p_defines.h" +#include "pipe/p_screen.h" #include "pipe/p_context.h" #include "xm_winsys_aub.h" @@ -833,7 +834,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) fail: if (c->st) st_destroy_context(c->st); - if (pipe) + else if (pipe) pipe->destroy(pipe); FREE(c); return NULL; @@ -844,7 +845,9 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) PUBLIC void XMesaDestroyContext( XMesaContext c ) { + struct pipe_screen *screen = c->st->pipe->screen; st_destroy_context(c->st); + screen->destroy(screen); _mesa_free(c); } diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 6071a5ad5e..3ab4c67cae 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -55,7 +55,6 @@ #endif #ifdef GALLIUM_TRACE -#include "trace/tr_winsys.h" #include "trace/tr_screen.h" #include "trace/tr_context.h" #endif @@ -651,11 +650,7 @@ xmesa_get_pipe_winsys(struct xmesa_visual *xm_vis) ws->base.get_name = xm_get_name; } -#ifdef GALLIUM_TRACE - return trace_winsys_create(&ws->base); -#else - return &ws->base; -#endif + return &ws->base; } @@ -684,14 +679,12 @@ xmesa_create_pipe_context(XMesaContext xmesa, uint pixelformat) { struct pipe_screen *screen = softpipe_create_screen(pws); -#ifdef GALLIUM_TRACE - screen = trace_screen_create(screen); -#endif - pipe = softpipe_create(screen, pws, NULL); #ifdef GALLIUM_TRACE - pipe = trace_context_create(pipe); + screen = trace_screen_create(screen); + + pipe = trace_context_create(screen, pipe); #endif } -- cgit v1.2.3 From 90ed1742d55a246ffa63e57f291b18a1a43e41ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 10:47:55 +0100 Subject: python: Remove unused var. --- src/gallium/state_trackers/python/p_context.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index a23c805852..535783b641 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -147,7 +147,7 @@ struct st_context { unsigned buffer_offset, struct st_buffer *buffer) { - unsigned i, num_vertex_buffers; + unsigned i; struct pipe_vertex_buffer state; memset(&state, 0, sizeof(state)); -- cgit v1.2.3 From 92675f6e22a1caa11146c2e9f3b2fb2285fdccea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 10:48:29 +0100 Subject: python: Fix typo in buffer::write. --- src/gallium/state_trackers/python/p_texture.i | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i index fd38e0733f..06bc105465 100644 --- a/src/gallium/state_trackers/python/p_texture.i +++ b/src/gallium/state_trackers/python/p_texture.i @@ -183,8 +183,20 @@ struct st_buffer { struct pipe_winsys *winsys = $self->st_dev->screen->winsys; char *map; + assert($self->buffer->refcount); + + if(offset > $self->buffer->size) { + PyErr_SetString(PyExc_ValueError, "offset must be smaller than buffer size"); + return; + } + + if(offset + LENGTH > $self->buffer->size) { + PyErr_SetString(PyExc_ValueError, "data length must fit inside the buffer"); + return; + } + map = winsys->buffer_map(winsys, $self->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); - if(!map) { + if(map) { memcpy(map + offset, STRING, LENGTH); winsys->buffer_unmap(winsys, $self->buffer); } -- cgit v1.2.3 From ffaa4e816fb1d7360e6c14cbbfd4df8e027b9573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 10:58:23 +0100 Subject: python: Allow to use trace pipe driver with python. --- src/gallium/state_trackers/python/SConscript | 2 +- src/gallium/state_trackers/python/st_device.c | 35 ++++++++++++++++++++++----- src/gallium/state_trackers/python/st_device.h | 4 ++- 3 files changed, 33 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index 973d96d55a..1581182aec 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -30,5 +30,5 @@ if 'python' in env['statetrackers']: source = [ 'st_hardpipe_winsys.c', ], - LIBS = [pyst, softpipe] + auxiliaries + env['LIBS'], + LIBS = [pyst, softpipe, trace] + auxiliaries + env['LIBS'], ) diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index c82261e4e7..a1889539dc 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -33,6 +33,9 @@ #include "pipe/p_inlines.h" #include "cso_cache/cso_context.h" #include "util/u_simple_shaders.h" +#include "trace/tr_screen.h" +#include "trace/tr_context.h" + #include "st_device.h" #include "st_winsys.h" @@ -71,9 +74,17 @@ st_device_create_from_st_winsys(const struct st_winsys *st_ws) st_dev->refcount = 1; st_dev->st_ws = st_ws; - st_dev->screen = st_ws->screen_create(); - if(!st_dev->screen) + st_dev->real_screen = st_ws->screen_create(); + if(!st_dev->real_screen) { + st_device_destroy(st_dev); + return NULL; + } + + st_dev->screen = trace_screen_create(st_dev->real_screen); + if(!st_dev->screen) { st_device_destroy(st_dev); + return NULL; + } return st_dev; } @@ -130,13 +141,23 @@ st_context_create(struct st_device *st_dev) st_ctx->st_dev = st_dev; ++st_dev->refcount; - st_ctx->pipe = st_dev->st_ws->context_create(st_dev->screen); - if(!st_ctx->pipe) + st_ctx->real_pipe = st_dev->st_ws->context_create(st_dev->real_screen); + if(!st_ctx->real_pipe) { st_context_destroy(st_ctx); + return NULL; + } + st_ctx->pipe = trace_context_create(st_dev->screen, st_ctx->real_pipe); + if(!st_ctx->pipe) { + st_context_destroy(st_ctx); + return NULL; + } + st_ctx->cso = cso_create_context(st_ctx->pipe); - if(!st_ctx->cso) + if(!st_ctx->cso) { st_context_destroy(st_ctx); + return NULL; + } /* disabled blending/masking */ { @@ -291,8 +312,10 @@ st_buffer_create(struct st_device *st_dev, st_buf->st_dev = st_dev; st_buf->buffer = winsys->buffer_create(winsys, alignment, usage, size); - if(!st_buf->buffer) + if(!st_buf->buffer) { st_buffer_destroy(st_buf); + return NULL; + } return st_buf; } diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h index 644c263b53..7cfe6de9f6 100644 --- a/src/gallium/state_trackers/python/st_device.h +++ b/src/gallium/state_trackers/python/st_device.h @@ -48,6 +48,7 @@ struct st_buffer { struct st_context { struct st_device *st_dev; + struct pipe_context *real_pipe; struct pipe_context *pipe; struct cso_context *cso; @@ -68,7 +69,8 @@ struct st_context { struct st_device { const struct st_winsys *st_ws; - + + struct pipe_screen *real_screen; struct pipe_screen *screen; /* FIXME: we also need to refcount for textures and surfaces... */ -- cgit v1.2.3 From 468c9775cbc863b024f41fccad3d6bb967e10ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 11:00:22 +0100 Subject: python/retrace: Application capable of replaying gallium traces. At the moment it is capable of replaying trivial/tri kind of apps. See README for status. --- src/gallium/state_trackers/python/retrace/README | 18 + .../state_trackers/python/retrace/interpreter.py | 418 +++++++++++++++++++++ src/gallium/state_trackers/python/retrace/model.py | 151 ++++++++ .../state_trackers/python/retrace/parser.py | 332 ++++++++++++++++ 4 files changed, 919 insertions(+) create mode 100644 src/gallium/state_trackers/python/retrace/README create mode 100755 src/gallium/state_trackers/python/retrace/interpreter.py create mode 100755 src/gallium/state_trackers/python/retrace/model.py create mode 100755 src/gallium/state_trackers/python/retrace/parser.py (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/retrace/README b/src/gallium/state_trackers/python/retrace/README new file mode 100644 index 0000000000..c0ad8ae6c1 --- /dev/null +++ b/src/gallium/state_trackers/python/retrace/README @@ -0,0 +1,18 @@ +This is + + +To use it follow the instructions in src/gallium/drivers/trace/README and +src/gallium/state_trackers/python/README, and then do + + python src/gallium/state_trackers/python/samples/retrace/interpreter.py filename.trace + + + + +This is still work in progress: +- not everything is captured/replayed + - surface/textures contents +- any tiny error will result in a crash + +-- +Jose Fonseca diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py new file mode 100755 index 0000000000..ae62bc04a8 --- /dev/null +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -0,0 +1,418 @@ +#!/usr/bin/env python +############################################################################# +# +# Copyright 2008 Tungsten Graphics, Inc. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +############################################################################# + + +import sys +import gallium +import model +from parser import TraceParser + + +def make_image(surface): + pixels = gallium.FloatArray(surface.height*surface.width*4) + surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) + + import Image + outimage = Image.new( + mode='RGB', + size=(surface.width, surface.height), + color=(0,0,0)) + outpixels = outimage.load() + for y in range(0, surface.height): + for x in range(0, surface.width): + offset = (y*surface.width + x)*4 + r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] + outpixels[x, y] = r, g, b + return outimage + +def save_image(filename, surface): + outimage = make_image(surface) + outimage.save(filename, "PNG") + +def show_image(surface): + outimage = make_image(surface) + + import Tkinter as tk + from PIL import Image, ImageTk + root = tk.Tk() + + root.title('background image') + + image1 = ImageTk.PhotoImage(outimage) + w = image1.width() + h = image1.height() + x = 100 + y = 100 + root.geometry("%dx%d+%d+%d" % (w, h, x, y)) + panel1 = tk.Label(root, image=image1) + panel1.pack(side='top', fill='both', expand='yes') + panel1.image = image1 + root.mainloop() + + + + +class Struct: + """C-like struct""" + + # A basic Python class can pass as a C-like structure + pass + + +struct_factories = { + "pipe_blend_color": gallium.BlendColor, + "pipe_blend_state": gallium.Blend, + "pipe_clip_state": gallium.Clip, + #"pipe_constant_buffer": gallium.ConstantBuffer, + "pipe_depth_state": gallium.Depth, + "pipe_stencil_state": gallium.Stencil, + "pipe_alpha_state": gallium.Alpha, + "pipe_depth_stencil_alpha_state": gallium.DepthStencilAlpha, + "pipe_format_block": gallium.FormatBlock, + #"pipe_framebuffer_state": gallium.Framebuffer, + "pipe_poly_stipple": gallium.PolyStipple, + "pipe_rasterizer_state": gallium.Rasterizer, + "pipe_sampler_state": gallium.Sampler, + "pipe_scissor_state": gallium.Scissor, + #"pipe_shader_state": gallium.Shader, + #"pipe_vertex_buffer": gallium.VertexBuffer, + "pipe_vertex_element": gallium.VertexElement, + "pipe_viewport_state": gallium.Viewport, + #"pipe_texture": gallium.Texture, +} + + +member_array_factories = { + "pipe_rasterizer_state": {"sprite_coord_mode": gallium.ByteArray}, + "pipe_poly_stipple": {"stipple": gallium.UnsignedArray}, + "pipe_viewport_state": {"scale": gallium.FloatArray, "translate": gallium.FloatArray}, + "pipe_clip_state": {"ucp": gallium.FloatArray}, + "pipe_depth_stencil_alpha_state": {"stencil": gallium.StencilArray}, + "pipe_blend_color": {"color": gallium.FloatArray}, +} + + +class Translator(model.Visitor): + """Translate model arguments into regular Python objects""" + + def __init__(self, interpreter): + self.interpreter = interpreter + self.result = None + + def visit(self, node): + self.result = None + node.visit(self) + return self.result + + def visit_literal(self, node): + self.result = node.value + + def visit_named_constant(self, node): + # lookup the named constant in the gallium module + self.result = getattr(gallium, node.name) + + def visit_array(self, node): + array = [] + for element in node.elements: + array.append(self.visit(element)) + self.result = array + + def visit_struct(self, node): + struct_factory = struct_factories.get(node.name, Struct) + struct = struct_factory() + for member_name, member_node in node.members: + member_value = self.visit(member_node) + try: + array_factory = member_array_factories[node.name][member_name] + except KeyError: + pass + else: + assert isinstance(member_value, list) + array = array_factory(len(member_value)) + for i in range(len(member_value)): + array[i] = member_value[i] + member_value = array + #print node.name, member_name, member_value + assert isinstance(struct, Struct) or hasattr(struct, member_name) + setattr(struct, member_name, member_value) + self.result = struct + + def visit_pointer(self, node): + self.result = self.interpreter.lookup_object(node.address) + + +class Object: + + def __init__(self, interpreter, real): + self.interpreter = interpreter + self.real = real + + +class Global(Object): + + def __init__(self, interpreter, real): + self.interpreter = interpreter + self.real = real + + def pipe_winsys_create(self): + return Winsys(self.interpreter, gallium.Device()) + + def pipe_screen_create(self, winsys): + return Screen(self.interpreter, winsys.real) + + def pipe_context_create(self, screen): + context = screen.real.context_create() + return Context(self.interpreter, context) + + +class Winsys(Object): + + def __init__(self, interpreter, real): + self.interpreter = interpreter + self.real = real + + def get_name(self): + pass + + def buffer_create(self, alignment, usage, size): + return self.real.buffer_create(size, alignment, usage) + + def buffer_destroy(self, buffer): + pass + + def buffer_write(self, buffer, data, size): + buffer.write(data, size) + buffer.write(data, size) + + +class Screen(Object): + + def get_name(self): + pass + + def get_vendor(self): + pass + + def get_param(self, param): + pass + + def get_paramf(self, param): + pass + + def is_format_supported(self, format, target, tex_usage, geom_flags): + return self.real.is_format_supported(format, target, tex_usage, geom_flags) + + def texture_create(self, template): + return self.real.texture_create( + format = template.format, + width = template.width[0], + height = template.height[0], + depth = template.depth[0], + last_level = template.last_level, + target = template.target, + tex_usage = template.tex_usage, + ) + + def texture_release(self, texture): + self.interpreter.unregister_object(texture) + + def get_tex_surface(self, texture, face, level, zslice, usage): + return texture.get_surface(face, level, zslice, usage) + + def tex_surface_release(self, surface): + self.interpreter.unregister_object(surface) + + def surface_map(self, surface, flags): + return None + + def surface_unmap(self, surface): + pass + + +class Context(Object): + + def __init__(self, interpreter, real): + Object.__init__(self, interpreter, real) + self.cbufs = [] + self.zsbuf = None + + def create_blend_state(self, state): + return state + + def bind_blend_state(self, state): + self.real.set_blend(state) + + def create_sampler_state(self, state): + return state + + def bind_sampler_states(self, n, states): + for i in range(n): + self.real.set_sampler(i, states[i]) + + def create_rasterizer_state(self, state): + return state + + def bind_rasterizer_state(self, state): + self.real.set_rasterizer(state) + + def create_depth_stencil_alpha_state(self, state): + return state + + def bind_depth_stencil_alpha_state(self, state): + self.real.set_depth_stencil_alpha(state) + + def create_fs_state(self, state): + tokens = str(state.tokens) + shader = gallium.Shader(tokens) + return shader + + create_vs_state = create_fs_state + + def bind_fs_state(self, state): + self.real.set_fragment_shader(state) + + def bind_vs_state(self, state): + self.real.set_vertex_shader(state) + + def set_blend_color(self, state): + self.real.set_blend_color(state) + + def set_clip_state(self, state): + self.real.set_clip(state) + + def set_constant_buffer(self, shader, index, state): + self.real.set_constant_buffer(shader, index, state.buffer) + + def set_framebuffer_state(self, state): + _state = gallium.Framebuffer() + _state.width = state.width + _state.height = state.height + _state.num_cbufs = state.num_cbufs + for i in range(len(state.cbufs)): + _state.set_cbuf(i, state.cbufs[i]) + _state.set_zsbuf(state.zsbuf) + self.real.set_framebuffer(_state) + + self.cbufs = state.cbufs + self.zsbuf = state.zsbuf + + def set_polygon_stipple(self, state): + self.real.set_polygon_stipple(state) + + def set_scissor_state(self, state): + self.real.set_scissor(state) + + def set_viewport_state(self, state): + self.real.set_viewport(state) + + def set_sampler_textures(self, n, textures): + for i in range(n): + self.real.set_sampler_textures(textures[i]) + + def set_vertex_buffers(self, n, vbufs): + for i in range(n): + vbuf = vbufs[i] + self.real.set_vertex_buffer( + i, + pitch = vbuf.pitch, + max_index = vbuf.max_index, + buffer_offset = vbuf.buffer_offset, + buffer = vbuf.buffer, + ) + + def set_vertex_elements(self, n, elements): + for i in range(n): + self.real.set_vertex_element(i, elements[i]) + self.real.set_vertex_elements(n) + + def set_edgeflags(self, bitfield): + # FIXME + pass + + def draw_arrays(self, mode, start, count): + self.real.draw_arrays(mode, start, count) + self._update() + + def flush(self, flags, fence): + self.real.flush(flags) + + def clear(self, surface, value): + self.real.surface_clear(surface, value) + + def _update(self): + self.real.flush() + + if self.cbufs and self.cbufs[0]: + show_image(self.cbufs[0]) + + +class Interpreter: + + def __init__(self): + self.objects = {} + self.result = None + self.globl = Global(self, None) + + def register_object(self, address, object): + self.objects[address] = object + + def unregister_object(self, object): + # FIXME: + pass + + def lookup_object(self, address): + return self.objects[address] + + def interpret(self, trace): + for call in trace.calls: + self.interpret_call(call) + + def interpret_call(self, call): + sys.stderr.write("%s\n" % call) + + args = [self.interpret_arg(arg) for name, arg in call.args] + + if call.klass: + obj = args[0] + args = args[1:] + else: + obj = self.globl + + method = getattr(obj, call.method) + ret = method(*args) + + if call.ret and isinstance(call.ret, model.Pointer): + self.register_object(call.ret.address, ret) + + def interpret_arg(self, node): + translator = Translator(self) + return translator.visit(node) + + +def main(): + for arg in sys.argv[1:]: + parser = TraceParser(open(arg, 'rt')) + trace = parser.parse() + interpreter = Interpreter() + interpreter.interpret(trace) + + +if __name__ == '__main__': + main() diff --git a/src/gallium/state_trackers/python/retrace/model.py b/src/gallium/state_trackers/python/retrace/model.py new file mode 100755 index 0000000000..c17b5db9f8 --- /dev/null +++ b/src/gallium/state_trackers/python/retrace/model.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python +############################################################################# +# +# Copyright 2008 Tungsten Graphics, Inc. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +############################################################################# + + +'''Trace data model.''' + + +class Node: + + def visit(self, visitor): + raise NotImplementedError + + +class Literal(Node): + + def __init__(self, value): + self.value = value + + def visit(self, visitor): + visitor.visit_literal(self) + + def __str__(self): + if isinstance(self.value, str) and len(self.value) > 32: + return '...' + else: + return repr(self.value) + + +class NamedConstant(Node): + + def __init__(self, name): + self.name = name + + def visit(self, visitor): + visitor.visit_named_constant(self) + + def __str__(self): + return self.name + + +class Array(Node): + + def __init__(self, elements): + self.elements = elements + + def visit(self, visitor): + visitor.visit_array(self) + + def __str__(self): + return '{' + ', '.join([str(value) for value in self.elements]) + '}' + + +class Struct(Node): + + def __init__(self, name, members): + self.name = name + self.members = members + + def visit(self, visitor): + visitor.visit_struct(self) + + def __str__(self): + return '{' + ', '.join([name + ' = ' + str(value) for name, value in self.members]) + '}' + + +class Pointer(Node): + + def __init__(self, address): + self.address = address + + def visit(self, visitor): + visitor.visit_pointer(self) + + def __str__(self): + return hex(self.address) + + +class Call: + + def __init__(self, klass, method, args, ret): + self.klass = klass + self.method = method + self.args = args + self.ret = ret + + def visit(self, visitor): + visitor.visit_call(self) + + def __str__(self): + s = self.method + if self.klass: + s = self.klass + '::' + s + s += '(' + ', '.join([name + ' = ' + str(value) for name, value in self.args]) + ')' + if self.ret is not None: + s += ' = ' + str(self.ret) + return s + + +class Trace: + + def __init__(self, calls): + self.calls = calls + + def visit(self, visitor): + visitor.visit_trace(self) + + def __str__(self): + return '\n'.join([str(call) for call in self.calls]) + + +class Visitor: + + def visit_literal(self, node): + raise NotImplementedError + + def visit_named_constant(self, node): + raise NotImplementedError + + def visit_array(self, node): + raise NotImplementedError + + def visit_struct(self, node): + raise NotImplementedError + + def visit_pointer(self, node): + raise NotImplementedError + + def visit_call(self, node): + raise NotImplementedError + + def visit_trace(self, node): + raise NotImplementedError + + diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/src/gallium/state_trackers/python/retrace/parser.py new file mode 100755 index 0000000000..571d8f6eae --- /dev/null +++ b/src/gallium/state_trackers/python/retrace/parser.py @@ -0,0 +1,332 @@ +#!/usr/bin/env python +############################################################################# +# +# Copyright 2008 Tungsten Graphics, Inc. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +############################################################################# + + +import sys +import xml.parsers.expat +import binascii + +from model import * + + +ELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF = range(4) + + +class XmlToken: + + def __init__(self, type, name_or_data, attrs = None, line = None, column = None): + assert type in (ELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF) + self.type = type + self.name_or_data = name_or_data + self.attrs = attrs + self.line = line + self.column = column + + def __str__(self): + if self.type == ELEMENT_START: + return '<' + self.name_or_data + ' ...>' + if self.type == ELEMENT_END: + return '' + if self.type == CHARACTER_DATA: + return self.name_or_data + if self.type == EOF: + return 'end of file' + assert 0 + + +class XmlTokenizer: + """Expat based XML tokenizer.""" + + def __init__(self, fp, skip_ws = True): + self.fp = fp + self.tokens = [] + self.index = 0 + self.final = False + self.skip_ws = skip_ws + + self.character_pos = 0, 0 + self.character_data = '' + + self.parser = xml.parsers.expat.ParserCreate() + self.parser.StartElementHandler = self.handle_element_start + self.parser.EndElementHandler = self.handle_element_end + self.parser.CharacterDataHandler = self.handle_character_data + + def handle_element_start(self, name, attributes): + self.finish_character_data() + line, column = self.pos() + token = XmlToken(ELEMENT_START, name, attributes, line, column) + self.tokens.append(token) + + def handle_element_end(self, name): + self.finish_character_data() + line, column = self.pos() + token = XmlToken(ELEMENT_END, name, None, line, column) + self.tokens.append(token) + + def handle_character_data(self, data): + if not self.character_data: + self.character_pos = self.pos() + self.character_data += data + + def finish_character_data(self): + if self.character_data: + if not self.skip_ws or not self.character_data.isspace(): + line, column = self.character_pos + token = XmlToken(CHARACTER_DATA, self.character_data, None, line, column) + self.tokens.append(token) + self.character_data = '' + + def next(self): + size = 16*1024 + while self.index >= len(self.tokens) and not self.final: + self.tokens = [] + self.index = 0 + data = self.fp.read(size) + self.final = len(data) < size + try: + self.parser.Parse(data, self.final) + except xml.parsers.expat.ExpatError, e: + #if e.code == xml.parsers.expat.errors.XML_ERROR_NO_ELEMENTS: + if e.code == 3: + pass + else: + raise e + if self.index >= len(self.tokens): + line, column = self.pos() + token = XmlToken(EOF, None, None, line, column) + else: + token = self.tokens[self.index] + self.index += 1 + return token + + def pos(self): + return self.parser.CurrentLineNumber, self.parser.CurrentColumnNumber + + +class TokenMismatch(Exception): + + def __init__(self, expected, found): + self.expected = expected + self.found = found + + def __str__(self): + return '%u:%u: %s expected, %s found' % (self.found.line, self.found.column, str(self.expected), str(self.found)) + + + +class XmlParser: + """Base XML document parser.""" + + def __init__(self, fp): + self.tokenizer = XmlTokenizer(fp) + self.consume() + + def consume(self): + self.token = self.tokenizer.next() + + def match_element_start(self, name): + return self.token.type == ELEMENT_START and self.token.name_or_data == name + + def match_element_end(self, name): + return self.token.type == ELEMENT_END and self.token.name_or_data == name + + def element_start(self, name): + while self.token.type == CHARACTER_DATA: + self.consume() + if self.token.type != ELEMENT_START: + raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token) + if self.token.name_or_data != name: + raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token) + attrs = self.token.attrs + self.consume() + return attrs + + def element_end(self, name): + while self.token.type == CHARACTER_DATA: + self.consume() + if self.token.type != ELEMENT_END: + raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token) + if self.token.name_or_data != name: + raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token) + self.consume() + + def character_data(self, strip = True): + data = '' + while self.token.type == CHARACTER_DATA: + data += self.token.name_or_data + self.consume() + if strip: + data = data.strip() + return data + + +class TraceParser(XmlParser): + + def parse(self): + self.element_start('trace') + calls = [] + while self.token.type not in (ELEMENT_END, EOF): + calls.append(self.parse_call()) + if self.token.type != EOF: + self.element_end('trace') + return Trace(calls) + + def parse_call(self): + attrs = self.element_start('call') + klass = attrs['class'] + method = attrs['method'] + args = [] + ret = None + while self.token.type == ELEMENT_START: + if self.token.name_or_data == 'arg': + arg = self.parse_arg() + args.append(arg) + elif self.token.name_or_data == 'ret': + ret = self.parse_ret() + elif self.token.name_or_data == 'call': + # ignore nested function calls + self.parse_call() + else: + raise TokenMismatch(" or ", self.token) + self.element_end('call') + + return Call(klass, method, args, ret) + + def parse_arg(self): + attrs = self.element_start('arg') + name = attrs['name'] + value = self.parse_value() + self.element_end('arg') + + return name, value + + def parse_ret(self): + attrs = self.element_start('ret') + value = self.parse_value() + self.element_end('ret') + + return value + + def parse_value(self): + expected_tokens = ('null', 'bool', 'int', 'uint', 'float', 'string', 'enum', 'array', 'struct', 'ptr', 'bytes') + if self.token.type == ELEMENT_START: + if self.token.name_or_data in expected_tokens: + method = getattr(self, 'parse_' + self.token.name_or_data) + return method() + raise TokenMismatch(" or " .join(expected_tokens), self.token) + + def parse_null(self): + self.element_start('null') + self.element_end('null') + return Literal(None) + + def parse_bool(self): + self.element_start('bool') + value = int(self.character_data()) + self.element_end('bool') + return Literal(value) + + def parse_int(self): + self.element_start('int') + value = int(self.character_data()) + self.element_end('int') + return Literal(value) + + def parse_uint(self): + self.element_start('uint') + value = int(self.character_data()) + self.element_end('uint') + return Literal(value) + + def parse_float(self): + self.element_start('float') + value = float(self.character_data()) + self.element_end('float') + return Literal(value) + + def parse_enum(self): + self.element_start('enum') + name = self.character_data() + self.element_end('enum') + return NamedConstant(name) + + def parse_string(self): + self.element_start('string') + value = self.character_data() + self.element_end('string') + return Literal(value) + + def parse_bytes(self): + self.element_start('bytes') + value = binascii.a2b_hex(self.character_data()) + self.element_end('bytes') + return Literal(value) + + def parse_array(self): + self.element_start('array') + elems = [] + while self.token.type != ELEMENT_END: + elems.append(self.parse_elem()) + self.element_end('array') + return Array(elems) + + def parse_elem(self): + self.element_start('elem') + value = self.parse_value() + self.element_end('elem') + return value + + def parse_struct(self): + attrs = self.element_start('struct') + name = attrs['name'] + members = [] + while self.token.type != ELEMENT_END: + members.append(self.parse_member()) + self.element_end('struct') + return Struct(name, members) + + def parse_member(self): + attrs = self.element_start('member') + name = attrs['name'] + value = self.parse_value() + self.element_end('member') + + return name, value + + def parse_ptr(self): + self.element_start('ptr') + address = self.character_data() + self.element_end('ptr') + + address = int(address, 16) + + return Pointer(address) + + +def main(): + for arg in sys.argv[1:]: + parser = TraceParser(open(arg, 'rt')) + trace = parser.parse() + print trace + + +if __name__ == '__main__': + main() -- cgit v1.2.3 From 31bb6c0d17eb3265c9596bd25d5e6fabfefe4d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 11:00:40 +0100 Subject: python: Update status. --- src/gallium/state_trackers/python/README | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README index 8ab88ab2f8..8f45fb6d1b 100644 --- a/src/gallium/state_trackers/python/README +++ b/src/gallium/state_trackers/python/README @@ -24,9 +24,10 @@ and then try running which should show a triangle. -This is still in experimental phase, and there many limitations to what you can -do with from Python. - +This is still work in progress: +- errors are not handled properly and almost always result in crash +- state atoms with array members are awkward to set +- there no efficient way to view images -- Jose Fonseca -- cgit v1.2.3 From 19aee90179135387c3236c38b207cc47176226ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 11:00:49 +0100 Subject: trace: Update status. --- src/gallium/drivers/trace/README | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index 81da610bd5..4b763f2488 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -12,7 +12,7 @@ To use do ensure the right libGL.so is being picked by doing - ldd `which glxingo` + ldd `which glxinfo` and then try running @@ -31,7 +31,9 @@ further transform it by doing echo '' >> gallium.??.trace -This is still work in progress. +This is still work in progress, namely: +- surface writes are not traced +- no way to know the start/end of a frame -- Jose Fonseca -- cgit v1.2.3 From df3d694851fd99b6ea88c339b5153944824d3d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 11:15:13 +0100 Subject: python/retrace: Commit unsaved changes to the doc. --- src/gallium/state_trackers/python/retrace/README | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/retrace/README b/src/gallium/state_trackers/python/retrace/README index c0ad8ae6c1..822cd11404 100644 --- a/src/gallium/state_trackers/python/retrace/README +++ b/src/gallium/state_trackers/python/retrace/README @@ -1,4 +1,5 @@ -This is +This is an application written in python to replay the traces captured by the + trace pipe driver. To use it follow the instructions in src/gallium/drivers/trace/README and @@ -7,8 +8,6 @@ src/gallium/state_trackers/python/README, and then do python src/gallium/state_trackers/python/samples/retrace/interpreter.py filename.trace - - This is still work in progress: - not everything is captured/replayed - surface/textures contents -- cgit v1.2.3 From daa481a9c0825018d2320dcd8d9e2d7ddcfd46a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 11:39:41 +0100 Subject: gallium: New PIPE_FLUSH_FRAME flag to signal the end of a frame. --- src/gallium/include/pipe/p_defines.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index bdc6d4ef46..cda10a2f06 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -211,6 +211,7 @@ enum pipe_texture_target { #define PIPE_FLUSH_RENDER_CACHE 0x1 #define PIPE_FLUSH_TEXTURE_CACHE 0x2 #define PIPE_FLUSH_SWAPBUFFERS 0x4 +#define PIPE_FLUSH_FRAME 0x8 /**< Mark the end of a frame */ /** -- cgit v1.2.3 From 196167e9d5c84f9f6dfe6f15b3e2f2c3ec6825dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 12:50:52 +0100 Subject: trace: Make stream a global variable. This not only simplifies the code, but allows to use atexit() to ensure the log is closed when applications don't exit cleanly. --- src/gallium/drivers/trace/README | 11 +- src/gallium/drivers/trace/tr_context.c | 497 +++++++++++++++------------------ src/gallium/drivers/trace/tr_context.h | 5 - src/gallium/drivers/trace/tr_dump.c | 337 +++++++++++----------- src/gallium/drivers/trace/tr_dump.h | 120 ++++---- src/gallium/drivers/trace/tr_screen.c | 196 ++++++------- src/gallium/drivers/trace/tr_screen.h | 5 - src/gallium/drivers/trace/tr_state.c | 497 ++++++++++++++++----------------- src/gallium/drivers/trace/tr_state.h | 59 ++-- src/gallium/drivers/trace/tr_stream.h | 5 +- src/gallium/drivers/trace/tr_winsys.c | 185 ++++++------ src/gallium/drivers/trace/tr_winsys.h | 6 +- 12 files changed, 906 insertions(+), 1017 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index 4b763f2488..5752448b93 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -20,16 +20,7 @@ and then try running which should create a gallium.*.trace file, which is an XML file. You can view copying trace.xsl and trace.css to the same directory, and opening with a -XSLT capable browser like Firefox or Internet Explorer. It often happens that -the trace file was not properly terminated, and a - - - -closing tag is missing from the file end. Add it before try to open or -further transform it by doing - - echo '' >> gallium.??.trace - +XSLT capable browser like Firefox or Internet Explorer. This is still work in progress, namely: - surface writes are not traced diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index e43fc01c55..868b4f010d 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -26,12 +26,10 @@ **************************************************************************/ #include "pipe/p_util.h" +#include "pipe/p_screen.h" -#include "tr_stream.h" #include "tr_dump.h" #include "tr_state.h" -#include "tr_winsys.h" -#include "tr_screen.h" #include "tr_context.h" @@ -40,18 +38,17 @@ trace_context_set_edgeflags(struct pipe_context *_pipe, const unsigned *bitfield) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "set_edgeflags"); + trace_dump_call_begin("pipe_context", "set_edgeflags"); - trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(ptr, pipe); /* FIXME: we don't know how big this array is */ - trace_dump_arg(stream, ptr, bitfield); + trace_dump_arg(ptr, bitfield); pipe->set_edgeflags(pipe, bitfield);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -60,22 +57,21 @@ trace_context_draw_arrays(struct pipe_context *_pipe, unsigned mode, unsigned start, unsigned count) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; boolean result; - trace_dump_call_begin(stream, "pipe_context", "draw_arrays"); + trace_dump_call_begin("pipe_context", "draw_arrays"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, uint, mode); - trace_dump_arg(stream, uint, start); - trace_dump_arg(stream, uint, count); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, mode); + trace_dump_arg(uint, start); + trace_dump_arg(uint, count); result = pipe->draw_arrays(pipe, mode, start, count);; - trace_dump_ret(stream, bool, result); + trace_dump_ret(bool, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -88,24 +84,23 @@ trace_context_draw_elements(struct pipe_context *_pipe, unsigned mode, unsigned start, unsigned count) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; boolean result; - trace_dump_call_begin(stream, "pipe_context", "draw_elements"); + trace_dump_call_begin("pipe_context", "draw_elements"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, indexBuffer); - trace_dump_arg(stream, uint, indexSize); - trace_dump_arg(stream, uint, mode); - trace_dump_arg(stream, uint, start); - trace_dump_arg(stream, uint, count); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, indexBuffer); + trace_dump_arg(uint, indexSize); + trace_dump_arg(uint, mode); + trace_dump_arg(uint, start); + trace_dump_arg(uint, count); result = pipe->draw_elements(pipe, indexBuffer, indexSize, mode, start, count);; - trace_dump_ret(stream, bool, result); + trace_dump_ret(bool, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -122,29 +117,28 @@ trace_context_draw_range_elements(struct pipe_context *_pipe, unsigned count) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; boolean result; - trace_dump_call_begin(stream, "pipe_context", "draw_range_elements"); + trace_dump_call_begin("pipe_context", "draw_range_elements"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, indexBuffer); - trace_dump_arg(stream, uint, indexSize); - trace_dump_arg(stream, uint, minIndex); - trace_dump_arg(stream, uint, maxIndex); - trace_dump_arg(stream, uint, mode); - trace_dump_arg(stream, uint, start); - trace_dump_arg(stream, uint, count); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, indexBuffer); + trace_dump_arg(uint, indexSize); + trace_dump_arg(uint, minIndex); + trace_dump_arg(uint, maxIndex); + trace_dump_arg(uint, mode); + trace_dump_arg(uint, start); + trace_dump_arg(uint, count); result = pipe->draw_range_elements(pipe, indexBuffer, indexSize, minIndex, maxIndex, mode, start, count); - trace_dump_ret(stream, bool, result); + trace_dump_ret(bool, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -155,20 +149,19 @@ trace_context_create_query(struct pipe_context *_pipe, unsigned query_type) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; struct pipe_query *result; - trace_dump_call_begin(stream, "pipe_context", "create_query"); + trace_dump_call_begin("pipe_context", "create_query"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, uint, query_type); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, query_type); result = pipe->create_query(pipe, query_type);; - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -179,17 +172,16 @@ trace_context_destroy_query(struct pipe_context *_pipe, struct pipe_query *query) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "destroy_query"); + trace_dump_call_begin("pipe_context", "destroy_query"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, query); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, query); pipe->destroy_query(pipe, query);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -198,17 +190,16 @@ trace_context_begin_query(struct pipe_context *_pipe, struct pipe_query *query) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "begin_query"); + trace_dump_call_begin("pipe_context", "begin_query"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, query); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, query); pipe->begin_query(pipe, query);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -217,17 +208,16 @@ trace_context_end_query(struct pipe_context *_pipe, struct pipe_query *query) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "end_query"); + trace_dump_call_begin("pipe_context", "end_query"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, query); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, query); pipe->end_query(pipe, query); - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -238,22 +228,21 @@ trace_context_get_query_result(struct pipe_context *_pipe, uint64 *presult) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; uint64 result; boolean _result; - trace_dump_call_begin(stream, "pipe_context", "get_query_result"); + trace_dump_call_begin("pipe_context", "get_query_result"); - trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(ptr, pipe); _result = pipe->get_query_result(pipe, query, wait, presult);; result = *presult; - trace_dump_arg(stream, uint, result); - trace_dump_ret(stream, bool, _result); + trace_dump_arg(uint, result); + trace_dump_ret(bool, _result); - trace_dump_call_end(stream); + trace_dump_call_end(); return _result; } @@ -264,20 +253,19 @@ trace_context_create_blend_state(struct pipe_context *_pipe, const struct pipe_blend_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; - trace_dump_call_begin(stream, "pipe_context", "create_blend_state"); + trace_dump_call_begin("pipe_context", "create_blend_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, blend_state, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(blend_state, state); result = pipe->create_blend_state(pipe, state);; - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -288,17 +276,16 @@ trace_context_bind_blend_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "bind_blend_state"); + trace_dump_call_begin("pipe_context", "bind_blend_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); pipe->bind_blend_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -307,17 +294,16 @@ trace_context_delete_blend_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "delete_blend_state"); + trace_dump_call_begin("pipe_context", "delete_blend_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); pipe->delete_blend_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -326,20 +312,19 @@ trace_context_create_sampler_state(struct pipe_context *_pipe, const struct pipe_sampler_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; - trace_dump_call_begin(stream, "pipe_context", "create_sampler_state"); + trace_dump_call_begin("pipe_context", "create_sampler_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); result = pipe->create_sampler_state(pipe, state);; - trace_dump_ret(stream, sampler_state, result); + trace_dump_ret(sampler_state, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -350,18 +335,17 @@ trace_context_bind_sampler_states(struct pipe_context *_pipe, unsigned num_states, void **states) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "bind_sampler_states"); + trace_dump_call_begin("pipe_context", "bind_sampler_states"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, uint, num_states); - trace_dump_arg_array(stream, ptr, states, num_states); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, num_states); + trace_dump_arg_array(ptr, states, num_states); pipe->bind_sampler_states(pipe, num_states, states);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -370,17 +354,16 @@ trace_context_delete_sampler_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "delete_sampler_state"); + trace_dump_call_begin("pipe_context", "delete_sampler_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); pipe->delete_sampler_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -389,20 +372,19 @@ trace_context_create_rasterizer_state(struct pipe_context *_pipe, const struct pipe_rasterizer_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; - trace_dump_call_begin(stream, "pipe_context", "create_rasterizer_state"); + trace_dump_call_begin("pipe_context", "create_rasterizer_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, rasterizer_state, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(rasterizer_state, state); result = pipe->create_rasterizer_state(pipe, state);; - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -413,17 +395,16 @@ trace_context_bind_rasterizer_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "bind_rasterizer_state"); + trace_dump_call_begin("pipe_context", "bind_rasterizer_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); pipe->bind_rasterizer_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -432,17 +413,16 @@ trace_context_delete_rasterizer_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "delete_rasterizer_state"); + trace_dump_call_begin("pipe_context", "delete_rasterizer_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); pipe->delete_rasterizer_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -451,20 +431,19 @@ trace_context_create_depth_stencil_alpha_state(struct pipe_context *_pipe, const struct pipe_depth_stencil_alpha_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; - trace_dump_call_begin(stream, "pipe_context", "create_depth_stencil_alpha_state"); + trace_dump_call_begin("pipe_context", "create_depth_stencil_alpha_state"); result = pipe->create_depth_stencil_alpha_state(pipe, state);; - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, depth_stencil_alpha_state, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(depth_stencil_alpha_state, state); - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -475,17 +454,16 @@ trace_context_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "bind_depth_stencil_alpha_state"); + trace_dump_call_begin("pipe_context", "bind_depth_stencil_alpha_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); pipe->bind_depth_stencil_alpha_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -494,17 +472,16 @@ trace_context_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "delete_depth_stencil_alpha_state"); + trace_dump_call_begin("pipe_context", "delete_depth_stencil_alpha_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); pipe->delete_depth_stencil_alpha_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -513,20 +490,19 @@ trace_context_create_fs_state(struct pipe_context *_pipe, const struct pipe_shader_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; - trace_dump_call_begin(stream, "pipe_context", "create_fs_state"); + trace_dump_call_begin("pipe_context", "create_fs_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, shader_state, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(shader_state, state); result = pipe->create_fs_state(pipe, state);; - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -537,17 +513,16 @@ trace_context_bind_fs_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "bind_fs_state"); + trace_dump_call_begin("pipe_context", "bind_fs_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); pipe->bind_fs_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -556,17 +531,16 @@ trace_context_delete_fs_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "delete_fs_state"); + trace_dump_call_begin("pipe_context", "delete_fs_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); pipe->delete_fs_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -575,20 +549,19 @@ trace_context_create_vs_state(struct pipe_context *_pipe, const struct pipe_shader_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; void * result; - trace_dump_call_begin(stream, "pipe_context", "create_vs_state"); + trace_dump_call_begin("pipe_context", "create_vs_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, shader_state, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(shader_state, state); result = pipe->create_vs_state(pipe, state);; - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -599,17 +572,16 @@ trace_context_bind_vs_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "bind_vs_state"); + trace_dump_call_begin("pipe_context", "bind_vs_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); pipe->bind_vs_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -618,17 +590,16 @@ trace_context_delete_vs_state(struct pipe_context *_pipe, void *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "delete_vs_state"); + trace_dump_call_begin("pipe_context", "delete_vs_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, state); pipe->delete_vs_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -637,17 +608,16 @@ trace_context_set_blend_color(struct pipe_context *_pipe, const struct pipe_blend_color *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "set_blend_color"); + trace_dump_call_begin("pipe_context", "set_blend_color"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, blend_color, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(blend_color, state); pipe->set_blend_color(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -656,17 +626,16 @@ trace_context_set_clip_state(struct pipe_context *_pipe, const struct pipe_clip_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "set_clip_state"); + trace_dump_call_begin("pipe_context", "set_clip_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, clip_state, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(clip_state, state); pipe->set_clip_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -676,19 +645,18 @@ trace_context_set_constant_buffer(struct pipe_context *_pipe, const struct pipe_constant_buffer *buffer) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "set_constant_buffer"); + trace_dump_call_begin("pipe_context", "set_constant_buffer"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, uint, shader); - trace_dump_arg(stream, uint, index); - trace_dump_arg(stream, constant_buffer, buffer); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, shader); + trace_dump_arg(uint, index); + trace_dump_arg(constant_buffer, buffer); pipe->set_constant_buffer(pipe, shader, index, buffer);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -697,17 +665,16 @@ trace_context_set_framebuffer_state(struct pipe_context *_pipe, const struct pipe_framebuffer_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "set_framebuffer_state"); + trace_dump_call_begin("pipe_context", "set_framebuffer_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, framebuffer_state, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(framebuffer_state, state); pipe->set_framebuffer_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -716,17 +683,16 @@ trace_context_set_polygon_stipple(struct pipe_context *_pipe, const struct pipe_poly_stipple *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "set_polygon_stipple"); + trace_dump_call_begin("pipe_context", "set_polygon_stipple"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, poly_stipple, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(poly_stipple, state); pipe->set_polygon_stipple(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -735,17 +701,16 @@ trace_context_set_scissor_state(struct pipe_context *_pipe, const struct pipe_scissor_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "set_scissor_state"); + trace_dump_call_begin("pipe_context", "set_scissor_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, scissor_state, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(scissor_state, state); pipe->set_scissor_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -754,17 +719,16 @@ trace_context_set_viewport_state(struct pipe_context *_pipe, const struct pipe_viewport_state *state) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "set_viewport_state"); + trace_dump_call_begin("pipe_context", "set_viewport_state"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, viewport_state, state); + trace_dump_arg(ptr, pipe); + trace_dump_arg(viewport_state, state); pipe->set_viewport_state(pipe, state);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -774,18 +738,17 @@ trace_context_set_sampler_textures(struct pipe_context *_pipe, struct pipe_texture **textures) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "set_sampler_textures"); + trace_dump_call_begin("pipe_context", "set_sampler_textures"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, uint, num_textures); - trace_dump_arg_array(stream, ptr, textures, num_textures); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, num_textures); + trace_dump_arg_array(ptr, textures, num_textures); pipe->set_sampler_textures(pipe, num_textures, textures);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -795,21 +758,20 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe, const struct pipe_vertex_buffer *buffers) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "set_vertex_buffers"); + trace_dump_call_begin("pipe_context", "set_vertex_buffers"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, uint, num_buffers); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, num_buffers); - trace_dump_arg_begin(stream, "buffers"); - trace_dump_struct_array(stream, vertex_buffer, buffers, num_buffers); - trace_dump_arg_end(stream); + trace_dump_arg_begin("buffers"); + trace_dump_struct_array(vertex_buffer, buffers, num_buffers); + trace_dump_arg_end(); pipe->set_vertex_buffers(pipe, num_buffers, buffers);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -819,21 +781,20 @@ trace_context_set_vertex_elements(struct pipe_context *_pipe, const struct pipe_vertex_element *elements) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "set_vertex_elements"); + trace_dump_call_begin("pipe_context", "set_vertex_elements"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, uint, num_elements); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, num_elements); - trace_dump_arg_begin(stream, "elements"); - trace_dump_struct_array(stream, vertex_element, elements, num_elements); - trace_dump_arg_end(stream); + trace_dump_arg_begin("elements"); + trace_dump_struct_array(vertex_element, elements, num_elements); + trace_dump_arg_end(); pipe->set_vertex_elements(pipe, num_elements, elements);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -847,27 +808,26 @@ trace_context_surface_copy(struct pipe_context *_pipe, unsigned width, unsigned height) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "surface_copy"); + trace_dump_call_begin("pipe_context", "surface_copy"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, bool, do_flip); - trace_dump_arg(stream, ptr, dest); - trace_dump_arg(stream, uint, destx); - trace_dump_arg(stream, uint, desty); - trace_dump_arg(stream, ptr, src); - trace_dump_arg(stream, uint, srcx); - trace_dump_arg(stream, uint, srcy); - trace_dump_arg(stream, uint, width); - trace_dump_arg(stream, uint, height); + trace_dump_arg(ptr, pipe); + trace_dump_arg(bool, do_flip); + trace_dump_arg(ptr, dest); + trace_dump_arg(uint, destx); + trace_dump_arg(uint, desty); + trace_dump_arg(ptr, src); + trace_dump_arg(uint, srcx); + trace_dump_arg(uint, srcy); + trace_dump_arg(uint, width); + trace_dump_arg(uint, height); pipe->surface_copy(pipe, do_flip, dest, destx, desty, src, srcx, srcy, width, height); - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -879,21 +839,20 @@ trace_context_surface_fill(struct pipe_context *_pipe, unsigned value) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "surface_fill"); + trace_dump_call_begin("pipe_context", "surface_fill"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, dst); - trace_dump_arg(stream, uint, dstx); - trace_dump_arg(stream, uint, dsty); - trace_dump_arg(stream, uint, width); - trace_dump_arg(stream, uint, height); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, dst); + trace_dump_arg(uint, dstx); + trace_dump_arg(uint, dsty); + trace_dump_arg(uint, width); + trace_dump_arg(uint, height); pipe->surface_fill(pipe, dst, dstx, dsty, width, height, value);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -903,18 +862,17 @@ trace_context_clear(struct pipe_context *_pipe, unsigned clearValue) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "clear"); + trace_dump_call_begin("pipe_context", "clear"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, ptr, surface); - trace_dump_arg(stream, uint, clearValue); + trace_dump_arg(ptr, pipe); + trace_dump_arg(ptr, surface); + trace_dump_arg(uint, clearValue); pipe->clear(pipe, surface, clearValue);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -924,18 +882,17 @@ trace_context_flush(struct pipe_context *_pipe, struct pipe_fence_handle **fence) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "flush"); + trace_dump_call_begin("pipe_context", "flush"); - trace_dump_arg(stream, ptr, pipe); - trace_dump_arg(stream, uint, flags); - trace_dump_arg(stream, ptr, fence); + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, flags); + trace_dump_arg(ptr, fence); pipe->flush(pipe, flags, fence);; - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -943,16 +900,15 @@ static INLINE void trace_context_destroy(struct pipe_context *_pipe) { struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_stream *stream = tr_ctx->stream; struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin(stream, "pipe_context", "destroy"); + trace_dump_call_begin("pipe_context", "destroy"); - trace_dump_arg(stream, ptr, pipe); + trace_dump_arg(ptr, pipe); pipe->destroy(pipe); - trace_dump_call_end(stream); + trace_dump_call_end(); FREE(tr_ctx); } @@ -962,15 +918,14 @@ struct pipe_context * trace_context_create(struct pipe_screen *screen, struct pipe_context *pipe) { - struct trace_stream *stream; struct trace_context *tr_ctx; - if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) - return pipe; + if(!pipe) + goto error1; tr_ctx = CALLOC_STRUCT(trace_context); if(!tr_ctx) - return NULL; + goto error1; tr_ctx->base.winsys = screen->winsys; tr_ctx->base.screen = screen; @@ -1018,14 +973,16 @@ trace_context_create(struct pipe_screen *screen, tr_ctx->base.flush = trace_context_flush; tr_ctx->pipe = pipe; - tr_ctx->stream = stream = trace_screen(screen)->stream; - trace_dump_call_begin(stream, "", "pipe_context_create"); - trace_dump_arg_begin(stream, "screen"); - trace_dump_ptr(stream, pipe->screen); - trace_dump_arg_end(stream); - trace_dump_ret(stream, ptr, pipe); - trace_dump_call_end(stream); + trace_dump_call_begin("", "pipe_context_create"); + trace_dump_arg_begin("screen"); + trace_dump_ptr(pipe->screen); + trace_dump_arg_end(); + trace_dump_ret(ptr, pipe); + trace_dump_call_end(); return &tr_ctx->base; + +error1: + return pipe; } diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 1aa822ba02..679371e310 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -34,16 +34,11 @@ #include "pipe/p_context.h" -struct trace_stream; - - struct trace_context { struct pipe_context base; struct pipe_context *pipe; - - struct trace_stream *stream; }; diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 5269c4ddc8..6ebb639b7c 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -38,6 +38,11 @@ * @author Jose Fonseca */ +#include "pipe/p_config.h" + +#if defined(PIPE_OS_LINUX) +#include +#endif #include "pipe/p_compiler.h" #include "util/u_string.h" @@ -46,318 +51,328 @@ #include "tr_dump.h" +static struct trace_stream *stream = NULL; + + static INLINE void -trace_dump_write(struct trace_stream *stream, const char *s) +trace_dump_write(const char *buf, size_t size) { - trace_stream_write(stream, s, strlen(s)); + if(stream) + trace_stream_write(stream, buf, size); } static INLINE void -trace_dump_writef(struct trace_stream *stream, const char *format, ...) +trace_dump_writes(const char *s) { - char buf[1024]; + trace_dump_write(s, strlen(s)); +} + + +static INLINE void +trace_dump_writef(const char *format, ...) +{ + static char buf[1024]; + unsigned len; va_list ap; va_start(ap, format); - util_vsnprintf(buf, sizeof(buf), format, ap); + len = util_vsnprintf(buf, sizeof(buf), format, ap); va_end(ap); - trace_dump_write(stream, buf); + trace_dump_write(buf, len); } static INLINE void -trace_dump_escape(struct trace_stream *stream, const char *str) +trace_dump_escape(const char *str) { const unsigned char *p = (const unsigned char *)str; unsigned char c; while((c = *p++) != 0) { if(c == '<') - trace_dump_write(stream, "<"); + trace_dump_writes("<"); else if(c == '>') - trace_dump_write(stream, ">"); + trace_dump_writes(">"); else if(c == '&') - trace_dump_write(stream, "&"); + trace_dump_writes("&"); else if(c == '\'') - trace_dump_write(stream, "'"); + trace_dump_writes("'"); else if(c == '\"') - trace_dump_write(stream, """); + trace_dump_writes("""); else if(c >= 0x20 && c <= 0x7e) - trace_dump_writef(stream, "%c", c); + trace_dump_writef("%c", c); else - trace_dump_writef(stream, "&#%u;", c); + trace_dump_writef("&#%u;", c); } } static INLINE void -trace_dump_indent(struct trace_stream *stream, unsigned level) +trace_dump_indent(unsigned level) { unsigned i; for(i = 0; i < level; ++i) - trace_dump_write(stream, "\t"); + trace_dump_writes("\t"); } static INLINE void -trace_dump_newline(struct trace_stream *stream) +trace_dump_newline(void) { - trace_dump_write(stream, "\n"); + trace_dump_writes("\n"); } static INLINE void -trace_dump_tag(struct trace_stream *stream, - const char *name) +trace_dump_tag(const char *name) { - trace_dump_write(stream, "<"); - trace_dump_write(stream, name); - trace_dump_write(stream, "/>"); + trace_dump_writes("<"); + trace_dump_writes(name); + trace_dump_writes("/>"); } static INLINE void -trace_dump_tag_begin(struct trace_stream *stream, - const char *name) +trace_dump_tag_begin(const char *name) { - trace_dump_write(stream, "<"); - trace_dump_write(stream, name); - trace_dump_write(stream, ">"); + trace_dump_writes("<"); + trace_dump_writes(name); + trace_dump_writes(">"); } static INLINE void -trace_dump_tag_begin1(struct trace_stream *stream, - const char *name, +trace_dump_tag_begin1(const char *name, const char *attr1, const char *value1) { - trace_dump_write(stream, "<"); - trace_dump_write(stream, name); - trace_dump_write(stream, " "); - trace_dump_write(stream, attr1); - trace_dump_write(stream, "='"); - trace_dump_escape(stream, value1); - trace_dump_write(stream, "'>"); + trace_dump_writes("<"); + trace_dump_writes(name); + trace_dump_writes(" "); + trace_dump_writes(attr1); + trace_dump_writes("='"); + trace_dump_escape(value1); + trace_dump_writes("'>"); } static INLINE void -trace_dump_tag_begin2(struct trace_stream *stream, - const char *name, +trace_dump_tag_begin2(const char *name, const char *attr1, const char *value1, const char *attr2, const char *value2) { - trace_dump_write(stream, "<"); - trace_dump_write(stream, name); - trace_dump_write(stream, " "); - trace_dump_write(stream, attr1); - trace_dump_write(stream, "=\'"); - trace_dump_escape(stream, value1); - trace_dump_write(stream, "\' "); - trace_dump_write(stream, attr2); - trace_dump_write(stream, "=\'"); - trace_dump_escape(stream, value2); - trace_dump_write(stream, "\'>"); + trace_dump_writes("<"); + trace_dump_writes(name); + trace_dump_writes(" "); + trace_dump_writes(attr1); + trace_dump_writes("=\'"); + trace_dump_escape(value1); + trace_dump_writes("\' "); + trace_dump_writes(attr2); + trace_dump_writes("=\'"); + trace_dump_escape(value2); + trace_dump_writes("\'>"); } static INLINE void -trace_dump_tag_begin3(struct trace_stream *stream, - const char *name, +trace_dump_tag_begin3(const char *name, const char *attr1, const char *value1, const char *attr2, const char *value2, const char *attr3, const char *value3) { - trace_dump_write(stream, "<"); - trace_dump_write(stream, name); - trace_dump_write(stream, " "); - trace_dump_write(stream, attr1); - trace_dump_write(stream, "=\'"); - trace_dump_escape(stream, value1); - trace_dump_write(stream, "\' "); - trace_dump_write(stream, attr2); - trace_dump_write(stream, "=\'"); - trace_dump_escape(stream, value2); - trace_dump_write(stream, "\' "); - trace_dump_write(stream, attr3); - trace_dump_write(stream, "=\'"); - trace_dump_escape(stream, value3); - trace_dump_write(stream, "\'>"); + trace_dump_writes("<"); + trace_dump_writes(name); + trace_dump_writes(" "); + trace_dump_writes(attr1); + trace_dump_writes("=\'"); + trace_dump_escape(value1); + trace_dump_writes("\' "); + trace_dump_writes(attr2); + trace_dump_writes("=\'"); + trace_dump_escape(value2); + trace_dump_writes("\' "); + trace_dump_writes(attr3); + trace_dump_writes("=\'"); + trace_dump_escape(value3); + trace_dump_writes("\'>"); } static INLINE void -trace_dump_tag_end(struct trace_stream *stream, - const char *name) -{ - trace_dump_write(stream, ""); -} - - -void trace_dump_trace_begin(struct trace_stream *stream, - unsigned version) -{ - trace_dump_write(stream, "\n"); - trace_dump_write(stream, "\n"); - trace_dump_writef(stream, "\n", version); -} - - -void trace_dump_trace_end(struct trace_stream *stream) -{ - trace_dump_write(stream, "\n"); +trace_dump_tag_end(const char *name) +{ + trace_dump_writes(""); +} + +boolean trace_dump_trace_begin() +{ + if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) + return FALSE; + + stream = trace_stream_create("gallium", "trace"); + if(!stream) + return FALSE; + + trace_dump_writes("\n"); + trace_dump_writes("\n"); + trace_dump_writes("\n"); + +#if defined(PIPE_OS_LINUX) + /* Linux applications rarely cleanup GL / Gallium resources so catch + * application exit here */ + atexit(trace_dump_trace_end); +#endif + + return TRUE; +} + +void trace_dump_trace_end(void) +{ + if(stream) { + trace_dump_writes("\n"); + trace_stream_close(stream); + stream = NULL; + } } -void trace_dump_call_begin(struct trace_stream *stream, - const char *klass, const char *method) +void trace_dump_call_begin(const char *klass, const char *method) { - trace_dump_indent(stream, 1); - trace_dump_tag_begin2(stream, "call", "class", klass, "method", method); - trace_dump_newline(stream); + trace_dump_indent(1); + trace_dump_tag_begin2("call", "class", klass, "method", method); + trace_dump_newline(); } -void trace_dump_call_end(struct trace_stream *stream) +void trace_dump_call_end(void) { - trace_dump_indent(stream, 1); - trace_dump_tag_end(stream, "call"); - trace_dump_newline(stream); + trace_dump_indent(1); + trace_dump_tag_end("call"); + trace_dump_newline(); } -void trace_dump_arg_begin(struct trace_stream *stream, - const char *name) +void trace_dump_arg_begin(const char *name) { - trace_dump_indent(stream, 2); - trace_dump_tag_begin1(stream, "arg", "name", name); + trace_dump_indent(2); + trace_dump_tag_begin1("arg", "name", name); } -void trace_dump_arg_end(struct trace_stream *stream) +void trace_dump_arg_end(void) { - trace_dump_tag_end(stream, "arg"); - trace_dump_newline(stream); + trace_dump_tag_end("arg"); + trace_dump_newline(); } -void trace_dump_ret_begin(struct trace_stream *stream) +void trace_dump_ret_begin(void) { - trace_dump_indent(stream, 2); - trace_dump_tag_begin(stream, "ret"); + trace_dump_indent(2); + trace_dump_tag_begin("ret"); } -void trace_dump_ret_end(struct trace_stream *stream) +void trace_dump_ret_end(void) { - trace_dump_tag_end(stream, "ret"); - trace_dump_newline(stream); + trace_dump_tag_end("ret"); + trace_dump_newline(); } -void trace_dump_bool(struct trace_stream *stream, - int value) +void trace_dump_bool(int value) { - trace_dump_writef(stream, "%c", value ? '1' : '0'); + trace_dump_writef("%c", value ? '1' : '0'); } -void trace_dump_int(struct trace_stream *stream, - long int value) +void trace_dump_int(long int value) { - trace_dump_writef(stream, "%li", value); + trace_dump_writef("%li", value); } -void trace_dump_uint(struct trace_stream *stream, - long unsigned value) +void trace_dump_uint(long unsigned value) { - trace_dump_writef(stream, "%lu", value); + trace_dump_writef("%lu", value); } -void trace_dump_float(struct trace_stream *stream, - double value) +void trace_dump_float(double value) { - trace_dump_writef(stream, "%g", value); + trace_dump_writef("%g", value); } -void trace_dump_bytes(struct trace_stream *stream, - const void *data, +void trace_dump_bytes(const void *data, long unsigned size) { static const char hex_table[16] = "0123456789ABCDEF"; const uint8_t *p = data; long unsigned i; - trace_dump_write(stream, ""); + trace_dump_writes(""); for(i = 0; i < size; ++i) { uint8_t byte = *p++; char hex[2]; hex[0] = hex_table[byte >> 4]; hex[1] = hex_table[byte & 0xf]; - trace_stream_write(stream, hex, 2); + trace_dump_write(hex, 2); } - trace_dump_write(stream, ""); + trace_dump_writes(""); } -void trace_dump_string(struct trace_stream *stream, - const char *str) +void trace_dump_string(const char *str) { - trace_dump_write(stream, ""); - trace_dump_escape(stream, str); - trace_dump_write(stream, ""); + trace_dump_writes(""); + trace_dump_escape(str); + trace_dump_writes(""); } -void trace_dump_enum(struct trace_stream *stream, - const char *value) +void trace_dump_enum(const char *value) { - trace_dump_write(stream, ""); - trace_dump_escape(stream, value); - trace_dump_write(stream, ""); + trace_dump_writes(""); + trace_dump_escape(value); + trace_dump_writes(""); } -void trace_dump_array_begin(struct trace_stream *stream) +void trace_dump_array_begin(void) { - trace_dump_write(stream, ""); + trace_dump_writes(""); } -void trace_dump_array_end(struct trace_stream *stream) +void trace_dump_array_end(void) { - trace_dump_write(stream, ""); + trace_dump_writes(""); } -void trace_dump_elem_begin(struct trace_stream *stream) +void trace_dump_elem_begin(void) { - trace_dump_write(stream, ""); + trace_dump_writes(""); } -void trace_dump_elem_end(struct trace_stream *stream) +void trace_dump_elem_end(void) { - trace_dump_write(stream, ""); + trace_dump_writes(""); } -void trace_dump_struct_begin(struct trace_stream *stream, - const char *name) +void trace_dump_struct_begin(const char *name) { - trace_dump_writef(stream, "", name); + trace_dump_writef("", name); } -void trace_dump_struct_end(struct trace_stream *stream) +void trace_dump_struct_end(void) { - trace_dump_write(stream, ""); + trace_dump_writes(""); } -void trace_dump_member_begin(struct trace_stream *stream, - const char *name) +void trace_dump_member_begin(const char *name) { - trace_dump_writef(stream, "", name); + trace_dump_writef("", name); } -void trace_dump_member_end(struct trace_stream *stream) +void trace_dump_member_end(void) { - trace_dump_write(stream, ""); + trace_dump_writes(""); } -void trace_dump_null(struct trace_stream *stream) +void trace_dump_null(void) { - trace_dump_write(stream, ""); + trace_dump_writes(""); } -void trace_dump_ptr(struct trace_stream *stream, - const void *value) +void trace_dump_ptr(const void *value) { if(value) - trace_dump_writef(stream, "%p", value); + trace_dump_writef("%p", value); else - trace_dump_null(stream); + trace_dump_null(); } diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index b2367c3288..0beb1023b1 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -4,7 +4,7 @@ * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation streams (the + * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to @@ -34,100 +34,98 @@ #define TR_DUMP_H +#include "pipe/p_compiler.h" #include "pipe/p_util.h" -struct trace_stream; - - -void trace_dump_trace_begin(struct trace_stream *stream, unsigned version); -void trace_dump_trace_end(struct trace_stream *stream); -void trace_dump_call_begin(struct trace_stream *stream, const char *klass, const char *method); -void trace_dump_call_end(struct trace_stream *stream); -void trace_dump_arg_begin(struct trace_stream *stream, const char *name); -void trace_dump_arg_end(struct trace_stream *stream); -void trace_dump_ret_begin(struct trace_stream *stream); -void trace_dump_ret_end(struct trace_stream *stream); -void trace_dump_bool(struct trace_stream *stream, int value); -void trace_dump_int(struct trace_stream *stream, long int value); -void trace_dump_uint(struct trace_stream *stream, long unsigned value); -void trace_dump_float(struct trace_stream *stream, double value); -void trace_dump_bytes(struct trace_stream *stream, const void *data, long unsigned size); -void trace_dump_string(struct trace_stream *stream, const char *str); -void trace_dump_enum(struct trace_stream *stream, const char *value); -void trace_dump_array_begin(struct trace_stream *stream); -void trace_dump_array_end(struct trace_stream *stream); -void trace_dump_elem_begin(struct trace_stream *stream); -void trace_dump_elem_end(struct trace_stream *stream); -void trace_dump_struct_begin(struct trace_stream *stream, const char *name); -void trace_dump_struct_end(struct trace_stream *stream); -void trace_dump_member_begin(struct trace_stream *stream, const char *name); -void trace_dump_member_end(struct trace_stream *stream); -void trace_dump_null(struct trace_stream *stream); -void trace_dump_ptr(struct trace_stream *stream, const void *value); +boolean trace_dump_trace_begin(void); +void trace_dump_trace_end(void); +void trace_dump_call_begin(const char *klass, const char *method); +void trace_dump_call_end(void); +void trace_dump_arg_begin(const char *name); +void trace_dump_arg_end(void); +void trace_dump_ret_begin(void); +void trace_dump_ret_end(void); +void trace_dump_bool(int value); +void trace_dump_int(long int value); +void trace_dump_uint(long unsigned value); +void trace_dump_float(double value); +void trace_dump_bytes(const void *data, long unsigned size); +void trace_dump_string(const char *str); +void trace_dump_enum(const char *value); +void trace_dump_array_begin(void); +void trace_dump_array_end(void); +void trace_dump_elem_begin(void); +void trace_dump_elem_end(void); +void trace_dump_struct_begin(const char *name); +void trace_dump_struct_end(void); +void trace_dump_member_begin(const char *name); +void trace_dump_member_end(void); +void trace_dump_null(void); +void trace_dump_ptr(const void *value); /* * Code saving macros. */ -#define trace_dump_arg(_stream, _type, _arg) \ +#define trace_dump_arg(_type, _arg) \ do { \ - trace_dump_arg_begin(_stream, #_arg); \ - trace_dump_##_type(_stream, _arg); \ - trace_dump_arg_end(_stream); \ + trace_dump_arg_begin(#_arg); \ + trace_dump_##_type(_arg); \ + trace_dump_arg_end(); \ } while(0) -#define trace_dump_ret(_stream, _type, _arg) \ +#define trace_dump_ret(_type, _arg) \ do { \ - trace_dump_ret_begin(_stream); \ - trace_dump_##_type(_stream, _arg); \ - trace_dump_ret_end(_stream); \ + trace_dump_ret_begin(); \ + trace_dump_##_type(_arg); \ + trace_dump_ret_end(); \ } while(0) -#define trace_dump_array(_stream, _type, _obj, _size) \ +#define trace_dump_array(_type, _obj, _size) \ do { \ unsigned long idx; \ - trace_dump_array_begin(_stream); \ + trace_dump_array_begin(); \ for(idx = 0; idx < (_size); ++idx) { \ - trace_dump_elem_begin(_stream); \ - trace_dump_##_type(_stream, (_obj)[idx]); \ - trace_dump_elem_end(_stream); \ + trace_dump_elem_begin(); \ + trace_dump_##_type((_obj)[idx]); \ + trace_dump_elem_end(); \ } \ - trace_dump_array_end(_stream); \ + trace_dump_array_end(); \ } while(0) -#define trace_dump_struct_array(_stream, _type, _obj, _size) \ +#define trace_dump_struct_array(_type, _obj, _size) \ do { \ unsigned long idx; \ - trace_dump_array_begin(_stream); \ + trace_dump_array_begin(); \ for(idx = 0; idx < (_size); ++idx) { \ - trace_dump_elem_begin(_stream); \ - trace_dump_##_type(_stream, &(_obj)[idx]); \ - trace_dump_elem_end(_stream); \ + trace_dump_elem_begin(); \ + trace_dump_##_type(&(_obj)[idx]); \ + trace_dump_elem_end(); \ } \ - trace_dump_array_end(_stream); \ + trace_dump_array_end(); \ } while(0) -#define trace_dump_member(_stream, _type, _obj, _member) \ +#define trace_dump_member(_type, _obj, _member) \ do { \ - trace_dump_member_begin(_stream, #_member); \ - trace_dump_##_type(_stream, (_obj)->_member); \ - trace_dump_member_end(_stream); \ + trace_dump_member_begin(#_member); \ + trace_dump_##_type((_obj)->_member); \ + trace_dump_member_end(); \ } while(0) -#define trace_dump_arg_array(_stream, _type, _arg, _size) \ +#define trace_dump_arg_array(_type, _arg, _size) \ do { \ - trace_dump_arg_begin(_stream, #_arg); \ - trace_dump_array(_stream, _type, _arg, _size); \ - trace_dump_arg_end(_stream); \ + trace_dump_arg_begin(#_arg); \ + trace_dump_array(_type, _arg, _size); \ + trace_dump_arg_end(); \ } while(0) -#define trace_dump_member_array(_stream, _type, _obj, _member) \ +#define trace_dump_member_array(_type, _obj, _member) \ do { \ - trace_dump_member_begin(_stream, #_member); \ - trace_dump_array(_stream, _type, (_obj)->_member, sizeof((_obj)->_member)/sizeof((_obj)->_member[0])); \ - trace_dump_member_end(_stream); \ + trace_dump_member_begin(#_member); \ + trace_dump_array(_type, (_obj)->_member, sizeof((_obj)->_member)/sizeof((_obj)->_member[0])); \ + trace_dump_member_end(); \ } while(0) diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 0e253123ae..68165a4553 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -27,7 +27,6 @@ #include "pipe/p_util.h" -#include "tr_stream.h" #include "tr_dump.h" #include "tr_state.h" #include "tr_winsys.h" @@ -38,19 +37,18 @@ static const char * trace_screen_get_name(struct pipe_screen *_screen) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; const char *result; - trace_dump_call_begin(stream, "pipe_screen", "get_name"); + trace_dump_call_begin("pipe_screen", "get_name"); - trace_dump_arg(stream, ptr, screen); + trace_dump_arg(ptr, screen); result = screen->get_name(screen); - trace_dump_ret(stream, string, result); + trace_dump_ret(string, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -60,19 +58,18 @@ static const char * trace_screen_get_vendor(struct pipe_screen *_screen) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; const char *result; - trace_dump_call_begin(stream, "pipe_screen", "get_vendor"); + trace_dump_call_begin("pipe_screen", "get_vendor"); - trace_dump_arg(stream, ptr, screen); + trace_dump_arg(ptr, screen); result = screen->get_vendor(screen); - trace_dump_ret(stream, string, result); + trace_dump_ret(string, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -83,20 +80,19 @@ trace_screen_get_param(struct pipe_screen *_screen, int param) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; int result; - trace_dump_call_begin(stream, "pipe_screen", "get_param"); + trace_dump_call_begin("pipe_screen", "get_param"); - trace_dump_arg(stream, ptr, screen); - trace_dump_arg(stream, int, param); + trace_dump_arg(ptr, screen); + trace_dump_arg(int, param); result = screen->get_param(screen, param); - trace_dump_ret(stream, int, result); + trace_dump_ret(int, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -107,20 +103,19 @@ trace_screen_get_paramf(struct pipe_screen *_screen, int param) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; float result; - trace_dump_call_begin(stream, "pipe_screen", "get_paramf"); + trace_dump_call_begin("pipe_screen", "get_paramf"); - trace_dump_arg(stream, ptr, screen); - trace_dump_arg(stream, int, param); + trace_dump_arg(ptr, screen); + trace_dump_arg(int, param); result = screen->get_paramf(screen, param); - trace_dump_ret(stream, float, result); + trace_dump_ret(float, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -134,23 +129,22 @@ trace_screen_is_format_supported(struct pipe_screen *_screen, unsigned geom_flags) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; boolean result; - trace_dump_call_begin(stream, "pipe_screen", "is_format_supported"); + trace_dump_call_begin("pipe_screen", "is_format_supported"); - trace_dump_arg(stream, ptr, screen); - trace_dump_arg(stream, format, format); - trace_dump_arg(stream, int, target); - trace_dump_arg(stream, uint, tex_usage); - trace_dump_arg(stream, uint, geom_flags); + trace_dump_arg(ptr, screen); + trace_dump_arg(format, format); + trace_dump_arg(int, target); + trace_dump_arg(uint, tex_usage); + trace_dump_arg(uint, geom_flags); result = screen->is_format_supported(screen, format, target, tex_usage, geom_flags); - trace_dump_ret(stream, bool, result); + trace_dump_ret(bool, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -161,20 +155,19 @@ trace_screen_texture_create(struct pipe_screen *_screen, const struct pipe_texture *templat) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; struct pipe_texture *result; - trace_dump_call_begin(stream, "pipe_screen", "texture_create"); + trace_dump_call_begin("pipe_screen", "texture_create"); - trace_dump_arg(stream, ptr, screen); - trace_dump_arg(stream, template, templat); + trace_dump_arg(ptr, screen); + trace_dump_arg(template, templat); result = screen->texture_create(screen, templat); - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -187,23 +180,22 @@ trace_screen_texture_blanket(struct pipe_screen *_screen, struct pipe_buffer *buffer) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; unsigned pitch = *ppitch; struct pipe_texture *result; - trace_dump_call_begin(stream, "pipe_screen", "texture_blanket"); + trace_dump_call_begin("pipe_screen", "texture_blanket"); - trace_dump_arg(stream, ptr, screen); - trace_dump_arg(stream, template, templat); - trace_dump_arg(stream, uint, pitch); - trace_dump_arg(stream, ptr, buffer); + trace_dump_arg(ptr, screen); + trace_dump_arg(template, templat); + trace_dump_arg(uint, pitch); + trace_dump_arg(ptr, buffer); result = screen->texture_blanket(screen, templat, ppitch, buffer); - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -214,18 +206,17 @@ trace_screen_texture_release(struct pipe_screen *_screen, struct pipe_texture **ptexture) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; struct pipe_texture *texture = *ptexture; - trace_dump_call_begin(stream, "pipe_screen", "texture_release"); + trace_dump_call_begin("pipe_screen", "texture_release"); - trace_dump_arg(stream, ptr, screen); - trace_dump_arg(stream, ptr, texture); + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, texture); screen->texture_release(screen, ptexture); - trace_dump_call_end(stream); + trace_dump_call_end(); } static struct pipe_surface * @@ -236,24 +227,23 @@ trace_screen_get_tex_surface(struct pipe_screen *_screen, unsigned usage) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; struct pipe_surface *result; - trace_dump_call_begin(stream, "pipe_screen", "get_tex_surface"); + trace_dump_call_begin("pipe_screen", "get_tex_surface"); - trace_dump_arg(stream, ptr, screen); - trace_dump_arg(stream, ptr, texture); - trace_dump_arg(stream, uint, face); - trace_dump_arg(stream, uint, level); - trace_dump_arg(stream, uint, zslice); - trace_dump_arg(stream, uint, usage); + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, texture); + trace_dump_arg(uint, face); + trace_dump_arg(uint, level); + trace_dump_arg(uint, zslice); + trace_dump_arg(uint, usage); result = screen->get_tex_surface(screen, texture, face, level, zslice, usage); - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -264,18 +254,17 @@ trace_screen_tex_surface_release(struct pipe_screen *_screen, struct pipe_surface **psurface) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; struct pipe_surface *surface = *psurface; - trace_dump_call_begin(stream, "pipe_screen", "tex_surface_release"); + trace_dump_call_begin("pipe_screen", "tex_surface_release"); - trace_dump_arg(stream, ptr, screen); - trace_dump_arg(stream, ptr, surface); + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, surface); screen->tex_surface_release(screen, psurface); - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -285,21 +274,20 @@ trace_screen_surface_map(struct pipe_screen *_screen, unsigned flags) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; struct pipe_surface *result; - trace_dump_call_begin(stream, "pipe_screen", "surface_map"); + trace_dump_call_begin("pipe_screen", "surface_map"); - trace_dump_arg(stream, ptr, screen); - trace_dump_arg(stream, ptr, surface); - trace_dump_arg(stream, uint, flags); + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, surface); + trace_dump_arg(uint, flags); result = screen->surface_map(screen, surface, flags); - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -310,17 +298,16 @@ trace_screen_surface_unmap(struct pipe_screen *_screen, struct pipe_surface *surface) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; - trace_dump_call_begin(stream, "pipe_screen", "surface_unmap"); + trace_dump_call_begin("pipe_screen", "surface_unmap"); - trace_dump_arg(stream, ptr, screen); - trace_dump_arg(stream, ptr, surface); + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, surface); screen->surface_unmap(screen, surface); - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -328,20 +315,17 @@ static void trace_screen_destroy(struct pipe_screen *_screen) { struct trace_screen *tr_scr = trace_screen(_screen); - struct trace_stream *stream = tr_scr->stream; struct pipe_screen *screen = tr_scr->screen; - trace_dump_call_begin(stream, "pipe_screen", "destroy"); + trace_dump_call_begin("pipe_screen", "destroy"); - trace_dump_arg(stream, ptr, screen); + trace_dump_arg(ptr, screen); screen->destroy(screen); - trace_dump_call_end(stream); + trace_dump_call_end(); - trace_dump_trace_end(stream); - - trace_stream_close(stream); + trace_dump_trace_end(); FREE(tr_scr); } @@ -350,26 +334,22 @@ trace_screen_destroy(struct pipe_screen *_screen) struct pipe_screen * trace_screen_create(struct pipe_screen *screen) { - struct trace_stream *stream; struct trace_screen *tr_scr; struct pipe_winsys *winsys; - if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) - return screen; - - tr_scr = CALLOC_STRUCT(trace_screen); - if(!tr_scr) - return NULL; + if(!screen) + goto error1; - tr_scr->stream = stream = trace_stream_create("gallium", "trace"); - if(!tr_scr->stream) - return NULL; + if(!trace_dump_trace_begin()) + goto error1; - trace_dump_trace_begin(stream, 0); + tr_scr = CALLOC_STRUCT(trace_screen); + if(!tr_scr) + goto error2; - winsys = trace_winsys_create(stream, screen->winsys); + winsys = trace_winsys_create(screen->winsys); if(!winsys) - return NULL; + goto error3; tr_scr->base.winsys = winsys; tr_scr->base.destroy = trace_screen_destroy; @@ -387,14 +367,20 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->base.surface_unmap = trace_screen_surface_unmap; tr_scr->screen = screen; - tr_scr->stream = stream = trace_winsys(winsys)->stream; - trace_dump_call_begin(stream, "", "pipe_screen_create"); - trace_dump_arg_begin(stream, "winsys"); - trace_dump_ptr(stream, screen->winsys); - trace_dump_arg_end(stream); - trace_dump_ret(stream, ptr, screen); - trace_dump_call_end(stream); + trace_dump_call_begin("", "pipe_screen_create"); + trace_dump_arg_begin("winsys"); + trace_dump_ptr(screen->winsys); + trace_dump_arg_end(); + trace_dump_ret(ptr, screen); + trace_dump_call_end(); return &tr_scr->base; + +error3: + FREE(tr_scr); +error2: + trace_dump_trace_end(); +error1: + return screen; } diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h index 40b844778f..446c4af6a6 100644 --- a/src/gallium/drivers/trace/tr_screen.h +++ b/src/gallium/drivers/trace/tr_screen.h @@ -34,16 +34,11 @@ #include "pipe/p_screen.h" -struct trace_stream; - - struct trace_screen { struct pipe_screen base; struct pipe_screen *screen; - - struct trace_stream *stream; }; diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index e074ae7abc..7b35e89e75 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -33,461 +33,442 @@ #include "tr_state.h" -void trace_dump_format(struct trace_stream *stream, - enum pipe_format format) +void trace_dump_format(enum pipe_format format) { - trace_dump_enum(stream, pf_name(format) ); + trace_dump_enum(pf_name(format) ); } -void trace_dump_block(struct trace_stream *stream, - const struct pipe_format_block *block) +void trace_dump_block(const struct pipe_format_block *block) { - trace_dump_struct_begin(stream, "pipe_format_block"); - trace_dump_member(stream, uint, block, size); - trace_dump_member(stream, uint, block, width); - trace_dump_member(stream, uint, block, height); - trace_dump_struct_end(stream); + trace_dump_struct_begin("pipe_format_block"); + trace_dump_member(uint, block, size); + trace_dump_member(uint, block, width); + trace_dump_member(uint, block, height); + trace_dump_struct_end(); } -void trace_dump_template(struct trace_stream *stream, - const struct pipe_texture *templat) +void trace_dump_template(const struct pipe_texture *templat) { assert(templat); if(!templat) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_texture"); + trace_dump_struct_begin("pipe_texture"); - trace_dump_member(stream, int, templat, target); - trace_dump_member(stream, format, templat, format); + trace_dump_member(int, templat, target); + trace_dump_member(format, templat, format); - trace_dump_member_begin(stream, "width"); - trace_dump_array(stream, uint, templat->width, 1); - trace_dump_member_end(stream); + trace_dump_member_begin("width"); + trace_dump_array(uint, templat->width, 1); + trace_dump_member_end(); - trace_dump_member_begin(stream, "height"); - trace_dump_array(stream, uint, templat->height, 1); - trace_dump_member_end(stream); + trace_dump_member_begin("height"); + trace_dump_array(uint, templat->height, 1); + trace_dump_member_end(); - trace_dump_member_begin(stream, "depth"); - trace_dump_array(stream, uint, templat->depth, 1); - trace_dump_member_end(stream); + trace_dump_member_begin("depth"); + trace_dump_array(uint, templat->depth, 1); + trace_dump_member_end(); - trace_dump_member_begin(stream, "block"); - trace_dump_block(stream, &templat->block); - trace_dump_member_end(stream); + trace_dump_member_begin("block"); + trace_dump_block(&templat->block); + trace_dump_member_end(); - trace_dump_member(stream, uint, templat, last_level); - trace_dump_member(stream, uint, templat, tex_usage); + trace_dump_member(uint, templat, last_level); + trace_dump_member(uint, templat, tex_usage); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_rasterizer_state(struct trace_stream *stream, - const struct pipe_rasterizer_state *state) +void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) { assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_rasterizer_state"); - - trace_dump_member(stream, bool, state, flatshade); - trace_dump_member(stream, bool, state, light_twoside); - trace_dump_member(stream, uint, state, front_winding); - trace_dump_member(stream, uint, state, cull_mode); - trace_dump_member(stream, uint, state, fill_cw); - trace_dump_member(stream, uint, state, fill_ccw); - trace_dump_member(stream, bool, state, offset_cw); - trace_dump_member(stream, bool, state, offset_ccw); - trace_dump_member(stream, bool, state, scissor); - trace_dump_member(stream, bool, state, poly_smooth); - trace_dump_member(stream, bool, state, poly_stipple_enable); - trace_dump_member(stream, bool, state, point_smooth); - trace_dump_member(stream, bool, state, point_sprite); - trace_dump_member(stream, bool, state, point_size_per_vertex); - trace_dump_member(stream, bool, state, multisample); - trace_dump_member(stream, bool, state, line_smooth); - trace_dump_member(stream, bool, state, line_stipple_enable); - trace_dump_member(stream, uint, state, line_stipple_factor); - trace_dump_member(stream, uint, state, line_stipple_pattern); - trace_dump_member(stream, bool, state, line_last_pixel); - trace_dump_member(stream, bool, state, bypass_clipping); - trace_dump_member(stream, bool, state, bypass_vs); - trace_dump_member(stream, bool, state, origin_lower_left); - trace_dump_member(stream, bool, state, flatshade_first); - trace_dump_member(stream, bool, state, gl_rasterization_rules); - - trace_dump_member(stream, float, state, line_width); - trace_dump_member(stream, float, state, point_size); - trace_dump_member(stream, float, state, point_size_min); - trace_dump_member(stream, float, state, point_size_max); - trace_dump_member(stream, float, state, offset_units); - trace_dump_member(stream, float, state, offset_scale); + trace_dump_struct_begin("pipe_rasterizer_state"); + + trace_dump_member(bool, state, flatshade); + trace_dump_member(bool, state, light_twoside); + trace_dump_member(uint, state, front_winding); + trace_dump_member(uint, state, cull_mode); + trace_dump_member(uint, state, fill_cw); + trace_dump_member(uint, state, fill_ccw); + trace_dump_member(bool, state, offset_cw); + trace_dump_member(bool, state, offset_ccw); + trace_dump_member(bool, state, scissor); + trace_dump_member(bool, state, poly_smooth); + trace_dump_member(bool, state, poly_stipple_enable); + trace_dump_member(bool, state, point_smooth); + trace_dump_member(bool, state, point_sprite); + trace_dump_member(bool, state, point_size_per_vertex); + trace_dump_member(bool, state, multisample); + trace_dump_member(bool, state, line_smooth); + trace_dump_member(bool, state, line_stipple_enable); + trace_dump_member(uint, state, line_stipple_factor); + trace_dump_member(uint, state, line_stipple_pattern); + trace_dump_member(bool, state, line_last_pixel); + trace_dump_member(bool, state, bypass_clipping); + trace_dump_member(bool, state, bypass_vs); + trace_dump_member(bool, state, origin_lower_left); + trace_dump_member(bool, state, flatshade_first); + trace_dump_member(bool, state, gl_rasterization_rules); + + trace_dump_member(float, state, line_width); + trace_dump_member(float, state, point_size); + trace_dump_member(float, state, point_size_min); + trace_dump_member(float, state, point_size_max); + trace_dump_member(float, state, offset_units); + trace_dump_member(float, state, offset_scale); - trace_dump_member_array(stream, uint, state, sprite_coord_mode); + trace_dump_member_array(uint, state, sprite_coord_mode); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_poly_stipple(struct trace_stream *stream, - const struct pipe_poly_stipple *state) +void trace_dump_poly_stipple(const struct pipe_poly_stipple *state) { assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_poly_stipple"); + trace_dump_struct_begin("pipe_poly_stipple"); - trace_dump_member_begin(stream, "stipple"); - trace_dump_array(stream, - uint, + trace_dump_member_begin("stipple"); + trace_dump_array(uint, state->stipple, Elements(state->stipple)); - trace_dump_member_end(stream); + trace_dump_member_end(); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_viewport_state(struct trace_stream *stream, - const struct pipe_viewport_state *state) +void trace_dump_viewport_state(const struct pipe_viewport_state *state) { assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_viewport_state"); + trace_dump_struct_begin("pipe_viewport_state"); - trace_dump_member_array(stream, float, state, scale); - trace_dump_member_array(stream, float, state, translate); + trace_dump_member_array(float, state, scale); + trace_dump_member_array(float, state, translate); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_scissor_state(struct trace_stream *stream, - const struct pipe_scissor_state *state) +void trace_dump_scissor_state(const struct pipe_scissor_state *state) { assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_scissor_state"); + trace_dump_struct_begin("pipe_scissor_state"); - trace_dump_member(stream, uint, state, minx); - trace_dump_member(stream, uint, state, miny); - trace_dump_member(stream, uint, state, maxx); - trace_dump_member(stream, uint, state, maxy); + trace_dump_member(uint, state, minx); + trace_dump_member(uint, state, miny); + trace_dump_member(uint, state, maxx); + trace_dump_member(uint, state, maxy); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_clip_state(struct trace_stream *stream, - const struct pipe_clip_state *state) +void trace_dump_clip_state(const struct pipe_clip_state *state) { unsigned i; assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_scissor_state"); + trace_dump_struct_begin("pipe_scissor_state"); - trace_dump_member_begin(stream, "ucp"); - trace_dump_array_begin(stream); + trace_dump_member_begin("ucp"); + trace_dump_array_begin(); for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) - trace_dump_array(stream, float, state->ucp[i], 4); - trace_dump_array_end(stream); - trace_dump_member_end(stream); + trace_dump_array(float, state->ucp[i], 4); + trace_dump_array_end(); + trace_dump_member_end(); - trace_dump_member(stream, uint, state, nr); + trace_dump_member(uint, state, nr); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_constant_buffer(struct trace_stream *stream, - const struct pipe_constant_buffer *state) +void trace_dump_constant_buffer(const struct pipe_constant_buffer *state) { assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_constant_buffer"); + trace_dump_struct_begin("pipe_constant_buffer"); - trace_dump_member(stream, ptr, state, buffer); - trace_dump_member(stream, uint, state, size); + trace_dump_member(ptr, state, buffer); + trace_dump_member(uint, state, size); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_shader_state(struct trace_stream *stream, - const struct pipe_shader_state *state) +void trace_dump_shader_state(const struct pipe_shader_state *state) { static char str[8192]; assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } tgsi_dump_str(state->tokens, 0, str, sizeof(str)); - trace_dump_struct_begin(stream, "pipe_shader_state"); + trace_dump_struct_begin("pipe_shader_state"); - trace_dump_member_begin(stream, "tokens"); - trace_dump_string(stream, str); - trace_dump_member_end(stream); + trace_dump_member_begin("tokens"); + trace_dump_string(str); + trace_dump_member_end(); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_depth_stencil_alpha_state(struct trace_stream *stream, - const struct pipe_depth_stencil_alpha_state *state) +void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state) { unsigned i; assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_depth_stencil_alpha_state"); + trace_dump_struct_begin("pipe_depth_stencil_alpha_state"); - trace_dump_member_begin(stream, "depth"); - trace_dump_struct_begin(stream, "pipe_depth_state"); - trace_dump_member(stream, bool, &state->depth, enabled); - trace_dump_member(stream, bool, &state->depth, writemask); - trace_dump_member(stream, uint, &state->depth, func); - trace_dump_member(stream, bool, &state->depth, occlusion_count); - trace_dump_struct_end(stream); - trace_dump_member_end(stream); + trace_dump_member_begin("depth"); + trace_dump_struct_begin("pipe_depth_state"); + trace_dump_member(bool, &state->depth, enabled); + trace_dump_member(bool, &state->depth, writemask); + trace_dump_member(uint, &state->depth, func); + trace_dump_member(bool, &state->depth, occlusion_count); + trace_dump_struct_end(); + trace_dump_member_end(); - trace_dump_member_begin(stream, "stencil"); - trace_dump_array_begin(stream); + trace_dump_member_begin("stencil"); + trace_dump_array_begin(); for(i = 0; i < Elements(state->stencil); ++i) { - trace_dump_elem_begin(stream); - trace_dump_struct_begin(stream, "pipe_stencil_state"); - trace_dump_member(stream, bool, &state->stencil[i], enabled); - trace_dump_member(stream, uint, &state->stencil[i], func); - trace_dump_member(stream, uint, &state->stencil[i], fail_op); - trace_dump_member(stream, uint, &state->stencil[i], zpass_op); - trace_dump_member(stream, uint, &state->stencil[i], zfail_op); - trace_dump_member(stream, uint, &state->stencil[i], ref_value); - trace_dump_member(stream, uint, &state->stencil[i], value_mask); - trace_dump_member(stream, uint, &state->stencil[i], write_mask); - trace_dump_struct_end(stream); - trace_dump_elem_end(stream); + trace_dump_elem_begin(); + trace_dump_struct_begin("pipe_stencil_state"); + trace_dump_member(bool, &state->stencil[i], enabled); + trace_dump_member(uint, &state->stencil[i], func); + trace_dump_member(uint, &state->stencil[i], fail_op); + trace_dump_member(uint, &state->stencil[i], zpass_op); + trace_dump_member(uint, &state->stencil[i], zfail_op); + trace_dump_member(uint, &state->stencil[i], ref_value); + trace_dump_member(uint, &state->stencil[i], value_mask); + trace_dump_member(uint, &state->stencil[i], write_mask); + trace_dump_struct_end(); + trace_dump_elem_end(); } - trace_dump_array_end(stream); - trace_dump_member_end(stream); - - trace_dump_member_begin(stream, "alpha"); - trace_dump_struct_begin(stream, "pipe_alpha_state"); - trace_dump_member(stream, bool, &state->alpha, enabled); - trace_dump_member(stream, uint, &state->alpha, func); - trace_dump_member(stream, float, &state->alpha, ref); - trace_dump_struct_end(stream); - trace_dump_member_end(stream); - - trace_dump_struct_end(stream); + trace_dump_array_end(); + trace_dump_member_end(); + + trace_dump_member_begin("alpha"); + trace_dump_struct_begin("pipe_alpha_state"); + trace_dump_member(bool, &state->alpha, enabled); + trace_dump_member(uint, &state->alpha, func); + trace_dump_member(float, &state->alpha, ref); + trace_dump_struct_end(); + trace_dump_member_end(); + + trace_dump_struct_end(); } -void trace_dump_blend_state(struct trace_stream *stream, - const struct pipe_blend_state *state) +void trace_dump_blend_state(const struct pipe_blend_state *state) { assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_blend_state"); + trace_dump_struct_begin("pipe_blend_state"); - trace_dump_member(stream, bool, state, blend_enable); + trace_dump_member(bool, state, blend_enable); - trace_dump_member(stream, uint, state, rgb_func); - trace_dump_member(stream, uint, state, rgb_src_factor); - trace_dump_member(stream, uint, state, rgb_dst_factor); + trace_dump_member(uint, state, rgb_func); + trace_dump_member(uint, state, rgb_src_factor); + trace_dump_member(uint, state, rgb_dst_factor); - trace_dump_member(stream, uint, state, alpha_func); - trace_dump_member(stream, uint, state, alpha_src_factor); - trace_dump_member(stream, uint, state, alpha_dst_factor); + trace_dump_member(uint, state, alpha_func); + trace_dump_member(uint, state, alpha_src_factor); + trace_dump_member(uint, state, alpha_dst_factor); - trace_dump_member(stream, bool, state, logicop_enable); - trace_dump_member(stream, uint, state, logicop_func); + trace_dump_member(bool, state, logicop_enable); + trace_dump_member(uint, state, logicop_func); - trace_dump_member(stream, uint, state, colormask); - trace_dump_member(stream, bool, state, dither); + trace_dump_member(uint, state, colormask); + trace_dump_member(bool, state, dither); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_blend_color(struct trace_stream *stream, - const struct pipe_blend_color *state) +void trace_dump_blend_color(const struct pipe_blend_color *state) { assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_blend_color"); + trace_dump_struct_begin("pipe_blend_color"); - trace_dump_member_array(stream, float, state, color); + trace_dump_member_array(float, state, color); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_framebuffer_state(struct trace_stream *stream, - const struct pipe_framebuffer_state *state) +void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state) { - trace_dump_struct_begin(stream, "pipe_framebuffer_state"); + trace_dump_struct_begin("pipe_framebuffer_state"); - trace_dump_member(stream, uint, state, width); - trace_dump_member(stream, uint, state, height); - trace_dump_member(stream, uint, state, num_cbufs); - trace_dump_member_array(stream, ptr, state, cbufs); - trace_dump_member(stream, ptr, state, zsbuf); + trace_dump_member(uint, state, width); + trace_dump_member(uint, state, height); + trace_dump_member(uint, state, num_cbufs); + trace_dump_member_array(ptr, state, cbufs); + trace_dump_member(ptr, state, zsbuf); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_sampler_state(struct trace_stream *stream, - const struct pipe_sampler_state *state) +void trace_dump_sampler_state(const struct pipe_sampler_state *state) { assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_sampler_state"); - - trace_dump_member(stream, uint, state, wrap_s); - trace_dump_member(stream, uint, state, wrap_t); - trace_dump_member(stream, uint, state, wrap_r); - trace_dump_member(stream, uint, state, min_img_filter); - trace_dump_member(stream, uint, state, min_mip_filter); - trace_dump_member(stream, uint, state, mag_img_filter); - trace_dump_member(stream, bool, state, compare_mode); - trace_dump_member(stream, uint, state, compare_func); - trace_dump_member(stream, bool, state, normalized_coords); - trace_dump_member(stream, uint, state, prefilter); - trace_dump_member(stream, float, state, shadow_ambient); - trace_dump_member(stream, float, state, lod_bias); - trace_dump_member(stream, float, state, min_lod); - trace_dump_member(stream, float, state, max_lod); - trace_dump_member_array(stream, float, state, border_color); - trace_dump_member(stream, float, state, max_anisotropy); - - trace_dump_struct_end(stream); + trace_dump_struct_begin("pipe_sampler_state"); + + trace_dump_member(uint, state, wrap_s); + trace_dump_member(uint, state, wrap_t); + trace_dump_member(uint, state, wrap_r); + trace_dump_member(uint, state, min_img_filter); + trace_dump_member(uint, state, min_mip_filter); + trace_dump_member(uint, state, mag_img_filter); + trace_dump_member(bool, state, compare_mode); + trace_dump_member(uint, state, compare_func); + trace_dump_member(bool, state, normalized_coords); + trace_dump_member(uint, state, prefilter); + trace_dump_member(float, state, shadow_ambient); + trace_dump_member(float, state, lod_bias); + trace_dump_member(float, state, min_lod); + trace_dump_member(float, state, max_lod); + trace_dump_member_array(float, state, border_color); + trace_dump_member(float, state, max_anisotropy); + + trace_dump_struct_end(); } -void trace_dump_surface(struct trace_stream *stream, - const struct pipe_surface *state) +void trace_dump_surface(const struct pipe_surface *state) { assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_surface"); + trace_dump_struct_begin("pipe_surface"); - trace_dump_member(stream, ptr, state, buffer); - trace_dump_member(stream, format, state, format); - trace_dump_member(stream, uint, state, status); - trace_dump_member(stream, uint, state, clear_value); - trace_dump_member(stream, uint, state, width); - trace_dump_member(stream, uint, state, height); + trace_dump_member(ptr, state, buffer); + trace_dump_member(format, state, format); + trace_dump_member(uint, state, status); + trace_dump_member(uint, state, clear_value); + trace_dump_member(uint, state, width); + trace_dump_member(uint, state, height); - trace_dump_member_begin(stream, "block"); - trace_dump_block(stream, &state->block); - trace_dump_member_end(stream); + trace_dump_member_begin("block"); + trace_dump_block(&state->block); + trace_dump_member_end(); - trace_dump_member(stream, uint, state, nblocksx); - trace_dump_member(stream, uint, state, nblocksy); - trace_dump_member(stream, uint, state, stride); - trace_dump_member(stream, uint, state, layout); - trace_dump_member(stream, uint, state, offset); - trace_dump_member(stream, uint, state, refcount); - trace_dump_member(stream, uint, state, usage); - - trace_dump_member(stream, ptr, state, texture); - trace_dump_member(stream, uint, state, face); - trace_dump_member(stream, uint, state, level); - trace_dump_member(stream, uint, state, zslice); - - trace_dump_struct_end(stream); + trace_dump_member(uint, state, nblocksx); + trace_dump_member(uint, state, nblocksy); + trace_dump_member(uint, state, stride); + trace_dump_member(uint, state, layout); + trace_dump_member(uint, state, offset); + trace_dump_member(uint, state, refcount); + trace_dump_member(uint, state, usage); + + trace_dump_member(ptr, state, texture); + trace_dump_member(uint, state, face); + trace_dump_member(uint, state, level); + trace_dump_member(uint, state, zslice); + + trace_dump_struct_end(); } -void trace_dump_vertex_buffer(struct trace_stream *stream, - const struct pipe_vertex_buffer *state) +void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) { assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_vertex_buffer"); + trace_dump_struct_begin("pipe_vertex_buffer"); - trace_dump_member(stream, uint, state, pitch); - trace_dump_member(stream, uint, state, max_index); - trace_dump_member(stream, uint, state, buffer_offset); - trace_dump_member(stream, ptr, state, buffer); + trace_dump_member(uint, state, pitch); + trace_dump_member(uint, state, max_index); + trace_dump_member(uint, state, buffer_offset); + trace_dump_member(ptr, state, buffer); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } -void trace_dump_vertex_element(struct trace_stream *stream, - const struct pipe_vertex_element *state) +void trace_dump_vertex_element(const struct pipe_vertex_element *state) { assert(state); if(!state) { - trace_dump_null(stream); + trace_dump_null(); return; } - trace_dump_struct_begin(stream, "pipe_vertex_element"); + trace_dump_struct_begin("pipe_vertex_element"); - trace_dump_member(stream, uint, state, src_offset); + trace_dump_member(uint, state, src_offset); - trace_dump_member(stream, uint, state, vertex_buffer_index); - trace_dump_member(stream, uint, state, nr_components); + trace_dump_member(uint, state, vertex_buffer_index); + trace_dump_member(uint, state, nr_components); - trace_dump_member(stream, format, state, src_format); + trace_dump_member(format, state, src_format); - trace_dump_struct_end(stream); + trace_dump_struct_end(); } diff --git a/src/gallium/drivers/trace/tr_state.h b/src/gallium/drivers/trace/tr_state.h index c1df63db6a..5ae533dc66 100644 --- a/src/gallium/drivers/trace/tr_state.h +++ b/src/gallium/drivers/trace/tr_state.h @@ -4,7 +4,7 @@ * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation streams (the + * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to @@ -33,63 +33,44 @@ #include "pipe/p_shader_tokens.h" -void trace_dump_format(struct trace_stream *stream, - enum pipe_format format); +void trace_dump_format(enum pipe_format format); -void trace_dump_block(struct trace_stream *stream, - const struct pipe_format_block *block); +void trace_dump_block(const struct pipe_format_block *block); -void trace_dump_template(struct trace_stream *stream, - const struct pipe_texture *templat); +void trace_dump_template(const struct pipe_texture *templat); -void trace_dump_rasterizer_state(struct trace_stream *stream, - const struct pipe_rasterizer_state *state); +void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state); -void trace_dump_poly_stipple(struct trace_stream *stream, - const struct pipe_poly_stipple *state); +void trace_dump_poly_stipple(const struct pipe_poly_stipple *state); -void trace_dump_viewport_state(struct trace_stream *stream, - const struct pipe_viewport_state *state); +void trace_dump_viewport_state(const struct pipe_viewport_state *state); -void trace_dump_scissor_state(struct trace_stream *stream, - const struct pipe_scissor_state *state); +void trace_dump_scissor_state(const struct pipe_scissor_state *state); -void trace_dump_clip_state(struct trace_stream *stream, - const struct pipe_clip_state *state); +void trace_dump_clip_state(const struct pipe_clip_state *state); -void trace_dump_constant_buffer(struct trace_stream *stream, - const struct pipe_constant_buffer *state); +void trace_dump_constant_buffer(const struct pipe_constant_buffer *state); -void trace_dump_token(struct trace_stream *stream, - const struct tgsi_token *token); +void trace_dump_token(const struct tgsi_token *token); -void trace_dump_shader_state(struct trace_stream *stream, - const struct pipe_shader_state *state); +void trace_dump_shader_state(const struct pipe_shader_state *state); -void trace_dump_depth_stencil_alpha_state(struct trace_stream *stream, - const struct pipe_depth_stencil_alpha_state *state); +void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state); -void trace_dump_blend_state(struct trace_stream *stream, - const struct pipe_blend_state *state); +void trace_dump_blend_state(const struct pipe_blend_state *state); -void trace_dump_blend_color(struct trace_stream *stream, - const struct pipe_blend_color *state); +void trace_dump_blend_color(const struct pipe_blend_color *state); -void trace_dump_framebuffer_state(struct trace_stream *stream, - const struct pipe_framebuffer_state *state); +void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state); -void trace_dump_sampler_state(struct trace_stream *stream, - const struct pipe_sampler_state *state); +void trace_dump_sampler_state(const struct pipe_sampler_state *state); -void trace_dump_surface(struct trace_stream *stream, - const struct pipe_surface *state); +void trace_dump_surface(const struct pipe_surface *state); -void trace_dump_vertex_buffer(struct trace_stream *stream, - const struct pipe_vertex_buffer *state); +void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state); -void trace_dump_vertex_element(struct trace_stream *stream, - const struct pipe_vertex_element *state); +void trace_dump_vertex_element(const struct pipe_vertex_element *state); #endif /* TR_STATE_H */ diff --git a/src/gallium/drivers/trace/tr_stream.h b/src/gallium/drivers/trace/tr_stream.h index d50fed2691..53e854aa91 100644 --- a/src/gallium/drivers/trace/tr_stream.h +++ b/src/gallium/drivers/trace/tr_stream.h @@ -4,7 +4,7 @@ * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation streams (the + * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to @@ -28,6 +28,9 @@ /** * @file * Cross-platform sequential access stream abstraction. + * + * These are really general purpose file access functions, and might one day + * be moved into the util module. */ #ifndef TR_STREAM_H diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index 524049148d..be76c0716f 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -29,7 +29,6 @@ #include "pipe/p_state.h" #include "util/u_hash_table.h" -#include "tr_stream.h" #include "tr_dump.h" #include "tr_state.h" #include "tr_winsys.h" @@ -51,19 +50,18 @@ static const char * trace_winsys_get_name(struct pipe_winsys *_winsys) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; const char *result; - trace_dump_call_begin(stream, "pipe_winsys", "get_name"); + trace_dump_call_begin("pipe_winsys", "get_name"); - trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(ptr, winsys); result = winsys->get_name(winsys); - trace_dump_ret(stream, string, result); + trace_dump_ret(string, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -75,18 +73,17 @@ trace_winsys_flush_frontbuffer(struct pipe_winsys *_winsys, void *context_private) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; - trace_dump_call_begin(stream, "pipe_winsys", "flush_frontbuffer"); + trace_dump_call_begin("pipe_winsys", "flush_frontbuffer"); - trace_dump_arg(stream, ptr, winsys); - trace_dump_arg(stream, ptr, surface); - trace_dump_arg(stream, ptr, context_private); + trace_dump_arg(ptr, winsys); + trace_dump_arg(ptr, surface); + trace_dump_arg(ptr, context_private); winsys->flush_frontbuffer(winsys, surface, context_private); - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -94,19 +91,18 @@ static struct pipe_surface * trace_winsys_surface_alloc(struct pipe_winsys *_winsys) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; struct pipe_surface *result; - trace_dump_call_begin(stream, "pipe_winsys", "surface_alloc"); + trace_dump_call_begin("pipe_winsys", "surface_alloc"); - trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(ptr, winsys); result = winsys->surface_alloc(winsys); - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -121,19 +117,18 @@ trace_winsys_surface_alloc_storage(struct pipe_winsys *_winsys, unsigned tex_usage) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; int result; - trace_dump_call_begin(stream, "pipe_winsys", "surface_alloc_storage"); + trace_dump_call_begin("pipe_winsys", "surface_alloc_storage"); - trace_dump_arg(stream, ptr, winsys); - trace_dump_arg(stream, ptr, surface); - trace_dump_arg(stream, uint, width); - trace_dump_arg(stream, uint, height); - trace_dump_arg(stream, format, format); - trace_dump_arg(stream, uint, flags); - trace_dump_arg(stream, uint, tex_usage); + trace_dump_arg(ptr, winsys); + trace_dump_arg(ptr, surface); + trace_dump_arg(uint, width); + trace_dump_arg(uint, height); + trace_dump_arg(format, format); + trace_dump_arg(uint, flags); + trace_dump_arg(uint, tex_usage); result = winsys->surface_alloc_storage(winsys, surface, @@ -142,9 +137,9 @@ trace_winsys_surface_alloc_storage(struct pipe_winsys *_winsys, flags, tex_usage); - trace_dump_ret(stream, int, result); + trace_dump_ret(int, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -155,18 +150,17 @@ trace_winsys_surface_release(struct pipe_winsys *_winsys, struct pipe_surface **psurface) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; struct pipe_surface *surface = *psurface; - trace_dump_call_begin(stream, "pipe_winsys", "surface_release"); + trace_dump_call_begin("pipe_winsys", "surface_release"); - trace_dump_arg(stream, ptr, winsys); - trace_dump_arg(stream, ptr, surface); + trace_dump_arg(ptr, winsys); + trace_dump_arg(ptr, surface); winsys->surface_release(winsys, psurface); - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -177,22 +171,21 @@ trace_winsys_buffer_create(struct pipe_winsys *_winsys, unsigned size) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; struct pipe_buffer *buffer; - trace_dump_call_begin(stream, "pipe_winsys", "buffer_create"); + trace_dump_call_begin("pipe_winsys", "buffer_create"); - trace_dump_arg(stream, ptr, winsys); - trace_dump_arg(stream, uint, alignment); - trace_dump_arg(stream, uint, usage); - trace_dump_arg(stream, uint, size); + trace_dump_arg(ptr, winsys); + trace_dump_arg(uint, alignment); + trace_dump_arg(uint, usage); + trace_dump_arg(uint, size); buffer = winsys->buffer_create(winsys, alignment, usage, size); - trace_dump_ret(stream, ptr, buffer); + trace_dump_ret(ptr, buffer); - trace_dump_call_end(stream); + trace_dump_call_end(); /* Zero the buffer to avoid dumping uninitialized memory */ if(buffer->usage & PIPE_BUFFER_USAGE_CPU_WRITE) { @@ -214,21 +207,20 @@ trace_winsys_user_buffer_create(struct pipe_winsys *_winsys, unsigned bytes) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; struct pipe_buffer *result; - trace_dump_call_begin(stream, "pipe_winsys", "user_buffer_create"); + trace_dump_call_begin("pipe_winsys", "user_buffer_create"); - trace_dump_arg(stream, ptr, winsys); - trace_dump_arg(stream, ptr, ptr); - trace_dump_arg(stream, uint, bytes); + trace_dump_arg(ptr, winsys); + trace_dump_arg(ptr, ptr); + trace_dump_arg(uint, bytes); result = winsys->user_buffer_create(winsys, ptr, bytes); - trace_dump_ret(stream, ptr, result); + trace_dump_ret(ptr, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -260,27 +252,26 @@ trace_winsys_buffer_unmap(struct pipe_winsys *_winsys, struct pipe_buffer *buffer) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; const void *map; map = hash_table_get(tr_ws->buffer_maps, buffer); if(map) { - trace_dump_call_begin(stream, "pipe_winsys", "buffer_write"); + trace_dump_call_begin("pipe_winsys", "buffer_write"); - trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(ptr, winsys); - trace_dump_arg(stream, ptr, buffer); + trace_dump_arg(ptr, buffer); - trace_dump_arg_begin(stream, "data"); - trace_dump_bytes(stream, map, buffer->size); - trace_dump_arg_end(stream); + trace_dump_arg_begin("data"); + trace_dump_bytes(map, buffer->size); + trace_dump_arg_end(); - trace_dump_arg_begin(stream, "size"); - trace_dump_uint(stream, buffer->size); - trace_dump_arg_end(stream); + trace_dump_arg_begin("size"); + trace_dump_uint(buffer->size); + trace_dump_arg_end(); - trace_dump_call_end(stream); + trace_dump_call_end(); hash_table_remove(tr_ws->buffer_maps, buffer); } @@ -294,17 +285,16 @@ trace_winsys_buffer_destroy(struct pipe_winsys *_winsys, struct pipe_buffer *buffer) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; - trace_dump_call_begin(stream, "pipe_winsys", "buffer_destroy"); + trace_dump_call_begin("pipe_winsys", "buffer_destroy"); - trace_dump_arg(stream, ptr, winsys); - trace_dump_arg(stream, ptr, buffer); + trace_dump_arg(ptr, winsys); + trace_dump_arg(ptr, buffer); winsys->buffer_destroy(winsys, buffer); - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -314,19 +304,18 @@ trace_winsys_fence_reference(struct pipe_winsys *_winsys, struct pipe_fence_handle *src) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; struct pipe_fence_handle *dst = *pdst; - trace_dump_call_begin(stream, "pipe_winsys", "fence_reference"); + trace_dump_call_begin("pipe_winsys", "fence_reference"); - trace_dump_arg(stream, ptr, winsys); - trace_dump_arg(stream, ptr, dst); - trace_dump_arg(stream, ptr, src); + trace_dump_arg(ptr, winsys); + trace_dump_arg(ptr, dst); + trace_dump_arg(ptr, src); winsys->fence_reference(winsys, pdst, src); - trace_dump_call_end(stream); + trace_dump_call_end(); } @@ -336,21 +325,20 @@ trace_winsys_fence_signalled(struct pipe_winsys *_winsys, unsigned flag) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; int result; - trace_dump_call_begin(stream, "pipe_winsys", "fence_signalled"); + trace_dump_call_begin("pipe_winsys", "fence_signalled"); - trace_dump_arg(stream, ptr, winsys); - trace_dump_arg(stream, ptr, fence); - trace_dump_arg(stream, uint, flag); + trace_dump_arg(ptr, winsys); + trace_dump_arg(ptr, fence); + trace_dump_arg(uint, flag); result = winsys->fence_signalled(winsys, fence, flag); - trace_dump_ret(stream, int, result); + trace_dump_ret(int, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -362,21 +350,20 @@ trace_winsys_fence_finish(struct pipe_winsys *_winsys, unsigned flag) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; int result; - trace_dump_call_begin(stream, "pipe_winsys", "fence_finish"); + trace_dump_call_begin("pipe_winsys", "fence_finish"); - trace_dump_arg(stream, ptr, winsys); - trace_dump_arg(stream, ptr, fence); - trace_dump_arg(stream, uint, flag); + trace_dump_arg(ptr, winsys); + trace_dump_arg(ptr, fence); + trace_dump_arg(uint, flag); result = winsys->fence_finish(winsys, fence, flag); - trace_dump_ret(stream, int, result); + trace_dump_ret(int, result); - trace_dump_call_end(stream); + trace_dump_call_end(); return result; } @@ -386,18 +373,17 @@ static void trace_winsys_destroy(struct pipe_winsys *_winsys) { struct trace_winsys *tr_ws = trace_winsys(_winsys); - struct trace_stream *stream = tr_ws->stream; struct pipe_winsys *winsys = tr_ws->winsys; - trace_dump_call_begin(stream, "pipe_winsys", "destroy"); + trace_dump_call_begin("pipe_winsys", "destroy"); - trace_dump_arg(stream, ptr, winsys); + trace_dump_arg(ptr, winsys); /* winsys->destroy(winsys); */ - trace_dump_call_end(stream); + trace_dump_call_end(); hash_table_destroy(tr_ws->buffer_maps); @@ -406,15 +392,16 @@ trace_winsys_destroy(struct pipe_winsys *_winsys) struct pipe_winsys * -trace_winsys_create(struct trace_stream *stream, - struct pipe_winsys *winsys) +trace_winsys_create(struct pipe_winsys *winsys) { - struct trace_winsys *tr_ws; + if(!winsys) + goto error1; + tr_ws = CALLOC_STRUCT(trace_winsys); if(!tr_ws) - return NULL; + goto error1; tr_ws->base.destroy = trace_winsys_destroy; tr_ws->base.get_name = trace_winsys_get_name; @@ -432,16 +419,20 @@ trace_winsys_create(struct trace_stream *stream, tr_ws->base.fence_finish = trace_winsys_fence_finish; tr_ws->winsys = winsys; - tr_ws->stream = stream; tr_ws->buffer_maps = hash_table_create(trace_buffer_hash, trace_buffer_compare); if(!tr_ws->buffer_maps) - return NULL; + goto error2; - trace_dump_call_begin(stream, "", "pipe_winsys_create"); - trace_dump_ret(stream, ptr, winsys); - trace_dump_call_end(stream); + trace_dump_call_begin("", "pipe_winsys_create"); + trace_dump_ret(ptr, winsys); + trace_dump_call_end(); return &tr_ws->base; + +error2: + FREE(tr_ws); +error1: + return winsys; } diff --git a/src/gallium/drivers/trace/tr_winsys.h b/src/gallium/drivers/trace/tr_winsys.h index 704d2c57c8..2218117347 100644 --- a/src/gallium/drivers/trace/tr_winsys.h +++ b/src/gallium/drivers/trace/tr_winsys.h @@ -35,7 +35,6 @@ struct hash_table; -struct trace_stream; struct trace_winsys @@ -44,8 +43,6 @@ struct trace_winsys struct pipe_winsys *winsys; - struct trace_stream *stream; - struct hash_table *buffer_maps; }; @@ -60,8 +57,7 @@ trace_winsys(struct pipe_winsys *winsys) struct pipe_winsys * -trace_winsys_create(struct trace_stream *stream, - struct pipe_winsys *winsys); +trace_winsys_create(struct pipe_winsys *winsys); #endif /* TR_WINSYS_H_ */ -- cgit v1.2.3 From 424dea98d47e77f61efc79134b230f2046061ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 14:34:33 +0100 Subject: trace: Trace surface contents. --- src/gallium/drivers/trace/README | 4 -- src/gallium/drivers/trace/tr_screen.c | 75 +++++++++++++++++++++++++---------- src/gallium/drivers/trace/tr_screen.h | 5 +++ 3 files changed, 60 insertions(+), 24 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index 5752448b93..5f0ae2c641 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -22,9 +22,5 @@ which should create a gallium.*.trace file, which is an XML file. You can view copying trace.xsl and trace.css to the same directory, and opening with a XSLT capable browser like Firefox or Internet Explorer. -This is still work in progress, namely: -- surface writes are not traced -- no way to know the start/end of a frame - -- Jose Fonseca diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 68165a4553..2eecfdc187 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -26,6 +26,7 @@ **************************************************************************/ #include "pipe/p_util.h" +#include "util/u_hash_table.h" #include "tr_dump.h" #include "tr_state.h" @@ -33,6 +34,18 @@ #include "tr_screen.h" +static unsigned trace_surface_hash(void *surface) +{ + return (unsigned)(uintptr_t)surface; +} + + +static int trace_surface_compare(void *surface1, void *surface2) +{ + return (char *)surface2 - (char *)surface1; +} + + static const char * trace_screen_get_name(struct pipe_screen *_screen) { @@ -275,21 +288,17 @@ trace_screen_surface_map(struct pipe_screen *_screen, { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; - struct pipe_surface *result; - - trace_dump_call_begin("pipe_screen", "surface_map"); + void *map; - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, surface); - trace_dump_arg(uint, flags); - - result = screen->surface_map(screen, surface, flags); + map = screen->surface_map(screen, surface, flags); + if(map) { + if(flags & PIPE_BUFFER_USAGE_CPU_WRITE) { + assert(!hash_table_get(tr_scr->surface_maps, surface)); + hash_table_set(tr_scr->surface_maps, surface, map); + } + } - trace_dump_ret(ptr, result); - - trace_dump_call_end(); - - return result; + return map; } @@ -299,15 +308,36 @@ trace_screen_surface_unmap(struct pipe_screen *_screen, { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; - - trace_dump_call_begin("pipe_screen", "surface_unmap"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, surface); + const void *map; + + map = hash_table_get(tr_scr->surface_maps, surface); + if(map) { + size_t size = surface->nblocksy * surface->stride; + + trace_dump_call_begin("pipe_winsys", "surface_write"); + + trace_dump_arg(ptr, screen); + + trace_dump_arg(ptr, surface); + + trace_dump_arg_begin("data"); + trace_dump_bytes(map, size); + trace_dump_arg_end(); + + trace_dump_arg_begin("stride"); + trace_dump_uint(surface->stride); + trace_dump_arg_end(); + + trace_dump_arg_begin("size"); + trace_dump_uint(size); + trace_dump_arg_end(); + + trace_dump_call_end(); + + hash_table_remove(tr_scr->surface_maps, surface); + } screen->surface_unmap(screen, surface); - - trace_dump_call_end(); } @@ -368,6 +398,11 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->screen = screen; + tr_scr->surface_maps = hash_table_create(trace_surface_hash, + trace_surface_compare); + if(!tr_scr->surface_maps) + goto error3; + trace_dump_call_begin("", "pipe_screen_create"); trace_dump_arg_begin("winsys"); trace_dump_ptr(screen->winsys); diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h index 446c4af6a6..90103aa922 100644 --- a/src/gallium/drivers/trace/tr_screen.h +++ b/src/gallium/drivers/trace/tr_screen.h @@ -34,11 +34,16 @@ #include "pipe/p_screen.h" +struct hash_table; + + struct trace_screen { struct pipe_screen base; struct pipe_screen *screen; + + struct hash_table *surface_maps; }; -- cgit v1.2.3 From 37336b7d9e7f8bed8765e9d8e4f61f804e4d8107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 14:35:25 +0100 Subject: python: Fix put/get_tile_raw bindings. --- src/gallium/state_trackers/python/p_texture.i | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i index 06bc105465..f23afea167 100644 --- a/src/gallium/state_trackers/python/p_texture.i +++ b/src/gallium/state_trackers/python/p_texture.i @@ -102,12 +102,12 @@ void unmap( void ); void - get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, unsigned char *raw, unsigned stride) { + get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, char *raw, unsigned stride) { pipe_get_tile_raw($self, x, y, w, h, raw, stride); } void - put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned char *raw, unsigned stride) { + put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const char *raw, unsigned stride) { pipe_put_tile_raw($self, x, y, w, h, raw, stride); } -- cgit v1.2.3 From 4fffc9d63f117cfc5d5b2400536e8757c786cc1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 14:38:58 +0100 Subject: trace: Several fixes. --- src/gallium/drivers/trace/tr_context.c | 8 +++++--- src/gallium/drivers/trace/tr_winsys.c | 16 ++++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 868b4f010d..e81cab252c 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -318,11 +318,11 @@ trace_context_create_sampler_state(struct pipe_context *_pipe, trace_dump_call_begin("pipe_context", "create_sampler_state"); trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, state); + trace_dump_arg(sampler_state, state); result = pipe->create_sampler_state(pipe, state);; - trace_dump_ret(sampler_state, result); + trace_dump_ret(ptr, result); trace_dump_call_end(); @@ -888,10 +888,12 @@ trace_context_flush(struct pipe_context *_pipe, trace_dump_arg(ptr, pipe); trace_dump_arg(uint, flags); - trace_dump_arg(ptr, fence); pipe->flush(pipe, flags, fence);; + if(fence) + trace_dump_ret(ptr, *fence); + trace_dump_call_end(); } diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index be76c0716f..356579809a 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -74,12 +74,14 @@ trace_winsys_flush_frontbuffer(struct pipe_winsys *_winsys, { struct trace_winsys *tr_ws = trace_winsys(_winsys); struct pipe_winsys *winsys = tr_ws->winsys; - + trace_dump_call_begin("pipe_winsys", "flush_frontbuffer"); trace_dump_arg(ptr, winsys); trace_dump_arg(ptr, surface); + /* XXX: hide, as there is nothing we can do with this trace_dump_arg(ptr, context_private); + */ winsys->flush_frontbuffer(winsys, surface, context_private); @@ -203,8 +205,8 @@ trace_winsys_buffer_create(struct pipe_winsys *_winsys, static struct pipe_buffer * trace_winsys_user_buffer_create(struct pipe_winsys *_winsys, - void *ptr, - unsigned bytes) + void *data, + unsigned size) { struct trace_winsys *tr_ws = trace_winsys(_winsys); struct pipe_winsys *winsys = tr_ws->winsys; @@ -213,10 +215,12 @@ trace_winsys_user_buffer_create(struct pipe_winsys *_winsys, trace_dump_call_begin("pipe_winsys", "user_buffer_create"); trace_dump_arg(ptr, winsys); - trace_dump_arg(ptr, ptr); - trace_dump_arg(uint, bytes); + trace_dump_arg_begin("data"); + trace_dump_bytes(data, size); + trace_dump_arg_end(); + trace_dump_arg(uint, size); - result = winsys->user_buffer_create(winsys, ptr, bytes); + result = winsys->user_buffer_create(winsys, data, size); trace_dump_ret(ptr, result); -- cgit v1.2.3 From 14fe0d62ee8cf1dd48ec8d373ee3dcb3fe06fd77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 14:40:27 +0100 Subject: python/retrace: Keep addresses as strings. To simplify looking up these in the trace. --- src/gallium/state_trackers/python/retrace/model.py | 2 +- src/gallium/state_trackers/python/retrace/parser.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/retrace/model.py b/src/gallium/state_trackers/python/retrace/model.py index c17b5db9f8..a17a765914 100755 --- a/src/gallium/state_trackers/python/retrace/model.py +++ b/src/gallium/state_trackers/python/retrace/model.py @@ -89,7 +89,7 @@ class Pointer(Node): visitor.visit_pointer(self) def __str__(self): - return hex(self.address) + return self.address class Call: diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/src/gallium/state_trackers/python/retrace/parser.py index 571d8f6eae..9ee47f6e19 100755 --- a/src/gallium/state_trackers/python/retrace/parser.py +++ b/src/gallium/state_trackers/python/retrace/parser.py @@ -316,8 +316,6 @@ class TraceParser(XmlParser): address = self.character_data() self.element_end('ptr') - address = int(address, 16) - return Pointer(address) -- cgit v1.2.3 From c9751522b0ee1908c79f3f9d37b508ac0680bd16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 14 Aug 2008 22:03:35 +0100 Subject: pyhon/retrace: Retrace surface contents. Now capable of replaying trivial/quad-tex-2d --- .../state_trackers/python/retrace/interpreter.py | 35 ++++++++++++++++------ 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index ae62bc04a8..00b6376623 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -105,7 +105,8 @@ member_array_factories = { "pipe_viewport_state": {"scale": gallium.FloatArray, "translate": gallium.FloatArray}, "pipe_clip_state": {"ucp": gallium.FloatArray}, "pipe_depth_stencil_alpha_state": {"stencil": gallium.StencilArray}, - "pipe_blend_color": {"color": gallium.FloatArray}, + "pipe_blend_color": {"color": gallium.FloatArray}, + "pipe_sampler_state": {"border_color": gallium.FloatArray}, } @@ -191,6 +192,15 @@ class Winsys(Object): def get_name(self): pass + def user_buffer_create(self, data, size): + # We don't really care to distinguish between user and regular buffers + buffer = self.real.buffer_create(size, + 4, + gallium.PIPE_BUFFER_USAGE_CPU_READ | + gallium.PIPE_BUFFER_USAGE_CPU_WRITE ) + buffer.write(data, size) + return buffer + def buffer_create(self, alignment, usage, size): return self.real.buffer_create(size, alignment, usage) @@ -199,7 +209,15 @@ class Winsys(Object): def buffer_write(self, buffer, data, size): buffer.write(data, size) - buffer.write(data, size) + + def fence_finish(self, fence, flags): + pass + + def fence_reference(self, dst, src): + pass + + def flush_frontbuffer(self, surface): + pass class Screen(Object): @@ -239,11 +257,9 @@ class Screen(Object): def tex_surface_release(self, surface): self.interpreter.unregister_object(surface) - def surface_map(self, surface, flags): - return None - - def surface_unmap(self, surface): - pass + def surface_write(self, surface, data, stride, size): + assert surface.nblocksy * stride == size + surface.put_tile_raw(0, 0, surface.width, surface.height, data, stride) class Context(Object): @@ -324,7 +340,7 @@ class Context(Object): def set_sampler_textures(self, n, textures): for i in range(n): - self.real.set_sampler_textures(textures[i]) + self.real.set_sampler_texture(i, textures[i]) def set_vertex_buffers(self, n, vbufs): for i in range(n): @@ -350,8 +366,9 @@ class Context(Object): self.real.draw_arrays(mode, start, count) self._update() - def flush(self, flags, fence): + def flush(self, flags): self.real.flush(flags) + return None def clear(self, surface, value): self.real.surface_clear(surface, value) -- cgit v1.2.3 From f121d0e54f39d8f6361dcf0bf4d938ccb5ae4b5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Aug 2008 10:24:09 +0100 Subject: trace: Allow multiple screens. Flush after call. --- src/gallium/drivers/trace/tr_dump.c | 53 ++++++++++++++++++++++++----------- src/gallium/drivers/trace/tr_dump.h | 1 + src/gallium/drivers/trace/tr_stream.c | 12 ++++++++ src/gallium/drivers/trace/tr_stream.h | 3 ++ 4 files changed, 53 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 6ebb639b7c..c711a56b94 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -52,6 +52,7 @@ static struct trace_stream *stream = NULL; +static unsigned refcount = 0; static INLINE void @@ -204,35 +205,54 @@ trace_dump_tag_end(const char *name) trace_dump_writes(">"); } +static void +trace_dump_trace_close(void) +{ + if(stream) { + trace_dump_writes("\n"); + trace_stream_close(stream); + stream = NULL; + refcount = 0; + } +} + boolean trace_dump_trace_begin() { if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) return FALSE; - stream = trace_stream_create("gallium", "trace"); - if(!stream) - return FALSE; - - trace_dump_writes("\n"); - trace_dump_writes("\n"); - trace_dump_writes("\n"); + if(!stream) { + stream = trace_stream_create("gallium", "trace"); + if(!stream) + return FALSE; + + trace_dump_writes("\n"); + trace_dump_writes("\n"); + trace_dump_writes("\n"); + #if defined(PIPE_OS_LINUX) - /* Linux applications rarely cleanup GL / Gallium resources so catch - * application exit here */ - atexit(trace_dump_trace_end); + /* Linux applications rarely cleanup GL / Gallium resources so catch + * application exit here */ + atexit(trace_dump_trace_close); #endif + } + + ++refcount; return TRUE; } +boolean trace_dump_enabled(void) +{ + return stream ? TRUE : FALSE; +} + void trace_dump_trace_end(void) { - if(stream) { - trace_dump_writes("\n"); - trace_stream_close(stream); - stream = NULL; - } + if(stream) + if(!--refcount) + trace_dump_trace_close(); } void trace_dump_call_begin(const char *klass, const char *method) @@ -247,6 +267,7 @@ void trace_dump_call_end(void) trace_dump_indent(1); trace_dump_tag_end("call"); trace_dump_newline(); + trace_stream_flush(stream); } void trace_dump_arg_begin(const char *name) @@ -372,7 +393,7 @@ void trace_dump_null(void) void trace_dump_ptr(const void *value) { if(value) - trace_dump_writef("%p", value); + trace_dump_writef("0x%08lx", (unsigned long)(uintptr_t)value); else trace_dump_null(); } diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index 0beb1023b1..14176a78e9 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -39,6 +39,7 @@ boolean trace_dump_trace_begin(void); +boolean trace_dump_enabled(void); void trace_dump_trace_end(void); void trace_dump_call_begin(const char *klass, const char *method); void trace_dump_call_end(void); diff --git a/src/gallium/drivers/trace/tr_stream.c b/src/gallium/drivers/trace/tr_stream.c index 14cc257e15..aecc1286b8 100644 --- a/src/gallium/drivers/trace/tr_stream.c +++ b/src/gallium/drivers/trace/tr_stream.c @@ -86,6 +86,18 @@ trace_stream_write(struct trace_stream *stream, const void *data, size_t size) } +void +trace_stream_flush(struct trace_stream *stream) +{ + if(!stream) + return; + +#if defined(PIPE_OS_LINUX) + fflush(stream->file); +#endif +} + + void trace_stream_close(struct trace_stream *stream) { diff --git a/src/gallium/drivers/trace/tr_stream.h b/src/gallium/drivers/trace/tr_stream.h index 53e854aa91..679c4a725d 100644 --- a/src/gallium/drivers/trace/tr_stream.h +++ b/src/gallium/drivers/trace/tr_stream.h @@ -48,6 +48,9 @@ trace_stream_create(const char *name, const char *ext); boolean trace_stream_write(struct trace_stream *stream, const void *data, size_t size); +void +trace_stream_flush(struct trace_stream *stream); + void trace_stream_close(struct trace_stream *stream); -- cgit v1.2.3 From f40de50def1b7ee75dd320b151c025b7ddff45be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Aug 2008 10:31:23 +0100 Subject: trace: Wrap all textures and surface created by the pipe driver. That is, Unfortunately, this causes a regression in softpipe, where the output gets tyled. --- src/gallium/drivers/trace/SConscript | 11 ++-- src/gallium/drivers/trace/tr_context.c | 73 ++++++++++++++++++++- src/gallium/drivers/trace/tr_screen.c | 104 +++++++++++++++++++++--------- src/gallium/drivers/trace/tr_screen.h | 16 +---- src/gallium/drivers/trace/tr_texture.c | 112 +++++++++++++++++++++++++++++++++ src/gallium/drivers/trace/tr_texture.h | 95 ++++++++++++++++++++++++++++ src/gallium/drivers/trace/tr_winsys.c | 16 +++++ 7 files changed, 378 insertions(+), 49 deletions(-) create mode 100644 src/gallium/drivers/trace/tr_texture.c create mode 100644 src/gallium/drivers/trace/tr_texture.h (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript index 35507e21e4..a21ced9176 100644 --- a/src/gallium/drivers/trace/SConscript +++ b/src/gallium/drivers/trace/SConscript @@ -3,14 +3,15 @@ Import('*') env = env.Clone() trace = env.ConvenienceLibrary( - target = 'trace', - source = [ + target = 'trace', + source = [ 'tr_context.c', 'tr_dump.c', - 'tr_screen.c', + 'tr_screen.c', 'tr_state.c', - 'tr_stream.c', + 'tr_stream.c', + 'tr_texture.c', 'tr_winsys.c', - ]) + ]) Export('trace') \ No newline at end of file diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index e81cab252c..529bed3c6b 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -30,9 +30,53 @@ #include "tr_dump.h" #include "tr_state.h" +#include "tr_screen.h" +#include "tr_texture.h" #include "tr_context.h" +static INLINE struct pipe_texture * +trace_texture_unwrap(struct trace_context *tr_ctx, + struct pipe_texture *texture) +{ + struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen); + struct trace_texture *tr_tex; + + if(!texture) + return NULL; + + tr_tex = trace_texture(tr_scr, texture); + + assert(tr_tex->texture); + assert(tr_tex->texture->screen == tr_scr->screen); + return tr_tex->texture; +} + + +static INLINE struct pipe_surface * +trace_surface_unwrap(struct trace_context *tr_ctx, + struct pipe_surface *surface) +{ + struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen); + struct trace_texture *tr_tex; + struct trace_surface *tr_surf; + + if(!surface) + return NULL; + + assert(surface->texture); + if(!surface->texture) + return surface; + + tr_tex = trace_texture(tr_scr, surface->texture); + tr_surf = trace_surface(tr_tex, surface); + + assert(tr_surf->surface); + assert(tr_surf->surface->texture->screen == tr_scr->screen); + return tr_surf->surface; +} + + static INLINE void trace_context_set_edgeflags(struct pipe_context *_pipe, const unsigned *bitfield) @@ -666,7 +710,18 @@ trace_context_set_framebuffer_state(struct pipe_context *_pipe, { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - + struct pipe_framebuffer_state unwrapped_state; + unsigned i; + + /* Unwrap the input state */ + memcpy(&unwrapped_state, state, sizeof(unwrapped_state)); + for(i = 0; i < state->num_cbufs; ++i) + unwrapped_state.cbufs[i] = trace_surface_unwrap(tr_ctx, state->cbufs[i]); + for(i = state->num_cbufs; i < PIPE_MAX_COLOR_BUFS; ++i) + unwrapped_state.cbufs[i] = NULL; + unwrapped_state.zsbuf = trace_surface_unwrap(tr_ctx, state->zsbuf); + state = &unwrapped_state; + trace_dump_call_begin("pipe_context", "set_framebuffer_state"); trace_dump_arg(ptr, pipe); @@ -739,6 +794,12 @@ trace_context_set_sampler_textures(struct pipe_context *_pipe, { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS]; + unsigned i; + + for(i = 0; i < num_textures; ++i) + unwrapped_textures[i] = trace_texture_unwrap(tr_ctx, textures[i]); + textures = unwrapped_textures; trace_dump_call_begin("pipe_context", "set_sampler_textures"); @@ -810,6 +871,9 @@ trace_context_surface_copy(struct pipe_context *_pipe, struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; + dest = trace_surface_unwrap(tr_ctx, dest); + src = trace_surface_unwrap(tr_ctx, src); + trace_dump_call_begin("pipe_context", "surface_copy"); trace_dump_arg(ptr, pipe); @@ -841,6 +905,8 @@ trace_context_surface_fill(struct pipe_context *_pipe, struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; + dst = trace_surface_unwrap(tr_ctx, dst); + trace_dump_call_begin("pipe_context", "surface_fill"); trace_dump_arg(ptr, pipe); @@ -864,6 +930,8 @@ trace_context_clear(struct pipe_context *_pipe, struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; + surface = trace_surface_unwrap(tr_ctx, surface); + trace_dump_call_begin("pipe_context", "clear"); trace_dump_arg(ptr, pipe); @@ -925,6 +993,9 @@ trace_context_create(struct pipe_screen *screen, if(!pipe) goto error1; + if(!trace_dump_enabled()) + goto error1; + tr_ctx = CALLOC_STRUCT(trace_context); if(!tr_ctx) goto error1; diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index 2eecfdc187..cca8597a87 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -26,26 +26,14 @@ **************************************************************************/ #include "pipe/p_util.h" -#include "util/u_hash_table.h" #include "tr_dump.h" #include "tr_state.h" #include "tr_winsys.h" +#include "tr_texture.h" #include "tr_screen.h" -static unsigned trace_surface_hash(void *surface) -{ - return (unsigned)(uintptr_t)surface; -} - - -static int trace_surface_compare(void *surface1, void *surface2) -{ - return (char *)surface2 - (char *)surface1; -} - - static const char * trace_screen_get_name(struct pipe_screen *_screen) { @@ -182,6 +170,8 @@ trace_screen_texture_create(struct pipe_screen *_screen, trace_dump_call_end(); + result = trace_texture_create(tr_scr, result); + return result; } @@ -210,6 +200,8 @@ trace_screen_texture_blanket(struct pipe_screen *_screen, trace_dump_call_end(); + result = trace_texture_create(tr_scr, result); + return result; } @@ -220,18 +212,34 @@ trace_screen_texture_release(struct pipe_screen *_screen, { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; - struct pipe_texture *texture = *ptexture; + struct trace_texture *tr_tex; + struct pipe_texture *texture; + + assert(ptexture); + if(*ptexture) { + tr_tex = trace_texture(tr_scr, *ptexture); + texture = tr_tex->texture; + assert(texture->screen == screen); + } + else + texture = NULL; trace_dump_call_begin("pipe_screen", "texture_release"); trace_dump_arg(ptr, screen); trace_dump_arg(ptr, texture); - screen->texture_release(screen, ptexture); + if (*ptexture) { + if (!--(*ptexture)->refcount) + trace_texture_destroy(tr_scr, *ptexture); + + *ptexture = NULL; + } trace_dump_call_end(); } + static struct pipe_surface * trace_screen_get_tex_surface(struct pipe_screen *_screen, struct pipe_texture *texture, @@ -241,8 +249,14 @@ trace_screen_get_tex_surface(struct pipe_screen *_screen, { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; + struct trace_texture *tr_tex; struct pipe_surface *result; + assert(texture); + tr_tex = trace_texture(tr_scr, texture); + texture = tr_tex->texture; + assert(texture->screen == screen); + trace_dump_call_begin("pipe_screen", "get_tex_surface"); trace_dump_arg(ptr, screen); @@ -258,6 +272,8 @@ trace_screen_get_tex_surface(struct pipe_screen *_screen, trace_dump_call_end(); + result = trace_surface_create(tr_tex, result); + return result; } @@ -268,14 +284,30 @@ trace_screen_tex_surface_release(struct pipe_screen *_screen, { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; - struct pipe_surface *surface = *psurface; + struct trace_texture *tr_tex; + struct trace_surface *tr_surf; + struct pipe_surface *surface; + + assert(psurface); + if(*psurface) { + tr_tex = trace_texture(tr_scr, (*psurface)->texture); + tr_surf = trace_surface(tr_tex, *psurface); + surface = tr_surf->surface; + } + else + surface = NULL; trace_dump_call_begin("pipe_screen", "tex_surface_release"); trace_dump_arg(ptr, screen); trace_dump_arg(ptr, surface); - screen->tex_surface_release(screen, psurface); + if (*psurface) { + if (!--(*psurface)->refcount) + trace_surface_destroy(tr_tex, *psurface); + + *psurface = NULL; + } trace_dump_call_end(); } @@ -288,13 +320,19 @@ trace_screen_surface_map(struct pipe_screen *_screen, { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; + struct trace_texture *tr_tex; + struct trace_surface *tr_surf; void *map; + tr_tex = trace_texture(tr_scr, surface->texture); + tr_surf = trace_surface(tr_tex, surface); + surface = tr_surf->surface; + map = screen->surface_map(screen, surface, flags); if(map) { if(flags & PIPE_BUFFER_USAGE_CPU_WRITE) { - assert(!hash_table_get(tr_scr->surface_maps, surface)); - hash_table_set(tr_scr->surface_maps, surface, map); + assert(!tr_surf->map); + tr_surf->map = map; } } @@ -308,10 +346,14 @@ trace_screen_surface_unmap(struct pipe_screen *_screen, { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; - const void *map; + struct trace_texture *tr_tex; + struct trace_surface *tr_surf; - map = hash_table_get(tr_scr->surface_maps, surface); - if(map) { + tr_tex = trace_texture(tr_scr, surface->texture); + tr_surf = trace_surface(tr_tex, surface); + surface = tr_surf->surface; + + if(tr_surf->map) { size_t size = surface->nblocksy * surface->stride; trace_dump_call_begin("pipe_winsys", "surface_write"); @@ -321,7 +363,7 @@ trace_screen_surface_unmap(struct pipe_screen *_screen, trace_dump_arg(ptr, surface); trace_dump_arg_begin("data"); - trace_dump_bytes(map, size); + trace_dump_bytes(tr_surf->map, size); trace_dump_arg_end(); trace_dump_arg_begin("stride"); @@ -334,7 +376,7 @@ trace_screen_surface_unmap(struct pipe_screen *_screen, trace_dump_call_end(); - hash_table_remove(tr_scr->surface_maps, surface); + tr_surf->map = NULL; } screen->surface_unmap(screen, surface); @@ -398,11 +440,6 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->screen = screen; - tr_scr->surface_maps = hash_table_create(trace_surface_hash, - trace_surface_compare); - if(!tr_scr->surface_maps) - goto error3; - trace_dump_call_begin("", "pipe_screen_create"); trace_dump_arg_begin("winsys"); trace_dump_ptr(screen->winsys); @@ -419,3 +456,12 @@ error2: error1: return screen; } + + +struct trace_screen * +trace_screen(struct pipe_screen *screen) +{ + assert(screen); + assert(screen->destroy == trace_screen_destroy); + return (struct trace_screen *)screen; +} diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h index 90103aa922..698b84811d 100644 --- a/src/gallium/drivers/trace/tr_screen.h +++ b/src/gallium/drivers/trace/tr_screen.h @@ -29,31 +29,19 @@ #define TR_SCREEN_H_ -#include "pipe/p_compiler.h" -#include "pipe/p_debug.h" #include "pipe/p_screen.h" -struct hash_table; - - struct trace_screen { struct pipe_screen base; struct pipe_screen *screen; - - struct hash_table *surface_maps; }; -static INLINE struct trace_screen * -trace_screen(struct pipe_screen *screen) -{ - assert(screen); - return (struct trace_screen *)screen; -} - +struct trace_screen * +trace_screen(struct pipe_screen *screen); struct pipe_screen * diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c new file mode 100644 index 0000000000..99ba74d366 --- /dev/null +++ b/src/gallium/drivers/trace/tr_texture.c @@ -0,0 +1,112 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "util/u_hash_table.h" + +#include "tr_screen.h" +#include "tr_texture.h" + + +struct pipe_texture * +trace_texture_create(struct trace_screen *tr_scr, + struct pipe_texture *texture) +{ + struct trace_texture *tr_tex; + + if(!texture) + goto error; + + assert(texture->screen == tr_scr->screen); + + tr_tex = CALLOC_STRUCT(trace_texture); + if(!tr_tex) + goto error; + + memcpy(&tr_tex->base, texture, sizeof(struct pipe_texture)); + tr_tex->base.screen = &tr_scr->base; + tr_tex->texture = texture; + + return &tr_tex->base; + +error: + pipe_texture_reference(&texture, NULL); + return NULL; +} + + +void +trace_texture_destroy(struct trace_screen *tr_scr, + struct pipe_texture *texture) +{ + struct trace_texture *tr_tex = trace_texture(tr_scr, texture); + pipe_texture_reference(&tr_tex->texture, NULL); + FREE(tr_tex); +} + + +struct pipe_surface * +trace_surface_create(struct trace_texture *tr_tex, + struct pipe_surface *surface) +{ + struct trace_surface *tr_surf; + + if(!surface) + goto error; + + assert(surface->texture == tr_tex->texture); + + tr_surf = CALLOC_STRUCT(trace_surface); + if(!tr_surf) + goto error; + + memcpy(&tr_surf->base, surface, sizeof(struct pipe_surface)); + + tr_surf->base.winsys = tr_tex->base.screen->winsys; + tr_surf->base.texture = NULL; + pipe_texture_reference(&tr_surf->base.texture, &tr_tex->base); + tr_surf->surface = surface; + + return &tr_surf->base; + +error: + pipe_surface_reference(&surface, NULL); + return NULL; +} + + +void +trace_surface_destroy(struct trace_texture *tr_tex, + struct pipe_surface *surface) +{ + struct trace_surface *tr_surf = trace_surface(tr_tex, surface); + pipe_texture_reference(&tr_surf->base.texture, NULL); + pipe_surface_reference(&tr_surf->surface, NULL); + FREE(tr_surf); +} + diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h new file mode 100644 index 0000000000..9e72edb8a3 --- /dev/null +++ b/src/gallium/drivers/trace/tr_texture.h @@ -0,0 +1,95 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TR_TEXTURE_H_ +#define TR_TEXTURE_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "tr_screen.h" + + +struct trace_texture +{ + struct pipe_texture base; + + struct pipe_texture *texture; +}; + + +struct trace_surface +{ + struct pipe_surface base; + + struct pipe_surface *surface; + + void *map; +}; + + +static INLINE struct trace_texture * +trace_texture(struct trace_screen *tr_scr, + struct pipe_texture *texture) +{ + if(!texture) + return NULL; + assert(texture->screen == &tr_scr->base); + return (struct trace_texture *)texture; +} + + +static INLINE struct trace_surface * +trace_surface(struct trace_texture *tr_tex, + struct pipe_surface *surface) +{ + if(!surface) + return NULL; + assert(surface->texture == &tr_tex->base); + return (struct trace_surface *)surface; +} + + +struct pipe_texture * +trace_texture_create(struct trace_screen *tr_scr, + struct pipe_texture *texture); + +void +trace_texture_destroy(struct trace_screen *tr_scr, + struct pipe_texture *texture); + +struct pipe_surface * +trace_surface_create(struct trace_texture *tr_tex, + struct pipe_surface *surface); + +void +trace_surface_destroy(struct trace_texture *tr_tex, + struct pipe_surface *surface); + + +#endif /* TR_TEXTURE_H_ */ diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index 356579809a..c426211408 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -31,6 +31,8 @@ #include "tr_dump.h" #include "tr_state.h" +#include "tr_screen.h" +#include "tr_texture.h" #include "tr_winsys.h" @@ -75,6 +77,14 @@ trace_winsys_flush_frontbuffer(struct pipe_winsys *_winsys, struct trace_winsys *tr_ws = trace_winsys(_winsys); struct pipe_winsys *winsys = tr_ws->winsys; + assert(surface); + if(surface->texture) { + struct trace_screen *tr_scr = trace_screen(surface->texture->screen); + struct trace_screen *tr_tex = trace_texture(tr_scr, surface->texture); + struct trace_surface *tr_surf = trace_surface(tr_tex, surface); + surface = tr_surf->surface; + } + trace_dump_call_begin("pipe_winsys", "flush_frontbuffer"); trace_dump_arg(ptr, winsys); @@ -106,6 +116,8 @@ trace_winsys_surface_alloc(struct pipe_winsys *_winsys) trace_dump_call_end(); + assert(!result || !result->texture); + return result; } @@ -122,6 +134,8 @@ trace_winsys_surface_alloc_storage(struct pipe_winsys *_winsys, struct pipe_winsys *winsys = tr_ws->winsys; int result; + assert(surface && !surface->texture); + trace_dump_call_begin("pipe_winsys", "surface_alloc_storage"); trace_dump_arg(ptr, winsys); @@ -155,6 +169,8 @@ trace_winsys_surface_release(struct pipe_winsys *_winsys, struct pipe_winsys *winsys = tr_ws->winsys; struct pipe_surface *surface = *psurface; + assert(psurface && *psurface && !(*psurface)->texture); + trace_dump_call_begin("pipe_winsys", "surface_release"); trace_dump_arg(ptr, winsys); -- cgit v1.2.3 From 52ecb8f56368180b5dec303d1d77a8d0596aaef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Aug 2008 10:33:35 +0100 Subject: python/retrace: Update frame when PIPE_FLUSH_FRAME spotted. --- src/gallium/state_trackers/python/retrace/interpreter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index 00b6376623..fa9a65365c 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -364,10 +364,11 @@ class Context(Object): def draw_arrays(self, mode, start, count): self.real.draw_arrays(mode, start, count) - self._update() def flush(self, flags): self.real.flush(flags) + if flags & gallium.PIPE_FLUSH_FRAME: + self._update() return None def clear(self, surface, value): -- cgit v1.2.3 From 9d58b2a432d44fc2861f2df1a611188f92dc288f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Aug 2008 11:20:57 +0100 Subject: trace: Fix typo. --- src/gallium/drivers/trace/tr_winsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index c426211408..120006ea9f 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -80,7 +80,7 @@ trace_winsys_flush_frontbuffer(struct pipe_winsys *_winsys, assert(surface); if(surface->texture) { struct trace_screen *tr_scr = trace_screen(surface->texture->screen); - struct trace_screen *tr_tex = trace_texture(tr_scr, surface->texture); + struct trace_texture *tr_tex = trace_texture(tr_scr, surface->texture); struct trace_surface *tr_surf = trace_surface(tr_tex, surface); surface = tr_surf->surface; } -- cgit v1.2.3 From 4b1b5ca9bd4d861ac8654c510f12b52a1a646ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 15 Aug 2008 11:24:06 +0100 Subject: xlib: Kill xmesa_surface. A winsys cannot expect that the surfaces passed display_surface are the surfaces it created, as surface are now in generate texture views created by pipe_screen. Indeed, the fact it was working so far was mere luck. This fixes a weird tiled output when using the trace pipe driver. Winsys' surfaces should die. --- src/gallium/winsys/xlib/xm_winsys.c | 62 ++++++++++++------------------------- 1 file changed, 19 insertions(+), 43 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 3ab4c67cae..4b4dc56e84 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -81,18 +81,6 @@ struct xm_buffer }; -/** - * Subclass of pipe_surface for Xlib winsys - */ -struct xmesa_surface -{ - struct pipe_surface surface; - - int tileSize; - boolean no_swap; -}; - - /** * Subclass of pipe_winsys for Xlib winsys */ @@ -105,14 +93,6 @@ struct xmesa_pipe_winsys -/** Cast wrapper */ -static INLINE struct xmesa_surface * -xmesa_surface(struct pipe_surface *ps) -{ - return (struct xmesa_surface *) ps; -} - - /** Cast wrapper */ static INLINE struct xm_buffer * xm_buffer( struct pipe_buffer *buf ) @@ -358,13 +338,24 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) { XImage *ximage; struct xm_buffer *xm_buf = xm_buffer(surf->buffer); - const struct xmesa_surface *xm_surf - = xmesa_surface((struct pipe_surface *) surf); + static boolean no_swap = 0; + static boolean firsttime = 1; + static int tileSize = 0; - if (xm_surf->no_swap) + if (firsttime) { + no_swap = getenv("SP_NO_RAST") != NULL; +#ifdef GALLIUM_CELL + if (!getenv("GALLIUM_NOCELL")) { + tileSize = 32; /** probably temporary */ + } +#endif + firsttime = 0; + } + + if (no_swap) return; - if (xm_surf->tileSize) { + if (tileSize) { xmesa_display_surface_tiled(b, surf); return; } @@ -531,29 +522,14 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, static struct pipe_surface * xm_surface_alloc(struct pipe_winsys *ws) { - struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface); - static boolean no_swap = 0; - static boolean firsttime = 1; - - if (firsttime) { - no_swap = getenv("SP_NO_RAST") != NULL; - firsttime = 0; - } + struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); assert(ws); - xms->surface.refcount = 1; - xms->surface.winsys = ws; + surface->refcount = 1; + surface->winsys = ws; -#ifdef GALLIUM_CELL - if (!getenv("GALLIUM_NOCELL")) { - xms->tileSize = 32; /** probably temporary */ - } -#endif - - xms->no_swap = no_swap; - - return &xms->surface; + return surface; } -- cgit v1.2.3 From 2037b1381c129c74ba87a092484258608583d34e Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Sun, 17 Aug 2008 19:14:00 +0100 Subject: rather than use CRTC 1 (aka LVDS), try and setup all connectors/encoders and get the same output on all. --- src/gallium/winsys/egl_drm/intel/intel_egl.c | 111 ++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index 55f4d92afb..1851babaf6 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -66,7 +66,67 @@ egl_drm_create_device(int drmFD) return device; } -__GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size ); +static void +_egl_context_modes_destroy(__GLcontextModes *modes) +{ + _eglLog(_EGL_DEBUG, "%s", __FUNCTION__); + + while (modes) { + __GLcontextModes * const next = modes->next; + free(modes); + modes = next; + } +} +/** + * Create a linked list of 'count' GLcontextModes. + * These are used during the client/server visual negotiation phase, + * then discarded. + */ +static __GLcontextModes * +_egl_context_modes_create(unsigned count, size_t minimum_size) +{ + /* This code copied from libGLX, and modified */ + const size_t size = (minimum_size > sizeof(__GLcontextModes)) + ? minimum_size : sizeof(__GLcontextModes); + __GLcontextModes * head = NULL; + __GLcontextModes ** next; + unsigned i; + + _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size); + + next = & head; + for (i = 0 ; i < count ; i++) { + *next = (__GLcontextModes *) calloc(1, size); + if (*next == NULL) { + _egl_context_modes_destroy(head); + head = NULL; + break; + } + + (*next)->doubleBufferMode = 1; + (*next)->visualID = GLX_DONT_CARE; + (*next)->visualType = GLX_DONT_CARE; + (*next)->visualRating = GLX_NONE; + (*next)->transparentPixel = GLX_NONE; + (*next)->transparentRed = GLX_DONT_CARE; + (*next)->transparentGreen = GLX_DONT_CARE; + (*next)->transparentBlue = GLX_DONT_CARE; + (*next)->transparentAlpha = GLX_DONT_CARE; + (*next)->transparentIndex = GLX_DONT_CARE; + (*next)->xRenderable = GLX_DONT_CARE; + (*next)->fbconfigID = GLX_DONT_CARE; + (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; + (*next)->bindToTextureRgb = GLX_DONT_CARE; + (*next)->bindToTextureRgba = GLX_DONT_CARE; + (*next)->bindToMipmapTexture = GLX_DONT_CARE; + (*next)->bindToTextureTargets = 0; + (*next)->yInverted = GLX_DONT_CARE; + + next = & ((*next)->next); + } + + return head; +} struct drm_screen; @@ -102,7 +162,6 @@ struct drm_screen /* currently only support one connector */ drmModeConnectorPtr connector; - uint32_t connectorID; /* Has this screen been shown */ int shown; @@ -190,7 +249,6 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) screen = malloc(sizeof(struct drm_screen)); memset(screen, 0, sizeof(*screen)); - screen->connectorID = res->connectors[i]; screen->connector = connector; _eglInitScreen(&screen->base); _eglAddScreen(disp, &screen->base); @@ -225,17 +283,20 @@ static void drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) { struct drm_driver *drm_drv = (struct drm_driver *)drv; + unsigned int i; intel_bind_frontbuffer(screen->surf->drawable, NULL); screen->surf = NULL; - drmModeSetCrtc( - drm_drv->device->drmFD, - drm_drv->res->crtcs[1], - 0, // FD - 0, 0, - NULL, 0, // List of output ids - NULL); + for (i = 0; i < drm_drv->res->count_crtcs; i++) { + drmModeSetCrtc( + drm_drv->device->drmFD, + drm_drv->res->crtcs[i], + 0, // FD + 0, 0, + NULL, 0, // List of output ids + NULL); + } drmModeRmFB(drm_drv->device->drmFD, screen->fbID); drmModeFreeFB(screen->fb); @@ -560,9 +621,10 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, struct drm_surface *surf = lookup_drm_surface(surface); struct drm_screen *scrn = lookup_drm_screen(dpy, screen); _EGLMode *mode = _eglLookupMode(dpy, m); - size_t pitch = 2048 * 4; + size_t pitch = mode->Width * 4; size_t size = mode->Height * pitch; int ret; + unsigned int i,j,k; if (scrn->shown) drm_takedown_shown_screen(drv, scrn); @@ -596,14 +658,25 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, if (!scrn->mode) goto err_fb; - ret = drmModeSetCrtc( - drm_drv->device->drmFD, - drm_drv->res->crtcs[1], - scrn->fbID, - 0, 0, - &scrn->connectorID, 1, - scrn->mode); - + for (j = 0; j < drm_drv->res->count_connectors; j++) { + drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]); + for (k = 0; k < con->count_encoders; k++) { + drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]); + for (i = 0; i < drm_drv->res->count_crtcs; i++) { + if (enc->possible_crtcs & (1<device->drmFD, + drm_drv->res->crtcs[i], + scrn->fbID, + 0, 0, + &drm_drv->res->connectors[j], 1, + scrn->mode); + /* skip the other crtcs now */ + i = drm_drv->res->count_crtcs; + } + } + } + } scrn->front.handle = scrn->buffer.handle; scrn->front.pitch = pitch; -- cgit v1.2.3 From ccf1910dd4b2a8ccd04ddbdf725b6dd3f8026eee Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Sun, 17 Aug 2008 20:17:18 +0100 Subject: consolidate intel directories. we now have src/gallium/winsys/drm/intel/{common,dri,egl} --- src/gallium/winsys/SConscript | 4 +- src/gallium/winsys/common/Makefile | 20 - src/gallium/winsys/common/Makefile.template | 64 -- src/gallium/winsys/common/intel_drm/Makefile | 23 - src/gallium/winsys/common/intel_drm/glthread.h | 359 -------- .../winsys/common/intel_drm/intel_be_batchbuffer.c | 429 --------- .../winsys/common/intel_drm/intel_be_batchbuffer.h | 69 -- .../winsys/common/intel_drm/intel_be_context.c | 107 --- .../winsys/common/intel_drm/intel_be_context.h | 40 - .../winsys/common/intel_drm/intel_be_device.c | 308 ------- .../winsys/common/intel_drm/intel_be_device.h | 72 -- .../winsys/common/intel_drm/ws_dri_bufmgr.c | 949 -------------------- .../winsys/common/intel_drm/ws_dri_bufmgr.h | 138 --- .../winsys/common/intel_drm/ws_dri_bufpool.h | 102 --- .../winsys/common/intel_drm/ws_dri_drmpool.c | 268 ------ .../winsys/common/intel_drm/ws_dri_fencemgr.c | 377 -------- .../winsys/common/intel_drm/ws_dri_fencemgr.h | 115 --- .../winsys/common/intel_drm/ws_dri_mallocpool.c | 161 ---- .../winsys/common/intel_drm/ws_dri_slabpool.c | 968 --------------------- src/gallium/winsys/dri/Makefile | 38 - src/gallium/winsys/dri/Makefile.template | 125 --- src/gallium/winsys/dri/SConscript | 54 -- src/gallium/winsys/dri/intel/Makefile | 34 - src/gallium/winsys/dri/intel/SConscript | 41 - src/gallium/winsys/dri/intel/intel_batchbuffer.h | 24 - src/gallium/winsys/dri/intel/intel_context.c | 337 ------- src/gallium/winsys/dri/intel/intel_context.h | 164 ---- src/gallium/winsys/dri/intel/intel_lock.c | 102 --- src/gallium/winsys/dri/intel/intel_reg.h | 53 -- src/gallium/winsys/dri/intel/intel_screen.c | 607 ------------- src/gallium/winsys/dri/intel/intel_screen.h | 122 --- src/gallium/winsys/dri/intel/intel_swapbuffers.c | 261 ------ src/gallium/winsys/dri/intel/intel_swapbuffers.h | 47 - .../winsys/dri/intel/intel_winsys_softpipe.c | 82 -- .../winsys/dri/intel/intel_winsys_softpipe.h | 39 - src/gallium/winsys/dri/intel/server/i830_common.h | 255 ------ src/gallium/winsys/dri/intel/server/i830_dri.h | 62 -- src/gallium/winsys/drm/Makefile | 38 + src/gallium/winsys/drm/Makefile.template | 125 +++ src/gallium/winsys/drm/SConscript | 54 ++ src/gallium/winsys/drm/intel/Makefile | 25 + src/gallium/winsys/drm/intel/common/Makefile | 23 + .../winsys/drm/intel/common/Makefile.template | 64 ++ src/gallium/winsys/drm/intel/common/glthread.h | 359 ++++++++ .../winsys/drm/intel/common/intel_be_batchbuffer.c | 429 +++++++++ .../winsys/drm/intel/common/intel_be_batchbuffer.h | 69 ++ .../winsys/drm/intel/common/intel_be_context.c | 107 +++ .../winsys/drm/intel/common/intel_be_context.h | 40 + .../winsys/drm/intel/common/intel_be_device.c | 308 +++++++ .../winsys/drm/intel/common/intel_be_device.h | 72 ++ .../winsys/drm/intel/common/ws_dri_bufmgr.c | 949 ++++++++++++++++++++ .../winsys/drm/intel/common/ws_dri_bufmgr.h | 138 +++ .../winsys/drm/intel/common/ws_dri_bufpool.h | 102 +++ .../winsys/drm/intel/common/ws_dri_drmpool.c | 268 ++++++ .../winsys/drm/intel/common/ws_dri_fencemgr.c | 377 ++++++++ .../winsys/drm/intel/common/ws_dri_fencemgr.h | 115 +++ .../winsys/drm/intel/common/ws_dri_mallocpool.c | 161 ++++ .../winsys/drm/intel/common/ws_dri_slabpool.c | 968 +++++++++++++++++++++ src/gallium/winsys/drm/intel/dri/Makefile | 33 + src/gallium/winsys/drm/intel/dri/SConscript | 41 + .../winsys/drm/intel/dri/intel_batchbuffer.h | 24 + src/gallium/winsys/drm/intel/dri/intel_context.c | 337 +++++++ src/gallium/winsys/drm/intel/dri/intel_context.h | 164 ++++ src/gallium/winsys/drm/intel/dri/intel_lock.c | 102 +++ src/gallium/winsys/drm/intel/dri/intel_reg.h | 53 ++ src/gallium/winsys/drm/intel/dri/intel_screen.c | 607 +++++++++++++ src/gallium/winsys/drm/intel/dri/intel_screen.h | 122 +++ .../winsys/drm/intel/dri/intel_swapbuffers.c | 261 ++++++ .../winsys/drm/intel/dri/intel_swapbuffers.h | 47 + .../winsys/drm/intel/dri/intel_winsys_softpipe.c | 82 ++ .../winsys/drm/intel/dri/intel_winsys_softpipe.h | 39 + .../winsys/drm/intel/dri/server/i830_common.h | 255 ++++++ src/gallium/winsys/drm/intel/dri/server/i830_dri.h | 62 ++ src/gallium/winsys/drm/intel/egl/Makefile | 28 + src/gallium/winsys/drm/intel/egl/SConscript | 39 + .../winsys/drm/intel/egl/intel_batchbuffer.h | 24 + src/gallium/winsys/drm/intel/egl/intel_context.c | 242 ++++++ src/gallium/winsys/drm/intel/egl/intel_context.h | 118 +++ src/gallium/winsys/drm/intel/egl/intel_device.c | 137 +++ src/gallium/winsys/drm/intel/egl/intel_device.h | 50 ++ src/gallium/winsys/drm/intel/egl/intel_egl.c | 796 +++++++++++++++++ src/gallium/winsys/drm/intel/egl/intel_egl.h | 53 ++ src/gallium/winsys/drm/intel/egl/intel_reg.h | 53 ++ .../winsys/drm/intel/egl/intel_swapbuffers.c | 111 +++ src/gallium/winsys/egl_drm/Makefile | 38 - src/gallium/winsys/egl_drm/Makefile.template | 117 --- src/gallium/winsys/egl_drm/intel/Makefile | 29 - src/gallium/winsys/egl_drm/intel/SConscript | 39 - .../winsys/egl_drm/intel/intel_batchbuffer.h | 24 - src/gallium/winsys/egl_drm/intel/intel_context.c | 242 ------ src/gallium/winsys/egl_drm/intel/intel_context.h | 118 --- src/gallium/winsys/egl_drm/intel/intel_device.c | 137 --- src/gallium/winsys/egl_drm/intel/intel_device.h | 50 -- src/gallium/winsys/egl_drm/intel/intel_egl.c | 796 ----------------- src/gallium/winsys/egl_drm/intel/intel_egl.h | 53 -- src/gallium/winsys/egl_drm/intel/intel_reg.h | 53 -- .../winsys/egl_drm/intel/intel_swapbuffers.c | 111 --- src/gallium/winsys/gdi/wmesa.c | 70 -- 98 files changed, 8673 insertions(+), 8895 deletions(-) delete mode 100644 src/gallium/winsys/common/Makefile delete mode 100644 src/gallium/winsys/common/Makefile.template delete mode 100644 src/gallium/winsys/common/intel_drm/Makefile delete mode 100644 src/gallium/winsys/common/intel_drm/glthread.h delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_context.c delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_context.h delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_device.c delete mode 100644 src/gallium/winsys/common/intel_drm/intel_be_device.h delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c delete mode 100644 src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c delete mode 100644 src/gallium/winsys/dri/Makefile delete mode 100644 src/gallium/winsys/dri/Makefile.template delete mode 100644 src/gallium/winsys/dri/SConscript delete mode 100644 src/gallium/winsys/dri/intel/Makefile delete mode 100644 src/gallium/winsys/dri/intel/SConscript delete mode 100644 src/gallium/winsys/dri/intel/intel_batchbuffer.h delete mode 100644 src/gallium/winsys/dri/intel/intel_context.c delete mode 100644 src/gallium/winsys/dri/intel/intel_context.h delete mode 100644 src/gallium/winsys/dri/intel/intel_lock.c delete mode 100644 src/gallium/winsys/dri/intel/intel_reg.h delete mode 100644 src/gallium/winsys/dri/intel/intel_screen.c delete mode 100644 src/gallium/winsys/dri/intel/intel_screen.h delete mode 100644 src/gallium/winsys/dri/intel/intel_swapbuffers.c delete mode 100644 src/gallium/winsys/dri/intel/intel_swapbuffers.h delete mode 100644 src/gallium/winsys/dri/intel/intel_winsys_softpipe.c delete mode 100644 src/gallium/winsys/dri/intel/intel_winsys_softpipe.h delete mode 100644 src/gallium/winsys/dri/intel/server/i830_common.h delete mode 100644 src/gallium/winsys/dri/intel/server/i830_dri.h create mode 100644 src/gallium/winsys/drm/Makefile create mode 100644 src/gallium/winsys/drm/Makefile.template create mode 100644 src/gallium/winsys/drm/SConscript create mode 100644 src/gallium/winsys/drm/intel/Makefile create mode 100644 src/gallium/winsys/drm/intel/common/Makefile create mode 100644 src/gallium/winsys/drm/intel/common/Makefile.template create mode 100644 src/gallium/winsys/drm/intel/common/glthread.h create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.c create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.h create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_context.c create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_context.h create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_device.c create mode 100644 src/gallium/winsys/drm/intel/common/intel_be_device.h create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.h create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.h create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c create mode 100644 src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c create mode 100644 src/gallium/winsys/drm/intel/dri/Makefile create mode 100644 src/gallium/winsys/drm/intel/dri/SConscript create mode 100644 src/gallium/winsys/drm/intel/dri/intel_batchbuffer.h create mode 100644 src/gallium/winsys/drm/intel/dri/intel_context.c create mode 100644 src/gallium/winsys/drm/intel/dri/intel_context.h create mode 100644 src/gallium/winsys/drm/intel/dri/intel_lock.c create mode 100644 src/gallium/winsys/drm/intel/dri/intel_reg.h create mode 100644 src/gallium/winsys/drm/intel/dri/intel_screen.c create mode 100644 src/gallium/winsys/drm/intel/dri/intel_screen.h create mode 100644 src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c create mode 100644 src/gallium/winsys/drm/intel/dri/intel_swapbuffers.h create mode 100644 src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c create mode 100644 src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.h create mode 100644 src/gallium/winsys/drm/intel/dri/server/i830_common.h create mode 100644 src/gallium/winsys/drm/intel/dri/server/i830_dri.h create mode 100644 src/gallium/winsys/drm/intel/egl/Makefile create mode 100644 src/gallium/winsys/drm/intel/egl/SConscript create mode 100644 src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h create mode 100644 src/gallium/winsys/drm/intel/egl/intel_context.c create mode 100644 src/gallium/winsys/drm/intel/egl/intel_context.h create mode 100644 src/gallium/winsys/drm/intel/egl/intel_device.c create mode 100644 src/gallium/winsys/drm/intel/egl/intel_device.h create mode 100644 src/gallium/winsys/drm/intel/egl/intel_egl.c create mode 100644 src/gallium/winsys/drm/intel/egl/intel_egl.h create mode 100644 src/gallium/winsys/drm/intel/egl/intel_reg.h create mode 100644 src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c delete mode 100644 src/gallium/winsys/egl_drm/Makefile delete mode 100644 src/gallium/winsys/egl_drm/Makefile.template delete mode 100644 src/gallium/winsys/egl_drm/intel/Makefile delete mode 100644 src/gallium/winsys/egl_drm/intel/SConscript delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_context.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_context.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_device.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_device.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_egl.c delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_egl.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_reg.h delete mode 100644 src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c (limited to 'src/gallium') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index bf1718e7a5..ddab9efc86 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -1,8 +1,8 @@ Import('*') -if env['dri']: +if env['drm']: SConscript([ - 'dri/SConscript', + 'drm/SConscript', ]) if 'xlib' in env['winsys']: diff --git a/src/gallium/winsys/common/Makefile b/src/gallium/winsys/common/Makefile deleted file mode 100644 index 4c0f3545a5..0000000000 --- a/src/gallium/winsys/common/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -TOP = ../../../.. -include $(TOP)/configs/current - - -SUBDIRS = $(GALLIUM_WINSYS_COMMON_DIRS) - - -default: subdirs - - -subdirs: - @for dir in $(SUBDIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE)) || exit 1 ; \ - fi \ - done - - -clean: - rm -f `find . -name \*.[oa]` diff --git a/src/gallium/winsys/common/Makefile.template b/src/gallium/winsys/common/Makefile.template deleted file mode 100644 index 67af778157..0000000000 --- a/src/gallium/winsys/common/Makefile.template +++ /dev/null @@ -1,64 +0,0 @@ -# -*-makefile-*- - - -# We still have a dependency on the "dri" buffer manager. Most likely -# the interface can be reused in non-dri environments, and also as a -# frontend to simpler memory managers. -# -COMMON_SOURCES = - -OBJECTS = $(C_SOURCES:.c=.o) \ - $(CPP_SOURCES:.cpp=.o) \ - $(ASM_SOURCES:.S=.o) - - -### Include directories -INCLUDES = \ - -I. \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/include \ - $(DRIVER_INCLUDES) - - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.cpp.o: - $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - - -##### TARGETS ##### - -default: depend symlinks $(LIBNAME) - - -$(LIBNAME): $(OBJECTS) Makefile $(TOP)/src/gallium/winsys/common/Makefile.template - $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) - - -depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ - $(ASM_SOURCES) 2> /dev/null - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` `find ../include` - - -# Remove .o and backup files -clean:: - -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) - -rm -f depend depend.bak - - -include depend diff --git a/src/gallium/winsys/common/intel_drm/Makefile b/src/gallium/winsys/common/intel_drm/Makefile deleted file mode 100644 index 913dbeff20..0000000000 --- a/src/gallium/winsys/common/intel_drm/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -TOP = ../../../../.. -include $(TOP)/configs/current - -LIBNAME = inteldrm - -C_SOURCES = \ - intel_be_batchbuffer.c \ - intel_be_context.c \ - intel_be_device.c \ - ws_dri_bufmgr.c \ - ws_dri_drmpool.c \ - ws_dri_fencemgr.c \ - ws_dri_mallocpool.c \ - ws_dri_slabpool.c - - -include ../Makefile.template - -DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \ - && pkg-config libdrm --atleast-version=2.3.1 \ - && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") -symlinks: - diff --git a/src/gallium/winsys/common/intel_drm/glthread.h b/src/gallium/winsys/common/intel_drm/glthread.h deleted file mode 100644 index b8e9d5f59b..0000000000 --- a/src/gallium/winsys/common/intel_drm/glthread.h +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/* - * Thread support for gl dispatch. - * - * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) - * and Christoph Poliwoda (poliwoda@volumegraphics.com) - * Revised by Keith Whitwell - * Adapted for new gl dispatcher by Brian Paul - * - * - * - * DOCUMENTATION - * - * This thread module exports the following types: - * _glthread_TSD Thread-specific data area - * _glthread_Thread Thread datatype - * _glthread_Mutex Mutual exclusion lock - * - * Macros: - * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex - * _glthread_INIT_MUTEX(name) Initialize a mutex - * _glthread_LOCK_MUTEX(name) Lock a mutex - * _glthread_UNLOCK_MUTEX(name) Unlock a mutex - * - * Functions: - * _glthread_GetID(v) Get integer thread ID - * _glthread_InitTSD() Initialize thread-specific data - * _glthread_GetTSD() Get thread-specific data - * _glthread_SetTSD() Set thread-specific data - * - */ - -/* - * If this file is accidentally included by a non-threaded build, - * it should not cause the build to fail, or otherwise cause problems. - * In general, it should only be included when needed however. - */ - -#ifndef GLTHREAD_H -#define GLTHREAD_H - - -#if defined(USE_MGL_NAMESPACE) -#define _glapi_Dispatch _mglapi_Dispatch -#endif - - - -#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ - defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ - && !defined(THREADS) -# define THREADS -#endif - -#ifdef VMS -#include -#endif - -/* - * POSIX threads. This should be your choice in the Unix world - * whenever possible. When building with POSIX threads, be sure - * to enable any compiler flags which will cause the MT-safe - * libc (if one exists) to be used when linking, as well as any - * header macros for MT-safe errno, etc. For Solaris, this is the -mt - * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable - * proper compiling for MT-safe libc etc. - */ -#if defined(PTHREADS) -#include /* POSIX threads headers */ - -typedef struct { - pthread_key_t key; - int initMagic; -} _glthread_TSD; - -typedef pthread_t _glthread_Thread; - -typedef pthread_mutex_t _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER - -#define _glthread_INIT_MUTEX(name) \ - pthread_mutex_init(&(name), NULL) - -#define _glthread_DESTROY_MUTEX(name) \ - pthread_mutex_destroy(&(name)) - -#define _glthread_LOCK_MUTEX(name) \ - (void) pthread_mutex_lock(&(name)) - -#define _glthread_UNLOCK_MUTEX(name) \ - (void) pthread_mutex_unlock(&(name)) - -typedef pthread_cond_t _glthread_Cond; - -#define _glthread_DECLARE_STATIC_COND(name) \ - static _glthread_Cond name = PTHREAD_COND_INITIALIZER - -#define _glthread_INIT_COND(cond) \ - pthread_cond_init(&(cond), NULL) - -#define _glthread_DESTROY_COND(name) \ - pthread_cond_destroy(&(name)) - -#define _glthread_COND_WAIT(cond, mutex) \ - pthread_cond_wait(&(cond), &(mutex)) - -#define _glthread_COND_SIGNAL(cond) \ - pthread_cond_signal(&(cond)) - -#define _glthread_COND_BROADCAST(cond) \ - pthread_cond_broadcast(&(cond)) - - -#else /* PTHREADS */ - -typedef unsigned int _glthread_Cond; -#define _glthread_DECLARE_STATIC_COND(name) \ -// #warning Condition variables not implemented. - -#define _glthread_INIT_COND(cond) \ - abort(); - -#define _glthread_DESTROY_COND(name) \ - abort(); - -#define _glthread_COND_WAIT(cond, mutex) \ - abort(); - -#define _glthread_COND_SIGNAL(cond) \ - abort(); - -#define _glthread_COND_BROADCAST(cond) \ - abort(); - -#endif - - -/* - * Solaris threads. Use only up to Solaris 2.4. - * Solaris 2.5 and higher provide POSIX threads. - * Be sure to compile with -mt on the Solaris compilers, or - * use -D_REENTRANT if using gcc. - */ -#ifdef SOLARIS_THREADS -#include - -typedef struct { - thread_key_t key; - mutex_t keylock; - int initMagic; -} _glthread_TSD; - -typedef thread_t _glthread_Thread; - -typedef mutex_t _glthread_Mutex; - -/* XXX need to really implement mutex-related macros */ -#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 -#define _glthread_INIT_MUTEX(name) (void) name -#define _glthread_DESTROY_MUTEX(name) (void) name -#define _glthread_LOCK_MUTEX(name) (void) name -#define _glthread_UNLOCK_MUTEX(name) (void) name - -#endif /* SOLARIS_THREADS */ - - - - -/* - * Windows threads. Should work with Windows NT and 95. - * IMPORTANT: Link with multithreaded runtime library when THREADS are - * used! - */ -#ifdef WIN32_THREADS -#include - -typedef struct { - DWORD key; - int initMagic; -} _glthread_TSD; - -typedef HANDLE _glthread_Thread; - -typedef CRITICAL_SECTION _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) /*static*/ _glthread_Mutex name = {0,0,0,0,0,0} -#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name) -#define _glthread_DESTROY_MUTEX(name) DeleteCriticalSection(&name) -#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name) -#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name) - -#endif /* WIN32_THREADS */ - - - - -/* - * XFree86 has its own thread wrapper, Xthreads.h - * We wrap it again for GL. - */ -#ifdef USE_XTHREADS -#include - -typedef struct { - xthread_key_t key; - int initMagic; -} _glthread_TSD; - -typedef xthread_t _glthread_Thread; - -typedef xmutex_rec _glthread_Mutex; - -#ifdef XMUTEX_INITIALIZER -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name = XMUTEX_INITIALIZER -#else -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name -#endif - -#define _glthread_INIT_MUTEX(name) \ - xmutex_init(&(name)) - -#define _glthread_DESTROY_MUTEX(name) \ - xmutex_clear(&(name)) - -#define _glthread_LOCK_MUTEX(name) \ - (void) xmutex_lock(&(name)) - -#define _glthread_UNLOCK_MUTEX(name) \ - (void) xmutex_unlock(&(name)) - -#endif /* USE_XTHREADS */ - - - -/* - * BeOS threads. R5.x required. - */ -#ifdef BEOS_THREADS - -#include -#include - -typedef struct { - int32 key; - int initMagic; -} _glthread_TSD; - -typedef thread_id _glthread_Thread; - -/* Use Benaphore, aka speeder semaphore */ -typedef struct { - int32 lock; - sem_id sem; -} benaphore; -typedef benaphore _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = { 0, 0 } -#define _glthread_INIT_MUTEX(name) name.sem = create_sem(0, #name"_benaphore"), name.lock = 0 -#define _glthread_DESTROY_MUTEX(name) delete_sem(name.sem), name.lock = 0 -#define _glthread_LOCK_MUTEX(name) if (name.sem == 0) _glthread_INIT_MUTEX(name); \ - if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem) -#define _glthread_UNLOCK_MUTEX(name) if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem) - -#endif /* BEOS_THREADS */ - - - -#ifndef THREADS - -/* - * THREADS not defined - */ - -typedef GLuint _glthread_TSD; - -typedef GLuint _glthread_Thread; - -typedef GLuint _glthread_Mutex; - -#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 - -#define _glthread_INIT_MUTEX(name) (void) name - -#define _glthread_DESTROY_MUTEX(name) (void) name - -#define _glthread_LOCK_MUTEX(name) (void) name - -#define _glthread_UNLOCK_MUTEX(name) (void) name - -#endif /* THREADS */ - - - -/* - * Platform independent thread specific data API. - */ - -extern unsigned long -_glthread_GetID(void); - - -extern void -_glthread_InitTSD(_glthread_TSD *); - - -extern void * -_glthread_GetTSD(_glthread_TSD *); - - -extern void -_glthread_SetTSD(_glthread_TSD *, void *); - -#if defined(GLX_USE_TLS) - -extern __thread struct _glapi_table * _glapi_tls_Dispatch - __attribute__((tls_model("initial-exec"))); - -#define GET_DISPATCH() _glapi_tls_Dispatch - -#elif !defined(GL_CALL) -# if defined(THREADS) -# define GET_DISPATCH() \ - ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ - ? _glapi_Dispatch : _glapi_get_dispatch()) -# else -# define GET_DISPATCH() _glapi_Dispatch -# endif /* defined(THREADS) */ -#endif /* ndef GL_CALL */ - - -#endif /* THREADS_H */ diff --git a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c deleted file mode 100644 index bc13a5761e..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.c +++ /dev/null @@ -1,429 +0,0 @@ - -#include "intel_be_batchbuffer.h" -#include "intel_be_context.h" -#include "intel_be_device.h" -#include - -#include "xf86drm.h" - -static void -intel_realloc_relocs(struct intel_be_batchbuffer *batch, int num_relocs) -{ - unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; - - size *= sizeof(uint32_t); - batch->reloc = realloc(batch->reloc, size); - batch->reloc_size = num_relocs; -} - - -void -intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch) -{ - /* - * Get a new, free batchbuffer. - */ - drmBO *bo; - struct drm_bo_info_req *req; - - driBOUnrefUserList(batch->list); - driBOResetList(batch->list); - - /* base.size is the size available to the i915simple driver */ - batch->base.size = batch->device->max_batch_size - BATCH_RESERVED; - batch->base.actual_size = batch->device->max_batch_size; - driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0); - - /* - * Add the batchbuffer to the validate list. - */ - - driBOAddListItem(batch->list, batch->buffer, - DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, - &batch->dest_location, &batch->node); - - req = &batch->node->bo_arg.d.req.bo_req; - - /* - * Set up information needed for us to make relocations - * relative to the underlying drm buffer objects. - */ - - driReadLockKernelBO(); - bo = driBOKernel(batch->buffer); - req->presumed_offset = (uint64_t) bo->offset; - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - batch->drmBOVirtual = (uint8_t *) bo->virtual; - driReadUnlockKernelBO(); - - /* - * Adjust the relocation buffer size. - */ - - if (batch->reloc_size > INTEL_MAX_RELOCS || - batch->reloc == NULL) - intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); - - assert(batch->reloc != NULL); - batch->reloc[0] = 0; /* No relocs yet. */ - batch->reloc[1] = 1; /* Reloc type 1 */ - batch->reloc[2] = 0; /* Only a single relocation list. */ - batch->reloc[3] = 0; /* Only a single relocation list. */ - - batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); - batch->poolOffset = driBOPoolOffset(batch->buffer); - batch->base.ptr = batch->base.map; - batch->dirty_state = ~0; - batch->nr_relocs = 0; - batch->flags = 0; - batch->id = 0;//batch->intel->intelScreen->batch_id++; -} - -/*====================================================================== - * Public functions - */ -struct intel_be_batchbuffer * -intel_be_batchbuffer_alloc(struct intel_be_context *intel) -{ - struct intel_be_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel = intel; - batch->device = intel->device; - - driGenBuffers(intel->device->batchPool, "batchbuffer", 1, - &batch->buffer, 4096, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); - batch->last_fence = NULL; - batch->list = driBOCreateList(20); - batch->reloc = NULL; - intel_be_batchbuffer_reset(batch); - return batch; -} - -void -intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch) -{ - if (batch->last_fence) { - driFenceFinish(batch->last_fence, - DRM_FENCE_TYPE_EXE, FALSE); - driFenceUnReference(&batch->last_fence); - } - if (batch->base.map) { - driBOUnmap(batch->buffer); - batch->base.map = NULL; - } - driBOUnReference(batch->buffer); - driBOFreeList(batch->list); - if (batch->reloc) - free(batch->reloc); - batch->buffer = NULL; - free(batch); -} - -void -intel_be_offset_relocation(struct intel_be_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask) -{ - int itemLoc; - struct _drmBONode *node; - uint32_t *reloc; - struct drm_bo_info_req *req; - - driBOAddListItem(batch->list, driBO, val_flags, val_mask, - &itemLoc, &node); - req = &node->bo_arg.d.req.bo_req; - - if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { - - /* - * Stop other threads from tampering with the underlying - * drmBO while we're reading its offset. - */ - - driReadLockKernelBO(); - req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; - driReadUnlockKernelBO(); - req->hint = DRM_BO_HINT_PRESUMED_OFFSET; - } - - pre_add += driBOPoolOffset(driBO); - - if (batch->nr_relocs == batch->reloc_size) - intel_realloc_relocs(batch, batch->reloc_size * 2); - - reloc = batch->reloc + - (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); - - reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual); - i915_batchbuffer_dword(&batch->base, req->presumed_offset + pre_add); - reloc[1] = pre_add; - reloc[2] = itemLoc; - reloc[3] = batch->dest_location; - batch->nr_relocs++; -} - -static void -i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) -{ - buf->handle = rep->handle; - buf->flags = rep->flags; - buf->size = rep->size; - buf->offset = rep->offset; - buf->mapHandle = rep->arg_handle; - buf->proposedFlags = rep->proposed_flags; - buf->start = rep->buffer_start; - buf->fenceFlags = rep->fence_flags; - buf->replyFlags = rep->rep_flags; - buf->pageAlignment = rep->page_alignment; -} - -static int -i915_execbuf(struct intel_be_batchbuffer *batch, - unsigned int used, - boolean ignore_cliprects, - drmBOList *list, - struct drm_i915_execbuffer *ea) -{ -// struct intel_be_context *intel = batch->intel; - drmBONode *node; - drmMMListHead *l; - struct drm_i915_op_arg *arg, *first; - struct drm_bo_op_req *req; - struct drm_bo_info_rep *rep; - uint64_t *prevNext = NULL; - drmBO *buf; - int ret = 0; - uint32_t count = 0; - - first = NULL; - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - - arg = &node->bo_arg; - req = &arg->d.req; - - if (!first) - first = arg; - - if (prevNext) - *prevNext = (unsigned long)arg; - - prevNext = &arg->next; - req->bo_req.handle = node->buf->handle; - req->op = drm_bo_validate; - req->bo_req.flags = node->arg0; - req->bo_req.mask = node->arg1; - req->bo_req.hint |= 0; - count++; - } - - memset(ea, 0, sizeof(*ea)); - ea->num_buffers = count; - ea->batch.start = batch->poolOffset; - ea->batch.used = used; -#if 0 /* ZZZ JB: no cliprects used */ - ea->batch.cliprects = intel->pClipRects; - ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | - (((GLuint) intel->drawY) << 16)); -#else - ea->batch.cliprects = NULL; - ea->batch.num_cliprects = 0; - ea->batch.DR1 = 0; - ea->batch.DR4 = 0; -#endif - ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; - ea->ops_list = (unsigned long) first; - first->reloc_ptr = (unsigned long) batch->reloc; - batch->reloc[0] = batch->nr_relocs; - - //return -EFAULT; - do { - ret = drmCommandWriteRead(batch->device->fd, DRM_I915_EXECBUFFER, ea, - sizeof(*ea)); - } while (ret == -EAGAIN); - - if (ret != 0) - return ret; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - arg = &node->bo_arg; - rep = &arg->d.rep.bo_info; - - if (!arg->handled) { - return -EFAULT; - } - if (arg->d.rep.ret) - return arg->d.rep.ret; - - buf = node->buf; - i915_drm_copy_reply(rep, buf); - } - return 0; -} - -/* TODO: Push this whole function into bufmgr. - */ -static struct _DriFenceObject * -do_flush_locked(struct intel_be_batchbuffer *batch, - unsigned int used, - boolean ignore_cliprects, boolean allow_unlock) -{ - struct intel_be_context *intel = batch->intel; - struct _DriFenceObject *fo; - drmFence fence; - drmBOList *boList; - struct drm_i915_execbuffer ea; - int ret = 0; - - driBOValidateUserList(batch->list); - boList = driGetdrmBOList(batch->list); - -#if 0 /* ZZZ JB Allways run */ - if (!(intel->numClipRects == 0 && !ignore_cliprects)) { -#else - if (1) { -#endif - ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); - } else { - driPutdrmBOList(batch->list); - fo = NULL; - goto out; - } - driPutdrmBOList(batch->list); - if (ret) - abort(); - - if (ea.fence_arg.error != 0) { - - /* - * The hardware has been idled by the kernel. - * Don't fence the driBOs. - */ - - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); -#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ - _mesa_printf("fence error\n"); -#endif - batch->last_fence = NULL; - fo = NULL; - goto out; - } - - fence.handle = ea.fence_arg.handle; - fence.fence_class = ea.fence_arg.fence_class; - fence.type = ea.fence_arg.type; - fence.flags = ea.fence_arg.flags; - fence.signaled = ea.fence_arg.signaled; - - fo = driBOFenceUserList(batch->device->fenceMgr, batch->list, - "SuperFence", &fence); - - if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { - if (batch->last_fence) - driFenceUnReference(&batch->last_fence); - /* - * FIXME: Context last fence?? - */ - batch->last_fence = fo; - driFenceReference(fo); - } - out: -#if 0 /* ZZZ JB: fix this */ - intel->vtbl.lost_hardware(intel); -#else - (void)intel; -#endif - return fo; -} - - -struct _DriFenceObject * -intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch) -{ - struct intel_be_context *intel = batch->intel; - unsigned int used = batch->base.ptr - batch->base.map; - boolean was_locked = batch->intel->hardware_locked(intel); - struct _DriFenceObject *fence; - - if (used == 0) { - driFenceReference(batch->last_fence); - return batch->last_fence; - } - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a - * performance drain that we would like to avoid. - */ -#if 0 /* ZZZ JB: what should we do here? */ - if (used & 4) { - ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->base.ptr)[1] = 0; - ((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END; - used += 8; - } -#else - if (used & 4) { - ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->base.ptr)[1] = 0; - ((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; - ((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; - used += 8; - } -#endif - driBOUnmap(batch->buffer); - batch->base.ptr = NULL; - batch->base.map = NULL; - - /* TODO: Just pass the relocation list and dma buffer up to the - * kernel. - */ - if (!was_locked) - intel->hardware_lock(intel); - - fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), - FALSE); - - if (!was_locked) - intel->hardware_unlock(intel); - - /* Reset the buffer: - */ - intel_be_batchbuffer_reset(batch); - return fence; -} - -void -intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch) -{ - struct _DriFenceObject *fence = intel_be_batchbuffer_flush(batch); - driFenceFinish(fence, driFenceType(fence), FALSE); - driFenceUnReference(&fence); -} - -#if 0 -void -intel_be_batchbuffer_data(struct intel_be_batchbuffer *batch, - const void *data, unsigned int bytes, unsigned int flags) -{ - assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, flags); - memcpy(batch->base.ptr, data, bytes); - batch->base.ptr += bytes; -} -#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h b/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h deleted file mode 100644 index f150e3a674..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_batchbuffer.h +++ /dev/null @@ -1,69 +0,0 @@ - -#ifndef INTEL_BE_BATCHBUFFER_H -#define INTEL_BE_BATCHBUFFER_H - -#include "i915simple/i915_batch.h" - -#include "ws_dri_bufmgr.h" - -#define BATCH_RESERVED 16 - -#define INTEL_DEFAULT_RELOCS 100 -#define INTEL_MAX_RELOCS 400 - -#define INTEL_BATCH_NO_CLIPRECTS 0x1 -#define INTEL_BATCH_CLIPRECTS 0x2 - -struct intel_be_context; -struct intel_be_device; - -struct intel_be_batchbuffer -{ - struct i915_batchbuffer base; - - struct intel_be_context *intel; - struct intel_be_device *device; - - struct _DriBufferObject *buffer; - struct _DriFenceObject *last_fence; - uint32_t flags; - - struct _DriBufferList *list; - size_t list_count; - - uint32_t *reloc; - size_t reloc_size; - size_t nr_relocs; - - uint32_t dirty_state; - uint32_t id; - - uint32_t poolOffset; - uint8_t *drmBOVirtual; - struct _drmBONode *node; /* Validation list node for this buffer */ - int dest_location; /* Validation list sequence for this buffer */ -}; - -struct intel_be_batchbuffer * -intel_be_batchbuffer_alloc(struct intel_be_context *intel); - -void -intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch); - -void -intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch); - -struct _DriFenceObject * -intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch); - -void -intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch); - -void -intel_be_offset_relocation(struct intel_be_batchbuffer *batch, - unsigned pre_add, - struct _DriBufferObject *driBO, - uint64_t val_flags, - uint64_t val_mask); - -#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_context.c b/src/gallium/winsys/common/intel_drm/intel_be_context.c deleted file mode 100644 index 1af39674f4..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_context.c +++ /dev/null @@ -1,107 +0,0 @@ - -/* - * Authors: Jakob Bornecrantz - */ - -#include "ws_dri_fencemgr.h" -#include "intel_be_device.h" -#include "intel_be_context.h" -#include "intel_be_batchbuffer.h" - -static INLINE struct intel_be_context * -intel_be_context(struct i915_winsys *sws) -{ - return (struct intel_be_context *)sws; -} - -/* Simple batchbuffer interface: - */ - -static struct i915_batchbuffer* -intel_i915_batch_get(struct i915_winsys *sws) -{ - struct intel_be_context *intel = intel_be_context(sws); - return &intel->batch->base; -} - -static void intel_i915_batch_reloc(struct i915_winsys *sws, - struct pipe_buffer *buf, - unsigned access_flags, - unsigned delta) -{ - struct intel_be_context *intel = intel_be_context(sws); - - unsigned flags = DRM_BO_FLAG_MEM_TT; - unsigned mask = DRM_BO_MASK_MEM; - - if (access_flags & I915_BUFFER_ACCESS_WRITE) { - flags |= DRM_BO_FLAG_WRITE; - mask |= DRM_BO_FLAG_WRITE; - } - - if (access_flags & I915_BUFFER_ACCESS_READ) { - flags |= DRM_BO_FLAG_READ; - mask |= DRM_BO_FLAG_READ; - } - - intel_be_offset_relocation(intel->batch, - delta, - dri_bo(buf), - flags, - mask); -} - -static void intel_i915_batch_flush(struct i915_winsys *sws, - struct pipe_fence_handle **fence) -{ - struct intel_be_context *intel = intel_be_context(sws); - - union { - struct _DriFenceObject *dri; - struct pipe_fence_handle *pipe; - } fu; - - if (fence) - assert(!*fence); - - fu.dri = intel_be_batchbuffer_flush(intel->batch); - - if (!fu.dri) { - assert(0); - *fence = NULL; - return; - } - - if (fu.dri) { - if (fence) - *fence = fu.pipe; - else - driFenceUnReference(&fu.dri); - } - -} - -boolean -intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device) -{ - assert(intel); - assert(device); - - intel->device = device; - - /* TODO move framebuffer createion to the driver */ - - intel->base.batch_get = intel_i915_batch_get; - intel->base.batch_reloc = intel_i915_batch_reloc; - intel->base.batch_flush = intel_i915_batch_flush; - - intel->batch = intel_be_batchbuffer_alloc(intel); - - return true; -} - -void -intel_be_destroy_context(struct intel_be_context *intel) -{ - intel_be_batchbuffer_free(intel->batch); -} diff --git a/src/gallium/winsys/common/intel_drm/intel_be_context.h b/src/gallium/winsys/common/intel_drm/intel_be_context.h deleted file mode 100644 index d5cbc93594..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_context.h +++ /dev/null @@ -1,40 +0,0 @@ -/* These need to be diffrent from the intel winsys */ -#ifndef INTEL_BE_CONTEXT_H -#define INTEL_BE_CONTEXT_H - -#include "i915simple/i915_winsys.h" - -struct intel_be_context -{ - /** Interface to i915simple driver */ - struct i915_winsys base; - - struct intel_be_device *device; - struct intel_be_batchbuffer *batch; - - /* - * Hardware lock functions. - * - * Needs to be filled in by the winsys. - */ - void (*hardware_lock)(struct intel_be_context *context); - void (*hardware_unlock)(struct intel_be_context *context); - boolean (*hardware_locked)(struct intel_be_context *context); -}; - -/** - * Intialize a allocated intel_be_context struct. - * - * Remember to set the hardware_* functions. - */ -boolean -intel_be_init_context(struct intel_be_context *intel, - struct intel_be_device *device); - -/** - * Destroy a intel_be_context. - * Does not free the struct that is up to the winsys. - */ -void -intel_be_destroy_context(struct intel_be_context *intel); -#endif diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c deleted file mode 100644 index 8db0329615..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.c +++ /dev/null @@ -1,308 +0,0 @@ - - -/* - * Authors: Keith Whitwell - * Jakob Bornecrantz - */ - -#include "intel_be_device.h" -#include "ws_dri_bufmgr.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" - -#include "pipe/p_winsys.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" - -#include "i915simple/i915_screen.h" - -/* Turn a pipe winsys into an intel/pipe winsys: - */ -static INLINE struct intel_be_device * -intel_be_device( struct pipe_winsys *winsys ) -{ - return (struct intel_be_device *)winsys; -} - - -/* - * Buffer functions. - * - * Most callbacks map direcly onto dri_bufmgr operations: - */ - -static void *intel_be_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags ) -{ - unsigned drm_flags = 0; - - if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) - drm_flags |= DRM_BO_FLAG_WRITE; - - if (flags & PIPE_BUFFER_USAGE_CPU_READ) - drm_flags |= DRM_BO_FLAG_READ; - - return driBOMap( dri_bo(buf), drm_flags, 0 ); -} - -static void intel_be_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnmap( dri_bo(buf) ); -} - -static void -intel_be_buffer_destroy(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - driBOUnReference( dri_bo(buf) ); - FREE(buf); -} - -static struct pipe_buffer * -intel_be_buffer_create(struct pipe_winsys *winsys, - unsigned alignment, - unsigned usage, - unsigned size ) -{ - struct intel_be_buffer *buffer = CALLOC_STRUCT( intel_be_buffer ); - struct intel_be_device *iws = intel_be_device(winsys); - unsigned flags = 0; - struct _DriBufferPool *pool; - - buffer->base.refcount = 1; - buffer->base.alignment = alignment; - buffer->base.usage = usage; - buffer->base.size = size; - - if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { - flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; - pool = iws->mallocPool; - } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { - /* For vertex buffers */ - flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; - pool = iws->vertexPool; - } else { - flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; - pool = iws->regionPool; - } - - if (usage & PIPE_BUFFER_USAGE_GPU_READ) - flags |= DRM_BO_FLAG_READ; - - if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) - flags |= DRM_BO_FLAG_WRITE; - - /* drm complains if we don't set any read/write flags. - */ - if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) - flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - - buffer->pool = pool; - driGenBuffers( buffer->pool, - "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); - - driBOData( buffer->driBO, size, NULL, buffer->pool, 0 ); - - return &buffer->base; -} - - -static struct pipe_buffer * -intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) -{ - struct intel_be_buffer *buffer = CALLOC_STRUCT( intel_be_buffer ); - struct intel_be_device *iws = intel_be_device(winsys); - - driGenUserBuffer( iws->regionPool, - "pipe user buffer", &buffer->driBO, ptr, bytes ); - - buffer->base.refcount = 1; - - return &buffer->base; -} - -struct pipe_buffer * -intel_be_buffer_from_handle(struct intel_be_device *device, - const char* name, unsigned handle) -{ - struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); - struct pipe_buffer *buffer; - - if (!be_buf) - goto err; - - memset(be_buf, 0, sizeof(*be_buf)); - - driGenBuffers(device->staticPool, name, 1, &be_buf->driBO, 0, 0, 0); - driBOSetReferenced(be_buf->driBO, handle); - - if (0) /** XXX TODO check error */ - goto err_bo; - - buffer = &be_buf->base; - buffer->refcount = 1; - buffer->alignment = 0; - buffer->usage = 0; - buffer->size = driBOSize(be_buf->driBO); - - return buffer; -err_bo: - free(be_buf); -err: - return NULL; -} - - -/* - * Surface functions. - * - * Deprecated! - */ - -static struct pipe_surface * -intel_i915_surface_alloc(struct pipe_winsys *winsys) -{ - assert((size_t)"intel_i915_surface_alloc is deprecated" & 0); - return NULL; -} - -static int -intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, - struct pipe_surface *surf, - unsigned width, unsigned height, - enum pipe_format format, - unsigned flags, - unsigned tex_usage) -{ - assert((size_t)"intel_i915_surface_alloc_storage is deprecated" & 0); - return -1; -} - -static void -intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -{ - assert((size_t)"intel_i915_surface_release is deprecated" & 0); -} - - -/* - * Fence functions - */ - -static void -intel_be_fence_reference( struct pipe_winsys *sws, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence ) -{ - if (*ptr) - driFenceUnReference((struct _DriFenceObject **)ptr); - - if (fence) - *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); -} - -static int -intel_be_fence_signalled( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - return driFenceSignaled((struct _DriFenceObject *)fence, flag); -} - -static int -intel_be_fence_finish( struct pipe_winsys *sws, - struct pipe_fence_handle *fence, - unsigned flag ) -{ - return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); -} - - -/* - * Misc functions - */ - -boolean -intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) -{ - dev->fd = fd; - dev->max_batch_size = 16 * 4096; - dev->max_vertex_size = 128 * 4096; - - dev->base.buffer_create = intel_be_buffer_create; - dev->base.user_buffer_create = intel_be_user_buffer_create; - dev->base.buffer_map = intel_be_buffer_map; - dev->base.buffer_unmap = intel_be_buffer_unmap; - dev->base.buffer_destroy = intel_be_buffer_destroy; - dev->base.surface_alloc = intel_i915_surface_alloc; - dev->base.surface_alloc_storage = intel_i915_surface_alloc_storage; - dev->base.surface_release = intel_i915_surface_release; - dev->base.fence_reference = intel_be_fence_reference; - dev->base.fence_signalled = intel_be_fence_signalled; - dev->base.fence_finish = intel_be_fence_finish; - -#if 0 /* Set by the winsys */ - dev->base.flush_frontbuffer = intel_flush_frontbuffer; - dev->base.get_name = intel_get_name; -#endif - - dev->fMan = driInitFreeSlabManager(10, 10); - dev->fenceMgr = driFenceMgrTTMInit(dev->fd); - - dev->mallocPool = driMallocPoolInit(); - dev->staticPool = driDRMPoolInit(dev->fd); - /* Sizes: 64 128 256 512 1024 2048 4096 8192 16384 32768 */ - dev->regionPool = driSlabPoolInit(dev->fd, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - 64, - 10, 120, 4096 * 64, 0, - dev->fMan); - - dev->vertexPool = driSlabPoolInit(dev->fd, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT, - dev->max_vertex_size, - 1, 120, dev->max_vertex_size * 4, 0, - dev->fMan); - - dev->batchPool = driSlabPoolInit(dev->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT, - dev->max_batch_size, - 1, 40, dev->max_batch_size * 16, 0, - dev->fMan); - - /* Fill in this struct with callbacks that i915simple will need to - * communicate with the window system, buffer manager, etc. - */ - dev->screen = i915_create_screen(&dev->base, id); - - return true; -} - -void -intel_be_destroy_device(struct intel_be_device *dev) -{ - driPoolTakeDown(dev->mallocPool); - driPoolTakeDown(dev->staticPool); - driPoolTakeDown(dev->regionPool); - driPoolTakeDown(dev->vertexPool); - driPoolTakeDown(dev->batchPool); - - /** TODO takedown fenceMgr and fMan */ -} diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h deleted file mode 100644 index 3f8b3f585c..0000000000 --- a/src/gallium/winsys/common/intel_drm/intel_be_device.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef INTEL_DRM_DEVICE_H -#define INTEL_DRM_DEVICE_H - -#include "pipe/p_winsys.h" -#include "pipe/p_context.h" - -/* - * Device - */ - -struct intel_be_device -{ - struct pipe_winsys base; - - /** - * Hw level screen - */ - struct pipe_screen *screen; - - int fd; /**< Drm file discriptor */ - - size_t max_batch_size; - size_t max_vertex_size; - - struct _DriFenceMgr *fenceMgr; - - struct _DriBufferPool *batchPool; - struct _DriBufferPool *regionPool; - struct _DriBufferPool *mallocPool; - struct _DriBufferPool *vertexPool; - struct _DriBufferPool *staticPool; - struct _DriFreeSlabManager *fMan; -}; - -boolean -intel_be_init_device(struct intel_be_device *device, int fd, unsigned id); - -void -intel_be_destroy_device(struct intel_be_device *dev); - -/* - * Buffer - */ - -struct intel_be_buffer { - struct pipe_buffer base; - struct _DriBufferPool *pool; - struct _DriBufferObject *driBO; -}; - -/** - * Create a be buffer from a drm bo handle - * - * Takes a reference - */ -struct pipe_buffer * -intel_be_buffer_from_handle(struct intel_be_device *device, - const char* name, unsigned handle); - -static INLINE struct intel_be_buffer * -intel_be_buffer(struct pipe_buffer *buf) -{ - return (struct intel_be_buffer *)buf; -} - -static INLINE struct _DriBufferObject * -dri_bo(struct pipe_buffer *buf) -{ - return intel_be_buffer(buf)->driBO; -} - -#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c deleted file mode 100644 index b6d901f85e..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.c +++ /dev/null @@ -1,949 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - * Keith Whitwell - */ - -#include -#include -#include -#include "glthread.h" -#include "errno.h" -#include "ws_dri_bufmgr.h" -#include "string.h" -#include "pipe/p_debug.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" - - -/* - * This lock is here to protect drmBO structs changing underneath us during a - * validate list call, since validatelist cannot take individiual locks for - * each drmBO. Validatelist takes this lock in write mode. Any access to an - * individual drmBO should take this lock in read mode, since in that case, the - * driBufferObject mutex will protect the access. Locking order is - * driBufferObject mutex - > this rw lock. - */ - -_glthread_DECLARE_STATIC_MUTEX(bmMutex); -_glthread_DECLARE_STATIC_COND(bmCond); - -static int kernelReaders = 0; -static int num_buffers = 0; -static int num_user_buffers = 0; - -static drmBO *drmBOListBuf(void *iterator) -{ - drmBONode *node; - drmMMListHead *l = (drmMMListHead *) iterator; - node = DRMLISTENTRY(drmBONode, l, head); - return node->buf; -} - -static void *drmBOListIterator(drmBOList *list) -{ - void *ret = list->list.next; - - if (ret == &list->list) - return NULL; - return ret; -} - -static void *drmBOListNext(drmBOList *list, void *iterator) -{ - void *ret; - - drmMMListHead *l = (drmMMListHead *) iterator; - ret = l->next; - if (ret == &list->list) - return NULL; - return ret; -} - -static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, - uint64_t arg0, - uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } - else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADD(&node->head, &list->list); - list->numOnList++; - return node; -} - -static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, - uint64_t mask, int *newItem) -{ - drmBONode *node, *cur; - drmMMListHead *l; - - *newItem = 0; - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - } - if (!cur) { - cur = drmAddListItem(list, buf, flags, mask); - if (!cur) { - return -ENOMEM; - } - *newItem = 1; - cur->arg0 = flags; - cur->arg1 = mask; - } - else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - return 0; -} - -static void drmBOFreeList(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->list.next; - while(l != &list->list) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->list.next; - list->numCurrent--; - list->numOnList--; - } - - l = list->free.next; - while(l != &list->free) { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - l = list->free.next; - list->numCurrent--; - } -} - -static int drmAdjustListNodes(drmBOList *list) -{ - drmBONode *node; - drmMMListHead *l; - int ret = 0; - - while(list->numCurrent < list->numTarget) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - ret = -ENOMEM; - break; - } - list->numCurrent++; - DRMLISTADD(&node->head, &list->free); - } - - while(list->numCurrent > list->numTarget) { - l = list->free.next; - if (l == &list->free) - break; - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - free(node); - list->numCurrent--; - } - return ret; -} - -static int drmBOCreateList(int numTarget, drmBOList *list) -{ - DRMINITLISTHEAD(&list->list); - DRMINITLISTHEAD(&list->free); - list->numTarget = numTarget; - list->numCurrent = 0; - list->numOnList = 0; - return drmAdjustListNodes(list); -} - -static int drmBOResetList(drmBOList *list) -{ - drmMMListHead *l; - int ret; - - ret = drmAdjustListNodes(list); - if (ret) - return ret; - - l = list->list.next; - while (l != &list->list) { - DRMLISTDEL(l); - DRMLISTADD(l, &list->free); - list->numOnList--; - l = list->list.next; - } - return drmAdjustListNodes(list); -} - -void driWriteLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - while(kernelReaders != 0) - _glthread_COND_WAIT(bmCond, bmMutex); -} - -void driWriteUnlockKernelBO(void) -{ - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadLockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - kernelReaders++; - _glthread_UNLOCK_MUTEX(bmMutex); -} - -void driReadUnlockKernelBO(void) -{ - _glthread_LOCK_MUTEX(bmMutex); - if (--kernelReaders == 0) - _glthread_COND_BROADCAST(bmCond); - _glthread_UNLOCK_MUTEX(bmMutex); -} - - - - -/* - * TODO: Introduce fence pools in the same way as - * buffer object pools. - */ - -typedef struct _DriBufferObject -{ - DriBufferPool *pool; - _glthread_Mutex mutex; - int refCount; - const char *name; - uint64_t flags; - unsigned hint; - unsigned alignment; - unsigned createdByReference; - void *private; - /* user-space buffer: */ - unsigned userBuffer; - void *userData; - unsigned userSize; -} DriBufferObject; - -typedef struct _DriBufferList { - drmBOList drmBuffers; /* List of kernel buffers needing validation */ - drmBOList driBuffers; /* List of user-space buffers needing validation */ -} DriBufferList; - - -void -bmError(int val, const char *file, const char *function, int line) -{ - printf("Fatal video memory manager error \"%s\".\n" - "Check kernel logs or set the LIBGL_DEBUG\n" - "environment variable to \"verbose\" for more info.\n" - "Detected in file %s, line %d, function %s.\n", - strerror(-val), file, line, function); -#ifndef NDEBUG - abort(); -#else - abort(); -#endif -} - -extern drmBO * -driBOKernel(struct _DriBufferObject *buf) -{ - drmBO *ret; - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - ret = buf->pool->kernel(buf->pool, buf->private); - if (!ret) - BM_CKFATAL(-EINVAL); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - - return ret; -} - -void -driBOWaitIdle(struct _DriBufferObject *buf, int lazy) -{ - - /* - * This function may block. Is it sane to keep the mutex held during - * that time?? - */ - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void * -driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) -{ - void *virtual; - int retval; - - if (buf->userBuffer) { - return buf->userData; - } - - _glthread_LOCK_MUTEX(buf->mutex); - assert(buf->private != NULL); - retval = buf->pool->map(buf->pool, buf->private, flags, hint, - &buf->mutex, &virtual); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval == 0 ? virtual : NULL; -} - -void -driBOUnmap(struct _DriBufferObject *buf) -{ - if (buf->userBuffer) - return; - - assert(buf->private != NULL); - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -unsigned long -driBOOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->offset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -unsigned long -driBOPoolOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->poolOffset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -uint64_t -driBOFlags(struct _DriBufferObject *buf) -{ - uint64_t ret; - - assert(buf->private != NULL); - - driReadLockKernelBO(); - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->flags(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - driReadUnlockKernelBO(); - return ret; -} - -struct _DriBufferObject * -driBOReference(struct _DriBufferObject *buf) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (++buf->refCount == 1) { - _glthread_UNLOCK_MUTEX(buf->mutex); - BM_CKFATAL(-EINVAL); - } - _glthread_UNLOCK_MUTEX(buf->mutex); - return buf; -} - -void -driBOUnReference(struct _DriBufferObject *buf) -{ - int tmp; - - if (!buf) - return; - - _glthread_LOCK_MUTEX(buf->mutex); - tmp = --buf->refCount; - if (!tmp) { - _glthread_UNLOCK_MUTEX(buf->mutex); - if (buf->private) { - if (buf->createdByReference) - buf->pool->unreference(buf->pool, buf->private); - else - buf->pool->destroy(buf->pool, buf->private); - } - if (buf->userBuffer) - num_user_buffers--; - else - num_buffers--; - free(buf); - } else - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - - -int -driBOData(struct _DriBufferObject *buf, - unsigned size, const void *data, - DriBufferPool *newPool, - uint64_t flags) -{ - void *virtual = NULL; - int newBuffer; - int retval = 0; - struct _DriBufferPool *pool; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - pool = buf->pool; - - if (pool == NULL && newPool != NULL) { - buf->pool = newPool; - pool = newPool; - } - if (newPool == NULL) - newPool = pool; - - if (!pool->create) { - assert((size_t)"driBOData called on invalid buffer\n" & 0); - BM_CKFATAL(-EINVAL); - } - - newBuffer = (!buf->private || pool != newPool || - pool->size(pool, buf->private) < size); - - if (!flags) - flags = buf->flags; - - if (newBuffer) { - - if (buf->createdByReference) { - assert((size_t)"driBOData requiring resizing called on shared buffer.\n" & 0); - BM_CKFATAL(-EINVAL); - } - - if (buf->private) - buf->pool->destroy(buf->pool, buf->private); - - pool = newPool; - buf->pool = newPool; - buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (!buf->private) - retval = -ENOMEM; - - if (retval == 0) - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); - } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { - /* - * Buffer is busy. need to create a new one. - */ - - void *newBuf; - - newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, - buf->alignment); - if (newBuf) { - buf->pool->destroy(buf->pool, buf->private); - buf->private = newBuf; - } - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } else { - uint64_t flag_diff = flags ^ buf->flags; - - /* - * We might need to change buffer flags. - */ - - if (flag_diff){ - assert(pool->setStatus != NULL); - BM_CKFATAL(pool->unmap(pool, buf->private)); - BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, - buf->flags)); - if (!data) - goto out; - - retval = pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); - } - } - - if (retval == 0) { - if (data) - memcpy(virtual, data, size); - - BM_CKFATAL(pool->unmap(pool, buf->private)); - } - - out: - _glthread_UNLOCK_MUTEX(buf->mutex); - - return retval; -} - -void -driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, const void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &buf->mutex, - &virtual)); - memcpy((unsigned char *) virtual + offset, data, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, void *data) -{ - void *virtual; - - assert(!buf->userBuffer); /* XXX just do a memcpy? */ - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); - memcpy(data, (unsigned char *) virtual + offset, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->private != NULL) { - assert((size_t)"Invalid buffer for setReferenced\n" & 0); - BM_CKFATAL(-EINVAL); - - } - if (buf->pool->reference == NULL) { - assert((size_t)"Invalid buffer pool for setReferenced\n" & 0); - BM_CKFATAL(-EINVAL); - } - buf->private = buf->pool->reference(buf->pool, handle); - if (!buf->private) { - assert((size_t)"Invalid buffer pool for setStatic\n" & 0); - BM_CKFATAL(-ENOMEM); - } - buf->createdByReference = TRUE; - buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -int -driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint) -{ - struct _DriBufferObject *buf; - int i; - - flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - - ++num_buffers; - - assert(pool); - - for (i = 0; i < n; ++i) { - buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); - if (!buf) - return -ENOMEM; - - _glthread_INIT_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(buf->mutex); - buf->refCount = 1; - buf->flags = flags; - buf->hint = hint; - buf->name = name; - buf->alignment = alignment; - buf->pool = pool; - buf->createdByReference = 0; - _glthread_UNLOCK_MUTEX(buf->mutex); - buffers[i] = buf; - } - return 0; -} - -void -driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject **buffers, - void *ptr, unsigned bytes) -{ - const unsigned alignment = 1, flags = 0, hint = 0; - - --num_buffers; /* JB: is inced in GenBuffes */ - driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); - ++num_user_buffers; - - (*buffers)->userBuffer = 1; - (*buffers)->userData = ptr; - (*buffers)->userSize = bytes; -} - -void -driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) -{ - int i; - - for (i = 0; i < n; ++i) { - driBOUnReference(buffers[i]); - } -} - - -void -driInitBufMgr(int fd) -{ - ; -} - -/* - * Note that lists are per-context and don't need mutex protection. - */ - -struct _DriBufferList * -driBOCreateList(int target) -{ - struct _DriBufferList *list = calloc(sizeof(*list), 1); - - BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); - BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); - return list; -} - -int -driBOResetList(struct _DriBufferList * list) -{ - int ret; - ret = drmBOResetList(&list->drmBuffers); - if (ret) - return ret; - ret = drmBOResetList(&list->driBuffers); - return ret; -} - -void -driBOFreeList(struct _DriBufferList * list) -{ - drmBOFreeList(&list->drmBuffers); - drmBOFreeList(&list->driBuffers); - free(list); -} - - -/* - * Copied from libdrm, because it is needed by driAddValidateItem. - */ - -static drmBONode * -driAddListItem(drmBOList * list, drmBO * item, - uint64_t arg0, uint64_t arg1) -{ - drmBONode *node; - drmMMListHead *l; - - l = list->free.next; - if (l == &list->free) { - node = (drmBONode *) malloc(sizeof(*node)); - if (!node) { - return NULL; - } - list->numCurrent++; - } else { - DRMLISTDEL(l); - node = DRMLISTENTRY(drmBONode, l, head); - } - memset(&node->bo_arg, 0, sizeof(node->bo_arg)); - node->buf = item; - node->arg0 = arg0; - node->arg1 = arg1; - DRMLISTADDTAIL(&node->head, &list->list); - list->numOnList++; - return node; -} - -/* - * Slightly modified version compared to the libdrm version. - * This one returns the list index of the buffer put on the list. - */ - -static int -driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, - uint64_t mask, int *itemLoc, - struct _drmBONode **pnode) -{ - drmBONode *node, *cur; - drmMMListHead *l; - int count = 0; - - cur = NULL; - - for (l = list->list.next; l != &list->list; l = l->next) { - node = DRMLISTENTRY(drmBONode, l, head); - if (node->buf == buf) { - cur = node; - break; - } - count++; - } - if (!cur) { - cur = driAddListItem(list, buf, flags, mask); - if (!cur) - return -ENOMEM; - - cur->arg0 = flags; - cur->arg1 = mask; - } else { - uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; - uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; - - if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { - return -EINVAL; - } - - cur->arg1 |= mask; - cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); - - if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && - (cur->arg0 & DRM_BO_MASK_MEM) == 0) { - return -EINVAL; - } - } - *itemLoc = count; - *pnode = cur; - return 0; -} - - -void -driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node) -{ - int newItem; - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(driAddValidateItem(&list->drmBuffers, - buf->pool->kernel(buf->pool, buf->private), - flags, mask, itemLoc, node)); - BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, - flags, mask, &newItem)); - if (newItem) - buf->refCount++; - - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -drmBOList *driGetdrmBOList(struct _DriBufferList *list) -{ - driWriteLockKernelBO(); - return &list->drmBuffers; -} - -void driPutdrmBOList(struct _DriBufferList *list) -{ - driWriteUnlockKernelBO(); -} - - -void -driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->fence) - BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); - _glthread_UNLOCK_MUTEX(buf->mutex); - -} - -void -driBOUnrefUserList(struct _DriBufferList *list) -{ - struct _DriBufferObject *buf; - void *curBuf; - - curBuf = drmBOListIterator(&list->driBuffers); - while (curBuf) { - buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - -struct _DriFenceObject * -driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, const char *name, - drmFence *kFence) -{ - struct _DriFenceObject *fence; - struct _DriBufferObject *buf; - void *curBuf; - - fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, - kFence, sizeof(*kFence)); - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space fencing callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - driBOFence(buf, fence); - driBOUnReference(buf); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } - - driBOResetList(list); - return fence; -} - -void -driBOValidateUserList(struct _DriBufferList * list) -{ - void *curBuf; - struct _DriBufferObject *buf; - - curBuf = drmBOListIterator(&list->driBuffers); - - /* - * User-space validation callbacks. - */ - - while (curBuf) { - buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->pool->validate) - BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); - _glthread_UNLOCK_MUTEX(buf->mutex); - curBuf = drmBOListNext(&list->driBuffers, curBuf); - } -} - - -void -driPoolTakeDown(struct _DriBufferPool *pool) -{ - pool->takeDown(pool); - -} - -unsigned long -driBOSize(struct _DriBufferObject *buf) -{ - unsigned long size; - - _glthread_LOCK_MUTEX(buf->mutex); - size = buf->pool->size(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - - return size; - -} - -drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) -{ - return &list->drmBuffers; -} - -drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) -{ - return &list->driBuffers; -} - diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h b/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h deleted file mode 100644 index e6c0cff0a0..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_bufmgr.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - * Keith Whitwell - */ - -#ifndef _PSB_BUFMGR_H_ -#define _PSB_BUFMGR_H_ -#include -#include "i915_drm.h" -#include "ws_dri_fencemgr.h" - -typedef struct _drmBONode -{ - drmMMListHead head; - drmBO *buf; - struct drm_i915_op_arg bo_arg; - uint64_t arg0; - uint64_t arg1; -} drmBONode; - -typedef struct _drmBOList { - unsigned numTarget; - unsigned numCurrent; - unsigned numOnList; - drmMMListHead list; - drmMMListHead free; -} drmBOList; - - -struct _DriFenceObject; -struct _DriBufferObject; -struct _DriBufferPool; -struct _DriBufferList; - -/* - * Return a pointer to the libdrm buffer object this DriBufferObject - * uses. - */ - -extern drmBO *driBOKernel(struct _DriBufferObject *buf); -extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, - unsigned hint); -extern void driBOUnmap(struct _DriBufferObject *buf); -extern unsigned long driBOOffset(struct _DriBufferObject *buf); -extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); - -extern uint64_t driBOFlags(struct _DriBufferObject *buf); -extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); -extern void driBOUnReference(struct _DriBufferObject *buf); - -extern int driBOData(struct _DriBufferObject *r_buf, - unsigned size, const void *data, - struct _DriBufferPool *pool, uint64_t flags); - -extern void driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - const void *data); -extern void driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - void *data); -extern int driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, uint64_t flags, unsigned hint); -extern void driGenUserBuffer(struct _DriBufferPool *pool, - const char *name, - struct _DriBufferObject *buffers[], - void *ptr, unsigned bytes); -extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); -extern void driInitBufMgr(int fd); -extern struct _DriBufferList *driBOCreateList(int target); -extern int driBOResetList(struct _DriBufferList * list); -extern void driBOAddListItem(struct _DriBufferList * list, - struct _DriBufferObject *buf, - uint64_t flags, uint64_t mask, int *itemLoc, - struct _drmBONode **node); - -extern void driBOValidateList(int fd, struct _DriBufferList * list); -extern void driBOFreeList(struct _DriBufferList * list); -extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, - struct _DriBufferList *list, - const char *name, - drmFence *kFence); -extern void driBOUnrefUserList(struct _DriBufferList *list); -extern void driBOValidateUserList(struct _DriBufferList * list); -extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); -extern void driPutdrmBOList(struct _DriBufferList *list); - -extern void driBOFence(struct _DriBufferObject *buf, - struct _DriFenceObject *fence); - -extern void driPoolTakeDown(struct _DriBufferPool *pool); -extern void driBOSetReferenced(struct _DriBufferObject *buf, - unsigned long handle); -unsigned long driBOSize(struct _DriBufferObject *buf); -extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); -extern void driPoolTakeDown(struct _DriBufferPool *pool); - -extern void driReadLockKernelBO(void); -extern void driReadUnlockKernelBO(void); -extern void driWriteLockKernelBO(void); -extern void driWriteUnlockKernelBO(void); - -/* - * For debugging purposes. - */ - -extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); -extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); -#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h b/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h deleted file mode 100644 index bf60798924..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_bufpool.h +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#ifndef _PSB_BUFPOOL_H_ -#define _PSB_BUFPOOL_H_ - -#include -#include -struct _DriFenceObject; - -typedef struct _DriBufferPool -{ - int fd; - int (*map) (struct _DriBufferPool * pool, void *private, - unsigned flags, int hint, _glthread_Mutex *mutex, - void **virtual); - int (*unmap) (struct _DriBufferPool * pool, void *private); - int (*destroy) (struct _DriBufferPool * pool, void *private); - unsigned long (*offset) (struct _DriBufferPool * pool, void *private); - unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); - uint64_t (*flags) (struct _DriBufferPool * pool, void *private); - unsigned long (*size) (struct _DriBufferPool * pool, void *private); - void *(*create) (struct _DriBufferPool * pool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment); - void *(*reference) (struct _DriBufferPool * pool, unsigned handle); - int (*unreference) (struct _DriBufferPool * pool, void *private); - int (*fence) (struct _DriBufferPool * pool, void *private, - struct _DriFenceObject * fence); - drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); - int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); - int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy); - int (*setStatus) (struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags); - void (*takeDown) (struct _DriBufferPool * pool); - void *data; -} DriBufferPool; - -extern void bmError(int val, const char *file, const char *function, - int line); -#define BM_CKFATAL(val) \ - do{ \ - int tstVal = (val); \ - if (tstVal) \ - bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ - } while(0); - - -/* - * Builtin pools. - */ - -/* - * Kernel buffer objects. Size in multiples of page size. Page size aligned. - */ - -extern struct _DriBufferPool *driDRMPoolInit(int fd); -extern struct _DriBufferPool *driMallocPoolInit(void); - -struct _DriFreeSlabManager; -extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan); -extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); -extern struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); - - -#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c deleted file mode 100644 index 40929efa2f..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_drmpool.c +++ /dev/null @@ -1,268 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" -#include "assert.h" - -/* - * Buffer pool implementation using DRM buffer objects as DRI buffer objects. - */ - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - unsigned pageSize = getpagesize(); - - if (!buf) - return NULL; - - if ((alignment > pageSize) && (alignment % pageSize)) { - free(buf); - return NULL; - } - - ret = drmBOCreate(pool->fd, size, alignment / pageSize, - NULL, - flags, hint, buf); - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static void * -pool_reference(struct _DriBufferPool *pool, unsigned handle) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - - if (!buf) - return NULL; - - ret = drmBOReference(pool->fd, handle, buf); - - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unreference(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - driReadLockKernelBO(); - ret = drmBOUnreference(pool->fd, buf); - free(buf); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOMap(pool->fd, buf, flags, hint, virtual); - driReadUnlockKernelBO(); - return ret; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOUnmap(pool->fd, buf); - driReadUnlockKernelBO(); - - return ret; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long offset; - - driReadLockKernelBO(); - assert(buf->flags & DRM_BO_FLAG_NO_MOVE); - offset = buf->offset; - driReadUnlockKernelBO(); - - return buf->offset; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - uint64_t flags; - - driReadLockKernelBO(); - flags = buf->flags; - driReadUnlockKernelBO(); - - return flags; -} - - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - unsigned long size; - - driReadLockKernelBO(); - size = buf->size; - driReadUnlockKernelBO(); - - return buf->size; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - /* - * Noop. The kernel handles all fencing. - */ - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - return (drmBO *) private; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, - int lazy) -{ - drmBO *buf = (drmBO *) private; - int ret; - - driReadLockKernelBO(); - ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); - driReadUnlockKernelBO(); - - return ret; -} - - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - -/*static int -pool_setStatus(struct _DriBufferPool *pool, void *private, - uint64_t flag_diff, uint64_t old_flags) -{ - drmBO *buf = (drmBO *) private; - uint64_t new_flags = old_flags ^ flag_diff; - int ret; - - driReadLockKernelBO(); - ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, - 0, 0, 0); - driReadUnlockKernelBO(); - return ret; -}*/ - -struct _DriBufferPool * -driDRMPoolInit(int fd) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - - if (!pool) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - pool->reference = &pool_reference; - pool->unreference = &pool_unreference; - pool->data = NULL; - return pool; -} diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c deleted file mode 100644 index b56bc269da..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.c +++ /dev/null @@ -1,377 +0,0 @@ -#include "ws_dri_fencemgr.h" -#include "glthread.h" -#include -#include -#include - -/* - * Note: Locking order is - * _DriFenceObject::mutex - * _DriFenceMgr::mutex - */ - -struct _DriFenceMgr { - /* - * Constant members. Need no mutex protection. - */ - struct _DriFenceMgrCreateInfo info; - void *private; - - /* - * These members are protected by this->mutex - */ - _glthread_Mutex mutex; - int refCount; - drmMMListHead *heads; - int num_fences; -}; - -struct _DriFenceObject { - - /* - * These members are constant and need no mutex protection. - */ - struct _DriFenceMgr *mgr; - uint32_t fence_class; - uint32_t fence_type; - - /* - * These members are protected by mgr->mutex. - */ - drmMMListHead head; - int refCount; - - /* - * These members are protected by this->mutex. - */ - _glthread_Mutex mutex; - uint32_t signaled_type; - void *private; -}; - -uint32_t -driFenceType(struct _DriFenceObject *fence) -{ - return fence->fence_type; -} - -struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) -{ - struct _DriFenceMgr *tmp; - uint32_t i; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->refCount = 1; - tmp->info = *info; - tmp->num_fences = 0; - tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); - if (!tmp->heads) - goto out_err; - - for (i=0; iinfo.num_classes; ++i) { - DRMINITLISTHEAD(&tmp->heads[i]); - } - _glthread_UNLOCK_MUTEX(tmp->mutex); - return tmp; - - out_err: - if (tmp) - free(tmp); - return NULL; -} - -static void -driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) -{ - struct _DriFenceMgr *mgr = *pMgr; - - *pMgr = NULL; - if (--mgr->refCount == 0) - free(mgr); - else - _glthread_UNLOCK_MUTEX(mgr->mutex); -} - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr) -{ - _glthread_LOCK_MUTEX((*pMgr)->mutex); - driFenceMgrUnrefUnlock(pMgr); -} - -static void -driFenceUnReferenceLocked(struct _DriFenceObject **pFence) -{ - struct _DriFenceObject *fence = *pFence; - struct _DriFenceMgr *mgr = fence->mgr; - - *pFence = NULL; - if (--fence->refCount == 0) { - DRMLISTDELINIT(&fence->head); - if (fence->private) - mgr->info.unreference(mgr, &fence->private); - --mgr->num_fences; - fence->mgr = NULL; - --mgr->refCount; - free(fence); - - } -} - - -static void -driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, - drmMMListHead *list, - uint32_t fence_class, - uint32_t fence_type) -{ - struct _DriFenceObject *entry; - drmMMListHead *prev; - - while(list != &mgr->heads[fence_class]) { - entry = DRMLISTENTRY(struct _DriFenceObject, list, head); - - /* - * Up refcount so that entry doesn't disappear from under us - * when we unlock-relock mgr to get the correct locking order. - */ - - ++entry->refCount; - _glthread_UNLOCK_MUTEX(mgr->mutex); - _glthread_LOCK_MUTEX(entry->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - - prev = list->prev; - - - - if (list->prev == list) { - - /* - * Somebody else removed the entry from the list. - */ - - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - return; - } - - entry->signaled_type |= (fence_type & entry->fence_type); - if (entry->signaled_type == entry->fence_type) { - DRMLISTDELINIT(list); - mgr->info.unreference(mgr, &entry->private); - } - _glthread_UNLOCK_MUTEX(entry->mutex); - driFenceUnReferenceLocked(&entry); - list = prev; - } -} - - -int -driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint) -{ - struct _DriFenceMgr *mgr = fence->mgr; - int ret = 0; - - _glthread_LOCK_MUTEX(fence->mutex); - - if ((fence->signaled_type & fence_type) == fence_type) - goto out0; - - ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); - if (ret) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - fence_type); - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) -{ - uint32_t ret; - - _glthread_LOCK_MUTEX(fence->mutex); - ret = fence->signaled_type; - _glthread_UNLOCK_MUTEX(fence->mutex); - - return ret; -} - -int -driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, - uint32_t *signaled) -{ - int ret = 0; - struct _DriFenceMgr *mgr; - - _glthread_LOCK_MUTEX(fence->mutex); - mgr = fence->mgr; - *signaled = fence->signaled_type; - if ((fence->signaled_type & flush_type) == flush_type) - goto out0; - - ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); - if (ret) { - *signaled = fence->signaled_type; - goto out0; - } - - if ((fence->signaled_type | *signaled) == fence->signaled_type) - goto out0; - - _glthread_LOCK_MUTEX(mgr->mutex); - _glthread_UNLOCK_MUTEX(fence->mutex); - - driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, - *signaled); - - _glthread_UNLOCK_MUTEX(mgr->mutex); - return 0; - out0: - _glthread_UNLOCK_MUTEX(fence->mutex); - return ret; -} - -struct _DriFenceObject * -driFenceReference(struct _DriFenceObject *fence) -{ - _glthread_LOCK_MUTEX(fence->mgr->mutex); - ++fence->refCount; - _glthread_UNLOCK_MUTEX(fence->mgr->mutex); - return fence; -} - -void -driFenceUnReference(struct _DriFenceObject **pFence) -{ - struct _DriFenceMgr *mgr; - - if (*pFence == NULL) - return; - - mgr = (*pFence)->mgr; - _glthread_LOCK_MUTEX(mgr->mutex); - ++mgr->refCount; - driFenceUnReferenceLocked(pFence); - driFenceMgrUnrefUnlock(&mgr); -} - -struct _DriFenceObject -*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, - uint32_t fence_type, void *private, size_t private_size) -{ - struct _DriFenceObject *fence; - size_t fence_size = sizeof(*fence); - - if (private_size) - fence_size = ((fence_size + 15) & ~15); - - fence = calloc(1, fence_size + private_size); - - if (!fence) { - int ret = mgr->info.finish(mgr, private, fence_type, 0); - - if (ret) - usleep(10000000); - - return NULL; - } - - _glthread_INIT_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(fence->mutex); - _glthread_LOCK_MUTEX(mgr->mutex); - fence->refCount = 1; - DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); - fence->mgr = mgr; - ++mgr->refCount; - ++mgr->num_fences; - _glthread_UNLOCK_MUTEX(mgr->mutex); - fence->fence_class = fence_class; - fence->fence_type = fence_type; - fence->signaled_type = 0; - fence->private = private; - if (private_size) { - fence->private = (void *)(((uint8_t *) fence) + fence_size); - memcpy(fence->private, private, private_size); - } - - _glthread_UNLOCK_MUTEX(fence->mutex); - return fence; -} - - -static int -tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type) -{ - long fd = (long) mgr->private; - int dummy; - drmFence *fence = (drmFence *) private; - int ret; - - *signaled_type = 0; - ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); - if (ret) - return ret; - - *signaled_type = fence->signaled; - - return 0; -} - -static int -tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, - int lazy_hint) -{ - long fd = (long) mgr->private; - unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; - - return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); -} - -static int -tUnref(struct _DriFenceMgr *mgr, void **private) -{ - long fd = (long) mgr->private; - drmFence *fence = (drmFence *) *private; - *private = NULL; - - return drmFenceUnreference(fd, fence); -} - -struct _DriFenceMgr *driFenceMgrTTMInit(int fd) -{ - struct _DriFenceMgrCreateInfo info; - struct _DriFenceMgr *mgr; - - info.flags = DRI_FENCE_CLASS_ORDERED; - info.num_classes = 4; - info.signaled = tSignaled; - info.finish = tFinish; - info.unreference = tUnref; - - mgr = driFenceMgrCreate(&info); - if (mgr == NULL) - return NULL; - - mgr->private = (void *) (long) fd; - return mgr; -} - diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h b/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h deleted file mode 100644 index 4ea58dfe18..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_fencemgr.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef DRI_FENCEMGR_H -#define DRI_FENCEMGR_H - -#include -#include - -struct _DriFenceObject; -struct _DriFenceMgr; - -/* - * Do a quick check to see if the fence manager has registered the fence - * object as signaled. Note that this function may return a false negative - * answer. - */ -extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); - -/* - * Check if the fence object is signaled. This function can be substantially - * more expensive to call than the above function, but will not return a false - * negative answer. The argument "flush_type" sets the types that the - * underlying mechanism must make sure will eventually signal. - */ -extern int driFenceSignaledType(struct _DriFenceObject *fence, - uint32_t flush_type, uint32_t *signaled); - -/* - * Convenience functions. - */ - -static inline int driFenceSignaled(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types; - int ret = driFenceSignaledType(fence, flush_type, &signaled_types); - if (ret) - return 0; - return ((signaled_types & flush_type) == flush_type); -} - -static inline int driFenceSignaledCached(struct _DriFenceObject *fence, - uint32_t flush_type) -{ - uint32_t signaled_types = - driFenceSignaledTypeCached(fence); - - return ((signaled_types & flush_type) == flush_type); -} - -/* - * Reference a fence object. - */ -extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); - -/* - * Unreference a fence object. The fence object pointer will be reset to NULL. - */ - -extern void driFenceUnReference(struct _DriFenceObject **pFence); - - -/* - * Wait for a fence to signal the indicated fence_type. - * If "lazy_hint" is true, it indicates that the wait may sleep to avoid - * busy-wait polling. - */ -extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, - int lazy_hint); - -/* - * Create a DriFenceObject for manager "mgr". - * - * "private" is a pointer that should be used for the callbacks in - * struct _DriFenceMgrCreateInfo. - * - * if private_size is nonzero, then the info stored at *private, with size - * private size will be copied and the fence manager will instead use a - * pointer to the copied data for the callbacks in - * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by - * "private" may be destroyed after the call to driFenceCreate. - */ -extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, - uint32_t fence_class, - uint32_t fence_type, - void *private, - size_t private_size); - -extern uint32_t driFenceType(struct _DriFenceObject *fence); - -/* - * Fence creations are ordered. If a fence signals a fence_type, - * it is safe to assume that all fences of the same class that was - * created before that fence has signaled the same type. - */ - -#define DRI_FENCE_CLASS_ORDERED (1 << 0) - -struct _DriFenceMgrCreateInfo { - uint32_t flags; - uint32_t num_classes; - int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, - uint32_t *signaled_type); - int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); - int (*unreference) (struct _DriFenceMgr *mgr, void **private); -}; - -extern struct _DriFenceMgr * -driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); - -void -driFenceMgrUnReference(struct _DriFenceMgr **pMgr); - -extern struct _DriFenceMgr * -driFenceMgrTTMInit(int fd); - -#endif diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c deleted file mode 100644 index a80555c9c7..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_mallocpool.c +++ /dev/null @@ -1,161 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include -#include -#include "pipe/p_debug.h" -#include "glthread.h" -#include "ws_dri_bufpool.h" -#include "ws_dri_bufmgr.h" - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, uint64_t flags, unsigned hint, - unsigned alignment) -{ - unsigned long *private = malloc(size + 2*sizeof(unsigned long)); - if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) - abort(); - - *private = size; - return (void *)private; -} - - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - free(private); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - *virtual = (void *)((unsigned long *)private + 2); - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); - return 0UL; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - /* - * BUG - */ - abort(); -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - return *(unsigned long *) private; -} - - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - abort(); - return 0UL; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - abort(); - return NULL; -} - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - - -struct _DriBufferPool * -driMallocPoolInit(void) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - if (!pool) - return NULL; - - pool->data = NULL; - pool->fd = -1; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->poolOffset = &pool_poolOffset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - return pool; -} diff --git a/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c b/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c deleted file mode 100644 index dfcf6d6b19..0000000000 --- a/src/gallium/winsys/common/intel_drm/ws_dri_slabpool.c +++ /dev/null @@ -1,968 +0,0 @@ -/************************************************************************** - * - * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellstrom - */ - -#include -#include -#include -#include -#include -#include "ws_dri_bufpool.h" -#include "ws_dri_fencemgr.h" -#include "ws_dri_bufmgr.h" -#include "glthread.h" - -#define DRI_SLABPOOL_ALLOC_RETRIES 100 - -struct _DriSlab; - -struct _DriSlabBuffer { - int isSlabBuffer; - drmBO *bo; - struct _DriFenceObject *fence; - struct _DriSlab *parent; - drmMMListHead head; - uint32_t mapCount; - uint32_t start; - uint32_t fenceType; - int unFenced; - _glthread_Cond event; -}; - -struct _DriKernelBO { - int fd; - drmBO bo; - drmMMListHead timeoutHead; - drmMMListHead head; - struct timeval timeFreed; - uint32_t pageAlignment; - void *virtual; -}; - -struct _DriSlab{ - drmMMListHead head; - drmMMListHead freeBuffers; - uint32_t numBuffers; - uint32_t numFree; - struct _DriSlabBuffer *buffers; - struct _DriSlabSizeHeader *header; - struct _DriKernelBO *kbo; -}; - - -struct _DriSlabSizeHeader { - drmMMListHead slabs; - drmMMListHead freeSlabs; - drmMMListHead delayedBuffers; - uint32_t numDelayed; - struct _DriSlabPool *slabPool; - uint32_t bufSize; - _glthread_Mutex mutex; -}; - -struct _DriFreeSlabManager { - struct timeval slabTimeout; - struct timeval checkInterval; - struct timeval nextCheck; - drmMMListHead timeoutList; - drmMMListHead unCached; - drmMMListHead cached; - _glthread_Mutex mutex; -}; - - -struct _DriSlabPool { - - /* - * The data of this structure remains constant after - * initialization and thus needs no mutex protection. - */ - - struct _DriFreeSlabManager *fMan; - uint64_t proposedFlags; - uint64_t validMask; - uint32_t *bucketSizes; - uint32_t numBuckets; - uint32_t pageSize; - int fd; - int pageAlignment; - int maxSlabSize; - int desiredNumBuffers; - struct _DriSlabSizeHeader *headers; -}; - -/* - * FIXME: Perhaps arrange timeout slabs in size buckets for fast - * retreival?? - */ - - -static inline int -driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) -{ - return ((arg1->tv_sec > arg2->tv_sec) || - ((arg1->tv_sec == arg2->tv_sec) && - (arg1->tv_usec > arg2->tv_usec))); -} - -static inline void -driTimeAdd(struct timeval *arg, struct timeval *add) -{ - unsigned int sec; - - arg->tv_sec += add->tv_sec; - arg->tv_usec += add->tv_usec; - sec = arg->tv_usec / 1000000; - arg->tv_sec += sec; - arg->tv_usec -= sec*1000000; -} - -static void -driFreeKernelBO(struct _DriKernelBO *kbo) -{ - if (!kbo) - return; - - (void) drmBOUnreference(kbo->fd, &kbo->bo); - free(kbo); -} - - -static void -driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, - struct timeval *time) -{ - drmMMListHead *list, *next; - struct _DriKernelBO *kbo; - - if (!driTimeAfterEq(time, &fMan->nextCheck)) - return; - - for (list = fMan->timeoutList.next, next = list->next; - list != &fMan->timeoutList; - list = next, next = list->next) { - - kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); - - if (!driTimeAfterEq(time, &kbo->timeFreed)) - break; - - DRMLISTDELINIT(&kbo->timeoutHead); - DRMLISTDELINIT(&kbo->head); - driFreeKernelBO(kbo); - } - - fMan->nextCheck = *time; - driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); -} - - -/* - * Add a _DriKernelBO to the free slab manager. - * This means that it is available for reuse, but if it's not - * reused in a while, it will be freed. - */ - -static void -driSetKernelBOFree(struct _DriFreeSlabManager *fMan, - struct _DriKernelBO *kbo) -{ - struct timeval time; - - _glthread_LOCK_MUTEX(fMan->mutex); - gettimeofday(&time, NULL); - driTimeAdd(&time, &fMan->slabTimeout); - - kbo->timeFreed = time; - - if (kbo->bo.flags & DRM_BO_FLAG_CACHED) - DRMLISTADD(&kbo->head, &fMan->cached); - else - DRMLISTADD(&kbo->head, &fMan->unCached); - - DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); - driFreeTimeoutKBOsLocked(fMan, &time); - - _glthread_UNLOCK_MUTEX(fMan->mutex); -} - -/* - * Get a _DriKernelBO for us to use as storage for a slab. - * - */ - -static struct _DriKernelBO * -driAllocKernelBO(struct _DriSlabSizeHeader *header) - -{ - struct _DriSlabPool *slabPool = header->slabPool; - struct _DriFreeSlabManager *fMan = slabPool->fMan; - drmMMListHead *list, *next, *head; - uint32_t size = header->bufSize * slabPool->desiredNumBuffers; - struct _DriKernelBO *kbo; - struct _DriKernelBO *kboTmp; - int ret; - - /* - * FIXME: We should perhaps allow some variation in slabsize in order - * to efficiently reuse slabs. - */ - - size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; - size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); - _glthread_LOCK_MUTEX(fMan->mutex); - - kbo = NULL; - - retry: - head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? - &fMan->cached : &fMan->unCached; - - for (list = head->next, next = list->next; - list != head; - list = next, next = list->next) { - - kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); - - if ((kboTmp->bo.size == size) && - (slabPool->pageAlignment == 0 || - (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { - - if (!kbo) - kbo = kboTmp; - - if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) - break; - - } - } - - if (kbo) { - DRMLISTDELINIT(&kbo->head); - DRMLISTDELINIT(&kbo->timeoutHead); - } - - _glthread_UNLOCK_MUTEX(fMan->mutex); - - if (kbo) { - uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; - - ret = 0; - if (new_mask) { - ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, - new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); - } - if (ret == 0) - return kbo; - - driFreeKernelBO(kbo); - kbo = NULL; - goto retry; - } - - kbo = calloc(1, sizeof(struct _DriKernelBO)); - if (!kbo) - return NULL; - - kbo->fd = slabPool->fd; - DRMINITLISTHEAD(&kbo->head); - DRMINITLISTHEAD(&kbo->timeoutHead); - ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, - slabPool->proposedFlags, - DRM_BO_HINT_DONT_FENCE, &kbo->bo); - if (ret) - goto out_err0; - - ret = drmBOMap(kbo->fd, &kbo->bo, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &kbo->virtual); - - if (ret) - goto out_err1; - - ret = drmBOUnmap(kbo->fd, &kbo->bo); - if (ret) - goto out_err1; - - return kbo; - - out_err1: - drmBOUnreference(kbo->fd, &kbo->bo); - out_err0: - free(kbo); - return NULL; -} - - -static int -driAllocSlab(struct _DriSlabSizeHeader *header) -{ - struct _DriSlab *slab; - struct _DriSlabBuffer *buf; - uint32_t numBuffers; - int ret; - int i; - - slab = calloc(1, sizeof(*slab)); - if (!slab) - return -ENOMEM; - - slab->kbo = driAllocKernelBO(header); - if (!slab->kbo) { - ret = -ENOMEM; - goto out_err0; - } - - numBuffers = slab->kbo->bo.size / header->bufSize; - - slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); - if (!slab->buffers) { - ret = -ENOMEM; - goto out_err1; - } - - DRMINITLISTHEAD(&slab->head); - DRMINITLISTHEAD(&slab->freeBuffers); - slab->numBuffers = numBuffers; - slab->numFree = 0; - slab->header = header; - - buf = slab->buffers; - for (i=0; i < numBuffers; ++i) { - buf->parent = slab; - buf->start = i* header->bufSize; - buf->mapCount = 0; - buf->isSlabBuffer = 1; - _glthread_INIT_COND(buf->event); - DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); - slab->numFree++; - buf++; - } - - DRMLISTADDTAIL(&slab->head, &header->slabs); - - return 0; - - out_err1: - driSetKernelBOFree(header->slabPool->fMan, slab->kbo); - free(slab->buffers); - out_err0: - free(slab); - return ret; -} - -/* - * Delete a buffer from the slab header delayed list and put - * it on the slab free list. - */ - -static void -driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) -{ - struct _DriSlab *slab = buf->parent; - struct _DriSlabSizeHeader *header = slab->header; - drmMMListHead *list = &buf->head; - - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &slab->freeBuffers); - slab->numFree++; - - if (slab->head.next == &slab->head) - DRMLISTADDTAIL(&slab->head, &header->slabs); - - if (slab->numFree == slab->numBuffers) { - list = &slab->head; - DRMLISTDEL(list); - DRMLISTADDTAIL(list, &header->freeSlabs); - } - - if (header->slabs.next == &header->slabs || - slab->numFree != slab->numBuffers) { - - drmMMListHead *next; - struct _DriFreeSlabManager *fMan = header->slabPool->fMan; - - for (list = header->freeSlabs.next, next = list->next; - list != &header->freeSlabs; - list = next, next = list->next) { - - slab = DRMLISTENTRY(struct _DriSlab, list, head); - - DRMLISTDELINIT(list); - driSetKernelBOFree(fMan, slab->kbo); - free(slab->buffers); - free(slab); - } - } -} - -static void -driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) -{ - drmMMListHead *list, *prev, *first; - struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - int firstWasSignaled = 1; - int signaled; - int i; - int ret; - - /* - * Rerun the freeing test if the youngest tested buffer - * was signaled, since there might be more idle buffers - * in the delay list. - */ - - while (firstWasSignaled) { - firstWasSignaled = 0; - signaled = 0; - first = header->delayedBuffers.next; - - /* Only examine the oldest 1/3 of delayed buffers: - */ - if (header->numDelayed > 3) { - for (i = 0; i < header->numDelayed; i += 3) { - first = first->next; - } - } - - for (list = first, prev = list->prev; - list != &header->delayedBuffers; - list = prev, prev = list->prev) { - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - slab = buf->parent; - - if (!signaled) { - if (wait) { - ret = driFenceFinish(buf->fence, buf->fenceType, 0); - if (ret) - break; - signaled = 1; - wait = 0; - } else { - signaled = driFenceSignaled(buf->fence, buf->fenceType); - } - if (signaled) { - if (list == first) - firstWasSignaled = 1; - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { - driFenceUnReference(&buf->fence); - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - } - } -} - - -static struct _DriSlabBuffer * -driSlabAllocBuffer(struct _DriSlabSizeHeader *header) -{ - static struct _DriSlabBuffer *buf; - struct _DriSlab *slab; - drmMMListHead *list; - int count = DRI_SLABPOOL_ALLOC_RETRIES; - - _glthread_LOCK_MUTEX(header->mutex); - while(header->slabs.next == &header->slabs && count > 0) { - driSlabCheckFreeLocked(header, 0); - if (header->slabs.next != &header->slabs) - break; - - _glthread_UNLOCK_MUTEX(header->mutex); - if (count != DRI_SLABPOOL_ALLOC_RETRIES) - usleep(1); - _glthread_LOCK_MUTEX(header->mutex); - (void) driAllocSlab(header); - count--; - } - - list = header->slabs.next; - if (list == &header->slabs) { - _glthread_UNLOCK_MUTEX(header->mutex); - return NULL; - } - slab = DRMLISTENTRY(struct _DriSlab, list, head); - if (--slab->numFree == 0) - DRMLISTDELINIT(list); - - list = slab->freeBuffers.next; - DRMLISTDELINIT(list); - - _glthread_UNLOCK_MUTEX(header->mutex); - buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); - return buf; -} - -static void * -pool_create(struct _DriBufferPool *driPool, unsigned long size, - uint64_t flags, unsigned hint, unsigned alignment) -{ - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - struct _DriSlabSizeHeader *header; - struct _DriSlabBuffer *buf; - void *dummy; - int i; - int ret; - - /* - * FIXME: Check for compatibility. - */ - - header = pool->headers; - for (i=0; inumBuckets; ++i) { - if (header->bufSize >= size) - break; - header++; - } - - if (i < pool->numBuckets) - return driSlabAllocBuffer(header); - - - /* - * Fall back to allocate a buffer object directly from DRM. - * and wrap it in a driBO structure. - */ - - - buf = calloc(1, sizeof(*buf)); - - if (!buf) - return NULL; - - buf->bo = calloc(1, sizeof(*buf->bo)); - if (!buf->bo) - goto out_err0; - - if (alignment) { - if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) - goto out_err1; - if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) - goto out_err1; - } - - ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, - flags, hint, buf->bo); - if (ret) - goto out_err1; - - ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0, &dummy); - if (ret) - goto out_err2; - - ret = drmBOUnmap(pool->fd, buf->bo); - if (ret) - goto out_err2; - - return buf; - out_err2: - drmBOUnreference(pool->fd, buf->bo); - out_err1: - free(buf->bo); - out_err0: - free(buf); - return NULL; -} - -static int -pool_destroy(struct _DriBufferPool *driPool, void *private) -{ - struct _DriSlabBuffer *buf = - (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; - int ret; - - ret = drmBOUnreference(pool->fd, buf->bo); - free(buf->bo); - free(buf); - return ret; - } - - slab = buf->parent; - header = slab->header; - - _glthread_LOCK_MUTEX(header->mutex); - buf->unFenced = 0; - buf->mapCount = 0; - - if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { - DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); - header->numDelayed++; - } else { - if (buf->fence) - driFenceUnReference(&buf->fence); - driSlabFreeBufferLocked(buf); - } - - _glthread_UNLOCK_MUTEX(header->mutex); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *driPool, void *private, - _glthread_Mutex *mutex, int lazy) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - while(buf->unFenced) - _glthread_COND_WAIT(buf->event, *mutex); - - if (!buf->fence) - return 0; - - driFenceFinish(buf->fence, buf->fenceType, lazy); - driFenceUnReference(&buf->fence); - - return 0; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, _glthread_Mutex *mutex, void **virtual) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - int busy; - - if (buf->isSlabBuffer) - busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); - else - busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); - - - if (busy) { - if (hint & DRM_BO_HINT_DONT_BLOCK) - return -EBUSY; - else { - (void) pool_waitIdle(pool, private, mutex, 0); - } - } - - ++buf->mapCount; - *virtual = (buf->isSlabBuffer) ? - (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : - (void *) buf->bo->virtual; - - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - --buf->mapCount; - if (buf->mapCount == 0 && buf->isSlabBuffer) - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - struct _DriSlab *slab; - struct _DriSlabSizeHeader *header; - - if (!buf->isSlabBuffer) { - assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return buf->bo->offset; - } - - slab = buf->parent; - header = slab->header; - - (void) header; - assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); - return slab->kbo->bo.offset + buf->start; -} - -static unsigned long -pool_poolOffset(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - return buf->start; -} - -static uint64_t -pool_flags(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return buf->bo->flags; - - return buf->parent->kbo->bo.flags; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - if (!buf->isSlabBuffer) - return buf->bo->size; - - return buf->parent->header->bufSize; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - drmBO *bo; - - if (buf->fence) - driFenceUnReference(&buf->fence); - - buf->fence = driFenceReference(fence); - bo = (buf->isSlabBuffer) ? - &buf->parent->kbo->bo: - buf->bo; - buf->fenceType = bo->fenceFlags; - - buf->unFenced = 0; - _glthread_COND_BROADCAST(buf->event); - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; -} - -static int -pool_validate(struct _DriBufferPool *pool, void *private, - _glthread_Mutex *mutex) -{ - struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; - - if (!buf->isSlabBuffer) - return 0; - - while(buf->mapCount != 0) - _glthread_COND_WAIT(buf->event, *mutex); - - buf->unFenced = 1; - return 0; -} - - -struct _DriFreeSlabManager * -driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) -{ - struct _DriFreeSlabManager *tmp; - - tmp = calloc(1, sizeof(*tmp)); - if (!tmp) - return NULL; - - _glthread_INIT_MUTEX(tmp->mutex); - _glthread_LOCK_MUTEX(tmp->mutex); - tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; - tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; - tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; - - tmp->checkInterval.tv_usec = checkIntervalMsec*1000; - tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; - tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; - - gettimeofday(&tmp->nextCheck, NULL); - driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); - DRMINITLISTHEAD(&tmp->timeoutList); - DRMINITLISTHEAD(&tmp->unCached); - DRMINITLISTHEAD(&tmp->cached); - _glthread_UNLOCK_MUTEX(tmp->mutex); - - return tmp; -} - -void -driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) -{ - struct timeval time; - - time = fMan->nextCheck; - driTimeAdd(&time, &fMan->checkInterval); - - _glthread_LOCK_MUTEX(fMan->mutex); - driFreeTimeoutKBOsLocked(fMan, &time); - _glthread_UNLOCK_MUTEX(fMan->mutex); - - assert(fMan->timeoutList.next == &fMan->timeoutList); - assert(fMan->unCached.next == &fMan->unCached); - assert(fMan->cached.next == &fMan->cached); - - free(fMan); -} - -static void -driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, - struct _DriSlabSizeHeader *header) -{ - _glthread_INIT_MUTEX(header->mutex); - _glthread_LOCK_MUTEX(header->mutex); - - DRMINITLISTHEAD(&header->slabs); - DRMINITLISTHEAD(&header->freeSlabs); - DRMINITLISTHEAD(&header->delayedBuffers); - - header->numDelayed = 0; - header->slabPool = pool; - header->bufSize = size; - - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -driFinishSizeHeader(struct _DriSlabSizeHeader *header) -{ - drmMMListHead *list, *next; - struct _DriSlabBuffer *buf; - - _glthread_LOCK_MUTEX(header->mutex); - for (list = header->delayedBuffers.next, next = list->next; - list != &header->delayedBuffers; - list = next, next = list->next) { - - buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); - if (buf->fence) { - (void) driFenceFinish(buf->fence, buf->fenceType, 0); - driFenceUnReference(&buf->fence); - } - header->numDelayed--; - driSlabFreeBufferLocked(buf); - } - _glthread_UNLOCK_MUTEX(header->mutex); -} - -static void -pool_takedown(struct _DriBufferPool *driPool) -{ - struct _DriSlabPool *pool = driPool->data; - int i; - - for (i=0; inumBuckets; ++i) { - driFinishSizeHeader(&pool->headers[i]); - } - - free(pool->headers); - free(pool->bucketSizes); - free(pool); - free(driPool); -} - -struct _DriBufferPool * -driSlabPoolInit(int fd, uint64_t flags, - uint64_t validMask, - uint32_t smallestSize, - uint32_t numSizes, - uint32_t desiredNumBuffers, - uint32_t maxSlabSize, - uint32_t pageAlignment, - struct _DriFreeSlabManager *fMan) -{ - struct _DriBufferPool *driPool; - struct _DriSlabPool *pool; - uint32_t i; - - driPool = calloc(1, sizeof(*driPool)); - if (!driPool) - return NULL; - - pool = calloc(1, sizeof(*pool)); - if (!pool) - goto out_err0; - - pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); - if (!pool->bucketSizes) - goto out_err1; - - pool->headers = calloc(numSizes, sizeof(*pool->headers)); - if (!pool->headers) - goto out_err2; - - pool->fMan = fMan; - pool->proposedFlags = flags; - pool->validMask = validMask; - pool->numBuckets = numSizes; - pool->pageSize = getpagesize(); - pool->fd = fd; - pool->pageAlignment = pageAlignment; - pool->maxSlabSize = maxSlabSize; - pool->desiredNumBuffers = desiredNumBuffers; - - for (i=0; inumBuckets; ++i) { - pool->bucketSizes[i] = (smallestSize << i); - driInitSizeHeader(pool, pool->bucketSizes[i], - &pool->headers[i]); - } - - driPool->data = (void *) pool; - driPool->map = &pool_map; - driPool->unmap = &pool_unmap; - driPool->destroy = &pool_destroy; - driPool->offset = &pool_offset; - driPool->poolOffset = &pool_poolOffset; - driPool->flags = &pool_flags; - driPool->size = &pool_size; - driPool->create = &pool_create; - driPool->fence = &pool_fence; - driPool->kernel = &pool_kernel; - driPool->validate = &pool_validate; - driPool->waitIdle = &pool_waitIdle; - driPool->takeDown = &pool_takedown; - - return driPool; - - out_err2: - free(pool->bucketSizes); - out_err1: - free(pool); - out_err0: - free(driPool); - - return NULL; -} diff --git a/src/gallium/winsys/dri/Makefile b/src/gallium/winsys/dri/Makefile deleted file mode 100644 index f466ce6c3c..0000000000 --- a/src/gallium/winsys/dri/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# src/mesa/drivers/dri/Makefile - -TOP = ../../../.. - -include $(TOP)/configs/current - - - -default: $(TOP)/$(LIB_DIR) subdirs - - -$(TOP)/$(LIB_DIR): - -mkdir $(TOP)/$(LIB_DIR) - - -subdirs: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE)) || exit 1 ; \ - fi \ - done - - -install: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE) install) || exit 1 ; \ - fi \ - done - - -clean: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE) clean) ; \ - fi \ - done - -rm -f common/*.o diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template deleted file mode 100644 index 80e817b808..0000000000 --- a/src/gallium/winsys/dri/Makefile.template +++ /dev/null @@ -1,125 +0,0 @@ -# -*-makefile-*- - -MESA_MODULES = \ - $(TOP)/src/mesa/libmesa.a \ - $(GALLIUM_AUXILIARIES) - -COMMON_GALLIUM_SOURCES = \ - $(TOP)/src/mesa/drivers/dri/common/utils.c \ - $(TOP)/src/mesa/drivers/dri/common/vblank.c \ - $(TOP)/src/mesa/drivers/dri/common/dri_util.c \ - $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c - -COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ - $(TOP)/src/mesa/drivers/common/driverfuncs.c \ - $(TOP)/src/mesa/drivers/dri/common/texmem.c \ - $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c - -COMMON_BM_SOURCES = \ - $(TOP)/src/mesa/drivers/dri/common/dri_bufmgr.c \ - $(TOP)/src/mesa/drivers/dri/common/dri_drmpool.c - - -ifeq ($(WINDOW_SYSTEM),dri) -WINOBJ= -WINLIB= -INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) - -OBJECTS = \ - $(C_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) - -else -# miniglx -WINOBJ= -WINLIB=-L$(MESA)/src/glx/mini -MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini -INCLUDES = $(MINIGLX_INCLUDES) \ - $(SHARED_INCLUDES) \ - $(PCIACCESS_CFLAGS) - -OBJECTS = $(C_SOURCES:.c=.o) \ - $(MINIGLX_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) -endif - - -### Include directories -SHARED_INCLUDES = \ - -I. \ - -I$(TOP)/src/mesa/drivers/dri/common \ - -Iserver \ - -I$(TOP)/include \ - -I$(TOP)/include/GL/internal \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/gallium/winsys/common \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/main \ - -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/mesa/math \ - -I$(TOP)/src/mesa/transform \ - -I$(TOP)/src/mesa/shader \ - -I$(TOP)/src/mesa/swrast \ - -I$(TOP)/src/mesa/swrast_setup \ - -I$(TOP)/src/egl/main \ - -I$(TOP)/src/egl/drivers/dri \ - $(LIBDRM_CFLAGS) - - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - - -##### TARGETS ##### - -default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR)/$(LIBNAME_EGL) - - -$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template - $(TOP)/bin/mklib -noprefix -o $@ \ - $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) - -$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS) - $(TOP)/bin/mklib -o $(LIBNAME_EGL) \ - -linker "$(CC)" \ - -noprefix \ - $(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \ - --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive - -$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) - $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) - -$(TOP)/$(LIB_DIR)/$(LIBNAME_EGL): $(LIBNAME_EGL) - $(INSTALL) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR) - -depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ - $(ASM_SOURCES) 2> /dev/null - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` `find ../include` - - -# Remove .o and backup files -clean: - -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) - -rm -f depend depend.bak - - -install: $(LIBNAME) - $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) - $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) - - -include depend diff --git a/src/gallium/winsys/dri/SConscript b/src/gallium/winsys/dri/SConscript deleted file mode 100644 index aef5210a32..0000000000 --- a/src/gallium/winsys/dri/SConscript +++ /dev/null @@ -1,54 +0,0 @@ -Import('*') - -if env['dri']: - - drienv = env.Clone() - - drienv.Replace(CPPPATH = [ - '#src/mesa/drivers/dri/common', - '#include', - '#include/GL/internal', - '#src/gallium/include', - '#src/gallium/auxiliary', - '#src/gallium/drivers', - '#src/mesa', - '#src/mesa/main', - '#src/mesa/glapi', - '#src/mesa/math', - '#src/mesa/transform', - '#src/mesa/shader', - '#src/mesa/swrast', - '#src/mesa/swrast_setup', - '#src/egl/main', - '#src/egl/drivers/dri', - ]) - - drienv.ParseConfig('pkg-config --cflags --libs libdrm') - - COMMON_GALLIUM_SOURCES = [ - '#src/mesa/drivers/dri/common/utils.c', - '#src/mesa/drivers/dri/common/vblank.c', - '#src/mesa/drivers/dri/common/dri_util.c', - '#src/mesa/drivers/dri/common/xmlconfig.c', - ] - - COMMON_BM_SOURCES = [ - '#src/mesa/drivers/dri/common/dri_bufmgr.c', - '#src/mesa/drivers/dri/common/dri_drmpool.c', - ] - - Export([ - 'drienv', - 'COMMON_GALLIUM_SOURCES', - 'COMMON_BM_SOURCES', - ]) - - # TODO: Installation - #install: $(LIBNAME) - # $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) - # $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) - - if 'intel' in env['winsys']: - SConscript([ - 'intel/SConscript', - ]) diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile deleted file mode 100644 index e0716ea28e..0000000000 --- a/src/gallium/winsys/dri/intel/Makefile +++ /dev/null @@ -1,34 +0,0 @@ - -TOP = ../../../../.. -include $(TOP)/configs/current - -LIBNAME = i915_dri.so -LIBNAME_EGL = egl_i915_dri.so - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a - - -DRIVER_SOURCES = \ - intel_winsys_softpipe.c \ - intel_swapbuffers.c \ - intel_context.c \ - intel_lock.c \ - intel_screen.c - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - -DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ - && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") - -include ../Makefile.template - -#intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c - -symlinks: diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript deleted file mode 100644 index 6a4f50afcc..0000000000 --- a/src/gallium/winsys/dri/intel/SConscript +++ /dev/null @@ -1,41 +0,0 @@ -Import('*') - -if 'mesa' in env['statetrackers']: - - env = drienv.Clone() - - env.Append(CPPPATH = [ - '../intel', - 'server' - ]) - - #MINIGLX_SOURCES = server/intel_dri.c - - DRIVER_SOURCES = [ - 'intel_winsys_pipe.c', - 'intel_winsys_softpipe.c', - 'intel_winsys_i915.c', - 'intel_batchbuffer.c', - 'intel_swapbuffers.c', - 'intel_context.c', - 'intel_lock.c', - 'intel_screen.c', - 'intel_batchpool.c', - ] - - sources = \ - COMMON_GALLIUM_SOURCES + \ - COMMON_BM_SOURCES + \ - DRIVER_SOURCES - - drivers = [ - softpipe, - i915simple - ] - - # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions - env.SharedLibrary( - target ='i915tex_dri.so', - source = sources, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], - ) diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h deleted file mode 100644 index 1fa2719845..0000000000 --- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef INTEL_BATCHBUFFER_H -#define INTEL_BATCHBUFFER_H - -#include "intel_drm/intel_be_batchbuffer.h" - -/* - * Need to redefine the BATCH defines - */ - -#undef BEGIN_BATCH -#define BEGIN_BATCH(dwords, relocs) \ - (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) - -#undef OUT_BATCH -#define OUT_BATCH(d) \ - i915_batchbuffer_dword(&intel->base.batch->base, d) - -#undef OUT_RELOC -#define OUT_RELOC(buf,flags,mask,delta) do { \ - assert((delta) >= 0); \ - intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ -} while (0) - -#endif diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c deleted file mode 100644 index 97ef731aaa..0000000000 --- a/src/gallium/winsys/dri/intel/intel_context.c +++ /dev/null @@ -1,337 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "i830_dri.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_swapbuffers.h" -#include "intel_batchbuffer.h" -#include "intel_winsys_softpipe.h" - -#include "i915simple/i915_screen.h" - -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_context.h" - -#include "utils.h" - - -#ifdef DEBUG -int __intel_debug = 0; -#endif - - -#define need_GL_ARB_multisample -#define need_GL_ARB_point_parameters -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_buffer_object -#define need_GL_ARB_vertex_program -#define need_GL_ARB_window_pos -#define need_GL_EXT_blend_color -#define need_GL_EXT_blend_equation_separate -#define need_GL_EXT_blend_func_separate -#define need_GL_EXT_blend_minmax -#define need_GL_EXT_cull_vertex -#define need_GL_EXT_fog_coord -#define need_GL_EXT_framebuffer_object -#define need_GL_EXT_multi_draw_arrays -#define need_GL_EXT_secondary_color -#define need_GL_NV_vertex_program -#include "extension_helper.h" - - -/** - * Extension strings exported by the intel driver. - * - * \note - * It appears that ARB_texture_env_crossbar has "disappeared" compared to the - * old i830-specific driver. - */ -const struct dri_extension card_extensions[] = { - {"GL_ARB_multisample", GL_ARB_multisample_functions}, - {"GL_ARB_multitexture", NULL}, - {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, - {"GL_ARB_texture_border_clamp", NULL}, - {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, - {"GL_ARB_texture_cube_map", NULL}, - {"GL_ARB_texture_env_add", NULL}, - {"GL_ARB_texture_env_combine", NULL}, - {"GL_ARB_texture_env_dot3", NULL}, - {"GL_ARB_texture_mirrored_repeat", NULL}, - {"GL_ARB_texture_rectangle", NULL}, - {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, - {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, - {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, - {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, - {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, - {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, - {"GL_EXT_blend_subtract", NULL}, - {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, - {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, - {"GL_EXT_packed_depth_stencil", NULL}, - {"GL_EXT_pixel_buffer_object", NULL}, - {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, - {"GL_EXT_stencil_wrap", NULL}, - {"GL_EXT_texture_edge_clamp", NULL}, - {"GL_EXT_texture_env_combine", NULL}, - {"GL_EXT_texture_env_dot3", NULL}, - {"GL_EXT_texture_filter_anisotropic", NULL}, - {"GL_EXT_texture_lod_bias", NULL}, - {"GL_3DFX_texture_compression_FXT1", NULL}, - {"GL_APPLE_client_storage", NULL}, - {"GL_MESA_pack_invert", NULL}, - {"GL_MESA_ycbcr_texture", NULL}, - {"GL_NV_blend_square", NULL}, - {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, - {"GL_NV_vertex_program1_1", NULL}, - {"GL_SGIS_generate_mipmap", NULL }, - {NULL, NULL} -}; - - - -#ifdef DEBUG -static const struct dri_debug_control debug_control[] = { - {"ioctl", DEBUG_IOCTL}, - {"bat", DEBUG_BATCH}, - {"lock", DEBUG_LOCK}, - {"swap", DEBUG_SWAP}, - {NULL, 0} -}; -#endif - - - -static void -intel_lock_hardware(struct intel_be_context *context) -{ - struct intel_context *intel = (struct intel_context *)context; - LOCK_HARDWARE(intel); -} - -static void -intel_unlock_hardware(struct intel_be_context *context) -{ - struct intel_context *intel = (struct intel_context *)context; - UNLOCK_HARDWARE(intel); -} - -static boolean -intel_locked_hardware(struct intel_be_context *context) -{ - struct intel_context *intel = (struct intel_context *)context; - return intel->locked ? TRUE : FALSE; -} - -GLboolean -intelCreateContext(const __GLcontextModes * visual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate) -{ - struct intel_context *intel = CALLOC_STRUCT(intel_context); - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - struct intel_screen *intelScreen = intel_screen(sPriv); - drmI830Sarea *saPriv = intelScreen->sarea; - int fthrottle_mode; - GLboolean havePools; - struct pipe_context *pipe; - struct st_context *st_share = NULL; - - if (sharedContextPrivate) { - st_share = ((struct intel_context *) sharedContextPrivate)->st; - } - - driContextPriv->driverPrivate = intel; - intel->intelScreen = intelScreen; - intel->driScreen = sPriv; - intel->sarea = saPriv; - - driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, - intel->driScreen->myNum, "i915"); - - - /* - * memory pools - */ - DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); - // ZZZ JB should be per screen and not be done per context - havePools = intelCreatePools(sPriv); - DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); - if (!havePools) - return GL_FALSE; - - - /* Dri stuff */ - intel->hHWContext = driContextPriv->hHWContext; - intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; - - fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); - intel->iw.irq_seq = -1; - intel->irqsEmitted = 0; - - intel->last_swap_fence = NULL; - intel->first_swap_fence = NULL; - -#ifdef DEBUG - __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); -#endif - intel->base.hardware_lock = intel_lock_hardware; - intel->base.hardware_unlock = intel_unlock_hardware; - intel->base.hardware_locked = intel_locked_hardware; - - intel_be_init_context(&intel->base, &intelScreen->base); - - /* - * Pipe-related setup - */ - if (getenv("INTEL_SP")) { - /* use softpipe driver instead of hw */ - pipe = intel_create_softpipe( intel, &intelScreen->base.base ); - } - else { - switch (intel->intelScreen->deviceID) { - case PCI_CHIP_I945_G: - case PCI_CHIP_I945_GM: - case PCI_CHIP_I945_GME: - case PCI_CHIP_G33_G: - case PCI_CHIP_Q33_G: - case PCI_CHIP_Q35_G: - case PCI_CHIP_I915_G: - case PCI_CHIP_I915_GM: - pipe = i915_create_context(intelScreen->base.screen, - &intelScreen->base.base, - &intel->base.base); - break; - default: - fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", - intel->intelScreen->deviceID, __FUNCTION__); - - pipe = intel_create_softpipe( intel, &intelScreen->base.base ); - break; - } - } - - pipe->priv = intel; - - intel->st = st_create_context(pipe, visual, st_share); - - driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); - - return GL_TRUE; -} - - -void -intelDestroyContext(__DRIcontextPrivate * driContextPriv) -{ - struct intel_context *intel = intel_context(driContextPriv); - - assert(intel); /* should never be null */ - if (intel) { - st_finish(intel->st); - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - if (intel->first_swap_fence) { - driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = NULL; - } - - if (intel->intelScreen->dummyContext == intel) - intel->intelScreen->dummyContext = NULL; - - st_destroy_context(intel->st); - intel_be_destroy_context(&intel->base); - free(intel); - } -} - - -GLboolean -intelUnbindContext(__DRIcontextPrivate * driContextPriv) -{ - struct intel_context *intel = intel_context(driContextPriv); - st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); - /* XXX make_current(NULL)? */ - return GL_TRUE; -} - - -GLboolean -intelMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv) -{ - if (driContextPriv) { - struct intel_context *intel = intel_context(driContextPriv); - struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv); - struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv); - - assert(draw_fb->stfb); - assert(read_fb->stfb); - - /* This is for situations in which we need a rendering context but - * there may not be any currently bound. - */ - intel->intelScreen->dummyContext = intel; - - st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); - - if ((intel->driDrawable != driDrawPriv) || - (intel->lastStamp != driDrawPriv->lastStamp)) { - intel->driDrawable = driDrawPriv; - intelUpdateWindowSize(driDrawPriv); - intel->lastStamp = driDrawPriv->lastStamp; - } - - /* The size of the draw buffer will have been updated above. - * If the readbuffer is a different window, check/update its size now. - */ - if (driReadPriv != driDrawPriv) { - intelUpdateWindowSize(driReadPriv); - } - - } - else { - st_make_current(NULL, NULL, NULL); - } - - return GL_TRUE; -} diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h deleted file mode 100644 index ced18da143..0000000000 --- a/src/gallium/winsys/dri/intel/intel_context.h +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_CONTEXT_H -#define INTEL_CONTEXT_H - -#include -#include "drm.h" - -#include "pipe/p_debug.h" - -#include "intel_screen.h" -#include "i915_drm.h" - -#include "intel_drm/intel_be_context.h" - - -struct pipe_context; -struct intel_context; -struct _DriBufferObject; -struct st_context; - - -#define INTEL_MAX_FIXUP 64 - -/** - * Intel rendering context, contains a state tracker and intel-specific info. - */ -struct intel_context -{ - struct intel_be_context base; - struct st_context *st; - - struct _DriFenceObject *last_swap_fence; - struct _DriFenceObject *first_swap_fence; - -// struct intel_batchbuffer *batch; - - boolean locked; - char *prevLockFile; - int prevLockLine; - - uint irqsEmitted; - drm_i915_irq_wait_t iw; - - drm_context_t hHWContext; - drmLock *driHwLock; - int driFd; - - __DRIdrawablePrivate *driDrawable; - __DRIscreenPrivate *driScreen; - struct intel_screen *intelScreen; - drmI830Sarea *sarea; - - uint lastStamp; - - /** - * Configuration cache - */ - driOptionCache optionCache; -}; - - - -/** - * Intel framebuffer. - */ -struct intel_framebuffer -{ - struct st_framebuffer *stfb; - - /* other fields TBD */ - int other; -}; - - - - -/* These are functions now: - */ -void LOCK_HARDWARE( struct intel_context *intel ); -void UNLOCK_HARDWARE( struct intel_context *intel ); - -extern char *__progname; - - - -/* ================================================================ - * Debugging: - */ -#ifdef DEBUG -extern int __intel_debug; - -#define DEBUG_SWAP 0x1 -#define DEBUG_LOCK 0x2 -#define DEBUG_IOCTL 0x4 -#define DEBUG_BATCH 0x8 - -#define DBG(flag, ...) do { \ - if (__intel_debug & (DEBUG_##flag)) \ - printf(__VA_ARGS__); \ -} while(0) - -#else -#define DBG(flag, ...) -#endif - - - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GME 0x27AE -#define PCI_CHIP_G33_G 0x29C2 -#define PCI_CHIP_Q35_G 0x29B2 -#define PCI_CHIP_Q33_G 0x29D2 - - -/** Cast wrapper */ -static INLINE struct intel_context * -intel_context(__DRIcontextPrivate *driContextPriv) -{ - return (struct intel_context *) driContextPriv->driverPrivate; -} - - -/** Cast wrapper */ -static INLINE struct intel_framebuffer * -intel_framebuffer(__DRIdrawablePrivate * driDrawPriv) -{ - return (struct intel_framebuffer *) driDrawPriv->driverPrivate; -} - - -#endif diff --git a/src/gallium/winsys/dri/intel/intel_lock.c b/src/gallium/winsys/dri/intel/intel_lock.c deleted file mode 100644 index 406284c98f..0000000000 --- a/src/gallium/winsys/dri/intel/intel_lock.c +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "main/glheader.h" -#include "glapi/glthread.h" -#include -#include "state_tracker/st_public.h" -#include "intel_context.h" -#include "i830_dri.h" - - - -_glthread_DECLARE_STATIC_MUTEX( lockMutex ); - - -static void -intelContendedLock(struct intel_context *intel, uint flags) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - __DRIscreenPrivate *sPriv = intel->driScreen; - struct intel_screen *intelScreen = intel_screen(sPriv); - drmI830Sarea *sarea = intel->sarea; - - drmGetLock(intel->driFd, intel->hHWContext, flags); - - DBG(LOCK, "%s - got contended lock\n", __progname); - - /* If the window moved, may need to set a new cliprect now. - * - * NOTE: This releases and regains the hw lock, so all state - * checking must be done *after* this call: - */ - if (dPriv) - DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); - - if (sarea->width != intelScreen->front.width || - sarea->height != intelScreen->front.height) { - - intelUpdateScreenRotation(sPriv, sarea); - } -} - - -/* Lock the hardware and validate our state. - */ -void LOCK_HARDWARE( struct intel_context *intel ) -{ - char __ret = 0; - - _glthread_LOCK_MUTEX(lockMutex); - assert(!intel->locked); - - DRM_CAS(intel->driHwLock, intel->hHWContext, - (DRM_LOCK_HELD|intel->hHWContext), __ret); - - if (__ret) - intelContendedLock( intel, 0 ); - - DBG(LOCK, "%s - locked\n", __progname); - - intel->locked = 1; -} - - -/* Unlock the hardware using the global current context - */ -void UNLOCK_HARDWARE( struct intel_context *intel ) -{ - assert(intel->locked); - intel->locked = 0; - - DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); - - _glthread_UNLOCK_MUTEX(lockMutex); - - DBG(LOCK, "%s - unlocked\n", __progname); -} diff --git a/src/gallium/winsys/dri/intel/intel_reg.h b/src/gallium/winsys/dri/intel/intel_reg.h deleted file mode 100644 index 4f33bee438..0000000000 --- a/src/gallium/winsys/dri/intel/intel_reg.h +++ /dev/null @@ -1,53 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef _INTEL_REG_H_ -#define _INTEL_REG_H_ - - -#define BR00_BITBLT_CLIENT 0x40000000 -#define BR00_OP_COLOR_BLT 0x10000000 -#define BR00_OP_SRC_COPY_BLT 0x10C00000 -#define BR13_SOLID_PATTERN 0x80000000 - -#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) -#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) -#define XY_COLOR_BLT_WRITE_RGB (1<<20) - -#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) -#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) -#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) - -#define MI_WAIT_FOR_EVENT ((0x3<<23)) -#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) - -#define MI_BATCH_BUFFER_END (0xA<<23) - - -#endif diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c deleted file mode 100644 index b3022fd17a..0000000000 --- a/src/gallium/winsys/dri/intel/intel_screen.c +++ /dev/null @@ -1,607 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "utils.h" -#include "vblank.h" -#include "xmlpool.h" - -#include "intel_context.h" -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_swapbuffers.h" - -#include "i830_dri.h" -#include "intel_drm/ws_dri_bufpool.h" - -#include "pipe/p_context.h" -#include "pipe/p_screen.h" -#include "pipe/p_inlines.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_cb_fbo.h" - -static void -intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle); - -static void -intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle) -{ - struct pipe_screen *screen = intelScreen->base.screen; - struct pipe_texture *texture; - struct pipe_texture templat; - struct pipe_surface *surface; - struct pipe_buffer *buffer; - unsigned pitch; - - assert(intelScreen->front.cpp == 4); - - buffer = intel_be_buffer_from_handle(&intelScreen->base, - "front", handle); - - if (!buffer) - return; - - intelScreen->front.buffer = dri_bo(buffer); - - memset(&templat, 0, sizeof(templat)); - templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; - templat.target = PIPE_TEXTURE_2D; - templat.last_level = 0; - templat.depth[0] = 1; - templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; - templat.width[0] = intelScreen->front.width; - templat.height[0] = intelScreen->front.height; - pf_get_block(templat.format, &templat.block); - pitch = intelScreen->front.pitch; - - texture = screen->texture_blanket(screen, - &templat, - &pitch, - buffer); - - /* Unref the buffer we don't need it anyways */ - pipe_buffer_reference(screen->winsys, &buffer, NULL); - - surface = screen->get_tex_surface(screen, - texture, - 0, - 0, - 0, - PIPE_BUFFER_USAGE_GPU_WRITE); - - intelScreen->front.texture = texture; - intelScreen->front.surface = surface; -} - -PUBLIC const char __driConfigOptions[] = - DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE - DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) - DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) - DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY -// DRI_CONF_FORCE_S3TC_ENABLE(false) - DRI_CONF_ALLOW_LARGE_TEXTURES(1) - DRI_CONF_SECTION_END DRI_CONF_END; - -const uint __driNConfigOptions = 3; - -#ifdef USE_NEW_INTERFACE -static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; -#endif /*USE_NEW_INTERFACE */ - -extern const struct dri_extension card_extensions[]; - - - - -static void -intelPrintDRIInfo(struct intel_screen * intelScreen, - __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) -{ - fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->front.size, intelScreen->front.offset, - intelScreen->front.pitch); - fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); -} - - -#if 0 -static void -intelPrintSAREA(const drmI830Sarea * sarea) -{ - fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, - sarea->height); - fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); - fprintf(stderr, - "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->front_offset, sarea->front_size, - (unsigned) sarea->front_handle); - fprintf(stderr, - "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->back_offset, sarea->back_size, - (unsigned) sarea->back_handle); - fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->depth_offset, sarea->depth_size, - (unsigned) sarea->depth_handle); - fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); - fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); - fprintf(stderr, - "SAREA: rotated offset: 0x%08x size: 0x%x\n", - sarea->rotated_offset, sarea->rotated_size); - fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); -} -#endif - - -/** - * Use the information in the sarea to update the screen parameters - * related to screen rotation. Needs to be called locked. - */ -void -intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) -{ - struct intel_screen *intelScreen = intel_screen(sPriv); - - if (intelScreen->front.map) { - drmUnmap(intelScreen->front.map, intelScreen->front.size); - intelScreen->front.map = NULL; - } - - if (intelScreen->front.buffer) - driDeleteBuffers(1, &intelScreen->front.buffer); - - intelScreen->front.width = sarea->width; - intelScreen->front.height = sarea->height; - intelScreen->front.offset = sarea->front_offset; - intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp; - intelScreen->front.size = sarea->front_size; - intelScreen->front.handle = sarea->front_handle; - - assert( sarea->front_size >= - intelScreen->front.pitch * intelScreen->front.height ); - -#if 0 /* JB not important */ - if (!sarea->front_handle) - return; - - if (drmMap(sPriv->fd, - sarea->front_handle, - intelScreen->front.size, - (drmAddress *) & intelScreen->front.map) != 0) { - fprintf(stderr, "drmMap(frontbuffer) failed!\n"); - return; - } -#endif - -#if 0 /* JB */ - if (intelScreen->staticPool) { - driGenBuffers(intelScreen->staticPool, "static region", 1, - &intelScreen->front.buffer, 64, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - - driBOSetStatic(intelScreen->front.buffer, - intelScreen->front.offset, - intelScreen->front.pitch * intelScreen->front.height, - intelScreen->front.map, 0); - } -#else - if (intelScreen->base.staticPool) { - if (intelScreen->front.buffer) { - driBOUnReference(intelScreen->front.buffer); - pipe_surface_reference(&intelScreen->front.surface, NULL); - pipe_texture_reference(&intelScreen->front.texture, NULL); - } - intelCreateSurface(intelScreen, &intelScreen->base.base, sarea->front_bo_handle); - } -#endif -} - - -boolean -intelCreatePools(__DRIscreenPrivate * sPriv) -{ - //unsigned batchPoolSize = 1024*1024; - struct intel_screen *intelScreen = intel_screen(sPriv); - - if (intelScreen->havePools) - return GL_TRUE; - - intelScreen->havePools = GL_TRUE; - - intelUpdateScreenRotation(sPriv, intelScreen->sarea); - - return GL_TRUE; -} - -static const char * -intel_get_name( struct pipe_winsys *winsys ) -{ - return "Intel/DRI/ttm"; -} - -/* - * The state tracker (should!) keep track of whether the fake - * frontbuffer has been touched by any rendering since the last time - * we copied its contents to the real frontbuffer. Our task is easy: - */ -static void -intel_flush_frontbuffer( struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ - struct intel_context *intel = (struct intel_context *) context_private; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - intelDisplaySurface(dPriv, surf, NULL); -} - -static boolean -intelInitDriver(__DRIscreenPrivate * sPriv) -{ - struct intel_screen *intelScreen; - I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; - - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> - getProcAddress("glxEnableExtension")); - void *const psc = sPriv->psc->screenConfigs; - - if (sPriv->devPrivSize != sizeof(I830DRIRec)) { - fprintf(stderr, - "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); - return GL_FALSE; - } - - /* Allocate the private area */ - intelScreen = CALLOC_STRUCT(intel_screen); - if (!intelScreen) - return GL_FALSE; - - /* parse information in __driConfigOptions */ - driParseOptionInfo(&intelScreen->optionCache, - __driConfigOptions, __driNConfigOptions); - - sPriv->private = (void *) intelScreen; - - intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + - gDRIPriv->sarea_priv_offset); - intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->front.cpp = gDRIPriv->cpp; - intelScreen->drmMinor = sPriv->drmMinor; - - assert(gDRIPriv->bitsPerPixel == 16 || - gDRIPriv->bitsPerPixel == 32); - - intelUpdateScreenRotation(sPriv, intelScreen->sarea); - - if (0) - intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - - if (glx_enable_extension != NULL) { - (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); - (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); - (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); - } - - intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; - intelScreen->base.base.get_name = intel_get_name; - intel_be_init_device(&intelScreen->base, sPriv->fd, intelScreen->deviceID); - - return GL_TRUE; -} - - -static void -intelDestroyScreen(__DRIscreenPrivate * sPriv) -{ - struct intel_screen *intelScreen = intel_screen(sPriv); - - intel_be_destroy_device(&intelScreen->base); - /* intelUnmapScreenRegions(intelScreen); */ - - FREE(intelScreen); - sPriv->private = NULL; -} - - -/** - * This is called when we need to set up GL rendering to a new X window. - */ -static boolean -intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, - __DRIdrawablePrivate * driDrawPriv, - const __GLcontextModes * visual, boolean isPixmap) -{ - if (isPixmap) { - return GL_FALSE; /* not implemented */ - } - else { - enum pipe_format colorFormat, depthFormat, stencilFormat; - struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); - - if (!intelfb) - return GL_FALSE; - - if (visual->redBits == 5) - colorFormat = PIPE_FORMAT_R5G6B5_UNORM; - else - colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; - - if (visual->depthBits == 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits == 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_NONE; - - if (visual->stencilBits == 8) - stencilFormat = PIPE_FORMAT_S8Z24_UNORM; - else - stencilFormat = PIPE_FORMAT_NONE; - - intelfb->stfb = st_create_framebuffer(visual, - colorFormat, - depthFormat, - stencilFormat, - driDrawPriv->w, - driDrawPriv->h, - (void*) intelfb); - if (!intelfb->stfb) { - free(intelfb); - return GL_FALSE; - } - - driDrawPriv->driverPrivate = (void *) intelfb; - return GL_TRUE; - } -} - -static void -intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) -{ - struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv); - assert(intelfb->stfb); - st_unreference_framebuffer(&intelfb->stfb); - free(intelfb); -} - - -/** - * Get information about previous buffer swaps. - */ -static int -intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) -{ - if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) - || (sInfo == NULL)) { - return -1; - } - - return 0; -} - - -static void -intelSetTexOffset(__DRIcontext *pDRICtx, int texname, - unsigned long long offset, int depth, uint pitch) -{ - abort(); -#if 0 - struct intel_context *intel = (struct intel_context*) - ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; - struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); - struct st_texture_object *stObj = st_texture_object(tObj); - - if (!stObj) - return; - - if (stObj->pt) - st->pipe->texture_release(intel->st->pipe, &stObj->pt); - - stObj->imageOverride = GL_TRUE; - stObj->depthOverride = depth; - stObj->pitchOverride = pitch; - - if (offset) - stObj->textureOffset = offset; -#endif -} - - -static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetMSC = driGetMSC32, - .WaitForMSC = driWaitForMSC32, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = intelCopySubBuffer, - .setTexOffset = intelSetTexOffset, -}; - - -static __GLcontextModes * -intelFillInModes(unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, boolean have_back_buffer) -{ - __GLcontextModes *modes; - __GLcontextModes *m; - unsigned num_modes; - unsigned depth_buffer_factor; - unsigned back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML - }; - - uint8_t depth_bits_array[3]; - uint8_t stencil_bits_array[3]; - uint8_t msaa_samples_array[1]; - - - depth_bits_array[0] = 0; - depth_bits_array[1] = depth_bits; - depth_bits_array[2] = depth_bits; - msaa_samples_array[0] = 0; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = 0; - if (depth_bits == 24) - stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; - - stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; - - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; - back_buffer_factor = (have_back_buffer) ? 3 : 1; - - num_modes = depth_buffer_factor * back_buffer_factor * 4; - - if (pixel_bits == 16) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } - else { - fb_format = GL_BGRA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - modes = - (*dri_interface->createContextModes) (num_modes, - sizeof(__GLcontextModes)); - m = modes; - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, msaa_samples_array, 1, GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, msaa_samples_array, 1, GLX_DIRECT_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for (m = modes; m != NULL; m = m->next) { - if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { - m->visualRating = GLX_SLOW_CONFIG; - } - } - - return modes; -} - - -/** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. - * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. - */ -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, - __DRIscreen * psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) -{ - __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 7, 0 }; - static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 7, 0 }; - - dri_interface = interface; - - if (!driCheckDriDdxDrmVersions2("i915", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { - return NULL; - } - - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - - if (psp != NULL) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes(dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); - - /* Calling driInitExtensions here, with a NULL context pointer, - * does not actually enable the extensions. It just makes sure - * that all the dispatch offsets for all the extensions that - * *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create - * is called, but we can't enable the extensions until we have a - * context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions(NULL, card_extensions, GL_FALSE); - } - - return (void *) psp; -} - diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h deleted file mode 100644 index e62f9e71ec..0000000000 --- a/src/gallium/winsys/dri/intel/intel_screen.h +++ /dev/null @@ -1,122 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef _INTEL_SCREEN_H_ -#define _INTEL_SCREEN_H_ - -#include "dri_util.h" -#include "i830_common.h" -#include "xmlconfig.h" -#include "intel_drm/ws_dri_bufpool.h" - -#include "pipe/p_compiler.h" - -#include "intel_drm/intel_be_device.h" - -struct intel_screen -{ - struct intel_be_device base; - - struct { - drm_handle_t handle; - - /* We create a static dri buffer for the frontbuffer. - */ - struct _DriBufferObject *buffer; - struct pipe_surface *surface; - struct pipe_texture *texture; - - char *map; /* memory map */ - int offset; /* from start of video mem, in bytes */ - int pitch; /* row stride, in bytes */ - int width; - int height; - int size; - int cpp; /* for front and back buffers */ - } front; - - int deviceID; - int drmMinor; - - drmI830Sarea *sarea; - - /** - * Configuration cache with default values for all contexts - */ - driOptionCache optionCache; - - boolean havePools; - - /** - * Temporary(?) context to use for SwapBuffers or other situations in - * which we need a rendering context, but none is currently bound. - */ - struct intel_context *dummyContext; - - /* - * New stuff form the i915tex integration - */ - unsigned batch_id; - - - struct pipe_winsys *winsys; -}; - - - -/** cast wrapper */ -static INLINE struct intel_screen * -intel_screen(__DRIscreenPrivate *sPriv) -{ - return (struct intel_screen *) sPriv->private; -} - - -extern void -intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); - - -extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); - -extern boolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); - -extern boolean -intelMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv); - - -extern boolean -intelCreatePools(__DRIscreenPrivate *sPriv); - -extern boolean -intelCreateContext(const __GLcontextModes * visual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - - -#endif diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c deleted file mode 100644 index f751f97524..0000000000 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c +++ /dev/null @@ -1,261 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_swapbuffers.h" - -#include "intel_reg.h" - -#include "pipe/p_context.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "state_tracker/st_cb_fbo.h" - -#include "intel_drm/ws_dri_bufmgr.h" -#include "intel_batchbuffer.h" - -/** - * Display a colorbuffer surface in an X window. - * Used for SwapBuffers and flushing front buffer rendering. - * - * \param dPriv the window/drawable to display into - * \param surf the surface to display - * \param rect optional subrect of surface to display (may be NULL). - */ -void -intelDisplaySurface(__DRIdrawablePrivate *dPriv, - struct pipe_surface *surf, - const drm_clip_rect_t *rect) -{ - struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); - struct intel_context *intel = intelScreen->dummyContext; - - DBG(SWAP, "%s\n", __FUNCTION__); - - if (!intel) { - /* XXX this is where some kind of extra/meta context could be useful */ - return; - } - - if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); - driFenceUnReference(&intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - intel->last_swap_fence = intel->first_swap_fence; - intel->first_swap_fence = NULL; - - /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets - * should work regardless. - */ - LOCK_HARDWARE(intel); - /* if this drawable isn't currently bound the LOCK_HARDWARE done on the - * current context (which is what intelScreenContext should return) might - * not get a contended lock and thus cliprects not updated (tests/manywin) - */ - if (intel_context(dPriv->driContextPriv) != intel) - DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); - - - if (dPriv && dPriv->numClipRects) { - const int srcWidth = surf->width; - const int srcHeight = surf->height; - const int nbox = dPriv->numClipRects; - const drm_clip_rect_t *pbox = dPriv->pClipRects; - const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; - const int cpp = intelScreen->front.cpp; - const int srcpitch = surf->stride / cpp; - int BR13, CMD; - int i; - - ASSERT(surf->buffer); - ASSERT(surf->cpp == cpp); - - DBG(SWAP, "screen pitch %d src surface pitch %d\n", - pitch, surf->stride); - - if (cpp == 2) { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); - CMD = XY_SRC_COPY_BLT_CMD; - } - else { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - } - - for (i = 0; i < nbox; i++, pbox++) { - drm_clip_rect_t box; - drm_clip_rect_t sbox; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->front.width || - pbox->y2 > intelScreen->front.height) { - /* invalid cliprect, skip it */ - continue; - } - - box = *pbox; - - if (rect) { - /* intersect cliprect with user-provided src rect */ - drm_clip_rect_t rrect; - - rrect.x1 = dPriv->x + rect->x1; - rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; - rrect.x2 = rect->x2 + rrect.x1; - rrect.y2 = rect->y2 + rrect.y1; - if (rrect.x1 > box.x1) - box.x1 = rrect.x1; - if (rrect.y1 > box.y1) - box.y1 = rrect.y1; - if (rrect.x2 < box.x2) - box.x2 = rrect.x2; - if (rrect.y2 < box.y2) - box.y2 = rrect.y2; - - if (box.x1 > box.x2 || box.y1 > box.y2) - continue; - } - - /* restrict blit to size of actually rendered area */ - if (box.x2 - box.x1 > srcWidth) - box.x2 = srcWidth + box.x1; - if (box.y2 - box.y1 > srcHeight) - box.y2 = srcHeight + box.y1; - - DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", - box.x1, box.x2, box.y1, box.y2); - - sbox.x1 = box.x1 - dPriv->x; - sbox.y1 = box.y1 - dPriv->y; - - assert(box.x1 < box.x2); - assert(box.y1 < box.y2); - - /* XXX this could be done with pipe->surface_copy() */ - /* XXX should have its own batch buffer */ - if (!BEGIN_BATCH(8, 2)) { - /* - * Since we share this batch buffer with a context - * we can't flush it since that risks a GPU lockup - */ - assert(0); - continue; - } - - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((box.y1 << 16) | box.x1); - OUT_BATCH((box.y2 << 16) | box.x2); - - OUT_RELOC(intelScreen->front.buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); - OUT_BATCH((sbox.y1 << 16) | sbox.x1); - OUT_BATCH((srcpitch * cpp) & 0xffff); - OUT_RELOC(dri_bo(surf->buffer), - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - - } - - if (intel->first_swap_fence) - driFenceUnReference(&intel->first_swap_fence); - intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); - } - - UNLOCK_HARDWARE(intel); - - if (intel->lastStamp != dPriv->lastStamp) { - intelUpdateWindowSize(dPriv); - intel->lastStamp = dPriv->lastStamp; - } -} - - - -/** - * This will be called whenever the currently bound window is moved/resized. - */ -void -intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) -{ - struct intel_framebuffer *intelfb = intel_framebuffer(dPriv); - assert(intelfb->stfb); - st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); -} - - - -void -intelSwapBuffers(__DRIdrawablePrivate * dPriv) -{ - struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; - - assert(intel_fb); - assert(intel_fb->stfb); - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { - st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, NULL); - st_notify_swapbuffers_complete(intel_fb->stfb); - } -} - - -/** - * Called via glXCopySubBufferMESA() to copy a subrect of the back - * buffer to the front buffer/screen. - */ -void -intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) -{ - struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); - struct pipe_surface *back_surf; - - assert(intel_fb); - assert(intel_fb->stfb); - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, - ST_SURFACE_BACK_LEFT); - if (back_surf) { - drm_clip_rect_t rect; - rect.x1 = x; - rect.y1 = y; - rect.x2 = w; - rect.y2 = h; - - st_notify_swapbuffers(intel_fb->stfb); - intelDisplaySurface(dPriv, back_surf, &rect); - } -} diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.h b/src/gallium/winsys/dri/intel/intel_swapbuffers.h deleted file mode 100644 index 46c9bab3af..0000000000 --- a/src/gallium/winsys/dri/intel/intel_swapbuffers.h +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_SWAPBUFFERS_H -#define INTEL_SWAPBUFFERS_H - - -struct pipe_surface; - - -extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, - struct pipe_surface *surf, - const drm_clip_rect_t * rect); - -extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); - -extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, - int x, int y, int w, int h); - -extern void intelUpdateWindowSize(__DRIdrawablePrivate *dPriv); - - -#endif /* INTEL_SWAPBUFFERS_H */ diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c deleted file mode 100644 index 0d98d16cf1..0000000000 --- a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.c +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Keith Whitwell - */ - -#include "intel_context.h" -#include "intel_winsys_softpipe.h" -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "pipe/p_format.h" -#include "softpipe/sp_winsys.h" - - -struct intel_softpipe_winsys { - struct softpipe_winsys sws; - struct intel_context *intel; -}; - -/** - * Return list of surface formats supported by this driver. - */ -static boolean -intel_is_format_supported(struct softpipe_winsys *sws, - enum pipe_format format) -{ - switch(format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_S8Z24_UNORM: - return TRUE; - default: - return FALSE; - } -} - - -/** - * Create rendering context which uses software rendering. - */ -struct pipe_context * -intel_create_softpipe( struct intel_context *intel, - struct pipe_winsys *winsys ) -{ - struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); - struct pipe_screen *screen = softpipe_create_screen(winsys); - - /* Fill in this struct with callbacks that softpipe will need to - * communicate with the window system, buffer manager, etc. - */ - isws->sws.is_format_supported = intel_is_format_supported; - isws->intel = intel; - - /* Create the softpipe context: - */ - return softpipe_create( screen, winsys, &isws->sws ); -} diff --git a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h b/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h deleted file mode 100644 index 5fa14cb749..0000000000 --- a/src/gallium/winsys/dri/intel/intel_winsys_softpipe.h +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_SOFTPIPE_H -#define INTEL_SOFTPIPE_H - -struct pipe_winsys; -struct pipe_context; -struct intel_context; - -struct pipe_context * -intel_create_softpipe( struct intel_context *intel, - struct pipe_winsys *winsys ); - -#endif diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h deleted file mode 100644 index 3452ddb3c9..0000000000 --- a/src/gallium/winsys/dri/intel/server/i830_common.h +++ /dev/null @@ -1,255 +0,0 @@ -/************************************************************************** - -Copyright 2001 VA Linux Systems Inc., Fremont, California. -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -on the rights to use, copy, modify, merge, publish, distribute, sub -license, and/or sell copies of the Software, and to permit persons to whom -the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - - -#ifndef _I830_COMMON_H_ -#define _I830_COMMON_H_ - - -#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ -#define I830_LOG_MIN_TEX_REGION_SIZE 14 - - -/* Driver specific DRM command indices - * NOTE: these are not OS specific, but they are driver specific - */ -#define DRM_I830_INIT 0x00 -#define DRM_I830_FLUSH 0x01 -#define DRM_I830_FLIP 0x02 -#define DRM_I830_BATCHBUFFER 0x03 -#define DRM_I830_IRQ_EMIT 0x04 -#define DRM_I830_IRQ_WAIT 0x05 -#define DRM_I830_GETPARAM 0x06 -#define DRM_I830_SETPARAM 0x07 -#define DRM_I830_ALLOC 0x08 -#define DRM_I830_FREE 0x09 -#define DRM_I830_INIT_HEAP 0x0a -#define DRM_I830_CMDBUFFER 0x0b -#define DRM_I830_DESTROY_HEAP 0x0c -#define DRM_I830_SET_VBLANK_PIPE 0x0d -#define DRM_I830_GET_VBLANK_PIPE 0x0e -#define DRM_I830_MMIO 0x10 - -typedef struct { - enum { - I830_INIT_DMA = 0x01, - I830_CLEANUP_DMA = 0x02, - I830_RESUME_DMA = 0x03 - } func; - unsigned int mmio_offset; - int sarea_priv_offset; - unsigned int ring_start; - unsigned int ring_end; - unsigned int ring_size; - unsigned int front_offset; - unsigned int back_offset; - unsigned int depth_offset; - unsigned int w; - unsigned int h; - unsigned int pitch; - unsigned int pitch_bits; - unsigned int back_pitch; - unsigned int depth_pitch; - unsigned int cpp; - unsigned int chipset; -} drmI830Init; - -typedef struct { - drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; - int last_upload; /* last time texture was uploaded */ - int last_enqueue; /* last time a buffer was enqueued */ - int last_dispatch; /* age of the most recently dispatched buffer */ - int ctxOwner; /* last context to upload state */ - /** Last context that used the buffer manager. */ - int texAge; - int pf_enabled; /* is pageflipping allowed? */ - int pf_active; - int pf_current_page; /* which buffer is being displayed? */ - int perf_boxes; /* performance boxes to be displayed */ - int width, height; /* screen size in pixels */ - - drm_handle_t front_handle; - int front_offset; - int front_size; - - drm_handle_t back_handle; - int back_offset; - int back_size; - - drm_handle_t depth_handle; - int depth_offset; - int depth_size; - - drm_handle_t tex_handle; - int tex_offset; - int tex_size; - int log_tex_granularity; - int pitch; - int rotation; /* 0, 90, 180 or 270 */ - int rotated_offset; - int rotated_size; - int rotated_pitch; - int virtualX, virtualY; - - unsigned int front_tiled; - unsigned int back_tiled; - unsigned int depth_tiled; - unsigned int rotated_tiled; - unsigned int rotated2_tiled; - - int planeA_x; - int planeA_y; - int planeA_w; - int planeA_h; - int planeB_x; - int planeB_y; - int planeB_w; - int planeB_h; - - /* Triple buffering */ - drm_handle_t third_handle; - int third_offset; - int third_size; - unsigned int third_tiled; - - /* buffer object handles for the static buffers. May change - * over the lifetime of the client, though it doesn't in our current - * implementation. - */ - unsigned int front_bo_handle; - unsigned int back_bo_handle; - unsigned int third_bo_handle; - unsigned int depth_bo_handle; -} drmI830Sarea; - -/* Flags for perf_boxes - */ -#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ -#define I830_BOX_FLIP 0x2 /* populated by kernel */ -#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ -#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ -#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ - - -typedef struct { - int start; /* agp offset */ - int used; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830BatchBuffer; - -typedef struct { - char *buf; /* agp offset */ - int sz; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830CmdBuffer; - -typedef struct { - int *irq_seq; -} drmI830IrqEmit; - -typedef struct { - int irq_seq; -} drmI830IrqWait; - -typedef struct { - int param; - int *value; -} drmI830GetParam; - -#define I830_PARAM_IRQ_ACTIVE 1 -#define I830_PARAM_ALLOW_BATCHBUFFER 2 - -typedef struct { - int param; - int value; -} drmI830SetParam; - -#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 -#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 -#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 - - -/* A memory manager for regions of shared memory: - */ -#define I830_MEM_REGION_AGP 1 - -typedef struct { - int region; - int alignment; - int size; - int *region_offset; /* offset from start of fb or agp */ -} drmI830MemAlloc; - -typedef struct { - int region; - int region_offset; -} drmI830MemFree; - -typedef struct { - int region; - int size; - int start; -} drmI830MemInitHeap; - -typedef struct { - int region; -} drmI830MemDestroyHeap; - -#define DRM_I830_VBLANK_PIPE_A 1 -#define DRM_I830_VBLANK_PIPE_B 2 - -typedef struct { - int pipe; -} drmI830VBlankPipe; - -#define MMIO_READ 0 -#define MMIO_WRITE 1 - -#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 -#define MMIO_REGS_IA_VERTICES_COUNT 1 -#define MMIO_REGS_VS_INVOCATION_COUNT 2 -#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 -#define MMIO_REGS_GS_INVOCATION_COUNT 4 -#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 -#define MMIO_REGS_CL_INVOCATION_COUNT 6 -#define MMIO_REGS_PS_INVOCATION_COUNT 7 -#define MMIO_REGS_PS_DEPTH_COUNT 8 - -typedef struct { - unsigned int read_write:1; - unsigned int reg:31; - void __user *data; -} drmI830MMIO; - -#endif /* _I830_DRM_H_ */ diff --git a/src/gallium/winsys/dri/intel/server/i830_dri.h b/src/gallium/winsys/dri/intel/server/i830_dri.h deleted file mode 100644 index 0d514b6c38..0000000000 --- a/src/gallium/winsys/dri/intel/server/i830_dri.h +++ /dev/null @@ -1,62 +0,0 @@ - -#ifndef _I830_DRI_H -#define _I830_DRI_H - -#include "xf86drm.h" -#include "i830_common.h" - -#define I830_MAX_DRAWABLES 256 - -#define I830_MAJOR_VERSION 1 -#define I830_MINOR_VERSION 7 -#define I830_PATCHLEVEL 2 - -#define I830_REG_SIZE 0x80000 - -typedef struct _I830DRIRec { - drm_handle_t regs; - drmSize regsSize; - - drmSize unused1; /* backbufferSize */ - drm_handle_t unused2; /* backbuffer */ - - drmSize unused3; /* depthbufferSize */ - drm_handle_t unused4; /* depthbuffer */ - - drmSize unused5; /* rotatedSize */ - drm_handle_t unused6; /* rotatedbuffer */ - - drm_handle_t unused7; /* textures */ - int unused8; /* textureSize */ - - drm_handle_t unused9; /* agp_buffers */ - drmSize unused10; /* agp_buf_size */ - - int deviceID; - int width; - int height; - int mem; - int cpp; - int bitsPerPixel; - - int unused11[8]; /* was front/back/depth/rotated offset/pitch */ - - int unused12; /* logTextureGranularity */ - int unused13; /* textureOffset */ - - int irq; - int sarea_priv_offset; -} I830DRIRec, *I830DRIPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830ConfigPrivRec, *I830ConfigPrivPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830DRIContextRec, *I830DRIContextPtr; - - -#endif diff --git a/src/gallium/winsys/drm/Makefile b/src/gallium/winsys/drm/Makefile new file mode 100644 index 0000000000..f466ce6c3c --- /dev/null +++ b/src/gallium/winsys/drm/Makefile @@ -0,0 +1,38 @@ +# src/mesa/drivers/dri/Makefile + +TOP = ../../../.. + +include $(TOP)/configs/current + + + +default: $(TOP)/$(LIB_DIR) subdirs + + +$(TOP)/$(LIB_DIR): + -mkdir $(TOP)/$(LIB_DIR) + + +subdirs: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +install: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) install) || exit 1 ; \ + fi \ + done + + +clean: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) clean) ; \ + fi \ + done + -rm -f common/*.o diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template new file mode 100644 index 0000000000..80e817b808 --- /dev/null +++ b/src/gallium/winsys/drm/Makefile.template @@ -0,0 +1,125 @@ +# -*-makefile-*- + +MESA_MODULES = \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + +COMMON_GALLIUM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/utils.c \ + $(TOP)/src/mesa/drivers/dri/common/vblank.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_util.c \ + $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c + +COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ + $(TOP)/src/mesa/drivers/common/driverfuncs.c \ + $(TOP)/src/mesa/drivers/dri/common/texmem.c \ + $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c + +COMMON_BM_SOURCES = \ + $(TOP)/src/mesa/drivers/dri/common/dri_bufmgr.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_drmpool.c + + +ifeq ($(WINDOW_SYSTEM),dri) +WINOBJ= +WINLIB= +INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) + +OBJECTS = \ + $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) + +else +# miniglx +WINOBJ= +WINLIB=-L$(MESA)/src/glx/mini +MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini +INCLUDES = $(MINIGLX_INCLUDES) \ + $(SHARED_INCLUDES) \ + $(PCIACCESS_CFLAGS) + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(MINIGLX_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) +endif + + +### Include directories +SHARED_INCLUDES = \ + -I. \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -Iserver \ + -I$(TOP)/include \ + -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/winsys/common \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/mesa/math \ + -I$(TOP)/src/mesa/transform \ + -I$(TOP)/src/mesa/shader \ + -I$(TOP)/src/mesa/swrast \ + -I$(TOP)/src/mesa/swrast_setup \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/src/egl/drivers/dri \ + $(LIBDRM_CFLAGS) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR)/$(LIBNAME_EGL) + + +$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template + $(TOP)/bin/mklib -noprefix -o $@ \ + $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) + +$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS) + $(TOP)/bin/mklib -o $(LIBNAME_EGL) \ + -linker "$(CC)" \ + -noprefix \ + $(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \ + --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive + +$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) + $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) + +$(TOP)/$(LIB_DIR)/$(LIBNAME_EGL): $(LIBNAME_EGL) + $(INSTALL) $(LIBNAME_EGL) $(TOP)/$(LIB_DIR) + +depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +install: $(LIBNAME) + $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + + +include depend diff --git a/src/gallium/winsys/drm/SConscript b/src/gallium/winsys/drm/SConscript new file mode 100644 index 0000000000..aef5210a32 --- /dev/null +++ b/src/gallium/winsys/drm/SConscript @@ -0,0 +1,54 @@ +Import('*') + +if env['dri']: + + drienv = env.Clone() + + drienv.Replace(CPPPATH = [ + '#src/mesa/drivers/dri/common', + '#include', + '#include/GL/internal', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', + ]) + + drienv.ParseConfig('pkg-config --cflags --libs libdrm') + + COMMON_GALLIUM_SOURCES = [ + '#src/mesa/drivers/dri/common/utils.c', + '#src/mesa/drivers/dri/common/vblank.c', + '#src/mesa/drivers/dri/common/dri_util.c', + '#src/mesa/drivers/dri/common/xmlconfig.c', + ] + + COMMON_BM_SOURCES = [ + '#src/mesa/drivers/dri/common/dri_bufmgr.c', + '#src/mesa/drivers/dri/common/dri_drmpool.c', + ] + + Export([ + 'drienv', + 'COMMON_GALLIUM_SOURCES', + 'COMMON_BM_SOURCES', + ]) + + # TODO: Installation + #install: $(LIBNAME) + # $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) + # $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + + if 'intel' in env['winsys']: + SConscript([ + 'intel/SConscript', + ]) diff --git a/src/gallium/winsys/drm/intel/Makefile b/src/gallium/winsys/drm/intel/Makefile new file mode 100644 index 0000000000..a670ac044d --- /dev/null +++ b/src/gallium/winsys/drm/intel/Makefile @@ -0,0 +1,25 @@ +TOP = ../../../../.. +include $(TOP)/configs/current + + +SUBDIRS = common dri egl + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` + rm -f `find . -name depend` + + +# Dummy install target +install: diff --git a/src/gallium/winsys/drm/intel/common/Makefile b/src/gallium/winsys/drm/intel/common/Makefile new file mode 100644 index 0000000000..bf1a7d691f --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/Makefile @@ -0,0 +1,23 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +LIBNAME = inteldrm + +C_SOURCES = \ + intel_be_batchbuffer.c \ + intel_be_context.c \ + intel_be_device.c \ + ws_dri_bufmgr.c \ + ws_dri_drmpool.c \ + ws_dri_fencemgr.c \ + ws_dri_mallocpool.c \ + ws_dri_slabpool.c + + +include ./Makefile.template + +DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \ + && pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +symlinks: + diff --git a/src/gallium/winsys/drm/intel/common/Makefile.template b/src/gallium/winsys/drm/intel/common/Makefile.template new file mode 100644 index 0000000000..02ed363a43 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/Makefile.template @@ -0,0 +1,64 @@ +# -*-makefile-*- + + +# We still have a dependency on the "dri" buffer manager. Most likely +# the interface can be reused in non-dri environments, and also as a +# frontend to simpler memory managers. +# +COMMON_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(CPP_SOURCES:.cpp=.o) \ + $(ASM_SOURCES:.S=.o) + + +### Include directories +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/include \ + $(DRIVER_INCLUDES) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: depend symlinks $(LIBNAME) + + +$(LIBNAME): $(OBJECTS) Makefile Makefile.template + $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS) + + +depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ + $(ASM_SOURCES) 2> /dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean:: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +include depend diff --git a/src/gallium/winsys/drm/intel/common/glthread.h b/src/gallium/winsys/drm/intel/common/glthread.h new file mode 100644 index 0000000000..b8e9d5f59b --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/glthread.h @@ -0,0 +1,359 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* + * Thread support for gl dispatch. + * + * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) + * and Christoph Poliwoda (poliwoda@volumegraphics.com) + * Revised by Keith Whitwell + * Adapted for new gl dispatcher by Brian Paul + * + * + * + * DOCUMENTATION + * + * This thread module exports the following types: + * _glthread_TSD Thread-specific data area + * _glthread_Thread Thread datatype + * _glthread_Mutex Mutual exclusion lock + * + * Macros: + * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex + * _glthread_INIT_MUTEX(name) Initialize a mutex + * _glthread_LOCK_MUTEX(name) Lock a mutex + * _glthread_UNLOCK_MUTEX(name) Unlock a mutex + * + * Functions: + * _glthread_GetID(v) Get integer thread ID + * _glthread_InitTSD() Initialize thread-specific data + * _glthread_GetTSD() Get thread-specific data + * _glthread_SetTSD() Set thread-specific data + * + */ + +/* + * If this file is accidentally included by a non-threaded build, + * it should not cause the build to fail, or otherwise cause problems. + * In general, it should only be included when needed however. + */ + +#ifndef GLTHREAD_H +#define GLTHREAD_H + + +#if defined(USE_MGL_NAMESPACE) +#define _glapi_Dispatch _mglapi_Dispatch +#endif + + + +#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ + defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ + && !defined(THREADS) +# define THREADS +#endif + +#ifdef VMS +#include +#endif + +/* + * POSIX threads. This should be your choice in the Unix world + * whenever possible. When building with POSIX threads, be sure + * to enable any compiler flags which will cause the MT-safe + * libc (if one exists) to be used when linking, as well as any + * header macros for MT-safe errno, etc. For Solaris, this is the -mt + * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable + * proper compiling for MT-safe libc etc. + */ +#if defined(PTHREADS) +#include /* POSIX threads headers */ + +typedef struct { + pthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef pthread_t _glthread_Thread; + +typedef pthread_mutex_t _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER + +#define _glthread_INIT_MUTEX(name) \ + pthread_mutex_init(&(name), NULL) + +#define _glthread_DESTROY_MUTEX(name) \ + pthread_mutex_destroy(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) pthread_mutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) pthread_mutex_unlock(&(name)) + +typedef pthread_cond_t _glthread_Cond; + +#define _glthread_DECLARE_STATIC_COND(name) \ + static _glthread_Cond name = PTHREAD_COND_INITIALIZER + +#define _glthread_INIT_COND(cond) \ + pthread_cond_init(&(cond), NULL) + +#define _glthread_DESTROY_COND(name) \ + pthread_cond_destroy(&(name)) + +#define _glthread_COND_WAIT(cond, mutex) \ + pthread_cond_wait(&(cond), &(mutex)) + +#define _glthread_COND_SIGNAL(cond) \ + pthread_cond_signal(&(cond)) + +#define _glthread_COND_BROADCAST(cond) \ + pthread_cond_broadcast(&(cond)) + + +#else /* PTHREADS */ + +typedef unsigned int _glthread_Cond; +#define _glthread_DECLARE_STATIC_COND(name) \ +// #warning Condition variables not implemented. + +#define _glthread_INIT_COND(cond) \ + abort(); + +#define _glthread_DESTROY_COND(name) \ + abort(); + +#define _glthread_COND_WAIT(cond, mutex) \ + abort(); + +#define _glthread_COND_SIGNAL(cond) \ + abort(); + +#define _glthread_COND_BROADCAST(cond) \ + abort(); + +#endif + + +/* + * Solaris threads. Use only up to Solaris 2.4. + * Solaris 2.5 and higher provide POSIX threads. + * Be sure to compile with -mt on the Solaris compilers, or + * use -D_REENTRANT if using gcc. + */ +#ifdef SOLARIS_THREADS +#include + +typedef struct { + thread_key_t key; + mutex_t keylock; + int initMagic; +} _glthread_TSD; + +typedef thread_t _glthread_Thread; + +typedef mutex_t _glthread_Mutex; + +/* XXX need to really implement mutex-related macros */ +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 +#define _glthread_INIT_MUTEX(name) (void) name +#define _glthread_DESTROY_MUTEX(name) (void) name +#define _glthread_LOCK_MUTEX(name) (void) name +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* SOLARIS_THREADS */ + + + + +/* + * Windows threads. Should work with Windows NT and 95. + * IMPORTANT: Link with multithreaded runtime library when THREADS are + * used! + */ +#ifdef WIN32_THREADS +#include + +typedef struct { + DWORD key; + int initMagic; +} _glthread_TSD; + +typedef HANDLE _glthread_Thread; + +typedef CRITICAL_SECTION _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) /*static*/ _glthread_Mutex name = {0,0,0,0,0,0} +#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name) +#define _glthread_DESTROY_MUTEX(name) DeleteCriticalSection(&name) +#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name) +#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name) + +#endif /* WIN32_THREADS */ + + + + +/* + * XFree86 has its own thread wrapper, Xthreads.h + * We wrap it again for GL. + */ +#ifdef USE_XTHREADS +#include + +typedef struct { + xthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef xthread_t _glthread_Thread; + +typedef xmutex_rec _glthread_Mutex; + +#ifdef XMUTEX_INITIALIZER +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = XMUTEX_INITIALIZER +#else +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name +#endif + +#define _glthread_INIT_MUTEX(name) \ + xmutex_init(&(name)) + +#define _glthread_DESTROY_MUTEX(name) \ + xmutex_clear(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) xmutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) xmutex_unlock(&(name)) + +#endif /* USE_XTHREADS */ + + + +/* + * BeOS threads. R5.x required. + */ +#ifdef BEOS_THREADS + +#include +#include + +typedef struct { + int32 key; + int initMagic; +} _glthread_TSD; + +typedef thread_id _glthread_Thread; + +/* Use Benaphore, aka speeder semaphore */ +typedef struct { + int32 lock; + sem_id sem; +} benaphore; +typedef benaphore _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = { 0, 0 } +#define _glthread_INIT_MUTEX(name) name.sem = create_sem(0, #name"_benaphore"), name.lock = 0 +#define _glthread_DESTROY_MUTEX(name) delete_sem(name.sem), name.lock = 0 +#define _glthread_LOCK_MUTEX(name) if (name.sem == 0) _glthread_INIT_MUTEX(name); \ + if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem) +#define _glthread_UNLOCK_MUTEX(name) if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem) + +#endif /* BEOS_THREADS */ + + + +#ifndef THREADS + +/* + * THREADS not defined + */ + +typedef GLuint _glthread_TSD; + +typedef GLuint _glthread_Thread; + +typedef GLuint _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 + +#define _glthread_INIT_MUTEX(name) (void) name + +#define _glthread_DESTROY_MUTEX(name) (void) name + +#define _glthread_LOCK_MUTEX(name) (void) name + +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* THREADS */ + + + +/* + * Platform independent thread specific data API. + */ + +extern unsigned long +_glthread_GetID(void); + + +extern void +_glthread_InitTSD(_glthread_TSD *); + + +extern void * +_glthread_GetTSD(_glthread_TSD *); + + +extern void +_glthread_SetTSD(_glthread_TSD *, void *); + +#if defined(GLX_USE_TLS) + +extern __thread struct _glapi_table * _glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))); + +#define GET_DISPATCH() _glapi_tls_Dispatch + +#elif !defined(GL_CALL) +# if defined(THREADS) +# define GET_DISPATCH() \ + ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ + ? _glapi_Dispatch : _glapi_get_dispatch()) +# else +# define GET_DISPATCH() _glapi_Dispatch +# endif /* defined(THREADS) */ +#endif /* ndef GL_CALL */ + + +#endif /* THREADS_H */ diff --git a/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.c new file mode 100644 index 0000000000..bc13a5761e --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.c @@ -0,0 +1,429 @@ + +#include "intel_be_batchbuffer.h" +#include "intel_be_context.h" +#include "intel_be_device.h" +#include + +#include "xf86drm.h" + +static void +intel_realloc_relocs(struct intel_be_batchbuffer *batch, int num_relocs) +{ + unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER; + + size *= sizeof(uint32_t); + batch->reloc = realloc(batch->reloc, size); + batch->reloc_size = num_relocs; +} + + +void +intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch) +{ + /* + * Get a new, free batchbuffer. + */ + drmBO *bo; + struct drm_bo_info_req *req; + + driBOUnrefUserList(batch->list); + driBOResetList(batch->list); + + /* base.size is the size available to the i915simple driver */ + batch->base.size = batch->device->max_batch_size - BATCH_RESERVED; + batch->base.actual_size = batch->device->max_batch_size; + driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0); + + /* + * Add the batchbuffer to the validate list. + */ + + driBOAddListItem(batch->list, batch->buffer, + DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM, + &batch->dest_location, &batch->node); + + req = &batch->node->bo_arg.d.req.bo_req; + + /* + * Set up information needed for us to make relocations + * relative to the underlying drm buffer objects. + */ + + driReadLockKernelBO(); + bo = driBOKernel(batch->buffer); + req->presumed_offset = (uint64_t) bo->offset; + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + batch->drmBOVirtual = (uint8_t *) bo->virtual; + driReadUnlockKernelBO(); + + /* + * Adjust the relocation buffer size. + */ + + if (batch->reloc_size > INTEL_MAX_RELOCS || + batch->reloc == NULL) + intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS); + + assert(batch->reloc != NULL); + batch->reloc[0] = 0; /* No relocs yet. */ + batch->reloc[1] = 1; /* Reloc type 1 */ + batch->reloc[2] = 0; /* Only a single relocation list. */ + batch->reloc[3] = 0; /* Only a single relocation list. */ + + batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->poolOffset = driBOPoolOffset(batch->buffer); + batch->base.ptr = batch->base.map; + batch->dirty_state = ~0; + batch->nr_relocs = 0; + batch->flags = 0; + batch->id = 0;//batch->intel->intelScreen->batch_id++; +} + +/*====================================================================== + * Public functions + */ +struct intel_be_batchbuffer * +intel_be_batchbuffer_alloc(struct intel_be_context *intel) +{ + struct intel_be_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + batch->device = intel->device; + + driGenBuffers(intel->device->batchPool, "batchbuffer", 1, + &batch->buffer, 4096, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); + batch->last_fence = NULL; + batch->list = driBOCreateList(20); + batch->reloc = NULL; + intel_be_batchbuffer_reset(batch); + return batch; +} + +void +intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch) +{ + if (batch->last_fence) { + driFenceFinish(batch->last_fence, + DRM_FENCE_TYPE_EXE, FALSE); + driFenceUnReference(&batch->last_fence); + } + if (batch->base.map) { + driBOUnmap(batch->buffer); + batch->base.map = NULL; + } + driBOUnReference(batch->buffer); + driBOFreeList(batch->list); + if (batch->reloc) + free(batch->reloc); + batch->buffer = NULL; + free(batch); +} + +void +intel_be_offset_relocation(struct intel_be_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask) +{ + int itemLoc; + struct _drmBONode *node; + uint32_t *reloc; + struct drm_bo_info_req *req; + + driBOAddListItem(batch->list, driBO, val_flags, val_mask, + &itemLoc, &node); + req = &node->bo_arg.d.req.bo_req; + + if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) { + + /* + * Stop other threads from tampering with the underlying + * drmBO while we're reading its offset. + */ + + driReadLockKernelBO(); + req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset; + driReadUnlockKernelBO(); + req->hint = DRM_BO_HINT_PRESUMED_OFFSET; + } + + pre_add += driBOPoolOffset(driBO); + + if (batch->nr_relocs == batch->reloc_size) + intel_realloc_relocs(batch, batch->reloc_size * 2); + + reloc = batch->reloc + + (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE); + + reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual); + i915_batchbuffer_dword(&batch->base, req->presumed_offset + pre_add); + reloc[1] = pre_add; + reloc[2] = itemLoc; + reloc[3] = batch->dest_location; + batch->nr_relocs++; +} + +static void +i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf) +{ + buf->handle = rep->handle; + buf->flags = rep->flags; + buf->size = rep->size; + buf->offset = rep->offset; + buf->mapHandle = rep->arg_handle; + buf->proposedFlags = rep->proposed_flags; + buf->start = rep->buffer_start; + buf->fenceFlags = rep->fence_flags; + buf->replyFlags = rep->rep_flags; + buf->pageAlignment = rep->page_alignment; +} + +static int +i915_execbuf(struct intel_be_batchbuffer *batch, + unsigned int used, + boolean ignore_cliprects, + drmBOList *list, + struct drm_i915_execbuffer *ea) +{ +// struct intel_be_context *intel = batch->intel; + drmBONode *node; + drmMMListHead *l; + struct drm_i915_op_arg *arg, *first; + struct drm_bo_op_req *req; + struct drm_bo_info_rep *rep; + uint64_t *prevNext = NULL; + drmBO *buf; + int ret = 0; + uint32_t count = 0; + + first = NULL; + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + + arg = &node->bo_arg; + req = &arg->d.req; + + if (!first) + first = arg; + + if (prevNext) + *prevNext = (unsigned long)arg; + + prevNext = &arg->next; + req->bo_req.handle = node->buf->handle; + req->op = drm_bo_validate; + req->bo_req.flags = node->arg0; + req->bo_req.mask = node->arg1; + req->bo_req.hint |= 0; + count++; + } + + memset(ea, 0, sizeof(*ea)); + ea->num_buffers = count; + ea->batch.start = batch->poolOffset; + ea->batch.used = used; +#if 0 /* ZZZ JB: no cliprects used */ + ea->batch.cliprects = intel->pClipRects; + ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); +#else + ea->batch.cliprects = NULL; + ea->batch.num_cliprects = 0; + ea->batch.DR1 = 0; + ea->batch.DR4 = 0; +#endif + ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED; + ea->ops_list = (unsigned long) first; + first->reloc_ptr = (unsigned long) batch->reloc; + batch->reloc[0] = batch->nr_relocs; + + //return -EFAULT; + do { + ret = drmCommandWriteRead(batch->device->fd, DRM_I915_EXECBUFFER, ea, + sizeof(*ea)); + } while (ret == -EAGAIN); + + if (ret != 0) + return ret; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + arg = &node->bo_arg; + rep = &arg->d.rep.bo_info; + + if (!arg->handled) { + return -EFAULT; + } + if (arg->d.rep.ret) + return arg->d.rep.ret; + + buf = node->buf; + i915_drm_copy_reply(rep, buf); + } + return 0; +} + +/* TODO: Push this whole function into bufmgr. + */ +static struct _DriFenceObject * +do_flush_locked(struct intel_be_batchbuffer *batch, + unsigned int used, + boolean ignore_cliprects, boolean allow_unlock) +{ + struct intel_be_context *intel = batch->intel; + struct _DriFenceObject *fo; + drmFence fence; + drmBOList *boList; + struct drm_i915_execbuffer ea; + int ret = 0; + + driBOValidateUserList(batch->list); + boList = driGetdrmBOList(batch->list); + +#if 0 /* ZZZ JB Allways run */ + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { +#else + if (1) { +#endif + ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea); + } else { + driPutdrmBOList(batch->list); + fo = NULL; + goto out; + } + driPutdrmBOList(batch->list); + if (ret) + abort(); + + if (ea.fence_arg.error != 0) { + + /* + * The hardware has been idled by the kernel. + * Don't fence the driBOs. + */ + + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); +#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */ + _mesa_printf("fence error\n"); +#endif + batch->last_fence = NULL; + fo = NULL; + goto out; + } + + fence.handle = ea.fence_arg.handle; + fence.fence_class = ea.fence_arg.fence_class; + fence.type = ea.fence_arg.type; + fence.flags = ea.fence_arg.flags; + fence.signaled = ea.fence_arg.signaled; + + fo = driBOFenceUserList(batch->device->fenceMgr, batch->list, + "SuperFence", &fence); + + if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) { + if (batch->last_fence) + driFenceUnReference(&batch->last_fence); + /* + * FIXME: Context last fence?? + */ + batch->last_fence = fo; + driFenceReference(fo); + } + out: +#if 0 /* ZZZ JB: fix this */ + intel->vtbl.lost_hardware(intel); +#else + (void)intel; +#endif + return fo; +} + + +struct _DriFenceObject * +intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch) +{ + struct intel_be_context *intel = batch->intel; + unsigned int used = batch->base.ptr - batch->base.map; + boolean was_locked = batch->intel->hardware_locked(intel); + struct _DriFenceObject *fence; + + if (used == 0) { + driFenceReference(batch->last_fence); + return batch->last_fence; + } + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ +#if 0 /* ZZZ JB: what should we do here? */ + if (used & 4) { + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } +#else + if (used & 4) { + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = 0; + ((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH; + ((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END; + used += 8; + } +#endif + driBOUnmap(batch->buffer); + batch->base.ptr = NULL; + batch->base.map = NULL; + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!was_locked) + intel->hardware_lock(intel); + + fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + FALSE); + + if (!was_locked) + intel->hardware_unlock(intel); + + /* Reset the buffer: + */ + intel_be_batchbuffer_reset(batch); + return fence; +} + +void +intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch) +{ + struct _DriFenceObject *fence = intel_be_batchbuffer_flush(batch); + driFenceFinish(fence, driFenceType(fence), FALSE); + driFenceUnReference(&fence); +} + +#if 0 +void +intel_be_batchbuffer_data(struct intel_be_batchbuffer *batch, + const void *data, unsigned int bytes, unsigned int flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + memcpy(batch->base.ptr, data, bytes); + batch->base.ptr += bytes; +} +#endif diff --git a/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.h b/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.h new file mode 100644 index 0000000000..f150e3a674 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_batchbuffer.h @@ -0,0 +1,69 @@ + +#ifndef INTEL_BE_BATCHBUFFER_H +#define INTEL_BE_BATCHBUFFER_H + +#include "i915simple/i915_batch.h" + +#include "ws_dri_bufmgr.h" + +#define BATCH_RESERVED 16 + +#define INTEL_DEFAULT_RELOCS 100 +#define INTEL_MAX_RELOCS 400 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct intel_be_context; +struct intel_be_device; + +struct intel_be_batchbuffer +{ + struct i915_batchbuffer base; + + struct intel_be_context *intel; + struct intel_be_device *device; + + struct _DriBufferObject *buffer; + struct _DriFenceObject *last_fence; + uint32_t flags; + + struct _DriBufferList *list; + size_t list_count; + + uint32_t *reloc; + size_t reloc_size; + size_t nr_relocs; + + uint32_t dirty_state; + uint32_t id; + + uint32_t poolOffset; + uint8_t *drmBOVirtual; + struct _drmBONode *node; /* Validation list node for this buffer */ + int dest_location; /* Validation list sequence for this buffer */ +}; + +struct intel_be_batchbuffer * +intel_be_batchbuffer_alloc(struct intel_be_context *intel); + +void +intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch); + +void +intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch); + +struct _DriFenceObject * +intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch); + +void +intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch); + +void +intel_be_offset_relocation(struct intel_be_batchbuffer *batch, + unsigned pre_add, + struct _DriBufferObject *driBO, + uint64_t val_flags, + uint64_t val_mask); + +#endif diff --git a/src/gallium/winsys/drm/intel/common/intel_be_context.c b/src/gallium/winsys/drm/intel/common/intel_be_context.c new file mode 100644 index 0000000000..1af39674f4 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_context.c @@ -0,0 +1,107 @@ + +/* + * Authors: Jakob Bornecrantz + */ + +#include "ws_dri_fencemgr.h" +#include "intel_be_device.h" +#include "intel_be_context.h" +#include "intel_be_batchbuffer.h" + +static INLINE struct intel_be_context * +intel_be_context(struct i915_winsys *sws) +{ + return (struct intel_be_context *)sws; +} + +/* Simple batchbuffer interface: + */ + +static struct i915_batchbuffer* +intel_i915_batch_get(struct i915_winsys *sws) +{ + struct intel_be_context *intel = intel_be_context(sws); + return &intel->batch->base; +} + +static void intel_i915_batch_reloc(struct i915_winsys *sws, + struct pipe_buffer *buf, + unsigned access_flags, + unsigned delta) +{ + struct intel_be_context *intel = intel_be_context(sws); + + unsigned flags = DRM_BO_FLAG_MEM_TT; + unsigned mask = DRM_BO_MASK_MEM; + + if (access_flags & I915_BUFFER_ACCESS_WRITE) { + flags |= DRM_BO_FLAG_WRITE; + mask |= DRM_BO_FLAG_WRITE; + } + + if (access_flags & I915_BUFFER_ACCESS_READ) { + flags |= DRM_BO_FLAG_READ; + mask |= DRM_BO_FLAG_READ; + } + + intel_be_offset_relocation(intel->batch, + delta, + dri_bo(buf), + flags, + mask); +} + +static void intel_i915_batch_flush(struct i915_winsys *sws, + struct pipe_fence_handle **fence) +{ + struct intel_be_context *intel = intel_be_context(sws); + + union { + struct _DriFenceObject *dri; + struct pipe_fence_handle *pipe; + } fu; + + if (fence) + assert(!*fence); + + fu.dri = intel_be_batchbuffer_flush(intel->batch); + + if (!fu.dri) { + assert(0); + *fence = NULL; + return; + } + + if (fu.dri) { + if (fence) + *fence = fu.pipe; + else + driFenceUnReference(&fu.dri); + } + +} + +boolean +intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device) +{ + assert(intel); + assert(device); + + intel->device = device; + + /* TODO move framebuffer createion to the driver */ + + intel->base.batch_get = intel_i915_batch_get; + intel->base.batch_reloc = intel_i915_batch_reloc; + intel->base.batch_flush = intel_i915_batch_flush; + + intel->batch = intel_be_batchbuffer_alloc(intel); + + return true; +} + +void +intel_be_destroy_context(struct intel_be_context *intel) +{ + intel_be_batchbuffer_free(intel->batch); +} diff --git a/src/gallium/winsys/drm/intel/common/intel_be_context.h b/src/gallium/winsys/drm/intel/common/intel_be_context.h new file mode 100644 index 0000000000..d5cbc93594 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_context.h @@ -0,0 +1,40 @@ +/* These need to be diffrent from the intel winsys */ +#ifndef INTEL_BE_CONTEXT_H +#define INTEL_BE_CONTEXT_H + +#include "i915simple/i915_winsys.h" + +struct intel_be_context +{ + /** Interface to i915simple driver */ + struct i915_winsys base; + + struct intel_be_device *device; + struct intel_be_batchbuffer *batch; + + /* + * Hardware lock functions. + * + * Needs to be filled in by the winsys. + */ + void (*hardware_lock)(struct intel_be_context *context); + void (*hardware_unlock)(struct intel_be_context *context); + boolean (*hardware_locked)(struct intel_be_context *context); +}; + +/** + * Intialize a allocated intel_be_context struct. + * + * Remember to set the hardware_* functions. + */ +boolean +intel_be_init_context(struct intel_be_context *intel, + struct intel_be_device *device); + +/** + * Destroy a intel_be_context. + * Does not free the struct that is up to the winsys. + */ +void +intel_be_destroy_context(struct intel_be_context *intel); +#endif diff --git a/src/gallium/winsys/drm/intel/common/intel_be_device.c b/src/gallium/winsys/drm/intel/common/intel_be_device.c new file mode 100644 index 0000000000..8db0329615 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_device.c @@ -0,0 +1,308 @@ + + +/* + * Authors: Keith Whitwell + * Jakob Bornecrantz + */ + +#include "intel_be_device.h" +#include "ws_dri_bufmgr.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + +#include "pipe/p_winsys.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "i915simple/i915_screen.h" + +/* Turn a pipe winsys into an intel/pipe winsys: + */ +static INLINE struct intel_be_device * +intel_be_device( struct pipe_winsys *winsys ) +{ + return (struct intel_be_device *)winsys; +} + + +/* + * Buffer functions. + * + * Most callbacks map direcly onto dri_bufmgr operations: + */ + +static void *intel_be_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags ) +{ + unsigned drm_flags = 0; + + if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) + drm_flags |= DRM_BO_FLAG_WRITE; + + if (flags & PIPE_BUFFER_USAGE_CPU_READ) + drm_flags |= DRM_BO_FLAG_READ; + + return driBOMap( dri_bo(buf), drm_flags, 0 ); +} + +static void intel_be_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnmap( dri_bo(buf) ); +} + +static void +intel_be_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + driBOUnReference( dri_bo(buf) ); + FREE(buf); +} + +static struct pipe_buffer * +intel_be_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size ) +{ + struct intel_be_buffer *buffer = CALLOC_STRUCT( intel_be_buffer ); + struct intel_be_device *iws = intel_be_device(winsys); + unsigned flags = 0; + struct _DriBufferPool *pool; + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) { + flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; + pool = iws->mallocPool; + } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) { + /* For vertex buffers */ + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->vertexPool; + } else { + flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT; + pool = iws->regionPool; + } + + if (usage & PIPE_BUFFER_USAGE_GPU_READ) + flags |= DRM_BO_FLAG_READ; + + if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) + flags |= DRM_BO_FLAG_WRITE; + + /* drm complains if we don't set any read/write flags. + */ + if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0) + flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + buffer->pool = pool; + driGenBuffers( buffer->pool, + "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 ); + + driBOData( buffer->driBO, size, NULL, buffer->pool, 0 ); + + return &buffer->base; +} + + +static struct pipe_buffer * +intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes) +{ + struct intel_be_buffer *buffer = CALLOC_STRUCT( intel_be_buffer ); + struct intel_be_device *iws = intel_be_device(winsys); + + driGenUserBuffer( iws->regionPool, + "pipe user buffer", &buffer->driBO, ptr, bytes ); + + buffer->base.refcount = 1; + + return &buffer->base; +} + +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle) +{ + struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf)); + struct pipe_buffer *buffer; + + if (!be_buf) + goto err; + + memset(be_buf, 0, sizeof(*be_buf)); + + driGenBuffers(device->staticPool, name, 1, &be_buf->driBO, 0, 0, 0); + driBOSetReferenced(be_buf->driBO, handle); + + if (0) /** XXX TODO check error */ + goto err_bo; + + buffer = &be_buf->base; + buffer->refcount = 1; + buffer->alignment = 0; + buffer->usage = 0; + buffer->size = driBOSize(be_buf->driBO); + + return buffer; +err_bo: + free(be_buf); +err: + return NULL; +} + + +/* + * Surface functions. + * + * Deprecated! + */ + +static struct pipe_surface * +intel_i915_surface_alloc(struct pipe_winsys *winsys) +{ + assert((size_t)"intel_i915_surface_alloc is deprecated" & 0); + return NULL; +} + +static int +intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + assert((size_t)"intel_i915_surface_alloc_storage is deprecated" & 0); + return -1; +} + +static void +intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) +{ + assert((size_t)"intel_i915_surface_release is deprecated" & 0); +} + + +/* + * Fence functions + */ + +static void +intel_be_fence_reference( struct pipe_winsys *sws, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence ) +{ + if (*ptr) + driFenceUnReference((struct _DriFenceObject **)ptr); + + if (fence) + *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence); +} + +static int +intel_be_fence_signalled( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceSignaled((struct _DriFenceObject *)fence, flag); +} + +static int +intel_be_fence_finish( struct pipe_winsys *sws, + struct pipe_fence_handle *fence, + unsigned flag ) +{ + return driFenceFinish((struct _DriFenceObject *)fence, flag, 0); +} + + +/* + * Misc functions + */ + +boolean +intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id) +{ + dev->fd = fd; + dev->max_batch_size = 16 * 4096; + dev->max_vertex_size = 128 * 4096; + + dev->base.buffer_create = intel_be_buffer_create; + dev->base.user_buffer_create = intel_be_user_buffer_create; + dev->base.buffer_map = intel_be_buffer_map; + dev->base.buffer_unmap = intel_be_buffer_unmap; + dev->base.buffer_destroy = intel_be_buffer_destroy; + dev->base.surface_alloc = intel_i915_surface_alloc; + dev->base.surface_alloc_storage = intel_i915_surface_alloc_storage; + dev->base.surface_release = intel_i915_surface_release; + dev->base.fence_reference = intel_be_fence_reference; + dev->base.fence_signalled = intel_be_fence_signalled; + dev->base.fence_finish = intel_be_fence_finish; + +#if 0 /* Set by the winsys */ + dev->base.flush_frontbuffer = intel_flush_frontbuffer; + dev->base.get_name = intel_get_name; +#endif + + dev->fMan = driInitFreeSlabManager(10, 10); + dev->fenceMgr = driFenceMgrTTMInit(dev->fd); + + dev->mallocPool = driMallocPoolInit(); + dev->staticPool = driDRMPoolInit(dev->fd); + /* Sizes: 64 128 256 512 1024 2048 4096 8192 16384 32768 */ + dev->regionPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + 64, + 10, 120, 4096 * 64, 0, + dev->fMan); + + dev->vertexPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT, + dev->max_vertex_size, + 1, 120, dev->max_vertex_size * 4, 0, + dev->fMan); + + dev->batchPool = driSlabPoolInit(dev->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT, + dev->max_batch_size, + 1, 40, dev->max_batch_size * 16, 0, + dev->fMan); + + /* Fill in this struct with callbacks that i915simple will need to + * communicate with the window system, buffer manager, etc. + */ + dev->screen = i915_create_screen(&dev->base, id); + + return true; +} + +void +intel_be_destroy_device(struct intel_be_device *dev) +{ + driPoolTakeDown(dev->mallocPool); + driPoolTakeDown(dev->staticPool); + driPoolTakeDown(dev->regionPool); + driPoolTakeDown(dev->vertexPool); + driPoolTakeDown(dev->batchPool); + + /** TODO takedown fenceMgr and fMan */ +} diff --git a/src/gallium/winsys/drm/intel/common/intel_be_device.h b/src/gallium/winsys/drm/intel/common/intel_be_device.h new file mode 100644 index 0000000000..3f8b3f585c --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/intel_be_device.h @@ -0,0 +1,72 @@ +#ifndef INTEL_DRM_DEVICE_H +#define INTEL_DRM_DEVICE_H + +#include "pipe/p_winsys.h" +#include "pipe/p_context.h" + +/* + * Device + */ + +struct intel_be_device +{ + struct pipe_winsys base; + + /** + * Hw level screen + */ + struct pipe_screen *screen; + + int fd; /**< Drm file discriptor */ + + size_t max_batch_size; + size_t max_vertex_size; + + struct _DriFenceMgr *fenceMgr; + + struct _DriBufferPool *batchPool; + struct _DriBufferPool *regionPool; + struct _DriBufferPool *mallocPool; + struct _DriBufferPool *vertexPool; + struct _DriBufferPool *staticPool; + struct _DriFreeSlabManager *fMan; +}; + +boolean +intel_be_init_device(struct intel_be_device *device, int fd, unsigned id); + +void +intel_be_destroy_device(struct intel_be_device *dev); + +/* + * Buffer + */ + +struct intel_be_buffer { + struct pipe_buffer base; + struct _DriBufferPool *pool; + struct _DriBufferObject *driBO; +}; + +/** + * Create a be buffer from a drm bo handle + * + * Takes a reference + */ +struct pipe_buffer * +intel_be_buffer_from_handle(struct intel_be_device *device, + const char* name, unsigned handle); + +static INLINE struct intel_be_buffer * +intel_be_buffer(struct pipe_buffer *buf) +{ + return (struct intel_be_buffer *)buf; +} + +static INLINE struct _DriBufferObject * +dri_bo(struct pipe_buffer *buf) +{ + return intel_be_buffer(buf)->driBO; +} + +#endif diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c new file mode 100644 index 0000000000..b6d901f85e --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.c @@ -0,0 +1,949 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#include +#include +#include +#include "glthread.h" +#include "errno.h" +#include "ws_dri_bufmgr.h" +#include "string.h" +#include "pipe/p_debug.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" + + +/* + * This lock is here to protect drmBO structs changing underneath us during a + * validate list call, since validatelist cannot take individiual locks for + * each drmBO. Validatelist takes this lock in write mode. Any access to an + * individual drmBO should take this lock in read mode, since in that case, the + * driBufferObject mutex will protect the access. Locking order is + * driBufferObject mutex - > this rw lock. + */ + +_glthread_DECLARE_STATIC_MUTEX(bmMutex); +_glthread_DECLARE_STATIC_COND(bmCond); + +static int kernelReaders = 0; +static int num_buffers = 0; +static int num_user_buffers = 0; + +static drmBO *drmBOListBuf(void *iterator) +{ + drmBONode *node; + drmMMListHead *l = (drmMMListHead *) iterator; + node = DRMLISTENTRY(drmBONode, l, head); + return node->buf; +} + +static void *drmBOListIterator(drmBOList *list) +{ + void *ret = list->list.next; + + if (ret == &list->list) + return NULL; + return ret; +} + +static void *drmBOListNext(drmBOList *list, void *iterator) +{ + void *ret; + + drmMMListHead *l = (drmMMListHead *) iterator; + ret = l->next; + if (ret == &list->list) + return NULL; + return ret; +} + +static drmBONode *drmAddListItem(drmBOList *list, drmBO *item, + uint64_t arg0, + uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } + else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADD(&node->head, &list->list); + list->numOnList++; + return node; +} + +static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags, + uint64_t mask, int *newItem) +{ + drmBONode *node, *cur; + drmMMListHead *l; + + *newItem = 0; + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + } + if (!cur) { + cur = drmAddListItem(list, buf, flags, mask); + if (!cur) { + return -ENOMEM; + } + *newItem = 1; + cur->arg0 = flags; + cur->arg1 = mask; + } + else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + return 0; +} + +static void drmBOFreeList(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->list.next; + while(l != &list->list) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->list.next; + list->numCurrent--; + list->numOnList--; + } + + l = list->free.next; + while(l != &list->free) { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + l = list->free.next; + list->numCurrent--; + } +} + +static int drmAdjustListNodes(drmBOList *list) +{ + drmBONode *node; + drmMMListHead *l; + int ret = 0; + + while(list->numCurrent < list->numTarget) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + ret = -ENOMEM; + break; + } + list->numCurrent++; + DRMLISTADD(&node->head, &list->free); + } + + while(list->numCurrent > list->numTarget) { + l = list->free.next; + if (l == &list->free) + break; + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + free(node); + list->numCurrent--; + } + return ret; +} + +static int drmBOCreateList(int numTarget, drmBOList *list) +{ + DRMINITLISTHEAD(&list->list); + DRMINITLISTHEAD(&list->free); + list->numTarget = numTarget; + list->numCurrent = 0; + list->numOnList = 0; + return drmAdjustListNodes(list); +} + +static int drmBOResetList(drmBOList *list) +{ + drmMMListHead *l; + int ret; + + ret = drmAdjustListNodes(list); + if (ret) + return ret; + + l = list->list.next; + while (l != &list->list) { + DRMLISTDEL(l); + DRMLISTADD(l, &list->free); + list->numOnList--; + l = list->list.next; + } + return drmAdjustListNodes(list); +} + +void driWriteLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + while(kernelReaders != 0) + _glthread_COND_WAIT(bmCond, bmMutex); +} + +void driWriteUnlockKernelBO(void) +{ + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadLockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + kernelReaders++; + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void driReadUnlockKernelBO(void) +{ + _glthread_LOCK_MUTEX(bmMutex); + if (--kernelReaders == 0) + _glthread_COND_BROADCAST(bmCond); + _glthread_UNLOCK_MUTEX(bmMutex); +} + + + + +/* + * TODO: Introduce fence pools in the same way as + * buffer object pools. + */ + +typedef struct _DriBufferObject +{ + DriBufferPool *pool; + _glthread_Mutex mutex; + int refCount; + const char *name; + uint64_t flags; + unsigned hint; + unsigned alignment; + unsigned createdByReference; + void *private; + /* user-space buffer: */ + unsigned userBuffer; + void *userData; + unsigned userSize; +} DriBufferObject; + +typedef struct _DriBufferList { + drmBOList drmBuffers; /* List of kernel buffers needing validation */ + drmBOList driBuffers; /* List of user-space buffers needing validation */ +} DriBufferList; + + +void +bmError(int val, const char *file, const char *function, int line) +{ + printf("Fatal video memory manager error \"%s\".\n" + "Check kernel logs or set the LIBGL_DEBUG\n" + "environment variable to \"verbose\" for more info.\n" + "Detected in file %s, line %d, function %s.\n", + strerror(-val), file, line, function); +#ifndef NDEBUG + abort(); +#else + abort(); +#endif +} + +extern drmBO * +driBOKernel(struct _DriBufferObject *buf) +{ + drmBO *ret; + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + ret = buf->pool->kernel(buf->pool, buf->private); + if (!ret) + BM_CKFATAL(-EINVAL); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + + return ret; +} + +void +driBOWaitIdle(struct _DriBufferObject *buf, int lazy) +{ + + /* + * This function may block. Is it sane to keep the mutex held during + * that time?? + */ + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void * +driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) +{ + void *virtual; + int retval; + + if (buf->userBuffer) { + return buf->userData; + } + + _glthread_LOCK_MUTEX(buf->mutex); + assert(buf->private != NULL); + retval = buf->pool->map(buf->pool, buf->private, flags, hint, + &buf->mutex, &virtual); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval == 0 ? virtual : NULL; +} + +void +driBOUnmap(struct _DriBufferObject *buf) +{ + if (buf->userBuffer) + return; + + assert(buf->private != NULL); + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +unsigned long +driBOOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->offset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +unsigned long +driBOPoolOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->poolOffset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +uint64_t +driBOFlags(struct _DriBufferObject *buf) +{ + uint64_t ret; + + assert(buf->private != NULL); + + driReadLockKernelBO(); + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->flags(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + driReadUnlockKernelBO(); + return ret; +} + +struct _DriBufferObject * +driBOReference(struct _DriBufferObject *buf) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (++buf->refCount == 1) { + _glthread_UNLOCK_MUTEX(buf->mutex); + BM_CKFATAL(-EINVAL); + } + _glthread_UNLOCK_MUTEX(buf->mutex); + return buf; +} + +void +driBOUnReference(struct _DriBufferObject *buf) +{ + int tmp; + + if (!buf) + return; + + _glthread_LOCK_MUTEX(buf->mutex); + tmp = --buf->refCount; + if (!tmp) { + _glthread_UNLOCK_MUTEX(buf->mutex); + if (buf->private) { + if (buf->createdByReference) + buf->pool->unreference(buf->pool, buf->private); + else + buf->pool->destroy(buf->pool, buf->private); + } + if (buf->userBuffer) + num_user_buffers--; + else + num_buffers--; + free(buf); + } else + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + + +int +driBOData(struct _DriBufferObject *buf, + unsigned size, const void *data, + DriBufferPool *newPool, + uint64_t flags) +{ + void *virtual = NULL; + int newBuffer; + int retval = 0; + struct _DriBufferPool *pool; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + pool = buf->pool; + + if (pool == NULL && newPool != NULL) { + buf->pool = newPool; + pool = newPool; + } + if (newPool == NULL) + newPool = pool; + + if (!pool->create) { + assert((size_t)"driBOData called on invalid buffer\n" & 0); + BM_CKFATAL(-EINVAL); + } + + newBuffer = (!buf->private || pool != newPool || + pool->size(pool, buf->private) < size); + + if (!flags) + flags = buf->flags; + + if (newBuffer) { + + if (buf->createdByReference) { + assert((size_t)"driBOData requiring resizing called on shared buffer.\n" & 0); + BM_CKFATAL(-EINVAL); + } + + if (buf->private) + buf->pool->destroy(buf->pool, buf->private); + + pool = newPool; + buf->pool = newPool; + buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (!buf->private) + retval = -ENOMEM; + + if (retval == 0) + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual); + } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) { + /* + * Buffer is busy. need to create a new one. + */ + + void *newBuf; + + newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE, + buf->alignment); + if (newBuf) { + buf->pool->destroy(buf->pool, buf->private); + buf->private = newBuf; + } + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } else { + uint64_t flag_diff = flags ^ buf->flags; + + /* + * We might need to change buffer flags. + */ + + if (flag_diff){ + assert(pool->setStatus != NULL); + BM_CKFATAL(pool->unmap(pool, buf->private)); + BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff, + buf->flags)); + if (!data) + goto out; + + retval = pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual); + } + } + + if (retval == 0) { + if (data) + memcpy(virtual, data, size); + + BM_CKFATAL(pool->unmap(pool, buf->private)); + } + + out: + _glthread_UNLOCK_MUTEX(buf->mutex); + + return retval; +} + +void +driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, const void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &buf->mutex, + &virtual)); + memcpy((unsigned char *) virtual + offset, data, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, void *data) +{ + void *virtual; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual)); + memcpy(data, (unsigned char *) virtual + offset, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->private != NULL) { + assert((size_t)"Invalid buffer for setReferenced\n" & 0); + BM_CKFATAL(-EINVAL); + + } + if (buf->pool->reference == NULL) { + assert((size_t)"Invalid buffer pool for setReferenced\n" & 0); + BM_CKFATAL(-EINVAL); + } + buf->private = buf->pool->reference(buf->pool, handle); + if (!buf->private) { + assert((size_t)"Invalid buffer pool for setStatic\n" & 0); + BM_CKFATAL(-ENOMEM); + } + buf->createdByReference = TRUE; + buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags; + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +int +driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint) +{ + struct _DriBufferObject *buf; + int i; + + flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + ++num_buffers; + + assert(pool); + + for (i = 0; i < n; ++i) { + buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); + if (!buf) + return -ENOMEM; + + _glthread_INIT_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(buf->mutex); + buf->refCount = 1; + buf->flags = flags; + buf->hint = hint; + buf->name = name; + buf->alignment = alignment; + buf->pool = pool; + buf->createdByReference = 0; + _glthread_UNLOCK_MUTEX(buf->mutex); + buffers[i] = buf; + } + return 0; +} + +void +driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject **buffers, + void *ptr, unsigned bytes) +{ + const unsigned alignment = 1, flags = 0, hint = 0; + + --num_buffers; /* JB: is inced in GenBuffes */ + driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); + ++num_user_buffers; + + (*buffers)->userBuffer = 1; + (*buffers)->userData = ptr; + (*buffers)->userSize = bytes; +} + +void +driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) +{ + int i; + + for (i = 0; i < n; ++i) { + driBOUnReference(buffers[i]); + } +} + + +void +driInitBufMgr(int fd) +{ + ; +} + +/* + * Note that lists are per-context and don't need mutex protection. + */ + +struct _DriBufferList * +driBOCreateList(int target) +{ + struct _DriBufferList *list = calloc(sizeof(*list), 1); + + BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers)); + BM_CKFATAL(drmBOCreateList(target, &list->driBuffers)); + return list; +} + +int +driBOResetList(struct _DriBufferList * list) +{ + int ret; + ret = drmBOResetList(&list->drmBuffers); + if (ret) + return ret; + ret = drmBOResetList(&list->driBuffers); + return ret; +} + +void +driBOFreeList(struct _DriBufferList * list) +{ + drmBOFreeList(&list->drmBuffers); + drmBOFreeList(&list->driBuffers); + free(list); +} + + +/* + * Copied from libdrm, because it is needed by driAddValidateItem. + */ + +static drmBONode * +driAddListItem(drmBOList * list, drmBO * item, + uint64_t arg0, uint64_t arg1) +{ + drmBONode *node; + drmMMListHead *l; + + l = list->free.next; + if (l == &list->free) { + node = (drmBONode *) malloc(sizeof(*node)); + if (!node) { + return NULL; + } + list->numCurrent++; + } else { + DRMLISTDEL(l); + node = DRMLISTENTRY(drmBONode, l, head); + } + memset(&node->bo_arg, 0, sizeof(node->bo_arg)); + node->buf = item; + node->arg0 = arg0; + node->arg1 = arg1; + DRMLISTADDTAIL(&node->head, &list->list); + list->numOnList++; + return node; +} + +/* + * Slightly modified version compared to the libdrm version. + * This one returns the list index of the buffer put on the list. + */ + +static int +driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags, + uint64_t mask, int *itemLoc, + struct _drmBONode **pnode) +{ + drmBONode *node, *cur; + drmMMListHead *l; + int count = 0; + + cur = NULL; + + for (l = list->list.next; l != &list->list; l = l->next) { + node = DRMLISTENTRY(drmBONode, l, head); + if (node->buf == buf) { + cur = node; + break; + } + count++; + } + if (!cur) { + cur = driAddListItem(list, buf, flags, mask); + if (!cur) + return -ENOMEM; + + cur->arg0 = flags; + cur->arg1 = mask; + } else { + uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM; + uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM; + + if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) { + return -EINVAL; + } + + cur->arg1 |= mask; + cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask); + + if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) && + (cur->arg0 & DRM_BO_MASK_MEM) == 0) { + return -EINVAL; + } + } + *itemLoc = count; + *pnode = cur; + return 0; +} + + +void +driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node) +{ + int newItem; + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(driAddValidateItem(&list->drmBuffers, + buf->pool->kernel(buf->pool, buf->private), + flags, mask, itemLoc, node)); + BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf, + flags, mask, &newItem)); + if (newItem) + buf->refCount++; + + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +drmBOList *driGetdrmBOList(struct _DriBufferList *list) +{ + driWriteLockKernelBO(); + return &list->drmBuffers; +} + +void driPutdrmBOList(struct _DriBufferList *list) +{ + driWriteUnlockKernelBO(); +} + + +void +driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->fence) + BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + +void +driBOUnrefUserList(struct _DriBufferList *list) +{ + struct _DriBufferObject *buf; + void *curBuf; + + curBuf = drmBOListIterator(&list->driBuffers); + while (curBuf) { + buf = (struct _DriBufferObject *)drmBOListBuf(curBuf); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + +struct _DriFenceObject * +driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, const char *name, + drmFence *kFence) +{ + struct _DriFenceObject *fence; + struct _DriBufferObject *buf; + void *curBuf; + + fence = driFenceCreate(mgr, kFence->fence_class, kFence->type, + kFence, sizeof(*kFence)); + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space fencing callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + driBOFence(buf, fence); + driBOUnReference(buf); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } + + driBOResetList(list); + return fence; +} + +void +driBOValidateUserList(struct _DriBufferList * list) +{ + void *curBuf; + struct _DriBufferObject *buf; + + curBuf = drmBOListIterator(&list->driBuffers); + + /* + * User-space validation callbacks. + */ + + while (curBuf) { + buf = (struct _DriBufferObject *) drmBOListBuf(curBuf); + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->pool->validate) + BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex)); + _glthread_UNLOCK_MUTEX(buf->mutex); + curBuf = drmBOListNext(&list->driBuffers, curBuf); + } +} + + +void +driPoolTakeDown(struct _DriBufferPool *pool) +{ + pool->takeDown(pool); + +} + +unsigned long +driBOSize(struct _DriBufferObject *buf) +{ + unsigned long size; + + _glthread_LOCK_MUTEX(buf->mutex); + size = buf->pool->size(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + + return size; + +} + +drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list) +{ + return &list->drmBuffers; +} + +drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list) +{ + return &list->driBuffers; +} + diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.h b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.h new file mode 100644 index 0000000000..e6c0cff0a0 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_bufmgr.h @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#ifndef _PSB_BUFMGR_H_ +#define _PSB_BUFMGR_H_ +#include +#include "i915_drm.h" +#include "ws_dri_fencemgr.h" + +typedef struct _drmBONode +{ + drmMMListHead head; + drmBO *buf; + struct drm_i915_op_arg bo_arg; + uint64_t arg0; + uint64_t arg1; +} drmBONode; + +typedef struct _drmBOList { + unsigned numTarget; + unsigned numCurrent; + unsigned numOnList; + drmMMListHead list; + drmMMListHead free; +} drmBOList; + + +struct _DriFenceObject; +struct _DriBufferObject; +struct _DriBufferPool; +struct _DriBufferList; + +/* + * Return a pointer to the libdrm buffer object this DriBufferObject + * uses. + */ + +extern drmBO *driBOKernel(struct _DriBufferObject *buf); +extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, + unsigned hint); +extern void driBOUnmap(struct _DriBufferObject *buf); +extern unsigned long driBOOffset(struct _DriBufferObject *buf); +extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf); + +extern uint64_t driBOFlags(struct _DriBufferObject *buf); +extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); +extern void driBOUnReference(struct _DriBufferObject *buf); + +extern int driBOData(struct _DriBufferObject *r_buf, + unsigned size, const void *data, + struct _DriBufferPool *pool, uint64_t flags); + +extern void driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + const void *data); +extern void driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + void *data); +extern int driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, uint64_t flags, unsigned hint); +extern void driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject *buffers[], + void *ptr, unsigned bytes); +extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); +extern void driInitBufMgr(int fd); +extern struct _DriBufferList *driBOCreateList(int target); +extern int driBOResetList(struct _DriBufferList * list); +extern void driBOAddListItem(struct _DriBufferList * list, + struct _DriBufferObject *buf, + uint64_t flags, uint64_t mask, int *itemLoc, + struct _drmBONode **node); + +extern void driBOValidateList(int fd, struct _DriBufferList * list); +extern void driBOFreeList(struct _DriBufferList * list); +extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr, + struct _DriBufferList *list, + const char *name, + drmFence *kFence); +extern void driBOUnrefUserList(struct _DriBufferList *list); +extern void driBOValidateUserList(struct _DriBufferList * list); +extern drmBOList *driGetdrmBOList(struct _DriBufferList *list); +extern void driPutdrmBOList(struct _DriBufferList *list); + +extern void driBOFence(struct _DriBufferObject *buf, + struct _DriFenceObject *fence); + +extern void driPoolTakeDown(struct _DriBufferPool *pool); +extern void driBOSetReferenced(struct _DriBufferObject *buf, + unsigned long handle); +unsigned long driBOSize(struct _DriBufferObject *buf); +extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); +extern void driPoolTakeDown(struct _DriBufferPool *pool); + +extern void driReadLockKernelBO(void); +extern void driReadUnlockKernelBO(void); +extern void driWriteLockKernelBO(void); +extern void driWriteUnlockKernelBO(void); + +/* + * For debugging purposes. + */ + +extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list); +extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list); +#endif diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h b/src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h new file mode 100644 index 0000000000..bf60798924 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_bufpool.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#ifndef _PSB_BUFPOOL_H_ +#define _PSB_BUFPOOL_H_ + +#include +#include +struct _DriFenceObject; + +typedef struct _DriBufferPool +{ + int fd; + int (*map) (struct _DriBufferPool * pool, void *private, + unsigned flags, int hint, _glthread_Mutex *mutex, + void **virtual); + int (*unmap) (struct _DriBufferPool * pool, void *private); + int (*destroy) (struct _DriBufferPool * pool, void *private); + unsigned long (*offset) (struct _DriBufferPool * pool, void *private); + unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private); + uint64_t (*flags) (struct _DriBufferPool * pool, void *private); + unsigned long (*size) (struct _DriBufferPool * pool, void *private); + void *(*create) (struct _DriBufferPool * pool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment); + void *(*reference) (struct _DriBufferPool * pool, unsigned handle); + int (*unreference) (struct _DriBufferPool * pool, void *private); + int (*fence) (struct _DriBufferPool * pool, void *private, + struct _DriFenceObject * fence); + drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); + int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy); + int (*setStatus) (struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags); + void (*takeDown) (struct _DriBufferPool * pool); + void *data; +} DriBufferPool; + +extern void bmError(int val, const char *file, const char *function, + int line); +#define BM_CKFATAL(val) \ + do{ \ + int tstVal = (val); \ + if (tstVal) \ + bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ + } while(0); + + +/* + * Builtin pools. + */ + +/* + * Kernel buffer objects. Size in multiples of page size. Page size aligned. + */ + +extern struct _DriBufferPool *driDRMPoolInit(int fd); +extern struct _DriBufferPool *driMallocPoolInit(void); + +struct _DriFreeSlabManager; +extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan); +extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan); +extern struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec); + + +#endif diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c b/src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c new file mode 100644 index 0000000000..40929efa2f --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_drmpool.c @@ -0,0 +1,268 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" +#include "assert.h" + +/* + * Buffer pool implementation using DRM buffer objects as DRI buffer objects. + */ + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + unsigned pageSize = getpagesize(); + + if (!buf) + return NULL; + + if ((alignment > pageSize) && (alignment % pageSize)) { + free(buf); + return NULL; + } + + ret = drmBOCreate(pool->fd, size, alignment / pageSize, + NULL, + flags, hint, buf); + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static void * +pool_reference(struct _DriBufferPool *pool, unsigned handle) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + + if (!buf) + return NULL; + + ret = drmBOReference(pool->fd, handle, buf); + + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unreference(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + driReadLockKernelBO(); + ret = drmBOUnreference(pool->fd, buf); + free(buf); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOMap(pool->fd, buf, flags, hint, virtual); + driReadUnlockKernelBO(); + return ret; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOUnmap(pool->fd, buf); + driReadUnlockKernelBO(); + + return ret; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long offset; + + driReadLockKernelBO(); + assert(buf->flags & DRM_BO_FLAG_NO_MOVE); + offset = buf->offset; + driReadUnlockKernelBO(); + + return buf->offset; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + uint64_t flags; + + driReadLockKernelBO(); + flags = buf->flags; + driReadUnlockKernelBO(); + + return flags; +} + + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + unsigned long size; + + driReadLockKernelBO(); + size = buf->size; + driReadUnlockKernelBO(); + + return buf->size; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + /* + * Noop. The kernel handles all fencing. + */ + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + return (drmBO *) private; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex, + int lazy) +{ + drmBO *buf = (drmBO *) private; + int ret; + + driReadLockKernelBO(); + ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); + driReadUnlockKernelBO(); + + return ret; +} + + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + +/*static int +pool_setStatus(struct _DriBufferPool *pool, void *private, + uint64_t flag_diff, uint64_t old_flags) +{ + drmBO *buf = (drmBO *) private; + uint64_t new_flags = old_flags ^ flag_diff; + int ret; + + driReadLockKernelBO(); + ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff, + 0, 0, 0); + driReadUnlockKernelBO(); + return ret; +}*/ + +struct _DriBufferPool * +driDRMPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->reference = &pool_reference; + pool->unreference = &pool_unreference; + pool->data = NULL; + return pool; +} diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c b/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c new file mode 100644 index 0000000000..b56bc269da --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.c @@ -0,0 +1,377 @@ +#include "ws_dri_fencemgr.h" +#include "glthread.h" +#include +#include +#include + +/* + * Note: Locking order is + * _DriFenceObject::mutex + * _DriFenceMgr::mutex + */ + +struct _DriFenceMgr { + /* + * Constant members. Need no mutex protection. + */ + struct _DriFenceMgrCreateInfo info; + void *private; + + /* + * These members are protected by this->mutex + */ + _glthread_Mutex mutex; + int refCount; + drmMMListHead *heads; + int num_fences; +}; + +struct _DriFenceObject { + + /* + * These members are constant and need no mutex protection. + */ + struct _DriFenceMgr *mgr; + uint32_t fence_class; + uint32_t fence_type; + + /* + * These members are protected by mgr->mutex. + */ + drmMMListHead head; + int refCount; + + /* + * These members are protected by this->mutex. + */ + _glthread_Mutex mutex; + uint32_t signaled_type; + void *private; +}; + +uint32_t +driFenceType(struct _DriFenceObject *fence) +{ + return fence->fence_type; +} + +struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info) +{ + struct _DriFenceMgr *tmp; + uint32_t i; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->refCount = 1; + tmp->info = *info; + tmp->num_fences = 0; + tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads)); + if (!tmp->heads) + goto out_err; + + for (i=0; iinfo.num_classes; ++i) { + DRMINITLISTHEAD(&tmp->heads[i]); + } + _glthread_UNLOCK_MUTEX(tmp->mutex); + return tmp; + + out_err: + if (tmp) + free(tmp); + return NULL; +} + +static void +driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr) +{ + struct _DriFenceMgr *mgr = *pMgr; + + *pMgr = NULL; + if (--mgr->refCount == 0) + free(mgr); + else + _glthread_UNLOCK_MUTEX(mgr->mutex); +} + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr) +{ + _glthread_LOCK_MUTEX((*pMgr)->mutex); + driFenceMgrUnrefUnlock(pMgr); +} + +static void +driFenceUnReferenceLocked(struct _DriFenceObject **pFence) +{ + struct _DriFenceObject *fence = *pFence; + struct _DriFenceMgr *mgr = fence->mgr; + + *pFence = NULL; + if (--fence->refCount == 0) { + DRMLISTDELINIT(&fence->head); + if (fence->private) + mgr->info.unreference(mgr, &fence->private); + --mgr->num_fences; + fence->mgr = NULL; + --mgr->refCount; + free(fence); + + } +} + + +static void +driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr, + drmMMListHead *list, + uint32_t fence_class, + uint32_t fence_type) +{ + struct _DriFenceObject *entry; + drmMMListHead *prev; + + while(list != &mgr->heads[fence_class]) { + entry = DRMLISTENTRY(struct _DriFenceObject, list, head); + + /* + * Up refcount so that entry doesn't disappear from under us + * when we unlock-relock mgr to get the correct locking order. + */ + + ++entry->refCount; + _glthread_UNLOCK_MUTEX(mgr->mutex); + _glthread_LOCK_MUTEX(entry->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + + prev = list->prev; + + + + if (list->prev == list) { + + /* + * Somebody else removed the entry from the list. + */ + + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + return; + } + + entry->signaled_type |= (fence_type & entry->fence_type); + if (entry->signaled_type == entry->fence_type) { + DRMLISTDELINIT(list); + mgr->info.unreference(mgr, &entry->private); + } + _glthread_UNLOCK_MUTEX(entry->mutex); + driFenceUnReferenceLocked(&entry); + list = prev; + } +} + + +int +driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint) +{ + struct _DriFenceMgr *mgr = fence->mgr; + int ret = 0; + + _glthread_LOCK_MUTEX(fence->mutex); + + if ((fence->signaled_type & fence_type) == fence_type) + goto out0; + + ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint); + if (ret) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + fence_type); + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence) +{ + uint32_t ret; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = fence->signaled_type; + _glthread_UNLOCK_MUTEX(fence->mutex); + + return ret; +} + +int +driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type, + uint32_t *signaled) +{ + int ret = 0; + struct _DriFenceMgr *mgr; + + _glthread_LOCK_MUTEX(fence->mutex); + mgr = fence->mgr; + *signaled = fence->signaled_type; + if ((fence->signaled_type & flush_type) == flush_type) + goto out0; + + ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled); + if (ret) { + *signaled = fence->signaled_type; + goto out0; + } + + if ((fence->signaled_type | *signaled) == fence->signaled_type) + goto out0; + + _glthread_LOCK_MUTEX(mgr->mutex); + _glthread_UNLOCK_MUTEX(fence->mutex); + + driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class, + *signaled); + + _glthread_UNLOCK_MUTEX(mgr->mutex); + return 0; + out0: + _glthread_UNLOCK_MUTEX(fence->mutex); + return ret; +} + +struct _DriFenceObject * +driFenceReference(struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(fence->mgr->mutex); + ++fence->refCount; + _glthread_UNLOCK_MUTEX(fence->mgr->mutex); + return fence; +} + +void +driFenceUnReference(struct _DriFenceObject **pFence) +{ + struct _DriFenceMgr *mgr; + + if (*pFence == NULL) + return; + + mgr = (*pFence)->mgr; + _glthread_LOCK_MUTEX(mgr->mutex); + ++mgr->refCount; + driFenceUnReferenceLocked(pFence); + driFenceMgrUnrefUnlock(&mgr); +} + +struct _DriFenceObject +*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class, + uint32_t fence_type, void *private, size_t private_size) +{ + struct _DriFenceObject *fence; + size_t fence_size = sizeof(*fence); + + if (private_size) + fence_size = ((fence_size + 15) & ~15); + + fence = calloc(1, fence_size + private_size); + + if (!fence) { + int ret = mgr->info.finish(mgr, private, fence_type, 0); + + if (ret) + usleep(10000000); + + return NULL; + } + + _glthread_INIT_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(fence->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); + fence->refCount = 1; + DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]); + fence->mgr = mgr; + ++mgr->refCount; + ++mgr->num_fences; + _glthread_UNLOCK_MUTEX(mgr->mutex); + fence->fence_class = fence_class; + fence->fence_type = fence_type; + fence->signaled_type = 0; + fence->private = private; + if (private_size) { + fence->private = (void *)(((uint8_t *) fence) + fence_size); + memcpy(fence->private, private, private_size); + } + + _glthread_UNLOCK_MUTEX(fence->mutex); + return fence; +} + + +static int +tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type) +{ + long fd = (long) mgr->private; + int dummy; + drmFence *fence = (drmFence *) private; + int ret; + + *signaled_type = 0; + ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy); + if (ret) + return ret; + + *signaled_type = fence->signaled; + + return 0; +} + +static int +tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, + int lazy_hint) +{ + long fd = (long) mgr->private; + unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0; + + return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type); +} + +static int +tUnref(struct _DriFenceMgr *mgr, void **private) +{ + long fd = (long) mgr->private; + drmFence *fence = (drmFence *) *private; + *private = NULL; + + return drmFenceUnreference(fd, fence); +} + +struct _DriFenceMgr *driFenceMgrTTMInit(int fd) +{ + struct _DriFenceMgrCreateInfo info; + struct _DriFenceMgr *mgr; + + info.flags = DRI_FENCE_CLASS_ORDERED; + info.num_classes = 4; + info.signaled = tSignaled; + info.finish = tFinish; + info.unreference = tUnref; + + mgr = driFenceMgrCreate(&info); + if (mgr == NULL) + return NULL; + + mgr->private = (void *) (long) fd; + return mgr; +} + diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.h b/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.h new file mode 100644 index 0000000000..4ea58dfe18 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_fencemgr.h @@ -0,0 +1,115 @@ +#ifndef DRI_FENCEMGR_H +#define DRI_FENCEMGR_H + +#include +#include + +struct _DriFenceObject; +struct _DriFenceMgr; + +/* + * Do a quick check to see if the fence manager has registered the fence + * object as signaled. Note that this function may return a false negative + * answer. + */ +extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence); + +/* + * Check if the fence object is signaled. This function can be substantially + * more expensive to call than the above function, but will not return a false + * negative answer. The argument "flush_type" sets the types that the + * underlying mechanism must make sure will eventually signal. + */ +extern int driFenceSignaledType(struct _DriFenceObject *fence, + uint32_t flush_type, uint32_t *signaled); + +/* + * Convenience functions. + */ + +static inline int driFenceSignaled(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types; + int ret = driFenceSignaledType(fence, flush_type, &signaled_types); + if (ret) + return 0; + return ((signaled_types & flush_type) == flush_type); +} + +static inline int driFenceSignaledCached(struct _DriFenceObject *fence, + uint32_t flush_type) +{ + uint32_t signaled_types = + driFenceSignaledTypeCached(fence); + + return ((signaled_types & flush_type) == flush_type); +} + +/* + * Reference a fence object. + */ +extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); + +/* + * Unreference a fence object. The fence object pointer will be reset to NULL. + */ + +extern void driFenceUnReference(struct _DriFenceObject **pFence); + + +/* + * Wait for a fence to signal the indicated fence_type. + * If "lazy_hint" is true, it indicates that the wait may sleep to avoid + * busy-wait polling. + */ +extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type, + int lazy_hint); + +/* + * Create a DriFenceObject for manager "mgr". + * + * "private" is a pointer that should be used for the callbacks in + * struct _DriFenceMgrCreateInfo. + * + * if private_size is nonzero, then the info stored at *private, with size + * private size will be copied and the fence manager will instead use a + * pointer to the copied data for the callbacks in + * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by + * "private" may be destroyed after the call to driFenceCreate. + */ +extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr, + uint32_t fence_class, + uint32_t fence_type, + void *private, + size_t private_size); + +extern uint32_t driFenceType(struct _DriFenceObject *fence); + +/* + * Fence creations are ordered. If a fence signals a fence_type, + * it is safe to assume that all fences of the same class that was + * created before that fence has signaled the same type. + */ + +#define DRI_FENCE_CLASS_ORDERED (1 << 0) + +struct _DriFenceMgrCreateInfo { + uint32_t flags; + uint32_t num_classes; + int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type, + uint32_t *signaled_type); + int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint); + int (*unreference) (struct _DriFenceMgr *mgr, void **private); +}; + +extern struct _DriFenceMgr * +driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info); + +void +driFenceMgrUnReference(struct _DriFenceMgr **pMgr); + +extern struct _DriFenceMgr * +driFenceMgrTTMInit(int fd); + +#endif diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c b/src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c new file mode 100644 index 0000000000..a80555c9c7 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_mallocpool.c @@ -0,0 +1,161 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "pipe/p_debug.h" +#include "glthread.h" +#include "ws_dri_bufpool.h" +#include "ws_dri_bufmgr.h" + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, uint64_t flags, unsigned hint, + unsigned alignment) +{ + unsigned long *private = malloc(size + 2*sizeof(unsigned long)); + if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL) + abort(); + + *private = size; + return (void *)private; +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + free(private); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + *virtual = (void *)((unsigned long *)private + 2); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); + return 0UL; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + /* + * BUG + */ + abort(); +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + return *(unsigned long *) private; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + abort(); + return 0UL; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + abort(); + return NULL; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + + +struct _DriBufferPool * +driMallocPoolInit(void) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = NULL; + pool->fd = -1; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->poolOffset = &pool_poolOffset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c b/src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c new file mode 100644 index 0000000000..dfcf6d6b19 --- /dev/null +++ b/src/gallium/winsys/drm/intel/common/ws_dri_slabpool.c @@ -0,0 +1,968 @@ +/************************************************************************** + * + * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellstrom + */ + +#include +#include +#include +#include +#include +#include "ws_dri_bufpool.h" +#include "ws_dri_fencemgr.h" +#include "ws_dri_bufmgr.h" +#include "glthread.h" + +#define DRI_SLABPOOL_ALLOC_RETRIES 100 + +struct _DriSlab; + +struct _DriSlabBuffer { + int isSlabBuffer; + drmBO *bo; + struct _DriFenceObject *fence; + struct _DriSlab *parent; + drmMMListHead head; + uint32_t mapCount; + uint32_t start; + uint32_t fenceType; + int unFenced; + _glthread_Cond event; +}; + +struct _DriKernelBO { + int fd; + drmBO bo; + drmMMListHead timeoutHead; + drmMMListHead head; + struct timeval timeFreed; + uint32_t pageAlignment; + void *virtual; +}; + +struct _DriSlab{ + drmMMListHead head; + drmMMListHead freeBuffers; + uint32_t numBuffers; + uint32_t numFree; + struct _DriSlabBuffer *buffers; + struct _DriSlabSizeHeader *header; + struct _DriKernelBO *kbo; +}; + + +struct _DriSlabSizeHeader { + drmMMListHead slabs; + drmMMListHead freeSlabs; + drmMMListHead delayedBuffers; + uint32_t numDelayed; + struct _DriSlabPool *slabPool; + uint32_t bufSize; + _glthread_Mutex mutex; +}; + +struct _DriFreeSlabManager { + struct timeval slabTimeout; + struct timeval checkInterval; + struct timeval nextCheck; + drmMMListHead timeoutList; + drmMMListHead unCached; + drmMMListHead cached; + _glthread_Mutex mutex; +}; + + +struct _DriSlabPool { + + /* + * The data of this structure remains constant after + * initialization and thus needs no mutex protection. + */ + + struct _DriFreeSlabManager *fMan; + uint64_t proposedFlags; + uint64_t validMask; + uint32_t *bucketSizes; + uint32_t numBuckets; + uint32_t pageSize; + int fd; + int pageAlignment; + int maxSlabSize; + int desiredNumBuffers; + struct _DriSlabSizeHeader *headers; +}; + +/* + * FIXME: Perhaps arrange timeout slabs in size buckets for fast + * retreival?? + */ + + +static inline int +driTimeAfterEq(struct timeval *arg1, struct timeval *arg2) +{ + return ((arg1->tv_sec > arg2->tv_sec) || + ((arg1->tv_sec == arg2->tv_sec) && + (arg1->tv_usec > arg2->tv_usec))); +} + +static inline void +driTimeAdd(struct timeval *arg, struct timeval *add) +{ + unsigned int sec; + + arg->tv_sec += add->tv_sec; + arg->tv_usec += add->tv_usec; + sec = arg->tv_usec / 1000000; + arg->tv_sec += sec; + arg->tv_usec -= sec*1000000; +} + +static void +driFreeKernelBO(struct _DriKernelBO *kbo) +{ + if (!kbo) + return; + + (void) drmBOUnreference(kbo->fd, &kbo->bo); + free(kbo); +} + + +static void +driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan, + struct timeval *time) +{ + drmMMListHead *list, *next; + struct _DriKernelBO *kbo; + + if (!driTimeAfterEq(time, &fMan->nextCheck)) + return; + + for (list = fMan->timeoutList.next, next = list->next; + list != &fMan->timeoutList; + list = next, next = list->next) { + + kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead); + + if (!driTimeAfterEq(time, &kbo->timeFreed)) + break; + + DRMLISTDELINIT(&kbo->timeoutHead); + DRMLISTDELINIT(&kbo->head); + driFreeKernelBO(kbo); + } + + fMan->nextCheck = *time; + driTimeAdd(&fMan->nextCheck, &fMan->checkInterval); +} + + +/* + * Add a _DriKernelBO to the free slab manager. + * This means that it is available for reuse, but if it's not + * reused in a while, it will be freed. + */ + +static void +driSetKernelBOFree(struct _DriFreeSlabManager *fMan, + struct _DriKernelBO *kbo) +{ + struct timeval time; + + _glthread_LOCK_MUTEX(fMan->mutex); + gettimeofday(&time, NULL); + driTimeAdd(&time, &fMan->slabTimeout); + + kbo->timeFreed = time; + + if (kbo->bo.flags & DRM_BO_FLAG_CACHED) + DRMLISTADD(&kbo->head, &fMan->cached); + else + DRMLISTADD(&kbo->head, &fMan->unCached); + + DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList); + driFreeTimeoutKBOsLocked(fMan, &time); + + _glthread_UNLOCK_MUTEX(fMan->mutex); +} + +/* + * Get a _DriKernelBO for us to use as storage for a slab. + * + */ + +static struct _DriKernelBO * +driAllocKernelBO(struct _DriSlabSizeHeader *header) + +{ + struct _DriSlabPool *slabPool = header->slabPool; + struct _DriFreeSlabManager *fMan = slabPool->fMan; + drmMMListHead *list, *next, *head; + uint32_t size = header->bufSize * slabPool->desiredNumBuffers; + struct _DriKernelBO *kbo; + struct _DriKernelBO *kboTmp; + int ret; + + /* + * FIXME: We should perhaps allow some variation in slabsize in order + * to efficiently reuse slabs. + */ + + size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize; + size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1); + _glthread_LOCK_MUTEX(fMan->mutex); + + kbo = NULL; + + retry: + head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ? + &fMan->cached : &fMan->unCached; + + for (list = head->next, next = list->next; + list != head; + list = next, next = list->next) { + + kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head); + + if ((kboTmp->bo.size == size) && + (slabPool->pageAlignment == 0 || + (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) { + + if (!kbo) + kbo = kboTmp; + + if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0) + break; + + } + } + + if (kbo) { + DRMLISTDELINIT(&kbo->head); + DRMLISTDELINIT(&kbo->timeoutHead); + } + + _glthread_UNLOCK_MUTEX(fMan->mutex); + + if (kbo) { + uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags; + + ret = 0; + if (new_mask) { + ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags, + new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0); + } + if (ret == 0) + return kbo; + + driFreeKernelBO(kbo); + kbo = NULL; + goto retry; + } + + kbo = calloc(1, sizeof(struct _DriKernelBO)); + if (!kbo) + return NULL; + + kbo->fd = slabPool->fd; + DRMINITLISTHEAD(&kbo->head); + DRMINITLISTHEAD(&kbo->timeoutHead); + ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL, + slabPool->proposedFlags, + DRM_BO_HINT_DONT_FENCE, &kbo->bo); + if (ret) + goto out_err0; + + ret = drmBOMap(kbo->fd, &kbo->bo, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &kbo->virtual); + + if (ret) + goto out_err1; + + ret = drmBOUnmap(kbo->fd, &kbo->bo); + if (ret) + goto out_err1; + + return kbo; + + out_err1: + drmBOUnreference(kbo->fd, &kbo->bo); + out_err0: + free(kbo); + return NULL; +} + + +static int +driAllocSlab(struct _DriSlabSizeHeader *header) +{ + struct _DriSlab *slab; + struct _DriSlabBuffer *buf; + uint32_t numBuffers; + int ret; + int i; + + slab = calloc(1, sizeof(*slab)); + if (!slab) + return -ENOMEM; + + slab->kbo = driAllocKernelBO(header); + if (!slab->kbo) { + ret = -ENOMEM; + goto out_err0; + } + + numBuffers = slab->kbo->bo.size / header->bufSize; + + slab->buffers = calloc(numBuffers, sizeof(*slab->buffers)); + if (!slab->buffers) { + ret = -ENOMEM; + goto out_err1; + } + + DRMINITLISTHEAD(&slab->head); + DRMINITLISTHEAD(&slab->freeBuffers); + slab->numBuffers = numBuffers; + slab->numFree = 0; + slab->header = header; + + buf = slab->buffers; + for (i=0; i < numBuffers; ++i) { + buf->parent = slab; + buf->start = i* header->bufSize; + buf->mapCount = 0; + buf->isSlabBuffer = 1; + _glthread_INIT_COND(buf->event); + DRMLISTADDTAIL(&buf->head, &slab->freeBuffers); + slab->numFree++; + buf++; + } + + DRMLISTADDTAIL(&slab->head, &header->slabs); + + return 0; + + out_err1: + driSetKernelBOFree(header->slabPool->fMan, slab->kbo); + free(slab->buffers); + out_err0: + free(slab); + return ret; +} + +/* + * Delete a buffer from the slab header delayed list and put + * it on the slab free list. + */ + +static void +driSlabFreeBufferLocked(struct _DriSlabBuffer *buf) +{ + struct _DriSlab *slab = buf->parent; + struct _DriSlabSizeHeader *header = slab->header; + drmMMListHead *list = &buf->head; + + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &slab->freeBuffers); + slab->numFree++; + + if (slab->head.next == &slab->head) + DRMLISTADDTAIL(&slab->head, &header->slabs); + + if (slab->numFree == slab->numBuffers) { + list = &slab->head; + DRMLISTDEL(list); + DRMLISTADDTAIL(list, &header->freeSlabs); + } + + if (header->slabs.next == &header->slabs || + slab->numFree != slab->numBuffers) { + + drmMMListHead *next; + struct _DriFreeSlabManager *fMan = header->slabPool->fMan; + + for (list = header->freeSlabs.next, next = list->next; + list != &header->freeSlabs; + list = next, next = list->next) { + + slab = DRMLISTENTRY(struct _DriSlab, list, head); + + DRMLISTDELINIT(list); + driSetKernelBOFree(fMan, slab->kbo); + free(slab->buffers); + free(slab); + } + } +} + +static void +driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait) +{ + drmMMListHead *list, *prev, *first; + struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + int firstWasSignaled = 1; + int signaled; + int i; + int ret; + + /* + * Rerun the freeing test if the youngest tested buffer + * was signaled, since there might be more idle buffers + * in the delay list. + */ + + while (firstWasSignaled) { + firstWasSignaled = 0; + signaled = 0; + first = header->delayedBuffers.next; + + /* Only examine the oldest 1/3 of delayed buffers: + */ + if (header->numDelayed > 3) { + for (i = 0; i < header->numDelayed; i += 3) { + first = first->next; + } + } + + for (list = first, prev = list->prev; + list != &header->delayedBuffers; + list = prev, prev = list->prev) { + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + slab = buf->parent; + + if (!signaled) { + if (wait) { + ret = driFenceFinish(buf->fence, buf->fenceType, 0); + if (ret) + break; + signaled = 1; + wait = 0; + } else { + signaled = driFenceSignaled(buf->fence, buf->fenceType); + } + if (signaled) { + if (list == first) + firstWasSignaled = 1; + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) { + driFenceUnReference(&buf->fence); + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + } + } +} + + +static struct _DriSlabBuffer * +driSlabAllocBuffer(struct _DriSlabSizeHeader *header) +{ + static struct _DriSlabBuffer *buf; + struct _DriSlab *slab; + drmMMListHead *list; + int count = DRI_SLABPOOL_ALLOC_RETRIES; + + _glthread_LOCK_MUTEX(header->mutex); + while(header->slabs.next == &header->slabs && count > 0) { + driSlabCheckFreeLocked(header, 0); + if (header->slabs.next != &header->slabs) + break; + + _glthread_UNLOCK_MUTEX(header->mutex); + if (count != DRI_SLABPOOL_ALLOC_RETRIES) + usleep(1); + _glthread_LOCK_MUTEX(header->mutex); + (void) driAllocSlab(header); + count--; + } + + list = header->slabs.next; + if (list == &header->slabs) { + _glthread_UNLOCK_MUTEX(header->mutex); + return NULL; + } + slab = DRMLISTENTRY(struct _DriSlab, list, head); + if (--slab->numFree == 0) + DRMLISTDELINIT(list); + + list = slab->freeBuffers.next; + DRMLISTDELINIT(list); + + _glthread_UNLOCK_MUTEX(header->mutex); + buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head); + return buf; +} + +static void * +pool_create(struct _DriBufferPool *driPool, unsigned long size, + uint64_t flags, unsigned hint, unsigned alignment) +{ + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + struct _DriSlabSizeHeader *header; + struct _DriSlabBuffer *buf; + void *dummy; + int i; + int ret; + + /* + * FIXME: Check for compatibility. + */ + + header = pool->headers; + for (i=0; inumBuckets; ++i) { + if (header->bufSize >= size) + break; + header++; + } + + if (i < pool->numBuckets) + return driSlabAllocBuffer(header); + + + /* + * Fall back to allocate a buffer object directly from DRM. + * and wrap it in a driBO structure. + */ + + + buf = calloc(1, sizeof(*buf)); + + if (!buf) + return NULL; + + buf->bo = calloc(1, sizeof(*buf->bo)); + if (!buf->bo) + goto out_err0; + + if (alignment) { + if ((alignment < pool->pageSize) && (pool->pageSize % alignment)) + goto out_err1; + if ((alignment > pool->pageSize) && (alignment % pool->pageSize)) + goto out_err1; + } + + ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL, + flags, hint, buf->bo); + if (ret) + goto out_err1; + + ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0, &dummy); + if (ret) + goto out_err2; + + ret = drmBOUnmap(pool->fd, buf->bo); + if (ret) + goto out_err2; + + return buf; + out_err2: + drmBOUnreference(pool->fd, buf->bo); + out_err1: + free(buf->bo); + out_err0: + free(buf); + return NULL; +} + +static int +pool_destroy(struct _DriBufferPool *driPool, void *private) +{ + struct _DriSlabBuffer *buf = + (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data; + int ret; + + ret = drmBOUnreference(pool->fd, buf->bo); + free(buf->bo); + free(buf); + return ret; + } + + slab = buf->parent; + header = slab->header; + + _glthread_LOCK_MUTEX(header->mutex); + buf->unFenced = 0; + buf->mapCount = 0; + + if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) { + DRMLISTADDTAIL(&buf->head, &header->delayedBuffers); + header->numDelayed++; + } else { + if (buf->fence) + driFenceUnReference(&buf->fence); + driSlabFreeBufferLocked(buf); + } + + _glthread_UNLOCK_MUTEX(header->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *driPool, void *private, + _glthread_Mutex *mutex, int lazy) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + while(buf->unFenced) + _glthread_COND_WAIT(buf->event, *mutex); + + if (!buf->fence) + return 0; + + driFenceFinish(buf->fence, buf->fenceType, lazy); + driFenceUnReference(&buf->fence); + + return 0; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, _glthread_Mutex *mutex, void **virtual) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + int busy; + + if (buf->isSlabBuffer) + busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)); + else + busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType); + + + if (busy) { + if (hint & DRM_BO_HINT_DONT_BLOCK) + return -EBUSY; + else { + (void) pool_waitIdle(pool, private, mutex, 0); + } + } + + ++buf->mapCount; + *virtual = (buf->isSlabBuffer) ? + (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) : + (void *) buf->bo->virtual; + + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + --buf->mapCount; + if (buf->mapCount == 0 && buf->isSlabBuffer) + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + struct _DriSlab *slab; + struct _DriSlabSizeHeader *header; + + if (!buf->isSlabBuffer) { + assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return buf->bo->offset; + } + + slab = buf->parent; + header = slab->header; + + (void) header; + assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE); + return slab->kbo->bo.offset + buf->start; +} + +static unsigned long +pool_poolOffset(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return buf->start; +} + +static uint64_t +pool_flags(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return buf->bo->flags; + + return buf->parent->kbo->bo.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + if (!buf->isSlabBuffer) + return buf->bo->size; + + return buf->parent->header->bufSize; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + drmBO *bo; + + if (buf->fence) + driFenceUnReference(&buf->fence); + + buf->fence = driFenceReference(fence); + bo = (buf->isSlabBuffer) ? + &buf->parent->kbo->bo: + buf->bo; + buf->fenceType = bo->fenceFlags; + + buf->unFenced = 0; + _glthread_COND_BROADCAST(buf->event); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private, + _glthread_Mutex *mutex) +{ + struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private; + + if (!buf->isSlabBuffer) + return 0; + + while(buf->mapCount != 0) + _glthread_COND_WAIT(buf->event, *mutex); + + buf->unFenced = 1; + return 0; +} + + +struct _DriFreeSlabManager * +driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec) +{ + struct _DriFreeSlabManager *tmp; + + tmp = calloc(1, sizeof(*tmp)); + if (!tmp) + return NULL; + + _glthread_INIT_MUTEX(tmp->mutex); + _glthread_LOCK_MUTEX(tmp->mutex); + tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000; + tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000; + tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000; + + tmp->checkInterval.tv_usec = checkIntervalMsec*1000; + tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000; + tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000; + + gettimeofday(&tmp->nextCheck, NULL); + driTimeAdd(&tmp->nextCheck, &tmp->checkInterval); + DRMINITLISTHEAD(&tmp->timeoutList); + DRMINITLISTHEAD(&tmp->unCached); + DRMINITLISTHEAD(&tmp->cached); + _glthread_UNLOCK_MUTEX(tmp->mutex); + + return tmp; +} + +void +driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan) +{ + struct timeval time; + + time = fMan->nextCheck; + driTimeAdd(&time, &fMan->checkInterval); + + _glthread_LOCK_MUTEX(fMan->mutex); + driFreeTimeoutKBOsLocked(fMan, &time); + _glthread_UNLOCK_MUTEX(fMan->mutex); + + assert(fMan->timeoutList.next == &fMan->timeoutList); + assert(fMan->unCached.next == &fMan->unCached); + assert(fMan->cached.next == &fMan->cached); + + free(fMan); +} + +static void +driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size, + struct _DriSlabSizeHeader *header) +{ + _glthread_INIT_MUTEX(header->mutex); + _glthread_LOCK_MUTEX(header->mutex); + + DRMINITLISTHEAD(&header->slabs); + DRMINITLISTHEAD(&header->freeSlabs); + DRMINITLISTHEAD(&header->delayedBuffers); + + header->numDelayed = 0; + header->slabPool = pool; + header->bufSize = size; + + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +driFinishSizeHeader(struct _DriSlabSizeHeader *header) +{ + drmMMListHead *list, *next; + struct _DriSlabBuffer *buf; + + _glthread_LOCK_MUTEX(header->mutex); + for (list = header->delayedBuffers.next, next = list->next; + list != &header->delayedBuffers; + list = next, next = list->next) { + + buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head); + if (buf->fence) { + (void) driFenceFinish(buf->fence, buf->fenceType, 0); + driFenceUnReference(&buf->fence); + } + header->numDelayed--; + driSlabFreeBufferLocked(buf); + } + _glthread_UNLOCK_MUTEX(header->mutex); +} + +static void +pool_takedown(struct _DriBufferPool *driPool) +{ + struct _DriSlabPool *pool = driPool->data; + int i; + + for (i=0; inumBuckets; ++i) { + driFinishSizeHeader(&pool->headers[i]); + } + + free(pool->headers); + free(pool->bucketSizes); + free(pool); + free(driPool); +} + +struct _DriBufferPool * +driSlabPoolInit(int fd, uint64_t flags, + uint64_t validMask, + uint32_t smallestSize, + uint32_t numSizes, + uint32_t desiredNumBuffers, + uint32_t maxSlabSize, + uint32_t pageAlignment, + struct _DriFreeSlabManager *fMan) +{ + struct _DriBufferPool *driPool; + struct _DriSlabPool *pool; + uint32_t i; + + driPool = calloc(1, sizeof(*driPool)); + if (!driPool) + return NULL; + + pool = calloc(1, sizeof(*pool)); + if (!pool) + goto out_err0; + + pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes)); + if (!pool->bucketSizes) + goto out_err1; + + pool->headers = calloc(numSizes, sizeof(*pool->headers)); + if (!pool->headers) + goto out_err2; + + pool->fMan = fMan; + pool->proposedFlags = flags; + pool->validMask = validMask; + pool->numBuckets = numSizes; + pool->pageSize = getpagesize(); + pool->fd = fd; + pool->pageAlignment = pageAlignment; + pool->maxSlabSize = maxSlabSize; + pool->desiredNumBuffers = desiredNumBuffers; + + for (i=0; inumBuckets; ++i) { + pool->bucketSizes[i] = (smallestSize << i); + driInitSizeHeader(pool, pool->bucketSizes[i], + &pool->headers[i]); + } + + driPool->data = (void *) pool; + driPool->map = &pool_map; + driPool->unmap = &pool_unmap; + driPool->destroy = &pool_destroy; + driPool->offset = &pool_offset; + driPool->poolOffset = &pool_poolOffset; + driPool->flags = &pool_flags; + driPool->size = &pool_size; + driPool->create = &pool_create; + driPool->fence = &pool_fence; + driPool->kernel = &pool_kernel; + driPool->validate = &pool_validate; + driPool->waitIdle = &pool_waitIdle; + driPool->takeDown = &pool_takedown; + + return driPool; + + out_err2: + free(pool->bucketSizes); + out_err1: + free(pool); + out_err0: + free(driPool); + + return NULL; +} diff --git a/src/gallium/winsys/drm/intel/dri/Makefile b/src/gallium/winsys/drm/intel/dri/Makefile new file mode 100644 index 0000000000..2046441a22 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/Makefile @@ -0,0 +1,33 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +LIBNAME = i915_dri.so +LIBNAME_EGL = egl_i915_dri.so + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + ../common/libinteldrm.a \ + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a + + +DRIVER_SOURCES = \ + intel_winsys_softpipe.c \ + intel_swapbuffers.c \ + intel_context.c \ + intel_lock.c \ + intel_screen.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I../common $(shell pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") + +include ../../Makefile.template + +#intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c + +symlinks: diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript new file mode 100644 index 0000000000..6a4f50afcc --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/SConscript @@ -0,0 +1,41 @@ +Import('*') + +if 'mesa' in env['statetrackers']: + + env = drienv.Clone() + + env.Append(CPPPATH = [ + '../intel', + 'server' + ]) + + #MINIGLX_SOURCES = server/intel_dri.c + + DRIVER_SOURCES = [ + 'intel_winsys_pipe.c', + 'intel_winsys_softpipe.c', + 'intel_winsys_i915.c', + 'intel_batchbuffer.c', + 'intel_swapbuffers.c', + 'intel_context.c', + 'intel_lock.c', + 'intel_screen.c', + 'intel_batchpool.c', + ] + + sources = \ + COMMON_GALLIUM_SOURCES + \ + COMMON_BM_SOURCES + \ + DRIVER_SOURCES + + drivers = [ + softpipe, + i915simple + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='i915tex_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/winsys/drm/intel/dri/intel_batchbuffer.h b/src/gallium/winsys/drm/intel/dri/intel_batchbuffer.h new file mode 100644 index 0000000000..3e95326168 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_batchbuffer.h @@ -0,0 +1,24 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "intel_be_batchbuffer.h" + +/* + * Need to redefine the BATCH defines + */ + +#undef BEGIN_BATCH +#define BEGIN_BATCH(dwords, relocs) \ + (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) + +#undef OUT_BATCH +#define OUT_BATCH(d) \ + i915_batchbuffer_dword(&intel->base.batch->base, d) + +#undef OUT_RELOC +#define OUT_RELOC(buf,flags,mask,delta) do { \ + assert((delta) >= 0); \ + intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ +} while (0) + +#endif diff --git a/src/gallium/winsys/drm/intel/dri/intel_context.c b/src/gallium/winsys/drm/intel/dri/intel_context.c new file mode 100644 index 0000000000..97ef731aaa --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_context.c @@ -0,0 +1,337 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "i830_dri.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" +#include "intel_batchbuffer.h" +#include "intel_winsys_softpipe.h" + +#include "i915simple/i915_screen.h" + +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" + +#include "utils.h" + + +#ifdef DEBUG +int __intel_debug = 0; +#endif + + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +/** + * Extension strings exported by the intel driver. + * + * \note + * It appears that ARB_texture_env_crossbar has "disappeared" compared to the + * old i830-specific driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, + {"GL_SGIS_generate_mipmap", NULL }, + {NULL, NULL} +}; + + + +#ifdef DEBUG +static const struct dri_debug_control debug_control[] = { + {"ioctl", DEBUG_IOCTL}, + {"bat", DEBUG_BATCH}, + {"lock", DEBUG_LOCK}, + {"swap", DEBUG_SWAP}, + {NULL, 0} +}; +#endif + + + +static void +intel_lock_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + LOCK_HARDWARE(intel); +} + +static void +intel_unlock_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + UNLOCK_HARDWARE(intel); +} + +static boolean +intel_locked_hardware(struct intel_be_context *context) +{ + struct intel_context *intel = (struct intel_context *)context; + return intel->locked ? TRUE : FALSE; +} + +GLboolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct intel_context *intel = CALLOC_STRUCT(intel_context); + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *saPriv = intelScreen->sarea; + int fthrottle_mode; + GLboolean havePools; + struct pipe_context *pipe; + struct st_context *st_share = NULL; + + if (sharedContextPrivate) { + st_share = ((struct intel_context *) sharedContextPrivate)->st; + } + + driContextPriv->driverPrivate = intel; + intel->intelScreen = intelScreen; + intel->driScreen = sPriv; + intel->sarea = saPriv; + + driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i915"); + + + /* + * memory pools + */ + DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + // ZZZ JB should be per screen and not be done per context + havePools = intelCreatePools(sPriv); + DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext); + if (!havePools) + return GL_FALSE; + + + /* Dri stuff */ + intel->hHWContext = driContextPriv->hHWContext; + intel->driFd = sPriv->fd; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + + fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); + intel->iw.irq_seq = -1; + intel->irqsEmitted = 0; + + intel->last_swap_fence = NULL; + intel->first_swap_fence = NULL; + +#ifdef DEBUG + __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); +#endif + intel->base.hardware_lock = intel_lock_hardware; + intel->base.hardware_unlock = intel_unlock_hardware; + intel->base.hardware_locked = intel_locked_hardware; + + intel_be_init_context(&intel->base, &intelScreen->base); + + /* + * Pipe-related setup + */ + if (getenv("INTEL_SP")) { + /* use softpipe driver instead of hw */ + pipe = intel_create_softpipe( intel, &intelScreen->base.base ); + } + else { + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q33_G: + case PCI_CHIP_Q35_G: + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + pipe = i915_create_context(intelScreen->base.screen, + &intelScreen->base.base, + &intel->base.base); + break; + default: + fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n", + intel->intelScreen->deviceID, __FUNCTION__); + + pipe = intel_create_softpipe( intel, &intelScreen->base.base ); + break; + } + } + + pipe->priv = intel; + + intel->st = st_create_context(pipe, visual, st_share); + + driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE ); + + return GL_TRUE; +} + + +void +intelDestroyContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + + assert(intel); /* should never be null */ + if (intel) { + st_finish(intel->st); + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + if (intel->first_swap_fence) { + driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = NULL; + } + + if (intel->intelScreen->dummyContext == intel) + intel->intelScreen->dummyContext = NULL; + + st_destroy_context(intel->st); + intel_be_destroy_context(&intel->base); + free(intel); + } +} + + +GLboolean +intelUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = intel_context(driContextPriv); + st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL); + /* XXX make_current(NULL)? */ + return GL_TRUE; +} + + +GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + if (driContextPriv) { + struct intel_context *intel = intel_context(driContextPriv); + struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv); + struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv); + + assert(draw_fb->stfb); + assert(read_fb->stfb); + + /* This is for situations in which we need a rendering context but + * there may not be any currently bound. + */ + intel->intelScreen->dummyContext = intel; + + st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); + + if ((intel->driDrawable != driDrawPriv) || + (intel->lastStamp != driDrawPriv->lastStamp)) { + intel->driDrawable = driDrawPriv; + intelUpdateWindowSize(driDrawPriv); + intel->lastStamp = driDrawPriv->lastStamp; + } + + /* The size of the draw buffer will have been updated above. + * If the readbuffer is a different window, check/update its size now. + */ + if (driReadPriv != driDrawPriv) { + intelUpdateWindowSize(driReadPriv); + } + + } + else { + st_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} diff --git a/src/gallium/winsys/drm/intel/dri/intel_context.h b/src/gallium/winsys/drm/intel/dri/intel_context.h new file mode 100644 index 0000000000..5d22a422af --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_context.h @@ -0,0 +1,164 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_CONTEXT_H +#define INTEL_CONTEXT_H + +#include +#include "drm.h" + +#include "pipe/p_debug.h" + +#include "intel_screen.h" +#include "i915_drm.h" + +#include "intel_be_context.h" + + +struct pipe_context; +struct intel_context; +struct _DriBufferObject; +struct st_context; + + +#define INTEL_MAX_FIXUP 64 + +/** + * Intel rendering context, contains a state tracker and intel-specific info. + */ +struct intel_context +{ + struct intel_be_context base; + struct st_context *st; + + struct _DriFenceObject *last_swap_fence; + struct _DriFenceObject *first_swap_fence; + +// struct intel_batchbuffer *batch; + + boolean locked; + char *prevLockFile; + int prevLockLine; + + uint irqsEmitted; + drm_i915_irq_wait_t iw; + + drm_context_t hHWContext; + drmLock *driHwLock; + int driFd; + + __DRIdrawablePrivate *driDrawable; + __DRIscreenPrivate *driScreen; + struct intel_screen *intelScreen; + drmI830Sarea *sarea; + + uint lastStamp; + + /** + * Configuration cache + */ + driOptionCache optionCache; +}; + + + +/** + * Intel framebuffer. + */ +struct intel_framebuffer +{ + struct st_framebuffer *stfb; + + /* other fields TBD */ + int other; +}; + + + + +/* These are functions now: + */ +void LOCK_HARDWARE( struct intel_context *intel ); +void UNLOCK_HARDWARE( struct intel_context *intel ); + +extern char *__progname; + + + +/* ================================================================ + * Debugging: + */ +#ifdef DEBUG +extern int __intel_debug; + +#define DEBUG_SWAP 0x1 +#define DEBUG_LOCK 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BATCH 0x8 + +#define DBG(flag, ...) do { \ + if (__intel_debug & (DEBUG_##flag)) \ + printf(__VA_ARGS__); \ +} while(0) + +#else +#define DBG(flag, ...) +#endif + + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_Q33_G 0x29D2 + + +/** Cast wrapper */ +static INLINE struct intel_context * +intel_context(__DRIcontextPrivate *driContextPriv) +{ + return (struct intel_context *) driContextPriv->driverPrivate; +} + + +/** Cast wrapper */ +static INLINE struct intel_framebuffer * +intel_framebuffer(__DRIdrawablePrivate * driDrawPriv) +{ + return (struct intel_framebuffer *) driDrawPriv->driverPrivate; +} + + +#endif diff --git a/src/gallium/winsys/drm/intel/dri/intel_lock.c b/src/gallium/winsys/drm/intel/dri/intel_lock.c new file mode 100644 index 0000000000..406284c98f --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_lock.c @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "main/glheader.h" +#include "glapi/glthread.h" +#include +#include "state_tracker/st_public.h" +#include "intel_context.h" +#include "i830_dri.h" + + + +_glthread_DECLARE_STATIC_MUTEX( lockMutex ); + + +static void +intelContendedLock(struct intel_context *intel, uint flags) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIscreenPrivate *sPriv = intel->driScreen; + struct intel_screen *intelScreen = intel_screen(sPriv); + drmI830Sarea *sarea = intel->sarea; + + drmGetLock(intel->driFd, intel->hHWContext, flags); + + DBG(LOCK, "%s - got contended lock\n", __progname); + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + if (dPriv) + DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + + if (sarea->width != intelScreen->front.width || + sarea->height != intelScreen->front.height) { + + intelUpdateScreenRotation(sPriv, sarea); + } +} + + +/* Lock the hardware and validate our state. + */ +void LOCK_HARDWARE( struct intel_context *intel ) +{ + char __ret = 0; + + _glthread_LOCK_MUTEX(lockMutex); + assert(!intel->locked); + + DRM_CAS(intel->driHwLock, intel->hHWContext, + (DRM_LOCK_HELD|intel->hHWContext), __ret); + + if (__ret) + intelContendedLock( intel, 0 ); + + DBG(LOCK, "%s - locked\n", __progname); + + intel->locked = 1; +} + + +/* Unlock the hardware using the global current context + */ +void UNLOCK_HARDWARE( struct intel_context *intel ) +{ + assert(intel->locked); + intel->locked = 0; + + DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); + + _glthread_UNLOCK_MUTEX(lockMutex); + + DBG(LOCK, "%s - unlocked\n", __progname); +} diff --git a/src/gallium/winsys/drm/intel/dri/intel_reg.h b/src/gallium/winsys/drm/intel/dri/intel_reg.h new file mode 100644 index 0000000000..4f33bee438 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_reg.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef _INTEL_REG_H_ +#define _INTEL_REG_H_ + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + +#define MI_BATCH_BUFFER_END (0xA<<23) + + +#endif diff --git a/src/gallium/winsys/drm/intel/dri/intel_screen.c b/src/gallium/winsys/drm/intel/dri/intel_screen.c new file mode 100644 index 0000000000..46d4861e77 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_screen.c @@ -0,0 +1,607 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "utils.h" +#include "vblank.h" +#include "xmlpool.h" + +#include "intel_context.h" +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_swapbuffers.h" + +#include "i830_dri.h" +#include "ws_dri_bufpool.h" + +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_inlines.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_cb_fbo.h" + +static void +intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle); + +static void +intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle) +{ + struct pipe_screen *screen = intelScreen->base.screen; + struct pipe_texture *texture; + struct pipe_texture templat; + struct pipe_surface *surface; + struct pipe_buffer *buffer; + unsigned pitch; + + assert(intelScreen->front.cpp == 4); + + buffer = intel_be_buffer_from_handle(&intelScreen->base, + "front", handle); + + if (!buffer) + return; + + intelScreen->front.buffer = dri_bo(buffer); + + memset(&templat, 0, sizeof(templat)); + templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + templat.target = PIPE_TEXTURE_2D; + templat.last_level = 0; + templat.depth[0] = 1; + templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templat.width[0] = intelScreen->front.width; + templat.height[0] = intelScreen->front.height; + pf_get_block(templat.format, &templat.block); + pitch = intelScreen->front.pitch; + + texture = screen->texture_blanket(screen, + &templat, + &pitch, + buffer); + + /* Unref the buffer we don't need it anyways */ + pipe_buffer_reference(screen->winsys, &buffer, NULL); + + surface = screen->get_tex_surface(screen, + texture, + 0, + 0, + 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + + intelScreen->front.texture = texture; + intelScreen->front.surface = surface; +} + +PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY +// DRI_CONF_FORCE_S3TC_ENABLE(false) + DRI_CONF_ALLOW_LARGE_TEXTURES(1) + DRI_CONF_SECTION_END DRI_CONF_END; + +const uint __driNConfigOptions = 3; + +#ifdef USE_NEW_INTERFACE +static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; +#endif /*USE_NEW_INTERFACE */ + +extern const struct dri_extension card_extensions[]; + + + + +static void +intelPrintDRIInfo(struct intel_screen * intelScreen, + __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) +{ + fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->front.size, intelScreen->front.offset, + intelScreen->front.pitch); + fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); +} + + +#if 0 +static void +intelPrintSAREA(const drmI830Sarea * sarea) +{ + fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, + sarea->height); + fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); + fprintf(stderr, + "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->front_offset, sarea->front_size, + (unsigned) sarea->front_handle); + fprintf(stderr, + "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->back_offset, sarea->back_size, + (unsigned) sarea->back_handle); + fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->depth_offset, sarea->depth_size, + (unsigned) sarea->depth_handle); + fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); + fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); + fprintf(stderr, + "SAREA: rotated offset: 0x%08x size: 0x%x\n", + sarea->rotated_offset, sarea->rotated_size); + fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); +} +#endif + + +/** + * Use the information in the sarea to update the screen parameters + * related to screen rotation. Needs to be called locked. + */ +void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->front.map) { + drmUnmap(intelScreen->front.map, intelScreen->front.size); + intelScreen->front.map = NULL; + } + + if (intelScreen->front.buffer) + driDeleteBuffers(1, &intelScreen->front.buffer); + + intelScreen->front.width = sarea->width; + intelScreen->front.height = sarea->height; + intelScreen->front.offset = sarea->front_offset; + intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp; + intelScreen->front.size = sarea->front_size; + intelScreen->front.handle = sarea->front_handle; + + assert( sarea->front_size >= + intelScreen->front.pitch * intelScreen->front.height ); + +#if 0 /* JB not important */ + if (!sarea->front_handle) + return; + + if (drmMap(sPriv->fd, + sarea->front_handle, + intelScreen->front.size, + (drmAddress *) & intelScreen->front.map) != 0) { + fprintf(stderr, "drmMap(frontbuffer) failed!\n"); + return; + } +#endif + +#if 0 /* JB */ + if (intelScreen->staticPool) { + driGenBuffers(intelScreen->staticPool, "static region", 1, + &intelScreen->front.buffer, 64, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + + driBOSetStatic(intelScreen->front.buffer, + intelScreen->front.offset, + intelScreen->front.pitch * intelScreen->front.height, + intelScreen->front.map, 0); + } +#else + if (intelScreen->base.staticPool) { + if (intelScreen->front.buffer) { + driBOUnReference(intelScreen->front.buffer); + pipe_surface_reference(&intelScreen->front.surface, NULL); + pipe_texture_reference(&intelScreen->front.texture, NULL); + } + intelCreateSurface(intelScreen, &intelScreen->base.base, sarea->front_bo_handle); + } +#endif +} + + +boolean +intelCreatePools(__DRIscreenPrivate * sPriv) +{ + //unsigned batchPoolSize = 1024*1024; + struct intel_screen *intelScreen = intel_screen(sPriv); + + if (intelScreen->havePools) + return GL_TRUE; + + intelScreen->havePools = GL_TRUE; + + intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + return GL_TRUE; +} + +static const char * +intel_get_name( struct pipe_winsys *winsys ) +{ + return "Intel/DRI/ttm"; +} + +/* + * The state tracker (should!) keep track of whether the fake + * frontbuffer has been touched by any rendering since the last time + * we copied its contents to the real frontbuffer. Our task is easy: + */ +static void +intel_flush_frontbuffer( struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ + struct intel_context *intel = (struct intel_context *) context_private; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + intelDisplaySurface(dPriv, surf, NULL); +} + +static boolean +intelInitDriver(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen; + I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; + + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> + getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; + + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { + fprintf(stderr, + "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + + /* Allocate the private area */ + intelScreen = CALLOC_STRUCT(intel_screen); + if (!intelScreen) + return GL_FALSE; + + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + sPriv->private = (void *) intelScreen; + + intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + + gDRIPriv->sarea_priv_offset); + intelScreen->deviceID = gDRIPriv->deviceID; + intelScreen->front.cpp = gDRIPriv->cpp; + intelScreen->drmMinor = sPriv->drmMinor; + + assert(gDRIPriv->bitsPerPixel == 16 || + gDRIPriv->bitsPerPixel == 32); + + intelUpdateScreenRotation(sPriv, intelScreen->sarea); + + if (0) + intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); + + if (glx_enable_extension != NULL) { + (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); + (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); + (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); + } + + intelScreen->base.base.flush_frontbuffer = intel_flush_frontbuffer; + intelScreen->base.base.get_name = intel_get_name; + intel_be_init_device(&intelScreen->base, sPriv->fd, intelScreen->deviceID); + + return GL_TRUE; +} + + +static void +intelDestroyScreen(__DRIscreenPrivate * sPriv) +{ + struct intel_screen *intelScreen = intel_screen(sPriv); + + intel_be_destroy_device(&intelScreen->base); + /* intelUnmapScreenRegions(intelScreen); */ + + FREE(intelScreen); + sPriv->private = NULL; +} + + +/** + * This is called when we need to set up GL rendering to a new X window. + */ +static boolean +intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + const __GLcontextModes * visual, boolean isPixmap) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + driDrawPriv->w, + driDrawPriv->h, + (void*) intelfb); + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + driDrawPriv->driverPrivate = (void *) intelfb; + return GL_TRUE; + } +} + +static void +intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv); + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); +} + + +/** + * Get information about previous buffer swaps. + */ +static int +intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) +{ + if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) + || (sInfo == NULL)) { + return -1; + } + + return 0; +} + + +static void +intelSetTexOffset(__DRIcontext *pDRICtx, int texname, + unsigned long long offset, int depth, uint pitch) +{ + abort(); +#if 0 + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct st_texture_object *stObj = st_texture_object(tObj); + + if (!stObj) + return; + + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); + + stObj->imageOverride = GL_TRUE; + stObj->depthOverride = depth; + stObj->pitchOverride = pitch; + + if (offset) + stObj->textureOffset = offset; +#endif +} + + +static const struct __DriverAPIRec intelAPI = { + .InitDriver = intelInitDriver, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = intelCopySubBuffer, + .setTexOffset = intelSetTexOffset, +}; + + +static __GLcontextModes * +intelFillInModes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, boolean have_back_buffer) +{ + __GLcontextModes *modes; + __GLcontextModes *m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + uint8_t depth_bits_array[3]; + uint8_t stencil_bits_array[3]; + uint8_t msaa_samples_array[1]; + + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + depth_bits_array[2] = depth_bits; + msaa_samples_array[0] = 0; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. It will be a sw fallback, but some apps won't + * care about that. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = 0; + if (depth_bits == 24) + stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; + + stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + if (pixel_bits == 16) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + modes = + (*dri_interface->createContextModes) (num_modes, + sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, msaa_samples_array, 1, GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, msaa_samples_array, 1, GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for (m = modes; m != NULL; m = m->next) { + if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, + __DRIscreen * psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 7, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 7, 0 }; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("i915", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &intelAPI); + + if (psp != NULL) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); + + /* Calling driInitExtensions here, with a NULL context pointer, + * does not actually enable the extensions. It just makes sure + * that all the dispatch offsets for all the extensions that + * *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create + * is called, but we can't enable the extensions until we have a + * context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + } + + return (void *) psp; +} + diff --git a/src/gallium/winsys/drm/intel/dri/intel_screen.h b/src/gallium/winsys/drm/intel/dri/intel_screen.h new file mode 100644 index 0000000000..0bb43a915c --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_screen.h @@ -0,0 +1,122 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _INTEL_SCREEN_H_ +#define _INTEL_SCREEN_H_ + +#include "dri_util.h" +#include "i830_common.h" +#include "xmlconfig.h" +#include "ws_dri_bufpool.h" + +#include "pipe/p_compiler.h" + +#include "intel_be_device.h" + +struct intel_screen +{ + struct intel_be_device base; + + struct { + drm_handle_t handle; + + /* We create a static dri buffer for the frontbuffer. + */ + struct _DriBufferObject *buffer; + struct pipe_surface *surface; + struct pipe_texture *texture; + + char *map; /* memory map */ + int offset; /* from start of video mem, in bytes */ + int pitch; /* row stride, in bytes */ + int width; + int height; + int size; + int cpp; /* for front and back buffers */ + } front; + + int deviceID; + int drmMinor; + + drmI830Sarea *sarea; + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; + + boolean havePools; + + /** + * Temporary(?) context to use for SwapBuffers or other situations in + * which we need a rendering context, but none is currently bound. + */ + struct intel_context *dummyContext; + + /* + * New stuff form the i915tex integration + */ + unsigned batch_id; + + + struct pipe_winsys *winsys; +}; + + + +/** cast wrapper */ +static INLINE struct intel_screen * +intel_screen(__DRIscreenPrivate *sPriv) +{ + return (struct intel_screen *) sPriv->private; +} + + +extern void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); + + +extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); + +extern boolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); + +extern boolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + + +extern boolean +intelCreatePools(__DRIscreenPrivate *sPriv); + +extern boolean +intelCreateContext(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + + +#endif diff --git a/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c new file mode 100644 index 0000000000..8a18bfd9a4 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.c @@ -0,0 +1,261 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_swapbuffers.h" + +#include "intel_reg.h" + +#include "pipe/p_context.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_fbo.h" + +#include "ws_dri_bufmgr.h" +#include "intel_batchbuffer.h" + +/** + * Display a colorbuffer surface in an X window. + * Used for SwapBuffers and flushing front buffer rendering. + * + * \param dPriv the window/drawable to display into + * \param surf the surface to display + * \param rect optional subrect of surface to display (may be NULL). + */ +void +intelDisplaySurface(__DRIdrawablePrivate *dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t *rect) +{ + struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv); + struct intel_context *intel = intelScreen->dummyContext; + + DBG(SWAP, "%s\n", __FUNCTION__); + + if (!intel) { + /* XXX this is where some kind of extra/meta context could be useful */ + return; + } + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE); + driFenceUnReference(&intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + /* if this drawable isn't currently bound the LOCK_HARDWARE done on the + * current context (which is what intelScreenContext should return) might + * not get a contended lock and thus cliprects not updated (tests/manywin) + */ + if (intel_context(dPriv->driContextPriv) != intel) + DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv); + + + if (dPriv && dPriv->numClipRects) { + const int srcWidth = surf->width; + const int srcHeight = surf->height; + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + const int pitch = intelScreen->front.pitch / intelScreen->front.cpp; + const int cpp = intelScreen->front.cpp; + const int srcpitch = surf->stride / cpp; + int BR13, CMD; + int i; + + ASSERT(surf->buffer); + ASSERT(surf->cpp == cpp); + + DBG(SWAP, "screen pitch %d src surface pitch %d\n", + pitch, surf->stride); + + if (cpp == 2) { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + } + else { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + } + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + drm_clip_rect_t sbox; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->front.width || + pbox->y2 > intelScreen->front.height) { + /* invalid cliprect, skip it */ + continue; + } + + box = *pbox; + + if (rect) { + /* intersect cliprect with user-provided src rect */ + drm_clip_rect_t rrect; + + rrect.x1 = dPriv->x + rect->x1; + rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; + rrect.x2 = rect->x2 + rrect.x1; + rrect.y2 = rect->y2 + rrect.y1; + if (rrect.x1 > box.x1) + box.x1 = rrect.x1; + if (rrect.y1 > box.y1) + box.y1 = rrect.y1; + if (rrect.x2 < box.x2) + box.x2 = rrect.x2; + if (rrect.y2 < box.y2) + box.y2 = rrect.y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + /* restrict blit to size of actually rendered area */ + if (box.x2 - box.x1 > srcWidth) + box.x2 = srcWidth + box.x1; + if (box.y2 - box.y1 > srcHeight) + box.y2 = srcHeight + box.y1; + + DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n", + box.x1, box.x2, box.y1, box.y2); + + sbox.x1 = box.x1 - dPriv->x; + sbox.y1 = box.y1 - dPriv->y; + + assert(box.x1 < box.x2); + assert(box.y1 < box.y2); + + /* XXX this could be done with pipe->surface_copy() */ + /* XXX should have its own batch buffer */ + if (!BEGIN_BATCH(8, 2)) { + /* + * Since we share this batch buffer with a context + * we can't flush it since that risks a GPU lockup + */ + assert(0); + continue; + } + + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((box.y1 << 16) | box.x1); + OUT_BATCH((box.y2 << 16) | box.x2); + + OUT_RELOC(intelScreen->front.buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + OUT_BATCH((sbox.y1 << 16) | sbox.x1); + OUT_BATCH((srcpitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + } + + if (intel->first_swap_fence) + driFenceUnReference(&intel->first_swap_fence); + intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch); + } + + UNLOCK_HARDWARE(intel); + + if (intel->lastStamp != dPriv->lastStamp) { + intelUpdateWindowSize(dPriv); + intel->lastStamp = dPriv->lastStamp; + } +} + + + +/** + * This will be called whenever the currently bound window is moved/resized. + */ +void +intelUpdateWindowSize(__DRIdrawablePrivate *dPriv) +{ + struct intel_framebuffer *intelfb = intel_framebuffer(dPriv); + assert(intelfb->stfb); + st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h); +} + + + +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, NULL); + st_notify_swapbuffers_complete(intel_fb->stfb); + } +} + + +/** + * Called via glXCopySubBufferMESA() to copy a subrect of the back + * buffer to the front buffer/screen. + */ +void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv); + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, + ST_SURFACE_BACK_LEFT); + if (back_surf) { + drm_clip_rect_t rect; + rect.x1 = x; + rect.y1 = y; + rect.x2 = w; + rect.y2 = h; + + st_notify_swapbuffers(intel_fb->stfb); + intelDisplaySurface(dPriv, back_surf, &rect); + } +} diff --git a/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.h b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.h new file mode 100644 index 0000000000..46c9bab3af --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_swapbuffers.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_SWAPBUFFERS_H +#define INTEL_SWAPBUFFERS_H + + +struct pipe_surface; + + +extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv, + struct pipe_surface *surf, + const drm_clip_rect_t * rect); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, + int x, int y, int w, int h); + +extern void intelUpdateWindowSize(__DRIdrawablePrivate *dPriv); + + +#endif /* INTEL_SWAPBUFFERS_H */ diff --git a/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c new file mode 100644 index 0000000000..0d98d16cf1 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c @@ -0,0 +1,82 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Keith Whitwell + */ + +#include "intel_context.h" +#include "intel_winsys_softpipe.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_format.h" +#include "softpipe/sp_winsys.h" + + +struct intel_softpipe_winsys { + struct softpipe_winsys sws; + struct intel_context *intel; +}; + +/** + * Return list of surface formats supported by this driver. + */ +static boolean +intel_is_format_supported(struct softpipe_winsys *sws, + enum pipe_format format) +{ + switch(format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: + return TRUE; + default: + return FALSE; + } +} + + +/** + * Create rendering context which uses software rendering. + */ +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ) +{ + struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys ); + struct pipe_screen *screen = softpipe_create_screen(winsys); + + /* Fill in this struct with callbacks that softpipe will need to + * communicate with the window system, buffer manager, etc. + */ + isws->sws.is_format_supported = intel_is_format_supported; + isws->intel = intel; + + /* Create the softpipe context: + */ + return softpipe_create( screen, winsys, &isws->sws ); +} diff --git a/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.h b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.h new file mode 100644 index 0000000000..5fa14cb749 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_SOFTPIPE_H +#define INTEL_SOFTPIPE_H + +struct pipe_winsys; +struct pipe_context; +struct intel_context; + +struct pipe_context * +intel_create_softpipe( struct intel_context *intel, + struct pipe_winsys *winsys ); + +#endif diff --git a/src/gallium/winsys/drm/intel/dri/server/i830_common.h b/src/gallium/winsys/drm/intel/dri/server/i830_common.h new file mode 100644 index 0000000000..3452ddb3c9 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/server/i830_common.h @@ -0,0 +1,255 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. +Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + +#ifndef _I830_COMMON_H_ +#define _I830_COMMON_H_ + + +#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ +#define I830_LOG_MIN_TEX_REGION_SIZE 14 + + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_I830_INIT 0x00 +#define DRM_I830_FLUSH 0x01 +#define DRM_I830_FLIP 0x02 +#define DRM_I830_BATCHBUFFER 0x03 +#define DRM_I830_IRQ_EMIT 0x04 +#define DRM_I830_IRQ_WAIT 0x05 +#define DRM_I830_GETPARAM 0x06 +#define DRM_I830_SETPARAM 0x07 +#define DRM_I830_ALLOC 0x08 +#define DRM_I830_FREE 0x09 +#define DRM_I830_INIT_HEAP 0x0a +#define DRM_I830_CMDBUFFER 0x0b +#define DRM_I830_DESTROY_HEAP 0x0c +#define DRM_I830_SET_VBLANK_PIPE 0x0d +#define DRM_I830_GET_VBLANK_PIPE 0x0e +#define DRM_I830_MMIO 0x10 + +typedef struct { + enum { + I830_INIT_DMA = 0x01, + I830_CLEANUP_DMA = 0x02, + I830_RESUME_DMA = 0x03 + } func; + unsigned int mmio_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; + unsigned int back_pitch; + unsigned int depth_pitch; + unsigned int cpp; + unsigned int chipset; +} drmI830Init; + +typedef struct { + drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; + int last_upload; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int ctxOwner; /* last context to upload state */ + /** Last context that used the buffer manager. */ + int texAge; + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + int perf_boxes; /* performance boxes to be displayed */ + int width, height; /* screen size in pixels */ + + drm_handle_t front_handle; + int front_offset; + int front_size; + + drm_handle_t back_handle; + int back_offset; + int back_size; + + drm_handle_t depth_handle; + int depth_offset; + int depth_size; + + drm_handle_t tex_handle; + int tex_offset; + int tex_size; + int log_tex_granularity; + int pitch; + int rotation; /* 0, 90, 180 or 270 */ + int rotated_offset; + int rotated_size; + int rotated_pitch; + int virtualX, virtualY; + + unsigned int front_tiled; + unsigned int back_tiled; + unsigned int depth_tiled; + unsigned int rotated_tiled; + unsigned int rotated2_tiled; + + int planeA_x; + int planeA_y; + int planeA_w; + int planeA_h; + int planeB_x; + int planeB_y; + int planeB_w; + int planeB_h; + + /* Triple buffering */ + drm_handle_t third_handle; + int third_offset; + int third_size; + unsigned int third_tiled; + + /* buffer object handles for the static buffers. May change + * over the lifetime of the client, though it doesn't in our current + * implementation. + */ + unsigned int front_bo_handle; + unsigned int back_bo_handle; + unsigned int third_bo_handle; + unsigned int depth_bo_handle; +} drmI830Sarea; + +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + + +typedef struct { + int start; /* agp offset */ + int used; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830BatchBuffer; + +typedef struct { + char *buf; /* agp offset */ + int sz; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830CmdBuffer; + +typedef struct { + int *irq_seq; +} drmI830IrqEmit; + +typedef struct { + int irq_seq; +} drmI830IrqWait; + +typedef struct { + int param; + int *value; +} drmI830GetParam; + +#define I830_PARAM_IRQ_ACTIVE 1 +#define I830_PARAM_ALLOW_BATCHBUFFER 2 + +typedef struct { + int param; + int value; +} drmI830SetParam; + +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 +#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 +#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 + + +/* A memory manager for regions of shared memory: + */ +#define I830_MEM_REGION_AGP 1 + +typedef struct { + int region; + int alignment; + int size; + int *region_offset; /* offset from start of fb or agp */ +} drmI830MemAlloc; + +typedef struct { + int region; + int region_offset; +} drmI830MemFree; + +typedef struct { + int region; + int size; + int start; +} drmI830MemInitHeap; + +typedef struct { + int region; +} drmI830MemDestroyHeap; + +#define DRM_I830_VBLANK_PIPE_A 1 +#define DRM_I830_VBLANK_PIPE_B 2 + +typedef struct { + int pipe; +} drmI830VBlankPipe; + +#define MMIO_READ 0 +#define MMIO_WRITE 1 + +#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 +#define MMIO_REGS_IA_VERTICES_COUNT 1 +#define MMIO_REGS_VS_INVOCATION_COUNT 2 +#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 +#define MMIO_REGS_GS_INVOCATION_COUNT 4 +#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 +#define MMIO_REGS_CL_INVOCATION_COUNT 6 +#define MMIO_REGS_PS_INVOCATION_COUNT 7 +#define MMIO_REGS_PS_DEPTH_COUNT 8 + +typedef struct { + unsigned int read_write:1; + unsigned int reg:31; + void __user *data; +} drmI830MMIO; + +#endif /* _I830_DRM_H_ */ diff --git a/src/gallium/winsys/drm/intel/dri/server/i830_dri.h b/src/gallium/winsys/drm/intel/dri/server/i830_dri.h new file mode 100644 index 0000000000..0d514b6c38 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri/server/i830_dri.h @@ -0,0 +1,62 @@ + +#ifndef _I830_DRI_H +#define _I830_DRI_H + +#include "xf86drm.h" +#include "i830_common.h" + +#define I830_MAX_DRAWABLES 256 + +#define I830_MAJOR_VERSION 1 +#define I830_MINOR_VERSION 7 +#define I830_PATCHLEVEL 2 + +#define I830_REG_SIZE 0x80000 + +typedef struct _I830DRIRec { + drm_handle_t regs; + drmSize regsSize; + + drmSize unused1; /* backbufferSize */ + drm_handle_t unused2; /* backbuffer */ + + drmSize unused3; /* depthbufferSize */ + drm_handle_t unused4; /* depthbuffer */ + + drmSize unused5; /* rotatedSize */ + drm_handle_t unused6; /* rotatedbuffer */ + + drm_handle_t unused7; /* textures */ + int unused8; /* textureSize */ + + drm_handle_t unused9; /* agp_buffers */ + drmSize unused10; /* agp_buf_size */ + + int deviceID; + int width; + int height; + int mem; + int cpp; + int bitsPerPixel; + + int unused11[8]; /* was front/back/depth/rotated offset/pitch */ + + int unused12; /* logTextureGranularity */ + int unused13; /* textureOffset */ + + int irq; + int sarea_priv_offset; +} I830DRIRec, *I830DRIPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830ConfigPrivRec, *I830ConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830DRIContextRec, *I830DRIContextPtr; + + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile new file mode 100644 index 0000000000..f0b5a44389 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/Makefile @@ -0,0 +1,28 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +LIBNAME = EGL_i915.so + +PIPE_DRIVERS = \ + $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ + ../common/libinteldrm.a + +DRIVER_SOURCES = \ + intel_swapbuffers.c \ + intel_context.c \ + intel_device.c \ + intel_egl.c + +C_SOURCES = \ + $(COMMON_GALLIUM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I../common $(shell pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") + +include ../../Makefile.template + +symlinks: diff --git a/src/gallium/winsys/drm/intel/egl/SConscript b/src/gallium/winsys/drm/intel/egl/SConscript new file mode 100644 index 0000000000..0ad19d42a8 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/SConscript @@ -0,0 +1,39 @@ +Import('*') + +env = drienv.Clone() + +env.Append(CPPPATH = [ + '../intel', + 'server' +]) + +#MINIGLX_SOURCES = server/intel_dri.c + +DRIVER_SOURCES = [ + 'intel_winsys_pipe.c', + 'intel_winsys_softpipe.c', + 'intel_winsys_i915.c', + 'intel_batchbuffer.c', + 'intel_swapbuffers.c', + 'intel_context.c', + 'intel_lock.c', + 'intel_screen.c', + 'intel_batchpool.c', +] + +sources = \ + COMMON_GALLIUM_SOURCES + \ + COMMON_BM_SOURCES + \ + DRIVER_SOURCES + +drivers = [ + softpipe, + i915simple +] + +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions +env.SharedLibrary( + target ='i915tex_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], +) \ No newline at end of file diff --git a/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h b/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h new file mode 100644 index 0000000000..3e95326168 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h @@ -0,0 +1,24 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "intel_be_batchbuffer.h" + +/* + * Need to redefine the BATCH defines + */ + +#undef BEGIN_BATCH +#define BEGIN_BATCH(dwords, relocs) \ + (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) + +#undef OUT_BATCH +#define OUT_BATCH(d) \ + i915_batchbuffer_dword(&intel->base.batch->base, d) + +#undef OUT_RELOC +#define OUT_RELOC(buf,flags,mask,delta) do { \ + assert((delta) >= 0); \ + intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ +} while (0) + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_context.c b/src/gallium/winsys/drm/intel/egl/intel_context.c new file mode 100644 index 0000000000..927addb834 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_context.c @@ -0,0 +1,242 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "i915simple/i915_screen.h" + +#include "intel_device.h" +#include "intel_context.h" +#include "intel_batchbuffer.h" + +#include "state_tracker/st_public.h" +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "intel_egl.h" +#include "utils.h" + +#ifdef DEBUG +int __intel_debug = 0; +#endif + + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +/** + * Extension strings exported by the intel driver. + * + * \note + * It appears that ARB_texture_env_crossbar has "disappeared" compared to the + * old i830-specific driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, + {"GL_SGIS_generate_mipmap", NULL }, + {NULL, NULL} +}; + + +/* + * Hardware lock functions. + * Doesn't do anything in EGL + */ + +static void +intel_lock_hardware(struct intel_be_context *context) +{ + (void)context; +} + +static void +intel_unlock_hardware(struct intel_be_context *context) +{ + (void)context; +} + +static boolean +intel_locked_hardware(struct intel_be_context *context) +{ + (void)context; + return FALSE; +} + + +/* + * Misc functions. + */ + +int +intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) +{ + struct intel_context *intel = CALLOC_STRUCT(intel_context); + struct intel_device *device = (struct intel_device *)egl_context->device->priv; + struct pipe_context *pipe; + struct st_context *st_share = NULL; + + egl_context->priv = intel; + + intel->intel_device = device; + intel->egl_context = egl_context; + intel->egl_device = egl_context->device; + + intel->base.hardware_lock = intel_lock_hardware; + intel->base.hardware_unlock = intel_unlock_hardware; + intel->base.hardware_locked = intel_locked_hardware; + + intel_be_init_context(&intel->base, &device->base); + +#if 0 + pipe = intel_create_softpipe(intel, screen->winsys); +#else + pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base); +#endif + + pipe->priv = intel; + + intel->st = st_create_context(pipe, visual, st_share); + + device->dummy = intel; + + return TRUE; +} + +int +intel_destroy_context(struct egl_drm_context *egl_context) +{ + struct intel_context *intel = egl_context->priv; + + if (intel->intel_device->dummy == intel) + intel->intel_device->dummy = NULL; + + st_destroy_context(intel->st); + intel_be_destroy_context(&intel->base); + free(intel); + return TRUE; +} + +void +intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read) +{ + if (context) { + struct intel_context *intel = (struct intel_context *)context->priv; + struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; + struct intel_framebuffer *read_fb = (struct intel_framebuffer *)read->priv; + + assert(draw_fb->stfb); + assert(read_fb->stfb); + + st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); + + intel->egl_drawable = draw; + + st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); + + if (draw != read) + st_resize_framebuffer(read_fb->stfb, read->w, read->h); + + } else { + st_make_current(NULL, NULL, NULL); + } +} + +void +intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) +{ + struct intel_device *device = (struct intel_device *)draw->device->priv; + struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; + + if (draw_fb->front_buffer) + driBOUnReference(draw_fb->front_buffer); + + draw_fb->front_buffer = NULL; + draw_fb->front = NULL; + + /* to unbind just call this function with front == NULL */ + if (!front) + return; + + draw_fb->front = front; + + driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); + driBOSetReferenced(draw_fb->front_buffer, front->handle); + + st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); +} diff --git a/src/gallium/winsys/drm/intel/egl/intel_context.h b/src/gallium/winsys/drm/intel/egl/intel_context.h new file mode 100644 index 0000000000..477fdec7f7 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_context.h @@ -0,0 +1,118 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_CONTEXT_H +#define INTEL_CONTEXT_H + +#include "pipe/p_debug.h" +#include "intel_be_context.h" + + +struct st_context; +struct egl_drm_device; +struct egl_drm_context; +struct egl_drm_frontbuffer; + + +/** + * Intel rendering context, contains a state tracker and intel-specific info. + */ +struct intel_context +{ + struct intel_be_context base; + + struct st_context *st; + + struct intel_device *intel_device; + + /* new egl stuff */ + struct egl_drm_device *egl_device; + struct egl_drm_context *egl_context; + struct egl_drm_drawable *egl_drawable; +}; + + + +/** + * Intel framebuffer. + */ +struct intel_framebuffer +{ + struct st_framebuffer *stfb; + + struct intel_device *device; + struct _DriBufferObject *front_buffer; + struct egl_drm_frontbuffer *front; +}; + + + + +/* These are functions now: + */ +void LOCK_HARDWARE( struct intel_context *intel ); +void UNLOCK_HARDWARE( struct intel_context *intel ); + +extern char *__progname; + + + +/* ================================================================ + * Debugging: + */ +#ifdef DEBUG +extern int __intel_debug; + +#define DEBUG_SWAP 0x1 +#define DEBUG_LOCK 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BATCH 0x8 + +#define DBG(flag, ...) do { \ + if (__intel_debug & (DEBUG_##flag)) \ + printf(__VA_ARGS__); \ +} while(0) + +#else +#define DBG(flag, ...) +#endif + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_Q33_G 0x29D2 + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_device.c b/src/gallium/winsys/drm/intel/egl/intel_device.c new file mode 100644 index 0000000000..b9649cbec7 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_device.c @@ -0,0 +1,137 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "utils.h" + +#include "state_tracker/st_public.h" +#include "i915simple/i915_screen.h" + +#include "intel_context.h" +#include "intel_device.h" +#include "intel_batchbuffer.h" +#include "intel_egl.h" + + +extern const struct dri_extension card_extensions[]; + + +int +intel_create_device(struct egl_drm_device *device) +{ + struct intel_device *intel_device; + + /* Allocate the private area */ + intel_device = CALLOC_STRUCT(intel_device); + if (!intel_device) + return FALSE; + + device->priv = (void *)intel_device; + intel_device->device = device; + + intel_device->deviceID = device->deviceID; + + intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID); + + intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID); + + /* hack */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + + return TRUE; +} + +int +intel_destroy_device(struct egl_drm_device *device) +{ + struct intel_device *intel_device = (struct intel_device *)device->priv; + + intel_be_destroy_device(&intel_device->base); + + free(intel_device); + device->priv = NULL; + + return TRUE; +} + +int +intel_create_drawable(struct egl_drm_drawable *drawable, + const __GLcontextModes * visual) +{ + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); + + if (!intelfb) + return GL_FALSE; + + intelfb->device = drawable->device->priv; + + if (visual->redBits == 5) + colorFormat = PIPE_FORMAT_R5G6B5_UNORM; + else + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits == 16) + depthFormat = PIPE_FORMAT_Z16_UNORM; + else if (visual->depthBits == 24) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits == 8) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + intelfb->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + drawable->w, + drawable->h, + (void*) intelfb); + + if (!intelfb->stfb) { + free(intelfb); + return GL_FALSE; + } + + drawable->priv = (void *) intelfb; + return GL_TRUE; +} + +int +intel_destroy_drawable(struct egl_drm_drawable *drawable) +{ + struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; + drawable->priv = NULL; + + assert(intelfb->stfb); + st_unreference_framebuffer(&intelfb->stfb); + free(intelfb); + return TRUE; +} diff --git a/src/gallium/winsys/drm/intel/egl/intel_device.h b/src/gallium/winsys/drm/intel/egl/intel_device.h new file mode 100644 index 0000000000..323a7c2aef --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_device.h @@ -0,0 +1,50 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _INTEL_SCREEN_H_ +#define _INTEL_SCREEN_H_ + +#include "intel_be_device.h" + +#include "pipe/p_compiler.h" + +struct pipe_screen; +struct egl_drm_device; +struct intel_context; + +struct intel_device +{ + struct intel_be_device base; + struct pipe_screen *pipe; + + int deviceID; + struct egl_drm_device *device; + + struct intel_context *dummy; +}; + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.c b/src/gallium/winsys/drm/intel/egl/intel_egl.c new file mode 100644 index 0000000000..b89c5c508a --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_egl.c @@ -0,0 +1,796 @@ + +#include +#include +#include +#include +#include + +#include "eglconfig.h" +#include "eglcontext.h" +#include "egldisplay.h" +#include "egldriver.h" +#include "eglglobals.h" +#include "eglmode.h" +#include "eglscreen.h" +#include "eglsurface.h" +#include "egllog.h" + +#include "intel_egl.h" + +#include "xf86drm.h" +#include "xf86drmMode.h" + +#include "intel_context.h" + +#include "state_tracker/st_public.h" + +#define MAX_SCREENS 16 + +static void +drm_get_device_id(struct egl_drm_device *device) +{ + char path[512]; + FILE *file; + + /* TODO get the real minor */ + int minor = 0; + + snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); + file = fopen(path, "r"); + if (!file) { + _eglLog(_EGL_WARNING, "Could not retrive device ID\n"); + return; + } + + fgets(path, sizeof( path ), file); + sscanf(path, "%x", &device->deviceID); + fclose(file); +} + +static struct egl_drm_device* +egl_drm_create_device(int drmFD) +{ + struct egl_drm_device *device = malloc(sizeof(*device)); + memset(device, 0, sizeof(*device)); + device->drmFD = drmFD; + + device->version = drmGetVersion(device->drmFD); + + drm_get_device_id(device); + + if (!intel_create_device(device)) { + free(device); + return NULL; + } + + return device; +} + +static void +_egl_context_modes_destroy(__GLcontextModes *modes) +{ + _eglLog(_EGL_DEBUG, "%s", __FUNCTION__); + + while (modes) { + __GLcontextModes * const next = modes->next; + free(modes); + modes = next; + } +} +/** + * Create a linked list of 'count' GLcontextModes. + * These are used during the client/server visual negotiation phase, + * then discarded. + */ +static __GLcontextModes * +_egl_context_modes_create(unsigned count, size_t minimum_size) +{ + /* This code copied from libGLX, and modified */ + const size_t size = (minimum_size > sizeof(__GLcontextModes)) + ? minimum_size : sizeof(__GLcontextModes); + __GLcontextModes * head = NULL; + __GLcontextModes ** next; + unsigned i; + + _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size); + + next = & head; + for (i = 0 ; i < count ; i++) { + *next = (__GLcontextModes *) calloc(1, size); + if (*next == NULL) { + _egl_context_modes_destroy(head); + head = NULL; + break; + } + + (*next)->doubleBufferMode = 1; + (*next)->visualID = GLX_DONT_CARE; + (*next)->visualType = GLX_DONT_CARE; + (*next)->visualRating = GLX_NONE; + (*next)->transparentPixel = GLX_NONE; + (*next)->transparentRed = GLX_DONT_CARE; + (*next)->transparentGreen = GLX_DONT_CARE; + (*next)->transparentBlue = GLX_DONT_CARE; + (*next)->transparentAlpha = GLX_DONT_CARE; + (*next)->transparentIndex = GLX_DONT_CARE; + (*next)->xRenderable = GLX_DONT_CARE; + (*next)->fbconfigID = GLX_DONT_CARE; + (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; + (*next)->bindToTextureRgb = GLX_DONT_CARE; + (*next)->bindToTextureRgba = GLX_DONT_CARE; + (*next)->bindToMipmapTexture = GLX_DONT_CARE; + (*next)->bindToTextureTargets = 0; + (*next)->yInverted = GLX_DONT_CARE; + + next = & ((*next)->next); + } + + return head; +} + +struct drm_screen; + +struct drm_driver +{ + _EGLDriver base; /* base class/object */ + + drmModeResPtr res; + + struct drm_screen *screens[MAX_SCREENS]; + size_t count_screens; + + struct egl_drm_device *device; +}; + +struct drm_surface +{ + _EGLSurface base; /* base class/object */ + + struct egl_drm_drawable *drawable; +}; + +struct drm_context +{ + _EGLContext base; /* base class/object */ + + struct egl_drm_context *context; +}; + +struct drm_screen +{ + _EGLScreen base; + + /* currently only support one connector */ + drmModeConnectorPtr connector; + + /* Has this screen been shown */ + int shown; + + /* Surface that is currently attached to this screen */ + struct drm_surface *surf; + + /* backing buffer */ + drmBO buffer; + + /* framebuffer */ + drmModeFBPtr fb; + uint32_t fbID; + + /* crtc and mode used */ + drmModeCrtcPtr crtc; + uint32_t crtcID; + + struct drm_mode_modeinfo *mode; + + /* geometry of the screen */ + struct egl_drm_frontbuffer front; +}; + +static void +drm_update_res(struct drm_driver *drm_drv) +{ + drmModeFreeResources(drm_drv->res); + drm_drv->res = drmModeGetResources(drm_drv->device->drmFD); +} + +static void +drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) +{ + struct drm_mode_modeinfo *m; + int i; + + for (i = 0; i < connector->count_modes; i++) { + m = &connector->modes[i]; + _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); + } +} + + +static EGLBoolean +drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) +{ + _EGLDisplay *disp = _eglLookupDisplay(dpy); + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_screen *screen = NULL; + drmModeConnectorPtr connector = NULL; + drmModeResPtr res = NULL; + unsigned count_connectors = 0; + int num_screens = 0; + + EGLint i; + int fd; + + fd = drmOpen("i915", NULL); + if (fd < 0) { + return EGL_FALSE; + } + + drm_drv->device = egl_drm_create_device(fd); + if (!drm_drv->device) { + drmClose(fd); + return EGL_FALSE; + } + + drm_update_res(drm_drv); + res = drm_drv->res; + if (res) + count_connectors = res->count_connectors; + + for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { + connector = drmModeGetConnector(fd, res->connectors[i]); + + if (!connector) + continue; + + if (connector->connection != DRM_MODE_CONNECTED) { + drmModeFreeConnector(connector); + continue; + } + + screen = malloc(sizeof(struct drm_screen)); + memset(screen, 0, sizeof(*screen)); + screen->connector = connector; + _eglInitScreen(&screen->base); + _eglAddScreen(disp, &screen->base); + drm_add_modes_from_connector(&screen->base, connector); + drm_drv->screens[num_screens++] = screen; + } + drm_drv->count_screens = num_screens; + + /* for now we only have one config */ + _EGLConfig *config = calloc(1, sizeof(*config)); + memset(config, 1, sizeof(*config)); + _eglInitConfig(config, 1); + _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); + _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); + _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); + _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); + _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); + _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24); + _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); + _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); + _eglAddConfig(disp, config); + + drv->Initialized = EGL_TRUE; + + *major = 1; + *minor = 4; + + return EGL_TRUE; +} + +static void +drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + unsigned int i; + + intel_bind_frontbuffer(screen->surf->drawable, NULL); + screen->surf = NULL; + + for (i = 0; i < drm_drv->res->count_crtcs; i++) { + drmModeSetCrtc( + drm_drv->device->drmFD, + drm_drv->res->crtcs[i], + 0, // FD + 0, 0, + NULL, 0, // List of output ids + NULL); + } + + drmModeRmFB(drm_drv->device->drmFD, screen->fbID); + drmModeFreeFB(screen->fb); + screen->fb = NULL; + + drmBOUnreference(drm_drv->device->drmFD, &screen->buffer); + + screen->shown = 0; +} + +static EGLBoolean +drm_terminate(_EGLDriver *drv, EGLDisplay dpy) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_screen *screen; + int i = 0; + + intel_destroy_device(drm_drv->device); + drmFreeVersion(drm_drv->device->version); + + for (i = 0; i < drm_drv->count_screens; i++) { + screen = drm_drv->screens[i]; + + if (screen->shown) + drm_takedown_shown_screen(drv, screen); + + drmModeFreeConnector(screen->connector); + _eglDestroyScreen(&screen->base); + drm_drv->screens[i] = NULL; + } + + drmClose(drm_drv->device->drmFD); + + free(drm_drv->device); + + _eglCleanupDisplay(_eglLookupDisplay(dpy)); + free(drm_drv); + + return EGL_TRUE; +} + + +static struct drm_context * +lookup_drm_context(EGLContext context) +{ + _EGLContext *c = _eglLookupContext(context); + return (struct drm_context *) c; +} + + +static struct drm_surface * +lookup_drm_surface(EGLSurface surface) +{ + _EGLSurface *s = _eglLookupSurface(surface); + return (struct drm_surface *) s; +} + +static struct drm_screen * +lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen) +{ + _EGLScreen *s = _eglLookupScreen(dpy, screen); + return (struct drm_screen *) s; +} + +static __GLcontextModes* +visual_from_config(_EGLConfig *conf) +{ + __GLcontextModes *visual; + (void)conf; + + visual = _egl_context_modes_create(1, sizeof(*visual)); + visual->redBits = 8; + visual->greenBits = 8; + visual->blueBits = 8; + visual->alphaBits = 8; + + visual->rgbBits = 32; + visual->doubleBufferMode = 1; + + visual->depthBits = 24; + visual->haveDepthBuffer = visual->depthBits > 0; + visual->stencilBits = 8; + visual->haveStencilBuffer = visual->stencilBits > 0; + + return visual; +} + + + +static EGLContext +drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_context *c; + struct drm_egl_context *share = NULL; + _EGLConfig *conf; + int i; + int ret; + __GLcontextModes *visual; + struct egl_drm_context *context; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreateContext"); + return EGL_NO_CONTEXT; + } + + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + /* no attribs defined for now */ + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); + return EGL_NO_CONTEXT; + } + } + + c = (struct drm_context *) calloc(1, sizeof(struct drm_context)); + if (!c) + return EGL_NO_CONTEXT; + + _eglInitContext(drv, dpy, &c->base, config, attrib_list); + + context = malloc(sizeof(*context)); + memset(context, 0, sizeof(*context)); + + if (!context) + goto err_c; + + context->device = drm_drv->device; + visual = visual_from_config(conf); + + ret = intel_create_context(context, visual, share); + free(visual); + + if (!ret) + goto err_gl; + + c->context = context; + + /* generate handle and insert into hash table */ + _eglSaveContext(&c->base); + assert(_eglGetContextHandle(&c->base)); + + return _eglGetContextHandle(&c->base); +err_gl: + free(context); +err_c: + free(c); + return EGL_NO_CONTEXT; +} + +static EGLBoolean +drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) +{ + struct drm_context *fc = lookup_drm_context(context); + _eglRemoveContext(&fc->base); + if (fc->base.IsBound) { + fc->base.DeletePending = EGL_TRUE; + } else { + intel_destroy_context(fc->context); + free(fc->context); + free(fc); + } + return EGL_TRUE; +} + + +static EGLSurface +drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) +{ + return EGL_NO_SURFACE; +} + + +static EGLSurface +drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) +{ + return EGL_NO_SURFACE; +} + + +static EGLSurface +drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, + const EGLint *attrib_list) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + int i; + int ret; + int width = -1; + int height = -1; + struct drm_surface *surf = NULL; + struct egl_drm_drawable *drawable = NULL; + __GLcontextModes *visual; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface"); + return EGL_NO_CONTEXT; + } + + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + case EGL_WIDTH: + width = attrib_list[++i]; + break; + case EGL_HEIGHT: + height = attrib_list[++i]; + break; + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } + } + + if (width < 1 || height < 1) { + _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); + return EGL_NO_SURFACE; + } + + surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface)); + if (!surf) + goto err; + + if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list)) + goto err_surf; + + drawable = malloc(sizeof(*drawable)); + memset(drawable, 0, sizeof(*drawable)); + + drawable->w = width; + drawable->h = height; + + visual = visual_from_config(conf); + + drawable->device = drm_drv->device; + ret = intel_create_drawable(drawable, visual); + free(visual); + + if (!ret) + goto err_draw; + + surf->drawable = drawable; + + _eglSaveSurface(&surf->base); + return surf->base.Handle; + +err_draw: + free(drawable); +err_surf: + free(surf); +err: + return EGL_NO_SURFACE; +} + +static EGLSurface +drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, + const EGLint *attrib_list) +{ + EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list); + + return surf; +} + +static struct drm_mode_modeinfo * +drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) +{ + int i; + struct drm_mode_modeinfo *m; + + for (i = 0; i < connector->count_modes; i++) { + m = &connector->modes[i]; + if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) + break; + m = NULL; + } + + return m; +} +static void +draw(size_t x, size_t y, size_t w, size_t h, size_t pitch, size_t v, unsigned int *ptr) +{ + int i, j; + + for (i = x; i < x + w; i++) + for(j = y; j < y + h; j++) + ptr[(i * pitch / 4) + j] = v; + +} + +static void +prettyColors(int fd, unsigned int handle, size_t pitch) +{ + drmBO bo; + unsigned int *ptr; + void *p; + int i; + + drmBOReference(fd, handle, &bo); + drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &p); + ptr = (unsigned int*)p; + + for (i = 0; i < (bo.size / 4); i++) + ptr[i] = 0xFFFFFFFF; + + for (i = 0; i < 4; i++) + draw(i * 40, i * 40, 40, 40, pitch, 0, ptr); + + + draw(200, 100, 40, 40, pitch, 0xff00ff, ptr); + draw(100, 200, 40, 40, pitch, 0xff00ff, ptr); + + drmBOUnmap(fd, &bo); +} + +static EGLBoolean +drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, + EGLScreenMESA screen, + EGLSurface surface, EGLModeMESA m) +{ + struct drm_driver *drm_drv = (struct drm_driver *)drv; + struct drm_surface *surf = lookup_drm_surface(surface); + struct drm_screen *scrn = lookup_drm_screen(dpy, screen); + _EGLMode *mode = _eglLookupMode(dpy, m); + size_t pitch = mode->Width * 4; + size_t size = mode->Height * pitch; + int ret; + unsigned int i,j,k; + + if (scrn->shown) + drm_takedown_shown_screen(drv, scrn); + + ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_NO_EVICT, + DRM_BO_HINT_DONT_FENCE, &scrn->buffer); + + if (ret) + return EGL_FALSE; + + prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); + + ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height, + 32, 32, pitch, + scrn->buffer.handle, + &scrn->fbID); + + if (ret) + goto err_bo; + + scrn->fb = drmModeGetFB(drm_drv->device->drmFD, scrn->fbID); + if (!scrn->fb) + goto err_bo; + + scrn->mode = drm_find_mode(scrn->connector, mode); + if (!scrn->mode) + goto err_fb; + + for (j = 0; j < drm_drv->res->count_connectors; j++) { + drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]); + for (k = 0; k < con->count_encoders; k++) { + drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]); + for (i = 0; i < drm_drv->res->count_crtcs; i++) { + if (enc->possible_crtcs & (1<device->drmFD, + drm_drv->res->crtcs[i], + scrn->fbID, + 0, 0, + &drm_drv->res->connectors[j], 1, + scrn->mode); + /* skip the other crtcs now */ + i = drm_drv->res->count_crtcs; + } + } + } + } + + scrn->front.handle = scrn->buffer.handle; + scrn->front.pitch = pitch; + scrn->front.width = mode->Width; + scrn->front.height = mode->Height; + + scrn->surf = surf; + intel_bind_frontbuffer(surf->drawable, &scrn->front); + + scrn->shown = 1; + + return EGL_TRUE; + +err_fb: + /* TODO remove fb */ + +err_bo: + drmBOUnreference(drm_drv->device->drmFD, &scrn->buffer); + return EGL_FALSE; +} + +static EGLBoolean +drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +{ + struct drm_surface *fs = lookup_drm_surface(surface); + _eglRemoveSurface(&fs->base); + if (fs->base.IsBound) { + fs->base.DeletePending = EGL_TRUE; + } else { + intel_bind_frontbuffer(fs->drawable, NULL); + intel_destroy_drawable(fs->drawable); + free(fs->drawable); + free(fs); + } + return EGL_TRUE; +} + + +static EGLBoolean +drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) +{ + struct drm_surface *readSurf = lookup_drm_surface(read); + struct drm_surface *drawSurf = lookup_drm_surface(draw); + struct drm_context *ctx = lookup_drm_context(context); + EGLBoolean b; + + b = _eglMakeCurrent(drv, dpy, draw, read, context); + if (!b) + return EGL_FALSE; + + if (ctx) { + if (!drawSurf || !readSurf) + return EGL_FALSE; + + intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); + } else { + intel_make_current(NULL, NULL, NULL); + } + + return EGL_TRUE; +} + +static EGLBoolean +drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) +{ + struct drm_surface *surf = lookup_drm_surface(draw); + if (!surf) + return EGL_FALSE; + + /* error checking */ + if (!_eglSwapBuffers(drv, dpy, draw)) + return EGL_FALSE; + + intel_swap_buffers(surf->drawable); + return EGL_TRUE; +} + + +/** + * The bootstrap function. Return a new drm_driver object and + * plug in API functions. + */ +_EGLDriver * +_eglMain(_EGLDisplay *dpy, const char *args) +{ + struct drm_driver *drm; + + drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); + if (!drm) { + return NULL; + } + + /* First fill in the dispatch table with defaults */ + _eglInitDriverFallbacks(&drm->base); + /* then plug in our Drm-specific functions */ + drm->base.API.Initialize = drm_initialize; + drm->base.API.Terminate = drm_terminate; + drm->base.API.CreateContext = drm_create_context; + drm->base.API.MakeCurrent = drm_make_current; + drm->base.API.CreateWindowSurface = drm_create_window_surface; + drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface; + drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface; + drm->base.API.DestroySurface = drm_destroy_surface; + drm->base.API.DestroyContext = drm_destroy_context; + drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa; + drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; + drm->base.API.SwapBuffers = drm_swap_buffers; + + drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; + drm->base.Name = "DRM/Gallium"; + + /* enable supported extensions */ + drm->base.Extensions.MESA_screen_surface = EGL_TRUE; + drm->base.Extensions.MESA_copy_context = EGL_TRUE; + + return &drm->base; +} diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.h b/src/gallium/winsys/drm/intel/egl/intel_egl.h new file mode 100644 index 0000000000..1ee27e0847 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_egl.h @@ -0,0 +1,53 @@ + +#ifndef _INTEL_EGL_H_ +#define _INTEL_EGL_H_ + +#include + +struct egl_drm_device +{ + void *priv; + int drmFD; + + drmVersionPtr version; + int deviceID; +}; + +struct egl_drm_context +{ + void *priv; + struct egl_drm_device *device; +}; + +struct egl_drm_drawable +{ + void *priv; + struct egl_drm_device *device; + size_t h; + size_t w; +}; + +struct egl_drm_frontbuffer +{ + uint32_t handle; + uint32_t pitch; + uint32_t width; + uint32_t height; +}; + +#include "GL/internal/glcore.h" + +int intel_create_device(struct egl_drm_device *device); +int intel_destroy_device(struct egl_drm_device *device); + +int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate); +int intel_destroy_context(struct egl_drm_context *context); + +int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual); +int intel_destroy_drawable(struct egl_drm_drawable *drawable); + +void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read); +void intel_swap_buffers(struct egl_drm_drawable *draw); +void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front); + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_reg.h b/src/gallium/winsys/drm/intel/egl/intel_reg.h new file mode 100644 index 0000000000..4f33bee438 --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_reg.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef _INTEL_REG_H_ +#define _INTEL_REG_H_ + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + +#define MI_BATCH_BUFFER_END (0xA<<23) + + +#endif diff --git a/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c b/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c new file mode 100644 index 0000000000..2edcbc79ff --- /dev/null +++ b/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "intel_device.h" +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" + +#include "pipe/p_context.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_fbo.h" +#include "intel_egl.h" + + +static void +intel_display_surface(struct egl_drm_drawable *draw, + struct pipe_surface *surf); + +void intel_swap_buffers(struct egl_drm_drawable *draw) +{ + struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; + struct pipe_surface *back_surf; + + assert(intel_fb); + assert(intel_fb->stfb); + + back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT); + if (back_surf) { + st_notify_swapbuffers(intel_fb->stfb); + if (intel_fb->front) + intel_display_surface(draw, back_surf); + st_notify_swapbuffers_complete(intel_fb->stfb); + } +} + +static void +intel_display_surface(struct egl_drm_drawable *draw, + struct pipe_surface *surf) +{ + struct intel_context *intel = NULL; + struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; + struct _DriFenceObject *fence; + + //const int srcWidth = surf->width; + //const int srcHeight = surf->height; + + intel = intel_fb->device->dummy; + if (!intel) { + printf("No dummy context\n"); + return; + } + + const int dstWidth = intel_fb->front->width; + const int dstHeight = intel_fb->front->height; + const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp; + + const int cpp = 4;//intel_fb->front->cpp; + const int srcPitch = surf->stride / cpp; + + int BR13, CMD; + //int i; + + BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + + BEGIN_BATCH(8, 2); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((0 << 16) | 0); + OUT_BATCH((dstHeight << 16) | dstWidth); + + OUT_RELOC(intel_fb->front_buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + + OUT_BATCH((0 << 16) | 0); + OUT_BATCH((srcPitch * cpp) & 0xffff); + OUT_RELOC(dri_bo(surf->buffer), + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + fence = intel_be_batchbuffer_flush(intel->base.batch); + driFenceUnReference(&fence); + intel_be_batchbuffer_finish(intel->base.batch); +} diff --git a/src/gallium/winsys/egl_drm/Makefile b/src/gallium/winsys/egl_drm/Makefile deleted file mode 100644 index 4139d9e71f..0000000000 --- a/src/gallium/winsys/egl_drm/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# src/mesa/drivers/egl_drm/Makefile - -TOP = ../../../.. - -include $(TOP)/configs/current - - - -default: $(TOP)/$(LIB_DIR) subdirs - - -$(TOP)/$(LIB_DIR): - -mkdir $(TOP)/$(LIB_DIR) - - -subdirs: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE)) || exit 1 ; \ - fi \ - done - - -install: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE) install) || exit 1 ; \ - fi \ - done - - -clean: - @for dir in $(DRI_DIRS) ; do \ - if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE) clean) ; \ - fi \ - done - -rm -f common/*.o diff --git a/src/gallium/winsys/egl_drm/Makefile.template b/src/gallium/winsys/egl_drm/Makefile.template deleted file mode 100644 index 07abfa53f3..0000000000 --- a/src/gallium/winsys/egl_drm/Makefile.template +++ /dev/null @@ -1,117 +0,0 @@ -# -*-makefile-*- - -MESA_MODULES = \ - $(TOP)/src/mesa/libmesa.a \ - $(GALLIUM_AUXILIARIES) - -COMMON_GALLIUM_SOURCES = \ - $(TOP)/src/mesa/drivers/dri/common/utils.c \ - $(TOP)/src/mesa/drivers/dri/common/vblank.c \ - $(TOP)/src/mesa/drivers/dri/common/dri_util.c \ - $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c - -COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ - $(TOP)/src/mesa/drivers/common/driverfuncs.c \ - $(TOP)/src/mesa/drivers/dri/common/texmem.c \ - $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c - -COMMON_BM_SOURCES = \ - $(TOP)/src/mesa/drivers/dri/common/dri_bufmgr.c \ - $(TOP)/src/mesa/drivers/dri/common/dri_drmpool.c - - -ifeq ($(WINDOW_SYSTEM),dri) -WINOBJ= -WINLIB= -INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) - -OBJECTS = \ - $(C_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) - -else -# miniglx -WINOBJ= -WINLIB=-L$(MESA)/src/glx/mini -MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini -INCLUDES = $(MINIGLX_INCLUDES) \ - $(SHARED_INCLUDES) \ - $(PCIACCESS_CFLAGS) - -OBJECTS = $(C_SOURCES:.c=.o) \ - $(MINIGLX_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) -endif - - -### Include directories -SHARED_INCLUDES = \ - -I. \ - -I$(TOP)/src/mesa/drivers/dri/common \ - -Iserver \ - -I$(TOP)/include \ - -I$(TOP)/include/GL/internal \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/gallium/winsys/common \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/main \ - -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/mesa/math \ - -I$(TOP)/src/mesa/transform \ - -I$(TOP)/src/mesa/shader \ - -I$(TOP)/src/mesa/swrast \ - -I$(TOP)/src/mesa/swrast_setup \ - -I$(TOP)/src/egl/main \ - -I$(TOP)/src/egl/drivers/dri \ - $(LIBDRM_CFLAGS) - - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - - -##### TARGETS ##### - -default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) - - -$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template - $(TOP)/bin/mklib -noprefix -o $@ \ - $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) - - -$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) - $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) - - -depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ - $(ASM_SOURCES) 2> /dev/null - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` `find ../include` - - -# Remove .o and backup files -clean: - -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) - -rm -f depend depend.bak - - -install: $(LIBNAME) - $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) - $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) - - -include depend diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile deleted file mode 100644 index e67b49f3ad..0000000000 --- a/src/gallium/winsys/egl_drm/intel/Makefile +++ /dev/null @@ -1,29 +0,0 @@ - -TOP = ../../../../.. -include $(TOP)/configs/current - -LIBNAME = EGL_i915.so - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ - $(TOP)/src/gallium/winsys/common/intel_drm/libinteldrm.a - -DRIVER_SOURCES = \ - intel_swapbuffers.c \ - intel_context.c \ - intel_device.c \ - intel_egl.c - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - -DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ - && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") - -include ../Makefile.template - -symlinks: diff --git a/src/gallium/winsys/egl_drm/intel/SConscript b/src/gallium/winsys/egl_drm/intel/SConscript deleted file mode 100644 index 0ad19d42a8..0000000000 --- a/src/gallium/winsys/egl_drm/intel/SConscript +++ /dev/null @@ -1,39 +0,0 @@ -Import('*') - -env = drienv.Clone() - -env.Append(CPPPATH = [ - '../intel', - 'server' -]) - -#MINIGLX_SOURCES = server/intel_dri.c - -DRIVER_SOURCES = [ - 'intel_winsys_pipe.c', - 'intel_winsys_softpipe.c', - 'intel_winsys_i915.c', - 'intel_batchbuffer.c', - 'intel_swapbuffers.c', - 'intel_context.c', - 'intel_lock.c', - 'intel_screen.c', - 'intel_batchpool.c', -] - -sources = \ - COMMON_GALLIUM_SOURCES + \ - COMMON_BM_SOURCES + \ - DRIVER_SOURCES - -drivers = [ - softpipe, - i915simple -] - -# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -env.SharedLibrary( - target ='i915tex_dri.so', - source = sources, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], -) \ No newline at end of file diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h deleted file mode 100644 index 1fa2719845..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef INTEL_BATCHBUFFER_H -#define INTEL_BATCHBUFFER_H - -#include "intel_drm/intel_be_batchbuffer.h" - -/* - * Need to redefine the BATCH defines - */ - -#undef BEGIN_BATCH -#define BEGIN_BATCH(dwords, relocs) \ - (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs)) - -#undef OUT_BATCH -#define OUT_BATCH(d) \ - i915_batchbuffer_dword(&intel->base.batch->base, d) - -#undef OUT_RELOC -#define OUT_RELOC(buf,flags,mask,delta) do { \ - assert((delta) >= 0); \ - intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \ -} while (0) - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c deleted file mode 100644 index 927addb834..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_context.c +++ /dev/null @@ -1,242 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "i915simple/i915_screen.h" - -#include "intel_device.h" -#include "intel_context.h" -#include "intel_batchbuffer.h" - -#include "state_tracker/st_public.h" -#include "pipe/p_defines.h" -#include "pipe/p_context.h" -#include "intel_egl.h" -#include "utils.h" - -#ifdef DEBUG -int __intel_debug = 0; -#endif - - -#define need_GL_ARB_multisample -#define need_GL_ARB_point_parameters -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_buffer_object -#define need_GL_ARB_vertex_program -#define need_GL_ARB_window_pos -#define need_GL_EXT_blend_color -#define need_GL_EXT_blend_equation_separate -#define need_GL_EXT_blend_func_separate -#define need_GL_EXT_blend_minmax -#define need_GL_EXT_cull_vertex -#define need_GL_EXT_fog_coord -#define need_GL_EXT_framebuffer_object -#define need_GL_EXT_multi_draw_arrays -#define need_GL_EXT_secondary_color -#define need_GL_NV_vertex_program -#include "extension_helper.h" - - -/** - * Extension strings exported by the intel driver. - * - * \note - * It appears that ARB_texture_env_crossbar has "disappeared" compared to the - * old i830-specific driver. - */ -const struct dri_extension card_extensions[] = { - {"GL_ARB_multisample", GL_ARB_multisample_functions}, - {"GL_ARB_multitexture", NULL}, - {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, - {"GL_ARB_texture_border_clamp", NULL}, - {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, - {"GL_ARB_texture_cube_map", NULL}, - {"GL_ARB_texture_env_add", NULL}, - {"GL_ARB_texture_env_combine", NULL}, - {"GL_ARB_texture_env_dot3", NULL}, - {"GL_ARB_texture_mirrored_repeat", NULL}, - {"GL_ARB_texture_rectangle", NULL}, - {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, - {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, - {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, - {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, - {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, - {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, - {"GL_EXT_blend_subtract", NULL}, - {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, - {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, - {"GL_EXT_packed_depth_stencil", NULL}, - {"GL_EXT_pixel_buffer_object", NULL}, - {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, - {"GL_EXT_stencil_wrap", NULL}, - {"GL_EXT_texture_edge_clamp", NULL}, - {"GL_EXT_texture_env_combine", NULL}, - {"GL_EXT_texture_env_dot3", NULL}, - {"GL_EXT_texture_filter_anisotropic", NULL}, - {"GL_EXT_texture_lod_bias", NULL}, - {"GL_3DFX_texture_compression_FXT1", NULL}, - {"GL_APPLE_client_storage", NULL}, - {"GL_MESA_pack_invert", NULL}, - {"GL_MESA_ycbcr_texture", NULL}, - {"GL_NV_blend_square", NULL}, - {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, - {"GL_NV_vertex_program1_1", NULL}, - {"GL_SGIS_generate_mipmap", NULL }, - {NULL, NULL} -}; - - -/* - * Hardware lock functions. - * Doesn't do anything in EGL - */ - -static void -intel_lock_hardware(struct intel_be_context *context) -{ - (void)context; -} - -static void -intel_unlock_hardware(struct intel_be_context *context) -{ - (void)context; -} - -static boolean -intel_locked_hardware(struct intel_be_context *context) -{ - (void)context; - return FALSE; -} - - -/* - * Misc functions. - */ - -int -intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate) -{ - struct intel_context *intel = CALLOC_STRUCT(intel_context); - struct intel_device *device = (struct intel_device *)egl_context->device->priv; - struct pipe_context *pipe; - struct st_context *st_share = NULL; - - egl_context->priv = intel; - - intel->intel_device = device; - intel->egl_context = egl_context; - intel->egl_device = egl_context->device; - - intel->base.hardware_lock = intel_lock_hardware; - intel->base.hardware_unlock = intel_unlock_hardware; - intel->base.hardware_locked = intel_locked_hardware; - - intel_be_init_context(&intel->base, &device->base); - -#if 0 - pipe = intel_create_softpipe(intel, screen->winsys); -#else - pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base); -#endif - - pipe->priv = intel; - - intel->st = st_create_context(pipe, visual, st_share); - - device->dummy = intel; - - return TRUE; -} - -int -intel_destroy_context(struct egl_drm_context *egl_context) -{ - struct intel_context *intel = egl_context->priv; - - if (intel->intel_device->dummy == intel) - intel->intel_device->dummy = NULL; - - st_destroy_context(intel->st); - intel_be_destroy_context(&intel->base); - free(intel); - return TRUE; -} - -void -intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read) -{ - if (context) { - struct intel_context *intel = (struct intel_context *)context->priv; - struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; - struct intel_framebuffer *read_fb = (struct intel_framebuffer *)read->priv; - - assert(draw_fb->stfb); - assert(read_fb->stfb); - - st_make_current(intel->st, draw_fb->stfb, read_fb->stfb); - - intel->egl_drawable = draw; - - st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); - - if (draw != read) - st_resize_framebuffer(read_fb->stfb, read->w, read->h); - - } else { - st_make_current(NULL, NULL, NULL); - } -} - -void -intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front) -{ - struct intel_device *device = (struct intel_device *)draw->device->priv; - struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv; - - if (draw_fb->front_buffer) - driBOUnReference(draw_fb->front_buffer); - - draw_fb->front_buffer = NULL; - draw_fb->front = NULL; - - /* to unbind just call this function with front == NULL */ - if (!front) - return; - - draw_fb->front = front; - - driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0); - driBOSetReferenced(draw_fb->front_buffer, front->handle); - - st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h); -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h deleted file mode 100644 index dfa4720b08..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_context.h +++ /dev/null @@ -1,118 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_CONTEXT_H -#define INTEL_CONTEXT_H - -#include "pipe/p_debug.h" -#include "intel_drm/intel_be_context.h" - - -struct st_context; -struct egl_drm_device; -struct egl_drm_context; -struct egl_drm_frontbuffer; - - -/** - * Intel rendering context, contains a state tracker and intel-specific info. - */ -struct intel_context -{ - struct intel_be_context base; - - struct st_context *st; - - struct intel_device *intel_device; - - /* new egl stuff */ - struct egl_drm_device *egl_device; - struct egl_drm_context *egl_context; - struct egl_drm_drawable *egl_drawable; -}; - - - -/** - * Intel framebuffer. - */ -struct intel_framebuffer -{ - struct st_framebuffer *stfb; - - struct intel_device *device; - struct _DriBufferObject *front_buffer; - struct egl_drm_frontbuffer *front; -}; - - - - -/* These are functions now: - */ -void LOCK_HARDWARE( struct intel_context *intel ); -void UNLOCK_HARDWARE( struct intel_context *intel ); - -extern char *__progname; - - - -/* ================================================================ - * Debugging: - */ -#ifdef DEBUG -extern int __intel_debug; - -#define DEBUG_SWAP 0x1 -#define DEBUG_LOCK 0x2 -#define DEBUG_IOCTL 0x4 -#define DEBUG_BATCH 0x8 - -#define DBG(flag, ...) do { \ - if (__intel_debug & (DEBUG_##flag)) \ - printf(__VA_ARGS__); \ -} while(0) - -#else -#define DBG(flag, ...) -#endif - - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GME 0x27AE -#define PCI_CHIP_G33_G 0x29C2 -#define PCI_CHIP_Q35_G 0x29B2 -#define PCI_CHIP_Q33_G 0x29D2 - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.c b/src/gallium/winsys/egl_drm/intel/intel_device.c deleted file mode 100644 index b9649cbec7..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_device.c +++ /dev/null @@ -1,137 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "utils.h" - -#include "state_tracker/st_public.h" -#include "i915simple/i915_screen.h" - -#include "intel_context.h" -#include "intel_device.h" -#include "intel_batchbuffer.h" -#include "intel_egl.h" - - -extern const struct dri_extension card_extensions[]; - - -int -intel_create_device(struct egl_drm_device *device) -{ - struct intel_device *intel_device; - - /* Allocate the private area */ - intel_device = CALLOC_STRUCT(intel_device); - if (!intel_device) - return FALSE; - - device->priv = (void *)intel_device; - intel_device->device = device; - - intel_device->deviceID = device->deviceID; - - intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID); - - intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID); - - /* hack */ - driInitExtensions(NULL, card_extensions, GL_FALSE); - - return TRUE; -} - -int -intel_destroy_device(struct egl_drm_device *device) -{ - struct intel_device *intel_device = (struct intel_device *)device->priv; - - intel_be_destroy_device(&intel_device->base); - - free(intel_device); - device->priv = NULL; - - return TRUE; -} - -int -intel_create_drawable(struct egl_drm_drawable *drawable, - const __GLcontextModes * visual) -{ - enum pipe_format colorFormat, depthFormat, stencilFormat; - struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer); - - if (!intelfb) - return GL_FALSE; - - intelfb->device = drawable->device->priv; - - if (visual->redBits == 5) - colorFormat = PIPE_FORMAT_R5G6B5_UNORM; - else - colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; - - if (visual->depthBits == 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits == 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_NONE; - - if (visual->stencilBits == 8) - stencilFormat = PIPE_FORMAT_S8Z24_UNORM; - else - stencilFormat = PIPE_FORMAT_NONE; - - intelfb->stfb = st_create_framebuffer(visual, - colorFormat, - depthFormat, - stencilFormat, - drawable->w, - drawable->h, - (void*) intelfb); - - if (!intelfb->stfb) { - free(intelfb); - return GL_FALSE; - } - - drawable->priv = (void *) intelfb; - return GL_TRUE; -} - -int -intel_destroy_drawable(struct egl_drm_drawable *drawable) -{ - struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv; - drawable->priv = NULL; - - assert(intelfb->stfb); - st_unreference_framebuffer(&intelfb->stfb); - free(intelfb); - return TRUE; -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_device.h b/src/gallium/winsys/egl_drm/intel/intel_device.h deleted file mode 100644 index 2f9d4f887e..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_device.h +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef _INTEL_SCREEN_H_ -#define _INTEL_SCREEN_H_ - -#include "intel_drm/intel_be_device.h" - -#include "pipe/p_compiler.h" - -struct pipe_screen; -struct egl_drm_device; -struct intel_context; - -struct intel_device -{ - struct intel_be_device base; - struct pipe_screen *pipe; - - int deviceID; - struct egl_drm_device *device; - - struct intel_context *dummy; -}; - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c deleted file mode 100644 index 1851babaf6..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ /dev/null @@ -1,796 +0,0 @@ - -#include -#include -#include -#include -#include - -#include "eglconfig.h" -#include "eglcontext.h" -#include "egldisplay.h" -#include "egldriver.h" -#include "eglglobals.h" -#include "eglmode.h" -#include "eglscreen.h" -#include "eglsurface.h" -#include "egllog.h" - -#include "intel_egl.h" - -#include "xf86drm.h" -#include "xf86drmMode.h" - -#include "intel_context.h" - -#include "state_tracker/st_public.h" - -#define MAX_SCREENS 16 - -static void -drm_get_device_id(struct egl_drm_device *device) -{ - char path[512]; - FILE *file; - - /* TODO get the real minor */ - int minor = 0; - - snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor); - file = fopen(path, "r"); - if (!file) { - _eglLog(_EGL_WARNING, "Could not retrive device ID\n"); - return; - } - - fgets(path, sizeof( path ), file); - sscanf(path, "%x", &device->deviceID); - fclose(file); -} - -static struct egl_drm_device* -egl_drm_create_device(int drmFD) -{ - struct egl_drm_device *device = malloc(sizeof(*device)); - memset(device, 0, sizeof(*device)); - device->drmFD = drmFD; - - device->version = drmGetVersion(device->drmFD); - - drm_get_device_id(device); - - if (!intel_create_device(device)) { - free(device); - return NULL; - } - - return device; -} - -static void -_egl_context_modes_destroy(__GLcontextModes *modes) -{ - _eglLog(_EGL_DEBUG, "%s", __FUNCTION__); - - while (modes) { - __GLcontextModes * const next = modes->next; - free(modes); - modes = next; - } -} -/** - * Create a linked list of 'count' GLcontextModes. - * These are used during the client/server visual negotiation phase, - * then discarded. - */ -static __GLcontextModes * -_egl_context_modes_create(unsigned count, size_t minimum_size) -{ - /* This code copied from libGLX, and modified */ - const size_t size = (minimum_size > sizeof(__GLcontextModes)) - ? minimum_size : sizeof(__GLcontextModes); - __GLcontextModes * head = NULL; - __GLcontextModes ** next; - unsigned i; - - _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size); - - next = & head; - for (i = 0 ; i < count ; i++) { - *next = (__GLcontextModes *) calloc(1, size); - if (*next == NULL) { - _egl_context_modes_destroy(head); - head = NULL; - break; - } - - (*next)->doubleBufferMode = 1; - (*next)->visualID = GLX_DONT_CARE; - (*next)->visualType = GLX_DONT_CARE; - (*next)->visualRating = GLX_NONE; - (*next)->transparentPixel = GLX_NONE; - (*next)->transparentRed = GLX_DONT_CARE; - (*next)->transparentGreen = GLX_DONT_CARE; - (*next)->transparentBlue = GLX_DONT_CARE; - (*next)->transparentAlpha = GLX_DONT_CARE; - (*next)->transparentIndex = GLX_DONT_CARE; - (*next)->xRenderable = GLX_DONT_CARE; - (*next)->fbconfigID = GLX_DONT_CARE; - (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; - (*next)->bindToTextureRgb = GLX_DONT_CARE; - (*next)->bindToTextureRgba = GLX_DONT_CARE; - (*next)->bindToMipmapTexture = GLX_DONT_CARE; - (*next)->bindToTextureTargets = 0; - (*next)->yInverted = GLX_DONT_CARE; - - next = & ((*next)->next); - } - - return head; -} - -struct drm_screen; - -struct drm_driver -{ - _EGLDriver base; /* base class/object */ - - drmModeResPtr res; - - struct drm_screen *screens[MAX_SCREENS]; - size_t count_screens; - - struct egl_drm_device *device; -}; - -struct drm_surface -{ - _EGLSurface base; /* base class/object */ - - struct egl_drm_drawable *drawable; -}; - -struct drm_context -{ - _EGLContext base; /* base class/object */ - - struct egl_drm_context *context; -}; - -struct drm_screen -{ - _EGLScreen base; - - /* currently only support one connector */ - drmModeConnectorPtr connector; - - /* Has this screen been shown */ - int shown; - - /* Surface that is currently attached to this screen */ - struct drm_surface *surf; - - /* backing buffer */ - drmBO buffer; - - /* framebuffer */ - drmModeFBPtr fb; - uint32_t fbID; - - /* crtc and mode used */ - drmModeCrtcPtr crtc; - uint32_t crtcID; - - struct drm_mode_modeinfo *mode; - - /* geometry of the screen */ - struct egl_drm_frontbuffer front; -}; - -static void -drm_update_res(struct drm_driver *drm_drv) -{ - drmModeFreeResources(drm_drv->res); - drm_drv->res = drmModeGetResources(drm_drv->device->drmFD); -} - -static void -drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector) -{ - struct drm_mode_modeinfo *m; - int i; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name); - } -} - - -static EGLBoolean -drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) -{ - _EGLDisplay *disp = _eglLookupDisplay(dpy); - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_screen *screen = NULL; - drmModeConnectorPtr connector = NULL; - drmModeResPtr res = NULL; - unsigned count_connectors = 0; - int num_screens = 0; - - EGLint i; - int fd; - - fd = drmOpen("i915", NULL); - if (fd < 0) { - return EGL_FALSE; - } - - drm_drv->device = egl_drm_create_device(fd); - if (!drm_drv->device) { - drmClose(fd); - return EGL_FALSE; - } - - drm_update_res(drm_drv); - res = drm_drv->res; - if (res) - count_connectors = res->count_connectors; - - for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) { - connector = drmModeGetConnector(fd, res->connectors[i]); - - if (!connector) - continue; - - if (connector->connection != DRM_MODE_CONNECTED) { - drmModeFreeConnector(connector); - continue; - } - - screen = malloc(sizeof(struct drm_screen)); - memset(screen, 0, sizeof(*screen)); - screen->connector = connector; - _eglInitScreen(&screen->base); - _eglAddScreen(disp, &screen->base); - drm_add_modes_from_connector(&screen->base, connector); - drm_drv->screens[num_screens++] = screen; - } - drm_drv->count_screens = num_screens; - - /* for now we only have one config */ - _EGLConfig *config = calloc(1, sizeof(*config)); - memset(config, 1, sizeof(*config)); - _eglInitConfig(config, 1); - _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); - _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); - _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); - _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24); - _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); - _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); - _eglAddConfig(disp, config); - - drv->Initialized = EGL_TRUE; - - *major = 1; - *minor = 4; - - return EGL_TRUE; -} - -static void -drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - unsigned int i; - - intel_bind_frontbuffer(screen->surf->drawable, NULL); - screen->surf = NULL; - - for (i = 0; i < drm_drv->res->count_crtcs; i++) { - drmModeSetCrtc( - drm_drv->device->drmFD, - drm_drv->res->crtcs[i], - 0, // FD - 0, 0, - NULL, 0, // List of output ids - NULL); - } - - drmModeRmFB(drm_drv->device->drmFD, screen->fbID); - drmModeFreeFB(screen->fb); - screen->fb = NULL; - - drmBOUnreference(drm_drv->device->drmFD, &screen->buffer); - - screen->shown = 0; -} - -static EGLBoolean -drm_terminate(_EGLDriver *drv, EGLDisplay dpy) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_screen *screen; - int i = 0; - - intel_destroy_device(drm_drv->device); - drmFreeVersion(drm_drv->device->version); - - for (i = 0; i < drm_drv->count_screens; i++) { - screen = drm_drv->screens[i]; - - if (screen->shown) - drm_takedown_shown_screen(drv, screen); - - drmModeFreeConnector(screen->connector); - _eglDestroyScreen(&screen->base); - drm_drv->screens[i] = NULL; - } - - drmClose(drm_drv->device->drmFD); - - free(drm_drv->device); - - _eglCleanupDisplay(_eglLookupDisplay(dpy)); - free(drm_drv); - - return EGL_TRUE; -} - - -static struct drm_context * -lookup_drm_context(EGLContext context) -{ - _EGLContext *c = _eglLookupContext(context); - return (struct drm_context *) c; -} - - -static struct drm_surface * -lookup_drm_surface(EGLSurface surface) -{ - _EGLSurface *s = _eglLookupSurface(surface); - return (struct drm_surface *) s; -} - -static struct drm_screen * -lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen) -{ - _EGLScreen *s = _eglLookupScreen(dpy, screen); - return (struct drm_screen *) s; -} - -static __GLcontextModes* -visual_from_config(_EGLConfig *conf) -{ - __GLcontextModes *visual; - (void)conf; - - visual = _gl_context_modes_create(1, sizeof(*visual)); - visual->redBits = 8; - visual->greenBits = 8; - visual->blueBits = 8; - visual->alphaBits = 8; - - visual->rgbBits = 32; - visual->doubleBufferMode = 1; - - visual->depthBits = 24; - visual->haveDepthBuffer = visual->depthBits > 0; - visual->stencilBits = 8; - visual->haveStencilBuffer = visual->stencilBits > 0; - - return visual; -} - - - -static EGLContext -drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_context *c; - struct drm_egl_context *share = NULL; - _EGLConfig *conf; - int i; - int ret; - __GLcontextModes *visual; - struct egl_drm_context *context; - - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - /* no attribs defined for now */ - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); - return EGL_NO_CONTEXT; - } - } - - c = (struct drm_context *) calloc(1, sizeof(struct drm_context)); - if (!c) - return EGL_NO_CONTEXT; - - _eglInitContext(drv, dpy, &c->base, config, attrib_list); - - context = malloc(sizeof(*context)); - memset(context, 0, sizeof(*context)); - - if (!context) - goto err_c; - - context->device = drm_drv->device; - visual = visual_from_config(conf); - - ret = intel_create_context(context, visual, share); - free(visual); - - if (!ret) - goto err_gl; - - c->context = context; - - /* generate handle and insert into hash table */ - _eglSaveContext(&c->base); - assert(_eglGetContextHandle(&c->base)); - - return _eglGetContextHandle(&c->base); -err_gl: - free(context); -err_c: - free(c); - return EGL_NO_CONTEXT; -} - -static EGLBoolean -drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) -{ - struct drm_context *fc = lookup_drm_context(context); - _eglRemoveContext(&fc->base); - if (fc->base.IsBound) { - fc->base.DeletePending = EGL_TRUE; - } else { - intel_destroy_context(fc->context); - free(fc->context); - free(fc); - } - return EGL_TRUE; -} - - -static EGLSurface -drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) -{ - return EGL_NO_SURFACE; -} - - -static EGLSurface -drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) -{ - return EGL_NO_SURFACE; -} - - -static EGLSurface -drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, - const EGLint *attrib_list) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - int i; - int ret; - int width = -1; - int height = -1; - struct drm_surface *surf = NULL; - struct egl_drm_drawable *drawable = NULL; - __GLcontextModes *visual; - _EGLConfig *conf; - - conf = _eglLookupConfig(drv, dpy, config); - if (!conf) { - _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface"); - return EGL_NO_CONTEXT; - } - - for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { - switch (attrib_list[i]) { - case EGL_WIDTH: - width = attrib_list[++i]; - break; - case EGL_HEIGHT: - height = attrib_list[++i]; - break; - default: - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); - return EGL_NO_SURFACE; - } - } - - if (width < 1 || height < 1) { - _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface"); - return EGL_NO_SURFACE; - } - - surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface)); - if (!surf) - goto err; - - if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list)) - goto err_surf; - - drawable = malloc(sizeof(*drawable)); - memset(drawable, 0, sizeof(*drawable)); - - drawable->w = width; - drawable->h = height; - - visual = visual_from_config(conf); - - drawable->device = drm_drv->device; - ret = intel_create_drawable(drawable, visual); - free(visual); - - if (!ret) - goto err_draw; - - surf->drawable = drawable; - - _eglSaveSurface(&surf->base); - return surf->base.Handle; - -err_draw: - free(drawable); -err_surf: - free(surf); -err: - return EGL_NO_SURFACE; -} - -static EGLSurface -drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, - const EGLint *attrib_list) -{ - EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list); - - return surf; -} - -static struct drm_mode_modeinfo * -drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) -{ - int i; - struct drm_mode_modeinfo *m; - - for (i = 0; i < connector->count_modes; i++) { - m = &connector->modes[i]; - if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) - break; - m = NULL; - } - - return m; -} -static void -draw(size_t x, size_t y, size_t w, size_t h, size_t pitch, size_t v, unsigned int *ptr) -{ - int i, j; - - for (i = x; i < x + w; i++) - for(j = y; j < y + h; j++) - ptr[(i * pitch / 4) + j] = v; - -} - -static void -prettyColors(int fd, unsigned int handle, size_t pitch) -{ - drmBO bo; - unsigned int *ptr; - void *p; - int i; - - drmBOReference(fd, handle, &bo); - drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &p); - ptr = (unsigned int*)p; - - for (i = 0; i < (bo.size / 4); i++) - ptr[i] = 0xFFFFFFFF; - - for (i = 0; i < 4; i++) - draw(i * 40, i * 40, 40, 40, pitch, 0, ptr); - - - draw(200, 100, 40, 40, pitch, 0xff00ff, ptr); - draw(100, 200, 40, 40, pitch, 0xff00ff, ptr); - - drmBOUnmap(fd, &bo); -} - -static EGLBoolean -drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, - EGLScreenMESA screen, - EGLSurface surface, EGLModeMESA m) -{ - struct drm_driver *drm_drv = (struct drm_driver *)drv; - struct drm_surface *surf = lookup_drm_surface(surface); - struct drm_screen *scrn = lookup_drm_screen(dpy, screen); - _EGLMode *mode = _eglLookupMode(dpy, m); - size_t pitch = mode->Width * 4; - size_t size = mode->Height * pitch; - int ret; - unsigned int i,j,k; - - if (scrn->shown) - drm_takedown_shown_screen(drv, scrn); - - ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0, - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_NO_EVICT, - DRM_BO_HINT_DONT_FENCE, &scrn->buffer); - - if (ret) - return EGL_FALSE; - - prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch); - - ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height, - 32, 32, pitch, - scrn->buffer.handle, - &scrn->fbID); - - if (ret) - goto err_bo; - - scrn->fb = drmModeGetFB(drm_drv->device->drmFD, scrn->fbID); - if (!scrn->fb) - goto err_bo; - - scrn->mode = drm_find_mode(scrn->connector, mode); - if (!scrn->mode) - goto err_fb; - - for (j = 0; j < drm_drv->res->count_connectors; j++) { - drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]); - for (k = 0; k < con->count_encoders; k++) { - drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]); - for (i = 0; i < drm_drv->res->count_crtcs; i++) { - if (enc->possible_crtcs & (1<device->drmFD, - drm_drv->res->crtcs[i], - scrn->fbID, - 0, 0, - &drm_drv->res->connectors[j], 1, - scrn->mode); - /* skip the other crtcs now */ - i = drm_drv->res->count_crtcs; - } - } - } - } - - scrn->front.handle = scrn->buffer.handle; - scrn->front.pitch = pitch; - scrn->front.width = mode->Width; - scrn->front.height = mode->Height; - - scrn->surf = surf; - intel_bind_frontbuffer(surf->drawable, &scrn->front); - - scrn->shown = 1; - - return EGL_TRUE; - -err_fb: - /* TODO remove fb */ - -err_bo: - drmBOUnreference(drm_drv->device->drmFD, &scrn->buffer); - return EGL_FALSE; -} - -static EGLBoolean -drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) -{ - struct drm_surface *fs = lookup_drm_surface(surface); - _eglRemoveSurface(&fs->base); - if (fs->base.IsBound) { - fs->base.DeletePending = EGL_TRUE; - } else { - intel_bind_frontbuffer(fs->drawable, NULL); - intel_destroy_drawable(fs->drawable); - free(fs->drawable); - free(fs); - } - return EGL_TRUE; -} - - -static EGLBoolean -drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) -{ - struct drm_surface *readSurf = lookup_drm_surface(read); - struct drm_surface *drawSurf = lookup_drm_surface(draw); - struct drm_context *ctx = lookup_drm_context(context); - EGLBoolean b; - - b = _eglMakeCurrent(drv, dpy, draw, read, context); - if (!b) - return EGL_FALSE; - - if (ctx) { - if (!drawSurf || !readSurf) - return EGL_FALSE; - - intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable); - } else { - intel_make_current(NULL, NULL, NULL); - } - - return EGL_TRUE; -} - -static EGLBoolean -drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) -{ - struct drm_surface *surf = lookup_drm_surface(draw); - if (!surf) - return EGL_FALSE; - - /* error checking */ - if (!_eglSwapBuffers(drv, dpy, draw)) - return EGL_FALSE; - - intel_swap_buffers(surf->drawable); - return EGL_TRUE; -} - - -/** - * The bootstrap function. Return a new drm_driver object and - * plug in API functions. - */ -_EGLDriver * -_eglMain(_EGLDisplay *dpy, const char *args) -{ - struct drm_driver *drm; - - drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver)); - if (!drm) { - return NULL; - } - - /* First fill in the dispatch table with defaults */ - _eglInitDriverFallbacks(&drm->base); - /* then plug in our Drm-specific functions */ - drm->base.API.Initialize = drm_initialize; - drm->base.API.Terminate = drm_terminate; - drm->base.API.CreateContext = drm_create_context; - drm->base.API.MakeCurrent = drm_make_current; - drm->base.API.CreateWindowSurface = drm_create_window_surface; - drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface; - drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface; - drm->base.API.DestroySurface = drm_destroy_surface; - drm->base.API.DestroyContext = drm_destroy_context; - drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa; - drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa; - drm->base.API.SwapBuffers = drm_swap_buffers; - - drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/; - drm->base.Name = "DRM/Gallium"; - - /* enable supported extensions */ - drm->base.Extensions.MESA_screen_surface = EGL_TRUE; - drm->base.Extensions.MESA_copy_context = EGL_TRUE; - - return &drm->base; -} diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h deleted file mode 100644 index 1ee27e0847..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.h +++ /dev/null @@ -1,53 +0,0 @@ - -#ifndef _INTEL_EGL_H_ -#define _INTEL_EGL_H_ - -#include - -struct egl_drm_device -{ - void *priv; - int drmFD; - - drmVersionPtr version; - int deviceID; -}; - -struct egl_drm_context -{ - void *priv; - struct egl_drm_device *device; -}; - -struct egl_drm_drawable -{ - void *priv; - struct egl_drm_device *device; - size_t h; - size_t w; -}; - -struct egl_drm_frontbuffer -{ - uint32_t handle; - uint32_t pitch; - uint32_t width; - uint32_t height; -}; - -#include "GL/internal/glcore.h" - -int intel_create_device(struct egl_drm_device *device); -int intel_destroy_device(struct egl_drm_device *device); - -int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate); -int intel_destroy_context(struct egl_drm_context *context); - -int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual); -int intel_destroy_drawable(struct egl_drm_drawable *drawable); - -void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read); -void intel_swap_buffers(struct egl_drm_drawable *draw); -void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front); - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_reg.h b/src/gallium/winsys/egl_drm/intel/intel_reg.h deleted file mode 100644 index 4f33bee438..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_reg.h +++ /dev/null @@ -1,53 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef _INTEL_REG_H_ -#define _INTEL_REG_H_ - - -#define BR00_BITBLT_CLIENT 0x40000000 -#define BR00_OP_COLOR_BLT 0x10000000 -#define BR00_OP_SRC_COPY_BLT 0x10C00000 -#define BR13_SOLID_PATTERN 0x80000000 - -#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) -#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) -#define XY_COLOR_BLT_WRITE_RGB (1<<20) - -#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) -#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) -#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) - -#define MI_WAIT_FOR_EVENT ((0x3<<23)) -#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) - -#define MI_BATCH_BUFFER_END (0xA<<23) - - -#endif diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c deleted file mode 100644 index 2edcbc79ff..0000000000 --- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c +++ /dev/null @@ -1,111 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "intel_device.h" -#include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_reg.h" - -#include "pipe/p_context.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "state_tracker/st_cb_fbo.h" -#include "intel_egl.h" - - -static void -intel_display_surface(struct egl_drm_drawable *draw, - struct pipe_surface *surf); - -void intel_swap_buffers(struct egl_drm_drawable *draw) -{ - struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; - struct pipe_surface *back_surf; - - assert(intel_fb); - assert(intel_fb->stfb); - - back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT); - if (back_surf) { - st_notify_swapbuffers(intel_fb->stfb); - if (intel_fb->front) - intel_display_surface(draw, back_surf); - st_notify_swapbuffers_complete(intel_fb->stfb); - } -} - -static void -intel_display_surface(struct egl_drm_drawable *draw, - struct pipe_surface *surf) -{ - struct intel_context *intel = NULL; - struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv; - struct _DriFenceObject *fence; - - //const int srcWidth = surf->width; - //const int srcHeight = surf->height; - - intel = intel_fb->device->dummy; - if (!intel) { - printf("No dummy context\n"); - return; - } - - const int dstWidth = intel_fb->front->width; - const int dstHeight = intel_fb->front->height; - const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp; - - const int cpp = 4;//intel_fb->front->cpp; - const int srcPitch = surf->stride / cpp; - - int BR13, CMD; - //int i; - - BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - - BEGIN_BATCH(8, 2); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((0 << 16) | 0); - OUT_BATCH((dstHeight << 16) | dstWidth); - - OUT_RELOC(intel_fb->front_buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); - - OUT_BATCH((0 << 16) | 0); - OUT_BATCH((srcPitch * cpp) & 0xffff); - OUT_RELOC(dri_bo(surf->buffer), - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); - - fence = intel_be_batchbuffer_flush(intel->base.batch); - driFenceUnReference(&fence); - intel_be_batchbuffer_finish(intel->base.batch); -} diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c index 86b085ab84..ff52ceb8c4 100644 --- a/src/gallium/winsys/gdi/wmesa.c +++ b/src/gallium/winsys/gdi/wmesa.c @@ -118,48 +118,6 @@ static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC) } } - -/** - * Create DIB for back buffer. - * We write into this memory with the span routines and then blit it - * to the window on a buffer swap. - */ -BOOL wmCreateBackingStore(WMesaFramebuffer pwfb, long lxSize, long lySize) -{ - HDC hdc = pwfb->hDC; - BITMAPINFO bmi; - LPBITMAPINFO pbmi = &bmi; - HDC hic; - - pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmi->bmiHeader.biWidth = lxSize; - pbmi->bmiHeader.biHeight= -lySize; - pbmi->bmiHeader.biPlanes = 1; - pbmi->bmiHeader.biBitCount = pwfb->cColorBits; - pbmi->bmiHeader.biCompression = BI_RGB; - pbmi->bmiHeader.biSizeImage = 0; - pbmi->bmiHeader.biXPelsPerMeter = 0; - pbmi->bmiHeader.biYPelsPerMeter = 0; - pbmi->bmiHeader.biClrUsed = 0; - pbmi->bmiHeader.biClrImportant = 0; - - hic = CreateIC("display", NULL, NULL, NULL); - pwfb->dib_hDC = CreateCompatibleDC(hic); - - pwfb->hbmDIB = CreateDIBSection(hic, - pbmi, - DIB_RGB_COLORS, - (void **)&(pwfb->pbPixels), - 0, - 0); - pwfb->hOldBitmap = SelectObject(pwfb->dib_hDC, pwfb->hbmDIB); - - DeleteDC(hic); - - wmSetPixelFormat(pwfb, pwfb->hDC); - return TRUE; -} - /** * Create a new WMesaFramebuffer object which will correspond to the * given HDC (Window handle). @@ -201,10 +159,6 @@ wmesa_new_framebuffer(HDC hdc, GLvisual *visual, GLuint width, GLuint height) pwfb->cColorBits = GetDeviceCaps(hdc, BITSPIXEL); -#if 0 - wmCreateBackingStore(pwfb, width, height); -#endif - pwfb->hDC = hdc; /* insert at head of list */ pwfb->next = FirstFramebuffer; @@ -266,16 +220,6 @@ static WMesaContext wmesa_context(const GLcontext *ctx) return (WMesaContext) ctx; } -static wmDeleteBackingStore(WMesaFramebuffer pwfb) -{ - if (pwfb->hbmDIB) { - SelectObject(pwfb->dib_hDC, pwfb->hOldBitmap); - DeleteDC(pwfb->dib_hDC); - DeleteObject(pwfb->hbmDIB); - } -} - - /** * Find the width and height of the window named by hdc. */ @@ -383,11 +327,6 @@ wm_flush_frontbuffer(struct pipe_winsys *pws, struct wm_buffer *wm_buf; BITMAPINFO bmi, *pbmi; -#if 0 - if (pwfb) - BitBlt(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, - pwfb->dib_hDC, 0, 0, SRCCOPY); -#else wm_buf = wm_buffer(surf->buffer); pbmi = &bmi; @@ -405,7 +344,6 @@ wm_flush_frontbuffer(struct pipe_winsys *pws, pbmi->bmiHeader.biClrImportant = 0; StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY); -#endif } @@ -706,9 +644,6 @@ void WMesaDestroyContext( WMesaContext pwc ) /* clean up frame buffer resources */ pwfb = wmesa_lookup_framebuffer(pwc->hDC); if (pwfb) { -#if 0 - wmDeleteBackingStore(pwfb); -#endif wmesa_free_framebuffer(pwc->hDC); } @@ -779,10 +714,6 @@ void WMesaSwapBuffers( HDC hdc ) */ st_notify_swapbuffers(pwfb->stfb); -#if 0 - BitBlt(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, - pwfb->dib_hDC, 0, 0, SRCCOPY); -#else surf = st_get_framebuffer_surface(pwfb->stfb, ST_SURFACE_BACK_LEFT); wm_buf = wm_buffer(surf->buffer); @@ -809,7 +740,6 @@ void WMesaSwapBuffers( HDC hdc ) st_resize_framebuffer(pwfb->stfb, width, height); } -#endif } /* This is hopefully a temporary hack to define some needed dispatch -- cgit v1.2.3 From 9bbc55116f36a357ee75d2766b0adb039eaca806 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Sun, 17 Aug 2008 21:55:37 +0100 Subject: if we can't find a mode, return first. At least we should see the top left portion if we've got larger screens on other CRTC's --- src/gallium/winsys/drm/intel/egl/intel_egl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.c b/src/gallium/winsys/drm/intel/egl/intel_egl.c index b89c5c508a..3204ed3131 100644 --- a/src/gallium/winsys/drm/intel/egl/intel_egl.c +++ b/src/gallium/winsys/drm/intel/egl/intel_egl.c @@ -571,7 +571,7 @@ drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode) m = &connector->modes[i]; if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate) break; - m = NULL; + m = &connector->modes[0]; /* if we can't find one, return first */ } return m; @@ -654,12 +654,12 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, if (!scrn->fb) goto err_bo; - scrn->mode = drm_find_mode(scrn->connector, mode); - if (!scrn->mode) - goto err_fb; - for (j = 0; j < drm_drv->res->count_connectors; j++) { drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]); + scrn->mode = drm_find_mode(con, mode); + if (!scrn->mode) + goto err_fb; + for (k = 0; k < con->count_encoders; k++) { drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]); for (i = 0; i < drm_drv->res->count_crtcs; i++) { -- cgit v1.2.3 From 6fdc057887bd5e1e5f5ae2781529df050b3a31c6 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 18 Aug 2008 14:40:02 +0200 Subject: scons: Fix build. --- src/gallium/winsys/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index ddab9efc86..30c3378dff 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -1,6 +1,6 @@ Import('*') -if env['drm']: +if env['dri']: SConscript([ 'drm/SConscript', ]) -- cgit v1.2.3 From e2da7edd642198d7c515dbc0b9ba77d4286c3262 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 18 Aug 2008 15:42:26 +0200 Subject: tgsi: Add condition code (CC) register. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 13 +++++++++++-- src/gallium/auxiliary/tgsi/tgsi_exec.h | 29 ++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 7 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index a96209db1a..7974915211 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -26,7 +26,7 @@ **************************************************************************/ /** - * TGSI interpretor/executor. + * TGSI interpreter/executor. * * Flow control information: * @@ -88,6 +88,8 @@ #define TEMP_OUTPUT_C TGSI_EXEC_TEMP_OUTPUT_C #define TEMP_PRIMITIVE_I TGSI_EXEC_TEMP_PRIMITIVE_I #define TEMP_PRIMITIVE_C TGSI_EXEC_TEMP_PRIMITIVE_C +#define TEMP_CC_I TGSI_EXEC_TEMP_CC_I +#define TEMP_CC_C TGSI_EXEC_TEMP_CC_C #define TEMP_3_I TGSI_EXEC_TEMP_THREE_I #define TEMP_3_C TGSI_EXEC_TEMP_THREE_C #define TEMP_HALF_I TGSI_EXEC_TEMP_HALF_I @@ -2539,6 +2541,13 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach ) mach->Primitives[0] = 0; } + for (i = 0; i < QUAD_SIZE; i++) { + mach->Temps[TEMP_CC_I].xyzw[TEMP_CC_C].u[i] = + (TGSI_EXEC_CC_EQ << TGSI_EXEC_CC_X_SHIFT) | + (TGSI_EXEC_CC_EQ << TGSI_EXEC_CC_Y_SHIFT) | + (TGSI_EXEC_CC_EQ << TGSI_EXEC_CC_Z_SHIFT) | + (TGSI_EXEC_CC_EQ << TGSI_EXEC_CC_W_SHIFT); + } /* execute declarations (interpolants) */ for (i = 0; i < mach->NumDeclarations; i++) { diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 4f30650b07..c4e649e69c 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -25,7 +25,7 @@ * **************************************************************************/ -#if !defined TGSI_EXEC_H +#ifndef TGSI_EXEC_H #define TGSI_EXEC_H #include "pipe/p_compiler.h" @@ -140,11 +140,30 @@ struct tgsi_exec_labels #define TGSI_EXEC_TEMP_PRIMITIVE_I (TGSI_EXEC_NUM_TEMPS + 2) #define TGSI_EXEC_TEMP_PRIMITIVE_C 2 -#define TGSI_EXEC_TEMP_THREE_I (TGSI_EXEC_NUM_TEMPS + 2) -#define TGSI_EXEC_TEMP_THREE_C 3 +/* NVIDIA condition code (CC) vector + */ +#define TGSI_EXEC_CC_GT 0x01 +#define TGSI_EXEC_CC_EQ 0x02 +#define TGSI_EXEC_CC_LT 0x04 +#define TGSI_EXEC_CC_UN 0x08 + +#define TGSI_EXEC_CC_X_MASK 0x000000ff +#define TGSI_EXEC_CC_X_SHIFT 0 +#define TGSI_EXEC_CC_Y_MASK 0x0000ff00 +#define TGSI_EXEC_CC_Y_SHIFT 8 +#define TGSI_EXEC_CC_Z_MASK 0x00ff0000 +#define TGSI_EXEC_CC_Z_SHIFT 16 +#define TGSI_EXEC_CC_W_MASK 0xff000000 +#define TGSI_EXEC_CC_W_SHIFT 24 + +#define TGSI_EXEC_TEMP_CC_I (TGSI_EXEC_NUM_TEMPS + 2) +#define TGSI_EXEC_TEMP_CC_C 3 + +#define TGSI_EXEC_TEMP_THREE_I (TGSI_EXEC_NUM_TEMPS + 3) +#define TGSI_EXEC_TEMP_THREE_C 0 #define TGSI_EXEC_TEMP_HALF_I (TGSI_EXEC_NUM_TEMPS + 3) -#define TGSI_EXEC_TEMP_HALF_C 0 +#define TGSI_EXEC_TEMP_HALF_C 1 #define TGSI_EXEC_TEMP_R0 (TGSI_EXEC_NUM_TEMPS + 4) -- cgit v1.2.3 From 880b751e8e21cab21a0d522346300f463fd9c634 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 18 Aug 2008 15:57:39 +0200 Subject: tgsi: Cosmetic changes. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 7974915211..6b19ab5c8e 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -63,6 +63,11 @@ #define TILE_BOTTOM_LEFT 2 #define TILE_BOTTOM_RIGHT 3 +#define CHAN_X 0 +#define CHAN_Y 1 +#define CHAN_Z 2 +#define CHAN_W 3 + /* * Shorthand locations of various utility registers (_I = Index, _C = Channel) */ @@ -96,9 +101,6 @@ #define TEMP_HALF_C TGSI_EXEC_TEMP_HALF_C #define TEMP_R0 TGSI_EXEC_TEMP_R0 -#define FOR_EACH_CHANNEL(CHAN)\ - for (CHAN = 0; CHAN < 4; CHAN++) - #define IS_CHANNEL_ENABLED(INST, CHAN)\ ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) @@ -106,11 +108,11 @@ ((INST).FullDstRegisters[1].DstRegister.WriteMask & (1 << (CHAN))) #define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\ - FOR_EACH_CHANNEL( CHAN )\ + for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)\ if (IS_CHANNEL_ENABLED( INST, CHAN )) #define FOR_EACH_ENABLED_CHANNEL2(INST, CHAN)\ - FOR_EACH_CHANNEL( CHAN )\ + for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)\ if (IS_CHANNEL_ENABLED2( INST, CHAN )) @@ -118,14 +120,6 @@ #define UPDATE_EXEC_MASK(MACH) \ MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask - -#define CHAN_X 0 -#define CHAN_Y 1 -#define CHAN_Z 2 -#define CHAN_W 3 - - - /** * Initialize machine state by expanding tokens to full instructions, * allocating temporary storage, setting up constants, etc. @@ -1128,7 +1122,7 @@ store_dest( { union tgsi_exec_channel *dst; - switch( reg->DstRegister.File ) { + switch (reg->DstRegister.File) { case TGSI_FILE_NULL: return; @@ -1138,7 +1132,7 @@ store_dest( break; case TGSI_FILE_TEMPORARY: - assert(reg->DstRegister.Index < TGSI_EXEC_NUM_TEMPS); + assert( reg->DstRegister.Index < TGSI_EXEC_NUM_TEMPS ); dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index]; break; @@ -1151,8 +1145,7 @@ store_dest( return; } - switch (inst->Instruction.Saturate) - { + switch (inst->Instruction.Saturate) { case TGSI_SAT_NONE: if (mach->ExecMask & 0x1) dst->i[0] = chan->i[0]; @@ -1166,8 +1159,8 @@ store_dest( case TGSI_SAT_ZERO_ONE: /* XXX need to obey ExecMask here */ - micro_max(dst, chan, &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]); - micro_min(dst, dst, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]); + micro_max( dst, chan, &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); + micro_min( dst, dst, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); break; case TGSI_SAT_MINUS_PLUS_ONE: -- cgit v1.2.3 From 6aacca106b0619d87015aece1a0b1d6332910926 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 18 Aug 2008 17:03:56 +0200 Subject: tgsi: Respect condition codes when storing destination register. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 121 ++++++++++++++++++++++++++++++--- 1 file changed, 113 insertions(+), 8 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 6b19ab5c8e..1217ee71a5 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1120,7 +1120,9 @@ store_dest( const struct tgsi_full_instruction *inst, uint chan_index ) { + uint i; union tgsi_exec_channel *dst; + uint execmask = mach->ExecMask; switch (reg->DstRegister.File) { case TGSI_FILE_NULL: @@ -1145,16 +1147,119 @@ store_dest( return; } + if (inst->InstructionExtNv.CondFlowEnable) { + union tgsi_exec_channel *cc = &mach->Temps[TEMP_CC_I].xyzw[TEMP_CC_C]; + uint swizzle; + uint shift; + uint mask; + uint test; + + /* Only CC0 supported. + */ + assert( inst->InstructionExtNv.CondFlowIndex < 1 ); + + switch (chan_index) { + case CHAN_X: + swizzle = inst->InstructionExtNv.CondSwizzleX; + break; + case CHAN_Y: + swizzle = inst->InstructionExtNv.CondSwizzleY; + break; + case CHAN_Z: + swizzle = inst->InstructionExtNv.CondSwizzleZ; + break; + case CHAN_W: + swizzle = inst->InstructionExtNv.CondSwizzleW; + break; + default: + assert( 0 ); + return; + } + + switch (swizzle) { + case TGSI_SWIZZLE_X: + shift = TGSI_EXEC_CC_X_SHIFT; + mask = TGSI_EXEC_CC_X_MASK; + break; + case TGSI_SWIZZLE_Y: + shift = TGSI_EXEC_CC_Y_SHIFT; + mask = TGSI_EXEC_CC_Y_MASK; + break; + case TGSI_SWIZZLE_Z: + shift = TGSI_EXEC_CC_Z_SHIFT; + mask = TGSI_EXEC_CC_Z_MASK; + break; + case TGSI_SWIZZLE_W: + shift = TGSI_EXEC_CC_W_SHIFT; + mask = TGSI_EXEC_CC_W_MASK; + break; + default: + assert( 0 ); + return; + } + + switch (inst->InstructionExtNv.CondMask) { + case TGSI_CC_GT: + test = ~(TGSI_EXEC_CC_GT << shift) & mask; + for (i = 0; i < QUAD_SIZE; i++) + if (cc->u[i] & test) + execmask &= ~(1 << i); + break; + + case TGSI_CC_EQ: + test = ~(TGSI_EXEC_CC_EQ << shift) & mask; + for (i = 0; i < QUAD_SIZE; i++) + if (cc->u[i] & test) + execmask &= ~(1 << i); + break; + + case TGSI_CC_LT: + test = ~(TGSI_EXEC_CC_LT << shift) & mask; + for (i = 0; i < QUAD_SIZE; i++) + if (cc->u[i] & test) + execmask &= ~(1 << i); + break; + + case TGSI_CC_GE: + test = ~((TGSI_EXEC_CC_GT | TGSI_EXEC_CC_EQ) << shift) & mask; + for (i = 0; i < QUAD_SIZE; i++) + if (cc->u[i] & test) + execmask &= ~(1 << i); + break; + + case TGSI_CC_LE: + test = ~((TGSI_EXEC_CC_LT | TGSI_EXEC_CC_EQ) << shift) & mask; + for (i = 0; i < QUAD_SIZE; i++) + if (cc->u[i] & test) + execmask &= ~(1 << i); + break; + + case TGSI_CC_NE: + test = ~((TGSI_EXEC_CC_GT | TGSI_EXEC_CC_LT | TGSI_EXEC_CC_UN) << shift) & mask; + for (i = 0; i < QUAD_SIZE; i++) + if (cc->u[i] & test) + execmask &= ~(1 << i); + break; + + case TGSI_CC_TR: + break; + + case TGSI_CC_FL: + for (i = 0; i < QUAD_SIZE; i++) + execmask &= ~(1 << i); + break; + + default: + assert( 0 ); + return; + } + } + switch (inst->Instruction.Saturate) { case TGSI_SAT_NONE: - if (mach->ExecMask & 0x1) - dst->i[0] = chan->i[0]; - if (mach->ExecMask & 0x2) - dst->i[1] = chan->i[1]; - if (mach->ExecMask & 0x4) - dst->i[2] = chan->i[2]; - if (mach->ExecMask & 0x8) - dst->i[3] = chan->i[3]; + for (i = 0; i < QUAD_SIZE; i++) + if (execmask & (1 << i)) + dst->i[i] = chan->i[i]; break; case TGSI_SAT_ZERO_ONE: -- cgit v1.2.3 From 56c30bf17b9f57efdb93ae5d1b801677535a9651 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 18 Aug 2008 17:09:20 +0200 Subject: tgsi: Saturate modifier obeys ExecMask. Implement NVIDIA [-1;+1] saturate mode. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 1217ee71a5..dfd22270c8 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1263,13 +1263,27 @@ store_dest( break; case TGSI_SAT_ZERO_ONE: - /* XXX need to obey ExecMask here */ - micro_max( dst, chan, &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - micro_min( dst, dst, &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] ); + for (i = 0; i < QUAD_SIZE; i++) + if (execmask & (1 << i)) { + if (chan->f[i] < 0.0f) + dst->f[i] = 0.0f; + else if (chan->f[i] > 1.0f) + dst->f[i] = 1.0f; + else + dst->i[i] = chan->i[i]; + } break; case TGSI_SAT_MINUS_PLUS_ONE: - assert( 0 ); + for (i = 0; i < QUAD_SIZE; i++) + if (execmask & (1 << i)) { + if (chan->f[i] < -1.0f) + dst->f[i] = -1.0f; + else if (chan->f[i] > 1.0f) + dst->f[i] = 1.0f; + else + dst->i[i] = chan->i[i]; + } break; default: -- cgit v1.2.3 From e9ec60097cfed372f202aa64aa04674448881f0e Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 18 Aug 2008 17:18:58 +0200 Subject: tgsi: Update condition code vector when storing dest register. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 49 +++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index dfd22270c8..a2235de059 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1121,12 +1121,14 @@ store_dest( uint chan_index ) { uint i; + union tgsi_exec_channel null; union tgsi_exec_channel *dst; uint execmask = mach->ExecMask; switch (reg->DstRegister.File) { case TGSI_FILE_NULL: - return; + dst = &null; + break; case TGSI_FILE_OUTPUT: dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] @@ -1289,6 +1291,51 @@ store_dest( default: assert( 0 ); } + + if (inst->InstructionExtNv.CondDstUpdate) { + union tgsi_exec_channel *cc = &mach->Temps[TEMP_CC_I].xyzw[TEMP_CC_C]; + uint shift; + uint mask; + + /* Only CC0 supported. + */ + assert( inst->InstructionExtNv.CondDstIndex < 1 ); + + switch (chan_index) { + case CHAN_X: + shift = TGSI_EXEC_CC_X_SHIFT; + mask = ~TGSI_EXEC_CC_X_MASK; + break; + case CHAN_Y: + shift = TGSI_EXEC_CC_Y_SHIFT; + mask = ~TGSI_EXEC_CC_Y_MASK; + break; + case CHAN_Z: + shift = TGSI_EXEC_CC_Z_SHIFT; + mask = ~TGSI_EXEC_CC_Z_MASK; + break; + case CHAN_W: + shift = TGSI_EXEC_CC_W_SHIFT; + mask = ~TGSI_EXEC_CC_W_MASK; + break; + default: + assert( 0 ); + return; + } + + for (i = 0; i < QUAD_SIZE; i++) + if (execmask & (1 << i)) { + cc->u[i] &= mask; + if (dst->f[i] < 0.0f) + cc->u[i] |= TGSI_EXEC_CC_LT << shift; + else if (dst->f[i] > 0.0f) + cc->u[i] |= TGSI_EXEC_CC_GT << shift; + else if (dst->f[i] == 0.0f) + cc->u[i] |= TGSI_EXEC_CC_EQ << shift; + else + cc->u[i] |= TGSI_EXEC_CC_UN << shift; + } + } } #define FETCH(VAL,INDEX,CHAN)\ -- cgit v1.2.3 From 235981d8719aa7f67bfe547bf96e5343020e0373 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 18 Aug 2008 17:49:01 +0200 Subject: gallium: Remove TGSI_CC_UN. --- src/gallium/include/pipe/p_shader_tokens.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 3ab0c7deaf..f3e339619d 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -469,12 +469,11 @@ struct tgsi_instruction_ext #define TGSI_CC_GT 0 #define TGSI_CC_EQ 1 #define TGSI_CC_LT 2 -#define TGSI_CC_UN 3 -#define TGSI_CC_GE 4 -#define TGSI_CC_LE 5 -#define TGSI_CC_NE 6 -#define TGSI_CC_TR 7 -#define TGSI_CC_FL 8 +#define TGSI_CC_GE 3 +#define TGSI_CC_LE 4 +#define TGSI_CC_NE 5 +#define TGSI_CC_TR 6 +#define TGSI_CC_FL 7 #define TGSI_SWIZZLE_X 0 #define TGSI_SWIZZLE_Y 1 -- cgit v1.2.3 From 6a31bb6ad8251ae977327e64562f373a89f55c70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 16 Aug 2008 18:45:00 +0100 Subject: trace: Get the trace file from the GALLIUM_TRACE option itself. --- src/gallium/drivers/trace/README | 9 ++++----- src/gallium/drivers/trace/tr_dump.c | 7 +++++-- src/gallium/drivers/trace/tr_stream.c | 6 +----- src/gallium/drivers/trace/tr_stream.h | 3 ++- 4 files changed, 12 insertions(+), 13 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index 5f0ae2c641..7e98ec2454 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -8,7 +8,6 @@ To use do ln -s libGL.so build/linux-x86-debug/gallium/winsys/xlib/libGL.so.1 export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/gallium/winsys/xlib - export GALLIUM_TRACE=y ensure the right libGL.so is being picked by doing @@ -16,11 +15,11 @@ ensure the right libGL.so is being picked by doing and then try running - glxinfo + GALLIUM_TRACE=tri.trace ./progs/trivial/tri -which should create a gallium.*.trace file, which is an XML file. You can view -copying trace.xsl and trace.css to the same directory, and opening with a -XSLT capable browser like Firefox or Internet Explorer. +which should create a tri.trace file, which is an XML file. You can view copying +trace.xsl to the same directory, and opening with a XSLT capable browser like +Firefox or Internet Explorer. -- Jose Fonseca diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index c711a56b94..ecd0d6830d 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -218,12 +218,15 @@ trace_dump_trace_close(void) boolean trace_dump_trace_begin() { - if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) + const char *filename; + + filename = debug_get_option("GALLIUM_TRACE", NULL); + if(!filename) return FALSE; if(!stream) { - stream = trace_stream_create("gallium", "trace"); + stream = trace_stream_create(filename); if(!stream) return FALSE; diff --git a/src/gallium/drivers/trace/tr_stream.c b/src/gallium/drivers/trace/tr_stream.c index aecc1286b8..d008dbac27 100644 --- a/src/gallium/drivers/trace/tr_stream.c +++ b/src/gallium/drivers/trace/tr_stream.c @@ -47,18 +47,14 @@ struct trace_stream struct trace_stream * -trace_stream_create(const char *name, const char *ext) +trace_stream_create(const char *filename) { struct trace_stream *stream; - static unsigned file_no = 0; - char filename[1024]; stream = CALLOC_STRUCT(trace_stream); if(!stream) goto error1; - snprintf(filename, sizeof(filename), "%s.%u.%s", name, file_no, ext); - #if defined(PIPE_OS_LINUX) stream->file = fopen(filename, "w"); if(!stream->file) diff --git a/src/gallium/drivers/trace/tr_stream.h b/src/gallium/drivers/trace/tr_stream.h index 679c4a725d..6111174d6a 100644 --- a/src/gallium/drivers/trace/tr_stream.h +++ b/src/gallium/drivers/trace/tr_stream.h @@ -39,11 +39,12 @@ #include "pipe/p_compiler.h" + struct trace_stream; struct trace_stream * -trace_stream_create(const char *name, const char *ext); +trace_stream_create(const char *filename); boolean trace_stream_write(struct trace_stream *stream, const void *data, size_t size); -- cgit v1.2.3 From d042f415fc9edcc174573fc2cc06afa373a7ef9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 16 Aug 2008 19:44:37 +0100 Subject: trace: Use long longs to ensure covering 64bits integers. --- src/gallium/drivers/trace/tr_dump.c | 8 ++++---- src/gallium/drivers/trace/tr_dump.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index ecd0d6830d..1613a626df 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -302,14 +302,14 @@ void trace_dump_bool(int value) trace_dump_writef("%c", value ? '1' : '0'); } -void trace_dump_int(long int value) +void trace_dump_int(long long int value) { - trace_dump_writef("%li", value); + trace_dump_writef("%lli", value); } -void trace_dump_uint(long unsigned value) +void trace_dump_uint(long long unsigned value) { - trace_dump_writef("%lu", value); + trace_dump_writef("%llu", value); } void trace_dump_float(double value) diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index 14176a78e9..6ddc8fc15c 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -48,8 +48,8 @@ void trace_dump_arg_end(void); void trace_dump_ret_begin(void); void trace_dump_ret_end(void); void trace_dump_bool(int value); -void trace_dump_int(long int value); -void trace_dump_uint(long unsigned value); +void trace_dump_int(long long int value); +void trace_dump_uint(long long unsigned value); void trace_dump_float(double value); void trace_dump_bytes(const void *data, long unsigned size); void trace_dump_string(const char *str); -- cgit v1.2.3 From 747762f379f05d127865de77615d6e4dd46be191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Sat, 16 Aug 2008 19:45:05 +0100 Subject: trace: Preliminary stream implementation for GDI. --- src/gallium/drivers/trace/SConscript | 3 +- src/gallium/drivers/trace/tr_stream.c | 108 ----------------------- src/gallium/drivers/trace/tr_stream_stdc.c | 104 ++++++++++++++++++++++ src/gallium/drivers/trace/tr_stream_wd.c | 134 +++++++++++++++++++++++++++++ 4 files changed, 240 insertions(+), 109 deletions(-) delete mode 100644 src/gallium/drivers/trace/tr_stream.c create mode 100644 src/gallium/drivers/trace/tr_stream_stdc.c create mode 100644 src/gallium/drivers/trace/tr_stream_wd.c (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript index a21ced9176..5c49468c4e 100644 --- a/src/gallium/drivers/trace/SConscript +++ b/src/gallium/drivers/trace/SConscript @@ -9,7 +9,8 @@ trace = env.ConvenienceLibrary( 'tr_dump.c', 'tr_screen.c', 'tr_state.c', - 'tr_stream.c', + 'tr_stream_stdc.c', + 'tr_stream_wd.c', 'tr_texture.c', 'tr_winsys.c', ]) diff --git a/src/gallium/drivers/trace/tr_stream.c b/src/gallium/drivers/trace/tr_stream.c deleted file mode 100644 index d008dbac27..0000000000 --- a/src/gallium/drivers/trace/tr_stream.c +++ /dev/null @@ -1,108 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_config.h" - -#if defined(PIPE_OS_LINUX) -#include -#else -#error Unsupported platform -#endif - -#include "pipe/p_util.h" - -#include "tr_stream.h" - - -struct trace_stream -{ -#if defined(PIPE_OS_LINUX) - FILE *file; -#endif -}; - - -struct trace_stream * -trace_stream_create(const char *filename) -{ - struct trace_stream *stream; - - stream = CALLOC_STRUCT(trace_stream); - if(!stream) - goto error1; - -#if defined(PIPE_OS_LINUX) - stream->file = fopen(filename, "w"); - if(!stream->file) - goto error2; -#endif - - return stream; - -error2: - FREE(stream); -error1: - return NULL; -} - - -boolean -trace_stream_write(struct trace_stream *stream, const void *data, size_t size) -{ - if(!stream) - return FALSE; - -#if defined(PIPE_OS_LINUX) - return fwrite(data, size, 1, stream->file) == size ? TRUE : FALSE; -#endif -} - - -void -trace_stream_flush(struct trace_stream *stream) -{ - if(!stream) - return; - -#if defined(PIPE_OS_LINUX) - fflush(stream->file); -#endif -} - - -void -trace_stream_close(struct trace_stream *stream) -{ - if(!stream) - return; - -#if defined(PIPE_OS_LINUX) - fclose(stream->file); -#endif - - FREE(stream); -} diff --git a/src/gallium/drivers/trace/tr_stream_stdc.c b/src/gallium/drivers/trace/tr_stream_stdc.c new file mode 100644 index 0000000000..4c77e1c995 --- /dev/null +++ b/src/gallium/drivers/trace/tr_stream_stdc.c @@ -0,0 +1,104 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Stream implementation based on the Standard C Library. + */ + +#include "pipe/p_config.h" + +#if defined(PIPE_OS_LINUX) + +#include + +#include "pipe/p_util.h" + +#include "tr_stream.h" + + +struct trace_stream +{ + FILE *file; +}; + + +struct trace_stream * +trace_stream_create(const char *filename) +{ + struct trace_stream *stream; + + stream = CALLOC_STRUCT(trace_stream); + if(!stream) + goto error1; + + stream->file = fopen(filename, "w"); + if(!stream->file) + goto error2; + + return stream; + +error2: + FREE(stream); +error1: + return NULL; +} + + +boolean +trace_stream_write(struct trace_stream *stream, const void *data, size_t size) +{ + if(!stream) + return FALSE; + + return fwrite(data, size, 1, stream->file) == size ? TRUE : FALSE; +} + + +void +trace_stream_flush(struct trace_stream *stream) +{ + if(!stream) + return; + + fflush(stream->file); +} + + +void +trace_stream_close(struct trace_stream *stream) +{ + if(!stream) + return; + + fclose(stream->file); + + FREE(stream); +} + + +#endif diff --git a/src/gallium/drivers/trace/tr_stream_wd.c b/src/gallium/drivers/trace/tr_stream_wd.c new file mode 100644 index 0000000000..9a05c0cec8 --- /dev/null +++ b/src/gallium/drivers/trace/tr_stream_wd.c @@ -0,0 +1,134 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Stream implementation for the Windows Display driver. + */ + +#include "pipe/p_config.h" + +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + +#include +#include + +#include "pipe/p_util.h" + +#include "tr_stream.h" + + +#define MAP_FILE_SIZE (4*1024*1024) + + +struct trace_stream +{ + WCHAR wFileName[MAX_PATH + 1]; + ULONG_PTR iFile; + char *pMap; + size_t written; +}; + + +struct trace_stream * +trace_stream_create(const char *filename) +{ + struct trace_stream *stream; + ULONG BytesInUnicodeString; + + stream = CALLOC_STRUCT(trace_stream); + if(!stream) + goto error1; + + EngMultiByteToUnicodeN( + stream->wFileName, + sizeof(stream->wFileName), + &BytesInUnicodeString, + (char *)filename, + strlen(filename)); + + stream->pMap = EngMapFile(stream->wFileName, MAP_FILE_SIZE, &stream->iFile); + if(!stream->pMap) + goto error2; + + return stream; + +error2: + FREE(stream); +error1: + return NULL; +} + + +boolean +trace_stream_write(struct trace_stream *stream, const void *data, size_t size) +{ + boolean ret; + + if(!stream) + return FALSE; + + if(stream->written + size > MAP_FILE_SIZE) { + ret = FALSE; + size = MAP_FILE_SIZE - stream->written; + } + else + ret = TRUE; + + memcpy(stream->pMap + stream->written, data, size); + stream->written += size; + + return ret; +} + + +void +trace_stream_flush(struct trace_stream *stream) +{ + (void)stream; +} + + +void +trace_stream_close(struct trace_stream *stream) +{ + if(!stream) + return; + + EngUnmapFile(stream->iFile); + if(stream->written < MAP_FILE_SIZE) { + /* Truncate file size */ + stream->pMap = EngMapFile(stream->wFileName, stream->written, &stream->iFile); + if(stream->pMap) + EngUnmapFile(stream->iFile); + } + + FREE(stream); +} + + +#endif -- cgit v1.2.3 From 90a1c6e4032571a1c3e43daeb357068ba14136fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 18 Aug 2008 12:42:08 +0100 Subject: trace: Explain how to integrate with a state tracker or winsys. --- src/gallium/drivers/trace/README | 45 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index 7e98ec2454..e7a2f12b02 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -1,9 +1,20 @@ + TRACE PIPE DRIVER + + += About = + This directory contains a Gallium3D pipe driver which traces all incoming calls. + += Build Instructions = + To build, invoke scons on the top dir as scons statetrackers=mesa drivers=softpipe,i915simple,trace winsys=xlib + += Usage = + To use do ln -s libGL.so build/linux-x86-debug/gallium/winsys/xlib/libGL.so.1 @@ -11,15 +22,43 @@ To use do ensure the right libGL.so is being picked by doing - ldd `which glxinfo` + ldd progs/trivial/tri and then try running - GALLIUM_TRACE=tri.trace ./progs/trivial/tri + GALLIUM_TRACE=tri.trace progs/trivial/tri which should create a tri.trace file, which is an XML file. You can view copying -trace.xsl to the same directory, and opening with a XSLT capable browser like +trace.xsl to the same directory, and opening with a XSLT capable browser such as Firefox or Internet Explorer. + += Integrating = + +You can integrate the trace pipe driver either inside the state tracker or the +winsys. The procedure on both cases is the same. Let's assume you have a +pipe_screen and a pipe_context pair obtained by the usual means (variable and +function names are just for illustration purposes): + + real_screen = real_screen_create(...); + + real_context = real_context_create(...); + +The trace screen and pipe_context is then created by doing + + trace_screen = trace_screen_create(real_screen); + + trace_context = trace_context_create(trace_screen, real_context); + +You can then simply use trace_screen and trace_context instead of real_screen +and real_context. + +Do not call trace_winsys_create. Simply pass trace_screen->winsys or +trace_context->winsys in places you would pass winsys. + +You can create as many contexts you wish. Just ensure that you don't mistake +trace_screen with real_screen when creating them. + + -- Jose Fonseca -- cgit v1.2.3 From 93305bd6808787964c0088a88c428ecd1208aa44 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 18 Aug 2008 18:09:23 +0200 Subject: tgsi: Use NUM_CHANNELS. --- src/gallium/auxiliary/tgsi/tgsi_sse2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 47dc06faf6..0bf260c4dd 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -44,13 +44,13 @@ #define FOR_EACH_CHANNEL( CHAN )\ - for( CHAN = 0; CHAN < 4; CHAN++ ) + for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++) #define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ ((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN))) #define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ - if( IS_DST0_CHANNEL_ENABLED( INST, CHAN )) + if (IS_DST0_CHANNEL_ENABLED( INST, CHAN )) #define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\ FOR_EACH_CHANNEL( CHAN )\ @@ -1172,7 +1172,7 @@ emit_instruction( { unsigned chan_index; - switch( inst->Instruction.Opcode ) { + switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ARL: #if 0 /* XXX this isn't working properly (see glean vertProg1 test) */ -- cgit v1.2.3 From 2b512c0135bc8512cc80009ea7430f7cc0c869d6 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 18 Aug 2008 22:21:32 +0200 Subject: tgsi: Workaround debug output buffer size limitations. --- src/gallium/auxiliary/tgsi/tgsi_dump.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index 4309d1bc76..a168c94928 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -518,8 +518,23 @@ tgsi_dump( uint flags ) { static char str[4096]; - + uint len; + char *p = str; + tgsi_dump_str(tokens, flags, str, sizeof(str)); - - debug_printf("%s", str); + + /* Workaround output buffer size limitations. + */ + len = strlen( str ); + while (len > 256) { + char piggy_bank; + + piggy_bank = p[256]; + p[256] = '\0'; + debug_printf( "%s", p ); + p[256] = piggy_bank; + p += 256; + len -= 256; + } + debug_printf( "%s", p ); } -- cgit v1.2.3 From de3083be7197cccb8dbf223d644ebdb78a8c809d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 19 Aug 2008 00:42:30 +0200 Subject: tgsi: Fix ARL opcode in SSE2 codegen. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 6 +-- src/gallium/auxiliary/tgsi/tgsi_sse2.c | 87 +++++++++++++++++++++++++--------- 2 files changed, 68 insertions(+), 25 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index a2235de059..b793e1ebae 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1688,9 +1688,9 @@ exec_instruction( switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ARL: FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( &r[0], 0, chan_index ); - micro_f2it( &r[0], &r[0] ); - STORE( &r[0], 0, chan_index ); + FETCH( &r[0], 0, chan_index ); + micro_f2it( &r[0], &r[0] ); + STORE( &r[0], 0, chan_index ); } break; diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 0bf260c4dd..ca48d422e0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -62,6 +62,7 @@ #define CHAN_W 3 #define TEMP_R0 TGSI_EXEC_TEMP_R0 +#define TEMP_ADDR TGSI_EXEC_TEMP_ADDR /** * X86 utility functions. @@ -215,19 +216,61 @@ emit_ret( static void emit_const( struct x86_function *func, - unsigned xmm, - unsigned vec, - unsigned chan ) -{ - sse_movss( - func, - make_xmm( xmm ), - get_const( vec, chan ) ); - sse_shufps( - func, - make_xmm( xmm ), - make_xmm( xmm ), - SHUF( 0, 0, 0, 0 ) ); + uint xmm, + int vec, + uint chan, + uint indirect, + uint indirectFile, + int indirectIndex ) +{ + if (indirect) { + struct x86_reg r0 = get_input_base(); + struct x86_reg r1 = get_output_base(); + uint i; + + assert( indirectFile == TGSI_FILE_ADDRESS ); + assert( indirectIndex == 0 ); + + x86_push( func, r0 ); + x86_push( func, r1 ); + + for (i = 0; i < QUAD_SIZE; i++) { + x86_lea( func, r0, get_const( vec, chan ) ); + x86_mov( func, r1, x86_make_disp( get_temp( TEMP_ADDR, CHAN_X ), i * 4 ) ); + + /* Quick hack to multiply by 16 -- need to add SHL to rtasm. + */ + x86_add( func, r1, r1 ); + x86_add( func, r1, r1 ); + x86_add( func, r1, r1 ); + x86_add( func, r1, r1 ); + + x86_add( func, r0, r1 ); + x86_mov( func, r1, x86_deref( r0 ) ); + x86_mov( func, x86_make_disp( get_temp( TEMP_R0, CHAN_X ), i * 4 ), r1 ); + } + + x86_pop( func, r1 ); + x86_pop( func, r0 ); + + sse_movaps( + func, + make_xmm( xmm ), + get_temp( TEMP_R0, CHAN_X ) ); + } + else { + assert( vec >= 0 ); + + sse_movss( + func, + make_xmm( xmm ), + get_const( vec, chan ) ); + sse_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); + } } static void @@ -369,10 +412,12 @@ emit_addrs( unsigned vec, unsigned chan ) { + assert( vec == 0 ); + emit_temps( func, xmm, - vec + TGSI_EXEC_NUM_TEMPS, + vec + TGSI_EXEC_TEMP_ADDR, chan ); } @@ -855,18 +900,21 @@ emit_fetch( { unsigned swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index ); - switch( swizzle ) { + switch (swizzle) { case TGSI_EXTSWIZZLE_X: case TGSI_EXTSWIZZLE_Y: case TGSI_EXTSWIZZLE_Z: case TGSI_EXTSWIZZLE_W: - switch( reg->SrcRegister.File ) { + switch (reg->SrcRegister.File) { case TGSI_FILE_CONSTANT: emit_const( func, xmm, reg->SrcRegister.Index, - swizzle ); + swizzle, + reg->SrcRegister.Indirect, + reg->SrcRegisterInd.File, + reg->SrcRegisterInd.Index ); break; case TGSI_FILE_IMMEDIATE: @@ -1174,16 +1222,11 @@ emit_instruction( switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ARL: -#if 0 - /* XXX this isn't working properly (see glean vertProg1 test) */ FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); emit_f2it( func, 0 ); STORE( func, *inst, 0, 0, chan_index ); } -#else - return 0; -#endif break; case TGSI_OPCODE_MOV: -- cgit v1.2.3 From f9e14e0daca3b2f3662a68413c2fa71c05375b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Aug 2008 00:18:19 +0100 Subject: xlib: Revert destroying pipe_screen (temporary). --- src/gallium/winsys/xlib/xm_api.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_api.c b/src/gallium/winsys/xlib/xm_api.c index d2f92a0875..7256340420 100644 --- a/src/gallium/winsys/xlib/xm_api.c +++ b/src/gallium/winsys/xlib/xm_api.c @@ -847,7 +847,10 @@ void XMesaDestroyContext( XMesaContext c ) { struct pipe_screen *screen = c->st->pipe->screen; st_destroy_context(c->st); + /* FIXME: We should destroy the screen here, but if we do so, surfaces may + * outlive it, causing segfaults screen->destroy(screen); + */ _mesa_free(c); } -- cgit v1.2.3 From 0d9d2045e86a249a36d8eeebf59979a162c164af Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 19 Aug 2008 11:47:30 +0200 Subject: tgsi: Implement EXP opcode for SSE2. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 8 ++--- src/gallium/auxiliary/tgsi/tgsi_sse2.c | 64 ++++++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index b793e1ebae..d584a4e4fa 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1756,18 +1756,18 @@ exec_instruction( micro_flr( &r[1], &r[0] ); /* r1 = floor(r0) */ if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { micro_exp2( &r[2], &r[1] ); /* r2 = 2 ^ r1 */ - STORE( &r[2], 0, CHAN_X ); /* store r2 */ + STORE( &r[2], 0, CHAN_X ); /* store r2 */ } if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { micro_sub( &r[2], &r[0], &r[1] ); /* r2 = r0 - r1 */ - STORE( &r[2], 0, CHAN_Y ); /* store r2 */ + STORE( &r[2], 0, CHAN_Y ); /* store r2 */ } if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { micro_exp2( &r[2], &r[0] ); /* r2 = 2 ^ r0 */ - STORE( &r[2], 0, CHAN_Z ); /* store r2 */ + STORE( &r[2], 0, CHAN_Z ); /* store r2 */ } if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); } break; diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index ca48d422e0..684bc081e5 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -61,6 +61,9 @@ #define CHAN_Z 2 #define CHAN_W 3 +#define TEMP_ONE_I TGSI_EXEC_TEMP_ONE_I +#define TEMP_ONE_C TGSI_EXEC_TEMP_ONE_C + #define TEMP_R0 TGSI_EXEC_TEMP_R0 #define TEMP_ADDR TGSI_EXEC_TEMP_ADDR @@ -958,8 +961,8 @@ emit_fetch( emit_tempf( func, xmm, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); + TEMP_ONE_I, + TEMP_ONE_C ); break; default: @@ -1173,8 +1176,8 @@ emit_setcc( func, make_xmm( 0 ), get_temp( - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ) ); + TEMP_ONE_I, + TEMP_ONE_C ) ); STORE( func, *inst, 0, 0, chan_index ); } } @@ -1243,8 +1246,8 @@ emit_instruction( emit_tempf( func, 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C); + TEMP_ONE_I, + TEMP_ONE_C); if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ) { STORE( func, *inst, 0, 0, CHAN_X ); } @@ -1329,7 +1332,38 @@ emit_instruction( break; case TGSI_OPCODE_EXP: - return 0; + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( func, *inst, 0, 0, CHAN_X ); + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y )) { + emit_MOV( func, 1, 0 ); + emit_flr( func, 1 ); + /* dst.x = ex2(floor(src.x)) */ + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X )) { + emit_MOV( func, 2, 1 ); + emit_ex2( func, 2 ); + STORE( func, *inst, 2, 0, CHAN_X ); + } + /* dst.y = src.x - floor(src.x) */ + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y )) { + emit_MOV( func, 2, 0 ); + emit_sub( func, 2, 1 ); + STORE( func, *inst, 2, 0, CHAN_Y ); + } + } + /* dst.z = ex2(src.x) */ + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z )) { + emit_ex2( func, 0 ); + STORE( func, *inst, 0, 0, CHAN_Z ); + } + } + /* dst.w = 1.0 */ + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W )) { + emit_tempf( func, 0, TEMP_ONE_I, TEMP_ONE_C ); + STORE( func, *inst, 0, 0, CHAN_W ); + } break; case TGSI_OPCODE_LOG: @@ -1399,8 +1433,8 @@ emit_instruction( emit_tempf( func, 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); + TEMP_ONE_I, + TEMP_ONE_C ); STORE( func, *inst, 0, 0, CHAN_X ); } IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) { @@ -1603,8 +1637,8 @@ emit_instruction( emit_tempf( func, 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); + TEMP_ONE_I, + TEMP_ONE_C ); STORE( func, *inst, 0, 0, CHAN_W ); } break; @@ -1731,8 +1765,8 @@ emit_instruction( emit_tempf( func, 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); + TEMP_ONE_I, + TEMP_ONE_C ); FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { STORE( func, *inst, 0, 0, chan_index ); } @@ -1820,8 +1854,8 @@ emit_instruction( emit_tempf( func, 0, - TGSI_EXEC_TEMP_ONE_I, - TGSI_EXEC_TEMP_ONE_C ); + TEMP_ONE_I, + TEMP_ONE_C ); STORE( func, *inst, 0, 0, CHAN_W ); } break; -- cgit v1.2.3 From 4405e428e4c2a80172c803cc3c4933d546bf2b4d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 19 Aug 2008 12:07:25 +0200 Subject: tgsi: Implement LOG opcode for SSE2 codegen. --- src/gallium/auxiliary/tgsi/tgsi_exec.c | 8 ++++---- src/gallium/auxiliary/tgsi/tgsi_sse2.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 5 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index d584a4e4fa..88a34a6961 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1777,18 +1777,18 @@ exec_instruction( micro_lg2( &r[1], &r[2] ); /* r1 = lg2(r2) */ micro_flr( &r[0], &r[1] ); /* r0 = floor(r1) */ if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - STORE( &r[0], 0, CHAN_X ); + STORE( &r[0], 0, CHAN_X ); } if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { micro_exp2( &r[0], &r[0] ); /* r0 = 2 ^ r0 */ micro_div( &r[0], &r[2], &r[0] ); /* r0 = r2 / r0 */ - STORE( &r[0], 0, CHAN_Y ); + STORE( &r[0], 0, CHAN_Y ); } if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - STORE( &r[1], 0, CHAN_Z ); + STORE( &r[1], 0, CHAN_Z ); } if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); + STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); } break; diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 684bc081e5..485e5a0e6f 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -1367,7 +1367,38 @@ emit_instruction( break; case TGSI_OPCODE_LOG: - return 0; + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z )) { + FETCH( func, *inst, 0, 0, CHAN_X ); + emit_abs( func, 0 ); + emit_MOV( func, 1, 0 ); + emit_lg2( func, 1 ); + /* dst.z = lg2(abs(src.x)) */ + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z )) { + STORE( func, *inst, 1, 0, CHAN_Z ); + } + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) || + IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y )) { + emit_flr( func, 1 ); + /* dst.x = floor(lg2(abs(src.x))) */ + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X )) { + STORE( func, *inst, 1, 0, CHAN_X ); + } + /* dst.x = abs(src)/ex2(floor(lg2(abs(src.x)))) */ + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y )) { + emit_ex2( func, 1 ); + emit_rcp( func, 1, 1 ); + emit_mul( func, 0, 1 ); + STORE( func, *inst, 0, 0, CHAN_Y ); + } + } + } + /* dst.w = 1.0 */ + if (IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W )) { + emit_tempf( func, 0, TEMP_ONE_I, TEMP_ONE_C ); + STORE( func, *inst, 0, 0, CHAN_W ); + } break; case TGSI_OPCODE_MUL: -- cgit v1.2.3 From 146a0fba0011e21a4831a4b86969d7cd3f093bf6 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 19 Aug 2008 15:32:09 +0200 Subject: gallium: Add note about vs_2_0 EXPP mapping. --- src/gallium/include/pipe/p_shader_tokens.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index f3e339619d..a562e3a6b1 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -382,6 +382,7 @@ struct tgsi_immediate_float32 */ #define TGSI_OPCODE_SGN TGSI_OPCODE_SSG #define TGSI_OPCODE_MOVA TGSI_OPCODE_ARR +/* EXPP - use TGSI_OPCODE_EX2 */ /* * vs_2_x -- cgit v1.2.3 From 200d6dcc83ea9ac0bf6f1506214e0bd9b65714f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Aug 2008 17:08:41 +0100 Subject: trace: Support C++. --- src/gallium/drivers/trace/tr_context.h | 9 +++++++++ src/gallium/drivers/trace/tr_screen.h | 9 +++++++++ 2 files changed, 18 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 679371e310..7831900ec2 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -34,6 +34,11 @@ #include "pipe/p_context.h" +#ifdef __cplusplus +extern "C" { +#endif + + struct trace_context { struct pipe_context base; @@ -56,4 +61,8 @@ trace_context_create(struct pipe_screen *screen, struct pipe_context *pipe); +#ifdef __cplusplus +} +#endif + #endif /* TR_CONTEXT_H_ */ diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h index 698b84811d..93fefdb9a5 100644 --- a/src/gallium/drivers/trace/tr_screen.h +++ b/src/gallium/drivers/trace/tr_screen.h @@ -32,6 +32,11 @@ #include "pipe/p_screen.h" +#ifdef __cplusplus +extern "C" { +#endif + + struct trace_screen { struct pipe_screen base; @@ -48,4 +53,8 @@ struct pipe_screen * trace_screen_create(struct pipe_screen *screen); +#ifdef __cplusplus +} +#endif + #endif /* TR_SCREEN_H_ */ -- cgit v1.2.3 From 5f1ef11ad2e3016ac4029489d9429d7f93737fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Aug 2008 18:25:38 +0100 Subject: python/retrace: Trim null chars. They are often left in memory mapped files, and are not part of the XML accept chars anyway. --- src/gallium/state_trackers/python/retrace/parser.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/src/gallium/state_trackers/python/retrace/parser.py index 9ee47f6e19..d02fd7f741 100755 --- a/src/gallium/state_trackers/python/retrace/parser.py +++ b/src/gallium/state_trackers/python/retrace/parser.py @@ -101,6 +101,7 @@ class XmlTokenizer: self.index = 0 data = self.fp.read(size) self.final = len(data) < size + data = data.rstrip('\0') try: self.parser.Parse(data, self.final) except xml.parsers.expat.ExpatError, e: -- cgit v1.2.3 From 9adfc57a4c4deeb86d8f62491b94d6a44586eb1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Aug 2008 19:11:36 +0100 Subject: python: Handle null state. --- src/gallium/state_trackers/python/p_context.i | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 535783b641..496f738ad5 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -68,6 +68,11 @@ struct st_context { void set_fragment_shader( const struct pipe_shader_state *state ) { void *fs; + if(!state) { + cso_set_fragment_shader_handle($self->cso, NULL); + return; + } + fs = $self->pipe->create_fs_state($self->pipe, state); if(!fs) return; @@ -82,6 +87,11 @@ struct st_context { void set_vertex_shader( const struct pipe_shader_state *state ) { void *vs; + if(!state) { + cso_set_vertex_shader_handle($self->cso, NULL); + return; + } + vs = $self->pipe->create_vs_state($self->pipe, state); if(!vs) return; -- cgit v1.2.3 From d27ffb8c6d4551371995608a6d752dfeb26c2351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Aug 2008 19:11:47 +0100 Subject: trace: Fix pipe_clip_state dump. --- src/gallium/drivers/trace/tr_state.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index 7b35e89e75..30ab5a8fdc 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -51,7 +51,6 @@ void trace_dump_block(const struct pipe_format_block *block) void trace_dump_template(const struct pipe_texture *templat) { - assert(templat); if(!templat) { trace_dump_null(); return; @@ -87,7 +86,6 @@ void trace_dump_template(const struct pipe_texture *templat) void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) { - assert(state); if(!state) { trace_dump_null(); return; @@ -136,7 +134,6 @@ void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) void trace_dump_poly_stipple(const struct pipe_poly_stipple *state) { - assert(state); if(!state) { trace_dump_null(); return; @@ -156,7 +153,6 @@ void trace_dump_poly_stipple(const struct pipe_poly_stipple *state) void trace_dump_viewport_state(const struct pipe_viewport_state *state) { - assert(state); if(!state) { trace_dump_null(); return; @@ -173,7 +169,6 @@ void trace_dump_viewport_state(const struct pipe_viewport_state *state) void trace_dump_scissor_state(const struct pipe_scissor_state *state) { - assert(state); if(!state) { trace_dump_null(); return; @@ -194,18 +189,20 @@ void trace_dump_clip_state(const struct pipe_clip_state *state) { unsigned i; - assert(state); if(!state) { trace_dump_null(); return; } - trace_dump_struct_begin("pipe_scissor_state"); + trace_dump_struct_begin("pipe_clip_state"); trace_dump_member_begin("ucp"); trace_dump_array_begin(); - for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) + for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) { + trace_dump_elem_begin(); trace_dump_array(float, state->ucp[i], 4); + trace_dump_elem_end(); + } trace_dump_array_end(); trace_dump_member_end(); @@ -217,7 +214,6 @@ void trace_dump_clip_state(const struct pipe_clip_state *state) void trace_dump_constant_buffer(const struct pipe_constant_buffer *state) { - assert(state); if(!state) { trace_dump_null(); return; @@ -235,7 +231,7 @@ void trace_dump_constant_buffer(const struct pipe_constant_buffer *state) void trace_dump_shader_state(const struct pipe_shader_state *state) { static char str[8192]; - assert(state); + if(!state) { trace_dump_null(); return; @@ -257,7 +253,6 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_ { unsigned i; - assert(state); if(!state) { trace_dump_null(); return; @@ -307,7 +302,6 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_ void trace_dump_blend_state(const struct pipe_blend_state *state) { - assert(state); if(!state) { trace_dump_null(); return; @@ -337,7 +331,6 @@ void trace_dump_blend_state(const struct pipe_blend_state *state) void trace_dump_blend_color(const struct pipe_blend_color *state) { - assert(state); if(!state) { trace_dump_null(); return; @@ -367,7 +360,6 @@ void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state) void trace_dump_sampler_state(const struct pipe_sampler_state *state) { - assert(state); if(!state) { trace_dump_null(); return; @@ -398,7 +390,6 @@ void trace_dump_sampler_state(const struct pipe_sampler_state *state) void trace_dump_surface(const struct pipe_surface *state) { - assert(state); if(!state) { trace_dump_null(); return; @@ -436,7 +427,6 @@ void trace_dump_surface(const struct pipe_surface *state) void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) { - assert(state); if(!state) { trace_dump_null(); return; @@ -455,7 +445,6 @@ void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) void trace_dump_vertex_element(const struct pipe_vertex_element *state) { - assert(state); if(!state) { trace_dump_null(); return; -- cgit v1.2.3 From d7f8b95e097121a8c33332f920115795853d6ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Aug 2008 19:12:22 +0100 Subject: python/retrace: Add several missing functions. --- .../state_trackers/python/retrace/interpreter.py | 57 ++++++++++++++++++---- 1 file changed, 48 insertions(+), 9 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index fa9a65365c..a7a7341e06 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -79,7 +79,7 @@ class Struct: struct_factories = { "pipe_blend_color": gallium.BlendColor, "pipe_blend_state": gallium.Blend, - "pipe_clip_state": gallium.Clip, + #"pipe_clip_state": gallium.Clip, #"pipe_constant_buffer": gallium.ConstantBuffer, "pipe_depth_state": gallium.Depth, "pipe_stencil_state": gallium.Stencil, @@ -103,7 +103,7 @@ member_array_factories = { "pipe_rasterizer_state": {"sprite_coord_mode": gallium.ByteArray}, "pipe_poly_stipple": {"stipple": gallium.UnsignedArray}, "pipe_viewport_state": {"scale": gallium.FloatArray, "translate": gallium.FloatArray}, - "pipe_clip_state": {"ucp": gallium.FloatArray}, + #"pipe_clip_state": {"ucp": gallium.FloatArray}, "pipe_depth_stencil_alpha_state": {"stencil": gallium.StencilArray}, "pipe_blend_color": {"color": gallium.FloatArray}, "pipe_sampler_state": {"border_color": gallium.FloatArray}, @@ -219,6 +219,12 @@ class Winsys(Object): def flush_frontbuffer(self, surface): pass + def surface_alloc(self): + return None + + def surface_release(self, surface): + pass + class Screen(Object): @@ -269,15 +275,25 @@ class Context(Object): self.cbufs = [] self.zsbuf = None + def destroy(self): + pass + def create_blend_state(self, state): return state def bind_blend_state(self, state): - self.real.set_blend(state) - + if state is not None: + self.real.set_blend(state) + + def delete_blend_state(self, state): + pass + def create_sampler_state(self, state): return state + def delete_sampler_state(self, state): + pass + def bind_sampler_states(self, n, states): for i in range(n): self.real.set_sampler(i, states[i]) @@ -286,14 +302,22 @@ class Context(Object): return state def bind_rasterizer_state(self, state): - self.real.set_rasterizer(state) + if state is not None: + self.real.set_rasterizer(state) + def delete_rasterizer_state(self, state): + pass + def create_depth_stencil_alpha_state(self, state): return state def bind_depth_stencil_alpha_state(self, state): - self.real.set_depth_stencil_alpha(state) - + if state is not None: + self.real.set_depth_stencil_alpha(state) + + def delete_depth_stencil_alpha_state(self, state): + pass + def create_fs_state(self, state): tokens = str(state.tokens) shader = gallium.Shader(tokens) @@ -307,14 +331,29 @@ class Context(Object): def bind_vs_state(self, state): self.real.set_vertex_shader(state) + def delete_fs_state(self, state): + pass + + delete_vs_state = delete_fs_state + def set_blend_color(self, state): self.real.set_blend_color(state) def set_clip_state(self, state): - self.real.set_clip(state) + _state = gallium.Clip() + _state.nr = state.nr + if state.nr: + # FIXME + ucp = gallium.FloatArray(gallium.PIPE_MAX_CLIP_PLANES*4) + for i in range(len(state.ucp)): + for j in range(len(state.ucp[i])): + ucp[i*4 + j] = state.ucp[i][j] + _state.ucp = ucp + self.real.set_clip(_state) def set_constant_buffer(self, shader, index, state): - self.real.set_constant_buffer(shader, index, state.buffer) + if state is not None: + self.real.set_constant_buffer(shader, index, state.buffer) def set_framebuffer_state(self, state): _state = gallium.Framebuffer() -- cgit v1.2.3 From 9e3aaa50483b61d644306d483feed564c69018bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 19 Aug 2008 21:33:59 +0100 Subject: gallium: WinCE build fixes. --- src/gallium/auxiliary/util/u_snprintf.c | 9 +++++++++ src/gallium/include/pipe/p_util.h | 6 ++++++ 2 files changed, 15 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_snprintf.c b/src/gallium/auxiliary/util/u_snprintf.c index 7fa84d8bec..0d54299b28 100644 --- a/src/gallium/auxiliary/util/u_snprintf.c +++ b/src/gallium/auxiliary/util/u_snprintf.c @@ -334,6 +334,15 @@ static void *mymemcpy(void *, void *, size_t); #endif /* HAVE_UINTPTR_T || defined(uintptr_t) */ #endif /* !defined(UINTPTR_T) */ +/* WinCE5.0 does not have uintptr_t defined */ +#if (_WIN32_WCE < 600) +#ifdef UINTPTR_T +#undef UINTPTR_T +#endif +#define UINTPTR_T unsigned long int +#endif + + /* Support for ptrdiff_t. */ #ifndef PTRDIFF_T #if HAVE_PTRDIFF_T || defined(ptrdiff_t) diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index b4ab70a3fc..473a8d94ab 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -99,6 +99,12 @@ __inline double __cdecl atan2(double val) #include #endif + /* Define ENOMEM for WINCE */ +#if (_WIN32_WCE < 600) +#ifndef ENOMEM +#define ENOMEM 12 +#endif +#endif #ifdef __cplusplus extern "C" { -- cgit v1.2.3 From 63c0970dca9c13ab83ea24f108b41f75f2a290a7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 19 Aug 2008 17:04:48 -0600 Subject: gallium: fix an assertion --- src/gallium/auxiliary/draw/draw_vs_varient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index ad0b829afa..994ce3e889 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -298,7 +298,7 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, emit.element[i].input_offset = key->element[i].out.vs_output * 4 * sizeof(float); emit.element[i].output_format = draw_translate_vinfo_format(key->element[i].out.format); emit.element[i].output_offset = key->element[i].out.offset; - assert(emit.element[i].input_offset < fetch.output_stride); + assert(emit.element[i].input_offset <= fetch.output_stride); } else { emit.element[i].input_format = PIPE_FORMAT_R32_FLOAT; -- cgit v1.2.3 From 7f9959ae8394f8e52a180f5e261b0f9470f6c5bc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 19 Aug 2008 17:41:34 -0600 Subject: gallium: fix do_flip bug in sp_surface_copy() Surfaces are always in y=0=top raster order so the caller should invert the Y coordinate if needed; don't do it in sp_surface_copy(). Fixes a glCopyTexture regression. --- src/gallium/drivers/softpipe/sp_surface.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index 7dc15c38d1..4f1bb881cb 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -39,6 +39,9 @@ * Copy a rectangular region from one surface to another. * Surfaces must have same bpp. * + * Note that it's always the case that Y=0=top of the raster. + * If do_flip is non-zero, the region being copied will be flipped vertically. + * * Assumes all values are within bounds -- no checking at this level - * do it higher up if required. */ @@ -72,7 +75,7 @@ sp_surface_copy(struct pipe_context *pipe, width, height, src_map, do_flip ? -(int) src->stride : src->stride, - srcx, do_flip ? src->height - 1 - srcy : srcy); + srcx, srcy); pipe->screen->surface_unmap(pipe->screen, src); pipe->screen->surface_unmap(pipe->screen, dst); -- cgit v1.2.3 From 1d881b8e8472ff49482b2b0404ac29160f096771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 20 Aug 2008 14:02:43 +0100 Subject: python: bindings for draw_range_elements. --- src/gallium/state_trackers/python/p_context.i | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 496f738ad5..0b2621f7c3 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -209,6 +209,16 @@ struct st_context { mode, start, count); } + void draw_range_elements( struct st_buffer *indexBuffer, + unsigned indexSize, unsigned minIndex, unsigned maxIndex, + unsigned mode, unsigned start, unsigned count) + { + $self->pipe->draw_range_elements($self->pipe, + indexBuffer->buffer, + indexSize, minIndex, maxIndex, + mode, start, count); + } + void draw_vertices(unsigned prim, unsigned num_verts, unsigned num_attribs, -- cgit v1.2.3 From 34cffce33413fe7701975d0d4bd54207bc44cacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 20 Aug 2008 14:03:12 +0100 Subject: python/retrace: Retrace draw_elements and draw_range_elements. --- src/gallium/state_trackers/python/retrace/interpreter.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index a7a7341e06..7502c096b6 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -403,6 +403,12 @@ class Context(Object): def draw_arrays(self, mode, start, count): self.real.draw_arrays(mode, start, count) + + def draw_elements(self, indexBuffer, indexSize, mode, start, count): + self.real.draw_elements(indexBuffer, indexSize, mode, start, count) + + def draw_range_elements(self, indexBuffer, indexSize, minIndex, maxIndex, mode, start, count): + self.real.draw_range_elements(indexBuffer, indexSize, minIndex, maxIndex, mode, start, count) def flush(self, flags): self.real.flush(flags) -- cgit v1.2.3 From f6abdb20437b1b8d27d8c45c0787017dfcad3497 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 20 Aug 2008 10:27:30 -0600 Subject: gallium: fix typo in LINE() macro (replace i+1 with i1 var) We were sometimes referencing an invalid vertex. Fixes progs/trivial/line-clip.c test among others. --- src/gallium/auxiliary/draw/draw_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 3355c871ee..1db43876ef 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -238,7 +238,7 @@ void draw_pipeline_run( struct draw_context *draw, do_line( draw, \ flags, \ verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (i+1)) + verts + stride * (i1)) #define POINT(i0) \ do_point( draw, \ -- cgit v1.2.3 From 0fae7648987d8264f85a9b6b6d7f903bff82a0f0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 20 Aug 2008 10:31:38 -0600 Subject: gallium: test for and cull prims with inf/nan vertices in sp_setup.c code. --- src/gallium/drivers/softpipe/sp_setup.c | 45 +++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 11 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index b7f2f16307..dd0562e7ef 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -104,6 +104,16 @@ struct setup_context { +/** + * Test if x is NaN or +/- infinity. + */ +static INLINE boolean +is_inf_or_nan(float x) +{ + union fi tmp; + tmp.f = x; + return !(int)((unsigned int)((tmp.i & 0x7fffffff)-0x7f800000) >> 31); +} static boolean cull_tri( struct setup_context *setup, @@ -293,6 +303,9 @@ static void print_vertex(const struct setup_context *setup, } #endif +/** + * \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise + */ static boolean setup_sort_vertices( struct setup_context *setup, float det, const float (*v0)[4], @@ -370,10 +383,13 @@ static boolean setup_sort_vertices( struct setup_context *setup, setup->ebot.dx * setup->emaj.dy); setup->oneoverarea = 1.0f / area; + /* debug_printf("%s one-over-area %f area %f det %f\n", __FUNCTION__, setup->oneoverarea, area, det ); */ + if (is_inf_or_nan(setup->oneoverarea)) + return FALSE; } /* We need to know if this is a front or back-facing triangle for: @@ -742,7 +758,8 @@ void setup_tri( struct setup_context *setup, if (cull_tri( setup, det )) return; - setup_sort_vertices( setup, det, v0, v1, v2 ); + if (!setup_sort_vertices( setup, det, v0, v1, v2 )) + return; setup_tri_coefficients( setup ); setup_tri_edges( setup ); @@ -827,7 +844,7 @@ line_persp_coeff(struct setup_context *setup, * Compute the setup->coef[] array dadx, dady, a0 values. * Must be called after setup->vmin,vmax are initialized. */ -static INLINE void +static INLINE boolean setup_line_coefficients(struct setup_context *setup, const float (*v0)[4], const float (*v1)[4]) @@ -836,6 +853,7 @@ setup_line_coefficients(struct setup_context *setup, const struct sp_fragment_shader *spfs = softpipe->fs; const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; + float area; /* use setup->vmin, vmax to point to vertices */ setup->vprovoke = v1; @@ -844,9 +862,12 @@ setup_line_coefficients(struct setup_context *setup, setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; - /* NOTE: this is not really 1/area */ - setup->oneoverarea = 1.0f / (setup->emaj.dx * setup->emaj.dx + - setup->emaj.dy * setup->emaj.dy); + + /* NOTE: this is not really area but something proportional to it */ + area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; + if (area == 0.0f || is_inf_or_nan(area)) + return FALSE; + setup->oneoverarea = 1.0f / area; /* z and w are done by linear interpolation: */ @@ -886,6 +907,7 @@ setup_line_coefficients(struct setup_context *setup, setup->coef[fragSlot].dady[1] = 0.0; } } + return TRUE; } @@ -942,18 +964,19 @@ setup_line(struct setup_context *setup, print_vertex(setup, v1); #endif - assert(v0[0][0] < 1.0e9); - assert(v0[0][1] < 1.0e9); - assert(v1[0][0] < 1.0e9); - assert(v1[0][1] < 1.0e9); - if (setup->softpipe->no_rast) return; if (dx == 0 && dy == 0) return; - setup_line_coefficients(setup, v0, v1); + if (!setup_line_coefficients(setup, v0, v1)) + return; + + assert(v0[0][0] < 1.0e9); + assert(v0[0][1] < 1.0e9); + assert(v1[0][0] < 1.0e9); + assert(v1[0][1] < 1.0e9); if (dx < 0) { dx = -dx; /* make positive */ -- cgit v1.2.3 From 0fff3e4ea991ce2f841739ee8c8e8937452e56fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 21 Aug 2008 13:39:52 +0100 Subject: trace: Split the output stream on windows. Because windows limits the ammount of memory that can be mapped. --- src/gallium/drivers/trace/tr_stream_wd.c | 102 +++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 27 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_stream_wd.c b/src/gallium/drivers/trace/tr_stream_wd.c index 9a05c0cec8..c375f50b95 100644 --- a/src/gallium/drivers/trace/tr_stream_wd.c +++ b/src/gallium/drivers/trace/tr_stream_wd.c @@ -47,32 +47,73 @@ struct trace_stream { + char filename[MAX_PATH + 1]; WCHAR wFileName[MAX_PATH + 1]; ULONG_PTR iFile; char *pMap; size_t written; + unsigned suffix; }; +static INLINE boolean +trace_stream_map(struct trace_stream *stream) +{ + ULONG BytesInUnicodeString; + static char filename[MAX_PATH + 1]; + unsigned filename_len; + + filename_len = util_snprintf(filename, + sizeof(filename), + "\\??\\%s.%03u", + stream->filename, + stream->suffix++); + + EngMultiByteToUnicodeN( + stream->wFileName, + sizeof(stream->wFileName), + &BytesInUnicodeString, + filename, + filename_len); + + stream->pMap = EngMapFile(stream->wFileName, MAP_FILE_SIZE, &stream->iFile); + if(!stream->pMap) + return FALSE; + + memset(stream->pMap, 0, MAP_FILE_SIZE); + stream->written = 0; + + return TRUE; +} + + +static INLINE void +trace_stream_unmap(struct trace_stream *stream) +{ + EngUnmapFile(stream->iFile); + if(stream->written < MAP_FILE_SIZE) { + /* Truncate file size */ + stream->pMap = EngMapFile(stream->wFileName, stream->written, &stream->iFile); + if(stream->pMap) + EngUnmapFile(stream->iFile); + } + + stream->pMap = NULL; +} + + struct trace_stream * trace_stream_create(const char *filename) { struct trace_stream *stream; - ULONG BytesInUnicodeString; stream = CALLOC_STRUCT(trace_stream); if(!stream) goto error1; - EngMultiByteToUnicodeN( - stream->wFileName, - sizeof(stream->wFileName), - &BytesInUnicodeString, - (char *)filename, - strlen(filename)); + strncpy(stream->filename, filename, sizeof(stream->filename)); - stream->pMap = EngMapFile(stream->wFileName, MAP_FILE_SIZE, &stream->iFile); - if(!stream->pMap) + if(!trace_stream_map(stream)) goto error2; return stream; @@ -84,25 +125,38 @@ error1: } +static INLINE void +trace_stream_copy(struct trace_stream *stream, const char *data, size_t size) +{ + assert(stream->written + size <= MAP_FILE_SIZE); + memcpy(stream->pMap + stream->written, data, size); + stream->written += size; +} + + boolean trace_stream_write(struct trace_stream *stream, const void *data, size_t size) { - boolean ret; - if(!stream) return FALSE; - if(stream->written + size > MAP_FILE_SIZE) { - ret = FALSE; - size = MAP_FILE_SIZE - stream->written; - } - else - ret = TRUE; + if(!stream->pMap) + return FALSE; - memcpy(stream->pMap + stream->written, data, size); - stream->written += size; + while(stream->written + size > MAP_FILE_SIZE) { + size_t step = MAP_FILE_SIZE - stream->written; + trace_stream_copy(stream, data, step); + data = (const char *)data + step; + size -= step; + + trace_stream_unmap(stream); + if(!trace_stream_map(stream)) + return FALSE; + } + + trace_stream_copy(stream, data, size); - return ret; + return TRUE; } @@ -119,13 +173,7 @@ trace_stream_close(struct trace_stream *stream) if(!stream) return; - EngUnmapFile(stream->iFile); - if(stream->written < MAP_FILE_SIZE) { - /* Truncate file size */ - stream->pMap = EngMapFile(stream->wFileName, stream->written, &stream->iFile); - if(stream->pMap) - EngUnmapFile(stream->iFile); - } + trace_stream_unmap(stream); FREE(stream); } -- cgit v1.2.3 From 34d12c1787116c254e528dd981810b7b78b7a2ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 21 Aug 2008 13:57:59 +0100 Subject: trace: Hack to detect writes to user buffers. It often happens that new data is written directly to the user buffers without mapping/unmapping. This hack marks user buffers and dumps them before passing them to pipe context. --- src/gallium/drivers/trace/tr_context.c | 11 ++++++++++ src/gallium/drivers/trace/tr_winsys.c | 40 ++++++++++++++++++++++++++++++++++ src/gallium/drivers/trace/tr_winsys.h | 13 +++++++++++ 3 files changed, 64 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 529bed3c6b..f16359e8ad 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -32,6 +32,7 @@ #include "tr_state.h" #include "tr_screen.h" #include "tr_texture.h" +#include "tr_winsys.h" #include "tr_context.h" @@ -131,6 +132,8 @@ trace_context_draw_elements(struct pipe_context *_pipe, struct pipe_context *pipe = tr_ctx->pipe; boolean result; + trace_winsys_user_buffer_update(_pipe->winsys, indexBuffer); + trace_dump_call_begin("pipe_context", "draw_elements"); trace_dump_arg(ptr, pipe); @@ -164,6 +167,8 @@ trace_context_draw_range_elements(struct pipe_context *_pipe, struct pipe_context *pipe = tr_ctx->pipe; boolean result; + trace_winsys_user_buffer_update(_pipe->winsys, indexBuffer); + trace_dump_call_begin("pipe_context", "draw_range_elements"); trace_dump_arg(ptr, pipe); @@ -691,6 +696,8 @@ trace_context_set_constant_buffer(struct pipe_context *_pipe, struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; + trace_winsys_user_buffer_update(_pipe->winsys, (struct pipe_buffer *)buffer); + trace_dump_call_begin("pipe_context", "set_constant_buffer"); trace_dump_arg(ptr, pipe); @@ -820,6 +827,10 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe, { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; + unsigned i; + + for(i = 0; i < num_buffers; ++i) + trace_winsys_user_buffer_update(_pipe->winsys, buffers[i].buffer); trace_dump_call_begin("pipe_context", "set_vertex_buffers"); diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index 120006ea9f..2c7a6f893b 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -242,10 +242,50 @@ trace_winsys_user_buffer_create(struct pipe_winsys *_winsys, trace_dump_call_end(); + /* XXX: Mark the user buffers. (we should wrap pipe_buffers, but is is + * impossible to do so while texture-less surfaces are still around */ + if(result) { + assert(!(result->usage & TRACE_BUFFER_USAGE_USER)); + result->usage |= TRACE_BUFFER_USAGE_USER; + } + return result; } +void +trace_winsys_user_buffer_update(struct pipe_winsys *_winsys, + struct pipe_buffer *buffer) +{ + struct trace_winsys *tr_ws = trace_winsys(_winsys); + struct pipe_winsys *winsys = tr_ws->winsys; + const void *map; + + if(buffer && buffer->usage & TRACE_BUFFER_USAGE_USER) { + map = winsys->buffer_map(winsys, buffer, PIPE_BUFFER_USAGE_CPU_READ); + if(map) { + trace_dump_call_begin("pipe_winsys", "buffer_write"); + + trace_dump_arg(ptr, winsys); + + trace_dump_arg(ptr, buffer); + + trace_dump_arg_begin("data"); + trace_dump_bytes(map, buffer->size); + trace_dump_arg_end(); + + trace_dump_arg_begin("size"); + trace_dump_uint(buffer->size); + trace_dump_arg_end(); + + trace_dump_call_end(); + + winsys->buffer_unmap(winsys, buffer); + } + } +} + + static void * trace_winsys_buffer_map(struct pipe_winsys *_winsys, struct pipe_buffer *buffer, diff --git a/src/gallium/drivers/trace/tr_winsys.h b/src/gallium/drivers/trace/tr_winsys.h index 2218117347..062ddf66a0 100644 --- a/src/gallium/drivers/trace/tr_winsys.h +++ b/src/gallium/drivers/trace/tr_winsys.h @@ -34,6 +34,14 @@ #include "pipe/p_winsys.h" +/** + * It often happens that new data is written directly to the user buffers + * without mapping/unmapping. This flag marks user buffers, so that their + * contents can be dumpped before being used by the pipe context. + */ +#define TRACE_BUFFER_USAGE_USER (1 << 31) + + struct hash_table; @@ -60,4 +68,9 @@ struct pipe_winsys * trace_winsys_create(struct pipe_winsys *winsys); +void +trace_winsys_user_buffer_update(struct pipe_winsys *winsys, + struct pipe_buffer *buffer); + + #endif /* TR_WINSYS_H_ */ -- cgit v1.2.3 From 10624065b0dc631164d786b2c39f35655e55eadf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 21 Aug 2008 18:45:43 +0100 Subject: python/retrace: Support gziped traces. --- src/gallium/state_trackers/python/retrace/interpreter.py | 7 ++++++- src/gallium/state_trackers/python/retrace/parser.py | 10 ++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index 7502c096b6..f596a54d10 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -471,7 +471,12 @@ class Interpreter: def main(): for arg in sys.argv[1:]: - parser = TraceParser(open(arg, 'rt')) + if arg.endswith('.gz'): + import gzip + stream = gzip.GzipFile(arg, 'rt') + else: + stream = open(arg, 'rt') + parser = TraceParser(stream) trace = parser.parse() interpreter = Interpreter() interpreter.interpret(trace) diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/src/gallium/state_trackers/python/retrace/parser.py index d02fd7f741..2ee4d3068d 100755 --- a/src/gallium/state_trackers/python/retrace/parser.py +++ b/src/gallium/state_trackers/python/retrace/parser.py @@ -322,9 +322,15 @@ class TraceParser(XmlParser): def main(): for arg in sys.argv[1:]: - parser = TraceParser(open(arg, 'rt')) + if arg.endswith('.gz'): + import gzip + stream = gzip.GzipFile(arg, 'rt') + else: + stream = open(arg, 'rt') + parser = TraceParser(stream) trace = parser.parse() - print trace + for call in trace.calls: + print call if __name__ == '__main__': -- cgit v1.2.3 From 7f3c3683ce50bad42411547d4b78e03d7f20e498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 22 Aug 2008 01:23:48 +0100 Subject: python/retrace: Process the trace call-by-call (instead of reading everything into memory). --- .../state_trackers/python/retrace/interpreter.py | 24 +++++--------------- .../state_trackers/python/retrace/parser.py | 26 ++++++++++++++-------- 2 files changed, 23 insertions(+), 27 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index f596a54d10..a2f924f528 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -22,7 +22,7 @@ import sys import gallium import model -from parser import TraceParser +import parser def make_image(surface): @@ -426,9 +426,10 @@ class Context(Object): show_image(self.cbufs[0]) -class Interpreter: +class Interpreter(parser.TraceParser): - def __init__(self): + def __init__(self, stream): + parser.TraceParser.__init__(self, stream) self.objects = {} self.result = None self.globl = Global(self, None) @@ -447,7 +448,7 @@ class Interpreter: for call in trace.calls: self.interpret_call(call) - def interpret_call(self, call): + def handle_call(self, call): sys.stderr.write("%s\n" % call) args = [self.interpret_arg(arg) for name, arg in call.args] @@ -469,18 +470,5 @@ class Interpreter: return translator.visit(node) -def main(): - for arg in sys.argv[1:]: - if arg.endswith('.gz'): - import gzip - stream = gzip.GzipFile(arg, 'rt') - else: - stream = open(arg, 'rt') - parser = TraceParser(stream) - trace = parser.parse() - interpreter = Interpreter() - interpreter.interpret(trace) - - if __name__ == '__main__': - main() + parser.main(Interpreter) diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/src/gallium/state_trackers/python/retrace/parser.py index 2ee4d3068d..6bc75ad685 100755 --- a/src/gallium/state_trackers/python/retrace/parser.py +++ b/src/gallium/state_trackers/python/retrace/parser.py @@ -183,12 +183,11 @@ class TraceParser(XmlParser): def parse(self): self.element_start('trace') - calls = [] while self.token.type not in (ELEMENT_END, EOF): - calls.append(self.parse_call()) + call = self.parse_call() + self.handle_call(call) if self.token.type != EOF: self.element_end('trace') - return Trace(calls) def parse_call(self): attrs = self.element_start('call') @@ -319,19 +318,28 @@ class TraceParser(XmlParser): return Pointer(address) + def handle_call(self, call): + + pass + + +class TraceDumper(TraceParser): + + + def handle_call(self, call): + print call + -def main(): +def main(ParserFactory): for arg in sys.argv[1:]: if arg.endswith('.gz'): import gzip stream = gzip.GzipFile(arg, 'rt') else: stream = open(arg, 'rt') - parser = TraceParser(stream) - trace = parser.parse() - for call in trace.calls: - print call + parser = ParserFactory(stream) + parser.parse() if __name__ == '__main__': - main() + main(TraceDumper) -- cgit v1.2.3 From 152d00d199f2c8c46a96be450cfd017b4798b4d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 22 Aug 2008 03:13:27 +0100 Subject: trace: Use a 4 hexadecimal digit suffix. --- src/gallium/drivers/trace/tr_stream_wd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_stream_wd.c b/src/gallium/drivers/trace/tr_stream_wd.c index c375f50b95..45309dcb4e 100644 --- a/src/gallium/drivers/trace/tr_stream_wd.c +++ b/src/gallium/drivers/trace/tr_stream_wd.c @@ -65,7 +65,7 @@ trace_stream_map(struct trace_stream *stream) filename_len = util_snprintf(filename, sizeof(filename), - "\\??\\%s.%03u", + "\\??\\%s.%04x", stream->filename, stream->suffix++); -- cgit v1.2.3 From 807a7487ff6f0af60240ce467bd1ac160b0b054e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 22 Aug 2008 03:14:24 +0100 Subject: trace: Don't trace texture/surfaces releases, only destructions. --- src/gallium/drivers/trace/tr_screen.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index cca8597a87..a6467ec35f 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -224,19 +224,20 @@ trace_screen_texture_release(struct pipe_screen *_screen, else texture = NULL; - trace_dump_call_begin("pipe_screen", "texture_release"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, texture); - if (*ptexture) { - if (!--(*ptexture)->refcount) + if (!--(*ptexture)->refcount) { + trace_dump_call_begin("pipe_screen", "texture_destroy"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, texture); + trace_texture_destroy(tr_scr, *ptexture); + + trace_dump_call_end(); + } *ptexture = NULL; } - - trace_dump_call_end(); } @@ -297,19 +298,20 @@ trace_screen_tex_surface_release(struct pipe_screen *_screen, else surface = NULL; - trace_dump_call_begin("pipe_screen", "tex_surface_release"); - - trace_dump_arg(ptr, screen); - trace_dump_arg(ptr, surface); - if (*psurface) { - if (!--(*psurface)->refcount) + if (!--(*psurface)->refcount) { + trace_dump_call_begin("pipe_screen", "tex_surface_destroy"); + + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, surface); + trace_surface_destroy(tr_tex, *psurface); + + trace_dump_call_end(); + } *psurface = NULL; } - - trace_dump_call_end(); } -- cgit v1.2.3 From d32f51d4717686d626b0f7ec9a92c3c9af50009f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 22 Aug 2008 03:14:51 +0100 Subject: python/retrace: Interpret texture/surfaces destructions. --- src/gallium/state_trackers/python/retrace/interpreter.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index a2f924f528..351a6e739b 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -254,15 +254,21 @@ class Screen(Object): tex_usage = template.tex_usage, ) - def texture_release(self, texture): + def texture_destroy(self, texture): self.interpreter.unregister_object(texture) + def texture_release(self, surface): + pass + def get_tex_surface(self, texture, face, level, zslice, usage): return texture.get_surface(face, level, zslice, usage) - def tex_surface_release(self, surface): + def tex_surface_destroy(self, surface): self.interpreter.unregister_object(surface) + def tex_surface_release(self, surface): + pass + def surface_write(self, surface, data, stride, size): assert surface.nblocksy * stride == size surface.put_tile_raw(0, 0, surface.width, surface.height, data, stride) -- cgit v1.2.3 From 9e2b867b3f2e9afc9e9f9178788ae07f6be1f3c0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 Aug 2008 15:13:47 -0600 Subject: gallium: new u_math.[ch] files for math functions So far, optimized/low-precision versions of exp(), exp2(), log2(), pow(). --- src/gallium/auxiliary/util/Makefile | 1 + src/gallium/auxiliary/util/SConscript | 1 + src/gallium/auxiliary/util/u_math.c | 60 ++++++++++++++ src/gallium/auxiliary/util/u_math.h | 144 ++++++++++++++++++++++++++++++++++ 4 files changed, 206 insertions(+) create mode 100644 src/gallium/auxiliary/util/u_math.c create mode 100644 src/gallium/auxiliary/util/u_math.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index db3d810a2e..be1b97b535 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -12,6 +12,7 @@ C_SOURCES = \ u_gen_mipmap.c \ u_handle_table.c \ u_hash_table.c \ + u_math.c \ u_mm.c \ u_simple_shaders.c \ u_snprintf.c \ diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 0309de1ac2..7865307a7a 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -13,6 +13,7 @@ util = env.ConvenienceLibrary( 'u_gen_mipmap.c', 'u_handle_table.c', 'u_hash_table.c', + 'u_math.c', 'u_mm.c', 'u_simple_shaders.c', 'u_snprintf.c', diff --git a/src/gallium/auxiliary/util/u_math.c b/src/gallium/auxiliary/util/u_math.c new file mode 100644 index 0000000000..8bf6551b6e --- /dev/null +++ b/src/gallium/auxiliary/util/u_math.c @@ -0,0 +1,60 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + + +#include "util/u_math.h" + + + +float pow2_table[POW2_TABLE_SIZE]; + + +static void +init_pow2_table(void) +{ + int i; + for (i = 0; i < POW2_TABLE_SIZE; i++) { + pow2_table[i] = pow(2.0, i / POW2_TABLE_SCALE); + } +} + + +/** + * One time init for math utilities. + */ +void +util_init_math(void) +{ + static boolean initialized = FALSE; + if (!initialized) { + init_pow2_table(); + initialized = TRUE; + } +} + + diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h new file mode 100644 index 0000000000..e179ce700f --- /dev/null +++ b/src/gallium/auxiliary/util/u_math.h @@ -0,0 +1,144 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Math utilities and approximations for common math functions. + * Reduced precision is usually acceptable in shaders... + */ + + +#ifndef U_MATH_H +#define U_MATH_H + + +#include "pipe/p_util.h" +#include "util/u_math.h" + + + +#define POW2_TABLE_SIZE 256 +#define POW2_TABLE_SCALE ((float) (POW2_TABLE_SIZE-1)) +extern float pow2_table[POW2_TABLE_SIZE]; + + +extern void +util_init_math(void); + + + + +/** + * Fast approximation to exp(x). + * Compute with base 2 exponents: exp(x) = exp2(log2(e) * x) + * Note: log2(e) is a constant, k = 1.44269 + * So, exp(x) = exp2(k * x); + * Identity: exp2(a + b) = exp2(a) * exp2(b) + * Let ipart = int(k*x) + * Let fpart = k*x - ipart; + * So, exp2(k*x) = exp2(ipart) * exp2(fpart) + * Compute exp2(ipart) with i << ipart + * Compute exp2(fpart) with lookup table. + */ +static INLINE float +util_fast_exp(float x) +{ + if (x >= 0.0f) { + float k = 1.44269f; /* = log2(e) */ + float kx = k * x; + int ipart = (int) kx; + float fpart = kx - (float) ipart; + float y = (float) (1 << ipart) + * pow2_table[(int) (fpart * POW2_TABLE_SCALE)]; + return y; + } + else { + /* exp(-x) = 1.0 / exp(x) */ + float k = -1.44269f; + float kx = k * x; + int ipart = (int) kx; + float fpart = kx - (float) ipart; + float y = (float) (1 << ipart) + * pow2_table[(int) (fpart * POW2_TABLE_SCALE)]; + return 1.0f / y; + } +} + + +/** + * Fast version of 2^x + * XXX the above function could be implemented in terms of this one. + */ +static INLINE float +util_fast_exp2(float x) +{ + if (x >= 0.0f) { + int ipart = (int) x; + float fpart = x - (float) ipart; + float y = (float) (1 << ipart) + * pow2_table[(int) (fpart * POW2_TABLE_SCALE)]; + return y; + } + else { + /* exp(-x) = 1.0 / exp(x) */ + int ipart = (int) -x; + float fpart = -x - (float) ipart; + float y = (float) (1 << ipart) + * pow2_table[(int) (fpart * POW2_TABLE_SCALE)]; + return 1.0f / y; + } +} + + +/** + * Based on code from http://www.flipcode.com/totd/ + */ +static INLINE float +util_fast_log2(float val) +{ + union fi num; + int log_2; + num.f = val; + log_2 = ((num.i >> 23) & 255) - 128; + num.i &= ~(255 << 23); + num.i += 127 << 23; + num.f = ((-1.0f/3) * num.f + 2) * num.f - 2.0f/3; + return num.f + log_2; +} + + +static INLINE float +util_fast_pow(float x, float y) +{ + /* XXX this test may need adjustment */ + if (y >= 3.0 && -0.02f <= x && x <= 0.02f) + return 0.0f; + return util_fast_exp2(util_fast_log2(x) * y); +} + + +#endif /* U_MATH_H */ -- cgit v1.2.3 From 1c2ff4d9e65563c071747a9c3bd907bd24706da0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 Aug 2008 15:16:43 -0600 Subject: gallium: use new util_fast_exp2(), _log2(), pow() functions New code surrounded with #if FAST_MATH to allow comparing against original code if we need to debug. --- src/gallium/auxiliary/draw/draw_vs_aos.c | 66 +++++++++++++++++++++++++++++++- src/gallium/auxiliary/tgsi/tgsi_exec.c | 30 +++++++++++++++ src/gallium/auxiliary/tgsi/tgsi_sse2.c | 19 +++++++++ 3 files changed, 113 insertions(+), 2 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 441877d46f..41bdd012d5 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -31,6 +31,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" +#include "util/u_math.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" #include "tgsi/tgsi_exec.h" @@ -43,6 +44,7 @@ #ifdef PIPE_ARCH_X86 #define DISASSEM 0 +#define FAST_MATH 1 static const char *files[] = { @@ -1380,14 +1382,28 @@ static boolean emit_MAD( struct aos_compilation *cp, const struct tgsi_full_inst return TRUE; } + + /* A wrapper for powf(). * Makes sure it is cdecl and operates on floats. */ static float PIPE_CDECL _powerf( float x, float y ) { +#if FAST_MATH + return util_fast_pow(x, y); +#else return powf( x, y ); +#endif } +#if FAST_MATH +static float PIPE_CDECL _exp2(float x) +{ + return util_fast_exp2(x); +} +#endif + + /* Really not sufficient -- need to check for conditions that could * generate inf/nan values, which will slow things down hugely. */ @@ -1442,6 +1458,48 @@ static boolean emit_POW( struct aos_compilation *cp, const struct tgsi_full_inst } +#if FAST_MATH +static boolean emit_EXPBASE2( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) +{ + uint i; + + /* For absolute correctness, need to spill/invalidate all XMM regs + * too. + */ + for (i = 0; i < 8; i++) { + if (cp->xmm[i].dirty) + spill(cp, i); + aos_release_xmm_reg(cp, i); + } + + /* Push caller-save (ie scratch) regs. + */ + x86_cdecl_caller_push_regs( cp->func ); + + x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, -4) ); + + x87_fld_src( cp, &op->FullSrcRegisters[0], 0 ); + x87_fstp( cp->func, x86_make_disp( cp->stack_ESP, 0 ) ); + + /* tmp_EAX has been pushed & will be restored below */ + x86_mov_reg_imm( cp->func, cp->tmp_EAX, (unsigned long) _exp2 ); + x86_call( cp->func, cp->tmp_EAX ); + + x86_lea( cp->func, cp->stack_ESP, x86_make_disp(cp->stack_ESP, 4) ); + + x86_cdecl_caller_pop_regs( cp->func ); + + /* Note retval on x87 stack: + */ + cp->func->x87_stack++; + + x87_fstp_dest4( cp, &op->FullDstRegisters[0] ); + + return TRUE; +} +#endif + + static boolean emit_RCP( struct aos_compilation *cp, const struct tgsi_full_instruction *op ) { struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]); @@ -1662,7 +1720,9 @@ emit_instruction( struct aos_compilation *cp, return emit_RND(cp, inst); case TGSI_OPCODE_EXPBASE2: -#if 0 +#if FAST_MATH + return emit_EXPBASE2(cp, inst); +#elif 0 /* this seems to fail for "larger" exponents. * See glean tvertProg1's EX2 test. */ @@ -1827,6 +1887,8 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, struct aos_compilation cp; unsigned fixup, label; + util_init_math(); + tgsi_parse_init( &parse, varient->base.vs->state.tokens ); memset(&cp, 0, sizeof(cp)); @@ -2135,4 +2197,4 @@ struct draw_vs_varient *draw_vs_varient_aos_sse( struct draw_vertex_shader *vs, -#endif +#endif /* PIPE_ARCH_X86 */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 88a34a6961..e28b56c842 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -57,6 +57,9 @@ #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" #include "tgsi_exec.h" +#include "util/u_math.h" + +#define FAST_MATH 1 #define TILE_TOP_LEFT 0 #define TILE_TOP_RIGHT 1 @@ -145,6 +148,8 @@ tgsi_exec_machine_bind_shader( tgsi_dump(tokens, 0); #endif + util_init_math(); + mach->Tokens = tokens; mach->Samplers = samplers; @@ -448,10 +453,17 @@ micro_exp2( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src) { +#if FAST_MATH + dst->f[0] = util_fast_exp2( src->f[0] ); + dst->f[1] = util_fast_exp2( src->f[1] ); + dst->f[2] = util_fast_exp2( src->f[2] ); + dst->f[3] = util_fast_exp2( src->f[3] ); +#else dst->f[0] = powf( 2.0f, src->f[0] ); dst->f[1] = powf( 2.0f, src->f[1] ); dst->f[2] = powf( 2.0f, src->f[2] ); dst->f[3] = powf( 2.0f, src->f[3] ); +#endif } static void @@ -528,10 +540,17 @@ micro_lg2( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { +#if FAST_MATH + dst->f[0] = util_fast_log2( src->f[0] ); + dst->f[1] = util_fast_log2( src->f[1] ); + dst->f[2] = util_fast_log2( src->f[2] ); + dst->f[3] = util_fast_log2( src->f[3] ); +#else dst->f[0] = logf( src->f[0] ) * 1.442695f; dst->f[1] = logf( src->f[1] ) * 1.442695f; dst->f[2] = logf( src->f[2] ) * 1.442695f; dst->f[3] = logf( src->f[3] ) * 1.442695f; +#endif } static void @@ -796,10 +815,17 @@ micro_pow( const union tgsi_exec_channel *src0, const union tgsi_exec_channel *src1 ) { +#if FAST_MATH + dst->f[0] = util_fast_pow( src0->f[0], src1->f[0] ); + dst->f[1] = util_fast_pow( src0->f[1], src1->f[1] ); + dst->f[2] = util_fast_pow( src0->f[2], src1->f[2] ); + dst->f[3] = util_fast_pow( src0->f[3], src1->f[3] ); +#else dst->f[0] = powf( src0->f[0], src1->f[0] ); dst->f[1] = powf( src0->f[1], src1->f[1] ); dst->f[2] = powf( src0->f[2], src1->f[2] ); dst->f[3] = powf( src0->f[3], src1->f[3] ); +#endif } static void @@ -2024,7 +2050,11 @@ exec_instruction( /* TGSI_OPCODE_EX2 */ FETCH(&r[0], 0, CHAN_X); +#if FAST_MATH + micro_exp2( &r[0], &r[0] ); +#else micro_pow( &r[0], &mach->Temps[TEMP_2_I].xyzw[TEMP_2_C], &r[0] ); +#endif FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { STORE( &r[0], 0, chan_index ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 485e5a0e6f..e390607023 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -27,6 +27,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" +#include "util/u_math.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" #include "tgsi_exec.h" @@ -42,6 +43,8 @@ */ #define HIGH_PRECISION 1 +#define FAST_MATH 1 + #define FOR_EACH_CHANNEL( CHAN )\ for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++) @@ -623,10 +626,17 @@ ex24f( { const unsigned X = 0; +#if FAST_MATH + store[X + 0] = util_fast_exp2( store[X + 0] ); + store[X + 1] = util_fast_exp2( store[X + 1] ); + store[X + 2] = util_fast_exp2( store[X + 2] ); + store[X + 3] = util_fast_exp2( store[X + 3] ); +#else store[X + 0] = powf( 2.0f, store[X + 0] ); store[X + 1] = powf( 2.0f, store[X + 1] ); store[X + 2] = powf( 2.0f, store[X + 2] ); store[X + 3] = powf( 2.0f, store[X + 3] ); +#endif } static void @@ -762,10 +772,17 @@ pow4f( { const unsigned X = 0; +#if FAST_MATH + store[X + 0] = util_fast_pow( store[X + 0], store[X + 4] ); + store[X + 1] = util_fast_pow( store[X + 1], store[X + 5] ); + store[X + 2] = util_fast_pow( store[X + 2], store[X + 6] ); + store[X + 3] = util_fast_pow( store[X + 3], store[X + 7] ); +#else store[X + 0] = powf( store[X + 0], store[X + 4] ); store[X + 1] = powf( store[X + 1], store[X + 5] ); store[X + 2] = powf( store[X + 2], store[X + 6] ); store[X + 3] = powf( store[X + 3], store[X + 7] ); +#endif } static void @@ -2235,6 +2252,8 @@ tgsi_emit_sse2( unsigned ok = 1; uint num_immediates = 0; + util_init_math(); + func->csr = func->store; tgsi_parse_init( &parse, tokens ); -- cgit v1.2.3 From 1a46dcc8a927dfb38ca1381e7b3dafb789f8257c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 Aug 2008 15:25:21 -0600 Subject: gallium: replace LOG2() macro with util_fast_log2() inline func --- src/gallium/auxiliary/tgsi/tgsi_sse2.c | 8 ++++---- src/gallium/drivers/softpipe/sp_context.c | 3 +++ src/gallium/drivers/softpipe/sp_tex_sample.c | 3 ++- src/gallium/include/pipe/p_util.h | 15 --------------- 4 files changed, 9 insertions(+), 20 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index e390607023..00ed4da450 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -713,10 +713,10 @@ lg24f( { const unsigned X = 0; - store[X + 0] = LOG2( store[X + 0] ); - store[X + 1] = LOG2( store[X + 1] ); - store[X + 2] = LOG2( store[X + 2] ); - store[X + 3] = LOG2( store[X + 3] ); + store[X + 0] = util_fast_log2( store[X + 0] ); + store[X + 1] = util_fast_log2( store[X + 1] ); + store[X + 2] = util_fast_log2( store[X + 2] ); + store[X + 3] = util_fast_log2( store[X + 3] ); } static void diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 626c3a9d4e..9b1313bc83 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -33,6 +33,7 @@ #include "pipe/p_defines.h" #include "pipe/p_inlines.h" #include "pipe/p_util.h" +#include "util/u_math.h" #include "sp_clear.h" #include "sp_context.h" #include "sp_flush.h" @@ -128,6 +129,8 @@ softpipe_create( struct pipe_screen *screen, struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); uint i; + util_init_math(); + #ifdef PIPE_ARCH_X86 softpipe->use_sse = !debug_get_bool_option( "GALLIUM_NOSSE", FALSE ); #else diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 01f4d0ca81..d7680ffa81 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -41,6 +41,7 @@ #include "pipe/p_defines.h" #include "pipe/p_util.h" #include "tgsi/tgsi_exec.h" +#include "util/u_math.h" /* @@ -499,7 +500,7 @@ compute_lambda(struct tgsi_sampler *sampler, rho = MAX2(rho, max); } - lambda = LOG2(rho); + lambda = util_fast_log2(rho); lambda += lodbias + sampler->state->lod_bias; lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod); diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 473a8d94ab..660192b28e 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -443,21 +443,6 @@ static INLINE int iround(float f) #define FABSF(x) ((float) fabs(x)) #endif -/* Pretty fast, and accurate. - * Based on code from http://www.flipcode.com/totd/ - */ -static INLINE float LOG2(float val) -{ - union fi num; - int log_2; - - num.f = val; - log_2 = ((num.i >> 23) & 255) - 128; - num.i &= ~(255 << 23); - num.i += 127 << 23; - num.f = ((-1.0f/3) * num.f + 2) * num.f - 2.0f/3; - return num.f + log_2; -} #if defined(__GNUC__) #define CEILF(x) ceilf(x) -- cgit v1.2.3 From 120270def74149b240926f827b80ca073536d462 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 Aug 2008 15:49:36 -0600 Subject: gallium: stop using FABSF() macro --- src/gallium/auxiliary/draw/draw_pipe_offset.c | 4 ++-- src/gallium/auxiliary/draw/draw_pipe_wide_line.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index 8f1650e55c..2f5865741c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -84,8 +84,8 @@ static void do_offset_tri( struct draw_stage *stage, float a = ey*fz - ez*fy; float b = ez*fx - ex*fz; - float dzdx = FABSF(a * inv_det); - float dzdy = FABSF(b * inv_det); + float dzdx = fabsf(a * inv_det); + float dzdy = fabsf(b * inv_det); float zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale; diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c index 29649f5787..48ec2f1239 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -73,8 +73,8 @@ static void wideline_line( struct draw_stage *stage, float *pos2 = v2->data[pos]; float *pos3 = v3->data[pos]; - const float dx = FABSF(pos0[0] - pos2[0]); - const float dy = FABSF(pos0[1] - pos2[1]); + const float dx = fabsf(pos0[0] - pos2[0]); + const float dy = fabsf(pos0[1] - pos2[1]); /* small tweak to meet GL specification */ const float bias = 0.125f; -- cgit v1.2.3 From 9935e3b7303da656e258d4bd5bc799ffbfbc737b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 Aug 2008 15:51:02 -0600 Subject: gallium: stop using ifloor(), FABSF(), etc --- src/gallium/drivers/softpipe/sp_setup.c | 14 +++--- src/gallium/drivers/softpipe/sp_tex_sample.c | 72 ++++++++++++++-------------- 2 files changed, 44 insertions(+), 42 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index dd0562e7ef..c8c55fa6e8 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -44,6 +44,8 @@ #include "draw/draw_vertex.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" +#include "util/u_math.h" + #define DEBUG_VERTS 0 #define DEBUG_FRAGS 0 @@ -611,18 +613,18 @@ static void setup_tri_edges( struct setup_context *setup ) float vmid_y = setup->vmid[0][1] - 0.5f; float vmax_y = setup->vmax[0][1] - 0.5f; - setup->emaj.sy = CEILF(vmin_y); - setup->emaj.lines = (int) CEILF(vmax_y - setup->emaj.sy); + setup->emaj.sy = ceilf(vmin_y); + setup->emaj.lines = (int) ceilf(vmax_y - setup->emaj.sy); setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy; setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; - setup->etop.sy = CEILF(vmid_y); - setup->etop.lines = (int) CEILF(vmax_y - setup->etop.sy); + setup->etop.sy = ceilf(vmid_y); + setup->etop.lines = (int) ceilf(vmax_y - setup->etop.sy); setup->etop.dxdy = setup->etop.dx / setup->etop.dy; setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; - setup->ebot.sy = CEILF(vmin_y); - setup->ebot.lines = (int) CEILF(vmid_y - setup->ebot.sy); + setup->ebot.sy = ceilf(vmin_y); + setup->ebot.lines = (int) ceilf(vmid_y - setup->ebot.sy); setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy; setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; } diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index d7680ffa81..58a95d13e1 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -51,7 +51,7 @@ * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). */ -#define FRAC(f) ((f) - ifloor(f)) +#define FRAC(f) ((f) - util_ifloor(f)) /** @@ -100,7 +100,7 @@ nearest_texcoord(unsigned wrapMode, float s, unsigned size) case PIPE_TEX_WRAP_REPEAT: /* s limited to [0,1) */ /* i limited to [0,size-1] */ - i = ifloor(s * size); + i = util_ifloor(s * size); i = REMAINDER(i, size); return i; case PIPE_TEX_WRAP_CLAMP: @@ -111,7 +111,7 @@ nearest_texcoord(unsigned wrapMode, float s, unsigned size) else if (s >= 1.0F) i = size - 1; else - i = ifloor(s * size); + i = util_ifloor(s * size); return i; case PIPE_TEX_WRAP_CLAMP_TO_EDGE: { @@ -124,7 +124,7 @@ nearest_texcoord(unsigned wrapMode, float s, unsigned size) else if (s > max) i = size - 1; else - i = ifloor(s * size); + i = util_ifloor(s * size); } return i; case PIPE_TEX_WRAP_CLAMP_TO_BORDER: @@ -138,14 +138,14 @@ nearest_texcoord(unsigned wrapMode, float s, unsigned size) else if (s >= max) i = size; else - i = ifloor(s * size); + i = util_ifloor(s * size); } return i; case PIPE_TEX_WRAP_MIRROR_REPEAT: { const float min = 1.0F / (2.0F * size); const float max = 1.0F - min; - const int flr = ifloor(s); + const int flr = util_ifloor(s); float u; if (flr & 1) u = 1.0F - (s - (float) flr); @@ -156,20 +156,20 @@ nearest_texcoord(unsigned wrapMode, float s, unsigned size) else if (u > max) i = size - 1; else - i = ifloor(u * size); + i = util_ifloor(u * size); } return i; case PIPE_TEX_WRAP_MIRROR_CLAMP: { /* s limited to [0,1] */ /* i limited to [0,size-1] */ - const float u = FABSF(s); + const float u = fabsf(s); if (u <= 0.0F) i = 0; else if (u >= 1.0F) i = size - 1; else - i = ifloor(u * size); + i = util_ifloor(u * size); } return i; case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: @@ -178,13 +178,13 @@ nearest_texcoord(unsigned wrapMode, float s, unsigned size) /* i limited to [0, size-1] */ const float min = 1.0F / (2.0F * size); const float max = 1.0F - min; - const float u = FABSF(s); + const float u = fabsf(s); if (u < min) i = 0; else if (u > max) i = size - 1; else - i = ifloor(u * size); + i = util_ifloor(u * size); } return i; case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: @@ -193,13 +193,13 @@ nearest_texcoord(unsigned wrapMode, float s, unsigned size) /* i limited to [0, size-1] */ const float min = -1.0F / (2.0F * size); const float max = 1.0F - min; - const float u = FABSF(s); + const float u = fabsf(s); if (u < min) i = -1; else if (u > max) i = size; else - i = ifloor(u * size); + i = util_ifloor(u * size); } return i; default: @@ -226,7 +226,7 @@ linear_texcoord(unsigned wrapMode, float s, unsigned size, switch (wrapMode) { case PIPE_TEX_WRAP_REPEAT: u = s * size - 0.5F; - *i0 = REMAINDER(ifloor(u), size); + *i0 = REMAINDER(util_ifloor(u), size); *i1 = REMAINDER(*i0 + 1, size); break; case PIPE_TEX_WRAP_CLAMP: @@ -237,7 +237,7 @@ linear_texcoord(unsigned wrapMode, float s, unsigned size, else u = s * size; u -= 0.5F; - *i0 = ifloor(u); + *i0 = util_ifloor(u); *i1 = *i0 + 1; break; case PIPE_TEX_WRAP_CLAMP_TO_EDGE: @@ -248,7 +248,7 @@ linear_texcoord(unsigned wrapMode, float s, unsigned size, else u = s * size; u -= 0.5F; - *i0 = ifloor(u); + *i0 = util_ifloor(u); *i1 = *i0 + 1; if (*i0 < 0) *i0 = 0; @@ -266,19 +266,19 @@ linear_texcoord(unsigned wrapMode, float s, unsigned size, else u = s * size; u -= 0.5F; - *i0 = ifloor(u); + *i0 = util_ifloor(u); *i1 = *i0 + 1; } break; case PIPE_TEX_WRAP_MIRROR_REPEAT: { - const int flr = ifloor(s); + const int flr = util_ifloor(s); if (flr & 1) u = 1.0F - (s - (float) flr); else u = s - (float) flr; u = (u * size) - 0.5F; - *i0 = ifloor(u); + *i0 = util_ifloor(u); *i1 = *i0 + 1; if (*i0 < 0) *i0 = 0; @@ -287,23 +287,23 @@ linear_texcoord(unsigned wrapMode, float s, unsigned size, } break; case PIPE_TEX_WRAP_MIRROR_CLAMP: - u = FABSF(s); + u = fabsf(s); if (u >= 1.0F) u = (float) size; else u *= size; u -= 0.5F; - *i0 = ifloor(u); + *i0 = util_ifloor(u); *i1 = *i0 + 1; break; case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: - u = FABSF(s); + u = fabsf(s); if (u >= 1.0F) u = (float) size; else u *= size; u -= 0.5F; - *i0 = ifloor(u); + *i0 = util_ifloor(u); *i1 = *i0 + 1; if (*i0 < 0) *i0 = 0; @@ -314,7 +314,7 @@ linear_texcoord(unsigned wrapMode, float s, unsigned size, { const float min = -1.0F / (2.0F * size); const float max = 1.0F - min; - u = FABSF(s); + u = fabsf(s); if (u <= min) u = min * size; else if (u >= max) @@ -322,7 +322,7 @@ linear_texcoord(unsigned wrapMode, float s, unsigned size, else u *= size; u -= 0.5F; - *i0 = ifloor(u); + *i0 = util_ifloor(u); *i1 = *i0 + 1; } break; @@ -343,12 +343,12 @@ nearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size) int i; switch (wrapMode) { case PIPE_TEX_WRAP_CLAMP: - i = ifloor(s); + i = util_ifloor(s); return CLAMP(i, 0, (int) size-1); case PIPE_TEX_WRAP_CLAMP_TO_EDGE: /* fall-through */ case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - return ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) ); + return util_ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) ); default: assert(0); return 0; @@ -368,7 +368,7 @@ linear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size, case PIPE_TEX_WRAP_CLAMP: /* Not exactly what the spec says, but it matches NVIDIA output */ s = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f); - *i0 = ifloor(s); + *i0 = util_ifloor(s); *i1 = *i0 + 1; break; case PIPE_TEX_WRAP_CLAMP_TO_EDGE: @@ -376,7 +376,7 @@ linear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size, case PIPE_TEX_WRAP_CLAMP_TO_BORDER: s = CLAMP(s, 0.5F, (float) size - 0.5F); s -= 0.5F; - *i0 = ifloor(s); + *i0 = util_ifloor(s); *i1 = *i0 + 1; if (*i1 > (int) size - 1) *i1 = size - 1; @@ -402,7 +402,7 @@ choose_cube_face(float rx, float ry, float rz, float *newS, float *newT) +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz */ - const float arx = FABSF(rx), ary = FABSF(ry), arz = FABSF(rz); + const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); unsigned face; float sc, tc, ma; @@ -477,16 +477,16 @@ compute_lambda(struct tgsi_sampler *sampler, { float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; - dsdx = FABSF(dsdx); - dsdy = FABSF(dsdy); + dsdx = fabsf(dsdx); + dsdy = fabsf(dsdy); rho = MAX2(dsdx, dsdy) * sampler->texture->width[0]; } if (t) { float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; float dtdy = t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]; float max; - dtdx = FABSF(dtdx); - dtdy = FABSF(dtdy); + dtdx = fabsf(dtdx); + dtdy = fabsf(dtdy); max = MAX2(dtdx, dtdy) * sampler->texture->height[0]; rho = MAX2(rho, max); } @@ -494,8 +494,8 @@ compute_lambda(struct tgsi_sampler *sampler, float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]; float dpdy = p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]; float max; - dpdx = FABSF(dpdx); - dpdy = FABSF(dpdy); + dpdx = fabsf(dpdx); + dpdy = fabsf(dpdy); max = MAX2(dpdx, dpdy) * sampler->texture->depth[0]; rho = MAX2(rho, max); } -- cgit v1.2.3 From a22bdd42d77bc858814f37d657fa940a520dbe56 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 Aug 2008 15:51:38 -0600 Subject: gallium: move math macros from p_util.h to u_math.h More can be done... --- src/gallium/auxiliary/util/u_math.h | 49 +++++++++++++++++++++++++++++++++++ src/gallium/include/pipe/p_util.h | 51 ------------------------------------- 2 files changed, 49 insertions(+), 51 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index e179ce700f..09c55e437f 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -29,6 +29,9 @@ /** * Math utilities and approximations for common math functions. * Reduced precision is usually acceptable in shaders... + * + * "fast" is used in the names of functions which are low-precision, + * or at least lower-precision than the normal C lib functions. */ @@ -36,6 +39,7 @@ #define U_MATH_H +#include "pipe/p_compiler.h" #include "pipe/p_util.h" #include "util/u_math.h" @@ -141,4 +145,49 @@ util_fast_pow(float x, float y) } + +/** + * Floor(x), returned as int. + */ +static INLINE int +util_ifloor(float f) +{ + int ai, bi; + double af, bf; + union fi u; + af = (3 << 22) + 0.5 + (double)f; + bf = (3 << 22) + 0.5 - (double)f; + u.f = (float) af; ai = u.i; + u.f = (float) bf; bi = u.i; + return (ai - bi) >> 1; +} + + +/** + * Round float to nearest int. + */ +static INLINE int +util_iround(float f) +{ +#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) + int r; + __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st"); + return r; +#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) + int r; + _asm { + fld f + fistp r + } + return r; +#else + if (f >= 0.0f) + return (int) (f + 0.5f); + else + return (int) (f - 0.5f); +#endif +} + + + #endif /* U_MATH_H */ diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 660192b28e..8f5cb4ddc5 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -399,57 +399,6 @@ do { \ } while (0) -static INLINE int ifloor(float f) -{ - int ai, bi; - double af, bf; - union fi u; - - af = (3 << 22) + 0.5 + (double)f; - bf = (3 << 22) + 0.5 - (double)f; - u.f = (float) af; ai = u.i; - u.f = (float) bf; bi = u.i; - return (ai - bi) >> 1; -} - - -#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) -static INLINE int iround(float f) -{ - int r; - __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st"); - return r; -} -#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) -static INLINE int iround(float f) -{ - int r; - _asm { - fld f - fistp r - } - return r; -} -#else -#define IROUND(f) ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F))) -#endif - - -/* Could maybe have an inline version of this? - */ -#if defined(__GNUC__) -#define FABSF(x) fabsf(x) -#else -#define FABSF(x) ((float) fabs(x)) -#endif - - -#if defined(__GNUC__) -#define CEILF(x) ceilf(x) -#else -#define CEILF(x) ((float) ceil(x)) -#endif - static INLINE int align(int value, int alignment) { return (value + alignment - 1) & ~(alignment - 1); -- cgit v1.2.3 From f9c04d55d045b3cf3ffef24f805166e3995096e2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 Aug 2008 15:53:28 -0600 Subject: gallium: insert __cplusplus/extern wrappings --- src/gallium/auxiliary/util/u_math.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index 09c55e437f..a541d30a5d 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -44,12 +44,17 @@ #include "util/u_math.h" +#ifdef __cplusplus +extern "C" { +#endif + #define POW2_TABLE_SIZE 256 #define POW2_TABLE_SCALE ((float) (POW2_TABLE_SIZE-1)) extern float pow2_table[POW2_TABLE_SIZE]; + extern void util_init_math(void); @@ -190,4 +195,8 @@ util_iround(float f) +#ifdef __cplusplus +} +#endif + #endif /* U_MATH_H */ -- cgit v1.2.3 From a13475ff0057f1de8e3bc08d6ca42b9e135a3f5a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 Aug 2008 16:09:37 -0600 Subject: gallium: replace align_int() with align() The two functions are identical. Removed align_int() from p_util.h --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 6 +++--- src/gallium/drivers/i915simple/i915_texture.c | 8 ++++---- src/gallium/drivers/i965simple/brw_tex_layout.c | 8 ++++---- src/gallium/include/pipe/p_util.h | 11 +++-------- 4 files changed, 14 insertions(+), 19 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 0aec4b71ba..be3535ed9e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -119,7 +119,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, struct draw_context *draw = fpme->draw; struct draw_vertex_shader *shader = draw->vs.vertex_shader; unsigned opt = fpme->opt; - unsigned alloc_count = align_int( fetch_count, 4 ); + unsigned alloc_count = align( fetch_count, 4 ); struct vertex_header *pipeline_verts = (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); @@ -195,7 +195,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, struct draw_context *draw = fpme->draw; struct draw_vertex_shader *shader = draw->vs.vertex_shader; unsigned opt = fpme->opt; - unsigned alloc_count = align_int( count, 4 ); + unsigned alloc_count = align( count, 4 ); struct vertex_header *pipeline_verts = (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); @@ -271,7 +271,7 @@ static void fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle, struct draw_context *draw = fpme->draw; struct draw_vertex_shader *shader = draw->vs.vertex_shader; unsigned opt = fpme->opt; - unsigned alloc_count = align_int( count, 4 ); + unsigned alloc_count = align( count, 4 ); struct vertex_header *pipeline_verts = (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index cf4964b26b..ca0fb8761b 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -220,7 +220,7 @@ i945_miptree_layout_2d( struct i915_texture *tex ) */ if (pt->last_level > 0) { unsigned mip1_nblocksx - = align_int(pf_get_nblocksx(&pt->block, minify(width)), align_x) + = align(pf_get_nblocksx(&pt->block, minify(width)), align_x) + pf_get_nblocksx(&pt->block, minify(minify(width))); if (mip1_nblocksx > nblocksx) @@ -229,14 +229,14 @@ i945_miptree_layout_2d( struct i915_texture *tex ) /* Pitch must be a whole number of dwords */ - tex->stride = align_int(tex->stride, 64); + tex->stride = align(tex->stride, 64); tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 1, width, height, 1); i915_miptree_set_image_offset(tex, level, 0, x, y); - nblocksy = align_int(nblocksy, align_y); + nblocksy = align(nblocksy, align_y); /* Because the images are packed better, the final offset * might not be the maximal one: @@ -246,7 +246,7 @@ i945_miptree_layout_2d( struct i915_texture *tex ) /* Layout_below: step right after second mipmap level. */ if (level == 1) { - x += align_int(nblocksx, align_x); + x += align(nblocksx, align_x); } else { y += nblocksy; diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 8c7725605b..9b6cf81723 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -144,7 +144,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex) */ if (pt->last_level > 0) { unsigned mip1_nblocksx - = align_int(pf_get_nblocksx(&pt->block, minify(width)), align_x) + = align(pf_get_nblocksx(&pt->block, minify(width)), align_x) + pf_get_nblocksx(&pt->block, minify(minify(width))); if (mip1_nblocksx > nblocksx) @@ -153,14 +153,14 @@ static void i945_miptree_layout_2d(struct brw_texture *tex) /* Pitch must be a whole number of dwords */ - tex->stride = align_int(tex->stride, 64); + tex->stride = align(tex->stride, 64); tex->total_nblocksy = 0; for (level = 0; level <= pt->last_level; level++) { intel_miptree_set_level_info(tex, level, 1, x, y, width, height, 1); - nblocksy = align_int(nblocksy, align_y); + nblocksy = align(nblocksy, align_y); /* Because the images are packed better, the final offset * might not be the maximal one: @@ -170,7 +170,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex) /* Layout_below: step right after second mipmap level. */ if (level == 1) { - x += align_int(nblocksx, align_x); + x += align(nblocksx, align_x); } else { y += nblocksy; diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 8f5cb4ddc5..cac0039e12 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -289,13 +289,14 @@ align16( void *unaligned ) } -static INLINE int align_int(int x, int align) +static INLINE int align(int value, int alignment) { - return (x + align - 1) & ~(align - 1); + return (value + alignment - 1) & ~(alignment - 1); } + #if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) static INLINE unsigned ffs( unsigned u ) { @@ -399,12 +400,6 @@ do { \ } while (0) -static INLINE int align(int value, int alignment) -{ - return (value + alignment - 1) & ~(alignment - 1); -} - - /* util/p_util.c */ extern void pipe_copy_rect(ubyte * dst, const struct pipe_format_block *block, -- cgit v1.2.3 From fe1e39afbb147deab60ecc932c24f921b46f1364 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 Aug 2008 16:19:22 -0600 Subject: gallium: move pipe_copy_rect(), pipe_fill_rect() protos into new u_rect.h header --- src/gallium/auxiliary/util/p_util.c | 1 + src/gallium/auxiliary/util/u_rect.h | 54 +++++++++++++++++++++++++++ src/gallium/drivers/cell/ppu/cell_surface.c | 1 + src/gallium/drivers/i915simple/i915_surface.c | 1 + src/gallium/drivers/i965simple/brw_surface.c | 1 + src/gallium/drivers/softpipe/sp_surface.c | 1 + src/gallium/include/pipe/p_util.h | 13 ------- 7 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 src/gallium/auxiliary/util/u_rect.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_util.c b/src/gallium/auxiliary/util/p_util.c index 271be4edf1..787881b192 100644 --- a/src/gallium/auxiliary/util/p_util.c +++ b/src/gallium/auxiliary/util/p_util.c @@ -33,6 +33,7 @@ #include "pipe/p_defines.h" #include "pipe/p_util.h" #include "pipe/p_format.h" +#include "util/u_rect.h" /** diff --git a/src/gallium/auxiliary/util/u_rect.h b/src/gallium/auxiliary/util/u_rect.h new file mode 100644 index 0000000000..fba4808864 --- /dev/null +++ b/src/gallium/auxiliary/util/u_rect.h @@ -0,0 +1,54 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Pipe copy/fill rect helpers. + */ + + +#ifndef U_RECT_H +#define U_RECT_H + + +#include "pipe/p_format.h" + + +extern void +pipe_copy_rect(ubyte * dst, const struct pipe_format_block *block, + unsigned dst_stride, unsigned dst_x, unsigned dst_y, + unsigned width, unsigned height, const ubyte * src, + int src_stride, unsigned src_x, int src_y); + +extern void +pipe_fill_rect(ubyte * dst, const struct pipe_format_block *block, + unsigned dst_stride, unsigned dst_x, unsigned dst_y, + unsigned width, unsigned height, uint32_t value); + + + +#endif /* U_RECT_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c index 5549eb496d..01ffa31c2c 100644 --- a/src/gallium/drivers/cell/ppu/cell_surface.c +++ b/src/gallium/drivers/cell/ppu/cell_surface.c @@ -30,6 +30,7 @@ #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" #include "util/p_tile.h" +#include "util/u_rect.h" #include "cell_context.h" #include "cell_surface.h" diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index 4430e81626..17b5125e56 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -34,6 +34,7 @@ #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" #include "util/p_tile.h" +#include "util/u_rect.h" /* Assumes all values are within bounds -- no checking at this level - diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index 0be3dfc743..69da252285 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -33,6 +33,7 @@ #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" #include "util/p_tile.h" +#include "util/u_rect.h" diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index 4f1bb881cb..bfbae234f1 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -30,6 +30,7 @@ #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" #include "util/p_tile.h" +#include "util/u_rect.h" #include "sp_context.h" #include "sp_surface.h" diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index cac0039e12..4a3fca5962 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -31,7 +31,6 @@ #include "p_config.h" #include "p_compiler.h" #include "p_debug.h" -#include "p_format.h" #include "p_pointer.h" #if defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) @@ -400,18 +399,6 @@ do { \ } while (0) -/* util/p_util.c - */ -extern void pipe_copy_rect(ubyte * dst, const struct pipe_format_block *block, - unsigned dst_stride, unsigned dst_x, unsigned dst_y, - unsigned width, unsigned height, const ubyte * src, - int src_stride, unsigned src_x, int src_y); - -extern void -pipe_fill_rect(ubyte * dst, const struct pipe_format_block *block, - unsigned dst_stride, unsigned dst_x, unsigned dst_y, - unsigned width, unsigned height, uint32_t value); - #if defined(_MSC_VER) #if _MSC_VER < 1400 && !defined(__cplusplus) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) -- cgit v1.2.3 From 2b87174ec306673c59386102890f35907be497ef Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 Aug 2008 16:22:35 -0600 Subject: gallium: rename p_util.c to u_rect.c (it only contains rect copy/fill helpers) --- src/gallium/auxiliary/util/Makefile | 2 +- src/gallium/auxiliary/util/SConscript | 2 +- src/gallium/auxiliary/util/p_util.c | 151 ---------------------------------- src/gallium/auxiliary/util/u_rect.c | 151 ++++++++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 153 deletions(-) delete mode 100644 src/gallium/auxiliary/util/p_util.c create mode 100644 src/gallium/auxiliary/util/u_rect.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index be1b97b535..6eebf6d29b 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -6,7 +6,6 @@ LIBNAME = util C_SOURCES = \ p_debug.c \ p_tile.c \ - p_util.c \ u_blit.c \ u_draw_quad.c \ u_gen_mipmap.c \ @@ -14,6 +13,7 @@ C_SOURCES = \ u_hash_table.c \ u_math.c \ u_mm.c \ + u_rect.c \ u_simple_shaders.c \ u_snprintf.c \ u_time.c diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 7865307a7a..94382fe1f9 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -7,7 +7,6 @@ util = env.ConvenienceLibrary( 'p_debug_mem.c', 'p_debug_prof.c', 'p_tile.c', - 'p_util.c', 'u_blit.c', 'u_draw_quad.c', 'u_gen_mipmap.c', @@ -15,6 +14,7 @@ util = env.ConvenienceLibrary( 'u_hash_table.c', 'u_math.c', 'u_mm.c', + 'u_rect.c', 'u_simple_shaders.c', 'u_snprintf.c', 'u_time.c', diff --git a/src/gallium/auxiliary/util/p_util.c b/src/gallium/auxiliary/util/p_util.c deleted file mode 100644 index 787881b192..0000000000 --- a/src/gallium/auxiliary/util/p_util.c +++ /dev/null @@ -1,151 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * Miscellaneous utility functions. - */ - - -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "pipe/p_format.h" -#include "util/u_rect.h" - - -/** - * Copy 2D rect from one place to another. - * Position and sizes are in pixels. - * src_pitch may be negative to do vertical flip of pixels from source. - */ -void -pipe_copy_rect(ubyte * dst, - const struct pipe_format_block *block, - unsigned dst_stride, - unsigned dst_x, - unsigned dst_y, - unsigned width, - unsigned height, - const ubyte * src, - int src_stride, - unsigned src_x, - int src_y) -{ - unsigned i; - int src_stride_pos = src_stride < 0 ? -src_stride : src_stride; - - assert(block->size > 0); - assert(block->width > 0); - assert(block->height > 0); - assert(src_x >= 0); - assert(src_y >= 0); - assert(dst_x >= 0); - assert(dst_y >= 0); - - dst_x /= block->width; - dst_y /= block->height; - width = (width + block->width - 1)/block->width; - height = (height + block->height - 1)/block->height; - src_x /= block->width; - src_y /= block->height; - - dst += dst_x * block->size; - src += src_x * block->size; - dst += dst_y * dst_stride; - src += src_y * src_stride_pos; - width *= block->size; - - if (width == dst_stride && width == src_stride) - memcpy(dst, src, height * width); - else { - for (i = 0; i < height; i++) { - memcpy(dst, src, width); - dst += dst_stride; - src += src_stride; - } - } -} - -void -pipe_fill_rect(ubyte * dst, - const struct pipe_format_block *block, - unsigned dst_stride, - unsigned dst_x, - unsigned dst_y, - unsigned width, - unsigned height, - uint32_t value) -{ - unsigned i, j; - unsigned width_size; - - assert(block->size > 0); - assert(block->width > 0); - assert(block->height > 0); - assert(dst_x >= 0); - assert(dst_y >= 0); - - dst_x /= block->width; - dst_y /= block->height; - width = (width + block->width - 1)/block->width; - height = (height + block->height - 1)/block->height; - - dst += dst_x * block->size; - dst += dst_y * dst_stride; - width_size = width * block->size; - - switch (block->size) { - case 1: - if(dst_stride == width_size) - memset(dst, (ubyte) value, height * width_size); - else { - for (i = 0; i < height; i++) { - memset(dst, (ubyte) value, width_size); - dst += dst_stride; - } - } - break; - case 2: - for (i = 0; i < height; i++) { - uint16_t *row = (uint16_t *)dst; - for (j = 0; j < width; j++) - *row++ = (uint16_t) value; - dst += dst_stride; - } - break; - case 4: - for (i = 0; i < height; i++) { - uint32_t *row = (uint32_t *)dst; - for (j = 0; j < width; j++) - *row++ = value; - dst += dst_stride; - } - break; - default: - assert(0); - break; - } -} diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c new file mode 100644 index 0000000000..94e447b9d5 --- /dev/null +++ b/src/gallium/auxiliary/util/u_rect.c @@ -0,0 +1,151 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Rectangle-related helper functions. + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_format.h" +#include "util/u_rect.h" + + +/** + * Copy 2D rect from one place to another. + * Position and sizes are in pixels. + * src_pitch may be negative to do vertical flip of pixels from source. + */ +void +pipe_copy_rect(ubyte * dst, + const struct pipe_format_block *block, + unsigned dst_stride, + unsigned dst_x, + unsigned dst_y, + unsigned width, + unsigned height, + const ubyte * src, + int src_stride, + unsigned src_x, + int src_y) +{ + unsigned i; + int src_stride_pos = src_stride < 0 ? -src_stride : src_stride; + + assert(block->size > 0); + assert(block->width > 0); + assert(block->height > 0); + assert(src_x >= 0); + assert(src_y >= 0); + assert(dst_x >= 0); + assert(dst_y >= 0); + + dst_x /= block->width; + dst_y /= block->height; + width = (width + block->width - 1)/block->width; + height = (height + block->height - 1)/block->height; + src_x /= block->width; + src_y /= block->height; + + dst += dst_x * block->size; + src += src_x * block->size; + dst += dst_y * dst_stride; + src += src_y * src_stride_pos; + width *= block->size; + + if (width == dst_stride && width == src_stride) + memcpy(dst, src, height * width); + else { + for (i = 0; i < height; i++) { + memcpy(dst, src, width); + dst += dst_stride; + src += src_stride; + } + } +} + +void +pipe_fill_rect(ubyte * dst, + const struct pipe_format_block *block, + unsigned dst_stride, + unsigned dst_x, + unsigned dst_y, + unsigned width, + unsigned height, + uint32_t value) +{ + unsigned i, j; + unsigned width_size; + + assert(block->size > 0); + assert(block->width > 0); + assert(block->height > 0); + assert(dst_x >= 0); + assert(dst_y >= 0); + + dst_x /= block->width; + dst_y /= block->height; + width = (width + block->width - 1)/block->width; + height = (height + block->height - 1)/block->height; + + dst += dst_x * block->size; + dst += dst_y * dst_stride; + width_size = width * block->size; + + switch (block->size) { + case 1: + if(dst_stride == width_size) + memset(dst, (ubyte) value, height * width_size); + else { + for (i = 0; i < height; i++) { + memset(dst, (ubyte) value, width_size); + dst += dst_stride; + } + } + break; + case 2: + for (i = 0; i < height; i++) { + uint16_t *row = (uint16_t *)dst; + for (j = 0; j < width; j++) + *row++ = (uint16_t) value; + dst += dst_stride; + } + break; + case 4: + for (i = 0; i < height; i++) { + uint32_t *row = (uint32_t *)dst; + for (j = 0; j < width; j++) + *row++ = value; + dst += dst_stride; + } + break; + default: + assert(0); + break; + } +} -- cgit v1.2.3 From f3dfd5969d447515635c077b700a2d4957208167 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 23 Aug 2008 12:30:39 +0200 Subject: util: Include missing u_rect.h. --- src/gallium/auxiliary/util/p_tile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index e366039a27..8219041c80 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -37,7 +37,7 @@ #include "pipe/p_inlines.h" #include "p_tile.h" - +#include "u_rect.h" /** -- cgit v1.2.3 From e7ff7f78be6c14b6c48e451d6d1f597af379f8f8 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 23 Aug 2008 12:31:16 +0200 Subject: util: Silence compiler warnings on Windows. --- src/gallium/auxiliary/util/u_math.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_math.c b/src/gallium/auxiliary/util/u_math.c index 8bf6551b6e..0729114d6a 100644 --- a/src/gallium/auxiliary/util/u_math.c +++ b/src/gallium/auxiliary/util/u_math.c @@ -39,7 +39,7 @@ init_pow2_table(void) { int i; for (i = 0; i < POW2_TABLE_SIZE; i++) { - pow2_table[i] = pow(2.0, i / POW2_TABLE_SCALE); + pow2_table[i] = (float) pow(2.0, i / POW2_TABLE_SCALE); } } -- cgit v1.2.3 From ec7415642d7eb192164e7a513198b86756de484c Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Sat, 23 Aug 2008 12:31:50 +0200 Subject: trace: Include u_string.h. --- src/gallium/drivers/trace/tr_stream_wd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/drivers/trace/tr_stream_wd.c b/src/gallium/drivers/trace/tr_stream_wd.c index 45309dcb4e..b3b65f0971 100644 --- a/src/gallium/drivers/trace/tr_stream_wd.c +++ b/src/gallium/drivers/trace/tr_stream_wd.c @@ -38,6 +38,7 @@ #include #include "pipe/p_util.h" +#include "util/u_string.h" #include "tr_stream.h" -- cgit v1.2.3 From 4f25420bdd834e81a3e22733304efc5261c2998a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 24 Aug 2008 17:48:55 -0600 Subject: gallium: refactor/replace p_util.h with util/u_memory.h and util/u_math.h Also, rename p_tile.[ch] to u_tile.[ch] --- src/gallium/README.portability | 4 +- src/gallium/auxiliary/cso_cache/cso_cache.c | 3 +- src/gallium/auxiliary/cso_cache/cso_context.c | 2 +- src/gallium/auxiliary/cso_cache/cso_hash.c | 2 +- src/gallium/auxiliary/draw/draw_context.c | 3 +- src/gallium/auxiliary/draw/draw_pipe.c | 1 - src/gallium/auxiliary/draw/draw_pipe_aaline.c | 3 +- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 4 +- src/gallium/auxiliary/draw/draw_pipe_clip.c | 4 +- src/gallium/auxiliary/draw/draw_pipe_cull.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 4 +- src/gallium/auxiliary/draw/draw_pipe_offset.c | 3 +- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 4 +- src/gallium/auxiliary/draw/draw_pipe_stipple.c | 6 +- src/gallium/auxiliary/draw/draw_pipe_twoside.c | 3 +- src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_util.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_validate.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 3 +- src/gallium/auxiliary/draw/draw_pipe_wide_line.c | 3 +- src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 3 +- src/gallium/auxiliary/draw/draw_pt.c | 1 - src/gallium/auxiliary/draw/draw_pt_emit.c | 2 +- src/gallium/auxiliary/draw/draw_pt_fetch.c | 2 +- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 2 +- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 3 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 3 +- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 2 +- src/gallium/auxiliary/draw/draw_pt_util.c | 1 - src/gallium/auxiliary/draw/draw_pt_varray.c | 4 +- src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 +- src/gallium/auxiliary/draw/draw_vbuf.h | 2 - src/gallium/auxiliary/draw/draw_vs.c | 6 +- src/gallium/auxiliary/draw/draw_vs_aos.c | 4 +- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 2 +- src/gallium/auxiliary/draw/draw_vs_aos_machine.c | 3 +- src/gallium/auxiliary/draw/draw_vs_exec.c | 3 +- src/gallium/auxiliary/draw/draw_vs_llvm.c | 1 - src/gallium/auxiliary/draw/draw_vs_sse.c | 3 +- src/gallium/auxiliary/draw/draw_vs_varient.c | 3 +- src/gallium/auxiliary/gallivm/gallivm_cpu.cpp | 3 +- src/gallium/auxiliary/gallivm/instructions.cpp | 2 +- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 2 +- .../auxiliary/pipebuffer/pb_buffer_fenced.c | 2 +- .../auxiliary/pipebuffer/pb_buffer_malloc.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c | 2 +- .../auxiliary/pipebuffer/pb_bufmgr_fenced.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_validate.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_winsys.c | 2 +- src/gallium/auxiliary/rtasm/rtasm_execmem.c | 2 +- src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c | 2 +- src/gallium/auxiliary/sct/sct.c | 2 +- src/gallium/auxiliary/tgsi/tgsi_build.c | 1 - src/gallium/auxiliary/tgsi/tgsi_build.h | 4 + src/gallium/auxiliary/tgsi/tgsi_dump_c.c | 1 - src/gallium/auxiliary/tgsi/tgsi_exec.c | 2 +- src/gallium/auxiliary/tgsi/tgsi_parse.c | 2 +- src/gallium/auxiliary/tgsi/tgsi_scan.c | 6 +- src/gallium/auxiliary/tgsi/tgsi_sse2.c | 2 +- src/gallium/auxiliary/tgsi/tgsi_transform.c | 1 + src/gallium/auxiliary/tgsi/tgsi_transform.h | 1 - src/gallium/auxiliary/tgsi/tgsi_util.c | 1 - src/gallium/auxiliary/translate/translate.c | 1 - src/gallium/auxiliary/translate/translate_cache.c | 2 +- .../auxiliary/translate/translate_generic.c | 2 +- src/gallium/auxiliary/translate/translate_sse.c | 2 +- src/gallium/auxiliary/util/Makefile | 2 +- src/gallium/auxiliary/util/SConscript | 2 +- src/gallium/auxiliary/util/p_debug.c | 1 - src/gallium/auxiliary/util/u_blit.c | 5 +- src/gallium/auxiliary/util/u_gen_mipmap.c | 2 +- src/gallium/auxiliary/util/u_handle_table.c | 4 +- src/gallium/auxiliary/util/u_hash_table.c | 5 +- src/gallium/auxiliary/util/u_math.h | 240 +++- src/gallium/auxiliary/util/u_memory.h | 222 ++++ src/gallium/auxiliary/util/u_mm.c | 2 +- src/gallium/auxiliary/util/u_pack_color.h | 36 +- src/gallium/auxiliary/util/u_pointer.h | 107 ++ src/gallium/auxiliary/util/u_rect.c | 1 - src/gallium/auxiliary/util/u_simple_shaders.c | 2 +- src/gallium/auxiliary/util/u_tile.c | 1169 ++++++++++++++++++++ src/gallium/auxiliary/util/u_tile.h | 101 ++ src/gallium/drivers/cell/common.h | 1 - src/gallium/drivers/cell/ppu/cell_clear.c | 2 +- src/gallium/drivers/cell/ppu/cell_context.c | 2 +- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 2 +- src/gallium/drivers/cell/ppu/cell_render.c | 2 +- src/gallium/drivers/cell/ppu/cell_screen.c | 2 +- src/gallium/drivers/cell/ppu/cell_state_derived.c | 2 +- src/gallium/drivers/cell/ppu/cell_state_emit.c | 2 +- src/gallium/drivers/cell/ppu/cell_state_shader.c | 2 +- src/gallium/drivers/cell/ppu/cell_surface.c | 2 +- src/gallium/drivers/cell/ppu/cell_texture.c | 2 +- src/gallium/drivers/cell/ppu/cell_winsys.c | 2 +- src/gallium/drivers/cell/spu/spu_exec.c | 1 - src/gallium/drivers/cell/spu/spu_tri.c | 1 - src/gallium/drivers/cell/spu/spu_util.c | 1 - src/gallium/drivers/cell/spu/spu_vertex_fetch.c | 1 - src/gallium/drivers/cell/spu/spu_vertex_shader.c | 1 - src/gallium/drivers/failover/fo_context.c | 2 +- src/gallium/drivers/i915simple/i915_context.c | 2 +- src/gallium/drivers/i915simple/i915_debug_fp.c | 2 +- src/gallium/drivers/i915simple/i915_fpc.h | 1 - .../drivers/i915simple/i915_fpc_translate.c | 2 + src/gallium/drivers/i915simple/i915_prim_emit.c | 4 +- src/gallium/drivers/i915simple/i915_prim_vbuf.c | 3 +- src/gallium/drivers/i915simple/i915_screen.c | 2 +- src/gallium/drivers/i915simple/i915_state.c | 3 +- .../drivers/i915simple/i915_state_derived.c | 2 +- .../drivers/i915simple/i915_state_dynamic.c | 4 +- .../drivers/i915simple/i915_state_immediate.c | 2 +- .../drivers/i915simple/i915_state_sampler.c | 2 +- src/gallium/drivers/i915simple/i915_surface.c | 3 +- src/gallium/drivers/i915simple/i915_texture.c | 3 +- src/gallium/drivers/i965simple/brw_cc.c | 6 +- src/gallium/drivers/i965simple/brw_clip_state.c | 3 +- src/gallium/drivers/i965simple/brw_context.c | 2 +- src/gallium/drivers/i965simple/brw_curbe.c | 3 +- src/gallium/drivers/i965simple/brw_draw_upload.c | 1 + src/gallium/drivers/i965simple/brw_gs_state.c | 3 +- src/gallium/drivers/i965simple/brw_screen.c | 2 +- src/gallium/drivers/i965simple/brw_sf_state.c | 5 +- src/gallium/drivers/i965simple/brw_shader_info.c | 2 +- src/gallium/drivers/i965simple/brw_state.c | 2 +- src/gallium/drivers/i965simple/brw_state_batch.c | 2 +- src/gallium/drivers/i965simple/brw_state_cache.c | 2 +- src/gallium/drivers/i965simple/brw_state_pool.c | 3 +- src/gallium/drivers/i965simple/brw_state_upload.c | 2 +- src/gallium/drivers/i965simple/brw_surface.c | 3 +- src/gallium/drivers/i965simple/brw_tex_layout.c | 8 +- src/gallium/drivers/i965simple/brw_vs_state.c | 3 +- src/gallium/drivers/i965simple/brw_wm.c | 2 +- src/gallium/drivers/i965simple/brw_wm_decl.c | 3 +- src/gallium/drivers/i965simple/brw_wm_glsl.c | 3 +- .../drivers/i965simple/brw_wm_sampler_state.c | 3 +- src/gallium/drivers/i965simple/brw_wm_state.c | 3 +- src/gallium/drivers/softpipe/sp_context.c | 2 +- src/gallium/drivers/softpipe/sp_fs_exec.c | 2 +- src/gallium/drivers/softpipe/sp_fs_llvm.c | 2 +- src/gallium/drivers/softpipe/sp_fs_sse.c | 2 +- src/gallium/drivers/softpipe/sp_prim_setup.c | 2 +- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 1 + src/gallium/drivers/softpipe/sp_quad_alpha_test.c | 2 +- src/gallium/drivers/softpipe/sp_quad_blend.c | 29 +- src/gallium/drivers/softpipe/sp_quad_bufloop.c | 2 +- src/gallium/drivers/softpipe/sp_quad_colormask.c | 3 +- src/gallium/drivers/softpipe/sp_quad_coverage.c | 2 +- src/gallium/drivers/softpipe/sp_quad_depth_test.c | 2 +- src/gallium/drivers/softpipe/sp_quad_earlyz.c | 2 +- src/gallium/drivers/softpipe/sp_quad_fs.c | 3 +- src/gallium/drivers/softpipe/sp_quad_occlusion.c | 2 +- src/gallium/drivers/softpipe/sp_quad_output.c | 2 +- src/gallium/drivers/softpipe/sp_quad_stencil.c | 2 +- src/gallium/drivers/softpipe/sp_quad_stipple.c | 2 +- src/gallium/drivers/softpipe/sp_query.c | 2 +- src/gallium/drivers/softpipe/sp_screen.c | 2 +- src/gallium/drivers/softpipe/sp_setup.c | 2 +- src/gallium/drivers/softpipe/sp_state_blend.c | 2 +- src/gallium/drivers/softpipe/sp_state_derived.c | 3 +- src/gallium/drivers/softpipe/sp_state_fs.c | 2 +- src/gallium/drivers/softpipe/sp_state_rasterizer.c | 2 +- src/gallium/drivers/softpipe/sp_state_sampler.c | 2 +- src/gallium/drivers/softpipe/sp_surface.c | 3 +- src/gallium/drivers/softpipe/sp_tex_sample.c | 2 +- src/gallium/drivers/softpipe/sp_texture.c | 3 +- src/gallium/drivers/softpipe/sp_tile_cache.c | 4 +- src/gallium/drivers/trace/tr_context.c | 2 +- src/gallium/drivers/trace/tr_dump.c | 2 + src/gallium/drivers/trace/tr_dump.h | 1 - src/gallium/drivers/trace/tr_screen.c | 2 +- src/gallium/drivers/trace/tr_state.c | 1 + src/gallium/drivers/trace/tr_stream_stdc.c | 2 +- src/gallium/drivers/trace/tr_stream_wd.c | 2 +- src/gallium/drivers/trace/tr_texture.c | 2 +- src/gallium/drivers/trace/tr_winsys.c | 3 +- src/gallium/include/pipe/p_util.h | 460 -------- src/gallium/state_trackers/python/gallium.i | 2 +- src/gallium/state_trackers/python/st_device.c | 3 +- src/gallium/state_trackers/python/st_sample.c | 5 +- .../state_trackers/python/st_softpipe_winsys.c | 3 +- .../winsys/drm/intel/common/intel_be_device.c | 2 +- .../winsys/drm/intel/dri/intel_winsys_softpipe.c | 2 +- src/gallium/winsys/egl_xlib/egl_xlib.c | 2 +- src/gallium/winsys/egl_xlib/sw_winsys.c | 3 +- src/gallium/winsys/gdi/wmesa.c | 2 +- src/gallium/winsys/xlib/brw_aub.c | 1 - src/gallium/winsys/xlib/xm_winsys.c | 3 +- src/gallium/winsys/xlib/xm_winsys_aub.c | 2 +- 193 files changed, 2128 insertions(+), 679 deletions(-) create mode 100644 src/gallium/auxiliary/util/u_memory.h create mode 100644 src/gallium/auxiliary/util/u_pointer.h create mode 100644 src/gallium/auxiliary/util/u_tile.c create mode 100644 src/gallium/auxiliary/util/u_tile.h delete mode 100644 src/gallium/include/pipe/p_util.h (limited to 'src/gallium') diff --git a/src/gallium/README.portability b/src/gallium/README.portability index d5d5987a7f..adecf4bb79 100644 --- a/src/gallium/README.portability +++ b/src/gallium/README.portability @@ -35,8 +35,8 @@ not available in Windows Kernel Mode. Use the appropriate p_*.h include. * Use MALLOC, CALLOC, FREE instead of the malloc, calloc, free functions. -* Use align_pointer() function defined in p_util.h for aligning pointers in a -portable way. +* Use align_pointer() function defined in u_memory.h for aligning pointers + in a portable way. == Debugging == diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index 36dc46ff80..6b1754ea00 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -28,9 +28,10 @@ /* Authors: Zack Rusin */ -#include "pipe/p_util.h" #include "pipe/p_debug.h" +#include "util/u_memory.h" + #include "cso_cache.h" #include "cso_hash.h" diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 86e4d46a20..f22ba40824 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -36,7 +36,7 @@ */ #include "pipe/p_state.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index 0646efd952..7f0044c5a7 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -31,7 +31,7 @@ */ #include "pipe/p_debug.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "cso_hash.h" diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 2f263cf06a..1c26cb31a3 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -31,7 +31,8 @@ */ -#include "pipe/p_util.h" +#include "util/u_memory.h" +#include "util/u_math.h" #include "draw_context.h" #include "draw_vbuf.h" #include "draw_vs.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 1db43876ef..3cde9d36d3 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -30,7 +30,6 @@ * Keith Whitwell */ -#include "pipe/p_util.h" #include "draw/draw_private.h" #include "draw/draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 991304b2c8..20841bb5d6 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -32,11 +32,12 @@ */ -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "tgsi/tgsi_transform.h" #include "tgsi/tgsi_dump.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index c7f4349cb3..2c1cacbdb4 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -38,7 +38,6 @@ */ -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -47,6 +46,9 @@ #include "tgsi/tgsi_transform.h" #include "tgsi/tgsi_dump.h" +#include "util/u_math.h" +#include "util/u_memory.h" + #include "draw_context.h" #include "draw_vs.h" #include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index fa10f8efca..3265dcd154 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -32,7 +32,9 @@ */ -#include "pipe/p_util.h" +#include "util/u_memory.h" +#include "util/u_math.h" + #include "pipe/p_shader_tokens.h" #include "draw_vs.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c index d0d22a38e0..053be5f050 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_cull.c +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -33,7 +33,7 @@ */ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_defines.h" #include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c index 4741b22d02..43d1fecc4d 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -28,7 +28,9 @@ /* Authors: Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" + #include "pipe/p_shader_tokens.h" #include "draw_vs.h" #include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index 2f5865741c..1fea5e6dcb 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -32,7 +32,8 @@ * \author Brian Paul */ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index e97136fa1f..b764d9c518 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -34,12 +34,14 @@ */ -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" +#include "util/u_math.h" +#include "util/u_memory.h" + #include "tgsi/tgsi_transform.h" #include "tgsi/tgsi_dump.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c index bf0db18a68..b65e2aa102 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c @@ -36,10 +36,12 @@ */ -#include "pipe/p_util.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "draw_pipe.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "draw/draw_pipe.h" /** Subclass of draw_stage */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c index 3ac825f565..c329d92339 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -28,7 +28,8 @@ /* Authors: Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" #include "draw_vs.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c index 8f97fdedaa..68835fd1a5 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -33,7 +33,7 @@ /* Authors: Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_defines.h" #include "draw_private.h" #include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_util.c b/src/gallium/auxiliary/draw/draw_pipe_util.c index 04438f4dd0..e22e5fed0c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_util.c +++ b/src/gallium/auxiliary/draw/draw_pipe_util.c @@ -30,7 +30,7 @@ * Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "draw/draw_private.h" #include "draw/draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c index 6be1d369c3..f34c68728e 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_validate.c +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -28,7 +28,7 @@ /* Authors: Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_defines.h" #include "draw_private.h" #include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index a6fde77a0e..c0cf4269db 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -35,7 +35,8 @@ #include "pipe/p_debug.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "draw_vbuf.h" #include "draw_private.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c index 48ec2f1239..184e363594 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -28,9 +28,10 @@ /* Authors: Keith Whitwell */ -#include "pipe/p_util.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "draw_private.h" #include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index 54590984c6..4f1326053d 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -28,7 +28,8 @@ /* Authors: Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" #include "draw_vs.h" diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 85a75525c8..669c11c993 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -30,7 +30,6 @@ * Keith Whitwell */ -#include "pipe/p_util.h" #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_pt.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 40f05cb9e0..d4eca80588 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_vbuf.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 07f4c99164..6377f896fb 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_vbuf.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 4a1f3b0953..0684c93d10 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -30,7 +30,7 @@ * Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_vbuf.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index fdf9b6fe6a..87094f3092 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -31,7 +31,8 @@ */ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_vbuf.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index be3535ed9e..f617aac9f7 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -25,7 +25,8 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "draw/draw_context.h" #include "draw/draw_vbuf.h" #include "draw/draw_vertex.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index af6306b1c6..96dc706b99 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_context.h" #include "draw/draw_context.h" #include "draw/draw_private.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_util.c b/src/gallium/auxiliary/draw/draw_pt_util.c index 32c8a9632c..3bc7939c55 100644 --- a/src/gallium/auxiliary/draw/draw_pt_util.c +++ b/src/gallium/auxiliary/draw/draw_pt_util.c @@ -30,7 +30,6 @@ * Keith Whitwell */ -#include "pipe/p_util.h" #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_pt.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c index 46e722a154..c15afe65f1 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray.c +++ b/src/gallium/auxiliary/draw/draw_pt_varray.c @@ -25,7 +25,9 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" + #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_pt.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index cda2987c9e..b8b5de729d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -30,7 +30,7 @@ * Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_pt.h" diff --git a/src/gallium/auxiliary/draw/draw_vbuf.h b/src/gallium/auxiliary/draw/draw_vbuf.h index e90f37872a..62247ccd9f 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.h +++ b/src/gallium/auxiliary/draw/draw_vbuf.h @@ -37,8 +37,6 @@ #define DRAW_VBUF_H_ -#include "pipe/p_util.h" - struct draw_context; struct vertex_info; diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index f798b20492..34adbd49b0 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -31,11 +31,15 @@ * Brian Paul */ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" + #include "pipe/p_shader_tokens.h" + #include "draw_private.h" #include "draw_context.h" #include "draw_vs.h" + #include "translate/translate.h" #include "translate/translate_cache.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 41bdd012d5..760fcb389f 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -29,9 +29,9 @@ */ -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" +#include "util/u_memory.h" #include "util/u_math.h" +#include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" #include "tgsi/tgsi_exec.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index eda677cc62..ab3c5b94a5 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c index e029b7b4bb..b358bd2df4 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c @@ -29,8 +29,9 @@ #include "pipe/p_config.h" -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" #include "tgsi/tgsi_exec.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index e26903d8cc..44563803f9 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -31,7 +31,8 @@ * Brian Paul */ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "pipe/p_shader_tokens.h" #include "draw_private.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index fc03473b91..2ce30b9a02 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -32,7 +32,6 @@ * Brian Paul */ -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "draw_private.h" #include "draw_context.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 61f0c084c3..0efabd9de8 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -31,13 +31,14 @@ * Brian Paul */ +#include "util/u_math.h" +#include "util/u_memory.h" #include "pipe/p_config.h" #include "draw_vs.h" #if defined(PIPE_ARCH_X86) -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "draw_private.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index 994ce3e889..4daf05dae7 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -30,7 +30,8 @@ * Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_memory.h" +#include "util/u_math.h" #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_vbuf.h" diff --git a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp index cf5b978837..e64bfb1c6c 100644 --- a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp @@ -41,11 +41,12 @@ #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" -#include "pipe/p_util.h" #include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_dump.h" +#include "util/u_memory.h" + #include #include #include diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp index 035224e8f3..a82dc30306 100644 --- a/src/gallium/auxiliary/gallivm/instructions.cpp +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -35,7 +35,7 @@ #include "storage.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include #include diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 76049ade7c..efddc04e81 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -29,7 +29,7 @@ #include "storagesoa.h" #include "pipe/p_shader_tokens.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include #include diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index ce41418a0f..8ae052e875 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -45,7 +45,7 @@ #include "pipe/p_debug.h" #include "pipe/p_winsys.h" #include "pipe/p_thread.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "util/u_double_list.h" #include "pb_buffer.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c index e90d2e5623..20fc87b39d 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c @@ -35,7 +35,7 @@ #include "pipe/p_debug.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c index 0d2d6c0c1b..2afaeafa1a 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_alt.c @@ -35,7 +35,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_debug.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index bed4bec4fe..b914c2d0fe 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -38,7 +38,7 @@ #include "pipe/p_debug.h" #include "pipe/p_winsys.h" #include "pipe/p_thread.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "util/u_double_list.h" #include "util/u_time.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index d02e3500ff..5e518370d0 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -37,7 +37,7 @@ #include "pipe/p_debug.h" #include "pipe/p_winsys.h" #include "pipe/p_thread.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "util/u_double_list.h" #include "util/u_time.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c index 05efd8ce41..8fc63ce648 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c @@ -35,7 +35,7 @@ #include "pipe/p_debug.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pb_buffer.h" #include "pb_buffer_fenced.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index c51e582611..b40eb6cc90 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -36,7 +36,7 @@ #include "pipe/p_defines.h" #include "pipe/p_debug.h" #include "pipe/p_thread.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "util/u_double_list.h" #include "util/u_mm.h" #include "pb_buffer.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index 95af08929a..93d2cc9635 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -39,7 +39,7 @@ #include "pipe/p_debug.h" #include "pipe/p_thread.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "util/u_double_list.h" #include "pb_buffer.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index 598d9ce310..af307e265a 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -39,7 +39,7 @@ #include "pipe/p_debug.h" #include "pipe/p_thread.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "util/u_double_list.h" #include "util/u_time.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c index 362fd896f3..1e54fc39d4 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_validate.c +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c @@ -35,7 +35,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_error.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_debug.h" #include "pb_buffer.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_winsys.c b/src/gallium/auxiliary/pipebuffer/pb_winsys.c index 978944091f..28d137dbc4 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_winsys.c +++ b/src/gallium/auxiliary/pipebuffer/pb_winsys.c @@ -35,7 +35,7 @@ #include "pipe/p_winsys.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pb_buffer.h" diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c index 300c1c2d9d..dfa5c35ab6 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c @@ -33,7 +33,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_debug.h" #include "pipe/p_thread.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "rtasm_execmem.h" diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c index 7f6bf577b2..285ddc0e3f 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c @@ -30,7 +30,7 @@ */ #include "pipe/p_compiler.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "rtasm_ppc_spe.h" #ifdef GALLIUM_CELL diff --git a/src/gallium/auxiliary/sct/sct.c b/src/gallium/auxiliary/sct/sct.c index 5e4126e014..49bb7ea92e 100644 --- a/src/gallium/auxiliary/sct/sct.c +++ b/src/gallium/auxiliary/sct/sct.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_state.h" #include "pipe/p_inlines.h" #include "sct.h" diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index 050b448fe7..74614d3688 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -26,7 +26,6 @@ **************************************************************************/ #include "pipe/p_debug.h" -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "tgsi_build.h" #include "tgsi_parse.h" diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h index 6ae7f324f8..7d6234746a 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.h +++ b/src/gallium/auxiliary/tgsi/tgsi_build.h @@ -28,6 +28,10 @@ #ifndef TGSI_BUILD_H #define TGSI_BUILD_H + +struct tgsi_token; + + #if defined __cplusplus extern "C" { #endif diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c index 1025866a25..be25cb45a0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c @@ -26,7 +26,6 @@ **************************************************************************/ #include "pipe/p_debug.h" -#include "pipe/p_util.h" #include "util/u_string.h" #include "tgsi_dump_c.h" #include "tgsi_build.h" diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index e28b56c842..fb573fe1f0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -52,11 +52,11 @@ #include "pipe/p_compiler.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" #include "tgsi_exec.h" +#include "util/u_memory.h" #include "util/u_math.h" #define FAST_MATH 1 diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c index d16f0cdcad..3757486ba9 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.c +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c @@ -26,10 +26,10 @@ **************************************************************************/ #include "pipe/p_debug.h" -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "tgsi_parse.h" #include "tgsi_build.h" +#include "util/u_memory.h" void tgsi_full_token_init( diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c index 59bcf10b53..be4870a498 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c @@ -33,11 +33,11 @@ */ -#include "tgsi_scan.h" -#include "tgsi/tgsi_parse.h" +#include "util/u_math.h" #include "tgsi/tgsi_build.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_scan.h" -#include "pipe/p_util.h" diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 00ed4da450..626724ad4e 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "pipe/p_debug.h" #include "pipe/p_shader_tokens.h" #include "util/u_math.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/auxiliary/tgsi/tgsi_transform.c b/src/gallium/auxiliary/tgsi/tgsi_transform.c index 357f77b05a..ea87da31e5 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_transform.c +++ b/src/gallium/auxiliary/tgsi/tgsi_transform.c @@ -31,6 +31,7 @@ * Authors: Brian Paul */ +#include "pipe/p_debug.h" #include "tgsi_transform.h" diff --git a/src/gallium/auxiliary/tgsi/tgsi_transform.h b/src/gallium/auxiliary/tgsi/tgsi_transform.h index 3da0b38271..a121adbaef 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_transform.h +++ b/src/gallium/auxiliary/tgsi/tgsi_transform.h @@ -29,7 +29,6 @@ #define TGSI_TRANSFORM_H -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_build.h" diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.c b/src/gallium/auxiliary/tgsi/tgsi_util.c index 09486e649e..50101a9bb0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_util.c +++ b/src/gallium/auxiliary/tgsi/tgsi_util.c @@ -26,7 +26,6 @@ **************************************************************************/ #include "pipe/p_debug.h" -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "tgsi_parse.h" #include "tgsi_build.h" diff --git a/src/gallium/auxiliary/translate/translate.c b/src/gallium/auxiliary/translate/translate.c index b93fbf9033..7678903f75 100644 --- a/src/gallium/auxiliary/translate/translate.c +++ b/src/gallium/auxiliary/translate/translate.c @@ -31,7 +31,6 @@ */ #include "pipe/p_config.h" -#include "pipe/p_util.h" #include "pipe/p_state.h" #include "translate.h" diff --git a/src/gallium/auxiliary/translate/translate_cache.c b/src/gallium/auxiliary/translate/translate_cache.c index 115dc9287e..d8069a149c 100644 --- a/src/gallium/auxiliary/translate/translate_cache.c +++ b/src/gallium/auxiliary/translate/translate_cache.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_state.h" #include "translate.h" #include "translate_cache.h" diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 4c8179ffa8..4d336f47ea 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -30,7 +30,7 @@ * Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_state.h" #include "translate.h" diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index 18a212ac1c..7955186e16 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -28,7 +28,7 @@ #include "pipe/p_config.h" #include "pipe/p_compiler.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "util/u_simple_list.h" #include "translate.h" diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index 6eebf6d29b..6e5fd26c05 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -5,7 +5,6 @@ LIBNAME = util C_SOURCES = \ p_debug.c \ - p_tile.c \ u_blit.c \ u_draw_quad.c \ u_gen_mipmap.c \ @@ -16,6 +15,7 @@ C_SOURCES = \ u_rect.c \ u_simple_shaders.c \ u_snprintf.c \ + u_tile.c \ u_time.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index 94382fe1f9..ce3fad7068 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -6,7 +6,6 @@ util = env.ConvenienceLibrary( 'p_debug.c', 'p_debug_mem.c', 'p_debug_prof.c', - 'p_tile.c', 'u_blit.c', 'u_draw_quad.c', 'u_gen_mipmap.c', @@ -17,6 +16,7 @@ util = env.ConvenienceLibrary( 'u_rect.c', 'u_simple_shaders.c', 'u_snprintf.c', + 'u_tile.c', 'u_time.c', ]) diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 2c2f2f8931..7d1dba5a24 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -51,7 +51,6 @@ #endif #include "pipe/p_compiler.h" -#include "pipe/p_util.h" #include "pipe/p_debug.h" #include "pipe/p_format.h" #include "pipe/p_state.h" diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index ae087df4cf..05399f9885 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -37,12 +37,13 @@ #include "pipe/p_debug.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/p_util.h" #include "pipe/p_winsys.h" #include "pipe/p_shader_tokens.h" -#include "util/u_draw_quad.h" #include "util/u_blit.h" +#include "util/u_draw_quad.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "util/u_simple_shaders.h" #include "cso_cache/cso_context.h" diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 8713ff5d58..c1e2c19f87 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -37,10 +37,10 @@ #include "pipe/p_debug.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/p_util.h" #include "pipe/p_winsys.h" #include "pipe/p_shader_tokens.h" +#include "util/u_memory.h" #include "util/u_draw_quad.h" #include "util/u_gen_mipmap.h" #include "util/u_simple_shaders.h" diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c index 2176a00959..2c40011923 100644 --- a/src/gallium/auxiliary/util/u_handle_table.c +++ b/src/gallium/auxiliary/util/u_handle_table.c @@ -35,9 +35,9 @@ #include "pipe/p_compiler.h" #include "pipe/p_debug.h" -#include "pipe/p_util.h" -#include "u_handle_table.h" +#include "util/u_memory.h" +#include "util/u_handle_table.h" #define HANDLE_TABLE_INITIAL_SIZE 16 diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c index dd5eca7fca..0bc8de9632 100644 --- a/src/gallium/auxiliary/util/u_hash_table.c +++ b/src/gallium/auxiliary/util/u_hash_table.c @@ -40,10 +40,11 @@ #include "pipe/p_compiler.h" #include "pipe/p_debug.h" -#include "pipe/p_util.h" #include "cso_cache/cso_hash.h" -#include "u_hash_table.h" + +#include "util/u_memory.h" +#include "util/u_hash_table.h" struct hash_table diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index a541d30a5d..9b4ca39371 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -40,8 +40,6 @@ #include "pipe/p_compiler.h" -#include "pipe/p_util.h" -#include "util/u_math.h" #ifdef __cplusplus @@ -49,6 +47,132 @@ extern "C" { #endif +#if defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) +__inline double ceil(double val) +{ + double ceil_val; + + if((val - (long) val) == 0) { + ceil_val = val; + } + else { + if(val > 0) { + ceil_val = (long) val + 1; + } + else { + ceil_val = (long) val; + } + } + + return ceil_val; +} + +#ifndef PIPE_SUBSYSTEM_WINDOWS_CE +__inline double floor(double val) +{ + double floor_val; + + if((val - (long) val) == 0) { + floor_val = val; + } + else { + if(val > 0) { + floor_val = (long) val; + } + else { + floor_val = (long) val - 1; + } + } + + return floor_val; +} +#endif + +#pragma function(pow) +__inline double __cdecl pow(double val, double exponent) +{ + /* XXX */ + assert(0); + return 0; +} + +#pragma function(log) +__inline double __cdecl log(double val) +{ + /* XXX */ + assert(0); + return 0; +} + +#pragma function(atan2) +__inline double __cdecl atan2(double val) +{ + /* XXX */ + assert(0); + return 0; +} +#else +#include +#include +#endif + + +#if defined(_MSC_VER) +#if _MSC_VER < 1400 && !defined(__cplusplus) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) + +static INLINE float cosf( float f ) +{ + return (float) cos( (double) f ); +} + +static INLINE float sinf( float f ) +{ + return (float) sin( (double) f ); +} + +static INLINE float ceilf( float f ) +{ + return (float) ceil( (double) f ); +} + +static INLINE float floorf( float f ) +{ + return (float) floor( (double) f ); +} + +static INLINE float powf( float f, float g ) +{ + return (float) pow( (double) f, (double) g ); +} + +static INLINE float sqrtf( float f ) +{ + return (float) sqrt( (double) f ); +} + +static INLINE float fabsf( float f ) +{ + return (float) fabs( (double) f ); +} + +static INLINE float logf( float f ) +{ + return (float) log( (double) f ); +} + +#else +/* Work-around an extra semi-colon in VS 2005 logf definition */ +#ifdef logf +#undef logf +#define logf(x) ((float)log((double)(x))) +#endif /* logf */ +#endif +#endif /* _MSC_VER */ + + + + + #define POW2_TABLE_SIZE 256 #define POW2_TABLE_SCALE ((float) (POW2_TABLE_SIZE-1)) extern float pow2_table[POW2_TABLE_SIZE]; @@ -59,6 +183,11 @@ extern void util_init_math(void); +union fi { + float f; + int i; + unsigned ui; +}; /** @@ -195,6 +324,113 @@ util_iround(float f) +#if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) +/** + * Find first bit set in word. Least significant bit is 1. + * Return 0 if no bits set. + */ +static INLINE +unsigned ffs( unsigned u ) +{ + unsigned i; + + if( u == 0 ) { + return 0; + } + + __asm bsf eax, [u] + __asm inc eax + __asm mov [i], eax + + return i; +} +#endif + + +/** + * Return float bits. + */ +static INLINE unsigned +fui( float f ) +{ + union fi fi; + fi.f = f; + return fi.ui; +} + + + +static INLINE float +ubyte_to_float(ubyte ub) +{ + return (float) ub * (1.0f / 255.0f); +} + + +/** + * Convert float in [0,1] to ubyte in [0,255] with clamping. + */ +static INLINE ubyte +float_to_ubyte(float f) +{ + const int ieee_0996 = 0x3f7f0000; /* 0.996 or so */ + union fi tmp; + + tmp.f = f; + if (tmp.i < 0) { + return (ubyte) 0; + } + else if (tmp.i >= ieee_0996) { + return (ubyte) 255; + } + else { + tmp.f = tmp.f * (255.0f/256.0f) + 32768.0f; + return (ubyte) tmp.i; + } +} + + + +#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) + +#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) +#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) + + +static INLINE int +align(int value, int alignment) +{ + return (value + alignment - 1) & ~(alignment - 1); +} + + +#ifndef COPY_4V +#define COPY_4V( DST, SRC ) \ +do { \ + (DST)[0] = (SRC)[0]; \ + (DST)[1] = (SRC)[1]; \ + (DST)[2] = (SRC)[2]; \ + (DST)[3] = (SRC)[3]; \ +} while (0) +#endif + + +#ifndef COPY_4FV +#define COPY_4FV( DST, SRC ) COPY_4V(DST, SRC) +#endif + + +#ifndef ASSIGN_4V +#define ASSIGN_4V( DST, V0, V1, V2, V3 ) \ +do { \ + (DST)[0] = (V0); \ + (DST)[1] = (V1); \ + (DST)[2] = (V2); \ + (DST)[3] = (V3); \ +} while (0) +#endif + + #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/util/u_memory.h b/src/gallium/auxiliary/util/u_memory.h new file mode 100644 index 0000000000..148a5cb997 --- /dev/null +++ b/src/gallium/auxiliary/util/u_memory.h @@ -0,0 +1,222 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Memory functions + */ + + +#ifndef U_MEMORY_H +#define U_MEMORY_H + + +#include "util/u_pointer.h" + + + /* Define ENOMEM for WINCE */ +#if (_WIN32_WCE < 600) +#ifndef ENOMEM +#define ENOMEM 12 +#endif +#endif + + + +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && defined(DEBUG) + +/* memory debugging */ + +#include "p_debug.h" + +#define MALLOC( _size ) \ + debug_malloc( __FILE__, __LINE__, __FUNCTION__, _size ) +#define CALLOC( _count, _size ) \ + debug_calloc(__FILE__, __LINE__, __FUNCTION__, _count, _size ) +#define FREE( _ptr ) \ + debug_free( __FILE__, __LINE__, __FUNCTION__, _ptr ) +#define REALLOC( _ptr, _old_size, _size ) \ + debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _size ) + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + +void * __stdcall +EngAllocMem( + unsigned long Flags, + unsigned long MemSize, + unsigned long Tag ); + +void __stdcall +EngFreeMem( + void *Mem ); + +#define MALLOC( _size ) EngAllocMem( 0, _size, 'D3AG' ) +#define _FREE( _ptr ) EngFreeMem( _ptr ) + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) + +void * +ExAllocatePool( + unsigned long PoolType, + size_t NumberOfBytes); + +void +ExFreePool(void *P); + +#define MALLOC(_size) ExAllocatePool(0, _size) +#define _FREE(_ptr) ExFreePool(_ptr) + +#else + +#define MALLOC( SIZE ) malloc( SIZE ) +#define CALLOC( COUNT, SIZE ) calloc( COUNT, SIZE ) +#define FREE( PTR ) free( PTR ) +#define REALLOC( OLDPTR, OLDSIZE, NEWSIZE ) realloc( OLDPTR, NEWSIZE ) + +#endif + + +#ifndef CALLOC +static INLINE void * +CALLOC( unsigned count, unsigned size ) +{ + void *ptr = MALLOC( count * size ); + if( ptr ) { + memset( ptr, 0, count * size ); + } + return ptr; +} +#endif /* !CALLOC */ + +#ifndef FREE +static INLINE void +FREE( void *ptr ) +{ + if( ptr ) { + _FREE( ptr ); + } +} +#endif /* !FREE */ + +#ifndef REALLOC +static INLINE void * +REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) +{ + void *new_ptr = NULL; + + if (new_size != 0) { + unsigned copy_size = old_size < new_size ? old_size : new_size; + new_ptr = MALLOC( new_size ); + if (new_ptr && old_ptr && copy_size) { + memcpy( new_ptr, old_ptr, copy_size ); + } + } + + FREE( old_ptr ); + return new_ptr; +} +#endif /* !REALLOC */ + + +#define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T)) + +#define CALLOC_STRUCT(T) (struct T *) CALLOC(1, sizeof(struct T)) + + +/** + * Return memory on given byte alignment + */ +static INLINE void * +align_malloc(size_t bytes, uint alignment) +{ +#if defined(HAVE_POSIX_MEMALIGN) + void *mem; + alignment = (alignment + (uint)sizeof(void*) - 1) & ~((uint)sizeof(void*) - 1); + if(posix_memalign(& mem, alignment, bytes) != 0) + return NULL; + return mem; +#else + char *ptr, *buf; + + assert( alignment > 0 ); + + ptr = (char *) MALLOC(bytes + alignment + sizeof(void *)); + if (!ptr) + return NULL; + + buf = (char *) align_pointer( ptr + sizeof(void *), alignment ); + *(char **)(buf - sizeof(void *)) = ptr; + + return buf; +#endif /* defined(HAVE_POSIX_MEMALIGN) */ +} + +/** + * Free memory returned by align_malloc(). + */ +static INLINE void +align_free(void *ptr) +{ +#if defined(HAVE_POSIX_MEMALIGN) + FREE(ptr); +#else + void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); + void *realAddr = *cubbyHole; + FREE(realAddr); +#endif /* defined(HAVE_POSIX_MEMALIGN) */ +} + + +/** + * Duplicate a block of memory. + */ +static INLINE void * +mem_dup(const void *src, uint size) +{ + void *dup = MALLOC(size); + if (dup) + memcpy(dup, src, size); + return dup; +} + + +/** + * Number of elements in an array. + */ +#ifndef Elements +#define Elements(x) (sizeof(x)/sizeof((x)[0])) +#endif + + +/** + * Offset of a field in a struct, in bytes. + */ +#define Offset(TYPE, MEMBER) ((unsigned)&(((TYPE *)NULL)->MEMBER)) + + + +#endif /* U_MEMORY_H */ diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c index b49ae074e0..0f51dd5977 100644 --- a/src/gallium/auxiliary/util/u_mm.c +++ b/src/gallium/auxiliary/util/u_mm.c @@ -24,9 +24,9 @@ #include "pipe/p_compiler.h" -#include "pipe/p_util.h" #include "pipe/p_debug.h" +#include "util/u_memory.h" #include "util/u_mm.h" diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 06abb34d5a..39e4ae9d07 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -37,6 +37,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" +#include "util/u_math.h" /** @@ -150,10 +151,10 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest) if (pf_size_x(format) <= 8) { /* format uses 8-bit components or less */ - UNCLAMPED_FLOAT_TO_UBYTE(r, rgba[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, rgba[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, rgba[2]); - UNCLAMPED_FLOAT_TO_UBYTE(a, rgba[3]); + r = float_to_ubyte(rgba[0]); + g = float_to_ubyte(rgba[1]); + b = float_to_ubyte(rgba[2]); + a = float_to_ubyte(rgba[3]); } switch (format) { @@ -286,4 +287,31 @@ util_pack_z(enum pipe_format format, double z) } +/** + * Pack 4 ubytes into a 4-byte word + */ +static INLINE unsigned +pack_ub4(ubyte b0, ubyte b1, ubyte b2, ubyte b3) +{ + return ((((unsigned int)b0) << 0) | + (((unsigned int)b1) << 8) | + (((unsigned int)b2) << 16) | + (((unsigned int)b3) << 24)); +} + + +/** + * Pack/convert 4 floats into one 4-byte word. + */ +static INLINE unsigned +pack_ui32_float4(float a, float b, float c, float d) +{ + return pack_ub4( float_to_ubyte(a), + float_to_ubyte(b), + float_to_ubyte(c), + float_to_ubyte(d) ); +} + + + #endif /* U_PACK_COLOR_H */ diff --git a/src/gallium/auxiliary/util/u_pointer.h b/src/gallium/auxiliary/util/u_pointer.h new file mode 100644 index 0000000000..e1af9f11cb --- /dev/null +++ b/src/gallium/auxiliary/util/u_pointer.h @@ -0,0 +1,107 @@ +/************************************************************************** + * + * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef U_POINTER_H +#define U_POINTER_H + +#include "pipe/p_compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static INLINE intptr_t +pointer_to_intptr( const void *p ) +{ + union { + const void *p; + intptr_t i; + } pi; + pi.p = p; + return pi.i; +} + +static INLINE void * +intptr_to_pointer( intptr_t i ) +{ + union { + void *p; + intptr_t i; + } pi; + pi.i = i; + return pi.p; +} + +static INLINE uintptr_t +pointer_to_uintptr( const void *ptr ) +{ + union { + const void *p; + uintptr_t u; + } pu; + pu.p = ptr; + return pu.u; +} + +static INLINE void * +uintptr_to_pointer( uintptr_t u ) +{ + union { + void *p; + uintptr_t u; + } pu; + pu.u = u; + return pu.p; +} + +/** + * Return a pointer aligned to next multiple of N bytes. + */ +static INLINE void * +align_pointer( const void *unaligned, uintptr_t alignment ) +{ + uintptr_t aligned = (pointer_to_uintptr( unaligned ) + alignment - 1) & ~(alignment - 1); + return uintptr_to_pointer( aligned ); +} + + +/** + * Return a pointer aligned to next multiple of 16 bytes. + */ +static INLINE void * +align16( void *unaligned ) +{ + return align_pointer( unaligned, 16 ); +} + + + +#ifdef __cplusplus +} +#endif + +#endif /* U_POINTER_H */ diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c index 94e447b9d5..b31ab5415f 100644 --- a/src/gallium/auxiliary/util/u_rect.c +++ b/src/gallium/auxiliary/util/u_rect.c @@ -31,7 +31,6 @@ #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_format.h" #include "util/u_rect.h" diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index c34fb6ee33..f06d13c2c4 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -37,10 +37,10 @@ #include "pipe/p_debug.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/p_util.h" #include "pipe/p_winsys.h" #include "pipe/p_shader_tokens.h" +#include "util/u_memory.h" #include "util/u_simple_shaders.h" #include "tgsi/tgsi_build.h" diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c new file mode 100644 index 0000000000..853c503f4f --- /dev/null +++ b/src/gallium/auxiliary/util/u_tile.c @@ -0,0 +1,1169 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * RGBA/float tile get/put functions. + * Usable both by drivers and state trackers. + * Surfaces should already be in a mapped state. + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" + +#include "util/u_math.h" +#include "util/u_memory.h" +#include "util/u_rect.h" +#include "util/u_tile.h" + + +/** + * Move raw block of pixels from surface to user memory. + * This should be usable by any hw driver that has mappable surfaces. + */ +void +pipe_get_tile_raw(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + void *dst, int dst_stride) +{ + const void *src; + + if (dst_stride == 0) + dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + src = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ); + assert(src); + if(!src) + return; + + pipe_copy_rect(dst, &ps->block, dst_stride, 0, 0, w, h, src, ps->stride, x, y); + + pipe_surface_unmap(ps); +} + + +/** + * Move raw block of pixels from user memory to surface. + * This should be usable by any hw driver that has mappable surfaces. + */ +void +pipe_put_tile_raw(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const void *src, int src_stride) +{ + void *dst; + + if (src_stride == 0) + src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + dst = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE); + assert(dst); + if(!dst) + return; + + pipe_copy_rect(dst, &ps->block, ps->stride, x, y, w, h, src, src_stride, 0, 0); + + pipe_surface_unmap(ps); +} + + + + +/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */ +#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) + +#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \ + us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) + + + +/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ + +static void +a8r8g8b8_get_tile_rgba(const unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const unsigned pixel = *src++; + pRow[0] = ubyte_to_float((pixel >> 16) & 0xff); + pRow[1] = ubyte_to_float((pixel >> 8) & 0xff); + pRow[2] = ubyte_to_float((pixel >> 0) & 0xff); + pRow[3] = ubyte_to_float((pixel >> 24) & 0xff); + } + p += dst_stride; + } +} + + +static void +a8r8g8b8_put_tile_rgba(unsigned *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b, a; + r = float_to_ubyte(pRow[0]); + g = float_to_ubyte(pRow[1]); + b = float_to_ubyte(pRow[2]); + a = float_to_ubyte(pRow[3]); + *dst++ = (a << 24) | (r << 16) | (g << 8) | b; + } + p += src_stride; + } +} + + +/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ + +static void +x8r8g8b8_get_tile_rgba(const unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const unsigned pixel = *src++; + pRow[0] = ubyte_to_float((pixel >> 16) & 0xff); + pRow[1] = ubyte_to_float((pixel >> 8) & 0xff); + pRow[2] = ubyte_to_float((pixel >> 0) & 0xff); + pRow[3] = ubyte_to_float(0xff); + } + p += dst_stride; + } +} + + +static void +x8r8g8b8_put_tile_rgba(unsigned *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b; + r = float_to_ubyte(pRow[0]); + g = float_to_ubyte(pRow[1]); + b = float_to_ubyte(pRow[2]); + *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b; + } + p += src_stride; + } +} + + +/*** PIPE_FORMAT_B8G8R8A8_UNORM ***/ + +static void +b8g8r8a8_get_tile_rgba(const unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const unsigned pixel = *src++; + pRow[0] = ubyte_to_float((pixel >> 8) & 0xff); + pRow[1] = ubyte_to_float((pixel >> 16) & 0xff); + pRow[2] = ubyte_to_float((pixel >> 24) & 0xff); + pRow[3] = ubyte_to_float((pixel >> 0) & 0xff); + } + p += dst_stride; + } +} + + +static void +b8g8r8a8_put_tile_rgba(unsigned *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b, a; + r = float_to_ubyte(pRow[0]); + g = float_to_ubyte(pRow[1]); + b = float_to_ubyte(pRow[2]); + a = float_to_ubyte(pRow[3]); + *dst++ = (b << 24) | (g << 16) | (r << 8) | a; + } + p += src_stride; + } +} + + +/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/ + +static void +a1r5g5b5_get_tile_rgba(const ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const ushort pixel = *src++; + pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f); + pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f); + pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); + pRow[3] = ((pixel >> 15) ) * 1.0f; + } + p += dst_stride; + } +} + + +static void +a1r5g5b5_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b, a; + r = float_to_ubyte(pRow[0]); + g = float_to_ubyte(pRow[1]); + b = float_to_ubyte(pRow[2]); + a = float_to_ubyte(pRow[3]); + r = r >> 3; /* 5 bits */ + g = g >> 3; /* 5 bits */ + b = b >> 3; /* 5 bits */ + a = a >> 7; /* 1 bit */ + *dst++ = (a << 15) | (r << 10) | (g << 5) | b; + } + p += src_stride; + } +} + + +/*** PIPE_FORMAT_A4R4G4B4_UNORM ***/ + +static void +a4r4g4b4_get_tile_rgba(const ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const ushort pixel = *src++; + pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f); + pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f); + pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f); + pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f); + } + p += dst_stride; + } +} + + +static void +a4r4g4b4_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, g, b, a; + r = float_to_ubyte(pRow[0]); + g = float_to_ubyte(pRow[1]); + b = float_to_ubyte(pRow[2]); + a = float_to_ubyte(pRow[3]); + r >>= 4; + g >>= 4; + b >>= 4; + a >>= 4; + *dst++ = (a << 12) | (r << 16) | (g << 4) | b; + } + p += src_stride; + } +} + + +/*** PIPE_FORMAT_R5G6B5_UNORM ***/ + +static void +r5g6b5_get_tile_rgba(const ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + const ushort pixel = *src++; + pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f); + pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f); + pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); + pRow[3] = 1.0f; + } + p += dst_stride; + } +} + + +static void +r5g6b5_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0); + uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0); + uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0); + *dst++ = (r << 11) | (g << 5) | (b); + } + p += src_stride; + } +} + + + +/*** PIPE_FORMAT_Z16_UNORM ***/ + +/** + * Return each Z value as four floats in [0,1]. + */ +static void +z16_get_tile_rgba(const ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const float scale = 1.0f / 65535.0f; + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = *src++ * scale; + } + p += dst_stride; + } +} + + + + +/*** PIPE_FORMAT_L8_UNORM ***/ + +static void +l8_get_tile_rgba(const ubyte *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = ubyte_to_float(*src); + pRow[3] = 1.0; + } + p += dst_stride; + } +} + + +static void +l8_put_tile_rgba(ubyte *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r; + r = float_to_ubyte(pRow[0]); + *dst++ = r; + } + p += src_stride; + } +} + + + +/*** PIPE_FORMAT_A8_UNORM ***/ + +static void +a8_get_tile_rgba(const ubyte *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = 0.0; + pRow[3] = ubyte_to_float(*src); + } + p += dst_stride; + } +} + + +static void +a8_put_tile_rgba(ubyte *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned a; + a = float_to_ubyte(pRow[3]); + *dst++ = a; + } + p += src_stride; + } +} + + + +/*** PIPE_FORMAT_R16_SNORM ***/ + +static void +r16_get_tile_rgba(const short *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src++, pRow += 4) { + pRow[0] = SHORT_TO_FLOAT(src[0]); + pRow[1] = + pRow[2] = 0.0; + pRow[3] = 1.0; + } + p += dst_stride; + } +} + + +static void +r16_put_tile_rgba(short *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, dst++, pRow += 4) { + UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); + } + p += src_stride; + } +} + + +/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ + +static void +r16g16b16a16_get_tile_rgba(const short *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src += 4, pRow += 4) { + pRow[0] = SHORT_TO_FLOAT(src[0]); + pRow[1] = SHORT_TO_FLOAT(src[1]); + pRow[2] = SHORT_TO_FLOAT(src[2]); + pRow[3] = SHORT_TO_FLOAT(src[3]); + } + p += dst_stride; + } +} + + +static void +r16g16b16a16_put_tile_rgba(short *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, dst += 4, pRow += 4) { + UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); + UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]); + UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]); + UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]); + } + p += src_stride; + } +} + + + +/*** PIPE_FORMAT_I8_UNORM ***/ + +static void +i8_get_tile_rgba(const ubyte *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, src++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = ubyte_to_float(*src); + } + p += dst_stride; + } +} + + +static void +i8_put_tile_rgba(ubyte *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r; + r = float_to_ubyte(pRow[0]); + *dst++ = r; + } + p += src_stride; + } +} + + +/*** PIPE_FORMAT_A8L8_UNORM ***/ + +static void +a8l8_get_tile_rgba(const ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + ushort p = *src++; + pRow[0] = + pRow[1] = + pRow[2] = ubyte_to_float(p & 0xff); + pRow[3] = ubyte_to_float(p >> 8); + } + p += dst_stride; + } +} + + +static void +a8l8_put_tile_rgba(ushort *dst, + unsigned w, unsigned h, + const float *p, + unsigned src_stride) +{ + unsigned i, j; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + unsigned r, a; + r = float_to_ubyte(pRow[0]); + a = float_to_ubyte(pRow[3]); + *dst++ = (a << 8) | r; + } + p += src_stride; + } +} + + + + +/*** PIPE_FORMAT_Z32_UNORM ***/ + +/** + * Return each Z value as four floats in [0,1]. + */ +static void +z32_get_tile_rgba(const unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const double scale = 1.0 / (double) 0xffffffff; + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = (float) (*src++ * scale); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_S8Z24_UNORM ***/ + +/** + * Return Z component as four float in [0,1]. Stencil part ignored. + */ +static void +s8z24_get_tile_rgba(const unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const double scale = 1.0 / ((1 << 24) - 1); + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = (float) (scale * (*src++ & 0xffffff)); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_Z24S8_UNORM ***/ + +/** + * Return Z component as four float in [0,1]. Stencil part ignored. + */ +static void +z24s8_get_tile_rgba(const unsigned *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride) +{ + const double scale = 1.0 / ((1 << 24) - 1); + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++, pRow += 4) { + pRow[0] = + pRow[1] = + pRow[2] = + pRow[3] = (float) (scale * (*src++ >> 8)); + } + p += dst_stride; + } +} + + +/*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/ + +/** + * Convert YCbCr (or YCrCb) to RGBA. + */ +static void +ycbcr_get_tile_rgba(const ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride, + boolean rev) +{ + const float scale = 1.0f / 255.0f; + unsigned i, j; + + for (i = 0; i < h; i++) { + float *pRow = p; + /* do two texels at a time */ + for (j = 0; j < (w & ~1); j += 2, src += 2) { + const ushort t0 = src[0]; + const ushort t1 = src[1]; + const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ + const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */ + ubyte cb, cr; + float r, g, b; + + if (rev) { + cb = t1 & 0xff; /* chroma U */ + cr = t0 & 0xff; /* chroma V */ + } + else { + cb = t0 & 0xff; /* chroma U */ + cr = t1 & 0xff; /* chroma V */ + } + + /* even pixel: y0,cr,cb */ + r = 1.164f * (y0-16) + 1.596f * (cr-128); + g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128); + b = 1.164f * (y0-16) + 2.018f * (cb-128); + pRow[0] = r * scale; + pRow[1] = g * scale; + pRow[2] = b * scale; + pRow[3] = 1.0f; + pRow += 4; + + /* odd pixel: use y1,cr,cb */ + r = 1.164f * (y1-16) + 1.596f * (cr-128); + g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128); + b = 1.164f * (y1-16) + 2.018f * (cb-128); + pRow[0] = r * scale; + pRow[1] = g * scale; + pRow[2] = b * scale; + pRow[3] = 1.0f; + pRow += 4; + + } + /* do the last texel */ + if (w & 1) { + const ushort t0 = src[0]; + const ushort t1 = src[1]; + const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ + ubyte cb, cr; + float r, g, b; + + if (rev) { + cb = t1 & 0xff; /* chroma U */ + cr = t0 & 0xff; /* chroma V */ + } + else { + cb = t0 & 0xff; /* chroma U */ + cr = t1 & 0xff; /* chroma V */ + } + + /* even pixel: y0,cr,cb */ + r = 1.164f * (y0-16) + 1.596f * (cr-128); + g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128); + b = 1.164f * (y0-16) + 2.018f * (cb-128); + pRow[0] = r * scale; + pRow[1] = g * scale; + pRow[2] = b * scale; + pRow[3] = 1.0f; + pRow += 4; + } + p += dst_stride; + } +} + + +void +pipe_tile_raw_to_rgba(enum pipe_format format, + void *src, + uint w, uint h, + float *dst, unsigned dst_stride) +{ + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_X8R8G8B8_UNORM: + x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_A1R5G5B5_UNORM: + a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_A4R4G4B4_UNORM: + a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_R5G6B5_UNORM: + r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_L8_UNORM: + l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_A8_UNORM: + a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_I8_UNORM: + i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_A8L8_UNORM: + a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_R16_SNORM: + r16_get_tile_rgba((short *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_R16G16B16A16_SNORM: + r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_Z16_UNORM: + z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_Z32_UNORM: + z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_Z24S8_UNORM: + z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); + break; + case PIPE_FORMAT_YCBCR: + ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE); + break; + case PIPE_FORMAT_YCBCR_REV: + ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE); + break; + default: + assert(0); + } +} + + +void +pipe_get_tile_rgba(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + float *p) +{ + unsigned dst_stride = w * 4; + void *packed; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size); + + if (!packed) + return; + + if(ps->format == PIPE_FORMAT_YCBCR || ps->format == PIPE_FORMAT_YCBCR_REV) + assert((x & 1) == 0); + + pipe_get_tile_raw(ps, x, y, w, h, packed, 0); + + pipe_tile_raw_to_rgba(ps->format, packed, w, h, p, dst_stride); + + FREE(packed); +} + + +void +pipe_put_tile_rgba(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const float *p) +{ + unsigned src_stride = w * 4; + void *packed; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size); + + if (!packed) + return; + + switch (ps->format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_X8R8G8B8_UNORM: + x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_A1R5G5B5_UNORM: + a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_R5G6B5_UNORM: + r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + assert(0); + break; + case PIPE_FORMAT_A4R4G4B4_UNORM: + a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_L8_UNORM: + l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_A8_UNORM: + a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_I8_UNORM: + i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_A8L8_UNORM: + a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_R16_SNORM: + r16_put_tile_rgba((short *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_R16G16B16A16_SNORM: + r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride); + break; + case PIPE_FORMAT_Z16_UNORM: + /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_Z32_UNORM: + /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ + break; + case PIPE_FORMAT_Z24S8_UNORM: + /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ + break; + default: + assert(0); + } + + pipe_put_tile_raw(ps, x, y, w, h, packed, 0); + + FREE(packed); +} + + +/** + * Get a block of Z values, converted to 32-bit range. + */ +void +pipe_get_tile_z(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + uint *z) +{ + const uint dstStride = w; + ubyte *map; + uint *pDest = z; + uint i, j; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ); + if (!map) { + assert(0); + return; + } + + switch (ps->format) { + case PIPE_FORMAT_Z32_UNORM: + { + const uint *pSrc + = (const uint *)(map + y * ps->stride + x*4); + for (i = 0; i < h; i++) { + memcpy(pDest, pSrc, 4 * w); + pDest += dstStride; + pSrc += ps->stride/4; + } + } + break; + case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + { + const uint *pSrc + = (const uint *)(map + y * ps->stride + x*4); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + /* convert 24-bit Z to 32-bit Z */ + pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff); + } + pDest += dstStride; + pSrc += ps->stride/4; + } + } + break; + case PIPE_FORMAT_Z16_UNORM: + { + const ushort *pSrc + = (const ushort *)(map + y * ps->stride + x*2); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + /* convert 16-bit Z to 32-bit Z */ + pDest[j] = (pSrc[j] << 16) | pSrc[j]; + } + pDest += dstStride; + pSrc += ps->stride/2; + } + } + break; + default: + assert(0); + } + + pipe_surface_unmap(ps); +} + + +void +pipe_put_tile_z(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const uint *zSrc) +{ + const uint srcStride = w; + const uint *pSrc = zSrc; + ubyte *map; + uint i, j; + + if (pipe_clip_tile(x, y, &w, &h, ps)) + return; + + map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE); + if (!map) { + assert(0); + return; + } + + switch (ps->format) { + case PIPE_FORMAT_Z32_UNORM: + { + uint *pDest = (uint *) (map + y * ps->stride + x*4); + for (i = 0; i < h; i++) { + memcpy(pDest, pSrc, 4 * w); + pDest += ps->stride/4; + pSrc += srcStride; + } + } + break; + case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + { + uint *pDest = (uint *) (map + y * ps->stride + x*4); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + /* convert 32-bit Z to 24-bit Z (0 stencil) */ + pDest[j] = pSrc[j] >> 8; + } + pDest += ps->stride/4; + pSrc += srcStride; + } + } + break; + case PIPE_FORMAT_Z16_UNORM: + { + ushort *pDest = (ushort *) (map + y * ps->stride + x*2); + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + /* convert 32-bit Z to 16-bit Z */ + pDest[j] = pSrc[j] >> 16; + } + pDest += ps->stride/2; + pSrc += srcStride; + } + } + break; + default: + assert(0); + } + + pipe_surface_unmap(ps); +} + + diff --git a/src/gallium/auxiliary/util/u_tile.h b/src/gallium/auxiliary/util/u_tile.h new file mode 100644 index 0000000000..a8ac805308 --- /dev/null +++ b/src/gallium/auxiliary/util/u_tile.h @@ -0,0 +1,101 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef P_TILE_H +#define P_TILE_H + +#include "pipe/p_compiler.h" + +struct pipe_surface; + + +/** + * Clip tile against surface dims. + * \return TRUE if tile is totally clipped, FALSE otherwise + */ +static INLINE boolean +pipe_clip_tile(uint x, uint y, uint *w, uint *h, const struct pipe_surface *ps) +{ + if (x >= ps->width) + return TRUE; + if (y >= ps->height) + return TRUE; + if (x + *w > ps->width) + *w = ps->width - x; + if (y + *h > ps->height) + *h = ps->height - y; + return FALSE; +} + +#ifdef __cplusplus +extern "C" { +#endif + +void +pipe_get_tile_raw(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + void *p, int dst_stride); + +void +pipe_put_tile_raw(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const void *p, int src_stride); + + +void +pipe_get_tile_rgba(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + float *p); + +void +pipe_put_tile_rgba(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const float *p); + + +void +pipe_get_tile_z(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + uint *z); + +void +pipe_put_tile_z(struct pipe_surface *ps, + uint x, uint y, uint w, uint h, + const uint *z); + +void +pipe_tile_raw_to_rgba(enum pipe_format format, + void *src, + uint w, uint h, + float *dst, unsigned dst_stride); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index f430e88b9c..6bace0bb11 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -34,7 +34,6 @@ #define CELL_COMMON_H #include "pipe/p_compiler.h" -#include "pipe/p_util.h" #include "pipe/p_format.h" #include "pipe/p_state.h" diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c index 3ffe09add6..cee0917b63 100644 --- a/src/gallium/drivers/cell/ppu/cell_clear.c +++ b/src/gallium/drivers/cell/ppu/cell_clear.c @@ -34,7 +34,7 @@ #include #include #include "pipe/p_inlines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "cell/common.h" #include "cell_clear.h" #include "cell_context.h" diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index 12eb5aa254..5af95a3c10 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -35,7 +35,7 @@ #include "pipe/p_defines.h" #include "pipe/p_format.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_winsys.h" #include "pipe/p_screen.h" diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 67b87f16d7..971d65d09e 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -30,7 +30,7 @@ * Brian Paul */ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "draw/draw_context.h" #include "cell_context.h" diff --git a/src/gallium/drivers/cell/ppu/cell_render.c b/src/gallium/drivers/cell/ppu/cell_render.c index b663b37622..dd25ae880e 100644 --- a/src/gallium/drivers/cell/ppu/cell_render.c +++ b/src/gallium/drivers/cell/ppu/cell_render.c @@ -33,7 +33,7 @@ #include "cell_context.h" #include "cell_render.h" #include "cell_spu.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "draw/draw_private.h" diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 2bf441a0c5..139b3719b6 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_winsys.h" #include "pipe/p_defines.h" #include "pipe/p_screen.h" diff --git a/src/gallium/drivers/cell/ppu/cell_state_derived.c b/src/gallium/drivers/cell/ppu/cell_state_derived.c index 5480534ad9..8ab938a02a 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_derived.c +++ b/src/gallium/drivers/cell/ppu/cell_state_derived.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" #include "draw/draw_vertex.h" diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 9cae67f091..3646a0ee4f 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "cell_context.h" #include "cell_state.h" #include "cell_state_emit.h" diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c index f5707f2bb8..cd96b317fa 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -26,7 +26,7 @@ **************************************************************************/ #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" #include "draw/draw_context.h" diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c index 01ffa31c2c..2d31ad89a6 100644 --- a/src/gallium/drivers/cell/ppu/cell_surface.c +++ b/src/gallium/drivers/cell/ppu/cell_surface.c @@ -26,7 +26,7 @@ **************************************************************************/ #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" #include "util/p_tile.h" diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index 533b64227d..1add81373d 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -33,7 +33,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_winsys.h" #include "cell_context.h" diff --git a/src/gallium/drivers/cell/ppu/cell_winsys.c b/src/gallium/drivers/cell/ppu/cell_winsys.c index ebabce3c8f..d570bbd2f9 100644 --- a/src/gallium/drivers/cell/ppu/cell_winsys.c +++ b/src/gallium/drivers/cell/ppu/cell_winsys.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "cell_winsys.h" diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 42e5022f30..89c61136a4 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -63,7 +63,6 @@ #include "pipe/p_compiler.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index ab4ff8160a..8944ef171e 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -32,7 +32,6 @@ #include #include "pipe/p_compiler.h" #include "pipe/p_format.h" -#include "pipe/p_util.h" #include "spu_colorpack.h" #include "spu_main.h" #include "spu_texture.h" diff --git a/src/gallium/drivers/cell/spu/spu_util.c b/src/gallium/drivers/cell/spu/spu_util.c index 74ab2bbd1f..dbcf4b0eb9 100644 --- a/src/gallium/drivers/cell/spu/spu_util.c +++ b/src/gallium/drivers/cell/spu/spu_util.c @@ -1,4 +1,3 @@ -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" //#include "tgsi_build.h" diff --git a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c index 219fd90cc0..26f2363749 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c @@ -32,7 +32,6 @@ * Ian Romanick */ -#include "pipe/p_util.h" #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" #include "spu_exec.h" diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c index 3119a78c06..a1e81975e6 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c @@ -34,7 +34,6 @@ #include -#include "pipe/p_util.h" #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" #include "spu_vertex_shader.h" diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index 014a3e31d5..10c4ffc209 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -28,7 +28,7 @@ #include "pipe/p_defines.h" #include "pipe/p_winsys.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_context.h" #include "fo_context.h" diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index e2bf5ab678..c6776716a2 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -35,7 +35,7 @@ #include "draw/draw_context.h" #include "pipe/p_defines.h" #include "pipe/p_winsys.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_screen.h" diff --git a/src/gallium/drivers/i915simple/i915_debug_fp.c b/src/gallium/drivers/i915simple/i915_debug_fp.c index c024a051a5..48be3e1472 100644 --- a/src/gallium/drivers/i915simple/i915_debug_fp.c +++ b/src/gallium/drivers/i915simple/i915_debug_fp.c @@ -29,7 +29,7 @@ #include "i915_reg.h" #include "i915_debug.h" #include "pipe/p_winsys.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" static void diff --git a/src/gallium/drivers/i915simple/i915_fpc.h b/src/gallium/drivers/i915simple/i915_fpc.h index 80a9576304..2f0f99d046 100644 --- a/src/gallium/drivers/i915simple/i915_fpc.h +++ b/src/gallium/drivers/i915simple/i915_fpc.h @@ -29,7 +29,6 @@ #ifndef I915_FPC_H #define I915_FPC_H -#include "pipe/p_util.h" #include "i915_context.h" #include "i915_reg.h" diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c index 64432982c4..34b4a846c1 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_translate.c +++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c @@ -33,6 +33,8 @@ #include "i915_fpc.h" #include "pipe/p_shader_tokens.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "util/u_string.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_dump.h" diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c index 9ffa460138..d194c2fb15 100644 --- a/src/gallium/drivers/i915simple/i915_prim_emit.c +++ b/src/gallium/drivers/i915simple/i915_prim_emit.c @@ -27,7 +27,9 @@ #include "draw/draw_pipe.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "util/u_pack_color.h" #include "i915_context.h" #include "i915_winsys.h" diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c index aef3682bbf..e4ece55098 100644 --- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c @@ -41,9 +41,10 @@ #include "draw/draw_context.h" #include "draw/draw_vbuf.h" #include "pipe/p_debug.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "i915_context.h" #include "i915_reg.h" diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 0afa17bed8..e9e40c3f0b 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_winsys.h" #include "util/u_string.h" diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index e8521b385e..d2487d8277 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -31,8 +31,9 @@ #include "draw/draw_context.h" #include "pipe/p_winsys.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "tgsi/tgsi_parse.h" #include "i915_context.h" diff --git a/src/gallium/drivers/i915simple/i915_state_derived.c b/src/gallium/drivers/i915simple/i915_state_derived.c index 4daccec6e0..488615067c 100644 --- a/src/gallium/drivers/i915simple/i915_state_derived.c +++ b/src/gallium/drivers/i915simple/i915_state_derived.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" #include "draw/draw_vertex.h" diff --git a/src/gallium/drivers/i915simple/i915_state_dynamic.c b/src/gallium/drivers/i915simple/i915_state_dynamic.c index 8cfbdddd19..86126a5a15 100644 --- a/src/gallium/drivers/i915simple/i915_state_dynamic.c +++ b/src/gallium/drivers/i915simple/i915_state_dynamic.c @@ -30,7 +30,9 @@ #include "i915_context.h" #include "i915_reg.h" #include "i915_state.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "util/u_pack_color.h" #define FILE_DEBUG_FLAG DEBUG_STATE diff --git a/src/gallium/drivers/i915simple/i915_state_immediate.c b/src/gallium/drivers/i915simple/i915_state_immediate.c index 2501f2d7cb..8c16bb4e27 100644 --- a/src/gallium/drivers/i915simple/i915_state_immediate.c +++ b/src/gallium/drivers/i915simple/i915_state_immediate.c @@ -33,7 +33,7 @@ #include "i915_context.h" #include "i915_state.h" #include "i915_reg.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" /* All state expressable with the LOAD_STATE_IMMEDIATE_1 packet. diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c index 7868f21ca6..c09c10601b 100644 --- a/src/gallium/drivers/i915simple/i915_state_sampler.c +++ b/src/gallium/drivers/i915simple/i915_state_sampler.c @@ -27,7 +27,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "i915_state_inlines.h" #include "i915_context.h" diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index 17b5125e56..62f1926644 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -30,10 +30,9 @@ #include "i915_state.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "util/p_tile.h" +#include "util/u_tile.h" #include "util/u_rect.h" diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index ca0fb8761b..32344da4d5 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -34,8 +34,9 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/p_util.h" #include "pipe/p_winsys.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "i915_context.h" #include "i915_texture.h" diff --git a/src/gallium/drivers/i965simple/brw_cc.c b/src/gallium/drivers/i965simple/brw_cc.c index 337e4f95f6..79d4150383 100644 --- a/src/gallium/drivers/i965simple/brw_cc.c +++ b/src/gallium/drivers/i965simple/brw_cc.c @@ -29,7 +29,8 @@ * Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "brw_context.h" #include "brw_state.h" @@ -232,8 +233,7 @@ static void upload_cc_unit( struct brw_context *brw ) cc.cc3.alpha_test_func = brw_translate_compare_func(brw->attribs.DepthStencil->alpha.func); - UNCLAMPED_FLOAT_TO_UBYTE(cc.cc7.alpha_ref.ub[0], - brw->attribs.DepthStencil->alpha.ref); + cc.cc7.alpha_ref.ub[0] = float_to_ubyte(brw->attribs.DepthStencil->alpha.ref); cc.cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8; } diff --git a/src/gallium/drivers/i965simple/brw_clip_state.c b/src/gallium/drivers/i965simple/brw_clip_state.c index ea5c05a279..8e78dd51be 100644 --- a/src/gallium/drivers/i965simple/brw_clip_state.c +++ b/src/gallium/drivers/i965simple/brw_clip_state.c @@ -32,7 +32,8 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" static void upload_clip_unit( struct brw_context *brw ) diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index 8326f7b9c4..96920df008 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -39,7 +39,7 @@ #include "pipe/p_winsys.h" #include "pipe/p_context.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_screen.h" diff --git a/src/gallium/drivers/i965simple/brw_curbe.c b/src/gallium/drivers/i965simple/brw_curbe.c index 52bbd525c1..824ee7fd6d 100644 --- a/src/gallium/drivers/i965simple/brw_curbe.c +++ b/src/gallium/drivers/i965simple/brw_curbe.c @@ -39,7 +39,8 @@ #include "brw_wm.h" #include "pipe/p_state.h" #include "pipe/p_winsys.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #define FILE_DEBUG_FLAG DEBUG_FALLBACKS diff --git a/src/gallium/drivers/i965simple/brw_draw_upload.c b/src/gallium/drivers/i965simple/brw_draw_upload.c index 9c0c78c236..7c20ea52af 100644 --- a/src/gallium/drivers/i965simple/brw_draw_upload.c +++ b/src/gallium/drivers/i965simple/brw_draw_upload.c @@ -33,6 +33,7 @@ #include "brw_context.h" #include "brw_state.h" + struct brw_array_state { union header_union header; diff --git a/src/gallium/drivers/i965simple/brw_gs_state.c b/src/gallium/drivers/i965simple/brw_gs_state.c index 3932e9e939..5b8016b2e9 100644 --- a/src/gallium/drivers/i965simple/brw_gs_state.c +++ b/src/gallium/drivers/i965simple/brw_gs_state.c @@ -34,7 +34,8 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c index fadfbf94ab..ab7cd624b2 100644 --- a/src/gallium/drivers/i965simple/brw_screen.c +++ b/src/gallium/drivers/i965simple/brw_screen.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_winsys.h" #include "util/u_string.h" diff --git a/src/gallium/drivers/i965simple/brw_sf_state.c b/src/gallium/drivers/i965simple/brw_sf_state.c index 9acd3ea61b..2a5de61c21 100644 --- a/src/gallium/drivers/i965simple/brw_sf_state.c +++ b/src/gallium/drivers/i965simple/brw_sf_state.c @@ -30,11 +30,12 @@ */ - #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" + static void upload_sf_vp(struct brw_context *brw) { diff --git a/src/gallium/drivers/i965simple/brw_shader_info.c b/src/gallium/drivers/i965simple/brw_shader_info.c index 30f37a99d4..86d877d7ef 100644 --- a/src/gallium/drivers/i965simple/brw_shader_info.c +++ b/src/gallium/drivers/i965simple/brw_shader_info.c @@ -1,7 +1,7 @@ #include "brw_context.h" #include "brw_state.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index 27ca32843d..af46cb546f 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -31,7 +31,7 @@ #include "pipe/p_winsys.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_dump.h" diff --git a/src/gallium/drivers/i965simple/brw_state_batch.c b/src/gallium/drivers/i965simple/brw_state_batch.c index 35db76b594..43a1c89fc4 100644 --- a/src/gallium/drivers/i965simple/brw_state_batch.c +++ b/src/gallium/drivers/i965simple/brw_state_batch.c @@ -32,7 +32,7 @@ #include "brw_state.h" #include "brw_winsys.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" /* A facility similar to the data caching code above, which aims to * prevent identical commands being issued repeatedly. diff --git a/src/gallium/drivers/i965simple/brw_state_cache.c b/src/gallium/drivers/i965simple/brw_state_cache.c index b3a5124461..094248fa69 100644 --- a/src/gallium/drivers/i965simple/brw_state_cache.c +++ b/src/gallium/drivers/i965simple/brw_state_cache.c @@ -38,7 +38,7 @@ #include "brw_sf.h" #include "brw_gs.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" diff --git a/src/gallium/drivers/i965simple/brw_state_pool.c b/src/gallium/drivers/i965simple/brw_state_pool.c index f3174bfe0a..78d4c0e411 100644 --- a/src/gallium/drivers/i965simple/brw_state_pool.c +++ b/src/gallium/drivers/i965simple/brw_state_pool.c @@ -43,7 +43,8 @@ */ #include "pipe/p_winsys.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "brw_context.h" #include "brw_state.h" diff --git a/src/gallium/drivers/i965simple/brw_state_upload.c b/src/gallium/drivers/i965simple/brw_state_upload.c index e727601e1e..bac9161b5f 100644 --- a/src/gallium/drivers/i965simple/brw_state_upload.c +++ b/src/gallium/drivers/i965simple/brw_state_upload.c @@ -33,7 +33,7 @@ #include "brw_context.h" #include "brw_state.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" /* This is used to initialize brw->state.atoms[]. We could use this * list directly except for a single atom, brw_constant_buffer, which diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index 69da252285..b89756c47b 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -29,10 +29,9 @@ #include "brw_context.h" #include "brw_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "util/p_tile.h" +#include "util/u_tile.h" #include "util/u_rect.h" diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 9b6cf81723..05eda9d1f2 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -33,16 +33,16 @@ /* Code to layout images in a mipmap tree for i965. */ -#include "brw_tex_layout.h" - #include "pipe/p_state.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" - +#include "util/u_math.h" +#include "util/u_memory.h" #include "brw_context.h" +#include "brw_tex_layout.h" + #define FILE_DEBUG_FLAG DEBUG_TEXTURE diff --git a/src/gallium/drivers/i965simple/brw_vs_state.c b/src/gallium/drivers/i965simple/brw_vs_state.c index c73469929c..1eaff87892 100644 --- a/src/gallium/drivers/i965simple/brw_vs_state.c +++ b/src/gallium/drivers/i965simple/brw_vs_state.c @@ -34,7 +34,8 @@ #include "brw_state.h" #include "brw_defines.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" static void upload_vs_unit( struct brw_context *brw ) { diff --git a/src/gallium/drivers/i965simple/brw_wm.c b/src/gallium/drivers/i965simple/brw_wm.c index 7fc5f59a98..8de565b96c 100644 --- a/src/gallium/drivers/i965simple/brw_wm.c +++ b/src/gallium/drivers/i965simple/brw_wm.c @@ -35,7 +35,7 @@ #include "brw_wm.h" #include "brw_eu.h" #include "brw_state.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" diff --git a/src/gallium/drivers/i965simple/brw_wm_decl.c b/src/gallium/drivers/i965simple/brw_wm_decl.c index e6f1a44817..d50e66f613 100644 --- a/src/gallium/drivers/i965simple/brw_wm_decl.c +++ b/src/gallium/drivers/i965simple/brw_wm_decl.c @@ -2,7 +2,8 @@ #include "brw_context.h" #include "brw_eu.h" #include "brw_wm.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/i965simple/brw_wm_glsl.c b/src/gallium/drivers/i965simple/brw_wm_glsl.c index 6a4a5aef09..ab6410aa60 100644 --- a/src/gallium/drivers/i965simple/brw_wm_glsl.c +++ b/src/gallium/drivers/i965simple/brw_wm_glsl.c @@ -2,7 +2,8 @@ #include "brw_context.h" #include "brw_eu.h" #include "brw_wm.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/i965simple/brw_wm_sampler_state.c b/src/gallium/drivers/i965simple/brw_wm_sampler_state.c index b9eaee56ee..52b2909a65 100644 --- a/src/gallium/drivers/i965simple/brw_wm_sampler_state.c +++ b/src/gallium/drivers/i965simple/brw_wm_sampler_state.c @@ -34,7 +34,8 @@ #include "brw_state.h" #include "brw_defines.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #define COMPAREFUNC_ALWAYS 0 diff --git a/src/gallium/drivers/i965simple/brw_wm_state.c b/src/gallium/drivers/i965simple/brw_wm_state.c index f3aa36b07f..37a9bf919c 100644 --- a/src/gallium/drivers/i965simple/brw_wm_state.c +++ b/src/gallium/drivers/i965simple/brw_wm_state.c @@ -34,7 +34,8 @@ #include "brw_state.h" #include "brw_defines.h" #include "brw_wm.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" /*********************************************************************** * WM unit - fragment programs and rasterization diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 9b1313bc83..dda90f760a 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -32,8 +32,8 @@ #include "draw/draw_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/p_util.h" #include "util/u_math.h" +#include "util/u_memory.h" #include "sp_clear.h" #include "sp_context.h" #include "sp_flush.h" diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index cc171bbc39..d0456731be 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -34,7 +34,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_parse.h" diff --git a/src/gallium/drivers/softpipe/sp_fs_llvm.c b/src/gallium/drivers/softpipe/sp_fs_llvm.c index 20226da78c..34adac5226 100644 --- a/src/gallium/drivers/softpipe/sp_fs_llvm.c +++ b/src/gallium/drivers/softpipe/sp_fs_llvm.c @@ -36,7 +36,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "tgsi/tgsi_sse2.h" diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 8b7da7c747..35653a8e48 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -34,7 +34,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_sse2.h" diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 941ab62e00..038ff04d4f 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -41,7 +41,7 @@ #include "sp_prim_setup.h" #include "draw/draw_pipe.h" #include "draw/draw_vertex.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" /** * Triangle setup info (derived from draw_stage). diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index e9fae951e0..425e13cd28 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -43,6 +43,7 @@ #include "sp_setup.h" #include "draw/draw_context.h" #include "draw/draw_vbuf.h" +#include "util/u_memory.h" #define SP_MAX_VBUF_INDEXES 1024 diff --git a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c index 7a42b08ef5..7d3580fb4f 100644 --- a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c @@ -7,7 +7,7 @@ #include "sp_headers.h" #include "sp_quad.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" static void diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c index 74c6bff84a..a834accb86 100644 --- a/src/gallium/drivers/softpipe/sp_quad_blend.c +++ b/src/gallium/drivers/softpipe/sp_quad_blend.c @@ -31,7 +31,8 @@ */ #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "sp_context.h" #include "sp_headers.h" #include "sp_surface.h" @@ -128,15 +129,15 @@ logicop_quad(struct quad_stage *qs, struct quad_header *quad) /* convert to ubyte */ for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */ - UNCLAMPED_FLOAT_TO_UBYTE(dst[j][0], dest[j][0]); /* P0 */ - UNCLAMPED_FLOAT_TO_UBYTE(dst[j][1], dest[j][1]); /* P1 */ - UNCLAMPED_FLOAT_TO_UBYTE(dst[j][2], dest[j][2]); /* P2 */ - UNCLAMPED_FLOAT_TO_UBYTE(dst[j][3], dest[j][3]); /* P3 */ - - UNCLAMPED_FLOAT_TO_UBYTE(src[j][0], quadColor[j][0]); /* P0 */ - UNCLAMPED_FLOAT_TO_UBYTE(src[j][1], quadColor[j][1]); /* P1 */ - UNCLAMPED_FLOAT_TO_UBYTE(src[j][2], quadColor[j][2]); /* P2 */ - UNCLAMPED_FLOAT_TO_UBYTE(src[j][3], quadColor[j][3]); /* P3 */ + dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */ + dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */ + dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */ + dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */ + + src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */ + src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */ + src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */ + src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */ } switch (softpipe->blend->logicop_func) { @@ -209,10 +210,10 @@ logicop_quad(struct quad_stage *qs, struct quad_header *quad) } for (j = 0; j < 4; j++) { - quadColor[j][0] = UBYTE_TO_FLOAT(res[j][0]); - quadColor[j][1] = UBYTE_TO_FLOAT(res[j][1]); - quadColor[j][2] = UBYTE_TO_FLOAT(res[j][2]); - quadColor[j][3] = UBYTE_TO_FLOAT(res[j][3]); + quadColor[j][0] = ubyte_to_float(res[j][0]); + quadColor[j][1] = ubyte_to_float(res[j][1]); + quadColor[j][2] = ubyte_to_float(res[j][2]); + quadColor[j][3] = ubyte_to_float(res[j][3]); } } diff --git a/src/gallium/drivers/softpipe/sp_quad_bufloop.c b/src/gallium/drivers/softpipe/sp_quad_bufloop.c index b3db428ef1..92e9af09c1 100644 --- a/src/gallium/drivers/softpipe/sp_quad_bufloop.c +++ b/src/gallium/drivers/softpipe/sp_quad_bufloop.c @@ -1,5 +1,5 @@ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "sp_context.h" #include "sp_headers.h" #include "sp_surface.h" diff --git a/src/gallium/drivers/softpipe/sp_quad_colormask.c b/src/gallium/drivers/softpipe/sp_quad_colormask.c index 7fe080990b..f72f31db97 100644 --- a/src/gallium/drivers/softpipe/sp_quad_colormask.c +++ b/src/gallium/drivers/softpipe/sp_quad_colormask.c @@ -31,7 +31,8 @@ */ #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "sp_context.h" #include "sp_headers.h" #include "sp_surface.h" diff --git a/src/gallium/drivers/softpipe/sp_quad_coverage.c b/src/gallium/drivers/softpipe/sp_quad_coverage.c index dd5ebb2296..ad907ec25f 100644 --- a/src/gallium/drivers/softpipe/sp_quad_coverage.c +++ b/src/gallium/drivers/softpipe/sp_quad_coverage.c @@ -33,7 +33,7 @@ #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "sp_context.h" #include "sp_headers.h" #include "sp_quad.h" diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 0c82692c6e..227cb2014e 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -30,7 +30,7 @@ */ #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "sp_context.h" #include "sp_headers.h" #include "sp_surface.h" diff --git a/src/gallium/drivers/softpipe/sp_quad_earlyz.c b/src/gallium/drivers/softpipe/sp_quad_earlyz.c index 22ea99049f..5a66a86699 100644 --- a/src/gallium/drivers/softpipe/sp_quad_earlyz.c +++ b/src/gallium/drivers/softpipe/sp_quad_earlyz.c @@ -30,7 +30,7 @@ */ #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "sp_headers.h" #include "sp_quad.h" diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 8c88c192f8..5499ba5361 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -35,7 +35,8 @@ * all the enabled attributes run contiguously. */ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" diff --git a/src/gallium/drivers/softpipe/sp_quad_occlusion.c b/src/gallium/drivers/softpipe/sp_quad_occlusion.c index 54254df1f1..db13e73ae3 100644 --- a/src/gallium/drivers/softpipe/sp_quad_occlusion.c +++ b/src/gallium/drivers/softpipe/sp_quad_occlusion.c @@ -33,7 +33,7 @@ #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "sp_context.h" #include "sp_headers.h" #include "sp_surface.h" diff --git a/src/gallium/drivers/softpipe/sp_quad_output.c b/src/gallium/drivers/softpipe/sp_quad_output.c index 40083138a4..b64646a449 100644 --- a/src/gallium/drivers/softpipe/sp_quad_output.c +++ b/src/gallium/drivers/softpipe/sp_quad_output.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "sp_context.h" #include "sp_headers.h" #include "sp_surface.h" diff --git a/src/gallium/drivers/softpipe/sp_quad_stencil.c b/src/gallium/drivers/softpipe/sp_quad_stencil.c index b4c7e942fa..ce9562e07c 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stencil.c +++ b/src/gallium/drivers/softpipe/sp_quad_stencil.c @@ -10,7 +10,7 @@ #include "sp_tile_cache.h" #include "sp_quad.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" /** Only 8-bit stencil supported */ diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c index f1e9b80e09..a39ecc2e9d 100644 --- a/src/gallium/drivers/softpipe/sp_quad_stipple.c +++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c @@ -7,7 +7,7 @@ #include "sp_headers.h" #include "sp_quad.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" /** diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c index adf9ccf64c..2106ee1d23 100644 --- a/src/gallium/drivers/softpipe/sp_query.c +++ b/src/gallium/drivers/softpipe/sp_query.c @@ -32,7 +32,7 @@ #include "draw/draw_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "sp_context.h" #include "sp_query.h" diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index f6b3d7ac24..9644dbd168 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_winsys.h" #include "pipe/p_defines.h" #include "pipe/p_screen.h" diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index c8c55fa6e8..87336ab6e3 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -42,9 +42,9 @@ #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_vertex.h" -#include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "util/u_math.h" +#include "util/u_memory.h" #define DEBUG_VERTS 0 diff --git a/src/gallium/drivers/softpipe/sp_state_blend.c b/src/gallium/drivers/softpipe/sp_state_blend.c index 2d40d6bd8f..384fe559af 100644 --- a/src/gallium/drivers/softpipe/sp_state_blend.c +++ b/src/gallium/drivers/softpipe/sp_state_blend.c @@ -28,7 +28,7 @@ /* Authors: Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "sp_context.h" #include "sp_state.h" diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index f10a1fa471..6b6a4c3ff3 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -25,7 +25,8 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" #include "draw/draw_vertex.h" diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 76fe6bfef9..1be461b3a4 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -30,7 +30,7 @@ #include "sp_fs.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" #include "pipe/p_shader_tokens.h" diff --git a/src/gallium/drivers/softpipe/sp_state_rasterizer.c b/src/gallium/drivers/softpipe/sp_state_rasterizer.c index 98e04352db..87b7219683 100644 --- a/src/gallium/drivers/softpipe/sp_state_rasterizer.c +++ b/src/gallium/drivers/softpipe/sp_state_rasterizer.c @@ -26,7 +26,7 @@ **************************************************************************/ #include "pipe/p_defines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "sp_context.h" #include "sp_state.h" #include "draw/draw_context.h" diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 033288a0aa..99a28c0d7e 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -29,7 +29,7 @@ * Brian Paul */ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "draw/draw_context.h" diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index bfbae234f1..389aceb27c 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -26,10 +26,9 @@ **************************************************************************/ #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "util/p_tile.h" +#include "util/u_tile.h" #include "util/u_rect.h" #include "sp_context.h" #include "sp_surface.h" diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 58a95d13e1..49250ec084 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -39,9 +39,9 @@ #include "sp_tile_cache.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "tgsi/tgsi_exec.h" #include "util/u_math.h" +#include "util/u_memory.h" /* diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index f775591352..3a737d6f72 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -33,8 +33,9 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "pipe/p_util.h" #include "pipe/p_winsys.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "sp_context.h" #include "sp_state.h" diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 57c12ffe33..b50c984513 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -32,9 +32,9 @@ * Brian Paul */ -#include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "util/p_tile.h" +#include "util/u_memory.h" +#include "util/u_tile.h" #include "sp_context.h" #include "sp_surface.h" #include "sp_texture.h" diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index f16359e8ad..1dd7719379 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_screen.h" #include "tr_dump.h" diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 1613a626df..48032c1617 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -45,6 +45,8 @@ #endif #include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "util/u_memory.h" #include "util/u_string.h" #include "tr_stream.h" diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index 6ddc8fc15c..76a53731b3 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -35,7 +35,6 @@ #include "pipe/p_compiler.h" -#include "pipe/p_util.h" boolean trace_dump_trace_begin(void); diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index a6467ec35f..8789f86b1a 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -25,7 +25,7 @@ * **************************************************************************/ -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "tr_dump.h" #include "tr_state.h" diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c index 30ab5a8fdc..986d939e0c 100644 --- a/src/gallium/drivers/trace/tr_state.c +++ b/src/gallium/drivers/trace/tr_state.c @@ -27,6 +27,7 @@ #include "pipe/p_compiler.h" +#include "util/u_memory.h" #include "tgsi/tgsi_dump.h" #include "tr_dump.h" diff --git a/src/gallium/drivers/trace/tr_stream_stdc.c b/src/gallium/drivers/trace/tr_stream_stdc.c index 4c77e1c995..4c19ec0b24 100644 --- a/src/gallium/drivers/trace/tr_stream_stdc.c +++ b/src/gallium/drivers/trace/tr_stream_stdc.c @@ -36,7 +36,7 @@ #include -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "tr_stream.h" diff --git a/src/gallium/drivers/trace/tr_stream_wd.c b/src/gallium/drivers/trace/tr_stream_wd.c index b3b65f0971..704eb15bd7 100644 --- a/src/gallium/drivers/trace/tr_stream_wd.c +++ b/src/gallium/drivers/trace/tr_stream_wd.c @@ -37,7 +37,7 @@ #include #include -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "util/u_string.h" #include "tr_stream.h" diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c index 99ba74d366..440a78704a 100644 --- a/src/gallium/drivers/trace/tr_texture.c +++ b/src/gallium/drivers/trace/tr_texture.c @@ -25,9 +25,9 @@ * **************************************************************************/ -#include "pipe/p_util.h" #include "pipe/p_inlines.h" #include "util/u_hash_table.h" +#include "util/u_memory.h" #include "tr_screen.h" #include "tr_texture.h" diff --git a/src/gallium/drivers/trace/tr_winsys.c b/src/gallium/drivers/trace/tr_winsys.c index 2c7a6f893b..177835854e 100644 --- a/src/gallium/drivers/trace/tr_winsys.c +++ b/src/gallium/drivers/trace/tr_winsys.c @@ -25,8 +25,7 @@ * **************************************************************************/ -#include "pipe/p_util.h" -#include "pipe/p_state.h" +#include "util/u_memory.h" #include "util/u_hash_table.h" #include "tr_dump.h" diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h deleted file mode 100644 index 4a3fca5962..0000000000 --- a/src/gallium/include/pipe/p_util.h +++ /dev/null @@ -1,460 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef P_UTIL_H -#define P_UTIL_H - -#include "p_config.h" -#include "p_compiler.h" -#include "p_debug.h" -#include "p_pointer.h" - -#if defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) -__inline double ceil(double val) -{ - double ceil_val; - - if((val - (long) val) == 0) { - ceil_val = val; - } else { - if(val > 0) { - ceil_val = (long) val + 1; - } else { - ceil_val = (long) val; - } - } - - return ceil_val; -} - -#ifndef PIPE_SUBSYSTEM_WINDOWS_CE -__inline double floor(double val) -{ - double floor_val; - - if((val - (long) val) == 0) { - floor_val = val; - } else { - if(val > 0) { - floor_val = (long) val; - } else { - floor_val = (long) val - 1; - } - } - - return floor_val; -} -#endif - -#pragma function(pow) -__inline double __cdecl pow(double val, double exponent) -{ - /* XXX */ - assert(0); - return 0; -} - -#pragma function(log) -__inline double __cdecl log(double val) -{ - /* XXX */ - assert(0); - return 0; -} - -#pragma function(atan2) -__inline double __cdecl atan2(double val) -{ - /* XXX */ - assert(0); - return 0; -} -#else -#include -#include -#endif - - /* Define ENOMEM for WINCE */ -#if (_WIN32_WCE < 600) -#ifndef ENOMEM -#define ENOMEM 12 -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && defined(DEBUG) - -/* memory debugging */ - -#include "p_debug.h" - -#define MALLOC( _size ) \ - debug_malloc( __FILE__, __LINE__, __FUNCTION__, _size ) -#define CALLOC( _count, _size ) \ - debug_calloc(__FILE__, __LINE__, __FUNCTION__, _count, _size ) -#define FREE( _ptr ) \ - debug_free( __FILE__, __LINE__, __FUNCTION__, _ptr ) -#define REALLOC( _ptr, _old_size, _size ) \ - debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _size ) - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - -void * __stdcall -EngAllocMem( - unsigned long Flags, - unsigned long MemSize, - unsigned long Tag ); - -void __stdcall -EngFreeMem( - void *Mem ); - -#define MALLOC( _size ) EngAllocMem( 0, _size, 'D3AG' ) -#define _FREE( _ptr ) EngFreeMem( _ptr ) - -#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) - -void * -ExAllocatePool( - unsigned long PoolType, - size_t NumberOfBytes); - -void -ExFreePool(void *P); - -#define MALLOC(_size) ExAllocatePool(0, _size) -#define _FREE(_ptr) ExFreePool(_ptr) - -#else - -#define MALLOC( SIZE ) malloc( SIZE ) -#define CALLOC( COUNT, SIZE ) calloc( COUNT, SIZE ) -#define FREE( PTR ) free( PTR ) -#define REALLOC( OLDPTR, OLDSIZE, NEWSIZE ) realloc( OLDPTR, NEWSIZE ) - -#endif - - -#ifndef CALLOC -static INLINE void * -CALLOC( unsigned count, unsigned size ) -{ - void *ptr = MALLOC( count * size ); - if( ptr ) { - memset( ptr, 0, count * size ); - } - return ptr; -} -#endif /* !CALLOC */ - -#ifndef FREE -static INLINE void -FREE( void *ptr ) -{ - if( ptr ) { - _FREE( ptr ); - } -} -#endif /* !FREE */ - -#ifndef REALLOC -static INLINE void * -REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) -{ - void *new_ptr = NULL; - - if (new_size != 0) { - unsigned copy_size = old_size < new_size ? old_size : new_size; - new_ptr = MALLOC( new_size ); - if (new_ptr && old_ptr && copy_size) { - memcpy( new_ptr, old_ptr, copy_size ); - } - } - - FREE( old_ptr ); - return new_ptr; -} -#endif /* !REALLOC */ - - -#define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T)) - -#define CALLOC_STRUCT(T) (struct T *) CALLOC(1, sizeof(struct T)) - - -/** - * Return memory on given byte alignment - */ -static INLINE void * -align_malloc(size_t bytes, uint alignment) -{ -#if defined(HAVE_POSIX_MEMALIGN) - void *mem; - alignment = (alignment + (uint)sizeof(void*) - 1) & ~((uint)sizeof(void*) - 1); - if(posix_memalign(& mem, alignment, bytes) != 0) - return NULL; - return mem; -#else - char *ptr, *buf; - - assert( alignment > 0 ); - - ptr = (char *) MALLOC(bytes + alignment + sizeof(void *)); - if (!ptr) - return NULL; - - buf = (char *) align_pointer( ptr + sizeof(void *), alignment ); - *(char **)(buf - sizeof(void *)) = ptr; - - return buf; -#endif /* defined(HAVE_POSIX_MEMALIGN) */ -} - -/** - * Free memory returned by align_malloc(). - */ -static INLINE void -align_free(void *ptr) -{ -#if defined(HAVE_POSIX_MEMALIGN) - FREE(ptr); -#else - void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); - void *realAddr = *cubbyHole; - FREE(realAddr); -#endif /* defined(HAVE_POSIX_MEMALIGN) */ -} - - - -/** - * Duplicate a block of memory. - */ -static INLINE void * -mem_dup(const void *src, uint size) -{ - void *dup = MALLOC(size); - if (dup) - memcpy(dup, src, size); - return dup; -} - - - -#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) -#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) -#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) - -#ifndef Elements -#define Elements(x) (sizeof(x)/sizeof((x)[0])) -#endif -#define Offset(TYPE, MEMBER) ((unsigned)&(((TYPE *)NULL)->MEMBER)) - -/** - * Return a pointer aligned to next multiple of 16 bytes. - */ -static INLINE void * -align16( void *unaligned ) -{ - return align_pointer( unaligned, 16 ); -} - - -static INLINE int align(int value, int alignment) -{ - return (value + alignment - 1) & ~(alignment - 1); -} - - - - -#if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) -static INLINE unsigned ffs( unsigned u ) -{ - unsigned i; - - if( u == 0 ) { - return 0; - } - - __asm bsf eax, [u] - __asm inc eax - __asm mov [i], eax - - return i; -} -#endif - -union fi { - float f; - int i; - unsigned ui; -}; - -#define UBYTE_TO_FLOAT( ub ) ((float)(ub) / 255.0F) - -#define IEEE_0996 0x3f7f0000 /* 0.996 or so */ - -/* This function/macro is sensitive to precision. Test very carefully - * if you change it! - */ -#define UNCLAMPED_FLOAT_TO_UBYTE(UB, F) \ - do { \ - union fi __tmp; \ - __tmp.f = (F); \ - if (__tmp.i < 0) \ - UB = (ubyte) 0; \ - else if (__tmp.i >= IEEE_0996) \ - UB = (ubyte) 255; \ - else { \ - __tmp.f = __tmp.f * (255.0f/256.0f) + 32768.0f; \ - UB = (ubyte) __tmp.i; \ - } \ - } while (0) - - - -static INLINE unsigned pack_ub4( unsigned char b0, - unsigned char b1, - unsigned char b2, - unsigned char b3 ) -{ - return ((((unsigned int)b0) << 0) | - (((unsigned int)b1) << 8) | - (((unsigned int)b2) << 16) | - (((unsigned int)b3) << 24)); -} - -static INLINE unsigned fui( float f ) -{ - union fi fi; - fi.f = f; - return fi.ui; -} - -static INLINE unsigned char float_to_ubyte( float f ) -{ - unsigned char ub; - UNCLAMPED_FLOAT_TO_UBYTE(ub, f); - return ub; -} - -static INLINE unsigned pack_ui32_float4( float a, - float b, - float c, - float d ) -{ - return pack_ub4( float_to_ubyte(a), - float_to_ubyte(b), - float_to_ubyte(c), - float_to_ubyte(d) ); -} - -#define COPY_4V( DST, SRC ) \ -do { \ - (DST)[0] = (SRC)[0]; \ - (DST)[1] = (SRC)[1]; \ - (DST)[2] = (SRC)[2]; \ - (DST)[3] = (SRC)[3]; \ -} while (0) - - -#define COPY_4FV( DST, SRC ) COPY_4V(DST, SRC) - - -#define ASSIGN_4V( DST, V0, V1, V2, V3 ) \ -do { \ - (DST)[0] = (V0); \ - (DST)[1] = (V1); \ - (DST)[2] = (V2); \ - (DST)[3] = (V3); \ -} while (0) - - - -#if defined(_MSC_VER) -#if _MSC_VER < 1400 && !defined(__cplusplus) || defined(PIPE_SUBSYSTEM_WINDOWS_CE) - -static INLINE float cosf( float f ) -{ - return (float) cos( (double) f ); -} - -static INLINE float sinf( float f ) -{ - return (float) sin( (double) f ); -} - -static INLINE float ceilf( float f ) -{ - return (float) ceil( (double) f ); -} - -static INLINE float floorf( float f ) -{ - return (float) floor( (double) f ); -} - -static INLINE float powf( float f, float g ) -{ - return (float) pow( (double) f, (double) g ); -} - -static INLINE float sqrtf( float f ) -{ - return (float) sqrt( (double) f ); -} - -static INLINE float fabsf( float f ) -{ - return (float) fabs( (double) f ); -} - -static INLINE float logf( float f ) -{ - return (float) log( (double) f ); -} - -#else -/* Work-around an extra semi-colon in VS 2005 logf definition */ -#ifdef logf -#undef logf -#define logf(x) ((float)log((double)(x))) -#endif /* logf */ -#endif -#endif /* _MSC_VER */ - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 641b19e940..a67372c623 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -42,7 +42,7 @@ #include "pipe/p_screen.h" #include "pipe/p_context.h" #include "pipe/p_inlines.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_shader_tokens.h" #include "cso_cache/cso_context.h" #include "util/u_draw_quad.h" diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index a1889539dc..f71d85dd9b 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -26,12 +26,13 @@ **************************************************************************/ -#include "pipe/p_util.h" #include "pipe/p_winsys.h" #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" #include "pipe/p_inlines.h" #include "cso_cache/cso_context.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "util/u_simple_shaders.h" #include "trace/tr_screen.h" #include "trace/tr_context.h" diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c index b47c7be293..7765df3c4a 100644 --- a/src/gallium/state_trackers/python/st_sample.c +++ b/src/gallium/state_trackers/python/st_sample.c @@ -29,9 +29,10 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" -#include "util/p_tile.h" +#include "util/u_tile.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "st_sample.h" diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c index 6ea3c9a5cf..2d4f5434b3 100644 --- a/src/gallium/state_trackers/python/st_softpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -39,8 +39,9 @@ #include "pipe/p_winsys.h" #include "pipe/p_format.h" #include "pipe/p_context.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "softpipe/sp_winsys.h" #include "st_winsys.h" diff --git a/src/gallium/winsys/drm/intel/common/intel_be_device.c b/src/gallium/winsys/drm/intel/common/intel_be_device.c index 8db0329615..019ee5cbd2 100644 --- a/src/gallium/winsys/drm/intel/common/intel_be_device.c +++ b/src/gallium/winsys/drm/intel/common/intel_be_device.c @@ -13,8 +13,8 @@ #include "pipe/p_winsys.h" #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_memory.h" #include "i915simple/i915_screen.h" diff --git a/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c index 0d98d16cf1..20920a2052 100644 --- a/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c +++ b/src/gallium/winsys/drm/intel/dri/intel_winsys_softpipe.c @@ -32,8 +32,8 @@ #include "intel_context.h" #include "intel_winsys_softpipe.h" #include "pipe/p_defines.h" -#include "pipe/p_util.h" #include "pipe/p_format.h" +#include "util/u_memory.h" #include "softpipe/sp_winsys.h" diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index 829732eea8..e9f821d276 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -38,8 +38,8 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "pipe/p_winsys.h" +#include "util/u_memory.h" #include "softpipe/sp_winsys.h" #include "eglconfig.h" diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c index f4199e6f89..ae81d7f801 100644 --- a/src/gallium/winsys/egl_xlib/sw_winsys.c +++ b/src/gallium/winsys/egl_xlib/sw_winsys.c @@ -37,8 +37,9 @@ #include "pipe/p_winsys.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "sw_winsys.h" diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c index ff52ceb8c4..730fb1b541 100644 --- a/src/gallium/winsys/gdi/wmesa.c +++ b/src/gallium/winsys/gdi/wmesa.c @@ -12,8 +12,8 @@ #include "pipe/p_winsys.h" #include "pipe/p_format.h" #include "pipe/p_context.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_memory.h" #include "softpipe/sp_winsys.h" #include "glapi/glapi.h" #include "colors.h" diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index 6e814ce5d1..f319802962 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -34,7 +34,6 @@ #include "brw_aub.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "pipe/p_util.h" #include "pipe/p_debug.h" diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 4b4dc56e84..68ead7f528 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -42,8 +42,9 @@ #include "pipe/p_winsys.h" #include "pipe/p_format.h" #include "pipe/p_context.h" -#include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "softpipe/sp_winsys.h" #ifdef GALLIUM_CELL diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index 7fc9debdd5..3439367636 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -37,7 +37,7 @@ #include "xmesaP.h" #include "pipe/p_winsys.h" -#include "pipe/p_util.h" +#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "i965simple/brw_winsys.h" #include "i965simple/brw_screen.h" -- cgit v1.2.3 From 4c84e940d009fe56c1f249507028daadea749ef2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 24 Aug 2008 17:49:11 -0600 Subject: gallium: remove old tile util files --- src/gallium/auxiliary/util/p_tile.c | 1168 ----------------------------------- src/gallium/auxiliary/util/p_tile.h | 101 --- 2 files changed, 1269 deletions(-) delete mode 100644 src/gallium/auxiliary/util/p_tile.c delete mode 100644 src/gallium/auxiliary/util/p_tile.h (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c deleted file mode 100644 index 8219041c80..0000000000 --- a/src/gallium/auxiliary/util/p_tile.c +++ /dev/null @@ -1,1168 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * RGBA/float tile get/put functions. - * Usable both by drivers and state trackers. - * Surfaces should already be in a mapped state. - */ - - -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" - -#include "p_tile.h" -#include "u_rect.h" - - -/** - * Move raw block of pixels from surface to user memory. - * This should be usable by any hw driver that has mappable surfaces. - */ -void -pipe_get_tile_raw(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - void *dst, int dst_stride) -{ - const void *src; - - if (dst_stride == 0) - dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; - - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - - src = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ); - assert(src); - if(!src) - return; - - pipe_copy_rect(dst, &ps->block, dst_stride, 0, 0, w, h, src, ps->stride, x, y); - - pipe_surface_unmap(ps); -} - - -/** - * Move raw block of pixels from user memory to surface. - * This should be usable by any hw driver that has mappable surfaces. - */ -void -pipe_put_tile_raw(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const void *src, int src_stride) -{ - void *dst; - - if (src_stride == 0) - src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size; - - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - - dst = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE); - assert(dst); - if(!dst) - return; - - pipe_copy_rect(dst, &ps->block, ps->stride, x, y, w, h, src, src_stride, 0, 0); - - pipe_surface_unmap(ps); -} - - - - -/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */ -#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) - -#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \ - us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) - - - -/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ - -static void -a8r8g8b8_get_tile_rgba(const unsigned *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - const unsigned pixel = *src++; - pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); - pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); - pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); - pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); - } - p += dst_stride; - } -} - - -static void -a8r8g8b8_put_tile_rgba(unsigned *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - unsigned r, g, b, a; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); - UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); - *dst++ = (a << 24) | (r << 16) | (g << 8) | b; - } - p += src_stride; - } -} - - -/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ - -static void -x8r8g8b8_get_tile_rgba(const unsigned *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - const unsigned pixel = *src++; - pRow[0] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); - pRow[1] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); - pRow[2] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); - pRow[3] = UBYTE_TO_FLOAT(0xff); - } - p += dst_stride; - } -} - - -static void -x8r8g8b8_put_tile_rgba(unsigned *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - unsigned r, g, b; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); - *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b; - } - p += src_stride; - } -} - - -/*** PIPE_FORMAT_B8G8R8A8_UNORM ***/ - -static void -b8g8r8a8_get_tile_rgba(const unsigned *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - const unsigned pixel = *src++; - pRow[0] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); - pRow[1] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); - pRow[2] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); - pRow[3] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); - } - p += dst_stride; - } -} - - -static void -b8g8r8a8_put_tile_rgba(unsigned *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - unsigned r, g, b, a; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); - UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); - *dst++ = (b << 24) | (g << 16) | (r << 8) | a; - } - p += src_stride; - } -} - - -/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/ - -static void -a1r5g5b5_get_tile_rgba(const ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - const ushort pixel = *src++; - pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f); - pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f); - pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); - pRow[3] = ((pixel >> 15) ) * 1.0f; - } - p += dst_stride; - } -} - - -static void -a1r5g5b5_put_tile_rgba(ushort *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - unsigned r, g, b, a; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); - UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); - r = r >> 3; /* 5 bits */ - g = g >> 3; /* 5 bits */ - b = b >> 3; /* 5 bits */ - a = a >> 7; /* 1 bit */ - *dst++ = (a << 15) | (r << 10) | (g << 5) | b; - } - p += src_stride; - } -} - - -/*** PIPE_FORMAT_A4R4G4B4_UNORM ***/ - -static void -a4r4g4b4_get_tile_rgba(const ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - const ushort pixel = *src++; - pRow[0] = ((pixel >> 8) & 0xf) * (1.0f / 15.0f); - pRow[1] = ((pixel >> 4) & 0xf) * (1.0f / 15.0f); - pRow[2] = ((pixel ) & 0xf) * (1.0f / 15.0f); - pRow[3] = ((pixel >> 12) ) * (1.0f / 15.0f); - } - p += dst_stride; - } -} - - -static void -a4r4g4b4_put_tile_rgba(ushort *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - unsigned r, g, b, a; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); - UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); - r >>= 4; - g >>= 4; - b >>= 4; - a >>= 4; - *dst++ = (a << 12) | (r << 16) | (g << 4) | b; - } - p += src_stride; - } -} - - -/*** PIPE_FORMAT_R5G6B5_UNORM ***/ - -static void -r5g6b5_get_tile_rgba(const ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - const ushort pixel = *src++; - pRow[0] = ((pixel >> 11) & 0x1f) * (1.0f / 31.0f); - pRow[1] = ((pixel >> 5) & 0x3f) * (1.0f / 63.0f); - pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f); - pRow[3] = 1.0f; - } - p += dst_stride; - } -} - - -static void -r5g6b5_put_tile_rgba(ushort *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - uint r = (uint) (CLAMP(pRow[0], 0.0, 1.0) * 31.0); - uint g = (uint) (CLAMP(pRow[1], 0.0, 1.0) * 63.0); - uint b = (uint) (CLAMP(pRow[2], 0.0, 1.0) * 31.0); - *dst++ = (r << 11) | (g << 5) | (b); - } - p += src_stride; - } -} - - - -/*** PIPE_FORMAT_Z16_UNORM ***/ - -/** - * Return each Z value as four floats in [0,1]. - */ -static void -z16_get_tile_rgba(const ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - const float scale = 1.0f / 65535.0f; - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = - pRow[3] = *src++ * scale; - } - p += dst_stride; - } -} - - - - -/*** PIPE_FORMAT_L8_UNORM ***/ - -static void -l8_get_tile_rgba(const ubyte *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, src++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = UBYTE_TO_FLOAT(*src); - pRow[3] = 1.0; - } - p += dst_stride; - } -} - - -static void -l8_put_tile_rgba(ubyte *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - unsigned r; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - *dst++ = r; - } - p += src_stride; - } -} - - - -/*** PIPE_FORMAT_A8_UNORM ***/ - -static void -a8_get_tile_rgba(const ubyte *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, src++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = 0.0; - pRow[3] = UBYTE_TO_FLOAT(*src); - } - p += dst_stride; - } -} - - -static void -a8_put_tile_rgba(ubyte *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - unsigned a; - UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); - *dst++ = a; - } - p += src_stride; - } -} - - - -/*** PIPE_FORMAT_R16_SNORM ***/ - -static void -r16_get_tile_rgba(const short *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, src++, pRow += 4) { - pRow[0] = SHORT_TO_FLOAT(src[0]); - pRow[1] = - pRow[2] = 0.0; - pRow[3] = 1.0; - } - p += dst_stride; - } -} - - -static void -r16_put_tile_rgba(short *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, dst++, pRow += 4) { - UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); - } - p += src_stride; - } -} - - -/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ - -static void -r16g16b16a16_get_tile_rgba(const short *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, src += 4, pRow += 4) { - pRow[0] = SHORT_TO_FLOAT(src[0]); - pRow[1] = SHORT_TO_FLOAT(src[1]); - pRow[2] = SHORT_TO_FLOAT(src[2]); - pRow[3] = SHORT_TO_FLOAT(src[3]); - } - p += dst_stride; - } -} - - -static void -r16g16b16a16_put_tile_rgba(short *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, dst += 4, pRow += 4) { - UNCLAMPED_FLOAT_TO_SHORT(dst[0], pRow[0]); - UNCLAMPED_FLOAT_TO_SHORT(dst[1], pRow[1]); - UNCLAMPED_FLOAT_TO_SHORT(dst[2], pRow[2]); - UNCLAMPED_FLOAT_TO_SHORT(dst[3], pRow[3]); - } - p += src_stride; - } -} - - - -/*** PIPE_FORMAT_I8_UNORM ***/ - -static void -i8_get_tile_rgba(const ubyte *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, src++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = - pRow[3] = UBYTE_TO_FLOAT(*src); - } - p += dst_stride; - } -} - - -static void -i8_put_tile_rgba(ubyte *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - unsigned r; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - *dst++ = r; - } - p += src_stride; - } -} - - -/*** PIPE_FORMAT_A8L8_UNORM ***/ - -static void -a8l8_get_tile_rgba(const ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - ushort p = *src++; - pRow[0] = - pRow[1] = - pRow[2] = UBYTE_TO_FLOAT(p & 0xff); - pRow[3] = UBYTE_TO_FLOAT(p >> 8); - } - p += dst_stride; - } -} - - -static void -a8l8_put_tile_rgba(ushort *dst, - unsigned w, unsigned h, - const float *p, - unsigned src_stride) -{ - unsigned i, j; - - for (i = 0; i < h; i++) { - const float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - unsigned r, a; - UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); - UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); - *dst++ = (a << 8) | r; - } - p += src_stride; - } -} - - - - -/*** PIPE_FORMAT_Z32_UNORM ***/ - -/** - * Return each Z value as four floats in [0,1]. - */ -static void -z32_get_tile_rgba(const unsigned *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - const double scale = 1.0 / (double) 0xffffffff; - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = - pRow[3] = (float) (*src++ * scale); - } - p += dst_stride; - } -} - - -/*** PIPE_FORMAT_S8Z24_UNORM ***/ - -/** - * Return Z component as four float in [0,1]. Stencil part ignored. - */ -static void -s8z24_get_tile_rgba(const unsigned *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - const double scale = 1.0 / ((1 << 24) - 1); - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = - pRow[3] = (float) (scale * (*src++ & 0xffffff)); - } - p += dst_stride; - } -} - - -/*** PIPE_FORMAT_Z24S8_UNORM ***/ - -/** - * Return Z component as four float in [0,1]. Stencil part ignored. - */ -static void -z24s8_get_tile_rgba(const unsigned *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride) -{ - const double scale = 1.0 / ((1 << 24) - 1); - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - for (j = 0; j < w; j++, pRow += 4) { - pRow[0] = - pRow[1] = - pRow[2] = - pRow[3] = (float) (scale * (*src++ >> 8)); - } - p += dst_stride; - } -} - - -/*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/ - -/** - * Convert YCbCr (or YCrCb) to RGBA. - */ -static void -ycbcr_get_tile_rgba(const ushort *src, - unsigned w, unsigned h, - float *p, - unsigned dst_stride, - boolean rev) -{ - const float scale = 1.0f / 255.0f; - unsigned i, j; - - for (i = 0; i < h; i++) { - float *pRow = p; - /* do two texels at a time */ - for (j = 0; j < (w & ~1); j += 2, src += 2) { - const ushort t0 = src[0]; - const ushort t1 = src[1]; - const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ - const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */ - ubyte cb, cr; - float r, g, b; - - if (rev) { - cb = t1 & 0xff; /* chroma U */ - cr = t0 & 0xff; /* chroma V */ - } - else { - cb = t0 & 0xff; /* chroma U */ - cr = t1 & 0xff; /* chroma V */ - } - - /* even pixel: y0,cr,cb */ - r = 1.164f * (y0-16) + 1.596f * (cr-128); - g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128); - b = 1.164f * (y0-16) + 2.018f * (cb-128); - pRow[0] = r * scale; - pRow[1] = g * scale; - pRow[2] = b * scale; - pRow[3] = 1.0f; - pRow += 4; - - /* odd pixel: use y1,cr,cb */ - r = 1.164f * (y1-16) + 1.596f * (cr-128); - g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128); - b = 1.164f * (y1-16) + 2.018f * (cb-128); - pRow[0] = r * scale; - pRow[1] = g * scale; - pRow[2] = b * scale; - pRow[3] = 1.0f; - pRow += 4; - - } - /* do the last texel */ - if (w & 1) { - const ushort t0 = src[0]; - const ushort t1 = src[1]; - const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ - ubyte cb, cr; - float r, g, b; - - if (rev) { - cb = t1 & 0xff; /* chroma U */ - cr = t0 & 0xff; /* chroma V */ - } - else { - cb = t0 & 0xff; /* chroma U */ - cr = t1 & 0xff; /* chroma V */ - } - - /* even pixel: y0,cr,cb */ - r = 1.164f * (y0-16) + 1.596f * (cr-128); - g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128); - b = 1.164f * (y0-16) + 2.018f * (cb-128); - pRow[0] = r * scale; - pRow[1] = g * scale; - pRow[2] = b * scale; - pRow[3] = 1.0f; - pRow += 4; - } - p += dst_stride; - } -} - - -void -pipe_tile_raw_to_rgba(enum pipe_format format, - void *src, - uint w, uint h, - float *dst, unsigned dst_stride) -{ - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_X8R8G8B8_UNORM: - x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_B8G8R8A8_UNORM: - b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_A1R5G5B5_UNORM: - a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_A4R4G4B4_UNORM: - a4r4g4b4_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_R5G6B5_UNORM: - r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_L8_UNORM: - l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_A8_UNORM: - a8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_I8_UNORM: - i8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_A8L8_UNORM: - a8l8_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_R16_SNORM: - r16_get_tile_rgba((short *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_R16G16B16A16_SNORM: - r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_Z16_UNORM: - z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_Z32_UNORM: - z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_S8Z24_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_Z24S8_UNORM: - z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); - break; - case PIPE_FORMAT_YCBCR: - ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, FALSE); - break; - case PIPE_FORMAT_YCBCR_REV: - ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE); - break; - default: - assert(0); - } -} - - -void -pipe_get_tile_rgba(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - float *p) -{ - unsigned dst_stride = w * 4; - void *packed; - - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - - packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size); - - if (!packed) - return; - - if(ps->format == PIPE_FORMAT_YCBCR || ps->format == PIPE_FORMAT_YCBCR_REV) - assert((x & 1) == 0); - - pipe_get_tile_raw(ps, x, y, w, h, packed, 0); - - pipe_tile_raw_to_rgba(ps->format, packed, w, h, p, dst_stride); - - FREE(packed); -} - - -void -pipe_put_tile_rgba(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const float *p) -{ - unsigned src_stride = w * 4; - void *packed; - - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - - packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size); - - if (!packed) - return; - - switch (ps->format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_X8R8G8B8_UNORM: - x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_B8G8R8A8_UNORM: - b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_A1R5G5B5_UNORM: - a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_R5G6B5_UNORM: - r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_R8G8B8A8_UNORM: - assert(0); - break; - case PIPE_FORMAT_A4R4G4B4_UNORM: - a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_L8_UNORM: - l8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_A8_UNORM: - a8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_I8_UNORM: - i8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_A8L8_UNORM: - a8l8_put_tile_rgba((ushort *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_R16_SNORM: - r16_put_tile_rgba((short *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_R16G16B16A16_SNORM: - r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride); - break; - case PIPE_FORMAT_Z16_UNORM: - /*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_Z32_UNORM: - /*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_S8Z24_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ - break; - case PIPE_FORMAT_Z24S8_UNORM: - /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ - break; - default: - assert(0); - } - - pipe_put_tile_raw(ps, x, y, w, h, packed, 0); - - FREE(packed); -} - - -/** - * Get a block of Z values, converted to 32-bit range. - */ -void -pipe_get_tile_z(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - uint *z) -{ - const uint dstStride = w; - ubyte *map; - uint *pDest = z; - uint i, j; - - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - - map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ); - if (!map) { - assert(0); - return; - } - - switch (ps->format) { - case PIPE_FORMAT_Z32_UNORM: - { - const uint *pSrc - = (const uint *)(map + y * ps->stride + x*4); - for (i = 0; i < h; i++) { - memcpy(pDest, pSrc, 4 * w); - pDest += dstStride; - pSrc += ps->stride/4; - } - } - break; - case PIPE_FORMAT_S8Z24_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - { - const uint *pSrc - = (const uint *)(map + y * ps->stride + x*4); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 24-bit Z to 32-bit Z */ - pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff); - } - pDest += dstStride; - pSrc += ps->stride/4; - } - } - break; - case PIPE_FORMAT_Z16_UNORM: - { - const ushort *pSrc - = (const ushort *)(map + y * ps->stride + x*2); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 16-bit Z to 32-bit Z */ - pDest[j] = (pSrc[j] << 16) | pSrc[j]; - } - pDest += dstStride; - pSrc += ps->stride/2; - } - } - break; - default: - assert(0); - } - - pipe_surface_unmap(ps); -} - - -void -pipe_put_tile_z(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const uint *zSrc) -{ - const uint srcStride = w; - const uint *pSrc = zSrc; - ubyte *map; - uint i, j; - - if (pipe_clip_tile(x, y, &w, &h, ps)) - return; - - map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE); - if (!map) { - assert(0); - return; - } - - switch (ps->format) { - case PIPE_FORMAT_Z32_UNORM: - { - uint *pDest = (uint *) (map + y * ps->stride + x*4); - for (i = 0; i < h; i++) { - memcpy(pDest, pSrc, 4 * w); - pDest += ps->stride/4; - pSrc += srcStride; - } - } - break; - case PIPE_FORMAT_S8Z24_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - { - uint *pDest = (uint *) (map + y * ps->stride + x*4); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 32-bit Z to 24-bit Z (0 stencil) */ - pDest[j] = pSrc[j] >> 8; - } - pDest += ps->stride/4; - pSrc += srcStride; - } - } - break; - case PIPE_FORMAT_Z16_UNORM: - { - ushort *pDest = (ushort *) (map + y * ps->stride + x*2); - for (i = 0; i < h; i++) { - for (j = 0; j < w; j++) { - /* convert 32-bit Z to 16-bit Z */ - pDest[j] = pSrc[j] >> 16; - } - pDest += ps->stride/2; - pSrc += srcStride; - } - } - break; - default: - assert(0); - } - - pipe_surface_unmap(ps); -} - - diff --git a/src/gallium/auxiliary/util/p_tile.h b/src/gallium/auxiliary/util/p_tile.h deleted file mode 100644 index a8ac805308..0000000000 --- a/src/gallium/auxiliary/util/p_tile.h +++ /dev/null @@ -1,101 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef P_TILE_H -#define P_TILE_H - -#include "pipe/p_compiler.h" - -struct pipe_surface; - - -/** - * Clip tile against surface dims. - * \return TRUE if tile is totally clipped, FALSE otherwise - */ -static INLINE boolean -pipe_clip_tile(uint x, uint y, uint *w, uint *h, const struct pipe_surface *ps) -{ - if (x >= ps->width) - return TRUE; - if (y >= ps->height) - return TRUE; - if (x + *w > ps->width) - *w = ps->width - x; - if (y + *h > ps->height) - *h = ps->height - y; - return FALSE; -} - -#ifdef __cplusplus -extern "C" { -#endif - -void -pipe_get_tile_raw(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - void *p, int dst_stride); - -void -pipe_put_tile_raw(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const void *p, int src_stride); - - -void -pipe_get_tile_rgba(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - float *p); - -void -pipe_put_tile_rgba(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const float *p); - - -void -pipe_get_tile_z(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - uint *z); - -void -pipe_put_tile_z(struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const uint *z); - -void -pipe_tile_raw_to_rgba(enum pipe_format format, - void *src, - uint w, uint h, - float *dst, unsigned dst_stride); - - -#ifdef __cplusplus -} -#endif - -#endif -- cgit v1.2.3 From 6fd2feaad7029a2f6d02bcf7039cbe72f53c615c Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 24 Aug 2008 18:10:50 -0600 Subject: gallium: include u_memory.h, u_math.h --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c | 1 + src/gallium/winsys/xlib/brw_aub.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index 5e518370d0..4cb8c3bb55 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -37,6 +37,7 @@ #include "pipe/p_debug.h" #include "pipe/p_winsys.h" #include "pipe/p_thread.h" +#include "util/u_math.h" #include "util/u_memory.h" #include "util/u_double_list.h" #include "util/u_time.h" diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index f319802962..9e96efaa53 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -35,6 +35,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "pipe/p_debug.h" +#include "util/u_memory.h" struct brw_aubfile { -- cgit v1.2.3 From 2c4661f8fce8a27f2082c6ac498f9fb188878476 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 25 Aug 2008 10:42:00 +0200 Subject: gallium: Add missing includes. --- src/gallium/auxiliary/util/u_memory.h | 2 +- src/gallium/drivers/i915simple/i915_fpc_emit.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_memory.h b/src/gallium/auxiliary/util/u_memory.h index 148a5cb997..ec32d60fbe 100644 --- a/src/gallium/auxiliary/util/u_memory.h +++ b/src/gallium/auxiliary/util/u_memory.h @@ -51,7 +51,7 @@ /* memory debugging */ -#include "p_debug.h" +#include "pipe/p_debug.h" #define MALLOC( _size ) \ debug_malloc( __FILE__, __LINE__, __FUNCTION__, _size ) diff --git a/src/gallium/drivers/i915simple/i915_fpc_emit.c b/src/gallium/drivers/i915simple/i915_fpc_emit.c index 4bdeefb449..b054ce41d3 100644 --- a/src/gallium/drivers/i915simple/i915_fpc_emit.c +++ b/src/gallium/drivers/i915simple/i915_fpc_emit.c @@ -28,6 +28,7 @@ #include "i915_reg.h" #include "i915_context.h" #include "i915_fpc.h" +#include "util/u_math.h" #define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) -- cgit v1.2.3 From 85813e36f2646e00ac163fb6e6e78e1d2f73eb34 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 25 Aug 2008 08:32:50 -0600 Subject: gallium: include u_math.h --- src/gallium/winsys/xlib/xm_winsys_aub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index 3439367636..35c4ebc4ba 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -37,8 +37,9 @@ #include "xmesaP.h" #include "pipe/p_winsys.h" -#include "util/u_memory.h" #include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "i965simple/brw_winsys.h" #include "i965simple/brw_screen.h" #include "brw_aub.h" -- cgit v1.2.3 From fd06d01b80fd9b2924682686e943d819bfcf027b Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Aug 2008 11:29:39 -0600 Subject: gallium: include on linux to get sched_yield() proto --- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 8ae052e875..410d336fef 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -38,6 +38,7 @@ #if defined(PIPE_OS_LINUX) #include +#include #endif #include "pipe/p_compiler.h" -- cgit v1.2.3 From a644c5a850242376e6ab03f7f4bdbfb8a232490f Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Aug 2008 11:30:20 -0600 Subject: gallium: include p_debug.h for non-HAVE_POSIX_MEMALIGN --- src/gallium/auxiliary/util/u_memory.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/u_memory.h b/src/gallium/auxiliary/util/u_memory.h index ec32d60fbe..8fbbb4e55d 100644 --- a/src/gallium/auxiliary/util/u_memory.h +++ b/src/gallium/auxiliary/util/u_memory.h @@ -36,6 +36,7 @@ #include "util/u_pointer.h" +#include "pipe/p_debug.h" /* Define ENOMEM for WINCE */ -- cgit v1.2.3 From 60ac76175b6457ecc1cd8bd7a25cb79b2d529434 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Aug 2008 11:30:57 -0600 Subject: gallium: added const qualifiers on some draw funcs --- src/gallium/auxiliary/draw/draw_context.c | 4 ++-- src/gallium/auxiliary/draw/draw_context.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 1c26cb31a3..36751c2621 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -288,7 +288,7 @@ draw_enable_point_sprites(struct draw_context *draw, boolean enable) * work for the drivers. */ int -draw_find_vs_output(struct draw_context *draw, +draw_find_vs_output(const struct draw_context *draw, uint semantic_name, uint semantic_index) { const struct draw_vertex_shader *vs = draw->vs.vertex_shader; @@ -314,7 +314,7 @@ draw_find_vs_output(struct draw_context *draw, * Return number of vertex shader outputs. */ uint -draw_num_vs_outputs(struct draw_context *draw) +draw_num_vs_outputs(const struct draw_context *draw) { uint count = draw->vs.vertex_shader->info.num_outputs; if (draw->extra_vp_outputs.slot > 0) diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index b8f2bfa332..0ab3681b64 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -84,11 +84,11 @@ draw_install_pstipple_stage(struct draw_context *draw, struct pipe_context *pipe int -draw_find_vs_output(struct draw_context *draw, +draw_find_vs_output(const struct draw_context *draw, uint semantic_name, uint semantic_index); uint -draw_num_vs_outputs(struct draw_context *draw); +draw_num_vs_outputs(const struct draw_context *draw); -- cgit v1.2.3 From 6ba9fb9b6693904054ad4e1506ba42e324334b0a Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 25 Aug 2008 11:31:59 -0600 Subject: cell: asst fixes to get driver building/running again. Note that SPU vertex transformation is disabled at this time. --- src/gallium/drivers/cell/ppu/cell_clear.c | 4 +- src/gallium/drivers/cell/ppu/cell_context.c | 4 ++ src/gallium/drivers/cell/ppu/cell_draw_arrays.c | 35 ++++++++++-- src/gallium/drivers/cell/ppu/cell_draw_arrays.h | 24 ++++++-- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 6 +- src/gallium/drivers/cell/ppu/cell_state_emit.c | 14 ++--- src/gallium/drivers/cell/ppu/cell_state_shader.c | 4 +- src/gallium/drivers/cell/ppu/cell_surface.c | 11 ++-- src/gallium/drivers/cell/ppu/cell_texture.c | 69 ++++++++++++++++++++--- src/gallium/drivers/cell/ppu/cell_texture.h | 1 + src/gallium/drivers/cell/ppu/cell_vbuf.c | 1 + src/gallium/drivers/cell/ppu/cell_vertex_fetch.c | 4 ++ src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 5 ++ src/gallium/drivers/cell/spu/spu_exec.h | 2 +- src/gallium/drivers/cell/spu/spu_render.c | 2 +- src/gallium/drivers/cell/spu/spu_tri.c | 1 + src/gallium/drivers/cell/spu/spu_util.c | 2 + src/gallium/drivers/cell/spu/spu_vertex_shader.c | 26 ++++++++- 18 files changed, 176 insertions(+), 39 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c index cee0917b63..a421c95c8e 100644 --- a/src/gallium/drivers/cell/ppu/cell_clear.c +++ b/src/gallium/drivers/cell/ppu/cell_clear.c @@ -48,6 +48,7 @@ void cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, unsigned clearValue) { + struct pipe_screen *screen = pipe->screen; struct cell_context *cell = cell_context(pipe); uint surfIndex; @@ -56,7 +57,8 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, if (!cell->cbuf_map[0]) - cell->cbuf_map[0] = pipe_surface_map(ps); + cell->cbuf_map[0] = screen->surface_map(screen, ps, + PIPE_BUFFER_USAGE_GPU_WRITE); if (ps == cell->framebuffer.zsbuf) { surfIndex = 1; diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index 5af95a3c10..9ff4e86943 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -73,11 +73,13 @@ cell_draw_create(struct cell_context *cell) { struct draw_context *draw = draw_create(); +#if 0 /* broken */ if (getenv("GALLIUM_CELL_VS")) { /* plug in SPU-based vertex transformation code */ draw->shader_queue_flush = cell_vertex_shader_queue_flush; draw->driver_private = cell; } +#endif return draw; } @@ -108,6 +110,8 @@ cell_create_context(struct pipe_screen *screen, cell->pipe.draw_arrays = cell_draw_arrays; cell->pipe.draw_elements = cell_draw_elements; + cell->pipe.draw_range_elements = cell_draw_range_elements; + cell->pipe.set_edgeflags = cell_set_edgeflags; cell->pipe.clear = cell_clear_surface; cell->pipe.flush = cell_flush; diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index 6e08cf6fe8..f02dffe124 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -59,7 +59,8 @@ cell_map_constant_buffers(struct cell_context *sp) } draw_set_mapped_constant_buffer(sp->draw, - sp->mapped_constants[PIPE_SHADER_VERTEX]); + sp->mapped_constants[PIPE_SHADER_VERTEX], + sp->constants[PIPE_SHADER_VERTEX].size); } static void @@ -92,10 +93,12 @@ cell_draw_arrays(struct pipe_context *pipe, unsigned mode, * XXX should the element buffer be specified/bound with a separate function? */ boolean -cell_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned mode, unsigned start, unsigned count) +cell_draw_range_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned min_index, + unsigned max_index, + unsigned mode, unsigned start, unsigned count) { struct cell_context *sp = cell_context(pipe); struct draw_context *draw = sp->draw; @@ -152,3 +155,25 @@ cell_draw_elements(struct pipe_context *pipe, return TRUE; } + + +boolean +cell_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + return cell_draw_range_elements( pipe, indexBuffer, + indexSize, + 0, 0xffffffff, + mode, start, count ); +} + + + +void +cell_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags) +{ + struct cell_context *cell = cell_context(pipe); + draw_set_edgeflags(cell->draw, edgeflags); +} diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.h b/src/gallium/drivers/cell/ppu/cell_draw_arrays.h index d5df4aa05f..cd35ec17b4 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.h +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.h @@ -29,14 +29,26 @@ #define CELL_DRAW_ARRAYS_H -boolean cell_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count); +extern boolean +cell_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count); -boolean cell_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned mode, unsigned start, unsigned count); +extern boolean +cell_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count); +extern boolean +cell_draw_range_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned min_index, + unsigned max_index, + unsigned mode, unsigned start, unsigned count); + +extern void +cell_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags); #endif /* CELL_DRAW_ARRAYS_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 971d65d09e..fe5437023b 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -294,6 +294,8 @@ cell_set_framebuffer_state(struct pipe_context *pipe, struct pipe_surface *csurf = fb->cbufs[0]; struct pipe_surface *zsurf = fb->zsbuf; uint i; + uint flags = (PIPE_BUFFER_USAGE_GPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ); /* unmap old surfaces */ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { @@ -313,10 +315,10 @@ cell_set_framebuffer_state(struct pipe_context *pipe, /* map new surfaces */ if (csurf) - cell->cbuf_map[0] = pipe_surface_map(csurf); + cell->cbuf_map[0] = pipe_surface_map(csurf, flags); if (zsurf) - cell->zsbuf_map = pipe_surface_map(zsurf); + cell->zsbuf_map = pipe_surface_map(zsurf, flags); cell->dirty |= CELL_NEW_FRAMEBUFFER; } diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 3646a0ee4f..9d88c1cf3d 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -162,13 +162,13 @@ cell_emit_state(struct cell_context *cell) const struct draw_context *const draw = cell->draw; struct cell_shader_info info; - info.num_outputs = draw->num_vs_outputs; - info.declarations = (uintptr_t) draw->machine.Declarations; - info.num_declarations = draw->machine.NumDeclarations; - info.instructions = (uintptr_t) draw->machine.Instructions; - info.num_instructions = draw->machine.NumInstructions; - info.immediates = (uintptr_t) draw->machine.Imms; - info.num_immediates = draw->machine.ImmLimit / 4; + info.num_outputs = draw_num_vs_outputs(draw); + info.declarations = (uintptr_t) draw->vs.machine.Declarations; + info.num_declarations = draw->vs.machine.NumDeclarations; + info.instructions = (uintptr_t) draw->vs.machine.Instructions; + info.num_instructions = draw->vs.machine.NumInstructions; + info.immediates = (uintptr_t) draw->vs.machine.Imms; + info.num_immediates = draw->vs.machine.ImmLimit / 4; emit_state_cmd(cell, CELL_CMD_STATE_BIND_VS, & info, sizeof(info)); diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c index cd96b317fa..86bcad05e9 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -41,7 +41,7 @@ static INLINE struct cell_fragment_shader_state * cell_fragment_shader_state(void *shader) { - return (struct pipe_shader_state *) shader; + return (struct cell_fragment_shader_state *) shader; } @@ -49,7 +49,7 @@ cell_fragment_shader_state(void *shader) static INLINE struct cell_vertex_shader_state * cell_vertex_shader_state(void *shader) { - return (struct pipe_shader_state *) shader; + return (struct cell_vertex_shader_state *) shader; } diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c index 2d31ad89a6..d9e3b510dc 100644 --- a/src/gallium/drivers/cell/ppu/cell_surface.c +++ b/src/gallium/drivers/cell/ppu/cell_surface.c @@ -26,11 +26,12 @@ **************************************************************************/ #include "pipe/p_defines.h" -#include "util/u_memory.h" #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" -#include "util/p_tile.h" +#include "util/u_memory.h" #include "util/u_rect.h" +#include "util/u_tile.h" + #include "cell_context.h" #include "cell_surface.h" @@ -46,12 +47,12 @@ cell_surface_copy(struct pipe_context *pipe, { assert( dst->cpp == src->cpp ); - pipe_copy_rect(pipe_surface_map(dst), + pipe_copy_rect(pipe_surface_map(dst, PIPE_BUFFER_USAGE_CPU_WRITE), &dst->block, dst->stride, dstx, dsty, width, height, - pipe_surface_map(src), + pipe_surface_map(src, PIPE_BUFFER_USAGE_CPU_READ), do_flip ? -src->stride : src->stride, srcx, do_flip ? height - 1 - srcy : srcy); @@ -81,7 +82,7 @@ cell_surface_fill(struct pipe_context *pipe, unsigned width, unsigned height, unsigned value) { unsigned i, j; - void *dst_map = pipe_surface_map(dst); + void *dst_map = pipe_surface_map(dst, PIPE_BUFFER_USAGE_CPU_WRITE); assert(dst->stride > 0); diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index 1add81373d..5a0942bbd6 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -33,8 +33,9 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" -#include "util/u_memory.h" #include "pipe/p_winsys.h" +#include "util/u_math.h" +#include "util/u_memory.h" #include "cell_context.h" #include "cell_state.h" @@ -68,11 +69,13 @@ cell_texture_layout(struct cell_texture * spt) pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width); pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height); + spt->stride[level] = pt->nblocksx[level] * pt->block.size; + spt->level_offset[level] = spt->buffer_size; spt->buffer_size += (pt->nblocksy[level] * ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * - pt->nblocksx[level] * pt->block.size; + pt->nblocksx[level] * pt->block.size); width = minify(width); height = minify(height); @@ -147,7 +150,8 @@ cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, static struct pipe_surface * cell_get_tex_surface_screen(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) + unsigned face, unsigned level, unsigned zslice, + unsigned usage) { struct pipe_winsys *ws = screen->winsys; struct cell_texture *spt = cell_texture(pt); @@ -166,6 +170,10 @@ cell_get_tex_surface_screen(struct pipe_screen *screen, ps->nblocksy = pt->nblocksy[level]; ps->stride = spt->stride[level]; ps->offset = spt->level_offset[level]; + ps->usage = usage; + + /* XXX may need to override usage flags (see sp_texture.c) */ + if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * @@ -228,10 +236,11 @@ cell_tile_texture(struct cell_context *cell, assert(w % TILE_SIZE == 0); assert(h % TILE_SIZE == 0); - surf = screen->get_tex_surface(screen, &texture->base, face, level, zslice); + surf = screen->get_tex_surface(screen, &texture->base, face, level, zslice, + PIPE_BUFFER_USAGE_CPU_WRITE); ASSERT(surf); - src = (const uint *) pipe_surface_map(surf); + src = (const uint *) pipe_surface_map(surf, PIPE_BUFFER_USAGE_CPU_WRITE); if (texture->tiled_data) { align_free(texture->tiled_data); @@ -246,11 +255,12 @@ cell_tile_texture(struct cell_context *cell, } - void cell_update_texture_mapping(struct cell_context *cell) { +#if 0 uint face = 0, level = 0, zslice = 0; +#endif uint i; for (i = 0; i < CELL_MAX_SAMPLERS; i++) { @@ -275,10 +285,52 @@ cell_update_texture_mapping(struct cell_context *cell) } +static void * +cell_surface_map( struct pipe_screen *screen, + struct pipe_surface *surface, + unsigned flags ) +{ + ubyte *map; + + if (flags & ~surface->usage) { + assert(0); + return NULL; + } + + map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags ); + if (map == NULL) + return NULL; + + /* May want to different things here depending on read/write nature + * of the map: + */ + if (surface->texture && + (flags & PIPE_BUFFER_USAGE_CPU_WRITE)) + { + /* Do something to notify sharing contexts of a texture change. + * In softpipe, that would mean flushing the texture cache. + */ +#if 0 + cell_screen(screen)->timestamp++; +#endif + } + + return map + surface->offset; +} + + +static void +cell_surface_unmap(struct pipe_screen *screen, + struct pipe_surface *surface) +{ + screen->winsys->buffer_unmap( screen->winsys, surface->buffer ); +} + + void cell_init_texture_functions(struct cell_context *cell) { - cell->pipe.texture_update = cell_texture_update; + /*cell->pipe.texture_update = cell_texture_update;*/ } void @@ -287,4 +339,7 @@ cell_init_screen_texture_funcs(struct pipe_screen *screen) screen->texture_create = cell_texture_create_screen; screen->texture_release = cell_texture_release_screen; screen->get_tex_surface = cell_get_tex_surface_screen; + + screen->surface_map = cell_surface_map; + screen->surface_unmap = cell_surface_unmap; } diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h index fcee069d05..6d37e95ebc 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.h +++ b/src/gallium/drivers/cell/ppu/cell_texture.h @@ -41,6 +41,7 @@ struct cell_texture struct pipe_texture base; unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long stride[PIPE_MAX_TEXTURE_LEVELS]; /* The data is held here: */ diff --git a/src/gallium/drivers/cell/ppu/cell_vbuf.c b/src/gallium/drivers/cell/ppu/cell_vbuf.c index 3a181b585c..e4230c7a5f 100644 --- a/src/gallium/drivers/cell/ppu/cell_vbuf.c +++ b/src/gallium/drivers/cell/ppu/cell_vbuf.c @@ -37,6 +37,7 @@ #include "cell_spu.h" #include "cell_vbuf.h" #include "draw/draw_vbuf.h" +#include "util/u_memory.h" /** Allow vertex data to be inlined after RENDER command */ diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c index 49d5443cde..2ece0250f6 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c @@ -260,6 +260,7 @@ emit_fetch(struct spe_function *p, void cell_update_vertex_fetch(struct draw_context *draw) { +#if 0 struct cell_context *const cell = (struct cell_context *) draw->driver_private; struct spe_function *p = &cell->attrib_fetch; @@ -337,4 +338,7 @@ void cell_update_vertex_fetch(struct draw_context *draw) cell->attrib_fetch_offsets[function_index[i]]; } } +#else + assert(0); +#endif } diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index f753960a0f..3658947715 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -32,6 +32,7 @@ #include "pipe/p_defines.h" #include "pipe/p_context.h" #include "pipe/p_winsys.h" +#include "util/u_math.h" #include "cell_context.h" #include "cell_draw_arrays.h" @@ -50,6 +51,7 @@ void cell_vertex_shader_queue_flush(struct draw_context *draw) { +#if 0 struct cell_context *const cell = (struct cell_context *) draw->driver_private; struct cell_command_vs *const vs = &cell_global.command[0].vs; @@ -138,4 +140,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) draw->vs.post_nr = draw->vs.queue_nr; draw->vs.queue_nr = 0; +#else + assert(0); +#endif } diff --git a/src/gallium/drivers/cell/spu/spu_exec.h b/src/gallium/drivers/cell/spu/spu_exec.h index c68f78f59b..8605679940 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.h +++ b/src/gallium/drivers/cell/spu/spu_exec.h @@ -99,7 +99,7 @@ struct spu_exec_machine * 1 address */ struct spu_exec_vector Temps[TGSI_EXEC_NUM_TEMPS - + TGSI_EXEC_NUM_ADDRS + 1] + + TGSI_EXEC_NUM_TEMP_EXTRAS + 1] ALIGN16_ATTRIB; struct spu_exec_vector *Addrs; diff --git a/src/gallium/drivers/cell/spu/spu_render.c b/src/gallium/drivers/cell/spu/spu_render.c index 6df59abd36..305dc98881 100644 --- a/src/gallium/drivers/cell/spu/spu_render.c +++ b/src/gallium/drivers/cell/spu/spu_render.c @@ -35,7 +35,7 @@ #include "spu_tri.h" #include "spu_tile.h" #include "cell/common.h" - +#include "util/u_memory.h" /** diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index 8944ef171e..2a4e0b423c 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -32,6 +32,7 @@ #include #include "pipe/p_compiler.h" #include "pipe/p_format.h" +#include "util/u_math.h" #include "spu_colorpack.h" #include "spu_main.h" #include "spu_texture.h" diff --git a/src/gallium/drivers/cell/spu/spu_util.c b/src/gallium/drivers/cell/spu/spu_util.c index dbcf4b0eb9..b25ca4eafc 100644 --- a/src/gallium/drivers/cell/spu/spu_util.c +++ b/src/gallium/drivers/cell/spu/spu_util.c @@ -1,4 +1,6 @@ + #include "pipe/p_shader_tokens.h" +#include "pipe/p_debug.h" #include "tgsi/tgsi_parse.h" //#include "tgsi_build.h" #include "tgsi/tgsi_util.h" diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c index a1e81975e6..f81d19fea1 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c @@ -36,13 +36,35 @@ #include "pipe/p_state.h" #include "pipe/p_shader_tokens.h" -#include "spu_vertex_shader.h" -#include "spu_exec.h" +#include "util/u_math.h" #include "draw/draw_private.h" #include "draw/draw_context.h" #include "cell/common.h" +#include "spu_vertex_shader.h" +#include "spu_exec.h" #include "spu_main.h" + +#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) + + +#define CLIP_RIGHT_BIT 0x01 +#define CLIP_LEFT_BIT 0x02 +#define CLIP_TOP_BIT 0x04 +#define CLIP_BOTTOM_BIT 0x08 +#define CLIP_FAR_BIT 0x10 +#define CLIP_NEAR_BIT 0x20 + + +static INLINE float +dot4(const float *a, const float *b) +{ + return (a[0]*b[0] + + a[1]*b[1] + + a[2]*b[2] + + a[3]*b[3]); +} + static INLINE unsigned compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) { -- cgit v1.2.3 From e6887a5752774c18cf527477fdd3e57e4893ff3b Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 25 Aug 2008 11:19:24 +0100 Subject: draw: attempt atomic submit of large drawelements calls --- src/gallium/auxiliary/draw/draw_pt.h | 4 ++-- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 9 ++++----- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 7 ++++--- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 11 ++++------- src/gallium/auxiliary/draw/draw_pt_vcache.c | 21 +++++++++++++-------- src/gallium/auxiliary/draw/draw_vbuf.h | 3 ++- 6 files changed, 29 insertions(+), 26 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 3d2a9c78b7..c02f229110 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -98,9 +98,9 @@ struct draw_pt_middle_end { unsigned count); /* Transform all vertices in a linear range and then draw them with - * the supplied element list. + * the supplied element list. May fail and return FALSE. */ - void (*run_linear_elts)( struct draw_pt_middle_end *, + boolean (*run_linear_elts)( struct draw_pt_middle_end *, unsigned fetch_start, unsigned fetch_count, const ushort *draw_elts, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 0684c93d10..5a4db6cfe5 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -324,7 +324,7 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle, } -static void fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle, +static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle, unsigned start, unsigned count, const ushort *draw_elts, @@ -341,10 +341,8 @@ static void fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle, hw_verts = draw->render->allocate_vertices( draw->render, (ushort)feme->translate->key.output_stride, (ushort)count ); - if (!hw_verts) { - assert(0); - return; - } + if (!hw_verts) + return FALSE; /* Single routine to fetch vertices and emit HW verts. */ @@ -367,6 +365,7 @@ static void fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle, feme->translate->key.output_stride, count ); + return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 87094f3092..73fc70c1bc 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -332,7 +332,7 @@ fse_run(struct draw_pt_middle_end *middle, -static void fse_run_linear_elts( struct draw_pt_middle_end *middle, +static boolean fse_run_linear_elts( struct draw_pt_middle_end *middle, unsigned start, unsigned count, const ushort *draw_elts, @@ -351,8 +351,7 @@ static void fse_run_linear_elts( struct draw_pt_middle_end *middle, (ushort)count ); if (!hw_verts) { - assert(0); - return; + return FALSE; } /* Single routine to fetch vertices, run shader and emit HW verts. @@ -374,6 +373,8 @@ static void fse_run_linear_elts( struct draw_pt_middle_end *middle, hw_verts, fse->key.output_stride, count ); + + return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index f617aac9f7..ec3b41c320 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -262,7 +262,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, -static void fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle, +static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle, unsigned start, unsigned count, const ushort *draw_elts, @@ -277,12 +277,8 @@ static void fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle, struct vertex_header *pipeline_verts = (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); - if (!pipeline_verts) { - /* Not much we can do here - just skip the rendering. - */ - assert(0); - return; - } + if (!pipeline_verts) + return FALSE; /* Fetch into our vertex buffer */ @@ -336,6 +332,7 @@ static void fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle, } FREE(pipeline_verts); + return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index b8b5de729d..e8467b2ae3 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -306,6 +306,7 @@ static void vcache_check_run( struct draw_pt_front_end *frontend, unsigned fetch_count = max_index + 1 - min_index; const ushort *transformed_elts; ushort *storage = NULL; + boolean ok; if (0) debug_printf("fetch_count %d fetch_max %d draw_count %d\n", fetch_count, @@ -313,7 +314,6 @@ static void vcache_check_run( struct draw_pt_front_end *frontend, draw_count); if (max_index == 0xffffffff || - fetch_count >= vcache->fetch_max || fetch_count > draw_count) { if (0) debug_printf("fail\n"); goto fail; @@ -395,14 +395,19 @@ static void vcache_check_run( struct draw_pt_front_end *frontend, transformed_elts = storage; } - vcache->middle->run_linear_elts( vcache->middle, - min_index, /* start */ - fetch_count, - transformed_elts, - draw_count ); - + ok = vcache->middle->run_linear_elts( vcache->middle, + min_index, /* start */ + fetch_count, + transformed_elts, + draw_count ); + FREE(storage); - return; + + if (ok) + return; + + debug_printf("failed to execute atomic draw elts for %d/%d, splitting up\n", + fetch_count, draw_count); fail: vcache_run( frontend, get_elt, elts, draw_count ); diff --git a/src/gallium/auxiliary/draw/draw_vbuf.h b/src/gallium/auxiliary/draw/draw_vbuf.h index 62247ccd9f..b0aa2df309 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.h +++ b/src/gallium/auxiliary/draw/draw_vbuf.h @@ -79,7 +79,8 @@ struct vbuf_render { boolean (*set_primitive)( struct vbuf_render *, unsigned prim ); /** - * DrawElements, note indices are ushort: + * DrawElements, note indices are ushort. The driver must complete + * this call, if necessary splitting the index list itself. */ void (*draw)( struct vbuf_render *, const ushort *indices, -- cgit v1.2.3